/**************************************************************************** ** ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor ** the names of its contributors may be used to endorse or promote ** products derived from this software without specific prior written ** permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include #include "mainwindow.h" #include "diagramitem.h" #include "diagramscene.h" #include "diagramtextitem.h" #include "arrow.h" const int InsertTextButton = 10; //! [0] MainWindow::MainWindow() { createActions(); createToolBox(); createMenus(); scene = new DiagramScene(itemMenu, this); scene->setSceneRect(QRectF(0, 0, 5000, 5000)); connect(scene, SIGNAL(itemInserted(DiagramItem*)), this, SLOT(itemInserted(DiagramItem*))); connect(scene, SIGNAL(textInserted(QGraphicsTextItem*)), this, SLOT(textInserted(QGraphicsTextItem*))); connect(scene, SIGNAL(itemSelected(QGraphicsItem*)), this, SLOT(itemSelected(QGraphicsItem*))); createToolbars(); QHBoxLayout *layout = new QHBoxLayout; layout->addWidget(toolBox); view = new QGraphicsView(scene); layout->addWidget(view); QWidget *widget = new QWidget; widget->setLayout(layout); setCentralWidget(widget); setWindowTitle(tr("Diagramscene")); setUnifiedTitleAndToolBarOnMac(true); } //! [0] //! [1] void MainWindow::backgroundButtonGroupClicked(QAbstractButton *button) { QList buttons = backgroundButtonGroup->buttons(); foreach (QAbstractButton *myButton, buttons) { if (myButton != button) button->setChecked(false); } QString text = button->text(); if (text == tr("Blue Grid")) scene->setBackgroundBrush(QPixmap(":/images/background1.png")); else if (text == tr("White Grid")) scene->setBackgroundBrush(QPixmap(":/images/background2.png")); else if (text == tr("Gray Grid")) scene->setBackgroundBrush(QPixmap(":/images/background3.png")); else scene->setBackgroundBrush(QPixmap(":/images/background4.png")); scene->update(); view->update(); } //! [1] //! [2] void MainWindow::buttonGroupClicked(int id) { QList buttons = buttonGroup->buttons(); foreach (QAbstractButton *button, buttons) { if (buttonGroup->button(id) != button) button->setChecked(false); } if (id == InsertTextButton) { scene->setMode(DiagramScene::InsertText); } else { scene->setItemType(DiagramItem::DiagramType(id)); scene->setMode(DiagramScene::InsertItem); } } //! [2] //! [3] void MainWindow::deleteItem() { foreach (QGraphicsItem *item, scene->selectedItems()) { if (item->type() == Arrow::Type) { scene->removeItem(item); Arrow *arrow = qgraphicsitem_cast(item); arrow->startItem()->removeArrow(arrow); arrow->endItem()->removeArrow(arrow); delete item; } } foreach (QGraphicsItem *item, scene->selectedItems()) { if (item->type() == DiagramItem::Type) { qgraphicsitem_cast(item)->removeArrows(); } scene->removeItem(item); delete item; } } //! [3] //! [4] void MainWindow::pointerGroupClicked(int) { scene->setMode(DiagramScene::Mode(pointerTypeGroup->checkedId())); } //! [4] //! [5] void MainWindow::bringToFront() { if (scene->selectedItems().isEmpty()) return; QGraphicsItem *selectedItem = scene->selectedItems().first(); QList overlapItems = selectedItem->collidingItems(); qreal zValue = 0; foreach (QGraphicsItem *item, overlapItems) { if (item->zValue() >= zValue && item->type() == DiagramItem::Type) zValue = item->zValue() + 0.1; } selectedItem->setZValue(zValue); } //! [5] //! [6] void MainWindow::sendToBack() { if (scene->selectedItems().isEmpty()) return; QGraphicsItem *selectedItem = scene->selectedItems().first(); QList overlapItems = selectedItem->collidingItems(); qreal zValue = 0; foreach (QGraphicsItem *item, overlapItems) { if (item->zValue() <= zValue && item->type() == DiagramItem::Type) zValue = item->zValue() - 0.1; } selectedItem->setZValue(zValue); } //! [6] //! [7] void MainWindow::itemInserted(DiagramItem *item) { pointerTypeGroup->button(int(DiagramScene::MoveItem))->setChecked(true); scene->setMode(DiagramScene::Mode(pointerTypeGroup->checkedId())); buttonGroup->button(int(item->diagramType()))->setChecked(false); } //! [7] //! [8] void MainWindow::textInserted(QGraphicsTextItem *) { buttonGroup->button(InsertTextButton)->setChecked(false); scene->setMode(DiagramScene::Mode(pointerTypeGroup->checkedId())); } //! [8] //! [9] void MainWindow::currentFontChanged(const QFont &) { handleFontChange(); } //! [9] //! [10] void MainWindow::fontSizeChanged(const QString &) { handleFontChange(); } //! [10] //! [11] void MainWindow::sceneScaleChanged(const QString &scale) { double newScale = scale.left(scale.indexOf(tr("%"))).toDouble() / 100.0; QMatrix oldMatrix = view->matrix(); view->resetMatrix(); view->translate(oldMatrix.dx(), oldMatrix.dy()); view->scale(newScale, newScale); } //! [11] //! [12] void MainWindow::textColorChanged() { textAction = qobject_cast(sender()); fontColorToolButton->setIcon(createColorToolButtonIcon( ":/images/textpointer.png", qVariantValue(textAction->data()))); textButtonTriggered(); } //! [12] //! [13] void MainWindow::itemColorChanged() { fillAction = qobject_cast(sender()); fillColorToolButton->setIcon(createColorToolButtonIcon( ":/images/floodfill.png", qVariantValue(fillAction->data()))); fillButtonTriggered(); } //! [13] //! [14] void MainWindow::lineColorChanged() { lineAction = qobject_cast(sender()); lineColorToolButton->setIcon(createColorToolButtonIcon( ":/images/linecolor.png", qVariantValue(lineAction->data()))); lineButtonTriggered(); } //! [14] //! [15] void MainWindow::textButtonTriggered() { scene->setTextColor(qVariantValue(textAction->data())); } //! [15] //! [16] void MainWindow::fillButtonTriggered() { scene->setItemColor(qVariantValue(fillAction->data())); } //! [16] //! [17] void MainWindow::lineButtonTriggered() { scene->setLineColor(qVariantValue(lineAction->data())); } //! [17] //! [18] void MainWindow::handleFontChange() { QFont font = fontCombo->currentFont(); font.setPointSize(fontSizeCombo->currentText().toInt()); font.setWeight(boldAction->isChecked() ? QFont::Bold : QFont::Normal); font.setItalic(italicAction->isChecked()); font.setUnderline(underlineAction->isChecked()); scene->setFont(font); } //! [18] //! [19] void MainWindow::itemSelected(QGraphicsItem *item) { DiagramTextItem *textItem = qgraphicsitem_cast(item); QFont font = textItem->font(); QColor color = textItem->defaultTextColor(); fontCombo->setCurrentFont(font); fontSizeCombo->setEditText(QString().setNum(font.pointSize())); boldAction->setChecked(font.weight() == QFont::Bold); italicAction->setChecked(font.italic()); underlineAction->setChecked(font.underline()); } //! [19] //! [20] void MainWindow::about() { QMessageBox::about(this, tr("About Diagram Scene"), tr("The Diagram Scene example shows " "use of the graphics framework.")); } //! [20] //! [21] void MainWindow::createToolBox() { buttonGroup = new QButtonGroup(this); buttonGroup->setExclusive(false); connect(buttonGroup, SIGNAL(buttonClicked(int)), this, SLOT(buttonGroupClicked(int))); QGridLayout *layout = new QGridLayout; layout->addWidget(createCellWidget(tr("Conditional"), DiagramItem::Conditional), 0, 0); layout->addWidget(createCellWidget(tr("Process"), DiagramItem::Step),0, 1); layout->addWidget(createCellWidget(tr("Input/Output"), DiagramItem::Io), 1, 0); //! [21] QToolButton *textButton = new QToolButton; textButton->setCheckable(true); buttonGroup->addButton(textButton, InsertTextButton); textButton->setIcon(QIcon(QPixmap(":/images/textpointer.png") .scaled(30, 30))); textButton->setIconSize(QSize(50, 50)); QGridLayout *textLayout = new QGridLayout; textLayout->addWidget(textButton, 0, 0, Qt::AlignHCenter); textLayout->addWidget(new QLabel(tr("Text")), 1, 0, Qt::AlignCenter); QWidget *textWidget = new QWidget; textWidget->setLayout(textLayout); layout->addWidget(textWidget, 1, 1); layout->setRowStretch(3, 10); layout->setColumnStretch(2, 10); QWidget *itemWidget = new QWidget; itemWidget->setLayout(layout); backgroundButtonGroup = new QButtonGroup(this); connect(backgroundButtonGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(backgroundButtonGroupClicked(QAbstractButton*))); QGridLayout *backgroundLayout = new QGridLayout; backgroundLayout->addWidget(createBackgroundCellWidget(tr("Blue Grid"), ":/images/background1.png"), 0, 0); backgroundLayout->addWidget(createBackgroundCellWidget(tr("White Grid"), ":/images/background2.png"), 0, 1); backgroundLayout->addWidget(createBackgroundCellWidget(tr("Gray Grid"), ":/images/background3.png"), 1, 0); backgroundLayout->addWidget(createBackgroundCellWidget(tr("No Grid"), ":/images/background4.png"), 1, 1); backgroundLayout->setRowStretch(2, 10); backgroundLayout->setColumnStretch(2, 10); QWidget *backgroundWidget = new QWidget; backgroundWidget->setLayout(backgroundLayout); //! [22] toolBox = new QToolBox; toolBox->setSizePolicy(QSizePolicy(QSizePolicy::Maximum, QSizePolicy::Ignored)); toolBox->setMinimumWidth(itemWidget->sizeHint().width()); toolBox->addItem(itemWidget, tr("Basic Flowchart Shapes")); toolBox->addItem(backgroundWidget, tr("Backgrounds")); } //! [22] //! [23] void MainWindow::createActions() { toFrontAction = new QAction(QIcon(":/images/bringtofront.png"), tr("Bring to &Front"), this); toFrontAction->setShortcut(tr("Ctrl+F")); toFrontAction->setStatusTip(tr("Bring item to front")); connect(toFrontAction, SIGNAL(triggered()), this, SLOT(bringToFront())); //! [23] sendBackAction = new QAction(QIcon(":/images/sendtoback.png"), tr("Send to &Back"), this); sendBackAction->setShortcut(tr("Ctrl+B")); sendBackAction->setStatusTip(tr("Send item to back")); connect(sendBackAction, SIGNAL(triggered()), this, SLOT(sendToBack())); deleteAction = new QAction(QIcon(":/images/delete.png"), tr("&Delete"), this); deleteAction->setShortcut(tr("Delete")); deleteAction->setStatusTip(tr("Delete item from diagram")); connect(deleteAction, SIGNAL(triggered()), this, SLOT(deleteItem())); exitAction = new QAction(tr("E&xit"), this); exitAction->setShortcuts(QKeySequence::Quit); exitAction->setStatusTip(tr("Quit Scenediagram example")); connect(exitAction, SIGNAL(triggered()), this, SLOT(close())); boldAction = new QAction(tr("Bold"), this); boldAction->setCheckable(true); QPixmap pixmap(":/images/bold.png"); boldAction->setIcon(QIcon(pixmap)); boldAction->setShortcut(tr("Ctrl+B")); connect(boldAction, SIGNAL(triggered()), this, SLOT(handleFontChange())); italicAction = new QAction(QIcon(":/images/italic.png"), tr("Italic"), this); italicAction->setCheckable(true); italicAction->setShortcut(tr("Ctrl+I")); connect(italicAction, SIGNAL(triggered()), this, SLOT(handleFontChange())); underlineAction = new QAction(QIcon(":/images/underline.png"), tr("Underline"), this); underlineAction->setCheckable(true); underlineAction->setShortcut(tr("Ctrl+U")); connect(underlineAction, SIGNAL(triggered()), this, SLOT(handleFontChange())); aboutAction = new QAction(tr("A&bout"), this); aboutAction->setShortcut(tr("Ctrl+B")); connect(aboutAction, SIGNAL(triggered()), this, SLOT(about())); } //! [24] void MainWindow::createMenus() { fileMenu = menuBar()->addMenu(tr("&File")); fileMenu->addAction(exitAction); itemMenu = menuBar()->addMenu(tr("&Item")); itemMenu->addAction(deleteAction); itemMenu->addSeparator(); itemMenu->addAction(toFrontAction); itemMenu->addAction(sendBackAction); aboutMenu = menuBar()->addMenu(tr("&Help")); aboutMenu->addAction(aboutAction); } //! [24] //! [25] void MainWindow::createToolbars() { //! [25] editToolBar = addToolBar(tr("Edit")); editToolBar->addAction(deleteAction); editToolBar->addAction(toFrontAction); editToolBar->addAction(sendBackAction); fontCombo = new QFontComboBox(); connect(fontCombo, SIGNAL(currentFontChanged(QFont)), this, SLOT(currentFontChanged(QFont))); fontSizeCombo = new QComboBox; fontSizeCombo->setEditable(true); for (int i = 8; i < 30; i = i + 2) fontSizeCombo->addItem(QString().setNum(i)); QIntValidator *validator = new QIntValidator(2, 64, this); fontSizeCombo->setValidator(validator); connect(fontSizeCombo, SIGNAL(currentIndexChanged(QString)), this, SLOT(fontSizeChanged(QString))); fontColorToolButton = new QToolButton; fontColorToolButton->setPopupMode(QToolButton::MenuButtonPopup); fontColorToolButton->setMenu(createColorMenu(SLOT(textColorChanged()), Qt::black)); textAction = fontColorToolButton->menu()->defaultAction(); fontColorToolButton->setIcon(createColorToolButtonIcon( ":/images/textpointer.png", Qt::black)); fontColorToolButton->setAutoFillBackground(true); connect(fontColorToolButton, SIGNAL(clicked()), this, SLOT(textButtonTriggered())); //! [26] fillColorToolButton = new QToolButton; fillColorToolButton->setPopupMode(QToolButton::MenuButtonPopup); fillColorToolButton->setMenu(createColorMenu(SLOT(itemColorChanged()), Qt::white)); fillAction = fillColorToolButton->menu()->defaultAction(); fillColorToolButton->setIcon(createColorToolButtonIcon( ":/images/floodfill.png", Qt::white)); connect(fillColorToolButton, SIGNAL(clicked()), this, SLOT(fillButtonTriggered())); //! [26] lineColorToolButton = new QToolButton; lineColorToolButton->setPopupMode(QToolButton::MenuButtonPopup); lineColorToolButton->setMenu(createColorMenu(SLOT(lineColorChanged()), Qt::black)); lineAction = lineColorToolButton->menu()->defaultAction(); lineColorToolButton->setIcon(createColorToolButtonIcon( ":/images/linecolor.png", Qt::black)); connect(lineColorToolButton, SIGNAL(clicked()), this, SLOT(lineButtonTriggered())); textToolBar = addToolBar(tr("Font")); textToolBar->addWidget(fontCombo); textToolBar->addWidget(fontSizeCombo); textToolBar->addAction(boldAction); textToolBar->addAction(italicAction); textToolBar->addAction(underlineAction); colorToolBar = addToolBar(tr("Color")); colorToolBar->addWidget(fontColorToolButton); colorToolBar->addWidget(fillColorToolButton); colorToolBar->addWidget(lineColorToolButton); QToolButton *pointerButton = new QToolButton; pointerButton->setCheckable(true); pointerButton->setChecked(true); pointerButton->setIcon(QIcon(":/images/pointer.png")); QToolButton *linePointerButton = new QToolButton; linePointerButton->setCheckable(true); linePointerButton->setIcon(QIcon(":/images/linepointer.png")); pointerTypeGroup = new QButtonGroup(this); pointerTypeGroup->addButton(pointerButton, int(DiagramScene::MoveItem)); pointerTypeGroup->addButton(linePointerButton, int(DiagramScene::InsertLine)); connect(pointerTypeGroup, SIGNAL(buttonClicked(int)), this, SLOT(pointerGroupClicked(int))); sceneScaleCombo = new QComboBox; QStringList scales; scales << tr("50%") << tr("75%") << tr("100%") << tr("125%") << tr("150%"); sceneScaleCombo->addItems(scales); sceneScaleCombo->setCurrentIndex(2); connect(sceneScaleCombo, SIGNAL(currentIndexChanged(QString)), this, SLOT(sceneScaleChanged(QString))); pointerToolbar = addToolBar(tr("Pointer type")); pointerToolbar->addWidget(pointerButton); pointerToolbar->addWidget(linePointerButton); pointerToolbar->addWidget(sceneScaleCombo); //! [27] } //! [27] //! [28] QWidget *MainWindow::createBackgroundCellWidget(const QString &text, const QString &image) { QToolButton *button = new QToolButton; button->setText(text); button->setIcon(QIcon(image)); button->setIconSize(QSize(50, 50)); button->setCheckable(true); backgroundButtonGroup->addButton(button); QGridLayout *layout = new QGridLayout; layout->addWidget(button, 0, 0, Qt::AlignHCenter); layout->addWidget(new QLabel(text), 1, 0, Qt::AlignCenter); QWidget *widget = new QWidget; widget->setLayout(layout); return widget; } //! [28] //! [29] QWidget *MainWindow::createCellWidget(const QString &text, DiagramItem::DiagramType type) { DiagramItem item(type, itemMenu); QIcon icon(item.image()); QToolButton *button = new QToolButton; button->setIcon(icon); button->setIconSize(QSize(50, 50)); button->setCheckable(true); buttonGroup->addButton(button, int(type)); QGridLayout *layout = new QGridLayout; layout->addWidget(button, 0, 0, Qt::AlignHCenter); layout->addWidget(new QLabel(text), 1, 0, Qt::AlignCenter); QWidget *widget = new QWidget; widget->setLayout(layout); return widget; } //! [29] //! [30] QMenu *MainWindow::createColorMenu(const char *slot, QColor defaultColor) { QList colors; colors << Qt::black << Qt::white << Qt::red << Qt::blue << Qt::yellow; QStringList names; names << tr("black") << tr("white") << tr("red") << tr("blue") << tr("yellow"); QMenu *colorMenu = new QMenu(this); for (int i = 0; i < colors.count(); ++i) { QAction *action = new QAction(names.at(i), this); action->setData(colors.at(i)); action->setIcon(createColorIcon(colors.at(i))); connect(action, SIGNAL(triggered()), this, slot); colorMenu->addAction(action); if (colors.at(i) == defaultColor) { colorMenu->setDefaultAction(action); } } return colorMenu; } //! [30] //! [31] QIcon MainWindow::createColorToolButtonIcon(const QString &imageFile, QColor color) { QPixmap pixmap(50, 80); pixmap.fill(Qt::transparent); QPainter painter(&pixmap); QPixmap image(imageFile); QRect target(0, 0, 50, 60); QRect source(0, 0, 42, 42); painter.fillRect(QRect(0, 60, 50, 80), color); painter.drawPixmap(target, image, source); return QIcon(pixmap); } //! [31] //! [32] QIcon MainWindow::createColorIcon(QColor color) { QPixmap pixmap(20, 20); QPainter painter(&pixmap); painter.setPen(Qt::NoPen); painter.fillRect(QRect(0, 0, 20, 20), color); return QIcon(pixmap); } //! [32]