summaryrefslogtreecommitdiffstats
path: root/src/shared
diff options
context:
space:
mode:
Diffstat (limited to 'src/shared')
-rw-r--r--src/shared/deviceskin/deviceskin.cpp857
-rw-r--r--src/shared/deviceskin/deviceskin.h174
-rw-r--r--src/shared/deviceskin/deviceskin.pri12
-rw-r--r--src/shared/deviceskin/skins/ClamshellPhone.qrc5
-rw-r--r--src/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone.skin30
-rw-r--r--src/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone1-5-closed.pngbin0 -> 68200 bytes
-rw-r--r--src/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone1-5-pressed.pngbin0 -> 113907 bytes
-rw-r--r--src/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone1-5.pngbin0 -> 113450 bytes
-rw-r--r--src/shared/deviceskin/skins/ClamshellPhone.skin/defaultbuttons.conf78
-rw-r--r--src/shared/deviceskin/skins/PortableMedia.qrc5
-rw-r--r--src/shared/deviceskin/skins/PortableMedia.skin/PortableMedia.skin14
-rw-r--r--src/shared/deviceskin/skins/PortableMedia.skin/defaultbuttons.conf23
-rw-r--r--src/shared/deviceskin/skins/PortableMedia.skin/portablemedia-pressed.pngbin0 -> 6183 bytes
-rw-r--r--src/shared/deviceskin/skins/PortableMedia.skin/portablemedia.pngbin0 -> 6182 bytes
-rw-r--r--src/shared/deviceskin/skins/PortableMedia.skin/portablemedia.xcfbin0 -> 41592 bytes
-rw-r--r--src/shared/deviceskin/skins/S60-QVGA-Candybar.qrc5
-rw-r--r--src/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar-down.pngbin0 -> 161184 bytes
-rw-r--r--src/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar.pngbin0 -> 156789 bytes
-rw-r--r--src/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar.skin15
-rw-r--r--src/shared/deviceskin/skins/S60-QVGA-Candybar.skin/defaultbuttons.conf78
-rw-r--r--src/shared/deviceskin/skins/S60-nHD-Touchscreen.qrc5
-rw-r--r--src/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen-down.pngbin0 -> 241501 bytes
-rw-r--r--src/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen.pngbin0 -> 240615 bytes
-rw-r--r--src/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen.skin10
-rw-r--r--src/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/defaultbuttons.conf53
-rw-r--r--src/shared/deviceskin/skins/SmartPhone.qrc5
-rw-r--r--src/shared/deviceskin/skins/SmartPhone.skin/SmartPhone-pressed.pngbin0 -> 111515 bytes
-rw-r--r--src/shared/deviceskin/skins/SmartPhone.skin/SmartPhone.pngbin0 -> 101750 bytes
-rw-r--r--src/shared/deviceskin/skins/SmartPhone.skin/SmartPhone.skin28
-rw-r--r--src/shared/deviceskin/skins/SmartPhone.skin/defaultbuttons.conf78
-rw-r--r--src/shared/deviceskin/skins/SmartPhone2.qrc5
-rw-r--r--src/shared/deviceskin/skins/SmartPhone2.skin/SmartPhone2-pressed.pngbin0 -> 134749 bytes
-rw-r--r--src/shared/deviceskin/skins/SmartPhone2.skin/SmartPhone2.pngbin0 -> 121915 bytes
-rw-r--r--src/shared/deviceskin/skins/SmartPhone2.skin/SmartPhone2.skin25
-rw-r--r--src/shared/deviceskin/skins/SmartPhone2.skin/defaultbuttons.conf52
-rw-r--r--src/shared/deviceskin/skins/SmartPhoneWithButtons.qrc5
-rw-r--r--src/shared/deviceskin/skins/SmartPhoneWithButtons.skin/SmartPhoneWithButtons-pressed.pngbin0 -> 103838 bytes
-rw-r--r--src/shared/deviceskin/skins/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.pngbin0 -> 88470 bytes
-rw-r--r--src/shared/deviceskin/skins/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.skin31
-rw-r--r--src/shared/deviceskin/skins/SmartPhoneWithButtons.skin/defaultbuttons.conf103
-rw-r--r--src/shared/deviceskin/skins/TouchscreenPhone.qrc5
-rw-r--r--src/shared/deviceskin/skins/TouchscreenPhone.skin/TouchscreenPhone-pressed.pngbin0 -> 88599 bytes
-rw-r--r--src/shared/deviceskin/skins/TouchscreenPhone.skin/TouchscreenPhone.pngbin0 -> 61809 bytes
-rw-r--r--src/shared/deviceskin/skins/TouchscreenPhone.skin/TouchscreenPhone.skin16
-rw-r--r--src/shared/deviceskin/skins/TouchscreenPhone.skin/defaultbuttons.conf45
-rw-r--r--src/shared/findwidget/abstractfindwidget.cpp295
-rw-r--r--src/shared/findwidget/abstractfindwidget.h115
-rw-r--r--src/shared/findwidget/findwidget.pri4
-rw-r--r--src/shared/findwidget/findwidget.qrc14
-rw-r--r--src/shared/findwidget/images/mac/closetab.pngbin0 -> 516 bytes
-rw-r--r--src/shared/findwidget/images/mac/next.pngbin0 -> 1310 bytes
-rw-r--r--src/shared/findwidget/images/mac/previous.pngbin0 -> 1080 bytes
-rw-r--r--src/shared/findwidget/images/mac/searchfind.pngbin0 -> 1836 bytes
-rw-r--r--src/shared/findwidget/images/win/closetab.pngbin0 -> 375 bytes
-rw-r--r--src/shared/findwidget/images/win/next.pngbin0 -> 1038 bytes
-rw-r--r--src/shared/findwidget/images/win/previous.pngbin0 -> 898 bytes
-rw-r--r--src/shared/findwidget/images/win/searchfind.pngbin0 -> 1944 bytes
-rw-r--r--src/shared/findwidget/images/wrap.pngbin0 -> 500 bytes
-rw-r--r--src/shared/findwidget/itemviewfindwidget.cpp317
-rw-r--r--src/shared/findwidget/itemviewfindwidget.h78
-rw-r--r--src/shared/findwidget/texteditfindwidget.cpp169
-rw-r--r--src/shared/findwidget/texteditfindwidget.h73
-rw-r--r--src/shared/fontpanel/fontpanel.cpp308
-rw-r--r--src/shared/fontpanel/fontpanel.h108
-rw-r--r--src/shared/fontpanel/fontpanel.pri3
-rw-r--r--src/shared/qtgradienteditor/images/down.pngbin0 -> 594 bytes
-rw-r--r--src/shared/qtgradienteditor/images/edit.pngbin0 -> 503 bytes
-rw-r--r--src/shared/qtgradienteditor/images/editdelete.pngbin0 -> 831 bytes
-rw-r--r--src/shared/qtgradienteditor/images/minus.pngbin0 -> 250 bytes
-rw-r--r--src/shared/qtgradienteditor/images/plus.pngbin0 -> 462 bytes
-rw-r--r--src/shared/qtgradienteditor/images/spreadpad.pngbin0 -> 151 bytes
-rw-r--r--src/shared/qtgradienteditor/images/spreadreflect.pngbin0 -> 165 bytes
-rw-r--r--src/shared/qtgradienteditor/images/spreadrepeat.pngbin0 -> 156 bytes
-rw-r--r--src/shared/qtgradienteditor/images/typeconical.pngbin0 -> 937 bytes
-rw-r--r--src/shared/qtgradienteditor/images/typelinear.pngbin0 -> 145 bytes
-rw-r--r--src/shared/qtgradienteditor/images/typeradial.pngbin0 -> 583 bytes
-rw-r--r--src/shared/qtgradienteditor/images/up.pngbin0 -> 692 bytes
-rw-r--r--src/shared/qtgradienteditor/images/zoomin.pngbin0 -> 1208 bytes
-rw-r--r--src/shared/qtgradienteditor/images/zoomout.pngbin0 -> 1226 bytes
-rw-r--r--src/shared/qtgradienteditor/qtcolorbutton.cpp272
-rw-r--r--src/shared/qtgradienteditor/qtcolorbutton.h86
-rw-r--r--src/shared/qtgradienteditor/qtcolorbutton.pri4
-rw-r--r--src/shared/qtgradienteditor/qtcolorline.cpp1122
-rw-r--r--src/shared/qtgradienteditor/qtcolorline.h124
-rw-r--r--src/shared/qtgradienteditor/qtgradientdialog.cpp353
-rw-r--r--src/shared/qtgradienteditor/qtgradientdialog.h87
-rw-r--r--src/shared/qtgradienteditor/qtgradientdialog.ui121
-rw-r--r--src/shared/qtgradienteditor/qtgradienteditor.cpp952
-rw-r--r--src/shared/qtgradienteditor/qtgradienteditor.h111
-rw-r--r--src/shared/qtgradienteditor/qtgradienteditor.pri33
-rw-r--r--src/shared/qtgradienteditor/qtgradienteditor.qrc18
-rw-r--r--src/shared/qtgradienteditor/qtgradienteditor.ui1377
-rw-r--r--src/shared/qtgradienteditor/qtgradientmanager.cpp135
-rw-r--r--src/shared/qtgradienteditor/qtgradientmanager.h92
-rw-r--r--src/shared/qtgradienteditor/qtgradientstopscontroller.cpp724
-rw-r--r--src/shared/qtgradienteditor/qtgradientstopscontroller.h106
-rw-r--r--src/shared/qtgradienteditor/qtgradientstopsmodel.cpp477
-rw-r--r--src/shared/qtgradienteditor/qtgradientstopsmodel.h121
-rw-r--r--src/shared/qtgradienteditor/qtgradientstopswidget.cpp1154
-rw-r--r--src/shared/qtgradienteditor/qtgradientstopswidget.h115
-rw-r--r--src/shared/qtgradienteditor/qtgradientutils.cpp420
-rw-r--r--src/shared/qtgradienteditor/qtgradientutils.h66
-rw-r--r--src/shared/qtgradienteditor/qtgradientview.cpp292
-rw-r--r--src/shared/qtgradienteditor/qtgradientview.h99
-rw-r--r--src/shared/qtgradienteditor/qtgradientview.ui135
-rw-r--r--src/shared/qtgradienteditor/qtgradientviewdialog.cpp89
-rw-r--r--src/shared/qtgradienteditor/qtgradientviewdialog.h75
-rw-r--r--src/shared/qtgradienteditor/qtgradientviewdialog.ui121
-rw-r--r--src/shared/qtgradienteditor/qtgradientwidget.cpp815
-rw-r--r--src/shared/qtgradienteditor/qtgradientwidget.h120
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-arrow.pngbin0 -> 171 bytes
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-busy.pngbin0 -> 201 bytes
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-closedhand.pngbin0 -> 147 bytes
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-cross.pngbin0 -> 130 bytes
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-forbidden.pngbin0 -> 199 bytes
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-hand.pngbin0 -> 159 bytes
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-hsplit.pngbin0 -> 155 bytes
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-ibeam.pngbin0 -> 124 bytes
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-openhand.pngbin0 -> 160 bytes
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-sizeall.pngbin0 -> 174 bytes
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-sizeb.pngbin0 -> 161 bytes
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-sizef.pngbin0 -> 161 bytes
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-sizeh.pngbin0 -> 145 bytes
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-sizev.pngbin0 -> 141 bytes
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-uparrow.pngbin0 -> 132 bytes
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-vsplit.pngbin0 -> 161 bytes
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-wait.pngbin0 -> 172 bytes
-rw-r--r--src/shared/qtpropertybrowser/images/cursor-whatsthis.pngbin0 -> 191 bytes
-rw-r--r--src/shared/qtpropertybrowser/qtbuttonpropertybrowser.cpp627
-rw-r--r--src/shared/qtpropertybrowser/qtbuttonpropertybrowser.h85
-rw-r--r--src/shared/qtpropertybrowser/qteditorfactory.cpp2560
-rw-r--r--src/shared/qtpropertybrowser/qteditorfactory.h397
-rw-r--r--src/shared/qtpropertybrowser/qtgroupboxpropertybrowser.cpp529
-rw-r--r--src/shared/qtpropertybrowser/qtgroupboxpropertybrowser.h76
-rw-r--r--src/shared/qtpropertybrowser/qtpropertybrowser.cpp1955
-rw-r--r--src/shared/qtpropertybrowser/qtpropertybrowser.h309
-rw-r--r--src/shared/qtpropertybrowser/qtpropertybrowser.pri19
-rw-r--r--src/shared/qtpropertybrowser/qtpropertybrowser.qrc23
-rw-r--r--src/shared/qtpropertybrowser/qtpropertybrowserutils.cpp456
-rw-r--r--src/shared/qtpropertybrowser/qtpropertybrowserutils.pri4
-rw-r--r--src/shared/qtpropertybrowser/qtpropertybrowserutils_p.h161
-rw-r--r--src/shared/qtpropertybrowser/qtpropertymanager.cpp6451
-rw-r--r--src/shared/qtpropertybrowser/qtpropertymanager.h746
-rw-r--r--src/shared/qtpropertybrowser/qttreepropertybrowser.cpp1042
-rw-r--r--src/shared/qtpropertybrowser/qttreepropertybrowser.h134
-rw-r--r--src/shared/qtpropertybrowser/qtvariantproperty.cpp2268
-rw-r--r--src/shared/qtpropertybrowser/qtvariantproperty.h177
-rw-r--r--src/shared/qttoolbardialog/images/back.pngbin0 -> 678 bytes
-rw-r--r--src/shared/qttoolbardialog/images/down.pngbin0 -> 594 bytes
-rw-r--r--src/shared/qttoolbardialog/images/forward.pngbin0 -> 655 bytes
-rw-r--r--src/shared/qttoolbardialog/images/minus.pngbin0 -> 250 bytes
-rw-r--r--src/shared/qttoolbardialog/images/plus.pngbin0 -> 462 bytes
-rw-r--r--src/shared/qttoolbardialog/images/up.pngbin0 -> 692 bytes
-rw-r--r--src/shared/qttoolbardialog/qttoolbardialog.cpp1871
-rw-r--r--src/shared/qttoolbardialog/qttoolbardialog.h138
-rw-r--r--src/shared/qttoolbardialog/qttoolbardialog.pri6
-rw-r--r--src/shared/qttoolbardialog/qttoolbardialog.qrc10
-rw-r--r--src/shared/qttoolbardialog/qttoolbardialog.ui207
158 files changed, 33313 insertions, 0 deletions
diff --git a/src/shared/deviceskin/deviceskin.cpp b/src/shared/deviceskin/deviceskin.cpp
new file mode 100644
index 000000000..1e3748fe8
--- /dev/null
+++ b/src/shared/deviceskin/deviceskin.cpp
@@ -0,0 +1,857 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "deviceskin.h"
+
+#include <QtCore/qnamespace.h>
+#include <QtGui/QApplication>
+#include <QtGui/QBitmap>
+#include <QtGui/QPixmap>
+#include <QtGui/QPainter>
+#include <QtCore/QTextStream>
+#include <QtCore/QFile>
+#include <QtCore/QFileInfo>
+#include <QtGui/QImage>
+#include <QtCore/QTimer>
+#include <QtCore/QDir>
+#include <QtCore/QRegExp>
+#include <QtGui/QMouseEvent>
+#include <QtCore/QDebug>
+
+#ifdef TEST_SKIN
+# include <QtGui/QMainWindow>
+# include <QtGui/QDialog>
+# include <QtGui/QDialogButtonBox>
+# include <QtGui/QHBoxLayout>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+ enum { joydistance = 10, key_repeat_period = 50, key_repeat_delay = 500 };
+ enum { debugDeviceSkin = 0 };
+}
+
+static void parseRect(const QString &value, QRect *rect) {
+ const QStringList l = value.split(QLatin1Char(' '));
+ rect->setRect(l[0].toInt(), l[1].toInt(), l[2].toInt(), l[3].toInt());
+}
+
+static QString msgImageNotLoaded(const QString &f) {
+ return DeviceSkin::tr("The image file '%1' could not be loaded.").arg(f);
+}
+
+// ------------ DeviceSkinButtonArea
+DeviceSkinButtonArea::DeviceSkinButtonArea() :
+ keyCode(0),
+ activeWhenClosed(0)
+{
+}
+
+QDebug &operator<<(QDebug &str, const DeviceSkinButtonArea &a)
+{
+
+ str << "Area: " << a.name << " keyCode=" << a.keyCode << " area=" << a.area
+ << " text=" << a.text << " activeWhenClosed=" << a.activeWhenClosed;
+ return str;
+}
+
+// ------------ DeviceSkinParameters
+
+QDebug operator<<(QDebug str, const DeviceSkinParameters &p)
+{
+ str << "Images " << p.skinImageUpFileName << ','
+ << p.skinImageDownFileName<< ',' << p.skinImageClosedFileName
+ << ',' << p.skinCursorFileName <<"\nScreen: " << p.screenRect
+ << " back: " << p.backScreenRect << " closed: " << p.closedScreenRect
+ << " cursor: " << p.cursorHot << " Prefix: " << p.prefix
+ << " Joystick: " << p.joystick << " MouseHover" << p.hasMouseHover;
+ const int numAreas = p.buttonAreas.size();
+ for (int i = 0; i < numAreas; i++)
+ str << p.buttonAreas[i];
+ return str;
+}
+
+QSize DeviceSkinParameters::secondaryScreenSize() const
+{
+ return backScreenRect.isNull() ? closedScreenRect .size(): backScreenRect.size();
+}
+
+bool DeviceSkinParameters::hasSecondaryScreen() const
+{
+ return secondaryScreenSize() != QSize(0, 0);
+}
+
+bool DeviceSkinParameters::read(const QString &skinDirectory, ReadMode rm, QString *errorMessage)
+{
+ // Figure out the name. remove ending '/' if present
+ QString skinFile = skinDirectory;
+ if (skinFile.endsWith(QLatin1Char('/')))
+ skinFile.truncate(skinFile.length() - 1);
+
+ QFileInfo fi(skinFile);
+ QString fn;
+ if ( fi.isDir() ) {
+ prefix = skinFile;
+ prefix += QLatin1Char('/');
+ fn = prefix;
+ fn += fi.baseName();
+ fn += QLatin1String(".skin");
+ } else if (fi.isFile()){
+ fn = skinFile;
+ prefix = fi.path();
+ prefix += QLatin1Char('/');
+ } else {
+ *errorMessage = DeviceSkin::tr("The skin directory '%1' does not contain a configuration file.").arg(skinDirectory);
+ return false;
+ }
+ QFile f(fn);
+ if (!f.open(QIODevice::ReadOnly )) {
+ *errorMessage = DeviceSkin::tr("The skin configuration file '%1' could not be opened.").arg(fn);
+ return false;
+ }
+ QTextStream ts(&f);
+ const bool rc = read(ts, rm, errorMessage);
+ if (!rc)
+ *errorMessage = DeviceSkin::tr("The skin configuration file '%1' could not be read: %2").arg(fn).arg(*errorMessage);
+ return rc;
+}
+bool DeviceSkinParameters::read(QTextStream &ts, ReadMode rm, QString *errorMessage)
+{
+ QStringList closedAreas;
+ QStringList toggleAreas;
+ QStringList toggleActiveAreas;
+ int nareas = 0;
+ screenDepth = 0;
+ QString mark;
+ ts >> mark;
+ hasMouseHover = true; // historical default
+ if ( mark == QLatin1String("[SkinFile]") ) {
+ const QString UpKey = QLatin1String("Up");
+ const QString DownKey = QLatin1String("Down");
+ const QString ClosedKey = QLatin1String("Closed");
+ const QString ClosedAreasKey = QLatin1String("ClosedAreas");
+ const QString ScreenKey = QLatin1String("Screen");
+ const QString ScreenDepthKey = QLatin1String("ScreenDepth");
+ const QString BackScreenKey = QLatin1String("BackScreen");
+ const QString ClosedScreenKey = QLatin1String("ClosedScreen");
+ const QString CursorKey = QLatin1String("Cursor");
+ const QString AreasKey = QLatin1String("Areas");
+ const QString ToggleAreasKey = QLatin1String("ToggleAreas");
+ const QString ToggleActiveAreasKey = QLatin1String("ToggleActiveAreas");
+ const QString HasMouseHoverKey = QLatin1String("HasMouseHover");
+ // New
+ while (!nareas) {
+ QString line = ts.readLine();
+ if ( line.isNull() )
+ break;
+ if ( line[0] != QLatin1Char('#') && !line.isEmpty() ) {
+ int eq = line.indexOf(QLatin1Char('='));
+ if ( eq >= 0 ) {
+ const QString key = line.left(eq);
+ eq++;
+ while (eq<line.length()-1 && line[eq].isSpace())
+ eq++;
+ const QString value = line.mid(eq);
+ if ( key == UpKey ) {
+ skinImageUpFileName = value;
+ } else if ( key == DownKey ) {
+ skinImageDownFileName = value;
+ } else if ( key == ClosedKey ) {
+ skinImageClosedFileName = value;
+ } else if ( key == ClosedAreasKey ) {
+ closedAreas = value.split(QLatin1Char(' '));
+ } else if ( key == ScreenKey ) {
+ parseRect( value, &screenRect);
+ } else if ( key == ScreenDepthKey ) {
+ screenDepth = value.toInt();
+ } else if ( key == BackScreenKey ) {
+ parseRect(value, &backScreenRect);
+ } else if ( key == ClosedScreenKey ) {
+ parseRect( value, &closedScreenRect );
+ } else if ( key == CursorKey ) {
+ QStringList l = value.split(QLatin1Char(' '));
+ skinCursorFileName = l[0];
+ cursorHot = QPoint(l[1].toInt(),l[2].toInt());
+ } else if ( key == AreasKey ) {
+ nareas = value.toInt();
+ } else if ( key == ToggleAreasKey ) {
+ toggleAreas = value.split(QLatin1Char(' '));
+ } else if ( key == ToggleActiveAreasKey ) {
+ toggleActiveAreas = value.split(QLatin1Char(' '));
+ } else if ( key == HasMouseHoverKey ) {
+ hasMouseHover = value == QLatin1String("true") || value == QLatin1String("1");
+ }
+ } else {
+ *errorMessage = DeviceSkin::tr("Syntax error: %1").arg(line);
+ return false;
+ }
+ }
+ }
+ } else {
+ // Old
+ skinImageUpFileName = mark;
+ QString s;
+ int x,y,w,h,na;
+ ts >> s >> x >> y >> w >> h >> na;
+ skinImageDownFileName = s;
+ screenRect.setRect(x, y, w, h);
+ nareas = na;
+ }
+ // Done for short mode
+ if (rm == ReadSizeOnly)
+ return true;
+ // verify skin files exist
+ skinImageUpFileName.insert(0, prefix);
+ if (!QFile(skinImageUpFileName).exists()) {
+ *errorMessage = DeviceSkin::tr("The skin \"up\" image file '%1' does not exist.").arg(skinImageUpFileName);
+ return false;
+ }
+ if (!skinImageUp.load(skinImageUpFileName)) {
+ *errorMessage = msgImageNotLoaded(skinImageUpFileName);
+ return false;
+ }
+
+ skinImageDownFileName.insert(0, prefix);
+ if (!QFile(skinImageDownFileName).exists()) {
+ *errorMessage = DeviceSkin::tr("The skin \"down\" image file '%1' does not exist.").arg(skinImageDownFileName);
+ return false;
+ }
+ if (!skinImageDown.load(skinImageDownFileName)) {
+ *errorMessage = msgImageNotLoaded(skinImageDownFileName);
+ return false;
+ }
+
+ if (!skinImageClosedFileName.isEmpty()) {
+ skinImageClosedFileName.insert(0, prefix);
+ if (!QFile(skinImageClosedFileName).exists()) {
+ *errorMessage = DeviceSkin::tr("The skin \"closed\" image file '%1' does not exist.").arg(skinImageClosedFileName);
+ return false;
+ }
+ if (!skinImageClosed.load(skinImageClosedFileName)) {
+ *errorMessage = msgImageNotLoaded(skinImageClosedFileName);
+ return false;
+ }
+ }
+
+ if (!skinCursorFileName.isEmpty()) {
+ skinCursorFileName.insert(0, prefix);
+ if (!QFile(skinCursorFileName).exists()) {
+ *errorMessage = DeviceSkin::tr("The skin cursor image file '%1' does not exist.").arg(skinCursorFileName);
+ return false;
+ }
+ if (!skinCursor.load(skinCursorFileName)) {
+ *errorMessage = msgImageNotLoaded(skinCursorFileName);
+ return false;
+ }
+ }
+
+ // read areas
+ if (!nareas)
+ return true;
+ buttonAreas.reserve(nareas);
+
+ int i = 0;
+ ts.readLine(); // eol
+ joystick = -1;
+ const QString Joystick = QLatin1String("Joystick");
+ while (i < nareas && !ts.atEnd() ) {
+ buttonAreas.push_back(DeviceSkinButtonArea());
+ DeviceSkinButtonArea &area = buttonAreas.back();
+ const QString line = ts.readLine();
+ if ( !line.isEmpty() && line[0] != QLatin1Char('#') ) {
+ const QStringList tok = line.split(QRegExp(QLatin1String("[ \t][ \t]*")));
+ if ( tok.count()<6 ) {
+ *errorMessage = DeviceSkin::tr("Syntax error in area definition: %1").arg(line);
+ return false;
+ } else {
+ area.name = tok[0];
+ QString k = tok[1];
+ if ( k.left(2).toLower() == QLatin1String("0x")) {
+ area.keyCode = k.mid(2).toInt(0,16);
+ } else {
+ area.keyCode = k.toInt();
+ }
+
+ int p=0;
+ for (int j=2; j < tok.count() - 1; ) {
+ const int x = tok[j++].toInt();
+ const int y = tok[j++].toInt();
+ area.area.putPoints(p++,1,x,y);
+ }
+
+ const QChar doubleQuote = QLatin1Char('"');
+ if ( area.name[0] == doubleQuote && area.name.endsWith(doubleQuote)) {
+ area.name.truncate(area.name.size() - 1);
+ area.name.remove(0, 1);
+ }
+ if ( area.name.length() == 1 )
+ area.text = area.name;
+ if ( area.name == Joystick)
+ joystick = i;
+ area.activeWhenClosed = closedAreas.contains(area.name)
+ || area.keyCode == Qt::Key_Flip; // must be to work
+ area.toggleArea = toggleAreas.contains(area.name);
+ area.toggleActiveArea = toggleActiveAreas.contains(area.name);
+ if ( area.toggleArea )
+ toggleAreaList += i;
+ i++;
+ }
+ }
+ }
+ if (i != nareas) {
+ qWarning() << DeviceSkin::tr("Mismatch in number of areas, expected %1, got %2.")
+ .arg(nareas).arg(i);
+ }
+ if (debugDeviceSkin)
+ qDebug() << *this;
+ return true;
+}
+
+// --------- CursorWindow declaration
+
+namespace qvfb_internal {
+
+class CursorWindow : public QWidget
+{
+public:
+ explicit CursorWindow(const QImage &cursor, QPoint hot, QWidget *sk);
+
+ void setView(QWidget*);
+ void setPos(QPoint);
+ bool handleMouseEvent(QEvent *ev);
+
+protected:
+ bool event( QEvent *);
+ bool eventFilter( QObject*, QEvent *);
+
+private:
+ QWidget *mouseRecipient;
+ QWidget *m_view;
+ QWidget *skin;
+ QPoint hotspot;
+};
+}
+
+// --------- Skin
+
+DeviceSkin::DeviceSkin(const DeviceSkinParameters &parameters, QWidget *p ) :
+ QWidget(p),
+ m_parameters(parameters),
+ buttonRegions(parameters.buttonAreas.size(), QRegion()),
+ parent(p),
+ m_view(0),
+ m_secondaryView(0),
+ buttonPressed(false),
+ buttonIndex(0),
+ cursorw(0),
+ joydown(0),
+ t_skinkey(new QTimer(this)),
+ t_parentmove(new QTimer(this)),
+ flipped_open(true)
+{
+ Q_ASSERT(p);
+ setMouseTracking(true);
+ setAttribute(Qt::WA_NoSystemBackground);
+
+ setZoom(1.0);
+ connect( t_skinkey, SIGNAL(timeout()), this, SLOT(skinKeyRepeat()) );
+ t_parentmove->setSingleShot( true );
+ connect( t_parentmove, SIGNAL(timeout()), this, SLOT(moveParent()) );
+}
+
+void DeviceSkin::skinKeyRepeat()
+{
+ if ( m_view ) {
+ const DeviceSkinButtonArea &area = m_parameters.buttonAreas[buttonIndex];
+ emit skinKeyReleaseEvent( area.keyCode,area.text, true );
+ emit skinKeyPressEvent( area.keyCode, area.text, true );
+ t_skinkey->start(key_repeat_period);
+ }
+}
+
+void DeviceSkin::calcRegions()
+{
+ const int numAreas = m_parameters.buttonAreas.size();
+ for (int i=0; i<numAreas; i++) {
+ QPolygon xa(m_parameters.buttonAreas[i].area.count());
+ int n = m_parameters.buttonAreas[i].area.count();
+ for (int p=0; p<n; p++) {
+ xa.setPoint(p,transform.map(m_parameters.buttonAreas[i].area[p]));
+ }
+ if ( n == 2 ) {
+ buttonRegions[i] = QRegion(xa.boundingRect());
+ } else {
+ buttonRegions[i] = QRegion(xa);
+ }
+ }
+}
+
+void DeviceSkin::loadImages()
+{
+ QImage iup = m_parameters.skinImageUp;
+ QImage idown = m_parameters.skinImageDown;
+
+ QImage iclosed;
+ const bool hasClosedImage = !m_parameters.skinImageClosed.isNull();
+
+ if (hasClosedImage)
+ iclosed = m_parameters.skinImageClosed;
+ QImage icurs;
+ const bool hasCursorImage = !m_parameters.skinCursor.isNull();
+ if (hasCursorImage)
+ icurs = m_parameters.skinCursor;
+
+ if (!transform.isIdentity()) {
+ iup = iup.transformed(transform, Qt::SmoothTransformation);
+ idown = idown.transformed(transform, Qt::SmoothTransformation);
+ if (hasClosedImage)
+ iclosed = iclosed.transformed(transform, Qt::SmoothTransformation);
+ if (hasCursorImage)
+ icurs = icurs.transformed(transform, Qt::SmoothTransformation);
+ }
+ const Qt::ImageConversionFlags conv = Qt::ThresholdAlphaDither|Qt::AvoidDither;
+ skinImageUp = QPixmap::fromImage(iup);
+ skinImageDown = QPixmap::fromImage(idown, conv);
+ if (hasClosedImage)
+ skinImageClosed = QPixmap::fromImage(iclosed, conv);
+ if (hasCursorImage)
+ skinCursor = QPixmap::fromImage(icurs, conv);
+
+ setFixedSize( skinImageUp.size() );
+ if (!skinImageUp.mask())
+ skinImageUp.setMask(skinImageUp.createHeuristicMask());
+ if (!skinImageClosed.mask())
+ skinImageClosed.setMask(skinImageClosed.createHeuristicMask());
+
+ QWidget* parent = parentWidget();
+ parent->setMask( skinImageUp.mask() );
+ parent->setFixedSize( skinImageUp.size() );
+
+ delete cursorw;
+ cursorw = 0;
+ if (hasCursorImage) {
+ cursorw = new qvfb_internal::CursorWindow(m_parameters.skinCursor, m_parameters.cursorHot, this);
+ if ( m_view )
+ cursorw->setView(m_view);
+ }
+}
+
+DeviceSkin::~DeviceSkin( )
+{
+ delete cursorw;
+}
+
+void DeviceSkin::setTransform( const QMatrix& wm )
+{
+ transform = QImage::trueMatrix(wm,m_parameters.skinImageUp.width(),m_parameters.skinImageUp.height());
+ calcRegions();
+ loadImages();
+ if ( m_view ) {
+ QPoint p = transform.map(QPolygon(m_parameters.screenRect)).boundingRect().topLeft();
+ m_view->move(p);
+ }
+ updateSecondaryScreen();
+}
+
+void DeviceSkin::setZoom( double z )
+{
+ setTransform(QMatrix().scale(z,z));
+}
+
+void DeviceSkin::updateSecondaryScreen()
+{
+ if (!m_secondaryView)
+ return;
+ if (flipped_open) {
+ if (m_parameters.backScreenRect.isNull()) {
+ m_secondaryView->hide();
+ } else {
+ m_secondaryView->move(transform.map(QPolygon(m_parameters.backScreenRect)).boundingRect().topLeft());
+ m_secondaryView->show();
+ }
+ } else {
+ if (m_parameters.closedScreenRect.isNull()) {
+ m_secondaryView->hide();
+ } else {
+ m_secondaryView->move(transform.map(QPolygon(m_parameters.closedScreenRect)).boundingRect().topLeft());
+ m_secondaryView->show();
+ }
+ }
+}
+
+void DeviceSkin::setView( QWidget *v )
+{
+ m_view = v;
+ m_view->setFocus();
+ m_view->move(transform.map(QPolygon(m_parameters.screenRect)).boundingRect().topLeft());
+ if ( cursorw )
+ cursorw->setView(v);
+}
+
+void DeviceSkin::setSecondaryView( QWidget *v )
+{
+ m_secondaryView = v;
+ updateSecondaryScreen();
+}
+
+void DeviceSkin::paintEvent( QPaintEvent *)
+{
+ QPainter p( this );
+ if ( flipped_open ) {
+ p.drawPixmap( 0, 0, skinImageUp );
+ } else {
+ p.drawPixmap( 0, 0, skinImageClosed );
+ }
+ QList<int> toDraw;
+ if ( buttonPressed == true ) {
+ toDraw += buttonIndex;
+ }
+ foreach (int toggle, m_parameters.toggleAreaList) {
+ const DeviceSkinButtonArea &ba = m_parameters.buttonAreas[toggle];
+ if ( flipped_open || ba.activeWhenClosed ) {
+ if ( ba.toggleArea && ba.toggleActiveArea )
+ toDraw += toggle;
+ }
+ }
+ foreach (int button, toDraw ) {
+ const DeviceSkinButtonArea &ba = m_parameters.buttonAreas[button];
+ const QRect r = buttonRegions[button].boundingRect();
+ if ( ba.area.count() > 2 )
+ p.setClipRegion(buttonRegions[button]);
+ p.drawPixmap( r.topLeft(), skinImageDown, r);
+ }
+}
+
+void DeviceSkin::mousePressEvent( QMouseEvent *e )
+{
+ if (e->button() == Qt::RightButton) {
+ emit popupMenu();
+ } else {
+ buttonPressed = false;
+
+ onjoyrelease = -1;
+ const int numAreas = m_parameters.buttonAreas.size();
+ for (int i = 0; i < numAreas ; i++) {
+ const DeviceSkinButtonArea &ba = m_parameters.buttonAreas[i];
+ if ( buttonRegions[i].contains( e->pos() ) ) {
+ if ( flipped_open || ba.activeWhenClosed ) {
+ if ( m_parameters.joystick == i ) {
+ joydown = true;
+ } else {
+ if ( joydown )
+ onjoyrelease = i;
+ else
+ startPress(i);
+ break;
+ if (debugDeviceSkin)// Debug message to be sure we are clicking the right areas
+ qDebug()<< m_parameters.buttonAreas[i].name << " clicked";
+ }
+ }
+ }
+ }
+ clickPos = e->pos();
+// This is handy for finding the areas to define rectangles for new skins
+ if (debugDeviceSkin)
+ qDebug()<< "Clicked in " << e->pos().x() << ',' << e->pos().y();
+ clickPos = e->pos();
+ }
+}
+
+void DeviceSkin::flip(bool open)
+{
+ if ( flipped_open == open )
+ return;
+ if ( open ) {
+ parent->setMask( skinImageUp.mask() );
+ emit skinKeyReleaseEvent( Qt::Key(Qt::Key_Flip), QString(), false);
+ } else {
+ parent->setMask( skinImageClosed.mask() );
+ emit skinKeyPressEvent( Qt::Key(Qt::Key_Flip), QString(), false);
+ }
+ flipped_open = open;
+ updateSecondaryScreen();
+ repaint();
+}
+
+void DeviceSkin::startPress(int i)
+{
+ buttonPressed = true;
+ buttonIndex = i;
+ if (m_view) {
+ const DeviceSkinButtonArea &ba = m_parameters.buttonAreas[buttonIndex];
+ if ( ba.keyCode == Qt::Key_Flip ) {
+ flip(!flipped_open);
+ } else if ( ba.toggleArea ) {
+ bool active = !ba.toggleActiveArea;
+ const_cast<DeviceSkinButtonArea &>(ba).toggleActiveArea = active;
+ if ( active )
+ emit skinKeyPressEvent( ba.keyCode, ba.text, false);
+ else
+ emit skinKeyReleaseEvent( ba.keyCode, ba.text, false);
+ } else {
+ emit skinKeyPressEvent( ba.keyCode, ba.text, false);
+ t_skinkey->start(key_repeat_delay);
+ }
+ repaint( buttonRegions[buttonIndex].boundingRect() );
+ }
+}
+
+void DeviceSkin::endPress()
+{
+ const DeviceSkinButtonArea &ba = m_parameters.buttonAreas[buttonIndex];
+ if (m_view && ba.keyCode != Qt::Key_Flip && !ba.toggleArea )
+ emit skinKeyReleaseEvent(ba.keyCode, ba.text, false );
+ t_skinkey->stop();
+ buttonPressed = false;
+ repaint( buttonRegions[buttonIndex].boundingRect() );
+}
+
+void DeviceSkin::mouseMoveEvent( QMouseEvent *e )
+{
+ if ( e->buttons() & Qt::LeftButton ) {
+ const int joystick = m_parameters.joystick;
+ QPoint newpos = e->globalPos() - clickPos;
+ if ( joydown ) {
+ int k1=0, k2=0;
+ if ( newpos.x() < -joydistance ) {
+ k1 = joystick+1;
+ } else if ( newpos.x() > +joydistance ) {
+ k1 = joystick+3;
+ }
+ if ( newpos.y() < -joydistance ) {
+ k2 = joystick+2;
+ } else if ( newpos.y() > +joydistance ) {
+ k2 = joystick+4;
+ }
+ if ( k1 || k2 ) {
+ if ( !buttonPressed ) {
+ onjoyrelease = -1;
+ if ( k1 && k2 ) {
+ startPress(k2);
+ endPress();
+ }
+ startPress(k1 ? k1 : k2);
+ }
+ } else if ( buttonPressed ) {
+ endPress();
+ }
+ } else if ( buttonPressed == false ) {
+ parentpos = newpos;
+ if ( !t_parentmove->isActive() )
+ t_parentmove->start(50);
+ }
+ }
+ if ( cursorw )
+ cursorw->setPos(e->globalPos());
+}
+
+void DeviceSkin::moveParent()
+{
+ parent->move( parentpos );
+}
+
+void DeviceSkin::mouseReleaseEvent( QMouseEvent * )
+{
+ if ( buttonPressed )
+ endPress();
+ if ( joydown ) {
+ joydown = false;
+ if ( onjoyrelease >= 0 ) {
+ startPress(onjoyrelease);
+ endPress();
+ }
+ }
+}
+
+bool DeviceSkin::hasCursor() const
+{
+ return !skinCursor.isNull();
+}
+
+// ------------------ CursorWindow implementation
+
+namespace qvfb_internal {
+
+bool CursorWindow::eventFilter( QObject *, QEvent *ev)
+{
+ handleMouseEvent(ev);
+ return false;
+}
+
+bool CursorWindow::event( QEvent *ev )
+{
+ if (handleMouseEvent(ev))
+ return true;
+ return QWidget::event(ev);
+}
+
+bool CursorWindow::handleMouseEvent(QEvent *ev)
+{
+ bool handledEvent = false;
+ static int inhere=0;
+ if ( !inhere ) {
+ inhere++;
+ if ( m_view ) {
+ if ( ev->type() >= QEvent::MouseButtonPress && ev->type() <= QEvent::MouseMove ) {
+ QMouseEvent *e = (QMouseEvent*)ev;
+ QPoint gp = e->globalPos();
+ QPoint vp = m_view->mapFromGlobal(gp);
+ QPoint sp = skin->mapFromGlobal(gp);
+ if ( e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseButtonDblClick ) {
+ if ( m_view->rect().contains(vp) )
+ mouseRecipient = m_view;
+ else if ( skin->parentWidget()->geometry().contains(gp) )
+ mouseRecipient = skin;
+ else
+ mouseRecipient = 0;
+ }
+ if ( mouseRecipient ) {
+ setPos(gp);
+ QMouseEvent me(e->type(),mouseRecipient==skin ? sp : vp,gp,e->button(),e->buttons(),e->modifiers());
+ QApplication::sendEvent(mouseRecipient, &me);
+ } else if ( !skin->parentWidget()->geometry().contains(gp) ) {
+ hide();
+ } else {
+ setPos(gp);
+ }
+ if ( e->type() == QEvent::MouseButtonRelease )
+ mouseRecipient = 0;
+ handledEvent = true;
+ }
+ }
+ inhere--;
+ }
+ return handledEvent;
+}
+
+void CursorWindow::setView(QWidget* v)
+{
+ if ( m_view ) {
+ m_view->removeEventFilter(this);
+ m_view->removeEventFilter(this);
+ }
+ m_view = v;
+ m_view->installEventFilter(this);
+ m_view->installEventFilter(this);
+ mouseRecipient = 0;
+}
+
+CursorWindow::CursorWindow(const QImage &img, QPoint hot, QWidget* sk)
+ :QWidget(0),
+ m_view(0), skin(sk),
+ hotspot(hot)
+{
+ setWindowFlags( Qt::FramelessWindowHint );
+ mouseRecipient = 0;
+ setMouseTracking(true);
+#ifndef QT_NO_CURSOR
+ setCursor(Qt::BlankCursor);
+#endif
+ QPixmap p;
+ p = QPixmap::fromImage(img);
+ if (!p.mask()) {
+ if ( img.hasAlphaChannel() ) {
+ QBitmap bm;
+ bm = QPixmap::fromImage(img.createAlphaMask());
+ p.setMask( bm );
+ } else {
+ QBitmap bm;
+ bm = QPixmap::fromImage(img.createHeuristicMask());
+ p.setMask( bm );
+ }
+ }
+ QPalette palette;
+ palette.setBrush(backgroundRole(), QBrush(p));
+ setPalette(palette);
+ setFixedSize( p.size() );
+ if ( !p.mask().isNull() )
+ setMask( p.mask() );
+}
+
+void CursorWindow::setPos(QPoint p)
+{
+ move(p-hotspot);
+ show();
+ raise();
+}
+}
+
+#ifdef TEST_SKIN
+
+int main(int argc,char *argv[])
+{
+ if (argc < 1)
+ return 1;
+ const QString skinFile = QString::fromUtf8(argv[1]);
+ QApplication app(argc,argv);
+ QMainWindow mw;
+
+ DeviceSkinParameters params;
+ QString errorMessage;
+ if (!params.read(skinFile, DeviceSkinParameters::ReadAll, &errorMessage)) {
+ qWarning() << errorMessage;
+ return 1;
+ }
+ DeviceSkin ds(params, &mw);
+ // View Dialog
+ QDialog *dialog = new QDialog();
+ QHBoxLayout *dialogLayout = new QHBoxLayout();
+ dialog->setLayout(dialogLayout);
+ QDialogButtonBox *dialogButtonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel);
+ QObject::connect(dialogButtonBox, SIGNAL(rejected()), dialog, SLOT(reject()));
+ QObject::connect(dialogButtonBox, SIGNAL(accepted()), dialog, SLOT(accept()));
+ dialogLayout->addWidget(dialogButtonBox);
+ dialog->setFixedSize(params.screenSize());
+ dialog->setParent(&ds, Qt::SubWindow);
+ dialog->setAutoFillBackground(true);
+ ds.setView(dialog);
+
+ QObject::connect(&ds, SIGNAL(popupMenu()), &mw, SLOT(close()));
+ QObject::connect(&ds, SIGNAL(skinKeyPressEvent(int,QString,bool)), &mw, SLOT(close()));
+ mw.show();
+ return app.exec();
+}
+
+#endif
+
+QT_END_NAMESPACE
+
diff --git a/src/shared/deviceskin/deviceskin.h b/src/shared/deviceskin/deviceskin.h
new file mode 100644
index 000000000..8a53acffd
--- /dev/null
+++ b/src/shared/deviceskin/deviceskin.h
@@ -0,0 +1,174 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SKIN_H
+#define SKIN_H
+
+#include <QtGui/QWidget>
+#include <QtGui/QPolygon>
+#include <QtGui/QRegion>
+#include <QtGui/QPixmap>
+#include <QtCore/QVector>
+
+QT_BEGIN_NAMESPACE
+
+namespace qvfb_internal {
+ class CursorWindow;
+}
+
+class QTextStream;
+
+// ------- Button Area
+struct DeviceSkinButtonArea {
+ DeviceSkinButtonArea();
+ QString name;
+ int keyCode;
+ QPolygon area;
+ QString text;
+ bool activeWhenClosed;
+ bool toggleArea;
+ bool toggleActiveArea;
+};
+
+// -------- Parameters
+struct DeviceSkinParameters {
+ enum ReadMode { ReadAll, ReadSizeOnly };
+ bool read(const QString &skinDirectory, ReadMode rm, QString *errorMessage);
+ bool read(QTextStream &ts, ReadMode rm, QString *errorMessage);
+
+ QSize screenSize() const { return screenRect.size(); }
+ QSize secondaryScreenSize() const;
+ bool hasSecondaryScreen() const;
+
+ QString skinImageUpFileName;
+ QString skinImageDownFileName;
+ QString skinImageClosedFileName;
+ QString skinCursorFileName;
+
+ QImage skinImageUp;
+ QImage skinImageDown;
+ QImage skinImageClosed;
+ QImage skinCursor;
+
+ QRect screenRect;
+ QRect backScreenRect;
+ QRect closedScreenRect;
+ int screenDepth;
+ QPoint cursorHot;
+ QVector<DeviceSkinButtonArea> buttonAreas;
+ QList<int> toggleAreaList;
+
+ int joystick;
+ QString prefix;
+ bool hasMouseHover;
+};
+
+// --------- Skin Widget
+class DeviceSkin : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit DeviceSkin(const DeviceSkinParameters &parameters, QWidget *p );
+ ~DeviceSkin( );
+
+ QWidget *view() const { return m_view; }
+ void setView( QWidget *v );
+
+ QWidget *secondaryView() const { return m_secondaryView; }
+ void setSecondaryView( QWidget *v );
+
+ void setZoom( double );
+ void setTransform( const QMatrix& );
+
+ bool hasCursor() const;
+
+ QString prefix() const {return m_parameters.prefix;}
+
+signals:
+ void popupMenu();
+ void skinKeyPressEvent(int code, const QString& text, bool autorep);
+ void skinKeyReleaseEvent(int code, const QString& text, bool autorep);
+
+protected slots:
+ void skinKeyRepeat();
+ void moveParent();
+
+protected:
+ virtual void paintEvent( QPaintEvent * );
+ virtual void mousePressEvent( QMouseEvent *e );
+ virtual void mouseMoveEvent( QMouseEvent *e );
+ virtual void mouseReleaseEvent( QMouseEvent * );
+
+private:
+ void calcRegions();
+ void flip(bool open);
+ void updateSecondaryScreen();
+ void loadImages();
+ void startPress(int);
+ void endPress();
+
+ const DeviceSkinParameters m_parameters;
+ QVector<QRegion> buttonRegions;
+ QPixmap skinImageUp;
+ QPixmap skinImageDown;
+ QPixmap skinImageClosed;
+ QPixmap skinCursor;
+ QWidget *parent;
+ QWidget *m_view;
+ QWidget *m_secondaryView;
+ QPoint parentpos;
+ QPoint clickPos;
+ bool buttonPressed;
+ int buttonIndex;
+ QMatrix transform;
+ qvfb_internal::CursorWindow *cursorw;
+
+ bool joydown;
+ QTimer *t_skinkey;
+ QTimer *t_parentmove;
+ int onjoyrelease;
+
+ bool flipped_open;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/deviceskin/deviceskin.pri b/src/shared/deviceskin/deviceskin.pri
new file mode 100644
index 000000000..3e9935abb
--- /dev/null
+++ b/src/shared/deviceskin/deviceskin.pri
@@ -0,0 +1,12 @@
+INCLUDEPATH += $$PWD
+HEADERS += $$PWD/deviceskin.h
+SOURCES += $$PWD/deviceskin.cpp
+RESOURCES += $$PWD/skins/ClamshellPhone.qrc \
+ $$PWD/skins/SmartPhone2.qrc \
+ $$PWD/skins/SmartPhone.qrc \
+ $$PWD/skins/SmartPhoneWithButtons.qrc \
+ $$PWD/skins/TouchscreenPhone.qrc \
+ $$PWD/skins/PortableMedia.qrc \
+ $$PWD/skins/S60-QVGA-Candybar.qrc \
+ $$PWD/skins/S60-nHD-Touchscreen.qrc
+
diff --git a/src/shared/deviceskin/skins/ClamshellPhone.qrc b/src/shared/deviceskin/skins/ClamshellPhone.qrc
new file mode 100644
index 000000000..39cd42274
--- /dev/null
+++ b/src/shared/deviceskin/skins/ClamshellPhone.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/skins">
+ <file>ClamshellPhone.skin</file>
+</qresource>
+</RCC>
diff --git a/src/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone.skin b/src/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone.skin
new file mode 100644
index 000000000..cb24a8e14
--- /dev/null
+++ b/src/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone.skin
@@ -0,0 +1,30 @@
+[SkinFile]
+Up=ClamshellPhone1-5.png
+Down=ClamshellPhone1-5-pressed.png
+Closed=ClamshellPhone1-5-closed.png
+Screen=72 84 176 208
+Areas=22
+HasMouseHover=false
+
+"Power" 0x0100000a 205 563 249 586
+"1" 0x0031 62 414 119 438
+"2" 0x0032 130 414 189 438
+"3" 0x0033 198 413 257 438
+"4" 0x0034 54 444 117 470
+"5" 0x0035 128 444 189 471
+"6" 0x0036 202 444 264 471
+"7" 0x0037 47 477 113 507
+"8" 0x0038 126 477 190 507
+"9" 0x0039 205 478 270 509
+"*" 0x002a 39 515 110 552
+"0" 0x0030 122 515 195 553
+"#" 0x0023 207 516 280 553
+"Context1" 0x01100000 137 360 108 383 123 410 90 409 60 387 63 378 100 362
+"Back" 0x01000061 184 361 206 376 213 387 197 410 226 410 256 392 258 381 244 369
+"Backspace" 0x01000003 68 563 113 587
+"Select" 0x01010000 160 391 172 390 181 386 184 381 180 377 173 373 165 372 155 372 145 375 138 378 136 382 138 387 147 390
+"Left" 0x1000012 141 390 136 385 136 381 143 375 132 371 120 380 121 393 129 401
+"Down" 0x1000015 143 389 130 402 162 412 191 404 175 390
+"Right" 0x1000014 186 370 176 375 184 382 182 387 175 390 190 404 201 396 202 375
+"Up" 0x1000013 133 370 143 374 176 374 185 370 169 362 149 362
+"Flip" 0x01100006 98 325 225 353
diff --git a/src/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone1-5-closed.png b/src/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone1-5-closed.png
new file mode 100644
index 000000000..88ba3a147
--- /dev/null
+++ b/src/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone1-5-closed.png
Binary files differ
diff --git a/src/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone1-5-pressed.png b/src/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone1-5-pressed.png
new file mode 100644
index 000000000..971cdef64
--- /dev/null
+++ b/src/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone1-5-pressed.png
Binary files differ
diff --git a/src/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone1-5.png b/src/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone1-5.png
new file mode 100644
index 000000000..f3550ee7d
--- /dev/null
+++ b/src/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone1-5.png
Binary files differ
diff --git a/src/shared/deviceskin/skins/ClamshellPhone.skin/defaultbuttons.conf b/src/shared/deviceskin/skins/ClamshellPhone.skin/defaultbuttons.conf
new file mode 100644
index 000000000..e349dbc1f
--- /dev/null
+++ b/src/shared/deviceskin/skins/ClamshellPhone.skin/defaultbuttons.conf
@@ -0,0 +1,78 @@
+[Translation]
+File=QtopiaDefaults
+Context=Buttons
+[Menu]
+Rows=4
+Columns=3
+Map=123456789*0#
+Default=5
+1=Applications/camera.desktop
+2=Applications/datebook.desktop
+3=Applications
+4=Applications/qtmail.desktop
+5=Applications/addressbook.desktop
+6=Games
+7=Settings/Beaming.desktop
+8=Applications/simapp.desktop,Applications/calculator.desktop
+9=Settings
+*=Applications/mediarecorder.desktop
+0=Applications/todolist.desktop
+#=Documents
+Animator=Bounce
+AnimatorBackground=Radial
+[SoftKeys]
+Count=3
+Key0=Context1
+Key1=Select
+Key2=Back
+[SystemButtons]
+Count=5
+Key0=Context1
+Key1=Select
+Key2=Back
+Key3=Flip
+Key4=Backspace
+[TextButtons]
+Buttons=0123456789*#
+Hold0='0
+Hold1='1
+Hold2='2
+Hold3='3
+Hold4='4
+Hold5='5
+Hold6='6
+Hold7='7
+Hold8='8
+Hold9='9
+Hold*=symbol
+Hold#=mode
+Tap0=space
+Tap1="\".,'?!-@:1"
+Tap2="\"a\xe4\xe5\xe6\xe0\xe1\xe2\x62\x63\xe7\x32"
+Tap3="\"de\xe8\xe9\xea\x66\x33"
+Tap4="\"ghi\xec\xed\xee\x34"
+Tap5="\"jkl5"
+Tap6="\"mn\xf1o\xf6\xf8\xf2\xf3\x36"
+Tap7="\"pqrs\xdf\x37"
+Tap8="\"tu\xfc\xf9\xfav8"
+Tap9="\"wxyz9"
+Tap*=modify
+Tap#=shift
+[LocaleTextButtons]
+Buttons=23456789
+Tap2[]='abc
+Tap3[]='def
+Tap4[]='ghi
+Tap5[]='jkl
+Tap6[]='mno
+Tap7[]='pqrs
+Tap8[]='tuv
+Tap9[]='wxyz
+[PhoneTextButtons]
+Buttons=*#
+Tap*='*+pw
+Hold*=+
+Tap#=#
+Hold#=mode
+[Device]
+PrimaryInput=Keypad
diff --git a/src/shared/deviceskin/skins/PortableMedia.qrc b/src/shared/deviceskin/skins/PortableMedia.qrc
new file mode 100644
index 000000000..a902f1a73
--- /dev/null
+++ b/src/shared/deviceskin/skins/PortableMedia.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/skins">
+ <file>PortableMedia.skin</file>
+</qresource>
+</RCC>
diff --git a/src/shared/deviceskin/skins/PortableMedia.skin/PortableMedia.skin b/src/shared/deviceskin/skins/PortableMedia.skin/PortableMedia.skin
new file mode 100644
index 000000000..b76e5cfad
--- /dev/null
+++ b/src/shared/deviceskin/skins/PortableMedia.skin/PortableMedia.skin
@@ -0,0 +1,14 @@
+[SkinFile]
+Up=portablemedia.png
+Down=portablemedia-pressed.png
+Screen=18 20 480 272
+Areas=7
+HasMouseHover=false
+
+"Context1" 0x01100000 530 192 565 223
+"Back" 0x01000061 530 138 565 173
+"Select" 0x01010000 530 65 565 98
+"Left" 0x1000012 529 67 519 57 511 65 511 104 519 110 529 100 529 98
+"Down" 0x1000015 530 102 520 111 529 120 569 120 577 114 566 103 564 103
+"Right" 0x1000014 565 65 576 52 585 67 585 102 578 113 567 104
+"Up" 0x1000013 530 65 519 55 528 48 567 48 573 51 564 66
diff --git a/src/shared/deviceskin/skins/PortableMedia.skin/defaultbuttons.conf b/src/shared/deviceskin/skins/PortableMedia.skin/defaultbuttons.conf
new file mode 100644
index 000000000..514e8816e
--- /dev/null
+++ b/src/shared/deviceskin/skins/PortableMedia.skin/defaultbuttons.conf
@@ -0,0 +1,23 @@
+[Translation]
+File=QtopiaDefaults
+Context=Buttons
+[Menu]
+Map=123
+Default=1
+1=Applications/mediaplayer.desktop
+2=Applications/photoedit.desktop
+3=Settings
+Animator=Bounce
+AnimatorBackground=Radial
+[SoftKeys]
+Count=3
+Key0=Context1
+Key1=Select
+Key2=Back
+[SystemButtons]
+Count=5
+Key0=Context1
+Key1=Select
+Key2=Back
+[Device]
+PrimaryInput=Keypad
diff --git a/src/shared/deviceskin/skins/PortableMedia.skin/portablemedia-pressed.png b/src/shared/deviceskin/skins/PortableMedia.skin/portablemedia-pressed.png
new file mode 100644
index 000000000..730e76287
--- /dev/null
+++ b/src/shared/deviceskin/skins/PortableMedia.skin/portablemedia-pressed.png
Binary files differ
diff --git a/src/shared/deviceskin/skins/PortableMedia.skin/portablemedia.png b/src/shared/deviceskin/skins/PortableMedia.skin/portablemedia.png
new file mode 100644
index 000000000..e44cbe160
--- /dev/null
+++ b/src/shared/deviceskin/skins/PortableMedia.skin/portablemedia.png
Binary files differ
diff --git a/src/shared/deviceskin/skins/PortableMedia.skin/portablemedia.xcf b/src/shared/deviceskin/skins/PortableMedia.skin/portablemedia.xcf
new file mode 100644
index 000000000..127e07c8e
--- /dev/null
+++ b/src/shared/deviceskin/skins/PortableMedia.skin/portablemedia.xcf
Binary files differ
diff --git a/src/shared/deviceskin/skins/S60-QVGA-Candybar.qrc b/src/shared/deviceskin/skins/S60-QVGA-Candybar.qrc
new file mode 100644
index 000000000..813848479
--- /dev/null
+++ b/src/shared/deviceskin/skins/S60-QVGA-Candybar.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/skins">
+ <file>S60-QVGA-Candybar.skin</file>
+</qresource>
+</RCC>
diff --git a/src/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar-down.png b/src/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar-down.png
new file mode 100644
index 000000000..89d40cbed
--- /dev/null
+++ b/src/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar-down.png
Binary files differ
diff --git a/src/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar.png b/src/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar.png
new file mode 100644
index 000000000..0d0e598b9
--- /dev/null
+++ b/src/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar.png
Binary files differ
diff --git a/src/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar.skin b/src/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar.skin
new file mode 100644
index 000000000..4f8fe5dca
--- /dev/null
+++ b/src/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar.skin
@@ -0,0 +1,15 @@
+[SkinFile]
+Up=S60-QVGA-Candybar.png
+Down=S60-QVGA-Candybar-down.png
+Screen=61 93 240 320
+Areas=7
+HasMouseHover=false
+
+
+"Context1" 0x01100000 54 469 151 469 140 483 88 485 81 496 54 498
+"Back" 0x01000061 211 468 307 467 307 498 278 497 219 486
+"Select" 0x01010000 165 491 196 522
+"Left" 0x1000012 149 474 166 492 163 519 143 538 142 481
+"Down" 0x1000015 164 521 195 522 212 539 204 545 154 544 145 536
+"Right" 0x1000014 214 475 219 487 219 528 212 539 196 522 197 492
+"Up" 0x1000013 150 474 156 467 209 467 213 476 197 489 165 489
diff --git a/src/shared/deviceskin/skins/S60-QVGA-Candybar.skin/defaultbuttons.conf b/src/shared/deviceskin/skins/S60-QVGA-Candybar.skin/defaultbuttons.conf
new file mode 100644
index 000000000..e349dbc1f
--- /dev/null
+++ b/src/shared/deviceskin/skins/S60-QVGA-Candybar.skin/defaultbuttons.conf
@@ -0,0 +1,78 @@
+[Translation]
+File=QtopiaDefaults
+Context=Buttons
+[Menu]
+Rows=4
+Columns=3
+Map=123456789*0#
+Default=5
+1=Applications/camera.desktop
+2=Applications/datebook.desktop
+3=Applications
+4=Applications/qtmail.desktop
+5=Applications/addressbook.desktop
+6=Games
+7=Settings/Beaming.desktop
+8=Applications/simapp.desktop,Applications/calculator.desktop
+9=Settings
+*=Applications/mediarecorder.desktop
+0=Applications/todolist.desktop
+#=Documents
+Animator=Bounce
+AnimatorBackground=Radial
+[SoftKeys]
+Count=3
+Key0=Context1
+Key1=Select
+Key2=Back
+[SystemButtons]
+Count=5
+Key0=Context1
+Key1=Select
+Key2=Back
+Key3=Flip
+Key4=Backspace
+[TextButtons]
+Buttons=0123456789*#
+Hold0='0
+Hold1='1
+Hold2='2
+Hold3='3
+Hold4='4
+Hold5='5
+Hold6='6
+Hold7='7
+Hold8='8
+Hold9='9
+Hold*=symbol
+Hold#=mode
+Tap0=space
+Tap1="\".,'?!-@:1"
+Tap2="\"a\xe4\xe5\xe6\xe0\xe1\xe2\x62\x63\xe7\x32"
+Tap3="\"de\xe8\xe9\xea\x66\x33"
+Tap4="\"ghi\xec\xed\xee\x34"
+Tap5="\"jkl5"
+Tap6="\"mn\xf1o\xf6\xf8\xf2\xf3\x36"
+Tap7="\"pqrs\xdf\x37"
+Tap8="\"tu\xfc\xf9\xfav8"
+Tap9="\"wxyz9"
+Tap*=modify
+Tap#=shift
+[LocaleTextButtons]
+Buttons=23456789
+Tap2[]='abc
+Tap3[]='def
+Tap4[]='ghi
+Tap5[]='jkl
+Tap6[]='mno
+Tap7[]='pqrs
+Tap8[]='tuv
+Tap9[]='wxyz
+[PhoneTextButtons]
+Buttons=*#
+Tap*='*+pw
+Hold*=+
+Tap#=#
+Hold#=mode
+[Device]
+PrimaryInput=Keypad
diff --git a/src/shared/deviceskin/skins/S60-nHD-Touchscreen.qrc b/src/shared/deviceskin/skins/S60-nHD-Touchscreen.qrc
new file mode 100644
index 000000000..daf0cc363
--- /dev/null
+++ b/src/shared/deviceskin/skins/S60-nHD-Touchscreen.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/skins">
+ <file>S60-nHD-Touchscreen.skin</file>
+</qresource>
+</RCC>
diff --git a/src/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen-down.png b/src/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen-down.png
new file mode 100644
index 000000000..7253e3801
--- /dev/null
+++ b/src/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen-down.png
Binary files differ
diff --git a/src/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen.png b/src/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen.png
new file mode 100644
index 000000000..675563e5c
--- /dev/null
+++ b/src/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen.png
Binary files differ
diff --git a/src/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen.skin b/src/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen.skin
new file mode 100644
index 000000000..ed25d0eac
--- /dev/null
+++ b/src/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen.skin
@@ -0,0 +1,10 @@
+[SkinFile]
+Up=S60-nHD-Touchscreen.png
+Down=S60-nHD-Touchscreen-down.png
+Screen=53 183 360 640
+Areas=3
+HasMouseHover=false
+
+"Call" 0x01100004 76 874 171 899
+"Hangup" 0x01100005 300 876 393 899
+"Home" 0x1000010 174 878 298 899
diff --git a/src/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/defaultbuttons.conf b/src/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/defaultbuttons.conf
new file mode 100644
index 000000000..6665125c9
--- /dev/null
+++ b/src/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/defaultbuttons.conf
@@ -0,0 +1,53 @@
+[Translation]
+File=QtopiaDefaults
+Context=Buttons
+[Menu]
+Rows=4
+Columns=3
+Map=123456789*0#
+Default=5
+1=Applications/camera.desktop
+2=Applications/mediaplayer.desktop
+3=Applications/simapp.desktop,Applications/calculator.desktop
+4=Applications/qtmail.desktop
+5=Applications/addressbook.desktop
+6=Applications/datebook.desktop
+7=Games
+8=Settings/beaming.desktop
+9=Applications/todolist.desktop
+*=Settings
+0=Applications
+#=Documents
+Animator=Bounce
+AnimatorBackground=Radial
+[SoftKeys]
+Count=3
+Key0=Context1
+Key1=Select
+Key2=Back
+[SystemButtons]
+Count=5
+Key0=Context1
+Key1=Back
+Key2=Select
+Key3=Call
+Key4=Hangup
+[Device]
+PrimaryInput=Touchscreen
+[Button]
+Count=2
+[Button0]
+Name[]=Home Button
+Key=Home
+PressedActionMappable=0
+PressedActionService=TaskManager
+PressedActionMessage=multitask()
+HeldActionMappable=0
+HeldActionService=TaskManager
+HeldActionMessage=showRunningTasks()
+[Button1]
+Name=Power Button
+Key=Hangup
+HeldActionService=Launcher
+HeldActionMessage=execute(QString)
+HeldActionArgs=@ByteArray(\0\0\0\x1\0\0\0\n\0\0\0\0\x10\0s\0h\0u\0t\0\x64\0o\0w\0n)
diff --git a/src/shared/deviceskin/skins/SmartPhone.qrc b/src/shared/deviceskin/skins/SmartPhone.qrc
new file mode 100644
index 000000000..8bb53259a
--- /dev/null
+++ b/src/shared/deviceskin/skins/SmartPhone.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/skins">
+ <file>SmartPhone.skin</file>
+</qresource>
+</RCC>
diff --git a/src/shared/deviceskin/skins/SmartPhone.skin/SmartPhone-pressed.png b/src/shared/deviceskin/skins/SmartPhone.skin/SmartPhone-pressed.png
new file mode 100644
index 000000000..d0db2ed35
--- /dev/null
+++ b/src/shared/deviceskin/skins/SmartPhone.skin/SmartPhone-pressed.png
Binary files differ
diff --git a/src/shared/deviceskin/skins/SmartPhone.skin/SmartPhone.png b/src/shared/deviceskin/skins/SmartPhone.skin/SmartPhone.png
new file mode 100644
index 000000000..e6ac5a0f3
--- /dev/null
+++ b/src/shared/deviceskin/skins/SmartPhone.skin/SmartPhone.png
Binary files differ
diff --git a/src/shared/deviceskin/skins/SmartPhone.skin/SmartPhone.skin b/src/shared/deviceskin/skins/SmartPhone.skin/SmartPhone.skin
new file mode 100644
index 000000000..2f44c5aa8
--- /dev/null
+++ b/src/shared/deviceskin/skins/SmartPhone.skin/SmartPhone.skin
@@ -0,0 +1,28 @@
+[SkinFile]
+Up=SmartPhone.png
+Down=SmartPhone-pressed.png
+Screen=90 107 176 208
+Areas=21
+HasMouseHover=false
+
+"1" 0x0031 138 459 149 473 142 483 120 484 102 477 95 464 99 457 121 454
+"2" 0x0032 153 467 202 492
+"3" 0x0033 258 457 260 470 243 483 215 484 207 474 218 460 248 453
+"4" 0x0034 138 492 149 506 142 516 120 517 102 510 95 497 99 490 121 487
+"5" 0x0035 153 499 202 524
+"6" 0x0036 258 489 260 502 243 515 215 516 207 506 218 492 248 485
+"7" 0x0037 138 524 149 538 142 548 120 549 102 542 95 529 99 522 121 519
+"8" 0x0038 153 531 202 556
+"9" 0x0039 258 521 260 534 243 547 215 548 207 538 218 524 248 517
+"*" 0x002a 138 556 149 570 142 580 120 581 102 574 95 561 99 554 121 551
+"0" 0x0030 153 564 202 589
+"#" 0x0023 258 554 260 567 243 580 215 581 207 571 218 557 248 550
+"Call" 0x01100004 88 395 130 439
+"Hangup" 0x01100005 227 395 269 439
+"Context1" 0x01100000 145 321 134 333 132 361 134 374 110 343 109 318
+"Back" 0x01000061 249 322 240 354 219 373 223 344 216 325 208 318
+"Select" 0x01010000 160 338 195 371
+"Left" 0x1000012 159 338 149 328 141 336 141 373 149 381 159 371 159 369
+"Down" 0x1000015 160 373 150 382 159 391 199 391 207 385 196 374 194 374
+"Right" 0x1000014 195 336 206 323 215 338 215 373 208 384 197 375
+"Up" 0x1000013 160 336 149 326 158 319 197 319 203 322 194 337
diff --git a/src/shared/deviceskin/skins/SmartPhone.skin/defaultbuttons.conf b/src/shared/deviceskin/skins/SmartPhone.skin/defaultbuttons.conf
new file mode 100644
index 000000000..110335055
--- /dev/null
+++ b/src/shared/deviceskin/skins/SmartPhone.skin/defaultbuttons.conf
@@ -0,0 +1,78 @@
+[Translation]
+File=QtopiaDefaults
+Context=Buttons
+[Menu]
+Rows=4
+Columns=3
+Map=123456789*0#
+Default=5
+1=Applications/camera.desktop
+2=Applications/datebook.desktop
+3=Applications
+4=Applications/qtmail.desktop
+5=Applications/addressbook.desktop
+6=Games
+7=Settings/Beaming.desktop
+8=Applications/simapp.desktop,Applications/calculator.desktop
+9=Settings
+*=Applications/mediarecorder.desktop
+0=Applications/todolist.desktop
+#=Documents
+Animator=Bounce
+AnimatorBackground=Radial
+[SoftKeys]
+Count=3
+Key0=Context1
+Key1=Select
+Key2=Back
+[SystemButtons]
+Count=5
+Key0=Context1
+Key1=Select
+Key2=Back
+Key3=Call
+Key4=Hangup
+[TextButtons]
+Buttons=0123456789*#
+Hold0='0
+Hold1='1
+Hold2='2
+Hold3='3
+Hold4='4
+Hold5='5
+Hold6='6
+Hold7='7
+Hold8='8
+Hold9='9
+Hold*=symbol
+Hold#=mode
+Tap0=space
+Tap1="\".,'?!-@:1"
+Tap2="\"a\xe4\xe5\xe6\xe0\xe1\xe2\x62\x63\xe7\x32"
+Tap3="\"de\xe8\xe9\xea\x66\x33"
+Tap4="\"ghi\xec\xed\xee\x34"
+Tap5="\"jkl5"
+Tap6="\"mn\xf1o\xf6\xf8\xf2\xf3\x36"
+Tap7="\"pqrs\xdf\x37"
+Tap8="\"tu\xfc\xf9\xfav8"
+Tap9="\"wxyz9"
+Tap*=modify
+Tap#=shift
+[LocaleTextButtons]
+Buttons=23456789
+Tap2[]='abc
+Tap3[]='def
+Tap4[]='ghi
+Tap5[]='jkl
+Tap6[]='mno
+Tap7[]='pqrs
+Tap8[]='tuv
+Tap9[]='wxyz
+[PhoneTextButtons]
+Buttons=*#
+Tap*='*+pw
+Hold*=+
+Tap#='#
+Hold#=mode
+[Device]
+PrimaryInput=Keypad
diff --git a/src/shared/deviceskin/skins/SmartPhone2.qrc b/src/shared/deviceskin/skins/SmartPhone2.qrc
new file mode 100644
index 000000000..751e9852b
--- /dev/null
+++ b/src/shared/deviceskin/skins/SmartPhone2.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/skins">
+ <file>SmartPhone2.skin</file>
+</qresource>
+</RCC>
diff --git a/src/shared/deviceskin/skins/SmartPhone2.skin/SmartPhone2-pressed.png b/src/shared/deviceskin/skins/SmartPhone2.skin/SmartPhone2-pressed.png
new file mode 100644
index 000000000..d4eb5b0c8
--- /dev/null
+++ b/src/shared/deviceskin/skins/SmartPhone2.skin/SmartPhone2-pressed.png
Binary files differ
diff --git a/src/shared/deviceskin/skins/SmartPhone2.skin/SmartPhone2.png b/src/shared/deviceskin/skins/SmartPhone2.skin/SmartPhone2.png
new file mode 100644
index 000000000..48ccc1c5a
--- /dev/null
+++ b/src/shared/deviceskin/skins/SmartPhone2.skin/SmartPhone2.png
Binary files differ
diff --git a/src/shared/deviceskin/skins/SmartPhone2.skin/SmartPhone2.skin b/src/shared/deviceskin/skins/SmartPhone2.skin/SmartPhone2.skin
new file mode 100644
index 000000000..16884bfb5
--- /dev/null
+++ b/src/shared/deviceskin/skins/SmartPhone2.skin/SmartPhone2.skin
@@ -0,0 +1,25 @@
+SmartPhone2.png SmartPhone2-pressed.png
+90 107
+176 220
+21
+"Menu" 0x01100000 70 400 115 427
+"Backspace" 0x01000003 238 400 285 427
+"1" 0x0031 138 437 149 451 142 461 120 462 102 455 95 442 99 435 121 432
+"2" 0x0032 153 445 202 470
+"3" 0x0033 258 435 260 448 243 461 215 462 207 452 218 438 248 431
+"4" 0x0034 138 470 149 484 142 494 120 495 102 488 95 475 99 468 121 465
+"5" 0x0035 153 477 202 502
+"6" 0x0036 258 467 260 480 243 493 215 494 207 484 218 470 248 463
+"7" 0x0037 138 502 149 516 142 526 120 527 102 520 95 507 99 500 121 497
+"8" 0x0038 153 509 202 534
+"9" 0x0039 258 499 260 512 243 525 215 526 207 516 218 502 248 495
+"*" 0x002a 138 534 149 548 142 558 120 559 102 552 95 539 99 532 121 529
+"0" 0x0030 153 542 202 567
+"#" 0x0023 258 532 260 545 243 558 215 559 207 549 218 535 248 528
+"Yes" 0x01010001 91 343 141 393
+"No" 0x01010002 219 343 269 393
+"Select" 0x01010000 160 356 195 389
+"Left" 0x1000012 159 356 149 346 141 354 141 391 149 399 159 389 159 387
+"Down" 0x1000015 160 391 150 400 159 409 199 409 207 403 196 392 194 392
+"Right" 0x1000014 195 354 206 341 215 356 215 391 208 402 197 393
+"Up" 0x1000013 160 354 149 344 158 337 197 337 203 340 194 355
diff --git a/src/shared/deviceskin/skins/SmartPhone2.skin/defaultbuttons.conf b/src/shared/deviceskin/skins/SmartPhone2.skin/defaultbuttons.conf
new file mode 100644
index 000000000..b08320347
--- /dev/null
+++ b/src/shared/deviceskin/skins/SmartPhone2.skin/defaultbuttons.conf
@@ -0,0 +1,52 @@
+[Button]
+[IMethod]
+key_count = 5
+key_hold_action_1 = insertText
+key_hold_action_2 = insertText
+key_hold_action_3 = insertSymbol
+key_hold_action_4 = changeMode
+key_hold_arg_1 = 1
+key_hold_arg_2 = 0
+key_id_1 = 1
+key_id_2 = 0
+key_id_3 = *
+key_id_4 = #
+key_id_5 = *
+key_mode_1 = Abc
+key_mode_2 = Abc
+key_mode_3 = Abc
+key_mode_4 = Abc
+key_mode_5 = Phone
+key_tap_action_1 = insertText
+key_tap_action_2 = insertSpace
+key_tap_action_3 = modifyText
+key_tap_action_4 = changeShift
+key_tap_action_5 = insertText
+key_tap_arg_1 = .,'?!-@:〓
+key_tap_arg_5 = *+pw
+[Menu]
+1 = Applications/camera.desktop
+2 = Applications/datebook.desktop
+3 = Games
+4 = Applications/qtmail.desktop
+5 = Applications/addressbook.desktop
+6 = Settings
+7 = Settings/Beaming.desktop
+8 = Applications
+9 = Documents
+Columns = 3
+Default = 5
+Map = 123456789
+Rows = 3
+Animator=Bounce
+AnimatorBackground=Radial
+[SoftKeys]
+[SystemButtons]
+Count=5
+Key0=Yes
+Key1=Select
+Key2=No
+Key3=Menu
+Key4=Backspace
+[Device]
+PrimaryInput=Keypad
diff --git a/src/shared/deviceskin/skins/SmartPhoneWithButtons.qrc b/src/shared/deviceskin/skins/SmartPhoneWithButtons.qrc
new file mode 100644
index 000000000..f3393ba9d
--- /dev/null
+++ b/src/shared/deviceskin/skins/SmartPhoneWithButtons.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/skins">
+ <file>SmartPhoneWithButtons.skin</file>
+</qresource>
+</RCC>
diff --git a/src/shared/deviceskin/skins/SmartPhoneWithButtons.skin/SmartPhoneWithButtons-pressed.png b/src/shared/deviceskin/skins/SmartPhoneWithButtons.skin/SmartPhoneWithButtons-pressed.png
new file mode 100644
index 000000000..456a068ee
--- /dev/null
+++ b/src/shared/deviceskin/skins/SmartPhoneWithButtons.skin/SmartPhoneWithButtons-pressed.png
Binary files differ
diff --git a/src/shared/deviceskin/skins/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.png b/src/shared/deviceskin/skins/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.png
new file mode 100644
index 000000000..5ffbd6e4e
--- /dev/null
+++ b/src/shared/deviceskin/skins/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.png
Binary files differ
diff --git a/src/shared/deviceskin/skins/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.skin b/src/shared/deviceskin/skins/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.skin
new file mode 100644
index 000000000..9afa67f30
--- /dev/null
+++ b/src/shared/deviceskin/skins/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.skin
@@ -0,0 +1,31 @@
+[SkinFile]
+Up=SmartPhoneWithButtons.png
+Down=SmartPhoneWithButtons-pressed.png
+Screen=90 107 176 208
+Areas=24
+HasMouseHover=false
+
+"1" 0x0031 138 459 149 473 142 483 120 484 102 477 95 464 99 457 121 454
+"2" 0x0032 153 467 202 492
+"3" 0x0033 258 457 260 470 243 483 215 484 207 474 218 460 248 453
+"4" 0x0034 138 492 149 506 142 516 120 517 102 510 95 497 99 490 121 487
+"5" 0x0035 153 499 202 524
+"6" 0x0036 258 489 260 502 243 515 215 516 207 506 218 492 248 485
+"7" 0x0037 138 524 149 538 142 548 120 549 102 542 95 529 99 522 121 519
+"8" 0x0038 153 531 202 556
+"9" 0x0039 258 521 260 534 243 547 215 548 207 538 218 524 248 517
+"*" 0x002a 138 556 149 570 142 580 120 581 102 574 95 561 99 554 121 551
+"0" 0x0030 153 564 202 589
+"#" 0x0023 258 554 260 567 243 580 215 581 207 571 218 557 248 550
+"Call" 0x01100004 88 395 130 439
+"Hangup" 0x01100005 227 395 269 439
+"Context1" 0x01100000 145 321 134 333 132 361 134 374 110 343 109 318
+"Back" 0x01000061 249 322 240 354 219 373 223 344 216 325 208 318
+"Select" 0x01010000 160 338 195 371
+"Left" 0x1000012 159 338 149 328 141 336 141 373 149 381 159 371 159 369
+"Down" 0x1000015 160 373 150 382 159 391 199 391 207 385 196 374 194 374
+"Right" 0x1000014 195 336 206 323 215 338 215 373 208 384 197 375
+"Up" 0x1000013 160 336 149 326 158 319 197 319 203 322 194 337
+"Home" 0x1000010 164 402 195 434
+"F1" 0x1000030 138 422 163 448
+"F2" 0x1000031 196 422 220 448
diff --git a/src/shared/deviceskin/skins/SmartPhoneWithButtons.skin/defaultbuttons.conf b/src/shared/deviceskin/skins/SmartPhoneWithButtons.skin/defaultbuttons.conf
new file mode 100644
index 000000000..ebd6926ae
--- /dev/null
+++ b/src/shared/deviceskin/skins/SmartPhoneWithButtons.skin/defaultbuttons.conf
@@ -0,0 +1,103 @@
+[Translation]
+File=QtopiaDefaults
+Context=Buttons
+[Button]
+Count=3
+[Button0]
+Name[]=Calendar Button
+Key=F1
+PressedActionService=Calendar
+PressedActionMessage=raiseToday()
+HeldActionService=Calendar
+HeldActionMessage=newEvent()
+[Button1]
+Name[]=Tasks Button
+Key=F2
+PressedActionService=Tasks
+PressedActionMessage=raise()
+HeldActionService=Tasks
+HeldActionMessage=newTask()
+[Button2]
+Name[]=Home Button
+Key=Home
+PressedActionMappable=0
+PressedActionService=TaskManager
+PressedActionMessage=multitask()
+HeldActionMappable=0
+HeldActionService=TaskManager
+HeldActionMessage=showRunningTasks()
+[Menu]
+Rows=4
+Columns=3
+Map=123456789*0#
+Default=5
+1=Applications/camera.desktop
+2=Applications/datebook.desktop
+3=Applications
+4=Applications/qtmail.desktop
+5=Applications/addressbook.desktop
+6=Games
+7=Settings/Beaming.desktop
+8=Applications/simapp.desktop,Applications/calculator.desktop
+9=Settings
+*=Applications/mediarecorder.desktop
+0=Applications/todolist.desktop
+#=Documents
+Animator=Bounce
+AnimatorBackground=Radial
+[SoftKeys]
+Count=3
+Key0=Context1
+Key1=Select
+Key2=Back
+[SystemButtons]
+Count=5
+Key0=Context1
+Key1=Select
+Key2=Back
+Key3=Call
+Key4=Hangup
+[TextButtons]
+Buttons=0123456789*#
+Hold0='0
+Hold1='1
+Hold2='2
+Hold3='3
+Hold4='4
+Hold5='5
+Hold6='6
+Hold7='7
+Hold8='8
+Hold9='9
+Hold*=symbol
+Hold#=mode
+Tap0=space
+Tap1="\".,'?!-@:1"
+Tap2="\"a\xe4\xe5\xe6\xe0\xe1\xe2\x62\x63\xe7\x32"
+Tap3="\"de\xe8\xe9\xea\x66\x33"
+Tap4="\"ghi\xec\xed\xee\x34"
+Tap5="\"jkl5"
+Tap6="\"mn\xf1o\xf6\xf8\xf2\xf3\x36"
+Tap7="\"pqrs\xdf\x37"
+Tap8="\"tu\xfc\xf9\xfav8"
+Tap9="\"wxyz9"
+Tap*=modify
+Tap#=shift
+[LocaleTextButtons]
+Buttons=23456789
+Tap2[]='abc
+Tap3[]='def
+Tap4[]='ghi
+Tap5[]='jkl
+Tap6[]='mno
+Tap7[]='pqrs
+Tap8[]='tuv
+Tap9[]='wxyz
+[PhoneTextButtons]
+Buttons=*#
+Tap*='*+pw
+Hold*=+
+Tap#='#
+Hold#=mode
+[Device]
+PrimaryInput=Keypad
diff --git a/src/shared/deviceskin/skins/TouchscreenPhone.qrc b/src/shared/deviceskin/skins/TouchscreenPhone.qrc
new file mode 100644
index 000000000..023144d2f
--- /dev/null
+++ b/src/shared/deviceskin/skins/TouchscreenPhone.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/skins">
+ <file>TouchscreenPhone.skin</file>
+</qresource>
+</RCC>
diff --git a/src/shared/deviceskin/skins/TouchscreenPhone.skin/TouchscreenPhone-pressed.png b/src/shared/deviceskin/skins/TouchscreenPhone.skin/TouchscreenPhone-pressed.png
new file mode 100644
index 000000000..01acb8654
--- /dev/null
+++ b/src/shared/deviceskin/skins/TouchscreenPhone.skin/TouchscreenPhone-pressed.png
Binary files differ
diff --git a/src/shared/deviceskin/skins/TouchscreenPhone.skin/TouchscreenPhone.png b/src/shared/deviceskin/skins/TouchscreenPhone.skin/TouchscreenPhone.png
new file mode 100644
index 000000000..e90de0de4
--- /dev/null
+++ b/src/shared/deviceskin/skins/TouchscreenPhone.skin/TouchscreenPhone.png
Binary files differ
diff --git a/src/shared/deviceskin/skins/TouchscreenPhone.skin/TouchscreenPhone.skin b/src/shared/deviceskin/skins/TouchscreenPhone.skin/TouchscreenPhone.skin
new file mode 100644
index 000000000..24316a1b4
--- /dev/null
+++ b/src/shared/deviceskin/skins/TouchscreenPhone.skin/TouchscreenPhone.skin
@@ -0,0 +1,16 @@
+[SkinFile]
+Up=TouchscreenPhone.png
+Down=TouchscreenPhone-pressed.png
+Screen=90 107 176 208
+Areas=9
+HasMouseHover=false
+
+"Context1" 0x01100000 145 321 134 333 132 361 134 374 110 343 109 318
+"Call" 0x01100004 88 395 130 439
+"Hangup" 0x01100005 227 395 269 439
+"Back" 0x01000061 249 322 240 354 219 373 223 344 216 325 208 318
+"Left" 0x1000012 159 338 149 328 141 336 141 373 149 381 159 371 159 369
+"Down" 0x1000015 160 373 150 382 159 391 199 391 207 385 196 374 194 374
+"Right" 0x1000014 195 336 206 323 215 338 215 373 208 384 197 375
+"Up" 0x1000013 160 336 149 326 158 319 197 319 203 322 194 337
+"Select" 0x01010000 160 338 195 371
diff --git a/src/shared/deviceskin/skins/TouchscreenPhone.skin/defaultbuttons.conf b/src/shared/deviceskin/skins/TouchscreenPhone.skin/defaultbuttons.conf
new file mode 100644
index 000000000..a13dfdc3b
--- /dev/null
+++ b/src/shared/deviceskin/skins/TouchscreenPhone.skin/defaultbuttons.conf
@@ -0,0 +1,45 @@
+[Translation]
+File=QtopiaDefaults
+Context=Buttons
+[Menu]
+Rows=4
+Columns=3
+Map=123456789*0#
+Default=5
+1=Applications/camera.desktop
+2=Applications/datebook.desktop
+3=Applications
+4=Applications/qtmail.desktop
+5=Applications/addressbook.desktop
+6=Games
+7=Settings/Beaming.desktop
+8=Applications/simapp.desktop,Applications/calculator.desktop
+9=Settings
+*=Applications/mediarecorder.desktop
+0=Applications/todolist.desktop
+#=Documents
+Animator=Bounce
+AnimatorBackground=Radial
+[SoftKeys]
+Count=3
+Key0=Context1
+Key1=Select
+Key2=Back
+[SystemButtons]
+Count=5
+Key0=Context1
+Key1=Back
+Key2=Select
+Key3=Call
+Key4=Hangup
+[Button]
+Count=1
+[Button0]
+Name=Power Button
+Key=Hangup
+HeldActionService=Launcher
+HeldActionMessage=execute(QString)
+HeldActionArgs=@ByteArray(\0\0\0\x1\0\0\0\n\0\0\0\0\x10\0s\0h\0u\0t\0\x64\0o\0w\0n)
+[Device]
+PrimaryInput=Touchscreen
+
diff --git a/src/shared/findwidget/abstractfindwidget.cpp b/src/shared/findwidget/abstractfindwidget.cpp
new file mode 100644
index 000000000..b9f7a811e
--- /dev/null
+++ b/src/shared/findwidget/abstractfindwidget.cpp
@@ -0,0 +1,295 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*! \class AbstractFindWidget
+
+ \brief A search bar that is commonly added below a searchable widget.
+
+ \internal
+
+ This widget implements a search bar which becomes visible when the user
+ wants to start searching. It is a modern replacement for the commonly used
+ search dialog. It is usually placed below the target widget using a QVBoxLayout.
+
+ The search is incremental and can be set to case sensitive or whole words
+ using buttons available on the search bar.
+ */
+
+#include "abstractfindwidget.h"
+
+#include <QtCore/QEvent>
+#include <QtCore/QFile>
+#include <QtCore/QTimer>
+
+#include <QtGui/QCheckBox>
+#include <QtGui/QKeyEvent>
+#include <QtGui/QLabel>
+#include <QtGui/QLayout>
+#include <QtGui/QLineEdit>
+#include <QtGui/QSpacerItem>
+#include <QtGui/QToolButton>
+
+QT_BEGIN_NAMESPACE
+
+static QIcon createIconSet(const QString &name)
+{
+ QStringList candidates = QStringList()
+ << (QString::fromUtf8(":/trolltech/shared/images/") + name)
+#ifdef Q_WS_MAC
+ << (QString::fromUtf8(":/trolltech/shared/images/mac/") + name);
+#else
+ << (QString::fromUtf8(":/trolltech/shared/images/win/") + name);
+#endif
+
+ foreach (const QString &f, candidates) {
+ if (QFile::exists(f))
+ return QIcon(f);
+ }
+
+ return QIcon();
+}
+
+/*!
+ Constructs an AbstractFindWidget.
+
+ \a flags can change the layout and turn off certain features.
+ \a parent is passed to the QWidget constructor.
+ */
+AbstractFindWidget::AbstractFindWidget(FindFlags flags, QWidget *parent)
+ : QWidget(parent)
+{
+ QBoxLayout *topLayOut;
+ QBoxLayout *layOut;
+ if (flags & NarrowLayout) {
+ topLayOut = new QVBoxLayout(this);
+ layOut = new QHBoxLayout;
+ topLayOut->addLayout(layOut);
+ } else {
+ topLayOut = layOut = new QHBoxLayout(this);
+ }
+#ifndef Q_OS_MAC
+ topLayOut->setSpacing(6);
+ topLayOut->setMargin(0);
+#endif
+
+ m_toolClose = new QToolButton(this);
+ m_toolClose->setIcon(createIconSet(QLatin1String("closetab.png")));
+ m_toolClose->setAutoRaise(true);
+ layOut->addWidget(m_toolClose);
+ connect(m_toolClose, SIGNAL(clicked()), SLOT(deactivate()));
+
+ m_editFind = new QLineEdit(this);
+ layOut->addWidget(m_editFind);
+ connect(m_editFind, SIGNAL(returnPressed()), SLOT(findNext()));
+ connect(m_editFind, SIGNAL(textChanged(QString)), SLOT(findCurrentText()));
+ connect(m_editFind, SIGNAL(textChanged(QString)), SLOT(updateButtons()));
+
+ m_toolPrevious = new QToolButton(this);
+ m_toolPrevious->setAutoRaise(true);
+ m_toolPrevious->setText(tr("&Previous"));
+ m_toolPrevious->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ m_toolPrevious->setIcon(createIconSet(QLatin1String("previous.png")));
+ layOut->addWidget(m_toolPrevious);
+ connect(m_toolPrevious, SIGNAL(clicked()), SLOT(findPrevious()));
+
+ m_toolNext = new QToolButton(this);
+ m_toolNext->setAutoRaise(true);
+ m_toolNext->setText(tr("&Next"));
+ m_toolNext->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ m_toolNext->setIcon(createIconSet(QLatin1String("next.png")));
+ layOut->addWidget(m_toolNext);
+ connect(m_toolNext, SIGNAL(clicked()), SLOT(findNext()));
+
+ if (flags & NarrowLayout) {
+ QSizePolicy sp(QSizePolicy::Preferred, QSizePolicy::Fixed);
+ m_toolPrevious->setSizePolicy(sp);
+ m_toolPrevious->setMinimumWidth(m_toolPrevious->minimumSizeHint().height());
+ m_toolNext->setSizePolicy(sp);
+ m_toolNext->setMinimumWidth(m_toolNext->minimumSizeHint().height());
+
+ QSpacerItem *spacerItem =
+ new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ layOut->addItem(spacerItem);
+
+ layOut = new QHBoxLayout;
+ topLayOut->addLayout(layOut);
+ } else {
+ m_editFind->setMinimumWidth(150);
+ }
+
+ if (!(flags & NoCaseSensitive)) {
+ m_checkCase = new QCheckBox(tr("&Case sensitive"), this);
+ layOut->addWidget(m_checkCase);
+ connect(m_checkCase, SIGNAL(toggled(bool)), SLOT(findCurrentText()));
+ } else {
+ m_checkCase = 0;
+ }
+
+ if (!(flags & NoWholeWords)) {
+ m_checkWholeWords = new QCheckBox(tr("Whole &words"), this);
+ layOut->addWidget(m_checkWholeWords);
+ connect(m_checkWholeWords, SIGNAL(toggled(bool)), SLOT(findCurrentText()));
+ } else {
+ m_checkWholeWords = 0;
+ }
+
+ m_labelWrapped = new QLabel(this);
+ m_labelWrapped->setTextFormat(Qt::RichText);
+ m_labelWrapped->setAlignment(
+ Qt::AlignLeading | Qt::AlignLeft | Qt::AlignVCenter);
+ m_labelWrapped->setText(
+ tr("<img src=\":/trolltech/shared/images/wrap.png\">"
+ "&nbsp;Search wrapped"));
+ m_labelWrapped->hide();
+ layOut->addWidget(m_labelWrapped);
+
+ QSpacerItem *spacerItem =
+ new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ layOut->addItem(spacerItem);
+
+ setMinimumWidth(minimumSizeHint().width());
+
+ updateButtons();
+ hide();
+}
+
+/*!
+ Destroys the AbstractFindWidget.
+ */
+AbstractFindWidget::~AbstractFindWidget()
+{
+}
+
+/*!
+ Returns the icon set to be used for the action that initiates a search.
+ */
+QIcon AbstractFindWidget::findIconSet()
+{
+ return createIconSet(QLatin1String("searchfind.png"));
+}
+
+/*!
+ Activates the find widget, making it visible and having focus on its input
+ field.
+ */
+void AbstractFindWidget::activate()
+{
+ show();
+ m_editFind->selectAll();
+ m_editFind->setFocus(Qt::ShortcutFocusReason);
+}
+
+/*!
+ Deactivates the find widget, making it invisible and handing focus to any
+ associated QTextEdit.
+ */
+void AbstractFindWidget::deactivate()
+{
+ hide();
+}
+
+void AbstractFindWidget::findNext()
+{
+ findInternal(m_editFind->text(), true, false);
+}
+
+void AbstractFindWidget::findPrevious()
+{
+ findInternal(m_editFind->text(), true, true);
+}
+
+void AbstractFindWidget::findCurrentText()
+{
+ findInternal(m_editFind->text(), false, false);
+}
+
+void AbstractFindWidget::keyPressEvent(QKeyEvent *event)
+{
+ if (event->key() == Qt::Key_Escape) {
+ deactivate();
+ return;
+ }
+
+ QWidget::keyPressEvent(event);
+}
+
+void AbstractFindWidget::updateButtons()
+{
+ const bool en = !m_editFind->text().isEmpty();
+ m_toolPrevious->setEnabled(en);
+ m_toolNext->setEnabled(en);
+}
+
+void AbstractFindWidget::findInternal(const QString &ttf, bool skipCurrent, bool backward)
+{
+ bool found = false;
+ bool wrapped = false;
+ find(ttf, skipCurrent, backward, &found, &wrapped);
+ QPalette p;
+ p.setColor(QPalette::Active, QPalette::Base, found ? Qt::white : QColor(255, 102, 102));
+ m_editFind->setPalette(p);
+ m_labelWrapped->setVisible(wrapped);
+}
+
+bool AbstractFindWidget::caseSensitive() const
+{
+ return m_checkCase && m_checkCase->isChecked();
+}
+
+bool AbstractFindWidget::wholeWords() const
+{
+ return m_checkWholeWords && m_checkWholeWords->isChecked();
+}
+
+bool AbstractFindWidget::eventFilter(QObject *object, QEvent *e)
+{
+ if (isVisible() && e->type() == QEvent::KeyPress) {
+ QKeyEvent *ke = static_cast<QKeyEvent*>(e);
+ if (ke->key() == Qt::Key_Escape) {
+ hide();
+ return true;
+ }
+ }
+
+ return QWidget::eventFilter(object, e);
+}
+
+QT_END_NAMESPACE
diff --git a/src/shared/findwidget/abstractfindwidget.h b/src/shared/findwidget/abstractfindwidget.h
new file mode 100644
index 000000000..6592911a8
--- /dev/null
+++ b/src/shared/findwidget/abstractfindwidget.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ABSTRACTFINDWIDGET_H
+#define ABSTRACTFINDWIDGET_H
+
+#include <QtGui/QIcon>
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QCheckBox;
+class QEvent;
+class QKeyEvent;
+class QLabel;
+class QLineEdit;
+class QObject;
+class QToolButton;
+
+class AbstractFindWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ enum FindFlag {
+ /// Use a layout that is roughly half as wide and twice as high as the regular one.
+ NarrowLayout = 1,
+ /// Do not show the "Whole words" checkbox.
+ NoWholeWords = 2,
+ /// Do not show the "Case sensitive" checkbox.
+ NoCaseSensitive = 4
+ };
+ Q_DECLARE_FLAGS(FindFlags, FindFlag)
+
+ explicit AbstractFindWidget(FindFlags flags = FindFlags(), QWidget *parent = 0);
+ virtual ~AbstractFindWidget();
+
+ bool eventFilter(QObject *object, QEvent *e);
+
+ static QIcon findIconSet();
+
+public slots:
+ void activate();
+ virtual void deactivate();
+ void findNext();
+ void findPrevious();
+ void findCurrentText();
+
+protected:
+ void keyPressEvent(QKeyEvent *event);
+
+private slots:
+ void updateButtons();
+
+protected:
+ virtual void find(const QString &textToFind, bool skipCurrent, bool backward, bool *found, bool *wrapped) = 0;
+
+ bool caseSensitive() const;
+ bool wholeWords() const;
+
+private:
+ void findInternal(const QString &textToFind, bool skipCurrent, bool backward);
+
+ QLineEdit *m_editFind;
+ QLabel *m_labelWrapped;
+ QToolButton *m_toolNext;
+ QToolButton *m_toolClose;
+ QToolButton *m_toolPrevious;
+ QCheckBox *m_checkCase;
+ QCheckBox *m_checkWholeWords;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractFindWidget::FindFlags)
+
+QT_END_NAMESPACE
+
+#endif // ABSTRACTFINDWIDGET_H
diff --git a/src/shared/findwidget/findwidget.pri b/src/shared/findwidget/findwidget.pri
new file mode 100644
index 000000000..6e0f58aff
--- /dev/null
+++ b/src/shared/findwidget/findwidget.pri
@@ -0,0 +1,4 @@
+INCLUDEPATH += $$PWD
+HEADERS += $$PWD/abstractfindwidget.h $$PWD/texteditfindwidget.h $$PWD/itemviewfindwidget.h
+SOURCES += $$PWD/abstractfindwidget.cpp $$PWD/texteditfindwidget.cpp $$PWD/itemviewfindwidget.cpp
+RESOURCES += $$PWD/findwidget.qrc
diff --git a/src/shared/findwidget/findwidget.qrc b/src/shared/findwidget/findwidget.qrc
new file mode 100644
index 000000000..1d45b25dd
--- /dev/null
+++ b/src/shared/findwidget/findwidget.qrc
@@ -0,0 +1,14 @@
+<RCC>
+ <qresource prefix="/trolltech/shared">
+ <file>images/mac/closetab.png</file>
+ <file>images/mac/next.png</file>
+ <file>images/mac/previous.png</file>
+ <file>images/mac/searchfind.png</file>
+ <file>images/win/closetab.png</file>
+ <file>images/win/next.png</file>
+ <file>images/win/previous.png</file>
+ <file>images/win/searchfind.png</file>
+ <file>images/wrap.png</file>
+ </qresource>
+</RCC>
+
diff --git a/src/shared/findwidget/images/mac/closetab.png b/src/shared/findwidget/images/mac/closetab.png
new file mode 100644
index 000000000..ab9d669ee
--- /dev/null
+++ b/src/shared/findwidget/images/mac/closetab.png
Binary files differ
diff --git a/src/shared/findwidget/images/mac/next.png b/src/shared/findwidget/images/mac/next.png
new file mode 100644
index 000000000..a585cab80
--- /dev/null
+++ b/src/shared/findwidget/images/mac/next.png
Binary files differ
diff --git a/src/shared/findwidget/images/mac/previous.png b/src/shared/findwidget/images/mac/previous.png
new file mode 100644
index 000000000..612fb34dc
--- /dev/null
+++ b/src/shared/findwidget/images/mac/previous.png
Binary files differ
diff --git a/src/shared/findwidget/images/mac/searchfind.png b/src/shared/findwidget/images/mac/searchfind.png
new file mode 100644
index 000000000..3561745f0
--- /dev/null
+++ b/src/shared/findwidget/images/mac/searchfind.png
Binary files differ
diff --git a/src/shared/findwidget/images/win/closetab.png b/src/shared/findwidget/images/win/closetab.png
new file mode 100644
index 000000000..ef9e02086
--- /dev/null
+++ b/src/shared/findwidget/images/win/closetab.png
Binary files differ
diff --git a/src/shared/findwidget/images/win/next.png b/src/shared/findwidget/images/win/next.png
new file mode 100644
index 000000000..8df4127a0
--- /dev/null
+++ b/src/shared/findwidget/images/win/next.png
Binary files differ
diff --git a/src/shared/findwidget/images/win/previous.png b/src/shared/findwidget/images/win/previous.png
new file mode 100644
index 000000000..0780bc23d
--- /dev/null
+++ b/src/shared/findwidget/images/win/previous.png
Binary files differ
diff --git a/src/shared/findwidget/images/win/searchfind.png b/src/shared/findwidget/images/win/searchfind.png
new file mode 100644
index 000000000..6ea35e930
--- /dev/null
+++ b/src/shared/findwidget/images/win/searchfind.png
Binary files differ
diff --git a/src/shared/findwidget/images/wrap.png b/src/shared/findwidget/images/wrap.png
new file mode 100644
index 000000000..90f18d9f7
--- /dev/null
+++ b/src/shared/findwidget/images/wrap.png
Binary files differ
diff --git a/src/shared/findwidget/itemviewfindwidget.cpp b/src/shared/findwidget/itemviewfindwidget.cpp
new file mode 100644
index 000000000..9249ed5f7
--- /dev/null
+++ b/src/shared/findwidget/itemviewfindwidget.cpp
@@ -0,0 +1,317 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*! \class ItemViewFindWidget
+
+ \brief A search bar that is commonly added below the searchable item view.
+
+ \internal
+
+ This widget implements a search bar which becomes visible when the user
+ wants to start searching. It is a modern replacement for the commonly used
+ search dialog. It is usually placed below a QAbstractItemView using a QVBoxLayout.
+
+ The QAbstractItemView instance will need to be associated with this class using
+ setItemView().
+
+ The search is incremental and can be set to case sensitive or whole words
+ using buttons available on the search bar.
+
+ The item traversal order should fit QTreeView, QTableView and QListView alike.
+ More complex tree structures will work as well, assuming the branch structure
+ is painted left to the items, without crossing lines.
+
+ \sa QAbstractItemView
+ */
+
+#include "itemviewfindwidget.h"
+
+#include <QtGui/QAbstractItemView>
+#include <QtGui/QCheckBox>
+#include <QtGui/QTreeView>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ Constructs a ItemViewFindWidget.
+
+ \a flags is passed to the AbstractFindWidget constructor.
+ \a parent is passed to the QWidget constructor.
+ */
+ItemViewFindWidget::ItemViewFindWidget(FindFlags flags, QWidget *parent)
+ : AbstractFindWidget(flags, parent)
+ , m_itemView(0)
+{
+}
+
+/*!
+ Associates a QAbstractItemView with this find widget. Searches done using this find
+ widget will then apply to the given QAbstractItemView.
+
+ An event filter is set on the QAbstractItemView which intercepts the ESC key while
+ the find widget is active, and uses it to deactivate the find widget.
+
+ If the find widget is already associated with a QAbstractItemView, the event filter
+ is removed from this QAbstractItemView first.
+
+ \a itemView may be NULL.
+ */
+void ItemViewFindWidget::setItemView(QAbstractItemView *itemView)
+{
+ if (m_itemView)
+ m_itemView->removeEventFilter(this);
+
+ m_itemView = itemView;
+
+ if (m_itemView)
+ m_itemView->installEventFilter(this);
+}
+
+/*!
+ \reimp
+ */
+void ItemViewFindWidget::deactivate()
+{
+ if (m_itemView)
+ m_itemView->setFocus();
+
+ AbstractFindWidget::deactivate();
+}
+
+// Sorting is needed to find the start/end of the selection.
+// This is utter black magic. And it is damn slow.
+static bool indexLessThan(const QModelIndex &a, const QModelIndex &b)
+{
+ // First determine the nesting of each index in the tree.
+ QModelIndex aa = a;
+ int aDepth = 0;
+ while (aa.parent() != QModelIndex()) {
+ // As a side effect, check if one of the items is the parent of the other.
+ // Children are always displayed below their parents, so sort them further down.
+ if (aa.parent() == b)
+ return true;
+ aa = aa.parent();
+ aDepth++;
+ }
+ QModelIndex ba = b;
+ int bDepth = 0;
+ while (ba.parent() != QModelIndex()) {
+ if (ba.parent() == a)
+ return false;
+ ba = ba.parent();
+ bDepth++;
+ }
+ // Now find indices at comparable depth.
+ for (aa = a; aDepth > bDepth; aDepth--)
+ aa = aa.parent();
+ for (ba = b; aDepth < bDepth; bDepth--)
+ ba = ba.parent();
+ // If they have the same parent, sort them within a top-to-bottom, left-to-right rectangle.
+ if (aa.parent() == ba.parent()) {
+ if (aa.row() < ba.row())
+ return true;
+ if (aa.row() > ba.row())
+ return false;
+ return aa.column() < ba.column();
+ }
+ // Now try to find indices that have the same grandparent. This ends latest at the root node.
+ while (aa.parent().parent() != ba.parent().parent()) {
+ aa = aa.parent();
+ ba = ba.parent();
+ }
+ // A bigger row is always displayed further down.
+ if (aa.parent().row() < ba.parent().row())
+ return true;
+ if (aa.parent().row() > ba.parent().row())
+ return false;
+ // Here's the trick: a child spawned from a bigger column is displayed further *up*.
+ // That's because the tree lines are on the left and are supposed not to cross each other.
+ // This case is mostly academical, as "all" models spawn children from the first column.
+ return aa.parent().column() > ba.parent().column();
+}
+
+/*!
+ \reimp
+ */
+void ItemViewFindWidget::find(const QString &ttf, bool skipCurrent, bool backward, bool *found, bool *wrapped)
+{
+ if (!m_itemView || !m_itemView->model()->hasChildren())
+ return;
+
+ QModelIndex idx;
+ if (skipCurrent && m_itemView->selectionModel()->hasSelection()) {
+ QModelIndexList il = m_itemView->selectionModel()->selectedIndexes();
+ qSort(il.begin(), il.end(), indexLessThan);
+ idx = backward ? il.first() : il.last();
+ } else {
+ idx = m_itemView->currentIndex();
+ }
+
+ *found = true;
+ QModelIndex newIdx = idx;
+
+ if (!ttf.isEmpty()) {
+ if (newIdx.isValid()) {
+ int column = newIdx.column();
+ if (skipCurrent)
+ if (QTreeView *tv = qobject_cast<QTreeView *>(m_itemView))
+ if (tv->allColumnsShowFocus())
+ column = backward ? 0 : m_itemView->model()->columnCount(newIdx.parent()) - 1;
+ newIdx = findHelper(ttf, skipCurrent, backward,
+ newIdx.parent(), newIdx.row(), column);
+ }
+ if (!newIdx.isValid()) {
+ int row = backward ? m_itemView->model()->rowCount() : 0;
+ int column = backward ? 0 : -1;
+ newIdx = findHelper(ttf, true, backward, m_itemView->rootIndex(), row, column);
+ if (!newIdx.isValid()) {
+ *found = false;
+ newIdx = idx;
+ } else {
+ *wrapped = true;
+ }
+ }
+ }
+
+ if (!isVisible())
+ show();
+
+ m_itemView->setCurrentIndex(newIdx);
+}
+
+// You are not expected to understand the following two functions.
+// The traversal order is described in the indexLessThan() comments above.
+
+static inline bool skipForward(const QAbstractItemModel *model, QModelIndex &parent, int &row, int &column)
+{
+ forever {
+ column++;
+ if (column < model->columnCount(parent))
+ return true;
+ forever {
+ while (--column >= 0) {
+ QModelIndex nIdx = model->index(row, column, parent);
+ if (nIdx.isValid()) {
+ if (model->hasChildren(nIdx)) {
+ row = 0;
+ column = 0;
+ parent = nIdx;
+ return true;
+ }
+ }
+ }
+ if (++row < model->rowCount(parent))
+ break;
+ if (!parent.isValid())
+ return false;
+ row = parent.row();
+ column = parent.column();
+ parent = parent.parent();
+ }
+ }
+}
+
+static inline bool skipBackward(const QAbstractItemModel *model, QModelIndex &parent, int &row, int &column)
+{
+ column--;
+ if (column == -1) {
+ if (--row < 0) {
+ if (!parent.isValid())
+ return false;
+ row = parent.row();
+ column = parent.column();
+ parent = parent.parent();
+ }
+ while (++column < model->columnCount(parent)) {
+ QModelIndex nIdx = model->index(row, column, parent);
+ if (nIdx.isValid()) {
+ if (model->hasChildren(nIdx)) {
+ row = model->rowCount(nIdx) - 1;
+ column = -1;
+ parent = nIdx;
+ }
+ }
+ }
+ column--;
+ }
+ return true;
+}
+
+// QAbstractItemModel::match() does not support backwards searching. Still using it would
+// be just a bit inefficient (not much worse than when no match is found).
+// The bigger problem is that QAbstractItemView does not provide a method to sort a
+// set of indices in traversal order (to find the start and end of the selection).
+// Consequently, we do everything by ourselves to be consistent. Of course, this puts
+// constraints on the allowable visualizations.
+QModelIndex ItemViewFindWidget::findHelper(const QString &textToFind, bool skipCurrent, bool backward,
+ QModelIndex parent, int row, int column)
+{
+ const QAbstractItemModel *model = m_itemView->model();
+ forever {
+ if (skipCurrent) {
+ if (backward) {
+ if (!skipBackward(model, parent, row, column))
+ return QModelIndex();
+ } else {
+ if (!skipForward(model, parent, row, column))
+ return QModelIndex();
+ }
+ }
+
+ QModelIndex idx = model->index(row, column, parent);
+ if (idx.isValid()) {
+ Qt::CaseSensitivity cs = caseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive;
+
+ if (wholeWords()) {
+ QString rx = QLatin1String("\\b") + QRegExp::escape(textToFind) + QLatin1String("\\b");
+ if (idx.data().toString().indexOf(QRegExp(rx, cs)) >= 0)
+ return idx;
+ } else {
+ if (idx.data().toString().indexOf(textToFind, 0, cs) >= 0)
+ return idx;
+ }
+ }
+
+ skipCurrent = true;
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/shared/findwidget/itemviewfindwidget.h b/src/shared/findwidget/itemviewfindwidget.h
new file mode 100644
index 000000000..c42804a5f
--- /dev/null
+++ b/src/shared/findwidget/itemviewfindwidget.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ITEMVIEWFINDWIDGET_H
+#define ITEMVIEWFINDWIDGET_H
+
+#include "abstractfindwidget.h"
+
+#include <QModelIndex>
+
+QT_BEGIN_NAMESPACE
+
+class QAbstractItemView;
+
+class ItemViewFindWidget : public AbstractFindWidget
+{
+ Q_OBJECT
+
+public:
+ explicit ItemViewFindWidget(FindFlags flags = FindFlags(), QWidget *parent = 0);
+
+ QAbstractItemView *itemView() const
+ { return m_itemView; }
+
+ void setItemView(QAbstractItemView *itemView);
+
+protected:
+ virtual void deactivate();
+ virtual void find(const QString &textToFind, bool skipCurrent, bool backward, bool *found, bool *wrapped);
+
+private:
+ QModelIndex findHelper(const QString &textToFind, bool skipCurrent, bool backward,
+ QModelIndex parent, int row, int column);
+
+ QAbstractItemView *m_itemView;
+};
+
+QT_END_NAMESPACE
+
+#endif // ITEMVIEWFINDWIDGET_H
diff --git a/src/shared/findwidget/texteditfindwidget.cpp b/src/shared/findwidget/texteditfindwidget.cpp
new file mode 100644
index 000000000..f02bdcc33
--- /dev/null
+++ b/src/shared/findwidget/texteditfindwidget.cpp
@@ -0,0 +1,169 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*! \class TextEditFindWidget
+
+ \brief A search bar that is commonly added below the searchable text.
+
+ \internal
+
+ This widget implements a search bar which becomes visible when the user
+ wants to start searching. It is a modern replacement for the commonly used
+ search dialog. It is usually placed below a QTextEdit using a QVBoxLayout.
+
+ The QTextEdit instance will need to be associated with this class using
+ setTextEdit().
+
+ The search is incremental and can be set to case sensitive or whole words
+ using buttons available on the search bar.
+
+ \sa QTextEdit
+ */
+
+#include "texteditfindwidget.h"
+
+#include <QtGui/QCheckBox>
+#include <QtGui/QTextCursor>
+#include <QtGui/QTextEdit>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ Constructs a TextEditFindWidget.
+
+ \a flags is passed to the AbstractFindWidget constructor.
+ \a parent is passed to the QWidget constructor.
+ */
+TextEditFindWidget::TextEditFindWidget(FindFlags flags, QWidget *parent)
+ : AbstractFindWidget(flags, parent)
+ , m_textEdit(0)
+{
+}
+
+/*!
+ Associates a QTextEdit with this find widget. Searches done using this find
+ widget will then apply to the given QTextEdit.
+
+ An event filter is set on the QTextEdit which intercepts the ESC key while
+ the find widget is active, and uses it to deactivate the find widget.
+
+ If the find widget is already associated with a QTextEdit, the event filter
+ is removed from this QTextEdit first.
+
+ \a textEdit may be NULL.
+ */
+void TextEditFindWidget::setTextEdit(QTextEdit *textEdit)
+{
+ if (m_textEdit)
+ m_textEdit->removeEventFilter(this);
+
+ m_textEdit = textEdit;
+
+ if (m_textEdit)
+ m_textEdit->installEventFilter(this);
+}
+
+/*!
+ \reimp
+ */
+void TextEditFindWidget::deactivate()
+{
+ // Pass focus to the text edit
+ if (m_textEdit)
+ m_textEdit->setFocus();
+
+ AbstractFindWidget::deactivate();
+}
+
+/*!
+ \reimp
+ */
+void TextEditFindWidget::find(const QString &ttf, bool skipCurrent, bool backward, bool *found, bool *wrapped)
+{
+ if (!m_textEdit)
+ return;
+
+ QTextCursor cursor = m_textEdit->textCursor();
+ QTextDocument *doc = m_textEdit->document();
+
+ if (!doc || cursor.isNull())
+ return;
+
+ if (cursor.hasSelection())
+ cursor.setPosition((skipCurrent && !backward) ? cursor.position() : cursor.anchor());
+
+ *found = true;
+ QTextCursor newCursor = cursor;
+
+ if (!ttf.isEmpty()) {
+ QTextDocument::FindFlags options;
+
+ if (backward)
+ options |= QTextDocument::FindBackward;
+
+ if (caseSensitive())
+ options |= QTextDocument::FindCaseSensitively;
+
+ if (wholeWords())
+ options |= QTextDocument::FindWholeWords;
+
+ newCursor = doc->find(ttf, cursor, options);
+ if (newCursor.isNull()) {
+ QTextCursor ac(doc);
+ ac.movePosition(options & QTextDocument::FindBackward
+ ? QTextCursor::End : QTextCursor::Start);
+ newCursor = doc->find(ttf, ac, options);
+ if (newCursor.isNull()) {
+ *found = false;
+ newCursor = cursor;
+ } else {
+ *wrapped = true;
+ }
+ }
+ }
+
+ if (!isVisible())
+ show();
+
+ m_textEdit->setTextCursor(newCursor);
+}
+
+QT_END_NAMESPACE
diff --git a/src/shared/findwidget/texteditfindwidget.h b/src/shared/findwidget/texteditfindwidget.h
new file mode 100644
index 000000000..5429acfb8
--- /dev/null
+++ b/src/shared/findwidget/texteditfindwidget.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TEXTEDITFINDWIDGET_H
+#define TEXTEDITFINDWIDGET_H
+
+#include "abstractfindwidget.h"
+
+QT_BEGIN_NAMESPACE
+
+class QTextEdit;
+
+class TextEditFindWidget : public AbstractFindWidget
+{
+ Q_OBJECT
+
+public:
+ explicit TextEditFindWidget(FindFlags flags = FindFlags(), QWidget *parent = 0);
+
+ QTextEdit *textEdit() const
+ { return m_textEdit; }
+
+ void setTextEdit(QTextEdit *textEdit);
+
+protected:
+ virtual void deactivate();
+ virtual void find(const QString &textToFind, bool skipCurrent, bool backward, bool *found, bool *wrapped);
+
+private:
+ QTextEdit *m_textEdit;
+};
+
+QT_END_NAMESPACE
+
+#endif // TEXTEDITFINDWIDGET_H
diff --git a/src/shared/fontpanel/fontpanel.cpp b/src/shared/fontpanel/fontpanel.cpp
new file mode 100644
index 000000000..9bcef2a4b
--- /dev/null
+++ b/src/shared/fontpanel/fontpanel.cpp
@@ -0,0 +1,308 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "fontpanel.h"
+
+#include <QtGui/QLabel>
+#include <QtGui/QComboBox>
+#include <QtGui/QFormLayout>
+#include <QtGui/QSpacerItem>
+#include <QtGui/QFontComboBox>
+#include <QtCore/QTimer>
+#include <QtGui/QLineEdit>
+
+QT_BEGIN_NAMESPACE
+
+FontPanel::FontPanel(QWidget *parentWidget) :
+ QGroupBox(parentWidget),
+ m_previewLineEdit(new QLineEdit),
+ m_writingSystemComboBox(new QComboBox),
+ m_familyComboBox(new QFontComboBox),
+ m_styleComboBox(new QComboBox),
+ m_pointSizeComboBox(new QComboBox),
+ m_previewFontUpdateTimer(0)
+{
+ setTitle(tr("Font"));
+
+ QFormLayout *formLayout = new QFormLayout(this);
+ // writing systems
+ m_writingSystemComboBox->setEditable(false);
+
+ QList<QFontDatabase::WritingSystem> writingSystems = m_fontDatabase.writingSystems();
+ writingSystems.push_front(QFontDatabase::Any);
+ foreach (QFontDatabase::WritingSystem ws, writingSystems)
+ m_writingSystemComboBox->addItem(QFontDatabase::writingSystemName(ws), QVariant(ws));
+ connect(m_writingSystemComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotWritingSystemChanged(int)));
+ formLayout->addRow(tr("&Writing system"), m_writingSystemComboBox);
+
+ connect(m_familyComboBox, SIGNAL(currentFontChanged(QFont)), this, SLOT(slotFamilyChanged(QFont)));
+ formLayout->addRow(tr("&Family"), m_familyComboBox);
+
+ m_styleComboBox->setEditable(false);
+ connect(m_styleComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotStyleChanged(int)));
+ formLayout->addRow(tr("&Style"), m_styleComboBox);
+
+ m_pointSizeComboBox->setEditable(false);
+ connect(m_pointSizeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotPointSizeChanged(int)));
+ formLayout->addRow(tr("&Point size"), m_pointSizeComboBox);
+
+ m_previewLineEdit->setReadOnly(true);
+ formLayout->addRow(m_previewLineEdit);
+
+ setWritingSystem(QFontDatabase::Any);
+}
+
+QFont FontPanel::selectedFont() const
+{
+ QFont rc = m_familyComboBox->currentFont();
+ const QString family = rc.family();
+ rc.setPointSize(pointSize());
+ const QString styleDescription = styleString();
+ if (styleDescription.contains(QLatin1String("Italic")))
+ rc.setStyle(QFont::StyleItalic);
+ else if (styleDescription.contains(QLatin1String("Oblique")))
+ rc.setStyle(QFont::StyleOblique);
+ else
+ rc.setStyle(QFont::StyleNormal);
+ rc.setBold(m_fontDatabase.bold(family, styleDescription));
+
+ // Weight < 0 asserts...
+ const int weight = m_fontDatabase.weight(family, styleDescription);
+ if (weight >= 0)
+ rc.setWeight(weight);
+ return rc;
+}
+
+void FontPanel::setSelectedFont(const QFont &f)
+{
+ m_familyComboBox->setCurrentFont(f);
+ if (m_familyComboBox->currentIndex() < 0) {
+ // family not in writing system - find the corresponding one?
+ QList<QFontDatabase::WritingSystem> familyWritingSystems = m_fontDatabase.writingSystems(f.family());
+ if (familyWritingSystems.empty())
+ return;
+
+ setWritingSystem(familyWritingSystems.front());
+ m_familyComboBox->setCurrentFont(f);
+ }
+
+ updateFamily(family());
+
+ const int pointSizeIndex = closestPointSizeIndex(f.pointSize());
+ m_pointSizeComboBox->setCurrentIndex( pointSizeIndex);
+
+ const QString styleString = m_fontDatabase.styleString(f);
+ const int styleIndex = m_styleComboBox->findText(styleString);
+ m_styleComboBox->setCurrentIndex(styleIndex);
+ slotUpdatePreviewFont();
+}
+
+
+QFontDatabase::WritingSystem FontPanel::writingSystem() const
+{
+ const int currentIndex = m_writingSystemComboBox->currentIndex();
+ if ( currentIndex == -1)
+ return QFontDatabase::Latin;
+ return static_cast<QFontDatabase::WritingSystem>(m_writingSystemComboBox->itemData(currentIndex).toInt());
+}
+
+QString FontPanel::family() const
+{
+ const int currentIndex = m_familyComboBox->currentIndex();
+ return currentIndex != -1 ? m_familyComboBox->currentFont().family() : QString();
+}
+
+int FontPanel::pointSize() const
+{
+ const int currentIndex = m_pointSizeComboBox->currentIndex();
+ return currentIndex != -1 ? m_pointSizeComboBox->itemData(currentIndex).toInt() : 9;
+}
+
+QString FontPanel::styleString() const
+{
+ const int currentIndex = m_styleComboBox->currentIndex();
+ return currentIndex != -1 ? m_styleComboBox->itemText(currentIndex) : QString();
+}
+
+void FontPanel::setWritingSystem(QFontDatabase::WritingSystem ws)
+{
+ m_writingSystemComboBox->setCurrentIndex(m_writingSystemComboBox->findData(QVariant(ws)));
+ updateWritingSystem(ws);
+}
+
+
+void FontPanel::slotWritingSystemChanged(int)
+{
+ updateWritingSystem(writingSystem());
+ delayedPreviewFontUpdate();
+}
+
+void FontPanel::slotFamilyChanged(const QFont &)
+{
+ updateFamily(family());
+ delayedPreviewFontUpdate();
+}
+
+void FontPanel::slotStyleChanged(int)
+{
+ updatePointSizes(family(), styleString());
+ delayedPreviewFontUpdate();
+}
+
+void FontPanel::slotPointSizeChanged(int)
+{
+ delayedPreviewFontUpdate();
+}
+
+void FontPanel::updateWritingSystem(QFontDatabase::WritingSystem ws)
+{
+
+ m_previewLineEdit->setText(QFontDatabase::writingSystemSample(ws));
+ m_familyComboBox->setWritingSystem (ws);
+ // Current font not in WS ... set index 0.
+ if (m_familyComboBox->currentIndex() < 0) {
+ m_familyComboBox->setCurrentIndex(0);
+ updateFamily(family());
+ }
+}
+
+void FontPanel::updateFamily(const QString &family)
+{
+ // Update styles and trigger update of point sizes.
+ // Try to maintain selection or select normal
+ const QString oldStyleString = styleString();
+
+ const QStringList styles = m_fontDatabase.styles(family);
+ const bool hasStyles = !styles.empty();
+
+ m_styleComboBox->setCurrentIndex(-1);
+ m_styleComboBox->clear();
+ m_styleComboBox->setEnabled(hasStyles);
+
+ int normalIndex = -1;
+ const QString normalStyle = QLatin1String("Normal");
+
+ if (hasStyles) {
+ foreach (const QString &style, styles) {
+ // try to maintain selection or select 'normal' preferably
+ const int newIndex = m_styleComboBox->count();
+ m_styleComboBox->addItem(style);
+ if (oldStyleString == style) {
+ m_styleComboBox->setCurrentIndex(newIndex);
+ } else {
+ if (oldStyleString == normalStyle)
+ normalIndex = newIndex;
+ }
+ }
+ if (m_styleComboBox->currentIndex() == -1 && normalIndex != -1)
+ m_styleComboBox->setCurrentIndex(normalIndex);
+ }
+ updatePointSizes(family, styleString());
+}
+
+int FontPanel::closestPointSizeIndex(int desiredPointSize) const
+{
+ // try to maintain selection or select closest.
+ int closestIndex = -1;
+ int closestAbsError = 0xFFFF;
+
+ const int pointSizeCount = m_pointSizeComboBox->count();
+ for (int i = 0; i < pointSizeCount; i++) {
+ const int itemPointSize = m_pointSizeComboBox->itemData(i).toInt();
+ const int absError = qAbs(desiredPointSize - itemPointSize);
+ if (absError < closestAbsError) {
+ closestIndex = i;
+ closestAbsError = absError;
+ if (closestAbsError == 0)
+ break;
+ } else { // past optimum
+ if (absError > closestAbsError) {
+ break;
+ }
+ }
+ }
+ return closestIndex;
+}
+
+
+void FontPanel::updatePointSizes(const QString &family, const QString &styleString)
+{
+ const int oldPointSize = pointSize();
+
+ QList<int> pointSizes = m_fontDatabase.pointSizes(family, styleString);
+ if (pointSizes.empty())
+ pointSizes = QFontDatabase::standardSizes();
+
+ const bool hasSizes = !pointSizes.empty();
+ m_pointSizeComboBox->clear();
+ m_pointSizeComboBox->setEnabled(hasSizes);
+ m_pointSizeComboBox->setCurrentIndex(-1);
+
+ // try to maintain selection or select closest.
+ if (hasSizes) {
+ QString n;
+ foreach (int pointSize, pointSizes)
+ m_pointSizeComboBox->addItem(n.setNum(pointSize), QVariant(pointSize));
+ const int closestIndex = closestPointSizeIndex(oldPointSize);
+ if (closestIndex != -1)
+ m_pointSizeComboBox->setCurrentIndex(closestIndex);
+ }
+}
+
+void FontPanel::slotUpdatePreviewFont()
+{
+ m_previewLineEdit->setFont(selectedFont());
+}
+
+void FontPanel::delayedPreviewFontUpdate()
+{
+ if (!m_previewFontUpdateTimer) {
+ m_previewFontUpdateTimer = new QTimer(this);
+ connect(m_previewFontUpdateTimer, SIGNAL(timeout()), this, SLOT(slotUpdatePreviewFont()));
+ m_previewFontUpdateTimer->setInterval(0);
+ m_previewFontUpdateTimer->setSingleShot(true);
+ }
+ if (m_previewFontUpdateTimer->isActive())
+ return;
+ m_previewFontUpdateTimer->start();
+}
+
+QT_END_NAMESPACE
diff --git a/src/shared/fontpanel/fontpanel.h b/src/shared/fontpanel/fontpanel.h
new file mode 100644
index 000000000..204ff7d4a
--- /dev/null
+++ b/src/shared/fontpanel/fontpanel.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the Qt tools. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef FONTPANEL_H
+#define FONTPANEL_H
+
+#include <QtGui/QGroupBox>
+#include <QtGui/QFont>
+#include <QtGui/QFontDatabase>
+
+QT_BEGIN_NAMESPACE
+
+class QComboBox;
+class QFontComboBox;
+class QTimer;
+class QLineEdit;
+
+class FontPanel: public QGroupBox
+{
+ Q_OBJECT
+public:
+ FontPanel(QWidget *parentWidget = 0);
+
+ QFont selectedFont() const;
+ void setSelectedFont(const QFont &);
+
+ QFontDatabase::WritingSystem writingSystem() const;
+ void setWritingSystem(QFontDatabase::WritingSystem ws);
+
+private slots:
+ void slotWritingSystemChanged(int);
+ void slotFamilyChanged(const QFont &);
+ void slotStyleChanged(int);
+ void slotPointSizeChanged(int);
+ void slotUpdatePreviewFont();
+
+private:
+ QString family() const;
+ QString styleString() const;
+ int pointSize() const;
+ int closestPointSizeIndex(int ps) const;
+
+ void updateWritingSystem(QFontDatabase::WritingSystem ws);
+ void updateFamily(const QString &family);
+ void updatePointSizes(const QString &family, const QString &style);
+ void delayedPreviewFontUpdate();
+
+ QFontDatabase m_fontDatabase;
+ QLineEdit *m_previewLineEdit;
+ QComboBox *m_writingSystemComboBox;
+ QFontComboBox* m_familyComboBox;
+ QComboBox *m_styleComboBox;
+ QComboBox *m_pointSizeComboBox;
+ QTimer *m_previewFontUpdateTimer;
+};
+
+QT_END_NAMESPACE
+
+#endif // FONTPANEL_H
diff --git a/src/shared/fontpanel/fontpanel.pri b/src/shared/fontpanel/fontpanel.pri
new file mode 100644
index 000000000..9504853a7
--- /dev/null
+++ b/src/shared/fontpanel/fontpanel.pri
@@ -0,0 +1,3 @@
+INCLUDEPATH += $$PWD
+HEADERS += $$PWD/fontpanel.h
+SOURCES += $$PWD/fontpanel.cpp
diff --git a/src/shared/qtgradienteditor/images/down.png b/src/shared/qtgradienteditor/images/down.png
new file mode 100644
index 000000000..29d1d4439
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/down.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/edit.png b/src/shared/qtgradienteditor/images/edit.png
new file mode 100644
index 000000000..4231bd9a9
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/edit.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/editdelete.png b/src/shared/qtgradienteditor/images/editdelete.png
new file mode 100644
index 000000000..df2a147d2
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/editdelete.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/minus.png b/src/shared/qtgradienteditor/images/minus.png
new file mode 100644
index 000000000..d6f233d73
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/minus.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/plus.png b/src/shared/qtgradienteditor/images/plus.png
new file mode 100644
index 000000000..40df1134f
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/plus.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/spreadpad.png b/src/shared/qtgradienteditor/images/spreadpad.png
new file mode 100644
index 000000000..104c0a23d
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/spreadpad.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/spreadreflect.png b/src/shared/qtgradienteditor/images/spreadreflect.png
new file mode 100644
index 000000000..17b82b711
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/spreadreflect.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/spreadrepeat.png b/src/shared/qtgradienteditor/images/spreadrepeat.png
new file mode 100644
index 000000000..7aea898b1
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/spreadrepeat.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/typeconical.png b/src/shared/qtgradienteditor/images/typeconical.png
new file mode 100644
index 000000000..5479811df
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/typeconical.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/typelinear.png b/src/shared/qtgradienteditor/images/typelinear.png
new file mode 100644
index 000000000..dbd8a1f5a
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/typelinear.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/typeradial.png b/src/shared/qtgradienteditor/images/typeradial.png
new file mode 100644
index 000000000..dc5888dca
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/typeradial.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/up.png b/src/shared/qtgradienteditor/images/up.png
new file mode 100644
index 000000000..e43731221
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/up.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/zoomin.png b/src/shared/qtgradienteditor/images/zoomin.png
new file mode 100644
index 000000000..2e586fc7b
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/zoomin.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/images/zoomout.png b/src/shared/qtgradienteditor/images/zoomout.png
new file mode 100644
index 000000000..a736d3934
--- /dev/null
+++ b/src/shared/qtgradienteditor/images/zoomout.png
Binary files differ
diff --git a/src/shared/qtgradienteditor/qtcolorbutton.cpp b/src/shared/qtgradienteditor/qtcolorbutton.cpp
new file mode 100644
index 000000000..96a8b26ca
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtcolorbutton.cpp
@@ -0,0 +1,272 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtcolorbutton.h"
+#include <QtGui/QColorDialog>
+#include <QtGui/QPainter>
+#include <QtCore/QMimeData>
+#include <QtGui/QDragEnterEvent>
+#include <QtGui/QApplication>
+
+QT_BEGIN_NAMESPACE
+
+class QtColorButtonPrivate
+{
+ QtColorButton *q_ptr;
+ Q_DECLARE_PUBLIC(QtColorButton)
+public:
+ QColor m_color;
+#ifndef QT_NO_DRAGANDDROP
+ QColor m_dragColor;
+ QPoint m_dragStart;
+ bool m_dragging;
+#endif
+ bool m_backgroundCheckered;
+
+ void slotEditColor();
+ QColor shownColor() const;
+ QPixmap generatePixmap() const;
+};
+
+void QtColorButtonPrivate::slotEditColor()
+{
+ const QColor newColor = QColorDialog::getColor(m_color, q_ptr, QString(), QColorDialog::ShowAlphaChannel);
+ if (!newColor.isValid() || newColor == q_ptr->color())
+ return;
+ q_ptr->setColor(newColor);
+ emit q_ptr->colorChanged(m_color);
+}
+
+QColor QtColorButtonPrivate::shownColor() const
+{
+#ifndef QT_NO_DRAGANDDROP
+ if (m_dragging)
+ return m_dragColor;
+#endif
+ return m_color;
+}
+
+QPixmap QtColorButtonPrivate::generatePixmap() const
+{
+ QPixmap pix(24, 24);
+
+ int pixSize = 20;
+ QBrush br(shownColor());
+
+ QPixmap pm(2 * pixSize, 2 * pixSize);
+ QPainter pmp(&pm);
+ pmp.fillRect(0, 0, pixSize, pixSize, Qt::lightGray);
+ pmp.fillRect(pixSize, pixSize, pixSize, pixSize, Qt::lightGray);
+ pmp.fillRect(0, pixSize, pixSize, pixSize, Qt::darkGray);
+ pmp.fillRect(pixSize, 0, pixSize, pixSize, Qt::darkGray);
+ pmp.fillRect(0, 0, 2 * pixSize, 2 * pixSize, shownColor());
+ br = QBrush(pm);
+
+ QPainter p(&pix);
+ int corr = 1;
+ QRect r = pix.rect().adjusted(corr, corr, -corr, -corr);
+ p.setBrushOrigin((r.width() % pixSize + pixSize) / 2 + corr, (r.height() % pixSize + pixSize) / 2 + corr);
+ p.fillRect(r, br);
+
+ p.fillRect(r.width() / 4 + corr, r.height() / 4 + corr,
+ r.width() / 2, r.height() / 2,
+ QColor(shownColor().rgb()));
+ p.drawRect(pix.rect().adjusted(0, 0, -1, -1));
+
+ return pix;
+}
+
+///////////////
+
+QtColorButton::QtColorButton(QWidget *parent)
+ : QToolButton(parent), d_ptr(new QtColorButtonPrivate)
+{
+ d_ptr->q_ptr = this;
+ d_ptr->m_dragging = false;
+ d_ptr->m_backgroundCheckered = true;
+
+ setAcceptDrops(true);
+
+ connect(this, SIGNAL(clicked()), this, SLOT(slotEditColor()));
+ setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred));
+}
+
+QtColorButton::~QtColorButton()
+{
+}
+
+void QtColorButton::setColor(const QColor &color)
+{
+ if (d_ptr->m_color == color)
+ return;
+ d_ptr->m_color = color;
+ update();
+}
+
+QColor QtColorButton::color() const
+{
+ return d_ptr->m_color;
+}
+
+void QtColorButton::setBackgroundCheckered(bool checkered)
+{
+ if (d_ptr->m_backgroundCheckered == checkered)
+ return;
+ d_ptr->m_backgroundCheckered = checkered;
+ update();
+}
+
+bool QtColorButton::isBackgroundCheckered() const
+{
+ return d_ptr->m_backgroundCheckered;
+}
+
+void QtColorButton::paintEvent(QPaintEvent *event)
+{
+ QToolButton::paintEvent(event);
+ if (!isEnabled())
+ return;
+
+ const int pixSize = 10;
+ QBrush br(d_ptr->shownColor());
+ if (d_ptr->m_backgroundCheckered) {
+ QPixmap pm(2 * pixSize, 2 * pixSize);
+ QPainter pmp(&pm);
+ pmp.fillRect(0, 0, pixSize, pixSize, Qt::white);
+ pmp.fillRect(pixSize, pixSize, pixSize, pixSize, Qt::white);
+ pmp.fillRect(0, pixSize, pixSize, pixSize, Qt::black);
+ pmp.fillRect(pixSize, 0, pixSize, pixSize, Qt::black);
+ pmp.fillRect(0, 0, 2 * pixSize, 2 * pixSize, d_ptr->shownColor());
+ br = QBrush(pm);
+ }
+
+ QPainter p(this);
+ const int corr = 4;
+ QRect r = rect().adjusted(corr, corr, -corr, -corr);
+ p.setBrushOrigin((r.width() % pixSize + pixSize) / 2 + corr, (r.height() % pixSize + pixSize) / 2 + corr);
+ p.fillRect(r, br);
+
+ //const int adjX = qRound(r.width() / 4.0);
+ //const int adjY = qRound(r.height() / 4.0);
+ //p.fillRect(r.adjusted(adjX, adjY, -adjX, -adjY),
+ // QColor(d_ptr->shownColor().rgb()));
+ /*
+ p.fillRect(r.adjusted(0, r.height() * 3 / 4, 0, 0),
+ QColor(d_ptr->shownColor().rgb()));
+ p.fillRect(r.adjusted(0, 0, 0, -r.height() * 3 / 4),
+ QColor(d_ptr->shownColor().rgb()));
+ */
+ /*
+ const QColor frameColor0(0, 0, 0, qRound(0.2 * (0xFF - d_ptr->shownColor().alpha())));
+ p.setPen(frameColor0);
+ p.drawRect(r.adjusted(adjX, adjY, -adjX - 1, -adjY - 1));
+ */
+
+ const QColor frameColor1(0, 0, 0, 26);
+ p.setPen(frameColor1);
+ p.drawRect(r.adjusted(1, 1, -2, -2));
+ const QColor frameColor2(0, 0, 0, 51);
+ p.setPen(frameColor2);
+ p.drawRect(r.adjusted(0, 0, -1, -1));
+}
+
+void QtColorButton::mousePressEvent(QMouseEvent *event)
+{
+#ifndef QT_NO_DRAGANDDROP
+ if (event->button() == Qt::LeftButton)
+ d_ptr->m_dragStart = event->pos();
+#endif
+ QToolButton::mousePressEvent(event);
+}
+
+void QtColorButton::mouseMoveEvent(QMouseEvent *event)
+{
+#ifndef QT_NO_DRAGANDDROP
+ if (event->buttons() & Qt::LeftButton &&
+ (d_ptr->m_dragStart - event->pos()).manhattanLength() > QApplication::startDragDistance()) {
+ QMimeData *mime = new QMimeData;
+ mime->setColorData(color());
+ QDrag *drg = new QDrag(this);
+ drg->setMimeData(mime);
+ drg->setPixmap(d_ptr->generatePixmap());
+ setDown(false);
+ event->accept();
+ drg->start();
+ return;
+ }
+#endif
+ QToolButton::mouseMoveEvent(event);
+}
+
+#ifndef QT_NO_DRAGANDDROP
+void QtColorButton::dragEnterEvent(QDragEnterEvent *event)
+{
+ const QMimeData *mime = event->mimeData();
+ if (!mime->hasColor())
+ return;
+
+ event->accept();
+ d_ptr->m_dragColor = qvariant_cast<QColor>(mime->colorData());
+ d_ptr->m_dragging = true;
+ update();
+}
+
+void QtColorButton::dragLeaveEvent(QDragLeaveEvent *event)
+{
+ event->accept();
+ d_ptr->m_dragging = false;
+ update();
+}
+
+void QtColorButton::dropEvent(QDropEvent *event)
+{
+ event->accept();
+ d_ptr->m_dragging = false;
+ if (d_ptr->m_dragColor == color())
+ return;
+ setColor(d_ptr->m_dragColor);
+ emit colorChanged(color());
+}
+#endif
+
+QT_END_NAMESPACE
+
+#include "moc_qtcolorbutton.cpp"
diff --git a/src/shared/qtgradienteditor/qtcolorbutton.h b/src/shared/qtgradienteditor/qtcolorbutton.h
new file mode 100644
index 000000000..42fcfc113
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtcolorbutton.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTCOLORBUTTON_H
+#define QTCOLORBUTTON_H
+
+#include <QtGui/QToolButton>
+
+QT_BEGIN_NAMESPACE
+
+class QtColorButton : public QToolButton
+{
+ Q_OBJECT
+ Q_PROPERTY(bool backgroundCheckered READ isBackgroundCheckered WRITE setBackgroundCheckered)
+public:
+ QtColorButton(QWidget *parent = 0);
+ ~QtColorButton();
+
+ bool isBackgroundCheckered() const;
+ void setBackgroundCheckered(bool checkered);
+
+ QColor color() const;
+
+public slots:
+
+ void setColor(const QColor &color);
+
+signals:
+ void colorChanged(const QColor &color);
+protected:
+ void paintEvent(QPaintEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+#ifndef QT_NO_DRAGANDDROP
+ void dragEnterEvent(QDragEnterEvent *event);
+ void dragLeaveEvent(QDragLeaveEvent *event);
+ void dropEvent(QDropEvent *event);
+#endif
+private:
+ QScopedPointer<class QtColorButtonPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtColorButton)
+ Q_DISABLE_COPY(QtColorButton)
+ Q_PRIVATE_SLOT(d_func(), void slotEditColor())
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtgradienteditor/qtcolorbutton.pri b/src/shared/qtgradienteditor/qtcolorbutton.pri
new file mode 100644
index 000000000..0e41068f8
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtcolorbutton.pri
@@ -0,0 +1,4 @@
+INCLUDEPATH += $$PWD
+DEPENDPATH += $$PWD
+SOURCES += $$PWD/qtcolorbutton.cpp
+HEADERS += $$PWD/qtcolorbutton.h
diff --git a/src/shared/qtgradienteditor/qtcolorline.cpp b/src/shared/qtgradienteditor/qtcolorline.cpp
new file mode 100644
index 000000000..f4eda3f9b
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtcolorline.cpp
@@ -0,0 +1,1122 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtcolorline.h"
+#include "qdrawutil.h"
+
+#include <QtGui/QPainter>
+#include <QtGui/QPaintEvent>
+#include <QtGui/QStyleOption>
+
+QT_BEGIN_NAMESPACE
+
+class QtColorLinePrivate
+{
+ QtColorLine *q_ptr;
+ Q_DECLARE_PUBLIC(QtColorLine)
+public:
+ QtColorLinePrivate();
+
+ QColor color() const;
+ void setColor(const QColor &color);
+
+ QtColorLine::ColorComponent colorComponent() const;
+ void setColorComponent(QtColorLine::ColorComponent component);
+
+ void setIndicatorSize(int size);
+ int indicatorSize() const;
+
+ void setIndicatorSpace(int space);
+ int indicatorSpace() const;
+
+ void setFlip(bool flip);
+ bool flip() const;
+
+ void setBackgroundCheckered(bool checkered);
+ bool isBackgroundCheckered() const;
+
+ void setOrientation(Qt::Orientation orientation);
+ Qt::Orientation orientation() const;
+
+ void resizeEvent(QResizeEvent *event);
+ void paintEvent(QPaintEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
+ void mouseDoubleClickEvent(QMouseEvent *event);
+private:
+ void checkColor();
+ bool isMainPixmapValid() const;
+ void validate();
+ void recreateMainPixmap();
+ QSize pixmapSizeFromGeometrySize(const QSize &geometrySize) const;
+ QPixmap gradientPixmap(int size, Qt::Orientation orientation, const QColor &begin, const QColor &end, bool flipped = false) const;
+ QPixmap gradientPixmap(Qt::Orientation orientation, const QColor &begin, const QColor &end, bool flipped = false) const;
+ QPixmap hueGradientPixmap(int size, Qt::Orientation orientation, bool flipped = false,
+ int saturation = 0xFF, int value = 0xFF, int alpha = 0xFF) const;
+ QPixmap hueGradientPixmap(Qt::Orientation orientation, bool flipped = false,
+ int saturation = 0xFF, int value = 0xFF, int alpha = 0xFF) const;
+
+ QVector<QRect> rects(const QPointF &point) const;
+
+ QColor colorFromPoint(const QPointF &point) const;
+ QPointF pointFromColor(const QColor &color) const;
+
+ QColor m_color;
+ QtColorLine::ColorComponent m_component;
+ bool m_flipped;
+ bool m_backgroundCheckered;
+ Qt::Orientation m_orientation;
+ bool m_dragging;
+ bool m_combiningAlpha;
+ int m_indicatorSize;
+ int m_indicatorSpace;
+ QPointF m_point;
+ QPoint m_clickOffset;
+
+ QPixmap m_mainPixmap;
+ QPixmap m_alphalessPixmap;
+ QPixmap m_semiAlphaPixmap;
+ QSize m_pixmapSize;
+
+ struct PixData {
+ QSize size;
+ QColor color;
+ QtColorLine::ColorComponent component;
+ bool flipped;
+ Qt::Orientation orientation;
+ };
+
+ PixData m_lastValidMainPixmapData;
+};
+
+QtColorLinePrivate::QtColorLinePrivate()
+ : m_color(Qt::black), m_component(QtColorLine::Value),
+ m_flipped(false), m_backgroundCheckered(true), m_orientation(Qt::Horizontal), m_dragging(false), m_combiningAlpha(false)
+{
+ m_indicatorSize = 22;
+ m_indicatorSpace = 0;
+ m_pixmapSize = QSize(0, 0);
+ m_point = pointFromColor(m_color);
+}
+
+void QtColorLinePrivate::setColor(const QColor &color)
+{
+ if (m_color == color)
+ return;
+ if (!color.isValid())
+ return;
+ if (m_dragging) // Warning perhaps here, recursive call
+ return;
+ m_color = color;
+ checkColor();
+ QColor c = colorFromPoint(m_point);
+ m_point = pointFromColor(m_color);
+ q_ptr->update();
+}
+
+QColor QtColorLinePrivate::color() const
+{
+ return m_color;
+}
+
+void QtColorLinePrivate::setColorComponent(QtColorLine::ColorComponent component)
+{
+ if (m_component == component)
+ return;
+ if (m_dragging) // Warning perhaps here, recursive call
+ return;
+ m_component = component;
+ checkColor();
+ m_point = pointFromColor(m_color);
+ q_ptr->update();
+}
+
+QtColorLine::ColorComponent QtColorLinePrivate::colorComponent() const
+{
+ return m_component;
+}
+
+void QtColorLinePrivate::setIndicatorSize(int size)
+{
+ if (size <= 0)
+ return;
+ if (m_dragging) // Warning perhaps here, recursive call
+ return;
+ if (m_indicatorSize == size)
+ return;
+ m_indicatorSize = size;
+ m_pixmapSize = pixmapSizeFromGeometrySize(q_ptr->contentsRect().size());
+ q_ptr->update();
+ q_ptr->updateGeometry();
+}
+
+int QtColorLinePrivate::indicatorSize() const
+{
+ return m_indicatorSize;
+}
+
+void QtColorLinePrivate::setIndicatorSpace(int space)
+{
+ if (space < 0)
+ return;
+ if (m_dragging) // Warning perhaps here, recursive call
+ return;
+ if (m_indicatorSpace == space)
+ return;
+ m_indicatorSpace = space;
+ m_pixmapSize = pixmapSizeFromGeometrySize(q_ptr->contentsRect().size());
+ q_ptr->update();
+}
+
+int QtColorLinePrivate::indicatorSpace() const
+{
+ return m_indicatorSpace;
+}
+
+void QtColorLinePrivate::setFlip(bool flip)
+{
+ if (m_dragging) // Warning perhaps here, recursive call
+ return;
+ if (m_flipped == flip)
+ return;
+ m_flipped = flip;
+ m_point = pointFromColor(m_color);
+ q_ptr->update();
+}
+
+bool QtColorLinePrivate::flip() const
+{
+ return m_flipped;
+}
+
+void QtColorLinePrivate::setBackgroundCheckered(bool checkered)
+{
+ if (m_backgroundCheckered == checkered)
+ return;
+ m_backgroundCheckered = checkered;
+ q_ptr->update();
+}
+
+bool QtColorLinePrivate::isBackgroundCheckered() const
+{
+ return m_backgroundCheckered;
+}
+
+void QtColorLinePrivate::setOrientation(Qt::Orientation orientation)
+{
+ if (m_dragging) // Warning perhaps here, recursive call
+ return;
+ if (m_orientation == orientation)
+ return;
+
+ m_orientation = orientation;
+ if (!q_ptr->testAttribute(Qt::WA_WState_OwnSizePolicy)) {
+ QSizePolicy sp = q_ptr->sizePolicy();
+ sp.transpose();
+ q_ptr->setSizePolicy(sp);
+ q_ptr->setAttribute(Qt::WA_WState_OwnSizePolicy, false);
+ }
+ m_point = pointFromColor(m_color);
+ q_ptr->update();
+ q_ptr->updateGeometry();
+}
+
+Qt::Orientation QtColorLinePrivate::orientation() const
+{
+ return m_orientation;
+}
+
+void QtColorLinePrivate::checkColor()
+{
+ switch (m_component) {
+ case QtColorLine::Red:
+ case QtColorLine::Green:
+ case QtColorLine::Blue:
+ if (m_color.spec() != QColor::Rgb)
+ m_color = m_color.toRgb();
+ break;
+ case QtColorLine::Hue:
+ case QtColorLine::Saturation:
+ case QtColorLine::Value:
+ if (m_color.spec() != QColor::Hsv)
+ m_color = m_color.toHsv();
+ break;
+ default:
+ break;
+ }
+ if (m_color.spec() == QColor::Hsv) {
+ if (m_color.hue() == 360 || m_color.hue() == -1) {
+ m_color.setHsvF(0.0, m_color.saturationF(), m_color.valueF(), m_color.alphaF());
+ }
+ }
+}
+
+bool QtColorLinePrivate::isMainPixmapValid() const
+{
+ if (m_mainPixmap.isNull()) {
+ if (m_pixmapSize.isEmpty())
+ return true;
+ else
+ return false;
+ }
+ if (m_lastValidMainPixmapData.component != m_component)
+ return false;
+ if (m_lastValidMainPixmapData.size != m_pixmapSize)
+ return false;
+ if (m_lastValidMainPixmapData.flipped != m_flipped)
+ return false;
+ if (m_lastValidMainPixmapData.orientation != m_orientation)
+ return false;
+ if (m_lastValidMainPixmapData.color == m_color)
+ return true;
+ switch (m_component) {
+ case QtColorLine::Red:
+ if (m_color.green() == m_lastValidMainPixmapData.color.green() &&
+ m_color.blue() == m_lastValidMainPixmapData.color.blue() &&
+ (!m_combiningAlpha || m_color.alpha() == m_lastValidMainPixmapData.color.alpha()))
+ return true;
+ break;
+ case QtColorLine::Green:
+ if (m_color.red() == m_lastValidMainPixmapData.color.red() &&
+ m_color.blue() == m_lastValidMainPixmapData.color.blue() &&
+ (!m_combiningAlpha || m_color.alpha() == m_lastValidMainPixmapData.color.alpha()))
+ return true;
+ break;
+ case QtColorLine::Blue:
+ if (m_color.red() == m_lastValidMainPixmapData.color.red() &&
+ m_color.green() == m_lastValidMainPixmapData.color.green() &&
+ (!m_combiningAlpha || m_color.alpha() == m_lastValidMainPixmapData.color.alpha()))
+ return true;
+ break;
+ case QtColorLine::Hue:
+ if (m_color.saturation() == m_lastValidMainPixmapData.color.saturation() &&
+ m_color.value() == m_lastValidMainPixmapData.color.value() &&
+ (!m_combiningAlpha || m_color.alpha() == m_lastValidMainPixmapData.color.alpha()))
+ return true;
+ break;
+ case QtColorLine::Saturation:
+ if (m_color.hue() == m_lastValidMainPixmapData.color.hue() &&
+ m_color.value() == m_lastValidMainPixmapData.color.value() &&
+ (!m_combiningAlpha || m_color.alpha() == m_lastValidMainPixmapData.color.alpha()))
+ return true;
+ break;
+ case QtColorLine::Value:
+ if (m_color.hue() == m_lastValidMainPixmapData.color.hue() &&
+ m_color.saturation() == m_lastValidMainPixmapData.color.saturation() &&
+ (!m_combiningAlpha || m_color.alpha() == m_lastValidMainPixmapData.color.alpha()))
+ return true;
+ break;
+ case QtColorLine::Alpha:
+ if (m_color.hue() == m_lastValidMainPixmapData.color.hue() &&
+ m_color.saturation() == m_lastValidMainPixmapData.color.saturation() &&
+ m_color.value() == m_lastValidMainPixmapData.color.value())
+ return true;
+ }
+ return false;
+}
+
+void QtColorLinePrivate::validate()
+{
+ if (isMainPixmapValid())
+ return;
+
+ recreateMainPixmap();
+}
+
+QPixmap QtColorLinePrivate::gradientPixmap(Qt::Orientation orientation, const QColor &begin, const QColor &end, bool flipped) const
+{
+ int size = m_pixmapSize.width();
+ if (orientation == Qt::Vertical)
+ size = m_pixmapSize.height();
+ return gradientPixmap(size, orientation, begin, end, flipped);
+}
+
+QPixmap QtColorLinePrivate::gradientPixmap(int size, Qt::Orientation orientation,
+ const QColor &begin, const QColor &end, bool flipped) const
+{
+ int gradW = size;
+ int gradH = size;
+ int w = size;
+ int h = size;
+ if (orientation == Qt::Horizontal) {
+ gradH = 0;
+ h = 1;
+ } else {
+ gradW = 0;
+ w = 1;
+ }
+ QColor c1 = begin;
+ QColor c2 = end;
+ if (flipped) {
+ c1 = end;
+ c2 = begin;
+ }
+ QLinearGradient lg(0, 0, gradW, gradH);
+ lg.setColorAt(0, c1);
+ lg.setColorAt(1, c2);
+ QImage img(w, h, QImage::Format_ARGB32);
+ QPainter p(&img);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ p.fillRect(QRect(0, 0, w, h), lg);
+ return QPixmap::fromImage(img);
+}
+
+QPixmap QtColorLinePrivate::hueGradientPixmap(Qt::Orientation orientation, bool flipped,
+ int saturation, int value, int alpha) const
+{
+ int size = m_pixmapSize.width();
+ if (orientation == Qt::Vertical)
+ size = m_pixmapSize.height();
+ return hueGradientPixmap(size, orientation, flipped, saturation, value, alpha);
+}
+
+QPixmap QtColorLinePrivate::hueGradientPixmap(int size, Qt::Orientation orientation, bool flipped,
+ int saturation, int value, int alpha) const
+{
+ int gradW = size + 1;
+ int gradH = size + 1;
+ int w = size;
+ int h = size;
+ if (orientation == Qt::Horizontal) {
+ gradH = 0;
+ h = 1;
+ } else {
+ gradW = 0;
+ w = 1;
+ }
+ QList<QColor> colorList;
+ colorList << QColor::fromHsv(0, saturation, value, alpha);
+ colorList << QColor::fromHsv(60, saturation, value, alpha);
+ colorList << QColor::fromHsv(120, saturation, value, alpha);
+ colorList << QColor::fromHsv(180, saturation, value, alpha);
+ colorList << QColor::fromHsv(240, saturation, value, alpha);
+ colorList << QColor::fromHsv(300, saturation, value, alpha);
+ colorList << QColor::fromHsv(0, saturation, value, alpha);
+ QLinearGradient lg(0, 0, gradW, gradH);
+ for (int i = 0; i <= 6; i++)
+ lg.setColorAt((double)i / 6.0, flipped ? colorList.at(6 - i) : colorList.at(i));
+ QImage img(w, h, QImage::Format_ARGB32);
+ QPainter p(&img);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ p.fillRect(QRect(0, 0, w, h), lg);
+ return QPixmap::fromImage(img);
+}
+
+void QtColorLinePrivate::recreateMainPixmap()
+{
+ m_lastValidMainPixmapData.size = m_pixmapSize;
+ m_lastValidMainPixmapData.component = m_component;
+ m_lastValidMainPixmapData.color = m_color;
+ m_lastValidMainPixmapData.flipped = m_flipped;
+ m_lastValidMainPixmapData.orientation = m_orientation;
+
+ if (m_pixmapSize.isEmpty()) {
+ m_mainPixmap = QPixmap();
+ m_alphalessPixmap = QPixmap();
+ m_semiAlphaPixmap = QPixmap();
+ return;
+ }
+
+ if (m_mainPixmap.size() != m_pixmapSize) {
+ m_mainPixmap = QPixmap(m_pixmapSize);
+ m_alphalessPixmap = QPixmap(m_pixmapSize);
+ m_semiAlphaPixmap = QPixmap(m_pixmapSize);
+ }
+
+ Qt::Orientation orient = m_orientation;
+ const bool flip = m_flipped;
+
+ const int r = m_color.red();
+ const int g = m_color.green();
+ const int b = m_color.blue();
+ const int h = m_color.hue();
+ const int s = m_color.saturation();
+ const int v = m_color.value();
+ const int a = m_color.alpha();
+ const double coef = 0.5;
+ const int semi = qRound(a * coef + 0xFF * (1.0 - coef));
+
+ if (m_component == QtColorLine::Hue) {
+ m_alphalessPixmap = hueGradientPixmap(orient, flip, s, v, 0xFF);
+ if (m_combiningAlpha) {
+ m_mainPixmap = hueGradientPixmap(orient, flip, s, v, a);
+ m_semiAlphaPixmap = hueGradientPixmap(orient, flip, s, v, semi);
+ }
+ } else if (m_component == QtColorLine::Saturation) {
+ m_alphalessPixmap = gradientPixmap(orient, QColor::fromHsv(h, 0, v, 0xFF), QColor::fromHsv(h, 0xFF, v, 0xFF), flip);
+ if (m_combiningAlpha) {
+ m_mainPixmap = gradientPixmap(orient, QColor::fromHsv(h, 0, v, a), QColor::fromHsv(h, 0xFF, v, a), flip);
+ m_semiAlphaPixmap = gradientPixmap(orient, QColor::fromHsv(h, 0, v, semi), QColor::fromHsv(h, 0xFF, v, semi), flip);
+ }
+ } else if (m_component == QtColorLine::Value) {
+ m_alphalessPixmap = gradientPixmap(orient, QColor::fromRgb(0, 0, 0, 0xFF), QColor::fromHsv(h, s, 0xFF, 0xFF), flip);
+ if (m_combiningAlpha) {
+ m_mainPixmap = gradientPixmap(orient, QColor::fromRgb(0, 0, 0, a), QColor::fromHsv(h, s, 0xFF, a), flip);
+ m_semiAlphaPixmap = gradientPixmap(orient, QColor::fromRgb(0, 0, 0, semi), QColor::fromHsv(h, s, 0xFF, semi), flip);
+ }
+ } else if (m_component == QtColorLine::Red) {
+ m_alphalessPixmap = gradientPixmap(orient, QColor::fromRgb(0, g, b, 0xFF), QColor::fromRgb(0xFF, g, b, 0xFF), flip);
+ if (m_combiningAlpha) {
+ m_mainPixmap = gradientPixmap(orient, QColor::fromRgb(0, g, b, a), QColor::fromRgb(0xFF, g, b, a), flip);
+ m_semiAlphaPixmap = gradientPixmap(orient, QColor::fromRgb(0, g, b, semi), QColor::fromRgb(0xFF, g, b, semi), flip);
+ }
+ } else if (m_component == QtColorLine::Green) {
+ m_alphalessPixmap = gradientPixmap(orient, QColor::fromRgb(r, 0, b, 0xFF), QColor::fromRgb(r, 0xFF, b, 0xFF), flip);
+ if (m_combiningAlpha) {
+ m_mainPixmap = gradientPixmap(orient, QColor::fromRgb(r, 0, b, a), QColor::fromRgb(r, 0xFF, b, a), flip);
+ m_semiAlphaPixmap = gradientPixmap(orient, QColor::fromRgb(r, 0, b, semi), QColor::fromRgb(r, 0xFF, b, semi), flip);
+ }
+ } else if (m_component == QtColorLine::Blue) {
+ m_alphalessPixmap = gradientPixmap(orient, QColor::fromRgb(r, g, 0, 0xFF), QColor::fromRgb(r, g, 0xFF, 0xFF), flip);
+ if (m_combiningAlpha) {
+ m_mainPixmap = gradientPixmap(orient, QColor::fromRgb(r, g, 0, a), QColor::fromRgb(r, g, 0xFF, a), flip);
+ m_semiAlphaPixmap = gradientPixmap(orient, QColor::fromRgb(r, g, 0, semi), QColor::fromRgb(r, g, 0xFF, semi), flip);
+ }
+ } else if (m_component == QtColorLine::Alpha) {
+ m_mainPixmap = gradientPixmap(orient, QColor::fromRgb(r, g, b, 0), QColor::fromRgb(r, g, b, 0xFF), flip);
+
+// m_alphalessPixmap = gradientPixmap(orient, QColor::fromRgb(r, g, b, 0xFF), QColor::fromRgb(r, g, b, 0xFF), flip);
+// m_semiAlphaPixmap = gradientPixmap(orient, QColor::fromRgb(r, g, b, semi), QColor::fromRgb(r, g, b, semi), flip);
+ }
+ if (!m_combiningAlpha && m_component != QtColorLine::Alpha)
+ m_mainPixmap = m_alphalessPixmap;
+}
+
+QSize QtColorLinePrivate::pixmapSizeFromGeometrySize(
+ const QSize &geometrySize) const
+{
+ QSize size(m_indicatorSize + 2 * m_indicatorSpace - 1,
+ m_indicatorSize + 2 * m_indicatorSpace - 1);
+ if (m_orientation == Qt::Horizontal)
+ size.setHeight(0);
+ else
+ size.setWidth(0);
+ return geometrySize - size;
+}
+
+QColor QtColorLinePrivate::colorFromPoint(const QPointF &point) const
+{
+ QPointF p = point;
+ if (p.x() < 0)
+ p.setX(0.0);
+ else if (p.x() > 1)
+ p.setX(1.0);
+ if (p.y() < 0)
+ p.setY(0.0);
+ else if (p.y() > 1)
+ p.setY(1.0);
+
+ double pos = p.x();
+ if (m_orientation == Qt::Vertical)
+ pos = p.y();
+ if (m_flipped)
+ pos = 1.0 - pos;
+ QColor c;
+ qreal hue;
+ switch (m_component) {
+ case QtColorLine::Red:
+ c.setRgbF(pos, m_color.greenF(), m_color.blueF(), m_color.alphaF());
+ break;
+ case QtColorLine::Green:
+ c.setRgbF(m_color.redF(), pos, m_color.blueF(), m_color.alphaF());
+ break;
+ case QtColorLine::Blue:
+ c.setRgbF(m_color.redF(), m_color.greenF(), pos, m_color.alphaF());
+ break;
+ case QtColorLine::Hue:
+ hue = pos;
+ hue *= 35999.0 / 36000.0;
+ c.setHsvF(hue, m_color.saturationF(), m_color.valueF(), m_color.alphaF());
+ break;
+ case QtColorLine::Saturation:
+ c.setHsvF(m_color.hueF(), pos, m_color.valueF(), m_color.alphaF());
+ break;
+ case QtColorLine::Value:
+ c.setHsvF(m_color.hueF(), m_color.saturationF(), pos, m_color.alphaF());
+ break;
+ case QtColorLine::Alpha:
+ c.setHsvF(m_color.hueF(), m_color.saturationF(), m_color.valueF(), pos);
+ break;
+ }
+ return c;
+}
+
+QPointF QtColorLinePrivate::pointFromColor(const QColor &color) const
+{
+ qreal hue = color.hueF();
+ if (color.hue() == 360)
+ hue = 0.0;
+ else
+ hue *= 36000.0 / 35999.0;
+
+ double pos = 0.0;
+ switch (m_component) {
+ case QtColorLine::Red:
+ pos = color.redF();
+ break;
+ case QtColorLine::Green:
+ pos = color.greenF();
+ break;
+ case QtColorLine::Blue:
+ pos = color.blueF();
+ break;
+ case QtColorLine::Hue:
+ pos = hue;
+ break;
+ case QtColorLine::Saturation:
+ pos = color.saturationF();
+ break;
+ case QtColorLine::Value:
+ pos = color.valueF();
+ break;
+ case QtColorLine::Alpha:
+ pos = color.alphaF();
+ break;
+ }
+ if (m_flipped)
+ pos = 1.0 - pos;
+ QPointF p(pos, pos);
+ if (m_orientation == Qt::Horizontal)
+ p.setY(0);
+ else
+ p.setX(0);
+ return p;
+}
+
+QVector<QRect> QtColorLinePrivate::rects(const QPointF &point) const
+{
+ QRect r = q_ptr->geometry();
+ r.moveTo(0, 0);
+
+ int x1 = (int)((r.width() - m_indicatorSize - 2 * m_indicatorSpace) * point.x() + 0.5);
+ int x2 = x1 + m_indicatorSize + 2 * m_indicatorSpace;
+ int y1 = (int)((r.height() - m_indicatorSize - 2 * m_indicatorSpace) * point.y() + 0.5);
+ int y2 = y1 + m_indicatorSize + 2 * m_indicatorSpace;
+
+ QVector<QRect> rects;
+ if (m_orientation == Qt::Horizontal) {
+ // r0 r1 r2
+ QRect r0(0, 0, x1, r.height());
+ QRect r1(x1 + m_indicatorSpace, 0, m_indicatorSize, r.height());
+ QRect r2(x2, 0, r.width() - x2, r.height());
+
+ rects << r0 << r1 << r2;
+ } else {
+ // r0
+ // r1
+ // r2
+ QRect r0(0, 0, r.width(), y1);
+ QRect r1(0, y1 + m_indicatorSpace, r.width(), m_indicatorSize);
+ QRect r2(0, y2, r.width(), r.height() - y2);
+
+ rects << r0 << r1 << r2;
+ }
+ return rects;
+}
+
+void QtColorLinePrivate::resizeEvent(QResizeEvent *event)
+{
+ m_pixmapSize = pixmapSizeFromGeometrySize(event->size());
+}
+
+void QtColorLinePrivate::paintEvent(QPaintEvent *)
+{
+ QRect rect = q_ptr->rect();
+
+ QVector<QRect> r = rects(m_point);
+
+ QColor cBack = q_ptr->palette().color(QPalette::Active, QPalette::Window);
+ QColor c = colorFromPoint(m_point);
+ if (!m_combiningAlpha && m_component != QtColorLine::Alpha)
+ c.setAlpha(0xFF);
+
+ QPainter p(q_ptr);
+ if (q_ptr->isEnabled()) {
+ if (m_backgroundCheckered) {
+ int pixSize = 20;
+ QPixmap pm(2 * pixSize, 2 * pixSize);
+ QPainter pmp(&pm);
+ pmp.fillRect(0, 0, pixSize, pixSize, Qt::white);
+ pmp.fillRect(pixSize, pixSize, pixSize, pixSize, Qt::white);
+ pmp.fillRect(0, pixSize, pixSize, pixSize, Qt::black);
+ pmp.fillRect(pixSize, 0, pixSize, pixSize, Qt::black);
+ pmp.end();
+
+ p.setBrushOrigin((rect.width() % pixSize + pixSize) / 2, (rect.height() % pixSize + pixSize) / 2);
+ p.setClipRect(r[1].adjusted(4, 4, -4, -4));
+ p.setClipRect(QRect(rect.topLeft(), QPoint(r[1].left() + 0, rect.bottom())), Qt::UniteClip);
+ p.setClipRect(QRect(QPoint(r[1].right() - 0, rect.top()), rect.bottomRight()), Qt::UniteClip);
+ p.setClipRect(QRect(rect.topLeft(), QPoint(rect.right(), r[1].top() + 0)), Qt::UniteClip);
+ p.setClipRect(QRect(QPoint(rect.left(), r[1].bottom() - 0), rect.bottomRight()), Qt::UniteClip);
+ /*
+ p.setClipRect(r[1].adjusted(3, 3, -3, -3));
+ p.setClipRect(QRect(rect.topLeft(), QPoint(r[1].left() + 1, rect.bottom())), Qt::UniteClip);
+ p.setClipRect(QRect(QPoint(r[1].right() - 1, rect.top()), rect.bottomRight()), Qt::UniteClip);
+ p.setClipRect(QRect(rect.topLeft(), QPoint(rect.right(), r[1].top() + 1)), Qt::UniteClip);
+ p.setClipRect(QRect(QPoint(rect.left(), r[1].bottom() - 1), rect.bottomRight()), Qt::UniteClip);
+ */
+ p.fillRect(rect, pm);
+ p.setBrushOrigin(0, 0);
+ p.setClipping(false);
+ }
+
+ validate();
+
+ QSize fieldSize = pixmapSizeFromGeometrySize(q_ptr->geometry().size());
+
+ QPoint posOnField = r[1].topLeft() - QPoint(m_indicatorSpace, m_indicatorSpace);
+ int x = posOnField.x();
+ int y = posOnField.y();
+ int w = fieldSize.width();
+ int h = fieldSize.height();
+
+ QRect r0, r2;
+ if (m_orientation == Qt::Horizontal) {
+ r0 = QRect(0, 0, x, m_pixmapSize.height());
+ r2 = QRect(x + 1, 0, w - x - 1, m_pixmapSize.height());
+ } else {
+ r0 = QRect(0, 0, m_pixmapSize.width(), y);
+ r2 = QRect(0, y + 1, m_pixmapSize.width(), h - y - 1);
+ }
+
+ p.setBrush(m_mainPixmap);
+ p.setPen(Qt::NoPen);
+ if (r[0].isValid()) {
+ p.drawRect(r[0]);
+ }
+ if (r[2].isValid()) {
+ p.setBrushOrigin(r[2].topLeft() - r2.topLeft());
+ p.drawRect(r[2]);
+ }
+ if (m_indicatorSpace) {
+ p.setBrush(c);
+ if (m_orientation == Qt::Horizontal) {
+ p.drawRect(r[1].adjusted(-m_indicatorSpace, 0, -r[1].width(), 0));
+ p.drawRect(r[1].adjusted(r[1].width(), 0, m_indicatorSpace, 0));
+ } else {
+ p.drawRect(r[1].adjusted(0, -m_indicatorSpace, 0, -r[1].height()));
+ p.drawRect(r[1].adjusted(0, r[1].height(), 0, m_indicatorSpace));
+ }
+ }
+
+ QPen pen(c);
+ p.setPen(pen);
+ p.setBrush(Qt::NoBrush);
+ if (r[1].isValid()) {
+ p.drawRect(r[1].adjusted(0, 0, -1, -1));
+ // p.drawRect(r[1].adjusted(1, 1, -2, -2));
+ }
+ double coef = 9.0 / 10;
+ p.setPen(Qt::NoPen);
+ if (m_component != QtColorLine::Alpha && m_combiningAlpha) {
+ p.setBrush(m_alphalessPixmap);
+ if (r[0].isValid()) {
+ p.setBrushOrigin(QPoint(0, 0));
+ QRect thinRect1 = r[0];
+ QRect thinRect2 = r[0];
+ QRect thinRect = r[0];
+ if (m_orientation == Qt::Horizontal) {
+ thinRect1.adjust(0, qRound(thinRect1.height() * coef), 0, 0);
+ thinRect2.adjust(0, 0, 0, -qRound(thinRect2.height() * coef));
+ thinRect.adjust(0, qRound(thinRect.height() * coef), 0, -qRound(thinRect.height() * coef));
+ } else {
+ thinRect1.adjust(qRound(thinRect1.width() * coef), 0, 0, 0);
+ thinRect2.adjust(0, 0, -qRound(thinRect2.width() * coef), 0);
+ thinRect.adjust(qRound(thinRect.width() * coef), 0, -qRound(thinRect.width() * coef), 0);
+ }
+ p.drawRect(thinRect1);
+ p.drawRect(thinRect2);
+ //p.drawRect(thinRect);
+ }
+ if (r[2].isValid()) {
+ p.setBrushOrigin(r[2].topLeft() - r2.topLeft());
+ QRect thinRect1 = r[2];
+ QRect thinRect2 = r[2];
+ QRect thinRect = r[2];
+ if (m_orientation == Qt::Horizontal) {
+ thinRect1.adjust(0, qRound(thinRect1.height() * coef), 0, 0);
+ thinRect2.adjust(0, 0, 0, -qRound(thinRect2.height() * coef));
+ thinRect.adjust(0, qRound(thinRect.height() * coef), 0, -qRound(thinRect.height() * coef));
+ } else {
+ thinRect1.adjust(qRound(thinRect1.width() * coef), 0, 0, 0);
+ thinRect2.adjust(0, 0, -qRound(thinRect2.width() * coef), 0);
+ thinRect.adjust(qRound(thinRect.width() * coef), 0, -qRound(thinRect.width() * coef), 0);
+ }
+ p.drawRect(thinRect1);
+ p.drawRect(thinRect2);
+ //p.drawRect(thinRect);
+ }
+ /*
+
+*/
+
+
+
+
+
+ p.setPen(Qt::NoPen);
+
+ p.setBrush(m_semiAlphaPixmap);
+ if (r[0].isValid()) {
+ p.setBrushOrigin(QPoint(0, 0));
+ QRect thinRect1 = r[0];
+ QRect thinRect2 = r[0];
+ QRect thinRect = r[0];
+ if (m_orientation == Qt::Horizontal) {
+ thinRect1.adjust(0, qRound(thinRect1.height() * coef) - 1, 0, 0);
+ thinRect1.setBottom(thinRect1.top());
+ thinRect2.adjust(0, 0, 0, -qRound(thinRect2.height() * coef) + 1);
+ thinRect2.setTop(thinRect2.bottom());
+ thinRect.adjust(0, qRound(thinRect.height() * coef), 0, -qRound(thinRect.height() * coef));
+ } else {
+ thinRect1.adjust(qRound(thinRect1.width() * coef) - 1, 0, 0, 0);
+ thinRect1.setRight(thinRect1.left());
+ thinRect2.adjust(0, 0, -qRound(thinRect2.width() * coef) + 1, 0);
+ thinRect2.setLeft(thinRect2.right());
+ thinRect.adjust(qRound(thinRect.width() * coef), 0, -qRound(thinRect.width() * coef), 0);
+ }
+ p.drawRect(thinRect1);
+ p.drawRect(thinRect2);
+ //p.drawRect(thinRect);
+ }
+ if (r[2].isValid()) {
+ p.setBrushOrigin(r[2].topLeft() - r2.topLeft());
+ QRect thinRect1 = r[2];
+ QRect thinRect2 = r[2];
+ QRect thinRect = r[2];
+ if (m_orientation == Qt::Horizontal) {
+ thinRect1.adjust(0, qRound(thinRect1.height() * coef) - 1, 0, 0);
+ thinRect1.setBottom(thinRect1.top());
+ thinRect2.adjust(0, 0, 0, -qRound(thinRect2.height() * coef) + 1);
+ thinRect2.setTop(thinRect2.bottom());
+ thinRect.adjust(0, qRound(thinRect.height() * coef), 0, -qRound(thinRect.height() * coef));
+ } else {
+ thinRect1.adjust(qRound(thinRect1.width() * coef) - 1, 0, 0, 0);
+ thinRect1.setRight(thinRect1.left());
+ thinRect2.adjust(0, 0, -qRound(thinRect2.width() * coef) + 1, 0);
+ thinRect2.setLeft(thinRect2.right());
+ thinRect.adjust(qRound(thinRect.width() * coef), 0, -qRound(thinRect.width() * coef), 0);
+ }
+ p.drawRect(thinRect1);
+ p.drawRect(thinRect2);
+ //p.drawRect(thinRect);
+ }
+ p.setBrush(m_alphalessPixmap);
+ if (m_orientation == Qt::Horizontal) {
+ p.setClipRect(r[1].adjusted(0, qRound(r[1].height() * coef), 0, 0));
+ p.setClipRect(r[1].adjusted(0, 0, 0, -qRound(r[1].height() * coef)), Qt::UniteClip);
+ } else {
+ p.setClipRect(r[1].adjusted(qRound(r[1].width() * coef), 0, 0, 0));
+ p.setClipRect(r[1].adjusted(0, 0, -qRound(r[1].width() * coef), 0), Qt::UniteClip);
+ }
+ p.setBrush(Qt::NoBrush);
+ p.setPen(QPen(QColor(c.rgb())));
+
+ p.drawRect(r[1].adjusted(0, 0, -1, -1));
+ // p.drawRect(r[1].adjusted(1, 1, -2, -2));
+/*
+ p.setBrush(m_semiAlphaPixmap);
+ if (m_orientation == Qt::Horizontal) {
+ QRect top = r[1].adjusted(0, 0, 0, -qRound(r[1].height() * coef) + 1);
+ top.setTop(top.bottom());
+ QRect bottom = r[1].adjusted(0, qRound(r[1].height() * coef) - 1, 0, 0);
+ top.setBottom(bottom.top());
+ p.setClipRect(top);
+ p.setClipRect(bottom, Qt::UniteClip);
+ } else {
+
+ }
+ QColor semiColor(c.rgb());
+ semiColor.setAlpha((c.alpha() + 0xFF) / 2);
+ p.setPen(QPen(semiColor));
+ p.drawRect(r[1].adjusted(0, 0, -1, -1));
+ // p.drawRect(r[1].adjusted(1, 1, -2, -2));
+*/
+ p.setClipping(false);
+ }
+ }
+
+ p.setBrush(Qt::NoBrush);
+ int lw = 4;
+ //int br = 1;
+ int br = 0;
+ r[1].adjust(br, br, -br, -br);
+ if (r[1].adjusted(lw, lw, -lw, -lw).isValid()) {
+ QStyleOptionFrame opt;
+ opt.init(q_ptr);
+ opt.rect = r[1];
+ opt.lineWidth = 2;
+ opt.midLineWidth = 1;
+ if (m_dragging)
+ opt.state |= QStyle::State_Sunken;
+ else
+ opt.state |= QStyle::State_Raised;
+ q_ptr->style()->drawPrimitive(QStyle::PE_Frame, &opt, &p, q_ptr);
+ QRect colorRect = r[1].adjusted(lw, lw, -lw, -lw);
+ if (q_ptr->isEnabled()) {
+ p.fillRect(colorRect, c);
+ const QColor frameColor(0, 0, 0, 38);
+ p.setPen(frameColor);
+ p.drawRect(colorRect.adjusted(0, 0, -1, -1));
+ /*
+ p.fillRect(colorRect.width() / 4 + colorRect.left(),
+ colorRect.height() / 4 + colorRect.top(),
+ colorRect.width() / 2,
+ colorRect.height() / 2,
+ QColor(c.rgb()));
+ */
+ /*
+ if (m_component != QtColorLine::Alpha) {
+ p.fillRect(colorRect.adjusted(0, colorRect.height() * 4 / 5, 0, 0), QColor(c.rgb()));
+ p.fillRect(colorRect.adjusted(0, 0, 0, -colorRect.height() * 4 / 5), QColor(c.rgb()));
+ }
+ */
+ }
+ }
+}
+
+void QtColorLinePrivate::mousePressEvent(QMouseEvent *event)
+{
+ if (event->button() != Qt::LeftButton)
+ return;
+
+ QVector<QRect> r = rects(m_point);
+ QPoint clickPos = event->pos();
+
+ QSize fieldSize = q_ptr->geometry().size() -
+ QSize(m_indicatorSize + 2 * m_indicatorSpace - 1, m_indicatorSize + 2 * m_indicatorSpace - 1);
+ QPoint posOnField = r[1].topLeft() - QPoint(m_indicatorSpace, m_indicatorSpace);
+ m_clickOffset = posOnField - clickPos;
+
+ if (!r[1].contains(clickPos))
+ return;
+ m_dragging = true;
+ q_ptr->update();
+}
+
+void QtColorLinePrivate::mouseMoveEvent(QMouseEvent *event)
+{
+ if (!m_dragging)
+ return;
+ QPoint newPos = event->pos();
+
+ QSize fieldSize = q_ptr->geometry().size() -
+ QSize(m_indicatorSize + 2 * m_indicatorSpace - 1, m_indicatorSize + 2 * m_indicatorSpace - 1);
+ QPoint newPosOnField = newPos + m_clickOffset;
+ if (newPosOnField.x() < 0)
+ newPosOnField.setX(0);
+ else if (newPosOnField.x() > fieldSize.width())
+ newPosOnField.setX(fieldSize.width());
+ if (newPosOnField.y() < 0)
+ newPosOnField.setY(0);
+ else if (newPosOnField.y() > fieldSize.height())
+ newPosOnField.setY(fieldSize.height());
+
+ double x = (double)newPosOnField.x() / fieldSize.width();
+ double y = (double)newPosOnField.y() / fieldSize.height();
+ m_point = QPointF(x, y);
+ QColor color = colorFromPoint(m_point);
+ if (m_color == color)
+ return;
+ m_color = color;
+ emit q_ptr->colorChanged(color); // maybe before internal set, 1 line above
+ q_ptr->update();
+}
+
+void QtColorLinePrivate::mouseReleaseEvent(QMouseEvent *event)
+{
+ if (event->button() != Qt::LeftButton)
+ return;
+ m_dragging = false;
+ q_ptr->update();
+}
+
+void QtColorLinePrivate::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ if (event->button() != Qt::LeftButton)
+ return;
+
+ QVector<QRect> r = rects(m_point);
+ QPoint clickPos = event->pos();
+ if (!r[0].contains(clickPos) && !r[2].contains(clickPos))
+ return;
+ QPoint newPosOnField = clickPos;
+ if (r[2].contains(clickPos))
+ newPosOnField -= QPoint(m_indicatorSize + 2 * m_indicatorSpace - 2, m_indicatorSize + 2 * m_indicatorSpace - 2);
+ QSize fieldSize = q_ptr->geometry().size() -
+ QSize(m_indicatorSize + 2 * m_indicatorSpace - 1, m_indicatorSize + 2 * m_indicatorSpace - 1);
+
+ double x = (double)newPosOnField.x() / fieldSize.width();
+ double y = (double)newPosOnField.y() / fieldSize.height();
+ m_point = QPointF(x, y);
+ QColor color = colorFromPoint(m_point);
+ if (m_color == color)
+ return;
+ m_color = color;
+ emit q_ptr->colorChanged(color); // maybe before internal set, 1 line above
+ q_ptr->update();
+}
+
+////////////////////////////////////////////////////
+
+QtColorLine::QtColorLine(QWidget *parent)
+ : QWidget(parent), d_ptr(new QtColorLinePrivate)
+{
+ d_ptr->q_ptr = this;
+
+ setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
+}
+
+QtColorLine::~QtColorLine()
+{
+}
+
+QSize QtColorLine::minimumSizeHint() const
+{
+ return QSize(d_ptr->m_indicatorSize, d_ptr->m_indicatorSize);
+}
+
+QSize QtColorLine::sizeHint() const
+{
+ return QSize(d_ptr->m_indicatorSize, d_ptr->m_indicatorSize);
+}
+
+void QtColorLine::setColor(const QColor &color)
+{
+ d_ptr->setColor(color);
+}
+
+QColor QtColorLine::color() const
+{
+ return d_ptr->color();
+}
+
+void QtColorLine::setColorComponent(QtColorLine::ColorComponent component)
+{
+ d_ptr->setColorComponent(component);
+}
+
+QtColorLine::ColorComponent QtColorLine::colorComponent() const
+{
+ return d_ptr->colorComponent();
+}
+
+void QtColorLine::setIndicatorSize(int size)
+{
+ d_ptr->setIndicatorSize(size);
+}
+
+int QtColorLine::indicatorSize() const
+{
+ return d_ptr->indicatorSize();
+}
+
+void QtColorLine::setIndicatorSpace(int space)
+{
+ d_ptr->setIndicatorSpace(space);
+}
+
+int QtColorLine::indicatorSpace() const
+{
+ return d_ptr->indicatorSpace();
+}
+
+void QtColorLine::setFlip(bool flip)
+{
+ d_ptr->setFlip(flip);
+}
+
+bool QtColorLine::flip() const
+{
+ return d_ptr->flip();
+}
+
+void QtColorLine::setBackgroundCheckered(bool checkered)
+{
+ d_ptr->setBackgroundCheckered(checkered);
+}
+
+bool QtColorLine::isBackgroundCheckered() const
+{
+ return d_ptr->isBackgroundCheckered();
+}
+
+void QtColorLine::setOrientation(Qt::Orientation orientation)
+{
+ d_ptr->setOrientation(orientation);
+}
+
+Qt::Orientation QtColorLine::orientation() const
+{
+ return d_ptr->orientation();
+}
+void QtColorLine::resizeEvent(QResizeEvent *event)
+{
+ d_ptr->resizeEvent(event);
+}
+
+void QtColorLine::paintEvent(QPaintEvent *event)
+{
+ d_ptr->paintEvent(event);
+}
+
+void QtColorLine::mousePressEvent(QMouseEvent *event)
+{
+ d_ptr->mousePressEvent(event);
+}
+
+void QtColorLine::mouseMoveEvent(QMouseEvent *event)
+{
+ d_ptr->mouseMoveEvent(event);
+}
+
+void QtColorLine::mouseReleaseEvent(QMouseEvent *event)
+{
+ d_ptr->mouseReleaseEvent(event);
+}
+
+void QtColorLine::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ d_ptr->mouseDoubleClickEvent(event);
+}
+
+QT_END_NAMESPACE
diff --git a/src/shared/qtgradienteditor/qtcolorline.h b/src/shared/qtgradienteditor/qtcolorline.h
new file mode 100644
index 000000000..8d04a7ca7
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtcolorline.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTCOLORLINE_H
+#define QTCOLORLINE_H
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QtColorLine : public QWidget
+{
+ Q_OBJECT
+ Q_PROPERTY(QColor color READ color WRITE setColor)
+ Q_PROPERTY(int indicatorSpace READ indicatorSpace WRITE setIndicatorSpace)
+ Q_PROPERTY(int indicatorSize READ indicatorSize WRITE setIndicatorSize)
+ Q_PROPERTY(bool flip READ flip WRITE setFlip)
+ Q_PROPERTY(bool backgroundCheckered READ isBackgroundCheckered WRITE setBackgroundCheckered)
+ Q_PROPERTY(ColorComponent colorComponent READ colorComponent WRITE setColorComponent)
+ Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation)
+ Q_ENUMS(ColorComponent)
+public:
+
+ enum ColorComponent {
+ Red,
+ Green,
+ Blue,
+ Hue,
+ Saturation,
+ Value,
+ Alpha
+ };
+
+ QSize minimumSizeHint() const;
+ QSize sizeHint() const;
+
+ QtColorLine(QWidget *parent = 0);
+ ~QtColorLine();
+
+ QColor color() const;
+
+ void setIndicatorSize(int size);
+ int indicatorSize() const;
+
+ void setIndicatorSpace(int space);
+ int indicatorSpace() const;
+
+ void setFlip(bool flip);
+ bool flip() const;
+
+ bool isBackgroundCheckered() const;
+ void setBackgroundCheckered(bool checkered);
+
+ void setOrientation(Qt::Orientation orientation);
+ Qt::Orientation orientation() const;
+
+ void setColorComponent(ColorComponent component);
+ ColorComponent colorComponent() const;
+
+public slots:
+
+ void setColor(const QColor &color);
+
+signals:
+
+ void colorChanged(const QColor &color);
+
+protected:
+
+ void resizeEvent(QResizeEvent *event);
+ void paintEvent(QPaintEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
+ void mouseDoubleClickEvent(QMouseEvent *event);
+
+private:
+
+ QScopedPointer<class QtColorLinePrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtColorLine)
+ Q_DISABLE_COPY(QtColorLine)
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtgradienteditor/qtgradientdialog.cpp b/src/shared/qtgradienteditor/qtgradientdialog.cpp
new file mode 100644
index 000000000..dbeeb1f20
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientdialog.cpp
@@ -0,0 +1,353 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtgradientdialog.h"
+#include "ui_qtgradientdialog.h"
+#include <QtGui/QPushButton>
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientDialogPrivate
+{
+ QtGradientDialog *q_ptr;
+ Q_DECLARE_PUBLIC(QtGradientDialog)
+public:
+
+ void slotAboutToShowDetails(bool details, int extensionWidthHint);
+
+ Ui::QtGradientDialog m_ui;
+};
+
+void QtGradientDialogPrivate::slotAboutToShowDetails(bool details, int extensionWidthHint)
+{
+ if (details) {
+ q_ptr->resize(q_ptr->size() + QSize(extensionWidthHint, 0));
+ } else {
+ q_ptr->setMinimumSize(1, 1);
+ q_ptr->resize(q_ptr->size() - QSize(extensionWidthHint, 0));
+ q_ptr->setMinimumSize(0, 0);
+ }
+}
+
+/*!
+ \class QtGradientDialog
+
+ \brief The QtGradientDialog class provides a dialog for specifying gradients.
+
+ The gradient dialog's function is to allow users to edit gradients.
+ For example, you might use this in a drawing program to allow the user to set the brush gradient.
+
+ \table
+ \row
+ \o \inlineimage qtgradientdialog.png
+ \o \inlineimage qtgradientdialogextension.png
+ \header
+ \o Details extension hidden
+ \o Details extension visible
+ \endtable
+
+ Starting from the top of the dialog there are several buttons:
+
+ \image qtgradientdialogtopbuttons.png
+
+ The first three buttons allow for changing a type of the gradient (QGradient::Type), while the second three allow for
+ changing spread of the gradient (QGradient::Spread). The last button shows or hides the details extension of the dialog.
+ Conceptually the default view with hidden details provides the full functional control over gradient editing.
+ The additional extension with details allows to set gradient's parameters more precisely. The visibility
+ of extension can be controlled by detailsVisible property. Moreover, if you don't want the user to
+ switch on or off the visibility of extension you can set the detailsButtonVisible property to false.
+
+ Below top buttons there is an area where edited gradient is interactively previewed.
+ In addition the user can edit gradient type's specific parameters directly in this area by dragging
+ appropriate handles.
+
+ \table
+ \row
+ \o \inlineimage qtgradientdialoglineareditor.png
+ \o \inlineimage qtgradientdialogradialeditor.png
+ \o \inlineimage qtgradientdialogconicaleditor.png
+ \header
+ \o Editing linear type
+ \o Editing radial type
+ \o Editing conical type
+ \row
+ \o The user can change the start and final point positions by dragging the circular handles.
+ \o The user can change the center and focal point positions by dragging the circular handles
+ and can change the gradient's radius by dragging horizontal or vertical line.
+ \o The user can change the center point by dragging the circular handle
+ and can change the gradient's angle by dragging the big wheel.
+ \endtable
+
+ In the middle of the dialog there is an area where the user can edit gradient stops.
+
+ \table
+ \row
+ \o \inlineimage qtgradientdialogstops.png
+ \o \inlineimage qtgradientdialogstopszoomed.png
+ \endtable
+
+ The top part of this area contains stop handles, and bottom part shows the preview of gradient stops path.
+ In order to create a new gradient stop double click inside the view over the desired position.
+ If you double click on existing stop handle in the top part of the view, clicked handle will be duplicated
+ (duplicate will contain the same color).
+ The stop can be activated by clicking on its handle. You can activate previous or next stop by pressing
+ left or right key respectively. To jump to the first or last stop press home or end key respectively.
+ The gradient stops editor supports multiselection.
+ Clicking a handle holding the shift modifier key down will select a range of stops between
+ the active stop and clicked one. Clicking a handle holding control modifier key down will remove from or
+ add to selection the clicked stop depending if it was or wasn't already selected respectively.
+ Multiselection can also be created using rubberband (by pressing the left mouse button outside
+ of any handle and dragging).
+ Sometimes it's hard to select a stop because its handle can be partially covered by other handle.
+ In that case the user can zoom in the view by spinning mouse wheel.
+ The selected stop handles can be moved by drag & drop. In order to remove selected stops press delete key.
+ For convenience context menu is provided with the following actions:
+
+ \list
+ \o New Stop - creates a new gradient stop
+ \o Delete - removes the active and all selected stops
+ \o Flip All - mirrors all stops
+ \o Select All - selects all stops
+ \o Zoom In - zooms in
+ \o Zoom Out - zooms out
+ \o Zoom All - goes back to original 100% zoom
+ \endlist
+
+ The bottom part of the QtGradientDialog contains a set of widgets allowing to control the color of
+ the active and selected stops.
+
+ \table
+ \row
+ \o \inlineimage qtgradientdialogcolorhsv.png
+ \o \inlineimage qtgradientdialogcolorrgb.png
+ \endtable
+
+
+ The color button shows the color of the active gradient stop. It also allows for choosing
+ a color from standard color dialog and applying it to the
+ active stop and all selected stops. It's also possible to drag a color directly from the color button
+ and to drop it in gradient stops editor at desired position (it will create new stop with dragged color)
+ or at desired stop handle (it will change the color of that handle).
+
+ To the right of color button there is a set of 2 radio buttons which allows to switch between
+ HVS and RGB color spec.
+
+ Finally there are 4 color sliders working either in HSVA (hue saturation value alpha) or
+ RGBA (red green blue alpha) mode, depending on which radio button is chosen. The radio buttons
+ can be controlled programatically by spec() and setSpec() methods. The sliders show the
+ color of the active stop. By double clicking inside color slider you can set directly the desired color.
+ Changes of slider's are applied to stop selection in the way that the color
+ component being changed is applied to stops in selection only, while other components
+ remain unchanged in selected stops (e.g. when the user is changing the saturation,
+ new saturation is applied to selected stops preventing original hue, value and alpha in multiselection).
+
+ The convenient static functions getGradient() provide modal gradient dialogs, e.g.:
+
+ \snippet doc/src/snippets/code/tools_shared_qtgradienteditor_qtgradientdialog.cpp 0
+
+ In order to have more control over the properties of QtGradientDialog use
+ standard QDialog::exec() method:
+
+ \snippet doc/src/snippets/code/tools_shared_qtgradienteditor_qtgradientdialog.cpp 1
+
+ \sa {Gradient View Example}
+*/
+
+/*!
+ Constructs a gradient dialog with \a parent as parent widget.
+*/
+
+QtGradientDialog::QtGradientDialog(QWidget *parent)
+ : QDialog(parent), d_ptr(new QtGradientDialogPrivate())
+{
+// setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+ d_ptr->q_ptr = this;
+ d_ptr->m_ui.setupUi(this);
+ QPushButton *button = d_ptr->m_ui.buttonBox->button(QDialogButtonBox::Ok);
+ if (button)
+ button->setAutoDefault(false);
+ button = d_ptr->m_ui.buttonBox->button(QDialogButtonBox::Cancel);
+ if (button)
+ button->setAutoDefault(false);
+ connect(d_ptr->m_ui.gradientEditor, SIGNAL(aboutToShowDetails(bool,int)),
+ this, SLOT(slotAboutToShowDetails(bool,int)));
+}
+
+/*!
+ Destroys the gradient dialog
+*/
+
+QtGradientDialog::~QtGradientDialog()
+{
+}
+
+/*!
+ \property QtGradientDialog::gradient
+ \brief the gradient of the dialog
+*/
+void QtGradientDialog::setGradient(const QGradient &gradient)
+{
+ d_ptr->m_ui.gradientEditor->setGradient(gradient);
+}
+
+QGradient QtGradientDialog::gradient() const
+{
+ return d_ptr->m_ui.gradientEditor->gradient();
+}
+
+/*!
+ \property QtGradientDialog::backgroundCheckered
+ \brief whether the background of widgets able to show the colors with alpha channel is checkered.
+
+ \table
+ \row
+ \o \inlineimage qtgradientdialogbackgroundcheckered.png
+ \o \inlineimage qtgradientdialogbackgroundtransparent.png
+ \row
+ \o \snippet doc/src/snippets/code/tools_shared_qtgradienteditor_qtgradientdialog.cpp 2
+ \o \snippet doc/src/snippets/code/tools_shared_qtgradienteditor_qtgradientdialog.cpp 3
+ \endtable
+
+ When this property is set to true (the default) widgets inside gradient dialog like color button,
+ color sliders, gradient stops editor and gradient editor will show checkered background
+ in case of transparent colors. Otherwise the background of these widgets is transparent.
+*/
+
+bool QtGradientDialog::isBackgroundCheckered() const
+{
+ return d_ptr->m_ui.gradientEditor->isBackgroundCheckered();
+}
+
+void QtGradientDialog::setBackgroundCheckered(bool checkered)
+{
+ d_ptr->m_ui.gradientEditor->setBackgroundCheckered(checkered);
+}
+
+/*!
+ \property QtGradientDialog::detailsVisible
+ \brief whether details extension is visible.
+
+ When this property is set to true the details extension is visible. By default
+ this property is set to false and the details extension is hidden.
+
+ \sa detailsButtonVisible
+*/
+bool QtGradientDialog::detailsVisible() const
+{
+ return d_ptr->m_ui.gradientEditor->detailsVisible();
+}
+
+void QtGradientDialog::setDetailsVisible(bool visible)
+{
+ d_ptr->m_ui.gradientEditor->setDetailsVisible(visible);
+}
+
+/*!
+ \property QtGradientDialog::detailsButtonVisible
+ \brief whether the details button allowing for showing and hiding details extension is visible.
+
+ When this property is set to true (the default) the details button is visible and the user
+ can show and hide details extension interactively. Otherwise the button is hidden and the details
+ extension is always visible or hidded depending on the value of detailsVisible property.
+
+ \sa detailsVisible
+*/
+bool QtGradientDialog::isDetailsButtonVisible() const
+{
+ return d_ptr->m_ui.gradientEditor->isDetailsButtonVisible();
+}
+
+void QtGradientDialog::setDetailsButtonVisible(bool visible)
+{
+ d_ptr->m_ui.gradientEditor->setDetailsButtonVisible(visible);
+}
+
+/*!
+ Returns the current QColor::Spec used for the color sliders in the dialog.
+*/
+QColor::Spec QtGradientDialog::spec() const
+{
+ return d_ptr->m_ui.gradientEditor->spec();
+}
+
+/*!
+ Sets the current QColor::Spec to \a spec used for the color sliders in the dialog.
+*/
+void QtGradientDialog::setSpec(QColor::Spec spec)
+{
+ d_ptr->m_ui.gradientEditor->setSpec(spec);
+}
+
+/*!
+ Executes a modal gradient dialog, lets the user to specify a gradient, and returns that gradient.
+
+ If the user clicks \gui OK, the gradient specified by the user is returned. If the user clicks \gui Cancel, the \a initial gradient is returned.
+
+ The dialog is constructed with the given \a parent. \a caption is shown as the window title of the dialog and
+ \a initial is the initial gradient shown in the dialog. If the \a ok parameter is not-null,
+ the value it refers to is set to true if the user clicks \gui OK, and set to false if the user clicks \gui Cancel.
+*/
+QGradient QtGradientDialog::getGradient(bool *ok, const QGradient &initial, QWidget *parent, const QString &caption)
+{
+ QtGradientDialog dlg(parent);
+ if (!caption.isEmpty())
+ dlg.setWindowTitle(caption);
+ dlg.setGradient(initial);
+ const int res = dlg.exec();
+ if (ok) {
+ *ok = (res == QDialog::Accepted) ? true : false;
+ }
+ if (res == QDialog::Accepted)
+ return dlg.gradient();
+ return initial;
+}
+
+/*!
+ This method calls getGradient(ok, QLinearGradient(), parent, caption).
+*/
+QGradient QtGradientDialog::getGradient(bool *ok, QWidget *parent, const QString &caption)
+{
+ return getGradient(ok, QLinearGradient(), parent, caption);
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qtgradientdialog.cpp"
diff --git a/src/shared/qtgradienteditor/qtgradientdialog.h b/src/shared/qtgradienteditor/qtgradientdialog.h
new file mode 100644
index 000000000..c6330d164
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientdialog.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTGRADIENTDIALOG_H
+#define QTGRADIENTDIALOG_H
+
+#include <QtGui/QDialog>
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientDialog : public QDialog
+{
+ Q_OBJECT
+ Q_PROPERTY(QGradient gradient READ gradient WRITE setGradient)
+ Q_PROPERTY(bool backgroundCheckered READ isBackgroundCheckered WRITE setBackgroundCheckered)
+ Q_PROPERTY(bool detailsVisible READ detailsVisible WRITE setDetailsVisible)
+ Q_PROPERTY(bool detailsButtonVisible READ isDetailsButtonVisible WRITE setDetailsButtonVisible)
+public:
+ QtGradientDialog(QWidget *parent = 0);
+ ~QtGradientDialog();
+
+ void setGradient(const QGradient &gradient);
+ QGradient gradient() const;
+
+ bool isBackgroundCheckered() const;
+ void setBackgroundCheckered(bool checkered);
+
+ bool detailsVisible() const;
+ void setDetailsVisible(bool visible);
+
+ bool isDetailsButtonVisible() const;
+ void setDetailsButtonVisible(bool visible);
+
+ QColor::Spec spec() const;
+ void setSpec(QColor::Spec spec);
+
+ static QGradient getGradient(bool *ok, const QGradient &initial, QWidget *parent = 0, const QString &caption = QString());
+ static QGradient getGradient(bool *ok, QWidget *parent = 0, const QString &caption = QString());
+
+private:
+ QScopedPointer<class QtGradientDialogPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtGradientDialog)
+ Q_DISABLE_COPY(QtGradientDialog)
+ Q_PRIVATE_SLOT(d_func(), void slotAboutToShowDetails(bool details, int extensionWidthHint))
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtgradienteditor/qtgradientdialog.ui b/src/shared/qtgradienteditor/qtgradientdialog.ui
new file mode 100644
index 000000000..0652c1636
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientdialog.ui
@@ -0,0 +1,121 @@
+<ui version="4.0" >
+ <comment>*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <class>QtGradientDialog</class>
+ <widget class="QDialog" name="QtGradientDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>178</width>
+ <height>81</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Edit Gradient</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <item>
+ <widget class="QtGradientEditor" name="gradientEditor" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="MinimumExpanding" hsizetype="MinimumExpanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QtGradientEditor</class>
+ <extends>QFrame</extends>
+ <header>qtgradienteditor.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>QtGradientDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>72</x>
+ <y>224</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>21</x>
+ <y>243</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>QtGradientDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>168</x>
+ <y>233</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>152</x>
+ <y>251</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/shared/qtgradienteditor/qtgradienteditor.cpp b/src/shared/qtgradienteditor/qtgradienteditor.cpp
new file mode 100644
index 000000000..2855389d2
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradienteditor.cpp
@@ -0,0 +1,952 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtgradienteditor.h"
+#include "qtgradientstopscontroller.h"
+#include "ui_qtgradienteditor.h"
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientEditorPrivate
+{
+ QtGradientEditor *q_ptr;
+ Q_DECLARE_PUBLIC(QtGradientEditor)
+public:
+ QtGradientEditorPrivate() : m_gradient(QLinearGradient()) {}
+
+ void slotGradientStopsChanged(const QGradientStops &stops);
+ void slotTypeChanged(int type);
+ void slotSpreadChanged(int spread);
+ void slotStartLinearXChanged(double value);
+ void slotStartLinearYChanged(double value);
+ void slotEndLinearXChanged(double value);
+ void slotEndLinearYChanged(double value);
+ void slotCentralRadialXChanged(double value);
+ void slotCentralRadialYChanged(double value);
+ void slotFocalRadialXChanged(double value);
+ void slotFocalRadialYChanged(double value);
+ void slotRadiusRadialChanged(double value);
+ void slotCentralConicalXChanged(double value);
+ void slotCentralConicalYChanged(double value);
+ void slotAngleConicalChanged(double value);
+
+ void slotDetailsChanged(bool details);
+
+ void startLinearChanged(const QPointF &point);
+ void endLinearChanged(const QPointF &point);
+ void centralRadialChanged(const QPointF &point);
+ void focalRadialChanged(const QPointF &point);
+ void radiusRadialChanged(qreal radius);
+ void centralConicalChanged(const QPointF &point);
+ void angleConicalChanged(qreal angle);
+
+ void setStartLinear(const QPointF &point);
+ void setEndLinear(const QPointF &point);
+ void setCentralRadial(const QPointF &point);
+ void setFocalRadial(const QPointF &point);
+ void setRadiusRadial(qreal radius);
+ void setCentralConical(const QPointF &point);
+ void setAngleConical(qreal angle);
+
+ void setType(QGradient::Type type);
+ void showDetails(bool details);
+
+ void setSpinBox(QDoubleSpinBox *spinBox, const char *slot, double max = 1.0, double step = 0.01, int decimals = 3);
+ void reset();
+ void setLayout(bool details);
+ void layoutDetails(bool details);
+ bool row4Visible() const;
+ bool row5Visible() const;
+ int extensionWidthHint() const;
+
+ void setCombos(bool combos);
+
+ QGradient gradient() const;
+ void updateGradient(bool emitSignal);
+
+ Ui::QtGradientEditor m_ui;
+ QtGradientStopsController *m_gradientStopsController;
+
+ QDoubleSpinBox *startLinearXSpinBox;
+ QDoubleSpinBox *startLinearYSpinBox;
+ QDoubleSpinBox *endLinearXSpinBox;
+ QDoubleSpinBox *endLinearYSpinBox;
+ QDoubleSpinBox *centralRadialXSpinBox;
+ QDoubleSpinBox *centralRadialYSpinBox;
+ QDoubleSpinBox *focalRadialXSpinBox;
+ QDoubleSpinBox *focalRadialYSpinBox;
+ QDoubleSpinBox *radiusRadialSpinBox;
+ QDoubleSpinBox *centralConicalXSpinBox;
+ QDoubleSpinBox *centralConicalYSpinBox;
+ QDoubleSpinBox *angleConicalSpinBox;
+
+ QButtonGroup *m_typeGroup;
+ QButtonGroup *m_spreadGroup;
+
+ QGradient::Type m_type;
+
+ QGridLayout *m_gridLayout;
+ QWidget *m_hiddenWidget;
+ QGridLayout *m_hiddenLayout;
+ bool m_details;
+ bool m_detailsButtonVisible;
+ bool m_backgroundCheckered;
+
+ QGradient m_gradient;
+
+ bool m_combos;
+};
+
+QGradient QtGradientEditorPrivate::gradient() const
+{
+ QGradient *gradient = 0;
+ switch (m_ui.gradientWidget->gradientType()) {
+ case QGradient::LinearGradient:
+ gradient = new QLinearGradient(m_ui.gradientWidget->startLinear(),
+ m_ui.gradientWidget->endLinear());
+ break;
+ case QGradient::RadialGradient:
+ gradient = new QRadialGradient(m_ui.gradientWidget->centralRadial(),
+ m_ui.gradientWidget->radiusRadial(),
+ m_ui.gradientWidget->focalRadial());
+ break;
+ case QGradient::ConicalGradient:
+ gradient = new QConicalGradient(m_ui.gradientWidget->centralConical(),
+ m_ui.gradientWidget->angleConical());
+ break;
+ default:
+ break;
+ }
+ if (!gradient)
+ return QGradient();
+ gradient->setStops(m_ui.gradientWidget->gradientStops());
+ gradient->setSpread(m_ui.gradientWidget->gradientSpread());
+ gradient->setCoordinateMode(QGradient::StretchToDeviceMode);
+ QGradient gr = *gradient;
+ delete gradient;
+ return gr;
+}
+
+void QtGradientEditorPrivate::updateGradient(bool emitSignal)
+{
+ QGradient grad = gradient();
+ if (m_gradient == grad)
+ return;
+
+ m_gradient = grad;
+ if (emitSignal)
+ emit q_ptr->gradientChanged(m_gradient);
+}
+
+void QtGradientEditorPrivate::setCombos(bool combos)
+{
+ if (m_combos == combos)
+ return;
+
+ m_combos = combos;
+ m_ui.linearButton->setVisible(!m_combos);
+ m_ui.radialButton->setVisible(!m_combos);
+ m_ui.conicalButton->setVisible(!m_combos);
+ m_ui.padButton->setVisible(!m_combos);
+ m_ui.repeatButton->setVisible(!m_combos);
+ m_ui.reflectButton->setVisible(!m_combos);
+ m_ui.typeComboBox->setVisible(m_combos);
+ m_ui.spreadComboBox->setVisible(m_combos);
+}
+
+void QtGradientEditorPrivate::setLayout(bool details)
+{
+ QHBoxLayout *hboxLayout = new QHBoxLayout();
+ hboxLayout->setObjectName(QString::fromUtf8("hboxLayout"));
+ hboxLayout->addWidget(m_ui.typeComboBox);
+ hboxLayout->addWidget(m_ui.spreadComboBox);
+ QHBoxLayout *typeLayout = new QHBoxLayout();
+ typeLayout->setSpacing(0);
+ typeLayout->addWidget(m_ui.linearButton);
+ typeLayout->addWidget(m_ui.radialButton);
+ typeLayout->addWidget(m_ui.conicalButton);
+ hboxLayout->addLayout(typeLayout);
+ QHBoxLayout *spreadLayout = new QHBoxLayout();
+ spreadLayout->setSpacing(0);
+ spreadLayout->addWidget(m_ui.padButton);
+ spreadLayout->addWidget(m_ui.repeatButton);
+ spreadLayout->addWidget(m_ui.reflectButton);
+ hboxLayout->addLayout(spreadLayout);
+ hboxLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ hboxLayout->addWidget(m_ui.detailsButton);
+ m_gridLayout->addLayout(hboxLayout, 0, 0, 1, 2);
+ int span = 1;
+ if (details)
+ span = 7;
+ m_gridLayout->addWidget(m_ui.frame, 1, 0, span, 2);
+ int row = 2;
+ if (details) {
+ row = 8;
+ span = 4;
+ }
+ m_gridLayout->addWidget(m_ui.gradientStopsWidget, row, 0, span, 2);
+ QHBoxLayout *hboxLayout1 = new QHBoxLayout();
+ hboxLayout1->setObjectName(QString::fromUtf8("hboxLayout1"));
+ hboxLayout1->addWidget(m_ui.colorLabel);
+ hboxLayout1->addWidget(m_ui.colorButton);
+ hboxLayout1->addWidget(m_ui.hsvRadioButton);
+ hboxLayout1->addWidget(m_ui.rgbRadioButton);
+ hboxLayout1->addItem(new QSpacerItem(16, 23, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ int addRow = 0;
+ if (details)
+ addRow = 9;
+ m_gridLayout->addLayout(hboxLayout1, 3 + addRow, 0, 1, 2);
+ m_gridLayout->addWidget(m_ui.hLabel, 4 + addRow, 0, 1, 1);
+ m_gridLayout->addWidget(m_ui.frame_2, 4 + addRow, 1, 1, 1);
+ m_gridLayout->addWidget(m_ui.sLabel, 5 + addRow, 0, 1, 1);
+ m_gridLayout->addWidget(m_ui.frame_5, 5 + addRow, 1, 1, 1);
+ m_gridLayout->addWidget(m_ui.vLabel, 6 + addRow, 0, 1, 1);
+ m_gridLayout->addWidget(m_ui.frame_3, 6 + addRow, 1, 1, 1);
+ m_gridLayout->addWidget(m_ui.aLabel, 7 + addRow, 0, 1, 1);
+ m_gridLayout->addWidget(m_ui.frame_4, 7 + addRow, 1, 1, 1);
+
+ if (details) {
+ layoutDetails(details);
+ }
+}
+
+void QtGradientEditorPrivate::layoutDetails(bool details)
+{
+ QGridLayout *gridLayout = m_gridLayout;
+ int col = 2;
+ if (!details) {
+ col = 0;
+ if (!m_hiddenWidget) {
+ m_hiddenWidget = new QWidget();
+ m_hiddenLayout = new QGridLayout(m_hiddenWidget);
+ m_hiddenLayout->setContentsMargins(0, 0, 0, 0);
+ m_hiddenLayout->setSizeConstraint(QLayout::SetFixedSize);
+ }
+ gridLayout = m_hiddenLayout;
+ }
+ gridLayout->addWidget(m_ui.label1, 1, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.spinBox1, 1, col + 1, 1, 1);
+ gridLayout->addWidget(m_ui.label2, 2, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.spinBox2, 2, col + 1, 1, 1);
+ gridLayout->addWidget(m_ui.label3, 3, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.spinBox3, 3, col + 1, 1, 1);
+ gridLayout->addWidget(m_ui.label4, 4, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.spinBox4, 4, col + 1, 1, 1);
+ gridLayout->addWidget(m_ui.label5, 5, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.spinBox5, 5, col + 1, 1, 1);
+ gridLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), 6, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.line1Widget, 7, col + 0, 1, 2);
+ gridLayout->addWidget(m_ui.zoomLabel, 8, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.zoomWidget, 8, col + 1, 1, 1);
+ gridLayout->addWidget(m_ui.zoomButtonsWidget, 9, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.zoomAllButton, 9, col + 1, 1, 1);
+ gridLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Preferred), 10, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.line2Widget, 11, col + 0, 1, 2);
+ gridLayout->addWidget(m_ui.positionLabel, 12, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.positionWidget, 12, col + 1, 1, 1);
+ gridLayout->addWidget(m_ui.hueLabel, 13, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.hueWidget, 13, col + 1, 1, 1);
+ gridLayout->addWidget(m_ui.saturationLabel, 14, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.saturationWidget, 14, col + 1, 1, 1);
+ gridLayout->addWidget(m_ui.valueLabel, 15, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.valueWidget, 15, col + 1, 1, 1);
+ gridLayout->addWidget(m_ui.alphaLabel, 16, col + 0, 1, 1);
+ gridLayout->addWidget(m_ui.alphaWidget, 16, col + 1, 1, 1);
+
+ if (details) {
+ if (m_hiddenLayout) {
+ delete m_hiddenLayout;
+ m_hiddenLayout = 0;
+ }
+ if (m_hiddenWidget) {
+ delete m_hiddenWidget;
+ m_hiddenWidget = 0;
+ }
+ }
+}
+
+int QtGradientEditorPrivate::extensionWidthHint() const
+{
+ if (m_details)
+ return q_ptr->size().width() - m_ui.gradientStopsWidget->size().width();
+
+ const int space = m_ui.spinBox1->geometry().left() - m_ui.label1->geometry().right();
+
+ return m_hiddenLayout->minimumSize().width() + space;
+}
+
+void QtGradientEditorPrivate::slotDetailsChanged(bool details)
+{
+ showDetails(details);
+}
+
+bool QtGradientEditorPrivate::row4Visible() const
+{
+ if (m_type == QGradient::ConicalGradient)
+ return false;
+ return true;
+}
+
+bool QtGradientEditorPrivate::row5Visible() const
+{
+ if (m_type == QGradient::RadialGradient)
+ return true;
+ return false;
+}
+
+void QtGradientEditorPrivate::showDetails(bool details)
+{
+ if (m_details == details)
+ return;
+
+ bool blocked = m_ui.detailsButton->signalsBlocked();
+ m_ui.detailsButton->blockSignals(true);
+ m_ui.detailsButton->setChecked(details);
+ m_ui.detailsButton->blockSignals(blocked);
+
+ bool updates = q_ptr->updatesEnabled();
+ q_ptr->setUpdatesEnabled(false);
+
+ if (m_gridLayout) {
+ m_gridLayout->setEnabled(false);
+ delete m_gridLayout;
+ m_gridLayout = 0;
+ }
+
+ if (!details) {
+ layoutDetails(details);
+ }
+
+ emit q_ptr->aboutToShowDetails(details, extensionWidthHint());
+ m_details = details;
+
+ m_gridLayout = new QGridLayout(q_ptr);
+ m_gridLayout->setEnabled(false);
+ m_gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
+ m_gridLayout->setContentsMargins(0, 0, 0, 0);
+
+ m_ui.label4->setVisible(row4Visible());
+ m_ui.label5->setVisible(row5Visible());
+ m_ui.spinBox4->setVisible(row4Visible());
+ m_ui.spinBox5->setVisible(row5Visible());
+
+ setLayout(details);
+ m_gridLayout->setEnabled(true);
+
+ q_ptr->setUpdatesEnabled(updates);
+ q_ptr->update();
+}
+
+void QtGradientEditorPrivate::setSpinBox(QDoubleSpinBox *spinBox, const char *slot, double max, double step, int decimals)
+{
+ bool blocked = spinBox->signalsBlocked();
+ spinBox->blockSignals(true);
+ spinBox->setDecimals(decimals);
+ spinBox->setMaximum(max);
+ spinBox->setSingleStep(step);
+ spinBox->blockSignals(blocked);
+ QObject::connect(spinBox, SIGNAL(valueChanged(double)), q_ptr, slot);
+}
+
+void QtGradientEditorPrivate::reset()
+{
+ startLinearXSpinBox = 0;
+ startLinearYSpinBox = 0;
+ endLinearXSpinBox = 0;
+ endLinearYSpinBox = 0;
+ centralRadialXSpinBox = 0;
+ centralRadialYSpinBox = 0;
+ focalRadialXSpinBox = 0;
+ focalRadialYSpinBox = 0;
+ radiusRadialSpinBox = 0;
+ centralConicalXSpinBox = 0;
+ centralConicalYSpinBox = 0;
+ angleConicalSpinBox = 0;
+}
+
+void QtGradientEditorPrivate::setType(QGradient::Type type)
+{
+ if (m_type == type)
+ return;
+
+ m_type = type;
+ m_ui.spinBox1->disconnect(SIGNAL(valueChanged(double)));
+ m_ui.spinBox2->disconnect(SIGNAL(valueChanged(double)));
+ m_ui.spinBox3->disconnect(SIGNAL(valueChanged(double)));
+ m_ui.spinBox4->disconnect(SIGNAL(valueChanged(double)));
+ m_ui.spinBox5->disconnect(SIGNAL(valueChanged(double)));
+
+ reset();
+
+ bool ena = true;
+
+ if (m_gridLayout) {
+ ena = m_gridLayout->isEnabled();
+ m_gridLayout->setEnabled(false);
+ }
+
+ bool spreadEnabled = true;
+
+ if (type == QGradient::LinearGradient) {
+ startLinearXSpinBox = m_ui.spinBox1;
+ setSpinBox(startLinearXSpinBox, SLOT(slotStartLinearXChanged(double)));
+ m_ui.label1->setText(QApplication::translate("QtGradientEditor", "Start X", 0, QApplication::UnicodeUTF8));
+
+ startLinearYSpinBox = m_ui.spinBox2;
+ setSpinBox(startLinearYSpinBox, SLOT(slotStartLinearYChanged(double)));
+ m_ui.label2->setText(QApplication::translate("QtGradientEditor", "Start Y", 0, QApplication::UnicodeUTF8));
+
+ endLinearXSpinBox = m_ui.spinBox3;
+ setSpinBox(endLinearXSpinBox, SLOT(slotEndLinearXChanged(double)));
+ m_ui.label3->setText(QApplication::translate("QtGradientEditor", "Final X", 0, QApplication::UnicodeUTF8));
+
+ endLinearYSpinBox = m_ui.spinBox4;
+ setSpinBox(endLinearYSpinBox, SLOT(slotEndLinearYChanged(double)));
+ m_ui.label4->setText(QApplication::translate("QtGradientEditor", "Final Y", 0, QApplication::UnicodeUTF8));
+
+ setStartLinear(m_ui.gradientWidget->startLinear());
+ setEndLinear(m_ui.gradientWidget->endLinear());
+ } else if (type == QGradient::RadialGradient) {
+ centralRadialXSpinBox = m_ui.spinBox1;
+ setSpinBox(centralRadialXSpinBox, SLOT(slotCentralRadialXChanged(double)));
+ m_ui.label1->setText(QApplication::translate("QtGradientEditor", "Central X", 0, QApplication::UnicodeUTF8));
+
+ centralRadialYSpinBox = m_ui.spinBox2;
+ setSpinBox(centralRadialYSpinBox, SLOT(slotCentralRadialYChanged(double)));
+ m_ui.label2->setText(QApplication::translate("QtGradientEditor", "Central Y", 0, QApplication::UnicodeUTF8));
+
+ focalRadialXSpinBox = m_ui.spinBox3;
+ setSpinBox(focalRadialXSpinBox, SLOT(slotFocalRadialXChanged(double)));
+ m_ui.label3->setText(QApplication::translate("QtGradientEditor", "Focal X", 0, QApplication::UnicodeUTF8));
+
+ focalRadialYSpinBox = m_ui.spinBox4;
+ setSpinBox(focalRadialYSpinBox, SLOT(slotFocalRadialYChanged(double)));
+ m_ui.label4->setText(QApplication::translate("QtGradientEditor", "Focal Y", 0, QApplication::UnicodeUTF8));
+
+ radiusRadialSpinBox = m_ui.spinBox5;
+ setSpinBox(radiusRadialSpinBox, SLOT(slotRadiusRadialChanged(double)), 2.0);
+ m_ui.label5->setText(QApplication::translate("QtGradientEditor", "Radius", 0, QApplication::UnicodeUTF8));
+
+ setCentralRadial(m_ui.gradientWidget->centralRadial());
+ setFocalRadial(m_ui.gradientWidget->focalRadial());
+ setRadiusRadial(m_ui.gradientWidget->radiusRadial());
+ } else if (type == QGradient::ConicalGradient) {
+ centralConicalXSpinBox = m_ui.spinBox1;
+ setSpinBox(centralConicalXSpinBox, SLOT(slotCentralConicalXChanged(double)));
+ m_ui.label1->setText(QApplication::translate("QtGradientEditor", "Central X", 0, QApplication::UnicodeUTF8));
+
+ centralConicalYSpinBox = m_ui.spinBox2;
+ setSpinBox(centralConicalYSpinBox, SLOT(slotCentralConicalYChanged(double)));
+ m_ui.label2->setText(QApplication::translate("QtGradientEditor", "Central Y", 0, QApplication::UnicodeUTF8));
+
+ angleConicalSpinBox = m_ui.spinBox3;
+ setSpinBox(angleConicalSpinBox, SLOT(slotAngleConicalChanged(double)), 360.0, 1.0, 1);
+ m_ui.label3->setText(QApplication::translate("QtGradientEditor", "Angle", 0, QApplication::UnicodeUTF8));
+
+ setCentralConical(m_ui.gradientWidget->centralConical());
+ setAngleConical(m_ui.gradientWidget->angleConical());
+
+ spreadEnabled = false;
+ }
+ m_ui.spreadComboBox->setEnabled(spreadEnabled);
+ m_ui.padButton->setEnabled(spreadEnabled);
+ m_ui.repeatButton->setEnabled(spreadEnabled);
+ m_ui.reflectButton->setEnabled(spreadEnabled);
+
+ m_ui.label4->setVisible(row4Visible());
+ m_ui.spinBox4->setVisible(row4Visible());
+ m_ui.label5->setVisible(row5Visible());
+ m_ui.spinBox5->setVisible(row5Visible());
+
+ if (m_gridLayout) {
+ m_gridLayout->setEnabled(ena);
+ }
+}
+
+void QtGradientEditorPrivate::slotGradientStopsChanged(const QGradientStops &stops)
+{
+ m_ui.gradientWidget->setGradientStops(stops);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotTypeChanged(int idx)
+{
+ QGradient::Type type = QGradient::NoGradient;
+ if (idx == 0)
+ type = QGradient::LinearGradient;
+ else if (idx == 1)
+ type = QGradient::RadialGradient;
+ else if (idx == 2)
+ type = QGradient::ConicalGradient;
+ setType(type);
+ m_ui.typeComboBox->setCurrentIndex(idx);
+ m_typeGroup->button(idx)->setChecked(true);
+ m_ui.gradientWidget->setGradientType(type);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotSpreadChanged(int spread)
+{
+ if (spread == 0) {
+ m_ui.gradientWidget->setGradientSpread(QGradient::PadSpread);
+ } else if (spread == 1) {
+ m_ui.gradientWidget->setGradientSpread(QGradient::RepeatSpread);
+ } else if (spread == 2) {
+ m_ui.gradientWidget->setGradientSpread(QGradient::ReflectSpread);
+ }
+ m_ui.spreadComboBox->setCurrentIndex(spread);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotStartLinearXChanged(double value)
+{
+ QPointF point = m_ui.gradientWidget->startLinear();
+ point.setX(value);
+ m_ui.gradientWidget->setStartLinear(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotStartLinearYChanged(double value)
+{
+ QPointF point = m_ui.gradientWidget->startLinear();
+ point.setY(value);
+ m_ui.gradientWidget->setStartLinear(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotEndLinearXChanged(double value)
+{
+ QPointF point = m_ui.gradientWidget->endLinear();
+ point.setX(value);
+ m_ui.gradientWidget->setEndLinear(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotEndLinearYChanged(double value)
+{
+ QPointF point = m_ui.gradientWidget->endLinear();
+ point.setY(value);
+ m_ui.gradientWidget->setEndLinear(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotCentralRadialXChanged(double value)
+{
+ QPointF point = m_ui.gradientWidget->centralRadial();
+ point.setX(value);
+ m_ui.gradientWidget->setCentralRadial(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotCentralRadialYChanged(double value)
+{
+ QPointF point = m_ui.gradientWidget->centralRadial();
+ point.setY(value);
+ m_ui.gradientWidget->setCentralRadial(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotFocalRadialXChanged(double value)
+{
+ QPointF point = m_ui.gradientWidget->focalRadial();
+ point.setX(value);
+ m_ui.gradientWidget->setFocalRadial(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotFocalRadialYChanged(double value)
+{
+ QPointF point = m_ui.gradientWidget->focalRadial();
+ point.setY(value);
+ m_ui.gradientWidget->setFocalRadial(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotRadiusRadialChanged(double value)
+{
+ m_ui.gradientWidget->setRadiusRadial(value);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotCentralConicalXChanged(double value)
+{
+ QPointF point = m_ui.gradientWidget->centralConical();
+ point.setX(value);
+ m_ui.gradientWidget->setCentralConical(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotCentralConicalYChanged(double value)
+{
+ QPointF point = m_ui.gradientWidget->centralConical();
+ point.setY(value);
+ m_ui.gradientWidget->setCentralConical(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::slotAngleConicalChanged(double value)
+{
+ m_ui.gradientWidget->setAngleConical(value);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::startLinearChanged(const QPointF &point)
+{
+ setStartLinear(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::endLinearChanged(const QPointF &point)
+{
+ setEndLinear(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::centralRadialChanged(const QPointF &point)
+{
+ setCentralRadial(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::focalRadialChanged(const QPointF &point)
+{
+ setFocalRadial(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::radiusRadialChanged(qreal radius)
+{
+ setRadiusRadial(radius);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::centralConicalChanged(const QPointF &point)
+{
+ setCentralConical(point);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::angleConicalChanged(qreal angle)
+{
+ setAngleConical(angle);
+ updateGradient(true);
+}
+
+void QtGradientEditorPrivate::setStartLinear(const QPointF &point)
+{
+ if (startLinearXSpinBox)
+ startLinearXSpinBox->setValue(point.x());
+ if (startLinearYSpinBox)
+ startLinearYSpinBox->setValue(point.y());
+}
+
+void QtGradientEditorPrivate::setEndLinear(const QPointF &point)
+{
+ if (endLinearXSpinBox)
+ endLinearXSpinBox->setValue(point.x());
+ if (endLinearYSpinBox)
+ endLinearYSpinBox->setValue(point.y());
+}
+
+void QtGradientEditorPrivate::setCentralRadial(const QPointF &point)
+{
+ if (centralRadialXSpinBox)
+ centralRadialXSpinBox->setValue(point.x());
+ if (centralRadialYSpinBox)
+ centralRadialYSpinBox->setValue(point.y());
+}
+
+void QtGradientEditorPrivate::setFocalRadial(const QPointF &point)
+{
+ if (focalRadialXSpinBox)
+ focalRadialXSpinBox->setValue(point.x());
+ if (focalRadialYSpinBox)
+ focalRadialYSpinBox->setValue(point.y());
+}
+
+void QtGradientEditorPrivate::setRadiusRadial(qreal radius)
+{
+ if (radiusRadialSpinBox)
+ radiusRadialSpinBox->setValue(radius);
+}
+
+void QtGradientEditorPrivate::setCentralConical(const QPointF &point)
+{
+ if (centralConicalXSpinBox)
+ centralConicalXSpinBox->setValue(point.x());
+ if (centralConicalYSpinBox)
+ centralConicalYSpinBox->setValue(point.y());
+}
+
+void QtGradientEditorPrivate::setAngleConical(qreal angle)
+{
+ if (angleConicalSpinBox)
+ angleConicalSpinBox->setValue(angle);
+}
+
+QtGradientEditor::QtGradientEditor(QWidget *parent)
+ : QWidget(parent), d_ptr(new QtGradientEditorPrivate())
+{
+ d_ptr->q_ptr = this;
+ d_ptr->m_type = QGradient::RadialGradient;
+ d_ptr->m_ui.setupUi(this);
+ d_ptr->m_gridLayout = 0;
+ d_ptr->m_hiddenLayout = 0;
+ d_ptr->m_hiddenWidget = 0;
+ bool detailsDefault = false;
+ d_ptr->m_details = !detailsDefault;
+ d_ptr->m_detailsButtonVisible = true;
+ bool checkeredDefault = true;
+ d_ptr->m_backgroundCheckered = !checkeredDefault;
+ d_ptr->m_gradientStopsController = new QtGradientStopsController(this);
+ d_ptr->m_gradientStopsController->setUi(&d_ptr->m_ui);
+ d_ptr->reset();
+ d_ptr->setType(QGradient::LinearGradient);
+ d_ptr->m_combos = true;
+ d_ptr->setCombos(!d_ptr->m_combos);
+
+ d_ptr->showDetails(detailsDefault);
+ setBackgroundCheckered(checkeredDefault);
+
+ d_ptr->setStartLinear(QPointF(0, 0));
+ d_ptr->setEndLinear(QPointF(1, 1));
+ d_ptr->setCentralRadial(QPointF(0.5, 0.5));
+ d_ptr->setFocalRadial(QPointF(0.5, 0.5));
+ d_ptr->setRadiusRadial(0.5);
+ d_ptr->setCentralConical(QPointF(0.5, 0.5));
+ d_ptr->setAngleConical(0);
+
+ QIcon icon;
+ icon.addPixmap(style()->standardPixmap(QStyle::SP_ArrowRight), QIcon::Normal, QIcon::Off);
+ icon.addPixmap(style()->standardPixmap(QStyle::SP_ArrowLeft), QIcon::Normal, QIcon::On);
+ d_ptr->m_ui.detailsButton->setIcon(icon);
+
+ connect(d_ptr->m_ui.detailsButton, SIGNAL(clicked(bool)), this, SLOT(slotDetailsChanged(bool)));
+ connect(d_ptr->m_gradientStopsController, SIGNAL(gradientStopsChanged(QGradientStops)),
+ this, SLOT(slotGradientStopsChanged(QGradientStops)));
+
+ QIcon iconLinear(QLatin1String(":/trolltech/qtgradienteditor/images/typelinear.png"));
+ QIcon iconRadial(QLatin1String(":/trolltech/qtgradienteditor/images/typeradial.png"));
+ QIcon iconConical(QLatin1String(":/trolltech/qtgradienteditor/images/typeconical.png"));
+
+ d_ptr->m_ui.typeComboBox->addItem(iconLinear, tr("Linear"));
+ d_ptr->m_ui.typeComboBox->addItem(iconRadial, tr("Radial"));
+ d_ptr->m_ui.typeComboBox->addItem(iconConical, tr("Conical"));
+
+ d_ptr->m_ui.linearButton->setIcon(iconLinear);
+ d_ptr->m_ui.radialButton->setIcon(iconRadial);
+ d_ptr->m_ui.conicalButton->setIcon(iconConical);
+
+ d_ptr->m_typeGroup = new QButtonGroup(this);
+ d_ptr->m_typeGroup->addButton(d_ptr->m_ui.linearButton, 0);
+ d_ptr->m_typeGroup->addButton(d_ptr->m_ui.radialButton, 1);
+ d_ptr->m_typeGroup->addButton(d_ptr->m_ui.conicalButton, 2);
+
+ connect(d_ptr->m_typeGroup, SIGNAL(buttonClicked(int)),
+ this, SLOT(slotTypeChanged(int)));
+ connect(d_ptr->m_ui.typeComboBox, SIGNAL(activated(int)),
+ this, SLOT(slotTypeChanged(int)));
+
+ QIcon iconPad(QLatin1String(":/trolltech/qtgradienteditor/images/spreadpad.png"));
+ QIcon iconRepeat(QLatin1String(":/trolltech/qtgradienteditor/images/spreadrepeat.png"));
+ QIcon iconReflect(QLatin1String(":/trolltech/qtgradienteditor/images/spreadreflect.png"));
+
+ d_ptr->m_ui.spreadComboBox->addItem(iconPad, tr("Pad"));
+ d_ptr->m_ui.spreadComboBox->addItem(iconRepeat, tr("Repeat"));
+ d_ptr->m_ui.spreadComboBox->addItem(iconReflect, tr("Reflect"));
+
+ d_ptr->m_ui.padButton->setIcon(iconPad);
+ d_ptr->m_ui.repeatButton->setIcon(iconRepeat);
+ d_ptr->m_ui.reflectButton->setIcon(iconReflect);
+
+ d_ptr->m_spreadGroup = new QButtonGroup(this);
+ d_ptr->m_spreadGroup->addButton(d_ptr->m_ui.padButton, 0);
+ d_ptr->m_spreadGroup->addButton(d_ptr->m_ui.repeatButton, 1);
+ d_ptr->m_spreadGroup->addButton(d_ptr->m_ui.reflectButton, 2);
+ connect(d_ptr->m_spreadGroup, SIGNAL(buttonClicked(int)),
+ this, SLOT(slotSpreadChanged(int)));
+ connect(d_ptr->m_ui.spreadComboBox, SIGNAL(activated(int)),
+ this, SLOT(slotSpreadChanged(int)));
+
+ connect(d_ptr->m_ui.gradientWidget, SIGNAL(startLinearChanged(QPointF)),
+ this, SLOT(startLinearChanged(QPointF)));
+ connect(d_ptr->m_ui.gradientWidget, SIGNAL(endLinearChanged(QPointF)),
+ this, SLOT(endLinearChanged(QPointF)));
+ connect(d_ptr->m_ui.gradientWidget, SIGNAL(centralRadialChanged(QPointF)),
+ this, SLOT(centralRadialChanged(QPointF)));
+ connect(d_ptr->m_ui.gradientWidget, SIGNAL(focalRadialChanged(QPointF)),
+ this, SLOT(focalRadialChanged(QPointF)));
+ connect(d_ptr->m_ui.gradientWidget, SIGNAL(radiusRadialChanged(qreal)),
+ this, SLOT(radiusRadialChanged(qreal)));
+ connect(d_ptr->m_ui.gradientWidget, SIGNAL(centralConicalChanged(QPointF)),
+ this, SLOT(centralConicalChanged(QPointF)));
+ connect(d_ptr->m_ui.gradientWidget, SIGNAL(angleConicalChanged(qreal)),
+ this, SLOT(angleConicalChanged(qreal)));
+
+ QGradientStops stops = gradient().stops();
+ d_ptr->m_gradientStopsController->setGradientStops(stops);
+ d_ptr->m_ui.gradientWidget->setGradientStops(stops);
+}
+
+QtGradientEditor::~QtGradientEditor()
+{
+ if (d_ptr->m_hiddenWidget)
+ delete d_ptr->m_hiddenWidget;
+}
+
+void QtGradientEditor::setGradient(const QGradient &grad)
+{
+ if (grad == gradient())
+ return;
+
+ QGradient::Type type = grad.type();
+ int idx = 0;
+ switch (type) {
+ case QGradient::LinearGradient: idx = 0; break;
+ case QGradient::RadialGradient: idx = 1; break;
+ case QGradient::ConicalGradient: idx = 2; break;
+ default: return;
+ }
+ d_ptr->setType(type);
+ d_ptr->m_ui.typeComboBox->setCurrentIndex(idx);
+ d_ptr->m_ui.gradientWidget->setGradientType(type);
+ d_ptr->m_typeGroup->button(idx)->setChecked(true);
+
+ QGradient::Spread spread = grad.spread();
+ switch (spread) {
+ case QGradient::PadSpread: idx = 0; break;
+ case QGradient::RepeatSpread: idx = 1; break;
+ case QGradient::ReflectSpread: idx = 2; break;
+ default: idx = 0; break;
+ }
+ d_ptr->m_ui.spreadComboBox->setCurrentIndex(idx);
+ d_ptr->m_ui.gradientWidget->setGradientSpread(spread);
+ d_ptr->m_spreadGroup->button(idx)->setChecked(true);
+
+ if (type == QGradient::LinearGradient) {
+ QLinearGradient *gr = (QLinearGradient *)(&grad);
+ d_ptr->setStartLinear(gr->start());
+ d_ptr->setEndLinear(gr->finalStop());
+ d_ptr->m_ui.gradientWidget->setStartLinear(gr->start());
+ d_ptr->m_ui.gradientWidget->setEndLinear(gr->finalStop());
+ } else if (type == QGradient::RadialGradient) {
+ QRadialGradient *gr = (QRadialGradient *)(&grad);
+ d_ptr->setCentralRadial(gr->center());
+ d_ptr->setFocalRadial(gr->focalPoint());
+ d_ptr->setRadiusRadial(gr->radius());
+ d_ptr->m_ui.gradientWidget->setCentralRadial(gr->center());
+ d_ptr->m_ui.gradientWidget->setFocalRadial(gr->focalPoint());
+ d_ptr->m_ui.gradientWidget->setRadiusRadial(gr->radius());
+ } else if (type == QGradient::ConicalGradient) {
+ QConicalGradient *gr = (QConicalGradient *)(&grad);
+ d_ptr->setCentralConical(gr->center());
+ d_ptr->setAngleConical(gr->angle());
+ d_ptr->m_ui.gradientWidget->setCentralConical(gr->center());
+ d_ptr->m_ui.gradientWidget->setAngleConical(gr->angle());
+ }
+
+ d_ptr->m_gradientStopsController->setGradientStops(grad.stops());
+ d_ptr->m_ui.gradientWidget->setGradientStops(grad.stops());
+ d_ptr->updateGradient(false);
+}
+
+QGradient QtGradientEditor::gradient() const
+{
+ return d_ptr->m_gradient;
+}
+
+bool QtGradientEditor::isBackgroundCheckered() const
+{
+ return d_ptr->m_backgroundCheckered;
+}
+
+void QtGradientEditor::setBackgroundCheckered(bool checkered)
+{
+ if (d_ptr->m_backgroundCheckered == checkered)
+ return;
+
+ d_ptr->m_backgroundCheckered = checkered;
+ d_ptr->m_ui.hueColorLine->setBackgroundCheckered(checkered);
+ d_ptr->m_ui.saturationColorLine->setBackgroundCheckered(checkered);
+ d_ptr->m_ui.valueColorLine->setBackgroundCheckered(checkered);
+ d_ptr->m_ui.alphaColorLine->setBackgroundCheckered(checkered);
+ d_ptr->m_ui.gradientWidget->setBackgroundCheckered(checkered);
+ d_ptr->m_ui.gradientStopsWidget->setBackgroundCheckered(checkered);
+ d_ptr->m_ui.colorButton->setBackgroundCheckered(checkered);
+}
+
+bool QtGradientEditor::detailsVisible() const
+{
+ return d_ptr->m_details;
+}
+
+void QtGradientEditor::setDetailsVisible(bool visible)
+{
+ d_ptr->showDetails(visible);
+}
+
+bool QtGradientEditor::isDetailsButtonVisible() const
+{
+ return d_ptr->m_detailsButtonVisible;
+}
+
+void QtGradientEditor::setDetailsButtonVisible(bool visible)
+{
+ if (d_ptr->m_detailsButtonVisible == visible)
+ return;
+
+ d_ptr->m_detailsButtonVisible = visible;
+ d_ptr->m_ui.detailsButton->setVisible(visible);
+}
+
+QColor::Spec QtGradientEditor::spec() const
+{
+ return d_ptr->m_gradientStopsController->spec();
+}
+
+void QtGradientEditor::setSpec(QColor::Spec spec)
+{
+ d_ptr->m_gradientStopsController->setSpec(spec);
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qtgradienteditor.cpp"
diff --git a/src/shared/qtgradienteditor/qtgradienteditor.h b/src/shared/qtgradienteditor/qtgradienteditor.h
new file mode 100644
index 000000000..77e1d3470
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradienteditor.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTGRADIENTEDITOR_H
+#define QTGRADIENTEDITOR_H
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientEditor : public QWidget
+{
+ Q_OBJECT
+ Q_PROPERTY(QGradient gradient READ gradient WRITE setGradient)
+ Q_PROPERTY(bool backgroundCheckered READ isBackgroundCheckered WRITE setBackgroundCheckered)
+ Q_PROPERTY(bool detailsVisible READ detailsVisible WRITE setDetailsVisible)
+ Q_PROPERTY(bool detailsButtonVisible READ isDetailsButtonVisible WRITE setDetailsButtonVisible)
+public:
+ QtGradientEditor(QWidget *parent = 0);
+ ~QtGradientEditor();
+
+ void setGradient(const QGradient &gradient);
+ QGradient gradient() const;
+
+ bool isBackgroundCheckered() const;
+ void setBackgroundCheckered(bool checkered);
+
+ bool detailsVisible() const;
+ void setDetailsVisible(bool visible);
+
+ bool isDetailsButtonVisible() const;
+ void setDetailsButtonVisible(bool visible);
+
+ QColor::Spec spec() const;
+ void setSpec(QColor::Spec spec);
+
+signals:
+
+ void gradientChanged(const QGradient &gradient);
+ void aboutToShowDetails(bool details, int extenstionWidthHint);
+
+private:
+ QScopedPointer<class QtGradientEditorPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtGradientEditor)
+ Q_DISABLE_COPY(QtGradientEditor)
+ Q_PRIVATE_SLOT(d_func(), void slotGradientStopsChanged(const QGradientStops &stops))
+ Q_PRIVATE_SLOT(d_func(), void slotTypeChanged(int type))
+ Q_PRIVATE_SLOT(d_func(), void slotSpreadChanged(int type))
+ Q_PRIVATE_SLOT(d_func(), void slotStartLinearXChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotStartLinearYChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotEndLinearXChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotEndLinearYChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotCentralRadialXChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotCentralRadialYChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotFocalRadialXChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotFocalRadialYChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotRadiusRadialChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotCentralConicalXChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotCentralConicalYChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotAngleConicalChanged(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotDetailsChanged(bool details))
+ Q_PRIVATE_SLOT(d_func(), void startLinearChanged(const QPointF &))
+ Q_PRIVATE_SLOT(d_func(), void endLinearChanged(const QPointF &))
+ Q_PRIVATE_SLOT(d_func(), void centralRadialChanged(const QPointF &))
+ Q_PRIVATE_SLOT(d_func(), void focalRadialChanged(const QPointF &))
+ Q_PRIVATE_SLOT(d_func(), void radiusRadialChanged(qreal))
+ Q_PRIVATE_SLOT(d_func(), void centralConicalChanged(const QPointF &))
+ Q_PRIVATE_SLOT(d_func(), void angleConicalChanged(qreal))
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtgradienteditor/qtgradienteditor.pri b/src/shared/qtgradienteditor/qtgradienteditor.pri
new file mode 100644
index 000000000..4cf059e1f
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradienteditor.pri
@@ -0,0 +1,33 @@
+INCLUDEPATH += $$PWD
+DEPENDPATH += $$PWD
+FORMS += $$PWD/qtgradienteditor.ui \
+ $$PWD/qtgradientdialog.ui \
+ $$PWD/qtgradientview.ui \
+ $$PWD/qtgradientviewdialog.ui
+SOURCES += $$PWD/qtgradientstopsmodel.cpp \
+ $$PWD/qtgradientstopswidget.cpp \
+ $$PWD/qtgradientstopscontroller.cpp \
+ $$PWD/qtgradientwidget.cpp \
+ $$PWD/qtgradienteditor.cpp \
+ $$PWD/qtgradientdialog.cpp \
+ $$PWD/qtcolorbutton.cpp \
+ $$PWD/qtcolorline.cpp \
+ $$PWD/qtgradientview.cpp \
+ $$PWD/qtgradientviewdialog.cpp \
+ $$PWD/qtgradientmanager.cpp \
+ $$PWD/qtgradientutils.cpp
+HEADERS += $$PWD/qtgradientstopsmodel.h \
+ $$PWD/qtgradientstopswidget.h \
+ $$PWD/qtgradientstopscontroller.h \
+ $$PWD/qtgradientwidget.h \
+ $$PWD/qtgradienteditor.h \
+ $$PWD/qtgradientdialog.h \
+ $$PWD/qtcolorbutton.h \
+ $$PWD/qtcolorline.h \
+ $$PWD/qtgradientview.h \
+ $$PWD/qtgradientviewdialog.h \
+ $$PWD/qtgradientmanager.h \
+ $$PWD/qtgradientutils.h
+RESOURCES += $$PWD/qtgradienteditor.qrc
+
+QT += xml
diff --git a/src/shared/qtgradienteditor/qtgradienteditor.qrc b/src/shared/qtgradienteditor/qtgradienteditor.qrc
new file mode 100644
index 000000000..cce7ba622
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradienteditor.qrc
@@ -0,0 +1,18 @@
+<!DOCTYPE RCC><RCC version="1.0">
+ <qresource prefix="/trolltech/qtgradienteditor">
+ <file>images/edit.png</file>
+ <file>images/zoomin.png</file>
+ <file>images/zoomout.png</file>
+ <file>images/up.png</file>
+ <file>images/down.png</file>
+ <file>images/plus.png</file>
+ <file>images/minus.png</file>
+ <file>images/editdelete.png</file>
+ <file>images/spreadpad.png</file>
+ <file>images/spreadrepeat.png</file>
+ <file>images/spreadreflect.png</file>
+ <file>images/typelinear.png</file>
+ <file>images/typeradial.png</file>
+ <file>images/typeconical.png</file>
+ </qresource>
+</RCC>
diff --git a/src/shared/qtgradienteditor/qtgradienteditor.ui b/src/shared/qtgradienteditor/qtgradienteditor.ui
new file mode 100644
index 000000000..5a842ffe4
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradienteditor.ui
@@ -0,0 +1,1377 @@
+<ui version="4.0" >
+ <comment>*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <class>QtGradientEditor</class>
+ <widget class="QWidget" name="QtGradientEditor" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>364</width>
+ <height>518</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <widget class="QFrame" name="frame" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>69</y>
+ <width>193</width>
+ <height>150</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape" >
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QtGradientWidget" native="1" name="gradientWidget" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Gradient Editor</string>
+ </property>
+ <property name="whatsThis" >
+ <string>This area shows a preview of the gradient being edited. It also allows you to edit parameters specific to the gradient's type such as start and final point, radius, etc. by drag &amp; drop.</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QLabel" name="label1" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>69</y>
+ <width>64</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>1</string>
+ </property>
+ </widget>
+ <widget class="QDoubleSpinBox" name="spinBox1" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>69</y>
+ <width>73</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="keyboardTracking" >
+ <bool>false</bool>
+ </property>
+ <property name="decimals" >
+ <number>3</number>
+ </property>
+ <property name="maximum" >
+ <double>1.000000000000000</double>
+ </property>
+ <property name="singleStep" >
+ <double>0.010000000000000</double>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label2" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>99</y>
+ <width>64</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>2</string>
+ </property>
+ </widget>
+ <widget class="QDoubleSpinBox" name="spinBox2" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>99</y>
+ <width>73</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="keyboardTracking" >
+ <bool>false</bool>
+ </property>
+ <property name="decimals" >
+ <number>3</number>
+ </property>
+ <property name="maximum" >
+ <double>1.000000000000000</double>
+ </property>
+ <property name="singleStep" >
+ <double>0.010000000000000</double>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label3" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>129</y>
+ <width>64</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>3</string>
+ </property>
+ </widget>
+ <widget class="QDoubleSpinBox" name="spinBox3" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>129</y>
+ <width>73</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="keyboardTracking" >
+ <bool>false</bool>
+ </property>
+ <property name="decimals" >
+ <number>3</number>
+ </property>
+ <property name="maximum" >
+ <double>1.000000000000000</double>
+ </property>
+ <property name="singleStep" >
+ <double>0.010000000000000</double>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label4" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>159</y>
+ <width>64</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>4</string>
+ </property>
+ </widget>
+ <widget class="QDoubleSpinBox" name="spinBox4" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>159</y>
+ <width>73</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="keyboardTracking" >
+ <bool>false</bool>
+ </property>
+ <property name="decimals" >
+ <number>3</number>
+ </property>
+ <property name="maximum" >
+ <double>1.000000000000000</double>
+ </property>
+ <property name="singleStep" >
+ <double>0.010000000000000</double>
+ </property>
+ </widget>
+ <widget class="QLabel" name="label5" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>189</y>
+ <width>64</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>5</string>
+ </property>
+ </widget>
+ <widget class="QDoubleSpinBox" name="spinBox5" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>189</y>
+ <width>73</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="keyboardTracking" >
+ <bool>false</bool>
+ </property>
+ <property name="decimals" >
+ <number>3</number>
+ </property>
+ <property name="maximum" >
+ <double>1.000000000000000</double>
+ </property>
+ <property name="singleStep" >
+ <double>0.010000000000000</double>
+ </property>
+ </widget>
+ <widget class="QtGradientStopsWidget" native="1" name="gradientStopsWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>225</y>
+ <width>193</width>
+ <height>67</height>
+ </rect>
+ </property>
+ <property name="toolTip" >
+ <string>Gradient Stops Editor</string>
+ </property>
+ <property name="whatsThis" >
+ <string>This area allows you to edit gradient stops. Double click on the existing stop handle to duplicate it. Double click outside of the existing stop handles to create a new stop. Drag &amp; drop the handle to reposition it. Use right mouse button to popup context menu with extra actions.</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="zoomLabel" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>231</y>
+ <width>64</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>Zoom</string>
+ </property>
+ </widget>
+ <widget class="QToolButton" name="zoomAllButton" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>260</y>
+ <width>72</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Reset Zoom</string>
+ </property>
+ <property name="text" >
+ <string>Reset Zoom</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="positionLabel" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>304</y>
+ <width>64</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="text" >
+ <string>Position</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="hLabel" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>335</y>
+ <width>32</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Hue</string>
+ </property>
+ <property name="text" >
+ <string>H</string>
+ </property>
+ </widget>
+ <widget class="QFrame" name="frame_2" >
+ <property name="geometry" >
+ <rect>
+ <x>48</x>
+ <y>333</y>
+ <width>155</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Ignored" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape" >
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QHBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QtColorLine" native="1" name="hueColorLine" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Hue</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QLabel" name="hueLabel" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>335</y>
+ <width>64</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Hue</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="sLabel" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>364</y>
+ <width>32</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Saturation</string>
+ </property>
+ <property name="text" >
+ <string>S</string>
+ </property>
+ </widget>
+ <widget class="QFrame" name="frame_5" >
+ <property name="geometry" >
+ <rect>
+ <x>48</x>
+ <y>362</y>
+ <width>155</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Ignored" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape" >
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QHBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QtColorLine" native="1" name="saturationColorLine" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Saturation</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QLabel" name="saturationLabel" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>364</y>
+ <width>64</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Sat</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="vLabel" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>393</y>
+ <width>32</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Value</string>
+ </property>
+ <property name="text" >
+ <string>V</string>
+ </property>
+ </widget>
+ <widget class="QFrame" name="frame_3" >
+ <property name="geometry" >
+ <rect>
+ <x>48</x>
+ <y>391</y>
+ <width>155</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Ignored" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape" >
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QHBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QtColorLine" native="1" name="valueColorLine" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Value</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QLabel" name="valueLabel" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>393</y>
+ <width>64</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Val</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="aLabel" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>422</y>
+ <width>32</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Alpha</string>
+ </property>
+ <property name="text" >
+ <string>A</string>
+ </property>
+ </widget>
+ <widget class="QFrame" name="frame_4" >
+ <property name="geometry" >
+ <rect>
+ <x>48</x>
+ <y>420</y>
+ <width>155</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Ignored" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape" >
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QHBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QtColorLine" native="1" name="alphaColorLine" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Expanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Alpha</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QLabel" name="alphaLabel" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>422</y>
+ <width>64</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Alpha</string>
+ </property>
+ </widget>
+ <widget class="QComboBox" name="typeComboBox" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>40</y>
+ <width>79</width>
+ <height>22</height>
+ </rect>
+ </property>
+ <property name="toolTip" >
+ <string>Type</string>
+ </property>
+ </widget>
+ <widget class="QComboBox" name="spreadComboBox" >
+ <property name="geometry" >
+ <rect>
+ <x>96</x>
+ <y>40</y>
+ <width>72</width>
+ <height>22</height>
+ </rect>
+ </property>
+ <property name="toolTip" >
+ <string>Spread</string>
+ </property>
+ </widget>
+ <widget class="QLabel" name="colorLabel" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>298</y>
+ <width>32</width>
+ <height>29</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Fixed" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Color</string>
+ </property>
+ </widget>
+ <widget class="QtColorButton" name="colorButton" >
+ <property name="geometry" >
+ <rect>
+ <x>48</x>
+ <y>300</y>
+ <width>26</width>
+ <height>25</height>
+ </rect>
+ </property>
+ <property name="toolTip" >
+ <string>Current stop's color</string>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ </widget>
+ <widget class="QRadioButton" name="hsvRadioButton" >
+ <property name="geometry" >
+ <rect>
+ <x>80</x>
+ <y>301</y>
+ <width>49</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Show HSV specification</string>
+ </property>
+ <property name="text" >
+ <string>HSV</string>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QRadioButton" name="rgbRadioButton" >
+ <property name="geometry" >
+ <rect>
+ <x>135</x>
+ <y>301</y>
+ <width>49</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Show RGB specification</string>
+ </property>
+ <property name="text" >
+ <string>RGB</string>
+ </property>
+ </widget>
+ <widget class="QWidget" native="1" name="positionWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>304</y>
+ <width>73</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QDoubleSpinBox" name="positionSpinBox" >
+ <property name="toolTip" >
+ <string>Current stop's position</string>
+ </property>
+ <property name="keyboardTracking" >
+ <bool>false</bool>
+ </property>
+ <property name="decimals" >
+ <number>3</number>
+ </property>
+ <property name="minimum" >
+ <double>0.000000000000000</double>
+ </property>
+ <property name="maximum" >
+ <double>1.000000000000000</double>
+ </property>
+ <property name="singleStep" >
+ <double>0.010000000000000</double>
+ </property>
+ <property name="value" >
+ <double>0.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" native="1" name="hueWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>333</y>
+ <width>73</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QSpinBox" name="hueSpinBox" >
+ <property name="keyboardTracking" >
+ <bool>false</bool>
+ </property>
+ <property name="maximum" >
+ <number>359</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" native="1" name="saturationWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>362</y>
+ <width>73</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QSpinBox" name="saturationSpinBox" >
+ <property name="keyboardTracking" >
+ <bool>false</bool>
+ </property>
+ <property name="maximum" >
+ <number>255</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" native="1" name="valueWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>391</y>
+ <width>73</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QSpinBox" name="valueSpinBox" >
+ <property name="keyboardTracking" >
+ <bool>false</bool>
+ </property>
+ <property name="maximum" >
+ <number>255</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" native="1" name="alphaWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>420</y>
+ <width>73</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QSpinBox" name="alphaSpinBox" >
+ <property name="keyboardTracking" >
+ <bool>false</bool>
+ </property>
+ <property name="maximum" >
+ <number>255</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" native="1" name="zoomWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>279</x>
+ <y>231</y>
+ <width>73</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QSpinBox" name="zoomSpinBox" >
+ <property name="keyboardTracking" >
+ <bool>false</bool>
+ </property>
+ <property name="suffix" >
+ <string>%</string>
+ </property>
+ <property name="minimum" >
+ <number>100</number>
+ </property>
+ <property name="maximum" >
+ <number>10000</number>
+ </property>
+ <property name="singleStep" >
+ <number>100</number>
+ </property>
+ <property name="value" >
+ <number>100</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" native="1" name="line1Widget" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>219</y>
+ <width>143</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="Line" name="line1" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" native="1" name="line2Widget" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>292</y>
+ <width>143</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="Line" name="line2" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" native="1" name="zoomButtonsWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>209</x>
+ <y>260</y>
+ <width>64</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Maximum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <layout class="QHBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QToolButton" name="zoomInButton" >
+ <property name="toolTip" >
+ <string>Zoom In</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="zoomOutButton" >
+ <property name="toolTip" >
+ <string>Zoom Out</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>0</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QToolButton" name="detailsButton" >
+ <property name="geometry" >
+ <rect>
+ <x>176</x>
+ <y>40</y>
+ <width>25</width>
+ <height>22</height>
+ </rect>
+ </property>
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Ignored" hsizetype="Fixed" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Toggle details extension</string>
+ </property>
+ <property name="text" >
+ <string>></string>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QToolButton" name="linearButton" >
+ <property name="geometry" >
+ <rect>
+ <x>10</x>
+ <y>10</y>
+ <width>30</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <property name="toolTip" >
+ <string>Linear Type</string>
+ </property>
+ <property name="text" >
+ <string>...</string>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QToolButton" name="radialButton" >
+ <property name="geometry" >
+ <rect>
+ <x>40</x>
+ <y>10</y>
+ <width>30</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <property name="toolTip" >
+ <string>Radial Type</string>
+ </property>
+ <property name="text" >
+ <string>...</string>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QToolButton" name="conicalButton" >
+ <property name="geometry" >
+ <rect>
+ <x>70</x>
+ <y>10</y>
+ <width>30</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <property name="toolTip" >
+ <string>Conical Type</string>
+ </property>
+ <property name="text" >
+ <string>...</string>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QToolButton" name="padButton" >
+ <property name="geometry" >
+ <rect>
+ <x>110</x>
+ <y>10</y>
+ <width>30</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <property name="toolTip" >
+ <string>Pad Spread</string>
+ </property>
+ <property name="text" >
+ <string>...</string>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QToolButton" name="repeatButton" >
+ <property name="geometry" >
+ <rect>
+ <x>140</x>
+ <y>10</y>
+ <width>30</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <property name="toolTip" >
+ <string>Repeat Spread</string>
+ </property>
+ <property name="text" >
+ <string>...</string>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QToolButton" name="reflectButton" >
+ <property name="geometry" >
+ <rect>
+ <x>170</x>
+ <y>10</y>
+ <width>30</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <property name="toolTip" >
+ <string>Reflect Spread</string>
+ </property>
+ <property name="text" >
+ <string>...</string>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QtColorButton</class>
+ <extends>QToolButton</extends>
+ <header>qtcolorbutton.h</header>
+ </customwidget>
+ <customwidget>
+ <class>QtColorLine</class>
+ <extends>QWidget</extends>
+ <header>qtcolorline.h</header>
+ <container>1</container>
+ </customwidget>
+ <customwidget>
+ <class>QtGradientStopsWidget</class>
+ <extends>QWidget</extends>
+ <header>qtgradientstopswidget.h</header>
+ <container>1</container>
+ </customwidget>
+ <customwidget>
+ <class>QtGradientWidget</class>
+ <extends>QWidget</extends>
+ <header>qtgradientwidget.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <tabstops>
+ <tabstop>typeComboBox</tabstop>
+ <tabstop>spreadComboBox</tabstop>
+ <tabstop>detailsButton</tabstop>
+ <tabstop>spinBox1</tabstop>
+ <tabstop>spinBox2</tabstop>
+ <tabstop>spinBox3</tabstop>
+ <tabstop>spinBox4</tabstop>
+ <tabstop>spinBox5</tabstop>
+ <tabstop>zoomSpinBox</tabstop>
+ <tabstop>zoomInButton</tabstop>
+ <tabstop>zoomOutButton</tabstop>
+ <tabstop>zoomAllButton</tabstop>
+ <tabstop>colorButton</tabstop>
+ <tabstop>hsvRadioButton</tabstop>
+ <tabstop>rgbRadioButton</tabstop>
+ <tabstop>positionSpinBox</tabstop>
+ <tabstop>hueSpinBox</tabstop>
+ <tabstop>saturationSpinBox</tabstop>
+ <tabstop>valueSpinBox</tabstop>
+ <tabstop>alphaSpinBox</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/shared/qtgradienteditor/qtgradientmanager.cpp b/src/shared/qtgradienteditor/qtgradientmanager.cpp
new file mode 100644
index 000000000..afa26c042
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientmanager.cpp
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtgradientmanager.h"
+#include <QtGui/QPixmap>
+#include <QtCore/QMetaEnum>
+
+QT_BEGIN_NAMESPACE
+
+QtGradientManager::QtGradientManager(QObject *parent)
+ : QObject(parent)
+{
+}
+
+QMap<QString, QGradient> QtGradientManager::gradients() const
+{
+ return m_idToGradient;
+}
+
+QString QtGradientManager::uniqueId(const QString &id) const
+{
+ if (!m_idToGradient.contains(id))
+ return id;
+
+ QString base = id;
+ while (base.count() > 0 && base.at(base.count() - 1).isDigit())
+ base = base.left(base.count() - 1);
+ QString newId = base;
+ int counter = 0;
+ while (m_idToGradient.contains(newId)) {
+ ++counter;
+ newId = base + QString::number(counter);
+ }
+ return newId;
+}
+
+QString QtGradientManager::addGradient(const QString &id, const QGradient &gradient)
+{
+ QString newId = uniqueId(id);
+
+ m_idToGradient[newId] = gradient;
+
+ emit gradientAdded(newId, gradient);
+
+ return newId;
+}
+
+void QtGradientManager::removeGradient(const QString &id)
+{
+ if (!m_idToGradient.contains(id))
+ return;
+
+ emit gradientRemoved(id);
+
+ m_idToGradient.remove(id);
+}
+
+void QtGradientManager::renameGradient(const QString &id, const QString &newId)
+{
+ if (!m_idToGradient.contains(id))
+ return;
+
+ if (newId == id)
+ return;
+
+ QString changedId = uniqueId(newId);
+ QGradient gradient = m_idToGradient.value(id);
+
+ emit gradientRenamed(id, changedId);
+
+ m_idToGradient.remove(id);
+ m_idToGradient[changedId] = gradient;
+}
+
+void QtGradientManager::changeGradient(const QString &id, const QGradient &newGradient)
+{
+ if (!m_idToGradient.contains(id))
+ return;
+
+ if (m_idToGradient.value(id) == newGradient)
+ return;
+
+ emit gradientChanged(id, newGradient);
+
+ m_idToGradient[id] = newGradient;
+}
+
+void QtGradientManager::clear()
+{
+ QMap<QString, QGradient> grads = gradients();
+ QMapIterator<QString, QGradient> itGrad(grads);
+ while (itGrad.hasNext()) {
+ removeGradient(itGrad.next().key());
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/shared/qtgradienteditor/qtgradientmanager.h b/src/shared/qtgradienteditor/qtgradientmanager.h
new file mode 100644
index 000000000..c0ad6c2b9
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientmanager.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GRADIENTMANAGER_H
+#define GRADIENTMANAGER_H
+
+#include <QtCore/QObject>
+#include <QtCore/QMap>
+#include <QtCore/QSize>
+#include <QtXml/QDomDocument>
+#include <QtXml/QDomElement>
+#include <QtGui/QGradient>
+
+QT_BEGIN_NAMESPACE
+
+class QGradient;
+class QPixmap;
+class QColor;
+
+class QtGradientManager : public QObject
+{
+ Q_OBJECT
+public:
+ QtGradientManager(QObject *parent = 0);
+
+ QMap<QString, QGradient> gradients() const;
+
+ QString uniqueId(const QString &id) const;
+
+public slots:
+
+ QString addGradient(const QString &id, const QGradient &gradient);
+ void renameGradient(const QString &id, const QString &newId);
+ void changeGradient(const QString &id, const QGradient &newGradient);
+ void removeGradient(const QString &id);
+
+ //utils
+ void clear();
+
+signals:
+
+ void gradientAdded(const QString &id, const QGradient &gradient);
+ void gradientRenamed(const QString &id, const QString &newId);
+ void gradientChanged(const QString &id, const QGradient &newGradient);
+ void gradientRemoved(const QString &id);
+
+private:
+
+ QMap<QString, QGradient> m_idToGradient;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtgradienteditor/qtgradientstopscontroller.cpp b/src/shared/qtgradienteditor/qtgradientstopscontroller.cpp
new file mode 100644
index 000000000..0e65e015c
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientstopscontroller.cpp
@@ -0,0 +1,724 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtgradientstopscontroller.h"
+#include "ui_qtgradienteditor.h"
+#include "qtgradientstopsmodel.h"
+
+#include <QtCore/QTimer>
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientStopsControllerPrivate
+{
+ QtGradientStopsController *q_ptr;
+ Q_DECLARE_PUBLIC(QtGradientStopsController)
+public:
+ typedef QMap<qreal, QColor> PositionColorMap;
+ typedef QMap<qreal, QtGradientStop *> PositionStopMap;
+
+ void slotHsvClicked();
+ void slotRgbClicked();
+
+ void slotCurrentStopChanged(QtGradientStop *stop);
+ void slotStopMoved(QtGradientStop *stop, qreal newPos);
+ void slotStopsSwapped(QtGradientStop *stop1, QtGradientStop *stop2);
+ void slotStopChanged(QtGradientStop *stop, const QColor &newColor);
+ void slotStopSelected(QtGradientStop *stop, bool selected);
+ void slotStopAdded(QtGradientStop *stop);
+ void slotStopRemoved(QtGradientStop *stop);
+ void slotUpdatePositionSpinBox();
+
+ void slotChangeColor(const QColor &color);
+ void slotChangeHue(const QColor &color);
+ void slotChangeSaturation(const QColor &color);
+ void slotChangeValue(const QColor &color);
+ void slotChangeAlpha(const QColor &color);
+ void slotChangeHue(int color);
+ void slotChangeSaturation(int color);
+ void slotChangeValue(int color);
+ void slotChangeAlpha(int color);
+ void slotChangePosition(double value);
+
+ void slotChangeZoom(int value);
+ void slotZoomIn();
+ void slotZoomOut();
+ void slotZoomAll();
+ void slotZoomChanged(double zoom);
+
+ void enableCurrent(bool enable);
+ void setColorSpinBoxes(const QColor &color);
+ PositionColorMap stopsData(const PositionStopMap &stops) const;
+ QGradientStops makeGradientStops(const PositionColorMap &data) const;
+ void updateZoom(double zoom);
+
+ QtGradientStopsModel *m_model;
+ QColor::Spec m_spec;
+
+ Ui::QtGradientEditor *m_ui;
+};
+
+void QtGradientStopsControllerPrivate::enableCurrent(bool enable)
+{
+ m_ui->positionLabel->setEnabled(enable);
+ m_ui->colorLabel->setEnabled(enable);
+ m_ui->hLabel->setEnabled(enable);
+ m_ui->sLabel->setEnabled(enable);
+ m_ui->vLabel->setEnabled(enable);
+ m_ui->aLabel->setEnabled(enable);
+ m_ui->hueLabel->setEnabled(enable);
+ m_ui->saturationLabel->setEnabled(enable);
+ m_ui->valueLabel->setEnabled(enable);
+ m_ui->alphaLabel->setEnabled(enable);
+
+ m_ui->positionSpinBox->setEnabled(enable);
+ m_ui->colorButton->setEnabled(enable);
+
+ m_ui->hueColorLine->setEnabled(enable);
+ m_ui->saturationColorLine->setEnabled(enable);
+ m_ui->valueColorLine->setEnabled(enable);
+ m_ui->alphaColorLine->setEnabled(enable);
+
+ m_ui->hueSpinBox->setEnabled(enable);
+ m_ui->saturationSpinBox->setEnabled(enable);
+ m_ui->valueSpinBox->setEnabled(enable);
+ m_ui->alphaSpinBox->setEnabled(enable);
+}
+
+QtGradientStopsControllerPrivate::PositionColorMap QtGradientStopsControllerPrivate::stopsData(const PositionStopMap &stops) const
+{
+ PositionColorMap data;
+ PositionStopMap::ConstIterator itStop = stops.constBegin();
+ while (itStop != stops.constEnd()) {
+ QtGradientStop *stop = itStop.value();
+ data[stop->position()] = stop->color();
+
+ ++itStop;
+ }
+ return data;
+}
+
+QGradientStops QtGradientStopsControllerPrivate::makeGradientStops(const PositionColorMap &data) const
+{
+ QGradientStops stops;
+ PositionColorMap::ConstIterator itData = data.constBegin();
+ while (itData != data.constEnd()) {
+ stops << QPair<qreal, QColor>(itData.key(), itData.value());
+
+ ++itData;
+ }
+ return stops;
+}
+
+void QtGradientStopsControllerPrivate::updateZoom(double zoom)
+{
+ m_ui->gradientStopsWidget->setZoom(zoom);
+ m_ui->zoomSpinBox->blockSignals(true);
+ m_ui->zoomSpinBox->setValue(qRound(zoom * 100));
+ m_ui->zoomSpinBox->blockSignals(false);
+ bool zoomInEnabled = true;
+ bool zoomOutEnabled = true;
+ bool zoomAllEnabled = true;
+ if (zoom <= 1) {
+ zoomAllEnabled = false;
+ zoomOutEnabled = false;
+ } else if (zoom >= 100) {
+ zoomInEnabled = false;
+ }
+ m_ui->zoomInButton->setEnabled(zoomInEnabled);
+ m_ui->zoomOutButton->setEnabled(zoomOutEnabled);
+ m_ui->zoomAllButton->setEnabled(zoomAllEnabled);
+}
+
+void QtGradientStopsControllerPrivate::slotHsvClicked()
+{
+ QString h = QApplication::translate("qdesigner_internal::QtGradientStopsController", "H", 0, QApplication::UnicodeUTF8);
+ QString s = QApplication::translate("qdesigner_internal::QtGradientStopsController", "S", 0, QApplication::UnicodeUTF8);
+ QString v = QApplication::translate("qdesigner_internal::QtGradientStopsController", "V", 0, QApplication::UnicodeUTF8);
+
+ m_ui->hLabel->setText(h);
+ m_ui->sLabel->setText(s);
+ m_ui->vLabel->setText(v);
+
+ h = QApplication::translate("qdesigner_internal::QtGradientStopsController", "Hue", 0, QApplication::UnicodeUTF8);
+ s = QApplication::translate("qdesigner_internal::QtGradientStopsController", "Sat", 0, QApplication::UnicodeUTF8);
+ v = QApplication::translate("qdesigner_internal::QtGradientStopsController", "Val", 0, QApplication::UnicodeUTF8);
+
+ const QString hue = QApplication::translate("qdesigner_internal::QtGradientStopsController", "Hue", 0, QApplication::UnicodeUTF8);
+ const QString saturation = QApplication::translate("qdesigner_internal::QtGradientStopsController", "Saturation", 0, QApplication::UnicodeUTF8);
+ const QString value = QApplication::translate("qdesigner_internal::QtGradientStopsController", "Value", 0, QApplication::UnicodeUTF8);
+
+ m_ui->hLabel->setToolTip(hue);
+ m_ui->hueLabel->setText(h);
+ m_ui->hueColorLine->setToolTip(hue);
+ m_ui->hueColorLine->setColorComponent(QtColorLine::Hue);
+
+ m_ui->sLabel->setToolTip(saturation);
+ m_ui->saturationLabel->setText(s);
+ m_ui->saturationColorLine->setToolTip(saturation);
+ m_ui->saturationColorLine->setColorComponent(QtColorLine::Saturation);
+
+ m_ui->vLabel->setToolTip(value);
+ m_ui->valueLabel->setText(v);
+ m_ui->valueColorLine->setToolTip(value);
+ m_ui->valueColorLine->setColorComponent(QtColorLine::Value);
+
+ setColorSpinBoxes(m_ui->colorButton->color());
+}
+
+void QtGradientStopsControllerPrivate::slotRgbClicked()
+{
+ QString r = QApplication::translate("qdesigner_internal::QtGradientStopsController", "R", 0, QApplication::UnicodeUTF8);
+ QString g = QApplication::translate("qdesigner_internal::QtGradientStopsController", "G", 0, QApplication::UnicodeUTF8);
+ QString b = QApplication::translate("qdesigner_internal::QtGradientStopsController", "B", 0, QApplication::UnicodeUTF8);
+
+ m_ui->hLabel->setText(r);
+ m_ui->sLabel->setText(g);
+ m_ui->vLabel->setText(b);
+
+ QString red = QApplication::translate("qdesigner_internal::QtGradientStopsController", "Red", 0, QApplication::UnicodeUTF8);
+ QString green = QApplication::translate("qdesigner_internal::QtGradientStopsController", "Green", 0, QApplication::UnicodeUTF8);
+ QString blue = QApplication::translate("qdesigner_internal::QtGradientStopsController", "Blue", 0, QApplication::UnicodeUTF8);
+
+ m_ui->hLabel->setToolTip(red);
+ m_ui->hueLabel->setText(red);
+ m_ui->hueColorLine->setToolTip(red);
+ m_ui->hueColorLine->setColorComponent(QtColorLine::Red);
+
+ m_ui->sLabel->setToolTip(green);
+ m_ui->saturationLabel->setText(green);
+ m_ui->saturationColorLine->setToolTip(green);
+ m_ui->saturationColorLine->setColorComponent(QtColorLine::Green);
+
+ m_ui->vLabel->setToolTip(blue);
+ m_ui->valueLabel->setText(blue);
+ m_ui->valueColorLine->setToolTip(blue);
+ m_ui->valueColorLine->setColorComponent(QtColorLine::Blue);
+
+ setColorSpinBoxes(m_ui->colorButton->color());
+}
+
+void QtGradientStopsControllerPrivate::setColorSpinBoxes(const QColor &color)
+{
+ m_ui->hueSpinBox->blockSignals(true);
+ m_ui->saturationSpinBox->blockSignals(true);
+ m_ui->valueSpinBox->blockSignals(true);
+ m_ui->alphaSpinBox->blockSignals(true);
+ if (m_ui->hsvRadioButton->isChecked()) {
+ if (m_ui->hueSpinBox->maximum() != 359)
+ m_ui->hueSpinBox->setMaximum(359);
+ if (m_ui->hueSpinBox->value() != color.hue())
+ m_ui->hueSpinBox->setValue(color.hue());
+ if (m_ui->saturationSpinBox->value() != color.saturation())
+ m_ui->saturationSpinBox->setValue(color.saturation());
+ if (m_ui->valueSpinBox->value() != color.value())
+ m_ui->valueSpinBox->setValue(color.value());
+ } else {
+ if (m_ui->hueSpinBox->maximum() != 255)
+ m_ui->hueSpinBox->setMaximum(255);
+ if (m_ui->hueSpinBox->value() != color.red())
+ m_ui->hueSpinBox->setValue(color.red());
+ if (m_ui->saturationSpinBox->value() != color.green())
+ m_ui->saturationSpinBox->setValue(color.green());
+ if (m_ui->valueSpinBox->value() != color.blue())
+ m_ui->valueSpinBox->setValue(color.blue());
+ }
+ m_ui->alphaSpinBox->setValue(color.alpha());
+ m_ui->hueSpinBox->blockSignals(false);
+ m_ui->saturationSpinBox->blockSignals(false);
+ m_ui->valueSpinBox->blockSignals(false);
+ m_ui->alphaSpinBox->blockSignals(false);
+}
+
+void QtGradientStopsControllerPrivate::slotCurrentStopChanged(QtGradientStop *stop)
+{
+ if (!stop) {
+ enableCurrent(false);
+ return;
+ }
+ enableCurrent(true);
+
+ QTimer::singleShot(0, q_ptr, SLOT(slotUpdatePositionSpinBox()));
+
+ m_ui->colorButton->setColor(stop->color());
+ m_ui->hueColorLine->setColor(stop->color());
+ m_ui->saturationColorLine->setColor(stop->color());
+ m_ui->valueColorLine->setColor(stop->color());
+ m_ui->alphaColorLine->setColor(stop->color());
+ setColorSpinBoxes(stop->color());
+}
+
+void QtGradientStopsControllerPrivate::slotStopMoved(QtGradientStop *stop, qreal newPos)
+{
+ QTimer::singleShot(0, q_ptr, SLOT(slotUpdatePositionSpinBox()));
+
+ PositionColorMap stops = stopsData(m_model->stops());
+ stops.remove(stop->position());
+ stops[newPos] = stop->color();
+
+ QGradientStops gradStops = makeGradientStops(stops);
+ emit q_ptr->gradientStopsChanged(gradStops);
+}
+
+void QtGradientStopsControllerPrivate::slotStopsSwapped(QtGradientStop *stop1, QtGradientStop *stop2)
+{
+ QTimer::singleShot(0, q_ptr, SLOT(slotUpdatePositionSpinBox()));
+
+ PositionColorMap stops = stopsData(m_model->stops());
+ const qreal pos1 = stop1->position();
+ const qreal pos2 = stop2->position();
+ stops[pos1] = stop2->color();
+ stops[pos2] = stop1->color();
+
+ QGradientStops gradStops = makeGradientStops(stops);
+ emit q_ptr->gradientStopsChanged(gradStops);
+}
+
+void QtGradientStopsControllerPrivate::slotStopAdded(QtGradientStop *stop)
+{
+ PositionColorMap stops = stopsData(m_model->stops());
+ stops[stop->position()] = stop->color();
+
+ QGradientStops gradStops = makeGradientStops(stops);
+ emit q_ptr->gradientStopsChanged(gradStops);
+}
+
+void QtGradientStopsControllerPrivate::slotStopRemoved(QtGradientStop *stop)
+{
+ PositionColorMap stops = stopsData(m_model->stops());
+ stops.remove(stop->position());
+
+ QGradientStops gradStops = makeGradientStops(stops);
+ emit q_ptr->gradientStopsChanged(gradStops);
+}
+
+void QtGradientStopsControllerPrivate::slotStopChanged(QtGradientStop *stop, const QColor &newColor)
+{
+ if (m_model->currentStop() == stop) {
+ m_ui->colorButton->setColor(newColor);
+ m_ui->hueColorLine->setColor(newColor);
+ m_ui->saturationColorLine->setColor(newColor);
+ m_ui->valueColorLine->setColor(newColor);
+ m_ui->alphaColorLine->setColor(newColor);
+ setColorSpinBoxes(newColor);
+ }
+
+ PositionColorMap stops = stopsData(m_model->stops());
+ stops[stop->position()] = newColor;
+
+ QGradientStops gradStops = makeGradientStops(stops);
+ emit q_ptr->gradientStopsChanged(gradStops);
+}
+
+void QtGradientStopsControllerPrivate::slotStopSelected(QtGradientStop *stop, bool selected)
+{
+ Q_UNUSED(stop)
+ Q_UNUSED(selected)
+ QTimer::singleShot(0, q_ptr, SLOT(slotUpdatePositionSpinBox()));
+}
+
+void QtGradientStopsControllerPrivate::slotUpdatePositionSpinBox()
+{
+ QtGradientStop *current = m_model->currentStop();
+ if (!current)
+ return;
+
+ qreal min = 0.0;
+ qreal max = 1.0;
+ const qreal pos = current->position();
+
+ QtGradientStop *first = m_model->firstSelected();
+ QtGradientStop *last = m_model->lastSelected();
+
+ if (first && last) {
+ const qreal minPos = pos - first->position() - 0.0004999;
+ const qreal maxPos = pos + 1.0 - last->position() + 0.0004999;
+
+ if (max > maxPos)
+ max = maxPos;
+ if (min < minPos)
+ min = minPos;
+
+ if (first->position() == 0.0)
+ min = pos;
+ if (last->position() == 1.0)
+ max = pos;
+ }
+
+ const int spinMin = qRound(m_ui->positionSpinBox->minimum() * 1000);
+ const int spinMax = qRound(m_ui->positionSpinBox->maximum() * 1000);
+
+ const int newMin = qRound(min * 1000);
+ const int newMax = qRound(max * 1000);
+
+ m_ui->positionSpinBox->blockSignals(true);
+ if (spinMin != newMin || spinMax != newMax) {
+ m_ui->positionSpinBox->setRange((double)newMin / 1000, (double)newMax / 1000);
+ }
+ if (m_ui->positionSpinBox->value() != pos)
+ m_ui->positionSpinBox->setValue(pos);
+ m_ui->positionSpinBox->blockSignals(false);
+}
+
+void QtGradientStopsControllerPrivate::slotChangeColor(const QColor &color)
+{
+ QtGradientStop *stop = m_model->currentStop();
+ if (!stop)
+ return;
+ m_model->changeStop(stop, color);
+ QList<QtGradientStop *> stops = m_model->selectedStops();
+ QListIterator<QtGradientStop *> itStop(stops);
+ while (itStop.hasNext()) {
+ QtGradientStop *s = itStop.next();
+ if (s != stop)
+ m_model->changeStop(s, color);
+ }
+}
+
+void QtGradientStopsControllerPrivate::slotChangeHue(const QColor &color)
+{
+ QtGradientStop *stop = m_model->currentStop();
+ if (!stop)
+ return;
+ m_model->changeStop(stop, color);
+ QList<QtGradientStop *> stops = m_model->selectedStops();
+ QListIterator<QtGradientStop *> itStop(stops);
+ while (itStop.hasNext()) {
+ QtGradientStop *s = itStop.next();
+ if (s != stop) {
+ QColor c = s->color();
+ if (m_ui->hsvRadioButton->isChecked())
+ c.setHsvF(color.hueF(), c.saturationF(), c.valueF(), c.alphaF());
+ else
+ c.setRgbF(color.redF(), c.greenF(), c.blueF(), c.alphaF());
+ m_model->changeStop(s, c);
+ }
+ }
+}
+
+void QtGradientStopsControllerPrivate::slotChangeHue(int color)
+{
+ QColor c = m_ui->hueColorLine->color();
+ if (m_ui->hsvRadioButton->isChecked())
+ c.setHsvF((qreal)color / 360.0, c.saturationF(), c.valueF(), c.alphaF());
+ else
+ c.setRed(color);
+ slotChangeHue(c);
+}
+
+void QtGradientStopsControllerPrivate::slotChangeSaturation(const QColor &color)
+{
+ QtGradientStop *stop = m_model->currentStop();
+ if (!stop)
+ return;
+ m_model->changeStop(stop, color);
+ QList<QtGradientStop *> stops = m_model->selectedStops();
+ QListIterator<QtGradientStop *> itStop(stops);
+ while (itStop.hasNext()) {
+ QtGradientStop *s = itStop.next();
+ if (s != stop) {
+ QColor c = s->color();
+ if (m_ui->hsvRadioButton->isChecked()) {
+ c.setHsvF(c.hueF(), color.saturationF(), c.valueF(), c.alphaF());
+ int hue = c.hue();
+ if (hue == 360 || hue == -1)
+ c.setHsvF(0.0, c.saturationF(), c.valueF(), c.alphaF());
+ } else {
+ c.setRgbF(c.redF(), color.greenF(), c.blueF(), c.alphaF());
+ }
+ m_model->changeStop(s, c);
+ }
+ }
+}
+
+void QtGradientStopsControllerPrivate::slotChangeSaturation(int color)
+{
+ QColor c = m_ui->saturationColorLine->color();
+ if (m_ui->hsvRadioButton->isChecked())
+ c.setHsvF(c.hueF(), (qreal)color / 255, c.valueF(), c.alphaF());
+ else
+ c.setGreen(color);
+ slotChangeSaturation(c);
+}
+
+void QtGradientStopsControllerPrivate::slotChangeValue(const QColor &color)
+{
+ QtGradientStop *stop = m_model->currentStop();
+ if (!stop)
+ return;
+ m_model->changeStop(stop, color);
+ QList<QtGradientStop *> stops = m_model->selectedStops();
+ QListIterator<QtGradientStop *> itStop(stops);
+ while (itStop.hasNext()) {
+ QtGradientStop *s = itStop.next();
+ if (s != stop) {
+ QColor c = s->color();
+ if (m_ui->hsvRadioButton->isChecked()) {
+ c.setHsvF(c.hueF(), c.saturationF(), color.valueF(), c.alphaF());
+ int hue = c.hue();
+ if (hue == 360 || hue == -1)
+ c.setHsvF(0.0, c.saturationF(), c.valueF(), c.alphaF());
+ } else {
+ c.setRgbF(c.redF(), c.greenF(), color.blueF(), c.alphaF());
+ }
+ m_model->changeStop(s, c);
+ }
+ }
+}
+
+void QtGradientStopsControllerPrivate::slotChangeValue(int color)
+{
+ QColor c = m_ui->valueColorLine->color();
+ if (m_ui->hsvRadioButton->isChecked())
+ c.setHsvF(c.hueF(), c.saturationF(), (qreal)color / 255, c.alphaF());
+ else
+ c.setBlue(color);
+ slotChangeValue(c);
+}
+
+void QtGradientStopsControllerPrivate::slotChangeAlpha(const QColor &color)
+{
+ QtGradientStop *stop = m_model->currentStop();
+ if (!stop)
+ return;
+ m_model->changeStop(stop, color);
+ QList<QtGradientStop *> stops = m_model->selectedStops();
+ QListIterator<QtGradientStop *> itStop(stops);
+ while (itStop.hasNext()) {
+ QtGradientStop *s = itStop.next();
+ if (s != stop) {
+ QColor c = s->color();
+ if (m_ui->hsvRadioButton->isChecked()) {
+ c.setHsvF(c.hueF(), c.saturationF(), c.valueF(), color.alphaF());
+ int hue = c.hue();
+ if (hue == 360 || hue == -1)
+ c.setHsvF(0.0, c.saturationF(), c.valueF(), c.alphaF());
+ } else {
+ c.setRgbF(c.redF(), c.greenF(), c.blueF(), color.alphaF());
+ }
+ m_model->changeStop(s, c);
+ }
+ }
+}
+
+void QtGradientStopsControllerPrivate::slotChangeAlpha(int color)
+{
+ QColor c = m_ui->alphaColorLine->color();
+ if (m_ui->hsvRadioButton->isChecked())
+ c.setHsvF(c.hueF(), c.saturationF(), c.valueF(), (qreal)color / 255);
+ else
+ c.setAlpha(color);
+ slotChangeAlpha(c);
+}
+
+void QtGradientStopsControllerPrivate::slotChangePosition(double value)
+{
+ QtGradientStop *stop = m_model->currentStop();
+ if (!stop)
+ return;
+
+ m_model->moveStops(value);
+}
+
+void QtGradientStopsControllerPrivate::slotChangeZoom(int value)
+{
+ updateZoom(value / 100.0);
+}
+
+void QtGradientStopsControllerPrivate::slotZoomIn()
+{
+ double newZoom = m_ui->gradientStopsWidget->zoom() * 2;
+ if (newZoom > 100)
+ newZoom = 100;
+ updateZoom(newZoom);
+}
+
+void QtGradientStopsControllerPrivate::slotZoomOut()
+{
+ double newZoom = m_ui->gradientStopsWidget->zoom() / 2;
+ if (newZoom < 1)
+ newZoom = 1;
+ updateZoom(newZoom);
+}
+
+void QtGradientStopsControllerPrivate::slotZoomAll()
+{
+ updateZoom(1);
+}
+
+void QtGradientStopsControllerPrivate::slotZoomChanged(double zoom)
+{
+ updateZoom(zoom);
+}
+
+QtGradientStopsController::QtGradientStopsController(QObject *parent)
+ : QObject(parent), d_ptr(new QtGradientStopsControllerPrivate())
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->m_spec = QColor::Hsv;
+}
+
+void QtGradientStopsController::setUi(Ui::QtGradientEditor *ui)
+{
+ d_ptr->m_ui = ui;
+
+ d_ptr->m_ui->hueColorLine->setColorComponent(QtColorLine::Hue);
+ d_ptr->m_ui->saturationColorLine->setColorComponent(QtColorLine::Saturation);
+ d_ptr->m_ui->valueColorLine->setColorComponent(QtColorLine::Value);
+ d_ptr->m_ui->alphaColorLine->setColorComponent(QtColorLine::Alpha);
+
+ d_ptr->m_model = new QtGradientStopsModel(this);
+ d_ptr->m_ui->gradientStopsWidget->setGradientStopsModel(d_ptr->m_model);
+ connect(d_ptr->m_model, SIGNAL(currentStopChanged(QtGradientStop*)),
+ this, SLOT(slotCurrentStopChanged(QtGradientStop*)));
+ connect(d_ptr->m_model, SIGNAL(stopMoved(QtGradientStop*,qreal)),
+ this, SLOT(slotStopMoved(QtGradientStop*,qreal)));
+ connect(d_ptr->m_model, SIGNAL(stopsSwapped(QtGradientStop*,QtGradientStop*)),
+ this, SLOT(slotStopsSwapped(QtGradientStop*,QtGradientStop*)));
+ connect(d_ptr->m_model, SIGNAL(stopChanged(QtGradientStop*,QColor)),
+ this, SLOT(slotStopChanged(QtGradientStop*,QColor)));
+ connect(d_ptr->m_model, SIGNAL(stopSelected(QtGradientStop*,bool)),
+ this, SLOT(slotStopSelected(QtGradientStop*,bool)));
+ connect(d_ptr->m_model, SIGNAL(stopAdded(QtGradientStop*)),
+ this, SLOT(slotStopAdded(QtGradientStop*)));
+ connect(d_ptr->m_model, SIGNAL(stopRemoved(QtGradientStop*)),
+ this, SLOT(slotStopRemoved(QtGradientStop*)));
+
+ connect(d_ptr->m_ui->hueColorLine, SIGNAL(colorChanged(QColor)),
+ this, SLOT(slotChangeHue(QColor)));
+ connect(d_ptr->m_ui->saturationColorLine, SIGNAL(colorChanged(QColor)),
+ this, SLOT(slotChangeSaturation(QColor)));
+ connect(d_ptr->m_ui->valueColorLine, SIGNAL(colorChanged(QColor)),
+ this, SLOT(slotChangeValue(QColor)));
+ connect(d_ptr->m_ui->alphaColorLine, SIGNAL(colorChanged(QColor)),
+ this, SLOT(slotChangeAlpha(QColor)));
+ connect(d_ptr->m_ui->colorButton, SIGNAL(colorChanged(QColor)),
+ this, SLOT(slotChangeColor(QColor)));
+
+ connect(d_ptr->m_ui->hueSpinBox, SIGNAL(valueChanged(int)),
+ this, SLOT(slotChangeHue(int)));
+ connect(d_ptr->m_ui->saturationSpinBox, SIGNAL(valueChanged(int)),
+ this, SLOT(slotChangeSaturation(int)));
+ connect(d_ptr->m_ui->valueSpinBox, SIGNAL(valueChanged(int)),
+ this, SLOT(slotChangeValue(int)));
+ connect(d_ptr->m_ui->alphaSpinBox, SIGNAL(valueChanged(int)),
+ this, SLOT(slotChangeAlpha(int)));
+
+ connect(d_ptr->m_ui->positionSpinBox, SIGNAL(valueChanged(double)),
+ this, SLOT(slotChangePosition(double)));
+
+ connect(d_ptr->m_ui->zoomSpinBox, SIGNAL(valueChanged(int)),
+ this, SLOT(slotChangeZoom(int)));
+ connect(d_ptr->m_ui->zoomInButton, SIGNAL(clicked()),
+ this, SLOT(slotZoomIn()));
+ connect(d_ptr->m_ui->zoomOutButton, SIGNAL(clicked()),
+ this, SLOT(slotZoomOut()));
+ connect(d_ptr->m_ui->zoomAllButton, SIGNAL(clicked()),
+ this, SLOT(slotZoomAll()));
+ connect(d_ptr->m_ui->gradientStopsWidget, SIGNAL(zoomChanged(double)),
+ this, SLOT(slotZoomChanged(double)));
+
+ connect(d_ptr->m_ui->hsvRadioButton, SIGNAL(clicked()),
+ this, SLOT(slotHsvClicked()));
+ connect(d_ptr->m_ui->rgbRadioButton, SIGNAL(clicked()),
+ this, SLOT(slotRgbClicked()));
+
+ d_ptr->enableCurrent(false);
+ d_ptr->m_ui->zoomInButton->setIcon(QIcon(QLatin1String(":/trolltech/qtgradienteditor/images/zoomin.png")));
+ d_ptr->m_ui->zoomOutButton->setIcon(QIcon(QLatin1String(":/trolltech/qtgradienteditor/images/zoomout.png")));
+ d_ptr->updateZoom(1);
+}
+
+QtGradientStopsController::~QtGradientStopsController()
+{
+}
+
+void QtGradientStopsController::setGradientStops(const QGradientStops &stops)
+{
+ d_ptr->m_model->clear();
+ QVectorIterator<QPair<qreal, QColor> > it(stops);
+ QtGradientStop *first = 0;
+ while (it.hasNext()) {
+ QPair<qreal, QColor> pair = it.next();
+ QtGradientStop *stop = d_ptr->m_model->addStop(pair.first, pair.second);
+ if (!first)
+ first = stop;
+ }
+ if (first)
+ d_ptr->m_model->setCurrentStop(first);
+}
+
+QGradientStops QtGradientStopsController::gradientStops() const
+{
+ QGradientStops stops;
+ QList<QtGradientStop *> stopsList = d_ptr->m_model->stops().values();
+ QListIterator<QtGradientStop *> itStop(stopsList);
+ while (itStop.hasNext()) {
+ QtGradientStop *stop = itStop.next();
+ stops << QPair<qreal, QColor>(stop->position(), stop->color());
+ }
+ return stops;
+}
+
+QColor::Spec QtGradientStopsController::spec() const
+{
+ return d_ptr->m_spec;
+}
+
+void QtGradientStopsController::setSpec(QColor::Spec spec)
+{
+ if (d_ptr->m_spec == spec)
+ return;
+
+ d_ptr->m_spec = spec;
+ if (d_ptr->m_spec == QColor::Rgb) {
+ d_ptr->m_ui->rgbRadioButton->setChecked(true);
+ d_ptr->slotRgbClicked();
+ } else {
+ d_ptr->m_ui->hsvRadioButton->setChecked(true);
+ d_ptr->slotHsvClicked();
+ }
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qtgradientstopscontroller.cpp"
diff --git a/src/shared/qtgradienteditor/qtgradientstopscontroller.h b/src/shared/qtgradienteditor/qtgradientstopscontroller.h
new file mode 100644
index 000000000..1ae96aafe
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientstopscontroller.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTGRADIENTSTOPSCONTROLLER_H
+#define QTGRADIENTSTOPSCONTROLLER_H
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+namespace Ui {
+ class QtGradientEditor;
+}
+
+class QtGradientStopsController : public QObject
+{
+ Q_OBJECT
+public:
+ QtGradientStopsController(QObject *parent = 0);
+ ~QtGradientStopsController();
+
+ void setUi(Ui::QtGradientEditor *editor);
+
+ void setGradientStops(const QGradientStops &stops);
+ QGradientStops gradientStops() const;
+
+ QColor::Spec spec() const;
+ void setSpec(QColor::Spec spec);
+
+signals:
+
+ void gradientStopsChanged(const QGradientStops &stops);
+
+private:
+ QScopedPointer<class QtGradientStopsControllerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtGradientStopsController)
+ Q_DISABLE_COPY(QtGradientStopsController)
+ Q_PRIVATE_SLOT(d_func(), void slotHsvClicked())
+ Q_PRIVATE_SLOT(d_func(), void slotRgbClicked())
+ Q_PRIVATE_SLOT(d_func(), void slotCurrentStopChanged(QtGradientStop *stop))
+ Q_PRIVATE_SLOT(d_func(), void slotStopMoved(QtGradientStop *stop, qreal newPos))
+ Q_PRIVATE_SLOT(d_func(), void slotStopsSwapped(QtGradientStop *stop1, QtGradientStop *stop2))
+ Q_PRIVATE_SLOT(d_func(), void slotStopChanged(QtGradientStop *stop, const QColor &newColor))
+ Q_PRIVATE_SLOT(d_func(), void slotStopSelected(QtGradientStop *stop, bool selected))
+ Q_PRIVATE_SLOT(d_func(), void slotStopAdded(QtGradientStop *stop))
+ Q_PRIVATE_SLOT(d_func(), void slotStopRemoved(QtGradientStop *stop))
+ Q_PRIVATE_SLOT(d_func(), void slotUpdatePositionSpinBox())
+ Q_PRIVATE_SLOT(d_func(), void slotChangeColor(const QColor &color))
+ Q_PRIVATE_SLOT(d_func(), void slotChangeHue(const QColor &color))
+ Q_PRIVATE_SLOT(d_func(), void slotChangeSaturation(const QColor &color))
+ Q_PRIVATE_SLOT(d_func(), void slotChangeValue(const QColor &color))
+ Q_PRIVATE_SLOT(d_func(), void slotChangeAlpha(const QColor &color))
+ Q_PRIVATE_SLOT(d_func(), void slotChangeHue(int))
+ Q_PRIVATE_SLOT(d_func(), void slotChangeSaturation(int))
+ Q_PRIVATE_SLOT(d_func(), void slotChangeValue(int))
+ Q_PRIVATE_SLOT(d_func(), void slotChangeAlpha(int))
+ //Q_PRIVATE_SLOT(d_func(), void slotChangePosition(double newPos))
+ Q_PRIVATE_SLOT(d_func(), void slotChangePosition(double value))
+ Q_PRIVATE_SLOT(d_func(), void slotChangeZoom(int value))
+ Q_PRIVATE_SLOT(d_func(), void slotZoomIn())
+ Q_PRIVATE_SLOT(d_func(), void slotZoomOut())
+ Q_PRIVATE_SLOT(d_func(), void slotZoomAll())
+ Q_PRIVATE_SLOT(d_func(), void slotZoomChanged(double))
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtgradienteditor/qtgradientstopsmodel.cpp b/src/shared/qtgradienteditor/qtgradientstopsmodel.cpp
new file mode 100644
index 000000000..427e6eed3
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientstopsmodel.cpp
@@ -0,0 +1,477 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtgradientstopsmodel.h"
+#include <QtGui/QColor>
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientStopPrivate
+{
+public:
+ qreal m_position;
+ QColor m_color;
+ QtGradientStopsModel *m_model;
+};
+
+qreal QtGradientStop::position() const
+{
+ return d_ptr->m_position;
+}
+
+QColor QtGradientStop::color() const
+{
+ return d_ptr->m_color;
+}
+
+QtGradientStopsModel *QtGradientStop::gradientModel() const
+{
+ return d_ptr->m_model;
+}
+
+void QtGradientStop::setColor(const QColor &color)
+{
+ d_ptr->m_color = color;
+}
+
+void QtGradientStop::setPosition(qreal position)
+{
+ d_ptr->m_position = position;
+}
+
+QtGradientStop::QtGradientStop(QtGradientStopsModel *model)
+ : d_ptr(new QtGradientStopPrivate())
+{
+ d_ptr->m_position = 0;
+ d_ptr->m_color = Qt::white;
+ d_ptr->m_model = model;
+}
+
+QtGradientStop::~QtGradientStop()
+{
+}
+
+class QtGradientStopsModelPrivate
+{
+ QtGradientStopsModel *q_ptr;
+ Q_DECLARE_PUBLIC(QtGradientStopsModel)
+public:
+ QMap<qreal, QtGradientStop *> m_posToStop;
+ QMap<QtGradientStop *, qreal> m_stopToPos;
+ QMap<QtGradientStop *, bool> m_selection;
+ QtGradientStop *m_current;
+};
+
+
+
+QtGradientStopsModel::QtGradientStopsModel(QObject *parent)
+ : QObject(parent), d_ptr(new QtGradientStopsModelPrivate)
+{
+ d_ptr->q_ptr = this;
+ d_ptr->m_current = 0;
+}
+
+QtGradientStopsModel::~QtGradientStopsModel()
+{
+ clear();
+}
+
+QtGradientStopsModel::PositionStopMap QtGradientStopsModel::stops() const
+{
+ return d_ptr->m_posToStop;
+}
+
+QtGradientStop *QtGradientStopsModel::at(qreal pos) const
+{
+ if (d_ptr->m_posToStop.contains(pos))
+ return d_ptr->m_posToStop[pos];
+ return 0;
+}
+
+QColor QtGradientStopsModel::color(qreal pos) const
+{
+ PositionStopMap gradStops = stops();
+ if (gradStops.isEmpty())
+ return QColor::fromRgbF(pos, pos, pos, 1.0);
+ if (gradStops.contains(pos))
+ return gradStops[pos]->color();
+
+ gradStops[pos] = 0;
+ PositionStopMap::ConstIterator itStop = gradStops.constFind(pos);
+ if (itStop == gradStops.constBegin()) {
+ ++itStop;
+ return itStop.value()->color();
+ }
+ if (itStop == --gradStops.constEnd()) {
+ --itStop;
+ return itStop.value()->color();
+ }
+ PositionStopMap::ConstIterator itPrev = itStop;
+ PositionStopMap::ConstIterator itNext = itStop;
+ --itPrev;
+ ++itNext;
+
+ double prevX = itPrev.key();
+ double nextX = itNext.key();
+
+ double coefX = (pos - prevX) / (nextX - prevX);
+ QColor prevCol = itPrev.value()->color();
+ QColor nextCol = itNext.value()->color();
+
+ QColor newColor;
+ newColor.setRgbF((nextCol.redF() - prevCol.redF() ) * coefX + prevCol.redF(),
+ (nextCol.greenF() - prevCol.greenF()) * coefX + prevCol.greenF(),
+ (nextCol.blueF() - prevCol.blueF() ) * coefX + prevCol.blueF(),
+ (nextCol.alphaF() - prevCol.alphaF()) * coefX + prevCol.alphaF());
+ return newColor;
+}
+
+QList<QtGradientStop *> QtGradientStopsModel::selectedStops() const
+{
+ return d_ptr->m_selection.keys();
+}
+
+QtGradientStop *QtGradientStopsModel::currentStop() const
+{
+ return d_ptr->m_current;
+}
+
+bool QtGradientStopsModel::isSelected(QtGradientStop *stop) const
+{
+ if (d_ptr->m_selection.contains(stop))
+ return true;
+ return false;
+}
+
+QtGradientStop *QtGradientStopsModel::addStop(qreal pos, const QColor &color)
+{
+ qreal newPos = pos;
+ if (pos < 0.0)
+ newPos = 0.0;
+ if (pos > 1.0)
+ newPos = 1.0;
+ if (d_ptr->m_posToStop.contains(newPos))
+ return 0;
+ QtGradientStop *stop = new QtGradientStop();
+ stop->setPosition(newPos);
+ stop->setColor(color);
+
+ d_ptr->m_posToStop[newPos] = stop;
+ d_ptr->m_stopToPos[stop] = newPos;
+
+ emit stopAdded(stop);
+
+ return stop;
+}
+
+void QtGradientStopsModel::removeStop(QtGradientStop *stop)
+{
+ if (!d_ptr->m_stopToPos.contains(stop))
+ return;
+ if (currentStop() == stop)
+ setCurrentStop(0);
+ selectStop(stop, false);
+
+ emit stopRemoved(stop);
+
+ qreal pos = d_ptr->m_stopToPos[stop];
+ d_ptr->m_stopToPos.remove(stop);
+ d_ptr->m_posToStop.remove(pos);
+ delete stop;
+}
+
+void QtGradientStopsModel::moveStop(QtGradientStop *stop, qreal newPos)
+{
+ if (!d_ptr->m_stopToPos.contains(stop))
+ return;
+ if (d_ptr->m_posToStop.contains(newPos))
+ return;
+
+ if (newPos > 1.0)
+ newPos = 1.0;
+ else if (newPos < 0.0)
+ newPos = 0.0;
+
+ emit stopMoved(stop, newPos);
+
+ const qreal oldPos = stop->position();
+ stop->setPosition(newPos);
+ d_ptr->m_stopToPos[stop] = newPos;
+ d_ptr->m_posToStop.remove(oldPos);
+ d_ptr->m_posToStop[newPos] = stop;
+}
+
+void QtGradientStopsModel::swapStops(QtGradientStop *stop1, QtGradientStop *stop2)
+{
+ if (stop1 == stop2)
+ return;
+ if (!d_ptr->m_stopToPos.contains(stop1))
+ return;
+ if (!d_ptr->m_stopToPos.contains(stop2))
+ return;
+
+ emit stopsSwapped(stop1, stop2);
+
+ const qreal pos1 = stop1->position();
+ const qreal pos2 = stop2->position();
+ stop1->setPosition(pos2);
+ stop2->setPosition(pos1);
+ d_ptr->m_stopToPos[stop1] = pos2;
+ d_ptr->m_stopToPos[stop2] = pos1;
+ d_ptr->m_posToStop[pos1] = stop2;
+ d_ptr->m_posToStop[pos2] = stop1;
+}
+
+void QtGradientStopsModel::changeStop(QtGradientStop *stop, const QColor &newColor)
+{
+ if (!d_ptr->m_stopToPos.contains(stop))
+ return;
+ if (stop->color() == newColor)
+ return;
+
+ emit stopChanged(stop, newColor);
+
+ stop->setColor(newColor);
+}
+
+void QtGradientStopsModel::selectStop(QtGradientStop *stop, bool select)
+{
+ if (!d_ptr->m_stopToPos.contains(stop))
+ return;
+ bool selected = d_ptr->m_selection.contains(stop);
+ if (select == selected)
+ return;
+
+ emit stopSelected(stop, select);
+
+ if (select)
+ d_ptr->m_selection[stop] = true;
+ else
+ d_ptr->m_selection.remove(stop);
+}
+
+void QtGradientStopsModel::setCurrentStop(QtGradientStop *stop)
+{
+ if (stop && !d_ptr->m_stopToPos.contains(stop))
+ return;
+ if (stop == currentStop())
+ return;
+
+ emit currentStopChanged(stop);
+
+ d_ptr->m_current = stop;
+}
+
+QtGradientStop *QtGradientStopsModel::firstSelected() const
+{
+ PositionStopMap stopList = stops();
+ PositionStopMap::ConstIterator itStop = stopList.constBegin();
+ while (itStop != stopList.constEnd()) {
+ QtGradientStop *stop = itStop.value();
+ if (isSelected(stop))
+ return stop;
+ ++itStop;
+ };
+ return 0;
+}
+
+QtGradientStop *QtGradientStopsModel::lastSelected() const
+{
+ PositionStopMap stopList = stops();
+ PositionStopMap::ConstIterator itStop = stopList.constEnd();
+ while (itStop != stopList.constBegin()) {
+ --itStop;
+
+ QtGradientStop *stop = itStop.value();
+ if (isSelected(stop))
+ return stop;
+ };
+ return 0;
+}
+
+QtGradientStopsModel *QtGradientStopsModel::clone() const
+{
+ QtGradientStopsModel *model = new QtGradientStopsModel();
+
+ QMap<qreal, QtGradientStop *> stopsToClone = stops();
+ QMapIterator<qreal, QtGradientStop *> it(stopsToClone);
+ while (it.hasNext()) {
+ it.next();
+ model->addStop(it.key(), it.value()->color());
+ }
+ // clone selection and current also
+ return model;
+}
+
+void QtGradientStopsModel::moveStops(double newPosition)
+{
+ QtGradientStop *current = currentStop();
+ if (!current)
+ return;
+
+ double newPos = newPosition;
+
+ if (newPos > 1)
+ newPos = 1;
+ else if (newPos < 0)
+ newPos = 0;
+
+ if (newPos == current->position())
+ return;
+
+ double offset = newPos - current->position();
+
+ QtGradientStop *first = firstSelected();
+ QtGradientStop *last = lastSelected();
+
+ if (first && last) { // multiselection
+ double maxOffset = 1.0 - last->position();
+ double minOffset = -first->position();
+
+ if (offset > maxOffset)
+ offset = maxOffset;
+ else if (offset < minOffset)
+ offset = minOffset;
+
+ }
+
+ if (offset == 0)
+ return;
+
+ bool forward = (offset > 0) ? false : true;
+
+ PositionStopMap stopList;
+
+ QList<QtGradientStop *> selected = selectedStops();
+ QListIterator<QtGradientStop *> it(selected);
+ while (it.hasNext()) {
+ QtGradientStop *stop = it.next();
+ stopList[stop->position()] = stop;
+ }
+ stopList[current->position()] = current;
+
+ PositionStopMap::ConstIterator itStop = forward ? stopList.constBegin() : stopList.constEnd();
+ while (itStop != (forward ? stopList.constEnd() : stopList.constBegin())) {
+ if (!forward)
+ --itStop;
+ QtGradientStop *stop = itStop.value();
+ double pos = stop->position() + offset;
+ if (pos > 1)
+ pos = 1;
+ if (pos < 0)
+ pos = 0;
+
+ if (current == stop)
+ pos = newPos;
+
+ QtGradientStop *oldStop = at(pos);
+ if (oldStop && !stopList.values().contains(oldStop))
+ removeStop(oldStop);
+ moveStop(stop, pos);
+
+ if (forward)
+ ++itStop;
+ }
+}
+
+void QtGradientStopsModel::clear()
+{
+ QList<QtGradientStop *> stopsList = stops().values();
+ QListIterator<QtGradientStop *> it(stopsList);
+ while (it.hasNext())
+ removeStop(it.next());
+}
+
+void QtGradientStopsModel::clearSelection()
+{
+ QList<QtGradientStop *> stopsList = selectedStops();
+ QListIterator<QtGradientStop *> it(stopsList);
+ while (it.hasNext())
+ selectStop(it.next(), false);
+}
+
+void QtGradientStopsModel::flipAll()
+{
+ QMap<qreal, QtGradientStop *> stopsMap = stops();
+ QMapIterator<qreal, QtGradientStop *> itStop(stopsMap);
+ itStop.toBack();
+
+ QMap<QtGradientStop *, bool> swappedList;
+
+ while (itStop.hasPrevious()) {
+ itStop.previous();
+
+ QtGradientStop *stop = itStop.value();
+ if (swappedList.contains(stop))
+ continue;
+ const double newPos = 1.0 - itStop.key();
+ if (stopsMap.contains(newPos)) {
+ QtGradientStop *swapped = stopsMap.value(newPos);
+ swappedList[swapped] = true;
+ swapStops(stop, swapped);
+ } else {
+ moveStop(stop, newPos);
+ }
+ }
+}
+
+void QtGradientStopsModel::selectAll()
+{
+ QList<QtGradientStop *> stopsList = stops().values();
+ QListIterator<QtGradientStop *> it(stopsList);
+ while (it.hasNext())
+ selectStop(it.next(), true);
+}
+
+void QtGradientStopsModel::deleteStops()
+{
+ QList<QtGradientStop *> selected = selectedStops();
+ QListIterator<QtGradientStop *> itSel(selected);
+ while (itSel.hasNext()) {
+ QtGradientStop *stop = itSel.next();
+ removeStop(stop);
+ }
+ QtGradientStop *current = currentStop();
+ if (current)
+ removeStop(current);
+}
+
+QT_END_NAMESPACE
diff --git a/src/shared/qtgradienteditor/qtgradientstopsmodel.h b/src/shared/qtgradienteditor/qtgradientstopsmodel.h
new file mode 100644
index 000000000..fac7d5642
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientstopsmodel.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTGRADIENTSTOPSMODEL_H
+#define QTGRADIENTSTOPSMODEL_H
+
+#include <QtCore/QObject>
+#include <QtCore/QMap>
+
+QT_BEGIN_NAMESPACE
+
+class QColor;
+
+class QtGradientStopsModel;
+
+class QtGradientStop
+{
+public:
+ qreal position() const;
+ QColor color() const;
+ QtGradientStopsModel *gradientModel() const;
+
+private:
+ void setColor(const QColor &color);
+ void setPosition(qreal position);
+ friend class QtGradientStopsModel;
+ QtGradientStop(QtGradientStopsModel *model = 0);
+ ~QtGradientStop();
+ QScopedPointer<class QtGradientStopPrivate> d_ptr;
+};
+
+class QtGradientStopsModel : public QObject
+{
+ Q_OBJECT
+public:
+ typedef QMap<qreal, QtGradientStop *> PositionStopMap;
+
+ QtGradientStopsModel(QObject *parent = 0);
+ ~QtGradientStopsModel();
+
+ PositionStopMap stops() const;
+ QtGradientStop *at(qreal pos) const;
+ QColor color(qreal pos) const; // calculated between points
+ QList<QtGradientStop *> selectedStops() const;
+ QtGradientStop *currentStop() const;
+ bool isSelected(QtGradientStop *stop) const;
+ QtGradientStop *firstSelected() const;
+ QtGradientStop *lastSelected() const;
+ QtGradientStopsModel *clone() const;
+
+ QtGradientStop *addStop(qreal pos, const QColor &color);
+ void removeStop(QtGradientStop *stop);
+ void moveStop(QtGradientStop *stop, qreal newPos);
+ void swapStops(QtGradientStop *stop1, QtGradientStop *stop2);
+ void changeStop(QtGradientStop *stop, const QColor &newColor);
+ void selectStop(QtGradientStop *stop, bool select);
+ void setCurrentStop(QtGradientStop *stop);
+
+ void moveStops(double newPosition); // moves current stop to newPos and all selected stops are moved accordingly
+ void clear();
+ void clearSelection();
+ void flipAll();
+ void selectAll();
+ void deleteStops();
+
+signals:
+ void stopAdded(QtGradientStop *stop);
+ void stopRemoved(QtGradientStop *stop);
+ void stopMoved(QtGradientStop *stop, qreal newPos);
+ void stopsSwapped(QtGradientStop *stop1, QtGradientStop *stop2);
+ void stopChanged(QtGradientStop *stop, const QColor &newColor);
+ void stopSelected(QtGradientStop *stop, bool selected);
+ void currentStopChanged(QtGradientStop *stop);
+
+private:
+ QScopedPointer<class QtGradientStopsModelPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtGradientStopsModel)
+ Q_DISABLE_COPY(QtGradientStopsModel)
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtgradienteditor/qtgradientstopswidget.cpp b/src/shared/qtgradienteditor/qtgradientstopswidget.cpp
new file mode 100644
index 000000000..a4104327b
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientstopswidget.cpp
@@ -0,0 +1,1154 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtgradientstopswidget.h"
+#include "qtgradientstopsmodel.h"
+
+#include <QtCore/QMap>
+#include <QtGui/QImage>
+#include <QtGui/QPainter>
+#include <QtGui/QScrollBar>
+#include <QtGui/QMouseEvent>
+#include <QtGui/QRubberBand>
+#include <QtGui/QMenu>
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientStopsWidgetPrivate
+{
+ QtGradientStopsWidget *q_ptr;
+ Q_DECLARE_PUBLIC(QtGradientStopsWidget)
+public:
+ typedef QMap<qreal, QColor> PositionColorMap;
+ typedef QMap<QtGradientStop *, qreal> StopPositionMap;
+
+ void slotStopAdded(QtGradientStop *stop);
+ void slotStopRemoved(QtGradientStop *stop);
+ void slotStopMoved(QtGradientStop *stop, qreal newPos);
+ void slotStopsSwapped(QtGradientStop *stop1, QtGradientStop *stop2);
+ void slotStopChanged(QtGradientStop *stop, const QColor &newColor);
+ void slotStopSelected(QtGradientStop *stop, bool selected);
+ void slotCurrentStopChanged(QtGradientStop *stop);
+ void slotNewStop();
+ void slotDelete();
+ void slotFlipAll();
+ void slotSelectAll();
+ void slotZoomIn();
+ void slotZoomOut();
+ void slotResetZoom();
+
+ double fromViewport(int x) const;
+ double toViewport(double x) const;
+ QtGradientStop *stopAt(const QPoint &viewportPos) const;
+ QList<QtGradientStop *> stopsAt(const QPoint &viewportPos) const;
+ void setupMove(QtGradientStop *stop, int x);
+ void ensureVisible(double x); // x = stop position
+ void ensureVisible(QtGradientStop *stop);
+ QtGradientStop *newStop(const QPoint &viewportPos);
+
+ bool m_backgroundCheckered;
+ QtGradientStopsModel *m_model;
+ double m_handleSize;
+ int m_scaleFactor;
+ double m_zoom;
+
+#ifndef QT_NO_DRAGANDDROP
+ QtGradientStop *m_dragStop;
+ QtGradientStop *m_changedStop;
+ QtGradientStop *m_clonedStop;
+ QtGradientStopsModel *m_dragModel;
+ QColor m_dragColor;
+ void clearDrag();
+ void removeClonedStop();
+ void restoreChangedStop();
+ void changeStop(qreal pos);
+ void cloneStop(qreal pos);
+#endif
+
+ QRubberBand *m_rubber;
+ QPoint m_clickPos;
+
+ QList<QtGradientStop *> m_stops;
+
+ bool m_moving;
+ int m_moveOffset;
+ StopPositionMap m_moveStops;
+
+ PositionColorMap m_moveOriginal;
+};
+
+double QtGradientStopsWidgetPrivate::fromViewport(int x) const
+{
+ QSize size = q_ptr->viewport()->size();
+ int w = size.width();
+ int max = q_ptr->horizontalScrollBar()->maximum();
+ int val = q_ptr->horizontalScrollBar()->value();
+ return ((double)x * m_scaleFactor + w * val) / (w * (m_scaleFactor + max));
+}
+
+double QtGradientStopsWidgetPrivate::toViewport(double x) const
+{
+ QSize size = q_ptr->viewport()->size();
+ int w = size.width();
+ int max = q_ptr->horizontalScrollBar()->maximum();
+ int val = q_ptr->horizontalScrollBar()->value();
+ return w * (x * (m_scaleFactor + max) - val) / m_scaleFactor;
+}
+
+QtGradientStop *QtGradientStopsWidgetPrivate::stopAt(const QPoint &viewportPos) const
+{
+ double posY = m_handleSize / 2;
+ QListIterator<QtGradientStop *> itStop(m_stops);
+ while (itStop.hasNext()) {
+ QtGradientStop *stop = itStop.next();
+
+ double posX = toViewport(stop->position());
+
+ double x = viewportPos.x() - posX;
+ double y = viewportPos.y() - posY;
+
+ if ((m_handleSize * m_handleSize / 4) > (x * x + y * y))
+ return stop;
+ }
+ return 0;
+}
+
+QList<QtGradientStop *> QtGradientStopsWidgetPrivate::stopsAt(const QPoint &viewportPos) const
+{
+ QList<QtGradientStop *> stops;
+ double posY = m_handleSize / 2;
+ QListIterator<QtGradientStop *> itStop(m_stops);
+ while (itStop.hasNext()) {
+ QtGradientStop *stop = itStop.next();
+
+ double posX = toViewport(stop->position());
+
+ double x = viewportPos.x() - posX;
+ double y = viewportPos.y() - posY;
+
+ if ((m_handleSize * m_handleSize / 4) > (x * x + y * y))
+ stops.append(stop);
+ }
+ return stops;
+}
+
+void QtGradientStopsWidgetPrivate::setupMove(QtGradientStop *stop, int x)
+{
+ m_model->setCurrentStop(stop);
+
+ int viewportX = qRound(toViewport(stop->position()));
+ m_moveOffset = x - viewportX;
+
+ QList<QtGradientStop *> stops = m_stops;
+ m_stops.clear();
+ QListIterator<QtGradientStop *> itStop(stops);
+ while (itStop.hasNext()) {
+ QtGradientStop *s = itStop.next();
+ if (m_model->isSelected(s) || s == stop) {
+ m_moveStops[s] = s->position() - stop->position();
+ m_stops.append(s);
+ } else {
+ m_moveOriginal[s->position()] = s->color();
+ }
+ }
+ itStop.toFront();
+ while (itStop.hasNext()) {
+ QtGradientStop *s = itStop.next();
+ if (!m_model->isSelected(s))
+ m_stops.append(s);
+ }
+ m_stops.removeAll(stop);
+ m_stops.prepend(stop);
+}
+
+void QtGradientStopsWidgetPrivate::ensureVisible(double x)
+{
+ double viewX = toViewport(x);
+ if (viewX < 0 || viewX > q_ptr->viewport()->size().width()) {
+ int max = q_ptr->horizontalScrollBar()->maximum();
+ int newVal = qRound(x * (max + m_scaleFactor) - m_scaleFactor / 2);
+ q_ptr->horizontalScrollBar()->setValue(newVal);
+ }
+}
+
+void QtGradientStopsWidgetPrivate::ensureVisible(QtGradientStop *stop)
+{
+ if (!stop)
+ return;
+ ensureVisible(stop->position());
+}
+
+QtGradientStop *QtGradientStopsWidgetPrivate::newStop(const QPoint &viewportPos)
+{
+ QtGradientStop *copyStop = stopAt(viewportPos);
+ double posX = fromViewport(viewportPos.x());
+ QtGradientStop *stop = m_model->at(posX);
+ if (!stop) {
+ QColor newColor;
+ if (copyStop)
+ newColor = copyStop->color();
+ else
+ newColor = m_model->color(posX);
+ if (!newColor.isValid())
+ newColor = Qt::white;
+ stop = m_model->addStop(posX, newColor);
+ }
+ return stop;
+}
+
+void QtGradientStopsWidgetPrivate::slotStopAdded(QtGradientStop *stop)
+{
+ m_stops.append(stop);
+ q_ptr->viewport()->update();
+}
+
+void QtGradientStopsWidgetPrivate::slotStopRemoved(QtGradientStop *stop)
+{
+ m_stops.removeAll(stop);
+ q_ptr->viewport()->update();
+}
+
+void QtGradientStopsWidgetPrivate::slotStopMoved(QtGradientStop *stop, qreal newPos)
+{
+ Q_UNUSED(stop)
+ Q_UNUSED(newPos)
+ q_ptr->viewport()->update();
+}
+
+void QtGradientStopsWidgetPrivate::slotStopsSwapped(QtGradientStop *stop1, QtGradientStop *stop2)
+{
+ Q_UNUSED(stop1)
+ Q_UNUSED(stop2)
+ q_ptr->viewport()->update();
+}
+
+void QtGradientStopsWidgetPrivate::slotStopChanged(QtGradientStop *stop, const QColor &newColor)
+{
+ Q_UNUSED(stop)
+ Q_UNUSED(newColor)
+ q_ptr->viewport()->update();
+}
+
+void QtGradientStopsWidgetPrivate::slotStopSelected(QtGradientStop *stop, bool selected)
+{
+ Q_UNUSED(stop)
+ Q_UNUSED(selected)
+ q_ptr->viewport()->update();
+}
+
+void QtGradientStopsWidgetPrivate::slotCurrentStopChanged(QtGradientStop *stop)
+{
+ Q_UNUSED(stop)
+
+ if (!m_model)
+ return;
+ q_ptr->viewport()->update();
+ if (stop) {
+ m_stops.removeAll(stop);
+ m_stops.prepend(stop);
+ }
+}
+
+void QtGradientStopsWidgetPrivate::slotNewStop()
+{
+ if (!m_model)
+ return;
+
+ QtGradientStop *stop = newStop(m_clickPos);
+
+ if (!stop)
+ return;
+
+ m_model->clearSelection();
+ m_model->selectStop(stop, true);
+ m_model->setCurrentStop(stop);
+}
+
+void QtGradientStopsWidgetPrivate::slotDelete()
+{
+ if (!m_model)
+ return;
+
+ m_model->deleteStops();
+}
+
+void QtGradientStopsWidgetPrivate::slotFlipAll()
+{
+ if (!m_model)
+ return;
+
+ m_model->flipAll();
+}
+
+void QtGradientStopsWidgetPrivate::slotSelectAll()
+{
+ if (!m_model)
+ return;
+
+ m_model->selectAll();
+}
+
+void QtGradientStopsWidgetPrivate::slotZoomIn()
+{
+ double newZoom = q_ptr->zoom() * 2;
+ if (newZoom > 100)
+ newZoom = 100;
+ if (newZoom == q_ptr->zoom())
+ return;
+
+ q_ptr->setZoom(newZoom);
+ emit q_ptr->zoomChanged(q_ptr->zoom());
+}
+
+void QtGradientStopsWidgetPrivate::slotZoomOut()
+{
+ double newZoom = q_ptr->zoom() / 2;
+ if (newZoom < 1)
+ newZoom = 1;
+ if (newZoom == q_ptr->zoom())
+ return;
+
+ q_ptr->setZoom(newZoom);
+ emit q_ptr->zoomChanged(q_ptr->zoom());
+}
+
+void QtGradientStopsWidgetPrivate::slotResetZoom()
+{
+ if (1 == q_ptr->zoom())
+ return;
+
+ q_ptr->setZoom(1);
+ emit q_ptr->zoomChanged(1);
+}
+
+QtGradientStopsWidget::QtGradientStopsWidget(QWidget *parent)
+ : QAbstractScrollArea(parent), d_ptr(new QtGradientStopsWidgetPrivate)
+{
+ d_ptr->q_ptr = this;
+ d_ptr->m_backgroundCheckered = true;
+ d_ptr->m_model = 0;
+ d_ptr->m_handleSize = 25.0;
+ d_ptr->m_scaleFactor = 1000;
+ d_ptr->m_moving = false;
+ d_ptr->m_zoom = 1;
+ d_ptr->m_rubber = new QRubberBand(QRubberBand::Rectangle, this);
+#ifndef QT_NO_DRAGANDDROP
+ d_ptr->m_dragStop = 0;
+ d_ptr->m_changedStop = 0;
+ d_ptr->m_clonedStop = 0;
+ d_ptr->m_dragModel = 0;
+#endif
+ setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ horizontalScrollBar()->setRange(0, (int)(d_ptr->m_scaleFactor * (d_ptr->m_zoom - 1) + 0.5));
+ horizontalScrollBar()->setPageStep(d_ptr->m_scaleFactor);
+ horizontalScrollBar()->setSingleStep(4);
+ viewport()->setAutoFillBackground(false);
+
+ setAcceptDrops(true);
+
+ setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred));
+}
+
+QtGradientStopsWidget::~QtGradientStopsWidget()
+{
+}
+
+QSize QtGradientStopsWidget::sizeHint() const
+{
+ return QSize(qRound(2 * d_ptr->m_handleSize), qRound(3 * d_ptr->m_handleSize) + horizontalScrollBar()->sizeHint().height());
+}
+
+QSize QtGradientStopsWidget::minimumSizeHint() const
+{
+ return QSize(qRound(2 * d_ptr->m_handleSize), qRound(3 * d_ptr->m_handleSize) + horizontalScrollBar()->minimumSizeHint().height());
+}
+
+void QtGradientStopsWidget::setBackgroundCheckered(bool checkered)
+{
+ if (d_ptr->m_backgroundCheckered == checkered)
+ return;
+ d_ptr->m_backgroundCheckered = checkered;
+ update();
+}
+
+bool QtGradientStopsWidget::isBackgroundCheckered() const
+{
+ return d_ptr->m_backgroundCheckered;
+}
+
+void QtGradientStopsWidget::setGradientStopsModel(QtGradientStopsModel *model)
+{
+ if (d_ptr->m_model == model)
+ return;
+
+ if (d_ptr->m_model) {
+ disconnect(d_ptr->m_model, SIGNAL(stopAdded(QtGradientStop*)),
+ this, SLOT(slotStopAdded(QtGradientStop*)));
+ disconnect(d_ptr->m_model, SIGNAL(stopRemoved(QtGradientStop*)),
+ this, SLOT(slotStopRemoved(QtGradientStop*)));
+ disconnect(d_ptr->m_model, SIGNAL(stopMoved(QtGradientStop*,qreal)),
+ this, SLOT(slotStopMoved(QtGradientStop*,qreal)));
+ disconnect(d_ptr->m_model, SIGNAL(stopsSwapped(QtGradientStop*,QtGradientStop*)),
+ this, SLOT(slotStopsSwapped(QtGradientStop*,QtGradientStop*)));
+ disconnect(d_ptr->m_model, SIGNAL(stopChanged(QtGradientStop*,QColor)),
+ this, SLOT(slotStopChanged(QtGradientStop*,QColor)));
+ disconnect(d_ptr->m_model, SIGNAL(stopSelected(QtGradientStop*,bool)),
+ this, SLOT(slotStopSelected(QtGradientStop*,bool)));
+ disconnect(d_ptr->m_model, SIGNAL(currentStopChanged(QtGradientStop*)),
+ this, SLOT(slotCurrentStopChanged(QtGradientStop*)));
+
+ d_ptr->m_stops.clear();
+ }
+
+ d_ptr->m_model = model;
+
+ if (d_ptr->m_model) {
+ connect(d_ptr->m_model, SIGNAL(stopAdded(QtGradientStop*)),
+ this, SLOT(slotStopAdded(QtGradientStop*)));
+ connect(d_ptr->m_model, SIGNAL(stopRemoved(QtGradientStop*)),
+ this, SLOT(slotStopRemoved(QtGradientStop*)));
+ connect(d_ptr->m_model, SIGNAL(stopMoved(QtGradientStop*,qreal)),
+ this, SLOT(slotStopMoved(QtGradientStop*,qreal)));
+ connect(d_ptr->m_model, SIGNAL(stopsSwapped(QtGradientStop*,QtGradientStop*)),
+ this, SLOT(slotStopsSwapped(QtGradientStop*,QtGradientStop*)));
+ connect(d_ptr->m_model, SIGNAL(stopChanged(QtGradientStop*,QColor)),
+ this, SLOT(slotStopChanged(QtGradientStop*,QColor)));
+ connect(d_ptr->m_model, SIGNAL(stopSelected(QtGradientStop*,bool)),
+ this, SLOT(slotStopSelected(QtGradientStop*,bool)));
+ connect(d_ptr->m_model, SIGNAL(currentStopChanged(QtGradientStop*)),
+ this, SLOT(slotCurrentStopChanged(QtGradientStop*)));
+
+ QList<QtGradientStop *> stops = d_ptr->m_model->stops().values();
+ QListIterator<QtGradientStop *> itStop(stops);
+ while (itStop.hasNext())
+ d_ptr->slotStopAdded(itStop.next());
+
+ QList<QtGradientStop *> selected = d_ptr->m_model->selectedStops();
+ QListIterator<QtGradientStop *> itSelect(selected);
+ while (itSelect.hasNext())
+ d_ptr->slotStopSelected(itSelect.next(), true);
+
+ d_ptr->slotCurrentStopChanged(d_ptr->m_model->currentStop());
+ }
+}
+
+void QtGradientStopsWidget::mousePressEvent(QMouseEvent *e)
+{
+ typedef QtGradientStopsModel::PositionStopMap PositionStopMap;
+ if (!d_ptr->m_model)
+ return;
+
+ if (e->button() != Qt::LeftButton)
+ return;
+
+ d_ptr->m_moving = true;
+
+ d_ptr->m_moveStops.clear();
+ d_ptr->m_moveOriginal.clear();
+ d_ptr->m_clickPos = e->pos();
+ QtGradientStop *stop = d_ptr->stopAt(e->pos());
+ if (stop) {
+ if (e->modifiers() & Qt::ControlModifier) {
+ d_ptr->m_model->selectStop(stop, !d_ptr->m_model->isSelected(stop));
+ } else if (e->modifiers() & Qt::ShiftModifier) {
+ QtGradientStop *oldCurrent = d_ptr->m_model->currentStop();
+ if (oldCurrent) {
+ PositionStopMap stops = d_ptr->m_model->stops();
+ PositionStopMap::ConstIterator itSt = stops.constFind(oldCurrent->position());
+ if (itSt != stops.constEnd()) {
+ while (itSt != stops.constFind(stop->position())) {
+ d_ptr->m_model->selectStop(itSt.value(), true);
+ if (oldCurrent->position() < stop->position())
+ ++itSt;
+ else
+ --itSt;
+ }
+ }
+ }
+ d_ptr->m_model->selectStop(stop, true);
+ } else {
+ if (!d_ptr->m_model->isSelected(stop)) {
+ d_ptr->m_model->clearSelection();
+ d_ptr->m_model->selectStop(stop, true);
+ }
+ }
+ d_ptr->setupMove(stop, e->pos().x());
+ } else {
+ d_ptr->m_model->clearSelection();
+ d_ptr->m_rubber->setGeometry(QRect(d_ptr->m_clickPos, QSize()));
+ d_ptr->m_rubber->show();
+ }
+ viewport()->update();
+}
+
+void QtGradientStopsWidget::mouseReleaseEvent(QMouseEvent *e)
+{
+ if (!d_ptr->m_model)
+ return;
+
+ if (e->button() != Qt::LeftButton)
+ return;
+
+ d_ptr->m_moving = false;
+ d_ptr->m_rubber->hide();
+ d_ptr->m_moveStops.clear();
+ d_ptr->m_moveOriginal.clear();
+}
+
+void QtGradientStopsWidget::mouseMoveEvent(QMouseEvent *e)
+{
+ typedef QtGradientStopsWidgetPrivate::PositionColorMap PositionColorMap;
+ typedef QtGradientStopsModel::PositionStopMap PositionStopMap;
+ typedef QtGradientStopsWidgetPrivate::StopPositionMap StopPositionMap;
+ if (!d_ptr->m_model)
+ return;
+
+ if (!(e->buttons() & Qt::LeftButton))
+ return;
+
+ if (!d_ptr->m_moving)
+ return;
+
+ if (!d_ptr->m_moveStops.isEmpty()) {
+ double maxOffset = 0.0;
+ double minOffset = 0.0;
+ bool first = true;
+ StopPositionMap::ConstIterator itStop = d_ptr->m_moveStops.constBegin();
+ while (itStop != d_ptr->m_moveStops.constEnd()) {
+ double offset = itStop.value();
+
+ if (first) {
+ maxOffset = offset;
+ minOffset = offset;
+ first = false;
+ } else {
+ if (maxOffset < offset)
+ maxOffset = offset;
+ else if (minOffset > offset)
+ minOffset = offset;
+ }
+ ++itStop;
+ }
+
+ double viewportMin = d_ptr->toViewport(-minOffset);
+ double viewportMax = d_ptr->toViewport(1.0 - maxOffset);
+
+ PositionStopMap newPositions;
+
+ int viewportX = e->pos().x() - d_ptr->m_moveOffset;
+
+ if (viewportX > viewport()->size().width())
+ viewportX = viewport()->size().width();
+ else if (viewportX < 0)
+ viewportX = 0;
+
+ double posX = d_ptr->fromViewport(viewportX);
+
+ if (viewportX > viewportMax)
+ posX = 1.0 - maxOffset;
+ else if (viewportX < viewportMin)
+ posX = -minOffset;
+
+ itStop = d_ptr->m_moveStops.constBegin();
+ while (itStop != d_ptr->m_moveStops.constEnd()) {
+ QtGradientStop *stop = itStop.key();
+
+ newPositions[posX + itStop.value()] = stop;
+
+ ++itStop;
+ }
+
+ bool forward = true;
+ PositionStopMap::ConstIterator itNewPos = newPositions.constBegin();
+ if (itNewPos.value()->position() < itNewPos.key())
+ forward = false;
+
+ itNewPos = forward ? newPositions.constBegin() : newPositions.constEnd();
+ while (itNewPos != (forward ? newPositions.constEnd() : newPositions.constBegin())) {
+ if (!forward)
+ --itNewPos;
+ QtGradientStop *stop = itNewPos.value();
+ double newPos = itNewPos.key();
+ if (newPos > 1)
+ newPos = 1;
+ else if (newPos < 0)
+ newPos = 0;
+
+ QtGradientStop *existingStop = d_ptr->m_model->at(newPos);
+ if (existingStop && !d_ptr->m_moveStops.contains(existingStop))
+ d_ptr->m_model->removeStop(existingStop);
+ d_ptr->m_model->moveStop(stop, newPos);
+
+ if (forward)
+ ++itNewPos;
+ }
+
+ PositionColorMap::ConstIterator itOld = d_ptr->m_moveOriginal.constBegin();
+ while (itOld != d_ptr->m_moveOriginal.constEnd()) {
+ double position = itOld.key();
+ if (!d_ptr->m_model->at(position))
+ d_ptr->m_model->addStop(position, itOld.value());
+
+ ++itOld;
+ }
+
+ } else {
+ QRect r(QRect(d_ptr->m_clickPos, e->pos()).normalized());
+ r.translate(1, 0);
+ d_ptr->m_rubber->setGeometry(r);
+ //d_ptr->m_model->clearSelection();
+
+ int xv1 = d_ptr->m_clickPos.x();
+ int xv2 = e->pos().x();
+ if (xv1 > xv2) {
+ int temp = xv1;
+ xv1 = xv2;
+ xv2 = temp;
+ }
+ int yv1 = d_ptr->m_clickPos.y();
+ int yv2 = e->pos().y();
+ if (yv1 > yv2) {
+ int temp = yv1;
+ yv1 = yv2;
+ yv2 = temp;
+ }
+
+ QPoint p1, p2;
+
+ if (yv2 < d_ptr->m_handleSize / 2) {
+ p1 = QPoint(xv1, yv2);
+ p2 = QPoint(xv2, yv2);
+ } else if (yv1 > d_ptr->m_handleSize / 2) {
+ p1 = QPoint(xv1, yv1);
+ p2 = QPoint(xv2, yv1);
+ } else {
+ p1 = QPoint(xv1, qRound(d_ptr->m_handleSize / 2));
+ p2 = QPoint(xv2, qRound(d_ptr->m_handleSize / 2));
+ }
+
+ QList<QtGradientStop *> beginList = d_ptr->stopsAt(p1);
+ QList<QtGradientStop *> endList = d_ptr->stopsAt(p2);
+
+ double x1 = d_ptr->fromViewport(xv1);
+ double x2 = d_ptr->fromViewport(xv2);
+
+ QListIterator<QtGradientStop *> itStop(d_ptr->m_stops);
+ while (itStop.hasNext()) {
+ QtGradientStop *stop = itStop.next();
+ if ((stop->position() >= x1 && stop->position() <= x2) ||
+ beginList.contains(stop) || endList.contains(stop))
+ d_ptr->m_model->selectStop(stop, true);
+ else
+ d_ptr->m_model->selectStop(stop, false);
+ }
+ }
+}
+
+void QtGradientStopsWidget::mouseDoubleClickEvent(QMouseEvent *e)
+{
+ if (!d_ptr->m_model)
+ return;
+
+ if (e->button() != Qt::LeftButton)
+ return;
+
+ if (d_ptr->m_clickPos != e->pos()) {
+ mousePressEvent(e);
+ return;
+ }
+ d_ptr->m_moving = true;
+ d_ptr->m_moveStops.clear();
+ d_ptr->m_moveOriginal.clear();
+
+ QtGradientStop *stop = d_ptr->newStop(e->pos());
+
+ if (!stop)
+ return;
+
+ d_ptr->m_model->clearSelection();
+ d_ptr->m_model->selectStop(stop, true);
+
+ d_ptr->setupMove(stop, e->pos().x());
+
+ viewport()->update();
+}
+
+void QtGradientStopsWidget::keyPressEvent(QKeyEvent *e)
+{
+ typedef QtGradientStopsModel::PositionStopMap PositionStopMap;
+ if (!d_ptr->m_model)
+ return;
+
+ if (e->key() == Qt::Key_Delete || e->key() == Qt::Key_Backspace) {
+ d_ptr->m_model->deleteStops();
+ } else if (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right ||
+ e->key() == Qt::Key_Home || e->key() == Qt::Key_End) {
+ PositionStopMap stops = d_ptr->m_model->stops();
+ if (stops.isEmpty())
+ return;
+ QtGradientStop *newCurrent = 0;
+ QtGradientStop *current = d_ptr->m_model->currentStop();
+ if (!current || e->key() == Qt::Key_Home || e->key() == Qt::Key_End) {
+ if (e->key() == Qt::Key_Left || e->key() == Qt::Key_Home)
+ newCurrent = stops.constBegin().value();
+ else if (e->key() == Qt::Key_Right || e->key() == Qt::Key_End)
+ newCurrent = (--stops.constEnd()).value();
+ } else {
+ PositionStopMap::ConstIterator itStop = stops.constBegin();
+ while (itStop.value() != current)
+ ++itStop;
+ if (e->key() == Qt::Key_Left && itStop != stops.constBegin())
+ --itStop;
+ else if (e->key() == Qt::Key_Right && itStop != --stops.constEnd())
+ ++itStop;
+ newCurrent = itStop.value();
+ }
+ d_ptr->m_model->clearSelection();
+ d_ptr->m_model->selectStop(newCurrent, true);
+ d_ptr->m_model->setCurrentStop(newCurrent);
+ d_ptr->ensureVisible(newCurrent);
+ } else if (e->key() == Qt::Key_A) {
+ if (e->modifiers() & Qt::ControlModifier)
+ d_ptr->m_model->selectAll();
+ }
+}
+
+void QtGradientStopsWidget::paintEvent(QPaintEvent *e)
+{
+ Q_UNUSED(e)
+ if (!d_ptr->m_model)
+ return;
+
+ QtGradientStopsModel *model = d_ptr->m_model;
+#ifndef QT_NO_DRAGANDDROP
+ if (d_ptr->m_dragModel)
+ model = d_ptr->m_dragModel;
+#endif
+
+ QSize size = viewport()->size();
+ int w = size.width();
+ double h = size.height() - d_ptr->m_handleSize;
+ if (w <= 0)
+ return;
+
+ QPixmap pix(size);
+ QPainter p;
+
+ if (d_ptr->m_backgroundCheckered) {
+ int pixSize = 20;
+ QPixmap pm(2 * pixSize, 2 * pixSize);
+ QPainter pmp(&pm);
+ pmp.fillRect(0, 0, pixSize, pixSize, Qt::white);
+ pmp.fillRect(pixSize, pixSize, pixSize, pixSize, Qt::white);
+ pmp.fillRect(0, pixSize, pixSize, pixSize, Qt::black);
+ pmp.fillRect(pixSize, 0, pixSize, pixSize, Qt::black);
+
+ p.begin(&pix);
+ p.setBrushOrigin((size.width() % pixSize + pixSize) / 2, (size.height() % pixSize + pixSize) / 2);
+ p.fillRect(viewport()->rect(), pm);
+ p.setBrushOrigin(0, 0);
+ } else {
+ p.begin(viewport());
+ }
+
+ double viewBegin = (double)w * horizontalScrollBar()->value() / d_ptr->m_scaleFactor;
+
+ int val = horizontalScrollBar()->value();
+ int max = horizontalScrollBar()->maximum();
+
+ double begin = (double)val / (d_ptr->m_scaleFactor + max);
+ double end = (double)(val + d_ptr->m_scaleFactor) / (d_ptr->m_scaleFactor + max);
+ double width = end - begin;
+
+ if (h > 0) {
+ QLinearGradient lg(0, 0, w, 0);
+ QMap<qreal, QtGradientStop *> stops = model->stops();
+ QMapIterator<qreal, QtGradientStop *> itStop(stops);
+ while (itStop.hasNext()) {
+ QtGradientStop *stop = itStop.next().value();
+ double pos = stop->position();
+ if (pos >= begin && pos <= end) {
+ double gradPos = (pos - begin) / width;
+ QColor c = stop->color();
+ lg.setColorAt(gradPos, c);
+ }
+ //lg.setColorAt(stop->position(), stop->color());
+ }
+ lg.setColorAt(0, model->color(begin));
+ lg.setColorAt(1, model->color(end));
+ QImage img(w, 1, QImage::Format_ARGB32_Premultiplied);
+ QPainter p1(&img);
+ p1.setCompositionMode(QPainter::CompositionMode_Source);
+
+ /*
+ if (viewBegin != 0)
+ p1.translate(-viewBegin, 0);
+ if (d_ptr->m_zoom != 1)
+ p1.scale(d_ptr->m_zoom, 1);
+ */
+ p1.fillRect(0, 0, w, 1, lg);
+
+ p.fillRect(QRectF(0, d_ptr->m_handleSize, w, h), QPixmap::fromImage(img));
+ }
+
+
+ double handleWidth = d_ptr->m_handleSize * d_ptr->m_scaleFactor / (w * (d_ptr->m_scaleFactor + max));
+
+ QColor insideColor = QColor::fromRgb(0x20, 0x20, 0x20, 0xFF);
+ QColor borderColor = QColor(Qt::white);
+ QColor drawColor;
+ QColor back1 = QColor(Qt::lightGray);
+ QColor back2 = QColor(Qt::darkGray);
+ QColor back = QColor::fromRgb((back1.red() + back2.red()) / 2,
+ (back1.green() + back2.green()) / 2,
+ (back1.blue() + back2.blue()) / 2);
+
+ QPen pen;
+ p.setRenderHint(QPainter::Antialiasing);
+ QListIterator<QtGradientStop *> itStop(d_ptr->m_stops);
+ itStop.toBack();
+ while (itStop.hasPrevious()) {
+ QtGradientStop *stop = itStop.previous();
+ double x = stop->position();
+ if (x >= begin - handleWidth / 2 && x <= end + handleWidth / 2) {
+ double viewX = x * w * (d_ptr->m_scaleFactor + max) / d_ptr->m_scaleFactor - viewBegin;
+ p.save();
+ QColor c = stop->color();
+#ifndef QT_NO_DRAGANDDROP
+ if (stop == d_ptr->m_dragStop)
+ c = d_ptr->m_dragColor;
+#endif
+ if ((0.3 * c.redF() + 0.59 * c.greenF() + 0.11 * c.blueF()) * c.alphaF() +
+ (0.3 * back.redF() + 0.59 * back.greenF() + 0.11 * back.blueF()) * (1.0 - c.alphaF()) < 0.5) {
+ drawColor = QColor::fromRgb(0xC0, 0xC0, 0xC0, 0xB0);
+ } else {
+ drawColor = QColor::fromRgb(0x40, 0x40, 0x40, 0x80);
+ }
+ QRectF rect(viewX - d_ptr->m_handleSize / 2, 0, d_ptr->m_handleSize, d_ptr->m_handleSize);
+ rect.adjust(0.5, 0.5, -0.5, -0.5);
+ if (h > 0) {
+ pen.setWidthF(1);
+ QLinearGradient lg(0, d_ptr->m_handleSize, 0, d_ptr->m_handleSize + h / 2);
+ lg.setColorAt(0, drawColor);
+ QColor alphaZero = drawColor;
+ alphaZero.setAlpha(0);
+ lg.setColorAt(1, alphaZero);
+ pen.setBrush(lg);
+ p.setPen(pen);
+ p.drawLine(QPointF(viewX, d_ptr->m_handleSize), QPointF(viewX, d_ptr->m_handleSize + h / 2));
+
+ pen.setWidthF(1);
+ pen.setBrush(drawColor);
+ p.setPen(pen);
+ QRectF r1 = rect.adjusted(0.5, 0.5, -0.5, -0.5);
+ QRectF r2 = rect.adjusted(1.5, 1.5, -1.5, -1.5);
+ QColor inColor = QColor::fromRgb(0x80, 0x80, 0x80, 0x80);
+ if (!d_ptr->m_model->isSelected(stop)) {
+ p.setBrush(c);
+ p.drawEllipse(rect);
+ } else {
+ pen.setBrush(insideColor);
+ pen.setWidthF(2);
+ p.setPen(pen);
+ p.setBrush(Qt::NoBrush);
+ p.drawEllipse(r1);
+
+ pen.setBrush(inColor);
+ pen.setWidthF(1);
+ p.setPen(pen);
+ p.setBrush(c);
+ p.drawEllipse(r2);
+ }
+
+ if (d_ptr->m_model->currentStop() == stop) {
+ p.setBrush(Qt::NoBrush);
+ pen.setWidthF(5);
+ pen.setBrush(drawColor);
+ int corr = 4;
+ if (!d_ptr->m_model->isSelected(stop)) {
+ corr = 3;
+ pen.setWidthF(7);
+ }
+ p.setPen(pen);
+ p.drawEllipse(rect.adjusted(corr, corr, -corr, -corr));
+ }
+
+ }
+ p.restore();
+ }
+ }
+ if (d_ptr->m_backgroundCheckered) {
+ p.end();
+ p.begin(viewport());
+ p.drawPixmap(0, 0, pix);
+ }
+ p.end();
+}
+
+void QtGradientStopsWidget::focusInEvent(QFocusEvent *e)
+{
+ Q_UNUSED(e)
+ viewport()->update();
+}
+
+void QtGradientStopsWidget::focusOutEvent(QFocusEvent *e)
+{
+ Q_UNUSED(e)
+ viewport()->update();
+}
+
+void QtGradientStopsWidget::contextMenuEvent(QContextMenuEvent *e)
+{
+ if (!d_ptr->m_model)
+ return;
+
+ d_ptr->m_clickPos = e->pos();
+
+ QMenu menu(this);
+ QAction *newStopAction = new QAction(tr("New Stop"), &menu);
+ QAction *deleteAction = new QAction(tr("Delete"), &menu);
+ QAction *flipAllAction = new QAction(tr("Flip All"), &menu);
+ QAction *selectAllAction = new QAction(tr("Select All"), &menu);
+ QAction *zoomInAction = new QAction(tr("Zoom In"), &menu);
+ QAction *zoomOutAction = new QAction(tr("Zoom Out"), &menu);
+ QAction *zoomAllAction = new QAction(tr("Reset Zoom"), &menu);
+ if (d_ptr->m_model->selectedStops().isEmpty() && !d_ptr->m_model->currentStop())
+ deleteAction->setEnabled(false);
+ if (zoom() <= 1) {
+ zoomOutAction->setEnabled(false);
+ zoomAllAction->setEnabled(false);
+ } else if (zoom() >= 100) {
+ zoomInAction->setEnabled(false);
+ }
+ connect(newStopAction, SIGNAL(triggered()), this, SLOT(slotNewStop()));
+ connect(deleteAction, SIGNAL(triggered()), this, SLOT(slotDelete()));
+ connect(flipAllAction, SIGNAL(triggered()), this, SLOT(slotFlipAll()));
+ connect(selectAllAction, SIGNAL(triggered()), this, SLOT(slotSelectAll()));
+ connect(zoomInAction, SIGNAL(triggered()), this, SLOT(slotZoomIn()));
+ connect(zoomOutAction, SIGNAL(triggered()), this, SLOT(slotZoomOut()));
+ connect(zoomAllAction, SIGNAL(triggered()), this, SLOT(slotResetZoom()));
+ menu.addAction(newStopAction);
+ menu.addAction(deleteAction);
+ menu.addAction(flipAllAction);
+ menu.addAction(selectAllAction);
+ menu.addSeparator();
+ menu.addAction(zoomInAction);
+ menu.addAction(zoomOutAction);
+ menu.addAction(zoomAllAction);
+ menu.exec(e->globalPos());
+}
+
+void QtGradientStopsWidget::wheelEvent(QWheelEvent *e)
+{
+ int numDegrees = e->delta() / 8;
+ int numSteps = numDegrees / 15;
+
+ int shift = numSteps;
+ if (shift < 0)
+ shift = -shift;
+ int pow = 1 << shift;
+ //const double c = 0.7071067; // 2 steps per doubled value
+ const double c = 0.5946036; // 4 steps pre doubled value
+ // in general c = pow(2, 1 / n) / 2; where n is the step
+ double factor = pow * c;
+
+ double newZoom = zoom();
+ if (numSteps < 0)
+ newZoom /= factor;
+ else
+ newZoom *= factor;
+ if (newZoom > 100)
+ newZoom = 100;
+ if (newZoom < 1)
+ newZoom = 1;
+
+ if (newZoom == zoom())
+ return;
+
+ setZoom(newZoom);
+ emit zoomChanged(zoom());
+}
+
+#ifndef QT_NO_DRAGANDDROP
+void QtGradientStopsWidget::dragEnterEvent(QDragEnterEvent *event)
+{
+ const QMimeData *mime = event->mimeData();
+ if (!mime->hasColor())
+ return;
+ event->accept();
+ d_ptr->m_dragModel = d_ptr->m_model->clone();
+
+ d_ptr->m_dragColor = qvariant_cast<QColor>(mime->colorData());
+ update();
+}
+
+void QtGradientStopsWidget::dragMoveEvent(QDragMoveEvent *event)
+{
+ QRectF rect = viewport()->rect();
+ rect.adjust(0, d_ptr->m_handleSize, 0, 0);
+ double x = d_ptr->fromViewport(event->pos().x());
+ QtGradientStop *dragStop = d_ptr->stopAt(event->pos());
+ if (dragStop) {
+ event->accept();
+ d_ptr->removeClonedStop();
+ d_ptr->changeStop(dragStop->position());
+ } else if (rect.contains(event->pos())) {
+ event->accept();
+ if (d_ptr->m_model->at(x)) {
+ d_ptr->removeClonedStop();
+ d_ptr->changeStop(x);
+ } else {
+ d_ptr->restoreChangedStop();
+ d_ptr->cloneStop(x);
+ }
+ } else {
+ event->ignore();
+ d_ptr->removeClonedStop();
+ d_ptr->restoreChangedStop();
+ }
+
+ update();
+}
+
+void QtGradientStopsWidget::dragLeaveEvent(QDragLeaveEvent *event)
+{
+ event->accept();
+ d_ptr->clearDrag();
+ update();
+}
+
+void QtGradientStopsWidget::dropEvent(QDropEvent *event)
+{
+ event->accept();
+ if (!d_ptr->m_dragModel)
+ return;
+
+ if (d_ptr->m_changedStop)
+ d_ptr->m_model->changeStop(d_ptr->m_model->at(d_ptr->m_changedStop->position()), d_ptr->m_dragColor);
+ else if (d_ptr->m_clonedStop)
+ d_ptr->m_model->addStop(d_ptr->m_clonedStop->position(), d_ptr->m_dragColor);
+
+ d_ptr->clearDrag();
+ update();
+}
+
+void QtGradientStopsWidgetPrivate::clearDrag()
+{
+ removeClonedStop();
+ restoreChangedStop();
+ delete m_dragModel;
+ m_dragModel = 0;
+}
+
+void QtGradientStopsWidgetPrivate::removeClonedStop()
+{
+ if (!m_clonedStop)
+ return;
+ m_dragModel->removeStop(m_clonedStop);
+ m_clonedStop = 0;
+}
+
+void QtGradientStopsWidgetPrivate::restoreChangedStop()
+{
+ if (!m_changedStop)
+ return;
+ m_dragModel->changeStop(m_changedStop, m_model->at(m_changedStop->position())->color());
+ m_changedStop = 0;
+ m_dragStop = 0;
+}
+
+void QtGradientStopsWidgetPrivate::changeStop(qreal pos)
+{
+ QtGradientStop *stop = m_dragModel->at(pos);
+ if (!stop)
+ return;
+
+ m_dragModel->changeStop(stop, m_dragColor);
+ m_changedStop = stop;
+ m_dragStop = m_model->at(stop->position());
+}
+
+void QtGradientStopsWidgetPrivate::cloneStop(qreal pos)
+{
+ if (m_clonedStop) {
+ m_dragModel->moveStop(m_clonedStop, pos);
+ return;
+ }
+ QtGradientStop *stop = m_dragModel->at(pos);
+ if (stop)
+ return;
+
+ m_clonedStop = m_dragModel->addStop(pos, m_dragColor);
+}
+
+#endif
+
+void QtGradientStopsWidget::setZoom(double zoom)
+{
+ double z = zoom;
+ if (z < 1)
+ z = 1;
+ else if (z > 100)
+ z = 100;
+
+ if (d_ptr->m_zoom == z)
+ return;
+
+ d_ptr->m_zoom = z;
+ int oldMax = horizontalScrollBar()->maximum();
+ int oldVal = horizontalScrollBar()->value();
+ horizontalScrollBar()->setRange(0, qRound(d_ptr->m_scaleFactor * (d_ptr->m_zoom - 1)));
+ int newMax = horizontalScrollBar()->maximum();
+ double newVal = (oldVal + (double)d_ptr->m_scaleFactor / 2) * (newMax + d_ptr->m_scaleFactor)
+ / (oldMax + d_ptr->m_scaleFactor) - (double)d_ptr->m_scaleFactor / 2;
+ horizontalScrollBar()->setValue(qRound(newVal));
+ viewport()->update();
+}
+
+double QtGradientStopsWidget::zoom() const
+{
+ return d_ptr->m_zoom;
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qtgradientstopswidget.cpp"
diff --git a/src/shared/qtgradienteditor/qtgradientstopswidget.h b/src/shared/qtgradienteditor/qtgradientstopswidget.h
new file mode 100644
index 000000000..a6893c07b
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientstopswidget.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTGRADIENTSTOPSWIDGET_H
+#define QTGRADIENTSTOPSWIDGET_H
+
+#include <QtGui/QAbstractScrollArea>
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientStopsModel;
+class QtGradientStopsWidgetPrivate;
+
+class QtGradientStopsWidget : public QAbstractScrollArea
+{
+ Q_OBJECT
+ Q_PROPERTY(bool backgroundCheckered READ isBackgroundCheckered WRITE setBackgroundCheckered)
+public:
+ QtGradientStopsWidget(QWidget *parent = 0);
+ ~QtGradientStopsWidget();
+
+ QSize minimumSizeHint() const;
+ QSize sizeHint() const;
+
+ bool isBackgroundCheckered() const;
+ void setBackgroundCheckered(bool checkered);
+
+ void setGradientStopsModel(QtGradientStopsModel *model);
+
+ void setZoom(double zoom);
+ double zoom() const;
+
+signals:
+
+ void zoomChanged(double zoom);
+
+protected:
+ void paintEvent(QPaintEvent *e);
+ void mousePressEvent(QMouseEvent *e);
+ void mouseReleaseEvent(QMouseEvent *e);
+ void mouseMoveEvent(QMouseEvent *e);
+ void mouseDoubleClickEvent(QMouseEvent *e);
+ void keyPressEvent(QKeyEvent *e);
+ void focusInEvent(QFocusEvent *e);
+ void focusOutEvent(QFocusEvent *e);
+ void contextMenuEvent(QContextMenuEvent *e);
+ void wheelEvent(QWheelEvent *e);
+#ifndef QT_NO_DRAGANDDROP
+ void dragEnterEvent(QDragEnterEvent *event);
+ void dragMoveEvent(QDragMoveEvent *event);
+ void dragLeaveEvent(QDragLeaveEvent *event);
+ void dropEvent(QDropEvent *event);
+#endif
+
+private:
+ QScopedPointer<QtGradientStopsWidgetPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtGradientStopsWidget)
+ Q_DISABLE_COPY(QtGradientStopsWidget)
+ Q_PRIVATE_SLOT(d_func(), void slotStopAdded(QtGradientStop *stop))
+ Q_PRIVATE_SLOT(d_func(), void slotStopRemoved(QtGradientStop *stop))
+ Q_PRIVATE_SLOT(d_func(), void slotStopMoved(QtGradientStop *stop, qreal newPos))
+ Q_PRIVATE_SLOT(d_func(), void slotStopsSwapped(QtGradientStop *stop1, QtGradientStop *stop2))
+ Q_PRIVATE_SLOT(d_func(), void slotStopChanged(QtGradientStop *stop, const QColor &newColor))
+ Q_PRIVATE_SLOT(d_func(), void slotStopSelected(QtGradientStop *stop, bool selected))
+ Q_PRIVATE_SLOT(d_func(), void slotCurrentStopChanged(QtGradientStop *stop))
+ Q_PRIVATE_SLOT(d_func(), void slotNewStop())
+ Q_PRIVATE_SLOT(d_func(), void slotDelete())
+ Q_PRIVATE_SLOT(d_func(), void slotFlipAll())
+ Q_PRIVATE_SLOT(d_func(), void slotSelectAll())
+ Q_PRIVATE_SLOT(d_func(), void slotZoomIn())
+ Q_PRIVATE_SLOT(d_func(), void slotZoomOut())
+ Q_PRIVATE_SLOT(d_func(), void slotResetZoom())
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtgradienteditor/qtgradientutils.cpp b/src/shared/qtgradienteditor/qtgradientutils.cpp
new file mode 100644
index 000000000..cfc4c25b8
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientutils.cpp
@@ -0,0 +1,420 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtgradientutils.h"
+#include "qtgradientmanager.h"
+#include <QtGui/QLinearGradient>
+#include <QtGui/QRadialGradient>
+#include <QtGui/QConicalGradient>
+#include <QtXml/QDomDocument>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+static QString gradientTypeToString(QGradient::Type type)
+{
+ if (type == QGradient::LinearGradient)
+ return QLatin1String("LinearGradient");
+ if (type == QGradient::RadialGradient)
+ return QLatin1String("RadialGradient");
+ if (type == QGradient::ConicalGradient)
+ return QLatin1String("ConicalGradient");
+ return QLatin1String("NoGradient");
+}
+
+static QGradient::Type stringToGradientType(const QString &name)
+{
+ if (name == QLatin1String("LinearGradient"))
+ return QGradient::LinearGradient;
+ if (name == QLatin1String("RadialGradient"))
+ return QGradient::RadialGradient;
+ if (name == QLatin1String("ConicalGradient"))
+ return QGradient::ConicalGradient;
+ return QGradient::NoGradient;
+}
+
+static QString gradientSpreadToString(QGradient::Spread spread)
+{
+ if (spread == QGradient::PadSpread)
+ return QLatin1String("PadSpread");
+ if (spread == QGradient::RepeatSpread)
+ return QLatin1String("RepeatSpread");
+ if (spread == QGradient::ReflectSpread)
+ return QLatin1String("ReflectSpread");
+ return QLatin1String("PadSpread");
+}
+
+static QGradient::Spread stringToGradientSpread(const QString &name)
+{
+ if (name == QLatin1String("PadSpread"))
+ return QGradient::PadSpread;
+ if (name == QLatin1String("RepeatSpread"))
+ return QGradient::RepeatSpread;
+ if (name == QLatin1String("ReflectSpread"))
+ return QGradient::ReflectSpread;
+ return QGradient::PadSpread;
+}
+
+static QString gradientCoordinateModeToString(QGradient::CoordinateMode mode)
+{
+ if (mode == QGradient::LogicalMode)
+ return QLatin1String("LogicalMode");
+ if (mode == QGradient::StretchToDeviceMode)
+ return QLatin1String("StretchToDeviceMode");
+ if (mode == QGradient::ObjectBoundingMode)
+ return QLatin1String("ObjectBoundingMode");
+ return QLatin1String("StretchToDeviceMode");
+}
+
+static QGradient::CoordinateMode stringToGradientCoordinateMode(const QString &name)
+{
+ if (name == QLatin1String("LogicalMode"))
+ return QGradient::LogicalMode;
+ if (name == QLatin1String("StretchToDeviceMode"))
+ return QGradient::StretchToDeviceMode;
+ if (name == QLatin1String("ObjectBoundingMode"))
+ return QGradient::ObjectBoundingMode;
+ return QGradient::StretchToDeviceMode;
+}
+
+static QDomElement saveColor(QDomDocument &doc, const QColor &color)
+{
+ QDomElement colorElem = doc.createElement(QLatin1String("colorData"));
+
+ colorElem.setAttribute(QLatin1String("r"), QString::number(color.red()));
+ colorElem.setAttribute(QLatin1String("g"), QString::number(color.green()));
+ colorElem.setAttribute(QLatin1String("b"), QString::number(color.blue()));
+ colorElem.setAttribute(QLatin1String("a"), QString::number(color.alpha()));
+
+ return colorElem;
+}
+
+static QDomElement saveGradientStop(QDomDocument &doc, const QGradientStop &stop)
+{
+ QDomElement stopElem = doc.createElement(QLatin1String("stopData"));
+
+ stopElem.setAttribute(QLatin1String("position"), QString::number(stop.first));
+
+ const QDomElement colorElem = saveColor(doc, stop.second);
+ stopElem.appendChild(colorElem);
+
+ return stopElem;
+}
+
+static QDomElement saveGradient(QDomDocument &doc, const QGradient &gradient)
+{
+ QDomElement gradElem = doc.createElement(QLatin1String("gradientData"));
+
+ const QGradient::Type type = gradient.type();
+ gradElem.setAttribute(QLatin1String("type"), gradientTypeToString(type));
+ gradElem.setAttribute(QLatin1String("spread"), gradientSpreadToString(gradient.spread()));
+ gradElem.setAttribute(QLatin1String("coordinateMode"), gradientCoordinateModeToString(gradient.coordinateMode()));
+
+ QGradientStops stops = gradient.stops();
+ QVectorIterator<QGradientStop > it(stops);
+ while (it.hasNext())
+ gradElem.appendChild(saveGradientStop(doc, it.next()));
+
+ if (type == QGradient::LinearGradient) {
+ const QLinearGradient &g = *static_cast<const QLinearGradient *>(&gradient);
+ gradElem.setAttribute(QLatin1String("startX"), QString::number(g.start().x()));
+ gradElem.setAttribute(QLatin1String("startY"), QString::number(g.start().y()));
+ gradElem.setAttribute(QLatin1String("endX"), QString::number(g.finalStop().x()));
+ gradElem.setAttribute(QLatin1String("endY"), QString::number(g.finalStop().y()));
+ } else if (type == QGradient::RadialGradient) {
+ const QRadialGradient &g = *static_cast<const QRadialGradient *>(&gradient);
+ gradElem.setAttribute(QLatin1String("centerX"), QString::number(g.center().x()));
+ gradElem.setAttribute(QLatin1String("centerY"), QString::number(g.center().y()));
+ gradElem.setAttribute(QLatin1String("focalX"), QString::number(g.focalPoint().x()));
+ gradElem.setAttribute(QLatin1String("focalY"), QString::number(g.focalPoint().y()));
+ gradElem.setAttribute(QLatin1String("radius"), QString::number(g.radius()));
+ } else if (type == QGradient::ConicalGradient) {
+ const QConicalGradient &g = *static_cast<const QConicalGradient*>(&gradient);
+ gradElem.setAttribute(QLatin1String("centerX"), QString::number(g.center().x()));
+ gradElem.setAttribute(QLatin1String("centerY"), QString::number(g.center().y()));
+ gradElem.setAttribute(QLatin1String("angle"), QString::number(g.angle()));
+ }
+
+ return gradElem;
+}
+
+static QColor loadColor(const QDomElement &elem)
+{
+ if (elem.tagName() != QLatin1String("colorData"))
+ return QColor();
+
+ return QColor(elem.attribute(QLatin1String("r")).toInt(),
+ elem.attribute(QLatin1String("g")).toInt(),
+ elem.attribute(QLatin1String("b")).toInt(),
+ elem.attribute(QLatin1String("a")).toInt());
+}
+
+static QGradientStop loadGradientStop(const QDomElement &elem)
+{
+ if (elem.tagName() != QLatin1String("stopData"))
+ return QGradientStop();
+
+ const qreal pos = static_cast<qreal>(elem.attribute(QLatin1String("position")).toDouble());
+ return qMakePair(pos, loadColor(elem.firstChild().toElement()));
+}
+
+static QGradient loadGradient(const QDomElement &elem)
+{
+ if (elem.tagName() != QLatin1String("gradientData"))
+ return QLinearGradient();
+
+ const QGradient::Type type = stringToGradientType(elem.attribute(QLatin1String("type")));
+ const QGradient::Spread spread = stringToGradientSpread(elem.attribute(QLatin1String("spread")));
+ const QGradient::CoordinateMode mode = stringToGradientCoordinateMode(elem.attribute(QLatin1String("coordinateMode")));
+
+ QGradient gradient = QLinearGradient();
+
+ if (type == QGradient::LinearGradient) {
+ QLinearGradient g;
+ g.setStart(elem.attribute(QLatin1String("startX")).toDouble(), elem.attribute(QLatin1String("startY")).toDouble());
+ g.setFinalStop(elem.attribute(QLatin1String("endX")).toDouble(), elem.attribute(QLatin1String("endY")).toDouble());
+ gradient = g;
+ } else if (type == QGradient::RadialGradient) {
+ QRadialGradient g;
+ g.setCenter(elem.attribute(QLatin1String("centerX")).toDouble(), elem.attribute(QLatin1String("centerY")).toDouble());
+ g.setFocalPoint(elem.attribute(QLatin1String("focalX")).toDouble(), elem.attribute(QLatin1String("focalY")).toDouble());
+ g.setRadius(elem.attribute(QLatin1String("radius")).toDouble());
+ gradient = g;
+ } else if (type == QGradient::ConicalGradient) {
+ QConicalGradient g;
+ g.setCenter(elem.attribute(QLatin1String("centerX")).toDouble(), elem.attribute(QLatin1String("centerY")).toDouble());
+ g.setAngle(elem.attribute(QLatin1String("angle")).toDouble());
+ gradient = g;
+ }
+
+ QDomElement stopElem = elem.firstChildElement();
+ while (!stopElem.isNull()) {
+ QGradientStop stop = loadGradientStop(stopElem);
+
+ gradient.setColorAt(stop.first, stop.second);
+
+ stopElem = stopElem.nextSiblingElement();
+ }
+
+ gradient.setSpread(spread);
+ gradient.setCoordinateMode(mode);
+
+ return gradient;
+}
+
+QString QtGradientUtils::saveState(const QtGradientManager *manager)
+{
+ QDomDocument doc;
+
+ QDomElement rootElem = doc.createElement(QLatin1String("gradients"));
+
+ QMap<QString, QGradient> grads = manager->gradients();
+ QMapIterator<QString, QGradient> itGrad(grads);
+ while (itGrad.hasNext()) {
+ itGrad.next();
+ QDomElement idElem = doc.createElement(QLatin1String("gradient"));
+ idElem.setAttribute(QLatin1String("name"), itGrad.key());
+ QDomElement gradElem = saveGradient(doc, itGrad.value());
+ idElem.appendChild(gradElem);
+
+ rootElem.appendChild(idElem);
+ }
+
+ doc.appendChild(rootElem);
+
+ return doc.toString();
+}
+
+void QtGradientUtils::restoreState(QtGradientManager *manager, const QString &state)
+{
+ manager->clear();
+
+ QDomDocument doc;
+ doc.setContent(state);
+
+ QDomElement rootElem = doc.documentElement();
+
+ QDomElement gradElem = rootElem.firstChildElement();
+ while (!gradElem.isNull()) {
+ const QString name = gradElem.attribute(QLatin1String("name"));
+ const QGradient gradient = loadGradient(gradElem.firstChildElement());
+
+ manager->addGradient(name, gradient);
+ gradElem = gradElem.nextSiblingElement();
+ }
+}
+
+QPixmap QtGradientUtils::gradientPixmap(const QGradient &gradient, const QSize &size, bool checkeredBackground)
+{
+ QImage image(size, QImage::Format_ARGB32);
+ QPainter p(&image);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+
+ if (checkeredBackground) {
+ int pixSize = 20;
+ QPixmap pm(2 * pixSize, 2 * pixSize);
+
+ QPainter pmp(&pm);
+ pmp.fillRect(0, 0, pixSize, pixSize, Qt::lightGray);
+ pmp.fillRect(pixSize, pixSize, pixSize, pixSize, Qt::lightGray);
+ pmp.fillRect(0, pixSize, pixSize, pixSize, Qt::darkGray);
+ pmp.fillRect(pixSize, 0, pixSize, pixSize, Qt::darkGray);
+
+ p.setBrushOrigin((size.width() % pixSize + pixSize) / 2, (size.height() % pixSize + pixSize) / 2);
+ p.fillRect(0, 0, size.width(), size.height(), pm);
+ p.setBrushOrigin(0, 0);
+ p.setCompositionMode(QPainter::CompositionMode_SourceOver);
+ }
+
+ const qreal scaleFactor = 0.999999;
+ p.scale(scaleFactor, scaleFactor);
+ QGradient grad = gradient;
+ grad.setCoordinateMode(QGradient::StretchToDeviceMode);
+ p.fillRect(QRect(0, 0, size.width(), size.height()), grad);
+ p.drawRect(QRect(0, 0, size.width() - 1, size.height() - 1));
+
+ return QPixmap::fromImage(image);
+}
+
+static QString styleSheetFillName(const QGradient &gradient)
+{
+ QString result;
+
+ switch (gradient.type()) {
+ case QGradient::LinearGradient:
+ result += QLatin1String("qlineargradient");
+ break;
+ case QGradient::RadialGradient:
+ result += QLatin1String("qradialgradient");
+ break;
+ case QGradient::ConicalGradient:
+ result += QLatin1String("qconicalgradient");
+ break;
+ default:
+ qWarning() << "QtGradientUtils::styleSheetFillName(): gradient type" << gradient.type() << "not supported!";
+ break;
+ }
+
+ return result;
+}
+
+static QStringList styleSheetParameters(const QGradient &gradient)
+{
+ QStringList result;
+
+ if (gradient.type() != QGradient::ConicalGradient) {
+ QString spread;
+ switch (gradient.spread()) {
+ case QGradient::PadSpread:
+ spread = QLatin1String("pad");
+ break;
+ case QGradient::ReflectSpread:
+ spread = QLatin1String("reflect");
+ break;
+ case QGradient::RepeatSpread:
+ spread = QLatin1String("repeat");
+ break;
+ default:
+ qWarning() << "QtGradientUtils::styleSheetParameters(): gradient spread" << gradient.spread() << "not supported!";
+ break;
+ }
+ result << QLatin1String("spread:") + spread;
+ }
+
+ switch (gradient.type()) {
+ case QGradient::LinearGradient: {
+ const QLinearGradient *linearGradient = static_cast<const QLinearGradient*>(&gradient);
+ result << QLatin1String("x1:") + QString::number(linearGradient->start().x())
+ << QLatin1String("y1:") + QString::number(linearGradient->start().y())
+ << QLatin1String("x2:") + QString::number(linearGradient->finalStop().x())
+ << QLatin1String("y2:") + QString::number(linearGradient->finalStop().y());
+ break;
+ }
+ case QGradient::RadialGradient: {
+ const QRadialGradient *radialGradient = static_cast<const QRadialGradient*>(&gradient);
+ result << QLatin1String("cx:") + QString::number(radialGradient->center().x())
+ << QLatin1String("cy:") + QString::number(radialGradient->center().y())
+ << QLatin1String("radius:") + QString::number(radialGradient->radius())
+ << QLatin1String("fx:") + QString::number(radialGradient->focalPoint().x())
+ << QLatin1String("fy:") + QString::number(radialGradient->focalPoint().y());
+ break;
+ }
+ case QGradient::ConicalGradient: {
+ const QConicalGradient *conicalGradient = static_cast<const QConicalGradient*>(&gradient);
+ result << QLatin1String("cx:") + QString::number(conicalGradient->center().x())
+ << QLatin1String("cy:") + QString::number(conicalGradient->center().y())
+ << QLatin1String("angle:") + QString::number(conicalGradient->angle());
+ break;
+ }
+ default:
+ qWarning() << "QtGradientUtils::styleSheetParameters(): gradient type" << gradient.type() << "not supported!";
+ break;
+ }
+
+ return result;
+}
+
+static QStringList styleSheetStops(const QGradient &gradient)
+{
+ QStringList result;
+ foreach (const QGradientStop &stop, gradient.stops()) {
+ const QColor color = stop.second;
+
+ const QString stopDescription = QLatin1String("stop:") + QString::number(stop.first) + QLatin1String(" rgba(")
+ + QString::number(color.red()) + QLatin1String(", ")
+ + QString::number(color.green()) + QLatin1String(", ")
+ + QString::number(color.blue()) + QLatin1String(", ")
+ + QString::number(color.alpha()) + QLatin1Char(')');
+ result << stopDescription;
+ }
+
+ return result;
+}
+
+QString QtGradientUtils::styleSheetCode(const QGradient &gradient)
+{
+ QStringList gradientParameters;
+ gradientParameters << styleSheetParameters(gradient) << styleSheetStops(gradient);
+
+ return styleSheetFillName(gradient) + QLatin1Char('(') + gradientParameters.join(QLatin1String(", ")) + QLatin1Char(')');
+}
+
+QT_END_NAMESPACE
diff --git a/src/shared/qtgradienteditor/qtgradientutils.h b/src/shared/qtgradienteditor/qtgradientutils.h
new file mode 100644
index 000000000..6c0d75e60
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientutils.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GRADIENTUTILS_H
+#define GRADIENTUTILS_H
+
+#include <QtGui/QGradient>
+#include <QtGui/QPainter>
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientManager;
+
+class QtGradientUtils
+{
+public:
+ static QString styleSheetCode(const QGradient &gradient);
+ // utils methods, they could be outside of this class
+ static QString saveState(const QtGradientManager *manager);
+ static void restoreState(QtGradientManager *manager, const QString &state);
+
+ static QPixmap gradientPixmap(const QGradient &gradient, const QSize &size = QSize(64, 64), bool checkeredBackground = false);
+
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtgradienteditor/qtgradientview.cpp b/src/shared/qtgradienteditor/qtgradientview.cpp
new file mode 100644
index 000000000..a3d17950d
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientview.cpp
@@ -0,0 +1,292 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtgradientview.h"
+#include "qtgradientmanager.h"
+#include "qtgradientdialog.h"
+#include "qtgradientutils.h"
+#include <QtGui/QPainter>
+#include <QtGui/QMessageBox>
+#include <QtGui/QClipboard>
+
+QT_BEGIN_NAMESPACE
+
+void QtGradientView::slotGradientAdded(const QString &id, const QGradient &gradient)
+{
+ QListWidgetItem *item = new QListWidgetItem(QtGradientUtils::gradientPixmap(gradient), id, m_ui.listWidget);
+ item->setToolTip(id);
+ item->setSizeHint(QSize(72, 84));
+ item->setFlags(item->flags() | Qt::ItemIsEditable);
+
+ m_idToItem[id] = item;
+ m_itemToId[item] = id;
+}
+
+void QtGradientView::slotGradientRenamed(const QString &id, const QString &newId)
+{
+ if (!m_idToItem.contains(id))
+ return;
+
+ QListWidgetItem *item = m_idToItem.value(id);
+ item->setText(newId);
+ item->setToolTip(newId);
+ m_itemToId[item] = newId;
+ m_idToItem.remove(id);
+ m_idToItem[newId] = item;
+}
+
+void QtGradientView::slotGradientChanged(const QString &id, const QGradient &newGradient)
+{
+ if (!m_idToItem.contains(id))
+ return;
+
+ QListWidgetItem *item = m_idToItem.value(id);
+ item->setIcon(QtGradientUtils::gradientPixmap(newGradient));
+}
+
+void QtGradientView::slotGradientRemoved(const QString &id)
+{
+ if (!m_idToItem.contains(id))
+ return;
+
+ QListWidgetItem *item = m_idToItem.value(id);
+ delete item;
+ m_itemToId.remove(item);
+ m_idToItem.remove(id);
+}
+
+void QtGradientView::slotNewGradient()
+{
+ bool ok;
+ QListWidgetItem *item = m_ui.listWidget->currentItem();
+ QGradient grad = QLinearGradient();
+ if (item)
+ grad = m_manager->gradients().value(m_itemToId.value(item));
+ QGradient gradient = QtGradientDialog::getGradient(&ok, grad, this);
+ if (!ok)
+ return;
+
+ QString id = m_manager->addGradient(tr("Grad"), gradient);
+ m_ui.listWidget->setCurrentItem(m_idToItem.value(id));
+}
+
+void QtGradientView::slotEditGradient()
+{
+ bool ok;
+ QListWidgetItem *item = m_ui.listWidget->currentItem();
+ if (!item)
+ return;
+
+ const QString id = m_itemToId.value(item);
+ QGradient grad = m_manager->gradients().value(id);
+ QGradient gradient = QtGradientDialog::getGradient(&ok, grad, this);
+ if (!ok)
+ return;
+
+ m_manager->changeGradient(id, gradient);
+}
+
+void QtGradientView::slotRemoveGradient()
+{
+ QListWidgetItem *item = m_ui.listWidget->currentItem();
+ if (!item)
+ return;
+
+ if (QMessageBox::question(this, tr("Remove Gradient"),
+ tr("Are you sure you want to remove the selected gradient?"),
+ QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel) != QMessageBox::Yes)
+ return;
+
+ const QString id = m_itemToId.value(item);
+ m_manager->removeGradient(id);
+}
+
+void QtGradientView::slotRenameGradient()
+{
+ QListWidgetItem *item = m_ui.listWidget->currentItem();
+ if (!item)
+ return;
+
+ m_ui.listWidget->editItem(item);
+}
+
+void QtGradientView::slotRenameGradient(QListWidgetItem *item)
+{
+ if (!item)
+ return;
+
+ const QString id = m_itemToId.value(item);
+ m_manager->renameGradient(id, item->text());
+}
+
+void QtGradientView::slotCurrentItemChanged(QListWidgetItem *item)
+{
+ m_editAction->setEnabled(item);
+ m_renameAction->setEnabled(item);
+ m_removeAction->setEnabled(item);
+ emit currentGradientChanged(m_itemToId.value(item));
+}
+
+void QtGradientView::slotGradientActivated(QListWidgetItem *item)
+{
+ const QString id = m_itemToId.value(item);
+ if (!id.isEmpty())
+ emit gradientActivated(id);
+}
+
+QtGradientView::QtGradientView(QWidget *parent)
+ : QWidget(parent)
+{
+ m_manager = 0;
+
+ m_ui.setupUi(this);
+
+ m_ui.listWidget->setViewMode(QListView::IconMode);
+ m_ui.listWidget->setMovement(QListView::Static);
+ m_ui.listWidget->setTextElideMode(Qt::ElideRight);
+ m_ui.listWidget->setResizeMode(QListWidget::Adjust);
+ m_ui.listWidget->setIconSize(QSize(64, 64));
+ m_ui.listWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
+
+ QPalette pal = m_ui.listWidget->viewport()->palette();
+ int pixSize = 18;
+ QPixmap pm(2 * pixSize, 2 * pixSize);
+
+ QColor c1 = palette().color(QPalette::Midlight);
+ QColor c2 = palette().color(QPalette::Dark);
+ QPainter pmp(&pm);
+ pmp.fillRect(0, 0, pixSize, pixSize, c1);
+ pmp.fillRect(pixSize, pixSize, pixSize, pixSize, c1);
+ pmp.fillRect(0, pixSize, pixSize, pixSize, c2);
+ pmp.fillRect(pixSize, 0, pixSize, pixSize, c2);
+
+ pal.setBrush(QPalette::Base, QBrush(pm));
+ m_ui.listWidget->viewport()->setPalette(pal);
+
+ connect(m_ui.listWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(slotGradientActivated(QListWidgetItem*)));
+ connect(m_ui.listWidget, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(slotRenameGradient(QListWidgetItem*)));
+ connect(m_ui.listWidget, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), this, SLOT(slotCurrentItemChanged(QListWidgetItem*)));
+
+ m_newAction = new QAction(QIcon(QLatin1String(":/trolltech/qtgradienteditor/images/plus.png")), tr("New..."), this);
+ m_editAction = new QAction(QIcon(QLatin1String(":/trolltech/qtgradienteditor/images/edit.png")), tr("Edit..."), this);
+ m_renameAction = new QAction(tr("Rename"), this);
+ m_removeAction = new QAction(QIcon(QLatin1String(":/trolltech/qtgradienteditor/images/minus.png")), tr("Remove"), this);
+
+ connect(m_newAction, SIGNAL(triggered()), this, SLOT(slotNewGradient()));
+ connect(m_editAction, SIGNAL(triggered()), this, SLOT(slotEditGradient()));
+ connect(m_removeAction, SIGNAL(triggered()), this, SLOT(slotRemoveGradient()));
+ connect(m_renameAction, SIGNAL(triggered()), this, SLOT(slotRenameGradient()));
+
+ m_ui.listWidget->addAction(m_newAction);
+ m_ui.listWidget->addAction(m_editAction);
+ m_ui.listWidget->addAction(m_renameAction);
+ m_ui.listWidget->addAction(m_removeAction);
+
+ m_ui.newButton->setDefaultAction(m_newAction);
+ m_ui.editButton->setDefaultAction(m_editAction);
+ m_ui.renameButton->setDefaultAction(m_renameAction);
+ m_ui.removeButton->setDefaultAction(m_removeAction);
+
+ m_ui.listWidget->setContextMenuPolicy(Qt::ActionsContextMenu);
+}
+
+void QtGradientView::setGradientManager(QtGradientManager *manager)
+{
+ if (m_manager == manager)
+ return;
+
+ if (m_manager) {
+ disconnect(m_manager, SIGNAL(gradientAdded(QString,QGradient)),
+ this, SLOT(slotGradientAdded(QString,QGradient)));
+ disconnect(m_manager, SIGNAL(gradientRenamed(QString,QString)),
+ this, SLOT(slotGradientRenamed(QString,QString)));
+ disconnect(m_manager, SIGNAL(gradientChanged(QString,QGradient)),
+ this, SLOT(slotGradientChanged(QString,QGradient)));
+ disconnect(m_manager, SIGNAL(gradientRemoved(QString)),
+ this, SLOT(slotGradientRemoved(QString)));
+
+ m_ui.listWidget->clear();
+ m_idToItem.clear();
+ m_itemToId.clear();
+ }
+
+ m_manager = manager;
+
+ if (!m_manager)
+ return;
+
+ QMap<QString, QGradient> gradients = m_manager->gradients();
+ QMapIterator<QString, QGradient> itGrad(gradients);
+ while (itGrad.hasNext()) {
+ itGrad.next();
+ slotGradientAdded(itGrad.key(), itGrad.value());
+ }
+
+ connect(m_manager, SIGNAL(gradientAdded(QString,QGradient)),
+ this, SLOT(slotGradientAdded(QString,QGradient)));
+ connect(m_manager, SIGNAL(gradientRenamed(QString,QString)),
+ this, SLOT(slotGradientRenamed(QString,QString)));
+ connect(m_manager, SIGNAL(gradientChanged(QString,QGradient)),
+ this, SLOT(slotGradientChanged(QString,QGradient)));
+ connect(m_manager, SIGNAL(gradientRemoved(QString)),
+ this, SLOT(slotGradientRemoved(QString)));
+}
+
+QtGradientManager *QtGradientView::gradientManager() const
+{
+ return m_manager;
+}
+
+void QtGradientView::setCurrentGradient(const QString &id)
+{
+ QListWidgetItem *item = m_idToItem.value(id);
+ if (!item)
+ return;
+
+ m_ui.listWidget->setCurrentItem(item);
+}
+
+QString QtGradientView::currentGradient() const
+{
+ return m_itemToId.value(m_ui.listWidget->currentItem());
+}
+
+QT_END_NAMESPACE
diff --git a/src/shared/qtgradienteditor/qtgradientview.h b/src/shared/qtgradienteditor/qtgradientview.h
new file mode 100644
index 000000000..8a45ecfcb
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientview.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GRADIENTVIEW_H
+#define GRADIENTVIEW_H
+
+#include <QtGui/QWidget>
+#include <QtCore/QMap>
+#include "ui_qtgradientview.h"
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientManager;
+class QListViewItem;
+class QAction;
+
+class QtGradientView : public QWidget
+{
+ Q_OBJECT
+public:
+ QtGradientView(QWidget *parent = 0);
+
+ void setGradientManager(QtGradientManager *manager);
+ QtGradientManager *gradientManager() const;
+
+ void setCurrentGradient(const QString &id);
+ QString currentGradient() const;
+
+signals:
+ void currentGradientChanged(const QString &id);
+ void gradientActivated(const QString &id);
+
+private slots:
+ void slotGradientAdded(const QString &id, const QGradient &gradient);
+ void slotGradientRenamed(const QString &id, const QString &newId);
+ void slotGradientChanged(const QString &id, const QGradient &newGradient);
+ void slotGradientRemoved(const QString &id);
+ void slotNewGradient();
+ void slotEditGradient();
+ void slotRemoveGradient();
+ void slotRenameGradient();
+ void slotRenameGradient(QListWidgetItem *item);
+ void slotCurrentItemChanged(QListWidgetItem *item);
+ void slotGradientActivated(QListWidgetItem *item);
+
+private:
+ QMap<QString, QListWidgetItem *> m_idToItem;
+ QMap<QListWidgetItem *, QString> m_itemToId;
+
+ QAction *m_newAction;
+ QAction *m_editAction;
+ QAction *m_renameAction;
+ QAction *m_removeAction;
+
+ QtGradientManager *m_manager;
+ Ui::QtGradientView m_ui;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtgradienteditor/qtgradientview.ui b/src/shared/qtgradienteditor/qtgradientview.ui
new file mode 100644
index 000000000..af7267ea2
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientview.ui
@@ -0,0 +1,135 @@
+<ui version="4.0" >
+ <class>QtGradientView</class>
+ <widget class="QWidget" name="QtGradientView" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>484</width>
+ <height>228</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Gradient View</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
+ </property>
+ <property name="topMargin" >
+ <number>0</number>
+ </property>
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" >
+ <item>
+ <widget class="QToolButton" name="newButton" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Minimum" hsizetype="Minimum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>New...</string>
+ </property>
+ <property name="toolButtonStyle" >
+ <enum>Qt::ToolButtonTextBesideIcon</enum>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="editButton" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Minimum" hsizetype="Minimum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Edit...</string>
+ </property>
+ <property name="toolButtonStyle" >
+ <enum>Qt::ToolButtonTextBesideIcon</enum>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="renameButton" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Minimum" hsizetype="Minimum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Rename</string>
+ </property>
+ <property name="toolButtonStyle" >
+ <enum>Qt::ToolButtonTextBesideIcon</enum>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="removeButton" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Minimum" hsizetype="Minimum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Remove</string>
+ </property>
+ <property name="toolButtonStyle" >
+ <enum>Qt::ToolButtonTextBesideIcon</enum>
+ </property>
+ <property name="autoRaise" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>71</width>
+ <height>26</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QListWidget" name="listWidget" />
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>listWidget</tabstop>
+ <tabstop>newButton</tabstop>
+ <tabstop>editButton</tabstop>
+ <tabstop>renameButton</tabstop>
+ <tabstop>removeButton</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/shared/qtgradienteditor/qtgradientviewdialog.cpp b/src/shared/qtgradienteditor/qtgradientviewdialog.cpp
new file mode 100644
index 000000000..260641d32
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientviewdialog.cpp
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtgradientviewdialog.h"
+#include "qtgradientmanager.h"
+#include <QtGui/QPushButton>
+
+QT_BEGIN_NAMESPACE
+
+QtGradientViewDialog::QtGradientViewDialog(QWidget *parent)
+ : QDialog(parent)
+{
+ m_ui.setupUi(this);
+ m_ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
+ connect(m_ui.gradientView, SIGNAL(currentGradientChanged(QString)),
+ this, SLOT(slotGradientSelected(QString)));
+ connect(m_ui.gradientView, SIGNAL(gradientActivated(QString)),
+ this, SLOT(slotGradientActivated(QString)));
+}
+
+void QtGradientViewDialog::setGradientManager(QtGradientManager *manager)
+{
+ m_ui.gradientView->setGradientManager(manager);
+}
+
+QGradient QtGradientViewDialog::getGradient(bool *ok, QtGradientManager *manager, QWidget *parent, const QString &caption)
+{
+ QtGradientViewDialog dlg(parent);
+ dlg.setGradientManager(manager);
+ dlg.setWindowTitle(caption);
+ QGradient grad = QLinearGradient();
+ const int res = dlg.exec();
+ if (res == QDialog::Accepted)
+ grad = dlg.m_ui.gradientView->gradientManager()->gradients().value(dlg.m_ui.gradientView->currentGradient());
+ if (ok)
+ *ok = res == QDialog::Accepted;
+ return grad;
+}
+
+void QtGradientViewDialog::slotGradientSelected(const QString &id)
+{
+ m_ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!id.isEmpty());
+}
+
+void QtGradientViewDialog::slotGradientActivated(const QString &id)
+{
+ Q_UNUSED(id)
+ accept();
+}
+
+QT_END_NAMESPACE
diff --git a/src/shared/qtgradienteditor/qtgradientviewdialog.h b/src/shared/qtgradienteditor/qtgradientviewdialog.h
new file mode 100644
index 000000000..66cfeea40
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientviewdialog.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GRADIENTVIEWDIALOG_H
+#define GRADIENTVIEWDIALOG_H
+
+#include <QtGui/QWidget>
+#include <QtCore/QMap>
+#include "ui_qtgradientviewdialog.h"
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientManager;
+
+class QtGradientViewDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ QtGradientViewDialog(QWidget *parent = 0);
+
+ void setGradientManager(QtGradientManager *manager);
+ QtGradientManager *gradientManager() const;
+
+ static QGradient getGradient(bool *ok, QtGradientManager *manager, QWidget *parent = 0, const QString &caption = tr("Select Gradient", 0));
+
+private slots:
+ void slotGradientSelected(const QString &id);
+ void slotGradientActivated(const QString &id);
+
+private:
+ Ui::QtGradientViewDialog m_ui;
+};
+
+QT_END_NAMESPACE
+
+#endif
+
diff --git a/src/shared/qtgradienteditor/qtgradientviewdialog.ui b/src/shared/qtgradienteditor/qtgradientviewdialog.ui
new file mode 100644
index 000000000..1aa32a323
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientviewdialog.ui
@@ -0,0 +1,121 @@
+<ui version="4.0" >
+ <comment>*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <class>QtGradientViewDialog</class>
+ <widget class="QDialog" name="QtGradientViewDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>178</width>
+ <height>72</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Select Gradient</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <item>
+ <widget class="QtGradientView" name="gradientView" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="MinimumExpanding" hsizetype="MinimumExpanding" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QtGradientView</class>
+ <extends>QFrame</extends>
+ <header>qtgradientview.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>QtGradientViewDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>72</x>
+ <y>224</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>21</x>
+ <y>243</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>QtGradientViewDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>168</x>
+ <y>233</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>152</x>
+ <y>251</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/shared/qtgradienteditor/qtgradientwidget.cpp b/src/shared/qtgradienteditor/qtgradientwidget.cpp
new file mode 100644
index 000000000..d9056a703
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientwidget.cpp
@@ -0,0 +1,815 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtgradientwidget.h"
+#include <QtCore/QMap>
+#include <QtGui/QImage>
+#include <QtGui/QPainter>
+#include <QtGui/QScrollBar>
+#include <QtGui/QMouseEvent>
+
+#define _USE_MATH_DEFINES
+
+
+#include "math.h"
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientWidgetPrivate
+{
+ QtGradientWidget *q_ptr;
+ Q_DECLARE_PUBLIC(QtGradientWidget)
+public:
+ QPointF fromViewport(const QPointF &point) const;
+ QPointF toViewport(const QPointF &point) const;
+// void setupDrag(QtGradientStop *stop, int x);
+
+ QPointF checkRange(const QPointF &point) const;
+ QRectF pointRect(const QPointF &point, double size) const;
+
+ double correctAngle(double angle) const;
+ void setAngleConical(double angle);
+
+ void paintPoint(QPainter *painter, const QPointF &point, double size) const;
+
+ double m_handleSize;
+ bool m_backgroundCheckered;
+
+ QGradientStops m_gradientStops;
+ QGradient::Type m_gradientType;
+ QGradient::Spread m_gradientSpread;
+ QPointF m_startLinear;
+ QPointF m_endLinear;
+ QPointF m_centralRadial;
+ QPointF m_focalRadial;
+ qreal m_radiusRadial;
+ QPointF m_centralConical;
+ qreal m_angleConical;
+
+ enum Handle {
+ NoHandle,
+ StartLinearHandle,
+ EndLinearHandle,
+ CentralRadialHandle,
+ FocalRadialHandle,
+ RadiusRadialHandle,
+ CentralConicalHandle,
+ AngleConicalHandle
+ };
+
+ Handle m_dragHandle;
+ QPointF m_dragOffset;
+ //double m_radiusOffset;
+ double m_radiusFactor;
+ double m_dragRadius;
+ double m_angleOffset;
+ double m_dragAngle;
+};
+
+double QtGradientWidgetPrivate::correctAngle(double angle) const
+{
+ double a = angle;
+ while (a >= 360)
+ a -= 360;
+ while (a < 0)
+ a += 360;
+ return a;
+}
+
+void QtGradientWidgetPrivate::setAngleConical(double angle)
+{
+ double a = correctAngle(angle);
+ if (m_angleConical == a)
+ return;
+ m_angleConical = a;
+ emit q_ptr->angleConicalChanged(m_angleConical);
+}
+
+QRectF QtGradientWidgetPrivate::pointRect(const QPointF &point, double size) const
+{
+ return QRectF(point.x() - size / 2, point.y() - size / 2, size, size);
+}
+
+QPointF QtGradientWidgetPrivate::checkRange(const QPointF &point) const
+{
+ QPointF p = point;
+ if (p.x() > 1)
+ p.setX(1);
+ else if (p.x() < 0)
+ p.setX(0);
+ if (p.y() > 1)
+ p.setY(1);
+ else if (p.y() < 0)
+ p.setY(0);
+ return p;
+}
+
+QPointF QtGradientWidgetPrivate::fromViewport(const QPointF &point) const
+{
+ QSize size = q_ptr->size();
+ return QPointF(point.x() / size.width(), point.y() / size.height());
+}
+
+QPointF QtGradientWidgetPrivate::toViewport(const QPointF &point) const
+{
+ QSize size = q_ptr->size();
+ return QPointF(point.x() * size.width(), point.y() * size.height());
+}
+
+void QtGradientWidgetPrivate::paintPoint(QPainter *painter, const QPointF &point, double size) const
+{
+ QPointF pf = toViewport(point);
+ QRectF rf = pointRect(pf, size);
+
+ QPen pen;
+ pen.setWidthF(1);
+ QColor alphaZero = Qt::white;
+ alphaZero.setAlpha(0);
+
+ painter->save();
+ painter->drawEllipse(rf);
+
+ /*
+ painter->save();
+
+ QLinearGradient lgV(0, rf.top(), 0, rf.bottom());
+ lgV.setColorAt(0, alphaZero);
+ lgV.setColorAt(0.25, Qt::white);
+ lgV.setColorAt(0.25, Qt::white);
+ lgV.setColorAt(1, alphaZero);
+ pen.setBrush(lgV);
+ painter->setPen(pen);
+
+ painter->drawLine(QPointF(pf.x(), rf.top()), QPointF(pf.x(), rf.bottom()));
+
+ QLinearGradient lgH(rf.left(), 0, rf.right(), 0);
+ lgH.setColorAt(0, alphaZero);
+ lgH.setColorAt(0.5, Qt::white);
+ lgH.setColorAt(1, alphaZero);
+ pen.setBrush(lgH);
+ painter->setPen(pen);
+
+ painter->drawLine(QPointF(rf.left(), pf.y()), QPointF(rf.right(), pf.y()));
+
+ painter->restore();
+ */
+
+ painter->restore();
+}
+
+/*
+void QtGradientWidgetPrivate::setupDrag(QtGradientStop *stop, int x)
+{
+ m_model->setCurrentStop(stop);
+
+ int viewportX = qRound(toViewport(stop->position()));
+ m_dragOffset = x - viewportX;
+
+ QList<QtGradientStop *> stops = m_stops;
+ m_stops.clear();
+ QListIterator<QtGradientStop *> itStop(stops);
+ while (itStop.hasNext()) {
+ QtGradientStop *s = itStop.next();
+ if (m_model->isSelected(s) || s == stop) {
+ m_dragStops[s] = s->position() - stop->position();
+ m_stops.append(s);
+ } else {
+ m_dragOriginal[s->position()] = s->color();
+ }
+ }
+ itStop.toFront();
+ while (itStop.hasNext()) {
+ QtGradientStop *s = itStop.next();
+ if (!m_model->isSelected(s))
+ m_stops.append(s);
+ }
+ m_stops.removeAll(stop);
+ m_stops.prepend(stop);
+}
+*/
+////////////////////////////
+
+QtGradientWidget::QtGradientWidget(QWidget *parent)
+ : QWidget(parent), d_ptr(new QtGradientWidgetPrivate)
+{
+ d_ptr->q_ptr = this;
+ d_ptr->m_backgroundCheckered = true;
+ d_ptr->m_handleSize = 20.0;
+ d_ptr->m_gradientType = QGradient::LinearGradient;
+ d_ptr->m_startLinear = QPointF(0, 0);
+ d_ptr->m_endLinear = QPointF(1, 1);
+ d_ptr->m_centralRadial = QPointF(0.5, 0.5);
+ d_ptr->m_focalRadial = QPointF(0.5, 0.5);
+ d_ptr->m_radiusRadial = 0.5;
+ d_ptr->m_centralConical = QPointF(0.5, 0.5);
+ d_ptr->m_angleConical = 0;
+ d_ptr->m_dragHandle = QtGradientWidgetPrivate::NoHandle;
+
+ setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred));
+}
+
+QtGradientWidget::~QtGradientWidget()
+{
+}
+
+QSize QtGradientWidget::sizeHint() const
+{
+ return QSize(176, 176);
+}
+
+QSize QtGradientWidget::minimumSizeHint() const
+{
+ return QSize(128, 128);
+}
+
+int QtGradientWidget::heightForWidth(int w) const
+{
+ return w;
+}
+
+void QtGradientWidget::setBackgroundCheckered(bool checkered)
+{
+ if (d_ptr->m_backgroundCheckered == checkered)
+ return;
+ d_ptr->m_backgroundCheckered = checkered;
+ update();
+}
+
+bool QtGradientWidget::isBackgroundCheckered() const
+{
+ return d_ptr->m_backgroundCheckered;
+}
+
+void QtGradientWidget::mousePressEvent(QMouseEvent *e)
+{
+ if (e->button() != Qt::LeftButton)
+ return;
+
+ QPoint p = e->pos();
+ if (d_ptr->m_gradientType == QGradient::LinearGradient) {
+ QPointF startPoint = d_ptr->toViewport(d_ptr->m_startLinear);
+ double x = p.x() - startPoint.x();
+ double y = p.y() - startPoint.y();
+
+ if ((d_ptr->m_handleSize * d_ptr->m_handleSize / 4) > (x * x + y * y)) {
+ d_ptr->m_dragHandle = QtGradientWidgetPrivate::StartLinearHandle;
+ d_ptr->m_dragOffset = QPointF(x, y);
+ update();
+ return;
+ }
+
+ QPointF endPoint = d_ptr->toViewport(d_ptr->m_endLinear);
+ x = p.x() - endPoint.x();
+ y = p.y() - endPoint.y();
+
+ if ((d_ptr->m_handleSize * d_ptr->m_handleSize / 4) > (x * x + y * y)) {
+ d_ptr->m_dragHandle = QtGradientWidgetPrivate::EndLinearHandle;
+ d_ptr->m_dragOffset = QPointF(x, y);
+ update();
+ return;
+ }
+ } else if (d_ptr->m_gradientType == QGradient::RadialGradient) {
+ QPointF focalPoint = d_ptr->toViewport(d_ptr->m_focalRadial);
+ double x = p.x() - focalPoint.x();
+ double y = p.y() - focalPoint.y();
+
+ if ((d_ptr->m_handleSize * d_ptr->m_handleSize / 9) > (x * x + y * y)) {
+ d_ptr->m_dragHandle = QtGradientWidgetPrivate::FocalRadialHandle;
+ d_ptr->m_dragOffset = QPointF(x, y);
+ update();
+ return;
+ }
+
+ QPointF centralPoint = d_ptr->toViewport(d_ptr->m_centralRadial);
+ x = p.x() - centralPoint.x();
+ y = p.y() - centralPoint.y();
+
+ if ((d_ptr->m_handleSize * d_ptr->m_handleSize / 4) > (x * x + y * y)) {
+ d_ptr->m_dragHandle = QtGradientWidgetPrivate::CentralRadialHandle;
+ d_ptr->m_dragOffset = QPointF(x, y);
+ update();
+ return;
+ }
+
+ QPointF central = d_ptr->toViewport(d_ptr->m_centralRadial);
+ QRectF r = d_ptr->pointRect(central, 2 * d_ptr->m_handleSize / 3);
+ QRectF r1(0, r.y(), size().width(), r.height());
+ QRectF r2(r.x(), 0, r.width(), r.y());
+ QRectF r3(r.x(), r.y() + r.height(), r.width(), size().height() - r.y() - r.height());
+ QPointF pF(p.x(), p.y());
+ if (r1.contains(pF) || r2.contains(pF) || r3.contains(pF)) {
+ x = pF.x() / size().width() - d_ptr->m_centralRadial.x();
+ y = pF.y() / size().height() - d_ptr->m_centralRadial.y();
+ double clickRadius = sqrt(x * x + y * y);
+ //d_ptr->m_radiusOffset = d_ptr->m_radiusRadial - clickRadius;
+ d_ptr->m_radiusFactor = d_ptr->m_radiusRadial / clickRadius;
+ if (d_ptr->m_radiusFactor == 0)
+ d_ptr->m_radiusFactor = 1;
+ d_ptr->m_dragRadius = d_ptr->m_radiusRadial;
+ d_ptr->m_dragHandle = QtGradientWidgetPrivate::RadiusRadialHandle;
+ mouseMoveEvent(e);
+ update();
+ return;
+ }
+ } else if (d_ptr->m_gradientType == QGradient::ConicalGradient) {
+ QPointF centralPoint = d_ptr->toViewport(d_ptr->m_centralConical);
+ double x = p.x() - centralPoint.x();
+ double y = p.y() - centralPoint.y();
+
+ if ((d_ptr->m_handleSize * d_ptr->m_handleSize / 4) > (x * x + y * y)) {
+ d_ptr->m_dragHandle = QtGradientWidgetPrivate::CentralConicalHandle;
+ d_ptr->m_dragOffset = QPointF(x, y);
+ update();
+ return;
+ }
+ double radius = size().width();
+ if (size().height() < radius)
+ radius = size().height();
+ radius /= 2;
+ double corr = d_ptr->m_handleSize / 3;
+ radius -= corr;
+ QPointF vp = d_ptr->toViewport(d_ptr->m_centralConical);
+ x = p.x() - vp.x();
+ y = p.y() - vp.y();
+ if (((radius - corr) * (radius - corr) < (x * x + y * y)) &&
+ ((radius + corr) * (radius + corr) > (x * x + y * y))) {
+ QPointF central = d_ptr->toViewport(d_ptr->m_centralConical);
+ QPointF current(e->pos().x(), e->pos().y());
+ x = current.x() - central.x();
+ y = current.y() - central.y();
+ x /= size().width() / 2;
+ y /= size().height() / 2;
+ double r = sqrt(x * x + y * y);
+
+ double arcSin = asin(y / r);
+ double arcCos = acos(x / r);
+
+ double angle = arcCos * 180 / M_PI;
+ if (arcSin > 0) {
+ angle = -angle;
+ }
+
+ d_ptr->m_angleOffset = d_ptr->m_angleConical - angle;
+ d_ptr->m_dragAngle = d_ptr->m_angleConical;
+ d_ptr->m_dragHandle = QtGradientWidgetPrivate::AngleConicalHandle;
+ update();
+ return;
+ }
+ }
+}
+
+void QtGradientWidget::mouseReleaseEvent(QMouseEvent *e)
+{
+ Q_UNUSED(e)
+ d_ptr->m_dragHandle = QtGradientWidgetPrivate::NoHandle;
+ update();
+}
+
+void QtGradientWidget::mouseMoveEvent(QMouseEvent *e)
+{
+ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::NoHandle)
+ return;
+
+ QPointF newPos = QPointF((double)e->pos().x() - d_ptr->m_dragOffset.x(),
+ (double)e->pos().y() - d_ptr->m_dragOffset.y());
+ QPointF newPoint = d_ptr->fromViewport(newPos);
+ if (newPoint.x() < 0)
+ newPoint.setX(0);
+ else if (newPoint.x() > 1)
+ newPoint.setX(1);
+ if (newPoint.y() < 0)
+ newPoint.setY(0);
+ else if (newPoint.y() > 1)
+ newPoint.setY(1);
+
+ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::StartLinearHandle) {
+ d_ptr->m_startLinear = newPoint;
+ emit startLinearChanged(newPoint);
+ } else if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::EndLinearHandle) {
+ d_ptr->m_endLinear = newPoint;
+ emit endLinearChanged(newPoint);
+ } else if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::CentralRadialHandle) {
+ d_ptr->m_centralRadial = newPoint;
+ emit centralRadialChanged(newPoint);
+ } else if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::FocalRadialHandle) {
+ d_ptr->m_focalRadial = newPoint;
+ emit focalRadialChanged(newPoint);
+ } else if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::RadiusRadialHandle) {
+ QPointF centralPoint = d_ptr->toViewport(d_ptr->m_centralRadial);
+ QPointF pF(e->pos().x(), e->pos().y());
+ double x = pF.x() - centralPoint.x();
+ double y = pF.y() - centralPoint.y();
+
+ if ((d_ptr->m_handleSize * d_ptr->m_handleSize / 4) > (x * x + y * y)) {
+ if (d_ptr->m_radiusRadial != d_ptr->m_dragRadius) {
+ d_ptr->m_radiusRadial = d_ptr->m_dragRadius;
+ emit radiusRadialChanged(d_ptr->m_radiusRadial);
+ }
+ } else {
+ x = pF.x() / size().width() - d_ptr->m_centralRadial.x();
+ y = pF.y() / size().height() - d_ptr->m_centralRadial.y();
+ double moveRadius = sqrt(x * x + y * y);
+ //double newRadius = moveRadius + d_ptr->m_radiusOffset;
+ double newRadius = moveRadius * d_ptr->m_radiusFactor;
+ if (newRadius > 2)
+ newRadius = 2;
+ d_ptr->m_radiusRadial = newRadius;
+ emit radiusRadialChanged(d_ptr->m_radiusRadial);
+ }
+ } else if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::CentralConicalHandle) {
+ d_ptr->m_centralConical = newPoint;
+ emit centralConicalChanged(newPoint);
+ } else if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::AngleConicalHandle) {
+ QPointF centralPoint = d_ptr->toViewport(d_ptr->m_centralConical);
+ QPointF pF(e->pos().x(), e->pos().y());
+ double x = pF.x() - centralPoint.x();
+ double y = pF.y() - centralPoint.y();
+
+ if ((d_ptr->m_handleSize * d_ptr->m_handleSize / 4) > (x * x + y * y)) {
+ if (d_ptr->m_angleConical != d_ptr->m_dragAngle) {
+ d_ptr->m_angleConical = d_ptr->m_dragAngle;
+ emit angleConicalChanged(d_ptr->m_angleConical);
+ }
+ } else {
+ QPointF central = d_ptr->toViewport(d_ptr->m_centralConical);
+ QPointF current = pF;
+ x = current.x() - central.x();
+ y = current.y() - central.y();
+ x /= size().width() / 2;
+ y /= size().height() / 2;
+ double r = sqrt(x * x + y * y);
+
+ double arcSin = asin(y / r);
+ double arcCos = acos(x / r);
+
+ double angle = arcCos * 180 / M_PI;
+ if (arcSin > 0) {
+ angle = -angle;
+ }
+
+ angle += d_ptr->m_angleOffset;
+
+ d_ptr->setAngleConical(angle);
+ }
+ }
+ update();
+}
+
+void QtGradientWidget::mouseDoubleClickEvent(QMouseEvent *e)
+{
+ mousePressEvent(e);
+}
+
+void QtGradientWidget::paintEvent(QPaintEvent *e)
+{
+ Q_UNUSED(e)
+
+ QPainter p(this);
+
+ if (d_ptr->m_backgroundCheckered) {
+ int pixSize = 40;
+ QPixmap pm(2 * pixSize, 2 * pixSize);
+
+ QPainter pmp(&pm);
+ pmp.fillRect(0, 0, pixSize, pixSize, Qt::white);
+ pmp.fillRect(pixSize, pixSize, pixSize, pixSize, Qt::white);
+ pmp.fillRect(0, pixSize, pixSize, pixSize, Qt::black);
+ pmp.fillRect(pixSize, 0, pixSize, pixSize, Qt::black);
+
+ p.setBrushOrigin((size().width() % pixSize + pixSize) / 2, (size().height() % pixSize + pixSize) / 2);
+ p.fillRect(rect(), pm);
+ p.setBrushOrigin(0, 0);
+ }
+
+ QGradient *gradient = 0;
+ switch (d_ptr->m_gradientType) {
+ case QGradient::LinearGradient:
+ gradient = new QLinearGradient(d_ptr->m_startLinear, d_ptr->m_endLinear);
+ break;
+ case QGradient::RadialGradient:
+ gradient = new QRadialGradient(d_ptr->m_centralRadial, d_ptr->m_radiusRadial, d_ptr->m_focalRadial);
+ break;
+ case QGradient::ConicalGradient:
+ gradient = new QConicalGradient(d_ptr->m_centralConical, d_ptr->m_angleConical);
+ break;
+ default:
+ break;
+ }
+ if (!gradient)
+ return;
+
+ gradient->setStops(d_ptr->m_gradientStops);
+ gradient->setSpread(d_ptr->m_gradientSpread);
+
+ p.save();
+ p.scale(size().width(), size().height());
+ p.fillRect(QRect(0, 0, 1, 1), *gradient);
+ p.restore();
+
+ p.setRenderHint(QPainter::Antialiasing);
+
+ QColor c = QColor::fromRgbF(0.5, 0.5, 0.5, 0.5);
+ QBrush br(c);
+ p.setBrush(br);
+ QPen pen(Qt::white);
+ pen.setWidthF(1);
+ p.setPen(pen);
+ QPen dragPen = pen;
+ dragPen.setWidthF(2);
+ if (d_ptr->m_gradientType == QGradient::LinearGradient) {
+ p.save();
+ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::StartLinearHandle)
+ p.setPen(dragPen);
+ d_ptr->paintPoint(&p, d_ptr->m_startLinear, d_ptr->m_handleSize);
+ p.restore();
+
+ p.save();
+ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::EndLinearHandle)
+ p.setPen(dragPen);
+ d_ptr->paintPoint(&p, d_ptr->m_endLinear, d_ptr->m_handleSize);
+ p.restore();
+ } else if (d_ptr->m_gradientType == QGradient::RadialGradient) {
+ QPointF central = d_ptr->toViewport(d_ptr->m_centralRadial);
+
+ p.save();
+ QRectF r = d_ptr->pointRect(central, 2 * d_ptr->m_handleSize / 3);
+ QRectF r1(0, r.y(), size().width(), r.height());
+ QRectF r2(r.x(), 0, r.width(), r.y());
+ QRectF r3(r.x(), r.y() + r.height(), r.width(), size().height() - r.y() - r.height());
+ p.fillRect(r1, c);
+ p.fillRect(r2, c);
+ p.fillRect(r3, c);
+ p.setBrush(Qt::NoBrush);
+ p.save();
+ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::CentralRadialHandle)
+ p.setPen(dragPen);
+ d_ptr->paintPoint(&p, d_ptr->m_centralRadial, d_ptr->m_handleSize);
+ p.restore();
+
+ QRectF rect = QRectF(central.x() - d_ptr->m_radiusRadial * size().width(),
+ central.y() - d_ptr->m_radiusRadial * size().height(),
+ 2 * d_ptr->m_radiusRadial * size().width(),
+ 2 * d_ptr->m_radiusRadial * size().height());
+ p.setClipRect(r1);
+ p.setClipRect(r2, Qt::UniteClip);
+ p.setClipRect(r3, Qt::UniteClip);
+ p.drawEllipse(rect);
+ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::RadiusRadialHandle) {
+ p.save();
+ p.setPen(dragPen);
+ QRectF rect = QRectF(central.x() - d_ptr->m_radiusRadial / d_ptr->m_radiusFactor * size().width(),
+ central.y() - d_ptr->m_radiusRadial / d_ptr->m_radiusFactor * size().height(),
+ 2 * d_ptr->m_radiusRadial / d_ptr->m_radiusFactor * size().width(),
+ 2 * d_ptr->m_radiusRadial / d_ptr->m_radiusFactor * size().height());
+ p.drawEllipse(rect);
+
+ p.restore();
+ }
+ p.restore();
+
+ p.save();
+ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::FocalRadialHandle)
+ p.setPen(dragPen);
+ d_ptr->paintPoint(&p, d_ptr->m_focalRadial, 2 * d_ptr->m_handleSize / 3);
+ p.restore();
+ } else if (d_ptr->m_gradientType == QGradient::ConicalGradient) {
+ double radius = size().width();
+ if (size().height() < radius)
+ radius = size().height();
+ radius /= 2;
+ double corr = d_ptr->m_handleSize / 3;
+ radius -= corr;
+ QPointF central = d_ptr->toViewport(d_ptr->m_centralConical);
+
+ p.save();
+ p.setBrush(Qt::NoBrush);
+ QPen pen2(c);
+ pen2.setWidthF(2 * d_ptr->m_handleSize / 3);
+ p.setPen(pen2);
+ p.drawEllipse(d_ptr->pointRect(central, 2 * radius));
+ p.restore();
+
+ p.save();
+ p.setBrush(Qt::NoBrush);
+ int pointCount = 2;
+ for (int i = 0; i < pointCount; i++) {
+ QPointF ang(cos(M_PI * (i * 180.0 / pointCount + d_ptr->m_angleConical) / 180) * size().width() / 2,
+ -sin(M_PI * (i * 180.0 / pointCount + d_ptr->m_angleConical) / 180) * size().height() / 2);
+ double mod = sqrt(ang.x() * ang.x() + ang.y() * ang.y());
+ p.drawLine(QPointF(central.x() + ang.x() * (radius - corr) / mod,
+ central.y() + ang.y() * (radius - corr) / mod),
+ QPointF(central.x() + ang.x() * (radius + corr) / mod,
+ central.y() + ang.y() * (radius + corr) / mod));
+ p.drawLine(QPointF(central.x() - ang.x() * (radius - corr) / mod,
+ central.y() - ang.y() * (radius - corr) / mod),
+ QPointF(central.x() - ang.x() * (radius + corr) / mod,
+ central.y() - ang.y() * (radius + corr) / mod));
+ }
+ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::AngleConicalHandle) {
+ p.save();
+ p.setPen(dragPen);
+ QPointF ang(cos(M_PI * (d_ptr->m_angleConical - d_ptr->m_angleOffset) / 180) * size().width() / 2,
+ -sin(M_PI * (d_ptr->m_angleConical - d_ptr->m_angleOffset) / 180) * size().height() / 2);
+ double mod = sqrt(ang.x() * ang.x() + ang.y() * ang.y());
+ p.drawLine(QPointF(central.x() + ang.x() * (radius - corr) / mod,
+ central.y() + ang.y() * (radius - corr) / mod),
+ QPointF(central.x() + ang.x() * (radius + corr) / mod,
+ central.y() + ang.y() * (radius + corr) / mod));
+ p.restore();
+ }
+
+ p.restore();
+
+ p.save();
+ if (d_ptr->m_dragHandle == QtGradientWidgetPrivate::CentralConicalHandle)
+ p.setPen(dragPen);
+ d_ptr->paintPoint(&p, d_ptr->m_centralConical, d_ptr->m_handleSize);
+ p.restore();
+
+ }
+
+ delete gradient;
+}
+
+void QtGradientWidget::setGradientStops(const QGradientStops &stops)
+{
+ d_ptr->m_gradientStops = stops;
+ update();
+}
+
+QGradientStops QtGradientWidget::gradientStops() const
+{
+ return d_ptr->m_gradientStops;
+}
+
+void QtGradientWidget::setGradientType(QGradient::Type type)
+{
+ if (type == QGradient::NoGradient)
+ return;
+ if (d_ptr->m_gradientType == type)
+ return;
+
+ d_ptr->m_gradientType = type;
+ update();
+}
+
+QGradient::Type QtGradientWidget::gradientType() const
+{
+ return d_ptr->m_gradientType;
+}
+
+void QtGradientWidget::setGradientSpread(QGradient::Spread spread)
+{
+ if (d_ptr->m_gradientSpread == spread)
+ return;
+
+ d_ptr->m_gradientSpread = spread;
+ update();
+}
+
+QGradient::Spread QtGradientWidget::gradientSpread() const
+{
+ return d_ptr->m_gradientSpread;
+}
+
+void QtGradientWidget::setStartLinear(const QPointF &point)
+{
+ if (d_ptr->m_startLinear == point)
+ return;
+
+ d_ptr->m_startLinear = d_ptr->checkRange(point);
+ update();
+}
+
+QPointF QtGradientWidget::startLinear() const
+{
+ return d_ptr->m_startLinear;
+}
+
+void QtGradientWidget::setEndLinear(const QPointF &point)
+{
+ if (d_ptr->m_endLinear == point)
+ return;
+
+ d_ptr->m_endLinear = d_ptr->checkRange(point);
+ update();
+}
+
+QPointF QtGradientWidget::endLinear() const
+{
+ return d_ptr->m_endLinear;
+}
+
+void QtGradientWidget::setCentralRadial(const QPointF &point)
+{
+ if (d_ptr->m_centralRadial == point)
+ return;
+
+ d_ptr->m_centralRadial = point;
+ update();
+}
+
+QPointF QtGradientWidget::centralRadial() const
+{
+ return d_ptr->m_centralRadial;
+}
+
+void QtGradientWidget::setFocalRadial(const QPointF &point)
+{
+ if (d_ptr->m_focalRadial == point)
+ return;
+
+ d_ptr->m_focalRadial = point;
+ update();
+}
+
+QPointF QtGradientWidget::focalRadial() const
+{
+ return d_ptr->m_focalRadial;
+}
+
+void QtGradientWidget::setRadiusRadial(qreal radius)
+{
+ if (d_ptr->m_radiusRadial == radius)
+ return;
+
+ d_ptr->m_radiusRadial = radius;
+ update();
+}
+
+qreal QtGradientWidget::radiusRadial() const
+{
+ return d_ptr->m_radiusRadial;
+}
+
+void QtGradientWidget::setCentralConical(const QPointF &point)
+{
+ if (d_ptr->m_centralConical == point)
+ return;
+
+ d_ptr->m_centralConical = point;
+ update();
+}
+
+QPointF QtGradientWidget::centralConical() const
+{
+ return d_ptr->m_centralConical;
+}
+
+void QtGradientWidget::setAngleConical(qreal angle)
+{
+ if (d_ptr->m_angleConical == angle)
+ return;
+
+ d_ptr->m_angleConical = angle;
+ update();
+}
+
+qreal QtGradientWidget::angleConical() const
+{
+ return d_ptr->m_angleConical;
+}
+
+QT_END_NAMESPACE
diff --git a/src/shared/qtgradienteditor/qtgradientwidget.h b/src/shared/qtgradienteditor/qtgradientwidget.h
new file mode 100644
index 000000000..ee866feb9
--- /dev/null
+++ b/src/shared/qtgradienteditor/qtgradientwidget.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTGRADIENTWIDGET_H
+#define QTGRADIENTWIDGET_H
+
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QtGradientWidget : public QWidget
+{
+ Q_OBJECT
+ Q_PROPERTY(bool backgroundCheckered READ isBackgroundCheckered WRITE setBackgroundCheckered)
+public:
+ QtGradientWidget(QWidget *parent = 0);
+ ~QtGradientWidget();
+
+ QSize minimumSizeHint() const;
+ QSize sizeHint() const;
+ int heightForWidth(int w) const;
+
+ bool isBackgroundCheckered() const;
+ void setBackgroundCheckered(bool checkered);
+
+ QGradientStops gradientStops() const;
+
+ void setGradientType(QGradient::Type type);
+ QGradient::Type gradientType() const;
+
+ void setGradientSpread(QGradient::Spread spread);
+ QGradient::Spread gradientSpread() const;
+
+ void setStartLinear(const QPointF &point);
+ QPointF startLinear() const;
+
+ void setEndLinear(const QPointF &point);
+ QPointF endLinear() const;
+
+ void setCentralRadial(const QPointF &point);
+ QPointF centralRadial() const;
+
+ void setFocalRadial(const QPointF &point);
+ QPointF focalRadial() const;
+
+ void setRadiusRadial(qreal radius);
+ qreal radiusRadial() const;
+
+ void setCentralConical(const QPointF &point);
+ QPointF centralConical() const;
+
+ void setAngleConical(qreal angle);
+ qreal angleConical() const;
+
+public slots:
+ void setGradientStops(const QGradientStops &stops);
+signals:
+
+ void startLinearChanged(const QPointF &point);
+ void endLinearChanged(const QPointF &point);
+ void centralRadialChanged(const QPointF &point);
+ void focalRadialChanged(const QPointF &point);
+ void radiusRadialChanged(qreal radius);
+ void centralConicalChanged(const QPointF &point);
+ void angleConicalChanged(qreal angle);
+
+protected:
+ void paintEvent(QPaintEvent *e);
+ void mousePressEvent(QMouseEvent *e);
+ void mouseReleaseEvent(QMouseEvent *e);
+ void mouseMoveEvent(QMouseEvent *e);
+ void mouseDoubleClickEvent(QMouseEvent *e);
+
+private:
+ QScopedPointer<class QtGradientWidgetPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtGradientWidget)
+ Q_DISABLE_COPY(QtGradientWidget)
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtpropertybrowser/images/cursor-arrow.png b/src/shared/qtpropertybrowser/images/cursor-arrow.png
new file mode 100644
index 000000000..a69ef4eb6
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-arrow.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/images/cursor-busy.png b/src/shared/qtpropertybrowser/images/cursor-busy.png
new file mode 100644
index 000000000..53717e499
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-busy.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/images/cursor-closedhand.png b/src/shared/qtpropertybrowser/images/cursor-closedhand.png
new file mode 100644
index 000000000..b78dd1dac
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-closedhand.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/images/cursor-cross.png b/src/shared/qtpropertybrowser/images/cursor-cross.png
new file mode 100644
index 000000000..fe38e7448
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-cross.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/images/cursor-forbidden.png b/src/shared/qtpropertybrowser/images/cursor-forbidden.png
new file mode 100644
index 000000000..2b08c4e2a
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-forbidden.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/images/cursor-hand.png b/src/shared/qtpropertybrowser/images/cursor-hand.png
new file mode 100644
index 000000000..d2004aefa
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-hand.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/images/cursor-hsplit.png b/src/shared/qtpropertybrowser/images/cursor-hsplit.png
new file mode 100644
index 000000000..a5667e3ff
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-hsplit.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/images/cursor-ibeam.png b/src/shared/qtpropertybrowser/images/cursor-ibeam.png
new file mode 100644
index 000000000..097fc5fa7
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-ibeam.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/images/cursor-openhand.png b/src/shared/qtpropertybrowser/images/cursor-openhand.png
new file mode 100644
index 000000000..9181c859e
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-openhand.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/images/cursor-sizeall.png b/src/shared/qtpropertybrowser/images/cursor-sizeall.png
new file mode 100644
index 000000000..69f13eb34
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-sizeall.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/images/cursor-sizeb.png b/src/shared/qtpropertybrowser/images/cursor-sizeb.png
new file mode 100644
index 000000000..f37d7b91e
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-sizeb.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/images/cursor-sizef.png b/src/shared/qtpropertybrowser/images/cursor-sizef.png
new file mode 100644
index 000000000..3b127a05d
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-sizef.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/images/cursor-sizeh.png b/src/shared/qtpropertybrowser/images/cursor-sizeh.png
new file mode 100644
index 000000000..a9f40cbc3
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-sizeh.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/images/cursor-sizev.png b/src/shared/qtpropertybrowser/images/cursor-sizev.png
new file mode 100644
index 000000000..1edbab27a
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-sizev.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/images/cursor-uparrow.png b/src/shared/qtpropertybrowser/images/cursor-uparrow.png
new file mode 100644
index 000000000..d3e70ef4c
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-uparrow.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/images/cursor-vsplit.png b/src/shared/qtpropertybrowser/images/cursor-vsplit.png
new file mode 100644
index 000000000..1beda2570
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-vsplit.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/images/cursor-wait.png b/src/shared/qtpropertybrowser/images/cursor-wait.png
new file mode 100644
index 000000000..69056c479
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-wait.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/images/cursor-whatsthis.png b/src/shared/qtpropertybrowser/images/cursor-whatsthis.png
new file mode 100644
index 000000000..b47601c37
--- /dev/null
+++ b/src/shared/qtpropertybrowser/images/cursor-whatsthis.png
Binary files differ
diff --git a/src/shared/qtpropertybrowser/qtbuttonpropertybrowser.cpp b/src/shared/qtpropertybrowser/qtbuttonpropertybrowser.cpp
new file mode 100644
index 000000000..09571243f
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qtbuttonpropertybrowser.cpp
@@ -0,0 +1,627 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtbuttonpropertybrowser.h"
+#include <QtCore/QSet>
+#include <QtGui/QGridLayout>
+#include <QtGui/QLabel>
+#include <QtCore/QTimer>
+#include <QtCore/QMap>
+#include <QtGui/QToolButton>
+#include <QtGui/QStyle>
+
+QT_BEGIN_NAMESPACE
+
+class QtButtonPropertyBrowserPrivate
+{
+ QtButtonPropertyBrowser *q_ptr;
+ Q_DECLARE_PUBLIC(QtButtonPropertyBrowser)
+public:
+
+ void init(QWidget *parent);
+
+ void propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex);
+ void propertyRemoved(QtBrowserItem *index);
+ void propertyChanged(QtBrowserItem *index);
+ QWidget *createEditor(QtProperty *property, QWidget *parent) const
+ { return q_ptr->createEditor(property, parent); }
+
+ void slotEditorDestroyed();
+ void slotUpdate();
+ void slotToggled(bool checked);
+
+ struct WidgetItem
+ {
+ WidgetItem() : widget(0), label(0), widgetLabel(0),
+ button(0), container(0), layout(0), /*line(0), */parent(0), expanded(false) { }
+ QWidget *widget; // can be null
+ QLabel *label; // main label with property name
+ QLabel *widgetLabel; // label substitute showing the current value if there is no widget
+ QToolButton *button; // expandable button for items with children
+ QWidget *container; // container which is expanded when the button is clicked
+ QGridLayout *layout; // layout in container
+ WidgetItem *parent;
+ QList<WidgetItem *> children;
+ bool expanded;
+ };
+private:
+ void updateLater();
+ void updateItem(WidgetItem *item);
+ void insertRow(QGridLayout *layout, int row) const;
+ void removeRow(QGridLayout *layout, int row) const;
+ int gridRow(WidgetItem *item) const;
+ int gridSpan(WidgetItem *item) const;
+ void setExpanded(WidgetItem *item, bool expanded);
+ QToolButton *createButton(QWidget *panret = 0) const;
+
+ QMap<QtBrowserItem *, WidgetItem *> m_indexToItem;
+ QMap<WidgetItem *, QtBrowserItem *> m_itemToIndex;
+ QMap<QWidget *, WidgetItem *> m_widgetToItem;
+ QMap<QObject *, WidgetItem *> m_buttonToItem;
+ QGridLayout *m_mainLayout;
+ QList<WidgetItem *> m_children;
+ QList<WidgetItem *> m_recreateQueue;
+};
+
+QToolButton *QtButtonPropertyBrowserPrivate::createButton(QWidget *parent) const
+{
+ QToolButton *button = new QToolButton(parent);
+ button->setCheckable(true);
+ button->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed));
+ button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ button->setArrowType(Qt::DownArrow);
+ button->setIconSize(QSize(3, 16));
+ /*
+ QIcon icon;
+ icon.addPixmap(q_ptr->style()->standardPixmap(QStyle::SP_ArrowDown), QIcon::Normal, QIcon::Off);
+ icon.addPixmap(q_ptr->style()->standardPixmap(QStyle::SP_ArrowUp), QIcon::Normal, QIcon::On);
+ button->setIcon(icon);
+ */
+ return button;
+}
+
+int QtButtonPropertyBrowserPrivate::gridRow(WidgetItem *item) const
+{
+ QList<WidgetItem *> siblings;
+ if (item->parent)
+ siblings = item->parent->children;
+ else
+ siblings = m_children;
+
+ int row = 0;
+ QListIterator<WidgetItem *> it(siblings);
+ while (it.hasNext()) {
+ WidgetItem *sibling = it.next();
+ if (sibling == item)
+ return row;
+ row += gridSpan(sibling);
+ }
+ return -1;
+}
+
+int QtButtonPropertyBrowserPrivate::gridSpan(WidgetItem *item) const
+{
+ if (item->container && item->expanded)
+ return 2;
+ return 1;
+}
+
+void QtButtonPropertyBrowserPrivate::init(QWidget *parent)
+{
+ m_mainLayout = new QGridLayout();
+ parent->setLayout(m_mainLayout);
+ QLayoutItem *item = new QSpacerItem(0, 0,
+ QSizePolicy::Fixed, QSizePolicy::Expanding);
+ m_mainLayout->addItem(item, 0, 0);
+}
+
+void QtButtonPropertyBrowserPrivate::slotEditorDestroyed()
+{
+ QWidget *editor = qobject_cast<QWidget *>(q_ptr->sender());
+ if (!editor)
+ return;
+ if (!m_widgetToItem.contains(editor))
+ return;
+ m_widgetToItem[editor]->widget = 0;
+ m_widgetToItem.remove(editor);
+}
+
+void QtButtonPropertyBrowserPrivate::slotUpdate()
+{
+ QListIterator<WidgetItem *> itItem(m_recreateQueue);
+ while (itItem.hasNext()) {
+ WidgetItem *item = itItem.next();
+
+ WidgetItem *parent = item->parent;
+ QWidget *w = 0;
+ QGridLayout *l = 0;
+ const int oldRow = gridRow(item);
+ if (parent) {
+ w = parent->container;
+ l = parent->layout;
+ } else {
+ w = q_ptr;
+ l = m_mainLayout;
+ }
+
+ int span = 1;
+ if (!item->widget && !item->widgetLabel)
+ span = 2;
+ item->label = new QLabel(w);
+ item->label->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
+ l->addWidget(item->label, oldRow, 0, 1, span);
+
+ updateItem(item);
+ }
+ m_recreateQueue.clear();
+}
+
+void QtButtonPropertyBrowserPrivate::setExpanded(WidgetItem *item, bool expanded)
+{
+ if (item->expanded == expanded)
+ return;
+
+ if (!item->container)
+ return;
+
+ item->expanded = expanded;
+ const int row = gridRow(item);
+ WidgetItem *parent = item->parent;
+ QGridLayout *l = 0;
+ if (parent)
+ l = parent->layout;
+ else
+ l = m_mainLayout;
+
+ if (expanded) {
+ insertRow(l, row + 1);
+ l->addWidget(item->container, row + 1, 0, 1, 2);
+ item->container->show();
+ } else {
+ l->removeWidget(item->container);
+ item->container->hide();
+ removeRow(l, row + 1);
+ }
+
+ item->button->setChecked(expanded);
+ item->button->setArrowType(expanded ? Qt::UpArrow : Qt::DownArrow);
+}
+
+void QtButtonPropertyBrowserPrivate::slotToggled(bool checked)
+{
+ WidgetItem *item = m_buttonToItem.value(q_ptr->sender());
+ if (!item)
+ return;
+
+ setExpanded(item, checked);
+
+ if (checked)
+ emit q_ptr->expanded(m_itemToIndex.value(item));
+ else
+ emit q_ptr->collapsed(m_itemToIndex.value(item));
+}
+
+void QtButtonPropertyBrowserPrivate::updateLater()
+{
+ QTimer::singleShot(0, q_ptr, SLOT(slotUpdate()));
+}
+
+void QtButtonPropertyBrowserPrivate::propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex)
+{
+ WidgetItem *afterItem = m_indexToItem.value(afterIndex);
+ WidgetItem *parentItem = m_indexToItem.value(index->parent());
+
+ WidgetItem *newItem = new WidgetItem();
+ newItem->parent = parentItem;
+
+ QGridLayout *layout = 0;
+ QWidget *parentWidget = 0;
+ int row = -1;
+ if (!afterItem) {
+ row = 0;
+ if (parentItem)
+ parentItem->children.insert(0, newItem);
+ else
+ m_children.insert(0, newItem);
+ } else {
+ row = gridRow(afterItem) + gridSpan(afterItem);
+ if (parentItem)
+ parentItem->children.insert(parentItem->children.indexOf(afterItem) + 1, newItem);
+ else
+ m_children.insert(m_children.indexOf(afterItem) + 1, newItem);
+ }
+
+ if (!parentItem) {
+ layout = m_mainLayout;
+ parentWidget = q_ptr;
+ } else {
+ if (!parentItem->container) {
+ m_recreateQueue.removeAll(parentItem);
+ WidgetItem *grandParent = parentItem->parent;
+ QWidget *w = 0;
+ QGridLayout *l = 0;
+ const int oldRow = gridRow(parentItem);
+ if (grandParent) {
+ w = grandParent->container;
+ l = grandParent->layout;
+ } else {
+ w = q_ptr;
+ l = m_mainLayout;
+ }
+ QFrame *container = new QFrame();
+ container->setFrameShape(QFrame::Panel);
+ container->setFrameShadow(QFrame::Raised);
+ parentItem->container = container;
+ parentItem->button = createButton();
+ m_buttonToItem[parentItem->button] = parentItem;
+ q_ptr->connect(parentItem->button, SIGNAL(toggled(bool)), q_ptr, SLOT(slotToggled(bool)));
+ parentItem->layout = new QGridLayout();
+ container->setLayout(parentItem->layout);
+ if (parentItem->label) {
+ l->removeWidget(parentItem->label);
+ delete parentItem->label;
+ parentItem->label = 0;
+ }
+ int span = 1;
+ if (!parentItem->widget && !parentItem->widgetLabel)
+ span = 2;
+ l->addWidget(parentItem->button, oldRow, 0, 1, span);
+ updateItem(parentItem);
+ }
+ layout = parentItem->layout;
+ parentWidget = parentItem->container;
+ }
+
+ newItem->label = new QLabel(parentWidget);
+ newItem->label->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
+ newItem->widget = createEditor(index->property(), parentWidget);
+ if (newItem->widget) {
+ QObject::connect(newItem->widget, SIGNAL(destroyed()), q_ptr, SLOT(slotEditorDestroyed()));
+ m_widgetToItem[newItem->widget] = newItem;
+ } else if (index->property()->hasValue()) {
+ newItem->widgetLabel = new QLabel(parentWidget);
+ newItem->widgetLabel->setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed));
+ }
+
+ insertRow(layout, row);
+ int span = 1;
+ if (newItem->widget)
+ layout->addWidget(newItem->widget, row, 1);
+ else if (newItem->widgetLabel)
+ layout->addWidget(newItem->widgetLabel, row, 1);
+ else
+ span = 2;
+ layout->addWidget(newItem->label, row, 0, span, 1);
+
+ m_itemToIndex[newItem] = index;
+ m_indexToItem[index] = newItem;
+
+ updateItem(newItem);
+}
+
+void QtButtonPropertyBrowserPrivate::propertyRemoved(QtBrowserItem *index)
+{
+ WidgetItem *item = m_indexToItem.value(index);
+
+ m_indexToItem.remove(index);
+ m_itemToIndex.remove(item);
+
+ WidgetItem *parentItem = item->parent;
+
+ const int row = gridRow(item);
+
+ if (parentItem)
+ parentItem->children.removeAt(parentItem->children.indexOf(item));
+ else
+ m_children.removeAt(m_children.indexOf(item));
+
+ const int colSpan = gridSpan(item);
+
+ m_buttonToItem.remove(item->button);
+
+ if (item->widget)
+ delete item->widget;
+ if (item->label)
+ delete item->label;
+ if (item->widgetLabel)
+ delete item->widgetLabel;
+ if (item->button)
+ delete item->button;
+ if (item->container)
+ delete item->container;
+
+ if (!parentItem) {
+ removeRow(m_mainLayout, row);
+ if (colSpan > 1)
+ removeRow(m_mainLayout, row);
+ } else if (parentItem->children.count() != 0) {
+ removeRow(parentItem->layout, row);
+ if (colSpan > 1)
+ removeRow(parentItem->layout, row);
+ } else {
+ const WidgetItem *grandParent = parentItem->parent;
+ QGridLayout *l = 0;
+ if (grandParent) {
+ l = grandParent->layout;
+ } else {
+ l = m_mainLayout;
+ }
+
+ const int parentRow = gridRow(parentItem);
+ const int parentSpan = gridSpan(parentItem);
+
+ l->removeWidget(parentItem->button);
+ l->removeWidget(parentItem->container);
+ delete parentItem->button;
+ delete parentItem->container;
+ parentItem->button = 0;
+ parentItem->container = 0;
+ parentItem->layout = 0;
+ if (!m_recreateQueue.contains(parentItem))
+ m_recreateQueue.append(parentItem);
+ if (parentSpan > 1)
+ removeRow(l, parentRow + 1);
+
+ updateLater();
+ }
+ m_recreateQueue.removeAll(item);
+
+ delete item;
+}
+
+void QtButtonPropertyBrowserPrivate::insertRow(QGridLayout *layout, int row) const
+{
+ QMap<QLayoutItem *, QRect> itemToPos;
+ int idx = 0;
+ while (idx < layout->count()) {
+ int r, c, rs, cs;
+ layout->getItemPosition(idx, &r, &c, &rs, &cs);
+ if (r >= row) {
+ itemToPos[layout->takeAt(idx)] = QRect(r + 1, c, rs, cs);
+ } else {
+ idx++;
+ }
+ }
+
+ const QMap<QLayoutItem *, QRect>::ConstIterator icend = itemToPos.constEnd();
+ for(QMap<QLayoutItem *, QRect>::ConstIterator it = itemToPos.constBegin(); it != icend; ++it) {
+ const QRect r = it.value();
+ layout->addItem(it.key(), r.x(), r.y(), r.width(), r.height());
+ }
+}
+
+void QtButtonPropertyBrowserPrivate::removeRow(QGridLayout *layout, int row) const
+{
+ QMap<QLayoutItem *, QRect> itemToPos;
+ int idx = 0;
+ while (idx < layout->count()) {
+ int r, c, rs, cs;
+ layout->getItemPosition(idx, &r, &c, &rs, &cs);
+ if (r > row) {
+ itemToPos[layout->takeAt(idx)] = QRect(r - 1, c, rs, cs);
+ } else {
+ idx++;
+ }
+ }
+
+ const QMap<QLayoutItem *, QRect>::ConstIterator icend = itemToPos.constEnd();
+ for(QMap<QLayoutItem *, QRect>::ConstIterator it = itemToPos.constBegin(); it != icend; ++it) {
+ const QRect r = it.value();
+ layout->addItem(it.key(), r.x(), r.y(), r.width(), r.height());
+ }
+}
+
+void QtButtonPropertyBrowserPrivate::propertyChanged(QtBrowserItem *index)
+{
+ WidgetItem *item = m_indexToItem.value(index);
+
+ updateItem(item);
+}
+
+void QtButtonPropertyBrowserPrivate::updateItem(WidgetItem *item)
+{
+ QtProperty *property = m_itemToIndex[item]->property();
+ if (item->button) {
+ QFont font = item->button->font();
+ font.setUnderline(property->isModified());
+ item->button->setFont(font);
+ item->button->setText(property->propertyName());
+ item->button->setToolTip(property->toolTip());
+ item->button->setStatusTip(property->statusTip());
+ item->button->setWhatsThis(property->whatsThis());
+ item->button->setEnabled(property->isEnabled());
+ }
+ if (item->label) {
+ QFont font = item->label->font();
+ font.setUnderline(property->isModified());
+ item->label->setFont(font);
+ item->label->setText(property->propertyName());
+ item->label->setToolTip(property->toolTip());
+ item->label->setStatusTip(property->statusTip());
+ item->label->setWhatsThis(property->whatsThis());
+ item->label->setEnabled(property->isEnabled());
+ }
+ if (item->widgetLabel) {
+ QFont font = item->widgetLabel->font();
+ font.setUnderline(false);
+ item->widgetLabel->setFont(font);
+ item->widgetLabel->setText(property->valueText());
+ item->widgetLabel->setToolTip(property->valueText());
+ item->widgetLabel->setEnabled(property->isEnabled());
+ }
+ if (item->widget) {
+ QFont font = item->widget->font();
+ font.setUnderline(false);
+ item->widget->setFont(font);
+ item->widget->setEnabled(property->isEnabled());
+ item->widget->setToolTip(property->valueText());
+ }
+}
+
+
+
+/*!
+ \class QtButtonPropertyBrowser
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtButtonPropertyBrowser class provides a drop down QToolButton
+ based property browser.
+
+ A property browser is a widget that enables the user to edit a
+ given set of properties. Each property is represented by a label
+ specifying the property's name, and an editing widget (e.g. a line
+ edit or a combobox) holding its value. A property can have zero or
+ more subproperties.
+
+ QtButtonPropertyBrowser provides drop down button for all nested
+ properties, i.e. subproperties are enclosed by a container associated with
+ the drop down button. The parent property's name is displayed as button text. For example:
+
+ \image qtbuttonpropertybrowser.png
+
+ Use the QtAbstractPropertyBrowser API to add, insert and remove
+ properties from an instance of the QtButtonPropertyBrowser
+ class. The properties themselves are created and managed by
+ implementations of the QtAbstractPropertyManager class.
+
+ \sa QtTreePropertyBrowser, QtAbstractPropertyBrowser
+*/
+
+/*!
+ \fn void QtButtonPropertyBrowser::collapsed(QtBrowserItem *item)
+
+ This signal is emitted when the \a item is collapsed.
+
+ \sa expanded(), setExpanded()
+*/
+
+/*!
+ \fn void QtButtonPropertyBrowser::expanded(QtBrowserItem *item)
+
+ This signal is emitted when the \a item is expanded.
+
+ \sa collapsed(), setExpanded()
+*/
+
+/*!
+ Creates a property browser with the given \a parent.
+*/
+QtButtonPropertyBrowser::QtButtonPropertyBrowser(QWidget *parent)
+ : QtAbstractPropertyBrowser(parent), d_ptr(new QtButtonPropertyBrowserPrivate)
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->init(this);
+}
+
+/*!
+ Destroys this property browser.
+
+ Note that the properties that were inserted into this browser are
+ \e not destroyed since they may still be used in other
+ browsers. The properties are owned by the manager that created
+ them.
+
+ \sa QtProperty, QtAbstractPropertyManager
+*/
+QtButtonPropertyBrowser::~QtButtonPropertyBrowser()
+{
+ const QMap<QtButtonPropertyBrowserPrivate::WidgetItem *, QtBrowserItem *>::ConstIterator icend = d_ptr->m_itemToIndex.constEnd();
+ for (QMap<QtButtonPropertyBrowserPrivate::WidgetItem *, QtBrowserItem *>::ConstIterator it = d_ptr->m_itemToIndex.constBegin(); it != icend; ++it)
+ delete it.key();
+}
+
+/*!
+ \reimp
+*/
+void QtButtonPropertyBrowser::itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem)
+{
+ d_ptr->propertyInserted(item, afterItem);
+}
+
+/*!
+ \reimp
+*/
+void QtButtonPropertyBrowser::itemRemoved(QtBrowserItem *item)
+{
+ d_ptr->propertyRemoved(item);
+}
+
+/*!
+ \reimp
+*/
+void QtButtonPropertyBrowser::itemChanged(QtBrowserItem *item)
+{
+ d_ptr->propertyChanged(item);
+}
+
+/*!
+ Sets the \a item to either collapse or expanded, depending on the value of \a expanded.
+
+ \sa isExpanded(), expanded(), collapsed()
+*/
+
+void QtButtonPropertyBrowser::setExpanded(QtBrowserItem *item, bool expanded)
+{
+ QtButtonPropertyBrowserPrivate::WidgetItem *itm = d_ptr->m_indexToItem.value(item);
+ if (itm)
+ d_ptr->setExpanded(itm, expanded);
+}
+
+/*!
+ Returns true if the \a item is expanded; otherwise returns false.
+
+ \sa setExpanded()
+*/
+
+bool QtButtonPropertyBrowser::isExpanded(QtBrowserItem *item) const
+{
+ QtButtonPropertyBrowserPrivate::WidgetItem *itm = d_ptr->m_indexToItem.value(item);
+ if (itm)
+ return itm->expanded;
+ return false;
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qtbuttonpropertybrowser.cpp"
diff --git a/src/shared/qtpropertybrowser/qtbuttonpropertybrowser.h b/src/shared/qtpropertybrowser/qtbuttonpropertybrowser.h
new file mode 100644
index 000000000..53067ccf5
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qtbuttonpropertybrowser.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTBUTTONPROPERTYBROWSER_H
+#define QTBUTTONPROPERTYBROWSER_H
+
+#include "qtpropertybrowser.h"
+
+QT_BEGIN_NAMESPACE
+
+class QtButtonPropertyBrowserPrivate;
+
+class QtButtonPropertyBrowser : public QtAbstractPropertyBrowser
+{
+ Q_OBJECT
+public:
+
+ QtButtonPropertyBrowser(QWidget *parent = 0);
+ ~QtButtonPropertyBrowser();
+
+ void setExpanded(QtBrowserItem *item, bool expanded);
+ bool isExpanded(QtBrowserItem *item) const;
+
+Q_SIGNALS:
+
+ void collapsed(QtBrowserItem *item);
+ void expanded(QtBrowserItem *item);
+
+protected:
+ virtual void itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem);
+ virtual void itemRemoved(QtBrowserItem *item);
+ virtual void itemChanged(QtBrowserItem *item);
+
+private:
+
+ QScopedPointer<QtButtonPropertyBrowserPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtButtonPropertyBrowser)
+ Q_DISABLE_COPY(QtButtonPropertyBrowser)
+ Q_PRIVATE_SLOT(d_func(), void slotUpdate())
+ Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed())
+ Q_PRIVATE_SLOT(d_func(), void slotToggled(bool))
+
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtpropertybrowser/qteditorfactory.cpp b/src/shared/qtpropertybrowser/qteditorfactory.cpp
new file mode 100644
index 000000000..90ba3d3a2
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qteditorfactory.cpp
@@ -0,0 +1,2560 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qteditorfactory.h"
+#include "qtpropertybrowserutils_p.h"
+#include <QtGui/QSpinBox>
+#include <QtGui/QScrollBar>
+#include <QtGui/QComboBox>
+#include <QtGui/QAbstractItemView>
+#include <QtGui/QLineEdit>
+#include <QtGui/QDateTimeEdit>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QMenu>
+#include <QtGui/QKeyEvent>
+#include <QtGui/QApplication>
+#include <QtGui/QLabel>
+#include <QtGui/QToolButton>
+#include <QtGui/QColorDialog>
+#include <QtGui/QFontDialog>
+#include <QtGui/QSpacerItem>
+#include <QtCore/QMap>
+
+#if defined(Q_CC_MSVC)
+# pragma warning(disable: 4786) /* MS VS 6: truncating debug info after 255 characters */
+#endif
+
+QT_BEGIN_NAMESPACE
+
+// Set a hard coded left margin to account for the indentation
+// of the tree view icon when switching to an editor
+
+static inline void setupTreeViewEditorMargin(QLayout *lt)
+{
+ enum { DecorationMargin = 4 };
+ if (QApplication::layoutDirection() == Qt::LeftToRight)
+ lt->setContentsMargins(DecorationMargin, 0, 0, 0);
+ else
+ lt->setContentsMargins(0, 0, DecorationMargin, 0);
+}
+
+// ---------- EditorFactoryPrivate :
+// Base class for editor factory private classes. Manages mapping of properties to editors and vice versa.
+
+template <class Editor>
+class EditorFactoryPrivate
+{
+public:
+
+ typedef QList<Editor *> EditorList;
+ typedef QMap<QtProperty *, EditorList> PropertyToEditorListMap;
+ typedef QMap<Editor *, QtProperty *> EditorToPropertyMap;
+
+ Editor *createEditor(QtProperty *property, QWidget *parent);
+ void initializeEditor(QtProperty *property, Editor *e);
+ void slotEditorDestroyed(QObject *object);
+
+ PropertyToEditorListMap m_createdEditors;
+ EditorToPropertyMap m_editorToProperty;
+};
+
+template <class Editor>
+Editor *EditorFactoryPrivate<Editor>::createEditor(QtProperty *property, QWidget *parent)
+{
+ Editor *editor = new Editor(parent);
+ initializeEditor(property, editor);
+ return editor;
+}
+
+template <class Editor>
+void EditorFactoryPrivate<Editor>::initializeEditor(QtProperty *property, Editor *editor)
+{
+ Q_TYPENAME PropertyToEditorListMap::iterator it = m_createdEditors.find(property);
+ if (it == m_createdEditors.end())
+ it = m_createdEditors.insert(property, EditorList());
+ it.value().append(editor);
+ m_editorToProperty.insert(editor, property);
+}
+
+template <class Editor>
+void EditorFactoryPrivate<Editor>::slotEditorDestroyed(QObject *object)
+{
+ const Q_TYPENAME EditorToPropertyMap::iterator ecend = m_editorToProperty.end();
+ for (Q_TYPENAME EditorToPropertyMap::iterator itEditor = m_editorToProperty.begin(); itEditor != ecend; ++itEditor) {
+ if (itEditor.key() == object) {
+ Editor *editor = itEditor.key();
+ QtProperty *property = itEditor.value();
+ const Q_TYPENAME PropertyToEditorListMap::iterator pit = m_createdEditors.find(property);
+ if (pit != m_createdEditors.end()) {
+ pit.value().removeAll(editor);
+ if (pit.value().empty())
+ m_createdEditors.erase(pit);
+ }
+ m_editorToProperty.erase(itEditor);
+ return;
+ }
+ }
+}
+
+// ------------ QtSpinBoxFactory
+
+class QtSpinBoxFactoryPrivate : public EditorFactoryPrivate<QSpinBox>
+{
+ QtSpinBoxFactory *q_ptr;
+ Q_DECLARE_PUBLIC(QtSpinBoxFactory)
+public:
+
+ void slotPropertyChanged(QtProperty *property, int value);
+ void slotRangeChanged(QtProperty *property, int min, int max);
+ void slotSingleStepChanged(QtProperty *property, int step);
+ void slotSetValue(int value);
+};
+
+void QtSpinBoxFactoryPrivate::slotPropertyChanged(QtProperty *property, int value)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+ QListIterator<QSpinBox *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QSpinBox *editor = itEditor.next();
+ if (editor->value() != value) {
+ editor->blockSignals(true);
+ editor->setValue(value);
+ editor->blockSignals(false);
+ }
+ }
+}
+
+void QtSpinBoxFactoryPrivate::slotRangeChanged(QtProperty *property, int min, int max)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+
+ QtIntPropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+
+ QListIterator<QSpinBox *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QSpinBox *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setRange(min, max);
+ editor->setValue(manager->value(property));
+ editor->blockSignals(false);
+ }
+}
+
+void QtSpinBoxFactoryPrivate::slotSingleStepChanged(QtProperty *property, int step)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+ QListIterator<QSpinBox *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QSpinBox *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setSingleStep(step);
+ editor->blockSignals(false);
+ }
+}
+
+void QtSpinBoxFactoryPrivate::slotSetValue(int value)
+{
+ QObject *object = q_ptr->sender();
+ const QMap<QSpinBox *, QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
+ for (QMap<QSpinBox *, QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor) {
+ if (itEditor.key() == object) {
+ QtProperty *property = itEditor.value();
+ QtIntPropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+ manager->setValue(property, value);
+ return;
+ }
+ }
+}
+
+/*!
+ \class QtSpinBoxFactory
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtSpinBoxFactory class provides QSpinBox widgets for
+ properties created by QtIntPropertyManager objects.
+
+ \sa QtAbstractEditorFactory, QtIntPropertyManager
+*/
+
+/*!
+ Creates a factory with the given \a parent.
+*/
+QtSpinBoxFactory::QtSpinBoxFactory(QObject *parent)
+ : QtAbstractEditorFactory<QtIntPropertyManager>(parent), d_ptr(new QtSpinBoxFactoryPrivate())
+{
+ d_ptr->q_ptr = this;
+
+}
+
+/*!
+ Destroys this factory, and all the widgets it has created.
+*/
+QtSpinBoxFactory::~QtSpinBoxFactory()
+{
+ qDeleteAll(d_ptr->m_editorToProperty.keys());
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtSpinBoxFactory::connectPropertyManager(QtIntPropertyManager *manager)
+{
+ connect(manager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotPropertyChanged(QtProperty*,int)));
+ connect(manager, SIGNAL(rangeChanged(QtProperty*,int,int)),
+ this, SLOT(slotRangeChanged(QtProperty*,int,int)));
+ connect(manager, SIGNAL(singleStepChanged(QtProperty*,int)),
+ this, SLOT(slotSingleStepChanged(QtProperty*,int)));
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+QWidget *QtSpinBoxFactory::createEditor(QtIntPropertyManager *manager, QtProperty *property,
+ QWidget *parent)
+{
+ QSpinBox *editor = d_ptr->createEditor(property, parent);
+ editor->setSingleStep(manager->singleStep(property));
+ editor->setRange(manager->minimum(property), manager->maximum(property));
+ editor->setValue(manager->value(property));
+ editor->setKeyboardTracking(false);
+
+ connect(editor, SIGNAL(valueChanged(int)), this, SLOT(slotSetValue(int)));
+ connect(editor, SIGNAL(destroyed(QObject*)),
+ this, SLOT(slotEditorDestroyed(QObject*)));
+ return editor;
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtSpinBoxFactory::disconnectPropertyManager(QtIntPropertyManager *manager)
+{
+ disconnect(manager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotPropertyChanged(QtProperty*,int)));
+ disconnect(manager, SIGNAL(rangeChanged(QtProperty*,int,int)),
+ this, SLOT(slotRangeChanged(QtProperty*,int,int)));
+ disconnect(manager, SIGNAL(singleStepChanged(QtProperty*,int)),
+ this, SLOT(slotSingleStepChanged(QtProperty*,int)));
+}
+
+// QtSliderFactory
+
+class QtSliderFactoryPrivate : public EditorFactoryPrivate<QSlider>
+{
+ QtSliderFactory *q_ptr;
+ Q_DECLARE_PUBLIC(QtSliderFactory)
+public:
+ void slotPropertyChanged(QtProperty *property, int value);
+ void slotRangeChanged(QtProperty *property, int min, int max);
+ void slotSingleStepChanged(QtProperty *property, int step);
+ void slotSetValue(int value);
+};
+
+void QtSliderFactoryPrivate::slotPropertyChanged(QtProperty *property, int value)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+ QListIterator<QSlider *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QSlider *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setValue(value);
+ editor->blockSignals(false);
+ }
+}
+
+void QtSliderFactoryPrivate::slotRangeChanged(QtProperty *property, int min, int max)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+
+ QtIntPropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+
+ QListIterator<QSlider *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QSlider *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setRange(min, max);
+ editor->setValue(manager->value(property));
+ editor->blockSignals(false);
+ }
+}
+
+void QtSliderFactoryPrivate::slotSingleStepChanged(QtProperty *property, int step)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+ QListIterator<QSlider *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QSlider *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setSingleStep(step);
+ editor->blockSignals(false);
+ }
+}
+
+void QtSliderFactoryPrivate::slotSetValue(int value)
+{
+ QObject *object = q_ptr->sender();
+ const QMap<QSlider *, QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
+ for (QMap<QSlider *, QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor ) {
+ if (itEditor.key() == object) {
+ QtProperty *property = itEditor.value();
+ QtIntPropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+ manager->setValue(property, value);
+ return;
+ }
+ }
+}
+
+/*!
+ \class QtSliderFactory
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtSliderFactory class provides QSlider widgets for
+ properties created by QtIntPropertyManager objects.
+
+ \sa QtAbstractEditorFactory, QtIntPropertyManager
+*/
+
+/*!
+ Creates a factory with the given \a parent.
+*/
+QtSliderFactory::QtSliderFactory(QObject *parent)
+ : QtAbstractEditorFactory<QtIntPropertyManager>(parent), d_ptr(new QtSliderFactoryPrivate())
+{
+ d_ptr->q_ptr = this;
+
+}
+
+/*!
+ Destroys this factory, and all the widgets it has created.
+*/
+QtSliderFactory::~QtSliderFactory()
+{
+ qDeleteAll(d_ptr->m_editorToProperty.keys());
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtSliderFactory::connectPropertyManager(QtIntPropertyManager *manager)
+{
+ connect(manager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotPropertyChanged(QtProperty*,int)));
+ connect(manager, SIGNAL(rangeChanged(QtProperty*,int,int)),
+ this, SLOT(slotRangeChanged(QtProperty*,int,int)));
+ connect(manager, SIGNAL(singleStepChanged(QtProperty*,int)),
+ this, SLOT(slotSingleStepChanged(QtProperty*,int)));
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+QWidget *QtSliderFactory::createEditor(QtIntPropertyManager *manager, QtProperty *property,
+ QWidget *parent)
+{
+ QSlider *editor = new QSlider(Qt::Horizontal, parent);
+ d_ptr->initializeEditor(property, editor);
+ editor->setSingleStep(manager->singleStep(property));
+ editor->setRange(manager->minimum(property), manager->maximum(property));
+ editor->setValue(manager->value(property));
+
+ connect(editor, SIGNAL(valueChanged(int)), this, SLOT(slotSetValue(int)));
+ connect(editor, SIGNAL(destroyed(QObject*)),
+ this, SLOT(slotEditorDestroyed(QObject*)));
+ return editor;
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtSliderFactory::disconnectPropertyManager(QtIntPropertyManager *manager)
+{
+ disconnect(manager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotPropertyChanged(QtProperty*,int)));
+ disconnect(manager, SIGNAL(rangeChanged(QtProperty*,int,int)),
+ this, SLOT(slotRangeChanged(QtProperty*,int,int)));
+ disconnect(manager, SIGNAL(singleStepChanged(QtProperty*,int)),
+ this, SLOT(slotSingleStepChanged(QtProperty*,int)));
+}
+
+// QtSliderFactory
+
+class QtScrollBarFactoryPrivate : public EditorFactoryPrivate<QScrollBar>
+{
+ QtScrollBarFactory *q_ptr;
+ Q_DECLARE_PUBLIC(QtScrollBarFactory)
+public:
+ void slotPropertyChanged(QtProperty *property, int value);
+ void slotRangeChanged(QtProperty *property, int min, int max);
+ void slotSingleStepChanged(QtProperty *property, int step);
+ void slotSetValue(int value);
+};
+
+void QtScrollBarFactoryPrivate::slotPropertyChanged(QtProperty *property, int value)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+
+ QListIterator<QScrollBar *> itEditor( m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QScrollBar *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setValue(value);
+ editor->blockSignals(false);
+ }
+}
+
+void QtScrollBarFactoryPrivate::slotRangeChanged(QtProperty *property, int min, int max)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+
+ QtIntPropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+
+ QListIterator<QScrollBar *> itEditor( m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QScrollBar *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setRange(min, max);
+ editor->setValue(manager->value(property));
+ editor->blockSignals(false);
+ }
+}
+
+void QtScrollBarFactoryPrivate::slotSingleStepChanged(QtProperty *property, int step)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+ QListIterator<QScrollBar *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QScrollBar *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setSingleStep(step);
+ editor->blockSignals(false);
+ }
+}
+
+void QtScrollBarFactoryPrivate::slotSetValue(int value)
+{
+ QObject *object = q_ptr->sender();
+ const QMap<QScrollBar *, QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
+ for (QMap<QScrollBar *, QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
+ if (itEditor.key() == object) {
+ QtProperty *property = itEditor.value();
+ QtIntPropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+ manager->setValue(property, value);
+ return;
+ }
+}
+
+/*!
+ \class QtScrollBarFactory
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtScrollBarFactory class provides QScrollBar widgets for
+ properties created by QtIntPropertyManager objects.
+
+ \sa QtAbstractEditorFactory, QtIntPropertyManager
+*/
+
+/*!
+ Creates a factory with the given \a parent.
+*/
+QtScrollBarFactory::QtScrollBarFactory(QObject *parent)
+ : QtAbstractEditorFactory<QtIntPropertyManager>(parent), d_ptr(new QtScrollBarFactoryPrivate())
+{
+ d_ptr->q_ptr = this;
+
+}
+
+/*!
+ Destroys this factory, and all the widgets it has created.
+*/
+QtScrollBarFactory::~QtScrollBarFactory()
+{
+ qDeleteAll(d_ptr->m_editorToProperty.keys());
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtScrollBarFactory::connectPropertyManager(QtIntPropertyManager *manager)
+{
+ connect(manager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotPropertyChanged(QtProperty*,int)));
+ connect(manager, SIGNAL(rangeChanged(QtProperty*,int,int)),
+ this, SLOT(slotRangeChanged(QtProperty*,int,int)));
+ connect(manager, SIGNAL(singleStepChanged(QtProperty*,int)),
+ this, SLOT(slotSingleStepChanged(QtProperty*,int)));
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+QWidget *QtScrollBarFactory::createEditor(QtIntPropertyManager *manager, QtProperty *property,
+ QWidget *parent)
+{
+ QScrollBar *editor = new QScrollBar(Qt::Horizontal, parent);
+ d_ptr->initializeEditor(property, editor);
+ editor->setSingleStep(manager->singleStep(property));
+ editor->setRange(manager->minimum(property), manager->maximum(property));
+ editor->setValue(manager->value(property));
+ connect(editor, SIGNAL(valueChanged(int)), this, SLOT(slotSetValue(int)));
+ connect(editor, SIGNAL(destroyed(QObject*)),
+ this, SLOT(slotEditorDestroyed(QObject*)));
+ return editor;
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtScrollBarFactory::disconnectPropertyManager(QtIntPropertyManager *manager)
+{
+ disconnect(manager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotPropertyChanged(QtProperty*,int)));
+ disconnect(manager, SIGNAL(rangeChanged(QtProperty*,int,int)),
+ this, SLOT(slotRangeChanged(QtProperty*,int,int)));
+ disconnect(manager, SIGNAL(singleStepChanged(QtProperty*,int)),
+ this, SLOT(slotSingleStepChanged(QtProperty*,int)));
+}
+
+// QtCheckBoxFactory
+
+class QtCheckBoxFactoryPrivate : public EditorFactoryPrivate<QtBoolEdit>
+{
+ QtCheckBoxFactory *q_ptr;
+ Q_DECLARE_PUBLIC(QtCheckBoxFactory)
+public:
+ void slotPropertyChanged(QtProperty *property, bool value);
+ void slotSetValue(bool value);
+};
+
+void QtCheckBoxFactoryPrivate::slotPropertyChanged(QtProperty *property, bool value)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+
+ QListIterator<QtBoolEdit *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QtBoolEdit *editor = itEditor.next();
+ editor->blockCheckBoxSignals(true);
+ editor->setChecked(value);
+ editor->blockCheckBoxSignals(false);
+ }
+}
+
+void QtCheckBoxFactoryPrivate::slotSetValue(bool value)
+{
+ QObject *object = q_ptr->sender();
+
+ const QMap<QtBoolEdit *, QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
+ for (QMap<QtBoolEdit *, QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
+ if (itEditor.key() == object) {
+ QtProperty *property = itEditor.value();
+ QtBoolPropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+ manager->setValue(property, value);
+ return;
+ }
+}
+
+/*!
+ \class QtCheckBoxFactory
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtCheckBoxFactory class provides QCheckBox widgets for
+ properties created by QtBoolPropertyManager objects.
+
+ \sa QtAbstractEditorFactory, QtBoolPropertyManager
+*/
+
+/*!
+ Creates a factory with the given \a parent.
+*/
+QtCheckBoxFactory::QtCheckBoxFactory(QObject *parent)
+ : QtAbstractEditorFactory<QtBoolPropertyManager>(parent), d_ptr(new QtCheckBoxFactoryPrivate())
+{
+ d_ptr->q_ptr = this;
+
+}
+
+/*!
+ Destroys this factory, and all the widgets it has created.
+*/
+QtCheckBoxFactory::~QtCheckBoxFactory()
+{
+ qDeleteAll(d_ptr->m_editorToProperty.keys());
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtCheckBoxFactory::connectPropertyManager(QtBoolPropertyManager *manager)
+{
+ connect(manager, SIGNAL(valueChanged(QtProperty*,bool)),
+ this, SLOT(slotPropertyChanged(QtProperty*,bool)));
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+QWidget *QtCheckBoxFactory::createEditor(QtBoolPropertyManager *manager, QtProperty *property,
+ QWidget *parent)
+{
+ QtBoolEdit *editor = d_ptr->createEditor(property, parent);
+ editor->setChecked(manager->value(property));
+
+ connect(editor, SIGNAL(toggled(bool)), this, SLOT(slotSetValue(bool)));
+ connect(editor, SIGNAL(destroyed(QObject*)),
+ this, SLOT(slotEditorDestroyed(QObject*)));
+ return editor;
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtCheckBoxFactory::disconnectPropertyManager(QtBoolPropertyManager *manager)
+{
+ disconnect(manager, SIGNAL(valueChanged(QtProperty*,bool)),
+ this, SLOT(slotPropertyChanged(QtProperty*,bool)));
+}
+
+// QtDoubleSpinBoxFactory
+
+class QtDoubleSpinBoxFactoryPrivate : public EditorFactoryPrivate<QDoubleSpinBox>
+{
+ QtDoubleSpinBoxFactory *q_ptr;
+ Q_DECLARE_PUBLIC(QtDoubleSpinBoxFactory)
+public:
+
+ void slotPropertyChanged(QtProperty *property, double value);
+ void slotRangeChanged(QtProperty *property, double min, double max);
+ void slotSingleStepChanged(QtProperty *property, double step);
+ void slotDecimalsChanged(QtProperty *property, int prec);
+ void slotSetValue(double value);
+};
+
+void QtDoubleSpinBoxFactoryPrivate::slotPropertyChanged(QtProperty *property, double value)
+{
+ QList<QDoubleSpinBox *> editors = m_createdEditors[property];
+ QListIterator<QDoubleSpinBox *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QDoubleSpinBox *editor = itEditor.next();
+ if (editor->value() != value) {
+ editor->blockSignals(true);
+ editor->setValue(value);
+ editor->blockSignals(false);
+ }
+ }
+}
+
+void QtDoubleSpinBoxFactoryPrivate::slotRangeChanged(QtProperty *property,
+ double min, double max)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+
+ QtDoublePropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+
+ QList<QDoubleSpinBox *> editors = m_createdEditors[property];
+ QListIterator<QDoubleSpinBox *> itEditor(editors);
+ while (itEditor.hasNext()) {
+ QDoubleSpinBox *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setRange(min, max);
+ editor->setValue(manager->value(property));
+ editor->blockSignals(false);
+ }
+}
+
+void QtDoubleSpinBoxFactoryPrivate::slotSingleStepChanged(QtProperty *property, double step)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+
+ QtDoublePropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+
+ QList<QDoubleSpinBox *> editors = m_createdEditors[property];
+ QListIterator<QDoubleSpinBox *> itEditor(editors);
+ while (itEditor.hasNext()) {
+ QDoubleSpinBox *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setSingleStep(step);
+ editor->blockSignals(false);
+ }
+}
+
+void QtDoubleSpinBoxFactoryPrivate::slotDecimalsChanged(QtProperty *property, int prec)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+
+ QtDoublePropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+
+ QList<QDoubleSpinBox *> editors = m_createdEditors[property];
+ QListIterator<QDoubleSpinBox *> itEditor(editors);
+ while (itEditor.hasNext()) {
+ QDoubleSpinBox *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setDecimals(prec);
+ editor->setValue(manager->value(property));
+ editor->blockSignals(false);
+ }
+}
+
+void QtDoubleSpinBoxFactoryPrivate::slotSetValue(double value)
+{
+ QObject *object = q_ptr->sender();
+ const QMap<QDoubleSpinBox *, QtProperty *>::ConstIterator itcend = m_editorToProperty.constEnd();
+ for (QMap<QDoubleSpinBox *, QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != itcend; ++itEditor) {
+ if (itEditor.key() == object) {
+ QtProperty *property = itEditor.value();
+ QtDoublePropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+ manager->setValue(property, value);
+ return;
+ }
+ }
+}
+
+/*! \class QtDoubleSpinBoxFactory
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtDoubleSpinBoxFactory class provides QDoubleSpinBox
+ widgets for properties created by QtDoublePropertyManager objects.
+
+ \sa QtAbstractEditorFactory, QtDoublePropertyManager
+*/
+
+/*!
+ Creates a factory with the given \a parent.
+*/
+QtDoubleSpinBoxFactory::QtDoubleSpinBoxFactory(QObject *parent)
+ : QtAbstractEditorFactory<QtDoublePropertyManager>(parent), d_ptr(new QtDoubleSpinBoxFactoryPrivate())
+{
+ d_ptr->q_ptr = this;
+
+}
+
+/*!
+ Destroys this factory, and all the widgets it has created.
+*/
+QtDoubleSpinBoxFactory::~QtDoubleSpinBoxFactory()
+{
+ qDeleteAll(d_ptr->m_editorToProperty.keys());
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtDoubleSpinBoxFactory::connectPropertyManager(QtDoublePropertyManager *manager)
+{
+ connect(manager, SIGNAL(valueChanged(QtProperty*,double)),
+ this, SLOT(slotPropertyChanged(QtProperty*,double)));
+ connect(manager, SIGNAL(rangeChanged(QtProperty*,double,double)),
+ this, SLOT(slotRangeChanged(QtProperty*,double,double)));
+ connect(manager, SIGNAL(singleStepChanged(QtProperty*,double)),
+ this, SLOT(slotSingleStepChanged(QtProperty*,double)));
+ connect(manager, SIGNAL(decimalsChanged(QtProperty*,int)),
+ this, SLOT(slotDecimalsChanged(QtProperty*,int)));
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+QWidget *QtDoubleSpinBoxFactory::createEditor(QtDoublePropertyManager *manager,
+ QtProperty *property, QWidget *parent)
+{
+ QDoubleSpinBox *editor = d_ptr->createEditor(property, parent);
+ editor->setSingleStep(manager->singleStep(property));
+ editor->setDecimals(manager->decimals(property));
+ editor->setRange(manager->minimum(property), manager->maximum(property));
+ editor->setValue(manager->value(property));
+ editor->setKeyboardTracking(false);
+
+ connect(editor, SIGNAL(valueChanged(double)), this, SLOT(slotSetValue(double)));
+ connect(editor, SIGNAL(destroyed(QObject*)),
+ this, SLOT(slotEditorDestroyed(QObject*)));
+ return editor;
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtDoubleSpinBoxFactory::disconnectPropertyManager(QtDoublePropertyManager *manager)
+{
+ disconnect(manager, SIGNAL(valueChanged(QtProperty*,double)),
+ this, SLOT(slotPropertyChanged(QtProperty*,double)));
+ disconnect(manager, SIGNAL(rangeChanged(QtProperty*,double,double)),
+ this, SLOT(slotRangeChanged(QtProperty*,double,double)));
+ disconnect(manager, SIGNAL(singleStepChanged(QtProperty*,double)),
+ this, SLOT(slotSingleStepChanged(QtProperty*,double)));
+ disconnect(manager, SIGNAL(decimalsChanged(QtProperty*,int)),
+ this, SLOT(slotDecimalsChanged(QtProperty*,int)));
+}
+
+// QtLineEditFactory
+
+class QtLineEditFactoryPrivate : public EditorFactoryPrivate<QLineEdit>
+{
+ QtLineEditFactory *q_ptr;
+ Q_DECLARE_PUBLIC(QtLineEditFactory)
+public:
+
+ void slotPropertyChanged(QtProperty *property, const QString &value);
+ void slotRegExpChanged(QtProperty *property, const QRegExp &regExp);
+ void slotSetValue(const QString &value);
+};
+
+void QtLineEditFactoryPrivate::slotPropertyChanged(QtProperty *property,
+ const QString &value)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+
+ QListIterator<QLineEdit *> itEditor( m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QLineEdit *editor = itEditor.next();
+ if (editor->text() != value)
+ editor->setText(value);
+ }
+}
+
+void QtLineEditFactoryPrivate::slotRegExpChanged(QtProperty *property,
+ const QRegExp &regExp)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+
+ QtStringPropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+
+ QListIterator<QLineEdit *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QLineEdit *editor = itEditor.next();
+ editor->blockSignals(true);
+ const QValidator *oldValidator = editor->validator();
+ QValidator *newValidator = 0;
+ if (regExp.isValid()) {
+ newValidator = new QRegExpValidator(regExp, editor);
+ }
+ editor->setValidator(newValidator);
+ if (oldValidator)
+ delete oldValidator;
+ editor->blockSignals(false);
+ }
+}
+
+void QtLineEditFactoryPrivate::slotSetValue(const QString &value)
+{
+ QObject *object = q_ptr->sender();
+ const QMap<QLineEdit *, QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
+ for (QMap<QLineEdit *, QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
+ if (itEditor.key() == object) {
+ QtProperty *property = itEditor.value();
+ QtStringPropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+ manager->setValue(property, value);
+ return;
+ }
+}
+
+/*!
+ \class QtLineEditFactory
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtLineEditFactory class provides QLineEdit widgets for
+ properties created by QtStringPropertyManager objects.
+
+ \sa QtAbstractEditorFactory, QtStringPropertyManager
+*/
+
+/*!
+ Creates a factory with the given \a parent.
+*/
+QtLineEditFactory::QtLineEditFactory(QObject *parent)
+ : QtAbstractEditorFactory<QtStringPropertyManager>(parent), d_ptr(new QtLineEditFactoryPrivate())
+{
+ d_ptr->q_ptr = this;
+
+}
+
+/*!
+ Destroys this factory, and all the widgets it has created.
+*/
+QtLineEditFactory::~QtLineEditFactory()
+{
+ qDeleteAll(d_ptr->m_editorToProperty.keys());
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtLineEditFactory::connectPropertyManager(QtStringPropertyManager *manager)
+{
+ connect(manager, SIGNAL(valueChanged(QtProperty*,QString)),
+ this, SLOT(slotPropertyChanged(QtProperty*,QString)));
+ connect(manager, SIGNAL(regExpChanged(QtProperty*,QRegExp)),
+ this, SLOT(slotRegExpChanged(QtProperty*,QRegExp)));
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+QWidget *QtLineEditFactory::createEditor(QtStringPropertyManager *manager,
+ QtProperty *property, QWidget *parent)
+{
+
+ QLineEdit *editor = d_ptr->createEditor(property, parent);
+ QRegExp regExp = manager->regExp(property);
+ if (regExp.isValid()) {
+ QValidator *validator = new QRegExpValidator(regExp, editor);
+ editor->setValidator(validator);
+ }
+ editor->setText(manager->value(property));
+
+ connect(editor, SIGNAL(textEdited(QString)),
+ this, SLOT(slotSetValue(QString)));
+ connect(editor, SIGNAL(destroyed(QObject*)),
+ this, SLOT(slotEditorDestroyed(QObject*)));
+ return editor;
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtLineEditFactory::disconnectPropertyManager(QtStringPropertyManager *manager)
+{
+ disconnect(manager, SIGNAL(valueChanged(QtProperty*,QString)),
+ this, SLOT(slotPropertyChanged(QtProperty*,QString)));
+ disconnect(manager, SIGNAL(regExpChanged(QtProperty*,QRegExp)),
+ this, SLOT(slotRegExpChanged(QtProperty*,QRegExp)));
+}
+
+// QtDateEditFactory
+
+class QtDateEditFactoryPrivate : public EditorFactoryPrivate<QDateEdit>
+{
+ QtDateEditFactory *q_ptr;
+ Q_DECLARE_PUBLIC(QtDateEditFactory)
+public:
+
+ void slotPropertyChanged(QtProperty *property, const QDate &value);
+ void slotRangeChanged(QtProperty *property, const QDate &min, const QDate &max);
+ void slotSetValue(const QDate &value);
+};
+
+void QtDateEditFactoryPrivate::slotPropertyChanged(QtProperty *property, const QDate &value)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+ QListIterator<QDateEdit *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QDateEdit *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setDate(value);
+ editor->blockSignals(false);
+ }
+}
+
+void QtDateEditFactoryPrivate::slotRangeChanged(QtProperty *property,
+ const QDate &min, const QDate &max)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+
+ QtDatePropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+
+ QListIterator<QDateEdit *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QDateEdit *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setDateRange(min, max);
+ editor->setDate(manager->value(property));
+ editor->blockSignals(false);
+ }
+}
+
+void QtDateEditFactoryPrivate::slotSetValue(const QDate &value)
+{
+ QObject *object = q_ptr->sender();
+ const QMap<QDateEdit *, QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
+ for (QMap<QDateEdit *, QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
+ if (itEditor.key() == object) {
+ QtProperty *property = itEditor.value();
+ QtDatePropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+ manager->setValue(property, value);
+ return;
+ }
+}
+
+/*!
+ \class QtDateEditFactory
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtDateEditFactory class provides QDateEdit widgets for
+ properties created by QtDatePropertyManager objects.
+
+ \sa QtAbstractEditorFactory, QtDatePropertyManager
+*/
+
+/*!
+ Creates a factory with the given \a parent.
+*/
+QtDateEditFactory::QtDateEditFactory(QObject *parent)
+ : QtAbstractEditorFactory<QtDatePropertyManager>(parent), d_ptr(new QtDateEditFactoryPrivate())
+{
+ d_ptr->q_ptr = this;
+
+}
+
+/*!
+ Destroys this factory, and all the widgets it has created.
+*/
+QtDateEditFactory::~QtDateEditFactory()
+{
+ qDeleteAll(d_ptr->m_editorToProperty.keys());
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtDateEditFactory::connectPropertyManager(QtDatePropertyManager *manager)
+{
+ connect(manager, SIGNAL(valueChanged(QtProperty*,QDate)),
+ this, SLOT(slotPropertyChanged(QtProperty*,QDate)));
+ connect(manager, SIGNAL(rangeChanged(QtProperty*,QDate,QDate)),
+ this, SLOT(slotRangeChanged(QtProperty*,QDate,QDate)));
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+QWidget *QtDateEditFactory::createEditor(QtDatePropertyManager *manager, QtProperty *property,
+ QWidget *parent)
+{
+ QDateEdit *editor = d_ptr->createEditor(property, parent);
+ editor->setDisplayFormat(QtPropertyBrowserUtils::dateFormat());
+ editor->setCalendarPopup(true);
+ editor->setDateRange(manager->minimum(property), manager->maximum(property));
+ editor->setDate(manager->value(property));
+
+ connect(editor, SIGNAL(dateChanged(QDate)),
+ this, SLOT(slotSetValue(QDate)));
+ connect(editor, SIGNAL(destroyed(QObject*)),
+ this, SLOT(slotEditorDestroyed(QObject*)));
+ return editor;
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtDateEditFactory::disconnectPropertyManager(QtDatePropertyManager *manager)
+{
+ disconnect(manager, SIGNAL(valueChanged(QtProperty*,QDate)),
+ this, SLOT(slotPropertyChanged(QtProperty*,QDate)));
+ disconnect(manager, SIGNAL(rangeChanged(QtProperty*,QDate,QDate)),
+ this, SLOT(slotRangeChanged(QtProperty*,QDate,QDate)));
+}
+
+// QtTimeEditFactory
+
+class QtTimeEditFactoryPrivate : public EditorFactoryPrivate<QTimeEdit>
+{
+ QtTimeEditFactory *q_ptr;
+ Q_DECLARE_PUBLIC(QtTimeEditFactory)
+public:
+
+ void slotPropertyChanged(QtProperty *property, const QTime &value);
+ void slotSetValue(const QTime &value);
+};
+
+void QtTimeEditFactoryPrivate::slotPropertyChanged(QtProperty *property, const QTime &value)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+ QListIterator<QTimeEdit *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QTimeEdit *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setTime(value);
+ editor->blockSignals(false);
+ }
+}
+
+void QtTimeEditFactoryPrivate::slotSetValue(const QTime &value)
+{
+ QObject *object = q_ptr->sender();
+ const QMap<QTimeEdit *, QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
+ for (QMap<QTimeEdit *, QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
+ if (itEditor.key() == object) {
+ QtProperty *property = itEditor.value();
+ QtTimePropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+ manager->setValue(property, value);
+ return;
+ }
+}
+
+/*!
+ \class QtTimeEditFactory
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtTimeEditFactory class provides QTimeEdit widgets for
+ properties created by QtTimePropertyManager objects.
+
+ \sa QtAbstractEditorFactory, QtTimePropertyManager
+*/
+
+/*!
+ Creates a factory with the given \a parent.
+*/
+QtTimeEditFactory::QtTimeEditFactory(QObject *parent)
+ : QtAbstractEditorFactory<QtTimePropertyManager>(parent), d_ptr(new QtTimeEditFactoryPrivate())
+{
+ d_ptr->q_ptr = this;
+
+}
+
+/*!
+ Destroys this factory, and all the widgets it has created.
+*/
+QtTimeEditFactory::~QtTimeEditFactory()
+{
+ qDeleteAll(d_ptr->m_editorToProperty.keys());
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtTimeEditFactory::connectPropertyManager(QtTimePropertyManager *manager)
+{
+ connect(manager, SIGNAL(valueChanged(QtProperty*,QTime)),
+ this, SLOT(slotPropertyChanged(QtProperty*,QTime)));
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+QWidget *QtTimeEditFactory::createEditor(QtTimePropertyManager *manager, QtProperty *property,
+ QWidget *parent)
+{
+ QTimeEdit *editor = d_ptr->createEditor(property, parent);
+ editor->setDisplayFormat(QtPropertyBrowserUtils::timeFormat());
+ editor->setTime(manager->value(property));
+
+ connect(editor, SIGNAL(timeChanged(QTime)),
+ this, SLOT(slotSetValue(QTime)));
+ connect(editor, SIGNAL(destroyed(QObject*)),
+ this, SLOT(slotEditorDestroyed(QObject*)));
+ return editor;
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtTimeEditFactory::disconnectPropertyManager(QtTimePropertyManager *manager)
+{
+ disconnect(manager, SIGNAL(valueChanged(QtProperty*,QTime)),
+ this, SLOT(slotPropertyChanged(QtProperty*,QTime)));
+}
+
+// QtDateTimeEditFactory
+
+class QtDateTimeEditFactoryPrivate : public EditorFactoryPrivate<QDateTimeEdit>
+{
+ QtDateTimeEditFactory *q_ptr;
+ Q_DECLARE_PUBLIC(QtDateTimeEditFactory)
+public:
+
+ void slotPropertyChanged(QtProperty *property, const QDateTime &value);
+ void slotSetValue(const QDateTime &value);
+
+};
+
+void QtDateTimeEditFactoryPrivate::slotPropertyChanged(QtProperty *property,
+ const QDateTime &value)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+
+ QListIterator<QDateTimeEdit *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QDateTimeEdit *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setDateTime(value);
+ editor->blockSignals(false);
+ }
+}
+
+void QtDateTimeEditFactoryPrivate::slotSetValue(const QDateTime &value)
+{
+ QObject *object = q_ptr->sender();
+ const QMap<QDateTimeEdit *, QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
+ for (QMap<QDateTimeEdit *, QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
+ if (itEditor.key() == object) {
+ QtProperty *property = itEditor.value();
+ QtDateTimePropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+ manager->setValue(property, value);
+ return;
+ }
+}
+
+/*!
+ \class QtDateTimeEditFactory
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtDateTimeEditFactory class provides QDateTimeEdit
+ widgets for properties created by QtDateTimePropertyManager objects.
+
+ \sa QtAbstractEditorFactory, QtDateTimePropertyManager
+*/
+
+/*!
+ Creates a factory with the given \a parent.
+*/
+QtDateTimeEditFactory::QtDateTimeEditFactory(QObject *parent)
+ : QtAbstractEditorFactory<QtDateTimePropertyManager>(parent), d_ptr(new QtDateTimeEditFactoryPrivate())
+{
+ d_ptr->q_ptr = this;
+
+}
+
+/*!
+ Destroys this factory, and all the widgets it has created.
+*/
+QtDateTimeEditFactory::~QtDateTimeEditFactory()
+{
+ qDeleteAll(d_ptr->m_editorToProperty.keys());
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtDateTimeEditFactory::connectPropertyManager(QtDateTimePropertyManager *manager)
+{
+ connect(manager, SIGNAL(valueChanged(QtProperty*,QDateTime)),
+ this, SLOT(slotPropertyChanged(QtProperty*,QDateTime)));
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+QWidget *QtDateTimeEditFactory::createEditor(QtDateTimePropertyManager *manager,
+ QtProperty *property, QWidget *parent)
+{
+ QDateTimeEdit *editor = d_ptr->createEditor(property, parent);
+ editor->setDisplayFormat(QtPropertyBrowserUtils::dateTimeFormat());
+ editor->setDateTime(manager->value(property));
+
+ connect(editor, SIGNAL(dateTimeChanged(QDateTime)),
+ this, SLOT(slotSetValue(QDateTime)));
+ connect(editor, SIGNAL(destroyed(QObject*)),
+ this, SLOT(slotEditorDestroyed(QObject*)));
+ return editor;
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtDateTimeEditFactory::disconnectPropertyManager(QtDateTimePropertyManager *manager)
+{
+ disconnect(manager, SIGNAL(valueChanged(QtProperty*,QDateTime)),
+ this, SLOT(slotPropertyChanged(QtProperty*,QDateTime)));
+}
+
+// QtKeySequenceEditorFactory
+
+class QtKeySequenceEditorFactoryPrivate : public EditorFactoryPrivate<QtKeySequenceEdit>
+{
+ QtKeySequenceEditorFactory *q_ptr;
+ Q_DECLARE_PUBLIC(QtKeySequenceEditorFactory)
+public:
+
+ void slotPropertyChanged(QtProperty *property, const QKeySequence &value);
+ void slotSetValue(const QKeySequence &value);
+};
+
+void QtKeySequenceEditorFactoryPrivate::slotPropertyChanged(QtProperty *property,
+ const QKeySequence &value)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+
+ QListIterator<QtKeySequenceEdit *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QtKeySequenceEdit *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setKeySequence(value);
+ editor->blockSignals(false);
+ }
+}
+
+void QtKeySequenceEditorFactoryPrivate::slotSetValue(const QKeySequence &value)
+{
+ QObject *object = q_ptr->sender();
+ const QMap<QtKeySequenceEdit *, QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
+ for (QMap<QtKeySequenceEdit *, QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
+ if (itEditor.key() == object) {
+ QtProperty *property = itEditor.value();
+ QtKeySequencePropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+ manager->setValue(property, value);
+ return;
+ }
+}
+
+/*!
+ \class QtKeySequenceEditorFactory
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtKeySequenceEditorFactory class provides editor
+ widgets for properties created by QtKeySequencePropertyManager objects.
+
+ \sa QtAbstractEditorFactory
+*/
+
+/*!
+ Creates a factory with the given \a parent.
+*/
+QtKeySequenceEditorFactory::QtKeySequenceEditorFactory(QObject *parent)
+ : QtAbstractEditorFactory<QtKeySequencePropertyManager>(parent), d_ptr(new QtKeySequenceEditorFactoryPrivate())
+{
+ d_ptr->q_ptr = this;
+
+}
+
+/*!
+ Destroys this factory, and all the widgets it has created.
+*/
+QtKeySequenceEditorFactory::~QtKeySequenceEditorFactory()
+{
+ qDeleteAll(d_ptr->m_editorToProperty.keys());
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtKeySequenceEditorFactory::connectPropertyManager(QtKeySequencePropertyManager *manager)
+{
+ connect(manager, SIGNAL(valueChanged(QtProperty*,QKeySequence)),
+ this, SLOT(slotPropertyChanged(QtProperty*,QKeySequence)));
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+QWidget *QtKeySequenceEditorFactory::createEditor(QtKeySequencePropertyManager *manager,
+ QtProperty *property, QWidget *parent)
+{
+ QtKeySequenceEdit *editor = d_ptr->createEditor(property, parent);
+ editor->setKeySequence(manager->value(property));
+
+ connect(editor, SIGNAL(keySequenceChanged(QKeySequence)),
+ this, SLOT(slotSetValue(QKeySequence)));
+ connect(editor, SIGNAL(destroyed(QObject*)),
+ this, SLOT(slotEditorDestroyed(QObject*)));
+ return editor;
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtKeySequenceEditorFactory::disconnectPropertyManager(QtKeySequencePropertyManager *manager)
+{
+ disconnect(manager, SIGNAL(valueChanged(QtProperty*,QKeySequence)),
+ this, SLOT(slotPropertyChanged(QtProperty*,QKeySequence)));
+}
+
+// QtCharEdit
+
+class QtCharEdit : public QWidget
+{
+ Q_OBJECT
+public:
+ QtCharEdit(QWidget *parent = 0);
+
+ QChar value() const;
+ bool eventFilter(QObject *o, QEvent *e);
+public Q_SLOTS:
+ void setValue(const QChar &value);
+Q_SIGNALS:
+ void valueChanged(const QChar &value);
+protected:
+ void focusInEvent(QFocusEvent *e);
+ void focusOutEvent(QFocusEvent *e);
+ void keyPressEvent(QKeyEvent *e);
+ void keyReleaseEvent(QKeyEvent *e);
+ bool event(QEvent *e);
+private slots:
+ void slotClearChar();
+private:
+ void handleKeyEvent(QKeyEvent *e);
+
+ QChar m_value;
+ QLineEdit *m_lineEdit;
+};
+
+QtCharEdit::QtCharEdit(QWidget *parent)
+ : QWidget(parent), m_lineEdit(new QLineEdit(this))
+{
+ QHBoxLayout *layout = new QHBoxLayout(this);
+ layout->addWidget(m_lineEdit);
+ layout->setMargin(0);
+ m_lineEdit->installEventFilter(this);
+ m_lineEdit->setReadOnly(true);
+ m_lineEdit->setFocusProxy(this);
+ setFocusPolicy(m_lineEdit->focusPolicy());
+ setAttribute(Qt::WA_InputMethodEnabled);
+}
+
+bool QtCharEdit::eventFilter(QObject *o, QEvent *e)
+{
+ if (o == m_lineEdit && e->type() == QEvent::ContextMenu) {
+ QContextMenuEvent *c = static_cast<QContextMenuEvent *>(e);
+ QMenu *menu = m_lineEdit->createStandardContextMenu();
+ QList<QAction *> actions = menu->actions();
+ QListIterator<QAction *> itAction(actions);
+ while (itAction.hasNext()) {
+ QAction *action = itAction.next();
+ action->setShortcut(QKeySequence());
+ QString actionString = action->text();
+ const int pos = actionString.lastIndexOf(QLatin1Char('\t'));
+ if (pos > 0)
+ actionString = actionString.remove(pos, actionString.length() - pos);
+ action->setText(actionString);
+ }
+ QAction *actionBefore = 0;
+ if (actions.count() > 0)
+ actionBefore = actions[0];
+ QAction *clearAction = new QAction(tr("Clear Char"), menu);
+ menu->insertAction(actionBefore, clearAction);
+ menu->insertSeparator(actionBefore);
+ clearAction->setEnabled(!m_value.isNull());
+ connect(clearAction, SIGNAL(triggered()), this, SLOT(slotClearChar()));
+ menu->exec(c->globalPos());
+ delete menu;
+ e->accept();
+ return true;
+ }
+
+ return QWidget::eventFilter(o, e);
+}
+
+void QtCharEdit::slotClearChar()
+{
+ if (m_value.isNull())
+ return;
+ setValue(QChar());
+ emit valueChanged(m_value);
+}
+
+void QtCharEdit::handleKeyEvent(QKeyEvent *e)
+{
+ const int key = e->key();
+ switch (key) {
+ case Qt::Key_Control:
+ case Qt::Key_Shift:
+ case Qt::Key_Meta:
+ case Qt::Key_Alt:
+ case Qt::Key_Super_L:
+ case Qt::Key_Return:
+ return;
+ default:
+ break;
+ }
+
+ const QString text = e->text();
+ if (text.count() != 1)
+ return;
+
+ const QChar c = text.at(0);
+ if (!c.isPrint())
+ return;
+
+ if (m_value == c)
+ return;
+
+ m_value = c;
+ const QString str = m_value.isNull() ? QString() : QString(m_value);
+ m_lineEdit->setText(str);
+ e->accept();
+ emit valueChanged(m_value);
+}
+
+void QtCharEdit::setValue(const QChar &value)
+{
+ if (value == m_value)
+ return;
+
+ m_value = value;
+ QString str = value.isNull() ? QString() : QString(value);
+ m_lineEdit->setText(str);
+}
+
+QChar QtCharEdit::value() const
+{
+ return m_value;
+}
+
+void QtCharEdit::focusInEvent(QFocusEvent *e)
+{
+ m_lineEdit->event(e);
+ m_lineEdit->selectAll();
+ QWidget::focusInEvent(e);
+}
+
+void QtCharEdit::focusOutEvent(QFocusEvent *e)
+{
+ m_lineEdit->event(e);
+ QWidget::focusOutEvent(e);
+}
+
+void QtCharEdit::keyPressEvent(QKeyEvent *e)
+{
+ handleKeyEvent(e);
+ e->accept();
+}
+
+void QtCharEdit::keyReleaseEvent(QKeyEvent *e)
+{
+ m_lineEdit->event(e);
+}
+
+bool QtCharEdit::event(QEvent *e)
+{
+ switch(e->type()) {
+ case QEvent::Shortcut:
+ case QEvent::ShortcutOverride:
+ case QEvent::KeyRelease:
+ e->accept();
+ return true;
+ default:
+ break;
+ }
+ return QWidget::event(e);
+}
+
+// QtCharEditorFactory
+
+class QtCharEditorFactoryPrivate : public EditorFactoryPrivate<QtCharEdit>
+{
+ QtCharEditorFactory *q_ptr;
+ Q_DECLARE_PUBLIC(QtCharEditorFactory)
+public:
+
+ void slotPropertyChanged(QtProperty *property, const QChar &value);
+ void slotSetValue(const QChar &value);
+
+};
+
+void QtCharEditorFactoryPrivate::slotPropertyChanged(QtProperty *property,
+ const QChar &value)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+
+ QListIterator<QtCharEdit *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QtCharEdit *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setValue(value);
+ editor->blockSignals(false);
+ }
+}
+
+void QtCharEditorFactoryPrivate::slotSetValue(const QChar &value)
+{
+ QObject *object = q_ptr->sender();
+ const QMap<QtCharEdit *, QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
+ for (QMap<QtCharEdit *, QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
+ if (itEditor.key() == object) {
+ QtProperty *property = itEditor.value();
+ QtCharPropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+ manager->setValue(property, value);
+ return;
+ }
+}
+
+/*!
+ \class QtCharEditorFactory
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtCharEditorFactory class provides editor
+ widgets for properties created by QtCharPropertyManager objects.
+
+ \sa QtAbstractEditorFactory
+*/
+
+/*!
+ Creates a factory with the given \a parent.
+*/
+QtCharEditorFactory::QtCharEditorFactory(QObject *parent)
+ : QtAbstractEditorFactory<QtCharPropertyManager>(parent), d_ptr(new QtCharEditorFactoryPrivate())
+{
+ d_ptr->q_ptr = this;
+
+}
+
+/*!
+ Destroys this factory, and all the widgets it has created.
+*/
+QtCharEditorFactory::~QtCharEditorFactory()
+{
+ qDeleteAll(d_ptr->m_editorToProperty.keys());
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtCharEditorFactory::connectPropertyManager(QtCharPropertyManager *manager)
+{
+ connect(manager, SIGNAL(valueChanged(QtProperty*,QChar)),
+ this, SLOT(slotPropertyChanged(QtProperty*,QChar)));
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+QWidget *QtCharEditorFactory::createEditor(QtCharPropertyManager *manager,
+ QtProperty *property, QWidget *parent)
+{
+ QtCharEdit *editor = d_ptr->createEditor(property, parent);
+ editor->setValue(manager->value(property));
+
+ connect(editor, SIGNAL(valueChanged(QChar)),
+ this, SLOT(slotSetValue(QChar)));
+ connect(editor, SIGNAL(destroyed(QObject*)),
+ this, SLOT(slotEditorDestroyed(QObject*)));
+ return editor;
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtCharEditorFactory::disconnectPropertyManager(QtCharPropertyManager *manager)
+{
+ disconnect(manager, SIGNAL(valueChanged(QtProperty*,QChar)),
+ this, SLOT(slotPropertyChanged(QtProperty*,QChar)));
+}
+
+// QtEnumEditorFactory
+
+class QtEnumEditorFactoryPrivate : public EditorFactoryPrivate<QComboBox>
+{
+ QtEnumEditorFactory *q_ptr;
+ Q_DECLARE_PUBLIC(QtEnumEditorFactory)
+public:
+
+ void slotPropertyChanged(QtProperty *property, int value);
+ void slotEnumNamesChanged(QtProperty *property, const QStringList &);
+ void slotEnumIconsChanged(QtProperty *property, const QMap<int, QIcon> &);
+ void slotSetValue(int value);
+};
+
+void QtEnumEditorFactoryPrivate::slotPropertyChanged(QtProperty *property, int value)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+
+ QListIterator<QComboBox *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QComboBox *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->setCurrentIndex(value);
+ editor->blockSignals(false);
+ }
+}
+
+void QtEnumEditorFactoryPrivate::slotEnumNamesChanged(QtProperty *property,
+ const QStringList &enumNames)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+
+ QtEnumPropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+
+ QMap<int, QIcon> enumIcons = manager->enumIcons(property);
+
+ QListIterator<QComboBox *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QComboBox *editor = itEditor.next();
+ editor->blockSignals(true);
+ editor->clear();
+ editor->addItems(enumNames);
+ const int nameCount = enumNames.count();
+ for (int i = 0; i < nameCount; i++)
+ editor->setItemIcon(i, enumIcons.value(i));
+ editor->setCurrentIndex(manager->value(property));
+ editor->blockSignals(false);
+ }
+}
+
+void QtEnumEditorFactoryPrivate::slotEnumIconsChanged(QtProperty *property,
+ const QMap<int, QIcon> &enumIcons)
+{
+ if (!m_createdEditors.contains(property))
+ return;
+
+ QtEnumPropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+
+ const QStringList enumNames = manager->enumNames(property);
+ QListIterator<QComboBox *> itEditor(m_createdEditors[property]);
+ while (itEditor.hasNext()) {
+ QComboBox *editor = itEditor.next();
+ editor->blockSignals(true);
+ const int nameCount = enumNames.count();
+ for (int i = 0; i < nameCount; i++)
+ editor->setItemIcon(i, enumIcons.value(i));
+ editor->setCurrentIndex(manager->value(property));
+ editor->blockSignals(false);
+ }
+}
+
+void QtEnumEditorFactoryPrivate::slotSetValue(int value)
+{
+ QObject *object = q_ptr->sender();
+ const QMap<QComboBox *, QtProperty *>::ConstIterator ecend = m_editorToProperty.constEnd();
+ for (QMap<QComboBox *, QtProperty *>::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
+ if (itEditor.key() == object) {
+ QtProperty *property = itEditor.value();
+ QtEnumPropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+ manager->setValue(property, value);
+ return;
+ }
+}
+
+/*!
+ \class QtEnumEditorFactory
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtEnumEditorFactory class provides QComboBox widgets for
+ properties created by QtEnumPropertyManager objects.
+
+ \sa QtAbstractEditorFactory, QtEnumPropertyManager
+*/
+
+/*!
+ Creates a factory with the given \a parent.
+*/
+QtEnumEditorFactory::QtEnumEditorFactory(QObject *parent)
+ : QtAbstractEditorFactory<QtEnumPropertyManager>(parent), d_ptr(new QtEnumEditorFactoryPrivate())
+{
+ d_ptr->q_ptr = this;
+
+}
+
+/*!
+ Destroys this factory, and all the widgets it has created.
+*/
+QtEnumEditorFactory::~QtEnumEditorFactory()
+{
+ qDeleteAll(d_ptr->m_editorToProperty.keys());
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtEnumEditorFactory::connectPropertyManager(QtEnumPropertyManager *manager)
+{
+ connect(manager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotPropertyChanged(QtProperty*,int)));
+ connect(manager, SIGNAL(enumNamesChanged(QtProperty*,QStringList)),
+ this, SLOT(slotEnumNamesChanged(QtProperty*,QStringList)));
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+QWidget *QtEnumEditorFactory::createEditor(QtEnumPropertyManager *manager, QtProperty *property,
+ QWidget *parent)
+{
+ QComboBox *editor = d_ptr->createEditor(property, parent);
+ editor->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
+ editor->view()->setTextElideMode(Qt::ElideRight);
+ QStringList enumNames = manager->enumNames(property);
+ editor->addItems(enumNames);
+ QMap<int, QIcon> enumIcons = manager->enumIcons(property);
+ const int enumNamesCount = enumNames.count();
+ for (int i = 0; i < enumNamesCount; i++)
+ editor->setItemIcon(i, enumIcons.value(i));
+ editor->setCurrentIndex(manager->value(property));
+
+ connect(editor, SIGNAL(currentIndexChanged(int)), this, SLOT(slotSetValue(int)));
+ connect(editor, SIGNAL(destroyed(QObject*)),
+ this, SLOT(slotEditorDestroyed(QObject*)));
+ return editor;
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtEnumEditorFactory::disconnectPropertyManager(QtEnumPropertyManager *manager)
+{
+ disconnect(manager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotPropertyChanged(QtProperty*,int)));
+ disconnect(manager, SIGNAL(enumNamesChanged(QtProperty*,QStringList)),
+ this, SLOT(slotEnumNamesChanged(QtProperty*,QStringList)));
+}
+
+// QtCursorEditorFactory
+
+Q_GLOBAL_STATIC(QtCursorDatabase, cursorDatabase)
+
+class QtCursorEditorFactoryPrivate
+{
+ QtCursorEditorFactory *q_ptr;
+ Q_DECLARE_PUBLIC(QtCursorEditorFactory)
+public:
+ QtCursorEditorFactoryPrivate();
+
+ void slotPropertyChanged(QtProperty *property, const QCursor &cursor);
+ void slotEnumChanged(QtProperty *property, int value);
+ void slotEditorDestroyed(QObject *object);
+
+ QtEnumEditorFactory *m_enumEditorFactory;
+ QtEnumPropertyManager *m_enumPropertyManager;
+
+ QMap<QtProperty *, QtProperty *> m_propertyToEnum;
+ QMap<QtProperty *, QtProperty *> m_enumToProperty;
+ QMap<QtProperty *, QList<QWidget *> > m_enumToEditors;
+ QMap<QWidget *, QtProperty *> m_editorToEnum;
+ bool m_updatingEnum;
+};
+
+QtCursorEditorFactoryPrivate::QtCursorEditorFactoryPrivate()
+ : m_updatingEnum(false)
+{
+
+}
+
+void QtCursorEditorFactoryPrivate::slotPropertyChanged(QtProperty *property, const QCursor &cursor)
+{
+ // update enum property
+ QtProperty *enumProp = m_propertyToEnum.value(property);
+ if (!enumProp)
+ return;
+
+ m_updatingEnum = true;
+ m_enumPropertyManager->setValue(enumProp, cursorDatabase()->cursorToValue(cursor));
+ m_updatingEnum = false;
+}
+
+void QtCursorEditorFactoryPrivate::slotEnumChanged(QtProperty *property, int value)
+{
+ if (m_updatingEnum)
+ return;
+ // update cursor property
+ QtProperty *prop = m_enumToProperty.value(property);
+ if (!prop)
+ return;
+ QtCursorPropertyManager *cursorManager = q_ptr->propertyManager(prop);
+ if (!cursorManager)
+ return;
+#ifndef QT_NO_CURSOR
+ cursorManager->setValue(prop, QCursor(cursorDatabase()->valueToCursor(value)));
+#endif
+}
+
+void QtCursorEditorFactoryPrivate::slotEditorDestroyed(QObject *object)
+{
+ // remove from m_editorToEnum map;
+ // remove from m_enumToEditors map;
+ // if m_enumToEditors doesn't contains more editors delete enum property;
+ const QMap<QWidget *, QtProperty *>::ConstIterator ecend = m_editorToEnum.constEnd();
+ for (QMap<QWidget *, QtProperty *>::ConstIterator itEditor = m_editorToEnum.constBegin(); itEditor != ecend; ++itEditor)
+ if (itEditor.key() == object) {
+ QWidget *editor = itEditor.key();
+ QtProperty *enumProp = itEditor.value();
+ m_editorToEnum.remove(editor);
+ m_enumToEditors[enumProp].removeAll(editor);
+ if (m_enumToEditors[enumProp].isEmpty()) {
+ m_enumToEditors.remove(enumProp);
+ QtProperty *property = m_enumToProperty.value(enumProp);
+ m_enumToProperty.remove(enumProp);
+ m_propertyToEnum.remove(property);
+ delete enumProp;
+ }
+ return;
+ }
+}
+
+/*!
+ \class QtCursorEditorFactory
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtCursorEditorFactory class provides QComboBox widgets for
+ properties created by QtCursorPropertyManager objects.
+
+ \sa QtAbstractEditorFactory, QtCursorPropertyManager
+*/
+
+/*!
+ Creates a factory with the given \a parent.
+*/
+QtCursorEditorFactory::QtCursorEditorFactory(QObject *parent)
+ : QtAbstractEditorFactory<QtCursorPropertyManager>(parent), d_ptr(new QtCursorEditorFactoryPrivate())
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->m_enumEditorFactory = new QtEnumEditorFactory(this);
+ d_ptr->m_enumPropertyManager = new QtEnumPropertyManager(this);
+ connect(d_ptr->m_enumPropertyManager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotEnumChanged(QtProperty*,int)));
+ d_ptr->m_enumEditorFactory->addPropertyManager(d_ptr->m_enumPropertyManager);
+}
+
+/*!
+ Destroys this factory, and all the widgets it has created.
+*/
+QtCursorEditorFactory::~QtCursorEditorFactory()
+{
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtCursorEditorFactory::connectPropertyManager(QtCursorPropertyManager *manager)
+{
+ connect(manager, SIGNAL(valueChanged(QtProperty*,QCursor)),
+ this, SLOT(slotPropertyChanged(QtProperty*,QCursor)));
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+QWidget *QtCursorEditorFactory::createEditor(QtCursorPropertyManager *manager, QtProperty *property,
+ QWidget *parent)
+{
+ QtProperty *enumProp = 0;
+ if (d_ptr->m_propertyToEnum.contains(property)) {
+ enumProp = d_ptr->m_propertyToEnum[property];
+ } else {
+ enumProp = d_ptr->m_enumPropertyManager->addProperty(property->propertyName());
+ d_ptr->m_enumPropertyManager->setEnumNames(enumProp, cursorDatabase()->cursorShapeNames());
+ d_ptr->m_enumPropertyManager->setEnumIcons(enumProp, cursorDatabase()->cursorShapeIcons());
+#ifndef QT_NO_CURSOR
+ d_ptr->m_enumPropertyManager->setValue(enumProp, cursorDatabase()->cursorToValue(manager->value(property)));
+#endif
+ d_ptr->m_propertyToEnum[property] = enumProp;
+ d_ptr->m_enumToProperty[enumProp] = property;
+ }
+ QtAbstractEditorFactoryBase *af = d_ptr->m_enumEditorFactory;
+ QWidget *editor = af->createEditor(enumProp, parent);
+ d_ptr->m_enumToEditors[enumProp].append(editor);
+ d_ptr->m_editorToEnum[editor] = enumProp;
+ connect(editor, SIGNAL(destroyed(QObject*)),
+ this, SLOT(slotEditorDestroyed(QObject*)));
+ return editor;
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtCursorEditorFactory::disconnectPropertyManager(QtCursorPropertyManager *manager)
+{
+ disconnect(manager, SIGNAL(valueChanged(QtProperty*,QCursor)),
+ this, SLOT(slotPropertyChanged(QtProperty*,QCursor)));
+}
+
+// QtColorEditWidget
+
+class QtColorEditWidget : public QWidget {
+ Q_OBJECT
+
+public:
+ QtColorEditWidget(QWidget *parent);
+
+ bool eventFilter(QObject *obj, QEvent *ev);
+
+public Q_SLOTS:
+ void setValue(const QColor &value);
+
+private Q_SLOTS:
+ void buttonClicked();
+
+Q_SIGNALS:
+ void valueChanged(const QColor &value);
+
+private:
+ QColor m_color;
+ QLabel *m_pixmapLabel;
+ QLabel *m_label;
+ QToolButton *m_button;
+};
+
+QtColorEditWidget::QtColorEditWidget(QWidget *parent) :
+ QWidget(parent),
+ m_pixmapLabel(new QLabel),
+ m_label(new QLabel),
+ m_button(new QToolButton)
+{
+ QHBoxLayout *lt = new QHBoxLayout(this);
+ setupTreeViewEditorMargin(lt);
+ lt->setSpacing(0);
+ lt->addWidget(m_pixmapLabel);
+ lt->addWidget(m_label);
+ lt->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored));
+
+ m_button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored);
+ m_button->setFixedWidth(20);
+ setFocusProxy(m_button);
+ setFocusPolicy(m_button->focusPolicy());
+ m_button->setText(tr("..."));
+ m_button->installEventFilter(this);
+ connect(m_button, SIGNAL(clicked()), this, SLOT(buttonClicked()));
+ lt->addWidget(m_button);
+ m_pixmapLabel->setPixmap(QtPropertyBrowserUtils::brushValuePixmap(QBrush(m_color)));
+ m_label->setText(QtPropertyBrowserUtils::colorValueText(m_color));
+}
+
+void QtColorEditWidget::setValue(const QColor &c)
+{
+ if (m_color != c) {
+ m_color = c;
+ m_pixmapLabel->setPixmap(QtPropertyBrowserUtils::brushValuePixmap(QBrush(c)));
+ m_label->setText(QtPropertyBrowserUtils::colorValueText(c));
+ }
+}
+
+void QtColorEditWidget::buttonClicked()
+{
+ const QColor newColor = QColorDialog::getColor(m_color, this, QString(), QColorDialog::ShowAlphaChannel);
+ if (newColor.isValid() && newColor != m_color) {
+ setValue(newColor);
+ emit valueChanged(m_color);
+ }
+}
+
+bool QtColorEditWidget::eventFilter(QObject *obj, QEvent *ev)
+{
+ if (obj == m_button) {
+ switch (ev->type()) {
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease: { // Prevent the QToolButton from handling Enter/Escape meant control the delegate
+ switch (static_cast<const QKeyEvent*>(ev)->key()) {
+ case Qt::Key_Escape:
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ ev->ignore();
+ return true;
+ default:
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ return QWidget::eventFilter(obj, ev);
+}
+
+// QtColorEditorFactoryPrivate
+
+class QtColorEditorFactoryPrivate : public EditorFactoryPrivate<QtColorEditWidget>
+{
+ QtColorEditorFactory *q_ptr;
+ Q_DECLARE_PUBLIC(QtColorEditorFactory)
+public:
+
+ void slotPropertyChanged(QtProperty *property, const QColor &value);
+ void slotSetValue(const QColor &value);
+};
+
+void QtColorEditorFactoryPrivate::slotPropertyChanged(QtProperty *property,
+ const QColor &value)
+{
+ const PropertyToEditorListMap::iterator it = m_createdEditors.find(property);
+ if (it == m_createdEditors.end())
+ return;
+ QListIterator<QtColorEditWidget *> itEditor(it.value());
+
+ while (itEditor.hasNext())
+ itEditor.next()->setValue(value);
+}
+
+void QtColorEditorFactoryPrivate::slotSetValue(const QColor &value)
+{
+ QObject *object = q_ptr->sender();
+ const EditorToPropertyMap::ConstIterator ecend = m_editorToProperty.constEnd();
+ for (EditorToPropertyMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
+ if (itEditor.key() == object) {
+ QtProperty *property = itEditor.value();
+ QtColorPropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+ manager->setValue(property, value);
+ return;
+ }
+}
+
+/*!
+ \class QtColorEditorFactory
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtColorEditorFactory class provides color editing for
+ properties created by QtColorPropertyManager objects.
+
+ \sa QtAbstractEditorFactory, QtColorPropertyManager
+*/
+
+/*!
+ Creates a factory with the given \a parent.
+*/
+QtColorEditorFactory::QtColorEditorFactory(QObject *parent) :
+ QtAbstractEditorFactory<QtColorPropertyManager>(parent),
+ d_ptr(new QtColorEditorFactoryPrivate())
+{
+ d_ptr->q_ptr = this;
+}
+
+/*!
+ Destroys this factory, and all the widgets it has created.
+*/
+QtColorEditorFactory::~QtColorEditorFactory()
+{
+ qDeleteAll(d_ptr->m_editorToProperty.keys());
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtColorEditorFactory::connectPropertyManager(QtColorPropertyManager *manager)
+{
+ connect(manager, SIGNAL(valueChanged(QtProperty*,QColor)),
+ this, SLOT(slotPropertyChanged(QtProperty*,QColor)));
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+QWidget *QtColorEditorFactory::createEditor(QtColorPropertyManager *manager,
+ QtProperty *property, QWidget *parent)
+{
+ QtColorEditWidget *editor = d_ptr->createEditor(property, parent);
+ editor->setValue(manager->value(property));
+ connect(editor, SIGNAL(valueChanged(QColor)), this, SLOT(slotSetValue(QColor)));
+ connect(editor, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*)));
+ return editor;
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtColorEditorFactory::disconnectPropertyManager(QtColorPropertyManager *manager)
+{
+ disconnect(manager, SIGNAL(valueChanged(QtProperty*,QColor)), this, SLOT(slotPropertyChanged(QtProperty*,QColor)));
+}
+
+// QtFontEditWidget
+
+class QtFontEditWidget : public QWidget {
+ Q_OBJECT
+
+public:
+ QtFontEditWidget(QWidget *parent);
+
+ bool eventFilter(QObject *obj, QEvent *ev);
+
+public Q_SLOTS:
+ void setValue(const QFont &value);
+
+private Q_SLOTS:
+ void buttonClicked();
+
+Q_SIGNALS:
+ void valueChanged(const QFont &value);
+
+private:
+ QFont m_font;
+ QLabel *m_pixmapLabel;
+ QLabel *m_label;
+ QToolButton *m_button;
+};
+
+QtFontEditWidget::QtFontEditWidget(QWidget *parent) :
+ QWidget(parent),
+ m_pixmapLabel(new QLabel),
+ m_label(new QLabel),
+ m_button(new QToolButton)
+{
+ QHBoxLayout *lt = new QHBoxLayout(this);
+ setupTreeViewEditorMargin(lt);
+ lt->setSpacing(0);
+ lt->addWidget(m_pixmapLabel);
+ lt->addWidget(m_label);
+ lt->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored));
+
+ m_button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored);
+ m_button->setFixedWidth(20);
+ setFocusProxy(m_button);
+ setFocusPolicy(m_button->focusPolicy());
+ m_button->setText(tr("..."));
+ m_button->installEventFilter(this);
+ connect(m_button, SIGNAL(clicked()), this, SLOT(buttonClicked()));
+ lt->addWidget(m_button);
+ m_pixmapLabel->setPixmap(QtPropertyBrowserUtils::fontValuePixmap(m_font));
+ m_label->setText(QtPropertyBrowserUtils::fontValueText(m_font));
+}
+
+void QtFontEditWidget::setValue(const QFont &f)
+{
+ if (m_font != f) {
+ m_font = f;
+ m_pixmapLabel->setPixmap(QtPropertyBrowserUtils::fontValuePixmap(f));
+ m_label->setText(QtPropertyBrowserUtils::fontValueText(f));
+ }
+}
+
+void QtFontEditWidget::buttonClicked()
+{
+ bool ok = false;
+ QFont newFont = QFontDialog::getFont(&ok, m_font, this, tr("Select Font"));
+ if (ok && newFont != m_font) {
+ QFont f = m_font;
+ // prevent mask for unchanged attributes, don't change other attributes (like kerning, etc...)
+ if (m_font.family() != newFont.family())
+ f.setFamily(newFont.family());
+ if (m_font.pointSize() != newFont.pointSize())
+ f.setPointSize(newFont.pointSize());
+ if (m_font.bold() != newFont.bold())
+ f.setBold(newFont.bold());
+ if (m_font.italic() != newFont.italic())
+ f.setItalic(newFont.italic());
+ if (m_font.underline() != newFont.underline())
+ f.setUnderline(newFont.underline());
+ if (m_font.strikeOut() != newFont.strikeOut())
+ f.setStrikeOut(newFont.strikeOut());
+ setValue(f);
+ emit valueChanged(m_font);
+ }
+}
+
+bool QtFontEditWidget::eventFilter(QObject *obj, QEvent *ev)
+{
+ if (obj == m_button) {
+ switch (ev->type()) {
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease: { // Prevent the QToolButton from handling Enter/Escape meant control the delegate
+ switch (static_cast<const QKeyEvent*>(ev)->key()) {
+ case Qt::Key_Escape:
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ ev->ignore();
+ return true;
+ default:
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ return QWidget::eventFilter(obj, ev);
+}
+
+// QtFontEditorFactoryPrivate
+
+class QtFontEditorFactoryPrivate : public EditorFactoryPrivate<QtFontEditWidget>
+{
+ QtFontEditorFactory *q_ptr;
+ Q_DECLARE_PUBLIC(QtFontEditorFactory)
+public:
+
+ void slotPropertyChanged(QtProperty *property, const QFont &value);
+ void slotSetValue(const QFont &value);
+};
+
+void QtFontEditorFactoryPrivate::slotPropertyChanged(QtProperty *property,
+ const QFont &value)
+{
+ const PropertyToEditorListMap::iterator it = m_createdEditors.find(property);
+ if (it == m_createdEditors.end())
+ return;
+ QListIterator<QtFontEditWidget *> itEditor(it.value());
+
+ while (itEditor.hasNext())
+ itEditor.next()->setValue(value);
+}
+
+void QtFontEditorFactoryPrivate::slotSetValue(const QFont &value)
+{
+ QObject *object = q_ptr->sender();
+ const EditorToPropertyMap::ConstIterator ecend = m_editorToProperty.constEnd();
+ for (EditorToPropertyMap::ConstIterator itEditor = m_editorToProperty.constBegin(); itEditor != ecend; ++itEditor)
+ if (itEditor.key() == object) {
+ QtProperty *property = itEditor.value();
+ QtFontPropertyManager *manager = q_ptr->propertyManager(property);
+ if (!manager)
+ return;
+ manager->setValue(property, value);
+ return;
+ }
+}
+
+/*!
+ \class QtFontEditorFactory
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtFontEditorFactory class provides font editing for
+ properties created by QtFontPropertyManager objects.
+
+ \sa QtAbstractEditorFactory, QtFontPropertyManager
+*/
+
+/*!
+ Creates a factory with the given \a parent.
+*/
+QtFontEditorFactory::QtFontEditorFactory(QObject *parent) :
+ QtAbstractEditorFactory<QtFontPropertyManager>(parent),
+ d_ptr(new QtFontEditorFactoryPrivate())
+{
+ d_ptr->q_ptr = this;
+}
+
+/*!
+ Destroys this factory, and all the widgets it has created.
+*/
+QtFontEditorFactory::~QtFontEditorFactory()
+{
+ qDeleteAll(d_ptr->m_editorToProperty.keys());
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtFontEditorFactory::connectPropertyManager(QtFontPropertyManager *manager)
+{
+ connect(manager, SIGNAL(valueChanged(QtProperty*,QFont)),
+ this, SLOT(slotPropertyChanged(QtProperty*,QFont)));
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+QWidget *QtFontEditorFactory::createEditor(QtFontPropertyManager *manager,
+ QtProperty *property, QWidget *parent)
+{
+ QtFontEditWidget *editor = d_ptr->createEditor(property, parent);
+ editor->setValue(manager->value(property));
+ connect(editor, SIGNAL(valueChanged(QFont)), this, SLOT(slotSetValue(QFont)));
+ connect(editor, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*)));
+ return editor;
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtFontEditorFactory::disconnectPropertyManager(QtFontPropertyManager *manager)
+{
+ disconnect(manager, SIGNAL(valueChanged(QtProperty*,QFont)), this, SLOT(slotPropertyChanged(QtProperty*,QFont)));
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qteditorfactory.cpp"
+#include "qteditorfactory.moc"
diff --git a/src/shared/qtpropertybrowser/qteditorfactory.h b/src/shared/qtpropertybrowser/qteditorfactory.h
new file mode 100644
index 000000000..95564f02b
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qteditorfactory.h
@@ -0,0 +1,397 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTEDITORFACTORY_H
+#define QTEDITORFACTORY_H
+
+#include "qtpropertymanager.h"
+
+QT_BEGIN_NAMESPACE
+
+class QtSpinBoxFactoryPrivate;
+
+class QtSpinBoxFactory : public QtAbstractEditorFactory<QtIntPropertyManager>
+{
+ Q_OBJECT
+public:
+ QtSpinBoxFactory(QObject *parent = 0);
+ ~QtSpinBoxFactory();
+protected:
+ void connectPropertyManager(QtIntPropertyManager *manager);
+ QWidget *createEditor(QtIntPropertyManager *manager, QtProperty *property,
+ QWidget *parent);
+ void disconnectPropertyManager(QtIntPropertyManager *manager);
+private:
+ QScopedPointer<QtSpinBoxFactoryPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtSpinBoxFactory)
+ Q_DISABLE_COPY(QtSpinBoxFactory)
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, int, int))
+ Q_PRIVATE_SLOT(d_func(), void slotSingleStepChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotSetValue(int))
+ Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
+};
+
+class QtSliderFactoryPrivate;
+
+class QtSliderFactory : public QtAbstractEditorFactory<QtIntPropertyManager>
+{
+ Q_OBJECT
+public:
+ QtSliderFactory(QObject *parent = 0);
+ ~QtSliderFactory();
+protected:
+ void connectPropertyManager(QtIntPropertyManager *manager);
+ QWidget *createEditor(QtIntPropertyManager *manager, QtProperty *property,
+ QWidget *parent);
+ void disconnectPropertyManager(QtIntPropertyManager *manager);
+private:
+ QScopedPointer<QtSliderFactoryPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtSliderFactory)
+ Q_DISABLE_COPY(QtSliderFactory)
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, int, int))
+ Q_PRIVATE_SLOT(d_func(), void slotSingleStepChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotSetValue(int))
+ Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
+};
+
+class QtScrollBarFactoryPrivate;
+
+class QtScrollBarFactory : public QtAbstractEditorFactory<QtIntPropertyManager>
+{
+ Q_OBJECT
+public:
+ QtScrollBarFactory(QObject *parent = 0);
+ ~QtScrollBarFactory();
+protected:
+ void connectPropertyManager(QtIntPropertyManager *manager);
+ QWidget *createEditor(QtIntPropertyManager *manager, QtProperty *property,
+ QWidget *parent);
+ void disconnectPropertyManager(QtIntPropertyManager *manager);
+private:
+ QScopedPointer<QtScrollBarFactoryPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtScrollBarFactory)
+ Q_DISABLE_COPY(QtScrollBarFactory)
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, int, int))
+ Q_PRIVATE_SLOT(d_func(), void slotSingleStepChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotSetValue(int))
+ Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
+};
+
+class QtCheckBoxFactoryPrivate;
+
+class QtCheckBoxFactory : public QtAbstractEditorFactory<QtBoolPropertyManager>
+{
+ Q_OBJECT
+public:
+ QtCheckBoxFactory(QObject *parent = 0);
+ ~QtCheckBoxFactory();
+protected:
+ void connectPropertyManager(QtBoolPropertyManager *manager);
+ QWidget *createEditor(QtBoolPropertyManager *manager, QtProperty *property,
+ QWidget *parent);
+ void disconnectPropertyManager(QtBoolPropertyManager *manager);
+private:
+ QScopedPointer<QtCheckBoxFactoryPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtCheckBoxFactory)
+ Q_DISABLE_COPY(QtCheckBoxFactory)
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, bool))
+ Q_PRIVATE_SLOT(d_func(), void slotSetValue(bool))
+ Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
+};
+
+class QtDoubleSpinBoxFactoryPrivate;
+
+class QtDoubleSpinBoxFactory : public QtAbstractEditorFactory<QtDoublePropertyManager>
+{
+ Q_OBJECT
+public:
+ QtDoubleSpinBoxFactory(QObject *parent = 0);
+ ~QtDoubleSpinBoxFactory();
+protected:
+ void connectPropertyManager(QtDoublePropertyManager *manager);
+ QWidget *createEditor(QtDoublePropertyManager *manager, QtProperty *property,
+ QWidget *parent);
+ void disconnectPropertyManager(QtDoublePropertyManager *manager);
+private:
+ QScopedPointer<QtDoubleSpinBoxFactoryPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtDoubleSpinBoxFactory)
+ Q_DISABLE_COPY(QtDoubleSpinBoxFactory)
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, double))
+ Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, double, double))
+ Q_PRIVATE_SLOT(d_func(), void slotSingleStepChanged(QtProperty *, double))
+ Q_PRIVATE_SLOT(d_func(), void slotDecimalsChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotSetValue(double))
+ Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
+};
+
+class QtLineEditFactoryPrivate;
+
+class QtLineEditFactory : public QtAbstractEditorFactory<QtStringPropertyManager>
+{
+ Q_OBJECT
+public:
+ QtLineEditFactory(QObject *parent = 0);
+ ~QtLineEditFactory();
+protected:
+ void connectPropertyManager(QtStringPropertyManager *manager);
+ QWidget *createEditor(QtStringPropertyManager *manager, QtProperty *property,
+ QWidget *parent);
+ void disconnectPropertyManager(QtStringPropertyManager *manager);
+private:
+ QScopedPointer<QtLineEditFactoryPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtLineEditFactory)
+ Q_DISABLE_COPY(QtLineEditFactory)
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QString &))
+ Q_PRIVATE_SLOT(d_func(), void slotRegExpChanged(QtProperty *, const QRegExp &))
+ Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QString &))
+ Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
+};
+
+class QtDateEditFactoryPrivate;
+
+class QtDateEditFactory : public QtAbstractEditorFactory<QtDatePropertyManager>
+{
+ Q_OBJECT
+public:
+ QtDateEditFactory(QObject *parent = 0);
+ ~QtDateEditFactory();
+protected:
+ void connectPropertyManager(QtDatePropertyManager *manager);
+ QWidget *createEditor(QtDatePropertyManager *manager, QtProperty *property,
+ QWidget *parent);
+ void disconnectPropertyManager(QtDatePropertyManager *manager);
+private:
+ QScopedPointer<QtDateEditFactoryPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtDateEditFactory)
+ Q_DISABLE_COPY(QtDateEditFactory)
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QDate &))
+ Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *,
+ const QDate &, const QDate &))
+ Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QDate &))
+ Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
+};
+
+class QtTimeEditFactoryPrivate;
+
+class QtTimeEditFactory : public QtAbstractEditorFactory<QtTimePropertyManager>
+{
+ Q_OBJECT
+public:
+ QtTimeEditFactory(QObject *parent = 0);
+ ~QtTimeEditFactory();
+protected:
+ void connectPropertyManager(QtTimePropertyManager *manager);
+ QWidget *createEditor(QtTimePropertyManager *manager, QtProperty *property,
+ QWidget *parent);
+ void disconnectPropertyManager(QtTimePropertyManager *manager);
+private:
+ QScopedPointer<QtTimeEditFactoryPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtTimeEditFactory)
+ Q_DISABLE_COPY(QtTimeEditFactory)
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QTime &))
+ Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QTime &))
+ Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
+};
+
+class QtDateTimeEditFactoryPrivate;
+
+class QtDateTimeEditFactory : public QtAbstractEditorFactory<QtDateTimePropertyManager>
+{
+ Q_OBJECT
+public:
+ QtDateTimeEditFactory(QObject *parent = 0);
+ ~QtDateTimeEditFactory();
+protected:
+ void connectPropertyManager(QtDateTimePropertyManager *manager);
+ QWidget *createEditor(QtDateTimePropertyManager *manager, QtProperty *property,
+ QWidget *parent);
+ void disconnectPropertyManager(QtDateTimePropertyManager *manager);
+private:
+ QScopedPointer<QtDateTimeEditFactoryPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtDateTimeEditFactory)
+ Q_DISABLE_COPY(QtDateTimeEditFactory)
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QDateTime &))
+ Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QDateTime &))
+ Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
+};
+
+class QtKeySequenceEditorFactoryPrivate;
+
+class QtKeySequenceEditorFactory : public QtAbstractEditorFactory<QtKeySequencePropertyManager>
+{
+ Q_OBJECT
+public:
+ QtKeySequenceEditorFactory(QObject *parent = 0);
+ ~QtKeySequenceEditorFactory();
+protected:
+ void connectPropertyManager(QtKeySequencePropertyManager *manager);
+ QWidget *createEditor(QtKeySequencePropertyManager *manager, QtProperty *property,
+ QWidget *parent);
+ void disconnectPropertyManager(QtKeySequencePropertyManager *manager);
+private:
+ QScopedPointer<QtKeySequenceEditorFactoryPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtKeySequenceEditorFactory)
+ Q_DISABLE_COPY(QtKeySequenceEditorFactory)
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QKeySequence &))
+ Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QKeySequence &))
+ Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
+};
+
+class QtCharEditorFactoryPrivate;
+
+class QtCharEditorFactory : public QtAbstractEditorFactory<QtCharPropertyManager>
+{
+ Q_OBJECT
+public:
+ QtCharEditorFactory(QObject *parent = 0);
+ ~QtCharEditorFactory();
+protected:
+ void connectPropertyManager(QtCharPropertyManager *manager);
+ QWidget *createEditor(QtCharPropertyManager *manager, QtProperty *property,
+ QWidget *parent);
+ void disconnectPropertyManager(QtCharPropertyManager *manager);
+private:
+ QScopedPointer<QtCharEditorFactoryPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtCharEditorFactory)
+ Q_DISABLE_COPY(QtCharEditorFactory)
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QChar &))
+ Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QChar &))
+ Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
+};
+
+class QtEnumEditorFactoryPrivate;
+
+class QtEnumEditorFactory : public QtAbstractEditorFactory<QtEnumPropertyManager>
+{
+ Q_OBJECT
+public:
+ QtEnumEditorFactory(QObject *parent = 0);
+ ~QtEnumEditorFactory();
+protected:
+ void connectPropertyManager(QtEnumPropertyManager *manager);
+ QWidget *createEditor(QtEnumPropertyManager *manager, QtProperty *property,
+ QWidget *parent);
+ void disconnectPropertyManager(QtEnumPropertyManager *manager);
+private:
+ QScopedPointer<QtEnumEditorFactoryPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtEnumEditorFactory)
+ Q_DISABLE_COPY(QtEnumEditorFactory)
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotEnumNamesChanged(QtProperty *,
+ const QStringList &))
+ Q_PRIVATE_SLOT(d_func(), void slotEnumIconsChanged(QtProperty *,
+ const QMap<int, QIcon> &))
+ Q_PRIVATE_SLOT(d_func(), void slotSetValue(int))
+ Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
+};
+
+class QtCursorEditorFactoryPrivate;
+
+class QtCursorEditorFactory : public QtAbstractEditorFactory<QtCursorPropertyManager>
+{
+ Q_OBJECT
+public:
+ QtCursorEditorFactory(QObject *parent = 0);
+ ~QtCursorEditorFactory();
+protected:
+ void connectPropertyManager(QtCursorPropertyManager *manager);
+ QWidget *createEditor(QtCursorPropertyManager *manager, QtProperty *property,
+ QWidget *parent);
+ void disconnectPropertyManager(QtCursorPropertyManager *manager);
+private:
+ QScopedPointer<QtCursorEditorFactoryPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtCursorEditorFactory)
+ Q_DISABLE_COPY(QtCursorEditorFactory)
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QCursor &))
+ Q_PRIVATE_SLOT(d_func(), void slotEnumChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
+};
+
+class QtColorEditorFactoryPrivate;
+
+class QtColorEditorFactory : public QtAbstractEditorFactory<QtColorPropertyManager>
+{
+ Q_OBJECT
+public:
+ QtColorEditorFactory(QObject *parent = 0);
+ ~QtColorEditorFactory();
+protected:
+ void connectPropertyManager(QtColorPropertyManager *manager);
+ QWidget *createEditor(QtColorPropertyManager *manager, QtProperty *property,
+ QWidget *parent);
+ void disconnectPropertyManager(QtColorPropertyManager *manager);
+private:
+ QScopedPointer<QtColorEditorFactoryPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtColorEditorFactory)
+ Q_DISABLE_COPY(QtColorEditorFactory)
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QColor &))
+ Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
+ Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QColor &))
+};
+
+class QtFontEditorFactoryPrivate;
+
+class QtFontEditorFactory : public QtAbstractEditorFactory<QtFontPropertyManager>
+{
+ Q_OBJECT
+public:
+ QtFontEditorFactory(QObject *parent = 0);
+ ~QtFontEditorFactory();
+protected:
+ void connectPropertyManager(QtFontPropertyManager *manager);
+ QWidget *createEditor(QtFontPropertyManager *manager, QtProperty *property,
+ QWidget *parent);
+ void disconnectPropertyManager(QtFontPropertyManager *manager);
+private:
+ QScopedPointer<QtFontEditorFactoryPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtFontEditorFactory)
+ Q_DISABLE_COPY(QtFontEditorFactory)
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QFont &))
+ Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed(QObject *))
+ Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QFont &))
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtpropertybrowser/qtgroupboxpropertybrowser.cpp b/src/shared/qtpropertybrowser/qtgroupboxpropertybrowser.cpp
new file mode 100644
index 000000000..0633aa4f6
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qtgroupboxpropertybrowser.cpp
@@ -0,0 +1,529 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtgroupboxpropertybrowser.h"
+#include <QtCore/QSet>
+#include <QtGui/QGridLayout>
+#include <QtGui/QLabel>
+#include <QtGui/QGroupBox>
+#include <QtCore/QTimer>
+#include <QtCore/QMap>
+
+QT_BEGIN_NAMESPACE
+
+class QtGroupBoxPropertyBrowserPrivate
+{
+ QtGroupBoxPropertyBrowser *q_ptr;
+ Q_DECLARE_PUBLIC(QtGroupBoxPropertyBrowser)
+public:
+
+ void init(QWidget *parent);
+
+ void propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex);
+ void propertyRemoved(QtBrowserItem *index);
+ void propertyChanged(QtBrowserItem *index);
+ QWidget *createEditor(QtProperty *property, QWidget *parent) const
+ { return q_ptr->createEditor(property, parent); }
+
+ void slotEditorDestroyed();
+ void slotUpdate();
+
+ struct WidgetItem
+ {
+ WidgetItem() : widget(0), label(0), widgetLabel(0),
+ groupBox(0), layout(0), line(0), parent(0) { }
+ QWidget *widget; // can be null
+ QLabel *label;
+ QLabel *widgetLabel;
+ QGroupBox *groupBox;
+ QGridLayout *layout;
+ QFrame *line;
+ WidgetItem *parent;
+ QList<WidgetItem *> children;
+ };
+private:
+ void updateLater();
+ void updateItem(WidgetItem *item);
+ void insertRow(QGridLayout *layout, int row) const;
+ void removeRow(QGridLayout *layout, int row) const;
+
+ bool hasHeader(WidgetItem *item) const;
+
+ QMap<QtBrowserItem *, WidgetItem *> m_indexToItem;
+ QMap<WidgetItem *, QtBrowserItem *> m_itemToIndex;
+ QMap<QWidget *, WidgetItem *> m_widgetToItem;
+ QGridLayout *m_mainLayout;
+ QList<WidgetItem *> m_children;
+ QList<WidgetItem *> m_recreateQueue;
+};
+
+void QtGroupBoxPropertyBrowserPrivate::init(QWidget *parent)
+{
+ m_mainLayout = new QGridLayout();
+ parent->setLayout(m_mainLayout);
+ QLayoutItem *item = new QSpacerItem(0, 0,
+ QSizePolicy::Fixed, QSizePolicy::Expanding);
+ m_mainLayout->addItem(item, 0, 0);
+}
+
+void QtGroupBoxPropertyBrowserPrivate::slotEditorDestroyed()
+{
+ QWidget *editor = qobject_cast<QWidget *>(q_ptr->sender());
+ if (!editor)
+ return;
+ if (!m_widgetToItem.contains(editor))
+ return;
+ m_widgetToItem[editor]->widget = 0;
+ m_widgetToItem.remove(editor);
+}
+
+void QtGroupBoxPropertyBrowserPrivate::slotUpdate()
+{
+ QListIterator<WidgetItem *> itItem(m_recreateQueue);
+ while (itItem.hasNext()) {
+ WidgetItem *item = itItem.next();
+
+ WidgetItem *par = item->parent;
+ QWidget *w = 0;
+ QGridLayout *l = 0;
+ int oldRow = -1;
+ if (!par) {
+ w = q_ptr;
+ l = m_mainLayout;
+ oldRow = m_children.indexOf(item);
+ } else {
+ w = par->groupBox;
+ l = par->layout;
+ oldRow = par->children.indexOf(item);
+ if (hasHeader(par))
+ oldRow += 2;
+ }
+
+ if (item->widget) {
+ item->widget->setParent(w);
+ } else if (item->widgetLabel) {
+ item->widgetLabel->setParent(w);
+ } else {
+ item->widgetLabel = new QLabel(w);
+ }
+ int span = 1;
+ if (item->widget)
+ l->addWidget(item->widget, oldRow, 1, 1, 1);
+ else if (item->widgetLabel)
+ l->addWidget(item->widgetLabel, oldRow, 1, 1, 1);
+ else
+ span = 2;
+ item->label = new QLabel(w);
+ item->label->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
+ l->addWidget(item->label, oldRow, 0, 1, span);
+
+ updateItem(item);
+ }
+ m_recreateQueue.clear();
+}
+
+void QtGroupBoxPropertyBrowserPrivate::updateLater()
+{
+ QTimer::singleShot(0, q_ptr, SLOT(slotUpdate()));
+}
+
+void QtGroupBoxPropertyBrowserPrivate::propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex)
+{
+ WidgetItem *afterItem = m_indexToItem.value(afterIndex);
+ WidgetItem *parentItem = m_indexToItem.value(index->parent());
+
+ WidgetItem *newItem = new WidgetItem();
+ newItem->parent = parentItem;
+
+ QGridLayout *layout = 0;
+ QWidget *parentWidget = 0;
+ int row = -1;
+ if (!afterItem) {
+ row = 0;
+ if (parentItem)
+ parentItem->children.insert(0, newItem);
+ else
+ m_children.insert(0, newItem);
+ } else {
+ if (parentItem) {
+ row = parentItem->children.indexOf(afterItem) + 1;
+ parentItem->children.insert(row, newItem);
+ } else {
+ row = m_children.indexOf(afterItem) + 1;
+ m_children.insert(row, newItem);
+ }
+ }
+ if (parentItem && hasHeader(parentItem))
+ row += 2;
+
+ if (!parentItem) {
+ layout = m_mainLayout;
+ parentWidget = q_ptr;;
+ } else {
+ if (!parentItem->groupBox) {
+ m_recreateQueue.removeAll(parentItem);
+ WidgetItem *par = parentItem->parent;
+ QWidget *w = 0;
+ QGridLayout *l = 0;
+ int oldRow = -1;
+ if (!par) {
+ w = q_ptr;
+ l = m_mainLayout;
+ oldRow = m_children.indexOf(parentItem);
+ } else {
+ w = par->groupBox;
+ l = par->layout;
+ oldRow = par->children.indexOf(parentItem);
+ if (hasHeader(par))
+ oldRow += 2;
+ }
+ parentItem->groupBox = new QGroupBox(w);
+ parentItem->layout = new QGridLayout();
+ parentItem->groupBox->setLayout(parentItem->layout);
+ if (parentItem->label) {
+ l->removeWidget(parentItem->label);
+ delete parentItem->label;
+ parentItem->label = 0;
+ }
+ if (parentItem->widget) {
+ l->removeWidget(parentItem->widget);
+ parentItem->widget->setParent(parentItem->groupBox);
+ parentItem->layout->addWidget(parentItem->widget, 0, 0, 1, 2);
+ parentItem->line = new QFrame(parentItem->groupBox);
+ } else if (parentItem->widgetLabel) {
+ l->removeWidget(parentItem->widgetLabel);
+ delete parentItem->widgetLabel;
+ parentItem->widgetLabel = 0;
+ }
+ if (parentItem->line) {
+ parentItem->line->setFrameShape(QFrame::HLine);
+ parentItem->line->setFrameShadow(QFrame::Sunken);
+ parentItem->layout->addWidget(parentItem->line, 1, 0, 1, 2);
+ }
+ l->addWidget(parentItem->groupBox, oldRow, 0, 1, 2);
+ updateItem(parentItem);
+ }
+ layout = parentItem->layout;
+ parentWidget = parentItem->groupBox;
+ }
+
+ newItem->label = new QLabel(parentWidget);
+ newItem->label->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
+ newItem->widget = createEditor(index->property(), parentWidget);
+ if (!newItem->widget) {
+ newItem->widgetLabel = new QLabel(parentWidget);
+ } else {
+ QObject::connect(newItem->widget, SIGNAL(destroyed()), q_ptr, SLOT(slotEditorDestroyed()));
+ m_widgetToItem[newItem->widget] = newItem;
+ }
+
+ insertRow(layout, row);
+ int span = 1;
+ if (newItem->widget)
+ layout->addWidget(newItem->widget, row, 1);
+ else if (newItem->widgetLabel)
+ layout->addWidget(newItem->widgetLabel, row, 1);
+ else
+ span = 2;
+ layout->addWidget(newItem->label, row, 0, 1, span);
+
+ m_itemToIndex[newItem] = index;
+ m_indexToItem[index] = newItem;
+
+ updateItem(newItem);
+}
+
+void QtGroupBoxPropertyBrowserPrivate::propertyRemoved(QtBrowserItem *index)
+{
+ WidgetItem *item = m_indexToItem.value(index);
+
+ m_indexToItem.remove(index);
+ m_itemToIndex.remove(item);
+
+ WidgetItem *parentItem = item->parent;
+
+ int row = -1;
+
+ if (parentItem) {
+ row = parentItem->children.indexOf(item);
+ parentItem->children.removeAt(row);
+ if (hasHeader(parentItem))
+ row += 2;
+ } else {
+ row = m_children.indexOf(item);
+ m_children.removeAt(row);
+ }
+
+ if (item->widget)
+ delete item->widget;
+ if (item->label)
+ delete item->label;
+ if (item->widgetLabel)
+ delete item->widgetLabel;
+ if (item->groupBox)
+ delete item->groupBox;
+
+ if (!parentItem) {
+ removeRow(m_mainLayout, row);
+ } else if (parentItem->children.count() != 0) {
+ removeRow(parentItem->layout, row);
+ } else {
+ WidgetItem *par = parentItem->parent;
+ QWidget *w = 0;
+ QGridLayout *l = 0;
+ int oldRow = -1;
+ if (!par) {
+ w = q_ptr;
+ l = m_mainLayout;
+ oldRow = m_children.indexOf(parentItem);
+ } else {
+ w = par->groupBox;
+ l = par->layout;
+ oldRow = par->children.indexOf(parentItem);
+ if (hasHeader(par))
+ oldRow += 2;
+ }
+
+ if (parentItem->widget) {
+ parentItem->widget->hide();
+ parentItem->widget->setParent(0);
+ } else if (parentItem->widgetLabel) {
+ parentItem->widgetLabel->hide();
+ parentItem->widgetLabel->setParent(0);
+ } else {
+ //parentItem->widgetLabel = new QLabel(w);
+ }
+ l->removeWidget(parentItem->groupBox);
+ delete parentItem->groupBox;
+ parentItem->groupBox = 0;
+ parentItem->line = 0;
+ parentItem->layout = 0;
+ if (!m_recreateQueue.contains(parentItem))
+ m_recreateQueue.append(parentItem);
+ updateLater();
+ }
+ m_recreateQueue.removeAll(item);
+
+ delete item;
+}
+
+void QtGroupBoxPropertyBrowserPrivate::insertRow(QGridLayout *layout, int row) const
+{
+ QMap<QLayoutItem *, QRect> itemToPos;
+ int idx = 0;
+ while (idx < layout->count()) {
+ int r, c, rs, cs;
+ layout->getItemPosition(idx, &r, &c, &rs, &cs);
+ if (r >= row) {
+ itemToPos[layout->takeAt(idx)] = QRect(r + 1, c, rs, cs);
+ } else {
+ idx++;
+ }
+ }
+
+ const QMap<QLayoutItem *, QRect>::ConstIterator icend = itemToPos.constEnd();
+ for (QMap<QLayoutItem *, QRect>::ConstIterator it = itemToPos.constBegin(); it != icend; ++it) {
+ const QRect r = it.value();
+ layout->addItem(it.key(), r.x(), r.y(), r.width(), r.height());
+ }
+}
+
+void QtGroupBoxPropertyBrowserPrivate::removeRow(QGridLayout *layout, int row) const
+{
+ QMap<QLayoutItem *, QRect> itemToPos;
+ int idx = 0;
+ while (idx < layout->count()) {
+ int r, c, rs, cs;
+ layout->getItemPosition(idx, &r, &c, &rs, &cs);
+ if (r > row) {
+ itemToPos[layout->takeAt(idx)] = QRect(r - 1, c, rs, cs);
+ } else {
+ idx++;
+ }
+ }
+
+ const QMap<QLayoutItem *, QRect>::ConstIterator icend = itemToPos.constEnd();
+ for (QMap<QLayoutItem *, QRect>::ConstIterator it = itemToPos.constBegin(); it != icend; ++it) {
+ const QRect r = it.value();
+ layout->addItem(it.key(), r.x(), r.y(), r.width(), r.height());
+ }
+}
+
+bool QtGroupBoxPropertyBrowserPrivate::hasHeader(WidgetItem *item) const
+{
+ if (item->widget)
+ return true;
+ return false;
+}
+
+void QtGroupBoxPropertyBrowserPrivate::propertyChanged(QtBrowserItem *index)
+{
+ WidgetItem *item = m_indexToItem.value(index);
+
+ updateItem(item);
+}
+
+void QtGroupBoxPropertyBrowserPrivate::updateItem(WidgetItem *item)
+{
+ QtProperty *property = m_itemToIndex[item]->property();
+ if (item->groupBox) {
+ QFont font = item->groupBox->font();
+ font.setUnderline(property->isModified());
+ item->groupBox->setFont(font);
+ item->groupBox->setTitle(property->propertyName());
+ item->groupBox->setToolTip(property->toolTip());
+ item->groupBox->setStatusTip(property->statusTip());
+ item->groupBox->setWhatsThis(property->whatsThis());
+ item->groupBox->setEnabled(property->isEnabled());
+ }
+ if (item->label) {
+ QFont font = item->label->font();
+ font.setUnderline(property->isModified());
+ item->label->setFont(font);
+ item->label->setText(property->propertyName());
+ item->label->setToolTip(property->toolTip());
+ item->label->setStatusTip(property->statusTip());
+ item->label->setWhatsThis(property->whatsThis());
+ item->label->setEnabled(property->isEnabled());
+ }
+ if (item->widgetLabel) {
+ QFont font = item->widgetLabel->font();
+ font.setUnderline(false);
+ item->widgetLabel->setFont(font);
+ item->widgetLabel->setText(property->valueText());
+ item->widgetLabel->setEnabled(property->isEnabled());
+ }
+ if (item->widget) {
+ QFont font = item->widget->font();
+ font.setUnderline(false);
+ item->widget->setFont(font);
+ item->widget->setEnabled(property->isEnabled());
+ item->widget->setToolTip(property->valueText());
+ }
+ //item->setIcon(1, property->valueIcon());
+}
+
+
+
+/*!
+ \class QtGroupBoxPropertyBrowser
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtGroupBoxPropertyBrowser class provides a QGroupBox
+ based property browser.
+
+ A property browser is a widget that enables the user to edit a
+ given set of properties. Each property is represented by a label
+ specifying the property's name, and an editing widget (e.g. a line
+ edit or a combobox) holding its value. A property can have zero or
+ more subproperties.
+
+ QtGroupBoxPropertyBrowser provides group boxes for all nested
+ properties, i.e. subproperties are enclosed by a group box with
+ the parent property's name as its title. For example:
+
+ \image qtgroupboxpropertybrowser.png
+
+ Use the QtAbstractPropertyBrowser API to add, insert and remove
+ properties from an instance of the QtGroupBoxPropertyBrowser
+ class. The properties themselves are created and managed by
+ implementations of the QtAbstractPropertyManager class.
+
+ \sa QtTreePropertyBrowser, QtAbstractPropertyBrowser
+*/
+
+/*!
+ Creates a property browser with the given \a parent.
+*/
+QtGroupBoxPropertyBrowser::QtGroupBoxPropertyBrowser(QWidget *parent)
+ : QtAbstractPropertyBrowser(parent), d_ptr(new QtGroupBoxPropertyBrowserPrivate)
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->init(this);
+}
+
+/*!
+ Destroys this property browser.
+
+ Note that the properties that were inserted into this browser are
+ \e not destroyed since they may still be used in other
+ browsers. The properties are owned by the manager that created
+ them.
+
+ \sa QtProperty, QtAbstractPropertyManager
+*/
+QtGroupBoxPropertyBrowser::~QtGroupBoxPropertyBrowser()
+{
+ const QMap<QtGroupBoxPropertyBrowserPrivate::WidgetItem *, QtBrowserItem *>::ConstIterator icend = d_ptr->m_itemToIndex.constEnd();
+ for (QMap<QtGroupBoxPropertyBrowserPrivate::WidgetItem *, QtBrowserItem *>::ConstIterator it = d_ptr->m_itemToIndex.constBegin(); it != icend; ++it)
+ delete it.key();
+}
+
+/*!
+ \reimp
+*/
+void QtGroupBoxPropertyBrowser::itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem)
+{
+ d_ptr->propertyInserted(item, afterItem);
+}
+
+/*!
+ \reimp
+*/
+void QtGroupBoxPropertyBrowser::itemRemoved(QtBrowserItem *item)
+{
+ d_ptr->propertyRemoved(item);
+}
+
+/*!
+ \reimp
+*/
+void QtGroupBoxPropertyBrowser::itemChanged(QtBrowserItem *item)
+{
+ d_ptr->propertyChanged(item);
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qtgroupboxpropertybrowser.cpp"
diff --git a/src/shared/qtpropertybrowser/qtgroupboxpropertybrowser.h b/src/shared/qtpropertybrowser/qtgroupboxpropertybrowser.h
new file mode 100644
index 000000000..d53d9492d
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qtgroupboxpropertybrowser.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTGROUPBOXPROPERTYBROWSER_H
+#define QTGROUPBOXPROPERTYBROWSER_H
+
+#include "qtpropertybrowser.h"
+
+QT_BEGIN_NAMESPACE
+
+class QtGroupBoxPropertyBrowserPrivate;
+
+class QtGroupBoxPropertyBrowser : public QtAbstractPropertyBrowser
+{
+ Q_OBJECT
+public:
+
+ QtGroupBoxPropertyBrowser(QWidget *parent = 0);
+ ~QtGroupBoxPropertyBrowser();
+
+protected:
+ virtual void itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem);
+ virtual void itemRemoved(QtBrowserItem *item);
+ virtual void itemChanged(QtBrowserItem *item);
+
+private:
+
+ QScopedPointer<QtGroupBoxPropertyBrowserPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtGroupBoxPropertyBrowser)
+ Q_DISABLE_COPY(QtGroupBoxPropertyBrowser)
+ Q_PRIVATE_SLOT(d_func(), void slotUpdate())
+ Q_PRIVATE_SLOT(d_func(), void slotEditorDestroyed())
+
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtpropertybrowser/qtpropertybrowser.cpp b/src/shared/qtpropertybrowser/qtpropertybrowser.cpp
new file mode 100644
index 000000000..3771ef686
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qtpropertybrowser.cpp
@@ -0,0 +1,1955 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtpropertybrowser.h"
+#include <QtCore/QSet>
+#include <QtCore/QMap>
+#include <QtGui/QIcon>
+
+#if defined(Q_CC_MSVC)
+# pragma warning(disable: 4786) /* MS VS 6: truncating debug info after 255 characters */
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QtPropertyPrivate
+{
+public:
+ QtPropertyPrivate(QtAbstractPropertyManager *manager) : m_enabled(true), m_modified(false), m_manager(manager) {}
+ QtProperty *q_ptr;
+
+ QSet<QtProperty *> m_parentItems;
+ QList<QtProperty *> m_subItems;
+
+ QString m_toolTip;
+ QString m_statusTip;
+ QString m_whatsThis;
+ QString m_name;
+ bool m_enabled;
+ bool m_modified;
+
+ QtAbstractPropertyManager * const m_manager;
+};
+
+class QtAbstractPropertyManagerPrivate
+{
+ QtAbstractPropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtAbstractPropertyManager)
+public:
+ void propertyDestroyed(QtProperty *property);
+ void propertyChanged(QtProperty *property) const;
+ void propertyRemoved(QtProperty *property,
+ QtProperty *parentProperty) const;
+ void propertyInserted(QtProperty *property, QtProperty *parentProperty,
+ QtProperty *afterProperty) const;
+
+ QSet<QtProperty *> m_properties;
+};
+
+/*!
+ \class QtProperty
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtProperty class encapsulates an instance of a property.
+
+ Properties are created by objects of QtAbstractPropertyManager
+ subclasses; a manager can create properties of a given type, and
+ is used in conjunction with the QtAbstractPropertyBrowser class. A
+ property is always owned by the manager that created it, which can
+ be retrieved using the propertyManager() function.
+
+ QtProperty contains the most common property attributes, and
+ provides functions for retrieving as well as setting their values:
+
+ \table
+ \header \o Getter \o Setter
+ \row
+ \o propertyName() \o setPropertyName()
+ \row
+ \o statusTip() \o setStatusTip()
+ \row
+ \o toolTip() \o setToolTip()
+ \row
+ \o whatsThis() \o setWhatsThis()
+ \row
+ \o isEnabled() \o setEnabled()
+ \row
+ \o isModified() \o setModified()
+ \row
+ \o valueText() \o Nop
+ \row
+ \o valueIcon() \o Nop
+ \endtable
+
+ It is also possible to nest properties: QtProperty provides the
+ addSubProperty(), insertSubProperty() and removeSubProperty() functions to
+ manipulate the set of subproperties. Use the subProperties()
+ function to retrieve a property's current set of subproperties.
+ Note that nested properties are not owned by the parent property,
+ i.e. each subproperty is owned by the manager that created it.
+
+ \sa QtAbstractPropertyManager, QtBrowserItem
+*/
+
+/*!
+ Creates a property with the given \a manager.
+
+ This constructor is only useful when creating a custom QtProperty
+ subclass (e.g. QtVariantProperty). To create a regular QtProperty
+ object, use the QtAbstractPropertyManager::addProperty()
+ function instead.
+
+ \sa QtAbstractPropertyManager::addProperty()
+*/
+QtProperty::QtProperty(QtAbstractPropertyManager *manager)
+ : d_ptr(new QtPropertyPrivate(manager))
+{
+ d_ptr->q_ptr = this;
+}
+
+/*!
+ Destroys this property.
+
+ Note that subproperties are detached but not destroyed, i.e. they
+ can still be used in another context.
+
+ \sa QtAbstractPropertyManager::clear()
+
+*/
+QtProperty::~QtProperty()
+{
+ QSetIterator<QtProperty *> itParent(d_ptr->m_parentItems);
+ while (itParent.hasNext()) {
+ QtProperty *property = itParent.next();
+ property->d_ptr->m_manager->d_ptr->propertyRemoved(this, property);
+ }
+
+ d_ptr->m_manager->d_ptr->propertyDestroyed(this);
+
+ QListIterator<QtProperty *> itChild(d_ptr->m_subItems);
+ while (itChild.hasNext()) {
+ QtProperty *property = itChild.next();
+ property->d_ptr->m_parentItems.remove(this);
+ }
+
+ itParent.toFront();
+ while (itParent.hasNext()) {
+ QtProperty *property = itParent.next();
+ property->d_ptr->m_subItems.removeAll(this);
+ }
+}
+
+/*!
+ Returns the set of subproperties.
+
+ Note that subproperties are not owned by \e this property, but by
+ the manager that created them.
+
+ \sa insertSubProperty(), removeSubProperty()
+*/
+QList<QtProperty *> QtProperty::subProperties() const
+{
+ return d_ptr->m_subItems;
+}
+
+/*!
+ Returns a pointer to the manager that owns this property.
+*/
+QtAbstractPropertyManager *QtProperty::propertyManager() const
+{
+ return d_ptr->m_manager;
+}
+
+/*!
+ Returns the property's tool tip.
+
+ \sa setToolTip()
+*/
+QString QtProperty::toolTip() const
+{
+ return d_ptr->m_toolTip;
+}
+
+/*!
+ Returns the property's status tip.
+
+ \sa setStatusTip()
+*/
+QString QtProperty::statusTip() const
+{
+ return d_ptr->m_statusTip;
+}
+
+/*!
+ Returns the property's "What's This" help text.
+
+ \sa setWhatsThis()
+*/
+QString QtProperty::whatsThis() const
+{
+ return d_ptr->m_whatsThis;
+}
+
+/*!
+ Returns the property's name.
+
+ \sa setPropertyName()
+*/
+QString QtProperty::propertyName() const
+{
+ return d_ptr->m_name;
+}
+
+/*!
+ Returns whether the property is enabled.
+
+ \sa setEnabled()
+*/
+bool QtProperty::isEnabled() const
+{
+ return d_ptr->m_enabled;
+}
+
+/*!
+ Returns whether the property is modified.
+
+ \sa setModified()
+*/
+bool QtProperty::isModified() const
+{
+ return d_ptr->m_modified;
+}
+
+/*!
+ Returns whether the property has a value.
+
+ \sa QtAbstractPropertyManager::hasValue()
+*/
+bool QtProperty::hasValue() const
+{
+ return d_ptr->m_manager->hasValue(this);
+}
+
+/*!
+ Returns an icon representing the current state of this property.
+
+ If the given property type can not generate such an icon, this
+ function returns an invalid icon.
+
+ \sa QtAbstractPropertyManager::valueIcon()
+*/
+QIcon QtProperty::valueIcon() const
+{
+ return d_ptr->m_manager->valueIcon(this);
+}
+
+/*!
+ Returns a string representing the current state of this property.
+
+ If the given property type can not generate such a string, this
+ function returns an empty string.
+
+ \sa QtAbstractPropertyManager::valueText()
+*/
+QString QtProperty::valueText() const
+{
+ return d_ptr->m_manager->valueText(this);
+}
+
+/*!
+ Sets the property's tool tip to the given \a text.
+
+ \sa toolTip()
+*/
+void QtProperty::setToolTip(const QString &text)
+{
+ if (d_ptr->m_toolTip == text)
+ return;
+
+ d_ptr->m_toolTip = text;
+ propertyChanged();
+}
+
+/*!
+ Sets the property's status tip to the given \a text.
+
+ \sa statusTip()
+*/
+void QtProperty::setStatusTip(const QString &text)
+{
+ if (d_ptr->m_statusTip == text)
+ return;
+
+ d_ptr->m_statusTip = text;
+ propertyChanged();
+}
+
+/*!
+ Sets the property's "What's This" help text to the given \a text.
+
+ \sa whatsThis()
+*/
+void QtProperty::setWhatsThis(const QString &text)
+{
+ if (d_ptr->m_whatsThis == text)
+ return;
+
+ d_ptr->m_whatsThis = text;
+ propertyChanged();
+}
+
+/*!
+ \fn void QtProperty::setPropertyName(const QString &name)
+
+ Sets the property's name to the given \a name.
+
+ \sa propertyName()
+*/
+void QtProperty::setPropertyName(const QString &text)
+{
+ if (d_ptr->m_name == text)
+ return;
+
+ d_ptr->m_name = text;
+ propertyChanged();
+}
+
+/*!
+ Enables or disables the property according to the passed \a enable value.
+
+ \sa isEnabled()
+*/
+void QtProperty::setEnabled(bool enable)
+{
+ if (d_ptr->m_enabled == enable)
+ return;
+
+ d_ptr->m_enabled = enable;
+ propertyChanged();
+}
+
+/*!
+ Sets the property's modified state according to the passed \a modified value.
+
+ \sa isModified()
+*/
+void QtProperty::setModified(bool modified)
+{
+ if (d_ptr->m_modified == modified)
+ return;
+
+ d_ptr->m_modified = modified;
+ propertyChanged();
+}
+
+/*!
+ Appends the given \a property to this property's subproperties.
+
+ If the given \a property already is added, this function does
+ nothing.
+
+ \sa insertSubProperty(), removeSubProperty()
+*/
+void QtProperty::addSubProperty(QtProperty *property)
+{
+ QtProperty *after = 0;
+ if (d_ptr->m_subItems.count() > 0)
+ after = d_ptr->m_subItems.last();
+ insertSubProperty(property, after);
+}
+
+/*!
+ \fn void QtProperty::insertSubProperty(QtProperty *property, QtProperty *precedingProperty)
+
+ Inserts the given \a property after the specified \a
+ precedingProperty into this property's list of subproperties. If
+ \a precedingProperty is 0, the specified \a property is inserted
+ at the beginning of the list.
+
+ If the given \a property already is inserted, this function does
+ nothing.
+
+ \sa addSubProperty(), removeSubProperty()
+*/
+void QtProperty::insertSubProperty(QtProperty *property,
+ QtProperty *afterProperty)
+{
+ if (!property)
+ return;
+
+ if (property == this)
+ return;
+
+ // traverse all children of item. if this item is a child of item then cannot add.
+ QList<QtProperty *> pendingList = property->subProperties();
+ QMap<QtProperty *, bool> visited;
+ while (!pendingList.isEmpty()) {
+ QtProperty *i = pendingList.first();
+ if (i == this)
+ return;
+ pendingList.removeFirst();
+ if (visited.contains(i))
+ continue;
+ visited[i] = true;
+ pendingList += i->subProperties();
+ }
+
+ pendingList = subProperties();
+ int pos = 0;
+ int newPos = 0;
+ QtProperty *properAfterProperty = 0;
+ while (pos < pendingList.count()) {
+ QtProperty *i = pendingList.at(pos);
+ if (i == property)
+ return; // if item is already inserted in this item then cannot add.
+ if (i == afterProperty) {
+ newPos = pos + 1;
+ properAfterProperty = afterProperty;
+ }
+ pos++;
+ }
+
+ d_ptr->m_subItems.insert(newPos, property);
+ property->d_ptr->m_parentItems.insert(this);
+
+ d_ptr->m_manager->d_ptr->propertyInserted(property, this, properAfterProperty);
+}
+
+/*!
+ Removes the given \a property from the list of subproperties
+ without deleting it.
+
+ \sa addSubProperty(), insertSubProperty()
+*/
+void QtProperty::removeSubProperty(QtProperty *property)
+{
+ if (!property)
+ return;
+
+ d_ptr->m_manager->d_ptr->propertyRemoved(property, this);
+
+ QList<QtProperty *> pendingList = subProperties();
+ int pos = 0;
+ while (pos < pendingList.count()) {
+ if (pendingList.at(pos) == property) {
+ d_ptr->m_subItems.removeAt(pos);
+ property->d_ptr->m_parentItems.remove(this);
+
+ return;
+ }
+ pos++;
+ }
+}
+
+/*!
+ \internal
+*/
+void QtProperty::propertyChanged()
+{
+ d_ptr->m_manager->d_ptr->propertyChanged(this);
+}
+
+////////////////////////////////
+
+void QtAbstractPropertyManagerPrivate::propertyDestroyed(QtProperty *property)
+{
+ if (m_properties.contains(property)) {
+ emit q_ptr->propertyDestroyed(property);
+ q_ptr->uninitializeProperty(property);
+ m_properties.remove(property);
+ }
+}
+
+void QtAbstractPropertyManagerPrivate::propertyChanged(QtProperty *property) const
+{
+ emit q_ptr->propertyChanged(property);
+}
+
+void QtAbstractPropertyManagerPrivate::propertyRemoved(QtProperty *property,
+ QtProperty *parentProperty) const
+{
+ emit q_ptr->propertyRemoved(property, parentProperty);
+}
+
+void QtAbstractPropertyManagerPrivate::propertyInserted(QtProperty *property,
+ QtProperty *parentProperty, QtProperty *afterProperty) const
+{
+ emit q_ptr->propertyInserted(property, parentProperty, afterProperty);
+}
+
+/*!
+ \class QtAbstractPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtAbstractPropertyManager provides an interface for
+ property managers.
+
+ A manager can create and manage properties of a given type, and is
+ used in conjunction with the QtAbstractPropertyBrowser class.
+
+ When using a property browser widget, the properties are created
+ and managed by implementations of the QtAbstractPropertyManager
+ class. To ensure that the properties' values will be displayed
+ using suitable editing widgets, the managers are associated with
+ objects of QtAbstractEditorFactory subclasses. The property browser
+ will use these associations to determine which factories it should
+ use to create the preferred editing widgets.
+
+ The QtAbstractPropertyManager class provides common functionality
+ like creating a property using the addProperty() function, and
+ retrieving the properties created by the manager using the
+ properties() function. The class also provides signals that are
+ emitted when the manager's properties change: propertyInserted(),
+ propertyRemoved(), propertyChanged() and propertyDestroyed().
+
+ QtAbstractPropertyManager subclasses are supposed to provide their
+ own type specific API. Note that several ready-made
+ implementations are available:
+
+ \list
+ \o QtBoolPropertyManager
+ \o QtColorPropertyManager
+ \o QtDatePropertyManager
+ \o QtDateTimePropertyManager
+ \o QtDoublePropertyManager
+ \o QtEnumPropertyManager
+ \o QtFlagPropertyManager
+ \o QtFontPropertyManager
+ \o QtGroupPropertyManager
+ \o QtIntPropertyManager
+ \o QtPointPropertyManager
+ \o QtRectPropertyManager
+ \o QtSizePropertyManager
+ \o QtSizePolicyPropertyManager
+ \o QtStringPropertyManager
+ \o QtTimePropertyManager
+ \o QtVariantPropertyManager
+ \endlist
+
+ \sa QtAbstractEditorFactoryBase, QtAbstractPropertyBrowser, QtProperty
+*/
+
+/*!
+ \fn void QtAbstractPropertyManager::propertyInserted(QtProperty *newProperty,
+ QtProperty *parentProperty, QtProperty *precedingProperty)
+
+ This signal is emitted when a new subproperty is inserted into an
+ existing property, passing pointers to the \a newProperty, \a
+ parentProperty and \a precedingProperty as parameters.
+
+ If \a precedingProperty is 0, the \a newProperty was inserted at
+ the beginning of the \a parentProperty's subproperties list.
+
+ Note that signal is emitted only if the \a parentProperty is created
+ by this manager.
+
+ \sa QtAbstractPropertyBrowser::itemInserted()
+*/
+
+/*!
+ \fn void QtAbstractPropertyManager::propertyChanged(QtProperty *property)
+
+ This signal is emitted whenever a property's data changes, passing
+ a pointer to the \a property as parameter.
+
+ Note that signal is only emitted for properties that are created by
+ this manager.
+
+ \sa QtAbstractPropertyBrowser::itemChanged()
+*/
+
+/*!
+ \fn void QtAbstractPropertyManager::propertyRemoved(QtProperty *property, QtProperty *parent)
+
+ This signal is emitted when a subproperty is removed, passing
+ pointers to the removed \a property and the \a parent property as
+ parameters.
+
+ Note that signal is emitted only when the \a parent property is
+ created by this manager.
+
+ \sa QtAbstractPropertyBrowser::itemRemoved()
+*/
+
+/*!
+ \fn void QtAbstractPropertyManager::propertyDestroyed(QtProperty *property)
+
+ This signal is emitted when the specified \a property is about to
+ be destroyed.
+
+ Note that signal is only emitted for properties that are created
+ by this manager.
+
+ \sa clear(), uninitializeProperty()
+*/
+
+/*!
+ \fn void QtAbstractPropertyBrowser::currentItemChanged(QtBrowserItem *current)
+
+ This signal is emitted when the current item changes. The current item is specified by \a current.
+
+ \sa QtAbstractPropertyBrowser::setCurrentItem()
+*/
+
+/*!
+ Creates an abstract property manager with the given \a parent.
+*/
+QtAbstractPropertyManager::QtAbstractPropertyManager(QObject *parent)
+ : QObject(parent), d_ptr(new QtAbstractPropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+
+}
+
+/*!
+ Destroys the manager. All properties created by the manager are
+ destroyed.
+*/
+QtAbstractPropertyManager::~QtAbstractPropertyManager()
+{
+ clear();
+}
+
+/*!
+ Destroys all the properties that this manager has created.
+
+ \sa propertyDestroyed(), uninitializeProperty()
+*/
+void QtAbstractPropertyManager::clear() const
+{
+ while (!properties().isEmpty()) {
+ QSetIterator<QtProperty *> itProperty(properties());
+ QtProperty *prop = itProperty.next();
+ delete prop;
+ }
+}
+
+/*!
+ Returns the set of properties created by this manager.
+
+ \sa addProperty()
+*/
+QSet<QtProperty *> QtAbstractPropertyManager::properties() const
+{
+ return d_ptr->m_properties;
+}
+
+/*!
+ Returns whether the given \a property has a value.
+
+ The default implementation of this function returns true.
+
+ \sa QtProperty::hasValue()
+*/
+bool QtAbstractPropertyManager::hasValue(const QtProperty *property) const
+{
+ Q_UNUSED(property)
+ return true;
+}
+
+/*!
+ Returns an icon representing the current state of the given \a
+ property.
+
+ The default implementation of this function returns an invalid
+ icon.
+
+ \sa QtProperty::valueIcon()
+*/
+QIcon QtAbstractPropertyManager::valueIcon(const QtProperty *property) const
+{
+ Q_UNUSED(property)
+ return QIcon();
+}
+
+/*!
+ Returns a string representing the current state of the given \a
+ property.
+
+ The default implementation of this function returns an empty
+ string.
+
+ \sa QtProperty::valueText()
+*/
+QString QtAbstractPropertyManager::valueText(const QtProperty *property) const
+{
+ Q_UNUSED(property)
+ return QString();
+}
+
+/*!
+ Creates a property with the given \a name which then is owned by this manager.
+
+ Internally, this function calls the createProperty() and
+ initializeProperty() functions.
+
+ \sa initializeProperty(), properties()
+*/
+QtProperty *QtAbstractPropertyManager::addProperty(const QString &name)
+{
+ QtProperty *property = createProperty();
+ if (property) {
+ property->setPropertyName(name);
+ d_ptr->m_properties.insert(property);
+ initializeProperty(property);
+ }
+ return property;
+}
+
+/*!
+ Creates a property.
+
+ The base implementation produce QtProperty instances; Reimplement
+ this function to make this manager produce objects of a QtProperty
+ subclass.
+
+ \sa addProperty(), initializeProperty()
+*/
+QtProperty *QtAbstractPropertyManager::createProperty()
+{
+ return new QtProperty(this);
+}
+
+/*!
+ \fn void QtAbstractPropertyManager::initializeProperty(QtProperty *property) = 0
+
+ This function is called whenever a new valid property pointer has
+ been created, passing the pointer as parameter.
+
+ The purpose is to let the manager know that the \a property has
+ been created so that it can provide additional attributes for the
+ new property, e.g. QtIntPropertyManager adds \l
+ {QtIntPropertyManager::value()}{value}, \l
+ {QtIntPropertyManager::minimum()}{minimum} and \l
+ {QtIntPropertyManager::maximum()}{maximum} attributes. Since each manager
+ subclass adds type specific attributes, this function is pure
+ virtual and must be reimplemented when deriving from the
+ QtAbstractPropertyManager class.
+
+ \sa addProperty(), createProperty()
+*/
+
+/*!
+ This function is called just before the specified \a property is destroyed.
+
+ The purpose is to let the property manager know that the \a
+ property is being destroyed so that it can remove the property's
+ additional attributes.
+
+ \sa clear(), propertyDestroyed()
+*/
+void QtAbstractPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ Q_UNUSED(property)
+}
+
+////////////////////////////////////
+
+/*!
+ \class QtAbstractEditorFactoryBase
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtAbstractEditorFactoryBase provides an interface for
+ editor factories.
+
+ An editor factory is a class that is able to create an editing
+ widget of a specified type (e.g. line edits or comboboxes) for a
+ given QtProperty object, and it is used in conjunction with the
+ QtAbstractPropertyManager and QtAbstractPropertyBrowser classes.
+
+ When using a property browser widget, the properties are created
+ and managed by implementations of the QtAbstractPropertyManager
+ class. To ensure that the properties' values will be displayed
+ using suitable editing widgets, the managers are associated with
+ objects of QtAbstractEditorFactory subclasses. The property browser
+ will use these associations to determine which factories it should
+ use to create the preferred editing widgets.
+
+ Typically, an editor factory is created by subclassing the
+ QtAbstractEditorFactory template class which inherits
+ QtAbstractEditorFactoryBase. But note that several ready-made
+ implementations are available:
+
+ \list
+ \o QtCheckBoxFactory
+ \o QtDateEditFactory
+ \o QtDateTimeEditFactory
+ \o QtDoubleSpinBoxFactory
+ \o QtEnumEditorFactory
+ \o QtLineEditFactory
+ \o QtScrollBarFactory
+ \o QtSliderFactory
+ \o QtSpinBoxFactory
+ \o QtTimeEditFactory
+ \o QtVariantEditorFactory
+ \endlist
+
+ \sa QtAbstractPropertyManager, QtAbstractPropertyBrowser
+*/
+
+/*!
+ \fn virtual QWidget *QtAbstractEditorFactoryBase::createEditor(QtProperty *property,
+ QWidget *parent) = 0
+
+ Creates an editing widget (with the given \a parent) for the given
+ \a property.
+
+ This function is reimplemented in QtAbstractEditorFactory template class
+ which also provides a pure virtual convenience overload of this
+ function enabling access to the property's manager.
+
+ \sa QtAbstractEditorFactory::createEditor()
+*/
+
+/*!
+ \fn QtAbstractEditorFactoryBase::QtAbstractEditorFactoryBase(QObject *parent = 0)
+
+ Creates an abstract editor factory with the given \a parent.
+*/
+
+/*!
+ \fn virtual void QtAbstractEditorFactoryBase::breakConnection(QtAbstractPropertyManager *manager) = 0
+
+ \internal
+
+ Detaches property manager from factory.
+ This method is reimplemented in QtAbstractEditorFactory template subclass.
+ You don't need to reimplement it in your subclasses. Instead implement more convenient
+ QtAbstractEditorFactory::disconnectPropertyManager() which gives you access to particular manager subclass.
+*/
+
+/*!
+ \fn virtual void QtAbstractEditorFactoryBase::managerDestroyed(QObject *manager) = 0
+
+ \internal
+
+ This method is called when property manager is being destroyed.
+ Basically it notifies factory not to produce editors for properties owned by \a manager.
+ You don't need to reimplement it in your subclass. This method is implemented in
+ QtAbstractEditorFactory template subclass.
+*/
+
+/*!
+ \class QtAbstractEditorFactory
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtAbstractEditorFactory is the base template class for editor
+ factories.
+
+ An editor factory is a class that is able to create an editing
+ widget of a specified type (e.g. line edits or comboboxes) for a
+ given QtProperty object, and it is used in conjunction with the
+ QtAbstractPropertyManager and QtAbstractPropertyBrowser classes.
+
+ Note that the QtAbstractEditorFactory functions are using the
+ PropertyManager template argument class which can be any
+ QtAbstractPropertyManager subclass. For example:
+
+ \snippet doc/src/snippets/code/tools_shared_qtpropertybrowser_qtpropertybrowser.cpp 0
+
+ Note that QtSpinBoxFactory by definition creates editing widgets
+ \e only for properties created by QtIntPropertyManager.
+
+ When using a property browser widget, the properties are created
+ and managed by implementations of the QtAbstractPropertyManager
+ class. To ensure that the properties' values will be displayed
+ using suitable editing widgets, the managers are associated with
+ objects of QtAbstractEditorFactory subclasses. The property browser will
+ use these associations to determine which factories it should use
+ to create the preferred editing widgets.
+
+ A QtAbstractEditorFactory object is capable of producing editors for
+ several property managers at the same time. To create an
+ association between this factory and a given manager, use the
+ addPropertyManager() function. Use the removePropertyManager() function to make
+ this factory stop producing editors for a given property
+ manager. Use the propertyManagers() function to retrieve the set of
+ managers currently associated with this factory.
+
+ Several ready-made implementations of the QtAbstractEditorFactory class
+ are available:
+
+ \list
+ \o QtCheckBoxFactory
+ \o QtDateEditFactory
+ \o QtDateTimeEditFactory
+ \o QtDoubleSpinBoxFactory
+ \o QtEnumEditorFactory
+ \o QtLineEditFactory
+ \o QtScrollBarFactory
+ \o QtSliderFactory
+ \o QtSpinBoxFactory
+ \o QtTimeEditFactory
+ \o QtVariantEditorFactory
+ \endlist
+
+ When deriving from the QtAbstractEditorFactory class, several pure virtual
+ functions must be implemented: the connectPropertyManager() function is
+ used by the factory to connect to the given manager's signals, the
+ createEditor() function is supposed to create an editor for the
+ given property controlled by the given manager, and finally the
+ disconnectPropertyManager() function is used by the factory to disconnect
+ from the specified manager's signals.
+
+ \sa QtAbstractEditorFactoryBase, QtAbstractPropertyManager
+*/
+
+/*!
+ \fn QtAbstractEditorFactory::QtAbstractEditorFactory(QObject *parent = 0)
+
+ Creates an editor factory with the given \a parent.
+
+ \sa addPropertyManager()
+*/
+
+/*!
+ \fn QWidget *QtAbstractEditorFactory::createEditor(QtProperty *property, QWidget *parent)
+
+ Creates an editing widget (with the given \a parent) for the given
+ \a property.
+*/
+
+/*!
+ \fn void QtAbstractEditorFactory::addPropertyManager(PropertyManager *manager)
+
+ Adds the given \a manager to this factory's set of managers,
+ making this factory produce editing widgets for properties created
+ by the given manager.
+
+ The PropertyManager type is a template argument class, and represents the chosen
+ QtAbstractPropertyManager subclass.
+
+ \sa propertyManagers(), removePropertyManager()
+*/
+
+/*!
+ \fn void QtAbstractEditorFactory::removePropertyManager(PropertyManager *manager)
+
+ Removes the given \a manager from this factory's set of
+ managers. The PropertyManager type is a template argument class, and may be
+ any QtAbstractPropertyManager subclass.
+
+ \sa propertyManagers(), addPropertyManager()
+*/
+
+/*!
+ \fn virtual void QtAbstractEditorFactory::connectPropertyManager(PropertyManager *manager) = 0
+
+ Connects this factory to the given \a manager's signals. The
+ PropertyManager type is a template argument class, and represents
+ the chosen QtAbstractPropertyManager subclass.
+
+ This function is used internally by the addPropertyManager() function, and
+ makes it possible to update an editing widget when the associated
+ property's data changes. This is typically done in custom slots
+ responding to the signals emitted by the property's manager,
+ e.g. QtIntPropertyManager::valueChanged() and
+ QtIntPropertyManager::rangeChanged().
+
+ \sa propertyManagers(), disconnectPropertyManager()
+*/
+
+/*!
+ \fn virtual QWidget *QtAbstractEditorFactory::createEditor(PropertyManager *manager, QtProperty *property,
+ QWidget *parent) = 0
+
+ Creates an editing widget with the given \a parent for the
+ specified \a property created by the given \a manager. The
+ PropertyManager type is a template argument class, and represents
+ the chosen QtAbstractPropertyManager subclass.
+
+ This function must be implemented in derived classes: It is
+ recommended to store a pointer to the widget and map it to the
+ given \a property, since the widget must be updated whenever the
+ associated property's data changes. This is typically done in
+ custom slots responding to the signals emitted by the property's
+ manager, e.g. QtIntPropertyManager::valueChanged() and
+ QtIntPropertyManager::rangeChanged().
+
+ \sa connectPropertyManager()
+*/
+
+/*!
+ \fn virtual void QtAbstractEditorFactory::disconnectPropertyManager(PropertyManager *manager) = 0
+
+ Disconnects this factory from the given \a manager's signals. The
+ PropertyManager type is a template argument class, and represents
+ the chosen QtAbstractPropertyManager subclass.
+
+ This function is used internally by the removePropertyManager() function.
+
+ \sa propertyManagers(), connectPropertyManager()
+*/
+
+/*!
+ \fn QSet<PropertyManager *> QtAbstractEditorFactory::propertyManagers() const
+
+ Returns the factory's set of associated managers. The
+ PropertyManager type is a template argument class, and represents
+ the chosen QtAbstractPropertyManager subclass.
+
+ \sa addPropertyManager(), removePropertyManager()
+*/
+
+/*!
+ \fn PropertyManager *QtAbstractEditorFactory::propertyManager(QtProperty *property) const
+
+ Returns the property manager for the given \a property, or 0 if
+ the given \a property doesn't belong to any of this factory's
+ registered managers.
+
+ The PropertyManager type is a template argument class, and represents the chosen
+ QtAbstractPropertyManager subclass.
+
+ \sa propertyManagers()
+*/
+
+/*!
+ \fn virtual void QtAbstractEditorFactory::managerDestroyed(QObject *manager)
+
+ \internal
+ \reimp
+*/
+
+////////////////////////////////////
+class QtBrowserItemPrivate
+{
+public:
+ QtBrowserItemPrivate(QtAbstractPropertyBrowser *browser, QtProperty *property, QtBrowserItem *parent)
+ : m_browser(browser), m_property(property), m_parent(parent), q_ptr(0) {}
+
+ void addChild(QtBrowserItem *index, QtBrowserItem *after);
+ void removeChild(QtBrowserItem *index);
+
+ QtAbstractPropertyBrowser * const m_browser;
+ QtProperty *m_property;
+ QtBrowserItem *m_parent;
+
+ QtBrowserItem *q_ptr;
+
+ QList<QtBrowserItem *> m_children;
+
+};
+
+void QtBrowserItemPrivate::addChild(QtBrowserItem *index, QtBrowserItem *after)
+{
+ if (m_children.contains(index))
+ return;
+ int idx = m_children.indexOf(after) + 1; // we insert after returned idx, if it was -1 then we set idx to 0;
+ m_children.insert(idx, index);
+}
+
+void QtBrowserItemPrivate::removeChild(QtBrowserItem *index)
+{
+ m_children.removeAll(index);
+}
+
+
+/*!
+ \class QtBrowserItem
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtBrowserItem class represents a property in
+ a property browser instance.
+
+ Browser items are created whenever a QtProperty is inserted to the
+ property browser. A QtBrowserItem uniquely identifies a
+ browser's item. Thus, if the same QtProperty is inserted multiple
+ times, each occurrence gets its own unique QtBrowserItem. The
+ items are owned by QtAbstractPropertyBrowser and automatically
+ deleted when they are removed from the browser.
+
+ You can traverse a browser's properties by calling parent() and
+ children(). The property and the browser associated with an item
+ are available as property() and browser().
+
+ \sa QtAbstractPropertyBrowser, QtProperty
+*/
+
+/*!
+ Returns the property which is accosiated with this item. Note that
+ several items can be associated with the same property instance in
+ the same property browser.
+
+ \sa QtAbstractPropertyBrowser::items()
+*/
+
+QtProperty *QtBrowserItem::property() const
+{
+ return d_ptr->m_property;
+}
+
+/*!
+ Returns the parent item of \e this item. Returns 0 if \e this item
+ is associated with top-level property in item's property browser.
+
+ \sa children()
+*/
+
+QtBrowserItem *QtBrowserItem::parent() const
+{
+ return d_ptr->m_parent;
+}
+
+/*!
+ Returns the children items of \e this item. The properties
+ reproduced from children items are always the same as
+ reproduced from associated property' children, for example:
+
+ \snippet doc/src/snippets/code/tools_shared_qtpropertybrowser_qtpropertybrowser.cpp 1
+
+ The \e childrenItems list represents the same list as \e childrenProperties.
+*/
+
+QList<QtBrowserItem *> QtBrowserItem::children() const
+{
+ return d_ptr->m_children;
+}
+
+/*!
+ Returns the property browser which owns \e this item.
+*/
+
+QtAbstractPropertyBrowser *QtBrowserItem::browser() const
+{
+ return d_ptr->m_browser;
+}
+
+QtBrowserItem::QtBrowserItem(QtAbstractPropertyBrowser *browser, QtProperty *property, QtBrowserItem *parent)
+ : d_ptr(new QtBrowserItemPrivate(browser, property, parent))
+{
+ d_ptr->q_ptr = this;
+}
+
+QtBrowserItem::~QtBrowserItem()
+{
+}
+
+
+////////////////////////////////////
+
+typedef QMap<QtAbstractPropertyBrowser *, QMap<QtAbstractPropertyManager *,
+ QtAbstractEditorFactoryBase *> > Map1;
+typedef QMap<QtAbstractPropertyManager *, QMap<QtAbstractEditorFactoryBase *,
+ QList<QtAbstractPropertyBrowser *> > > Map2;
+Q_GLOBAL_STATIC(Map1, m_viewToManagerToFactory)
+Q_GLOBAL_STATIC(Map2, m_managerToFactoryToViews)
+
+class QtAbstractPropertyBrowserPrivate
+{
+ QtAbstractPropertyBrowser *q_ptr;
+ Q_DECLARE_PUBLIC(QtAbstractPropertyBrowser)
+public:
+ QtAbstractPropertyBrowserPrivate();
+
+ void insertSubTree(QtProperty *property,
+ QtProperty *parentProperty);
+ void removeSubTree(QtProperty *property,
+ QtProperty *parentProperty);
+ void createBrowserIndexes(QtProperty *property, QtProperty *parentProperty, QtProperty *afterProperty);
+ void removeBrowserIndexes(QtProperty *property, QtProperty *parentProperty);
+ QtBrowserItem *createBrowserIndex(QtProperty *property, QtBrowserItem *parentIndex, QtBrowserItem *afterIndex);
+ void removeBrowserIndex(QtBrowserItem *index);
+ void clearIndex(QtBrowserItem *index);
+
+ void slotPropertyInserted(QtProperty *property,
+ QtProperty *parentProperty, QtProperty *afterProperty);
+ void slotPropertyRemoved(QtProperty *property, QtProperty *parentProperty);
+ void slotPropertyDestroyed(QtProperty *property);
+ void slotPropertyDataChanged(QtProperty *property);
+
+ QList<QtProperty *> m_subItems;
+ QMap<QtAbstractPropertyManager *, QList<QtProperty *> > m_managerToProperties;
+ QMap<QtProperty *, QList<QtProperty *> > m_propertyToParents;
+
+ QMap<QtProperty *, QtBrowserItem *> m_topLevelPropertyToIndex;
+ QList<QtBrowserItem *> m_topLevelIndexes;
+ QMap<QtProperty *, QList<QtBrowserItem *> > m_propertyToIndexes;
+
+ QtBrowserItem *m_currentItem;
+};
+
+QtAbstractPropertyBrowserPrivate::QtAbstractPropertyBrowserPrivate() :
+ m_currentItem(0)
+{
+}
+
+void QtAbstractPropertyBrowserPrivate::insertSubTree(QtProperty *property,
+ QtProperty *parentProperty)
+{
+ if (m_propertyToParents.contains(property)) {
+ // property was already inserted, so its manager is connected
+ // and all its children are inserted and theirs managers are connected
+ // we just register new parent (parent has to be new).
+ m_propertyToParents[property].append(parentProperty);
+ // don't need to update m_managerToProperties map since
+ // m_managerToProperties[manager] already contains property.
+ return;
+ }
+ QtAbstractPropertyManager *manager = property->propertyManager();
+ if (m_managerToProperties[manager].isEmpty()) {
+ // connect manager's signals
+ q_ptr->connect(manager, SIGNAL(propertyInserted(QtProperty *,
+ QtProperty *, QtProperty *)),
+ q_ptr, SLOT(slotPropertyInserted(QtProperty *,
+ QtProperty *, QtProperty *)));
+ q_ptr->connect(manager, SIGNAL(propertyRemoved(QtProperty *,
+ QtProperty *)),
+ q_ptr, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*)));
+ q_ptr->connect(manager, SIGNAL(propertyDestroyed(QtProperty*)),
+ q_ptr, SLOT(slotPropertyDestroyed(QtProperty*)));
+ q_ptr->connect(manager, SIGNAL(propertyChanged(QtProperty*)),
+ q_ptr, SLOT(slotPropertyDataChanged(QtProperty*)));
+ }
+ m_managerToProperties[manager].append(property);
+ m_propertyToParents[property].append(parentProperty);
+
+ QList<QtProperty *> subList = property->subProperties();
+ QListIterator<QtProperty *> itSub(subList);
+ while (itSub.hasNext()) {
+ QtProperty *subProperty = itSub.next();
+ insertSubTree(subProperty, property);
+ }
+}
+
+void QtAbstractPropertyBrowserPrivate::removeSubTree(QtProperty *property,
+ QtProperty *parentProperty)
+{
+ if (!m_propertyToParents.contains(property)) {
+ // ASSERT
+ return;
+ }
+
+ m_propertyToParents[property].removeAll(parentProperty);
+ if (!m_propertyToParents[property].isEmpty())
+ return;
+
+ m_propertyToParents.remove(property);
+ QtAbstractPropertyManager *manager = property->propertyManager();
+ m_managerToProperties[manager].removeAll(property);
+ if (m_managerToProperties[manager].isEmpty()) {
+ // disconnect manager's signals
+ q_ptr->disconnect(manager, SIGNAL(propertyInserted(QtProperty *,
+ QtProperty *, QtProperty *)),
+ q_ptr, SLOT(slotPropertyInserted(QtProperty *,
+ QtProperty *, QtProperty *)));
+ q_ptr->disconnect(manager, SIGNAL(propertyRemoved(QtProperty *,
+ QtProperty *)),
+ q_ptr, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*)));
+ q_ptr->disconnect(manager, SIGNAL(propertyDestroyed(QtProperty*)),
+ q_ptr, SLOT(slotPropertyDestroyed(QtProperty*)));
+ q_ptr->disconnect(manager, SIGNAL(propertyChanged(QtProperty*)),
+ q_ptr, SLOT(slotPropertyDataChanged(QtProperty*)));
+
+ m_managerToProperties.remove(manager);
+ }
+
+ QList<QtProperty *> subList = property->subProperties();
+ QListIterator<QtProperty *> itSub(subList);
+ while (itSub.hasNext()) {
+ QtProperty *subProperty = itSub.next();
+ removeSubTree(subProperty, property);
+ }
+}
+
+void QtAbstractPropertyBrowserPrivate::createBrowserIndexes(QtProperty *property, QtProperty *parentProperty, QtProperty *afterProperty)
+{
+ QMap<QtBrowserItem *, QtBrowserItem *> parentToAfter;
+ if (afterProperty) {
+ QMap<QtProperty *, QList<QtBrowserItem *> >::ConstIterator it =
+ m_propertyToIndexes.find(afterProperty);
+ if (it == m_propertyToIndexes.constEnd())
+ return;
+
+ QList<QtBrowserItem *> indexes = it.value();
+ QListIterator<QtBrowserItem *> itIndex(indexes);
+ while (itIndex.hasNext()) {
+ QtBrowserItem *idx = itIndex.next();
+ QtBrowserItem *parentIdx = idx->parent();
+ if ((parentProperty && parentIdx && parentIdx->property() == parentProperty) || (!parentProperty && !parentIdx))
+ parentToAfter[idx->parent()] = idx;
+ }
+ } else if (parentProperty) {
+ QMap<QtProperty *, QList<QtBrowserItem *> >::ConstIterator it =
+ m_propertyToIndexes.find(parentProperty);
+ if (it == m_propertyToIndexes.constEnd())
+ return;
+
+ QList<QtBrowserItem *> indexes = it.value();
+ QListIterator<QtBrowserItem *> itIndex(indexes);
+ while (itIndex.hasNext()) {
+ QtBrowserItem *idx = itIndex.next();
+ parentToAfter[idx] = 0;
+ }
+ } else {
+ parentToAfter[0] = 0;
+ }
+
+ const QMap<QtBrowserItem *, QtBrowserItem *>::ConstIterator pcend = parentToAfter.constEnd();
+ for (QMap<QtBrowserItem *, QtBrowserItem *>::ConstIterator it = parentToAfter.constBegin(); it != pcend; ++it)
+ createBrowserIndex(property, it.key(), it.value());
+}
+
+QtBrowserItem *QtAbstractPropertyBrowserPrivate::createBrowserIndex(QtProperty *property,
+ QtBrowserItem *parentIndex, QtBrowserItem *afterIndex)
+{
+ QtBrowserItem *newIndex = new QtBrowserItem(q_ptr, property, parentIndex);
+ if (parentIndex) {
+ parentIndex->d_ptr->addChild(newIndex, afterIndex);
+ } else {
+ m_topLevelPropertyToIndex[property] = newIndex;
+ m_topLevelIndexes.insert(m_topLevelIndexes.indexOf(afterIndex) + 1, newIndex);
+ }
+ m_propertyToIndexes[property].append(newIndex);
+
+ q_ptr->itemInserted(newIndex, afterIndex);
+
+ QList<QtProperty *> subItems = property->subProperties();
+ QListIterator<QtProperty *> itChild(subItems);
+ QtBrowserItem *afterChild = 0;
+ while (itChild.hasNext()) {
+ QtProperty *child = itChild.next();
+ afterChild = createBrowserIndex(child, newIndex, afterChild);
+ }
+ return newIndex;
+}
+
+void QtAbstractPropertyBrowserPrivate::removeBrowserIndexes(QtProperty *property, QtProperty *parentProperty)
+{
+ QList<QtBrowserItem *> toRemove;
+ QMap<QtProperty *, QList<QtBrowserItem *> >::ConstIterator it =
+ m_propertyToIndexes.find(property);
+ if (it == m_propertyToIndexes.constEnd())
+ return;
+
+ QList<QtBrowserItem *> indexes = it.value();
+ QListIterator<QtBrowserItem *> itIndex(indexes);
+ while (itIndex.hasNext()) {
+ QtBrowserItem *idx = itIndex.next();
+ QtBrowserItem *parentIdx = idx->parent();
+ if ((parentProperty && parentIdx && parentIdx->property() == parentProperty) || (!parentProperty && !parentIdx))
+ toRemove.append(idx);
+ }
+
+ QListIterator<QtBrowserItem *> itRemove(toRemove);
+ while (itRemove.hasNext()) {
+ QtBrowserItem *index = itRemove.next();
+ removeBrowserIndex(index);
+ }
+}
+
+void QtAbstractPropertyBrowserPrivate::removeBrowserIndex(QtBrowserItem *index)
+{
+ QList<QtBrowserItem *> children = index->children();
+ for (int i = children.count(); i > 0; i--) {
+ removeBrowserIndex(children.at(i - 1));
+ }
+
+ q_ptr->itemRemoved(index);
+
+ if (index->parent()) {
+ index->parent()->d_ptr->removeChild(index);
+ } else {
+ m_topLevelPropertyToIndex.remove(index->property());
+ m_topLevelIndexes.removeAll(index);
+ }
+
+ QtProperty *property = index->property();
+
+ m_propertyToIndexes[property].removeAll(index);
+ if (m_propertyToIndexes[property].isEmpty())
+ m_propertyToIndexes.remove(property);
+
+ delete index;
+}
+
+void QtAbstractPropertyBrowserPrivate::clearIndex(QtBrowserItem *index)
+{
+ QList<QtBrowserItem *> children = index->children();
+ QListIterator<QtBrowserItem *> itChild(children);
+ while (itChild.hasNext()) {
+ clearIndex(itChild.next());
+ }
+ delete index;
+}
+
+void QtAbstractPropertyBrowserPrivate::slotPropertyInserted(QtProperty *property,
+ QtProperty *parentProperty, QtProperty *afterProperty)
+{
+ if (!m_propertyToParents.contains(parentProperty))
+ return;
+ createBrowserIndexes(property, parentProperty, afterProperty);
+ insertSubTree(property, parentProperty);
+ //q_ptr->propertyInserted(property, parentProperty, afterProperty);
+}
+
+void QtAbstractPropertyBrowserPrivate::slotPropertyRemoved(QtProperty *property,
+ QtProperty *parentProperty)
+{
+ if (!m_propertyToParents.contains(parentProperty))
+ return;
+ removeSubTree(property, parentProperty); // this line should be probably moved down after propertyRemoved call
+ //q_ptr->propertyRemoved(property, parentProperty);
+ removeBrowserIndexes(property, parentProperty);
+}
+
+void QtAbstractPropertyBrowserPrivate::slotPropertyDestroyed(QtProperty *property)
+{
+ if (!m_subItems.contains(property))
+ return;
+ q_ptr->removeProperty(property);
+}
+
+void QtAbstractPropertyBrowserPrivate::slotPropertyDataChanged(QtProperty *property)
+{
+ if (!m_propertyToParents.contains(property))
+ return;
+
+ QMap<QtProperty *, QList<QtBrowserItem *> >::ConstIterator it =
+ m_propertyToIndexes.find(property);
+ if (it == m_propertyToIndexes.constEnd())
+ return;
+
+ QList<QtBrowserItem *> indexes = it.value();
+ QListIterator<QtBrowserItem *> itIndex(indexes);
+ while (itIndex.hasNext()) {
+ QtBrowserItem *idx = itIndex.next();
+ q_ptr->itemChanged(idx);
+ }
+ //q_ptr->propertyChanged(property);
+}
+
+/*!
+ \class QtAbstractPropertyBrowser
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief QtAbstractPropertyBrowser provides a base class for
+ implementing property browsers.
+
+ A property browser is a widget that enables the user to edit a
+ given set of properties. Each property is represented by a label
+ specifying the property's name, and an editing widget (e.g. a line
+ edit or a combobox) holding its value. A property can have zero or
+ more subproperties.
+
+ \image qtpropertybrowser.png
+
+ The top level properties can be retrieved using the
+ properties() function. To traverse each property's
+ subproperties, use the QtProperty::subProperties() function. In
+ addition, the set of top level properties can be manipulated using
+ the addProperty(), insertProperty() and removeProperty()
+ functions. Note that the QtProperty class provides a corresponding
+ set of functions making it possible to manipulate the set of
+ subproperties as well.
+
+ To remove all the properties from the property browser widget, use
+ the clear() function. This function will clear the editor, but it
+ will not delete the properties since they can still be used in
+ other editors.
+
+ The properties themselves are created and managed by
+ implementations of the QtAbstractPropertyManager class. A manager
+ can handle (i.e. create and manage) properties of a given type. In
+ the property browser the managers are associated with
+ implementations of the QtAbstractEditorFactory: A factory is a
+ class able to create an editing widget of a specified type.
+
+ When using a property browser widget, managers must be created for
+ each of the required property types before the properties
+ themselves can be created. To ensure that the properties' values
+ will be displayed using suitable editing widgets, the managers
+ must be associated with objects of the preferred factory
+ implementations using the setFactoryForManager() function. The
+ property browser will use these associations to determine which
+ factory it should use to create the preferred editing widget.
+
+ Note that a factory can be associated with many managers, but a
+ manager can only be associated with one single factory within the
+ context of a single property browser. The associations between
+ managers and factories can at any time be removed using the
+ unsetFactoryForManager() function.
+
+ Whenever the property data changes or a property is inserted or
+ removed, the itemChanged(), itemInserted() or
+ itemRemoved() functions are called, respectively. These
+ functions must be reimplemented in derived classes in order to
+ update the property browser widget. Be aware that some property
+ instances can appear several times in an abstract tree
+ structure. For example:
+
+ \table 100%
+ \row
+ \o
+ \snippet doc/src/snippets/code/tools_shared_qtpropertybrowser_qtpropertybrowser.cpp 2
+ \o \image qtpropertybrowser-duplicate.png
+ \endtable
+
+ The addProperty() function returns a QtBrowserItem that uniquely
+ identifies the created item.
+
+ To make a property editable in the property browser, the
+ createEditor() function must be called to provide the
+ property with a suitable editing widget.
+
+ Note that there are two ready-made property browser
+ implementations:
+
+ \list
+ \o QtGroupBoxPropertyBrowser
+ \o QtTreePropertyBrowser
+ \endlist
+
+ \sa QtAbstractPropertyManager, QtAbstractEditorFactoryBase
+*/
+
+/*!
+ \fn void QtAbstractPropertyBrowser::setFactoryForManager(PropertyManager *manager,
+ QtAbstractEditorFactory<PropertyManager> *factory)
+
+ Connects the given \a manager to the given \a factory, ensuring
+ that properties of the \a manager's type will be displayed with an
+ editing widget suitable for their value.
+
+ For example:
+
+ \snippet doc/src/snippets/code/tools_shared_qtpropertybrowser_qtpropertybrowser.cpp 3
+
+ In this example the \c myInteger property's value is displayed
+ with a QSpinBox widget, while the \c myDouble property's value is
+ displayed with a QDoubleSpinBox widget.
+
+ Note that a factory can be associated with many managers, but a
+ manager can only be associated with one single factory. If the
+ given \a manager already is associated with another factory, the
+ old association is broken before the new one established.
+
+ This function ensures that the given \a manager and the given \a
+ factory are compatible, and it automatically calls the
+ QtAbstractEditorFactory::addPropertyManager() function if necessary.
+
+ \sa unsetFactoryForManager()
+*/
+
+/*!
+ \fn virtual void QtAbstractPropertyBrowser::itemInserted(QtBrowserItem *insertedItem,
+ QtBrowserItem *precedingItem) = 0
+
+ This function is called to update the widget whenever a property
+ is inserted or added to the property browser, passing pointers to
+ the \a insertedItem of property and the specified
+ \a precedingItem as parameters.
+
+ If \a precedingItem is 0, the \a insertedItem was put at
+ the beginning of its parent item's list of subproperties. If
+ the parent of \a insertedItem is 0, the \a insertedItem was added as a top
+ level property of \e this property browser.
+
+ This function must be reimplemented in derived classes. Note that
+ if the \a insertedItem's property has subproperties, this
+ method will be called for those properties as soon as the current call is finished.
+
+ \sa insertProperty(), addProperty()
+*/
+
+/*!
+ \fn virtual void QtAbstractPropertyBrowser::itemRemoved(QtBrowserItem *item) = 0
+
+ This function is called to update the widget whenever a property
+ is removed from the property browser, passing the pointer to the
+ \a item of the property as parameters. The passed \a item is
+ deleted just after this call is finished.
+
+ If the the parent of \a item is 0, the removed \a item was a
+ top level property in this editor.
+
+ This function must be reimplemented in derived classes. Note that
+ if the removed \a item's property has subproperties, this
+ method will be called for those properties just before the current call is started.
+
+ \sa removeProperty()
+*/
+
+/*!
+ \fn virtual void QtAbstractPropertyBrowser::itemChanged(QtBrowserItem *item) = 0
+
+ This function is called whenever a property's data changes,
+ passing a pointer to the \a item of property as parameter.
+
+ This function must be reimplemented in derived classes in order to
+ update the property browser widget whenever a property's name,
+ tool tip, status tip, "what's this" text, value text or value icon
+ changes.
+
+ Note that if the property browser contains several occurrences of
+ the same property, this method will be called once for each
+ occurrence (with a different item each time).
+
+ \sa QtProperty, items()
+*/
+
+/*!
+ Creates an abstract property browser with the given \a parent.
+*/
+QtAbstractPropertyBrowser::QtAbstractPropertyBrowser(QWidget *parent)
+ : QWidget(parent), d_ptr(new QtAbstractPropertyBrowserPrivate)
+{
+ d_ptr->q_ptr = this;
+
+}
+
+/*!
+ Destroys the property browser, and destroys all the items that were
+ created by this property browser.
+
+ Note that the properties that were displayed in the editor are not
+ deleted since they still can be used in other editors. Neither
+ does the destructor delete the property managers and editor
+ factories that were used by this property browser widget unless
+ this widget was their parent.
+
+ \sa QtAbstractPropertyManager::~QtAbstractPropertyManager()
+*/
+QtAbstractPropertyBrowser::~QtAbstractPropertyBrowser()
+{
+ QList<QtBrowserItem *> indexes = topLevelItems();
+ QListIterator<QtBrowserItem *> itItem(indexes);
+ while (itItem.hasNext())
+ d_ptr->clearIndex(itItem.next());
+}
+
+/*!
+ Returns the property browser's list of top level properties.
+
+ To traverse the subproperties, use the QtProperty::subProperties()
+ function.
+
+ \sa addProperty(), insertProperty(), removeProperty()
+*/
+QList<QtProperty *> QtAbstractPropertyBrowser::properties() const
+{
+ return d_ptr->m_subItems;
+}
+
+/*!
+ Returns the property browser's list of all items associated
+ with the given \a property.
+
+ There is one item per instance of the property in the browser.
+
+ \sa topLevelItem()
+*/
+
+QList<QtBrowserItem *> QtAbstractPropertyBrowser::items(QtProperty *property) const
+{
+ return d_ptr->m_propertyToIndexes.value(property);
+}
+
+/*!
+ Returns the top-level items associated with the given \a property.
+
+ Returns 0 if \a property wasn't inserted into this property
+ browser or isn't a top-level one.
+
+ \sa topLevelItems(), items()
+*/
+
+QtBrowserItem *QtAbstractPropertyBrowser::topLevelItem(QtProperty *property) const
+{
+ return d_ptr->m_topLevelPropertyToIndex.value(property);
+}
+
+/*!
+ Returns the list of top-level items.
+
+ \sa topLevelItem()
+*/
+
+QList<QtBrowserItem *> QtAbstractPropertyBrowser::topLevelItems() const
+{
+ return d_ptr->m_topLevelIndexes;
+}
+
+/*!
+ Removes all the properties from the editor, but does not delete
+ them since they can still be used in other editors.
+
+ \sa removeProperty(), QtAbstractPropertyManager::clear()
+*/
+void QtAbstractPropertyBrowser::clear()
+{
+ QList<QtProperty *> subList = properties();
+ QListIterator<QtProperty *> itSub(subList);
+ itSub.toBack();
+ while (itSub.hasPrevious()) {
+ QtProperty *property = itSub.previous();
+ removeProperty(property);
+ }
+}
+
+/*!
+ Appends the given \a property (and its subproperties) to the
+ property browser's list of top level properties. Returns the item
+ created by property browser which is associated with the \a property.
+ In order to get all children items created by the property
+ browser in this call, the returned item should be traversed.
+
+ If the specified \a property is already added, this function does
+ nothing and returns 0.
+
+ \sa insertProperty(), QtProperty::addSubProperty(), properties()
+*/
+QtBrowserItem *QtAbstractPropertyBrowser::addProperty(QtProperty *property)
+{
+ QtProperty *afterProperty = 0;
+ if (d_ptr->m_subItems.count() > 0)
+ afterProperty = d_ptr->m_subItems.last();
+ return insertProperty(property, afterProperty);
+}
+
+/*!
+ \fn QtBrowserItem *QtAbstractPropertyBrowser::insertProperty(QtProperty *property,
+ QtProperty *afterProperty)
+
+ Inserts the given \a property (and its subproperties) after
+ the specified \a afterProperty in the browser's list of top
+ level properties. Returns item created by property browser which
+ is associated with the \a property. In order to get all children items
+ created by the property browser in this call returned item should be traversed.
+
+ If the specified \a afterProperty is 0, the given \a property is
+ inserted at the beginning of the list. If \a property is
+ already inserted, this function does nothing and returns 0.
+
+ \sa addProperty(), QtProperty::insertSubProperty(), properties()
+*/
+QtBrowserItem *QtAbstractPropertyBrowser::insertProperty(QtProperty *property,
+ QtProperty *afterProperty)
+{
+ if (!property)
+ return 0;
+
+ // if item is already inserted in this item then cannot add.
+ QList<QtProperty *> pendingList = properties();
+ int pos = 0;
+ int newPos = 0;
+ QtProperty *properAfterProperty = 0;
+ while (pos < pendingList.count()) {
+ QtProperty *prop = pendingList.at(pos);
+ if (prop == property)
+ return 0;
+ if (prop == afterProperty) {
+ newPos = pos + 1;
+ properAfterProperty = afterProperty;
+ }
+ pos++;
+ }
+ d_ptr->createBrowserIndexes(property, 0, afterProperty);
+
+ // traverse inserted subtree and connect to manager's signals
+ d_ptr->insertSubTree(property, 0);
+
+ d_ptr->m_subItems.insert(newPos, property);
+ //propertyInserted(property, 0, properAfterProperty);
+ return topLevelItem(property);
+}
+
+/*!
+ Removes the specified \a property (and its subproperties) from the
+ property browser's list of top level properties. All items
+ that were associated with the given \a property and its children
+ are deleted.
+
+ Note that the properties are \e not deleted since they can still
+ be used in other editors.
+
+ \sa clear(), QtProperty::removeSubProperty(), properties()
+*/
+void QtAbstractPropertyBrowser::removeProperty(QtProperty *property)
+{
+ if (!property)
+ return;
+
+ QList<QtProperty *> pendingList = properties();
+ int pos = 0;
+ while (pos < pendingList.count()) {
+ if (pendingList.at(pos) == property) {
+ d_ptr->m_subItems.removeAt(pos); //perhaps this two lines
+ d_ptr->removeSubTree(property, 0); //should be moved down after propertyRemoved call.
+ //propertyRemoved(property, 0);
+
+ d_ptr->removeBrowserIndexes(property, 0);
+
+ // when item is deleted, item will call removeItem for top level items,
+ // and itemRemoved for nested items.
+
+ return;
+ }
+ pos++;
+ }
+}
+
+/*!
+ Creates an editing widget (with the given \a parent) for the given
+ \a property according to the previously established associations
+ between property managers and editor factories.
+
+ If the property is created by a property manager which was not
+ associated with any of the existing factories in \e this property
+ editor, the function returns 0.
+
+ To make a property editable in the property browser, the
+ createEditor() function must be called to provide the
+ property with a suitable editing widget.
+
+ Reimplement this function to provide additional decoration for the
+ editing widgets created by the installed factories.
+
+ \sa setFactoryForManager()
+*/
+QWidget *QtAbstractPropertyBrowser::createEditor(QtProperty *property,
+ QWidget *parent)
+{
+ QtAbstractEditorFactoryBase *factory = 0;
+ QtAbstractPropertyManager *manager = property->propertyManager();
+
+ if (m_viewToManagerToFactory()->contains(this) &&
+ (*m_viewToManagerToFactory())[this].contains(manager)) {
+ factory = (*m_viewToManagerToFactory())[this][manager];
+ }
+
+ if (!factory)
+ return 0;
+ return factory->createEditor(property, parent);
+}
+
+bool QtAbstractPropertyBrowser::addFactory(QtAbstractPropertyManager *abstractManager,
+ QtAbstractEditorFactoryBase *abstractFactory)
+{
+ bool connectNeeded = false;
+ if (!m_managerToFactoryToViews()->contains(abstractManager) ||
+ !(*m_managerToFactoryToViews())[abstractManager].contains(abstractFactory)) {
+ connectNeeded = true;
+ } else if ((*m_managerToFactoryToViews())[abstractManager][abstractFactory]
+ .contains(this)) {
+ return connectNeeded;
+ }
+
+ if (m_viewToManagerToFactory()->contains(this) &&
+ (*m_viewToManagerToFactory())[this].contains(abstractManager)) {
+ unsetFactoryForManager(abstractManager);
+ }
+
+ (*m_managerToFactoryToViews())[abstractManager][abstractFactory].append(this);
+ (*m_viewToManagerToFactory())[this][abstractManager] = abstractFactory;
+
+ return connectNeeded;
+}
+
+/*!
+ Removes the association between the given \a manager and the
+ factory bound to it, automatically calling the
+ QtAbstractEditorFactory::removePropertyManager() function if necessary.
+
+ \sa setFactoryForManager()
+*/
+void QtAbstractPropertyBrowser::unsetFactoryForManager(QtAbstractPropertyManager *manager)
+{
+ if (!m_viewToManagerToFactory()->contains(this) ||
+ !(*m_viewToManagerToFactory())[this].contains(manager)) {
+ return;
+ }
+
+ QtAbstractEditorFactoryBase *abstractFactory =
+ (*m_viewToManagerToFactory())[this][manager];
+ (*m_viewToManagerToFactory())[this].remove(manager);
+ if ((*m_viewToManagerToFactory())[this].isEmpty()) {
+ (*m_viewToManagerToFactory()).remove(this);
+ }
+
+ (*m_managerToFactoryToViews())[manager][abstractFactory].removeAll(this);
+ if ((*m_managerToFactoryToViews())[manager][abstractFactory].isEmpty()) {
+ (*m_managerToFactoryToViews())[manager].remove(abstractFactory);
+ abstractFactory->breakConnection(manager);
+ if ((*m_managerToFactoryToViews())[manager].isEmpty()) {
+ (*m_managerToFactoryToViews()).remove(manager);
+ }
+ }
+}
+
+/*!
+ Returns the current item in the property browser.
+
+ \sa setCurrentItem()
+*/
+QtBrowserItem *QtAbstractPropertyBrowser::currentItem() const
+{
+ return d_ptr->m_currentItem;
+}
+
+/*!
+ Sets the current item in the property browser to \a item.
+
+ \sa currentItem(), currentItemChanged()
+*/
+void QtAbstractPropertyBrowser::setCurrentItem(QtBrowserItem *item)
+{
+ QtBrowserItem *oldItem = d_ptr->m_currentItem;
+ d_ptr->m_currentItem = item;
+ if (oldItem != item)
+ emit currentItemChanged(item);
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qtpropertybrowser.cpp"
diff --git a/src/shared/qtpropertybrowser/qtpropertybrowser.h b/src/shared/qtpropertybrowser/qtpropertybrowser.h
new file mode 100644
index 000000000..619f43501
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qtpropertybrowser.h
@@ -0,0 +1,309 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTPROPERTYBROWSER_H
+#define QTPROPERTYBROWSER_H
+
+#include <QtGui/QWidget>
+#include <QtCore/QSet>
+
+QT_BEGIN_NAMESPACE
+
+class QtAbstractPropertyManager;
+class QtPropertyPrivate;
+
+class QtProperty
+{
+public:
+ virtual ~QtProperty();
+
+ QList<QtProperty *> subProperties() const;
+
+ QtAbstractPropertyManager *propertyManager() const;
+
+ QString toolTip() const;
+ QString statusTip() const;
+ QString whatsThis() const;
+ QString propertyName() const;
+ bool isEnabled() const;
+ bool isModified() const;
+
+ bool hasValue() const;
+ QIcon valueIcon() const;
+ QString valueText() const;
+
+ void setToolTip(const QString &text);
+ void setStatusTip(const QString &text);
+ void setWhatsThis(const QString &text);
+ void setPropertyName(const QString &text);
+ void setEnabled(bool enable);
+ void setModified(bool modified);
+
+ void addSubProperty(QtProperty *property);
+ void insertSubProperty(QtProperty *property, QtProperty *afterProperty);
+ void removeSubProperty(QtProperty *property);
+protected:
+ explicit QtProperty(QtAbstractPropertyManager *manager);
+ void propertyChanged();
+private:
+ friend class QtAbstractPropertyManager;
+ QScopedPointer<QtPropertyPrivate> d_ptr;
+};
+
+class QtAbstractPropertyManagerPrivate;
+
+class QtAbstractPropertyManager : public QObject
+{
+ Q_OBJECT
+public:
+
+ explicit QtAbstractPropertyManager(QObject *parent = 0);
+ ~QtAbstractPropertyManager();
+
+ QSet<QtProperty *> properties() const;
+ void clear() const;
+
+ QtProperty *addProperty(const QString &name = QString());
+Q_SIGNALS:
+
+ void propertyInserted(QtProperty *property,
+ QtProperty *parent, QtProperty *after);
+ void propertyChanged(QtProperty *property);
+ void propertyRemoved(QtProperty *property, QtProperty *parent);
+ void propertyDestroyed(QtProperty *property);
+protected:
+ virtual bool hasValue(const QtProperty *property) const;
+ virtual QIcon valueIcon(const QtProperty *property) const;
+ virtual QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property) = 0;
+ virtual void uninitializeProperty(QtProperty *property);
+ virtual QtProperty *createProperty();
+private:
+ friend class QtProperty;
+ QScopedPointer<QtAbstractPropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtAbstractPropertyManager)
+ Q_DISABLE_COPY(QtAbstractPropertyManager)
+};
+
+class QtAbstractEditorFactoryBase : public QObject
+{
+ Q_OBJECT
+public:
+ virtual QWidget *createEditor(QtProperty *property, QWidget *parent) = 0;
+protected:
+ explicit QtAbstractEditorFactoryBase(QObject *parent = 0)
+ : QObject(parent) {}
+
+ virtual void breakConnection(QtAbstractPropertyManager *manager) = 0;
+protected Q_SLOTS:
+ virtual void managerDestroyed(QObject *manager) = 0;
+
+ friend class QtAbstractPropertyBrowser;
+};
+
+template <class PropertyManager>
+class QtAbstractEditorFactory : public QtAbstractEditorFactoryBase
+{
+public:
+ explicit QtAbstractEditorFactory(QObject *parent) : QtAbstractEditorFactoryBase(parent) {}
+ QWidget *createEditor(QtProperty *property, QWidget *parent)
+ {
+ QSetIterator<PropertyManager *> it(m_managers);
+ while (it.hasNext()) {
+ PropertyManager *manager = it.next();
+ if (manager == property->propertyManager()) {
+ return createEditor(manager, property, parent);
+ }
+ }
+ return 0;
+ }
+ void addPropertyManager(PropertyManager *manager)
+ {
+ if (m_managers.contains(manager))
+ return;
+ m_managers.insert(manager);
+ connectPropertyManager(manager);
+ connect(manager, SIGNAL(destroyed(QObject *)),
+ this, SLOT(managerDestroyed(QObject *)));
+ }
+ void removePropertyManager(PropertyManager *manager)
+ {
+ if (!m_managers.contains(manager))
+ return;
+ disconnect(manager, SIGNAL(destroyed(QObject *)),
+ this, SLOT(managerDestroyed(QObject *)));
+ disconnectPropertyManager(manager);
+ m_managers.remove(manager);
+ }
+ QSet<PropertyManager *> propertyManagers() const
+ {
+ return m_managers;
+ }
+ PropertyManager *propertyManager(QtProperty *property) const
+ {
+ QtAbstractPropertyManager *manager = property->propertyManager();
+ QSetIterator<PropertyManager *> itManager(m_managers);
+ while (itManager.hasNext()) {
+ PropertyManager *m = itManager.next();
+ if (m == manager) {
+ return m;
+ }
+ }
+ return 0;
+ }
+protected:
+ virtual void connectPropertyManager(PropertyManager *manager) = 0;
+ virtual QWidget *createEditor(PropertyManager *manager, QtProperty *property,
+ QWidget *parent) = 0;
+ virtual void disconnectPropertyManager(PropertyManager *manager) = 0;
+ void managerDestroyed(QObject *manager)
+ {
+ QSetIterator<PropertyManager *> it(m_managers);
+ while (it.hasNext()) {
+ PropertyManager *m = it.next();
+ if (m == manager) {
+ m_managers.remove(m);
+ return;
+ }
+ }
+ }
+private:
+ void breakConnection(QtAbstractPropertyManager *manager)
+ {
+ QSetIterator<PropertyManager *> it(m_managers);
+ while (it.hasNext()) {
+ PropertyManager *m = it.next();
+ if (m == manager) {
+ removePropertyManager(m);
+ return;
+ }
+ }
+ }
+private:
+ QSet<PropertyManager *> m_managers;
+ friend class QtAbstractPropertyEditor;
+};
+
+class QtAbstractPropertyBrowser;
+class QtBrowserItemPrivate;
+
+class QtBrowserItem
+{
+public:
+ QtProperty *property() const;
+ QtBrowserItem *parent() const;
+ QList<QtBrowserItem *> children() const;
+ QtAbstractPropertyBrowser *browser() const;
+private:
+ explicit QtBrowserItem(QtAbstractPropertyBrowser *browser, QtProperty *property, QtBrowserItem *parent);
+ ~QtBrowserItem();
+ QScopedPointer<QtBrowserItemPrivate> d_ptr;
+ friend class QtAbstractPropertyBrowserPrivate;
+};
+
+class QtAbstractPropertyBrowserPrivate;
+
+class QtAbstractPropertyBrowser : public QWidget
+{
+ Q_OBJECT
+public:
+
+ explicit QtAbstractPropertyBrowser(QWidget *parent = 0);
+ ~QtAbstractPropertyBrowser();
+
+ QList<QtProperty *> properties() const;
+ QList<QtBrowserItem *> items(QtProperty *property) const;
+ QtBrowserItem *topLevelItem(QtProperty *property) const;
+ QList<QtBrowserItem *> topLevelItems() const;
+ void clear();
+
+ template <class PropertyManager>
+ void setFactoryForManager(PropertyManager *manager,
+ QtAbstractEditorFactory<PropertyManager> *factory) {
+ QtAbstractPropertyManager *abstractManager = manager;
+ QtAbstractEditorFactoryBase *abstractFactory = factory;
+
+ if (addFactory(abstractManager, abstractFactory))
+ factory->addPropertyManager(manager);
+ }
+
+ void unsetFactoryForManager(QtAbstractPropertyManager *manager);
+
+ QtBrowserItem *currentItem() const;
+ void setCurrentItem(QtBrowserItem *);
+
+Q_SIGNALS:
+ void currentItemChanged(QtBrowserItem *);
+
+public Q_SLOTS:
+
+ QtBrowserItem *addProperty(QtProperty *property);
+ QtBrowserItem *insertProperty(QtProperty *property, QtProperty *afterProperty);
+ void removeProperty(QtProperty *property);
+
+protected:
+
+ virtual void itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem) = 0;
+ virtual void itemRemoved(QtBrowserItem *item) = 0;
+ // can be tooltip, statustip, whatsthis, name, icon, text.
+ virtual void itemChanged(QtBrowserItem *item) = 0;
+
+ virtual QWidget *createEditor(QtProperty *property, QWidget *parent);
+private:
+
+ bool addFactory(QtAbstractPropertyManager *abstractManager,
+ QtAbstractEditorFactoryBase *abstractFactory);
+
+ QScopedPointer<QtAbstractPropertyBrowserPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtAbstractPropertyBrowser)
+ Q_DISABLE_COPY(QtAbstractPropertyBrowser)
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyInserted(QtProperty *,
+ QtProperty *, QtProperty *))
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyRemoved(QtProperty *,
+ QtProperty *))
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *))
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyDataChanged(QtProperty *))
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QTPROPERTYBROWSER_H
diff --git a/src/shared/qtpropertybrowser/qtpropertybrowser.pri b/src/shared/qtpropertybrowser/qtpropertybrowser.pri
new file mode 100644
index 000000000..85c2b8d70
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qtpropertybrowser.pri
@@ -0,0 +1,19 @@
+INCLUDEPATH += $$PWD
+DEPENDPATH += $$PWD
+SOURCES += $$PWD/qtpropertybrowser.cpp \
+ $$PWD/qtpropertymanager.cpp \
+ $$PWD/qteditorfactory.cpp \
+ $$PWD/qtvariantproperty.cpp \
+ $$PWD/qttreepropertybrowser.cpp \
+ $$PWD/qtbuttonpropertybrowser.cpp \
+ $$PWD/qtgroupboxpropertybrowser.cpp \
+ $$PWD/qtpropertybrowserutils.cpp
+HEADERS += $$PWD/qtpropertybrowser.h \
+ $$PWD/qtpropertymanager.h \
+ $$PWD/qteditorfactory.h \
+ $$PWD/qtvariantproperty.h \
+ $$PWD/qttreepropertybrowser.h \
+ $$PWD/qtbuttonpropertybrowser.h \
+ $$PWD/qtgroupboxpropertybrowser.h \
+ $$PWD/qtpropertybrowserutils_p.h
+RESOURCES += $$PWD/qtpropertybrowser.qrc
diff --git a/src/shared/qtpropertybrowser/qtpropertybrowser.qrc b/src/shared/qtpropertybrowser/qtpropertybrowser.qrc
new file mode 100644
index 000000000..4f91ab782
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qtpropertybrowser.qrc
@@ -0,0 +1,23 @@
+<RCC version="1.0">
+ <qresource prefix="/trolltech/qtpropertybrowser">
+ <file>images/cursor-arrow.png</file>
+ <file>images/cursor-busy.png</file>
+ <file>images/cursor-closedhand.png</file>
+ <file>images/cursor-cross.png</file>
+ <file>images/cursor-forbidden.png</file>
+ <file>images/cursor-hand.png</file>
+ <file>images/cursor-hsplit.png</file>
+ <file>images/cursor-ibeam.png</file>
+ <file>images/cursor-openhand.png</file>
+ <file>images/cursor-sizeall.png</file>
+ <file>images/cursor-sizeb.png</file>
+ <file>images/cursor-sizef.png</file>
+ <file>images/cursor-sizeh.png</file>
+ <file>images/cursor-sizev.png</file>
+ <file>images/cursor-uparrow.png</file>
+ <file>images/cursor-vsplit.png</file>
+ <file>images/cursor-wait.png</file>
+ <file>images/cursor-whatsthis.png</file>
+ </qresource>
+</RCC>
+
diff --git a/src/shared/qtpropertybrowser/qtpropertybrowserutils.cpp b/src/shared/qtpropertybrowser/qtpropertybrowserutils.cpp
new file mode 100644
index 000000000..0b57cff88
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qtpropertybrowserutils.cpp
@@ -0,0 +1,456 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtpropertybrowserutils_p.h"
+#include <QtGui/QApplication>
+#include <QtGui/QPainter>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QMouseEvent>
+#include <QtGui/QCheckBox>
+#include <QtGui/QLineEdit>
+#include <QtGui/QMenu>
+#include <QtCore/QLocale>
+
+QT_BEGIN_NAMESPACE
+
+QtCursorDatabase::QtCursorDatabase()
+{
+ appendCursor(Qt::ArrowCursor, QApplication::translate("QtCursorDatabase", "Arrow", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-arrow.png")));
+ appendCursor(Qt::UpArrowCursor, QApplication::translate("QtCursorDatabase", "Up Arrow", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-uparrow.png")));
+ appendCursor(Qt::CrossCursor, QApplication::translate("QtCursorDatabase", "Cross", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-cross.png")));
+ appendCursor(Qt::WaitCursor, QApplication::translate("QtCursorDatabase", "Wait", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-wait.png")));
+ appendCursor(Qt::IBeamCursor, QApplication::translate("QtCursorDatabase", "IBeam", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-ibeam.png")));
+ appendCursor(Qt::SizeVerCursor, QApplication::translate("QtCursorDatabase", "Size Vertical", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-sizev.png")));
+ appendCursor(Qt::SizeHorCursor, QApplication::translate("QtCursorDatabase", "Size Horizontal", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-sizeh.png")));
+ appendCursor(Qt::SizeFDiagCursor, QApplication::translate("QtCursorDatabase", "Size Backslash", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-sizef.png")));
+ appendCursor(Qt::SizeBDiagCursor, QApplication::translate("QtCursorDatabase", "Size Slash", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-sizeb.png")));
+ appendCursor(Qt::SizeAllCursor, QApplication::translate("QtCursorDatabase", "Size All", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-sizeall.png")));
+ appendCursor(Qt::BlankCursor, QApplication::translate("QtCursorDatabase", "Blank", 0,
+ QApplication::UnicodeUTF8), QIcon());
+ appendCursor(Qt::SplitVCursor, QApplication::translate("QtCursorDatabase", "Split Vertical", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-vsplit.png")));
+ appendCursor(Qt::SplitHCursor, QApplication::translate("QtCursorDatabase", "Split Horizontal", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-hsplit.png")));
+ appendCursor(Qt::PointingHandCursor, QApplication::translate("QtCursorDatabase", "Pointing Hand", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-hand.png")));
+ appendCursor(Qt::ForbiddenCursor, QApplication::translate("QtCursorDatabase", "Forbidden", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-forbidden.png")));
+ appendCursor(Qt::OpenHandCursor, QApplication::translate("QtCursorDatabase", "Open Hand", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-openhand.png")));
+ appendCursor(Qt::ClosedHandCursor, QApplication::translate("QtCursorDatabase", "Closed Hand", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-closedhand.png")));
+ appendCursor(Qt::WhatsThisCursor, QApplication::translate("QtCursorDatabase", "What's This", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-whatsthis.png")));
+ appendCursor(Qt::BusyCursor, QApplication::translate("QtCursorDatabase", "Busy", 0,
+ QApplication::UnicodeUTF8), QIcon(QLatin1String(":/trolltech/qtpropertybrowser/images/cursor-busy.png")));
+}
+
+void QtCursorDatabase::clear()
+{
+ m_cursorNames.clear();
+ m_cursorIcons.clear();
+ m_valueToCursorShape.clear();
+ m_cursorShapeToValue.clear();
+}
+
+void QtCursorDatabase::appendCursor(Qt::CursorShape shape, const QString &name, const QIcon &icon)
+{
+ if (m_cursorShapeToValue.contains(shape))
+ return;
+ const int value = m_cursorNames.count();
+ m_cursorNames.append(name);
+ m_cursorIcons.insert(value, icon);
+ m_valueToCursorShape.insert(value, shape);
+ m_cursorShapeToValue.insert(shape, value);
+}
+
+QStringList QtCursorDatabase::cursorShapeNames() const
+{
+ return m_cursorNames;
+}
+
+QMap<int, QIcon> QtCursorDatabase::cursorShapeIcons() const
+{
+ return m_cursorIcons;
+}
+
+QString QtCursorDatabase::cursorToShapeName(const QCursor &cursor) const
+{
+ int val = cursorToValue(cursor);
+ if (val >= 0)
+ return m_cursorNames.at(val);
+ return QString();
+}
+
+QIcon QtCursorDatabase::cursorToShapeIcon(const QCursor &cursor) const
+{
+ int val = cursorToValue(cursor);
+ return m_cursorIcons.value(val);
+}
+
+int QtCursorDatabase::cursorToValue(const QCursor &cursor) const
+{
+#ifndef QT_NO_CURSOR
+ Qt::CursorShape shape = cursor.shape();
+ if (m_cursorShapeToValue.contains(shape))
+ return m_cursorShapeToValue[shape];
+#endif
+ return -1;
+}
+
+#ifndef QT_NO_CURSOR
+QCursor QtCursorDatabase::valueToCursor(int value) const
+{
+ if (m_valueToCursorShape.contains(value))
+ return QCursor(m_valueToCursorShape[value]);
+ return QCursor();
+}
+#endif
+
+QPixmap QtPropertyBrowserUtils::brushValuePixmap(const QBrush &b)
+{
+ QImage img(16, 16, QImage::Format_ARGB32_Premultiplied);
+ img.fill(0);
+
+ QPainter painter(&img);
+ painter.setCompositionMode(QPainter::CompositionMode_Source);
+ painter.fillRect(0, 0, img.width(), img.height(), b);
+ QColor color = b.color();
+ if (color.alpha() != 255) { // indicate alpha by an inset
+ QBrush opaqueBrush = b;
+ color.setAlpha(255);
+ opaqueBrush.setColor(color);
+ painter.fillRect(img.width() / 4, img.height() / 4,
+ img.width() / 2, img.height() / 2, opaqueBrush);
+ }
+ painter.end();
+ return QPixmap::fromImage(img);
+}
+
+QIcon QtPropertyBrowserUtils::brushValueIcon(const QBrush &b)
+{
+ return QIcon(brushValuePixmap(b));
+}
+
+QString QtPropertyBrowserUtils::colorValueText(const QColor &c)
+{
+ return QApplication::translate("QtPropertyBrowserUtils", "[%1, %2, %3] (%4)", 0, QApplication::UnicodeUTF8)
+ .arg(QString::number(c.red()))
+ .arg(QString::number(c.green()))
+ .arg(QString::number(c.blue()))
+ .arg(QString::number(c.alpha()));
+}
+
+QPixmap QtPropertyBrowserUtils::fontValuePixmap(const QFont &font)
+{
+ QFont f = font;
+ QImage img(16, 16, QImage::Format_ARGB32_Premultiplied);
+ img.fill(0);
+ QPainter p(&img);
+ p.setRenderHint(QPainter::TextAntialiasing, true);
+ p.setRenderHint(QPainter::Antialiasing, true);
+ f.setPointSize(13);
+ p.setFont(f);
+ QTextOption t;
+ t.setAlignment(Qt::AlignCenter);
+ p.drawText(QRect(0, 0, 16, 16), QString(QLatin1Char('A')), t);
+ return QPixmap::fromImage(img);
+}
+
+QIcon QtPropertyBrowserUtils::fontValueIcon(const QFont &f)
+{
+ return QIcon(fontValuePixmap(f));
+}
+
+QString QtPropertyBrowserUtils::fontValueText(const QFont &f)
+{
+ return QApplication::translate("QtPropertyBrowserUtils", "[%1, %2]", 0, QApplication::UnicodeUTF8)
+ .arg(f.family())
+ .arg(f.pointSize());
+}
+
+QString QtPropertyBrowserUtils::dateFormat()
+{
+ QLocale loc;
+ return loc.dateFormat(QLocale::ShortFormat);
+}
+
+QString QtPropertyBrowserUtils::timeFormat()
+{
+ QLocale loc;
+ // ShortFormat is missing seconds on UNIX.
+ return loc.timeFormat(QLocale::LongFormat);
+}
+
+QString QtPropertyBrowserUtils::dateTimeFormat()
+{
+ QString format = dateFormat();
+ format += QLatin1Char(' ');
+ format += timeFormat();
+ return format;
+}
+
+QtBoolEdit::QtBoolEdit(QWidget *parent) :
+ QWidget(parent),
+ m_checkBox(new QCheckBox(this)),
+ m_textVisible(true)
+{
+ QHBoxLayout *lt = new QHBoxLayout;
+ if (QApplication::layoutDirection() == Qt::LeftToRight)
+ lt->setContentsMargins(4, 0, 0, 0);
+ else
+ lt->setContentsMargins(0, 0, 4, 0);
+ lt->addWidget(m_checkBox);
+ setLayout(lt);
+ connect(m_checkBox, SIGNAL(toggled(bool)), this, SIGNAL(toggled(bool)));
+ setFocusProxy(m_checkBox);
+ m_checkBox->setText(tr("True"));
+}
+
+void QtBoolEdit::setTextVisible(bool textVisible)
+{
+ if (m_textVisible == textVisible)
+ return;
+
+ m_textVisible = textVisible;
+ if (m_textVisible)
+ m_checkBox->setText(isChecked() ? tr("True") : tr("False"));
+ else
+ m_checkBox->setText(QString());
+}
+
+Qt::CheckState QtBoolEdit::checkState() const
+{
+ return m_checkBox->checkState();
+}
+
+void QtBoolEdit::setCheckState(Qt::CheckState state)
+{
+ m_checkBox->setCheckState(state);
+}
+
+bool QtBoolEdit::isChecked() const
+{
+ return m_checkBox->isChecked();
+}
+
+void QtBoolEdit::setChecked(bool c)
+{
+ m_checkBox->setChecked(c);
+ if (!m_textVisible)
+ return;
+ m_checkBox->setText(isChecked() ? tr("True") : tr("False"));
+}
+
+bool QtBoolEdit::blockCheckBoxSignals(bool block)
+{
+ return m_checkBox->blockSignals(block);
+}
+
+void QtBoolEdit::mousePressEvent(QMouseEvent *event)
+{
+ if (event->buttons() == Qt::LeftButton) {
+ m_checkBox->click();
+ event->accept();
+ } else {
+ QWidget::mousePressEvent(event);
+ }
+}
+
+
+QtKeySequenceEdit::QtKeySequenceEdit(QWidget *parent)
+ : QWidget(parent), m_num(0), m_lineEdit(new QLineEdit(this))
+{
+ QHBoxLayout *layout = new QHBoxLayout(this);
+ layout->addWidget(m_lineEdit);
+ layout->setMargin(0);
+ m_lineEdit->installEventFilter(this);
+ m_lineEdit->setReadOnly(true);
+ m_lineEdit->setFocusProxy(this);
+ setFocusPolicy(m_lineEdit->focusPolicy());
+ setAttribute(Qt::WA_InputMethodEnabled);
+}
+
+bool QtKeySequenceEdit::eventFilter(QObject *o, QEvent *e)
+{
+ if (o == m_lineEdit && e->type() == QEvent::ContextMenu) {
+ QContextMenuEvent *c = static_cast<QContextMenuEvent *>(e);
+ QMenu *menu = m_lineEdit->createStandardContextMenu();
+ const QList<QAction *> actions = menu->actions();
+ QListIterator<QAction *> itAction(actions);
+ while (itAction.hasNext()) {
+ QAction *action = itAction.next();
+ action->setShortcut(QKeySequence());
+ QString actionString = action->text();
+ const int pos = actionString.lastIndexOf(QLatin1Char('\t'));
+ if (pos > 0)
+ actionString.remove(pos, actionString.length() - pos);
+ action->setText(actionString);
+ }
+ QAction *actionBefore = 0;
+ if (actions.count() > 0)
+ actionBefore = actions[0];
+ QAction *clearAction = new QAction(tr("Clear Shortcut"), menu);
+ menu->insertAction(actionBefore, clearAction);
+ menu->insertSeparator(actionBefore);
+ clearAction->setEnabled(!m_keySequence.isEmpty());
+ connect(clearAction, SIGNAL(triggered()), this, SLOT(slotClearShortcut()));
+ menu->exec(c->globalPos());
+ delete menu;
+ e->accept();
+ return true;
+ }
+
+ return QWidget::eventFilter(o, e);
+}
+
+void QtKeySequenceEdit::slotClearShortcut()
+{
+ if (m_keySequence.isEmpty())
+ return;
+ setKeySequence(QKeySequence());
+ emit keySequenceChanged(m_keySequence);
+}
+
+void QtKeySequenceEdit::handleKeyEvent(QKeyEvent *e)
+{
+ int nextKey = e->key();
+ if (nextKey == Qt::Key_Control || nextKey == Qt::Key_Shift ||
+ nextKey == Qt::Key_Meta || nextKey == Qt::Key_Alt ||
+ nextKey == Qt::Key_Super_L || nextKey == Qt::Key_AltGr)
+ return;
+
+ nextKey |= translateModifiers(e->modifiers(), e->text());
+ int k0 = m_keySequence[0];
+ int k1 = m_keySequence[1];
+ int k2 = m_keySequence[2];
+ int k3 = m_keySequence[3];
+ switch (m_num) {
+ case 0: k0 = nextKey; k1 = 0; k2 = 0; k3 = 0; break;
+ case 1: k1 = nextKey; k2 = 0; k3 = 0; break;
+ case 2: k2 = nextKey; k3 = 0; break;
+ case 3: k3 = nextKey; break;
+ default: break;
+ }
+ ++m_num;
+ if (m_num > 3)
+ m_num = 0;
+ m_keySequence = QKeySequence(k0, k1, k2, k3);
+ m_lineEdit->setText(m_keySequence.toString(QKeySequence::NativeText));
+ e->accept();
+ emit keySequenceChanged(m_keySequence);
+}
+
+void QtKeySequenceEdit::setKeySequence(const QKeySequence &sequence)
+{
+ if (sequence == m_keySequence)
+ return;
+ m_num = 0;
+ m_keySequence = sequence;
+ m_lineEdit->setText(m_keySequence.toString(QKeySequence::NativeText));
+}
+
+QKeySequence QtKeySequenceEdit::keySequence() const
+{
+ return m_keySequence;
+}
+
+int QtKeySequenceEdit::translateModifiers(Qt::KeyboardModifiers state, const QString &text) const
+{
+ int result = 0;
+ if ((state & Qt::ShiftModifier) && (text.size() == 0 || !text.at(0).isPrint() || text.at(0).isLetter() || text.at(0).isSpace()))
+ result |= Qt::SHIFT;
+ if (state & Qt::ControlModifier)
+ result |= Qt::CTRL;
+ if (state & Qt::MetaModifier)
+ result |= Qt::META;
+ if (state & Qt::AltModifier)
+ result |= Qt::ALT;
+ return result;
+}
+
+void QtKeySequenceEdit::focusInEvent(QFocusEvent *e)
+{
+ m_lineEdit->event(e);
+ m_lineEdit->selectAll();
+ QWidget::focusInEvent(e);
+}
+
+void QtKeySequenceEdit::focusOutEvent(QFocusEvent *e)
+{
+ m_num = 0;
+ m_lineEdit->event(e);
+ QWidget::focusOutEvent(e);
+}
+
+void QtKeySequenceEdit::keyPressEvent(QKeyEvent *e)
+{
+ handleKeyEvent(e);
+ e->accept();
+}
+
+void QtKeySequenceEdit::keyReleaseEvent(QKeyEvent *e)
+{
+ m_lineEdit->event(e);
+}
+
+bool QtKeySequenceEdit::event(QEvent *e)
+{
+ if (e->type() == QEvent::Shortcut ||
+ e->type() == QEvent::ShortcutOverride ||
+ e->type() == QEvent::KeyRelease) {
+ e->accept();
+ return true;
+ }
+ return QWidget::event(e);
+}
+
+QT_END_NAMESPACE
diff --git a/src/shared/qtpropertybrowser/qtpropertybrowserutils.pri b/src/shared/qtpropertybrowser/qtpropertybrowserutils.pri
new file mode 100644
index 000000000..17554481c
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qtpropertybrowserutils.pri
@@ -0,0 +1,4 @@
+INCLUDEPATH += $$PWD
+DEPENDPATH += $$PWD
+SOURCES += $$PWD/qtpropertybrowserutils.cpp
+HEADERS += $$PWD/qtpropertybrowserutils_p.h
diff --git a/src/shared/qtpropertybrowser/qtpropertybrowserutils_p.h b/src/shared/qtpropertybrowser/qtpropertybrowserutils_p.h
new file mode 100644
index 000000000..440ec9a11
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qtpropertybrowserutils_p.h
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QTPROPERTYBROWSERUTILS_H
+#define QTPROPERTYBROWSERUTILS_H
+
+#include <QtCore/QMap>
+#include <QtGui/QIcon>
+#include <QtGui/QWidget>
+#include <QtCore/QStringList>
+
+QT_BEGIN_NAMESPACE
+
+class QMouseEvent;
+class QCheckBox;
+class QLineEdit;
+
+class QtCursorDatabase
+{
+public:
+ QtCursorDatabase();
+ void clear();
+
+ QStringList cursorShapeNames() const;
+ QMap<int, QIcon> cursorShapeIcons() const;
+ QString cursorToShapeName(const QCursor &cursor) const;
+ QIcon cursorToShapeIcon(const QCursor &cursor) const;
+ int cursorToValue(const QCursor &cursor) const;
+#ifndef QT_NO_CURSOR
+ QCursor valueToCursor(int value) const;
+#endif
+private:
+ void appendCursor(Qt::CursorShape shape, const QString &name, const QIcon &icon);
+ QStringList m_cursorNames;
+ QMap<int, QIcon> m_cursorIcons;
+ QMap<int, Qt::CursorShape> m_valueToCursorShape;
+ QMap<Qt::CursorShape, int> m_cursorShapeToValue;
+};
+
+class QtPropertyBrowserUtils
+{
+public:
+ static QPixmap brushValuePixmap(const QBrush &b);
+ static QIcon brushValueIcon(const QBrush &b);
+ static QString colorValueText(const QColor &c);
+ static QPixmap fontValuePixmap(const QFont &f);
+ static QIcon fontValueIcon(const QFont &f);
+ static QString fontValueText(const QFont &f);
+ static QString dateFormat();
+ static QString timeFormat();
+ static QString dateTimeFormat();
+};
+
+class QtBoolEdit : public QWidget {
+ Q_OBJECT
+public:
+ QtBoolEdit(QWidget *parent = 0);
+
+ bool textVisible() const { return m_textVisible; }
+ void setTextVisible(bool textVisible);
+
+ Qt::CheckState checkState() const;
+ void setCheckState(Qt::CheckState state);
+
+ bool isChecked() const;
+ void setChecked(bool c);
+
+ bool blockCheckBoxSignals(bool block);
+
+Q_SIGNALS:
+ void toggled(bool);
+
+protected:
+ void mousePressEvent(QMouseEvent * event);
+
+private:
+ QCheckBox *m_checkBox;
+ bool m_textVisible;
+};
+
+class QtKeySequenceEdit : public QWidget
+{
+ Q_OBJECT
+public:
+ QtKeySequenceEdit(QWidget *parent = 0);
+
+ QKeySequence keySequence() const;
+ bool eventFilter(QObject *o, QEvent *e);
+public Q_SLOTS:
+ void setKeySequence(const QKeySequence &sequence);
+Q_SIGNALS:
+ void keySequenceChanged(const QKeySequence &sequence);
+protected:
+ void focusInEvent(QFocusEvent *e);
+ void focusOutEvent(QFocusEvent *e);
+ void keyPressEvent(QKeyEvent *e);
+ void keyReleaseEvent(QKeyEvent *e);
+ bool event(QEvent *e);
+private slots:
+ void slotClearShortcut();
+private:
+ void handleKeyEvent(QKeyEvent *e);
+ int translateModifiers(Qt::KeyboardModifiers state, const QString &text) const;
+
+ int m_num;
+ QKeySequence m_keySequence;
+ QLineEdit *m_lineEdit;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtpropertybrowser/qtpropertymanager.cpp b/src/shared/qtpropertybrowser/qtpropertymanager.cpp
new file mode 100644
index 000000000..962e35727
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qtpropertymanager.cpp
@@ -0,0 +1,6451 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtpropertymanager.h"
+#include "qtpropertybrowserutils_p.h"
+#include <QtCore/QDateTime>
+#include <QtCore/QLocale>
+#include <QtCore/QMap>
+#include <QtCore/QTimer>
+#include <QtGui/QIcon>
+#include <QtCore/QMetaEnum>
+#include <QtGui/QFontDatabase>
+#include <QtGui/QStyleOption>
+#include <QtGui/QStyle>
+#include <QtGui/QApplication>
+#include <QtGui/QPainter>
+#include <QtGui/QLabel>
+
+#include <limits.h>
+#include <float.h>
+
+#if defined(Q_CC_MSVC)
+# pragma warning(disable: 4786) /* MS VS 6: truncating debug info after 255 characters */
+#endif
+
+QT_BEGIN_NAMESPACE
+
+template <class PrivateData, class Value>
+static void setSimpleMinimumData(PrivateData *data, const Value &minVal)
+{
+ data->minVal = minVal;
+ if (data->maxVal < data->minVal)
+ data->maxVal = data->minVal;
+
+ if (data->val < data->minVal)
+ data->val = data->minVal;
+}
+
+template <class PrivateData, class Value>
+static void setSimpleMaximumData(PrivateData *data, const Value &maxVal)
+{
+ data->maxVal = maxVal;
+ if (data->minVal > data->maxVal)
+ data->minVal = data->maxVal;
+
+ if (data->val > data->maxVal)
+ data->val = data->maxVal;
+}
+
+template <class PrivateData, class Value>
+static void setSizeMinimumData(PrivateData *data, const Value &newMinVal)
+{
+ data->minVal = newMinVal;
+ if (data->maxVal.width() < data->minVal.width())
+ data->maxVal.setWidth(data->minVal.width());
+ if (data->maxVal.height() < data->minVal.height())
+ data->maxVal.setHeight(data->minVal.height());
+
+ if (data->val.width() < data->minVal.width())
+ data->val.setWidth(data->minVal.width());
+ if (data->val.height() < data->minVal.height())
+ data->val.setHeight(data->minVal.height());
+}
+
+template <class PrivateData, class Value>
+static void setSizeMaximumData(PrivateData *data, const Value &newMaxVal)
+{
+ data->maxVal = newMaxVal;
+ if (data->minVal.width() > data->maxVal.width())
+ data->minVal.setWidth(data->maxVal.width());
+ if (data->minVal.height() > data->maxVal.height())
+ data->minVal.setHeight(data->maxVal.height());
+
+ if (data->val.width() > data->maxVal.width())
+ data->val.setWidth(data->maxVal.width());
+ if (data->val.height() > data->maxVal.height())
+ data->val.setHeight(data->maxVal.height());
+}
+
+template <class SizeValue>
+static SizeValue qBoundSize(const SizeValue &minVal, const SizeValue &val, const SizeValue &maxVal)
+{
+ SizeValue croppedVal = val;
+ if (minVal.width() > val.width())
+ croppedVal.setWidth(minVal.width());
+ else if (maxVal.width() < val.width())
+ croppedVal.setWidth(maxVal.width());
+
+ if (minVal.height() > val.height())
+ croppedVal.setHeight(minVal.height());
+ else if (maxVal.height() < val.height())
+ croppedVal.setHeight(maxVal.height());
+
+ return croppedVal;
+}
+
+// Match the exact signature of qBound for VS 6.
+QSize qBound(QSize minVal, QSize val, QSize maxVal)
+{
+ return qBoundSize(minVal, val, maxVal);
+}
+
+QSizeF qBound(QSizeF minVal, QSizeF val, QSizeF maxVal)
+{
+ return qBoundSize(minVal, val, maxVal);
+}
+
+namespace {
+
+namespace {
+template <class Value>
+void orderBorders(Value &minVal, Value &maxVal)
+{
+ if (minVal > maxVal)
+ qSwap(minVal, maxVal);
+}
+
+template <class Value>
+static void orderSizeBorders(Value &minVal, Value &maxVal)
+{
+ Value fromSize = minVal;
+ Value toSize = maxVal;
+ if (fromSize.width() > toSize.width()) {
+ fromSize.setWidth(maxVal.width());
+ toSize.setWidth(minVal.width());
+ }
+ if (fromSize.height() > toSize.height()) {
+ fromSize.setHeight(maxVal.height());
+ toSize.setHeight(minVal.height());
+ }
+ minVal = fromSize;
+ maxVal = toSize;
+}
+
+void orderBorders(QSize &minVal, QSize &maxVal)
+{
+ orderSizeBorders(minVal, maxVal);
+}
+
+void orderBorders(QSizeF &minVal, QSizeF &maxVal)
+{
+ orderSizeBorders(minVal, maxVal);
+}
+
+}
+}
+////////
+
+template <class Value, class PrivateData>
+static Value getData(const QMap<const QtProperty *, PrivateData> &propertyMap,
+ Value PrivateData::*data,
+ const QtProperty *property, const Value &defaultValue = Value())
+{
+ typedef QMap<const QtProperty *, PrivateData> PropertyToData;
+ typedef Q_TYPENAME PropertyToData::const_iterator PropertyToDataConstIterator;
+ const PropertyToDataConstIterator it = propertyMap.constFind(property);
+ if (it == propertyMap.constEnd())
+ return defaultValue;
+ return it.value().*data;
+}
+
+template <class Value, class PrivateData>
+static Value getValue(const QMap<const QtProperty *, PrivateData> &propertyMap,
+ const QtProperty *property, const Value &defaultValue = Value())
+{
+ return getData<Value>(propertyMap, &PrivateData::val, property, defaultValue);
+}
+
+template <class Value, class PrivateData>
+static Value getMinimum(const QMap<const QtProperty *, PrivateData> &propertyMap,
+ const QtProperty *property, const Value &defaultValue = Value())
+{
+ return getData<Value>(propertyMap, &PrivateData::minVal, property, defaultValue);
+}
+
+template <class Value, class PrivateData>
+static Value getMaximum(const QMap<const QtProperty *, PrivateData> &propertyMap,
+ const QtProperty *property, const Value &defaultValue = Value())
+{
+ return getData<Value>(propertyMap, &PrivateData::maxVal, property, defaultValue);
+}
+
+template <class ValueChangeParameter, class Value, class PropertyManager>
+static void setSimpleValue(QMap<const QtProperty *, Value> &propertyMap,
+ PropertyManager *manager,
+ void (PropertyManager::*propertyChangedSignal)(QtProperty *),
+ void (PropertyManager::*valueChangedSignal)(QtProperty *, ValueChangeParameter),
+ QtProperty *property, const Value &val)
+{
+ typedef QMap<const QtProperty *, Value> PropertyToData;
+ typedef Q_TYPENAME PropertyToData::iterator PropertyToDataIterator;
+ const PropertyToDataIterator it = propertyMap.find(property);
+ if (it == propertyMap.end())
+ return;
+
+ if (it.value() == val)
+ return;
+
+ it.value() = val;
+
+ emit (manager->*propertyChangedSignal)(property);
+ emit (manager->*valueChangedSignal)(property, val);
+}
+
+template <class ValueChangeParameter, class PropertyManagerPrivate, class PropertyManager, class Value>
+static void setValueInRange(PropertyManager *manager, PropertyManagerPrivate *managerPrivate,
+ void (PropertyManager::*propertyChangedSignal)(QtProperty *),
+ void (PropertyManager::*valueChangedSignal)(QtProperty *, ValueChangeParameter),
+ QtProperty *property, const Value &val,
+ void (PropertyManagerPrivate::*setSubPropertyValue)(QtProperty *, ValueChangeParameter))
+{
+ typedef Q_TYPENAME PropertyManagerPrivate::Data PrivateData;
+ typedef QMap<const QtProperty *, PrivateData> PropertyToData;
+ typedef Q_TYPENAME PropertyToData::iterator PropertyToDataIterator;
+ const PropertyToDataIterator it = managerPrivate->m_values.find(property);
+ if (it == managerPrivate->m_values.end())
+ return;
+
+ PrivateData &data = it.value();
+
+ if (data.val == val)
+ return;
+
+ const Value oldVal = data.val;
+
+ data.val = qBound(data.minVal, val, data.maxVal);
+
+ if (data.val == oldVal)
+ return;
+
+ if (setSubPropertyValue)
+ (managerPrivate->*setSubPropertyValue)(property, data.val);
+
+ emit (manager->*propertyChangedSignal)(property);
+ emit (manager->*valueChangedSignal)(property, data.val);
+}
+
+template <class ValueChangeParameter, class PropertyManagerPrivate, class PropertyManager, class Value>
+static void setBorderValues(PropertyManager *manager, PropertyManagerPrivate *managerPrivate,
+ void (PropertyManager::*propertyChangedSignal)(QtProperty *),
+ void (PropertyManager::*valueChangedSignal)(QtProperty *, ValueChangeParameter),
+ void (PropertyManager::*rangeChangedSignal)(QtProperty *, ValueChangeParameter, ValueChangeParameter),
+ QtProperty *property, const Value &minVal, const Value &maxVal,
+ void (PropertyManagerPrivate::*setSubPropertyRange)(QtProperty *,
+ ValueChangeParameter, ValueChangeParameter, ValueChangeParameter))
+{
+ typedef Q_TYPENAME PropertyManagerPrivate::Data PrivateData;
+ typedef QMap<const QtProperty *, PrivateData> PropertyToData;
+ typedef Q_TYPENAME PropertyToData::iterator PropertyToDataIterator;
+ const PropertyToDataIterator it = managerPrivate->m_values.find(property);
+ if (it == managerPrivate->m_values.end())
+ return;
+
+ Value fromVal = minVal;
+ Value toVal = maxVal;
+ orderBorders(fromVal, toVal);
+
+ PrivateData &data = it.value();
+
+ if (data.minVal == fromVal && data.maxVal == toVal)
+ return;
+
+ const Value oldVal = data.val;
+
+ data.setMinimumValue(fromVal);
+ data.setMaximumValue(toVal);
+
+ emit (manager->*rangeChangedSignal)(property, data.minVal, data.maxVal);
+
+ if (setSubPropertyRange)
+ (managerPrivate->*setSubPropertyRange)(property, data.minVal, data.maxVal, data.val);
+
+ if (data.val == oldVal)
+ return;
+
+ emit (manager->*propertyChangedSignal)(property);
+ emit (manager->*valueChangedSignal)(property, data.val);
+}
+
+template <class ValueChangeParameter, class PropertyManagerPrivate, class PropertyManager, class Value, class PrivateData>
+static void setBorderValue(PropertyManager *manager, PropertyManagerPrivate *managerPrivate,
+ void (PropertyManager::*propertyChangedSignal)(QtProperty *),
+ void (PropertyManager::*valueChangedSignal)(QtProperty *, ValueChangeParameter),
+ void (PropertyManager::*rangeChangedSignal)(QtProperty *, ValueChangeParameter, ValueChangeParameter),
+ QtProperty *property,
+ Value (PrivateData::*getRangeVal)() const,
+ void (PrivateData::*setRangeVal)(ValueChangeParameter), const Value &borderVal,
+ void (PropertyManagerPrivate::*setSubPropertyRange)(QtProperty *,
+ ValueChangeParameter, ValueChangeParameter, ValueChangeParameter))
+{
+ typedef QMap<const QtProperty *, PrivateData> PropertyToData;
+ typedef Q_TYPENAME PropertyToData::iterator PropertyToDataIterator;
+ const PropertyToDataIterator it = managerPrivate->m_values.find(property);
+ if (it == managerPrivate->m_values.end())
+ return;
+
+ PrivateData &data = it.value();
+
+ if ((data.*getRangeVal)() == borderVal)
+ return;
+
+ const Value oldVal = data.val;
+
+ (data.*setRangeVal)(borderVal);
+
+ emit (manager->*rangeChangedSignal)(property, data.minVal, data.maxVal);
+
+ if (setSubPropertyRange)
+ (managerPrivate->*setSubPropertyRange)(property, data.minVal, data.maxVal, data.val);
+
+ if (data.val == oldVal)
+ return;
+
+ emit (manager->*propertyChangedSignal)(property);
+ emit (manager->*valueChangedSignal)(property, data.val);
+}
+
+template <class ValueChangeParameter, class PropertyManagerPrivate, class PropertyManager, class Value, class PrivateData>
+static void setMinimumValue(PropertyManager *manager, PropertyManagerPrivate *managerPrivate,
+ void (PropertyManager::*propertyChangedSignal)(QtProperty *),
+ void (PropertyManager::*valueChangedSignal)(QtProperty *, ValueChangeParameter),
+ void (PropertyManager::*rangeChangedSignal)(QtProperty *, ValueChangeParameter, ValueChangeParameter),
+ QtProperty *property, const Value &minVal)
+{
+ void (PropertyManagerPrivate::*setSubPropertyRange)(QtProperty *,
+ ValueChangeParameter, ValueChangeParameter, ValueChangeParameter) = 0;
+ setBorderValue<ValueChangeParameter, PropertyManagerPrivate, PropertyManager, Value, PrivateData>(manager, managerPrivate,
+ propertyChangedSignal, valueChangedSignal, rangeChangedSignal,
+ property, &PropertyManagerPrivate::Data::minimumValue, &PropertyManagerPrivate::Data::setMinimumValue, minVal, setSubPropertyRange);
+}
+
+template <class ValueChangeParameter, class PropertyManagerPrivate, class PropertyManager, class Value, class PrivateData>
+static void setMaximumValue(PropertyManager *manager, PropertyManagerPrivate *managerPrivate,
+ void (PropertyManager::*propertyChangedSignal)(QtProperty *),
+ void (PropertyManager::*valueChangedSignal)(QtProperty *, ValueChangeParameter),
+ void (PropertyManager::*rangeChangedSignal)(QtProperty *, ValueChangeParameter, ValueChangeParameter),
+ QtProperty *property, const Value &maxVal)
+{
+ void (PropertyManagerPrivate::*setSubPropertyRange)(QtProperty *,
+ ValueChangeParameter, ValueChangeParameter, ValueChangeParameter) = 0;
+ setBorderValue<ValueChangeParameter, PropertyManagerPrivate, PropertyManager, Value, PrivateData>(manager, managerPrivate,
+ propertyChangedSignal, valueChangedSignal, rangeChangedSignal,
+ property, &PropertyManagerPrivate::Data::maximumValue, &PropertyManagerPrivate::Data::setMaximumValue, maxVal, setSubPropertyRange);
+}
+
+class QtMetaEnumWrapper : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QSizePolicy::Policy policy READ policy)
+public:
+ QSizePolicy::Policy policy() const { return QSizePolicy::Ignored; }
+private:
+ QtMetaEnumWrapper(QObject *parent) : QObject(parent) {}
+};
+
+class QtMetaEnumProvider
+{
+public:
+ QtMetaEnumProvider();
+
+ QStringList policyEnumNames() const { return m_policyEnumNames; }
+ QStringList languageEnumNames() const { return m_languageEnumNames; }
+ QStringList countryEnumNames(QLocale::Language language) const { return m_countryEnumNames.value(language); }
+
+ QSizePolicy::Policy indexToSizePolicy(int index) const;
+ int sizePolicyToIndex(QSizePolicy::Policy policy) const;
+
+ void indexToLocale(int languageIndex, int countryIndex, QLocale::Language *language, QLocale::Country *country) const;
+ void localeToIndex(QLocale::Language language, QLocale::Country country, int *languageIndex, int *countryIndex) const;
+
+private:
+ void initLocale();
+
+ QStringList m_policyEnumNames;
+ QStringList m_languageEnumNames;
+ QMap<QLocale::Language, QStringList> m_countryEnumNames;
+ QMap<int, QLocale::Language> m_indexToLanguage;
+ QMap<QLocale::Language, int> m_languageToIndex;
+ QMap<int, QMap<int, QLocale::Country> > m_indexToCountry;
+ QMap<QLocale::Language, QMap<QLocale::Country, int> > m_countryToIndex;
+ QMetaEnum m_policyEnum;
+};
+
+static QList<QLocale::Country> sortCountries(const QList<QLocale::Country> &countries)
+{
+ QMultiMap<QString, QLocale::Country> nameToCountry;
+ QListIterator<QLocale::Country> itCountry(countries);
+ while (itCountry.hasNext()) {
+ QLocale::Country country = itCountry.next();
+ nameToCountry.insert(QLocale::countryToString(country), country);
+ }
+ return nameToCountry.values();
+}
+
+void QtMetaEnumProvider::initLocale()
+{
+ QMultiMap<QString, QLocale::Language> nameToLanguage;
+ QLocale::Language language = QLocale::C;
+ while (language <= QLocale::LastLanguage) {
+ QLocale locale(language);
+ if (locale.language() == language)
+ nameToLanguage.insert(QLocale::languageToString(language), language);
+ language = (QLocale::Language)((uint)language + 1); // ++language
+ }
+
+ const QLocale system = QLocale::system();
+ if (!nameToLanguage.contains(QLocale::languageToString(system.language())))
+ nameToLanguage.insert(QLocale::languageToString(system.language()), system.language());
+
+ QList<QLocale::Language> languages = nameToLanguage.values();
+ QListIterator<QLocale::Language> itLang(languages);
+ while (itLang.hasNext()) {
+ QLocale::Language language = itLang.next();
+ QList<QLocale::Country> countries;
+ countries = QLocale::countriesForLanguage(language);
+ if (countries.isEmpty() && language == system.language())
+ countries << system.country();
+
+ if (!countries.isEmpty() && !m_languageToIndex.contains(language)) {
+ countries = sortCountries(countries);
+ int langIdx = m_languageEnumNames.count();
+ m_indexToLanguage[langIdx] = language;
+ m_languageToIndex[language] = langIdx;
+ QStringList countryNames;
+ QListIterator<QLocale::Country> it(countries);
+ int countryIdx = 0;
+ while (it.hasNext()) {
+ QLocale::Country country = it.next();
+ countryNames << QLocale::countryToString(country);
+ m_indexToCountry[langIdx][countryIdx] = country;
+ m_countryToIndex[language][country] = countryIdx;
+ ++countryIdx;
+ }
+ m_languageEnumNames << QLocale::languageToString(language);
+ m_countryEnumNames[language] = countryNames;
+ }
+ }
+}
+
+QtMetaEnumProvider::QtMetaEnumProvider()
+{
+ QMetaProperty p;
+
+ p = QtMetaEnumWrapper::staticMetaObject.property(
+ QtMetaEnumWrapper::staticMetaObject.propertyOffset() + 0);
+ m_policyEnum = p.enumerator();
+ const int keyCount = m_policyEnum.keyCount();
+ for (int i = 0; i < keyCount; i++)
+ m_policyEnumNames << QLatin1String(m_policyEnum.key(i));
+
+ initLocale();
+}
+
+QSizePolicy::Policy QtMetaEnumProvider::indexToSizePolicy(int index) const
+{
+ return static_cast<QSizePolicy::Policy>(m_policyEnum.value(index));
+}
+
+int QtMetaEnumProvider::sizePolicyToIndex(QSizePolicy::Policy policy) const
+{
+ const int keyCount = m_policyEnum.keyCount();
+ for (int i = 0; i < keyCount; i++)
+ if (indexToSizePolicy(i) == policy)
+ return i;
+ return -1;
+}
+
+void QtMetaEnumProvider::indexToLocale(int languageIndex, int countryIndex, QLocale::Language *language, QLocale::Country *country) const
+{
+ QLocale::Language l = QLocale::C;
+ QLocale::Country c = QLocale::AnyCountry;
+ if (m_indexToLanguage.contains(languageIndex)) {
+ l = m_indexToLanguage[languageIndex];
+ if (m_indexToCountry.contains(languageIndex) && m_indexToCountry[languageIndex].contains(countryIndex))
+ c = m_indexToCountry[languageIndex][countryIndex];
+ }
+ if (language)
+ *language = l;
+ if (country)
+ *country = c;
+}
+
+void QtMetaEnumProvider::localeToIndex(QLocale::Language language, QLocale::Country country, int *languageIndex, int *countryIndex) const
+{
+ int l = -1;
+ int c = -1;
+ if (m_languageToIndex.contains(language)) {
+ l = m_languageToIndex[language];
+ if (m_countryToIndex.contains(language) && m_countryToIndex[language].contains(country))
+ c = m_countryToIndex[language][country];
+ }
+
+ if (languageIndex)
+ *languageIndex = l;
+ if (countryIndex)
+ *countryIndex = c;
+}
+
+Q_GLOBAL_STATIC(QtMetaEnumProvider, metaEnumProvider)
+
+// QtGroupPropertyManager
+
+/*!
+ \class QtGroupPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtGroupPropertyManager provides and manages group properties.
+
+ This class is intended to provide a grouping element without any value.
+
+ \sa QtAbstractPropertyManager
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtGroupPropertyManager::QtGroupPropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent)
+{
+
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtGroupPropertyManager::~QtGroupPropertyManager()
+{
+
+}
+
+/*!
+ \reimp
+*/
+bool QtGroupPropertyManager::hasValue(const QtProperty *property) const
+{
+ Q_UNUSED(property)
+ return false;
+}
+
+/*!
+ \reimp
+*/
+void QtGroupPropertyManager::initializeProperty(QtProperty *property)
+{
+ Q_UNUSED(property)
+}
+
+/*!
+ \reimp
+*/
+void QtGroupPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ Q_UNUSED(property)
+}
+
+// QtIntPropertyManager
+
+class QtIntPropertyManagerPrivate
+{
+ QtIntPropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtIntPropertyManager)
+public:
+
+ struct Data
+ {
+ Data() : val(0), minVal(-INT_MAX), maxVal(INT_MAX), singleStep(1) {}
+ int val;
+ int minVal;
+ int maxVal;
+ int singleStep;
+ int minimumValue() const { return minVal; }
+ int maximumValue() const { return maxVal; }
+ void setMinimumValue(int newMinVal) { setSimpleMinimumData(this, newMinVal); }
+ void setMaximumValue(int newMaxVal) { setSimpleMaximumData(this, newMaxVal); }
+ };
+
+ typedef QMap<const QtProperty *, Data> PropertyValueMap;
+ PropertyValueMap m_values;
+};
+
+/*!
+ \class QtIntPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtIntPropertyManager provides and manages int properties.
+
+ An int property has a current value, and a range specifying the
+ valid values. The range is defined by a minimum and a maximum
+ value.
+
+ The property's value and range can be retrieved using the value(),
+ minimum() and maximum() functions, and can be set using the
+ setValue(), setMinimum() and setMaximum() slots. Alternatively,
+ the range can be defined in one go using the setRange() slot.
+
+ In addition, QtIntPropertyManager provides the valueChanged() signal which
+ is emitted whenever a property created by this manager changes,
+ and the rangeChanged() signal which is emitted whenever such a
+ property changes its range of valid values.
+
+ \sa QtAbstractPropertyManager, QtSpinBoxFactory, QtSliderFactory, QtScrollBarFactory
+*/
+
+/*!
+ \fn void QtIntPropertyManager::valueChanged(QtProperty *property, int value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the new
+ \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ \fn void QtIntPropertyManager::rangeChanged(QtProperty *property, int minimum, int maximum)
+
+ This signal is emitted whenever a property created by this manager
+ changes its range of valid values, passing a pointer to the
+ \a property and the new \a minimum and \a maximum values.
+
+ \sa setRange()
+*/
+
+/*!
+ \fn void QtIntPropertyManager::singleStepChanged(QtProperty *property, int step)
+
+ This signal is emitted whenever a property created by this manager
+ changes its single step property, passing a pointer to the
+ \a property and the new \a step value
+
+ \sa setSingleStep()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtIntPropertyManager::QtIntPropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtIntPropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtIntPropertyManager::~QtIntPropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given property is not managed by this manager, this
+ function returns 0.
+
+ \sa setValue()
+*/
+int QtIntPropertyManager::value(const QtProperty *property) const
+{
+ return getValue<int>(d_ptr->m_values, property, 0);
+}
+
+/*!
+ Returns the given \a property's minimum value.
+
+ \sa setMinimum(), maximum(), setRange()
+*/
+int QtIntPropertyManager::minimum(const QtProperty *property) const
+{
+ return getMinimum<int>(d_ptr->m_values, property, 0);
+}
+
+/*!
+ Returns the given \a property's maximum value.
+
+ \sa setMaximum(), minimum(), setRange()
+*/
+int QtIntPropertyManager::maximum(const QtProperty *property) const
+{
+ return getMaximum<int>(d_ptr->m_values, property, 0);
+}
+
+/*!
+ Returns the given \a property's step value.
+
+ The step is typically used to increment or decrement a property value while pressing an arrow key.
+
+ \sa setSingleStep()
+*/
+int QtIntPropertyManager::singleStep(const QtProperty *property) const
+{
+ return getData<int>(d_ptr->m_values, &QtIntPropertyManagerPrivate::Data::singleStep, property, 0);
+}
+
+/*!
+ \reimp
+*/
+QString QtIntPropertyManager::valueText(const QtProperty *property) const
+{
+ const QtIntPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+ return QString::number(it.value().val);
+}
+
+/*!
+ \fn void QtIntPropertyManager::setValue(QtProperty *property, int value)
+
+ Sets the value of the given \a property to \a value.
+
+ If the specified \a value is not valid according to the given \a
+ property's range, the \a value is adjusted to the nearest valid
+ value within the range.
+
+ \sa value(), setRange(), valueChanged()
+*/
+void QtIntPropertyManager::setValue(QtProperty *property, int val)
+{
+ void (QtIntPropertyManagerPrivate::*setSubPropertyValue)(QtProperty *, int) = 0;
+ setValueInRange<int, QtIntPropertyManagerPrivate, QtIntPropertyManager, int>(this, d_ptr.data(),
+ &QtIntPropertyManager::propertyChanged,
+ &QtIntPropertyManager::valueChanged,
+ property, val, setSubPropertyValue);
+}
+
+/*!
+ Sets the minimum value for the given \a property to \a minVal.
+
+ When setting the minimum value, the maximum and current values are
+ adjusted if necessary (ensuring that the range remains valid and
+ that the current value is within the range).
+
+ \sa minimum(), setRange(), rangeChanged()
+*/
+void QtIntPropertyManager::setMinimum(QtProperty *property, int minVal)
+{
+ setMinimumValue<int, QtIntPropertyManagerPrivate, QtIntPropertyManager, int, QtIntPropertyManagerPrivate::Data>(this, d_ptr.data(),
+ &QtIntPropertyManager::propertyChanged,
+ &QtIntPropertyManager::valueChanged,
+ &QtIntPropertyManager::rangeChanged,
+ property, minVal);
+}
+
+/*!
+ Sets the maximum value for the given \a property to \a maxVal.
+
+ When setting maximum value, the minimum and current values are
+ adjusted if necessary (ensuring that the range remains valid and
+ that the current value is within the range).
+
+ \sa maximum(), setRange(), rangeChanged()
+*/
+void QtIntPropertyManager::setMaximum(QtProperty *property, int maxVal)
+{
+ setMaximumValue<int, QtIntPropertyManagerPrivate, QtIntPropertyManager, int, QtIntPropertyManagerPrivate::Data>(this, d_ptr.data(),
+ &QtIntPropertyManager::propertyChanged,
+ &QtIntPropertyManager::valueChanged,
+ &QtIntPropertyManager::rangeChanged,
+ property, maxVal);
+}
+
+/*!
+ \fn void QtIntPropertyManager::setRange(QtProperty *property, int minimum, int maximum)
+
+ Sets the range of valid values.
+
+ This is a convenience function defining the range of valid values
+ in one go; setting the \a minimum and \a maximum values for the
+ given \a property with a single function call.
+
+ When setting a new range, the current value is adjusted if
+ necessary (ensuring that the value remains within range).
+
+ \sa setMinimum(), setMaximum(), rangeChanged()
+*/
+void QtIntPropertyManager::setRange(QtProperty *property, int minVal, int maxVal)
+{
+ void (QtIntPropertyManagerPrivate::*setSubPropertyRange)(QtProperty *, int, int, int) = 0;
+ setBorderValues<int, QtIntPropertyManagerPrivate, QtIntPropertyManager, int>(this, d_ptr.data(),
+ &QtIntPropertyManager::propertyChanged,
+ &QtIntPropertyManager::valueChanged,
+ &QtIntPropertyManager::rangeChanged,
+ property, minVal, maxVal, setSubPropertyRange);
+}
+
+/*!
+ Sets the step value for the given \a property to \a step.
+
+ The step is typically used to increment or decrement a property value while pressing an arrow key.
+
+ \sa singleStep()
+*/
+void QtIntPropertyManager::setSingleStep(QtProperty *property, int step)
+{
+ const QtIntPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ QtIntPropertyManagerPrivate::Data data = it.value();
+
+ if (step < 0)
+ step = 0;
+
+ if (data.singleStep == step)
+ return;
+
+ data.singleStep = step;
+
+ it.value() = data;
+
+ emit singleStepChanged(property, data.singleStep);
+}
+
+/*!
+ \reimp
+*/
+void QtIntPropertyManager::initializeProperty(QtProperty *property)
+{
+ d_ptr->m_values[property] = QtIntPropertyManagerPrivate::Data();
+}
+
+/*!
+ \reimp
+*/
+void QtIntPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ d_ptr->m_values.remove(property);
+}
+
+// QtDoublePropertyManager
+
+class QtDoublePropertyManagerPrivate
+{
+ QtDoublePropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtDoublePropertyManager)
+public:
+
+ struct Data
+ {
+ Data() : val(0), minVal(-INT_MAX), maxVal(INT_MAX), singleStep(1), decimals(2) {}
+ double val;
+ double minVal;
+ double maxVal;
+ double singleStep;
+ int decimals;
+ double minimumValue() const { return minVal; }
+ double maximumValue() const { return maxVal; }
+ void setMinimumValue(double newMinVal) { setSimpleMinimumData(this, newMinVal); }
+ void setMaximumValue(double newMaxVal) { setSimpleMaximumData(this, newMaxVal); }
+ };
+
+ typedef QMap<const QtProperty *, Data> PropertyValueMap;
+ PropertyValueMap m_values;
+};
+
+/*!
+ \class QtDoublePropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtDoublePropertyManager provides and manages double properties.
+
+ A double property has a current value, and a range specifying the
+ valid values. The range is defined by a minimum and a maximum
+ value.
+
+ The property's value and range can be retrieved using the value(),
+ minimum() and maximum() functions, and can be set using the
+ setValue(), setMinimum() and setMaximum() slots.
+ Alternatively, the range can be defined in one go using the
+ setRange() slot.
+
+ In addition, QtDoublePropertyManager provides the valueChanged() signal
+ which is emitted whenever a property created by this manager
+ changes, and the rangeChanged() signal which is emitted whenever
+ such a property changes its range of valid values.
+
+ \sa QtAbstractPropertyManager, QtDoubleSpinBoxFactory
+*/
+
+/*!
+ \fn void QtDoublePropertyManager::valueChanged(QtProperty *property, double value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the new
+ \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ \fn void QtDoublePropertyManager::rangeChanged(QtProperty *property, double minimum, double maximum)
+
+ This signal is emitted whenever a property created by this manager
+ changes its range of valid values, passing a pointer to the
+ \a property and the new \a minimum and \a maximum values
+
+ \sa setRange()
+*/
+
+/*!
+ \fn void QtDoublePropertyManager::decimalsChanged(QtProperty *property, int prec)
+
+ This signal is emitted whenever a property created by this manager
+ changes its precision of value, passing a pointer to the
+ \a property and the new \a prec value
+
+ \sa setDecimals()
+*/
+
+/*!
+ \fn void QtDoublePropertyManager::singleStepChanged(QtProperty *property, double step)
+
+ This signal is emitted whenever a property created by this manager
+ changes its single step property, passing a pointer to the
+ \a property and the new \a step value
+
+ \sa setSingleStep()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtDoublePropertyManager::QtDoublePropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtDoublePropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtDoublePropertyManager::~QtDoublePropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given property is not managed by this manager, this
+ function returns 0.
+
+ \sa setValue()
+*/
+double QtDoublePropertyManager::value(const QtProperty *property) const
+{
+ return getValue<double>(d_ptr->m_values, property, 0.0);
+}
+
+/*!
+ Returns the given \a property's minimum value.
+
+ \sa maximum(), setRange()
+*/
+double QtDoublePropertyManager::minimum(const QtProperty *property) const
+{
+ return getMinimum<double>(d_ptr->m_values, property, 0.0);
+}
+
+/*!
+ Returns the given \a property's maximum value.
+
+ \sa minimum(), setRange()
+*/
+double QtDoublePropertyManager::maximum(const QtProperty *property) const
+{
+ return getMaximum<double>(d_ptr->m_values, property, 0.0);
+}
+
+/*!
+ Returns the given \a property's step value.
+
+ The step is typically used to increment or decrement a property value while pressing an arrow key.
+
+ \sa setSingleStep()
+*/
+double QtDoublePropertyManager::singleStep(const QtProperty *property) const
+{
+ return getData<double>(d_ptr->m_values, &QtDoublePropertyManagerPrivate::Data::singleStep, property, 0);
+}
+
+/*!
+ Returns the given \a property's precision, in decimals.
+
+ \sa setDecimals()
+*/
+int QtDoublePropertyManager::decimals(const QtProperty *property) const
+{
+ return getData<int>(d_ptr->m_values, &QtDoublePropertyManagerPrivate::Data::decimals, property, 0);
+}
+
+/*!
+ \reimp
+*/
+QString QtDoublePropertyManager::valueText(const QtProperty *property) const
+{
+ const QtDoublePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+ return QString::number(it.value().val, 'f', it.value().decimals);
+}
+
+/*!
+ \fn void QtDoublePropertyManager::setValue(QtProperty *property, double value)
+
+ Sets the value of the given \a property to \a value.
+
+ If the specified \a value is not valid according to the given
+ \a property's range, the \a value is adjusted to the nearest valid value
+ within the range.
+
+ \sa value(), setRange(), valueChanged()
+*/
+void QtDoublePropertyManager::setValue(QtProperty *property, double val)
+{
+ void (QtDoublePropertyManagerPrivate::*setSubPropertyValue)(QtProperty *, double) = 0;
+ setValueInRange<double, QtDoublePropertyManagerPrivate, QtDoublePropertyManager, double>(this, d_ptr.data(),
+ &QtDoublePropertyManager::propertyChanged,
+ &QtDoublePropertyManager::valueChanged,
+ property, val, setSubPropertyValue);
+}
+
+/*!
+ Sets the step value for the given \a property to \a step.
+
+ The step is typically used to increment or decrement a property value while pressing an arrow key.
+
+ \sa singleStep()
+*/
+void QtDoublePropertyManager::setSingleStep(QtProperty *property, double step)
+{
+ const QtDoublePropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ QtDoublePropertyManagerPrivate::Data data = it.value();
+
+ if (step < 0)
+ step = 0;
+
+ if (data.singleStep == step)
+ return;
+
+ data.singleStep = step;
+
+ it.value() = data;
+
+ emit singleStepChanged(property, data.singleStep);
+}
+
+/*!
+ \fn void QtDoublePropertyManager::setDecimals(QtProperty *property, int prec)
+
+ Sets the precision of the given \a property to \a prec.
+
+ The valid decimal range is 0-13. The default is 2.
+
+ \sa decimals()
+*/
+void QtDoublePropertyManager::setDecimals(QtProperty *property, int prec)
+{
+ const QtDoublePropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ QtDoublePropertyManagerPrivate::Data data = it.value();
+
+ if (prec > 13)
+ prec = 13;
+ else if (prec < 0)
+ prec = 0;
+
+ if (data.decimals == prec)
+ return;
+
+ data.decimals = prec;
+
+ it.value() = data;
+
+ emit decimalsChanged(property, data.decimals);
+}
+
+/*!
+ Sets the minimum value for the given \a property to \a minVal.
+
+ When setting the minimum value, the maximum and current values are
+ adjusted if necessary (ensuring that the range remains valid and
+ that the current value is within in the range).
+
+ \sa minimum(), setRange(), rangeChanged()
+*/
+void QtDoublePropertyManager::setMinimum(QtProperty *property, double minVal)
+{
+ setMinimumValue<double, QtDoublePropertyManagerPrivate, QtDoublePropertyManager, double, QtDoublePropertyManagerPrivate::Data>(this, d_ptr.data(),
+ &QtDoublePropertyManager::propertyChanged,
+ &QtDoublePropertyManager::valueChanged,
+ &QtDoublePropertyManager::rangeChanged,
+ property, minVal);
+}
+
+/*!
+ Sets the maximum value for the given \a property to \a maxVal.
+
+ When setting the maximum value, the minimum and current values are
+ adjusted if necessary (ensuring that the range remains valid and
+ that the current value is within in the range).
+
+ \sa maximum(), setRange(), rangeChanged()
+*/
+void QtDoublePropertyManager::setMaximum(QtProperty *property, double maxVal)
+{
+ setMaximumValue<double, QtDoublePropertyManagerPrivate, QtDoublePropertyManager, double, QtDoublePropertyManagerPrivate::Data>(this, d_ptr.data(),
+ &QtDoublePropertyManager::propertyChanged,
+ &QtDoublePropertyManager::valueChanged,
+ &QtDoublePropertyManager::rangeChanged,
+ property, maxVal);
+}
+
+/*!
+ \fn void QtDoublePropertyManager::setRange(QtProperty *property, double minimum, double maximum)
+
+ Sets the range of valid values.
+
+ This is a convenience function defining the range of valid values
+ in one go; setting the \a minimum and \a maximum values for the
+ given \a property with a single function call.
+
+ When setting a new range, the current value is adjusted if
+ necessary (ensuring that the value remains within range).
+
+ \sa setMinimum(), setMaximum(), rangeChanged()
+*/
+void QtDoublePropertyManager::setRange(QtProperty *property, double minVal, double maxVal)
+{
+ void (QtDoublePropertyManagerPrivate::*setSubPropertyRange)(QtProperty *, double, double, double) = 0;
+ setBorderValues<double, QtDoublePropertyManagerPrivate, QtDoublePropertyManager, double>(this, d_ptr.data(),
+ &QtDoublePropertyManager::propertyChanged,
+ &QtDoublePropertyManager::valueChanged,
+ &QtDoublePropertyManager::rangeChanged,
+ property, minVal, maxVal, setSubPropertyRange);
+}
+
+/*!
+ \reimp
+*/
+void QtDoublePropertyManager::initializeProperty(QtProperty *property)
+{
+ d_ptr->m_values[property] = QtDoublePropertyManagerPrivate::Data();
+}
+
+/*!
+ \reimp
+*/
+void QtDoublePropertyManager::uninitializeProperty(QtProperty *property)
+{
+ d_ptr->m_values.remove(property);
+}
+
+// QtStringPropertyManager
+
+class QtStringPropertyManagerPrivate
+{
+ QtStringPropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtStringPropertyManager)
+public:
+
+ struct Data
+ {
+ Data() : regExp(QString(QLatin1Char('*')), Qt::CaseSensitive, QRegExp::Wildcard)
+ {
+ }
+ QString val;
+ QRegExp regExp;
+ };
+
+ typedef QMap<const QtProperty *, Data> PropertyValueMap;
+ QMap<const QtProperty *, Data> m_values;
+};
+
+/*!
+ \class QtStringPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtStringPropertyManager provides and manages QString properties.
+
+ A string property's value can be retrieved using the value()
+ function, and set using the setValue() slot.
+
+ The current value can be checked against a regular expression. To
+ set the regular expression use the setRegExp() slot, use the
+ regExp() function to retrieve the currently set expression.
+
+ In addition, QtStringPropertyManager provides the valueChanged() signal
+ which is emitted whenever a property created by this manager
+ changes, and the regExpChanged() signal which is emitted whenever
+ such a property changes its currently set regular expression.
+
+ \sa QtAbstractPropertyManager, QtLineEditFactory
+*/
+
+/*!
+ \fn void QtStringPropertyManager::valueChanged(QtProperty *property, const QString &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the
+ new \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ \fn void QtStringPropertyManager::regExpChanged(QtProperty *property, const QRegExp &regExp)
+
+ This signal is emitted whenever a property created by this manager
+ changes its currenlty set regular expression, passing a pointer to
+ the \a property and the new \a regExp as parameters.
+
+ \sa setRegExp()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtStringPropertyManager::QtStringPropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtStringPropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtStringPropertyManager::~QtStringPropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given property is not managed by this manager, this
+ function returns an empty string.
+
+ \sa setValue()
+*/
+QString QtStringPropertyManager::value(const QtProperty *property) const
+{
+ return getValue<QString>(d_ptr->m_values, property);
+}
+
+/*!
+ Returns the given \a property's currently set regular expression.
+
+ If the given \a property is not managed by this manager, this
+ function returns an empty expression.
+
+ \sa setRegExp()
+*/
+QRegExp QtStringPropertyManager::regExp(const QtProperty *property) const
+{
+ return getData<QRegExp>(d_ptr->m_values, &QtStringPropertyManagerPrivate::Data::regExp, property, QRegExp());
+}
+
+/*!
+ \reimp
+*/
+QString QtStringPropertyManager::valueText(const QtProperty *property) const
+{
+ const QtStringPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+ return it.value().val;
+}
+
+/*!
+ \fn void QtStringPropertyManager::setValue(QtProperty *property, const QString &value)
+
+ Sets the value of the given \a property to \a value.
+
+ If the specified \a value doesn't match the given \a property's
+ regular expression, this function does nothing.
+
+ \sa value(), setRegExp(), valueChanged()
+*/
+void QtStringPropertyManager::setValue(QtProperty *property, const QString &val)
+{
+ const QtStringPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ QtStringPropertyManagerPrivate::Data data = it.value();
+
+ if (data.val == val)
+ return;
+
+ if (data.regExp.isValid() && !data.regExp.exactMatch(val))
+ return;
+
+ data.val = val;
+
+ it.value() = data;
+
+ emit propertyChanged(property);
+ emit valueChanged(property, data.val);
+}
+
+/*!
+ Sets the regular expression of the given \a property to \a regExp.
+
+ \sa regExp(), setValue(), regExpChanged()
+*/
+void QtStringPropertyManager::setRegExp(QtProperty *property, const QRegExp &regExp)
+{
+ const QtStringPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ QtStringPropertyManagerPrivate::Data data = it.value() ;
+
+ if (data.regExp == regExp)
+ return;
+
+ data.regExp = regExp;
+
+ it.value() = data;
+
+ emit regExpChanged(property, data.regExp);
+}
+
+/*!
+ \reimp
+*/
+void QtStringPropertyManager::initializeProperty(QtProperty *property)
+{
+ d_ptr->m_values[property] = QtStringPropertyManagerPrivate::Data();
+}
+
+/*!
+ \reimp
+*/
+void QtStringPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ d_ptr->m_values.remove(property);
+}
+
+// QtBoolPropertyManager
+// Return an icon containing a check box indicator
+static QIcon drawCheckBox(bool value)
+{
+ QStyleOptionButton opt;
+ opt.state |= value ? QStyle::State_On : QStyle::State_Off;
+ opt.state |= QStyle::State_Enabled;
+ const QStyle *style = QApplication::style();
+ // Figure out size of an indicator and make sure it is not scaled down in a list view item
+ // by making the pixmap as big as a list view icon and centering the indicator in it.
+ // (if it is smaller, it can't be helped)
+ const int indicatorWidth = style->pixelMetric(QStyle::PM_IndicatorWidth, &opt);
+ const int indicatorHeight = style->pixelMetric(QStyle::PM_IndicatorHeight, &opt);
+ const int listViewIconSize = indicatorWidth;
+ const int pixmapWidth = indicatorWidth;
+ const int pixmapHeight = qMax(indicatorHeight, listViewIconSize);
+
+ opt.rect = QRect(0, 0, indicatorWidth, indicatorHeight);
+ QPixmap pixmap = QPixmap(pixmapWidth, pixmapHeight);
+ pixmap.fill(Qt::transparent);
+ {
+ // Center?
+ const int xoff = (pixmapWidth > indicatorWidth) ? (pixmapWidth - indicatorWidth) / 2 : 0;
+ const int yoff = (pixmapHeight > indicatorHeight) ? (pixmapHeight - indicatorHeight) / 2 : 0;
+ QPainter painter(&pixmap);
+ painter.translate(xoff, yoff);
+ style->drawPrimitive(QStyle::PE_IndicatorCheckBox, &opt, &painter);
+ }
+ return QIcon(pixmap);
+}
+
+class QtBoolPropertyManagerPrivate
+{
+ QtBoolPropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtBoolPropertyManager)
+public:
+ QtBoolPropertyManagerPrivate();
+
+ QMap<const QtProperty *, bool> m_values;
+ const QIcon m_checkedIcon;
+ const QIcon m_uncheckedIcon;
+};
+
+QtBoolPropertyManagerPrivate::QtBoolPropertyManagerPrivate() :
+ m_checkedIcon(drawCheckBox(true)),
+ m_uncheckedIcon(drawCheckBox(false))
+{
+}
+
+/*!
+ \class QtBoolPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtBoolPropertyManager class provides and manages boolean properties.
+
+ The property's value can be retrieved using the value() function,
+ and set using the setValue() slot.
+
+ In addition, QtBoolPropertyManager provides the valueChanged() signal
+ which is emitted whenever a property created by this manager
+ changes.
+
+ \sa QtAbstractPropertyManager, QtCheckBoxFactory
+*/
+
+/*!
+ \fn void QtBoolPropertyManager::valueChanged(QtProperty *property, bool value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the
+ new \a value as parameters.
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtBoolPropertyManager::QtBoolPropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtBoolPropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtBoolPropertyManager::~QtBoolPropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given \a property is not managed by \e this manager, this
+ function returns false.
+
+ \sa setValue()
+*/
+bool QtBoolPropertyManager::value(const QtProperty *property) const
+{
+ return d_ptr->m_values.value(property, false);
+}
+
+/*!
+ \reimp
+*/
+QString QtBoolPropertyManager::valueText(const QtProperty *property) const
+{
+ const QMap<const QtProperty *, bool>::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+
+ static const QString trueText = tr("True");
+ static const QString falseText = tr("False");
+ return it.value() ? trueText : falseText;
+}
+
+/*!
+ \reimp
+*/
+QIcon QtBoolPropertyManager::valueIcon(const QtProperty *property) const
+{
+ const QMap<const QtProperty *, bool>::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QIcon();
+
+ return it.value() ? d_ptr->m_checkedIcon : d_ptr->m_uncheckedIcon;
+}
+
+/*!
+ \fn void QtBoolPropertyManager::setValue(QtProperty *property, bool value)
+
+ Sets the value of the given \a property to \a value.
+
+ \sa value()
+*/
+void QtBoolPropertyManager::setValue(QtProperty *property, bool val)
+{
+ setSimpleValue<bool, bool, QtBoolPropertyManager>(d_ptr->m_values, this,
+ &QtBoolPropertyManager::propertyChanged,
+ &QtBoolPropertyManager::valueChanged,
+ property, val);
+}
+
+/*!
+ \reimp
+*/
+void QtBoolPropertyManager::initializeProperty(QtProperty *property)
+{
+ d_ptr->m_values[property] = false;
+}
+
+/*!
+ \reimp
+*/
+void QtBoolPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ d_ptr->m_values.remove(property);
+}
+
+// QtDatePropertyManager
+
+class QtDatePropertyManagerPrivate
+{
+ QtDatePropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtDatePropertyManager)
+public:
+ explicit QtDatePropertyManagerPrivate(QtDatePropertyManager *q);
+
+ struct Data
+ {
+ Data() : val(QDate::currentDate()), minVal(QDate(1752, 9, 14)),
+ maxVal(QDate(7999, 12, 31)) {}
+ QDate val;
+ QDate minVal;
+ QDate maxVal;
+ QDate minimumValue() const { return minVal; }
+ QDate maximumValue() const { return maxVal; }
+ void setMinimumValue(const QDate &newMinVal) { setSimpleMinimumData(this, newMinVal); }
+ void setMaximumValue(const QDate &newMaxVal) { setSimpleMaximumData(this, newMaxVal); }
+ };
+
+ QString m_format;
+
+ typedef QMap<const QtProperty *, Data> PropertyValueMap;
+ QMap<const QtProperty *, Data> m_values;
+};
+
+QtDatePropertyManagerPrivate::QtDatePropertyManagerPrivate(QtDatePropertyManager *q) :
+ q_ptr(q),
+ m_format(QtPropertyBrowserUtils::dateFormat())
+{
+}
+
+/*!
+ \class QtDatePropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtDatePropertyManager provides and manages QDate properties.
+
+ A date property has a current value, and a range specifying the
+ valid dates. The range is defined by a minimum and a maximum
+ value.
+
+ The property's values can be retrieved using the minimum(),
+ maximum() and value() functions, and can be set using the
+ setMinimum(), setMaximum() and setValue() slots. Alternatively,
+ the range can be defined in one go using the setRange() slot.
+
+ In addition, QtDatePropertyManager provides the valueChanged() signal
+ which is emitted whenever a property created by this manager
+ changes, and the rangeChanged() signal which is emitted whenever
+ such a property changes its range of valid dates.
+
+ \sa QtAbstractPropertyManager, QtDateEditFactory, QtDateTimePropertyManager
+*/
+
+/*!
+ \fn void QtDatePropertyManager::valueChanged(QtProperty *property, const QDate &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the new
+ \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ \fn void QtDatePropertyManager::rangeChanged(QtProperty *property, const QDate &minimum, const QDate &maximum)
+
+ This signal is emitted whenever a property created by this manager
+ changes its range of valid dates, passing a pointer to the \a
+ property and the new \a minimum and \a maximum dates.
+
+ \sa setRange()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtDatePropertyManager::QtDatePropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtDatePropertyManagerPrivate(this))
+{
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtDatePropertyManager::~QtDatePropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given \a property is not managed by \e this manager, this
+ function returns an invalid date.
+
+ \sa setValue()
+*/
+QDate QtDatePropertyManager::value(const QtProperty *property) const
+{
+ return getValue<QDate>(d_ptr->m_values, property);
+}
+
+/*!
+ Returns the given \a property's minimum date.
+
+ \sa maximum(), setRange()
+*/
+QDate QtDatePropertyManager::minimum(const QtProperty *property) const
+{
+ return getMinimum<QDate>(d_ptr->m_values, property);
+}
+
+/*!
+ Returns the given \a property's maximum date.
+
+ \sa minimum(), setRange()
+*/
+QDate QtDatePropertyManager::maximum(const QtProperty *property) const
+{
+ return getMaximum<QDate>(d_ptr->m_values, property);
+}
+
+/*!
+ \reimp
+*/
+QString QtDatePropertyManager::valueText(const QtProperty *property) const
+{
+ const QtDatePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+ return it.value().val.toString(d_ptr->m_format);
+}
+
+/*!
+ \fn void QtDatePropertyManager::setValue(QtProperty *property, const QDate &value)
+
+ Sets the value of the given \a property to \a value.
+
+ If the specified \a value is not a valid date according to the
+ given \a property's range, the value is adjusted to the nearest
+ valid value within the range.
+
+ \sa value(), setRange(), valueChanged()
+*/
+void QtDatePropertyManager::setValue(QtProperty *property, const QDate &val)
+{
+ void (QtDatePropertyManagerPrivate::*setSubPropertyValue)(QtProperty *, const QDate &) = 0;
+ setValueInRange<const QDate &, QtDatePropertyManagerPrivate, QtDatePropertyManager, const QDate>(this, d_ptr.data(),
+ &QtDatePropertyManager::propertyChanged,
+ &QtDatePropertyManager::valueChanged,
+ property, val, setSubPropertyValue);
+}
+
+/*!
+ Sets the minimum value for the given \a property to \a minVal.
+
+ When setting the minimum value, the maximum and current values are
+ adjusted if necessary (ensuring that the range remains valid and
+ that the current value is within in the range).
+
+ \sa minimum(), setRange()
+*/
+void QtDatePropertyManager::setMinimum(QtProperty *property, const QDate &minVal)
+{
+ setMinimumValue<const QDate &, QtDatePropertyManagerPrivate, QtDatePropertyManager, QDate, QtDatePropertyManagerPrivate::Data>(this, d_ptr.data(),
+ &QtDatePropertyManager::propertyChanged,
+ &QtDatePropertyManager::valueChanged,
+ &QtDatePropertyManager::rangeChanged,
+ property, minVal);
+}
+
+/*!
+ Sets the maximum value for the given \a property to \a maxVal.
+
+ When setting the maximum value, the minimum and current
+ values are adjusted if necessary (ensuring that the range remains
+ valid and that the current value is within in the range).
+
+ \sa maximum(), setRange()
+*/
+void QtDatePropertyManager::setMaximum(QtProperty *property, const QDate &maxVal)
+{
+ setMaximumValue<const QDate &, QtDatePropertyManagerPrivate, QtDatePropertyManager, QDate, QtDatePropertyManagerPrivate::Data>(this, d_ptr.data(),
+ &QtDatePropertyManager::propertyChanged,
+ &QtDatePropertyManager::valueChanged,
+ &QtDatePropertyManager::rangeChanged,
+ property, maxVal);
+}
+
+/*!
+ \fn void QtDatePropertyManager::setRange(QtProperty *property, const QDate &minimum, const QDate &maximum)
+
+ Sets the range of valid dates.
+
+ This is a convenience function defining the range of valid dates
+ in one go; setting the \a minimum and \a maximum values for the
+ given \a property with a single function call.
+
+ When setting a new date range, the current value is adjusted if
+ necessary (ensuring that the value remains in date range).
+
+ \sa setMinimum(), setMaximum(), rangeChanged()
+*/
+void QtDatePropertyManager::setRange(QtProperty *property, const QDate &minVal, const QDate &maxVal)
+{
+ void (QtDatePropertyManagerPrivate::*setSubPropertyRange)(QtProperty *, const QDate &,
+ const QDate &, const QDate &) = 0;
+ setBorderValues<const QDate &, QtDatePropertyManagerPrivate, QtDatePropertyManager, QDate>(this, d_ptr.data(),
+ &QtDatePropertyManager::propertyChanged,
+ &QtDatePropertyManager::valueChanged,
+ &QtDatePropertyManager::rangeChanged,
+ property, minVal, maxVal, setSubPropertyRange);
+}
+
+/*!
+ \reimp
+*/
+void QtDatePropertyManager::initializeProperty(QtProperty *property)
+{
+ d_ptr->m_values[property] = QtDatePropertyManagerPrivate::Data();
+}
+
+/*!
+ \reimp
+*/
+void QtDatePropertyManager::uninitializeProperty(QtProperty *property)
+{
+ d_ptr->m_values.remove(property);
+}
+
+// QtTimePropertyManager
+
+class QtTimePropertyManagerPrivate
+{
+ QtTimePropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtTimePropertyManager)
+public:
+ explicit QtTimePropertyManagerPrivate(QtTimePropertyManager *q);
+
+ const QString m_format;
+
+ typedef QMap<const QtProperty *, QTime> PropertyValueMap;
+ PropertyValueMap m_values;
+};
+
+QtTimePropertyManagerPrivate::QtTimePropertyManagerPrivate(QtTimePropertyManager *q) :
+ q_ptr(q),
+ m_format(QtPropertyBrowserUtils::timeFormat())
+{
+}
+
+/*!
+ \class QtTimePropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtTimePropertyManager provides and manages QTime properties.
+
+ A time property's value can be retrieved using the value()
+ function, and set using the setValue() slot.
+
+ In addition, QtTimePropertyManager provides the valueChanged() signal
+ which is emitted whenever a property created by this manager
+ changes.
+
+ \sa QtAbstractPropertyManager, QtTimeEditFactory
+*/
+
+/*!
+ \fn void QtTimePropertyManager::valueChanged(QtProperty *property, const QTime &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the
+ new \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtTimePropertyManager::QtTimePropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtTimePropertyManagerPrivate(this))
+{
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtTimePropertyManager::~QtTimePropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given property is not managed by this manager, this
+ function returns an invalid time object.
+
+ \sa setValue()
+*/
+QTime QtTimePropertyManager::value(const QtProperty *property) const
+{
+ return d_ptr->m_values.value(property, QTime());
+}
+
+/*!
+ \reimp
+*/
+QString QtTimePropertyManager::valueText(const QtProperty *property) const
+{
+ const QtTimePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+ return it.value().toString(d_ptr->m_format);
+}
+
+/*!
+ \fn void QtTimePropertyManager::setValue(QtProperty *property, const QTime &value)
+
+ Sets the value of the given \a property to \a value.
+
+ \sa value(), valueChanged()
+*/
+void QtTimePropertyManager::setValue(QtProperty *property, const QTime &val)
+{
+ setSimpleValue<const QTime &, QTime, QtTimePropertyManager>(d_ptr->m_values, this,
+ &QtTimePropertyManager::propertyChanged,
+ &QtTimePropertyManager::valueChanged,
+ property, val);
+}
+
+/*!
+ \reimp
+*/
+void QtTimePropertyManager::initializeProperty(QtProperty *property)
+{
+ d_ptr->m_values[property] = QTime::currentTime();
+}
+
+/*!
+ \reimp
+*/
+void QtTimePropertyManager::uninitializeProperty(QtProperty *property)
+{
+ d_ptr->m_values.remove(property);
+}
+
+// QtDateTimePropertyManager
+
+class QtDateTimePropertyManagerPrivate
+{
+ QtDateTimePropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtDateTimePropertyManager)
+public:
+ explicit QtDateTimePropertyManagerPrivate(QtDateTimePropertyManager *q);
+
+ const QString m_format;
+
+ typedef QMap<const QtProperty *, QDateTime> PropertyValueMap;
+ PropertyValueMap m_values;
+};
+
+QtDateTimePropertyManagerPrivate::QtDateTimePropertyManagerPrivate(QtDateTimePropertyManager *q) :
+ q_ptr(q),
+ m_format(QtPropertyBrowserUtils::dateTimeFormat())
+{
+}
+
+/*! \class QtDateTimePropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtDateTimePropertyManager provides and manages QDateTime properties.
+
+ A date and time property has a current value which can be
+ retrieved using the value() function, and set using the setValue()
+ slot. In addition, QtDateTimePropertyManager provides the
+ valueChanged() signal which is emitted whenever a property created
+ by this manager changes.
+
+ \sa QtAbstractPropertyManager, QtDateTimeEditFactory, QtDatePropertyManager
+*/
+
+/*!
+ \fn void QtDateTimePropertyManager::valueChanged(QtProperty *property, const QDateTime &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the new
+ \a value as parameters.
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtDateTimePropertyManager::QtDateTimePropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtDateTimePropertyManagerPrivate(this))
+{
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtDateTimePropertyManager::~QtDateTimePropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given \a property is not managed by this manager, this
+ function returns an invalid QDateTime object.
+
+ \sa setValue()
+*/
+QDateTime QtDateTimePropertyManager::value(const QtProperty *property) const
+{
+ return d_ptr->m_values.value(property, QDateTime());
+}
+
+/*!
+ \reimp
+*/
+QString QtDateTimePropertyManager::valueText(const QtProperty *property) const
+{
+ const QtDateTimePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+ return it.value().toString(d_ptr->m_format);
+}
+
+/*!
+ \fn void QtDateTimePropertyManager::setValue(QtProperty *property, const QDateTime &value)
+
+ Sets the value of the given \a property to \a value.
+
+ \sa value(), valueChanged()
+*/
+void QtDateTimePropertyManager::setValue(QtProperty *property, const QDateTime &val)
+{
+ setSimpleValue<const QDateTime &, QDateTime, QtDateTimePropertyManager>(d_ptr->m_values, this,
+ &QtDateTimePropertyManager::propertyChanged,
+ &QtDateTimePropertyManager::valueChanged,
+ property, val);
+}
+
+/*!
+ \reimp
+*/
+void QtDateTimePropertyManager::initializeProperty(QtProperty *property)
+{
+ d_ptr->m_values[property] = QDateTime::currentDateTime();
+}
+
+/*!
+ \reimp
+*/
+void QtDateTimePropertyManager::uninitializeProperty(QtProperty *property)
+{
+ d_ptr->m_values.remove(property);
+}
+
+// QtKeySequencePropertyManager
+
+class QtKeySequencePropertyManagerPrivate
+{
+ QtKeySequencePropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtKeySequencePropertyManager)
+public:
+
+ QString m_format;
+
+ typedef QMap<const QtProperty *, QKeySequence> PropertyValueMap;
+ PropertyValueMap m_values;
+};
+
+/*! \class QtKeySequencePropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtKeySequencePropertyManager provides and manages QKeySequence properties.
+
+ A key sequence's value can be retrieved using the value()
+ function, and set using the setValue() slot.
+
+ In addition, QtKeySequencePropertyManager provides the valueChanged() signal
+ which is emitted whenever a property created by this manager
+ changes.
+
+ \sa QtAbstractPropertyManager
+*/
+
+/*!
+ \fn void QtKeySequencePropertyManager::valueChanged(QtProperty *property, const QKeySequence &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the new
+ \a value as parameters.
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtKeySequencePropertyManager::QtKeySequencePropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtKeySequencePropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtKeySequencePropertyManager::~QtKeySequencePropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given \a property is not managed by this manager, this
+ function returns an empty QKeySequence object.
+
+ \sa setValue()
+*/
+QKeySequence QtKeySequencePropertyManager::value(const QtProperty *property) const
+{
+ return d_ptr->m_values.value(property, QKeySequence());
+}
+
+/*!
+ \reimp
+*/
+QString QtKeySequencePropertyManager::valueText(const QtProperty *property) const
+{
+ const QtKeySequencePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+ return it.value().toString(QKeySequence::NativeText);
+}
+
+/*!
+ \fn void QtKeySequencePropertyManager::setValue(QtProperty *property, const QKeySequence &value)
+
+ Sets the value of the given \a property to \a value.
+
+ \sa value(), valueChanged()
+*/
+void QtKeySequencePropertyManager::setValue(QtProperty *property, const QKeySequence &val)
+{
+ setSimpleValue<const QKeySequence &, QKeySequence, QtKeySequencePropertyManager>(d_ptr->m_values, this,
+ &QtKeySequencePropertyManager::propertyChanged,
+ &QtKeySequencePropertyManager::valueChanged,
+ property, val);
+}
+
+/*!
+ \reimp
+*/
+void QtKeySequencePropertyManager::initializeProperty(QtProperty *property)
+{
+ d_ptr->m_values[property] = QKeySequence();
+}
+
+/*!
+ \reimp
+*/
+void QtKeySequencePropertyManager::uninitializeProperty(QtProperty *property)
+{
+ d_ptr->m_values.remove(property);
+}
+
+// QtCharPropertyManager
+
+class QtCharPropertyManagerPrivate
+{
+ QtCharPropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtCharPropertyManager)
+public:
+
+ typedef QMap<const QtProperty *, QChar> PropertyValueMap;
+ PropertyValueMap m_values;
+};
+
+/*! \class QtCharPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtCharPropertyManager provides and manages QChar properties.
+
+ A char's value can be retrieved using the value()
+ function, and set using the setValue() slot.
+
+ In addition, QtCharPropertyManager provides the valueChanged() signal
+ which is emitted whenever a property created by this manager
+ changes.
+
+ \sa QtAbstractPropertyManager
+*/
+
+/*!
+ \fn void QtCharPropertyManager::valueChanged(QtProperty *property, const QChar &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the new
+ \a value as parameters.
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtCharPropertyManager::QtCharPropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtCharPropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtCharPropertyManager::~QtCharPropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given \a property is not managed by this manager, this
+ function returns an null QChar object.
+
+ \sa setValue()
+*/
+QChar QtCharPropertyManager::value(const QtProperty *property) const
+{
+ return d_ptr->m_values.value(property, QChar());
+}
+
+/*!
+ \reimp
+*/
+QString QtCharPropertyManager::valueText(const QtProperty *property) const
+{
+ const QtCharPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+ const QChar c = it.value();
+ return c.isNull() ? QString() : QString(c);
+}
+
+/*!
+ \fn void QtCharPropertyManager::setValue(QtProperty *property, const QChar &value)
+
+ Sets the value of the given \a property to \a value.
+
+ \sa value(), valueChanged()
+*/
+void QtCharPropertyManager::setValue(QtProperty *property, const QChar &val)
+{
+ setSimpleValue<const QChar &, QChar, QtCharPropertyManager>(d_ptr->m_values, this,
+ &QtCharPropertyManager::propertyChanged,
+ &QtCharPropertyManager::valueChanged,
+ property, val);
+}
+
+/*!
+ \reimp
+*/
+void QtCharPropertyManager::initializeProperty(QtProperty *property)
+{
+ d_ptr->m_values[property] = QChar();
+}
+
+/*!
+ \reimp
+*/
+void QtCharPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ d_ptr->m_values.remove(property);
+}
+
+// QtLocalePropertyManager
+
+class QtLocalePropertyManagerPrivate
+{
+ QtLocalePropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtLocalePropertyManager)
+public:
+
+ QtLocalePropertyManagerPrivate();
+
+ void slotEnumChanged(QtProperty *property, int value);
+ void slotPropertyDestroyed(QtProperty *property);
+
+ typedef QMap<const QtProperty *, QLocale> PropertyValueMap;
+ PropertyValueMap m_values;
+
+ QtEnumPropertyManager *m_enumPropertyManager;
+
+ QMap<const QtProperty *, QtProperty *> m_propertyToLanguage;
+ QMap<const QtProperty *, QtProperty *> m_propertyToCountry;
+
+ QMap<const QtProperty *, QtProperty *> m_languageToProperty;
+ QMap<const QtProperty *, QtProperty *> m_countryToProperty;
+};
+
+QtLocalePropertyManagerPrivate::QtLocalePropertyManagerPrivate()
+{
+}
+
+void QtLocalePropertyManagerPrivate::slotEnumChanged(QtProperty *property, int value)
+{
+ if (QtProperty *prop = m_languageToProperty.value(property, 0)) {
+ const QLocale loc = m_values[prop];
+ QLocale::Language newLanguage = loc.language();
+ QLocale::Country newCountry = loc.country();
+ metaEnumProvider()->indexToLocale(value, 0, &newLanguage, 0);
+ QLocale newLoc(newLanguage, newCountry);
+ q_ptr->setValue(prop, newLoc);
+ } else if (QtProperty *prop = m_countryToProperty.value(property, 0)) {
+ const QLocale loc = m_values[prop];
+ QLocale::Language newLanguage = loc.language();
+ QLocale::Country newCountry = loc.country();
+ metaEnumProvider()->indexToLocale(m_enumPropertyManager->value(m_propertyToLanguage.value(prop)), value, &newLanguage, &newCountry);
+ QLocale newLoc(newLanguage, newCountry);
+ q_ptr->setValue(prop, newLoc);
+ }
+}
+
+void QtLocalePropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property)
+{
+ if (QtProperty *subProp = m_languageToProperty.value(property, 0)) {
+ m_propertyToLanguage[subProp] = 0;
+ m_languageToProperty.remove(property);
+ } else if (QtProperty *subProp = m_countryToProperty.value(property, 0)) {
+ m_propertyToCountry[subProp] = 0;
+ m_countryToProperty.remove(property);
+ }
+}
+
+/*!
+ \class QtLocalePropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtLocalePropertyManager provides and manages QLocale properties.
+
+ A locale property has nested \e language and \e country
+ subproperties. The top-level property's value can be retrieved
+ using the value() function, and set using the setValue() slot.
+
+ The subproperties are created by QtEnumPropertyManager object.
+ These submanager can be retrieved using the subEnumPropertyManager()
+ function. In order to provide editing widgets for the subproperties
+ in a property browser widget, this manager must be associated with editor factory.
+
+ In addition, QtLocalePropertyManager provides the valueChanged()
+ signal which is emitted whenever a property created by this
+ manager changes.
+
+ \sa QtAbstractPropertyManager, QtEnumPropertyManager
+*/
+
+/*!
+ \fn void QtLocalePropertyManager::valueChanged(QtProperty *property, const QLocale &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the
+ new \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtLocalePropertyManager::QtLocalePropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtLocalePropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->m_enumPropertyManager = new QtEnumPropertyManager(this);
+ connect(d_ptr->m_enumPropertyManager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotEnumChanged(QtProperty*,int)));
+
+ connect(d_ptr->m_enumPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
+ this, SLOT(slotPropertyDestroyed(QtProperty*)));
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtLocalePropertyManager::~QtLocalePropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the manager that creates the nested \e language
+ and \e country subproperties.
+
+ In order to provide editing widgets for the mentioned subproperties
+ in a property browser widget, this manager must be associated with
+ an editor factory.
+
+ \sa QtAbstractPropertyBrowser::setFactoryForManager()
+*/
+QtEnumPropertyManager *QtLocalePropertyManager::subEnumPropertyManager() const
+{
+ return d_ptr->m_enumPropertyManager;
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given property is not managed by this manager, this
+ function returns the default locale.
+
+ \sa setValue()
+*/
+QLocale QtLocalePropertyManager::value(const QtProperty *property) const
+{
+ return d_ptr->m_values.value(property, QLocale());
+}
+
+/*!
+ \reimp
+*/
+QString QtLocalePropertyManager::valueText(const QtProperty *property) const
+{
+ const QtLocalePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+
+ const QLocale loc = it.value();
+
+ int langIdx = 0;
+ int countryIdx = 0;
+ const QtMetaEnumProvider *me = metaEnumProvider();
+ me->localeToIndex(loc.language(), loc.country(), &langIdx, &countryIdx);
+ if (langIdx < 0) {
+ qWarning("QtLocalePropertyManager::valueText: Unknown language %d", loc.language());
+ return tr("<Invalid>");
+ }
+ const QString languageName = me->languageEnumNames().at(langIdx);
+ if (countryIdx < 0) {
+ qWarning("QtLocalePropertyManager::valueText: Unknown country %d for %s", loc.country(), qPrintable(languageName));
+ return languageName;
+ }
+ const QString countryName = me->countryEnumNames(loc.language()).at(countryIdx);
+ return tr("%1, %2").arg(languageName, countryName);
+}
+
+/*!
+ \fn void QtLocalePropertyManager::setValue(QtProperty *property, const QLocale &value)
+
+ Sets the value of the given \a property to \a value. Nested
+ properties are updated automatically.
+
+ \sa value(), valueChanged()
+*/
+void QtLocalePropertyManager::setValue(QtProperty *property, const QLocale &val)
+{
+ const QtLocalePropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ const QLocale loc = it.value();
+ if (loc == val)
+ return;
+
+ it.value() = val;
+
+ int langIdx = 0;
+ int countryIdx = 0;
+ metaEnumProvider()->localeToIndex(val.language(), val.country(), &langIdx, &countryIdx);
+ if (loc.language() != val.language()) {
+ d_ptr->m_enumPropertyManager->setValue(d_ptr->m_propertyToLanguage.value(property), langIdx);
+ d_ptr->m_enumPropertyManager->setEnumNames(d_ptr->m_propertyToCountry.value(property),
+ metaEnumProvider()->countryEnumNames(val.language()));
+ }
+ d_ptr->m_enumPropertyManager->setValue(d_ptr->m_propertyToCountry.value(property), countryIdx);
+
+ emit propertyChanged(property);
+ emit valueChanged(property, val);
+}
+
+/*!
+ \reimp
+*/
+void QtLocalePropertyManager::initializeProperty(QtProperty *property)
+{
+ QLocale val;
+ d_ptr->m_values[property] = val;
+
+ int langIdx = 0;
+ int countryIdx = 0;
+ metaEnumProvider()->localeToIndex(val.language(), val.country(), &langIdx, &countryIdx);
+
+ QtProperty *languageProp = d_ptr->m_enumPropertyManager->addProperty();
+ languageProp->setPropertyName(tr("Language"));
+ d_ptr->m_enumPropertyManager->setEnumNames(languageProp, metaEnumProvider()->languageEnumNames());
+ d_ptr->m_enumPropertyManager->setValue(languageProp, langIdx);
+ d_ptr->m_propertyToLanguage[property] = languageProp;
+ d_ptr->m_languageToProperty[languageProp] = property;
+ property->addSubProperty(languageProp);
+
+ QtProperty *countryProp = d_ptr->m_enumPropertyManager->addProperty();
+ countryProp->setPropertyName(tr("Country"));
+ d_ptr->m_enumPropertyManager->setEnumNames(countryProp, metaEnumProvider()->countryEnumNames(val.language()));
+ d_ptr->m_enumPropertyManager->setValue(countryProp, countryIdx);
+ d_ptr->m_propertyToCountry[property] = countryProp;
+ d_ptr->m_countryToProperty[countryProp] = property;
+ property->addSubProperty(countryProp);
+}
+
+/*!
+ \reimp
+*/
+void QtLocalePropertyManager::uninitializeProperty(QtProperty *property)
+{
+ QtProperty *languageProp = d_ptr->m_propertyToLanguage[property];
+ if (languageProp) {
+ d_ptr->m_languageToProperty.remove(languageProp);
+ delete languageProp;
+ }
+ d_ptr->m_propertyToLanguage.remove(property);
+
+ QtProperty *countryProp = d_ptr->m_propertyToCountry[property];
+ if (countryProp) {
+ d_ptr->m_countryToProperty.remove(countryProp);
+ delete countryProp;
+ }
+ d_ptr->m_propertyToCountry.remove(property);
+
+ d_ptr->m_values.remove(property);
+}
+
+// QtPointPropertyManager
+
+class QtPointPropertyManagerPrivate
+{
+ QtPointPropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtPointPropertyManager)
+public:
+
+ void slotIntChanged(QtProperty *property, int value);
+ void slotPropertyDestroyed(QtProperty *property);
+
+ typedef QMap<const QtProperty *, QPoint> PropertyValueMap;
+ PropertyValueMap m_values;
+
+ QtIntPropertyManager *m_intPropertyManager;
+
+ QMap<const QtProperty *, QtProperty *> m_propertyToX;
+ QMap<const QtProperty *, QtProperty *> m_propertyToY;
+
+ QMap<const QtProperty *, QtProperty *> m_xToProperty;
+ QMap<const QtProperty *, QtProperty *> m_yToProperty;
+};
+
+void QtPointPropertyManagerPrivate::slotIntChanged(QtProperty *property, int value)
+{
+ if (QtProperty *xprop = m_xToProperty.value(property, 0)) {
+ QPoint p = m_values[xprop];
+ p.setX(value);
+ q_ptr->setValue(xprop, p);
+ } else if (QtProperty *yprop = m_yToProperty.value(property, 0)) {
+ QPoint p = m_values[yprop];
+ p.setY(value);
+ q_ptr->setValue(yprop, p);
+ }
+}
+
+void QtPointPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property)
+{
+ if (QtProperty *pointProp = m_xToProperty.value(property, 0)) {
+ m_propertyToX[pointProp] = 0;
+ m_xToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_yToProperty.value(property, 0)) {
+ m_propertyToY[pointProp] = 0;
+ m_yToProperty.remove(property);
+ }
+}
+
+/*! \class QtPointPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtPointPropertyManager provides and manages QPoint properties.
+
+ A point property has nested \e x and \e y subproperties. The
+ top-level property's value can be retrieved using the value()
+ function, and set using the setValue() slot.
+
+ The subproperties are created by a QtIntPropertyManager object. This
+ manager can be retrieved using the subIntPropertyManager() function. In
+ order to provide editing widgets for the subproperties in a
+ property browser widget, this manager must be associated with an
+ editor factory.
+
+ In addition, QtPointPropertyManager provides the valueChanged() signal which
+ is emitted whenever a property created by this manager changes.
+
+ \sa QtAbstractPropertyManager, QtIntPropertyManager, QtPointFPropertyManager
+*/
+
+/*!
+ \fn void QtPointPropertyManager::valueChanged(QtProperty *property, const QPoint &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the
+ new \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtPointPropertyManager::QtPointPropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtPointPropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->m_intPropertyManager = new QtIntPropertyManager(this);
+ connect(d_ptr->m_intPropertyManager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotIntChanged(QtProperty*,int)));
+ connect(d_ptr->m_intPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
+ this, SLOT(slotPropertyDestroyed(QtProperty*)));
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtPointPropertyManager::~QtPointPropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the manager that creates the nested \e x and \e y
+ subproperties.
+
+ In order to provide editing widgets for the subproperties in a
+ property browser widget, this manager must be associated with an
+ editor factory.
+
+ \sa QtAbstractPropertyBrowser::setFactoryForManager()
+*/
+QtIntPropertyManager *QtPointPropertyManager::subIntPropertyManager() const
+{
+ return d_ptr->m_intPropertyManager;
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given \a property is not managed by this manager, this
+ function returns a point with coordinates (0, 0).
+
+ \sa setValue()
+*/
+QPoint QtPointPropertyManager::value(const QtProperty *property) const
+{
+ return d_ptr->m_values.value(property, QPoint());
+}
+
+/*!
+ \reimp
+*/
+QString QtPointPropertyManager::valueText(const QtProperty *property) const
+{
+ const QtPointPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+ const QPoint v = it.value();
+ return tr("(%1, %2)").arg(QString::number(v.x()))
+ .arg(QString::number(v.y()));
+}
+
+/*!
+ \fn void QtPointPropertyManager::setValue(QtProperty *property, const QPoint &value)
+
+ Sets the value of the given \a property to \a value. Nested
+ properties are updated automatically.
+
+ \sa value(), valueChanged()
+*/
+void QtPointPropertyManager::setValue(QtProperty *property, const QPoint &val)
+{
+ const QtPointPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ if (it.value() == val)
+ return;
+
+ it.value() = val;
+ d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToX[property], val.x());
+ d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToY[property], val.y());
+
+ emit propertyChanged(property);
+ emit valueChanged(property, val);
+}
+
+/*!
+ \reimp
+*/
+void QtPointPropertyManager::initializeProperty(QtProperty *property)
+{
+ d_ptr->m_values[property] = QPoint(0, 0);
+
+ QtProperty *xProp = d_ptr->m_intPropertyManager->addProperty();
+ xProp->setPropertyName(tr("X"));
+ d_ptr->m_intPropertyManager->setValue(xProp, 0);
+ d_ptr->m_propertyToX[property] = xProp;
+ d_ptr->m_xToProperty[xProp] = property;
+ property->addSubProperty(xProp);
+
+ QtProperty *yProp = d_ptr->m_intPropertyManager->addProperty();
+ yProp->setPropertyName(tr("Y"));
+ d_ptr->m_intPropertyManager->setValue(yProp, 0);
+ d_ptr->m_propertyToY[property] = yProp;
+ d_ptr->m_yToProperty[yProp] = property;
+ property->addSubProperty(yProp);
+}
+
+/*!
+ \reimp
+*/
+void QtPointPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ QtProperty *xProp = d_ptr->m_propertyToX[property];
+ if (xProp) {
+ d_ptr->m_xToProperty.remove(xProp);
+ delete xProp;
+ }
+ d_ptr->m_propertyToX.remove(property);
+
+ QtProperty *yProp = d_ptr->m_propertyToY[property];
+ if (yProp) {
+ d_ptr->m_yToProperty.remove(yProp);
+ delete yProp;
+ }
+ d_ptr->m_propertyToY.remove(property);
+
+ d_ptr->m_values.remove(property);
+}
+
+// QtPointFPropertyManager
+
+class QtPointFPropertyManagerPrivate
+{
+ QtPointFPropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtPointFPropertyManager)
+public:
+
+ struct Data
+ {
+ Data() : decimals(2) {}
+ QPointF val;
+ int decimals;
+ };
+
+ void slotDoubleChanged(QtProperty *property, double value);
+ void slotPropertyDestroyed(QtProperty *property);
+
+ typedef QMap<const QtProperty *, Data> PropertyValueMap;
+ PropertyValueMap m_values;
+
+ QtDoublePropertyManager *m_doublePropertyManager;
+
+ QMap<const QtProperty *, QtProperty *> m_propertyToX;
+ QMap<const QtProperty *, QtProperty *> m_propertyToY;
+
+ QMap<const QtProperty *, QtProperty *> m_xToProperty;
+ QMap<const QtProperty *, QtProperty *> m_yToProperty;
+};
+
+void QtPointFPropertyManagerPrivate::slotDoubleChanged(QtProperty *property, double value)
+{
+ if (QtProperty *prop = m_xToProperty.value(property, 0)) {
+ QPointF p = m_values[prop].val;
+ p.setX(value);
+ q_ptr->setValue(prop, p);
+ } else if (QtProperty *prop = m_yToProperty.value(property, 0)) {
+ QPointF p = m_values[prop].val;
+ p.setY(value);
+ q_ptr->setValue(prop, p);
+ }
+}
+
+void QtPointFPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property)
+{
+ if (QtProperty *pointProp = m_xToProperty.value(property, 0)) {
+ m_propertyToX[pointProp] = 0;
+ m_xToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_yToProperty.value(property, 0)) {
+ m_propertyToY[pointProp] = 0;
+ m_yToProperty.remove(property);
+ }
+}
+
+/*! \class QtPointFPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtPointFPropertyManager provides and manages QPointF properties.
+
+ A point property has nested \e x and \e y subproperties. The
+ top-level property's value can be retrieved using the value()
+ function, and set using the setValue() slot.
+
+ The subproperties are created by a QtDoublePropertyManager object. This
+ manager can be retrieved using the subDoublePropertyManager() function. In
+ order to provide editing widgets for the subproperties in a
+ property browser widget, this manager must be associated with an
+ editor factory.
+
+ In addition, QtPointFPropertyManager provides the valueChanged() signal which
+ is emitted whenever a property created by this manager changes.
+
+ \sa QtAbstractPropertyManager, QtDoublePropertyManager, QtPointPropertyManager
+*/
+
+/*!
+ \fn void QtPointFPropertyManager::valueChanged(QtProperty *property, const QPointF &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the
+ new \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ \fn void QtPointFPropertyManager::decimalsChanged(QtProperty *property, int prec)
+
+ This signal is emitted whenever a property created by this manager
+ changes its precision of value, passing a pointer to the
+ \a property and the new \a prec value
+
+ \sa setDecimals()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtPointFPropertyManager::QtPointFPropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtPointFPropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->m_doublePropertyManager = new QtDoublePropertyManager(this);
+ connect(d_ptr->m_doublePropertyManager, SIGNAL(valueChanged(QtProperty*,double)),
+ this, SLOT(slotDoubleChanged(QtProperty*,double)));
+ connect(d_ptr->m_doublePropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
+ this, SLOT(slotPropertyDestroyed(QtProperty*)));
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtPointFPropertyManager::~QtPointFPropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the manager that creates the nested \e x and \e y
+ subproperties.
+
+ In order to provide editing widgets for the subproperties in a
+ property browser widget, this manager must be associated with an
+ editor factory.
+
+ \sa QtAbstractPropertyBrowser::setFactoryForManager()
+*/
+QtDoublePropertyManager *QtPointFPropertyManager::subDoublePropertyManager() const
+{
+ return d_ptr->m_doublePropertyManager;
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given \a property is not managed by this manager, this
+ function returns a point with coordinates (0, 0).
+
+ \sa setValue()
+*/
+QPointF QtPointFPropertyManager::value(const QtProperty *property) const
+{
+ return getValue<QPointF>(d_ptr->m_values, property);
+}
+
+/*!
+ Returns the given \a property's precision, in decimals.
+
+ \sa setDecimals()
+*/
+int QtPointFPropertyManager::decimals(const QtProperty *property) const
+{
+ return getData<int>(d_ptr->m_values, &QtPointFPropertyManagerPrivate::Data::decimals, property, 0);
+}
+
+/*!
+ \reimp
+*/
+QString QtPointFPropertyManager::valueText(const QtProperty *property) const
+{
+ const QtPointFPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+ const QPointF v = it.value().val;
+ const int dec = it.value().decimals;
+ return tr("(%1, %2)").arg(QString::number(v.x(), 'f', dec))
+ .arg(QString::number(v.y(), 'f', dec));
+}
+
+/*!
+ \fn void QtPointFPropertyManager::setValue(QtProperty *property, const QPointF &value)
+
+ Sets the value of the given \a property to \a value. Nested
+ properties are updated automatically.
+
+ \sa value(), valueChanged()
+*/
+void QtPointFPropertyManager::setValue(QtProperty *property, const QPointF &val)
+{
+ const QtPointFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ if (it.value().val == val)
+ return;
+
+ it.value().val = val;
+ d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToX[property], val.x());
+ d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToY[property], val.y());
+
+ emit propertyChanged(property);
+ emit valueChanged(property, val);
+}
+
+/*!
+ \fn void QtPointFPropertyManager::setDecimals(QtProperty *property, int prec)
+
+ Sets the precision of the given \a property to \a prec.
+
+ The valid decimal range is 0-13. The default is 2.
+
+ \sa decimals()
+*/
+void QtPointFPropertyManager::setDecimals(QtProperty *property, int prec)
+{
+ const QtPointFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ QtPointFPropertyManagerPrivate::Data data = it.value();
+
+ if (prec > 13)
+ prec = 13;
+ else if (prec < 0)
+ prec = 0;
+
+ if (data.decimals == prec)
+ return;
+
+ data.decimals = prec;
+ d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToX[property], prec);
+ d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToY[property], prec);
+
+ it.value() = data;
+
+ emit decimalsChanged(property, data.decimals);
+}
+
+/*!
+ \reimp
+*/
+void QtPointFPropertyManager::initializeProperty(QtProperty *property)
+{
+ d_ptr->m_values[property] = QtPointFPropertyManagerPrivate::Data();
+
+ QtProperty *xProp = d_ptr->m_doublePropertyManager->addProperty();
+ xProp->setPropertyName(tr("X"));
+ d_ptr->m_doublePropertyManager->setDecimals(xProp, decimals(property));
+ d_ptr->m_doublePropertyManager->setValue(xProp, 0);
+ d_ptr->m_propertyToX[property] = xProp;
+ d_ptr->m_xToProperty[xProp] = property;
+ property->addSubProperty(xProp);
+
+ QtProperty *yProp = d_ptr->m_doublePropertyManager->addProperty();
+ yProp->setPropertyName(tr("Y"));
+ d_ptr->m_doublePropertyManager->setDecimals(yProp, decimals(property));
+ d_ptr->m_doublePropertyManager->setValue(yProp, 0);
+ d_ptr->m_propertyToY[property] = yProp;
+ d_ptr->m_yToProperty[yProp] = property;
+ property->addSubProperty(yProp);
+}
+
+/*!
+ \reimp
+*/
+void QtPointFPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ QtProperty *xProp = d_ptr->m_propertyToX[property];
+ if (xProp) {
+ d_ptr->m_xToProperty.remove(xProp);
+ delete xProp;
+ }
+ d_ptr->m_propertyToX.remove(property);
+
+ QtProperty *yProp = d_ptr->m_propertyToY[property];
+ if (yProp) {
+ d_ptr->m_yToProperty.remove(yProp);
+ delete yProp;
+ }
+ d_ptr->m_propertyToY.remove(property);
+
+ d_ptr->m_values.remove(property);
+}
+
+// QtSizePropertyManager
+
+class QtSizePropertyManagerPrivate
+{
+ QtSizePropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtSizePropertyManager)
+public:
+
+ void slotIntChanged(QtProperty *property, int value);
+ void slotPropertyDestroyed(QtProperty *property);
+ void setValue(QtProperty *property, const QSize &val);
+ void setRange(QtProperty *property,
+ const QSize &minVal, const QSize &maxVal, const QSize &val);
+
+ struct Data
+ {
+ Data() : val(QSize(0, 0)), minVal(QSize(0, 0)), maxVal(QSize(INT_MAX, INT_MAX)) {}
+ QSize val;
+ QSize minVal;
+ QSize maxVal;
+ QSize minimumValue() const { return minVal; }
+ QSize maximumValue() const { return maxVal; }
+ void setMinimumValue(const QSize &newMinVal) { setSizeMinimumData(this, newMinVal); }
+ void setMaximumValue(const QSize &newMaxVal) { setSizeMaximumData(this, newMaxVal); }
+ };
+
+ typedef QMap<const QtProperty *, Data> PropertyValueMap;
+ PropertyValueMap m_values;
+
+ QtIntPropertyManager *m_intPropertyManager;
+
+ QMap<const QtProperty *, QtProperty *> m_propertyToW;
+ QMap<const QtProperty *, QtProperty *> m_propertyToH;
+
+ QMap<const QtProperty *, QtProperty *> m_wToProperty;
+ QMap<const QtProperty *, QtProperty *> m_hToProperty;
+};
+
+void QtSizePropertyManagerPrivate::slotIntChanged(QtProperty *property, int value)
+{
+ if (QtProperty *prop = m_wToProperty.value(property, 0)) {
+ QSize s = m_values[prop].val;
+ s.setWidth(value);
+ q_ptr->setValue(prop, s);
+ } else if (QtProperty *prop = m_hToProperty.value(property, 0)) {
+ QSize s = m_values[prop].val;
+ s.setHeight(value);
+ q_ptr->setValue(prop, s);
+ }
+}
+
+void QtSizePropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property)
+{
+ if (QtProperty *pointProp = m_wToProperty.value(property, 0)) {
+ m_propertyToW[pointProp] = 0;
+ m_wToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_hToProperty.value(property, 0)) {
+ m_propertyToH[pointProp] = 0;
+ m_hToProperty.remove(property);
+ }
+}
+
+void QtSizePropertyManagerPrivate::setValue(QtProperty *property, const QSize &val)
+{
+ m_intPropertyManager->setValue(m_propertyToW.value(property), val.width());
+ m_intPropertyManager->setValue(m_propertyToH.value(property), val.height());
+}
+
+void QtSizePropertyManagerPrivate::setRange(QtProperty *property,
+ const QSize &minVal, const QSize &maxVal, const QSize &val)
+{
+ QtProperty *wProperty = m_propertyToW.value(property);
+ QtProperty *hProperty = m_propertyToH.value(property);
+ m_intPropertyManager->setRange(wProperty, minVal.width(), maxVal.width());
+ m_intPropertyManager->setValue(wProperty, val.width());
+ m_intPropertyManager->setRange(hProperty, minVal.height(), maxVal.height());
+ m_intPropertyManager->setValue(hProperty, val.height());
+}
+
+/*!
+ \class QtSizePropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtSizePropertyManager provides and manages QSize properties.
+
+ A size property has nested \e width and \e height
+ subproperties. The top-level property's value can be retrieved
+ using the value() function, and set using the setValue() slot.
+
+ The subproperties are created by a QtIntPropertyManager object. This
+ manager can be retrieved using the subIntPropertyManager() function. In
+ order to provide editing widgets for the subproperties in a
+ property browser widget, this manager must be associated with an
+ editor factory.
+
+ A size property also has a range of valid values defined by a
+ minimum size and a maximum size. These sizes can be retrieved
+ using the minimum() and the maximum() functions, and set using the
+ setMinimum() and setMaximum() slots. Alternatively, the range can
+ be defined in one go using the setRange() slot.
+
+ In addition, QtSizePropertyManager provides the valueChanged() signal
+ which is emitted whenever a property created by this manager
+ changes, and the rangeChanged() signal which is emitted whenever
+ such a property changes its range of valid sizes.
+
+ \sa QtAbstractPropertyManager, QtIntPropertyManager, QtSizeFPropertyManager
+*/
+
+/*!
+ \fn void QtSizePropertyManager::valueChanged(QtProperty *property, const QSize &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the new
+ \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ \fn void QtSizePropertyManager::rangeChanged(QtProperty *property, const QSize &minimum, const QSize &maximum)
+
+ This signal is emitted whenever a property created by this manager
+ changes its range of valid sizes, passing a pointer to the \a
+ property and the new \a minimum and \a maximum sizes.
+
+ \sa setRange()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtSizePropertyManager::QtSizePropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtSizePropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->m_intPropertyManager = new QtIntPropertyManager(this);
+ connect(d_ptr->m_intPropertyManager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotIntChanged(QtProperty*,int)));
+ connect(d_ptr->m_intPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
+ this, SLOT(slotPropertyDestroyed(QtProperty*)));
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtSizePropertyManager::~QtSizePropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the manager that creates the nested \e width and \e height
+ subproperties.
+
+ In order to provide editing widgets for the \e width and \e height
+ properties in a property browser widget, this manager must be
+ associated with an editor factory.
+
+ \sa QtAbstractPropertyBrowser::setFactoryForManager()
+*/
+QtIntPropertyManager *QtSizePropertyManager::subIntPropertyManager() const
+{
+ return d_ptr->m_intPropertyManager;
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given \a property is not managed by this manager, this
+ function returns an invalid size
+
+ \sa setValue()
+*/
+QSize QtSizePropertyManager::value(const QtProperty *property) const
+{
+ return getValue<QSize>(d_ptr->m_values, property);
+}
+
+/*!
+ Returns the given \a property's minimum size value.
+
+ \sa setMinimum(), maximum(), setRange()
+*/
+QSize QtSizePropertyManager::minimum(const QtProperty *property) const
+{
+ return getMinimum<QSize>(d_ptr->m_values, property);
+}
+
+/*!
+ Returns the given \a property's maximum size value.
+
+ \sa setMaximum(), minimum(), setRange()
+*/
+QSize QtSizePropertyManager::maximum(const QtProperty *property) const
+{
+ return getMaximum<QSize>(d_ptr->m_values, property);
+}
+
+/*!
+ \reimp
+*/
+QString QtSizePropertyManager::valueText(const QtProperty *property) const
+{
+ const QtSizePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+ const QSize v = it.value().val;
+ return tr("%1 x %2").arg(QString::number(v.width()))
+ .arg(QString::number(v.height()));
+}
+
+/*!
+ \fn void QtSizePropertyManager::setValue(QtProperty *property, const QSize &value)
+
+ Sets the value of the given \a property to \a value.
+
+ If the specified \a value is not valid according to the given \a
+ property's size range, the \a value is adjusted to the nearest
+ valid value within the size range.
+
+ \sa value(), setRange(), valueChanged()
+*/
+void QtSizePropertyManager::setValue(QtProperty *property, const QSize &val)
+{
+ setValueInRange<const QSize &, QtSizePropertyManagerPrivate, QtSizePropertyManager, const QSize>(this, d_ptr.data(),
+ &QtSizePropertyManager::propertyChanged,
+ &QtSizePropertyManager::valueChanged,
+ property, val, &QtSizePropertyManagerPrivate::setValue);
+}
+
+/*!
+ Sets the minimum size value for the given \a property to \a minVal.
+
+ When setting the minimum size value, the maximum and current
+ values are adjusted if necessary (ensuring that the size range
+ remains valid and that the current value is within the range).
+
+ \sa minimum(), setRange(), rangeChanged()
+*/
+void QtSizePropertyManager::setMinimum(QtProperty *property, const QSize &minVal)
+{
+ setBorderValue<const QSize &, QtSizePropertyManagerPrivate, QtSizePropertyManager, QSize, QtSizePropertyManagerPrivate::Data>(this, d_ptr.data(),
+ &QtSizePropertyManager::propertyChanged,
+ &QtSizePropertyManager::valueChanged,
+ &QtSizePropertyManager::rangeChanged,
+ property,
+ &QtSizePropertyManagerPrivate::Data::minimumValue,
+ &QtSizePropertyManagerPrivate::Data::setMinimumValue,
+ minVal, &QtSizePropertyManagerPrivate::setRange);
+}
+
+/*!
+ Sets the maximum size value for the given \a property to \a maxVal.
+
+ When setting the maximum size value, the minimum and current
+ values are adjusted if necessary (ensuring that the size range
+ remains valid and that the current value is within the range).
+
+ \sa maximum(), setRange(), rangeChanged()
+*/
+void QtSizePropertyManager::setMaximum(QtProperty *property, const QSize &maxVal)
+{
+ setBorderValue<const QSize &, QtSizePropertyManagerPrivate, QtSizePropertyManager, QSize, QtSizePropertyManagerPrivate::Data>(this, d_ptr.data(),
+ &QtSizePropertyManager::propertyChanged,
+ &QtSizePropertyManager::valueChanged,
+ &QtSizePropertyManager::rangeChanged,
+ property,
+ &QtSizePropertyManagerPrivate::Data::maximumValue,
+ &QtSizePropertyManagerPrivate::Data::setMaximumValue,
+ maxVal, &QtSizePropertyManagerPrivate::setRange);
+}
+
+/*!
+ \fn void QtSizePropertyManager::setRange(QtProperty *property, const QSize &minimum, const QSize &maximum)
+
+ Sets the range of valid values.
+
+ This is a convenience function defining the range of valid values
+ in one go; setting the \a minimum and \a maximum values for the
+ given \a property with a single function call.
+
+ When setting a new range, the current value is adjusted if
+ necessary (ensuring that the value remains within the range).
+
+ \sa setMinimum(), setMaximum(), rangeChanged()
+*/
+void QtSizePropertyManager::setRange(QtProperty *property, const QSize &minVal, const QSize &maxVal)
+{
+ setBorderValues<const QSize &, QtSizePropertyManagerPrivate, QtSizePropertyManager, QSize>(this, d_ptr.data(),
+ &QtSizePropertyManager::propertyChanged,
+ &QtSizePropertyManager::valueChanged,
+ &QtSizePropertyManager::rangeChanged,
+ property, minVal, maxVal, &QtSizePropertyManagerPrivate::setRange);
+}
+
+/*!
+ \reimp
+*/
+void QtSizePropertyManager::initializeProperty(QtProperty *property)
+{
+ d_ptr->m_values[property] = QtSizePropertyManagerPrivate::Data();
+
+ QtProperty *wProp = d_ptr->m_intPropertyManager->addProperty();
+ wProp->setPropertyName(tr("Width"));
+ d_ptr->m_intPropertyManager->setValue(wProp, 0);
+ d_ptr->m_intPropertyManager->setMinimum(wProp, 0);
+ d_ptr->m_propertyToW[property] = wProp;
+ d_ptr->m_wToProperty[wProp] = property;
+ property->addSubProperty(wProp);
+
+ QtProperty *hProp = d_ptr->m_intPropertyManager->addProperty();
+ hProp->setPropertyName(tr("Height"));
+ d_ptr->m_intPropertyManager->setValue(hProp, 0);
+ d_ptr->m_intPropertyManager->setMinimum(hProp, 0);
+ d_ptr->m_propertyToH[property] = hProp;
+ d_ptr->m_hToProperty[hProp] = property;
+ property->addSubProperty(hProp);
+}
+
+/*!
+ \reimp
+*/
+void QtSizePropertyManager::uninitializeProperty(QtProperty *property)
+{
+ QtProperty *wProp = d_ptr->m_propertyToW[property];
+ if (wProp) {
+ d_ptr->m_wToProperty.remove(wProp);
+ delete wProp;
+ }
+ d_ptr->m_propertyToW.remove(property);
+
+ QtProperty *hProp = d_ptr->m_propertyToH[property];
+ if (hProp) {
+ d_ptr->m_hToProperty.remove(hProp);
+ delete hProp;
+ }
+ d_ptr->m_propertyToH.remove(property);
+
+ d_ptr->m_values.remove(property);
+}
+
+// QtSizeFPropertyManager
+
+class QtSizeFPropertyManagerPrivate
+{
+ QtSizeFPropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtSizeFPropertyManager)
+public:
+
+ void slotDoubleChanged(QtProperty *property, double value);
+ void slotPropertyDestroyed(QtProperty *property);
+ void setValue(QtProperty *property, const QSizeF &val);
+ void setRange(QtProperty *property,
+ const QSizeF &minVal, const QSizeF &maxVal, const QSizeF &val);
+
+ struct Data
+ {
+ Data() : val(QSizeF(0, 0)), minVal(QSizeF(0, 0)), maxVal(QSizeF(INT_MAX, INT_MAX)), decimals(2) {}
+ QSizeF val;
+ QSizeF minVal;
+ QSizeF maxVal;
+ int decimals;
+ QSizeF minimumValue() const { return minVal; }
+ QSizeF maximumValue() const { return maxVal; }
+ void setMinimumValue(const QSizeF &newMinVal) { setSizeMinimumData(this, newMinVal); }
+ void setMaximumValue(const QSizeF &newMaxVal) { setSizeMaximumData(this, newMaxVal); }
+ };
+
+ typedef QMap<const QtProperty *, Data> PropertyValueMap;
+ PropertyValueMap m_values;
+
+ QtDoublePropertyManager *m_doublePropertyManager;
+
+ QMap<const QtProperty *, QtProperty *> m_propertyToW;
+ QMap<const QtProperty *, QtProperty *> m_propertyToH;
+
+ QMap<const QtProperty *, QtProperty *> m_wToProperty;
+ QMap<const QtProperty *, QtProperty *> m_hToProperty;
+};
+
+void QtSizeFPropertyManagerPrivate::slotDoubleChanged(QtProperty *property, double value)
+{
+ if (QtProperty *prop = m_wToProperty.value(property, 0)) {
+ QSizeF s = m_values[prop].val;
+ s.setWidth(value);
+ q_ptr->setValue(prop, s);
+ } else if (QtProperty *prop = m_hToProperty.value(property, 0)) {
+ QSizeF s = m_values[prop].val;
+ s.setHeight(value);
+ q_ptr->setValue(prop, s);
+ }
+}
+
+void QtSizeFPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property)
+{
+ if (QtProperty *pointProp = m_wToProperty.value(property, 0)) {
+ m_propertyToW[pointProp] = 0;
+ m_wToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_hToProperty.value(property, 0)) {
+ m_propertyToH[pointProp] = 0;
+ m_hToProperty.remove(property);
+ }
+}
+
+void QtSizeFPropertyManagerPrivate::setValue(QtProperty *property, const QSizeF &val)
+{
+ m_doublePropertyManager->setValue(m_propertyToW.value(property), val.width());
+ m_doublePropertyManager->setValue(m_propertyToH.value(property), val.height());
+}
+
+void QtSizeFPropertyManagerPrivate::setRange(QtProperty *property,
+ const QSizeF &minVal, const QSizeF &maxVal, const QSizeF &val)
+{
+ m_doublePropertyManager->setRange(m_propertyToW[property], minVal.width(), maxVal.width());
+ m_doublePropertyManager->setValue(m_propertyToW[property], val.width());
+ m_doublePropertyManager->setRange(m_propertyToH[property], minVal.height(), maxVal.height());
+ m_doublePropertyManager->setValue(m_propertyToH[property], val.height());
+}
+
+/*!
+ \class QtSizeFPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtSizeFPropertyManager provides and manages QSizeF properties.
+
+ A size property has nested \e width and \e height
+ subproperties. The top-level property's value can be retrieved
+ using the value() function, and set using the setValue() slot.
+
+ The subproperties are created by a QtDoublePropertyManager object. This
+ manager can be retrieved using the subDoublePropertyManager() function. In
+ order to provide editing widgets for the subproperties in a
+ property browser widget, this manager must be associated with an
+ editor factory.
+
+ A size property also has a range of valid values defined by a
+ minimum size and a maximum size. These sizes can be retrieved
+ using the minimum() and the maximum() functions, and set using the
+ setMinimum() and setMaximum() slots. Alternatively, the range can
+ be defined in one go using the setRange() slot.
+
+ In addition, QtSizeFPropertyManager provides the valueChanged() signal
+ which is emitted whenever a property created by this manager
+ changes, and the rangeChanged() signal which is emitted whenever
+ such a property changes its range of valid sizes.
+
+ \sa QtAbstractPropertyManager, QtDoublePropertyManager, QtSizePropertyManager
+*/
+
+/*!
+ \fn void QtSizeFPropertyManager::valueChanged(QtProperty *property, const QSizeF &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the new
+ \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ \fn void QtSizeFPropertyManager::rangeChanged(QtProperty *property, const QSizeF &minimum, const QSizeF &maximum)
+
+ This signal is emitted whenever a property created by this manager
+ changes its range of valid sizes, passing a pointer to the \a
+ property and the new \a minimum and \a maximum sizes.
+
+ \sa setRange()
+*/
+
+/*!
+ \fn void QtSizeFPropertyManager::decimalsChanged(QtProperty *property, int prec)
+
+ This signal is emitted whenever a property created by this manager
+ changes its precision of value, passing a pointer to the
+ \a property and the new \a prec value
+
+ \sa setDecimals()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtSizeFPropertyManager::QtSizeFPropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtSizeFPropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->m_doublePropertyManager = new QtDoublePropertyManager(this);
+ connect(d_ptr->m_doublePropertyManager, SIGNAL(valueChanged(QtProperty*,double)),
+ this, SLOT(slotDoubleChanged(QtProperty*,double)));
+ connect(d_ptr->m_doublePropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
+ this, SLOT(slotPropertyDestroyed(QtProperty*)));
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtSizeFPropertyManager::~QtSizeFPropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the manager that creates the nested \e width and \e height
+ subproperties.
+
+ In order to provide editing widgets for the \e width and \e height
+ properties in a property browser widget, this manager must be
+ associated with an editor factory.
+
+ \sa QtAbstractPropertyBrowser::setFactoryForManager()
+*/
+QtDoublePropertyManager *QtSizeFPropertyManager::subDoublePropertyManager() const
+{
+ return d_ptr->m_doublePropertyManager;
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given \a property is not managed by this manager, this
+ function returns an invalid size
+
+ \sa setValue()
+*/
+QSizeF QtSizeFPropertyManager::value(const QtProperty *property) const
+{
+ return getValue<QSizeF>(d_ptr->m_values, property);
+}
+
+/*!
+ Returns the given \a property's precision, in decimals.
+
+ \sa setDecimals()
+*/
+int QtSizeFPropertyManager::decimals(const QtProperty *property) const
+{
+ return getData<int>(d_ptr->m_values, &QtSizeFPropertyManagerPrivate::Data::decimals, property, 0);
+}
+
+/*!
+ Returns the given \a property's minimum size value.
+
+ \sa setMinimum(), maximum(), setRange()
+*/
+QSizeF QtSizeFPropertyManager::minimum(const QtProperty *property) const
+{
+ return getMinimum<QSizeF>(d_ptr->m_values, property);
+}
+
+/*!
+ Returns the given \a property's maximum size value.
+
+ \sa setMaximum(), minimum(), setRange()
+*/
+QSizeF QtSizeFPropertyManager::maximum(const QtProperty *property) const
+{
+ return getMaximum<QSizeF>(d_ptr->m_values, property);
+}
+
+/*!
+ \reimp
+*/
+QString QtSizeFPropertyManager::valueText(const QtProperty *property) const
+{
+ const QtSizeFPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+ const QSizeF v = it.value().val;
+ const int dec = it.value().decimals;
+ return tr("%1 x %2").arg(QString::number(v.width(), 'f', dec))
+ .arg(QString::number(v.height(), 'f', dec));
+}
+
+/*!
+ \fn void QtSizeFPropertyManager::setValue(QtProperty *property, const QSizeF &value)
+
+ Sets the value of the given \a property to \a value.
+
+ If the specified \a value is not valid according to the given \a
+ property's size range, the \a value is adjusted to the nearest
+ valid value within the size range.
+
+ \sa value(), setRange(), valueChanged()
+*/
+void QtSizeFPropertyManager::setValue(QtProperty *property, const QSizeF &val)
+{
+ setValueInRange<const QSizeF &, QtSizeFPropertyManagerPrivate, QtSizeFPropertyManager, QSizeF>(this, d_ptr.data(),
+ &QtSizeFPropertyManager::propertyChanged,
+ &QtSizeFPropertyManager::valueChanged,
+ property, val, &QtSizeFPropertyManagerPrivate::setValue);
+}
+
+/*!
+ \fn void QtSizeFPropertyManager::setDecimals(QtProperty *property, int prec)
+
+ Sets the precision of the given \a property to \a prec.
+
+ The valid decimal range is 0-13. The default is 2.
+
+ \sa decimals()
+*/
+void QtSizeFPropertyManager::setDecimals(QtProperty *property, int prec)
+{
+ const QtSizeFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ QtSizeFPropertyManagerPrivate::Data data = it.value();
+
+ if (prec > 13)
+ prec = 13;
+ else if (prec < 0)
+ prec = 0;
+
+ if (data.decimals == prec)
+ return;
+
+ data.decimals = prec;
+ d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToW[property], prec);
+ d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToH[property], prec);
+
+ it.value() = data;
+
+ emit decimalsChanged(property, data.decimals);
+}
+
+/*!
+ Sets the minimum size value for the given \a property to \a minVal.
+
+ When setting the minimum size value, the maximum and current
+ values are adjusted if necessary (ensuring that the size range
+ remains valid and that the current value is within the range).
+
+ \sa minimum(), setRange(), rangeChanged()
+*/
+void QtSizeFPropertyManager::setMinimum(QtProperty *property, const QSizeF &minVal)
+{
+ setBorderValue<const QSizeF &, QtSizeFPropertyManagerPrivate, QtSizeFPropertyManager, QSizeF, QtSizeFPropertyManagerPrivate::Data>(this, d_ptr.data(),
+ &QtSizeFPropertyManager::propertyChanged,
+ &QtSizeFPropertyManager::valueChanged,
+ &QtSizeFPropertyManager::rangeChanged,
+ property,
+ &QtSizeFPropertyManagerPrivate::Data::minimumValue,
+ &QtSizeFPropertyManagerPrivate::Data::setMinimumValue,
+ minVal, &QtSizeFPropertyManagerPrivate::setRange);
+}
+
+/*!
+ Sets the maximum size value for the given \a property to \a maxVal.
+
+ When setting the maximum size value, the minimum and current
+ values are adjusted if necessary (ensuring that the size range
+ remains valid and that the current value is within the range).
+
+ \sa maximum(), setRange(), rangeChanged()
+*/
+void QtSizeFPropertyManager::setMaximum(QtProperty *property, const QSizeF &maxVal)
+{
+ setBorderValue<const QSizeF &, QtSizeFPropertyManagerPrivate, QtSizeFPropertyManager, QSizeF, QtSizeFPropertyManagerPrivate::Data>(this, d_ptr.data(),
+ &QtSizeFPropertyManager::propertyChanged,
+ &QtSizeFPropertyManager::valueChanged,
+ &QtSizeFPropertyManager::rangeChanged,
+ property,
+ &QtSizeFPropertyManagerPrivate::Data::maximumValue,
+ &QtSizeFPropertyManagerPrivate::Data::setMaximumValue,
+ maxVal, &QtSizeFPropertyManagerPrivate::setRange);
+}
+
+/*!
+ \fn void QtSizeFPropertyManager::setRange(QtProperty *property, const QSizeF &minimum, const QSizeF &maximum)
+
+ Sets the range of valid values.
+
+ This is a convenience function defining the range of valid values
+ in one go; setting the \a minimum and \a maximum values for the
+ given \a property with a single function call.
+
+ When setting a new range, the current value is adjusted if
+ necessary (ensuring that the value remains within the range).
+
+ \sa setMinimum(), setMaximum(), rangeChanged()
+*/
+void QtSizeFPropertyManager::setRange(QtProperty *property, const QSizeF &minVal, const QSizeF &maxVal)
+{
+ setBorderValues<const QSizeF &, QtSizeFPropertyManagerPrivate, QtSizeFPropertyManager, QSizeF>(this, d_ptr.data(),
+ &QtSizeFPropertyManager::propertyChanged,
+ &QtSizeFPropertyManager::valueChanged,
+ &QtSizeFPropertyManager::rangeChanged,
+ property, minVal, maxVal, &QtSizeFPropertyManagerPrivate::setRange);
+}
+
+/*!
+ \reimp
+*/
+void QtSizeFPropertyManager::initializeProperty(QtProperty *property)
+{
+ d_ptr->m_values[property] = QtSizeFPropertyManagerPrivate::Data();
+
+ QtProperty *wProp = d_ptr->m_doublePropertyManager->addProperty();
+ wProp->setPropertyName(tr("Width"));
+ d_ptr->m_doublePropertyManager->setDecimals(wProp, decimals(property));
+ d_ptr->m_doublePropertyManager->setValue(wProp, 0);
+ d_ptr->m_doublePropertyManager->setMinimum(wProp, 0);
+ d_ptr->m_propertyToW[property] = wProp;
+ d_ptr->m_wToProperty[wProp] = property;
+ property->addSubProperty(wProp);
+
+ QtProperty *hProp = d_ptr->m_doublePropertyManager->addProperty();
+ hProp->setPropertyName(tr("Height"));
+ d_ptr->m_doublePropertyManager->setDecimals(hProp, decimals(property));
+ d_ptr->m_doublePropertyManager->setValue(hProp, 0);
+ d_ptr->m_doublePropertyManager->setMinimum(hProp, 0);
+ d_ptr->m_propertyToH[property] = hProp;
+ d_ptr->m_hToProperty[hProp] = property;
+ property->addSubProperty(hProp);
+}
+
+/*!
+ \reimp
+*/
+void QtSizeFPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ QtProperty *wProp = d_ptr->m_propertyToW[property];
+ if (wProp) {
+ d_ptr->m_wToProperty.remove(wProp);
+ delete wProp;
+ }
+ d_ptr->m_propertyToW.remove(property);
+
+ QtProperty *hProp = d_ptr->m_propertyToH[property];
+ if (hProp) {
+ d_ptr->m_hToProperty.remove(hProp);
+ delete hProp;
+ }
+ d_ptr->m_propertyToH.remove(property);
+
+ d_ptr->m_values.remove(property);
+}
+
+// QtRectPropertyManager
+
+class QtRectPropertyManagerPrivate
+{
+ QtRectPropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtRectPropertyManager)
+public:
+
+ void slotIntChanged(QtProperty *property, int value);
+ void slotPropertyDestroyed(QtProperty *property);
+ void setConstraint(QtProperty *property, const QRect &constraint, const QRect &val);
+
+ struct Data
+ {
+ Data() : val(0, 0, 0, 0) {}
+ QRect val;
+ QRect constraint;
+ };
+
+ typedef QMap<const QtProperty *, Data> PropertyValueMap;
+ PropertyValueMap m_values;
+
+ QtIntPropertyManager *m_intPropertyManager;
+
+ QMap<const QtProperty *, QtProperty *> m_propertyToX;
+ QMap<const QtProperty *, QtProperty *> m_propertyToY;
+ QMap<const QtProperty *, QtProperty *> m_propertyToW;
+ QMap<const QtProperty *, QtProperty *> m_propertyToH;
+
+ QMap<const QtProperty *, QtProperty *> m_xToProperty;
+ QMap<const QtProperty *, QtProperty *> m_yToProperty;
+ QMap<const QtProperty *, QtProperty *> m_wToProperty;
+ QMap<const QtProperty *, QtProperty *> m_hToProperty;
+};
+
+void QtRectPropertyManagerPrivate::slotIntChanged(QtProperty *property, int value)
+{
+ if (QtProperty *prop = m_xToProperty.value(property, 0)) {
+ QRect r = m_values[prop].val;
+ r.moveLeft(value);
+ q_ptr->setValue(prop, r);
+ } else if (QtProperty *prop = m_yToProperty.value(property)) {
+ QRect r = m_values[prop].val;
+ r.moveTop(value);
+ q_ptr->setValue(prop, r);
+ } else if (QtProperty *prop = m_wToProperty.value(property, 0)) {
+ Data data = m_values[prop];
+ QRect r = data.val;
+ r.setWidth(value);
+ if (!data.constraint.isNull() && data.constraint.x() + data.constraint.width() < r.x() + r.width()) {
+ r.moveLeft(data.constraint.left() + data.constraint.width() - r.width());
+ }
+ q_ptr->setValue(prop, r);
+ } else if (QtProperty *prop = m_hToProperty.value(property, 0)) {
+ Data data = m_values[prop];
+ QRect r = data.val;
+ r.setHeight(value);
+ if (!data.constraint.isNull() && data.constraint.y() + data.constraint.height() < r.y() + r.height()) {
+ r.moveTop(data.constraint.top() + data.constraint.height() - r.height());
+ }
+ q_ptr->setValue(prop, r);
+ }
+}
+
+void QtRectPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property)
+{
+ if (QtProperty *pointProp = m_xToProperty.value(property, 0)) {
+ m_propertyToX[pointProp] = 0;
+ m_xToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_yToProperty.value(property, 0)) {
+ m_propertyToY[pointProp] = 0;
+ m_yToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_wToProperty.value(property, 0)) {
+ m_propertyToW[pointProp] = 0;
+ m_wToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_hToProperty.value(property, 0)) {
+ m_propertyToH[pointProp] = 0;
+ m_hToProperty.remove(property);
+ }
+}
+
+void QtRectPropertyManagerPrivate::setConstraint(QtProperty *property,
+ const QRect &constraint, const QRect &val)
+{
+ const bool isNull = constraint.isNull();
+ const int left = isNull ? INT_MIN : constraint.left();
+ const int right = isNull ? INT_MAX : constraint.left() + constraint.width();
+ const int top = isNull ? INT_MIN : constraint.top();
+ const int bottom = isNull ? INT_MAX : constraint.top() + constraint.height();
+ const int width = isNull ? INT_MAX : constraint.width();
+ const int height = isNull ? INT_MAX : constraint.height();
+
+ m_intPropertyManager->setRange(m_propertyToX[property], left, right);
+ m_intPropertyManager->setRange(m_propertyToY[property], top, bottom);
+ m_intPropertyManager->setRange(m_propertyToW[property], 0, width);
+ m_intPropertyManager->setRange(m_propertyToH[property], 0, height);
+
+ m_intPropertyManager->setValue(m_propertyToX[property], val.x());
+ m_intPropertyManager->setValue(m_propertyToY[property], val.y());
+ m_intPropertyManager->setValue(m_propertyToW[property], val.width());
+ m_intPropertyManager->setValue(m_propertyToH[property], val.height());
+}
+
+/*!
+ \class QtRectPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtRectPropertyManager provides and manages QRect properties.
+
+ A rectangle property has nested \e x, \e y, \e width and \e height
+ subproperties. The top-level property's value can be retrieved
+ using the value() function, and set using the setValue() slot.
+
+ The subproperties are created by a QtIntPropertyManager object. This
+ manager can be retrieved using the subIntPropertyManager() function. In
+ order to provide editing widgets for the subproperties in a
+ property browser widget, this manager must be associated with an
+ editor factory.
+
+ A rectangle property also has a constraint rectangle which can be
+ retrieved using the constraint() function, and set using the
+ setConstraint() slot.
+
+ In addition, QtRectPropertyManager provides the valueChanged() signal
+ which is emitted whenever a property created by this manager
+ changes, and the constraintChanged() signal which is emitted
+ whenever such a property changes its constraint rectangle.
+
+ \sa QtAbstractPropertyManager, QtIntPropertyManager, QtRectFPropertyManager
+*/
+
+/*!
+ \fn void QtRectPropertyManager::valueChanged(QtProperty *property, const QRect &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the new
+ \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ \fn void QtRectPropertyManager::constraintChanged(QtProperty *property, const QRect &constraint)
+
+ This signal is emitted whenever property changes its constraint
+ rectangle, passing a pointer to the \a property and the new \a
+ constraint rectangle as parameters.
+
+ \sa setConstraint()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtRectPropertyManager::QtRectPropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtRectPropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->m_intPropertyManager = new QtIntPropertyManager(this);
+ connect(d_ptr->m_intPropertyManager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotIntChanged(QtProperty*,int)));
+ connect(d_ptr->m_intPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
+ this, SLOT(slotPropertyDestroyed(QtProperty*)));
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtRectPropertyManager::~QtRectPropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the manager that creates the nested \e x, \e y, \e width
+ and \e height subproperties.
+
+ In order to provide editing widgets for the mentioned
+ subproperties in a property browser widget, this manager must be
+ associated with an editor factory.
+
+ \sa QtAbstractPropertyBrowser::setFactoryForManager()
+*/
+QtIntPropertyManager *QtRectPropertyManager::subIntPropertyManager() const
+{
+ return d_ptr->m_intPropertyManager;
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given \a property is not managed by this manager, this
+ function returns an invalid rectangle.
+
+ \sa setValue(), constraint()
+*/
+QRect QtRectPropertyManager::value(const QtProperty *property) const
+{
+ return getValue<QRect>(d_ptr->m_values, property);
+}
+
+/*!
+ Returns the given \a property's constraining rectangle. If returned value is null QRect it means there is no constraint applied.
+
+ \sa value(), setConstraint()
+*/
+QRect QtRectPropertyManager::constraint(const QtProperty *property) const
+{
+ return getData<QRect>(d_ptr->m_values, &QtRectPropertyManagerPrivate::Data::constraint, property, QRect());
+}
+
+/*!
+ \reimp
+*/
+QString QtRectPropertyManager::valueText(const QtProperty *property) const
+{
+ const QtRectPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+ const QRect v = it.value().val;
+ return tr("[(%1, %2), %3 x %4]").arg(QString::number(v.x()))
+ .arg(QString::number(v.y()))
+ .arg(QString::number(v.width()))
+ .arg(QString::number(v.height()));
+}
+
+/*!
+ \fn void QtRectPropertyManager::setValue(QtProperty *property, const QRect &value)
+
+ Sets the value of the given \a property to \a value. Nested
+ properties are updated automatically.
+
+ If the specified \a value is not inside the given \a property's
+ constraining rectangle, the value is adjusted accordingly to fit
+ within the constraint.
+
+ \sa value(), setConstraint(), valueChanged()
+*/
+void QtRectPropertyManager::setValue(QtProperty *property, const QRect &val)
+{
+ const QtRectPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ QtRectPropertyManagerPrivate::Data data = it.value();
+
+ QRect newRect = val.normalized();
+ if (!data.constraint.isNull() && !data.constraint.contains(newRect)) {
+ const QRect r1 = data.constraint;
+ const QRect r2 = newRect;
+ newRect.setLeft(qMax(r1.left(), r2.left()));
+ newRect.setRight(qMin(r1.right(), r2.right()));
+ newRect.setTop(qMax(r1.top(), r2.top()));
+ newRect.setBottom(qMin(r1.bottom(), r2.bottom()));
+ if (newRect.width() < 0 || newRect.height() < 0)
+ return;
+ }
+
+ if (data.val == newRect)
+ return;
+
+ data.val = newRect;
+
+ it.value() = data;
+ d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToX[property], newRect.x());
+ d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToY[property], newRect.y());
+ d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToW[property], newRect.width());
+ d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToH[property], newRect.height());
+
+ emit propertyChanged(property);
+ emit valueChanged(property, data.val);
+}
+
+/*!
+ Sets the given \a property's constraining rectangle to \a
+ constraint.
+
+ When setting the constraint, the current value is adjusted if
+ necessary (ensuring that the current rectangle value is inside the
+ constraint). In order to reset the constraint pass a null QRect value.
+
+ \sa setValue(), constraint(), constraintChanged()
+*/
+void QtRectPropertyManager::setConstraint(QtProperty *property, const QRect &constraint)
+{
+ const QtRectPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ QtRectPropertyManagerPrivate::Data data = it.value();
+
+ QRect newConstraint = constraint.normalized();
+ if (data.constraint == newConstraint)
+ return;
+
+ const QRect oldVal = data.val;
+
+ data.constraint = newConstraint;
+
+ if (!data.constraint.isNull() && !data.constraint.contains(oldVal)) {
+ QRect r1 = data.constraint;
+ QRect r2 = data.val;
+
+ if (r2.width() > r1.width())
+ r2.setWidth(r1.width());
+ if (r2.height() > r1.height())
+ r2.setHeight(r1.height());
+ if (r2.left() < r1.left())
+ r2.moveLeft(r1.left());
+ else if (r2.right() > r1.right())
+ r2.moveRight(r1.right());
+ if (r2.top() < r1.top())
+ r2.moveTop(r1.top());
+ else if (r2.bottom() > r1.bottom())
+ r2.moveBottom(r1.bottom());
+
+ data.val = r2;
+ }
+
+ it.value() = data;
+
+ emit constraintChanged(property, data.constraint);
+
+ d_ptr->setConstraint(property, data.constraint, data.val);
+
+ if (data.val == oldVal)
+ return;
+
+ emit propertyChanged(property);
+ emit valueChanged(property, data.val);
+}
+
+/*!
+ \reimp
+*/
+void QtRectPropertyManager::initializeProperty(QtProperty *property)
+{
+ d_ptr->m_values[property] = QtRectPropertyManagerPrivate::Data();
+
+ QtProperty *xProp = d_ptr->m_intPropertyManager->addProperty();
+ xProp->setPropertyName(tr("X"));
+ d_ptr->m_intPropertyManager->setValue(xProp, 0);
+ d_ptr->m_propertyToX[property] = xProp;
+ d_ptr->m_xToProperty[xProp] = property;
+ property->addSubProperty(xProp);
+
+ QtProperty *yProp = d_ptr->m_intPropertyManager->addProperty();
+ yProp->setPropertyName(tr("Y"));
+ d_ptr->m_intPropertyManager->setValue(yProp, 0);
+ d_ptr->m_propertyToY[property] = yProp;
+ d_ptr->m_yToProperty[yProp] = property;
+ property->addSubProperty(yProp);
+
+ QtProperty *wProp = d_ptr->m_intPropertyManager->addProperty();
+ wProp->setPropertyName(tr("Width"));
+ d_ptr->m_intPropertyManager->setValue(wProp, 0);
+ d_ptr->m_intPropertyManager->setMinimum(wProp, 0);
+ d_ptr->m_propertyToW[property] = wProp;
+ d_ptr->m_wToProperty[wProp] = property;
+ property->addSubProperty(wProp);
+
+ QtProperty *hProp = d_ptr->m_intPropertyManager->addProperty();
+ hProp->setPropertyName(tr("Height"));
+ d_ptr->m_intPropertyManager->setValue(hProp, 0);
+ d_ptr->m_intPropertyManager->setMinimum(hProp, 0);
+ d_ptr->m_propertyToH[property] = hProp;
+ d_ptr->m_hToProperty[hProp] = property;
+ property->addSubProperty(hProp);
+}
+
+/*!
+ \reimp
+*/
+void QtRectPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ QtProperty *xProp = d_ptr->m_propertyToX[property];
+ if (xProp) {
+ d_ptr->m_xToProperty.remove(xProp);
+ delete xProp;
+ }
+ d_ptr->m_propertyToX.remove(property);
+
+ QtProperty *yProp = d_ptr->m_propertyToY[property];
+ if (yProp) {
+ d_ptr->m_yToProperty.remove(yProp);
+ delete yProp;
+ }
+ d_ptr->m_propertyToY.remove(property);
+
+ QtProperty *wProp = d_ptr->m_propertyToW[property];
+ if (wProp) {
+ d_ptr->m_wToProperty.remove(wProp);
+ delete wProp;
+ }
+ d_ptr->m_propertyToW.remove(property);
+
+ QtProperty *hProp = d_ptr->m_propertyToH[property];
+ if (hProp) {
+ d_ptr->m_hToProperty.remove(hProp);
+ delete hProp;
+ }
+ d_ptr->m_propertyToH.remove(property);
+
+ d_ptr->m_values.remove(property);
+}
+
+// QtRectFPropertyManager
+
+class QtRectFPropertyManagerPrivate
+{
+ QtRectFPropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtRectFPropertyManager)
+public:
+
+ void slotDoubleChanged(QtProperty *property, double value);
+ void slotPropertyDestroyed(QtProperty *property);
+ void setConstraint(QtProperty *property, const QRectF &constraint, const QRectF &val);
+
+ struct Data
+ {
+ Data() : val(0, 0, 0, 0), decimals(2) {}
+ QRectF val;
+ QRectF constraint;
+ int decimals;
+ };
+
+ typedef QMap<const QtProperty *, Data> PropertyValueMap;
+ PropertyValueMap m_values;
+
+ QtDoublePropertyManager *m_doublePropertyManager;
+
+ QMap<const QtProperty *, QtProperty *> m_propertyToX;
+ QMap<const QtProperty *, QtProperty *> m_propertyToY;
+ QMap<const QtProperty *, QtProperty *> m_propertyToW;
+ QMap<const QtProperty *, QtProperty *> m_propertyToH;
+
+ QMap<const QtProperty *, QtProperty *> m_xToProperty;
+ QMap<const QtProperty *, QtProperty *> m_yToProperty;
+ QMap<const QtProperty *, QtProperty *> m_wToProperty;
+ QMap<const QtProperty *, QtProperty *> m_hToProperty;
+};
+
+void QtRectFPropertyManagerPrivate::slotDoubleChanged(QtProperty *property, double value)
+{
+ if (QtProperty *prop = m_xToProperty.value(property, 0)) {
+ QRectF r = m_values[prop].val;
+ r.moveLeft(value);
+ q_ptr->setValue(prop, r);
+ } else if (QtProperty *prop = m_yToProperty.value(property, 0)) {
+ QRectF r = m_values[prop].val;
+ r.moveTop(value);
+ q_ptr->setValue(prop, r);
+ } else if (QtProperty *prop = m_wToProperty.value(property, 0)) {
+ Data data = m_values[prop];
+ QRectF r = data.val;
+ r.setWidth(value);
+ if (!data.constraint.isNull() && data.constraint.x() + data.constraint.width() < r.x() + r.width()) {
+ r.moveLeft(data.constraint.left() + data.constraint.width() - r.width());
+ }
+ q_ptr->setValue(prop, r);
+ } else if (QtProperty *prop = m_hToProperty.value(property, 0)) {
+ Data data = m_values[prop];
+ QRectF r = data.val;
+ r.setHeight(value);
+ if (!data.constraint.isNull() && data.constraint.y() + data.constraint.height() < r.y() + r.height()) {
+ r.moveTop(data.constraint.top() + data.constraint.height() - r.height());
+ }
+ q_ptr->setValue(prop, r);
+ }
+}
+
+void QtRectFPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property)
+{
+ if (QtProperty *pointProp = m_xToProperty.value(property, 0)) {
+ m_propertyToX[pointProp] = 0;
+ m_xToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_yToProperty.value(property, 0)) {
+ m_propertyToY[pointProp] = 0;
+ m_yToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_wToProperty.value(property, 0)) {
+ m_propertyToW[pointProp] = 0;
+ m_wToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_hToProperty.value(property, 0)) {
+ m_propertyToH[pointProp] = 0;
+ m_hToProperty.remove(property);
+ }
+}
+
+void QtRectFPropertyManagerPrivate::setConstraint(QtProperty *property,
+ const QRectF &constraint, const QRectF &val)
+{
+ const bool isNull = constraint.isNull();
+ const float left = isNull ? FLT_MIN : constraint.left();
+ const float right = isNull ? FLT_MAX : constraint.left() + constraint.width();
+ const float top = isNull ? FLT_MIN : constraint.top();
+ const float bottom = isNull ? FLT_MAX : constraint.top() + constraint.height();
+ const float width = isNull ? FLT_MAX : constraint.width();
+ const float height = isNull ? FLT_MAX : constraint.height();
+
+ m_doublePropertyManager->setRange(m_propertyToX[property], left, right);
+ m_doublePropertyManager->setRange(m_propertyToY[property], top, bottom);
+ m_doublePropertyManager->setRange(m_propertyToW[property], 0, width);
+ m_doublePropertyManager->setRange(m_propertyToH[property], 0, height);
+
+ m_doublePropertyManager->setValue(m_propertyToX[property], val.x());
+ m_doublePropertyManager->setValue(m_propertyToY[property], val.y());
+ m_doublePropertyManager->setValue(m_propertyToW[property], val.width());
+ m_doublePropertyManager->setValue(m_propertyToH[property], val.height());
+}
+
+/*!
+ \class QtRectFPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtRectFPropertyManager provides and manages QRectF properties.
+
+ A rectangle property has nested \e x, \e y, \e width and \e height
+ subproperties. The top-level property's value can be retrieved
+ using the value() function, and set using the setValue() slot.
+
+ The subproperties are created by a QtDoublePropertyManager object. This
+ manager can be retrieved using the subDoublePropertyManager() function. In
+ order to provide editing widgets for the subproperties in a
+ property browser widget, this manager must be associated with an
+ editor factory.
+
+ A rectangle property also has a constraint rectangle which can be
+ retrieved using the constraint() function, and set using the
+ setConstraint() slot.
+
+ In addition, QtRectFPropertyManager provides the valueChanged() signal
+ which is emitted whenever a property created by this manager
+ changes, and the constraintChanged() signal which is emitted
+ whenever such a property changes its constraint rectangle.
+
+ \sa QtAbstractPropertyManager, QtDoublePropertyManager, QtRectPropertyManager
+*/
+
+/*!
+ \fn void QtRectFPropertyManager::valueChanged(QtProperty *property, const QRectF &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the new
+ \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ \fn void QtRectFPropertyManager::constraintChanged(QtProperty *property, const QRectF &constraint)
+
+ This signal is emitted whenever property changes its constraint
+ rectangle, passing a pointer to the \a property and the new \a
+ constraint rectangle as parameters.
+
+ \sa setConstraint()
+*/
+
+/*!
+ \fn void QtRectFPropertyManager::decimalsChanged(QtProperty *property, int prec)
+
+ This signal is emitted whenever a property created by this manager
+ changes its precision of value, passing a pointer to the
+ \a property and the new \a prec value
+
+ \sa setDecimals()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtRectFPropertyManager::QtRectFPropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtRectFPropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->m_doublePropertyManager = new QtDoublePropertyManager(this);
+ connect(d_ptr->m_doublePropertyManager, SIGNAL(valueChanged(QtProperty*,double)),
+ this, SLOT(slotDoubleChanged(QtProperty*,double)));
+ connect(d_ptr->m_doublePropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
+ this, SLOT(slotPropertyDestroyed(QtProperty*)));
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtRectFPropertyManager::~QtRectFPropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the manager that creates the nested \e x, \e y, \e width
+ and \e height subproperties.
+
+ In order to provide editing widgets for the mentioned
+ subproperties in a property browser widget, this manager must be
+ associated with an editor factory.
+
+ \sa QtAbstractPropertyBrowser::setFactoryForManager()
+*/
+QtDoublePropertyManager *QtRectFPropertyManager::subDoublePropertyManager() const
+{
+ return d_ptr->m_doublePropertyManager;
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given \a property is not managed by this manager, this
+ function returns an invalid rectangle.
+
+ \sa setValue(), constraint()
+*/
+QRectF QtRectFPropertyManager::value(const QtProperty *property) const
+{
+ return getValue<QRectF>(d_ptr->m_values, property);
+}
+
+/*!
+ Returns the given \a property's precision, in decimals.
+
+ \sa setDecimals()
+*/
+int QtRectFPropertyManager::decimals(const QtProperty *property) const
+{
+ return getData<int>(d_ptr->m_values, &QtRectFPropertyManagerPrivate::Data::decimals, property, 0);
+}
+
+/*!
+ Returns the given \a property's constraining rectangle. If returned value is null QRectF it means there is no constraint applied.
+
+ \sa value(), setConstraint()
+*/
+QRectF QtRectFPropertyManager::constraint(const QtProperty *property) const
+{
+ return getData<QRectF>(d_ptr->m_values, &QtRectFPropertyManagerPrivate::Data::constraint, property, QRect());
+}
+
+/*!
+ \reimp
+*/
+QString QtRectFPropertyManager::valueText(const QtProperty *property) const
+{
+ const QtRectFPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+ const QRectF v = it.value().val;
+ const int dec = it.value().decimals;
+ return QString(tr("[(%1, %2), %3 x %4]").arg(QString::number(v.x(), 'f', dec))
+ .arg(QString::number(v.y(), 'f', dec))
+ .arg(QString::number(v.width(), 'f', dec))
+ .arg(QString::number(v.height(), 'f', dec)));
+}
+
+/*!
+ \fn void QtRectFPropertyManager::setValue(QtProperty *property, const QRectF &value)
+
+ Sets the value of the given \a property to \a value. Nested
+ properties are updated automatically.
+
+ If the specified \a value is not inside the given \a property's
+ constraining rectangle, the value is adjusted accordingly to fit
+ within the constraint.
+
+ \sa value(), setConstraint(), valueChanged()
+*/
+void QtRectFPropertyManager::setValue(QtProperty *property, const QRectF &val)
+{
+ const QtRectFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ QtRectFPropertyManagerPrivate::Data data = it.value();
+
+ QRectF newRect = val.normalized();
+ if (!data.constraint.isNull() && !data.constraint.contains(newRect)) {
+ const QRectF r1 = data.constraint;
+ const QRectF r2 = newRect;
+ newRect.setLeft(qMax(r1.left(), r2.left()));
+ newRect.setRight(qMin(r1.right(), r2.right()));
+ newRect.setTop(qMax(r1.top(), r2.top()));
+ newRect.setBottom(qMin(r1.bottom(), r2.bottom()));
+ if (newRect.width() < 0 || newRect.height() < 0)
+ return;
+ }
+
+ if (data.val == newRect)
+ return;
+
+ data.val = newRect;
+
+ it.value() = data;
+ d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToX[property], newRect.x());
+ d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToY[property], newRect.y());
+ d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToW[property], newRect.width());
+ d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToH[property], newRect.height());
+
+ emit propertyChanged(property);
+ emit valueChanged(property, data.val);
+}
+
+/*!
+ Sets the given \a property's constraining rectangle to \a
+ constraint.
+
+ When setting the constraint, the current value is adjusted if
+ necessary (ensuring that the current rectangle value is inside the
+ constraint). In order to reset the constraint pass a null QRectF value.
+
+ \sa setValue(), constraint(), constraintChanged()
+*/
+void QtRectFPropertyManager::setConstraint(QtProperty *property, const QRectF &constraint)
+{
+ const QtRectFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ QtRectFPropertyManagerPrivate::Data data = it.value();
+
+ QRectF newConstraint = constraint.normalized();
+ if (data.constraint == newConstraint)
+ return;
+
+ const QRectF oldVal = data.val;
+
+ data.constraint = newConstraint;
+
+ if (!data.constraint.isNull() && !data.constraint.contains(oldVal)) {
+ QRectF r1 = data.constraint;
+ QRectF r2 = data.val;
+
+ if (r2.width() > r1.width())
+ r2.setWidth(r1.width());
+ if (r2.height() > r1.height())
+ r2.setHeight(r1.height());
+ if (r2.left() < r1.left())
+ r2.moveLeft(r1.left());
+ else if (r2.right() > r1.right())
+ r2.moveRight(r1.right());
+ if (r2.top() < r1.top())
+ r2.moveTop(r1.top());
+ else if (r2.bottom() > r1.bottom())
+ r2.moveBottom(r1.bottom());
+
+ data.val = r2;
+ }
+
+ it.value() = data;
+
+ emit constraintChanged(property, data.constraint);
+
+ d_ptr->setConstraint(property, data.constraint, data.val);
+
+ if (data.val == oldVal)
+ return;
+
+ emit propertyChanged(property);
+ emit valueChanged(property, data.val);
+}
+
+/*!
+ \fn void QtRectFPropertyManager::setDecimals(QtProperty *property, int prec)
+
+ Sets the precision of the given \a property to \a prec.
+
+ The valid decimal range is 0-13. The default is 2.
+
+ \sa decimals()
+*/
+void QtRectFPropertyManager::setDecimals(QtProperty *property, int prec)
+{
+ const QtRectFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ QtRectFPropertyManagerPrivate::Data data = it.value();
+
+ if (prec > 13)
+ prec = 13;
+ else if (prec < 0)
+ prec = 0;
+
+ if (data.decimals == prec)
+ return;
+
+ data.decimals = prec;
+ d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToX[property], prec);
+ d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToY[property], prec);
+ d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToW[property], prec);
+ d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToH[property], prec);
+
+ it.value() = data;
+
+ emit decimalsChanged(property, data.decimals);
+}
+
+/*!
+ \reimp
+*/
+void QtRectFPropertyManager::initializeProperty(QtProperty *property)
+{
+ d_ptr->m_values[property] = QtRectFPropertyManagerPrivate::Data();
+
+ QtProperty *xProp = d_ptr->m_doublePropertyManager->addProperty();
+ xProp->setPropertyName(tr("X"));
+ d_ptr->m_doublePropertyManager->setDecimals(xProp, decimals(property));
+ d_ptr->m_doublePropertyManager->setValue(xProp, 0);
+ d_ptr->m_propertyToX[property] = xProp;
+ d_ptr->m_xToProperty[xProp] = property;
+ property->addSubProperty(xProp);
+
+ QtProperty *yProp = d_ptr->m_doublePropertyManager->addProperty();
+ yProp->setPropertyName(tr("Y"));
+ d_ptr->m_doublePropertyManager->setDecimals(yProp, decimals(property));
+ d_ptr->m_doublePropertyManager->setValue(yProp, 0);
+ d_ptr->m_propertyToY[property] = yProp;
+ d_ptr->m_yToProperty[yProp] = property;
+ property->addSubProperty(yProp);
+
+ QtProperty *wProp = d_ptr->m_doublePropertyManager->addProperty();
+ wProp->setPropertyName(tr("Width"));
+ d_ptr->m_doublePropertyManager->setDecimals(wProp, decimals(property));
+ d_ptr->m_doublePropertyManager->setValue(wProp, 0);
+ d_ptr->m_doublePropertyManager->setMinimum(wProp, 0);
+ d_ptr->m_propertyToW[property] = wProp;
+ d_ptr->m_wToProperty[wProp] = property;
+ property->addSubProperty(wProp);
+
+ QtProperty *hProp = d_ptr->m_doublePropertyManager->addProperty();
+ hProp->setPropertyName(tr("Height"));
+ d_ptr->m_doublePropertyManager->setDecimals(hProp, decimals(property));
+ d_ptr->m_doublePropertyManager->setValue(hProp, 0);
+ d_ptr->m_doublePropertyManager->setMinimum(hProp, 0);
+ d_ptr->m_propertyToH[property] = hProp;
+ d_ptr->m_hToProperty[hProp] = property;
+ property->addSubProperty(hProp);
+}
+
+/*!
+ \reimp
+*/
+void QtRectFPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ QtProperty *xProp = d_ptr->m_propertyToX[property];
+ if (xProp) {
+ d_ptr->m_xToProperty.remove(xProp);
+ delete xProp;
+ }
+ d_ptr->m_propertyToX.remove(property);
+
+ QtProperty *yProp = d_ptr->m_propertyToY[property];
+ if (yProp) {
+ d_ptr->m_yToProperty.remove(yProp);
+ delete yProp;
+ }
+ d_ptr->m_propertyToY.remove(property);
+
+ QtProperty *wProp = d_ptr->m_propertyToW[property];
+ if (wProp) {
+ d_ptr->m_wToProperty.remove(wProp);
+ delete wProp;
+ }
+ d_ptr->m_propertyToW.remove(property);
+
+ QtProperty *hProp = d_ptr->m_propertyToH[property];
+ if (hProp) {
+ d_ptr->m_hToProperty.remove(hProp);
+ delete hProp;
+ }
+ d_ptr->m_propertyToH.remove(property);
+
+ d_ptr->m_values.remove(property);
+}
+
+// QtEnumPropertyManager
+
+class QtEnumPropertyManagerPrivate
+{
+ QtEnumPropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtEnumPropertyManager)
+public:
+
+ struct Data
+ {
+ Data() : val(-1) {}
+ int val;
+ QStringList enumNames;
+ QMap<int, QIcon> enumIcons;
+ };
+
+ typedef QMap<const QtProperty *, Data> PropertyValueMap;
+ PropertyValueMap m_values;
+};
+
+/*!
+ \class QtEnumPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtEnumPropertyManager provides and manages enum properties.
+
+ Each enum property has an associated list of enum names which can
+ be retrieved using the enumNames() function, and set using the
+ corresponding setEnumNames() function. An enum property's value is
+ represented by an index in this list, and can be retrieved and set
+ using the value() and setValue() slots respectively.
+
+ Each enum value can also have an associated icon. The mapping from
+ values to icons can be set using the setEnumIcons() function and
+ queried with the enumIcons() function.
+
+ In addition, QtEnumPropertyManager provides the valueChanged() signal
+ which is emitted whenever a property created by this manager
+ changes. The enumNamesChanged() or enumIconsChanged() signal is emitted
+ whenever the list of enum names or icons is altered.
+
+ \sa QtAbstractPropertyManager, QtEnumEditorFactory
+*/
+
+/*!
+ \fn void QtEnumPropertyManager::valueChanged(QtProperty *property, int value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the new
+ \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ \fn void QtEnumPropertyManager::enumNamesChanged(QtProperty *property, const QStringList &names)
+
+ This signal is emitted whenever a property created by this manager
+ changes its enum names, passing a pointer to the \a property and
+ the new \a names as parameters.
+
+ \sa setEnumNames()
+*/
+
+/*!
+ \fn void QtEnumPropertyManager::enumIconsChanged(QtProperty *property, const QMap<int, QIcon> &icons)
+
+ This signal is emitted whenever a property created by this manager
+ changes its enum icons, passing a pointer to the \a property and
+ the new mapping of values to \a icons as parameters.
+
+ \sa setEnumIcons()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtEnumPropertyManager::QtEnumPropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtEnumPropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtEnumPropertyManager::~QtEnumPropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the given \a property's value which is an index in the
+ list returned by enumNames()
+
+ If the given property is not managed by this manager, this
+ function returns -1.
+
+ \sa enumNames(), setValue()
+*/
+int QtEnumPropertyManager::value(const QtProperty *property) const
+{
+ return getValue<int>(d_ptr->m_values, property, -1);
+}
+
+/*!
+ Returns the given \a property's list of enum names.
+
+ \sa value(), setEnumNames()
+*/
+QStringList QtEnumPropertyManager::enumNames(const QtProperty *property) const
+{
+ return getData<QStringList>(d_ptr->m_values, &QtEnumPropertyManagerPrivate::Data::enumNames, property, QStringList());
+}
+
+/*!
+ Returns the given \a property's map of enum values to their icons.
+
+ \sa value(), setEnumIcons()
+*/
+QMap<int, QIcon> QtEnumPropertyManager::enumIcons(const QtProperty *property) const
+{
+ return getData<QMap<int, QIcon> >(d_ptr->m_values, &QtEnumPropertyManagerPrivate::Data::enumIcons, property, QMap<int, QIcon>());
+}
+
+/*!
+ \reimp
+*/
+QString QtEnumPropertyManager::valueText(const QtProperty *property) const
+{
+ const QtEnumPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+
+ const QtEnumPropertyManagerPrivate::Data &data = it.value();
+
+ const int v = data.val;
+ if (v >= 0 && v < data.enumNames.count())
+ return data.enumNames.at(v);
+ return QString();
+}
+
+/*!
+ \reimp
+*/
+QIcon QtEnumPropertyManager::valueIcon(const QtProperty *property) const
+{
+ const QtEnumPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QIcon();
+
+ const QtEnumPropertyManagerPrivate::Data &data = it.value();
+
+ const int v = data.val;
+ return data.enumIcons.value(v);
+}
+
+/*!
+ \fn void QtEnumPropertyManager::setValue(QtProperty *property, int value)
+
+ Sets the value of the given \a property to \a value.
+
+ The specified \a value must be less than the size of the given \a
+ property's enumNames() list, and larger than (or equal to) 0.
+
+ \sa value(), valueChanged()
+*/
+void QtEnumPropertyManager::setValue(QtProperty *property, int val)
+{
+ const QtEnumPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ QtEnumPropertyManagerPrivate::Data data = it.value();
+
+ if (val >= data.enumNames.count())
+ return;
+
+ if (val < 0 && data.enumNames.count() > 0)
+ return;
+
+ if (val < 0)
+ val = -1;
+
+ if (data.val == val)
+ return;
+
+ data.val = val;
+
+ it.value() = data;
+
+ emit propertyChanged(property);
+ emit valueChanged(property, data.val);
+}
+
+/*!
+ Sets the given \a property's list of enum names to \a
+ enumNames. The \a property's current value is reset to 0
+ indicating the first item of the list.
+
+ If the specified \a enumNames list is empty, the \a property's
+ current value is set to -1.
+
+ \sa enumNames(), enumNamesChanged()
+*/
+void QtEnumPropertyManager::setEnumNames(QtProperty *property, const QStringList &enumNames)
+{
+ const QtEnumPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ QtEnumPropertyManagerPrivate::Data data = it.value();
+
+ if (data.enumNames == enumNames)
+ return;
+
+ data.enumNames = enumNames;
+
+ data.val = -1;
+
+ if (enumNames.count() > 0)
+ data.val = 0;
+
+ it.value() = data;
+
+ emit enumNamesChanged(property, data.enumNames);
+
+ emit propertyChanged(property);
+ emit valueChanged(property, data.val);
+}
+
+/*!
+ Sets the given \a property's map of enum values to their icons to \a
+ enumIcons.
+
+ Each enum value can have associated icon. This association is represented with passed \a enumIcons map.
+
+ \sa enumNames(), enumNamesChanged()
+*/
+void QtEnumPropertyManager::setEnumIcons(QtProperty *property, const QMap<int, QIcon> &enumIcons)
+{
+ const QtEnumPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ it.value().enumIcons = enumIcons;
+
+ emit enumIconsChanged(property, it.value().enumIcons);
+
+ emit propertyChanged(property);
+}
+
+/*!
+ \reimp
+*/
+void QtEnumPropertyManager::initializeProperty(QtProperty *property)
+{
+ d_ptr->m_values[property] = QtEnumPropertyManagerPrivate::Data();
+}
+
+/*!
+ \reimp
+*/
+void QtEnumPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ d_ptr->m_values.remove(property);
+}
+
+// QtFlagPropertyManager
+
+class QtFlagPropertyManagerPrivate
+{
+ QtFlagPropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtFlagPropertyManager)
+public:
+
+ void slotBoolChanged(QtProperty *property, bool value);
+ void slotPropertyDestroyed(QtProperty *property);
+
+ struct Data
+ {
+ Data() : val(-1) {}
+ int val;
+ QStringList flagNames;
+ };
+
+ typedef QMap<const QtProperty *, Data> PropertyValueMap;
+ PropertyValueMap m_values;
+
+ QtBoolPropertyManager *m_boolPropertyManager;
+
+ QMap<const QtProperty *, QList<QtProperty *> > m_propertyToFlags;
+
+ QMap<const QtProperty *, QtProperty *> m_flagToProperty;
+};
+
+void QtFlagPropertyManagerPrivate::slotBoolChanged(QtProperty *property, bool value)
+{
+ QtProperty *prop = m_flagToProperty.value(property, 0);
+ if (prop == 0)
+ return;
+
+ QListIterator<QtProperty *> itProp(m_propertyToFlags[prop]);
+ int level = 0;
+ while (itProp.hasNext()) {
+ QtProperty *p = itProp.next();
+ if (p == property) {
+ int v = m_values[prop].val;
+ if (value) {
+ v |= (1 << level);
+ } else {
+ v &= ~(1 << level);
+ }
+ q_ptr->setValue(prop, v);
+ return;
+ }
+ level++;
+ }
+}
+
+void QtFlagPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property)
+{
+ QtProperty *flagProperty = m_flagToProperty.value(property, 0);
+ if (flagProperty == 0)
+ return;
+
+ m_propertyToFlags[flagProperty].replace(m_propertyToFlags[flagProperty].indexOf(property), 0);
+ m_flagToProperty.remove(property);
+}
+
+/*!
+ \class QtFlagPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtFlagPropertyManager provides and manages flag properties.
+
+ Each flag property has an associated list of flag names which can
+ be retrieved using the flagNames() function, and set using the
+ corresponding setFlagNames() function.
+
+ The flag manager provides properties with nested boolean
+ subproperties representing each flag, i.e. a flag property's value
+ is the binary combination of the subproperties' values. A
+ property's value can be retrieved and set using the value() and
+ setValue() slots respectively. The combination of flags is represented
+ by single int value - that's why it's possible to store up to
+ 32 independent flags in one flag property.
+
+ The subproperties are created by a QtBoolPropertyManager object. This
+ manager can be retrieved using the subBoolPropertyManager() function. In
+ order to provide editing widgets for the subproperties in a
+ property browser widget, this manager must be associated with an
+ editor factory.
+
+ In addition, QtFlagPropertyManager provides the valueChanged() signal
+ which is emitted whenever a property created by this manager
+ changes, and the flagNamesChanged() signal which is emitted
+ whenever the list of flag names is altered.
+
+ \sa QtAbstractPropertyManager, QtBoolPropertyManager
+*/
+
+/*!
+ \fn void QtFlagPropertyManager::valueChanged(QtProperty *property, int value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the new
+ \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ \fn void QtFlagPropertyManager::flagNamesChanged(QtProperty *property, const QStringList &names)
+
+ This signal is emitted whenever a property created by this manager
+ changes its flag names, passing a pointer to the \a property and the
+ new \a names as parameters.
+
+ \sa setFlagNames()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtFlagPropertyManager::QtFlagPropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtFlagPropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->m_boolPropertyManager = new QtBoolPropertyManager(this);
+ connect(d_ptr->m_boolPropertyManager, SIGNAL(valueChanged(QtProperty*,bool)),
+ this, SLOT(slotBoolChanged(QtProperty*,bool)));
+ connect(d_ptr->m_boolPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
+ this, SLOT(slotPropertyDestroyed(QtProperty*)));
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtFlagPropertyManager::~QtFlagPropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the manager that produces the nested boolean subproperties
+ representing each flag.
+
+ In order to provide editing widgets for the subproperties in a
+ property browser widget, this manager must be associated with an
+ editor factory.
+
+ \sa QtAbstractPropertyBrowser::setFactoryForManager()
+*/
+QtBoolPropertyManager *QtFlagPropertyManager::subBoolPropertyManager() const
+{
+ return d_ptr->m_boolPropertyManager;
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given property is not managed by this manager, this
+ function returns 0.
+
+ \sa flagNames(), setValue()
+*/
+int QtFlagPropertyManager::value(const QtProperty *property) const
+{
+ return getValue<int>(d_ptr->m_values, property, 0);
+}
+
+/*!
+ Returns the given \a property's list of flag names.
+
+ \sa value(), setFlagNames()
+*/
+QStringList QtFlagPropertyManager::flagNames(const QtProperty *property) const
+{
+ return getData<QStringList>(d_ptr->m_values, &QtFlagPropertyManagerPrivate::Data::flagNames, property, QStringList());
+}
+
+/*!
+ \reimp
+*/
+QString QtFlagPropertyManager::valueText(const QtProperty *property) const
+{
+ const QtFlagPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+
+ const QtFlagPropertyManagerPrivate::Data &data = it.value();
+
+ QString str;
+ int level = 0;
+ const QChar bar = QLatin1Char('|');
+ const QStringList::const_iterator fncend = data.flagNames.constEnd();
+ for (QStringList::const_iterator it = data.flagNames.constBegin(); it != fncend; ++it) {
+ if (data.val & (1 << level)) {
+ if (!str.isEmpty())
+ str += bar;
+ str += *it;
+ }
+
+ level++;
+ }
+ return str;
+}
+
+/*!
+ \fn void QtFlagPropertyManager::setValue(QtProperty *property, int value)
+
+ Sets the value of the given \a property to \a value. Nested
+ properties are updated automatically.
+
+ The specified \a value must be less than the binary combination of
+ the property's flagNames() list size (i.e. less than 2\sup n,
+ where \c n is the size of the list) and larger than (or equal to)
+ 0.
+
+ \sa value(), valueChanged()
+*/
+void QtFlagPropertyManager::setValue(QtProperty *property, int val)
+{
+ const QtFlagPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ QtFlagPropertyManagerPrivate::Data data = it.value();
+
+ if (data.val == val)
+ return;
+
+ if (val > (1 << data.flagNames.count()) - 1)
+ return;
+
+ if (val < 0)
+ return;
+
+ data.val = val;
+
+ it.value() = data;
+
+ QListIterator<QtProperty *> itProp(d_ptr->m_propertyToFlags[property]);
+ int level = 0;
+ while (itProp.hasNext()) {
+ QtProperty *prop = itProp.next();
+ if (prop)
+ d_ptr->m_boolPropertyManager->setValue(prop, val & (1 << level));
+ level++;
+ }
+
+ emit propertyChanged(property);
+ emit valueChanged(property, data.val);
+}
+
+/*!
+ Sets the given \a property's list of flag names to \a flagNames. The
+ property's current value is reset to 0 indicating the first item
+ of the list.
+
+ \sa flagNames(), flagNamesChanged()
+*/
+void QtFlagPropertyManager::setFlagNames(QtProperty *property, const QStringList &flagNames)
+{
+ const QtFlagPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ QtFlagPropertyManagerPrivate::Data data = it.value();
+
+ if (data.flagNames == flagNames)
+ return;
+
+ data.flagNames = flagNames;
+ data.val = 0;
+
+ it.value() = data;
+
+ QListIterator<QtProperty *> itProp(d_ptr->m_propertyToFlags[property]);
+ while (itProp.hasNext()) {
+ QtProperty *prop = itProp.next();
+ if (prop) {
+ delete prop;
+ d_ptr->m_flagToProperty.remove(prop);
+ }
+ }
+ d_ptr->m_propertyToFlags[property].clear();
+
+ QStringListIterator itFlag(flagNames);
+ while (itFlag.hasNext()) {
+ const QString flagName = itFlag.next();
+ QtProperty *prop = d_ptr->m_boolPropertyManager->addProperty();
+ prop->setPropertyName(flagName);
+ property->addSubProperty(prop);
+ d_ptr->m_propertyToFlags[property].append(prop);
+ d_ptr->m_flagToProperty[prop] = property;
+ }
+
+ emit flagNamesChanged(property, data.flagNames);
+
+ emit propertyChanged(property);
+ emit valueChanged(property, data.val);
+}
+
+/*!
+ \reimp
+*/
+void QtFlagPropertyManager::initializeProperty(QtProperty *property)
+{
+ d_ptr->m_values[property] = QtFlagPropertyManagerPrivate::Data();
+
+ d_ptr->m_propertyToFlags[property] = QList<QtProperty *>();
+}
+
+/*!
+ \reimp
+*/
+void QtFlagPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ QListIterator<QtProperty *> itProp(d_ptr->m_propertyToFlags[property]);
+ while (itProp.hasNext()) {
+ QtProperty *prop = itProp.next();
+ if (prop) {
+ delete prop;
+ d_ptr->m_flagToProperty.remove(prop);
+ }
+ }
+ d_ptr->m_propertyToFlags.remove(property);
+
+ d_ptr->m_values.remove(property);
+}
+
+// QtSizePolicyPropertyManager
+
+class QtSizePolicyPropertyManagerPrivate
+{
+ QtSizePolicyPropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtSizePolicyPropertyManager)
+public:
+
+ QtSizePolicyPropertyManagerPrivate();
+
+ void slotIntChanged(QtProperty *property, int value);
+ void slotEnumChanged(QtProperty *property, int value);
+ void slotPropertyDestroyed(QtProperty *property);
+
+ typedef QMap<const QtProperty *, QSizePolicy> PropertyValueMap;
+ PropertyValueMap m_values;
+
+ QtIntPropertyManager *m_intPropertyManager;
+ QtEnumPropertyManager *m_enumPropertyManager;
+
+ QMap<const QtProperty *, QtProperty *> m_propertyToHPolicy;
+ QMap<const QtProperty *, QtProperty *> m_propertyToVPolicy;
+ QMap<const QtProperty *, QtProperty *> m_propertyToHStretch;
+ QMap<const QtProperty *, QtProperty *> m_propertyToVStretch;
+
+ QMap<const QtProperty *, QtProperty *> m_hPolicyToProperty;
+ QMap<const QtProperty *, QtProperty *> m_vPolicyToProperty;
+ QMap<const QtProperty *, QtProperty *> m_hStretchToProperty;
+ QMap<const QtProperty *, QtProperty *> m_vStretchToProperty;
+};
+
+QtSizePolicyPropertyManagerPrivate::QtSizePolicyPropertyManagerPrivate()
+{
+}
+
+void QtSizePolicyPropertyManagerPrivate::slotIntChanged(QtProperty *property, int value)
+{
+ if (QtProperty *prop = m_hStretchToProperty.value(property, 0)) {
+ QSizePolicy sp = m_values[prop];
+ sp.setHorizontalStretch(value);
+ q_ptr->setValue(prop, sp);
+ } else if (QtProperty *prop = m_vStretchToProperty.value(property, 0)) {
+ QSizePolicy sp = m_values[prop];
+ sp.setVerticalStretch(value);
+ q_ptr->setValue(prop, sp);
+ }
+}
+
+void QtSizePolicyPropertyManagerPrivate::slotEnumChanged(QtProperty *property, int value)
+{
+ if (QtProperty *prop = m_hPolicyToProperty.value(property, 0)) {
+ QSizePolicy sp = m_values[prop];
+ sp.setHorizontalPolicy(metaEnumProvider()->indexToSizePolicy(value));
+ q_ptr->setValue(prop, sp);
+ } else if (QtProperty *prop = m_vPolicyToProperty.value(property, 0)) {
+ QSizePolicy sp = m_values[prop];
+ sp.setVerticalPolicy(metaEnumProvider()->indexToSizePolicy(value));
+ q_ptr->setValue(prop, sp);
+ }
+}
+
+void QtSizePolicyPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property)
+{
+ if (QtProperty *pointProp = m_hStretchToProperty.value(property, 0)) {
+ m_propertyToHStretch[pointProp] = 0;
+ m_hStretchToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_vStretchToProperty.value(property, 0)) {
+ m_propertyToVStretch[pointProp] = 0;
+ m_vStretchToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_hPolicyToProperty.value(property, 0)) {
+ m_propertyToHPolicy[pointProp] = 0;
+ m_hPolicyToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_vPolicyToProperty.value(property, 0)) {
+ m_propertyToVPolicy[pointProp] = 0;
+ m_vPolicyToProperty.remove(property);
+ }
+}
+
+/*!
+ \class QtSizePolicyPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtSizePolicyPropertyManager provides and manages QSizePolicy properties.
+
+ A size policy property has nested \e horizontalPolicy, \e
+ verticalPolicy, \e horizontalStretch and \e verticalStretch
+ subproperties. The top-level property's value can be retrieved
+ using the value() function, and set using the setValue() slot.
+
+ The subproperties are created by QtIntPropertyManager and QtEnumPropertyManager
+ objects. These managers can be retrieved using the subIntPropertyManager()
+ and subEnumPropertyManager() functions respectively. In order to provide
+ editing widgets for the subproperties in a property browser widget,
+ these managers must be associated with editor factories.
+
+ In addition, QtSizePolicyPropertyManager provides the valueChanged()
+ signal which is emitted whenever a property created by this
+ manager changes.
+
+ \sa QtAbstractPropertyManager, QtIntPropertyManager, QtEnumPropertyManager
+*/
+
+/*!
+ \fn void QtSizePolicyPropertyManager::valueChanged(QtProperty *property, const QSizePolicy &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the
+ new \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtSizePolicyPropertyManager::QtSizePolicyPropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtSizePolicyPropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->m_intPropertyManager = new QtIntPropertyManager(this);
+ connect(d_ptr->m_intPropertyManager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotIntChanged(QtProperty*,int)));
+ d_ptr->m_enumPropertyManager = new QtEnumPropertyManager(this);
+ connect(d_ptr->m_enumPropertyManager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotEnumChanged(QtProperty*,int)));
+
+ connect(d_ptr->m_intPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
+ this, SLOT(slotPropertyDestroyed(QtProperty*)));
+ connect(d_ptr->m_enumPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
+ this, SLOT(slotPropertyDestroyed(QtProperty*)));
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtSizePolicyPropertyManager::~QtSizePolicyPropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the manager that creates the nested \e horizontalStretch
+ and \e verticalStretch subproperties.
+
+ In order to provide editing widgets for the mentioned subproperties
+ in a property browser widget, this manager must be associated with
+ an editor factory.
+
+ \sa QtAbstractPropertyBrowser::setFactoryForManager()
+*/
+QtIntPropertyManager *QtSizePolicyPropertyManager::subIntPropertyManager() const
+{
+ return d_ptr->m_intPropertyManager;
+}
+
+/*!
+ Returns the manager that creates the nested \e horizontalPolicy
+ and \e verticalPolicy subproperties.
+
+ In order to provide editing widgets for the mentioned subproperties
+ in a property browser widget, this manager must be associated with
+ an editor factory.
+
+ \sa QtAbstractPropertyBrowser::setFactoryForManager()
+*/
+QtEnumPropertyManager *QtSizePolicyPropertyManager::subEnumPropertyManager() const
+{
+ return d_ptr->m_enumPropertyManager;
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given property is not managed by this manager, this
+ function returns the default size policy.
+
+ \sa setValue()
+*/
+QSizePolicy QtSizePolicyPropertyManager::value(const QtProperty *property) const
+{
+ return d_ptr->m_values.value(property, QSizePolicy());
+}
+
+/*!
+ \reimp
+*/
+QString QtSizePolicyPropertyManager::valueText(const QtProperty *property) const
+{
+ const QtSizePolicyPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+
+ const QSizePolicy sp = it.value();
+ const QtMetaEnumProvider *mep = metaEnumProvider();
+ const int hIndex = mep->sizePolicyToIndex(sp.horizontalPolicy());
+ const int vIndex = mep->sizePolicyToIndex(sp.verticalPolicy());
+ //! Unknown size policy on reading invalid uic3 files
+ const QString hPolicy = hIndex != -1 ? mep->policyEnumNames().at(hIndex) : tr("<Invalid>");
+ const QString vPolicy = vIndex != -1 ? mep->policyEnumNames().at(vIndex) : tr("<Invalid>");
+ const QString str = tr("[%1, %2, %3, %4]").arg(hPolicy, vPolicy).arg(sp.horizontalStretch()).arg(sp.verticalStretch());
+ return str;
+}
+
+/*!
+ \fn void QtSizePolicyPropertyManager::setValue(QtProperty *property, const QSizePolicy &value)
+
+ Sets the value of the given \a property to \a value. Nested
+ properties are updated automatically.
+
+ \sa value(), valueChanged()
+*/
+void QtSizePolicyPropertyManager::setValue(QtProperty *property, const QSizePolicy &val)
+{
+ const QtSizePolicyPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ if (it.value() == val)
+ return;
+
+ it.value() = val;
+
+ d_ptr->m_enumPropertyManager->setValue(d_ptr->m_propertyToHPolicy[property],
+ metaEnumProvider()->sizePolicyToIndex(val.horizontalPolicy()));
+ d_ptr->m_enumPropertyManager->setValue(d_ptr->m_propertyToVPolicy[property],
+ metaEnumProvider()->sizePolicyToIndex(val.verticalPolicy()));
+ d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToHStretch[property],
+ val.horizontalStretch());
+ d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToVStretch[property],
+ val.verticalStretch());
+
+ emit propertyChanged(property);
+ emit valueChanged(property, val);
+}
+
+/*!
+ \reimp
+*/
+void QtSizePolicyPropertyManager::initializeProperty(QtProperty *property)
+{
+ QSizePolicy val;
+ d_ptr->m_values[property] = val;
+
+ QtProperty *hPolicyProp = d_ptr->m_enumPropertyManager->addProperty();
+ hPolicyProp->setPropertyName(tr("Horizontal Policy"));
+ d_ptr->m_enumPropertyManager->setEnumNames(hPolicyProp, metaEnumProvider()->policyEnumNames());
+ d_ptr->m_enumPropertyManager->setValue(hPolicyProp,
+ metaEnumProvider()->sizePolicyToIndex(val.horizontalPolicy()));
+ d_ptr->m_propertyToHPolicy[property] = hPolicyProp;
+ d_ptr->m_hPolicyToProperty[hPolicyProp] = property;
+ property->addSubProperty(hPolicyProp);
+
+ QtProperty *vPolicyProp = d_ptr->m_enumPropertyManager->addProperty();
+ vPolicyProp->setPropertyName(tr("Vertical Policy"));
+ d_ptr->m_enumPropertyManager->setEnumNames(vPolicyProp, metaEnumProvider()->policyEnumNames());
+ d_ptr->m_enumPropertyManager->setValue(vPolicyProp,
+ metaEnumProvider()->sizePolicyToIndex(val.verticalPolicy()));
+ d_ptr->m_propertyToVPolicy[property] = vPolicyProp;
+ d_ptr->m_vPolicyToProperty[vPolicyProp] = property;
+ property->addSubProperty(vPolicyProp);
+
+ QtProperty *hStretchProp = d_ptr->m_intPropertyManager->addProperty();
+ hStretchProp->setPropertyName(tr("Horizontal Stretch"));
+ d_ptr->m_intPropertyManager->setValue(hStretchProp, val.horizontalStretch());
+ d_ptr->m_intPropertyManager->setRange(hStretchProp, 0, 0xff);
+ d_ptr->m_propertyToHStretch[property] = hStretchProp;
+ d_ptr->m_hStretchToProperty[hStretchProp] = property;
+ property->addSubProperty(hStretchProp);
+
+ QtProperty *vStretchProp = d_ptr->m_intPropertyManager->addProperty();
+ vStretchProp->setPropertyName(tr("Vertical Stretch"));
+ d_ptr->m_intPropertyManager->setValue(vStretchProp, val.verticalStretch());
+ d_ptr->m_intPropertyManager->setRange(vStretchProp, 0, 0xff);
+ d_ptr->m_propertyToVStretch[property] = vStretchProp;
+ d_ptr->m_vStretchToProperty[vStretchProp] = property;
+ property->addSubProperty(vStretchProp);
+
+}
+
+/*!
+ \reimp
+*/
+void QtSizePolicyPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ QtProperty *hPolicyProp = d_ptr->m_propertyToHPolicy[property];
+ if (hPolicyProp) {
+ d_ptr->m_hPolicyToProperty.remove(hPolicyProp);
+ delete hPolicyProp;
+ }
+ d_ptr->m_propertyToHPolicy.remove(property);
+
+ QtProperty *vPolicyProp = d_ptr->m_propertyToVPolicy[property];
+ if (vPolicyProp) {
+ d_ptr->m_vPolicyToProperty.remove(vPolicyProp);
+ delete vPolicyProp;
+ }
+ d_ptr->m_propertyToVPolicy.remove(property);
+
+ QtProperty *hStretchProp = d_ptr->m_propertyToHStretch[property];
+ if (hStretchProp) {
+ d_ptr->m_hStretchToProperty.remove(hStretchProp);
+ delete hStretchProp;
+ }
+ d_ptr->m_propertyToHStretch.remove(property);
+
+ QtProperty *vStretchProp = d_ptr->m_propertyToVStretch[property];
+ if (vStretchProp) {
+ d_ptr->m_vStretchToProperty.remove(vStretchProp);
+ delete vStretchProp;
+ }
+ d_ptr->m_propertyToVStretch.remove(property);
+
+ d_ptr->m_values.remove(property);
+}
+
+// QtFontPropertyManager:
+// QtFontPropertyManagerPrivate has a mechanism for reacting
+// to QApplication::fontDatabaseChanged() [4.5], which is emitted
+// when someone loads an application font. The signals are compressed
+// using a timer with interval 0, which then causes the family
+// enumeration manager to re-set its strings and index values
+// for each property.
+
+Q_GLOBAL_STATIC(QFontDatabase, fontDatabase)
+
+class QtFontPropertyManagerPrivate
+{
+ QtFontPropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtFontPropertyManager)
+public:
+
+ QtFontPropertyManagerPrivate();
+
+ void slotIntChanged(QtProperty *property, int value);
+ void slotEnumChanged(QtProperty *property, int value);
+ void slotBoolChanged(QtProperty *property, bool value);
+ void slotPropertyDestroyed(QtProperty *property);
+ void slotFontDatabaseChanged();
+ void slotFontDatabaseDelayedChange();
+
+ QStringList m_familyNames;
+
+ typedef QMap<const QtProperty *, QFont> PropertyValueMap;
+ PropertyValueMap m_values;
+
+ QtIntPropertyManager *m_intPropertyManager;
+ QtEnumPropertyManager *m_enumPropertyManager;
+ QtBoolPropertyManager *m_boolPropertyManager;
+
+ QMap<const QtProperty *, QtProperty *> m_propertyToFamily;
+ QMap<const QtProperty *, QtProperty *> m_propertyToPointSize;
+ QMap<const QtProperty *, QtProperty *> m_propertyToBold;
+ QMap<const QtProperty *, QtProperty *> m_propertyToItalic;
+ QMap<const QtProperty *, QtProperty *> m_propertyToUnderline;
+ QMap<const QtProperty *, QtProperty *> m_propertyToStrikeOut;
+ QMap<const QtProperty *, QtProperty *> m_propertyToKerning;
+
+ QMap<const QtProperty *, QtProperty *> m_familyToProperty;
+ QMap<const QtProperty *, QtProperty *> m_pointSizeToProperty;
+ QMap<const QtProperty *, QtProperty *> m_boldToProperty;
+ QMap<const QtProperty *, QtProperty *> m_italicToProperty;
+ QMap<const QtProperty *, QtProperty *> m_underlineToProperty;
+ QMap<const QtProperty *, QtProperty *> m_strikeOutToProperty;
+ QMap<const QtProperty *, QtProperty *> m_kerningToProperty;
+
+ bool m_settingValue;
+ QTimer *m_fontDatabaseChangeTimer;
+};
+
+QtFontPropertyManagerPrivate::QtFontPropertyManagerPrivate() :
+ m_settingValue(false),
+ m_fontDatabaseChangeTimer(0)
+{
+}
+
+void QtFontPropertyManagerPrivate::slotIntChanged(QtProperty *property, int value)
+{
+ if (m_settingValue)
+ return;
+ if (QtProperty *prop = m_pointSizeToProperty.value(property, 0)) {
+ QFont f = m_values[prop];
+ f.setPointSize(value);
+ q_ptr->setValue(prop, f);
+ }
+}
+
+void QtFontPropertyManagerPrivate::slotEnumChanged(QtProperty *property, int value)
+{
+ if (m_settingValue)
+ return;
+ if (QtProperty *prop = m_familyToProperty.value(property, 0)) {
+ QFont f = m_values[prop];
+ f.setFamily(m_familyNames.at(value));
+ q_ptr->setValue(prop, f);
+ }
+}
+
+void QtFontPropertyManagerPrivate::slotBoolChanged(QtProperty *property, bool value)
+{
+ if (m_settingValue)
+ return;
+ if (QtProperty *prop = m_boldToProperty.value(property, 0)) {
+ QFont f = m_values[prop];
+ f.setBold(value);
+ q_ptr->setValue(prop, f);
+ } else if (QtProperty *prop = m_italicToProperty.value(property, 0)) {
+ QFont f = m_values[prop];
+ f.setItalic(value);
+ q_ptr->setValue(prop, f);
+ } else if (QtProperty *prop = m_underlineToProperty.value(property, 0)) {
+ QFont f = m_values[prop];
+ f.setUnderline(value);
+ q_ptr->setValue(prop, f);
+ } else if (QtProperty *prop = m_strikeOutToProperty.value(property, 0)) {
+ QFont f = m_values[prop];
+ f.setStrikeOut(value);
+ q_ptr->setValue(prop, f);
+ } else if (QtProperty *prop = m_kerningToProperty.value(property, 0)) {
+ QFont f = m_values[prop];
+ f.setKerning(value);
+ q_ptr->setValue(prop, f);
+ }
+}
+
+void QtFontPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property)
+{
+ if (QtProperty *pointProp = m_pointSizeToProperty.value(property, 0)) {
+ m_propertyToPointSize[pointProp] = 0;
+ m_pointSizeToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_familyToProperty.value(property, 0)) {
+ m_propertyToFamily[pointProp] = 0;
+ m_familyToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_boldToProperty.value(property, 0)) {
+ m_propertyToBold[pointProp] = 0;
+ m_boldToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_italicToProperty.value(property, 0)) {
+ m_propertyToItalic[pointProp] = 0;
+ m_italicToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_underlineToProperty.value(property, 0)) {
+ m_propertyToUnderline[pointProp] = 0;
+ m_underlineToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_strikeOutToProperty.value(property, 0)) {
+ m_propertyToStrikeOut[pointProp] = 0;
+ m_strikeOutToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_kerningToProperty.value(property, 0)) {
+ m_propertyToKerning[pointProp] = 0;
+ m_kerningToProperty.remove(property);
+ }
+}
+
+void QtFontPropertyManagerPrivate::slotFontDatabaseChanged()
+{
+ if (!m_fontDatabaseChangeTimer) {
+ m_fontDatabaseChangeTimer = new QTimer(q_ptr);
+ m_fontDatabaseChangeTimer->setInterval(0);
+ m_fontDatabaseChangeTimer->setSingleShot(true);
+ QObject::connect(m_fontDatabaseChangeTimer, SIGNAL(timeout()), q_ptr, SLOT(slotFontDatabaseDelayedChange()));
+ }
+ if (!m_fontDatabaseChangeTimer->isActive())
+ m_fontDatabaseChangeTimer->start();
+}
+
+void QtFontPropertyManagerPrivate::slotFontDatabaseDelayedChange()
+{
+ typedef QMap<const QtProperty *, QtProperty *> PropertyPropertyMap;
+ // rescan available font names
+ const QStringList oldFamilies = m_familyNames;
+ m_familyNames = fontDatabase()->families();
+
+ // Adapt all existing properties
+ if (!m_propertyToFamily.empty()) {
+ PropertyPropertyMap::const_iterator cend = m_propertyToFamily.constEnd();
+ for (PropertyPropertyMap::const_iterator it = m_propertyToFamily.constBegin(); it != cend; ++it) {
+ QtProperty *familyProp = it.value();
+ const int oldIdx = m_enumPropertyManager->value(familyProp);
+ int newIdx = m_familyNames.indexOf(oldFamilies.at(oldIdx));
+ if (newIdx < 0)
+ newIdx = 0;
+ m_enumPropertyManager->setEnumNames(familyProp, m_familyNames);
+ m_enumPropertyManager->setValue(familyProp, newIdx);
+ }
+ }
+}
+
+/*!
+ \class QtFontPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtFontPropertyManager provides and manages QFont properties.
+
+ A font property has nested \e family, \e pointSize, \e bold, \e
+ italic, \e underline, \e strikeOut and \e kerning subproperties. The top-level
+ property's value can be retrieved using the value() function, and
+ set using the setValue() slot.
+
+ The subproperties are created by QtIntPropertyManager, QtEnumPropertyManager and
+ QtBoolPropertyManager objects. These managers can be retrieved using the
+ corresponding subIntPropertyManager(), subEnumPropertyManager() and
+ subBoolPropertyManager() functions. In order to provide editing widgets
+ for the subproperties in a property browser widget, these managers
+ must be associated with editor factories.
+
+ In addition, QtFontPropertyManager provides the valueChanged() signal
+ which is emitted whenever a property created by this manager
+ changes.
+
+ \sa QtAbstractPropertyManager, QtEnumPropertyManager, QtIntPropertyManager, QtBoolPropertyManager
+*/
+
+/*!
+ \fn void QtFontPropertyManager::valueChanged(QtProperty *property, const QFont &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the
+ new \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtFontPropertyManager::QtFontPropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtFontPropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+ QObject::connect(qApp, SIGNAL(fontDatabaseChanged()), this, SLOT(slotFontDatabaseChanged()));
+
+ d_ptr->m_intPropertyManager = new QtIntPropertyManager(this);
+ connect(d_ptr->m_intPropertyManager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotIntChanged(QtProperty*,int)));
+ d_ptr->m_enumPropertyManager = new QtEnumPropertyManager(this);
+ connect(d_ptr->m_enumPropertyManager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotEnumChanged(QtProperty*,int)));
+ d_ptr->m_boolPropertyManager = new QtBoolPropertyManager(this);
+ connect(d_ptr->m_boolPropertyManager, SIGNAL(valueChanged(QtProperty*,bool)),
+ this, SLOT(slotBoolChanged(QtProperty*,bool)));
+
+ connect(d_ptr->m_intPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
+ this, SLOT(slotPropertyDestroyed(QtProperty*)));
+ connect(d_ptr->m_enumPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
+ this, SLOT(slotPropertyDestroyed(QtProperty*)));
+ connect(d_ptr->m_boolPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
+ this, SLOT(slotPropertyDestroyed(QtProperty*)));
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtFontPropertyManager::~QtFontPropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the manager that creates the \e pointSize subproperty.
+
+ In order to provide editing widgets for the \e pointSize property
+ in a property browser widget, this manager must be associated
+ with an editor factory.
+
+ \sa QtAbstractPropertyBrowser::setFactoryForManager()
+*/
+QtIntPropertyManager *QtFontPropertyManager::subIntPropertyManager() const
+{
+ return d_ptr->m_intPropertyManager;
+}
+
+/*!
+ Returns the manager that create the \e family subproperty.
+
+ In order to provide editing widgets for the \e family property
+ in a property browser widget, this manager must be associated
+ with an editor factory.
+
+ \sa QtAbstractPropertyBrowser::setFactoryForManager()
+*/
+QtEnumPropertyManager *QtFontPropertyManager::subEnumPropertyManager() const
+{
+ return d_ptr->m_enumPropertyManager;
+}
+
+/*!
+ Returns the manager that creates the \e bold, \e italic, \e underline,
+ \e strikeOut and \e kerning subproperties.
+
+ In order to provide editing widgets for the mentioned properties
+ in a property browser widget, this manager must be associated with
+ an editor factory.
+
+ \sa QtAbstractPropertyBrowser::setFactoryForManager()
+*/
+QtBoolPropertyManager *QtFontPropertyManager::subBoolPropertyManager() const
+{
+ return d_ptr->m_boolPropertyManager;
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given property is not managed by this manager, this
+ function returns a font object that uses the application's default
+ font.
+
+ \sa setValue()
+*/
+QFont QtFontPropertyManager::value(const QtProperty *property) const
+{
+ return d_ptr->m_values.value(property, QFont());
+}
+
+/*!
+ \reimp
+*/
+QString QtFontPropertyManager::valueText(const QtProperty *property) const
+{
+ const QtFontPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+
+ return QtPropertyBrowserUtils::fontValueText(it.value());
+}
+
+/*!
+ \reimp
+*/
+QIcon QtFontPropertyManager::valueIcon(const QtProperty *property) const
+{
+ const QtFontPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QIcon();
+
+ return QtPropertyBrowserUtils::fontValueIcon(it.value());
+}
+
+/*!
+ \fn void QtFontPropertyManager::setValue(QtProperty *property, const QFont &value)
+
+ Sets the value of the given \a property to \a value. Nested
+ properties are updated automatically.
+
+ \sa value(), valueChanged()
+*/
+void QtFontPropertyManager::setValue(QtProperty *property, const QFont &val)
+{
+ const QtFontPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ const QFont oldVal = it.value();
+ if (oldVal == val && oldVal.resolve() == val.resolve())
+ return;
+
+ it.value() = val;
+
+ int idx = d_ptr->m_familyNames.indexOf(val.family());
+ if (idx == -1)
+ idx = 0;
+ bool settingValue = d_ptr->m_settingValue;
+ d_ptr->m_settingValue = true;
+ d_ptr->m_enumPropertyManager->setValue(d_ptr->m_propertyToFamily[property], idx);
+ d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToPointSize[property], val.pointSize());
+ d_ptr->m_boolPropertyManager->setValue(d_ptr->m_propertyToBold[property], val.bold());
+ d_ptr->m_boolPropertyManager->setValue(d_ptr->m_propertyToItalic[property], val.italic());
+ d_ptr->m_boolPropertyManager->setValue(d_ptr->m_propertyToUnderline[property], val.underline());
+ d_ptr->m_boolPropertyManager->setValue(d_ptr->m_propertyToStrikeOut[property], val.strikeOut());
+ d_ptr->m_boolPropertyManager->setValue(d_ptr->m_propertyToKerning[property], val.kerning());
+ d_ptr->m_settingValue = settingValue;
+
+ emit propertyChanged(property);
+ emit valueChanged(property, val);
+}
+
+/*!
+ \reimp
+*/
+void QtFontPropertyManager::initializeProperty(QtProperty *property)
+{
+ QFont val;
+ d_ptr->m_values[property] = val;
+
+ QtProperty *familyProp = d_ptr->m_enumPropertyManager->addProperty();
+ familyProp->setPropertyName(tr("Family"));
+ if (d_ptr->m_familyNames.empty())
+ d_ptr->m_familyNames = fontDatabase()->families();
+ d_ptr->m_enumPropertyManager->setEnumNames(familyProp, d_ptr->m_familyNames);
+ int idx = d_ptr->m_familyNames.indexOf(val.family());
+ if (idx == -1)
+ idx = 0;
+ d_ptr->m_enumPropertyManager->setValue(familyProp, idx);
+ d_ptr->m_propertyToFamily[property] = familyProp;
+ d_ptr->m_familyToProperty[familyProp] = property;
+ property->addSubProperty(familyProp);
+
+ QtProperty *pointSizeProp = d_ptr->m_intPropertyManager->addProperty();
+ pointSizeProp->setPropertyName(tr("Point Size"));
+ d_ptr->m_intPropertyManager->setValue(pointSizeProp, val.pointSize());
+ d_ptr->m_intPropertyManager->setMinimum(pointSizeProp, 1);
+ d_ptr->m_propertyToPointSize[property] = pointSizeProp;
+ d_ptr->m_pointSizeToProperty[pointSizeProp] = property;
+ property->addSubProperty(pointSizeProp);
+
+ QtProperty *boldProp = d_ptr->m_boolPropertyManager->addProperty();
+ boldProp->setPropertyName(tr("Bold"));
+ d_ptr->m_boolPropertyManager->setValue(boldProp, val.bold());
+ d_ptr->m_propertyToBold[property] = boldProp;
+ d_ptr->m_boldToProperty[boldProp] = property;
+ property->addSubProperty(boldProp);
+
+ QtProperty *italicProp = d_ptr->m_boolPropertyManager->addProperty();
+ italicProp->setPropertyName(tr("Italic"));
+ d_ptr->m_boolPropertyManager->setValue(italicProp, val.italic());
+ d_ptr->m_propertyToItalic[property] = italicProp;
+ d_ptr->m_italicToProperty[italicProp] = property;
+ property->addSubProperty(italicProp);
+
+ QtProperty *underlineProp = d_ptr->m_boolPropertyManager->addProperty();
+ underlineProp->setPropertyName(tr("Underline"));
+ d_ptr->m_boolPropertyManager->setValue(underlineProp, val.underline());
+ d_ptr->m_propertyToUnderline[property] = underlineProp;
+ d_ptr->m_underlineToProperty[underlineProp] = property;
+ property->addSubProperty(underlineProp);
+
+ QtProperty *strikeOutProp = d_ptr->m_boolPropertyManager->addProperty();
+ strikeOutProp->setPropertyName(tr("Strikeout"));
+ d_ptr->m_boolPropertyManager->setValue(strikeOutProp, val.strikeOut());
+ d_ptr->m_propertyToStrikeOut[property] = strikeOutProp;
+ d_ptr->m_strikeOutToProperty[strikeOutProp] = property;
+ property->addSubProperty(strikeOutProp);
+
+ QtProperty *kerningProp = d_ptr->m_boolPropertyManager->addProperty();
+ kerningProp->setPropertyName(tr("Kerning"));
+ d_ptr->m_boolPropertyManager->setValue(kerningProp, val.kerning());
+ d_ptr->m_propertyToKerning[property] = kerningProp;
+ d_ptr->m_kerningToProperty[kerningProp] = property;
+ property->addSubProperty(kerningProp);
+}
+
+/*!
+ \reimp
+*/
+void QtFontPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ QtProperty *familyProp = d_ptr->m_propertyToFamily[property];
+ if (familyProp) {
+ d_ptr->m_familyToProperty.remove(familyProp);
+ delete familyProp;
+ }
+ d_ptr->m_propertyToFamily.remove(property);
+
+ QtProperty *pointSizeProp = d_ptr->m_propertyToPointSize[property];
+ if (pointSizeProp) {
+ d_ptr->m_pointSizeToProperty.remove(pointSizeProp);
+ delete pointSizeProp;
+ }
+ d_ptr->m_propertyToPointSize.remove(property);
+
+ QtProperty *boldProp = d_ptr->m_propertyToBold[property];
+ if (boldProp) {
+ d_ptr->m_boldToProperty.remove(boldProp);
+ delete boldProp;
+ }
+ d_ptr->m_propertyToBold.remove(property);
+
+ QtProperty *italicProp = d_ptr->m_propertyToItalic[property];
+ if (italicProp) {
+ d_ptr->m_italicToProperty.remove(italicProp);
+ delete italicProp;
+ }
+ d_ptr->m_propertyToItalic.remove(property);
+
+ QtProperty *underlineProp = d_ptr->m_propertyToUnderline[property];
+ if (underlineProp) {
+ d_ptr->m_underlineToProperty.remove(underlineProp);
+ delete underlineProp;
+ }
+ d_ptr->m_propertyToUnderline.remove(property);
+
+ QtProperty *strikeOutProp = d_ptr->m_propertyToStrikeOut[property];
+ if (strikeOutProp) {
+ d_ptr->m_strikeOutToProperty.remove(strikeOutProp);
+ delete strikeOutProp;
+ }
+ d_ptr->m_propertyToStrikeOut.remove(property);
+
+ QtProperty *kerningProp = d_ptr->m_propertyToKerning[property];
+ if (kerningProp) {
+ d_ptr->m_kerningToProperty.remove(kerningProp);
+ delete kerningProp;
+ }
+ d_ptr->m_propertyToKerning.remove(property);
+
+ d_ptr->m_values.remove(property);
+}
+
+// QtColorPropertyManager
+
+class QtColorPropertyManagerPrivate
+{
+ QtColorPropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtColorPropertyManager)
+public:
+
+ void slotIntChanged(QtProperty *property, int value);
+ void slotPropertyDestroyed(QtProperty *property);
+
+ typedef QMap<const QtProperty *, QColor> PropertyValueMap;
+ PropertyValueMap m_values;
+
+ QtIntPropertyManager *m_intPropertyManager;
+
+ QMap<const QtProperty *, QtProperty *> m_propertyToR;
+ QMap<const QtProperty *, QtProperty *> m_propertyToG;
+ QMap<const QtProperty *, QtProperty *> m_propertyToB;
+ QMap<const QtProperty *, QtProperty *> m_propertyToA;
+
+ QMap<const QtProperty *, QtProperty *> m_rToProperty;
+ QMap<const QtProperty *, QtProperty *> m_gToProperty;
+ QMap<const QtProperty *, QtProperty *> m_bToProperty;
+ QMap<const QtProperty *, QtProperty *> m_aToProperty;
+};
+
+void QtColorPropertyManagerPrivate::slotIntChanged(QtProperty *property, int value)
+{
+ if (QtProperty *prop = m_rToProperty.value(property, 0)) {
+ QColor c = m_values[prop];
+ c.setRed(value);
+ q_ptr->setValue(prop, c);
+ } else if (QtProperty *prop = m_gToProperty.value(property, 0)) {
+ QColor c = m_values[prop];
+ c.setGreen(value);
+ q_ptr->setValue(prop, c);
+ } else if (QtProperty *prop = m_bToProperty.value(property, 0)) {
+ QColor c = m_values[prop];
+ c.setBlue(value);
+ q_ptr->setValue(prop, c);
+ } else if (QtProperty *prop = m_aToProperty.value(property, 0)) {
+ QColor c = m_values[prop];
+ c.setAlpha(value);
+ q_ptr->setValue(prop, c);
+ }
+}
+
+void QtColorPropertyManagerPrivate::slotPropertyDestroyed(QtProperty *property)
+{
+ if (QtProperty *pointProp = m_rToProperty.value(property, 0)) {
+ m_propertyToR[pointProp] = 0;
+ m_rToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_gToProperty.value(property, 0)) {
+ m_propertyToG[pointProp] = 0;
+ m_gToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_bToProperty.value(property, 0)) {
+ m_propertyToB[pointProp] = 0;
+ m_bToProperty.remove(property);
+ } else if (QtProperty *pointProp = m_aToProperty.value(property, 0)) {
+ m_propertyToA[pointProp] = 0;
+ m_aToProperty.remove(property);
+ }
+}
+
+/*!
+ \class QtColorPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtColorPropertyManager provides and manages QColor properties.
+
+ A color property has nested \e red, \e green and \e blue
+ subproperties. The top-level property's value can be retrieved
+ using the value() function, and set using the setValue() slot.
+
+ The subproperties are created by a QtIntPropertyManager object. This
+ manager can be retrieved using the subIntPropertyManager() function. In
+ order to provide editing widgets for the subproperties in a
+ property browser widget, this manager must be associated with an
+ editor factory.
+
+ In addition, QtColorPropertyManager provides the valueChanged() signal
+ which is emitted whenever a property created by this manager
+ changes.
+
+ \sa QtAbstractPropertyManager, QtAbstractPropertyBrowser, QtIntPropertyManager
+*/
+
+/*!
+ \fn void QtColorPropertyManager::valueChanged(QtProperty *property, const QColor &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the new
+ \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtColorPropertyManager::QtColorPropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtColorPropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->m_intPropertyManager = new QtIntPropertyManager(this);
+ connect(d_ptr->m_intPropertyManager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotIntChanged(QtProperty*,int)));
+
+ connect(d_ptr->m_intPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
+ this, SLOT(slotPropertyDestroyed(QtProperty*)));
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtColorPropertyManager::~QtColorPropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the manager that produces the nested \e red, \e green and
+ \e blue subproperties.
+
+ In order to provide editing widgets for the subproperties in a
+ property browser widget, this manager must be associated with an
+ editor factory.
+
+ \sa QtAbstractPropertyBrowser::setFactoryForManager()
+*/
+QtIntPropertyManager *QtColorPropertyManager::subIntPropertyManager() const
+{
+ return d_ptr->m_intPropertyManager;
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given \a property is not managed by \e this manager, this
+ function returns an invalid color.
+
+ \sa setValue()
+*/
+QColor QtColorPropertyManager::value(const QtProperty *property) const
+{
+ return d_ptr->m_values.value(property, QColor());
+}
+
+/*!
+ \reimp
+*/
+
+QString QtColorPropertyManager::valueText(const QtProperty *property) const
+{
+ const QtColorPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+
+ return QtPropertyBrowserUtils::colorValueText(it.value());
+}
+
+/*!
+ \reimp
+*/
+
+QIcon QtColorPropertyManager::valueIcon(const QtProperty *property) const
+{
+ const QtColorPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QIcon();
+ return QtPropertyBrowserUtils::brushValueIcon(QBrush(it.value()));
+}
+
+/*!
+ \fn void QtColorPropertyManager::setValue(QtProperty *property, const QColor &value)
+
+ Sets the value of the given \a property to \a value. Nested
+ properties are updated automatically.
+
+ \sa value(), valueChanged()
+*/
+void QtColorPropertyManager::setValue(QtProperty *property, const QColor &val)
+{
+ const QtColorPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ if (it.value() == val)
+ return;
+
+ it.value() = val;
+
+ d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToR[property], val.red());
+ d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToG[property], val.green());
+ d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToB[property], val.blue());
+ d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToA[property], val.alpha());
+
+ emit propertyChanged(property);
+ emit valueChanged(property, val);
+}
+
+/*!
+ \reimp
+*/
+void QtColorPropertyManager::initializeProperty(QtProperty *property)
+{
+ QColor val;
+ d_ptr->m_values[property] = val;
+
+ QtProperty *rProp = d_ptr->m_intPropertyManager->addProperty();
+ rProp->setPropertyName(tr("Red"));
+ d_ptr->m_intPropertyManager->setValue(rProp, val.red());
+ d_ptr->m_intPropertyManager->setRange(rProp, 0, 0xFF);
+ d_ptr->m_propertyToR[property] = rProp;
+ d_ptr->m_rToProperty[rProp] = property;
+ property->addSubProperty(rProp);
+
+ QtProperty *gProp = d_ptr->m_intPropertyManager->addProperty();
+ gProp->setPropertyName(tr("Green"));
+ d_ptr->m_intPropertyManager->setValue(gProp, val.green());
+ d_ptr->m_intPropertyManager->setRange(gProp, 0, 0xFF);
+ d_ptr->m_propertyToG[property] = gProp;
+ d_ptr->m_gToProperty[gProp] = property;
+ property->addSubProperty(gProp);
+
+ QtProperty *bProp = d_ptr->m_intPropertyManager->addProperty();
+ bProp->setPropertyName(tr("Blue"));
+ d_ptr->m_intPropertyManager->setValue(bProp, val.blue());
+ d_ptr->m_intPropertyManager->setRange(bProp, 0, 0xFF);
+ d_ptr->m_propertyToB[property] = bProp;
+ d_ptr->m_bToProperty[bProp] = property;
+ property->addSubProperty(bProp);
+
+ QtProperty *aProp = d_ptr->m_intPropertyManager->addProperty();
+ aProp->setPropertyName(tr("Alpha"));
+ d_ptr->m_intPropertyManager->setValue(aProp, val.alpha());
+ d_ptr->m_intPropertyManager->setRange(aProp, 0, 0xFF);
+ d_ptr->m_propertyToA[property] = aProp;
+ d_ptr->m_aToProperty[aProp] = property;
+ property->addSubProperty(aProp);
+}
+
+/*!
+ \reimp
+*/
+void QtColorPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ QtProperty *rProp = d_ptr->m_propertyToR[property];
+ if (rProp) {
+ d_ptr->m_rToProperty.remove(rProp);
+ delete rProp;
+ }
+ d_ptr->m_propertyToR.remove(property);
+
+ QtProperty *gProp = d_ptr->m_propertyToG[property];
+ if (gProp) {
+ d_ptr->m_gToProperty.remove(gProp);
+ delete gProp;
+ }
+ d_ptr->m_propertyToG.remove(property);
+
+ QtProperty *bProp = d_ptr->m_propertyToB[property];
+ if (bProp) {
+ d_ptr->m_bToProperty.remove(bProp);
+ delete bProp;
+ }
+ d_ptr->m_propertyToB.remove(property);
+
+ QtProperty *aProp = d_ptr->m_propertyToA[property];
+ if (aProp) {
+ d_ptr->m_aToProperty.remove(aProp);
+ delete aProp;
+ }
+ d_ptr->m_propertyToA.remove(property);
+
+ d_ptr->m_values.remove(property);
+}
+
+// QtCursorPropertyManager
+
+// Make sure icons are removed as soon as QApplication is destroyed, otherwise,
+// handles are leaked on X11.
+static void clearCursorDatabase();
+Q_GLOBAL_STATIC_WITH_INITIALIZER(QtCursorDatabase, cursorDatabase, qAddPostRoutine(clearCursorDatabase))
+
+static void clearCursorDatabase()
+{
+ cursorDatabase()->clear();
+}
+
+class QtCursorPropertyManagerPrivate
+{
+ QtCursorPropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtCursorPropertyManager)
+public:
+ typedef QMap<const QtProperty *, QCursor> PropertyValueMap;
+ PropertyValueMap m_values;
+};
+
+/*!
+ \class QtCursorPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtCursorPropertyManager provides and manages QCursor properties.
+
+ A cursor property has a current value which can be
+ retrieved using the value() function, and set using the setValue()
+ slot. In addition, QtCursorPropertyManager provides the
+ valueChanged() signal which is emitted whenever a property created
+ by this manager changes.
+
+ \sa QtAbstractPropertyManager
+*/
+
+/*!
+ \fn void QtCursorPropertyManager::valueChanged(QtProperty *property, const QCursor &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the new
+ \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtCursorPropertyManager::QtCursorPropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtCursorPropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtCursorPropertyManager::~QtCursorPropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given \a property is not managed by this manager, this
+ function returns a default QCursor object.
+
+ \sa setValue()
+*/
+#ifndef QT_NO_CURSOR
+QCursor QtCursorPropertyManager::value(const QtProperty *property) const
+{
+ return d_ptr->m_values.value(property, QCursor());
+}
+#endif
+
+/*!
+ \reimp
+*/
+QString QtCursorPropertyManager::valueText(const QtProperty *property) const
+{
+ const QtCursorPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QString();
+
+ return cursorDatabase()->cursorToShapeName(it.value());
+}
+
+/*!
+ \reimp
+*/
+QIcon QtCursorPropertyManager::valueIcon(const QtProperty *property) const
+{
+ const QtCursorPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
+ if (it == d_ptr->m_values.constEnd())
+ return QIcon();
+
+ return cursorDatabase()->cursorToShapeIcon(it.value());
+}
+
+/*!
+ \fn void QtCursorPropertyManager::setValue(QtProperty *property, const QCursor &value)
+
+ Sets the value of the given \a property to \a value.
+
+ \sa value(), valueChanged()
+*/
+void QtCursorPropertyManager::setValue(QtProperty *property, const QCursor &value)
+{
+#ifndef QT_NO_CURSOR
+ const QtCursorPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
+ if (it == d_ptr->m_values.end())
+ return;
+
+ if (it.value().shape() == value.shape() && value.shape() != Qt::BitmapCursor)
+ return;
+
+ it.value() = value;
+
+ emit propertyChanged(property);
+ emit valueChanged(property, value);
+#endif
+}
+
+/*!
+ \reimp
+*/
+void QtCursorPropertyManager::initializeProperty(QtProperty *property)
+{
+#ifndef QT_NO_CURSOR
+ d_ptr->m_values[property] = QCursor();
+#endif
+}
+
+/*!
+ \reimp
+*/
+void QtCursorPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ d_ptr->m_values.remove(property);
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qtpropertymanager.cpp"
+#include "qtpropertymanager.moc"
diff --git a/src/shared/qtpropertybrowser/qtpropertymanager.h b/src/shared/qtpropertybrowser/qtpropertymanager.h
new file mode 100644
index 000000000..f821ff152
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qtpropertymanager.h
@@ -0,0 +1,746 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTPROPERTYMANAGER_H
+#define QTPROPERTYMANAGER_H
+
+#include "qtpropertybrowser.h"
+
+QT_BEGIN_NAMESPACE
+
+class QDate;
+class QTime;
+class QDateTime;
+class QLocale;
+
+class QtGroupPropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtGroupPropertyManager(QObject *parent = 0);
+ ~QtGroupPropertyManager();
+
+protected:
+ virtual bool hasValue(const QtProperty *property) const;
+
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+};
+
+class QtIntPropertyManagerPrivate;
+
+class QtIntPropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtIntPropertyManager(QObject *parent = 0);
+ ~QtIntPropertyManager();
+
+ int value(const QtProperty *property) const;
+ int minimum(const QtProperty *property) const;
+ int maximum(const QtProperty *property) const;
+ int singleStep(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, int val);
+ void setMinimum(QtProperty *property, int minVal);
+ void setMaximum(QtProperty *property, int maxVal);
+ void setRange(QtProperty *property, int minVal, int maxVal);
+ void setSingleStep(QtProperty *property, int step);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, int val);
+ void rangeChanged(QtProperty *property, int minVal, int maxVal);
+ void singleStepChanged(QtProperty *property, int step);
+protected:
+ QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtIntPropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtIntPropertyManager)
+ Q_DISABLE_COPY(QtIntPropertyManager)
+};
+
+class QtBoolPropertyManagerPrivate;
+
+class QtBoolPropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtBoolPropertyManager(QObject *parent = 0);
+ ~QtBoolPropertyManager();
+
+ bool value(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, bool val);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, bool val);
+protected:
+ QString valueText(const QtProperty *property) const;
+ QIcon valueIcon(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtBoolPropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtBoolPropertyManager)
+ Q_DISABLE_COPY(QtBoolPropertyManager)
+};
+
+class QtDoublePropertyManagerPrivate;
+
+class QtDoublePropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtDoublePropertyManager(QObject *parent = 0);
+ ~QtDoublePropertyManager();
+
+ double value(const QtProperty *property) const;
+ double minimum(const QtProperty *property) const;
+ double maximum(const QtProperty *property) const;
+ double singleStep(const QtProperty *property) const;
+ int decimals(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, double val);
+ void setMinimum(QtProperty *property, double minVal);
+ void setMaximum(QtProperty *property, double maxVal);
+ void setRange(QtProperty *property, double minVal, double maxVal);
+ void setSingleStep(QtProperty *property, double step);
+ void setDecimals(QtProperty *property, int prec);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, double val);
+ void rangeChanged(QtProperty *property, double minVal, double maxVal);
+ void singleStepChanged(QtProperty *property, double step);
+ void decimalsChanged(QtProperty *property, int prec);
+protected:
+ QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtDoublePropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtDoublePropertyManager)
+ Q_DISABLE_COPY(QtDoublePropertyManager)
+};
+
+class QtStringPropertyManagerPrivate;
+
+class QtStringPropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtStringPropertyManager(QObject *parent = 0);
+ ~QtStringPropertyManager();
+
+ QString value(const QtProperty *property) const;
+ QRegExp regExp(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, const QString &val);
+ void setRegExp(QtProperty *property, const QRegExp &regExp);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QString &val);
+ void regExpChanged(QtProperty *property, const QRegExp &regExp);
+protected:
+ QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtStringPropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtStringPropertyManager)
+ Q_DISABLE_COPY(QtStringPropertyManager)
+};
+
+class QtDatePropertyManagerPrivate;
+
+class QtDatePropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtDatePropertyManager(QObject *parent = 0);
+ ~QtDatePropertyManager();
+
+ QDate value(const QtProperty *property) const;
+ QDate minimum(const QtProperty *property) const;
+ QDate maximum(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, const QDate &val);
+ void setMinimum(QtProperty *property, const QDate &minVal);
+ void setMaximum(QtProperty *property, const QDate &maxVal);
+ void setRange(QtProperty *property, const QDate &minVal, const QDate &maxVal);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QDate &val);
+ void rangeChanged(QtProperty *property, const QDate &minVal, const QDate &maxVal);
+protected:
+ QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtDatePropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtDatePropertyManager)
+ Q_DISABLE_COPY(QtDatePropertyManager)
+};
+
+class QtTimePropertyManagerPrivate;
+
+class QtTimePropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtTimePropertyManager(QObject *parent = 0);
+ ~QtTimePropertyManager();
+
+ QTime value(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, const QTime &val);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QTime &val);
+protected:
+ QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtTimePropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtTimePropertyManager)
+ Q_DISABLE_COPY(QtTimePropertyManager)
+};
+
+class QtDateTimePropertyManagerPrivate;
+
+class QtDateTimePropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtDateTimePropertyManager(QObject *parent = 0);
+ ~QtDateTimePropertyManager();
+
+ QDateTime value(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, const QDateTime &val);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QDateTime &val);
+protected:
+ QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtDateTimePropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtDateTimePropertyManager)
+ Q_DISABLE_COPY(QtDateTimePropertyManager)
+};
+
+class QtKeySequencePropertyManagerPrivate;
+
+class QtKeySequencePropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtKeySequencePropertyManager(QObject *parent = 0);
+ ~QtKeySequencePropertyManager();
+
+ QKeySequence value(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, const QKeySequence &val);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QKeySequence &val);
+protected:
+ QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtKeySequencePropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtKeySequencePropertyManager)
+ Q_DISABLE_COPY(QtKeySequencePropertyManager)
+};
+
+class QtCharPropertyManagerPrivate;
+
+class QtCharPropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtCharPropertyManager(QObject *parent = 0);
+ ~QtCharPropertyManager();
+
+ QChar value(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, const QChar &val);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QChar &val);
+protected:
+ QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtCharPropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtCharPropertyManager)
+ Q_DISABLE_COPY(QtCharPropertyManager)
+};
+
+class QtEnumPropertyManager;
+class QtLocalePropertyManagerPrivate;
+
+class QtLocalePropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtLocalePropertyManager(QObject *parent = 0);
+ ~QtLocalePropertyManager();
+
+ QtEnumPropertyManager *subEnumPropertyManager() const;
+
+ QLocale value(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, const QLocale &val);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QLocale &val);
+protected:
+ QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtLocalePropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtLocalePropertyManager)
+ Q_DISABLE_COPY(QtLocalePropertyManager)
+ Q_PRIVATE_SLOT(d_func(), void slotEnumChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *))
+};
+
+class QtPointPropertyManagerPrivate;
+
+class QtPointPropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtPointPropertyManager(QObject *parent = 0);
+ ~QtPointPropertyManager();
+
+ QtIntPropertyManager *subIntPropertyManager() const;
+
+ QPoint value(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, const QPoint &val);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QPoint &val);
+protected:
+ QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtPointPropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtPointPropertyManager)
+ Q_DISABLE_COPY(QtPointPropertyManager)
+ Q_PRIVATE_SLOT(d_func(), void slotIntChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *))
+};
+
+class QtPointFPropertyManagerPrivate;
+
+class QtPointFPropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtPointFPropertyManager(QObject *parent = 0);
+ ~QtPointFPropertyManager();
+
+ QtDoublePropertyManager *subDoublePropertyManager() const;
+
+ QPointF value(const QtProperty *property) const;
+ int decimals(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, const QPointF &val);
+ void setDecimals(QtProperty *property, int prec);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QPointF &val);
+ void decimalsChanged(QtProperty *property, int prec);
+protected:
+ QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtPointFPropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtPointFPropertyManager)
+ Q_DISABLE_COPY(QtPointFPropertyManager)
+ Q_PRIVATE_SLOT(d_func(), void slotDoubleChanged(QtProperty *, double))
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *))
+};
+
+class QtSizePropertyManagerPrivate;
+
+class QtSizePropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtSizePropertyManager(QObject *parent = 0);
+ ~QtSizePropertyManager();
+
+ QtIntPropertyManager *subIntPropertyManager() const;
+
+ QSize value(const QtProperty *property) const;
+ QSize minimum(const QtProperty *property) const;
+ QSize maximum(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, const QSize &val);
+ void setMinimum(QtProperty *property, const QSize &minVal);
+ void setMaximum(QtProperty *property, const QSize &maxVal);
+ void setRange(QtProperty *property, const QSize &minVal, const QSize &maxVal);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QSize &val);
+ void rangeChanged(QtProperty *property, const QSize &minVal, const QSize &maxVal);
+protected:
+ QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtSizePropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtSizePropertyManager)
+ Q_DISABLE_COPY(QtSizePropertyManager)
+ Q_PRIVATE_SLOT(d_func(), void slotIntChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *))
+};
+
+class QtSizeFPropertyManagerPrivate;
+
+class QtSizeFPropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtSizeFPropertyManager(QObject *parent = 0);
+ ~QtSizeFPropertyManager();
+
+ QtDoublePropertyManager *subDoublePropertyManager() const;
+
+ QSizeF value(const QtProperty *property) const;
+ QSizeF minimum(const QtProperty *property) const;
+ QSizeF maximum(const QtProperty *property) const;
+ int decimals(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, const QSizeF &val);
+ void setMinimum(QtProperty *property, const QSizeF &minVal);
+ void setMaximum(QtProperty *property, const QSizeF &maxVal);
+ void setRange(QtProperty *property, const QSizeF &minVal, const QSizeF &maxVal);
+ void setDecimals(QtProperty *property, int prec);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QSizeF &val);
+ void rangeChanged(QtProperty *property, const QSizeF &minVal, const QSizeF &maxVal);
+ void decimalsChanged(QtProperty *property, int prec);
+protected:
+ QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtSizeFPropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtSizeFPropertyManager)
+ Q_DISABLE_COPY(QtSizeFPropertyManager)
+ Q_PRIVATE_SLOT(d_func(), void slotDoubleChanged(QtProperty *, double))
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *))
+};
+
+class QtRectPropertyManagerPrivate;
+
+class QtRectPropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtRectPropertyManager(QObject *parent = 0);
+ ~QtRectPropertyManager();
+
+ QtIntPropertyManager *subIntPropertyManager() const;
+
+ QRect value(const QtProperty *property) const;
+ QRect constraint(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, const QRect &val);
+ void setConstraint(QtProperty *property, const QRect &constraint);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QRect &val);
+ void constraintChanged(QtProperty *property, const QRect &constraint);
+protected:
+ QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtRectPropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtRectPropertyManager)
+ Q_DISABLE_COPY(QtRectPropertyManager)
+ Q_PRIVATE_SLOT(d_func(), void slotIntChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *))
+};
+
+class QtRectFPropertyManagerPrivate;
+
+class QtRectFPropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtRectFPropertyManager(QObject *parent = 0);
+ ~QtRectFPropertyManager();
+
+ QtDoublePropertyManager *subDoublePropertyManager() const;
+
+ QRectF value(const QtProperty *property) const;
+ QRectF constraint(const QtProperty *property) const;
+ int decimals(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, const QRectF &val);
+ void setConstraint(QtProperty *property, const QRectF &constraint);
+ void setDecimals(QtProperty *property, int prec);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QRectF &val);
+ void constraintChanged(QtProperty *property, const QRectF &constraint);
+ void decimalsChanged(QtProperty *property, int prec);
+protected:
+ QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtRectFPropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtRectFPropertyManager)
+ Q_DISABLE_COPY(QtRectFPropertyManager)
+ Q_PRIVATE_SLOT(d_func(), void slotDoubleChanged(QtProperty *, double))
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *))
+};
+
+class QtEnumPropertyManagerPrivate;
+
+class QtEnumPropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtEnumPropertyManager(QObject *parent = 0);
+ ~QtEnumPropertyManager();
+
+ int value(const QtProperty *property) const;
+ QStringList enumNames(const QtProperty *property) const;
+ QMap<int, QIcon> enumIcons(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, int val);
+ void setEnumNames(QtProperty *property, const QStringList &names);
+ void setEnumIcons(QtProperty *property, const QMap<int, QIcon> &icons);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, int val);
+ void enumNamesChanged(QtProperty *property, const QStringList &names);
+ void enumIconsChanged(QtProperty *property, const QMap<int, QIcon> &icons);
+protected:
+ QString valueText(const QtProperty *property) const;
+ QIcon valueIcon(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtEnumPropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtEnumPropertyManager)
+ Q_DISABLE_COPY(QtEnumPropertyManager)
+};
+
+class QtFlagPropertyManagerPrivate;
+
+class QtFlagPropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtFlagPropertyManager(QObject *parent = 0);
+ ~QtFlagPropertyManager();
+
+ QtBoolPropertyManager *subBoolPropertyManager() const;
+
+ int value(const QtProperty *property) const;
+ QStringList flagNames(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, int val);
+ void setFlagNames(QtProperty *property, const QStringList &names);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, int val);
+ void flagNamesChanged(QtProperty *property, const QStringList &names);
+protected:
+ QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtFlagPropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtFlagPropertyManager)
+ Q_DISABLE_COPY(QtFlagPropertyManager)
+ Q_PRIVATE_SLOT(d_func(), void slotBoolChanged(QtProperty *, bool))
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *))
+};
+
+class QtSizePolicyPropertyManagerPrivate;
+
+class QtSizePolicyPropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtSizePolicyPropertyManager(QObject *parent = 0);
+ ~QtSizePolicyPropertyManager();
+
+ QtIntPropertyManager *subIntPropertyManager() const;
+ QtEnumPropertyManager *subEnumPropertyManager() const;
+
+ QSizePolicy value(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, const QSizePolicy &val);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QSizePolicy &val);
+protected:
+ QString valueText(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtSizePolicyPropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtSizePolicyPropertyManager)
+ Q_DISABLE_COPY(QtSizePolicyPropertyManager)
+ Q_PRIVATE_SLOT(d_func(), void slotIntChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotEnumChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *))
+};
+
+class QtFontPropertyManagerPrivate;
+
+class QtFontPropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtFontPropertyManager(QObject *parent = 0);
+ ~QtFontPropertyManager();
+
+ QtIntPropertyManager *subIntPropertyManager() const;
+ QtEnumPropertyManager *subEnumPropertyManager() const;
+ QtBoolPropertyManager *subBoolPropertyManager() const;
+
+ QFont value(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, const QFont &val);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QFont &val);
+protected:
+ QString valueText(const QtProperty *property) const;
+ QIcon valueIcon(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtFontPropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtFontPropertyManager)
+ Q_DISABLE_COPY(QtFontPropertyManager)
+ Q_PRIVATE_SLOT(d_func(), void slotIntChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotEnumChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotBoolChanged(QtProperty *, bool))
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *))
+ Q_PRIVATE_SLOT(d_func(), void slotFontDatabaseChanged())
+ Q_PRIVATE_SLOT(d_func(), void slotFontDatabaseDelayedChange())
+};
+
+class QtColorPropertyManagerPrivate;
+
+class QtColorPropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtColorPropertyManager(QObject *parent = 0);
+ ~QtColorPropertyManager();
+
+ QtIntPropertyManager *subIntPropertyManager() const;
+
+ QColor value(const QtProperty *property) const;
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, const QColor &val);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QColor &val);
+protected:
+ QString valueText(const QtProperty *property) const;
+ QIcon valueIcon(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtColorPropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtColorPropertyManager)
+ Q_DISABLE_COPY(QtColorPropertyManager)
+ Q_PRIVATE_SLOT(d_func(), void slotIntChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *))
+};
+
+class QtCursorPropertyManagerPrivate;
+
+class QtCursorPropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtCursorPropertyManager(QObject *parent = 0);
+ ~QtCursorPropertyManager();
+
+#ifndef QT_NO_CURSOR
+ QCursor value(const QtProperty *property) const;
+#endif
+
+public Q_SLOTS:
+ void setValue(QtProperty *property, const QCursor &val);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QCursor &val);
+protected:
+ QString valueText(const QtProperty *property) const;
+ QIcon valueIcon(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+private:
+ QScopedPointer<QtCursorPropertyManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtCursorPropertyManager)
+ Q_DISABLE_COPY(QtCursorPropertyManager)
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtpropertybrowser/qttreepropertybrowser.cpp b/src/shared/qtpropertybrowser/qttreepropertybrowser.cpp
new file mode 100644
index 000000000..58a29e0e2
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qttreepropertybrowser.cpp
@@ -0,0 +1,1042 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qttreepropertybrowser.h"
+#include <QtCore/QSet>
+#include <QtGui/QIcon>
+#include <QtGui/QTreeWidget>
+#include <QtGui/QItemDelegate>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QHeaderView>
+#include <QtGui/QPainter>
+#include <QtGui/QApplication>
+#include <QtGui/QFocusEvent>
+#include <QtGui/QStyle>
+#include <QtGui/QPalette>
+
+QT_BEGIN_NAMESPACE
+
+class QtPropertyEditorView;
+
+class QtTreePropertyBrowserPrivate
+{
+ QtTreePropertyBrowser *q_ptr;
+ Q_DECLARE_PUBLIC(QtTreePropertyBrowser)
+
+public:
+ QtTreePropertyBrowserPrivate();
+ void init(QWidget *parent);
+
+ void propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex);
+ void propertyRemoved(QtBrowserItem *index);
+ void propertyChanged(QtBrowserItem *index);
+ QWidget *createEditor(QtProperty *property, QWidget *parent) const
+ { return q_ptr->createEditor(property, parent); }
+ QtProperty *indexToProperty(const QModelIndex &index) const;
+ QTreeWidgetItem *indexToItem(const QModelIndex &index) const;
+ QtBrowserItem *indexToBrowserItem(const QModelIndex &index) const;
+ bool lastColumn(int column) const;
+ void disableItem(QTreeWidgetItem *item) const;
+ void enableItem(QTreeWidgetItem *item) const;
+ bool hasValue(QTreeWidgetItem *item) const;
+
+ void slotCollapsed(const QModelIndex &index);
+ void slotExpanded(const QModelIndex &index);
+
+ QColor calculatedBackgroundColor(QtBrowserItem *item) const;
+
+ QtPropertyEditorView *treeWidget() const { return m_treeWidget; }
+ bool markPropertiesWithoutValue() const { return m_markPropertiesWithoutValue; }
+
+ QtBrowserItem *currentItem() const;
+ void setCurrentItem(QtBrowserItem *browserItem, bool block);
+ void editItem(QtBrowserItem *browserItem);
+
+ void slotCurrentBrowserItemChanged(QtBrowserItem *item);
+ void slotCurrentTreeItemChanged(QTreeWidgetItem *newItem, QTreeWidgetItem *);
+
+ QTreeWidgetItem *editedItem() const;
+
+private:
+ void updateItem(QTreeWidgetItem *item);
+
+ QMap<QtBrowserItem *, QTreeWidgetItem *> m_indexToItem;
+ QMap<QTreeWidgetItem *, QtBrowserItem *> m_itemToIndex;
+
+ QMap<QtBrowserItem *, QColor> m_indexToBackgroundColor;
+
+ QtPropertyEditorView *m_treeWidget;
+
+ bool m_headerVisible;
+ QtTreePropertyBrowser::ResizeMode m_resizeMode;
+ class QtPropertyEditorDelegate *m_delegate;
+ bool m_markPropertiesWithoutValue;
+ bool m_browserChangedBlocked;
+ QIcon m_expandIcon;
+};
+
+// ------------ QtPropertyEditorView
+class QtPropertyEditorView : public QTreeWidget
+{
+ Q_OBJECT
+public:
+ QtPropertyEditorView(QWidget *parent = 0);
+
+ void setEditorPrivate(QtTreePropertyBrowserPrivate *editorPrivate)
+ { m_editorPrivate = editorPrivate; }
+
+ QTreeWidgetItem *indexToItem(const QModelIndex &index) const
+ { return itemFromIndex(index); }
+
+protected:
+ void keyPressEvent(QKeyEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void drawRow(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
+
+private:
+ QtTreePropertyBrowserPrivate *m_editorPrivate;
+};
+
+QtPropertyEditorView::QtPropertyEditorView(QWidget *parent) :
+ QTreeWidget(parent),
+ m_editorPrivate(0)
+{
+ connect(header(), SIGNAL(sectionDoubleClicked(int)), this, SLOT(resizeColumnToContents(int)));
+}
+
+void QtPropertyEditorView::drawRow(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+ QStyleOptionViewItemV3 opt = option;
+ bool hasValue = true;
+ if (m_editorPrivate) {
+ QtProperty *property = m_editorPrivate->indexToProperty(index);
+ if (property)
+ hasValue = property->hasValue();
+ }
+ if (!hasValue && m_editorPrivate->markPropertiesWithoutValue()) {
+ const QColor c = option.palette.color(QPalette::Dark);
+ painter->fillRect(option.rect, c);
+ opt.palette.setColor(QPalette::AlternateBase, c);
+ } else {
+ const QColor c = m_editorPrivate->calculatedBackgroundColor(m_editorPrivate->indexToBrowserItem(index));
+ if (c.isValid()) {
+ painter->fillRect(option.rect, c);
+ opt.palette.setColor(QPalette::AlternateBase, c.lighter(112));
+ }
+ }
+ QTreeWidget::drawRow(painter, opt, index);
+ QColor color = static_cast<QRgb>(QApplication::style()->styleHint(QStyle::SH_Table_GridLineColor, &opt));
+ painter->save();
+ painter->setPen(QPen(color));
+ painter->drawLine(opt.rect.x(), opt.rect.bottom(), opt.rect.right(), opt.rect.bottom());
+ painter->restore();
+}
+
+void QtPropertyEditorView::keyPressEvent(QKeyEvent *event)
+{
+ switch (event->key()) {
+ case Qt::Key_Return:
+ case Qt::Key_Enter:
+ case Qt::Key_Space: // Trigger Edit
+ if (!m_editorPrivate->editedItem())
+ if (const QTreeWidgetItem *item = currentItem())
+ if (item->columnCount() >= 2 && ((item->flags() & (Qt::ItemIsEditable | Qt::ItemIsEnabled)) == (Qt::ItemIsEditable | Qt::ItemIsEnabled))) {
+ event->accept();
+ // If the current position is at column 0, move to 1.
+ QModelIndex index = currentIndex();
+ if (index.column() == 0) {
+ index = index.sibling(index.row(), 1);
+ setCurrentIndex(index);
+ }
+ edit(index);
+ return;
+ }
+ break;
+ default:
+ break;
+ }
+ QTreeWidget::keyPressEvent(event);
+}
+
+void QtPropertyEditorView::mousePressEvent(QMouseEvent *event)
+{
+ QTreeWidget::mousePressEvent(event);
+ QTreeWidgetItem *item = itemAt(event->pos());
+
+ if (item) {
+ if ((item != m_editorPrivate->editedItem()) && (event->button() == Qt::LeftButton)
+ && (header()->logicalIndexAt(event->pos().x()) == 1)
+ && ((item->flags() & (Qt::ItemIsEditable | Qt::ItemIsEnabled)) == (Qt::ItemIsEditable | Qt::ItemIsEnabled))) {
+ editItem(item, 1);
+ } else if (!m_editorPrivate->hasValue(item) && m_editorPrivate->markPropertiesWithoutValue() && !rootIsDecorated()) {
+ if (event->pos().x() + header()->offset() < 20)
+ item->setExpanded(!item->isExpanded());
+ }
+ }
+}
+
+// ------------ QtPropertyEditorDelegate
+class QtPropertyEditorDelegate : public QItemDelegate
+{
+ Q_OBJECT
+public:
+ QtPropertyEditorDelegate(QObject *parent = 0)
+ : QItemDelegate(parent), m_editorPrivate(0), m_editedItem(0), m_editedWidget(0)
+ {}
+
+ void setEditorPrivate(QtTreePropertyBrowserPrivate *editorPrivate)
+ { m_editorPrivate = editorPrivate; }
+
+ QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+
+ void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+
+ void paint(QPainter *painter, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+
+ QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
+
+ void setModelData(QWidget *, QAbstractItemModel *,
+ const QModelIndex &) const {}
+
+ void setEditorData(QWidget *, const QModelIndex &) const {}
+
+ bool eventFilter(QObject *object, QEvent *event);
+ void closeEditor(QtProperty *property);
+
+ QTreeWidgetItem *editedItem() const { return m_editedItem; }
+
+private slots:
+ void slotEditorDestroyed(QObject *object);
+
+private:
+ int indentation(const QModelIndex &index) const;
+
+ typedef QMap<QWidget *, QtProperty *> EditorToPropertyMap;
+ mutable EditorToPropertyMap m_editorToProperty;
+
+ typedef QMap<QtProperty *, QWidget *> PropertyToEditorMap;
+ mutable PropertyToEditorMap m_propertyToEditor;
+ QtTreePropertyBrowserPrivate *m_editorPrivate;
+ mutable QTreeWidgetItem *m_editedItem;
+ mutable QWidget *m_editedWidget;
+};
+
+int QtPropertyEditorDelegate::indentation(const QModelIndex &index) const
+{
+ if (!m_editorPrivate)
+ return 0;
+
+ QTreeWidgetItem *item = m_editorPrivate->indexToItem(index);
+ int indent = 0;
+ while (item->parent()) {
+ item = item->parent();
+ ++indent;
+ }
+ if (m_editorPrivate->treeWidget()->rootIsDecorated())
+ ++indent;
+ return indent * m_editorPrivate->treeWidget()->indentation();
+}
+
+void QtPropertyEditorDelegate::slotEditorDestroyed(QObject *object)
+{
+ if (QWidget *w = qobject_cast<QWidget *>(object)) {
+ const EditorToPropertyMap::iterator it = m_editorToProperty.find(w);
+ if (it != m_editorToProperty.end()) {
+ m_propertyToEditor.remove(it.value());
+ m_editorToProperty.erase(it);
+ }
+ if (m_editedWidget == w) {
+ m_editedWidget = 0;
+ m_editedItem = 0;
+ }
+ }
+}
+
+void QtPropertyEditorDelegate::closeEditor(QtProperty *property)
+{
+ if (QWidget *w = m_propertyToEditor.value(property, 0))
+ w->deleteLater();
+}
+
+QWidget *QtPropertyEditorDelegate::createEditor(QWidget *parent,
+ const QStyleOptionViewItem &, const QModelIndex &index) const
+{
+ if (index.column() == 1 && m_editorPrivate) {
+ QtProperty *property = m_editorPrivate->indexToProperty(index);
+ QTreeWidgetItem *item = m_editorPrivate->indexToItem(index);
+ if (property && item && (item->flags() & Qt::ItemIsEnabled)) {
+ QWidget *editor = m_editorPrivate->createEditor(property, parent);
+ if (editor) {
+ editor->setAutoFillBackground(true);
+ editor->installEventFilter(const_cast<QtPropertyEditorDelegate *>(this));
+ connect(editor, SIGNAL(destroyed(QObject*)), this, SLOT(slotEditorDestroyed(QObject*)));
+ m_propertyToEditor[property] = editor;
+ m_editorToProperty[editor] = property;
+ m_editedItem = item;
+ m_editedWidget = editor;
+ }
+ return editor;
+ }
+ }
+ return 0;
+}
+
+void QtPropertyEditorDelegate::updateEditorGeometry(QWidget *editor,
+ const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+ Q_UNUSED(index)
+ editor->setGeometry(option.rect.adjusted(0, 0, 0, -1));
+}
+
+void QtPropertyEditorDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+{
+ bool hasValue = true;
+ if (m_editorPrivate) {
+ QtProperty *property = m_editorPrivate->indexToProperty(index);
+ if (property)
+ hasValue = property->hasValue();
+ }
+ QStyleOptionViewItemV3 opt = option;
+ if ((m_editorPrivate && index.column() == 0) || !hasValue) {
+ QtProperty *property = m_editorPrivate->indexToProperty(index);
+ if (property && property->isModified()) {
+ opt.font.setBold(true);
+ opt.fontMetrics = QFontMetrics(opt.font);
+ }
+ }
+ QColor c;
+ if (!hasValue && m_editorPrivate->markPropertiesWithoutValue()) {
+ c = opt.palette.color(QPalette::Dark);
+ opt.palette.setColor(QPalette::Text, opt.palette.color(QPalette::BrightText));
+ } else {
+ c = m_editorPrivate->calculatedBackgroundColor(m_editorPrivate->indexToBrowserItem(index));
+ if (c.isValid() && (opt.features & QStyleOptionViewItemV2::Alternate))
+ c = c.lighter(112);
+ }
+ if (c.isValid())
+ painter->fillRect(option.rect, c);
+ opt.state &= ~QStyle::State_HasFocus;
+ QItemDelegate::paint(painter, opt, index);
+
+ opt.palette.setCurrentColorGroup(QPalette::Active);
+ QColor color = static_cast<QRgb>(QApplication::style()->styleHint(QStyle::SH_Table_GridLineColor, &opt));
+ painter->save();
+ painter->setPen(QPen(color));
+ if (!m_editorPrivate || (!m_editorPrivate->lastColumn(index.column()) && hasValue)) {
+ int right = (option.direction == Qt::LeftToRight) ? option.rect.right() : option.rect.left();
+ painter->drawLine(right, option.rect.y(), right, option.rect.bottom());
+ }
+ painter->restore();
+}
+
+QSize QtPropertyEditorDelegate::sizeHint(const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+{
+ return QItemDelegate::sizeHint(option, index) + QSize(3, 4);
+}
+
+bool QtPropertyEditorDelegate::eventFilter(QObject *object, QEvent *event)
+{
+ if (event->type() == QEvent::FocusOut) {
+ QFocusEvent *fe = static_cast<QFocusEvent *>(event);
+ if (fe->reason() == Qt::ActiveWindowFocusReason)
+ return false;
+ }
+ return QItemDelegate::eventFilter(object, event);
+}
+
+// -------- QtTreePropertyBrowserPrivate implementation
+QtTreePropertyBrowserPrivate::QtTreePropertyBrowserPrivate() :
+ m_treeWidget(0),
+ m_headerVisible(true),
+ m_resizeMode(QtTreePropertyBrowser::Stretch),
+ m_delegate(0),
+ m_markPropertiesWithoutValue(false),
+ m_browserChangedBlocked(false)
+{
+}
+
+// Draw an icon indicating opened/closing branches
+static QIcon drawIndicatorIcon(const QPalette &palette, QStyle *style)
+{
+ QPixmap pix(14, 14);
+ pix.fill(Qt::transparent);
+ QStyleOption branchOption;
+ QRect r(QPoint(0, 0), pix.size());
+ branchOption.rect = QRect(2, 2, 9, 9); // ### hardcoded in qcommonstyle.cpp
+ branchOption.palette = palette;
+ branchOption.state = QStyle::State_Children;
+
+ QPainter p;
+ // Draw closed state
+ p.begin(&pix);
+ style->drawPrimitive(QStyle::PE_IndicatorBranch, &branchOption, &p);
+ p.end();
+ QIcon rc = pix;
+ rc.addPixmap(pix, QIcon::Selected, QIcon::Off);
+ // Draw opened state
+ branchOption.state |= QStyle::State_Open;
+ pix.fill(Qt::transparent);
+ p.begin(&pix);
+ style->drawPrimitive(QStyle::PE_IndicatorBranch, &branchOption, &p);
+ p.end();
+
+ rc.addPixmap(pix, QIcon::Normal, QIcon::On);
+ rc.addPixmap(pix, QIcon::Selected, QIcon::On);
+ return rc;
+}
+
+void QtTreePropertyBrowserPrivate::init(QWidget *parent)
+{
+ QHBoxLayout *layout = new QHBoxLayout(parent);
+ layout->setMargin(0);
+ m_treeWidget = new QtPropertyEditorView(parent);
+ m_treeWidget->setEditorPrivate(this);
+ m_treeWidget->setIconSize(QSize(18, 18));
+ layout->addWidget(m_treeWidget);
+
+ m_treeWidget->setColumnCount(2);
+ QStringList labels;
+ labels.append(QApplication::translate("QtTreePropertyBrowser", "Property", 0, QApplication::UnicodeUTF8));
+ labels.append(QApplication::translate("QtTreePropertyBrowser", "Value", 0, QApplication::UnicodeUTF8));
+ m_treeWidget->setHeaderLabels(labels);
+ m_treeWidget->setAlternatingRowColors(true);
+ m_treeWidget->setEditTriggers(QAbstractItemView::EditKeyPressed);
+ m_delegate = new QtPropertyEditorDelegate(parent);
+ m_delegate->setEditorPrivate(this);
+ m_treeWidget->setItemDelegate(m_delegate);
+ m_treeWidget->header()->setMovable(false);
+ m_treeWidget->header()->setResizeMode(QHeaderView::Stretch);
+
+ m_expandIcon = drawIndicatorIcon(q_ptr->palette(), q_ptr->style());
+
+ QObject::connect(m_treeWidget, SIGNAL(collapsed(QModelIndex)), q_ptr, SLOT(slotCollapsed(QModelIndex)));
+ QObject::connect(m_treeWidget, SIGNAL(expanded(QModelIndex)), q_ptr, SLOT(slotExpanded(QModelIndex)));
+ QObject::connect(m_treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), q_ptr, SLOT(slotCurrentTreeItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)));
+}
+
+QtBrowserItem *QtTreePropertyBrowserPrivate::currentItem() const
+{
+ if (QTreeWidgetItem *treeItem = m_treeWidget->currentItem())
+ return m_itemToIndex.value(treeItem);
+ return 0;
+}
+
+void QtTreePropertyBrowserPrivate::setCurrentItem(QtBrowserItem *browserItem, bool block)
+{
+ const bool blocked = block ? m_treeWidget->blockSignals(true) : false;
+ if (browserItem == 0)
+ m_treeWidget->setCurrentItem(0);
+ else
+ m_treeWidget->setCurrentItem(m_indexToItem.value(browserItem));
+ if (block)
+ m_treeWidget->blockSignals(blocked);
+}
+
+QtProperty *QtTreePropertyBrowserPrivate::indexToProperty(const QModelIndex &index) const
+{
+ QTreeWidgetItem *item = m_treeWidget->indexToItem(index);
+ QtBrowserItem *idx = m_itemToIndex.value(item);
+ if (idx)
+ return idx->property();
+ return 0;
+}
+
+QtBrowserItem *QtTreePropertyBrowserPrivate::indexToBrowserItem(const QModelIndex &index) const
+{
+ QTreeWidgetItem *item = m_treeWidget->indexToItem(index);
+ return m_itemToIndex.value(item);
+}
+
+QTreeWidgetItem *QtTreePropertyBrowserPrivate::indexToItem(const QModelIndex &index) const
+{
+ return m_treeWidget->indexToItem(index);
+}
+
+bool QtTreePropertyBrowserPrivate::lastColumn(int column) const
+{
+ return m_treeWidget->header()->visualIndex(column) == m_treeWidget->columnCount() - 1;
+}
+
+void QtTreePropertyBrowserPrivate::disableItem(QTreeWidgetItem *item) const
+{
+ Qt::ItemFlags flags = item->flags();
+ if (flags & Qt::ItemIsEnabled) {
+ flags &= ~Qt::ItemIsEnabled;
+ item->setFlags(flags);
+ m_delegate->closeEditor(m_itemToIndex[item]->property());
+ const int childCount = item->childCount();
+ for (int i = 0; i < childCount; i++) {
+ QTreeWidgetItem *child = item->child(i);
+ disableItem(child);
+ }
+ }
+}
+
+void QtTreePropertyBrowserPrivate::enableItem(QTreeWidgetItem *item) const
+{
+ Qt::ItemFlags flags = item->flags();
+ flags |= Qt::ItemIsEnabled;
+ item->setFlags(flags);
+ const int childCount = item->childCount();
+ for (int i = 0; i < childCount; i++) {
+ QTreeWidgetItem *child = item->child(i);
+ QtProperty *property = m_itemToIndex[child]->property();
+ if (property->isEnabled()) {
+ enableItem(child);
+ }
+ }
+}
+
+bool QtTreePropertyBrowserPrivate::hasValue(QTreeWidgetItem *item) const
+{
+ QtBrowserItem *browserItem = m_itemToIndex.value(item);
+ if (browserItem)
+ return browserItem->property()->hasValue();
+ return false;
+}
+
+void QtTreePropertyBrowserPrivate::propertyInserted(QtBrowserItem *index, QtBrowserItem *afterIndex)
+{
+ QTreeWidgetItem *afterItem = m_indexToItem.value(afterIndex);
+ QTreeWidgetItem *parentItem = m_indexToItem.value(index->parent());
+
+ QTreeWidgetItem *newItem = 0;
+ if (parentItem) {
+ newItem = new QTreeWidgetItem(parentItem, afterItem);
+ } else {
+ newItem = new QTreeWidgetItem(m_treeWidget, afterItem);
+ }
+ m_itemToIndex[newItem] = index;
+ m_indexToItem[index] = newItem;
+
+ newItem->setFlags(newItem->flags() | Qt::ItemIsEditable);
+ m_treeWidget->setItemExpanded(newItem, true);
+
+ updateItem(newItem);
+}
+
+void QtTreePropertyBrowserPrivate::propertyRemoved(QtBrowserItem *index)
+{
+ QTreeWidgetItem *item = m_indexToItem.value(index);
+
+ if (m_treeWidget->currentItem() == item) {
+ m_treeWidget->setCurrentItem(0);
+ }
+
+ delete item;
+
+ m_indexToItem.remove(index);
+ m_itemToIndex.remove(item);
+ m_indexToBackgroundColor.remove(index);
+}
+
+void QtTreePropertyBrowserPrivate::propertyChanged(QtBrowserItem *index)
+{
+ QTreeWidgetItem *item = m_indexToItem.value(index);
+
+ updateItem(item);
+}
+
+void QtTreePropertyBrowserPrivate::updateItem(QTreeWidgetItem *item)
+{
+ QtProperty *property = m_itemToIndex[item]->property();
+ QIcon expandIcon;
+ if (property->hasValue()) {
+ QString toolTip = property->toolTip();
+ if (toolTip.isEmpty())
+ toolTip = property->valueText();
+ item->setToolTip(1, toolTip);
+ item->setIcon(1, property->valueIcon());
+ item->setText(1, property->valueText());
+ } else if (markPropertiesWithoutValue() && !m_treeWidget->rootIsDecorated()) {
+ expandIcon = m_expandIcon;
+ }
+ item->setIcon(0, expandIcon);
+ item->setFirstColumnSpanned(!property->hasValue());
+ item->setToolTip(0, property->propertyName());
+ item->setStatusTip(0, property->statusTip());
+ item->setWhatsThis(0, property->whatsThis());
+ item->setText(0, property->propertyName());
+ bool wasEnabled = item->flags() & Qt::ItemIsEnabled;
+ bool isEnabled = wasEnabled;
+ if (property->isEnabled()) {
+ QTreeWidgetItem *parent = item->parent();
+ if (!parent || (parent->flags() & Qt::ItemIsEnabled))
+ isEnabled = true;
+ else
+ isEnabled = false;
+ } else {
+ isEnabled = false;
+ }
+ if (wasEnabled != isEnabled) {
+ if (isEnabled)
+ enableItem(item);
+ else
+ disableItem(item);
+ }
+ m_treeWidget->viewport()->update();
+}
+
+QColor QtTreePropertyBrowserPrivate::calculatedBackgroundColor(QtBrowserItem *item) const
+{
+ QtBrowserItem *i = item;
+ const QMap<QtBrowserItem *, QColor>::const_iterator itEnd = m_indexToBackgroundColor.constEnd();
+ while (i) {
+ QMap<QtBrowserItem *, QColor>::const_iterator it = m_indexToBackgroundColor.constFind(i);
+ if (it != itEnd)
+ return it.value();
+ i = i->parent();
+ }
+ return QColor();
+}
+
+void QtTreePropertyBrowserPrivate::slotCollapsed(const QModelIndex &index)
+{
+ QTreeWidgetItem *item = indexToItem(index);
+ QtBrowserItem *idx = m_itemToIndex.value(item);
+ if (item)
+ emit q_ptr->collapsed(idx);
+}
+
+void QtTreePropertyBrowserPrivate::slotExpanded(const QModelIndex &index)
+{
+ QTreeWidgetItem *item = indexToItem(index);
+ QtBrowserItem *idx = m_itemToIndex.value(item);
+ if (item)
+ emit q_ptr->expanded(idx);
+}
+
+void QtTreePropertyBrowserPrivate::slotCurrentBrowserItemChanged(QtBrowserItem *item)
+{
+ if (!m_browserChangedBlocked && item != currentItem())
+ setCurrentItem(item, true);
+}
+
+void QtTreePropertyBrowserPrivate::slotCurrentTreeItemChanged(QTreeWidgetItem *newItem, QTreeWidgetItem *)
+{
+ QtBrowserItem *browserItem = newItem ? m_itemToIndex.value(newItem) : 0;
+ m_browserChangedBlocked = true;
+ q_ptr->setCurrentItem(browserItem);
+ m_browserChangedBlocked = false;
+}
+
+QTreeWidgetItem *QtTreePropertyBrowserPrivate::editedItem() const
+{
+ return m_delegate->editedItem();
+}
+
+void QtTreePropertyBrowserPrivate::editItem(QtBrowserItem *browserItem)
+{
+ if (QTreeWidgetItem *treeItem = m_indexToItem.value(browserItem, 0)) {
+ m_treeWidget->setCurrentItem (treeItem, 1);
+ m_treeWidget->editItem(treeItem, 1);
+ }
+}
+
+/*!
+ \class QtTreePropertyBrowser
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtTreePropertyBrowser class provides QTreeWidget based
+ property browser.
+
+ A property browser is a widget that enables the user to edit a
+ given set of properties. Each property is represented by a label
+ specifying the property's name, and an editing widget (e.g. a line
+ edit or a combobox) holding its value. A property can have zero or
+ more subproperties.
+
+ QtTreePropertyBrowser provides a tree based view for all nested
+ properties, i.e. properties that have subproperties can be in an
+ expanded (subproperties are visible) or collapsed (subproperties
+ are hidden) state. For example:
+
+ \image qttreepropertybrowser.png
+
+ Use the QtAbstractPropertyBrowser API to add, insert and remove
+ properties from an instance of the QtTreePropertyBrowser class.
+ The properties themselves are created and managed by
+ implementations of the QtAbstractPropertyManager class.
+
+ \sa QtGroupBoxPropertyBrowser, QtAbstractPropertyBrowser
+*/
+
+/*!
+ \fn void QtTreePropertyBrowser::collapsed(QtBrowserItem *item)
+
+ This signal is emitted when the \a item is collapsed.
+
+ \sa expanded(), setExpanded()
+*/
+
+/*!
+ \fn void QtTreePropertyBrowser::expanded(QtBrowserItem *item)
+
+ This signal is emitted when the \a item is expanded.
+
+ \sa collapsed(), setExpanded()
+*/
+
+/*!
+ Creates a property browser with the given \a parent.
+*/
+QtTreePropertyBrowser::QtTreePropertyBrowser(QWidget *parent)
+ : QtAbstractPropertyBrowser(parent), d_ptr(new QtTreePropertyBrowserPrivate)
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->init(this);
+ connect(this, SIGNAL(currentItemChanged(QtBrowserItem*)), this, SLOT(slotCurrentBrowserItemChanged(QtBrowserItem*)));
+}
+
+/*!
+ Destroys this property browser.
+
+ Note that the properties that were inserted into this browser are
+ \e not destroyed since they may still be used in other
+ browsers. The properties are owned by the manager that created
+ them.
+
+ \sa QtProperty, QtAbstractPropertyManager
+*/
+QtTreePropertyBrowser::~QtTreePropertyBrowser()
+{
+}
+
+/*!
+ \property QtTreePropertyBrowser::indentation
+ \brief indentation of the items in the tree view.
+*/
+int QtTreePropertyBrowser::indentation() const
+{
+ return d_ptr->m_treeWidget->indentation();
+}
+
+void QtTreePropertyBrowser::setIndentation(int i)
+{
+ d_ptr->m_treeWidget->setIndentation(i);
+}
+
+/*!
+ \property QtTreePropertyBrowser::rootIsDecorated
+ \brief whether to show controls for expanding and collapsing root items.
+*/
+bool QtTreePropertyBrowser::rootIsDecorated() const
+{
+ return d_ptr->m_treeWidget->rootIsDecorated();
+}
+
+void QtTreePropertyBrowser::setRootIsDecorated(bool show)
+{
+ d_ptr->m_treeWidget->setRootIsDecorated(show);
+ QMapIterator<QTreeWidgetItem *, QtBrowserItem *> it(d_ptr->m_itemToIndex);
+ while (it.hasNext()) {
+ QtProperty *property = it.next().value()->property();
+ if (!property->hasValue())
+ d_ptr->updateItem(it.key());
+ }
+}
+
+/*!
+ \property QtTreePropertyBrowser::alternatingRowColors
+ \brief whether to draw the background using alternating colors.
+ By default this property is set to true.
+*/
+bool QtTreePropertyBrowser::alternatingRowColors() const
+{
+ return d_ptr->m_treeWidget->alternatingRowColors();
+}
+
+void QtTreePropertyBrowser::setAlternatingRowColors(bool enable)
+{
+ d_ptr->m_treeWidget->setAlternatingRowColors(enable);
+ QMapIterator<QTreeWidgetItem *, QtBrowserItem *> it(d_ptr->m_itemToIndex);
+}
+
+/*!
+ \property QtTreePropertyBrowser::headerVisible
+ \brief whether to show the header.
+*/
+bool QtTreePropertyBrowser::isHeaderVisible() const
+{
+ return d_ptr->m_headerVisible;
+}
+
+void QtTreePropertyBrowser::setHeaderVisible(bool visible)
+{
+ if (d_ptr->m_headerVisible == visible)
+ return;
+
+ d_ptr->m_headerVisible = visible;
+ d_ptr->m_treeWidget->header()->setVisible(visible);
+}
+
+/*!
+ \enum QtTreePropertyBrowser::ResizeMode
+
+ The resize mode specifies the behavior of the header sections.
+
+ \value Interactive The user can resize the sections.
+ The sections can also be resized programmatically using setSplitterPosition().
+
+ \value Fixed The user cannot resize the section.
+ The section can only be resized programmatically using setSplitterPosition().
+
+ \value Stretch QHeaderView will automatically resize the section to fill the available space.
+ The size cannot be changed by the user or programmatically.
+
+ \value ResizeToContents QHeaderView will automatically resize the section to its optimal
+ size based on the contents of the entire column.
+ The size cannot be changed by the user or programmatically.
+
+ \sa setResizeMode()
+*/
+
+/*!
+ \property QtTreePropertyBrowser::resizeMode
+ \brief the resize mode of setions in the header.
+*/
+
+QtTreePropertyBrowser::ResizeMode QtTreePropertyBrowser::resizeMode() const
+{
+ return d_ptr->m_resizeMode;
+}
+
+void QtTreePropertyBrowser::setResizeMode(QtTreePropertyBrowser::ResizeMode mode)
+{
+ if (d_ptr->m_resizeMode == mode)
+ return;
+
+ d_ptr->m_resizeMode = mode;
+ QHeaderView::ResizeMode m = QHeaderView::Stretch;
+ switch (mode) {
+ case QtTreePropertyBrowser::Interactive: m = QHeaderView::Interactive; break;
+ case QtTreePropertyBrowser::Fixed: m = QHeaderView::Fixed; break;
+ case QtTreePropertyBrowser::ResizeToContents: m = QHeaderView::ResizeToContents; break;
+ case QtTreePropertyBrowser::Stretch:
+ default: m = QHeaderView::Stretch; break;
+ }
+ d_ptr->m_treeWidget->header()->setResizeMode(m);
+}
+
+/*!
+ \property QtTreePropertyBrowser::splitterPosition
+ \brief the position of the splitter between the colunms.
+*/
+
+int QtTreePropertyBrowser::splitterPosition() const
+{
+ return d_ptr->m_treeWidget->header()->sectionSize(0);
+}
+
+void QtTreePropertyBrowser::setSplitterPosition(int position)
+{
+ d_ptr->m_treeWidget->header()->resizeSection(0, position);
+}
+
+/*!
+ Sets the \a item to either collapse or expanded, depending on the value of \a expanded.
+
+ \sa isExpanded(), expanded(), collapsed()
+*/
+
+void QtTreePropertyBrowser::setExpanded(QtBrowserItem *item, bool expanded)
+{
+ QTreeWidgetItem *treeItem = d_ptr->m_indexToItem.value(item);
+ if (treeItem)
+ treeItem->setExpanded(expanded);
+}
+
+/*!
+ Returns true if the \a item is expanded; otherwise returns false.
+
+ \sa setExpanded()
+*/
+
+bool QtTreePropertyBrowser::isExpanded(QtBrowserItem *item) const
+{
+ QTreeWidgetItem *treeItem = d_ptr->m_indexToItem.value(item);
+ if (treeItem)
+ return treeItem->isExpanded();
+ return false;
+}
+
+/*!
+ Returns true if the \a item is visible; otherwise returns false.
+
+ \sa setItemVisible()
+ \since 4.5
+*/
+
+bool QtTreePropertyBrowser::isItemVisible(QtBrowserItem *item) const
+{
+ if (const QTreeWidgetItem *treeItem = d_ptr->m_indexToItem.value(item))
+ return !treeItem->isHidden();
+ return false;
+}
+
+/*!
+ Sets the \a item to be visible, depending on the value of \a visible.
+
+ \sa isItemVisible()
+ \since 4.5
+*/
+
+void QtTreePropertyBrowser::setItemVisible(QtBrowserItem *item, bool visible)
+{
+ if (QTreeWidgetItem *treeItem = d_ptr->m_indexToItem.value(item))
+ treeItem->setHidden(!visible);
+}
+
+/*!
+ Sets the \a item's background color to \a color. Note that while item's background
+ is rendered every second row is being drawn with alternate color (which is a bit lighter than items \a color)
+
+ \sa backgroundColor(), calculatedBackgroundColor()
+*/
+
+void QtTreePropertyBrowser::setBackgroundColor(QtBrowserItem *item, const QColor &color)
+{
+ if (!d_ptr->m_indexToItem.contains(item))
+ return;
+ if (color.isValid())
+ d_ptr->m_indexToBackgroundColor[item] = color;
+ else
+ d_ptr->m_indexToBackgroundColor.remove(item);
+ d_ptr->m_treeWidget->viewport()->update();
+}
+
+/*!
+ Returns the \a item's color. If there is no color set for item it returns invalid color.
+
+ \sa calculatedBackgroundColor(), setBackgroundColor()
+*/
+
+QColor QtTreePropertyBrowser::backgroundColor(QtBrowserItem *item) const
+{
+ return d_ptr->m_indexToBackgroundColor.value(item);
+}
+
+/*!
+ Returns the \a item's color. If there is no color set for item it returns parent \a item's
+ color (if there is no color set for parent it returns grandparent's color and so on). In case
+ the color is not set for \a item and it's top level item it returns invalid color.
+
+ \sa backgroundColor(), setBackgroundColor()
+*/
+
+QColor QtTreePropertyBrowser::calculatedBackgroundColor(QtBrowserItem *item) const
+{
+ return d_ptr->calculatedBackgroundColor(item);
+}
+
+/*!
+ \property QtTreePropertyBrowser::propertiesWithoutValueMarked
+ \brief whether to enable or disable marking properties without value.
+
+ When marking is enabled the item's background is rendered in dark color and item's
+ foreground is rendered with light color.
+
+ \sa propertiesWithoutValueMarked()
+*/
+void QtTreePropertyBrowser::setPropertiesWithoutValueMarked(bool mark)
+{
+ if (d_ptr->m_markPropertiesWithoutValue == mark)
+ return;
+
+ d_ptr->m_markPropertiesWithoutValue = mark;
+ QMapIterator<QTreeWidgetItem *, QtBrowserItem *> it(d_ptr->m_itemToIndex);
+ while (it.hasNext()) {
+ QtProperty *property = it.next().value()->property();
+ if (!property->hasValue())
+ d_ptr->updateItem(it.key());
+ }
+ d_ptr->m_treeWidget->viewport()->update();
+}
+
+bool QtTreePropertyBrowser::propertiesWithoutValueMarked() const
+{
+ return d_ptr->m_markPropertiesWithoutValue;
+}
+
+/*!
+ \reimp
+*/
+void QtTreePropertyBrowser::itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem)
+{
+ d_ptr->propertyInserted(item, afterItem);
+}
+
+/*!
+ \reimp
+*/
+void QtTreePropertyBrowser::itemRemoved(QtBrowserItem *item)
+{
+ d_ptr->propertyRemoved(item);
+}
+
+/*!
+ \reimp
+*/
+void QtTreePropertyBrowser::itemChanged(QtBrowserItem *item)
+{
+ d_ptr->propertyChanged(item);
+}
+
+/*!
+ Sets the current item to \a item and opens the relevant editor for it.
+*/
+void QtTreePropertyBrowser::editItem(QtBrowserItem *item)
+{
+ d_ptr->editItem(item);
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qttreepropertybrowser.cpp"
+#include "qttreepropertybrowser.moc"
diff --git a/src/shared/qtpropertybrowser/qttreepropertybrowser.h b/src/shared/qtpropertybrowser/qttreepropertybrowser.h
new file mode 100644
index 000000000..c0d8e4cb1
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qttreepropertybrowser.h
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTTREEPROPERTYBROWSER_H
+#define QTTREEPROPERTYBROWSER_H
+
+#include "qtpropertybrowser.h"
+
+QT_BEGIN_NAMESPACE
+
+class QTreeWidgetItem;
+class QtTreePropertyBrowserPrivate;
+
+class QtTreePropertyBrowser : public QtAbstractPropertyBrowser
+{
+ Q_OBJECT
+ Q_ENUMS(ResizeMode)
+ Q_PROPERTY(int indentation READ indentation WRITE setIndentation)
+ Q_PROPERTY(bool rootIsDecorated READ rootIsDecorated WRITE setRootIsDecorated)
+ Q_PROPERTY(bool alternatingRowColors READ alternatingRowColors WRITE setAlternatingRowColors)
+ Q_PROPERTY(bool headerVisible READ isHeaderVisible WRITE setHeaderVisible)
+ Q_PROPERTY(ResizeMode resizeMode READ resizeMode WRITE setResizeMode)
+ Q_PROPERTY(int splitterPosition READ splitterPosition WRITE setSplitterPosition)
+ Q_PROPERTY(bool propertiesWithoutValueMarked READ propertiesWithoutValueMarked WRITE setPropertiesWithoutValueMarked)
+public:
+
+ enum ResizeMode
+ {
+ Interactive,
+ Stretch,
+ Fixed,
+ ResizeToContents
+ };
+
+ QtTreePropertyBrowser(QWidget *parent = 0);
+ ~QtTreePropertyBrowser();
+
+ int indentation() const;
+ void setIndentation(int i);
+
+ bool rootIsDecorated() const;
+ void setRootIsDecorated(bool show);
+
+ bool alternatingRowColors() const;
+ void setAlternatingRowColors(bool enable);
+
+ bool isHeaderVisible() const;
+ void setHeaderVisible(bool visible);
+
+ ResizeMode resizeMode() const;
+ void setResizeMode(ResizeMode mode);
+
+ int splitterPosition() const;
+ void setSplitterPosition(int position);
+
+ void setExpanded(QtBrowserItem *item, bool expanded);
+ bool isExpanded(QtBrowserItem *item) const;
+
+ bool isItemVisible(QtBrowserItem *item) const;
+ void setItemVisible(QtBrowserItem *item, bool visible);
+
+ void setBackgroundColor(QtBrowserItem *item, const QColor &color);
+ QColor backgroundColor(QtBrowserItem *item) const;
+ QColor calculatedBackgroundColor(QtBrowserItem *item) const;
+
+ void setPropertiesWithoutValueMarked(bool mark);
+ bool propertiesWithoutValueMarked() const;
+
+ void editItem(QtBrowserItem *item);
+
+Q_SIGNALS:
+
+ void collapsed(QtBrowserItem *item);
+ void expanded(QtBrowserItem *item);
+
+protected:
+ virtual void itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem);
+ virtual void itemRemoved(QtBrowserItem *item);
+ virtual void itemChanged(QtBrowserItem *item);
+
+private:
+
+ QScopedPointer<QtTreePropertyBrowserPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtTreePropertyBrowser)
+ Q_DISABLE_COPY(QtTreePropertyBrowser)
+
+ Q_PRIVATE_SLOT(d_func(), void slotCollapsed(const QModelIndex &))
+ Q_PRIVATE_SLOT(d_func(), void slotExpanded(const QModelIndex &))
+ Q_PRIVATE_SLOT(d_func(), void slotCurrentBrowserItemChanged(QtBrowserItem *))
+ Q_PRIVATE_SLOT(d_func(), void slotCurrentTreeItemChanged(QTreeWidgetItem *, QTreeWidgetItem *))
+
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qtpropertybrowser/qtvariantproperty.cpp b/src/shared/qtpropertybrowser/qtvariantproperty.cpp
new file mode 100644
index 000000000..9647b3ac7
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qtvariantproperty.cpp
@@ -0,0 +1,2268 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtvariantproperty.h"
+#include "qtpropertymanager.h"
+#include "qteditorfactory.h"
+#include <QtCore/QVariant>
+#include <QtGui/QIcon>
+#include <QtCore/QDate>
+#include <QtCore/QLocale>
+
+#if defined(Q_CC_MSVC)
+# pragma warning(disable: 4786) /* MS VS 6: truncating debug info after 255 characters */
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QtEnumPropertyType
+{
+};
+
+
+class QtFlagPropertyType
+{
+};
+
+
+class QtGroupPropertyType
+{
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QtEnumPropertyType)
+Q_DECLARE_METATYPE(QtFlagPropertyType)
+Q_DECLARE_METATYPE(QtGroupPropertyType)
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ Returns the type id for an enum property.
+
+ Note that the property's value type can be retrieved using the
+ valueType() function (which is QVariant::Int for the enum property
+ type).
+
+ \sa propertyType(), valueType()
+*/
+int QtVariantPropertyManager::enumTypeId()
+{
+ return qMetaTypeId<QtEnumPropertyType>();
+}
+
+/*!
+ Returns the type id for a flag property.
+
+ Note that the property's value type can be retrieved using the
+ valueType() function (which is QVariant::Int for the flag property
+ type).
+
+ \sa propertyType(), valueType()
+*/
+int QtVariantPropertyManager::flagTypeId()
+{
+ return qMetaTypeId<QtFlagPropertyType>();
+}
+
+/*!
+ Returns the type id for a group property.
+
+ Note that the property's value type can be retrieved using the
+ valueType() function (which is QVariant::Invalid for the group
+ property type, since it doesn't provide any value).
+
+ \sa propertyType(), valueType()
+*/
+int QtVariantPropertyManager::groupTypeId()
+{
+ return qMetaTypeId<QtGroupPropertyType>();
+}
+
+/*!
+ Returns the type id for a icon map attribute.
+
+ Note that the property's attribute type can be retrieved using the
+ attributeType() function.
+
+ \sa attributeType(), QtEnumPropertyManager::enumIcons()
+*/
+int QtVariantPropertyManager::iconMapTypeId()
+{
+ return qMetaTypeId<QtIconMap>();
+}
+
+typedef QMap<const QtProperty *, QtProperty *> PropertyMap;
+Q_GLOBAL_STATIC(PropertyMap, propertyToWrappedProperty)
+
+static QtProperty *wrappedProperty(QtProperty *property)
+{
+ return propertyToWrappedProperty()->value(property, 0);
+}
+
+class QtVariantPropertyPrivate
+{
+ QtVariantProperty *q_ptr;
+public:
+ QtVariantPropertyPrivate(QtVariantPropertyManager *m) : manager(m) {}
+
+ QtVariantPropertyManager *manager;
+};
+
+/*!
+ \class QtVariantProperty
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtVariantProperty class is a convenience class handling
+ QVariant based properties.
+
+ QtVariantProperty provides additional API: A property's type,
+ value type, attribute values and current value can easily be
+ retrieved using the propertyType(), valueType(), attributeValue()
+ and value() functions respectively. In addition, the attribute
+ values and the current value can be set using the corresponding
+ setValue() and setAttribute() functions.
+
+ For example, instead of writing:
+
+ \snippet doc/src/snippets/code/tools_shared_qtpropertybrowser_qtvariantproperty.cpp 0
+
+ you can write:
+
+ \snippet doc/src/snippets/code/tools_shared_qtpropertybrowser_qtvariantproperty.cpp 1
+
+ QtVariantProperty instances can only be created by the
+ QtVariantPropertyManager class.
+
+ \sa QtProperty, QtVariantPropertyManager, QtVariantEditorFactory
+*/
+
+/*!
+ Creates a variant property using the given \a manager.
+
+ Do not use this constructor to create variant property instances;
+ use the QtVariantPropertyManager::addProperty() function
+ instead. This constructor is used internally by the
+ QtVariantPropertyManager::createProperty() function.
+
+ \sa QtVariantPropertyManager
+*/
+QtVariantProperty::QtVariantProperty(QtVariantPropertyManager *manager)
+ : QtProperty(manager), d_ptr(new QtVariantPropertyPrivate(manager))
+{
+}
+
+/*!
+ Destroys this property.
+
+ \sa QtProperty::~QtProperty()
+*/
+QtVariantProperty::~QtVariantProperty()
+{
+}
+
+/*!
+ Returns the property's current value.
+
+ \sa valueType(), setValue()
+*/
+QVariant QtVariantProperty::value() const
+{
+ return d_ptr->manager->value(this);
+}
+
+/*!
+ Returns this property's value for the specified \a attribute.
+
+ QtVariantPropertyManager provides a couple of related functions:
+ \l{QtVariantPropertyManager::attributes()}{attributes()} and
+ \l{QtVariantPropertyManager::attributeType()}{attributeType()}.
+
+ \sa setAttribute()
+*/
+QVariant QtVariantProperty::attributeValue(const QString &attribute) const
+{
+ return d_ptr->manager->attributeValue(this, attribute);
+}
+
+/*!
+ Returns the type of this property's value.
+
+ \sa propertyType()
+*/
+int QtVariantProperty::valueType() const
+{
+ return d_ptr->manager->valueType(this);
+}
+
+/*!
+ Returns this property's type.
+
+ QtVariantPropertyManager provides several related functions:
+ \l{QtVariantPropertyManager::enumTypeId()}{enumTypeId()},
+ \l{QtVariantPropertyManager::flagTypeId()}{flagTypeId()} and
+ \l{QtVariantPropertyManager::groupTypeId()}{groupTypeId()}.
+
+ \sa valueType()
+*/
+int QtVariantProperty::propertyType() const
+{
+ return d_ptr->manager->propertyType(this);
+}
+
+/*!
+ Sets the value of this property to \a value.
+
+ The specified \a value must be of the type returned by
+ valueType(), or of a type that can be converted to valueType()
+ using the QVariant::canConvert() function; otherwise this function
+ does nothing.
+
+ \sa value()
+*/
+void QtVariantProperty::setValue(const QVariant &value)
+{
+ d_ptr->manager->setValue(this, value);
+}
+
+/*!
+ Sets the \a attribute of property to \a value.
+
+ QtVariantPropertyManager provides the related
+ \l{QtVariantPropertyManager::setAttribute()}{setAttribute()}
+ function.
+
+ \sa attributeValue()
+*/
+void QtVariantProperty::setAttribute(const QString &attribute, const QVariant &value)
+{
+ d_ptr->manager->setAttribute(this, attribute, value);
+}
+
+class QtVariantPropertyManagerPrivate
+{
+ QtVariantPropertyManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtVariantPropertyManager)
+public:
+ QtVariantPropertyManagerPrivate();
+
+ bool m_creatingProperty;
+ bool m_creatingSubProperties;
+ bool m_destroyingSubProperties;
+ int m_propertyType;
+
+ void slotValueChanged(QtProperty *property, int val);
+ void slotRangeChanged(QtProperty *property, int min, int max);
+ void slotSingleStepChanged(QtProperty *property, int step);
+ void slotValueChanged(QtProperty *property, double val);
+ void slotRangeChanged(QtProperty *property, double min, double max);
+ void slotSingleStepChanged(QtProperty *property, double step);
+ void slotDecimalsChanged(QtProperty *property, int prec);
+ void slotValueChanged(QtProperty *property, bool val);
+ void slotValueChanged(QtProperty *property, const QString &val);
+ void slotRegExpChanged(QtProperty *property, const QRegExp &regExp);
+ void slotValueChanged(QtProperty *property, const QDate &val);
+ void slotRangeChanged(QtProperty *property, const QDate &min, const QDate &max);
+ void slotValueChanged(QtProperty *property, const QTime &val);
+ void slotValueChanged(QtProperty *property, const QDateTime &val);
+ void slotValueChanged(QtProperty *property, const QKeySequence &val);
+ void slotValueChanged(QtProperty *property, const QChar &val);
+ void slotValueChanged(QtProperty *property, const QLocale &val);
+ void slotValueChanged(QtProperty *property, const QPoint &val);
+ void slotValueChanged(QtProperty *property, const QPointF &val);
+ void slotValueChanged(QtProperty *property, const QSize &val);
+ void slotRangeChanged(QtProperty *property, const QSize &min, const QSize &max);
+ void slotValueChanged(QtProperty *property, const QSizeF &val);
+ void slotRangeChanged(QtProperty *property, const QSizeF &min, const QSizeF &max);
+ void slotValueChanged(QtProperty *property, const QRect &val);
+ void slotConstraintChanged(QtProperty *property, const QRect &val);
+ void slotValueChanged(QtProperty *property, const QRectF &val);
+ void slotConstraintChanged(QtProperty *property, const QRectF &val);
+ void slotValueChanged(QtProperty *property, const QColor &val);
+ void slotEnumChanged(QtProperty *property, int val);
+ void slotEnumNamesChanged(QtProperty *property, const QStringList &enumNames);
+ void slotEnumIconsChanged(QtProperty *property, const QMap<int, QIcon> &enumIcons);
+ void slotValueChanged(QtProperty *property, const QSizePolicy &val);
+ void slotValueChanged(QtProperty *property, const QFont &val);
+ void slotValueChanged(QtProperty *property, const QCursor &val);
+ void slotFlagChanged(QtProperty *property, int val);
+ void slotFlagNamesChanged(QtProperty *property, const QStringList &flagNames);
+ void slotPropertyInserted(QtProperty *property, QtProperty *parent, QtProperty *after);
+ void slotPropertyRemoved(QtProperty *property, QtProperty *parent);
+
+ void valueChanged(QtProperty *property, const QVariant &val);
+
+ int internalPropertyToType(QtProperty *property) const;
+ QtVariantProperty *createSubProperty(QtVariantProperty *parent, QtVariantProperty *after,
+ QtProperty *internal);
+ void removeSubProperty(QtVariantProperty *property);
+
+ QMap<int, QtAbstractPropertyManager *> m_typeToPropertyManager;
+ QMap<int, QMap<QString, int> > m_typeToAttributeToAttributeType;
+
+ QMap<const QtProperty *, QPair<QtVariantProperty *, int> > m_propertyToType;
+
+ QMap<int, int> m_typeToValueType;
+
+
+ QMap<QtProperty *, QtVariantProperty *> m_internalToProperty;
+
+ const QString m_constraintAttribute;
+ const QString m_singleStepAttribute;
+ const QString m_decimalsAttribute;
+ const QString m_enumIconsAttribute;
+ const QString m_enumNamesAttribute;
+ const QString m_flagNamesAttribute;
+ const QString m_maximumAttribute;
+ const QString m_minimumAttribute;
+ const QString m_regExpAttribute;
+};
+
+QtVariantPropertyManagerPrivate::QtVariantPropertyManagerPrivate() :
+ m_constraintAttribute(QLatin1String("constraint")),
+ m_singleStepAttribute(QLatin1String("singleStep")),
+ m_decimalsAttribute(QLatin1String("decimals")),
+ m_enumIconsAttribute(QLatin1String("enumIcons")),
+ m_enumNamesAttribute(QLatin1String("enumNames")),
+ m_flagNamesAttribute(QLatin1String("flagNames")),
+ m_maximumAttribute(QLatin1String("maximum")),
+ m_minimumAttribute(QLatin1String("minimum")),
+ m_regExpAttribute(QLatin1String("regExp"))
+{
+}
+
+int QtVariantPropertyManagerPrivate::internalPropertyToType(QtProperty *property) const
+{
+ int type = 0;
+ QtAbstractPropertyManager *internPropertyManager = property->propertyManager();
+ if (qobject_cast<QtIntPropertyManager *>(internPropertyManager))
+ type = QVariant::Int;
+ else if (qobject_cast<QtEnumPropertyManager *>(internPropertyManager))
+ type = QtVariantPropertyManager::enumTypeId();
+ else if (qobject_cast<QtBoolPropertyManager *>(internPropertyManager))
+ type = QVariant::Bool;
+ else if (qobject_cast<QtDoublePropertyManager *>(internPropertyManager))
+ type = QVariant::Double;
+ return type;
+}
+
+QtVariantProperty *QtVariantPropertyManagerPrivate::createSubProperty(QtVariantProperty *parent,
+ QtVariantProperty *after, QtProperty *internal)
+{
+ int type = internalPropertyToType(internal);
+ if (!type)
+ return 0;
+
+ bool wasCreatingSubProperties = m_creatingSubProperties;
+ m_creatingSubProperties = true;
+
+ QtVariantProperty *varChild = q_ptr->addProperty(type, internal->propertyName());
+
+ m_creatingSubProperties = wasCreatingSubProperties;
+
+ varChild->setPropertyName(internal->propertyName());
+ varChild->setToolTip(internal->toolTip());
+ varChild->setStatusTip(internal->statusTip());
+ varChild->setWhatsThis(internal->whatsThis());
+
+ parent->insertSubProperty(varChild, after);
+
+ m_internalToProperty[internal] = varChild;
+ propertyToWrappedProperty()->insert(varChild, internal);
+ return varChild;
+}
+
+void QtVariantPropertyManagerPrivate::removeSubProperty(QtVariantProperty *property)
+{
+ QtProperty *internChild = wrappedProperty(property);
+ bool wasDestroyingSubProperties = m_destroyingSubProperties;
+ m_destroyingSubProperties = true;
+ delete property;
+ m_destroyingSubProperties = wasDestroyingSubProperties;
+ m_internalToProperty.remove(internChild);
+ propertyToWrappedProperty()->remove(property);
+}
+
+void QtVariantPropertyManagerPrivate::slotPropertyInserted(QtProperty *property,
+ QtProperty *parent, QtProperty *after)
+{
+ if (m_creatingProperty)
+ return;
+
+ QtVariantProperty *varParent = m_internalToProperty.value(parent, 0);
+ if (!varParent)
+ return;
+
+ QtVariantProperty *varAfter = 0;
+ if (after) {
+ varAfter = m_internalToProperty.value(after, 0);
+ if (!varAfter)
+ return;
+ }
+
+ createSubProperty(varParent, varAfter, property);
+}
+
+void QtVariantPropertyManagerPrivate::slotPropertyRemoved(QtProperty *property, QtProperty *parent)
+{
+ Q_UNUSED(parent)
+
+ QtVariantProperty *varProperty = m_internalToProperty.value(property, 0);
+ if (!varProperty)
+ return;
+
+ removeSubProperty(varProperty);
+}
+
+void QtVariantPropertyManagerPrivate::valueChanged(QtProperty *property, const QVariant &val)
+{
+ QtVariantProperty *varProp = m_internalToProperty.value(property, 0);
+ if (!varProp)
+ return;
+ emit q_ptr->valueChanged(varProp, val);
+ emit q_ptr->propertyChanged(varProp);
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, int val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotRangeChanged(QtProperty *property, int min, int max)
+{
+ if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) {
+ emit q_ptr->attributeChanged(varProp, m_minimumAttribute, QVariant(min));
+ emit q_ptr->attributeChanged(varProp, m_maximumAttribute, QVariant(max));
+ }
+}
+
+void QtVariantPropertyManagerPrivate::slotSingleStepChanged(QtProperty *property, int step)
+{
+ if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0))
+ emit q_ptr->attributeChanged(varProp, m_singleStepAttribute, QVariant(step));
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, double val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotRangeChanged(QtProperty *property, double min, double max)
+{
+ if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) {
+ emit q_ptr->attributeChanged(varProp, m_minimumAttribute, QVariant(min));
+ emit q_ptr->attributeChanged(varProp, m_maximumAttribute, QVariant(max));
+ }
+}
+
+void QtVariantPropertyManagerPrivate::slotSingleStepChanged(QtProperty *property, double step)
+{
+ if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0))
+ emit q_ptr->attributeChanged(varProp, m_singleStepAttribute, QVariant(step));
+}
+
+void QtVariantPropertyManagerPrivate::slotDecimalsChanged(QtProperty *property, int prec)
+{
+ if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0))
+ emit q_ptr->attributeChanged(varProp, m_decimalsAttribute, QVariant(prec));
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, bool val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QString &val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotRegExpChanged(QtProperty *property, const QRegExp &regExp)
+{
+ if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0))
+ emit q_ptr->attributeChanged(varProp, m_regExpAttribute, QVariant(regExp));
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QDate &val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotRangeChanged(QtProperty *property, const QDate &min, const QDate &max)
+{
+ if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) {
+ emit q_ptr->attributeChanged(varProp, m_minimumAttribute, QVariant(min));
+ emit q_ptr->attributeChanged(varProp, m_maximumAttribute, QVariant(max));
+ }
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QTime &val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QDateTime &val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QKeySequence &val)
+{
+ QVariant v;
+ v.setValue(val);
+ valueChanged(property, v);
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QChar &val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QLocale &val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QPoint &val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QPointF &val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QSize &val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotRangeChanged(QtProperty *property, const QSize &min, const QSize &max)
+{
+ if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) {
+ emit q_ptr->attributeChanged(varProp, m_minimumAttribute, QVariant(min));
+ emit q_ptr->attributeChanged(varProp, m_maximumAttribute, QVariant(max));
+ }
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QSizeF &val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotRangeChanged(QtProperty *property, const QSizeF &min, const QSizeF &max)
+{
+ if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) {
+ emit q_ptr->attributeChanged(varProp, m_minimumAttribute, QVariant(min));
+ emit q_ptr->attributeChanged(varProp, m_maximumAttribute, QVariant(max));
+ }
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QRect &val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotConstraintChanged(QtProperty *property, const QRect &constraint)
+{
+ if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0))
+ emit q_ptr->attributeChanged(varProp, m_constraintAttribute, QVariant(constraint));
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QRectF &val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotConstraintChanged(QtProperty *property, const QRectF &constraint)
+{
+ if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0))
+ emit q_ptr->attributeChanged(varProp, m_constraintAttribute, QVariant(constraint));
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QColor &val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotEnumNamesChanged(QtProperty *property, const QStringList &enumNames)
+{
+ if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0))
+ emit q_ptr->attributeChanged(varProp, m_enumNamesAttribute, QVariant(enumNames));
+}
+
+void QtVariantPropertyManagerPrivate::slotEnumIconsChanged(QtProperty *property, const QMap<int, QIcon> &enumIcons)
+{
+ if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) {
+ QVariant v;
+ v.setValue(enumIcons);
+ emit q_ptr->attributeChanged(varProp, m_enumIconsAttribute, v);
+ }
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QSizePolicy &val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QFont &val)
+{
+ valueChanged(property, QVariant(val));
+}
+
+void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QCursor &val)
+{
+#ifndef QT_NO_CURSOR
+ valueChanged(property, QVariant(val));
+#endif
+}
+
+void QtVariantPropertyManagerPrivate::slotFlagNamesChanged(QtProperty *property, const QStringList &flagNames)
+{
+ if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0))
+ emit q_ptr->attributeChanged(varProp, m_flagNamesAttribute, QVariant(flagNames));
+}
+
+/*!
+ \class QtVariantPropertyManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtVariantPropertyManager class provides and manages QVariant based properties.
+
+ QtVariantPropertyManager provides the addProperty() function which
+ creates QtVariantProperty objects. The QtVariantProperty class is
+ a convenience class handling QVariant based properties inheriting
+ QtProperty. A QtProperty object created by a
+ QtVariantPropertyManager instance can be converted into a
+ QtVariantProperty object using the variantProperty() function.
+
+ The property's value can be retrieved using the value(), and set
+ using the setValue() slot. In addition the property's type, and
+ the type of its value, can be retrieved using the propertyType()
+ and valueType() functions respectively.
+
+ A property's type is a QVariant::Type enumerator value, and
+ usually a property's type is the same as its value type. But for
+ some properties the types differ, for example for enums, flags and
+ group types in which case QtVariantPropertyManager provides the
+ enumTypeId(), flagTypeId() and groupTypeId() functions,
+ respectively, to identify their property type (the value types are
+ QVariant::Int for the enum and flag types, and QVariant::Invalid
+ for the group type).
+
+ Use the isPropertyTypeSupported() function to check if a particular
+ property type is supported. The currently supported property types
+ are:
+
+ \table
+ \header
+ \o Property Type
+ \o Property Type Id
+ \row
+ \o int
+ \o QVariant::Int
+ \row
+ \o double
+ \o QVariant::Double
+ \row
+ \o bool
+ \o QVariant::Bool
+ \row
+ \o QString
+ \o QVariant::String
+ \row
+ \o QDate
+ \o QVariant::Date
+ \row
+ \o QTime
+ \o QVariant::Time
+ \row
+ \o QDateTime
+ \o QVariant::DateTime
+ \row
+ \o QKeySequence
+ \o QVariant::KeySequence
+ \row
+ \o QChar
+ \o QVariant::Char
+ \row
+ \o QLocale
+ \o QVariant::Locale
+ \row
+ \o QPoint
+ \o QVariant::Point
+ \row
+ \o QPointF
+ \o QVariant::PointF
+ \row
+ \o QSize
+ \o QVariant::Size
+ \row
+ \o QSizeF
+ \o QVariant::SizeF
+ \row
+ \o QRect
+ \o QVariant::Rect
+ \row
+ \o QRectF
+ \o QVariant::RectF
+ \row
+ \o QColor
+ \o QVariant::Color
+ \row
+ \o QSizePolicy
+ \o QVariant::SizePolicy
+ \row
+ \o QFont
+ \o QVariant::Font
+ \row
+ \o QCursor
+ \o QVariant::Cursor
+ \row
+ \o enum
+ \o enumTypeId()
+ \row
+ \o flag
+ \o flagTypeId()
+ \row
+ \o group
+ \o groupTypeId()
+ \endtable
+
+ Each property type can provide additional attributes,
+ e.g. QVariant::Int and QVariant::Double provides minimum and
+ maximum values. The currently supported attributes are:
+
+ \table
+ \header
+ \o Property Type
+ \o Attribute Name
+ \o Attribute Type
+ \row
+ \o \c int
+ \o minimum
+ \o QVariant::Int
+ \row
+ \o
+ \o maximum
+ \o QVariant::Int
+ \row
+ \o
+ \o singleStep
+ \o QVariant::Int
+ \row
+ \o \c double
+ \o minimum
+ \o QVariant::Double
+ \row
+ \o
+ \o maximum
+ \o QVariant::Double
+ \row
+ \o
+ \o singleStep
+ \o QVariant::Double
+ \row
+ \o
+ \o decimals
+ \o QVariant::Int
+ \row
+ \o QString
+ \o regExp
+ \o QVariant::RegExp
+ \row
+ \o QDate
+ \o minimum
+ \o QVariant::Date
+ \row
+ \o
+ \o maximum
+ \o QVariant::Date
+ \row
+ \o QPointF
+ \o decimals
+ \o QVariant::Int
+ \row
+ \o QSize
+ \o minimum
+ \o QVariant::Size
+ \row
+ \o
+ \o maximum
+ \o QVariant::Size
+ \row
+ \o QSizeF
+ \o minimum
+ \o QVariant::SizeF
+ \row
+ \o
+ \o maximum
+ \o QVariant::SizeF
+ \row
+ \o
+ \o decimals
+ \o QVariant::Int
+ \row
+ \o QRect
+ \o constraint
+ \o QVariant::Rect
+ \row
+ \o QRectF
+ \o constraint
+ \o QVariant::RectF
+ \row
+ \o
+ \o decimals
+ \o QVariant::Int
+ \row
+ \o \c enum
+ \o enumNames
+ \o QVariant::StringList
+ \row
+ \o
+ \o enumIcons
+ \o iconMapTypeId()
+ \row
+ \o \c flag
+ \o flagNames
+ \o QVariant::StringList
+ \endtable
+
+ The attributes for a given property type can be retrieved using
+ the attributes() function. Each attribute has a value type which
+ can be retrieved using the attributeType() function, and a value
+ accessible through the attributeValue() function. In addition, the
+ value can be set using the setAttribute() slot.
+
+ QtVariantManager also provides the valueChanged() signal which is
+ emitted whenever a property created by this manager change, and
+ the attributeChanged() signal which is emitted whenever an
+ attribute of such a property changes.
+
+ \sa QtVariantProperty, QtVariantEditorFactory
+*/
+
+/*!
+ \fn void QtVariantPropertyManager::valueChanged(QtProperty *property, const QVariant &value)
+
+ This signal is emitted whenever a property created by this manager
+ changes its value, passing a pointer to the \a property and the
+ new \a value as parameters.
+
+ \sa setValue()
+*/
+
+/*!
+ \fn void QtVariantPropertyManager::attributeChanged(QtProperty *property,
+ const QString &attribute, const QVariant &value)
+
+ This signal is emitted whenever an attribute of a property created
+ by this manager changes its value, passing a pointer to the \a
+ property, the \a attribute and the new \a value as parameters.
+
+ \sa setAttribute()
+*/
+
+/*!
+ Creates a manager with the given \a parent.
+*/
+QtVariantPropertyManager::QtVariantPropertyManager(QObject *parent)
+ : QtAbstractPropertyManager(parent), d_ptr(new QtVariantPropertyManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->m_creatingProperty = false;
+ d_ptr->m_creatingSubProperties = false;
+ d_ptr->m_destroyingSubProperties = false;
+ d_ptr->m_propertyType = 0;
+
+ // IntPropertyManager
+ QtIntPropertyManager *intPropertyManager = new QtIntPropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::Int] = intPropertyManager;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::Int][d_ptr->m_minimumAttribute] = QVariant::Int;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::Int][d_ptr->m_maximumAttribute] = QVariant::Int;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::Int][d_ptr->m_singleStepAttribute] = QVariant::Int;
+ d_ptr->m_typeToValueType[QVariant::Int] = QVariant::Int;
+ connect(intPropertyManager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotValueChanged(QtProperty*,int)));
+ connect(intPropertyManager, SIGNAL(rangeChanged(QtProperty*,int,int)),
+ this, SLOT(slotRangeChanged(QtProperty*,int,int)));
+ connect(intPropertyManager, SIGNAL(singleStepChanged(QtProperty*,int)),
+ this, SLOT(slotSingleStepChanged(QtProperty*,int)));
+ // DoublePropertyManager
+ QtDoublePropertyManager *doublePropertyManager = new QtDoublePropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::Double] = doublePropertyManager;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::Double][d_ptr->m_minimumAttribute] =
+ QVariant::Double;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::Double][d_ptr->m_maximumAttribute] =
+ QVariant::Double;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::Double][d_ptr->m_singleStepAttribute] =
+ QVariant::Double;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::Double][d_ptr->m_decimalsAttribute] =
+ QVariant::Int;
+ d_ptr->m_typeToValueType[QVariant::Double] = QVariant::Double;
+ connect(doublePropertyManager, SIGNAL(valueChanged(QtProperty*,double)),
+ this, SLOT(slotValueChanged(QtProperty*,double)));
+ connect(doublePropertyManager, SIGNAL(rangeChanged(QtProperty*,double,double)),
+ this, SLOT(slotRangeChanged(QtProperty*,double,double)));
+ connect(doublePropertyManager, SIGNAL(singleStepChanged(QtProperty*,double)),
+ this, SLOT(slotSingleStepChanged(QtProperty*,double)));
+ connect(doublePropertyManager, SIGNAL(decimalsChanged(QtProperty*,int)),
+ this, SLOT(slotDecimalsChanged(QtProperty*,int)));
+ // BoolPropertyManager
+ QtBoolPropertyManager *boolPropertyManager = new QtBoolPropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::Bool] = boolPropertyManager;
+ d_ptr->m_typeToValueType[QVariant::Bool] = QVariant::Bool;
+ connect(boolPropertyManager, SIGNAL(valueChanged(QtProperty*,bool)),
+ this, SLOT(slotValueChanged(QtProperty*,bool)));
+ // StringPropertyManager
+ QtStringPropertyManager *stringPropertyManager = new QtStringPropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::String] = stringPropertyManager;
+ d_ptr->m_typeToValueType[QVariant::String] = QVariant::String;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::String][d_ptr->m_regExpAttribute] =
+ QVariant::RegExp;
+ connect(stringPropertyManager, SIGNAL(valueChanged(QtProperty*,QString)),
+ this, SLOT(slotValueChanged(QtProperty*,QString)));
+ connect(stringPropertyManager, SIGNAL(regExpChanged(QtProperty*,QRegExp)),
+ this, SLOT(slotRegExpChanged(QtProperty*,QRegExp)));
+ // DatePropertyManager
+ QtDatePropertyManager *datePropertyManager = new QtDatePropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::Date] = datePropertyManager;
+ d_ptr->m_typeToValueType[QVariant::Date] = QVariant::Date;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::Date][d_ptr->m_minimumAttribute] =
+ QVariant::Date;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::Date][d_ptr->m_maximumAttribute] =
+ QVariant::Date;
+ connect(datePropertyManager, SIGNAL(valueChanged(QtProperty*,QDate)),
+ this, SLOT(slotValueChanged(QtProperty*,QDate)));
+ connect(datePropertyManager, SIGNAL(rangeChanged(QtProperty*,QDate,QDate)),
+ this, SLOT(slotRangeChanged(QtProperty*,QDate,QDate)));
+ // TimePropertyManager
+ QtTimePropertyManager *timePropertyManager = new QtTimePropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::Time] = timePropertyManager;
+ d_ptr->m_typeToValueType[QVariant::Time] = QVariant::Time;
+ connect(timePropertyManager, SIGNAL(valueChanged(QtProperty*,QTime)),
+ this, SLOT(slotValueChanged(QtProperty*,QTime)));
+ // DateTimePropertyManager
+ QtDateTimePropertyManager *dateTimePropertyManager = new QtDateTimePropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::DateTime] = dateTimePropertyManager;
+ d_ptr->m_typeToValueType[QVariant::DateTime] = QVariant::DateTime;
+ connect(dateTimePropertyManager, SIGNAL(valueChanged(QtProperty*,QDateTime)),
+ this, SLOT(slotValueChanged(QtProperty*,QDateTime)));
+ // KeySequencePropertyManager
+ QtKeySequencePropertyManager *keySequencePropertyManager = new QtKeySequencePropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::KeySequence] = keySequencePropertyManager;
+ d_ptr->m_typeToValueType[QVariant::KeySequence] = QVariant::KeySequence;
+ connect(keySequencePropertyManager, SIGNAL(valueChanged(QtProperty*,QKeySequence)),
+ this, SLOT(slotValueChanged(QtProperty*,QKeySequence)));
+ // CharPropertyManager
+ QtCharPropertyManager *charPropertyManager = new QtCharPropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::Char] = charPropertyManager;
+ d_ptr->m_typeToValueType[QVariant::Char] = QVariant::Char;
+ connect(charPropertyManager, SIGNAL(valueChanged(QtProperty*,QChar)),
+ this, SLOT(slotValueChanged(QtProperty*,QChar)));
+ // LocalePropertyManager
+ QtLocalePropertyManager *localePropertyManager = new QtLocalePropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::Locale] = localePropertyManager;
+ d_ptr->m_typeToValueType[QVariant::Locale] = QVariant::Locale;
+ connect(localePropertyManager, SIGNAL(valueChanged(QtProperty*,QLocale)),
+ this, SLOT(slotValueChanged(QtProperty*,QLocale)));
+ connect(localePropertyManager->subEnumPropertyManager(), SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotValueChanged(QtProperty*,int)));
+ connect(localePropertyManager, SIGNAL(propertyInserted(QtProperty*,QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyInserted(QtProperty*,QtProperty*,QtProperty*)));
+ connect(localePropertyManager, SIGNAL(propertyRemoved(QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*)));
+ // PointPropertyManager
+ QtPointPropertyManager *pointPropertyManager = new QtPointPropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::Point] = pointPropertyManager;
+ d_ptr->m_typeToValueType[QVariant::Point] = QVariant::Point;
+ connect(pointPropertyManager, SIGNAL(valueChanged(QtProperty*,QPoint)),
+ this, SLOT(slotValueChanged(QtProperty*,QPoint)));
+ connect(pointPropertyManager->subIntPropertyManager(), SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotValueChanged(QtProperty*,int)));
+ connect(pointPropertyManager, SIGNAL(propertyInserted(QtProperty*,QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyInserted(QtProperty*,QtProperty*,QtProperty*)));
+ connect(pointPropertyManager, SIGNAL(propertyRemoved(QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*)));
+ // PointFPropertyManager
+ QtPointFPropertyManager *pointFPropertyManager = new QtPointFPropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::PointF] = pointFPropertyManager;
+ d_ptr->m_typeToValueType[QVariant::PointF] = QVariant::PointF;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::PointF][d_ptr->m_decimalsAttribute] =
+ QVariant::Int;
+ connect(pointFPropertyManager, SIGNAL(valueChanged(QtProperty*,QPointF)),
+ this, SLOT(slotValueChanged(QtProperty*,QPointF)));
+ connect(pointFPropertyManager, SIGNAL(decimalsChanged(QtProperty*,int)),
+ this, SLOT(slotDecimalsChanged(QtProperty*,int)));
+ connect(pointFPropertyManager->subDoublePropertyManager(), SIGNAL(valueChanged(QtProperty*,double)),
+ this, SLOT(slotValueChanged(QtProperty*,double)));
+ connect(pointFPropertyManager, SIGNAL(propertyInserted(QtProperty*,QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyInserted(QtProperty*,QtProperty*,QtProperty*)));
+ connect(pointFPropertyManager, SIGNAL(propertyRemoved(QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*)));
+ // SizePropertyManager
+ QtSizePropertyManager *sizePropertyManager = new QtSizePropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::Size] = sizePropertyManager;
+ d_ptr->m_typeToValueType[QVariant::Size] = QVariant::Size;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::Size][d_ptr->m_minimumAttribute] =
+ QVariant::Size;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::Size][d_ptr->m_maximumAttribute] =
+ QVariant::Size;
+ connect(sizePropertyManager, SIGNAL(valueChanged(QtProperty*,QSize)),
+ this, SLOT(slotValueChanged(QtProperty*,QSize)));
+ connect(sizePropertyManager, SIGNAL(rangeChanged(QtProperty*,QSize,QSize)),
+ this, SLOT(slotRangeChanged(QtProperty*,QSize,QSize)));
+ connect(sizePropertyManager->subIntPropertyManager(), SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotValueChanged(QtProperty*,int)));
+ connect(sizePropertyManager->subIntPropertyManager(), SIGNAL(rangeChanged(QtProperty*,int,int)),
+ this, SLOT(slotRangeChanged(QtProperty*,int,int)));
+ connect(sizePropertyManager, SIGNAL(propertyInserted(QtProperty*,QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyInserted(QtProperty*,QtProperty*,QtProperty*)));
+ connect(sizePropertyManager, SIGNAL(propertyRemoved(QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*)));
+ // SizeFPropertyManager
+ QtSizeFPropertyManager *sizeFPropertyManager = new QtSizeFPropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::SizeF] = sizeFPropertyManager;
+ d_ptr->m_typeToValueType[QVariant::SizeF] = QVariant::SizeF;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::SizeF][d_ptr->m_minimumAttribute] =
+ QVariant::SizeF;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::SizeF][d_ptr->m_maximumAttribute] =
+ QVariant::SizeF;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::SizeF][d_ptr->m_decimalsAttribute] =
+ QVariant::Int;
+ connect(sizeFPropertyManager, SIGNAL(valueChanged(QtProperty*,QSizeF)),
+ this, SLOT(slotValueChanged(QtProperty*,QSizeF)));
+ connect(sizeFPropertyManager, SIGNAL(rangeChanged(QtProperty*,QSizeF,QSizeF)),
+ this, SLOT(slotRangeChanged(QtProperty*,QSizeF,QSizeF)));
+ connect(sizeFPropertyManager, SIGNAL(decimalsChanged(QtProperty*,int)),
+ this, SLOT(slotDecimalsChanged(QtProperty*,int)));
+ connect(sizeFPropertyManager->subDoublePropertyManager(), SIGNAL(valueChanged(QtProperty*,double)),
+ this, SLOT(slotValueChanged(QtProperty*,double)));
+ connect(sizeFPropertyManager->subDoublePropertyManager(), SIGNAL(rangeChanged(QtProperty*,double,double)),
+ this, SLOT(slotRangeChanged(QtProperty*,double,double)));
+ connect(sizeFPropertyManager, SIGNAL(propertyInserted(QtProperty*,QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyInserted(QtProperty*,QtProperty*,QtProperty*)));
+ connect(sizeFPropertyManager, SIGNAL(propertyRemoved(QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*)));
+ // RectPropertyManager
+ QtRectPropertyManager *rectPropertyManager = new QtRectPropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::Rect] = rectPropertyManager;
+ d_ptr->m_typeToValueType[QVariant::Rect] = QVariant::Rect;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::Rect][d_ptr->m_constraintAttribute] =
+ QVariant::Rect;
+ connect(rectPropertyManager, SIGNAL(valueChanged(QtProperty*,QRect)),
+ this, SLOT(slotValueChanged(QtProperty*,QRect)));
+ connect(rectPropertyManager, SIGNAL(constraintChanged(QtProperty*,QRect)),
+ this, SLOT(slotConstraintChanged(QtProperty*,QRect)));
+ connect(rectPropertyManager->subIntPropertyManager(), SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotValueChanged(QtProperty*,int)));
+ connect(rectPropertyManager->subIntPropertyManager(), SIGNAL(rangeChanged(QtProperty*,int,int)),
+ this, SLOT(slotRangeChanged(QtProperty*,int,int)));
+ connect(rectPropertyManager, SIGNAL(propertyInserted(QtProperty*,QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyInserted(QtProperty*,QtProperty*,QtProperty*)));
+ connect(rectPropertyManager, SIGNAL(propertyRemoved(QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*)));
+ // RectFPropertyManager
+ QtRectFPropertyManager *rectFPropertyManager = new QtRectFPropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::RectF] = rectFPropertyManager;
+ d_ptr->m_typeToValueType[QVariant::RectF] = QVariant::RectF;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::RectF][d_ptr->m_constraintAttribute] =
+ QVariant::RectF;
+ d_ptr->m_typeToAttributeToAttributeType[QVariant::RectF][d_ptr->m_decimalsAttribute] =
+ QVariant::Int;
+ connect(rectFPropertyManager, SIGNAL(valueChanged(QtProperty*,QRectF)),
+ this, SLOT(slotValueChanged(QtProperty*,QRectF)));
+ connect(rectFPropertyManager, SIGNAL(constraintChanged(QtProperty*,QRectF)),
+ this, SLOT(slotConstraintChanged(QtProperty*,QRectF)));
+ connect(rectFPropertyManager, SIGNAL(decimalsChanged(QtProperty*,int)),
+ this, SLOT(slotDecimalsChanged(QtProperty*,int)));
+ connect(rectFPropertyManager->subDoublePropertyManager(), SIGNAL(valueChanged(QtProperty*,double)),
+ this, SLOT(slotValueChanged(QtProperty*,double)));
+ connect(rectFPropertyManager->subDoublePropertyManager(), SIGNAL(rangeChanged(QtProperty*,double,double)),
+ this, SLOT(slotRangeChanged(QtProperty*,double,double)));
+ connect(rectFPropertyManager, SIGNAL(propertyInserted(QtProperty*,QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyInserted(QtProperty*,QtProperty*,QtProperty*)));
+ connect(rectFPropertyManager, SIGNAL(propertyRemoved(QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*)));
+ // ColorPropertyManager
+ QtColorPropertyManager *colorPropertyManager = new QtColorPropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::Color] = colorPropertyManager;
+ d_ptr->m_typeToValueType[QVariant::Color] = QVariant::Color;
+ connect(colorPropertyManager, SIGNAL(valueChanged(QtProperty*,QColor)),
+ this, SLOT(slotValueChanged(QtProperty*,QColor)));
+ connect(colorPropertyManager->subIntPropertyManager(), SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotValueChanged(QtProperty*,int)));
+ connect(colorPropertyManager, SIGNAL(propertyInserted(QtProperty*,QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyInserted(QtProperty*,QtProperty*,QtProperty*)));
+ connect(colorPropertyManager, SIGNAL(propertyRemoved(QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*)));
+ // EnumPropertyManager
+ int enumId = enumTypeId();
+ QtEnumPropertyManager *enumPropertyManager = new QtEnumPropertyManager(this);
+ d_ptr->m_typeToPropertyManager[enumId] = enumPropertyManager;
+ d_ptr->m_typeToValueType[enumId] = QVariant::Int;
+ d_ptr->m_typeToAttributeToAttributeType[enumId][d_ptr->m_enumNamesAttribute] =
+ QVariant::StringList;
+ d_ptr->m_typeToAttributeToAttributeType[enumId][d_ptr->m_enumIconsAttribute] =
+ iconMapTypeId();
+ connect(enumPropertyManager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotValueChanged(QtProperty*,int)));
+ connect(enumPropertyManager, SIGNAL(enumNamesChanged(QtProperty*,QStringList)),
+ this, SLOT(slotEnumNamesChanged(QtProperty*,QStringList)));
+ connect(enumPropertyManager, SIGNAL(enumIconsChanged(QtProperty*,QMap<int,QIcon>)),
+ this, SLOT(slotEnumIconsChanged(QtProperty*,QMap<int,QIcon>)));
+ // SizePolicyPropertyManager
+ QtSizePolicyPropertyManager *sizePolicyPropertyManager = new QtSizePolicyPropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::SizePolicy] = sizePolicyPropertyManager;
+ d_ptr->m_typeToValueType[QVariant::SizePolicy] = QVariant::SizePolicy;
+ connect(sizePolicyPropertyManager, SIGNAL(valueChanged(QtProperty*,QSizePolicy)),
+ this, SLOT(slotValueChanged(QtProperty*,QSizePolicy)));
+ connect(sizePolicyPropertyManager->subIntPropertyManager(), SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotValueChanged(QtProperty*,int)));
+ connect(sizePolicyPropertyManager->subIntPropertyManager(), SIGNAL(rangeChanged(QtProperty*,int,int)),
+ this, SLOT(slotRangeChanged(QtProperty*,int,int)));
+ connect(sizePolicyPropertyManager->subEnumPropertyManager(), SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotValueChanged(QtProperty*,int)));
+ connect(sizePolicyPropertyManager->subEnumPropertyManager(),
+ SIGNAL(enumNamesChanged(QtProperty*,QStringList)),
+ this, SLOT(slotEnumNamesChanged(QtProperty*,QStringList)));
+ connect(sizePolicyPropertyManager, SIGNAL(propertyInserted(QtProperty*,QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyInserted(QtProperty*,QtProperty*,QtProperty*)));
+ connect(sizePolicyPropertyManager, SIGNAL(propertyRemoved(QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*)));
+ // FontPropertyManager
+ QtFontPropertyManager *fontPropertyManager = new QtFontPropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::Font] = fontPropertyManager;
+ d_ptr->m_typeToValueType[QVariant::Font] = QVariant::Font;
+ connect(fontPropertyManager, SIGNAL(valueChanged(QtProperty*,QFont)),
+ this, SLOT(slotValueChanged(QtProperty*,QFont)));
+ connect(fontPropertyManager->subIntPropertyManager(), SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotValueChanged(QtProperty*,int)));
+ connect(fontPropertyManager->subIntPropertyManager(), SIGNAL(rangeChanged(QtProperty*,int,int)),
+ this, SLOT(slotRangeChanged(QtProperty*,int,int)));
+ connect(fontPropertyManager->subEnumPropertyManager(), SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotValueChanged(QtProperty*,int)));
+ connect(fontPropertyManager->subEnumPropertyManager(),
+ SIGNAL(enumNamesChanged(QtProperty*,QStringList)),
+ this, SLOT(slotEnumNamesChanged(QtProperty*,QStringList)));
+ connect(fontPropertyManager->subBoolPropertyManager(), SIGNAL(valueChanged(QtProperty*,bool)),
+ this, SLOT(slotValueChanged(QtProperty*,bool)));
+ connect(fontPropertyManager, SIGNAL(propertyInserted(QtProperty*,QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyInserted(QtProperty*,QtProperty*,QtProperty*)));
+ connect(fontPropertyManager, SIGNAL(propertyRemoved(QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*)));
+ // CursorPropertyManager
+ QtCursorPropertyManager *cursorPropertyManager = new QtCursorPropertyManager(this);
+ d_ptr->m_typeToPropertyManager[QVariant::Cursor] = cursorPropertyManager;
+ d_ptr->m_typeToValueType[QVariant::Cursor] = QVariant::Cursor;
+ connect(cursorPropertyManager, SIGNAL(valueChanged(QtProperty*,QCursor)),
+ this, SLOT(slotValueChanged(QtProperty*,QCursor)));
+ // FlagPropertyManager
+ int flagId = flagTypeId();
+ QtFlagPropertyManager *flagPropertyManager = new QtFlagPropertyManager(this);
+ d_ptr->m_typeToPropertyManager[flagId] = flagPropertyManager;
+ d_ptr->m_typeToValueType[flagId] = QVariant::Int;
+ d_ptr->m_typeToAttributeToAttributeType[flagId][d_ptr->m_flagNamesAttribute] =
+ QVariant::StringList;
+ connect(flagPropertyManager, SIGNAL(valueChanged(QtProperty*,int)),
+ this, SLOT(slotValueChanged(QtProperty*,int)));
+ connect(flagPropertyManager, SIGNAL(flagNamesChanged(QtProperty*,QStringList)),
+ this, SLOT(slotFlagNamesChanged(QtProperty*,QStringList)));
+ connect(flagPropertyManager->subBoolPropertyManager(), SIGNAL(valueChanged(QtProperty*,bool)),
+ this, SLOT(slotValueChanged(QtProperty*,bool)));
+ connect(flagPropertyManager, SIGNAL(propertyInserted(QtProperty*,QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyInserted(QtProperty*,QtProperty*,QtProperty*)));
+ connect(flagPropertyManager, SIGNAL(propertyRemoved(QtProperty*,QtProperty*)),
+ this, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*)));
+ // FlagPropertyManager
+ int groupId = groupTypeId();
+ QtGroupPropertyManager *groupPropertyManager = new QtGroupPropertyManager(this);
+ d_ptr->m_typeToPropertyManager[groupId] = groupPropertyManager;
+ d_ptr->m_typeToValueType[groupId] = QVariant::Invalid;
+}
+
+/*!
+ Destroys this manager, and all the properties it has created.
+*/
+QtVariantPropertyManager::~QtVariantPropertyManager()
+{
+ clear();
+}
+
+/*!
+ Returns the given \a property converted into a QtVariantProperty.
+
+ If the \a property was not created by this variant manager, the
+ function returns 0.
+
+ \sa createProperty()
+*/
+QtVariantProperty *QtVariantPropertyManager::variantProperty(const QtProperty *property) const
+{
+ const QMap<const QtProperty *, QPair<QtVariantProperty *, int> >::const_iterator it = d_ptr->m_propertyToType.constFind(property);
+ if (it == d_ptr->m_propertyToType.constEnd())
+ return 0;
+ return it.value().first;
+}
+
+/*!
+ Returns true if the given \a propertyType is supported by this
+ variant manager; otherwise false.
+
+ \sa propertyType()
+*/
+bool QtVariantPropertyManager::isPropertyTypeSupported(int propertyType) const
+{
+ if (d_ptr->m_typeToValueType.contains(propertyType))
+ return true;
+ return false;
+}
+
+/*!
+ Creates and returns a variant property of the given \a propertyType
+ with the given \a name.
+
+ If the specified \a propertyType is not supported by this variant
+ manager, this function returns 0.
+
+ Do not use the inherited
+ QtAbstractPropertyManager::addProperty() function to create a
+ variant property (that function will always return 0 since it will
+ not be clear what type the property should have).
+
+ \sa isPropertyTypeSupported()
+*/
+QtVariantProperty *QtVariantPropertyManager::addProperty(int propertyType, const QString &name)
+{
+ if (!isPropertyTypeSupported(propertyType))
+ return 0;
+
+ bool wasCreating = d_ptr->m_creatingProperty;
+ d_ptr->m_creatingProperty = true;
+ d_ptr->m_propertyType = propertyType;
+ QtProperty *property = QtAbstractPropertyManager::addProperty(name);
+ d_ptr->m_creatingProperty = wasCreating;
+ d_ptr->m_propertyType = 0;
+
+ if (!property)
+ return 0;
+
+ return variantProperty(property);
+}
+
+/*!
+ Returns the given \a property's value.
+
+ If the given \a property is not managed by this manager, this
+ function returns an invalid variant.
+
+ \sa setValue()
+*/
+QVariant QtVariantPropertyManager::value(const QtProperty *property) const
+{
+ QtProperty *internProp = propertyToWrappedProperty()->value(property, 0);
+ if (internProp == 0)
+ return QVariant();
+
+ QtAbstractPropertyManager *manager = internProp->propertyManager();
+ if (QtIntPropertyManager *intManager = qobject_cast<QtIntPropertyManager *>(manager)) {
+ return intManager->value(internProp);
+ } else if (QtDoublePropertyManager *doubleManager = qobject_cast<QtDoublePropertyManager *>(manager)) {
+ return doubleManager->value(internProp);
+ } else if (QtBoolPropertyManager *boolManager = qobject_cast<QtBoolPropertyManager *>(manager)) {
+ return boolManager->value(internProp);
+ } else if (QtStringPropertyManager *stringManager = qobject_cast<QtStringPropertyManager *>(manager)) {
+ return stringManager->value(internProp);
+ } else if (QtDatePropertyManager *dateManager = qobject_cast<QtDatePropertyManager *>(manager)) {
+ return dateManager->value(internProp);
+ } else if (QtTimePropertyManager *timeManager = qobject_cast<QtTimePropertyManager *>(manager)) {
+ return timeManager->value(internProp);
+ } else if (QtDateTimePropertyManager *dateTimeManager = qobject_cast<QtDateTimePropertyManager *>(manager)) {
+ return dateTimeManager->value(internProp);
+ } else if (QtKeySequencePropertyManager *keySequenceManager = qobject_cast<QtKeySequencePropertyManager *>(manager)) {
+ return keySequenceManager->value(internProp);
+ } else if (QtCharPropertyManager *charManager = qobject_cast<QtCharPropertyManager *>(manager)) {
+ return charManager->value(internProp);
+ } else if (QtLocalePropertyManager *localeManager = qobject_cast<QtLocalePropertyManager *>(manager)) {
+ return localeManager->value(internProp);
+ } else if (QtPointPropertyManager *pointManager = qobject_cast<QtPointPropertyManager *>(manager)) {
+ return pointManager->value(internProp);
+ } else if (QtPointFPropertyManager *pointFManager = qobject_cast<QtPointFPropertyManager *>(manager)) {
+ return pointFManager->value(internProp);
+ } else if (QtSizePropertyManager *sizeManager = qobject_cast<QtSizePropertyManager *>(manager)) {
+ return sizeManager->value(internProp);
+ } else if (QtSizeFPropertyManager *sizeFManager = qobject_cast<QtSizeFPropertyManager *>(manager)) {
+ return sizeFManager->value(internProp);
+ } else if (QtRectPropertyManager *rectManager = qobject_cast<QtRectPropertyManager *>(manager)) {
+ return rectManager->value(internProp);
+ } else if (QtRectFPropertyManager *rectFManager = qobject_cast<QtRectFPropertyManager *>(manager)) {
+ return rectFManager->value(internProp);
+ } else if (QtColorPropertyManager *colorManager = qobject_cast<QtColorPropertyManager *>(manager)) {
+ return colorManager->value(internProp);
+ } else if (QtEnumPropertyManager *enumManager = qobject_cast<QtEnumPropertyManager *>(manager)) {
+ return enumManager->value(internProp);
+ } else if (QtSizePolicyPropertyManager *sizePolicyManager =
+ qobject_cast<QtSizePolicyPropertyManager *>(manager)) {
+ return sizePolicyManager->value(internProp);
+ } else if (QtFontPropertyManager *fontManager = qobject_cast<QtFontPropertyManager *>(manager)) {
+ return fontManager->value(internProp);
+#ifndef QT_NO_CURSOR
+ } else if (QtCursorPropertyManager *cursorManager = qobject_cast<QtCursorPropertyManager *>(manager)) {
+ return cursorManager->value(internProp);
+#endif
+ } else if (QtFlagPropertyManager *flagManager = qobject_cast<QtFlagPropertyManager *>(manager)) {
+ return flagManager->value(internProp);
+ }
+ return QVariant();
+}
+
+/*!
+ Returns the given \a property's value type.
+
+ \sa propertyType()
+*/
+int QtVariantPropertyManager::valueType(const QtProperty *property) const
+{
+ int propType = propertyType(property);
+ return valueType(propType);
+}
+
+/*!
+ \overload
+
+ Returns the value type associated with the given \a propertyType.
+*/
+int QtVariantPropertyManager::valueType(int propertyType) const
+{
+ if (d_ptr->m_typeToValueType.contains(propertyType))
+ return d_ptr->m_typeToValueType[propertyType];
+ return 0;
+}
+
+/*!
+ Returns the given \a property's type.
+
+ \sa valueType()
+*/
+int QtVariantPropertyManager::propertyType(const QtProperty *property) const
+{
+ const QMap<const QtProperty *, QPair<QtVariantProperty *, int> >::const_iterator it = d_ptr->m_propertyToType.constFind(property);
+ if (it == d_ptr->m_propertyToType.constEnd())
+ return 0;
+ return it.value().second;
+}
+
+/*!
+ Returns the given \a property's value for the specified \a
+ attribute
+
+ If the given \a property was not created by \e this manager, or if
+ the specified \a attribute does not exist, this function returns
+ an invalid variant.
+
+ \sa attributes(), attributeType(), setAttribute()
+*/
+QVariant QtVariantPropertyManager::attributeValue(const QtProperty *property, const QString &attribute) const
+{
+ int propType = propertyType(property);
+ if (!propType)
+ return QVariant();
+
+ QMap<int, QMap<QString, int> >::ConstIterator it =
+ d_ptr->m_typeToAttributeToAttributeType.find(propType);
+ if (it == d_ptr->m_typeToAttributeToAttributeType.constEnd())
+ return QVariant();
+
+ QMap<QString, int> attributes = it.value();
+ QMap<QString, int>::ConstIterator itAttr = attributes.find(attribute);
+ if (itAttr == attributes.constEnd())
+ return QVariant();
+
+ QtProperty *internProp = propertyToWrappedProperty()->value(property, 0);
+ if (internProp == 0)
+ return QVariant();
+
+ QtAbstractPropertyManager *manager = internProp->propertyManager();
+ if (QtIntPropertyManager *intManager = qobject_cast<QtIntPropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_maximumAttribute)
+ return intManager->maximum(internProp);
+ if (attribute == d_ptr->m_minimumAttribute)
+ return intManager->minimum(internProp);
+ if (attribute == d_ptr->m_singleStepAttribute)
+ return intManager->singleStep(internProp);
+ return QVariant();
+ } else if (QtDoublePropertyManager *doubleManager = qobject_cast<QtDoublePropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_maximumAttribute)
+ return doubleManager->maximum(internProp);
+ if (attribute == d_ptr->m_minimumAttribute)
+ return doubleManager->minimum(internProp);
+ if (attribute == d_ptr->m_singleStepAttribute)
+ return doubleManager->singleStep(internProp);
+ if (attribute == d_ptr->m_decimalsAttribute)
+ return doubleManager->decimals(internProp);
+ return QVariant();
+ } else if (QtStringPropertyManager *stringManager = qobject_cast<QtStringPropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_regExpAttribute)
+ return stringManager->regExp(internProp);
+ return QVariant();
+ } else if (QtDatePropertyManager *dateManager = qobject_cast<QtDatePropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_maximumAttribute)
+ return dateManager->maximum(internProp);
+ if (attribute == d_ptr->m_minimumAttribute)
+ return dateManager->minimum(internProp);
+ return QVariant();
+ } else if (QtPointFPropertyManager *pointFManager = qobject_cast<QtPointFPropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_decimalsAttribute)
+ return pointFManager->decimals(internProp);
+ return QVariant();
+ } else if (QtSizePropertyManager *sizeManager = qobject_cast<QtSizePropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_maximumAttribute)
+ return sizeManager->maximum(internProp);
+ if (attribute == d_ptr->m_minimumAttribute)
+ return sizeManager->minimum(internProp);
+ return QVariant();
+ } else if (QtSizeFPropertyManager *sizeFManager = qobject_cast<QtSizeFPropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_maximumAttribute)
+ return sizeFManager->maximum(internProp);
+ if (attribute == d_ptr->m_minimumAttribute)
+ return sizeFManager->minimum(internProp);
+ if (attribute == d_ptr->m_decimalsAttribute)
+ return sizeFManager->decimals(internProp);
+ return QVariant();
+ } else if (QtRectPropertyManager *rectManager = qobject_cast<QtRectPropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_constraintAttribute)
+ return rectManager->constraint(internProp);
+ return QVariant();
+ } else if (QtRectFPropertyManager *rectFManager = qobject_cast<QtRectFPropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_constraintAttribute)
+ return rectFManager->constraint(internProp);
+ if (attribute == d_ptr->m_decimalsAttribute)
+ return rectFManager->decimals(internProp);
+ return QVariant();
+ } else if (QtEnumPropertyManager *enumManager = qobject_cast<QtEnumPropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_enumNamesAttribute)
+ return enumManager->enumNames(internProp);
+ if (attribute == d_ptr->m_enumIconsAttribute) {
+ QVariant v;
+ v.setValue(enumManager->enumIcons(internProp));
+ return v;
+ }
+ return QVariant();
+ } else if (QtFlagPropertyManager *flagManager = qobject_cast<QtFlagPropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_flagNamesAttribute)
+ return flagManager->flagNames(internProp);
+ return QVariant();
+ }
+ return QVariant();
+}
+
+/*!
+ Returns a list of the given \a propertyType 's attributes.
+
+ \sa attributeValue(), attributeType()
+*/
+QStringList QtVariantPropertyManager::attributes(int propertyType) const
+{
+ QMap<int, QMap<QString, int> >::ConstIterator it =
+ d_ptr->m_typeToAttributeToAttributeType.find(propertyType);
+ if (it == d_ptr->m_typeToAttributeToAttributeType.constEnd())
+ return QStringList();
+ return it.value().keys();
+}
+
+/*!
+ Returns the type of the specified \a attribute of the given \a
+ propertyType.
+
+ If the given \a propertyType is not supported by \e this manager,
+ or if the given \a propertyType does not possess the specified \a
+ attribute, this function returns QVariant::Invalid.
+
+ \sa attributes(), valueType()
+*/
+int QtVariantPropertyManager::attributeType(int propertyType, const QString &attribute) const
+{
+ QMap<int, QMap<QString, int> >::ConstIterator it =
+ d_ptr->m_typeToAttributeToAttributeType.find(propertyType);
+ if (it == d_ptr->m_typeToAttributeToAttributeType.constEnd())
+ return 0;
+
+ QMap<QString, int> attributes = it.value();
+ QMap<QString, int>::ConstIterator itAttr = attributes.find(attribute);
+ if (itAttr == attributes.constEnd())
+ return 0;
+ return itAttr.value();
+}
+
+/*!
+ \fn void QtVariantPropertyManager::setValue(QtProperty *property, const QVariant &value)
+
+ Sets the value of the given \a property to \a value.
+
+ The specified \a value must be of a type returned by valueType(),
+ or of type that can be converted to valueType() using the
+ QVariant::canConvert() function, otherwise this function does
+ nothing.
+
+ \sa value(), QtVariantProperty::setValue(), valueChanged()
+*/
+void QtVariantPropertyManager::setValue(QtProperty *property, const QVariant &val)
+{
+ int propType = val.userType();
+ if (!propType)
+ return;
+
+ int valType = valueType(property);
+
+ if (propType != valType && !val.canConvert(static_cast<QVariant::Type>(valType)))
+ return;
+
+ QtProperty *internProp = propertyToWrappedProperty()->value(property, 0);
+ if (internProp == 0)
+ return;
+
+
+ QtAbstractPropertyManager *manager = internProp->propertyManager();
+ if (QtIntPropertyManager *intManager = qobject_cast<QtIntPropertyManager *>(manager)) {
+ intManager->setValue(internProp, qvariant_cast<int>(val));
+ return;
+ } else if (QtDoublePropertyManager *doubleManager = qobject_cast<QtDoublePropertyManager *>(manager)) {
+ doubleManager->setValue(internProp, qvariant_cast<double>(val));
+ return;
+ } else if (QtBoolPropertyManager *boolManager = qobject_cast<QtBoolPropertyManager *>(manager)) {
+ boolManager->setValue(internProp, qvariant_cast<bool>(val));
+ return;
+ } else if (QtStringPropertyManager *stringManager = qobject_cast<QtStringPropertyManager *>(manager)) {
+ stringManager->setValue(internProp, qvariant_cast<QString>(val));
+ return;
+ } else if (QtDatePropertyManager *dateManager = qobject_cast<QtDatePropertyManager *>(manager)) {
+ dateManager->setValue(internProp, qvariant_cast<QDate>(val));
+ return;
+ } else if (QtTimePropertyManager *timeManager = qobject_cast<QtTimePropertyManager *>(manager)) {
+ timeManager->setValue(internProp, qvariant_cast<QTime>(val));
+ return;
+ } else if (QtDateTimePropertyManager *dateTimeManager = qobject_cast<QtDateTimePropertyManager *>(manager)) {
+ dateTimeManager->setValue(internProp, qvariant_cast<QDateTime>(val));
+ return;
+ } else if (QtKeySequencePropertyManager *keySequenceManager = qobject_cast<QtKeySequencePropertyManager *>(manager)) {
+ keySequenceManager->setValue(internProp, qvariant_cast<QKeySequence>(val));
+ return;
+ } else if (QtCharPropertyManager *charManager = qobject_cast<QtCharPropertyManager *>(manager)) {
+ charManager->setValue(internProp, qvariant_cast<QChar>(val));
+ return;
+ } else if (QtLocalePropertyManager *localeManager = qobject_cast<QtLocalePropertyManager *>(manager)) {
+ localeManager->setValue(internProp, qvariant_cast<QLocale>(val));
+ return;
+ } else if (QtPointPropertyManager *pointManager = qobject_cast<QtPointPropertyManager *>(manager)) {
+ pointManager->setValue(internProp, qvariant_cast<QPoint>(val));
+ return;
+ } else if (QtPointFPropertyManager *pointFManager = qobject_cast<QtPointFPropertyManager *>(manager)) {
+ pointFManager->setValue(internProp, qvariant_cast<QPointF>(val));
+ return;
+ } else if (QtSizePropertyManager *sizeManager = qobject_cast<QtSizePropertyManager *>(manager)) {
+ sizeManager->setValue(internProp, qvariant_cast<QSize>(val));
+ return;
+ } else if (QtSizeFPropertyManager *sizeFManager = qobject_cast<QtSizeFPropertyManager *>(manager)) {
+ sizeFManager->setValue(internProp, qvariant_cast<QSizeF>(val));
+ return;
+ } else if (QtRectPropertyManager *rectManager = qobject_cast<QtRectPropertyManager *>(manager)) {
+ rectManager->setValue(internProp, qvariant_cast<QRect>(val));
+ return;
+ } else if (QtRectFPropertyManager *rectFManager = qobject_cast<QtRectFPropertyManager *>(manager)) {
+ rectFManager->setValue(internProp, qvariant_cast<QRectF>(val));
+ return;
+ } else if (QtColorPropertyManager *colorManager = qobject_cast<QtColorPropertyManager *>(manager)) {
+ colorManager->setValue(internProp, qvariant_cast<QColor>(val));
+ return;
+ } else if (QtEnumPropertyManager *enumManager = qobject_cast<QtEnumPropertyManager *>(manager)) {
+ enumManager->setValue(internProp, qvariant_cast<int>(val));
+ return;
+ } else if (QtSizePolicyPropertyManager *sizePolicyManager =
+ qobject_cast<QtSizePolicyPropertyManager *>(manager)) {
+ sizePolicyManager->setValue(internProp, qvariant_cast<QSizePolicy>(val));
+ return;
+ } else if (QtFontPropertyManager *fontManager = qobject_cast<QtFontPropertyManager *>(manager)) {
+ fontManager->setValue(internProp, qvariant_cast<QFont>(val));
+ return;
+#ifndef QT_NO_CURSOR
+ } else if (QtCursorPropertyManager *cursorManager = qobject_cast<QtCursorPropertyManager *>(manager)) {
+ cursorManager->setValue(internProp, qvariant_cast<QCursor>(val));
+ return;
+#endif
+ } else if (QtFlagPropertyManager *flagManager = qobject_cast<QtFlagPropertyManager *>(manager)) {
+ flagManager->setValue(internProp, qvariant_cast<int>(val));
+ return;
+ }
+}
+
+/*!
+ Sets the value of the specified \a attribute of the given \a
+ property, to \a value.
+
+ The new \a value's type must be of the type returned by
+ attributeType(), or of a type that can be converted to
+ attributeType() using the QVariant::canConvert() function,
+ otherwise this function does nothing.
+
+ \sa attributeValue(), QtVariantProperty::setAttribute(), attributeChanged()
+*/
+void QtVariantPropertyManager::setAttribute(QtProperty *property,
+ const QString &attribute, const QVariant &value)
+{
+ QVariant oldAttr = attributeValue(property, attribute);
+ if (!oldAttr.isValid())
+ return;
+
+ int attrType = value.userType();
+ if (!attrType)
+ return;
+
+ if (attrType != attributeType(propertyType(property), attribute) &&
+ !value.canConvert((QVariant::Type)attrType))
+ return;
+
+ QtProperty *internProp = propertyToWrappedProperty()->value(property, 0);
+ if (internProp == 0)
+ return;
+
+ QtAbstractPropertyManager *manager = internProp->propertyManager();
+ if (QtIntPropertyManager *intManager = qobject_cast<QtIntPropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_maximumAttribute)
+ intManager->setMaximum(internProp, qvariant_cast<int>(value));
+ else if (attribute == d_ptr->m_minimumAttribute)
+ intManager->setMinimum(internProp, qvariant_cast<int>(value));
+ else if (attribute == d_ptr->m_singleStepAttribute)
+ intManager->setSingleStep(internProp, qvariant_cast<int>(value));
+ return;
+ } else if (QtDoublePropertyManager *doubleManager = qobject_cast<QtDoublePropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_maximumAttribute)
+ doubleManager->setMaximum(internProp, qvariant_cast<double>(value));
+ if (attribute == d_ptr->m_minimumAttribute)
+ doubleManager->setMinimum(internProp, qvariant_cast<double>(value));
+ if (attribute == d_ptr->m_singleStepAttribute)
+ doubleManager->setSingleStep(internProp, qvariant_cast<double>(value));
+ if (attribute == d_ptr->m_decimalsAttribute)
+ doubleManager->setDecimals(internProp, qvariant_cast<int>(value));
+ return;
+ } else if (QtStringPropertyManager *stringManager = qobject_cast<QtStringPropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_regExpAttribute)
+ stringManager->setRegExp(internProp, qvariant_cast<QRegExp>(value));
+ return;
+ } else if (QtDatePropertyManager *dateManager = qobject_cast<QtDatePropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_maximumAttribute)
+ dateManager->setMaximum(internProp, qvariant_cast<QDate>(value));
+ if (attribute == d_ptr->m_minimumAttribute)
+ dateManager->setMinimum(internProp, qvariant_cast<QDate>(value));
+ return;
+ } else if (QtPointFPropertyManager *pointFManager = qobject_cast<QtPointFPropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_decimalsAttribute)
+ pointFManager->setDecimals(internProp, qvariant_cast<int>(value));
+ return;
+ } else if (QtSizePropertyManager *sizeManager = qobject_cast<QtSizePropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_maximumAttribute)
+ sizeManager->setMaximum(internProp, qvariant_cast<QSize>(value));
+ if (attribute == d_ptr->m_minimumAttribute)
+ sizeManager->setMinimum(internProp, qvariant_cast<QSize>(value));
+ return;
+ } else if (QtSizeFPropertyManager *sizeFManager = qobject_cast<QtSizeFPropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_maximumAttribute)
+ sizeFManager->setMaximum(internProp, qvariant_cast<QSizeF>(value));
+ if (attribute == d_ptr->m_minimumAttribute)
+ sizeFManager->setMinimum(internProp, qvariant_cast<QSizeF>(value));
+ if (attribute == d_ptr->m_decimalsAttribute)
+ sizeFManager->setDecimals(internProp, qvariant_cast<int>(value));
+ return;
+ } else if (QtRectPropertyManager *rectManager = qobject_cast<QtRectPropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_constraintAttribute)
+ rectManager->setConstraint(internProp, qvariant_cast<QRect>(value));
+ return;
+ } else if (QtRectFPropertyManager *rectFManager = qobject_cast<QtRectFPropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_constraintAttribute)
+ rectFManager->setConstraint(internProp, qvariant_cast<QRectF>(value));
+ if (attribute == d_ptr->m_decimalsAttribute)
+ rectFManager->setDecimals(internProp, qvariant_cast<int>(value));
+ return;
+ } else if (QtEnumPropertyManager *enumManager = qobject_cast<QtEnumPropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_enumNamesAttribute)
+ enumManager->setEnumNames(internProp, qvariant_cast<QStringList>(value));
+ if (attribute == d_ptr->m_enumIconsAttribute)
+ enumManager->setEnumIcons(internProp, qvariant_cast<QtIconMap>(value));
+ return;
+ } else if (QtFlagPropertyManager *flagManager = qobject_cast<QtFlagPropertyManager *>(manager)) {
+ if (attribute == d_ptr->m_flagNamesAttribute)
+ flagManager->setFlagNames(internProp, qvariant_cast<QStringList>(value));
+ return;
+ }
+}
+
+/*!
+ \reimp
+*/
+bool QtVariantPropertyManager::hasValue(const QtProperty *property) const
+{
+ if (propertyType(property) == groupTypeId())
+ return false;
+ return true;
+}
+
+/*!
+ \reimp
+*/
+QString QtVariantPropertyManager::valueText(const QtProperty *property) const
+{
+ const QtProperty *internProp = propertyToWrappedProperty()->value(property, 0);
+ return internProp ? internProp->valueText() : QString();
+}
+
+/*!
+ \reimp
+*/
+QIcon QtVariantPropertyManager::valueIcon(const QtProperty *property) const
+{
+ const QtProperty *internProp = propertyToWrappedProperty()->value(property, 0);
+ return internProp ? internProp->valueIcon() : QIcon();
+}
+
+/*!
+ \reimp
+*/
+void QtVariantPropertyManager::initializeProperty(QtProperty *property)
+{
+ QtVariantProperty *varProp = variantProperty(property);
+ if (!varProp)
+ return;
+
+ QMap<int, QtAbstractPropertyManager *>::ConstIterator it =
+ d_ptr->m_typeToPropertyManager.find(d_ptr->m_propertyType);
+ if (it != d_ptr->m_typeToPropertyManager.constEnd()) {
+ QtProperty *internProp = 0;
+ if (!d_ptr->m_creatingSubProperties) {
+ QtAbstractPropertyManager *manager = it.value();
+ internProp = manager->addProperty();
+ d_ptr->m_internalToProperty[internProp] = varProp;
+ }
+ propertyToWrappedProperty()->insert(varProp, internProp);
+ if (internProp) {
+ QList<QtProperty *> children = internProp->subProperties();
+ QListIterator<QtProperty *> itChild(children);
+ QtVariantProperty *lastProperty = 0;
+ while (itChild.hasNext()) {
+ QtVariantProperty *prop = d_ptr->createSubProperty(varProp, lastProperty, itChild.next());
+ lastProperty = prop ? prop : lastProperty;
+ }
+ }
+ }
+}
+
+/*!
+ \reimp
+*/
+void QtVariantPropertyManager::uninitializeProperty(QtProperty *property)
+{
+ const QMap<const QtProperty *, QPair<QtVariantProperty *, int> >::iterator type_it = d_ptr->m_propertyToType.find(property);
+ if (type_it == d_ptr->m_propertyToType.end())
+ return;
+
+ PropertyMap::iterator it = propertyToWrappedProperty()->find(property);
+ if (it != propertyToWrappedProperty()->end()) {
+ QtProperty *internProp = it.value();
+ if (internProp) {
+ d_ptr->m_internalToProperty.remove(internProp);
+ if (!d_ptr->m_destroyingSubProperties) {
+ delete internProp;
+ }
+ }
+ propertyToWrappedProperty()->erase(it);
+ }
+ d_ptr->m_propertyToType.erase(type_it);
+}
+
+/*!
+ \reimp
+*/
+QtProperty *QtVariantPropertyManager::createProperty()
+{
+ if (!d_ptr->m_creatingProperty)
+ return 0;
+
+ QtVariantProperty *property = new QtVariantProperty(this);
+ d_ptr->m_propertyToType.insert(property, qMakePair(property, d_ptr->m_propertyType));
+
+ return property;
+}
+
+/////////////////////////////
+
+class QtVariantEditorFactoryPrivate
+{
+ QtVariantEditorFactory *q_ptr;
+ Q_DECLARE_PUBLIC(QtVariantEditorFactory)
+public:
+
+ QtSpinBoxFactory *m_spinBoxFactory;
+ QtDoubleSpinBoxFactory *m_doubleSpinBoxFactory;
+ QtCheckBoxFactory *m_checkBoxFactory;
+ QtLineEditFactory *m_lineEditFactory;
+ QtDateEditFactory *m_dateEditFactory;
+ QtTimeEditFactory *m_timeEditFactory;
+ QtDateTimeEditFactory *m_dateTimeEditFactory;
+ QtKeySequenceEditorFactory *m_keySequenceEditorFactory;
+ QtCharEditorFactory *m_charEditorFactory;
+ QtEnumEditorFactory *m_comboBoxFactory;
+ QtCursorEditorFactory *m_cursorEditorFactory;
+ QtColorEditorFactory *m_colorEditorFactory;
+ QtFontEditorFactory *m_fontEditorFactory;
+
+ QMap<QtAbstractEditorFactoryBase *, int> m_factoryToType;
+ QMap<int, QtAbstractEditorFactoryBase *> m_typeToFactory;
+};
+
+/*!
+ \class QtVariantEditorFactory
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtVariantEditorFactory class provides widgets for properties
+ created by QtVariantPropertyManager objects.
+
+ The variant factory provides the following widgets for the
+ specified property types:
+
+ \table
+ \header
+ \o Property Type
+ \o Widget
+ \row
+ \o \c int
+ \o QSpinBox
+ \row
+ \o \c double
+ \o QDoubleSpinBox
+ \row
+ \o \c bool
+ \o QCheckBox
+ \row
+ \o QString
+ \o QLineEdit
+ \row
+ \o QDate
+ \o QDateEdit
+ \row
+ \o QTime
+ \o QTimeEdit
+ \row
+ \o QDateTime
+ \o QDateTimeEdit
+ \row
+ \o QKeySequence
+ \o customized editor
+ \row
+ \o QChar
+ \o customized editor
+ \row
+ \o \c enum
+ \o QComboBox
+ \row
+ \o QCursor
+ \o QComboBox
+ \endtable
+
+ Note that QtVariantPropertyManager supports several additional property
+ types for which the QtVariantEditorFactory class does not provide
+ editing widgets, e.g. QPoint and QSize. To provide widgets for other
+ types using the variant approach, derive from the QtVariantEditorFactory
+ class.
+
+ \sa QtAbstractEditorFactory, QtVariantPropertyManager
+*/
+
+/*!
+ Creates a factory with the given \a parent.
+*/
+QtVariantEditorFactory::QtVariantEditorFactory(QObject *parent)
+ : QtAbstractEditorFactory<QtVariantPropertyManager>(parent), d_ptr(new QtVariantEditorFactoryPrivate())
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->m_spinBoxFactory = new QtSpinBoxFactory(this);
+ d_ptr->m_factoryToType[d_ptr->m_spinBoxFactory] = QVariant::Int;
+ d_ptr->m_typeToFactory[QVariant::Int] = d_ptr->m_spinBoxFactory;
+
+ d_ptr->m_doubleSpinBoxFactory = new QtDoubleSpinBoxFactory(this);
+ d_ptr->m_factoryToType[d_ptr->m_doubleSpinBoxFactory] = QVariant::Double;
+ d_ptr->m_typeToFactory[QVariant::Double] = d_ptr->m_doubleSpinBoxFactory;
+
+ d_ptr->m_checkBoxFactory = new QtCheckBoxFactory(this);
+ d_ptr->m_factoryToType[d_ptr->m_checkBoxFactory] = QVariant::Bool;
+ d_ptr->m_typeToFactory[QVariant::Bool] = d_ptr->m_checkBoxFactory;
+
+ d_ptr->m_lineEditFactory = new QtLineEditFactory(this);
+ d_ptr->m_factoryToType[d_ptr->m_lineEditFactory] = QVariant::String;
+ d_ptr->m_typeToFactory[QVariant::String] = d_ptr->m_lineEditFactory;
+
+ d_ptr->m_dateEditFactory = new QtDateEditFactory(this);
+ d_ptr->m_factoryToType[d_ptr->m_dateEditFactory] = QVariant::Date;
+ d_ptr->m_typeToFactory[QVariant::Date] = d_ptr->m_dateEditFactory;
+
+ d_ptr->m_timeEditFactory = new QtTimeEditFactory(this);
+ d_ptr->m_factoryToType[d_ptr->m_timeEditFactory] = QVariant::Time;
+ d_ptr->m_typeToFactory[QVariant::Time] = d_ptr->m_timeEditFactory;
+
+ d_ptr->m_dateTimeEditFactory = new QtDateTimeEditFactory(this);
+ d_ptr->m_factoryToType[d_ptr->m_dateTimeEditFactory] = QVariant::DateTime;
+ d_ptr->m_typeToFactory[QVariant::DateTime] = d_ptr->m_dateTimeEditFactory;
+
+ d_ptr->m_keySequenceEditorFactory = new QtKeySequenceEditorFactory(this);
+ d_ptr->m_factoryToType[d_ptr->m_keySequenceEditorFactory] = QVariant::KeySequence;
+ d_ptr->m_typeToFactory[QVariant::KeySequence] = d_ptr->m_keySequenceEditorFactory;
+
+ d_ptr->m_charEditorFactory = new QtCharEditorFactory(this);
+ d_ptr->m_factoryToType[d_ptr->m_charEditorFactory] = QVariant::Char;
+ d_ptr->m_typeToFactory[QVariant::Char] = d_ptr->m_charEditorFactory;
+
+ d_ptr->m_cursorEditorFactory = new QtCursorEditorFactory(this);
+ d_ptr->m_factoryToType[d_ptr->m_cursorEditorFactory] = QVariant::Cursor;
+ d_ptr->m_typeToFactory[QVariant::Cursor] = d_ptr->m_cursorEditorFactory;
+
+ d_ptr->m_colorEditorFactory = new QtColorEditorFactory(this);
+ d_ptr->m_factoryToType[d_ptr->m_colorEditorFactory] = QVariant::Color;
+ d_ptr->m_typeToFactory[QVariant::Color] = d_ptr->m_colorEditorFactory;
+
+ d_ptr->m_fontEditorFactory = new QtFontEditorFactory(this);
+ d_ptr->m_factoryToType[d_ptr->m_fontEditorFactory] = QVariant::Font;
+ d_ptr->m_typeToFactory[QVariant::Font] = d_ptr->m_fontEditorFactory;
+
+ d_ptr->m_comboBoxFactory = new QtEnumEditorFactory(this);
+ const int enumId = QtVariantPropertyManager::enumTypeId();
+ d_ptr->m_factoryToType[d_ptr->m_comboBoxFactory] = enumId;
+ d_ptr->m_typeToFactory[enumId] = d_ptr->m_comboBoxFactory;
+}
+
+/*!
+ Destroys this factory, and all the widgets it has created.
+*/
+QtVariantEditorFactory::~QtVariantEditorFactory()
+{
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtVariantEditorFactory::connectPropertyManager(QtVariantPropertyManager *manager)
+{
+ QList<QtIntPropertyManager *> intPropertyManagers = manager->findChildren<QtIntPropertyManager *>();
+ QListIterator<QtIntPropertyManager *> itInt(intPropertyManagers);
+ while (itInt.hasNext())
+ d_ptr->m_spinBoxFactory->addPropertyManager(itInt.next());
+
+ QList<QtDoublePropertyManager *> doublePropertyManagers = manager->findChildren<QtDoublePropertyManager *>();
+ QListIterator<QtDoublePropertyManager *> itDouble(doublePropertyManagers);
+ while (itDouble.hasNext())
+ d_ptr->m_doubleSpinBoxFactory->addPropertyManager(itDouble.next());
+
+ QList<QtBoolPropertyManager *> boolPropertyManagers = manager->findChildren<QtBoolPropertyManager *>();
+ QListIterator<QtBoolPropertyManager *> itBool(boolPropertyManagers);
+ while (itBool.hasNext())
+ d_ptr->m_checkBoxFactory->addPropertyManager(itBool.next());
+
+ QList<QtStringPropertyManager *> stringPropertyManagers = manager->findChildren<QtStringPropertyManager *>();
+ QListIterator<QtStringPropertyManager *> itString(stringPropertyManagers);
+ while (itString.hasNext())
+ d_ptr->m_lineEditFactory->addPropertyManager(itString.next());
+
+ QList<QtDatePropertyManager *> datePropertyManagers = manager->findChildren<QtDatePropertyManager *>();
+ QListIterator<QtDatePropertyManager *> itDate(datePropertyManagers);
+ while (itDate.hasNext())
+ d_ptr->m_dateEditFactory->addPropertyManager(itDate.next());
+
+ QList<QtTimePropertyManager *> timePropertyManagers = manager->findChildren<QtTimePropertyManager *>();
+ QListIterator<QtTimePropertyManager *> itTime(timePropertyManagers);
+ while (itTime.hasNext())
+ d_ptr->m_timeEditFactory->addPropertyManager(itTime.next());
+
+ QList<QtDateTimePropertyManager *> dateTimePropertyManagers = manager->findChildren<QtDateTimePropertyManager *>();
+ QListIterator<QtDateTimePropertyManager *> itDateTime(dateTimePropertyManagers);
+ while (itDateTime.hasNext())
+ d_ptr->m_dateTimeEditFactory->addPropertyManager(itDateTime.next());
+
+ QList<QtKeySequencePropertyManager *> keySequencePropertyManagers = manager->findChildren<QtKeySequencePropertyManager *>();
+ QListIterator<QtKeySequencePropertyManager *> itKeySequence(keySequencePropertyManagers);
+ while (itKeySequence.hasNext())
+ d_ptr->m_keySequenceEditorFactory->addPropertyManager(itKeySequence.next());
+
+ QList<QtCharPropertyManager *> charPropertyManagers = manager->findChildren<QtCharPropertyManager *>();
+ QListIterator<QtCharPropertyManager *> itChar(charPropertyManagers);
+ while (itChar.hasNext())
+ d_ptr->m_charEditorFactory->addPropertyManager(itChar.next());
+
+ QList<QtLocalePropertyManager *> localePropertyManagers = manager->findChildren<QtLocalePropertyManager *>();
+ QListIterator<QtLocalePropertyManager *> itLocale(localePropertyManagers);
+ while (itLocale.hasNext())
+ d_ptr->m_comboBoxFactory->addPropertyManager(itLocale.next()->subEnumPropertyManager());
+
+ QList<QtPointPropertyManager *> pointPropertyManagers = manager->findChildren<QtPointPropertyManager *>();
+ QListIterator<QtPointPropertyManager *> itPoint(pointPropertyManagers);
+ while (itPoint.hasNext())
+ d_ptr->m_spinBoxFactory->addPropertyManager(itPoint.next()->subIntPropertyManager());
+
+ QList<QtPointFPropertyManager *> pointFPropertyManagers = manager->findChildren<QtPointFPropertyManager *>();
+ QListIterator<QtPointFPropertyManager *> itPointF(pointFPropertyManagers);
+ while (itPointF.hasNext())
+ d_ptr->m_doubleSpinBoxFactory->addPropertyManager(itPointF.next()->subDoublePropertyManager());
+
+ QList<QtSizePropertyManager *> sizePropertyManagers = manager->findChildren<QtSizePropertyManager *>();
+ QListIterator<QtSizePropertyManager *> itSize(sizePropertyManagers);
+ while (itSize.hasNext())
+ d_ptr->m_spinBoxFactory->addPropertyManager(itSize.next()->subIntPropertyManager());
+
+ QList<QtSizeFPropertyManager *> sizeFPropertyManagers = manager->findChildren<QtSizeFPropertyManager *>();
+ QListIterator<QtSizeFPropertyManager *> itSizeF(sizeFPropertyManagers);
+ while (itSizeF.hasNext())
+ d_ptr->m_doubleSpinBoxFactory->addPropertyManager(itSizeF.next()->subDoublePropertyManager());
+
+ QList<QtRectPropertyManager *> rectPropertyManagers = manager->findChildren<QtRectPropertyManager *>();
+ QListIterator<QtRectPropertyManager *> itRect(rectPropertyManagers);
+ while (itRect.hasNext())
+ d_ptr->m_spinBoxFactory->addPropertyManager(itRect.next()->subIntPropertyManager());
+
+ QList<QtRectFPropertyManager *> rectFPropertyManagers = manager->findChildren<QtRectFPropertyManager *>();
+ QListIterator<QtRectFPropertyManager *> itRectF(rectFPropertyManagers);
+ while (itRectF.hasNext())
+ d_ptr->m_doubleSpinBoxFactory->addPropertyManager(itRectF.next()->subDoublePropertyManager());
+
+ QList<QtColorPropertyManager *> colorPropertyManagers = manager->findChildren<QtColorPropertyManager *>();
+ QListIterator<QtColorPropertyManager *> itColor(colorPropertyManagers);
+ while (itColor.hasNext()) {
+ QtColorPropertyManager *manager = itColor.next();
+ d_ptr->m_colorEditorFactory->addPropertyManager(manager);
+ d_ptr->m_spinBoxFactory->addPropertyManager(manager->subIntPropertyManager());
+ }
+
+ QList<QtEnumPropertyManager *> enumPropertyManagers = manager->findChildren<QtEnumPropertyManager *>();
+ QListIterator<QtEnumPropertyManager *> itEnum(enumPropertyManagers);
+ while (itEnum.hasNext())
+ d_ptr->m_comboBoxFactory->addPropertyManager(itEnum.next());
+
+ QList<QtSizePolicyPropertyManager *> sizePolicyPropertyManagers = manager->findChildren<QtSizePolicyPropertyManager *>();
+ QListIterator<QtSizePolicyPropertyManager *> itSizePolicy(sizePolicyPropertyManagers);
+ while (itSizePolicy.hasNext()) {
+ QtSizePolicyPropertyManager *manager = itSizePolicy.next();
+ d_ptr->m_spinBoxFactory->addPropertyManager(manager->subIntPropertyManager());
+ d_ptr->m_comboBoxFactory->addPropertyManager(manager->subEnumPropertyManager());
+ }
+
+ QList<QtFontPropertyManager *> fontPropertyManagers = manager->findChildren<QtFontPropertyManager *>();
+ QListIterator<QtFontPropertyManager *> itFont(fontPropertyManagers);
+ while (itFont.hasNext()) {
+ QtFontPropertyManager *manager = itFont.next();
+ d_ptr->m_fontEditorFactory->addPropertyManager(manager);
+ d_ptr->m_spinBoxFactory->addPropertyManager(manager->subIntPropertyManager());
+ d_ptr->m_comboBoxFactory->addPropertyManager(manager->subEnumPropertyManager());
+ d_ptr->m_checkBoxFactory->addPropertyManager(manager->subBoolPropertyManager());
+ }
+
+ QList<QtCursorPropertyManager *> cursorPropertyManagers = manager->findChildren<QtCursorPropertyManager *>();
+ QListIterator<QtCursorPropertyManager *> itCursor(cursorPropertyManagers);
+ while (itCursor.hasNext())
+ d_ptr->m_cursorEditorFactory->addPropertyManager(itCursor.next());
+
+ QList<QtFlagPropertyManager *> flagPropertyManagers = manager->findChildren<QtFlagPropertyManager *>();
+ QListIterator<QtFlagPropertyManager *> itFlag(flagPropertyManagers);
+ while (itFlag.hasNext())
+ d_ptr->m_checkBoxFactory->addPropertyManager(itFlag.next()->subBoolPropertyManager());
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+QWidget *QtVariantEditorFactory::createEditor(QtVariantPropertyManager *manager, QtProperty *property,
+ QWidget *parent)
+{
+ const int propType = manager->propertyType(property);
+ QtAbstractEditorFactoryBase *factory = d_ptr->m_typeToFactory.value(propType, 0);
+ if (!factory)
+ return 0;
+ return factory->createEditor(wrappedProperty(property), parent);
+}
+
+/*!
+ \internal
+
+ Reimplemented from the QtAbstractEditorFactory class.
+*/
+void QtVariantEditorFactory::disconnectPropertyManager(QtVariantPropertyManager *manager)
+{
+ QList<QtIntPropertyManager *> intPropertyManagers = manager->findChildren<QtIntPropertyManager *>();
+ QListIterator<QtIntPropertyManager *> itInt(intPropertyManagers);
+ while (itInt.hasNext())
+ d_ptr->m_spinBoxFactory->removePropertyManager(itInt.next());
+
+ QList<QtDoublePropertyManager *> doublePropertyManagers = manager->findChildren<QtDoublePropertyManager *>();
+ QListIterator<QtDoublePropertyManager *> itDouble(doublePropertyManagers);
+ while (itDouble.hasNext())
+ d_ptr->m_doubleSpinBoxFactory->removePropertyManager(itDouble.next());
+
+ QList<QtBoolPropertyManager *> boolPropertyManagers = manager->findChildren<QtBoolPropertyManager *>();
+ QListIterator<QtBoolPropertyManager *> itBool(boolPropertyManagers);
+ while (itBool.hasNext())
+ d_ptr->m_checkBoxFactory->removePropertyManager(itBool.next());
+
+ QList<QtStringPropertyManager *> stringPropertyManagers = manager->findChildren<QtStringPropertyManager *>();
+ QListIterator<QtStringPropertyManager *> itString(stringPropertyManagers);
+ while (itString.hasNext())
+ d_ptr->m_lineEditFactory->removePropertyManager(itString.next());
+
+ QList<QtDatePropertyManager *> datePropertyManagers = manager->findChildren<QtDatePropertyManager *>();
+ QListIterator<QtDatePropertyManager *> itDate(datePropertyManagers);
+ while (itDate.hasNext())
+ d_ptr->m_dateEditFactory->removePropertyManager(itDate.next());
+
+ QList<QtTimePropertyManager *> timePropertyManagers = manager->findChildren<QtTimePropertyManager *>();
+ QListIterator<QtTimePropertyManager *> itTime(timePropertyManagers);
+ while (itTime.hasNext())
+ d_ptr->m_timeEditFactory->removePropertyManager(itTime.next());
+
+ QList<QtDateTimePropertyManager *> dateTimePropertyManagers = manager->findChildren<QtDateTimePropertyManager *>();
+ QListIterator<QtDateTimePropertyManager *> itDateTime(dateTimePropertyManagers);
+ while (itDateTime.hasNext())
+ d_ptr->m_dateTimeEditFactory->removePropertyManager(itDateTime.next());
+
+ QList<QtKeySequencePropertyManager *> keySequencePropertyManagers = manager->findChildren<QtKeySequencePropertyManager *>();
+ QListIterator<QtKeySequencePropertyManager *> itKeySequence(keySequencePropertyManagers);
+ while (itKeySequence.hasNext())
+ d_ptr->m_keySequenceEditorFactory->removePropertyManager(itKeySequence.next());
+
+ QList<QtCharPropertyManager *> charPropertyManagers = manager->findChildren<QtCharPropertyManager *>();
+ QListIterator<QtCharPropertyManager *> itChar(charPropertyManagers);
+ while (itChar.hasNext())
+ d_ptr->m_charEditorFactory->removePropertyManager(itChar.next());
+
+ QList<QtLocalePropertyManager *> localePropertyManagers = manager->findChildren<QtLocalePropertyManager *>();
+ QListIterator<QtLocalePropertyManager *> itLocale(localePropertyManagers);
+ while (itLocale.hasNext())
+ d_ptr->m_comboBoxFactory->removePropertyManager(itLocale.next()->subEnumPropertyManager());
+
+ QList<QtPointPropertyManager *> pointPropertyManagers = manager->findChildren<QtPointPropertyManager *>();
+ QListIterator<QtPointPropertyManager *> itPoint(pointPropertyManagers);
+ while (itPoint.hasNext())
+ d_ptr->m_spinBoxFactory->removePropertyManager(itPoint.next()->subIntPropertyManager());
+
+ QList<QtPointFPropertyManager *> pointFPropertyManagers = manager->findChildren<QtPointFPropertyManager *>();
+ QListIterator<QtPointFPropertyManager *> itPointF(pointFPropertyManagers);
+ while (itPointF.hasNext())
+ d_ptr->m_doubleSpinBoxFactory->removePropertyManager(itPointF.next()->subDoublePropertyManager());
+
+ QList<QtSizePropertyManager *> sizePropertyManagers = manager->findChildren<QtSizePropertyManager *>();
+ QListIterator<QtSizePropertyManager *> itSize(sizePropertyManagers);
+ while (itSize.hasNext())
+ d_ptr->m_spinBoxFactory->removePropertyManager(itSize.next()->subIntPropertyManager());
+
+ QList<QtSizeFPropertyManager *> sizeFPropertyManagers = manager->findChildren<QtSizeFPropertyManager *>();
+ QListIterator<QtSizeFPropertyManager *> itSizeF(sizeFPropertyManagers);
+ while (itSizeF.hasNext())
+ d_ptr->m_doubleSpinBoxFactory->removePropertyManager(itSizeF.next()->subDoublePropertyManager());
+
+ QList<QtRectPropertyManager *> rectPropertyManagers = manager->findChildren<QtRectPropertyManager *>();
+ QListIterator<QtRectPropertyManager *> itRect(rectPropertyManagers);
+ while (itRect.hasNext())
+ d_ptr->m_spinBoxFactory->removePropertyManager(itRect.next()->subIntPropertyManager());
+
+ QList<QtRectFPropertyManager *> rectFPropertyManagers = manager->findChildren<QtRectFPropertyManager *>();
+ QListIterator<QtRectFPropertyManager *> itRectF(rectFPropertyManagers);
+ while (itRectF.hasNext())
+ d_ptr->m_doubleSpinBoxFactory->removePropertyManager(itRectF.next()->subDoublePropertyManager());
+
+ QList<QtColorPropertyManager *> colorPropertyManagers = manager->findChildren<QtColorPropertyManager *>();
+ QListIterator<QtColorPropertyManager *> itColor(colorPropertyManagers);
+ while (itColor.hasNext()) {
+ QtColorPropertyManager *manager = itColor.next();
+ d_ptr->m_colorEditorFactory->removePropertyManager(manager);
+ d_ptr->m_spinBoxFactory->removePropertyManager(manager->subIntPropertyManager());
+ }
+
+ QList<QtEnumPropertyManager *> enumPropertyManagers = manager->findChildren<QtEnumPropertyManager *>();
+ QListIterator<QtEnumPropertyManager *> itEnum(enumPropertyManagers);
+ while (itEnum.hasNext())
+ d_ptr->m_comboBoxFactory->removePropertyManager(itEnum.next());
+
+ QList<QtSizePolicyPropertyManager *> sizePolicyPropertyManagers = manager->findChildren<QtSizePolicyPropertyManager *>();
+ QListIterator<QtSizePolicyPropertyManager *> itSizePolicy(sizePolicyPropertyManagers);
+ while (itSizePolicy.hasNext()) {
+ QtSizePolicyPropertyManager *manager = itSizePolicy.next();
+ d_ptr->m_spinBoxFactory->removePropertyManager(manager->subIntPropertyManager());
+ d_ptr->m_comboBoxFactory->removePropertyManager(manager->subEnumPropertyManager());
+ }
+
+ QList<QtFontPropertyManager *> fontPropertyManagers = manager->findChildren<QtFontPropertyManager *>();
+ QListIterator<QtFontPropertyManager *> itFont(fontPropertyManagers);
+ while (itFont.hasNext()) {
+ QtFontPropertyManager *manager = itFont.next();
+ d_ptr->m_fontEditorFactory->removePropertyManager(manager);
+ d_ptr->m_spinBoxFactory->removePropertyManager(manager->subIntPropertyManager());
+ d_ptr->m_comboBoxFactory->removePropertyManager(manager->subEnumPropertyManager());
+ d_ptr->m_checkBoxFactory->removePropertyManager(manager->subBoolPropertyManager());
+ }
+
+ QList<QtCursorPropertyManager *> cursorPropertyManagers = manager->findChildren<QtCursorPropertyManager *>();
+ QListIterator<QtCursorPropertyManager *> itCursor(cursorPropertyManagers);
+ while (itCursor.hasNext())
+ d_ptr->m_cursorEditorFactory->removePropertyManager(itCursor.next());
+
+ QList<QtFlagPropertyManager *> flagPropertyManagers = manager->findChildren<QtFlagPropertyManager *>();
+ QListIterator<QtFlagPropertyManager *> itFlag(flagPropertyManagers);
+ while (itFlag.hasNext())
+ d_ptr->m_checkBoxFactory->removePropertyManager(itFlag.next()->subBoolPropertyManager());
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qtvariantproperty.cpp"
diff --git a/src/shared/qtpropertybrowser/qtvariantproperty.h b/src/shared/qtpropertybrowser/qtvariantproperty.h
new file mode 100644
index 000000000..b5fe1f928
--- /dev/null
+++ b/src/shared/qtpropertybrowser/qtvariantproperty.h
@@ -0,0 +1,177 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTVARIANTPROPERTY_H
+#define QTVARIANTPROPERTY_H
+
+#include "qtpropertybrowser.h"
+#include <QtCore/QVariant>
+#include <QtGui/QIcon>
+
+QT_BEGIN_NAMESPACE
+
+typedef QMap<int, QIcon> QtIconMap;
+
+class QtVariantPropertyManager;
+
+class QtVariantProperty : public QtProperty
+{
+public:
+ ~QtVariantProperty();
+ QVariant value() const;
+ QVariant attributeValue(const QString &attribute) const;
+ int valueType() const;
+ int propertyType() const;
+
+ void setValue(const QVariant &value);
+ void setAttribute(const QString &attribute, const QVariant &value);
+protected:
+ QtVariantProperty(QtVariantPropertyManager *manager);
+private:
+ friend class QtVariantPropertyManager;
+ QScopedPointer<class QtVariantPropertyPrivate> d_ptr;
+};
+
+class QtVariantPropertyManager : public QtAbstractPropertyManager
+{
+ Q_OBJECT
+public:
+ QtVariantPropertyManager(QObject *parent = 0);
+ ~QtVariantPropertyManager();
+
+ virtual QtVariantProperty *addProperty(int propertyType, const QString &name = QString());
+
+ int propertyType(const QtProperty *property) const;
+ int valueType(const QtProperty *property) const;
+ QtVariantProperty *variantProperty(const QtProperty *property) const;
+
+ virtual bool isPropertyTypeSupported(int propertyType) const;
+ virtual int valueType(int propertyType) const;
+ virtual QStringList attributes(int propertyType) const;
+ virtual int attributeType(int propertyType, const QString &attribute) const;
+
+ virtual QVariant value(const QtProperty *property) const;
+ virtual QVariant attributeValue(const QtProperty *property, const QString &attribute) const;
+
+ static int enumTypeId();
+ static int flagTypeId();
+ static int groupTypeId();
+ static int iconMapTypeId();
+public Q_SLOTS:
+ virtual void setValue(QtProperty *property, const QVariant &val);
+ virtual void setAttribute(QtProperty *property,
+ const QString &attribute, const QVariant &value);
+Q_SIGNALS:
+ void valueChanged(QtProperty *property, const QVariant &val);
+ void attributeChanged(QtProperty *property,
+ const QString &attribute, const QVariant &val);
+protected:
+ virtual bool hasValue(const QtProperty *property) const;
+ QString valueText(const QtProperty *property) const;
+ QIcon valueIcon(const QtProperty *property) const;
+ virtual void initializeProperty(QtProperty *property);
+ virtual void uninitializeProperty(QtProperty *property);
+ virtual QtProperty *createProperty();
+private:
+ QScopedPointer<class QtVariantPropertyManagerPrivate> d_ptr;
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, int, int))
+ Q_PRIVATE_SLOT(d_func(), void slotSingleStepChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, double))
+ Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, double, double))
+ Q_PRIVATE_SLOT(d_func(), void slotSingleStepChanged(QtProperty *, double))
+ Q_PRIVATE_SLOT(d_func(), void slotDecimalsChanged(QtProperty *, int))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, bool))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QString &))
+ Q_PRIVATE_SLOT(d_func(), void slotRegExpChanged(QtProperty *, const QRegExp &))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QDate &))
+ Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, const QDate &, const QDate &))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QTime &))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QDateTime &))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QKeySequence &))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QChar &))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QLocale &))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QPoint &))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QPointF &))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QSize &))
+ Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, const QSize &, const QSize &))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QSizeF &))
+ Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, const QSizeF &, const QSizeF &))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QRect &))
+ Q_PRIVATE_SLOT(d_func(), void slotConstraintChanged(QtProperty *, const QRect &))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QRectF &))
+ Q_PRIVATE_SLOT(d_func(), void slotConstraintChanged(QtProperty *, const QRectF &))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QColor &))
+ Q_PRIVATE_SLOT(d_func(), void slotEnumNamesChanged(QtProperty *, const QStringList &))
+ Q_PRIVATE_SLOT(d_func(), void slotEnumIconsChanged(QtProperty *, const QMap<int, QIcon> &))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QSizePolicy &))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QFont &))
+ Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QCursor &))
+ Q_PRIVATE_SLOT(d_func(), void slotFlagNamesChanged(QtProperty *, const QStringList &))
+
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyInserted(QtProperty *, QtProperty *, QtProperty *))
+ Q_PRIVATE_SLOT(d_func(), void slotPropertyRemoved(QtProperty *, QtProperty *))
+ Q_DECLARE_PRIVATE(QtVariantPropertyManager)
+ Q_DISABLE_COPY(QtVariantPropertyManager)
+};
+
+class QtVariantEditorFactory : public QtAbstractEditorFactory<QtVariantPropertyManager>
+{
+ Q_OBJECT
+public:
+ QtVariantEditorFactory(QObject *parent = 0);
+ ~QtVariantEditorFactory();
+protected:
+ void connectPropertyManager(QtVariantPropertyManager *manager);
+ QWidget *createEditor(QtVariantPropertyManager *manager, QtProperty *property,
+ QWidget *parent);
+ void disconnectPropertyManager(QtVariantPropertyManager *manager);
+private:
+ QScopedPointer<class QtVariantEditorFactoryPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtVariantEditorFactory)
+ Q_DISABLE_COPY(QtVariantEditorFactory)
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QIcon)
+Q_DECLARE_METATYPE(QtIconMap)
+#endif
diff --git a/src/shared/qttoolbardialog/images/back.png b/src/shared/qttoolbardialog/images/back.png
new file mode 100644
index 000000000..e58177f43
--- /dev/null
+++ b/src/shared/qttoolbardialog/images/back.png
Binary files differ
diff --git a/src/shared/qttoolbardialog/images/down.png b/src/shared/qttoolbardialog/images/down.png
new file mode 100644
index 000000000..29d1d4439
--- /dev/null
+++ b/src/shared/qttoolbardialog/images/down.png
Binary files differ
diff --git a/src/shared/qttoolbardialog/images/forward.png b/src/shared/qttoolbardialog/images/forward.png
new file mode 100644
index 000000000..34b91f09f
--- /dev/null
+++ b/src/shared/qttoolbardialog/images/forward.png
Binary files differ
diff --git a/src/shared/qttoolbardialog/images/minus.png b/src/shared/qttoolbardialog/images/minus.png
new file mode 100644
index 000000000..d6f233d73
--- /dev/null
+++ b/src/shared/qttoolbardialog/images/minus.png
Binary files differ
diff --git a/src/shared/qttoolbardialog/images/plus.png b/src/shared/qttoolbardialog/images/plus.png
new file mode 100644
index 000000000..40df1134f
--- /dev/null
+++ b/src/shared/qttoolbardialog/images/plus.png
Binary files differ
diff --git a/src/shared/qttoolbardialog/images/up.png b/src/shared/qttoolbardialog/images/up.png
new file mode 100644
index 000000000..e43731221
--- /dev/null
+++ b/src/shared/qttoolbardialog/images/up.png
Binary files differ
diff --git a/src/shared/qttoolbardialog/qttoolbardialog.cpp b/src/shared/qttoolbardialog/qttoolbardialog.cpp
new file mode 100644
index 000000000..b45bef290
--- /dev/null
+++ b/src/shared/qttoolbardialog/qttoolbardialog.cpp
@@ -0,0 +1,1871 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qttoolbardialog.h"
+#include "ui_qttoolbardialog.h"
+
+#include <QtCore/QSet>
+#include <QtGui/QtEvents>
+#include <QtGui/QAction>
+#include <QtGui/QToolBar>
+#include <QtGui/QMainWindow>
+#include <QtGui/QHeaderView>
+#include <QtGui/QPushButton>
+
+QT_BEGIN_NAMESPACE
+
+class QtFullToolBarManagerPrivate;
+
+class QtFullToolBarManager : public QObject
+{
+ Q_OBJECT
+public:
+ QtFullToolBarManager(QObject *parent);
+ ~QtFullToolBarManager();
+
+ void setMainWindow(QMainWindow *mainWindow);
+ QMainWindow *mainWindow() const;
+
+ void addCategory(const QString &category);
+ bool hasCategory(const QString &category) const;
+ QStringList categories() const;
+ QList<QAction *> categoryActions(const QString &category) const;
+ QString actionCategory(QAction *action) const;
+
+ // only non-separator
+ void addAction(QAction *action, const QString &category);
+
+ void removeAction(QAction *action);
+
+ QSet<QAction *> actions() const;
+ bool isWidgetAction(QAction *action) const;
+
+ /*
+ Adds (registers) toolBar. Adds (registers) actions that already exists in toolBar.
+ Remembers toolbar and its actions as a default.
+ */
+ void addDefaultToolBar(QToolBar *toolBar, const QString &category);
+
+ void removeDefaultToolBar(QToolBar *toolBar);
+ // NULL on action list means separator.
+ QMap<QToolBar *, QList<QAction *> > defaultToolBars() const;
+ bool isDefaultToolBar(QToolBar *toolBar) const;
+
+ QToolBar *createToolBar(const QString &toolBarName);
+ void deleteToolBar(QToolBar *toolBar); // only those which were created, not added
+
+ QList<QAction *> actions(QToolBar *toolBar) const;
+
+ void setToolBars(const QMap<QToolBar *, QList<QAction *> > &actions);
+ void setToolBar(QToolBar *toolBar, const QList<QAction *> &actions);
+
+ QMap<QToolBar *, QList<QAction *> > toolBarsActions() const;
+ QByteArray saveState(int version = 0) const;
+ bool restoreState(const QByteArray &state, int version = 0);
+
+public slots:
+
+ void resetToolBar(QToolBar *toolBar);
+ void resetAllToolBars();
+
+signals:
+ void toolBarCreated(QToolBar *toolBar);
+ void toolBarRemoved(QToolBar *toolBar);
+
+ /*
+ If QToolBarWidgetAction was in another tool bar and is inserted into
+ this toolBar, toolBarChanged is first emitted for other toolbar - without
+ that action. (Another approach may be that user first must call setToolBar
+ without that action for old tool bar)
+ */
+ void toolBarChanged(QToolBar *toolBar, const QList<QAction *> &actions);
+
+private:
+ QScopedPointer<QtFullToolBarManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtFullToolBarManager)
+ Q_DISABLE_COPY(QtFullToolBarManager)
+};
+
+class QtFullToolBarManagerPrivate
+{
+ class QtFullToolBarManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtFullToolBarManager)
+
+public:
+
+ QToolBar *toolBarWidgetAction(QAction *action) const;
+ void removeWidgetActions(const QMap<QToolBar *, QList<QAction *> > &actions);
+
+ enum {
+ VersionMarker = 0xff,
+ ToolBarMarker = 0xfe,
+ CustomToolBarMarker = 0xfd,
+ };
+
+ void saveState(QDataStream &stream) const;
+ bool restoreState(QDataStream &stream) const;
+ QToolBar *findDefaultToolBar(const QString &objectName) const;
+ QAction *findAction(const QString &actionName) const;
+
+ QToolBar *toolBarByName(const QString &toolBarName) const;
+
+ QtFullToolBarManagerPrivate();
+
+ QMap<QString, QList<QAction *> > categoryToActions;
+ QMap<QAction *, QString> actionToCategory;
+
+ QSet<QAction *> allActions;
+ QMap<QAction *, QToolBar *> widgetActions;
+ QSet<QAction *> regularActions;
+ QMap<QAction *, QList<QToolBar *> > actionToToolBars;
+
+ QMap<QToolBar *, QList<QAction *> > toolBars;
+ QMap<QToolBar *, QList<QAction *> > toolBarsWithSeparators;
+ QMap<QToolBar *, QList<QAction *> > defaultToolBars;
+ QList<QToolBar *> customToolBars;
+
+ QMainWindow *theMainWindow;
+};
+
+
+
+
+QtFullToolBarManagerPrivate::QtFullToolBarManagerPrivate()
+ : theMainWindow(0)
+{
+}
+
+QToolBar *QtFullToolBarManagerPrivate::toolBarWidgetAction(QAction *action) const
+{
+ if (widgetActions.contains(action))
+ return widgetActions.value(action);
+ return 0;
+}
+
+void QtFullToolBarManagerPrivate::removeWidgetActions(const QMap<QToolBar *, QList<QAction *> >
+ &actions)
+{
+ QMap<QToolBar *, QList<QAction *> >::ConstIterator itToolBar = actions.constBegin();
+ while (itToolBar != actions.constEnd()) {
+ QToolBar *toolBar = itToolBar.key();
+ QList<QAction *> newActions = toolBars.value(toolBar);
+ QList<QAction *> newActionsWithSeparators = toolBarsWithSeparators.value(toolBar);
+
+ QList<QAction *> removedActions;
+ QList<QAction *> actionList = itToolBar.value();
+ QListIterator<QAction *> itAction(actionList);
+ while (itAction.hasNext()) {
+ QAction *action = itAction.next();
+ if (newActions.contains(action) && toolBarWidgetAction(action) == toolBar) {
+ newActions.removeAll(action);
+ newActionsWithSeparators.removeAll(action);
+ removedActions.append(action);
+ }
+ }
+
+ //emit q_ptr->toolBarChanged(toolBar, newActions);
+
+ toolBars.insert(toolBar, newActions);
+ toolBarsWithSeparators.insert(toolBar, newActionsWithSeparators);
+ QListIterator<QAction *> itRemovedAction(removedActions);
+ while (itRemovedAction.hasNext()) {
+ QAction *oldAction = itRemovedAction.next();
+ widgetActions.insert(oldAction, 0);
+ actionToToolBars[oldAction].removeAll(toolBar);
+ }
+
+ ++itToolBar;
+ }
+}
+
+void QtFullToolBarManagerPrivate::saveState(QDataStream &stream) const
+{
+ stream << (uchar) ToolBarMarker;
+ stream << defaultToolBars.size();
+ QMap<QToolBar *, QList<QAction *> >::ConstIterator itToolBar =
+ defaultToolBars.constBegin();
+ while (itToolBar != defaultToolBars.constEnd()) {
+ QToolBar *tb = itToolBar.key();
+ if (tb->objectName().isEmpty()) {
+ qWarning("QtToolBarManager::saveState(): 'objectName' not set for QToolBar "
+ "%p '%s', using 'windowTitle' instead",
+ tb, tb->windowTitle().toLocal8Bit().constData());
+ stream << tb->windowTitle();
+ } else {
+ stream << tb->objectName();
+ }
+
+ stream << toolBars[tb].size();
+ QListIterator<QAction *> itAction(toolBars[tb]);
+ while (itAction.hasNext()) {
+ QAction *action = itAction.next();
+
+ if (action) {
+ if (action->objectName().isEmpty()) {
+ qWarning("QtToolBarManager::saveState(): 'objectName' not set for QAction "
+ "%p '%s', using 'text' instead",
+ action, action->text().toLocal8Bit().constData());
+ stream << action->text();
+ } else {
+ stream << action->objectName();
+ }
+ } else {
+ stream << QString();
+ }
+ }
+ ++itToolBar;
+ }
+
+
+ stream << (uchar) CustomToolBarMarker;
+ stream << toolBars.size() - defaultToolBars.size();
+ itToolBar = toolBars.constBegin();
+ while (itToolBar != toolBars.constEnd()) {
+ QToolBar *tb = itToolBar.key();
+ if (!defaultToolBars.contains(tb)) {
+ stream << tb->objectName();
+ stream << tb->windowTitle();
+
+ stream << toolBars[tb].size();
+ QListIterator<QAction *> itAction(toolBars[tb]);
+ while (itAction.hasNext()) {
+ QAction *action = itAction.next();
+
+ if (action) {
+ if (action->objectName().isEmpty()) {
+ qWarning("QtToolBarManager::saveState(): 'objectName' not set for QAction "
+ "%p '%s', using 'text' instead",
+ action, action->text().toLocal8Bit().constData());
+ stream << action->text();
+ } else {
+ stream << action->objectName();
+ }
+ } else {
+ stream << QString();
+ }
+ }
+ }
+ ++itToolBar;
+ }
+}
+
+bool QtFullToolBarManagerPrivate::restoreState(QDataStream &stream) const
+{
+ uchar tmarker;
+ stream >> tmarker;
+ if (tmarker != ToolBarMarker)
+ return false;
+
+ int toolBars;
+ stream >> toolBars;
+ for (int i = 0; i < toolBars; i++) {
+ QString objectName;
+ stream >> objectName;
+ int actionCount;
+ stream >> actionCount;
+ QList<QAction *> actions;
+ for (int j = 0; j < actionCount; j++) {
+ QString actionName;
+ stream >> actionName;
+
+ if (actionName.isEmpty())
+ actions.append(0);
+ else {
+ QAction *action = findAction(actionName);
+ if (action)
+ actions.append(action);
+ }
+ }
+
+ QToolBar *toolBar = findDefaultToolBar(objectName);
+ if (toolBar)
+ q_ptr->setToolBar(toolBar, actions);
+ }
+
+
+
+ uchar ctmarker;
+ stream >> ctmarker;
+ if (ctmarker != CustomToolBarMarker)
+ return false;
+
+ QList<QToolBar *> oldCustomToolBars = customToolBars;
+
+ stream >> toolBars;
+ for (int i = 0; i < toolBars; i++) {
+ QString objectName;
+ QString toolBarName;
+ int actionCount;
+ stream >> objectName;
+ stream >> toolBarName;
+ stream >> actionCount;
+ QList<QAction *> actions;
+ for (int j = 0; j < actionCount; j++) {
+ QString actionName;
+ stream >> actionName;
+
+ if (actionName.isEmpty())
+ actions.append(0);
+ else {
+ QAction *action = findAction(actionName);
+ if (action)
+ actions.append(action);
+ }
+ }
+
+ QToolBar *toolBar = toolBarByName(objectName);
+ if (toolBar) {
+ toolBar->setWindowTitle(toolBarName);
+ oldCustomToolBars.removeAll(toolBar);
+ }
+ else
+ toolBar = q_ptr->createToolBar(toolBarName);
+ if (toolBar) {
+ toolBar->setObjectName(objectName);
+ q_ptr->setToolBar(toolBar, actions);
+ }
+ }
+ QListIterator<QToolBar *> itToolBar(oldCustomToolBars);
+ while (itToolBar.hasNext())
+ q_ptr->deleteToolBar(itToolBar.next());
+ return true;
+}
+
+QToolBar *QtFullToolBarManagerPrivate::findDefaultToolBar(const QString &objectName) const
+{
+ QMap<QToolBar *, QList<QAction *> >::ConstIterator itToolBar =
+ defaultToolBars.constBegin();
+ while (itToolBar != defaultToolBars.constEnd()) {
+ QToolBar *tb = itToolBar.key();
+ if (tb->objectName() == objectName)
+ return tb;
+
+ ++itToolBar;
+ }
+
+ qWarning("QtToolBarManager::restoreState(): cannot find a QToolBar named "
+ "'%s', trying to match using 'windowTitle' instead.",
+ objectName.toLocal8Bit().constData());
+
+ itToolBar = defaultToolBars.constBegin();
+ while (itToolBar != defaultToolBars.constEnd()) {
+ QToolBar *tb = itToolBar.key();
+ if (tb->windowTitle() == objectName)
+ return tb;
+
+ ++itToolBar;
+ }
+ qWarning("QtToolBarManager::restoreState(): cannot find a QToolBar with "
+ "matching 'windowTitle' (looking for '%s').",
+ objectName.toLocal8Bit().constData());
+
+ return 0;
+}
+
+QAction *QtFullToolBarManagerPrivate::findAction(const QString &actionName) const
+{
+ QSetIterator<QAction *> itAction(allActions);
+ while (itAction.hasNext()) {
+ QAction *action = itAction.next();
+
+ if (action->objectName() == actionName)
+ return action;
+ }
+ qWarning("QtToolBarManager::restoreState(): cannot find a QAction named "
+ "'%s', trying to match using 'text' instead.",
+ actionName.toLocal8Bit().constData());
+
+ itAction.toFront();
+ while (itAction.hasNext()) {
+ QAction *action = itAction.next();
+
+ if (action->text() == actionName)
+ return action;
+ }
+ qWarning("QtToolBarManager::restoreState(): cannot find a QAction with "
+ "matching 'text' (looking for '%s').",
+ actionName.toLocal8Bit().constData());
+
+ return 0;
+}
+
+QToolBar *QtFullToolBarManagerPrivate::toolBarByName(const QString &toolBarName) const
+{
+ QMap<QToolBar *, QList<QAction *> >::ConstIterator itToolBar = toolBars.constBegin();
+ while (itToolBar != toolBars.constEnd()) {
+ QToolBar *toolBar = itToolBar.key();
+ if (toolBar->objectName() == toolBarName)
+ return toolBar;
+
+ ++itToolBar;
+ }
+ return 0;
+}
+
+//////////////////////////////
+
+QtFullToolBarManager::QtFullToolBarManager(QObject *parent)
+ : QObject(parent), d_ptr(new QtFullToolBarManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+}
+
+QtFullToolBarManager::~QtFullToolBarManager()
+{
+}
+
+void QtFullToolBarManager::setMainWindow(QMainWindow *mainWindow)
+{
+ d_ptr->theMainWindow = mainWindow;
+}
+
+QMainWindow *QtFullToolBarManager::mainWindow() const
+{
+ return d_ptr->theMainWindow;
+}
+
+void QtFullToolBarManager::addCategory(const QString &category)
+{
+ d_ptr->categoryToActions[category] = QList<QAction *>();
+}
+
+bool QtFullToolBarManager::hasCategory(const QString &category) const
+{
+ return d_ptr->categoryToActions.contains(category);
+}
+
+QStringList QtFullToolBarManager::categories() const
+{
+ return d_ptr->categoryToActions.keys();
+}
+
+QList<QAction *> QtFullToolBarManager::categoryActions(const QString &category) const
+{
+ QMap<QString, QList<QAction *> >::ConstIterator it =
+ d_ptr->categoryToActions.find(category);
+ if (it != d_ptr->categoryToActions.constEnd())
+ return it.value();
+ return QList<QAction *>();
+}
+
+QString QtFullToolBarManager::actionCategory(QAction *action) const
+{
+ QMap<QAction *, QString>::ConstIterator it = d_ptr->actionToCategory.find(action);
+ if (it != d_ptr->actionToCategory.constEnd())
+ return it.value();
+ return QString();
+}
+
+void QtFullToolBarManager::addAction(QAction *action, const QString &category)
+{
+ if (!action)
+ return;
+ if (action->isSeparator())
+ return;
+ if (d_ptr->allActions.contains(action))
+ return;
+ if (QLatin1String(action->metaObject()->className()) ==
+ QLatin1String("QToolBarWidgetAction"))
+ d_ptr->widgetActions.insert(action, 0);
+ else
+ d_ptr->regularActions.insert(action);
+ d_ptr->allActions.insert(action);
+ d_ptr->categoryToActions[category].append(action);
+ d_ptr->actionToCategory[action] = category;
+}
+
+void QtFullToolBarManager::removeAction(QAction *action)
+{
+ if (!d_ptr->allActions.contains(action))
+ return;
+
+ QList<QToolBar *> toolBars = d_ptr->actionToToolBars[action];
+ QListIterator<QToolBar *> itToolBar(toolBars);
+ while (itToolBar.hasNext()) {
+ QToolBar *toolBar = itToolBar.next();
+
+ d_ptr->toolBars[toolBar].removeAll(action);
+ d_ptr->toolBarsWithSeparators[toolBar].removeAll(action);
+
+ toolBar->removeAction(action);
+ }
+
+ QMap<QToolBar *, QList<QAction *> >::ConstIterator itDefault =
+ d_ptr->defaultToolBars.constBegin();
+ while (itDefault != d_ptr->defaultToolBars.constEnd()) {
+ if (itDefault.value().contains(action))
+ d_ptr->defaultToolBars[itDefault.key()].removeAll(action);
+
+ itDefault++;
+ }
+
+ d_ptr->allActions.remove(action);
+ d_ptr->widgetActions.remove(action);
+ d_ptr->regularActions.remove(action);
+ d_ptr->actionToToolBars.remove(action);
+
+ QString category = d_ptr->actionToCategory.value(action);
+ d_ptr->actionToCategory.remove(action);
+ d_ptr->categoryToActions[category].removeAll(action);
+
+ if (d_ptr->categoryToActions[category].isEmpty())
+ d_ptr->categoryToActions.remove(category);
+}
+
+QSet<QAction *> QtFullToolBarManager::actions() const
+{
+ return d_ptr->allActions;
+}
+
+bool QtFullToolBarManager::isWidgetAction(QAction *action) const
+{
+ if (d_ptr->widgetActions.contains(action))
+ return true;
+ return false;
+}
+
+void QtFullToolBarManager::addDefaultToolBar(QToolBar *toolBar, const QString &category)
+{
+ if (!toolBar)
+ return;
+ if (d_ptr->toolBars.contains(toolBar))
+ return;
+ // could be also checked if toolBar belongs to mainwindow
+
+ QList<QAction *> newActionsWithSeparators;
+ QList<QAction *> newActions;
+ QList<QAction *> actions = toolBar->actions();
+ QListIterator<QAction *> itAction(actions);
+ while (itAction.hasNext()) {
+ QAction *action = itAction.next();
+ addAction(action, category);
+ if (d_ptr->widgetActions.contains(action))
+ d_ptr->widgetActions.insert(action, toolBar);
+ newActionsWithSeparators.append(action);
+ if (action->isSeparator())
+ action = 0;
+ else
+ d_ptr->actionToToolBars[action].append(toolBar);
+ newActions.append(action);
+ }
+ d_ptr->defaultToolBars.insert(toolBar, newActions);
+ //Below could be done by call setToolBar() if we want signal emission here.
+ d_ptr->toolBars.insert(toolBar, newActions);
+ d_ptr->toolBarsWithSeparators.insert(toolBar, newActionsWithSeparators);
+}
+
+void QtFullToolBarManager::removeDefaultToolBar(QToolBar *toolBar)
+{
+ if (!d_ptr->defaultToolBars.contains(toolBar))
+ return;
+
+ QList<QAction *> defaultActions = d_ptr->defaultToolBars[toolBar];
+ setToolBar(toolBar, QList<QAction *>());
+ QListIterator<QAction *> itAction(defaultActions);
+ while (itAction.hasNext())
+ removeAction(itAction.next());
+
+ d_ptr->toolBars.remove(toolBar);
+ d_ptr->toolBarsWithSeparators.remove(toolBar);
+ d_ptr->defaultToolBars.remove(toolBar);
+
+ itAction.toFront();
+ while (itAction.hasNext()) {
+ QAction *action = itAction.next();
+ if (action)
+ toolBar->insertAction(0, action);
+ else
+ toolBar->insertSeparator(0);
+ }
+}
+
+QMap<QToolBar *, QList<QAction *> > QtFullToolBarManager::defaultToolBars() const
+{
+ return d_ptr->defaultToolBars;
+}
+
+bool QtFullToolBarManager::isDefaultToolBar(QToolBar *toolBar) const
+{
+ if (d_ptr->defaultToolBars.contains(toolBar))
+ return true;
+ return false;
+}
+
+QToolBar *QtFullToolBarManager::createToolBar(const QString &toolBarName)
+{
+ if (!mainWindow())
+ return 0;
+ QToolBar *toolBar = new QToolBar(toolBarName, mainWindow());
+ int i = 1;
+ const QString prefix = QLatin1String("_Custom_Toolbar_%1");
+ QString name = prefix.arg(i);
+ while (d_ptr->toolBarByName(name))
+ name = prefix.arg(++i);
+ toolBar->setObjectName(name);
+ mainWindow()->addToolBar(toolBar);
+ d_ptr->customToolBars.append(toolBar);
+ d_ptr->toolBars.insert(toolBar, QList<QAction *>());
+ d_ptr->toolBarsWithSeparators.insert(toolBar, QList<QAction *>());
+ return toolBar;
+}
+
+void QtFullToolBarManager::deleteToolBar(QToolBar *toolBar)
+{
+ if (!d_ptr->toolBars.contains(toolBar))
+ return;
+ if (d_ptr->defaultToolBars.contains(toolBar))
+ return;
+ setToolBar(toolBar, QList<QAction *>());
+ d_ptr->customToolBars.removeAll(toolBar);
+ d_ptr->toolBars.remove(toolBar);
+ d_ptr->toolBarsWithSeparators.remove(toolBar);
+ delete toolBar;
+}
+
+QList<QAction *> QtFullToolBarManager::actions(QToolBar *toolBar) const
+{
+ if (d_ptr->toolBars.contains(toolBar))
+ return d_ptr->toolBars.value(toolBar);
+ return QList<QAction *>();
+}
+
+void QtFullToolBarManager::setToolBars(const QMap<QToolBar *, QList<QAction *> > &actions)
+{
+ QMap<QToolBar *, QList<QAction *> >::ConstIterator it = actions.constBegin();
+ while (it != actions.constEnd()) {
+ setToolBar(it.key(), it.value());
+ ++it;
+ }
+}
+
+void QtFullToolBarManager::setToolBar(QToolBar *toolBar, const QList<QAction *> &actions)
+{
+ if (!toolBar)
+ return;
+ if (!d_ptr->toolBars.contains(toolBar))
+ return;
+
+ if (actions == d_ptr->toolBars[toolBar])
+ return;
+
+ QMap<QToolBar *, QList<QAction *> > toRemove;
+
+ QList<QAction *> newActions;
+ QListIterator<QAction *> itAction(actions);
+ while (itAction.hasNext()) {
+ QAction *action = itAction.next();
+ if (!action || (!newActions.contains(action) && d_ptr->allActions.contains(action)))
+ newActions.append(action);
+
+ QToolBar *oldToolBar = d_ptr->toolBarWidgetAction(action);
+ if (oldToolBar && oldToolBar != toolBar)
+ toRemove[oldToolBar].append(action);
+ }
+
+ d_ptr->removeWidgetActions(toRemove);
+
+ QList<QAction *> oldActions = d_ptr->toolBarsWithSeparators.value(toolBar);
+ QListIterator<QAction *> itOldAction(oldActions);
+ while (itOldAction.hasNext()) {
+ QAction *action = itOldAction.next();
+ /*
+ When addDefaultToolBar() separator actions could be checked if they are
+ inserted in other toolbars - if yes then create new one.
+ */
+ if (d_ptr->toolBarWidgetAction(action) == toolBar)
+ d_ptr->widgetActions.insert(action, 0);
+ toolBar->removeAction(action);
+ if (action->isSeparator())
+ delete action;
+ else
+ d_ptr->actionToToolBars[action].removeAll(toolBar);
+ }
+
+ QList<QAction *> newActionsWithSeparators;
+ QListIterator<QAction *> itNewActions(newActions);
+ while (itNewActions.hasNext()) {
+ QAction *action = itNewActions.next();
+ QAction *newAction = 0;
+ if (!action)
+ newAction = toolBar->insertSeparator(0);
+ if (d_ptr->allActions.contains(action)) {
+ toolBar->insertAction(0, action);
+ newAction = action;
+ d_ptr->actionToToolBars[action].append(toolBar);
+ }
+ newActionsWithSeparators.append(newAction);
+ }
+ d_ptr->toolBars.insert(toolBar, newActions);
+ d_ptr->toolBarsWithSeparators.insert(toolBar, newActionsWithSeparators);
+}
+
+QMap<QToolBar *, QList<QAction *> > QtFullToolBarManager::toolBarsActions() const
+{
+ return d_ptr->toolBars;
+}
+
+void QtFullToolBarManager::resetToolBar(QToolBar *toolBar)
+{
+ if (!isDefaultToolBar(toolBar))
+ return;
+ setToolBar(toolBar, defaultToolBars().value(toolBar));
+}
+
+void QtFullToolBarManager::resetAllToolBars()
+{
+ setToolBars(defaultToolBars());
+ QList<QToolBar *> oldCustomToolBars = d_ptr->customToolBars;
+ QListIterator<QToolBar *> itToolBar(oldCustomToolBars);
+ while (itToolBar.hasNext()) {
+ deleteToolBar(itToolBar.next());
+ }
+}
+
+QByteArray QtFullToolBarManager::saveState(int version) const
+{
+ QByteArray data;
+ QDataStream stream(&data, QIODevice::WriteOnly);
+ stream << QtFullToolBarManagerPrivate::VersionMarker;
+ stream << version;
+ d_ptr->saveState(stream);
+ return data;
+}
+
+bool QtFullToolBarManager::restoreState(const QByteArray &state, int version)
+{
+ QByteArray sd = state;
+ QDataStream stream(&sd, QIODevice::ReadOnly);
+ int marker, v;
+ stream >> marker;
+ stream >> v;
+ if (marker != QtFullToolBarManagerPrivate::VersionMarker || v != version)
+ return false;
+ return d_ptr->restoreState(stream);
+}
+
+
+class QtToolBarManagerPrivate
+{
+ class QtToolBarManager *q_ptr;
+ Q_DECLARE_PUBLIC(QtToolBarManager)
+public:
+ QtFullToolBarManager *manager;
+};
+
+//////////////////////////////////////
+
+/*! \class QtToolBarManager
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtToolBarManager class provides toolbar management for
+ main windows.
+
+ The QtToolBarManager is typically used with a QtToolBarDialog
+ which allows the user to customize the toolbars for a given main
+ window. The QtToolBarDialog class's functionality is controlled by
+ an instance of the QtToolBarManager class, and the main window is
+ specified using the QtToolBarManager class's setMainWindow()
+ function.
+
+ The currently specified main window can be retrieved using the
+ mainWindow() function.
+
+ The toolbar manager holds lists of the given main window's actions
+ and toolbars, and can add actions and toolbars to these
+ lists using the addAction() and addToolBar() functions
+ respectively. The actions can in addition be categorized
+ acccording to the user's preferences. The toolbar manager can also
+ remove custom actions and toolbars using the removeAction() and
+ removeToolBar() functions.
+
+ Finally, the QtToolBarManager is able to save the customized state
+ of its toolbars using the saveState() function as well as restore
+ the toolbars' saved state using restoreState() function.
+
+ \sa QtToolBarDialog
+*/
+
+/*!
+ Creates a toolbar manager with the given \a parent.
+*/
+QtToolBarManager::QtToolBarManager(QObject *parent)
+ : QObject(parent), d_ptr(new QtToolBarManagerPrivate)
+{
+ d_ptr->q_ptr = this;
+
+ d_ptr->manager = new QtFullToolBarManager(this);
+}
+
+/*!
+ Destroys the toolbar manager.
+*/
+QtToolBarManager::~QtToolBarManager()
+{
+}
+
+/*!
+ Sets the main window upon which the toolbar manager operates, to
+ be the given \a mainWindow.
+*/
+void QtToolBarManager::setMainWindow(QMainWindow *mainWindow)
+{
+ d_ptr->manager->setMainWindow(mainWindow);
+}
+
+/*!
+ Returns the main window associated this toolbar manager.
+*/
+QMainWindow *QtToolBarManager::mainWindow() const
+{
+ return d_ptr->manager->mainWindow();
+}
+
+/*!
+ Adds the given \a action to the given \a category in the manager's
+ list of actions. If the \a category doesn't exist it is created.
+ Only non separator actions can be added. If the action is already
+ added to the list, the function doesn't do anything.
+
+ \sa removeAction()
+*/
+void QtToolBarManager::addAction(QAction *action, const QString &category)
+{
+ d_ptr->manager->addAction(action, category);
+}
+
+/*!
+ Removes the specified \a action from the manager's list of
+ actions. The action is also removed from all the registered
+ toolbars. If the specified \a action is the only action in its
+ category, that category is removed as well.
+
+ \sa addAction()
+*/
+void QtToolBarManager::removeAction(QAction *action)
+{
+ d_ptr->manager->removeAction(action);
+}
+
+/*!
+ Adds the given \a toolBar to the manager's toolbar list.
+
+ All the \a toolBar's actions are automatically added to the given
+ \a category in the manager's list of actions if they're not
+ already there. The manager remembers which toolbar the actions
+ belonged to, so, when the \a toolBar is removed, its actions will
+ be removed as well.
+
+ Custom toolbars are created with the main window returned by
+ the mainWindow() function, as its parent.
+
+ \sa removeToolBar()
+*/
+void QtToolBarManager::addToolBar(QToolBar *toolBar, const QString &category)
+{
+ d_ptr->manager->addDefaultToolBar(toolBar, category);
+}
+
+/*!
+ Removes the specified \a toolBar from the manager's list. All the
+ actions that existed in the specified \a toolBar when it was
+ added are removed as well.
+
+ \sa addToolBar()
+*/
+void QtToolBarManager::removeToolBar(QToolBar *toolBar)
+{
+ d_ptr->manager->removeDefaultToolBar(toolBar);
+}
+
+/*!
+ Returns the manager's toolbar list.
+*/
+QList<QToolBar *> QtToolBarManager::toolBars() const
+{
+ return d_ptr->manager->toolBarsActions().keys();
+}
+
+/*
+void QtToolBarManager::resetToolBar(QToolBar *toolBar)
+{
+ d_ptr->manager->resetToolBar(toolBar);
+}
+
+void QtToolBarManager::resetAllToolBars()
+{
+ d_ptr->manager->resetAllToolBars();
+}
+*/
+
+/*!
+ Saves the state of the toolbar manager's toolbars. The \a version
+ number is stored as part of the data.
+
+ Identifies all the QToolBar and QAction objects by their object
+ name property. Ensure that this property is unique for each
+ QToolBar and QAction that you add using the QtToolBarManager.
+
+ Returns an identifier for the state which can be passed along with
+ the version number to the restoreState() function to restore the
+ saved state.
+
+ \sa restoreState()
+*/
+QByteArray QtToolBarManager::saveState(int version) const
+{
+ return d_ptr->manager->saveState(version);
+}
+
+/*!
+ Restores the saved state of the toolbar manager's toolbars. The
+ \a version number is compared with the version number of the
+ stored \a state.
+
+ Returns true if the version numbers are matching and the toolbar
+ manager's state is restored; otherwise the toolbar manager's state
+ is left unchanged and the function returns false.
+
+ Note that the state of the toolbar manager's toolbars should be
+ restored before restoring the state of the main window's toolbars
+ and dockwidgets using the QMainWindow::restoreState() function. In
+ that way the restoreState() function can create the custom
+ toolbars before the QMainWindow::restoreState() function restores
+ the custom toolbars' positions.
+
+ \sa saveState()
+*/
+bool QtToolBarManager::restoreState(const QByteArray &state, int version)
+{
+ return d_ptr->manager->restoreState(state, version);
+}
+
+//////////////////////
+
+class ToolBarItem {
+public:
+ ToolBarItem() : tb(0) {}
+ ToolBarItem(QToolBar *toolBar) : tb(toolBar) {}
+ ToolBarItem(QToolBar *toolBar, const QString &toolBarName)
+ : tb(toolBar), tbName(toolBarName) {}
+ ToolBarItem(const QString &toolBarName) : tb(0), tbName(toolBarName) {}
+ QToolBar *toolBar() const
+ { return tb; }
+ void setToolBar(QToolBar *toolBar)
+ { tb = toolBar; }
+ QString toolBarName() const
+ { return tbName; }
+ void setToolBarName(const QString &toolBarName)
+ { tbName = toolBarName; }
+private:
+ QToolBar *tb;
+ QString tbName;
+};
+
+class QtToolBarDialogPrivate {
+ QtToolBarDialog *q_ptr;
+ Q_DECLARE_PUBLIC(QtToolBarDialog)
+public:
+ QtToolBarDialogPrivate()
+ : toolBarManager(0),
+ currentAction(0),
+ currentToolBar(0)
+ { }
+
+ ToolBarItem *createItem(QToolBar *toolBar);
+ ToolBarItem *createItem(const QString &toolBarName);
+ void deleteItem(ToolBarItem *item);
+
+ void newClicked();
+ void removeClicked();
+ void defaultClicked();
+ void okClicked();
+ void applyClicked();
+ void cancelClicked();
+ void upClicked();
+ void downClicked();
+ void leftClicked();
+ void rightClicked();
+ void renameClicked();
+ void toolBarRenamed(QListWidgetItem *item);
+ void currentActionChanged(QTreeWidgetItem *current);
+ void currentToolBarChanged(QListWidgetItem *current);
+ void currentToolBarActionChanged(QListWidgetItem *current);
+
+ void removeToolBar(ToolBarItem *item);
+ bool isDefaultToolBar(ToolBarItem *item) const;
+ void setButtons();
+ void clearOld();
+ void fillNew();
+ QtFullToolBarManager *toolBarManager;
+ QMap<ToolBarItem *, QList<QAction *> > currentState;
+ QMap<QToolBar *, ToolBarItem *> toolBarItems;
+ QSet<ToolBarItem *> createdItems;
+ QSet<ToolBarItem *> removedItems;
+
+ QSet<ToolBarItem *> allToolBarItems;
+
+ // static
+ QTreeWidgetItem *currentAction;
+ QMap<QAction *, QTreeWidgetItem *> actionToItem;
+ QMap<QTreeWidgetItem *, QAction *> itemToAction;
+
+ // dynamic
+ ToolBarItem *currentToolBar;
+ QMap<ToolBarItem *, QListWidgetItem *> toolBarToItem;
+ QMap<QListWidgetItem *, ToolBarItem *> itemToToolBar;
+
+ // dynamic
+ QMap<QAction *, QListWidgetItem *> actionToCurrentItem;
+ QMap<QListWidgetItem *, QAction *> currentItemToAction;
+
+ QMap<QAction *, ToolBarItem *> widgetActionToToolBar;
+ QMap<ToolBarItem *, QSet<QAction *> > toolBarToWidgetActions;
+
+ QString separatorText;
+ Ui::QtToolBarDialog ui;
+};
+
+ToolBarItem *QtToolBarDialogPrivate::createItem(QToolBar *toolBar)
+{
+ if (!toolBar)
+ return 0;
+ ToolBarItem *item = new ToolBarItem(toolBar, toolBar->windowTitle());
+ allToolBarItems.insert(item);
+ return item;
+}
+
+ToolBarItem *QtToolBarDialogPrivate::createItem(const QString &toolBarName)
+{
+ ToolBarItem *item = new ToolBarItem(toolBarName);
+ allToolBarItems.insert(item);
+ return item;
+}
+
+void QtToolBarDialogPrivate::deleteItem(ToolBarItem *item)
+{
+ if (!allToolBarItems.contains(item))
+ return;
+ allToolBarItems.remove(item);
+ delete item;
+}
+
+void QtToolBarDialogPrivate::clearOld()
+{
+ ui.actionTree->clear();
+ ui.toolBarList->clear();
+ ui.currentToolBarList->clear();
+ ui.removeButton->setEnabled(false);
+ ui.newButton->setEnabled(false);
+ ui.upButton->setEnabled(false);
+ ui.downButton->setEnabled(false);
+ ui.leftButton->setEnabled(false);
+ ui.rightButton->setEnabled(false);
+
+ actionToItem.clear();
+ itemToAction.clear();
+ toolBarToItem.clear();
+ itemToToolBar.clear();
+ actionToCurrentItem.clear();
+ currentItemToAction.clear();
+ widgetActionToToolBar.clear();
+ toolBarToWidgetActions.clear();
+
+ toolBarItems.clear();
+ currentState.clear();
+ createdItems.clear();
+ removedItems.clear();
+ QSetIterator<ToolBarItem *> itItem(allToolBarItems);
+ while (itItem.hasNext())
+ delete itItem.next();
+ allToolBarItems.clear();
+
+ currentToolBar = 0;
+ currentAction = 0;
+}
+
+void QtToolBarDialogPrivate::fillNew()
+{
+ if (!toolBarManager)
+ return;
+
+ QTreeWidgetItem *item = new QTreeWidgetItem(ui.actionTree);
+ item->setText(0, separatorText);
+ ui.actionTree->setCurrentItem(item);
+ currentAction = item;
+ actionToItem.insert(0, item);
+ itemToAction.insert(item, 0);
+ QStringList categories = toolBarManager->categories();
+ QStringListIterator itCategory(categories);
+ while (itCategory.hasNext()) {
+ QString category = itCategory.next();
+ QTreeWidgetItem *categoryItem = new QTreeWidgetItem(ui.actionTree);
+ categoryItem->setText(0, category);
+ QList<QAction *> actions = toolBarManager->categoryActions(category);
+ QListIterator<QAction *> itAction(actions);
+ while (itAction.hasNext()) {
+ QAction *action = itAction.next();
+ item = new QTreeWidgetItem(categoryItem);
+ item->setText(0, action->text());
+ item->setIcon(0, action->icon());
+ item->setTextAlignment(0, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic);
+ actionToItem.insert(action, item);
+ itemToAction.insert(item, action);
+ if (toolBarManager->isWidgetAction(action)) {
+ item->setData(0, Qt::TextColorRole, QColor(Qt::blue));
+ widgetActionToToolBar.insert(action, 0);
+ }
+ item->setFlags(item->flags() | Qt::ItemIsDragEnabled);
+ }
+ ui.actionTree->setItemExpanded(categoryItem, true);
+ }
+ //ui.actionTree->sortItems(0, Qt::AscendingOrder);
+
+ QMap<QToolBar *, QList<QAction *> > toolBars = toolBarManager->toolBarsActions();
+ QMap<QToolBar *, QList<QAction *> >::ConstIterator it = toolBars.constBegin();
+ while (it != toolBars.constEnd()) {
+ QToolBar *toolBar = it.key();
+ ToolBarItem *tbItem = createItem(toolBar);
+ toolBarItems.insert(toolBar, tbItem);
+ QListWidgetItem *item = new QListWidgetItem(toolBar->windowTitle(),
+ ui.toolBarList);
+ toolBarToItem.insert(tbItem, item);
+ itemToToolBar.insert(item, tbItem);
+ QList<QAction *> actions = it.value();
+ QListIterator<QAction *> itAction(actions);
+ while (itAction.hasNext()) {
+ QAction *action = itAction.next();
+ if (toolBarManager->isWidgetAction(action)) {
+ widgetActionToToolBar.insert(action, tbItem);
+ toolBarToWidgetActions[tbItem].insert(action);
+ }
+ }
+ currentState.insert(tbItem, actions);
+ if (it == toolBars.constBegin())
+ ui.toolBarList->setCurrentItem(item);
+ if (isDefaultToolBar(tbItem))
+ item->setData(Qt::TextColorRole, QColor(Qt::darkGreen));
+ else
+ item->setFlags(item->flags() | Qt::ItemIsEditable);
+
+ ++it;
+ }
+ ui.toolBarList->sortItems();
+ setButtons();
+}
+
+bool QtToolBarDialogPrivate::isDefaultToolBar(ToolBarItem *item) const
+{
+ if (!item)
+ return false;
+ if (!item->toolBar())
+ return false;
+ return toolBarManager->isDefaultToolBar(item->toolBar());
+}
+
+void QtToolBarDialogPrivate::setButtons()
+{
+ bool newEnabled = false;
+ bool removeEnabled = false;
+ bool renameEnabled = false;
+ bool upEnabled = false;
+ bool downEnabled = false;
+ bool leftEnabled = false;
+ bool rightEnabled = false;
+
+ if (toolBarManager) {
+ newEnabled = true;
+ removeEnabled = !isDefaultToolBar(currentToolBar);
+ renameEnabled = removeEnabled;
+ QListWidgetItem *currentToolBarAction = ui.currentToolBarList->currentItem();
+ if (currentToolBarAction) {
+ int row = ui.currentToolBarList->row(currentToolBarAction);
+ upEnabled = row > 0;
+ downEnabled = row < ui.currentToolBarList->count() - 1;
+ leftEnabled = true;
+ }
+ if (currentAction && currentToolBar)
+ rightEnabled = true;
+ }
+ ui.newButton->setEnabled(newEnabled);
+ ui.removeButton->setEnabled(removeEnabled);
+ ui.renameButton->setEnabled(renameEnabled);
+ ui.upButton->setEnabled(upEnabled);
+ ui.downButton->setEnabled(downEnabled);
+ ui.leftButton->setEnabled(leftEnabled);
+ ui.rightButton->setEnabled(rightEnabled);
+}
+
+void QtToolBarDialogPrivate::newClicked()
+{
+ QString toolBarName = QtToolBarDialog::tr("Custom Toolbar"); // = QInputDialog::getString();
+ // produce unique name
+ ToolBarItem *item = createItem(toolBarName);
+ currentState.insert(item, QList<QAction *>());
+ createdItems.insert(item);
+ QListWidgetItem *i = new QListWidgetItem(toolBarName, ui.toolBarList);
+ i->setFlags(i->flags() | Qt::ItemIsEditable);
+ ui.toolBarList->setCurrentItem(i);
+ itemToToolBar.insert(i, item);
+ toolBarToItem.insert(item, i);
+ ui.toolBarList->sortItems();
+ ui.toolBarList->setCurrentItem(i);
+ currentToolBarChanged(i);
+ renameClicked();
+}
+
+void QtToolBarDialogPrivate::removeToolBar(ToolBarItem *item)
+{
+ if (!item)
+ return;
+ if (item->toolBar() && toolBarManager->isDefaultToolBar(item->toolBar()))
+ return;
+ if (!toolBarToItem.contains(item))
+ return;
+ QListWidgetItem *i = toolBarToItem.value(item);
+ bool wasCurrent = false;
+ if (i == ui.toolBarList->currentItem())
+ wasCurrent = true;
+ int row = ui.toolBarList->row(i);
+ QMap<ToolBarItem *, QSet<QAction *> >::ConstIterator itToolBar =
+ toolBarToWidgetActions.find(item);
+ if (itToolBar != toolBarToWidgetActions.constEnd()) {
+ QSet<QAction *> actions = itToolBar.value();
+ QSetIterator<QAction *> itAction(actions);
+ while (itAction.hasNext()) {
+ QAction *action = itAction.next();
+ widgetActionToToolBar.insert(action, 0);
+ }
+ toolBarToWidgetActions.remove(item);
+ }
+
+ currentState.remove(item);
+ createdItems.remove(item);
+ toolBarToItem.remove(item);
+ itemToToolBar.remove(i);
+ delete i;
+ if (item->toolBar())
+ removedItems.insert(item);
+ else
+ deleteItem(item);
+ if (wasCurrent) {
+ if (row == ui.toolBarList->count())
+ row--;
+ if (row < 0)
+ ;
+ else
+ ui.toolBarList->setCurrentRow(row);
+ }
+ setButtons();
+}
+
+void QtToolBarDialogPrivate::removeClicked()
+{
+ QListWidgetItem *i = ui.toolBarList->currentItem();
+ if (!i)
+ return;
+ ToolBarItem *item = itemToToolBar.value(i);
+ removeToolBar(item);
+}
+
+void QtToolBarDialogPrivate::defaultClicked()
+{
+ QMap<QToolBar *, QList<QAction *> > defaultToolBars = toolBarManager->defaultToolBars();
+ QMap<QToolBar *, QList<QAction *> >::ConstIterator itToolBar = defaultToolBars.constBegin();
+ while (itToolBar != defaultToolBars.constEnd()) {
+ QToolBar *toolBar = itToolBar.key();
+ ToolBarItem *toolBarItem = toolBarItems.value(toolBar);
+
+ if (toolBarToWidgetActions.contains(toolBarItem)) {
+ QSetIterator<QAction *> itAction(toolBarToWidgetActions.value(toolBarItem));
+ while (itAction.hasNext())
+ widgetActionToToolBar.insert(itAction.next(), 0);
+ toolBarToWidgetActions.remove(toolBarItem);
+ }
+
+ currentState.remove(toolBarItem);
+
+ QListIterator<QAction *> itAction(itToolBar.value());
+ while (itAction.hasNext()) {
+ QAction *action = itAction.next();
+ if (toolBarManager->isWidgetAction(action)) {
+ ToolBarItem *otherToolBar = widgetActionToToolBar.value(action);
+ if (otherToolBar) {
+ toolBarToWidgetActions[otherToolBar].remove(action);
+ currentState[otherToolBar].removeAll(action);
+ }
+ widgetActionToToolBar.insert(action, toolBarItem);
+ toolBarToWidgetActions[toolBarItem].insert(action);
+ }
+ }
+ currentState.insert(toolBarItem, itToolBar.value());
+
+ ++itToolBar;
+ }
+ currentToolBarChanged(toolBarToItem.value(currentToolBar));
+
+ QList<ToolBarItem *> toolBars = currentState.keys();
+ QListIterator<ToolBarItem *> itTb(toolBars);
+ while (itTb.hasNext())
+ removeToolBar(itTb.next());
+}
+
+void QtToolBarDialogPrivate::okClicked()
+{
+ applyClicked();
+ q_ptr->accept();
+}
+
+void QtToolBarDialogPrivate::applyClicked()
+{
+ QMap<ToolBarItem *, QList<QAction *> > toolBars = currentState;
+ QMap<ToolBarItem *, QList<QAction *> >::ConstIterator itToolBar = toolBars.constBegin();
+ while (itToolBar != toolBars.constEnd()) {
+ ToolBarItem *item = itToolBar.key();
+ QToolBar *toolBar = item->toolBar();
+ if (toolBar) {
+ toolBarManager->setToolBar(toolBar, itToolBar.value());
+ toolBar->setWindowTitle(item->toolBarName());
+ }
+
+ ++itToolBar;
+ }
+
+ QSet<ToolBarItem *> toRemove = removedItems;
+ QSetIterator<ToolBarItem *> itRemove(toRemove);
+ while (itRemove.hasNext()) {
+ ToolBarItem *item = itRemove.next();
+ QToolBar *toolBar = item->toolBar();
+ removedItems.remove(item);
+ currentState.remove(item);
+ deleteItem(item);
+ if (toolBar)
+ toolBarManager->deleteToolBar(toolBar);
+ }
+
+ QSet<ToolBarItem *> toCreate = createdItems;
+ QSetIterator<ToolBarItem *> itCreate(toCreate);
+ while (itCreate.hasNext()) {
+ ToolBarItem *item = itCreate.next();
+ QString toolBarName = item->toolBarName();
+ createdItems.remove(item);
+ QList<QAction *> actions = currentState.value(item);
+ QToolBar *toolBar = toolBarManager->createToolBar(toolBarName);
+ item->setToolBar(toolBar);
+ toolBarManager->setToolBar(toolBar, actions);
+ }
+}
+
+void QtToolBarDialogPrivate::upClicked()
+{
+ QListWidgetItem *currentToolBarAction = ui.currentToolBarList->currentItem();
+ if (!currentToolBarAction)
+ return;
+ int row = ui.currentToolBarList->row(currentToolBarAction);
+ if (row == 0)
+ return;
+ ui.currentToolBarList->takeItem(row);
+ int newRow = row - 1;
+ ui.currentToolBarList->insertItem(newRow, currentToolBarAction);
+ QList<QAction *> actions = currentState.value(currentToolBar);
+ QAction *action = actions.at(row);
+ actions.removeAt(row);
+ actions.insert(newRow, action);
+ currentState.insert(currentToolBar, actions);
+ ui.currentToolBarList->setCurrentItem(currentToolBarAction);
+ setButtons();
+}
+
+void QtToolBarDialogPrivate::downClicked()
+{
+ QListWidgetItem *currentToolBarAction = ui.currentToolBarList->currentItem();
+ if (!currentToolBarAction)
+ return;
+ int row = ui.currentToolBarList->row(currentToolBarAction);
+ if (row == ui.currentToolBarList->count() - 1)
+ return;
+ ui.currentToolBarList->takeItem(row);
+ int newRow = row + 1;
+ ui.currentToolBarList->insertItem(newRow, currentToolBarAction);
+ QList<QAction *> actions = currentState.value(currentToolBar);
+ QAction *action = actions.at(row);
+ actions.removeAt(row);
+ actions.insert(newRow, action);
+ currentState.insert(currentToolBar, actions);
+ ui.currentToolBarList->setCurrentItem(currentToolBarAction);
+ setButtons();
+}
+
+void QtToolBarDialogPrivate::leftClicked()
+{
+ QListWidgetItem *currentToolBarAction = ui.currentToolBarList->currentItem();
+ if (!currentToolBarAction)
+ return;
+ int row = ui.currentToolBarList->row(currentToolBarAction);
+ currentState[currentToolBar].removeAt(row);
+ QAction *action = currentItemToAction.value(currentToolBarAction);
+ if (widgetActionToToolBar.contains(action)) {
+ ToolBarItem *item = widgetActionToToolBar.value(action);
+ if (item == currentToolBar) { // have to be
+ toolBarToWidgetActions[item].remove(action);
+ if (toolBarToWidgetActions[item].empty())
+ toolBarToWidgetActions.remove(item);
+ }
+ widgetActionToToolBar.insert(action, 0);
+ }
+ if (action)
+ actionToCurrentItem.remove(action);
+ currentItemToAction.remove(currentToolBarAction);
+ delete currentToolBarAction;
+ if (row == ui.currentToolBarList->count())
+ row--;
+ if (row >= 0) {
+ QListWidgetItem *item = ui.currentToolBarList->item(row);
+ ui.currentToolBarList->setCurrentItem(item);
+ }
+ setButtons();
+}
+
+void QtToolBarDialogPrivate::rightClicked()
+{
+ if (!currentAction)
+ return;
+ if (!currentToolBar)
+ return;
+ QListWidgetItem *currentToolBarAction = ui.currentToolBarList->currentItem();
+
+ QAction *action = itemToAction.value(currentAction);
+ QListWidgetItem *item = 0;
+ if (action) {
+ if (currentState[currentToolBar].contains(action)) {
+ item = actionToCurrentItem.value(action);
+ if (item == currentToolBarAction)
+ return;
+ int row = ui.currentToolBarList->row(item);
+ ui.currentToolBarList->takeItem(row);
+ currentState[currentToolBar].removeAt(row);
+ // only reorder here
+ } else {
+ item = new QListWidgetItem(action->text());
+ item->setIcon(action->icon());
+ item->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic);
+ currentItemToAction.insert(item, action);
+ actionToCurrentItem.insert(action, item);
+ if (widgetActionToToolBar.contains(action)) {
+ item->setData(Qt::TextColorRole, QColor(Qt::blue));
+ ToolBarItem *toolBar = widgetActionToToolBar.value(action);
+ if (toolBar) {
+ currentState[toolBar].removeAll(action);
+ toolBarToWidgetActions[toolBar].remove(action);
+ if (toolBarToWidgetActions[toolBar].empty())
+ toolBarToWidgetActions.remove(toolBar);
+ }
+ widgetActionToToolBar.insert(action, currentToolBar);
+ toolBarToWidgetActions[currentToolBar].insert(action);
+ }
+ }
+ } else {
+ item = new QListWidgetItem(separatorText);
+ currentItemToAction.insert(item, 0);
+ }
+
+ int row = ui.currentToolBarList->count();
+ if (currentToolBarAction) {
+ row = ui.currentToolBarList->row(currentToolBarAction) + 1;
+ }
+ ui.currentToolBarList->insertItem(row, item);
+ currentState[currentToolBar].insert(row, action);
+ ui.currentToolBarList->setCurrentItem(item);
+
+ setButtons();
+}
+
+void QtToolBarDialogPrivate::renameClicked()
+{
+ if (!currentToolBar)
+ return;
+
+ QListWidgetItem *item = toolBarToItem.value(currentToolBar);
+ ui.toolBarList->editItem(item);
+}
+
+void QtToolBarDialogPrivate::toolBarRenamed(QListWidgetItem *item)
+{
+ if (!currentToolBar)
+ return;
+
+ ToolBarItem *tbItem = itemToToolBar.value(item);
+ if (!tbItem)
+ return;
+ tbItem->setToolBarName(item->text());
+ //ui.toolBarList->sortItems();
+}
+
+void QtToolBarDialogPrivate::currentActionChanged(QTreeWidgetItem *current)
+{
+ if (itemToAction.contains(current))
+ currentAction = current;
+ else
+ currentAction = NULL;
+ setButtons();
+}
+
+void QtToolBarDialogPrivate::currentToolBarChanged(QListWidgetItem *current)
+{
+ currentToolBar = itemToToolBar.value(current);
+ ui.currentToolBarList->clear();
+ actionToCurrentItem.clear();
+ currentItemToAction.clear();
+ setButtons();
+ if (!currentToolBar) {
+ return;
+ }
+ QList<QAction *> actions = currentState.value(currentToolBar);
+ QListIterator<QAction *> itAction(actions);
+ QListWidgetItem *first = 0;
+ while (itAction.hasNext()) {
+ QAction *action = itAction.next();
+ QString actionName = separatorText;
+ if (action)
+ actionName = action->text();
+ QListWidgetItem *item = new QListWidgetItem(actionName, ui.currentToolBarList);
+ if (action) {
+ item->setIcon(action->icon());
+ item->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic);
+ actionToCurrentItem.insert(action, item);
+ if (widgetActionToToolBar.contains(action))
+ item->setData(Qt::TextColorRole, QColor(Qt::blue));
+ }
+ currentItemToAction.insert(item, action);
+ if (!first)
+ first = item;
+ }
+ if (first)
+ ui.currentToolBarList->setCurrentItem(first);
+}
+
+void QtToolBarDialogPrivate::currentToolBarActionChanged(QListWidgetItem *)
+{
+ setButtons();
+}
+
+void QtToolBarDialogPrivate::cancelClicked()
+{
+ // just nothing
+ q_ptr->reject();
+}
+
+//////////////////////
+/*
+class FeedbackItemDelegate : public QItemDelegate
+{
+ Q_OBJECT
+public:
+ FeedbackItemDelegate(QObject *parent = 0) : QItemDelegate(parent) { }
+
+ virtual void paint(QPainter *painter, const QStyleOptionViewItem &option,
+ const QModelIndex & index) const;
+ virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
+};
+
+void FeedbackItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+{
+ if ()
+ painter->save();
+ QRect r = option.rect;
+ float yCentral = r.height() / 2.0;
+ float margin = 2.0;
+ float arrowWidth = 5.0;
+ float width = 20;
+ qDebug("rect: x %d, y %d, w %d, h %d", r.x(), r.y(), r.width(), r.height());
+ QLineF lineBase(0.0 + margin, r.y() + yCentral, width - margin, r.y() + yCentral);
+ QLineF lineArrowLeft(width - margin - arrowWidth, r.y() + yCentral - arrowWidth,
+ width - margin, r.y() + yCentral);
+ QLineF lineArrowRight(width - margin - arrowWidth, r.y() + yCentral + arrowWidth,
+ width - margin, r.y() + yCentral);
+ painter->drawLine(lineBase);
+ painter->drawLine(lineArrowLeft);
+ painter->drawLine(lineArrowRight);
+ painter->translate(QPoint(width, 0));
+ QItemDelegate::paint(painter, option, index);
+ painter->restore();
+}
+
+QSize FeedbackItemDelegate::sizeHint(const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+{
+ //return QItemDelegate::sizeHint(option, index);
+ QSize s = QItemDelegate::sizeHint(option, index);
+ s.setWidth(s.width() - 20);
+ return s;
+}
+
+class QtToolBarListWidget : public QListWidget
+{
+ Q_OBJECT
+public:
+ QtToolBarListWidget(QWidget *parent) : QListWidget(parent), actionDrag(false) {}
+
+protected:
+ void startDrag(Qt::DropActions supportedActions);
+
+ void dragEnterEvent(QDragEnterEvent *event);
+ void dragMoveEvent(QDragMoveEvent *event);
+ void dragLeaveEvent(QDragLeaveEvent *);
+ void dropEvent(QDropEvent *event);
+
+ void setDragAction(const QString *action) { actionName = action; }
+private:
+ QPersistentModelIndex lastDropIndicator;
+ QString actionName;
+ bool actionDrag;
+};
+
+void QtToolBarListWidget::startDrag(Qt::DropActions supportedActions)
+{
+ QListWidgetItem *item = currentItem();
+ if (item) {
+ actionName = QString();
+ emit aboutToDrag(item);
+ if (!actionName.isEmpty()) {
+ QDrag *drag = new QDrag(this);
+ QMimeData *data = new QMimeData;
+ data->setData("action", actionName.toLocal8Bit().constData());
+ drag->setMimeData(data);
+ drag->start(supportedActions);
+ }
+ }
+}
+
+void QtToolBarListWidget::dragEnterEvent(QDragEnterEvent *event)
+{
+ const QMimeData *mime = event->mimeData();
+ actionDrag = mime->hasFormat("action");
+ if (actionDrag)
+ event->accept();
+ else
+ event->ignore();
+}
+
+void QtToolBarListWidget::dragMoveEvent(QDragMoveEvent *event)
+{
+ event->ignore();
+ if (actionDrag) {
+ QPoint p = event->pos();
+ QListWidgetItem *item = itemAt(p);
+ Indicator indic = QtToolBarListWidget::None;
+ if (item) {
+ QRect rect = visualItemRect(item);
+ if (p.y() - rect.top() < rect.height() / 2)
+ indic = QtToolBarListWidget::Above;
+ else
+ indic = QtToolBarListWidget::Below;
+ }
+ setIndicator(item, indic);
+ event->accept();
+ }
+}
+
+void QtToolBarListWidget::dragLeaveEvent(QDragLeaveEvent *)
+{
+ if (actionDrag) {
+ actionDrag = false;
+ setIndicator(item, QtToolBarListWidget::None);
+ }
+}
+
+void QtToolBarListWidget::dropEvent(QDropEvent *event)
+{
+ if (actionDrag) {
+ QListWidgetItem *item = indicatorItem();
+ Indicator indic = indicator();
+ QByteArray array = event->mimeData()->data("action");
+ QDataStream stream(&array, QIODevice::ReadOnly);
+ QString action;
+ stream >> action;
+ emit actionDropped(action, item, );
+
+ actionDrag = false;
+ setIndicator(item, QtToolBarListWidget::None);
+ }
+}
+*/
+
+/*! \class QtToolBarDialog
+ \internal
+ \inmodule QtDesigner
+ \since 4.4
+
+ \brief The QtToolBarDialog class provides a dialog for customizing
+ toolbars.
+
+ QtToolBarDialog allows the user to customize the toolbars for a
+ given main window.
+
+ \image qttoolbardialog.png
+
+ The dialog lets the users add, rename and remove custom toolbars.
+ Note that built-in toolbars are marked with a green color, and
+ cannot be removed or renamed.
+
+ The users can also add and remove actions from the toolbars. An
+ action can be added to many toolbars, but a toolbar can only
+ contain one instance of each action. Actions that contains a
+ widget are marked with a blue color in the list of actions, and
+ can only be added to one single toolbar.
+
+ Finally, the users can add separators to the toolbars.
+
+ The original toolbars can be restored by clicking the \gui
+ {Restore all} button. All custom toolbars will then be removed,
+ and all built-in toolbars will be restored to their original state.
+
+ The QtToolBarDialog class's functionality is controlled by an
+ instance of the QtToolBarManager class, and the main window is
+ specified using the QtToolBarManager::setMainWindow() function.
+
+ All you need to do to use QtToolBarDialog is to specify an
+ QtToolBarManager instance and call the QDialog::exec() slot:
+
+ \snippet doc/src/snippets/code/tools_shared_qttoolbardialog_qttoolbardialog.cpp 0
+
+ \sa QtToolBarManager
+*/
+
+/*!
+ Creates a toolbar dialog with the given \a parent and the specified
+ window \a flags.
+*/
+QtToolBarDialog::QtToolBarDialog(QWidget *parent, Qt::WindowFlags flags)
+ : QDialog(parent, flags), d_ptr(new QtToolBarDialogPrivate)
+{
+ d_ptr->q_ptr = this;
+ d_ptr->ui.setupUi(this);
+ d_ptr->separatorText = tr("< S E P A R A T O R >");
+
+ d_ptr->ui.actionTree->setColumnCount(1);
+ d_ptr->ui.actionTree->setRootIsDecorated(false);
+ d_ptr->ui.actionTree->header()->hide();
+
+ d_ptr->ui.upButton->setIcon(QIcon(QLatin1String(":/trolltech/qttoolbardialog/images/up.png")));
+ d_ptr->ui.downButton->setIcon(QIcon(QLatin1String(":/trolltech/qttoolbardialog/images/down.png")));
+ d_ptr->ui.leftButton->setIcon(QIcon(QLatin1String(":/trolltech/qttoolbardialog/images/back.png")));
+ d_ptr->ui.rightButton->setIcon(QIcon(QLatin1String(":/trolltech/qttoolbardialog/images/forward.png")));
+ d_ptr->ui.newButton->setIcon(QIcon(QLatin1String(":/trolltech/qttoolbardialog/images/plus.png")));
+ d_ptr->ui.removeButton->setIcon(QIcon(QLatin1String(":/trolltech/qttoolbardialog/images/minus.png")));
+
+ connect(d_ptr->ui.newButton, SIGNAL(clicked()), this, SLOT(newClicked()));
+ connect(d_ptr->ui.removeButton, SIGNAL(clicked()), this, SLOT(removeClicked()));
+ connect(d_ptr->ui.renameButton, SIGNAL(clicked()), this, SLOT(renameClicked()));
+ connect(d_ptr->ui.upButton, SIGNAL(clicked()), this, SLOT(upClicked()));
+ connect(d_ptr->ui.downButton, SIGNAL(clicked()), this, SLOT(downClicked()));
+ connect(d_ptr->ui.leftButton, SIGNAL(clicked()), this, SLOT(leftClicked()));
+ connect(d_ptr->ui.rightButton, SIGNAL(clicked()), this, SLOT(rightClicked()));
+
+ connect(d_ptr->ui.buttonBox->button(QDialogButtonBox::RestoreDefaults), SIGNAL(clicked()), this, SLOT(defaultClicked()));
+ connect(d_ptr->ui.buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(okClicked()));
+ connect(d_ptr->ui.buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked()), this, SLOT(applyClicked()));
+ connect(d_ptr->ui.buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(cancelClicked()));
+
+ connect(d_ptr->ui.actionTree, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
+ this, SLOT(currentActionChanged(QTreeWidgetItem*)));
+ connect(d_ptr->ui.toolBarList, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
+ this, SLOT(currentToolBarChanged(QListWidgetItem*)));
+ connect(d_ptr->ui.currentToolBarList,
+ SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
+ this, SLOT(currentToolBarActionChanged(QListWidgetItem*)));
+
+ connect(d_ptr->ui.actionTree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),
+ this, SLOT(rightClicked()));
+ connect(d_ptr->ui.currentToolBarList, SIGNAL(itemDoubleClicked(QListWidgetItem*)),
+ this, SLOT(leftClicked()));
+ connect(d_ptr->ui.toolBarList, SIGNAL(itemChanged(QListWidgetItem*)),
+ this, SLOT(toolBarRenamed(QListWidgetItem*)));
+}
+
+/*!
+ Destroys the toolbar dialog.
+*/
+QtToolBarDialog::~QtToolBarDialog()
+{
+ d_ptr->clearOld();
+}
+
+/*!
+ Connects the toolbar dialog to the given \a toolBarManager. Then,
+ when exec() is called, the toolbar dialog will operate using the
+ given \a toolBarManager.
+*/
+void QtToolBarDialog::setToolBarManager(QtToolBarManager *toolBarManager)
+{
+ if (d_ptr->toolBarManager == toolBarManager->d_ptr->manager)
+ return;
+ if (isVisible())
+ d_ptr->clearOld();
+ d_ptr->toolBarManager = toolBarManager->d_ptr->manager;
+ if (isVisible())
+ d_ptr->fillNew();
+}
+
+/*!
+ \reimp
+*/
+void QtToolBarDialog::showEvent(QShowEvent *event)
+{
+ if (!event->spontaneous())
+ d_ptr->fillNew();
+}
+
+/*!
+ \reimp
+*/
+void QtToolBarDialog::hideEvent(QHideEvent *event)
+{
+ if (!event->spontaneous())
+ d_ptr->clearOld();
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qttoolbardialog.cpp"
+#include "qttoolbardialog.moc"
diff --git a/src/shared/qttoolbardialog/qttoolbardialog.h b/src/shared/qttoolbardialog/qttoolbardialog.h
new file mode 100644
index 000000000..925662e4b
--- /dev/null
+++ b/src/shared/qttoolbardialog/qttoolbardialog.h
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt Designer. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QTTOOLBARDIALOG_H
+#define QTTOOLBARDIALOG_H
+
+#include <QtGui/QDialog>
+
+QT_BEGIN_NAMESPACE
+
+class QMainWindow;
+class QAction;
+class QToolBar;
+
+class QtToolBarManagerPrivate;
+
+class QtToolBarManager : public QObject
+{
+ Q_OBJECT
+public:
+
+ explicit QtToolBarManager(QObject *parent = 0);
+ ~QtToolBarManager();
+
+ void setMainWindow(QMainWindow *mainWindow);
+ QMainWindow *mainWindow() const;
+
+ void addAction(QAction *action, const QString &category);
+ void removeAction(QAction *action);
+
+ void addToolBar(QToolBar *toolBar, const QString &category);
+ void removeToolBar(QToolBar *toolBar);
+
+ QList<QToolBar *> toolBars() const;
+
+ QByteArray saveState(int version = 0) const;
+ bool restoreState(const QByteArray &state, int version = 0);
+
+private:
+
+ friend class QtToolBarDialog;
+ QScopedPointer<QtToolBarManagerPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtToolBarManager)
+ Q_DISABLE_COPY(QtToolBarManager)
+};
+
+class QtToolBarDialogPrivate;
+
+class QtToolBarDialog : public QDialog
+{
+ Q_OBJECT
+public:
+
+ explicit QtToolBarDialog(QWidget *parent = 0, Qt::WindowFlags flags = 0);
+ ~QtToolBarDialog();
+
+ void setToolBarManager(QtToolBarManager *toolBarManager);
+
+protected:
+
+ void showEvent(QShowEvent *event);
+ void hideEvent(QHideEvent *event);
+
+private:
+
+ QScopedPointer<QtToolBarDialogPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QtToolBarDialog)
+ Q_DISABLE_COPY(QtToolBarDialog)
+
+ Q_PRIVATE_SLOT(d_func(), void newClicked())
+ Q_PRIVATE_SLOT(d_func(), void removeClicked())
+ Q_PRIVATE_SLOT(d_func(), void defaultClicked())
+ Q_PRIVATE_SLOT(d_func(), void okClicked())
+ Q_PRIVATE_SLOT(d_func(), void applyClicked())
+ Q_PRIVATE_SLOT(d_func(), void cancelClicked())
+ Q_PRIVATE_SLOT(d_func(), void upClicked())
+ Q_PRIVATE_SLOT(d_func(), void downClicked())
+ Q_PRIVATE_SLOT(d_func(), void leftClicked())
+ Q_PRIVATE_SLOT(d_func(), void rightClicked())
+ Q_PRIVATE_SLOT(d_func(), void renameClicked())
+ Q_PRIVATE_SLOT(d_func(), void toolBarRenamed(QListWidgetItem *))
+ Q_PRIVATE_SLOT(d_func(), void currentActionChanged(QTreeWidgetItem *))
+ Q_PRIVATE_SLOT(d_func(), void currentToolBarChanged(QListWidgetItem *))
+ Q_PRIVATE_SLOT(d_func(), void currentToolBarActionChanged(QListWidgetItem *))
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/shared/qttoolbardialog/qttoolbardialog.pri b/src/shared/qttoolbardialog/qttoolbardialog.pri
new file mode 100644
index 000000000..5aca44757
--- /dev/null
+++ b/src/shared/qttoolbardialog/qttoolbardialog.pri
@@ -0,0 +1,6 @@
+INCLUDEPATH += $$PWD
+DEPENDPATH += $$PWD
+SOURCES += $$PWD/qttoolbardialog.cpp
+HEADERS += $$PWD/qttoolbardialog.h
+FORMS += $$PWD/qttoolbardialog.ui
+RESOURCES += $$PWD/qttoolbardialog.qrc
diff --git a/src/shared/qttoolbardialog/qttoolbardialog.qrc b/src/shared/qttoolbardialog/qttoolbardialog.qrc
new file mode 100644
index 000000000..ce0336682
--- /dev/null
+++ b/src/shared/qttoolbardialog/qttoolbardialog.qrc
@@ -0,0 +1,10 @@
+<RCC version="1.0">
+ <qresource prefix="/trolltech/qttoolbardialog">
+ <file>images/up.png</file>
+ <file>images/down.png</file>
+ <file>images/forward.png</file>
+ <file>images/back.png</file>
+ <file>images/plus.png</file>
+ <file>images/minus.png</file>
+ </qresource>
+</RCC>
diff --git a/src/shared/qttoolbardialog/qttoolbardialog.ui b/src/shared/qttoolbardialog/qttoolbardialog.ui
new file mode 100644
index 000000000..c4ad934f8
--- /dev/null
+++ b/src/shared/qttoolbardialog/qttoolbardialog.ui
@@ -0,0 +1,207 @@
+<ui version="4.0" >
+ <class>QtToolBarDialog</class>
+ <widget class="QDialog" name="QtToolBarDialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>583</width>
+ <height>508</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Customize Toolbars</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>8</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item rowspan="3" row="1" column="0" >
+ <widget class="QTreeWidget" name="actionTree" >
+ <column>
+ <property name="text" >
+ <string>1</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Actions</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="2" >
+ <layout class="QHBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>Toolbars</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="newButton" >
+ <property name="toolTip" >
+ <string>Add new toolbar</string>
+ </property>
+ <property name="text" >
+ <string>New</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="removeButton" >
+ <property name="toolTip" >
+ <string>Remove selected toolbar</string>
+ </property>
+ <property name="text" >
+ <string>Remove</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="renameButton" >
+ <property name="toolTip" >
+ <string>Rename toolbar</string>
+ </property>
+ <property name="text" >
+ <string>Rename</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="3" column="1" >
+ <layout class="QVBoxLayout" >
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QToolButton" name="upButton" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Minimum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Move action up</string>
+ </property>
+ <property name="text" >
+ <string>Up</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="leftButton" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Minimum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Remove action from toolbar</string>
+ </property>
+ <property name="text" >
+ <string>&lt;-</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="rightButton" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Minimum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Add action to toolbar</string>
+ </property>
+ <property name="text" >
+ <string>-></string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="downButton" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Minimum" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip" >
+ <string>Move action down</string>
+ </property>
+ <property name="text" >
+ <string>Down</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>29</width>
+ <height>16</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item row="3" column="2" >
+ <widget class="QListWidget" name="currentToolBarList" />
+ </item>
+ <item row="2" column="1" colspan="2" >
+ <widget class="QLabel" name="label_3" >
+ <property name="text" >
+ <string>Current Toolbar Actions</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" colspan="2" >
+ <widget class="QListWidget" name="toolBarList" />
+ </item>
+ <item row="5" column="0" colspan="3" >
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>newButton</tabstop>
+ <tabstop>removeButton</tabstop>
+ <tabstop>renameButton</tabstop>
+ <tabstop>toolBarList</tabstop>
+ <tabstop>upButton</tabstop>
+ <tabstop>leftButton</tabstop>
+ <tabstop>rightButton</tabstop>
+ <tabstop>downButton</tabstop>
+ <tabstop>currentToolBarList</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>