OSDN Git Service

Fixes: cmd+h (hide) is overridden by designer's layout horizontally
[qt-creator-jp/qt-creator-jp.git] / src / plugins / designer / formeditorw.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact:  Qt Software Information (qt-info@nokia.com)
8 **
9 ** Commercial Usage
10 **
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.
15 **
16 ** GNU Lesser General Public License Usage
17 **
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.
24 **
25 ** If you are unsure which license is appropriate for your use, please
26 ** contact the sales department at qt-sales@nokia.com.
27 **
28 **************************************************************************/
29
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 "workbenchintegration.h"
37
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>
45
46 #include <QtDesigner/QDesignerFormEditorPluginInterface>
47 #include <qt_private/pluginmanager_p.h>
48
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>
54
55 #include <QtDesigner/QDesignerWidgetBoxInterface>
56 #include <QtDesigner/abstractobjectinspector.h>
57 #include <QtDesigner/QDesignerComponents>
58 #include <QtDesigner/QDesignerPropertyEditorInterface>
59 #include <QtDesigner/QDesignerActionEditorInterface>
60
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/QMenu>
70 #include <QtGui/QMainWindow>
71 #include <QtGui/QMessageBox>
72 #include <QtGui/QKeySequence>
73 #include <QtGui/QPrintDialog>
74 #include <QtGui/QPrinter>
75 #include <QtGui/QPainter>
76 #include <QtGui/QStatusBar>
77 #include <QtGui/QStyle>
78 #include <QtGui/QToolBar>
79
80 #include <QtCore/QDebug>
81 #include <QtCore/QSettings>
82
83 static const char *editorWidgetStateKeyC = "editorWidgetState";
84 static const char *settingsGroup = "Designer";
85
86 static inline QIcon designerIcon(const QString &iconName)
87 {
88     const QIcon icon = qdesigner_internal::createIconSet(iconName);
89     if (icon.isNull())
90         qWarning() << "Unable to locate " << iconName;
91     return icon;
92 }
93
94 // Create an action to activate a designer tool
95 static inline QAction *createEditModeAction(QActionGroup *ag,
96                                      const QList<int> &context,
97                                      Core::ActionManager *am,
98                                      Core::ActionContainer *medit,
99                                      const QString &actionName,
100                                      const QString &name,
101                                      int toolNumber,
102                                      const QString &iconName =  QString(),
103                                      const QString &keySequence = QString())
104 {
105     QAction *rc = new QAction(actionName, ag);
106     rc->setCheckable(true);
107     if (!iconName.isEmpty())
108          rc->setIcon(designerIcon(iconName));
109     Core::Command *command = am->registerAction(rc, name, context);
110     if (!keySequence.isEmpty())
111         command->setDefaultKeySequence(QKeySequence(keySequence));
112     command->setAttribute(Core::Command::CA_Hide);
113     medit->addAction(command, Core::Constants::G_EDIT_OTHER);
114     rc->setData(toolNumber);
115     ag->addAction(rc);
116     return rc;
117 }
118
119
120 // Create a menu separato
121 static inline QAction * createSeparator(QObject *parent,
122                                  Core::ActionManager *am,
123                                  const QList<int> &context,
124                                  Core::ActionContainer *container,
125                                  const QString &name = QString(),
126                                  const QString &group = QString())
127 {
128     QAction *actSeparator = new QAction(parent);
129     actSeparator->setSeparator(true);
130     Core::Command *command = am->registerAction(actSeparator, name, context);
131     container->addAction(command, group);
132     return actSeparator;
133 }
134
135 // Create a tool action
136 static inline void addToolAction(QAction *a,
137                    Core::ActionManager *am,
138                    const QList<int> &context,
139                    const QString &name,
140                    Core::ActionContainer *c1,
141                    const QString &keySequence = QString())
142 {
143     Core::Command *command = am->registerAction(a, name, context);
144     if (!keySequence.isEmpty())
145         command->setDefaultKeySequence(QKeySequence(keySequence));
146     c1->addAction(command);
147 }
148
149 // --------- FormEditorW
150
151 using namespace Designer::Internal;
152 using namespace Designer::Constants;
153
154 FormEditorW *FormEditorW::m_self = 0;
155
156 FormEditorW::FormEditorW() :
157     m_formeditor(QDesignerComponents::createFormEditor(0)),
158     m_integration(0),
159     m_fwm(0),
160     m_core(Core::ICore::instance()),
161     m_initStage(RegisterPlugins),
162     m_actionGroupEditMode(0),
163     m_actionPrint(0)
164 {
165     if (Designer::Constants::Internal::debug)
166         qDebug() << Q_FUNC_INFO;
167     QTC_ASSERT(!m_self, return);
168     m_self = this;
169     QTC_ASSERT(m_core, return);
170
171     qFill(m_designerSubWindows, m_designerSubWindows + Designer::Constants::DesignerSubWindowCount,
172           static_cast<QWidget *>(0));
173
174     m_formeditor->setTopLevel(qobject_cast<QWidget *>(m_core->editorManager()));
175     m_formeditor->setSettingsManager(new SettingsManager());
176
177     m_fwm = qobject_cast<qdesigner_internal::QDesignerFormWindowManager*>(m_formeditor->formWindowManager());
178     QTC_ASSERT(m_fwm, return);
179
180     const int uid = m_core->uniqueIDManager()->uniqueIdentifier(QLatin1String(C_FORMEDITOR));
181     m_context << uid;
182
183     setupActions();
184
185     foreach (QDesignerOptionsPageInterface *designerPage, m_formeditor->optionsPages()) {
186         SettingsPage *settingsPage = new SettingsPage(designerPage);
187         ExtensionSystem::PluginManager::instance()->addObject(settingsPage);
188         m_settingsPages.append(settingsPage);
189     }
190     restoreSettings(m_core->settings());
191
192     connect(m_core->editorManager(), SIGNAL(currentEditorChanged(Core::IEditor *)),
193             this, SLOT(currentEditorChanged(Core::IEditor *)));
194 }
195
196 FormEditorW::~FormEditorW()
197 {
198     saveSettings(m_core->settings());
199
200     for (int i = 0; i < Designer::Constants::DesignerSubWindowCount; ++i)
201         delete m_designerSubWindows[i];
202
203     delete m_formeditor;
204     foreach (SettingsPage *settingsPage, m_settingsPages) {
205         ExtensionSystem::PluginManager::instance()->removeObject(settingsPage);
206         delete settingsPage;
207     }
208     delete  m_integration;
209     m_self = 0;
210 }
211
212 void FormEditorW::fullInit()
213 {
214     QTC_ASSERT(m_initStage == RegisterPlugins, return);
215     QTime *initTime = 0;
216     if (Designer::Constants::Internal::debug) {
217         initTime = new QTime;
218         initTime->start();
219     }
220
221     QDesignerComponents::createTaskMenu(m_formeditor, parent());
222     QDesignerComponents::initializePlugins(designerEditor());
223     QDesignerComponents::initializeResources();
224     initDesignerSubWindows();
225     m_integration = new WorkbenchIntegration(m_formeditor, this);
226     m_formeditor->setIntegration(m_integration);
227
228     /**
229      * This will initialize our TabOrder, Signals and slots and Buddy editors.
230      */
231     QList<QObject*> plugins = QPluginLoader::staticInstances();
232     plugins += m_formeditor->pluginManager()->instances();
233     foreach (QObject *plugin, plugins) {
234         if (QDesignerFormEditorPluginInterface *formEditorPlugin = qobject_cast<QDesignerFormEditorPluginInterface*>(plugin)) {
235             if (!formEditorPlugin->isInitialized())
236                 formEditorPlugin->initialize(m_formeditor);
237         }
238     }
239
240     if (Designer::Constants::Internal::debug) {
241         qDebug() << Q_FUNC_INFO << initTime->elapsed() << "ms";
242         delete initTime;
243     }
244     m_initStage = FullyInitialized;
245 }
246
247 void FormEditorW::initDesignerSubWindows()
248 {
249     qFill(m_designerSubWindows, m_designerSubWindows + Designer::Constants::DesignerSubWindowCount, static_cast<QWidget*>(0));
250
251     QDesignerWidgetBoxInterface *wb = QDesignerComponents::createWidgetBox(m_formeditor, 0);
252     wb->setWindowTitle(tr("Designer widgetbox"));
253     m_formeditor->setWidgetBox(wb);
254     m_designerSubWindows[WidgetBoxSubWindow] = wb;
255
256     QDesignerObjectInspectorInterface *oi = QDesignerComponents::createObjectInspector(m_formeditor, 0);
257     oi->setWindowTitle(tr("Object inspector"));
258     m_formeditor->setObjectInspector(oi);
259     m_designerSubWindows[ObjectInspectorSubWindow] = oi;
260
261     QDesignerPropertyEditorInterface *pe = QDesignerComponents::createPropertyEditor(m_formeditor, 0);
262     pe->setWindowTitle(tr("Property editor"));
263     m_formeditor->setPropertyEditor(pe);
264     m_designerSubWindows[PropertyEditorSubWindow] = pe;
265
266     QWidget *se = QDesignerComponents::createSignalSlotEditor(m_formeditor, 0);
267     se->setWindowTitle(tr("Signals and slots editor"));
268     m_designerSubWindows[SignalSlotEditorSubWindow] = se;
269
270     QDesignerActionEditorInterface *ae = QDesignerComponents::createActionEditor(m_formeditor, 0);
271     ae->setWindowTitle(tr("Action editor"));
272     m_formeditor->setActionEditor(ae);
273     m_designerSubWindows[ActionEditorSubWindow] = ae;
274 }
275
276 void FormEditorW::ensureInitStage(InitializationStage s)
277 {
278     if (Designer::Constants::Internal::debug)
279         qDebug() << Q_FUNC_INFO << s;
280     if (!m_self)
281         m_self = new FormEditorW;
282     if (m_self->m_initStage >= s)
283         return;
284     QApplication::setOverrideCursor(Qt::WaitCursor);
285     m_self->fullInit();
286     QApplication::restoreOverrideCursor();
287 }
288
289 FormEditorW *FormEditorW::instance()
290 {
291     ensureInitStage(FullyInitialized);
292     return m_self;
293 }
294
295 void FormEditorW::deleteInstance()
296 {
297     delete m_self;
298 }
299
300 void FormEditorW::setupActions()
301 {
302     Core::ActionManager *am = m_core->actionManager();
303     Core::Command *command;
304
305     //menus
306     Core::ActionContainer *medit =
307         am->actionContainer(Core::Constants::M_EDIT);
308     Core::ActionContainer *mtools =
309         am->actionContainer(Core::Constants::M_TOOLS);
310
311     Core::ActionContainer *mformtools =
312         am->createMenu(M_FORMEDITOR);
313     mformtools->menu()->setTitle(tr("For&m editor"));
314     mtools->addMenu(mformtools);
315
316     //overridden actions
317     am->registerAction(m_fwm->actionUndo(), Core::Constants::UNDO, m_context);
318     am->registerAction(m_fwm->actionRedo(), Core::Constants::REDO, m_context);
319     am->registerAction(m_fwm->actionCut(), Core::Constants::CUT, m_context);
320     am->registerAction(m_fwm->actionCopy(), Core::Constants::COPY, m_context);
321     am->registerAction(m_fwm->actionPaste(), Core::Constants::PASTE, m_context);
322     am->registerAction(m_fwm->actionSelectAll(), Core::Constants::SELECTALL, m_context);
323
324     m_actionPrint = new QAction(this);
325     am->registerAction(m_actionPrint, Core::Constants::PRINT, m_context);
326     connect(m_actionPrint, SIGNAL(triggered()), this, SLOT(print()));
327
328     //'delete' action
329     command = am->registerAction(m_fwm->actionDelete(), QLatin1String("FormEditor.Edit.Delete"), m_context);
330     command->setDefaultKeySequence(QKeySequence::Delete);
331     command->setAttribute(Core::Command::CA_Hide);
332     medit->addAction(command, Core::Constants::G_EDIT_COPYPASTE);
333
334     //editor Modes. Store ids for editor tool bars
335     m_actionGroupEditMode = new QActionGroup(this);
336     m_actionGroupEditMode->setExclusive(true);
337     connect(m_actionGroupEditMode, SIGNAL(triggered(QAction*)), this, SLOT(activateEditMode(QAction*)));
338
339     m_toolActionIds.push_back(QLatin1String("FormEditor.WidgetEditor"));
340     createEditModeAction(m_actionGroupEditMode, m_context, am, medit,
341                          QLatin1String("Edit widgets"), m_toolActionIds.back(),
342                          EditModeWidgetEditor, QLatin1String("widgettool.png"), tr("F3"));
343
344     m_toolActionIds.push_back(QLatin1String("FormEditor.SignalsSlotsEditor"));
345     createEditModeAction(m_actionGroupEditMode,  m_context, am, medit,
346                          QLatin1String("Edit signals/slots"), m_toolActionIds.back(),
347                          EditModeSignalsSlotEditor, QLatin1String("signalslottool.png"), tr("F4"));
348
349     m_toolActionIds.push_back(QLatin1String("FormEditor.BuddyEditor"));
350     createEditModeAction(m_actionGroupEditMode,  m_context, am, medit,
351                          QLatin1String("Edit buddies"), m_toolActionIds.back(),
352                          EditModeBuddyEditor, QLatin1String("buddytool.png"));
353
354     m_toolActionIds.push_back(QLatin1String("FormEditor.TabOrderEditor"));
355     createEditModeAction(m_actionGroupEditMode,  m_context, am, medit,
356                          QLatin1String("Edit tab order"),  m_toolActionIds.back(),
357                          EditModeTabOrderEditor, QLatin1String("tabordertool.png"));
358
359     //tool actions
360     m_toolActionIds.push_back(QLatin1String("FormEditor.LayoutHorizontally"));
361 #ifndef Q_OS_MAC
362     addToolAction(m_fwm->actionHorizontalLayout(), am, m_context,
363                   m_toolActionIds.back(), mformtools, tr("Ctrl+H"));
364 #else
365     addToolAction(m_fwm->actionHorizontalLayout(), am, m_context,
366                   m_toolActionIds.back(), mformtools, tr("Meta+H"));
367 #endif
368     m_toolActionIds.push_back(QLatin1String("FormEditor.LayoutVertically"));
369 #ifndef Q_OS_MAC
370     addToolAction(m_fwm->actionVerticalLayout(), am, m_context,
371                   m_toolActionIds.back(),  mformtools, tr("Ctrl+L"));
372 #else
373     addToolAction(m_fwm->actionVerticalLayout(), am, m_context,
374                   m_toolActionIds.back(),  mformtools, tr("Meta+L"));
375 #endif
376
377     m_toolActionIds.push_back(QLatin1String("FormEditor.SplitHorizontal"));
378     addToolAction(m_fwm->actionSplitHorizontal(), am, m_context,
379                   m_toolActionIds.back(), mformtools);
380
381     m_toolActionIds.push_back(QLatin1String("FormEditor.SplitVertical"));
382     addToolAction(m_fwm->actionSplitVertical(), am, m_context,
383                   m_toolActionIds.back(), mformtools);
384
385     m_toolActionIds.push_back(QLatin1String("FormEditor.LayoutForm"));
386     addToolAction(m_fwm->actionFormLayout(), am, m_context,
387                   m_toolActionIds.back(),  mformtools);
388
389     m_toolActionIds.push_back(QLatin1String("FormEditor.LayoutGrid"));
390 #ifndef Q_OS_MAC
391     addToolAction(m_fwm->actionGridLayout(), am, m_context,
392                   m_toolActionIds.back(),  mformtools, tr("Ctrl+G"));
393 #else
394     addToolAction(m_fwm->actionGridLayout(), am, m_context,
395                   m_toolActionIds.back(),  mformtools, tr("Meta+G"));
396 #endif
397
398     m_toolActionIds.push_back(QLatin1String("FormEditor.LayoutBreak"));
399     addToolAction(m_fwm->actionBreakLayout(), am, m_context,
400                   m_toolActionIds.back(), mformtools);
401
402     m_toolActionIds.push_back(QLatin1String("FormEditor.LayoutAdjustSize"));
403 #ifndef Q_OS_MAC
404     addToolAction(m_fwm->actionAdjustSize(), am, m_context,
405                   m_toolActionIds.back(),  mformtools, tr("Ctrl+J"));
406 #else
407     addToolAction(m_fwm->actionAdjustSize(), am, m_context,
408                   m_toolActionIds.back(),  mformtools, tr("Meta+J"));
409 #endif
410
411     m_toolActionIds.push_back(QLatin1String("FormEditor.SimplifyLayout"));
412     addToolAction(m_fwm->actionSimplifyLayout(), am, m_context,
413                   m_toolActionIds.back(),  mformtools);
414
415     createSeparator(this, am, m_context, mformtools, QLatin1String("FormEditor.Menu.Tools.Separator1"));
416
417     addToolAction(m_fwm->actionLower(), am, m_context,
418                   QLatin1String("FormEditor.Lower"), mformtools);
419
420     addToolAction(m_fwm->actionRaise(), am, m_context,
421                   QLatin1String("FormEditor.Raise"), mformtools);
422
423     // Commands that do not go into the editor toolbar
424     createSeparator(this, am, m_context, mformtools, QLatin1String("FormEditor.Menu.Tools.Separator2"));
425
426     m_actionPreview = m_fwm->actionDefaultPreview();
427     QTC_ASSERT(m_actionPreview, return);
428     addToolAction(m_actionPreview,  am,  m_context,
429                    QLatin1String("FormEditor.Preview"), mformtools, tr("Ctrl+Alt+R"));
430
431     // Preview in style...
432     m_actionGroupPreviewInStyle = m_fwm->actionGroupPreviewInStyle();
433     mformtools->addMenu(createPreviewStyleMenu(am, m_actionGroupPreviewInStyle));
434
435     // Form settings
436     createSeparator(this, am, m_context,  medit, QLatin1String("FormEditor.Edit.Separator2"), Core::Constants::G_EDIT_OTHER);
437
438 #if QT_VERSION >= 0x040500
439     createSeparator(this, am, m_context, mformtools, QLatin1String("FormEditor.Menu.Tools.Separator3"));
440     QAction *actionFormSettings = m_fwm->actionShowFormWindowSettingsDialog();
441     addToolAction(actionFormSettings, am, m_context, QLatin1String("FormEditor.FormSettings"), mformtools);
442 #endif
443     // FWM
444     connect(m_fwm, SIGNAL(activeFormWindowChanged(QDesignerFormWindowInterface *)), this, SLOT(activeFormWindowChanged(QDesignerFormWindowInterface *)));
445 }
446
447
448 QToolBar *FormEditorW::createEditorToolBar() const
449 {
450     QToolBar *rc = new QToolBar;
451     rc->addSeparator();
452     Core::ActionManager *am = m_core->actionManager();
453     const QStringList::const_iterator cend = m_toolActionIds.constEnd();
454     for (QStringList::const_iterator it = m_toolActionIds.constBegin(); it != cend; ++it) {
455         Core::Command *cmd = am->command(*it);
456         QTC_ASSERT(cmd, continue);
457         QAction *action = cmd->action();
458         if (!action->icon().isNull()) // Simplify grid has no action yet
459             rc->addAction(action);
460     }
461     int size = rc->style()->pixelMetric(QStyle::PM_SmallIconSize);
462     rc->setIconSize(QSize(size, size));
463     return rc;
464 }
465
466 Core::ActionContainer *FormEditorW::createPreviewStyleMenu(Core::ActionManager *am,
467                                                             QActionGroup *actionGroup)
468 {
469     const QString menuId = QLatin1String(M_FORMEDITOR_PREVIEW);
470     Core::ActionContainer *menuPreviewStyle = am->createMenu(menuId);
471     menuPreviewStyle->menu()->setTitle(tr("Preview in"));
472
473     // The preview menu is a list of invisible actions for the embedded design
474     // device profiles (integer data) followed by a separator and the styles
475     // (string data). Make device profiles update their text and hide them
476     // in the configuration dialog.
477     const QList<QAction*> actions = actionGroup->actions();
478
479     const QString deviceProfilePrefix = QLatin1String("DeviceProfile");
480     const QChar dot = QLatin1Char('.');
481
482     foreach (QAction* a, actions) {
483         QString name = menuId;
484         name += dot;
485         const QVariant data = a->data();
486         const bool isDeviceProfile = data.type() == QVariant::Int;
487         if (isDeviceProfile) {
488             name += deviceProfilePrefix;
489             name += dot;
490         }
491         name += data.toString();
492         Core::Command *command = am->registerAction(a, name, m_context);
493         if (isDeviceProfile) {
494             command->setAttribute(Core::Command::CA_UpdateText);
495             command->setAttribute(Core::Command::CA_NonConfigureable);
496         }
497         menuPreviewStyle->addAction(command);
498     }
499     return menuPreviewStyle;
500 }
501
502 void FormEditorW::saveSettings(QSettings *s)
503 {
504     s->beginGroup(settingsGroup);
505     s->setValue(QLatin1String(editorWidgetStateKeyC), EditorWidget::state().toVariant());
506     s->endGroup();
507 }
508
509 void FormEditorW::restoreSettings(const QSettings *s)
510 {
511     QString key = QLatin1String(settingsGroup) + QLatin1Char('/')
512                                 + QLatin1String(editorWidgetStateKeyC);
513     const QVariant ev = s->value(key);
514     if (ev.type() != QVariant::Invalid) {
515         EditorWidgetState st;
516         if (st.fromVariant(ev))
517             EditorWidget::setState(st);
518     }
519 }
520
521
522 void FormEditorW::critical(const QString &errorMessage)
523 {
524     QMessageBox::critical(m_core->mainWindow(), tr("Designer"),  errorMessage);
525 }
526
527 FormWindowEditor *FormEditorW::createFormWindowEditor(QWidget* parentWidget)
528 {
529     m_fwm->closeAllPreviews();
530     QDesignerFormWindowInterface *form = m_fwm->createFormWindow(0);
531     connect(form, SIGNAL(toolChanged(int)), this, SLOT(toolChanged(int)));
532     qdesigner_internal::FormWindowBase::setupDefaultAction(form);
533     FormWindowEditor *fww = new FormWindowEditor(m_context, form, parentWidget);
534     // Store a pointer to all form windows so we can unselect
535     // all other formwindows except the active one.
536     m_formWindows.append(fww);
537     connect(fww, SIGNAL(destroyed()), this, SLOT(editorDestroyed()));
538     return fww;
539 }
540
541 void FormEditorW::editorDestroyed()
542 {
543     QObject *source = sender();
544
545     if (Designer::Constants::Internal::debug)
546         qDebug() << Q_FUNC_INFO << source;
547
548     for (EditorList::iterator it = m_formWindows.begin(); it != m_formWindows.end(); ) {
549         if (*it == source) {
550             it = m_formWindows.erase(it);
551             break;
552         } else {
553             ++it;
554         }
555     }
556 }
557
558 void FormEditorW::currentEditorChanged(Core::IEditor *editor)
559 {
560     if (Designer::Constants::Internal::debug)
561         qDebug() << Q_FUNC_INFO << editor << " of " << m_fwm->formWindowCount();
562
563     // Deactivate Designer if a non-form is being edited
564     if (editor && !qstrcmp(editor->kind(), Constants::C_FORMEDITOR)) {
565         FormWindowEditor *fw = qobject_cast<FormWindowEditor *>(editor);
566         QTC_ASSERT(fw, return);
567         fw->activate();
568         m_fwm->setActiveFormWindow(fw->formWindow());
569     } else {
570         m_fwm->setActiveFormWindow(0);
571     }
572 }
573
574 void FormEditorW::activeFormWindowChanged(QDesignerFormWindowInterface *afw)
575 {
576     if (Designer::Constants::Internal::debug)
577         qDebug() << Q_FUNC_INFO << afw << " of " << m_fwm->formWindowCount() << m_formWindows;
578
579     m_fwm->closeAllPreviews();
580
581     bool foundFormWindow = false;
582     // Display form selection handles only on active window
583     EditorList::const_iterator cend = m_formWindows.constEnd();
584     for (EditorList::const_iterator it = m_formWindows.constBegin(); it != cend ; ++it) {
585         FormWindowEditor *fwe = *it;
586         const bool active = fwe->formWindow() == afw;
587         if (active)
588             foundFormWindow = true;
589         fwe->updateFormWindowSelectionHandles(active);
590     }
591
592     m_actionPreview->setEnabled(foundFormWindow);
593     m_actionGroupPreviewInStyle->setEnabled(foundFormWindow);
594 }
595
596 FormWindowEditor *FormEditorW::activeFormWindow()
597 {
598     QDesignerFormWindowInterface *afw = m_fwm->activeFormWindow();
599     for (int i = 0; i < m_formWindows.count(); ++i) {
600         if (FormWindowEditor *fw = m_formWindows[i]) {
601             QDesignerFormWindowInterface *fwd = fw->formWindow();
602             if (fwd == afw) {
603                 return fw;
604             }
605         }
606     }
607     return 0;
608 }
609
610 void FormEditorW::activateEditMode(int id)
611 {
612     if (const int count = m_fwm->formWindowCount())
613         for (int i = 0; i <  count; i++)
614              m_fwm->formWindow(i)->setCurrentTool(id);
615 }
616
617 void FormEditorW::activateEditMode(QAction* a)
618 {
619     activateEditMode(a->data().toInt());
620 }
621
622 void FormEditorW::toolChanged(int t)
623 {
624     typedef QList<QAction *> ActionList;
625     if (const QAction *currentAction = m_actionGroupEditMode->checkedAction())
626         if (currentAction->data().toInt() == t)
627             return;
628     const ActionList actions = m_actionGroupEditMode->actions();
629     const ActionList::const_iterator cend = actions.constEnd();
630     for (ActionList::const_iterator it = actions.constBegin(); it != cend; ++it)
631         if ( (*it)->data().toInt() == t) {
632             (*it)->setChecked(true);
633             break;
634         }
635 }
636
637 void FormEditorW::print()
638 {
639     // Printing code courtesy of designer_actions.cpp
640     QDesignerFormWindowInterface *fw = m_fwm->activeFormWindow();
641     if (!fw)
642         return;
643
644     const bool oldFullPage =  m_core->printer()->fullPage();
645     const QPrinter::Orientation oldOrientation =  m_core->printer()->orientation ();
646     m_core->printer()->setFullPage(false);
647     do {
648
649         // Grab the image to be able to a suggest suitable orientation
650         QString errorMessage;
651         const QPixmap pixmap = m_fwm->createPreviewPixmap(&errorMessage);
652         if (pixmap.isNull()) {
653             critical(tr("The image could not be create: %1").arg(errorMessage));
654             break;
655         }
656
657         const QSizeF pixmapSize = pixmap.size();
658         m_core->printer()->setOrientation( pixmapSize.width() > pixmapSize.height() ?  QPrinter::Landscape :  QPrinter::Portrait);
659
660         // Printer parameters
661         QPrintDialog dialog(m_core->printer(), fw);
662         if (!dialog.exec())
663            break;
664
665         const QCursor oldCursor = m_core->mainWindow()->cursor();
666         m_core->mainWindow()->setCursor(Qt::WaitCursor);
667         // Estimate of required scaling to make form look the same on screen and printer.
668         const double suggestedScaling = static_cast<double>(m_core->printer()->physicalDpiX()) /  static_cast<double>(fw->physicalDpiX());
669
670         QPainter painter(m_core->printer());
671         painter.setRenderHint(QPainter::SmoothPixmapTransform);
672
673         // Clamp to page
674         const QRectF page =  painter.viewport();
675         const double maxScaling = qMin(page.size().width() / pixmapSize.width(), page.size().height() / pixmapSize.height());
676         const double scaling = qMin(suggestedScaling, maxScaling);
677
678         const double xOffset = page.left() + qMax(0.0, (page.size().width()  - scaling * pixmapSize.width())  / 2.0);
679         const double yOffset = page.top()  + qMax(0.0, (page.size().height() - scaling * pixmapSize.height()) / 2.0);
680
681         // Draw.
682         painter.translate(xOffset, yOffset);
683         painter.scale(scaling, scaling);
684         painter.drawPixmap(0, 0, pixmap);
685         m_core->mainWindow()->setCursor(oldCursor);
686
687     } while (false);
688     m_core->printer()->setFullPage(oldFullPage);
689     m_core->printer()->setOrientation(oldOrientation);
690 }