summaryrefslogtreecommitdiffstats
path: root/unix
diff options
context:
space:
mode:
authorwart <wart@noemail.net>1999-06-18 18:44:00 (GMT)
committerwart <wart@noemail.net>1999-06-18 18:44:00 (GMT)
commita696654fdaa75a0b34c3444c7e07877190ab01ed (patch)
tree41b21b952dbc906244f567e01f4353e1e88d8c70 /unix
parentf4885fa53714cff050c2d41f5a412d29808df300 (diff)
downloadtk-a696654fdaa75a0b34c3444c7e07877190ab01ed.zip
tk-a696654fdaa75a0b34c3444c7e07877190ab01ed.tar.gz
tk-a696654fdaa75a0b34c3444c7e07877190ab01ed.tar.bz2
Changed references to LD_FLAGS to LDFLAGS to be consistent with Tcl.
FossilOrigin-Name: ef51171aac9228b038c942c42c8b8bc7a5c968d7
Diffstat (limited to 'unix')
-rw-r--r--unix/Makefile.in8
1 files changed, 4 insertions, 4 deletions
diff --git a/unix/Makefile.in b/unix/Makefile.in
index 50d86b7..3b7b69f 100644
--- a/unix/Makefile.in
+++ b/unix/Makefile.in
@@ -5,7 +5,7 @@
# "autoconf" program (constructs like "@foo@" will get replaced in the
# actual Makefile.
#
-# RCS: @(#) $Id: Makefile.in,v 1.19 1999/06/16 20:11:29 surles Exp $
+# RCS: @(#) $Id: Makefile.in,v 1.20 1999/06/18 18:44:01 wart Exp $
# Current Tk version; used in various names.
@@ -375,17 +375,17 @@ objs: ${OBJS}
wish: $(WISH_OBJS) $(TK_LIB_FILE) $(TK_STUB_LIB_FILE)
- $(CC) @LD_FLAGS@ $(WISH_OBJS) \
+ $(CC) @LDFLAGS@ $(WISH_OBJS) \
@TK_BUILD_LIB_SPEC@ \
$(WISH_LIBS) $(TK_CC_SEARCH_FLAGS) -o wish
tktest: $(TKTEST_OBJS) $(TK_LIB_FILE)
- ${CC} @LD_FLAGS@ $(TKTEST_OBJS) \
+ ${CC} @LDFLAGS@ $(TKTEST_OBJS) \
@TK_BUILD_LIB_SPEC@ \
$(WISH_LIBS) $(TK_CC_SEARCH_FLAGS) -o tktest
xttest: test.o tkTest.o tkSquare.o $(TK_LIB_FILE)
- ${CC} @LD_FLAGS@ test.o tkTest.o tkSquare.o \
+ ${CC} @LDFLAGS@ test.o tkTest.o tkSquare.o \
@TK_BUILD_LIB_SPEC@ \
$(WISH_LIBS) $(TK_LD_SEARCH_FLAGS) -lXt -o xttest
.git/diff/tools/shared/qtgradienteditor/qtgradientmanager.h?h=v4.7.0-beta1&id=e5fcad302d86d316390c6b0f62759a067313e8a9'>tools/shared/qtgradienteditor/qtgradientmanager.h92
-rw-r--r--tools/shared/qtgradienteditor/qtgradientstopscontroller.cpp730
-rw-r--r--tools/shared/qtgradienteditor/qtgradientstopscontroller.h106
-rw-r--r--tools/shared/qtgradienteditor/qtgradientstopsmodel.cpp480
-rw-r--r--tools/shared/qtgradienteditor/qtgradientstopsmodel.h121
-rw-r--r--tools/shared/qtgradienteditor/qtgradientstopswidget.cpp1156
-rw-r--r--tools/shared/qtgradienteditor/qtgradientstopswidget.h115
-rw-r--r--tools/shared/qtgradienteditor/qtgradientutils.cpp420
-rw-r--r--tools/shared/qtgradienteditor/qtgradientutils.h66
-rw-r--r--tools/shared/qtgradienteditor/qtgradientview.cpp292
-rw-r--r--tools/shared/qtgradienteditor/qtgradientview.h99
-rw-r--r--tools/shared/qtgradienteditor/qtgradientview.ui135
-rw-r--r--tools/shared/qtgradienteditor/qtgradientviewdialog.cpp89
-rw-r--r--tools/shared/qtgradienteditor/qtgradientviewdialog.h75
-rw-r--r--tools/shared/qtgradienteditor/qtgradientviewdialog.ui121
-rw-r--r--tools/shared/qtgradienteditor/qtgradientwidget.cpp817
-rw-r--r--tools/shared/qtgradienteditor/qtgradientwidget.h120
-rw-r--r--tools/shared/qtpropertybrowser/images/cursor-arrow.pngbin0 -> 171 bytes-rw-r--r--tools/shared/qtpropertybrowser/images/cursor-busy.pngbin0 -> 201 bytes-rw-r--r--tools/shared/qtpropertybrowser/images/cursor-closedhand.pngbin0 -> 147 bytes-rw-r--r--tools/shared/qtpropertybrowser/images/cursor-cross.pngbin0 -> 130 bytes-rw-r--r--tools/shared/qtpropertybrowser/images/cursor-forbidden.pngbin0 -> 199 bytes-rw-r--r--tools/shared/qtpropertybrowser/images/cursor-hand.pngbin0 -> 159 bytes-rw-r--r--tools/shared/qtpropertybrowser/images/cursor-hsplit.pngbin0 -> 155 bytes-rw-r--r--tools/shared/qtpropertybrowser/images/cursor-ibeam.pngbin0 -> 124 bytes-rw-r--r--tools/shared/qtpropertybrowser/images/cursor-openhand.pngbin0 -> 160 bytes-rw-r--r--tools/shared/qtpropertybrowser/images/cursor-sizeall.pngbin0 -> 174 bytes-rw-r--r--tools/shared/qtpropertybrowser/images/cursor-sizeb.pngbin0 -> 161 bytes-rw-r--r--tools/shared/qtpropertybrowser/images/cursor-sizef.pngbin0 -> 161 bytes-rw-r--r--tools/shared/qtpropertybrowser/images/cursor-sizeh.pngbin0 -> 145 bytes-rw-r--r--tools/shared/qtpropertybrowser/images/cursor-sizev.pngbin0 -> 141 bytes-rw-r--r--tools/shared/qtpropertybrowser/images/cursor-uparrow.pngbin0 -> 132 bytes-rw-r--r--tools/shared/qtpropertybrowser/images/cursor-vsplit.pngbin0 -> 161 bytes-rw-r--r--tools/shared/qtpropertybrowser/images/cursor-wait.pngbin0 -> 172 bytes-rw-r--r--tools/shared/qtpropertybrowser/images/cursor-whatsthis.pngbin0 -> 191 bytes-rw-r--r--tools/shared/qtpropertybrowser/qtbuttonpropertybrowser.cpp633
-rw-r--r--tools/shared/qtpropertybrowser/qtbuttonpropertybrowser.h89
-rw-r--r--tools/shared/qtpropertybrowser/qteditorfactory.cpp2591
-rw-r--r--tools/shared/qtpropertybrowser/qteditorfactory.h401
-rw-r--r--tools/shared/qtpropertybrowser/qtgroupboxpropertybrowser.cpp535
-rw-r--r--tools/shared/qtpropertybrowser/qtgroupboxpropertybrowser.h80
-rw-r--r--tools/shared/qtpropertybrowser/qtpropertybrowser.cpp1965
-rw-r--r--tools/shared/qtpropertybrowser/qtpropertybrowser.h315
-rw-r--r--tools/shared/qtpropertybrowser/qtpropertybrowser.pri19
-rw-r--r--tools/shared/qtpropertybrowser/qtpropertybrowser.qrc23
-rw-r--r--tools/shared/qtpropertybrowser/qtpropertybrowserutils.cpp434
-rw-r--r--tools/shared/qtpropertybrowser/qtpropertybrowserutils_p.h161
-rw-r--r--tools/shared/qtpropertybrowser/qtpropertymanager.cpp6493
-rw-r--r--tools/shared/qtpropertybrowser/qtpropertymanager.h750
-rw-r--r--tools/shared/qtpropertybrowser/qttreepropertybrowser.cpp1048
-rw-r--r--tools/shared/qtpropertybrowser/qttreepropertybrowser.h138
-rw-r--r--tools/shared/qtpropertybrowser/qtvariantproperty.cpp2282
-rw-r--r--tools/shared/qtpropertybrowser/qtvariantproperty.h181
-rw-r--r--tools/shared/qttoolbardialog/images/back.pngbin0 -> 678 bytes-rw-r--r--tools/shared/qttoolbardialog/images/down.pngbin0 -> 594 bytes-rw-r--r--tools/shared/qttoolbardialog/images/forward.pngbin0 -> 655 bytes-rw-r--r--tools/shared/qttoolbardialog/images/minus.pngbin0 -> 250 bytes-rw-r--r--tools/shared/qttoolbardialog/images/plus.pngbin0 -> 462 bytes-rw-r--r--tools/shared/qttoolbardialog/images/up.pngbin0 -> 692 bytes-rw-r--r--tools/shared/qttoolbardialog/qttoolbardialog.cpp1877
-rw-r--r--tools/shared/qttoolbardialog/qttoolbardialog.h138
-rw-r--r--tools/shared/qttoolbardialog/qttoolbardialog.pri6
-rw-r--r--tools/shared/qttoolbardialog/qttoolbardialog.qrc10
-rw-r--r--tools/shared/qttoolbardialog/qttoolbardialog.ui207
115 files changed, 32739 insertions, 0 deletions
diff --git a/tools/shared/deviceskin/deviceskin.cpp b/tools/shared/deviceskin/deviceskin.cpp
new file mode 100644
index 0000000..3301d24
--- /dev/null
+++ b/tools/shared/deviceskin/deviceskin.cpp
@@ -0,0 +1,857 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@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/tools/shared/deviceskin/deviceskin.h b/tools/shared/deviceskin/deviceskin.h
new file mode 100644
index 0000000..8f3fefd
--- /dev/null
+++ b/tools/shared/deviceskin/deviceskin.h
@@ -0,0 +1,174 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@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/tools/shared/deviceskin/deviceskin.pri b/tools/shared/deviceskin/deviceskin.pri
new file mode 100644
index 0000000..e4c9ef7
--- /dev/null
+++ b/tools/shared/deviceskin/deviceskin.pri
@@ -0,0 +1,3 @@
+INCLUDEPATH += $$PWD
+HEADERS += $$PWD/deviceskin.h
+SOURCES += $$PWD/deviceskin.cpp
diff --git a/tools/shared/findwidget/abstractfindwidget.cpp b/tools/shared/findwidget/abstractfindwidget.cpp
new file mode 100644
index 0000000..e52722c
--- /dev/null
+++ b/tools/shared/findwidget/abstractfindwidget.cpp
@@ -0,0 +1,295 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@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/tools/shared/findwidget/abstractfindwidget.h b/tools/shared/findwidget/abstractfindwidget.h
new file mode 100644
index 0000000..fe0c932
--- /dev/null
+++ b/tools/shared/findwidget/abstractfindwidget.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@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)
+
+ 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/tools/shared/findwidget/findwidget.pri b/tools/shared/findwidget/findwidget.pri
new file mode 100644
index 0000000..6e0f58a
--- /dev/null
+++ b/tools/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/tools/shared/findwidget/findwidget.qrc b/tools/shared/findwidget/findwidget.qrc
new file mode 100644
index 0000000..1d45b25
--- /dev/null
+++ b/tools/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/tools/shared/findwidget/images/mac/closetab.png b/tools/shared/findwidget/images/mac/closetab.png
new file mode 100644
index 0000000..ab9d669
--- /dev/null
+++ b/tools/shared/findwidget/images/mac/closetab.png
Binary files differ
diff --git a/tools/shared/findwidget/images/mac/next.png b/tools/shared/findwidget/images/mac/next.png
new file mode 100644
index 0000000..a585cab
--- /dev/null
+++ b/tools/shared/findwidget/images/mac/next.png
Binary files differ
diff --git a/tools/shared/findwidget/images/mac/previous.png b/tools/shared/findwidget/images/mac/previous.png
new file mode 100644
index 0000000..612fb34
--- /dev/null
+++ b/tools/shared/findwidget/images/mac/previous.png
Binary files differ
diff --git a/tools/shared/findwidget/images/mac/searchfind.png b/tools/shared/findwidget/images/mac/searchfind.png
new file mode 100644
index 0000000..3561745
--- /dev/null
+++ b/tools/shared/findwidget/images/mac/searchfind.png
Binary files differ
diff --git a/tools/shared/findwidget/images/win/closetab.png b/tools/shared/findwidget/images/win/closetab.png
new file mode 100644
index 0000000..ef9e020
--- /dev/null
+++ b/tools/shared/findwidget/images/win/closetab.png
Binary files differ
diff --git a/tools/shared/findwidget/images/win/next.png b/tools/shared/findwidget/images/win/next.png
new file mode 100644
index 0000000..8df4127
--- /dev/null
+++ b/tools/shared/findwidget/images/win/next.png
Binary files differ
diff --git a/tools/shared/findwidget/images/win/previous.png b/tools/shared/findwidget/images/win/previous.png
new file mode 100644
index 0000000..0780bc2
--- /dev/null
+++ b/tools/shared/findwidget/images/win/previous.png
Binary files differ
diff --git a/tools/shared/findwidget/images/win/searchfind.png b/tools/shared/findwidget/images/win/searchfind.png
new file mode 100644
index 0000000..6ea35e9
--- /dev/null
+++ b/tools/shared/findwidget/images/win/searchfind.png
Binary files differ
diff --git a/tools/shared/findwidget/images/wrap.png b/tools/shared/findwidget/images/wrap.png
new file mode 100644
index 0000000..90f18d9
--- /dev/null
+++ b/tools/shared/findwidget/images/wrap.png
Binary files differ
diff --git a/tools/shared/findwidget/itemviewfindwidget.cpp b/tools/shared/findwidget/itemviewfindwidget.cpp
new file mode 100644
index 0000000..e1f8468
--- /dev/null
+++ b/tools/shared/findwidget/itemviewfindwidget.cpp
@@ -0,0 +1,317 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@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/tools/shared/findwidget/itemviewfindwidget.h b/tools/shared/findwidget/itemviewfindwidget.h
new file mode 100644
index 0000000..71bb8f6
--- /dev/null
+++ b/tools/shared/findwidget/itemviewfindwidget.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@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:
+ 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/tools/shared/findwidget/texteditfindwidget.cpp b/tools/shared/findwidget/texteditfindwidget.cpp
new file mode 100644
index 0000000..73100f5
--- /dev/null
+++ b/tools/shared/findwidget/texteditfindwidget.cpp
@@ -0,0 +1,169 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@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/tools/shared/findwidget/texteditfindwidget.h b/tools/shared/findwidget/texteditfindwidget.h
new file mode 100644
index 0000000..4074ff0
--- /dev/null
+++ b/tools/shared/findwidget/texteditfindwidget.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@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:
+ 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/tools/shared/fontpanel/fontpanel.cpp b/tools/shared/fontpanel/fontpanel.cpp
new file mode 100644
index 0000000..4545baa
--- /dev/null
+++ b/tools/shared/fontpanel/fontpanel.cpp
@@ -0,0 +1,304 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@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();
+ rc.setItalic(m_fontDatabase.italic(family, styleDescription));
+
+ 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 (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/tools/shared/fontpanel/fontpanel.h b/tools/shared/fontpanel/fontpanel.h
new file mode 100644
index 0000000..0f542c6
--- /dev/null
+++ b/tools/shared/fontpanel/fontpanel.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@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/tools/shared/fontpanel/fontpanel.pri b/tools/shared/fontpanel/fontpanel.pri
new file mode 100644
index 0000000..9504853
--- /dev/null
+++ b/tools/shared/fontpanel/fontpanel.pri
@@ -0,0 +1,3 @@
+INCLUDEPATH += $$PWD
+HEADERS += $$PWD/fontpanel.h
+SOURCES += $$PWD/fontpanel.cpp
diff --git a/tools/shared/qtgradienteditor/images/down.png b/tools/shared/qtgradienteditor/images/down.png
new file mode 100644
index 0000000..29d1d44
--- /dev/null
+++ b/tools/shared/qtgradienteditor/images/down.png
Binary files differ
diff --git a/tools/shared/qtgradienteditor/images/edit.png b/tools/shared/qtgradienteditor/images/edit.png
new file mode 100644
index 0000000..4231bd9
--- /dev/null
+++ b/tools/shared/qtgradienteditor/images/edit.png
Binary files differ
diff --git a/tools/shared/qtgradienteditor/images/editdelete.png b/tools/shared/qtgradienteditor/images/editdelete.png
new file mode 100644
index 0000000..df2a147
--- /dev/null
+++ b/tools/shared/qtgradienteditor/images/editdelete.png
Binary files differ
diff --git a/tools/shared/qtgradienteditor/images/minus.png b/tools/shared/qtgradienteditor/images/minus.png
new file mode 100644
index 0000000..d6f233d
--- /dev/null
+++ b/tools/shared/qtgradienteditor/images/minus.png
Binary files differ
diff --git a/tools/shared/qtgradienteditor/images/plus.png b/tools/shared/qtgradienteditor/images/plus.png
new file mode 100644
index 0000000..40df113
--- /dev/null
+++ b/tools/shared/qtgradienteditor/images/plus.png
Binary files differ
diff --git a/tools/shared/qtgradienteditor/images/spreadpad.png b/tools/shared/qtgradienteditor/images/spreadpad.png
new file mode 100644
index 0000000..104c0a2
--- /dev/null
+++ b/tools/shared/qtgradienteditor/images/spreadpad.png
Binary files differ
diff --git a/tools/shared/qtgradienteditor/images/spreadreflect.png b/tools/shared/qtgradienteditor/images/spreadreflect.png
new file mode 100644
index 0000000..17b82b7
--- /dev/null
+++ b/tools/shared/qtgradienteditor/images/spreadreflect.png
Binary files differ
diff --git a/tools/shared/qtgradienteditor/images/spreadrepeat.png b/tools/shared/qtgradienteditor/images/spreadrepeat.png
new file mode 100644
index 0000000..7aea898
--- /dev/null
+++ b/tools/shared/qtgradienteditor/images/spreadrepeat.png
Binary files differ
diff --git a/tools/shared/qtgradienteditor/images/typeconical.png b/tools/shared/qtgradienteditor/images/typeconical.png
new file mode 100644
index 0000000..5479811
--- /dev/null
+++ b/tools/shared/qtgradienteditor/images/typeconical.png
Binary files differ
diff --git a/tools/shared/qtgradienteditor/images/typelinear.png b/tools/shared/qtgradienteditor/images/typelinear.png
new file mode 100644
index 0000000..dbd8a1f
--- /dev/null
+++ b/tools/shared/qtgradienteditor/images/typelinear.png
Binary files differ
diff --git a/tools/shared/qtgradienteditor/images/typeradial.png b/tools/shared/qtgradienteditor/images/typeradial.png
new file mode 100644
index 0000000..dc5888d
--- /dev/null
+++ b/tools/shared/qtgradienteditor/images/typeradial.png
Binary files differ
diff --git a/tools/shared/qtgradienteditor/images/up.png b/tools/shared/qtgradienteditor/images/up.png
new file mode 100644
index 0000000..e437312
--- /dev/null
+++ b/tools/shared/qtgradienteditor/images/up.png
Binary files differ
diff --git a/tools/shared/qtgradienteditor/images/zoomin.png b/tools/shared/qtgradienteditor/images/zoomin.png
new file mode 100644
index 0000000..2e586fc
--- /dev/null
+++ b/tools/shared/qtgradienteditor/images/zoomin.png
Binary files differ
diff --git a/tools/shared/qtgradienteditor/images/zoomout.png b/tools/shared/qtgradienteditor/images/zoomout.png
new file mode 100644
index 0000000..a736d39
--- /dev/null
+++ b/tools/shared/qtgradienteditor/images/zoomout.png
Binary files differ
diff --git a/tools/shared/qtgradienteditor/qtcolorbutton.cpp b/tools/shared/qtgradienteditor/qtcolorbutton.cpp
new file mode 100644
index 0000000..6926f60
--- /dev/null
+++ b/tools/shared/qtgradienteditor/qtcolorbutton.cpp
@@ -0,0 +1,278 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@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()
+{
+ bool ok;
+ const QRgb rgba = QColorDialog::getRgba(m_color.rgba(), &ok, q_ptr);
+ if (!ok)
+ return;
+ const QColor c = QColor::fromRgba(rgba);
+ if (c == q_ptr->color())
+ return;
+ q_ptr->setColor(c);
+ 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()
+{
+ delete d_ptr;
+}
+
+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/tools/shared/qtgradienteditor/qtcolorbutton.h b/tools/shared/qtgradienteditor/qtcolorbutton.h
new file mode 100644
index 0000000..fb91452
--- /dev/null
+++ b/tools/shared/qtgradienteditor/qtcolorbutton.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@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:
+ 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/tools/shared/qtgradienteditor/qtcolorbutton.pri b/tools/shared/qtgradienteditor/qtcolorbutton.pri
new file mode 100644
index 0000000..0e41068
--- /dev/null
+++ b/tools/shared/qtgradienteditor/qtcolorbutton.pri
@@ -0,0 +1,4 @@
+INCLUDEPATH += $$PWD
+DEPENDPATH += $$PWD
+SOURCES += $$PWD/qtcolorbutton.cpp
+HEADERS += $$PWD/qtcolorbutton.h
diff --git a/tools/shared/qtgradienteditor/qtcolorline.cpp b/tools/shared/qtgradienteditor/qtcolorline.cpp
new file mode 100644
index 0000000..337726c
--- /dev/null
+++ b/tools/shared/qtgradienteditor/qtcolorline.cpp
@@ -0,0 +1,1124 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@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()
+{
+ delete d_ptr;
+}
+
+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/tools/shared/qtgradienteditor/qtcolorline.h b/tools/shared/qtgradienteditor/qtcolorline.h
new file mode 100644
index 0000000..d5535b1
--- /dev/null
+++ b/tools/shared/qtgradienteditor/qtcolorline.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@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:
+
+ class QtColorLinePrivate *d_ptr;
+ Q_DECLARE_PRIVATE(QtColorLine)
+ Q_DISABLE_COPY(QtColorLine)
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/shared/qtgradienteditor/qtgradientdialog.cpp b/tools/shared/qtgradienteditor/qtgradientdialog.cpp
new file mode 100644
index 0000000..032cb16
--- /dev/null
+++ b/tools/shared/qtgradienteditor/qtgradientdialog.cpp
@@ -0,0 +1,359 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+TRANSLATOR qdesigner_internal::QtGradientDialog
+*/
+
+#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)
+{
+// setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+ d_ptr = new QtGradientDialogPrivate();
+ 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()
+{
+ delete d_ptr;
+}
+
+/*!
+ \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/tools/shared/qtgradienteditor/qtgradientdialog.h b/tools/shared/qtgradienteditor/qtgradientdialog.h
new file mode 100644
index 0000000..d3bafc9
--- /dev/null
+++ b/tools/shared/qtgradienteditor/qtgradientdialog.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@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:
+ 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/tools/shared/qtgradienteditor/qtgradientdialog.ui b/tools/shared/qtgradienteditor/qtgradientdialog.ui
new file mode 100644
index 0000000..0b3db0b
--- /dev/null
+++ b/tools/shared/qtgradienteditor/qtgradientdialog.ui
@@ -0,0 +1,121 @@
+<ui version="4.0" >
+ <comment>*********************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@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/tools/shared/qtgradienteditor/qtgradienteditor.cpp b/tools/shared/qtgradienteditor/qtgradienteditor.cpp
new file mode 100644
index 0000000..9eca9d8
--- /dev/null
+++ b/tools/shared/qtgradienteditor/qtgradienteditor.cpp
@@ -0,0 +1,958 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+TRANSLATOR qdesigner_internal::QtGradientEditor
+*/
+
+#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(const QGradientStops &)),
+ this, SLOT(slotGradientStopsChanged(const 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(const QPointF &)),
+ this, SLOT(startLinearChanged(const QPointF &)));
+ connect(d_ptr->m_ui.gradientWidget, SIGNAL(endLinearChanged(const QPointF &)),
+ this, SLOT(endLinearChanged(const QPointF &)));
+ connect(d_ptr->m_ui.gradientWidget, SIGNAL(centralRadialChanged(const QPointF &)),
+ this, SLOT(centralRadialChanged(const QPointF &)));
+ connect(d_ptr->m_ui.gradientWidget, SIGNAL(focalRadialChanged(const QPointF &)),
+ this, SLOT(focalRadialChanged(const QPointF &)));
+ connect(d_ptr->m_ui.gradientWidget, SIGNAL(radiusRadialChanged(qreal)),
+ this, SLOT(radiusRadialChanged(qreal)));
+ connect(d_ptr->m_ui.gradientWidget, SIGNAL(centralConicalChanged(const QPointF &)),
+ this, SLOT(centralConicalChanged(const 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;
+ delete d_ptr;
+}
+
+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/tools/shared/qtgradienteditor/qtgradienteditor.h b/tools/shared/qtgradienteditor/qtgradienteditor.h
new file mode 100644
index 0000000..9974065
--- /dev/null
+++ b/tools/shared/qtgradienteditor/qtgradienteditor.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@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:
+ 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/tools/shared/qtgradienteditor/qtgradienteditor.pri b/tools/shared/qtgradienteditor/qtgradienteditor.pri
new file mode 100644
index 0000000..4cf059e
--- /dev/null
+++ b/tools/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/tools/shared/qtgradienteditor/qtgradienteditor.qrc b/tools/shared/qtgradienteditor/qtgradienteditor.qrc
new file mode 100644
index 0000000..cce7ba6
--- /dev/null
+++ b/tools/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/tools/shared/qtgradienteditor/qtgradienteditor.ui b/tools/shared/qtgradienteditor/qtgradienteditor.ui
new file mode 100644
index 0000000..4d103e3
--- /dev/null
+++ b/tools/shared/qtgradienteditor/qtgradienteditor.ui
@@ -0,0 +1,1377 @@
+<ui version="4.0" >
+ <comment>*********************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@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/tools/shared/qtgradienteditor/qtgradientmanager.cpp b/tools/shared/qtgradienteditor/qtgradientmanager.cpp
new file mode 100644
index 0000000..51b5d96
--- /dev/null
+++ b/tools/shared/qtgradienteditor/qtgradientmanager.cpp
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@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/tools/shared/qtgradienteditor/qtgradientmanager.h b/tools/shared/qtgradienteditor/qtgradientmanager.h
new file mode 100644
index 0000000..ff9ebf7
--- /dev/null
+++ b/tools/shared/qtgradienteditor/qtgradientmanager.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@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/tools/shared/qtgradienteditor/qtgradientstopscontroller.cpp b/tools/shared/qtgradienteditor/qtgradientstopscontroller.cpp
new file mode 100644
index 0000000..cbc53db
--- /dev/null
+++ b/tools/shared/qtgradienteditor/qtgradientstopscontroller.cpp
@@ -0,0 +1,730 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+TRANSLATOR qdesigner_internal::QtGradientStopsController
+*/
+
+#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 *, const QColor &)),
+ this, SLOT(slotStopChanged(QtGradientStop *, const 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(const QColor &)),
+ this, SLOT(slotChangeHue(const QColor &)));
+ connect(d_ptr->m_ui->saturationColorLine, SIGNAL(colorChanged(const QColor &)),
+ this, SLOT(slotChangeSaturation(const QColor &)));
+ connect(d_ptr->m_ui->valueColorLine, SIGNAL(colorChanged(const QColor &)),
+ this, SLOT(slotChangeValue(const QColor &)));
+ connect(d_ptr->m_ui->alphaColorLine, SIGNAL(colorChanged(const QColor &)),
+ this, SLOT(slotChangeAlpha(const QColor &)));
+ connect(d_ptr->m_ui->colorButton, SIGNAL(colorChanged(const QColor &)),
+ this, SLOT(slotChangeColor(const 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()
+{
+ delete d_ptr;
+}
+
+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/tools/shared/qtgradienteditor/qtgradientstopscontroller.h b/tools/shared/qtgradienteditor/qtgradientstopscontroller.h
new file mode 100644
index 0000000..9f16fb0
--- /dev/null
+++ b/tools/shared/qtgradienteditor/qtgradientstopscontroller.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@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:
+ 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/tools/shared/qtgradienteditor/qtgradientstopsmodel.cpp b/tools/shared/qtgradienteditor/qtgradientstopsmodel.cpp
new file mode 100644
index 0000000..a632c0f
--- /dev/null
+++ b/tools/shared/qtgradienteditor/qtgradientstopsmodel.cpp
@@ -0,0 +1,480 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@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()
+{
+ delete d_ptr;
+}
+
+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();
+ delete d_ptr;
+}
+
+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/tools/shared/qtgradienteditor/qtgradientstopsmodel.h b/tools/shared/qtgradienteditor/qtgradientstopsmodel.h
new file mode 100644
index 0000000..d4e6b3c
--- /dev/null
+++ b/tools/shared/qtgradienteditor/qtgradientstopsmodel.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@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();
+ 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:
+ class QtGradientStopsModelPrivate *d_ptr;
+ Q_DECLARE_PRIVATE(QtGradientStopsModel)
+ Q_DISABLE_COPY(QtGradientStopsModel)
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/shared/qtgradienteditor/qtgradientstopswidget.cpp b/tools/shared/qtgradienteditor/qtgradientstopswidget.cpp
new file mode 100644