File indexing completed on 2024-05-05 05:46:08

0001 /***************************************************************************
0002  *   Copyright (C) 2005 by David Saxton                                    *
0003  *   david@bluehaze.org                                                    *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  ***************************************************************************/
0010 
0011 #include "probe.h" //HACK: This has to be included before the oscilloscope headers
0012 #include "ecnode.h"
0013 #include "libraryitem.h"
0014 #include "logic.h"
0015 #include "oscilloscope.h"
0016 #include "oscilloscopedata.h"
0017 #include "pin.h"
0018 #include "simulator.h"
0019 #include "voltagesource.h"
0020 
0021 #include <KLocalizedString>
0022 #include <QPainter>
0023 #include <QPainterPath>
0024 
0025 // BEGIN class Probe
0026 Probe::Probe(ICNDocument *icnDocument, bool newItem, const char *id)
0027     : Component(icnDocument, newItem, id)
0028 {
0029     p_probeData = nullptr;
0030     setSize(-16, -8, 32, 16);
0031 
0032     createProperty("color", Variant::Type::Color);
0033     property("color")->setCaption(i18n("Color"));
0034     property("color")->setValue(QColor(Qt::black));
0035 }
0036 
0037 Probe::~Probe()
0038 {
0039     delete p_probeData;
0040 }
0041 
0042 void Probe::dataChanged()
0043 {
0044     m_color = dataColor("color");
0045     if (p_probeData)
0046         p_probeData->setColor(m_color);
0047     setChanged();
0048 }
0049 // END class Probe
0050 
0051 // BEGIN class FloatingProbe
0052 FloatingProbe::FloatingProbe(ICNDocument *icnDocument, bool newItem, const char *id)
0053     : Probe(icnDocument, newItem, id)
0054 {
0055     p_probeData = m_pFloatingProbeData = static_cast<FloatingProbeData *>(registerProbe(this));
0056     property("color")->setValue(p_probeData->color());
0057 
0058     createProperty("scaling", Variant::Type::Select);
0059     property("scaling")->setCaption(i18n("Scaling"));
0060     QStringMap allowed;
0061     allowed["Linear"] = i18n("Linear");
0062     allowed["Logarithmic"] = i18n("Logarithmic");
0063     property("scaling")->setAllowed(allowed);
0064     property("scaling")->setValue("Linear");
0065     property("scaling")->setAdvanced(true);
0066 
0067     createProperty("upper_abs_value", Variant::Type::Double);
0068     property("upper_abs_value")->setCaption(i18n("Upper Absolute Value"));
0069     property("upper_abs_value")->setValue(10.0);
0070     property("upper_abs_value")->setMinValue(0.0);
0071     property("upper_abs_value")->setUnit("V");
0072     property("upper_abs_value")->setAdvanced(true);
0073 
0074     createProperty("lower_abs_value", Variant::Type::Double);
0075     property("lower_abs_value")->setCaption(i18n("Lower Absolute Value"));
0076     property("lower_abs_value")->setValue(0.1);
0077     property("lower_abs_value")->setMinValue(0.0);
0078     property("lower_abs_value")->setUnit("V");
0079     property("lower_abs_value")->setAdvanced(true);
0080 }
0081 
0082 FloatingProbe::~FloatingProbe()
0083 {
0084 }
0085 
0086 void FloatingProbe::dataChanged()
0087 {
0088     Probe::dataChanged();
0089 
0090     if (dataString("scaling") == "Linear")
0091         m_pFloatingProbeData->setScaling(FloatingProbeData::Linear);
0092     else
0093         m_pFloatingProbeData->setScaling(FloatingProbeData::Logarithmic);
0094 
0095     m_pFloatingProbeData->setUpperAbsValue(dataDouble("upper_abs_value"));
0096     m_pFloatingProbeData->setLowerAbsValue(dataDouble("lower_abs_value"));
0097 }
0098 
0099 void FloatingProbe::drawShape(QPainter &p)
0100 {
0101     initPainter(p);
0102 
0103     int _x = int(x()) - 16;
0104     int _y = int(y()) - 8;
0105 
0106     p.drawRect(_x, _y, 32, 16);
0107 
0108     QPolygon bezier(4);
0109 
0110     bezier[0] = QPoint(_x + 4, _y + 10);
0111     bezier[1] = QPoint(_x + 12, _y - 6);
0112     bezier[2] = QPoint(_x + 20, _y + 24);
0113     bezier[3] = QPoint(_x + 28, _y + 4);
0114 
0115     p.setPen(QPen(m_color, 2));
0116     // p.drawCubicBezier(bezier); // 2018.12.07
0117     QPainterPath path;
0118     path.moveTo(bezier.at(0));
0119     ;
0120     path.cubicTo(bezier.at(1), bezier.at(2), bezier.at(3));
0121     p.strokePath(path, p.pen());
0122 
0123     deinitPainter(p);
0124 }
0125 // END class FloatingProbe
0126 
0127 // BEGIN class VoltageProbe
0128 Item *VoltageProbe::construct(ItemDocument *itemDocument, bool newItem, const char *id)
0129 {
0130     return new VoltageProbe(static_cast<ICNDocument *>(itemDocument), newItem, id);
0131 }
0132 
0133 LibraryItem *VoltageProbe::libraryItem()
0134 {
0135     return new LibraryItem(QStringList(QString("ec/voltageprobe")), i18n("Voltage Probe"), i18n("Outputs"), "floatingprobe.png", LibraryItem::lit_component, VoltageProbe::construct);
0136 }
0137 
0138 VoltageProbe::VoltageProbe(ICNDocument *icnDocument, bool newItem, const char *id)
0139     : FloatingProbe(icnDocument, newItem, id ? id : "voltageprobe")
0140 {
0141     m_name = i18n("Voltage Probe");
0142 
0143     init1PinLeft();
0144     init1PinRight();
0145     m_pPin1 = m_pNNode[0]->pin();
0146     m_pPin2 = m_pPNode[0]->pin();
0147 }
0148 
0149 VoltageProbe::~VoltageProbe()
0150 {
0151 }
0152 
0153 void VoltageProbe::stepNonLogic()
0154 {
0155     m_pFloatingProbeData->addDataPoint(m_pPin1->voltage() - m_pPin2->voltage());
0156 }
0157 // END class VoltageProbe
0158 
0159 // BEGIN class CurrentProbe
0160 Item *CurrentProbe::construct(ItemDocument *itemDocument, bool newItem, const char *id)
0161 {
0162     return new CurrentProbe(static_cast<ICNDocument *>(itemDocument), newItem, id);
0163 }
0164 
0165 LibraryItem *CurrentProbe::libraryItem()
0166 {
0167     return new LibraryItem(QStringList(QString("ec/currentprobe")), i18n("Current Probe"), i18n("Outputs"), "floatingprobe.png", LibraryItem::lit_component, CurrentProbe::construct);
0168 }
0169 
0170 CurrentProbe::CurrentProbe(ICNDocument *icnDocument, bool newItem, const char *id)
0171     : FloatingProbe(icnDocument, newItem, id ? id : "currentprobe")
0172 {
0173     m_name = i18n("Current Probe");
0174 
0175     init1PinLeft(0);
0176     init1PinRight(0);
0177 
0178     m_voltageSource = createVoltageSource(m_pNNode[0], m_pPNode[0], 0.);
0179 }
0180 
0181 CurrentProbe::~CurrentProbe()
0182 {
0183 }
0184 
0185 void CurrentProbe::stepNonLogic()
0186 {
0187     m_pFloatingProbeData->addDataPoint(-m_voltageSource->cbranchCurrent(0));
0188 }
0189 // END class CurrentProbe
0190 
0191 // BEGIN class LogicProbe
0192 void LogicProbe_logicCallback(void *objV, bool state) {
0193     LogicProbe *objT = static_cast<LogicProbe*>(objV);
0194     objT->logicCallback(state);
0195 }
0196 
0197 Item *LogicProbe::construct(ItemDocument *itemDocument, bool newItem, const char *id)
0198 {
0199     return new LogicProbe(static_cast<ICNDocument *>(itemDocument), newItem, id);
0200 }
0201 
0202 LibraryItem *LogicProbe::libraryItem()
0203 {
0204     QStringList ids;
0205     ids << "ec/probe"
0206         << "ec/logicprobe";
0207     return new LibraryItem(ids, i18n("Logic Probe"), i18n("Outputs"), "logicprobe.png", LibraryItem::lit_component, LogicProbe::construct);
0208 }
0209 
0210 LogicProbe::LogicProbe(ICNDocument *icnDocument, bool newItem, const char *id)
0211     : Probe(icnDocument, newItem, id ? id : "probe")
0212 {
0213     m_name = i18n("Logic Probe");
0214 
0215     init1PinRight();
0216     m_pIn = createLogicIn(m_pPNode[0]);
0217 
0218     p_probeData = p_logicProbeData = static_cast<LogicProbeData *>(registerProbe(this));
0219     property("color")->setValue(p_probeData->color());
0220 
0221     m_pSimulator = Simulator::self();
0222     //m_pIn->setCallback(this, (CallbackPtr)(&LogicProbe::logicCallback));
0223     m_pIn->setCallback2(LogicProbe_logicCallback, this);
0224     logicCallback(false);
0225 }
0226 
0227 LogicProbe::~LogicProbe()
0228 {
0229 }
0230 
0231 void LogicProbe::logicCallback(bool value)
0232 {
0233     p_logicProbeData->addDataPoint(LogicDataPoint(value, m_pSimulator->time()));
0234 }
0235 
0236 void LogicProbe::drawShape(QPainter &p)
0237 {
0238     initPainter(p);
0239 
0240     int _x = int(x()) - 16;
0241     int _y = int(y()) - 8;
0242 
0243     p.drawRect(_x, _y, 32, 16);
0244 
0245     p.setPen(QPen(m_color, 2));
0246 
0247     p.drawLine(_x + 4, _y + 11, _x + 6, _y + 11);
0248     p.drawLine(_x + 6, _y + 11, _x + 6, _y + 4);
0249     p.drawLine(_x + 6, _y + 4, _x + 10, _y + 4);
0250     p.drawLine(_x + 10, _y + 4, _x + 10, _y + 11);
0251     p.drawLine(_x + 10, _y + 11, _x + 16, _y + 11);
0252     p.drawLine(_x + 16, _y + 11, _x + 16, _y + 4);
0253     p.drawLine(_x + 16, _y + 4, _x + 23, _y + 4);
0254     p.drawLine(_x + 23, _y + 4, _x + 23, _y + 11);
0255     p.drawLine(_x + 23, _y + 11, _x + 28, _y + 11);
0256     //  p.drawLine( _x+23, _y+11, _x+26, _y+11 );
0257     //  p.drawLine( _x+26, _y+11, _x+26, _y+4 );
0258     //  p.drawLine( _x+26, _y+4, _x+28, _y+4 );
0259 
0260     deinitPainter(p);
0261 }
0262 // END class LogicProbe