00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "canvasitemparts.h"
00012 #include "circuitdocument.h"
00013 #include "component.h"
00014 #include "src/core/ktlconfig.h"
00015 #include "ecnode.h"
00016 #include "itemdocumentdata.h"
00017 #include "node.h"
00018 #include "pin.h"
00019 #include "simulator.h"
00020
00021 #include "bjt.h"
00022 #include "capacitance.h"
00023 #include "cccs.h"
00024 #include "ccvs.h"
00025 #include "currentsignal.h"
00026 #include "currentsource.h"
00027 #include "diode.h"
00028 #include "inductance.h"
00029 #include "logic.h"
00030 #include "opamp.h"
00031 #include "resistance.h"
00032 #include "switch.h"
00033 #include "vccs.h"
00034 #include "vcvs.h"
00035 #include "voltagepoint.h"
00036 #include "voltagesignal.h"
00037 #include "voltagesource.h"
00038
00039 #include <cmath>
00040 #include <kdebug.h>
00041 #include <qbitarray.h>
00042 #include <qpainter.h>
00043 #include <qwidget.h>
00044 #include <qwmatrix.h>
00045
00046 const int dipWidth = 112;
00047 const int pairSep = 32;
00048
00049
00050 static const double DPR = 180/M_PI;
00051
00052
00053
00054 Component::Component(ICNDocument *icnDocument, bool newItem, const QString &id)
00055 : CNItem(icnDocument, newItem, id),
00056 m_angleDegrees(0),
00057 b_flipped(false)
00058 {
00059 m_pCircuitDocument = dynamic_cast<CircuitDocument*>(icnDocument);
00060
00061 for(int i=0; i<4; ++i) {
00062 m_pPNode[i] = 0;
00063 m_pNNode[i] = 0;
00064 }
00065
00066
00067 slotUpdateConfiguration();
00068
00069
00070 icnDocument->registerItem(this);
00071 }
00072
00073
00074
00075 Component::~Component()
00076 {
00077 removeElements();
00078 Simulator::self()->detachComponent(this);
00079 }
00080
00081
00082
00083 void Component::removeItem()
00084 {
00085 if(b_deleted) return;
00086
00087 Simulator::self()->detachComponent(this);
00088 CNItem::removeItem();
00089 }
00090
00091
00092
00093 void Component::removeElements(bool setPinsInterIndependent)
00094 {
00095 const ElementMapList::iterator end = m_elementMapList.end();
00096 for(ElementMapList::iterator it = m_elementMapList.begin(); it != end; ++it) {
00097 Element *e = (*it).e;
00098 if(e) {
00099 emit elementDestroyed(e);
00100 e->componentDeleted();
00101 }
00102 }
00103
00104 m_elementMapList.clear();
00105
00106
00107 const SwitchList::iterator swEnd = m_switchList.end();
00108 for(SwitchList::iterator it = m_switchList.begin(); it != swEnd; ++it) {
00109 Switch * sw = *it;
00110 if(!sw) continue;
00111 emit switchDestroyed(sw);
00112 delete sw;
00113 }
00114 m_switchList.clear();
00115
00116
00117 if(setPinsInterIndependent) setAllPinsInterIndependent();
00118 }
00119
00120
00121
00122 void Component::removeElement(Element *element, bool setPinsInterIndependent)
00123 {
00124 if(!element) return;
00125
00126 emit elementDestroyed(element);
00127 element->componentDeleted();
00128
00129 const ElementMapList::iterator end = m_elementMapList.end();
00130 for(ElementMapList::iterator it = m_elementMapList.begin(); it != end;) {
00131
00132 ElementMapList::iterator next = it;
00133 ++next;
00134
00135 if((*it).e == element) m_elementMapList.remove(it);
00136 it = next;
00137 }
00138
00139 if(setPinsInterIndependent) rebuildPinInterDepedence();
00140 }
00141
00142
00143
00144 void Component::removeSwitch(Switch * sw)
00145 {
00146 if(!sw) return;
00147
00148 emit switchDestroyed(sw);
00149 delete sw;
00150 m_switchList.remove(sw);
00151 m_pCircuitDocument->requestAssignCircuits();
00152 }
00153
00154
00155
00156 void Component::setNodalCurrents()
00157 {
00158 const ElementMapList::iterator end = m_elementMapList.end();
00159 for(ElementMapList::iterator it = m_elementMapList.begin(); it != end; ++it) {
00160 ElementMap m = (*it);
00161 for(int i=0; i<4; i++) {
00162 if(m.n[i]) m.n[i]->mergeCurrent(m.e->nodeCurrent(i));
00163 }
00164 }
00165 }
00166
00167 void Component::initPainter(QPainter &p)
00168 {
00169 CNItem::initPainter(p);
00170
00171 if(!b_flipped && (m_angleDegrees%360 == 0)) return;
00172
00173 p.save();
00174 p.translate(int(x()), int(y()));
00175
00176 if(b_flipped) p.scale(-1, 1);
00177
00178 p.rotate(m_angleDegrees);
00179 p.translate(-int(x()), -int(y()));
00180 }
00181
00182 void Component::deinitPainter(QPainter &p)
00183 {
00184 if(!b_flipped && (m_angleDegrees%360 == 0)) return;
00185
00186 p.restore();
00187 }
00188
00189 void Component::setAngleDegrees(int degrees)
00190 {
00191 updateConnectorPoints(false);
00192 m_angleDegrees = degrees;
00193 itemPointsChanged();
00194 updateAttachedPositioning();
00195 p_icnDocument->requestRerouteInvalidatedConnectors();
00196 }
00197
00198 void Component::setFlipped(bool flipped)
00199 {
00200 updateConnectorPoints(false);
00201 b_flipped = flipped;
00202 itemPointsChanged();
00203 updateAttachedPositioning();
00204 p_icnDocument->requestRerouteInvalidatedConnectors();
00205 }
00206
00207 void Component::itemPointsChanged()
00208 {
00209 QPointArray transformedPoints = transMatrix(m_angleDegrees, b_flipped, 0, 0, false).map(m_itemPoints);
00210
00211 setPoints(transformedPoints);
00212 }
00213
00214 void Component::restoreFromItemData(const ItemData &itemData)
00215 {
00216 CNItem::restoreFromItemData(itemData);
00217
00218 setAngleDegrees(int(itemData.angleDegrees));
00219 setFlipped(itemData.flipped);
00220 }
00221
00222 ItemData Component::itemData() const
00223 {
00224 ItemData itemData = CNItem::itemData();
00225 itemData.angleDegrees = m_angleDegrees;
00226 itemData.flipped = b_flipped;
00227 return itemData;
00228 }
00229
00230 QWMatrix Component::transMatrix(int angleDegrees, bool flipped, int x, int y, bool inverse)
00231 {
00232 QWMatrix m;
00233 m.translate(x, y);
00234
00235 if(inverse) {
00236 m.rotate(-angleDegrees);
00237 if(flipped) m.scale(-1, 1);
00238 } else {
00239 if(flipped) m.scale(-1, 1);
00240 m.rotate(angleDegrees);
00241 }
00242
00243 m.translate(-x, -y);
00244 m.setTransformationMode(QWMatrix::Areas);
00245 return m;
00246 }
00247
00248 void Component::finishedCreation()
00249 {
00250 CNItem::finishedCreation();
00251 updateAttachedPositioning();
00252 }
00253
00254 void Component::updateAttachedPositioning()
00255 {
00256 if(b_deleted || !m_bDoneCreation) return;
00257
00258
00259 const NodeMap::iterator end = m_nodeMap.end();
00260 for(NodeMap::iterator it = m_nodeMap.begin(); it != end; ++it) {
00261 if(!it.data().node) kdError() << k_funcinfo << "Node in nodemap is null" << endl;
00262 else {
00263 int nx = int((std::cos(m_angleDegrees/DPR) * it.data().x) - (std::sin(m_angleDegrees/DPR) * it.data().y));
00264 int ny = int((std::sin(m_angleDegrees/DPR) * it.data().x) + (std::cos(m_angleDegrees/DPR) * it.data().y));
00265
00266 if(b_flipped) nx = -nx;
00267
00268 #define round_8(x) (((x) > 0) ? int(((x)+4)/8)*8 : int(((x)-4)/8)*8)
00269 nx = round_8(nx);
00270 ny = round_8(ny);
00271 #undef round_8
00272
00273 int newDir = (((m_angleDegrees + it.data().orientation)%360)+360)%360;
00274 if(b_flipped) newDir = (((180-newDir)%360)+360)%360;
00275
00276 it.data().node->move(nx+x(), ny+y());
00277 it.data().node->setOrientation((Node::node_dir)newDir);
00278 }
00279 }
00280
00281
00282
00283 QWMatrix m;
00284
00285 if(b_flipped) m.scale(-1, 1);
00286
00287 m.rotate(m_angleDegrees);
00288 m.setTransformationMode(QWMatrix::Areas);
00289
00290 const TextMap::iterator textMapEnd = m_textMap.end();
00291 for(TextMap::iterator it = m_textMap.begin(); it != textMapEnd; ++it) {
00292 QRect newPos = m.mapRect(it.data()->recommendedRect());
00293 it.data()->move(newPos.x() + x(), newPos.y() + y());
00294 it.data()->setGuiPartSize(newPos.width(), newPos.height());
00295 it.data()->setAngleDegrees(m_angleDegrees);
00296 }
00297
00298 const WidgetMap::iterator widgetMapEnd = m_widgetMap.end();
00299 for(WidgetMap::iterator it = m_widgetMap.begin(); it != widgetMapEnd; ++it) {
00300 QRect newPos = m.mapRect(it.data()->recommendedRect());
00301 it.data()->move(newPos.x() + x(), newPos.y() + y());
00302 it.data()->setGuiPartSize(newPos.width(), newPos.height());
00303 it.data()->setAngleDegrees(m_angleDegrees);
00304 }
00305
00306 }
00307
00308 void Component::drawPortShape(QPainter & p)
00309 {
00310 int h = height();
00311 int w = width() - 1;
00312 int _x = int(x() + offsetX());
00313 int _y = int(y() + offsetY());
00314
00315 double roundSize = 8;
00316 double slantIndent = 8;
00317
00318 double inner = std::atan(h/slantIndent);
00319 double outer = M_PI-inner;
00320
00321 int inner16 = int(16*inner*DPR);
00322 int outer16 = int(16*outer*DPR);
00323
00324 p.save();
00325 p.setPen(Qt::NoPen);
00326 p.drawPolygon(areaPoints());
00327 p.restore();
00328
00329 initPainter(p);
00330
00331
00332 p.drawLine(int(_x), int(_y+roundSize/2), int(_x), int(_y+h-roundSize/2));
00333
00334
00335 p.drawLine(int(_x+w), int(_y-slantIndent+h-roundSize/2), int(_x+w), int(_y+slantIndent+roundSize/2));
00336
00337
00338 p.drawLine(int(_x+(1-std::cos(outer))*(roundSize/2)), int(_y+h+(std::sin(outer)-1)*(roundSize/2)), int(_x+w+(std::cos(inner)-1)*(roundSize/2)), int(_y+h-slantIndent+(std::sin(inner)-1)*(roundSize/2)));
00339
00340
00341 p.drawLine(int(_x+w+(std::cos(outer)-1)*(roundSize/2)), int(_y+slantIndent+(1-std::sin(inner))*(roundSize/2)), int(_x+(1-std::cos(inner))*(roundSize/2)), int(_y+(1-std::sin(outer))*(roundSize/2)));
00342
00343
00344 p.drawArc(int(_x), int(_y), int(roundSize), int(roundSize), 90*16, outer16);
00345
00346
00347 p.drawArc(int(_x), int(_y+h-roundSize), int(roundSize), int(roundSize), 180*16, outer16);
00348
00349
00350 p.drawArc(int(_x+w-roundSize), int(_y+slantIndent), int(roundSize), int(roundSize), 0, inner16);
00351
00352
00353 p.drawArc(int(_x+w-roundSize), int(_y-slantIndent+h-roundSize), int(roundSize), int(roundSize), 270*16, inner16);
00354
00355 deinitPainter(p);
00356 }
00357
00358 void Component::initDIP(const QStringList & pins)
00359 {
00360 const int numPins = pins.size();
00361 const int numSide = numPins/2 + numPins%2;
00362
00363
00364 for(int i=0; i<numSide; i++) {
00365 if(!pins[i].isEmpty()) {
00366 const int nodeX = -8+offsetX();
00367 const int nodeY = (i+1)*16+offsetY();
00368 ECNode *node = ecNodeWithID(pins[i]);
00369
00370 if(node) {
00371 m_nodeMap[pins[i]].x = nodeX;
00372 m_nodeMap[pins[i]].y = nodeY;
00373 m_nodeMap[pins[i]].orientation = (Node::node_dir)0;
00374 } else createPin(nodeX, nodeY, 0, pins[i]);
00375 }
00376 }
00377
00378
00379 for(int i=numSide; i<numPins; i++) {
00380 if(!pins[i].isEmpty()) {
00381 const int nodeX = width()+8+offsetX();
00382 const int nodeY = (2*numSide-i)*16+offsetY();
00383 ECNode *node = ecNodeWithID(pins[i]);
00384 if(node) {
00385 m_nodeMap[pins[i]].x = nodeX;
00386 m_nodeMap[pins[i]].y = nodeY;
00387 m_nodeMap[pins[i]].orientation = (Node::node_dir)180;
00388 } else createPin(nodeX, nodeY, 180, pins[i]);
00389 }
00390 }
00391
00392 updateAttachedPositioning();
00393 }
00394
00395 void Component::initDIPSymbol(const QStringList & pins, int _width)
00396 {
00397 const int numPins = pins.size();
00398 const int numSide = numPins/2 + numPins%2;
00399
00400 setSize(-(_width-(_width%16))/2, -(numSide+1)*8, _width, (numSide+1)*16, true);
00401
00402 QWidget tmpWidget;
00403 QPainter p(&tmpWidget);
00404
00405 p.setFont(m_font);
00406
00407
00408 for(int i=0; i<numSide; i++) {
00409 if(!pins[i].isEmpty()) {
00410 const QString text = *pins.at(i);
00411
00412 const int _top = (i+1)*16-8 + offsetY();
00413 const int _width = width()/2 - 6;
00414 const int _left = 6 + offsetX();
00415 const int _height = 16;
00416
00417 QRect br = p.boundingRect(QRect(_left, _top, _width, _height), Qt::AlignLeft, text);
00418 addDisplayText(text, br, text);
00419 }
00420 }
00421
00422 for(int i=numSide; i<numPins; i++) {
00423 if(!pins[i].isEmpty()) {
00424 const QString text = *pins.at(i);
00425
00426 const int _top = (2*numSide-i)*16 - 8 + offsetY();
00427 const int _width = width()/2 - 6;
00428 const int _left = (width()/2) + offsetX();
00429 const int _height = 16;
00430
00431 QRect br = p.boundingRect(QRect(_left, _top, _width, _height), Qt::AlignRight, text);
00432 addDisplayText(text, br, text);
00433 }
00434 }
00435
00436 updateAttachedPositioning();
00437 }
00438
00439
00440
00441 void Component::init1PinLeft(int h1)
00442 {
00443 if(h1 == -1) h1 = offsetY()+height()/2;
00444
00445 m_pNNode[0] = createPin(offsetX()-8, h1, 0, "n1");
00446 }
00447
00448 void Component::init2PinLeft(int h1, int h2)
00449 {
00450 if(h1 == -1) h1 = offsetY()+8;
00451 if(h2 == -1) h2 = offsetY()+height()-8;
00452
00453 m_pNNode[0] = createPin(offsetX()-8, h1, 0, "n1");
00454 m_pNNode[1] = createPin(offsetX()-8, h2, 0, "n2");
00455 }
00456
00457 void Component::init3PinLeft(int h1, int h2, int h3)
00458 {
00459 if(h1 == -1) h1 = offsetY()+8;
00460 if(h2 == -1) h2 = offsetY()+height()/2;
00461 if(h3 == -1) h3 = offsetY()+height()-8;
00462
00463 m_pNNode[0] = createPin(offsetX()-8, h1, 0, "n1");
00464 m_pNNode[1] = createPin(offsetX()-8, h2, 0, "n2");
00465 m_pNNode[2] = createPin(offsetX()-8, h3, 0, "n3");
00466 }
00467
00468 void Component::init4PinLeft(int h1, int h2, int h3, int h4)
00469 {
00470 if(h1 == -1) h1 = offsetY()+8;
00471 if(h2 == -1) h2 = offsetY()+24;
00472 if(h3 == -1) h3 = offsetY()+height()-24;
00473 if(h4 == -1) h4 = offsetY()+height()-8;
00474
00475 m_pNNode[0] = createPin(offsetX()-8, h1, 0, "n1");
00476 m_pNNode[1] = createPin(offsetX()-8, h2, 0, "n2");
00477 m_pNNode[2] = createPin(offsetX()-8, h3, 0, "n3");
00478 m_pNNode[3] = createPin(offsetX()-8, h4, 0, "n4");
00479 }
00480
00481 void Component::init1PinRight(int h1)
00482 {
00483 if(h1 == -1) h1 = offsetY()+height()/2;
00484
00485 m_pPNode[0] = createPin(offsetX()+width()+8, h1, 180, "p1");
00486 }
00487
00488 void Component::init2PinRight(int h1, int h2)
00489 {
00490 if(h1 == -1) h1 = offsetY()+8;
00491 if(h2 == -1) h2 = offsetY()+height()-8;
00492
00493 m_pPNode[0] = createPin(offsetX()+width()+8, h1, 180, "p1");
00494 m_pPNode[1] = createPin(offsetX()+width()+8, h2, 180, "p2");
00495 }
00496
00497 void Component::init3PinRight(int h1, int h2, int h3)
00498 {
00499 if(h1 == -1) h1 = offsetY()+8;
00500 if(h2 == -1) h2 = offsetY()+height()/2;
00501 if(h3 == -1) h3 = offsetY()+height()-8;
00502
00503 m_pPNode[0] = createPin(offsetX()+width()+8, h1, 180, "p1");
00504 m_pPNode[1] = createPin(offsetX()+width()+8, h2, 180, "p2");
00505 m_pPNode[2] = createPin(offsetX()+width()+8, h3, 180, "p3");
00506 }
00507
00508 void Component::init4PinRight(int h1, int h2, int h3, int h4)
00509 {
00510 if(h1 == -1) h1 = offsetY()+8;
00511 if(h2 == -1) h2 = offsetY()+24;
00512 if(h3 == -1) h3 = offsetY()+height()-24;
00513 if(h4 == -1) h4 = offsetY()+height()-8;
00514
00515 m_pPNode[0] = createPin(offsetX()+width()+8, h1, 180, "p1");
00516 m_pPNode[1] = createPin(offsetX()+width()+8, h2, 180, "p2");
00517 m_pPNode[2] = createPin(offsetX()+width()+8, h3, 180, "p3");
00518 m_pPNode[3] = createPin(offsetX()+width()+8, h4, 180, "p4");
00519 }
00520
00521
00522
00523 ECNode* Component::ecNodeWithID(const QString &ecNodeId)
00524 {
00525 return dynamic_cast<ECNode*>(p_icnDocument->nodeWithID(nodeId(ecNodeId)));
00526 }
00527
00528 void Component::slotUpdateConfiguration()
00529 {
00530 const LogicConfig logicConfig = LogicIn::getConfig();
00531
00532 const ElementMapList::iterator end = m_elementMapList.end();
00533 for(ElementMapList::iterator it = m_elementMapList.begin(); it != end; ++it)
00534 {
00535 if(LogicIn *logicIn = dynamic_cast<LogicIn*>((*it).e))
00536 logicIn->setLogic(logicConfig);
00537 }
00538 }
00539
00540 BJT *Component::createBJT(ECNode *c, ECNode *b, ECNode *e, bool isNPN)
00541 {
00542 return createBJT(c->pin(), b->pin(), e->pin(), isNPN);
00543 }
00544
00545 Capacitance *Component::createCapacitance(ECNode *n0, ECNode *n1, double capacitance)
00546 {
00547 return createCapacitance(n0->pin(), n1->pin(), capacitance);
00548 }
00549
00550 CCCS *Component::createCCCS(ECNode *n0, ECNode *n1, ECNode *n2, ECNode *n3, double gain)
00551 {
00552 return createCCCS(n0->pin(), n1->pin(), n2->pin(), n3->pin(), gain);
00553 }
00554
00555 CCVS *Component::createCCVS(ECNode *n0, ECNode *n1, ECNode *n2, ECNode *n3, double gain)
00556 {
00557 return createCCVS(n0->pin(), n1->pin(), n2->pin(), n3->pin(), gain);
00558 }
00559
00560 CurrentSignal *Component::createCurrentSignal(ECNode *n0, ECNode *n1, double current)
00561 {
00562 return createCurrentSignal(n0->pin(), n1->pin(), current);
00563 }
00564
00565 CurrentSource *Component::createCurrentSource(ECNode *n0, ECNode *n1, double current)
00566 {
00567 return createCurrentSource(n0->pin(), n1->pin(), current);
00568 }
00569
00570 Diode *Component::createDiode(ECNode *n0, ECNode *n1)
00571 {
00572 return createDiode(n0->pin(), n1->pin());
00573 }
00574
00575 Inductance *Component::createInductance(ECNode *n0, ECNode *n1, double inductance)
00576 {
00577 return createInductance(n0->pin(), n1->pin(), inductance);
00578 }
00579
00580 LogicIn *Component::createLogicIn(ECNode *node)
00581 {
00582 return createLogicIn(node->pin());
00583 }
00584
00585 LogicOut *Component::createLogicOut(ECNode *node, bool isHigh)
00586 {
00587 return createLogicOut(node->pin(), isHigh);
00588 }
00589
00590 OpAmp *Component::createOpAmp(ECNode * nonInverting, ECNode * out, ECNode * inverting)
00591 {
00592 return createOpAmp(nonInverting->pin(), out->pin(), inverting->pin());
00593 }
00594
00595 Resistance *Component::createResistance(ECNode *n0, ECNode *n1, double resistance)
00596 {
00597 return createResistance(n0->pin(), n1->pin(), resistance);
00598 }
00599
00600 Switch *Component::createSwitch(ECNode *n0, ECNode *n1, bool open)
00601 {
00602 return createSwitch(n0->pin(), n1->pin(), open);
00603 }
00604
00605 VCCS *Component::createVCCS(ECNode *n0, ECNode *n1, ECNode *n2, ECNode *n3, double gain)
00606 {
00607 return createVCCS(n0->pin(), n1->pin(), n2->pin(), n3->pin(), gain); }
00608
00609 VCVS *Component::createVCVS(ECNode *n0, ECNode *n1, ECNode *n2, ECNode *n3, double gain)
00610 {
00611 return createVCVS(n0->pin(), n1->pin(), n2->pin(), n3->pin(), gain);
00612 }
00613
00614 VoltagePoint *Component::createVoltagePoint(ECNode *n0, double voltage)
00615 {
00616 return createVoltagePoint(n0->pin(), voltage);
00617 }
00618
00619 VoltageSignal *Component::createVoltageSignal(ECNode *n0, ECNode *n1, double voltage)
00620 {
00621 return createVoltageSignal(n0->pin(), n1->pin(), voltage);
00622 }
00623
00624 VoltageSource *Component::createVoltageSource(ECNode *n0, ECNode *n1, double voltage)
00625 {
00626 return createVoltageSource(n0->pin(), n1->pin(), voltage);
00627 }
00628
00629 BJT* Component::createBJT(Pin *cN, Pin *bN, Pin *eN, bool isNPN)
00630 {
00631 BJT *e = new BJT(isNPN);
00632
00633 QValueList<Pin*> pins;
00634 pins << bN << cN << eN;
00635
00636 ElementMapList::iterator it = handleElement(e, pins);
00637 setInterDependent(it, pins);
00638 return e;
00639 }
00640
00641 Capacitance* Component::createCapacitance(Pin *n0, Pin *n1, double capacitance)
00642 {
00643 Capacitance *e = new Capacitance(capacitance, 1./LINEAR_UPDATE_RATE);
00644
00645 QValueList<Pin*> pins;
00646 pins << n0 << n1;
00647
00648 ElementMapList::iterator it = handleElement(e, pins);
00649 setInterDependent(it, pins);
00650 return e;
00651 }
00652
00653 CCCS* Component::createCCCS(Pin *n0, Pin *n1, Pin *n2, Pin *n3, double gain)
00654 {
00655 CCCS *e = new CCCS(gain);
00656
00657 QValueList<Pin*> pins;
00658 pins << n0 << n1 << n2 << n3;
00659
00660 ElementMapList::iterator it = handleElement(e, pins);
00661 setInterDependent(it, pins);
00662 return e;
00663 }
00664
00665 CCVS* Component::createCCVS(Pin *n0, Pin *n1, Pin *n2, Pin *n3, double gain)
00666 {
00667 CCVS *e = new CCVS(gain);
00668
00669 QValueList<Pin*> pins;
00670 pins << n0 << n1 << n2 << n3;
00671
00672 ElementMapList::iterator it = handleElement(e, pins);
00673 setInterCircuitDependent(it, pins);
00674
00675 pins.clear();
00676 pins << n0 << n1;
00677 setInterGroundDependent(it, pins);
00678
00679 pins.clear();
00680 pins << n2 << n3;
00681 setInterGroundDependent(it, pins);
00682
00683 return e;
00684 }
00685
00686 CurrentSignal *Component::createCurrentSignal(Pin *n0, Pin *n1, double current)
00687 {
00688 CurrentSignal *e = new CurrentSignal(1./LINEAR_UPDATE_RATE, current);
00689
00690 QValueList<Pin*> pins;
00691 pins << n0 << n1;
00692
00693 ElementMapList::iterator it = handleElement(e, pins);
00694 setInterDependent(it, pins);
00695 return e;
00696 }
00697
00698 CurrentSource *Component::createCurrentSource(Pin *n0, Pin *n1, double current)
00699 {
00700 CurrentSource *e = new CurrentSource(current);
00701
00702 QValueList<Pin*> pins;
00703 pins << n0 << n1;
00704
00705 ElementMapList::iterator it = handleElement(e, pins);
00706 setInterDependent(it, pins);
00707 return e;
00708 }
00709
00710 Diode *Component::createDiode(Pin *n0, Pin *n1)
00711 {
00712 Diode *e = new Diode();
00713
00714 QValueList<Pin*> pins;
00715 pins << n0 << n1;
00716
00717 ElementMapList::iterator it = handleElement(e, pins);
00718 setInterDependent(it, pins);
00719 return e;
00720 }
00721
00722 Inductance *Component::createInductance(Pin *n0, Pin *n1, double inductance)
00723 {
00724 Inductance *e = new Inductance(inductance, 1./LINEAR_UPDATE_RATE);
00725
00726 QValueList<Pin*> pins;
00727 pins << n0 << n1;
00728
00729 ElementMapList::iterator it = handleElement(e, pins);
00730 setInterDependent(it, pins);
00731 return e;
00732 }
00733
00734 LogicIn *Component::createLogicIn(Pin *node)
00735 {
00736 LogicIn *e = new LogicIn(LogicIn::getConfig());
00737
00738 QValueList<Pin*> pins;
00739 pins << node;
00740
00741 ElementMapList::iterator it = handleElement(e, pins);
00742 return e;
00743 }
00744
00745 LogicOut *Component::createLogicOut(Pin *node, bool isHigh)
00746 {
00747 LogicOut *e = new LogicOut(LogicIn::getConfig(), isHigh);
00748
00749 QValueList<Pin*> pins;
00750 pins << node;
00751
00752 ElementMapList::iterator it = handleElement(e, pins);
00753 setInterDependent(it, pins);
00754 return e;
00755 }
00756
00757 OpAmp * Component::createOpAmp(Pin * nonInverting, Pin * inverting, Pin * out)
00758 {
00759 OpAmp *e = new OpAmp();
00760
00761 QValueList<Pin*> pins;
00762 pins << nonInverting << inverting << out;
00763
00764 ElementMapList::iterator it = handleElement(e, pins);
00765 setInterDependent(it, pins);
00766 return e;
00767 }
00768
00769 Resistance* Component::createResistance(Pin *n0, Pin *n1, double resistance)
00770 {
00771 Resistance *e = new Resistance(resistance);
00772
00773 QValueList<Pin*> pins;
00774 pins << n0 << n1;
00775
00776 ElementMapList::iterator it = handleElement(e, pins);
00777 setInterDependent(it, pins);
00778 return e;
00779 }
00780
00781 Switch* Component::createSwitch(Pin *n0, Pin *n1, bool open)
00782 {
00783
00784
00785
00786 Switch *e = new Switch(this, n0, n1, open ? Switch::Open : Switch::Closed);
00787 m_switchList.append(e);
00788 n0->addSwitch(e);
00789 n1->addSwitch(e);
00790 emit switchCreated(e);
00791 return e;
00792 }
00793
00794 VCCS* Component::createVCCS(Pin *n0, Pin *n1, Pin *n2, Pin *n3, double gain)
00795 {
00796 VCCS *e = new VCCS(gain);
00797
00798 QValueList<Pin*> pins;
00799 pins << n0 << n1 << n2 << n3;
00800
00801 ElementMapList::iterator it = handleElement(e, pins);
00802 setInterDependent(it, pins);
00803 return e;
00804 }
00805
00806 VCVS* Component::createVCVS(Pin *n0, Pin *n1, Pin *n2, Pin *n3, double gain)
00807 {
00808 VCVS *e = new VCVS(gain);
00809
00810 QValueList<Pin*> pins;
00811 pins << n0 << n1 << n2 << n3;
00812
00813 ElementMapList::iterator it = handleElement(e, pins);
00814 setInterCircuitDependent(it, pins);
00815
00816 pins.clear();
00817 pins << n0 << n1;
00818 setInterGroundDependent(it, pins);
00819
00820 pins.clear();
00821 pins << n2 << n3;
00822 setInterGroundDependent(it, pins);
00823 return e;
00824 }
00825
00826 VoltagePoint* Component::createVoltagePoint(Pin *n0, double voltage)
00827 {
00828 VoltagePoint *e = new VoltagePoint(voltage);
00829
00830 QValueList<Pin*> pins;
00831 pins << n0;
00832
00833 ElementMapList::iterator it = handleElement(e, pins);
00834 setInterDependent(it, pins);
00835 return e;
00836 }
00837
00838 VoltageSignal* Component::createVoltageSignal(Pin *n0, Pin *n1, double voltage)
00839 {
00840 VoltageSignal *e = new VoltageSignal(1./LINEAR_UPDATE_RATE, voltage);
00841
00842 QValueList<Pin*> pins;
00843 pins << n0 << n1;
00844
00845 ElementMapList::iterator it = handleElement(e, pins);
00846 setInterDependent(it, pins);
00847 return e;
00848 }
00849
00850 VoltageSource* Component::createVoltageSource(Pin *n0, Pin *n1, double voltage)
00851 {
00852 VoltageSource *e = new VoltageSource(voltage);
00853
00854 QValueList<Pin*> pins;
00855 pins << n0 << n1;
00856
00857 ElementMapList::iterator it = handleElement(e, pins);
00858 setInterDependent(it, pins);
00859 return e;
00860 }
00861
00862 ElementMapList::iterator Component::handleElement(Element *e, const QValueList<Pin*> & pins) {
00863 if(!e) return m_elementMapList.end();
00864
00865 ElementMap em;
00866 em.e = e;
00867 int at = 0;
00868
00869 QValueList<Pin*>::ConstIterator end = pins.end();
00870 for(QValueList<Pin*>::ConstIterator it = pins.begin(); it != end; ++it) {
00871 (*it)->addElement(e);
00872 em.n[at++] = *it;
00873 }
00874
00875 ElementMapList::iterator it = m_elementMapList.append(em);
00876
00877 emit elementCreated(e);
00878 return it;
00879 }
00880
00881 void Component::setInterDependent(ElementMapList::iterator it, const QValueList<Pin*> &pins)
00882 {
00883 setInterCircuitDependent(it, pins);
00884 setInterGroundDependent(it, pins);
00885 }
00886
00887 void Component::setInterCircuitDependent(ElementMapList::iterator it, const QValueList<Pin*> & pins)
00888 {
00889 QValueList<Pin*>::ConstIterator end = pins.end();
00890 for(QValueList<Pin*>::ConstIterator it1 = pins.begin(); it1 != end; ++it1) {
00891 for(QValueList<Pin*>::ConstIterator it2 = pins.begin(); it2 != end; ++it2) {
00892 (*it1)->addCircuitDependentPin(*it2);
00893 }
00894 }
00895
00896 (*it).interCircuitDependent.append(pins);
00897 }
00898
00899 void Component::setInterGroundDependent(ElementMapList::iterator it, const QValueList<Pin*> & pins)
00900 {
00901 QValueList<Pin*>::ConstIterator end = pins.end();
00902 for(QValueList<Pin*>::ConstIterator it1 = pins.begin(); it1 != end; ++it1) {
00903 for(QValueList<Pin*>::ConstIterator it2 = pins.begin(); it2 != end; ++it2) {
00904 (*it1)->addGroundDependentPin(*it2);
00905 }
00906 }
00907
00908 (*it).interGroundDependent.append(pins);
00909 }
00910
00911 void Component::rebuildPinInterDepedence()
00912 {
00913 setAllPinsInterIndependent();
00914
00915
00916 ElementMapList::iterator emlEnd = m_elementMapList.end();
00917 for(ElementMapList::iterator it = m_elementMapList.begin(); it != emlEnd; ++it)
00918 {
00919
00920 PinListList list = (*it).interCircuitDependent;
00921
00922 PinListList::iterator depEnd = list.end();
00923 for(PinListList::iterator depIt = list.begin(); depIt != depEnd; ++depIt)
00924 setInterCircuitDependent(it, *depIt);
00925
00926 list = (*it).interGroundDependent;
00927
00928 depEnd = list.end();
00929 for(PinListList::iterator depIt = list.begin(); depIt != depEnd; ++depIt)
00930 setInterGroundDependent(it, *depIt);
00931 }
00932 }
00933
00934 void Component::setAllPinsInterIndependent()
00935 {
00936 NodeMap::iterator nmEnd = m_nodeMap.end();
00937 for(NodeMap::iterator it = m_nodeMap.begin(); it != nmEnd; ++it)
00938 {
00939 PinVector pins = (static_cast<ECNode*>(it.data().node))->pins();
00940 PinVector::iterator pinsEnd = pins.end();
00941 for(PinVector::iterator pinsIt = pins.begin(); pinsIt != pinsEnd; ++pinsIt)
00942 {
00943 if(*pinsIt) (*pinsIt)->removeDependentPins();
00944 }
00945 }
00946 }
00947
00948 void Component::initElements(const uint stage)
00949 {
00951
00952 const ElementMapList::iterator end = m_elementMapList.end();
00953
00954 if(stage == 1) {
00955 for(ElementMapList::iterator it = m_elementMapList.begin(); it != end; ++it) {
00956 (*it).e->add_initial_dc();
00957 }
00958 return;
00959 }
00960
00961 for(ElementMapList::iterator it = m_elementMapList.begin(); it != end; ++it) {
00962 ElementMap m = *it;
00963
00964 if(m.n[3]) m.e->setCNodes(m.n[0]->eqId(), m.n[1]->eqId(), m.n[2]->eqId(), m.n[3]->eqId());
00965 else if(m.n[2]) m.e->setCNodes(m.n[0]->eqId(), m.n[1]->eqId(), m.n[2]->eqId());
00966 else if(m.n[1]) m.e->setCNodes(m.n[0]->eqId(), m.n[1]->eqId());
00967 else if(m.n[0]) m.e->setCNodes(m.n[0]->eqId());
00968 }
00969
00970 for(ElementMapList::iterator it = m_elementMapList.begin(); it != end; ++it) {
00971 (*it).e->add_map();
00972 }
00973 }
00974
00975 ECNode *Component::createPin(double x, double y, int orientation, const QString & name)
00976 {
00977 return dynamic_cast<ECNode*>(createNode(x, y, orientation, name, Node::ec_pin));
00978 }
00979
00980
00981 ElementMap::ElementMap()
00982 {
00983 e = 0;
00984 for(int i = 0; i < 4; ++i) n[i] = 0;
00985 }
00986
00987
00988
00989 #include "component.moc"