doc/src/examples/diagramscene.qdoc
changeset 7 f7bc934e204c
equal deleted inserted replaced
3:41300fa6a67c 7:f7bc934e204c
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the documentation of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    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 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 /*!
       
    43     \example graphicsview/diagramscene
       
    44     \title Diagram Scene Example
       
    45     
       
    46     This example shows use of Qt's graphics framework. 
       
    47 
       
    48     \image diagramscene.png
       
    49 
       
    50     The Diagram Scene example is an application in which you can
       
    51     create a flowchart diagram. It is possible to add flowchart shapes
       
    52     and text and connect the shapes by arrows as shown in the image
       
    53     above.  The shapes, arrows, and text can be given different
       
    54     colors, and it is possible to change the font, style, and
       
    55     underline of the text.
       
    56 
       
    57     The Qt graphics view framework is designed to manage and
       
    58     display custom 2D graphics items. The main classes of the
       
    59     framework are QGraphicsItem, QGraphicsScene and QGraphicsView. The
       
    60     graphics scene manages the items and provides a surface for them.
       
    61     QGraphicsView is a widget that is used to render a scene on the
       
    62     screen. See the \l{The Graphics View Framework}{overview document}
       
    63     for a more detailed description of the framework. 
       
    64 
       
    65     In this example we show how to create such custom graphics
       
    66     scenes and items by implementing classes that inherit
       
    67     QGraphicsScene and QGraphicsItem. 
       
    68 
       
    69     In particular we show how to:
       
    70 
       
    71     \list
       
    72 	\o Create custom graphics items.
       
    73 	\o Handle mouse events and movement of items.
       
    74 	\o Implement a graphics scene that can manage our custom items.
       
    75 	\o Custom painting of items.
       
    76 	\o Create a movable and editable text item.
       
    77     \endlist
       
    78 
       
    79     The example consists of the following classes:
       
    80     \list
       
    81 	\o \c MainWindow creates the widgets and display
       
    82 	   them in a QMainWindow. It also manages the interaction 
       
    83 	   between the widgets and the graphics scene, view and 
       
    84 	   items.
       
    85 	\o \c DiagramItem inherits QGraphicsPolygonItem and
       
    86 	   represents a flowchart shape. 
       
    87 	\o \c TextDiagramItem inherits QGraphicsTextItem and
       
    88 	   represents text items in the diagram. The class adds
       
    89 	   support for moving the item with the mouse, which is not
       
    90 	   supported by QGraphicsTextItem.
       
    91 	\o \c Arrow inherits QGraphicsLineItem and is an arrow
       
    92 	   that connect two DiagramItems. 
       
    93 	\o \c DiagramScene inherits QGraphicsDiagramScene and
       
    94 	   provides support for \c DiagramItem, \c Arrow and 
       
    95 	   \c DiagramTextItem (In addition to the support already
       
    96 	   handled by QGraphicsScene).
       
    97     \endlist
       
    98 
       
    99     \section1 MainWindow Class Definition
       
   100 
       
   101     \snippet examples/graphicsview/diagramscene/mainwindow.h 0
       
   102 
       
   103     The \c MainWindow class creates and lays out the widgets in a
       
   104     QMainWindow. The class forwards input from the widgets to the
       
   105     DiagramScene. It also updates its widgets when the diagram 
       
   106     scene's text item changes, or a diagram item or a diagram text item
       
   107     is inserted into the scene.
       
   108 
       
   109     The class also deletes items from the scene and handles the
       
   110     z-ordering, which decides the order in which items are drawn when
       
   111     they overlap each other.
       
   112 
       
   113     \section1 MainWindow Class Implementation
       
   114 
       
   115 
       
   116     We start with a look at the constructor:
       
   117 
       
   118     \snippet examples/graphicsview/diagramscene/mainwindow.cpp 0
       
   119 
       
   120     In the constructor we call methods to create the widgets and
       
   121     layouts of the example before we create the diagram scene. 
       
   122     The toolbars must be created after the scene as they connect 
       
   123     to its signals. We then lay the widgets out in the window.
       
   124 
       
   125     We connect to the \c itemInserted() and \c textInserted() slots of
       
   126     the diagram scenes as we want to uncheck the buttons in the tool
       
   127     box when an item is inserted. When an item is selected in
       
   128     the scene we receive the \c itemSelected() signal. We use this to
       
   129     update the widgets that display font properties if the item
       
   130     selected is a \c DiagramTextItem.
       
   131 
       
   132     The \c createToolBox() function creates and lays out the widgets 
       
   133     of the \c toolBox QToolBox. We will not examine it with a
       
   134     high level of detail as it does not deal with graphics framework 
       
   135     specific functionality. Here is its implementation:
       
   136 
       
   137     \snippet examples/graphicsview/diagramscene/mainwindow.cpp 21
       
   138     
       
   139     This part of the function sets up the tabbed widget item that
       
   140     contains the flowchart shapes. An exclusive QButtonGroup always 
       
   141     keeps one button checked; we want the group to allow all buttons
       
   142     to be unchecked.
       
   143     We still use a button group since we can associate user
       
   144     data, which we use to store the diagram type, with each button. 
       
   145     The \c createCellWidget() function sets up the buttons in the 
       
   146     tabbed widget item and is examined later.
       
   147 
       
   148     The buttons of the background tabbed widget item is set up in the
       
   149     same way, so we skip to the creation of the tool box:
       
   150 
       
   151     \snippet examples/graphicsview/diagramscene/mainwindow.cpp 22
       
   152 
       
   153     We set the preferred size of the toolbox as its maximum. This
       
   154     way, more space is given to the graphics view. 
       
   155 
       
   156     Here is the \c createActions() function:
       
   157 
       
   158     \snippet examples/graphicsview/diagramscene/mainwindow.cpp 23
       
   159 
       
   160     We show an example of the creation of an action. The
       
   161     functionality the actions trigger is discussed in the slots we
       
   162     connect the actions to. You can see the \l{Application
       
   163     Example}{application example} if you need a high-level
       
   164     introduction to actions.
       
   165 
       
   166     The is the \c createMenus() function:
       
   167 
       
   168     \snippet examples/graphicsview/diagramscene/mainwindow.cpp 24
       
   169 
       
   170     We create the three menus' of the example.
       
   171 
       
   172     The \c createToolbars() function sets up the examples tool
       
   173     bars.  The three \l{QToolButton}s in the \c colorToolBar, the \c
       
   174     fontColorToolButton, \c fillColorToolButton, and \c
       
   175     lineColorToolButton, are interesting as we create icons for them
       
   176     by drawing on a QPixmap with a QPainter. We show how the \c
       
   177     fillColorToolButton is created. This button lets the user select a
       
   178     color for the diagram items.
       
   179 
       
   180     \snippet examples/graphicsview/diagramscene/mainwindow.cpp 25
       
   181     \dots
       
   182     \snippet examples/graphicsview/diagramscene/mainwindow.cpp 26
       
   183 
       
   184     We set the menu of the tool button with
       
   185     \l{QToolButton::}{setMenu()}. We need the \c fillAction QAction
       
   186     object to always be pointing to the selected action of the menu.
       
   187     The menu is created with the \c createColorMenu() function and, as
       
   188     we shall see later, contains one menu item for each color that the
       
   189     items can have.  When the user presses the button, which trigger
       
   190     the \l{QToolButton::}{clicked()} signal, we can set the color of
       
   191     the selected item to the color of \c fillAction. It is with \c
       
   192     createColorToolButtonIcon() we create the icon for the button.
       
   193 
       
   194     \dots
       
   195     \snippet examples/graphicsview/diagramscene/mainwindow.cpp 27
       
   196 
       
   197     Here is the \c createBackgroundCellWidget() function:
       
   198 
       
   199     \snippet examples/graphicsview/diagramscene/mainwindow.cpp 28
       
   200 
       
   201     This function creates \l{QWidget}s containing a tool button
       
   202     and a label. The widgets created with this function are used for
       
   203     the background tabbed widget item in the tool box.
       
   204 
       
   205     Here is the \c createCellWidget() function:
       
   206 
       
   207     \snippet examples/graphicsview/diagramscene/mainwindow.cpp 29
       
   208 
       
   209     This function returns a QWidget containing a QToolButton with
       
   210     an image of one of the \c DiagramItems, i.e., flowchart shapes.
       
   211     The image is created by the \c DiagramItem through the \c image()
       
   212     function.  The QButtonGroup class lets us attach a QVariant with
       
   213     each button; we store the diagram's type, i.e., the
       
   214     DiagramItem::DiagramType enum. We use the stored diagram type when
       
   215     we create new diagram items for the scene.  The widgets created
       
   216     with this function is used in the tool box.
       
   217 
       
   218     Here is the \c createColorMenu() function:
       
   219     
       
   220     \snippet examples/graphicsview/diagramscene/mainwindow.cpp 30
       
   221 
       
   222     This function creates a color menu that is used as the
       
   223     drop-down menu for the tool buttons in the \c colorToolBar. We
       
   224     create an action for each color that we add to the menu. We fetch
       
   225     the actions data when we set the color of items, lines, and text.
       
   226 
       
   227     Here is the \c createColorToolButtonIcon() function:
       
   228 
       
   229     \snippet examples/graphicsview/diagramscene/mainwindow.cpp 31
       
   230 
       
   231     This function is used to create the QIcon of the \c
       
   232     fillColorToolButton, \c fontColorToolButton, and \c
       
   233     lineColorToolButton. The \a imageFile string is either the text,
       
   234     flood-fill, or line symbol that is used for the buttons. Beneath
       
   235     the image we draw a filled rectangle using \a color.
       
   236 
       
   237     Here is the \c createColorIcon() function:
       
   238 
       
   239     \snippet examples/graphicsview/diagramscene/mainwindow.cpp 32
       
   240 
       
   241     This function creates an icon with a filled rectangle in the 
       
   242     color of \a color. It is used for creating icons for the color
       
   243     menus in the \c fillColorToolButton, \c fontColorToolButton, and
       
   244     \c lineColorToolButton.
       
   245 
       
   246     Here is the \c backgroundButtonGroupClicked() slot:
       
   247 
       
   248     \snippet examples/graphicsview/diagramscene/mainwindow.cpp 1
       
   249 
       
   250     In this function we set the QBrush that is used to draw the
       
   251     background of the diagramscene. The background can be a grid of
       
   252     squares of blue, gray, or white tiles, or no grid at all. We have
       
   253     \l{QPixmap}s of the tiles from png files that we create the brush
       
   254     with.
       
   255 
       
   256     When one of the buttons in the background tabbed widget item is
       
   257     clicked we change the brush; we find out which button it is by 
       
   258     checking its text. 
       
   259 
       
   260     Here is the implementation of \c buttonGroupClicked():
       
   261 
       
   262     \snippet examples/graphicsview/diagramscene/mainwindow.cpp 2
       
   263 
       
   264     This slot is called when a button in \c buttonGroup is checked.
       
   265     When a button is checked the user can click on the graphics view
       
   266     and a \c DiagramItem of the selected type will be inserted into
       
   267     the \c DiagramScene. We must loop through the buttons in the group
       
   268     to uncheck other buttons as only one button is allowed to be
       
   269     checked at a time.
       
   270 
       
   271     \c QButtonGroup assigns an id to each button. We have set the id
       
   272     of each button to the diagram type, as given by DiagramItem::DiagramType 
       
   273     that will be inserted into the scene when it is clicked. We can 
       
   274     then use the button id when we set the diagram type with 
       
   275     \c setItemType(). In the case of text we assigned an id that has a
       
   276     value that is not in the DiagramType enum.
       
   277     
       
   278     Here is the implementation of \c deleteItem():
       
   279     
       
   280     \snippet examples/graphicsview/diagramscene/mainwindow.cpp 3
       
   281     
       
   282     This slot deletes the selected item, if any, from the scene. If
       
   283     the item to be deleted is a \c DiagramItem, we also need to delete
       
   284     arrows connected to it; we don't want arrows in the scene that
       
   285     aren't connected to items in both ends.
       
   286     
       
   287     This is the implementation of pointerGroupClicked():
       
   288     
       
   289     \snippet examples/graphicsview/diagramscene/mainwindow.cpp 4
       
   290     
       
   291     The \c pointerTypeGroup decides whether the scene is in ItemMove
       
   292     or InsertLine mode. This button group is exclusive, i.e., only 
       
   293     one button is checked at any time. As with the \c buttonGroup above
       
   294     we have assigned an id to the buttons that matches values of the
       
   295     DiagramScene::Mode enum, so that we can use the id to set the
       
   296     correct mode.
       
   297     
       
   298     Here is the \c bringToFront() slot:
       
   299     
       
   300     \snippet examples/graphicsview/diagramscene/mainwindow.cpp 5
       
   301     
       
   302     Several items may collide, i.e., overlap, with each other in
       
   303     the scene.  This slot is called when the user requests that an
       
   304     item should be placed on top of the items it collides with.
       
   305     \l{QGraphicsItem}{QGrapicsItems} have a z-value that decides the
       
   306     order in which items are stacked in the scene; you can think of it
       
   307     as the z-axis in a 3D coordinate system.  When items collide the
       
   308     items with higher z-values will be drawn on top of items with
       
   309     lower values. When we bring an item to the front we can loop
       
   310     through the items it collides with and set a z-value that is
       
   311     higher than all of them.
       
   312     
       
   313     Here is the \c sendToBack() slot:
       
   314     
       
   315     \snippet examples/graphicsview/diagramscene/mainwindow.cpp 6
       
   316     
       
   317     This slot works in the same way as \c bringToFront() described
       
   318     above, but sets a z-value that is lower than items the item that
       
   319     should be send to the back collides with.
       
   320     
       
   321     This is the implementation of \c itemInserted():
       
   322     
       
   323     \snippet examples/graphicsview/diagramscene/mainwindow.cpp 7
       
   324     
       
   325     This slot is called from the \c DiagramScene when an item has been
       
   326     added to the scene. We set the mode of the scene back to the mode
       
   327     before the item was inserted, which is ItemMove or InsertText
       
   328     depending on which button is checked in the \c pointerTypeGroup. 
       
   329     We must also uncheck the button in the in the \c buttonGroup.
       
   330     
       
   331     Here is the implementation of \c textInserted():
       
   332     
       
   333     \snippet examples/graphicsview/diagramscene/mainwindow.cpp 8
       
   334     
       
   335     We simply set the mode of the scene back to the mode it had before
       
   336     the text was inserted.
       
   337     
       
   338     Here is the \c currentFontChanged() slot:
       
   339     
       
   340     \snippet examples/graphicsview/diagramscene/mainwindow.cpp 9
       
   341     
       
   342     When the user requests a font change, by using one of the
       
   343     widgets in the \c fontToolBar, we create a new QFont object and
       
   344     set its properties to match the state of the widgets. This is done
       
   345     in \c handleFontChange(), so we simply call that slot.
       
   346     
       
   347     Here is the \c fontSizeChanged() slot:
       
   348     
       
   349     \snippet examples/graphicsview/diagramscene/mainwindow.cpp 10
       
   350     
       
   351     When the user requests a font change, by using one of the
       
   352     widgets in the \c fontToolBar, we create a new QFont object and
       
   353     set its properties to match the state of the widgets. This is done
       
   354     in \c handleFontChange(), so we simply call that slot.
       
   355     
       
   356     Here is the implementation of \c sceneScaleChanged():
       
   357     
       
   358     \snippet examples/graphicsview/diagramscene/mainwindow.cpp 11
       
   359     
       
   360     The user can increase or decrease the scale, with the \c
       
   361     sceneScaleCombo, the scene is drawn in.
       
   362     It is not the scene itself that changes its scale, but only the
       
   363     view.  
       
   364     
       
   365     Here is the \c textColorChanged() slot:
       
   366     
       
   367     \snippet examples/graphicsview/diagramscene/mainwindow.cpp 12
       
   368     
       
   369     This slot is called when an item in the drop-down menu of the \c
       
   370     fontColorToolButton is pressed. We need to change the icon on 
       
   371     the button to the color of the selected QAction. We keep a pointer
       
   372     to the selected action in \c textAction. It is in \c
       
   373     textButtonTriggered() we change the text color to the color of \c
       
   374     textAction, so we call that slot.
       
   375     
       
   376     Here is the \c itemColorChanged() implementation:
       
   377     
       
   378     \snippet examples/graphicsview/diagramscene/mainwindow.cpp 13
       
   379     
       
   380     This slot handles requests for changing the color of \c
       
   381     DiagramItems in the same manner as \c textColorChanged() does for
       
   382     \c DiagramTextItems.
       
   383     
       
   384     Here is the implementation of \c lineColorChanged():
       
   385     
       
   386     \snippet examples/graphicsview/diagramscene/mainwindow.cpp 14
       
   387     
       
   388     This slot handles requests for changing the color of \c Arrows in
       
   389     the same manner that \c textColorChanged() does it for \c
       
   390     DiagramTextItems.
       
   391     
       
   392     Here is the \c textButtonTriggered() slot:
       
   393     
       
   394     \snippet examples/graphicsview/diagramscene/mainwindow.cpp 15
       
   395     
       
   396     \c textAction points to the  QAction of the currently selected menu item
       
   397     in the \c fontColorToolButton's color drop-down menu. We have set
       
   398     the data of the action to the QColor the action represents, so we
       
   399     can simply fetch this when we set the color of text with \c
       
   400     setTextColor().
       
   401     
       
   402     Here is the \c fillButtonTriggered() slot:
       
   403     
       
   404     \snippet examples/graphicsview/diagramscene/mainwindow.cpp 16
       
   405     
       
   406     \c fillAction points to the selected menu item in the drop-down
       
   407     menu of \c fillColorToolButton(). We can therefore use the data of
       
   408     this action when we set the item color with \c setItemColor().
       
   409     
       
   410     Here is the \c lineButtonTriggered() slot:
       
   411     
       
   412     \snippet examples/graphicsview/diagramscene/mainwindow.cpp 17
       
   413     
       
   414     \c lineAction point to the selected item in the drop-down menu of
       
   415     \c lineColorToolButton. We use its data when we set the arrow 
       
   416     color with \c setLineColor().
       
   417     
       
   418     Here is the \c handleFontChange() function:
       
   419     
       
   420     \snippet examples/graphicsview/diagramscene/mainwindow.cpp 18
       
   421     
       
   422     \c handleFontChange() is called when any of the widgets that show
       
   423     font properties changes. We create a new QFont object and set its
       
   424     properties based on the widgets. We then call the \c setFont()
       
   425     function of \c DiagramScene; it is the scene that set the font of
       
   426     the \c DiagramTextItems it manages.
       
   427     
       
   428     Here is the \c itemSelected() slot:
       
   429     
       
   430     \snippet examples/graphicsview/diagramscene/mainwindow.cpp 19
       
   431     
       
   432     This slot is called when an item in the \c DiagramScene is
       
   433     selected. In the case of this example it is only text items that
       
   434     emit signals when they are selected, so we do not need to check
       
   435     what kind of graphics \a item is.
       
   436     
       
   437     We set the state of the widgets to match the properties of the
       
   438     font of the selected text item.
       
   439     
       
   440     This is the \c about() slot:
       
   441     
       
   442     \snippet examples/graphicsview/diagramscene/mainwindow.cpp 20
       
   443     
       
   444     This slot displays an about box for the example when the user
       
   445     selects the about menu item from the help menu.
       
   446     
       
   447     \section1 DiagramScene Class Definition
       
   448     
       
   449     The \c DiagramScene class inherits QGraphicsScene and adds
       
   450     functionality to handle \c DiagramItems, \c Arrows, and \c
       
   451     DiagramTextItems in addition to the items handled by its super
       
   452     class.
       
   453     
       
   454     
       
   455     \snippet examples/graphicsview/diagramscene/diagramscene.h 0
       
   456     
       
   457     In the \c DiagramScene a mouse click can give three different
       
   458     actions: the item under the mouse can be moved, an item may be
       
   459     inserted, or an arrow may be connected between to diagram items.
       
   460     Which action a mouse click has depends on the mode, given by the
       
   461     Mode enum, the scene is in. The mode is set with the \c setMode()
       
   462     function.
       
   463     
       
   464     The scene also sets the color of its items and the font of its
       
   465     text items.  The colors and font used by the scene can be set with
       
   466     the \c setLineColor(), \c setTextColor(), \c setItemColor() and \c
       
   467     setFont() functions. The type of \c DiagramItem, given by the
       
   468     DiagramItem::DiagramType function, to be created when an item is
       
   469     inserted is set with the \c setItemType() slot.
       
   470     
       
   471     The \c MainWindow and \c DiagramScene share responsibility for
       
   472     the examples functionality. \c MainWindow handles the following
       
   473     tasks: the deletion of items, text, and arrows; moving diagram
       
   474     items to the back and front; and setting the scale of the scene. 
       
   475 
       
   476     \section1 DiagramScene Class Implementation
       
   477 
       
   478 
       
   479     We start with the constructor:
       
   480 
       
   481     \snippet examples/graphicsview/diagramscene/diagramscene.cpp 0
       
   482 
       
   483     The scene uses \c myItemMenu to set the context menu when it
       
   484     creates \c DiagramItems. We set the default mode to \c
       
   485     DiagramScene::MoveItem as this gives the default behavior of
       
   486     QGraphicsScene.
       
   487 
       
   488     Here is the \c setLineColor() function:
       
   489 
       
   490     \snippet examples/graphicsview/diagramscene/diagramscene.cpp 1
       
   491 
       
   492     The \c isItemChange function returns true if an \c Arrow item is
       
   493     selected in the scene in which case we want to change its color.
       
   494     When the \c DiagramScene creates and adds new arrows to the scene
       
   495     it will also use the new \a color.
       
   496 
       
   497     Here is the \c setTextColor() function:
       
   498 
       
   499     \snippet examples/graphicsview/diagramscene/diagramscene.cpp 2
       
   500 
       
   501     This function sets the color of \c DiagramTextItems equal to the
       
   502     way \c setLineColor() sets the color of \c Arrows.
       
   503 
       
   504     Here is the \c setItemColor() function:
       
   505 
       
   506     \snippet examples/graphicsview/diagramscene/diagramscene.cpp 3
       
   507 
       
   508     This function sets the color the scene will use when creating 
       
   509     \c DiagramItems. It also changes the color of a selected \c
       
   510     DiagramItem.
       
   511 
       
   512     This is the implementation of \c setFont():
       
   513     
       
   514     \snippet examples/graphicsview/diagramscene/diagramscene.cpp 4
       
   515 
       
   516     Set the font to use for new and selected, if a text item is
       
   517     selected, \c DiagramTextItems.
       
   518 
       
   519     This is the implementation of \c editorLostFocus() slot:
       
   520 
       
   521     \snippet examples/graphicsview/diagramscene/diagramscene.cpp 5
       
   522 
       
   523     \c DiagramTextItems emit a signal when they loose focus, which is
       
   524     connected to this slot. We remove the item if it has no text.
       
   525     If not, we would leak memory and confuse the user as the items
       
   526     will be edited when pressed on by the mouse.
       
   527     
       
   528     The \c mousePressEvent() function handles mouse press event's
       
   529     different depending on which mode the \c DiagramScene is in. We
       
   530     examine its implementation for each mode:
       
   531     
       
   532     \snippet examples/graphicsview/diagramscene/diagramscene.cpp 6
       
   533 
       
   534     We simply create a new \c DiagramItem and add it to the scene at
       
   535     the position the mouse was pressed. Note that the origin of its 
       
   536     local coordinate system will be under the mouse pointer position.
       
   537 
       
   538     \snippet examples/graphicsview/diagramscene/diagramscene.cpp 7
       
   539 
       
   540     The user adds \c Arrows to the scene by stretching a line between
       
   541     the items the arrow should connect. The start of the line is fixed
       
   542     in the place the user clicked the mouse and the end follows the
       
   543     mouse pointer as long as the button is held down. When the user
       
   544     releases the mouse button an \c Arrow will be added to the scene
       
   545     if there is a \c DiagramItem under the start and end of the line.
       
   546     We will see how this is implemented later; here we simply add the
       
   547     line.
       
   548 
       
   549     \snippet examples/graphicsview/diagramscene/diagramscene.cpp 8
       
   550     
       
   551     The \c DiagramTextItem is editable when the
       
   552     Qt::TextEditorInteraction flag is set, else it is movable by the
       
   553     mouse. We always want the text to be drawn on top of the other
       
   554     items in the scene, so we set the value to a number higher
       
   555     than other items in the scene.
       
   556 
       
   557     \snippet examples/graphicsview/diagramscene/diagramscene.cpp 9
       
   558 
       
   559     We are in MoveItem mode if we get to the default switch; we
       
   560     can then call the QGraphicsScene implementation, which
       
   561     handles movement of items with the mouse. We make this call even
       
   562     if we are in another mode making it possible to add an item and
       
   563     then keep the mouse button pressed down and start moving 
       
   564     the item. In the case of text items, this is not possible as they
       
   565     do not propagate mouse events when they are editable.
       
   566 
       
   567     This is the \c mouseMoveEvent() function:
       
   568     
       
   569     \snippet examples/graphicsview/diagramscene/diagramscene.cpp 10
       
   570 
       
   571     We must draw the line if we are in InsertMode and the mouse button
       
   572     is pressed down (the line is not 0). As discussed in \c
       
   573     mousePressEvent() the line is drawn from the position the mouse
       
   574     was pressed to the current position of the mouse.
       
   575 
       
   576     If we are in MoveItem mode, we call the QGraphicsScene
       
   577     implementation, which handles movement of items.
       
   578 
       
   579     In the \c mouseReleaseEvent() function we need to check if an arrow
       
   580     should be added to the scene:
       
   581 
       
   582     \snippet examples/graphicsview/diagramscene/diagramscene.cpp 11
       
   583     
       
   584     First we need to get the items (if any) under the line's start
       
   585     and end points. The line itself is the first item at these points,
       
   586     so we remove it from the lists. As a precaution, we check if the
       
   587     lists are empty, but this should never happen.
       
   588 
       
   589     \snippet examples/graphicsview/diagramscene/diagramscene.cpp 12
       
   590 
       
   591     Now we check if there are two different \c DiagramItems under
       
   592     the lines start and end points. If there are we can create an \c
       
   593     Arrow with the two items. The arrow is then added to each item and
       
   594     finally the scene. The arrow must be updated to adjust its start
       
   595     and end points to the items. We set the z-value of the arrow to
       
   596     -1000.0 because we always want it to be drawn under the items.
       
   597 
       
   598     \snippet examples/graphicsview/diagramscene/diagramscene.cpp 13
       
   599 
       
   600     Here is the \c isItemChange() function:
       
   601 
       
   602     \snippet examples/graphicsview/diagramscene/diagramscene.cpp 14
       
   603 
       
   604     The scene has single selection, i.e., only one item can be
       
   605     selected at any given time. The foreach will then loop one time
       
   606     with the selected item or none if no item is selected. \c
       
   607     isItemChange() is used to check whether a selected item exists
       
   608     and also is of the specified diagram \a type.
       
   609 
       
   610     \section1 DiagramItem Class Definition
       
   611 
       
   612 
       
   613     \snippet examples/graphicsview/diagramscene/diagramitem.h 0
       
   614 
       
   615     The \c DiagramItem represents a flowchart shape in the \c
       
   616     DiagramScene. It inherits QGraphicsPolygonItem and has a polygon
       
   617     for each shape. The enum DiagramType has a value for each of the
       
   618     flowchart shapes.
       
   619     
       
   620     The class has a list of the arrows that are connected to it.
       
   621     This is necessary because only the item knows when it is being
       
   622     moved (with the \c itemChanged() function) at which time the
       
   623     arrows must be updated. The item can also draw itself onto a
       
   624     QPixmap with the \c image() function. This is used for the tool
       
   625     buttons in \c MainWindow, see \c createColorToolButtonIcon() in
       
   626     \c MainWindow.
       
   627 
       
   628     The Type enum is a unique identifier of the class. It is used by 
       
   629     \c qgraphicsitem_cast(), which does dynamic casts of graphics
       
   630     items. The UserType constant is the minimum value a custom
       
   631     graphics item type can be.
       
   632 
       
   633     \section1 DiagramItem Class Implementation
       
   634 
       
   635 
       
   636     We start with a look at the constructor:
       
   637 
       
   638     \snippet examples/graphicsview/diagramscene/diagramitem.cpp 0
       
   639 
       
   640     In the constructor we create the items polygon according to
       
   641     \a diagramType. \l{QGraphicsItem}s are not movable or selectable
       
   642     by default, so we must set these properties.
       
   643 
       
   644     Here is the \c removeArrow() function:
       
   645 
       
   646     \snippet examples/graphicsview/diagramscene/diagramitem.cpp 1
       
   647 
       
   648     \c removeArrow() is used to remove \c Arrow items when they
       
   649     or \c DiagramItems they are connected to are removed from the
       
   650     scene.
       
   651 
       
   652     Here is the \c removeArrows() function:
       
   653 
       
   654     \snippet examples/graphicsview/diagramscene/diagramitem.cpp 2
       
   655 
       
   656     This function is called when the item is removed from the scene
       
   657     and removes all arrows that are connected to this item. The arrow
       
   658     must be removed from the \c arrows list of both its start and end
       
   659     item.
       
   660 
       
   661     Here is the \c addArrow() function:
       
   662     
       
   663     \snippet examples/graphicsview/diagramscene/diagramitem.cpp 3
       
   664 
       
   665     This function simply adds the \a arrow to the items \c arrows list.
       
   666 
       
   667     Here is the \c image() function:
       
   668 
       
   669     \snippet examples/graphicsview/diagramscene/diagramitem.cpp 4
       
   670 
       
   671     This function draws the polygon of the item onto a QPixmap. In
       
   672     this example we use this to create icons for the tool buttons in
       
   673     the tool box.
       
   674 
       
   675     Here is the \c contextMenuEvent() function:
       
   676 
       
   677     \snippet examples/graphicsview/diagramscene/diagramitem.cpp 5
       
   678 
       
   679     We show the context menu. As right mouse clicks, which shows the
       
   680     menu, don't select items by default we set the item selected with
       
   681     \l{QGraphicsItem::}{setSelected()}. This is necessary since an
       
   682     item must be selected to change its elevation with the
       
   683     \c bringToFront and \c sendToBack actions.
       
   684 
       
   685     This is the implementation of \c itemChange():
       
   686 
       
   687     \snippet examples/graphicsview/diagramscene/diagramitem.cpp 6
       
   688 
       
   689     If the item has moved, we need to update the positions of the
       
   690     arrows connected to it. The implementation of QGraphicsItem does
       
   691     nothing, so we just return \a value.
       
   692 
       
   693     \section1 DiagramTextItem Class Definition
       
   694 
       
   695     The \c TextDiagramItem class inherits QGraphicsTextItem and
       
   696     adds the possibility to move editable text items. Editable
       
   697     QGraphicsTextItems are designed to be fixed in place and editing
       
   698     starts when the user single clicks on the item. With \c
       
   699     DiagramTextItem the editing starts with a double click leaving
       
   700     single click available to interact with and move it.
       
   701 
       
   702     \snippet examples/graphicsview/diagramscene/diagramtextitem.h 0
       
   703 
       
   704     We use \c itemChange() and \c focusOutEvent() to notify the
       
   705     \c DiagramScene when the text item loses focus and gets selected.
       
   706 
       
   707     We reimplement the functions that handle mouse events to make it
       
   708     possible to alter the mouse behavior of QGraphicsTextItem.
       
   709 
       
   710     \section1 DiagramTextItem Implementation
       
   711     
       
   712     We start with the constructor:
       
   713 
       
   714     \snippet examples/graphicsview/diagramscene/diagramtextitem.cpp 0
       
   715 
       
   716     We simply set the item movable and selectable, as these flags are
       
   717     off by default.
       
   718 
       
   719     Here is the \c itemChange() function:
       
   720 
       
   721     \snippet examples/graphicsview/diagramscene/diagramtextitem.cpp 1
       
   722 
       
   723     When the item is selected we emit the selectedChanged signal. The
       
   724     \c MainWindow uses this signal to update the widgets that display
       
   725     font properties to the font of the selected text item.
       
   726 
       
   727     Here is the \c focusOutEvent() function:
       
   728 
       
   729     \snippet examples/graphicsview/diagramscene/diagramtextitem.cpp 2
       
   730 
       
   731     \c DiagramScene uses the signal emitted when the text item looses
       
   732     focus to remove the item if it is empty, i.e., it contains no
       
   733     text. 
       
   734 
       
   735     This is the implementation of \c mouseDoubleClickEvent():
       
   736 
       
   737     \snippet examples/graphicsview/diagramscene/diagramtextitem.cpp 5
       
   738 
       
   739     When we receive a double click event, we make the item editable by calling
       
   740     QGraphicsTextItem::setTextInteractionFlags(). We then forward the
       
   741     double-click to the item itself.
       
   742 
       
   743     \section1 Arrow Class Definition
       
   744 
       
   745     The \c Arrow class is a graphics item that connects two \c
       
   746     DiagramItems. It draws an arrow head to one of the items. To
       
   747     achieve this the item needs to paint itself and also re implement
       
   748     methods used by the graphics scene to check for collisions and
       
   749     selections. The class inherits QGraphicsLine item, and draws the
       
   750     arrowhead and moves with the items it connects.
       
   751 
       
   752     \snippet examples/graphicsview/diagramscene/arrow.h 0
       
   753 
       
   754     The item's color can be set with \c setColor().
       
   755 
       
   756     \c boundingRect() and \c shape() are reimplemented 
       
   757     from QGraphicsLineItem and are used by the scene
       
   758     to check for collisions and selections.
       
   759 
       
   760     Calling \c updatePosition() causes the arrow to recalculate its
       
   761     position and arrow head angle. \c paint() is reimplemented so that
       
   762     we can paint an arrow rather than just a line between items.
       
   763 
       
   764     \c myStartItem and \c myEndItem are the diagram items that the
       
   765     arrow connects. The arrow is drawn with its head to the end item.
       
   766     \c arrowHead is a polygon with three vertices's we use to draw the
       
   767     arrow head.
       
   768 
       
   769     \section1 Arrow Class Implementation
       
   770 
       
   771     The constructor of the \c Arrow class looks like this:
       
   772 
       
   773     \snippet examples/graphicsview/diagramscene/arrow.cpp 0
       
   774 
       
   775     We set the start and end diagram items of the arrow. The arrow
       
   776     head will be drawn where the line intersects the end item.
       
   777 
       
   778     Here is the \c boundingRect() function:
       
   779 
       
   780     \snippet examples/graphicsview/diagramscene/arrow.cpp 1
       
   781 
       
   782     We need to reimplement this function because the arrow is
       
   783     larger than the bounding rectangle of the QGraphicsLineItem. The
       
   784     graphics scene uses the bounding rectangle to know which regions
       
   785     of the scene to update. 
       
   786 
       
   787     Here is the \c shape() function:
       
   788 
       
   789     \snippet examples/graphicsview/diagramscene/arrow.cpp 2
       
   790 
       
   791     The shape function returns a QPainterPath that is the exact
       
   792     shape of the item. The QGraphicsLineItem::shape() returns a path
       
   793     with a line drawn with the current pen, so we only need to add
       
   794     the arrow head. This function is used to check for collisions and
       
   795     selections with the mouse. 
       
   796 
       
   797     Here is the \c updatePosition() slot:
       
   798 
       
   799     \snippet examples/graphicsview/diagramscene/arrow.cpp 3
       
   800 
       
   801     This slot updates the arrow by setting the start and end
       
   802     points of its line to the center of the items it connects. 
       
   803 
       
   804     Here is the \c paint() function:
       
   805 
       
   806     \snippet examples/graphicsview/diagramscene/arrow.cpp 4
       
   807 
       
   808     If the start and end items collide we do not draw the arrow; the
       
   809     algorithm we use to find the point the arrow should be drawn at
       
   810     may fail if the items collide.
       
   811 
       
   812     We first set the pen and brush we will use for drawing the arrow.
       
   813 
       
   814     \snippet examples/graphicsview/diagramscene/arrow.cpp 5
       
   815 
       
   816     We then need to find the position at which to draw the
       
   817     arrowhead.  The head should be drawn where the line and the end
       
   818     item intersects. This is done by taking the line between each
       
   819     point in the polygon and check if it intersects with the line of
       
   820     the arrow. Since the line start and end points are set to the
       
   821     center of the items the arrow line should intersect one and only
       
   822     one of the lines of the polygon. Note that the points in the
       
   823     polygon are relative to the local coordinate system of the item.
       
   824     We must therefore add the position of the end item to make the
       
   825     coordinates relative to the scene. 
       
   826 
       
   827     \snippet examples/graphicsview/diagramscene/arrow.cpp 6
       
   828 
       
   829     We calculate the angle between the x-axis and the line of the
       
   830     arrow. We need to turn the arrow head to this angle so that it
       
   831     follows the direction of the arrow. If the angle is negative we
       
   832     must turn the direction of the arrow.
       
   833 
       
   834     We can then calculate the three points of the arrow head polygon.
       
   835     One of the points is the end of the line, which now is the
       
   836     intersection between the arrow line and the end polygon. Then we
       
   837     clear the \c arrowHead polygon from the previous calculated arrow
       
   838     head and set these new points.
       
   839 
       
   840     \snippet examples/graphicsview/diagramscene/arrow.cpp 7
       
   841 
       
   842     If the line is selected, we draw two dotted lines that are
       
   843     parallel with the line of the arrow. We do not use the default
       
   844     implementation, which uses \l{QGraphicsItem::}{boundingRect()}
       
   845     because the QRect bounding rectangle is considerably larger than
       
   846     the line.
       
   847 */