OSDN Git Service

Update license.
[qt-creator-jp/qt-creator-jp.git] / src / plugins / qmldesigner / components / formeditor / formeditorwidget.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (info@qt.nokia.com)
8 **
9 **
10 ** GNU Lesser General Public License Usage
11 **
12 ** This file may be used under the terms of the GNU Lesser General Public
13 ** License version 2.1 as published by the Free Software Foundation and
14 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
15 ** Please review the following information to ensure the GNU Lesser General
16 ** Public License version 2.1 requirements will be met:
17 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 **
19 ** In addition, as a special exception, Nokia gives you certain additional
20 ** rights. These rights are described in the Nokia Qt LGPL Exception
21 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 **
23 ** Other Usage
24 **
25 ** Alternatively, this file may be used in accordance with the terms and
26 ** conditions contained in a signed written agreement between you and Nokia.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **************************************************************************/
32
33 #include "formeditorwidget.h"
34 #include "qmldesignerplugin.h"
35 #include "designersettings.h"
36
37 #include <QWheelEvent>
38 #include <cmath>
39 #include <QCoreApplication>
40 #include <QPushButton>
41 #include <QFile>
42 #include <QVBoxLayout>
43 #include <QActionGroup>
44 #include <QGraphicsView>
45 #include <toolbox.h>
46 #include <zoomaction.h>
47 #include <formeditorgraphicsview.h>
48 #include <formeditorscene.h>
49 #include <formeditorview.h>
50 #include <lineeditaction.h>
51
52 namespace QmlDesigner {
53
54 FormEditorWidget::FormEditorWidget(FormEditorView *view)
55     : QWidget(),
56     m_formEditorView(view)
57 {
58     QFile file(":/qmldesigner/formeditorstylesheet.css");
59     file.open(QFile::ReadOnly);
60     QString styleSheet = QLatin1String(file.readAll());
61     setStyleSheet(styleSheet);
62
63     QVBoxLayout *fillLayout = new QVBoxLayout(this);
64     fillLayout->setMargin(0);
65     fillLayout->setSpacing(0);
66     setLayout(fillLayout);
67
68     QList<QAction*> upperActions;
69
70     m_toolActionGroup = new QActionGroup(this);
71
72     m_transformToolAction = m_toolActionGroup->addAction("Transform Tool (Press Key Q)");
73     m_transformToolAction->setShortcut(Qt::Key_Q);
74     m_transformToolAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
75     m_transformToolAction->setCheckable(true);
76     m_transformToolAction->setChecked(true);
77     m_transformToolAction->setIcon(QPixmap(":/icon/tool/transform.png"));
78     connect(m_transformToolAction.data(), SIGNAL(triggered(bool)), SLOT(changeTransformTool(bool)));
79
80     m_anchorToolAction = m_toolActionGroup->addAction("Anchor Tool (Press Key W)");
81     m_anchorToolAction->setShortcut(Qt::Key_W);
82     m_anchorToolAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
83     m_anchorToolAction->setCheckable(true);
84     m_anchorToolAction->setIcon(QPixmap(":/icon/tool/anchor.png"));
85     connect(m_anchorToolAction.data(), SIGNAL(triggered(bool)), SLOT(changeAnchorTool(bool)));
86
87 //    addActions(m_toolActionGroup->actions());
88 //    upperActions.append(m_toolActionGroup->actions());
89
90     QActionGroup *layoutActionGroup = new QActionGroup(this);
91     layoutActionGroup->setExclusive(false);
92     m_snappingAction = layoutActionGroup->addAction(tr("Snap to guides (E)"));
93     m_snappingAction->setShortcut(Qt::Key_E);
94     m_snappingAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
95     m_snappingAction->setCheckable(true);
96     m_snappingAction->setChecked(true);
97     m_snappingAction->setIcon(QPixmap(":/icon/layout/snapping.png"));
98
99     m_snappingAndAnchoringAction = layoutActionGroup->addAction("Toogle Snapping And Anchoring (Press Key R)");
100     m_snappingAndAnchoringAction->setShortcut(Qt::Key_R);
101     m_snappingAndAnchoringAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
102     m_snappingAndAnchoringAction->setCheckable(true);
103     m_snappingAndAnchoringAction->setChecked(false);
104     m_snappingAndAnchoringAction->setEnabled(false);
105     m_snappingAndAnchoringAction->setVisible(false);
106     m_snappingAndAnchoringAction->setIcon(QPixmap(":/icon/layout/snapping_and_anchoring.png"));
107
108     addActions(layoutActionGroup->actions());
109     upperActions.append(layoutActionGroup->actions());
110
111     QAction *separatorAction = new QAction(this);
112     separatorAction->setSeparator(true);
113     addAction(separatorAction);
114     upperActions.append(separatorAction);
115
116     m_showBoundingRectAction = new QAction(tr("Show bounding rectangles (A)"), this);
117     m_showBoundingRectAction->setShortcut(Qt::Key_A);
118     m_showBoundingRectAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
119     m_showBoundingRectAction->setCheckable(true);
120     m_showBoundingRectAction->setChecked(true);
121     m_showBoundingRectAction->setIcon(QPixmap(":/icon/layout/boundingrect.png"));
122
123     addAction(m_showBoundingRectAction.data());
124     upperActions.append(m_showBoundingRectAction.data());
125
126     m_selectOnlyContentItemsAction = new QAction(tr("Only select items with content (S)"), this);
127     m_selectOnlyContentItemsAction->setShortcut(Qt::Key_S);
128     m_selectOnlyContentItemsAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
129     m_selectOnlyContentItemsAction->setCheckable(true);
130     m_selectOnlyContentItemsAction->setChecked(false);
131     m_selectOnlyContentItemsAction->setIcon(QPixmap(":/icon/selection/selectonlycontentitems.png"));
132
133     addAction(m_selectOnlyContentItemsAction.data());
134     upperActions.append(m_selectOnlyContentItemsAction.data());
135
136     m_rootWidthAction = new LineEditAction("width", this);
137     connect(m_rootWidthAction.data(), SIGNAL(textChanged(QString)), this, SLOT(changeRootItemWidth(QString)));
138     addAction(m_rootWidthAction.data());
139     upperActions.append(m_rootWidthAction.data());
140
141     m_rootHeightAction =  new LineEditAction("height", this);
142     connect(m_rootHeightAction.data(), SIGNAL(textChanged(QString)), this, SLOT(changeRootItemHeight(QString)));
143     addAction(m_rootHeightAction.data());
144     upperActions.append(m_rootHeightAction.data());
145
146     m_snappingAndAnchoringAction = layoutActionGroup->addAction("Toogle Snapping And Anchoring (Press Key R)");
147
148     m_toolBox = new ToolBox(this);
149     fillLayout->addWidget(m_toolBox.data());
150     m_toolBox->setLeftSideActions(upperActions);
151
152     m_graphicsView = new FormEditorGraphicsView(this);
153     fillLayout->addWidget(m_graphicsView.data());
154
155     {
156         QFile file(":/qmldesigner/scrollbar.css");
157         file.open(QFile::ReadOnly);
158         m_graphicsView.data()->setStyleSheet(file.readAll());
159     }
160
161     QList<QAction*> lowerActions;
162
163     m_zoomAction = new ZoomAction(m_toolActionGroup.data());
164     connect(m_zoomAction.data(), SIGNAL(zoomLevelChanged(double)), SLOT(setZoomLevel(double)));
165     addAction(m_zoomAction.data());
166     upperActions.append(m_zoomAction.data());
167     m_toolBox->addRightSideAction(m_zoomAction.data());
168
169     m_resetAction = new QAction(tr("Reset view (R)"), this);
170     m_resetAction->setShortcut(Qt::Key_R);
171     m_resetAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
172     m_resetAction->setIcon(QPixmap(":/icon/reset.png"));
173     connect(m_resetAction.data(), SIGNAL(triggered(bool)), this, SLOT(resetNodeInstanceView()));
174     addAction(m_resetAction.data());
175     upperActions.append(m_resetAction.data());
176     m_toolBox->addRightSideAction(m_resetAction.data());
177 }
178
179 void FormEditorWidget::enterEvent(QEvent *event)
180 {
181     m_graphicsView->setFocus();
182     QWidget::enterEvent(event);
183 }
184
185 void FormEditorWidget::changeTransformTool(bool checked)
186 {
187     if (checked)
188
189         m_formEditorView->changeToTransformTools();
190 }
191
192 void FormEditorWidget::changeRootItemWidth(const QString &widthText)
193 {
194     bool canConvert;
195     int width = widthText.toInt(&canConvert);
196     if (canConvert) {
197         m_formEditorView->rootModelNode().setAuxiliaryData("width", width);
198     } else {
199         m_formEditorView->rootModelNode().setAuxiliaryData("width", QVariant());
200     }
201 }
202
203 void FormEditorWidget::changeRootItemHeight(const QString &heighText)
204 {
205     bool canConvert;
206     int height = heighText.toInt(&canConvert);
207     if (canConvert) {
208         m_formEditorView->rootModelNode().setAuxiliaryData("height", height);
209     } else {
210         m_formEditorView->rootModelNode().setAuxiliaryData("height", QVariant());
211     }
212 }
213
214 void FormEditorWidget::resetNodeInstanceView()
215 {
216     m_formEditorView->setCurrentState(m_formEditorView->baseState());
217     m_formEditorView->emitCustomNotification(QLatin1String("reset QmlPuppet"));
218 }
219
220 void FormEditorWidget::changeAnchorTool(bool checked)
221 {
222     if (checked && m_formEditorView->currentState().isBaseState())
223         m_formEditorView->changeToAnchorTool();
224 }
225
226 void FormEditorWidget::wheelEvent(QWheelEvent *event)
227 {
228     if (event->modifiers().testFlag(Qt::ControlModifier)) {
229         if (event->delta() > 0) {
230             zoomAction()->zoomOut();
231         } else {
232             zoomAction()->zoomIn();
233         }
234
235         event->accept();
236     } else {
237         QWidget::wheelEvent(event);
238     }
239
240 }
241
242 void FormEditorWidget::updateActions()
243 {
244     if (m_formEditorView->model() && m_formEditorView->rootModelNode().isValid()) {
245         if (m_formEditorView->rootModelNode().hasAuxiliaryData("width") && m_formEditorView->rootModelNode().auxiliaryData("width").isValid()) {
246             m_rootWidthAction->setLineEditText(m_formEditorView->rootModelNode().auxiliaryData("width").toString());
247         } else {
248             m_rootWidthAction->clearLineEditText();
249         }
250         if (m_formEditorView->rootModelNode().hasAuxiliaryData("height") && m_formEditorView->rootModelNode().auxiliaryData("height").isValid()) {
251             m_rootHeightAction->setLineEditText(m_formEditorView->rootModelNode().auxiliaryData("height").toString());
252         } else {
253             m_rootHeightAction->clearLineEditText();
254         }
255     } else {
256         m_rootWidthAction->clearLineEditText();
257         m_rootHeightAction->clearLineEditText();
258     }
259 }
260
261
262 void FormEditorWidget::resetView()
263 {
264     setRootItemRect(QRectF());
265 }
266
267 void FormEditorWidget::centerScene()
268 {
269     m_graphicsView->centerOn(rootItemRect().center());
270 }
271
272 ZoomAction *FormEditorWidget::zoomAction() const
273 {
274     return m_zoomAction.data();
275 }
276
277 QAction *FormEditorWidget::anchorToolAction() const
278 {
279     return m_anchorToolAction.data();
280 }
281
282 QAction *FormEditorWidget::transformToolAction() const
283 {
284     return m_transformToolAction.data();
285 }
286
287 QAction *FormEditorWidget::showBoundingRectAction() const
288 {
289     return m_showBoundingRectAction.data();
290 }
291
292 QAction *FormEditorWidget::selectOnlyContentItemsAction() const
293 {
294     return m_selectOnlyContentItemsAction.data();
295 }
296
297 QAction *FormEditorWidget::snappingAction() const
298 {
299     return m_snappingAction.data();
300 }
301
302 QAction *FormEditorWidget::snappingAndAnchoringAction() const
303 {
304     return m_snappingAndAnchoringAction.data();
305 }
306
307 void FormEditorWidget::setZoomLevel(double zoomLevel)
308 {
309     m_graphicsView->resetTransform();
310
311     m_graphicsView->scale(zoomLevel, zoomLevel);
312 }
313
314 void FormEditorWidget::setScene(FormEditorScene *scene)
315 {
316     m_graphicsView->setScene(scene);
317 }
318
319 QActionGroup *FormEditorWidget::toolActionGroup() const
320 {
321     return m_toolActionGroup.data();
322 }
323
324 ToolBox *FormEditorWidget::toolBox() const
325 {
326      return m_toolBox.data();
327 }
328
329 double FormEditorWidget::spacing() const
330 {
331     DesignerSettings settings = Internal::BauhausPlugin::pluginInstance()->settings();
332     return settings.itemSpacing;
333 }
334
335 double FormEditorWidget::margins() const
336 {
337     DesignerSettings settings = Internal::BauhausPlugin::pluginInstance()->settings();
338     return settings.snapMargin;
339 }
340
341 void FormEditorWidget::setFeedbackNode(const QmlItemNode &node)
342 {
343     m_graphicsView->setFeedbackNode(node);
344 }
345
346 QString FormEditorWidget::contextHelpId() const
347 {
348     if (!m_formEditorView)
349         return QString();
350
351     QList<ModelNode> nodes = m_formEditorView->selectedModelNodes();
352     QString helpId;
353     if (!nodes.isEmpty()) {
354         helpId = nodes.first().type();
355         helpId.replace("QtQuick", "QML");
356     }
357
358     return helpId;
359 }
360
361 void FormEditorWidget::setRootItemRect(const QRectF &rect)
362 {
363     m_graphicsView->setRootItemRect(rect);
364 }
365
366 QRectF FormEditorWidget::rootItemRect() const
367 {
368     return m_graphicsView->rootItemRect();
369 }
370
371 }
372
373