File indexing completed on 2025-01-19 06:54:49
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"