mirror of
https://github.com/ra3xdh/qucs_s
synced 2025-03-28 21:13:26 +00:00

Conflicts: qucs-core/ChangeLog qucs-core/NEWS qucs-core/README qucs-core/RELEASE qucs-core/autodsp.sh qucs-core/configure.ac qucs-core/src/ChangeLog qucs-core/src/acsolver.cpp qucs-core/src/acsolver.h qucs-core/src/analyses.h qucs-core/src/analysis.cpp qucs-core/src/analysis.h qucs-core/src/applications.h qucs-core/src/characteristic.cpp qucs-core/src/characteristic.h qucs-core/src/check_citi.cpp qucs-core/src/check_citi.h qucs-core/src/check_csv.cpp qucs-core/src/check_csv.h qucs-core/src/check_dataset.cpp qucs-core/src/check_dataset.h qucs-core/src/check_mdl.cpp qucs-core/src/check_mdl.h qucs-core/src/check_netlist.cpp qucs-core/src/check_netlist.h qucs-core/src/check_touchstone.cpp qucs-core/src/check_touchstone.h qucs-core/src/check_zvr.cpp qucs-core/src/check_zvr.h qucs-core/src/circuit.cpp qucs-core/src/circuit.h qucs-core/src/compat.h qucs-core/src/components/ChangeLog qucs-core/src/components/Makefile.am qucs-core/src/components/amplifier.cpp qucs-core/src/components/amplifier.h qucs-core/src/components/attenuator.cpp qucs-core/src/components/attenuator.h qucs-core/src/components/biastee.cpp qucs-core/src/components/biastee.h qucs-core/src/components/capacitor.cpp qucs-core/src/components/capacitor.h qucs-core/src/components/cccs.cpp qucs-core/src/components/cccs.h qucs-core/src/components/ccvs.cpp qucs-core/src/components/ccvs.h qucs-core/src/components/circulator.cpp qucs-core/src/components/circulator.h qucs-core/src/components/coaxline.cpp qucs-core/src/components/coaxline.h qucs-core/src/components/component.h qucs-core/src/components/component_id.h qucs-core/src/components/components.h qucs-core/src/components/coupler.cpp qucs-core/src/components/coupler.h qucs-core/src/components/cross.cpp qucs-core/src/components/cross.h qucs-core/src/components/dcblock.cpp qucs-core/src/components/dcblock.h qucs-core/src/components/dcfeed.cpp qucs-core/src/components/dcfeed.h qucs-core/src/components/devices/Makefile.am qucs-core/src/components/devices/bjt.cpp qucs-core/src/components/devices/bjt.h qucs-core/src/components/devices/device.cpp qucs-core/src/components/devices/device.h qucs-core/src/components/devices/diac.cpp qucs-core/src/components/devices/diac.h qucs-core/src/components/devices/diode.cpp qucs-core/src/components/devices/diode.h qucs-core/src/components/devices/eqndefined.cpp qucs-core/src/components/devices/eqndefined.h qucs-core/src/components/devices/jfet.cpp qucs-core/src/components/devices/jfet.h qucs-core/src/components/devices/libdevices.ap qucs-core/src/components/devices/mosfet.cpp qucs-core/src/components/devices/mosfet.h qucs-core/src/components/devices/thyristor.cpp qucs-core/src/components/devices/thyristor.h qucs-core/src/components/devices/triac.cpp qucs-core/src/components/devices/triac.h qucs-core/src/components/digital/and.cpp qucs-core/src/components/digital/and.h qucs-core/src/components/digital/buffer.cpp qucs-core/src/components/digital/buffer.h qucs-core/src/components/digital/digisource.cpp qucs-core/src/components/digital/digisource.h qucs-core/src/components/digital/digital.cpp qucs-core/src/components/digital/digital.h qucs-core/src/components/digital/inverter.cpp qucs-core/src/components/digital/inverter.h qucs-core/src/components/digital/nand.cpp qucs-core/src/components/digital/nand.h qucs-core/src/components/digital/nor.cpp qucs-core/src/components/digital/nor.h qucs-core/src/components/digital/or.cpp qucs-core/src/components/digital/or.h qucs-core/src/components/digital/xnor.cpp qucs-core/src/components/digital/xnor.h qucs-core/src/components/digital/xor.cpp qucs-core/src/components/digital/xor.h qucs-core/src/components/ground.cpp qucs-core/src/components/ground.h qucs-core/src/components/gyrator.cpp qucs-core/src/components/gyrator.h qucs-core/src/components/iac.cpp qucs-core/src/components/iac.h qucs-core/src/components/idc.cpp qucs-core/src/components/idc.h qucs-core/src/components/iexp.cpp qucs-core/src/components/iexp.h qucs-core/src/components/ifile.cpp qucs-core/src/components/ifile.h qucs-core/src/components/iinoise.cpp qucs-core/src/components/iinoise.h qucs-core/src/components/inductor.cpp qucs-core/src/components/inductor.h qucs-core/src/components/inoise.cpp qucs-core/src/components/inoise.h qucs-core/src/components/iprobe.cpp qucs-core/src/components/iprobe.h qucs-core/src/components/ipulse.cpp qucs-core/src/components/ipulse.h qucs-core/src/components/irect.cpp qucs-core/src/components/irect.h qucs-core/src/components/isolator.cpp qucs-core/src/components/isolator.h qucs-core/src/components/itrafo.cpp qucs-core/src/components/itrafo.h qucs-core/src/components/ivnoise.cpp qucs-core/src/components/ivnoise.h qucs-core/src/components/libcomponent.ap qucs-core/src/components/microstrip/bondwire.cpp qucs-core/src/components/microstrip/bondwire.h qucs-core/src/components/microstrip/cpwgap.cpp qucs-core/src/components/microstrip/cpwgap.h qucs-core/src/components/microstrip/cpwline.cpp qucs-core/src/components/microstrip/cpwline.h qucs-core/src/components/microstrip/cpwopen.cpp qucs-core/src/components/microstrip/cpwopen.h qucs-core/src/components/microstrip/cpwshort.cpp qucs-core/src/components/microstrip/cpwshort.h qucs-core/src/components/microstrip/cpwstep.cpp qucs-core/src/components/microstrip/cpwstep.h qucs-core/src/components/microstrip/mscorner.cpp qucs-core/src/components/microstrip/mscorner.h qucs-core/src/components/microstrip/mscoupled.cpp qucs-core/src/components/microstrip/mscoupled.h qucs-core/src/components/microstrip/mscross.cpp qucs-core/src/components/microstrip/mscross.h qucs-core/src/components/microstrip/msgap.cpp qucs-core/src/components/microstrip/msgap.h qucs-core/src/components/microstrip/msline.cpp qucs-core/src/components/microstrip/msline.h qucs-core/src/components/microstrip/msmbend.cpp qucs-core/src/components/microstrip/msmbend.h qucs-core/src/components/microstrip/msopen.cpp qucs-core/src/components/microstrip/msopen.h qucs-core/src/components/microstrip/msrstub.cpp qucs-core/src/components/microstrip/msrstub.h qucs-core/src/components/microstrip/msstep.cpp qucs-core/src/components/microstrip/msstep.h qucs-core/src/components/microstrip/mstee.cpp qucs-core/src/components/microstrip/mstee.h qucs-core/src/components/microstrip/msvia.cpp qucs-core/src/components/microstrip/msvia.h qucs-core/src/components/microstrip/substrate.cpp qucs-core/src/components/microstrip/substrate.h qucs-core/src/components/mutual.cpp qucs-core/src/components/mutual.h qucs-core/src/components/mutual2.cpp qucs-core/src/components/mutual2.h qucs-core/src/components/mutualx.cpp qucs-core/src/components/mutualx.h qucs-core/src/components/opamp.cpp qucs-core/src/components/opamp.h qucs-core/src/components/open.cpp qucs-core/src/components/open.h qucs-core/src/components/pac.cpp qucs-core/src/components/pac.h qucs-core/src/components/phaseshifter.cpp qucs-core/src/components/phaseshifter.h qucs-core/src/components/rectline.cpp qucs-core/src/components/relais.cpp qucs-core/src/components/relais.h qucs-core/src/components/resistor.cpp qucs-core/src/components/resistor.h qucs-core/src/components/rfedd.cpp qucs-core/src/components/rfedd.h qucs-core/src/components/rlcg.cpp qucs-core/src/components/rlcg.h qucs-core/src/components/short.cpp qucs-core/src/components/short.h qucs-core/src/components/spfile.cpp qucs-core/src/components/spfile.h qucs-core/src/components/strafo.cpp qucs-core/src/components/strafo.h qucs-core/src/components/tee.cpp qucs-core/src/components/tee.h qucs-core/src/components/tline.cpp qucs-core/src/components/tline.h qucs-core/src/components/tline4p.cpp qucs-core/src/components/tline4p.h qucs-core/src/components/trafo.cpp qucs-core/src/components/trafo.h qucs-core/src/components/tswitch.cpp qucs-core/src/components/tswitch.h qucs-core/src/components/twistedpair.cpp qucs-core/src/components/twistedpair.h qucs-core/src/components/vac.cpp qucs-core/src/components/vac.h qucs-core/src/components/vam.cpp qucs-core/src/components/vam.h qucs-core/src/components/vccs.cpp qucs-core/src/components/vccs.h qucs-core/src/components/vcvs.cpp qucs-core/src/components/vcvs.h qucs-core/src/components/vdc.cpp qucs-core/src/components/vdc.h qucs-core/src/components/verilog/ChangeLog qucs-core/src/components/verilog/Makefile.am qucs-core/src/components/verilog/constants.vams qucs-core/src/components/verilog/disciplines.vams qucs-core/src/components/vexp.cpp qucs-core/src/components/vexp.h qucs-core/src/components/vfile.cpp qucs-core/src/components/vfile.h qucs-core/src/components/vnoise.cpp qucs-core/src/components/vnoise.h qucs-core/src/components/vpm.cpp qucs-core/src/components/vpm.h qucs-core/src/components/vprobe.cpp qucs-core/src/components/vprobe.h qucs-core/src/components/vpulse.cpp qucs-core/src/components/vpulse.h qucs-core/src/components/vrect.cpp qucs-core/src/components/vrect.h qucs-core/src/components/vvnoise.cpp qucs-core/src/components/vvnoise.h qucs-core/src/constants.h qucs-core/src/consts.h qucs-core/src/converter/ChangeLog qucs-core/src/converter/check_spice.cpp qucs-core/src/converter/check_spice.h qucs-core/src/converter/check_vcd.cpp qucs-core/src/converter/check_vcd.h qucs-core/src/converter/csv_producer.cpp qucs-core/src/converter/csv_producer.h qucs-core/src/converter/matlab_producer.cpp qucs-core/src/converter/matlab_producer.h qucs-core/src/converter/parse_spice.y qucs-core/src/converter/parse_vcd.y qucs-core/src/converter/qucs_producer.cpp qucs-core/src/converter/qucs_producer.h qucs-core/src/converter/qucsconv.cpp qucs-core/src/converter/scan_spice.l qucs-core/src/converter/scan_vcd.l qucs-core/src/converter/touchstone_producer.cpp qucs-core/src/converter/touchstone_producer.h qucs-core/src/dataset.cpp qucs-core/src/dataset.h qucs-core/src/dcsolver.cpp qucs-core/src/dcsolver.h qucs-core/src/devstates.cpp qucs-core/src/devstates.h qucs-core/src/differentiate.cpp qucs-core/src/differentiate.h qucs-core/src/environment.cpp qucs-core/src/environment.h qucs-core/src/eqnsys.cpp qucs-core/src/eqnsys.h qucs-core/src/equation.cpp qucs-core/src/equation.h qucs-core/src/evaluate.cpp qucs-core/src/evaluate.h qucs-core/src/exception.cpp qucs-core/src/exception.h qucs-core/src/exceptionstack.cpp qucs-core/src/exceptionstack.h qucs-core/src/fourier.cpp qucs-core/src/fourier.h qucs-core/src/gperfappgen.cpp qucs-core/src/hash.cpp qucs-core/src/hash.h qucs-core/src/hbsolver.cpp qucs-core/src/hbsolver.h qucs-core/src/history.cpp qucs-core/src/history.h qucs-core/src/input.cpp qucs-core/src/input.h qucs-core/src/integrator.cpp qucs-core/src/integrator.h qucs-core/src/interpolator.cpp qucs-core/src/interpolator.h qucs-core/src/libqucsator.h qucs-core/src/logging.c qucs-core/src/logging.h qucs-core/src/math/cbesselj.cpp qucs-core/src/math/cmplx.cpp qucs-core/src/math/cmplx.h qucs-core/src/math/complex.cpp qucs-core/src/math/complex.h qucs-core/src/math/fspecial.cpp qucs-core/src/math/fspecial.h qucs-core/src/math/precision.c qucs-core/src/math/precision.h qucs-core/src/math/real.cpp qucs-core/src/math/real.h qucs-core/src/matrix.cpp qucs-core/src/matrix.h qucs-core/src/matvec.cpp qucs-core/src/matvec.h qucs-core/src/module.cpp qucs-core/src/module.h qucs-core/src/nasolution.cpp qucs-core/src/nasolution.h qucs-core/src/nasolver.cpp qucs-core/src/nasolver.h qucs-core/src/net.cpp qucs-core/src/net.h qucs-core/src/netdefs.h qucs-core/src/node.cpp qucs-core/src/node.h qucs-core/src/nodelist.cpp qucs-core/src/nodelist.h qucs-core/src/nodeset.cpp qucs-core/src/nodeset.h qucs-core/src/object.cpp qucs-core/src/object.h qucs-core/src/operatingpoint.cpp qucs-core/src/operatingpoint.h qucs-core/src/pair.cpp qucs-core/src/pair.h qucs-core/src/parasweep.cpp qucs-core/src/parasweep.h qucs-core/src/parse_citi.y qucs-core/src/parse_csv.y qucs-core/src/parse_dataset.y qucs-core/src/parse_mdl.y qucs-core/src/parse_netlist.y qucs-core/src/parse_touchstone.y qucs-core/src/parse_zvr.y qucs-core/src/poly.h qucs-core/src/property.cpp qucs-core/src/property.h qucs-core/src/ptrlist.cpp qucs-core/src/ptrlist.h qucs-core/src/range.cpp qucs-core/src/range.h qucs-core/src/receiver.cpp qucs-core/src/receiver.h qucs-core/src/scan_citi.l qucs-core/src/scan_csv.l qucs-core/src/scan_dataset.l qucs-core/src/scan_mdl.l qucs-core/src/scan_netlist.l qucs-core/src/scan_touchstone.l qucs-core/src/scan_zvr.l qucs-core/src/spline.cpp qucs-core/src/spline.h qucs-core/src/spsolver.cpp qucs-core/src/spsolver.h qucs-core/src/states.cpp qucs-core/src/states.h qucs-core/src/strlist.cpp qucs-core/src/strlist.h qucs-core/src/sweep.cpp qucs-core/src/sweep.h qucs-core/src/tmatrix.cpp qucs-core/src/tmatrix.h qucs-core/src/transient.cpp qucs-core/src/transient.h qucs-core/src/tridiag.cpp qucs-core/src/tridiag.h qucs-core/src/trsolver.cpp qucs-core/src/trsolver.h qucs-core/src/tvector.cpp qucs-core/src/tvector.h qucs-core/src/ucs.cpp qucs-core/src/valuelist.cpp qucs-core/src/valuelist.h qucs-core/src/variable.cpp qucs-core/src/variable.h qucs-core/src/vector.cpp qucs-core/src/vector.h qucs-doc/NEWS qucs-doc/README qucs-doc/RELEASE qucs-doc/technical/ChangeLog qucs-doc/technical/transline.tex qucs-doc/tutorial/equations/content.tex qucs/ChangeLog qucs/NEWS qucs/README qucs/RELEASE qucs/autodsp.sh qucs/configure.ac qucs/contrib/innosetup/freehdl.iss qucs/contrib/innosetup/qucs.iss qucs/qucs-help/ChangeLog qucs/qucs-help/docs/en/Makefile.am qucs/qucs-help/docs/en/index.html qucs/qucs-lib/ChangeLog qucs/qucs-lib/library/Ideal.lib qucs/qucs-lib/symbolwidget.cpp qucs/qucs-transcalc/ChangeLog qucs/qucs-transcalc/coax.cpp qucs/qucs-transcalc/rectwaveguide.cpp qucs/qucs/ChangeLog qucs/qucs/Makefile.am qucs/qucs/bitmaps/Makefile.am qucs/qucs/bitmaps/photodiode.png qucs/qucs/bitmaps/phototransistor.png qucs/qucs/components/ChangeLog qucs/qucs/components/Makefile.am qucs/qucs/components/component.cpp qucs/qucs/components/components.h qucs/qucs/components/libcomponents.ap qucs/qucs/components/mslange.cpp qucs/qucs/diagrams/graph.cpp qucs/qucs/dialogs/settingsdialog.cpp qucs/qucs/dialogs/settingsdialog.h qucs/qucs/dialogs/simmessage.cpp qucs/qucs/dialogs/simmessage.h qucs/qucs/main.cpp qucs/qucs/main.h qucs/qucs/module.cpp qucs/qucs/paintings/graphictext.cpp qucs/qucs/qucs.ap qucs/qucs/qucs.cpp qucs/qucs/qucs.h qucs/qucs/qucs_ar.ts qucs/qucs/qucs_ca.ts qucs/qucs/qucs_cs.ts qucs/qucs/qucs_de.ts qucs/qucs/qucs_es.ts qucs/qucs/qucs_fr.ts qucs/qucs/qucs_he.ts qucs/qucs/qucs_hu.ts qucs/qucs/qucs_init.cpp qucs/qucs/qucs_it.ts qucs/qucs/qucs_jp.ts qucs/qucs/qucs_kk.ts qucs/qucs/qucs_pl.ts qucs/qucs/qucs_pt.ts qucs/qucs/qucs_ro.ts qucs/qucs/qucs_ru.ts qucs/qucs/qucs_sv.ts qucs/qucs/qucs_tr.ts qucs/qucs/qucs_uk.ts qucs/qucs/qucsdigi.bat qucs/qucs/qucsdigilib.bat qucs/qucs/qucsdoc.cpp qucs/qucs/qucsdoc.h qucs/qucs/schematic.cpp qucs/qucs/schematic_file.cpp qucs/qucs/syntax.cpp qucs/qucs/syntax.h qucs/qucs/textdoc.cpp
1557 lines
43 KiB
C++
1557 lines
43 KiB
C++
/***************************************************************************
|
|
component.cpp
|
|
---------------
|
|
begin : Sat Aug 23 2003
|
|
copyright : (C) 2003 by Michael Margraf
|
|
email : michael.margraf@alumni.tu-berlin.de
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* *
|
|
* 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. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <qdir.h>
|
|
#include <qpen.h>
|
|
#include <qpoint.h>
|
|
#include <qstring.h>
|
|
#include <qpainter.h>
|
|
#include <qtabwidget.h>
|
|
#include <qmessagebox.h>
|
|
#include <qdom.h>
|
|
#include <qdict.h>
|
|
|
|
#include "components.h"
|
|
#include "node.h"
|
|
#include "main.h"
|
|
#include "qucs.h"
|
|
#include "schematic.h"
|
|
#include "viewpainter.h"
|
|
#include "module.h"
|
|
|
|
// ***********************************************************************
|
|
// ********** **********
|
|
// ********** class "Component" **********
|
|
// ********** **********
|
|
// ***********************************************************************
|
|
Component::Component()
|
|
{
|
|
Type = isAnalogComponent;
|
|
|
|
mirroredX = false;
|
|
rotated = 0;
|
|
isSelected = false;
|
|
isActive = COMP_IS_ACTIVE;
|
|
showName = true;
|
|
|
|
cx = 0;
|
|
cy = 0;
|
|
tx = 0;
|
|
ty = 0;
|
|
|
|
Arcs.setAutoDelete(true);
|
|
Lines.setAutoDelete(true);
|
|
Rects.setAutoDelete(true);
|
|
Ellips.setAutoDelete(true);
|
|
Ports.setAutoDelete(true);
|
|
Texts.setAutoDelete(true);
|
|
Props.setAutoDelete(true);
|
|
}
|
|
|
|
// -------------------------------------------------------
|
|
Component* Component::newOne()
|
|
{
|
|
return new Component();
|
|
}
|
|
|
|
// -------------------------------------------------------
|
|
void Component::Bounding(int& _x1, int& _y1, int& _x2, int& _y2)
|
|
{
|
|
_x1 = x1+cx;
|
|
_y1 = y1+cy;
|
|
_x2 = x2+cx;
|
|
_y2 = y2+cy;
|
|
}
|
|
|
|
// -------------------------------------------------------
|
|
// Size of component text.
|
|
int Component::textSize(int& _dx, int& _dy)
|
|
{
|
|
QFontMetrics metrics(QucsSettings.font); // get size of text
|
|
int tmp, count=0;
|
|
_dx = _dy = 0;
|
|
if(showName) {
|
|
_dx = metrics.width(Name);
|
|
_dy = metrics.height();
|
|
count++;
|
|
}
|
|
for(Property *pp = Props.first(); pp != 0; pp = Props.next())
|
|
if(pp->display) {
|
|
// get width of text
|
|
tmp = metrics.width(pp->Name+"="+pp->Value);
|
|
if(tmp > _dx) _dx = tmp;
|
|
_dy += metrics.height();
|
|
count++;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
// -------------------------------------------------------
|
|
// Boundings including the component text.
|
|
void Component::entireBounds(int& _x1, int& _y1, int& _x2, int& _y2, float Corr)
|
|
{
|
|
_x1 = x1+cx;
|
|
_y1 = y1+cy;
|
|
_x2 = x2+cx;
|
|
_y2 = y2+cy;
|
|
|
|
// text boundings
|
|
if(tx < x1) _x1 = tx+cx;
|
|
if(ty < y1) _y1 = ty+cy;
|
|
|
|
int dx, dy, ny;
|
|
ny = textSize(dx, dy);
|
|
dy = int(float(ny) / Corr); // correction for unproportional font scaling
|
|
|
|
if((tx+dx) > x2) _x2 = tx+dx+cx;
|
|
if((ty+dy) > y2) _y2 = ty+dy+cy;
|
|
}
|
|
|
|
// -------------------------------------------------------
|
|
void Component::setCenter(int x, int y, bool relative)
|
|
{
|
|
if(relative) { cx += x; cy += y; }
|
|
else { cx = x; cy = y; }
|
|
}
|
|
|
|
// -------------------------------------------------------
|
|
void Component::getCenter(int& x, int& y)
|
|
{
|
|
x = cx;
|
|
y = cy;
|
|
}
|
|
|
|
// -------------------------------------------------------
|
|
int Component::getTextSelected(int x_, int y_, float Corr)
|
|
{
|
|
x_ -= cx;
|
|
y_ -= cy;
|
|
if(x_ < tx) return -1;
|
|
if(y_ < ty) return -1;
|
|
|
|
x_ -= tx;
|
|
y_ -= ty;
|
|
int w, dy = int(float(y_) * Corr); // correction for font scaling
|
|
QFontMetrics metrics(QucsSettings.font);
|
|
if(showName) {
|
|
w = metrics.width(Name);
|
|
if(dy < 1) {
|
|
if(x_ < w) return 0;
|
|
return -1;
|
|
}
|
|
dy--;
|
|
}
|
|
|
|
Property *pp;
|
|
for(pp = Props.first(); pp != 0; pp = Props.next())
|
|
if(pp->display)
|
|
if((dy--) < 1) break;
|
|
if(!pp) return -1;
|
|
|
|
// get width of text
|
|
w = metrics.width(pp->Name+"="+pp->Value);
|
|
if(x_ > w) return -1;
|
|
return Props.at()+1; // number the property
|
|
}
|
|
|
|
// -------------------------------------------------------
|
|
bool Component::getSelected(int x_, int y_)
|
|
{
|
|
x_ -= cx;
|
|
y_ -= cy;
|
|
if(x_ >= x1) if(x_ <= x2) if(y_ >= y1) if(y_ <= y2)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
// -------------------------------------------------------
|
|
void Component::paint(ViewPainter *p)
|
|
{
|
|
Text *pt;
|
|
int x, y, a, b, xb, yb;
|
|
QFont f = p->Painter->font(); // save current font
|
|
QFont newFont = f;
|
|
|
|
if(Model.at(0) == '.') { // is simulation component (dc, ac, ...)
|
|
newFont.setPointSizeFloat(p->Scale * Texts.getFirst()->Size);
|
|
newFont.setWeight(QFont::DemiBold);
|
|
p->Painter->setFont(newFont);
|
|
p->map(cx, cy, x, y);
|
|
|
|
p->Painter->setPen(QPen(QPen::darkBlue,2));
|
|
a = b = 0;
|
|
QRect r, t;
|
|
for(pt = Texts.first(); pt != 0; pt = Texts.next()) {
|
|
t.setRect(x, y+b, 0, 0);
|
|
p->Painter->drawText(t, Qt::AlignLeft|Qt::DontClip, pt->s, -1, &r);
|
|
b += r.height();
|
|
if(a < r.width()) a = r.width();
|
|
}
|
|
xb = a + int(12.0*p->Scale);
|
|
yb = b + int(10.0*p->Scale);
|
|
x2 = x1+25 + int(float(a) / p->Scale);
|
|
y2 = y1+23 + int(float(b) / p->Scale);
|
|
if(ty < y2+1) if(ty > y1-r.height()) ty = y2 + 1;
|
|
|
|
p->map(cx-1, cy, x, y);
|
|
p->map(cx-6, cy-5, a, b);
|
|
p->Painter->drawRect(a, b, xb, yb);
|
|
p->Painter->drawLine(x, y+yb, a, b+yb);
|
|
p->Painter->drawLine(x+xb-1, y+yb, x, y+yb);
|
|
p->Painter->drawLine(x+xb-1, y+yb, a+xb, b+yb);
|
|
p->Painter->drawLine(x+xb-1, y+yb, x+xb-1, y);
|
|
p->Painter->drawLine(x+xb-1, y, a+xb, b);
|
|
}
|
|
else { // normal components go here
|
|
|
|
// paint all lines
|
|
for(Line *p1 = Lines.first(); p1 != 0; p1 = Lines.next()) {
|
|
p->Painter->setPen(p1->style);
|
|
p->drawLine(cx+p1->x1, cy+p1->y1, cx+p1->x2, cy+p1->y2);
|
|
}
|
|
|
|
// paint all arcs
|
|
for(Arc *p3 = Arcs.first(); p3 != 0; p3 = Arcs.next()) {
|
|
p->Painter->setPen(p3->style);
|
|
p->drawArc(cx+p3->x, cy+p3->y, p3->w, p3->h, p3->angle, p3->arclen);
|
|
}
|
|
|
|
// paint all rectangles
|
|
Area *pa;
|
|
for(pa = Rects.first(); pa != 0; pa = Rects.next()) {
|
|
p->Painter->setPen(pa->Pen);
|
|
p->Painter->setBrush(pa->Brush);
|
|
p->drawRect(cx+pa->x, cy+pa->y, pa->w, pa->h);
|
|
}
|
|
|
|
// paint all ellipses
|
|
for(pa = Ellips.first(); pa != 0; pa = Ellips.next()) {
|
|
p->Painter->setPen(pa->Pen);
|
|
p->Painter->setBrush(pa->Brush);
|
|
p->drawEllipse(cx+pa->x, cy+pa->y, pa->w, pa->h);
|
|
}
|
|
p->Painter->setBrush(QBrush::NoBrush);
|
|
|
|
newFont.setWeight(QFont::Light);
|
|
QWMatrix wm = p->Painter->worldMatrix();
|
|
// write all text
|
|
for(pt = Texts.first(); pt != 0; pt = Texts.next()) {
|
|
p->Painter->setWorldMatrix(
|
|
QWMatrix(pt->mCos, -pt->mSin, pt->mSin, pt->mCos,
|
|
p->DX + float(cx+pt->x) * p->Scale,
|
|
p->DY + float(cy+pt->y) * p->Scale));
|
|
newFont.setPointSizeFloat(p->Scale * pt->Size);
|
|
newFont.setOverline(pt->over);
|
|
newFont.setUnderline(pt->under);
|
|
p->Painter->setFont(newFont);
|
|
p->Painter->setPen(pt->Color);
|
|
if (0) {
|
|
p->Painter->drawText(0, 0, 0, 0, Qt::AlignLeft|Qt::DontClip, pt->s);
|
|
} else {
|
|
int w, h;
|
|
w = p->drawTextMapped (pt->s, 0, 0, &h);
|
|
}
|
|
}
|
|
p->Painter->setWorldMatrix(wm);
|
|
p->Painter->setWorldXForm(false);
|
|
}
|
|
|
|
// restore old font
|
|
p->Painter->setFont(f);
|
|
|
|
p->Painter->setPen(QPen(QPen::black,1));
|
|
p->map(cx+tx, cy+ty, x, y);
|
|
if(showName) {
|
|
p->Painter->drawText(x, y, 0, 0, Qt::DontClip, Name);
|
|
y += p->LineSpacing;
|
|
}
|
|
// write all properties
|
|
for(Property *p4 = Props.first(); p4 != 0; p4 = Props.next())
|
|
if(p4->display) {
|
|
p->Painter->drawText(x, y, 0, 0, Qt::DontClip, p4->Name+"="+p4->Value);
|
|
y += p->LineSpacing;
|
|
}
|
|
|
|
if(isActive == COMP_IS_OPEN)
|
|
p->Painter->setPen(QPen(QPen::red,0));
|
|
else if(isActive & COMP_IS_SHORTEN)
|
|
p->Painter->setPen(QPen(QPen::darkGreen,0));
|
|
if(isActive != COMP_IS_ACTIVE) {
|
|
p->drawRect(cx+x1, cy+y1, x2-x1+1, y2-y1+1);
|
|
p->drawLine(cx+x1, cy+y1, cx+x2, cy+y2);
|
|
p->drawLine(cx+x1, cy+y2, cx+x2, cy+y1);
|
|
}
|
|
|
|
if(isSelected) {
|
|
p->Painter->setPen(QPen(QPen::darkGray,3));
|
|
p->drawRoundRect(cx+x1, cy+y1, x2-x1, y2-y1);
|
|
}
|
|
}
|
|
|
|
// -------------------------------------------------------
|
|
// Paints the component when moved with the mouse.
|
|
void Component::paintScheme(QPainter *p)
|
|
{
|
|
if(Model.at(0) == '.') { // is simulation component (dc, ac, ...)
|
|
Text *pt;
|
|
int a, b, xb, yb;
|
|
QFont newFont = p->font();
|
|
|
|
float Scale =
|
|
((Schematic*)QucsMain->DocumentTab->currentPage())->Scale;
|
|
newFont.setPointSizeFloat(float(Scale) * QucsSettings.largeFontSize);
|
|
newFont.setWeight(QFont::DemiBold);
|
|
QFontMetrics metrics(newFont);
|
|
|
|
a = b = 0;
|
|
QSize r;
|
|
for(pt = Texts.first(); pt != 0; pt = Texts.next()) {
|
|
r = metrics.size(0, pt->s);
|
|
b += r.height();
|
|
if(a < r.width()) a = r.width();
|
|
}
|
|
xb = a + int(12.0*Scale);
|
|
yb = b + int(10.0*Scale);
|
|
x2 = x1+25 + int(float(a) / Scale);
|
|
y2 = y1+23 + int(float(b) / Scale);
|
|
if(ty < y2+1) if(ty > y1-r.height()) ty = y2 + 1;
|
|
|
|
p->drawRect(cx-6, cy-5, xb, yb);
|
|
p->drawLine(cx-1, cy+yb, cx-6, cy+yb-5);
|
|
p->drawLine(cx+xb-2, cy+yb, cx-1, cy+yb);
|
|
p->drawLine(cx+xb-2, cy+yb, cx+xb-6, cy+yb-5);
|
|
p->drawLine(cx+xb-2, cy+yb, cx+xb-2, cy);
|
|
p->drawLine(cx+xb-2, cy, cx+xb-6, cy-5);
|
|
return;
|
|
}
|
|
|
|
// paint all lines
|
|
for(Line *p1 = Lines.first(); p1 != 0; p1 = Lines.next())
|
|
p->drawLine(cx+p1->x1, cy+p1->y1, cx+p1->x2, cy+p1->y2);
|
|
|
|
// paint all ports
|
|
for(Port *p2 = Ports.first(); p2 != 0; p2 = Ports.next())
|
|
if(p2->avail) p->drawEllipse(cx+p2->x-4, cy+p2->y-4, 8, 8);
|
|
|
|
for(Arc *p3 = Arcs.first(); p3 != 0; p3 = Arcs.next()) // paint all arcs
|
|
p->drawArc(cx+p3->x, cy+p3->y, p3->w, p3->h, p3->angle, p3->arclen);
|
|
|
|
Area *pa;
|
|
for(pa = Rects.first(); pa != 0; pa = Rects.next()) // paint all rectangles
|
|
p->drawRect(cx+pa->x, cy+pa->y, pa->w, pa->h);
|
|
|
|
for(pa = Ellips.first(); pa != 0; pa = Ellips.next()) // paint all ellipses
|
|
p->drawEllipse(cx+pa->x, cy+pa->y, pa->w, pa->h);
|
|
}
|
|
|
|
// -------------------------------------------------------
|
|
// For output on a printer device.
|
|
void Component::print(ViewPainter *p, float FontScale)
|
|
{
|
|
Text *pt;
|
|
for(pt = Texts.first(); pt != 0; pt = Texts.next())
|
|
pt->Size *= FontScale;
|
|
|
|
paint(p);
|
|
|
|
for(pt = Texts.first(); pt != 0; pt = Texts.next())
|
|
pt->Size /= FontScale;
|
|
}
|
|
|
|
// -------------------------------------------------------
|
|
// Rotates the component 90 counter-clockwise around its center
|
|
void Component::rotate()
|
|
{
|
|
if(Ports.count() < 1) return; // do not rotate components without ports
|
|
int tmp, dx, dy;
|
|
|
|
// rotate all lines
|
|
for(Line *p1 = Lines.first(); p1 != 0; p1 = Lines.next()) {
|
|
tmp = -p1->x1;
|
|
p1->x1 = p1->y1;
|
|
p1->y1 = tmp;
|
|
tmp = -p1->x2;
|
|
p1->x2 = p1->y2;
|
|
p1->y2 = tmp;
|
|
}
|
|
|
|
// rotate all ports
|
|
for(Port *p2 = Ports.first(); p2 != 0; p2 = Ports.next()) {
|
|
tmp = -p2->x;
|
|
p2->x = p2->y;
|
|
p2->y = tmp;
|
|
}
|
|
|
|
// rotate all arcs
|
|
for(Arc *p3 = Arcs.first(); p3 != 0; p3 = Arcs.next()) {
|
|
tmp = -p3->x;
|
|
p3->x = p3->y;
|
|
p3->y = tmp - p3->w;
|
|
tmp = p3->w;
|
|
p3->w = p3->h;
|
|
p3->h = tmp;
|
|
p3->angle += 16*90;
|
|
if(p3->angle >= 16*360) p3->angle -= 16*360;;
|
|
}
|
|
|
|
Area *pa;
|
|
// rotate all rectangles
|
|
for(pa = Rects.first(); pa != 0; pa = Rects.next()) {
|
|
tmp = -pa->x;
|
|
pa->x = pa->y;
|
|
pa->y = tmp - pa->w;
|
|
tmp = pa->w;
|
|
pa->w = pa->h;
|
|
pa->h = tmp;
|
|
}
|
|
|
|
// rotate all ellipses
|
|
for(pa = Ellips.first(); pa != 0; pa = Ellips.next()) {
|
|
tmp = -pa->x;
|
|
pa->x = pa->y;
|
|
pa->y = tmp - pa->w;
|
|
tmp = pa->w;
|
|
pa->w = pa->h;
|
|
pa->h = tmp;
|
|
}
|
|
|
|
// rotate all text
|
|
float ftmp;
|
|
for(Text *pt = Texts.first(); pt != 0; pt = Texts.next()) {
|
|
tmp = -pt->x;
|
|
pt->x = pt->y;
|
|
pt->y = tmp;
|
|
|
|
ftmp = -pt->mSin;
|
|
pt->mSin = pt->mCos;
|
|
pt->mCos = ftmp;
|
|
}
|
|
|
|
tmp = -x1; // rotate boundings
|
|
x1 = y1; y1 = -x2;
|
|
x2 = y2; y2 = tmp;
|
|
|
|
tmp = -tx; // rotate text position
|
|
tx = ty;
|
|
ty = tmp;
|
|
QFontMetrics metrics(QucsSettings.font); // get size of text
|
|
dx = dy = 0;
|
|
if(showName) {
|
|
dx = metrics.width(Name);
|
|
dy = metrics.lineSpacing();
|
|
}
|
|
for(Property *pp = Props.first(); pp != 0; pp = Props.next())
|
|
if(pp->display) {
|
|
// get width of text
|
|
tmp = metrics.width(pp->Name+"="+pp->Value);
|
|
if(tmp > dx) dx = tmp;
|
|
dy += metrics.lineSpacing();
|
|
}
|
|
if(tx > x2) ty = y1-ty+y2; // rotate text position
|
|
else if(ty < y1) ty -= dy;
|
|
else if(tx < x1) { tx += dy-dx; ty = y1-ty+y2; }
|
|
else ty -= dx;
|
|
|
|
rotated++; // keep track of what's done
|
|
rotated &= 3;
|
|
}
|
|
|
|
// -------------------------------------------------------
|
|
// Mirrors the component about the x-axis.
|
|
void Component::mirrorX()
|
|
{
|
|
if(Ports.count() < 1) return; // do not rotate components without ports
|
|
|
|
// mirror all lines
|
|
for(Line *p1 = Lines.first(); p1 != 0; p1 = Lines.next()) {
|
|
p1->y1 = -p1->y1;
|
|
p1->y2 = -p1->y2;
|
|
}
|
|
|
|
// mirror all ports
|
|
for(Port *p2 = Ports.first(); p2 != 0; p2 = Ports.next())
|
|
p2->y = -p2->y;
|
|
|
|
// mirror all arcs
|
|
for(Arc *p3 = Arcs.first(); p3 != 0; p3 = Arcs.next()) {
|
|
p3->y = -p3->y - p3->h;
|
|
if(p3->angle > 16*180) p3->angle -= 16*360;
|
|
p3->angle = -p3->angle; // mirror
|
|
p3->angle -= p3->arclen; // go back to end of arc
|
|
if(p3->angle < 0) p3->angle += 16*360; // angle has to be > 0
|
|
}
|
|
|
|
Area *pa;
|
|
// mirror all rectangles
|
|
for(pa = Rects.first(); pa != 0; pa = Rects.next())
|
|
pa->y = -pa->y - pa->h;
|
|
|
|
// mirror all ellipses
|
|
for(pa = Ellips.first(); pa != 0; pa = Ellips.next())
|
|
pa->y = -pa->y - pa->h;
|
|
|
|
QFont f = QucsSettings.font;
|
|
// mirror all text
|
|
for(Text *pt = Texts.first(); pt != 0; pt = Texts.next()) {
|
|
f.setPointSizeFloat(pt->Size);
|
|
QFontMetrics smallMetrics(f);
|
|
QSize s = smallMetrics.size(0, pt->s); // use size for more lines
|
|
pt->y = -pt->y - int(pt->mCos)*s.height() + int(pt->mSin)*s.width();
|
|
}
|
|
|
|
int tmp = y1;
|
|
y1 = -y2; y2 = -tmp; // mirror boundings
|
|
|
|
QFontMetrics metrics(QucsSettings.font); // get size of text
|
|
int dy = 0;
|
|
if(showName)
|
|
dy = metrics.lineSpacing(); // for "Name"
|
|
for(Property *pp = Props.first(); pp != 0; pp = Props.next())
|
|
if(pp->display) dy += metrics.lineSpacing();
|
|
if((tx > x1) && (tx < x2)) ty = -ty-dy; // mirror text position
|
|
else ty = y1+ty+y2;
|
|
|
|
mirroredX = !mirroredX; // keep track of what's done
|
|
rotated += rotated << 1;
|
|
rotated &= 3;
|
|
}
|
|
|
|
// -------------------------------------------------------
|
|
// Mirrors the component about the y-axis.
|
|
void Component::mirrorY()
|
|
{
|
|
if(Ports.count() < 1) return; // do not rotate components without ports
|
|
|
|
// mirror all lines
|
|
for(Line *p1 = Lines.first(); p1 != 0; p1 = Lines.next()) {
|
|
p1->x1 = -p1->x1;
|
|
p1->x2 = -p1->x2;
|
|
}
|
|
|
|
// mirror all ports
|
|
for(Port *p2 = Ports.first(); p2 != 0; p2 = Ports.next())
|
|
p2->x = -p2->x;
|
|
|
|
// mirror all arcs
|
|
for(Arc *p3 = Arcs.first(); p3 != 0; p3 = Arcs.next()) {
|
|
p3->x = -p3->x - p3->w;
|
|
p3->angle = 16*180 - p3->angle - p3->arclen; // mirror
|
|
if(p3->angle < 0) p3->angle += 16*360; // angle has to be > 0
|
|
}
|
|
|
|
Area *pa;
|
|
// mirror all rectangles
|
|
for(pa = Rects.first(); pa != 0; pa = Rects.next())
|
|
pa->x = -pa->x - pa->w;
|
|
|
|
// mirror all ellipses
|
|
for(pa = Ellips.first(); pa != 0; pa = Ellips.next())
|
|
pa->x = -pa->x - pa->w;
|
|
|
|
int tmp;
|
|
QFont f = QucsSettings.font;
|
|
// mirror all text
|
|
for(Text *pt = Texts.first(); pt != 0; pt = Texts.next()) {
|
|
f.setPointSizeFloat(pt->Size);
|
|
QFontMetrics smallMetrics(f);
|
|
QSize s = smallMetrics.size(0, pt->s); // use size for more lines
|
|
pt->x = -pt->x - int(pt->mSin)*s.height() - int(pt->mCos)*s.width();
|
|
}
|
|
|
|
tmp = x1;
|
|
x1 = -x2; x2 = -tmp; // mirror boundings
|
|
|
|
QFontMetrics metrics(QucsSettings.font); // get size of text
|
|
int dx = 0;
|
|
if(showName)
|
|
dx = metrics.width(Name);
|
|
for(Property *pp = Props.first(); pp != 0; pp = Props.next())
|
|
if(pp->display) {
|
|
// get width of text
|
|
tmp = metrics.width(pp->Name+"="+pp->Value);
|
|
if(tmp > dx) dx = tmp;
|
|
}
|
|
if((ty > y1) && (ty < y2)) tx = -tx-dx; // mirror text position
|
|
else tx = x1+tx+x2;
|
|
|
|
mirroredX = !mirroredX; // keep track of what's done
|
|
rotated += rotated << 1;
|
|
rotated += 2;
|
|
rotated &= 3;
|
|
}
|
|
|
|
// -------------------------------------------------------
|
|
QString Component::netlist()
|
|
{
|
|
QString s = Model+":"+Name;
|
|
|
|
// output all node names
|
|
for(Port *p1 = Ports.first(); p1 != 0; p1 = Ports.next())
|
|
s += " "+p1->Connection->Name; // node names
|
|
|
|
// output all properties
|
|
for(Property *p2 = Props.first(); p2 != 0; p2 = Props.next())
|
|
if(p2->Name != "Symbol")
|
|
s += " "+p2->Name+"=\""+p2->Value+"\"";
|
|
|
|
return s + '\n';
|
|
}
|
|
|
|
// -------------------------------------------------------
|
|
QString Component::getNetlist()
|
|
{
|
|
switch(isActive) {
|
|
case COMP_IS_ACTIVE:
|
|
return netlist();
|
|
case COMP_IS_OPEN:
|
|
return QString("");
|
|
}
|
|
|
|
// Component is shortened.
|
|
int z=0;
|
|
QString s;
|
|
QString Node1 = Ports.first()->Connection->Name;
|
|
for(Port *pp = Ports.next(); pp != 0; pp = Ports.next())
|
|
s += "R:" + Name + "." + QString::number(z++) + " " +
|
|
Node1 + " " + pp->Connection->Name + " R=\"0\"\n";
|
|
return s;
|
|
}
|
|
|
|
// -------------------------------------------------------
|
|
QString Component::verilogCode(int)
|
|
{
|
|
return QString(""); // no digital model
|
|
}
|
|
|
|
// -------------------------------------------------------
|
|
QString Component::get_Verilog_Code(int NumPorts)
|
|
{
|
|
switch(isActive) {
|
|
case COMP_IS_OPEN:
|
|
return QString("");
|
|
case COMP_IS_ACTIVE:
|
|
return verilogCode(NumPorts);
|
|
}
|
|
|
|
// Component is shortened.
|
|
Port *p = Ports.first();
|
|
QString Node1 = p->Connection->Name;
|
|
QString s = "";
|
|
for(p = Ports.next(); p != 0; p = Ports.next())
|
|
s += " assign " + p->Connection->Name + " = " + Node1 + ";\n";
|
|
return s;
|
|
}
|
|
|
|
// -------------------------------------------------------
|
|
QString Component::vhdlCode(int)
|
|
{
|
|
return QString(""); // no digital model
|
|
}
|
|
|
|
// -------------------------------------------------------
|
|
QString Component::get_VHDL_Code(int NumPorts)
|
|
{
|
|
switch(isActive) {
|
|
case COMP_IS_OPEN:
|
|
return QString("");
|
|
case COMP_IS_ACTIVE:
|
|
return vhdlCode(NumPorts);
|
|
}
|
|
|
|
// Component is shortened.
|
|
// This puts the signal of the second port onto the first port.
|
|
// This is locigally correct for the inverter only, but makes
|
|
// some sense for the gates (OR, AND etc.).
|
|
// Has anyone a better idea?
|
|
QString Node1 = Ports.first()->Connection->Name;
|
|
return " " + Node1 + " <= " + Ports.next()->Connection->Name + ";\n";
|
|
}
|
|
|
|
// -------------------------------------------------------
|
|
QString Component::save()
|
|
{
|
|
#if XML
|
|
QDomDocument doc;
|
|
QDomElement el = doc.createElement (Model);
|
|
doc.appendChild (el);
|
|
el.setTagName (Model);
|
|
el.setAttribute ("inst", Name.isEmpty() ? "*" : Name);
|
|
el.setAttribute ("display", isActive | (showName ? 4 : 0));
|
|
el.setAttribute ("cx", cx);
|
|
el.setAttribute ("cy", cy);
|
|
el.setAttribute ("tx", tx);
|
|
el.setAttribute ("ty", ty);
|
|
el.setAttribute ("mirror", mirroredX);
|
|
el.setAttribute ("rotate", rotated);
|
|
|
|
for (Property *pr = Props.first(); pr != 0; pr = Props.next()) {
|
|
el.setAttribute (pr->Name, (pr->display ? "1@" : "0@") + pr->Value);
|
|
}
|
|
qDebug (doc.toString());
|
|
#endif
|
|
QString s = "<" + Model;
|
|
|
|
if(Name.isEmpty()) s += " * ";
|
|
else s += " "+Name+" ";
|
|
|
|
int i=0;
|
|
if(!showName)
|
|
i = 4;
|
|
i |= isActive;
|
|
s += QString::number(i);
|
|
s += " "+QString::number(cx)+" "+QString::number(cy);
|
|
s += " "+QString::number(tx)+" "+QString::number(ty);
|
|
if(mirroredX) s += " 1";
|
|
else s += " 0";
|
|
s += " "+QString::number(rotated);
|
|
|
|
// write all properties
|
|
for(Property *p1 = Props.first(); p1 != 0; p1 = Props.next()) {
|
|
if(p1->Description.isEmpty())
|
|
s += " \""+p1->Name+"="+p1->Value+"\""; // e.g. for equations
|
|
else s += " \""+p1->Value+"\"";
|
|
if(p1->display) s += " 1";
|
|
else s += " 0";
|
|
}
|
|
|
|
return s+">";
|
|
}
|
|
|
|
// -------------------------------------------------------
|
|
bool Component::load(const QString& _s)
|
|
{
|
|
bool ok;
|
|
int ttx, tty, tmp;
|
|
QString s = _s;
|
|
|
|
if(s.at(0) != '<') return false;
|
|
if(s.at(s.length()-1) != '>') return false;
|
|
s = s.mid(1, s.length()-2); // cut off start and end character
|
|
|
|
QString n;
|
|
Name = s.section(' ',1,1); // Name
|
|
if(Name == "*") Name = "";
|
|
|
|
n = s.section(' ',2,2); // isActive
|
|
tmp = n.toInt(&ok);
|
|
if(!ok) return false;
|
|
isActive = tmp & 3;
|
|
|
|
if(tmp & 4)
|
|
showName = false;
|
|
else
|
|
showName = true;
|
|
|
|
n = s.section(' ',3,3); // cx
|
|
cx = n.toInt(&ok);
|
|
if(!ok) return false;
|
|
|
|
n = s.section(' ',4,4); // cy
|
|
cy = n.toInt(&ok);
|
|
if(!ok) return false;
|
|
|
|
n = s.section(' ',5,5); // tx
|
|
ttx = n.toInt(&ok);
|
|
if(!ok) return false;
|
|
|
|
n = s.section(' ',6,6); // ty
|
|
tty = n.toInt(&ok);
|
|
if(!ok) return false;
|
|
|
|
if(Model.at(0) != '.') { // is simulation component (dc, ac, ...) ?
|
|
|
|
n = s.section(' ',7,7); // mirroredX
|
|
if(n.toInt(&ok) == 1) mirrorX();
|
|
if(!ok) return false;
|
|
|
|
n = s.section(' ',8,8); // rotated
|
|
tmp = n.toInt(&ok);
|
|
if(!ok) return false;
|
|
if(rotated > tmp) // neccessary because of historical flaw in ...
|
|
tmp += 4; // ... components like "volt_dc"
|
|
for(int z=rotated; z<tmp; z++) rotate();
|
|
|
|
}
|
|
|
|
tx = ttx; ty = tty; // restore text position (was changed by rotate/mirror)
|
|
|
|
unsigned int z=0, counts = s.contains('"');
|
|
if(Model == "Sub")
|
|
tmp = 2; // first property (File) already exists
|
|
else if(Model == "Lib")
|
|
tmp = 3;
|
|
else if(Model == "EDD")
|
|
tmp = 5;
|
|
else if(Model == "RFEDD")
|
|
tmp = 8;
|
|
else if(Model == "VHDL")
|
|
tmp = 2;
|
|
else tmp = counts + 1; // "+1" because "counts" could be zero
|
|
|
|
for(; tmp<=(int)counts/2; tmp++)
|
|
Props.append(new Property("p", "", true, " "));
|
|
|
|
// load all properties
|
|
Property *p1;
|
|
for(p1 = Props.first(); p1 != 0; p1 = Props.next()) {
|
|
z++;
|
|
n = s.section('"',z,z); // property value
|
|
z++;
|
|
// not all properties have to be mentioned (backward compatible)
|
|
if(z > counts) {
|
|
if(p1->Description.isEmpty())
|
|
Props.remove(); // remove if allocated in vain
|
|
|
|
if(Model == "Diode") {
|
|
if(counts < 56) { // backward compatible
|
|
counts >>= 1;
|
|
p1 = Props.at(counts-1);
|
|
for(; p1 != 0; p1 = Props.current()) {
|
|
if(counts-- < 19)
|
|
break;
|
|
|
|
n = Props.prev()->Value;
|
|
p1->Value = n;
|
|
}
|
|
|
|
p1 = Props.at(17);
|
|
p1->Value = Props.at(11)->Value;
|
|
Props.current()->Value = "0";
|
|
}
|
|
}
|
|
else if(Model == "AND" || Model == "NAND" || Model == "NOR" ||
|
|
Model == "OR" || Model == "XNOR"|| Model == "XOR") {
|
|
if(counts < 10) { // backward compatible
|
|
counts >>= 1;
|
|
p1 = Props.at(counts);
|
|
for(; p1 != 0; p1 = Props.current()) {
|
|
if(counts-- < 4)
|
|
break;
|
|
n = Props.prev()->Value;
|
|
p1->Value = n;
|
|
}
|
|
Props.current()->Value = "10";
|
|
}
|
|
}
|
|
else if(Model == "Buf" || Model == "Inv") {
|
|
if(counts < 8) { // backward compatible
|
|
counts >>= 1;
|
|
p1 = Props.at(counts);
|
|
for(; p1 != 0; p1 = Props.current()) {
|
|
if(counts-- < 3)
|
|
break;
|
|
n = Props.prev()->Value;
|
|
p1->Value = n;
|
|
}
|
|
Props.current()->Value = "10";
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// for equations
|
|
if(Model != "EDD" && Model != "RFEDD" && Model != "RFEDD2P")
|
|
if(p1->Description.isEmpty()) { // unknown number of properties ?
|
|
p1->Name = n.section('=',0,0);
|
|
n = n.section('=',1);
|
|
// allocate memory for a new property (e.g. for equations)
|
|
if(Props.count() < (counts>>1)) {
|
|
Props.insert(z >> 1, new Property("y", "1", true));
|
|
Props.prev();
|
|
}
|
|
}
|
|
if(z == 6) if(counts == 6) // backward compatible
|
|
if(Model == "R") {
|
|
Props.getLast()->Value = n;
|
|
return true;
|
|
}
|
|
p1->Value = n;
|
|
|
|
n = s.section('"',z,z); // display
|
|
p1->display = (n.at(1) == '1');
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// *******************************************************************
|
|
// *** The following functions are used to load the schematic symbol
|
|
// *** from file. (e.g. subcircuit, library component)
|
|
|
|
int Component::analyseLine(const QString& Row, int numProps)
|
|
{
|
|
QPen Pen;
|
|
QBrush Brush;
|
|
QColor Color;
|
|
QString s;
|
|
int i1, i2, i3, i4, i5, i6;
|
|
|
|
s = Row.section(' ',0,0); // component type
|
|
if((s == "PortSym") || (s == ".PortSym")) { // backward compatible
|
|
if(!getIntegers(Row, &i1, &i2, &i3))
|
|
return -1;
|
|
for(i6 = Ports.count(); i6<i3; i6++) // if ports not in numerical order
|
|
Ports.append(new Port(0, 0, false));
|
|
|
|
Ports.at(i3-1)->x = i1;
|
|
Ports.current()->y = i2;
|
|
Ports.current()->avail = true;
|
|
|
|
if(i1 < x1) x1 = i1; // keep track of component boundings
|
|
if(i1 > x2) x2 = i1;
|
|
if(i2 < y1) y1 = i2;
|
|
if(i2 > y2) y2 = i2;
|
|
return 0; // do not count Ports
|
|
}
|
|
else if(s == "Line") {
|
|
if(!getIntegers(Row, &i1, &i2, &i3, &i4)) return -1;
|
|
if(!getPen(Row, Pen, 5)) return -1;
|
|
i3 += i1;
|
|
i4 += i2;
|
|
Lines.append(new Line(i1, i2, i3, i4, Pen));
|
|
|
|
if(i1 < x1) x1 = i1; // keep track of component boundings
|
|
if(i1 > x2) x2 = i1;
|
|
if(i2 < y1) y1 = i2;
|
|
if(i2 > y2) y2 = i2;
|
|
if(i3 < x1) x1 = i3;
|
|
if(i3 > x2) x2 = i3;
|
|
if(i4 < y1) y1 = i4;
|
|
if(i4 > y2) y2 = i4;
|
|
return 1;
|
|
}
|
|
else if(s == "EArc") {
|
|
if(!getIntegers(Row, &i1, &i2, &i3, &i4, &i5, &i6))
|
|
return -1;
|
|
if(!getPen(Row, Pen, 7)) return -1;
|
|
Arcs.append(new struct Arc(i1, i2, i3, i4, i5, i6, Pen));
|
|
|
|
if(i1 < x1) x1 = i1; // keep track of component boundings
|
|
if(i1+i3 > x2) x2 = i1+i3;
|
|
if(i2 < y1) y1 = i2;
|
|
if(i2+i4 > y2) y2 = i2+i4;
|
|
return 1;
|
|
}
|
|
else if(s == ".ID") {
|
|
if(!getIntegers(Row, &i1, &i2)) return -1;
|
|
tx = i1;
|
|
ty = i2;
|
|
Name = Row.section(' ',3,3);
|
|
if(Name.isEmpty()) Name = "SUB";
|
|
|
|
i1 = 1;
|
|
Property *pp = Props.at(numProps-1);
|
|
for(;;) {
|
|
s = Row.section('"', i1,i1);
|
|
if(s.isEmpty()) break;
|
|
|
|
pp = Props.next();
|
|
if(pp == 0) {
|
|
pp = new Property();
|
|
Props.append(pp);
|
|
|
|
pp->display = (s.at(0) == '1');
|
|
pp->Value = s.section('=', 2,2);
|
|
}
|
|
|
|
pp->Name = s.section('=', 1,1);
|
|
pp->Description = s.section('=', 3,3);
|
|
if(pp->Description.isEmpty())
|
|
pp->Description = " ";
|
|
|
|
i1 += 2;
|
|
}
|
|
|
|
while(pp != Props.last())
|
|
Props.remove();
|
|
return 0; // do not count IDs
|
|
}
|
|
else if(s == "Arrow") {
|
|
if(!getIntegers(Row, &i1, &i2, &i3, &i4, &i5, &i6)) return -1;
|
|
if(!getPen(Row, Pen, 7)) return -1;
|
|
|
|
double beta = atan2(double(i6), double(i5));
|
|
double phi = atan2(double(i4), double(i3));
|
|
double Length = sqrt(double(i6*i6 + i5*i5));
|
|
|
|
i3 += i1;
|
|
i4 += i2;
|
|
if(i1 < x1) x1 = i1; // keep track of component boundings
|
|
if(i1 > x2) x2 = i1;
|
|
if(i3 < x1) x1 = i3;
|
|
if(i3 > x2) x2 = i3;
|
|
if(i2 < y1) y1 = i2;
|
|
if(i2 > y2) y2 = i2;
|
|
if(i4 < y1) y1 = i4;
|
|
if(i4 > y2) y2 = i4;
|
|
|
|
Lines.append(new Line(i1, i2, i3, i4, Pen)); // base line
|
|
|
|
double w = beta+phi;
|
|
i5 = i3-int(Length*cos(w));
|
|
i6 = i4-int(Length*sin(w));
|
|
Lines.append(new Line(i3, i4, i5, i6, Pen)); // arrow head
|
|
if(i5 < x1) x1 = i5; // keep track of component boundings
|
|
if(i5 > x2) x2 = i5;
|
|
if(i6 < y1) y1 = i6;
|
|
if(i6 > y2) y2 = i6;
|
|
|
|
w = phi-beta;
|
|
i5 = i3-int(Length*cos(w));
|
|
i6 = i4-int(Length*sin(w));
|
|
Lines.append(new Line(i3, i4, i5, i6, Pen));
|
|
if(i5 < x1) x1 = i5; // keep track of component boundings
|
|
if(i5 > x2) x2 = i5;
|
|
if(i6 < y1) y1 = i6;
|
|
if(i6 > y2) y2 = i6;
|
|
|
|
return 1;
|
|
}
|
|
else if(s == "Ellipse") {
|
|
if(!getIntegers(Row, &i1, &i2, &i3, &i4)) return -1;
|
|
if(!getPen(Row, Pen, 5)) return -1;
|
|
if(!getBrush(Row, Brush, 8)) return -1;
|
|
Ellips.append(new Area(i1, i2, i3, i4, Pen, Brush));
|
|
|
|
if(i1 < x1) x1 = i1; // keep track of component boundings
|
|
if(i1 > x2) x2 = i1;
|
|
if(i2 < y1) y1 = i2;
|
|
if(i2 > y2) y2 = i2;
|
|
if(i1+i3 < x1) x1 = i1+i3;
|
|
if(i1+i3 > x2) x2 = i1+i3;
|
|
if(i2+i4 < y1) y1 = i2+i4;
|
|
if(i2+i4 > y2) y2 = i2+i4;
|
|
return 1;
|
|
}
|
|
else if(s == "Rectangle") {
|
|
if(!getIntegers(Row, &i1, &i2, &i3, &i4)) return -1;
|
|
if(!getPen(Row, Pen, 5)) return -1;
|
|
if(!getBrush(Row, Brush, 8)) return -1;
|
|
Rects.append(new Area(i1, i2, i3, i4, Pen, Brush));
|
|
|
|
if(i1 < x1) x1 = i1; // keep track of component boundings
|
|
if(i1 > x2) x2 = i1;
|
|
if(i2 < y1) y1 = i2;
|
|
if(i2 > y2) y2 = i2;
|
|
if(i1+i3 < x1) x1 = i1+i3;
|
|
if(i1+i3 > x2) x2 = i1+i3;
|
|
if(i2+i4 < y1) y1 = i2+i4;
|
|
if(i2+i4 > y2) y2 = i2+i4;
|
|
return 1;
|
|
}
|
|
else if(s == "Text") { // must be last in order to reuse "s" *********
|
|
if(!getIntegers(Row, &i1, &i2, &i3, 0, &i4)) return -1;
|
|
Color.setNamedColor(Row.section(' ',4,4));
|
|
if(!Color.isValid()) return -1;
|
|
|
|
s = Row.mid(Row.find('"')+1); // Text (can contain " !!!)
|
|
s = s.left(s.length()-1);
|
|
if(s.isEmpty()) return -1;
|
|
convert2Unicode(s);
|
|
|
|
Texts.append(new Text(i1, i2, s, Color, float(i3),
|
|
float(cos(float(i4)*M_PI/180.0)),
|
|
float(sin(float(i4)*M_PI/180.0))));
|
|
|
|
QFont Font(QucsSettings.font);
|
|
Font.setPointSizeFloat(float(i3));
|
|
QFontMetrics metrics(Font);
|
|
QSize r = metrics.size(0, s); // get size of text
|
|
i3 = i1 + int(float(r.width()) * Texts.current()->mCos)
|
|
+ int(float(r.height()) * Texts.current()->mSin);
|
|
i4 = i2 + int(float(r.width()) * -Texts.current()->mSin)
|
|
+ int(float(r.height()) * Texts.current()->mCos);
|
|
|
|
if(i1 < x1) x1 = i1; // keep track of component boundings
|
|
if(i2 < y1) y1 = i2;
|
|
if(i1 > x2) x2 = i1;
|
|
if(i2 > y2) y2 = i2;
|
|
|
|
if(i3 < x1) x1 = i3;
|
|
if(i4 < y1) y1 = i4;
|
|
if(i3 > x2) x2 = i3;
|
|
if(i4 > y2) y2 = i4;
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
bool Component::getIntegers(const QString& s, int *i1, int *i2, int *i3,
|
|
int *i4, int *i5, int *i6)
|
|
{
|
|
bool ok;
|
|
QString n;
|
|
|
|
if(!i1) return true;
|
|
n = s.section(' ',1,1);
|
|
*i1 = n.toInt(&ok);
|
|
if(!ok) return false;
|
|
|
|
if(!i2) return true;
|
|
n = s.section(' ',2,2);
|
|
*i2 = n.toInt(&ok);
|
|
if(!ok) return false;
|
|
|
|
if(!i3) return true;
|
|
n = s.section(' ',3,3);
|
|
*i3 = n.toInt(&ok);
|
|
if(!ok) return false;
|
|
|
|
if(i4) {
|
|
n = s.section(' ',4,4);
|
|
*i4 = n.toInt(&ok);
|
|
if(!ok) return false;
|
|
}
|
|
|
|
if(!i5) return true;
|
|
n = s.section(' ',5,5);
|
|
*i5 = n.toInt(&ok);
|
|
if(!ok) return false;
|
|
|
|
if(!i6) return true;
|
|
n = s.section(' ',6,6);
|
|
*i6 = n.toInt(&ok);
|
|
if(!ok) return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
bool Component::getPen(const QString& s, QPen& Pen, int i)
|
|
{
|
|
bool ok;
|
|
QString n;
|
|
|
|
n = s.section(' ',i,i); // color
|
|
QColor co;
|
|
co.setNamedColor(n);
|
|
Pen.setColor(co);
|
|
if(!Pen.color().isValid()) return false;
|
|
|
|
i++;
|
|
n = s.section(' ',i,i); // thickness
|
|
Pen.setWidth(n.toInt(&ok));
|
|
if(!ok) return false;
|
|
|
|
i++;
|
|
n = s.section(' ',i,i); // line style
|
|
Pen.setStyle((Qt::PenStyle)n.toInt(&ok));
|
|
if(!ok) return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
bool Component::getBrush(const QString& s, QBrush& Brush, int i)
|
|
{
|
|
bool ok;
|
|
QString n;
|
|
|
|
n = s.section(' ',i,i); // fill color
|
|
QColor co;
|
|
co.setNamedColor(n);
|
|
Brush.setColor(co);
|
|
if(!Brush.color().isValid()) return false;
|
|
|
|
i++;
|
|
n = s.section(' ',i,i); // fill style
|
|
Brush.setStyle((Qt::BrushStyle)n.toInt(&ok));
|
|
if(!ok) return false;
|
|
|
|
i++;
|
|
n = s.section(' ',i,i); // filled
|
|
if(n.toInt(&ok) == 0) Brush.setStyle(QBrush::NoBrush);
|
|
if(!ok) return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
Property * Component::getProperty(const QString& name)
|
|
{
|
|
for(Property *pp = Props.first(); pp != 0; pp = Props.next())
|
|
if(pp->Name == name) {
|
|
return pp;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
void Component::copyComponent(Component *pc)
|
|
{
|
|
Type = pc->Type;
|
|
x1 = pc->x1;
|
|
y1 = pc->y1;
|
|
x2 = pc->x2;
|
|
y2 = pc->y2;
|
|
|
|
Model = pc->Model;
|
|
Name = pc->Name;
|
|
showName = pc->showName;
|
|
Description = pc->Description;
|
|
|
|
isActive = pc->isActive;
|
|
rotated = pc->rotated;
|
|
mirroredX = pc->mirroredX;
|
|
tx = pc->tx;
|
|
ty = pc->ty;
|
|
|
|
Props = pc->Props;
|
|
Ports = pc->Ports;
|
|
Lines = pc->Lines;
|
|
Arcs = pc->Arcs;
|
|
Rects = pc->Rects;
|
|
Ellips = pc->Ellips;
|
|
Texts = pc->Texts;
|
|
}
|
|
|
|
|
|
// ***********************************************************************
|
|
// ******** ********
|
|
// ******** Functions of class MultiViewComponent ********
|
|
// ******** ********
|
|
// ***********************************************************************
|
|
void MultiViewComponent::recreate(Schematic *Doc)
|
|
{
|
|
if(Doc) {
|
|
Doc->Components->setAutoDelete(false);
|
|
Doc->deleteComp(this);
|
|
}
|
|
|
|
Ellips.clear();
|
|
Texts.clear();
|
|
Ports.clear();
|
|
Lines.clear();
|
|
Rects.clear();
|
|
Arcs.clear();
|
|
createSymbol();
|
|
|
|
bool mmir = mirroredX;
|
|
int rrot = rotated;
|
|
if(mmir) mirrorX(); // mirror
|
|
for(int z=0; z<rrot; z++) rotate(); // rotate
|
|
|
|
rotated = rrot; // restore properties (were changed by rotate/mirror)
|
|
mirroredX = mmir;
|
|
|
|
if(Doc) {
|
|
Doc->insertRawComponent(this);
|
|
Doc->Components->setAutoDelete(true);
|
|
}
|
|
}
|
|
|
|
|
|
// ***********************************************************************
|
|
// ******** ********
|
|
// ******** Functions of class GateComponent ********
|
|
// ******** ********
|
|
// ***********************************************************************
|
|
GateComponent::GateComponent()
|
|
{
|
|
Type = isComponent; // both analog and digital
|
|
Name = "Y";
|
|
|
|
// the list order must be preserved !!!
|
|
Props.append(new Property("in", "2", false,
|
|
QObject::tr("number of input ports")));
|
|
Props.append(new Property("V", "1 V", false,
|
|
QObject::tr("voltage of high level")));
|
|
Props.append(new Property("t", "0", false,
|
|
QObject::tr("delay time")));
|
|
Props.append(new Property("TR", "10", false,
|
|
QObject::tr("transfer function scaling factor")));
|
|
|
|
// this must be the last property in the list !!!
|
|
Props.append(new Property("Symbol", "old", false,
|
|
QObject::tr("schematic symbol")+" [old, DIN40900]"));
|
|
}
|
|
|
|
// -------------------------------------------------------
|
|
QString GateComponent::netlist()
|
|
{
|
|
QString s = Model+":"+Name;
|
|
|
|
// output all node names
|
|
for(Port *pp = Ports.first(); pp != 0; pp = Ports.next())
|
|
s += " "+pp->Connection->Name; // node names
|
|
|
|
// output all properties
|
|
Property *p = Props.at(1);
|
|
s += " " + p->Name + "=\"" + p->Value + "\"";
|
|
p = Props.next();
|
|
s += " " + p->Name + "=\"" + p->Value + "\"";
|
|
p = Props.next();
|
|
s += " " + p->Name + "=\"" + p->Value + "\"\n";
|
|
return s;
|
|
}
|
|
|
|
// -------------------------------------------------------
|
|
QString GateComponent::vhdlCode(int NumPorts)
|
|
{
|
|
Port *pp = Ports.first();
|
|
QString s = " " + pp->Connection->Name + " <= "; // output port
|
|
|
|
// xnor NOT defined for std_logic, so here use not and xor
|
|
if (Model == "XNOR") {
|
|
QString Op = " xor ";
|
|
|
|
// first input port
|
|
pp = Ports.next();
|
|
QString rhs = pp->Connection->Name;
|
|
|
|
// output all input ports with node names
|
|
for (pp = Ports.next (); pp != 0; pp = Ports.next ())
|
|
rhs = "not ((" + rhs + ")" + Op + pp->Connection->Name + ")";
|
|
s += rhs;
|
|
}
|
|
else {
|
|
QString Op = ' ' + Model.lower() + ' ';
|
|
if(Model.at(0) == 'N') {
|
|
s += "not ("; // nor, nand is NOT assoziative !!! but xnor is !!!
|
|
Op = Op.remove(1, 1);
|
|
}
|
|
|
|
pp = Ports.next();
|
|
s += pp->Connection->Name; // first input port
|
|
|
|
// output all input ports with node names
|
|
for(pp = Ports.next(); pp != 0; pp = Ports.next())
|
|
s += Op + pp->Connection->Name;
|
|
if(Model.at(0) == 'N')
|
|
s += ')';
|
|
}
|
|
|
|
if(NumPorts <= 0) { // no truth table simulation ?
|
|
QString td = Props.at(2)->Value; // delay time
|
|
if(!VHDL_Delay(td, Name)) return td;
|
|
s += td;
|
|
}
|
|
|
|
s += ";\n";
|
|
return s;
|
|
}
|
|
|
|
// -------------------------------------------------------
|
|
QString GateComponent::verilogCode(int NumPorts)
|
|
{
|
|
bool synthesize = true;
|
|
Port *pp = Ports.first();
|
|
QString s("");
|
|
|
|
if(synthesize) {
|
|
QString op = Model.lower();
|
|
if(op == "and" || op == "nand")
|
|
op = "&";
|
|
else if (op == "or" || op == "nor")
|
|
op = "|";
|
|
else if (op == "xor")
|
|
op = "^";
|
|
else if (op == "xnor")
|
|
op = "^~";
|
|
|
|
s = " assign";
|
|
|
|
if(NumPorts <= 0) { // no truth table simulation ?
|
|
QString td = Props.at(2)->Value; // delay time
|
|
if(!Verilog_Delay(td, Name)) return td;
|
|
s += td;
|
|
}
|
|
s += " " + pp->Connection->Name + " = "; // output port
|
|
if(Model.at(0) == 'N') s += "~(";
|
|
|
|
pp = Ports.next();
|
|
s += pp->Connection->Name; // first input port
|
|
|
|
// output all input ports with node names
|
|
for(pp = Ports.next(); pp != 0; pp = Ports.next())
|
|
s += " " + op + " " + pp->Connection->Name;
|
|
|
|
if(Model.at(0) == 'N') s += ")";
|
|
s += ";\n";
|
|
}
|
|
else {
|
|
s = " " + Model.lower();
|
|
|
|
if(NumPorts <= 0) { // no truth table simulation ?
|
|
QString td = Props.at(2)->Value; // delay time
|
|
if(!Verilog_Delay(td, Name)) return td;
|
|
s += td;
|
|
}
|
|
s += " " + Name + " (" + pp->Connection->Name; // output port
|
|
|
|
pp = Ports.next();
|
|
s += ", " + pp->Connection->Name; // first input port
|
|
|
|
// output all input ports with node names
|
|
for(pp = Ports.next(); pp != 0; pp = Ports.next())
|
|
s += ", " + pp->Connection->Name;
|
|
|
|
s += ");\n";
|
|
}
|
|
return s;
|
|
}
|
|
|
|
// -------------------------------------------------------
|
|
void GateComponent::createSymbol()
|
|
{
|
|
int Num = Props.getFirst()->Value.toInt();
|
|
if(Num < 2) Num = 2;
|
|
else if(Num > 8) Num = 8;
|
|
Props.getFirst()->Value = QString::number(Num);
|
|
|
|
int xl, xr, y = 10*Num, z;
|
|
x1 = -30; y1 = -y-3;
|
|
x2 = 30; y2 = y+3;
|
|
|
|
tx = x1+4;
|
|
ty = y2+4;
|
|
|
|
z = 0;
|
|
if(Model.at(0) == 'N') z = 1;
|
|
|
|
if(Props.getLast()->Value.at(0) == 'D') { // DIN symbol
|
|
xl = -15;
|
|
xr = 15;
|
|
Lines.append(new Line( 15,-y, 15, y,QPen(QPen::darkBlue,2)));
|
|
Lines.append(new Line(-15,-y, 15,-y,QPen(QPen::darkBlue,2)));
|
|
Lines.append(new Line(-15, y, 15, y,QPen(QPen::darkBlue,2)));
|
|
Lines.append(new Line(-15,-y,-15, y,QPen(QPen::darkBlue,2)));
|
|
Lines.append(new Line( 15, 0, 30, 0,QPen(QPen::darkBlue,2)));
|
|
|
|
if(Model.at(z) == 'O') {
|
|
Lines.append(new Line(-11, 6-y,-6, 9-y,QPen(QPen::darkBlue,0)));
|
|
Lines.append(new Line(-11,12-y,-6, 9-y,QPen(QPen::darkBlue,0)));
|
|
Lines.append(new Line(-11,14-y,-6,14-y,QPen(QPen::darkBlue,0)));
|
|
Lines.append(new Line(-11,16-y,-6,16-y,QPen(QPen::darkBlue,0)));
|
|
Texts.append(new Text( -4, 3-y, "1", QPen::darkBlue, 15.0));
|
|
}
|
|
else if(Model.at(z) == 'A')
|
|
Texts.append(new Text( -10, 3-y, "&", QPen::darkBlue, 15.0));
|
|
else if(Model.at(0) == 'X') {
|
|
if(Model.at(1) == 'N') {
|
|
Ellips.append(new Area(xr,-4, 8, 8,
|
|
QPen(QPen::darkBlue,0), QBrush(QPen::darkBlue)));
|
|
Texts.append(new Text( -11, 3-y, "=1", QPen::darkBlue, 15.0));
|
|
}
|
|
else
|
|
Texts.append(new Text( -11, 3-y, "=1", QPen::darkBlue, 15.0));
|
|
}
|
|
}
|
|
else { // old symbol
|
|
|
|
if(Model.at(z) == 'O') xl = 10;
|
|
else xl = -10;
|
|
xr = 10;
|
|
Lines.append(new Line(-10,-y,-10, y,QPen(QPen::darkBlue,2)));
|
|
Lines.append(new Line( 10, 0, 30, 0,QPen(QPen::darkBlue,2)));
|
|
Arcs.append(new Arc(-30,-y, 40, 30, 0, 16*90,QPen(QPen::darkBlue,2)));
|
|
Arcs.append(new Arc(-30,y-30, 40, 30, 0,-16*90,QPen(QPen::darkBlue,2)));
|
|
Lines.append(new Line( 10,15-y, 10, y-15,QPen(QPen::darkBlue,2)));
|
|
|
|
if(Model.at(0) == 'X') {
|
|
Lines.append(new Line(-5, 0, 5, 0,QPen(QPen::darkBlue,1)));
|
|
if(Model.at(1) == 'N') {
|
|
Lines.append(new Line(-5,-3, 5,-3,QPen(QPen::darkBlue,1)));
|
|
Lines.append(new Line(-5, 3, 5, 3,QPen(QPen::darkBlue,1)));
|
|
}
|
|
else {
|
|
Arcs.append(new Arc(-5,-5, 10, 10, 0, 16*360,QPen(QPen::darkBlue,1)));
|
|
Lines.append(new Line( 0,-5, 0, 5,QPen(QPen::darkBlue,1)));
|
|
}
|
|
}
|
|
}
|
|
|
|
if(Model.at(0) == 'N')
|
|
Ellips.append(new Area(xr,-4, 8, 8,
|
|
QPen(QPen::darkBlue,0), QBrush(QPen::darkBlue)));
|
|
|
|
Ports.append(new Port( 30, 0));
|
|
y += 10;
|
|
for(z=0; z<Num; z++) {
|
|
y -= 20;
|
|
Ports.append(new Port(-30, y));
|
|
if(xl == 10) if((z == 0) || (z == Num-1)) {
|
|
Lines.append(new Line(-30, y, 9, y,QPen(QPen::darkBlue,2)));
|
|
continue;
|
|
}
|
|
Lines.append(new Line(-30, y, xl, y,QPen(QPen::darkBlue,2)));
|
|
}
|
|
}
|
|
|
|
|
|
// ***********************************************************************
|
|
// ******** ********
|
|
// ******** The following function does not below to any class. ********
|
|
// ******** It creates a component by getting the identification ********
|
|
// ******** string used in the schematic file and for copy/paste. ********
|
|
// ******** ********
|
|
// ***********************************************************************
|
|
|
|
Component* getComponentFromName(QString& Line)
|
|
{
|
|
Component *c = 0;
|
|
|
|
Line = Line.stripWhiteSpace();
|
|
if(Line.at(0) != '<') {
|
|
QMessageBox::critical(0, QObject::tr("Error"),
|
|
QObject::tr("Format Error:\nWrong line start!"));
|
|
return 0;
|
|
}
|
|
|
|
QString cstr = Line.section (' ',0,0); // component type
|
|
cstr.remove (0,1); // remove leading "<"
|
|
if (cstr == "Lib") c = new LibComp ();
|
|
else if (cstr == "Eqn") c = new Equation ();
|
|
<<<<<<< HEAD
|
|
=======
|
|
else if (cstr == "SPICE") c = new SpiceFile();
|
|
>>>>>>> 80028cb8206ee83926db69b5bd20c9a3c932403d
|
|
else if (cstr == "Rus") c = new Resistor (false); // backward compatible
|
|
else if (cstr.left (6) == "SPfile" && cstr != "SPfile") {
|
|
// backward compatible
|
|
c = new SParamFile ();
|
|
c->Props.getLast()->Value = cstr.mid (6); }
|
|
else
|
|
c = Module::getComponent (cstr);
|
|
|
|
if(!c) {
|
|
QMessageBox::critical(0, QObject::tr("Error"),
|
|
QObject::tr("Format Error:\nUnknown component!"));
|
|
return 0;
|
|
}
|
|
|
|
if(!c->load(Line)) {
|
|
QMessageBox::critical(0, QObject::tr("Error"),
|
|
QObject::tr("Format Error:\nWrong 'component' line format!"));
|
|
delete c;
|
|
return 0;
|
|
}
|
|
|
|
cstr = c->Name; // is perhaps changed in "recreate" (e.g. subcircuit)
|
|
int x = c->tx, y = c->ty;
|
|
c->recreate(0);
|
|
c->Name = cstr;
|
|
c->tx = x; c->ty = y;
|
|
return c;
|
|
}
|