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 }