Connector *CircuitICNDocument::createConnector( const QString &startNodeId, const QString &endNodeId, QPointList *pointList ) { ECNode *startNode = getEcNodeWithID(startNodeId); ECNode *endNode = getEcNodeWithID(endNodeId); if ( !startNode || !endNode ) { kDebug() << "Either/both the connector start node and end node could not be found" << endl; return 0L; } if ( !canConnect( startNode, endNode ) ) return 0l; Connector *connector = endNode->createConnector(startNode); if (!connector) { kError() << k_funcinfo << "End node did not create the connector" << endl; return 0l; } startNode->addConnector(connector); flushDeleteList(); // Delete any connectors that might have been removed by the nodes // Set the route to the manual created one if the user created such a route if(pointList) connector->setRoutePoints(*pointList,true); // FIXME WTF is going on here? Redundant/meaningless code? // ConnectorList connectorList; // connectorList.append(connector); setModified(true); requestRerouteInvalidatedConnectors(); return connector; }
Connector * CircuitICNDocument::createConnector( Node *node, Connector *con, const QPoint &pos2, QPointList *pointList ) { if(!canConnect( node, con ) ) return 0; // FIXME dynamic_cast used, fix it in Connector class ECNode *conStartNode = dynamic_cast<ECNode *> (con->startNode() ); ECNode *conEndNode = dynamic_cast<ECNode *> (con->endNode() ); ECNode *ecNode = dynamic_cast<ECNode *> (node ); const bool usedManual = con->usesManualPoints(); ECNode *newNode = new JunctionNode(this, 0, pos2); QPointList autoPoints; if (!pointList) { addAllItemConnectorPoints(); ConRouter cr(this); cr.mapRoute( int(node->x()), int(node->y()), pos2.x(), pos2.y() ); autoPoints = cr.pointList(false); pointList = &autoPoints; } QList<QPointList> oldConPoints = con->splitConnectorPoints(pos2); con->hide(); // The actual new connector Connector *new1 = newNode->createConnector(node); ecNode->addConnector(new1); new1->setRoutePoints(*pointList,usedManual); // The two connectors formed from the original one when split Connector *new2 = newNode->createConnector(conStartNode); conStartNode->addConnector(new2); new2->setRoutePoints( oldConPoints.at(0), usedManual ); Connector *new3 = conEndNode->createConnector(newNode); newNode->addConnector(new3); new3->setRoutePoints( oldConPoints.at(1), usedManual ); // Avoid flicker: tell them to update their draw lists now con->updateConnectorPoints(false); new1->updateDrawList(); new2->updateDrawList(); new3->updateDrawList(); // Now it's safe to remove the connector... con->removeConnector(); flushDeleteList(); deleteNodeGroup(conStartNode); deleteNodeGroup(conEndNode); createNodeGroup(newNode)->init(); return new1; }
void CircuitICNDocument::flushDeleteList() { // Remove duplicate items in the delete list KtlQCanvasItemList::iterator end = m_itemDeleteList.end(); for ( KtlQCanvasItemList::iterator it = m_itemDeleteList.begin(); it != end; ++it ) { if ( *it && (m_itemDeleteList.count( *it ) > 1) ) { *it = 0; } } m_itemDeleteList.remove(0); /* again we're spending time to figure out what special method to call instead of a generic call..*/ end = m_itemDeleteList.end(); for ( KtlQCanvasItemList::iterator it = m_itemDeleteList.begin(); it != end; ++it ) { KtlQCanvasItem *qcanvasItem = *it; m_selectList->removeQCanvasItem ( *it ); if ( Item *item = dynamic_cast<Item*> ( qcanvasItem ) ) m_itemList.remove ( item->id() ); else if ( ECNode * node = dynamic_cast<ECNode*> ( qcanvasItem ) ) m_ecNodeList.remove ( node->id() ); else if ( Connector * con = dynamic_cast<Connector*> ( qcanvasItem ) ) m_connectorList.remove ( con ); else kError() << k_funcinfo << "Unknown qcanvasItem! "<<qcanvasItem << endl; qcanvasItem->setCanvas(0); delete qcanvasItem; *it = 0; } // // Check connectors for merging bool doneJoin = false; const ECNodeMap::iterator nlEnd = m_ecNodeList.end(); for ( ECNodeMap::iterator it = m_ecNodeList.begin(); it != nlEnd; ++it ) { ( *it )->removeNullConnectors(); int conCount = ( *it )->connectorList().count(); if ( conCount == 2 && ! ( *it )->parentItem() ) { if ( joinConnectors ( *it ) ) doneJoin = true; } } if(doneJoin) flushDeleteList(); requestRerouteInvalidatedConnectors(); }
void ItemDocument::paste() { QString xml = KApplication::clipboard()->text(QClipboard::Clipboard); if (xml.isEmpty()) return; unselectAll(); ItemDocumentData data(type()); if (!data.fromXML(xml)) return; data.generateUniqueIDs(this); // data.translateContents( 64, 64 ); data.mergeWithDocument(this, true); // Get rid of any garbage that shouldn't be around / merge connectors / etc flushDeleteList(); requestStateSave(); }
Connector *CircuitICNDocument::createConnector(Connector *con1, Connector *con2, const QPoint &pos1, const QPoint &pos2, QPointList *pointList ) { if ( !canConnect( con1, con2 ) ) return 0; const bool con1UsedManual = con1->usesManualPoints(); const bool con2UsedManual = con2->usesManualPoints(); QList<QPointList> oldCon1Points = con1->splitConnectorPoints(pos1); QList<QPointList> oldCon2Points = con2->splitConnectorPoints(pos2); ECNode *node1a = dynamic_cast<ECNode*> ( con1->startNode() ); ECNode *node1b = dynamic_cast<ECNode*> ( con1->endNode( ) ); ECNode *node2a = dynamic_cast<ECNode*> ( con2->startNode() ); ECNode *node2b = dynamic_cast<ECNode*> ( con2->endNode( ) ); if ( !node1a || !node1b || !node2a || !node2b ) return 0; con1->hide(); con2->hide(); // from this point forward, we are dealing with a circuit document -> all nodes are electronic ECNode *newNode1 = new JunctionNode( this, 0, pos1 ); ECNode *newNode2 = new JunctionNode( this, 0, pos2 ); Connector *con1a = newNode1->createConnector(node1a); node1a->addConnector(con1a); Connector *con1b = newNode1->createConnector(node1b); node1b->addConnector(con1b); Connector *newCon = newNode1->createConnector(newNode2); newNode2->addConnector(newCon); Connector *con2a = node2a->createConnector(newNode2); newNode2->addConnector(con2a); Connector *con2b = node2b->createConnector(newNode2); newNode2->addConnector(con2b); if(!con1a || !con1b || !con2a || !con2b ) { // This should never happen, as the canConnect function should strictly // determine whether the connectors could be created before hand. kWarning() << k_funcinfo << "Not all the connectors were created, this should never happen" << endl; if(con1a) con1a->removeConnector(); if(con1b) con1b->removeConnector(); if(con2a) con2a->removeConnector(); if(con2b) con2b->removeConnector(); newNode1->removeNode(); newNode2->removeNode(); flushDeleteList(); return 0; } con1a->setRoutePoints(oldCon1Points.at(0), con1UsedManual ); con1b->setRoutePoints(oldCon1Points.at(1), con1UsedManual ); con2a->setRoutePoints(oldCon2Points.at(0), con2UsedManual ); con2b->setRoutePoints(oldCon2Points.at(1), con2UsedManual ); QPointList autoPoints; if (!pointList) { addAllItemConnectorPoints(); ConRouter cr(this); cr.mapRoute( pos1.x(), pos1.y(), pos2.x(), pos2.y() ); autoPoints = cr.pointList(false); pointList = &autoPoints; } newCon->setRoutePoints(*pointList,true); // Avoid flicker: tell them to update their draw lists now con1->updateConnectorPoints(false); con2->updateConnectorPoints(false); newCon->updateDrawList(); con1a->updateDrawList(); con1b->updateDrawList(); con2a->updateDrawList(); con2b->updateDrawList(); // Now it's safe to remove the connectors con1->removeConnector(); con2->removeConnector(); flushDeleteList(); deleteNodeGroup(node1a); deleteNodeGroup(node1b); deleteNodeGroup(node2a); deleteNodeGroup(node2b); NodeGroup *ng = createNodeGroup(newNode1); ng->addNode( newNode2, true ); ng->init(); return newCon; }