Hardware Design: SIE
Sign in or create your account | Project List | Help
Hardware Design: SIE Git Source Tree
Root/
Source at commit 9d578912b727722b22319832985451a79ec35747 created 13 years 27 days ago. By Juan64Bits, Updating prototype of SIE code generator. | |
---|---|
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 | |
46 | DiagramScene::DiagramScene(QMenu *itemMenu, QObject *parent) |
47 | : QGraphicsScene(parent) |
48 | { |
49 | myItemMenu = itemMenu; |
50 | myMode = MoveItem; |
51 | |
52 | line = 0; |
53 | textItem = 0; |
54 | myItemColor = Qt::white; |
55 | myTextColor = Qt::black; |
56 | myLineColor = Qt::black; |
57 | snapToGrid=1; |
58 | myGrid=10; |
59 | myPolygonPath=0; |
60 | myCorners=0; |
61 | |
62 | TitleText = new DiagramTextItem(0,0,1,0xFFF,255,"BLOCK NAME HERE (not visible)", |
63 | QPointF(250,250)); |
64 | addItem(TitleText); |
65 | |
66 | } |
67 | |
68 | void DiagramScene::editorLostFocus(DiagramTextItem *item) |
69 | { |
70 | QTextCursor cursor = item->textCursor(); |
71 | cursor.clearSelection(); |
72 | item->setTextCursor(cursor); |
73 | |
74 | if (item->toPlainText().isEmpty()) { |
75 | removeItem(item); |
76 | item->deleteLater(); |
77 | } |
78 | } |
79 | |
80 | void DiagramScene::drawBackground(QPainter *p, const QRectF &r) |
81 | { |
82 | p -> save(); |
83 | |
84 | p -> setRenderHint(QPainter::Antialiasing, false); |
85 | p -> setRenderHint(QPainter::TextAntialiasing, true); |
86 | p -> setRenderHint(QPainter::SmoothPixmapTransform, false); |
87 | |
88 | p -> setPen(Qt::NoPen); |
89 | p -> setBrush(Qt::white); |
90 | p -> drawRect(r); |
91 | |
92 | |
93 | p -> setPen(Qt::gray); |
94 | p -> setBrush(Qt::NoBrush); |
95 | qreal limite_x = r.x() + r.width(); |
96 | qreal limite_y = r.y() + r.height(); |
97 | |
98 | int g_x = (int)ceil(r.x()); |
99 | while (g_x % myGrid) ++ g_x; |
100 | int g_y = (int)ceil(r.y()); |
101 | while (g_y % myGrid) ++ g_y; |
102 | |
103 | QPolygon points; |
104 | for (int gx = g_x ; gx < limite_x ; gx += myGrid) { |
105 | for (int gy = g_y ; gy < limite_y ; gy += myGrid) { |
106 | points << QPoint(gx, gy); |
107 | } |
108 | } |
109 | p -> drawPoints(points); |
110 | |
111 | p->drawLine(500,0,500,1000); |
112 | p->drawLine(0,500,1000,500); |
113 | |
114 | p -> restore(); |
115 | } |
116 | |
117 | void DiagramScene::doSnapToGrid(QGraphicsSceneMouseEvent *mouseEvent) |
118 | { |
119 | if(snapToGrid){ |
120 | mouseEvent->setScenePos(QPointF( |
121 | round(mouseEvent->scenePos().x()/myGrid)*myGrid, |
122 | round(mouseEvent->scenePos().y()/myGrid)*myGrid |
123 | )); |
124 | } |
125 | } |
126 | |
127 | void DiagramScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) |
128 | { |
129 | doSnapToGrid(mouseEvent); |
130 | QString Text; |
131 | |
132 | if (mouseEvent->button() != Qt::LeftButton) |
133 | return; |
134 | |
135 | switch (myMode) |
136 | { |
137 | case InsertText: |
138 | //TODO: limit text items to 255 maximum |
139 | if(myTextType<256) |
140 | if(myTextType & 0b10000000) |
141 | Text = "IN " +myTypeString; |
142 | else |
143 | Text = "OUT " +myTypeString; |
144 | else |
145 | Text = myTypeString; |
146 | |
147 | textItem = new DiagramTextItem(0,0,1,myTextType,0,Text, |
148 | mouseEvent->scenePos()); |
149 | if(addTextItem(textItem)) |
150 | { |
151 | textItem->setZValue(1000.0); |
152 | connect(textItem, SIGNAL(lostFocus(DiagramTextItem*)), |
153 | this, SLOT(editorLostFocus(DiagramTextItem*))); |
154 | addItem(textItem); |
155 | } |
156 | else |
157 | { |
158 | delete(textItem); |
159 | QMessageBox::warning(0,"Full","The block can only have only" |
160 | "255 text items"); |
161 | } |
162 | emit textInserted(textItem); |
163 | break; |
164 | case EditPolygon: |
165 | if(line == 0 && items().indexOf(myPolygonPath)==-1) |
166 | { |
167 | line = new QGraphicsLineItem(QLineF(mouseEvent->scenePos(), |
168 | mouseEvent->scenePos())); |
169 | line->setPen(QPen(Qt::blue, 2)); |
170 | line->setZValue(1000.0); |
171 | addItem(line); |
172 | } |
173 | else if(line != 0 && items().indexOf(myPolygonPath)==-1 && |
174 | line->line().length()>5) |
175 | { |
176 | myPolygonPath = new Arrow(line->line().p1(),line->line().p2(), |
177 | 0,this); |
178 | QLineF newLine(line->line().p2(),line->line().p2()); |
179 | line->setLine(newLine); |
180 | } |
181 | else if(line != 0 && items().indexOf(myPolygonPath)!=-1 && |
182 | line->line().length()>5) |
183 | { |
184 | myPolygonPath->createCorner(line->line().p1(),myCorners); |
185 | myPolygonPath->setEndPoint(line->line().p2()); |
186 | myPolygonPath->updatePosition(); |
187 | QLineF newLine(line->line().p2(),line->line().p2()); |
188 | line->setLine(newLine); |
189 | |
190 | myCorners++; |
191 | } |
192 | |
193 | case MoveItem: |
194 | QGraphicsScene::mousePressEvent(mouseEvent); |
195 | break; |
196 | default: ; |
197 | } |
198 | |
199 | } |
200 | |
201 | void DiagramScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) |
202 | { |
203 | doSnapToGrid(mouseEvent); |
204 | if (myMode == EditPolygon && line != 0 ) |
205 | { |
206 | QLineF newLine(line->line().p1(), mouseEvent->scenePos()); |
207 | line->setLine(newLine); |
208 | } |
209 | |
210 | QGraphicsScene::mouseMoveEvent(mouseEvent); |
211 | |
212 | } |
213 | |
214 | void DiagramScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *mouseEvent) |
215 | { |
216 | doSnapToGrid(mouseEvent); |
217 | if (myMode == EditPolygon && line != 0 && myCorners>0) |
218 | { |
219 | if(myPolygonPath->getStartPoint()!=line->line().p2()) |
220 | myPolygonPath->createCorner(line->line().p2(),myCorners); |
221 | |
222 | myPolygonPath->setEndPoint(myPolygonPath->getStartPoint()); |
223 | myPolygonPath->createFirstCorner(); |
224 | myPolygonPath->updatePosition(); |
225 | myCorners=0; |
226 | removeItem(line); |
227 | line = 0; |
228 | myMode = MoveItem; |
229 | emit textInserted(textItem);//Is the same for all buttons |
230 | } |
231 | else if (myMode != EditPolygon) |
232 | { |
233 | QGraphicsScene::mouseDoubleClickEvent(mouseEvent); |
234 | } |
235 | } |
236 | |
237 | void DiagramScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) |
238 | { |
239 | doSnapToGrid(mouseEvent); |
240 | if (myMode != EditPolygon && line == 0) |
241 | QGraphicsScene::mouseReleaseEvent(mouseEvent); |
242 | } |
243 | |
244 | bool DiagramScene::isItemChange(int type) |
245 | { |
246 | foreach (QGraphicsItem *item, selectedItems()) { |
247 | if (item->type() == type) |
248 | return true; |
249 | } |
250 | return false; |
251 | } |
252 | |
253 | QDomDocument DiagramScene::toXmlFormat() |
254 | { |
255 | QDomDocument document; |
256 | QDomComment initialComments=document.createComment( |
257 | "File for SIE Code Generator. Custmos Blocks"); |
258 | document.appendChild(initialComments); |
259 | QDomElement diagram = document.createElement("CustomItem"); |
260 | diagram.setAttribute("BlockName",TitleText->toPlainText()); |
261 | document.appendChild(diagram); |
262 | //Lists of items |
263 | QList<DiagramTextItem *> Items; |
264 | QList<Arrow *> Arrows; |
265 | foreach(QGraphicsItem *item, items()) |
266 | { |
267 | if(item->type() == DiagramTextItem::Type) |
268 | Items.append(qgraphicsitem_cast<DiagramTextItem *>(item)); |
269 | else if(item->type() == Arrow::Type) |
270 | Arrows.append(qgraphicsitem_cast<Arrow *>(item)); |
271 | } |
272 | |
273 | if(Arrows.count()>1) {printf("Something is wrong.\n"); fflush(stdout);} |
274 | |
275 | //Create the XML structure |
276 | diagram.appendChild(myPolygonPath->toXml(document)); |
277 | |
278 | QDomElement element; |
279 | if(Items.count()>0) |
280 | { |
281 | QDomElement textItems = document.createElement("TextItems"); |
282 | foreach(DiagramTextItem *item, Items) |
283 | { |
284 | if(item->styleIO() != 0xFFF) |
285 | { |
286 | element = item->toXml(document); |
287 | element.setAttribute("ID",textItemsByID.key(item)); |
288 | textItems.appendChild(element); |
289 | } |
290 | } |
291 | diagram.appendChild(textItems); |
292 | } |
293 | |
294 | return(document); |
295 | } |
296 | |
297 | int DiagramScene::fromXmlFormat(QDomDocument document) |
298 | { |
299 | //Read items TODO: in future... add multi items on same file |
300 | QDomNodeList customsItems = document.elementsByTagName("CustomItem"); |
301 | if(!customsItems.at(0).isElement()) |
302 | return -1; |
303 | //Load the first item in the document |
304 | QDomElement customItem = customsItems.at(0).toElement(); |
305 | if(customItem.attribute("BlockName")=="") |
306 | TitleText->setPlainText("Please set Block Name"); |
307 | else |
308 | TitleText->setPlainText(customItem.attribute("BlockName")); |
309 | TitleText->updatePosition(); |
310 | for (QDomNode node = customItem.firstChild() ; |
311 | !node.isNull() ; |
312 | node = node.nextSibling()) |
313 | { |
314 | QDomElement element = node.toElement(); |
315 | if(element.tagName()=="Polygon") |
316 | { |
317 | QList<QPointF> points; |
318 | for (QDomNode node = element.firstChild() ; |
319 | !node.isNull() ; |
320 | node = node.nextSibling()) |
321 | { |
322 | QDomElement point = node.toElement(); |
323 | if(point.tagName()!="Point") |
324 | return -1; |
325 | points.append(QPointF((QPointF(point.attribute("x").toFloat(),0) |
326 | +QPointF(500,500)).x(), |
327 | (QPointF(0,point.attribute("y").toFloat()) |
328 | +QPointF(500,500)).y())); |
329 | } |
330 | |
331 | if(points.count()>0) |
332 | { |
333 | myPolygonPath = new Arrow(points.at(0),points.at(0),0,this); |
334 | for(int i=1; i< points.count();i++) |
335 | { |
336 | myPolygonPath->createCorner(points.at(i),i-1); |
337 | } |
338 | myPolygonPath->createFirstCorner(); |
339 | myPolygonPath->updatePosition(); |
340 | } |
341 | } |
342 | else if(element.tagName()=="TextItems") |
343 | { |
344 | for (QDomNode node = element.firstChild() ; |
345 | !node.isNull() ; |
346 | node = node.nextSibling()) |
347 | { |
348 | QDomElement textItemE = node.toElement(); |
349 | if(textItemE.tagName()!="TextItem") |
350 | return -1; |
351 | |
352 | int myStyleIO = textItemE.attribute("myStyleIO").toInt(); |
353 | int myID = textItemE.attribute("ID").toInt(); |
354 | bool editableItem = textItemE.attribute("editableItem").toInt(); |
355 | QPointF posOffset= |
356 | QPointF((QPointF(textItemE.attribute("posOffset-x") |
357 | .toFloat(),0)+QPointF(500,500)).x(), |
358 | (-QPointF(0,textItemE.attribute("posOffset-y") |
359 | .toFloat())+QPointF(500,500)).y()); |
360 | QString itemString=textItemE.attribute("text"); |
361 | |
362 | if(myStyleIO==0) |
363 | { |
364 | if(!editableItem) |
365 | myStyleIO=256; |
366 | else |
367 | myStyleIO=257; |
368 | } |
369 | |
370 | DiagramTextItem * newTextItem = |
371 | new DiagramTextItem(0,0,1,myStyleIO,myID,itemString,posOffset); |
372 | newTextItem->setZValue(1000.0); |
373 | connect(newTextItem, SIGNAL(lostFocus(DiagramTextItem*)), |
374 | this, SLOT(editorLostFocus(DiagramTextItem*))); |
375 | addItem(newTextItem); |
376 | textItemsByID.insert(myID,newTextItem); |
377 | } |
378 | } |
379 | } |
380 | |
381 | return 1; |
382 | } |
383 | |
384 | void DiagramScene::cleanScene() |
385 | { |
386 | //Lists of items |
387 | QList<DiagramTextItem *> Items; |
388 | foreach(QGraphicsItem *item, items()) |
389 | { |
390 | if(item->type() == DiagramTextItem::Type) |
391 | Items.append(qgraphicsitem_cast<DiagramTextItem *>(item)); |
392 | } |
393 | //Remove Diagram Text Items |
394 | foreach(DiagramTextItem *item, Items) |
395 | { |
396 | if(item->styleIO() != 0xFFF) |
397 | { |
398 | removeItem(item); |
399 | delete(item); |
400 | } |
401 | } |
402 | //Remove Polygon Path |
403 | if(items().indexOf(myPolygonPath)!=-1) |
404 | { |
405 | myPolygonPath->removeLines(); |
406 | removeItem(myPolygonPath); |
407 | delete(myPolygonPath); |
408 | } |
409 | TitleText->setPlainText("BLOCK NAME HERE (not visible)"); |
410 | TitleText->updatePosition(); |
411 | } |
412 | |
413 | int DiagramScene::addTextItem(DiagramTextItem * textItem) |
414 | { |
415 | for(int i=0; i<255; i++) |
416 | { |
417 | QHash<int,DiagramTextItem *>::iterator iter= textItemsByID.find(i); |
418 | if(iter==textItemsByID.end()) |
419 | { |
420 | textItemsByID.insert(i,textItem); |
421 | return 1; |
422 | } |
423 | } |
424 | return 0; |
425 | } |
426 | |
427 | void DiagramScene::removeTextItem(DiagramTextItem * textItem) |
428 | { |
429 | textItemsByID.remove(textItemsByID.key(textItem)); |
430 | } |
431 |
Branches:
master