summaryrefslogtreecommitdiffstats
path: root/src/designer/src/designer
diff options
context:
space:
mode:
Diffstat (limited to 'src/designer/src/designer')
-rw-r--r--src/designer/src/designer/Info_mac.plist35
-rw-r--r--src/designer/src/designer/appfontdialog.cpp429
-rw-r--r--src/designer/src/designer/appfontdialog.h101
-rw-r--r--src/designer/src/designer/assistantclient.cpp175
-rw-r--r--src/designer/src/designer/assistantclient.h83
-rw-r--r--src/designer/src/designer/designer.icnsbin0 -> 154893 bytes
-rw-r--r--src/designer/src/designer/designer.icobin0 -> 355574 bytes
-rw-r--r--src/designer/src/designer/designer.pro90
-rw-r--r--src/designer/src/designer/designer.qrc5
-rw-r--r--src/designer/src/designer/designer.rc32
-rw-r--r--src/designer/src/designer/designer_enums.h52
-rw-r--r--src/designer/src/designer/images/designer.pngbin0 -> 4205 bytes
-rw-r--r--src/designer/src/designer/images/mdi.pngbin0 -> 59505 bytes
-rw-r--r--src/designer/src/designer/images/sdi.pngbin0 -> 61037 bytes
-rw-r--r--src/designer/src/designer/images/workbench.pngbin0 -> 2085 bytes
-rw-r--r--src/designer/src/designer/main.cpp58
-rw-r--r--src/designer/src/designer/mainwindow.cpp419
-rw-r--r--src/designer/src/designer/mainwindow.h187
-rw-r--r--src/designer/src/designer/newform.cpp227
-rw-r--r--src/designer/src/designer/newform.h104
-rw-r--r--src/designer/src/designer/preferencesdialog.cpp118
-rw-r--r--src/designer/src/designer/preferencesdialog.h82
-rw-r--r--src/designer/src/designer/preferencesdialog.ui91
-rw-r--r--src/designer/src/designer/qdesigner.cpp320
-rw-r--r--src/designer/src/designer/qdesigner.h102
-rw-r--r--src/designer/src/designer/qdesigner_actions.cpp1437
-rw-r--r--src/designer/src/designer/qdesigner_actions.h231
-rw-r--r--src/designer/src/designer/qdesigner_appearanceoptions.cpp167
-rw-r--r--src/designer/src/designer/qdesigner_appearanceoptions.h136
-rw-r--r--src/designer/src/designer/qdesigner_appearanceoptions.ui57
-rw-r--r--src/designer/src/designer/qdesigner_formwindow.cpp290
-rw-r--r--src/designer/src/designer/qdesigner_formwindow.h97
-rw-r--r--src/designer/src/designer/qdesigner_pch.h59
-rw-r--r--src/designer/src/designer/qdesigner_server.cpp156
-rw-r--r--src/designer/src/designer/qdesigner_server.h89
-rw-r--r--src/designer/src/designer/qdesigner_settings.cpp250
-rw-r--r--src/designer/src/designer/qdesigner_settings.h94
-rw-r--r--src/designer/src/designer/qdesigner_toolwindow.cpp438
-rw-r--r--src/designer/src/designer/qdesigner_toolwindow.h123
-rw-r--r--src/designer/src/designer/qdesigner_workbench.cpp1100
-rw-r--r--src/designer/src/designer/qdesigner_workbench.h215
-rw-r--r--src/designer/src/designer/saveformastemplate.cpp173
-rw-r--r--src/designer/src/designer/saveformastemplate.h77
-rw-r--r--src/designer/src/designer/saveformastemplate.ui166
-rw-r--r--src/designer/src/designer/uifile.icnsbin0 -> 123696 bytes
-rw-r--r--src/designer/src/designer/versiondialog.cpp191
-rw-r--r--src/designer/src/designer/versiondialog.h58
47 files changed, 8314 insertions, 0 deletions
diff --git a/src/designer/src/designer/Info_mac.plist b/src/designer/src/designer/Info_mac.plist
new file mode 100644
index 000000000..f19176fa7
--- /dev/null
+++ b/src/designer/src/designer/Info_mac.plist
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
+<plist version="0.9">
+<dict>
+ <key>CFBundleIconFile</key>
+ <string>@ICON@</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleGetInfoString</key>
+ <string>Created by Qt/QMake</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.trolltech.Designer</string>
+ <key>CFBundleSignature</key>
+ <string>ttxt</string>
+ <key>CFBundleExecutable</key>
+ <string>@EXECUTABLE@</string>
+ <key>CFBundleDocumentTypes</key>
+ <array>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>ui</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>uifile.icns</string>
+ <key>CFBundleTypeRole</key>
+ <string>Editor</string>
+ <key>LSIsAppleDefaultForType</key>
+ <true/>
+ </dict>
+ </array>
+ <key>NOTE</key>
+ <string>Qt/Designer by Nokia Corporation and/or its subsidiary(-ies)</string>
+</dict>
+</plist>
diff --git a/src/designer/src/designer/appfontdialog.cpp b/src/designer/src/designer/appfontdialog.cpp
new file mode 100644
index 000000000..00b91fa0d
--- /dev/null
+++ b/src/designer/src/designer/appfontdialog.cpp
@@ -0,0 +1,429 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "appfontdialog.h"
+
+#include <iconloader_p.h>
+#include <abstractsettings_p.h>
+
+#include <QtGui/QTreeView>
+#include <QtGui/QToolButton>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QSpacerItem>
+#include <QtGui/QFileDialog>
+#include <QtGui/QStandardItemModel>
+#include <QtGui/QMessageBox>
+#include <QtGui/QFontDatabase>
+#include <QtGui/QDialogButtonBox>
+
+#include <QtCore/QSettings>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QStringList>
+#include <QtCore/QFileInfo>
+#include <QtCore/QtAlgorithms>
+#include <QtCore/QVector>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+enum {FileNameRole = Qt::UserRole + 1, IdRole = Qt::UserRole + 2 };
+enum { debugAppFontWidget = 0 };
+
+static const char fontFileKeyC[] = "fontFiles";
+
+// AppFontManager: Singleton that maintains the mapping of loaded application font
+// ids to the file names (which are not stored in QFontDatabase)
+// and provides API for loading/unloading fonts as well for saving/restoring settings.
+
+class AppFontManager
+{
+ Q_DISABLE_COPY(AppFontManager)
+ AppFontManager();
+public:
+ static AppFontManager &instance();
+
+ void save(QDesignerSettingsInterface *s, const QString &prefix) const;
+ void restore(const QDesignerSettingsInterface *s, const QString &prefix);
+
+ // Return id or -1
+ int add(const QString &fontFile, QString *errorMessage);
+
+ bool remove(int id, QString *errorMessage);
+ bool remove(const QString &fontFile, QString *errorMessage);
+ bool removeAt(int index, QString *errorMessage);
+
+ // Store loaded fonts as pair of file name and Id
+ typedef QPair<QString,int> FileNameFontIdPair;
+ typedef QList<FileNameFontIdPair> FileNameFontIdPairs;
+ const FileNameFontIdPairs &fonts() const;
+
+private:
+ FileNameFontIdPairs m_fonts;
+};
+
+AppFontManager::AppFontManager()
+{
+}
+
+AppFontManager &AppFontManager::instance()
+{
+ static AppFontManager rc;
+ return rc;
+}
+
+void AppFontManager::save(QDesignerSettingsInterface *s, const QString &prefix) const
+{
+ // Store as list of file names
+ QStringList fontFiles;
+ const FileNameFontIdPairs::const_iterator cend = m_fonts.constEnd();
+ for (FileNameFontIdPairs::const_iterator it = m_fonts.constBegin(); it != cend; ++it)
+ fontFiles.push_back(it->first);
+
+ s->beginGroup(prefix);
+ s->setValue(QLatin1String(fontFileKeyC), fontFiles);
+ s->endGroup();
+
+ if (debugAppFontWidget)
+ qDebug() << "AppFontManager::saved" << fontFiles.size() << "fonts under " << prefix;
+}
+
+void AppFontManager::restore(const QDesignerSettingsInterface *s, const QString &prefix)
+{
+ QString key = prefix;
+ key += QLatin1Char('/');
+ key += QLatin1String(fontFileKeyC);
+ const QStringList fontFiles = s->value(key, QStringList()).toStringList();
+
+ if (debugAppFontWidget)
+ qDebug() << "AppFontManager::restoring" << fontFiles.size() << "fonts from " << prefix;
+ if (!fontFiles.empty()) {
+ QString errorMessage;
+ const QStringList::const_iterator cend = fontFiles.constEnd();
+ for (QStringList::const_iterator it = fontFiles.constBegin(); it != cend; ++it)
+ if (add(*it, &errorMessage) == -1)
+ qWarning("%s", qPrintable(errorMessage));
+ }
+}
+
+int AppFontManager::add(const QString &fontFile, QString *errorMessage)
+{
+ const QFileInfo inf(fontFile);
+ if (!inf.isFile()) {
+ *errorMessage = QCoreApplication::translate("AppFontManager", "'%1' is not a file.").arg(fontFile);
+ return -1;
+ }
+ if (!inf.isReadable()) {
+ *errorMessage = QCoreApplication::translate("AppFontManager", "The font file '%1' does not have read permissions.").arg(fontFile);
+ return -1;
+ }
+ const QString fullPath = inf.absoluteFilePath();
+ // Check if already loaded
+ const FileNameFontIdPairs::const_iterator cend = m_fonts.constEnd();
+ for (FileNameFontIdPairs::const_iterator it = m_fonts.constBegin(); it != cend; ++it) {
+ if (it->first == fullPath) {
+ *errorMessage = QCoreApplication::translate("AppFontManager", "The font file '%1' is already loaded.").arg(fontFile);
+ return -1;
+ }
+ }
+
+ const int id = QFontDatabase::addApplicationFont(fullPath);
+ if (id == -1) {
+ *errorMessage = QCoreApplication::translate("AppFontManager", "The font file '%1' could not be loaded.").arg(fontFile);
+ return -1;
+ }
+
+ if (debugAppFontWidget)
+ qDebug() << "AppFontManager::add" << fontFile << id;
+ m_fonts.push_back(FileNameFontIdPair(fullPath, id));
+ return id;
+}
+
+bool AppFontManager::remove(int id, QString *errorMessage)
+{
+ const int count = m_fonts.size();
+ for (int i = 0; i < count; i++)
+ if (m_fonts[i].second == id)
+ return removeAt(i, errorMessage);
+
+ *errorMessage = QCoreApplication::translate("AppFontManager", "'%1' is not a valid font id.").arg(id);
+ return false;
+}
+
+bool AppFontManager::remove(const QString &fontFile, QString *errorMessage)
+{
+ const int count = m_fonts.size();
+ for (int i = 0; i < count; i++)
+ if (m_fonts[i].first == fontFile)
+ return removeAt(i, errorMessage);
+
+ *errorMessage = QCoreApplication::translate("AppFontManager", "There is no loaded font matching the id '%1'.").arg(fontFile);
+ return false;
+}
+
+bool AppFontManager::removeAt(int index, QString *errorMessage)
+{
+ Q_ASSERT(index >= 0 && index < m_fonts.size());
+
+ const QString fontFile = m_fonts[index].first;
+ const int id = m_fonts[index].second;
+
+ if (debugAppFontWidget)
+ qDebug() << "AppFontManager::removeAt" << index << '(' << fontFile << id << ')';
+
+ if (!QFontDatabase::removeApplicationFont(id)) {
+ *errorMessage = QCoreApplication::translate("AppFontManager", "The font '%1' (%2) could not be unloaded.").arg(fontFile).arg(id);
+ return false;
+ }
+ m_fonts.removeAt(index);
+ return true;
+}
+
+const AppFontManager::FileNameFontIdPairs &AppFontManager::fonts() const
+{
+ return m_fonts;
+}
+
+// ------------- AppFontModel
+class AppFontModel : public QStandardItemModel {
+ Q_DISABLE_COPY(AppFontModel)
+public:
+ AppFontModel(QObject *parent = 0);
+
+ void init(const AppFontManager &mgr);
+ void add(const QString &fontFile, int id);
+ int idAt(const QModelIndex &idx) const;
+};
+
+AppFontModel::AppFontModel(QObject * parent) :
+ QStandardItemModel(parent)
+{
+ setHorizontalHeaderLabels(QStringList(AppFontWidget::tr("Fonts")));
+}
+
+void AppFontModel::init(const AppFontManager &mgr)
+{
+ typedef AppFontManager::FileNameFontIdPairs FileNameFontIdPairs;
+
+ const FileNameFontIdPairs &fonts = mgr.fonts();
+ const FileNameFontIdPairs::const_iterator cend = fonts.constEnd();
+ for (FileNameFontIdPairs::const_iterator it = fonts.constBegin(); it != cend; ++it)
+ add(it->first, it->second);
+}
+
+void AppFontModel::add(const QString &fontFile, int id)
+{
+ const QFileInfo inf(fontFile);
+ // Root item with base name
+ QStandardItem *fileItem = new QStandardItem(inf.completeBaseName());
+ const QString fullPath = inf.absoluteFilePath();
+ fileItem->setData(fullPath, FileNameRole);
+ fileItem->setToolTip(fullPath);
+ fileItem->setData(id, IdRole);
+ fileItem->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);
+
+ appendRow(fileItem);
+ const QStringList families = QFontDatabase::applicationFontFamilies(id);
+ const QStringList::const_iterator cend = families.constEnd();
+ for (QStringList::const_iterator it = families.constBegin(); it != cend; ++it) {
+ QStandardItem *familyItem = new QStandardItem(*it);
+ familyItem->setToolTip(fullPath);
+ familyItem->setFont(QFont(*it));
+ familyItem->setFlags(Qt::ItemIsEnabled);
+ fileItem->appendRow(familyItem);
+ }
+}
+
+int AppFontModel::idAt(const QModelIndex &idx) const
+{
+ if (const QStandardItem *item = itemFromIndex(idx))
+ return item->data(IdRole).toInt();
+ return -1;
+}
+
+// ------------- AppFontWidget
+AppFontWidget::AppFontWidget(QWidget *parent) :
+ QGroupBox(parent),
+ m_view(new QTreeView),
+ m_addButton(new QToolButton),
+ m_removeButton(new QToolButton),
+ m_removeAllButton(new QToolButton),
+ m_model(new AppFontModel(this))
+{
+ m_model->init(AppFontManager::instance());
+ m_view->setModel(m_model);
+ m_view->setSelectionMode(QAbstractItemView::ExtendedSelection);
+ m_view->expandAll();
+ connect(m_view->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(selectionChanged(QItemSelection,QItemSelection)));
+
+ m_addButton->setToolTip(tr("Add font files"));
+ m_addButton->setIcon(qdesigner_internal::createIconSet(QString::fromUtf8("plus.png")));
+ connect(m_addButton, SIGNAL(clicked()), this, SLOT(addFiles()));
+
+ m_removeButton->setEnabled(false);
+ m_removeButton->setToolTip(tr("Remove current font file"));
+ m_removeButton->setIcon(qdesigner_internal::createIconSet(QString::fromUtf8("minus.png")));
+ connect(m_removeButton, SIGNAL(clicked()), this, SLOT(slotRemoveFiles()));
+
+ m_removeAllButton->setToolTip(tr("Remove all font files"));
+ m_removeAllButton->setIcon(qdesigner_internal::createIconSet(QString::fromUtf8("editdelete.png")));
+ connect(m_removeAllButton, SIGNAL(clicked()), this, SLOT(slotRemoveAll()));
+
+ QHBoxLayout *hLayout = new QHBoxLayout;
+ hLayout->addWidget(m_addButton);
+ hLayout->addWidget(m_removeButton);
+ hLayout->addWidget(m_removeAllButton);
+ hLayout->addItem(new QSpacerItem(0, 0,QSizePolicy::MinimumExpanding));
+
+ QVBoxLayout *vLayout = new QVBoxLayout;
+ vLayout->addWidget(m_view);
+ vLayout->addLayout(hLayout);
+ setLayout(vLayout);
+}
+
+void AppFontWidget::addFiles()
+{
+ const QStringList files =
+ QFileDialog::getOpenFileNames(this, tr("Add Font Files"), QString(),
+ tr("Font files (*.ttf)"));
+ if (files.empty())
+ return;
+
+ QString errorMessage;
+
+ AppFontManager &fmgr = AppFontManager::instance();
+ const QStringList::const_iterator cend = files.constEnd();
+ for (QStringList::const_iterator it = files.constBegin(); it != cend; ++it) {
+ const int id = fmgr.add(*it, &errorMessage);
+ if (id != -1) {
+ m_model->add(*it, id);
+ } else {
+ QMessageBox::critical(this, tr("Error Adding Fonts"), errorMessage);
+ }
+ }
+ m_view->expandAll();
+}
+
+static void removeFonts(const QModelIndexList &selectedIndexes, AppFontModel *model, QWidget *dialogParent)
+{
+ if (selectedIndexes.empty())
+ return;
+
+ // Reverse sort top level rows and remove
+ AppFontManager &fmgr = AppFontManager::instance();
+ QVector<int> rows;
+ rows.reserve(selectedIndexes.size());
+
+ QString errorMessage;
+ const QModelIndexList::const_iterator cend = selectedIndexes.constEnd();
+ for (QModelIndexList::const_iterator it = selectedIndexes.constBegin(); it != cend; ++it) {
+ const int id = model->idAt(*it);
+ if (id != -1) {
+ if (fmgr.remove(id, &errorMessage)) {
+ rows.push_back(it->row());
+ } else {
+ QMessageBox::critical(dialogParent, AppFontWidget::tr("Error Removing Fonts"), errorMessage);
+ }
+ }
+ }
+
+ qStableSort(rows.begin(), rows.end());
+ for (int i = rows.size() - 1; i >= 0; i--)
+ model->removeRow(rows[i]);
+}
+
+void AppFontWidget::slotRemoveFiles()
+{
+ removeFonts(m_view->selectionModel()->selectedIndexes(), m_model, this);
+}
+
+void AppFontWidget::slotRemoveAll()
+{
+ const int count = m_model->rowCount();
+ if (!count)
+ return;
+
+ const QMessageBox::StandardButton answer =
+ QMessageBox::question(this, tr("Remove Fonts"), tr("Would you like to remove all fonts?"),
+ QMessageBox::Yes|QMessageBox::No, QMessageBox::No);
+ if (answer == QMessageBox::No)
+ return;
+
+ QModelIndexList topLevels;
+ for (int i = 0; i < count; i++)
+ topLevels.push_back(m_model->index(i, 0));
+ removeFonts(topLevels, m_model, this);
+}
+
+void AppFontWidget::selectionChanged(const QItemSelection &selected, const QItemSelection & /*deselected*/)
+{
+ m_removeButton->setEnabled(!selected.indexes().empty());
+}
+
+void AppFontWidget::save(QDesignerSettingsInterface *s, const QString &prefix)
+{
+ AppFontManager::instance().save(s, prefix);
+}
+
+void AppFontWidget::restore(const QDesignerSettingsInterface *s, const QString &prefix)
+{
+ AppFontManager::instance().restore(s, prefix);
+}
+
+// ------------ AppFontDialog
+AppFontDialog::AppFontDialog(QWidget *parent) :
+ QDialog(parent),
+ m_appFontWidget(new AppFontWidget)
+{
+ setAttribute(Qt::WA_DeleteOnClose, true);
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+ setWindowTitle(tr("Additional Fonts"));
+ setModal(false);
+ QVBoxLayout *vl = new QVBoxLayout;
+ vl->addWidget(m_appFontWidget);
+
+ QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Close);
+ QDialog::connect(bb, SIGNAL(rejected()), this, SLOT(reject()));
+ vl->addWidget(bb);
+ setLayout(vl);
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/designer/appfontdialog.h b/src/designer/src/designer/appfontdialog.h
new file mode 100644
index 000000000..a373217ac
--- /dev/null
+++ b/src/designer/src/designer/appfontdialog.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDESIGNER_APPFONTWIDGET_H
+#define QDESIGNER_APPFONTWIDGET_H
+
+#include <QtGui/QGroupBox>
+#include <QtGui/QDialog>
+
+QT_BEGIN_NAMESPACE
+
+class AppFontModel;
+
+class QTreeView;
+class QToolButton;
+class QItemSelection;
+class QDesignerSettingsInterface;
+
+// AppFontWidget: Manages application fonts which the user can load and
+// provides API for saving/restoring them.
+
+class AppFontWidget : public QGroupBox
+{
+ Q_DISABLE_COPY(AppFontWidget)
+ Q_OBJECT
+public:
+ explicit AppFontWidget(QWidget *parent = 0);
+
+ QStringList fontFiles() const;
+
+ static void save(QDesignerSettingsInterface *s, const QString &prefix);
+ static void restore(const QDesignerSettingsInterface *s, const QString &prefix);
+
+private slots:
+ void addFiles();
+ void slotRemoveFiles();
+ void slotRemoveAll();
+ void selectionChanged(const QItemSelection & selected, const QItemSelection & deselected);
+
+private:
+ QTreeView *m_view;
+ QToolButton *m_addButton;
+ QToolButton *m_removeButton;
+ QToolButton *m_removeAllButton;
+ AppFontModel *m_model;
+};
+
+// AppFontDialog: Non modal dialog for AppFontWidget which has Qt::WA_DeleteOnClose set.
+
+class AppFontDialog : public QDialog
+{
+ Q_DISABLE_COPY(AppFontDialog)
+ Q_OBJECT
+public:
+ explicit AppFontDialog(QWidget *parent = 0);
+
+private:
+ AppFontWidget *m_appFontWidget;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_APPFONTWIDGET_H
diff --git a/src/designer/src/designer/assistantclient.cpp b/src/designer/src/designer/assistantclient.cpp
new file mode 100644
index 000000000..0433c5c51
--- /dev/null
+++ b/src/designer/src/designer/assistantclient.cpp
@@ -0,0 +1,175 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "assistantclient.h"
+
+#include <QtCore/QString>
+#include <QtCore/QProcess>
+#include <QtCore/QDir>
+#include <QtCore/QLibraryInfo>
+#include <QtCore/QDebug>
+#include <QtCore/QFileInfo>
+#include <QtCore/QObject>
+#include <QtCore/QTextStream>
+#include <QtCore/QCoreApplication>
+
+QT_BEGIN_NAMESPACE
+
+enum { debugAssistantClient = 0 };
+
+AssistantClient::AssistantClient() :
+ m_process(0)
+{
+}
+
+AssistantClient::~AssistantClient()
+{
+ if (isRunning()) {
+ m_process->terminate();
+ m_process->waitForFinished();
+ }
+ delete m_process;
+}
+
+bool AssistantClient::showPage(const QString &path, QString *errorMessage)
+{
+ QString cmd = QLatin1String("SetSource ");
+ cmd += path;
+ return sendCommand(cmd, errorMessage);
+}
+
+bool AssistantClient::activateIdentifier(const QString &identifier, QString *errorMessage)
+{
+ QString cmd = QLatin1String("ActivateIdentifier ");
+ cmd += identifier;
+ return sendCommand(cmd, errorMessage);
+}
+
+bool AssistantClient::activateKeyword(const QString &keyword, QString *errorMessage)
+{
+ QString cmd = QLatin1String("ActivateKeyword ");
+ cmd += keyword;
+ return sendCommand(cmd, errorMessage);
+}
+
+bool AssistantClient::sendCommand(const QString &cmd, QString *errorMessage)
+{
+ if (debugAssistantClient)
+ qDebug() << "sendCommand " << cmd;
+ if (!ensureRunning(errorMessage))
+ return false;
+ if (!m_process->isWritable() || m_process->bytesToWrite() > 0) {
+ *errorMessage = QCoreApplication::translate("AssistantClient", "Unable to send request: Assistant is not responding.");
+ return false;
+ }
+ QTextStream str(m_process);
+ str << cmd << QLatin1Char('\n') << endl;
+ return true;
+}
+
+bool AssistantClient::isRunning() const
+{
+ return m_process && m_process->state() != QProcess::NotRunning;
+}
+
+QString AssistantClient::binary()
+{
+ QString app = QLibraryInfo::location(QLibraryInfo::BinariesPath) + QDir::separator();
+#if !defined(Q_OS_MAC)
+ app += QLatin1String("assistant");
+#else
+ app += QLatin1String("Assistant.app/Contents/MacOS/Assistant");
+#endif
+
+#if defined(Q_OS_WIN)
+ app += QLatin1String(".exe");
+#endif
+
+ return app;
+}
+
+bool AssistantClient::ensureRunning(QString *errorMessage)
+{
+ if (isRunning())
+ return true;
+
+ if (!m_process)
+ m_process = new QProcess;
+
+ const QString app = binary();
+ if (!QFileInfo(app).isFile()) {
+ *errorMessage = QCoreApplication::translate("AssistantClient", "The binary '%1' does not exist.").arg(app);
+ return false;
+ }
+ if (debugAssistantClient)
+ qDebug() << "Running " << app;
+ // run
+ QStringList args(QLatin1String("-enableRemoteControl"));
+ m_process->start(app, args);
+ if (!m_process->waitForStarted()) {
+ *errorMessage = QCoreApplication::translate("AssistantClient", "Unable to launch assistant (%1).").arg(app);
+ return false;
+ }
+ return true;
+}
+
+QString AssistantClient::documentUrl(const QString &prefix, int qtVersion)
+{
+ if (qtVersion == 0)
+ qtVersion = QT_VERSION;
+ QString rc;
+ QTextStream(&rc) << QLatin1String("qthelp://com.trolltech.") << prefix << QLatin1Char('.')
+ << (qtVersion >> 16) << ((qtVersion >> 8) & 0xFF) << (qtVersion & 0xFF)
+ << QLatin1String("/qdoc/");
+ return rc;
+}
+
+QString AssistantClient::designerManualUrl(int qtVersion)
+{
+ return documentUrl(QLatin1String("designer"), qtVersion);
+}
+
+QString AssistantClient::qtReferenceManualUrl(int qtVersion)
+{
+ return documentUrl(QLatin1String("qt"), qtVersion);
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/designer/assistantclient.h b/src/designer/src/designer/assistantclient.h
new file mode 100644
index 000000000..67257d191
--- /dev/null
+++ b/src/designer/src/designer/assistantclient.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ASSISTANTCLIENT_H
+#define ASSISTANTCLIENT_H
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+class QProcess;
+class QString;
+
+class AssistantClient
+{
+ AssistantClient(const AssistantClient &);
+ AssistantClient &operator=(const AssistantClient &);
+
+public:
+ AssistantClient();
+ ~AssistantClient();
+
+ bool showPage(const QString &path, QString *errorMessage);
+ bool activateIdentifier(const QString &identifier, QString *errorMessage);
+ bool activateKeyword(const QString &keyword, QString *errorMessage);
+
+ bool isRunning() const;
+
+ static QString documentUrl(const QString &prefix, int qtVersion = 0);
+ // Root of the Qt Designer documentation
+ static QString designerManualUrl(int qtVersion = 0);
+ // Root of the Qt Reference documentation
+ static QString qtReferenceManualUrl(int qtVersion = 0);
+
+private:
+ static QString binary();
+ bool sendCommand(const QString &cmd, QString *errorMessage);
+ bool ensureRunning(QString *errorMessage);
+
+ QProcess *m_process;
+};
+
+QT_END_NAMESPACE
+
+#endif // ASSISTANTCLIENT_H
diff --git a/src/designer/src/designer/designer.icns b/src/designer/src/designer/designer.icns
new file mode 100644
index 000000000..9940214fc
--- /dev/null
+++ b/src/designer/src/designer/designer.icns
Binary files differ
diff --git a/src/designer/src/designer/designer.ico b/src/designer/src/designer/designer.ico
new file mode 100644
index 000000000..ef667333d
--- /dev/null
+++ b/src/designer/src/designer/designer.ico
Binary files differ
diff --git a/src/designer/src/designer/designer.pro b/src/designer/src/designer/designer.pro
new file mode 100644
index 000000000..8564e96cb
--- /dev/null
+++ b/src/designer/src/designer/designer.pro
@@ -0,0 +1,90 @@
+
+DESTDIR = ../../../../bin
+QT += xml network
+contains(QT_CONFIG, script): QT += script
+build_all:!build_pass {
+ CONFIG -= build_all
+ CONFIG += release
+}
+
+INCLUDEPATH += \
+ ../lib/sdk \
+ ../lib/extension \
+ ../lib/shared \
+ ../lib/uilib \
+ extra
+
+QMAKE_LIBDIR += ../../lib ../../../../lib
+LIBS += -lQtDesignerComponents -lQtDesigner
+
+RESOURCES += designer.qrc
+
+contains(CONFIG, static) {
+ DEFINES += QT_DESIGNER_STATIC
+}
+
+TARGET = designer
+
+include(../../../shared/fontpanel/fontpanel.pri)
+include(../../../shared/qttoolbardialog/qttoolbardialog.pri)
+
+HEADERS += \
+ qdesigner.h \
+ qdesigner_toolwindow.h \
+ qdesigner_formwindow.h \
+ qdesigner_workbench.h \
+ qdesigner_settings.h \
+ qdesigner_actions.h \
+ qdesigner_server.h \
+ qdesigner_appearanceoptions.h \
+ saveformastemplate.h \
+ newform.h \
+ versiondialog.h \
+ designer_enums.h \
+ appfontdialog.h \
+ preferencesdialog.h \
+ assistantclient.h \
+ mainwindow.h
+
+SOURCES += main.cpp \
+ qdesigner.cpp \
+ qdesigner_toolwindow.cpp \
+ qdesigner_formwindow.cpp \
+ qdesigner_workbench.cpp \
+ qdesigner_settings.cpp \
+ qdesigner_server.cpp \
+ qdesigner_actions.cpp \
+ qdesigner_appearanceoptions.cpp \
+ saveformastemplate.cpp \
+ newform.cpp \
+ versiondialog.cpp \
+ appfontdialog.cpp \
+ preferencesdialog.cpp \
+ assistantclient.cpp \
+ mainwindow.cpp
+
+PRECOMPILED_HEADER=qdesigner_pch.h
+
+FORMS += saveformastemplate.ui \
+ preferencesdialog.ui \
+ qdesigner_appearanceoptions.ui
+
+win32 {
+ RC_FILE = designer.rc
+}
+
+mac {
+ ICON = designer.icns
+ QMAKE_INFO_PLIST = Info_mac.plist
+ TARGET = Designer
+ FILETYPES.files = uifile.icns
+ FILETYPES.path = Contents/Resources
+ QMAKE_BUNDLE_DATA += FILETYPES
+}
+
+target.path=$$[QT_INSTALL_BINS]
+INSTALLS += target
+
+include(../sharedcomponents.pri)
+
+unix:!mac:LIBS += -lm
diff --git a/src/designer/src/designer/designer.qrc b/src/designer/src/designer/designer.qrc
new file mode 100644
index 000000000..fac8120d0
--- /dev/null
+++ b/src/designer/src/designer/designer.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+ <qresource prefix="/trolltech/designer">
+ <file>images/designer.png</file>
+ </qresource>
+</RCC>
diff --git a/src/designer/src/designer/designer.rc b/src/designer/src/designer/designer.rc
new file mode 100644
index 000000000..9c396b555
--- /dev/null
+++ b/src/designer/src/designer/designer.rc
@@ -0,0 +1,32 @@
+#include "winver.h"
+
+IDI_ICON1 ICON DISCARDABLE "designer.ico"
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,0
+ PRODUCTVERSION 1,0,0,0
+ FILEFLAGS 0x0L
+ FILEFLAGSMASK 0x3fL
+ FILEOS 0x00040004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "000004b0"
+ BEGIN
+ VALUE "CompanyName", "Nokia Corporation and/or its subsidiary(-ies)"
+ VALUE "FileDescription", "Qt Designer"
+ VALUE "FileVersion", "1.0.0.0"
+ VALUE "LegalCopyright", "Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)."
+ VALUE "InternalName", "designer"
+ VALUE "OriginalFilename", "designer.exe"
+ VALUE "ProductName", "Qt Designer"
+ VALUE "ProductVersion", "1.0.0.0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1200
+ END
+END
diff --git a/src/designer/src/designer/designer_enums.h b/src/designer/src/designer/designer_enums.h
new file mode 100644
index 000000000..ca115c37a
--- /dev/null
+++ b/src/designer/src/designer/designer_enums.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DESIGNERENUMS_H
+#define DESIGNERENUMS_H
+
+enum UIMode
+{
+ NeutralMode,
+ TopLevelMode,
+ DockedMode
+};
+
+#endif // DESIGNERENUMS_H
diff --git a/src/designer/src/designer/images/designer.png b/src/designer/src/designer/images/designer.png
new file mode 100644
index 000000000..0988fcee3
--- /dev/null
+++ b/src/designer/src/designer/images/designer.png
Binary files differ
diff --git a/src/designer/src/designer/images/mdi.png b/src/designer/src/designer/images/mdi.png
new file mode 100644
index 000000000..5012ab304
--- /dev/null
+++ b/src/designer/src/designer/images/mdi.png
Binary files differ
diff --git a/src/designer/src/designer/images/sdi.png b/src/designer/src/designer/images/sdi.png
new file mode 100644
index 000000000..7fff6e8b6
--- /dev/null
+++ b/src/designer/src/designer/images/sdi.png
Binary files differ
diff --git a/src/designer/src/designer/images/workbench.png b/src/designer/src/designer/images/workbench.png
new file mode 100644
index 000000000..06716a44f
--- /dev/null
+++ b/src/designer/src/designer/images/workbench.png
Binary files differ
diff --git a/src/designer/src/designer/main.cpp b/src/designer/src/designer/main.cpp
new file mode 100644
index 000000000..8a5b5c044
--- /dev/null
+++ b/src/designer/src/designer/main.cpp
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner.h"
+#include <QtCore/QLibraryInfo>
+#include <QtCore/QDir>
+
+#include <stdlib.h>
+
+QT_USE_NAMESPACE
+
+int main(int argc, char *argv[])
+{
+ Q_INIT_RESOURCE(designer);
+
+ QDesigner app(argc, argv);
+ app.setQuitOnLastWindowClosed(false);
+
+ return app.exec();
+}
diff --git a/src/designer/src/designer/mainwindow.cpp b/src/designer/src/designer/mainwindow.cpp
new file mode 100644
index 000000000..67e1a4053
--- /dev/null
+++ b/src/designer/src/designer/mainwindow.cpp
@@ -0,0 +1,419 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "mainwindow.h"
+#include "qdesigner.h"
+#include "qdesigner_actions.h"
+#include "qdesigner_workbench.h"
+#include "qdesigner_formwindow.h"
+#include "qdesigner_toolwindow.h"
+#include "qdesigner_settings.h"
+#include "qttoolbardialog.h"
+
+#include <QtDesigner/QDesignerFormWindowInterface>
+
+#include <QtGui/QAction>
+#include <QtGui/QCloseEvent>
+#include <QtGui/QToolBar>
+#include <QtGui/QMdiSubWindow>
+#include <QtGui/QStatusBar>
+#include <QtGui/QMenu>
+#include <QtGui/QLayout>
+#include <QtGui/QDockWidget>
+
+#include <QtCore/QUrl>
+#include <QtCore/QDebug>
+
+static const char *uriListMimeFormatC = "text/uri-list";
+
+QT_BEGIN_NAMESPACE
+
+typedef QList<QAction *> ActionList;
+
+// Helpers for creating toolbars and menu
+
+static void addActionsToToolBar(const ActionList &actions, QToolBar *t)
+{
+ const ActionList::const_iterator cend = actions.constEnd();
+ for (ActionList::const_iterator it = actions.constBegin(); it != cend; ++it) {
+ QAction *action = *it;
+ if (action->property(QDesignerActions::defaultToolbarPropertyName).toBool())
+ t->addAction(action);
+ }
+}
+static QToolBar *createToolBar(const QString &title, const QString &objectName, const ActionList &actions)
+{
+ QToolBar *rc = new QToolBar;
+ rc->setObjectName(objectName);
+ rc->setWindowTitle(title);
+ addActionsToToolBar(actions, rc);
+ return rc;
+}
+
+// ---------------- MainWindowBase
+
+MainWindowBase::MainWindowBase(QWidget *parent, Qt::WindowFlags flags) :
+ QMainWindow(parent, flags),
+ m_policy(AcceptCloseEvents)
+{
+#ifndef Q_WS_MAC
+ setWindowIcon(qDesigner->windowIcon());
+#endif
+}
+
+void MainWindowBase::closeEvent(QCloseEvent *e)
+{
+ switch (m_policy) {
+ case AcceptCloseEvents:
+ QMainWindow::closeEvent(e);
+ break;
+ case EmitCloseEventSignal:
+ emit closeEventReceived(e);
+ break;
+ }
+}
+
+QList<QToolBar *> MainWindowBase::createToolBars(const QDesignerActions *actions, bool singleToolBar)
+{
+ // Note that whenever you want to add a new tool bar here, you also have to update the default
+ // action groups added to the toolbar manager in the mainwindow constructor
+ QList<QToolBar *> rc;
+ if (singleToolBar) {
+ //: Not currently used (main tool bar)
+ QToolBar *main = createToolBar(tr("Main"), QLatin1String("mainToolBar"), actions->fileActions()->actions());
+ addActionsToToolBar(actions->editActions()->actions(), main);
+ addActionsToToolBar(actions->toolActions()->actions(), main);
+ addActionsToToolBar(actions->formActions()->actions(), main);
+ rc.push_back(main);
+ } else {
+ rc.push_back(createToolBar(tr("File"), QLatin1String("fileToolBar"), actions->fileActions()->actions()));
+ rc.push_back(createToolBar(tr("Edit"), QLatin1String("editToolBar"), actions->editActions()->actions()));
+ rc.push_back(createToolBar(tr("Tools"), QLatin1String("toolsToolBar"), actions->toolActions()->actions()));
+ rc.push_back(createToolBar(tr("Form"), QLatin1String("formToolBar"), actions->formActions()->actions()));
+ }
+ return rc;
+}
+
+QString MainWindowBase::mainWindowTitle()
+{
+ return tr("Qt Designer");
+}
+
+// Use the minor Qt version as settings versions to avoid conflicts
+int MainWindowBase::settingsVersion()
+{
+ const int version = QT_VERSION;
+ return (version & 0x00FF00) >> 8;
+}
+
+// ----------------- DockedMdiArea
+
+DockedMdiArea::DockedMdiArea(const QString &extension, QWidget *parent) :
+ QMdiArea(parent),
+ m_extension(extension)
+{
+ setAcceptDrops(true);
+ setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+}
+
+QStringList DockedMdiArea::uiFiles(const QMimeData *d) const
+{
+ // Extract dropped UI files from Mime data.
+ QStringList rc;
+ if (!d->hasFormat(QLatin1String(uriListMimeFormatC)))
+ return rc;
+ const QList<QUrl> urls = d->urls();
+ if (urls.empty())
+ return rc;
+ const QList<QUrl>::const_iterator cend = urls.constEnd();
+ for (QList<QUrl>::const_iterator it = urls.constBegin(); it != cend; ++it) {
+ const QString fileName = it->toLocalFile();
+ if (!fileName.isEmpty() && fileName.endsWith(m_extension))
+ rc.push_back(fileName);
+ }
+ return rc;
+}
+
+bool DockedMdiArea::event(QEvent *event)
+{
+ // Listen for desktop file manager drop and emit a signal once a file is
+ // dropped.
+ switch (event->type()) {
+ case QEvent::DragEnter: {
+ QDragEnterEvent *e = static_cast<QDragEnterEvent*>(event);
+ if (!uiFiles(e->mimeData()).empty()) {
+ e->acceptProposedAction();
+ return true;
+ }
+ }
+ break;
+ case QEvent::Drop: {
+ QDropEvent *e = static_cast<QDropEvent*>(event);
+ const QStringList files = uiFiles(e->mimeData());
+ const QStringList::const_iterator cend = files.constEnd();
+ for (QStringList::const_iterator it = files.constBegin(); it != cend; ++it) {
+ emit fileDropped(*it);
+ }
+ e->acceptProposedAction();
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
+ return QMdiArea::event(event);
+}
+
+// ------------- ToolBarManager:
+
+static void addActionsToToolBarManager(const ActionList &al, const QString &title, QtToolBarManager *tbm)
+{
+ const ActionList::const_iterator cend = al.constEnd();
+ for (ActionList::const_iterator it = al.constBegin(); it != cend; ++it)
+ tbm->addAction(*it, title);
+}
+
+ToolBarManager::ToolBarManager(QMainWindow *configureableMainWindow,
+ QWidget *parent,
+ QMenu *toolBarMenu,
+ const QDesignerActions *actions,
+ const QList<QToolBar *> &toolbars,
+ const QList<QDesignerToolWindow*> &toolWindows) :
+ QObject(parent),
+ m_configureableMainWindow(configureableMainWindow),
+ m_parent(parent),
+ m_toolBarMenu(toolBarMenu),
+ m_manager(new QtToolBarManager(this)),
+ m_configureAction(new QAction(tr("Configure Toolbars..."), this)),
+ m_toolbars(toolbars)
+{
+ m_configureAction->setMenuRole(QAction::NoRole);
+ m_configureAction->setObjectName(QLatin1String("__qt_configure_tool_bars_action"));
+ connect(m_configureAction, SIGNAL(triggered()), this, SLOT(configureToolBars()));
+
+ m_manager->setMainWindow(configureableMainWindow);
+
+ foreach(QToolBar *tb, m_toolbars) {
+ const QString title = tb->windowTitle();
+ m_manager->addToolBar(tb, title);
+ addActionsToToolBarManager(tb->actions(), title, m_manager);
+ }
+
+ addActionsToToolBarManager(actions->windowActions()->actions(), tr("Window"), m_manager);
+ addActionsToToolBarManager(actions->helpActions()->actions(), tr("Help"), m_manager);
+
+ // Filter out the device profile preview actions which have int data().
+ ActionList previewActions = actions->styleActions()->actions();
+ ActionList::iterator it = previewActions.begin();
+ for ( ; (*it)->isSeparator() || (*it)->data().type() == QVariant::Int; ++it) ;
+ previewActions.erase(previewActions.begin(), it);
+ addActionsToToolBarManager(previewActions, tr("Style"), m_manager);
+
+ const QString dockTitle = tr("Dock views");
+ foreach (QDesignerToolWindow *tw, toolWindows) {
+ if (QAction *action = tw->action())
+ m_manager->addAction(action, dockTitle);
+ }
+
+ QString category(tr("File"));
+ foreach(QAction *action, actions->fileActions()->actions())
+ m_manager->addAction(action, category);
+
+ category = tr("Edit");
+ foreach(QAction *action, actions->editActions()->actions())
+ m_manager->addAction(action, category);
+
+ category = tr("Tools");
+ foreach(QAction *action, actions->toolActions()->actions())
+ m_manager->addAction(action, category);
+
+ category = tr("Form");
+ foreach(QAction *action, actions->formActions()->actions())
+ m_manager->addAction(action, category);
+
+ m_manager->addAction(m_configureAction, tr("Toolbars"));
+ updateToolBarMenu();
+}
+
+// sort function for sorting tool bars alphabetically by title [non-static since called from template]
+
+bool toolBarTitleLessThan(const QToolBar *t1, const QToolBar *t2)
+{
+ return t1->windowTitle() < t2->windowTitle();
+}
+
+void ToolBarManager::updateToolBarMenu()
+{
+ // Sort tool bars alphabetically by title
+ qStableSort(m_toolbars.begin(), m_toolbars.end(), toolBarTitleLessThan);
+ // add to menu
+ m_toolBarMenu->clear();
+ foreach (QToolBar *tb, m_toolbars)
+ m_toolBarMenu->addAction(tb->toggleViewAction());
+ m_toolBarMenu->addAction(m_configureAction);
+}
+
+void ToolBarManager::configureToolBars()
+{
+ QtToolBarDialog dlg(m_parent);
+ dlg.setWindowFlags(dlg.windowFlags() & ~Qt::WindowContextHelpButtonHint);
+ dlg.setToolBarManager(m_manager);
+ dlg.exec();
+ updateToolBarMenu();
+}
+
+QByteArray ToolBarManager::saveState(int version) const
+{
+ return m_manager->saveState(version);
+}
+
+bool ToolBarManager::restoreState(const QByteArray &state, int version)
+{
+ return m_manager->restoreState(state, version);
+}
+
+// ---------- DockedMainWindow
+
+DockedMainWindow::DockedMainWindow(QDesignerWorkbench *wb,
+ QMenu *toolBarMenu,
+ const QList<QDesignerToolWindow*> &toolWindows) :
+ m_toolBarManager(0)
+{
+ setObjectName(QLatin1String("MDIWindow"));
+ setWindowTitle(mainWindowTitle());
+
+ const QList<QToolBar *> toolbars = createToolBars(wb->actionManager(), false);
+ foreach (QToolBar *tb, toolbars)
+ addToolBar(tb);
+ DockedMdiArea *dma = new DockedMdiArea(wb->actionManager()->uiExtension());
+ connect(dma, SIGNAL(fileDropped(QString)),
+ this, SIGNAL(fileDropped(QString)));
+ connect(dma, SIGNAL(subWindowActivated(QMdiSubWindow*)),
+ this, SLOT(slotSubWindowActivated(QMdiSubWindow*)));
+ setCentralWidget(dma);
+
+ QStatusBar *sb = statusBar();
+ Q_UNUSED(sb)
+
+ m_toolBarManager = new ToolBarManager(this, this, toolBarMenu, wb->actionManager(), toolbars, toolWindows);
+}
+
+QMdiArea *DockedMainWindow::mdiArea() const
+{
+ return static_cast<QMdiArea *>(centralWidget());
+}
+
+void DockedMainWindow::slotSubWindowActivated(QMdiSubWindow* subWindow)
+{
+ if (subWindow) {
+ QWidget *widget = subWindow->widget();
+ if (QDesignerFormWindow *fw = qobject_cast<QDesignerFormWindow*>(widget)) {
+ emit formWindowActivated(fw);
+ mdiArea()->setActiveSubWindow(subWindow);
+ }
+ }
+}
+
+// Create a MDI subwindow for the form.
+QMdiSubWindow *DockedMainWindow::createMdiSubWindow(QWidget *fw, Qt::WindowFlags f, const QKeySequence &designerCloseActionShortCut)
+{
+ QMdiSubWindow *rc = mdiArea()->addSubWindow(fw, f);
+ // Make action shortcuts respond only if focused to avoid conflicts with
+ // designer menu actions
+ if (designerCloseActionShortCut == QKeySequence(QKeySequence::Close)) {
+ const ActionList systemMenuActions = rc->systemMenu()->actions();
+ if (!systemMenuActions.empty()) {
+ const ActionList::const_iterator cend = systemMenuActions.constEnd();
+ for (ActionList::const_iterator it = systemMenuActions.constBegin(); it != cend; ++it) {
+ if ( (*it)->shortcut() == designerCloseActionShortCut) {
+ (*it)->setShortcutContext(Qt::WidgetShortcut);
+ break;
+ }
+ }
+ }
+ }
+ return rc;
+}
+
+DockedMainWindow::DockWidgetList DockedMainWindow::addToolWindows(const DesignerToolWindowList &tls)
+{
+ DockWidgetList rc;
+ foreach (QDesignerToolWindow *tw, tls) {
+ QDockWidget *dockWidget = new QDockWidget;
+ dockWidget->setObjectName(tw->objectName() + QLatin1String("_dock"));
+ dockWidget->setWindowTitle(tw->windowTitle());
+ addDockWidget(tw->dockWidgetAreaHint(), dockWidget);
+ dockWidget->setWidget(tw);
+ rc.push_back(dockWidget);
+ }
+ return rc;
+}
+
+// Settings consist of MainWindow state and tool bar manager state
+void DockedMainWindow::restoreSettings(const QDesignerSettings &s, const DockWidgetList &dws, const QRect &desktopArea)
+{
+ const int version = settingsVersion();
+ m_toolBarManager->restoreState(s.toolBarsState(DockedMode), version);
+
+ // If there are no old geometry settings, show the window maximized
+ s.restoreGeometry(this, QRect(desktopArea.topLeft(), QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)));
+
+ const QByteArray mainWindowState = s.mainWindowState(DockedMode);
+ const bool restored = !mainWindowState.isEmpty() && restoreState(mainWindowState, version);
+ if (!restored) {
+ // Default: Tabify less relevant windows bottom/right.
+ tabifyDockWidget(dws.at(QDesignerToolWindow::SignalSlotEditor),
+ dws.at(QDesignerToolWindow::ActionEditor));
+ tabifyDockWidget(dws.at(QDesignerToolWindow::ActionEditor),
+ dws.at(QDesignerToolWindow::ResourceEditor));
+ }
+}
+
+void DockedMainWindow::saveSettings(QDesignerSettings &s) const
+{
+ const int version = settingsVersion();
+ s.setToolBarsState(DockedMode, m_toolBarManager->saveState(version));
+ s.saveGeometryFor(this);
+ s.setMainWindowState(DockedMode, saveState(version));
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/designer/mainwindow.h b/src/designer/src/designer/mainwindow.h
new file mode 100644
index 000000000..e39e57203
--- /dev/null
+++ b/src/designer/src/designer/mainwindow.h
@@ -0,0 +1,187 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QtGui/QMainWindow>
+#include <QtCore/QList>
+#include <QtGui/QMdiArea>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerActions;
+class QDesignerWorkbench;
+class QDesignerToolWindow;
+class QDesignerFormWindow;
+class QDesignerSettings;
+
+class QtToolBarManager;
+class QToolBar;
+class QMdiArea;
+class QMenu;
+class QByteArray;
+class QMimeData;
+
+/* A main window that has a configureable policy on handling close events. If
+ * enabled, it can forward the close event to external handlers.
+ * Base class for windows that can switch roles between tool windows
+ * and main windows. */
+
+class MainWindowBase: public QMainWindow
+{
+ Q_DISABLE_COPY(MainWindowBase)
+ Q_OBJECT
+protected:
+ explicit MainWindowBase(QWidget *parent = 0, Qt::WindowFlags flags = Qt::Window);
+
+public:
+ enum CloseEventPolicy {
+ /* Always accept close events */
+ AcceptCloseEvents,
+ /* Emit a signal with the event, have it handled elsewhere */
+ EmitCloseEventSignal };
+
+ CloseEventPolicy closeEventPolicy() const { return m_policy; }
+ void setCloseEventPolicy(CloseEventPolicy pol) { m_policy = pol; }
+
+ static QList<QToolBar *> createToolBars(const QDesignerActions *actions, bool singleToolBar);
+ static QString mainWindowTitle();
+
+ // Use the minor Qt version as settings versions to avoid conflicts
+ static int settingsVersion();
+
+signals:
+ void closeEventReceived(QCloseEvent *e);
+
+protected:
+ virtual void closeEvent(QCloseEvent *e);
+private:
+ CloseEventPolicy m_policy;
+};
+
+/* An MdiArea that listens for desktop file manager file drop events and emits
+ * a signal to open a dropped file. */
+class DockedMdiArea : public QMdiArea
+{
+ Q_DISABLE_COPY(DockedMdiArea)
+ Q_OBJECT
+public:
+ explicit DockedMdiArea(const QString &extension, QWidget *parent = 0);
+
+signals:
+ void fileDropped(const QString &);
+
+protected:
+ bool event (QEvent *event);
+
+private:
+ QStringList uiFiles(const QMimeData *d) const;
+
+ const QString m_extension;
+};
+
+// Convenience class that manages a QtToolBarManager and an action to trigger
+// it on a mainwindow.
+class ToolBarManager : public QObject
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(ToolBarManager)
+public:
+ explicit ToolBarManager(QMainWindow *configureableMainWindow,
+ QWidget *parent,
+ QMenu *toolBarMenu,
+ const QDesignerActions *actions,
+ const QList<QToolBar *> &toolbars,
+ const QList<QDesignerToolWindow*> &toolWindows);
+
+ QByteArray saveState(int version = 0) const;
+ bool restoreState(const QByteArray &state, int version = 0);
+
+private slots:
+ void configureToolBars();
+ void updateToolBarMenu();
+
+private:
+ QMainWindow *m_configureableMainWindow;
+ QWidget *m_parent;
+ QMenu *m_toolBarMenu;
+ QtToolBarManager *m_manager;
+ QAction *m_configureAction;
+ QList<QToolBar *> m_toolbars;
+};
+
+/* Main window to be used for docked mode */
+class DockedMainWindow : public MainWindowBase {
+ Q_OBJECT
+ Q_DISABLE_COPY(DockedMainWindow)
+public:
+ typedef QList<QDesignerToolWindow*> DesignerToolWindowList;
+ typedef QList<QDockWidget *> DockWidgetList;
+
+ explicit DockedMainWindow(QDesignerWorkbench *wb,
+ QMenu *toolBarMenu,
+ const DesignerToolWindowList &toolWindows);
+
+ // Create a MDI subwindow for the form.
+ QMdiSubWindow *createMdiSubWindow(QWidget *fw, Qt::WindowFlags f, const QKeySequence &designerCloseActionShortCut);
+
+ QMdiArea *mdiArea() const;
+
+ DockWidgetList addToolWindows(const DesignerToolWindowList &toolWindows);
+
+ void restoreSettings(const QDesignerSettings &s, const DockWidgetList &dws, const QRect &desktopArea);
+ void saveSettings(QDesignerSettings &) const;
+
+signals:
+ void fileDropped(const QString &);
+ void formWindowActivated(QDesignerFormWindow *);
+
+private slots:
+ void slotSubWindowActivated(QMdiSubWindow*);
+
+private:
+ ToolBarManager *m_toolBarManager;
+};
+
+QT_END_NAMESPACE
+
+#endif // MAINWINDOW_H
diff --git a/src/designer/src/designer/newform.cpp b/src/designer/src/designer/newform.cpp
new file mode 100644
index 000000000..34461f52a
--- /dev/null
+++ b/src/designer/src/designer/newform.cpp
@@ -0,0 +1,227 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "newform.h"
+#include "qdesigner_workbench.h"
+#include "qdesigner_actions.h"
+#include "qdesigner_formwindow.h"
+#include "qdesigner_settings.h"
+
+#include <newformwidget_p.h>
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+#include <QtCore/QDebug>
+#include <QtCore/QDir>
+#include <QtCore/QTemporaryFile>
+
+#include <QtGui/QApplication>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QPushButton>
+#include <QtGui/QDialogButtonBox>
+#include <QtGui/QMenu>
+#include <QtGui/QCheckBox>
+#include <QtGui/QFrame>
+#include <QtGui/QMessageBox>
+
+QT_BEGIN_NAMESPACE
+
+NewForm::NewForm(QDesignerWorkbench *workbench, QWidget *parentWidget, const QString &fileName)
+ : QDialog(parentWidget,
+#ifdef Q_WS_MAC
+ Qt::Tool |
+#endif
+ Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
+ m_fileName(fileName),
+ m_newFormWidget(QDesignerNewFormWidgetInterface::createNewFormWidget(workbench->core())),
+ m_workbench(workbench),
+ m_chkShowOnStartup(new QCheckBox(tr("Show this Dialog on Startup"))),
+ m_createButton(new QPushButton(QApplication::translate("NewForm", "C&reate", 0, QApplication::UnicodeUTF8))),
+ m_recentButton(new QPushButton(QApplication::translate("NewForm", "Recent", 0, QApplication::UnicodeUTF8))),
+ m_buttonBox(0)
+{
+ setWindowTitle(tr("New Form"));
+ QDesignerSettings settings(m_workbench->core());
+
+ QVBoxLayout *vBoxLayout = new QVBoxLayout;
+
+ connect(m_newFormWidget, SIGNAL(templateActivated()), this, SLOT(slotTemplateActivated()));
+ connect(m_newFormWidget, SIGNAL(currentTemplateChanged(bool)), this, SLOT(slotCurrentTemplateChanged(bool)));
+ vBoxLayout->addWidget(m_newFormWidget);
+
+ QFrame *horizontalLine = new QFrame;
+ horizontalLine->setFrameShape(QFrame::HLine);
+ horizontalLine->setFrameShadow(QFrame::Sunken);
+ vBoxLayout->addWidget(horizontalLine);
+
+ m_chkShowOnStartup->setChecked(settings.showNewFormOnStartup());
+ vBoxLayout->addWidget(m_chkShowOnStartup);
+
+ m_buttonBox = createButtonBox();
+ vBoxLayout->addWidget(m_buttonBox);
+ setLayout(vBoxLayout);
+
+ resize(500, 400);
+ slotCurrentTemplateChanged(m_newFormWidget->hasCurrentTemplate());
+}
+
+QDialogButtonBox *NewForm::createButtonBox()
+{
+ // Dialog buttons with 'recent files'
+ QDialogButtonBox *buttonBox = new QDialogButtonBox;
+ buttonBox->addButton(QApplication::translate("NewForm", "&Close", 0,
+ QApplication::UnicodeUTF8), QDialogButtonBox::RejectRole);
+ buttonBox->addButton(m_createButton, QDialogButtonBox::AcceptRole);
+ buttonBox->addButton(QApplication::translate("NewForm", "&Open...", 0,
+ QApplication::UnicodeUTF8), QDialogButtonBox::ActionRole);
+ buttonBox->addButton(m_recentButton, QDialogButtonBox::ActionRole);
+ QDesignerActions *da = m_workbench->actionManager();
+ QMenu *recentFilesMenu = new QMenu(tr("&Recent Forms"), m_recentButton);
+ // Pop the "Recent Files" stuff in here.
+ const QList<QAction *> recentActions = da->recentFilesActions()->actions();
+ if (!recentActions.empty()) {
+ const QList<QAction *>::const_iterator acend = recentActions.constEnd();
+ for (QList<QAction *>::const_iterator it = recentActions.constBegin(); it != acend; ++it) {
+ recentFilesMenu->addAction(*it);
+ connect(*it, SIGNAL(triggered()), this, SLOT(recentFileChosen()));
+ }
+ }
+ m_recentButton->setMenu(recentFilesMenu);
+ connect(buttonBox, SIGNAL(clicked(QAbstractButton*)), this, SLOT(slotButtonBoxClicked(QAbstractButton*)));
+ return buttonBox;
+}
+
+NewForm::~NewForm()
+{
+ QDesignerSettings settings (m_workbench->core());
+ settings.setShowNewFormOnStartup(m_chkShowOnStartup->isChecked());
+}
+
+void NewForm::recentFileChosen()
+{
+ QAction *action = qobject_cast<QAction *>(sender());
+ if (!action)
+ return;
+ if (action->objectName() == QLatin1String("__qt_action_clear_menu_"))
+ return;
+ close();
+}
+
+void NewForm::slotCurrentTemplateChanged(bool templateSelected)
+{
+ if (templateSelected) {
+ m_createButton->setEnabled(true);
+ m_createButton->setDefault(true);
+ } else {
+ m_createButton->setEnabled(false);
+ }
+}
+
+void NewForm::slotTemplateActivated()
+{
+ m_createButton->animateClick(0);
+}
+
+void NewForm::slotButtonBoxClicked(QAbstractButton *btn)
+{
+ switch (m_buttonBox->buttonRole(btn)) {
+ case QDialogButtonBox::RejectRole:
+ reject();
+ break;
+ case QDialogButtonBox::ActionRole:
+ if (btn != m_recentButton) {
+ m_fileName.clear();
+ if (m_workbench->actionManager()->openForm(this))
+ accept();
+ }
+ break;
+ case QDialogButtonBox::AcceptRole: {
+ QString errorMessage;
+ if (openTemplate(&errorMessage)) {
+ accept();
+ } else {
+ QMessageBox::warning(this, tr("Read error"), errorMessage);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+bool NewForm::openTemplate(QString *ptrToErrorMessage)
+{
+ const QString contents = m_newFormWidget->currentTemplate(ptrToErrorMessage);
+ if (contents.isEmpty())
+ return false;
+ // Write to temporary file and open
+ QString tempPattern = QDir::tempPath();
+ if (!tempPattern.endsWith(QDir::separator())) // platform-dependant
+ tempPattern += QDir::separator();
+ tempPattern += QLatin1String("XXXXXX.ui");
+ QTemporaryFile tempFormFile(tempPattern);
+
+ tempFormFile.setAutoRemove(true);
+ if (!tempFormFile.open()) {
+ *ptrToErrorMessage = tr("A temporary form file could not be created in %1.").arg(QDir::tempPath());
+ return false;
+ }
+ const QString tempFormFileName = tempFormFile.fileName();
+ tempFormFile.write(contents.toUtf8());
+ if (!tempFormFile.flush()) {
+ *ptrToErrorMessage = tr("The temporary form file %1 could not be written.").arg(tempFormFileName);
+ return false;
+ }
+ tempFormFile.close();
+ return m_workbench->openTemplate(tempFormFileName, m_fileName, ptrToErrorMessage);
+}
+
+QImage NewForm::grabForm(QDesignerFormEditorInterface *core,
+ QIODevice &file,
+ const QString &workingDir,
+ const qdesigner_internal::DeviceProfile &dp)
+{
+ return qdesigner_internal::NewFormWidget::grabForm(core, file, workingDir, dp);
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/designer/newform.h b/src/designer/src/designer/newform.h
new file mode 100644
index 000000000..ad51118b9
--- /dev/null
+++ b/src/designer/src/designer/newform.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef NEWFORM_H
+#define NEWFORM_H
+
+#include <QtGui/QDialog>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+ class DeviceProfile;
+}
+
+class QDesignerFormEditorInterface;
+class QDesignerNewFormWidgetInterface;
+class QDesignerWorkbench;
+
+class QCheckBox;
+class QAbstractButton;
+class QPushButton;
+class QDialogButtonBox;
+class QImage;
+class QIODevice;
+
+class NewForm: public QDialog
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(NewForm)
+
+public:
+ NewForm(QDesignerWorkbench *workbench,
+ QWidget *parentWidget,
+ // Use that file name instead of a temporary one
+ const QString &fileName = QString());
+
+ virtual ~NewForm();
+
+ // Convenience for implementing file dialogs with preview
+ static QImage grabForm(QDesignerFormEditorInterface *core,
+ QIODevice &file,
+ const QString &workingDir,
+ const qdesigner_internal::DeviceProfile &dp);
+
+private slots:
+ void slotButtonBoxClicked(QAbstractButton *btn);
+ void recentFileChosen();
+ void slotCurrentTemplateChanged(bool templateSelected);
+ void slotTemplateActivated();
+
+private:
+ QDialogButtonBox *createButtonBox();
+ bool openTemplate(QString *ptrToErrorMessage);
+
+ QString m_fileName;
+ QDesignerNewFormWidgetInterface *m_newFormWidget;
+ QDesignerWorkbench *m_workbench;
+ QCheckBox *m_chkShowOnStartup;
+ QPushButton *m_createButton;
+ QPushButton *m_recentButton;
+ QDialogButtonBox *m_buttonBox;
+};
+
+QT_END_NAMESPACE
+
+#endif // NEWFORM_H
diff --git a/src/designer/src/designer/preferencesdialog.cpp b/src/designer/src/designer/preferencesdialog.cpp
new file mode 100644
index 000000000..a27e366a5
--- /dev/null
+++ b/src/designer/src/designer/preferencesdialog.cpp
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "preferencesdialog.h"
+#include "ui_preferencesdialog.h"
+#include "qdesigner_appearanceoptions.h"
+
+#include <QtDesigner/private/abstractoptionspage_p.h>
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtGui/QFileDialog>
+#include <QtGui/QPushButton>
+
+QT_BEGIN_NAMESPACE
+
+PreferencesDialog::PreferencesDialog(QDesignerFormEditorInterface *core, QWidget *parentWidget) :
+ QDialog(parentWidget),
+ m_ui(new Ui::PreferencesDialog()),
+ m_core(core)
+{
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+ m_ui->setupUi(this);
+
+ m_optionsPages = core->optionsPages();
+
+ m_ui->m_optionTabWidget->clear();
+ foreach (QDesignerOptionsPageInterface *optionsPage, m_optionsPages) {
+ QWidget *page = optionsPage->createPage(this);
+ m_ui->m_optionTabWidget->addTab(page, optionsPage->name());
+ if (QDesignerAppearanceOptionsWidget *appearanceWidget = qobject_cast<QDesignerAppearanceOptionsWidget *>(page))
+ connect(appearanceWidget, SIGNAL(uiModeChanged(bool)), this, SLOT(slotUiModeChanged(bool)));
+ }
+
+ connect(m_ui->m_dialogButtonBox, SIGNAL(rejected()), this, SLOT(slotRejected()));
+ connect(m_ui->m_dialogButtonBox, SIGNAL(accepted()), this, SLOT(slotAccepted()));
+ connect(applyButton(), SIGNAL(clicked()), this, SLOT(slotApply()));
+}
+
+PreferencesDialog::~PreferencesDialog()
+{
+ delete m_ui;
+}
+
+QPushButton *PreferencesDialog::applyButton() const
+{
+ return m_ui->m_dialogButtonBox->button(QDialogButtonBox::Apply);
+}
+
+void PreferencesDialog::slotApply()
+{
+ foreach (QDesignerOptionsPageInterface *optionsPage, m_optionsPages)
+ optionsPage->apply();
+}
+
+void PreferencesDialog::slotAccepted()
+{
+ slotApply();
+ closeOptionPages();
+ accept();
+}
+
+void PreferencesDialog::slotRejected()
+{
+ closeOptionPages();
+ reject();
+}
+
+void PreferencesDialog::slotUiModeChanged(bool modified)
+{
+ // Cannot "apply" a ui mode change (destroy the dialogs parent)
+ applyButton()->setEnabled(!modified);
+}
+
+void PreferencesDialog::closeOptionPages()
+{
+ foreach (QDesignerOptionsPageInterface *optionsPage, m_optionsPages)
+ optionsPage->finish();
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/designer/preferencesdialog.h b/src/designer/src/designer/preferencesdialog.h
new file mode 100644
index 000000000..5ffd7d365
--- /dev/null
+++ b/src/designer/src/designer/preferencesdialog.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PREFERENCESDIALOG_H
+#define PREFERENCESDIALOG_H
+
+#include <QtGui/QDialog>
+
+QT_BEGIN_NAMESPACE
+
+class QPushButton;
+class QDesignerFormEditorInterface;
+class QDesignerOptionsPageInterface;
+
+namespace Ui {
+ class PreferencesDialog;
+}
+
+class PreferencesDialog: public QDialog
+{
+ Q_OBJECT
+public:
+ explicit PreferencesDialog(QDesignerFormEditorInterface *core, QWidget *parentWidget = 0);
+ ~PreferencesDialog();
+
+
+private slots:
+ void slotAccepted();
+ void slotRejected();
+ void slotApply();
+ void slotUiModeChanged(bool modified);
+
+private:
+ QPushButton *applyButton() const;
+ void closeOptionPages();
+
+ Ui::PreferencesDialog *m_ui;
+ QDesignerFormEditorInterface *m_core;
+ QList<QDesignerOptionsPageInterface*> m_optionsPages;
+};
+
+QT_END_NAMESPACE
+
+#endif // PREFERENCESDIALOG_H
diff --git a/src/designer/src/designer/preferencesdialog.ui b/src/designer/src/designer/preferencesdialog.ui
new file mode 100644
index 000000000..28d14bb83
--- /dev/null
+++ b/src/designer/src/designer/preferencesdialog.ui
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>PreferencesDialog</class>
+ <widget class="QDialog" name="PreferencesDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>474</width>
+ <height>304</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Preferences</string>
+ </property>
+ <property name="modal">
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTabWidget" name="m_optionTabWidget">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="tab_2">
+ <attribute name="title">
+ <string notr="true">Tab 1</string>
+ </attribute>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="m_dialogButtonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Apply|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>m_dialogButtonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>PreferencesDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>m_dialogButtonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>PreferencesDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/designer/src/designer/qdesigner.cpp b/src/designer/src/designer/qdesigner.cpp
new file mode 100644
index 000000000..1e838c197
--- /dev/null
+++ b/src/designer/src/designer/qdesigner.cpp
@@ -0,0 +1,320 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// designer
+#include "qdesigner.h"
+#include "qdesigner_actions.h"
+#include "qdesigner_server.h"
+#include "qdesigner_settings.h"
+#include "qdesigner_workbench.h"
+#include "mainwindow.h"
+
+#include <qdesigner_propertysheet_p.h>
+
+#include <QtGui/QFileOpenEvent>
+#include <QtGui/QCloseEvent>
+#include <QtGui/QMessageBox>
+#include <QtGui/QIcon>
+#include <QtGui/QErrorMessage>
+#include <QtCore/QMetaObject>
+#include <QtCore/QFile>
+#include <QtCore/QLibraryInfo>
+#include <QtCore/QLocale>
+#include <QtCore/QTimer>
+#include <QtCore/QTranslator>
+#include <QtCore/QFileInfo>
+#include <QtCore/qdebug.h>
+
+#include <QtDesigner/QDesignerComponents>
+
+QT_BEGIN_NAMESPACE
+
+static const char *designerApplicationName = "Designer";
+static const char *designerWarningPrefix = "Designer: ";
+
+static void designerMessageHandler(QtMsgType type, const char *msg)
+{
+ // Only Designer warnings are displayed as box
+ QDesigner *designerApp = qDesigner;
+ if (type != QtWarningMsg || !designerApp || qstrncmp(designerWarningPrefix, msg, qstrlen(designerWarningPrefix))) {
+ qInstallMsgHandler(0);
+ qt_message_output(type, msg);
+ qInstallMsgHandler (designerMessageHandler);
+ return;
+ }
+ designerApp->showErrorMessage(msg);
+}
+
+QDesigner::QDesigner(int &argc, char **argv)
+ : QApplication(argc, argv),
+ m_server(0),
+ m_client(0),
+ m_workbench(0), m_suppressNewFormShow(false)
+{
+ setOrganizationName(QLatin1String("Trolltech"));
+ setApplicationName(QLatin1String(designerApplicationName));
+ QDesignerComponents::initializeResources();
+
+#ifndef Q_WS_MAC
+ setWindowIcon(QIcon(QLatin1String(":/trolltech/designer/images/designer.png")));
+#endif
+ initialize();
+}
+
+QDesigner::~QDesigner()
+{
+ if (m_workbench)
+ delete m_workbench;
+ if (m_server)
+ delete m_server;
+ if (m_client)
+ delete m_client;
+}
+
+void QDesigner::showErrorMessage(const char *message)
+{
+ // strip the prefix
+ const QString qMessage = QString::fromUtf8(message + qstrlen(designerWarningPrefix));
+ // If there is no main window yet, just store the message.
+ // The QErrorMessage would otherwise be hidden by the main window.
+ if (m_mainWindow) {
+ showErrorMessageBox(qMessage);
+ } else {
+ qInstallMsgHandler(0);
+ qt_message_output(QtWarningMsg, message); // just in case we crash
+ qInstallMsgHandler (designerMessageHandler);
+ m_initializationErrors += qMessage;
+ m_initializationErrors += QLatin1Char('\n');
+ }
+}
+
+void QDesigner::showErrorMessageBox(const QString &msg)
+{
+ // Manually suppress consecutive messages.
+ // This happens if for example sth is wrong with custom widget creation.
+ // The same warning will be displayed by Widget box D&D and form Drop
+ // while trying to create instance.
+ if (m_errorMessageDialog && m_lastErrorMessage == msg)
+ return;
+
+ if (!m_errorMessageDialog) {
+ m_lastErrorMessage.clear();
+ m_errorMessageDialog = new QErrorMessage(m_mainWindow);
+ const QString title = QCoreApplication::translate("QDesigner", "%1 - warning").arg(QLatin1String(designerApplicationName));
+ m_errorMessageDialog->setWindowTitle(title);
+ m_errorMessageDialog->setMinimumSize(QSize(600, 250));
+ m_errorMessageDialog->setWindowFlags(m_errorMessageDialog->windowFlags() & ~Qt::WindowContextHelpButtonHint);
+ }
+ m_errorMessageDialog->showMessage(msg);
+ m_lastErrorMessage = msg;
+}
+
+QDesignerWorkbench *QDesigner::workbench() const
+{
+ return m_workbench;
+}
+
+QDesignerServer *QDesigner::server() const
+{
+ return m_server;
+}
+
+bool QDesigner::parseCommandLineArgs(QStringList &fileNames, QString &resourceDir)
+{
+ const QStringList args = arguments();
+ const QStringList::const_iterator acend = args.constEnd();
+ QStringList::const_iterator it = args.constBegin();
+ for (++it; it != acend; ++it) {
+ const QString &argument = *it;
+ do {
+ // Arguments
+ if (!argument.startsWith(QLatin1Char('-'))) {
+ if (!fileNames.contains(argument))
+ fileNames.append(argument);
+ break;
+ }
+ // Options
+ if (argument == QLatin1String("-server")) {
+ m_server = new QDesignerServer();
+ printf("%d\n", m_server->serverPort());
+ fflush(stdout);
+ break;
+ }
+ if (argument == QLatin1String("-client")) {
+ bool ok = true;
+ if (++it == acend) {
+ qWarning("** WARNING The option -client requires an argument");
+ return false;
+ }
+ const quint16 port = it->toUShort(&ok);
+ if (ok) {
+ m_client = new QDesignerClient(port, this);
+ } else {
+ qWarning("** WARNING Non-numeric argument specified for -client");
+ return false;
+ }
+ break;
+ }
+ if (argument == QLatin1String("-resourcedir")) {
+ if (++it == acend) {
+ qWarning("** WARNING The option -resourcedir requires an argument");
+ return false;
+ }
+ resourceDir = QFile::decodeName(it->toLocal8Bit());
+ break;
+ }
+ if (argument == QLatin1String("-enableinternaldynamicproperties")) {
+ QDesignerPropertySheet::setInternalDynamicPropertiesEnabled(true);
+ break;
+ }
+ const QString msg = QString::fromUtf8("** WARNING Unknown option %1").arg(argument);
+ qWarning("%s", qPrintable(msg));
+ } while (false);
+ }
+ return true;
+}
+
+void QDesigner::initialize()
+{
+ // initialize the sub components
+ QStringList files;
+ QString resourceDir = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
+ parseCommandLineArgs(files, resourceDir);
+
+ QTranslator *translator = new QTranslator(this);
+ QTranslator *qtTranslator = new QTranslator(this);
+
+ const QString localSysName = QLocale::system().name();
+ QString translatorFileName = QLatin1String("designer_");
+ translatorFileName += localSysName;
+ translator->load(translatorFileName, resourceDir);
+
+ translatorFileName = QLatin1String("qt_");
+ translatorFileName += localSysName;
+ qtTranslator->load(translatorFileName, resourceDir);
+ installTranslator(translator);
+ installTranslator(qtTranslator);
+
+ if (QLibraryInfo::licensedProducts() == QLatin1String("Console")) {
+ QMessageBox::information(0, tr("Qt Designer"),
+ tr("This application cannot be used for the Console edition of Qt"));
+ QMetaObject::invokeMethod(this, "quit", Qt::QueuedConnection);
+ return;
+ }
+
+ m_workbench = new QDesignerWorkbench();
+
+ emit initialized();
+ qInstallMsgHandler(designerMessageHandler); // Warn when loading faulty forms
+
+ m_suppressNewFormShow = m_workbench->readInBackup();
+
+ if (!files.empty()) {
+ const QStringList::const_iterator cend = files.constEnd();
+ for (QStringList::const_iterator it = files.constBegin(); it != cend; ++it) {
+ // Ensure absolute paths for recent file list to be unique
+ QString fileName = *it;
+ const QFileInfo fi(fileName);
+ if (fi.exists() && fi.isRelative())
+ fileName = fi.absoluteFilePath();
+ m_workbench->readInForm(fileName);
+ }
+ }
+ if ( m_workbench->formWindowCount())
+ m_suppressNewFormShow = true;
+
+ // Show up error box with parent now if something went wrong
+ if (m_initializationErrors.isEmpty()) {
+ if (!m_suppressNewFormShow && QDesignerSettings(m_workbench->core()).showNewFormOnStartup())
+ QTimer::singleShot(100, this, SLOT(callCreateForm())); // won't show anything if suppressed
+ } else {
+ showErrorMessageBox(m_initializationErrors);
+ m_initializationErrors.clear();
+ }
+}
+
+bool QDesigner::event(QEvent *ev)
+{
+ bool eaten;
+ switch (ev->type()) {
+ case QEvent::FileOpen:
+ // Set it true first since, if it's a Qt 3 form, the messagebox from convert will fire the timer.
+ m_suppressNewFormShow = true;
+ if (!m_workbench->readInForm(static_cast<QFileOpenEvent *>(ev)->file()))
+ m_suppressNewFormShow = false;
+ eaten = true;
+ break;
+ case QEvent::Close: {
+ QCloseEvent *closeEvent = static_cast<QCloseEvent *>(ev);
+ closeEvent->setAccepted(m_workbench->handleClose());
+ if (closeEvent->isAccepted()) {
+ // We're going down, make sure that we don't get our settings saved twice.
+ if (m_mainWindow)
+ m_mainWindow->setCloseEventPolicy(MainWindowBase::AcceptCloseEvents);
+ eaten = QApplication::event(ev);
+ }
+ eaten = true;
+ break;
+ }
+ default:
+ eaten = QApplication::event(ev);
+ break;
+ }
+ return eaten;
+}
+
+void QDesigner::setMainWindow(MainWindowBase *tw)
+{
+ m_mainWindow = tw;
+}
+
+MainWindowBase *QDesigner::mainWindow() const
+{
+ return m_mainWindow;
+}
+
+void QDesigner::callCreateForm()
+{
+ if (!m_suppressNewFormShow)
+ m_workbench->actionManager()->createForm();
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/designer/qdesigner.h b/src/designer/src/designer/qdesigner.h
new file mode 100644
index 000000000..ff45edffd
--- /dev/null
+++ b/src/designer/src/designer/qdesigner.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDESIGNER_H
+#define QDESIGNER_H
+
+#include <QtCore/QPointer>
+#include <QtGui/QApplication>
+
+QT_BEGIN_NAMESPACE
+
+#define qDesigner \
+ (static_cast<QDesigner*>(QCoreApplication::instance()))
+
+class QDesignerWorkbench;
+class QDesignerToolWindow;
+class MainWindowBase;
+class QDesignerServer;
+class QDesignerClient;
+class QErrorMessage;
+
+class QDesigner: public QApplication
+{
+ Q_OBJECT
+public:
+ QDesigner(int &argc, char **argv);
+ virtual ~QDesigner();
+
+ QDesignerWorkbench *workbench() const;
+ QDesignerServer *server() const;
+ MainWindowBase *mainWindow() const;
+ void setMainWindow(MainWindowBase *tw);
+
+protected:
+ bool event(QEvent *ev);
+
+signals:
+ void initialized();
+
+public slots:
+ void showErrorMessage(const char *message);
+
+private slots:
+ void initialize();
+ void callCreateForm();
+
+private:
+ bool parseCommandLineArgs(QStringList &fileNames, QString &resourceDir);
+ void showErrorMessageBox(const QString &);
+
+ QDesignerServer *m_server;
+ QDesignerClient *m_client;
+ QDesignerWorkbench *m_workbench;
+ QPointer<MainWindowBase> m_mainWindow;
+ QPointer<QErrorMessage> m_errorMessageDialog;
+
+ QString m_initializationErrors;
+ QString m_lastErrorMessage;
+ bool m_suppressNewFormShow;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_H
diff --git a/src/designer/src/designer/qdesigner_actions.cpp b/src/designer/src/designer/qdesigner_actions.cpp
new file mode 100644
index 000000000..a84e0732d
--- /dev/null
+++ b/src/designer/src/designer/qdesigner_actions.cpp
@@ -0,0 +1,1437 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_actions.h"
+#include "designer_enums.h"
+#include "qdesigner.h"
+#include "qdesigner_workbench.h"
+#include "qdesigner_formwindow.h"
+#include "newform.h"
+#include "versiondialog.h"
+#include "saveformastemplate.h"
+#include "qdesigner_toolwindow.h"
+#include "preferencesdialog.h"
+#include "appfontdialog.h"
+
+#include <pluginmanager_p.h>
+#include <qdesigner_formbuilder_p.h>
+#include <qdesigner_utils_p.h>
+#include <iconloader_p.h>
+#include <qsimpleresource_p.h>
+#include <previewmanager_p.h>
+#include <codedialog_p.h>
+#include <qdesigner_formwindowmanager_p.h>
+#include "qdesigner_integration_p.h"
+
+// sdk
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerLanguageExtension>
+#include <QtDesigner/QDesignerMetaDataBaseInterface>
+#include <QtDesigner/QDesignerFormWindowManagerInterface>
+#include <QtDesigner/QDesignerFormWindowCursorInterface>
+#include <QtDesigner/QDesignerFormEditorPluginInterface>
+#include <QtDesigner/QExtensionManager>
+
+#include <QtDesigner/private/shared_settings_p.h>
+#include <QtDesigner/private/formwindowbase_p.h>
+
+#include <QtGui/QAction>
+#include <QtGui/QActionGroup>
+#include <QtGui/QStyleFactory>
+#include <QtGui/QCloseEvent>
+#include <QtGui/QFileDialog>
+#include <QtGui/QMenu>
+#include <QtGui/QMessageBox>
+#include <QtGui/QPushButton>
+#include <QtGui/QIcon>
+#include <QtGui/QImage>
+#include <QtGui/QPixmap>
+#include <QtGui/QMdiSubWindow>
+#include <QtGui/QPrintDialog>
+#include <QtGui/QPainter>
+#include <QtGui/QTransform>
+#include <QtGui/QCursor>
+#include <QtCore/QSizeF>
+
+#include <QtCore/QLibraryInfo>
+#include <QtCore/QBuffer>
+#include <QtCore/QPluginLoader>
+#include <QtCore/qdebug.h>
+#include <QtCore/QTimer>
+#include <QtCore/QMetaObject>
+#include <QtCore/QFileInfo>
+#include <QtGui/QStatusBar>
+#include <QtGui/QDesktopWidget>
+#include <QtXml/QDomDocument>
+
+QT_BEGIN_NAMESPACE
+
+using namespace qdesigner_internal;
+
+const char *QDesignerActions::defaultToolbarPropertyName = "__qt_defaultToolBarAction";
+
+//#ifdef Q_WS_MAC
+# define NONMODAL_PREVIEW
+//#endif
+
+static QAction *createSeparator(QObject *parent) {
+ QAction * rc = new QAction(parent);
+ rc->setSeparator(true);
+ return rc;
+}
+
+static QActionGroup *createActionGroup(QObject *parent, bool exclusive = false) {
+ QActionGroup * rc = new QActionGroup(parent);
+ rc->setExclusive(exclusive);
+ return rc;
+}
+
+static inline QString savedMessage(const QString &fileName)
+{
+ return QDesignerActions::tr("Saved %1.").arg(fileName);
+}
+
+// Prompt for a file and make sure an extension is added
+// unless the user explicitly specifies another one.
+
+static QString getSaveFileNameWithExtension(QWidget *parent, const QString &title, QString dir, const QString &filter, const QString &extension)
+{
+ const QChar dot = QLatin1Char('.');
+
+ QString saveFile;
+ while (true) {
+ saveFile = QFileDialog::getSaveFileName(parent, title, dir, filter, 0, QFileDialog::DontConfirmOverwrite);
+ if (saveFile.isEmpty())
+ return saveFile;
+
+ const QFileInfo fInfo(saveFile);
+ if (fInfo.suffix().isEmpty() && !fInfo.fileName().endsWith(dot)) {
+ saveFile += dot;
+ saveFile += extension;
+ }
+
+ const QFileInfo fi(saveFile);
+ if (!fi.exists())
+ break;
+
+ const QString prompt = QDesignerActions::tr("%1 already exists.\nDo you want to replace it?").arg(fi.fileName());
+ if (QMessageBox::warning(parent, title, prompt, QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)
+ break;
+
+ dir = saveFile;
+ }
+ return saveFile;
+}
+
+QDesignerActions::QDesignerActions(QDesignerWorkbench *workbench)
+ : QObject(workbench),
+ m_workbench(workbench),
+ m_core(workbench->core()),
+ m_settings(workbench->core()),
+ m_backupTimer(new QTimer(this)),
+ m_fileActions(createActionGroup(this)),
+ m_recentFilesActions(createActionGroup(this)),
+ m_editActions(createActionGroup(this)),
+ m_formActions(createActionGroup(this)),
+ m_settingsActions(createActionGroup(this)),
+ m_windowActions(createActionGroup(this)),
+ m_toolActions(createActionGroup(this, true)),
+ m_helpActions(0),
+ m_styleActions(0),
+ m_editWidgetsAction(new QAction(tr("Edit Widgets"), this)),
+ m_newFormAction(new QAction(qdesigner_internal::createIconSet(QLatin1String("filenew.png")), tr("&New..."), this)),
+ m_openFormAction(new QAction(qdesigner_internal::createIconSet(QLatin1String("fileopen.png")), tr("&Open..."), this)),
+ m_saveFormAction(new QAction(qdesigner_internal::createIconSet(QLatin1String("filesave.png")), tr("&Save"), this)),
+ m_saveFormAsAction(new QAction(tr("Save &As..."), this)),
+ m_saveAllFormsAction(new QAction(tr("Save A&ll"), this)),
+ m_saveFormAsTemplateAction(new QAction(tr("Save As &Template..."), this)),
+ m_closeFormAction(new QAction(tr("&Close"), this)),
+ m_savePreviewImageAction(new QAction(tr("Save &Image..."), this)),
+ m_printPreviewAction(new QAction(tr("&Print..."), this)),
+ m_quitAction(new QAction(tr("&Quit"), this)),
+ m_previewFormAction(0),
+ m_viewCodeAction(new QAction(tr("View &Code..."), this)),
+ m_minimizeAction(new QAction(tr("&Minimize"), this)),
+ m_bringAllToFrontSeparator(createSeparator(this)),
+ m_bringAllToFrontAction(new QAction(tr("Bring All to Front"), this)),
+ m_windowListSeparatorAction(createSeparator(this)),
+ m_preferencesAction(new QAction(tr("Preferences..."), this)),
+ m_appFontAction(new QAction(tr("Additional Fonts..."), this)),
+ m_appFontDialog(0),
+#ifndef QT_NO_PRINTER
+ m_printer(0),
+#endif
+ m_previewManager(0)
+{
+#ifdef Q_WS_X11
+ m_newFormAction->setIcon(QIcon::fromTheme("document-new", m_newFormAction->icon()));
+ m_openFormAction->setIcon(QIcon::fromTheme("document-open", m_openFormAction->icon()));
+ m_saveFormAction->setIcon(QIcon::fromTheme("document-save", m_saveFormAction->icon()));
+ m_saveFormAsAction->setIcon(QIcon::fromTheme("document-save-as", m_saveFormAsAction->icon()));
+ m_printPreviewAction->setIcon(QIcon::fromTheme("document-print", m_printPreviewAction->icon()));
+ m_closeFormAction->setIcon(QIcon::fromTheme("window-close", m_closeFormAction->icon()));
+ m_quitAction->setIcon(QIcon::fromTheme("application-exit", m_quitAction->icon()));
+#endif
+
+ Q_ASSERT(m_core != 0);
+ qdesigner_internal::QDesignerFormWindowManager *ifwm = qobject_cast<qdesigner_internal::QDesignerFormWindowManager *>(m_core->formWindowManager());
+ Q_ASSERT(ifwm);
+ m_previewManager = ifwm->previewManager();
+ m_previewFormAction = ifwm->actionDefaultPreview();
+ m_styleActions = ifwm->actionGroupPreviewInStyle();
+ connect(ifwm, SIGNAL(formWindowSettingsChanged(QDesignerFormWindowInterface*)),
+ this, SLOT(formWindowSettingsChanged(QDesignerFormWindowInterface*)));
+
+ m_editWidgetsAction->setObjectName(QLatin1String("__qt_edit_widgets_action"));
+ m_newFormAction->setObjectName(QLatin1String("__qt_new_form_action"));
+ m_openFormAction->setObjectName(QLatin1String("__qt_open_form_action"));
+ m_saveFormAction->setObjectName(QLatin1String("__qt_save_form_action"));
+ m_saveFormAsAction->setObjectName(QLatin1String("__qt_save_form_as_action"));
+ m_saveAllFormsAction->setObjectName(QLatin1String("__qt_save_all_forms_action"));
+ m_saveFormAsTemplateAction->setObjectName(QLatin1String("__qt_save_form_as_template_action"));
+ m_closeFormAction->setObjectName(QLatin1String("__qt_close_form_action"));
+ m_quitAction->setObjectName(QLatin1String("__qt_quit_action"));
+ m_previewFormAction->setObjectName(QLatin1String("__qt_preview_form_action"));
+ m_viewCodeAction->setObjectName(QLatin1String("__qt_preview_code_action"));
+ m_minimizeAction->setObjectName(QLatin1String("__qt_minimize_action"));
+ m_bringAllToFrontAction->setObjectName(QLatin1String("__qt_bring_all_to_front_action"));
+ m_preferencesAction->setObjectName(QLatin1String("__qt_preferences_action"));
+
+ m_helpActions = createHelpActions();
+
+ m_newFormAction->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+ m_openFormAction->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+ m_saveFormAction->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+
+ QDesignerFormWindowManagerInterface *formWindowManager = m_core->formWindowManager();
+ Q_ASSERT(formWindowManager != 0);
+
+//
+// file actions
+//
+ m_newFormAction->setShortcut(QKeySequence::New);
+ connect(m_newFormAction, SIGNAL(triggered()), this, SLOT(createForm()));
+ m_fileActions->addAction(m_newFormAction);
+
+ m_openFormAction->setShortcut(QKeySequence::Open);
+ connect(m_openFormAction, SIGNAL(triggered()), this, SLOT(slotOpenForm()));
+ m_fileActions->addAction(m_openFormAction);
+
+ m_fileActions->addAction(createRecentFilesMenu());
+ m_fileActions->addAction(createSeparator(this));
+
+ m_saveFormAction->setShortcut(QKeySequence::Save);
+ connect(m_saveFormAction, SIGNAL(triggered()), this, SLOT(saveForm()));
+ m_fileActions->addAction(m_saveFormAction);
+
+ connect(m_saveFormAsAction, SIGNAL(triggered()), this, SLOT(saveFormAs()));
+ m_fileActions->addAction(m_saveFormAsAction);
+
+#ifdef Q_OS_MAC
+ m_saveAllFormsAction->setShortcut(tr("ALT+CTRL+S"));
+#else
+ m_saveAllFormsAction->setShortcut(tr("CTRL+SHIFT+S")); // Commonly "Save As" on Mac
+#endif
+ connect(m_saveAllFormsAction, SIGNAL(triggered()), this, SLOT(saveAllForms()));
+ m_fileActions->addAction(m_saveAllFormsAction);
+
+ connect(m_saveFormAsTemplateAction, SIGNAL(triggered()), this, SLOT(saveFormAsTemplate()));
+ m_fileActions->addAction(m_saveFormAsTemplateAction);
+
+ m_fileActions->addAction(createSeparator(this));
+
+ m_printPreviewAction->setShortcut(QKeySequence::Print);
+ connect(m_printPreviewAction, SIGNAL(triggered()), this, SLOT(printPreviewImage()));
+ m_fileActions->addAction(m_printPreviewAction);
+ m_printPreviewAction->setObjectName(QLatin1String("__qt_print_action"));
+
+ connect(m_savePreviewImageAction, SIGNAL(triggered()), this, SLOT(savePreviewImage()));
+ m_savePreviewImageAction->setObjectName(QLatin1String("__qt_saveimage_action"));
+ m_fileActions->addAction(m_savePreviewImageAction);
+ m_fileActions->addAction(createSeparator(this));
+
+ m_closeFormAction->setShortcut(QKeySequence::Close);
+ connect(m_closeFormAction, SIGNAL(triggered()), this, SLOT(closeForm()));
+ m_fileActions->addAction(m_closeFormAction);
+ updateCloseAction();
+
+ m_fileActions->addAction(createSeparator(this));
+
+ m_quitAction->setShortcuts(QKeySequence::Quit);
+ m_quitAction->setMenuRole(QAction::QuitRole);
+ connect(m_quitAction, SIGNAL(triggered()), this, SLOT(shutdown()));
+ m_fileActions->addAction(m_quitAction);
+
+//
+// edit actions
+//
+ QAction *undoAction = formWindowManager->actionUndo();
+ undoAction->setObjectName(QLatin1String("__qt_undo_action"));
+ undoAction->setShortcut(QKeySequence::Undo);
+ m_editActions->addAction(undoAction);
+
+ QAction *redoAction = formWindowManager->actionRedo();
+ redoAction->setObjectName(QLatin1String("__qt_redo_action"));
+ redoAction->setShortcut(QKeySequence::Redo);
+ m_editActions->addAction(redoAction);
+
+ m_editActions->addAction(createSeparator(this));
+
+ m_editActions->addAction(formWindowManager->actionCut());
+ m_editActions->addAction(formWindowManager->actionCopy());
+ m_editActions->addAction(formWindowManager->actionPaste());
+ m_editActions->addAction(formWindowManager->actionDelete());
+
+ m_editActions->addAction(formWindowManager->actionSelectAll());
+
+ m_editActions->addAction(createSeparator(this));
+
+ m_editActions->addAction(formWindowManager->actionLower());
+ m_editActions->addAction(formWindowManager->actionRaise());
+
+ formWindowManager->actionLower()->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+ formWindowManager->actionRaise()->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+
+//
+// edit mode actions
+//
+
+ m_editWidgetsAction->setCheckable(true);
+ QList<QKeySequence> shortcuts;
+ shortcuts.append(QKeySequence(Qt::Key_F3));
+#if QT_VERSION >= 0x040900 // "ESC" switching to edit mode: Activate once item delegates handle shortcut overrides for ESC.
+ shortcuts.append(QKeySequence(Qt::Key_Escape));
+#endif
+ m_editWidgetsAction->setShortcuts(shortcuts);
+ QIcon fallback(m_core->resourceLocation() + QLatin1String("/widgettool.png"));
+ m_editWidgetsAction->setIcon(QIcon::fromTheme("designer-edit-widget", fallback));
+ connect(m_editWidgetsAction, SIGNAL(triggered()), this, SLOT(editWidgetsSlot()));
+ m_editWidgetsAction->setChecked(true);
+ m_editWidgetsAction->setEnabled(false);
+ m_editWidgetsAction->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+ m_toolActions->addAction(m_editWidgetsAction);
+
+ connect(formWindowManager, SIGNAL(activeFormWindowChanged(QDesignerFormWindowInterface*)),
+ this, SLOT(activeFormWindowChanged(QDesignerFormWindowInterface*)));
+
+ QList<QObject*> builtinPlugins = QPluginLoader::staticInstances();
+ builtinPlugins += m_core->pluginManager()->instances();
+ foreach (QObject *plugin, builtinPlugins) {
+ if (QDesignerFormEditorPluginInterface *formEditorPlugin = qobject_cast<QDesignerFormEditorPluginInterface*>(plugin)) {
+ if (QAction *action = formEditorPlugin->action()) {
+ m_toolActions->addAction(action);
+ action->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+ action->setCheckable(true);
+ }
+ }
+ }
+
+ connect(m_preferencesAction, SIGNAL(triggered()), this, SLOT(showPreferencesDialog()));
+ m_preferencesAction->setMenuRole(QAction::PreferencesRole);
+ m_settingsActions->addAction(m_preferencesAction);
+
+ connect(m_appFontAction, SIGNAL(triggered()), this, SLOT(showAppFontDialog()));
+ m_appFontAction->setMenuRole(QAction::PreferencesRole);
+ m_settingsActions->addAction(m_appFontAction);
+//
+// form actions
+//
+
+ m_formActions->addAction(formWindowManager->actionHorizontalLayout());
+ m_formActions->addAction(formWindowManager->actionVerticalLayout());
+ m_formActions->addAction(formWindowManager->actionSplitHorizontal());
+ m_formActions->addAction(formWindowManager->actionSplitVertical());
+ m_formActions->addAction(formWindowManager->actionGridLayout());
+ m_formActions->addAction(formWindowManager->actionFormLayout());
+ m_formActions->addAction(formWindowManager->actionBreakLayout());
+ m_formActions->addAction(formWindowManager->actionAdjustSize());
+ m_formActions->addAction(formWindowManager->actionSimplifyLayout());
+ m_formActions->addAction(createSeparator(this));
+
+ formWindowManager->actionHorizontalLayout()->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+ formWindowManager->actionVerticalLayout()->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+ formWindowManager->actionSplitHorizontal()->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+ formWindowManager->actionSplitVertical()->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+ formWindowManager->actionGridLayout()->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+ formWindowManager->actionFormLayout()->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+ formWindowManager->actionBreakLayout()->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+ formWindowManager->actionAdjustSize()->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+
+ m_previewFormAction->setShortcut(tr("CTRL+R"));
+ m_formActions->addAction(m_previewFormAction);
+ connect(m_previewManager, SIGNAL(firstPreviewOpened()), this, SLOT(updateCloseAction()));
+ connect(m_previewManager, SIGNAL(lastPreviewClosed()), this, SLOT(updateCloseAction()));
+
+ connect(m_viewCodeAction, SIGNAL(triggered()), this, SLOT(viewCode()));
+ // Preview code only in Cpp
+ if (qt_extension<QDesignerLanguageExtension *>(m_core->extensionManager(), m_core) == 0)
+ m_formActions->addAction(m_viewCodeAction);
+
+ m_formActions->addAction(createSeparator(this));
+
+ m_formActions->addAction(ifwm->actionShowFormWindowSettingsDialog());
+//
+// window actions
+//
+ m_minimizeAction->setEnabled(false);
+ m_minimizeAction->setCheckable(true);
+ m_minimizeAction->setShortcut(tr("CTRL+M"));
+ connect(m_minimizeAction, SIGNAL(triggered()), m_workbench, SLOT(toggleFormMinimizationState()));
+ m_windowActions->addAction(m_minimizeAction);
+
+ m_windowActions->addAction(m_bringAllToFrontSeparator);
+ connect(m_bringAllToFrontAction, SIGNAL(triggered()), m_workbench, SLOT(bringAllToFront()));
+ m_windowActions->addAction(m_bringAllToFrontAction);
+ m_windowActions->addAction(m_windowListSeparatorAction);
+
+ setWindowListSeparatorVisible(false);
+
+//
+// connections
+//
+ fixActionContext();
+ activeFormWindowChanged(core()->formWindowManager()->activeFormWindow());
+
+ m_backupTimer->start(180000); // 3min
+ connect(m_backupTimer, SIGNAL(timeout()), this, SLOT(backupForms()));
+
+ // Enable application font action
+ connect(formWindowManager, SIGNAL(formWindowAdded(QDesignerFormWindowInterface*)), this, SLOT(formWindowCountChanged()));
+ connect(formWindowManager, SIGNAL(formWindowRemoved(QDesignerFormWindowInterface*)), this, SLOT(formWindowCountChanged()));
+ formWindowCountChanged();
+}
+
+QActionGroup *QDesignerActions::createHelpActions()
+{
+ QActionGroup *helpActions = createActionGroup(this);
+
+#ifndef QT_JAMBI_BUILD
+ QAction *mainHelpAction = new QAction(tr("Qt Designer &Help"), this);
+ mainHelpAction->setObjectName(QLatin1String("__qt_designer_help_action"));
+ connect(mainHelpAction, SIGNAL(triggered()), this, SLOT(showDesignerHelp()));
+ mainHelpAction->setShortcut(Qt::CTRL + Qt::Key_Question);
+ helpActions->addAction(mainHelpAction);
+
+ helpActions->addAction(createSeparator(this));
+ QAction *widgetHelp = new QAction(tr("Current Widget Help"), this);
+ widgetHelp->setObjectName(QLatin1String("__qt_current_widget_help_action"));
+ widgetHelp->setShortcut(Qt::Key_F1);
+ connect(widgetHelp, SIGNAL(triggered()), this, SLOT(showWidgetSpecificHelp()));
+ helpActions->addAction(widgetHelp);
+
+ helpActions->addAction(createSeparator(this));
+ QAction *whatsNewAction = new QAction(tr("What's New in Qt Designer?"), this);
+ whatsNewAction->setObjectName(QLatin1String("__qt_whats_new_in_qt_designer_action"));
+ connect(whatsNewAction, SIGNAL(triggered()), this, SLOT(showWhatsNew()));
+ helpActions->addAction(whatsNewAction);
+#endif
+
+ helpActions->addAction(createSeparator(this));
+ QAction *aboutPluginsAction = new QAction(tr("About Plugins"), this);
+ aboutPluginsAction->setObjectName(QLatin1String("__qt_about_plugins_action"));
+ aboutPluginsAction->setMenuRole(QAction::ApplicationSpecificRole);
+ connect(aboutPluginsAction, SIGNAL(triggered()), m_core->formWindowManager(), SLOT(aboutPlugins()));
+ helpActions->addAction(aboutPluginsAction);
+
+ QAction *aboutDesignerAction = new QAction(tr("About Qt Designer"), this);
+ aboutDesignerAction->setMenuRole(QAction::AboutRole);
+ aboutDesignerAction->setObjectName(QLatin1String("__qt_about_designer_action"));
+ connect(aboutDesignerAction, SIGNAL(triggered()), this, SLOT(aboutDesigner()));
+ helpActions->addAction(aboutDesignerAction);
+
+ QAction *aboutQtAction = new QAction(tr("About Qt"), this);
+ aboutQtAction->setMenuRole(QAction::AboutQtRole);
+ aboutQtAction->setObjectName(QLatin1String("__qt_about_qt_action"));
+ connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
+ helpActions->addAction(aboutQtAction);
+ return helpActions;
+}
+
+QDesignerActions::~QDesignerActions()
+{
+#ifndef QT_NO_PRINTER
+ delete m_printer;
+#endif
+}
+
+QString QDesignerActions::uiExtension() const
+{
+ QDesignerLanguageExtension *lang
+ = qt_extension<QDesignerLanguageExtension *>(m_core->extensionManager(), m_core);
+ if (lang)
+ return lang->uiExtension();
+ return QLatin1String("ui");
+}
+
+QAction *QDesignerActions::createRecentFilesMenu()
+{
+ QMenu *menu = new QMenu;
+ QAction *act;
+ // Need to insert this into the QAction.
+ for (int i = 0; i < MaxRecentFiles; ++i) {
+ act = new QAction(this);
+ act->setVisible(false);
+ connect(act, SIGNAL(triggered()), this, SLOT(openRecentForm()));
+ m_recentFilesActions->addAction(act);
+ menu->addAction(act);
+ }
+ updateRecentFileActions();
+ menu->addSeparator();
+ act = new QAction(QIcon::fromTheme("edit-clear"), tr("Clear &Menu"), this);
+ act->setObjectName(QLatin1String("__qt_action_clear_menu_"));
+ connect(act, SIGNAL(triggered()), this, SLOT(clearRecentFiles()));
+ m_recentFilesActions->addAction(act);
+ menu->addAction(act);
+
+ act = new QAction(QIcon::fromTheme("document-open-recent"), tr("&Recent Forms"), this);
+ act->setMenu(menu);
+ return act;
+}
+
+QActionGroup *QDesignerActions::toolActions() const
+{ return m_toolActions; }
+
+QDesignerWorkbench *QDesignerActions::workbench() const
+{ return m_workbench; }
+
+QDesignerFormEditorInterface *QDesignerActions::core() const
+{ return m_core; }
+
+QActionGroup *QDesignerActions::fileActions() const
+{ return m_fileActions; }
+
+QActionGroup *QDesignerActions::editActions() const
+{ return m_editActions; }
+
+QActionGroup *QDesignerActions::formActions() const
+{ return m_formActions; }
+
+QActionGroup *QDesignerActions::settingsActions() const
+{ return m_settingsActions; }
+
+QActionGroup *QDesignerActions::windowActions() const
+{ return m_windowActions; }
+
+QActionGroup *QDesignerActions::helpActions() const
+{ return m_helpActions; }
+
+QActionGroup *QDesignerActions::styleActions() const
+{ return m_styleActions; }
+
+QAction *QDesignerActions::previewFormAction() const
+{ return m_previewFormAction; }
+
+QAction *QDesignerActions::viewCodeAction() const
+{ return m_viewCodeAction; }
+
+
+void QDesignerActions::editWidgetsSlot()
+{
+ QDesignerFormWindowManagerInterface *formWindowManager = core()->formWindowManager();
+ for (int i=0; i<formWindowManager->formWindowCount(); ++i) {
+ QDesignerFormWindowInterface *formWindow = formWindowManager->formWindow(i);
+ formWindow->editWidgets();
+ }
+}
+
+void QDesignerActions::createForm()
+{
+ showNewFormDialog(QString());
+}
+
+void QDesignerActions::showNewFormDialog(const QString &fileName)
+{
+ closePreview();
+ NewForm *dlg = new NewForm(workbench(), workbench()->core()->topLevel(), fileName);
+
+ dlg->setAttribute(Qt::WA_DeleteOnClose);
+ dlg->setAttribute(Qt::WA_ShowModal);
+
+ dlg->setGeometry(fixDialogRect(dlg->rect()));
+ dlg->exec();
+}
+
+void QDesignerActions::slotOpenForm()
+{
+ openForm(core()->topLevel());
+}
+
+bool QDesignerActions::openForm(QWidget *parent)
+{
+ closePreview();
+ const QString extension = uiExtension();
+ const QStringList fileNames = QFileDialog::getOpenFileNames(parent, tr("Open Form"),
+ m_openDirectory, tr("Designer UI files (*.%1);;All Files (*)").arg(extension), 0, QFileDialog::DontUseSheet);
+
+ if (fileNames.isEmpty())
+ return false;
+
+ bool atLeastOne = false;
+ foreach (const QString &fileName, fileNames) {
+ if (readInForm(fileName) && !atLeastOne)
+ atLeastOne = true;
+ }
+
+ return atLeastOne;
+}
+
+bool QDesignerActions::saveFormAs(QDesignerFormWindowInterface *fw)
+{
+ const QString extension = uiExtension();
+
+ QString dir = fw->fileName();
+ if (dir.isEmpty()) {
+ do {
+ // Build untitled name
+ if (!m_saveDirectory.isEmpty()) {
+ dir = m_saveDirectory;
+ break;
+ }
+ if (!m_openDirectory.isEmpty()) {
+ dir = m_openDirectory;
+ break;
+ }
+ dir = QDir::current().absolutePath();
+ } while (false);
+ dir += QDir::separator();
+ dir += QLatin1String("untitled.");
+ dir += extension;
+ }
+
+ const QString saveFile = getSaveFileNameWithExtension(fw, tr("Save Form As"), dir, tr("Designer UI files (*.%1);;All Files (*)").arg(extension), extension);
+ if (saveFile.isEmpty())
+ return false;
+
+ fw->setFileName(saveFile);
+ return writeOutForm(fw, saveFile);
+}
+
+void QDesignerActions::saveForm()
+{
+ if (QDesignerFormWindowInterface *fw = core()->formWindowManager()->activeFormWindow()) {
+ if (saveForm(fw))
+ showStatusBarMessage(savedMessage(QFileInfo(fw->fileName()).fileName()));
+ }
+}
+
+void QDesignerActions::saveAllForms()
+{
+ QString fileNames;
+ QDesignerFormWindowManagerInterface *formWindowManager = core()->formWindowManager();
+ if (const int totalWindows = formWindowManager->formWindowCount()) {
+ const QString separator = QLatin1String(", ");
+ for (int i = 0; i < totalWindows; ++i) {
+ QDesignerFormWindowInterface *fw = formWindowManager->formWindow(i);
+ if (fw && fw->isDirty()) {
+ formWindowManager->setActiveFormWindow(fw);
+ if (saveForm(fw)) {
+ if (!fileNames.isEmpty())
+ fileNames += separator;
+ fileNames += QFileInfo(fw->fileName()).fileName();
+ } else {
+ break;
+ }
+ }
+ }
+ }
+
+ if (!fileNames.isEmpty()) {
+ showStatusBarMessage(savedMessage(fileNames));
+ }
+}
+
+bool QDesignerActions::saveForm(QDesignerFormWindowInterface *fw)
+{
+ bool ret;
+ if (fw->fileName().isEmpty())
+ ret = saveFormAs(fw);
+ else
+ ret = writeOutForm(fw, fw->fileName());
+ return ret;
+}
+
+void QDesignerActions::closeForm()
+{
+ if (m_previewManager->previewCount()) {
+ closePreview();
+ return;
+ }
+
+ if (QDesignerFormWindowInterface *fw = core()->formWindowManager()->activeFormWindow())
+ if (QWidget *parent = fw->parentWidget()) {
+ if (QMdiSubWindow *mdiSubWindow = qobject_cast<QMdiSubWindow *>(parent->parentWidget())) {
+ mdiSubWindow->close();
+ } else {
+ parent->close();
+ }
+ }
+}
+
+void QDesignerActions::saveFormAs()
+{
+ if (QDesignerFormWindowInterface *fw = core()->formWindowManager()->activeFormWindow()) {
+ if (saveFormAs(fw))
+ showStatusBarMessage(savedMessage(fw->fileName()));
+ }
+}
+
+void QDesignerActions::saveFormAsTemplate()
+{
+ if (QDesignerFormWindowInterface *fw = core()->formWindowManager()->activeFormWindow()) {
+ SaveFormAsTemplate dlg(core(), fw, fw->window());
+ dlg.exec();
+ }
+}
+
+void QDesignerActions::notImplementedYet()
+{
+ QMessageBox::information(core()->topLevel(), tr("Designer"), tr("Feature not implemented yet!"));
+}
+
+void QDesignerActions::closePreview()
+{
+ m_previewManager->closeAllPreviews();
+}
+
+void QDesignerActions::viewCode()
+{
+ QDesignerFormWindowInterface *fw = core()->formWindowManager()->activeFormWindow();
+ if (!fw)
+ return;
+ QString errorMessage;
+ if (!qdesigner_internal::CodeDialog::showCodeDialog(fw, fw, &errorMessage))
+ QMessageBox::warning(fw, tr("Code generation failed"), errorMessage);
+}
+
+void QDesignerActions::fixActionContext()
+{
+ QList<QAction*> actions;
+ actions += m_fileActions->actions();
+ actions += m_editActions->actions();
+ actions += m_toolActions->actions();
+ actions += m_formActions->actions();
+ actions += m_windowActions->actions();
+ actions += m_helpActions->actions();
+
+ foreach (QAction *a, actions) {
+ a->setShortcutContext(Qt::ApplicationShortcut);
+ }
+}
+
+bool QDesignerActions::readInForm(const QString &fileName)
+{
+ QString fn = fileName;
+
+ // First make sure that we don't have this one open already.
+ QDesignerFormWindowManagerInterface *formWindowManager = core()->formWindowManager();
+ const int totalWindows = formWindowManager->formWindowCount();
+ for (int i = 0; i < totalWindows; ++i) {
+ QDesignerFormWindowInterface *w = formWindowManager->formWindow(i);
+ if (w->fileName() == fn) {
+ w->raise();
+ formWindowManager->setActiveFormWindow(w);
+ addRecentFile(fn);
+ return true;
+ }
+ }
+
+ // Otherwise load it.
+ do {
+ QString errorMessage;
+ if (workbench()->openForm(fn, &errorMessage)) {
+ addRecentFile(fn);
+ m_openDirectory = QFileInfo(fn).absolutePath();
+ return true;
+ } else {
+ // prompt to reload
+ QMessageBox box(QMessageBox::Warning, tr("Read error"),
+ tr("%1\nDo you want to update the file location or generate a new form?").arg(errorMessage),
+ QMessageBox::Cancel, core()->topLevel());
+
+ QPushButton *updateButton = box.addButton(tr("&Update"), QMessageBox::ActionRole);
+ QPushButton *newButton = box.addButton(tr("&New Form"), QMessageBox::ActionRole);
+ box.exec();
+ if (box.clickedButton() == box.button(QMessageBox::Cancel))
+ return false;
+
+ if (box.clickedButton() == updateButton) {
+ const QString extension = uiExtension();
+ fn = QFileDialog::getOpenFileName(core()->topLevel(),
+ tr("Open Form"), m_openDirectory,
+ tr("Designer UI files (*.%1);;All Files (*)").arg(extension), 0, QFileDialog::DontUseSheet);
+
+ if (fn.isEmpty())
+ return false;
+ } else if (box.clickedButton() == newButton) {
+ // If the file does not exist, but its directory, is valid, open the template with the editor file name set to it.
+ // (called from command line).
+ QString newFormFileName;
+ const QFileInfo fInfo(fn);
+ if (!fInfo.exists()) {
+ // Normalize file name
+ const QString directory = fInfo.absolutePath();
+ if (QDir(directory).exists()) {
+ newFormFileName = directory;
+ newFormFileName += QLatin1Char('/');
+ newFormFileName += fInfo.fileName();
+ }
+ }
+ showNewFormDialog(newFormFileName);
+ return false;
+ }
+ }
+ } while (true);
+ return true;
+}
+
+static QString createBackup(const QString &fileName)
+{
+ const QString suffix = QLatin1String(".bak");
+ QString backupFile = fileName + suffix;
+ QFileInfo fi(backupFile);
+ int i = 0;
+ while (fi.exists()) {
+ backupFile = fileName + suffix + QString::number(++i);
+ fi.setFile(backupFile);
+ }
+
+ if (QFile::copy(fileName, backupFile))
+ return backupFile;
+ return QString();
+}
+
+static void removeBackup(const QString &backupFile)
+{
+ if (!backupFile.isEmpty())
+ QFile::remove(backupFile);
+}
+
+bool QDesignerActions::writeOutForm(QDesignerFormWindowInterface *fw, const QString &saveFile)
+{
+ Q_ASSERT(fw && !saveFile.isEmpty());
+
+ QString backupFile;
+ QFileInfo fi(saveFile);
+ if (fi.exists())
+ backupFile = createBackup(saveFile);
+
+ QString contents = fw->contents();
+ if (qdesigner_internal::FormWindowBase *fwb = qobject_cast<qdesigner_internal::FormWindowBase *>(fw)) {
+ if (fwb->lineTerminatorMode() == qdesigner_internal::FormWindowBase::CRLFLineTerminator)
+ contents.replace(QLatin1Char('\n'), QLatin1String("\r\n"));
+ }
+ const QByteArray utf8Array = contents.toUtf8();
+ m_workbench->updateBackup(fw);
+
+ QFile f(saveFile);
+ while (!f.open(QFile::WriteOnly)) {
+ QMessageBox box(QMessageBox::Warning,
+ tr("Save Form?"),
+ tr("Could not open file"),
+ QMessageBox::NoButton, fw);
+
+ box.setWindowModality(Qt::WindowModal);
+ box.setInformativeText(tr("The file %1 could not be opened."
+ "\nReason: %2"
+ "\nWould you like to retry or select a different file?")
+ .arg(f.fileName()).arg(f.errorString()));
+ QPushButton *retryButton = box.addButton(QMessageBox::Retry);
+ retryButton->setDefault(true);
+ QPushButton *switchButton = box.addButton(tr("Select New File"), QMessageBox::AcceptRole);
+ QPushButton *cancelButton = box.addButton(QMessageBox::Cancel);
+ box.exec();
+
+ if (box.clickedButton() == cancelButton) {
+ removeBackup(backupFile);
+ return false;
+ } else if (box.clickedButton() == switchButton) {
+ QString extension = uiExtension();
+ const QString fileName = QFileDialog::getSaveFileName(fw, tr("Save Form As"),
+ QDir::current().absolutePath(),
+ QLatin1String("*.") + extension);
+ if (fileName.isEmpty()) {
+ removeBackup(backupFile);
+ return false;
+ }
+ if (f.fileName() != fileName) {
+ removeBackup(backupFile);
+ fi.setFile(fileName);
+ backupFile.clear();
+ if (fi.exists())
+ backupFile = createBackup(fileName);
+ }
+ f.setFileName(fileName);
+ fw->setFileName(fileName);
+ }
+ // loop back around...
+ }
+ while (f.write(utf8Array, utf8Array.size()) != utf8Array.size()) {
+ QMessageBox box(QMessageBox::Warning, tr("Save Form?"),
+ tr("Could not write file"),
+ QMessageBox::Retry|QMessageBox::Cancel, fw);
+ box.setWindowModality(Qt::WindowModal);
+ box.setInformativeText(tr("It was not possible to write the entire file %1 to disk."
+ "\nReason:%2\nWould you like to retry?")
+ .arg(f.fileName()).arg(f.errorString()));
+ box.setDefaultButton(QMessageBox::Retry);
+ switch (box.exec()) {
+ case QMessageBox::Retry:
+ f.resize(0);
+ break;
+ default:
+ return false;
+ }
+ }
+ f.close();
+ removeBackup(backupFile);
+ addRecentFile(saveFile);
+ m_saveDirectory = QFileInfo(f).absolutePath();
+
+ fw->setDirty(false);
+ fw->parentWidget()->setWindowModified(false);
+ return true;
+}
+
+void QDesignerActions::shutdown()
+{
+ // Follow the idea from the Mac, i.e. send the Application a close event
+ // and if it's accepted, quit.
+ QCloseEvent ev;
+ QApplication::sendEvent(qDesigner, &ev);
+ if (ev.isAccepted())
+ qDesigner->quit();
+}
+
+void QDesignerActions::activeFormWindowChanged(QDesignerFormWindowInterface *formWindow)
+{
+ const bool enable = formWindow != 0;
+ m_saveFormAction->setEnabled(enable);
+ m_saveFormAsAction->setEnabled(enable);
+ m_saveAllFormsAction->setEnabled(enable);
+ m_saveFormAsTemplateAction->setEnabled(enable);
+ m_closeFormAction->setEnabled(enable);
+ m_savePreviewImageAction->setEnabled(enable);
+ m_printPreviewAction->setEnabled(enable);
+
+ m_editWidgetsAction->setEnabled(enable);
+
+ m_previewFormAction->setEnabled(enable);
+ m_viewCodeAction->setEnabled(enable);
+ m_styleActions->setEnabled(enable);
+}
+
+void QDesignerActions::formWindowSettingsChanged(QDesignerFormWindowInterface *fw)
+{
+ if (QDesignerFormWindow *window = m_workbench->findFormWindow(fw))
+ window->updateChanged();
+}
+
+void QDesignerActions::updateRecentFileActions()
+{
+ QStringList files = m_settings.recentFilesList();
+ const int originalSize = files.size();
+ int numRecentFiles = qMin(files.size(), int(MaxRecentFiles));
+ const QList<QAction *> recentFilesActs = m_recentFilesActions->actions();
+
+ for (int i = 0; i < numRecentFiles; ++i) {
+ const QFileInfo fi(files[i]);
+ // If the file doesn't exist anymore, just remove it from the list so
+ // people don't get confused.
+ if (!fi.exists()) {
+ files.removeAt(i);
+ --i;
+ numRecentFiles = qMin(files.size(), int(MaxRecentFiles));
+ continue;
+ }
+ const QString text = fi.fileName();
+ recentFilesActs[i]->setText(text);
+ recentFilesActs[i]->setIconText(files[i]);
+ recentFilesActs[i]->setVisible(true);
+ }
+
+ for (int j = numRecentFiles; j < MaxRecentFiles; ++j)
+ recentFilesActs[j]->setVisible(false);
+
+ // If there's been a change, right it back
+ if (originalSize != files.size())
+ m_settings.setRecentFilesList(files);
+}
+
+void QDesignerActions::openRecentForm()
+{
+ if (const QAction *action = qobject_cast<const QAction *>(sender())) {
+ if (!readInForm(action->iconText()))
+ updateRecentFileActions(); // File doesn't exist, remove it from settings
+ }
+}
+
+void QDesignerActions::clearRecentFiles()
+{
+ m_settings.setRecentFilesList(QStringList());
+ updateRecentFileActions();
+}
+
+QActionGroup *QDesignerActions::recentFilesActions() const
+{
+ return m_recentFilesActions;
+}
+
+void QDesignerActions::addRecentFile(const QString &fileName)
+{
+ QStringList files = m_settings.recentFilesList();
+ files.removeAll(fileName);
+ files.prepend(fileName);
+ while (files.size() > MaxRecentFiles)
+ files.removeLast();
+
+ m_settings.setRecentFilesList(files);
+ updateRecentFileActions();
+}
+
+QAction *QDesignerActions::openFormAction() const
+{
+ return m_openFormAction;
+}
+
+QAction *QDesignerActions::closeFormAction() const
+{
+ return m_closeFormAction;
+}
+
+QAction *QDesignerActions::minimizeAction() const
+{
+ return m_minimizeAction;
+}
+
+void QDesignerActions::showDesignerHelp()
+{
+ QString url = AssistantClient::designerManualUrl();
+ url += QLatin1String("designer-manual.html");
+ showHelp(url);
+}
+
+void QDesignerActions::showWhatsNew()
+{
+ QString url = AssistantClient::qtReferenceManualUrl();
+ url += QLatin1String("qt4-designer.html");
+ showHelp(url);
+}
+
+void QDesignerActions::helpRequested(const QString &manual, const QString &document)
+{
+ QString url = AssistantClient::documentUrl(manual);
+ url += document;
+ showHelp(url);
+}
+
+void QDesignerActions::showHelp(const QString &url)
+{
+ QString errorMessage;
+ if (!m_assistantClient.showPage(url, &errorMessage))
+ QMessageBox::warning(core()->topLevel(), tr("Assistant"), errorMessage);
+}
+
+void QDesignerActions::aboutDesigner()
+{
+ VersionDialog mb(core()->topLevel());
+ mb.setWindowTitle(tr("About Qt Designer"));
+ if (mb.exec()) {
+ QMessageBox messageBox(QMessageBox::Information, QLatin1String("Easter Egg"),
+ QLatin1String("Easter Egg"), QMessageBox::Ok, core()->topLevel());
+ messageBox.setInformativeText(QLatin1String("The Easter Egg has been removed."));
+ messageBox.exec();
+ }
+}
+
+QAction *QDesignerActions::editWidgets() const
+{
+ return m_editWidgetsAction;
+}
+
+void QDesignerActions::showWidgetSpecificHelp()
+{
+ QString helpId;
+ if (const qdesigner_internal::QDesignerIntegration *integration = qobject_cast<qdesigner_internal::QDesignerIntegration *>(core()->integration()))
+ helpId = integration->contextHelpId();
+
+ if (helpId.isEmpty()) {
+ showDesignerHelp();
+ return;
+ }
+
+ QString errorMessage;
+ const bool rc = m_assistantClient.activateIdentifier(helpId, &errorMessage);
+ if (!rc)
+ QMessageBox::warning(core()->topLevel(), tr("Assistant"), errorMessage);
+}
+
+void QDesignerActions::updateCloseAction()
+{
+ if (m_previewManager->previewCount()) {
+ m_closeFormAction->setText(tr("&Close Preview"));
+ } else {
+ m_closeFormAction->setText(tr("&Close"));
+ }
+}
+
+void QDesignerActions::backupForms()
+{
+ const int count = m_workbench->formWindowCount();
+ if (!count || !ensureBackupDirectories())
+ return;
+
+
+ QStringList tmpFiles;
+ QMap<QString, QString> backupMap;
+ QDir backupDir(m_backupPath);
+ const bool warningsEnabled = qdesigner_internal::QSimpleResource::setWarningsEnabled(false);
+ for (int i = 0; i < count; ++i) {
+ QDesignerFormWindow *fw = m_workbench->formWindow(i);
+ QDesignerFormWindowInterface *fwi = fw->editor();
+
+ QString formBackupName;
+ QTextStream(&formBackupName) << m_backupPath << QDir::separator()
+ << QLatin1String("backup") << i << QLatin1String(".bak");
+
+ QString fwn = QDir::convertSeparators(fwi->fileName());
+ if (fwn.isEmpty())
+ fwn = fw->windowTitle();
+
+ backupMap.insert(fwn, formBackupName);
+
+ QFile file(formBackupName.replace(m_backupPath, m_backupTmpPath));
+ if (file.open(QFile::WriteOnly)){
+ QString contents = fixResourceFileBackupPath(fwi, backupDir);
+ if (qdesigner_internal::FormWindowBase *fwb = qobject_cast<qdesigner_internal::FormWindowBase *>(fwi)) {
+ if (fwb->lineTerminatorMode() == qdesigner_internal::FormWindowBase::CRLFLineTerminator)
+ contents.replace(QLatin1Char('\n'), QLatin1String("\r\n"));
+ }
+ const QByteArray utf8Array = contents.toUtf8();
+ if (file.write(utf8Array, utf8Array.size()) != utf8Array.size()) {
+ backupMap.remove(fwn);
+ qdesigner_internal::designerWarning(tr("The backup file %1 could not be written.").arg(file.fileName()));
+ } else
+ tmpFiles.append(formBackupName);
+
+ file.close();
+ }
+ }
+ qdesigner_internal::QSimpleResource::setWarningsEnabled(warningsEnabled);
+ if(!tmpFiles.isEmpty()) {
+ const QStringList backupFiles = backupDir.entryList(QDir::Files);
+ if(!backupFiles.isEmpty()) {
+ QStringListIterator it(backupFiles);
+ while (it.hasNext())
+ backupDir.remove(it.next());
+ }
+
+ QStringListIterator it(tmpFiles);
+ while (it.hasNext()) {
+ const QString tmpName = it.next();
+ QString name(tmpName);
+ name.replace(m_backupTmpPath, m_backupPath);
+ QFile tmpFile(tmpName);
+ if (!tmpFile.copy(name))
+ qdesigner_internal::designerWarning(tr("The backup file %1 could not be written.").arg(name));
+ tmpFile.remove();
+ }
+
+ m_settings.setBackup(backupMap);
+ }
+}
+
+QString QDesignerActions::fixResourceFileBackupPath(QDesignerFormWindowInterface *fwi, const QDir& backupDir)
+{
+ const QString content = fwi->contents();
+ QDomDocument domDoc(QLatin1String("backup"));
+ if(!domDoc.setContent(content))
+ return content;
+
+ const QDomNodeList list = domDoc.elementsByTagName(QLatin1String("resources"));
+ if (list.isEmpty())
+ return content;
+
+ for (int i = 0; i < list.count(); i++) {
+ const QDomNode node = list.at(i);
+ if (!node.isNull()) {
+ const QDomElement element = node.toElement();
+ if(!element.isNull() && element.tagName() == QLatin1String("resources")) {
+ QDomNode childNode = element.firstChild();
+ while (!childNode.isNull()) {
+ QDomElement childElement = childNode.toElement();
+ if(!childElement.isNull() && childElement.tagName() == QLatin1String("include")) {
+ const QString attr = childElement.attribute(QLatin1String("location"));
+ const QString path = fwi->absoluteDir().absoluteFilePath(attr);
+ childElement.setAttribute(QLatin1String("location"), backupDir.relativeFilePath(path));
+ }
+ childNode = childNode.nextSibling();
+ }
+ }
+ }
+ }
+
+
+ return domDoc.toString();
+}
+
+QRect QDesignerActions::fixDialogRect(const QRect &rect) const
+{
+ QRect frameGeometry;
+ const QRect availableGeometry = QApplication::desktop()->availableGeometry(core()->topLevel());
+
+ if (workbench()->mode() == DockedMode) {
+ frameGeometry = core()->topLevel()->frameGeometry();
+ } else
+ frameGeometry = availableGeometry;
+
+ QRect dlgRect = rect;
+ dlgRect.moveCenter(frameGeometry.center());
+
+ // make sure that parts of the dialog are not outside of screen
+ dlgRect.moveBottom(qMin(dlgRect.bottom(), availableGeometry.bottom()));
+ dlgRect.moveRight(qMin(dlgRect.right(), availableGeometry.right()));
+ dlgRect.moveLeft(qMax(dlgRect.left(), availableGeometry.left()));
+ dlgRect.moveTop(qMax(dlgRect.top(), availableGeometry.top()));
+
+ return dlgRect;
+}
+
+void QDesignerActions::showStatusBarMessage(const QString &message) const
+{
+ if (workbench()->mode() == DockedMode) {
+ QStatusBar *bar = qDesigner->mainWindow()->statusBar();
+ if (bar && !bar->isHidden())
+ bar->showMessage(message, 3000);
+ }
+}
+
+void QDesignerActions::setBringAllToFrontVisible(bool visible)
+{
+ m_bringAllToFrontSeparator->setVisible(visible);
+ m_bringAllToFrontAction->setVisible(visible);
+}
+
+void QDesignerActions::setWindowListSeparatorVisible(bool visible)
+{
+ m_windowListSeparatorAction->setVisible(visible);
+}
+
+bool QDesignerActions::ensureBackupDirectories() {
+
+ if (m_backupPath.isEmpty()) {
+ // create names
+ m_backupPath = QDir::homePath();
+ m_backupPath += QDir::separator();
+ m_backupPath += QLatin1String(".designer");
+ m_backupPath += QDir::separator();
+ m_backupPath += QLatin1String("backup");
+ m_backupPath = QDir::convertSeparators(m_backupPath );
+
+ m_backupTmpPath = m_backupPath;
+ m_backupTmpPath += QDir::separator();
+ m_backupTmpPath += QLatin1String("tmp");
+ m_backupTmpPath = QDir::convertSeparators(m_backupTmpPath);
+ }
+
+ // ensure directories
+ const QDir backupDir(m_backupPath);
+ const QDir backupTmpDir(m_backupTmpPath);
+
+ if (!backupDir.exists()) {
+ if (!backupDir.mkpath(m_backupPath)) {
+ qdesigner_internal::designerWarning(tr("The backup directory %1 could not be created.").arg(m_backupPath));
+ return false;
+ }
+ }
+ if (!backupTmpDir.exists()) {
+ if (!backupTmpDir.mkpath(m_backupTmpPath)) {
+ qdesigner_internal::designerWarning(tr("The temporary backup directory %1 could not be created.").arg(m_backupTmpPath));
+ return false;
+ }
+ }
+ return true;
+}
+
+void QDesignerActions::showPreferencesDialog()
+{
+ PreferencesDialog preferencesDialog(workbench()->core(), m_core->topLevel());
+ preferencesDialog.exec();
+}
+
+void QDesignerActions::showAppFontDialog()
+{
+ if (!m_appFontDialog) // Might get deleted when switching ui modes
+ m_appFontDialog = new AppFontDialog(core()->topLevel());
+ m_appFontDialog->show();
+ m_appFontDialog->raise();
+}
+
+QPixmap QDesignerActions::createPreviewPixmap(QDesignerFormWindowInterface *fw)
+{
+ const QCursor oldCursor = core()->topLevel()->cursor();
+ core()->topLevel()->setCursor(Qt::WaitCursor);
+
+ QString errorMessage;
+ const QPixmap pixmap = m_previewManager->createPreviewPixmap(fw, QString(), &errorMessage);
+ core()->topLevel()->setCursor(oldCursor);
+ if (pixmap.isNull()) {
+ QMessageBox::warning(fw, tr("Preview failed"), errorMessage);
+ }
+ return pixmap;
+}
+
+qdesigner_internal::PreviewConfiguration QDesignerActions::previewConfiguration()
+{
+ qdesigner_internal::PreviewConfiguration pc;
+ QDesignerSharedSettings settings(core());
+ if (settings.isCustomPreviewConfigurationEnabled())
+ pc = settings.customPreviewConfiguration();
+ return pc;
+}
+
+void QDesignerActions::savePreviewImage()
+{
+ const char *format = "png";
+
+ QDesignerFormWindowInterface *fw = core()->formWindowManager()->activeFormWindow();
+ if (!fw)
+ return;
+
+ QImage image;
+ const QString extension = QString::fromAscii(format);
+ const QString filter = tr("Image files (*.%1)").arg(extension);
+
+ QString suggestion = fw->fileName();
+ if (!suggestion.isEmpty()) {
+ suggestion = QFileInfo(suggestion).baseName();
+ suggestion += QLatin1Char('.');
+ suggestion += extension;
+ }
+ do {
+ const QString fileName = getSaveFileNameWithExtension(fw, tr("Save Image"), suggestion, filter, extension);
+ if (fileName.isEmpty())
+ break;
+
+ if (image.isNull()) {
+ const QPixmap pixmap = createPreviewPixmap(fw);
+ if (pixmap.isNull())
+ break;
+
+ image = pixmap.toImage();
+ }
+
+ if (image.save(fileName, format)) {
+ showStatusBarMessage(tr("Saved image %1.").arg(QFileInfo(fileName).fileName()));
+ break;
+ }
+
+ QMessageBox box(QMessageBox::Warning, tr("Save Image"),
+ tr("The file %1 could not be written.").arg( fileName),
+ QMessageBox::Retry|QMessageBox::Cancel, fw);
+ if (box.exec() == QMessageBox::Cancel)
+ break;
+ } while (true);
+}
+
+void QDesignerActions::formWindowCountChanged()
+{
+ const bool enabled = m_core->formWindowManager()->formWindowCount() == 0;
+ /* Disable the application font action if there are form windows open
+ * as the reordering of the fonts sets font properties to 'changed'
+ * and overloaded fonts are not updated. */
+ static const QString disabledTip = tr("Please close all forms to enable the loading of additional fonts.");
+ m_appFontAction->setEnabled(enabled);
+ m_appFontAction->setStatusTip(enabled ? QString() : disabledTip);
+}
+
+void QDesignerActions::printPreviewImage()
+{
+#ifndef QT_NO_PRINTER
+ QDesignerFormWindowInterface *fw = core()->formWindowManager()->activeFormWindow();
+ if (!fw)
+ return;
+
+ if (!m_printer)
+ m_printer = new QPrinter(QPrinter::HighResolution);
+
+ m_printer->setFullPage(false);
+
+ // Grab the image to be able to a suggest suitable orientation
+ const QPixmap pixmap = createPreviewPixmap(fw);
+ if (pixmap.isNull())
+ return;
+
+ const QSizeF pixmapSize = pixmap.size();
+ m_printer->setOrientation( pixmapSize.width() > pixmapSize.height() ? QPrinter::Landscape : QPrinter::Portrait);
+
+ // Printer parameters
+ QPrintDialog dialog(m_printer, fw);
+ if (!dialog.exec())
+ return;
+
+ const QCursor oldCursor = core()->topLevel()->cursor();
+ core()->topLevel()->setCursor(Qt::WaitCursor);
+ // Estimate of required scaling to make form look the same on screen and printer.
+ const double suggestedScaling = static_cast<double>(m_printer->physicalDpiX()) / static_cast<double>(fw->physicalDpiX());
+
+ QPainter painter(m_printer);
+ painter.setRenderHint(QPainter::SmoothPixmapTransform);
+
+ // Clamp to page
+ const QRectF page = painter.viewport();
+ const double maxScaling = qMin(page.size().width() / pixmapSize.width(), page.size().height() / pixmapSize.height());
+ const double scaling = qMin(suggestedScaling, maxScaling);
+
+ const double xOffset = page.left() + qMax(0.0, (page.size().width() - scaling * pixmapSize.width()) / 2.0);
+ const double yOffset = page.top() + qMax(0.0, (page.size().height() - scaling * pixmapSize.height()) / 2.0);
+
+ // Draw.
+ painter.translate(xOffset, yOffset);
+ painter.scale(scaling, scaling);
+ painter.drawPixmap(0, 0, pixmap);
+ core()->topLevel()->setCursor(oldCursor);
+
+ showStatusBarMessage(tr("Printed %1.").arg(QFileInfo(fw->fileName()).fileName()));
+#endif
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/designer/qdesigner_actions.h b/src/designer/src/designer/qdesigner_actions.h
new file mode 100644
index 000000000..910901bcb
--- /dev/null
+++ b/src/designer/src/designer/qdesigner_actions.h
@@ -0,0 +1,231 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDESIGNER_ACTIONS_H
+#define QDESIGNER_ACTIONS_H
+
+#include "assistantclient.h"
+#include "qdesigner_settings.h"
+
+#include <QtCore/QObject>
+#include <QtCore/QPointer>
+#include <QtGui/QPrinter>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerWorkbench;
+
+class QDir;
+class QTimer;
+class QAction;
+class QActionGroup;
+class QDesignerFormEditorInterface;
+class QDesignerFormWindowInterface;
+class AppFontDialog;
+
+class QRect;
+class QWidget;
+class QPixmap;
+class QMenu;
+
+namespace qdesigner_internal {
+ class PreviewConfiguration;
+ class PreviewManager;
+}
+
+class QDesignerActions: public QObject
+{
+ Q_OBJECT
+public:
+ explicit QDesignerActions(QDesignerWorkbench *mainWindow);
+ virtual ~QDesignerActions();
+
+ QDesignerWorkbench *workbench() const;
+ QDesignerFormEditorInterface *core() const;
+
+ bool saveForm(QDesignerFormWindowInterface *fw);
+ bool readInForm(const QString &fileName);
+ bool writeOutForm(QDesignerFormWindowInterface *formWindow, const QString &fileName);
+
+ QActionGroup *fileActions() const;
+ QActionGroup *recentFilesActions() const;
+ QActionGroup *editActions() const;
+ QActionGroup *formActions() const;
+ QActionGroup *settingsActions() const;
+ QActionGroup *windowActions() const;
+ QActionGroup *toolActions() const;
+ QActionGroup *helpActions() const;
+ QActionGroup *uiMode() const;
+ QActionGroup *styleActions() const;
+ // file actions
+ QAction *openFormAction() const;
+ QAction *closeFormAction() const;
+ // window actions
+ QAction *minimizeAction() const;
+ // edit mode actions
+ QAction *editWidgets() const;
+ // form actions
+ QAction *previewFormAction() const;
+ QAction *viewCodeAction() const;
+
+ void setBringAllToFrontVisible(bool visible);
+ void setWindowListSeparatorVisible(bool visible);
+
+ bool openForm(QWidget *parent);
+
+ QString uiExtension() const;
+
+ // Boolean dynamic property set on actions to
+ // show them in the default toolbar layout
+ static const char *defaultToolbarPropertyName;
+
+public slots:
+ void activeFormWindowChanged(QDesignerFormWindowInterface *formWindow);
+ void createForm();
+ void slotOpenForm();
+ void helpRequested(const QString &manual, const QString &document);
+
+signals:
+ void useBigIcons(bool);
+
+private slots:
+ void saveForm();
+ void saveFormAs();
+ void saveAllForms();
+ void saveFormAsTemplate();
+ void viewCode();
+ void notImplementedYet();
+ void shutdown();
+ void editWidgetsSlot();
+ void openRecentForm();
+ void clearRecentFiles();
+ void closeForm();
+ void showDesignerHelp();
+ void showWhatsNew();
+ void aboutDesigner();
+ void showWidgetSpecificHelp();
+ void backupForms();
+ void showNewFormDialog(const QString &fileName);
+ void showPreferencesDialog();
+ void showAppFontDialog();
+ void savePreviewImage();
+ void printPreviewImage();
+ void updateCloseAction();
+ void formWindowCountChanged();
+ void formWindowSettingsChanged(QDesignerFormWindowInterface *fw);
+
+private:
+ QAction *createRecentFilesMenu();
+ bool saveFormAs(QDesignerFormWindowInterface *fw);
+ void fixActionContext();
+ void updateRecentFileActions();
+ void addRecentFile(const QString &fileName);
+ void showHelp(const QString &help);
+ void closePreview();
+ QRect fixDialogRect(const QRect &rect) const;
+ QString fixResourceFileBackupPath(QDesignerFormWindowInterface *fwi, const QDir& backupDir);
+ void showStatusBarMessage(const QString &message) const;
+ QActionGroup *createHelpActions();
+ bool ensureBackupDirectories();
+ QPixmap createPreviewPixmap(QDesignerFormWindowInterface *fw);
+ qdesigner_internal::PreviewConfiguration previewConfiguration();
+
+ enum { MaxRecentFiles = 10 };
+ QDesignerWorkbench *m_workbench;
+ QDesignerFormEditorInterface *m_core;
+ QDesignerSettings m_settings;
+ AssistantClient m_assistantClient;
+ QString m_openDirectory;
+ QString m_saveDirectory;
+
+
+ QString m_backupPath;
+ QString m_backupTmpPath;
+
+ QTimer* m_backupTimer;
+
+ QActionGroup *m_fileActions;
+ QActionGroup *m_recentFilesActions;
+ QActionGroup *m_editActions;
+ QActionGroup *m_formActions;
+ QActionGroup *m_settingsActions;
+ QActionGroup *m_windowActions;
+ QActionGroup *m_toolActions;
+ QActionGroup *m_helpActions;
+ QActionGroup *m_styleActions;
+
+ QAction *m_editWidgetsAction;
+
+ QAction *m_newFormAction;
+ QAction *m_openFormAction;
+ QAction *m_saveFormAction;
+ QAction *m_saveFormAsAction;
+ QAction *m_saveAllFormsAction;
+ QAction *m_saveFormAsTemplateAction;
+ QAction *m_closeFormAction;
+ QAction *m_savePreviewImageAction;
+ QAction *m_printPreviewAction;
+
+ QAction *m_quitAction;
+
+ QAction *m_previewFormAction;
+ QAction *m_viewCodeAction;
+
+ QAction *m_minimizeAction;
+ QAction *m_bringAllToFrontSeparator;
+ QAction *m_bringAllToFrontAction;
+ QAction *m_windowListSeparatorAction;
+
+ QAction *m_preferencesAction;
+ QAction *m_appFontAction;
+
+ QPointer<AppFontDialog> m_appFontDialog;
+
+#ifndef QT_NO_PRINTER
+ QPrinter *m_printer;
+#endif
+
+ qdesigner_internal::PreviewManager *m_previewManager;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_ACTIONS_H
diff --git a/src/designer/src/designer/qdesigner_appearanceoptions.cpp b/src/designer/src/designer/qdesigner_appearanceoptions.cpp
new file mode 100644
index 000000000..f5b3f3d6d
--- /dev/null
+++ b/src/designer/src/designer/qdesigner_appearanceoptions.cpp
@@ -0,0 +1,167 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_appearanceoptions.h"
+#include "ui_qdesigner_appearanceoptions.h"
+
+#include "qdesigner_settings.h"
+#include "qdesigner_toolwindow.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtCore/QTimer>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+// ---------------- AppearanceOptions
+AppearanceOptions::AppearanceOptions() :
+ uiMode(DockedMode)
+{
+}
+
+bool AppearanceOptions::equals(const AppearanceOptions &rhs) const
+{
+ return uiMode == rhs.uiMode && toolWindowFontSettings == rhs.toolWindowFontSettings;
+}
+
+void AppearanceOptions::toSettings(QDesignerSettings &settings) const
+{
+ settings.setUiMode(uiMode);
+ settings.setToolWindowFont(toolWindowFontSettings);
+}
+
+void AppearanceOptions::fromSettings(const QDesignerSettings &settings)
+{
+ uiMode = settings.uiMode();
+ toolWindowFontSettings = settings.toolWindowFont();
+}
+
+// ---------------- QDesignerAppearanceOptionsWidget
+QDesignerAppearanceOptionsWidget::QDesignerAppearanceOptionsWidget(QWidget *parent) :
+ QWidget(parent),
+ m_ui(new Ui::AppearanceOptionsWidget),
+ m_initialUIMode(NeutralMode)
+{
+ m_ui->setupUi(this);
+
+ m_ui->m_uiModeCombo->addItem(tr("Docked Window"), QVariant(DockedMode));
+ m_ui->m_uiModeCombo->addItem(tr("Multiple Top-Level Windows"), QVariant(TopLevelMode));
+ connect(m_ui->m_uiModeCombo, SIGNAL(currentIndexChanged(int)),
+ this, SLOT(slotUiModeComboChanged()));
+
+ m_ui->m_fontPanel->setCheckable(true);
+ m_ui->m_fontPanel->setTitle(tr("Toolwindow Font"));
+
+}
+
+QDesignerAppearanceOptionsWidget::~QDesignerAppearanceOptionsWidget()
+{
+ delete m_ui;
+}
+
+UIMode QDesignerAppearanceOptionsWidget::uiMode() const
+{
+ return static_cast<UIMode>(m_ui->m_uiModeCombo->itemData(m_ui->m_uiModeCombo->currentIndex()).toInt());
+}
+
+AppearanceOptions QDesignerAppearanceOptionsWidget::appearanceOptions() const
+{
+ AppearanceOptions rc;
+ rc.uiMode = uiMode();
+ rc.toolWindowFontSettings.m_font = m_ui->m_fontPanel->selectedFont();
+ rc.toolWindowFontSettings.m_useFont = m_ui->m_fontPanel->isChecked();
+ rc.toolWindowFontSettings.m_writingSystem = m_ui->m_fontPanel->writingSystem();
+ return rc;
+}
+
+void QDesignerAppearanceOptionsWidget::setAppearanceOptions(const AppearanceOptions &ao)
+{
+ m_initialUIMode = ao.uiMode;
+ m_ui->m_uiModeCombo->setCurrentIndex(m_ui->m_uiModeCombo->findData(QVariant(ao.uiMode)));
+ m_ui->m_fontPanel->setWritingSystem(ao.toolWindowFontSettings.m_writingSystem);
+ m_ui->m_fontPanel->setSelectedFont(ao.toolWindowFontSettings.m_font);
+ m_ui->m_fontPanel->setChecked(ao.toolWindowFontSettings.m_useFont);
+}
+
+void QDesignerAppearanceOptionsWidget::slotUiModeComboChanged()
+{
+ emit uiModeChanged(m_initialUIMode != uiMode());
+}
+
+// ----------- QDesignerAppearanceOptionsPage
+QDesignerAppearanceOptionsPage::QDesignerAppearanceOptionsPage(QDesignerFormEditorInterface *core) :
+ m_core(core)
+{
+}
+
+QString QDesignerAppearanceOptionsPage::name() const
+{
+ //: Tab in preferences dialog
+ return QCoreApplication::translate("QDesignerAppearanceOptionsPage", "Appearance");
+}
+
+QWidget *QDesignerAppearanceOptionsPage::createPage(QWidget *parent)
+{
+ m_widget = new QDesignerAppearanceOptionsWidget(parent);
+ m_initialOptions.fromSettings(QDesignerSettings(m_core));
+ m_widget->setAppearanceOptions(m_initialOptions);
+ return m_widget;
+}
+
+void QDesignerAppearanceOptionsPage::apply()
+{
+ if (m_widget) {
+ const AppearanceOptions newOptions = m_widget->appearanceOptions();
+ if (newOptions != m_initialOptions) {
+ QDesignerSettings settings(m_core);
+ newOptions.toSettings(settings);
+ QTimer::singleShot(0, this, SIGNAL(settingsChangedDelayed()));
+ m_initialOptions = newOptions;
+ }
+ }
+}
+
+void QDesignerAppearanceOptionsPage::finish()
+{
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/designer/src/designer/qdesigner_appearanceoptions.h b/src/designer/src/designer/qdesigner_appearanceoptions.h
new file mode 100644
index 000000000..a6e4f9a49
--- /dev/null
+++ b/src/designer/src/designer/qdesigner_appearanceoptions.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDESIGNER_APPEARANCEOPTIONS_H
+#define QDESIGNER_APPEARANCEOPTIONS_H
+
+#include "designer_enums.h"
+#include "qdesigner_toolwindow.h"
+
+#include <QtDesigner/private/abstractoptionspage_p.h>
+#include <QtCore/QObject>
+#include <QtCore/QPointer>
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+class QDesignerSettings;
+
+namespace Ui {
+ class AppearanceOptionsWidget;
+}
+
+/* AppearanceOptions data */
+struct AppearanceOptions {
+ AppearanceOptions();
+ bool equals(const AppearanceOptions&) const;
+ void toSettings(QDesignerSettings &) const;
+ void fromSettings(const QDesignerSettings &);
+
+ UIMode uiMode;
+ ToolWindowFontSettings toolWindowFontSettings;
+};
+
+inline bool operator==(const AppearanceOptions &ao1, const AppearanceOptions &ao2)
+{
+ return ao1.equals(ao2);
+}
+
+inline bool operator!=(const AppearanceOptions &ao1, const AppearanceOptions &ao2)
+{
+ return !ao1.equals(ao2);
+}
+
+/* QDesignerAppearanceOptionsWidget: Let the user edit AppearanceOptions */
+class QDesignerAppearanceOptionsWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit QDesignerAppearanceOptionsWidget(QWidget *parent = 0);
+ ~QDesignerAppearanceOptionsWidget();
+
+ AppearanceOptions appearanceOptions() const;
+ void setAppearanceOptions(const AppearanceOptions &ao);
+
+signals:
+ void uiModeChanged(bool modified);
+
+private slots:
+ void slotUiModeComboChanged();
+
+private:
+ UIMode uiMode() const;
+
+ Ui::AppearanceOptionsWidget *m_ui;
+ UIMode m_initialUIMode;
+};
+
+/* The options page for appearance options. Emits a Timer-0 delayed changed
+ * signal to allow the preferences dialog to close (and be deleted) before a
+ * possible switch from docked mode to top-level mode happens. (The switch
+ * would delete the main window, which the preference dialog is a child of
+ * -> BOOM) */
+
+class QDesignerAppearanceOptionsPage : public QObject, public QDesignerOptionsPageInterface
+{
+ Q_OBJECT
+
+public:
+ QDesignerAppearanceOptionsPage(QDesignerFormEditorInterface *core);
+
+ QString name() const;
+ QWidget *createPage(QWidget *parent);
+ virtual void apply();
+ virtual void finish();
+
+signals:
+ void settingsChangedDelayed();
+
+private:
+ QDesignerFormEditorInterface *m_core;
+ QPointer<QDesignerAppearanceOptionsWidget> m_widget;
+ AppearanceOptions m_initialOptions;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_APPEARANCEOPTIONS_H
diff --git a/src/designer/src/designer/qdesigner_appearanceoptions.ui b/src/designer/src/designer/qdesigner_appearanceoptions.ui
new file mode 100644
index 000000000..a5582f2ab
--- /dev/null
+++ b/src/designer/src/designer/qdesigner_appearanceoptions.ui
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>AppearanceOptionsWidget</class>
+ <widget class="QWidget" name="AppearanceOptionsWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>325</width>
+ <height>360</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QGroupBox" name="m_uiModeGroupBox">
+ <property name="title">
+ <string>User Interface Mode</string>
+ </property>
+ <layout class="QVBoxLayout">
+ <item>
+ <widget class="QComboBox" name="m_uiModeCombo"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="FontPanel" name="m_fontPanel"/>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>FontPanel</class>
+ <extends>QGroupBox</extends>
+ <header>fontpanel.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/designer/src/designer/qdesigner_formwindow.cpp b/src/designer/src/designer/qdesigner_formwindow.cpp
new file mode 100644
index 000000000..4770d2a58
--- /dev/null
+++ b/src/designer/src/designer/qdesigner_formwindow.cpp
@@ -0,0 +1,290 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_formwindow.h"
+#include "qdesigner_workbench.h"
+#include "formwindowbase_p.h"
+
+// sdk
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerPropertySheetExtension>
+#include <QtDesigner/QDesignerPropertyEditorInterface>
+#include <QtDesigner/QDesignerFormWindowManagerInterface>
+#include <QtDesigner/QDesignerTaskMenuExtension>
+#include <QtDesigner/QExtensionManager>
+
+#include <QtCore/QEvent>
+#include <QtCore/QFile>
+
+#include <QtGui/QAction>
+#include <QtGui/QCloseEvent>
+#include <QtGui/QFileDialog>
+#include <QtGui/QMessageBox>
+#include <QtGui/QPushButton>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QUndoCommand>
+#include <QtGui/QWindowStateChangeEvent>
+
+QT_BEGIN_NAMESPACE
+
+QDesignerFormWindow::QDesignerFormWindow(QDesignerFormWindowInterface *editor, QDesignerWorkbench *workbench, QWidget *parent, Qt::WindowFlags flags)
+ : QWidget(parent, flags),
+ m_editor(editor),
+ m_workbench(workbench),
+ m_action(new QAction(this)),
+ m_initialized(false),
+ m_windowTitleInitialized(false)
+{
+ Q_ASSERT(workbench);
+
+ setMaximumSize(0xFFF, 0xFFF);
+ QDesignerFormEditorInterface *core = workbench->core();
+
+ if (m_editor) {
+ m_editor->setParent(this);
+ } else {
+ m_editor = core->formWindowManager()->createFormWindow(this);
+ }
+
+ QVBoxLayout *l = new QVBoxLayout(this);
+ l->setMargin(0);
+ l->addWidget(m_editor);
+
+ m_action->setCheckable(true);
+
+ connect(m_editor->commandHistory(), SIGNAL(indexChanged(int)), this, SLOT(updateChanged()));
+ connect(m_editor, SIGNAL(geometryChanged()), this, SLOT(geometryChanged()));
+ qdesigner_internal::FormWindowBase::setupDefaultAction(m_editor);
+}
+
+QDesignerFormWindow::~QDesignerFormWindow()
+{
+ if (workbench())
+ workbench()->removeFormWindow(this);
+}
+
+QAction *QDesignerFormWindow::action() const
+{
+ return m_action;
+}
+
+void QDesignerFormWindow::changeEvent(QEvent *e)
+{
+ switch (e->type()) {
+ case QEvent::WindowTitleChange:
+ m_action->setText(windowTitle().remove(QLatin1String("[*]")));
+ break;
+ case QEvent::WindowIconChange:
+ m_action->setIcon(windowIcon());
+ break;
+ case QEvent::WindowStateChange: {
+ const QWindowStateChangeEvent *wsce = static_cast<const QWindowStateChangeEvent *>(e);
+ const bool wasMinimized = Qt::WindowMinimized & wsce->oldState();
+ const bool isMinimizedNow = isMinimized();
+ if (wasMinimized != isMinimizedNow )
+ emit minimizationStateChanged(m_editor, isMinimizedNow);
+ }
+ break;
+ default:
+ break;
+ }
+ QWidget::changeEvent(e);
+}
+
+QRect QDesignerFormWindow::geometryHint() const
+{
+ const QPoint point(0, 0);
+ // If we have a container, we want to be just as big.
+ // QMdiSubWindow attempts to resize its children to sizeHint() when switching user interface modes.
+ if (QWidget *mainContainer = m_editor->mainContainer())
+ return QRect(point, mainContainer->size());
+
+ return QRect(point, sizeHint());
+}
+
+QDesignerFormWindowInterface *QDesignerFormWindow::editor() const
+{
+ return m_editor;
+}
+
+QDesignerWorkbench *QDesignerFormWindow::workbench() const
+{
+ return m_workbench;
+}
+
+void QDesignerFormWindow::firstShow()
+{
+ // Set up handling of file name changes and set initial title.
+ if (!m_windowTitleInitialized) {
+ m_windowTitleInitialized = true;
+ if (m_editor) {
+ connect(m_editor, SIGNAL(fileNameChanged(QString)), this, SLOT(updateWindowTitle(QString)));
+ updateWindowTitle(m_editor->fileName());
+ updateChanged();
+ }
+ }
+ show();
+}
+
+int QDesignerFormWindow::getNumberOfUntitledWindows() const
+{
+ const int totalWindows = m_workbench->formWindowCount();
+ if (!totalWindows)
+ return 0;
+
+ int maxUntitled = 0;
+ // Find the number of untitled windows excluding ourselves.
+ // Do not fall for 'untitled.ui', match with modified place holder.
+ // This will cause some problems with i18n, but for now I need the string to be "static"
+ QRegExp rx(QLatin1String("untitled( (\\d+))?\\[\\*\\]"));
+ for (int i = 0; i < totalWindows; ++i) {
+ QDesignerFormWindow *fw = m_workbench->formWindow(i);
+ if (fw != this) {
+ const QString title = m_workbench->formWindow(i)->windowTitle();
+ if (rx.indexIn(title) != -1) {
+ if (maxUntitled == 0)
+ ++maxUntitled;
+ if (rx.captureCount() > 1) {
+ const QString numberCapture = rx.cap(2);
+ if (!numberCapture.isEmpty())
+ maxUntitled = qMax(numberCapture.toInt(), maxUntitled);
+ }
+ }
+ }
+ }
+ return maxUntitled;
+}
+
+void QDesignerFormWindow::updateWindowTitle(const QString &fileName)
+{
+ if (!m_windowTitleInitialized) {
+ m_windowTitleInitialized = true;
+ if (m_editor)
+ connect(m_editor, SIGNAL(fileNameChanged(QString)), this, SLOT(updateWindowTitle(QString)));
+ }
+
+ QString fileNameTitle;
+ if (fileName.isEmpty()) {
+ fileNameTitle = QLatin1String("untitled");
+ if (const int maxUntitled = getNumberOfUntitledWindows()) {
+ fileNameTitle += QLatin1Char(' ');
+ fileNameTitle += QString::number(maxUntitled + 1);
+ }
+ } else {
+ fileNameTitle = QFileInfo(fileName).fileName();
+ }
+
+ if (const QWidget *mc = m_editor->mainContainer()) {
+ setWindowIcon(mc->windowIcon());
+ setWindowTitle(tr("%1 - %2[*]").arg(mc->windowTitle()).arg(fileNameTitle));
+ } else {
+ setWindowTitle(fileNameTitle);
+ }
+}
+
+void QDesignerFormWindow::closeEvent(QCloseEvent *ev)
+{
+ if (m_editor->isDirty()) {
+ raise();
+ QMessageBox box(QMessageBox::Information, tr("Save Form?"),
+ tr("Do you want to save the changes to this document before closing?"),
+ QMessageBox::Discard | QMessageBox::Cancel | QMessageBox::Save, m_editor);
+ box.setInformativeText(tr("If you don't save, your changes will be lost."));
+ box.setWindowModality(Qt::WindowModal);
+ static_cast<QPushButton *>(box.button(QMessageBox::Save))->setDefault(true);
+
+ switch (box.exec()) {
+ case QMessageBox::Save: {
+ bool ok = workbench()->saveForm(m_editor);
+ ev->setAccepted(ok);
+ m_editor->setDirty(!ok);
+ break;
+ }
+ case QMessageBox::Discard:
+ m_editor->setDirty(false); // Not really necessary, but stops problems if we get close again.
+ ev->accept();
+ break;
+ case QMessageBox::Cancel:
+ ev->ignore();
+ break;
+ }
+ }
+}
+
+void QDesignerFormWindow::updateChanged()
+{
+ // Sometimes called after form window destruction.
+ if (m_editor) {
+ setWindowModified(m_editor->isDirty());
+ updateWindowTitle(m_editor->fileName());
+ }
+}
+
+void QDesignerFormWindow::resizeEvent(QResizeEvent *rev)
+{
+ if(m_initialized) {
+ m_editor->setDirty(true);
+ setWindowModified(true);
+ }
+
+ m_initialized = true;
+ QWidget::resizeEvent(rev);
+}
+
+void QDesignerFormWindow::geometryChanged()
+{
+ // If the form window changes, re-update the geometry of the current widget in the property editor.
+ // Note that in the case of layouts, non-maincontainer widgets must also be updated,
+ // so, do not do it for the main container only
+ const QDesignerFormEditorInterface *core = m_editor->core();
+ QObject *object = core->propertyEditor()->object();
+ if (object == 0 || !object->isWidgetType())
+ return;
+ static const QString geometryProperty = QLatin1String("geometry");
+ const QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), object);
+ const int geometryIndex = sheet->indexOf(geometryProperty);
+ if (geometryIndex == -1)
+ return;
+ core->propertyEditor()->setPropertyValue(geometryProperty, sheet->property(geometryIndex));
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/designer/qdesigner_formwindow.h b/src/designer/src/designer/qdesigner_formwindow.h
new file mode 100644
index 000000000..5ee4c40b4
--- /dev/null
+++ b/src/designer/src/designer/qdesigner_formwindow.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDESIGNER_FORMWINDOW_H
+#define QDESIGNER_FORMWINDOW_H
+
+#include <QtCore/QPointer>
+#include <QtGui/QWidget>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerWorkbench;
+class QDesignerFormWindowInterface;
+
+class QDesignerFormWindow: public QWidget
+{
+ Q_OBJECT
+public:
+ QDesignerFormWindow(QDesignerFormWindowInterface *formWindow, QDesignerWorkbench *workbench,
+ QWidget *parent = 0, Qt::WindowFlags flags = 0);
+
+ void firstShow();
+
+ virtual ~QDesignerFormWindow();
+
+ QAction *action() const;
+ QDesignerWorkbench *workbench() const;
+ QDesignerFormWindowInterface *editor() const;
+
+ QRect geometryHint() const;
+
+public slots:
+ void updateChanged();
+
+private slots:
+ void updateWindowTitle(const QString &fileName);
+ void geometryChanged();
+
+signals:
+ void minimizationStateChanged(QDesignerFormWindowInterface *formWindow, bool minimized);
+ void triggerAction();
+
+protected:
+ virtual void changeEvent(QEvent *e);
+ virtual void closeEvent(QCloseEvent *ev);
+ virtual void resizeEvent(QResizeEvent* rev);
+
+private:
+ int getNumberOfUntitledWindows() const;
+ QPointer<QDesignerFormWindowInterface> m_editor;
+ QPointer<QDesignerWorkbench> m_workbench;
+ QAction *m_action;
+ bool m_initialized;
+ bool m_windowTitleInitialized;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_FORMWINDOW_H
diff --git a/src/designer/src/designer/qdesigner_pch.h b/src/designer/src/designer/qdesigner_pch.h
new file mode 100644
index 000000000..12eb3f376
--- /dev/null
+++ b/src/designer/src/designer/qdesigner_pch.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#if defined __cplusplus
+#include <QtCore/QObject>
+#include <QtCore/QPointer>
+#include <QtCore/QSettings>
+#include <QtCore/qdebug.h>
+#include <QtGui/QCloseEvent>
+#include <QtGui/QHeaderView>
+#include <QtGui/QMessageBox>
+#include <QtGui/QVBoxLayout>
+#include <QtDesigner/abstractformeditor.h>
+#include <QtDesigner/abstractformwindow.h>
+
+#include "qdesigner.h"
+#include "qdesigner_formwindow.h"
+#include "qdesigner_settings.h"
+#include "qdesigner_toolwindow.h"
+#include "qdesigner_workbench.h"
+#endif
diff --git a/src/designer/src/designer/qdesigner_server.cpp b/src/designer/src/designer/qdesigner_server.cpp
new file mode 100644
index 000000000..bffee5b7e
--- /dev/null
+++ b/src/designer/src/designer/qdesigner_server.cpp
@@ -0,0 +1,156 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QFileInfo>
+#include <QtCore/QStringList>
+
+#include <QtNetwork/QHostAddress>
+#include <QtNetwork/QTcpServer>
+#include <QtNetwork/QTcpSocket>
+
+#include "qdesigner.h"
+#include "qdesigner_server.h"
+
+#include <qevent.h>
+
+QT_BEGIN_NAMESPACE
+
+// ### review
+
+QDesignerServer::QDesignerServer(QObject *parent)
+ : QObject(parent)
+{
+ m_socket = 0;
+ m_server = new QTcpServer(this);
+ m_server->listen(QHostAddress::LocalHost, 0);
+ if (m_server->isListening())
+ {
+ connect(m_server, SIGNAL(newConnection()),
+ this, SLOT(handleNewConnection()));
+ }
+}
+
+QDesignerServer::~QDesignerServer()
+{
+}
+
+quint16 QDesignerServer::serverPort() const
+{
+ return m_server ? m_server->serverPort() : 0;
+}
+
+void QDesignerServer::sendOpenRequest(int port, const QStringList &files)
+{
+ QTcpSocket *sSocket = new QTcpSocket();
+ sSocket->connectToHost(QHostAddress::LocalHost, port);
+ if(sSocket->waitForConnected(3000))
+ {
+ foreach(const QString &file, files)
+ {
+ QFileInfo fi(file);
+ sSocket->write(fi.absoluteFilePath().toUtf8() + '\n');
+ }
+ sSocket->waitForBytesWritten(3000);
+ sSocket->close();
+ }
+ delete sSocket;
+}
+
+void QDesignerServer::readFromClient()
+{
+ while (m_socket->canReadLine()) {
+ QString file = QString::fromUtf8(m_socket->readLine());
+ if (!file.isNull()) {
+ file.remove(QLatin1Char('\n'));
+ file.remove(QLatin1Char('\r'));
+ qDesigner->postEvent(qDesigner, new QFileOpenEvent(file));
+ }
+ }
+}
+
+void QDesignerServer::socketClosed()
+{
+ m_socket = 0;
+}
+
+void QDesignerServer::handleNewConnection()
+{
+ // no need for more than one connection
+ if (m_socket == 0) {
+ m_socket = m_server->nextPendingConnection();
+ connect(m_socket, SIGNAL(readyRead()),
+ this, SLOT(readFromClient()));
+ connect(m_socket, SIGNAL(disconnected()),
+ this, SLOT(socketClosed()));
+ }
+}
+
+
+QDesignerClient::QDesignerClient(quint16 port, QObject *parent)
+: QObject(parent)
+{
+ m_socket = new QTcpSocket(this);
+ m_socket->connectToHost(QHostAddress::LocalHost, port);
+ connect(m_socket, SIGNAL(readyRead()),
+ this, SLOT(readFromSocket()));
+
+}
+
+QDesignerClient::~QDesignerClient()
+{
+ m_socket->close();
+ m_socket->flush();
+}
+
+void QDesignerClient::readFromSocket()
+{
+ while (m_socket->canReadLine()) {
+ QString file = QString::fromUtf8(m_socket->readLine());
+ if (!file.isNull()) {
+ file.remove(QLatin1Char('\n'));
+ file.remove(QLatin1Char('\r'));
+ if (QFile::exists(file))
+ qDesigner->postEvent(qDesigner, new QFileOpenEvent(file));
+ }
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/designer/qdesigner_server.h b/src/designer/src/designer/qdesigner_server.h
new file mode 100644
index 000000000..3aeeebdee
--- /dev/null
+++ b/src/designer/src/designer/qdesigner_server.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDESIGNER_SERVER_H
+#define QDESIGNER_SERVER_H
+
+#include <QtCore/QObject>
+
+QT_BEGIN_NAMESPACE
+
+class QTcpServer;
+class QTcpSocket;
+
+class QDesignerServer: public QObject
+{
+ Q_OBJECT
+public:
+ explicit QDesignerServer(QObject *parent = 0);
+ virtual ~QDesignerServer();
+
+ quint16 serverPort() const;
+
+ static void sendOpenRequest(int port, const QStringList &files);
+
+private slots:
+ void handleNewConnection();
+ void readFromClient();
+ void socketClosed();
+
+private:
+ QTcpServer *m_server;
+ QTcpSocket *m_socket;
+};
+
+class QDesignerClient: public QObject
+{
+ Q_OBJECT
+public:
+ explicit QDesignerClient(quint16 port, QObject *parent = 0);
+ virtual ~QDesignerClient();
+
+private slots:
+ void readFromSocket();
+
+private:
+ QTcpSocket *m_socket;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_SERVER_H
diff --git a/src/designer/src/designer/qdesigner_settings.cpp b/src/designer/src/designer/qdesigner_settings.cpp
new file mode 100644
index 000000000..89bec14f2
--- /dev/null
+++ b/src/designer/src/designer/qdesigner_settings.cpp
@@ -0,0 +1,250 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner.h"
+#include "qdesigner_settings.h"
+#include "qdesigner_toolwindow.h"
+#include "qdesigner_workbench.h"
+
+#include <abstractformeditor.h>
+#include <abstractsettings_p.h>
+#include <qdesigner_utils_p.h>
+#include <previewmanager_p.h>
+
+#include <QtCore/QVariant>
+#include <QtCore/QDir>
+
+#include <QtGui/QDesktopWidget>
+#include <QtGui/QStyle>
+#include <QtGui/QListView>
+
+#include <QtCore/qdebug.h>
+
+enum { debugSettings = 0 };
+
+QT_BEGIN_NAMESPACE
+
+static const char *newFormShowKey = "newFormDialog/ShowOnStartup";
+
+// Change the version whenever the arrangement changes significantly.
+static const char *mainWindowStateKey = "MainWindowState45";
+static const char *toolBarsStateKey = "ToolBarsState45";
+
+static const char *backupOrgListKey = "backup/fileListOrg";
+static const char *backupBakListKey = "backup/fileListBak";
+static const char *recentFilesListKey = "recentFilesList";
+
+QDesignerSettings::QDesignerSettings(QDesignerFormEditorInterface *core) :
+ qdesigner_internal::QDesignerSharedSettings(core)
+{
+}
+
+void QDesignerSettings::setValue(const QString &key, const QVariant &value)
+{
+ settings()->setValue(key, value);
+}
+
+QVariant QDesignerSettings::value(const QString &key, const QVariant &defaultValue) const
+{
+ return settings()->value(key, defaultValue);
+}
+
+static inline QChar modeChar(UIMode mode)
+{
+ return QLatin1Char(static_cast<char>(mode) + '0');
+}
+
+void QDesignerSettings::saveGeometryFor(const QWidget *w)
+{
+ Q_ASSERT(w && !w->objectName().isEmpty());
+ QDesignerSettingsInterface *s = settings();
+ const bool visible = w->isVisible();
+ if (debugSettings)
+ qDebug() << Q_FUNC_INFO << w << "visible=" << visible;
+ s->beginGroup(w->objectName());
+ s->setValue(QLatin1String("visible"), visible);
+ s->setValue(QLatin1String("geometry"), w->saveGeometry());
+ s->endGroup();
+}
+
+void QDesignerSettings::restoreGeometry(QWidget *w, QRect fallBack) const
+{
+ Q_ASSERT(w && !w->objectName().isEmpty());
+ const QString key = w->objectName();
+ const QByteArray ba(settings()->value(key + QLatin1String("/geometry")).toByteArray());
+ const bool visible = settings()->value(key + QLatin1String("/visible"), true).toBool();
+
+ if (debugSettings)
+ qDebug() << Q_FUNC_INFO << w << fallBack << "visible=" << visible;
+ if (ba.isEmpty()) {
+ /// Apply default geometry, check for null and maximal size
+ if (fallBack.isNull())
+ fallBack = QRect(QPoint(0, 0), w->sizeHint());
+ if (fallBack.size() == QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)) {
+ w->setWindowState(w->windowState() | Qt::WindowMaximized);
+ } else {
+ w->move(fallBack.topLeft());
+ w->resize(fallBack.size());
+ }
+ } else {
+ w->restoreGeometry(ba);
+ }
+
+ if (visible)
+ w->show();
+}
+
+QStringList QDesignerSettings::recentFilesList() const
+{
+ return settings()->value(QLatin1String(recentFilesListKey)).toStringList();
+}
+
+void QDesignerSettings::setRecentFilesList(const QStringList &sl)
+{
+ settings()->setValue(QLatin1String(recentFilesListKey), sl);
+}
+
+void QDesignerSettings::setShowNewFormOnStartup(bool showIt)
+{
+ settings()->setValue(QLatin1String(newFormShowKey), showIt);
+}
+
+bool QDesignerSettings::showNewFormOnStartup() const
+{
+ return settings()->value(QLatin1String(newFormShowKey), true).toBool();
+}
+
+QByteArray QDesignerSettings::mainWindowState(UIMode mode) const
+{
+ return settings()->value(QLatin1String(mainWindowStateKey) + modeChar(mode)).toByteArray();
+}
+
+void QDesignerSettings::setMainWindowState(UIMode mode, const QByteArray &mainWindowState)
+{
+ settings()->setValue(QLatin1String(mainWindowStateKey) + modeChar(mode), mainWindowState);
+}
+
+QByteArray QDesignerSettings::toolBarsState(UIMode mode) const
+{
+ QString key = QLatin1String(toolBarsStateKey);
+ key += modeChar(mode);
+ return settings()->value(key).toByteArray();
+}
+
+void QDesignerSettings::setToolBarsState(UIMode mode, const QByteArray &toolBarsState)
+{
+ QString key = QLatin1String(toolBarsStateKey);
+ key += modeChar(mode);
+ settings()->setValue(key, toolBarsState);
+}
+
+void QDesignerSettings::clearBackup()
+{
+ QDesignerSettingsInterface *s = settings();
+ s->remove(QLatin1String(backupOrgListKey));
+ s->remove(QLatin1String(backupBakListKey));
+}
+
+void QDesignerSettings::setBackup(const QMap<QString, QString> &map)
+{
+ const QStringList org = map.keys();
+ const QStringList bak = map.values();
+
+ QDesignerSettingsInterface *s = settings();
+ s->setValue(QLatin1String(backupOrgListKey), org);
+ s->setValue(QLatin1String(backupBakListKey), bak);
+}
+
+QMap<QString, QString> QDesignerSettings::backup() const
+{
+ const QStringList org = settings()->value(QLatin1String(backupOrgListKey), QStringList()).toStringList();
+ const QStringList bak = settings()->value(QLatin1String(backupBakListKey), QStringList()).toStringList();
+
+ QMap<QString, QString> map;
+ const int orgCount = org.count();
+ for (int i = 0; i < orgCount; ++i)
+ map.insert(org.at(i), bak.at(i));
+
+ return map;
+}
+
+void QDesignerSettings::setUiMode(UIMode mode)
+{
+ QDesignerSettingsInterface *s = settings();
+ s->beginGroup(QLatin1String("UI"));
+ s->setValue(QLatin1String("currentMode"), mode);
+ s->endGroup();
+}
+
+UIMode QDesignerSettings::uiMode() const
+{
+#ifdef Q_WS_MAC
+ const UIMode defaultMode = TopLevelMode;
+#else
+ const UIMode defaultMode = DockedMode;
+#endif
+ UIMode uiMode = static_cast<UIMode>(value(QLatin1String("UI/currentMode"), defaultMode).toInt());
+ return uiMode;
+}
+
+void QDesignerSettings::setToolWindowFont(const ToolWindowFontSettings &fontSettings)
+{
+ QDesignerSettingsInterface *s = settings();
+ s->beginGroup(QLatin1String("UI"));
+ s->setValue(QLatin1String("font"), fontSettings.m_font);
+ s->setValue(QLatin1String("useFont"), fontSettings.m_useFont);
+ s->setValue(QLatin1String("writingSystem"), fontSettings.m_writingSystem);
+ s->endGroup();
+}
+
+ToolWindowFontSettings QDesignerSettings::toolWindowFont() const
+{
+ ToolWindowFontSettings fontSettings;
+ fontSettings.m_writingSystem =
+ static_cast<QFontDatabase::WritingSystem>(value(QLatin1String("UI/writingSystem"),
+ QFontDatabase::Any).toInt());
+ fontSettings.m_font = qvariant_cast<QFont>(value(QLatin1String("UI/font")));
+ fontSettings.m_useFont =
+ settings()->value(QLatin1String("UI/useFont"), QVariant(false)).toBool();
+ return fontSettings;
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/designer/qdesigner_settings.h b/src/designer/src/designer/qdesigner_settings.h
new file mode 100644
index 000000000..2391581b8
--- /dev/null
+++ b/src/designer/src/designer/qdesigner_settings.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDESIGNER_SETTINGS_H
+#define QDESIGNER_SETTINGS_H
+
+#include "designer_enums.h"
+#include <shared_settings_p.h>
+#include <QtCore/QMap>
+#include <QtCore/QRect>
+#include <QtCore/QStringList>
+#include <QtCore/QVariant>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+class QDesignerSettingsInterface;
+struct ToolWindowFontSettings;
+
+class QDesignerSettings : public qdesigner_internal::QDesignerSharedSettings
+{
+public:
+ QDesignerSettings(QDesignerFormEditorInterface *core);
+
+ void setValue(const QString &key, const QVariant &value);
+ QVariant value(const QString &key, const QVariant &defaultValue = QVariant()) const;
+
+ void restoreGeometry(QWidget *w, QRect fallBack = QRect()) const;
+ void saveGeometryFor(const QWidget *w);
+
+ QStringList recentFilesList() const;
+ void setRecentFilesList(const QStringList &list);
+
+ void setShowNewFormOnStartup(bool showIt);
+ bool showNewFormOnStartup() const;
+
+ void setUiMode(UIMode mode);
+ UIMode uiMode() const;
+
+ void setToolWindowFont(const ToolWindowFontSettings &fontSettings);
+ ToolWindowFontSettings toolWindowFont() const;
+
+ QByteArray mainWindowState(UIMode mode) const;
+ void setMainWindowState(UIMode mode, const QByteArray &mainWindowState);
+
+ QByteArray toolBarsState(UIMode mode) const;
+ void setToolBarsState(UIMode mode, const QByteArray &mainWindowState);
+
+ void clearBackup();
+ void setBackup(const QMap<QString, QString> &map);
+ QMap<QString, QString> backup() const;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_SETTINGS_H
diff --git a/src/designer/src/designer/qdesigner_toolwindow.cpp b/src/designer/src/designer/qdesigner_toolwindow.cpp
new file mode 100644
index 000000000..376b0afae
--- /dev/null
+++ b/src/designer/src/designer/qdesigner_toolwindow.cpp
@@ -0,0 +1,438 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner.h"
+#include "qdesigner_toolwindow.h"
+#include "qdesigner_settings.h"
+#include "qdesigner_workbench.h"
+
+#include <QtDesigner/QDesignerPropertyEditorInterface>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerActionEditorInterface>
+#include <QtDesigner/QDesignerObjectInspectorInterface>
+#include <QtDesigner/QDesignerWidgetBoxInterface>
+#include <QtDesigner/QDesignerComponents>
+
+#include <QtCore/QEvent>
+#include <QtCore/QDebug>
+#include <QtGui/QAction>
+#include <QtGui/QCloseEvent>
+
+enum { debugToolWindow = 0 };
+
+QT_BEGIN_NAMESPACE
+
+// ---------------- QDesignerToolWindowFontSettings
+ToolWindowFontSettings::ToolWindowFontSettings() :
+ m_writingSystem(QFontDatabase::Any),
+ m_useFont(false)
+{
+}
+
+bool ToolWindowFontSettings::equals(const ToolWindowFontSettings &rhs) const
+{
+ return m_useFont == rhs.m_useFont &&
+ m_writingSystem == rhs.m_writingSystem &&
+ m_font == rhs.m_font;
+}
+
+// ---------------- QDesignerToolWindow
+QDesignerToolWindow::QDesignerToolWindow(QDesignerWorkbench *workbench,
+ QWidget *w,
+ const QString &objectName,
+ const QString &title,
+ const QString &actionObjectName,
+ Qt::DockWidgetArea dockAreaHint,
+ QWidget *parent,
+ Qt::WindowFlags flags) :
+ MainWindowBase(parent, flags),
+ m_dockAreaHint(dockAreaHint),
+ m_workbench(workbench),
+ m_action(new QAction(this))
+{
+ setObjectName(objectName);
+ setCentralWidget(w);
+
+ setWindowTitle(title);
+
+ m_action->setObjectName(actionObjectName);
+ m_action->setShortcutContext(Qt::ApplicationShortcut);
+ m_action->setText(title);
+ m_action->setCheckable(true);
+ connect(m_action, SIGNAL(triggered(bool)), this, SLOT(showMe(bool)));
+}
+
+void QDesignerToolWindow::showMe(bool v)
+{
+ // Access the QMdiSubWindow in MDI mode.
+ if (QWidget *target = m_workbench->mode() == DockedMode ? parentWidget() : this) {
+ if (v)
+ target->setWindowState(target->windowState() & ~Qt::WindowMinimized);
+ target->setVisible(v);
+ }
+}
+
+void QDesignerToolWindow::showEvent(QShowEvent *e)
+{
+ Q_UNUSED(e);
+
+ bool blocked = m_action->blockSignals(true);
+ m_action->setChecked(true);
+ m_action->blockSignals(blocked);
+}
+
+void QDesignerToolWindow::hideEvent(QHideEvent *e)
+{
+ Q_UNUSED(e);
+
+ bool blocked = m_action->blockSignals(true);
+ m_action->setChecked(false);
+ m_action->blockSignals(blocked);
+}
+
+QAction *QDesignerToolWindow::action() const
+{
+ return m_action;
+}
+
+void QDesignerToolWindow::changeEvent(QEvent *e)
+{
+ switch (e->type()) {
+ case QEvent::WindowTitleChange:
+ m_action->setText(windowTitle());
+ break;
+ case QEvent::WindowIconChange:
+ m_action->setIcon(windowIcon());
+ break;
+ default:
+ break;
+ }
+ QMainWindow::changeEvent(e);
+}
+
+QDesignerWorkbench *QDesignerToolWindow::workbench() const
+{
+ return m_workbench;
+}
+
+QRect QDesignerToolWindow::geometryHint() const
+{
+ return QRect();
+}
+
+QRect QDesignerToolWindow::availableToolWindowGeometry() const
+{
+ return m_workbench->availableGeometry();
+}
+
+// ---------------------- PropertyEditorToolWindow
+
+static inline QWidget *createPropertyEditor(QDesignerFormEditorInterface *core, QWidget *parent = 0)
+{
+ QDesignerPropertyEditorInterface *widget = QDesignerComponents::createPropertyEditor(core, parent);
+ core->setPropertyEditor(widget);
+ return widget;
+}
+
+class PropertyEditorToolWindow : public QDesignerToolWindow
+{
+public:
+ explicit PropertyEditorToolWindow(QDesignerWorkbench *workbench);
+
+ virtual QRect geometryHint() const;
+
+protected:
+ virtual void showEvent(QShowEvent *event);
+};
+
+PropertyEditorToolWindow::PropertyEditorToolWindow(QDesignerWorkbench *workbench) :
+ QDesignerToolWindow(workbench,
+ createPropertyEditor(workbench->core()),
+ QLatin1String("qt_designer_propertyeditor"),
+ QDesignerToolWindow::tr("Property Editor"),
+ QLatin1String("__qt_property_editor_action"),
+ Qt::RightDockWidgetArea)
+{
+ action()->setShortcut(Qt::CTRL + Qt::Key_I);
+
+}
+
+QRect PropertyEditorToolWindow::geometryHint() const
+{
+ const QRect g = availableToolWindowGeometry();
+ const int margin = workbench()->marginHint();
+ const int spacing = 40;
+ const QSize sz(g.width() * 1/4, g.height() * 4/6);
+
+ const QRect rc = QRect((g.right() + 1 - sz.width() - margin),
+ (g.top() + margin + g.height() * 1/6) + spacing,
+ sz.width(), sz.height());
+ if (debugToolWindow)
+ qDebug() << Q_FUNC_INFO << rc;
+ return rc;
+}
+
+void PropertyEditorToolWindow::showEvent(QShowEvent *event)
+{
+ if (QDesignerPropertyEditorInterface *e = workbench()->core()->propertyEditor()) {
+ // workaround to update the propertyeditor when it is not visible!
+ e->setObject(e->object()); // ### remove me
+ }
+
+ QDesignerToolWindow::showEvent(event);
+}
+
+// ---------------------- ActionEditorToolWindow
+
+static inline QWidget *createActionEditor(QDesignerFormEditorInterface *core, QWidget *parent = 0)
+{
+ QDesignerActionEditorInterface *widget = QDesignerComponents::createActionEditor(core, parent);
+ core->setActionEditor(widget);
+ return widget;
+}
+
+class ActionEditorToolWindow: public QDesignerToolWindow
+{
+public:
+ explicit ActionEditorToolWindow(QDesignerWorkbench *workbench);
+
+ virtual QRect geometryHint() const;
+};
+
+ActionEditorToolWindow::ActionEditorToolWindow(QDesignerWorkbench *workbench) :
+ QDesignerToolWindow(workbench,
+ createActionEditor(workbench->core()),
+ QLatin1String("qt_designer_actioneditor"),
+ QDesignerToolWindow::tr("Action Editor"),
+ QLatin1String("__qt_action_editor_tool_action"),
+ Qt::RightDockWidgetArea)
+{
+}
+
+QRect ActionEditorToolWindow::geometryHint() const
+{
+ const QRect g = availableToolWindowGeometry();
+ const int margin = workbench()->marginHint();
+
+ const QSize sz(g.width() * 1/4, g.height() * 1/6);
+
+ const QRect rc = QRect((g.right() + 1 - sz.width() - margin),
+ g.top() + margin,
+ sz.width(), sz.height());
+ if (debugToolWindow)
+ qDebug() << Q_FUNC_INFO << rc;
+ return rc;
+}
+
+// ---------------------- ObjectInspectorToolWindow
+
+static inline QWidget *createObjectInspector(QDesignerFormEditorInterface *core, QWidget *parent = 0)
+{
+ QDesignerObjectInspectorInterface *widget = QDesignerComponents::createObjectInspector(core, parent);
+ core->setObjectInspector(widget);
+ return widget;
+}
+
+class ObjectInspectorToolWindow: public QDesignerToolWindow
+{
+public:
+ explicit ObjectInspectorToolWindow(QDesignerWorkbench *workbench);
+
+ virtual QRect geometryHint() const;
+};
+
+ObjectInspectorToolWindow::ObjectInspectorToolWindow(QDesignerWorkbench *workbench) :
+ QDesignerToolWindow(workbench,
+ createObjectInspector(workbench->core()),
+ QLatin1String("qt_designer_objectinspector"),
+ QDesignerToolWindow::tr("Object Inspector"),
+ QLatin1String("__qt_object_inspector_tool_action"),
+ Qt::RightDockWidgetArea)
+{
+}
+
+QRect ObjectInspectorToolWindow::geometryHint() const
+{
+ const QRect g = availableToolWindowGeometry();
+ const int margin = workbench()->marginHint();
+
+ const QSize sz(g.width() * 1/4, g.height() * 1/6);
+
+ const QRect rc = QRect((g.right() + 1 - sz.width() - margin),
+ g.top() + margin,
+ sz.width(), sz.height());
+ if (debugToolWindow)
+ qDebug() << Q_FUNC_INFO << rc;
+ return rc;
+}
+
+// ---------------------- ResourceEditorToolWindow
+
+class ResourceEditorToolWindow: public QDesignerToolWindow
+{
+public:
+ explicit ResourceEditorToolWindow(QDesignerWorkbench *workbench);
+
+ virtual QRect geometryHint() const;
+};
+
+ResourceEditorToolWindow::ResourceEditorToolWindow(QDesignerWorkbench *workbench) :
+ QDesignerToolWindow(workbench,
+ QDesignerComponents::createResourceEditor(workbench->core(), 0),
+ QLatin1String("qt_designer_resourceeditor"),
+ QDesignerToolWindow::tr("Resource Browser"),
+ QLatin1String("__qt_resource_editor_tool_action"),
+ Qt::RightDockWidgetArea)
+{
+}
+
+QRect ResourceEditorToolWindow::geometryHint() const
+{
+ const QRect g = availableToolWindowGeometry();
+ const int margin = workbench()->marginHint();
+
+ const QSize sz(g.width() * 1/3, g.height() * 1/6);
+ QRect r(QPoint(0, 0), sz);
+ r.moveCenter(g.center());
+ r.moveBottom(g.bottom() - margin);
+ if (debugToolWindow)
+ qDebug() << Q_FUNC_INFO << r;
+ return r;
+}
+
+// ---------------------- SignalSlotEditorToolWindow
+
+class SignalSlotEditorToolWindow: public QDesignerToolWindow
+{
+public:
+ explicit SignalSlotEditorToolWindow(QDesignerWorkbench *workbench);
+
+ virtual QRect geometryHint() const;
+};
+
+SignalSlotEditorToolWindow::SignalSlotEditorToolWindow(QDesignerWorkbench *workbench) :
+ QDesignerToolWindow(workbench,
+ QDesignerComponents::createSignalSlotEditor(workbench->core(), 0),
+ QLatin1String("qt_designer_signalsloteditor"),
+ QDesignerToolWindow::tr("Signal/Slot Editor"),
+ QLatin1String("__qt_signal_slot_editor_tool_action"),
+ Qt::RightDockWidgetArea)
+{
+}
+
+QRect SignalSlotEditorToolWindow::geometryHint() const
+{
+ const QRect g = availableToolWindowGeometry();
+ const int margin = workbench()->marginHint();
+
+ const QSize sz(g.width() * 1/3, g.height() * 1/6);
+ QRect r(QPoint(0, 0), sz);
+ r.moveCenter(g.center());
+ r.moveTop(margin + g.top());
+ if (debugToolWindow)
+ qDebug() << Q_FUNC_INFO << r;
+ return r;
+}
+
+// ---------------------- WidgetBoxToolWindow
+
+static inline QWidget *createWidgetBox(QDesignerFormEditorInterface *core, QWidget *parent = 0)
+{
+ QDesignerWidgetBoxInterface *widget = QDesignerComponents::createWidgetBox(core, parent);
+ core->setWidgetBox(widget);
+ return widget;
+}
+
+class WidgetBoxToolWindow: public QDesignerToolWindow
+{
+public:
+ explicit WidgetBoxToolWindow(QDesignerWorkbench *workbench);
+
+ virtual QRect geometryHint() const;
+};
+
+WidgetBoxToolWindow::WidgetBoxToolWindow(QDesignerWorkbench *workbench) :
+ QDesignerToolWindow(workbench,
+ createWidgetBox(workbench->core()),
+ QLatin1String("qt_designer_widgetbox"),
+ QDesignerToolWindow::tr("Widget Box"),
+ QLatin1String("__qt_widget_box_tool_action"),
+ Qt::LeftDockWidgetArea)
+{
+}
+
+QRect WidgetBoxToolWindow::geometryHint() const
+{
+ const QRect g = availableToolWindowGeometry();
+ const int margin = workbench()->marginHint();
+ const QRect rc = QRect(g.left() + margin,
+ g.top() + margin,
+ g.width() * 1/4, g.height() * 5/6);
+ if (debugToolWindow)
+ qDebug() << Q_FUNC_INFO << rc;
+ return rc;
+}
+
+// -- Factory
+QDesignerToolWindow *QDesignerToolWindow::createStandardToolWindow(StandardToolWindow which,
+ QDesignerWorkbench *workbench)
+{
+ switch (which) {
+ case ActionEditor:
+ return new ActionEditorToolWindow(workbench);
+ case ResourceEditor:
+ return new ResourceEditorToolWindow(workbench);
+ case SignalSlotEditor:
+ return new SignalSlotEditorToolWindow(workbench);
+ case PropertyEditor:
+ return new PropertyEditorToolWindow(workbench);
+ case ObjectInspector:
+ return new ObjectInspectorToolWindow(workbench);
+ case WidgetBox:
+ return new WidgetBoxToolWindow(workbench);
+ default:
+ break;
+ }
+ return 0;
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/designer/qdesigner_toolwindow.h b/src/designer/src/designer/qdesigner_toolwindow.h
new file mode 100644
index 000000000..1c7b876d1
--- /dev/null
+++ b/src/designer/src/designer/qdesigner_toolwindow.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDESIGNER_TOOLWINDOW_H
+#define QDESIGNER_TOOLWINDOW_H
+
+#include "mainwindow.h"
+
+#include <QtCore/QPointer>
+#include <QtGui/QFontDatabase>
+#include <QtGui/QMainWindow>
+
+QT_BEGIN_NAMESPACE
+
+struct ToolWindowFontSettings {
+ ToolWindowFontSettings();
+ bool equals(const ToolWindowFontSettings &) const;
+
+ QFont m_font;
+ QFontDatabase::WritingSystem m_writingSystem;
+ bool m_useFont;
+};
+
+inline bool operator==(const ToolWindowFontSettings &tw1, const ToolWindowFontSettings &tw2)
+{
+ return tw1.equals(tw2);
+}
+
+inline bool operator!=(const ToolWindowFontSettings &tw1, const ToolWindowFontSettings &tw2)
+{
+ return !tw1.equals(tw2);
+}
+
+class QDesignerWorkbench;
+
+/* A tool window with an action that activates it. Note that in toplevel mode,
+ * the Widget box is a tool window as well as the applications' main window,
+ * So, we need to inherit from MainWindowBase. */
+
+class QDesignerToolWindow : public MainWindowBase
+{
+ Q_OBJECT
+protected:
+ explicit QDesignerToolWindow(QDesignerWorkbench *workbench,
+ QWidget *w,
+ const QString &objectName,
+ const QString &title,
+ const QString &actionObjectName,
+ Qt::DockWidgetArea dockAreaHint,
+ QWidget *parent = 0,
+ Qt::WindowFlags flags = Qt::Window);
+
+public:
+ // Note: The order influences the dock widget position.
+ enum StandardToolWindow { WidgetBox, ObjectInspector, PropertyEditor,
+ ResourceEditor, ActionEditor, SignalSlotEditor,
+ StandardToolWindowCount };
+
+ static QDesignerToolWindow *createStandardToolWindow(StandardToolWindow which, QDesignerWorkbench *workbench);
+
+ QDesignerWorkbench *workbench() const;
+ QAction *action() const;
+
+ Qt::DockWidgetArea dockWidgetAreaHint() const { return m_dockAreaHint; }
+ virtual QRect geometryHint() const;
+
+private slots:
+ void showMe(bool);
+
+protected:
+ virtual void showEvent(QShowEvent *e);
+ virtual void hideEvent(QHideEvent *e);
+ virtual void changeEvent(QEvent *e);
+
+ QRect availableToolWindowGeometry() const;
+
+private:
+ const Qt::DockWidgetArea m_dockAreaHint;
+ QDesignerWorkbench *m_workbench;
+ QAction *m_action;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_TOOLWINDOW_H
diff --git a/src/designer/src/designer/qdesigner_workbench.cpp b/src/designer/src/designer/qdesigner_workbench.cpp
new file mode 100644
index 000000000..ffc4b8c7a
--- /dev/null
+++ b/src/designer/src/designer/qdesigner_workbench.cpp
@@ -0,0 +1,1100 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_workbench.h"
+#include "qdesigner.h"
+#include "qdesigner_actions.h"
+#include "qdesigner_appearanceoptions.h"
+#include "qdesigner_settings.h"
+#include "qdesigner_toolwindow.h"
+#include "qdesigner_formwindow.h"
+#include "appfontdialog.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerFormWindowInterface>
+#include <QtDesigner/QDesignerFormWindowManagerInterface>
+#include <QtDesigner/QDesignerFormEditorPluginInterface>
+#include <QtDesigner/QDesignerWidgetBoxInterface>
+#include <QtDesigner/QDesignerMetaDataBaseInterface>
+
+#include <QtDesigner/QDesignerComponents>
+#include <QtDesigner/private/qdesigner_integration_p.h>
+#include <QtDesigner/private/pluginmanager_p.h>
+#include <QtDesigner/private/formwindowbase_p.h>
+#include <QtDesigner/private/actioneditor_p.h>
+
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtCore/QUrl>
+#include <QtCore/QTimer>
+#include <QtCore/QPluginLoader>
+#include <QtCore/qdebug.h>
+
+#include <QtGui/QActionGroup>
+#include <QtGui/QCloseEvent>
+#include <QtGui/QDesktopWidget>
+#include <QtGui/QDockWidget>
+#include <QtGui/QMenu>
+#include <QtGui/QMenuBar>
+#include <QtGui/QMessageBox>
+#include <QtGui/QPushButton>
+#include <QtGui/QToolBar>
+#include <QtGui/QMdiArea>
+#include <QtGui/QMdiSubWindow>
+#include <QtGui/QLayout>
+
+QT_BEGIN_NAMESPACE
+
+static const char *appFontPrefixC = "AppFonts";
+
+typedef QList<QAction *> ActionList;
+
+static QMdiSubWindow *mdiSubWindowOf(const QWidget *w)
+{
+ QMdiSubWindow *rc = qobject_cast<QMdiSubWindow *>(w->parentWidget());
+ Q_ASSERT(rc);
+ return rc;
+}
+
+static QDockWidget *dockWidgetOf(const QWidget *w)
+{
+ for (QWidget *parentWidget = w->parentWidget(); parentWidget ; parentWidget = parentWidget->parentWidget()) {
+ if (QDockWidget *dw = qobject_cast<QDockWidget *>(parentWidget)) {
+ return dw;
+ }
+ }
+ Q_ASSERT("Dock widget not found");
+ return 0;
+}
+
+// ------------ QDesignerWorkbench::Position
+QDesignerWorkbench::Position::Position(const QMdiSubWindow *mdiSubWindow, const QPoint &mdiAreaOffset) :
+ m_minimized(mdiSubWindow->isShaded()),
+ m_position(mdiSubWindow->pos() + mdiAreaOffset)
+{
+}
+
+QDesignerWorkbench::Position::Position(const QDockWidget *dockWidget) :
+ m_minimized(dockWidget->isMinimized()),
+ m_position(dockWidget->pos())
+{
+}
+
+QDesignerWorkbench::Position::Position(const QWidget *topLevelWindow, const QPoint &desktopTopLeft)
+{
+ const QWidget *window =topLevelWindow->window ();
+ Q_ASSERT(window);
+ m_minimized = window->isMinimized();
+ m_position = window->pos() - desktopTopLeft;
+}
+
+void QDesignerWorkbench::Position::applyTo(QMdiSubWindow *mdiSubWindow,
+ const QPoint &mdiAreaOffset) const
+{
+ // QMdiSubWindow attempts to resize its children to sizeHint() when switching user interface modes.
+ // Restore old size
+ const QPoint mdiAreaPos = QPoint(qMax(0, m_position.x() - mdiAreaOffset.x()),
+ qMax(0, m_position.y() - mdiAreaOffset.y()));
+ mdiSubWindow->move(mdiAreaPos);
+ const QSize decorationSize = mdiSubWindow->size() - mdiSubWindow->contentsRect().size();
+ mdiSubWindow->resize(mdiSubWindow->widget()->size() + decorationSize);
+ mdiSubWindow->show();
+ if (m_minimized) {
+ mdiSubWindow->showShaded();
+ }
+}
+
+void QDesignerWorkbench::Position::applyTo(QWidget *topLevelWindow, const QPoint &desktopTopLeft) const
+{
+ QWidget *window = topLevelWindow->window ();
+ const QPoint newPos = m_position + desktopTopLeft;
+ window->move(newPos);
+ if ( m_minimized) {
+ topLevelWindow->showMinimized();
+ } else {
+ topLevelWindow->show();
+ }
+}
+
+void QDesignerWorkbench::Position::applyTo(QDockWidget *dockWidget) const
+{
+ dockWidget->widget()->setVisible(true);
+ dockWidget->setVisible(!m_minimized);
+}
+
+static inline void addActionsToMenu(QMenu *m, const ActionList &al)
+{
+ const ActionList::const_iterator cend = al.constEnd();
+ for (ActionList::const_iterator it = al.constBegin(); it != cend; ++it)
+ m->addAction(*it);
+}
+
+static inline QMenu *addMenu(QMenuBar *mb, const QString &title, const ActionList &al)
+{
+ QMenu *rc = mb->addMenu(title);
+ addActionsToMenu(rc, al);
+ return rc;
+}
+
+// -------- QDesignerWorkbench
+
+QDesignerWorkbench::QDesignerWorkbench() :
+ m_core(QDesignerComponents::createFormEditor(this)),
+ m_windowActions(new QActionGroup(this)),
+ m_globalMenuBar(new QMenuBar),
+ m_mode(NeutralMode),
+ m_dockedMainWindow(0),
+ m_state(StateInitializing)
+{
+ QDesignerSettings settings(m_core);
+
+ (void) QDesignerComponents::createTaskMenu(core(), this);
+
+ initializeCorePlugins();
+ QDesignerComponents::initializePlugins(core());
+ m_actionManager = new QDesignerActions(this); // accesses plugin components
+
+ m_windowActions->setExclusive(true);
+ connect(m_windowActions, SIGNAL(triggered(QAction*)), this, SLOT(formWindowActionTriggered(QAction*)));
+
+ // Build main menu bar
+ addMenu(m_globalMenuBar, tr("&File"), m_actionManager->fileActions()->actions());
+
+ QMenu *editMenu = addMenu(m_globalMenuBar, tr("&Edit"), m_actionManager->editActions()->actions());
+ editMenu->addSeparator();
+ addActionsToMenu(editMenu, m_actionManager->toolActions()->actions());
+
+ QMenu *formMenu = addMenu(m_globalMenuBar, tr("F&orm"), m_actionManager->formActions()->actions());
+ QMenu *previewSubMenu = new QMenu(tr("Preview in"), formMenu);
+ formMenu->insertMenu(m_actionManager->previewFormAction(), previewSubMenu);
+ addActionsToMenu(previewSubMenu, m_actionManager->styleActions()->actions());
+
+ QMenu *viewMenu = m_globalMenuBar->addMenu(tr("&View"));
+
+ addMenu(m_globalMenuBar, tr("&Settings"), m_actionManager->settingsActions()->actions());
+
+ m_windowMenu = addMenu(m_globalMenuBar, tr("&Window"), m_actionManager->windowActions()->actions());
+
+ addMenu(m_globalMenuBar, tr("&Help"), m_actionManager->helpActions()->actions());
+
+ // Add the tools in view menu order
+ QActionGroup *viewActions = new QActionGroup(this);
+ viewActions->setExclusive(false);
+
+ for (int i = 0; i < QDesignerToolWindow::StandardToolWindowCount; i++) {
+ QDesignerToolWindow *toolWindow = QDesignerToolWindow::createStandardToolWindow(static_cast< QDesignerToolWindow::StandardToolWindow>(i), this);
+ m_toolWindows.push_back(toolWindow);
+ if (QAction *action = toolWindow->action()) {
+ viewMenu->addAction(action);
+ viewActions->addAction(action);
+ }
+ // The widget box becomes the main window in top level mode
+ if (i == QDesignerToolWindow::WidgetBox)
+ connect(toolWindow, SIGNAL(closeEventReceived(QCloseEvent*)), this, SLOT(handleCloseEvent(QCloseEvent*)));
+ }
+ // Integration
+ m_integration = new qdesigner_internal::QDesignerIntegration(m_core, this);
+ connect(m_integration, SIGNAL(helpRequested(QString,QString)), m_actionManager, SLOT(helpRequested(QString,QString)));
+
+ // remaining view options (config toolbars)
+ viewMenu->addSeparator();
+ m_toolbarMenu = viewMenu->addMenu(tr("Toolbars"));
+
+ emit initialized();
+
+ connect(m_core->formWindowManager(), SIGNAL(activeFormWindowChanged(QDesignerFormWindowInterface*)),
+ this, SLOT(updateWindowMenu(QDesignerFormWindowInterface*)));
+
+
+ { // Add application specific options pages
+ QDesignerAppearanceOptionsPage *appearanceOptions = new QDesignerAppearanceOptionsPage(m_core);
+ connect(appearanceOptions, SIGNAL(settingsChangedDelayed()), this, SLOT(restoreUISettings()));
+ QList<QDesignerOptionsPageInterface*> optionsPages = m_core->optionsPages();
+ optionsPages.push_front(appearanceOptions);
+ m_core->setOptionsPages(optionsPages);
+ }
+
+ restoreUISettings();
+ AppFontWidget::restore(m_core->settingsManager(), QLatin1String(appFontPrefixC));
+ m_state = StateUp;
+}
+
+QDesignerWorkbench::~QDesignerWorkbench()
+{
+ switch (m_mode) {
+ case NeutralMode:
+ case DockedMode:
+ qDeleteAll(m_toolWindows);
+ break;
+ case TopLevelMode: // Everything parented here
+ delete widgetBoxToolWindow();
+ break;
+ }
+}
+
+void QDesignerWorkbench::saveGeometriesForModeChange()
+{
+ m_Positions.clear();
+ switch (m_mode) {
+ case NeutralMode:
+ break;
+ case TopLevelMode: {
+ const QPoint desktopOffset = QApplication::desktop()->availableGeometry().topLeft();
+ foreach (QDesignerToolWindow *tw, m_toolWindows)
+ m_Positions.insert(tw, Position(tw, desktopOffset));
+ foreach (QDesignerFormWindow *fw, m_formWindows) {
+ m_Positions.insert(fw, Position(fw, desktopOffset));
+ }
+ }
+ break;
+ case DockedMode: {
+ const QPoint mdiAreaOffset = m_dockedMainWindow->mdiArea()->pos();
+ foreach (QDesignerToolWindow *tw, m_toolWindows) {
+ m_Positions.insert(tw, Position(dockWidgetOf(tw)));
+ }
+ foreach (QDesignerFormWindow *fw, m_formWindows) {
+ m_Positions.insert(fw, Position(mdiSubWindowOf(fw), mdiAreaOffset));
+ }
+ }
+ break;
+ }
+}
+
+UIMode QDesignerWorkbench::mode() const
+{
+ return m_mode;
+}
+
+void QDesignerWorkbench::addFormWindow(QDesignerFormWindow *formWindow)
+{
+ // ### Q_ASSERT(formWindow->windowTitle().isEmpty() == false);
+
+ m_formWindows.append(formWindow);
+
+
+ m_actionManager->setWindowListSeparatorVisible(true);
+
+ if (QAction *action = formWindow->action()) {
+ m_windowActions->addAction(action);
+ m_windowMenu->addAction(action);
+ action->setChecked(true);
+ }
+
+ m_actionManager->minimizeAction()->setEnabled(true);
+ m_actionManager->minimizeAction()->setChecked(false);
+ connect(formWindow, SIGNAL(minimizationStateChanged(QDesignerFormWindowInterface*,bool)),
+ this, SLOT(minimizationStateChanged(QDesignerFormWindowInterface*,bool)));
+
+ m_actionManager->editWidgets()->trigger();
+}
+
+Qt::WindowFlags QDesignerWorkbench::magicalWindowFlags(const QWidget *widgetForFlags) const
+{
+ switch (m_mode) {
+ case TopLevelMode: {
+#ifdef Q_WS_MAC
+ if (qobject_cast<const QDesignerToolWindow *>(widgetForFlags))
+ return Qt::Tool;
+#else
+ Q_UNUSED(widgetForFlags);
+#endif
+ return Qt::Window;
+ }
+ case DockedMode:
+ return Qt::Window | Qt::WindowShadeButtonHint | Qt::WindowSystemMenuHint | Qt::WindowTitleHint;
+ case NeutralMode:
+ return Qt::Window;
+ default:
+ Q_ASSERT(0);
+ return 0;
+ }
+}
+
+QWidget *QDesignerWorkbench::magicalParent(const QWidget *w) const
+{
+ switch (m_mode) {
+ case TopLevelMode: {
+ // Use widget box as parent for all windows except self. This will
+ // result in having just one entry in the MS Windows task bar.
+ QWidget *widgetBoxWrapper = widgetBoxToolWindow();
+ return w == widgetBoxWrapper ? 0 : widgetBoxWrapper;
+ }
+ case DockedMode:
+ return m_dockedMainWindow->mdiArea();
+ case NeutralMode:
+ return 0;
+ default:
+ Q_ASSERT(0);
+ return 0;
+ }
+}
+
+void QDesignerWorkbench::switchToNeutralMode()
+{
+ QDesignerSettings settings(m_core);
+ saveGeometries(settings);
+ saveGeometriesForModeChange();
+
+ if (m_mode == TopLevelMode) {
+ delete m_topLevelData.toolbarManager;
+ m_topLevelData.toolbarManager = 0;
+ qDeleteAll(m_topLevelData.toolbars);
+ m_topLevelData.toolbars.clear();
+ }
+
+ m_mode = NeutralMode;
+
+ foreach (QDesignerToolWindow *tw, m_toolWindows) {
+ tw->setCloseEventPolicy(MainWindowBase::AcceptCloseEvents);
+ tw->setParent(0);
+ }
+
+ foreach (QDesignerFormWindow *fw, m_formWindows) {
+ fw->setParent(0);
+ fw->setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
+ }
+
+#ifndef Q_WS_MAC
+ m_globalMenuBar->setParent(0);
+#endif
+
+ m_core->setTopLevel(0);
+ qDesigner->setMainWindow(0);
+
+ delete m_dockedMainWindow;
+ m_dockedMainWindow = 0;
+}
+
+void QDesignerWorkbench::switchToDockedMode()
+{
+ if (m_mode == DockedMode)
+ return;
+
+ switchToNeutralMode();
+
+#ifndef Q_WS_MAC
+ QDesignerToolWindow *widgetBoxWrapper = widgetBoxToolWindow();
+ widgetBoxWrapper->action()->setVisible(true);
+ widgetBoxWrapper->setWindowTitle(tr("Widget Box"));
+#endif
+
+ m_mode = DockedMode;
+ const QDesignerSettings settings(m_core);
+ m_dockedMainWindow = new DockedMainWindow(this, m_toolbarMenu, m_toolWindows);
+ m_dockedMainWindow->setUnifiedTitleAndToolBarOnMac(true);
+ m_dockedMainWindow->setCloseEventPolicy(MainWindowBase::EmitCloseEventSignal);
+ connect(m_dockedMainWindow, SIGNAL(closeEventReceived(QCloseEvent*)), this, SLOT(handleCloseEvent(QCloseEvent*)));
+ connect(m_dockedMainWindow, SIGNAL(fileDropped(QString)), this, SLOT(slotFileDropped(QString)));
+ connect(m_dockedMainWindow, SIGNAL(formWindowActivated(QDesignerFormWindow*)), this, SLOT(slotFormWindowActivated(QDesignerFormWindow*)));
+ m_dockedMainWindow->restoreSettings(settings, m_dockedMainWindow->addToolWindows(m_toolWindows), desktopGeometry());
+
+ m_core->setTopLevel(m_dockedMainWindow);
+
+#ifndef Q_WS_MAC
+ m_dockedMainWindow->setMenuBar(m_globalMenuBar);
+ m_globalMenuBar->show();
+#endif
+ qDesigner->setMainWindow(m_dockedMainWindow);
+
+ foreach (QDesignerFormWindow *fw, m_formWindows) {
+ QMdiSubWindow *subwin = m_dockedMainWindow->createMdiSubWindow(fw, magicalWindowFlags(fw),
+ m_actionManager->closeFormAction()->shortcut());
+ subwin->hide();
+ if (QWidget *mainContainer = fw->editor()->mainContainer())
+ resizeForm(fw, mainContainer);
+ }
+
+ m_actionManager->setBringAllToFrontVisible(false);
+ m_dockedMainWindow->show();
+ // Trigger adjustMDIFormPositions() delayed as viewport size is not yet known.
+
+ if (m_state != StateInitializing)
+ QMetaObject::invokeMethod(this, "adjustMDIFormPositions", Qt::QueuedConnection);
+}
+
+void QDesignerWorkbench::adjustMDIFormPositions()
+{
+ const QPoint mdiAreaOffset = m_dockedMainWindow->mdiArea()->pos();
+
+ foreach (QDesignerFormWindow *fw, m_formWindows) {
+ const PositionMap::const_iterator pit = m_Positions.constFind(fw);
+ if (pit != m_Positions.constEnd())
+ pit->applyTo(mdiSubWindowOf(fw), mdiAreaOffset);
+ }
+}
+
+void QDesignerWorkbench::switchToTopLevelMode()
+{
+ if (m_mode == TopLevelMode)
+ return;
+
+ // make sure that the widgetbox is visible if it is different from neutral.
+ QDesignerToolWindow *widgetBoxWrapper = widgetBoxToolWindow();
+ Q_ASSERT(widgetBoxWrapper);
+
+ switchToNeutralMode();
+ const QPoint desktopOffset = desktopGeometry().topLeft();
+ m_mode = TopLevelMode;
+
+ // The widget box is special, it gets the menubar and gets to be the main widget.
+
+ m_core->setTopLevel(widgetBoxWrapper);
+#ifndef Q_WS_MAC
+ widgetBoxWrapper->setMenuBar(m_globalMenuBar);
+ widgetBoxWrapper->action()->setVisible(false);
+ widgetBoxWrapper->setCloseEventPolicy(MainWindowBase::EmitCloseEventSignal);
+ qDesigner->setMainWindow(widgetBoxWrapper);
+ widgetBoxWrapper->setWindowTitle(MainWindowBase::mainWindowTitle());
+#endif
+
+ const QDesignerSettings settings(m_core);
+ m_topLevelData.toolbars = MainWindowBase::createToolBars(m_actionManager, false);
+ m_topLevelData.toolbarManager = new ToolBarManager(widgetBoxWrapper, widgetBoxWrapper,
+ m_toolbarMenu, m_actionManager,
+ m_topLevelData.toolbars, m_toolWindows);
+ const int toolBarCount = m_topLevelData.toolbars.size();
+ for (int i = 0; i < toolBarCount; i++) {
+ widgetBoxWrapper->addToolBar(m_topLevelData.toolbars.at(i));
+ if (i == 3)
+ widgetBoxWrapper->insertToolBarBreak(m_topLevelData.toolbars.at(i));
+ }
+ m_topLevelData.toolbarManager->restoreState(settings.toolBarsState(m_mode), MainWindowBase::settingsVersion());
+ widgetBoxWrapper->restoreState(settings.mainWindowState(m_mode), MainWindowBase::settingsVersion());
+
+ bool found_visible_window = false;
+ foreach (QDesignerToolWindow *tw, m_toolWindows) {
+ tw->setParent(magicalParent(tw), magicalWindowFlags(tw));
+ settings.restoreGeometry(tw, tw->geometryHint());
+ tw->action()->setChecked(tw->isVisible());
+ found_visible_window |= tw->isVisible();
+ }
+
+ if (!m_toolWindows.isEmpty() && !found_visible_window)
+ m_toolWindows.first()->show();
+
+ m_actionManager->setBringAllToFrontVisible(true);
+
+ foreach (QDesignerFormWindow *fw, m_formWindows) {
+ fw->setParent(magicalParent(fw), magicalWindowFlags(fw));
+ fw->setAttribute(Qt::WA_DeleteOnClose, true);
+ const PositionMap::const_iterator pit = m_Positions.constFind(fw);
+ if (pit != m_Positions.constEnd()) pit->applyTo(fw, desktopOffset);
+ // Force an activate in order to refresh minimumSize, otherwise it will not be respected
+ if (QLayout *layout = fw->layout())
+ layout->invalidate();
+ if (QWidget *mainContainer = fw->editor()->mainContainer())
+ resizeForm(fw, mainContainer);
+ }
+}
+
+QDesignerFormWindowManagerInterface *QDesignerWorkbench::formWindowManager() const
+{
+ return m_core->formWindowManager();
+}
+
+QDesignerFormEditorInterface *QDesignerWorkbench::core() const
+{
+ return m_core;
+}
+
+int QDesignerWorkbench::toolWindowCount() const
+{
+ return m_toolWindows.count();
+}
+
+QDesignerToolWindow *QDesignerWorkbench::toolWindow(int index) const
+{
+ return m_toolWindows.at(index);
+}
+
+int QDesignerWorkbench::formWindowCount() const
+{
+ return m_formWindows.count();
+}
+
+QDesignerFormWindow *QDesignerWorkbench::formWindow(int index) const
+{
+ return m_formWindows.at(index);
+}
+
+QRect QDesignerWorkbench::desktopGeometry() const
+{
+ // Return geometry of the desktop designer is running in.
+ QWidget *widget = 0;
+ switch (m_mode) {
+ case DockedMode:
+ widget = m_dockedMainWindow;
+ break;
+ case TopLevelMode:
+ widget = widgetBoxToolWindow();
+ break;
+ case NeutralMode:
+ break;
+ }
+ const QDesktopWidget *desktop = qApp->desktop();
+ const int screenNumber = widget ? desktop->screenNumber(widget) : 0;
+ return desktop->availableGeometry(screenNumber);
+}
+
+QRect QDesignerWorkbench::availableGeometry() const
+{
+ if (m_mode == DockedMode)
+ return m_dockedMainWindow->mdiArea()->geometry();
+
+ const QDesktopWidget *desktop = qDesigner->desktop();
+ return desktop->availableGeometry(desktop->screenNumber(widgetBoxToolWindow()));
+}
+
+int QDesignerWorkbench::marginHint() const
+{ return 20;
+}
+
+void QDesignerWorkbench::slotFormWindowActivated(QDesignerFormWindow* fw)
+{
+ core()->formWindowManager()->setActiveFormWindow(fw->editor());
+}
+
+void QDesignerWorkbench::removeFormWindow(QDesignerFormWindow *formWindow)
+{
+ QDesignerFormWindowInterface *editor = formWindow->editor();
+ const bool loadOk = editor->mainContainer();
+ updateBackup(editor);
+ const int index = m_formWindows.indexOf(formWindow);
+ if (index != -1) {
+ m_formWindows.removeAt(index);
+ }
+
+ if (QAction *action = formWindow->action()) {
+ m_windowActions->removeAction(action);
+ m_windowMenu->removeAction(action);
+ }
+
+ if (m_formWindows.empty()) {
+ m_actionManager->setWindowListSeparatorVisible(false);
+ // Show up new form dialog unless closing
+ if (loadOk && m_state == StateUp
+ && QDesignerSettings(m_core).showNewFormOnStartup()) {
+ QTimer::singleShot(200, m_actionManager, SLOT(createForm()));
+ }
+ }
+}
+
+void QDesignerWorkbench::initializeCorePlugins()
+{
+ QList<QObject*> plugins = QPluginLoader::staticInstances();
+ plugins += core()->pluginManager()->instances();
+
+ foreach (QObject *plugin, plugins) {
+ if (QDesignerFormEditorPluginInterface *formEditorPlugin = qobject_cast<QDesignerFormEditorPluginInterface*>(plugin)) {
+ if (!formEditorPlugin->isInitialized())
+ formEditorPlugin->initialize(core());
+ }
+ }
+}
+
+void QDesignerWorkbench::saveSettings() const
+{
+ QDesignerSettings settings(m_core);
+ settings.clearBackup();
+ saveGeometries(settings);
+ AppFontWidget::save(m_core->settingsManager(), QLatin1String(appFontPrefixC));
+}
+
+void QDesignerWorkbench::saveGeometries(QDesignerSettings &settings) const
+{
+ switch (m_mode) {
+ case DockedMode:
+ m_dockedMainWindow->saveSettings(settings);
+ break;
+ case TopLevelMode:
+ settings.setToolBarsState(m_mode, m_topLevelData.toolbarManager->saveState(MainWindowBase::settingsVersion()));
+ settings.setMainWindowState(m_mode, widgetBoxToolWindow()->saveState(MainWindowBase::settingsVersion()));
+ foreach (const QDesignerToolWindow *tw, m_toolWindows)
+ settings.saveGeometryFor(tw);
+ break;
+ case NeutralMode:
+ break;
+ }
+}
+
+void QDesignerWorkbench::slotFileDropped(const QString &f)
+{
+ readInForm(f);
+}
+
+bool QDesignerWorkbench::readInForm(const QString &fileName) const
+{
+ return m_actionManager->readInForm(fileName);
+}
+
+bool QDesignerWorkbench::writeOutForm(QDesignerFormWindowInterface *formWindow, const QString &fileName) const
+{
+ return m_actionManager->writeOutForm(formWindow, fileName);
+}
+
+bool QDesignerWorkbench::saveForm(QDesignerFormWindowInterface *frm)
+{
+ return m_actionManager->saveForm(frm);
+}
+
+QDesignerFormWindow *QDesignerWorkbench::findFormWindow(QWidget *widget) const
+{
+ foreach (QDesignerFormWindow *formWindow, m_formWindows) {
+ if (formWindow->editor() == widget)
+ return formWindow;
+ }
+
+ return 0;
+}
+
+bool QDesignerWorkbench::handleClose()
+{
+ m_state = StateClosing;
+ QList<QDesignerFormWindow *> dirtyForms;
+ foreach (QDesignerFormWindow *w, m_formWindows) {
+ if (w->editor()->isDirty())
+ dirtyForms << w;
+ }
+
+ if (dirtyForms.size()) {
+ if (dirtyForms.size() == 1) {
+ if (!dirtyForms.at(0)->close()) {
+ m_state = StateUp;
+ return false;
+ }
+ } else {
+ int count = dirtyForms.size();
+ QMessageBox box(QMessageBox::Warning, tr("Save Forms?"),
+ tr("There are %n forms with unsaved changes."
+ " Do you want to review these changes before quitting?", "", count),
+ QMessageBox::Cancel | QMessageBox::Discard | QMessageBox::Save);
+ box.setInformativeText(tr("If you do not review your documents, all your changes will be lost."));
+ box.button(QMessageBox::Discard)->setText(tr("Discard Changes"));
+ QPushButton *save = static_cast<QPushButton *>(box.button(QMessageBox::Save));
+ save->setText(tr("Review Changes"));
+ box.setDefaultButton(save);
+ switch (box.exec()) {
+ case QMessageBox::Cancel:
+ m_state = StateUp;
+ return false;
+ case QMessageBox::Save:
+ foreach (QDesignerFormWindow *fw, dirtyForms) {
+ fw->show();
+ fw->raise();
+ if (!fw->close()) {
+ m_state = StateUp;
+ return false;
+ }
+ }
+ break;
+ case QMessageBox::Discard:
+ foreach (QDesignerFormWindow *fw, dirtyForms) {
+ fw->editor()->setDirty(false);
+ fw->setWindowModified(false);
+ }
+ break;
+ }
+ }
+ }
+
+ foreach (QDesignerFormWindow *fw, m_formWindows)
+ fw->close();
+
+ saveSettings();
+ return true;
+}
+
+QDesignerActions *QDesignerWorkbench::actionManager() const
+{
+ return m_actionManager;
+}
+
+void QDesignerWorkbench::updateWindowMenu(QDesignerFormWindowInterface *fwi)
+{
+ bool minimizeChecked = false;
+ bool minimizeEnabled = false;
+ QDesignerFormWindow *activeFormWindow = 0;
+ do {
+ if (!fwi)
+ break;
+ activeFormWindow = qobject_cast<QDesignerFormWindow *>(fwi->parentWidget());
+ if (!activeFormWindow)
+ break;
+
+ minimizeEnabled = true;
+ minimizeChecked = isFormWindowMinimized(activeFormWindow);
+ } while (false) ;
+
+ m_actionManager->minimizeAction()->setEnabled(minimizeEnabled);
+ m_actionManager->minimizeAction()->setChecked(minimizeChecked);
+
+ if (!m_formWindows.empty()) {
+ const QList<QDesignerFormWindow*>::const_iterator cend = m_formWindows.constEnd();
+ for (QList<QDesignerFormWindow*>::const_iterator it = m_formWindows.constBegin(); it != cend; ++it)
+ (*it)->action()->setChecked(*it == activeFormWindow);
+ }
+}
+
+void QDesignerWorkbench::formWindowActionTriggered(QAction *a)
+{
+ QDesignerFormWindow *fw = qobject_cast<QDesignerFormWindow *>(a->parentWidget());
+ Q_ASSERT(fw);
+
+ if (isFormWindowMinimized(fw))
+ setFormWindowMinimized(fw, false);
+
+ if (m_mode == DockedMode) {
+ if (QMdiSubWindow *subWindow = qobject_cast<QMdiSubWindow *>(fw->parent())) {
+ m_dockedMainWindow->mdiArea()->setActiveSubWindow(subWindow);
+ }
+ } else {
+ fw->activateWindow();
+ fw->raise();
+ }
+}
+
+void QDesignerWorkbench::closeAllToolWindows()
+{
+ foreach (QDesignerToolWindow *tw, m_toolWindows)
+ tw->hide();
+}
+
+bool QDesignerWorkbench::readInBackup()
+{
+ const QMap<QString, QString> backupFileMap = QDesignerSettings(m_core).backup();
+ if (backupFileMap.isEmpty())
+ return false;
+
+ const QMessageBox::StandardButton answer =
+ QMessageBox::question(0, tr("Backup Information"),
+ tr("The last session of Designer was not terminated correctly. "
+ "Backup files were left behind. Do you want to load them?"),
+ QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes);
+ if (answer == QMessageBox::No)
+ return false;
+
+ const QString modifiedPlaceHolder = QLatin1String("[*]");
+ QMapIterator<QString, QString> it(backupFileMap);
+ while(it.hasNext()) {
+ it.next();
+
+ QString fileName = it.key();
+ fileName.remove(modifiedPlaceHolder);
+
+ if(m_actionManager->readInForm(it.value()))
+ formWindowManager()->activeFormWindow()->setFileName(fileName);
+
+ }
+ return true;
+}
+
+void QDesignerWorkbench::updateBackup(QDesignerFormWindowInterface* fwi)
+{
+ QString fwn = QDir::convertSeparators(fwi->fileName());
+ if (fwn.isEmpty())
+ fwn = fwi->parentWidget()->windowTitle();
+
+ QDesignerSettings settings(m_core);
+ QMap<QString, QString> map = settings.backup();
+ map.remove(fwn);
+ settings.setBackup(map);
+}
+
+namespace {
+ void raiseWindow(QWidget *w) {
+ if (w->isMinimized())
+ w->setWindowState(w->windowState() & ~Qt::WindowMinimized);
+ w->raise();
+ }
+}
+
+void QDesignerWorkbench::bringAllToFront()
+{
+ if (m_mode != TopLevelMode)
+ return;
+ foreach(QDesignerToolWindow *tw, m_toolWindows)
+ raiseWindow(tw);
+ foreach(QDesignerFormWindow *dfw, m_formWindows)
+ raiseWindow(dfw);
+}
+
+// Resize a form window taking MDI decorations into account
+// Apply maximum size as there is no layout connection between
+// the form's main container and the integration's outer
+// container due to the tool widget stack.
+
+void QDesignerWorkbench::resizeForm(QDesignerFormWindow *fw, const QWidget *mainContainer) const
+{
+ const QSize containerSize = mainContainer->size();
+ const QSize containerMinimumSize = mainContainer->minimumSize();
+ const QSize containerMaximumSize = mainContainer->maximumSize();
+ if (m_mode != DockedMode) {
+ fw->resize(containerSize);
+ fw->setMaximumSize(containerMaximumSize);
+ return;
+ }
+ // get decorations and resize MDI
+ QMdiSubWindow *mdiSubWindow = qobject_cast<QMdiSubWindow *>(fw->parent());
+ Q_ASSERT(mdiSubWindow);
+ const QSize decorationSize = mdiSubWindow->geometry().size() - mdiSubWindow->contentsRect().size();
+ mdiSubWindow->resize(containerSize + decorationSize);
+ // In Qt::RightToLeft mode, the window can grow to be partially hidden by the right border.
+ const int mdiAreaWidth = m_dockedMainWindow->mdiArea()->width();
+ if (qApp->layoutDirection() == Qt::RightToLeft && mdiSubWindow->geometry().right() >= mdiAreaWidth)
+ mdiSubWindow->move(mdiAreaWidth - mdiSubWindow->width(), mdiSubWindow->pos().y());
+
+ if (containerMaximumSize == QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)) {
+ mdiSubWindow->setMaximumSize(containerMaximumSize);
+ } else {
+ mdiSubWindow->setMaximumSize(containerMaximumSize + decorationSize);
+ }
+}
+
+
+// Load a form or return 0 and do cleanup. file name and editor file
+// name in case of loading a template file.
+
+QDesignerFormWindow * QDesignerWorkbench::loadForm(const QString &fileName,
+ bool detectLineTermiantorMode,
+ bool *uic3Converted,
+ QString *errorMessage)
+{
+ QFile file(fileName);
+
+ qdesigner_internal::FormWindowBase::LineTerminatorMode mode = qdesigner_internal::FormWindowBase::NativeLineTerminator;
+
+ if (detectLineTermiantorMode) {
+ if (file.open(QFile::ReadOnly)) {
+ const QString text = QString::fromUtf8(file.readLine());
+ file.close();
+
+ const int lf = text.indexOf(QLatin1Char('\n'));
+ if (lf > 0 && text.at(lf-1) == QLatin1Char('\r')) {
+ mode = qdesigner_internal::FormWindowBase::CRLFLineTerminator;
+ } else if (lf >= 0) {
+ mode = qdesigner_internal::FormWindowBase::LFLineTerminator;
+ }
+ }
+ }
+
+ if (!file.open(QFile::ReadOnly|QFile::Text)) {
+ *errorMessage = tr("The file <b>%1</b> could not be opened.").arg(file.fileName());
+ return 0;
+ }
+
+
+ // Create a form
+ QDesignerFormWindowManagerInterface *formWindowManager = m_core->formWindowManager();
+
+ QDesignerFormWindow *formWindow = new QDesignerFormWindow(/*formWindow=*/ 0, this);
+ addFormWindow(formWindow);
+ QDesignerFormWindowInterface *editor = formWindow->editor();
+ Q_ASSERT(editor);
+
+ // Temporarily set the file name. It is needed when converting a UIC 3 file.
+ // In this case, the file name will we be cleared on return to force a save box.
+ editor->setFileName(fileName);
+ editor->setContents(&file);
+
+ if (qdesigner_internal::FormWindowBase *fwb = qobject_cast<qdesigner_internal::FormWindowBase *>(editor))
+ fwb->setLineTerminatorMode(mode);
+
+ switch (m_mode) {
+ case DockedMode: {
+ // below code must be after above call to setContents(), because setContents() may popup warning dialogs which would cause
+ // mdi sub window activation (because of dialogs internal call to processEvent or such)
+ // That activation could have worse consequences, e.g. NULL resource set for active form) before the form is loaded
+ QMdiSubWindow *subWin = m_dockedMainWindow->createMdiSubWindow(formWindow, magicalWindowFlags(formWindow), m_actionManager->closeFormAction()->shortcut());
+ m_dockedMainWindow->mdiArea()->setActiveSubWindow(subWin);
+ }
+ break;
+ case TopLevelMode: {
+ const QRect formWindowGeometryHint = formWindow->geometryHint();
+ formWindow->setAttribute(Qt::WA_DeleteOnClose, true);
+ formWindow->setParent(magicalParent(formWindow), magicalWindowFlags(formWindow));
+ formWindow->resize(formWindowGeometryHint.size());
+ formWindow->move(availableGeometry().center() - formWindowGeometryHint.center());
+ }
+ break;
+ case NeutralMode:
+ break;
+ }
+
+ if (!editor->mainContainer()) {
+ removeFormWindow(formWindow);
+ formWindowManager->removeFormWindow(editor);
+ m_core->metaDataBase()->remove(editor);
+ *errorMessage = tr("The file <b>%1</b> is not a valid Designer UI file.").arg(file.fileName());
+ return 0;
+ }
+ *uic3Converted = editor->fileName().isEmpty();
+ // Did user specify another (missing) resource path -> set dirty.
+ const bool dirty = editor->property("_q_resourcepathchanged").toBool();
+ editor->setDirty(dirty);
+ resizeForm(formWindow, editor->mainContainer());
+ formWindowManager->setActiveFormWindow(editor);
+ return formWindow;
+}
+
+
+QDesignerFormWindow * QDesignerWorkbench::openForm(const QString &fileName, QString *errorMessage)
+{
+ bool uic3Converted;
+ QDesignerFormWindow *rc =loadForm(fileName, true, &uic3Converted, errorMessage);
+ if (!rc)
+ return 0;
+
+ if (!uic3Converted)
+ rc->editor()->setFileName(fileName);
+ rc->firstShow();
+ return rc;
+}
+
+QDesignerFormWindow * QDesignerWorkbench::openTemplate(const QString &templateFileName,
+ const QString &editorFileName,
+ QString *errorMessage)
+{
+ bool uic3Converted;
+ QDesignerFormWindow *rc =loadForm(templateFileName, false, &uic3Converted, errorMessage);
+ if (!rc)
+ return 0;
+
+ if (!uic3Converted)
+ rc->editor()->setFileName(editorFileName);
+
+ rc->firstShow();
+ return rc;
+}
+
+void QDesignerWorkbench::minimizationStateChanged(QDesignerFormWindowInterface *formWindow, bool minimized)
+{
+ // refresh the minimize action state
+ if (core()->formWindowManager()->activeFormWindow() == formWindow) {
+ m_actionManager->minimizeAction()->setChecked(minimized);
+ }
+}
+
+void QDesignerWorkbench::toggleFormMinimizationState()
+{
+ QDesignerFormWindowInterface *fwi = core()->formWindowManager()->activeFormWindow();
+ if (!fwi || m_mode == NeutralMode)
+ return;
+ QDesignerFormWindow *fw = qobject_cast<QDesignerFormWindow *>(fwi->parentWidget());
+ Q_ASSERT(fw);
+ setFormWindowMinimized(fw, !isFormWindowMinimized(fw));
+}
+
+bool QDesignerWorkbench::isFormWindowMinimized(const QDesignerFormWindow *fw)
+{
+ switch (m_mode) {
+ case DockedMode:
+ return mdiSubWindowOf(fw)->isShaded();
+ case TopLevelMode:
+ return fw->window()->isMinimized();
+ default:
+ break;
+ }
+ return fw->isMinimized();
+}
+
+void QDesignerWorkbench::setFormWindowMinimized(QDesignerFormWindow *fw, bool minimized)
+{
+ switch (m_mode) {
+ case DockedMode: {
+ QMdiSubWindow *mdiSubWindow = mdiSubWindowOf(fw);
+ if (minimized) {
+ mdiSubWindow->showShaded();
+ } else {
+ mdiSubWindow->setWindowState(mdiSubWindow->windowState() & ~Qt::WindowMinimized);
+ }
+ }
+ break;
+ case TopLevelMode: {
+ QWidget *window = fw->window();
+ if (window->isMinimized()) {
+ window->setWindowState(window->windowState() & ~Qt::WindowMinimized);
+ } else {
+ window->showMinimized();
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void QDesignerWorkbench::restoreUISettings()
+{
+ UIMode mode = QDesignerSettings(m_core).uiMode();
+ switch (mode) {
+ case TopLevelMode:
+ switchToTopLevelMode();
+ break;
+ case DockedMode:
+ switchToDockedMode();
+ break;
+
+ default: Q_ASSERT(0);
+ }
+
+ ToolWindowFontSettings fontSettings = QDesignerSettings(m_core).toolWindowFont();
+ const QFont &font = fontSettings.m_useFont ? fontSettings.m_font : qApp->font();
+
+ if (font == m_toolWindows.front()->font())
+ return;
+
+ foreach(QDesignerToolWindow *tw, m_toolWindows)
+ tw->setFont(font);
+}
+
+void QDesignerWorkbench::handleCloseEvent(QCloseEvent *ev)
+{
+ ev->setAccepted(handleClose());
+ if (ev->isAccepted())
+ QMetaObject::invokeMethod(qDesigner, "quit", Qt::QueuedConnection); // We're going down!
+}
+
+QDesignerToolWindow *QDesignerWorkbench::widgetBoxToolWindow() const
+{
+ return m_toolWindows.at(QDesignerToolWindow::WidgetBox);
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/designer/qdesigner_workbench.h b/src/designer/src/designer/qdesigner_workbench.h
new file mode 100644
index 000000000..9266eea60
--- /dev/null
+++ b/src/designer/src/designer/qdesigner_workbench.h
@@ -0,0 +1,215 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDESIGNER_WORKBENCH_H
+#define QDESIGNER_WORKBENCH_H
+
+#include "designer_enums.h"
+
+#include <QtCore/QObject>
+#include <QtCore/QHash>
+#include <QtCore/QSet>
+#include <QtCore/QList>
+#include <QtCore/QRect>
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerActions;
+class QDesignerToolWindow;
+class QDesignerFormWindow;
+class DockedMainWindow;
+class QDesignerSettings;
+
+class QAction;
+class QActionGroup;
+class QDockWidget;
+class QMenu;
+class QMenuBar;
+class QMainWindow;
+class QToolBar;
+class QMdiArea;
+class QMdiSubWindow;
+class QCloseEvent;
+class QFont;
+class QtToolBarManager;
+class ToolBarManager;
+
+class QDesignerFormEditorInterface;
+class QDesignerFormWindowInterface;
+class QDesignerFormWindowManagerInterface;
+
+namespace qdesigner_internal {
+class QDesignerIntegration;
+}
+
+class QDesignerWorkbench: public QObject
+{
+ Q_OBJECT
+
+public:
+ QDesignerWorkbench();
+ virtual ~QDesignerWorkbench();
+
+ UIMode mode() const;
+
+ QDesignerFormEditorInterface *core() const;
+ QDesignerFormWindow *findFormWindow(QWidget *widget) const;
+
+ QDesignerFormWindow *openForm(const QString &fileName, QString *errorMessage);
+ QDesignerFormWindow *openTemplate(const QString &templateFileName,
+ const QString &editorFileName,
+ QString *errorMessage);
+
+ int toolWindowCount() const;
+ QDesignerToolWindow *toolWindow(int index) const;
+
+ int formWindowCount() const;
+ QDesignerFormWindow *formWindow(int index) const;
+
+ QDesignerActions *actionManager() const;
+
+ QActionGroup *modeActionGroup() const;
+
+ QRect availableGeometry() const;
+ QRect desktopGeometry() const;
+
+ int marginHint() const;
+
+ bool readInForm(const QString &fileName) const;
+ bool writeOutForm(QDesignerFormWindowInterface *formWindow, const QString &fileName) const;
+ bool saveForm(QDesignerFormWindowInterface *fw);
+ bool handleClose();
+ bool readInBackup();
+ void updateBackup(QDesignerFormWindowInterface* fwi);
+
+signals:
+ void modeChanged(UIMode mode);
+ void initialized();
+
+public slots:
+ void addFormWindow(QDesignerFormWindow *formWindow);
+ void removeFormWindow(QDesignerFormWindow *formWindow);
+ void bringAllToFront();
+ void toggleFormMinimizationState();
+
+private slots:
+ void switchToNeutralMode();
+ void switchToDockedMode();
+ void switchToTopLevelMode();
+ void initializeCorePlugins();
+ void handleCloseEvent(QCloseEvent *);
+ void slotFormWindowActivated(QDesignerFormWindow* fw);
+ void updateWindowMenu(QDesignerFormWindowInterface *fw);
+ void formWindowActionTriggered(QAction *a);
+ void adjustMDIFormPositions();
+ void minimizationStateChanged(QDesignerFormWindowInterface *formWindow, bool minimized);
+
+ void restoreUISettings();
+ void slotFileDropped(const QString &f);
+
+private:
+ QWidget *magicalParent(const QWidget *w) const;
+ Qt::WindowFlags magicalWindowFlags(const QWidget *widgetForFlags) const;
+ QDesignerFormWindowManagerInterface *formWindowManager() const;
+ void closeAllToolWindows();
+ QDesignerToolWindow *widgetBoxToolWindow() const;
+ QDesignerFormWindow *loadForm(const QString &fileName, bool detectLineTermiantorMode, bool *uic3Converted, QString *errorMessage);
+ void resizeForm(QDesignerFormWindow *fw, const QWidget *mainContainer) const;
+ void saveGeometriesForModeChange();
+ void saveGeometries(QDesignerSettings &settings) const;
+
+ bool isFormWindowMinimized(const QDesignerFormWindow *fw);
+ void setFormWindowMinimized(QDesignerFormWindow *fw, bool minimized);
+ void saveSettings() const;
+
+ QDesignerFormEditorInterface *m_core;
+ qdesigner_internal::QDesignerIntegration *m_integration;
+
+ QDesignerActions *m_actionManager;
+ QActionGroup *m_windowActions;
+
+ QMenu *m_windowMenu;
+
+ QMenuBar *m_globalMenuBar;
+
+ struct TopLevelData {
+ ToolBarManager *toolbarManager;
+ QList<QToolBar *> toolbars;
+ };
+ TopLevelData m_topLevelData;
+
+ UIMode m_mode;
+ DockedMainWindow *m_dockedMainWindow;
+
+ QList<QDesignerToolWindow*> m_toolWindows;
+ QList<QDesignerFormWindow*> m_formWindows;
+
+ QMenu *m_toolbarMenu;
+
+ // Helper class to remember the position of a window while switching user
+ // interface modes.
+ class Position {
+ public:
+ Position(const QDockWidget *dockWidget);
+ Position(const QMdiSubWindow *mdiSubWindow, const QPoint &mdiAreaOffset);
+ Position(const QWidget *topLevelWindow, const QPoint &desktopTopLeft);
+
+ void applyTo(QMdiSubWindow *mdiSubWindow, const QPoint &mdiAreaOffset) const;
+ void applyTo(QWidget *topLevelWindow, const QPoint &desktopTopLeft) const;
+ void applyTo(QDockWidget *dockWidget) const;
+
+ QPoint position() const { return m_position; }
+ private:
+ bool m_minimized;
+ // Position referring to top-left corner (desktop in top-level mode or
+ // main window in MDI mode)
+ QPoint m_position;
+ };
+ typedef QHash<QWidget*, Position> PositionMap;
+ PositionMap m_Positions;
+
+ enum State { StateInitializing, StateUp, StateClosing };
+ State m_state;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDESIGNER_WORKBENCH_H
diff --git a/src/designer/src/designer/saveformastemplate.cpp b/src/designer/src/designer/saveformastemplate.cpp
new file mode 100644
index 000000000..49ac64ee5
--- /dev/null
+++ b/src/designer/src/designer/saveformastemplate.cpp
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "saveformastemplate.h"
+#include "qdesigner_settings.h"
+
+#include <QtCore/QFile>
+#include <QtGui/QFileDialog>
+#include <QtGui/QMessageBox>
+#include <QtGui/QPushButton>
+
+#include <QtDesigner/abstractformeditor.h>
+#include <QtDesigner/abstractformwindow.h>
+
+QT_BEGIN_NAMESPACE
+
+SaveFormAsTemplate::SaveFormAsTemplate(QDesignerFormEditorInterface *core,
+ QDesignerFormWindowInterface *formWindow,
+ QWidget *parent)
+ : QDialog(parent, Qt::Sheet),
+ m_core(core),
+ m_formWindow(formWindow)
+{
+ ui.setupUi(this);
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+
+ ui.templateNameEdit->setText(formWindow->mainContainer()->objectName());
+ ui.templateNameEdit->selectAll();
+
+ ui.templateNameEdit->setFocus();
+
+ QStringList paths = QDesignerSettings(m_core).formTemplatePaths();
+ ui.categoryCombo->addItems(paths);
+ ui.categoryCombo->addItem(tr("Add path..."));
+ m_addPathIndex = ui.categoryCombo->count() - 1;
+ connect(ui.templateNameEdit, SIGNAL(textChanged(QString)),
+ this, SLOT(updateOKButton(QString)));
+ connect(ui.categoryCombo, SIGNAL(activated(int)), this, SLOT(checkToAddPath(int)));
+}
+
+SaveFormAsTemplate::~SaveFormAsTemplate()
+{
+}
+
+void SaveFormAsTemplate::accept()
+{
+ QString templateFileName = ui.categoryCombo->currentText();
+ templateFileName += QLatin1Char('/');
+ const QString name = ui.templateNameEdit->text();
+ templateFileName += name;
+ const QString extension = QLatin1String(".ui");
+ if (!templateFileName.endsWith(extension))
+ templateFileName.append(extension);
+ QFile file(templateFileName);
+
+ if (file.exists()) {
+ QMessageBox msgBox(QMessageBox::Information, tr("Template Exists"),
+ tr("A template with the name %1 already exists.\n"
+ "Do you want overwrite the template?").arg(name), QMessageBox::Cancel, m_formWindow);
+ msgBox.setDefaultButton(QMessageBox::Cancel);
+ QPushButton *overwriteButton = msgBox.addButton(tr("Overwrite Template"), QMessageBox::AcceptRole);
+ msgBox.exec();
+ if (msgBox.clickedButton() != overwriteButton)
+ return;
+ }
+
+ while (!file.open(QFile::WriteOnly)) {
+ if (QMessageBox::information(m_formWindow, tr("Open Error"),
+ tr("There was an error opening template %1 for writing. Reason: %2").arg(name).arg(file.errorString()),
+ QMessageBox::Retry|QMessageBox::Cancel, QMessageBox::Cancel) == QMessageBox::Cancel) {
+ return;
+ }
+ }
+
+ const QString origName = m_formWindow->fileName();
+ // ensure m_formWindow->contents() will convert properly resource paths to relative paths
+ // (relative to template location, not to the current form location)
+ m_formWindow->setFileName(templateFileName);
+ QByteArray ba = m_formWindow->contents().toUtf8();
+ m_formWindow->setFileName(origName);
+ while (file.write(ba) != ba.size()) {
+ if (QMessageBox::information(m_formWindow, tr("Write Error"),
+ tr("There was an error writing the template %1 to disk. Reason: %2").arg(name).arg(file.errorString()),
+ QMessageBox::Retry|QMessageBox::Cancel, QMessageBox::Cancel) == QMessageBox::Cancel) {
+ file.close();
+ file.remove();
+ return;
+ }
+ file.reset();
+ }
+ // update the list of places too...
+ QStringList sl;
+ for (int i = 0; i < m_addPathIndex; ++i)
+ sl << ui.categoryCombo->itemText(i);
+
+ QDesignerSettings(m_core).setFormTemplatePaths(sl);
+
+ QDialog::accept();
+}
+
+void SaveFormAsTemplate::updateOKButton(const QString &str)
+{
+ QPushButton *okButton = ui.buttonBox->button(QDialogButtonBox::Ok);
+ okButton->setEnabled(!str.isEmpty());
+}
+
+QString SaveFormAsTemplate::chooseTemplatePath(QWidget *parent)
+{
+ QString rc = QFileDialog::getExistingDirectory(parent,
+ tr("Pick a directory to save templates in"));
+ if (rc.isEmpty())
+ return rc;
+
+ if (rc.endsWith(QDir::separator()))
+ rc.remove(rc.size() - 1, 1);
+ return rc;
+}
+
+void SaveFormAsTemplate::checkToAddPath(int itemIndex)
+{
+ if (itemIndex != m_addPathIndex)
+ return;
+
+ const QString dir = chooseTemplatePath(this);
+ if (dir.isEmpty()) {
+ ui.categoryCombo->setCurrentIndex(0);
+ return;
+ }
+
+ ui.categoryCombo->insertItem(m_addPathIndex, dir);
+ ui.categoryCombo->setCurrentIndex(m_addPathIndex);
+ ++m_addPathIndex;
+}
+
+QT_END_NAMESPACE
diff --git a/src/designer/src/designer/saveformastemplate.h b/src/designer/src/designer/saveformastemplate.h
new file mode 100644
index 000000000..8b0b3ab8e
--- /dev/null
+++ b/src/designer/src/designer/saveformastemplate.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SAVEFORMASTEMPLATE_H
+#define SAVEFORMASTEMPLATE_H
+
+#include "ui_saveformastemplate.h"
+
+QT_BEGIN_NAMESPACE
+
+class QDesignerFormEditorInterface;
+class QDesignerFormWindowInterface;
+
+class SaveFormAsTemplate: public QDialog
+{
+ Q_OBJECT
+public:
+ explicit SaveFormAsTemplate(QDesignerFormEditorInterface *m_core,
+ QDesignerFormWindowInterface *formWindow,
+ QWidget *parent = 0);
+ virtual ~SaveFormAsTemplate();
+
+private slots:
+ void accept();
+ void updateOKButton(const QString &str);
+ void checkToAddPath(int itemIndex);
+
+private:
+ static QString chooseTemplatePath(QWidget *parent);
+
+ Ui::SaveFormAsTemplate ui;
+ QDesignerFormEditorInterface *m_core;
+ QDesignerFormWindowInterface *m_formWindow;
+ int m_addPathIndex;
+};
+
+QT_END_NAMESPACE
+
+#endif // SAVEFORMASTEMPLATE_H
diff --git a/src/designer/src/designer/saveformastemplate.ui b/src/designer/src/designer/saveformastemplate.ui
new file mode 100644
index 000000000..c29ad9ad4
--- /dev/null
+++ b/src/designer/src/designer/saveformastemplate.ui
@@ -0,0 +1,166 @@
+<ui version="4.0" >
+ <comment>*********************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+*********************************************************************</comment>
+ <class>SaveFormAsTemplate</class>
+ <widget class="QDialog" name="SaveFormAsTemplate" >
+ <property name="windowTitle" >
+ <string>Save Form As Template</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <item>
+ <layout class="QFormLayout" >
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="frameShape" >
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Plain</enum>
+ </property>
+ <property name="text" >
+ <string>&amp;Name:</string>
+ </property>
+ <property name="textFormat" >
+ <enum>Qt::AutoText</enum>
+ </property>
+ <property name="buddy" >
+ <cstring>templateNameEdit</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QLineEdit" name="templateNameEdit" >
+ <property name="minimumSize" >
+ <size>
+ <width>222</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string/>
+ </property>
+ <property name="echoMode" >
+ <enum>QLineEdit::Normal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_2" >
+ <property name="frameShape" >
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Plain</enum>
+ </property>
+ <property name="text" >
+ <string>&amp;Category:</string>
+ </property>
+ <property name="textFormat" >
+ <enum>Qt::AutoText</enum>
+ </property>
+ <property name="buddy" >
+ <cstring>categoryCombo</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QComboBox" name="categoryCombo" />
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QFrame" name="horizontalLine" >
+ <property name="frameShape" >
+ <enum>QFrame::HLine</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Sunken</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>SaveFormAsTemplate</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>256</x>
+ <y>124</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>113</x>
+ <y>143</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>SaveFormAsTemplate</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>332</x>
+ <y>127</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>372</x>
+ <y>147</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/designer/src/designer/uifile.icns b/src/designer/src/designer/uifile.icns
new file mode 100644
index 000000000..2473ea4dc
--- /dev/null
+++ b/src/designer/src/designer/uifile.icns
Binary files differ
diff --git a/src/designer/src/designer/versiondialog.cpp b/src/designer/src/designer/versiondialog.cpp
new file mode 100644
index 000000000..63a95e6d7
--- /dev/null
+++ b/src/designer/src/designer/versiondialog.cpp
@@ -0,0 +1,191 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QVector>
+#include <QtGui/QMouseEvent>
+#include <QtGui/QGridLayout>
+#include <QtGui/QLabel>
+#include <QtGui/QPushButton>
+#include <QtGui/QDialogButtonBox>
+#include <QtGui/QPainter>
+#include <QtGui/QPainterPath>
+#include <QtGui/QStyleOption>
+#include "versiondialog.h"
+
+QT_BEGIN_NAMESPACE
+
+class VersionLabel : public QLabel
+{
+ Q_OBJECT
+public:
+ VersionLabel(QWidget *parent = 0);
+
+signals:
+ void triggered();
+
+protected:
+ void mousePressEvent(QMouseEvent *me);
+ void mouseMoveEvent(QMouseEvent *me);
+ void mouseReleaseEvent(QMouseEvent *me);
+ void paintEvent(QPaintEvent *pe);
+private:
+ QVector<QPoint> hitPoints;
+ QVector<QPoint> missPoints;
+ QPainterPath m_path;
+ bool secondStage;
+ bool m_pushed;
+};
+
+VersionLabel::VersionLabel(QWidget *parent)
+ : QLabel(parent), secondStage(false), m_pushed(false)
+{
+ setPixmap(QPixmap(QLatin1String(":/trolltech/designer/images/designer.png")));
+ hitPoints.append(QPoint(56, 25));
+ hitPoints.append(QPoint(29, 55));
+ hitPoints.append(QPoint(56, 87));
+ hitPoints.append(QPoint(82, 55));
+ hitPoints.append(QPoint(58, 56));
+
+ secondStage = false;
+ m_pushed = false;
+}
+
+void VersionLabel::mousePressEvent(QMouseEvent *me)
+{
+ if (me->button() == Qt::LeftButton) {
+ if (!secondStage) {
+ m_path = QPainterPath(me->pos());
+ } else {
+ m_pushed = true;
+ update();
+ }
+ }
+}
+
+void VersionLabel::mouseMoveEvent(QMouseEvent *me)
+{
+ if (me->buttons() & Qt::LeftButton)
+ if (!secondStage)
+ m_path.lineTo(me->pos());
+}
+
+void VersionLabel::mouseReleaseEvent(QMouseEvent *me)
+{
+ if (me->button() == Qt::LeftButton) {
+ if (!secondStage) {
+ m_path.lineTo(me->pos());
+ bool gotIt = true;
+ foreach(const QPoint &pt, hitPoints) {
+ if (!m_path.contains(pt)) {
+ gotIt = false;
+ break;
+ }
+ }
+ if (gotIt) {
+ foreach(const QPoint &pt, missPoints) {
+ if (m_path.contains(pt)) {
+ gotIt = false;
+ break;
+ }
+ }
+ }
+ if (gotIt && !secondStage) {
+ secondStage = true;
+ m_path = QPainterPath();
+ update();
+ }
+ } else {
+ m_pushed = false;
+ update();
+ emit triggered();
+ }
+ }
+}
+
+void VersionLabel::paintEvent(QPaintEvent *pe)
+{
+ if (secondStage) {
+ QPainter p(this);
+ QStyleOptionButton opt;
+ opt.init(this);
+ if (!m_pushed)
+ opt.state |= QStyle::State_Raised;
+ else
+ opt.state |= QStyle::State_Sunken;
+ opt.state &= ~QStyle::State_HasFocus;
+ style()->drawControl(QStyle::CE_PushButtonBevel, &opt, &p, this);
+ }
+ QLabel::paintEvent(pe);
+}
+
+VersionDialog::VersionDialog(QWidget *parent)
+ : QDialog(parent
+#ifdef Q_WS_MAC
+ , Qt::Tool
+#endif
+ )
+{
+ setWindowFlags((windowFlags() & ~Qt::WindowContextHelpButtonHint) | Qt::MSWindowsFixedSizeDialogHint);
+ QGridLayout *layout = new QGridLayout(this);
+ VersionLabel *label = new VersionLabel;
+ QLabel *lbl = new QLabel;
+ QString version = tr("<h3>%1</h3><br/><br/>Version %2");
+ version = version.arg(tr("Qt Designer")).arg(QLatin1String(QT_VERSION_STR));
+ version.append(tr("<br/>Qt Designer is a graphical user interface designer for Qt applications.<br/>"));
+
+ lbl->setText(tr("%1"
+ "<br/>Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)."
+ ).arg(version));
+
+ lbl->setWordWrap(true);
+ lbl->setOpenExternalLinks(true);
+
+ QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close);
+ connect(buttonBox , SIGNAL(rejected()), this, SLOT(reject()));
+ connect(label, SIGNAL(triggered()), this, SLOT(accept()));
+ layout->addWidget(label, 0, 0, 1, 1);
+ layout->addWidget(lbl, 0, 1, 4, 4);
+ layout->addWidget(buttonBox, 4, 2, 1, 1);
+}
+
+QT_END_NAMESPACE
+
+#include "versiondialog.moc"
diff --git a/src/designer/src/designer/versiondialog.h b/src/designer/src/designer/versiondialog.h
new file mode 100644
index 000000000..0e6760092
--- /dev/null
+++ b/src/designer/src/designer/versiondialog.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef VERSIONDIALOG_H
+#define VERSIONDIALOG_H
+
+#include <QtGui/QDialog>
+
+QT_BEGIN_NAMESPACE
+
+class VersionDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ explicit VersionDialog(QWidget *parent);
+};
+
+QT_END_NAMESPACE
+
+#endif