source: trunk/tools/designer/src/lib/uilib/formbuilderextra.cpp@ 385

Last change on this file since 385 was 2, checked in by Dmitry A. Kuminov, 17 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 17.2 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the Qt Designer of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "formbuilderextra_p.h"
43#include "abstractformbuilder.h"
44#include "resourcebuilder_p.h"
45#include "textbuilder_p.h"
46#include "ui4_p.h"
47
48#include <QtGui/QLabel>
49#include <QtGui/QBoxLayout>
50#include <QtGui/QGridLayout>
51
52#include <QtCore/QVariant>
53#include <QtCore/qdebug.h>
54#include <QtCore/QTextStream>
55#include <QtCore/QStringList>
56#include <QtCore/QCoreApplication>
57
58QT_BEGIN_NAMESPACE
59
60#ifdef QFORMINTERNAL_NAMESPACE
61namespace QFormInternal {
62#endif
63
64void uiLibWarning(const QString &message) {
65 qWarning("Designer: %s", qPrintable(message));
66}
67
68QFormBuilderExtra::QFormBuilderExtra() :
69 m_layoutWidget(false),
70 m_resourceBuilder(0),
71 m_textBuilder(0)
72{
73}
74
75QFormBuilderExtra::~QFormBuilderExtra()
76{
77 clearResourceBuilder();
78 clearTextBuilder();
79}
80
81void QFormBuilderExtra::clear()
82{
83 m_buddies.clear();
84 m_rootWidget = 0;
85#ifndef QT_FORMBUILDER_NO_SCRIPT
86 m_FormScriptRunner.clearErrors();
87 m_customWidgetScriptHash.clear();
88#endif
89 m_buttonGroups.clear();
90}
91
92
93bool QFormBuilderExtra::applyPropertyInternally(QObject *o, const QString &propertyName, const QVariant &value)
94{
95 // Store buddies and apply them later on as the widgets might not exist yet.
96 QLabel *label = qobject_cast<QLabel*>(o);
97 if (!label || propertyName != QFormBuilderStrings::instance().buddyProperty)
98 return false;
99
100 m_buddies.insert(label, value.toString());
101 return true;
102}
103
104void QFormBuilderExtra::applyInternalProperties() const
105{
106 if (m_buddies.empty())
107 return;
108
109 const BuddyHash::const_iterator cend = m_buddies.constEnd();
110 for (BuddyHash::const_iterator it = m_buddies.constBegin(); it != cend; ++it )
111 applyBuddy(it.value(), BuddyApplyAll, it.key());
112}
113
114bool QFormBuilderExtra::applyBuddy(const QString &buddyName, BuddyMode applyMode, QLabel *label)
115{
116 if (buddyName.isEmpty()) {
117 label->setBuddy(0);
118 return false;
119 }
120
121 const QWidgetList widgets = qFindChildren<QWidget*>(label->topLevelWidget(), buddyName);
122 if (widgets.empty()) {
123 label->setBuddy(0);
124 return false;
125 }
126
127 const QWidgetList::const_iterator cend = widgets.constEnd();
128 for ( QWidgetList::const_iterator it = widgets.constBegin(); it != cend; ++it) {
129 if (applyMode == BuddyApplyAll || !(*it)->isHidden()) {
130 label->setBuddy(*it);
131 return true;
132 }
133 }
134
135 label->setBuddy(0);
136 return false;
137}
138
139const QPointer<QWidget> &QFormBuilderExtra::rootWidget() const
140{
141 return m_rootWidget;
142}
143
144void QFormBuilderExtra::setRootWidget(const QPointer<QWidget> &w)
145{
146 m_rootWidget = w;
147}
148
149#ifndef QT_FORMBUILDER_NO_SCRIPT
150QFormScriptRunner &QFormBuilderExtra::formScriptRunner()
151{
152 return m_FormScriptRunner;
153}
154
155void QFormBuilderExtra::storeCustomWidgetScript(const QString &className, const QString &script)
156{
157 m_customWidgetScriptHash.insert(className, script);
158}
159
160QString QFormBuilderExtra::customWidgetScript(const QString &className) const
161{
162 const CustomWidgetScriptHash::const_iterator it = m_customWidgetScriptHash.constFind(className);
163 if ( it == m_customWidgetScriptHash.constEnd())
164 return QString();
165 return it.value();
166}
167
168#endif
169
170void QFormBuilderExtra::storeCustomWidgetBaseClass(const QString &className, const QString &baseClassName)
171{
172 m_customWidgetBaseClassHash.insert(className, baseClassName);
173}
174
175QString QFormBuilderExtra::customWidgetBaseClass(const QString &className) const
176{
177 const QHash<QString, QString>::const_iterator it = m_customWidgetBaseClassHash.constFind(className);
178 if (it == m_customWidgetBaseClassHash.constEnd())
179 return QString();
180 return it.value();
181}
182
183void QFormBuilderExtra::storeCustomWidgetAddPageMethod(const QString &className, const QString &ct)
184{
185 m_customWidgetAddPageMethodHash.insert(className, ct);
186}
187
188QString QFormBuilderExtra::customWidgetAddPageMethod(const QString &className) const
189{
190 const QHash<QString, QString>::const_iterator it = m_customWidgetAddPageMethodHash.constFind(className);
191 if (it == m_customWidgetAddPageMethodHash.constEnd())
192 return QString();
193 return it.value();
194}
195
196namespace {
197 typedef QHash<const QAbstractFormBuilder *, QFormBuilderExtra *> FormBuilderPrivateHash;
198}
199
200Q_GLOBAL_STATIC(FormBuilderPrivateHash, g_FormBuilderPrivateHash)
201
202QFormBuilderExtra *QFormBuilderExtra::instance(const QAbstractFormBuilder *afb)
203{
204 FormBuilderPrivateHash &fbHash = *g_FormBuilderPrivateHash();
205
206 FormBuilderPrivateHash::iterator it = fbHash.find(afb);
207 if (it == fbHash.end())
208 it = fbHash.insert(afb, new QFormBuilderExtra);
209 return it.value();
210}
211
212void QFormBuilderExtra::removeInstance(const QAbstractFormBuilder *afb)
213{
214 FormBuilderPrivateHash &fbHash = *g_FormBuilderPrivateHash();
215
216 FormBuilderPrivateHash::iterator it = fbHash.find(afb);
217 if (it != fbHash.end()) {
218 delete it.value();
219 fbHash.erase(it);
220 }
221}
222
223void QFormBuilderExtra::setProcessingLayoutWidget(bool processing)
224{
225 m_layoutWidget = processing;
226}
227
228 bool QFormBuilderExtra::processingLayoutWidget() const
229{
230 return m_layoutWidget;
231}
232void QFormBuilderExtra::setResourceBuilder(QResourceBuilder *builder)
233{
234 if (m_resourceBuilder == builder)
235 return;
236 clearResourceBuilder();
237 m_resourceBuilder = builder;
238}
239
240QResourceBuilder *QFormBuilderExtra::resourceBuilder() const
241{
242 return m_resourceBuilder;
243}
244
245void QFormBuilderExtra::clearResourceBuilder()
246{
247 if (m_resourceBuilder) {
248 delete m_resourceBuilder;
249 m_resourceBuilder = 0;
250 }
251}
252
253void QFormBuilderExtra::setTextBuilder(QTextBuilder *builder)
254{
255 if (m_textBuilder == builder)
256 return;
257 clearTextBuilder();
258 m_textBuilder = builder;
259}
260
261QTextBuilder *QFormBuilderExtra::textBuilder() const
262{
263 return m_textBuilder;
264}
265
266void QFormBuilderExtra::clearTextBuilder()
267{
268 if (m_textBuilder) {
269 delete m_textBuilder;
270 m_textBuilder = 0;
271 }
272}
273
274void QFormBuilderExtra::registerButtonGroups(const DomButtonGroups *domGroups)
275{
276 typedef QList<DomButtonGroup*> DomButtonGroupList;
277 const DomButtonGroupList domGroupList = domGroups->elementButtonGroup();
278 const DomButtonGroupList::const_iterator cend = domGroupList.constEnd();
279 for (DomButtonGroupList::const_iterator it = domGroupList.constBegin(); it != cend; ++it) {
280 DomButtonGroup *domGroup = *it;
281 m_buttonGroups.insert(domGroup->attributeName(), ButtonGroupEntry(domGroup, 0));
282 }
283}
284
285// Utilities for parsing per-cell integer properties that have setters and
286// getters of the form 'setX(int idx, int value)' and 'x(int index)'
287// (converting them to comma-separated string lists and back).
288// Used for layout stretch and grid per-row/column properties.
289
290// Format a list of cell-properties of one dimension as a ','-separated list
291template <class Layout>
292inline QString perCellPropertyToString(const Layout *l, int count, int (Layout::*getter)(int) const)
293{
294 if (count == 0)
295 return QString();
296 QString rc;
297 {
298 QTextStream str(&rc);
299 for (int i = 0; i < count; i++) {
300 if (i)
301 str << QLatin1Char(',');
302 str << (l->*getter)(i);
303 }
304 }
305 return rc;
306}
307
308// Clear the property, set all cells to 0
309
310template <class Layout>
311inline void clearPerCellValue(Layout *l, int count, void (Layout::*setter)(int,int), int value = 0)
312{
313 for (int i = 0; i < count; i++)
314 (l->*setter)(i, value);
315}
316
317// Parse and set the property from a comma-separated list
318
319template <class Layout>
320inline bool parsePerCellProperty(Layout *l, int count, void (Layout::*setter)(int,int), const QString &s, int defaultValue = 0)
321{
322 if (s.isEmpty()) {
323 clearPerCellValue(l, count, setter, defaultValue);
324 return true;
325 }
326 const QStringList list = s.split(QLatin1Char(','));
327 if (list.empty()) {
328 clearPerCellValue(l, count, setter, defaultValue);
329 return true;
330 }
331 // Apply all values contained in list
332 const int ac = qMin(count, list.size());
333 bool ok;
334 int i = 0;
335 for ( ; i < ac; i++) {
336 const int value = list.at(i).toInt(&ok);
337 if (!ok || value < 0)
338 return false;
339 (l->*setter)(i, value);
340 }
341 // Clear rest
342 for ( ; i < count; i++)
343 (l->*setter)(i, defaultValue);
344 return true;
345}
346
347// Read and write stretch
348static QString msgInvalidStretch(const QString &objectName, const QString &stretch)
349{
350 //: Parsing layout stretch values
351 return QCoreApplication::translate("FormBuilder", "Invalid stretch value for '%1': '%2'").arg(objectName, stretch);
352}
353
354QString QFormBuilderExtra::boxLayoutStretch(const QBoxLayout *box)
355{
356 return perCellPropertyToString(box, box->count(), &QBoxLayout::stretch);
357}
358
359bool QFormBuilderExtra::setBoxLayoutStretch(const QString &s, QBoxLayout *box)
360{
361 const bool rc = parsePerCellProperty(box, box->count(), &QBoxLayout::setStretch, s);
362 if (!rc)
363 uiLibWarning(msgInvalidStretch(box->objectName(), s));
364 return rc;
365}
366
367void QFormBuilderExtra::clearBoxLayoutStretch(QBoxLayout *box)
368{
369 clearPerCellValue(box, box->count(), &QBoxLayout::setStretch);
370}
371
372QString QFormBuilderExtra::gridLayoutRowStretch(const QGridLayout *grid)
373{
374 return perCellPropertyToString(grid, grid->rowCount(), &QGridLayout::rowStretch);
375}
376
377bool QFormBuilderExtra::setGridLayoutRowStretch(const QString &s, QGridLayout *grid)
378{
379 const bool rc = parsePerCellProperty(grid, grid->rowCount(), &QGridLayout::setRowStretch, s);
380 if (!rc)
381 uiLibWarning(msgInvalidStretch(grid->objectName(), s));
382 return rc;
383}
384
385void QFormBuilderExtra::clearGridLayoutRowStretch(QGridLayout *grid)
386{
387 clearPerCellValue(grid, grid->rowCount(), &QGridLayout::setRowStretch);
388}
389
390QString QFormBuilderExtra::gridLayoutColumnStretch(const QGridLayout *grid)
391{
392 return perCellPropertyToString(grid, grid->columnCount(), &QGridLayout::columnStretch);
393}
394
395bool QFormBuilderExtra::setGridLayoutColumnStretch(const QString &s, QGridLayout *grid)
396{
397 const bool rc = parsePerCellProperty(grid, grid->columnCount(), &QGridLayout::setColumnStretch, s);
398 if (!rc)
399 uiLibWarning(msgInvalidStretch(grid->objectName(), s));
400 return rc;
401}
402
403void QFormBuilderExtra::clearGridLayoutColumnStretch(QGridLayout *grid)
404{
405 clearPerCellValue(grid, grid->columnCount(), &QGridLayout::setColumnStretch);
406}
407
408// Read and write grid layout row/column size limits
409
410static QString msgInvalidMinimumSize(const QString &objectName, const QString &ms)
411{
412 //: Parsing grid layout minimum size values
413 return QCoreApplication::translate("FormBuilder", "Invalid minimum size for '%1': '%2'").arg(objectName, ms);
414}
415
416QString QFormBuilderExtra::gridLayoutRowMinimumHeight(const QGridLayout *grid)
417{
418 return perCellPropertyToString(grid, grid->rowCount(), &QGridLayout::rowMinimumHeight);
419}
420
421bool QFormBuilderExtra::setGridLayoutRowMinimumHeight(const QString &s, QGridLayout *grid)
422{
423 const bool rc = parsePerCellProperty(grid, grid->rowCount(), &QGridLayout::setRowMinimumHeight, s);
424 if (!rc)
425 uiLibWarning(msgInvalidMinimumSize(grid->objectName(), s));
426 return rc;
427}
428
429void QFormBuilderExtra::clearGridLayoutRowMinimumHeight(QGridLayout *grid)
430{
431 clearPerCellValue(grid, grid->rowCount(), &QGridLayout::setRowMinimumHeight);
432}
433
434QString QFormBuilderExtra::gridLayoutColumnMinimumWidth(const QGridLayout *grid)
435{
436 return perCellPropertyToString(grid, grid->columnCount(), &QGridLayout::columnMinimumWidth);
437}
438
439bool QFormBuilderExtra::setGridLayoutColumnMinimumWidth(const QString &s, QGridLayout *grid)
440{
441 const bool rc = parsePerCellProperty(grid, grid->columnCount(), &QGridLayout::setColumnMinimumWidth, s);
442 if (!rc)
443 uiLibWarning(msgInvalidMinimumSize(grid->objectName(), s));
444 return rc;
445}
446
447void QFormBuilderExtra::clearGridLayoutColumnMinimumWidth(QGridLayout *grid)
448{
449 clearPerCellValue(grid, grid->columnCount(), &QGridLayout::setColumnMinimumWidth);
450}
451
452// ------------ QFormBuilderStrings
453
454QFormBuilderStrings::QFormBuilderStrings() :
455 buddyProperty(QLatin1String("buddy")),
456 cursorProperty(QLatin1String("cursor")),
457 objectNameProperty(QLatin1String("objectName")),
458 trueValue(QLatin1String("true")),
459 falseValue(QLatin1String("false")),
460 horizontalPostFix(QLatin1String("Horizontal")),
461 separator(QLatin1String("separator")),
462 defaultTitle(QLatin1String("Page")),
463 titleAttribute(QLatin1String("title")),
464 labelAttribute(QLatin1String("label")),
465 toolTipAttribute(QLatin1String("toolTip")),
466 whatsThisAttribute(QLatin1String("whatsThis")),
467 flagsAttribute(QLatin1String("flags")),
468 iconAttribute(QLatin1String("icon")),
469 pixmapAttribute(QLatin1String("pixmap")),
470 textAttribute(QLatin1String("text")),
471 currentIndexProperty(QLatin1String("currentIndex")),
472 toolBarAreaAttribute(QLatin1String("toolBarArea")),
473 toolBarBreakAttribute(QLatin1String("toolBarBreak")),
474 dockWidgetAreaAttribute(QLatin1String("dockWidgetArea")),
475 marginProperty(QLatin1String("margin")),
476 spacingProperty(QLatin1String("spacing")),
477 leftMarginProperty(QLatin1String("leftMargin")),
478 topMarginProperty(QLatin1String("topMargin")),
479 rightMarginProperty(QLatin1String("rightMargin")),
480 bottomMarginProperty(QLatin1String("bottomMargin")),
481 horizontalSpacingProperty(QLatin1String("horizontalSpacing")),
482 verticalSpacingProperty(QLatin1String("verticalSpacing")),
483 sizeHintProperty(QLatin1String("sizeHint")),
484 sizeTypeProperty(QLatin1String("sizeType")),
485 orientationProperty(QLatin1String("orientation")),
486 styleSheetProperty(QLatin1String("styleSheet")),
487 qtHorizontal(QLatin1String("Qt::Horizontal")),
488 qtVertical(QLatin1String("Qt::Vertical")),
489 currentRowProperty(QLatin1String("currentRow")),
490 tabSpacingProperty(QLatin1String("tabSpacing")),
491 qWidgetClass(QLatin1String("QWidget")),
492 lineClass(QLatin1String("Line")),
493 geometryProperty(QLatin1String("geometry")),
494 scriptWidgetVariable(QLatin1String("widget")),
495 scriptChildWidgetsVariable(QLatin1String("childWidgets"))
496{
497 itemRoles.append(qMakePair(Qt::FontRole, QString::fromLatin1("font")));
498 itemRoles.append(qMakePair(Qt::TextAlignmentRole, QString::fromLatin1("textAlignment")));
499 itemRoles.append(qMakePair(Qt::BackgroundRole, QString::fromLatin1("background")));
500 itemRoles.append(qMakePair(Qt::ForegroundRole, QString::fromLatin1("foreground")));
501 itemRoles.append(qMakePair(Qt::CheckStateRole, QString::fromLatin1("checkState")));
502
503 foreach (const RoleNName &it, itemRoles)
504 treeItemRoleHash.insert(it.second, it.first);
505
506 itemTextRoles.append(qMakePair(qMakePair(Qt::EditRole, Qt::DisplayPropertyRole),
507 textAttribute)); // This must be first for the loop below
508 itemTextRoles.append(qMakePair(qMakePair(Qt::ToolTipRole, Qt::ToolTipPropertyRole),
509 toolTipAttribute));
510 itemTextRoles.append(qMakePair(qMakePair(Qt::StatusTipRole, Qt::StatusTipPropertyRole),
511 QString::fromLatin1("statusTip")));
512 itemTextRoles.append(qMakePair(qMakePair(Qt::WhatsThisRole, Qt::WhatsThisPropertyRole),
513 whatsThisAttribute));
514
515 // Note: this skips the first item!
516 QList<TextRoleNName>::const_iterator it = itemTextRoles.constBegin(), end = itemTextRoles.constEnd();
517 while (++it != end)
518 treeItemTextRoleHash.insert(it->second, it->first);
519}
520
521const QFormBuilderStrings &QFormBuilderStrings::instance()
522{
523 static const QFormBuilderStrings rc;
524 return rc;
525}
526
527#ifdef QFORMINTERNAL_NAMESPACE
528} // namespace QFormInternal
529#endif
530
531QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.