Hardware Design: SIE
Sign in or create your account | Project List | Help
Hardware Design: SIE Git Source Tree
Root/
Source at commit 2efe106cf30654a74ec979a00de820e2aca3021e created 13 years 4 months ago. By Juan64Bits, Adding bases to the code generator. Code text edit, fixing input/output ID control, etc. | |
---|---|
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, 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,370)); |
66 | addItem(TitleText); |
67 | |
68 | } |
69 | |
70 | void DiagramScene::editorLostFocus(DiagramTextItem *item) |
71 | { |
72 | QTextCursor cursor = item->textCursor(); |
73 | cursor.clearSelection(); |
74 | item->setTextCursor(cursor); |
75 | |
76 | if (item->toPlainText().isEmpty()) { |
77 | removeItem(item); |
78 | item->deleteLater(); |
79 | } |
80 | } |
81 | |
82 | void DiagramScene::drawBackground(QPainter *p, const QRectF &r) |
83 | { |
84 | p -> save(); |
85 | |
86 | p -> setRenderHint(QPainter::Antialiasing, false); |
87 | p -> setRenderHint(QPainter::TextAntialiasing, true); |
88 | p -> setRenderHint(QPainter::SmoothPixmapTransform, false); |
89 | |
90 | p -> setPen(Qt::NoPen); |
91 | p -> setBrush(Qt::white); |
92 | p -> drawRect(r); |
93 | |
94 | |
95 | p -> setPen(Qt::gray); |
96 | p -> setBrush(Qt::NoBrush); |
97 | qreal limite_x = r.x() + r.width(); |
98 | qreal limite_y = r.y() + r.height(); |
99 | |
100 | int g_x = (int)ceil(r.x()); |
101 | while (g_x % myGrid) ++ g_x; |
102 | int g_y = (int)ceil(r.y()); |
103 | while (g_y % myGrid) ++ g_y; |
104 | |
105 | QPolygon points; |
106 | for (int gx = g_x ; gx < limite_x ; gx += myGrid) { |
107 | for (int gy = g_y ; gy < limite_y ; gy += myGrid) { |
108 | points << QPoint(gx, gy); |
109 | } |
110 | } |
111 | p -> drawPoints(points); |
112 | |
113 | p->drawLine(500,0,500,1000); |
114 | p->drawLine(0,500,1000,500); |
115 | |
116 | p -> restore(); |
117 | } |
118 | |
119 | void DiagramScene::doSnapToGrid(QGraphicsSceneMouseEvent *mouseEvent) |
120 | { |
121 | if(snapToGrid){ |
122 | mouseEvent->setScenePos(QPointF( |
123 | round(mouseEvent->scenePos().x()/myGrid)*myGrid, |
124 | round(mouseEvent->scenePos().y()/myGrid)*myGrid |
125 | )); |
126 | } |
127 | } |
128 | |
129 | QString DiagramScene::createPrototype() |
130 | { |
131 | bool first = 1; |
132 | QString functionPrototype = "\nvoid " + |
133 | TitleText->toPlainText().replace(' ','_') + "("; |
134 | |
135 | foreach (QGraphicsItem *item, this->items()) { |
136 | if (item->type() == DiagramTextItem::Type) { |
137 | int styleIO = qgraphicsitem_cast<DiagramTextItem*>(item)->styleIO(); |
138 | if(styleIO<256) |
139 | { |
140 | int ioID = qgraphicsitem_cast<DiagramTextItem*>(item)->textID(); |
141 | if(!first) functionPrototype += ","; first = 0; |
142 | switch(styleIO&127) |
143 | { |
144 | case 1: |
145 | functionPrototype += "bool "; |
146 | break; |
147 | case 2: |
148 | functionPrototype += "char "; |
149 | break; |
150 | case 3: |
151 | functionPrototype += "integer "; |
152 | break; |
153 | case 4: |
154 | functionPrototype += "double "; |
155 | break; |
156 | case 5: |
157 | functionPrototype += "float "; |
158 | break; |
159 | case 6: |
160 | functionPrototype += "short "; |
161 | break; |
162 | case 7: |
163 | functionPrototype += "long "; |
164 | break; |
165 | case 8: |
166 | functionPrototype += "unsigned char "; |
167 | break; |
168 | case 9: |
169 | functionPrototype += "unsigned integer "; |
170 | break; |
171 | case 10: |
172 | functionPrototype += "unsigned short "; |
173 | break; |
174 | case 11: |
175 | functionPrototype += "unsigned long "; |
176 | break; |
177 | default:; |
178 | } |
179 | functionPrototype += (styleIO>>7)? "in":"&out"; |
180 | functionPrototype += "_" + QString::number(ioID); |
181 | } |
182 | } |
183 | } |
184 | |
185 | functionPrototype += ") {"; |
186 | return functionPrototype; |
187 | } |
188 | |
189 | void DiagramScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) |
190 | { |
191 | doSnapToGrid(mouseEvent); |
192 | foreach (QGraphicsItem *item, this->items(mouseEvent->scenePos())) { |
193 | if (item->type() == DiagramTextItem::Type) { |
194 | if(qgraphicsitem_cast<DiagramTextItem *>(item)->styleIO()<256) |
195 | { |
196 | myOwnerWindow->statusBar->showMessage( |
197 | qgraphicsitem_cast<DiagramTextItem *>(item)->toPlainText() + |
198 | tr("\t : Input/Output text label -> {ID = ") + |
199 | QString::number(qgraphicsitem_cast<DiagramTextItem *> |
200 | (item)->textID()) + tr("}")); |
201 | } |
202 | else if(qgraphicsitem_cast<DiagramTextItem *>(item)->styleIO()==256) |
203 | { |
204 | myOwnerWindow->statusBar->showMessage( |
205 | qgraphicsitem_cast<DiagramTextItem *>(item)->toPlainText() + |
206 | tr("\t : Text label -> {ID = ") + |
207 | QString::number(qgraphicsitem_cast<DiagramTextItem *> |
208 | (item)->textID()) + tr("}")); |
209 | } |
210 | else if(qgraphicsitem_cast<DiagramTextItem *>(item)->styleIO()==257) |
211 | { |
212 | myOwnerWindow->statusBar->showMessage( |
213 | qgraphicsitem_cast<DiagramTextItem *>(item)->toPlainText() + |
214 | tr("\t : Editable text label -> {ID = ") + |
215 | QString::number(qgraphicsitem_cast<DiagramTextItem *> |
216 | (item)->textID()) + tr("}")); |
217 | } |
218 | } |
219 | } |
220 | myOwnerWindow->updateProt(); |
221 | |
222 | QString Text; |
223 | if (mouseEvent->button() != Qt::LeftButton) |
224 | return; |
225 | |
226 | int addResult=0; |
227 | |
228 | switch (myMode) |
229 | { |
230 | case InsertText: |
231 | //TODO: limit text items to 255 maximum |
232 | if(myTextType<256) |
233 | if(myTextType & 0b10000000) |
234 | Text = "IN " +myTypeString; |
235 | else |
236 | Text = "OUT " +myTypeString; |
237 | else |
238 | Text = myTypeString; |
239 | |
240 | textItem = new DiagramTextItem(0,0,1,myTextType,0,Text, |
241 | mouseEvent->scenePos()); |
242 | addResult=addTextItem(textItem); |
243 | if(addResult!=-1) |
244 | { |
245 | textItem->setZValue(1000.0); |
246 | connect(textItem, SIGNAL(lostFocus(DiagramTextItem*)), |
247 | this, SLOT(editorLostFocus(DiagramTextItem*))); |
248 | addItem(textItem); |
249 | textItem->setTextID(addResult); |
250 | } |
251 | else |
252 | { |
253 | delete(textItem); |
254 | QMessageBox::warning(0,"Full","The block can only have " |
255 | "255 text items"); |
256 | } |
257 | emit textInserted(textItem); |
258 | break; |
259 | case EditPolygon: |
260 | if(line == 0 && items().indexOf(myPolygonPath)==-1) |
261 | { |
262 | line = new QGraphicsLineItem(QLineF(mouseEvent->scenePos(), |
263 | mouseEvent->scenePos())); |
264 | line->setPen(QPen(Qt::blue, 2)); |
265 | line->setZValue(1000.0); |
266 | addItem(line); |
267 | } |
268 | else if(line != 0 && items().indexOf(myPolygonPath)==-1 && |
269 | line->line().length()>5) |
270 | { |
271 | myPolygonPath = new Arrow(line->line().p1(),line->line().p2(), |
272 | 0,this); |
273 | QLineF newLine(line->line().p2(),line->line().p2()); |
274 | line->setLine(newLine); |
275 | } |
276 | else if(line != 0 && items().indexOf(myPolygonPath)!=-1 && |
277 | line->line().length()>5) |
278 | { |
279 | myPolygonPath->createCorner(line->line().p1(),myCorners); |
280 | myPolygonPath->setEndPoint(line->line().p2()); |
281 | myPolygonPath->updatePosition(); |
282 | QLineF newLine(line->line().p2(),line->line().p2()); |
283 | line->setLine(newLine); |
284 | |
285 | myCorners++; |
286 | } |
287 | |
288 | case MoveItem: |
289 | QGraphicsScene::mousePressEvent(mouseEvent); |
290 | break; |
291 | default: ; |
292 | } |
293 | |
294 | } |
295 | |
296 | void DiagramScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) |
297 | { |
298 | doSnapToGrid(mouseEvent); |
299 | if (myMode == EditPolygon && line != 0 ) |
300 | { |
301 | QLineF newLine(line->line().p1(), mouseEvent->scenePos()); |
302 | line->setLine(newLine); |
303 | } |
304 | |
305 | QGraphicsScene::mouseMoveEvent(mouseEvent); |
306 | |
307 | } |
308 | |
309 | void DiagramScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *mouseEvent) |
310 | { |
311 | doSnapToGrid(mouseEvent); |
312 | if (myMode == EditPolygon && line != 0 && myCorners>0) |
313 | { |
314 | if(myPolygonPath->getStartPoint()!=line->line().p2()) |
315 | myPolygonPath->createCorner(line->line().p2(),myCorners); |
316 | |
317 | myPolygonPath->setEndPoint(myPolygonPath->getStartPoint()); |
318 | myPolygonPath->createFirstCorner(); |
319 | myPolygonPath->updatePosition(); |
320 | myCorners=0; |
321 | removeItem(line); |
322 | line = 0; |
323 | myMode = MoveItem; |
324 | emit textInserted(textItem);//Is the same for all buttons |
325 | } |
326 | else if (myMode != EditPolygon) |
327 | { |
328 | QGraphicsScene::mouseDoubleClickEvent(mouseEvent); |
329 | } |
330 | } |
331 | |
332 | void DiagramScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) |
333 | { |
334 | doSnapToGrid(mouseEvent); |
335 | if(myMode != EditPolygon && line == 0) |
336 | QGraphicsScene::mouseReleaseEvent(mouseEvent); |
337 | } |
338 | |
339 | bool DiagramScene::isItemChange(int type) |
340 | { |
341 | foreach (QGraphicsItem *item, selectedItems()) { |
342 | if (item->type() == type) |
343 | return true; |
344 | } |
345 | return false; |
346 | } |
347 | |
348 | QDomDocument DiagramScene::toXmlFormat() |
349 | { |
350 | QDomDocument document; |
351 | QDomComment initialComments=document.createComment( |
352 | "File for SIE Code Generator. Custmos Blocks"); |
353 | document.appendChild(initialComments); |
354 | QDomElement diagram = document.createElement("CustomItem"); |
355 | diagram.setAttribute("BlockName",TitleText->toPlainText()); |
356 | document.appendChild(diagram); |
357 | //Lists of items |
358 | QList<DiagramTextItem *> Items; |
359 | QList<Arrow *> Arrows; |
360 | foreach(QGraphicsItem *item, items()) |
361 | { |
362 | if(item->type() == DiagramTextItem::Type) |
363 | Items.append(qgraphicsitem_cast<DiagramTextItem *>(item)); |
364 | else if(item->type() == Arrow::Type) |
365 | Arrows.append(qgraphicsitem_cast<Arrow *>(item)); |
366 | } |
367 | |
368 | if(Arrows.count()>1) {printf("Something is wrong.\n"); fflush(stdout);} |
369 | |
370 | //Create the XML structure |
371 | diagram.appendChild(myPolygonPath->toXml(document)); |
372 | |
373 | QDomElement element; |
374 | if(Items.count()>0) |
375 | { |
376 | QDomElement textItems = document.createElement("TextItems"); |
377 | foreach(DiagramTextItem *item, Items) |
378 | { |
379 | if(item->styleIO() != 0xFFF) |
380 | { |
381 | element = item->toXml(document); |
382 | element.setAttribute("ID",textItemsByID.key(item)); |
383 | textItems.appendChild(element); |
384 | } |
385 | } |
386 | diagram.appendChild(textItems); |
387 | } |
388 | |
389 | return(document); |
390 | } |
391 | |
392 | int DiagramScene::fromXmlFormat(QDomDocument document) |
393 | { |
394 | //Read items TODO: in future... add multi items on same file |
395 | QDomNodeList customsItems = document.elementsByTagName("CustomItem"); |
396 | if(!customsItems.at(0).isElement()) |
397 | return -1; |
398 | //Load the first item in the document |
399 | QDomElement customItem = customsItems.at(0).toElement(); |
400 | if(customItem.attribute("BlockName")=="") |
401 | TitleText->setPlainText("Please set Block Name"); |
402 | else |
403 | TitleText->setPlainText(customItem.attribute("BlockName")); |
404 | TitleText->updatePosition(); |
405 | for (QDomNode node = customItem.firstChild() ; |
406 | !node.isNull() ; |
407 | node = node.nextSibling()) |
408 | { |
409 | QDomElement element = node.toElement(); |
410 | if(element.tagName()=="Polygon") |
411 | { |
412 | QList<QPointF> points; |
413 | for (QDomNode node = element.firstChild() ; |
414 | !node.isNull() ; |
415 | node = node.nextSibling()) |
416 | { |
417 | QDomElement point = node.toElement(); |
418 | if(point.tagName()!="Point") |
419 | return -1; |
420 | points.append(QPointF((QPointF(point.attribute("x").toFloat(),0) |
421 | +QPointF(500,500)).x(), |
422 | (QPointF(0,point.attribute("y").toFloat()) |
423 | +QPointF(500,500)).y())); |
424 | } |
425 | |
426 | if(points.count()>0) |
427 | { |
428 | myPolygonPath = new Arrow(points.at(0),points.at(0),0,this); |
429 | for(int i=1; i< points.count();i++) |
430 | { |
431 | myPolygonPath->createCorner(points.at(i),i-1); |
432 | } |
433 | myPolygonPath->createFirstCorner(); |
434 | myPolygonPath->updatePosition(); |
435 | } |
436 | } |
437 | else if(element.tagName()=="TextItems") |
438 | { |
439 | for (QDomNode node = element.firstChild() ; |
440 | !node.isNull() ; |
441 | node = node.nextSibling()) |
442 | { |
443 | QDomElement textItemE = node.toElement(); |
444 | if(textItemE.tagName()!="TextItem") |
445 | return -1; |
446 | |
447 | int myStyleIO = textItemE.attribute("myStyleIO").toInt(); |
448 | int myID = textItemE.attribute("ID").toInt(); |
449 | bool editableItem = textItemE.attribute("editableItem").toInt(); |
450 | QPointF posOffset= |
451 | QPointF((QPointF(textItemE.attribute("posOffset-x") |
452 | .toFloat(),0)+QPointF(500,500)).x(), |
453 | (-QPointF(0,textItemE.attribute("posOffset-y") |
454 | .toFloat())+QPointF(500,500)).y()); |
455 | QString itemString=textItemE.attribute("text"); |
456 | |
457 | if(myStyleIO==0) |
458 | { |
459 | if(!editableItem) |
460 | myStyleIO=256; |
461 | else |
462 | myStyleIO=257; |
463 | } |
464 | |
465 | DiagramTextItem * newTextItem = |
466 | new DiagramTextItem(0,0,1,myStyleIO,myID,itemString,posOffset); |
467 | newTextItem->setZValue(1000.0); |
468 | connect(newTextItem, SIGNAL(lostFocus(DiagramTextItem*)), |
469 | this, SLOT(editorLostFocus(DiagramTextItem*))); |
470 | addItem(newTextItem); |
471 | textItemsByID.insert(myID,newTextItem); |
472 | } |
473 | } |
474 | } |
475 | myOwnerWindow->updateProt(); |
476 | return 1; |
477 | } |
478 | |
479 | void DiagramScene::cleanScene() |
480 | { |
481 | //Lists of items |
482 | QList<DiagramTextItem *> Items; |
483 | foreach(QGraphicsItem *item, items()) |
484 | { |
485 | if(item->type() == DiagramTextItem::Type) |
486 | Items.append(qgraphicsitem_cast<DiagramTextItem *>(item)); |
487 | } |
488 | //Remove Diagram Text Items |
489 | foreach(DiagramTextItem *item, Items) |
490 | { |
491 | if(item->styleIO() != 0xFFF) |
492 | { |
493 | removeItem(item); |
494 | delete(item); |
495 | } |
496 | } |
497 | //Remove Polygon Path |
498 | if(items().indexOf(myPolygonPath)!=-1) |
499 | { |
500 | myPolygonPath->removeLines(); |
501 | removeItem(myPolygonPath); |
502 | delete(myPolygonPath); |
503 | } |
504 | TitleText->setPlainText("BLOCK NAME HERE (not visible)"); |
505 | TitleText->updatePosition(); |
506 | } |
507 | |
508 | int DiagramScene::addTextItem(DiagramTextItem * textItem) |
509 | { |
510 | for(int i=0; i<255; i++) |
511 | { |
512 | QHash<int,DiagramTextItem *>::iterator iter= textItemsByID.find(i); |
513 | if(iter==textItemsByID.end()) |
514 | { |
515 | textItemsByID.insert(i,textItem); |
516 | return i; |
517 | } |
518 | } |
519 | return -1; |
520 | } |
521 | |
522 | void DiagramScene::removeTextItem(DiagramTextItem * textItem) |
523 | { |
524 | textItemsByID.remove(textItemsByID.key(textItem)); |
525 | } |
526 |
Branches:
master