summaryrefslogtreecommitdiffstats
path: root/demos/mainwindow/mainwindow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'demos/mainwindow/mainwindow.cpp')
-rw-r--r--demos/mainwindow/mainwindow.cpp510
1 files changed, 510 insertions, 0 deletions
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);
+}