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 createdGroupInfos.remove(node);
00264 createdGroups.remove(node->getId());
00265 delete node;
00266 }
00267 }
00268
00269
00270 foreach(QGraphicsItem *item, scene->selectedItems()) {
00271 Node *node = dynamic_cast<InputNode *>(item);
00272 if (!node) node = dynamic_cast<MiddleNode *>(item);
00273 if (!node) node = dynamic_cast<OutputNode *>(item);
00274
00275 if (node) {
00276 uint itemnode = 0;
00277 itemnode = node->getId();
00278 designer->delItem(itemnode);
00279 }
00280 }
00281 }
00282
00283 void SlateWindow::join()
00284 {
00285 QList<QGraphicsItem *> group = selectedNodeGroup();
00286
00287
00288 QPointF middlePos;
00289 int count = 0;
00290 foreach (QGraphicsItem *item, group) {
00291 Node *itemNode = dynamic_cast<Node *>(item);
00292 if (itemNode) {
00293 middlePos += itemNode->pos();
00294 count++;
00295 }
00296 }
00297 middlePos /= count;
00298
00299
00300 GroupNode *node = new GroupNode("Group", this, 0, scene);
00301 node->setPos(middlePos);
00302
00303
00304 if ( !group.isEmpty() && group.first() && group.first()->parentItem() ) {
00305 GroupNode *parentNode = dynamic_cast<GroupNode *>(group.first()->parentItem());
00306 if (parentNode) parentNode->addNode(node);
00307 }
00308
00309
00310 foreach (QGraphicsItem *item, group) {
00311 Node *itemNode = dynamic_cast<Node *>(item);
00312 if (itemNode) {
00313 node->addNode(itemNode);
00314
00315
00316
00317 foreach (Link *link, itemNode->getInLinks()) {
00318 Node *other = link->fromNode();
00319 if (group.contains(other)) {
00320 QPen pen = link->pen();
00321 pen.setWidthF(pen.width()*0.5);
00322 link->setPen(pen);
00323 link->update();
00324 }
00325 }
00326 foreach (Link *link, itemNode->getOutLinks()) {
00327 Node *other = link->toNode();
00328 if (group.contains(other)) {
00329 QPen pen = link->pen();
00330 pen.setWidthF(pen.width()*0.5);
00331 link->setPen(pen);
00332 link->update();
00333 }
00334 }
00335 itemNode->updateLinksPos();
00336 }
00337 }
00338
00339 createdGroupInfos.insert(node, node->getInfo());
00340 createdGroups.insert(node->getId(), node);
00341 }
00342
00343 void SlateWindow::bringToFront()
00344 {
00345 maxZ += 2;
00346 setZValue(maxZ);
00347 }
00348
00349 void SlateWindow::sendToBack()
00350 {
00351 minZ += 2;
00352 setZValue(minZ);
00353 }
00354
00355 void SlateWindow::run()
00356 {
00357 foreach (QAction *action, insertMenu->actions()) {
00358 action->setEnabled(false);
00359 }
00360 foreach (QMenu *submenu, insertSubmenus) {
00361 submenu->setEnabled(false);
00362 foreach (QAction *action, submenu->actions()) {
00363 action->setEnabled(false);
00364 }
00365 }
00366
00367 deleteAction->setEnabled(false);
00368 openAction->setEnabled(false);
00369
00370 runAction->setEnabled(false);
00371 stopAction->setEnabled(true);
00372 designer->run();
00373 }
00374
00375 void SlateWindow::stop()
00376 {
00377 designer->stop();
00378 stopAction->setEnabled(false);
00379 runAction->setChecked(false);
00380 runAction->setEnabled(true);
00381
00382 bool hasSelection = !scene->selectedItems().isEmpty();
00383 deleteAction->setEnabled(hasSelection);
00384 openAction->setEnabled(true);
00385
00386 foreach (QAction *action, insertMenu->actions()) {
00387 action->setEnabled(true);
00388 }
00389 foreach (QMenu *submenu, insertSubmenus) {
00390 foreach (QAction *action, submenu->actions()) {
00391 action->setEnabled(true);
00392 }
00393 submenu->setEnabled(true);
00394 }
00395 }
00396
00397 void SlateWindow::setZValue(int z)
00398 {
00399 Node *node = selectedNode();
00400 if (node) {
00401 node->setZValue(z);
00402 node->updateLinksPos();
00403 }
00404 }
00405
00406 void SlateWindow::showProperties()
00407 {
00408 Node *node = selectedNode();
00409
00410 if (node) showProperties(node);
00411 }
00412
00413 void SlateWindow::showProperties(Node *node)
00414 {
00415 uint itemnode = 0;
00416 itemnode = node->getId();
00417
00418 designer->showProperties(itemnode);
00419 }
00420
00421 void SlateWindow::updateActions()
00422 {
00423 bool hasSelection = !scene->selectedItems().isEmpty();
00424 bool isNode = (selectedNode() != 0);
00425
00426 bool isNodeGroup = false;
00427 int count = 0;
00428 foreach (QGraphicsItem *item, selectedNodeGroup())
00429 if (dynamic_cast<Node *>(item)) count++;
00430 if (count > 0) isNodeGroup = true;
00431
00432 joinAction->setEnabled(isNodeGroup);
00433
00434 if (runAction->isEnabled()) {
00435 deleteAction->setEnabled(hasSelection);
00436 openAction->setEnabled(true);
00437 }
00438 bringToFrontAction->setEnabled(isNode);
00439 sendToBackAction->setEnabled(isNode);
00440 propertiesAction->setEnabled(isNode);
00441
00442 foreach (QAction *action, view->actions())
00443 view->removeAction(action);
00444
00445 foreach (QAction *action, editMenu->actions()) {
00446 if (action->isEnabled())
00447 view->addAction(action);
00448 }
00449
00450 if (!hasSelection) {
00451
00452 QAction *insertTitle = new QAction(tr("Insert"), this);
00453 insertTitle->setEnabled(false);
00454 QFont font(insertTitle->font());
00455 font.setWeight(QFont::Black);
00456 font.setStyle(QFont::StyleItalic);
00457 insertTitle->setFont(font);
00458 view->addAction(insertTitle);
00459 view->addActions(insertMenu->actions());
00460 }
00461 }
00462
00463 void SlateWindow::clearSelection()
00464 {
00465 scene->clearSelection();
00466 }
00467
00468 bool SlateWindow::isSelected(QGraphicsItem *item)
00469 {
00470 return scene->selectedItems().contains(item);
00471 }
00472
00473 void SlateWindow::setupNode(Node *node)
00474 {
00475 node->setPos( QPoint(10 + (seqNumber % 10) * 6, 20 + (seqNumber % 10) * 6) );
00476 ++seqNumber;
00477
00478 clearSelection();
00479 node->setSelected(true);
00480 bringToFront();
00481 }
00482
00483 void SlateWindow::createMenus()
00484 {
00486 exitAction = new QAction(tr("E&xit"), this);
00487 exitAction->setShortcut(tr("Ctrl+Q"));
00488 connect(exitAction, SIGNAL(triggered()), this, SLOT(close()));
00489
00490 addALinkAction = new QAction(tr("&Asynchronous Link Mode"), this);
00491 addALinkAction->setIcon(QIcon(":/images/alink.png"));
00492 addALinkAction->setShortcut(tr("Ctrl+A"));
00493 addALinkAction->setCheckable(true);
00494 addALinkAction->setChecked(true);
00495
00496 addSLinkAction = new QAction(tr("&Synchronous Link Mode"), this);
00497 addSLinkAction->setIcon(QIcon(":/images/slink.png"));
00498 addSLinkAction->setShortcut(tr("Ctrl+S"));
00499 addSLinkAction->setCheckable(true);
00500
00501 addQLinkAction = new QAction(tr("Se&quential Link Mode"), this);
00502 addQLinkAction->setIcon(QIcon(":/images/qlink.png"));
00503 addQLinkAction->setShortcut(tr("Ctrl+Q"));
00504 addQLinkAction->setCheckable(true);
00505
00506
00507 linkGroup = new QActionGroup(this);
00508 linkGroup->setExclusive(true);
00509 linkGroup->addAction(addALinkAction);
00510 linkGroup->addAction(addSLinkAction);
00511 linkGroup->addAction(addQLinkAction);
00512
00513
00514 joinAction = new QAction(tr("&Join"), this);
00515 joinAction->setIcon(QIcon(":/images/join.png"));
00516 joinAction->setShortcut(tr("Ctrl+J"));
00517 connect(joinAction, SIGNAL(triggered()), this, SLOT(join()));
00518
00519 deleteAction = new QAction(tr("&Delete"), this);
00520 deleteAction->setIcon(QIcon(":/images/delete.png"));
00521 deleteAction->setShortcut(tr("Del"));
00522 deleteAction->setEnabled(false);
00523 connect(deleteAction, SIGNAL(triggered()), this, SLOT(del()));
00524
00525 bringToFrontAction = new QAction(tr("Bring to &Front"), this);
00526 bringToFrontAction->setIcon(QIcon(":/images/bringtofront.png"));
00527 connect(bringToFrontAction, SIGNAL(triggered()),this, SLOT(bringToFront()));
00528
00529 sendToBackAction = new QAction(tr("&Send to Back"), this);
00530 sendToBackAction->setIcon(QIcon(":/images/sendtoback.png"));
00531 connect(sendToBackAction, SIGNAL(triggered()), this, SLOT(sendToBack()));
00532
00533 propertiesAction = new QAction(tr("P&roperties..."), this);
00534 connect(propertiesAction, SIGNAL(triggered()), this, SLOT(showProperties()));
00535
00536 runAction = new QAction(tr("&Run"), this);
00537 runAction->setIcon(QIcon(":/images/run.png"));
00538 runAction->setCheckable(true);
00539 runAction->setChecked(true);
00540 runAction->setEnabled(false);
00541 connect(runAction, SIGNAL(triggered()), this, SLOT(run()));
00542
00543 stopAction = new QAction(tr("&Stop"), this);
00544 stopAction->setIcon(QIcon(":/images/stop.png"));
00545 stopAction->setEnabled(true);
00546 connect(stopAction, SIGNAL(triggered()), this, SLOT(stop()));
00547
00548 exportAction = new QAction(tr("&Export"), this);
00549 exportAction->setShortcut(tr("Ctrl+E"));
00550 connect(exportAction, SIGNAL(triggered()), this, SLOT(exportAs()));
00551
00552 saveAsAction = new QAction(tr("&Save As"), this);
00553 saveAsAction->setShortcut(tr("Ctrl+S"));
00554 connect(saveAsAction, SIGNAL(triggered()), this, SLOT(saveAs()));
00555
00556 openAction = new QAction(tr("&Load"), this);
00557 openAction->setShortcut(tr("Ctrl+L"));
00558 openAction->setEnabled(false);
00559 connect(openAction, SIGNAL(triggered()), this, SLOT(open()));
00560
00561 fileMenu = menuBar()->addMenu(tr("&File"));
00562 fileMenu->addAction(exportAction);
00563 fileMenu->addAction(saveAsAction);
00564 fileMenu->addAction(openAction);
00565 fileMenu->addAction(exitAction);
00566
00567 editMenu = menuBar()->addMenu(tr("&Edit"));
00568 editMenu->addAction(addALinkAction);
00569 editMenu->addAction(addSLinkAction);
00570 editMenu->addAction(addQLinkAction);
00571
00572 editMenu->addSeparator();
00573 editMenu->addAction(joinAction);
00574 editMenu->addAction(deleteAction);
00575 editMenu->addSeparator();
00576 editMenu->addAction(bringToFrontAction);
00577 editMenu->addAction(sendToBackAction);
00578 editMenu->addSeparator();
00579 editMenu->addAction(propertiesAction);
00580
00581
00582
00583 insertMenu = menuBar()->addMenu(tr("&Insert"));
00584
00585 QMap<QString, QList<QString> > itemTypes = designer->getItemTypes();
00586 foreach (QString group, itemTypes.keys()) {
00587 QMenu *submenu = insertMenu->addMenu(group);
00588 submenu->setEnabled(false);
00589 insertSubmenus.append(submenu);
00590
00591 foreach (QString item, itemTypes.value(group))
00592 {
00593 InsertAction *action = new InsertAction(item, this);
00594 action->setEnabled(false);
00595 connect(action, SIGNAL(triggered(QString)), this, SLOT(insertItem(QString)));
00596 submenu->addAction(action);
00597 }
00598 }
00599 insertUserSubmenu = insertMenu->addMenu("User node");
00600 insertUserSubmenu->setEnabled(false);
00601 insertSubmenus.append(insertUserSubmenu);
00602 }
00603
00604 void SlateWindow::includeItemType(QString itemType)
00605 {
00606 InsertAction *action = new InsertAction(itemType, this);
00607 action->setEnabled(false);
00608 connect(action, SIGNAL(triggered(QString)), this, SLOT(insertItem(QString)));
00609 insertUserSubmenu->addAction(action);
00610
00611 updateActions();
00612 }
00613
00614 void SlateWindow::createToolBars()
00615 {
00616 editToolBar = addToolBar(tr("Edit"));
00617 editToolBar->addAction(addALinkAction);
00618 editToolBar->addAction(addSLinkAction);
00619 editToolBar->addAction(addQLinkAction);
00620 editToolBar->addAction(joinAction);
00621 editToolBar->addAction(deleteAction);
00622 editToolBar->addSeparator();
00623 editToolBar->addSeparator();
00624 editToolBar->addAction(bringToFrontAction);
00625 editToolBar->addAction(sendToBackAction);
00626
00627 editToolBar->addSeparator();
00628 editToolBar->addAction(runAction);
00629 editToolBar->addAction(stopAction);
00630 }
00631
00632 Node *SlateWindow::selectedNode() const
00633 {
00634 QList<QGraphicsItem *> items = scene->selectedItems();
00635 if (items.count() == 1) {
00636 return dynamic_cast<Node *>(items.first());
00637 } else {
00638 return 0;
00639 }
00640 }
00641
00642 Link *SlateWindow::selectedLink() const
00643 {
00644 QList<QGraphicsItem *> items = scene->selectedItems();
00645 if (items.count() == 1) {
00646 return dynamic_cast<Link *>(items.first());
00647 } else {
00648 return 0;
00649 }
00650 }
00651
00652 SlateWindow::NodePair SlateWindow::selectedNodePair() const
00653 {
00654 QList<QGraphicsItem *> items = scene->selectedItems();
00655 if (items.count() == 2) {
00656 Node *first = dynamic_cast<Node *>(items.first());
00657 Node *second = dynamic_cast<Node *>(items.last());
00658 if (first && second)
00659 return NodePair(first, second);
00660 }
00661 return NodePair();
00662 }
00663
00664
00665 QList<QGraphicsItem *> SlateWindow::selectedNodeGroup() const
00666 {
00667 QList<QGraphicsItem *> items = onlyParents(scene->selectedItems());
00668
00669
00670 if (items.count() > 1) {
00671
00672 QGraphicsItem * parent = 0;
00673 QMutableListIterator<QGraphicsItem *> i(items);
00674 if (i.hasNext()) parent = i.next()->parentItem();
00675
00676 while (i.hasNext())
00677 if ( i.next()->parentItem() != parent) return QList<QGraphicsItem *>();
00678
00679 return items;
00680 }
00681 return items;
00682 }
00683
00684
00685 QList<QGraphicsItem *> SlateWindow::onlyParents(QList<QGraphicsItem *> items) const
00686 {
00687 QList<QGraphicsItem *> parentItems;
00688
00689 QMutableListIterator<QGraphicsItem *> i(items);
00690 while (i.hasNext()) {
00691 i.next();
00692 bool parent = true;
00693 QMutableListIterator<QGraphicsItem *> j(items);
00694 while (j.hasNext()) {
00695 j.next();
00696 if ( (i.value()) && (i.value()->parentItem() == j.value()) ) {
00697 parent = false;
00698 break;
00699 }
00700 }
00701 if (parent) parentItems.append(i.value());
00702 }
00703
00704 return parentItems;
00705 }
00706
00707 bool SlateWindow::exportAs()
00708 {
00709 QString fileName = QFileDialog::getSaveFileName(this,
00710 tr("Save C++"), ".",
00711 tr("C++ files (*.cpp)"));
00712 if (fileName.isEmpty())
00713 return false;
00714 return saveFile(fileName, false);
00715 }
00716
00717 bool SlateWindow::saveAs()
00718 {
00719 QString fileName = QFileDialog::getSaveFileName(this,
00720 tr("Save XML"), ".",
00721 tr("XML files (*.xml)"));
00722 if (fileName.isEmpty())
00723 return false;
00724 return saveFile(fileName, true);
00725 }
00726
00727 bool SlateWindow::open()
00728 {
00729 QString fileName = QFileDialog::getOpenFileName(this,
00730 tr("Open File"), ".",
00731 tr("XML files (*.xml)"));
00732 if (fileName.isEmpty()) return false;
00733
00734
00735 QFile file(fileName);
00736 if (!file.open(QIODevice::ReadOnly)) {
00737 QMessageBox::warning(this, tr("QVDesignerGUI"),
00738 tr("Cannot open file %1:\n%2.")
00739 .arg(file.fileName())
00740 .arg(file.errorString()));
00741 return false;
00742 }
00743 QTextStream in(&file);
00744 return (designer->loadXML(in.readAll()));
00745 }
00746
00747 bool SlateWindow::saveFile(const QString &fileName, bool xmlFile)
00748 {
00749 QFile file(fileName);
00750 if (!file.open(QIODevice::WriteOnly)) {
00751 QMessageBox::warning(this, tr("QVDesignerGUI"),
00752 tr("Cannot write file %1:\n%2.")
00753 .arg(file.fileName())
00754 .arg(file.errorString()));
00755 return false;
00756 }
00757
00758 QTextStream out(&file);
00759 if (xmlFile)
00760 out << designer->getXMLText();
00761 else
00762 out << designer->getCppText();
00763
00764 return true;
00765 }
00766
00767 void SlateWindow::showMessage(QString message)
00768 {
00769 if (statusbar)
00770 statusbar->showMessage(message, 10000);
00771 }
00772
00773
00774 void SlateWindow::arrangeItems()
00775 {
00776 QList<QList<Node *> *> levels;
00777 int left = 10;
00778 int bottom = 20;
00779 const int MARGIN = 20;
00780
00781
00782 foreach(Node *node, insertNodes) {
00783 int level = node->precursors();
00784 while(levels.size() <= level)
00785 levels.append(new QList<Node *>);
00786 levels[level]->append(node);
00787 }
00788
00789
00790 foreach(QList<Node *> *levelNodes, levels) {
00791 int maxWidth = 0;
00792 if (levelNodes) {
00793 foreach(Node *node, *levelNodes) {
00794 node->setPos(QPoint(left, bottom));
00795 insertNodesPos.insert(insertNodes.key(node), node->pos());
00796 bottom += (int)node->boundingRect().height() + MARGIN;
00797 int width = (int)node->boundingRect().width();
00798 if (maxWidth < width) maxWidth = width;
00799 }
00800 }
00801 left += maxWidth + MARGIN;
00802 bottom = 20;
00803 }
00804
00805
00806 foreach(QList<Node *> *levelNodes, levels) {
00807 levelNodes->clear();
00808 delete levelNodes;
00809 }
00810 }
00811
00812 QPointF SlateWindow::getNodePos(uint id) const
00813 {
00814 return insertNodesPos.value(id);
00815 }
00816
00817 bool SlateWindow::moveNode(uint id, QPointF pos)
00818 {
00819 if (insertNodes.contains(id)) {
00820 Node *node = insertNodes.value(id);
00821 node->setPos(pos);
00822 insertNodesPos.remove(id);
00823 insertNodesPos.insert(id, node->pos());
00824 return true;
00825 }
00826
00827 return false;
00828 }
00829
00830 QList<GroupInfo> SlateWindow::getGroups()
00831 {
00832
00833 foreach(Node *group, createdGroupInfos.keys()) {
00834 createdGroupInfos[group].setPos(group->pos());
00835 }
00836
00837 return createdGroupInfos.values();
00838 }
00839
00840 void SlateWindow::eraseGroups()
00841 {
00842 foreach(Node *group, createdGroupInfos.keys()) {
00843 delete group;
00844 }
00845
00846 createdGroupInfos.clear();
00847 createdGroups.clear();
00848 }
00849
00850 uint SlateWindow::createGroup(GroupInfo info)
00851 {
00852 QList<QGraphicsItem *> group;
00853 foreach (uint nodeId, info.getNodes()) {
00854 if (insertNodes.contains(nodeId)) {
00855 group.append(insertNodes.value(nodeId));
00856 }
00857 else {
00858
00859 return 0;
00860 }
00861 }
00862 foreach (uint subgroupId, info.getSubgroups()) {
00863 if (createdGroups.contains(subgroupId)) {
00864 group.append(createdGroups.value(subgroupId));
00865 }
00866 else {
00867
00868 return 0;
00869 }
00870 }
00871
00872
00873 GroupNode *node = new GroupNode(info.getName(), this, 0, scene);
00874 node->setPos(info.getPos());
00875
00876
00877 if ( !group.isEmpty() && group.first() && group.first()->parentItem() ) {
00878 GroupNode *parentNode = dynamic_cast<GroupNode *>(group.first()->parentItem());
00879 if (parentNode) parentNode->addNode(node);
00880 }
00881
00882
00883 foreach (QGraphicsItem *item, group) {
00884 Node *itemNode = dynamic_cast<Node *>(item);
00885 if (itemNode) {
00886 node->addNode(itemNode);
00887
00888
00889
00890 foreach (Link *link, itemNode->getInLinks()) {
00891 Node *other = link->fromNode();
00892 if (group.contains(other)) {
00893 QPen pen = link->pen();
00894 pen.setWidthF(pen.width()*0.5);
00895 link->setPen(pen);
00896 link->update();
00897 }
00898 }
00899 foreach (Link *link, itemNode->getOutLinks()) {
00900 Node *other = link->toNode();
00901 if (group.contains(other)) {
00902 QPen pen = link->pen();
00903 pen.setWidthF(pen.width()*0.5);
00904 link->setPen(pen);
00905 link->update();
00906 }
00907 }
00908 itemNode->updateLinksPos();
00909 }
00910 }
00911
00912 createdGroupInfos.insert(node, node->getInfo());
00913 createdGroups.insert(node->getId(), node);
00914 node->abstractView(true);
00915
00916 return node->getId();
00917 }
00918
00919
00920