diff options
author | axis <qt-info@nokia.com> | 2009-04-24 11:34:15 (GMT) |
---|---|---|
committer | axis <qt-info@nokia.com> | 2009-04-24 11:34:15 (GMT) |
commit | 8f427b2b914d5b575a4a7c0ed65d2fb8f45acc76 (patch) | |
tree | a17e1a767a89542ab59907462206d7dcf2e504b2 /demos/mainwindow | |
download | Qt-8f427b2b914d5b575a4a7c0ed65d2fb8f45acc76.zip Qt-8f427b2b914d5b575a4a7c0ed65d2fb8f45acc76.tar.gz Qt-8f427b2b914d5b575a4a7c0ed65d2fb8f45acc76.tar.bz2 |
Long live Qt for S60!
Diffstat (limited to 'demos/mainwindow')
-rw-r--r-- | demos/mainwindow/colorswatch.cpp | 746 | ||||
-rw-r--r-- | demos/mainwindow/colorswatch.h | 136 | ||||
-rw-r--r-- | demos/mainwindow/main.cpp | 164 | ||||
-rw-r--r-- | demos/mainwindow/mainwindow.cpp | 510 | ||||
-rw-r--r-- | demos/mainwindow/mainwindow.h | 90 | ||||
-rw-r--r-- | demos/mainwindow/mainwindow.pro | 18 | ||||
-rw-r--r-- | demos/mainwindow/mainwindow.qrc | 8 | ||||
-rw-r--r-- | demos/mainwindow/qt.png | bin | 0 -> 2037 bytes | |||
-rw-r--r-- | demos/mainwindow/titlebarCenter.png | bin | 0 -> 146 bytes | |||
-rw-r--r-- | demos/mainwindow/titlebarLeft.png | bin | 0 -> 5148 bytes | |||
-rw-r--r-- | demos/mainwindow/titlebarRight.png | bin | 0 -> 2704 bytes | |||
-rw-r--r-- | demos/mainwindow/toolbar.cpp | 383 | ||||
-rw-r--r-- | demos/mainwindow/toolbar.h | 118 |
13 files changed, 2173 insertions, 0 deletions
diff --git a/demos/mainwindow/colorswatch.cpp b/demos/mainwindow/colorswatch.cpp new file mode 100644 index 0000000..ba6a076 --- /dev/null +++ b/demos/mainwindow/colorswatch.cpp @@ -0,0 +1,746 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "colorswatch.h" + +#include <QAction> +#include <QtEvents> +#include <QFrame> +#include <QMainWindow> +#include <QMenu> +#include <QPainter> +#include <QImage> +#include <QColor> +#include <QDialog> +#include <QGridLayout> +#include <QSpinBox> +#include <QLabel> +#include <QPainterPath> +#include <QPushButton> +#include <QHBoxLayout> +#include <QBitmap> +#include <QtDebug> + +#undef DEBUG_SIZEHINTS + +QColor bgColorForName(const QString &name) +{ + if (name == "Black") + return QColor("#D8D8D8"); + else if (name == "White") + return QColor("#F1F1F1"); + else if (name == "Red") + return QColor("#F1D8D8"); + else if (name == "Green") + return QColor("#D8E4D8"); + else if (name == "Blue") + return QColor("#D8D8F1"); + else if (name == "Yellow") + return QColor("#F1F0D8"); + return QColor(name).light(110); +} + +QColor fgColorForName(const QString &name) +{ + if (name == "Black") + return QColor("#6C6C6C"); + else if (name == "White") + return QColor("#F8F8F8"); + else if (name == "Red") + return QColor("#F86C6C"); + else if (name == "Green") + return QColor("#6CB26C"); + else if (name == "Blue") + return QColor("#6C6CF8"); + else if (name == "Yellow") + return QColor("#F8F76C"); + return QColor(name); +} + +class ColorDock : public QFrame +{ + Q_OBJECT +public: + ColorDock(const QString &c, QWidget *parent); + + virtual QSize sizeHint() const; + virtual QSize minimumSizeHint() const; + + void setCustomSizeHint(const QSize &size); + +public slots: + void changeSizeHints(); + +protected: + void paintEvent(QPaintEvent *); + QString color; + QSize szHint, minSzHint; +}; + +ColorDock::ColorDock(const QString &c, QWidget *parent) + : QFrame(parent) , color(c) +{ + QFont font = this->font(); + font.setPointSize(8); + setFont(font); + szHint = QSize(-1, -1); + minSzHint = QSize(125, 75); +} + +QSize ColorDock::sizeHint() const +{ + return szHint; +} + +QSize ColorDock::minimumSizeHint() const +{ + return minSzHint; +} + +void ColorDock::paintEvent(QPaintEvent *) +{ + QPainter p(this); + p.setRenderHint(QPainter::Antialiasing); + p.fillRect(rect(), bgColorForName(color)); + + p.save(); + + extern void render_qt_text(QPainter *, int, int, const QColor &); + render_qt_text(&p, width(), height(), fgColorForName(color)); + + p.restore(); + +#ifdef DEBUG_SIZEHINTS + p.setRenderHint(QPainter::Antialiasing, false); + + QSize sz = size(); + QSize szHint = sizeHint(); + QSize minSzHint = minimumSizeHint(); + QSize maxSz = maximumSize(); + QString text = QString::fromLatin1("sz: %1x%2\nszHint: %3x%4\nminSzHint: %5x%6\n" + "maxSz: %8x%9") + .arg(sz.width()).arg(sz.height()) + .arg(szHint.width()).arg(szHint.height()) + .arg(minSzHint.width()).arg(minSzHint.height()) + .arg(maxSz.width()).arg(maxSz.height()); + + QRect r = fontMetrics().boundingRect(rect(), Qt::AlignLeft|Qt::AlignTop, text); + r.adjust(-2, -2, 1, 1); + p.translate(4, 4); + QColor bg = Qt::yellow; + bg.setAlpha(120); + p.setBrush(bg); + p.setPen(Qt::black); + p.drawRect(r); + p.drawText(rect(), Qt::AlignLeft|Qt::AlignTop, text); +#endif // DEBUG_SIZEHINTS +} + +static QSpinBox *createSpinBox(int value, QWidget *parent, int max = 1000) +{ + QSpinBox *result = new QSpinBox(parent); + result->setMinimum(-1); + result->setMaximum(max); + result->setValue(value); + return result; +} + +void ColorDock::changeSizeHints() +{ + QDialog dialog(this); + dialog.setWindowTitle(color); + + QVBoxLayout *topLayout = new QVBoxLayout(&dialog); + + QGridLayout *inputLayout = new QGridLayout(); + topLayout->addLayout(inputLayout); + + inputLayout->addWidget(new QLabel(tr("Size Hint:"), &dialog), 0, 0); + inputLayout->addWidget(new QLabel(tr("Min Size Hint:"), &dialog), 1, 0); + inputLayout->addWidget(new QLabel(tr("Max Size:"), &dialog), 2, 0); + inputLayout->addWidget(new QLabel(tr("Dockwgt Max Size:"), &dialog), 3, 0); + + QSpinBox *szHintW = createSpinBox(szHint.width(), &dialog); + inputLayout->addWidget(szHintW, 0, 1); + QSpinBox *szHintH = createSpinBox(szHint.height(), &dialog); + inputLayout->addWidget(szHintH, 0, 2); + + QSpinBox *minSzHintW = createSpinBox(minSzHint.width(), &dialog); + inputLayout->addWidget(minSzHintW, 1, 1); + QSpinBox *minSzHintH = createSpinBox(minSzHint.height(), &dialog); + inputLayout->addWidget(minSzHintH, 1, 2); + + QSize maxSz = maximumSize(); + QSpinBox *maxSzW = createSpinBox(maxSz.width(), &dialog, QWIDGETSIZE_MAX); + inputLayout->addWidget(maxSzW, 2, 1); + QSpinBox *maxSzH = createSpinBox(maxSz.height(), &dialog, QWIDGETSIZE_MAX); + inputLayout->addWidget(maxSzH, 2, 2); + + QSize dwMaxSz = parentWidget()->maximumSize(); + QSpinBox *dwMaxSzW = createSpinBox(dwMaxSz.width(), &dialog, QWIDGETSIZE_MAX); + inputLayout->addWidget(dwMaxSzW, 3, 1); + QSpinBox *dwMaxSzH = createSpinBox(dwMaxSz.height(), &dialog, QWIDGETSIZE_MAX); + inputLayout->addWidget(dwMaxSzH, 3, 2); + + inputLayout->setColumnStretch(1, 1); + inputLayout->setColumnStretch(2, 1); + + topLayout->addStretch(); + + QHBoxLayout *buttonBox = new QHBoxLayout(); + topLayout->addLayout(buttonBox); + + QPushButton *okButton = new QPushButton(tr("Ok"), &dialog); + QPushButton *cancelButton = new QPushButton(tr("Cancel"), &dialog); + connect(okButton, SIGNAL(clicked()), &dialog, SLOT(accept())); + connect(cancelButton, SIGNAL(clicked()), &dialog, SLOT(reject())); + buttonBox->addStretch(); + buttonBox->addWidget(cancelButton); + buttonBox->addWidget(okButton); + + + if (!dialog.exec()) + return; + + szHint = QSize(szHintW->value(), szHintH->value()); + minSzHint = QSize(minSzHintW->value(), minSzHintH->value()); + maxSz = QSize(maxSzW->value(), maxSzH->value()); + setMaximumSize(maxSz); + dwMaxSz = QSize(dwMaxSzW->value(), dwMaxSzH->value()); + parentWidget()->setMaximumSize(dwMaxSz); + updateGeometry(); + update(); +} + +void ColorDock::setCustomSizeHint(const QSize &size) +{ + szHint = size; + updateGeometry(); +} + +ColorSwatch::ColorSwatch(const QString &colorName, QWidget *parent, Qt::WindowFlags flags) + : QDockWidget(parent, flags) +{ + setObjectName(colorName + QLatin1String(" Dock Widget")); + setWindowTitle(objectName() + QLatin1String(" [*]")); + + QFrame *swatch = new ColorDock(colorName, this); + swatch->setFrameStyle(QFrame::Box | QFrame::Sunken); + + setWidget(swatch); + + changeSizeHintsAction = new QAction(tr("Change Size Hints"), this); + connect(changeSizeHintsAction, SIGNAL(triggered()), swatch, SLOT(changeSizeHints())); + + closableAction = new QAction(tr("Closable"), this); + closableAction->setCheckable(true); + connect(closableAction, SIGNAL(triggered(bool)), SLOT(changeClosable(bool))); + + movableAction = new QAction(tr("Movable"), this); + movableAction->setCheckable(true); + connect(movableAction, SIGNAL(triggered(bool)), SLOT(changeMovable(bool))); + + floatableAction = new QAction(tr("Floatable"), this); + floatableAction->setCheckable(true); + connect(floatableAction, SIGNAL(triggered(bool)), SLOT(changeFloatable(bool))); + + verticalTitleBarAction = new QAction(tr("Vertical title bar"), this); + verticalTitleBarAction->setCheckable(true); + connect(verticalTitleBarAction, SIGNAL(triggered(bool)), + SLOT(changeVerticalTitleBar(bool))); + + floatingAction = new QAction(tr("Floating"), this); + floatingAction->setCheckable(true); + connect(floatingAction, SIGNAL(triggered(bool)), SLOT(changeFloating(bool))); + + allowedAreasActions = new QActionGroup(this); + allowedAreasActions->setExclusive(false); + + allowLeftAction = new QAction(tr("Allow on Left"), this); + allowLeftAction->setCheckable(true); + connect(allowLeftAction, SIGNAL(triggered(bool)), SLOT(allowLeft(bool))); + + allowRightAction = new QAction(tr("Allow on Right"), this); + allowRightAction->setCheckable(true); + connect(allowRightAction, SIGNAL(triggered(bool)), SLOT(allowRight(bool))); + + allowTopAction = new QAction(tr("Allow on Top"), this); + allowTopAction->setCheckable(true); + connect(allowTopAction, SIGNAL(triggered(bool)), SLOT(allowTop(bool))); + + allowBottomAction = new QAction(tr("Allow on Bottom"), this); + allowBottomAction->setCheckable(true); + connect(allowBottomAction, SIGNAL(triggered(bool)), SLOT(allowBottom(bool))); + + allowedAreasActions->addAction(allowLeftAction); + allowedAreasActions->addAction(allowRightAction); + allowedAreasActions->addAction(allowTopAction); + allowedAreasActions->addAction(allowBottomAction); + + areaActions = new QActionGroup(this); + areaActions->setExclusive(true); + + leftAction = new QAction(tr("Place on Left") , this); + leftAction->setCheckable(true); + connect(leftAction, SIGNAL(triggered(bool)), SLOT(placeLeft(bool))); + + rightAction = new QAction(tr("Place on Right") , this); + rightAction->setCheckable(true); + connect(rightAction, SIGNAL(triggered(bool)), SLOT(placeRight(bool))); + + topAction = new QAction(tr("Place on Top") , this); + topAction->setCheckable(true); + connect(topAction, SIGNAL(triggered(bool)), SLOT(placeTop(bool))); + + bottomAction = new QAction(tr("Place on Bottom") , this); + bottomAction->setCheckable(true); + connect(bottomAction, SIGNAL(triggered(bool)), SLOT(placeBottom(bool))); + + areaActions->addAction(leftAction); + areaActions->addAction(rightAction); + areaActions->addAction(topAction); + areaActions->addAction(bottomAction); + + connect(movableAction, SIGNAL(triggered(bool)), areaActions, SLOT(setEnabled(bool))); + + connect(movableAction, SIGNAL(triggered(bool)), allowedAreasActions, SLOT(setEnabled(bool))); + + connect(floatableAction, SIGNAL(triggered(bool)), floatingAction, SLOT(setEnabled(bool))); + + connect(floatingAction, SIGNAL(triggered(bool)), floatableAction, SLOT(setDisabled(bool))); + connect(movableAction, SIGNAL(triggered(bool)), floatableAction, SLOT(setEnabled(bool))); + + tabMenu = new QMenu(this); + tabMenu->setTitle(tr("Tab into")); + connect(tabMenu, SIGNAL(triggered(QAction*)), this, SLOT(tabInto(QAction*))); + + splitHMenu = new QMenu(this); + splitHMenu->setTitle(tr("Split horizontally into")); + connect(splitHMenu, SIGNAL(triggered(QAction*)), this, SLOT(splitInto(QAction*))); + + splitVMenu = new QMenu(this); + splitVMenu->setTitle(tr("Split vertically into")); + connect(splitVMenu, SIGNAL(triggered(QAction*)), this, SLOT(splitInto(QAction*))); + + windowModifiedAction = new QAction(tr("Modified"), this); + windowModifiedAction->setCheckable(true); + windowModifiedAction->setChecked(false); + connect(windowModifiedAction, SIGNAL(toggled(bool)), this, SLOT(setWindowModified(bool))); + + menu = new QMenu(colorName, this); + menu->addAction(toggleViewAction()); + QAction *action = menu->addAction(tr("Raise")); + connect(action, SIGNAL(triggered()), this, SLOT(raise())); + menu->addAction(changeSizeHintsAction); + menu->addSeparator(); + menu->addAction(closableAction); + menu->addAction(movableAction); + menu->addAction(floatableAction); + menu->addAction(floatingAction); + menu->addAction(verticalTitleBarAction); + menu->addSeparator(); + menu->addActions(allowedAreasActions->actions()); + menu->addSeparator(); + menu->addActions(areaActions->actions()); + menu->addSeparator(); + menu->addMenu(splitHMenu); + menu->addMenu(splitVMenu); + menu->addMenu(tabMenu); + menu->addSeparator(); + menu->addAction(windowModifiedAction); + + connect(menu, SIGNAL(aboutToShow()), this, SLOT(updateContextMenu())); + + if(colorName == "Black") { + leftAction->setShortcut(Qt::CTRL|Qt::Key_W); + rightAction->setShortcut(Qt::CTRL|Qt::Key_E); + toggleViewAction()->setShortcut(Qt::CTRL|Qt::Key_R); + } +} + +void ColorSwatch::updateContextMenu() +{ + QMainWindow *mainWindow = qobject_cast<QMainWindow *>(parentWidget()); + const Qt::DockWidgetArea area = mainWindow->dockWidgetArea(this); + const Qt::DockWidgetAreas areas = allowedAreas(); + + closableAction->setChecked(features() & QDockWidget::DockWidgetClosable); + if (windowType() == Qt::Drawer) { + floatableAction->setEnabled(false); + floatingAction->setEnabled(false); + movableAction->setEnabled(false); + verticalTitleBarAction->setChecked(false); + } else { + floatableAction->setChecked(features() & QDockWidget::DockWidgetFloatable); + floatingAction->setChecked(isWindow()); + // done after floating, to get 'floatable' correctly initialized + movableAction->setChecked(features() & QDockWidget::DockWidgetMovable); + verticalTitleBarAction + ->setChecked(features() & QDockWidget::DockWidgetVerticalTitleBar); + } + + allowLeftAction->setChecked(isAreaAllowed(Qt::LeftDockWidgetArea)); + allowRightAction->setChecked(isAreaAllowed(Qt::RightDockWidgetArea)); + allowTopAction->setChecked(isAreaAllowed(Qt::TopDockWidgetArea)); + allowBottomAction->setChecked(isAreaAllowed(Qt::BottomDockWidgetArea)); + + if (allowedAreasActions->isEnabled()) { + allowLeftAction->setEnabled(area != Qt::LeftDockWidgetArea); + allowRightAction->setEnabled(area != Qt::RightDockWidgetArea); + allowTopAction->setEnabled(area != Qt::TopDockWidgetArea); + allowBottomAction->setEnabled(area != Qt::BottomDockWidgetArea); + } + + leftAction->blockSignals(true); + rightAction->blockSignals(true); + topAction->blockSignals(true); + bottomAction->blockSignals(true); + + leftAction->setChecked(area == Qt::LeftDockWidgetArea); + rightAction->setChecked(area == Qt::RightDockWidgetArea); + topAction->setChecked(area == Qt::TopDockWidgetArea); + bottomAction->setChecked(area == Qt::BottomDockWidgetArea); + + leftAction->blockSignals(false); + rightAction->blockSignals(false); + topAction->blockSignals(false); + bottomAction->blockSignals(false); + + if (areaActions->isEnabled()) { + leftAction->setEnabled(areas & Qt::LeftDockWidgetArea); + rightAction->setEnabled(areas & Qt::RightDockWidgetArea); + topAction->setEnabled(areas & Qt::TopDockWidgetArea); + bottomAction->setEnabled(areas & Qt::BottomDockWidgetArea); + } + + tabMenu->clear(); + splitHMenu->clear(); + splitVMenu->clear(); + QList<ColorSwatch*> dock_list = qFindChildren<ColorSwatch*>(mainWindow); + foreach (ColorSwatch *dock, dock_list) { +// if (!dock->isVisible() || dock->isFloating()) +// continue; + tabMenu->addAction(dock->objectName()); + splitHMenu->addAction(dock->objectName()); + splitVMenu->addAction(dock->objectName()); + } +} + +void ColorSwatch::splitInto(QAction *action) +{ + QMainWindow *mainWindow = qobject_cast<QMainWindow *>(parentWidget()); + QList<ColorSwatch*> dock_list = qFindChildren<ColorSwatch*>(mainWindow); + ColorSwatch *target = 0; + foreach (ColorSwatch *dock, dock_list) { + if (action->text() == dock->objectName()) { + target = dock; + break; + } + } + if (target == 0) + return; + + Qt::Orientation o = action->parent() == splitHMenu + ? Qt::Horizontal : Qt::Vertical; + mainWindow->splitDockWidget(target, this, o); +} + +void ColorSwatch::tabInto(QAction *action) +{ + QMainWindow *mainWindow = qobject_cast<QMainWindow *>(parentWidget()); + QList<ColorSwatch*> dock_list = qFindChildren<ColorSwatch*>(mainWindow); + ColorSwatch *target = 0; + foreach (ColorSwatch *dock, dock_list) { + if (action->text() == dock->objectName()) { + target = dock; + break; + } + } + if (target == 0) + return; + + mainWindow->tabifyDockWidget(target, this); +} + +void ColorSwatch::contextMenuEvent(QContextMenuEvent *event) +{ + event->accept(); + menu->exec(event->globalPos()); +} + +void ColorSwatch::resizeEvent(QResizeEvent *e) +{ + if (BlueTitleBar *btb = qobject_cast<BlueTitleBar*>(titleBarWidget())) + btb->updateMask(); + + QDockWidget::resizeEvent(e); +} + + +void ColorSwatch::allow(Qt::DockWidgetArea area, bool a) +{ + Qt::DockWidgetAreas areas = allowedAreas(); + areas = a ? areas | area : areas & ~area; + setAllowedAreas(areas); + + if (areaActions->isEnabled()) { + leftAction->setEnabled(areas & Qt::LeftDockWidgetArea); + rightAction->setEnabled(areas & Qt::RightDockWidgetArea); + topAction->setEnabled(areas & Qt::TopDockWidgetArea); + bottomAction->setEnabled(areas & Qt::BottomDockWidgetArea); + } +} + +void ColorSwatch::place(Qt::DockWidgetArea area, bool p) +{ + if (!p) return; + + QMainWindow *mainWindow = qobject_cast<QMainWindow *>(parentWidget()); + mainWindow->addDockWidget(area, this); + + if (allowedAreasActions->isEnabled()) { + allowLeftAction->setEnabled(area != Qt::LeftDockWidgetArea); + allowRightAction->setEnabled(area != Qt::RightDockWidgetArea); + allowTopAction->setEnabled(area != Qt::TopDockWidgetArea); + allowBottomAction->setEnabled(area != Qt::BottomDockWidgetArea); + } +} + +void ColorSwatch::setCustomSizeHint(const QSize &size) +{ + if (ColorDock *dock = qobject_cast<ColorDock*>(widget())) + dock->setCustomSizeHint(size); +} + +void ColorSwatch::changeClosable(bool on) +{ setFeatures(on ? features() | DockWidgetClosable : features() & ~DockWidgetClosable); } + +void ColorSwatch::changeMovable(bool on) +{ setFeatures(on ? features() | DockWidgetMovable : features() & ~DockWidgetMovable); } + +void ColorSwatch::changeFloatable(bool on) +{ setFeatures(on ? features() | DockWidgetFloatable : features() & ~DockWidgetFloatable); } + +void ColorSwatch::changeFloating(bool floating) +{ setFloating(floating); } + +void ColorSwatch::allowLeft(bool a) +{ allow(Qt::LeftDockWidgetArea, a); } + +void ColorSwatch::allowRight(bool a) +{ allow(Qt::RightDockWidgetArea, a); } + +void ColorSwatch::allowTop(bool a) +{ allow(Qt::TopDockWidgetArea, a); } + +void ColorSwatch::allowBottom(bool a) +{ allow(Qt::BottomDockWidgetArea, a); } + +void ColorSwatch::placeLeft(bool p) +{ place(Qt::LeftDockWidgetArea, p); } + +void ColorSwatch::placeRight(bool p) +{ place(Qt::RightDockWidgetArea, p); } + +void ColorSwatch::placeTop(bool p) +{ place(Qt::TopDockWidgetArea, p); } + +void ColorSwatch::placeBottom(bool p) +{ place(Qt::BottomDockWidgetArea, p); } + +void ColorSwatch::changeVerticalTitleBar(bool on) +{ + setFeatures(on ? features() | DockWidgetVerticalTitleBar + : features() & ~DockWidgetVerticalTitleBar); +} + +QSize BlueTitleBar::minimumSizeHint() const +{ + QDockWidget *dw = qobject_cast<QDockWidget*>(parentWidget()); + Q_ASSERT(dw != 0); + QSize result(leftPm.width() + rightPm.width(), centerPm.height()); + if (dw->features() & QDockWidget::DockWidgetVerticalTitleBar) + result.transpose(); + return result; +} + +BlueTitleBar::BlueTitleBar(QWidget *parent) + : QWidget(parent) +{ + leftPm = QPixmap(":/res/titlebarLeft.png"); + centerPm = QPixmap(":/res/titlebarCenter.png"); + rightPm = QPixmap(":/res/titlebarRight.png"); +} + +void BlueTitleBar::paintEvent(QPaintEvent*) +{ + QPainter painter(this); + QRect rect = this->rect(); + + QDockWidget *dw = qobject_cast<QDockWidget*>(parentWidget()); + Q_ASSERT(dw != 0); + + if (dw->features() & QDockWidget::DockWidgetVerticalTitleBar) { + QSize s = rect.size(); + s.transpose(); + rect.setSize(s); + + painter.translate(rect.left(), rect.top() + rect.width()); + painter.rotate(-90); + painter.translate(-rect.left(), -rect.top()); + } + + painter.drawPixmap(rect.topLeft(), leftPm); + painter.drawPixmap(rect.topRight() - QPoint(rightPm.width() - 1, 0), rightPm); + QBrush brush(centerPm); + painter.fillRect(rect.left() + leftPm.width(), rect.top(), + rect.width() - leftPm.width() - rightPm.width(), + centerPm.height(), centerPm); +} + +void BlueTitleBar::mousePressEvent(QMouseEvent *event) +{ + QPoint pos = event->pos(); + + QRect rect = this->rect(); + + QDockWidget *dw = qobject_cast<QDockWidget*>(parentWidget()); + Q_ASSERT(dw != 0); + + if (dw->features() & QDockWidget::DockWidgetVerticalTitleBar) { + QPoint p = pos; + pos.setX(rect.left() + rect.bottom() - p.y()); + pos.setY(rect.top() + p.x() - rect.left()); + + QSize s = rect.size(); + s.transpose(); + rect.setSize(s); + } + + const int buttonRight = 7; + const int buttonWidth = 20; + int right = rect.right() - pos.x(); + int button = (right - buttonRight)/buttonWidth; + switch (button) { + case 0: + event->accept(); + dw->close(); + break; + case 1: + event->accept(); + dw->setFloating(!dw->isFloating()); + break; + case 2: { + event->accept(); + QDockWidget::DockWidgetFeatures features = dw->features(); + if (features & QDockWidget::DockWidgetVerticalTitleBar) + features &= ~QDockWidget::DockWidgetVerticalTitleBar; + else + features |= QDockWidget::DockWidgetVerticalTitleBar; + dw->setFeatures(features); + break; + } + default: + event->ignore(); + break; + } +} + +void BlueTitleBar::updateMask() +{ + QDockWidget *dw = qobject_cast<QDockWidget*>(parent()); + Q_ASSERT(dw != 0); + + QRect rect = dw->rect(); + QPixmap bitmap(dw->size()); + + { + QPainter painter(&bitmap); + + ///initialize to transparent + painter.fillRect(rect, Qt::color0); + + QRect contents = rect; + contents.setTopLeft(geometry().bottomLeft()); + contents.setRight(geometry().right()); + contents.setBottom(contents.bottom()-y()); + painter.fillRect(contents, Qt::color1); + + + + //let's pait the titlebar + + QRect titleRect = this->geometry(); + + if (dw->features() & QDockWidget::DockWidgetVerticalTitleBar) { + QSize s = rect.size(); + s.transpose(); + rect.setSize(s); + + QSize s2 = size(); + s2.transpose(); + titleRect.setSize(s2); + + painter.translate(rect.left(), rect.top() + rect.width()); + painter.rotate(-90); + painter.translate(-rect.left(), -rect.top()); + } + + contents.setTopLeft(titleRect.bottomLeft()); + contents.setRight(titleRect.right()); + contents.setBottom(rect.bottom()-y()); + + QRect rect = titleRect; + + + painter.drawPixmap(rect.topLeft(), leftPm.mask()); + painter.fillRect(rect.left() + leftPm.width(), rect.top(), + rect.width() - leftPm.width() - rightPm.width(), + centerPm.height(), Qt::color1); + painter.drawPixmap(rect.topRight() - QPoint(rightPm.width() - 1, 0), rightPm.mask()); + + painter.fillRect(contents, Qt::color1); + } + + dw->setMask(bitmap); +} + +#include "colorswatch.moc" diff --git a/demos/mainwindow/colorswatch.h b/demos/mainwindow/colorswatch.h new file mode 100644 index 0000000..57c5ac6 --- /dev/null +++ b/demos/mainwindow/colorswatch.h @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef COLORSWATCH_H +#define COLORSWATCH_H + +#include <QDockWidget> + +QT_FORWARD_DECLARE_CLASS(QAction) +QT_FORWARD_DECLARE_CLASS(QActionGroup) +QT_FORWARD_DECLARE_CLASS(QMenu) + +class ColorSwatch : public QDockWidget +{ + Q_OBJECT + + QAction *closableAction; + QAction *movableAction; + QAction *floatableAction; + QAction *floatingAction; + QAction *verticalTitleBarAction; + + QActionGroup *allowedAreasActions; + QAction *allowLeftAction; + QAction *allowRightAction; + QAction *allowTopAction; + QAction *allowBottomAction; + + QActionGroup *areaActions; + QAction *leftAction; + QAction *rightAction; + QAction *topAction; + QAction *bottomAction; + + QAction *changeSizeHintsAction; + + QMenu *tabMenu; + QMenu *splitHMenu; + QMenu *splitVMenu; + + QAction *windowModifiedAction; + +public: + ColorSwatch(const QString &colorName, QWidget *parent = 0, Qt::WindowFlags flags = 0); + + QMenu *menu; + void setCustomSizeHint(const QSize &size); + +protected: + virtual void contextMenuEvent(QContextMenuEvent *event); + virtual void resizeEvent(QResizeEvent *e); + +private: + void allow(Qt::DockWidgetArea area, bool allow); + void place(Qt::DockWidgetArea area, bool place); + +private slots: + void changeClosable(bool on); + void changeMovable(bool on); + void changeFloatable(bool on); + void changeFloating(bool on); + void changeVerticalTitleBar(bool on); + void updateContextMenu(); + + void allowLeft(bool a); + void allowRight(bool a); + void allowTop(bool a); + void allowBottom(bool a); + + void placeLeft(bool p); + void placeRight(bool p); + void placeTop(bool p); + void placeBottom(bool p); + + void splitInto(QAction *action); + void tabInto(QAction *action); +}; + +class BlueTitleBar : public QWidget +{ + Q_OBJECT +public: + BlueTitleBar(QWidget *parent = 0); + + QSize sizeHint() const { return minimumSizeHint(); } + QSize minimumSizeHint() const; +protected: + void paintEvent(QPaintEvent *event); + void mousePressEvent(QMouseEvent *event); +public slots: + void updateMask(); + +private: + QPixmap leftPm, centerPm, rightPm; +}; + + +#endif diff --git a/demos/mainwindow/main.cpp b/demos/mainwindow/main.cpp new file mode 100644 index 0000000..46268b5 --- /dev/null +++ b/demos/mainwindow/main.cpp @@ -0,0 +1,164 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mainwindow.h" + +#include <QApplication> +#include <QPainterPath> +#include <QPainter> +#include <QMap> +#include <qdebug.h> + +void render_qt_text(QPainter *painter, int w, int h, const QColor &color) { + QPainterPath path; + path.moveTo(-0.083695, 0.283849); + path.cubicTo(-0.049581, 0.349613, -0.012720, 0.397969, 0.026886, 0.428917); + path.cubicTo(0.066493, 0.459865, 0.111593, 0.477595, 0.162186, 0.482108); + path.lineTo(0.162186, 0.500000); + path.cubicTo(0.115929, 0.498066, 0.066565, 0.487669, 0.014094, 0.468810); + path.cubicTo(-0.038378, 0.449952, -0.088103, 0.423839, -0.135082, 0.390474); + path.cubicTo(-0.182061, 0.357108, -0.222608, 0.321567, -0.256722, 0.283849); + path.cubicTo(-0.304712, 0.262250, -0.342874, 0.239362, -0.371206, 0.215184); + path.cubicTo(-0.411969, 0.179078, -0.443625, 0.134671, -0.466175, 0.081963); + path.cubicTo(-0.488725, 0.029255, -0.500000, -0.033043, -0.500000, -0.104932); + path.cubicTo(-0.500000, -0.218407, -0.467042, -0.312621, -0.401127, -0.387573); + path.cubicTo(-0.335212, -0.462524, -0.255421, -0.500000, -0.161752, -0.500000); + path.cubicTo(-0.072998, -0.500000, 0.003903, -0.462444, 0.068951, -0.387331); + path.cubicTo(0.133998, -0.312218, 0.166522, -0.217440, 0.166522, -0.102998); + path.cubicTo(0.166522, -0.010155, 0.143394, 0.071325, 0.097138, 0.141441); + path.cubicTo(0.050882, 0.211557, -0.009396, 0.259026, -0.083695, 0.283849); + path.moveTo(-0.167823, -0.456963); + path.cubicTo(-0.228823, -0.456963, -0.277826, -0.432624, -0.314831, -0.383946); + path.cubicTo(-0.361665, -0.323340, -0.385082, -0.230335, -0.385082, -0.104932); + path.cubicTo(-0.385082, 0.017569, -0.361376, 0.112025, -0.313964, 0.178433); + path.cubicTo(-0.277248, 0.229368, -0.228534, 0.254836, -0.167823, 0.254836); + path.cubicTo(-0.105088, 0.254836, -0.054496, 0.229368, -0.016045, 0.178433); + path.cubicTo(0.029055, 0.117827, 0.051605, 0.028691, 0.051605, -0.088975); + path.cubicTo(0.051605, -0.179562, 0.039318, -0.255803, 0.014744, -0.317698); + path.cubicTo(-0.004337, -0.365409, -0.029705, -0.400548, -0.061362, -0.423114); + path.cubicTo(-0.093018, -0.445680, -0.128505, -0.456963, -0.167823, -0.456963); + path.moveTo(0.379011, -0.404739); + path.lineTo(0.379011, -0.236460); + path.lineTo(0.486123, -0.236460); + path.lineTo(0.486123, -0.197292); + path.lineTo(0.379011, -0.197292); + path.lineTo(0.379011, 0.134913); + path.cubicTo(0.379011, 0.168117, 0.383276, 0.190442, 0.391804, 0.201886); + path.cubicTo(0.400332, 0.213330, 0.411246, 0.219052, 0.424545, 0.219052); + path.cubicTo(0.435531, 0.219052, 0.446227, 0.215264, 0.456635, 0.207689); + path.cubicTo(0.467042, 0.200113, 0.474993, 0.188910, 0.480486, 0.174081); + path.lineTo(0.500000, 0.174081); + path.cubicTo(0.488436, 0.210509, 0.471957, 0.237911, 0.450564, 0.256286); + path.cubicTo(0.429170, 0.274662, 0.407054, 0.283849, 0.384215, 0.283849); + path.cubicTo(0.368893, 0.283849, 0.353859, 0.279094, 0.339115, 0.269584); + path.cubicTo(0.324371, 0.260074, 0.313530, 0.246534, 0.306592, 0.228965); + path.cubicTo(0.299653, 0.211396, 0.296184, 0.184075, 0.296184, 0.147002); + path.lineTo(0.296184, -0.197292); + path.lineTo(0.223330, -0.197292); + path.lineTo(0.223330, -0.215667); + path.cubicTo(0.241833, -0.224049, 0.260697, -0.237992, 0.279922, -0.257495); + path.cubicTo(0.299147, -0.276999, 0.316276, -0.300129, 0.331310, -0.326886); + path.cubicTo(0.338826, -0.341070, 0.349523, -0.367021, 0.363400, -0.404739); + path.lineTo(0.379011, -0.404739); + path.moveTo(-0.535993, 0.275629); + + painter->translate(w / 2, h / 2); + double scale = qMin(w, h) * 8 / 10.0; + painter->scale(scale, scale); + + painter->setRenderHint(QPainter::Antialiasing); + + painter->save(); + painter->translate(.1, .1); + painter->fillPath(path, QColor(0, 0, 0, 63)); + painter->restore(); + + painter->setBrush(color); + painter->setPen(QPen(Qt::black, 0.02, Qt::SolidLine, Qt::FlatCap, Qt::RoundJoin)); + painter->drawPath(path); +} + +void usage() +{ + qWarning() << "Usage: mainwindow [-SizeHint<color> <width>x<height>] ..."; + exit(1); +} + +QMap<QString, QSize> parseCustomSizeHints(int argc, char **argv) +{ + QMap<QString, QSize> result; + + for (int i = 1; i < argc; ++i) { + QString arg = QString::fromLocal8Bit(argv[i]); + + if (arg.startsWith(QLatin1String("-SizeHint"))) { + QString name = arg.mid(9); + if (name.isEmpty()) + usage(); + if (++i == argc) + usage(); + QString sizeStr = QString::fromLocal8Bit(argv[i]); + int idx = sizeStr.indexOf(QLatin1Char('x')); + if (idx == -1) + usage(); + bool ok; + int w = sizeStr.left(idx).toInt(&ok); + if (!ok) + usage(); + int h = sizeStr.mid(idx + 1).toInt(&ok); + if (!ok) + usage(); + result[name] = QSize(w, h); + } + } + + return result; +} + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + QMap<QString, QSize> customSizeHints = parseCustomSizeHints(argc, argv); + MainWindow mainWin(customSizeHints); + mainWin.resize(800, 600); + mainWin.show(); + return app.exec(); +} diff --git a/demos/mainwindow/mainwindow.cpp b/demos/mainwindow/mainwindow.cpp new file mode 100644 index 0000000..7edaf52 --- /dev/null +++ b/demos/mainwindow/mainwindow.cpp @@ -0,0 +1,510 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mainwindow.h" +#include "colorswatch.h" +#include "toolbar.h" + +#include <QAction> +#include <QLayout> +#include <QMenu> +#include <QMenuBar> +#include <QStatusBar> +#include <QTextEdit> +#include <QFile> +#include <QDataStream> +#include <QFileDialog> +#include <QMessageBox> +#include <QSignalMapper> +#include <QApplication> +#include <QPainter> +#include <QMouseEvent> +#include <QLineEdit> +#include <QComboBox> +#include <QLabel> +#include <QPushButton> +#include <qdebug.h> + +static const char * const message = + "<p><b>Qt Main Window Demo</b></p>" + + "<p>This is a demonstration of the QMainWindow, QToolBar and " + "QDockWidget classes.</p>" + + "<p>The tool bar and dock widgets can be dragged around and rearranged " + "using the mouse or via the menu.</p>" + + "<p>Each dock widget contains a colored frame and a context " + "(right-click) menu.</p>" + +#ifdef Q_WS_MAC + "<p>On Mac OS X, the \"Black\" dock widget has been created as a " + "<em>Drawer</em>, which is a special kind of QDockWidget.</p>" +#endif + ; + +MainWindow::MainWindow(const QMap<QString, QSize> &customSizeHints, + QWidget *parent, Qt::WindowFlags flags) + : QMainWindow(parent, flags) +{ + setObjectName("MainWindow"); + setWindowTitle("Qt Main Window Demo"); + + center = new QTextEdit(this); + center->setReadOnly(true); + center->setMinimumSize(400, 205); + setCentralWidget(center); + + setupToolBar(); + setupMenuBar(); + setupDockWidgets(customSizeHints); + + statusBar()->showMessage(tr("Status Bar")); +} + +void MainWindow::actionTriggered(QAction *action) +{ + qDebug("action '%s' triggered", action->text().toLocal8Bit().data()); +} + +void MainWindow::setupToolBar() +{ + for (int i = 0; i < 3; ++i) { + ToolBar *tb = new ToolBar(QString::fromLatin1("Tool Bar %1").arg(i + 1), this); + toolBars.append(tb); + addToolBar(tb); + } +} + +void MainWindow::setupMenuBar() +{ + QMenu *menu = menuBar()->addMenu(tr("&File")); + + QAction *action = menu->addAction(tr("Save layout...")); + connect(action, SIGNAL(triggered()), this, SLOT(saveLayout())); + + action = menu->addAction(tr("Load layout...")); + connect(action, SIGNAL(triggered()), this, SLOT(loadLayout())); + + action = menu->addAction(tr("Switch layout direction")); + connect(action, SIGNAL(triggered()), this, SLOT(switchLayoutDirection())); + + menu->addSeparator(); + + menu->addAction(tr("&Quit"), this, SLOT(close())); + + mainWindowMenu = menuBar()->addMenu(tr("Main window")); + + action = mainWindowMenu->addAction(tr("Animated docks")); + action->setCheckable(true); + action->setChecked(dockOptions() & AnimatedDocks); + connect(action, SIGNAL(toggled(bool)), this, SLOT(setDockOptions())); + + action = mainWindowMenu->addAction(tr("Allow nested docks")); + action->setCheckable(true); + action->setChecked(dockOptions() & AllowNestedDocks); + connect(action, SIGNAL(toggled(bool)), this, SLOT(setDockOptions())); + + action = mainWindowMenu->addAction(tr("Allow tabbed docks")); + action->setCheckable(true); + action->setChecked(dockOptions() & AllowTabbedDocks); + connect(action, SIGNAL(toggled(bool)), this, SLOT(setDockOptions())); + + action = mainWindowMenu->addAction(tr("Force tabbed docks")); + action->setCheckable(true); + action->setChecked(dockOptions() & ForceTabbedDocks); + connect(action, SIGNAL(toggled(bool)), this, SLOT(setDockOptions())); + + action = mainWindowMenu->addAction(tr("Vertical tabs")); + action->setCheckable(true); + action->setChecked(dockOptions() & VerticalTabs); + connect(action, SIGNAL(toggled(bool)), this, SLOT(setDockOptions())); + + QMenu *toolBarMenu = menuBar()->addMenu(tr("Tool bars")); + for (int i = 0; i < toolBars.count(); ++i) + toolBarMenu->addMenu(toolBars.at(i)->menu); + + dockWidgetMenu = menuBar()->addMenu(tr("&Dock Widgets")); +} + +void MainWindow::setDockOptions() +{ + DockOptions opts; + QList<QAction*> actions = mainWindowMenu->actions(); + + if (actions.at(0)->isChecked()) + opts |= AnimatedDocks; + if (actions.at(1)->isChecked()) + opts |= AllowNestedDocks; + if (actions.at(2)->isChecked()) + opts |= AllowTabbedDocks; + if (actions.at(3)->isChecked()) + opts |= ForceTabbedDocks; + if (actions.at(4)->isChecked()) + opts |= VerticalTabs; + + QMainWindow::setDockOptions(opts); +} + +void MainWindow::saveLayout() +{ + QString fileName + = QFileDialog::getSaveFileName(this, tr("Save layout")); + if (fileName.isEmpty()) + return; + QFile file(fileName); + if (!file.open(QFile::WriteOnly)) { + QString msg = tr("Failed to open %1\n%2") + .arg(fileName) + .arg(file.errorString()); + QMessageBox::warning(this, tr("Error"), msg); + return; + } + + QByteArray geo_data = saveGeometry(); + QByteArray layout_data = saveState(); + + bool ok = file.putChar((uchar)geo_data.size()); + if (ok) + ok = file.write(geo_data) == geo_data.size(); + if (ok) + ok = file.write(layout_data) == layout_data.size(); + + if (!ok) { + QString msg = tr("Error writing to %1\n%2") + .arg(fileName) + .arg(file.errorString()); + QMessageBox::warning(this, tr("Error"), msg); + return; + } +} + +void MainWindow::loadLayout() +{ + QString fileName + = QFileDialog::getOpenFileName(this, tr("Load layout")); + if (fileName.isEmpty()) + return; + QFile file(fileName); + if (!file.open(QFile::ReadOnly)) { + QString msg = tr("Failed to open %1\n%2") + .arg(fileName) + .arg(file.errorString()); + QMessageBox::warning(this, tr("Error"), msg); + return; + } + + uchar geo_size; + QByteArray geo_data; + QByteArray layout_data; + + bool ok = file.getChar((char*)&geo_size); + if (ok) { + geo_data = file.read(geo_size); + ok = geo_data.size() == geo_size; + } + if (ok) { + layout_data = file.readAll(); + ok = layout_data.size() > 0; + } + + if (ok) + ok = restoreGeometry(geo_data); + if (ok) + ok = restoreState(layout_data); + + if (!ok) { + QString msg = tr("Error reading %1") + .arg(fileName); + QMessageBox::warning(this, tr("Error"), msg); + return; + } +} + +QAction *addAction(QMenu *menu, const QString &text, QActionGroup *group, QSignalMapper *mapper, + int id) +{ + bool first = group->actions().isEmpty(); + QAction *result = menu->addAction(text); + result->setCheckable(true); + result->setChecked(first); + group->addAction(result); + QObject::connect(result, SIGNAL(triggered()), mapper, SLOT(map())); + mapper->setMapping(result, id); + return result; +} + +void MainWindow::setupDockWidgets(const QMap<QString, QSize> &customSizeHints) +{ + mapper = new QSignalMapper(this); + connect(mapper, SIGNAL(mapped(int)), this, SLOT(setCorner(int))); + + QMenu *corner_menu = dockWidgetMenu->addMenu(tr("Top left corner")); + QActionGroup *group = new QActionGroup(this); + group->setExclusive(true); + ::addAction(corner_menu, tr("Top dock area"), group, mapper, 0); + ::addAction(corner_menu, tr("Left dock area"), group, mapper, 1); + + corner_menu = dockWidgetMenu->addMenu(tr("Top right corner")); + group = new QActionGroup(this); + group->setExclusive(true); + ::addAction(corner_menu, tr("Top dock area"), group, mapper, 2); + ::addAction(corner_menu, tr("Right dock area"), group, mapper, 3); + + corner_menu = dockWidgetMenu->addMenu(tr("Bottom left corner")); + group = new QActionGroup(this); + group->setExclusive(true); + ::addAction(corner_menu, tr("Bottom dock area"), group, mapper, 4); + ::addAction(corner_menu, tr("Left dock area"), group, mapper, 5); + + corner_menu = dockWidgetMenu->addMenu(tr("Bottom right corner")); + group = new QActionGroup(this); + group->setExclusive(true); + ::addAction(corner_menu, tr("Bottom dock area"), group, mapper, 6); + ::addAction(corner_menu, tr("Right dock area"), group, mapper, 7); + + dockWidgetMenu->addSeparator(); + + static const struct Set { + const char * name; + uint flags; + Qt::DockWidgetArea area; + } sets [] = { +#ifndef Q_WS_MAC + { "Black", 0, Qt::LeftDockWidgetArea }, +#else + { "Black", Qt::Drawer, Qt::LeftDockWidgetArea }, +#endif + { "White", 0, Qt::RightDockWidgetArea }, + { "Red", 0, Qt::TopDockWidgetArea }, + { "Green", 0, Qt::TopDockWidgetArea }, + { "Blue", 0, Qt::BottomDockWidgetArea }, + { "Yellow", 0, Qt::BottomDockWidgetArea } + }; + const int setCount = sizeof(sets) / sizeof(Set); + + for (int i = 0; i < setCount; ++i) { + ColorSwatch *swatch = new ColorSwatch(tr(sets[i].name), this, Qt::WindowFlags(sets[i].flags)); + if (i%2) + swatch->setWindowIcon(QIcon(QPixmap(":/res/qt.png"))); + if (qstrcmp(sets[i].name, "Blue") == 0) { + BlueTitleBar *titlebar = new BlueTitleBar(swatch); + swatch->setTitleBarWidget(titlebar); + connect(swatch, SIGNAL(topLevelChanged(bool)), titlebar, SLOT(updateMask())); + connect(swatch, SIGNAL(featuresChanged(QDockWidget::DockWidgetFeatures)), titlebar, SLOT(updateMask())); + +#ifdef Q_WS_QWS + QPalette pal = palette(); + pal.setBrush(backgroundRole(), QColor(0,0,0,0)); + swatch->setPalette(pal); +#endif + } + + QString name = QString::fromLatin1(sets[i].name); + if (customSizeHints.contains(name)) + swatch->setCustomSizeHint(customSizeHints.value(name)); + + addDockWidget(sets[i].area, swatch); + dockWidgetMenu->addMenu(swatch->menu); + } + + createDockWidgetAction = new QAction(tr("Add dock widget..."), this); + connect(createDockWidgetAction, SIGNAL(triggered()), this, SLOT(createDockWidget())); + destroyDockWidgetMenu = new QMenu(tr("Destroy dock widget"), this); + destroyDockWidgetMenu->setEnabled(false); + connect(destroyDockWidgetMenu, SIGNAL(triggered(QAction*)), this, SLOT(destroyDockWidget(QAction*))); + + dockWidgetMenu->addSeparator(); + dockWidgetMenu->addAction(createDockWidgetAction); + dockWidgetMenu->addMenu(destroyDockWidgetMenu); +} + +void MainWindow::setCorner(int id) +{ + switch (id) { + case 0: + QMainWindow::setCorner(Qt::TopLeftCorner, Qt::TopDockWidgetArea); + break; + case 1: + QMainWindow::setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea); + break; + case 2: + QMainWindow::setCorner(Qt::TopRightCorner, Qt::TopDockWidgetArea); + break; + case 3: + QMainWindow::setCorner(Qt::TopRightCorner, Qt::RightDockWidgetArea); + break; + case 4: + QMainWindow::setCorner(Qt::BottomLeftCorner, Qt::BottomDockWidgetArea); + break; + case 5: + QMainWindow::setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea); + break; + case 6: + QMainWindow::setCorner(Qt::BottomRightCorner, Qt::BottomDockWidgetArea); + break; + case 7: + QMainWindow::setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea); + break; + } +} + +void MainWindow::showEvent(QShowEvent *event) +{ + QMainWindow::showEvent(event); +} + +void MainWindow::switchLayoutDirection() +{ + if (layoutDirection() == Qt::LeftToRight) + qApp->setLayoutDirection(Qt::RightToLeft); + else + qApp->setLayoutDirection(Qt::LeftToRight); +} + +class CreateDockWidgetDialog : public QDialog +{ +public: + CreateDockWidgetDialog(QWidget *parent = 0); + + QString objectName() const; + Qt::DockWidgetArea location() const; + +private: + QLineEdit *m_objectName; + QComboBox *m_location; +}; + +CreateDockWidgetDialog::CreateDockWidgetDialog(QWidget *parent) + : QDialog(parent) +{ + QGridLayout *layout = new QGridLayout(this); + + layout->addWidget(new QLabel(tr("Object name:")), 0, 0); + m_objectName = new QLineEdit; + layout->addWidget(m_objectName, 0, 1); + + layout->addWidget(new QLabel(tr("Location:")), 1, 0); + m_location = new QComboBox; + m_location->setEditable(false); + m_location->addItem(tr("Top")); + m_location->addItem(tr("Left")); + m_location->addItem(tr("Right")); + m_location->addItem(tr("Bottom")); + m_location->addItem(tr("Restore")); + layout->addWidget(m_location, 1, 1); + + QHBoxLayout *buttonLayout = new QHBoxLayout; + layout->addLayout(buttonLayout, 2, 0, 1, 2); + buttonLayout->addStretch(); + + QPushButton *cancelButton = new QPushButton(tr("Cancel")); + connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject())); + buttonLayout->addWidget(cancelButton); + QPushButton *okButton = new QPushButton(tr("Ok")); + connect(okButton, SIGNAL(clicked()), this, SLOT(accept())); + buttonLayout->addWidget(okButton); + + okButton->setDefault(true); +} + +QString CreateDockWidgetDialog::objectName() const +{ + return m_objectName->text(); +} + +Qt::DockWidgetArea CreateDockWidgetDialog::location() const +{ + switch (m_location->currentIndex()) { + case 0: return Qt::TopDockWidgetArea; + case 1: return Qt::LeftDockWidgetArea; + case 2: return Qt::RightDockWidgetArea; + case 3: return Qt::BottomDockWidgetArea; + default: + break; + } + return Qt::NoDockWidgetArea; +} + +void MainWindow::createDockWidget() +{ + CreateDockWidgetDialog dialog(this); + int ret = dialog.exec(); + if (ret == QDialog::Rejected) + return; + + QDockWidget *dw = new QDockWidget; + dw->setObjectName(dialog.objectName()); + dw->setWindowTitle(dialog.objectName()); + dw->setWidget(new QTextEdit); + + Qt::DockWidgetArea area = dialog.location(); + switch (area) { + case Qt::LeftDockWidgetArea: + case Qt::RightDockWidgetArea: + case Qt::TopDockWidgetArea: + case Qt::BottomDockWidgetArea: + addDockWidget(area, dw); + break; + default: + if (!restoreDockWidget(dw)) { + QMessageBox::warning(this, QString(), tr("Failed to restore dock widget")); + delete dw; + return; + } + break; + } + + extraDockWidgets.append(dw); + destroyDockWidgetMenu->setEnabled(true); + destroyDockWidgetMenu->addAction(new QAction(dialog.objectName(), this)); +} + +void MainWindow::destroyDockWidget(QAction *action) +{ + int index = destroyDockWidgetMenu->actions().indexOf(action); + delete extraDockWidgets.takeAt(index); + destroyDockWidgetMenu->removeAction(action); + action->deleteLater(); + + if (destroyDockWidgetMenu->isEmpty()) + destroyDockWidgetMenu->setEnabled(false); +} diff --git a/demos/mainwindow/mainwindow.h b/demos/mainwindow/mainwindow.h new file mode 100644 index 0000000..9c7f620 --- /dev/null +++ b/demos/mainwindow/mainwindow.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include <QMainWindow> +#include <QTextEdit> + +class ToolBar; +QT_FORWARD_DECLARE_CLASS(QMenu) +QT_FORWARD_DECLARE_CLASS(QSignalMapper) + +class MainWindow : public QMainWindow +{ + Q_OBJECT + + QTextEdit *center; + QList<ToolBar*> toolBars; + QMenu *dockWidgetMenu; + QMenu *mainWindowMenu; + QSignalMapper *mapper; + QList<QDockWidget*> extraDockWidgets; + QAction *createDockWidgetAction; + QMenu *destroyDockWidgetMenu; + +public: + MainWindow(const QMap<QString, QSize> &customSizeHints, + QWidget *parent = 0, Qt::WindowFlags flags = 0); + +protected: + void showEvent(QShowEvent *event); + +public slots: + void actionTriggered(QAction *action); + void saveLayout(); + void loadLayout(); + void setCorner(int id); + void switchLayoutDirection(); + void setDockOptions(); + + void createDockWidget(); + void destroyDockWidget(QAction *action); + +private: + void setupToolBar(); + void setupMenuBar(); + void setupDockWidgets(const QMap<QString, QSize> &customSizeHints); +}; + + +#endif diff --git a/demos/mainwindow/mainwindow.pro b/demos/mainwindow/mainwindow.pro new file mode 100644 index 0000000..6e7d784 --- /dev/null +++ b/demos/mainwindow/mainwindow.pro @@ -0,0 +1,18 @@ +TEMPLATE = app +HEADERS += colorswatch.h mainwindow.h toolbar.h +SOURCES += colorswatch.cpp mainwindow.cpp toolbar.cpp main.cpp +build_all:!build_pass { + CONFIG -= build_all + CONFIG += release +} + +RESOURCES += mainwindow.qrc + +# install +target.path = $$[QT_INSTALL_DEMOS]/mainwindow +sources.files = $$SOURCES $$HEADERS $$FORMS $$RESOURCES *.png *.jpg *.pro +sources.path = $$[QT_INSTALL_DEMOS]/mainwindow +INSTALLS += target sources + +include($$QT_SOURCE_TREE/demos/demobase.pri) + diff --git a/demos/mainwindow/mainwindow.qrc b/demos/mainwindow/mainwindow.qrc new file mode 100644 index 0000000..47ff22a --- /dev/null +++ b/demos/mainwindow/mainwindow.qrc @@ -0,0 +1,8 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource prefix="/res"> + <file>qt.png</file> + <file>titlebarLeft.png</file> + <file>titlebarCenter.png</file> + <file>titlebarRight.png</file> +</qresource> +</RCC> diff --git a/demos/mainwindow/qt.png b/demos/mainwindow/qt.png Binary files differnew file mode 100644 index 0000000..48fa9fc --- /dev/null +++ b/demos/mainwindow/qt.png diff --git a/demos/mainwindow/titlebarCenter.png b/demos/mainwindow/titlebarCenter.png Binary files differnew file mode 100644 index 0000000..5cc1413 --- /dev/null +++ b/demos/mainwindow/titlebarCenter.png diff --git a/demos/mainwindow/titlebarLeft.png b/demos/mainwindow/titlebarLeft.png Binary files differnew file mode 100644 index 0000000..3151662 --- /dev/null +++ b/demos/mainwindow/titlebarLeft.png diff --git a/demos/mainwindow/titlebarRight.png b/demos/mainwindow/titlebarRight.png Binary files differnew file mode 100644 index 0000000..a450526 --- /dev/null +++ b/demos/mainwindow/titlebarRight.png diff --git a/demos/mainwindow/toolbar.cpp b/demos/mainwindow/toolbar.cpp new file mode 100644 index 0000000..9de1348 --- /dev/null +++ b/demos/mainwindow/toolbar.cpp @@ -0,0 +1,383 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "toolbar.h" + +#include <QMainWindow> +#include <QMenu> +#include <QPainter> +#include <QPainterPath> +#include <QSpinBox> +#include <QLabel> +#include <QToolTip> + +#include <stdlib.h> + +static QPixmap genIcon(const QSize &iconSize, const QString &, const QColor &color) +{ + int w = iconSize.width(); + int h = iconSize.height(); + + QImage image(w, h, QImage::Format_ARGB32_Premultiplied); + image.fill(0); + + QPainter p(&image); + + extern void render_qt_text(QPainter *, int, int, const QColor &); + render_qt_text(&p, w, h, color); + + return QPixmap::fromImage(image, Qt::DiffuseDither | Qt::DiffuseAlphaDither); +} + +static QPixmap genIcon(const QSize &iconSize, int number, const QColor &color) +{ return genIcon(iconSize, QString::number(number), color); } + +ToolBar::ToolBar(const QString &title, QWidget *parent) + : QToolBar(parent), spinbox(0), spinboxAction(0) +{ + tip = 0; + setWindowTitle(title); + setObjectName(title); + + setIconSize(QSize(32, 32)); + + QColor bg(palette().background().color()); + menu = new QMenu("One", this); + menu->setIcon(genIcon(iconSize(), 1, Qt::black)); + menu->addAction(genIcon(iconSize(), "A", Qt::blue), "A"); + menu->addAction(genIcon(iconSize(), "B", Qt::blue), "B"); + menu->addAction(genIcon(iconSize(), "C", Qt::blue), "C"); + addAction(menu->menuAction()); + + QAction *two = addAction(genIcon(iconSize(), 2, Qt::white), "Two"); + QFont boldFont; + boldFont.setBold(true); + two->setFont(boldFont); + + addAction(genIcon(iconSize(), 3, Qt::red), "Three"); + addAction(genIcon(iconSize(), 4, Qt::green), "Four"); + addAction(genIcon(iconSize(), 5, Qt::blue), "Five"); + addAction(genIcon(iconSize(), 6, Qt::yellow), "Six"); + orderAction = new QAction(this); + orderAction->setText(tr("Order Items in Tool Bar")); + connect(orderAction, SIGNAL(triggered()), SLOT(order())); + + randomizeAction = new QAction(this); + randomizeAction->setText(tr("Randomize Items in Tool Bar")); + connect(randomizeAction, SIGNAL(triggered()), SLOT(randomize())); + + addSpinBoxAction = new QAction(this); + addSpinBoxAction->setText(tr("Add Spin Box")); + connect(addSpinBoxAction, SIGNAL(triggered()), SLOT(addSpinBox())); + + removeSpinBoxAction = new QAction(this); + removeSpinBoxAction->setText(tr("Remove Spin Box")); + removeSpinBoxAction->setEnabled(false); + connect(removeSpinBoxAction, SIGNAL(triggered()), SLOT(removeSpinBox())); + + movableAction = new QAction(tr("Movable"), this); + movableAction->setCheckable(true); + connect(movableAction, SIGNAL(triggered(bool)), SLOT(changeMovable(bool))); + + allowedAreasActions = new QActionGroup(this); + allowedAreasActions->setExclusive(false); + + allowLeftAction = new QAction(tr("Allow on Left"), this); + allowLeftAction->setCheckable(true); + connect(allowLeftAction, SIGNAL(triggered(bool)), SLOT(allowLeft(bool))); + + allowRightAction = new QAction(tr("Allow on Right"), this); + allowRightAction->setCheckable(true); + connect(allowRightAction, SIGNAL(triggered(bool)), SLOT(allowRight(bool))); + + allowTopAction = new QAction(tr("Allow on Top"), this); + allowTopAction->setCheckable(true); + connect(allowTopAction, SIGNAL(triggered(bool)), SLOT(allowTop(bool))); + + allowBottomAction = new QAction(tr("Allow on Bottom"), this); + allowBottomAction->setCheckable(true); + connect(allowBottomAction, SIGNAL(triggered(bool)), SLOT(allowBottom(bool))); + + allowedAreasActions->addAction(allowLeftAction); + allowedAreasActions->addAction(allowRightAction); + allowedAreasActions->addAction(allowTopAction); + allowedAreasActions->addAction(allowBottomAction); + + areaActions = new QActionGroup(this); + areaActions->setExclusive(true); + + leftAction = new QAction(tr("Place on Left") , this); + leftAction->setCheckable(true); + connect(leftAction, SIGNAL(triggered(bool)), SLOT(placeLeft(bool))); + + rightAction = new QAction(tr("Place on Right") , this); + rightAction->setCheckable(true); + connect(rightAction, SIGNAL(triggered(bool)), SLOT(placeRight(bool))); + + topAction = new QAction(tr("Place on Top") , this); + topAction->setCheckable(true); + connect(topAction, SIGNAL(triggered(bool)), SLOT(placeTop(bool))); + + bottomAction = new QAction(tr("Place on Bottom") , this); + bottomAction->setCheckable(true); + connect(bottomAction, SIGNAL(triggered(bool)), SLOT(placeBottom(bool))); + + areaActions->addAction(leftAction); + areaActions->addAction(rightAction); + areaActions->addAction(topAction); + areaActions->addAction(bottomAction); + + toolBarBreakAction = new QAction(tr("Insert break"), this); + connect(toolBarBreakAction, SIGNAL(triggered(bool)), this, SLOT(insertToolBarBreak())); + + connect(movableAction, SIGNAL(triggered(bool)), areaActions, SLOT(setEnabled(bool))); + + connect(movableAction, SIGNAL(triggered(bool)), allowedAreasActions, SLOT(setEnabled(bool))); + + menu = new QMenu(title, this); + menu->addAction(toggleViewAction()); + menu->addSeparator(); + menu->addAction(orderAction); + menu->addAction(randomizeAction); + menu->addSeparator(); + menu->addAction(addSpinBoxAction); + menu->addAction(removeSpinBoxAction); + menu->addSeparator(); + menu->addAction(movableAction); + menu->addSeparator(); + menu->addActions(allowedAreasActions->actions()); + menu->addSeparator(); + menu->addActions(areaActions->actions()); + menu->addSeparator(); + menu->addAction(toolBarBreakAction); + + connect(menu, SIGNAL(aboutToShow()), this, SLOT(updateMenu())); + + randomize(); +} + +void ToolBar::updateMenu() +{ + QMainWindow *mainWindow = qobject_cast<QMainWindow *>(parentWidget()); + Q_ASSERT(mainWindow != 0); + + const Qt::ToolBarArea area = mainWindow->toolBarArea(this); + const Qt::ToolBarAreas areas = allowedAreas(); + + movableAction->setChecked(isMovable()); + + allowLeftAction->setChecked(isAreaAllowed(Qt::LeftToolBarArea)); + allowRightAction->setChecked(isAreaAllowed(Qt::RightToolBarArea)); + allowTopAction->setChecked(isAreaAllowed(Qt::TopToolBarArea)); + allowBottomAction->setChecked(isAreaAllowed(Qt::BottomToolBarArea)); + + if (allowedAreasActions->isEnabled()) { + allowLeftAction->setEnabled(area != Qt::LeftToolBarArea); + allowRightAction->setEnabled(area != Qt::RightToolBarArea); + allowTopAction->setEnabled(area != Qt::TopToolBarArea); + allowBottomAction->setEnabled(area != Qt::BottomToolBarArea); + } + + leftAction->setChecked(area == Qt::LeftToolBarArea); + rightAction->setChecked(area == Qt::RightToolBarArea); + topAction->setChecked(area == Qt::TopToolBarArea); + bottomAction->setChecked(area == Qt::BottomToolBarArea); + + if (areaActions->isEnabled()) { + leftAction->setEnabled(areas & Qt::LeftToolBarArea); + rightAction->setEnabled(areas & Qt::RightToolBarArea); + topAction->setEnabled(areas & Qt::TopToolBarArea); + bottomAction->setEnabled(areas & Qt::BottomToolBarArea); + } +} + +void ToolBar::order() +{ + QList<QAction *> ordered, actions1 = actions(), + actions2 = qFindChildren<QAction *>(this); + while (!actions2.isEmpty()) { + QAction *action = actions2.takeFirst(); + if (!actions1.contains(action)) + continue; + actions1.removeAll(action); + ordered.append(action); + } + + clear(); + addActions(ordered); + + orderAction->setEnabled(false); +} + +void ToolBar::randomize() +{ + QList<QAction *> randomized, actions = this->actions(); + while (!actions.isEmpty()) { + QAction *action = actions.takeAt(rand() % actions.size()); + randomized.append(action); + } + clear(); + addActions(randomized); + + orderAction->setEnabled(true); +} + +void ToolBar::addSpinBox() +{ + if (!spinbox) { + spinbox = new QSpinBox(this); + } + if (!spinboxAction) + spinboxAction = addWidget(spinbox); + else + addAction(spinboxAction); + + addSpinBoxAction->setEnabled(false); + removeSpinBoxAction->setEnabled(true); +} + +void ToolBar::removeSpinBox() +{ + if (spinboxAction) + removeAction(spinboxAction); + + addSpinBoxAction->setEnabled(true); + removeSpinBoxAction->setEnabled(false); +} + +void ToolBar::allow(Qt::ToolBarArea area, bool a) +{ + Qt::ToolBarAreas areas = allowedAreas(); + areas = a ? areas | area : areas & ~area; + setAllowedAreas(areas); + + if (areaActions->isEnabled()) { + leftAction->setEnabled(areas & Qt::LeftToolBarArea); + rightAction->setEnabled(areas & Qt::RightToolBarArea); + topAction->setEnabled(areas & Qt::TopToolBarArea); + bottomAction->setEnabled(areas & Qt::BottomToolBarArea); + } +} + +void ToolBar::place(Qt::ToolBarArea area, bool p) +{ + if (!p) + return; + + QMainWindow *mainWindow = qobject_cast<QMainWindow *>(parentWidget()); + Q_ASSERT(mainWindow != 0); + + mainWindow->addToolBar(area, this); + + if (allowedAreasActions->isEnabled()) { + allowLeftAction->setEnabled(area != Qt::LeftToolBarArea); + allowRightAction->setEnabled(area != Qt::RightToolBarArea); + allowTopAction->setEnabled(area != Qt::TopToolBarArea); + allowBottomAction->setEnabled(area != Qt::BottomToolBarArea); + } +} + +void ToolBar::changeMovable(bool movable) +{ setMovable(movable); } + +void ToolBar::allowLeft(bool a) +{ allow(Qt::LeftToolBarArea, a); } + +void ToolBar::allowRight(bool a) +{ allow(Qt::RightToolBarArea, a); } + +void ToolBar::allowTop(bool a) +{ allow(Qt::TopToolBarArea, a); } + +void ToolBar::allowBottom(bool a) +{ allow(Qt::BottomToolBarArea, a); } + +void ToolBar::placeLeft(bool p) +{ place(Qt::LeftToolBarArea, p); } + +void ToolBar::placeRight(bool p) +{ place(Qt::RightToolBarArea, p); } + +void ToolBar::placeTop(bool p) +{ place(Qt::TopToolBarArea, p); } + +void ToolBar::placeBottom(bool p) +{ place(Qt::BottomToolBarArea, p); } + +void ToolBar::insertToolBarBreak() +{ + QMainWindow *mainWindow = qobject_cast<QMainWindow *>(parentWidget()); + Q_ASSERT(mainWindow != 0); + + mainWindow->insertToolBarBreak(this); +} + +void ToolBar::enterEvent(QEvent*) +{ +/* + These labels on top of toolbars look darn ugly + + if (tip == 0) { + tip = new QLabel(windowTitle(), this); + QPalette pal = tip->palette(); + QColor c = Qt::black; + c.setAlpha(100); + pal.setColor(QPalette::Window, c); + pal.setColor(QPalette::Foreground, Qt::white); + tip->setPalette(pal); + tip->setAutoFillBackground(true); + tip->setMargin(3); + tip->setText(windowTitle()); + } + QPoint c = rect().center(); + QSize hint = tip->sizeHint(); + tip->setGeometry(c.x() - hint.width()/2, c.y() - hint.height()/2, + hint.width(), hint.height()); + + tip->show(); +*/ +} + +void ToolBar::leaveEvent(QEvent*) +{ + if (tip != 0) + tip->hide(); +} diff --git a/demos/mainwindow/toolbar.h b/demos/mainwindow/toolbar.h new file mode 100644 index 0000000..a9b9af2 --- /dev/null +++ b/demos/mainwindow/toolbar.h @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef TOOLBAR_H +#define TOOLBAR_H + +#include <QToolBar> + +QT_FORWARD_DECLARE_CLASS(QAction) +QT_FORWARD_DECLARE_CLASS(QActionGroup) +QT_FORWARD_DECLARE_CLASS(QMenu) +QT_FORWARD_DECLARE_CLASS(QSpinBox) +QT_FORWARD_DECLARE_CLASS(QLabel) + +class ToolBar : public QToolBar +{ + Q_OBJECT + + QSpinBox *spinbox; + QAction *spinboxAction; + + QAction *orderAction; + QAction *randomizeAction; + QAction *addSpinBoxAction; + QAction *removeSpinBoxAction; + + QAction *movableAction; + + QActionGroup *allowedAreasActions; + QAction *allowLeftAction; + QAction *allowRightAction; + QAction *allowTopAction; + QAction *allowBottomAction; + + QActionGroup *areaActions; + QAction *leftAction; + QAction *rightAction; + QAction *topAction; + QAction *bottomAction; + + QAction *toolBarBreakAction; + +public: + ToolBar(const QString &title, QWidget *parent); + + QMenu *menu; + +protected: + void enterEvent(QEvent*); + void leaveEvent(QEvent*); + +private: + void allow(Qt::ToolBarArea area, bool allow); + void place(Qt::ToolBarArea area, bool place); + QLabel *tip; + +private slots: + void order(); + void randomize(); + void addSpinBox(); + void removeSpinBox(); + + void changeMovable(bool movable); + + void allowLeft(bool a); + void allowRight(bool a); + void allowTop(bool a); + void allowBottom(bool a); + + void placeLeft(bool p); + void placeRight(bool p); + void placeTop(bool p); + void placeBottom(bool p); + + void updateMenu(); + void insertToolBarBreak(); + +}; + +#endif |