File indexing completed on 2024-05-12 16:39:50
0001 /* This file is part of the KDE project 0002 Copyright (C) 2003 Lucijan Busch <lucijan@gmx.at> 0003 Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr> 0004 Copyright (C) 2006-2010 Jarosław Staniek <staniek@kde.org> 0005 0006 This library is free software; you can redistribute it and/or 0007 modify it under the terms of the GNU Library General Public 0008 License as published by the Free Software Foundation; either 0009 version 2 of the License, or (at your option) any later version. 0010 0011 This library is distributed in the hope that it will be useful, 0012 but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0014 Library General Public License for more details. 0015 0016 You should have received a copy of the GNU Library General Public License 0017 along with this library; see the file COPYING.LIB. If not, write to 0018 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0019 * Boston, MA 02110-1301, USA. 0020 */ 0021 0022 #include <QDebug> 0023 #include <QWidget> 0024 #include <QVariant> 0025 #include <QTextStream> 0026 #include <QDomElement> 0027 0028 #include "form.h" 0029 #include "container.h" 0030 #include "objecttree.h" 0031 0032 0033 using namespace KFormDesigner; 0034 0035 ///////////////////////////////////////////////////////////////////////////////////////// 0036 ///////////////// ObjectTreeItem ///////////// 0037 //////////////////////////////////////////////////////////////////////////////////////// 0038 0039 class Q_DECL_HIDDEN ObjectTreeItem::Private 0040 { 0041 public: 0042 Private(const QString &classn, const QString &name_, QWidget *widget_, 0043 Container *parentContainer_, Container *c); 0044 0045 ~Private(); 0046 0047 QString className; 0048 QString name; 0049 ObjectTreeList children; 0050 QPointer<Container> container; 0051 QHash<QString, QVariant> props; 0052 QHash<QString, QVariant> *subprops; 0053 QString unknownProps; 0054 QHash<QByteArray, QString> pixmapNames; 0055 ObjectTreeItem* parent; 0056 QPointer<QWidget> widget; 0057 QPointer<EventEater> eater; 0058 0059 bool enabled; 0060 0061 int row, col, rowspan, colspan; 0062 bool span; 0063 }; 0064 0065 ObjectTreeItem::Private::Private(const QString &classn, const QString &name_, QWidget *widget_, 0066 Container *parentContainer_, Container *c) 0067 : className(classn), name(name_), container(c) 0068 , subprops(0), parent(0), widget(widget_), eater(new EventEater(widget_, parentContainer_)) 0069 , enabled(true), row(-1), col(-1), rowspan(-1), colspan(-1), span(false) 0070 { 0071 0072 } 0073 0074 ObjectTreeItem::Private::~Private() 0075 { 0076 delete subprops; 0077 } 0078 0079 ObjectTreeItem::ObjectTreeItem(const QString &classn, const QString &name, QWidget *widget, 0080 Container *parentContainer, Container *container) 0081 : d(new Private(classn, name, widget, parentContainer, container)) 0082 { 0083 //qDebug() << classn << name << widget->objectName() << "parentContainer:" << parentContainer << "container:" << container; 0084 } 0085 0086 ObjectTreeItem::~ObjectTreeItem() 0087 { 0088 delete d; 0089 } 0090 0091 void 0092 ObjectTreeItem::rename(const QString &name) 0093 { 0094 d->name = name; 0095 } 0096 0097 void 0098 ObjectTreeItem::addChild(ObjectTreeItem *c) 0099 { 0100 d->children.append(c); 0101 c->setParent(this); 0102 } 0103 0104 void 0105 ObjectTreeItem::removeChild(ObjectTreeItem *c) 0106 { 0107 d->children.removeAt( d->children.indexOf(c) ); 0108 } 0109 0110 void 0111 ObjectTreeItem::addModifiedProperty(const QByteArray &property, const QVariant &oldValue) 0112 { 0113 if (property == "objectName") 0114 return; 0115 0116 if (!d->props.contains(property)) { 0117 d->props.insert(property, oldValue); 0118 //qDebug() << "Added this property in the list: " << property << " oldValue: " << oldValue; 0119 } 0120 } 0121 0122 void 0123 ObjectTreeItem::addSubproperty(const QByteArray &property, const QVariant& value) 0124 { 0125 if (!d->subprops) 0126 d->subprops = new QHash<QString, QVariant>(); 0127 if (!d->props.contains(property)) 0128 d->subprops->insert(property, value); 0129 } 0130 0131 void 0132 ObjectTreeItem::storeUnknownProperty(QDomElement &el) 0133 { 0134 if (!el.isNull()) { 0135 QTextStream ts(&d->unknownProps, QIODevice::WriteOnly | QIODevice::Append); 0136 el.save(ts, 0); 0137 } 0138 } 0139 0140 QString ObjectTreeItem::unknownProperties() 0141 { 0142 return d->unknownProps; 0143 } 0144 0145 void ObjectTreeItem::setUnknownProperties(const QString &set) 0146 { 0147 d->unknownProps = set; 0148 } 0149 0150 void 0151 ObjectTreeItem::setPixmapName(const QByteArray &property, const QString &name) 0152 { 0153 d->pixmapNames.insert(property, name); 0154 } 0155 0156 QString 0157 ObjectTreeItem::pixmapName(const QByteArray &property) 0158 { 0159 return d->pixmapNames.value(property); 0160 } 0161 0162 void 0163 ObjectTreeItem::setGridPos(int row, int col, int rowspan, int colspan) 0164 { 0165 d->row = row; d->col = col; 0166 d->rowspan = rowspan; 0167 d->colspan = colspan; 0168 if (colspan || rowspan) 0169 d->span = true; 0170 else 0171 d->span = false; 0172 } 0173 0174 QHash<QString, QVariant>* ObjectTreeItem::subproperties() const 0175 { 0176 return d->subprops; 0177 } 0178 0179 void ObjectTreeItem::setEnabled(bool enabled) 0180 { 0181 d->enabled = enabled; 0182 } 0183 0184 bool ObjectTreeItem::isEnabled() const 0185 { 0186 return d->enabled; 0187 } 0188 0189 int ObjectTreeItem::gridRow() const 0190 { 0191 return d->row; 0192 } 0193 0194 int ObjectTreeItem::gridCol() const 0195 { 0196 return d->col; 0197 } 0198 0199 int ObjectTreeItem::gridRowSpan() const 0200 { 0201 return d->rowspan; 0202 } 0203 0204 int ObjectTreeItem::gridColSpan() const 0205 { 0206 return d->colspan; 0207 } 0208 0209 bool ObjectTreeItem::spanMultipleCells() const 0210 { 0211 return d->span; 0212 } 0213 0214 QString ObjectTreeItem::name() const 0215 { 0216 return d->name; 0217 } 0218 0219 QString ObjectTreeItem::className() const 0220 { 0221 return d->className; 0222 } 0223 0224 QWidget* ObjectTreeItem::widget() const 0225 { 0226 return d->widget; 0227 } 0228 0229 EventEater* ObjectTreeItem::eventEater() const 0230 { 0231 return d->eater; 0232 } 0233 0234 ObjectTreeItem* ObjectTreeItem::parent() const 0235 { 0236 return d->parent; 0237 } 0238 0239 ObjectTreeList* ObjectTreeItem::children() 0240 { 0241 return &d->children; 0242 } 0243 0244 const QHash<QString, QVariant>* ObjectTreeItem::modifiedProperties() const 0245 { 0246 return &d->props; 0247 } 0248 0249 Container* ObjectTreeItem::container() const 0250 { 0251 return d->container; 0252 } 0253 0254 void ObjectTreeItem::setWidget(QWidget *w) 0255 { 0256 d->widget = w; 0257 } 0258 0259 void ObjectTreeItem::setParent(ObjectTreeItem *parent) 0260 { 0261 d->parent = parent; 0262 } 0263 0264 0265 ///////////////////////////////////////////////////////////////////////////////////////// 0266 /// ObjectTree ///////// 0267 //////////////////////////////////////////////////////////////////////////////////////// 0268 0269 class Q_DECL_HIDDEN ObjectTree::Private 0270 { 0271 public: 0272 Private() 0273 { 0274 0275 } 0276 0277 ~Private() 0278 { 0279 0280 } 0281 0282 ObjectTreeHash treeHash; 0283 }; 0284 0285 ObjectTree::ObjectTree(const QString &classn, const QString &name, QWidget *widget, Container *container) 0286 : ObjectTreeItem(classn, name, widget, container, container), d(new Private()) 0287 { 0288 } 0289 0290 ObjectTree::~ObjectTree() 0291 { 0292 while (!children()->isEmpty()) { 0293 removeItem(children()->first()); 0294 } 0295 delete d; 0296 } 0297 0298 bool 0299 ObjectTree::rename(const QString &oldname, const QString &newname) 0300 { 0301 if (oldname == name()) { 0302 ObjectTreeItem::rename(newname); 0303 return true; 0304 } 0305 0306 ObjectTreeItem *it = lookup(oldname); 0307 if (!it) 0308 return false; 0309 0310 it->rename(newname); 0311 d->treeHash.remove(oldname); 0312 d->treeHash.insert(newname, it); 0313 0314 return true; 0315 } 0316 0317 bool 0318 ObjectTree::reparent(const QString &name, const QString &newparent) 0319 { 0320 ObjectTreeItem *item = lookup(name); 0321 if (!item) return false; 0322 ObjectTreeItem *parent = lookup(newparent); 0323 if (!parent) return false; 0324 0325 item->parent()->removeChild(item); 0326 parent->addChild(item); 0327 return true; 0328 } 0329 0330 ObjectTreeItem* 0331 ObjectTree::lookup(const QString &name) 0332 { 0333 if (name == this->name()) 0334 return this; 0335 else 0336 return d->treeHash.value(name); 0337 } 0338 0339 void 0340 ObjectTree::addItem(ObjectTreeItem *parent, ObjectTreeItem *c) 0341 { 0342 d->treeHash.insert(c->name(), c); 0343 0344 if (!parent) 0345 parent = this; 0346 parent->addChild(c); 0347 container()->form()->emitChildAdded(c); 0348 0349 //qDebug() << "adding " << c->name() << " to " << parent->name(); 0350 } 0351 0352 void 0353 ObjectTree::removeItem(const QString &name) 0354 { 0355 ObjectTreeItem *c = lookup(name); 0356 removeItem(c); 0357 } 0358 0359 void 0360 ObjectTree::removeItem(ObjectTreeItem *c) 0361 { 0362 if (container() && container()->form()) 0363 container()->form()->emitChildRemoved(c); 0364 0365 foreach (ObjectTreeItem *titem, *c->children()) { 0366 removeItem(titem->name()); 0367 } 0368 0369 d->treeHash.remove(c->name()); 0370 c->parent()->removeChild(c); 0371 delete c; 0372 } 0373 0374 QByteArray 0375 ObjectTree::generateUniqueName(const QByteArray &prefix, bool numberSuffixRequired) 0376 { 0377 if (!numberSuffixRequired && !lookup(prefix)) 0378 return prefix; 0379 QString name(prefix); 0380 int i = 2; //start from 2, i.e. we have: "widget", "widget2", etc. 0381 while (lookup(name + QString::number(i))) 0382 i++; 0383 0384 return (name + QString::number(i)).toLatin1(); 0385 } 0386 0387 ObjectTreeHash* ObjectTree::hash() 0388 { 0389 return &d->treeHash; 0390 }