Qucs-GUI  0.0.19
/home/travis/build/Qucs/qucs/qucs/qucs/module.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002                                module.cpp
00003                               ------------
00004     begin                : Thu Nov 5 2009
00005     copyright            : (C) 2009 by Stefan Jahn
00006     email                : stefan@lkcc.org
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 #include <QHash>
00018 #include <QString>
00019 #include <QStringList>
00020 #include <QList>
00021 #include <QDebug>
00022 
00023 #include "element.h"
00024 #include "components/component.h"
00025 #include "components/components.h"
00026 #include "paintings/paintings.h"
00027 #include "diagrams/diagrams.h"
00028 #include "module.h"
00029 
00030 // Global category and component lists.
00031 QHash<QString, Module *> Module::Modules;
00032 QList<Category *> Category::Categories;
00033 
00034 QMap<QString, QString> Module::vaComponents;
00035 
00036 // Constructor creates instance of module object.
00037 Module::Module () {
00038   info = 0;
00039   category = "#special";
00040 }
00041 
00042 // Destructor removes instance of module object from memory.
00043 Module::~Module () {
00044 }
00045 
00046 // Module registration using a category name and the appropriate
00047 // function returning a modules instance object.
00048 void Module::registerModule (QString category, pInfoFunc info) {
00049   Module * m = new Module ();
00050   m->info = info;
00051   m->category = category;
00052   intoCategory (m);
00053 }
00054 
00055 // Component registration using a category name and the appropriate
00056 // function returning a components instance object.
00057 void Module::registerComponent (QString category, pInfoFunc info) {
00058   Module * m = new Module ();
00059   m->info = info;
00060   m->category = category;
00061 
00062   // instantiation of the component once in order to obtain "Model"
00063   // property of the component
00064   QString Name, Model;
00065   char * File;
00066   Component * c = (Component *) info (Name, File, true);
00067   Model = c->Model;
00068   delete c;
00069 
00070   // put into category and the component hash
00071   intoCategory (m);
00072   if (!Modules.contains (Model))
00073     Modules.insert (Model, m);
00074 }
00075 
00076 // Returns instantiated component based on the given "Model" name.  If
00077 // there is no such component registers the function returns NULL.
00078 Component * Module::getComponent (QString Model) {
00079   if ( Modules.contains(Model)) {
00080     Module *m = Modules.find(Model).value();
00081     QString Name;
00082     char * File;
00083     QString vaBitmap;
00084     if (vaComponents.contains(Model))
00085       return (Component *)
00086               vacomponent::info (Name, vaBitmap, true, vaComponents[Model]);
00087     else
00088       return (Component *) m->info (Name, File, true);
00089   }
00090   return 0;
00091 }
00092 
00093 void Module::registerDynamicComponents()
00094 {
00095     qDebug() << "Module::registerDynamicComponents()";
00096 
00097 
00098   // vaComponents is populated in QucsApp::slotLoadModule
00099 
00100   // register modules symbol and properties out of in vaComponents
00101   QMapIterator<QString, QString> i(vaComponents);
00102    while (i.hasNext()) {
00103      i.next();
00104 
00105 //     qDebug() << i.key() << ": " << i.value() << endl;
00106 
00107      Module * m = new Module ();
00108 
00109      // what now? pointer to info?
00110 
00111      // the typedef needs to be different
00112      //passes the pointer, but it has no idea how to call the JSON
00113      m->infoVA = &vacomponent::info;
00114 
00115      // TODO maybe allow user load into custom category?
00116      m->category = QObject::tr("verilog-a user devices");
00117 
00118      // instantiation of the component once in order
00119      // to obtain "Model" property of the component
00120      //QString Name, Model;
00121      //char * File;
00122      QString Name, Model, vaBitmap;
00123 //     char * File;
00124      Component * c = (Component *)
00125              vacomponent::info (Name, vaBitmap, true, vaComponents[i.key()]);
00126      Model = c->Model;
00127      delete c;
00128 
00129      // put into category and the component hash
00130      intoCategory (m);
00131 
00132      if (!Modules.contains (Model))
00133          Modules.insert (Model, m);
00134 
00135    } // while
00136 }
00137 
00138 // The function appends the given module to the appropriate category.
00139 // If there is no such category yet, then the category gets created.
00140 void Module::intoCategory (Module * m) {
00141 
00142   // look through existing categories
00143   QList<Category *>::const_iterator it;
00144   for (it = Category::Categories.constBegin();
00145        it != Category::Categories.constEnd(); it++) {
00146     if ((*it)->Name == m->category) {
00147       (*it)->Content.append (m);
00148       break;
00149     }
00150   }
00151 
00152   // if there is no such category, then create it
00153   if (it == Category::Categories.constEnd()) {
00154     Category *cat = new Category (m->category);
00155     Category::Categories.append (cat);
00156     cat->Content.append (m);
00157   }
00158 }
00159 
00160 // Helper macros for module registration.
00161 #define REGISTER_MOD_1(cat,val) \
00162   registerModule (cat, &val::info)
00163 #define REGISTER_MOD_2(cat,val,inf1,inf2) \
00164   registerModule (cat, &val::inf1); \
00165   registerModule (cat, &val::inf2)
00166 #define REGISTER_MOD_3(cat,val,inf1,inf2,inf3) \
00167   registerModule (cat, &val::inf1); \
00168   registerModule (cat, &val::inf2); \
00169   registerModule (cat, &val::inf3)
00170 
00171 #define REGISTER_COMP_1(cat,val) \
00172   registerComponent (cat, &val::info)
00173 #define REGISTER_COMP_2(cat,val,inf1,inf2) \
00174   registerComponent (cat, &val::inf1); \
00175   registerComponent (cat, &val::inf2)
00176 #define REGISTER_COMP_3(cat,val,inf1,inf2,inf3) \
00177   registerComponent (cat, &val::inf1); \
00178   registerComponent (cat, &val::inf2); \
00179   registerComponent (cat, &val::inf3)
00180 
00181 #define REGISTER_LUMPED_1(val) \
00182   REGISTER_COMP_1 (QObject::tr("lumped components"),val)
00183 #define REGISTER_LUMPED_2(val,inf1,inf2) \
00184   REGISTER_COMP_2 (QObject::tr("lumped components"),val,inf1,inf2)
00185 #define REGISTER_SOURCE_1(val) \
00186   REGISTER_COMP_1 (QObject::tr("sources"),val)
00187 #define REGISTER_PROBE_1(val) \
00188   REGISTER_COMP_1 (QObject::tr("probes"),val)
00189 #define REGISTER_TRANS_1(val) \
00190   REGISTER_COMP_1 (QObject::tr("transmission lines"),val)
00191 #define REGISTER_NONLINEAR_1(val) \
00192   REGISTER_COMP_1 (QObject::tr("nonlinear components"),val)
00193 #define REGISTER_NONLINEAR_2(val,inf1,inf2) \
00194   REGISTER_COMP_2 (QObject::tr("nonlinear components"),val,inf1,inf2)
00195 #define REGISTER_NONLINEAR_3(val,inf1,inf2,inf3) \
00196   REGISTER_COMP_3 (QObject::tr("nonlinear components"),val,inf1,inf2,inf3)
00197 #define REGISTER_VERILOGA_1(val) \
00198   REGISTER_COMP_1 (QObject::tr("verilog-a devices"),val)
00199 #define REGISTER_VERILOGA_2(val,inf1,inf2) \
00200   REGISTER_COMP_2 (QObject::tr("verilog-a devices"),val,inf1,inf2)
00201 #define REGISTER_DIGITAL_1(val) \
00202   REGISTER_COMP_1 (QObject::tr("digital components"),val)
00203 #define REGISTER_FILE_1(val) \
00204   REGISTER_COMP_1 (QObject::tr("file components"),val)
00205 #define REGISTER_FILE_3(val,inf1,inf2,inf3) \
00206   REGISTER_COMP_3 (QObject::tr("file components"),val,inf1,inf2,inf3)
00207 #define REGISTER_SIMULATION_1(val) \
00208   REGISTER_COMP_1 (QObject::tr("simulations"),val)
00209 #define REGISTER_DIAGRAM_1(val) \
00210   REGISTER_MOD_1 (QObject::tr("diagrams"),val)
00211 #define REGISTER_DIAGRAM_2(val,inf1,inf2) \
00212   REGISTER_MOD_2 (QObject::tr("diagrams"),val,inf1,inf2)
00213 #define REGISTER_PAINT_1(val) \
00214   REGISTER_MOD_1 (QObject::tr("paintings"),val)
00215 #define REGISTER_PAINT_2(val,inf1,inf2) \
00216   REGISTER_MOD_2 (QObject::tr("paintings"),val,inf1,inf2)
00217 #define REGISTER_EXTERNAL_1(val) \
00218   REGISTER_COMP_1 (QObject::tr("external sim components"),val)
00219 
00220 // This function has to be called once at application startup.  It
00221 // registers every component available in the application.  Put here
00222 // any new component.
00223 void Module::registerModules (void) {
00224 
00225   // lumped components
00226   REGISTER_LUMPED_2 (Resistor, info, info_us);
00227   REGISTER_LUMPED_1 (Capacitor);
00228   REGISTER_LUMPED_1 (Inductor);
00229   REGISTER_LUMPED_1 (Ground);
00230   REGISTER_LUMPED_1 (SubCirPort);
00231   REGISTER_LUMPED_1 (Transformer);
00232   REGISTER_LUMPED_1 (symTrafo);
00233   REGISTER_LUMPED_1 (dcBlock);
00234   REGISTER_LUMPED_1 (dcFeed);
00235   REGISTER_LUMPED_1 (BiasT);
00236   REGISTER_LUMPED_1 (Attenuator);
00237   REGISTER_LUMPED_1 (Amplifier);
00238   REGISTER_LUMPED_1 (Isolator);
00239   REGISTER_LUMPED_1 (Circulator);
00240   REGISTER_LUMPED_1 (Gyrator);
00241   REGISTER_LUMPED_1 (Phaseshifter);
00242   REGISTER_LUMPED_1 (Coupler);
00243   REGISTER_LUMPED_1 (Hybrid);
00244   REGISTER_LUMPED_1 (iProbe);
00245   REGISTER_LUMPED_1 (vProbe);
00246   REGISTER_LUMPED_1 (Mutual);
00247   REGISTER_LUMPED_1 (Mutual2);
00248   REGISTER_LUMPED_1 (MutualX);
00249   REGISTER_LUMPED_1 (Switch);
00250   REGISTER_LUMPED_1 (Relais);
00251   REGISTER_LUMPED_1 (RFedd);
00252   REGISTER_LUMPED_1 (RFedd2P);
00253 
00254   // sources
00255   REGISTER_SOURCE_1 (Volt_dc);
00256   REGISTER_SOURCE_1 (Ampere_dc);
00257   REGISTER_SOURCE_1 (Volt_ac);
00258   REGISTER_SOURCE_1 (Ampere_ac);
00259   REGISTER_SOURCE_1 (Source_ac);
00260   REGISTER_SOURCE_1 (Volt_noise);
00261   REGISTER_SOURCE_1 (Ampere_noise);
00262   REGISTER_SOURCE_1 (VCCS);
00263   REGISTER_SOURCE_1 (CCCS);
00264   REGISTER_SOURCE_1 (VCVS);
00265   REGISTER_SOURCE_1 (CCVS);
00266   REGISTER_SOURCE_1 (vPulse);
00267   REGISTER_SOURCE_1 (iPulse);
00268   REGISTER_SOURCE_1 (vRect);
00269   REGISTER_SOURCE_1 (iRect);
00270   REGISTER_SOURCE_1 (Noise_ii);
00271   REGISTER_SOURCE_1 (Noise_vv);
00272   REGISTER_SOURCE_1 (Noise_iv);
00273   REGISTER_SOURCE_1 (AM_Modulator);
00274   REGISTER_SOURCE_1 (PM_Modulator);
00275   REGISTER_SOURCE_1 (iExp);
00276   REGISTER_SOURCE_1 (vExp);
00277   REGISTER_SOURCE_1 (vFile);
00278   REGISTER_SOURCE_1 (iFile);
00279 
00280   // probes
00281   REGISTER_PROBE_1 (iProbe);
00282   REGISTER_PROBE_1 (vProbe);
00283 
00284   // transmission lines
00285   REGISTER_TRANS_1 (TLine);
00286   REGISTER_TRANS_1 (TLine_4Port);
00287   REGISTER_TRANS_1 (CoupledTLine);
00288   REGISTER_TRANS_1 (TwistedPair);
00289   REGISTER_TRANS_1 (CoaxialLine);
00290   REGISTER_TRANS_1 (RectLine);
00291   REGISTER_TRANS_1 (RLCG);
00292   REGISTER_TRANS_1 (Substrate);
00293   REGISTER_TRANS_1 (MSline);
00294   REGISTER_TRANS_1 (MScoupled);
00295   REGISTER_TRANS_1 (MSlange);
00296   REGISTER_TRANS_1 (MScorner);
00297   REGISTER_TRANS_1 (MSmbend);
00298   REGISTER_TRANS_1 (MSstep);
00299   REGISTER_TRANS_1 (MStee);
00300   REGISTER_TRANS_1 (MScross);
00301   REGISTER_TRANS_1 (MSopen);
00302   REGISTER_TRANS_1 (MSgap);
00303   REGISTER_TRANS_1 (MSvia);
00304   REGISTER_TRANS_1 (MSrstub);
00305   REGISTER_TRANS_1 (Coplanar);
00306   REGISTER_TRANS_1 (CPWopen);
00307   REGISTER_TRANS_1 (CPWshort);
00308   REGISTER_TRANS_1 (CPWgap);
00309   REGISTER_TRANS_1 (CPWstep);
00310   REGISTER_TRANS_1 (BondWire);
00311 
00312   // nonlinear components
00313   REGISTER_NONLINEAR_1 (Diode);
00314   REGISTER_NONLINEAR_2 (BJT, info, info_pnp);
00315   REGISTER_NONLINEAR_2 (BJTsub, info, info_pnp);
00316   REGISTER_NONLINEAR_2 (JFET, info, info_p);
00317   REGISTER_NONLINEAR_3 (MOSFET, info, info_p, info_depl);
00318   REGISTER_NONLINEAR_3 (MOSFET_sub, info, info_p, info_depl);
00319   REGISTER_NONLINEAR_1 (OpAmp);
00320   REGISTER_NONLINEAR_1 (EqnDefined);
00321   REGISTER_NONLINEAR_1 (Diac);
00322   REGISTER_NONLINEAR_1 (Triac);
00323   REGISTER_NONLINEAR_1 (Thyristor);
00324   REGISTER_NONLINEAR_1 (TunnelDiode);
00325 
00326   // verilog-a devices
00327   REGISTER_VERILOGA_1 (hicumL2V2p1);
00328   REGISTER_VERILOGA_1 (HBT_X);
00329   REGISTER_VERILOGA_1 (mod_amp);
00330   REGISTER_VERILOGA_1 (hic2_full);
00331   REGISTER_VERILOGA_1 (log_amp);
00332   REGISTER_VERILOGA_2 (hic0_full, info, info_pnp);
00333   REGISTER_VERILOGA_1 (potentiometer);
00334   REGISTER_VERILOGA_1 (MESFET);
00335   REGISTER_VERILOGA_2 (EKV26MOS, info, info_pmos);
00336   REGISTER_VERILOGA_1 (bsim3v34nMOS);
00337   REGISTER_VERILOGA_1 (bsim3v34pMOS);
00338   REGISTER_VERILOGA_1 (bsim4v30nMOS);
00339   REGISTER_VERILOGA_1 (bsim4v30pMOS);
00340   REGISTER_VERILOGA_2 (hicumL0V1p2, info, info_pnp);
00341   REGISTER_VERILOGA_2 (hicumL0V1p2g, info, info_pnp);
00342   REGISTER_VERILOGA_2 (hicumL0V1p3, info, info_pnp);
00343   REGISTER_VERILOGA_1 (hicumL2V2p23);
00344   REGISTER_VERILOGA_1 (hicumL2V2p24);
00345   REGISTER_VERILOGA_1 (hicumL2V2p31n);
00346   REGISTER_VERILOGA_1 (photodiode);
00347   REGISTER_VERILOGA_1 (phototransistor);
00348   REGISTER_VERILOGA_1 (nigbt);
00349   REGISTER_VERILOGA_1 (vcresistor);
00350 
00351   // digital components
00352   REGISTER_DIGITAL_1 (Digi_Source);
00353   REGISTER_DIGITAL_1 (Logical_Inv);
00354   REGISTER_DIGITAL_1 (Logical_OR);
00355   REGISTER_DIGITAL_1 (Logical_NOR);
00356   REGISTER_DIGITAL_1 (Logical_AND);
00357   REGISTER_DIGITAL_1 (Logical_NAND);
00358   REGISTER_DIGITAL_1 (Logical_XOR);
00359   REGISTER_DIGITAL_1 (Logical_XNOR);
00360   REGISTER_DIGITAL_1 (Logical_Buf);
00361   REGISTER_DIGITAL_1 (andor4x2);
00362   REGISTER_DIGITAL_1 (andor4x3);
00363   REGISTER_DIGITAL_1 (andor4x4);
00364   REGISTER_DIGITAL_1 (mux2to1);
00365   REGISTER_DIGITAL_1 (mux4to1);
00366   REGISTER_DIGITAL_1 (mux8to1);
00367   REGISTER_DIGITAL_1 (dmux2to4);
00368   REGISTER_DIGITAL_1 (dmux3to8);
00369   REGISTER_DIGITAL_1 (dmux4to16);
00370   REGISTER_DIGITAL_1 (ha1b);
00371   REGISTER_DIGITAL_1 (fa1b);
00372   REGISTER_DIGITAL_1 (fa2b);
00373   REGISTER_DIGITAL_1 (RS_FlipFlop);
00374   REGISTER_DIGITAL_1 (D_FlipFlop);
00375   REGISTER_DIGITAL_1 (dff_SR);
00376   REGISTER_DIGITAL_1 (JK_FlipFlop);
00377   REGISTER_DIGITAL_1 (jkff_SR);
00378   REGISTER_DIGITAL_1 (tff_SR);
00379   REGISTER_DIGITAL_1 (gatedDlatch);
00380   REGISTER_DIGITAL_1 (logic_0);
00381   REGISTER_DIGITAL_1 (logic_1);
00382   REGISTER_DIGITAL_1 (pad2bit);
00383   REGISTER_DIGITAL_1 (pad3bit);
00384   REGISTER_DIGITAL_1 (pad4bit);
00385   REGISTER_DIGITAL_1 (DLS_nto1);
00386   REGISTER_DIGITAL_1 (DLS_1ton);
00387   REGISTER_DIGITAL_1 (binarytogrey4bit);
00388   REGISTER_DIGITAL_1 (greytobinary4bit);
00389   REGISTER_DIGITAL_1 (comp_1bit);
00390   REGISTER_DIGITAL_1 (comp_2bit);
00391   REGISTER_DIGITAL_1 (comp_4bit);
00392   REGISTER_DIGITAL_1 (hpribin4bit);
00393   REGISTER_DIGITAL_1 (VHDL_File);
00394   REGISTER_DIGITAL_1 (Verilog_File);
00395   REGISTER_DIGITAL_1 (Digi_Sim);
00396 
00397   // file components
00398   REGISTER_FILE_1 (SpiceFile);
00399   REGISTER_FILE_3 (SParamFile, info1, info2, info);
00400   REGISTER_FILE_1 (Subcircuit);
00401 
00402   // simulations
00403   REGISTER_SIMULATION_1 (DC_Sim);
00404   REGISTER_SIMULATION_1 (TR_Sim);
00405   REGISTER_SIMULATION_1 (AC_Sim);
00406   REGISTER_SIMULATION_1 (SP_Sim);
00407   REGISTER_SIMULATION_1 (HB_Sim);
00408   REGISTER_SIMULATION_1 (Param_Sweep);
00409   REGISTER_SIMULATION_1 (Digi_Sim);
00410   REGISTER_SIMULATION_1 (Optimize_Sim);
00411 
00412   // diagrams
00413   REGISTER_DIAGRAM_1 (RectDiagram);
00414   REGISTER_DIAGRAM_1 (PolarDiagram);
00415   REGISTER_DIAGRAM_1 (TabDiagram);
00416   REGISTER_DIAGRAM_2 (SmithDiagram, info, info_y);
00417   REGISTER_DIAGRAM_2 (PSDiagram, info, info_sp);
00418   REGISTER_DIAGRAM_1 (Rect3DDiagram);
00419   REGISTER_DIAGRAM_1 (CurveDiagram);
00420   REGISTER_DIAGRAM_1 (TimingDiagram);
00421   REGISTER_DIAGRAM_1 (TruthDiagram);
00422 
00423   // external simulation
00424   REGISTER_EXTERNAL_1 (ETR_Sim);
00425   REGISTER_EXTERNAL_1 (ecvs);
00426 
00427   // paintings
00428   REGISTER_PAINT_1 (GraphicLine);
00429   REGISTER_PAINT_1 (Arrow);
00430   REGISTER_PAINT_1 (GraphicText);
00431   REGISTER_PAINT_2 (Ellipse, info, info_filled);
00432   REGISTER_PAINT_2 (Rectangle, info, info_filled);
00433   REGISTER_PAINT_1 (EllipseArc);
00434 
00435 }
00436 
00437 // This function has to be called once at application end.  It removes
00438 // all categories and registered modules from memory.
00439 void Module::unregisterModules (void) {
00440   while(!Category::Categories.isEmpty()) {
00441     delete Category::Categories.takeFirst();
00442   }
00443 
00444   //remove all modules by iterator, require in qhash
00445   QHashIterator<QString, Module *> it( Modules );
00446   while(it.hasNext()) {
00447     it.next();
00448     delete it.value();
00449   }
00450   Modules.clear ();
00451 }
00452 
00453 // Constructor creates instance of module object.
00454 Category::Category () {
00455   Name = "#special";
00456   while(!Content.isEmpty()) {
00457     delete Content.takeFirst();
00458   }
00459 }
00460 
00461 // Constructor creates named instance of module object.
00462 Category::Category (const QString name) {
00463   Name = name;
00464   while(!Content.isEmpty()) {
00465     delete Content.takeFirst();
00466   }
00467 }
00468 
00469 // Destructor removes instance of module object from memory.
00470 Category::~Category () {
00471   while(!Content.isEmpty()) {
00472     delete Content.takeFirst();
00473   }
00474 }
00475 
00476 // Returns the available category names in a list of strings.
00477 QStringList Category::getCategories (void) {
00478   QStringList res;
00479   QList<Category *>::const_iterator it;
00480   for (it = Category::Categories.constBegin(); 
00481        it != Category::Categories.constEnd(); it++) {
00482     res.append ((*it)->Name);
00483   }
00484   return res;
00485 }
00486 
00487 // The function returns the registered modules in the given category
00488 // as a pointer list.  The pointer list is empty if there is no such
00489 // category available.
00490 QList<Module *> Category::getModules (QString category) {
00491   QList<Module *> res;
00492   QList<Category *>::const_iterator it;
00493   for (it = Category::Categories.constBegin();
00494        it != Category::Categories.constEnd(); it++) {
00495     if (category == (*it)->Name) {
00496       res = (*it)->Content;
00497     }
00498   }
00499   return res;
00500 }
00501 
00502 // Returns the index number into the category list for the given
00503 // category name.  The function returns minus 1 if there is no such
00504 // category.
00505 int Category::getModulesNr (QString category) {
00506   for (int i = 0; i < Category::Categories.size(); i++) {
00507     if (category == Category::Categories.at(i)->Name)
00508       return i;
00509   }
00510   return -1;
00511 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines