nodeeditor_doxy
src/Impl/diagramscene.cpp
Go to the documentation of this file.
00001 #include <QtGui>
00002 
00003 #include "diagramscene.h"
00004 /*
00005 #include "nodeconnection.h"
00006 #include "nodeconnector.h"
00007 */
00008 
00010 DiagramScene::DiagramScene(QMenu *itemMenu, QObject *parent)
00011     : QGraphicsScene(parent)
00012 {
00013     mItemMenu = itemMenu;
00014     mMode = MoveItem;
00015     mLineColor = Qt::black;
00016         tmpArrow = NULL;
00017         tmpConnector = NULL;
00018         lastHighlighted = NULL;
00019         mDebugDraw = false;
00020 }
00022 
00024 void DiagramScene::setLineColor(const QColor &color)
00025 {
00026     mLineColor = color;
00027 /*    if (isItemChange(Arrow::Type)) {
00028         Arrow *item =
00029             qgraphicsitem_cast<Arrow *>(selectedItems().first());
00030         item->setColor(mLineColor);
00031         update();
00032     }
00033         */
00034 }
00036 
00037 void DiagramScene::setMode(Mode mode)
00038 {
00039     mMode = mode;
00040 }
00041 
00042 
00043 /*
00044 void DiagramScene::setItemType(DiagramItem::DiagramType type)
00045 {
00046     mItemType = type;
00047 }
00048 
00050 void DiagramScene::editorLostFocus(DiagramTextItem *item)
00051 {
00052     QTextCursor cursor = item->textCursor();
00053     cursor.clearSelection();
00054     item->setTextCursor(cursor);
00055 
00056     if (item->toPlainText().isEmpty()) {
00057         removeItem(item);
00058         item->deleteLater();
00059     }
00060 }
00061 */
00063 
00065 void DiagramScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
00066 {
00067         if (mouseEvent->button() == Qt::LeftButton) {
00068                 QList<QGraphicsItem *> startConnectors = items(mouseEvent->scenePos());
00069                 foreach(QGraphicsItem * g, startConnectors) {
00070                         if (g->type() == NodeConnector::Type) {
00071                                 NodeConnector* start = dynamic_cast<NodeConnector*>(g);
00072                                 //dw ugly
00073                                 if (start->mSingleConnection) {
00074                                         start->deleteConnections();
00075                                 }
00076 
00077                                 tmpConnector = new NodeConnector(NULL, this, NULL,NodeConnector::InOut);
00078                                 tmpConnector->setPos(mouseEvent->scenePos());
00079                                 //dw needed? addItem(tmpConnector);
00080                                 
00081                                 //dw667 backmerge: to slow if connector is child of item
00082                                 //addItem(tmpConnector);
00083                                 
00084                                 if (isDebugDraw()) {
00085                                         //debug draw
00086                                         tmpConnector->mRadius = 5;
00087                                 }
00088                                 else {
00089                                         tmpConnector->setVisible(false);
00090                                         tmpConnector->mRadius = 0;
00091                                 }
00092 
00093 
00094                                 if (start->connectorType() != NodeConnector::In) {
00095                                         tmpArrow = new NodeConnection(start, tmpConnector, NULL, this);
00096                                 }
00097                                 else {
00098                                         tmpArrow = new NodeConnection(tmpConnector, start, NULL, this);
00099                                 }
00100                                 //dw needed? addItem(tmpArrow);
00101                                 start->setHighlight(true);
00102                                 existingConnector = start;
00103 
00104                                 
00105                                 existingConnector->updatePosition();
00106                                 existingConnector->update();
00107                                 tmpConnector->updatePosition();
00108                                 tmpConnector->update();
00109                                 tmpArrow->updatePosition();
00110                                 tmpArrow->update();
00111 
00112                                 //dw667 backmerge: was commented
00113                                 //QGraphicsScene::mousePressEvent(mouseEvent);
00114                                 return;
00115                                 //addItem(tmpArrow);
00116                                 //if (
00117                         }
00118                 }
00119         }
00120 
00121     QGraphicsScene::mousePressEvent(mouseEvent);
00122 }
00124 
00126 void DiagramScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
00127 {
00128     if (tmpArrow != 0) {
00129 
00130                 //simple right/left handling
00131                 if (tmpArrow->startConnector()->mapToScene(0,0).x() < tmpArrow->endConnector()->mapToScene(0,0).x()) {
00132                         if (tmpConnector == tmpArrow->endConnector())
00133                                 tmpConnector->setConnectorAlignment(NodeConnector::ConnectorAlignment::Left);// right = false;
00134                         else
00135                                 //tmpConnector->right = true;
00136                                 tmpConnector->setConnectorAlignment(NodeConnector::ConnectorAlignment::Right);
00137                 }
00138                 else {
00139                         if (tmpConnector == tmpArrow->endConnector())
00140                                 //tmpConnector->right = true;
00141                                 tmpConnector->setConnectorAlignment(NodeConnector::ConnectorAlignment::Right);
00142                         else
00143                                 //tmpConnector->right = false;
00144                                 tmpConnector->setConnectorAlignment(NodeConnector::ConnectorAlignment::Left);
00145                 }
00146 
00147                 // if we hit a connecor, highlight it and take 'right' over, switch in and out if neccessary
00148                 QList<QGraphicsItem *> intersectedItems = items(mouseEvent->scenePos());
00149                 while(intersectedItems.count() && (intersectedItems.first() == tmpArrow || intersectedItems.first() == tmpConnector || intersectedItems.first()->type() != NodeConnector::Type)) {
00150             intersectedItems.removeFirst();
00151                 }
00152                 if (intersectedItems.count() && intersectedItems.first() != tmpConnector && intersectedItems.first() != existingConnector) {
00153                         //dw thats how a cast should look like
00154                         NodeConnector *node = qgraphicsitem_cast<NodeConnector *>(intersectedItems.first());
00155                         //ugly direction handling, only case where a switch is possible
00156                         if (existingConnector->connectorType() == NodeConnector::InOut) {
00157                                 //switch if non matching
00158                                 if ((node->connectorType() == NodeConnector::Out && tmpArrow->startConnector() == existingConnector)
00159                                         || (node->connectorType() == NodeConnector::In && tmpArrow->endConnector() == existingConnector)) {
00160                                         //tmpConnector->setConnectorType(node->connectorType());
00161                                         NodeConnector* old1 = tmpArrow->startConnector();
00162                                         NodeConnector* old2 = tmpArrow->endConnector();
00163                                         //dw needed? removeItem(tmpArrow);
00164                                         //dw667 backmerge: to slow if connector is child of item
00165                                         //removeItem(tmpArrow);
00166                                         delete tmpArrow;
00167                                         tmpArrow = new NodeConnection(old2, old1, NULL, this);
00168                                         //dw667 backmerge: to slow if connector is child of item
00169                                         //addItem(tmpArrow);
00170                                 }
00171                         }
00172                         //check if uncompatible
00173                         else if (node->connectorType() != NodeConnector::InOut && node->connectorType() == existingConnector->connectorType()) {
00174                                 return;
00175                         }
00176 
00177                         node->setHighlight(true);
00178                         /*node->updatePosition();
00179                         node->update();*/
00180                         //dw667 backmerge:
00181                         node->updatePosition();
00182                         node->update();
00183                         
00184                         tmpConnector->setConnectorAlignment(node->connectorAlignment());
00185                         tmpConnector->setConnectorType(node->connectorType());
00186                         //FIXME: make configurable
00187                         tmpArrow->setBidirectional(true);
00188 
00189                         tmpConnector->updatePosition();
00190                         tmpConnector->update();
00191                         lastHighlighted = node;
00192                 }
00193                 else if (lastHighlighted != NULL) {
00194                         lastHighlighted->setHighlight(false);
00195                         /*lastHighlighted->updatePosition();
00196                         lastHighlighted->update();*/
00197                         //dw667 backmerge:
00198                         lastHighlighted->updatePosition();
00199                         lastHighlighted->update();
00200                         
00201                         lastHighlighted = NULL;
00202                         tmpConnector->updatePosition();
00203                         tmpConnector->update();
00204                 }
00205 
00206         //QLineF newLine(line->line().p1(), mouseEvent->scenePos());
00207                 //line->setLine(newLine);
00208                 //tmpConnector = new NodeConnector(NULL, scene, NULL, NodeConnector::InOut);
00209                 //tmpConnector-> = new NodeConnector(NULL, scene, NULL, NodeConnector::InOut);
00210                 tmpConnector->setPos(mouseEvent->scenePos());
00211                 tmpArrow->updatePosition();
00212                 tmpArrow->update();
00213                 //dw667 backmerge: was commented
00214                 tmpConnector->updatePosition();
00215                 
00216                 tmpConnector->update();
00217                 return;
00218     }
00219         QGraphicsScene::mouseMoveEvent(mouseEvent);
00220 }
00222 
00224 void DiagramScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
00225 {
00226     if (tmpArrow != 0) {
00227                 NodeConnector* startC = tmpArrow->startConnector();
00228                 NodeConnector* endC = tmpArrow->endConnector();
00229                 QPointF startPos(startC->mapToScene(0, 0));
00230                 QPointF endPos(endC->mapToScene(0, 0));
00231                 //QPointF endPos(mouseEvent->scenePos());
00232 
00233                 tmpArrow->startConnector()->setHighlight(false);
00234                 tmpArrow->endConnector()->setHighlight(false);
00235                 /*tmpArrow->startConnector()->updatePosition();
00236                 tmpArrow->startConnector()->update();
00237                 tmpArrow->endConnector()->updatePosition();
00238                 tmpArrow->endConnector()->update();*/
00239 
00240                 QList<QGraphicsItem *> startConnectors = items(startPos);
00241                 while(startConnectors.count() && (startConnectors.first() == tmpArrow || startConnectors.first() == tmpConnector || startConnectors.first()->type() != NodeConnector::Type)) {
00242             startConnectors.removeFirst();
00243                 }
00244                 QList<QGraphicsItem *> endConnectors = items(endPos);
00245                 while(endConnectors.count() && (endConnectors.first() == tmpArrow || endConnectors.first() == tmpConnector || endConnectors.first()->type() != NodeConnector::Type)) {
00246             endConnectors.removeFirst();
00247                 }
00248 
00249                 //removeItem(tmpArrow);
00250 
00251         delete tmpArrow;
00252                 tmpArrow = 0;
00253                 //dw now done in dtor, good idea?
00254                 //dw new
00255                 //removeItem(tmpConnector);
00256         delete tmpConnector;
00257                 //tmpConnector->deleteLater();
00258                 tmpConnector = 0;
00259         
00260                 if (startConnectors.count() > 0 && endConnectors.count() > 0 &&
00261             startConnectors.first()->type() == NodeConnector::Type &&
00262                         endConnectors.first()->type() == NodeConnector::Type &&
00263             startConnectors.first() != endConnectors.first())
00264                 {
00265             NodeConnector *startConnector =
00266                 qgraphicsitem_cast<NodeConnector *>(startConnectors.first());
00267             NodeConnector *endConnector =
00268                 qgraphicsitem_cast<NodeConnector *>(endConnectors.first());
00269 
00270                         //dw new: verify again:
00271                         if (!((startConnector->connectorType() == NodeConnector::In && endConnector->connectorType() == NodeConnector::In) || (startConnector->connectorType() == NodeConnector::Out && endConnector->connectorType() == NodeConnector::Out)))
00272                         {
00273                                 NodeConnection *arrow = new NodeConnection(startConnector, endConnector, NULL, this);
00274                                 arrow->setColor(mLineColor);
00275                                 startConnector->addConnection(arrow);
00276                                 endConnector->addConnection(arrow);
00277                                 arrow->setZValue(-1000.0);
00278 
00279                                 arrow->startConnector()->setHighlight(false);
00280                                 arrow->endConnector()->setHighlight(false);
00281                                 arrow->startConnector()->update();
00282                                 arrow->endConnector()->update();
00283                         }
00284 
00285 //            arrow->setZValue(2.0);
00286             //addItem(arrow);
00287                         startConnector->setHighlight(false);
00288                         endConnector->setHighlight(false);
00289             //arrow->updatePosition();
00290                         //dw new
00291 
00292                         /*startConnector->updatePosition();
00293                         startConnector->update();
00294                         endConnector->updatePosition();
00295                         endConnector->update();*/
00296         }
00297                         //NOTE: assumtion that lastHighlighted is never deleted while drawing lines, otherwise pointer can go to nirvana (TODO: can we use this assumtion?)
00298                 if (lastHighlighted != NULL) {
00299                         lastHighlighted->setHighlight(false);
00300                         /*lastHighlighted->updatePosition();
00301                         lastHighlighted->update();*/
00302                         lastHighlighted = NULL;
00303                 }
00304                 return;
00305     }
00306 
00308     //line = 0;
00309     QGraphicsScene::mouseReleaseEvent(mouseEvent);
00310 }
00312 
00314 bool DiagramScene::isItemChange(int type)
00315 {
00316     foreach (QGraphicsItem *item, selectedItems()) {
00317         if (item->type() == type)
00318             return true;
00319     }
00320     return false;
00321 }
00322 
00323 
00324 void DiagramScene::setDebugDraw(bool enabled) {
00325         mDebugDraw = enabled;
00326         this->update();
00327 }
00328 
00329 
00330 
00331