1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the examples of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:BSD$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** BSD License Usage |
18 | ** Alternatively, you may use this file under the terms of the BSD license |
19 | ** as follows: |
20 | ** |
21 | ** "Redistribution and use in source and binary forms, with or without |
22 | ** modification, are permitted provided that the following conditions are |
23 | ** met: |
24 | ** * Redistributions of source code must retain the above copyright |
25 | ** notice, this list of conditions and the following disclaimer. |
26 | ** * Redistributions in binary form must reproduce the above copyright |
27 | ** notice, this list of conditions and the following disclaimer in |
28 | ** the documentation and/or other materials provided with the |
29 | ** distribution. |
30 | ** * Neither the name of The Qt Company Ltd nor the names of its |
31 | ** contributors may be used to endorse or promote products derived |
32 | ** from this software without specific prior written permission. |
33 | ** |
34 | ** |
35 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
36 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
37 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
38 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
39 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
40 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
41 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
42 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
43 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
44 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
45 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." |
46 | ** |
47 | ** $QT_END_LICENSE$ |
48 | ** |
49 | ****************************************************************************/ |
50 | |
51 | #include "arrow.h" |
52 | #include "diagramitem.h" |
53 | #include "diagramscene.h" |
54 | #include "diagramtextitem.h" |
55 | #include "mainwindow.h" |
56 | |
57 | #include <QtWidgets> |
58 | |
59 | const int InsertTextButton = 10; |
60 | |
61 | //! [0] |
62 | MainWindow::MainWindow() |
63 | { |
64 | createActions(); |
65 | createToolBox(); |
66 | createMenus(); |
67 | |
68 | scene = new DiagramScene(itemMenu, this); |
69 | scene->setSceneRect(QRectF(0, 0, 5000, 5000)); |
70 | connect(sender: scene, signal: &DiagramScene::itemInserted, |
71 | receiver: this, slot: &MainWindow::itemInserted); |
72 | connect(sender: scene, signal: &DiagramScene::textInserted, |
73 | receiver: this, slot: &MainWindow::textInserted); |
74 | connect(sender: scene, signal: &DiagramScene::itemSelected, |
75 | receiver: this, slot: &MainWindow::itemSelected); |
76 | createToolbars(); |
77 | |
78 | QHBoxLayout *layout = new QHBoxLayout; |
79 | layout->addWidget(toolBox); |
80 | view = new QGraphicsView(scene); |
81 | layout->addWidget(view); |
82 | |
83 | QWidget *widget = new QWidget; |
84 | widget->setLayout(layout); |
85 | |
86 | setCentralWidget(widget); |
87 | setWindowTitle(tr(s: "Diagramscene" )); |
88 | setUnifiedTitleAndToolBarOnMac(true); |
89 | } |
90 | //! [0] |
91 | |
92 | //! [1] |
93 | void MainWindow::backgroundButtonGroupClicked(QAbstractButton *button) |
94 | { |
95 | const QList<QAbstractButton *> buttons = backgroundButtonGroup->buttons(); |
96 | for (QAbstractButton *myButton : buttons) { |
97 | if (myButton != button) |
98 | button->setChecked(false); |
99 | } |
100 | QString text = button->text(); |
101 | if (text == tr(s: "Blue Grid" )) |
102 | scene->setBackgroundBrush(QPixmap(":/images/background1.png" )); |
103 | else if (text == tr(s: "White Grid" )) |
104 | scene->setBackgroundBrush(QPixmap(":/images/background2.png" )); |
105 | else if (text == tr(s: "Gray Grid" )) |
106 | scene->setBackgroundBrush(QPixmap(":/images/background3.png" )); |
107 | else |
108 | scene->setBackgroundBrush(QPixmap(":/images/background4.png" )); |
109 | |
110 | scene->update(); |
111 | view->update(); |
112 | } |
113 | //! [1] |
114 | |
115 | //! [2] |
116 | void MainWindow::buttonGroupClicked(QAbstractButton *button) |
117 | { |
118 | const QList<QAbstractButton *> buttons = buttonGroup->buttons(); |
119 | for (QAbstractButton *myButton : buttons) { |
120 | if (myButton != button) |
121 | button->setChecked(false); |
122 | } |
123 | const int id = buttonGroup->id(button); |
124 | if (id == InsertTextButton) { |
125 | scene->setMode(DiagramScene::InsertText); |
126 | } else { |
127 | scene->setItemType(DiagramItem::DiagramType(id)); |
128 | scene->setMode(DiagramScene::InsertItem); |
129 | } |
130 | } |
131 | //! [2] |
132 | |
133 | //! [3] |
134 | void MainWindow::deleteItem() |
135 | { |
136 | QList<QGraphicsItem *> selectedItems = scene->selectedItems(); |
137 | for (QGraphicsItem *item : qAsConst(t&: selectedItems)) { |
138 | if (item->type() == Arrow::Type) { |
139 | scene->removeItem(item); |
140 | Arrow *arrow = qgraphicsitem_cast<Arrow *>(item); |
141 | arrow->startItem()->removeArrow(arrow); |
142 | arrow->endItem()->removeArrow(arrow); |
143 | delete item; |
144 | } |
145 | } |
146 | |
147 | selectedItems = scene->selectedItems(); |
148 | for (QGraphicsItem *item : qAsConst(t&: selectedItems)) { |
149 | if (item->type() == DiagramItem::Type) |
150 | qgraphicsitem_cast<DiagramItem *>(item)->removeArrows(); |
151 | scene->removeItem(item); |
152 | delete item; |
153 | } |
154 | } |
155 | //! [3] |
156 | |
157 | //! [4] |
158 | void MainWindow::pointerGroupClicked() |
159 | { |
160 | scene->setMode(DiagramScene::Mode(pointerTypeGroup->checkedId())); |
161 | } |
162 | //! [4] |
163 | |
164 | //! [5] |
165 | void MainWindow::bringToFront() |
166 | { |
167 | if (scene->selectedItems().isEmpty()) |
168 | return; |
169 | |
170 | QGraphicsItem *selectedItem = scene->selectedItems().first(); |
171 | const QList<QGraphicsItem *> overlapItems = selectedItem->collidingItems(); |
172 | |
173 | qreal zValue = 0; |
174 | for (const QGraphicsItem *item : overlapItems) { |
175 | if (item->zValue() >= zValue && item->type() == DiagramItem::Type) |
176 | zValue = item->zValue() + 0.1; |
177 | } |
178 | selectedItem->setZValue(zValue); |
179 | } |
180 | //! [5] |
181 | |
182 | //! [6] |
183 | void MainWindow::sendToBack() |
184 | { |
185 | if (scene->selectedItems().isEmpty()) |
186 | return; |
187 | |
188 | QGraphicsItem *selectedItem = scene->selectedItems().first(); |
189 | const QList<QGraphicsItem *> overlapItems = selectedItem->collidingItems(); |
190 | |
191 | qreal zValue = 0; |
192 | for (const QGraphicsItem *item : overlapItems) { |
193 | if (item->zValue() <= zValue && item->type() == DiagramItem::Type) |
194 | zValue = item->zValue() - 0.1; |
195 | } |
196 | selectedItem->setZValue(zValue); |
197 | } |
198 | //! [6] |
199 | |
200 | //! [7] |
201 | void MainWindow::itemInserted(DiagramItem *item) |
202 | { |
203 | pointerTypeGroup->button(id: int(DiagramScene::MoveItem))->setChecked(true); |
204 | scene->setMode(DiagramScene::Mode(pointerTypeGroup->checkedId())); |
205 | buttonGroup->button(id: int(item->diagramType()))->setChecked(false); |
206 | } |
207 | //! [7] |
208 | |
209 | //! [8] |
210 | void MainWindow::textInserted(QGraphicsTextItem *) |
211 | { |
212 | buttonGroup->button(id: InsertTextButton)->setChecked(false); |
213 | scene->setMode(DiagramScene::Mode(pointerTypeGroup->checkedId())); |
214 | } |
215 | //! [8] |
216 | |
217 | //! [9] |
218 | void MainWindow::currentFontChanged(const QFont &) |
219 | { |
220 | handleFontChange(); |
221 | } |
222 | //! [9] |
223 | |
224 | //! [10] |
225 | void MainWindow::fontSizeChanged(const QString &) |
226 | { |
227 | handleFontChange(); |
228 | } |
229 | //! [10] |
230 | |
231 | //! [11] |
232 | void MainWindow::sceneScaleChanged(const QString &scale) |
233 | { |
234 | double newScale = scale.left(n: scale.indexOf(s: tr(s: "%" ))).toDouble() / 100.0; |
235 | QTransform oldMatrix = view->transform(); |
236 | view->resetTransform(); |
237 | view->translate(dx: oldMatrix.dx(), dy: oldMatrix.dy()); |
238 | view->scale(sx: newScale, sy: newScale); |
239 | } |
240 | //! [11] |
241 | |
242 | //! [12] |
243 | void MainWindow::textColorChanged() |
244 | { |
245 | textAction = qobject_cast<QAction *>(object: sender()); |
246 | fontColorToolButton->setIcon(createColorToolButtonIcon( |
247 | image: ":/images/textpointer.png" , |
248 | color: qvariant_cast<QColor>(v: textAction->data()))); |
249 | textButtonTriggered(); |
250 | } |
251 | //! [12] |
252 | |
253 | //! [13] |
254 | void MainWindow::itemColorChanged() |
255 | { |
256 | fillAction = qobject_cast<QAction *>(object: sender()); |
257 | fillColorToolButton->setIcon(createColorToolButtonIcon( |
258 | image: ":/images/floodfill.png" , |
259 | color: qvariant_cast<QColor>(v: fillAction->data()))); |
260 | fillButtonTriggered(); |
261 | } |
262 | //! [13] |
263 | |
264 | //! [14] |
265 | void MainWindow::lineColorChanged() |
266 | { |
267 | lineAction = qobject_cast<QAction *>(object: sender()); |
268 | lineColorToolButton->setIcon(createColorToolButtonIcon( |
269 | image: ":/images/linecolor.png" , |
270 | color: qvariant_cast<QColor>(v: lineAction->data()))); |
271 | lineButtonTriggered(); |
272 | } |
273 | //! [14] |
274 | |
275 | //! [15] |
276 | void MainWindow::textButtonTriggered() |
277 | { |
278 | scene->setTextColor(qvariant_cast<QColor>(v: textAction->data())); |
279 | } |
280 | //! [15] |
281 | |
282 | //! [16] |
283 | void MainWindow::fillButtonTriggered() |
284 | { |
285 | scene->setItemColor(qvariant_cast<QColor>(v: fillAction->data())); |
286 | } |
287 | //! [16] |
288 | |
289 | //! [17] |
290 | void MainWindow::lineButtonTriggered() |
291 | { |
292 | scene->setLineColor(qvariant_cast<QColor>(v: lineAction->data())); |
293 | } |
294 | //! [17] |
295 | |
296 | //! [18] |
297 | void MainWindow::handleFontChange() |
298 | { |
299 | QFont font = fontCombo->currentFont(); |
300 | font.setPointSize(fontSizeCombo->currentText().toInt()); |
301 | font.setWeight(boldAction->isChecked() ? QFont::Bold : QFont::Normal); |
302 | font.setItalic(italicAction->isChecked()); |
303 | font.setUnderline(underlineAction->isChecked()); |
304 | |
305 | scene->setFont(font); |
306 | } |
307 | //! [18] |
308 | |
309 | //! [19] |
310 | void MainWindow::itemSelected(QGraphicsItem *item) |
311 | { |
312 | DiagramTextItem *textItem = |
313 | qgraphicsitem_cast<DiagramTextItem *>(item); |
314 | |
315 | QFont font = textItem->font(); |
316 | fontCombo->setCurrentFont(font); |
317 | fontSizeCombo->setEditText(QString().setNum(n: font.pointSize())); |
318 | boldAction->setChecked(font.weight() == QFont::Bold); |
319 | italicAction->setChecked(font.italic()); |
320 | underlineAction->setChecked(font.underline()); |
321 | } |
322 | //! [19] |
323 | |
324 | //! [20] |
325 | void MainWindow::about() |
326 | { |
327 | QMessageBox::about(parent: this, title: tr(s: "About Diagram Scene" ), |
328 | text: tr(s: "The <b>Diagram Scene</b> example shows " |
329 | "use of the graphics framework." )); |
330 | } |
331 | //! [20] |
332 | |
333 | //! [21] |
334 | void MainWindow::createToolBox() |
335 | { |
336 | buttonGroup = new QButtonGroup(this); |
337 | buttonGroup->setExclusive(false); |
338 | connect(sender: buttonGroup, signal: QOverload<QAbstractButton *>::of(ptr: &QButtonGroup::buttonClicked), |
339 | receiver: this, slot: &MainWindow::buttonGroupClicked); |
340 | QGridLayout *layout = new QGridLayout; |
341 | layout->addWidget(createCellWidget(text: tr(s: "Conditional" ), type: DiagramItem::Conditional), row: 0, column: 0); |
342 | layout->addWidget(createCellWidget(text: tr(s: "Process" ), type: DiagramItem::Step),row: 0, column: 1); |
343 | layout->addWidget(createCellWidget(text: tr(s: "Input/Output" ), type: DiagramItem::Io), row: 1, column: 0); |
344 | //! [21] |
345 | |
346 | QToolButton *textButton = new QToolButton; |
347 | textButton->setCheckable(true); |
348 | buttonGroup->addButton(textButton, id: InsertTextButton); |
349 | textButton->setIcon(QIcon(QPixmap(":/images/textpointer.png" ))); |
350 | textButton->setIconSize(QSize(50, 50)); |
351 | QGridLayout *textLayout = new QGridLayout; |
352 | textLayout->addWidget(textButton, row: 0, column: 0, Qt::AlignHCenter); |
353 | textLayout->addWidget(new QLabel(tr(s: "Text" )), row: 1, column: 0, Qt::AlignCenter); |
354 | QWidget *textWidget = new QWidget; |
355 | textWidget->setLayout(textLayout); |
356 | layout->addWidget(textWidget, row: 1, column: 1); |
357 | |
358 | layout->setRowStretch(row: 3, stretch: 10); |
359 | layout->setColumnStretch(column: 2, stretch: 10); |
360 | |
361 | QWidget *itemWidget = new QWidget; |
362 | itemWidget->setLayout(layout); |
363 | |
364 | backgroundButtonGroup = new QButtonGroup(this); |
365 | connect(sender: backgroundButtonGroup, signal: QOverload<QAbstractButton *>::of(ptr: &QButtonGroup::buttonClicked), |
366 | receiver: this, slot: &MainWindow::backgroundButtonGroupClicked); |
367 | |
368 | QGridLayout *backgroundLayout = new QGridLayout; |
369 | backgroundLayout->addWidget(createBackgroundCellWidget(text: tr(s: "Blue Grid" ), |
370 | image: ":/images/background1.png" ), row: 0, column: 0); |
371 | backgroundLayout->addWidget(createBackgroundCellWidget(text: tr(s: "White Grid" ), |
372 | image: ":/images/background2.png" ), row: 0, column: 1); |
373 | backgroundLayout->addWidget(createBackgroundCellWidget(text: tr(s: "Gray Grid" ), |
374 | image: ":/images/background3.png" ), row: 1, column: 0); |
375 | backgroundLayout->addWidget(createBackgroundCellWidget(text: tr(s: "No Grid" ), |
376 | image: ":/images/background4.png" ), row: 1, column: 1); |
377 | |
378 | backgroundLayout->setRowStretch(row: 2, stretch: 10); |
379 | backgroundLayout->setColumnStretch(column: 2, stretch: 10); |
380 | |
381 | QWidget *backgroundWidget = new QWidget; |
382 | backgroundWidget->setLayout(backgroundLayout); |
383 | |
384 | |
385 | //! [22] |
386 | toolBox = new QToolBox; |
387 | toolBox->setSizePolicy(QSizePolicy(QSizePolicy::Maximum, QSizePolicy::Ignored)); |
388 | toolBox->setMinimumWidth(itemWidget->sizeHint().width()); |
389 | toolBox->addItem(item: itemWidget, text: tr(s: "Basic Flowchart Shapes" )); |
390 | toolBox->addItem(item: backgroundWidget, text: tr(s: "Backgrounds" )); |
391 | } |
392 | //! [22] |
393 | |
394 | //! [23] |
395 | void MainWindow::createActions() |
396 | { |
397 | toFrontAction = new QAction(QIcon(":/images/bringtofront.png" ), |
398 | tr(s: "Bring to &Front" ), this); |
399 | toFrontAction->setShortcut(tr(s: "Ctrl+F" )); |
400 | toFrontAction->setStatusTip(tr(s: "Bring item to front" )); |
401 | connect(sender: toFrontAction, signal: &QAction::triggered, receiver: this, slot: &MainWindow::bringToFront); |
402 | //! [23] |
403 | |
404 | sendBackAction = new QAction(QIcon(":/images/sendtoback.png" ), tr(s: "Send to &Back" ), this); |
405 | sendBackAction->setShortcut(tr(s: "Ctrl+T" )); |
406 | sendBackAction->setStatusTip(tr(s: "Send item to back" )); |
407 | connect(sender: sendBackAction, signal: &QAction::triggered, receiver: this, slot: &MainWindow::sendToBack); |
408 | |
409 | deleteAction = new QAction(QIcon(":/images/delete.png" ), tr(s: "&Delete" ), this); |
410 | deleteAction->setShortcut(tr(s: "Delete" )); |
411 | deleteAction->setStatusTip(tr(s: "Delete item from diagram" )); |
412 | connect(sender: deleteAction, signal: &QAction::triggered, receiver: this, slot: &MainWindow::deleteItem); |
413 | |
414 | exitAction = new QAction(tr(s: "E&xit" ), this); |
415 | exitAction->setShortcuts(QKeySequence::Quit); |
416 | exitAction->setStatusTip(tr(s: "Quit Scenediagram example" )); |
417 | connect(sender: exitAction, signal: &QAction::triggered, receiver: this, slot: &QWidget::close); |
418 | |
419 | boldAction = new QAction(tr(s: "Bold" ), this); |
420 | boldAction->setCheckable(true); |
421 | QPixmap pixmap(":/images/bold.png" ); |
422 | boldAction->setIcon(QIcon(pixmap)); |
423 | boldAction->setShortcut(tr(s: "Ctrl+B" )); |
424 | connect(sender: boldAction, signal: &QAction::triggered, receiver: this, slot: &MainWindow::handleFontChange); |
425 | |
426 | italicAction = new QAction(QIcon(":/images/italic.png" ), tr(s: "Italic" ), this); |
427 | italicAction->setCheckable(true); |
428 | italicAction->setShortcut(tr(s: "Ctrl+I" )); |
429 | connect(sender: italicAction, signal: &QAction::triggered, receiver: this, slot: &MainWindow::handleFontChange); |
430 | |
431 | underlineAction = new QAction(QIcon(":/images/underline.png" ), tr(s: "Underline" ), this); |
432 | underlineAction->setCheckable(true); |
433 | underlineAction->setShortcut(tr(s: "Ctrl+U" )); |
434 | connect(sender: underlineAction, signal: &QAction::triggered, receiver: this, slot: &MainWindow::handleFontChange); |
435 | |
436 | aboutAction = new QAction(tr(s: "A&bout" ), this); |
437 | aboutAction->setShortcut(tr(s: "F1" )); |
438 | connect(sender: aboutAction, signal: &QAction::triggered, receiver: this, slot: &MainWindow::about); |
439 | } |
440 | |
441 | //! [24] |
442 | void MainWindow::createMenus() |
443 | { |
444 | fileMenu = menuBar()->addMenu(title: tr(s: "&File" )); |
445 | fileMenu->addAction(action: exitAction); |
446 | |
447 | itemMenu = menuBar()->addMenu(title: tr(s: "&Item" )); |
448 | itemMenu->addAction(action: deleteAction); |
449 | itemMenu->addSeparator(); |
450 | itemMenu->addAction(action: toFrontAction); |
451 | itemMenu->addAction(action: sendBackAction); |
452 | |
453 | aboutMenu = menuBar()->addMenu(title: tr(s: "&Help" )); |
454 | aboutMenu->addAction(action: aboutAction); |
455 | } |
456 | //! [24] |
457 | |
458 | //! [25] |
459 | void MainWindow::createToolbars() |
460 | { |
461 | //! [25] |
462 | editToolBar = addToolBar(title: tr(s: "Edit" )); |
463 | editToolBar->addAction(action: deleteAction); |
464 | editToolBar->addAction(action: toFrontAction); |
465 | editToolBar->addAction(action: sendBackAction); |
466 | |
467 | fontCombo = new QFontComboBox(); |
468 | connect(sender: fontCombo, signal: &QFontComboBox::currentFontChanged, |
469 | receiver: this, slot: &MainWindow::currentFontChanged); |
470 | |
471 | fontSizeCombo = new QComboBox; |
472 | fontSizeCombo->setEditable(true); |
473 | for (int i = 8; i < 30; i = i + 2) |
474 | fontSizeCombo->addItem(atext: QString().setNum(n: i)); |
475 | QIntValidator *validator = new QIntValidator(2, 64, this); |
476 | fontSizeCombo->setValidator(validator); |
477 | connect(sender: fontSizeCombo, signal: &QComboBox::currentTextChanged, |
478 | receiver: this, slot: &MainWindow::fontSizeChanged); |
479 | |
480 | fontColorToolButton = new QToolButton; |
481 | fontColorToolButton->setPopupMode(QToolButton::MenuButtonPopup); |
482 | fontColorToolButton->setMenu(createColorMenu(SLOT(textColorChanged()), defaultColor: Qt::black)); |
483 | textAction = fontColorToolButton->menu()->defaultAction(); |
484 | fontColorToolButton->setIcon(createColorToolButtonIcon(image: ":/images/textpointer.png" , color: Qt::black)); |
485 | fontColorToolButton->setAutoFillBackground(true); |
486 | connect(sender: fontColorToolButton, signal: &QAbstractButton::clicked, |
487 | receiver: this, slot: &MainWindow::textButtonTriggered); |
488 | |
489 | //! [26] |
490 | fillColorToolButton = new QToolButton; |
491 | fillColorToolButton->setPopupMode(QToolButton::MenuButtonPopup); |
492 | fillColorToolButton->setMenu(createColorMenu(SLOT(itemColorChanged()), defaultColor: Qt::white)); |
493 | fillAction = fillColorToolButton->menu()->defaultAction(); |
494 | fillColorToolButton->setIcon(createColorToolButtonIcon( |
495 | image: ":/images/floodfill.png" , color: Qt::white)); |
496 | connect(sender: fillColorToolButton, signal: &QAbstractButton::clicked, |
497 | receiver: this, slot: &MainWindow::fillButtonTriggered); |
498 | //! [26] |
499 | |
500 | lineColorToolButton = new QToolButton; |
501 | lineColorToolButton->setPopupMode(QToolButton::MenuButtonPopup); |
502 | lineColorToolButton->setMenu(createColorMenu(SLOT(lineColorChanged()), defaultColor: Qt::black)); |
503 | lineAction = lineColorToolButton->menu()->defaultAction(); |
504 | lineColorToolButton->setIcon(createColorToolButtonIcon( |
505 | image: ":/images/linecolor.png" , color: Qt::black)); |
506 | connect(sender: lineColorToolButton, signal: &QAbstractButton::clicked, |
507 | receiver: this, slot: &MainWindow::lineButtonTriggered); |
508 | |
509 | textToolBar = addToolBar(title: tr(s: "Font" )); |
510 | textToolBar->addWidget(widget: fontCombo); |
511 | textToolBar->addWidget(widget: fontSizeCombo); |
512 | textToolBar->addAction(action: boldAction); |
513 | textToolBar->addAction(action: italicAction); |
514 | textToolBar->addAction(action: underlineAction); |
515 | |
516 | colorToolBar = addToolBar(title: tr(s: "Color" )); |
517 | colorToolBar->addWidget(widget: fontColorToolButton); |
518 | colorToolBar->addWidget(widget: fillColorToolButton); |
519 | colorToolBar->addWidget(widget: lineColorToolButton); |
520 | |
521 | QToolButton *pointerButton = new QToolButton; |
522 | pointerButton->setCheckable(true); |
523 | pointerButton->setChecked(true); |
524 | pointerButton->setIcon(QIcon(":/images/pointer.png" )); |
525 | QToolButton *linePointerButton = new QToolButton; |
526 | linePointerButton->setCheckable(true); |
527 | linePointerButton->setIcon(QIcon(":/images/linepointer.png" )); |
528 | |
529 | pointerTypeGroup = new QButtonGroup(this); |
530 | pointerTypeGroup->addButton(pointerButton, id: int(DiagramScene::MoveItem)); |
531 | pointerTypeGroup->addButton(linePointerButton, id: int(DiagramScene::InsertLine)); |
532 | connect(sender: pointerTypeGroup, signal: QOverload<QAbstractButton *>::of(ptr: &QButtonGroup::buttonClicked), |
533 | receiver: this, slot: &MainWindow::pointerGroupClicked); |
534 | |
535 | sceneScaleCombo = new QComboBox; |
536 | QStringList scales; |
537 | scales << tr(s: "50%" ) << tr(s: "75%" ) << tr(s: "100%" ) << tr(s: "125%" ) << tr(s: "150%" ); |
538 | sceneScaleCombo->addItems(texts: scales); |
539 | sceneScaleCombo->setCurrentIndex(2); |
540 | connect(sender: sceneScaleCombo, signal: &QComboBox::currentTextChanged, |
541 | receiver: this, slot: &MainWindow::sceneScaleChanged); |
542 | |
543 | pointerToolbar = addToolBar(title: tr(s: "Pointer type" )); |
544 | pointerToolbar->addWidget(widget: pointerButton); |
545 | pointerToolbar->addWidget(widget: linePointerButton); |
546 | pointerToolbar->addWidget(widget: sceneScaleCombo); |
547 | //! [27] |
548 | } |
549 | //! [27] |
550 | |
551 | //! [28] |
552 | QWidget *MainWindow::createBackgroundCellWidget(const QString &text, const QString &image) |
553 | { |
554 | QToolButton *button = new QToolButton; |
555 | button->setText(text); |
556 | button->setIcon(QIcon(image)); |
557 | button->setIconSize(QSize(50, 50)); |
558 | button->setCheckable(true); |
559 | backgroundButtonGroup->addButton(button); |
560 | |
561 | QGridLayout *layout = new QGridLayout; |
562 | layout->addWidget(button, row: 0, column: 0, Qt::AlignHCenter); |
563 | layout->addWidget(new QLabel(text), row: 1, column: 0, Qt::AlignCenter); |
564 | |
565 | QWidget *widget = new QWidget; |
566 | widget->setLayout(layout); |
567 | |
568 | return widget; |
569 | } |
570 | //! [28] |
571 | |
572 | //! [29] |
573 | QWidget *MainWindow::createCellWidget(const QString &text, DiagramItem::DiagramType type) |
574 | { |
575 | |
576 | DiagramItem item(type, itemMenu); |
577 | QIcon icon(item.image()); |
578 | |
579 | QToolButton *button = new QToolButton; |
580 | button->setIcon(icon); |
581 | button->setIconSize(QSize(50, 50)); |
582 | button->setCheckable(true); |
583 | buttonGroup->addButton(button, id: int(type)); |
584 | |
585 | QGridLayout *layout = new QGridLayout; |
586 | layout->addWidget(button, row: 0, column: 0, Qt::AlignHCenter); |
587 | layout->addWidget(new QLabel(text), row: 1, column: 0, Qt::AlignCenter); |
588 | |
589 | QWidget *widget = new QWidget; |
590 | widget->setLayout(layout); |
591 | |
592 | return widget; |
593 | } |
594 | //! [29] |
595 | |
596 | //! [30] |
597 | QMenu *MainWindow::createColorMenu(const char *slot, QColor defaultColor) |
598 | { |
599 | QList<QColor> colors; |
600 | colors << Qt::black << Qt::white << Qt::red << Qt::blue << Qt::yellow; |
601 | QStringList names; |
602 | names << tr(s: "black" ) << tr(s: "white" ) << tr(s: "red" ) << tr(s: "blue" ) |
603 | << tr(s: "yellow" ); |
604 | |
605 | QMenu * = new QMenu(this); |
606 | for (int i = 0; i < colors.count(); ++i) { |
607 | QAction *action = new QAction(names.at(i), this); |
608 | action->setData(colors.at(i)); |
609 | action->setIcon(createColorIcon(color: colors.at(i))); |
610 | connect(sender: action, SIGNAL(triggered()), receiver: this, member: slot); |
611 | colorMenu->addAction(action); |
612 | if (colors.at(i) == defaultColor) |
613 | colorMenu->setDefaultAction(action); |
614 | } |
615 | return colorMenu; |
616 | } |
617 | //! [30] |
618 | |
619 | //! [31] |
620 | QIcon MainWindow::createColorToolButtonIcon(const QString &imageFile, QColor color) |
621 | { |
622 | QPixmap pixmap(50, 80); |
623 | pixmap.fill(fillColor: Qt::transparent); |
624 | QPainter painter(&pixmap); |
625 | QPixmap image(imageFile); |
626 | // Draw icon centred horizontally on button. |
627 | QRect target(4, 0, 42, 43); |
628 | QRect source(0, 0, 42, 43); |
629 | painter.fillRect(QRect(0, 60, 50, 80), color); |
630 | painter.drawPixmap(targetRect: target, pixmap: image, sourceRect: source); |
631 | |
632 | return QIcon(pixmap); |
633 | } |
634 | //! [31] |
635 | |
636 | //! [32] |
637 | QIcon MainWindow::createColorIcon(QColor color) |
638 | { |
639 | QPixmap pixmap(20, 20); |
640 | QPainter painter(&pixmap); |
641 | painter.setPen(Qt::NoPen); |
642 | painter.fillRect(QRect(0, 0, 20, 20), color); |
643 | |
644 | return QIcon(pixmap); |
645 | } |
646 | //! [32] |
647 | |