summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Kamm <christian.d.kamm@nokia.com>2010-02-26 09:40:50 +0100
committerChristian Kamm <christian.d.kamm@nokia.com>2010-02-26 09:40:50 +0100
commit40c3f2af63cd3c584f355e49d1b2b19be579ce60 (patch)
tree13a37759f849b9b9a30c8462e112cca4a75941cc
Initial version of the remote control widget.
-rw-r--r--example/example.pro16
-rw-r--r--example/main.cpp13
-rw-r--r--library/locationui.cpp76
-rw-r--r--library/locationui.h34
-rw-r--r--library/optionsitem.cpp149
-rw-r--r--library/optionsitem.h63
-rw-r--r--library/remotecontrolwidget.cpp182
-rw-r--r--library/remotecontrolwidget.h50
-rw-r--r--library/remotecontrolwidget.pro41
-rw-r--r--library/remotecontrolwidget_global.h12
-rw-r--r--library/style/fancylineedit.cpp315
-rw-r--r--library/style/fancylineedit.h108
-rw-r--r--library/style/filterlineedit.cpp51
-rw-r--r--library/style/filterlineedit.h53
-rw-r--r--library/style/images/advanced.pngbin0 -> 1201 bytes
-rw-r--r--library/style/images/closebutton.pngbin0 -> 2106 bytes
-rw-r--r--library/style/images/favoriteScripts.pngbin0 -> 516 bytes
-rw-r--r--library/style/images/reset.pngbin0 -> 184 bytes
-rw-r--r--library/style/manhattanstyle.cpp1187
-rw-r--r--library/style/manhattanstyle.h94
-rw-r--r--library/style/qtcassert.h45
-rw-r--r--library/style/style.pri16
-rw-r--r--library/style/style.qrc8
-rw-r--r--library/style/styleanimator.cpp154
-rw-r--r--library/style/styleanimator.h101
-rw-r--r--library/style/styledbar.cpp93
-rw-r--r--library/style/styledbar.h57
-rw-r--r--library/style/stylehelper.cpp296
-rw-r--r--library/style/stylehelper.h77
-rw-r--r--library/toolbox.cpp366
-rw-r--r--library/toolbox.h92
31 files changed, 3749 insertions, 0 deletions
diff --git a/example/example.pro b/example/example.pro
new file mode 100644
index 0000000..9b8f895
--- /dev/null
+++ b/example/example.pro
@@ -0,0 +1,16 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2010-02-25T15:28:57
+#
+#-------------------------------------------------
+
+QT += core gui
+
+TARGET = example
+TEMPLATE = app
+
+INCLUDEPATH += ../library
+LIBS += -L../library -lremotecontrolwidget -Wl,-rpath=../library
+
+SOURCES += main.cpp
+
diff --git a/example/main.cpp b/example/main.cpp
new file mode 100644
index 0000000..1274a5b
--- /dev/null
+++ b/example/main.cpp
@@ -0,0 +1,13 @@
+#include <QtGui/QApplication>
+#include "remotecontrolwidget.h"
+#include "locationui.h"
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+ RemoteControlWidget w;
+ LocationUi l(&w);
+
+ w.show();
+ return a.exec();
+}
diff --git a/library/locationui.cpp b/library/locationui.cpp
new file mode 100644
index 0000000..4d1f6ff
--- /dev/null
+++ b/library/locationui.cpp
@@ -0,0 +1,76 @@
+#include "locationui.h"
+
+#include "optionsitem.h"
+#include "remotecontrolwidget.h"
+
+#include <QtGui/QLineEdit>
+#include <QtGui/QDoubleValidator>
+#include <QtGui/QPushButton>
+#include <QtGui/QBoxLayout>
+#include <QtGui/QDateTimeEdit>
+
+LocationUi::LocationUi(RemoteControlWidget *w)
+ : QObject(w)
+ , mLatitudeEdit(0)
+ , mLongitudeEdit(0)
+ , mAltitudeEdit(0)
+ , mTimeEdit(0)
+{
+ QStringList tags;
+ QList<OptionsItem *> optionsList;
+
+ mLatitudeEdit = new QLineEdit("52.5056819");
+ mLatitudeEdit->setValidator(new QDoubleValidator(-90, 90, 10, this));
+ OptionsItem *item = new OptionsItem(tr("Latitude"), mLatitudeEdit);
+ //connect(mLatitudeEdit, SIGNAL(editingFinished()), SLOT(triggerLocationInfoChange()));
+ item->setTags(tags);
+ optionsList << item;
+
+ mLongitudeEdit = new QLineEdit("13.3232027");
+ mLatitudeEdit->setValidator(new QDoubleValidator(-180, 180, 10, this));
+ item = new OptionsItem(tr("Longitude"), mLongitudeEdit);
+ //connect(mLongitudeEdit, SIGNAL(editingFinished()), SLOT(triggerLocationInfoChange()));
+ item->setTags(tags);
+ optionsList << item;
+
+ mAltitudeEdit = new QLineEdit("13.3232027");
+ mAltitudeEdit->setValidator(new QDoubleValidator(-15000, 15000, 10, this));
+ item = new OptionsItem(tr("Altitude"), mAltitudeEdit);
+ //connect(mAltitudeEdit, SIGNAL(editingFinished()), SLOT(triggerLocationInfoChange()));
+ item->setTags(tags);
+ optionsList << item;
+
+ mTimeEdit = new QDateTimeEdit();
+ QPushButton *locationTimeButton = new QPushButton(tr("Now"));
+ QHBoxLayout *hLayout = new QHBoxLayout();
+ hLayout->setContentsMargins(0, 0, 0, 0);
+ QVBoxLayout *vLayout = new QVBoxLayout();
+ vLayout->addWidget(mTimeEdit);
+ vLayout->addWidget(locationTimeButton);
+ hLayout->addLayout(vLayout);
+ QWidget *tmp = new QWidget();
+ tmp->setLayout(hLayout);
+ //connect(mTimeEdit, SIGNAL(dateTimeChanged(const QDateTime &)), SLOT(triggerLocationInfoChange()));
+ connect(locationTimeButton, SIGNAL(clicked()), this, SLOT(updateLocationTime()));
+ item = new OptionsItem(tr("Timestamp"), tmp);
+ item->setTags(tags);
+ optionsList << item;
+
+ w->addToolBoxPage(tr("Location"), optionsList);
+}
+
+void LocationUi::updateLocationTime()
+{
+ mTimeEdit->setDateTime(QDateTime::currentDateTime());
+}
+
+void LocationUi::setLocation()
+{
+ /*
+ mLatitudeEdit->setText(QString::number(mLocation->latitude(), 'f', 8));
+ mLongitudeEdit->setText(QString::number(mLocation->longitude(), 'f', 8));
+ mAltitudeEdit->setText(QString::number(mLocation->altitude(), 'f', 8));
+ mTimeEdit->setDateTime(mLocation->dateTime());
+ */
+}
+
diff --git a/library/locationui.h b/library/locationui.h
new file mode 100644
index 0000000..53d0d14
--- /dev/null
+++ b/library/locationui.h
@@ -0,0 +1,34 @@
+#ifndef LOCATIONUI_H
+#define LOCATIONUI_H
+
+#include "remotecontrolwidget_global.h"
+
+#include <QtCore/QObject>
+
+class RemoteControlWidget;
+class QLineEdit;
+class QDateTimeEdit;
+
+class REMOTECONTROLWIDGETSHARED_EXPORT LocationUi : public QObject
+{
+ Q_OBJECT
+public:
+ LocationUi(RemoteControlWidget* w);
+
+public slots:
+ void setLocation(/* LocationData */);
+
+signals:
+ void locationChanged(/* LocationData */);
+
+private slots:
+ void updateLocationTime();
+
+private:
+ QLineEdit *mLatitudeEdit;
+ QLineEdit *mLongitudeEdit;
+ QLineEdit *mAltitudeEdit;
+ QDateTimeEdit *mTimeEdit;
+};
+
+#endif // LOCATIONUI_H
diff --git a/library/optionsitem.cpp b/library/optionsitem.cpp
new file mode 100644
index 0000000..91d117d
--- /dev/null
+++ b/library/optionsitem.cpp
@@ -0,0 +1,149 @@
+#include "optionsitem.h"
+
+#include <QtCore/QString>
+#include <QtGui/QAbstractButton>
+#include <QtGui/QBoxLayout>
+#include <QtGui/QFormLayout>
+#include <QtGui/QLabel>
+
+OptionsItem::OptionsItem(const QString &name, QWidget *inputWidget, bool fullWidth, QObject *parent)
+ : QObject(parent)
+ , mLabel(0)
+ , mInputWidget(inputWidget)
+ , mAdvancedPage(0)
+ , mHidden(false)
+ , mAdvanced(false)
+{
+ if (fullWidth)
+ mType = FullWidthType;
+ else {
+ mType = DefaultType;
+
+ mInputLayout = new QHBoxLayout();
+ mInputLayout->addStretch();
+ mInputLayout->addWidget(mInputWidget);
+ }
+ if (name != 0 && !name.isEmpty())
+ mLabel = new QLabel(name);
+}
+
+OptionsItem::~OptionsItem()
+{}
+
+bool OptionsItem::addTag(const QString &tag)
+{
+ if (!mTags.contains(tag.toLower())) {
+ mTags.append(tag.toLower());
+ return true;
+ }
+ return false;
+}
+
+QLabel *OptionsItem::label() const
+{
+ return mLabel;
+}
+
+QWidget *OptionsItem::inputWidget() const
+{
+ return mInputWidget;
+}
+
+QHBoxLayout *OptionsItem::inputLayout() const
+{
+ return mInputLayout;
+}
+
+bool OptionsItem::setAdvancedPage(OptionsItem *advancedPage)
+{
+ QAbstractButton *inputButton = qobject_cast<QAbstractButton *>(mInputWidget);
+ if (!inputButton)
+ return false;
+ mAdvancedPage = advancedPage;
+ mType = AdvancedType;
+ mAdvancedPage->setTags(mTags);
+ mAdvancedPage->setVisible(false, true);
+ disconnect(inputButton, SIGNAL(clicked()), this, SLOT(buttonClicked()));
+ connect(inputButton, SIGNAL(clicked()), SLOT(buttonClicked()));
+ return true;
+}
+
+OptionsItem *OptionsItem::advancedPage() const
+{
+ return mAdvancedPage;
+}
+
+void OptionsItem::setVisible(bool visible, bool explicitly)
+{
+ if (mLabel)
+ mLabel->setVisible(visible);
+ mInputWidget->setVisible(visible);
+ if (!visible && explicitly)
+ mHidden = true;
+ else
+ mHidden = false;
+}
+
+bool OptionsItem::addTags(const QStringList &tags)
+{
+ bool ret = true;
+ foreach(const QString &tag, tags)
+ if (!addTag(tag))
+ ret = false;
+ return ret;
+}
+
+bool OptionsItem::removeTag(const QString &tag)
+{
+ return (mTags.removeAll(tag.toLower()) > 0);
+}
+
+bool OptionsItem::removeTags(const QStringList &tags)
+{
+ bool ret = true;
+ foreach (const QString &tag, tags)
+ if (!removeTag(tag))
+ ret = false;
+ return ret;
+}
+
+bool OptionsItem::setTags(const QStringList &tags)
+{
+ mTags.clear();
+ return addTags(tags);
+}
+
+bool OptionsItem::matchTag(const QString &tag) const
+{
+ if (mLabel && mLabel->text().toLower().contains(tag.toLower()))
+ return true;
+ foreach (const QString &tagInList, mTags)
+ if (tagInList.contains(tag.toLower()))
+ return true;
+ return false;
+}
+
+OptionsItem::OptionsType OptionsItem::type() const
+{
+ return mType;
+}
+
+bool OptionsItem::isExplicitlyHidden() const
+{
+ return mHidden;
+}
+
+void OptionsItem::setAdvanced(bool advanced)
+{
+ mAdvanced = advanced;
+}
+
+bool OptionsItem::isAdvanced() const
+{
+ return mAdvanced;
+}
+
+void OptionsItem::buttonClicked()
+{
+ emit toggleAdvanced(this);
+}
diff --git a/library/optionsitem.h b/library/optionsitem.h
new file mode 100644
index 0000000..e6130ca
--- /dev/null
+++ b/library/optionsitem.h
@@ -0,0 +1,63 @@
+#ifndef OPTIONSITEM_H
+#define OPTIONSITEM_H
+
+#include "remotecontrolwidget_global.h"
+
+#include <QtCore/QObject>
+#include <QtCore/QStringList>
+
+class QLayout;
+class QLabel;
+class QHBoxLayout;
+
+class REMOTECONTROLWIDGETSHARED_EXPORT OptionsItem: public QObject
+{
+ Q_OBJECT
+public:
+ enum OptionsType {
+ DefaultType,
+ FullWidthType,
+ AdvancedType
+ };
+
+ OptionsItem(const QString &name, QWidget *inputWidget, bool fullWidth = false, QObject *parent = 0);
+ virtual ~OptionsItem();
+
+ QLabel *label() const;
+ QWidget *inputWidget() const;
+ QHBoxLayout *inputLayout() const;
+
+ void setVisible(bool visible, bool explicitly = false);
+ bool setAdvancedPage(OptionsItem *advancedPage);
+ OptionsItem *advancedPage() const;
+
+ bool addTag(const QString &tag);
+ bool addTags(const QStringList &tags);
+ bool removeTag(const QString &tag);
+ bool removeTags(const QStringList &tags);
+ bool setTags(const QStringList &tags);
+ bool matchTag(const QString &tag) const;
+ OptionsType type() const;
+ bool isExplicitlyHidden() const;
+ void setAdvanced(bool advanced = true);
+ bool isAdvanced() const;
+
+private:
+ friend class ToolBoxPage;
+ QLabel *mLabel;
+ QWidget *mInputWidget;
+ QHBoxLayout *mInputLayout;
+ OptionsItem *mAdvancedPage;
+ QStringList mTags;
+ OptionsType mType;
+ bool mHidden;
+ bool mAdvanced;
+
+private slots:
+ void buttonClicked();
+
+signals:
+ void toggleAdvanced(OptionsItem *item);
+};
+
+#endif //OPTIONSITEM_H
diff --git a/library/remotecontrolwidget.cpp b/library/remotecontrolwidget.cpp
new file mode 100644
index 0000000..33adc40
--- /dev/null
+++ b/library/remotecontrolwidget.cpp
@@ -0,0 +1,182 @@
+#include "remotecontrolwidget.h"
+#include "toolbox.h"
+#include "optionsitem.h"
+#include "style/filterlineedit.h"
+#include "style/manhattanstyle.h"
+#include "style/styledbar.h"
+
+#include <qmath.h>
+#include <QtCore/QSettings>
+#include <QtCore/QThread>
+#include <QtCore/QDir>
+#include <QtGui/QApplication>
+#include <QtGui/QDesktopWidget>
+#include <QtGui/QScrollBar>
+#include <QtGui/QMessageBox>
+#include <QtGui/QToolButton>
+#include <QtGui/QCloseEvent>
+#include <QtGui/QScrollArea>
+#include <QtGui/QFrame>
+#include <QtGui/QBoxLayout>
+#include <QtGui/QLabel>
+
+RemoteControlWidget::RemoteControlWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ QString baseName = style()->objectName();
+#ifdef Q_WS_X11
+ if (baseName == QLatin1String("windows")) {
+ // Sometimes we get the standard windows 95 style as a fallback
+ // e.g. if we are running on a KDE4 desktop
+ QByteArray desktopEnvironment = qgetenv("DESKTOP_SESSION");
+ if (desktopEnvironment == "kde")
+ baseName = QLatin1String("plastique");
+ else
+ baseName = QLatin1String("cleanlooks");
+ }
+#endif
+ mManhattanStyle = new ManhattanStyle(baseName);
+
+ QVBoxLayout *mainLayout = new QVBoxLayout;
+ mainLayout->setMargin(0);
+ mainLayout->setSpacing(0);
+ setLayout(mainLayout);
+
+ StyledBar *menuBar = initializeMenuBar();
+ mainLayout->addWidget(menuBar);
+
+ QLabel *simulateLabel = new QLabel(tr("Simulate"));
+ QMargins labelMargins = simulateLabel->contentsMargins();
+ QFont labelFont = simulateLabel->font();
+ labelFont.setBold(true);
+ labelFont.setPointSize(11);
+ simulateLabel->setFont(labelFont);
+ simulateLabel->setStyle(mManhattanStyle);
+ QHBoxLayout *hLayout = new QHBoxLayout();
+ hLayout->setContentsMargins(9, 0, labelMargins.right(), 0);
+ hLayout->addWidget(simulateLabel);
+ StyledBar *simulateBar = new StyledBar();
+ simulateBar->setStyle(mManhattanStyle);
+ simulateBar->setLayout(hLayout);
+ mainLayout->addWidget(simulateBar);
+
+ QScrollArea *simulateArea = new QScrollArea;
+ simulateArea->setWidgetResizable(true);
+
+ mToolBox = new ToolBox(false);
+ mToolBox->setStyle(mManhattanStyle);
+ simulateArea->setWidget(mToolBox);
+ mainLayout->addWidget(simulateArea);
+
+ // Some styles have extra up/down buttons in the scrollbar. We only support
+ // the plain scrollbars and therefore force the style to be derived from cleanlooks for them.
+ QStyle *forceScrollbarStyle = new ManhattanStyle("cleanlooks");
+ simulateArea->setStyle(forceScrollbarStyle);
+ simulateArea->verticalScrollBar()->setStyle(forceScrollbarStyle);
+ simulateArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
+ simulateArea->verticalScrollBar()->setProperty("styledScrollBar", true);
+
+ mViewButton = new QToolButton();
+ mViewButton->setFont(labelFont);
+ mViewButton->setText(tr("View"));
+ mViewButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ mViewButton->setArrowType(Qt::RightArrow);
+ mViewButton->setSizePolicy(QSizePolicy::Expanding, mViewButton->sizePolicy().verticalPolicy());
+ mViewButton->setStyle(mManhattanStyle);
+ hLayout = new QHBoxLayout();
+ hLayout->setMargin(0);
+ hLayout->addWidget(mViewButton);
+ StyledBar *viewBar = new StyledBar();
+ viewBar->setStyle(mManhattanStyle);
+ viewBar->setLayout(hLayout);
+ mainLayout->addWidget(viewBar);
+ connect(mViewButton, SIGNAL(clicked()), SLOT(toggleViewPaneVisible()));
+
+ mViewArea = new QFrame();
+ initializeViewArea(mViewArea);
+ mainLayout->addWidget(mViewArea);
+}
+
+RemoteControlWidget::~RemoteControlWidget()
+{
+
+}
+
+void RemoteControlWidget::filtersChanged()
+{
+ mToolBox->filtersChanged(mFilterLineEdit->typedText());
+}
+
+void RemoteControlWidget::addToolBoxPage(const QString &title, const QList<OptionsItem *> &options)
+{
+ mToolBox->addPage(title, options);
+}
+
+void RemoteControlWidget::addMenuButton(QToolButton *button)
+{
+ mMenuLayout->addWidget(button);
+}
+
+void RemoteControlWidget::writeSettings(const QString &vendor, const QString &name) const
+{
+ QSettings settings(vendor, name);
+
+ settings.beginGroup("ConfigurationWidget");
+ settings.setValue("size", size());
+ settings.setValue("pos", pos());
+ settings.endGroup();
+}
+
+void RemoteControlWidget::readSettings(const QString &vendor, const QString &name)
+{
+ QSettings settings(vendor, name);
+
+ settings.beginGroup("ConfigurationWidget");
+ if (settings.contains("size"))
+ resize(settings.value("size").toSize());
+ if (settings.contains("pos"))
+ move(settings.value("pos").toPoint());
+ settings.endGroup();
+}
+
+void RemoteControlWidget::toggleViewPaneVisible()
+{
+ if (mViewArea->isHidden()) {
+ mViewArea->show();
+ mViewButton->setArrowType(Qt::RightArrow);
+ } else {
+ mViewArea->hide();
+ mViewButton->setArrowType(Qt::DownArrow);
+ }
+}
+
+StyledBar *RemoteControlWidget::initializeMenuBar()
+{
+ mMenuLayout = new QHBoxLayout;
+ mMenuLayout->setSpacing(0);
+ mMenuLayout->setMargin(0);
+
+ QHBoxLayout *toplayout = new QHBoxLayout;
+ toplayout->setSpacing(0);
+ toplayout->setMargin(0);
+ toplayout->addLayout(mMenuLayout);
+ toplayout->addStretch();
+ mFilterLineEdit = new FilterLineEdit();
+ mFilterLineEdit->setStyle(mManhattanStyle);
+ connect(mFilterLineEdit, SIGNAL(filterChanged(const QString &)), SLOT(filtersChanged()));
+ toplayout->addWidget(mFilterLineEdit);
+
+ StyledBar *bar = new StyledBar;
+ bar->setLayout(toplayout);
+ bar->setStyle(mManhattanStyle);
+ return bar;
+}
+
+void RemoteControlWidget::initializeViewArea(QFrame *f)
+{
+ QVBoxLayout *layout = new QVBoxLayout;
+ QLabel *test = new QLabel(f);
+ test->setText("Test!");
+ layout->addWidget(test);
+ f->setLayout(layout);
+}
diff --git a/library/remotecontrolwidget.h b/library/remotecontrolwidget.h
new file mode 100644
index 0000000..891dcd2
--- /dev/null
+++ b/library/remotecontrolwidget.h
@@ -0,0 +1,50 @@
+#ifndef CONFIGURATIONWIDGET_H
+#define CONFIGURATIONWIDGET_H
+
+#include "remotecontrolwidget_global.h"
+
+#include <QtGui/QWidget>
+
+class OptionsItem;
+class FilterLineEdit;
+class ToolBox;
+class StyledBar;
+class ManhattanStyle;
+class QToolButton;
+class QFrame;
+class QLayout;
+
+class REMOTECONTROLWIDGETSHARED_EXPORT RemoteControlWidget: public QWidget
+{
+ Q_OBJECT
+public:
+ explicit RemoteControlWidget(QWidget *parent = 0);
+ ~RemoteControlWidget();
+
+ virtual void writeSettings(const QString &vendor, const QString &name) const;
+ virtual void readSettings(const QString &vendor, const QString &name);
+
+ void addToolBoxPage(const QString &title, const QList<OptionsItem *> &options);
+ void addMenuButton(QToolButton *button);
+
+protected:
+ virtual void initializeViewArea(QFrame *target);
+
+private slots:
+ void filtersChanged();
+ void toggleViewPaneVisible();
+
+private:
+ StyledBar *initializeMenuBar();
+
+private:
+ ToolBox *mToolBox;
+ FilterLineEdit *mFilterLineEdit;
+ QLayout *mMenuLayout;
+ QToolButton *mViewButton;
+ QFrame *mViewArea;
+
+ ManhattanStyle *mManhattanStyle;
+};
+
+#endif //CONFIGURATIONWIDGET_H
diff --git a/library/remotecontrolwidget.pro b/library/remotecontrolwidget.pro
new file mode 100644
index 0000000..f3cc3eb
--- /dev/null
+++ b/library/remotecontrolwidget.pro
@@ -0,0 +1,41 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2010-02-25T14:32:24
+#
+#-------------------------------------------------
+
+TARGET = remotecontrolwidget
+TEMPLATE = lib
+
+CONFIG += hide_symbols
+
+DEFINES += REMOTECONTROLWIDGET_LIBRARY
+
+SOURCES += \
+ remotecontrolwidget.cpp \
+ toolbox.cpp \
+ optionsitem.cpp \
+ locationui.cpp \
+ style/stylehelper.cpp \
+ style/styledbar.cpp \
+ style/styleanimator.cpp \
+ style/manhattanstyle.cpp \
+ style/filterlineedit.cpp \
+ style/fancylineedit.cpp
+
+HEADERS += \
+ remotecontrolwidget.h \
+ remotecontrolwidget_global.h \
+ toolbox.h \
+ optionsitem.h \
+ locationui.h \
+ style/styledbar.h \
+ style/styleanimator.h \
+ style/qtcassert.h \
+ style/manhattanstyle.h \
+ style/filterlineedit.h \
+ style/fancylineedit.h \
+ style/stylehelper.h
+
+RESOURCES += \
+ style/style.qrc
diff --git a/library/remotecontrolwidget_global.h b/library/remotecontrolwidget_global.h
new file mode 100644
index 0000000..a6223ce
--- /dev/null
+++ b/library/remotecontrolwidget_global.h
@@ -0,0 +1,12 @@
+#ifndef REMOTECONTROLWIDGET_GLOBAL_H
+#define REMOTECONTROLWIDGET_GLOBAL_H
+
+#include <QtCore/qglobal.h>
+
+#if defined(REMOTECONTROLWIDGET_LIBRARY)
+# define REMOTECONTROLWIDGETSHARED_EXPORT Q_DECL_EXPORT
+#else
+# define REMOTECONTROLWIDGETSHARED_EXPORT Q_DECL_IMPORT
+#endif
+
+#endif // REMOTECONTROLWIDGET_GLOBAL_H
diff --git a/library/style/fancylineedit.cpp b/library/style/fancylineedit.cpp
new file mode 100644
index 0000000..f326770
--- /dev/null
+++ b/library/style/fancylineedit.cpp
@@ -0,0 +1,315 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "fancylineedit.h"
+
+#include <QtCore/QEvent>
+#include <QtCore/QDebug>
+#include <QtCore/QString>
+#include <QtGui/QApplication>
+#include <QtGui/QMenu>
+#include <QtGui/QMouseEvent>
+#include <QtGui/QLabel>
+
+enum { margin = 6 };
+
+static inline QString sideToStyleSheetString(FancyLineEdit::Side side)
+{
+ return side == FancyLineEdit::Left ? QLatin1String("left") : QLatin1String("right");
+}
+
+// Format style sheet for the label containing the pixmap. It has a margin on
+// the outer side of the whole FancyLineEdit.
+static QString labelStyleSheet(FancyLineEdit::Side side)
+{
+ QString rc = QLatin1String("QLabel { margin-");
+ rc += sideToStyleSheetString(side);
+ rc += QLatin1String(": ");
+ rc += QString::number(margin);
+ rc += QLatin1Char('}');
+ return rc;
+}
+
+// --------- FancyLineEditPrivate as QObject with label
+// event filter
+
+class FancyLineEditPrivate : public QObject {
+public:
+ explicit FancyLineEditPrivate(FancyLineEdit *parent);
+
+ virtual bool eventFilter(QObject *obj, QEvent *event);
+
+ const QString m_leftLabelStyleSheet;
+ const QString m_rightLabelStyleSheet;
+
+ FancyLineEdit *m_lineEdit;
+ QPixmap m_pixmap;
+ QMenu *m_menu;
+ QLabel *m_menuLabel;
+ FancyLineEdit::Side m_side;
+ bool m_useLayoutDirection;
+ bool m_menuTabFocusTrigger;
+ QString m_hintText;
+ bool m_showingHintText;
+};
+
+
+FancyLineEditPrivate::FancyLineEditPrivate(FancyLineEdit *parent) :
+ QObject(parent),
+ m_leftLabelStyleSheet(labelStyleSheet(FancyLineEdit::Left)),
+ m_rightLabelStyleSheet(labelStyleSheet(FancyLineEdit::Right)),
+ m_lineEdit(parent),
+ m_menu(0),
+ m_menuLabel(0),
+ m_side(FancyLineEdit::Left),
+ m_useLayoutDirection(false),
+ m_menuTabFocusTrigger(false),
+ m_showingHintText(false)
+{
+}
+
+bool FancyLineEditPrivate::eventFilter(QObject *obj, QEvent *event)
+{
+ if (obj != m_menuLabel)
+ return QObject::eventFilter(obj, event);
+
+ switch (event->type()) {
+ case QEvent::MouseButtonPress: {
+ const QMouseEvent *me = static_cast<QMouseEvent *>(event);
+ if (m_menu) {
+ m_menu->exec(me->globalPos());
+ } else {
+ emit m_lineEdit->buttonClicked();
+ }
+ return true;
+ }
+ case QEvent::FocusIn:
+ if (m_menuTabFocusTrigger && m_menu) {
+ m_lineEdit->setFocus();
+ m_menu->exec(m_menuLabel->mapToGlobal(m_menuLabel->rect().center()));
+ return true;
+ }
+ default:
+ break;
+ }
+ return QObject::eventFilter(obj, event);
+}
+
+// --------- FancyLineEdit
+FancyLineEdit::FancyLineEdit(QWidget *parent) :
+ QLineEdit(parent),
+ m_d(new FancyLineEditPrivate(this))
+{
+ m_d->m_menuLabel = new QLabel(this);
+ m_d->m_menuLabel->installEventFilter(m_d);
+ updateMenuLabel();
+ showHintText();
+}
+
+FancyLineEdit::~FancyLineEdit()
+{
+}
+
+// Position the menu label left or right according to size.
+// Called when switching side and from resizeEvent.
+void FancyLineEdit::positionMenuLabel()
+{
+ switch (side()) {
+ case Left:
+ m_d->m_menuLabel->setGeometry(0, 0, m_d->m_pixmap.width()+margin, height());
+ break;
+ case Right:
+ m_d->m_menuLabel->setGeometry(width() - m_d->m_pixmap.width() - margin, 0,
+ m_d->m_pixmap.width()+margin, height());
+ break;
+ }
+}
+
+void FancyLineEdit::updateStyleSheet(Side side)
+{
+ // Udate the LineEdit style sheet. Make room for the label on the
+ // respective side and set color according to whether we are showing the
+ // hint text
+ QString sheet = QLatin1String("QLineEdit{ padding-");
+ sheet += sideToStyleSheetString(side);
+ sheet += QLatin1String(": ");
+ sheet += QString::number(m_d->m_pixmap.width() + margin);
+ sheet += QLatin1Char(';');
+ if (m_d->m_showingHintText)
+ sheet += QLatin1String(" color: #BBBBBB;");
+ // Fix the stylesheet's clearing the size hint.
+ sheet += QLatin1String(" height: ");
+ sheet += QString::number(sizeHint().height());
+ sheet += QLatin1Char('}');
+ setStyleSheet(sheet);
+}
+
+void FancyLineEdit::updateMenuLabel()
+{
+ m_d->m_menuLabel->setPixmap(m_d->m_pixmap);
+ const Side s = side();
+ switch (s) {
+ case Left:
+ m_d->m_menuLabel->setAlignment(Qt::AlignVCenter | Qt::AlignLeft);
+ m_d->m_menuLabel->setStyleSheet(m_d->m_leftLabelStyleSheet);
+ break;
+ case Right:
+ m_d->m_menuLabel->setAlignment(Qt::AlignVCenter | Qt::AlignRight);
+ m_d->m_menuLabel->setStyleSheet(m_d->m_rightLabelStyleSheet);
+ break;
+ }
+ updateStyleSheet(s);
+ positionMenuLabel();
+}
+
+void FancyLineEdit::setSide(Side side)
+{
+ m_d->m_side = side;
+ updateMenuLabel();
+}
+
+FancyLineEdit::Side FancyLineEdit::side() const
+{
+ if (m_d->m_useLayoutDirection)
+ return qApp->layoutDirection() == Qt::LeftToRight ? Left : Right;
+ return m_d->m_side;
+}
+
+void FancyLineEdit::resizeEvent(QResizeEvent *)
+{
+ positionMenuLabel();
+}
+
+void FancyLineEdit::setPixmap(const QPixmap &pixmap)
+{
+ m_d->m_pixmap = pixmap;
+ updateMenuLabel();
+}
+
+QPixmap FancyLineEdit::pixmap() const
+{
+ return m_d->m_pixmap;
+}
+
+void FancyLineEdit::setMenu(QMenu *menu)
+{
+ m_d->m_menu = menu;
+}
+
+QMenu *FancyLineEdit::menu() const
+{
+ return m_d->m_menu;
+}
+
+bool FancyLineEdit::useLayoutDirection() const
+{
+ return m_d->m_useLayoutDirection;
+}
+
+void FancyLineEdit::setUseLayoutDirection(bool v)
+{
+ m_d->m_useLayoutDirection = v;
+}
+
+bool FancyLineEdit::isSideStored() const
+{
+ return !m_d->m_useLayoutDirection;
+}
+
+bool FancyLineEdit::hasMenuTabFocusTrigger() const
+{
+ return m_d->m_menuTabFocusTrigger;
+}
+
+void FancyLineEdit::setMenuTabFocusTrigger(bool v)
+{
+ if (m_d->m_menuTabFocusTrigger == v)
+ return;
+
+ m_d->m_menuTabFocusTrigger = v;
+ m_d->m_menuLabel->setFocusPolicy(v ? Qt::TabFocus : Qt::NoFocus);
+}
+
+QString FancyLineEdit::hintText() const
+{
+ return m_d->m_hintText;
+}
+
+void FancyLineEdit::setHintText(const QString &ht)
+{
+ // Updating magic to make the property work in Designer.
+ if (ht == m_d->m_hintText)
+ return;
+ hideHintText();
+ m_d->m_hintText = ht;
+ if (!hasFocus() && !ht.isEmpty())
+ showHintText();
+}
+
+void FancyLineEdit::showHintText()
+{
+ if (!m_d->m_showingHintText && text().isEmpty() && !m_d->m_hintText.isEmpty()) {
+ m_d->m_showingHintText = true;
+ setText(m_d->m_hintText);
+ updateStyleSheet(side());
+ }
+}
+
+void FancyLineEdit::hideHintText()
+{
+ if (m_d->m_showingHintText && !m_d->m_hintText.isEmpty()) {
+ m_d->m_showingHintText = false;
+ setText(QString());
+ updateStyleSheet(side());
+ }
+}
+
+void FancyLineEdit::focusInEvent(QFocusEvent *e)
+{
+ hideHintText();
+ QLineEdit::focusInEvent(e);
+}
+
+void FancyLineEdit::focusOutEvent(QFocusEvent *e)
+{
+ // Focus out: Switch to displaying the hint text unless
+ // there is user input
+ showHintText();
+ QLineEdit::focusOutEvent(e);
+}
+
+bool FancyLineEdit::isShowingHintText() const
+{
+ return m_d->m_showingHintText;
+}
+
+QString FancyLineEdit::typedText() const
+{
+ return m_d->m_showingHintText ? QString() : text();
+}
diff --git a/library/style/fancylineedit.h b/library/style/fancylineedit.h
new file mode 100644
index 0000000..01978e0
--- /dev/null
+++ b/library/style/fancylineedit.h
@@ -0,0 +1,108 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef FANCYLINEEDIT_H
+#define FANCYLINEEDIT_H
+
+#include <QtGui/QLineEdit>
+
+class FancyLineEditPrivate;
+
+/* A line edit with an embedded pixmap on one side that is connected to
+ * a menu. Additionally, it can display a grayed hintText (like "Type Here to")
+ * when not focused and empty. When connecting to the changed signals and
+ * querying text, one has to be aware that the text is set to that hint
+ * text if isShowingHintText() returns true (that is, does not contain
+ * valid user input).
+ */
+class FancyLineEdit : public QLineEdit
+{
+ Q_DISABLE_COPY(FancyLineEdit)
+ Q_OBJECT
+ Q_ENUMS(Side)
+ Q_PROPERTY(QPixmap pixmap READ pixmap WRITE setPixmap DESIGNABLE true)
+ Q_PROPERTY(Side side READ side WRITE setSide DESIGNABLE isSideStored STORED isSideStored)
+ Q_PROPERTY(bool useLayoutDirection READ useLayoutDirection WRITE setUseLayoutDirection DESIGNABLE true)
+ Q_PROPERTY(bool menuTabFocusTrigger READ hasMenuTabFocusTrigger WRITE setMenuTabFocusTrigger DESIGNABLE true)
+ Q_PROPERTY(QString hintText READ hintText WRITE setHintText DESIGNABLE true)
+
+public:
+ enum Side {Left, Right};
+
+ explicit FancyLineEdit(QWidget *parent = 0);
+ ~FancyLineEdit();
+
+ QPixmap pixmap() const;
+
+ void setMenu(QMenu *menu);
+ QMenu *menu() const;
+
+ void setSide(Side side);
+ Side side() const;
+
+ bool useLayoutDirection() const;
+ void setUseLayoutDirection(bool v);
+
+ // Set whether tabbing in will trigger the menu.
+ bool hasMenuTabFocusTrigger() const;
+ void setMenuTabFocusTrigger(bool v);
+
+ // Hint text that is displayed when no focus is set.
+ QString hintText() const;
+
+ bool isShowingHintText() const;
+
+ // Convenience for accessing the text that returns "" in case of isShowingHintText().
+ QString typedText() const;
+
+signals:
+ void buttonClicked();
+
+public slots:
+ void setPixmap(const QPixmap &pixmap);
+ void setHintText(const QString &ht);
+ void showHintText();
+ void hideHintText();
+
+protected:
+ virtual void resizeEvent(QResizeEvent *e);
+ virtual void focusInEvent(QFocusEvent *e);
+ virtual void focusOutEvent(QFocusEvent *e);
+
+private:
+ friend class FancyLineEditPrivate;
+ bool isSideStored() const;
+ void updateMenuLabel();
+ void positionMenuLabel();
+ void updateStyleSheet(Side side);
+
+ FancyLineEditPrivate *m_d;
+};
+
+#endif // FANCYLINEEDIT_H
diff --git a/library/style/filterlineedit.cpp b/library/style/filterlineedit.cpp
new file mode 100644
index 0000000..cc5e358
--- /dev/null
+++ b/library/style/filterlineedit.cpp
@@ -0,0 +1,51 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "filterlineedit.h"
+
+FilterLineEdit::FilterLineEdit(QWidget *parent) :
+ FancyLineEdit(parent),
+ m_lastFilterText(typedText())
+{
+ setSide(FancyLineEdit::Right);
+ setPixmap(QPixmap(QLatin1String(":/style/images/reset.png")));
+ setHintText(tr("Type to filter"));
+
+ connect(this, SIGNAL(buttonClicked()), this, SLOT(clear()));
+ connect(this, SIGNAL(textChanged(QString)), this, SLOT(slotTextChanged()));
+}
+
+void FilterLineEdit::slotTextChanged()
+{
+ const QString newlyTypedText = typedText();
+ if (newlyTypedText != m_lastFilterText) {
+ m_lastFilterText = newlyTypedText;
+ emit filterChanged(m_lastFilterText);
+ }
+}
diff --git a/library/style/filterlineedit.h b/library/style/filterlineedit.h
new file mode 100644
index 0000000..d0adb50
--- /dev/null
+++ b/library/style/filterlineedit.h
@@ -0,0 +1,53 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef FILTERLINEEDIT_H
+#define FILTERLINEEDIT_H
+
+#include "fancylineedit.h"
+
+/* A fancy line edit customized for filtering purposes with a clear button. */
+
+class FilterLineEdit : public FancyLineEdit
+{
+ Q_OBJECT
+public:
+ explicit FilterLineEdit(QWidget *parent = 0);
+
+signals:
+ void filterChanged(const QString &);
+
+private slots:
+ void slotTextChanged();
+
+private:
+ QString m_lastFilterText;
+};
+
+#endif // FILTERLINEEDIT_H
diff --git a/library/style/images/advanced.png b/library/style/images/advanced.png
new file mode 100644
index 0000000..2a894ec
--- /dev/null
+++ b/library/style/images/advanced.png
Binary files differ
diff --git a/library/style/images/closebutton.png b/library/style/images/closebutton.png
new file mode 100644
index 0000000..6eea001
--- /dev/null
+++ b/library/style/images/closebutton.png
Binary files differ
diff --git a/library/style/images/favoriteScripts.png b/library/style/images/favoriteScripts.png
new file mode 100644
index 0000000..1348354
--- /dev/null
+++ b/library/style/images/favoriteScripts.png
Binary files differ
diff --git a/library/style/images/reset.png b/library/style/images/reset.png
new file mode 100644
index 0000000..cc0d6a2
--- /dev/null
+++ b/library/style/images/reset.png
Binary files differ
diff --git a/library/style/manhattanstyle.cpp b/library/style/manhattanstyle.cpp
new file mode 100644
index 0000000..3d43e7a
--- /dev/null
+++ b/library/style/manhattanstyle.cpp
@@ -0,0 +1,1187 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "manhattanstyle.h"
+
+#include "styleanimator.h"
+
+#include <QtCore/QLibrary>
+
+#include "qtcassert.h"
+#include "stylehelper.h"
+
+#include <QtGui/QApplication>
+#include <QtGui/QComboBox>
+#include <QtGui/QDialog>
+#include <QtGui/QDialogButtonBox>
+#include <QtGui/QDockWidget>
+#include <QtGui/QLabel>
+#include <QtGui/QLineEdit>
+#include <QtGui/QMainWindow>
+#include <QtGui/QMenuBar>
+#include <QtGui/QPainter>
+#include <QtGui/QPixmap>
+#include <QtGui/QPixmapCache>
+#include <QtGui/QPushButton>
+#include <QtGui/QScrollArea>
+#include <QtGui/QSplitter>
+#include <QtGui/QStatusBar>
+#include <QtGui/QStyleFactory>
+#include <QtGui/QStyleOption>
+#include <QtGui/QToolBar>
+#include <QtGui/QToolButton>
+
+// We define a currently unused state for indicating animations
+#define State_Animating 0x00000040
+
+// Because designer needs to disable this for widget previews
+// we have a custom property that is inherited
+bool styleEnabled(const QWidget *widget)
+{
+ const QWidget *p = widget;
+ while (p) {
+ if (p->property("_q_custom_style_disabled").toBool())
+ return false;
+ p = p->parentWidget();
+ }
+ return true;
+}
+
+// Consider making this a QStyle state
+bool panelWidget(const QWidget *widget)
+{
+ if (!widget)
+ return false;
+
+ // Don't style dialogs or explicitly ignored widgets
+ if (qobject_cast<const QDialog *>(widget->window()))
+ return false;
+
+ const QWidget *p = widget;
+ while (p) {
+ if (qobject_cast<const QToolBar *>(p) ||
+ qobject_cast<const QStatusBar *>(p) ||
+ qobject_cast<const QMenuBar *>(p))
+ return styleEnabled(widget);
+ if (p->property("panelwidget").toBool())
+ return true;
+ p = p->parentWidget();
+ }
+ return false;
+}
+
+bool styledScrollBar(const QWidget *widget)
+{
+ if (!widget)
+ return false;
+
+ // Don't style dialogs or explicitly ignored widgets
+ if (qobject_cast<const QDialog *>(widget->window()))
+ return false;
+
+ const QWidget *p = widget;
+ while (p) {
+ if (qobject_cast<const QToolBar *>(p) ||
+ qobject_cast<const QStatusBar *>(p) ||
+ qobject_cast<const QMenuBar *>(p))
+ return styleEnabled(widget);
+ if (p->property("styledScrollBar").toBool())
+ return true;
+ p = p->parentWidget();
+ }
+ return false;
+}
+
+// Consider making this a QStyle state
+bool lightColored(const QWidget *widget)
+{
+ if (!widget)
+ return false;
+
+ // Don't style dialogs or explicitly ignored widgets
+ if (qobject_cast<const QDialog *>(widget->window()))
+ return false;
+
+ const QWidget *p = widget;
+ while (p) {
+ if (p->property("lightColored").toBool())
+ return true;
+ p = p->parentWidget();
+ }
+ return false;
+}
+
+class ManhattanStylePrivate
+{
+public:
+ ManhattanStylePrivate(const QString &baseStyleName)
+ {
+ style = QStyleFactory::create(baseStyleName);
+ QTC_ASSERT(style, /**/);
+
+ lineeditImage = QImage(":/core/images/inputfield.png");
+ lineeditImage_disabled = QImage(":/core/images/inputfield_disabled.png");
+ }
+
+ ~ManhattanStylePrivate()
+ {
+ delete style;
+ style = 0;
+ }
+
+ void init();
+
+public:
+ QStyle *style;
+ QImage lineeditImage;
+ QImage lineeditImage_disabled;
+
+ StyleAnimator animator;
+};
+
+ManhattanStyle::ManhattanStyle(const QString &baseStyleName)
+ : QWindowsStyle(), d(new ManhattanStylePrivate(baseStyleName))
+{
+}
+
+ManhattanStyle::~ManhattanStyle()
+{
+ delete d;
+ d = 0;
+}
+
+QStyle *ManhattanStyle::systemStyle() const
+{
+ return d->style;
+}
+
+// Draws a CSS-like border image where the defined borders are not stretched
+void drawCornerImage(const QImage &img, QPainter *painter, QRect rect,
+ int left = 0, int top = 0, int right = 0,
+ int bottom = 0)
+{
+ QSize size = img.size();
+ if (top > 0) { //top
+ painter->drawImage(QRect(rect.left() + left, rect.top(), rect.width() -right - left, top), img,
+ QRect(left, 0, size.width() -right - left, top));
+ if (left > 0) //top-left
+ painter->drawImage(QRect(rect.left(), rect.top(), left, top), img,
+ QRect(0, 0, left, top));
+ if (right > 0) //top-right
+ painter->drawImage(QRect(rect.left() + rect.width() - right, rect.top(), right, top), img,
+ QRect(size.width() - right, 0, right, top));
+ }
+ //left
+ if (left > 0)
+ painter->drawImage(QRect(rect.left(), rect.top()+top, left, rect.height() - top - bottom), img,
+ QRect(0, top, left, size.height() - bottom - top));
+ //center
+ painter->drawImage(QRect(rect.left() + left, rect.top()+top, rect.width() -right - left,
+ rect.height() - bottom - top), img,
+ QRect(left, top, size.width() -right -left,
+ size.height() - bottom - top));
+ if (right > 0) //right
+ painter->drawImage(QRect(rect.left() +rect.width() - right, rect.top()+top, right, rect.height() - top - bottom), img,
+ QRect(size.width() - right, top, right, size.height() - bottom - top));
+ if (bottom > 0) { //bottom
+ painter->drawImage(QRect(rect.left() +left, rect.top() + rect.height() - bottom,
+ rect.width() - right - left, bottom), img,
+ QRect(left, size.height() - bottom,
+ size.width() - right - left, bottom));
+ if (left > 0) //bottom-left
+ painter->drawImage(QRect(rect.left(), rect.top() + rect.height() - bottom, left, bottom), img,
+ QRect(0, size.height() - bottom, left, bottom));
+ if (right > 0) //bottom-right
+ painter->drawImage(QRect(rect.left() + rect.width() - right, rect.top() + rect.height() - bottom, right, bottom), img,
+ QRect(size.width() - right, size.height() - bottom, right, bottom));
+ }
+}
+
+QPixmap ManhattanStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const
+{
+ QPixmap result;
+ result = d->style->generatedIconPixmap(iconMode, pixmap, opt);
+ return result;
+}
+
+int ManhattanStyle::layoutSpacingImplementation(QSizePolicy::ControlType control1,
+ QSizePolicy::ControlType control2,
+ Qt::Orientation orientation,
+ const QStyleOption * option ,
+ const QWidget * widget ) const
+{
+ return d->style->layoutSpacing(control1, control2, orientation, option, widget);
+
+}
+
+QSize ManhattanStyle::sizeFromContents(ContentsType type, const QStyleOption *option,
+ const QSize &size, const QWidget *widget) const
+{
+ QSize newSize = d->style->sizeFromContents(type, option, size, widget);
+
+ if (type == CT_Splitter && widget && widget->property("minisplitter").toBool())
+ return QSize(1, 1);
+ else if (type == CT_ComboBox && panelWidget(widget))
+ newSize += QSize(14, 0);
+ return newSize;
+}
+
+QRect ManhattanStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const
+{
+ QRect rect;
+ rect = d->style->subElementRect(element, option, widget);
+ return rect;
+}
+
+QRect ManhattanStyle::subControlRect(ComplexControl control, const QStyleOptionComplex *option,
+ SubControl subControl, const QWidget *widget) const
+{
+ QRect rect;
+ rect = d->style->subControlRect(control, option, subControl, widget);
+ return rect;
+}
+
+QStyle::SubControl ManhattanStyle::hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ const QPoint &pos, const QWidget *widget) const
+{
+ SubControl result = QStyle::SC_None;
+ result = d->style->hitTestComplexControl(control, option, pos, widget);
+ return result;
+}
+
+int ManhattanStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const
+{
+ int retval = 0;
+ retval = d->style->pixelMetric(metric, option, widget);
+ switch (metric) {
+ case PM_SplitterWidth:
+ if (widget && widget->property("minisplitter").toBool())
+ retval = 1;
+ break;
+ case PM_ToolBarIconSize:
+ if (panelWidget(widget))
+ retval = 16;
+ break;
+ case PM_MenuPanelWidth:
+ case PM_MenuBarHMargin:
+ case PM_MenuBarVMargin:
+ case PM_ToolBarFrameWidth:
+ if (panelWidget(widget))
+ retval = 1;
+ break;
+ case PM_ButtonShiftVertical:
+ case PM_ButtonShiftHorizontal:
+ case PM_MenuBarPanelWidth:
+ case PM_ToolBarItemMargin:
+ case PM_ToolBarItemSpacing:
+ if (panelWidget(widget))
+ retval = 0;
+ break;
+ case PM_DefaultFrameWidth:
+ if (qobject_cast<const QLineEdit*>(widget) && panelWidget(widget))
+ return 1;
+ break;
+ default:
+ break;
+ }
+ return retval;
+}
+
+QPalette ManhattanStyle::standardPalette() const
+{
+ QPalette result;
+ result = d->style->standardPalette();
+ return result;
+}
+
+void ManhattanStyle::polish(QApplication *app)
+{
+ d->style->polish(app);
+}
+
+void ManhattanStyle::unpolish(QApplication *app)
+{
+ d->style->unpolish(app);
+}
+
+QPalette panelPalette(const QPalette &oldPalette, bool lightColored = false)
+{
+ QColor color = StyleHelper::panelTextColor(lightColored);
+ QPalette pal = oldPalette;
+ pal.setBrush(QPalette::All, QPalette::WindowText, color);
+ pal.setBrush(QPalette::All, QPalette::ButtonText, color);
+ pal.setBrush(QPalette::All, QPalette::Foreground, color);
+ color.setAlpha(100);
+ pal.setBrush(QPalette::Disabled, QPalette::WindowText, color);
+ pal.setBrush(QPalette::Disabled, QPalette::ButtonText, color);
+ pal.setBrush(QPalette::Disabled, QPalette::Foreground, color);
+ return pal;
+}
+
+void ManhattanStyle::polish(QWidget *widget)
+{
+ d->style->polish(widget);
+
+ // OxygenStyle forces a rounded widget mask on toolbars
+ if (d->style->inherits("OxygenStyle")) {
+ if (qobject_cast<QToolBar*>(widget))
+ widget->removeEventFilter(d->style);
+ }
+ if (panelWidget(widget)) {
+ widget->setAttribute(Qt::WA_LayoutUsesWidgetRect, true);
+ if (qobject_cast<QToolButton*>(widget)) {
+ widget->setAttribute(Qt::WA_Hover);
+ widget->setMaximumHeight(StyleHelper::navigationWidgetHeight() - 1);
+ }
+ else if (qobject_cast<QLineEdit*>(widget)) {
+ widget->setAttribute(Qt::WA_Hover);
+ widget->setMaximumHeight(StyleHelper::navigationWidgetHeight() - 1);
+ }
+ else if (qobject_cast<QLabel*>(widget))
+ widget->setPalette(panelPalette(widget->palette()));
+ else if (qobject_cast<QToolBar*>(widget) || widget->property("panelwidget_singlerow").toBool())
+ widget->setFixedHeight(StyleHelper::navigationWidgetHeight());
+ else if (qobject_cast<QStatusBar*>(widget))
+ widget->setFixedHeight(StyleHelper::navigationWidgetHeight() + 2);
+ else if (qobject_cast<QComboBox*>(widget)) {
+ widget->setMaximumHeight(StyleHelper::navigationWidgetHeight() - 1);
+ widget->setAttribute(Qt::WA_Hover);
+ }
+ }
+}
+
+void ManhattanStyle::unpolish(QWidget *widget)
+{
+ d->style->unpolish(widget);
+ if (panelWidget(widget)) {
+ widget->setAttribute(Qt::WA_LayoutUsesWidgetRect, false);
+ if (qobject_cast<QTabBar*>(widget))
+ widget->setAttribute(Qt::WA_Hover, false);
+ else if (qobject_cast<QToolBar*>(widget))
+ widget->setAttribute(Qt::WA_Hover, false);
+ else if (qobject_cast<QComboBox*>(widget))
+ widget->setAttribute(Qt::WA_Hover, false);
+ }
+}
+
+void ManhattanStyle::polish(QPalette &pal)
+{
+ d->style->polish(pal);
+}
+
+QIcon ManhattanStyle::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option,
+ const QWidget *widget) const
+{
+ QIcon icon;
+ switch (standardIcon) {
+ case QStyle::SP_TitleBarCloseButton:
+ case QStyle::SP_ToolBarHorizontalExtensionButton:
+ return QIcon(standardPixmap(standardIcon, option, widget));
+ default:
+ icon = d->style->standardIcon(standardIcon, option, widget);
+ }
+ return icon;
+}
+
+QPixmap ManhattanStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
+ const QWidget *widget) const
+{
+ if (widget && !panelWidget(widget))
+ return d->style->standardPixmap(standardPixmap, opt, widget);
+
+ QPixmap pixmap;
+ switch (standardPixmap) {
+ case QStyle::SP_ToolBarHorizontalExtensionButton: {
+ static const QPixmap extButton(":/core/images/extension.png");
+ pixmap = extButton;
+ }
+ break;
+ case QStyle::SP_TitleBarCloseButton: {
+ static const QPixmap closeButton(":/style/images/closebutton.png");
+ pixmap = closeButton;
+ }
+ break;
+ default:
+ pixmap = d->style->standardPixmap(standardPixmap, opt, widget);
+ }
+ return pixmap;
+}
+
+
+int ManhattanStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget,
+ QStyleHintReturn *returnData) const
+{
+ int ret = d->style->styleHint(hint, option, widget, returnData);
+ switch (hint) {
+ // Make project explorer alternate rows all the way
+ case QStyle::SH_ItemView_PaintAlternatingRowColorsForEmptyArea:
+ if (widget && widget->property("AlternateEmpty").toBool())
+ ret = true;
+ break;
+ case QStyle::SH_EtchDisabledText:
+ if (panelWidget(widget))
+ ret = false;
+ break;
+ default:
+ break;
+ }
+ return ret;
+}
+
+void ManhattanStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const
+{
+ if (!panelWidget(widget))
+ return d->style->drawPrimitive(element, option, painter, widget);
+
+ bool animating = (option->state & State_Animating);
+ int state = option->state;
+ QRect rect = option->rect;
+ QRect oldRect;
+ QRect newRect;
+ if (widget && (element == PE_PanelButtonTool) && !animating) {
+ QWidget *w = const_cast<QWidget *> (widget);
+ int oldState = w->property("_q_stylestate").toInt();
+ oldRect = w->property("_q_stylerect").toRect();
+ newRect = w->rect();
+ w->setProperty("_q_stylestate", (int)option->state);
+ w->setProperty("_q_stylerect", w->rect());
+
+ // Determine the animated transition
+ bool doTransition = ((state & State_On) != (oldState & State_On) ||
+ (state & State_MouseOver) != (oldState & State_MouseOver));
+ if (oldRect != newRect)
+ {
+ doTransition = false;
+ d->animator.stopAnimation(widget);
+ }
+
+ if (doTransition) {
+ QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
+ QImage endImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied);
+ Animation *anim = d->animator.widgetAnimation(widget);
+ QStyleOption opt = *option;
+ opt.state = (QStyle::State)oldState;
+ opt.state |= (State)State_Animating;
+ startImage.fill(0);
+ Transition *t = new Transition;
+ t->setWidget(w);
+ QPainter startPainter(&startImage);
+ if (!anim) {
+ drawPrimitive(element, &opt, &startPainter, widget);
+ } else {
+ anim->paint(&startPainter, &opt);
+ d->animator.stopAnimation(widget);
+ }
+ QStyleOption endOpt = *option;
+ endOpt.state |= (State)State_Animating;
+ t->setStartImage(startImage);
+ d->animator.startAnimation(t);
+ endImage.fill(0);
+ QPainter endPainter(&endImage);
+ drawPrimitive(element, &endOpt, &endPainter, widget);
+ t->setEndImage(endImage);
+ if (oldState & State_MouseOver)
+ t->setDuration(150);
+ else
+ t->setDuration(75);
+ t->setStartTime(QTime::currentTime());
+ }
+ }
+
+ switch (element) {
+ case PE_PanelLineEdit:
+ {
+ painter->save();
+
+ // Fill the line edit background
+ QRect filledRect = option->rect.adjusted(1, 1, -1, -1);
+ painter->setBrushOrigin(filledRect.topLeft());
+ painter->fillRect(filledRect, option->palette.base());
+
+ if (option->state & State_Enabled)
+ drawCornerImage(d->lineeditImage, painter, option->rect, 5, 5, 5, 5);
+ else
+ drawCornerImage(d->lineeditImage_disabled, painter, option->rect, 5, 5, 5, 5);
+
+ if (option->state & State_HasFocus || option->state & State_MouseOver) {
+ QColor hover = StyleHelper::baseColor();
+ if (state & State_HasFocus)
+ hover.setAlpha(100);
+ else
+ hover.setAlpha(50);
+
+ painter->setPen(QPen(hover, 1));
+ painter->drawRect(option->rect.adjusted(1, 1, -2 ,-2));
+ }
+ painter->restore();
+ }
+ break;
+
+ case PE_FrameStatusBarItem:
+ break;
+
+ case PE_PanelButtonTool: {
+ Animation *anim = d->animator.widgetAnimation(widget);
+ if (!animating && anim) {
+ anim->paint(painter, option);
+ } else {
+ bool pressed = option->state & State_Sunken || option->state & State_On;
+ QColor shadow(0, 0, 0, 30);
+ painter->setPen(shadow);
+ if (pressed) {
+ QColor shade(0, 0, 0, 40);
+ painter->fillRect(rect, shade);
+ painter->drawLine(rect.topLeft() + QPoint(1, 0), rect.topRight() - QPoint(1, 0));
+ painter->drawLine(rect.topLeft(), rect.bottomLeft());
+ painter->drawLine(rect.topRight(), rect.bottomRight());
+ // painter->drawLine(rect.bottomLeft() + QPoint(1, 0), rect.bottomRight() - QPoint(1, 0));
+ QColor highlight(255, 255, 255, 30);
+ painter->setPen(highlight);
+ }
+ else if (option->state & State_Enabled &&
+ option->state & State_MouseOver) {
+ QColor lighter(255, 255, 255, 37);
+ painter->fillRect(rect, lighter);
+ }
+ }
+ }
+ break;
+
+ case PE_PanelStatusBar:
+ {
+ painter->save();
+ QLinearGradient grad(option->rect.topLeft(), QPoint(rect.center().x(), rect.bottom()));
+ QColor startColor = StyleHelper::shadowColor().darker(164);
+ QColor endColor = StyleHelper::baseColor().darker(130);
+ grad.setColorAt(0, startColor);
+ grad.setColorAt(1, endColor);
+ painter->fillRect(option->rect, grad);
+ painter->setPen(QColor(255, 255, 255, 60));
+ painter->drawLine(rect.topLeft() + QPoint(0,1),
+ rect.topRight()+ QPoint(0,1));
+ painter->setPen(StyleHelper::borderColor().darker(110));
+ painter->drawLine(rect.topLeft(), rect.topRight());
+ painter->restore();
+ }
+ break;
+
+ case PE_IndicatorToolBarSeparator:
+ {
+ QColor separatorColor = StyleHelper::borderColor();
+ separatorColor.setAlpha(100);
+ painter->setPen(separatorColor);
+ const int margin = 6;
+ if (option->state & State_Horizontal) {
+ const int offset = rect.width()/2;
+ painter->drawLine(rect.bottomLeft().x() + offset,
+ rect.bottomLeft().y() - margin,
+ rect.topLeft().x() + offset,
+ rect.topLeft().y() + margin);
+ } else { //Draw vertical separator
+ const int offset = rect.height()/2;
+ painter->setPen(QPen(option->palette.background().color().darker(110)));
+ painter->drawLine(rect.topLeft().x() + margin ,
+ rect.topLeft().y() + offset,
+ rect.topRight().x() - margin,
+ rect.topRight().y() + offset);
+ }
+ }
+ break;
+
+ case PE_IndicatorToolBarHandle:
+ {
+ bool horizontal = option->state & State_Horizontal;
+ painter->save();
+ QPainterPath path;
+ int x = option->rect.x() + horizontal ? 2 : 6;
+ int y = option->rect.y() + horizontal ? 6 : 2;
+ static const int RectHeight = 2;
+ if (horizontal) {
+ while (y < option->rect.height() - RectHeight - 6) {
+ path.moveTo(x, y);
+ path.addRect(x, y, RectHeight, RectHeight);
+ y += 6;
+ }
+ } else {
+ while (x < option->rect.width() - RectHeight - 6) {
+ path.moveTo(x, y);
+ path.addRect(x, y, RectHeight, RectHeight);
+ x += 6;
+ }
+ }
+
+ painter->setPen(Qt::NoPen);
+ QColor dark = StyleHelper::borderColor();
+ dark.setAlphaF(0.4);
+
+ QColor light = StyleHelper::baseColor();
+ light.setAlphaF(0.4);
+
+ painter->fillPath(path, light);
+ painter->save();
+ painter->translate(1, 1);
+ painter->fillPath(path, dark);
+ painter->restore();
+ painter->translate(3, 3);
+ painter->fillPath(path, light);
+ painter->translate(1, 1);
+ painter->fillPath(path, dark);
+ painter->restore();
+ }
+ break;
+ case PE_IndicatorArrowUp:
+ case PE_IndicatorArrowDown:
+ case PE_IndicatorArrowRight:
+ case PE_IndicatorArrowLeft:
+ {
+ // From windowsstyle but modified to enable AA
+ if (option->rect.width() <= 1 || option->rect.height() <= 1)
+ break;
+
+ QRect r = option->rect;
+ int size = qMin(r.height(), r.width());
+ QPixmap pixmap;
+ QString pixmapName;
+ pixmapName.sprintf("%s-%s-%d-%d-%d-%lld",
+ "$qt_ia", metaObject()->className(),
+ uint(option->state), element,
+ size, option->palette.cacheKey());
+ if (!QPixmapCache::find(pixmapName, pixmap)) {
+ int border = size/5;
+ int sqsize = 2*(size/2);
+ QImage image(sqsize, sqsize, QImage::Format_ARGB32);
+ image.fill(Qt::transparent);
+ QPainter imagePainter(&image);
+ imagePainter.setRenderHint(QPainter::Antialiasing, true);
+ imagePainter.translate(0.5, 0.5);
+ QPolygon a;
+ switch (element) {
+ case PE_IndicatorArrowUp:
+ a.setPoints(3, border, sqsize/2, sqsize/2, border, sqsize - border, sqsize/2);
+ break;
+ case PE_IndicatorArrowDown:
+ a.setPoints(3, border, sqsize/2, sqsize/2, sqsize - border, sqsize - border, sqsize/2);
+ break;
+ case PE_IndicatorArrowRight:
+ a.setPoints(3, sqsize - border, sqsize/2, sqsize/2, border, sqsize/2, sqsize - border);
+ break;
+ case PE_IndicatorArrowLeft:
+ a.setPoints(3, border, sqsize/2, sqsize/2, border, sqsize/2, sqsize - border);
+ break;
+ default:
+ break;
+ }
+
+ int bsx = 0;
+ int bsy = 0;
+
+ if (option->state & State_Sunken) {
+ bsx = pixelMetric(PM_ButtonShiftHorizontal);
+ bsy = pixelMetric(PM_ButtonShiftVertical);
+ }
+
+ QRect bounds = a.boundingRect();
+ int sx = sqsize / 2 - bounds.center().x() - 1;
+ int sy = sqsize / 2 - bounds.center().y() - 1;
+ imagePainter.translate(sx + bsx, sy + bsy);
+
+ if (!(option->state & State_Enabled)) {
+ QColor foreGround(150, 150, 150, 150);
+ imagePainter.setBrush(option->palette.mid().color());
+ imagePainter.setPen(option->palette.mid().color());
+ } else {
+ QColor shadow(0, 0, 0, 100);
+ imagePainter.translate(0, 1);
+ imagePainter.setPen(shadow);
+ imagePainter.setBrush(shadow);
+ QColor foreGround(255, 255, 255, 210);
+ imagePainter.drawPolygon(a);
+ imagePainter.translate(0, -1);
+ imagePainter.setPen(foreGround);
+ imagePainter.setBrush(foreGround);
+ }
+ imagePainter.drawPolygon(a);
+ imagePainter.end();
+ pixmap = QPixmap::fromImage(image);
+ QPixmapCache::insert(pixmapName, pixmap);
+ }
+ int xOffset = r.x() + (r.width() - size)/2;
+ int yOffset = r.y() + (r.height() - size)/2;
+ painter->drawPixmap(xOffset, yOffset, pixmap);
+ }
+ break;
+
+ default:
+ d->style->drawPrimitive(element, option, painter, widget);
+ break;
+ }
+}
+
+void ManhattanStyle::drawControl(ControlElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const
+{
+ if (!panelWidget(widget)
+ && !styledScrollBar(widget))
+ return d->style->drawControl(element, option, painter, widget);
+
+ switch (element) {
+ case CE_MenuBarItem:
+ painter->save();
+ if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
+ QColor highlightOutline = StyleHelper::borderColor().lighter(120);
+ bool act = mbi->state & State_Selected && mbi->state & State_Sunken;
+ bool dis = !(mbi->state & State_Enabled);
+ StyleHelper::menuGradient(painter, option->rect, option->rect);
+ QStyleOptionMenuItem item = *mbi;
+ item.rect = mbi->rect;
+ QPalette pal = mbi->palette;
+ pal.setBrush(QPalette::ButtonText, dis ? Qt::gray : Qt::black);
+ item.palette = pal;
+ QCommonStyle::drawControl(element, &item, painter, widget);
+ QRect r = option->rect;
+
+ if (act) {
+ // Fill|
+ QColor baseColor = StyleHelper::baseColor();
+ QLinearGradient grad(option->rect.topLeft(), option->rect.bottomLeft());
+ grad.setColorAt(0, baseColor.lighter(120));
+ grad.setColorAt(1, baseColor.lighter(130));
+ painter->fillRect(option->rect.adjusted(1, 1, -1, 0), grad);
+
+ // Outline
+ painter->setPen(QPen(highlightOutline, 0));
+ painter->drawLine(QPoint(r.left(), r.top() + 1), QPoint(r.left(), r.bottom()));
+ painter->drawLine(QPoint(r.right(), r.top() + 1), QPoint(r.right(), r.bottom()));
+ painter->drawLine(QPoint(r.left() + 1, r.top()), QPoint(r.right() - 1, r.top()));
+ highlightOutline.setAlpha(60);
+ painter->setPen(QPen(highlightOutline, 0));
+ painter->drawPoint(r.topLeft());
+ painter->drawPoint(r.topRight());
+
+ QPalette pal = mbi->palette;
+ uint alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
+ if (!styleHint(SH_UnderlineShortcut, mbi, widget))
+ alignment |= Qt::TextHideMnemonic;
+ pal.setBrush(QPalette::Text, dis ? Qt::gray : QColor(0, 0, 0, 60));
+ drawItemText(painter, item.rect.translated(0, 1), alignment, pal, mbi->state & State_Enabled, mbi->text, QPalette::Text);
+ pal.setBrush(QPalette::Text, dis ? Qt::gray : Qt::white);
+ drawItemText(painter, item.rect, alignment, pal, mbi->state & State_Enabled, mbi->text, QPalette::Text);
+ }
+ }
+ painter->restore();
+ break;
+
+ case CE_ComboBoxLabel:
+ if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+ if (panelWidget(widget)) {
+ QRect editRect = subControlRect(CC_ComboBox, cb, SC_ComboBoxEditField, widget);
+ QPalette customPal = cb->palette;
+
+ if (!cb->currentIcon.isNull()) {
+ QIcon::Mode mode = cb->state & State_Enabled ? QIcon::Normal
+ : QIcon::Disabled;
+ QPixmap pixmap = cb->currentIcon.pixmap(cb->iconSize, mode);
+ QRect iconRect(editRect);
+ iconRect.setWidth(cb->iconSize.width() + 4);
+ iconRect = alignedRect(cb->direction,
+ Qt::AlignLeft | Qt::AlignVCenter,
+ iconRect.size(), editRect);
+ if (cb->editable)
+ painter->fillRect(iconRect, customPal.brush(QPalette::Base));
+ drawItemPixmap(painter, iconRect, Qt::AlignCenter, pixmap);
+
+ if (cb->direction == Qt::RightToLeft)
+ editRect.translate(-4 - cb->iconSize.width(), 0);
+ else
+ editRect.translate(cb->iconSize.width() + 4, 0);
+
+ // Reserve some space for the down-arrow
+ editRect.adjust(0, 0, -13, 0);
+ }
+
+ customPal.setBrush(QPalette::All, QPalette::ButtonText, QColor(0, 0, 0, 70));
+
+ QString text = option->fontMetrics.elidedText(cb->currentText, Qt::ElideRight, editRect.width());
+ drawItemText(painter, editRect.translated(0, 1),
+ visualAlignment(option->direction, Qt::AlignLeft | Qt::AlignVCenter),
+ customPal, cb->state & State_Enabled, text, QPalette::ButtonText);
+ customPal.setBrush(QPalette::All, QPalette::ButtonText, StyleHelper::panelTextColor());
+ drawItemText(painter, editRect,
+ visualAlignment(option->direction, Qt::AlignLeft | Qt::AlignVCenter),
+ customPal, cb->state & State_Enabled, text, QPalette::ButtonText);
+ } else {
+ d->style->drawControl(element, option, painter, widget);
+ }
+ }
+ break;
+
+ case CE_SizeGrip: {
+ painter->save();
+ QColor dark = Qt::white;
+ dark.setAlphaF(0.1);
+ int x, y, w, h;
+ option->rect.getRect(&x, &y, &w, &h);
+ int sw = qMin(h, w);
+ if (h > w)
+ painter->translate(0, h - w);
+ else
+ painter->translate(w - h, 0);
+ int sx = x;
+ int sy = y;
+ int s = 4;
+ painter->setPen(dark);
+ if (option->direction == Qt::RightToLeft) {
+ sx = x + sw;
+ for (int i = 0; i < 4; ++i) {
+ painter->drawLine(x, sy, sx, sw);
+ sx -= s;
+ sy += s;
+ }
+ } else {
+ for (int i = 0; i < 4; ++i) {
+ painter->drawLine(sx, sw, sw, sy);
+ sx += s;
+ sy += s;
+ }
+ }
+ painter->restore();
+ }
+ break;
+
+ case CE_MenuBarEmptyArea: {
+ StyleHelper::menuGradient(painter, option->rect, option->rect);
+ painter->save();
+ painter->setPen(StyleHelper::borderColor());
+ painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight());
+ painter->restore();
+ }
+ break;
+
+ case CE_ToolBar:
+ {
+ QString key;
+ QColor keyColor = StyleHelper::baseColor(lightColored(widget));
+ key.sprintf("mh_toolbar %d %d %d", option->rect.width(), option->rect.height(), keyColor.rgb());;
+
+ QPixmap pixmap;
+ QPainter *p = painter;
+ QRect rect = option->rect;
+ bool horizontal = option->state & State_Horizontal;
+ if (StyleHelper::usePixmapCache() && !QPixmapCache::find(key, pixmap)) {
+ pixmap = QPixmap(option->rect.size());
+ p = new QPainter(&pixmap);
+ rect = QRect(0, 0, option->rect.width(), option->rect.height());
+ }
+
+ if (!StyleHelper::usePixmapCache() || !QPixmapCache::find(key, pixmap)) {
+ // Map offset for global window gradient
+ QPoint offset = widget->window()->mapToGlobal(option->rect.topLeft()) -
+ widget->mapToGlobal(option->rect.topLeft());
+ QRect gradientSpan;
+ if (widget) {
+ gradientSpan = QRect(offset, widget->window()->size());
+ }
+ bool drawLightColored = lightColored(widget);
+ if (horizontal)
+ StyleHelper::horizontalGradient(p, gradientSpan, rect, drawLightColored);
+ else
+ StyleHelper::verticalGradient(p, gradientSpan, rect, drawLightColored);
+ }
+
+ if (StyleHelper::usePixmapCache() && !QPixmapCache::find(key, pixmap)) {
+ delete p;
+ QPixmapCache::insert(key, pixmap);
+ }
+ if (StyleHelper::usePixmapCache()) {
+ painter->drawPixmap(rect.topLeft(), pixmap);
+ }
+
+ painter->setPen(StyleHelper::borderColor());
+
+ if (horizontal) {
+ // Note: This is a hack to determine if the
+ // toolbar should draw the top or bottom outline
+ // (needed for the find toolbar for instance)
+ QColor lighter(255, 255, 255, 40);
+ if (widget && widget->property("topBorder").toBool()) {
+ painter->drawLine(rect.topLeft(), rect.topRight());
+ painter->setPen(lighter);
+ painter->drawLine(rect.topLeft() + QPoint(0, 1), rect.topRight() + QPoint(0, 1));
+ } else {
+ painter->drawLine(rect.bottomLeft(), rect.bottomRight());
+ painter->setPen(lighter);
+ painter->drawLine(rect.topLeft(), rect.topRight());
+ }
+ } else {
+ painter->drawLine(rect.topLeft(), rect.bottomLeft());
+ painter->drawLine(rect.topRight(), rect.bottomRight());
+ }
+ painter->end();
+ }
+ break;
+ case CE_ScrollBarAddLine:
+ case CE_ScrollBarSubLine: {
+ PrimitiveElement arrow;
+ if (option->state & State_Horizontal) {
+ if (element == CE_ScrollBarAddLine)
+ arrow = option->direction == Qt::LeftToRight ? PE_IndicatorArrowRight : PE_IndicatorArrowLeft;
+ else
+ arrow = option->direction == Qt::LeftToRight ? PE_IndicatorArrowLeft : PE_IndicatorArrowRight;
+ } else {
+ if (element == CE_ScrollBarAddLine)
+ arrow = PE_IndicatorArrowDown;
+ else
+ arrow = PE_IndicatorArrowUp;
+ }
+ QStyleOption arrowOpt = *option;
+ arrowOpt.palette.setColor(QPalette::Active, QPalette::ButtonText, StyleHelper::baseColor());
+ arrowOpt.palette.setColor(QPalette::Disabled, QPalette::ButtonText, StyleHelper::shadowColor());
+ int squareSide = qMin(option->rect.width(), option->rect.height());
+ arrowOpt.rect.setSize(QSize(squareSide, squareSide));
+ arrowOpt.rect.adjust(5, 5, -1, -3);
+
+ drawPrimitive(arrow, &arrowOpt, painter, widget);
+ break; }
+ case CE_ScrollBarSlider: {
+ QRect rect = option->rect.adjusted(5, 0, -3, 0);
+ if (option->state & State_Enabled) {
+ StyleHelper::drawSlider(painter, rect);
+ }
+ break; }
+ default:
+ d->style->drawControl(element, option, painter, widget);
+ break;
+ }
+}
+
+void ManhattanStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
+ QPainter *painter, const QWidget *widget) const
+{
+ if (!panelWidget(widget) && !styledScrollBar(widget))
+ return d->style->drawComplexControl(control, option, painter, widget);
+
+ QRect rect = option->rect;
+ switch (control) {
+ case CC_ToolButton:
+ if (const QStyleOptionToolButton *toolbutton = qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
+ QRect button, menuarea;
+ button = subControlRect(control, toolbutton, SC_ToolButton, widget);
+ menuarea = subControlRect(control, toolbutton, SC_ToolButtonMenu, widget);
+
+ State bflags = toolbutton->state;
+ if (bflags & State_AutoRaise) {
+ if (!(bflags & State_MouseOver)) {
+ bflags &= ~State_Raised;
+ }
+ }
+
+ State mflags = bflags;
+ if (toolbutton->state & State_Sunken) {
+ if (toolbutton->activeSubControls & SC_ToolButton)
+ bflags |= State_Sunken;
+ if (toolbutton->activeSubControls & SC_ToolButtonMenu)
+ mflags |= State_Sunken;
+ }
+
+ QStyleOption tool(0);
+ tool.palette = toolbutton->palette;
+ if (toolbutton->subControls & SC_ToolButton) {
+ tool.rect = button;
+ tool.state = bflags;
+ drawPrimitive(PE_PanelButtonTool, &tool, painter, widget);
+ }
+
+ if (toolbutton->state & State_HasFocus) {
+ QStyleOptionFocusRect fr;
+ fr.QStyleOption::operator=(*toolbutton);
+ fr.rect.adjust(3, 3, -3, -3);
+ if (toolbutton->features & QStyleOptionToolButton::MenuButtonPopup)
+ fr.rect.adjust(0, 0, -pixelMetric(QStyle::PM_MenuButtonIndicator,
+ toolbutton, widget), 0);
+ QPen oldPen = painter->pen();
+ QColor focusColor = StyleHelper::panelTextColor();
+ focusColor.setAlpha(120);
+ QPen outline(focusColor, 1);
+ outline.setStyle(Qt::DotLine);
+ painter->setPen(outline);
+ QRect r = option->rect.adjusted(2, 2, -2, -2);
+ painter->drawRect(r);
+ painter->setPen(oldPen);
+ }
+
+ QStyleOptionToolButton label = *toolbutton;
+
+ label.palette = panelPalette(option->palette, lightColored(widget));
+ int fw = pixelMetric(PM_DefaultFrameWidth, option, widget);
+ label.rect = button.adjusted(fw, fw, -fw, -fw);
+
+ drawControl(CE_ToolButtonLabel, &label, painter, widget);
+
+ if (toolbutton->subControls & SC_ToolButtonMenu) {
+ tool.state = mflags;
+ tool.rect = menuarea.adjusted(1, 1, -1, -1);
+ if (mflags & (State_Sunken | State_On | State_Raised)) {
+ painter->setPen(Qt::gray);
+ painter->drawLine(tool.rect.topLeft(), tool.rect.bottomLeft());
+ if (mflags & (State_Sunken)) {
+ QColor shade(0, 0, 0, 50);
+ painter->fillRect(tool.rect.adjusted(0, -1, 1, 1), shade);
+ }
+#ifndef Q_WS_MAC
+ else if (mflags & (State_MouseOver)) {
+ QColor shade(255, 255, 255, 50);
+ painter->fillRect(tool.rect.adjusted(0, -1, 1, 1), shade);
+ }
+#endif
+ }
+ tool.rect = tool.rect.adjusted(2, 2, -2, -2);
+ drawPrimitive(PE_IndicatorArrowDown, &tool, painter, widget);
+ } else if (toolbutton->features & QStyleOptionToolButton::HasMenu
+ && !widget->property("noArrow").toBool()) {
+ int arrowSize = 6;
+ QRect ir = toolbutton->rect.adjusted(1, 1, -1, -1);
+ QStyleOptionToolButton newBtn = *toolbutton;
+ newBtn.palette = panelPalette(option->palette);
+ newBtn.rect = QRect(ir.right() - arrowSize - 1,
+ ir.height() - arrowSize - 2, arrowSize, arrowSize);
+ drawPrimitive(PE_IndicatorArrowDown, &newBtn, painter, widget);
+ }
+ }
+ break;
+
+ case CC_ComboBox:
+ if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+ painter->save();
+ bool isEmpty = cb->currentText.isEmpty() && cb->currentIcon.isNull();
+ bool reverse = option->direction == Qt::RightToLeft;
+
+ // Draw tool button
+ QLinearGradient grad(option->rect.topRight(), option->rect.bottomRight());
+ grad.setColorAt(0, QColor(255, 255, 255, 20));
+ grad.setColorAt(0.4, QColor(255, 255, 255, 60));
+ grad.setColorAt(0.7, QColor(255, 255, 255, 50));
+ grad.setColorAt(1, QColor(255, 255, 255, 40));
+ painter->setPen(QPen(grad, 0));
+ painter->drawLine(rect.topRight(), rect.bottomRight());
+ grad.setColorAt(0, QColor(0, 0, 0, 30));
+ grad.setColorAt(0.4, QColor(0, 0, 0, 70));
+ grad.setColorAt(0.7, QColor(0, 0, 0, 70));
+ grad.setColorAt(1, QColor(0, 0, 0, 40));
+ painter->setPen(QPen(grad, 0));
+ if (!reverse)
+ painter->drawLine(rect.topRight() - QPoint(1,0), rect.bottomRight() - QPoint(1,0));
+ else
+ painter->drawLine(rect.topLeft(), rect.bottomLeft());
+ QStyleOption toolbutton = *option;
+ if (isEmpty)
+ toolbutton.state &= ~(State_Enabled | State_Sunken);
+ painter->save();
+ painter->setClipRect(toolbutton.rect.adjusted(0, 0, -2, 0));
+ drawPrimitive(PE_PanelButtonTool, &toolbutton, painter, widget);
+ painter->restore();
+ // Draw arrow
+ int menuButtonWidth = 12;
+ int left = !reverse ? rect.right() - menuButtonWidth : rect.left();
+ int right = !reverse ? rect.right() : rect.left() + menuButtonWidth;
+ QRect arrowRect((left + right) / 2 + (reverse ? 6 : -6), rect.center().y() - 3, 9, 9);
+ if (option->state & State_On)
+ arrowRect.translate(d->style->pixelMetric(PM_ButtonShiftHorizontal, option, widget),
+ d->style->pixelMetric(PM_ButtonShiftVertical, option, widget));
+
+ QStyleOption arrowOpt = *option;
+ arrowOpt.rect = arrowRect;
+ if (isEmpty)
+ arrowOpt.state &= ~(State_Enabled | State_Sunken);
+
+ if (styleHint(SH_ComboBox_Popup, option, widget)) {
+ arrowOpt.rect.translate(0, -3);
+ drawPrimitive(PE_IndicatorArrowUp, &arrowOpt, painter, widget);
+ arrowOpt.rect.translate(0, 6);
+ drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, painter, widget);
+ } else {
+ drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, painter, widget);
+ }
+ painter->restore();
+ }
+ break;
+
+ case CC_ScrollBar:
+ if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ // Make a copy here and reset it for each primitive.
+ QStyleOptionSlider newScrollbar = *scrollbar;
+ State saveFlags = scrollbar->state;
+ if (scrollbar->minimum == scrollbar->maximum)
+ saveFlags &= ~State_Enabled;
+ StyleHelper::rectWithLeftLine(widget, painter, newScrollbar.rect);
+
+ if (scrollbar->subControls & SC_ScrollBarSubLine) {
+ newScrollbar.state = saveFlags;
+ newScrollbar.rect = proxy()->subControlRect(control, &newScrollbar, SC_ScrollBarSubLine, widget);
+ if (newScrollbar.rect.isValid()) {
+ if (!(scrollbar->activeSubControls & SC_ScrollBarSubLine))
+ newScrollbar.state &= ~(State_Sunken | State_MouseOver);
+ drawControl(CE_ScrollBarSubLine, &newScrollbar, painter, widget);
+ }
+ }
+ if (scrollbar->subControls & SC_ScrollBarAddLine) {
+ newScrollbar.rect = scrollbar->rect;
+ newScrollbar.state = saveFlags;
+ newScrollbar.rect = proxy()->subControlRect(control, &newScrollbar, SC_ScrollBarAddLine, widget);
+ if (newScrollbar.rect.isValid()) {
+ if (!(scrollbar->activeSubControls & SC_ScrollBarAddLine))
+ newScrollbar.state &= ~(State_Sunken | State_MouseOver);
+ drawControl(CE_ScrollBarAddLine, &newScrollbar, painter, widget);
+ }
+ }
+ if (scrollbar->subControls & SC_ScrollBarSlider) {
+ newScrollbar.rect = scrollbar->rect;
+ newScrollbar.state = saveFlags;
+ newScrollbar.rect = proxy()->subControlRect(control, &newScrollbar, SC_ScrollBarSlider, widget);
+ if (newScrollbar.rect.isValid()) {
+ if (!(scrollbar->activeSubControls & SC_ScrollBarSlider))
+ newScrollbar.state &= ~(State_Sunken | State_MouseOver);
+ drawControl(CE_ScrollBarSlider, &newScrollbar, painter, widget);
+ }
+ }
+ }
+ break;
+ default:
+ d->style->drawComplexControl(control, option, painter, widget);
+ break;
+ }
+}
+
+// Mac style reimplements this to control the
+// focus widget among other things
+bool ManhattanStyle::event(QEvent *e)
+{
+ Q_ASSERT(d->style);
+ return d->style->event(e);
+}
diff --git a/library/style/manhattanstyle.h b/library/style/manhattanstyle.h
new file mode 100644
index 0000000..527b0b4
--- /dev/null
+++ b/library/style/manhattanstyle.h
@@ -0,0 +1,94 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef MANHATTANSTYLE_H
+#define MANHATTANSTYLE_H
+
+#include <QtGui/QWindowsStyle>
+
+QT_BEGIN_NAMESPACE
+class QLinearGradient;
+class QBrush;
+QT_END_NAMESPACE
+
+class ManhattanStylePrivate;
+
+class ManhattanStyle : public QWindowsStyle
+{
+ Q_OBJECT
+
+public:
+ ManhattanStyle(const QString &);
+
+ ~ManhattanStyle();
+
+ QStyle *systemStyle() const;
+
+ void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = 0) const;
+ void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = 0) const;
+ void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget = 0) const;
+
+ QSize sizeFromContents(ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget) const;
+ QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const;
+ QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, const QWidget *widget) const;
+
+ SubControl hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option, const QPoint &pos, const QWidget *widget = 0) const;
+ QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget = 0) const;
+ int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0, QStyleHintReturn *returnData = 0) const;
+ QRect itemRect(QPainter *p, const QRect &r, int flags, bool enabled, const QPixmap *pixmap, const QString &text, int len = -1) const;
+ QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const;
+
+ int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const;
+
+ QPalette standardPalette() const;
+
+ void polish(QWidget *widget);
+ void polish(QPalette &pal);
+ void polish(QApplication *app);
+
+ void unpolish(QWidget *widget);
+ void unpolish(QApplication *app);
+
+protected:
+ bool event(QEvent *e);
+
+protected Q_SLOTS:
+ QIcon standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget) const;
+ int layoutSpacingImplementation(QSizePolicy::ControlType control1,
+ QSizePolicy::ControlType control2,
+ Qt::Orientation orientation,
+ const QStyleOption *option = 0,
+ const QWidget *widget = 0) const;
+
+private:
+ ManhattanStylePrivate *d;
+ Q_DISABLE_COPY(ManhattanStyle)
+};
+
+#endif // MANHATTANSTYLE_H
diff --git a/library/style/qtcassert.h b/library/style/qtcassert.h
new file mode 100644
index 0000000..a03f5f2
--- /dev/null
+++ b/library/style/qtcassert.h
@@ -0,0 +1,45 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef QTC_ASSERT_H
+#define QTC_ASSERT_H
+
+#include <QtCore/QDebug>
+
+#define QTC_ASSERT_STRINGIFY_INTERNAL(x) #x
+#define QTC_ASSERT_STRINGIFY(x) QTC_ASSERT_STRINGIFY_INTERNAL(x)
+
+// we do not use the 'do {...} while (0)' idiom here to be able to use
+// 'break' and 'continue' as 'actions'.
+
+#define QTC_ASSERT(cond, action) \
+ if(cond){}else{qDebug()<<"ASSERTION " #cond " FAILED AT " __FILE__ ":" QTC_ASSERT_STRINGIFY(__LINE__);action;}
+
+#endif // QTC_ASSERT_H
+
diff --git a/library/style/style.pri b/library/style/style.pri
new file mode 100644
index 0000000..f50e4bf
--- /dev/null
+++ b/library/style/style.pri
@@ -0,0 +1,16 @@
+INCLUDEPATH += src/ui/style
+DEPENDPATH += src/ui/style
+HEADERS += manhattanstyle.h \
+ stylehelper.h \
+ styleanimator.h \
+ qtcassert.h \
+ styledbar.h \
+ fancylineedit.h \
+ filterlineedit.h
+SOURCES += manhattanstyle.cpp \
+ stylehelper.cpp \
+ styleanimator.cpp \
+ styledbar.cpp \
+ fancylineedit.cpp \
+ filterlineedit.cpp
+RESOURCES += style.qrc
diff --git a/library/style/style.qrc b/library/style/style.qrc
new file mode 100644
index 0000000..77e34eb
--- /dev/null
+++ b/library/style/style.qrc
@@ -0,0 +1,8 @@
+<RCC>
+ <qresource prefix="/style">
+ <file>images/advanced.png</file>
+ <file>images/closebutton.png</file>
+ <file>images/reset.png</file>
+ <file>images/favoriteScripts.png</file>
+ </qresource>
+</RCC>
diff --git a/library/style/styleanimator.cpp b/library/style/styleanimator.cpp
new file mode 100644
index 0000000..14de4e2
--- /dev/null
+++ b/library/style/styleanimator.cpp
@@ -0,0 +1,154 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "styleanimator.h"
+
+#include <QtGui/QStyleOption>
+
+Animation * StyleAnimator::widgetAnimation(const QWidget *widget) const
+{
+ if (!widget)
+ return 0;
+ foreach (Animation *a, animations) {
+ if (a->widget() == widget)
+ return a;
+ }
+ return 0;
+}
+
+void Animation::paint(QPainter *painter, const QStyleOption *option)
+{
+ Q_UNUSED(option)
+ Q_UNUSED(painter)
+}
+
+void Animation::drawBlendedImage(QPainter *painter, QRect rect, float alpha)
+{
+ if (m_secondaryImage.isNull() || m_primaryImage.isNull())
+ return;
+
+ if (m_tempImage.isNull())
+ m_tempImage = m_secondaryImage;
+
+ const int a = qRound(alpha*256);
+ const int ia = 256 - a;
+ const int sw = m_primaryImage.width();
+ const int sh = m_primaryImage.height();
+ const int bpl = m_primaryImage.bytesPerLine();
+ switch (m_primaryImage.depth()) {
+ case 32:
+ {
+ uchar *mixed_data = m_tempImage.bits();
+ const uchar *back_data = m_primaryImage.bits();
+ const uchar *front_data = m_secondaryImage.bits();
+ for (int sy = 0; sy < sh; sy++) {
+ quint32 *mixed = (quint32*)mixed_data;
+ const quint32* back = (const quint32*)back_data;
+ const quint32* front = (const quint32*)front_data;
+ for (int sx = 0; sx < sw; sx++) {
+ quint32 bp = back[sx];
+ quint32 fp = front[sx];
+ mixed[sx] = qRgba ((qRed(bp)*ia + qRed(fp)*a)>>8,
+ (qGreen(bp)*ia + qGreen(fp)*a)>>8,
+ (qBlue(bp)*ia + qBlue(fp)*a)>>8,
+ (qAlpha(bp)*ia + qAlpha(fp)*a)>>8);
+ }
+ mixed_data += bpl;
+ back_data += bpl;
+ front_data += bpl;
+ }
+ }
+ default:
+ break;
+ }
+ painter->drawImage(rect, m_tempImage);
+}
+
+void Transition::paint(QPainter *painter, const QStyleOption *option)
+{
+ float alpha = 1.0;
+ if (m_duration > 0) {
+ QTime current = QTime::currentTime();
+
+ if (m_startTime > current)
+ m_startTime = current;
+
+ int timeDiff = m_startTime.msecsTo(current);
+ alpha = timeDiff/(float)m_duration;
+ if (timeDiff > m_duration) {
+ m_running = false;
+ alpha = 1.0;
+ }
+ }
+ else {
+ m_running = false;
+ }
+ drawBlendedImage(painter, option->rect, alpha);
+}
+
+void StyleAnimator::timerEvent(QTimerEvent *)
+{
+ for (int i = animations.size() - 1 ; i >= 0 ; --i) {
+ if (animations[i]->widget())
+ animations[i]->widget()->update();
+
+ if (!animations[i]->widget() ||
+ !animations[i]->widget()->isEnabled() ||
+ !animations[i]->widget()->isVisible() ||
+ animations[i]->widget()->window()->isMinimized() ||
+ !animations[i]->running())
+ {
+ Animation *a = animations.takeAt(i);
+ delete a;
+ }
+ }
+ if (animations.size() == 0 && animationTimer.isActive()) {
+ animationTimer.stop();
+ }
+}
+
+void StyleAnimator::stopAnimation(const QWidget *w)
+{
+ for (int i = animations.size() - 1 ; i >= 0 ; --i) {
+ if (animations[i]->widget() == w) {
+ Animation *a = animations.takeAt(i);
+ delete a;
+ break;
+ }
+ }
+}
+
+void StyleAnimator::startAnimation(Animation *t)
+{
+ stopAnimation(t->widget());
+ animations.append(t);
+ if (animations.size() > 0 && !animationTimer.isActive()) {
+ animationTimer.start(35, this);
+ }
+}
diff --git a/library/style/styleanimator.h b/library/style/styleanimator.h
new file mode 100644
index 0000000..5b81827
--- /dev/null
+++ b/library/style/styleanimator.h
@@ -0,0 +1,101 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef ANIMATION_H
+#define ANIMATION_H
+
+#include <QtCore/QPointer>
+#include <QtCore/QTime>
+#include <QtCore/QBasicTimer>
+#include <QtGui/QStyle>
+#include <QtGui/QPainter>
+#include <QtGui/QWidget>
+
+/*
+ * This is a set of helper classes to allow for widget animations in
+ * the style. Its mostly taken from Vista style so it should be fully documented
+ * there.
+ *
+ */
+
+class Animation
+{
+public :
+ Animation() : m_running(true) { }
+ virtual ~Animation() { }
+ QWidget * widget() const { return m_widget; }
+ bool running() const { return m_running; }
+ const QTime &startTime() const { return m_startTime; }
+ void setRunning(bool val) { m_running = val; }
+ void setWidget(QWidget *widget) { m_widget = widget; }
+ void setStartTime(const QTime &startTime) { m_startTime = startTime; }
+ virtual void paint(QPainter *painter, const QStyleOption *option);
+
+protected:
+ void drawBlendedImage(QPainter *painter, QRect rect, float value);
+ QTime m_startTime;
+ QPointer<QWidget> m_widget;
+ QImage m_primaryImage;
+ QImage m_secondaryImage;
+ QImage m_tempImage;
+ bool m_running;
+};
+
+// Handles state transition animations
+class Transition : public Animation
+{
+public :
+ Transition() : Animation() {}
+ virtual ~Transition() {}
+ void setDuration(int duration) { m_duration = duration; }
+ void setStartImage(const QImage &image) { m_primaryImage = image; }
+ void setEndImage(const QImage &image) { m_secondaryImage = image; }
+ virtual void paint(QPainter *painter, const QStyleOption *option);
+ int duration() const { return m_duration; }
+ int m_duration; //set time in ms to complete a state transition
+};
+
+class StyleAnimator : public QObject
+{
+ Q_OBJECT
+
+public:
+ StyleAnimator(QObject *parent = 0) : QObject(parent) {}
+
+ void timerEvent(QTimerEvent *);
+ void startAnimation(Animation *);
+ void stopAnimation(const QWidget *);
+ Animation* widgetAnimation(const QWidget *) const;
+
+private:
+ QBasicTimer animationTimer;
+ QList <Animation*> animations;
+};
+
+#endif // ANIMATION_H
diff --git a/library/style/styledbar.cpp b/library/style/styledbar.cpp
new file mode 100644
index 0000000..ad7416d
--- /dev/null
+++ b/library/style/styledbar.cpp
@@ -0,0 +1,93 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "styledbar.h"
+
+#include "stylehelper.h"
+
+#include <QtCore/QVariant>
+#include <QtGui/QPainter>
+#include <QtGui/QPixmapCache>
+#include <QtGui/QStyle>
+#include <QtGui/QStyleOption>
+
+StyledBar::StyledBar(QWidget *parent)
+ : QWidget(parent)
+{
+ setProperty("panelwidget", true);
+ setProperty("panelwidget_singlerow", true);
+ setProperty("lightColored", false);
+}
+
+void StyledBar::setSingleRow(bool singleRow)
+{
+ setProperty("panelwidget_singlerow", singleRow);
+}
+
+bool StyledBar::isSingleRow() const
+{
+ return property("panelwidget_singlerow").toBool();
+}
+
+void StyledBar::setLightColored(bool lightColored)
+{
+ setProperty("lightColored", lightColored);
+}
+
+bool StyledBar::isLightColored() const
+{
+ return property("lightColored").toBool();
+}
+
+void StyledBar::paintEvent(QPaintEvent *event)
+{
+ Q_UNUSED(event)
+ QPainter painter(this);
+ QStyleOption option;
+ option.rect = rect();
+ option.state = QStyle::State_Horizontal;
+ style()->drawControl(QStyle::CE_ToolBar, &option, &painter, this);
+}
+
+StyledSeparator::StyledSeparator(QWidget *parent)
+ : QWidget(parent)
+{
+ setFixedWidth(10);
+}
+
+void StyledSeparator::paintEvent(QPaintEvent *event)
+{
+ Q_UNUSED(event)
+ QPainter painter(this);
+ QStyleOption option;
+ option.rect = rect();
+ option.state = QStyle::State_Horizontal;
+ option.palette = palette();
+ style()->drawPrimitive(QStyle::PE_IndicatorToolBarSeparator, &option, &painter, this);
+}
diff --git a/library/style/styledbar.h b/library/style/styledbar.h
new file mode 100644
index 0000000..72469f6
--- /dev/null
+++ b/library/style/styledbar.h
@@ -0,0 +1,57 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef STYLEDBAR_H
+#define STYLEDBAR_H
+
+#include <QtGui/QWidget>
+
+class StyledBar : public QWidget
+{
+public:
+ StyledBar(QWidget *parent = 0);
+ void setSingleRow(bool singleRow);
+ bool isSingleRow() const;
+
+ void setLightColored(bool lightColored);
+ bool isLightColored() const;
+
+protected:
+ void paintEvent(QPaintEvent *event);
+};
+
+class StyledSeparator : public QWidget
+{
+public:
+ StyledSeparator(QWidget *parent = 0);
+protected:
+ void paintEvent(QPaintEvent *event);
+};
+
+#endif // STYLEDBAR_H
diff --git a/library/style/stylehelper.cpp b/library/style/stylehelper.cpp
new file mode 100644
index 0000000..1983ede
--- /dev/null
+++ b/library/style/stylehelper.cpp
@@ -0,0 +1,296 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "stylehelper.h"
+
+#include <QtGui/QPixmapCache>
+#include <QtGui/QWidget>
+#include <QtCore/QRect>
+#include <QtGui/QPainter>
+#include <QtGui/QApplication>
+#include <QtGui/QPalette>
+
+// Clamps float color values within (0, 255)
+static int clamp(float x)
+{
+ const int val = x > 255 ? 255 : static_cast<int>(x);
+ return val < 0 ? 0 : val;
+}
+
+// Clamps float color values within (0, 255)
+/*
+static int range(float x, int min, int max)
+{
+ int val = x > max ? max : x;
+ return val < min ? min : val;
+}
+*/
+
+QColor StyleHelper::mergedColors(const QColor &colorA, const QColor &colorB, int factor)
+{
+ const int maxFactor = 100;
+ QColor tmp = colorA;
+ tmp.setRed((tmp.red() * factor) / maxFactor + (colorB.red() * (maxFactor - factor)) / maxFactor);
+ tmp.setGreen((tmp.green() * factor) / maxFactor + (colorB.green() * (maxFactor - factor)) / maxFactor);
+ tmp.setBlue((tmp.blue() * factor) / maxFactor + (colorB.blue() * (maxFactor - factor)) / maxFactor);
+ return tmp;
+}
+
+qreal StyleHelper::sidebarFontSize()
+{
+#if defined(Q_WS_MAC)
+ return 9;
+#else
+ return 7.5;
+#endif
+}
+
+QPalette StyleHelper::sidebarFontPalette(const QPalette &original)
+{
+ QPalette palette = original;
+ palette.setColor(QPalette::Active, QPalette::Text, panelTextColor());
+ palette.setColor(QPalette::Active, QPalette::WindowText, panelTextColor());
+ palette.setColor(QPalette::Inactive, QPalette::Text, panelTextColor().darker());
+ palette.setColor(QPalette::Inactive, QPalette::WindowText, panelTextColor().darker());
+ return palette;
+}
+
+QColor StyleHelper::panelTextColor(bool lightColored)
+{
+ //qApp->palette().highlightedText().color();
+ if (!lightColored)
+ return Qt::white;
+ else
+ return Qt::black;
+}
+
+QColor StyleHelper::m_baseColor(0x666666);
+
+QColor StyleHelper::baseColor(bool lightColored)
+{
+ if (!lightColored)
+ return m_baseColor;
+ else
+ return m_baseColor.lighter(230);
+}
+
+QColor StyleHelper::highlightColor(bool lightColored)
+{
+ QColor result = baseColor(lightColored);
+ if (!lightColored)
+ result.setHsv(result.hue(),
+ clamp(result.saturation()),
+ clamp(result.value() * 1.16));
+ else
+ result.setHsv(result.hue(),
+ clamp(result.saturation()),
+ clamp(result.value() * 1.06));
+ return result;
+}
+
+QColor StyleHelper::shadowColor(bool lightColored)
+{
+ QColor result = baseColor(lightColored);
+ result.setHsv(result.hue(),
+ clamp(result.saturation() * 1.1),
+ clamp(result.value() * 0.70));
+ return result;
+}
+
+QColor StyleHelper::borderColor(bool lightColored)
+{
+ QColor result = baseColor(lightColored);
+ result.setHsv(result.hue(),
+ result.saturation(),
+ result.value() / 2);
+ return result;
+}
+
+void StyleHelper::setBaseColor(const QColor &color)
+{
+ if (color.isValid() && color != m_baseColor) {
+ m_baseColor = color;
+ foreach (QWidget *w, QApplication::topLevelWidgets())
+ w->update();
+ }
+}
+
+static void verticalGradientHelper(QPainter *p, const QRect &spanRect, const QRect &rect, bool lightColored)
+{
+ QColor base = StyleHelper::baseColor(lightColored);
+ QColor highlight = StyleHelper::highlightColor(lightColored);
+ QColor shadow = StyleHelper::shadowColor(lightColored);
+ QLinearGradient grad(spanRect.topRight(), spanRect.topLeft());
+ grad.setColorAt(0, highlight);
+ grad.setColorAt(0.301, base);
+ grad.setColorAt(1, shadow);
+ p->fillRect(rect, grad);
+
+ QColor light(255, 255, 255, 80);
+ p->setPen(light);
+ p->drawLine(rect.topRight() - QPoint(1, 0), rect.bottomRight() - QPoint(1, 0));
+}
+
+void StyleHelper::verticalGradient(QPainter *painter, const QRect &spanRect, const QRect &clipRect, bool lightColored)
+{
+ if (StyleHelper::usePixmapCache()) {
+ QString key;
+ QColor keyColor = StyleHelper::baseColor(lightColored);
+ key.sprintf("mh_vertical %d %d %d %d %d",
+ spanRect.width(), spanRect.height(), clipRect.width(),
+ clipRect.height(), keyColor.rgb());;
+
+ QPixmap pixmap;
+ if (!QPixmapCache::find(key, pixmap)) {
+ pixmap = QPixmap(clipRect.size());
+ QPainter p(&pixmap);
+ QRect rect(0, 0, clipRect.width(), clipRect.height());
+ verticalGradientHelper(&p, spanRect, rect, lightColored);
+ p.end();
+ QPixmapCache::insert(key, pixmap);
+ }
+
+ painter->drawPixmap(clipRect.topLeft(), pixmap);
+ } else {
+ verticalGradientHelper(painter, spanRect, clipRect, lightColored);
+ }
+}
+
+static void horizontalGradientHelper(QPainter *p, const QRect &spanRect, const
+QRect &rect, bool lightColored)
+{
+ QColor base = StyleHelper::baseColor(lightColored);
+ QColor highlight = StyleHelper::highlightColor(lightColored);
+ QColor shadow = StyleHelper::shadowColor(lightColored);
+ QLinearGradient grad(rect.topLeft(), rect.bottomLeft());
+ grad.setColorAt(0, highlight.lighter(120));
+ if (rect.height() == StyleHelper::navigationWidgetHeight()) {
+ grad.setColorAt(0.4, highlight);
+ grad.setColorAt(0.401, base);
+ }
+ grad.setColorAt(1, shadow);
+ p->fillRect(rect, grad);
+
+ QLinearGradient shadowGradient(spanRect.topLeft(), spanRect.topRight());
+ shadowGradient.setColorAt(0, QColor(0, 0, 0, 30));
+ QColor lighterHighlight;
+ if (!lightColored)
+ lighterHighlight = highlight.lighter(130);
+ else
+ lighterHighlight = highlight.lighter(90);
+ lighterHighlight.setAlpha(100);
+ shadowGradient.setColorAt(0.7, lighterHighlight);
+ shadowGradient.setColorAt(1, QColor(0, 0, 0, 40));
+ p->fillRect(rect, shadowGradient);
+}
+
+void StyleHelper::horizontalGradient(QPainter *painter, const QRect &spanRect, const QRect &clipRect, bool lightColored)
+{
+ if (StyleHelper::usePixmapCache()) {
+ QString key;
+ QColor keyColor = StyleHelper::baseColor(lightColored);
+ key.sprintf("mh_horizontal %d %d %d %d %d",
+ spanRect.width(), spanRect.height(), clipRect.width(),
+ clipRect.height(), keyColor.rgb());
+
+ QPixmap pixmap;
+ if (!QPixmapCache::find(key, pixmap)) {
+ pixmap = QPixmap(clipRect.size());
+ QPainter p(&pixmap);
+ QRect rect = QRect(0, 0, clipRect.width(), clipRect.height());
+ horizontalGradientHelper(&p, spanRect, rect, lightColored);
+ p.end();
+ QPixmapCache::insert(key, pixmap);
+ }
+
+ painter->drawPixmap(clipRect.topLeft(), pixmap);
+
+ } else {
+ horizontalGradientHelper(painter, spanRect, clipRect, lightColored);
+ }
+}
+
+static void menuGradientHelper(QPainter *p, const QRect &spanRect, const QRect &rect)
+{
+ QLinearGradient grad(spanRect.topLeft(), spanRect.bottomLeft());
+ QColor menuColor = StyleHelper::mergedColors(StyleHelper::baseColor(), QColor(244, 244, 244), 25);
+ grad.setColorAt(0, menuColor.lighter(112));
+ grad.setColorAt(1, menuColor);
+ p->fillRect(rect, grad);
+}
+
+void StyleHelper::menuGradient(QPainter *painter, const QRect &spanRect, const QRect &clipRect)
+{
+ if (StyleHelper::usePixmapCache()) {
+ QString key;
+ key.sprintf("mh_menu %d %d %d %d %d",
+ spanRect.width(), spanRect.height(), clipRect.width(),
+ clipRect.height(), StyleHelper::baseColor().rgb());
+
+ QPixmap pixmap;
+ if (!QPixmapCache::find(key, pixmap)) {
+ pixmap = QPixmap(clipRect.size());
+ QPainter p(&pixmap);
+ QRect rect = QRect(0, 0, clipRect.width(), clipRect.height());
+ menuGradientHelper(&p, spanRect, rect);
+ p.end();
+ QPixmapCache::insert(key, pixmap);
+ }
+
+ painter->drawPixmap(clipRect.topLeft(), pixmap);
+ } else {
+ menuGradientHelper(painter, spanRect, clipRect);
+ }
+}
+
+void StyleHelper::rectWithLeftLine(const QWidget *widget, QPainter *painter, const QRect &rect)
+{
+ painter->save();
+ painter->setBrush(QBrush(widget->palette().background()));
+ painter->setPen(Qt::NoPen);
+ painter->drawRect(rect);
+ QPen pen = painter->pen();
+ pen.setColor(highlightColor().lighter());
+ pen.setStyle(Qt::SolidLine);
+ painter->setPen(pen);
+ painter->drawLine(rect.topLeft(), rect.bottomLeft());
+ painter->restore();
+}
+
+void StyleHelper::drawSlider(QPainter *painter, const QRect &rect)
+{
+ QColor base = StyleHelper::baseColor();
+ QLinearGradient grad(rect.topRight(), rect.topLeft());
+ grad.setColorAt(0, base.lighter());
+ grad.setColorAt(1, base.lighter(190));
+ painter->setRenderHint(QPainter::Antialiasing);
+ painter->setBrush(grad);
+ painter->setPen(Qt::NoPen);
+ painter->drawRoundedRect(rect, 3, 3);
+}
diff --git a/library/style/stylehelper.h b/library/style/stylehelper.h
new file mode 100644
index 0000000..69765e2
--- /dev/null
+++ b/library/style/stylehelper.h
@@ -0,0 +1,77 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef STYLEHELPER_H
+#define STYLEHELPER_H
+
+#include <QtGui/QColor>
+
+QT_BEGIN_NAMESPACE
+class QPalette;
+class QPainter;
+class QRect;
+QT_END_NAMESPACE
+
+// Helper class holding all custom color values
+
+class StyleHelper
+{
+public:
+ // Height of the project explorer navigation bar
+ static int navigationWidgetHeight() { return 24; }
+ static qreal sidebarFontSize();
+ static QPalette sidebarFontPalette(const QPalette &original);
+
+ // This is our color table, all colors derive from baseColor
+ static QColor baseColor(bool lightColored = false);
+ static QColor panelTextColor(bool lightColored = false);
+ static QColor highlightColor(bool lightColored = false);
+ static QColor shadowColor(bool lightColored = false);
+ static QColor borderColor(bool lightColored = false);
+ static QColor buttonTextColor() { return QColor(0x4c4c4c); }
+ static QColor mergedColors(const QColor &colorA, const QColor &colorB, int factor = 50);
+
+ // Sets the base color and makes sure all top level widgets are updated
+ static void setBaseColor(const QColor &color);
+
+ // Gradients used for panels
+ static void horizontalGradient(QPainter *painter, const QRect &spanRect, const QRect &clipRect, bool lightColored = false);
+ static void verticalGradient(QPainter *painter, const QRect &spanRect, const QRect &clipRect, bool lightColored = false);
+ static void menuGradient(QPainter *painter, const QRect &spanRect, const QRect &clipRect);
+
+ static void rectWithLeftLine(const QWidget *widget, QPainter *painter, const QRect &rect);
+ static void drawSlider(QPainter *painter, const QRect &rect);
+
+ // Pixmap cache should only be enabled for X11 due to slow gradients
+ static bool usePixmapCache() { return true; }
+
+private:
+ static QColor m_baseColor;
+};
+#endif // STYLEHELPER_H
diff --git a/library/toolbox.cpp b/library/toolbox.cpp
new file mode 100644
index 0000000..eb88a45
--- /dev/null
+++ b/library/toolbox.cpp
@@ -0,0 +1,366 @@
+#include "toolbox.h"
+#include "style/styledbar.h"
+
+#include <QtCore/QStringList>
+#include <QtGui/QPushButton>
+#include <QtGui/QToolButton>
+#include <QtGui/QLabel>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QFormLayout>
+#include <QtGui/QSpacerItem>
+
+ToolBox::ToolBox(bool pagesOpenOnInsertion, QWidget *parent, Qt::WindowFlags f)
+ : QFrame(parent, f)
+ , mLayout(0)
+ , mLargestMinimalInputWidth(0)
+ , mDefaultPagesOpen(pagesOpenOnInsertion)
+{
+ mLayout = new QVBoxLayout();
+ mLayout->setAlignment(Qt::AlignTop);
+ mLayout->setSpacing(0);
+ mLayout->setMargin(0);
+ mLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::MinimumExpanding));
+ setLayout(mLayout);
+}
+
+ToolBox::~ToolBox()
+{
+}
+
+bool ToolBox::addPage(const QString &title, const QList<OptionsItem *> &options)
+{
+ return insertPage(-1, title, options);
+}
+bool ToolBox::insertPage(int index, const QString &title, const QList<OptionsItem *> &options)
+{
+ if (index == -1)
+ index = layout()->count() - 1; //As the spacer is the layout's last item
+ if (index < 0 || index > layout()->count() - 1)
+ return false;
+ ToolBoxPage *page = new ToolBoxPage(title, options, this);
+ page->setStyle(style());
+ mLayout->insertWidget(index, page);
+ mPages.insert(index, page);
+ connect(page, SIGNAL(minimalInputWidthChanged(int)), SLOT(processPageMinimalInputWidth(int)));
+ page->init();
+ if (mDefaultPagesOpen && page->isHidden())
+ page->showContent(true);
+ return true;
+}
+
+bool ToolBox::insertPageIntoLayout(int index, ToolBoxPage *page)
+{
+ if (index == -1)
+ index = layout()->count() - 1; //As the spacer is the layout's last item
+ if (index < 0 || index > layout()->count() - 1)
+ return false;
+ mLayout->insertWidget(index, page);
+ return true;
+}
+
+bool ToolBox::removePageFromLayout(ToolBoxPage *page)
+{
+ int pageIndex = mLayout->indexOf(page);
+ if (pageIndex == -1)
+ return false;
+ mLayout->removeWidget(page);
+ return true;
+}
+
+void ToolBox::filtersChanged(const QString &filters)
+{
+ QStringList filterList = filters.split(' ', QString::SkipEmptyParts);
+ int i = 0;
+ foreach(ToolBoxPage *page, mPages) {
+ int itemCount = 0;
+ itemCount = page->filtersChanged(filterList);
+ int pageIndex = mLayout->indexOf(page);
+ // Increase i a) if the layout already contains the page and it is not removed
+ // or b) if the page is added. Thereby we keep the order of the toolboxpages.
+ if (pageIndex != -1)
+ {
+ if (itemCount == 0) {
+ removePageFromLayout(page);
+ page->setVisible(false);
+ } else {
+ i++;
+ }
+ }
+ else if (itemCount > 0 && pageIndex == -1) {
+ insertPageIntoLayout(i, page);
+ page->setVisible(true);
+ i++;
+ }
+ }
+}
+
+void ToolBox::processPageMinimalInputWidth(int newWidth)
+{
+ if (newWidth > mLargestMinimalInputWidth)
+ {
+ mLargestMinimalInputWidth = newWidth;
+ foreach (ToolBoxPage *page, mPages)
+ page->setFixedInputWidth(newWidth);
+ }
+}
+
+ToolBoxPage::ToolBoxPage(const QString &title, const QList<OptionsItem *> &options, ToolBox *box)
+ : QFrame(box)
+ , mButton(0)
+ , mPage(0)
+ , mInnerLayout(0)
+ , mHeaderLayout(0)
+ , mOptions(options)
+ , mAdvancedMode(false)
+ , mExplicitOpen(false)
+ , mMinimalInputWidth(0)
+{
+ setFrameShadow(QFrame::Raised);
+
+ QVBoxLayout *vLayout = new QVBoxLayout();
+ vLayout->setMargin(0);
+ setLayout(vLayout);
+
+ mButton = new QToolButton(this);
+ mButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ mButton->setText(title);
+ mButton->setArrowType(Qt::RightArrow);
+ mButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ mButton->setStyle(box->style());
+ connect(mButton, SIGNAL(clicked()), SLOT(toggleOpenExplicitly()));
+ mHeaderLayout = new QHBoxLayout();
+ mHeaderLayout->setSpacing(0);
+ mHeaderLayout->setContentsMargins(0,0,0,0);
+ mHeaderLayout->addWidget(mButton);
+ StyledBar *top = new StyledBar;
+ top->setStyle(box->style());
+ top->setLightColored(true);
+ top->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
+ top->setLayout(mHeaderLayout);
+ vLayout->addWidget(top);
+
+ mPage = new QWidget(this);
+ mInnerLayout = new QFormLayout();
+ mInnerLayout->setVerticalSpacing(9);
+ mInnerLayout->setRowWrapPolicy(QFormLayout::WrapLongRows);
+ mInnerLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
+ mInnerLayout->setLabelAlignment(Qt::AlignLeft);
+ mPage->setLayout(mInnerLayout);
+ mPage->hide();
+}
+
+ToolBoxPage::~ToolBoxPage()
+{
+}
+
+void ToolBoxPage::init()
+{
+ //Initially add all the "basic" items to the page, even if nothing is visible
+ int foundItems = findUnfilteredItems();
+ //If the number of unfiltered items is smaller than the one of the given options,
+ //there have to be advanced items
+ if (foundItems < mOptions.count())
+ addAdvancedButtonToHeader();
+ emit minimalInputWidthChanged(mMinimalInputWidth);
+}
+
+void ToolBoxPage::showContent(bool show)
+{
+ QVBoxLayout *vLayout = qobject_cast<QVBoxLayout*>(layout());
+ if (show) {
+ if (vLayout->indexOf(mPage) == -1)
+ vLayout->addWidget(mPage);
+ mPage->show();
+ mButton->setArrowType(Qt::DownArrow);
+ } else {
+ if (vLayout->indexOf(mPage) != -1)
+ vLayout->removeWidget(mPage);
+ mPage->hide();
+ mButton->setArrowType(Qt::RightArrow);
+ }
+}
+
+void ToolBoxPage::toggleOpenExplicitly()
+{
+ if (mPage->isHidden())
+ mExplicitOpen = true;
+ else
+ mExplicitOpen = false;
+ showContent(mExplicitOpen);
+}
+
+void ToolBoxPage::setAdvanced(bool advanced)
+{
+ mAdvancedMode = advanced;
+ if (mLastFilters.isEmpty()) {
+ findUnfilteredItems();
+ showContent(true);
+ }
+}
+
+void ToolBoxPage::addItem(OptionsItem *item)
+{
+ insertItem(-1, item);
+}
+
+void ToolBoxPage::insertItem(int row, OptionsItem *item)
+{
+ if (row == -1)
+ row = mInnerLayout->count();
+ if (item->type() == OptionsItem::FullWidthType)
+ mInnerLayout->insertRow(row, item->inputWidget());
+ else {
+ item->inputLayout()->setParent(0);
+ mInnerLayout->insertRow(row, item->label(), item->inputLayout());
+ }
+ item->setVisible(true);
+
+ if (item->type() == OptionsItem::AdvancedType) {
+ connect(item, SIGNAL(toggleAdvanced(OptionsItem *)),
+ this, SLOT(advancedToggled(OptionsItem *)));
+ }
+ int width = item->inputWidget()->sizeHint().width();
+ if (item->type() != OptionsItem::FullWidthType
+ && width > mMinimalInputWidth)
+ mMinimalInputWidth = width;
+}
+
+void ToolBoxPage::addItemsAndSpacer(QList<OptionsItem *> items)
+{
+ foreach (OptionsItem *item, items)
+ addItem(item);
+ if (mInnerLayout->count() > 0)
+ mInnerLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
+}
+
+void ToolBoxPage::setFixedInputWidth(int newInputWidth)
+{
+ // force size
+ foreach (OptionsItem *item, mOptions) {
+ if (item->type() != OptionsItem::FullWidthType)
+ item->inputWidget()->setFixedWidth(newInputWidth);
+ }
+}
+
+void ToolBoxPage::addAdvancedButtonToHeader()
+{
+ if (mHeaderLayout->count() == 1) {
+ QToolButton *advancedButton = new QToolButton();
+ advancedButton->setCheckable(true);
+ advancedButton->setIcon(QIcon(":/style/images/advanced.png"));
+ mHeaderLayout->addWidget(advancedButton);
+ connect(advancedButton, SIGNAL(toggled(bool)), SLOT(setAdvanced(bool)));
+ }
+}
+
+unsigned int ToolBoxPage::filtersChanged(const QStringList &filters)
+{
+ mLastFilters = filters;
+ int foundItems = 0;
+ if (filters.length() == 0) {
+ foundItems = findUnfilteredItems();
+ showContent(mExplicitOpen);
+ } else {
+ foundItems = findFilteredItems(filters);
+ if (foundItems > 0)
+ showContent(true);
+ }
+ return foundItems;
+}
+
+bool ToolBoxPage::filterItem(const QStringList &filters, OptionsItem *option)
+{
+ // If the option has an advanced page and this page is opened, close it before applying the filter
+ if (option->type() == OptionsItem::AdvancedType && !option->advancedPage()->inputWidget()->isHidden())
+ advancedToggled(option);
+ if (option->isExplicitlyHidden())
+ return false;
+
+ option->setVisible(false);
+ foreach (const QString &filter, filters) {
+ if (option->matchTag(filter)) {
+ addItem(option);
+ return true;
+ }
+ }
+ return false;
+}
+
+unsigned int ToolBoxPage::findFilteredItems(const QStringList &filters)
+{
+ // remove current options
+ while (mInnerLayout->count())
+ mInnerLayout->takeAt(0);
+
+ // add matching
+ QList<OptionsItem *> shownItems;
+ foreach(OptionsItem *item, mOptions) {
+ if (item->type() == OptionsItem::AdvancedType) {
+ if (!item->advancedPage()->inputWidget()->isHidden())
+ advancedToggled(item);
+ disconnect(item, SIGNAL(toggleAdvanced(OptionsItem *)),
+ this, SLOT(advancedToggled(OptionsItem *)));
+ }
+ if (filterItem(filters, item)) {
+ shownItems += item;
+ }
+ }
+
+ addItemsAndSpacer(shownItems);
+
+ return shownItems.count();
+}
+
+unsigned int ToolBoxPage::findUnfilteredItems()
+{
+ //If a filter is applied, just ignore the call
+ if (mLastFilters.length() > 0)
+ return 0;
+
+ while (mInnerLayout->count())
+ mInnerLayout->takeAt(0);
+
+ QList<OptionsItem *> shownItems;
+ foreach(OptionsItem *item, mOptions) {
+ if (item && item->type() == OptionsItem::AdvancedType) {
+ if (!item->advancedPage()->inputWidget()->isHidden())
+ advancedToggled(item);
+ disconnect(item, SIGNAL(toggleAdvanced(OptionsItem *)),
+ this, SLOT(advancedToggled(OptionsItem *)));
+ }
+ if ((!mAdvancedMode && item->isAdvanced()) || item->isExplicitlyHidden())
+ {
+ item->setVisible(false);
+ continue;
+ }
+
+ shownItems += item;
+
+ }
+
+ addItemsAndSpacer(shownItems);
+
+ return shownItems.count();
+}
+
+void ToolBoxPage::advancedToggled(OptionsItem *item)
+{
+ QAbstractButton *clickedButton = qobject_cast<QAbstractButton *>(item->inputWidget());
+ if (clickedButton->text() == tr("Show"))
+ clickedButton->setText(tr("Hide"));
+ else
+ clickedButton->setText(tr("Show"));
+
+ QWidget *advancedInput = item->advancedPage()->inputWidget();
+ if (!advancedInput->isHidden())
+ {
+ mInnerLayout->removeWidget(advancedInput);
+ advancedInput->hide();
+ } else {
+ int row = 0;
+ mInnerLayout->getLayoutPosition(item->inputLayout(), &row, 0);
+ ++row;
+ mInnerLayout->insertRow(row, advancedInput);
+ advancedInput->show();
+ }
+}
diff --git a/library/toolbox.h b/library/toolbox.h
new file mode 100644
index 0000000..6ce7425
--- /dev/null
+++ b/library/toolbox.h
@@ -0,0 +1,92 @@
+#ifndef TOOLBOX_H
+#define TOOLBOX_H
+
+#include "optionsitem.h"
+
+#include <QtGui/QFrame>
+#include <QtGui/QWidget>
+#include <QtCore/QList>
+
+class ToolBoxPage;
+class QToolButton;
+class QFormLayout;
+class OptionsItem;
+class QStringList;
+class QVBoxLayout;
+class QHBoxLayout;
+
+class ToolBox : public QFrame
+{
+ Q_OBJECT
+public:
+
+ explicit ToolBox(bool pagesOpenOnInsertion = false, QWidget *parent = 0, Qt::WindowFlags f = 0);
+ virtual ~ToolBox();
+
+public:
+ bool addPage(const QString &title, const QList<OptionsItem *> &options);
+ bool insertPage(int index, const QString &title, const QList<OptionsItem *> &options);
+
+ void filtersChanged(const QString &filters);
+
+private:
+ bool insertPageIntoLayout(int index, ToolBoxPage *page);
+ bool removePageFromLayout(ToolBoxPage *page);
+ QVBoxLayout *mLayout;
+ int mLargestMinimalInputWidth;
+
+ bool mDefaultPagesOpen;
+ QList<ToolBoxPage *> mPages;
+
+private slots:
+ void processPageMinimalInputWidth(int newWidth);
+};
+
+class ToolBoxPage : public QFrame
+{
+ Q_OBJECT
+ friend class ToolBox;
+public:
+ ToolBoxPage(const QString &title, const QList<OptionsItem *> &options, ToolBox *box);
+ virtual ~ToolBoxPage();
+
+public slots:
+ unsigned int filtersChanged(const QStringList &filters);
+ void advancedToggled(OptionsItem *item);
+
+private:
+ QToolButton *mButton;
+ QWidget *mPage;
+ QFormLayout *mInnerLayout;
+ QHBoxLayout *mHeaderLayout;
+ QList<OptionsItem *> mOptions;
+ bool mAdvancedMode;
+ QStringList mLastFilters;
+ bool mExplicitOpen;
+ int mMinimalInputWidth;
+
+ void init();
+ void addAdvancedButtonToHeader();
+ void addItem(OptionsItem *item);
+ void insertItem(int row, OptionsItem *item);
+
+ void showContent(bool show);
+
+ bool filterItem(const QStringList &filters, OptionsItem * option);
+
+ unsigned int findFilteredItems(const QStringList &filters);
+ unsigned int findUnfilteredItems();
+
+ void addItemsAndSpacer(QList<OptionsItem *> items);
+
+ void setFixedInputWidth(int newInputWidth);
+
+private slots:
+ void toggleOpenExplicitly();
+ void setAdvanced(bool advanced);
+
+signals:
+ void minimalInputWidthChanged(int newWidth);
+};
+
+#endif //TOOLBOX_H