Skip to content

Commit

Permalink
introduce symbol class. (start to) use it in qucslib
Browse files Browse the repository at this point in the history
  • Loading branch information
felix-salfelder committed Aug 18, 2016
1 parent 2c08997 commit c15a7a1
Show file tree
Hide file tree
Showing 7 changed files with 150 additions and 96 deletions.
89 changes: 89 additions & 0 deletions qucs/qucs-lib/libcomp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#include "symbol.h"

/*!
* \brief this library provides symbols. these.
*/
class QucsLibComponent : public Symbol{
public:
QucsLibComponent( QString& , const QString&, const QString& );

};

QucsLibComponent::QucsLibComponent( QString& SymbolString,
const QString& Lib_, const QString& Comp_)
: Symbol(), LibraryName(Lib_), ComponentName(Comp_)
{
if (SymbolString.isEmpty())//Whenever SymbolString is empty, it tries to load the default symbol
{
//Load the default symbol for the current Qucs library
ComponentLibrary parsedlib;
QString libpath = QucsSettings.LibDir + Lib_ + ".lib";
int result = parseComponentLibrary (libpath, parsedlib);

// BUG: throw if there is an error. don't randomly spawn Messageboxes
// (cleanup later)
switch (result)//Check if the library was properly loaded
{
case QUCS_COMP_LIB_IO_ERROR:
QMessageBox::critical(0, tr ("Error"), tr("Cannot open \"%1\".").arg (libpath));
return -1;
case QUCS_COMP_LIB_CORRUPT:
QMessageBox::critical(0, tr("Error"), tr("Library is corrupt."));
return -1;
default:
break;
}

// copy the contents of default symbol section to a string
SymbolString = parsedlib.defaultSymbol;
}
}

QucsLibComponent::draw(Qwidget& w)
{
w.Arcs.clear();
w.Lines.clear();
w.Rects.clear();
w.Ellips.clear();
w.Texts.clear();

QString Line;
///QString foo = SymbolString;
QTextStream stream(&SymbolString, QIODevice::ReadOnly);

x1 = y1 = INT_MAX;
x2 = y2 = INT_MIN;

int z=0, Result;
while(!stream.atEnd()) {
Line = stream.readLine();
Line = Line.trimmed();
if(Line.isEmpty()) continue;

if(Line.at(0) != '<') return -1; // check for start char
if(Line.at(Line.length()-1) != '>') return -1; // check for end char
Line = Line.mid(1, Line.length()-2); // cut off start and end character
Result = analyseLine(Line);
if(Result < 0) return -6; // line format error
z += Result;
}

x1 -= 4; // enlarge component boundings a little
x2 += 4;
y1 -= 4;
y2 += 4;
cx = -x1 + TextWidth;
cy = -y1;

int dx = x2-x1 + TextWidth;
if((x2-x1) < DragNDropWidth)
dx = (x2-x1 + DragNDropWidth)/2 + TextWidth;
if(dx < DragNDropWidth)
dx = DragNDropWidth;
setMinimumSize(dx, y2-y1 + TextHeight+4);
if(width() > dx) dx = width();
resize(dx, y2-y1 + TextHeight+4);
update();
return z; // return number of ports
}

25 changes: 13 additions & 12 deletions qucs/qucs-lib/qucslib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ QucsLib::QucsLib()
CompDescr->setWordWrapMode(QTextOption::NoWrap);


Symbol = new SymbolWidget();
symWidget = new SymbolWidget();

QGroupBox *ButtonGroup = new QGroupBox();
QHBoxLayout *ButtonGroupLayout = new QHBoxLayout();
Expand All @@ -152,7 +152,7 @@ QucsLib::QucsLib()


CompGroupLayout->addWidget(CompDescr);
CompGroupLayout->addWidget(Symbol);
CompGroupLayout->addWidget(symWidget);
CompGroupLayout->addWidget(ButtonGroup);
CompGroup->setLayout(CompGroupLayout);

