00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "canvasmanipulator.h"
00012 #include "circuitdocument.h"
00013 #include "circuitview.h"
00014 #include "component.h"
00015 #include "connector.h"
00016 #include "core/ktlconfig.h"
00017 #include "cnitemgroup.h"
00018 #include "documentiface.h"
00019 #include "drawpart.h"
00020 #include "ecnode.h"
00021 #include "itemdocumentdata.h"
00022 #include "ktechlab.h"
00023 #include "pin.h"
00024 #include "simulator.h"
00025 #include "subcircuits.h"
00026 #include "switch.h"
00027
00028 #include <kdebug.h>
00029 #include <kinputdialog.h>
00030 #include <klocale.h>
00031 #include <kmessagebox.h>
00032 #include <qregexp.h>
00033 #include <qtimer.h>
00034 #include <cassert>
00035
00036 CircuitDocument::CircuitDocument( const QString & caption, KTechlab *ktechlab, const char *name )
00037 : ICNDocument( caption, ktechlab, name )
00038 {
00039 m_pOrientationAction = new KActionMenu( i18n("Orientation"), "rotate", this );
00040
00041 m_type = Document::dt_circuit;
00042 m_pDocumentIface = new CircuitDocumentIface(this);
00043 m_fileExtensionInfo = i18n("*.circuit|Circuit(*.circuit)\n*|All Files");
00044
00045 m_cmManager->addManipulatorInfo( CMSelect::manipulatorInfo() );
00046 m_cmManager->addManipulatorInfo( CMDraw::manipulatorInfo() );
00047 m_cmManager->addManipulatorInfo( CMRightClick::manipulatorInfo() );
00048 m_cmManager->addManipulatorInfo( CMRepeatedItemAdd::manipulatorInfo() );
00049 m_cmManager->addManipulatorInfo( CMItemResize::manipulatorInfo() );
00050 m_cmManager->addManipulatorInfo( CMItemDrag::manipulatorInfo() );
00051
00052 connect( this, SIGNAL(connectorAdded(Connector*)), this, SLOT(requestAssignCircuits()) );
00053 connect( this, SIGNAL(connectorAdded(Connector*)), this, SLOT(connectorAdded(Connector*)) );
00054
00055 m_updateCircuitsTmr = new QTimer();
00056 connect( m_updateCircuitsTmr, SIGNAL(timeout()), this, SLOT(assignCircuits()) );
00057
00058 requestStateSave();
00059 }
00060
00061 CircuitDocument::~CircuitDocument()
00062 {
00063 m_bDeleted = true;
00064 deleteCircuits();
00065
00066 delete m_updateCircuitsTmr;
00067 delete m_pDocumentIface;
00068 }
00069
00070 void CircuitDocument::slotInitItemActions( Item *itemBase )
00071 {
00072 ICNDocument::slotInitItemActions(itemBase);
00073
00074 CircuitView * activeCircuitView = dynamic_cast<CircuitView*>(activeView());
00075 if ( !p_ktechlab || !activeCircuitView )
00076 return;
00077
00078 Component * item = dynamic_cast<Component*>(itemBase);
00079
00080 if ( !item && m_selectList->count() > 0 || !m_selectList->itemsAreSameType() )
00081 return;
00082
00083 KAction * orientation_actions[] = {
00084 activeCircuitView->action("edit_orientation_0"),
00085 activeCircuitView->action("edit_orientation_90"),
00086 activeCircuitView->action("edit_orientation_180"),
00087 activeCircuitView->action("edit_orientation_270") };
00088
00089 if ( !item || !item->canRotate() ) {
00090 for ( unsigned i = 0; i < 4; ++i )
00091 orientation_actions[i]->setEnabled(false);
00092 return;
00093 }
00094
00095 for ( unsigned i = 0; i < 4; ++ i) {
00096 orientation_actions[i]->setEnabled(true);
00097 m_pOrientationAction->remove( orientation_actions[i] );
00098 m_pOrientationAction->insert( orientation_actions[i] );
00099 }
00100
00101 if ( item->angleDegrees() == 0 )
00102 (static_cast<KToggleAction*>( orientation_actions[0] ))->setChecked(true);
00103 else if ( item->angleDegrees() == 90 )
00104 (static_cast<KToggleAction*>( orientation_actions[1] ))->setChecked(true);
00105 else if ( item->angleDegrees() == 180 )
00106 (static_cast<KToggleAction*>( orientation_actions[2] ))->setChecked(true);
00107 else if ( item->angleDegrees() == 270 )
00108 (static_cast<KToggleAction*>( orientation_actions[3] ))->setChecked(true);
00109 }
00110
00111 void CircuitDocument::rotateCounterClockwise()
00112 {
00113 m_selectList->slotRotateCCW();
00114 requestRerouteInvalidatedConnectors();
00115 }
00116
00117 void CircuitDocument::rotateClockwise()
00118 {
00119 m_selectList->slotRotateCW();
00120 requestRerouteInvalidatedConnectors();
00121 }
00122
00123 void CircuitDocument::itemFlip()
00124 {
00125 m_selectList->slotFlip();
00126 requestRerouteInvalidatedConnectors();
00127 }
00128
00129 void CircuitDocument::setOrientation0()
00130 {
00131 m_selectList->slotSetOrientation0();
00132 requestRerouteInvalidatedConnectors();
00133 }
00134
00135 void CircuitDocument::setOrientation90()
00136 {
00137 m_selectList->slotSetOrientation90();
00138 requestRerouteInvalidatedConnectors();
00139 }
00140
00141 void CircuitDocument::setOrientation180()
00142 {
00143 m_selectList->slotSetOrientation180();
00144 requestRerouteInvalidatedConnectors();
00145 }
00146
00147 void CircuitDocument::setOrientation270()
00148 {
00149 m_selectList->slotSetOrientation270();
00150 requestRerouteInvalidatedConnectors();
00151 }
00152
00153 View *CircuitDocument::createView( ViewContainer *viewContainer, uint viewAreaId, const char *name )
00154 {
00155 View *view = new CircuitView( this, viewContainer, viewAreaId, name );
00156 handleNewView(view);
00157 return view;
00158 }
00159
00160 void CircuitDocument::slotUpdateConfiguration()
00161 {
00162 ICNDocument::slotUpdateConfiguration();
00163
00164 NodeList::iterator nodeEnd = m_nodeList.end();
00165 for(NodeList::iterator it = m_nodeList.begin(); it != nodeEnd; ++it) {
00166 (static_cast<ECNode*>((Node*)*it))->setShowVoltageBars( KTLConfig::showVoltageBars() );
00167 }
00168
00169 ComponentList::iterator componentsEnd = m_componentList.end();
00170 for(ComponentList::iterator it = m_componentList.begin(); it != componentsEnd; ++it)
00171 (*it)->slotUpdateConfiguration();
00172 }
00173
00174 void CircuitDocument::update()
00175 {
00176 ICNDocument::update();
00177
00178 if(KTLConfig::showVoltageBars()) {
00179 NodeList::iterator end = m_nodeList.end();
00180 for(NodeList::iterator it = m_nodeList.begin(); it != end; ++it ) {
00181 (static_cast<ECNode*>((Node*)*it))->setNodeChanged();
00182 }
00183 }
00184 }
00185
00186 void CircuitDocument::fillContextMenu( const QPoint &pos )
00187 {
00188 ICNDocument::fillContextMenu(pos);
00189
00190 CircuitView *activeCircuitView = dynamic_cast<CircuitView*>(activeView());
00191
00192 if(m_selectList->count() < 1 || !activeCircuitView ) return;
00193
00194 Component *item = dynamic_cast<Component*>( selectList()->activeItem() );
00195
00196
00197
00198 if(!(!item && m_selectList->count() > 0 || !m_selectList->itemsAreSameType() )) {
00199 KAction *orientation_actions[] = {
00200 activeCircuitView->action("edit_orientation_0"),
00201 activeCircuitView->action("edit_orientation_90"),
00202 activeCircuitView->action("edit_orientation_180"),
00203 activeCircuitView->action("edit_orientation_270") };
00204
00205 if(!item || !item->canRotate() ) return;
00206
00207 for(unsigned i = 0; i < 4; ++ i) {
00208 m_pOrientationAction->remove( orientation_actions[i] );
00209 m_pOrientationAction->insert( orientation_actions[i] );
00210 }
00211
00212 QPtrList<KAction> orientation_actionlist;
00213
00214 orientation_actionlist.append( m_pOrientationAction );
00215 p_ktechlab->plugActionList( "orientation_actionlist", orientation_actionlist );
00216 }
00217
00218 if(m_selectList->count() > 1 && countExtCon(m_selectList->items()) > 0) {
00219 QPtrList<KAction> component_actionlist;
00220
00221 component_actionlist.append( activeCircuitView->action("circuit_create_subcircuit") );
00222 p_ktechlab->plugActionList( "component_actionlist", component_actionlist );
00223 }
00224 }
00225
00226 void CircuitDocument::deleteCircuits()
00227 {
00228 const CircuitList::iterator end = m_circuitList.end();
00229 for(CircuitList::iterator it = m_circuitList.begin(); it != end; ++it ) {
00230 Simulator::self()->detachCircuit(*it);
00231 delete *it;
00232 }
00233
00234 m_circuitList.clear();
00235 m_pinList.clear();
00236 m_wireList.clear();
00237 }
00238
00239 void CircuitDocument::requestAssignCircuits() {
00240
00241 deleteCircuits();
00242 m_updateCircuitsTmr->stop();
00243 m_updateCircuitsTmr->start( 0, true );
00244 }
00245
00246 void CircuitDocument::connectorAdded( Connector * connector )
00247 {
00248 if (connector) {
00249 connect( connector, SIGNAL(numWiresChanged(unsigned )), this, SLOT(requestAssignCircuits()) );
00250 connect( connector, SIGNAL(removed(Connector*)), this, SLOT(requestAssignCircuits()) );
00251 }
00252 }
00253
00254 void CircuitDocument::itemAdded( Item * item)
00255 {
00256 ICNDocument::itemAdded( item );
00257 componentAdded( item );
00258 }
00259
00260 void CircuitDocument::componentAdded( Item * item )
00261 {
00262 Component *component = dynamic_cast<Component*>(item);
00263
00264 if(!component) return;
00265
00266 requestAssignCircuits();
00267
00268 connect( component, SIGNAL(elementCreated(Element*)), this, SLOT(requestAssignCircuits()) );
00269 connect( component, SIGNAL(elementDestroyed(Element*)), this, SLOT(requestAssignCircuits()) );
00270 connect( component, SIGNAL(removed(Item*)), this, SLOT(componentRemoved(Item*)) );
00271
00272
00273
00274
00275 if ( !m_toSimulateList.contains(component) )
00276 m_toSimulateList << component;
00277 }
00278
00279 void CircuitDocument::componentRemoved( Item * item )
00280 {
00281 Component *component = dynamic_cast<Component*>(item);
00282
00283 if (!component) return;
00284
00285 m_componentList.remove(component);
00286
00287 requestAssignCircuits();
00288 Simulator::self()->detachComponent(component);
00289 }
00290
00291 void CircuitDocument::calculateConnectorCurrents()
00292 {
00293 const CircuitList::iterator circuitEnd = m_circuitList.end();
00294 for(CircuitList::iterator it = m_circuitList.begin(); it != circuitEnd; ++it )
00295 (*it)->updateCurrents();
00296
00297 PinList groundPins;
00298
00299
00300
00301 m_pinList.remove((Pin*)0);
00302 const PinList::iterator pinEnd = m_pinList.end();
00303 for(PinList::iterator it = m_pinList.begin(); it != pinEnd; ++it ) {
00304 if(Pin *n = dynamic_cast<Pin*>((Pin*)*it) ) {
00305 n->resetCurrent();
00306 n->setSwitchCurrentsUnknown();
00307
00308 if ( !n->parentECNode()->isChildNode() ) {
00309 n->setCurrentKnown( true );
00310
00311 } else if ( n->groundType() == Pin::gt_always ) {
00312 groundPins << n;
00313 n->setCurrentKnown( false );
00314 } else {
00315
00316 n->setCurrentKnown( n->parentECNode()->numPins() < 2 );
00317 }
00318 }
00319 }
00320
00321
00322 const ComponentList::iterator componentEnd = m_componentList.end();
00323 for ( ComponentList::iterator it = m_componentList.begin(); it != componentEnd; ++it ) (*it)->setNodalCurrents();
00324
00325
00326 m_wireList.remove((Wire*)0);
00327 const WireList::iterator clEnd = m_wireList.end();
00328 for ( WireList::iterator it = m_wireList.begin(); it != clEnd; ++it )
00329 (*it)->setCurrentKnown(false);
00330
00331 SwitchList switches = m_switchList;
00332 WireList wires = m_wireList;
00333 bool found = true;
00334 while((!wires.isEmpty() || !switches.isEmpty() || !groundPins.isEmpty()) && found ) {
00335 found = false;
00336
00337 WireList::iterator wiresEnd = wires.end();
00338 for ( WireList::iterator it = wires.begin(); it != wiresEnd; )
00339 {
00340 if ( (*it)->calculateCurrent() ) {
00341 found = true;
00342 WireList::iterator oldIt = it;
00343 ++it;
00344 wires.remove(oldIt);
00345 } else ++it;
00346 }
00347
00348 SwitchList::iterator switchesEnd = switches.end();
00349 for(SwitchList::iterator it = switches.begin(); it != switchesEnd; ) {
00350 if ( (*it)->calculateCurrent() ) {
00351 found = true;
00352 SwitchList::iterator oldIt = it;
00353 ++it;
00354 switches.remove(oldIt);
00355 } else ++it;
00356 }
00357
00358 PinList::iterator groundPinsEnd = groundPins.end();
00359 for(PinList::iterator it = groundPins.begin(); it != groundPinsEnd; ) {
00360 if ( (*it)->calculateCurrentFromWires() )
00361 {
00362 found = true;
00363 PinList::iterator oldIt = it;
00364 ++it;
00365 groundPins.remove(oldIt);
00366 } else ++it;
00367 }
00368 }
00369 }
00370
00371 void CircuitDocument::assignCircuits()
00372 {
00373
00374 const ComponentList::iterator toSimulateEnd = m_toSimulateList.end();
00375 for ( ComponentList::iterator it = m_toSimulateList.begin(); it != toSimulateEnd; ++it )
00376 Simulator::self()->attachComponent(*it);
00377 m_toSimulateList.clear();
00378
00379
00380 m_pinList.clear();
00381 const NodeList::const_iterator nodeListEnd = m_nodeList.end();
00382 for ( NodeList::const_iterator it = m_nodeList.begin(); it != nodeListEnd; ++it ) {
00383 if ( ECNode * ecnode = dynamic_cast<ECNode*>((Node*)*it) ) {
00384 for ( unsigned i = 0; i < ecnode->numPins(); i++ )
00385 m_pinList << ecnode->pin(i);
00386 }
00387 }
00388
00389 m_wireList.clear();
00390 const ConnectorList::const_iterator connectorListEnd = m_connectorList.end();
00391 for ( ConnectorList::const_iterator it = m_connectorList.begin(); it != connectorListEnd; ++it ) {
00392 for ( unsigned i = 0; i < (*it)->numWires(); i++ )
00393 m_wireList << (*it)->wire(i);
00394 }
00395
00396 typedef QValueList<PinList> PinListList;
00397
00398
00399
00400 PinList unassignedPins = m_pinList;
00401 PinListList pinListList;
00402
00403 while(!unassignedPins.isEmpty() ) {
00404 PinList pinList;
00405 getPartition( *unassignedPins.begin(), & pinList, & unassignedPins );
00406 pinListList.append(pinList);
00407 }
00408
00409
00410
00411 const PinListList::iterator nllEnd = pinListList.end();
00412
00413 for ( PinListList::iterator it = pinListList.begin(); it != nllEnd; ++it )
00414 splitIntoCircuits(&*it);
00415
00416
00417 m_circuitList.remove(0);
00418 CircuitList::iterator circuitListEnd = m_circuitList.end();
00419
00420 for(CircuitList::iterator it = m_circuitList.begin(); it != circuitListEnd; ++it) (*it)->init();
00421
00422 m_switchList.clear();
00423 m_componentList.clear();
00424 const ItemList::const_iterator cilEnd = m_itemList.end();
00425
00426 for(ItemList::const_iterator it = m_itemList.begin(); it != cilEnd; ++it ) {
00427 Component * component = dynamic_cast<Component*>((Item*)(*it));
00428 if ( !component ) continue;
00429
00430 m_componentList << component;
00431 component->initElements(0);
00432 m_switchList += component->switchList();
00433 }
00434
00435 circuitListEnd = m_circuitList.end();
00436 for ( CircuitList::iterator it = m_circuitList.begin(); it != circuitListEnd; ++it )
00437 (*it)->createMatrixMap();
00438
00439 for(ItemList::const_iterator it = m_itemList.begin(); it != cilEnd; ++it ) {
00440 Component * component = dynamic_cast<Component*>((Item*)(*it));
00441 if (component)
00442 component->initElements(1);
00443 }
00444
00445 circuitListEnd = m_circuitList.end();
00446 for ( CircuitList::iterator it = m_circuitList.begin(); it != circuitListEnd; ++it ) {
00447 (*it)->initCache();
00448 Simulator::self()->attachCircuit(*it);
00449 }
00450 }
00451
00452 void CircuitDocument::getPartition( Pin *pin, PinList *pinList, PinList *unassignedPins, bool onlyGroundDependent ) {
00453 if(!pin) return;
00454
00455 unassignedPins->remove(pin);
00456
00457 if ( pinList->contains(pin) ) return;
00458
00459 pinList->append(pin);
00460
00461 const PinList localConnectedPins = pin->localConnectedPins();
00462 const PinList::const_iterator end = localConnectedPins.end();
00463
00464 for ( PinList::const_iterator it = localConnectedPins.begin(); it != end; ++it )
00465 getPartition( *it, pinList, unassignedPins, onlyGroundDependent );
00466
00467 const PinList groundDependentPins = pin->groundDependentPins();
00468 const PinList::const_iterator dEnd = groundDependentPins.end();
00469
00470 for ( PinList::const_iterator it = groundDependentPins.begin(); it != dEnd; ++it )
00471 getPartition( *it, pinList, unassignedPins, onlyGroundDependent );
00472
00473 if (!onlyGroundDependent) {
00474 PinList circuitDependentPins = pin->circuitDependentPins();
00475 const PinList::const_iterator dEnd = circuitDependentPins.end();
00476 for ( PinList::const_iterator it = circuitDependentPins.begin(); it != dEnd; ++it )
00477 getPartition( *it, pinList, unassignedPins, onlyGroundDependent );
00478 }
00479 }
00480
00481 void CircuitDocument::splitIntoCircuits( PinList *pinList )
00482 {
00483
00484 PinList unassignedPins = *pinList;
00485
00486 typedef QValueList<PinList> PinListList;
00487
00488 PinListList pinListList;
00489 while ( !unassignedPins.isEmpty() ) {
00490 PinList tempPinList;
00491 getPartition( *unassignedPins.begin(), & tempPinList, & unassignedPins, true );
00492 pinListList.append(tempPinList);
00493 }
00494
00495 const PinListList::iterator nllEnd = pinListList.end();
00496 for(PinListList::iterator it = pinListList.begin(); it != nllEnd; ++it )
00497 Circuit::identifyGround(*it);
00498
00499 bool allGround = false;
00500 while(!pinList->isEmpty() && !allGround ) {
00501 PinList::iterator end = pinList->end();
00502 PinList::iterator it = pinList->begin();
00503
00504 while(it != end && (*it)->eqId() == -1 )
00505 ++it;
00506
00507 if ( it == end ) allGround = true;
00508 else {
00509 Circuitoid *circuitoid = new Circuitoid;
00510 recursivePinAdd( *it, circuitoid, pinList );
00511
00512 if ( !tryAsLogicCircuit(circuitoid) )
00513 m_circuitList += createCircuit(circuitoid);
00514
00515 delete circuitoid;
00516 }
00517 }
00518
00519
00520
00521 const PinList::iterator end = pinList->end();
00522 for(PinList::iterator it = pinList->begin(); it != end; ++it ) {
00523 (*it)->setVoltage(0.0);
00524
00525 ElementList elements = (*it)->elements();
00526 const ElementList::iterator eEnd = elements.end();
00527 for(ElementList::iterator it = elements.begin(); it != eEnd; ++it )
00528 {
00529 if(LogicIn * logicIn = dynamic_cast<LogicIn*>(*it) ) {
00530 logicIn->setLastState(false);
00531 logicIn->callCallback();
00532 }
00533 }
00534 }
00535 }
00536
00537 void CircuitDocument::recursivePinAdd( Pin *pin, Circuitoid *circuitoid, PinList *unassignedPins )
00538 {
00539 if (!pin) return;
00540
00541 if ( pin->eqId() != -1 )
00542 unassignedPins->remove(pin);
00543
00544 if ( circuitoid->contains(pin) ) return;
00545
00546 circuitoid->addPin(pin);
00547
00548 if ( pin->eqId() == -1 ) return;
00549
00550 const PinList localConnectedPins = pin->localConnectedPins();
00551 const PinList::const_iterator end = localConnectedPins.end();
00552
00553 for ( PinList::const_iterator it = localConnectedPins.begin(); it != end; ++it )
00554 recursivePinAdd( *it, circuitoid, unassignedPins );
00555
00556 const WireList inputList = pin->inputWireList();
00557 WireList::const_iterator conEnd = inputList.end();
00558
00559 for ( WireList::const_iterator it = inputList.begin(); it != conEnd; ++it )
00560 circuitoid->addWire(*it);
00561
00562 const WireList outputList = pin->outputWireList();
00563 conEnd = outputList.end();
00564
00565 for ( WireList::const_iterator it = outputList.begin(); it != conEnd; ++it )
00566 circuitoid->addWire(*it);
00567
00568 const PinList groundDependentPins = pin->groundDependentPins();
00569 const PinList::const_iterator gdEnd = groundDependentPins.end();
00570
00571 for ( PinList::const_iterator it = groundDependentPins.begin(); it != gdEnd; ++it )
00572 recursivePinAdd( *it, circuitoid, unassignedPins );
00573
00574 const PinList circuitDependentPins = pin->circuitDependentPins();
00575 const PinList::const_iterator cdEnd = circuitDependentPins.end();
00576
00577 for ( PinList::const_iterator it = circuitDependentPins.begin(); it != cdEnd; ++it )
00578 recursivePinAdd( *it, circuitoid, unassignedPins );
00579
00580 const ElementList elements = pin->elements();
00581 const ElementList::const_iterator eEnd = elements.end();
00582
00583 for ( ElementList::const_iterator it = elements.begin(); it != eEnd; ++it )
00584 circuitoid->addElement(*it);
00585 }
00586
00587 bool CircuitDocument::tryAsLogicCircuit( Circuitoid *circuitoid )
00588 {
00589 if (!circuitoid) return false;
00590
00591 if ( circuitoid->elementList.size() == 0 )
00592 {
00593
00594
00595 const PinList::const_iterator pinListEnd = circuitoid->pinList.constEnd();
00596 for ( PinList::const_iterator it = circuitoid->pinList.constBegin(); it != pinListEnd; ++it )
00597 (*it)->setVoltage(0.0);
00598
00599
00600
00601 return true;
00602 }
00603
00604 LogicInList logicInList;
00605 LogicOut *out = 0;
00606
00607 uint logicInCount = 0;
00608 uint logicOutCount = 0;
00609 ElementList::const_iterator end = circuitoid->elementList.end();
00610 for ( ElementList::const_iterator it = circuitoid->elementList.begin(); it != end; ++it ) {
00611 if ( (*it)->type() == Element::Element_LogicOut ) {
00612 logicOutCount++;
00613 out = static_cast<LogicOut*>(*it);
00614 } else if ( (*it)->type() == Element::Element_LogicIn ) {
00615 logicInCount++;
00616 logicInList += static_cast<LogicIn*>(*it);
00617 } else return false;
00618 }
00619
00620 if ( logicOutCount > 1 ) return false;
00621 else if ( logicOutCount == 1 )
00622 Simulator::self()->createLogicChain( out, logicInList, circuitoid->pinList );
00623 else {
00624
00625
00626 const PinList::const_iterator pinListEnd = circuitoid->pinList.constEnd();
00627 for ( PinList::const_iterator it = circuitoid->pinList.constBegin(); it != pinListEnd; ++it )
00628 (*it)->setVoltage(0.0);
00629
00630 for(ElementList::const_iterator it = circuitoid->elementList.begin(); it != end; ++it) {
00631 LogicIn * logicIn = static_cast<LogicIn*>(*it);
00632 logicIn->setNextLogic(0);
00633 logicIn->setElementSet(0);
00634 if ( logicIn->isHigh() ) {
00635 logicIn->setLastState(false);
00636 logicIn->callCallback();
00637 }
00638 }
00639 }
00640
00641 return true;
00642 }
00643
00644 Circuit *CircuitDocument::createCircuit( Circuitoid *circuitoid )
00645 {
00646 if (!circuitoid) return 0;
00647
00648 Circuit *circuit = new Circuit();
00649
00650 const PinList::const_iterator nEnd = circuitoid->pinList.end();
00651 for ( PinList::const_iterator it = circuitoid->pinList.begin(); it != nEnd; ++it )
00652 circuit->addPin(*it);
00653
00654 const ElementList::const_iterator eEnd = circuitoid->elementList.end();
00655 for ( ElementList::const_iterator it = circuitoid->elementList.begin(); it != eEnd; ++it )
00656 circuit->addElement(*it);
00657
00658 return circuit;
00659 }
00660
00661 void CircuitDocument::createSubcircuit()
00662 {
00663 ItemList itemList = m_selectList->items();
00664 const ItemList::iterator itemListEnd = itemList.end();
00665 for ( ItemList::iterator it = itemList.begin(); it != itemListEnd; ++it ) {
00666 if( !dynamic_cast<Component*>((Item*)*it) ) *it = 0;
00667 }
00668
00669 itemList.remove((Item*)0);
00670
00671 if ( itemList.isEmpty() ) {
00672 KMessageBox::sorry( activeView(), i18n("No components were found in the selection.") );
00673 return;
00674 }
00675
00676
00677 const int extConCount = countExtCon(itemList);
00678 if ( extConCount == 0 ) {
00679 KMessageBox::sorry( activeView(), i18n("No External Connection components were found in the selection.") );
00680 return;
00681 }
00682
00683 bool ok;
00684 const QString name = KInputDialog::getText( "Subcircuit", "Name", QString::null, &ok, activeView() );
00685
00686 if (!ok) return;
00687
00688 SubcircuitData subcircuit;
00689 subcircuit.addItems(itemList);
00690 subcircuit.addNodes( getCommonNodes(itemList) );
00691 subcircuit.addConnectors( getCommonConnectors(itemList) );
00692
00693 Subcircuits::addSubcircuit( name, subcircuit.toXML() );
00694 }
00695
00696 int CircuitDocument::countExtCon( const ItemList &itemList ) const
00697 {
00698 int count = 0;
00699 const ItemList::const_iterator end = itemList.end();
00700 for(ItemList::const_iterator it = itemList.begin(); it != end; ++it ) {
00701 Item *item = *it;
00702 if(item && item->type() == "ec/external_connection" )
00703 count++;
00704 }
00705 return count;
00706 }
00707
00708 bool CircuitDocument::isValidItem( const QString &itemId )
00709 {
00710 return itemId.startsWith("ec/") || itemId.startsWith("dp/") || itemId.startsWith("sc/");
00711 }
00712
00713 bool CircuitDocument::isValidItem( Item *item )
00714 {
00715 return (dynamic_cast<Component*>(item) || dynamic_cast<DrawPart*>(item));
00716 }
00717
00718 void CircuitDocument::displayEquations()
00719 {
00720 kdDebug() << "######################################################" << endl;
00721 const CircuitList::iterator end = m_circuitList.end();
00722 int i = 1;
00723 for(CircuitList::iterator it = m_circuitList.begin(); it != end; ++it ) {
00724 kdDebug() << "Equation set "<<i<<":\n";
00725 (*it)->displayEquations();
00726 i++;
00727 }
00728 kdDebug() << "######################################################" << endl;
00729 }
00730
00731 #include "circuitdocument.moc"
00732