File indexing completed on 2024-05-12 16:39:51
0001 /* This file is part of the KDE project 0002 Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr> 0003 Copyright (C) 2007-2009 Jarosław Staniek <staniek@kde.org> 0004 0005 This library is free software; you can redistribute it and/or 0006 modify it under the terms of the GNU Library General Public 0007 License as published by the Free Software Foundation; either 0008 version 2 of the License, or (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 GNU 0013 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, write to 0017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0018 * Boston, MA 02110-1301, USA. 0019 */ 0020 0021 #include <QApplication> 0022 #include <QClipboard> 0023 #include <QDomDocument> 0024 #include <QMimeData> 0025 #include <QPen> 0026 #include <QPainter> 0027 #include <QDebug> 0028 0029 #include <kexiutils/utils.h> 0030 0031 #include "form.h" 0032 #include "formIO.h" 0033 #include "objecttree.h" 0034 #include "utils.h" 0035 0036 using namespace KFormDesigner; 0037 0038 void 0039 KFormDesigner::removeChildrenFromList(QWidgetList &list) 0040 { 0041 QSet<QWidget*> toRemove; 0042 foreach (QWidget *w, list) { 0043 // If any widget in the list is a child of this widget, we remove it from the list 0044 foreach (QWidget *widg, list) { 0045 if ((w != widg) && (w->findChild<QWidget*>(widg->objectName()))) { 0046 qDebug() << "Removing the widget " << widg->objectName() 0047 << "which is a child of " << w->objectName(); 0048 toRemove.insert(widg); 0049 } 0050 } 0051 } 0052 QSet<QWidget*> all(list.toSet()); 0053 all.subtract(toRemove); 0054 list = all.toList(); 0055 } 0056 0057 void 0058 KFormDesigner::setRecursiveCursor(QWidget *w, Form *form) 0059 { 0060 ObjectTreeItem *tree = form->objectTree()->lookup(w->objectName()); 0061 if (tree && ((tree->modifiedProperties()->contains("cursor")) || !tree->children()->isEmpty()) 0062 && !w->inherits("QLineEdit") && !w->inherits("QTextEdit")) 0063 { 0064 //fix weird behaviour 0065 return; // if the user has set a cursor for this widget or this is a container, don't change it 0066 } 0067 0068 w->setCursor(Qt::ArrowCursor); 0069 0070 const QList<QWidget*> list(w->findChildren<QWidget*>()); 0071 foreach(QWidget *widget, list) { 0072 widget->setCursor(Qt::ArrowCursor); 0073 } 0074 } 0075 0076 QSize 0077 KFormDesigner::getSizeFromChildren(QWidget *w, const char *inheritClass) 0078 { 0079 int tmpw = 0, tmph = 0; 0080 const QList<QWidget*> list(w->findChildren<QWidget*>()); 0081 foreach(QWidget *widget, list) { 0082 if (widget->inherits(inheritClass)) { 0083 tmpw = qMax(tmpw, widget->geometry().right()); 0084 tmph = qMax(tmph, widget->geometry().bottom()); 0085 } 0086 } 0087 return QSize(tmpw, tmph) + QSize(10, 10); 0088 } 0089 0090 // ----------------- 0091 0092 class HorizontalWidgetList::LessThan 0093 { 0094 public: 0095 explicit LessThan(QWidget *topLevelWidget) 0096 : m_topLevelWidget(topLevelWidget) 0097 { 0098 } 0099 bool operator()(QWidget *w1, QWidget *w2) { 0100 return w1->mapTo(m_topLevelWidget, QPoint(0, 0)).x() 0101 - w2->mapTo(m_topLevelWidget, QPoint(0, 0)).x(); 0102 } 0103 QWidget *m_topLevelWidget; 0104 }; 0105 0106 HorizontalWidgetList::HorizontalWidgetList(QWidget *topLevelWidget) 0107 : CustomSortableWidgetList() 0108 , m_lessThan(new LessThan(topLevelWidget)) 0109 { 0110 } 0111 0112 HorizontalWidgetList::HorizontalWidgetList(const HorizontalWidgetList& list) 0113 : CustomSortableWidgetList(list) 0114 , m_lessThan(new LessThan(list.m_lessThan->m_topLevelWidget)) 0115 { 0116 } 0117 0118 0119 HorizontalWidgetList::~HorizontalWidgetList() 0120 { 0121 delete m_lessThan; 0122 } 0123 0124 void HorizontalWidgetList::sort() 0125 { 0126 std::sort(begin(), end(), *m_lessThan); 0127 } 0128 0129 // ----------------- 0130 0131 class VerticalWidgetList::LessThan 0132 { 0133 public: 0134 explicit LessThan(QWidget *topLevelWidget) 0135 : m_topLevelWidget(topLevelWidget) 0136 { 0137 } 0138 bool operator()(QWidget *w1, QWidget *w2) 0139 { 0140 int y1, y2; 0141 QObject *page1 = 0; 0142 TabWidget *tw1 = KFormDesigner::findParent<KFormDesigner::TabWidget>( 0143 w1, "KFormDesigner::TabWidget", page1); 0144 if (tw1) // special case 0145 y1 = w1->mapTo(m_topLevelWidget, QPoint(0, 0)).y() + tw1->tabBarHeight() - 2 - 2; 0146 else 0147 y1 = w1->mapTo(m_topLevelWidget, QPoint(0, 0)).y(); 0148 0149 QObject *page2 = 0; 0150 TabWidget *tw2 = KFormDesigner::findParent<KFormDesigner::TabWidget>( 0151 w2, "KFormDesigner::TabWidget", page2); 0152 if (tw1 && tw2 && tw1 == tw2 && page1 != page2) { 0153 // this sorts widgets by tabs there're put in 0154 return tw1->indexOf(static_cast<QWidget*>(page1)) < tw2->indexOf(static_cast<QWidget*>(page2)); 0155 } 0156 0157 if (tw2) // special case 0158 y2 = w2->mapTo(m_topLevelWidget, QPoint(0, 0)).y() + tw2->tabBarHeight() - 2 - 2; 0159 else 0160 y2 = w2->mapTo(m_topLevelWidget, QPoint(0, 0)).y(); 0161 0162 qDebug() << w1->objectName() << ": " << y1 << " " 0163 << " | " << w2->objectName() << ": " << y2; 0164 0165 0166 //qDebug() << w1->name() << ": " << w1->mapTo(m_topLevelWidget, QPoint(0,0)) << " " << w1->y() 0167 //<< " | " << w2->name() << ":" /*<< w2->mapFrom(m_topLevelWidget, QPoint(0,w2->y()))*/ << " " << w2->y(); 0168 return y1 < y2; 0169 } 0170 QWidget *m_topLevelWidget; 0171 }; 0172 0173 VerticalWidgetList::VerticalWidgetList(QWidget *topLevelWidget) 0174 : CustomSortableWidgetList() 0175 , m_lessThan(new LessThan(topLevelWidget)) 0176 { 0177 } 0178 0179 VerticalWidgetList::VerticalWidgetList(const VerticalWidgetList& list) 0180 : CustomSortableWidgetList(list) 0181 , m_lessThan(new LessThan(list.m_lessThan->m_topLevelWidget)) 0182 { 0183 } 0184 0185 VerticalWidgetList::~VerticalWidgetList() 0186 { 0187 delete m_lessThan; 0188 } 0189 0190 void VerticalWidgetList::sort() 0191 { 0192 std::sort(begin(), end(), *m_lessThan); 0193 } 0194 0195 // ---- 0196 0197 QMimeData *KFormDesigner::deepCopyOfMimeData(const QMimeData *data) 0198 { 0199 QMimeData *newData = new QMimeData(); 0200 foreach(const QString& format, data->formats()) { 0201 newData->setData(format, data->data(format)); 0202 } 0203 return newData; 0204 } 0205 0206 void KFormDesigner::copyToClipboard(const QString& xml) 0207 { 0208 //qDebug() << xml; 0209 QMimeData *data = new QMimeData(); 0210 data->setText(xml); 0211 data->setData(KFormDesigner::mimeType(), xml.toUtf8()); 0212 QClipboard *cb = QApplication::clipboard(); 0213 cb->setMimeData(data); 0214 } 0215 0216 void KFormDesigner::widgetsToXML(QDomDocument& doc, 0217 QHash<QByteArray, QByteArray>& containers, 0218 QHash<QByteArray, QByteArray>& parents, 0219 const Form& form, const QWidgetList &list) 0220 { 0221 containers.clear(); 0222 parents.clear(); 0223 doc = QDomDocument("UI"); 0224 doc.appendChild(doc.createElement("UI")); 0225 QDomElement parent = doc.firstChildElement("UI"); 0226 0227 QWidgetList topLevelList(list); 0228 KFormDesigner::removeChildrenFromList(topLevelList); 0229 0230 foreach (QWidget *w, topLevelList) { 0231 ObjectTreeItem *item = form.objectTree()->lookup(w->objectName()); 0232 if (!item) 0233 return; 0234 Container *c = form.parentContainer(item->widget()); 0235 if (!c) 0236 return; 0237 0238 // We need to store both parentContainer and parentWidget as they may be different (eg for TabWidget page) 0239 containers.insert( 0240 item->name().toLatin1(), 0241 c->widget()->objectName().toLatin1() 0242 ); 0243 parents.insert( 0244 item->name().toLatin1(), 0245 item->parent()->name().toLatin1() 0246 ); 0247 FormIO::saveWidget(item, parent, doc); 0248 #ifdef KFD_SIGSLOTS 0249 form.connectionBuffer()->saveAllConnectionsForWidget( 0250 item->widget()->objectName(), doc); 0251 #endif 0252 } 0253 0254 FormIO::cleanClipboard(parent); 0255 } 0256 0257 //----------------------------- 0258 0259 class Q_DECL_HIDDEN ActionGroup::Private { 0260 public: 0261 Private() {} 0262 QHash<QString, QAction*> actions; 0263 }; 0264 0265 ActionGroup::ActionGroup( QObject * parent ) 0266 : QActionGroup(parent) 0267 , d( new Private ) 0268 { 0269 } 0270 0271 ActionGroup::~ActionGroup() 0272 { 0273 delete d; 0274 } 0275 0276 void ActionGroup::addAction(QAction* action) 0277 { 0278 QActionGroup::addAction(action); 0279 d->actions.insert(action->objectName(), action); 0280 } 0281 0282 QAction *ActionGroup::action(const QString& name) const 0283 { 0284 return d->actions.value(name); 0285 } 0286 0287 //----------------------------- 0288 0289 int KFormDesigner::alignValueToGrid(int value, int gridSize) 0290 { 0291 if ((value % gridSize * 2) < gridSize) 0292 return value / gridSize * gridSize; 0293 return (value / gridSize + 1) * gridSize; 0294 } 0295 0296 //----------------------------- 0297 0298 void KFormDesigner::paintWidgetFrame(QPainter& p, const QRect& geometry) 0299 { 0300 QColor c1(Qt::white); 0301 c1.setAlpha(100); 0302 QColor c2(Qt::black); 0303 c2.setAlpha(100); 0304 QRect r(geometry); 0305 r.setWidth(r.width()-1); 0306 r.setHeight(r.height()-1); 0307 QPen pen1(c1, 1, Qt::DashLine); 0308 QPen pen2(c2, 1, Qt::DashLine); 0309 p.setPen(pen1); 0310 p.drawRect(r); 0311 p.setPen(pen2); 0312 p.drawRect(r); 0313 } 0314