Root/Software/sie_cg/block_editor/diagramscene.cpp

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 examples of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
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** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at qt-info@nokia.com.
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include <QtGui>
43#include <QHash>
44#include "diagramscene.h"
45
46DiagramScene::DiagramScene(QMenu *itemMenu, MainWindow *ownerWindow,
47                           QObject *parent)
48    : QGraphicsScene(parent)
49{
50    myOwnerWindow = ownerWindow;
51    myItemMenu = itemMenu;
52    myMode = MoveItem;
53
54    line = 0;
55    textItem = 0;
56    myItemColor = Qt::white;
57    myTextColor = Qt::black;
58    myLineColor = Qt::black;
59    snapToGrid=1;
60    myGrid=10;
61    myPolygonPath=0;
62    myCorners=0;
63
64    TitleText = new DiagramTextItem(0,0,1,0xFFF,255,"BLOCK NAME HERE not visible",
65                                    QPointF(500,420));
66    TitleText->setZValue(1000);
67    addItem(TitleText);
68
69}
70
71void DiagramScene::drawBackground(QPainter *p, const QRectF &r)
72{
73    p -> save();
74    
75    p -> setRenderHint(QPainter::Antialiasing, false);
76    p -> setRenderHint(QPainter::TextAntialiasing, true);
77    p -> setRenderHint(QPainter::SmoothPixmapTransform, false);
78        
79    p -> setPen(Qt::NoPen);
80    p -> setBrush(Qt::white);
81    p -> drawRect(r);
82    
83
84        p -> setPen(Qt::gray);
85        p -> setBrush(Qt::NoBrush);
86        qreal limite_x = r.x() + r.width();
87        qreal limite_y = r.y() + r.height();
88        
89        int g_x = (int)ceil(r.x());
90        while (g_x % myGrid) ++ g_x;
91        int g_y = (int)ceil(r.y());
92        while (g_y % myGrid) ++ g_y;
93        
94        QPolygon points;
95        for (int gx = g_x ; gx < limite_x ; gx += myGrid) {
96            for (int gy = g_y ; gy < limite_y ; gy += myGrid) {
97                points << QPoint(gx, gy);
98            }
99        }
100        p -> drawPoints(points);
101
102    p->drawLine(500,0,500,1000);
103    p->drawLine(0,500,1000,500);
104
105    p -> restore();
106}
107
108void DiagramScene::doSnapToGrid(QGraphicsSceneMouseEvent *mouseEvent)
109{
110    if(snapToGrid){
111        mouseEvent->setScenePos(QPointF(
112                                round(mouseEvent->scenePos().x()/myGrid)*myGrid,
113                                round(mouseEvent->scenePos().y()/myGrid)*myGrid
114                                ));
115    }
116}
117
118QString DiagramScene::createPrototype()
119{
120    bool first = 1;
121    QString functionPrototype = "\nvoid " +
122                                TitleText->toPlainText().replace(' ','_') + "(";
123
124    foreach (QGraphicsItem *item, this->items()) {
125        if (item->type() == DiagramTextItem::Type) {
126            int styleIO = qgraphicsitem_cast<DiagramTextItem*>(item)->styleIO();
127            if(styleIO<256)
128            {
129              int ioID = qgraphicsitem_cast<DiagramTextItem*>(item)->textID();
130              if(!first) functionPrototype += ","; first = 0;
131              switch(styleIO&127)
132              {
133                  case 1:
134                      functionPrototype += "bool ";
135                      break;
136                  case 2:
137                      functionPrototype += "char ";
138                      break;
139                  case 3:
140                      functionPrototype += "int ";
141                      break;
142                  case 4:
143                      functionPrototype += "double ";
144                      break;
145                  case 5:
146                      functionPrototype += "float ";
147                      break;
148                  case 6:
149                      functionPrototype += "short int ";
150                      break;
151                  case 7:
152                      functionPrototype += "long int ";
153                      break;
154                  case 8:
155                      functionPrototype += "unsigned char ";
156                      break;
157                  case 9:
158                      functionPrototype += "unsigned integer ";
159                      break;
160                  case 10:
161                      functionPrototype += "unsigned short int ";
162                      break;
163                  case 11:
164                      functionPrototype += "unsigned long int ";
165                      break;
166                  default:;
167              }
168              functionPrototype += (styleIO>>7)? "in":"&out";
169              functionPrototype += "_" + QString::number(ioID);
170            }
171        }
172    }
173
174    functionPrototype += ") {";
175    return functionPrototype;
176}
177
178void DiagramScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
179{
180    doSnapToGrid(mouseEvent);
181    myOwnerWindow->updateProt();
182
183    QString Text;
184    if (mouseEvent->button() != Qt::LeftButton)
185        return;
186
187    int addResult=0;
188
189    switch (myMode)
190    {
191        case InsertText:
192            //TODO: limit text items to 255 maximum
193            if(myTextType<256)
194                if(myTextType & 0b10000000)
195                    Text = "IN " +myTypeString;
196                else
197                    Text = "OUT " +myTypeString;
198            else
199                Text = myTypeString;
200
201            textItem = new DiagramTextItem(0,0,1,myTextType,0,Text,
202                                           mouseEvent->scenePos());
203            addResult=addTextItem(textItem);
204            if(addResult!=-1)
205            {
206                textItem->setZValue(1000.0);
207                addItem(textItem);
208                textItem->setTextID(addResult);
209            }
210            else
211            {
212                delete(textItem);
213                QMessageBox::warning(0,"Full","The block can only have "
214                                     "255 labels/IOs.");
215            }
216            emit textInserted(textItem);
217            break;
218        case EditPolygon:
219            if(line == 0 && items().indexOf(myPolygonPath)==-1)
220            {
221                line = new QGraphicsLineItem(QLineF(mouseEvent->scenePos(),
222                                            mouseEvent->scenePos()));
223                line->setPen(QPen(Qt::blue, 2));
224                line->setZValue(1000.0);
225                addItem(line);
226            }
227            else if(line != 0 && items().indexOf(myPolygonPath)==-1 &&
228                    line->line().length()>5)
229            {
230                myPolygonPath = new Arrow(line->line().p1(),line->line().p2(),
231                                          0,this);
232                QLineF newLine(line->line().p2(),line->line().p2());
233                line->setLine(newLine);
234            }
235            else if(line != 0 && items().indexOf(myPolygonPath)!=-1 &&
236                    line->line().length()>5)
237            {
238                myPolygonPath->createCorner(line->line().p1(),myCorners);
239                myPolygonPath->setEndPoint(line->line().p2());
240                myPolygonPath->updatePosition();
241                QLineF newLine(line->line().p2(),line->line().p2());
242                line->setLine(newLine);
243
244                myCorners++;
245            }
246
247        case MoveItem:
248            QGraphicsScene::mousePressEvent(mouseEvent);
249            break;
250        default: ;
251    }
252
253}
254
255void DiagramScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
256{
257    doSnapToGrid(mouseEvent);
258    if (myMode == EditPolygon && line != 0 )
259    {
260        QLineF newLine(line->line().p1(), mouseEvent->scenePos());
261        line->setLine(newLine);
262    }
263    QGraphicsScene::mouseMoveEvent(mouseEvent);
264    QPointF mousePos = mouseEvent->scenePos();
265    mousePos.setX(mousePos.x()-500);
266    mousePos.setY(-(mousePos.y()-500));
267
268    QString barMesg= QString("X[%1] Y[%2]").arg(QString::number(mousePos.x()))
269                                           .arg(QString::number(mousePos.y()));
270
271    foreach (QGraphicsItem *item, this->items(mouseEvent->scenePos())) {
272        if (item->type() == DiagramTextItem::Type) {
273            if(qgraphicsitem_cast<DiagramTextItem *>(item)->styleIO()<256)
274            {
275                barMesg +=
276                    tr(" ** Over In/Out text label with {ID = ") +
277                    QString::number(qgraphicsitem_cast<DiagramTextItem *>
278                              (item)->textID()) + tr("}");
279            }
280            else if(qgraphicsitem_cast<DiagramTextItem *>(item)->styleIO()==256)
281            {
282                barMesg +=
283                    tr(" ** Over text label with {ID = ") +
284                    QString::number(qgraphicsitem_cast<DiagramTextItem *>
285                              (item)->textID()) + tr("}");
286            }
287            else if(qgraphicsitem_cast<DiagramTextItem *>(item)->styleIO()==257)
288            {
289                barMesg +=
290                    tr(" ** Over editable text label with {ID = ") +
291                    QString::number(qgraphicsitem_cast<DiagramTextItem *>
292                              (item)->textID()) + tr("}");
293            }
294        }
295    }
296    myOwnerWindow->statusBar->showMessage(barMesg);
297
298}
299
300void DiagramScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *mouseEvent)
301{
302    doSnapToGrid(mouseEvent);
303    if (myMode == EditPolygon && line != 0 && myCorners>0)
304    {
305        if(myPolygonPath->getStartPoint()!=line->line().p2())
306            myPolygonPath->createCorner(line->line().p2(),myCorners);
307
308        myPolygonPath->setEndPoint(myPolygonPath->getStartPoint());
309        myPolygonPath->createFirstCorner();
310        myPolygonPath->updatePosition();
311        myCorners=0;
312        removeItem(line);
313        line = 0;
314        myMode = MoveItem;
315        emit textInserted(textItem);//Is the same for all buttons
316    }
317    else if (myMode != EditPolygon)
318    {
319       QGraphicsScene::mouseDoubleClickEvent(mouseEvent);
320    }
321}
322
323void DiagramScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
324{
325    doSnapToGrid(mouseEvent);
326   if(myMode != EditPolygon && line == 0)
327        QGraphicsScene::mouseReleaseEvent(mouseEvent);
328}
329
330bool DiagramScene::isItemChange(int type)
331{
332    foreach (QGraphicsItem *item, selectedItems()) {
333        if (item->type() == type)
334            return true;
335    }
336    return false;
337}
338
339QDomDocument DiagramScene::toXmlFormat()
340{
341    QDomDocument document;
342    QDomComment initialComments=document.createComment(
343        "File for SIE Code Generator. Custmos Blocks");
344    document.appendChild(initialComments);
345
346    QDomElement diagram = document.createElement("CustomItem");
347    diagram.setAttribute("BlockName",TitleText->toPlainText());
348    document.appendChild(diagram);
349
350    //Lists of items
351    QList<DiagramTextItem *> Items;
352    QList<Arrow *> Arrows;
353    foreach(QGraphicsItem *item, items())
354    {
355        if(item->type() == DiagramTextItem::Type)
356            Items.append(qgraphicsitem_cast<DiagramTextItem *>(item));
357        else if(item->type() == Arrow::Type)
358            Arrows.append(qgraphicsitem_cast<Arrow *>(item));
359    }
360
361    if(Arrows.count()>1) {printf("Something is wrong.\n"); fflush(stdout);}
362
363    //Create the XML structure
364    if(myPolygonPath!=0)
365        diagram.appendChild(myPolygonPath->toXml(document));
366
367    QDomElement element;
368    if(Items.count()>0)
369    {
370        QDomElement textItems = document.createElement("TextItems");
371        foreach(DiagramTextItem *item, Items)
372        {
373            if(item->styleIO() != 0xFFF)
374            {
375                element = item->toXml(document);
376                element.setAttribute("ID",textItemsByID.key(item));
377                textItems.appendChild(element);
378            }
379        }
380        diagram.appendChild(textItems);
381    }
382
383
384    //Add the code as CDATA sections
385    //Order: Header Code, Init Code, Block Code and Extra Code.
386
387    QDomCDATASection headerCode=document.createCDATASection(
388            myOwnerWindow->headerTextEdit->toPlainText());
389    diagram.appendChild(headerCode);
390
391    QDomCDATASection initCode=document.createCDATASection(
392            myOwnerWindow->initTextEdit->toPlainText());
393    diagram.appendChild(initCode);
394
395    QDomCDATASection blockCode=document.createCDATASection(
396            myOwnerWindow->blockTextEdit->toPlainText());
397    diagram.appendChild(blockCode);
398
399    QDomCDATASection extraCode=document.createCDATASection(
400            myOwnerWindow->extraTextEdit->toPlainText());
401    diagram.appendChild(extraCode);
402
403    return(document);
404}
405
406int DiagramScene::fromXmlFormat(QDomDocument document)
407{
408    //Read items TODO: in future... add multi items on same file
409    QDomNodeList customsItems = document.elementsByTagName("CustomItem");
410    if(!customsItems.at(0).isElement())
411        return -1;
412    //Load the first item in the document
413    QDomElement customItem = customsItems.at(0).toElement();
414    if(customItem.attribute("BlockName")=="")
415        TitleText->setPlainText("Please set Block Name");
416    else
417        TitleText->setPlainText(customItem.attribute("BlockName"));
418
419    TitleText->updatePosition();
420    int codeIdx = 0;
421
422    for (QDomNode node = customItem.firstChild() ;
423         !node.isNull() ;
424         node = node.nextSibling())
425    {
426      if(node.isCDATASection())
427      {
428          QDomCDATASection Code = node.toCDATASection();
429          switch(codeIdx)
430          {
431            case 0:
432                myOwnerWindow->headerTextEdit->setPlainText(Code.data());
433                break;
434            case 1:
435                myOwnerWindow->initTextEdit->setPlainText(Code.data());
436                break;
437            case 2:
438                myOwnerWindow->blockTextEdit->setPlainText(Code.data());
439                break;
440            case 3:
441                myOwnerWindow->extraTextEdit->setPlainText(Code.data());
442                break;
443            default:
444                QMessageBox::warning(0,"Parsing XML", tr("Extra CDATA found in")
445                                   +tr(" file, this section will be ignored."));
446          }
447          codeIdx++;
448      }
449      else
450      {
451        QDomElement element = node.toElement();
452        if(element.tagName()=="Polygon")
453        {
454            QList<QPointF> points;
455            for (QDomNode node = element.firstChild() ;
456                             !node.isNull() ;
457                             node = node.nextSibling())
458            {
459                QDomElement point = node.toElement();
460                if(point.tagName()!="Point")
461                    return -1;
462                points.append(QPointF((QPointF(point.attribute("x").toFloat(),0)
463                                              +QPointF(500,500)).x(),
464                                     (QPointF(0,point.attribute("y").toFloat())
465                                              +QPointF(500,500)).y()));
466            }
467
468            if(points.count()>0)
469            {
470                myPolygonPath = new Arrow(points.at(0),points.at(0),0,this);
471                for(int i=1; i< points.count();i++)
472                {
473                     myPolygonPath->createCorner(points.at(i),i-1);
474                }
475                myPolygonPath->createFirstCorner();
476                myPolygonPath->updatePosition();
477            }
478        }
479        else if(element.tagName()=="TextItems")
480        {
481            for (QDomNode node = element.firstChild() ;
482                             !node.isNull() ;
483                             node = node.nextSibling())
484            {
485                QDomElement textItemE = node.toElement();
486                if(textItemE.tagName()!="TextItem")
487                    return -1;
488
489                int myStyleIO = textItemE.attribute("myStyleIO").toInt();
490                int myID = textItemE.attribute("ID").toInt();
491
492                bool editableItem = textItemE.attribute("editableItem").toInt();
493                QPointF posOffset=
494                        QPointF((QPointF(textItemE.attribute("posOffset-x")
495                                         .toFloat(),0)+QPointF(500,500)).x(),
496                               (-QPointF(0,textItemE.attribute("posOffset-y")
497                                         .toFloat())+QPointF(500,500)).y());
498                QString itemString=textItemE.attribute("text");
499
500                if(myStyleIO==0)
501                {
502                    if(!editableItem)
503                        myStyleIO=256;
504                    else
505                        myStyleIO=257;
506                }
507
508                DiagramTextItem * newTextItem =
509                 new DiagramTextItem(0,0,1,myStyleIO,myID,itemString,posOffset);
510                newTextItem->setZValue(1000.0);
511                addItem(newTextItem);
512
513                if(textItemsByID.find(myID)!=textItemsByID.end())
514                {
515                    int result=addTextItem(newTextItem);
516                    QMessageBox::warning(0,"ID Problems",
517                        tr("Label with ID[")+QString::number(myID)+
518                        tr("] already exists, this will be reasigned to [")+
519                        QString::number(result)+
520                        tr("] for prevent problems."));
521                    newTextItem->setTextID(result);
522                }
523                else
524                    textItemsByID.insert(myID,newTextItem);
525            }
526        }
527      }
528    }
529    myOwnerWindow->updateProt();
530    return 1;
531}
532
533void DiagramScene::cleanScene()
534{
535    //Lists of items
536    QList<DiagramTextItem *> Items;
537    foreach(QGraphicsItem *item, items())
538    {
539        if(item->type() == DiagramTextItem::Type)
540            Items.append(qgraphicsitem_cast<DiagramTextItem *>(item));
541    }
542    //Remove Diagram Text Items
543    foreach(DiagramTextItem *item, Items)
544    {
545        if(item->styleIO() != 0xFFF)
546        {
547            removeItem(item);
548            delete(item);
549        }
550    }
551    //Remove Polygon Path
552    if(items().indexOf(myPolygonPath)!=-1)
553    {
554        myPolygonPath->removeLines();
555        removeItem(myPolygonPath);
556        delete(myPolygonPath);
557    }
558    TitleText->setPlainText("BLOCK NAME HERE not visible");
559    TitleText->updatePosition();
560    this->addItem(TitleText);
561    textItemsByID.clear();
562}
563
564int DiagramScene::addTextItem(DiagramTextItem * textItem)
565{
566    for(int i=0; i<256; i++)
567    {
568        QHash<int,DiagramTextItem *>::iterator iter= textItemsByID.find(i);
569        if(iter==textItemsByID.end())
570        {
571            textItemsByID.insert(i,textItem);
572            return i;
573        }
574    }
575    return -1;
576}
577
578void DiagramScene::removeTextItem(DiagramTextItem * textItem)
579{
580    textItemsByID.remove(textItemsByID.key(textItem));
581}
582

Archive Download this file

Branches:
master



interactive