File indexing completed on 2024-03-24 15:43:44

0001 //
0002 // C++ Implementation: clistobject
0003 //
0004 // Description: 
0005 //
0006 /*
0007 Copyright 2007-2011 Tomas Mecir <kmuddy@kmuddy.com>
0008 
0009 This program is free software; you can redistribute it and/or
0010 modify it under the terms of the GNU General Public License as
0011 published by the Free Software Foundation; either version 2 of 
0012 the License, or (at your option) any later version.
0013 
0014 This program is distributed in the hope that it will be useful,
0015 but WITHOUT ANY WARRANTY; without even the implied warranty of
0016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0017 GNU General Public License for more details.
0018 
0019 You should have received a copy of the GNU General Public License
0020 along with this program.  If not, see <http://www.gnu.org/licenses/>.
0021 */
0022 
0023 #include "clistobject.h"
0024 
0025 #include "clistgroup.h"
0026 #include "clist.h"
0027 #include "clistmanager.h"
0028 
0029 #include <QXmlStreamReader>
0030 #include <QXmlStreamWriter>
0031 
0032 struct cListObject::Private {
0033   cList *list;
0034   cListGroup *parent;
0035 
0036   cListObjectData data;
0037   int groupPos, groupPriorityPos;
0038   QString visibleName;
0039 };
0040 
0041 cListObject::cListObject (cList *list)
0042 {
0043   d = new Private;
0044   d->list = list;
0045   d->parent = nullptr;
0046   d->data.enabled = true;
0047   d->groupPos = 0;
0048   d->groupPriorityPos = 0;
0049   d->data.priority = DEFAULT_OBJECT_PRIORITY;
0050 
0051   d->visibleName = list->objName ();
0052   
0053   d->list->addObject (this);
0054   cListManager::self()->registerObject (this);
0055 }
0056 
0057 cListObject::~cListObject ()
0058 {
0059   d->data.intValues.clear ();
0060   d->data.strValues.clear ();
0061   d->data.boolValues.clear ();
0062   if (d->parent) d->parent->removeObject (this);
0063   d->list->removeObject (this);
0064   cListManager::self()->unregisterObject (this);
0065 
0066   delete d;
0067 }
0068 
0069 cList *cListObject::list ()
0070 {
0071   return d->list;
0072 }
0073 
0074 cListGroup *cListObject::parentGroup ()
0075 {
0076   return d->parent;
0077 }
0078 
0079 int cListObject::priority ()
0080 {
0081   return d->data.priority;
0082 }
0083 
0084 void cListObject::setPriority (int p)
0085 {
0086   if (p < 1) p = 1;
0087   if (p > 1000) p = 1000;
0088   d->data.priority = p;
0089   if (d->parent)
0090     d->parent->objectChanged (this);
0091 }
0092 
0093 void cListObject::setName (const QString &n)
0094 {
0095   d->data.name = n;
0096   updateVisibleName ();
0097 }
0098 
0099 QString cListObject::name ()
0100 {
0101   return d->data.name;
0102 }
0103 
0104 QString cListObject::visibleName ()
0105 {
0106   return d->visibleName;
0107 }
0108 
0109 void cListObject::setVisibleName (const QString &name)
0110 {
0111   d->visibleName = name;
0112   emit changed (this);
0113   list()->notifyChanged (this);
0114 }
0115 
0116 void cListObject::updateVisibleName ()
0117 {
0118   // default implementation simply uses object type name
0119   setVisibleName (list()->objName());
0120 }
0121 
0122 int cListObject::intVal (const QString &name)
0123 {
0124   if (d->data.intValues.count (name))
0125     return d->data.intValues[name];
0126   return d->list->defaultIntValue (name);
0127 }
0128 
0129 void cListObject::setInt (const QString &name, int value)
0130 {
0131   if (value == d->list->defaultIntValue (name))
0132     clearInt (name);
0133   else
0134     d->data.intValues[name] = value;
0135   emit changed (this);
0136   attribChanged (name);
0137 }
0138 
0139 void cListObject::clearInt (const QString &name)
0140 {
0141   d->data.intValues.erase (name);
0142 }
0143 
0144 QString cListObject::strVal (const QString &name)
0145 {
0146   if (d->data.strValues.count (name))
0147     return d->data.strValues[name];
0148   return d->list->defaultStrValue (name);
0149 }
0150 
0151 void cListObject::setStr (const QString &name, const QString &value)
0152 {
0153   if (value == d->list->defaultStrValue (name))
0154     clearStr (name);
0155   else
0156     d->data.strValues[name] = value;
0157   emit changed (this);
0158   attribChanged (name);
0159 }
0160 
0161 void cListObject::clearStr (const QString &name)
0162 {
0163   d->data.strValues.erase (name);
0164 }
0165 
0166 bool cListObject::boolVal (const QString &name)
0167 {
0168   if (d->data.boolValues.count (name))
0169     return d->data.boolValues[name];
0170   return d->list->defaultBoolValue (name);
0171 }
0172 
0173 void cListObject::setBool (const QString &name, bool value)
0174 {
0175   if (value == d->list->defaultBoolValue (name))
0176     clearBool (name);
0177   else
0178     d->data.boolValues[name] = value;
0179   emit changed (this);
0180   attribChanged (name);
0181 }
0182 
0183 void cListObject::clearBool (const QString &name)
0184 {
0185   d->data.boolValues.erase (name);
0186 }
0187 
0188 int cListObject::strListCount (const QString &name)
0189 {
0190   return intVal (name + "-count");
0191 }
0192 
0193 void cListObject::setStrListCount (const QString &name, int count)
0194 {
0195   int oldCount = strListCount (name);
0196   // clear data that's removed, if any
0197   for (int i = count + 1; i <= oldCount; ++i)
0198     clearStr (name + "-" + QString::number(i));
0199   setInt (name + "-count", count);
0200 }
0201 
0202 QString cListObject::strListValue (const QString &name, int which)
0203 {
0204   return strVal (name + "-" + QString::number (which));
0205 }
0206 
0207 void cListObject::setStrListValue (const QString &name, int which, const QString &value)
0208 {
0209   if (which <= 0) return;
0210   if (which > strListCount (name)) setStrListCount (name, which);
0211 
0212   setStr (name + "-" + QString::number(which), value);
0213 }
0214 
0215 void cListObject::clearStrList (const QString &name)
0216 {
0217   setStrListCount (name, 0);
0218 }
0219 
0220 void cListObject::attribChanged (const QString &)
0221 {
0222   // nothing here - childs may override
0223 }
0224 
0225 cListObjectData cListObject::data ()
0226 {
0227   return d->data;
0228 }
0229 
0230 bool cListObject::enabled ()
0231 {
0232   return d->data.enabled;
0233 }
0234 
0235 void cListObject::setEnabled (bool en)
0236 {
0237   bool e = d->data.enabled;
0238   d->data.enabled = en;
0239   
0240   if (e != en) {
0241     en ? objectEnabled () : objectDisabled ();
0242     emit changed (this);
0243     list()->notifyChanged (this);
0244   }
0245 }
0246 
0247 void cListObject::setParentGroup (cListGroup *group)
0248 {
0249   if (d->parent == group) return;  // already there ? do nothing
0250   if (d->parent)
0251     d->parent->removeObject (this);
0252   d->parent = group;
0253   d->parent->addObject (this);
0254   objectMoved ();
0255 }
0256 
0257 void cListObject::setPositionInGroup (int pos)
0258 {
0259   int oldpos = d->groupPos;
0260   d->groupPos = pos;
0261   if (oldpos != pos) objectMoved ();
0262 }
0263 
0264 int cListObject::positionInGroup () const
0265 
0266 {
0267   return d->groupPos;
0268 }
0269 
0270 void cListObject::setPriorityInGroup (int pos)
0271 {
0272   int oldpos = d->groupPriorityPos;
0273   d->groupPriorityPos = pos;
0274   if (oldpos != pos) objectMoved ();
0275 }
0276 
0277 int cListObject::priorityInGroup () const
0278 {
0279   return d->groupPriorityPos;
0280 }
0281 
0282 void cListObject::objectMoved ()
0283 {
0284   // nothing here - subclasses may override
0285 }
0286 
0287 cList::TraverseAction cListObject::traverse (int)
0288 {
0289   return cList::Stop;
0290 }
0291 
0292 void cListObject::load (QXmlStreamReader *reader)
0293 {
0294   setEnabled (true);
0295   setPriority (DEFAULT_OBJECT_PRIORITY);  // revert priority to default
0296 
0297   QString en = reader->attributes().value ("enabled").toString();
0298   if ((!en.isEmpty()) && (en.toLower() == "false"))
0299     setEnabled (false);
0300   QString pri = reader->attributes().value ("priority").toString();
0301   if (!pri.isEmpty()) {
0302     int p = pri.toInt();
0303     if (p) setPriority (p);
0304   }
0305 
0306   // okay, now traverse child tags, if any
0307   while (!reader->atEnd()) {
0308     reader->readNext ();
0309     // Error ? Break out.
0310     if (reader->hasError()) break;
0311     // we're done with the tag
0312     if (reader->isEndElement() && (reader->name() == "object")) break;
0313     if (!reader->isStartElement()) continue;  // anything else than start of element - ignore it and continue with the next
0314     if (reader->name() == "attrib") {
0315       QStringRef type = reader->attributes().value ("type");
0316       QString name = reader->attributes().value ("name").toString();
0317       QString value;
0318       while (!reader->isEndElement()) {
0319         // read the data
0320         // the data may be split into parts, if it contains entities
0321         reader->readNext ();
0322         if (reader->isCharacters()) value += reader->text().toString();
0323       }
0324       if (type == "bool")
0325         setBool (name, (value.toLower() == "true"));
0326       else if (type == "int")
0327         setInt (name, value.toInt());
0328       else
0329         setStr (name, value);
0330     }
0331   }
0332 }
0333 
0334 void cListObject::save (QXmlStreamWriter *writer)
0335 {
0336   writer->writeStartElement ("object");
0337 
0338   if (!name().isEmpty()) writer->writeAttribute ("name", name());
0339   if (!enabled())
0340     writer->writeAttribute ("enabled", "false");
0341   if (priority() != DEFAULT_OBJECT_PRIORITY)
0342     writer->writeAttribute ("priority", QString::number (priority()));
0343 
0344   // save the attributes
0345   std::map<QString, int>::iterator it1;
0346   std::map<QString, QString>::iterator it2;
0347   std::map<QString, bool>::iterator it3;
0348   for (it1 = d->data.intValues.begin(); it1 != d->data.intValues.end(); ++it1)
0349   {
0350     writer->writeStartElement ("attrib");
0351     writer->writeAttribute ("type", "int");
0352     writer->writeAttribute ("name", it1->first);
0353     writer->writeCharacters (QString::number (it1->second));
0354     writer->writeEndElement ();
0355   }
0356   for (it2 = d->data.strValues.begin(); it2 != d->data.strValues.end(); ++it2)
0357   {
0358     writer->writeStartElement ("attrib");
0359     writer->writeAttribute ("type", "string");
0360     writer->writeAttribute ("name", it2->first);
0361     writer->writeCharacters (it2->second);
0362     writer->writeEndElement ();
0363   }
0364   for (it3 = d->data.boolValues.begin(); it3 != d->data.boolValues.end(); ++it3)
0365   {
0366     writer->writeStartElement ("attrib");
0367     writer->writeAttribute ("type", "bool");
0368     writer->writeAttribute ("name", it3->first);
0369     writer->writeCharacters (it3->second ? "true" : "false");
0370     writer->writeEndElement ();
0371   }
0372 
0373   writer->writeEndElement ();  // end the object element
0374 }
0375 
0376 #include "moc_clistobject.cpp"