- Qt 5.5
- Qt Widgets
- Diagram Scene Example
- diagramscene.cpp Example File
- Qt 5.5.1 Reference Documentation

# diagramscene.cpp Example File

graphicsview/diagramscene/diagramscene.cpp

    /****************************************************************************
    **
    ** Copyright (C) 2015 The Qt Company Ltd.
    ** Contact: http://www.qt.io/licensing/
    **
    ** 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 The Qt Company Ltd 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 "diagramscene.h"
    #include "arrow.h"

    #include <QTextCursor>
    #include <QGraphicsSceneMouseEvent>

    DiagramScene::DiagramScene(QMenu *itemMenu, QObject *parent)
        : QGraphicsScene(parent)
    {
        myItemMenu = itemMenu;
        myMode = MoveItem;
        myItemType = DiagramItem::Step;
        line = 0;
        textItem = 0;
        myItemColor = Qt::white;
        myTextColor = Qt::black;
        myLineColor = Qt::black;
    }

    void DiagramScene::setLineColor(const QColor &color)
    {
        myLineColor = color;
        if (isItemChange(Arrow::Type)) {
            Arrow *item = qgraphicsitem_cast<Arrow *>(selectedItems().first());
            item->setColor(myLineColor);
            update();
        }
    }

    void DiagramScene::setTextColor(const QColor &color)
    {
        myTextColor = color;
        if (isItemChange(DiagramTextItem::Type)) {
            DiagramTextItem *item = qgraphicsitem_cast<DiagramTextItem *>(selectedItems().first());
            item->setDefaultTextColor(myTextColor);
        }
    }

    void DiagramScene::setItemColor(const QColor &color)
    {
        myItemColor = color;
        if (isItemChange(DiagramItem::Type)) {
            DiagramItem *item = qgraphicsitem_cast<DiagramItem *>(selectedItems().first());
            item->setBrush(myItemColor);
        }
    }

    void DiagramScene::setFont(const QFont &font)
    {
        myFont = font;

        if (isItemChange(DiagramTextItem::Type)) {
            QGraphicsTextItem *item = qgraphicsitem_cast<DiagramTextItem *>(selectedItems().first());
            //At this point the selection can change so the first selected item might not be a DiagramTextItem
            if (item)
                item->setFont(myFont);
        }
    }

    void DiagramScene::setMode(Mode mode)
    {
        myMode = mode;
    }

    void DiagramScene::setItemType(DiagramItem::DiagramType type)
    {
        myItemType = type;
    }

    void DiagramScene::editorLostFocus(DiagramTextItem *item)
    {
        QTextCursor cursor = item->textCursor();
        cursor.clearSelection();
        item->setTextCursor(cursor);

        if (item->toPlainText().isEmpty()) {
            removeItem(item);
            item->deleteLater();
        }
    }

    void DiagramScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
    {
        if (mouseEvent->button() != Qt::LeftButton)
            return;

        DiagramItem *item;
        switch (myMode) {
            case InsertItem:
                item = new DiagramItem(myItemType, myItemMenu);
                item->setBrush(myItemColor);
                addItem(item);
                item->setPos(mouseEvent->scenePos());
                emit itemInserted(item);
                break;
            case InsertLine:
                line = new QGraphicsLineItem(QLineF(mouseEvent->scenePos(),
                                            mouseEvent->scenePos()));
                line->setPen(QPen(myLineColor, 2));
                addItem(line);
                break;
            case InsertText:
                textItem = new DiagramTextItem();
                textItem->setFont(myFont);
                textItem->setTextInteractionFlags(Qt::TextEditorInteraction);
                textItem->setZValue(1000.0);
                connect(textItem, SIGNAL(lostFocus(DiagramTextItem*)),
                        this, SLOT(editorLostFocus(DiagramTextItem*)));
                connect(textItem, SIGNAL(selectedChange(QGraphicsItem*)),
                        this, SIGNAL(itemSelected(QGraphicsItem*)));
                addItem(textItem);
                textItem->setDefaultTextColor(myTextColor);
                textItem->setPos(mouseEvent->scenePos());
                emit textInserted(textItem);
        default:
            ;
        }
        QGraphicsScene::mousePressEvent(mouseEvent);
    }

    void DiagramScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
    {
        if (myMode == InsertLine && line != 0) {
            QLineF newLine(line->line().p1(), mouseEvent->scenePos());
            line->setLine(newLine);
        } else if (myMode == MoveItem) {
            QGraphicsScene::mouseMoveEvent(mouseEvent);
        }
    }

    void DiagramScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
    {
        if (line != 0 && myMode == InsertLine) {
            QList<QGraphicsItem *> startItems = items(line->line().p1());
            if (startItems.count() && startItems.first() == line)
                startItems.removeFirst();
            QList<QGraphicsItem *> endItems = items(line->line().p2());
            if (endItems.count() && endItems.first() == line)
                endItems.removeFirst();

            removeItem(line);
            delete line;

            if (startItems.count() > 0 && endItems.count() > 0 &&
                startItems.first()->type() == DiagramItem::Type &&
                endItems.first()->type() == DiagramItem::Type &&
                startItems.first() != endItems.first()) {
                DiagramItem *startItem = qgraphicsitem_cast<DiagramItem *>(startItems.first());
                DiagramItem *endItem = qgraphicsitem_cast<DiagramItem *>(endItems.first());
                Arrow *arrow = new Arrow(startItem, endItem);
                arrow->setColor(myLineColor);
                startItem->addArrow(arrow);
                endItem->addArrow(arrow);
                arrow->setZValue(-1000.0);
                addItem(arrow);
                arrow->updatePosition();
            }
        }
        line = 0;
        QGraphicsScene::mouseReleaseEvent(mouseEvent);
    }

    bool DiagramScene::isItemChange(int type)
    {
        foreach (QGraphicsItem *item, selectedItems()) {
            if (item->type() == type)
                return true;
        }
        return false;
    }