1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the Qt Designer of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file.  Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "designerpropertymanager.h"
43 #include "qtpropertymanager.h"
44 #include "paletteeditorbutton.h"
45 #include "qlonglongvalidator.h"
46 #include "stringlisteditorbutton.h"
47 #include "qtresourceview_p.h"
48 #include "qtpropertybrowserutils_p.h"
49 
50 #include <formwindowbase_p.h>
51 #include <textpropertyeditor_p.h>
52 #include <stylesheeteditor_p.h>
53 #include <richtexteditor_p.h>
54 #include <plaintexteditor_p.h>
55 #include <iconloader_p.h>
56 #include <iconselector_p.h>
57 #include <abstractdialoggui_p.h>
58 
59 #include <QtDesigner/QDesignerIconCacheInterface>
60 
61 #include <QtGui/QLabel>
62 #include <QtGui/QToolButton>
63 #include <QtGui/QHBoxLayout>
64 #include <QtCore/QFileInfo>
65 #include <QtGui/QClipboard>
66 #include <QtGui/QLineEdit>
67 #include <QtGui/QDialogButtonBox>
68 #include <QtGui/QPushButton>
69 #include <QtGui/QFileDialog>
70 #include <QtGui/QAction>
71 #include <QtGui/QMenu>
72 #include <QtGui/QContextMenuEvent>
73 #include <QtGui/QApplication>
74 #include <QtCore/QUrl>
75 
76 #include <QtCore/QDebug>
77 
78 QT_BEGIN_NAMESPACE
79 
80 static const char *resettableAttributeC = "resettable";
81 static const char *flagsAttributeC = "flags";
82 static const char *validationModesAttributeC = "validationMode";
83 static const char *superPaletteAttributeC = "superPalette";
84 static const char *defaultResourceAttributeC = "defaultResource";
85 static const char *fontAttributeC = "font";
86 static const char *themeAttributeC = "theme";
87 
88 class DesignerFlagPropertyType
89 {
90 };
91 
92 
93 class DesignerAlignmentPropertyType
94 {
95 };
96 
97 QT_END_NAMESPACE
98 
99 Q_DECLARE_METATYPE(DesignerFlagPropertyType)
100 Q_DECLARE_METATYPE(DesignerAlignmentPropertyType)
101 
102 QT_BEGIN_NAMESPACE
103 
104 namespace qdesigner_internal {
105 
106 // ------------ TextEditor
107 class TextEditor : public QWidget
108 {
109     Q_OBJECT
110 public:
111     TextEditor(QDesignerFormEditorInterface *core, QWidget *parent);
112 
113     TextPropertyValidationMode textPropertyValidationMode() const;
114     void setTextPropertyValidationMode(TextPropertyValidationMode vm);
115 
setRichTextDefaultFont(const QFont & font)116     void setRichTextDefaultFont(const QFont &font) { m_richTextDefaultFont = font; }
richTextDefaultFont() const117     QFont richTextDefaultFont() const { return m_richTextDefaultFont; }
118 
119     void setSpacing(int spacing);
120 
updateMode() const121     TextPropertyEditor::UpdateMode updateMode() const     { return m_editor->updateMode(); }
setUpdateMode(TextPropertyEditor::UpdateMode um)122     void setUpdateMode(TextPropertyEditor::UpdateMode um) { m_editor->setUpdateMode(um); }
123 
124     void setIconThemeModeEnabled(bool enable);
125 
126 public slots:
127     void setText(const QString &text);
128 
129 signals:
130     void textChanged(const QString &text);
131 
132 private slots:
133     void buttonClicked();
134     void resourceActionActivated();
135     void fileActionActivated();
136 private:
137     TextPropertyEditor *m_editor;
138     IconThemeEditor *m_themeEditor;
139     bool m_iconThemeModeEnabled;
140     QFont m_richTextDefaultFont;
141     QToolButton *m_button;
142     QMenu *m_menu;
143     QAction *m_resourceAction;
144     QAction *m_fileAction;
145     QHBoxLayout *m_layout;
146     QDesignerFormEditorInterface *m_core;
147 };
148 
TextEditor(QDesignerFormEditorInterface * core,QWidget * parent)149 TextEditor::TextEditor(QDesignerFormEditorInterface *core, QWidget *parent) :
150     QWidget(parent),
151     m_editor(new TextPropertyEditor(this)),
152     m_themeEditor(new IconThemeEditor(this, false)),
153     m_iconThemeModeEnabled(false),
154     m_richTextDefaultFont(QApplication::font()),
155     m_button(new QToolButton(this)),
156     m_menu(new QMenu(this)),
157     m_resourceAction(new QAction(tr("Choose Resource..."), this)),
158     m_fileAction(new QAction(tr("Choose File..."), this)),
159     m_layout(new QHBoxLayout(this)),
160     m_core(core)
161 {
162     m_themeEditor->setVisible(false);
163     m_button->setVisible(false);
164 
165     m_layout->addWidget(m_editor);
166     m_layout->addWidget(m_themeEditor);
167     m_button->setText(tr("..."));
168     m_button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored);
169     m_button->setFixedWidth(20);
170     m_layout->addWidget(m_button);
171     m_layout->setMargin(0);
172     m_layout->setSpacing(0);
173 
174     connect(m_resourceAction, SIGNAL(triggered()), this, SLOT(resourceActionActivated()));
175     connect(m_fileAction, SIGNAL(triggered()), this, SLOT(fileActionActivated()));
176     connect(m_editor, SIGNAL(textChanged(QString)), this, SIGNAL(textChanged(QString)));
177     connect(m_themeEditor, SIGNAL(edited(QString)), this, SIGNAL(textChanged(QString)));
178     connect(m_button, SIGNAL(clicked()), this, SLOT(buttonClicked()));
179 
180     setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed));
181     setFocusProxy(m_editor);
182 
183     m_menu->addAction(m_resourceAction);
184     m_menu->addAction(m_fileAction);
185 }
186 
setSpacing(int spacing)187 void TextEditor::setSpacing(int spacing)
188 {
189     m_layout->setSpacing(spacing);
190 }
191 
setIconThemeModeEnabled(bool enable)192 void TextEditor::setIconThemeModeEnabled(bool enable)
193 {
194     if (m_iconThemeModeEnabled == enable)
195         return; // nothing changes
196     m_iconThemeModeEnabled = enable;
197     m_editor->setVisible(!enable);
198     m_themeEditor->setVisible(enable);
199     if (enable) {
200         m_themeEditor->setTheme(m_editor->text());
201         setFocusProxy(m_themeEditor);
202     } else {
203         m_editor->setText(m_themeEditor->theme());
204         setFocusProxy(m_editor);
205     }
206 }
207 
textPropertyValidationMode() const208 TextPropertyValidationMode TextEditor::textPropertyValidationMode() const
209 {
210     return m_editor->textPropertyValidationMode();
211 }
212 
setTextPropertyValidationMode(TextPropertyValidationMode vm)213 void TextEditor::setTextPropertyValidationMode(TextPropertyValidationMode vm)
214 {
215     m_editor->setTextPropertyValidationMode(vm);
216     if (vm == ValidationURL) {
217         m_button->setMenu(m_menu);
218         m_button->setFixedWidth(30);
219         m_button->setPopupMode(QToolButton::MenuButtonPopup);
220     } else {
221         m_button->setMenu(0);
222         m_button->setFixedWidth(20);
223         m_button->setPopupMode(QToolButton::DelayedPopup);
224     }
225     m_button->setVisible(vm == ValidationStyleSheet || vm == ValidationRichText || vm == ValidationMultiLine || vm == ValidationURL);
226 }
227 
setText(const QString & text)228 void TextEditor::setText(const QString &text)
229 {
230     if (m_iconThemeModeEnabled)
231         m_themeEditor->setTheme(text);
232     else
233         m_editor->setText(text);
234 }
235 
buttonClicked()236 void TextEditor::buttonClicked()
237 {
238     const QString oldText = m_editor->text();
239     QString newText;
240     switch (textPropertyValidationMode()) {
241     case ValidationStyleSheet: {
242         StyleSheetEditorDialog dlg(m_core, this);
243         dlg.setText(oldText);
244         if (dlg.exec() != QDialog::Accepted)
245             return;
246         newText = dlg.text();
247     }
248         break;
249     case ValidationRichText: {
250         RichTextEditorDialog dlg(m_core, this);
251         dlg.setDefaultFont(m_richTextDefaultFont);
252         dlg.setText(oldText);
253         if (dlg.showDialog() != QDialog::Accepted)
254             return;
255         newText = dlg.text(Qt::AutoText);
256     }
257         break;
258     case ValidationMultiLine: {
259         PlainTextEditorDialog dlg(m_core, this);
260         dlg.setDefaultFont(m_richTextDefaultFont);
261         dlg.setText(oldText);
262         if (dlg.showDialog() != QDialog::Accepted)
263             return;
264         newText = dlg.text();
265     }
266         break;
267     case ValidationURL: {
268         QString oldPath = oldText;
269         if (oldPath.isEmpty() || oldPath.startsWith(QLatin1String("qrc:")))
270             resourceActionActivated();
271         else
272             fileActionActivated();
273     }
274         return;
275     default:
276         return;
277     }
278     if (newText != oldText) {
279         m_editor->setText(newText);
280         emit textChanged(newText);
281     }
282 }
283 
resourceActionActivated()284 void TextEditor::resourceActionActivated()
285 {
286     QString oldPath = m_editor->text();
287     if (oldPath.startsWith(QLatin1String("qrc:")))
288         oldPath.remove(0, 4);
289     // returns ':/file'
290     QString newPath = IconSelector::choosePixmapResource(m_core, m_core->resourceModel(), oldPath, this);
291     if (newPath.startsWith(QLatin1Char(':')))
292          newPath.remove(0, 1);
293     if (newPath.isEmpty() || newPath == oldPath)
294         return;
295     const QString newText = QLatin1String("qrc:") + newPath;
296     m_editor->setText(newText);
297     emit textChanged(newText);
298 }
299 
fileActionActivated()300 void TextEditor::fileActionActivated()
301 {
302     QString oldPath = m_editor->text();
303     if (oldPath.startsWith(QLatin1String("file:")))
304         oldPath = oldPath.mid(5);
305     const QString newPath = m_core->dialogGui()->getOpenFileName(this, tr("Choose a File"), oldPath);
306     if (newPath.isEmpty() || newPath == oldPath)
307         return;
308     const QString newText = QUrl::fromLocalFile(newPath).toString();
309     m_editor->setText(newText);
310     emit textChanged(newText);
311 }
312 
313 // ------------ ThemeInputDialog
314 
315 class IconThemeDialog : public QDialog
316 {
317     Q_OBJECT
318 public:
319     static QString getTheme(QWidget *parent, const QString &theme, bool *ok);
320 private:
321     IconThemeDialog(QWidget *parent);
322     IconThemeEditor *m_editor;
323 };
324 
IconThemeDialog(QWidget * parent)325 IconThemeDialog::IconThemeDialog(QWidget *parent)
326     : QDialog(parent)
327 {
328     setWindowTitle(tr("Set Icon From Theme"));
329 
330     QVBoxLayout *layout = new QVBoxLayout(this);
331     QLabel *label = new QLabel(tr("Input icon name from the current theme:"), this);
332     m_editor = new IconThemeEditor(this);
333     QDialogButtonBox *buttons = new QDialogButtonBox(this);
334     buttons->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
335 
336     layout->addWidget(label);
337     layout->addWidget(m_editor);
338     layout->addWidget(buttons);
339 
340     connect(buttons, SIGNAL(accepted()), this, SLOT(accept()));
341     connect(buttons, SIGNAL(rejected()), this, SLOT(reject()));
342 }
343 
getTheme(QWidget * parent,const QString & theme,bool * ok)344 QString IconThemeDialog::getTheme(QWidget *parent, const QString &theme, bool *ok)
345 {
346     IconThemeDialog dlg(parent);
347     dlg.m_editor->setTheme(theme);
348     if (dlg.exec() == QDialog::Accepted) {
349         *ok = true;
350         return dlg.m_editor->theme();
351     }
352     *ok = false;
353     return QString();
354 }
355 
356 // ------------ PixmapEditor
357 class PixmapEditor : public QWidget
358 {
359     Q_OBJECT
360 public:
361     PixmapEditor(QDesignerFormEditorInterface *core, QWidget *parent);
362 
363     void setSpacing(int spacing);
364     void setPixmapCache(DesignerPixmapCache *cache);
365     void setIconThemeModeEnabled(bool enabled);
366 public slots:
367     void setPath(const QString &path);
368     void setTheme(const QString &theme);
369     void setDefaultPixmap(const QPixmap &pixmap);
370 
371 signals:
372     void pathChanged(const QString &path);
373     void themeChanged(const QString &theme);
374 
375 protected:
376     void contextMenuEvent(QContextMenuEvent *event);
377 
378 private slots:
379     void defaultActionActivated();
380     void resourceActionActivated();
381     void fileActionActivated();
382     void themeActionActivated();
383     void copyActionActivated();
384     void pasteActionActivated();
385     void clipboardDataChanged();
386 private:
387     void updateLabels();
388     bool m_iconThemeModeEnabled;
389     QDesignerFormEditorInterface *m_core;
390     QLabel *m_pixmapLabel;
391     QLabel *m_pathLabel;
392     QToolButton *m_button;
393     QAction *m_resourceAction;
394     QAction *m_fileAction;
395     QAction *m_themeAction;
396     QAction *m_copyAction;
397     QAction *m_pasteAction;
398     QHBoxLayout *m_layout;
399     QPixmap m_defaultPixmap;
400     QString m_path;
401     QString m_theme;
402     DesignerPixmapCache *m_pixmapCache;
403 };
404 
PixmapEditor(QDesignerFormEditorInterface * core,QWidget * parent)405 PixmapEditor::PixmapEditor(QDesignerFormEditorInterface *core, QWidget *parent) :
406     QWidget(parent),
407     m_iconThemeModeEnabled(false),
408     m_core(core),
409     m_pixmapLabel(new QLabel(this)),
410     m_pathLabel(new QLabel(this)),
411     m_button(new QToolButton(this)),
412     m_resourceAction(new QAction(tr("Choose Resource..."), this)),
413     m_fileAction(new QAction(tr("Choose File..."), this)),
414     m_themeAction(new QAction(tr("Set Icon From Theme..."), this)),
415     m_copyAction(new QAction(createIconSet(QLatin1String("editcopy.png")), tr("Copy Path"), this)),
416     m_pasteAction(new QAction(createIconSet(QLatin1String("editpaste.png")), tr("Paste Path"), this)),
417     m_layout(new QHBoxLayout(this)),
418     m_pixmapCache(0)
419 {
420     m_layout->addWidget(m_pixmapLabel);
421     m_layout->addWidget(m_pathLabel);
422     m_button->setText(tr("..."));
423     m_button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored);
424     m_button->setFixedWidth(30);
425     m_button->setPopupMode(QToolButton::MenuButtonPopup);
426     m_layout->addWidget(m_button);
427     m_layout->setMargin(0);
428     m_layout->setSpacing(0);
429     m_pixmapLabel->setFixedWidth(16);
430     m_pixmapLabel->setAlignment(Qt::AlignCenter);
431     m_pathLabel->setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed));
432     m_themeAction->setVisible(false);
433 
434     QMenu *menu = new QMenu(this);
435     menu->addAction(m_resourceAction);
436     menu->addAction(m_fileAction);
437     menu->addAction(m_themeAction);
438 
439     m_button->setMenu(menu);
440     m_button->setText(tr("..."));
441 
442     connect(m_button, SIGNAL(clicked()), this, SLOT(defaultActionActivated()));
443     connect(m_resourceAction, SIGNAL(triggered()), this, SLOT(resourceActionActivated()));
444     connect(m_fileAction, SIGNAL(triggered()), this, SLOT(fileActionActivated()));
445     connect(m_themeAction, SIGNAL(triggered()), this, SLOT(themeActionActivated()));
446     connect(m_copyAction, SIGNAL(triggered()), this, SLOT(copyActionActivated()));
447     connect(m_pasteAction, SIGNAL(triggered()), this, SLOT(pasteActionActivated()));
448     setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Ignored));
449     setFocusProxy(m_button);
450 
451     connect(QApplication::clipboard(), SIGNAL(dataChanged()), this, SLOT(clipboardDataChanged()));
452     clipboardDataChanged();
453 }
454 
setPixmapCache(DesignerPixmapCache * cache)455 void PixmapEditor::setPixmapCache(DesignerPixmapCache *cache)
456 {
457     m_pixmapCache = cache;
458 }
459 
setIconThemeModeEnabled(bool enabled)460 void PixmapEditor::setIconThemeModeEnabled(bool enabled)
461 {
462     if (m_iconThemeModeEnabled == enabled)
463         return;
464     m_iconThemeModeEnabled = enabled;
465     m_themeAction->setVisible(enabled);
466 }
467 
setSpacing(int spacing)468 void PixmapEditor::setSpacing(int spacing)
469 {
470     m_layout->setSpacing(spacing);
471 }
472 
setPath(const QString & path)473 void PixmapEditor::setPath(const QString &path)
474 {
475     m_path = path;
476     updateLabels();
477 }
478 
setTheme(const QString & theme)479 void PixmapEditor::setTheme(const QString &theme)
480 {
481     m_theme = theme;
482     updateLabels();
483 }
484 
updateLabels()485 void PixmapEditor::updateLabels()
486 {
487     if (m_iconThemeModeEnabled && QIcon::hasThemeIcon(m_theme)) {
488         m_pixmapLabel->setPixmap(QIcon::fromTheme(m_theme).pixmap(16, 16));
489         m_pathLabel->setText(tr("[Theme] %1").arg(m_theme));
490         m_copyAction->setEnabled(true);
491     } else {
492         if (m_path.isEmpty()) {
493             m_pathLabel->setText(m_path);
494             m_pixmapLabel->setPixmap(m_defaultPixmap);
495             m_copyAction->setEnabled(false);
496         } else {
497             m_pathLabel->setText(QFileInfo(m_path).fileName());
498             if (m_pixmapCache)
499                 m_pixmapLabel->setPixmap(QIcon(m_pixmapCache->pixmap(PropertySheetPixmapValue(m_path))).pixmap(16, 16));
500             m_copyAction->setEnabled(true);
501         }
502     }
503 }
504 
setDefaultPixmap(const QPixmap & pixmap)505 void PixmapEditor::setDefaultPixmap(const QPixmap &pixmap)
506 {
507     m_defaultPixmap = QIcon(pixmap).pixmap(16, 16);
508     const bool hasThemeIcon = m_iconThemeModeEnabled && QIcon::hasThemeIcon(m_theme);
509     if (!hasThemeIcon && m_path.isEmpty())
510         m_pixmapLabel->setPixmap(m_defaultPixmap);
511 }
512 
contextMenuEvent(QContextMenuEvent * event)513 void PixmapEditor::contextMenuEvent(QContextMenuEvent *event)
514 {
515     QMenu menu(this);
516     menu.addAction(m_copyAction);
517     menu.addAction(m_pasteAction);
518     menu.exec(event->globalPos());
519     event->accept();
520 }
521 
defaultActionActivated()522 void PixmapEditor::defaultActionActivated()
523 {
524     if (m_iconThemeModeEnabled && QIcon::hasThemeIcon(m_theme)) {
525         themeActionActivated();
526         return;
527     }
528     // Default to resource
529     const PropertySheetPixmapValue::PixmapSource ps = m_path.isEmpty() ? PropertySheetPixmapValue::ResourcePixmap : PropertySheetPixmapValue::getPixmapSource(m_core, m_path);
530     switch (ps) {
531     case PropertySheetPixmapValue::LanguageResourcePixmap:
532     case PropertySheetPixmapValue::ResourcePixmap:
533         resourceActionActivated();
534         break;
535     case PropertySheetPixmapValue::FilePixmap:
536         fileActionActivated();
537         break;
538     }
539 }
540 
resourceActionActivated()541 void PixmapEditor::resourceActionActivated()
542 {
543     const QString oldPath = m_path;
544     const  QString newPath = IconSelector::choosePixmapResource(m_core, m_core->resourceModel(), oldPath, this);
545     if (!newPath.isEmpty() &&  newPath != oldPath) {
546         setTheme(QString());
547         setPath(newPath);
548         emit pathChanged(newPath);
549     }
550 }
551 
fileActionActivated()552 void PixmapEditor::fileActionActivated()
553 {
554     const QString newPath = IconSelector::choosePixmapFile(m_path, m_core->dialogGui(), this);
555     if (!newPath.isEmpty() && newPath != m_path) {
556         setTheme(QString());
557         setPath(newPath);
558         emit pathChanged(newPath);
559     }
560 }
561 
themeActionActivated()562 void PixmapEditor::themeActionActivated()
563 {
564     bool ok;
565     const QString newTheme = IconThemeDialog::getTheme(this, m_theme, &ok);
566     if (ok && newTheme != m_theme) {
567         setTheme(newTheme);
568         setPath(QString());
569         emit themeChanged(newTheme);
570     }
571 }
572 
copyActionActivated()573 void PixmapEditor::copyActionActivated()
574 {
575     QClipboard *clipboard = QApplication::clipboard();
576     if (m_iconThemeModeEnabled && QIcon::hasThemeIcon(m_theme))
577         clipboard->setText(m_theme);
578     else
579         clipboard->setText(m_path);
580 }
581 
pasteActionActivated()582 void PixmapEditor::pasteActionActivated()
583 {
584     QClipboard *clipboard = QApplication::clipboard();
585     QString subtype = QLatin1String("plain");
586     QString text = clipboard->text(subtype);
587     if (!text.isNull()) {
588         QStringList list = text.split(QLatin1Char('\n'));
589         if (list.size() > 0) {
590             text = list.at(0);
591             if (m_iconThemeModeEnabled && QIcon::hasThemeIcon(text)) {
592                 setTheme(text);
593                 setPath(QString());
594                 emit themeChanged(text);
595             } else {
596                 setPath(text);
597                 setTheme(QString());
598                 emit pathChanged(text);
599             }
600         }
601     }
602 }
603 
clipboardDataChanged()604 void PixmapEditor::clipboardDataChanged()
605 {
606     QClipboard *clipboard = QApplication::clipboard();
607     QString subtype = QLatin1String("plain");
608     const QString text = clipboard->text(subtype);
609     m_pasteAction->setEnabled(!text.isNull());
610 }
611 
612 // --------------- ResetWidget
613 class ResetWidget : public QWidget
614 {
615     Q_OBJECT
616 public:
617     ResetWidget(QtProperty *property, QWidget *parent = 0);
618 
619     void setWidget(QWidget *widget);
620     void setResetEnabled(bool enabled);
621     void setValueText(const QString &text);
622     void setValueIcon(const QIcon &icon);
623     void setSpacing(int spacing);
624 signals:
625     void resetProperty(QtProperty *property);
626 private slots:
627     void slotClicked();
628 private:
629     QtProperty *m_property;
630     QLabel *m_textLabel;
631     QLabel *m_iconLabel;
632     QToolButton *m_button;
633     int m_spacing;
634 };
635 
ResetWidget(QtProperty * property,QWidget * parent)636 ResetWidget::ResetWidget(QtProperty *property, QWidget *parent) :
637     QWidget(parent),
638     m_property(property),
639     m_textLabel(new QLabel(this)),
640     m_iconLabel(new QLabel(this)),
641     m_button(new QToolButton(this)),
642     m_spacing(-1)
643 {
644     m_textLabel->setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed));
645     m_iconLabel->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
646     m_button->setToolButtonStyle(Qt::ToolButtonIconOnly);
647     m_button->setIcon(createIconSet(QLatin1String("resetproperty.png")));
648     m_button->setIconSize(QSize(8,8));
649     m_button->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::MinimumExpanding));
650     connect(m_button, SIGNAL(clicked()), this, SLOT(slotClicked()));
651     QLayout *layout = new QHBoxLayout(this);
652     layout->setMargin(0);
653     layout->setSpacing(m_spacing);
654     layout->addWidget(m_iconLabel);
655     layout->addWidget(m_textLabel);
656     layout->addWidget(m_button);
657     setFocusProxy(m_textLabel);
658     setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed));
659 }
660 
setSpacing(int spacing)661 void ResetWidget::setSpacing(int spacing)
662 {
663     m_spacing = spacing;
664     layout()->setSpacing(m_spacing);
665 }
666 
setWidget(QWidget * widget)667 void ResetWidget::setWidget(QWidget *widget)
668 {
669     if (m_textLabel) {
670         delete m_textLabel;
671         m_textLabel = 0;
672     }
673     if (m_iconLabel) {
674         delete m_iconLabel;
675         m_iconLabel = 0;
676     }
677     delete layout();
678     QLayout *layout = new QHBoxLayout(this);
679     layout->setMargin(0);
680     layout->setSpacing(m_spacing);
681     layout->addWidget(widget);
682     layout->addWidget(m_button);
683     setFocusProxy(widget);
684 }
685 
setResetEnabled(bool enabled)686 void ResetWidget::setResetEnabled(bool enabled)
687 {
688     m_button->setEnabled(enabled);
689 }
690 
setValueText(const QString & text)691 void ResetWidget::setValueText(const QString &text)
692 {
693     if (m_textLabel)
694         m_textLabel->setText(text);
695 }
696 
setValueIcon(const QIcon & icon)697 void ResetWidget::setValueIcon(const QIcon &icon)
698 {
699     QPixmap pix = icon.pixmap(QSize(16, 16));
700     if (m_iconLabel) {
701         m_iconLabel->setVisible(!pix.isNull());
702         m_iconLabel->setPixmap(pix);
703     }
704 }
705 
slotClicked()706 void ResetWidget::slotClicked()
707 {
708     emit resetProperty(m_property);
709 }
710 
711 
712 // ------------ DesignerPropertyManager:
713 
DesignerPropertyManager(QDesignerFormEditorInterface * core,QObject * parent)714 DesignerPropertyManager::DesignerPropertyManager(QDesignerFormEditorInterface *core, QObject *parent) :
715     QtVariantPropertyManager(parent),
716     m_changingSubValue(false),
717     m_core(core),
718     m_sourceOfChange(0)
719 {
720     connect(this, SIGNAL(valueChanged(QtProperty*,QVariant)), this, SLOT(slotValueChanged(QtProperty*,QVariant)));
721     connect(this, SIGNAL(propertyDestroyed(QtProperty*)), this, SLOT(slotPropertyDestroyed(QtProperty*)));
722 }
723 
~DesignerPropertyManager()724 DesignerPropertyManager::~DesignerPropertyManager()
725 {
726     clear();
727 }
728 
bitCount(int mask) const729 int DesignerPropertyManager::bitCount(int mask) const
730 {
731     int count = 0;
732     for (; mask; count++)
733         mask &= mask - 1; // clear the least significant bit set
734     return count;
735 }
736 
alignToIndexH(uint align) const737 int DesignerPropertyManager::alignToIndexH(uint align) const
738 {
739     if (align & Qt::AlignLeft)
740         return 0;
741     if (align & Qt::AlignHCenter)
742         return 1;
743     if (align & Qt::AlignRight)
744         return 2;
745     if (align & Qt::AlignJustify)
746         return 3;
747     return 0;
748 }
749 
alignToIndexV(uint align) const750 int DesignerPropertyManager::alignToIndexV(uint align) const
751 {
752     if (align & Qt::AlignTop)
753         return 0;
754     if (align & Qt::AlignVCenter)
755         return 1;
756     if (align & Qt::AlignBottom)
757         return 2;
758     return 1;
759 }
760 
indexHToAlign(int idx) const761 uint DesignerPropertyManager::indexHToAlign(int idx) const
762 {
763     switch (idx) {
764         case 0: return Qt::AlignLeft;
765         case 1: return Qt::AlignHCenter;
766         case 2: return Qt::AlignRight;
767         case 3: return Qt::AlignJustify;
768         default: break;
769     }
770     return Qt::AlignLeft;
771 }
772 
indexVToAlign(int idx) const773 uint DesignerPropertyManager::indexVToAlign(int idx) const
774 {
775     switch (idx) {
776         case 0: return Qt::AlignTop;
777         case 1: return Qt::AlignVCenter;
778         case 2: return Qt::AlignBottom;
779         default: break;
780     }
781     return Qt::AlignVCenter;
782 }
783 
indexHToString(int idx) const784 QString DesignerPropertyManager::indexHToString(int idx) const
785 {
786     switch (idx) {
787         case 0: return tr("AlignLeft");
788         case 1: return tr("AlignHCenter");
789         case 2: return tr("AlignRight");
790         case 3: return tr("AlignJustify");
791         default: break;
792     }
793     return tr("AlignLeft");
794 }
795 
indexVToString(int idx) const796 QString DesignerPropertyManager::indexVToString(int idx) const
797 {
798     switch (idx) {
799         case 0: return tr("AlignTop");
800         case 1: return tr("AlignVCenter");
801         case 2: return tr("AlignBottom");
802         default: break;
803     }
804     return tr("AlignVCenter");
805 }
806 
slotValueChanged(QtProperty * property,const QVariant & value)807 void DesignerPropertyManager::slotValueChanged(QtProperty *property, const QVariant &value)
808 {
809     if (m_changingSubValue)
810         return;
811     bool enableSubPropertyHandling = true;
812 
813     if (QtProperty *flagProperty = m_flagToProperty.value(property, 0)) {
814         const QList<QtProperty *> subFlags = m_propertyToFlags.value(flagProperty);
815         const int subFlagCount = subFlags.count();
816         // flag changed
817         const bool subValue = variantProperty(property)->value().toBool();
818         const int subIndex = subFlags.indexOf(property);
819         if (subIndex < 0)
820             return;
821 
822         uint newValue = 0;
823 
824         m_changingSubValue = true;
825 
826         FlagData data = m_flagValues.value(flagProperty);
827         const QList<uint> values = data.values;
828         // Compute new value, without including (additional) supermasks
829         if (values.at(subIndex) == 0) {
830             for (int i = 0; i < subFlagCount; ++i) {
831                 QtVariantProperty *subFlag = variantProperty(subFlags.at(i));
832                 subFlag->setValue(i == subIndex);
833             }
834         } else {
835             if (subValue)
836                 newValue = values.at(subIndex); // value mask of subValue
837             for (int i = 0; i < subFlagCount; ++i) {
838                 QtVariantProperty *subFlag = variantProperty(subFlags.at(i));
839                 if (subFlag->value().toBool() && bitCount(values.at(i)) == 1)
840                     newValue |= values.at(i);
841             }
842             if (newValue == 0) {
843                 // Uncheck all items except 0-mask
844                 for (int i = 0; i < subFlagCount; ++i) {
845                     QtVariantProperty *subFlag = variantProperty(subFlags.at(i));
846                     subFlag->setValue(values.at(i) == 0);
847                 }
848             } else if (newValue == data.val) {
849                 if (!subValue && bitCount(values.at(subIndex)) > 1) {
850                     // We unchecked something, but the original value still holds
851                     variantProperty(property)->setValue(true);
852                 }
853             } else {
854                 // Make sure 0-mask is not selected
855                 for (int i = 0; i < subFlagCount; ++i) {
856                     QtVariantProperty *subFlag = variantProperty(subFlags.at(i));
857                     if (values.at(i) == 0)
858                         subFlag->setValue(false);
859                 }
860                 // Check/uncheck proper masks
861                 if (subValue) {
862                     // Make sure submasks and supermasks are selected
863                     for (int i = 0; i < subFlagCount; ++i) {
864                         QtVariantProperty *subFlag = variantProperty(subFlags.at(i));
865                         const uint vi = values.at(i);
866                         if ((vi != 0) && ((vi & newValue) == vi) && !subFlag->value().toBool())
867                             subFlag->setValue(true);
868                     }
869                 } else {
870                     // Make sure supermasks are not selected if they're no longer valid
871                     for (int i = 0; i < subFlagCount; ++i) {
872                         QtVariantProperty *subFlag = variantProperty(subFlags.at(i));
873                         const uint vi = values.at(i);
874                         if (subFlag->value().toBool() && ((vi & newValue) != vi))
875                             subFlag->setValue(false);
876                     }
877                 }
878             }
879         }
880         m_changingSubValue = false;
881         data.val = newValue;
882         QVariant v;
883         v.setValue(data.val);
884         variantProperty(flagProperty)->setValue(v);
885     } else if (QtProperty *alignProperty = m_alignHToProperty.value(property, 0)) {
886         const uint v = m_alignValues.value(alignProperty);
887         const uint newValue = indexHToAlign(value.toInt()) | indexVToAlign(alignToIndexV(v));
888         if (v == newValue)
889             return;
890 
891         variantProperty(alignProperty)->setValue(newValue);
892     } else if (QtProperty *alignProperty = m_alignVToProperty.value(property, 0)) {
893         const uint v = m_alignValues.value(alignProperty);
894         const uint newValue = indexVToAlign(value.toInt()) | indexHToAlign(alignToIndexH(v));
895         if (v == newValue)
896             return;
897 
898         variantProperty(alignProperty)->setValue(newValue);
899     } else if (QtProperty *stringProperty = m_commentToString.value(property, 0)) {
900         const PropertySheetStringValue v = m_stringValues.value(stringProperty);
901         PropertySheetStringValue newValue = v;
902         newValue.setComment(value.toString());
903         if (v == newValue)
904             return;
905 
906         variantProperty(stringProperty)->setValue(QVariant::fromValue(newValue));
907     } else if (QtProperty *stringProperty = m_translatableToString.value(property, 0)) {
908         const PropertySheetStringValue v = m_stringValues.value(stringProperty);
909         PropertySheetStringValue newValue = v;
910         newValue.setTranslatable(value.toBool());
911         if (v == newValue)
912             return;
913 
914         variantProperty(stringProperty)->setValue(QVariant::fromValue(newValue));
915     } else if (QtProperty *stringProperty = m_disambiguationToString.value(property, 0)) {
916         const PropertySheetStringValue v = m_stringValues.value(stringProperty);
917         PropertySheetStringValue newValue = v;
918         newValue.setDisambiguation(value.toString());
919         if (v == newValue)
920             return;
921 
922         variantProperty(stringProperty)->setValue(QVariant::fromValue(newValue));
923     } else if (QtProperty *keySequenceProperty = m_commentToKeySequence.value(property, 0)) {
924         const PropertySheetKeySequenceValue v = m_keySequenceValues.value(keySequenceProperty);
925         PropertySheetKeySequenceValue newValue = v;
926         newValue.setComment(value.toString());
927         if (v == newValue)
928             return;
929 
930         variantProperty(keySequenceProperty)->setValue(QVariant::fromValue(newValue));
931     } else if (QtProperty *keySequenceProperty = m_translatableToKeySequence.value(property, 0)) {
932         const PropertySheetKeySequenceValue v = m_keySequenceValues.value(keySequenceProperty);
933         PropertySheetKeySequenceValue newValue = v;
934         newValue.setTranslatable(value.toBool());
935         if (v == newValue)
936             return;
937 
938         variantProperty(keySequenceProperty)->setValue(QVariant::fromValue(newValue));
939     } else if (QtProperty *keySequenceProperty = m_disambiguationToKeySequence.value(property, 0)) {
940         const PropertySheetKeySequenceValue v = m_keySequenceValues.value(keySequenceProperty);
941         PropertySheetKeySequenceValue newValue = v;
942         newValue.setDisambiguation(value.toString());
943         if (v == newValue)
944             return;
945 
946         variantProperty(keySequenceProperty)->setValue(QVariant::fromValue(newValue));
947     } else if (QtProperty *iProperty = m_iconSubPropertyToProperty.value(property, 0)) {
948         QtVariantProperty *iconProperty = variantProperty(iProperty);
949         PropertySheetIconValue icon = qvariant_cast<PropertySheetIconValue>(iconProperty->value());
950         QMap<QtProperty *, QPair<QIcon::Mode, QIcon::State> >::ConstIterator itState = m_iconSubPropertyToState.constFind(property);
951         if (itState != m_iconSubPropertyToState.constEnd()) {
952             QPair<QIcon::Mode, QIcon::State> pair = m_iconSubPropertyToState.value(property);
953             icon.setPixmap(pair.first, pair.second, qvariant_cast<PropertySheetPixmapValue>(value));
954         } else { // must be theme property
955             icon.setTheme(value.toString());
956         }
957         QtProperty *origSourceOfChange = m_sourceOfChange;
958         if (!origSourceOfChange)
959             m_sourceOfChange = property;
960         iconProperty->setValue(QVariant::fromValue(icon));
961         if (!origSourceOfChange)
962             m_sourceOfChange = origSourceOfChange;
963     } else if (m_iconValues.contains(property)) {
964         enableSubPropertyHandling = m_sourceOfChange;
965     } else {
966         if (m_brushManager.valueChanged(this, property, value) == BrushPropertyManager::Unchanged)
967             return;
968         if (m_fontManager.valueChanged(this, property, value) == FontPropertyManager::Unchanged)
969             return;
970     }
971 
972     emit valueChanged(property, value, enableSubPropertyHandling);
973 }
974 
slotPropertyDestroyed(QtProperty * property)975 void DesignerPropertyManager::slotPropertyDestroyed(QtProperty *property)
976 {
977     if (QtProperty *flagProperty = m_flagToProperty.value(property, 0)) {
978         PropertyToPropertyListMap::iterator it = m_propertyToFlags.find(flagProperty);
979         QList<QtProperty *> &propertyList = it.value();
980         propertyList.replace(propertyList.indexOf(property), 0);
981         m_flagToProperty.remove(property);
982     } else if (QtProperty *alignProperty = m_alignHToProperty.value(property, 0)) {
983         m_propertyToAlignH.remove(alignProperty);
984         m_alignHToProperty.remove(property);
985     } else if (QtProperty *alignProperty = m_alignVToProperty.value(property, 0)) {
986         m_propertyToAlignV.remove(alignProperty);
987         m_alignVToProperty.remove(property);
988     } else if (QtProperty *stringCommentProperty = m_commentToString.value(property, 0)) {
989         m_stringToComment.remove(stringCommentProperty);
990         m_commentToString.remove(property);
991     } else if (QtProperty *stringTranslatableProperty = m_translatableToString.value(property, 0)) {
992         m_stringToTranslatable.remove(stringTranslatableProperty);
993         m_translatableToString.remove(property);
994     } else if (QtProperty *stringDisambiguationProperty = m_disambiguationToString.value(property, 0)) {
995         m_stringToDisambiguation.remove(stringDisambiguationProperty);
996         m_disambiguationToString.remove(property);
997     } else if (QtProperty *keySequenceCommentProperty = m_commentToKeySequence.value(property, 0)) {
998         m_keySequenceToComment.remove(keySequenceCommentProperty);
999         m_commentToKeySequence.remove(property);
1000     } else if (QtProperty *keySequenceTranslatableProperty = m_translatableToKeySequence.value(property, 0)) {
1001         m_keySequenceToTranslatable.remove(keySequenceTranslatableProperty);
1002         m_translatableToKeySequence.remove(property);
1003     } else if (QtProperty *keySequenceDisambiguationProperty = m_disambiguationToKeySequence.value(property, 0)) {
1004         m_keySequenceToDisambiguation.remove(keySequenceDisambiguationProperty);
1005         m_disambiguationToKeySequence.remove(property);
1006     } else if (QtProperty *iconProperty = m_iconSubPropertyToProperty.value(property, 0)) {
1007         if (m_propertyToTheme.value(iconProperty) == property) {
1008             m_propertyToTheme.remove(iconProperty);
1009         } else {
1010             QMap<QtProperty *, QMap<QPair<QIcon::Mode, QIcon::State>, QtProperty *> >::iterator it =
1011                         m_propertyToIconSubProperties.find(iconProperty);
1012             QPair<QIcon::Mode, QIcon::State> state = m_iconSubPropertyToState.value(property);
1013             QMap<QPair<QIcon::Mode, QIcon::State>, QtProperty *> &propertyList = it.value();
1014             propertyList.remove(state);
1015             m_iconSubPropertyToState.remove(property);
1016         }
1017         m_iconSubPropertyToProperty.remove(property);
1018     } else {
1019         m_fontManager.slotPropertyDestroyed(property);
1020         m_brushManager.slotPropertyDestroyed(property);
1021     }
1022 }
1023 
attributes(int propertyType) const1024 QStringList DesignerPropertyManager::attributes(int propertyType) const
1025 {
1026     if (!isPropertyTypeSupported(propertyType))
1027         return QStringList();
1028 
1029     QStringList list = QtVariantPropertyManager::attributes(propertyType);
1030     if (propertyType == designerFlagTypeId()) {
1031         list.append(QLatin1String(flagsAttributeC));
1032     } else if (propertyType == designerPixmapTypeId()) {
1033         list.append(QLatin1String(defaultResourceAttributeC));
1034     } else if (propertyType == designerIconTypeId()) {
1035         list.append(QLatin1String(defaultResourceAttributeC));
1036     } else if (propertyType == designerStringTypeId() || propertyType == QVariant::String) {
1037         list.append(QLatin1String(validationModesAttributeC));
1038         list.append(QLatin1String(fontAttributeC));
1039         list.append(QLatin1String(themeAttributeC));
1040     } else if (propertyType == QVariant::Palette) {
1041         list.append(QLatin1String(superPaletteAttributeC));
1042     }
1043     list.append(QLatin1String(resettableAttributeC));
1044     return list;
1045 }
1046 
attributeType(int propertyType,const QString & attribute) const1047 int DesignerPropertyManager::attributeType(int propertyType, const QString &attribute) const
1048 {
1049     if (!isPropertyTypeSupported(propertyType))
1050         return 0;
1051 
1052     if (propertyType == designerFlagTypeId() && attribute == QLatin1String(flagsAttributeC))
1053         return designerFlagListTypeId();
1054     if (propertyType == designerPixmapTypeId() && attribute == QLatin1String(defaultResourceAttributeC))
1055         return QVariant::Pixmap;
1056     if (propertyType == designerIconTypeId() && attribute == QLatin1String(defaultResourceAttributeC))
1057         return QVariant::Icon;
1058     if (attribute == QLatin1String(resettableAttributeC))
1059         return QVariant::Bool;
1060     if (propertyType == designerStringTypeId() || propertyType == QVariant::String) {
1061         if (attribute == QLatin1String(validationModesAttributeC))
1062             return QVariant::Int;
1063         if (attribute == QLatin1String(fontAttributeC))
1064             return QVariant::Font;
1065         if (attribute == QLatin1String(themeAttributeC))
1066             return QVariant::Bool;
1067     }
1068     if (propertyType == QVariant::Palette && attribute == QLatin1String(superPaletteAttributeC))
1069         return QVariant::Palette;
1070 
1071     return QtVariantPropertyManager::attributeType(propertyType, attribute);
1072 }
1073 
attributeValue(const QtProperty * property,const QString & attribute) const1074 QVariant DesignerPropertyManager::attributeValue(const QtProperty *property, const QString &attribute) const
1075 {
1076     QtProperty *prop = const_cast<QtProperty *>(property);
1077 
1078     if (attribute == QLatin1String(resettableAttributeC)) {
1079         const PropertyBoolMap::const_iterator it = m_resetMap.constFind(prop);
1080         if (it != m_resetMap.constEnd())
1081             return it.value();
1082     }
1083 
1084     if (attribute == QLatin1String(flagsAttributeC)) {
1085         PropertyFlagDataMap::const_iterator it = m_flagValues.constFind(prop);
1086         if (it != m_flagValues.constEnd()) {
1087             QVariant v;
1088             v.setValue(it.value().flags);
1089             return v;
1090         }
1091     }
1092     if (attribute == QLatin1String(validationModesAttributeC)) {
1093         const PropertyIntMap::const_iterator it = m_stringAttributes.constFind(prop);
1094         if (it !=  m_stringAttributes.constEnd())
1095             return it.value();
1096     }
1097 
1098     if (attribute == QLatin1String(fontAttributeC)) {
1099         const PropertyFontMap::const_iterator it = m_stringFontAttributes.constFind(prop);
1100         if (it !=  m_stringFontAttributes.constEnd())
1101             return it.value();
1102     }
1103 
1104     if (attribute == QLatin1String(themeAttributeC)) {
1105         const PropertyBoolMap::const_iterator it = m_stringThemeAttributes.constFind(prop);
1106         if (it !=  m_stringThemeAttributes.constEnd())
1107             return it.value();
1108     }
1109 
1110     if (attribute == QLatin1String(superPaletteAttributeC)) {
1111         PropertyPaletteDataMap::const_iterator it = m_paletteValues.constFind(prop);
1112         if (it !=  m_paletteValues.constEnd())
1113             return it.value().superPalette;
1114     }
1115 
1116     if (attribute == QLatin1String(defaultResourceAttributeC)) {
1117         QMap<QtProperty *, QPixmap>::const_iterator itPix = m_defaultPixmaps.constFind(prop);
1118         if (itPix != m_defaultPixmaps.constEnd())
1119             return itPix.value();
1120 
1121         QMap<QtProperty *, QIcon>::const_iterator itIcon = m_defaultIcons.constFind(prop);
1122         if (itIcon != m_defaultIcons.constEnd())
1123             return itIcon.value();
1124     }
1125 
1126     return QtVariantPropertyManager::attributeValue(property, attribute);
1127 }
1128 
setAttribute(QtProperty * property,const QString & attribute,const QVariant & value)1129 void DesignerPropertyManager::setAttribute(QtProperty *property,
1130             const QString &attribute, const QVariant &value)
1131 {
1132     if (attribute == QLatin1String(resettableAttributeC) && m_resetMap.contains(property)) {
1133         if (value.userType() != QVariant::Bool)
1134             return;
1135         const bool val = value.toBool();
1136         const PropertyBoolMap::iterator it = m_resetMap.find(property);
1137         if (it.value() == val)
1138             return;
1139         it.value() = val;
1140         emit attributeChanged(variantProperty(property), attribute, value);
1141         return;
1142     } else if (attribute == QLatin1String(flagsAttributeC) && m_flagValues.contains(property)) {
1143         if (value.userType() != designerFlagListTypeId())
1144             return;
1145 
1146         const DesignerFlagList flags = qvariant_cast<DesignerFlagList>(value);
1147         PropertyFlagDataMap::iterator fit = m_flagValues.find(property);
1148         FlagData data = fit.value();
1149         if (data.flags == flags)
1150             return;
1151 
1152         PropertyToPropertyListMap::iterator pfit = m_propertyToFlags.find(property);
1153         QListIterator<QtProperty *> itProp(pfit.value());
1154         while (itProp.hasNext()) {
1155             if (QtProperty *prop = itProp.next()) {
1156                 delete prop;
1157                 m_flagToProperty.remove(prop);
1158             }
1159         }
1160         pfit.value().clear();
1161 
1162         QList<uint> values;
1163 
1164         QListIterator<QPair<QString, uint> > itFlag(flags);
1165         while (itFlag.hasNext()) {
1166             const QPair<QString, uint> pair = itFlag.next();
1167             const QString flagName = pair.first;
1168             QtProperty *prop = addProperty(QVariant::Bool);
1169             prop->setPropertyName(flagName);
1170             property->addSubProperty(prop);
1171             m_propertyToFlags[property].append(prop);
1172             m_flagToProperty[prop] = property;
1173             values.append(pair.second);
1174         }
1175 
1176         data.val = 0;
1177         data.flags = flags;
1178         data.values = values;
1179 
1180         fit.value() = data;
1181 
1182         QVariant v;
1183         v.setValue(flags);
1184         emit attributeChanged(property, attribute, v);
1185 
1186         emit propertyChanged(property);
1187         emit QtVariantPropertyManager::valueChanged(property, data.val);
1188     } else if (attribute == QLatin1String(validationModesAttributeC) && m_stringAttributes.contains(property)) {
1189         if (value.userType() != QVariant::Int)
1190             return;
1191 
1192         const PropertyIntMap::iterator it = m_stringAttributes.find(property);
1193         const int oldValue = it.value();
1194 
1195         const int newValue = value.toInt();
1196 
1197         if (oldValue == newValue)
1198             return;
1199 
1200         it.value() = newValue;
1201 
1202         emit attributeChanged(property, attribute, newValue);
1203     } else if (attribute == QLatin1String(fontAttributeC) && m_stringFontAttributes.contains(property)) {
1204         if (value.userType() != QVariant::Font)
1205             return;
1206 
1207         const PropertyFontMap::iterator it = m_stringFontAttributes.find(property);
1208         const QFont oldValue = it.value();
1209 
1210         const QFont newValue = qvariant_cast<QFont>(value);
1211 
1212         if (oldValue == newValue)
1213             return;
1214 
1215         it.value() = newValue;
1216 
1217         emit attributeChanged(property, attribute, newValue);
1218     } else if (attribute == QLatin1String(themeAttributeC) && m_stringThemeAttributes.contains(property)) {
1219         if (value.userType() != QVariant::Bool)
1220             return;
1221 
1222         const PropertyBoolMap::iterator it = m_stringThemeAttributes.find(property);
1223         const bool oldValue = it.value();
1224 
1225         const bool newValue = value.toBool();
1226 
1227         if (oldValue == newValue)
1228             return;
1229 
1230         it.value() = newValue;
1231 
1232         emit attributeChanged(property, attribute, newValue);
1233     } else if (attribute == QLatin1String(superPaletteAttributeC) && m_paletteValues.contains(property)) {
1234         if (value.userType() != QVariant::Palette)
1235             return;
1236 
1237         QPalette superPalette = qvariant_cast<QPalette>(value);
1238 
1239         const PropertyPaletteDataMap::iterator it = m_paletteValues.find(property);
1240         PaletteData data = it.value();
1241         if (data.superPalette == superPalette)
1242             return;
1243 
1244         data.superPalette = superPalette;
1245         // resolve here
1246         const uint mask = data.val.resolve();
1247         data.val = data.val.resolve(superPalette);
1248         data.val.resolve(mask);
1249 
1250         it.value() = data;
1251 
1252         QVariant v;
1253         v.setValue(superPalette);
1254         emit attributeChanged(property, attribute, v);
1255 
1256         emit propertyChanged(property);
1257         emit QtVariantPropertyManager::valueChanged(property, data.val); // if resolve was done, this is also for consistency
1258     } else if (attribute == QLatin1String(defaultResourceAttributeC) && m_defaultPixmaps.contains(property)) {
1259         if (value.userType() != QVariant::Pixmap)
1260             return;
1261 
1262         QPixmap defaultPixmap = qvariant_cast<QPixmap>(value);
1263 
1264         const QMap<QtProperty *, QPixmap>::iterator it = m_defaultPixmaps.find(property);
1265         QPixmap oldDefaultPixmap = it.value();
1266         if (defaultPixmap.cacheKey() == oldDefaultPixmap.cacheKey())
1267             return;
1268 
1269         it.value() = defaultPixmap;
1270 
1271         QVariant v = QVariant::fromValue(defaultPixmap);
1272         emit attributeChanged(property, attribute, v);
1273 
1274         emit propertyChanged(property);
1275     } else if (attribute == QLatin1String(defaultResourceAttributeC) && m_defaultIcons.contains(property)) {
1276         if (value.userType() != QVariant::Icon)
1277             return;
1278 
1279         QIcon defaultIcon = qvariant_cast<QIcon>(value);
1280 
1281         const QMap<QtProperty *, QIcon>::iterator it = m_defaultIcons.find(property);
1282         QIcon oldDefaultIcon = it.value();
1283         if (defaultIcon.cacheKey() == oldDefaultIcon.cacheKey())
1284             return;
1285 
1286         it.value() = defaultIcon;
1287 
1288         qdesigner_internal::PropertySheetIconValue icon = m_iconValues.value(property);
1289         if (icon.paths().isEmpty()) {
1290             QMap<QPair<QIcon::Mode, QIcon::State>, QtProperty *> subIconProperties = m_propertyToIconSubProperties.value(property);
1291             QMapIterator<QPair<QIcon::Mode, QIcon::State>, QtProperty *> itSub(subIconProperties);
1292             while (itSub.hasNext()) {
1293                 QPair<QIcon::Mode, QIcon::State> pair = itSub.next().key();
1294                 QtProperty *subProp = itSub.value();
1295                 setAttribute(subProp, QLatin1String(defaultResourceAttributeC),
1296                              defaultIcon.pixmap(16, 16, pair.first, pair.second));
1297             }
1298         }
1299 
1300         QVariant v = QVariant::fromValue(defaultIcon);
1301         emit attributeChanged(property, attribute, v);
1302 
1303         emit propertyChanged(property);
1304     }
1305     QtVariantPropertyManager::setAttribute(property, attribute, value);
1306 }
1307 
designerFlagTypeId()1308 int DesignerPropertyManager::designerFlagTypeId()
1309 {
1310     static const int rc = qMetaTypeId<DesignerFlagPropertyType>();
1311     return rc;
1312 }
1313 
designerFlagListTypeId()1314 int DesignerPropertyManager::designerFlagListTypeId()
1315 {
1316     static const int rc = qMetaTypeId<DesignerFlagList>();
1317     return rc;
1318 }
1319 
designerAlignmentTypeId()1320 int DesignerPropertyManager::designerAlignmentTypeId()
1321 {
1322     static const int rc = qMetaTypeId<DesignerAlignmentPropertyType>();
1323     return rc;
1324 }
1325 
designerPixmapTypeId()1326 int DesignerPropertyManager::designerPixmapTypeId()
1327 {
1328     return qMetaTypeId<PropertySheetPixmapValue>();
1329 }
1330 
designerIconTypeId()1331 int DesignerPropertyManager::designerIconTypeId()
1332 {
1333     return qMetaTypeId<PropertySheetIconValue>();
1334 }
1335 
designerStringTypeId()1336 int DesignerPropertyManager::designerStringTypeId()
1337 {
1338     return qMetaTypeId<PropertySheetStringValue>();
1339 }
1340 
designerKeySequenceTypeId()1341 int DesignerPropertyManager::designerKeySequenceTypeId()
1342 {
1343     return qMetaTypeId<PropertySheetKeySequenceValue>();
1344 }
1345 
isPropertyTypeSupported(int propertyType) const1346 bool DesignerPropertyManager::isPropertyTypeSupported(int propertyType) const
1347 {
1348     switch (propertyType) {
1349     case QVariant::Palette:
1350     case QVariant::UInt:
1351     case QVariant::LongLong:
1352     case QVariant::ULongLong:
1353     case QVariant::Url:
1354     case QVariant::ByteArray:
1355     case QVariant::StringList:
1356     case QVariant::Brush:
1357         return true;
1358     default:
1359         break;
1360     }
1361 
1362     if (propertyType == designerFlagTypeId())
1363         return true;
1364     if (propertyType == designerAlignmentTypeId())
1365         return true;
1366     if (propertyType == designerPixmapTypeId())
1367         return true;
1368     if (propertyType == designerIconTypeId())
1369         return true;
1370     if (propertyType == designerStringTypeId())
1371         return true;
1372     if (propertyType == designerKeySequenceTypeId())
1373         return true;
1374     return QtVariantPropertyManager::isPropertyTypeSupported(propertyType);
1375 }
1376 
valueText(const QtProperty * property) const1377 QString DesignerPropertyManager::valueText(const QtProperty *property) const
1378 {
1379     if (m_flagValues.contains(const_cast<QtProperty *>(property))) {
1380         const FlagData data = m_flagValues.value(const_cast<QtProperty *>(property));
1381         const uint v = data.val;
1382         const QChar bar = QLatin1Char('|');
1383         QString valueStr;
1384         const QList<QPair<QString, uint> > flags = data.flags;
1385         const  QList<QPair<QString, uint> >::const_iterator fcend = flags.constEnd();
1386         for (QList<QPair<QString, uint> >::const_iterator it = flags.constBegin(); it != fcend; ++it) {
1387             const uint val = it->second;
1388             const bool checked = (val == 0) ? (v == 0) : ((val & v) == val);
1389             if (checked) {
1390                 if (!valueStr.isEmpty())
1391                     valueStr += bar;
1392                 valueStr += it->first;
1393             }
1394         }
1395         return valueStr;
1396     }
1397     if (m_alignValues.contains(const_cast<QtProperty *>(property))) {
1398         const uint v = m_alignValues.value(const_cast<QtProperty *>(property));
1399         return tr("%1, %2").arg(indexHToString(alignToIndexH(v))).arg(indexVToString(alignToIndexV(v)));
1400     }
1401     if (m_paletteValues.contains(const_cast<QtProperty *>(property))) {
1402         const PaletteData data = m_paletteValues.value(const_cast<QtProperty *>(property));
1403         const uint mask = data.val.resolve();
1404         if (mask)
1405             return tr("Customized (%n roles)", 0, bitCount(mask));
1406         static const QString inherited = tr("Inherited");
1407         return inherited;
1408     }
1409     if (m_iconValues.contains(const_cast<QtProperty *>(property))) {
1410         const PropertySheetIconValue icon = m_iconValues.value(const_cast<QtProperty *>(property));
1411         const QString theme = icon.theme();
1412         if (!theme.isEmpty() && QIcon::hasThemeIcon(theme))
1413             return tr("[Theme] %1").arg(theme);
1414         const PropertySheetIconValue::ModeStateToPixmapMap paths = icon.paths();
1415         const PropertySheetIconValue::ModeStateToPixmapMap::const_iterator it = paths.constFind(qMakePair(QIcon::Normal, QIcon::Off));
1416         if (it == paths.constEnd())
1417             return QString();
1418         return QFileInfo(it.value().path()).fileName();
1419     }
1420     if (m_pixmapValues.contains(const_cast<QtProperty *>(property))) {
1421         const QString path =  m_pixmapValues.value(const_cast<QtProperty *>(property)).path();
1422         if (path.isEmpty())
1423             return QString();
1424         return QFileInfo(path).fileName();
1425     }
1426     if (m_uintValues.contains(const_cast<QtProperty *>(property))) {
1427         return QString::number(m_uintValues.value(const_cast<QtProperty *>(property)));
1428     }
1429     if (m_longLongValues.contains(const_cast<QtProperty *>(property))) {
1430         return QString::number(m_longLongValues.value(const_cast<QtProperty *>(property)));
1431     }
1432     if (m_uLongLongValues.contains(const_cast<QtProperty *>(property))) {
1433         return QString::number(m_uLongLongValues.value(const_cast<QtProperty *>(property)));
1434     }
1435     if (m_urlValues.contains(const_cast<QtProperty *>(property))) {
1436         return m_urlValues.value(const_cast<QtProperty *>(property)).toString();
1437     }
1438     if (m_byteArrayValues.contains(const_cast<QtProperty *>(property))) {
1439         return QString::fromUtf8(m_byteArrayValues.value(const_cast<QtProperty *>(property)));
1440     }
1441     if (m_stringListValues.contains(const_cast<QtProperty *>(property))) {
1442         return m_stringListValues.value(const_cast<QtProperty *>(property)).join(QLatin1String("; "));
1443     }
1444     if (QtVariantPropertyManager::valueType(property) == QVariant::String || QtVariantPropertyManager::valueType(property) == designerStringTypeId()) {
1445         const QString str = (QtVariantPropertyManager::valueType(property) == QVariant::String) ? value(property).toString() : qvariant_cast<PropertySheetStringValue>(value(property)).value();
1446         const int validationMode = attributeValue(property, QLatin1String(validationModesAttributeC)).toInt();
1447         return TextPropertyEditor::stringToEditorString(str, static_cast<TextPropertyValidationMode>(validationMode));
1448     }
1449     if (QtVariantPropertyManager::valueType(property) == designerKeySequenceTypeId()) {
1450         return qvariant_cast<PropertySheetKeySequenceValue>(value(property)).value();
1451     }
1452     if (QtVariantPropertyManager::valueType(property) == QVariant::Bool) {
1453         return QString();
1454     }
1455 
1456     QString rc;
1457     if (m_brushManager.valueText(property, &rc))
1458         return rc;
1459     return QtVariantPropertyManager::valueText(property);
1460 }
1461 
reloadResourceProperties()1462 void DesignerPropertyManager::reloadResourceProperties()
1463 {
1464     DesignerIconCache *iconCache = 0;
1465     QMapIterator<QtProperty *, qdesigner_internal::PropertySheetIconValue> itIcon(m_iconValues);
1466     while (itIcon.hasNext()) {
1467         QtProperty *property = itIcon.next().key();
1468         PropertySheetIconValue icon = itIcon.value();
1469 
1470         QIcon defaultIcon = m_defaultIcons.value(property);
1471         if (!icon.paths().isEmpty()) {
1472             if (!iconCache) {
1473                 QDesignerFormWindowInterface *formWindow = QDesignerFormWindowInterface::findFormWindow(m_object);
1474                 qdesigner_internal::FormWindowBase *fwb = qobject_cast<qdesigner_internal::FormWindowBase *>(formWindow);
1475                 iconCache = fwb->iconCache();
1476             }
1477             if (iconCache)
1478                 defaultIcon = iconCache->icon(icon);
1479         }
1480 
1481         QMap<QPair<QIcon::Mode, QIcon::State>, PropertySheetPixmapValue> iconPaths = icon.paths();
1482 
1483         QMap<QPair<QIcon::Mode, QIcon::State>, QtProperty *> subProperties = m_propertyToIconSubProperties.value(property);
1484         QMapIterator<QPair<QIcon::Mode, QIcon::State>, QtProperty *> itSub(subProperties);
1485         while (itSub.hasNext()) {
1486             const QPair<QIcon::Mode, QIcon::State> pair = itSub.next().key();
1487             QtVariantProperty *subProperty = variantProperty(itSub.value());
1488             subProperty->setAttribute(QLatin1String(defaultResourceAttributeC),
1489                                       defaultIcon.pixmap(16, 16, pair.first, pair.second));
1490         }
1491 
1492         emit propertyChanged(property);
1493         emit QtVariantPropertyManager::valueChanged(property, QVariant::fromValue(itIcon.value()));
1494     }
1495     QMapIterator<QtProperty *, qdesigner_internal::PropertySheetPixmapValue> itPix(m_pixmapValues);
1496     while (itPix.hasNext()) {
1497         QtProperty *property = itPix.next().key();
1498         emit propertyChanged(property);
1499         emit QtVariantPropertyManager::valueChanged(property, QVariant::fromValue(itPix.value()));
1500     }
1501 }
1502 
valueIcon(const QtProperty * property) const1503 QIcon DesignerPropertyManager::valueIcon(const QtProperty *property) const
1504 {
1505     if (m_iconValues.contains(const_cast<QtProperty *>(property))) {
1506         if (!property->isModified())
1507             return m_defaultIcons.value(const_cast<QtProperty *>(property)).pixmap(16, 16);
1508         QDesignerFormWindowInterface *formWindow = QDesignerFormWindowInterface::findFormWindow(m_object);
1509         qdesigner_internal::FormWindowBase *fwb = qobject_cast<qdesigner_internal::FormWindowBase *>(formWindow);
1510         if (fwb)
1511             return fwb->iconCache()->icon(m_iconValues.value(const_cast<QtProperty *>(property))).pixmap(16, 16);
1512     } else if (m_pixmapValues.contains(const_cast<QtProperty *>(property))) {
1513         if (!property->isModified())
1514             return m_defaultPixmaps.value(const_cast<QtProperty *>(property));
1515         QDesignerFormWindowInterface *formWindow = QDesignerFormWindowInterface::findFormWindow(m_object);
1516         qdesigner_internal::FormWindowBase *fwb = qobject_cast<qdesigner_internal::FormWindowBase *>(formWindow);
1517         if (fwb)
1518             return fwb->pixmapCache()->pixmap(m_pixmapValues.value(const_cast<QtProperty *>(property)));
1519     } else if (m_stringThemeAttributes.value(const_cast<QtProperty *>(property), false)) {
1520         return QIcon::fromTheme(value(property).toString());
1521     } else {
1522         QIcon rc;
1523         if (m_brushManager.valueIcon(property, &rc))
1524             return rc;
1525     }
1526 
1527     return QtVariantPropertyManager::valueIcon(property);
1528 }
1529 
value(const QtProperty * property) const1530 QVariant DesignerPropertyManager::value(const QtProperty *property) const
1531 {
1532     if (m_flagValues.contains(const_cast<QtProperty *>(property)))
1533         return m_flagValues.value(const_cast<QtProperty *>(property)).val;
1534     if (m_alignValues.contains(const_cast<QtProperty *>(property)))
1535         return m_alignValues.value(const_cast<QtProperty *>(property));
1536     if (m_paletteValues.contains(const_cast<QtProperty *>(property)))
1537         return m_paletteValues.value(const_cast<QtProperty *>(property)).val;
1538     if (m_iconValues.contains(const_cast<QtProperty *>(property)))
1539         return QVariant::fromValue(m_iconValues.value(const_cast<QtProperty *>(property)));
1540     if (m_pixmapValues.contains(const_cast<QtProperty *>(property)))
1541         return QVariant::fromValue(m_pixmapValues.value(const_cast<QtProperty *>(property)));
1542     if (m_stringValues.contains(const_cast<QtProperty *>(property)))
1543         return QVariant::fromValue(m_stringValues.value(const_cast<QtProperty *>(property)));
1544     if (m_keySequenceValues.contains(const_cast<QtProperty *>(property)))
1545         return QVariant::fromValue(m_keySequenceValues.value(const_cast<QtProperty *>(property)));
1546     if (m_uintValues.contains(const_cast<QtProperty *>(property)))
1547         return m_uintValues.value(const_cast<QtProperty *>(property));
1548     if (m_longLongValues.contains(const_cast<QtProperty *>(property)))
1549         return m_longLongValues.value(const_cast<QtProperty *>(property));
1550     if (m_uLongLongValues.contains(const_cast<QtProperty *>(property)))
1551         return m_uLongLongValues.value(const_cast<QtProperty *>(property));
1552     if (m_urlValues.contains(const_cast<QtProperty *>(property)))
1553         return m_urlValues.value(const_cast<QtProperty *>(property));
1554     if (m_byteArrayValues.contains(const_cast<QtProperty *>(property)))
1555         return m_byteArrayValues.value(const_cast<QtProperty *>(property));
1556     if (m_stringListValues.contains(const_cast<QtProperty *>(property)))
1557         return m_stringListValues.value(const_cast<QtProperty *>(property));
1558 
1559     QVariant rc;
1560     if (m_brushManager.value(property, &rc))
1561         return rc;
1562     return QtVariantPropertyManager::value(property);
1563 }
1564 
valueType(int propertyType) const1565 int DesignerPropertyManager::valueType(int propertyType) const
1566 {
1567     switch (propertyType) {
1568     case QVariant::Palette:
1569     case QVariant::UInt:
1570     case QVariant::LongLong:
1571     case QVariant::ULongLong:
1572     case QVariant::Url:
1573     case QVariant::ByteArray:
1574     case QVariant::StringList:
1575     case QVariant::Brush:
1576         return propertyType;
1577     default:
1578         break;
1579     }
1580     if (propertyType == designerFlagTypeId())
1581         return QVariant::UInt;
1582     if (propertyType == designerAlignmentTypeId())
1583         return QVariant::UInt;
1584     if (propertyType == designerPixmapTypeId())
1585         return propertyType;
1586     if (propertyType == designerIconTypeId())
1587         return propertyType;
1588     if (propertyType == designerStringTypeId())
1589         return propertyType;
1590     if (propertyType == designerKeySequenceTypeId())
1591         return propertyType;
1592     return QtVariantPropertyManager::valueType(propertyType);
1593 }
1594 
setValue(QtProperty * property,const QVariant & value)1595 void DesignerPropertyManager::setValue(QtProperty *property, const QVariant &value)
1596 {
1597     const PropertyFlagDataMap::iterator fit = m_flagValues.find(property);
1598 
1599     if (fit !=  m_flagValues.end()) {
1600         if (value.type() != QVariant::UInt && !value.canConvert(QVariant::UInt))
1601             return;
1602 
1603         const uint v = value.toUInt();
1604 
1605         FlagData data = fit.value();
1606         if (data.val == v)
1607             return;
1608 
1609         // set Value
1610 
1611         const QList<uint> values = data.values;
1612         const QList<QtProperty *> subFlags = m_propertyToFlags.value(property);
1613         const int subFlagCount = subFlags.count();
1614         for (int i = 0; i < subFlagCount; ++i) {
1615             QtVariantProperty *subFlag = variantProperty(subFlags.at(i));
1616             const uint val = values.at(i);
1617             const bool checked = (val == 0) ? (v == 0) : ((val & v) == val);
1618             subFlag->setValue(checked);
1619         }
1620 
1621         for (int i = 0; i < subFlagCount; ++i) {
1622             QtVariantProperty *subFlag = variantProperty(subFlags.at(i));
1623             const uint val = values.at(i);
1624             const bool checked = (val == 0) ? (v == 0) : ((val & v) == val);
1625             bool enabled = true;
1626             if (val == 0) {
1627                 if (checked)
1628                     enabled = false;
1629             } else if (bitCount(val) > 1) {
1630                 // Disabled if all flags contained in the mask are checked
1631                 uint currentMask = 0;
1632                 for (int j = 0; j < subFlagCount; ++j) {
1633                     QtVariantProperty *subFlag = variantProperty(subFlags.at(j));
1634                     if (bitCount(values.at(j)) == 1)
1635                         currentMask |= subFlag->value().toBool() ? values.at(j) : 0;
1636                 }
1637                 if ((currentMask & values.at(i)) == values.at(i))
1638                     enabled = false;
1639             }
1640             subFlag->setEnabled(enabled);
1641         }
1642 
1643         data.val = v;
1644         fit.value() = data;
1645 
1646         emit QtVariantPropertyManager::valueChanged(property, data.val);
1647         emit propertyChanged(property);
1648 
1649         return;
1650     } else if (m_alignValues.contains(property)) {
1651         if (value.type() != QVariant::UInt && !value.canConvert(QVariant::UInt))
1652             return;
1653 
1654         const uint v = value.toUInt();
1655 
1656         uint val = m_alignValues.value(property);
1657 
1658         if (val == v)
1659             return;
1660 
1661         QtVariantProperty *alignH = variantProperty(m_propertyToAlignH.value(property));
1662         QtVariantProperty *alignV = variantProperty(m_propertyToAlignV.value(property));
1663 
1664         if (alignH)
1665             alignH->setValue(alignToIndexH(v));
1666         if (alignV)
1667             alignV->setValue(alignToIndexV(v));
1668 
1669         m_alignValues[property] = v;
1670 
1671         emit QtVariantPropertyManager::valueChanged(property, v);
1672         emit propertyChanged(property);
1673 
1674         return;
1675     } else if (m_stringValues.contains(property)) {
1676         if (value.userType() != designerStringTypeId())
1677             return;
1678 
1679         const PropertySheetStringValue v = qvariant_cast<PropertySheetStringValue>(value);
1680 
1681         const PropertySheetStringValue val = m_stringValues.value(property);
1682 
1683         if (val == v)
1684             return;
1685 
1686         QtVariantProperty *comment = variantProperty(m_stringToComment.value(property));
1687         QtVariantProperty *translatable = variantProperty(m_stringToTranslatable.value(property));
1688         QtVariantProperty *disambiguation = variantProperty(m_stringToDisambiguation.value(property));
1689 
1690         if (comment)
1691             comment->setValue(v.comment());
1692         if (translatable)
1693             translatable->setValue(v.translatable());
1694         if (disambiguation)
1695             disambiguation->setValue(v.disambiguation());
1696 
1697         m_stringValues[property] = v;
1698 
1699         emit QtVariantPropertyManager::valueChanged(property, QVariant::fromValue(v));
1700         emit propertyChanged(property);
1701 
1702         return;
1703     } else if (m_keySequenceValues.contains(property)) {
1704         if (value.userType() != designerKeySequenceTypeId())
1705             return;
1706 
1707         const PropertySheetKeySequenceValue v = qvariant_cast<PropertySheetKeySequenceValue>(value);
1708 
1709         const PropertySheetKeySequenceValue val = m_keySequenceValues.value(property);
1710 
1711         if (val == v)
1712             return;
1713 
1714         QtVariantProperty *comment = variantProperty(m_keySequenceToComment.value(property));
1715         QtVariantProperty *translatable = variantProperty(m_keySequenceToTranslatable.value(property));
1716         QtVariantProperty *disambiguation = variantProperty(m_keySequenceToDisambiguation.value(property));
1717 
1718         if (comment)
1719             comment->setValue(v.comment());
1720         if (translatable)
1721             translatable->setValue(v.translatable());
1722         if (disambiguation)
1723             disambiguation->setValue(v.disambiguation());
1724 
1725         m_keySequenceValues[property] = v;
1726 
1727         emit QtVariantPropertyManager::valueChanged(property, QVariant::fromValue(v));
1728         emit propertyChanged(property);
1729 
1730         return;
1731     } else if (m_paletteValues.contains(property)) {
1732         if (value.type() != QVariant::Palette && !value.canConvert(QVariant::Palette))
1733             return;
1734 
1735         QPalette p = qvariant_cast<QPalette>(value);
1736 
1737         PaletteData data = m_paletteValues.value(property);
1738 
1739         const uint mask = p.resolve();
1740         p = p.resolve(data.superPalette);
1741         p.resolve(mask);
1742 
1743         if (data.val == p && data.val.resolve() == p.resolve())
1744             return;
1745 
1746         data.val = p;
1747         m_paletteValues[property] = data;
1748 
1749         emit QtVariantPropertyManager::valueChanged(property, data.val);
1750         emit propertyChanged(property);
1751 
1752         return;
1753     } else if (m_iconValues.contains(property)) {
1754         if (value.userType() != designerIconTypeId())
1755             return;
1756 
1757         const PropertySheetIconValue icon = qvariant_cast<PropertySheetIconValue>(value);
1758 
1759         const PropertySheetIconValue oldIcon = m_iconValues.value(property);
1760         if (icon == oldIcon)
1761             return;
1762 
1763         m_iconValues[property] = icon;
1764 
1765         QIcon defaultIcon = m_defaultIcons.value(property);
1766         if (!icon.paths().isEmpty()) {
1767             QDesignerFormWindowInterface *formWindow = QDesignerFormWindowInterface::findFormWindow(m_object);
1768             qdesigner_internal::FormWindowBase *fwb = qobject_cast<qdesigner_internal::FormWindowBase *>(formWindow);
1769             if (fwb)
1770                 defaultIcon = fwb->iconCache()->icon(icon);
1771         }
1772 
1773         QMap<QPair<QIcon::Mode, QIcon::State>, PropertySheetPixmapValue> iconPaths = icon.paths();
1774 
1775         QMap<QPair<QIcon::Mode, QIcon::State>, QtProperty *> subProperties = m_propertyToIconSubProperties.value(property);
1776         QMapIterator<QPair<QIcon::Mode, QIcon::State>, QtProperty *> itSub(subProperties);
1777         while (itSub.hasNext()) {
1778             const QPair<QIcon::Mode, QIcon::State> pair = itSub.next().key();
1779             QtVariantProperty *subProperty = variantProperty(itSub.value());
1780             bool hasPath = iconPaths.contains(pair);
1781             subProperty->setModified(hasPath);
1782             subProperty->setValue(QVariant::fromValue(iconPaths.value(pair)));
1783             subProperty->setAttribute(QLatin1String(defaultResourceAttributeC),
1784                                       defaultIcon.pixmap(16, 16, pair.first, pair.second));
1785         }
1786         QtVariantProperty *themeSubProperty = variantProperty(m_propertyToTheme.value(property));
1787         if (themeSubProperty) {
1788             const QString theme = icon.theme();
1789             themeSubProperty->setModified(!theme.isEmpty());
1790             themeSubProperty->setValue(theme);
1791         }
1792 
1793         emit QtVariantPropertyManager::valueChanged(property, QVariant::fromValue(icon));
1794         emit propertyChanged(property);
1795 
1796         QString toolTip;
1797         const QMap<QPair<QIcon::Mode, QIcon::State>, PropertySheetPixmapValue>::ConstIterator itNormalOff =
1798                     iconPaths.constFind(qMakePair(QIcon::Normal, QIcon::Off));
1799         if (itNormalOff != iconPaths.constEnd())
1800             toolTip = itNormalOff.value().path();
1801         property->setToolTip(toolTip);
1802 
1803         return;
1804     } else if (m_pixmapValues.contains(property)) {
1805         if (value.userType() != designerPixmapTypeId())
1806             return;
1807 
1808         const PropertySheetPixmapValue pixmap = qvariant_cast<PropertySheetPixmapValue>(value);
1809 
1810         const PropertySheetPixmapValue oldPixmap = m_pixmapValues.value(property);
1811         if (pixmap == oldPixmap)
1812             return;
1813 
1814         m_pixmapValues[property] = pixmap;
1815 
1816         emit QtVariantPropertyManager::valueChanged(property, QVariant::fromValue(pixmap));
1817         emit propertyChanged(property);
1818 
1819         property->setToolTip(pixmap.path());
1820 
1821         return;
1822     } else if (m_uintValues.contains(property)) {
1823         if (value.type() != QVariant::UInt && !value.canConvert(QVariant::UInt))
1824             return;
1825 
1826         const uint v = value.toUInt(0);
1827 
1828         const uint oldValue = m_uintValues.value(property);
1829         if (v == oldValue)
1830             return;
1831 
1832         m_uintValues[property] = v;
1833 
1834         emit QtVariantPropertyManager::valueChanged(property, v);
1835         emit propertyChanged(property);
1836 
1837         return;
1838     } else if (m_longLongValues.contains(property)) {
1839         if (value.type() != QVariant::LongLong && !value.canConvert(QVariant::LongLong))
1840             return;
1841 
1842         const qlonglong v = value.toLongLong(0);
1843 
1844         const qlonglong oldValue = m_longLongValues.value(property);
1845         if (v == oldValue)
1846             return;
1847 
1848         m_longLongValues[property] = v;
1849 
1850         emit QtVariantPropertyManager::valueChanged(property, v);
1851         emit propertyChanged(property);
1852 
1853         return;
1854     } else if (m_uLongLongValues.contains(property)) {
1855         if (value.type() != QVariant::ULongLong && !value.canConvert(QVariant::ULongLong))
1856             return;
1857 
1858         qulonglong v = value.toULongLong(0);
1859 
1860         qulonglong oldValue = m_uLongLongValues.value(property);
1861         if (v == oldValue)
1862             return;
1863 
1864         m_uLongLongValues[property] = v;
1865 
1866         emit QtVariantPropertyManager::valueChanged(property, v);
1867         emit propertyChanged(property);
1868 
1869         return;
1870     } else if (m_urlValues.contains(property)) {
1871         if (value.type() != QVariant::Url && !value.canConvert(QVariant::Url))
1872             return;
1873 
1874         const QUrl v = value.toUrl();
1875 
1876         const QUrl oldValue = m_urlValues.value(property);
1877         if (v == oldValue)
1878             return;
1879 
1880         m_urlValues[property] = v;
1881 
1882         emit QtVariantPropertyManager::valueChanged(property, v);
1883         emit propertyChanged(property);
1884 
1885         return;
1886     } else if (m_byteArrayValues.contains(property)) {
1887         if (value.type() != QVariant::ByteArray && !value.canConvert(QVariant::ByteArray))
1888             return;
1889 
1890         const QByteArray v = value.toByteArray();
1891 
1892         const QByteArray oldValue = m_byteArrayValues.value(property);
1893         if (v == oldValue)
1894             return;
1895 
1896         m_byteArrayValues[property] = v;
1897 
1898         emit QtVariantPropertyManager::valueChanged(property, v);
1899         emit propertyChanged(property);
1900 
1901         return;
1902     } else if (m_stringListValues.contains(property)) {
1903         if (value.type() != QVariant::StringList && !value.canConvert(QVariant::StringList))
1904             return;
1905 
1906         const QStringList v = value.toStringList();
1907 
1908         const QStringList oldValue = m_stringListValues.value(property);
1909         if (v == oldValue)
1910             return;
1911 
1912         m_stringListValues[property] = v;
1913 
1914         emit QtVariantPropertyManager::valueChanged(property, v);
1915         emit propertyChanged(property);
1916 
1917         return;
1918     }
1919     switch (m_brushManager.setValue(this, property, value)) {
1920     case BrushPropertyManager::Unchanged:
1921         return;
1922     case BrushPropertyManager::Changed:
1923         emit QtVariantPropertyManager::valueChanged(property, value);
1924         emit propertyChanged(property);
1925         return;
1926     default:
1927         break;
1928     }
1929     m_fontManager.setValue(this, property, value);
1930     QtVariantPropertyManager::setValue(property, value);
1931     if (QtVariantPropertyManager::valueType(property) == QVariant::String)
1932         property->setToolTip(DesignerPropertyManager::value(property).toString());
1933     else if (QtVariantPropertyManager::valueType(property) == designerStringTypeId())
1934         property->setToolTip(qvariant_cast<PropertySheetStringValue>(DesignerPropertyManager::value(property)).value());
1935     else if (QtVariantPropertyManager::valueType(property) == designerKeySequenceTypeId())
1936         property->setToolTip(qvariant_cast<PropertySheetKeySequenceValue>(DesignerPropertyManager::value(property)).value());
1937     else if (QtVariantPropertyManager::valueType(property) == QVariant::Bool)
1938         property->setToolTip(QtVariantPropertyManager::valueText(property));
1939 }
1940 
initializeProperty(QtProperty * property)1941 void DesignerPropertyManager::initializeProperty(QtProperty *property)
1942 {
1943     m_resetMap[property] = false;
1944 
1945     const int type = propertyType(property);
1946     m_fontManager.preInitializeProperty(property, type, m_resetMap);
1947     switch (type) {
1948     case QVariant::Palette:
1949         m_paletteValues[property] = PaletteData();
1950         break;
1951     case QVariant::String:
1952         m_stringAttributes[property] = ValidationSingleLine;
1953         m_stringFontAttributes[property] = QApplication::font();
1954         m_stringThemeAttributes[property] = false;
1955         break;
1956     case QVariant::UInt:
1957         m_uintValues[property] = 0;
1958         break;
1959     case QVariant::LongLong:
1960         m_longLongValues[property] = 0;
1961         break;
1962     case QVariant::ULongLong:
1963         m_uLongLongValues[property] = 0;
1964         break;
1965     case QVariant::Url:
1966         m_urlValues[property] = QUrl();
1967         break;
1968     case QVariant::ByteArray:
1969         m_byteArrayValues[property] = 0;
1970         break;
1971     case QVariant::StringList:
1972         m_stringListValues[property] = QStringList();
1973         break;
1974     case QVariant::Brush:
1975         m_brushManager.initializeProperty(this, property, enumTypeId());
1976         break;
1977     default:
1978         if (type == designerFlagTypeId()) {
1979             m_flagValues[property] = FlagData();
1980             m_propertyToFlags[property] = QList<QtProperty *>();
1981         }  else if (type == designerAlignmentTypeId()) {
1982             const uint align = Qt::AlignLeft | Qt::AlignVCenter;
1983             m_alignValues[property] = align;
1984 
1985             QtVariantProperty *alignH = addProperty(enumTypeId(), tr("Horizontal"));
1986             QStringList namesH;
1987             namesH << indexHToString(0) << indexHToString(1) << indexHToString(2) << indexHToString(3);
1988             alignH->setAttribute(QLatin1String("enumNames"), namesH);
1989             alignH->setValue(alignToIndexH(align));
1990             m_propertyToAlignH[property] = alignH;
1991             m_alignHToProperty[alignH] = property;
1992             property->addSubProperty(alignH);
1993 
1994             QtVariantProperty *alignV = addProperty(enumTypeId(), tr("Vertical"));
1995             QStringList namesV;
1996             namesV << indexVToString(0) << indexVToString(1) << indexVToString(2);
1997             alignV->setAttribute(QLatin1String("enumNames"), namesV);
1998             alignV->setValue(alignToIndexV(align));
1999             m_propertyToAlignV[property] = alignV;
2000             m_alignVToProperty[alignV] = property;
2001             property->addSubProperty(alignV);
2002         } else if (type == designerPixmapTypeId()) {
2003             m_pixmapValues[property] = PropertySheetPixmapValue();
2004             m_defaultPixmaps[property] = QPixmap();
2005         } else if (type == designerIconTypeId()) {
2006             m_iconValues[property] = PropertySheetIconValue();
2007             m_defaultIcons[property] = QIcon();
2008 
2009             QtVariantProperty *themeProp = addProperty(QVariant::String, tr("Theme"));
2010             themeProp->setAttribute(QLatin1String(themeAttributeC), true);
2011             m_iconSubPropertyToProperty[themeProp] = property;
2012             m_propertyToTheme[property] = themeProp;
2013             m_resetMap[themeProp] = true;
2014             property->addSubProperty(themeProp);
2015 
2016             createIconSubProperty(property, QIcon::Normal, QIcon::Off, tr("Normal Off"));
2017             createIconSubProperty(property, QIcon::Normal, QIcon::On, tr("Normal On"));
2018             createIconSubProperty(property, QIcon::Disabled, QIcon::Off, tr("Disabled Off"));
2019             createIconSubProperty(property, QIcon::Disabled, QIcon::On, tr("Disabled On"));
2020             createIconSubProperty(property, QIcon::Active, QIcon::Off, tr("Active Off"));
2021             createIconSubProperty(property, QIcon::Active, QIcon::On, tr("Active On"));
2022             createIconSubProperty(property, QIcon::Selected, QIcon::Off, tr("Selected Off"));
2023             createIconSubProperty(property, QIcon::Selected, QIcon::On, tr("Selected On"));
2024         } else if (type == designerStringTypeId()) {
2025             PropertySheetStringValue val;
2026             m_stringValues[property] = val;
2027             m_stringAttributes[property] = ValidationMultiLine;
2028             m_stringFontAttributes[property] = QApplication::font();
2029             m_stringThemeAttributes[property] = false;
2030 
2031             QtVariantProperty *translatable = addProperty(QVariant::Bool, tr("translatable"));
2032             translatable->setValue(val.translatable());
2033             m_stringToTranslatable[property] = translatable;
2034             m_translatableToString[translatable] = property;
2035             property->addSubProperty(translatable);
2036 
2037             QtVariantProperty *disambiguation = addProperty(QVariant::String, tr("disambiguation"));
2038             disambiguation->setValue(val.disambiguation());
2039             m_stringToDisambiguation[property] = disambiguation;
2040             m_disambiguationToString[disambiguation] = property;
2041             property->addSubProperty(disambiguation);
2042 
2043             QtVariantProperty *comment = addProperty(QVariant::String, tr("comment"));
2044             comment->setValue(val.comment());
2045             m_stringToComment[property] = comment;
2046             m_commentToString[comment] = property;
2047             property->addSubProperty(comment);
2048         } else if (type == designerKeySequenceTypeId()) {
2049             PropertySheetKeySequenceValue val;
2050             m_keySequenceValues[property] = val;
2051 
2052             QtVariantProperty *translatable = addProperty(QVariant::Bool, tr("translatable"));
2053             translatable->setValue(val.translatable());
2054             m_keySequenceToTranslatable[property] = translatable;
2055             m_translatableToKeySequence[translatable] = property;
2056             property->addSubProperty(translatable);
2057 
2058             QtVariantProperty *disambiguation = addProperty(QVariant::String, tr("disambiguation"));
2059             disambiguation->setValue(val.disambiguation());
2060             m_keySequenceToDisambiguation[property] = disambiguation;
2061             m_disambiguationToKeySequence[disambiguation] = property;
2062             property->addSubProperty(disambiguation);
2063 
2064             QtVariantProperty *comment = addProperty(QVariant::String, tr("comment"));
2065             comment->setValue(val.comment());
2066             m_keySequenceToComment[property] = comment;
2067             m_commentToKeySequence[comment] = property;
2068             property->addSubProperty(comment);
2069         }
2070     }
2071 
2072     QtVariantPropertyManager::initializeProperty(property);
2073     m_fontManager.postInitializeProperty(this, property, type, DesignerPropertyManager::enumTypeId());
2074     if (type == QVariant::Double)
2075         setAttribute(property, QLatin1String("decimals"), 6);
2076 }
2077 
createIconSubProperty(QtProperty * iconProperty,QIcon::Mode mode,QIcon::State state,const QString & subName)2078 void DesignerPropertyManager::createIconSubProperty(QtProperty *iconProperty, QIcon::Mode mode, QIcon::State state, const QString &subName)
2079 {
2080     QPair<QIcon::Mode, QIcon::State> pair = qMakePair(mode, state);
2081     QtVariantProperty *subProp = addProperty(DesignerPropertyManager::designerPixmapTypeId(), subName);
2082     m_propertyToIconSubProperties[iconProperty][pair] = subProp;
2083     m_iconSubPropertyToState[subProp] = pair;
2084     m_iconSubPropertyToProperty[subProp] = iconProperty;
2085     m_resetMap[subProp] = true;
2086     iconProperty->addSubProperty(subProp);
2087 }
2088 
uninitializeProperty(QtProperty * property)2089 void DesignerPropertyManager::uninitializeProperty(QtProperty *property)
2090 {
2091     m_resetMap.remove(property);
2092 
2093     QListIterator<QtProperty *> itProp(m_propertyToFlags[property]);
2094     while (itProp.hasNext()) {
2095         QtProperty *prop = itProp.next();
2096         if (prop) {
2097             delete prop;
2098             m_flagToProperty.remove(prop);
2099         }
2100     }
2101     m_propertyToFlags.remove(property);
2102     m_flagValues.remove(property);
2103 
2104     QtProperty *alignH = m_propertyToAlignH.value(property);
2105     if (alignH) {
2106         delete alignH;
2107         m_alignHToProperty.remove(alignH);
2108     }
2109     QtProperty *alignV = m_propertyToAlignV.value(property);
2110     if (alignV) {
2111         delete alignV;
2112         m_alignVToProperty.remove(alignV);
2113     }
2114 
2115     QtProperty *stringComment = m_stringToComment.value(property);
2116     if (stringComment) {
2117         delete stringComment;
2118         m_commentToString.remove(stringComment);
2119     }
2120 
2121     QtProperty *stringTranslatable = m_stringToTranslatable.value(property);
2122     if (stringTranslatable) {
2123         delete stringTranslatable;
2124         m_translatableToString.remove(stringTranslatable);
2125     }
2126 
2127     QtProperty *stringDisambiguation = m_stringToDisambiguation.value(property);
2128     if (stringDisambiguation) {
2129         delete stringDisambiguation;
2130         m_disambiguationToString.remove(stringDisambiguation);
2131     }
2132 
2133     QtProperty *keySequenceComment = m_keySequenceToComment.value(property);
2134     if (keySequenceComment) {
2135         delete keySequenceComment;
2136         m_commentToKeySequence.remove(keySequenceComment);
2137     }
2138 
2139     QtProperty *keySequenceTranslatable = m_keySequenceToTranslatable.value(property);
2140     if (keySequenceTranslatable) {
2141         delete keySequenceTranslatable;
2142         m_translatableToKeySequence.remove(keySequenceTranslatable);
2143     }
2144 
2145     QtProperty *keySequenceDisambiguation = m_keySequenceToDisambiguation.value(property);
2146     if (keySequenceDisambiguation) {
2147         delete keySequenceDisambiguation;
2148         m_disambiguationToKeySequence.remove(keySequenceDisambiguation);
2149     }
2150 
2151     QtProperty *iconTheme = m_propertyToTheme.value(property);
2152     if (iconTheme) {
2153         delete iconTheme;
2154         m_iconSubPropertyToProperty.remove(iconTheme);
2155     }
2156 
2157     m_propertyToAlignH.remove(property);
2158     m_propertyToAlignV.remove(property);
2159 
2160     m_stringToComment.remove(property);
2161     m_stringToTranslatable.remove(property);
2162     m_stringToDisambiguation.remove(property);
2163     m_stringValues.remove(property);
2164     m_stringAttributes.remove(property);
2165     m_stringFontAttributes.remove(property);
2166 
2167     m_keySequenceToComment.remove(property);
2168     m_keySequenceToTranslatable.remove(property);
2169     m_keySequenceToDisambiguation.remove(property);
2170     m_keySequenceValues.remove(property);
2171 
2172     m_paletteValues.remove(property);
2173 
2174     m_iconValues.remove(property);
2175     m_defaultIcons.remove(property);
2176 
2177     m_pixmapValues.remove(property);
2178     m_defaultPixmaps.remove(property);
2179 
2180     QMap<QPair<QIcon::Mode, QIcon::State>, QtProperty *> iconSubProperties = m_propertyToIconSubProperties.value(property);
2181     QMapIterator<QPair<QIcon::Mode, QIcon::State>, QtProperty *> itIcon(iconSubProperties);
2182     while (itIcon.hasNext()) {
2183         QtProperty *subIcon = itIcon.next().value();
2184         delete subIcon;
2185         m_iconSubPropertyToState.remove(subIcon);
2186         m_iconSubPropertyToProperty.remove(subIcon);
2187     }
2188     m_propertyToIconSubProperties.remove(property);
2189     m_iconSubPropertyToState.remove(property);
2190     m_iconSubPropertyToProperty.remove(property);
2191 
2192     m_uintValues.remove(property);
2193     m_longLongValues.remove(property);
2194     m_uLongLongValues.remove(property);
2195     m_urlValues.remove(property);
2196     m_byteArrayValues.remove(property);
2197     m_stringListValues.remove(property);
2198 
2199     m_fontManager.uninitializeProperty(property);
2200     m_brushManager.uninitializeProperty(property);
2201 
2202     QtVariantPropertyManager::uninitializeProperty(property);
2203 }
2204 
2205 
resetFontSubProperty(QtProperty * property)2206 bool DesignerPropertyManager::resetFontSubProperty(QtProperty *property)
2207 {
2208     return m_fontManager.resetFontSubProperty(this, property);
2209 }
2210 
resetIconSubProperty(QtProperty * property)2211 bool DesignerPropertyManager::resetIconSubProperty(QtProperty *property)
2212 {
2213     QtProperty *iconProperty = m_iconSubPropertyToProperty.value(property);
2214     if (!iconProperty)
2215         return false;
2216 
2217     if (m_pixmapValues.contains(property)) {
2218         QtVariantProperty *pixmapProperty = variantProperty(property);
2219         pixmapProperty->setValue(QVariant::fromValue(PropertySheetPixmapValue()));
2220         return true;
2221     } else if (m_propertyToTheme.contains(iconProperty)) {
2222         QtVariantProperty *themeProperty = variantProperty(property);
2223         themeProperty->setValue(QString());
2224         return true;
2225     }
2226     return false;
2227 }
2228 
2229 // -------- DesignerEditorFactory
DesignerEditorFactory(QDesignerFormEditorInterface * core,QObject * parent)2230 DesignerEditorFactory::DesignerEditorFactory(QDesignerFormEditorInterface *core, QObject *parent) :
2231     QtVariantEditorFactory(parent),
2232     m_resetDecorator(new ResetDecorator(this)),
2233     m_changingPropertyValue(false),
2234     m_core(core),
2235     m_spacing(-1)
2236 {
2237     connect(m_resetDecorator, SIGNAL(resetProperty(QtProperty*)), this, SIGNAL(resetProperty(QtProperty*)));
2238 }
2239 
~DesignerEditorFactory()2240 DesignerEditorFactory::~DesignerEditorFactory()
2241 {
2242 }
2243 
setSpacing(int spacing)2244 void DesignerEditorFactory::setSpacing(int spacing)
2245 {
2246     m_spacing = spacing;
2247     m_resetDecorator->setSpacing(spacing);
2248 }
2249 
setFormWindowBase(qdesigner_internal::FormWindowBase * fwb)2250 void DesignerEditorFactory::setFormWindowBase(qdesigner_internal::FormWindowBase *fwb)
2251 {
2252     m_fwb = fwb;
2253     DesignerPixmapCache *cache = 0;
2254     if (fwb)
2255         cache = fwb->pixmapCache();
2256     QMapIterator<PixmapEditor *, QtProperty *> itPixmapEditor(m_editorToPixmapProperty);
2257     while (itPixmapEditor.hasNext()) {
2258         PixmapEditor *pe = itPixmapEditor.next().key();
2259         pe->setPixmapCache(cache);
2260     }
2261     QMapIterator<PixmapEditor *, QtProperty *> itIconEditor(m_editorToIconProperty);
2262     while (itIconEditor.hasNext()) {
2263         PixmapEditor *pe = itIconEditor.next().key();
2264         pe->setPixmapCache(cache);
2265     }
2266 }
2267 
connectPropertyManager(QtVariantPropertyManager * manager)2268 void DesignerEditorFactory::connectPropertyManager(QtVariantPropertyManager *manager)
2269 {
2270     m_resetDecorator->connectPropertyManager(manager);
2271     connect(manager, SIGNAL(attributeChanged(QtProperty*,QString,QVariant)),
2272                 this, SLOT(slotAttributeChanged(QtProperty*,QString,QVariant)));
2273     connect(manager, SIGNAL(valueChanged(QtProperty*,QVariant)),
2274                 this, SLOT(slotValueChanged(QtProperty*,QVariant)));
2275     connect(manager, SIGNAL(propertyChanged(QtProperty*)),
2276                 this, SLOT(slotPropertyChanged(QtProperty*)));
2277     QtVariantEditorFactory::connectPropertyManager(manager);
2278 }
2279 
disconnectPropertyManager(QtVariantPropertyManager * manager)2280 void DesignerEditorFactory::disconnectPropertyManager(QtVariantPropertyManager *manager)
2281 {
2282     m_resetDecorator->disconnectPropertyManager(manager);
2283     disconnect(manager, SIGNAL(attributeChanged(QtProperty*,QString,QVariant)),
2284                 this, SLOT(slotAttributeChanged(QtProperty*,QString,QVariant)));
2285     disconnect(manager, SIGNAL(valueChanged(QtProperty*,QVariant)),
2286                 this, SLOT(slotValueChanged(QtProperty*,QVariant)));
2287     disconnect(manager, SIGNAL(propertyChanged(QtProperty*)),
2288                 this, SLOT(slotPropertyChanged(QtProperty*)));
2289     QtVariantEditorFactory::disconnectPropertyManager(manager);
2290 }
2291 
2292 // A helper that calls a setter with a value on a pointer list of editor objects.
2293 // Could use QList<Editor*> instead of EditorContainer/Editor, but that crashes VS 6.
2294 template <class EditorContainer, class Editor, class SetterParameter, class Value>
applyToEditors(const EditorContainer & list,void (Editor::* setter)(SetterParameter),const Value & value)2295 static inline void applyToEditors(const EditorContainer &list, void (Editor::*setter)(SetterParameter), const Value &value)
2296 {
2297     typedef Q_TYPENAME EditorContainer::const_iterator ListIterator;
2298     if (list.empty()) {
2299         return;
2300     }
2301     const ListIterator end = list.constEnd();
2302     for (ListIterator it = list.constBegin(); it != end; ++it) {
2303         Editor &editor = *(*it);
2304         (editor.*setter)(value);
2305     }
2306 }
2307 
slotAttributeChanged(QtProperty * property,const QString & attribute,const QVariant & value)2308 void DesignerEditorFactory::slotAttributeChanged(QtProperty *property, const QString &attribute, const QVariant &value)
2309 {
2310     QtVariantPropertyManager *manager = propertyManager(property);
2311     const int type = manager->propertyType(property);
2312     if (type == DesignerPropertyManager::designerPixmapTypeId() && attribute == QLatin1String(defaultResourceAttributeC)) {
2313         const QPixmap pixmap = qvariant_cast<QPixmap>(value);
2314         applyToEditors(m_pixmapPropertyToEditors.value(property), &PixmapEditor::setDefaultPixmap, pixmap);
2315     } else if (type == DesignerPropertyManager::designerStringTypeId() || type == QVariant::String) {
2316         if (attribute == QLatin1String(validationModesAttributeC)) {
2317             const TextPropertyValidationMode validationMode = static_cast<TextPropertyValidationMode>(value.toInt());
2318             applyToEditors(m_stringPropertyToEditors.value(property), &TextEditor::setTextPropertyValidationMode, validationMode);
2319         }
2320         if (attribute == QLatin1String(fontAttributeC)) {
2321             const QFont font = qvariant_cast<QFont>(value);
2322             applyToEditors(m_stringPropertyToEditors.value(property), &TextEditor::setRichTextDefaultFont, font);
2323         }
2324         if (attribute == QLatin1String(themeAttributeC)) {
2325             const bool themeEnabled = value.toBool();
2326             applyToEditors(m_stringPropertyToEditors.value(property), &TextEditor::setIconThemeModeEnabled, themeEnabled);
2327         }
2328     } else if (type == QVariant::Palette && attribute == QLatin1String(superPaletteAttributeC)) {
2329         const QPalette palette = qvariant_cast<QPalette>(value);
2330         applyToEditors(m_palettePropertyToEditors.value(property), &PaletteEditorButton::setSuperPalette, palette);
2331     }
2332 }
2333 
slotPropertyChanged(QtProperty * property)2334 void DesignerEditorFactory::slotPropertyChanged(QtProperty *property)
2335 {
2336     QtVariantPropertyManager *manager = propertyManager(property);
2337     const int type = manager->propertyType(property);
2338     if (type == DesignerPropertyManager::designerIconTypeId()) {
2339         QPixmap defaultPixmap;
2340         if (!property->isModified())
2341             defaultPixmap = qvariant_cast<QIcon>(manager->attributeValue(property, QLatin1String(defaultResourceAttributeC))).pixmap(16, 16);
2342         else if (m_fwb)
2343             defaultPixmap = m_fwb->iconCache()->icon(qvariant_cast<PropertySheetIconValue>(manager->value(property))).pixmap(16, 16);
2344         QList<PixmapEditor *> editors = m_iconPropertyToEditors.value(property);
2345         QListIterator<PixmapEditor *> it(editors);
2346         while (it.hasNext()) {
2347             PixmapEditor *editor = it.next();
2348             editor->setDefaultPixmap(defaultPixmap);
2349         }
2350     }
2351 }
2352 
slotValueChanged(QtProperty * property,const QVariant & value)2353 void DesignerEditorFactory::slotValueChanged(QtProperty *property, const QVariant &value)
2354 {
2355     if (m_changingPropertyValue)
2356         return;
2357 
2358     QtVariantPropertyManager *manager = propertyManager(property);
2359     const int type = manager->propertyType(property);
2360     switch (type) {
2361     case QVariant::String:
2362         applyToEditors(m_stringPropertyToEditors.value(property), &TextEditor::setText, value.toString());
2363         break;
2364     case QVariant::Palette:
2365         applyToEditors(m_palettePropertyToEditors.value(property), &PaletteEditorButton::setPalette, qvariant_cast<QPalette>(value));
2366         break;
2367     case QVariant::UInt:
2368         applyToEditors(m_uintPropertyToEditors.value(property), &QLineEdit::setText, QString::number(value.toUInt()));
2369         break;
2370     case QVariant::LongLong:
2371         applyToEditors(m_longLongPropertyToEditors.value(property), &QLineEdit::setText, QString::number(value.toLongLong()));
2372         break;
2373     case QVariant::ULongLong:
2374         applyToEditors(m_uLongLongPropertyToEditors.value(property), &QLineEdit::setText, QString::number(value.toULongLong()));
2375         break;
2376     case QVariant::Url:
2377         applyToEditors(m_urlPropertyToEditors.value(property), &TextEditor::setText, value.toUrl().toString());
2378         break;
2379     case QVariant::ByteArray:
2380         applyToEditors(m_byteArrayPropertyToEditors.value(property), &TextEditor::setText, QString::fromUtf8(value.toByteArray()));
2381         break;
2382     case QVariant::StringList:
2383         applyToEditors(m_stringListPropertyToEditors.value(property), &StringListEditorButton::setStringList, value.toStringList());
2384         break;
2385     default:
2386         if (type == DesignerPropertyManager::designerIconTypeId()) {
2387             PropertySheetIconValue iconValue = qvariant_cast<PropertySheetIconValue>(value);
2388             const QString theme = iconValue.theme();
2389             applyToEditors(m_iconPropertyToEditors.value(property), &PixmapEditor::setTheme, iconValue.theme());
2390             applyToEditors(m_iconPropertyToEditors.value(property), &PixmapEditor::setPath, iconValue.pixmap(QIcon::Normal, QIcon::Off).path());
2391         } else if (type == DesignerPropertyManager::designerPixmapTypeId()) {
2392             applyToEditors(m_pixmapPropertyToEditors.value(property), &PixmapEditor::setPath, qvariant_cast<PropertySheetPixmapValue>(value).path());
2393         } else if (type == DesignerPropertyManager::designerStringTypeId()) {
2394             applyToEditors(m_stringPropertyToEditors.value(property), &TextEditor::setText, qvariant_cast<PropertySheetStringValue>(value).value());
2395         } else if (type == DesignerPropertyManager::designerKeySequenceTypeId()) {
2396             applyToEditors(m_keySequencePropertyToEditors.value(property), &QtKeySequenceEdit::setKeySequence, qvariant_cast<PropertySheetKeySequenceValue>(value).value());
2397         }
2398         break;
2399     }
2400 }
2401 
createTextEditor(QWidget * parent,TextPropertyValidationMode vm,const QString & value)2402 TextEditor *DesignerEditorFactory::createTextEditor(QWidget *parent, TextPropertyValidationMode vm, const QString &value)
2403 {
2404     TextEditor *rc = new TextEditor(m_core, parent);
2405     rc->setText(value);
2406     rc->setSpacing(m_spacing);
2407     rc->setTextPropertyValidationMode(vm);
2408     connect(rc, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*)));
2409     return rc;
2410 }
2411 
createEditor(QtVariantPropertyManager * manager,QtProperty * property,QWidget * parent)2412 QWidget *DesignerEditorFactory::createEditor(QtVariantPropertyManager *manager, QtProperty *property,
2413             QWidget *parent)
2414 {
2415     QWidget *editor = 0;
2416     const int type = manager->propertyType(property);
2417     switch (type) {
2418     case QVariant::Bool: {
2419         editor = QtVariantEditorFactory::createEditor(manager, property, parent);
2420         QtBoolEdit *boolEdit = qobject_cast<QtBoolEdit *>(editor);
2421         if (boolEdit)
2422             boolEdit->setTextVisible(false);
2423     }
2424         break;
2425     case QVariant::String: {
2426         const TextPropertyValidationMode tvm = static_cast<TextPropertyValidationMode>(manager->attributeValue(property, QLatin1String(validationModesAttributeC)).toInt());
2427         TextEditor *ed = createTextEditor(parent, tvm, manager->value(property).toString());
2428         const QVariant richTextDefaultFont = manager->attributeValue(property, QLatin1String(fontAttributeC));
2429         if (richTextDefaultFont.type() == QVariant::Font)
2430             ed->setRichTextDefaultFont(qvariant_cast<QFont>(richTextDefaultFont));
2431         const bool themeEnabled = manager->attributeValue(property, QLatin1String(themeAttributeC)).toBool();
2432         ed->setIconThemeModeEnabled(themeEnabled);
2433         m_stringPropertyToEditors[property].append(ed);
2434         m_editorToStringProperty[ed] = property;
2435         connect(ed, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*)));
2436         connect(ed, SIGNAL(textChanged(QString)), this, SLOT(slotStringTextChanged(QString)));
2437         editor = ed;
2438     }
2439         break;
2440     case QVariant::Palette: {
2441         PaletteEditorButton *ed = new PaletteEditorButton(m_core, qvariant_cast<QPalette>(manager->value(property)), parent);
2442         ed->setSuperPalette(qvariant_cast<QPalette>(manager->attributeValue(property, QLatin1String(superPaletteAttributeC))));
2443         m_palettePropertyToEditors[property].append(ed);
2444         m_editorToPaletteProperty[ed] = property;
2445         connect(ed, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*)));
2446         connect(ed, SIGNAL(paletteChanged(QPalette)), this, SLOT(slotPaletteChanged(QPalette)));
2447         editor = ed;
2448     }
2449         break;
2450     case QVariant::UInt: {
2451         QLineEdit *ed = new QLineEdit(parent);
2452         ed->setValidator(new QULongLongValidator(0, UINT_MAX, ed));
2453         ed->setText(QString::number(manager->value(property).toUInt()));
2454         m_uintPropertyToEditors[property].append(ed);
2455         m_editorToUintProperty[ed] = property;
2456         connect(ed, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*)));
2457         connect(ed, SIGNAL(textChanged(QString)), this, SLOT(slotUintChanged(QString)));
2458         editor = ed;
2459     }
2460         break;
2461     case QVariant::LongLong: {
2462         QLineEdit *ed = new QLineEdit(parent);
2463         ed->setValidator(new QLongLongValidator(ed));
2464         ed->setText(QString::number(manager->value(property).toLongLong()));
2465         m_longLongPropertyToEditors[property].append(ed);
2466         m_editorToLongLongProperty[ed] = property;
2467         connect(ed, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*)));
2468         connect(ed, SIGNAL(textChanged(QString)), this, SLOT(slotLongLongChanged(QString)));
2469         editor = ed;
2470     }
2471         break;
2472     case QVariant::ULongLong: {
2473         QLineEdit *ed = new QLineEdit(parent);
2474         ed->setValidator(new QULongLongValidator(ed));
2475         ed->setText(QString::number(manager->value(property).toULongLong()));
2476         m_uLongLongPropertyToEditors[property].append(ed);
2477         m_editorToULongLongProperty[ed] = property;
2478         connect(ed, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*)));
2479         connect(ed, SIGNAL(textChanged(QString)), this, SLOT(slotULongLongChanged(QString)));
2480         editor = ed;
2481     }
2482         break;
2483     case QVariant::Url: {
2484         TextEditor *ed = createTextEditor(parent, ValidationURL, manager->value(property).toUrl().toString());
2485         ed->setUpdateMode(TextPropertyEditor::UpdateOnFinished);
2486         m_urlPropertyToEditors[property].append(ed);
2487         m_editorToUrlProperty[ed] = property;
2488         connect(ed, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*)));
2489         connect(ed, SIGNAL(textChanged(QString)), this, SLOT(slotUrlChanged(QString)));
2490         editor = ed;
2491     }
2492         break;
2493     case QVariant::ByteArray: {
2494         TextEditor *ed = createTextEditor(parent, ValidationMultiLine, QString::fromUtf8(manager->value(property).toByteArray()));
2495         m_byteArrayPropertyToEditors[property].append(ed);
2496         m_editorToByteArrayProperty[ed] = property;
2497         connect(ed, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*)));
2498         connect(ed, SIGNAL(textChanged(QString)), this, SLOT(slotByteArrayChanged(QString)));
2499         editor = ed;
2500     }
2501         break;
2502     case QVariant::StringList: {
2503         StringListEditorButton *ed = new StringListEditorButton(manager->value(property).toStringList(), parent);
2504         m_stringListPropertyToEditors[property].append(ed);
2505         m_editorToStringListProperty[ed] = property;
2506         connect(ed, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*)));
2507         connect(ed, SIGNAL(stringListChanged(QStringList)), this, SLOT(slotStringListChanged(QStringList)));
2508         editor = ed;
2509     }
2510         break;
2511     default:
2512         if (type == DesignerPropertyManager::designerPixmapTypeId()) {
2513             PixmapEditor *ed = new PixmapEditor(m_core, parent);
2514             ed->setPixmapCache(m_fwb->pixmapCache());
2515             ed->setPath(qvariant_cast<PropertySheetPixmapValue>(manager->value(property)).path());
2516             ed->setDefaultPixmap(qvariant_cast<QPixmap>(manager->attributeValue(property, QLatin1String(defaultResourceAttributeC))));
2517             ed->setSpacing(m_spacing);
2518             m_pixmapPropertyToEditors[property].append(ed);
2519             m_editorToPixmapProperty[ed] = property;
2520             connect(ed, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*)));
2521             connect(ed, SIGNAL(pathChanged(QString)), this, SLOT(slotPixmapChanged(QString)));
2522             editor = ed;
2523         } else if (type == DesignerPropertyManager::designerIconTypeId()) {
2524             PixmapEditor *ed = new PixmapEditor(m_core, parent);
2525             ed->setPixmapCache(m_fwb->pixmapCache());
2526             ed->setIconThemeModeEnabled(true);
2527             PropertySheetIconValue value = qvariant_cast<PropertySheetIconValue>(manager->value(property));
2528             ed->setTheme(value.theme());
2529             ed->setPath(value.pixmap(QIcon::Normal, QIcon::Off).path());
2530             QPixmap defaultPixmap;
2531             if (!property->isModified())
2532                 defaultPixmap = qvariant_cast<QIcon>(manager->attributeValue(property, QLatin1String(defaultResourceAttributeC))).pixmap(16, 16);
2533             else if (m_fwb)
2534                 defaultPixmap = m_fwb->iconCache()->icon(value).pixmap(16, 16);
2535             ed->setDefaultPixmap(defaultPixmap);
2536             ed->setSpacing(m_spacing);
2537             m_iconPropertyToEditors[property].append(ed);
2538             m_editorToIconProperty[ed] = property;
2539             connect(ed, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*)));
2540             connect(ed, SIGNAL(pathChanged(QString)), this, SLOT(slotIconChanged(QString)));
2541             connect(ed, SIGNAL(themeChanged(QString)), this, SLOT(slotIconThemeChanged(QString)));
2542             editor = ed;
2543         } else if (type == DesignerPropertyManager::designerStringTypeId()) {
2544             const TextPropertyValidationMode tvm = static_cast<TextPropertyValidationMode>(manager->attributeValue(property, QLatin1String(validationModesAttributeC)).toInt());
2545             TextEditor *ed = createTextEditor(parent, tvm, qvariant_cast<PropertySheetStringValue>(manager->value(property)).value());
2546             const QVariant richTextDefaultFont = manager->attributeValue(property, QLatin1String(fontAttributeC));
2547             if (richTextDefaultFont.type() == QVariant::Font)
2548                 ed->setRichTextDefaultFont(qvariant_cast<QFont>(richTextDefaultFont));
2549             m_stringPropertyToEditors[property].append(ed);
2550             m_editorToStringProperty[ed] = property;
2551             connect(ed, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*)));
2552             connect(ed, SIGNAL(textChanged(QString)), this, SLOT(slotStringTextChanged(QString)));
2553             editor = ed;
2554         } else if (type == DesignerPropertyManager::designerKeySequenceTypeId()) {
2555             QtKeySequenceEdit *ed = new QtKeySequenceEdit(parent);
2556             ed->setKeySequence(qvariant_cast<PropertySheetKeySequenceValue>(manager->value(property)).value());
2557             m_keySequencePropertyToEditors[property].append(ed);
2558             m_editorToKeySequenceProperty[ed] = property;
2559             connect(ed, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*)));
2560             connect(ed, SIGNAL(keySequenceChanged(QKeySequence)), this, SLOT(slotKeySequenceChanged(QKeySequence)));
2561             editor = ed;
2562         } else {
2563             editor = QtVariantEditorFactory::createEditor(manager, property, parent);
2564         }
2565         break;
2566     }
2567     return m_resetDecorator->editor(editor,
2568             manager->variantProperty(property)->attributeValue(QLatin1String(resettableAttributeC)).toBool(),
2569             manager, property, parent);
2570 }
2571 
2572 template <class Editor>
removeEditor(QObject * object,QMap<QtProperty *,QList<Editor>> * propertyToEditors,QMap<Editor,QtProperty * > * editorToProperty)2573 bool removeEditor(QObject *object,
2574                 QMap<QtProperty *, QList<Editor> > *propertyToEditors,
2575                 QMap<Editor, QtProperty *> *editorToProperty)
2576 {
2577     if (!propertyToEditors)
2578         return false;
2579     if (!editorToProperty)
2580         return false;
2581     QMapIterator<Editor, QtProperty *> it(*editorToProperty);
2582     while (it.hasNext()) {
2583         Editor editor = it.next().key();
2584         if (editor == object) {
2585             QtProperty *prop = it.value();
2586             (*propertyToEditors)[prop].removeAll(editor);
2587             if ((*propertyToEditors)[prop].count() == 0)
2588                 propertyToEditors->remove(prop);
2589             editorToProperty->remove(editor);
2590             return true;
2591         }
2592     }
2593     return false;
2594 }
2595 
slotEditorDestroyed(QObject * object)2596 void DesignerEditorFactory::slotEditorDestroyed(QObject *object)
2597 {
2598     if (removeEditor(object, &m_stringPropertyToEditors, &m_editorToStringProperty))
2599         return;
2600     if (removeEditor(object, &m_keySequencePropertyToEditors, &m_editorToKeySequenceProperty))
2601         return;
2602     if (removeEditor(object, &m_palettePropertyToEditors, &m_editorToPaletteProperty))
2603         return;
2604     if (removeEditor(object, &m_pixmapPropertyToEditors, &m_editorToPixmapProperty))
2605         return;
2606     if (removeEditor(object, &m_iconPropertyToEditors, &m_editorToIconProperty))
2607         return;
2608     if (removeEditor(object, &m_uintPropertyToEditors, &m_editorToUintProperty))
2609         return;
2610     if (removeEditor(object, &m_longLongPropertyToEditors, &m_editorToLongLongProperty))
2611         return;
2612     if (removeEditor(object, &m_uLongLongPropertyToEditors, &m_editorToULongLongProperty))
2613         return;
2614     if (removeEditor(object, &m_urlPropertyToEditors, &m_editorToUrlProperty))
2615         return;
2616     if (removeEditor(object, &m_byteArrayPropertyToEditors, &m_editorToByteArrayProperty))
2617         return;
2618     if (removeEditor(object, &m_stringListPropertyToEditors, &m_editorToStringListProperty))
2619         return;
2620 }
2621 
2622 template<class Editor>
updateManager(QtVariantEditorFactory * factory,bool * changingPropertyValue,const QMap<Editor,QtProperty * > & editorToProperty,QWidget * editor,const QVariant & value)2623 bool updateManager(QtVariantEditorFactory *factory, bool *changingPropertyValue,
2624         const QMap<Editor, QtProperty *> &editorToProperty, QWidget *editor, const QVariant &value)
2625 {
2626     if (!editor)
2627         return false;
2628     QMapIterator<Editor, QtProperty *> it(editorToProperty);
2629     while (it.hasNext()) {
2630         if (it.next().key() == editor) {
2631             QtProperty *prop = it.value();
2632             QtVariantPropertyManager *manager = factory->propertyManager(prop);
2633             *changingPropertyValue = true;
2634             manager->variantProperty(prop)->setValue(value);
2635             *changingPropertyValue = false;
2636             return true;
2637         }
2638     }
2639     return false;
2640 }
2641 
slotUintChanged(const QString & value)2642 void DesignerEditorFactory::slotUintChanged(const QString &value)
2643 {
2644     updateManager(this, &m_changingPropertyValue, m_editorToUintProperty, qobject_cast<QWidget *>(sender()), value.toUInt());
2645 }
2646 
slotLongLongChanged(const QString & value)2647 void DesignerEditorFactory::slotLongLongChanged(const QString &value)
2648 {
2649     updateManager(this, &m_changingPropertyValue, m_editorToLongLongProperty, qobject_cast<QWidget *>(sender()), value.toLongLong());
2650 }
2651 
slotULongLongChanged(const QString & value)2652 void DesignerEditorFactory::slotULongLongChanged(const QString &value)
2653 {
2654     updateManager(this, &m_changingPropertyValue, m_editorToULongLongProperty, qobject_cast<QWidget *>(sender()), value.toULongLong());
2655 }
2656 
slotUrlChanged(const QString & value)2657 void DesignerEditorFactory::slotUrlChanged(const QString &value)
2658 {
2659     updateManager(this, &m_changingPropertyValue, m_editorToUrlProperty, qobject_cast<QWidget *>(sender()), QUrl(value));
2660 }
2661 
slotByteArrayChanged(const QString & value)2662 void DesignerEditorFactory::slotByteArrayChanged(const QString &value)
2663 {
2664     updateManager(this, &m_changingPropertyValue, m_editorToByteArrayProperty, qobject_cast<QWidget *>(sender()), value.toUtf8());
2665 }
2666 
slotStringTextChanged(const QString & value)2667 void DesignerEditorFactory::slotStringTextChanged(const QString &value)
2668 {
2669     QMapIterator<TextEditor *, QtProperty *> it(m_editorToStringProperty);
2670     while (it.hasNext()) {
2671         if (it.next().key() == sender()) {
2672             QtProperty *prop = it.value();
2673             QtVariantPropertyManager *manager = propertyManager(prop);
2674             QtVariantProperty *varProp = manager->variantProperty(prop);
2675             QVariant val = varProp->value();
2676             if (val.userType() == DesignerPropertyManager::designerStringTypeId()) {
2677                 PropertySheetStringValue strVal = qvariant_cast<PropertySheetStringValue>(val);
2678                 strVal.setValue(value);
2679                 // Disable translation if no translation subproperties exist.
2680                 if (varProp->subProperties().empty())
2681                     strVal.setTranslatable(false);
2682                 val = QVariant::fromValue(strVal);
2683             } else {
2684                 val = QVariant(value);
2685             }
2686             m_changingPropertyValue = true;
2687             manager->variantProperty(prop)->setValue(val);
2688             m_changingPropertyValue = false;
2689         }
2690     }
2691 }
2692 
slotKeySequenceChanged(const QKeySequence & value)2693 void DesignerEditorFactory::slotKeySequenceChanged(const QKeySequence &value)
2694 {
2695     QMapIterator<QtKeySequenceEdit *, QtProperty *> it(m_editorToKeySequenceProperty);
2696     while (it.hasNext()) {
2697         if (it.next().key() == sender()) {
2698             QtProperty *prop = it.value();
2699             QtVariantPropertyManager *manager = propertyManager(prop);
2700             QtVariantProperty *varProp = manager->variantProperty(prop);
2701             QVariant val = varProp->value();
2702             if (val.userType() == DesignerPropertyManager::designerKeySequenceTypeId()) {
2703                 PropertySheetKeySequenceValue keyVal = qvariant_cast<PropertySheetKeySequenceValue>(val);
2704                 keyVal.setValue(value);
2705                 val = QVariant::fromValue(keyVal);
2706             } else {
2707                 val = QVariant::fromValue(value);
2708             }
2709             m_changingPropertyValue = true;
2710             manager->variantProperty(prop)->setValue(val);
2711             m_changingPropertyValue = false;
2712         }
2713     }
2714 }
2715 
slotPaletteChanged(const QPalette & value)2716 void DesignerEditorFactory::slotPaletteChanged(const QPalette &value)
2717 {
2718     updateManager(this, &m_changingPropertyValue, m_editorToPaletteProperty, qobject_cast<QWidget *>(sender()), QVariant::fromValue(value));
2719 }
2720 
slotPixmapChanged(const QString & value)2721 void DesignerEditorFactory::slotPixmapChanged(const QString &value)
2722 {
2723     updateManager(this, &m_changingPropertyValue, m_editorToPixmapProperty, qobject_cast<QWidget *>(sender()),
2724                     QVariant::fromValue(PropertySheetPixmapValue(value)));
2725 }
2726 
slotIconChanged(const QString & value)2727 void DesignerEditorFactory::slotIconChanged(const QString &value)
2728 {
2729     updateManager(this, &m_changingPropertyValue, m_editorToIconProperty, qobject_cast<QWidget *>(sender()),
2730                     QVariant::fromValue(PropertySheetIconValue(PropertySheetPixmapValue(value))));
2731 }
2732 
slotIconThemeChanged(const QString & value)2733 void DesignerEditorFactory::slotIconThemeChanged(const QString &value)
2734 {
2735     PropertySheetIconValue icon;
2736     icon.setTheme(value);
2737     updateManager(this, &m_changingPropertyValue, m_editorToIconProperty, qobject_cast<QWidget *>(sender()),
2738                     QVariant::fromValue(icon));
2739 }
2740 
slotStringListChanged(const QStringList & value)2741 void DesignerEditorFactory::slotStringListChanged(const QStringList &value)
2742 {
2743     updateManager(this, &m_changingPropertyValue, m_editorToStringListProperty, qobject_cast<QWidget *>(sender()), QVariant::fromValue(value));
2744 }
2745 
~ResetDecorator()2746 ResetDecorator::~ResetDecorator()
2747 {
2748     QList<ResetWidget *> editors = m_resetWidgetToProperty.keys();
2749     QListIterator<ResetWidget *> it(editors);
2750     while (it.hasNext())
2751         delete it.next();
2752 }
2753 
connectPropertyManager(QtAbstractPropertyManager * manager)2754 void ResetDecorator::connectPropertyManager(QtAbstractPropertyManager *manager)
2755 {
2756     connect(manager, SIGNAL(propertyChanged(QtProperty*)),
2757             this, SLOT(slotPropertyChanged(QtProperty*)));
2758 }
2759 
disconnectPropertyManager(QtAbstractPropertyManager * manager)2760 void ResetDecorator::disconnectPropertyManager(QtAbstractPropertyManager *manager)
2761 {
2762     disconnect(manager, SIGNAL(propertyChanged(QtProperty*)),
2763             this, SLOT(slotPropertyChanged(QtProperty*)));
2764 }
2765 
setSpacing(int spacing)2766 void ResetDecorator::setSpacing(int spacing)
2767 {
2768     m_spacing = spacing;
2769 }
2770 
editor(QWidget * subEditor,bool resettable,QtAbstractPropertyManager * manager,QtProperty * property,QWidget * parent)2771 QWidget *ResetDecorator::editor(QWidget *subEditor, bool resettable, QtAbstractPropertyManager *manager, QtProperty *property,
2772             QWidget *parent)
2773 {
2774     Q_UNUSED(manager)
2775 
2776     ResetWidget *resetWidget = 0;
2777     if (resettable) {
2778         resetWidget = new ResetWidget(property, parent);
2779         resetWidget->setSpacing(m_spacing);
2780         resetWidget->setResetEnabled(property->isModified());
2781         resetWidget->setValueText(property->valueText());
2782         resetWidget->setValueIcon(property->valueIcon());
2783         resetWidget->setAutoFillBackground(true);
2784         connect(resetWidget, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*)));
2785         connect(resetWidget, SIGNAL(resetProperty(QtProperty*)), this, SIGNAL(resetProperty(QtProperty*)));
2786         m_createdResetWidgets[property].append(resetWidget);
2787         m_resetWidgetToProperty[resetWidget] = property;
2788     }
2789     if (subEditor) {
2790         if (resetWidget) {
2791             subEditor->setParent(resetWidget);
2792             resetWidget->setWidget(subEditor);
2793         }
2794     }
2795     if (resetWidget)
2796         return resetWidget;
2797     return subEditor;
2798 }
2799 
slotPropertyChanged(QtProperty * property)2800 void ResetDecorator::slotPropertyChanged(QtProperty *property)
2801 {
2802     QMap<QtProperty *, QList<ResetWidget *> >::ConstIterator prIt = m_createdResetWidgets.constFind(property);
2803     if (prIt == m_createdResetWidgets.constEnd())
2804         return;
2805 
2806     const QList<ResetWidget *> editors = prIt.value();
2807     const QList<ResetWidget *>::ConstIterator cend = editors.constEnd();
2808     for (QList<ResetWidget *>::ConstIterator itEditor = editors.constBegin(); itEditor != cend; ++itEditor) {
2809         ResetWidget *widget = *itEditor;
2810         widget->setResetEnabled(property->isModified());
2811         widget->setValueText(property->valueText());
2812         widget->setValueIcon(property->valueIcon());
2813     }
2814 }
2815 
slotEditorDestroyed(QObject * object)2816 void ResetDecorator::slotEditorDestroyed(QObject *object)
2817 {
2818     const  QMap<ResetWidget *, QtProperty *>::ConstIterator rcend = m_resetWidgetToProperty.constEnd();
2819     for (QMap<ResetWidget *, QtProperty *>::ConstIterator itEditor =  m_resetWidgetToProperty.constBegin(); itEditor != rcend; ++itEditor) {
2820         if (itEditor.key() == object) {
2821             ResetWidget *editor = itEditor.key();
2822             QtProperty *property = itEditor.value();
2823             m_resetWidgetToProperty.remove(editor);
2824             m_createdResetWidgets[property].removeAll(editor);
2825             if (m_createdResetWidgets[property].isEmpty())
2826                 m_createdResetWidgets.remove(property);
2827             return;
2828         }
2829     }
2830 }
2831 
2832 }
2833 
2834 QT_END_NAMESPACE
2835 
2836 #include "designerpropertymanager.moc"
2837