File indexing completed on 2024-05-12 04:35:04

0001 /* This file is part of the TikZKit project.
0002  *
0003  * Copyright (C) 2015-2016 Dominik Haumann <dhaumann@kde.org>
0004  *
0005  * This library is free software; you can redistribute it and/or modify
0006  * it under the terms of the GNU Library General Public License as published
0007  * by the Free Software Foundation, either version 2 of the License, or
0008  * (at your option) any later version.
0009  *
0010  * This library is distributed in the hope that it will be useful,
0011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013  * GNU Library General Public License for more details.
0014  *
0015  * You should have received a copy of the GNU Library General Public License
0016  * along with this library; see the file COPYING.LIB.  If not, see
0017  * <http://www.gnu.org/licenses/>.
0018  */
0019 
0020 #include "Property.h"
0021 #include "PropertyInterface.h"
0022 
0023 #include <QJsonObject>
0024 
0025 namespace tikz {
0026 namespace core {
0027 
0028 class PropertyPrivate
0029 {
0030 public:
0031     Property * property = nullptr;
0032     QString title;
0033     QString propertyName;
0034     PropertyInterface * propertyInterface = nullptr;
0035     bool propertySet = false;
0036 
0037     //! change refcounter
0038     int changeRefCounter = 0;
0039 
0040 public: // change management
0041     //! Starts a change transaction.
0042     void beginChange()
0043     {
0044         ++changeRefCounter;
0045 
0046         if (changeRefCounter == 1 && propertyInterface) {
0047             propertyInterface->notifyPropertyAboutToChange(property);
0048         }
0049     }
0050 
0051     //! Ends a change transaction.
0052     void endChange()
0053     {
0054         --changeRefCounter;
0055         if (changeRefCounter == 0 && propertyInterface) {
0056             propertyInterface->notifyPropertyChanged(property);
0057         }
0058     }
0059 
0060     friend class Property::Transaction;
0061 };
0062 
0063 Property::Transaction::Transaction(Property * prop)
0064     : m_property(prop)
0065 {
0066     if (m_property) {
0067         m_property->d->beginChange();
0068     }
0069 }
0070 
0071 void Property::Transaction::endChange()
0072 {
0073     if (m_property) {
0074         m_property->d->endChange();
0075         m_property = nullptr;
0076     }
0077 }
0078 
0079 Property::Transaction::~Transaction()
0080 {
0081     endChange();
0082 }
0083 
0084 Property::Property(const QString & propertyName, PropertyInterface * interface)
0085     : d(new PropertyPrivate())
0086 {
0087     d->property = this;
0088     d->propertyName = propertyName;
0089     d->propertyInterface = interface;
0090 }
0091 
0092 Property::~Property()
0093 {
0094     delete d;
0095 }
0096 
0097 PropertyInterface * Property::propertyInterface() const
0098 {
0099     return d->propertyInterface;
0100 }
0101 
0102 Property * Property::parentProperty() const
0103 {
0104     if (d->propertyInterface) {
0105         auto iface = d->propertyInterface->parentPropertyInterface();
0106         if (iface) {
0107             auto prop = iface->property(propertyName());
0108             if (prop) {
0109                 // hierarchical properties must always have the same type.
0110                 Q_ASSERT(propertyType() == prop->propertyType());
0111             }
0112             return prop;
0113         }
0114     }
0115     return nullptr;
0116 }
0117 
0118 Entity * Property::entity() const
0119 {
0120     return d->propertyInterface ? d->propertyInterface->entity() : nullptr;
0121 }
0122 
0123 QString Property::propertyName() const
0124 {
0125     return d->propertyName;
0126 }
0127 
0128 void Property::setTitle(const QString & title)
0129 {
0130     if (d->title!= title) {
0131         Transaction trans(this);
0132         d->title = title;
0133     }
0134 }
0135 
0136 QString Property::title() const
0137 {
0138     return d->title;
0139 }
0140 
0141 void Property::unset()
0142 {
0143     if (d->propertySet) {
0144         Transaction trans(this);
0145         d->propertySet = false;
0146     }
0147 }
0148 
0149 bool Property::isSet() const
0150 {
0151     return d->propertySet;
0152 }
0153 
0154 void Property::load(const QJsonObject & json)
0155 {
0156     // load meta data
0157     d->propertyName = json["name"].toString(d->propertyName);
0158     d->title = json["title"].toString(d->title);
0159 
0160     // load payload
0161     loadData(json["data"].toObject());
0162 }
0163 
0164 void Property::loadData(const QJsonObject & json)
0165 {
0166     Q_UNUSED(json)
0167 }
0168 
0169 void Property::save(QJsonObject & json)
0170 {
0171     // save meta data
0172     json["name"] = propertyName();
0173     json["title"] = d->title;
0174     json["type"] = propertyType();
0175 
0176     // save payload
0177     QJsonObject joData;
0178     saveData(joData);
0179     json["data"] = joData;
0180 }
0181 
0182 void Property::saveData(QJsonObject & json)
0183 {
0184     Q_UNUSED(json)
0185 }
0186 
0187 }
0188 }
0189 
0190 // kate: indent-width 4; replace-tabs on;