/**************************************************************************** ** ** 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:LGPL$ ** Commercial Usage ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Commercial License Agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Nokia. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include #include "diagramscene.h" DiagramScene::DiagramScene(QMenu *itemMenu, QObject *parent) : QGraphicsScene(parent) { myItemMenu = itemMenu; myMode = MoveItem; line = 0; textItem = 0; myItemColor = Qt::white; myTextColor = Qt::black; myLineColor = Qt::black; snapToGrid=1; myGrid=10; myPolygonPath=0; myCorners=0; TitleText = new DiagramTextItem(0,0,1,0xFFF,255,"BLOCK NAME HERE (not visible)", QPointF(250,250)); addItem(TitleText); } void DiagramScene::editorLostFocus(DiagramTextItem *item) { QTextCursor cursor = item->textCursor(); cursor.clearSelection(); item->setTextCursor(cursor); if (item->toPlainText().isEmpty()) { removeItem(item); item->deleteLater(); } } void DiagramScene::drawBackground(QPainter *p, const QRectF &r) { p -> save(); p -> setRenderHint(QPainter::Antialiasing, false); p -> setRenderHint(QPainter::TextAntialiasing, true); p -> setRenderHint(QPainter::SmoothPixmapTransform, false); p -> setPen(Qt::NoPen); p -> setBrush(Qt::white); p -> drawRect(r); p -> setPen(Qt::gray); p -> setBrush(Qt::NoBrush); qreal limite_x = r.x() + r.width(); qreal limite_y = r.y() + r.height(); int g_x = (int)ceil(r.x()); while (g_x % myGrid) ++ g_x; int g_y = (int)ceil(r.y()); while (g_y % myGrid) ++ g_y; QPolygon points; for (int gx = g_x ; gx < limite_x ; gx += myGrid) { for (int gy = g_y ; gy < limite_y ; gy += myGrid) { points << QPoint(gx, gy); } } p -> drawPoints(points); p->drawLine(500,0,500,1000); p->drawLine(0,500,1000,500); p -> restore(); } void DiagramScene::doSnapToGrid(QGraphicsSceneMouseEvent *mouseEvent) { if(snapToGrid){ mouseEvent->setScenePos(QPointF( int(mouseEvent->scenePos().x()/myGrid)*myGrid, int(mouseEvent->scenePos().y()/myGrid)*myGrid )); } } void DiagramScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) { doSnapToGrid(mouseEvent); QString Text; if (mouseEvent->button() != Qt::LeftButton) return; switch (myMode) { case InsertText: //TODO: limit text items to 255 maximum if(myTextType<256) if(myTextType & 0b10000000) Text = "IN " +myTypeString; else Text = "OUT " +myTypeString; else Text = myTypeString; textItem = new DiagramTextItem(0,0,1,myTextType,0,Text, mouseEvent->scenePos()); if(addTextItem(textItem)) { textItem->setZValue(1000.0); connect(textItem, SIGNAL(lostFocus(DiagramTextItem*)), this, SLOT(editorLostFocus(DiagramTextItem*))); addItem(textItem); } else { delete(textItem); QMessageBox::warning(0,"Full","The block can only have only" "255 text items"); } emit textInserted(textItem); break; case EditPolygon: if(line == 0 && items().indexOf(myPolygonPath)==-1) { line = new QGraphicsLineItem(QLineF(mouseEvent->scenePos(), mouseEvent->scenePos())); line->setPen(QPen(Qt::blue, 2)); line->setZValue(1000.0); addItem(line); } else if(line != 0 && items().indexOf(myPolygonPath)==-1 && line->line().length()>5) { myPolygonPath = new Arrow(line->line().p1(),line->line().p2(), 0,this); QLineF newLine(line->line().p2(),line->line().p2()); line->setLine(newLine); } else if(line != 0 && items().indexOf(myPolygonPath)!=-1 && line->line().length()>5) { myPolygonPath->createCorner(line->line().p1(),myCorners); myPolygonPath->setEndPoint(line->line().p2()); myPolygonPath->updatePosition(); QLineF newLine(line->line().p2(),line->line().p2()); line->setLine(newLine); myCorners++; } case MoveItem: QGraphicsScene::mousePressEvent(mouseEvent); break; default: ; } } void DiagramScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) { doSnapToGrid(mouseEvent); if (myMode == EditPolygon && line != 0 ) { QLineF newLine(line->line().p1(), mouseEvent->scenePos()); line->setLine(newLine); } QGraphicsScene::mouseMoveEvent(mouseEvent); } void DiagramScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *mouseEvent) { doSnapToGrid(mouseEvent); if (myMode == EditPolygon && line != 0 && myCorners>0) { if(myPolygonPath->getStartPoint()!=line->line().p2()) myPolygonPath->createCorner(line->line().p2(),myCorners); myPolygonPath->setEndPoint(myPolygonPath->getStartPoint()); myPolygonPath->createFirstCorner(); myPolygonPath->updatePosition(); myCorners=0; removeItem(line); line = 0; myMode = MoveItem; emit textInserted(textItem);//Is the same for all buttons } else if (myMode != EditPolygon) { QGraphicsScene::mouseDoubleClickEvent(mouseEvent); } } void DiagramScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) { doSnapToGrid(mouseEvent); if (myMode != EditPolygon && line == 0) QGraphicsScene::mouseReleaseEvent(mouseEvent); } bool DiagramScene::isItemChange(int type) { foreach (QGraphicsItem *item, selectedItems()) { if (item->type() == type) return true; } return false; } QDomDocument DiagramScene::toXmlFormat() { QDomDocument document; QDomComment initialComments=document.createComment( "File for SIE Code Generator. Custmos Blocks"); document.appendChild(initialComments); QDomElement diagram = document.createElement("CustomItem"); diagram.setAttribute("BlockName",TitleText->toPlainText()); document.appendChild(diagram); //Lists of items QList Items; QList Arrows; foreach(QGraphicsItem *item, items()) { if(item->type() == DiagramTextItem::Type) Items.append(qgraphicsitem_cast(item)); else if(item->type() == Arrow::Type) Arrows.append(qgraphicsitem_cast(item)); } if(Arrows.count()>1) {printf("Something is wrong.\n"); fflush(stdout);} //Create the XML structure diagram.appendChild(myPolygonPath->toXml(document)); QDomElement element; if(Items.count()>0) { QDomElement textItems = document.createElement("TextItems"); foreach(DiagramTextItem *item, Items) { if(item->styleIO() != 0xFFF) { element = item->toXml(document); element.setAttribute("ID",textItemsByID.key(item)); textItems.appendChild(element); } } diagram.appendChild(textItems); } return(document); } int DiagramScene::fromXmlFormat(QDomDocument document) { //Read items TODO: in future... add multi items on same file QDomNodeList customsItems = document.elementsByTagName("CustomItem"); if(!customsItems.at(0).isElement()) return -1; //Load the first item in the document QDomElement customItem = customsItems.at(0).toElement(); if(customItem.attribute("BlockName")=="") TitleText->setPlainText("Please set Block Name"); else TitleText->setPlainText(customItem.attribute("BlockName")); TitleText->updatePosition(); for (QDomNode node = customItem.firstChild() ; !node.isNull() ; node = node.nextSibling()) { QDomElement element = node.toElement(); if(element.tagName()=="Polygon") { QList points; for (QDomNode node = element.firstChild() ; !node.isNull() ; node = node.nextSibling()) { QDomElement point = node.toElement(); if(point.tagName()!="Point") return -1; points.append(QPointF((QPointF(point.attribute("x").toFloat(),0) +QPointF(500,500)).x(), (QPointF(0,point.attribute("y").toFloat()) +QPointF(500,500)).y())); } if(points.count()>0) { myPolygonPath = new Arrow(points.at(0),points.at(0),0,this); for(int i=1; i< points.count();i++) { myPolygonPath->createCorner(points.at(i),i-1); } myPolygonPath->createFirstCorner(); myPolygonPath->updatePosition(); } } else if(element.tagName()=="TextItems") { for (QDomNode node = element.firstChild() ; !node.isNull() ; node = node.nextSibling()) { QDomElement textItemE = node.toElement(); if(textItemE.tagName()!="TextItem") return -1; int myStyleIO = textItemE.attribute("myStyleIO").toInt(); int myID = textItemE.attribute("ID").toInt(); bool editableItem = textItemE.attribute("editableItem").toInt(); QPointF posOffset= QPointF((QPointF(textItemE.attribute("posOffset-x") .toFloat(),0)+QPointF(500,500)).x(), (-QPointF(0,textItemE.attribute("posOffset-y") .toFloat())+QPointF(500,500)).y()); QString itemString=textItemE.attribute("text"); if(myStyleIO==0) { if(!editableItem) myStyleIO=256; else myStyleIO=257; } DiagramTextItem * newTextItem = new DiagramTextItem(0,0,1,myStyleIO,myID,itemString,posOffset); newTextItem->setZValue(1000.0); connect(newTextItem, SIGNAL(lostFocus(DiagramTextItem*)), this, SLOT(editorLostFocus(DiagramTextItem*))); addItem(newTextItem); textItemsByID.insert(myID,newTextItem); } } } return 1; } void DiagramScene::cleanScene() { //Lists of items QList Items; foreach(QGraphicsItem *item, items()) { if(item->type() == DiagramTextItem::Type) Items.append(qgraphicsitem_cast(item)); } //Remove Diagram Text Items foreach(DiagramTextItem *item, Items) { if(item->styleIO() != 0xFFF) { removeItem(item); delete(item); } } //Remove Polygon Path if(items().indexOf(myPolygonPath)!=-1) { myPolygonPath->removeLines(); removeItem(myPolygonPath); delete(myPolygonPath); } TitleText->setPlainText("BLOCK NAME HERE (not visible)"); TitleText->updatePosition(); } int DiagramScene::addTextItem(DiagramTextItem * textItem) { for(int i=0; i<255; i++) { QHash::iterator iter= textItemsByID.find(i); if(iter==textItemsByID.end()) { textItemsByID.insert(i,textItem); return 1; } } return 0; } void DiagramScene::removeTextItem(DiagramTextItem * textItem) { textItemsByID.remove(textItemsByID.key(textItem)); }