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; }
bool CircuitICNDocument::joinConnectors( ECNode *node ) { // We don't want to destroy the node if it has a parent if ( node->parentItem() ) return false; node->removeNullConnectors(); // an electronic node can be removed if it has exactly 2 connectors connected to it int conCount = node->getAllConnectors().count(); if ( conCount != 2 ) return false; Connector *con1, *con2; ECNode *startNode = NULL; ECNode *endNode = NULL; QPointList conPoints; con1 = node->connectorList().at(0).data(); con2 = node->connectorList().at(1).data(); if ( con1 == con2 ) return false; // we don't know on which end of the connectors is our node, so we must check both ends // HACK // TODO // dynamic_cast used, because Connector doesn't know about ECNode, only Node if( con1->startNode() == node ) startNode = dynamic_cast<ECNode*> ( con1->endNode() ); else startNode = dynamic_cast<ECNode*> ( con1->startNode() ); if( con2->startNode() == node ) endNode = dynamic_cast<ECNode*> ( con2->endNode() ); else endNode = dynamic_cast<ECNode*> ( con2->startNode() ); conPoints = con1->connectorPoints(false) + con2->connectorPoints(false); if( !startNode || !endNode ) return false; Connector *newCon = endNode->createConnector(startNode); if(!newCon) return false; startNode->addConnector(newCon); newCon->setRoutePoints( conPoints, con1->usesManualPoints() || con2->usesManualPoints() ); // Avoid flicker: update draw lists now con1->updateConnectorPoints(false); con2->updateConnectorPoints(false); newCon->updateDrawList(); node->removeNode(); con1->removeConnector(); con2->removeConnector(); return true; }
void MultiInputGate::updateInputs(int newNum) { if (newNum == m_numInputs) return; if (newNum < 2) newNum = 2; else if (newNum > maxGateInput) newNum = maxGateInput; int newWidth = logicSymbolShapeToWidth(); QRect r(-newWidth / 2, -8 * newNum, newWidth, 16 * newNum); setSize(r, true); updateSymbolText(); const bool added = (newNum > m_numInputs); if (added) { for (int i = m_numInputs; i < newNum; ++i) { ECNode *node = createPin(0, 0, 0, "in" + QString::number(i)); inNode[i] = node; inLogic[i] = new LogicIn(LogicConfig()); setup1pinElement(*(inLogic[i]), node->pin()); inLogic[i]->setCallback(this, (CallbackPtr)(&MultiInputGate::inStateChanged)); } } else { for (int i = newNum; i < m_numInputs; ++i) { removeNode("in" + QString::number(i)); removeElement(inLogic[i], false); inNode[i] = 0; inLogic[i] = 0; } } m_numInputs = newNum; // We can't call a pure-virtual function if we haven't finished our constructor yet... if (m_bDoneInit) inStateChanged(!added); updateAttachedPositioning(); }
void CircuitICNDocument::deleteAllNodes() { const ECNodeMap::iterator nodeListEnd = m_ecNodeList.end(); for ( ECNodeMap::iterator it = m_ecNodeList.begin(); it != nodeListEnd; ++it ) { qDebug() << "CircuitICNDocument::deleteAllNodes removing [" << it.key() << "] " << it.value(); //delete *it; // 2015.07.31 - this will not work // prevent crash on node destructor { ECNode *ecNode = it.value(); //unregisterUID( ecNode->id() ); // do not use, will modify m_ecNodeList ICNDocument::unregisterUID( ecNode->id() ); ecNode->setICNDocument( NULL ); } it.value()->deleteLater(); } m_ecNodeList.clear(); }
ParallelPortComponent::ParallelPortComponent(ICNDocument *icnDocument, bool newItem, const char *id) : DSubCon(icnDocument, newItem, id ? id : "parallel_port") { m_name = i18n("Parallel Port"); Q3PointArray pa(4); pa[0] = QPoint(-32, -112); pa[1] = QPoint(32, -104); pa[2] = QPoint(32, 104); pa[3] = QPoint(-32, 112); setItemPoints(pa); m_pParallelPort = new ParallelPort(); for (unsigned i = 0; i < 24; ++i) m_pLogic[i] = 0; ECNode *pin = 0; //BEGIN Data register for (int i = 0; i < 8; ++i) { QString id = QString("D%1").arg(i); QString name = id; pin = createPin(-40, -80 + 16 * i, 0, id); addDisplayText(id, QRect(-28, -88 + 16 * i, 28, 16), name, true, Qt::AlignLeft | Qt::AlignVCenter); m_pLogic[i] = new LogicOut(LogicConfig(), false); setup1pinElement(*(m_pLogic[i]), createPin(-40, -80 + 16 * i, 0, id)->pin()); // m_pLogic[i]->setCallback(this, (CallbackPtr)(&ParallelPortComponent::dataCallback)); } //END Data register //BEGIN Status register QString statusNames[] = {"ERR", "ON", "PE", "ACK", "BUSY"}; // The statusIDs are referenced in the save file and must not change QString statusIDs[] = {"ERROR", "ONLINE", "PE", "ACK", "BUSY"}; // Bits 0...2 in the Status register are not used for (int i = 3; i < 8; ++i) { QString id = statusIDs[i - 3]; QString name = statusNames[i - 3]; // Bit 3 (pin 15) doesn't not follow the same positioning pattern as // the other pins in the Status register. if (i == 3) { pin = createPin(40, -72, 180, id); addDisplayText(id, QRect(0, -80, 28, 16), name, true, Qt::AlignRight | Qt::AlignVCenter); } else { pin = createPin(-40, -16 + 16 * i, 0, id); addDisplayText(id, QRect(-28, -24 + 16*i, 28, 16), name, true, Qt::AlignLeft | Qt::AlignVCenter); } m_pLogic[i + 8] = new LogicOut(LogicConfig(), false); setup1pinElement(*(m_pLogic[i + 8]), pin->pin()); } //END Status register //BEGIN Control register QString controlNames[] = { "STR", "AUT", "INIT", "SEL" }; // The controlIDs are referenced in the save file and must not change QString controlIDs[] = { "STROBE", "AUTO", "INIT", "SELECT" }; // Bits 4..7 are not used (well; bit 5 is, but not as a pin) for (int i = 0; i < 4; ++i) { QString id = controlIDs[i]; QString name = controlNames[i]; if (i == 0) { pin = createPin(-40, -96, 0, id); addDisplayText(id, QRect(-28, -104, 28, 16), name, true, Qt::AlignLeft | Qt::AlignVCenter); } else if (i == 1) { pin = createPin(40, -88, 180, id); addDisplayText(id, QRect(0, -96, 28, 16), name, true, Qt::AlignRight | Qt::AlignVCenter); } else { pin = createPin(40, -88 + i * 16, 180, id); addDisplayText(id, QRect(0, -96 + i * 16, 28, 16), name, true, Qt::AlignRight | Qt::AlignVCenter); } m_pLogic[i + 16] = new LogicOut(LogicConfig(), false); setup1pinElement(*(m_pLogic[i + 16]), pin->pin()); // m_pLogic[i + 16]->setCallback(this, (CallbackPtr)(&ParallelPortComponent::controlCallback)); } //END Control register #if 0 // And make the rest of the pins ground for (int i = 0; i < 8; ++i) { pin = createPin(40, -24 + i * 16, 180, QString("GND%1").arg(i)); pin->pin()->setGroundType(Pin::gt_always); } #endif Variant *v = createProperty("port", Variant::Type::Combo); v->setAllowed(ParallelPort::ports(Port::ExistsAndRW)); v->setCaption(i18n("Port")); }
SerialPortComponent::SerialPortComponent( ICNDocument *icnDocument, bool newItem, const char *id ) : Component( icnDocument, newItem, id ? id : "serial_port" ) { m_name = i18n("Serial Port"); Q3PointArray pa( 4 ); pa[0] = QPoint( -32, -48 ); pa[1] = QPoint( 32, -40 ); pa[2] = QPoint( 32, 40 ); pa[3] = QPoint( -32, 48 ); setItemPoints( pa ); m_pSerialPort = new SerialPort(); ECNode * pin = 0; // Works pin = createPin( -40, 32, 0, "CD" ); addDisplayText( "CD", QRect( -28, 24, 28, 16 ), "CD", true, Qt::AlignLeft | Qt::AlignVCenter ); m_pCD = createLogicOut( pin, false ); // Doesn't work // pin = createPin( -40, 16, 0, "RD" ); addDisplayText( "RD", QRect( -28, 8, 28, 16 ), "RD", true, Qt::AlignLeft | Qt::AlignVCenter ); // m_pRD = createLogicOut( pin, false ); // Works pin = createPin( -40, 0, 0, "TD" ); addDisplayText( "TD", QRect( -28, -8, 28, 16 ), "TD", true, Qt::AlignLeft | Qt::AlignVCenter ); m_pTD = createLogicIn( pin); m_pTD->setCallback( this, (CallbackPtr)(&SerialPortComponent::tdCallback) ); // Works pin = createPin( -40, -16, 0, "DTR" ); addDisplayText( "DTR", QRect( -28, -24, 28, 16 ), "DTR", true, Qt::AlignLeft | Qt::AlignVCenter ); m_pDTR = createLogicIn( pin ); m_pDTR->setCallback( this, (CallbackPtr)(&SerialPortComponent::dtrCallback) ); // N/A pin = createPin( -40, -32, 0, "GND" ); addDisplayText( "GND", QRect( -28, -40, 28, 16 ), "GND", true, Qt::AlignLeft | Qt::AlignVCenter ); pin->pin()->setGroundType( Pin::gt_always ); // Doesn't work // pin = createPin( 40, 24, 180, "DSR" ); addDisplayText( "DSR", QRect( 0, 16, 28, 16 ), "DSR", true, Qt::AlignRight | Qt::AlignVCenter ); // m_pDSR = createLogicIn( pin ); // m_pDSR->setCallback( this, (CallbackPtr)(&SerialPortComponent::dsrCallback) ); // Doesn't work // pin = createPin( 40, 8, 180, "RTS" ); addDisplayText( "RTS", QRect( 0, 0, 28, 16 ), "RTS", true, Qt::AlignRight | Qt::AlignVCenter ); // m_pRTS = createLogicIn( pin ); // m_pRTS->setCallback( this, (CallbackPtr)(&SerialPortComponent::rtsCallback) ); // Works pin = createPin( 40, -8, 180, "CTS" ); addDisplayText( "CTS", QRect( 0, -16, 28, 16 ), "CTS", true, Qt::AlignRight | Qt::AlignVCenter ); m_pCTS = createLogicOut( pin, false ); // Works pin = createPin( 40, -24, 180, "RI" ); addDisplayText( "RI", QRect( 0, -32, 28, 16 ), "RI", true, Qt::AlignRight | Qt::AlignVCenter ); m_pRI = createLogicOut( pin, false ); Variant * v = createProperty( "port", Variant::Type::Combo ); v->setAllowed( SerialPort::ports( Port::ExistsAndRW ) ); v->setCaption( i18n("Port") ); // v = createProperty( "baudRate", Variant::Type::Select ); // v->setAllowed( QStringList::split( ",", "B0,B50,B75,B110,B134,B150,B200,B300,B600,B1200,B1800,B2400,B4800,B9600,B19200,B38400" ) ); // v->setCaption( i18n("Baud rate") ); // v->setValue("B9600"); }