|
|
|
/***************************************************************************
|
|
|
|
* Copyright (C) 2003 by David Saxton *
|
|
|
|
* david@bluehaze.org *
|
|
|
|
* *
|
|
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
|
|
* it under the terms of the GNU General Public License as published by *
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
|
|
* (at your option) any later version. *
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
#ifndef COMPONENT_H
|
|
|
|
#define COMPONENT_H
|
|
|
|
|
|
|
|
#include "cnitem.h"
|
|
|
|
|
|
|
|
#include <tqvaluelist.h>
|
|
|
|
|
|
|
|
class ICNDocument;
|
|
|
|
class CircuitDocument;
|
|
|
|
class ECNode;
|
|
|
|
class ECSubcircuit;
|
|
|
|
class Element;
|
|
|
|
class Node;
|
|
|
|
class Pin;
|
|
|
|
|
|
|
|
class BJT;
|
|
|
|
class Capacitance;
|
|
|
|
class CCCS;
|
|
|
|
class CCVS;
|
|
|
|
class CurrentSignal;
|
|
|
|
class CurrentSource;
|
|
|
|
class Diode;
|
|
|
|
class Inductance;
|
|
|
|
class LogicIn;
|
|
|
|
class LogicOut;
|
|
|
|
class OpAmp;
|
|
|
|
class Resistance;
|
|
|
|
class Switch;
|
|
|
|
class Transformer;
|
|
|
|
class VCCS;
|
|
|
|
class VCVS;
|
|
|
|
class VoltagePoint;
|
|
|
|
class VoltageSignal;
|
|
|
|
class VoltageSource;
|
|
|
|
|
|
|
|
typedef TQValueList<ECNode*> ECNodeList;
|
|
|
|
typedef TQValueList<Element*> ElementList;
|
|
|
|
typedef TQValueList<Switch*> SwitchList;
|
|
|
|
|
|
|
|
typedef TQValueList< TQValueList<Pin*> > PinListList;
|
|
|
|
|
|
|
|
/**
|
|
|
|
Contains vital information about the elements in the component.
|
|
|
|
*/
|
|
|
|
class ElementMap
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
ElementMap();
|
|
|
|
|
|
|
|
Element * e; // The element
|
|
|
|
Pin * n[4]; // The Pins associated with the CNodes in the element
|
|
|
|
|
|
|
|
/// @see Component::setInterCircuitDependent
|
|
|
|
PinListList interCircuitDependent;
|
|
|
|
|
|
|
|
/// @see Component::setInterGroundDependent
|
|
|
|
PinListList interGroundDependent;
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef TQValueList<ElementMap> ElementMapList;
|
|
|
|
|
|
|
|
/**
|
|
|
|
@short Bass class for all electrical components
|
|
|
|
@author David Saxton
|
|
|
|
*/
|
|
|
|
class Component : public CNItem
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
public:
|
|
|
|
Component( ICNDocument *icnDocument, bool newItem, const TQString &id );
|
|
|
|
virtual ~Component();
|
|
|
|
|
|
|
|
ECNode* createPin( double _x, double _y, int orientation, const TQString &name );
|
|
|
|
/**
|
|
|
|
* Reinherit this function to disallow rotation of the component.
|
|
|
|
*/
|
|
|
|
virtual bool canRotate() const { return true; }
|
|
|
|
/**
|
|
|
|
* Angle of orientation
|
|
|
|
*/
|
|
|
|
int angleDegrees() const { return m_angleDegrees; }
|
|
|
|
/**
|
|
|
|
* Sets the angle (in degrees)
|
|
|
|
*/
|
|
|
|
void setAngleDegrees( int degrees );
|
|
|
|
/**
|
|
|
|
* Whether or not the item is flipped
|
|
|
|
*/
|
|
|
|
bool flipped() const { return b_flipped; }
|
|
|
|
/**
|
|
|
|
* Sets whether or not the item is flipped
|
|
|
|
*/
|
|
|
|
void setFlipped( bool flipped );
|
|
|
|
/**
|
|
|
|
* After calculating nodal voltages, each component will be
|
|
|
|
* called to tell its nodes what the current flowing *into*
|
|
|
|
* the component is.
|
|
|
|
*/
|
|
|
|
void setNodalCurrents();
|
|
|
|
/**
|
|
|
|
* @return pointer to the CircuitDocument that we're in.
|
|
|
|
*/
|
|
|
|
CircuitDocument * circuitDocument() const { return m_pCircuitDocument; }
|
|
|
|
void initElements( const uint stage );
|
|
|
|
virtual void finishedCreation();
|
|
|
|
/**
|
|
|
|
* If reinherit (and use) the stepNonLogic function, then you must also
|
|
|
|
* reinherit this function so that it returns true. Else your component
|
|
|
|
* will not get called.
|
|
|
|
*/
|
|
|
|
virtual bool doesStepNonLogic() const { return false; }
|
|
|
|
virtual void stepNonLogic() {};
|
|
|
|
/**
|
|
|
|
* Returns the translation matrix used for painting et al
|
|
|
|
* @param orientation The orientation to use
|
|
|
|
* @param x x co-ordinate of the center of the object to be mapped
|
|
|
|
* @param y y co-ordinate of the center of the object to be mapped
|
|
|
|
* @param inverse If false, maps the unrotated item to a rotated one, else mapped->unmapped
|
|
|
|
*/
|
|
|
|
static TQWMatrix transMatrix( int angleDegrees, bool flipped, int x, int y, bool inverse = false );
|
|
|
|
/**
|
|
|
|
* @return Information about the component in an ItemData struct.
|
|
|
|
*/
|
|
|
|
virtual ItemData itemData() const;
|
|
|
|
/**
|
|
|
|
* Restores the state of the component from the ItemData struct.
|
|
|
|
*/
|
|
|
|
virtual void restoreFromItemData( const ItemData &itemData );
|
|
|
|
|
|
|
|
BJT * createBJT( Pin *c, Pin *b, Pin *e, bool isNPN = true );
|
|
|
|
BJT * createBJT( ECNode *c, ECNode *b, ECNode *e, bool isNPN = true );
|
|
|
|
|
|
|
|
Capacitance * createCapacitance( Pin *n0, Pin *n1, double capacitance );
|
|
|
|
Capacitance * createCapacitance( ECNode *n0, ECNode *n1, double capacitance );
|
|
|
|
|
|
|
|
CCCS * createCCCS( Pin *n0, Pin *n1, Pin *n2, Pin *n3, double gain );
|
|
|
|
CCCS * createCCCS( ECNode *n0, ECNode *n1, ECNode *n2, ECNode *n3, double gain );
|
|
|
|
|
|
|
|
CCVS * createCCVS( Pin *n0, Pin *n1, Pin *n2, Pin *n3, double gain );
|
|
|
|
CCVS * createCCVS( ECNode *n0, ECNode *n1, ECNode *n2, ECNode *n3, double gain );
|
|
|
|
|
|
|
|
CurrentSignal * createCurrentSignal( Pin *n0, Pin *n1, double current );
|
|
|
|
CurrentSignal * createCurrentSignal( ECNode *n0, ECNode *n1, double current );
|
|
|
|
|
|
|
|
CurrentSource * createCurrentSource( Pin *n0, Pin *n1, double current );
|
|
|
|
CurrentSource * createCurrentSource( ECNode *n0, ECNode *n1, double current );
|
|
|
|
|
|
|
|
Diode * createDiode( Pin *n0, Pin *n1 );
|
|
|
|
Diode * createDiode( ECNode *n0, ECNode *n1 );
|
|
|
|
|
|
|
|
Inductance * createInductance( Pin *n0, Pin *n1, double inductance );
|
|
|
|
Inductance * createInductance( ECNode *n0, ECNode *n1, double inductance );
|
|
|
|
|
|
|
|
LogicIn * createLogicIn( Pin *node );
|
|
|
|
LogicIn * createLogicIn( ECNode *node );
|
|
|
|
|
|
|
|
LogicOut * createLogicOut( Pin *node, bool isHigh );
|
|
|
|
LogicOut * createLogicOut( ECNode *node, bool isHigh );
|
|
|
|
|
|
|
|
OpAmp * createOpAmp( Pin * nonInverting, Pin * out, Pin * inverting );
|
|
|
|
OpAmp * createOpAmp( ECNode * nonInverting, ECNode * out, ECNode * inverting );
|
|
|
|
|
|
|
|
Resistance * createResistance( Pin *n0, Pin *n1, double resistance );
|
|
|
|
Resistance * createResistance( ECNode *n0, ECNode *n1, double resistance );
|
|
|
|
|
|
|
|
Switch * createSwitch( Pin *n0, Pin *n1, bool open );
|
|
|
|
Switch * createSwitch( ECNode *n0, ECNode *n1, bool open );
|
|
|
|
|
|
|
|
VCCS * createVCCS( Pin *n0, Pin *n1, Pin *n2, Pin *n3, double gain );
|
|
|
|
VCCS * createVCCS( ECNode *n0, ECNode *n1, ECNode *n2, ECNode *n3, double gain );
|
|
|
|
|
|
|
|
VCVS * createVCVS( Pin *n0, Pin *n1, Pin *n2, Pin *n3, double gain );
|
|
|
|
VCVS * createVCVS( ECNode *n0, ECNode *n1, ECNode *n2, ECNode *n3, double gain );
|
|
|
|
|
|
|
|
VoltagePoint * createVoltagePoint( Pin *n0, double voltage );
|
|
|
|
VoltagePoint * createVoltagePoint( ECNode *n0, double voltage );
|
|
|
|
|
|
|
|
VoltageSignal * createVoltageSignal( Pin *n0, Pin *n1, double voltage );
|
|
|
|
VoltageSignal * createVoltageSignal( ECNode *n0, ECNode *n1, double voltage );
|
|
|
|
|
|
|
|
VoltageSource * createVoltageSource( Pin *n0, Pin *n1, double voltage );
|
|
|
|
VoltageSource * createVoltageSource( ECNode *n0, ECNode *n1, double voltage );
|
|
|
|
|
|
|
|
|
|
|
|
ECNode* ecNodeWithID( const TQString &ecNodeId );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Safely delete an element - in this case, calls element->componentDeleted,
|
|
|
|
* and removes it from the element list.
|
|
|
|
* @param setPinsInterIndependent whether to call
|
|
|
|
* setPinsInterIndependent. The call is time-consuming, and unnecessary
|
|
|
|
* if the pins from which the element was originally attached will be/
|
|
|
|
* were removed, or they will become interdependent again.
|
|
|
|
*/
|
|
|
|
void removeElement( Element * element, bool setPinsInterIndependent );
|
|
|
|
/**
|
|
|
|
* Safely remove a switch.
|
|
|
|
*/
|
|
|
|
void removeSwitch( Switch * sw );
|
|
|
|
/**
|
|
|
|
* Removes all elements and switches.
|
|
|
|
* @param setPinsInterIndependent whether to bother calling
|
|
|
|
* setPinsInterIndependent. This is false when calling from the
|
|
|
|
* destructor, or when the dependency information is the same.
|
|
|
|
*/
|
|
|
|
void removeElements( bool setPinsInterIndependent = false );
|
|
|
|
/**
|
|
|
|
* @return the list of switches that this component uses.
|
|
|
|
*/
|
|
|
|
SwitchList switchList() const { return m_switchList; }
|
|
|
|
|
|
|
|
signals:
|
|
|
|
/**
|
|
|
|
* Emitted when an element is created.
|
|
|
|
*/
|
|
|
|
void elementCreated( Element * element );
|
|
|
|
/**
|
|
|
|
* Emitted when an element is destroyed.
|
|
|
|
*/
|
|
|
|
void elementDestroyed( Element * element );
|
|
|
|
/**
|
|
|
|
* Emitted when a switch. is created
|
|
|
|
*/
|
|
|
|
void switchCreated( Switch * sw );
|
|
|
|
/**
|
|
|
|
* Emitted when a switch is destroyed.
|
|
|
|
*/
|
|
|
|
void switchDestroyed( Switch * sw );
|
|
|
|
|
|
|
|
public slots:
|
|
|
|
virtual void slotUpdateConfiguration();
|
|
|
|
virtual void removeItem();
|
|
|
|
|
|
|
|
protected:
|
|
|
|
/**
|
|
|
|
* Convenience functionality provided for components in a port shape
|
|
|
|
* (such as ParallelPortComponent and SerialPortComponent).
|
|
|
|
*/
|
|
|
|
void drawPortShape( TQPainter & p );
|
|
|
|
virtual void itemPointsChanged();
|
|
|
|
virtual void updateAttachedPositioning();
|
|
|
|
virtual void initPainter( TQPainter &p );
|
|
|
|
/**
|
|
|
|
* Untranforms the painter from the matrix. This *must* be called after doing
|
|
|
|
* initPainter( TQPainter &p );
|
|
|
|
*/
|
|
|
|
virtual void deinitPainter( TQPainter &p );
|
|
|
|
/**
|
|
|
|
* This creates a set of nodes with their internal IDs set to those in TQStringList pins.
|
|
|
|
* The pins are in a DIP arrangement, and are spaced width() apart.
|
|
|
|
*/
|
|
|
|
void initDIP( const TQStringList & pins );
|
|
|
|
/**
|
|
|
|
* Creates the DIP symbol:
|
|
|
|
* @li constructs rectangular shape
|
|
|
|
* @li puts on text labels in appropriate positions from TQStringList pins
|
|
|
|
*/
|
|
|
|
void initDIPSymbol( const TQStringList & pins, int width );
|
|
|
|
/**
|
|
|
|
* Create 1 pin on the left of the component, placed half way down if h1 is
|
|
|
|
* -1 - else at the position of h1.
|
|
|
|
*/
|
|
|
|
void init1PinLeft( int h1 = -1 );
|
|
|
|
/**
|
|
|
|
* Create 2 pins on the left of the component, either spread out, or at the
|
|
|
|
* given heights.
|
|
|
|
*/
|
|
|
|
void init2PinLeft( int h1 = -1, int h2 = -1 );
|
|
|
|
/**
|
|
|
|
* Create 3 pins on the left of the component, either spread out, or at the
|
|
|
|
* given heights.
|
|
|
|
*/
|
|
|
|
void init3PinLeft( int h1 = -1, int h2 = -1, int h3 = -1 );
|
|
|
|
/**
|
|
|
|
* Create 4 pins on the left of the component, either spread out, or at the
|
|
|
|
* given heights.
|
|
|
|
*/
|
|
|
|
void init4PinLeft( int h1 = -1, int h2 = -1, int h3 = -1, int h4 = -1 );
|
|
|
|
/**
|
|
|
|
* Create 1 pin on the right of the component, placed half way down if h1 is
|
|
|
|
* -1 - else at the position of h1.
|
|
|
|
*/
|
|
|
|
void init1PinRight( int h1 = -1 );
|
|
|
|
/**
|
|
|
|
* Create 2 pins on the right of the component, either spread out, or at the
|
|
|
|
* given heights.
|
|
|
|
*/
|
|
|
|
void init2PinRight( int h1 = -1, int h2 = -1 );
|
|
|
|
/**
|
|
|
|
* Create 3 pins on the right of the component, either spread out, or at the
|
|
|
|
* given heights.
|
|
|
|
*/
|
|
|
|
void init3PinRight( int h1 = -1, int h2 = -1, int h3 = -1 );
|
|
|
|
/**
|
|
|
|
* Create 4 pins on the right of the component, either spread out, or at the
|
|
|
|
* given heights.
|
|
|
|
*/
|
|
|
|
void init4PinRight( int h1 = -1, int h2 = -1, int h3 = -1, int h4 = -1 );
|
|
|
|
/**
|
|
|
|
* When we remove an element, we have to rebuild the list of inter-dependent
|
|
|
|
* nodes. (when adding elements, we just call setInterDependent).
|
|
|
|
*/
|
|
|
|
void rebuildPinInterDepedence();
|
|
|
|
|
|
|
|
// Pointers to commonly used nodes
|
|
|
|
ECNode * m_pPNode[4];
|
|
|
|
ECNode * m_pNNode[4];
|
|
|
|
|
|
|
|
TQGuardedPtr<CircuitDocument> m_pCircuitDocument;
|
|
|
|
int m_angleDegrees;
|
|
|
|
bool b_flipped;
|
|
|
|
|
|
|
|
private:
|
|
|
|
/**
|
|
|
|
* Convenience function for calling both setInterCircuitDependent and
|
|
|
|
* setInterGroundDependent.
|
|
|
|
* @param it Which pins are inter-dependent needs to be recorded in case
|
|
|
|
* this information is later needed in rebuildPinInterDependence.
|
|
|
|
*/
|
|
|
|
void setInterDependent( ElementMapList::iterator it, const TQValueList<Pin*> & pins );
|
|
|
|
/**
|
|
|
|
* Sets all pins independent of each other.
|
|
|
|
*/
|
|
|
|
void setAllPinsInterIndependent();
|
|
|
|
/**
|
|
|
|
* The given pins will affect the simulation of each other. Therefore, they
|
|
|
|
* will need to be simulated in the same circuit.
|
|
|
|
*/
|
|
|
|
void setInterCircuitDependent( ElementMapList::iterator it, const TQValueList<Pin*> & pins );
|
|
|
|
/**
|
|
|
|
* If any of the given pins are ground, then that will affect whether
|
|
|
|
* any of the other pins can be ground.
|
|
|
|
*/
|
|
|
|
void setInterGroundDependent( ElementMapList::iterator it, const TQValueList<Pin*> & pins );
|
|
|
|
/**
|
|
|
|
* List of ElementMaps; which contain information on the pins associated
|
|
|
|
* with the element as well as the dependence between the pins for that
|
|
|
|
* element.
|
|
|
|
* @see ElementMap
|
|
|
|
*/
|
|
|
|
ElementMapList m_elementMapList;
|
|
|
|
/**
|
|
|
|
* The switches used by the component.
|
|
|
|
*/
|
|
|
|
SwitchList m_switchList;
|
|
|
|
/**
|
|
|
|
* @return an iterator to the element in m_elementMapList
|
|
|
|
*/
|
|
|
|
ElementMapList::iterator handleElement( Element *e, const TQValueList<Pin*> & pins );
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|