00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <QtGui>
00023 #include <QDebug>
00024 #include <iostream>
00025
00026 #include "slatewindow.h"
00027 #include "sinclink.h"
00028 #include "asinclink.h"
00029 #include "sequenlink.h"
00030 #include "node.h"
00031 #include "groupnode.h"
00032 #include "inputnode.h"
00033 #include "middlenode.h"
00034 #include "outputnode.h"
00035 #include "slateview.h"
00036 #include "insertaction.h"
00037
00038 #include <QVDesignerGUI>
00039
00040 #include "../facade/itemproperties.h"
00041
00042
00043 SlateWindow::SlateWindow(QVDesignerGUI *desig, QWidget * parent): QMainWindow(parent), designer(desig)
00044 {
00045 scene = new QGraphicsScene(-1180, -900, 3200, 2400);
00046
00047 view = new SlateView;
00048 view->setScene(scene);
00049 view->setDragMode(QGraphicsView::RubberBandDrag);
00050 view->setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
00051 view->setContextMenuPolicy(Qt::ActionsContextMenu);
00052 setCentralWidget(view);
00053
00054 minZ = 0;
00055 maxZ = 0;
00056 seqNumber = 0;
00057
00058 createMenus();
00059 createToolBars();
00060
00061 statusbar = new QStatusBar();
00062 setStatusBar(statusbar);
00063
00064 connect(scene, SIGNAL(selectionChanged()), this, SLOT(updateActions()));
00065
00066 scene->setBackgroundBrush(QPixmap(":/images/background1.png"));
00067
00068 setWindowTitle(tr("Slate"));
00069
00070 showMessage("Pulsa \"Stop\" para poder editar el ejemplo.");
00071
00072 updateActions();
00073 }
00074
00075 void SlateWindow::closeEvent(QCloseEvent *)
00076 {
00077 emit closed();
00078 }
00079
00081 bool SlateWindow::createLink(Node *fromNode, int fromPoint, Node *toNode, int toPoint)
00082 {
00083
00084 if (stopAction->isEnabled()) return false;
00085
00086 uint fromId = 0, toId = 0;
00087 fromId = fromNode->getId();
00088 toId = toNode->getId();
00089
00090 bool sinc = addSLinkAction->isChecked();
00091 bool sequ = (!addSLinkAction->isChecked() && !addALinkAction->isChecked());
00092
00093 designer->addLink(fromId, fromNode->propName(fromPoint), toId, toNode->propName(toPoint), sinc, sequ);
00094
00095 return true;
00096 }
00097
00098 void SlateWindow::addLinkLine(uint fromId, QString fromProp, uint toId, QString toProp, bool sinc, bool sequential)
00099 {
00100 Link *link;
00101 QString linkName = QString("%1").arg(fromId) + "[" + fromProp + "] => " + QString("%1").arg(toId) + "[" + toProp + "]";
00102
00103 if ( insertNodes.contains(fromId) && insertNodes.contains(toId) ) {
00104 Node *from = insertNodes.value(fromId);
00105 Node *to = insertNodes.value(toId);
00106
00107 if (sequential) {
00108 link = new SequenLink(from, fromProp, to, toProp, 0, scene);
00109 insertLinks.insert(linkName, link);
00110 link->trackNodes();
00111 }
00112 else if (sinc) {
00113 link = new SincLink(from, fromProp, to, toProp, 0, scene);
00114 insertLinks.insert(linkName, link);
00115 link->trackNodes();
00116 }
00117 else {
00118 link = new AsincLink(from, fromProp, to, toProp, 0, scene);
00119 insertLinks.insert(linkName, link);
00120 link->trackNodes();
00121 }
00122 }
00123 }
00124
00125 void SlateWindow::delLinkLine(uint fromId, QString fromProp, uint toId, QString toProp)
00126 {
00127 QString linkName = QString("%1").arg(fromId) + "[" + fromProp + "] => " + QString("%1").arg(toId) + "[" + toProp + "]";
00128 if (insertLinks.contains(linkName)) {
00129 delete insertLinks.value(linkName);
00130 insertLinks.remove(linkName);
00131 }
00132 }
00133
00134 void SlateWindow::insertItem(QString type)
00135 {
00136 QString name = type.toLower();
00137 name.replace('<', '_');
00138 name.replace(',', '_');
00139 name.replace('>', '_');
00140 name.replace(' ', "");
00141
00142 designer->addItem(type, name);
00143 }
00144
00145 void SlateWindow::setName(Node *item, QString name)
00146 {
00147 designer->setName(insertNodes.key(item), name);
00148 }
00149
00150 void SlateWindow::setItemName(uint id, QString name)
00151 {
00152 if (insertNodes.contains(id))
00153 insertNodes.value(id)->setName(name);
00154 }
00155
00156 void SlateWindow::addItemNode(QString type, QString name, uint id, ItemProperties *item, uint lastId)
00157 {
00159 bool inputItemsContainsType = false;
00160 foreach(QList<QString> groupItems, designer->getInputItemTypes().values())
00161 if (groupItems.contains(type)) {
00162 inputItemsContainsType = true;
00163 break;
00164 }
00165 if (inputItemsContainsType) {
00166 InputNode *node = new InputNode(*item, name, id, this, 0, scene);
00167 insertNodes.insert(id, node);
00168 setupNode(node);
00169 if (insertNodesPos.contains(lastId)) {
00170 node->setPos(insertNodesPos.value(lastId));
00171 insertNodesPos.remove(lastId);
00172 insertNodesPos.insert(id, node->pos());
00173 }
00174 else
00175 insertNodesPos.insert(id, node->pos());
00176 }
00177 else {
00178 bool middleItemsContainsType = false;
00179 foreach(QList<QString> groupItems, designer->getMiddleItemTypes().values())
00180 if (groupItems.contains(type)) {
00181 middleItemsContainsType = true;
00182 break;
00183 }
00184 if (middleItemsContainsType) {
00185 MiddleNode *node = new MiddleNode(*item, name, id, this, 0, scene);
00186 insertNodes.insert(id, node);
00187 setupNode(node);
00188 if (insertNodesPos.contains(lastId)) {
00189 node->setPos(insertNodesPos.value(lastId));
00190 insertNodesPos.remove(lastId);
00191 insertNodesPos.insert(id, node->pos());
00192 }
00193 else
00194 insertNodesPos.insert(id, node->pos());
00195 }
00196 else {
00197 bool outputItemsContainsType = false;
00198 foreach(QList<QString> groupItems, designer->getOutputItemTypes().values())
00199 if (groupItems.contains(type)) {
00200 outputItemsContainsType = true;
00201 break;
00202 }
00203 if (outputItemsContainsType) {
00204 OutputNode *node = new OutputNode(*item, name, id, this, 0, scene);
00205 insertNodes.insert(id, node);
00206 setupNode(node);
00207 if (insertNodesPos.contains(lastId)) {
00208 node->setPos(insertNodesPos.value(lastId));
00209 insertNodesPos.remove(lastId);
00210 insertNodesPos.insert(id, node->pos());
00211 }
00212 else
00213 insertNodesPos.insert(id, node->pos());
00214 }
00215 }
00216 }
00217 }
00218
00219 void SlateWindow::delItemNode(uint id)
00220 {
00221 if (insertNodes.contains(id)) {
00222 insertNodesPos.remove(id);
00223 insertNodesPos.insert(id, insertNodes.value(id)->pos());
00224 delete insertNodes.value(id);
00225 insertNodes.remove(id);
00226 }
00227 }
00228
00229 void SlateWindow::addProperty(uint id, QString propName, int type, bool in, bool out)
00230 {
00231 if (insertNodes.contains(id)) {
00232 insertNodes.value(id)->insertProperty(propName, type, in, out);
00233 }
00234 }
00235
00236 void SlateWindow::delProperty(uint id, QString propName)
00237 {
00238 if (insertNodes.contains(id)) {
00239 insertNodes.value(id)->removeProperty(propName);
00240 }
00241 }
00242
00243 void SlateWindow::del()
00244 {
00245
00246 foreach(QGraphicsItem *item, scene->selectedItems()) {
00247 Link *link = dynamic_cast<Link *>(item);
00248
00249 if (link && (link->fromNode() != NULL) && (link->toNode() != NULL)) {
00250 uint fromId = 0, toId = 0;
00251 fromId = link->fromNode()->getId();
00252 toId = link->toNode()->getId();
00253
00254 designer->delLink(fromId, link->fromProp(), toId, link->toProp());
00255 }
00256 }
00257
00258
00259 foreach(QGraphicsItem *item, scene->selectedItems()) {
00260 GroupNode *node = dynamic_cast<GroupNode *>(item);
00261
00262 if (node) {
00263
00264
00265 GroupInfo delGroupInfo = createdGroupInfos[(Node *)node];
00266 foreach(Node *group, createdGroupInfos.keys()) {
00267 GroupInfo groupInfo = createdGroupInfos[group];
00268 foreach(uint subgroupId, groupInfo.getSubgroups())
00269 if (subgroupId == delGroupInfo.getId()) {
00270 foreach(uint internalNode, delGroupInfo.getNodes())
00271 groupInfo.addNode(internalNode);
00272 foreach(uint internalSubgroup, delGroupInfo.getSubgroups())
00273 groupInfo.addSubgroup(internalSubgroup);
00274 groupInfo.delSubgroup(delGroupInfo.getId());
00275 createdGroupInfos.insert(group, groupInfo);
00276 }
00277 }
00278
00279 createdGroupInfos.remove(node);
00280 createdGroups.remove(node->getId());
00281 delete node;
00282 }
00283 }
00284
00285
00286 foreach(QGraphicsItem *item, scene->selectedItems()) {
00287 Node *node = dynamic_cast<InputNode *>(item);
00288 if (!node) node = dynamic_cast<MiddleNode *>(item);
00289 if (!node) node = dynamic_cast<OutputNode *>(item);
00290
00291 if (node) {
00292 uint itemnode = 0;
00293 itemnode = node->getId();
00294 designer->delItem(itemnode);
00295 }
00296 }
00297 }
00298
00299 void SlateWindow::join()
00300 {
00301 QList<QGraphicsItem *> group = selectedNodeGroup();
00302
00303
00304 QPointF middlePos;
00305 int count = 0;
00306 foreach (QGraphicsItem *item, group) {
00307 Node *itemNode = dynamic_cast<Node *>(item);
00308 if (itemNode) {
00309 middlePos += itemNode->pos();
00310 count++;
00311 }
00312 }
00313 middlePos /= count;
00314
00315
00316 GroupNode *node = new GroupNode("Group", this, 0, scene);
00317 node->setPos(middlePos);
00318
00319
00320 if ( !group.isEmpty() && group.first() && group.first()->parentItem() ) {
00321 GroupNode *parentNode = dynamic_cast<GroupNode *>(group.first()->parentItem());
00322 if (parentNode) parentNode->addNode(node);
00323 }
00324
00325
00326 foreach (QGraphicsItem *item, group) {
00327 Node *itemNode = dynamic_cast<Node *>(item);
00328 if (itemNode) {
00329 node->addNode(itemNode);
00330
00331
00332
00333 foreach (Link *link, itemNode->getInLinks()) {
00334 Node *other = link->fromNode();
00335 if (group.contains(other)) {
00336 QPen pen = link->pen();
00337 pen.setWidthF(pen.width()*0.5);
00338 link->setPen(pen);
00339 link->update();
00340 }
00341 }
00342 foreach (Link *link, itemNode->getOutLinks()) {
00343 Node *other = link->toNode();
00344 if (group.contains(other)) {
00345 QPen pen = link->pen();
00346 pen.setWidthF(pen.width()*0.5);
00347 link->setPen(pen);
00348 link->update();
00349 }
00350 }
00351 itemNode->updateLinksPos();
00352 }
00353 }
00354
00355 createdGroupInfos.insert(node, node->getInfo());
00356 createdGroups.insert(node->getId(), node);
00357 }
00358
00359 void SlateWindow::bringToFront()
00360 {
00361 maxZ += 2;
00362 setZValue(maxZ);
00363 }
00364
00365 void SlateWindow::sendToBack()
00366 {
00367 minZ += 2;
00368 setZValue(minZ);
00369 }
00370
00371 void SlateWindow::run()
00372 {
00373 foreach (QAction *action, insertMenu->actions()) {
00374 action->setEnabled(false);
00375 }
00376 foreach (QMenu *submenu, insertSubmenus) {
00377 submenu->setEnabled(false);
00378 foreach (QAction *action, submenu->actions()) {
00379 action->setEnabled(false);
00380 }
00381 }
00382
00383 deleteAction->setEnabled(false);
00384 openAction->setEnabled(false);
00385
00386 runAction->setEnabled(false);
00387 stopAction->setEnabled(true);
00388 designer->run();
00389 }
00390
00391 void SlateWindow::stop()
00392 {
00393 designer->stop();
00394 stopAction->setEnabled(false);
00395 runAction->setChecked(false);
00396 runAction->setEnabled(true);
00397
00398 bool hasSelection = !scene->selectedItems().isEmpty();
00399 deleteAction->setEnabled(hasSelection);
00400 openAction->setEnabled(true);
00401
00402 foreach (QAction *action, insertMenu->actions()) {
00403 action->setEnabled(true);
00404 }
00405 foreach (QMenu *submenu, insertSubmenus) {
00406 foreach (QAction *action, submenu->actions()) {
00407 action->setEnabled(true);
00408 }
00409 submenu->setEnabled(true);
00410 }
00411 }
00412
00413 void SlateWindow::setZValue(int z)
00414 {
00415 Node *node = selectedNode();
00416 if (node) {
00417 node->setZValue(z);
00418 node->updateLinksPos();
00419 }
00420 }
00421
00422 void SlateWindow::showProperties()
00423 {
00424 Node *node = selectedNode();
00425
00426 if (node) showProperties(node);
00427 }
00428
00429 void SlateWindow::showProperties(Node *node)
00430 {
00431 uint itemnode = 0;
00432 itemnode = node->getId();
00433
00434 designer->showProperties(itemnode);
00435 }
00436
00437 void SlateWindow::updateActions()
00438 {
00439 bool hasSelection = !scene->selectedItems().isEmpty();
00440 bool isNode = (selectedNode() != 0);
00441
00442 bool isNodeGroup = false;
00443 int count = 0;
00444 foreach (QGraphicsItem *item, selectedNodeGroup())
00445 if (dynamic_cast<Node *>(item)) count++;
00446 if (count > 0) isNodeGroup = true;
00447
00448 joinAction->setEnabled(isNodeGroup);
00449
00450 if (runAction->isEnabled()) {
00451 deleteAction->setEnabled(hasSelection);
00452 openAction->setEnabled(true);
00453 }
00454 bringToFrontAction->setEnabled(isNode);
00455 sendToBackAction->setEnabled(isNode);
00456 propertiesAction->setEnabled(isNode);
00457
00458 foreach (QAction *action, view->actions())
00459 view->removeAction(action);
00460
00461 foreach (QAction *action, editMenu->actions()) {
00462 if (action->isEnabled())
00463 view->addAction(action);
00464 }
00465
00466 if (!hasSelection) {
00467
00468 QAction *insertTitle = new QAction(tr("Insert"), this);
00469 insertTitle->setEnabled(false);
00470 QFont font(insertTitle->font());
00471 font.setWeight(QFont::Black);
00472 font.setStyle(QFont::StyleItalic);
00473 insertTitle->setFont(font);
00474 view->addAction(insertTitle);
00475 view->addActions(insertMenu->actions());
00476 }
00477 }
00478
00479 void SlateWindow::clearSelection()
00480 {
00481 scene->clearSelection();
00482 }
00483
00484 bool SlateWindow::isSelected(QGraphicsItem *item)
00485 {
00486 return scene->selectedItems().contains(item);
00487 }
00488
00489 void SlateWindow::setupNode(Node *node)
00490 {
00491 node->setPos( QPoint(10 + (seqNumber % 10) * 6, 20 + (seqNumber % 10) * 6) );
00492 ++seqNumber;
00493
00494 clearSelection();
00495 node->setSelected(true);
00496 bringToFront();
00497 }
00498
00499 void SlateWindow::createMenus()
00500 {
00502 exitAction = new QAction(tr("E&xit"), this);
00503 exitAction->setShortcut(tr("Ctrl+Q"));
00504 connect(exitAction, SIGNAL(triggered()), this, SLOT(close()));
00505
00506 addALinkAction = new QAction(tr("&Asynchronous Link Mode"), this);
00507 addALinkAction->setIcon(QIcon(":/images/alink.png"));
00508 addALinkAction->setShortcut(tr("Ctrl+A"));
00509 addALinkAction->setCheckable(true);
00510 addALinkAction->setChecked(true);
00511
00512 addSLinkAction = new QAction(tr("&Synchronous Link Mode"), this);
00513 addSLinkAction->setIcon(QIcon(":/images/slink.png"));
00514 addSLinkAction->setShortcut(tr("Ctrl+S"));
00515 addSLinkAction->setCheckable(true);
00516
00517 addQLinkAction = new QAction(tr("Se&quential Link Mode"), this);
00518 addQLinkAction->setIcon(QIcon(":/images/qlink.png"));
00519 addQLinkAction->setShortcut(tr("Ctrl+Q"));
00520 addQLinkAction->setCheckable(true);
00521
00522
00523 linkGroup = new QActionGroup(this);
00524 linkGroup->setExclusive(true);
00525 linkGroup->addAction(addALinkAction);
00526 linkGroup->addAction(addSLinkAction);
00527 linkGroup->addAction(addQLinkAction);
00528
00529
00530 joinAction = new QAction(tr("&Join"), this);
00531 joinAction->setIcon(QIcon(":/images/join.png"));
00532 joinAction->setShortcut(tr("Ctrl+J"));
00533 connect(joinAction, SIGNAL(triggered()), this, SLOT(join()));
00534
00535 deleteAction = new QAction(tr("&Delete"), this);
00536 deleteAction->setIcon(QIcon(":/images/delete.png"));
00537 deleteAction->setShortcut(tr("Del"));
00538 deleteAction->setEnabled(false);
00539 connect(deleteAction, SIGNAL(triggered()), this, SLOT(del()));
00540
00541 bringToFrontAction = new QAction(tr("Bring to &Front"), this);
00542 bringToFrontAction->setIcon(QIcon(":/images/bringtofront.png"));
00543 connect(bringToFrontAction, SIGNAL(triggered()),this, SLOT(bringToFront()));
00544
00545 sendToBackAction = new QAction(tr("&Send to Back"), this);
00546 sendToBackAction->setIcon(QIcon(":/images/sendtoback.png"));
00547 connect(sendToBackAction, SIGNAL(triggered()), this, SLOT(sendToBack()));
00548
00549 propertiesAction = new QAction(tr("P&roperties..."), this);
00550 connect(propertiesAction, SIGNAL(triggered()), this, SLOT(showProperties()));
00551
00552 runAction = new QAction(tr("&Run"), this);
00553 runAction->setIcon(QIcon(":/images/run.png"));
00554 runAction->setCheckable(true);
00555 runAction->setChecked(true);
00556 runAction->setEnabled(false);
00557 connect(runAction, SIGNAL(triggered()), this, SLOT(run()));
00558
00559 stopAction = new QAction(tr("&Stop"), this);
00560 stopAction->setIcon(QIcon(":/images/stop.png"));
00561 stopAction->setEnabled(true);
00562 connect(stopAction, SIGNAL(triggered()), this, SLOT(stop()));
00563
00564 exportAction = new QAction(tr("&Export"), this);
00565 exportAction->setShortcut(tr("Ctrl+E"));
00566 connect(exportAction, SIGNAL(triggered()), this, SLOT(exportAs()));
00567
00568 saveAsAction = new QAction(tr("&Save As"), this);
00569 saveAsAction->setShortcut(tr("Ctrl+S"));
00570 connect(saveAsAction, SIGNAL(triggered()), this, SLOT(saveAs()));
00571
00572 openAction = new QAction(tr("&Load"), this);
00573 openAction->setShortcut(tr("Ctrl+L"));
00574 openAction->setEnabled(false);
00575 connect(openAction, SIGNAL(triggered()), this, SLOT(open()));
00576
00577 fileMenu = menuBar()->addMenu(tr("&File"));
00578 fileMenu->addAction(exportAction);
00579 fileMenu->addAction(saveAsAction);
00580 fileMenu->addAction(openAction);
00581 fileMenu->addAction(exitAction);
00582
00583 editMenu = menuBar()->addMenu(tr("&Edit"));
00584 editMenu->addAction(addALinkAction);
00585 editMenu->addAction(addSLinkAction);
00586 editMenu->addAction(addQLinkAction);
00587
00588 editMenu->addSeparator();
00589 editMenu->addAction(joinAction);
00590 editMenu->addAction(deleteAction);
00591 editMenu->addSeparator();
00592 editMenu->addAction(bringToFrontAction);
00593 editMenu->addAction(sendToBackAction);
00594 editMenu->addSeparator();
00595 editMenu->addAction(propertiesAction);
00596
00597
00598
00599 insertMenu = menuBar()->addMenu(tr("&Insert"));
00600
00601 QMap<QString, QList<QString> > itemTypes = designer->getItemTypes();
00602 foreach (QString group, itemTypes.keys()) {
00603 QMenu *submenu = insertMenu->addMenu(group);
00604 submenu->setEnabled(false);
00605 insertSubmenus.append(submenu);
00606
00607 foreach (QString item, itemTypes.value(group))
00608 {
00609 InsertAction *action = new InsertAction(item, this);
00610 action->setEnabled(false);
00611 connect(action, SIGNAL(triggered(QString)), this, SLOT(insertItem(QString)));
00612 submenu->addAction(action);
00613 }
00614 }
00615 insertUserSubmenu = insertMenu->addMenu("User node");
00616 insertUserSubmenu->setEnabled(false);
00617 insertSubmenus.append(insertUserSubmenu);
00618 }
00619
00620 void SlateWindow::includeItemType(QString itemType)
00621 {
00622 InsertAction *action = new InsertAction(itemType, this);
00623 action->setEnabled(false);
00624 connect(action, SIGNAL(triggered(QString)), this, SLOT(insertItem(QString)));
00625 insertUserSubmenu->addAction(action);
00626
00627 updateActions();
00628 }
00629
00630 void SlateWindow::createToolBars()
00631 {
00632 editToolBar = addToolBar(tr("Edit"));
00633 editToolBar->addAction(addALinkAction);
00634 editToolBar->addAction(addSLinkAction);
00635 editToolBar->addAction(addQLinkAction);
00636 editToolBar->addAction(joinAction);
00637 editToolBar->addAction(deleteAction);
00638 editToolBar->addSeparator();
00639 editToolBar->addSeparator();
00640 editToolBar->addAction(bringToFrontAction);
00641 editToolBar->addAction(sendToBackAction);
00642
00643 editToolBar->addSeparator();
00644 editToolBar->addAction(runAction);
00645 editToolBar->addAction(stopAction);
00646 }
00647
00648 Node *SlateWindow::selectedNode() const
00649 {
00650 QList<QGraphicsItem *> items = scene->selectedItems();
00651 if (items.count() == 1) {
00652 return dynamic_cast<Node *>(items.first());
00653 } else {
00654 return 0;
00655 }
00656 }
00657
00658 Link *SlateWindow::selectedLink() const
00659 {
00660 QList<QGraphicsItem *> items = scene->selectedItems();
00661 if (items.count() == 1) {
00662 return dynamic_cast<Link *>(items.first());
00663 } else {
00664 return 0;
00665 }
00666 }
00667
00668 SlateWindow::NodePair SlateWindow::selectedNodePair() const
00669 {
00670 QList<QGraphicsItem *> items = scene->selectedItems();
00671 if (items.count() == 2) {
00672 Node *first = dynamic_cast<Node *>(items.first());
00673 Node *second = dynamic_cast<Node *>(items.last());
00674 if (first && second)
00675 return NodePair(first, second);
00676 }
00677 return NodePair();
00678 }
00679
00680
00681 QList<QGraphicsItem *> SlateWindow::selectedNodeGroup() const
00682 {
00683 QList<QGraphicsItem *> items = onlyParents(scene->selectedItems());
00684
00685
00686 if (items.count() > 1) {
00687
00688 QGraphicsItem * parent = 0;
00689 QMutableListIterator<QGraphicsItem *> i(items);
00690 if (i.hasNext()) parent = i.next()->parentItem();
00691
00692 while (i.hasNext())
00693 if ( i.next()->parentItem() != parent) return QList<QGraphicsItem *>();
00694
00695 return items;
00696 }
00697 return items;
00698 }
00699
00700
00701 QList<QGraphicsItem *> SlateWindow::onlyParents(QList<QGraphicsItem *> items) const
00702 {
00703 QList<QGraphicsItem *> parentItems;
00704
00705 QMutableListIterator<QGraphicsItem *> i(items);
00706 while (i.hasNext()) {
00707 i.next();
00708 bool parent = true;
00709 QMutableListIterator<QGraphicsItem *> j(items);
00710 while (j.hasNext()) {
00711 j.next();
00712 if ( (i.value()) && (i.value()->parentItem() == j.value()) ) {
00713 parent = false;
00714 break;
00715 }
00716 }
00717 if (parent) parentItems.append(i.value());
00718 }
00719
00720 return parentItems;
00721 }
00722
00723 bool SlateWindow::exportAs()
00724 {
00725 QString fileName = QFileDialog::getSaveFileName(this,
00726 tr("Save C++"), ".",
00727 tr("C++ files (*.cpp)"));
00728 if (fileName.isEmpty())
00729 return false;
00730 return saveFile(fileName, false);
00731 }
00732
00733 bool SlateWindow::saveAs()
00734 {
00735 QString fileName = QFileDialog::getSaveFileName(this,
00736 tr("Save XML"), ".",
00737 tr("XML files (*.xml)"));
00738 if (fileName.isEmpty())
00739 return false;
00740 return saveFile(fileName, true);
00741 }
00742
00743 bool SlateWindow::open()
00744 {
00745 QString fileName = QFileDialog::getOpenFileName(this,
00746 tr("Open File"), ".",
00747 tr("XML files (*.xml)"));
00748 if (fileName.isEmpty()) return false;
00749
00750
00751 QFile file(fileName);
00752 if (!file.open(QIODevice::ReadOnly)) {
00753 QMessageBox::warning(this, tr("QVDesignerGUI"),
00754 tr("Cannot open file %1:\n%2.")
00755 .arg(file.fileName())
00756 .arg(file.errorString()));
00757 return false;
00758 }
00759 QTextStream in(&file);
00760 return (designer->loadXML(in.readAll()));
00761 }
00762
00763 bool SlateWindow::saveFile(const QString &fileName, bool xmlFile)
00764 {
00765 QFile file(fileName);
00766 if (!file.open(QIODevice::WriteOnly)) {
00767 QMessageBox::warning(this, tr("QVDesignerGUI"),
00768 tr("Cannot write file %1:\n%2.")
00769 .arg(file.fileName())
00770 .arg(file.errorString()));
00771 return false;
00772 }
00773
00774 QTextStream out(&file);
00775 if (xmlFile)
00776 out << designer->getXMLText();
00777 else
00778 out << designer->getCppText();
00779
00780 return true;
00781 }
00782
00783 void SlateWindow::showMessage(QString message)
00784 {
00785 if (statusbar)
00786 statusbar->showMessage(message, 10000);
00787 }
00788
00789
00790 void SlateWindow::arrangeItems()
00791 {
00792 QList<QList<Node *> *> levels;
00793 int left = 10;
00794 int bottom = 20;
00795 const int MARGIN = 20;
00796
00797
00798 foreach(Node *node, insertNodes) {
00799 int level = node->precursors();
00800 while(levels.size() <= level)
00801 levels.append(new QList<Node *>);
00802 levels[level]->append(node);
00803 }
00804
00805
00806 foreach(QList<Node *> *levelNodes, levels) {
00807 int maxWidth = 0;
00808 if (levelNodes) {
00809 foreach(Node *node, *levelNodes) {
00810 node->setPos(QPoint(left, bottom));
00811 insertNodesPos.insert(insertNodes.key(node), node->pos());
00812 bottom += (int)node->boundingRect().height() + MARGIN;
00813 int width = (int)node->boundingRect().width();
00814 if (maxWidth < width) maxWidth = width;
00815 }
00816 }
00817 left += maxWidth + MARGIN;
00818 bottom = 20;
00819 }
00820
00821
00822 foreach(QList<Node *> *levelNodes, levels) {
00823 levelNodes->clear();
00824 delete levelNodes;
00825 }
00826 }
00827
00828 QPointF SlateWindow::getNodePos(uint id) const
00829 {
00830 return insertNodes.value(id)->pos();
00831 }
00832
00833 bool SlateWindow::moveNode(uint id, QPointF pos)
00834 {
00835 if (insertNodes.contains(id)) {
00836 Node *node = insertNodes.value(id);
00837 node->setPos(pos);
00838 insertNodesPos.remove(id);
00839 insertNodesPos.insert(id, node->pos());
00840 return true;
00841 }
00842
00843 return false;
00844 }
00845
00846 QList<GroupInfo> SlateWindow::getGroups()
00847 {
00848
00849 foreach(Node *group, createdGroupInfos.keys()) {
00850 createdGroupInfos[group].setPos(group->pos());
00851 createdGroupInfos[group].setName(group->getName());
00852 if (dynamic_cast<GroupNode *>(group))
00853 createdGroupInfos[group].setAbstract( ((GroupNode *)group)->getAbstract() );
00854 }
00855
00856 return createdGroupInfos.values();
00857 }
00858
00859 void SlateWindow::eraseGroups()
00860 {
00861 foreach(Node *group, createdGroupInfos.keys()) {
00862 delete group;
00863 }
00864
00865 createdGroupInfos.clear();
00866 createdGroups.clear();
00867 }
00868
00869 uint SlateWindow::createGroup(GroupInfo info)
00870 {
00871 QList<QGraphicsItem *> group;
00872 foreach (uint nodeId, info.getNodes()) {
00873 if (insertNodes.contains(nodeId)) {
00874 group.append(insertNodes.value(nodeId));
00875 }
00876 else {
00877
00878 return 0;
00879 }
00880 }
00881 foreach (uint subgroupId, info.getSubgroups()) {
00882 if (createdGroups.contains(subgroupId)) {
00883 group.append(createdGroups.value(subgroupId));
00884 }
00885 else {
00886
00887 return 0;
00888 }
00889 }
00890
00891
00892 GroupNode *node = new GroupNode(info.getName(), this, 0, scene);
00893 node->setPos(info.getPos());
00894
00895
00896 if ( !group.isEmpty() && group.first() && group.first()->parentItem() ) {
00897 GroupNode *parentNode = dynamic_cast<GroupNode *>(group.first()->parentItem());
00898 if (parentNode) parentNode->addNode(node);
00899 }
00900
00901
00902 foreach (QGraphicsItem *item, group) {
00903 Node *itemNode = dynamic_cast<Node *>(item);
00904 if (itemNode) {
00905 node->addNode(itemNode);
00906
00907
00908
00909 foreach (Link *link, itemNode->getInLinks()) {
00910 Node *other = link->fromNode();
00911 if (group.contains(other)) {
00912 QPen pen = link->pen();
00913 pen.setWidthF(pen.width()*0.5);
00914 link->setPen(pen);
00915 link->update();
00916 }
00917 }
00918 foreach (Link *link, itemNode->getOutLinks()) {
00919 Node *other = link->toNode();
00920 if (group.contains(other)) {
00921 QPen pen = link->pen();
00922 pen.setWidthF(pen.width()*0.5);
00923 link->setPen(pen);
00924 link->update();
00925 }
00926 }
00927 itemNode->updateLinksPos();
00928 }
00929 }
00930
00931 createdGroupInfos.insert(node, node->getInfo());
00932 createdGroups.insert(node->getId(), node);
00933 node->abstractView(info.getAbstract());
00934
00935 return node->getId();
00936 }
00937
00938
00939