Expand Down Expand Up @@ -283,7 +283,7 @@ void QucsLib::slotCopyToClipBoard()
{
QString s = "<Qucs Schematic " PACKAGE_VERSION ">\n";
s += "<Components>\n " +
Symbol->theModel() +
symWidget->theModel() +
"\n</Components>\n";

// put resulting schematic into clipboard
Expand All @@ -294,7 +294,7 @@ void QucsLib::slotCopyToClipBoard()
// ----------------------------------------------------
void QucsLib::slotShowModel()
{
DisplayDialog *d = new DisplayDialog(this, Symbol->ModelString, Symbol->VHDLModelString, Symbol->VerilogModelString);
DisplayDialog *d = new DisplayDialog(this, symWidget->ModelString, symWidget->VHDLModelString, symWidget->VerilogModelString);
d->setWindowTitle(tr("Model"));
d->resize(500, 150);
d->show();
Expand Down Expand Up @@ -487,34 +487,35 @@ void QucsLib::slotShowComponent(QListWidgetItem *Item)
QMessageBox::critical(this, tr("Error"), tr("Library is corrupt."));
return;
}
Symbol->ModelString = content;
if(Symbol->ModelString.count('\n') < 2)
Symbol->createSymbol(LibName, Item->text());
symWidget->ModelString = content;
if(symWidget->ModelString.count('\n') < 2)
symWidget->createSymbol(LibName, Item->text());

if(!getSection("VHDLModel", CompString, content))
{
QMessageBox::critical(this, tr("Error"), tr("Library is corrupt."));
return;
}
Symbol->VHDLModelString = content;
symWidget->VHDLModelString = content;

if(!getSection("VerilogModel", CompString, content))
{
QMessageBox::critical(this, tr("Error"), tr("Library is corrupt."));
return;
}
Symbol->VerilogModelString = content;
symWidget->VerilogModelString = content;

if(!getSection("Symbol", CompString, content))
{
QMessageBox::critical(this, tr("Error"), tr("Library is corrupt."));
return;
}

// it's a bit late, but without a symbol we cannot draw a symbol to the
// widget... lets create a symbol!
Symbol compSym(content, LibName, Item->text());
compSym.draw(symWidget);

Symbol->setSymbol(content, LibName, Item->text());


// change currently selected category, so the user will
// learn where the component comes from
Library->setCurrentIndex(i);
Expand Down
2 changes: 1 addition & 1 deletion qucs/qucs-lib/qucslib.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ private slots:

int UserLibCount;
int libCurIdx;
SymbolWidget *Symbol;
SymbolWidget *symWidget;
QTextEdit *CompDescr;
QVBoxLayout *all;
QLineEdit *CompSearch;
Expand Down
80 changes: 0 additions & 80 deletions qucs/qucs-lib/symbolwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -350,86 +350,6 @@ int SymbolWidget::createSymbol(const QString& Lib_, const QString& Comp_)
return PortNo;
}

/*!
* \brief Loads the symbol for the component from the symbol field
* \param SymbolString
* \param Lib_
* \param Comp_
* \return the number of painting elements or a negative nuber if error
*/
int SymbolWidget::setSymbol( QString& SymbolString,
const QString& Lib_, const QString& Comp_)
{
if (SymbolString.isEmpty())//Whenever SymbolString is empty, it tries to load the default symbol
{
//Load the default symbol for the current Qucs library
ComponentLibrary parsedlib;
QString libpath = QucsSettings.LibDir + Lib_ + ".lib";
int result = parseComponentLibrary (libpath, parsedlib);

switch (result)//Check if the library was properly loaded
{
case QUCS_COMP_LIB_IO_ERROR:
QMessageBox::critical(0, tr ("Error"), tr("Cannot open \"%1\".").arg (libpath));
return -1;
case QUCS_COMP_LIB_CORRUPT:
QMessageBox::critical(0, tr("Error"), tr("Library is corrupt."));
return -1;
default:
break;
}

// copy the contents of default symbol section to a string
SymbolString = parsedlib.defaultSymbol;
}

Arcs.clear();
Lines.clear();
Rects.clear();
Ellips.clear();
Texts.clear();
LibraryName = Lib_;
ComponentName = Comp_;

QString Line;
///QString foo = SymbolString;
QTextStream stream(&SymbolString, QIODevice::ReadOnly);

x1 = y1 = INT_MAX;
x2 = y2 = INT_MIN;

int z=0, Result;
while(!stream.atEnd()) {
Line = stream.readLine();
Line = Line.trimmed();
if(Line.isEmpty()) continue;

if(Line.at(0) != '<') return -1; // check for start char
if(Line.at(Line.length()-1) != '>') return -1; // check for end char
Line = Line.mid(1, Line.length()-2); // cut off start and end character
Result = analyseLine(Line);
if(Result < 0) return -6; // line format error
z += Result;
}

x1 -= 4; // enlarge component boundings a little
x2 += 4;
y1 -= 4;
y2 += 4;
cx = -x1 + TextWidth;
cy = -y1;

int dx = x2-x1 + TextWidth;
if((x2-x1) < DragNDropWidth)
dx = (x2-x1 + DragNDropWidth)/2 + TextWidth;
if(dx < DragNDropWidth)
dx = DragNDropWidth;
setMinimumSize(dx, y2-y1 + TextHeight+4);
if(width() > dx) dx = width();
resize(dx, y2-y1 + TextHeight+4);
update();
return z; // return number of ports
}

// ---------------------------------------------------------------------
int SymbolWidget::analyseLine(const QString& Row)
Expand Down
2 changes: 0 additions & 2 deletions qucs/qucs-lib/symbolwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@
#include <QPaintEvent>
#include <QMessageBox>

#include "element.h"

