1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
11 ** Licensees holding valid Qt Commercial licenses may use this file in
12 ** accordance with the Qt Commercial License Agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and Nokia.
16 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** If you are unsure which license is appropriate for your use, please
26 ** contact the sales department at http://qt.nokia.com/contact.
28 **************************************************************************/
30 #include "formeditorw.h"
31 #include "formwindoweditor.h"
32 #include "designerconstants.h"
33 #include "settingsmanager.h"
34 #include "settingspage.h"
35 #include "editorwidget.h"
36 #include "qtcreatorintegration.h"
38 #include <coreplugin/coreconstants.h>
39 #include <coreplugin/icore.h>
40 #include <coreplugin/uniqueidmanager.h>
41 #include <coreplugin/actionmanager/actionmanager.h>
42 #include <coreplugin/editormanager/editormanager.h>
43 #include <extensionsystem/pluginmanager.h>
44 #include <utils/qtcassert.h>
46 #include <QtDesigner/QDesignerFormEditorPluginInterface>
47 #include <qt_private/pluginmanager_p.h>
49 #include <qt_private/iconloader_p.h> // createIconSet
50 #include <qt_private/qdesigner_formwindowmanager_p.h>
51 #include <qt_private/formwindowbase_p.h>
52 #include <QtDesigner/QDesignerFormEditorInterface>
53 #include <QtDesigner/QDesignerComponents>
55 #include <QtDesigner/QDesignerWidgetBoxInterface>
56 #include <QtDesigner/abstractobjectinspector.h>
57 #include <QtDesigner/QDesignerComponents>
58 #include <QtDesigner/QDesignerPropertyEditorInterface>
59 #include <QtDesigner/QDesignerActionEditorInterface>
61 #include <QtCore/QPluginLoader>
62 #include <QtCore/QTemporaryFile>
63 #include <QtCore/QDir>
64 #include <QtCore/QTime>
65 #include <QtGui/QAction>
66 #include <QtGui/QActionGroup>
67 #include <QtGui/QApplication>
68 #include <QtGui/QCursor>
69 #include <QtGui/QDockWidget>
70 #include <QtGui/QMenu>
71 #include <QtGui/QMainWindow>
72 #include <QtGui/QMessageBox>
73 #include <QtGui/QKeySequence>
74 #include <QtGui/QPrintDialog>
75 #include <QtGui/QPrinter>
76 #include <QtGui/QPainter>
77 #include <QtGui/QStatusBar>
78 #include <QtGui/QStyle>
79 #include <QtGui/QToolBar>
81 #include <QtCore/QDebug>
82 #include <QtCore/QSettings>
84 static const char *settingsGroup = "Designer";
92 /* Actions of the designer plugin:
93 * Designer provides a toolbar which is subject to a context change (to
94 * "edit mode" context) when it is focussed.
95 * In order to prevent its actions from being disabled/hidden by that context
96 * change, the actions are registered on the global context. In currentEditorChanged(),
97 * the ones that are present in the global edit menu are set visible/invisible manually.
98 * The designer context is currently used for Cut/Copy/Paste, etc. */
100 static inline QIcon designerIcon(const QString &iconName)
102 const QIcon icon = qdesigner_internal::createIconSet(iconName);
104 qWarning() << "Unable to locate " << iconName;
108 // Create an action to activate a designer tool
109 static inline QAction *createEditModeAction(QActionGroup *ag,
110 const QList<int> &context,
111 Core::ActionManager *am,
112 Core::ActionContainer *medit,
113 const QString &actionName,
116 const QString &iconName = QString(),
117 const QString &keySequence = QString())
119 QAction *rc = new QAction(actionName, ag);
120 rc->setCheckable(true);
121 if (!iconName.isEmpty())
122 rc->setIcon(designerIcon(iconName));
123 Core::Command *command = am->registerAction(rc, name, context);
124 if (!keySequence.isEmpty())
125 command->setDefaultKeySequence(QKeySequence(keySequence));
126 medit->addAction(command, Core::Constants::G_EDIT_OTHER);
127 rc->setData(toolNumber);
133 // Create a menu separato
134 static inline QAction * createSeparator(QObject *parent,
135 Core::ActionManager *am,
136 const QList<int> &context,
137 Core::ActionContainer *container,
138 const QString &name = QString(),
139 const QString &group = QString())
141 QAction *actSeparator = new QAction(parent);
142 actSeparator->setSeparator(true);
143 Core::Command *command = am->registerAction(actSeparator, name, context);
144 container->addAction(command, group);
148 // Create a tool action
149 static inline void addToolAction(QAction *a,
150 Core::ActionManager *am,
151 const QList<int> &context,
153 Core::ActionContainer *c1,
154 const QString &keySequence = QString())
156 Core::Command *command = am->registerAction(a, name, context);
157 if (!keySequence.isEmpty())
158 command->setDefaultKeySequence(QKeySequence(keySequence));
159 c1->addAction(command);
162 using namespace Designer;
163 using namespace Designer::Internal;
164 using namespace Designer::Constants;
166 // --------- Proxy Action
168 ProxyAction::ProxyAction(const QString &defaultText, QObject *parent)
169 : QAction(defaultText, parent),
170 m_defaultText(defaultText),
176 void ProxyAction::setAction(QAction *action)
179 disconnect(m_action, SIGNAL(changed()), this, SLOT(update()));
180 disconnect(this, SIGNAL(triggered(bool)), m_action, SIGNAL(triggered(bool)));
181 disconnect(this, SIGNAL(toggled(bool)), m_action, SLOT(setChecked(bool)));
186 // if (hasAttribute(CA_Hide))
187 // m_action->setVisible(false);
188 // if (hasAttribute(CA_UpdateText)) {
189 setText(m_defaultText);
192 setCheckable(m_action->isCheckable());
193 setSeparator(m_action->isSeparator());
194 connect(m_action, SIGNAL(changed()), this, SLOT(update()));
195 // we want to avoid the toggling semantic on slot trigger(), so we just connect the signals
196 connect(this, SIGNAL(triggered(bool)), m_action, SIGNAL(triggered(bool)));
197 // we need to update the checked state, so we connect to setChecked slot, which also fires a toggled signal
198 connect(this, SIGNAL(toggled(bool)), m_action, SLOT(setChecked(bool)));
203 void ProxyAction::update()
205 QTC_ASSERT(m_action, return)
206 bool block = blockSignals(true);
207 // if (hasAttribute(CA_UpdateIcon)) {
208 setIcon(m_action->icon());
209 setIconText(m_action->iconText());
211 // if (hasAttribute(CA_UpdateText)) {
212 setText(m_action->text());
213 setToolTip(m_action->toolTip());
214 setStatusTip(m_action->statusTip());
215 setWhatsThis(m_action->whatsThis());
218 setChecked(m_action->isChecked());
220 setEnabled(m_action->isEnabled());
221 setVisible(m_action->isVisible());
226 // --------- FormEditorW
228 FormEditorW *FormEditorW::m_self = 0;
230 FormEditorW::FormEditorW() :
231 m_formeditor(QDesignerComponents::createFormEditor(0)),
234 m_core(Core::ICore::instance()),
235 m_initStage(RegisterPlugins),
236 m_actionGroupEditMode(0),
239 m_actionGroupPreviewInStyle(0),
240 m_actionAboutPlugins(0)
242 if (Designer::Constants::Internal::debug)
243 qDebug() << Q_FUNC_INFO;
244 QTC_ASSERT(!m_self, return);
246 QTC_ASSERT(m_core, return);
248 qFill(m_designerSubWindows, m_designerSubWindows + Designer::Constants::DesignerSubWindowCount,
249 static_cast<QWidget *>(0));
250 qFill(m_designerSubWindowActions, m_designerSubWindowActions + Designer::Constants::DesignerSubWindowCount,
251 static_cast<ProxyAction *>(0));
253 m_formeditor->setTopLevel(qobject_cast<QWidget *>(m_core->editorManager()));
254 m_formeditor->setSettingsManager(new SettingsManager());
256 m_fwm = qobject_cast<qdesigner_internal::QDesignerFormWindowManager*>(m_formeditor->formWindowManager());
257 QTC_ASSERT(m_fwm, return);
259 const int uid = m_core->uniqueIDManager()->uniqueIdentifier(QLatin1String(C_FORMEDITOR));
264 foreach (QDesignerOptionsPageInterface *designerPage, m_formeditor->optionsPages()) {
265 SettingsPage *settingsPage = new SettingsPage(designerPage);
266 ExtensionSystem::PluginManager::instance()->addObject(settingsPage);
267 m_settingsPages.append(settingsPage);
269 restoreSettings(m_core->settings());
271 connect(m_core->editorManager(), SIGNAL(currentEditorChanged(Core::IEditor *)),
272 this, SLOT(currentEditorChanged(Core::IEditor *)));
275 FormEditorW::~FormEditorW()
277 saveSettings(m_core->settings());
279 for (int i = 0; i < Designer::Constants::DesignerSubWindowCount; ++i)
280 delete m_designerSubWindows[i];
283 foreach (SettingsPage *settingsPage, m_settingsPages) {
284 ExtensionSystem::PluginManager::instance()->removeObject(settingsPage);
287 delete m_integration;
291 void FormEditorW::fullInit()
293 QTC_ASSERT(m_initStage == RegisterPlugins, return);
295 if (Designer::Constants::Internal::debug) {
296 initTime = new QTime;
300 QDesignerComponents::createTaskMenu(m_formeditor, parent());
301 QDesignerComponents::initializePlugins(designerEditor());
302 QDesignerComponents::initializeResources();
303 initDesignerSubWindows();
304 m_integration = new QtCreatorIntegration(m_formeditor, this);
305 m_formeditor->setIntegration(m_integration);
308 * This will initialize our TabOrder, Signals and slots and Buddy editors.
310 QList<QObject*> plugins = QPluginLoader::staticInstances();
311 plugins += m_formeditor->pluginManager()->instances();
312 foreach (QObject *plugin, plugins) {
313 if (QDesignerFormEditorPluginInterface *formEditorPlugin = qobject_cast<QDesignerFormEditorPluginInterface*>(plugin)) {
314 if (!formEditorPlugin->isInitialized())
315 formEditorPlugin->initialize(m_formeditor);
319 if (m_actionAboutPlugins)
320 m_actionAboutPlugins->setEnabled(true);
322 if (Designer::Constants::Internal::debug) {
323 qDebug() << Q_FUNC_INFO << initTime->elapsed() << "ms";
327 m_initStage = FullyInitialized;
330 void FormEditorW::initDesignerSubWindows()
332 qFill(m_designerSubWindows, m_designerSubWindows + Designer::Constants::DesignerSubWindowCount, static_cast<QWidget*>(0));
334 QDesignerWidgetBoxInterface *wb = QDesignerComponents::createWidgetBox(m_formeditor, 0);
335 wb->setWindowTitle(tr("Widget Box"));
336 m_formeditor->setWidgetBox(wb);
337 m_designerSubWindows[WidgetBoxSubWindow] = wb;
339 QDesignerObjectInspectorInterface *oi = QDesignerComponents::createObjectInspector(m_formeditor, 0);
340 oi->setWindowTitle(tr("Object Inspector"));
341 m_formeditor->setObjectInspector(oi);
342 m_designerSubWindows[ObjectInspectorSubWindow] = oi;
344 QDesignerPropertyEditorInterface *pe = QDesignerComponents::createPropertyEditor(m_formeditor, 0);
345 pe->setWindowTitle(tr("Property Editor"));
346 m_formeditor->setPropertyEditor(pe);
347 m_designerSubWindows[PropertyEditorSubWindow] = pe;
349 QWidget *se = QDesignerComponents::createSignalSlotEditor(m_formeditor, 0);
350 se->setWindowTitle(tr("Signals & Slots Editor"));
351 m_designerSubWindows[SignalSlotEditorSubWindow] = se;
353 QDesignerActionEditorInterface *ae = QDesignerComponents::createActionEditor(m_formeditor, 0);
354 ae->setWindowTitle(tr("Action Editor"));
355 m_formeditor->setActionEditor(ae);
356 m_designerSubWindows[ActionEditorSubWindow] = ae;
359 void FormEditorW::ensureInitStage(InitializationStage s)
361 if (Designer::Constants::Internal::debug)
362 qDebug() << Q_FUNC_INFO << s;
364 m_self = new FormEditorW;
365 if (m_self->m_initStage >= s)
367 QApplication::setOverrideCursor(Qt::WaitCursor);
369 QApplication::restoreOverrideCursor();
372 FormEditorW *FormEditorW::instance()
374 ensureInitStage(FullyInitialized);
378 void FormEditorW::deleteInstance()
383 void FormEditorW::setupActions()
385 Core::ActionManager *am = m_core->actionManager();
386 Core::Command *command;
389 Core::ActionContainer *medit =
390 am->actionContainer(Core::Constants::M_EDIT);
391 Core::ActionContainer *mtools =
392 am->actionContainer(Core::Constants::M_TOOLS);
394 Core::ActionContainer *mformtools =
395 am->createMenu(M_FORMEDITOR);
396 mformtools->menu()->setTitle(tr("For&m editor"));
397 mtools->addMenu(mformtools);
400 am->registerAction(m_fwm->actionUndo(), Core::Constants::UNDO, m_context);
401 am->registerAction(m_fwm->actionRedo(), Core::Constants::REDO, m_context);
402 am->registerAction(m_fwm->actionCut(), Core::Constants::CUT, m_context);
403 am->registerAction(m_fwm->actionCopy(), Core::Constants::COPY, m_context);
404 am->registerAction(m_fwm->actionPaste(), Core::Constants::PASTE, m_context);
405 am->registerAction(m_fwm->actionSelectAll(), Core::Constants::SELECTALL, m_context);
407 m_actionPrint = new QAction(this);
408 am->registerAction(m_actionPrint, Core::Constants::PRINT, m_context);
409 connect(m_actionPrint, SIGNAL(triggered()), this, SLOT(print()));
412 command = am->registerAction(m_fwm->actionDelete(), QLatin1String("FormEditor.Edit.Delete"), m_context);
413 command->setDefaultKeySequence(QKeySequence::Delete);
414 command->setAttribute(Core::Command::CA_Hide);
415 medit->addAction(command, Core::Constants::G_EDIT_COPYPASTE);
417 QList<int> globalcontext;
418 globalcontext << m_core->uniqueIDManager()->uniqueIdentifier(Core::Constants::C_GLOBAL);
420 m_actionGroupEditMode = new QActionGroup(this);
421 m_actionGroupEditMode->setExclusive(true);
422 connect(m_actionGroupEditMode, SIGNAL(triggered(QAction*)), this, SLOT(activateEditMode(QAction*)));
424 m_modeActionSeparator = new QAction(this);
425 m_modeActionSeparator->setSeparator(true);
426 command = am->registerAction(m_modeActionSeparator, QLatin1String("FormEditor.Sep.ModeActions"), globalcontext);
427 medit->addAction(command, Core::Constants::G_EDIT_OTHER);
429 m_toolActionIds.push_back(QLatin1String("FormEditor.WidgetEditor"));
430 createEditModeAction(m_actionGroupEditMode, globalcontext, am, medit,
431 tr("Edit widgets"), m_toolActionIds.back(),
432 EditModeWidgetEditor, QLatin1String("widgettool.png"), tr("F3"));
434 m_toolActionIds.push_back(QLatin1String("FormEditor.SignalsSlotsEditor"));
435 createEditModeAction(m_actionGroupEditMode, globalcontext, am, medit,
436 tr("Edit signals/slots"), m_toolActionIds.back(),
437 EditModeSignalsSlotEditor, QLatin1String("signalslottool.png"), tr("F4"));
439 m_toolActionIds.push_back(QLatin1String("FormEditor.BuddyEditor"));
440 createEditModeAction(m_actionGroupEditMode, globalcontext, am, medit,
441 tr("Edit buddies"), m_toolActionIds.back(),
442 EditModeBuddyEditor, QLatin1String("buddytool.png"));
444 m_toolActionIds.push_back(QLatin1String("FormEditor.TabOrderEditor"));
445 createEditModeAction(m_actionGroupEditMode, globalcontext, am, medit,
446 tr("Edit tab order"), m_toolActionIds.back(),
447 EditModeTabOrderEditor, QLatin1String("tabordertool.png"));
450 m_toolActionIds.push_back(QLatin1String("FormEditor.LayoutHorizontally"));
451 const QString horizLayoutShortcut = osMac ? tr("Meta+H") : tr("Ctrl+H");
452 addToolAction(m_fwm->actionHorizontalLayout(), am, globalcontext,
453 m_toolActionIds.back(), mformtools, horizLayoutShortcut);
455 m_toolActionIds.push_back(QLatin1String("FormEditor.LayoutVertically"));
456 const QString vertLayoutShortcut = osMac ? tr("Meta+L") : tr("Ctrl+L");
457 addToolAction(m_fwm->actionVerticalLayout(), am, globalcontext,
458 m_toolActionIds.back(), mformtools, vertLayoutShortcut);
460 m_toolActionIds.push_back(QLatin1String("FormEditor.SplitHorizontal"));
461 addToolAction(m_fwm->actionSplitHorizontal(), am, globalcontext,
462 m_toolActionIds.back(), mformtools);
464 m_toolActionIds.push_back(QLatin1String("FormEditor.SplitVertical"));
465 addToolAction(m_fwm->actionSplitVertical(), am, globalcontext,
466 m_toolActionIds.back(), mformtools);
468 m_toolActionIds.push_back(QLatin1String("FormEditor.LayoutForm"));
469 addToolAction(m_fwm->actionFormLayout(), am, globalcontext,
470 m_toolActionIds.back(), mformtools);
472 m_toolActionIds.push_back(QLatin1String("FormEditor.LayoutGrid"));
473 const QString gridShortcut = osMac ? tr("Meta+G") : tr("Ctrl+G");
474 addToolAction(m_fwm->actionGridLayout(), am, globalcontext,
475 m_toolActionIds.back(), mformtools, gridShortcut);
477 m_toolActionIds.push_back(QLatin1String("FormEditor.LayoutBreak"));
478 addToolAction(m_fwm->actionBreakLayout(), am, globalcontext,
479 m_toolActionIds.back(), mformtools);
481 m_toolActionIds.push_back(QLatin1String("FormEditor.LayoutAdjustSize"));
482 const QString adjustShortcut = osMac ? tr("Meta+J") : tr("Ctrl+J");
483 addToolAction(m_fwm->actionAdjustSize(), am, globalcontext,
484 m_toolActionIds.back(), mformtools, adjustShortcut);
486 m_toolActionIds.push_back(QLatin1String("FormEditor.SimplifyLayout"));
487 addToolAction(m_fwm->actionSimplifyLayout(), am, globalcontext,
488 m_toolActionIds.back(), mformtools);
490 createSeparator(this, am, m_context, mformtools, QLatin1String("FormEditor.Menu.Tools.Separator1"));
492 addToolAction(m_fwm->actionLower(), am, globalcontext,
493 QLatin1String("FormEditor.Lower"), mformtools);
495 addToolAction(m_fwm->actionRaise(), am, globalcontext,
496 QLatin1String("FormEditor.Raise"), mformtools);
499 createSeparator(this, am, globalcontext, mformtools, QLatin1String("FormEditor.Menu.Tools.SeparatorViews"));
501 Core::ActionContainer *mviews = am->createMenu(M_FORMEDITOR_VIEWS);
502 mviews->menu()->setTitle(tr("Views"));
503 mformtools->addMenu(mviews);
505 m_designerSubWindowActions[WidgetBoxSubWindow] = new ProxyAction(tr("Widget Box"), this);
506 addToolAction(m_designerSubWindowActions[WidgetBoxSubWindow], am, globalcontext,
507 QLatin1String("FormEditor.WidgetBox"), mviews, "");
509 m_designerSubWindowActions[ObjectInspectorSubWindow] = new ProxyAction(tr("Object Inspector"), this);
510 addToolAction(m_designerSubWindowActions[ObjectInspectorSubWindow], am, globalcontext,
511 QLatin1String("FormEditor.ObjectInspector"), mviews, "");
513 m_designerSubWindowActions[PropertyEditorSubWindow] = new ProxyAction(tr("Property Editor"), this);
514 addToolAction(m_designerSubWindowActions[PropertyEditorSubWindow], am, globalcontext,
515 QLatin1String("FormEditor.PropertyEditor"), mviews, "");
517 m_designerSubWindowActions[SignalSlotEditorSubWindow] = new ProxyAction(tr("Signals && Slots Editor"), this);
518 addToolAction(m_designerSubWindowActions[SignalSlotEditorSubWindow], am, globalcontext,
519 QLatin1String("FormEditor.SignalsAndSlotsEditor"), mviews, "");
521 m_designerSubWindowActions[ActionEditorSubWindow] = new ProxyAction(tr("Action Editor"), this);
522 addToolAction(m_designerSubWindowActions[ActionEditorSubWindow], am, globalcontext,
523 QLatin1String("FormEditor.ActionEditor"), mviews, "");
525 createSeparator(this, am, globalcontext, mviews, QLatin1String("FormEditor.Menu.Tools.Views.SeparatorLock"));
527 m_lockAction = new QAction(tr("Locked"), this);
528 m_lockAction->setCheckable(true);
529 addToolAction(m_lockAction, am, globalcontext, QLatin1String("FormEditor.Locked"), mviews, "");
530 connect(m_lockAction, SIGNAL(toggled(bool)), this, SLOT(setFormWindowLayoutLocked(bool)));
532 createSeparator(this, am, globalcontext, mviews, QLatin1String("FormEditor.Menu.Tools.Views.SeparatorReset"));
534 m_resetLayoutAction = new QAction(tr("Reset to Default Layout"), this);
535 addToolAction(m_resetLayoutAction, am, globalcontext, QLatin1String("FormEditor.ResetToDefaultLayout"), mviews, "");
536 connect(m_resetLayoutAction, SIGNAL(triggered()), this, SLOT(resetToDefaultLayout()));
538 // Commands that do not go into the editor toolbar
539 createSeparator(this, am, globalcontext, mformtools, QLatin1String("FormEditor.Menu.Tools.Separator2"));
541 m_actionPreview = m_fwm->actionDefaultPreview();
542 QTC_ASSERT(m_actionPreview, return);
543 addToolAction(m_actionPreview, am, globalcontext,
544 QLatin1String("FormEditor.Preview"), mformtools, tr("Ctrl+Alt+R"));
546 // Preview in style...
547 m_actionGroupPreviewInStyle = m_fwm->actionGroupPreviewInStyle();
548 mformtools->addMenu(createPreviewStyleMenu(am, m_actionGroupPreviewInStyle));
551 createSeparator(this, am, m_context, medit, QLatin1String("FormEditor.Edit.Separator2"), Core::Constants::G_EDIT_OTHER);
553 createSeparator(this, am, globalcontext, mformtools, QLatin1String("FormEditor.Menu.Tools.Separator3"));
554 QAction *actionFormSettings = m_fwm->actionShowFormWindowSettingsDialog();
555 addToolAction(actionFormSettings, am, globalcontext, QLatin1String("FormEditor.FormSettings"), mformtools);
557 #if QT_VERSION > 0x040500
558 createSeparator(this, am, globalcontext, mformtools, QLatin1String("FormEditor.Menu.Tools.Separator4"));
559 m_actionAboutPlugins = new QAction(tr("About Qt Designer plugins...."), this);
560 addToolAction(m_actionAboutPlugins, am, globalcontext,
561 QLatin1String("FormEditor.AboutPlugins"), mformtools);
562 connect(m_actionAboutPlugins, SIGNAL(triggered()), m_fwm, SLOT(aboutPlugins()));
563 m_actionAboutPlugins->setEnabled(false);
567 connect(m_fwm, SIGNAL(activeFormWindowChanged(QDesignerFormWindowInterface *)), this, SLOT(activeFormWindowChanged(QDesignerFormWindowInterface *)));
571 QToolBar *FormEditorW::createEditorToolBar() const
573 QToolBar *toolBar = new QToolBar;
574 Core::ActionManager *am = m_core->actionManager();
575 const QStringList::const_iterator cend = m_toolActionIds.constEnd();
576 for (QStringList::const_iterator it = m_toolActionIds.constBegin(); it != cend; ++it) {
577 Core::Command *cmd = am->command(*it);
578 QTC_ASSERT(cmd, continue);
579 QAction *action = cmd->action();
580 if (!action->icon().isNull()) // Simplify grid has no action yet
581 toolBar->addAction(action);
583 int size = toolBar->style()->pixelMetric(QStyle::PM_SmallIconSize);
584 toolBar->setIconSize(QSize(size, size));
585 toolBar->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
589 Core::ActionContainer *FormEditorW::createPreviewStyleMenu(Core::ActionManager *am,
590 QActionGroup *actionGroup)
592 const QString menuId = QLatin1String(M_FORMEDITOR_PREVIEW);
593 Core::ActionContainer *menuPreviewStyle = am->createMenu(menuId);
594 menuPreviewStyle->menu()->setTitle(tr("Preview in"));
596 // The preview menu is a list of invisible actions for the embedded design
597 // device profiles (integer data) followed by a separator and the styles
598 // (string data). Make device profiles update their text and hide them
599 // in the configuration dialog.
600 const QList<QAction*> actions = actionGroup->actions();
602 const QString deviceProfilePrefix = QLatin1String("DeviceProfile");
603 const QChar dot = QLatin1Char('.');
605 foreach (QAction* a, actions) {
606 QString name = menuId;
608 const QVariant data = a->data();
609 const bool isDeviceProfile = data.type() == QVariant::Int;
610 if (isDeviceProfile) {
611 name += deviceProfilePrefix;
614 name += data.toString();
615 Core::Command *command = am->registerAction(a, name, m_context);
616 if (isDeviceProfile) {
617 command->setAttribute(Core::Command::CA_UpdateText);
618 command->setAttribute(Core::Command::CA_NonConfigureable);
620 menuPreviewStyle->addAction(command);
622 return menuPreviewStyle;
625 void FormEditorW::saveSettings(QSettings *s)
627 s->beginGroup(settingsGroup);
628 EditorWidget::saveState(s);
632 void FormEditorW::restoreSettings(QSettings *s)
634 s->beginGroup(settingsGroup);
635 EditorWidget::restoreState(s);
640 void FormEditorW::critical(const QString &errorMessage)
642 QMessageBox::critical(m_core->mainWindow(), tr("Designer"), errorMessage);
645 FormWindowEditor *FormEditorW::createFormWindowEditor(QWidget* parentWidget)
647 m_fwm->closeAllPreviews();
648 QDesignerFormWindowInterface *form = m_fwm->createFormWindow(0);
649 connect(form, SIGNAL(toolChanged(int)), this, SLOT(toolChanged(int)));
650 qdesigner_internal::FormWindowBase::setupDefaultAction(form);
651 FormWindowEditor *fww = new FormWindowEditor(m_context, form, parentWidget);
652 // Store a pointer to all form windows so we can unselect
653 // all other formwindows except the active one.
654 m_formWindows.append(fww);
655 connect(fww, SIGNAL(destroyed()), this, SLOT(editorDestroyed()));
659 void FormEditorW::editorDestroyed()
661 QObject *source = sender();
663 if (Designer::Constants::Internal::debug)
664 qDebug() << Q_FUNC_INFO << source;
666 for (EditorList::iterator it = m_formWindows.begin(); it != m_formWindows.end(); ) {
668 it = m_formWindows.erase(it);
676 void FormEditorW::currentEditorChanged(Core::IEditor *editor)
678 if (Designer::Constants::Internal::debug)
679 qDebug() << Q_FUNC_INFO << editor << " of " << m_fwm->formWindowCount();
681 // Deactivate Designer if a non-form is being edited
682 if (editor && !qstrcmp(editor->kind(), Constants::C_FORMEDITOR)) {
683 FormWindowEditor *fw = qobject_cast<FormWindowEditor *>(editor);
684 QTC_ASSERT(fw, return);
686 m_fwm->setActiveFormWindow(fw->formWindow());
687 m_actionGroupEditMode->setVisible(true);
688 m_modeActionSeparator->setVisible(true);
689 QDockWidget * const*dockWidgets = fw->dockWidgets();
690 for (int i = 0; i < Designer::Constants::DesignerSubWindowCount; ++i) {
691 if (m_designerSubWindowActions[i] != 0 && dockWidgets[i] != 0)
692 m_designerSubWindowActions[i]->setAction(dockWidgets[i]->toggleViewAction());
694 m_lockAction->setEnabled(true);
695 m_lockAction->setChecked(fw->isLocked());
696 m_resetLayoutAction->setEnabled(true);
698 m_actionGroupEditMode->setVisible(false);
699 m_modeActionSeparator->setVisible(false);
700 m_fwm->setActiveFormWindow(0);
701 for (int i = 0; i < Designer::Constants::DesignerSubWindowCount; ++i) {
702 if (m_designerSubWindowActions[i] != 0)
703 m_designerSubWindowActions[i]->setAction(0);
705 m_lockAction->setEnabled(false);
706 m_resetLayoutAction->setEnabled(false);
710 void FormEditorW::activeFormWindowChanged(QDesignerFormWindowInterface *afw)
712 if (Designer::Constants::Internal::debug)
713 qDebug() << Q_FUNC_INFO << afw << " of " << m_fwm->formWindowCount() << m_formWindows;
715 m_fwm->closeAllPreviews();
717 bool foundFormWindow = false;
718 // Display form selection handles only on active window
719 EditorList::const_iterator cend = m_formWindows.constEnd();
720 for (EditorList::const_iterator it = m_formWindows.constBegin(); it != cend ; ++it) {
721 FormWindowEditor *fwe = *it;
722 const bool active = fwe->formWindow() == afw;
724 foundFormWindow = true;
725 fwe->updateFormWindowSelectionHandles(active);
728 m_actionPreview->setEnabled(foundFormWindow);
729 m_actionGroupPreviewInStyle->setEnabled(foundFormWindow);
732 FormWindowEditor *FormEditorW::activeFormWindow()
734 QDesignerFormWindowInterface *afw = m_fwm->activeFormWindow();
735 for (int i = 0; i < m_formWindows.count(); ++i) {
736 if (FormWindowEditor *fw = m_formWindows[i]) {
737 QDesignerFormWindowInterface *fwd = fw->formWindow();
746 void FormEditorW::activateEditMode(int id)
748 if (const int count = m_fwm->formWindowCount())
749 for (int i = 0; i < count; i++)
750 m_fwm->formWindow(i)->setCurrentTool(id);
753 void FormEditorW::activateEditMode(QAction* a)
755 activateEditMode(a->data().toInt());
758 void FormEditorW::toolChanged(int t)
760 typedef QList<QAction *> ActionList;
761 if (const QAction *currentAction = m_actionGroupEditMode->checkedAction())
762 if (currentAction->data().toInt() == t)
764 const ActionList actions = m_actionGroupEditMode->actions();
765 const ActionList::const_iterator cend = actions.constEnd();
766 for (ActionList::const_iterator it = actions.constBegin(); it != cend; ++it)
767 if ( (*it)->data().toInt() == t) {
768 (*it)->setChecked(true);
773 void FormEditorW::setFormWindowLayoutLocked(bool locked)
775 FormWindowEditor *fwe = activeFormWindow();
777 fwe->setLocked(locked);
780 void FormEditorW::resetToDefaultLayout()
782 FormWindowEditor *fwe = activeFormWindow();
784 fwe->resetToDefaultLayout();
787 void FormEditorW::print()
789 // Printing code courtesy of designer_actions.cpp
790 QDesignerFormWindowInterface *fw = m_fwm->activeFormWindow();
794 const bool oldFullPage = m_core->printer()->fullPage();
795 const QPrinter::Orientation oldOrientation = m_core->printer()->orientation ();
796 m_core->printer()->setFullPage(false);
799 // Grab the image to be able to a suggest suitable orientation
800 QString errorMessage;
801 const QPixmap pixmap = m_fwm->createPreviewPixmap(&errorMessage);
802 if (pixmap.isNull()) {
803 critical(tr("The image could not be created: %1").arg(errorMessage));
807 const QSizeF pixmapSize = pixmap.size();
808 m_core->printer()->setOrientation( pixmapSize.width() > pixmapSize.height() ? QPrinter::Landscape : QPrinter::Portrait);
810 // Printer parameters
811 QPrintDialog dialog(m_core->printer(), fw);
815 const QCursor oldCursor = m_core->mainWindow()->cursor();
816 m_core->mainWindow()->setCursor(Qt::WaitCursor);
817 // Estimate of required scaling to make form look the same on screen and printer.
818 const double suggestedScaling = static_cast<double>(m_core->printer()->physicalDpiX()) / static_cast<double>(fw->physicalDpiX());
820 QPainter painter(m_core->printer());
821 painter.setRenderHint(QPainter::SmoothPixmapTransform);
824 const QRectF page = painter.viewport();
825 const double maxScaling = qMin(page.size().width() / pixmapSize.width(), page.size().height() / pixmapSize.height());
826 const double scaling = qMin(suggestedScaling, maxScaling);
828 const double xOffset = page.left() + qMax(0.0, (page.size().width() - scaling * pixmapSize.width()) / 2.0);
829 const double yOffset = page.top() + qMax(0.0, (page.size().height() - scaling * pixmapSize.height()) / 2.0);
832 painter.translate(xOffset, yOffset);
833 painter.scale(scaling, scaling);
834 painter.drawPixmap(0, 0, pixmap);
835 m_core->mainWindow()->setCursor(oldCursor);
838 m_core->printer()->setFullPage(oldFullPage);
839 m_core->printer()->setOrientation(oldOrientation);