/*!
* \file symbolwidget.h
* \brief Definition of the SymbolWidget class.
Expand Down
3 changes: 2 additions & 1 deletion qucs/qucs/components/component.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,15 @@
#include <Q3PtrList>

#include "element.h"
// #include "symbol.h" not yet.

class Schematic;
class ViewPainter;
class QString;
class QPen;


class Component : public Element {
class Component : public Element /* public Symbol */ {
public:
Component();
virtual ~Component() {};
Expand Down
45 changes: 45 additions & 0 deletions qucs/qucs/symbol.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/***************************************************************************
element.h
-----------
begin : 2016
copyright : (C) 2016 Felix Salfelder
email : felix@salfelder.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. *
* *
***************************************************************************/

/** \file symbol.h
* \brief Defines symbols for components, to be used in schematics.
*
* a symbol mostly takes care of ports, parameters and connectivity.
* (this is under construction)
*
*/

#ifndef SYMBOL_H
#define SYMBOL_H

/** \class Symbol
* \brief Superclass of all circuit components (except wires).
*
*
*/
class Symbol {
public: // construct
Symbol();
virtual ~Symbol(){}

public: // interface
virtual void draw(Widget&) = 0;
//... more to come
};


#endif

14 comments on commit c15a7a1

@andresmmera
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! 👍
This template/eye-opener was really needed.
I'll try to help as much as I can. :)

@felix-salfelder
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you make it compile? there are some stupid mistakes... symbol.h line 40 must be QWidget (need to include the header). implementation should move to symbol.cpp, makefiles etc...

about Element: this class is confusing. it only holds the type and coordinates. this is not needed: the type is obvious from the type (sic!) and the coordinates are parameters actually. symbols will have parameters anyway...

(will have a look later today.)

@andresmmera
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can't compile, of course. There are a number of dependencies to be solved.
I'm working on it right now.

symbol.h line 40 must be QWidget

Yep, I've realized that it was a mistake :-)

Just in case,... if I understood correctly, here we should use QucsLibComponent instead of Symbol

On the other hand, I am wondering if SymbolWidget should keep the following fields: QString ModelString, VerilogModelString, VHDLModelString;? I mean, to my mind, the purpose of SymbolWidget is to be used by QucsLibComponent instance just to display the part symbol in the dialog, am I right? So, maybe, it would be more appropriate to put these strings in QucsLibComponent class.

@felix-salfelder
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just in case,... if I understood correctly, here we should use QucsLibComponent instead of Symbol

yes and no. (my code is still wrong.) actually what is needed here is a Symbol* pointing to an instance of QucsLibComponent. currently, there is no instance and no pointer, but the stupid ad-hoc instanciation...
(i think you can fix it by just putting it as you wrote, for now).

On the other hand, I am wondering if SymbolWidget should keep the following fields: QString ModelString,

yes, an instance of QucsLibComponent should hold all information required/available about that symbol. that's only a question of how far we go right now. proper code is easier to grasp, so moving stuff into place always makes sense, YMMV. do it if you like. it might trigger more code movement... i will definitely review it.

@andresmmera
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've pushed my changes to a branch: andresmmera@6a6c7e5

Take a look if you wish, but it is not finished. I guess I'll continue at night...

Meanwhile, I have to figure out how to convert SymbolWidget into QWidget here

@felix-salfelder
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice.

i was expecting that it's possible to draw to a QWidget. maybe that's not entirely correct. will have a look, there should be a way...

@andresmmera
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure whether it is possible or not... but I'll check if there's some sort of QWidget inheritance somewhere else in Qucs

@felix-salfelder
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm it seems to be.

the current code attaches a Painter to the QWidget and simply paints stuff. let me see if i can compile this....

@andresmmera
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At worse, we could remove draw(QWidget&) from the base class...

@felix-salfelder
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, painting should not be a problem. but the graphics must be held in the symbols instance. the widget is the wrong place, as it cannot be accessed from within qucs.

i am now wondering, how DragNDropWidth is meant to work. anyway, i will have to check the drag and drop thing: drag and drop should simply transport a const pointer to the symbol being dragged... but the other end does not understand symbols yet (argh).

@felix-salfelder
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could remove draw(QWidget&) from the base class...

we will want to draw symbols in other places, too. e.g. in the schematic. or in a pdf. i think this function is vital.

@felix-salfelder
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will have to move some code around but it's pretty clear to me now. expect an update later today.

@andresmmera
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I'll stay tuned for it.

I've moved some headers (and struct definitions, etc...) back and forth. (last commit: andresmmera@dcb1a9b) I think that, apart from the QWidget issue, the rest of the code can be compiled without errors.

@felix-salfelder
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i have merged dcb1a9b.

updated my branch, it now compiles. there are two constructors for QucsLibComponent. one of them is nonsense, i think. and... i will have to revisit the dragndrop code.

NB: the function i called "draw" now draws. i accidentally put constructor code there in my first pass...
and there is a doSometimg function, i don't know what it does, perhaps it must go to the constructor or to attach.

(looking forward to add the geda symbols...:)

Please sign in to comment.