From 3b3167474388843b43c26eeaf59d8935646c95f2 Mon Sep 17 00:00:00 2001 From: Krasilnikov Sergey Date: Mon, 11 Dec 2023 15:13:33 +0300 Subject: [PATCH] completely rewrite rotation of paintings fixes #203 --- qucs/mouseactions.cpp | 3040 ++++++++++++++-------------- qucs/paintings/arrow.cpp | 41 +- qucs/paintings/arrow.h | 2 +- qucs/paintings/ellipse.cpp | 24 +- qucs/paintings/ellipse.h | 2 +- qucs/paintings/ellipsearc.cpp | 31 +- qucs/paintings/ellipsearc.h | 2 +- qucs/paintings/graphicline.cpp | 25 +- qucs/paintings/graphicline.h | 2 +- qucs/paintings/graphictext.cpp | 517 ++--- qucs/paintings/graphictext.h | 2 +- qucs/paintings/id_text.cpp | 2 +- qucs/paintings/id_text.h | 2 +- qucs/paintings/painting.h | 2 +- qucs/paintings/portsymbol.cpp | 2 +- qucs/paintings/portsymbol.h | 2 +- qucs/paintings/rectangle.cpp | 24 +- qucs/paintings/rectangle.h | 2 +- qucs/schematic.cpp | 3404 +++++++++++++++++--------------- 19 files changed, 3718 insertions(+), 3410 deletions(-) diff --git a/qucs/mouseactions.cpp b/qucs/mouseactions.cpp index 26be53162..09f5d552d 100644 --- a/qucs/mouseactions.cpp +++ b/qucs/mouseactions.cpp @@ -16,258 +16,285 @@ * (at your option) any later version. * * * ***************************************************************************/ -#include "qucs.h" -#include "main.h" -#include "node.h" -#include "schematic.h" #include "mouseactions.h" -#include "module.h" #include "components/component.h" +#include "components/componentdialog.h" +#include "components/optimizedialog.h" #include "components/spicedialog.h" #include "components/spicefile.h" -#include "components/optimizedialog.h" -#include "components/componentdialog.h" #include "components/vacomponent.h" -#include "spicecomponents/sp_customsim.h" #include "diagrams/diagramdialog.h" #include "diagrams/markerdialog.h" #include "diagrams/tabdiagram.h" #include "diagrams/timingdiagram.h" #include "dialogs/labeldialog.h" #include "dialogs/textboxdialog.h" -#include "extsimkernels/customsimdialog.h" #include "dialogs/tuner.h" +#include "extsimkernels/customsimdialog.h" +#include "main.h" +#include "module.h" +#include "node.h" +#include "qucs.h" +#include "schematic.h" +#include "spicecomponents/sp_customsim.h" -#include -#include -#include -#include +#include #include -#include -#include +#include +#include #include -#include #include -#include +#include +#include +#include +#include +#include #include #include +#define DOC_X_POS(x) (int(float(x) / Doc->Scale) + Doc->ViewX1) +#define DOC_Y_POS(y) (int(float(y) / Doc->Scale) + Doc->ViewY1) +#define DOC_X_FPOS (float(Event->pos().x()) / Doc->Scale + float(Doc->ViewX1)) +#define DOC_Y_FPOS (float(Event->pos().y()) / Doc->Scale + float(Doc->ViewY1)) -#define DOC_X_POS(x) (int(float(x)/Doc->Scale) + Doc->ViewX1) -#define DOC_Y_POS(y) (int(float(y)/Doc->Scale) + Doc->ViewY1) -#define DOC_X_FPOS (float(Event->pos().x())/Doc->Scale + float(Doc->ViewX1)) -#define DOC_Y_FPOS (float(Event->pos().y())/Doc->Scale + float(Doc->ViewY1)) - -#define SCR_X_POS(x) int(float(x - Doc->ViewX1) * Doc->Scale) -#define SCR_Y_POS(y) int(float(y - Doc->ViewY1) * Doc->Scale) - -QAction *formerAction; // remember action before drag n'drop etc. +#define SCR_X_POS(x) int(float(x - Doc->ViewX1) * Doc->Scale) +#define SCR_Y_POS(y) int(float(y - Doc->ViewY1) * Doc->Scale) +QAction *formerAction; // remember action before drag n'drop etc. -MouseActions::MouseActions(QucsApp* App_) +MouseActions::MouseActions(QucsApp *App_) { - App = App_; // pointer to main app - selElem = 0; // no component/diagram is selected - isMoveEqual = false; // mouse cursor move x and y the same way - focusElement = 0; //element being interacted with mouse - - // ............................................................... - // initialize menu appearing by right mouse button click on component - ComponentMenu = new QMenu(QucsMain); - focusMEvent = new QMouseEvent(QEvent::MouseButtonPress, QPoint(0,0), - Qt::NoButton, Qt::NoButton, Qt::NoModifier); + App = App_; // pointer to main app + selElem = 0; // no component/diagram is selected + isMoveEqual = false; // mouse cursor move x and y the same way + focusElement = 0; //element being interacted with mouse + + // ............................................................... + // initialize menu appearing by right mouse button click on component + ComponentMenu = new QMenu(QucsMain); + focusMEvent = new QMouseEvent(QEvent::MouseButtonPress, + QPoint(0, 0), + Qt::NoButton, + Qt::NoButton, + Qt::NoModifier); } - MouseActions::~MouseActions() { - delete ComponentMenu; - delete focusMEvent; + delete ComponentMenu; + delete focusMEvent; } // ----------------------------------------------------------- void MouseActions::setPainter(Schematic *Doc) { - // contents to viewport transformation - - Doc->PostPaintEvent(_Translate,-Doc->contentsX(), -Doc->contentsY()); - Doc->PostPaintEvent(_Scale,Doc->Scale, Doc->Scale); - Doc->PostPaintEvent(_Translate,-Doc->ViewX1, -Doc->ViewY1); - Doc->PostPaintEvent(_DotLine); - Doc->PostPaintEvent(_NotRop); + // contents to viewport transformation + Doc->PostPaintEvent(_Translate, -Doc->contentsX(), -Doc->contentsY()); + Doc->PostPaintEvent(_Scale, Doc->Scale, Doc->Scale); + Doc->PostPaintEvent(_Translate, -Doc->ViewX1, -Doc->ViewY1); + Doc->PostPaintEvent(_DotLine); + Doc->PostPaintEvent(_NotRop); } // ----------------------------------------------------------- bool MouseActions::pasteElements(Schematic *Doc) { - QClipboard *cb = QApplication::clipboard(); // get system clipboard - QString s = cb->text(QClipboard::Clipboard); - QTextStream stream(&s, QIODevice::ReadOnly); - movingElements.clear(); - if(!Doc->paste(&stream, &movingElements)) return false; - - Element *pe; - int xmax, xmin, ymax, ymin; - xmin = ymin = INT_MAX; - xmax = ymax = INT_MIN; - // First, get the max and min coordinates of all selected elements. - for(pe = movingElements.first(); pe != 0; pe = movingElements.next()) { - if(pe->Type == isWire) { - if(pe->x1 < xmin) xmin = pe->x1; - if(pe->x2 > xmax) xmax = pe->x2; - if(pe->y1 < ymin) ymin = pe->y1; - if(pe->y2 > ymax) ymax = pe->y2; - } - else { - if(pe->cx < xmin) xmin = pe->cx; - if(pe->cx > xmax) xmax = pe->cx; - if(pe->cy < ymin) ymin = pe->cy; - if(pe->cy > ymax) ymax = pe->cy; - } - } - - xmin = -((xmax+xmin) >> 1); // calculate midpoint - ymin = -((ymax+ymin) >> 1); - Doc->setOnGrid(xmin, ymin); - - // moving with mouse cursor in the midpoint - for(pe = movingElements.first(); pe != 0; pe = movingElements.next()) - if(pe->Type & isLabel) { - pe->cx += xmin; pe->x1 += xmin; - pe->cy += ymin; pe->y1 += ymin; + QClipboard *cb = QApplication::clipboard(); // get system clipboard + QString s = cb->text(QClipboard::Clipboard); + QTextStream stream(&s, QIODevice::ReadOnly); + movingElements.clear(); + if (!Doc->paste(&stream, &movingElements)) + return false; + + Element *pe; + int xmax, xmin, ymax, ymin; + xmin = ymin = INT_MAX; + xmax = ymax = INT_MIN; + // First, get the max and min coordinates of all selected elements. + for (pe = movingElements.first(); pe != 0; pe = movingElements.next()) { + if (pe->Type == isWire) { + if (pe->x1 < xmin) + xmin = pe->x1; + if (pe->x2 > xmax) + xmax = pe->x2; + if (pe->y1 < ymin) + ymin = pe->y1; + if (pe->y2 > ymax) + ymax = pe->y2; + } else { + if (pe->cx < xmin) + xmin = pe->cx; + if (pe->cx > xmax) + xmax = pe->cx; + if (pe->cy < ymin) + ymin = pe->cy; + if (pe->cy > ymax) + ymax = pe->cy; + } } - else - pe->setCenter(xmin, ymin, true); - return true; + xmin = -((xmax + xmin) >> 1); // calculate midpoint + ymin = -((ymax + ymin) >> 1); + Doc->setOnGrid(xmin, ymin); + + // moving with mouse cursor in the midpoint + for (pe = movingElements.first(); pe != 0; pe = movingElements.next()) + if (pe->Type & isLabel) { + pe->cx += xmin; + pe->x1 += xmin; + pe->cy += ymin; + pe->y1 += ymin; + } else + pe->setCenter(xmin, ymin, true); + + return true; } // ----------------------------------------------------------- void MouseActions::editLabel(Schematic *Doc, WireLabel *pl) { - LabelDialog *Dia = new LabelDialog(pl, Doc); - int Result = Dia->exec(); - if(Result == 0) return; - - QString Name = Dia->NodeName->text(); - QString Value = Dia->InitValue->text(); - delete Dia; - - if(Name.isEmpty() && Value.isEmpty()) { // if nothing entered, delete label - pl->pOwner->Label = 0; // delete name of wire - delete pl; - } - else { -/* Name.replace(' ', '_'); // label must not contain spaces + LabelDialog *Dia = new LabelDialog(pl, Doc); + int Result = Dia->exec(); + if (Result == 0) + return; + + QString Name = Dia->NodeName->text(); + QString Value = Dia->InitValue->text(); + delete Dia; + + if (Name.isEmpty() && Value.isEmpty()) { // if nothing entered, delete label + pl->pOwner->Label = 0; // delete name of wire + delete pl; + } else { + /* Name.replace(' ', '_'); // label must not contain spaces while(Name.at(0) == '_') Name.remove(0,1); // must not start with '_' if(Name.isEmpty()) return; if(Name == pl->Name) return;*/ - if(Result == 1) return; // nothing changed - - int old_x2 = pl->x2; - pl->setName(Name); // set new name - pl->initValue = Value; - if(pl->cx > (pl->x1+(pl->x2>>1))) - pl->x1 -= pl->x2 - old_x2; // don't change position due to text width - } - - Doc->sizeOfAll(Doc->UsedX1, Doc->UsedY1, Doc->UsedX2, Doc->UsedY2); - Doc->viewport()->update(); - drawn = false; - Doc->setChanged(true, true); + if (Result == 1) + return; // nothing changed + + int old_x2 = pl->x2; + pl->setName(Name); // set new name + pl->initValue = Value; + if (pl->cx > (pl->x1 + (pl->x2 >> 1))) + pl->x1 -= pl->x2 - old_x2; // don't change position due to text width + } + + Doc->sizeOfAll(Doc->UsedX1, Doc->UsedY1, Doc->UsedX2, Doc->UsedY2); + Doc->viewport()->update(); + drawn = false; + Doc->setChanged(true, true); } // ----------------------------------------------------------- // Reinserts all elements (moved by the user) back into the schematic. void MouseActions::endElementMoving(Schematic *Doc, Q3PtrList *movElements) { - Element *pe; - for(pe = movElements->first(); pe!=0; pe = movElements->next()) { -// pe->isSelected = false; // deselect first (maybe afterwards pe == NULL) - switch(pe->Type) { // FIXME: use casts. - case isWire: - if(pe->x1 == pe->x2) - if(pe->y1 == pe->y2) { - // Delete wires with zero length, but preserve label. - if(((Wire*)pe)->Label) { - Doc->insertNodeLabel((WireLabel*)((Wire*)pe)->Label); - ((Wire*)pe)->Label = 0; - } - delete (Wire*)pe; - break; - } + Element *pe; + for (pe = movElements->first(); pe != 0; pe = movElements->next()) { + // pe->isSelected = false; // deselect first (maybe afterwards pe == NULL) + switch (pe->Type) { // FIXME: use casts. + case isWire: + if (pe->x1 == pe->x2) + if (pe->y1 == pe->y2) { + // Delete wires with zero length, but preserve label. + if (((Wire *) pe)->Label) { + Doc->insertNodeLabel((WireLabel *) ((Wire *) pe)->Label); + ((Wire *) pe)->Label = 0; + } + delete (Wire *) pe; + break; + } - Doc->insertWire((Wire*)pe); - break; - case isDiagram: - Doc->Diagrams->append((Diagram*)pe); - break; - case isPainting: - Doc->Paintings->append((Painting*)pe); - break; - case isComponent: - case isAnalogComponent: - case isDigitalComponent: - Doc->insertRawComponent((Component*)pe, false); - break; - case isMovingLabel: - case isHMovingLabel: - case isVMovingLabel: - Doc->insertNodeLabel((WireLabel*)pe); - break; - case isMarker: - assert(dynamic_cast(pe)); - break; + Doc->insertWire((Wire *) pe); + break; + case isDiagram: + Doc->Diagrams->append((Diagram *) pe); + break; + case isPainting: + Doc->Paintings->append((Painting *) pe); + break; + case isComponent: + case isAnalogComponent: + case isDigitalComponent: + Doc->insertRawComponent((Component *) pe, false); + break; + case isMovingLabel: + case isHMovingLabel: + case isVMovingLabel: + Doc->insertNodeLabel((WireLabel *) pe); + break; + case isMarker: + assert(dynamic_cast(pe)); + break; + } } - } - movElements->clear(); - if((MAx3 != 0) || (MAy3 != 0)) // moved or put at the same place ? - Doc->setChanged(true, true); + movElements->clear(); + if ((MAx3 != 0) || (MAy3 != 0)) // moved or put at the same place ? + Doc->setChanged(true, true); - // enlarge viewarea if components lie outside the view - Doc->sizeOfAll(Doc->UsedX1, Doc->UsedY1, Doc->UsedX2, Doc->UsedY2); - Doc->enlargeView(Doc->UsedX1, Doc->UsedY1, Doc->UsedX2, Doc->UsedY2); - Doc->viewport()->update(); - drawn = false; + // enlarge viewarea if components lie outside the view + Doc->sizeOfAll(Doc->UsedX1, Doc->UsedY1, Doc->UsedX2, Doc->UsedY2); + Doc->enlargeView(Doc->UsedX1, Doc->UsedY1, Doc->UsedX2, Doc->UsedY2); + Doc->viewport()->update(); + drawn = false; } // ----------------------------------------------------------- // Moves elements in "movElements" by x/y void MouseActions::moveElements(Q3PtrList *movElements, int x, int y) { - Wire *pw; - Element *pe; - for(pe = movElements->first(); pe != 0; pe = movElements->next()) { - if(pe->Type == isWire) { - pw = (Wire*)pe; // connected wires are not moved completely - - if(((uintptr_t)pw->Port1) > 3) { - pw->x1 += x; pw->y1 += y; - if(pw->Label) { pw->Label->cx += x; pw->Label->cy += y; } - } - else { if((uintptr_t)(pw->Port1) & 1) { pw->x1 += x; } - if((uintptr_t)(pw->Port1) & 2) { pw->y1 += y; } } - - if(((uintptr_t)pw->Port2) > 3) { pw->x2 += x; pw->y2 += y; } - else { if((uintptr_t)(pw->Port2) & 1) pw->x2 += x; - if((uintptr_t)(pw->Port2) & 2) pw->y2 += y; } - - if(pw->Label) { // root of node label must lie on wire - if(pw->Label->cx < pw->x1) pw->Label->cx = pw->x1; - if(pw->Label->cy < pw->y1) pw->Label->cy = pw->y1; - if(pw->Label->cx > pw->x2) pw->Label->cx = pw->x2; - if(pw->Label->cy > pw->y2) pw->Label->cy = pw->y2; - } + Wire *pw; + Element *pe; + for (pe = movElements->first(); pe != 0; pe = movElements->next()) { + if (pe->Type == isWire) { + pw = (Wire *) pe; // connected wires are not moved completely + + if (((uintptr_t) pw->Port1) > 3) { + pw->x1 += x; + pw->y1 += y; + if (pw->Label) { + pw->Label->cx += x; + pw->Label->cy += y; + } + } else { + if ((uintptr_t) (pw->Port1) & 1) { + pw->x1 += x; + } + if ((uintptr_t) (pw->Port1) & 2) { + pw->y1 += y; + } + } + + if (((uintptr_t) pw->Port2) > 3) { + pw->x2 += x; + pw->y2 += y; + } else { + if ((uintptr_t) (pw->Port2) & 1) + pw->x2 += x; + if ((uintptr_t) (pw->Port2) & 2) + pw->y2 += y; + } + if (pw->Label) { // root of node label must lie on wire + if (pw->Label->cx < pw->x1) + pw->Label->cx = pw->x1; + if (pw->Label->cy < pw->y1) + pw->Label->cy = pw->y1; + if (pw->Label->cx > pw->x2) + pw->Label->cx = pw->x2; + if (pw->Label->cy > pw->y2) + pw->Label->cy = pw->y2; + } + + } else + pe->setCenter(x, y, true); } - else pe->setCenter(x, y, true); - } } - // *********************************************************************** // ********** ********** // ********** Functions for serving mouse moving ********** @@ -275,44 +302,43 @@ void MouseActions::moveElements(Q3PtrList *movElements, int x, int y) // *********************************************************************** void MouseActions::MMoveElement(Schematic *Doc, QMouseEvent *Event) { - if(selElem == 0) return; - -// qDebug() << "MMoveElement got selElem"; + if (selElem == 0) + return; - int x = Event->pos().x(); - int y = Event->pos().y(); - int fx = DOC_X_POS(x); - int fy = DOC_Y_POS(y); - int gx = fx; - int gy = fy; - Doc->setOnGrid(gx, gy); + // qDebug() << "MMoveElement got selElem"; + int x = Event->pos().x(); + int y = Event->pos().y(); + int fx = DOC_X_POS(x); + int fy = DOC_Y_POS(y); + int gx = fx; + int gy = fy; + Doc->setOnGrid(gx, gy); - //QPainter painter(Doc->viewport()); - setPainter(Doc); + //QPainter painter(Doc->viewport()); + setPainter(Doc); + + if (selElem->Type == isPainting) { + Doc->PostPaintEvent(_NotRop, 0, 0, 0, 0); + x -= Doc->contentsX(); + y -= Doc->contentsY(); + ((Painting *) selElem)->MouseMoving(Doc, x, y, gx, gy, Doc, x, y, drawn); + drawn = true; + Doc->viewport()->update(); + return; + } // of "if(isPainting)" - if(selElem->Type == isPainting) { - Doc->PostPaintEvent (_NotRop, 0, 0, 0, 0); - x -= Doc->contentsX(); - y -= Doc->contentsY(); - ((Painting*)selElem)->MouseMoving(Doc, x, y, gx, gy, - Doc, x, y, drawn); + // ********** it is a component or diagram + if (drawn) + selElem->paintScheme(Doc); // erase old scheme drawn = true; - Doc->viewport()->update(); - return; - } // of "if(isPainting)" - - // ********** it is a component or diagram - if(drawn) selElem->paintScheme(Doc); // erase old scheme - drawn = true; + // Component *comp = (Component*)selElem; + //qDebug() << "desc" << comp->Description << "gx" << gx << "gy" << gy; -// Component *comp = (Component*)selElem; - //qDebug() << "desc" << comp->Description << "gx" << gx << "gy" << gy; - - selElem->setCenter(gx, gy); - selElem->paintScheme(Doc); // paint scheme at new position - Doc->viewport()->update(); + selElem->setCenter(gx, gy); + selElem->paintScheme(Doc); // paint scheme at new position + Doc->viewport()->update(); } /** @@ -321,37 +347,39 @@ void MouseActions::MMoveElement(Schematic *Doc, QMouseEvent *Event) * @param fx - document x-coordinate of center * @param fy - document x-coordinate of center */ -static void paintAim(Schematic *Doc, int fx,int fy){ - //let we reserve couple of points at the edges of lines for some aesthetics, - //and visual check that our calculations has fit the widget window. - const int ldelta = 2; - - //left and upper edges of our lines - int lx0 = DOC_X_POS(Doc->contentsX()+ldelta); - int ly0 = DOC_Y_POS(Doc->contentsY()+ldelta); - - //right and bottom edges - int lx1 = DOC_X_POS(Doc->contentsX()+Doc->viewport()->width()-1-ldelta); - int ly1 = DOC_Y_POS(Doc->contentsY()+Doc->viewport()->height()-1-ldelta); - - //post line paint events - Doc->PostPaintEvent (_Line, lx0, fy, lx1, fy); - Doc->PostPaintEvent (_Line, fx, ly0, fx, ly1); +static void paintAim(Schematic *Doc, int fx, int fy) +{ + //let we reserve couple of points at the edges of lines for some aesthetics, + //and visual check that our calculations has fit the widget window. + const int ldelta = 2; + + //left and upper edges of our lines + int lx0 = DOC_X_POS(Doc->contentsX() + ldelta); + int ly0 = DOC_Y_POS(Doc->contentsY() + ldelta); + + //right and bottom edges + int lx1 = DOC_X_POS(Doc->contentsX() + Doc->viewport()->width() - 1 - ldelta); + int ly1 = DOC_Y_POS(Doc->contentsY() + Doc->viewport()->height() - 1 - ldelta); + + //post line paint events + Doc->PostPaintEvent(_Line, lx0, fy, lx1, fy); + Doc->PostPaintEvent(_Line, fx, ly0, fx, ly1); } //paint ghost line - horizontal -static void paintGhostLineH(Schematic *Doc, int fx,int fy, int fxx){ - Doc->PostPaintEvent (_Line, fx, fy-1, fxx, fy-1); - Doc->PostPaintEvent (_Line, fx, fy+1, fxx, fy+1); +static void paintGhostLineH(Schematic *Doc, int fx, int fy, int fxx) +{ + Doc->PostPaintEvent(_Line, fx, fy - 1, fxx, fy - 1); + Doc->PostPaintEvent(_Line, fx, fy + 1, fxx, fy + 1); } //paint ghost line - vertical -static void paintGhostLineV(Schematic *Doc, int fx, int fy, int fyy){ - Doc->PostPaintEvent (_Line, fx-1, fy, fx-1, fyy); - Doc->PostPaintEvent (_Line, fx+1, fy, fx+1, fyy); +static void paintGhostLineV(Schematic *Doc, int fx, int fy, int fyy) +{ + Doc->PostPaintEvent(_Line, fx - 1, fy, fx - 1, fyy); + Doc->PostPaintEvent(_Line, fx + 1, fy, fx + 1, fyy); } - // ----------------------------------------------------------- /** * @brief MouseActions::MMoveWire2 Paint wire as it is being drawn with mouse. @@ -360,27 +388,25 @@ static void paintGhostLineV(Schematic *Doc, int fx, int fy, int fyy){ */ void MouseActions::MMoveWire2(Schematic *Doc, QMouseEvent *Event) { - MAx2 = DOC_X_POS(Event->pos().x()); - MAy2 = DOC_Y_POS(Event->pos().y()); - Doc->setOnGrid(MAx2, MAy2); - paintAim(Doc,MAx2,MAy2); //let we paint aim cross - - //because cross slightly masks a wire, let we make wire thicker - //better to make it by increasing of pen, but here we cannot access - //pen - if(MAx1 == 0) { - paintGhostLineV(Doc,MAx3,MAy3,MAy2); - paintGhostLineH(Doc,MAx3,MAy2,MAx2); - } - else { - paintGhostLineH(Doc,MAx3,MAy3,MAx2); - paintGhostLineV(Doc,MAx2,MAy3,MAy2); - } - - QucsMain->MouseDoubleClickAction = &MouseActions::MDoubleClickWire2; - Doc->viewport()->update(); -} + MAx2 = DOC_X_POS(Event->pos().x()); + MAy2 = DOC_Y_POS(Event->pos().y()); + Doc->setOnGrid(MAx2, MAy2); + paintAim(Doc, MAx2, MAy2); //let we paint aim cross + + //because cross slightly masks a wire, let we make wire thicker + //better to make it by increasing of pen, but here we cannot access + //pen + if (MAx1 == 0) { + paintGhostLineV(Doc, MAx3, MAy3, MAy2); + paintGhostLineH(Doc, MAx3, MAy2, MAx2); + } else { + paintGhostLineH(Doc, MAx3, MAy3, MAx2); + paintGhostLineV(Doc, MAx2, MAy3, MAy2); + } + QucsMain->MouseDoubleClickAction = &MouseActions::MDoubleClickWire2; + Doc->viewport()->update(); +} /** * @brief MouseActions::MMoveWire1 Paint hair cross for "insert wire" mode @@ -389,29 +415,37 @@ void MouseActions::MMoveWire2(Schematic *Doc, QMouseEvent *Event) */ void MouseActions::MMoveWire1(Schematic *Doc, QMouseEvent *Event) { - MAx3 = DOC_X_POS(Event->pos().x()); - MAy3 = DOC_Y_POS(Event->pos().y()); - Doc->setOnGrid(MAx3, MAy3); - paintAim(Doc,MAx3,MAy3); - MAx2 = DOC_X_POS(Doc->contentsX()+Doc->viewport()->width()-1-2); - MAx2 = DOC_Y_POS(Doc->contentsY()+Doc->viewport()->height()-1-2); - Doc->viewport()->update(); + MAx3 = DOC_X_POS(Event->pos().x()); + MAy3 = DOC_Y_POS(Event->pos().y()); + Doc->setOnGrid(MAx3, MAy3); + paintAim(Doc, MAx3, MAy3); + MAx2 = DOC_X_POS(Doc->contentsX() + Doc->viewport()->width() - 1 - 2); + MAx2 = DOC_Y_POS(Doc->contentsY() + Doc->viewport()->height() - 1 - 2); + Doc->viewport()->update(); } - /** * @brief MouseActions::MMoveSelect Paints a rectangle for select area. * @param Doc * @param Event */ -void MouseActions::MMoveSelect(Schematic *Doc, QMouseEvent *Event) { +void MouseActions::MMoveSelect(Schematic *Doc, QMouseEvent *Event) +{ //qDebug() << "MMoveSelect " << "select area"; MAx2 = DOC_X_POS(Event->pos().x()) - MAx1; MAy2 = DOC_Y_POS(Event->pos().y()) - MAy1; - if (isMoveEqual) { // x and y size must be equal ? + if (isMoveEqual) { // x and y size must be equal ? if (abs(MAx2) > abs(MAy2)) { - if (MAx2 < 0) MAx2 = -abs(MAy2); else MAx2 = abs(MAy2); - } else { if (MAy2 < 0) MAy2 = -abs(MAx2); else MAy2 = abs(MAx2); } + if (MAx2 < 0) + MAx2 = -abs(MAy2); + else + MAx2 = abs(MAy2); + } else { + if (MAy2 < 0) + MAy2 = -abs(MAx2); + else + MAy2 = abs(MAx2); + } } Doc->PostPaintEvent(_SelectionRect, MAx1, MAy1, MAx2, MAy2); @@ -420,104 +454,120 @@ void MouseActions::MMoveSelect(Schematic *Doc, QMouseEvent *Event) { // ----------------------------------------------------------- void MouseActions::MMoveResizePainting(Schematic *Doc, QMouseEvent *Event) { - setPainter(Doc); + setPainter(Doc); - MAx1 = DOC_X_POS(Event->pos().x()); - MAy1 = DOC_Y_POS(Event->pos().y()); - Doc->setOnGrid(MAx1, MAy1); - ((Painting*)focusElement)->MouseResizeMoving(MAx1, MAy1, Doc); + MAx1 = DOC_X_POS(Event->pos().x()); + MAy1 = DOC_Y_POS(Event->pos().y()); + Doc->setOnGrid(MAx1, MAy1); + ((Painting *) focusElement)->MouseResizeMoving(MAx1, MAy1, Doc); } // ----------------------------------------------------------- // Moves components by keeping the mouse button pressed. void MouseActions::MMoveMoving(Schematic *Doc, QMouseEvent *Event) { + setPainter(Doc); - setPainter(Doc); + MAx2 = DOC_X_POS(Event->pos().x()); + MAy2 = DOC_Y_POS(Event->pos().y()); - MAx2 = DOC_X_POS(Event->pos().x()); - MAy2 = DOC_Y_POS(Event->pos().y()); - - Doc->setOnGrid(MAx2, MAy2); - MAx3 = MAx1 = MAx2 - MAx1; - MAy3 = MAy1 = MAy2 - MAy1; - - movingElements.clear(); - Doc->copySelectedElements(&movingElements); - Doc->viewport()->repaint(); - - Wire *pw; - // Changes the position of all moving elements by dx/dy - for(Element *pe=movingElements.first(); pe!=0; pe=movingElements.next()) { - if(pe->Type == isWire) { - pw = (Wire*)pe; // connecting wires are not moved completely + Doc->setOnGrid(MAx2, MAy2); + MAx3 = MAx1 = MAx2 - MAx1; + MAy3 = MAy1 = MAy2 - MAy1; + + movingElements.clear(); + Doc->copySelectedElements(&movingElements); + Doc->viewport()->repaint(); + + Wire *pw; + // Changes the position of all moving elements by dx/dy + for (Element *pe = movingElements.first(); pe != 0; pe = movingElements.next()) { + if (pe->Type == isWire) { + pw = (Wire *) pe; // connecting wires are not moved completely + + if (((uintptr_t) pw->Port1) > 3) { + pw->x1 += MAx1; + pw->y1 += MAy1; + } else { + if ((uintptr_t) (pw->Port1) & 1) { + pw->x1 += MAx1; + } + if ((uintptr_t) (pw->Port1) & 2) { + pw->y1 += MAy1; + } + } - if(((uintptr_t)pw->Port1) > 3) { pw->x1 += MAx1; pw->y1 += MAy1; } - else { if((uintptr_t)(pw->Port1) & 1) { pw->x1 += MAx1; } - if((uintptr_t)(pw->Port1) & 2) { pw->y1 += MAy1; } } + if (((uintptr_t) pw->Port2) > 3) { + pw->x2 += MAx1; + pw->y2 += MAy1; + } else { + if ((uintptr_t) (pw->Port2) & 1) + pw->x2 += MAx1; + if ((uintptr_t) (pw->Port2) & 2) + pw->y2 += MAy1; + } - if(((uintptr_t)pw->Port2) > 3) { pw->x2 += MAx1; pw->y2 += MAy1; } - else { if((uintptr_t)(pw->Port2) & 1) pw->x2 += MAx1; - if((uintptr_t)(pw->Port2) & 2) pw->y2 += MAy1; } + if (pw->Label) { // root of node label must lie on wire + if (pw->Label->cx < pw->x1) + pw->Label->cx = pw->x1; + if (pw->Label->cy < pw->y1) + pw->Label->cy = pw->y1; + if (pw->Label->cx > pw->x2) + pw->Label->cx = pw->x2; + if (pw->Label->cy > pw->y2) + pw->Label->cy = pw->y2; + } - if(pw->Label) { // root of node label must lie on wire - if(pw->Label->cx < pw->x1) pw->Label->cx = pw->x1; - if(pw->Label->cy < pw->y1) pw->Label->cy = pw->y1; - if(pw->Label->cx > pw->x2) pw->Label->cx = pw->x2; - if(pw->Label->cy > pw->y2) pw->Label->cy = pw->y2; - } + } else + pe->setCenter(MAx1, MAy1, true); + pe->paintScheme(Doc); } - else pe->setCenter(MAx1, MAy1, true); - - pe->paintScheme(Doc); - } - - drawn = true; - MAx1 = MAx2; - MAy1 = MAy2; - QucsMain->MouseMoveAction = &MouseActions::MMoveMoving2; - QucsMain->MouseReleaseAction = &MouseActions::MReleaseMoving; + drawn = true; + MAx1 = MAx2; + MAy1 = MAy2; + QucsMain->MouseMoveAction = &MouseActions::MMoveMoving2; + QucsMain->MouseReleaseAction = &MouseActions::MReleaseMoving; } // ----------------------------------------------------------- // Moves components by keeping the mouse button pressed. void MouseActions::MMoveMoving2(Schematic *Doc, QMouseEvent *Event) { - setPainter(Doc); - - MAx2 = DOC_X_POS(Event->pos().x()); - MAy2 = DOC_Y_POS(Event->pos().y()); - - Element *pe; - if(drawn) // erase old scheme - for(pe = movingElements.first(); pe != 0; pe = movingElements.next()) - pe->paintScheme(Doc); -// if(pe->Type == isWire) if(((Wire*)pe)->Label) -// if(!((Wire*)pe)->Label->isSelected) -// ((Wire*)pe)->Label->paintScheme(&painter); - - drawn = true; - if((Event->modifiers().testFlag(Qt::ControlModifier)) == 0) - Doc->setOnGrid(MAx2, MAy2); // use grid only if CTRL key not pressed - MAx1 = MAx2 - MAx1; - MAy1 = MAy2 - MAy1; - MAx3 += MAx1; MAy3 += MAy1; // keep track of the complete movement - - moveElements(&movingElements, MAx1, MAy1); // moves elements by MAx1/MAy1 - - // paint afterwards to avoid conflict between wire and label painting - for(pe = movingElements.first(); pe != 0; pe = movingElements.next()) - pe->paintScheme(Doc); -// if(pe->Type == isWire) if(((Wire*)pe)->Label) -// if(!((Wire*)pe)->Label->isSelected) -// ((Wire*)pe)->Label->paintScheme(&painter); - - MAx1 = MAx2; - MAy1 = MAy2; -} + setPainter(Doc); + + MAx2 = DOC_X_POS(Event->pos().x()); + MAy2 = DOC_Y_POS(Event->pos().y()); + Element *pe; + if (drawn) // erase old scheme + for (pe = movingElements.first(); pe != 0; pe = movingElements.next()) + pe->paintScheme(Doc); + // if(pe->Type == isWire) if(((Wire*)pe)->Label) + // if(!((Wire*)pe)->Label->isSelected) + // ((Wire*)pe)->Label->paintScheme(&painter); + + drawn = true; + if ((Event->modifiers().testFlag(Qt::ControlModifier)) == 0) + Doc->setOnGrid(MAx2, MAy2); // use grid only if CTRL key not pressed + MAx1 = MAx2 - MAx1; + MAy1 = MAy2 - MAy1; + MAx3 += MAx1; + MAy3 += MAy1; // keep track of the complete movement + + moveElements(&movingElements, MAx1, MAy1); // moves elements by MAx1/MAy1 + + // paint afterwards to avoid conflict between wire and label painting + for (pe = movingElements.first(); pe != 0; pe = movingElements.next()) + pe->paintScheme(Doc); + // if(pe->Type == isWire) if(((Wire*)pe)->Label) + // if(!((Wire*)pe)->Label->isSelected) + // ((Wire*)pe)->Label->paintScheme(&painter); + + MAx1 = MAx2; + MAy1 = MAy2; +} /** * @brief MouseActions::MMovePaste Moves components after paste from clipboard. @@ -526,38 +576,37 @@ void MouseActions::MMoveMoving2(Schematic *Doc, QMouseEvent *Event) */ void MouseActions::MMovePaste(Schematic *Doc, QMouseEvent *Event) { - MAx1 = DOC_X_POS(Event->pos().x()); - MAy1 = DOC_Y_POS(Event->pos().y()); - moveElements(Doc,MAx1,MAy1); - paintElementsScheme(Doc); - - drawn = true; - QucsMain->MouseMoveAction = &MouseActions::MMoveMoving2; - QucsMain->MouseReleaseAction = &MouseActions::MReleasePaste; + MAx1 = DOC_X_POS(Event->pos().x()); + MAy1 = DOC_Y_POS(Event->pos().y()); + moveElements(Doc, MAx1, MAy1); + paintElementsScheme(Doc); + + drawn = true; + QucsMain->MouseMoveAction = &MouseActions::MMoveMoving2; + QucsMain->MouseReleaseAction = &MouseActions::MReleasePaste; } // ----------------------------------------------------------- // Moves scroll bar of diagram (e.g. tabular) according the mouse cursor. void MouseActions::MMoveScrollBar(Schematic *Doc, QMouseEvent *Event) { - TabDiagram *d = (TabDiagram*)focusElement; - int x = DOC_X_POS(Event->pos().x()); - int y = DOC_Y_POS(Event->pos().y()); - - if(d->scrollTo(MAx2, x - MAx1, y - MAy1)) { - Doc->setChanged(true, true, 'm'); // 'm' = only the first time - -// FIXME #warning QPainter p(Doc->viewport()); - // FIXME #warning ViewPainter Painter; - // FIXME #warning Painter.init(&p, Doc->Scale, -Doc->ViewX1, -Doc->ViewY1, -// FIXME #warning Doc->contentsX(), Doc->contentsY()); -// FIXME #warning Painter.fillRect(d->cx-d->x1, d->cy-d->y2, d->x2+d->x1, d->y2+d->y1, -// FIXME #warning QucsSettings.BGColor); -// FIXME #warning d->paint(&Painter); - } + TabDiagram *d = (TabDiagram *) focusElement; + int x = DOC_X_POS(Event->pos().x()); + int y = DOC_Y_POS(Event->pos().y()); + + if (d->scrollTo(MAx2, x - MAx1, y - MAy1)) { + Doc->setChanged(true, true, 'm'); // 'm' = only the first time + + // FIXME #warning QPainter p(Doc->viewport()); + // FIXME #warning ViewPainter Painter; + // FIXME #warning Painter.init(&p, Doc->Scale, -Doc->ViewX1, -Doc->ViewY1, + // FIXME #warning Doc->contentsX(), Doc->contentsY()); + // FIXME #warning Painter.fillRect(d->cx-d->x1, d->cy-d->y2, d->x2+d->x1, d->y2+d->y1, + // FIXME #warning QucsSettings.BGColor); + // FIXME #warning d->paint(&Painter); + } } - /** * @brief MouseActions::MMoveDelete * Paints a cross under the mouse cursor to show the delete mode. @@ -566,15 +615,14 @@ void MouseActions::MMoveScrollBar(Schematic *Doc, QMouseEvent *Event) */ void MouseActions::MMoveDelete(Schematic *Doc, QMouseEvent *Event) { - MAx3 = DOC_X_POS(Event->pos().x()); - MAy3 = DOC_Y_POS(Event->pos().y()); + MAx3 = DOC_X_POS(Event->pos().x()); + MAy3 = DOC_Y_POS(Event->pos().y()); - // cannot draw on the viewport, it is displaced by the size of dock and toolbar - Doc->PostPaintEvent (_Line, MAx3-15, MAy3-15, MAx3+15, MAy3+15,0,0,false); - Doc->PostPaintEvent (_Line, MAx3-15, MAy3+15, MAx3+15, MAy3-15,0,0,false); + // cannot draw on the viewport, it is displaced by the size of dock and toolbar + Doc->PostPaintEvent(_Line, MAx3 - 15, MAy3 - 15, MAx3 + 15, MAy3 + 15, 0, 0, false); + Doc->PostPaintEvent(_Line, MAx3 - 15, MAy3 + 15, MAx3 + 15, MAy3 - 15, 0, 0, false); } - /** * @brief MouseActions::MMoveLabel Paints a label above the mouse cursor for "set wire label". * @param Doc @@ -582,21 +630,20 @@ void MouseActions::MMoveDelete(Schematic *Doc, QMouseEvent *Event) */ void MouseActions::MMoveLabel(Schematic *Doc, QMouseEvent *Event) { - MAx3 = DOC_X_POS(Event->pos().x()); - MAy3 = DOC_Y_POS(Event->pos().y()); - - // paint marker - Doc->PostPaintEvent (_Line, MAx3, MAy3, MAx3+10, MAy3-10); - Doc->PostPaintEvent (_Line, MAx3+10, MAy3-10, MAx3+20, MAy3-10); - Doc->PostPaintEvent (_Line, MAx3+10, MAy3-10, MAx3+10, MAy3-17); - - // paint A - Doc->PostPaintEvent (_Line, MAx3+12, MAy3-12, MAx3+15, MAy3-23); - Doc->PostPaintEvent (_Line, MAx3+14, MAy3-17, MAx3+17, MAy3-17); - Doc->PostPaintEvent (_Line, MAx3+19, MAy3-12, MAx3+16, MAy3-23); + MAx3 = DOC_X_POS(Event->pos().x()); + MAy3 = DOC_Y_POS(Event->pos().y()); + + // paint marker + Doc->PostPaintEvent(_Line, MAx3, MAy3, MAx3 + 10, MAy3 - 10); + Doc->PostPaintEvent(_Line, MAx3 + 10, MAy3 - 10, MAx3 + 20, MAy3 - 10); + Doc->PostPaintEvent(_Line, MAx3 + 10, MAy3 - 10, MAx3 + 10, MAy3 - 17); + + // paint A + Doc->PostPaintEvent(_Line, MAx3 + 12, MAy3 - 12, MAx3 + 15, MAy3 - 23); + Doc->PostPaintEvent(_Line, MAx3 + 14, MAy3 - 17, MAx3 + 17, MAy3 - 17); + Doc->PostPaintEvent(_Line, MAx3 + 19, MAy3 - 12, MAx3 + 16, MAy3 - 23); } - /** * @brief MouseActions::MMoveMarker Paints a triangle above the mouse for "set marker on graph" * @param Doc @@ -604,15 +651,14 @@ void MouseActions::MMoveLabel(Schematic *Doc, QMouseEvent *Event) */ void MouseActions::MMoveMarker(Schematic *Doc, QMouseEvent *Event) { - MAx3 = DOC_X_POS(Event->pos().x()); - MAy3 = DOC_Y_POS(Event->pos().y()); + MAx3 = DOC_X_POS(Event->pos().x()); + MAy3 = DOC_Y_POS(Event->pos().y()); - Doc->PostPaintEvent (_Line, MAx3, MAy3-2, MAx3-8, MAy3-10); - Doc->PostPaintEvent (_Line, MAx3+1, MAy3-3, MAx3+8, MAy3-10); - Doc->PostPaintEvent (_Line, MAx3-7, MAy3-10, MAx3+7, MAy3-10); + Doc->PostPaintEvent(_Line, MAx3, MAy3 - 2, MAx3 - 8, MAy3 - 10); + Doc->PostPaintEvent(_Line, MAx3 + 1, MAy3 - 3, MAx3 + 8, MAy3 - 10); + Doc->PostPaintEvent(_Line, MAx3 - 7, MAy3 - 10, MAx3 + 7, MAy3 - 10); } - /** * @brief MouseActions::MMoveMirrorX Paints rounded "mirror about y axis" mouse cursor * @param Doc @@ -620,17 +666,16 @@ void MouseActions::MMoveMarker(Schematic *Doc, QMouseEvent *Event) */ void MouseActions::MMoveMirrorY(Schematic *Doc, QMouseEvent *Event) { - MAx3 = DOC_X_POS(Event->pos().x()); - MAy3 = DOC_Y_POS(Event->pos().y()); - - Doc->PostPaintEvent (_Line, MAx3-11, MAy3-4, MAx3-9, MAy3-9); - Doc->PostPaintEvent (_Line, MAx3-11, MAy3-3, MAx3-6, MAy3-3); - Doc->PostPaintEvent (_Line, MAx3+11, MAy3-4, MAx3+9, MAy3-9); - Doc->PostPaintEvent (_Line, MAx3+11, MAy3-3, MAx3+6, MAy3-3); - Doc->PostPaintEvent (_Arc, MAx3-10, MAy3-8, 21, 10, 16*20, 16*140,false); + MAx3 = DOC_X_POS(Event->pos().x()); + MAy3 = DOC_Y_POS(Event->pos().y()); + + Doc->PostPaintEvent(_Line, MAx3 - 11, MAy3 - 4, MAx3 - 9, MAy3 - 9); + Doc->PostPaintEvent(_Line, MAx3 - 11, MAy3 - 3, MAx3 - 6, MAy3 - 3); + Doc->PostPaintEvent(_Line, MAx3 + 11, MAy3 - 4, MAx3 + 9, MAy3 - 9); + Doc->PostPaintEvent(_Line, MAx3 + 11, MAy3 - 3, MAx3 + 6, MAy3 - 3); + Doc->PostPaintEvent(_Arc, MAx3 - 10, MAy3 - 8, 21, 10, 16 * 20, 16 * 140, false); } - /** * @brief MouseActions::MMoveMirrorX Paints rounded "mirror about x axis" mouse cursor * @param Doc @@ -638,14 +683,14 @@ void MouseActions::MMoveMirrorY(Schematic *Doc, QMouseEvent *Event) */ void MouseActions::MMoveMirrorX(Schematic *Doc, QMouseEvent *Event) { - MAx3 = DOC_X_POS(Event->pos().x()); - MAy3 = DOC_Y_POS(Event->pos().y()); - - Doc->PostPaintEvent (_Line, MAx3-4, MAy3-11, MAx3-9, MAy3-9); - Doc->PostPaintEvent (_Line, MAx3-3, MAy3-11, MAx3-3, MAy3-6); - Doc->PostPaintEvent (_Line, MAx3-4, MAy3+11, MAx3-9, MAy3+9); - Doc->PostPaintEvent (_Line, MAx3-3, MAy3+11, MAx3-3, MAy3+6); - Doc->PostPaintEvent (_Arc, MAx3-8, MAy3-10, 10, 21, 16*110, 16*140,false); + MAx3 = DOC_X_POS(Event->pos().x()); + MAy3 = DOC_Y_POS(Event->pos().y()); + + Doc->PostPaintEvent(_Line, MAx3 - 4, MAy3 - 11, MAx3 - 9, MAy3 - 9); + Doc->PostPaintEvent(_Line, MAx3 - 3, MAy3 - 11, MAx3 - 3, MAy3 - 6); + Doc->PostPaintEvent(_Line, MAx3 - 4, MAy3 + 11, MAx3 - 9, MAy3 + 9); + Doc->PostPaintEvent(_Line, MAx3 - 3, MAy3 + 11, MAx3 - 3, MAy3 + 6); + Doc->PostPaintEvent(_Arc, MAx3 - 8, MAy3 - 10, 10, 21, 16 * 110, 16 * 140, false); } /** @@ -655,15 +700,14 @@ void MouseActions::MMoveMirrorX(Schematic *Doc, QMouseEvent *Event) */ void MouseActions::MMoveRotate(Schematic *Doc, QMouseEvent *Event) { - MAx3 = DOC_X_POS(Event->pos().x()); - MAy3 = DOC_Y_POS(Event->pos().y()); + MAx3 = DOC_X_POS(Event->pos().x()); + MAy3 = DOC_Y_POS(Event->pos().y()); - Doc->PostPaintEvent (_Line, MAx3-6, MAy3+8, MAx3-6, MAy3+1); - Doc->PostPaintEvent (_Line, MAx3-7, MAy3+8, MAx3-12, MAy3+8); - Doc->PostPaintEvent (_Arc, MAx3-10, MAy3-10, 21, 21, -16*20, 16*240,false); + Doc->PostPaintEvent(_Line, MAx3 - 6, MAy3 + 8, MAx3 - 6, MAy3 + 1); + Doc->PostPaintEvent(_Line, MAx3 - 7, MAy3 + 8, MAx3 - 12, MAy3 + 8); + Doc->PostPaintEvent(_Arc, MAx3 - 10, MAy3 - 10, 21, 21, -16 * 20, 16 * 240, false); } - /** * @brief MouseActions::MMoveActivate Paints a crossed box mouse cursor to "(de)activate" components. * @param Doc @@ -671,15 +715,14 @@ void MouseActions::MMoveRotate(Schematic *Doc, QMouseEvent *Event) */ void MouseActions::MMoveActivate(Schematic *Doc, QMouseEvent *Event) { - MAx3 = DOC_X_POS(Event->pos().x()); - MAy3 = DOC_Y_POS(Event->pos().y()); + MAx3 = DOC_X_POS(Event->pos().x()); + MAy3 = DOC_Y_POS(Event->pos().y()); - Doc->PostPaintEvent (_Rect, MAx3, MAy3 - 9, 14, 10); - Doc->PostPaintEvent (_Line, MAx3, MAy3-9, MAx3+13, MAy3); - Doc->PostPaintEvent (_Line, MAx3, MAy3, MAx3+13, MAy3-9); + Doc->PostPaintEvent(_Rect, MAx3, MAy3 - 9, 14, 10); + Doc->PostPaintEvent(_Line, MAx3, MAy3 - 9, MAx3 + 13, MAy3); + Doc->PostPaintEvent(_Line, MAx3, MAy3, MAx3 + 13, MAy3 - 9); } - /** * @brief MouseActions::MMoveOnGrid Paints a grid beside the mouse cursor, put "on grid" mode. * @param Doc @@ -687,18 +730,17 @@ void MouseActions::MMoveActivate(Schematic *Doc, QMouseEvent *Event) */ void MouseActions::MMoveOnGrid(Schematic *Doc, QMouseEvent *Event) { - MAx3 = DOC_X_POS(Event->pos().x()); - MAy3 = DOC_Y_POS(Event->pos().y()); - - Doc->PostPaintEvent (_Line, MAx3+10, MAy3+ 3, MAx3+25, MAy3+3); - Doc->PostPaintEvent (_Line, MAx3+10, MAy3+ 7, MAx3+25, MAy3+7); - Doc->PostPaintEvent (_Line, MAx3+10, MAy3+11, MAx3+25, MAy3+11); - Doc->PostPaintEvent (_Line, MAx3+13, MAy3, MAx3+13, MAy3+15); - Doc->PostPaintEvent (_Line, MAx3+17, MAy3, MAx3+17, MAy3+15); - Doc->PostPaintEvent (_Line, MAx3+21, MAy3, MAx3+21, MAy3+15); + MAx3 = DOC_X_POS(Event->pos().x()); + MAy3 = DOC_Y_POS(Event->pos().y()); + + Doc->PostPaintEvent(_Line, MAx3 + 10, MAy3 + 3, MAx3 + 25, MAy3 + 3); + Doc->PostPaintEvent(_Line, MAx3 + 10, MAy3 + 7, MAx3 + 25, MAy3 + 7); + Doc->PostPaintEvent(_Line, MAx3 + 10, MAy3 + 11, MAx3 + 25, MAy3 + 11); + Doc->PostPaintEvent(_Line, MAx3 + 13, MAy3, MAx3 + 13, MAy3 + 15); + Doc->PostPaintEvent(_Line, MAx3 + 17, MAy3, MAx3 + 17, MAy3 + 15); + Doc->PostPaintEvent(_Line, MAx3 + 21, MAy3, MAx3 + 21, MAy3 + 15); } - /** * @brief MouseActions::MMoveMoveTextB Paints mouse symbol for "move component text" mode. * @param Doc @@ -706,20 +748,19 @@ void MouseActions::MMoveOnGrid(Schematic *Doc, QMouseEvent *Event) */ void MouseActions::MMoveMoveTextB(Schematic *Doc, QMouseEvent *Event) { - MAx3 = DOC_X_POS(Event->pos().x()); - MAy3 = DOC_Y_POS(Event->pos().y()); - - Doc->PostPaintEvent (_Line, MAx3+14, MAy3 , MAx3+16, MAy3); - Doc->PostPaintEvent (_Line, MAx3+23, MAy3 , MAx3+25, MAy3); - Doc->PostPaintEvent (_Line, MAx3+13, MAy3 , MAx3+13, MAy3+ 3); - Doc->PostPaintEvent (_Line, MAx3+13, MAy3+ 7, MAx3+13, MAy3+10); - Doc->PostPaintEvent (_Line, MAx3+14, MAy3+10, MAx3+16, MAy3+10); - Doc->PostPaintEvent (_Line, MAx3+23, MAy3+10, MAx3+25, MAy3+10); - Doc->PostPaintEvent (_Line, MAx3+26, MAy3 , MAx3+26, MAy3+ 3); - Doc->PostPaintEvent (_Line, MAx3+26, MAy3+ 7, MAx3+26, MAy3+10); + MAx3 = DOC_X_POS(Event->pos().x()); + MAy3 = DOC_Y_POS(Event->pos().y()); + + Doc->PostPaintEvent(_Line, MAx3 + 14, MAy3, MAx3 + 16, MAy3); + Doc->PostPaintEvent(_Line, MAx3 + 23, MAy3, MAx3 + 25, MAy3); + Doc->PostPaintEvent(_Line, MAx3 + 13, MAy3, MAx3 + 13, MAy3 + 3); + Doc->PostPaintEvent(_Line, MAx3 + 13, MAy3 + 7, MAx3 + 13, MAy3 + 10); + Doc->PostPaintEvent(_Line, MAx3 + 14, MAy3 + 10, MAx3 + 16, MAy3 + 10); + Doc->PostPaintEvent(_Line, MAx3 + 23, MAy3 + 10, MAx3 + 25, MAy3 + 10); + Doc->PostPaintEvent(_Line, MAx3 + 26, MAy3, MAx3 + 26, MAy3 + 3); + Doc->PostPaintEvent(_Line, MAx3 + 26, MAy3 + 7, MAx3 + 26, MAy3 + 10); } - /** * @brief MouseActions::MMoveMoveText Paint rectangle around component text being mouse moved * @param Doc @@ -727,17 +768,16 @@ void MouseActions::MMoveMoveTextB(Schematic *Doc, QMouseEvent *Event) */ void MouseActions::MMoveMoveText(Schematic *Doc, QMouseEvent *Event) { - int newX = DOC_X_POS(Event->pos().x()); - int newY = DOC_Y_POS(Event->pos().y()); - MAx1 += newX - MAx3; - MAy1 += newY - MAy3; - MAx3 = newX; - MAy3 = newY; - - Doc->PostPaintEvent (_Rect, MAx1, MAy1, MAx2, MAy2); + int newX = DOC_X_POS(Event->pos().x()); + int newY = DOC_Y_POS(Event->pos().y()); + MAx1 += newX - MAx3; + MAy1 += newY - MAy3; + MAx3 = newX; + MAy3 = newY; + + Doc->PostPaintEvent(_Rect, MAx1, MAy1, MAx2, MAy2); } - /** * @brief MouseActions::MMoveZoomIn Paints symbol beside the mouse to show the "Zoom in" modus. * @param Doc @@ -745,16 +785,15 @@ void MouseActions::MMoveMoveText(Schematic *Doc, QMouseEvent *Event) */ void MouseActions::MMoveZoomIn(Schematic *Doc, QMouseEvent *Event) { - MAx3 = DOC_X_POS(Event->pos().x()); - MAy3 = DOC_Y_POS(Event->pos().y()); + MAx3 = DOC_X_POS(Event->pos().x()); + MAy3 = DOC_Y_POS(Event->pos().y()); - Doc->PostPaintEvent (_Line, MAx3+14, MAy3 , MAx3+22, MAy3); - Doc->PostPaintEvent (_Line, MAx3+18, MAy3-4 , MAx3+18, MAy3+4); - Doc->PostPaintEvent (_Ellipse, MAx3+12, MAy3-6, 13, 13,0,0,false); - Doc->viewport()->update(); + Doc->PostPaintEvent(_Line, MAx3 + 14, MAy3, MAx3 + 22, MAy3); + Doc->PostPaintEvent(_Line, MAx3 + 18, MAy3 - 4, MAx3 + 18, MAy3 + 4); + Doc->PostPaintEvent(_Ellipse, MAx3 + 12, MAy3 - 6, 13, 13, 0, 0, false); + Doc->viewport()->update(); } - // ************************************************************************ // ********** ********** // ********** Functions for serving mouse button clicking ********** @@ -764,56 +803,59 @@ void MouseActions::MMoveZoomIn(Schematic *Doc, QMouseEvent *Event) // Is called from several MousePress functions to show right button menu. void MouseActions::rightPressMenu(Schematic *Doc, QMouseEvent *Event, float fX, float fY) { - MAx1 = int(fX); - MAy1 = int(fY); - focusElement = Doc->selectElement(fX, fY, false); - - if(focusElement) // remove special function (4 least significant bits) - focusElement->Type &= isSpecialMask; + MAx1 = int(fX); + MAy1 = int(fY); + focusElement = Doc->selectElement(fX, fY, false); + if (focusElement) // remove special function (4 least significant bits) + focusElement->Type &= isSpecialMask; - // define menu - ComponentMenu->clear(); - while(true) { - if(focusElement) { - focusElement->isSelected = true; - QAction *editProp = new QAction(QObject::tr("Edit Properties"), QucsMain); - QObject::connect(editProp,SIGNAL(triggered(bool)),QucsMain,SLOT(slotEditElement())); - ComponentMenu->addAction(editProp); + // define menu + ComponentMenu->clear(); + while (true) { + if (focusElement) { + focusElement->isSelected = true; + QAction *editProp = new QAction(QObject::tr("Edit Properties"), QucsMain); + QObject::connect(editProp, SIGNAL(triggered(bool)), QucsMain, SLOT(slotEditElement())); + ComponentMenu->addAction(editProp); - if((focusElement->Type & isComponent) == 0) break; + if ((focusElement->Type & isComponent) == 0) + break; + } else { + /// \todo "exchange like this" + //ComponentMenu->addAction(QucsMain->symEdit); + //to QucsMain->symEdit->addTo(ComponentMenu); + // see http://qt-project.org/doc/qt-4.8/qaction-qt3.html#addTo + ComponentMenu->addAction(QucsMain->symEdit); + ComponentMenu->addAction(QucsMain->fileSettings); + } + if (!QucsMain->moveText->isChecked()) + ComponentMenu->addAction(QucsMain->moveText); + break; } - else { -/// \todo "exchange like this" - //ComponentMenu->addAction(QucsMain->symEdit); - //to QucsMain->symEdit->addTo(ComponentMenu); - // see http://qt-project.org/doc/qt-4.8/qaction-qt3.html#addTo - ComponentMenu->addAction(QucsMain->symEdit); - ComponentMenu->addAction(QucsMain->fileSettings); + while (true) { + if (focusElement) + if (focusElement->Type == isGraph) + break; + if (!QucsMain->onGrid->isChecked()) + ComponentMenu->addAction(QucsMain->onGrid); + ComponentMenu->addAction(QucsMain->editCopy); + if (!QucsMain->editPaste->isChecked()) + ComponentMenu->addAction(QucsMain->editPaste); + break; } - if(!QucsMain->moveText->isChecked()) - ComponentMenu->addAction(QucsMain->moveText); - break; - } - while(true) { - if(focusElement) - if(focusElement->Type == isGraph) break; - if(!QucsMain->onGrid->isChecked()) - ComponentMenu->addAction(QucsMain->onGrid); - ComponentMenu->addAction(QucsMain->editCopy); - if(!QucsMain->editPaste->isChecked()) - ComponentMenu->addAction(QucsMain->editPaste); - break; - } - - while (true) { - if (focusElement) { - if (focusElement->Type == isDiagram) { - QAction *actExport = new QAction(QObject::tr("Export as image"), QucsMain); - QObject::connect(actExport,SIGNAL(triggered(bool)),QucsMain,SLOT(slotSaveDiagramToGraphicsFile())); - ComponentMenu->addAction(actExport); - } - /*if (focusElement->Type & isComponent) { + + while (true) { + if (focusElement) { + if (focusElement->Type == isDiagram) { + QAction *actExport = new QAction(QObject::tr("Export as image"), QucsMain); + QObject::connect(actExport, + SIGNAL(triggered(bool)), + QucsMain, + SLOT(slotSaveDiagramToGraphicsFile())); + ComponentMenu->addAction(actExport); + } + /*if (focusElement->Type & isComponent) { Component *pc = (Component *)focusElement; if (pc->Model == "EDD") { QAction *actEDDtoIFS = new QAction(QObject::tr("Create XSPICE IFS"), QucsMain); @@ -824,500 +866,518 @@ void MouseActions::rightPressMenu(Schematic *Doc, QMouseEvent *Event, float fX, ComponentMenu->addAction(actEDDtoMOD); } }*/ - } - break; - } - - if(!QucsMain->editDelete->isChecked()) - ComponentMenu->addAction(QucsMain->editDelete); - if(focusElement) if(focusElement->Type == isMarker) { - ComponentMenu->addSeparator(); - QString s = QObject::tr("power matching"); - if( ((Marker*)focusElement)->pGraph->Var == "Sopt" ) - s = QObject::tr("noise matching"); - QAction *actPwrMatching = new QAction(s, QucsMain); - QObject::connect(actPwrMatching,SIGNAL(triggered(bool)),QucsMain,SLOT(slotPowerMatching())); - ComponentMenu->addAction(actPwrMatching); - if( ((Marker*)focusElement)->pGraph->Var.left(2) == "S[" ) { - QAction *act2PortMatching = new QAction(QObject::tr("2-port matching"), QucsMain); - QObject::connect(act2PortMatching,SIGNAL(triggered(bool)),QucsMain,SLOT(slot2PortMatching())); - ComponentMenu->addAction(act2PortMatching); - } - } - do { - if(focusElement) { - if(focusElement->Type == isDiagram) break; - if(focusElement->Type == isGraph) { - ComponentMenu->addAction(QucsMain->graph2csv); + } break; - } - } - ComponentMenu->addSeparator(); - if(focusElement) if(focusElement->Type & isComponent) - if(!QucsMain->editActivate->isChecked()) - ComponentMenu->addAction(QucsMain->editActivate); - if(!QucsMain->editRotate->isChecked()) - ComponentMenu->addAction(QucsMain->editRotate); - if(!QucsMain->editMirror->isChecked()) - ComponentMenu->addAction(QucsMain->editMirror); - if(!QucsMain->editMirrorY->isChecked()) - ComponentMenu->addAction(QucsMain->editMirrorY); - - // right-click menu to go into hierarchy - if(focusElement) { - if(focusElement->Type & isComponent) - if(((Component*)focusElement)->Model == "Sub") - if(!QucsMain->intoH->isChecked()) - ComponentMenu->addAction(QucsMain->intoH); } - // right-click menu to pop out of hierarchy - if(!focusElement) - if(!QucsMain->popH->isChecked()) - ComponentMenu->addAction(QucsMain->popH); - } while(false); - //*focusMEvent = *Event; // remember event for "edit component" action + if (!QucsMain->editDelete->isChecked()) + ComponentMenu->addAction(QucsMain->editDelete); + if (focusElement) + if (focusElement->Type == isMarker) { + ComponentMenu->addSeparator(); + QString s = QObject::tr("power matching"); + if (((Marker *) focusElement)->pGraph->Var == "Sopt") + s = QObject::tr("noise matching"); + QAction *actPwrMatching = new QAction(s, QucsMain); + QObject::connect(actPwrMatching, + SIGNAL(triggered(bool)), + QucsMain, + SLOT(slotPowerMatching())); + ComponentMenu->addAction(actPwrMatching); + if (((Marker *) focusElement)->pGraph->Var.left(2) == "S[") { + QAction *act2PortMatching = new QAction(QObject::tr("2-port matching"), QucsMain); + QObject::connect(act2PortMatching, + SIGNAL(triggered(bool)), + QucsMain, + SLOT(slot2PortMatching())); + ComponentMenu->addAction(act2PortMatching); + } + } + do { + if (focusElement) { + if (focusElement->Type == isDiagram) + break; + if (focusElement->Type == isGraph) { + ComponentMenu->addAction(QucsMain->graph2csv); + break; + } + } + ComponentMenu->addSeparator(); + if (focusElement) + if (focusElement->Type & isComponent) + if (!QucsMain->editActivate->isChecked()) + ComponentMenu->addAction(QucsMain->editActivate); + if (!QucsMain->editRotate->isChecked()) + ComponentMenu->addAction(QucsMain->editRotate); + if (!QucsMain->editMirror->isChecked()) + ComponentMenu->addAction(QucsMain->editMirror); + if (!QucsMain->editMirrorY->isChecked()) + ComponentMenu->addAction(QucsMain->editMirrorY); + + // right-click menu to go into hierarchy + if (focusElement) { + if (focusElement->Type & isComponent) + if (((Component *) focusElement)->Model == "Sub") + if (!QucsMain->intoH->isChecked()) + ComponentMenu->addAction(QucsMain->intoH); + } + // right-click menu to pop out of hierarchy + if (!focusElement) + if (!QucsMain->popH->isChecked()) + ComponentMenu->addAction(QucsMain->popH); + } while (false); + + //*focusMEvent = *Event; // remember event for "edit component" action #if QT_VERSION >= 0x060000 - ComponentMenu->popup(Event->globalPosition().toPoint()); + ComponentMenu->popup(Event->globalPosition().toPoint()); #else - ComponentMenu->popup(Event->globalPos()); + ComponentMenu->popup(Event->globalPos()); #endif - Doc->viewport()->update(); - drawn = false; + Doc->viewport()->update(); + drawn = false; } // ----------------------------------------------------------- -void MouseActions::MPressLabel(Schematic *Doc, QMouseEvent*, float fX, float fY) +void MouseActions::MPressLabel(Schematic *Doc, QMouseEvent *, float fX, float fY) { - int x = int(fX), y = int(fY); - Wire *pw = 0; - WireLabel *pl=0; - Node *pn = Doc->selectedNode(x, y); - if(!pn) { - pw = Doc->selectedWire(x, y); - if(!pw) return; - } - - QString Name, Value; - Element *pe=0; - // is wire line already labeled ? - if(pw) pe = Doc->getWireLabel(pw->Port1); - else pe = Doc->getWireLabel(pn); - if(pe) { - if(pe->Type & isComponent) { - QMessageBox::information(0, QObject::tr("Info"), - QObject::tr("The ground potential cannot be labeled!")); - return; + int x = int(fX), y = int(fY); + Wire *pw = 0; + WireLabel *pl = 0; + Node *pn = Doc->selectedNode(x, y); + if (!pn) { + pw = Doc->selectedWire(x, y); + if (!pw) + return; } - pl = ((Conductor*)pe)->Label; - } - LabelDialog *Dia = new LabelDialog(pl, Doc); - if(Dia->exec() == 0) return; + QString Name, Value; + Element *pe = 0; + // is wire line already labeled ? + if (pw) + pe = Doc->getWireLabel(pw->Port1); + else + pe = Doc->getWireLabel(pn); + if (pe) { + if (pe->Type & isComponent) { + QMessageBox::information(0, + QObject::tr("Info"), + QObject::tr("The ground potential cannot be labeled!")); + return; + } + pl = ((Conductor *) pe)->Label; + } - Name = Dia->NodeName->text(); - Value = Dia->InitValue->text(); - delete Dia; + LabelDialog *Dia = new LabelDialog(pl, Doc); + if (Dia->exec() == 0) + return; - if(Name.isEmpty() && Value.isEmpty() ) { // if nothing entered, delete name - if(pe) { - if(((Conductor*)pe)->Label) - delete ((Conductor*)pe)->Label; // delete old name - ((Conductor*)pe)->Label = 0; - } - else { - if(pw) pw->setName("", ""); // delete name of wire - else pn->setName("", ""); - } - } - else { -/* Name.replace(' ', '_'); // label must not contain spaces + Name = Dia->NodeName->text(); + Value = Dia->InitValue->text(); + delete Dia; + + if (Name.isEmpty() && Value.isEmpty()) { // if nothing entered, delete name + if (pe) { + if (((Conductor *) pe)->Label) + delete ((Conductor *) pe)->Label; // delete old name + ((Conductor *) pe)->Label = 0; + } else { + if (pw) + pw->setName("", ""); // delete name of wire + else + pn->setName("", ""); + } + } else { + /* Name.replace(' ', '_'); // label must not contain spaces while(Name.at(0) == '_') Name.remove(0,1); // must not start with '_' if(Name.isEmpty()) return; */ - if(pe) { - delete ((Conductor*)pe)->Label; // delete old name - ((Conductor*)pe)->Label = nullptr; + if (pe) { + delete ((Conductor *) pe)->Label; // delete old name + ((Conductor *) pe)->Label = nullptr; + } + + int xl = x + 30; + int yl = y - 30; + Doc->setOnGrid(xl, yl); + // set new name + if (pw) + pw->setName(Name, Value, x - pw->x1 + y - pw->y1, xl, yl); + else + pn->setName(Name, Value, xl, yl); } - int xl = x+30; - int yl = y-30; - Doc->setOnGrid(xl, yl); - // set new name - if(pw) pw->setName(Name, Value, x-pw->x1 + y-pw->y1, xl, yl); - else pn->setName(Name, Value, xl, yl); - } - - Doc->sizeOfAll(Doc->UsedX1, Doc->UsedY1, Doc->UsedX2, Doc->UsedY2); - Doc->viewport()->update(); - drawn = false; - Doc->setChanged(true, true); + Doc->sizeOfAll(Doc->UsedX1, Doc->UsedY1, Doc->UsedX2, Doc->UsedY2); + Doc->viewport()->update(); + drawn = false; + Doc->setChanged(true, true); } // ----------------------------------------------------------- void MouseActions::MPressSelect(Schematic *Doc, QMouseEvent *Event, float fX, float fY) { - bool Ctrl; - if(Event->modifiers().testFlag(Qt::ControlModifier)) Ctrl = true; - else Ctrl = false; - - int No=0; - MAx1 = int(fX); - MAy1 = int(fY); - focusElement = Doc->selectElement(fX, fY, Ctrl, &No); - isMoveEqual = false; // moving not necessarily square - - if(focusElement) - // print define value in hex, see element.h - qDebug() << "MPressSelect: focusElement->Type" << QString("0x%1").arg(focusElement->Type, 0, 16); - else - qDebug() << "MPressSelect"; - - if(focusElement) - switch(focusElement->Type) - { - case isPaintingResize: // resize painting ? - focusElement->Type = isPainting; - QucsMain->MouseReleaseAction = &MouseActions::MReleaseResizePainting; - QucsMain->MouseMoveAction = &MouseActions::MMoveResizePainting; - QucsMain->MousePressAction = 0; - QucsMain->MouseDoubleClickAction = 0; - Doc->grabKeyboard(); // no keyboard inputs during move actions - // Update matching wire label highlighting - Doc->highlightWireLabels (); - return; - - case isDiagramResize: // resize diagram ? - if(((Diagram*)focusElement)->Name.left(4) != "Rect") - if(((Diagram*)focusElement)->Name.at(0) != 'T') - if(((Diagram*)focusElement)->Name != "Curve") - isMoveEqual = true; // diagram must be square - - focusElement->Type = isDiagram; - MAx1 = focusElement->cx; - MAx2 = focusElement->x2; - if(((Diagram*)focusElement)->State & 1) { - MAx1 += MAx2; - MAx2 *= -1; - } - MAy1 = focusElement->cy; - MAy2 = -focusElement->y2; - if(((Diagram*)focusElement)->State & 2) { - MAy1 += MAy2; - MAy2 *= -1; - } - - QucsMain->MouseReleaseAction = &MouseActions::MReleaseResizeDiagram; - QucsMain->MouseMoveAction = &MouseActions::MMoveSelect; - QucsMain->MousePressAction = 0; - QucsMain->MouseDoubleClickAction = 0; - Doc->grabKeyboard(); // no keyboard inputs during move actions - // Update matching wire label highlighting - Doc->highlightWireLabels (); - return; - - case isDiagramHScroll: // scroll in tabular ? - MAy1 = MAx1; - - case isDiagramVScroll: - focusElement->Type = isDiagram; - - No = ((TabDiagram*)focusElement)->scroll(MAy1); - - switch(No) - { - case 1: - Doc->setChanged(true, true, 'm'); // 'm' = only the first time - break; - case 2: // move scroll bar with mouse cursor - QucsMain->MouseMoveAction = &MouseActions::MMoveScrollBar; - QucsMain->MousePressAction = 0; - QucsMain->MouseDoubleClickAction = 0; - Doc->grabKeyboard(); // no keyboard inputs during move actions - - // Remember initial scroll bar position. - MAx2 = int(((TabDiagram*)focusElement)->xAxis.limit_min); - // Update matching wire label highlighting - Doc->highlightWireLabels (); - return; - } - // Update matching wire label highlighting - Doc->highlightWireLabels (); - Doc->viewport()->update(); - drawn = false; - return; - - case isComponentText: // property text of component ? - focusElement->Type &= (~isComponentText) | isComponent; - - MAx3 = No; - QucsMain->slotApplyCompText(); - // Update matching wire label highlighting - Doc->highlightWireLabels (); - return; - - case isNode: - if (QucsSettings.NodeWiring) - { - MAx1 = 0; // paint wire corner first up, then left/right - MAx3 = focusElement->cx; // works even if node is not on grid - MAy3 = focusElement->cy; - QucsMain->MouseMoveAction = &MouseActions::MMoveWire2; - QucsMain->MousePressAction = &MouseActions::MPressWire2; - QucsMain->MouseReleaseAction = 0; // if function is called from elsewhere - QucsMain->MouseDoubleClickAction = 0; + bool Ctrl; + if (Event->modifiers().testFlag(Qt::ControlModifier)) + Ctrl = true; + else + Ctrl = false; - formerAction = QucsMain->select; // to restore action afterwards - QucsMain->activeAction = QucsMain->insWire; + int No = 0; + MAx1 = int(fX); + MAy1 = int(fY); + focusElement = Doc->selectElement(fX, fY, Ctrl, &No); + isMoveEqual = false; // moving not necessarily square - QucsMain->select->blockSignals(true); - QucsMain->select->setChecked(false); - QucsMain->select->blockSignals(false); + if (focusElement) + // print define value in hex, see element.h + qDebug() << "MPressSelect: focusElement->Type" + << QString("0x%1").arg(focusElement->Type, 0, 16); + else + qDebug() << "MPressSelect"; + + if (focusElement) + switch (focusElement->Type) { + case isPaintingResize: // resize painting ? + focusElement->Type = isPainting; + QucsMain->MouseReleaseAction = &MouseActions::MReleaseResizePainting; + QucsMain->MouseMoveAction = &MouseActions::MMoveResizePainting; + QucsMain->MousePressAction = 0; + QucsMain->MouseDoubleClickAction = 0; + Doc->grabKeyboard(); // no keyboard inputs during move actions + // Update matching wire label highlighting + Doc->highlightWireLabels(); + return; - QucsMain->insWire->blockSignals(true); - QucsMain->insWire->setChecked(true); - QucsMain->insWire->blockSignals(false); - // Update matching wire label highlighting - Doc->highlightWireLabels (); - return; - } - } + case isDiagramResize: // resize diagram ? + if (((Diagram *) focusElement)->Name.left(4) != "Rect") + if (((Diagram *) focusElement)->Name.at(0) != 'T') + if (((Diagram *) focusElement)->Name != "Curve") + isMoveEqual = true; // diagram must be square + + focusElement->Type = isDiagram; + MAx1 = focusElement->cx; + MAx2 = focusElement->x2; + if (((Diagram *) focusElement)->State & 1) { + MAx1 += MAx2; + MAx2 *= -1; + } + MAy1 = focusElement->cy; + MAy2 = -focusElement->y2; + if (((Diagram *) focusElement)->State & 2) { + MAy1 += MAy2; + MAy2 *= -1; + } - QucsMain->MousePressAction = 0; - QucsMain->MouseDoubleClickAction = 0; - Doc->grabKeyboard(); // no keyboard inputs during move actions - Doc->viewport()->update(); - drawn = false; + QucsMain->MouseReleaseAction = &MouseActions::MReleaseResizeDiagram; + QucsMain->MouseMoveAction = &MouseActions::MMoveSelect; + QucsMain->MousePressAction = 0; + QucsMain->MouseDoubleClickAction = 0; + Doc->grabKeyboard(); // no keyboard inputs during move actions + // Update matching wire label highlighting + Doc->highlightWireLabels(); + return; - if(focusElement == 0) { - MAx2 = 0; // if not clicking on an element => open a rectangle - MAy2 = 0; - QucsMain->MouseReleaseAction = &MouseActions::MReleaseSelect2; - QucsMain->MouseMoveAction = &MouseActions::MMoveSelect; - } - else - { - // element could be moved - if(!Ctrl) - { - if(!focusElement->isSelected)// Don't move selected elements if clicked - Doc->deselectElements(focusElement); // element was not selected. - focusElement->isSelected = true; - } - Doc->setOnGrid(MAx1, MAy1); - QucsMain->MouseMoveAction = &MouseActions::MMoveMoving; - } - // Update matching wire label highlighting - Doc->highlightWireLabels (); -} + case isDiagramHScroll: // scroll in tabular ? + MAy1 = MAx1; -// ----------------------------------------------------------- -void MouseActions::MPressDelete(Schematic *Doc, QMouseEvent*, float fX, float fY) -{ - Element *pe = Doc->selectElement(fX, fY, false); - if(pe) - { - pe->isSelected = true; - Doc->deleteElements(); + case isDiagramVScroll: + focusElement->Type = isDiagram; - Doc->sizeOfAll(Doc->UsedX1, Doc->UsedY1, Doc->UsedX2, Doc->UsedY2); + No = ((TabDiagram *) focusElement)->scroll(MAy1); + + switch (No) { + case 1: + Doc->setChanged(true, true, 'm'); // 'm' = only the first time + break; + case 2: // move scroll bar with mouse cursor + QucsMain->MouseMoveAction = &MouseActions::MMoveScrollBar; + QucsMain->MousePressAction = 0; + QucsMain->MouseDoubleClickAction = 0; + Doc->grabKeyboard(); // no keyboard inputs during move actions + + // Remember initial scroll bar position. + MAx2 = int(((TabDiagram *) focusElement)->xAxis.limit_min); + // Update matching wire label highlighting + Doc->highlightWireLabels(); + return; + } + // Update matching wire label highlighting + Doc->highlightWireLabels(); + Doc->viewport()->update(); + drawn = false; + return; + + case isComponentText: // property text of component ? + focusElement->Type &= (~isComponentText) | isComponent; + + MAx3 = No; + QucsMain->slotApplyCompText(); + // Update matching wire label highlighting + Doc->highlightWireLabels(); + return; + + case isNode: + if (QucsSettings.NodeWiring) { + MAx1 = 0; // paint wire corner first up, then left/right + MAx3 = focusElement->cx; // works even if node is not on grid + MAy3 = focusElement->cy; + QucsMain->MouseMoveAction = &MouseActions::MMoveWire2; + QucsMain->MousePressAction = &MouseActions::MPressWire2; + QucsMain->MouseReleaseAction = 0; // if function is called from elsewhere + QucsMain->MouseDoubleClickAction = 0; + + formerAction = QucsMain->select; // to restore action afterwards + QucsMain->activeAction = QucsMain->insWire; + + QucsMain->select->blockSignals(true); + QucsMain->select->setChecked(false); + QucsMain->select->blockSignals(false); + + QucsMain->insWire->blockSignals(true); + QucsMain->insWire->setChecked(true); + QucsMain->insWire->blockSignals(false); + // Update matching wire label highlighting + Doc->highlightWireLabels(); + return; + } + } + + QucsMain->MousePressAction = 0; + QucsMain->MouseDoubleClickAction = 0; + Doc->grabKeyboard(); // no keyboard inputs during move actions Doc->viewport()->update(); drawn = false; - } + + if (focusElement == 0) { + MAx2 = 0; // if not clicking on an element => open a rectangle + MAy2 = 0; + QucsMain->MouseReleaseAction = &MouseActions::MReleaseSelect2; + QucsMain->MouseMoveAction = &MouseActions::MMoveSelect; + } else { + // element could be moved + if (!Ctrl) { + if (!focusElement->isSelected) // Don't move selected elements if clicked + Doc->deselectElements(focusElement); // element was not selected. + focusElement->isSelected = true; + } + Doc->setOnGrid(MAx1, MAy1); + QucsMain->MouseMoveAction = &MouseActions::MMoveMoving; + } + // Update matching wire label highlighting + Doc->highlightWireLabels(); } // ----------------------------------------------------------- -void MouseActions::MPressActivate(Schematic *Doc, QMouseEvent*, float fX, float fY) +void MouseActions::MPressDelete(Schematic *Doc, QMouseEvent *, float fX, float fY) { - MAx1 = int(fX); - MAy1 = int(fY); - if(!Doc->activateSpecifiedComponent(MAx1, MAy1)) { -// if(Event->button() != Qt::LeftButton) return; - MAx2 = 0; // if not clicking on a component => open a rectangle - MAy2 = 0; - QucsMain->MousePressAction = 0; - QucsMain->MouseReleaseAction = &MouseActions::MReleaseActivate; - QucsMain->MouseMoveAction = &MouseActions::MMoveSelect; - } - Doc->viewport()->update(); - drawn = false; + Element *pe = Doc->selectElement(fX, fY, false); + if (pe) { + pe->isSelected = true; + Doc->deleteElements(); + + Doc->sizeOfAll(Doc->UsedX1, Doc->UsedY1, Doc->UsedX2, Doc->UsedY2); + Doc->viewport()->update(); + drawn = false; + } } // ----------------------------------------------------------- -void MouseActions::MPressMirrorX(Schematic *Doc, QMouseEvent*, float fX, float fY) +void MouseActions::MPressActivate(Schematic *Doc, QMouseEvent *, float fX, float fY) { - // no use in mirroring wires or diagrams - Component *c = Doc->selectedComponent(int(fX), int(fY)); - if(c) { - if(c->Ports.count() < 1) return; // only mirror components with ports - c->mirrorX(); - Doc->setCompPorts(c); - } - else { - Painting *p = Doc->selectedPainting(fX, fY); - if(p == 0) return; - p->mirrorX(); - } - - Doc->viewport()->update(); - drawn = false; - Doc->setChanged(true, true); + MAx1 = int(fX); + MAy1 = int(fY); + if (!Doc->activateSpecifiedComponent(MAx1, MAy1)) { + // if(Event->button() != Qt::LeftButton) return; + MAx2 = 0; // if not clicking on a component => open a rectangle + MAy2 = 0; + QucsMain->MousePressAction = 0; + QucsMain->MouseReleaseAction = &MouseActions::MReleaseActivate; + QucsMain->MouseMoveAction = &MouseActions::MMoveSelect; + } + Doc->viewport()->update(); + drawn = false; } // ----------------------------------------------------------- -void MouseActions::MPressMirrorY(Schematic *Doc, QMouseEvent*, float fX, float fY) +void MouseActions::MPressMirrorX(Schematic *Doc, QMouseEvent *, float fX, float fY) { - // no use in mirroring wires or diagrams - Component *c = Doc->selectedComponent(int(fX), int(fY)); - if(c) { - if(c->Ports.count() < 1) return; // only mirror components with ports - c->mirrorY(); - Doc->setCompPorts(c); - } - else { - Painting *p = Doc->selectedPainting(fX, fY); - if(p == 0) return; - p->mirrorY(); - } - - Doc->viewport()->update(); - drawn = false; - Doc->setChanged(true, true); + // no use in mirroring wires or diagrams + Component *c = Doc->selectedComponent(int(fX), int(fY)); + if (c) { + if (c->Ports.count() < 1) + return; // only mirror components with ports + c->mirrorX(); + Doc->setCompPorts(c); + } else { + Painting *p = Doc->selectedPainting(fX, fY); + if (p == 0) + return; + p->mirrorX(); + } + + Doc->viewport()->update(); + drawn = false; + Doc->setChanged(true, true); } // ----------------------------------------------------------- -void MouseActions::MPressRotate(Schematic *Doc, QMouseEvent*, float fX, float fY) +void MouseActions::MPressMirrorY(Schematic *Doc, QMouseEvent *, float fX, float fY) { - Element *e = Doc->selectElement(int(fX), int(fY), false); - if(e == 0) return; - e->Type &= isSpecialMask; // remove special functions + // no use in mirroring wires or diagrams + Component *c = Doc->selectedComponent(int(fX), int(fY)); + if (c) { + if (c->Ports.count() < 1) + return; // only mirror components with ports + c->mirrorY(); + Doc->setCompPorts(c); + } else { + Painting *p = Doc->selectedPainting(fX, fY); + if (p == 0) + return; + p->mirrorY(); + } + Doc->viewport()->update(); + drawn = false; + Doc->setChanged(true, true); +} + +// ----------------------------------------------------------- +void MouseActions::MPressRotate(Schematic *Doc, QMouseEvent *, float fX, float fY) +{ + Element *e = Doc->selectElement(int(fX), int(fY), false); + if (e == 0) + return; + e->Type &= isSpecialMask; // remove special functions - WireLabel *pl; - int x1, y1, x2, y2; -// e->isSelected = false; - switch(e->Type) { + WireLabel *pl; + int x1, y1, x2, y2; + // e->isSelected = false; + switch (e->Type) { case isComponent: case isAnalogComponent: case isDigitalComponent: - if(((Component*)e)->Ports.count() < 1) - break; // do not rotate components without ports - ((Component*)e)->rotate(); - Doc->setCompPorts((Component*)e); - // enlarge viewarea if component lies outside the view - ((Component*)e)->entireBounds(x1,y1,x2,y2, Doc->textCorr()); - Doc->enlargeView(x1, y1, x2, y2); - break; + if (((Component *) e)->Ports.count() < 1) + break; // do not rotate components without ports + ((Component *) e)->rotate(); + Doc->setCompPorts((Component *) e); + // enlarge viewarea if component lies outside the view + ((Component *) e)->entireBounds(x1, y1, x2, y2, Doc->textCorr()); + Doc->enlargeView(x1, y1, x2, y2); + break; case isWire: - pl = ((Wire*)e)->Label; - ((Wire*)e)->Label = 0; // prevent label to be deleted - Doc->Wires->setAutoDelete(false); - Doc->deleteWire((Wire*)e); - ((Wire*)e)->Label = pl; - ((Wire*)e)->rotate(); - Doc->setOnGrid(e->x1, e->y1); - Doc->setOnGrid(e->x2, e->y2); - if(pl) Doc->setOnGrid(pl->cx, pl->cy); - Doc->insertWire((Wire*)e); - Doc->Wires->setAutoDelete(true); - if (Doc->Wires->containsRef ((Wire*)e)) - Doc->enlargeView(e->x1, e->y1, e->x2, e->y2); - break; + pl = ((Wire *) e)->Label; + ((Wire *) e)->Label = 0; // prevent label to be deleted + Doc->Wires->setAutoDelete(false); + Doc->deleteWire((Wire *) e); + ((Wire *) e)->Label = pl; + ((Wire *) e)->rotate(); + Doc->setOnGrid(e->x1, e->y1); + Doc->setOnGrid(e->x2, e->y2); + if (pl) + Doc->setOnGrid(pl->cx, pl->cy); + Doc->insertWire((Wire *) e); + Doc->Wires->setAutoDelete(true); + if (Doc->Wires->containsRef((Wire *) e)) + Doc->enlargeView(e->x1, e->y1, e->x2, e->y2); + break; case isPainting: - ((Painting*)e)->rotate(); - // enlarge viewarea if component lies outside the view - ((Painting*)e)->Bounding(x1,y1,x2,y2); - Doc->enlargeView(x1, y1, x2, y2); - break; + ((Painting *) e)->rotate(0, 0); + // enlarge viewarea if component lies outside the view + ((Painting *) e)->Bounding(x1, y1, x2, y2); + Doc->enlargeView(x1, y1, x2, y2); + break; default: - return; - } - Doc->viewport()->update(); - drawn = false; - Doc->setChanged(true, true); + return; + } + Doc->viewport()->update(); + drawn = false; + Doc->setChanged(true, true); } // ----------------------------------------------------------- // insert component, diagram, painting into schematic ?! -void MouseActions::MPressElement(Schematic *Doc, QMouseEvent *Event, float, float) { - if (selElem == 0) return; +void MouseActions::MPressElement(Schematic *Doc, QMouseEvent *Event, float, float) +{ + if (selElem == 0) + return; //QPainter painter(Doc->viewport()); //setPainter(Doc, &painter); - int x1, y1, x2, y2, rot; if (selElem->Type & isComponent) { Component *Comp = (Component *) selElem; -// qDebug() << "+-+ got to switch:" << Comp->Name; + // qDebug() << "+-+ got to switch:" << Comp->Name; QString entryName = Comp->Name; switch (Event->button()) { - case Qt::LeftButton : - // left mouse button inserts component into the schematic - // give the component a pointer to the schematic it's a - // part of - Comp->setSchematic(Doc); - Comp->textSize(x1, y1); - Doc->insertComponent(Comp); - Comp->textSize(x2, y2); - if (Comp->tx < Comp->x1) Comp->tx -= x2 - x1; - - // Note: insertCopmponents does increment name1 -> name2 -// qDebug() << " +-+ got to insert:" << Comp->Name; - - // enlarge viewarea if component lies outside the view - Comp->entireBounds(x1, y1, x2, y2, Doc->textCorr()); - Doc->enlargeView(x1, y1, x2, y2); + case Qt::LeftButton: + // left mouse button inserts component into the schematic + // give the component a pointer to the schematic it's a + // part of + Comp->setSchematic(Doc); + Comp->textSize(x1, y1); + Doc->insertComponent(Comp); + Comp->textSize(x2, y2); + if (Comp->tx < Comp->x1) + Comp->tx -= x2 - x1; + + // Note: insertCopmponents does increment name1 -> name2 + // qDebug() << " +-+ got to insert:" << Comp->Name; + + // enlarge viewarea if component lies outside the view + Comp->entireBounds(x1, y1, x2, y2, Doc->textCorr()); + Doc->enlargeView(x1, y1, x2, y2); - drawn = false; - Doc->viewport()->update(); - Doc->setChanged(true, true); - rot = Comp->rotated; - - // handle static and dynamic components -// QucsApp::CompChoose; - if (Module::vaComponents.contains(entryName)) { - QString filename = Module::vaComponents[entryName]; -// qDebug() << " ===+ recast"; - Comp = dynamic_cast(Comp)->newOne(filename); //va component - qDebug() << " => recast = Comp;" << Comp->Name << "filename: " << filename; - } else { - Comp = Comp->newOne(); // static component is used, so create a new one - } - rot -= Comp->rotated; - rot &= 3; - while (rot--) Comp->rotate(); // keep last rotation for single component - break; + drawn = false; + Doc->viewport()->update(); + Doc->setChanged(true, true); + rot = Comp->rotated; + + // handle static and dynamic components + // QucsApp::CompChoose; + if (Module::vaComponents.contains(entryName)) { + QString filename = Module::vaComponents[entryName]; + // qDebug() << " ===+ recast"; + Comp = dynamic_cast(Comp)->newOne(filename); //va component + qDebug() << " => recast = Comp;" << Comp->Name << "filename: " << filename; + } else { + Comp = Comp->newOne(); // static component is used, so create a new one + } + rot -= Comp->rotated; + rot &= 3; + while (rot--) + Comp->rotate(); // keep last rotation for single component + break; - case Qt::RightButton : // right mouse button rotates the component - if (Comp->Ports.count() == 0) - break; // do not rotate components without ports - Comp->paintScheme(Doc); // erase old component scheme - Doc->viewport()->repaint(); - Comp->rotate(); - Comp->paintScheme(Doc); // paint new component scheme - break; + case Qt::RightButton: // right mouse button rotates the component + if (Comp->Ports.count() == 0) + break; // do not rotate components without ports + Comp->paintScheme(Doc); // erase old component scheme + Doc->viewport()->repaint(); + Comp->rotate(); + Comp->paintScheme(Doc); // paint new component scheme + break; - default:; // avoids compiler warnings + default:; // avoids compiler warnings } -// qDebug() << " => selElem = Comp;" << Comp->Name; + // qDebug() << " => selElem = Comp;" << Comp->Name; // comp it getting empty selElem = Comp; return; - } // of "if(isComponent)" + } // of "if(isComponent)" else if (selElem->Type == isDiagram) { - if (Event->button() != Qt::LeftButton) return; + if (Event->button() != Qt::LeftButton) + return; Diagram *Diag = (Diagram *) selElem; QFileInfo Info(Doc->DocName); // dialog is Qt::WDestructiveClose !!! - DiagramDialog *dia = - new DiagramDialog(Diag, Doc); - if (dia->exec() == QDialog::Rejected) { // don't insert if dialog canceled + DiagramDialog *dia = new DiagramDialog(Diag, Doc); + if (dia->exec() == QDialog::Rejected) { // don't insert if dialog canceled Doc->viewport()->update(); drawn = false; return; @@ -1325,68 +1385,65 @@ void MouseActions::MPressElement(Schematic *Doc, QMouseEvent *Event, float, floa Doc->Diagrams->append(Diag); Doc->enlargeView(Diag->cx, Diag->cy - Diag->y2, Diag->cx + Diag->x2, Diag->cy); - Doc->setChanged(true, true); // document has been changed + Doc->setChanged(true, true); // document has been changed Doc->viewport()->repaint(); Diag = Diag->newOne(); // the component is used, so create a new one Diag->paintScheme(Doc); selElem = Diag; return; - } // of "if(isDiagram)" + } // of "if(isDiagram)" + // *********** it is a painting !!! + if (((Painting *) selElem)->MousePressing()) { + Doc->Paintings->append((Painting *) selElem); + ((Painting *) selElem)->Bounding(x1, y1, x2, y2); + //Doc->enlargeView(x1, y1, x2, y2); + selElem = ((Painting *) selElem)->newOne(); - // *********** it is a painting !!! - if(((Painting*)selElem)->MousePressing()) { - Doc->Paintings->append((Painting*)selElem); - ((Painting*)selElem)->Bounding(x1,y1,x2,y2); - //Doc->enlargeView(x1, y1, x2, y2); - selElem = ((Painting*)selElem)->newOne(); + Doc->viewport()->update(); + Doc->setChanged(true, true); - Doc->viewport()->update(); - Doc->setChanged(true, true); - - MMoveElement(Doc, Event); // needed before next mouse pressing - drawn = false; - } + MMoveElement(Doc, Event); // needed before next mouse pressing + drawn = false; + } } - /** * @brief MouseActions::MPressWire1 Is called if starting point of wire is pressed * @param Doc * @param fX * @param fY */ -void MouseActions::MPressWire1(Schematic *Doc, QMouseEvent*, float fX, float fY) +void MouseActions::MPressWire1(Schematic *Doc, QMouseEvent *, float fX, float fY) { - //Doc->PostPaintEvent (_DotLine); - //Doc->PostPaintEvent (PPENotRop); - //if(drawn) { -#if 0 //ALYS - it draws some garbage, not deleted because of possible questions + //Doc->PostPaintEvent (_DotLine); + //Doc->PostPaintEvent (PPENotRop); + //if(drawn) { +#if 0 //ALYS - it draws some garbage, not deleted because of possible questions Doc->PostPaintEvent (_Line, 0, MAy3, MAx2, MAy3); // erase old mouse cross Doc->PostPaintEvent (_Line, MAx3, 0, MAx3, MAy2); #endif - //} - //drawn = false; - - MAx1 = 0; // paint wire corner first up, then left/right - MAx3 = int(fX); - MAy3 = int(fY); - Doc->setOnGrid(MAx3, MAy3); - -//ALYS - draw aiming cross - paintAim(Doc,MAx3, MAy3); -//####################### - - formerAction = 0; // keep wire action active after first wire finished - QucsMain->MouseMoveAction = &MouseActions::MMoveWire2; - QucsMain->MousePressAction = &MouseActions::MPressWire2; - // Double-click action is set in "MMoveWire2" to not initiate it - // during "Wire1" actions. - Doc->viewport()->update(); + //} + //drawn = false; + + MAx1 = 0; // paint wire corner first up, then left/right + MAx3 = int(fX); + MAy3 = int(fY); + Doc->setOnGrid(MAx3, MAy3); + + //ALYS - draw aiming cross + paintAim(Doc, MAx3, MAy3); + //####################### + + formerAction = 0; // keep wire action active after first wire finished + QucsMain->MouseMoveAction = &MouseActions::MMoveWire2; + QucsMain->MousePressAction = &MouseActions::MPressWire2; + // Double-click action is set in "MMoveWire2" to not initiate it + // during "Wire1" actions. + Doc->viewport()->update(); } - /** * @brief MouseActions::MPressWire2 Is called if ending point of wire is pressed * @param Doc @@ -1396,52 +1453,50 @@ void MouseActions::MPressWire1(Schematic *Doc, QMouseEvent*, float fX, float fY) */ void MouseActions::MPressWire2(Schematic *Doc, QMouseEvent *Event, float fX, float fY) { + int set1 = 0, set2 = 0; + switch (Event->button()) { + case Qt::LeftButton: + if (MAx1 == 0) { // which wire direction first ? + if (MAy2 != MAy3) + set1 = Doc->insertWire(new Wire(MAx3, MAy3, MAx3, MAy2)); + if (MAx2 != MAx3) { + set2 = set1; + set1 = Doc->insertWire(new Wire(MAx3, MAy2, MAx2, MAy2)); + } + } else { + if (MAx2 != MAx3) + set1 = Doc->insertWire(new Wire(MAx3, MAy3, MAx2, MAy3)); + if (MAy2 != MAy3) { + set2 = set1; + set1 = Doc->insertWire(new Wire(MAx2, MAy3, MAx2, MAy2)); + } + } - int set1 = 0, set2 = 0; - switch(Event->button()) { - case Qt::LeftButton : - if(MAx1 == 0) { // which wire direction first ? - if(MAy2 != MAy3) - set1 = Doc->insertWire(new Wire(MAx3, MAy3, MAx3, MAy2)); - if(MAx2 != MAx3) { - set2 = set1; - set1 = Doc->insertWire(new Wire(MAx3, MAy2, MAx2, MAy2)); - } - } - else { - if(MAx2 != MAx3) - set1 = Doc->insertWire(new Wire(MAx3, MAy3, MAx2, MAy3)); - if(MAy2 != MAy3) { - set2 = set1; - set1 = Doc->insertWire(new Wire(MAx2, MAy3, MAx2, MAy2)); - } - } - - if(set1 & 2) { - // if last port is connected, then... - if(formerAction) { - // ...restore old action - QucsMain->select->setChecked(true); - } - else { - // ...start a new wire - QucsMain->MouseMoveAction = &MouseActions::MMoveWire1; - QucsMain->MousePressAction = &MouseActions::MPressWire1; - QucsMain->MouseDoubleClickAction = 0; - } - } + if (set1 & 2) { + // if last port is connected, then... + if (formerAction) { + // ...restore old action + QucsMain->select->setChecked(true); + } else { + // ...start a new wire + QucsMain->MouseMoveAction = &MouseActions::MMoveWire1; + QucsMain->MousePressAction = &MouseActions::MPressWire1; + QucsMain->MouseDoubleClickAction = 0; + } + } - //ALYS: excessive update. end of function does it. - //Doc->viewport()->update(); + //ALYS: excessive update. end of function does it. + //Doc->viewport()->update(); - drawn = false; - if(set1 | set2) Doc->setChanged(true, true); - MAx3 = MAx2; - MAy3 = MAy2; - break; + drawn = false; + if (set1 | set2) + Doc->setChanged(true, true); + MAx3 = MAx2; + MAy3 = MAy2; + break; - /// \todo document right mouse button changes the wire corner - case Qt::RightButton : + /// \todo document right mouse button changes the wire corner + case Qt::RightButton: #if 0 //ALYS - old code preserved because isn't clear - what it was??? @@ -1457,103 +1512,99 @@ void MouseActions::MPressWire2(Schematic *Doc, QMouseEvent *Event, float fX, flo } #endif - MAx2 = int(fX); - MAy2 = int(fY); - Doc->setOnGrid(MAx2, MAy2); + MAx2 = int(fX); + MAy2 = int(fY); + Doc->setOnGrid(MAx2, MAy2); + + MAx1 ^= 1; // change the painting direction of wire corner + if (MAx1 == 0) { + paintGhostLineV(Doc, MAx3, MAy3, MAy2); + paintGhostLineH(Doc, MAx3, MAy2, MAx2); + } else { + paintGhostLineH(Doc, MAx3, MAy3, MAx2); + paintGhostLineV(Doc, MAx2, MAy3, MAy2); + } + break; - MAx1 ^= 1; // change the painting direction of wire corner - if(MAx1 == 0) { - paintGhostLineV(Doc,MAx3,MAy3,MAy2); - paintGhostLineH(Doc,MAx3,MAy2,MAx2); - } - else { - paintGhostLineH(Doc,MAx3,MAy3,MAx2); - paintGhostLineV(Doc,MAx2,MAy3,MAy2); + default:; // avoids compiler warnings } - break; - default: ; // avoids compiler warnings - } - - paintAim(Doc,MAx2,MAy2); //ALYS - added missed aiming cross - Doc->viewport()->update(); + paintAim(Doc, MAx2, MAy2); //ALYS - added missed aiming cross + Doc->viewport()->update(); } // ----------------------------------------------------------- // Is called for setting a marker on a diagram's graph -void MouseActions::MPressMarker(Schematic *Doc, QMouseEvent*, float fX, float fY) +void MouseActions::MPressMarker(Schematic *Doc, QMouseEvent *, float fX, float fY) { - MAx1 = int(fX); - MAy1 = int(fY); - Marker *pm = Doc->setMarker(MAx1, MAy1); - - if(pm) { - assert(pm->diag()); - int x0 = pm->diag()->cx; - int y0 = pm->diag()->cy; - Doc->enlargeView(x0+pm->x1, y0-pm->y1-pm->y2, x0+pm->x1+pm->x2, y0-pm->y1); - } - Doc->viewport()->update(); - drawn = false; + MAx1 = int(fX); + MAy1 = int(fY); + Marker *pm = Doc->setMarker(MAx1, MAy1); + + if (pm) { + assert(pm->diag()); + int x0 = pm->diag()->cx; + int y0 = pm->diag()->cy; + Doc->enlargeView(x0 + pm->x1, y0 - pm->y1 - pm->y2, x0 + pm->x1 + pm->x2, y0 - pm->y1); + } + Doc->viewport()->update(); + drawn = false; } // ----------------------------------------------------------- -void MouseActions::MPressOnGrid(Schematic *Doc, QMouseEvent*, float fX, float fY) +void MouseActions::MPressOnGrid(Schematic *Doc, QMouseEvent *, float fX, float fY) { - Element *pe = Doc->selectElement(fX, fY, false); - if(pe) - { - pe->Type &= isSpecialMask; // remove special functions (4 lowest bits) - - // onGrid is toggle action -> no other element can be selected - pe->isSelected = true; - Doc->elementsOnGrid(); + Element *pe = Doc->selectElement(fX, fY, false); + if (pe) { + pe->Type &= isSpecialMask; // remove special functions (4 lowest bits) - Doc->sizeOfAll(Doc->UsedX1, Doc->UsedY1, Doc->UsedX2, Doc->UsedY2); - // Update matching wire label highlighting - Doc->highlightWireLabels (); - Doc->viewport()->update(); - drawn = false; - } + // onGrid is toggle action -> no other element can be selected + pe->isSelected = true; + Doc->elementsOnGrid(); + Doc->sizeOfAll(Doc->UsedX1, Doc->UsedY1, Doc->UsedX2, Doc->UsedY2); + // Update matching wire label highlighting + Doc->highlightWireLabels(); + Doc->viewport()->update(); + drawn = false; + } } // ----------------------------------------------------------- -void MouseActions::MPressMoveText(Schematic *Doc, QMouseEvent*, float fX, float fY) +void MouseActions::MPressMoveText(Schematic *Doc, QMouseEvent *, float fX, float fY) { - MAx1 = int(fX); - MAy1 = int(fY); - focusElement = Doc->selectCompText(MAx1, MAy1, MAx2, MAy2); - - if(focusElement) { - MAx3 = MAx1; - MAy3 = MAy1; - MAx1 = ((Component*)focusElement)->cx + ((Component*)focusElement)->tx; - MAy1 = ((Component*)focusElement)->cy + ((Component*)focusElement)->ty; - Doc->viewport()->update(); - drawn = false; - QucsMain->MouseMoveAction = &MouseActions::MMoveMoveText; - QucsMain->MouseReleaseAction = &MouseActions::MReleaseMoveText; - Doc->grabKeyboard(); // no keyboard inputs during move actions - } + MAx1 = int(fX); + MAy1 = int(fY); + focusElement = Doc->selectCompText(MAx1, MAy1, MAx2, MAy2); + + if (focusElement) { + MAx3 = MAx1; + MAy3 = MAy1; + MAx1 = ((Component *) focusElement)->cx + ((Component *) focusElement)->tx; + MAy1 = ((Component *) focusElement)->cy + ((Component *) focusElement)->ty; + Doc->viewport()->update(); + drawn = false; + QucsMain->MouseMoveAction = &MouseActions::MMoveMoveText; + QucsMain->MouseReleaseAction = &MouseActions::MReleaseMoveText; + Doc->grabKeyboard(); // no keyboard inputs during move actions + } } // ----------------------------------------------------------- -void MouseActions::MPressZoomIn(Schematic *Doc, QMouseEvent*, float fX, float fY) +void MouseActions::MPressZoomIn(Schematic *Doc, QMouseEvent *, float fX, float fY) { - qDebug() << "zoom into box"; - MAx1 = int(fX); - MAy1 = int(fY); - MAx2 = 0; // rectangle size - MAy2 = 0; - - QucsMain->MouseMoveAction = &MouseActions::MMoveSelect; - QucsMain->MouseReleaseAction = &MouseActions::MReleaseZoomIn; - Doc->grabKeyboard(); // no keyboard inputs during move actions - Doc->viewport()->update(); - drawn = false; -} + qDebug() << "zoom into box"; + MAx1 = int(fX); + MAy1 = int(fY); + MAx2 = 0; // rectangle size + MAy2 = 0; + QucsMain->MouseMoveAction = &MouseActions::MMoveSelect; + QucsMain->MouseReleaseAction = &MouseActions::MReleaseZoomIn; + Doc->grabKeyboard(); // no keyboard inputs during move actions + Doc->viewport()->update(); + drawn = false; +} // *********************************************************************** // ********** ********** @@ -1562,350 +1613,364 @@ void MouseActions::MPressZoomIn(Schematic *Doc, QMouseEvent*, float fX, float fY // *********************************************************************** void MouseActions::MReleaseSelect(Schematic *Doc, QMouseEvent *Event) { - bool ctrl; - if(Event->modifiers().testFlag(Qt::ControlModifier)) ctrl = true; - else ctrl = false; + bool ctrl; + if (Event->modifiers().testFlag(Qt::ControlModifier)) + ctrl = true; + else + ctrl = false; - if(!ctrl) Doc->deselectElements(focusElement); + if (!ctrl) + Doc->deselectElements(focusElement); - if(focusElement) if(Event->button() == Qt::LeftButton) - if(focusElement->Type == isWire) { - Doc->selectWireLine(focusElement, ((Wire*)focusElement)->Port1, ctrl); - Doc->selectWireLine(focusElement, ((Wire*)focusElement)->Port2, ctrl); - } + if (focusElement) + if (Event->button() == Qt::LeftButton) + if (focusElement->Type == isWire) { + Doc->selectWireLine(focusElement, ((Wire *) focusElement)->Port1, ctrl); + Doc->selectWireLine(focusElement, ((Wire *) focusElement)->Port2, ctrl); + } - Doc->releaseKeyboard(); // allow keyboard inputs again - QucsMain->MousePressAction = &MouseActions::MPressSelect; - QucsMain->MouseReleaseAction = &MouseActions::MReleaseSelect; - QucsMain->MouseDoubleClickAction = &MouseActions::MDoubleClickSelect; - QucsMain->MouseMoveAction = 0; // no element moving - Doc->highlightWireLabels (); - Doc->viewport()->update(); - drawn = false; + Doc->releaseKeyboard(); // allow keyboard inputs again + QucsMain->MousePressAction = &MouseActions::MPressSelect; + QucsMain->MouseReleaseAction = &MouseActions::MReleaseSelect; + QucsMain->MouseDoubleClickAction = &MouseActions::MDoubleClickSelect; + QucsMain->MouseMoveAction = 0; // no element moving + Doc->highlightWireLabels(); + Doc->viewport()->update(); + drawn = false; } // ----------------------------------------------------------- // Is called after the rectangle for selection is released. void MouseActions::MReleaseSelect2(Schematic *Doc, QMouseEvent *Event) { - if(Event->button() != Qt::LeftButton) return; - - bool IsCtrl = Event->modifiers().testFlag(Qt::ControlModifier); - bool IsShift = Event->modifiers().testFlag(Qt::ShiftModifier); - - // selects all elements within the rectangle - Doc->selectElements(MAx1, MAy1, MAx1+MAx2, MAy1+MAy2, IsCtrl, !IsShift); - - Doc->releaseKeyboard(); // allow keyboard inputs again - QucsMain->MouseMoveAction = 0; - QucsMain->MousePressAction = &MouseActions::MPressSelect; - QucsMain->MouseReleaseAction = &MouseActions::MReleaseSelect; - QucsMain->MouseDoubleClickAction = &MouseActions::MDoubleClickSelect; - Doc->highlightWireLabels (); - Doc->PostedPaintEvents.clear(); - Doc->viewport()->update(); - drawn = false; + if (Event->button() != Qt::LeftButton) + return; + + bool IsCtrl = Event->modifiers().testFlag(Qt::ControlModifier); + bool IsShift = Event->modifiers().testFlag(Qt::ShiftModifier); + + // selects all elements within the rectangle + Doc->selectElements(MAx1, MAy1, MAx1 + MAx2, MAy1 + MAy2, IsCtrl, !IsShift); + + Doc->releaseKeyboard(); // allow keyboard inputs again + QucsMain->MouseMoveAction = 0; + QucsMain->MousePressAction = &MouseActions::MPressSelect; + QucsMain->MouseReleaseAction = &MouseActions::MReleaseSelect; + QucsMain->MouseDoubleClickAction = &MouseActions::MDoubleClickSelect; + Doc->highlightWireLabels(); + Doc->PostedPaintEvents.clear(); + Doc->viewport()->update(); + drawn = false; } // ----------------------------------------------------------- void MouseActions::MReleaseActivate(Schematic *Doc, QMouseEvent *Event) { - if(Event->button() != Qt::LeftButton) return; - - // activates all components within the rectangle - Doc->activateCompsWithinRect(MAx1, MAy1, MAx1+MAx2, MAy1+MAy2); - - QucsMain->MouseMoveAction = &MouseActions::MMoveActivate; - QucsMain->MousePressAction = &MouseActions::MPressActivate; - QucsMain->MouseReleaseAction = 0; - QucsMain->MouseDoubleClickAction = 0; - Doc->highlightWireLabels (); - Doc->viewport()->update(); - drawn = false; + if (Event->button() != Qt::LeftButton) + return; + + // activates all components within the rectangle + Doc->activateCompsWithinRect(MAx1, MAy1, MAx1 + MAx2, MAy1 + MAy2); + + QucsMain->MouseMoveAction = &MouseActions::MMoveActivate; + QucsMain->MousePressAction = &MouseActions::MPressActivate; + QucsMain->MouseReleaseAction = 0; + QucsMain->MouseDoubleClickAction = 0; + Doc->highlightWireLabels(); + Doc->viewport()->update(); + drawn = false; } // ----------------------------------------------------------- // Is called after moving selected elements. -void MouseActions::MReleaseMoving(Schematic *Doc, QMouseEvent*) +void MouseActions::MReleaseMoving(Schematic *Doc, QMouseEvent *) { - // Allow all mouse buttons, because for others than the left one, - // a menu has already created. - endElementMoving(Doc, &movingElements); - Doc->releaseKeyboard(); // allow keyboard inputs again - - QucsMain->MouseMoveAction = 0; - QucsMain->MousePressAction = &MouseActions::MPressSelect; - QucsMain->MouseReleaseAction = &MouseActions::MReleaseSelect; - QucsMain->MouseDoubleClickAction = &MouseActions::MDoubleClickSelect; + // Allow all mouse buttons, because for others than the left one, + // a menu has already created. + endElementMoving(Doc, &movingElements); + Doc->releaseKeyboard(); // allow keyboard inputs again + + QucsMain->MouseMoveAction = 0; + QucsMain->MousePressAction = &MouseActions::MPressSelect; + QucsMain->MouseReleaseAction = &MouseActions::MReleaseSelect; + QucsMain->MouseDoubleClickAction = &MouseActions::MDoubleClickSelect; } // ----------------------------------------------------------- void MouseActions::MReleaseResizeDiagram(Schematic *Doc, QMouseEvent *Event) { - if(Event->button() != Qt::LeftButton) return; - - MAx3 = focusElement->cx; - MAy3 = focusElement->cy; - if(MAx2 < 0) { // resize diagram - if(MAx2 > -10) MAx2 = -10; // not smaller than 10 pixels - focusElement->x2 = -MAx2; - focusElement->cx = MAx1+MAx2; - } - else { - if(MAx2 < 10) MAx2 = 10; - focusElement->x2 = MAx2; - focusElement->cx = MAx1; - } - if(MAy2 < 0) { - if(MAy2 > -10) MAy2 = -10; - focusElement->y2 = -MAy2; - focusElement->cy = MAy1; - } - else { - if(MAy2 < 10) MAy2 = 10; - focusElement->y2 = MAy2; - focusElement->cy = MAy1+MAy2; - } - MAx3 -= focusElement->cx; - MAy3 -= focusElement->cy; - - Diagram *pd = (Diagram*)focusElement; - pd->updateGraphData(); - for (Graph *pg : pd->Graphs) - for(Marker *pm : pg->Markers) { - pm->x1 += MAx3; // correct changes due to move of diagram corner - pm->y1 += MAy3; + if (Event->button() != Qt::LeftButton) + return; + + MAx3 = focusElement->cx; + MAy3 = focusElement->cy; + if (MAx2 < 0) { // resize diagram + if (MAx2 > -10) + MAx2 = -10; // not smaller than 10 pixels + focusElement->x2 = -MAx2; + focusElement->cx = MAx1 + MAx2; + } else { + if (MAx2 < 10) + MAx2 = 10; + focusElement->x2 = MAx2; + focusElement->cx = MAx1; + } + if (MAy2 < 0) { + if (MAy2 > -10) + MAy2 = -10; + focusElement->y2 = -MAy2; + focusElement->cy = MAy1; + } else { + if (MAy2 < 10) + MAy2 = 10; + focusElement->y2 = MAy2; + focusElement->cy = MAy1 + MAy2; } + MAx3 -= focusElement->cx; + MAy3 -= focusElement->cy; + + Diagram *pd = (Diagram *) focusElement; + pd->updateGraphData(); + for (Graph *pg : pd->Graphs) + for (Marker *pm : pg->Markers) { + pm->x1 += MAx3; // correct changes due to move of diagram corner + pm->y1 += MAy3; + } - int x1, x2, y1, y2; - pd->Bounding(x1, x2, y1, y2); - Doc->enlargeView(x1, x2, y1, y2); + int x1, x2, y1, y2; + pd->Bounding(x1, x2, y1, y2); + Doc->enlargeView(x1, x2, y1, y2); - QucsMain->MouseMoveAction = nullptr; - QucsMain->MousePressAction = &MouseActions::MPressSelect; - QucsMain->MouseReleaseAction = &MouseActions::MReleaseSelect; - QucsMain->MouseDoubleClickAction = &MouseActions::MDoubleClickSelect; - Doc->releaseKeyboard(); // allow keyboard inputs again + QucsMain->MouseMoveAction = nullptr; + QucsMain->MousePressAction = &MouseActions::MPressSelect; + QucsMain->MouseReleaseAction = &MouseActions::MReleaseSelect; + QucsMain->MouseDoubleClickAction = &MouseActions::MDoubleClickSelect; + Doc->releaseKeyboard(); // allow keyboard inputs again - Doc->viewport()->update(); - drawn = false; - Doc->setChanged(true, true); + Doc->viewport()->update(); + drawn = false; + Doc->setChanged(true, true); } // ----------------------------------------------------------- void MouseActions::MReleaseResizePainting(Schematic *Doc, QMouseEvent *Event) { - if(Event->button() != Qt::LeftButton) return; + if (Event->button() != Qt::LeftButton) + return; - QucsMain->MouseMoveAction = nullptr; - QucsMain->MousePressAction = &MouseActions::MPressSelect; - QucsMain->MouseReleaseAction = &MouseActions::MReleaseSelect; - QucsMain->MouseDoubleClickAction = &MouseActions::MDoubleClickSelect; - Doc->releaseKeyboard(); // allow keyboard inputs again + QucsMain->MouseMoveAction = nullptr; + QucsMain->MousePressAction = &MouseActions::MPressSelect; + QucsMain->MouseReleaseAction = &MouseActions::MReleaseSelect; + QucsMain->MouseDoubleClickAction = &MouseActions::MDoubleClickSelect; + Doc->releaseKeyboard(); // allow keyboard inputs again - Doc->viewport()->update(); - drawn = false; - Doc->setChanged(true, true); + Doc->viewport()->update(); + drawn = false; + Doc->setChanged(true, true); } // ----------------------------------------------------------- void MouseActions::paintElementsScheme(Schematic *p) { - Element *pe; - for(pe = movingElements.first(); pe != nullptr; pe = movingElements.next()) - pe->paintScheme(p); + Element *pe; + for (pe = movingElements.first(); pe != nullptr; pe = movingElements.next()) + pe->paintScheme(p); } // ----------------------------------------------------------- -void MouseActions::moveElements(Schematic *Doc, int& x1, int& y1) +void MouseActions::moveElements(Schematic *Doc, int &x1, int &y1) { - Element *pe; - Doc->setOnGrid(x1, y1); - - for(pe=movingElements.first(); pe!=0; pe=movingElements.next()) { - if(pe->Type & isLabel) { - pe->cx += x1; pe->x1 += x1; - pe->cy += y1; pe->y1 += y1; + Element *pe; + Doc->setOnGrid(x1, y1); + + for (pe = movingElements.first(); pe != 0; pe = movingElements.next()) { + if (pe->Type & isLabel) { + pe->cx += x1; + pe->x1 += x1; + pe->cy += y1; + pe->y1 += y1; + } else + pe->setCenter(x1, y1, true); } - else - pe->setCenter(x1, y1, true); - } } // ----------------------------------------------------------- -void MouseActions::rotateElements(Schematic *Doc, int& x1, int& y1) +void MouseActions::rotateElements(Schematic *Doc, int &x1, int &y1) { - int x2, y2; - Element *pe; - Doc->setOnGrid(x1, y1); + int x2, y2; + Element *pe; + Doc->setOnGrid(x1, y1); - for(pe = movingElements.first(); pe != 0; pe = movingElements.next()) { - switch(pe->Type) { - case isComponent: - case isAnalogComponent: - case isDigitalComponent: - ((Component*)pe)->rotate(); // rotate !before! rotating the center - x2 = x1 - pe->cx; - pe->setCenter(pe->cy - y1 + x1, x2 + y1); - break; - case isWire: - x2 = pe->x1; - pe->x1 = pe->y1 - y1 + x1; - pe->y1 = x1 - x2 + y1; - x2 = pe->x2; - pe->x2 = pe->y2 - y1 + x1; - pe->y2 = x1 - x2 + y1; - break; - case isPainting: - ((Painting*)pe)->rotate(); // rotate !before! rotating the center - ((Painting*)pe)->getCenter(x2, y2); - pe->setCenter(y2 - y1 + x1, x1 - x2 + y1); - break; - default: - x2 = x1 - pe->cx; // if diagram -> only rotate cx/cy - pe->setCenter(pe->cy - y1 + x1, x2 + y1); - break; + for (pe = movingElements.first(); pe != 0; pe = movingElements.next()) { + switch (pe->Type) { + case isComponent: + case isAnalogComponent: + case isDigitalComponent: + ((Component *) pe)->rotate(); // rotate !before! rotating the center + x2 = x1 - pe->cx; + pe->setCenter(pe->cy - y1 + x1, x2 + y1); + break; + case isWire: + x2 = pe->x1; + pe->x1 = pe->y1 - y1 + x1; + pe->y1 = x1 - x2 + y1; + x2 = pe->x2; + pe->x2 = pe->y2 - y1 + x1; + pe->y2 = x1 - x2 + y1; + break; + case isPainting: + ((Painting *) pe)->rotate(x1, y1); // rotate around the center x1 y1 + break; + default: + x2 = x1 - pe->cx; // if diagram -> only rotate cx/cy + pe->setCenter(pe->cy - y1 + x1, x2 + y1); + break; + } } - } } // ----------------------------------------------------------- void MouseActions::MReleasePaste(Schematic *Doc, QMouseEvent *Event) { - int x1, y1, x2, y2, rot; - QFileInfo Info(Doc->DocName); - //QPainter painter(Doc->viewport()); - - Element *pe; - switch(Event->button()) { - case Qt::LeftButton : - // insert all moved elements into document - for(pe = movingElements.first(); pe!=0; pe = movingElements.next()) { - pe->isSelected = false; - switch(pe->Type) { - case isWire: - if(pe->x1 == pe->x2) if(pe->y1 == pe->y2) break; - Doc->insertWire((Wire*)pe); - if (Doc->Wires->containsRef ((Wire*)pe)) - Doc->enlargeView(pe->x1, pe->y1, pe->x2, pe->y2); - else pe = NULL; - break; - case isDiagram: - Doc->Diagrams->append((Diagram*)pe); - ((Diagram*)pe)->loadGraphData(Info.absolutePath() + QDir::separator() + - Doc->DataSet); - Doc->enlargeView(pe->cx, pe->cy-pe->y2, pe->cx+pe->x2, pe->cy); - break; - case isPainting: - Doc->Paintings->append((Painting*)pe); - ((Painting*)pe)->Bounding(x1,y1,x2,y2); - Doc->enlargeView(x1, y1, x2, y2); - break; - case isMovingLabel: - pe->Type = isNodeLabel; - Doc->placeNodeLabel((WireLabel*)pe); - break; - case isComponent: - case isAnalogComponent: - case isDigitalComponent: - Doc->insertComponent((Component*)pe); - ((Component*)pe)->entireBounds(x1,y1,x2,y2, Doc->textCorr()); - Doc->enlargeView(x1, y1, x2, y2); - break; - } - } - - pasteElements(Doc); - // keep rotation sticky for pasted elements - rot = movingRotated; - x1 = y1 = 0; - while(rot--) rotateElements(Doc,x1,y1); + int x1, y1, x2, y2, rot; + QFileInfo Info(Doc->DocName); + //QPainter painter(Doc->viewport()); - QucsMain->MouseMoveAction = &MouseActions::MMovePaste; - QucsMain->MousePressAction = 0; - QucsMain->MouseReleaseAction = 0; - QucsMain->MouseDoubleClickAction = 0; + Element *pe; + switch (Event->button()) { + case Qt::LeftButton: + // insert all moved elements into document + for (pe = movingElements.first(); pe != 0; pe = movingElements.next()) { + pe->isSelected = false; + switch (pe->Type) { + case isWire: + if (pe->x1 == pe->x2) + if (pe->y1 == pe->y2) + break; + Doc->insertWire((Wire *) pe); + if (Doc->Wires->containsRef((Wire *) pe)) + Doc->enlargeView(pe->x1, pe->y1, pe->x2, pe->y2); + else + pe = NULL; + break; + case isDiagram: + Doc->Diagrams->append((Diagram *) pe); + ((Diagram *) pe) + ->loadGraphData(Info.absolutePath() + QDir::separator() + Doc->DataSet); + Doc->enlargeView(pe->cx, pe->cy - pe->y2, pe->cx + pe->x2, pe->cy); + break; + case isPainting: + Doc->Paintings->append((Painting *) pe); + ((Painting *) pe)->Bounding(x1, y1, x2, y2); + Doc->enlargeView(x1, y1, x2, y2); + break; + case isMovingLabel: + pe->Type = isNodeLabel; + Doc->placeNodeLabel((WireLabel *) pe); + break; + case isComponent: + case isAnalogComponent: + case isDigitalComponent: + Doc->insertComponent((Component *) pe); + ((Component *) pe)->entireBounds(x1, y1, x2, y2, Doc->textCorr()); + Doc->enlargeView(x1, y1, x2, y2); + break; + } + } - drawn = false; - Doc->viewport()->update(); - Doc->setChanged(true, true); - break; + pasteElements(Doc); + // keep rotation sticky for pasted elements + rot = movingRotated; + x1 = y1 = 0; + while (rot--) + rotateElements(Doc, x1, y1); - // ............................................................ - case Qt::RightButton : // right button rotates the elements - //setPainter(Doc, &painter); + QucsMain->MouseMoveAction = &MouseActions::MMovePaste; + QucsMain->MousePressAction = 0; + QucsMain->MouseReleaseAction = 0; + QucsMain->MouseDoubleClickAction = 0; - if(drawn) // erase old scheme - paintElementsScheme(Doc); - drawn = true; + drawn = false; + Doc->viewport()->update(); + Doc->setChanged(true, true); + break; - x1 = DOC_X_POS(Event->pos().x()); - y1 = DOC_Y_POS(Event->pos().y()); - rotateElements(Doc,x1,y1); - paintElementsScheme(Doc); - // save rotation - movingRotated++; - movingRotated &= 3; - break; + // ............................................................ + case Qt::RightButton: // right button rotates the elements + //setPainter(Doc, &painter); + + if (drawn) // erase old scheme + paintElementsScheme(Doc); + drawn = true; + + x1 = DOC_X_POS(Event->pos().x()); + y1 = DOC_Y_POS(Event->pos().y()); + rotateElements(Doc, x1, y1); + paintElementsScheme(Doc); + // save rotation + movingRotated++; + movingRotated &= 3; + break; - default: ; // avoids compiler warnings - } + default:; // avoids compiler warnings + } } // ----------------------------------------------------------- void MouseActions::MReleaseMoveText(Schematic *Doc, QMouseEvent *Event) { - if(Event->button() != Qt::LeftButton) return; + if (Event->button() != Qt::LeftButton) + return; - QucsMain->MouseMoveAction = &MouseActions::MMoveMoveTextB; - QucsMain->MouseReleaseAction = 0; - Doc->releaseKeyboard(); // allow keyboard inputs again + QucsMain->MouseMoveAction = &MouseActions::MMoveMoveTextB; + QucsMain->MouseReleaseAction = 0; + Doc->releaseKeyboard(); // allow keyboard inputs again - ((Component*)focusElement)->tx = MAx1 - ((Component*)focusElement)->cx; - ((Component*)focusElement)->ty = MAy1 - ((Component*)focusElement)->cy; - Doc->viewport()->update(); - drawn = false; - Doc->setChanged(true, true); + ((Component *) focusElement)->tx = MAx1 - ((Component *) focusElement)->cx; + ((Component *) focusElement)->ty = MAy1 - ((Component *) focusElement)->cy; + Doc->viewport()->update(); + drawn = false; + Doc->setChanged(true, true); } // ----------------------------------------------------------- void MouseActions::MReleaseZoomIn(Schematic *Doc, QMouseEvent *Event) { - if(Event->button() != Qt::LeftButton) return; - - MAx1 = Event->pos().x(); - MAy1 = Event->pos().y(); - float DX = float(MAx2); - float DY = float(MAy2); - - float initialScale = Doc->Scale; - float scale = 1; - float xShift = 0; - float yShift = 0; - if((Doc->Scale * DX) < 6.0) { - // a simple click zooms by constant factor - scale = Doc->zoom(1.5)/initialScale; - - xShift = scale * Event->pos().x(); - yShift = scale * Event->pos().y(); - } else { - float xScale = float(Doc->visibleWidth()) / std::abs(DX); - float yScale = float(Doc->visibleHeight()) / std::abs(DY); - scale = qMin(xScale, yScale)/initialScale; - scale = Doc->zoom(scale)/initialScale; - - xShift = scale * (MAx1 - 0.5*DX); - yShift = scale * (MAy1 - 0.5*DY); - } - xShift -= (0.5*Doc->visibleWidth() + Doc->contentsX()); - yShift -= (0.5*Doc->visibleHeight() + Doc->contentsY()); - Doc->scrollBy(xShift, yShift); - - QucsMain->MouseMoveAction = &MouseActions::MMoveZoomIn; - QucsMain->MouseReleaseAction = 0; - Doc->releaseKeyboard(); // allow keyboard inputs again -} + if (Event->button() != Qt::LeftButton) + return; + + MAx1 = Event->pos().x(); + MAy1 = Event->pos().y(); + float DX = float(MAx2); + float DY = float(MAy2); + + float initialScale = Doc->Scale; + float scale = 1; + float xShift = 0; + float yShift = 0; + if ((Doc->Scale * DX) < 6.0) { + // a simple click zooms by constant factor + scale = Doc->zoom(1.5) / initialScale; + + xShift = scale * Event->pos().x(); + yShift = scale * Event->pos().y(); + } else { + float xScale = float(Doc->visibleWidth()) / std::abs(DX); + float yScale = float(Doc->visibleHeight()) / std::abs(DY); + scale = qMin(xScale, yScale) / initialScale; + scale = Doc->zoom(scale) / initialScale; + + xShift = scale * (MAx1 - 0.5 * DX); + yShift = scale * (MAy1 - 0.5 * DY); + } + xShift -= (0.5 * Doc->visibleWidth() + Doc->contentsX()); + yShift -= (0.5 * Doc->visibleHeight() + Doc->contentsY()); + Doc->scrollBy(xShift, yShift); + QucsMain->MouseMoveAction = &MouseActions::MMoveZoomIn; + QucsMain->MouseReleaseAction = 0; + Doc->releaseKeyboard(); // allow keyboard inputs again +} // *********************************************************************** // ********** ********** @@ -1914,146 +1979,146 @@ void MouseActions::MReleaseZoomIn(Schematic *Doc, QMouseEvent *Event) // *********************************************************************** void MouseActions::editElement(Schematic *Doc, QMouseEvent *Event) { -// qDebug() << "+double click, editElement"; + // qDebug() << "+double click, editElement"; - if(focusElement == 0) return; + if (focusElement == 0) + return; -// qDebug() << "+focusElement->Type" << focusElement->Type; + // qDebug() << "+focusElement->Type" << focusElement->Type; - Graph *pg; - Component *c; - Diagram *dia; - DiagramDialog *ddia; - MarkerDialog *mdia; - int x1, y1, x2, y2; + Graph *pg; + Component *c; + Diagram *dia; + DiagramDialog *ddia; + MarkerDialog *mdia; + int x1, y1, x2, y2; - QFileInfo Info(Doc->DocName); - float fX = DOC_X_FPOS, fY = DOC_Y_FPOS; + QFileInfo Info(Doc->DocName); + float fX = DOC_X_FPOS, fY = DOC_Y_FPOS; - switch(focusElement->Type) { + switch (focusElement->Type) { case isComponent: case isAnalogComponent: case isDigitalComponent: - c = (Component*)focusElement; -// qDebug() << "cast focusElement into" << c->Name; - if(c->Model == "GND") return; - - if ((c->Model == ".CUSTOMSIM")|| - (c->Model == ".XYCESCR") || - (c->Model == "INCLSCR")) { - CustomSimDialog *sd = new CustomSimDialog((SpiceCustomSim*)c, Doc); - if(sd->exec() != 1) break; // dialog is WDestructiveClose - } else if(c->Model == "SPICE") { - SpiceDialog *sd = new SpiceDialog(App, (SpiceFile*)c, Doc); - if(sd->exec() != 1) break; // dialog is WDestructiveClose - } - else if(c->Model == ".Opt") { - OptimizeDialog *od = new OptimizeDialog((Optimize_Sim*)c, Doc); - if(od->exec() != 1) break; // dialog is WDestructiveClose - } - else if (c->Model == "SPICEINIT") { - TextBoxDialog *od = new TextBoxDialog("Edit .spiceinit configuration", c, Doc); - if (od->exec() != 1) break; // dialog is WDestructiveClose - } - else { - ComponentDialog * cd = new ComponentDialog(c, Doc); - if(cd->exec() != 1) break; // dialog is WDestructiveClose - - Doc->Components->findRef(c); - Doc->Components->take(); - Doc->setComponentNumber(c); // for ports/power sources - Doc->Components->append(c); - } - - Doc->setChanged(true, true); - c->entireBounds(x1,y1,x2,y2, Doc->textCorr()); - Doc->enlargeView(x1,y1,x2,y2); - break; - - case isDiagram : - dia = (Diagram*)focusElement; - if(dia->Name.at(0) == 'T') { // don't open dialog on scrollbar - if(dia->Name == "Time") { - if(dia->cy < int(fY)) { - if(((TimingDiagram*)focusElement)->scroll(MAx1)) - Doc->setChanged(true, true, 'm'); // 'm' = only the first time - break; - } - } - else { - if(dia->cx > int(fX)) { - if(((TabDiagram*)focusElement)->scroll(MAy1)) - Doc->setChanged(true, true, 'm'); // 'm' = only the first time - break; - } - } - } - - ddia = new DiagramDialog(dia, Doc); - if(ddia->exec() != QDialog::Rejected) // is WDestructiveClose - Doc->setChanged(true, true); - - dia->Bounding(x1, x2, y1, y2); - Doc->enlargeView(x1, x2, y1, y2); - break; - - case isGraph : - pg = (Graph*)focusElement; - // searching diagram for this graph - for(dia = Doc->Diagrams->last(); dia != 0; dia = Doc->Diagrams->prev()) - if(dia->Graphs.indexOf(pg) >= 0) - break; - if(!dia) break; - - - ddia = new DiagramDialog(dia, Doc, pg); - if(ddia->exec() != QDialog::Rejected) // is WDestructiveClose - Doc->setChanged(true, true); - break; + c = (Component *) focusElement; + // qDebug() << "cast focusElement into" << c->Name; + if (c->Model == "GND") + return; + + if ((c->Model == ".CUSTOMSIM") || (c->Model == ".XYCESCR") || (c->Model == "INCLSCR")) { + CustomSimDialog *sd = new CustomSimDialog((SpiceCustomSim *) c, Doc); + if (sd->exec() != 1) + break; // dialog is WDestructiveClose + } else if (c->Model == "SPICE") { + SpiceDialog *sd = new SpiceDialog(App, (SpiceFile *) c, Doc); + if (sd->exec() != 1) + break; // dialog is WDestructiveClose + } else if (c->Model == ".Opt") { + OptimizeDialog *od = new OptimizeDialog((Optimize_Sim *) c, Doc); + if (od->exec() != 1) + break; // dialog is WDestructiveClose + } else if (c->Model == "SPICEINIT") { + TextBoxDialog *od = new TextBoxDialog("Edit .spiceinit configuration", c, Doc); + if (od->exec() != 1) + break; // dialog is WDestructiveClose + } else { + ComponentDialog *cd = new ComponentDialog(c, Doc); + if (cd->exec() != 1) + break; // dialog is WDestructiveClose + + Doc->Components->findRef(c); + Doc->Components->take(); + Doc->setComponentNumber(c); // for ports/power sources + Doc->Components->append(c); + } + + Doc->setChanged(true, true); + c->entireBounds(x1, y1, x2, y2, Doc->textCorr()); + Doc->enlargeView(x1, y1, x2, y2); + break; + + case isDiagram: + dia = (Diagram *) focusElement; + if (dia->Name.at(0) == 'T') { // don't open dialog on scrollbar + if (dia->Name == "Time") { + if (dia->cy < int(fY)) { + if (((TimingDiagram *) focusElement)->scroll(MAx1)) + Doc->setChanged(true, true, 'm'); // 'm' = only the first time + break; + } + } else { + if (dia->cx > int(fX)) { + if (((TabDiagram *) focusElement)->scroll(MAy1)) + Doc->setChanged(true, true, 'm'); // 'm' = only the first time + break; + } + } + } + + ddia = new DiagramDialog(dia, Doc); + if (ddia->exec() != QDialog::Rejected) // is WDestructiveClose + Doc->setChanged(true, true); + + dia->Bounding(x1, x2, y1, y2); + Doc->enlargeView(x1, x2, y1, y2); + break; + + case isGraph: + pg = (Graph *) focusElement; + // searching diagram for this graph + for (dia = Doc->Diagrams->last(); dia != 0; dia = Doc->Diagrams->prev()) + if (dia->Graphs.indexOf(pg) >= 0) + break; + if (!dia) + break; + + ddia = new DiagramDialog(dia, Doc, pg); + if (ddia->exec() != QDialog::Rejected) // is WDestructiveClose + Doc->setChanged(true, true); + break; case isWire: - MPressLabel(Doc, Event, fX, fY); - break; + MPressLabel(Doc, Event, fX, fY); + break; case isNodeLabel: case isHWireLabel: case isVWireLabel: - editLabel(Doc, (WireLabel*)focusElement); - // update highlighting, labels may have changed - Doc->highlightWireLabels (); - break; + editLabel(Doc, (WireLabel *) focusElement); + // update highlighting, labels may have changed + Doc->highlightWireLabels(); + break; case isPainting: - if( ((Painting*)focusElement)->Dialog() ) - Doc->setChanged(true, true); - break; + if (((Painting *) focusElement)->Dialog()) + Doc->setChanged(true, true); + break; case isMarker: - mdia = new MarkerDialog((Marker*)focusElement, Doc); - if(mdia->exec() > 1) - Doc->setChanged(true, true); - break; - } - - // Very strange: Now an open VHDL editor gets all the keyboard input !?! - // I don't know why it only happens here, nor am I sure whether it only - // happens here. Anyway, I hope the best and give the focus back to the - // current document. - Doc->setFocus(); - - Doc->viewport()->update(); - drawn = false; + mdia = new MarkerDialog((Marker *) focusElement, Doc); + if (mdia->exec() > 1) + Doc->setChanged(true, true); + break; + } + + // Very strange: Now an open VHDL editor gets all the keyboard input !?! + // I don't know why it only happens here, nor am I sure whether it only + // happens here. Anyway, I hope the best and give the focus back to the + // current document. + Doc->setFocus(); + + Doc->viewport()->update(); + drawn = false; } // ----------------------------------------------------------- void MouseActions::MDoubleClickSelect(Schematic *Doc, QMouseEvent *Event) { - Doc->releaseKeyboard(); // allow keyboard inputs again - QucsMain->editText->setHidden(true); - editElement(Doc, Event); + Doc->releaseKeyboard(); // allow keyboard inputs again + QucsMain->editText->setHidden(true); + editElement(Doc, Event); } - /** * @brief MouseActions::MDoubleClickWire2 Double click terminates wire insertion. * @param Doc @@ -2061,68 +2126,75 @@ void MouseActions::MDoubleClickSelect(Schematic *Doc, QMouseEvent *Event) */ void MouseActions::MDoubleClickWire2(Schematic *Doc, QMouseEvent *Event) { - MPressWire2(Doc, Event, DOC_X_FPOS, DOC_Y_FPOS); + MPressWire2(Doc, Event, DOC_X_FPOS, DOC_Y_FPOS); - if(formerAction) - QucsMain->select->setChecked(true); // restore old action - else { - QucsMain->MouseMoveAction = &MouseActions::MMoveWire1; - QucsMain->MousePressAction = &MouseActions::MPressWire1; - QucsMain->MouseDoubleClickAction = 0; - } + if (formerAction) + QucsMain->select->setChecked(true); // restore old action + else { + QucsMain->MouseMoveAction = &MouseActions::MMoveWire1; + QucsMain->MousePressAction = &MouseActions::MPressWire1; + QucsMain->MouseDoubleClickAction = 0; + } } void MouseActions::MPressTune(Schematic *Doc, QMouseEvent *Event, float fX, float fY) { Q_UNUSED(Event); - int No=0; + int No = 0; MAx1 = int(fX); MAy1 = int(fY); focusElement = Doc->selectElement(fX, fY, false, &No); - isMoveEqual = false; // moving not neccessarily square + isMoveEqual = false; // moving not neccessarily square - if(focusElement) - // print define value in hex, see element.h - qDebug() << "MPressTune: focusElement->Type" << QString("0x%1").arg(focusElement->Type, 0, 16); + if (focusElement) + // print define value in hex, see element.h + qDebug() << "MPressTune: focusElement->Type" + << QString("0x%1").arg(focusElement->Type, 0, 16); else - qDebug() << "MPressTune"; + qDebug() << "MPressTune"; - if(focusElement && App->TuningMode) - { + if (focusElement && App->TuningMode) { Component *pc = nullptr; Property *pp = nullptr; - switch(focusElement->Type) - { + switch (focusElement->Type) { case isComponent: // pick first property if device is clicked (i.e. R,C) case isAnalogComponent: - pc = (Component*)focusElement; - if(!pc) return; - if (pc->Props.isEmpty()) return; + pc = (Component *) focusElement; + if (!pc) + return; + if (pc->Props.isEmpty()) + return; pp = pc->Props.at(0); break; - case isComponentText: // property text of component ? + case isComponentText: // property text of component ? focusElement->Type &= (~isComponentText) | isComponent; - pc = (Component*)focusElement; + pc = (Component *) focusElement; pp = 0; - if(!pc) return; // should never happen + if (!pc) + return; // should never happen // current property if (No > 0) { - No--;// No counts also the on/screen component Name, so subtract 1 to get the actual property number + No--; // No counts also the on/screen component Name, so subtract 1 to get the actual property number pp = pc->Props.at(No); } - if (!pp) return; // should not happen + if (!pp) + return; // should not happen break; - default: return; + default: + return; } - if (pc == nullptr || pp == nullptr ) return; - if (!App->tunerDia->containsProperty(pp) ) { + if (pc == nullptr || pp == nullptr) + return; + if (!App->tunerDia->containsProperty(pp)) { if (checkProperty(pc, pp)) { tunerElement *tune = new tunerElement(App->tunerDia, pc, pp, No); tune->schematicName = Doc->DocName; - if (tune != NULL) App->tunerDia->addTunerElement(tune);//Tunable property + if (tune != NULL) + App->tunerDia->addTunerElement(tune); //Tunable property } else { - QMessageBox::warning(nullptr, "Property not correct", + QMessageBox::warning(nullptr, + "Property not correct", "You selected a non-tunable property", QMessageBox::Ok); return; diff --git a/qucs/paintings/arrow.cpp b/qucs/paintings/arrow.cpp index 4759a38d6..aca5a6739 100644 --- a/qucs/paintings/arrow.cpp +++ b/qucs/paintings/arrow.cpp @@ -439,22 +439,33 @@ void Arrow::Bounding(int& _x1, int& _y1, int& _x2, int& _y2) // -------------------------------------------------------------------------- // Rotates around the center. -void Arrow::rotate() +void Arrow::rotate(int xc, int yc) { - cx += (x2>>1) - (y2>>1); - cy += (x2>>1) + (y2>>1); - - int tmp = x2; - x2 = y2; - y2 = -tmp; - - tmp = xp1; - xp1 = yp1; - yp1 = -tmp; - - tmp = xp2; - xp2 = yp2; - yp2 = -tmp; + int xr1 = cx - xc; + int yr1 = cy - yc; + int xr2 = cx + x2 - xc; + int yr2 = cy + y2 - yc; + + int tmp = xr2; + xr2 = yr2; + yr2 = -tmp; + + tmp = xr1; + xr1 = yr1; + yr1 = -tmp; + + cx = xr1 + xc; + cy = yr1 + yc; + x2 = xr2 - xr1; + y2 = yr2 - yr1; + + tmp = xp1; + xp1 = yp1; + yp1 = -tmp; + + tmp = xp2; + xp2 = yp2; + yp2 = -tmp; } // -------------------------------------------------------------------------- diff --git a/qucs/paintings/arrow.h b/qucs/paintings/arrow.h index e2c21be2b..a6f8b2d94 100644 --- a/qucs/paintings/arrow.h +++ b/qucs/paintings/arrow.h @@ -46,7 +46,7 @@ class Arrow : public Painting { bool resizeTouched(float, float, float); void MouseResizeMoving(int, int, Schematic*); - void rotate(); + void rotate(int, int); void mirrorX(); void mirrorY(); bool Dialog(); diff --git a/qucs/paintings/ellipse.cpp b/qucs/paintings/ellipse.cpp index b253218b1..21d084a65 100644 --- a/qucs/paintings/ellipse.cpp +++ b/qucs/paintings/ellipse.cpp @@ -341,13 +341,25 @@ bool qucs::Ellipse::getSelected(float fX, float fY, float w) // -------------------------------------------------------------------------- // Rotates around the center. -void qucs::Ellipse::rotate() +void qucs::Ellipse::rotate(int xc, int yc) { - cy += (y2-x2) >> 1; - cx += (x2-y2) >> 1; - int tmp = x2; - x2 = y2; - y2 = tmp; + int xr1 = cx - xc; + int yr1 = cy - yc; + int xr2 = cx + x2 - xc; + int yr2 = cy + y2 - yc; + + int tmp = xr2; + xr2 = yr2; + yr2 = -tmp; + + tmp = xr1; + xr1 = yr1; + yr1 = -tmp; + + cx = xr1 + xc; + cy = yr1 + yc; + x2 = xr2 - xr1; + y2 = yr2 - yr1; } // -------------------------------------------------------------------------- diff --git a/qucs/paintings/ellipse.h b/qucs/paintings/ellipse.h index 0d15fffc8..9cccfc306 100644 --- a/qucs/paintings/ellipse.h +++ b/qucs/paintings/ellipse.h @@ -47,7 +47,7 @@ class Ellipse : public Painting { bool resizeTouched(float, float, float); void MouseResizeMoving(int, int, Schematic*); - void rotate(); + void rotate(int, int); void mirrorX(); void mirrorY(); bool Dialog(); diff --git a/qucs/paintings/ellipsearc.cpp b/qucs/paintings/ellipsearc.cpp index 1ed8f4b17..e94f0e4ad 100644 --- a/qucs/paintings/ellipsearc.cpp +++ b/qucs/paintings/ellipsearc.cpp @@ -345,16 +345,29 @@ bool EllipseArc::getSelected(float fX, float fY, float w) // -------------------------------------------------------------------------- // Rotates around the center. -void EllipseArc::rotate() +// Rotates around the center. +void EllipseArc::rotate(int xc, int yc) { - cy += (y2-x2) >> 1; - cx += (x2-y2) >> 1; - int tmp = x2; - x2 = y2; - y2 = tmp; - - Angle += 16*90; - if(Angle >= 16*360) Angle -= 16*360; + int xr1 = cx - xc; + int yr1 = cy - yc; + int xr2 = cx + x2 - xc; + int yr2 = cy + y2 - yc; + + int tmp = xr2; + xr2 = yr2; + yr2 = -tmp; + + tmp = xr1; + xr1 = yr1; + yr1 = -tmp; + + cx = xr1 + xc; + cy = yr1 + yc; + x2 = xr2 - xr1; + y2 = yr2 - yr1; + + Angle += 16*90; + if(Angle >= 16*360) Angle -= 16*360; } // -------------------------------------------------------------------------- diff --git a/qucs/paintings/ellipsearc.h b/qucs/paintings/ellipsearc.h index 26fd55722..9984c1ec4 100644 --- a/qucs/paintings/ellipsearc.h +++ b/qucs/paintings/ellipsearc.h @@ -45,7 +45,7 @@ class EllipseArc : public Painting { bool resizeTouched(float, float, float); void MouseResizeMoving(int, int, Schematic*); - void rotate(); + void rotate(int, int); void mirrorX(); void mirrorY(); bool Dialog(); diff --git a/qucs/paintings/graphicline.cpp b/qucs/paintings/graphicline.cpp index fb8007763..24428b215 100644 --- a/qucs/paintings/graphicline.cpp +++ b/qucs/paintings/graphicline.cpp @@ -291,14 +291,25 @@ void GraphicLine::Bounding(int& _x1, int& _y1, int& _x2, int& _y2) // -------------------------------------------------------------------------- // Rotates around the center. -void GraphicLine::rotate() +void GraphicLine::rotate(int xc, int yc) { - cx += (x2>>1) - (y2>>1); - cy += (x2>>1) + (y2>>1); - - int tmp = x2; - x2 = y2; - y2 = -tmp; + int xr1 = cx - xc; + int yr1 = cy - yc; + int xr2 = cx + x2 - xc; + int yr2 = cy + y2 - yc; + + int tmp = xr2; + xr2 = yr2; + yr2 = -tmp; + + tmp = xr1; + xr1 = yr1; + yr1 = -tmp; + + cx = xr1 + xc; + cy = yr1 + yc; + x2 = xr2 - xr1; + y2 = yr2 - yr1; } // -------------------------------------------------------------------------- diff --git a/qucs/paintings/graphicline.h b/qucs/paintings/graphicline.h index a228c97e7..f66490ab7 100644 --- a/qucs/paintings/graphicline.h +++ b/qucs/paintings/graphicline.h @@ -47,7 +47,7 @@ class GraphicLine : public Painting { bool resizeTouched(float, float, float); void MouseResizeMoving(int, int, Schematic*); - void rotate(); + void rotate(int, int); void mirrorX(); void mirrorY(); bool Dialog(); diff --git a/qucs/paintings/graphictext.cpp b/qucs/paintings/graphictext.cpp index 7d0e308a6..0da235324 100644 --- a/qucs/paintings/graphictext.cpp +++ b/qucs/paintings/graphictext.cpp @@ -14,239 +14,253 @@ * (at your option) any later version. * * * ***************************************************************************/ -#include "main.h" -#include "mnemo.h" -#include "viewpainter.h" #include "graphictext.h" #include "graphictextdialog.h" -#include "schematic.h" +#include "main.h" #include "misc.h" +#include "mnemo.h" +#include "schematic.h" +#include "viewpainter.h" +#include #include #include -#include #include #include GraphicText::GraphicText() { - Name = "Text "; - isSelected = false; - Color = QColor(0,0,0); - Font = QucsSettings.font; - cx = cy = 0; - x1 = x2 = 0; - y1 = y2 = 0; - Angle = 0; + Name = "Text "; + isSelected = false; + Color = QColor(0, 0, 0); + Font = QucsSettings.font; + cx = cy = 0; + x1 = x2 = 0; + y1 = y2 = 0; + Angle = 0; } -GraphicText::~GraphicText() -{ -} +GraphicText::~GraphicText() {} // ----------------------------------------------------------------------- void GraphicText::paint(ViewPainter *p) { - // keep track of painter state - p->Painter->save(); + // keep track of painter state + p->Painter->save(); - QTransform wm = p->Painter->worldTransform(); - QTransform Mat(1.0, 0.0, 0.0, 1.0, p->DX + qreal(cx) * p->Scale, - p->DY + qreal(cy) * p->Scale); - p->Painter->setWorldTransform(Mat); - p->Painter->rotate(-Angle); // automatically enables transformation + QTransform wm = p->Painter->worldTransform(); + QTransform Mat(1.0, 0.0, 0.0, 1.0, p->DX + qreal(cx) * p->Scale, p->DY + qreal(cy) * p->Scale); + p->Painter->setWorldTransform(Mat); + p->Painter->rotate(-Angle); // automatically enables transformation - int Size = Font.pointSize(); + int Size = Font.pointSize(); #ifdef __MINGW32__ - Font.setPointSizeF( (p->FontScale / p->PrintScale) * float(Size)); + Font.setPointSizeF((p->FontScale / p->PrintScale) * float(Size)); #else - Font.setPointSizeF( p->FontScale * float(Size)); + Font.setPointSizeF(p->FontScale * float(Size)); #endif - QFont f = p->Painter->font(); - p->Painter->setPen(Color); - p->Painter->setFont(Font); + QFont f = p->Painter->font(); + p->Painter->setPen(Color); + p->Painter->setFont(Font); - // Because of a bug in Qt 3.1, drawing this text is dangerous, if it - // contains linefeeds. Qt has problems with linefeeds. It remembers the - // last font metrics (within the font ???) and does not calculate it again. - // The error often appears at a very different drawText function !!! - int w, h; - w = p->drawTextMapped(Text, 0, 0, &h); + // Because of a bug in Qt 3.1, drawing this text is dangerous, if it + // contains linefeeds. Qt has problems with linefeeds. It remembers the + // last font metrics (within the font ???) and does not calculate it again. + // The error often appears at a very different drawText function !!! + int w, h; + w = p->drawTextMapped(Text, 0, 0, &h); - if(isSelected) { - p->Painter->setPen(QPen(Qt::darkGray,3)); - p->Painter->drawRect(-3, -2, w+6, h+5); - } + if (isSelected) { + p->Painter->setPen(QPen(Qt::darkGray, 3)); + p->Painter->drawRect(-3, -2, w + 6, h + 5); + } - Font.setPointSize(Size); // restore real font size - p->Painter->setWorldTransform(wm); - p->Painter->setWorldMatrixEnabled(false); + Font.setPointSize(Size); // restore real font size + p->Painter->setWorldTransform(wm); + p->Painter->setWorldMatrixEnabled(false); - // restore painter state - p->Painter->restore(); + // restore painter state + p->Painter->restore(); - x2 = int(float(w) / p->Scale); - y2 = int(float(h) / p->Scale); - p->Painter->setFont(f); + x2 = int(float(w) / p->Scale); + y2 = int(float(h) / p->Scale); + p->Painter->setFont(f); } // ----------------------------------------------------------------------- void GraphicText::paintScheme(Schematic *p) { - // FIXME #warning QMatrix wm = p->worldMatrix(); - // FIXME #warning QMatrix Mat (wm.m11(), 0.0, 0.0, wm.m22(), -// FIXME #warning wm.dx() + double(cx) * wm.m11(), -// FIXME #warning wm.dy() + double(cy) * wm.m22()); - // FIXME #warning p->setWorldMatrix(Mat); - // FIXME #warning p->rotate(-Angle); - p->PostPaintEvent(_Rect, 0, 0, x2, y2); - - // FIXME #warning p->setWorldMatrix(wm); + // FIXME #warning QMatrix wm = p->worldMatrix(); + // FIXME #warning QMatrix Mat (wm.m11(), 0.0, 0.0, wm.m22(), + // FIXME #warning wm.dx() + double(cx) * wm.m11(), + // FIXME #warning wm.dy() + double(cy) * wm.m22()); + // FIXME #warning p->setWorldMatrix(Mat); + // FIXME #warning p->rotate(-Angle); + p->PostPaintEvent(_Rect, cx, cy, x2, y2); + + // FIXME #warning p->setWorldMatrix(wm); } // ------------------------------------------------------------------------ -void GraphicText::getCenter(int& x, int &y) +void GraphicText::getCenter(int &x, int &y) { - x = cx+(x2>>1); - y = cy+(y2>>1); + x = cx + (x2 >> 1); + y = cy + (y2 >> 1); } // ----------------------------------------------------------------------- // Sets the center of the painting to x/y. void GraphicText::setCenter(int x, int y, bool relative) { - if(relative) { cx += x; cy += y; } - else { cx = x-(x2>>1); cy = y-(y2>>1); } + if (relative) { + cx += x; + cy += y; + } else { + cx = x - (x2 >> 1); + cy = y - (y2 >> 1); + } } // ----------------------------------------------------------------------- -Painting* GraphicText::newOne() +Painting *GraphicText::newOne() { - return new GraphicText(); + return new GraphicText(); } // -------------------------------------------------------------------------- -Element* GraphicText::info(QString& Name, char* &BitmapFile, bool getNewOne) +Element *GraphicText::info(QString &Name, char *&BitmapFile, bool getNewOne) { - Name = QObject::tr("Text"); - BitmapFile = (char *) "text"; + Name = QObject::tr("Text"); + BitmapFile = (char *) "text"; - if(getNewOne) return new GraphicText(); - return 0; + if (getNewOne) + return new GraphicText(); + return 0; } // ----------------------------------------------------------------------- -bool GraphicText::load(const QString& s) +bool GraphicText::load(const QString &s) { - bool ok; - - QString n; - n = s.section(' ',1,1); // cx - cx = n.toInt(&ok); - if(!ok) return false; - - n = s.section(' ',2,2); // cy - cy = n.toInt(&ok); - if(!ok) return false; - - n = s.section(' ',3,3); // Size - Font.setPointSize(n.toInt(&ok)); - if(!ok) return false; - - n = s.section(' ',4,4); // Color - Color = misc::ColorFromString(n); - if(!Color.isValid()) return false; + bool ok; + + QString n; + n = s.section(' ', 1, 1); // cx + cx = n.toInt(&ok); + if (!ok) + return false; + + n = s.section(' ', 2, 2); // cy + cy = n.toInt(&ok); + if (!ok) + return false; + + n = s.section(' ', 3, 3); // Size + Font.setPointSize(n.toInt(&ok)); + if (!ok) + return false; + + n = s.section(' ', 4, 4); // Color + Color = misc::ColorFromString(n); + if (!Color.isValid()) + return false; + + n = s.section(' ', 5, 5); // Angle + Angle = n.toInt(&ok); + if (!ok) + return false; + + Text = s.mid(s.indexOf('"') + 1); // Text (can contain " !!!) + Text.truncate(Text.length() - 1); + if (Text.isEmpty()) + return false; + + misc::convert2Unicode(Text); + // get size of text using the screen-compatible metric + QFontMetrics metrics(QucsSettings.font, 0); + QSize r = metrics.size(0, Text); // get overall size of text + x2 = r.width(); + y2 = r.height(); - n = s.section(' ',5,5); // Angle - Angle = n.toInt(&ok); - if(!ok) return false; - - Text = s.mid(s.indexOf('"')+1); // Text (can contain " !!!) - Text.truncate(Text.length()-1); - if(Text.isEmpty()) return false; - - misc::convert2Unicode(Text); - // get size of text using the screen-compatible metric - QFontMetrics metrics(QucsSettings.font, 0); - QSize r = metrics.size(0, Text); // get overall size of text - x2 = r.width(); - y2 = r.height(); - - return true; + return true; } // ----------------------------------------------------------------------- QString GraphicText::save() { - QString t = Text; - misc::convert2ASCII(t); - - // The 'Text' property has to be the last within the line ! - QString s = Name+QString::number(cx)+" "+QString::number(cy)+" " - + QString::number(Font.pointSize())+" "+Color.name()+" " - + QString::number(Angle) + " \""+t+"\""; - return s; + QString t = Text; + misc::convert2ASCII(t); + + // The 'Text' property has to be the last within the line ! + QString s = Name + QString::number(cx) + " " + QString::number(cy) + " " + + QString::number(Font.pointSize()) + " " + Color.name() + " " + + QString::number(Angle) + " \"" + t + "\""; + return s; } // -------------------------------------------------------------------------- QString GraphicText::saveCpp() { - QString t = Text; - misc::convert2ASCII(t); - - QString s = - QString ("new Text (%1, %2, \"%3\", QColor (\"%4\"), %5, %6, %7)"). - arg(cx).arg(cy).arg(t). - arg(Color.name()).arg(Font.pointSize()). - arg(cos(pi * Angle / 180.0)).arg(sin(pi * Angle / 180.0)); - s = "Texts.append (" + s + ");"; - return s; + QString t = Text; + misc::convert2ASCII(t); + + QString s = QString("new Text (%1, %2, \"%3\", QColor (\"%4\"), %5, %6, %7)") + .arg(cx) + .arg(cy) + .arg(t) + .arg(Color.name()) + .arg(Font.pointSize()) + .arg(cos(pi * Angle / 180.0)) + .arg(sin(pi * Angle / 180.0)); + s = "Texts.append (" + s + ");"; + return s; } QString GraphicText::saveJSON() { - QString t = Text; - misc::convert2ASCII(t); - - QString s = - QString ("{\"type\" : \"graphictext\", " - "\"x\" : %1, \"y\" : %2, \"s\" : \"%3\", " - "\"color\" : \"%4\", \"size\" : %5, \"cos\" : %6, \"sin\" : %7},"). - arg(cx).arg(cy).arg(t). - arg(Color.name()).arg(Font.pointSize()). - arg(cos(pi * Angle / 180.0)).arg(sin(pi * Angle / 180.0)); - return s; + QString t = Text; + misc::convert2ASCII(t); + + QString s = QString("{\"type\" : \"graphictext\", " + "\"x\" : %1, \"y\" : %2, \"s\" : \"%3\", " + "\"color\" : \"%4\", \"size\" : %5, \"cos\" : %6, \"sin\" : %7},") + .arg(cx) + .arg(cy) + .arg(t) + .arg(Color.name()) + .arg(Font.pointSize()) + .arg(cos(pi * Angle / 180.0)) + .arg(sin(pi * Angle / 180.0)); + return s; } // ----------------------------------------------------------------------- // fx/fy are the precise coordinates, gx/gy are the coordinates set on grid. // x/y are coordinates without scaling. void GraphicText::MouseMoving( - Schematic*, int, int, int gx, int gy, - Schematic *p, int x, int y, bool drawn) + Schematic *, int, int, int gx, int gy, Schematic *p, int x, int y, bool drawn) { - // FIXME #warning p->setPen(Qt::SolidLine); - if(drawn) { - p->PostPaintEvent(_Line, x1+15, y1+15, x1+20, y1,0,0,true); // erase old cursor symbol - p->PostPaintEvent(_Line, x1+26, y1+15, x1+21, y1,0,0,true); - p->PostPaintEvent(_Line, x1+17, y1+8, x1+23, y1+8,0,0,true); - } - x1 = x; - y1 = y; - p->PostPaintEvent(_Line, x1+15, y1+15, x1+20, y1,0,0,true); // paint new cursor symbol - p->PostPaintEvent(_Line, x1+26, y1+15, x1+21, y1,0,0,true); - p->PostPaintEvent(_Line, x1+17, y1+8, x1+23, y1+8,0,0,true); - - cx = gx; - cy = gy; + // FIXME #warning p->setPen(Qt::SolidLine); + if (drawn) { + p->PostPaintEvent(_Line, x1 + 15, y1 + 15, x1 + 20, y1, 0, 0, true); // erase old cursor symbol + p->PostPaintEvent(_Line, x1 + 26, y1 + 15, x1 + 21, y1, 0, 0, true); + p->PostPaintEvent(_Line, x1 + 17, y1 + 8, x1 + 23, y1 + 8, 0, 0, true); + } + x1 = x; + y1 = y; + p->PostPaintEvent(_Line, x1 + 15, y1 + 15, x1 + 20, y1, 0, 0, true); // paint new cursor symbol + p->PostPaintEvent(_Line, x1 + 26, y1 + 15, x1 + 21, y1, 0, 0, true); + p->PostPaintEvent(_Line, x1 + 17, y1 + 8, x1 + 23, y1 + 8, 0, 0, true); + + cx = gx; + cy = gy; } // ------------------------------------------------------------------------ bool GraphicText::MousePressing() { - return Dialog(); + return Dialog(); } // ------------------------------------------------------------------------ @@ -254,69 +268,106 @@ bool GraphicText::MousePressing() // 5 is the precision the user must point onto the painting. bool GraphicText::getSelected(float fX, float fY, float) { - double phi = pi/180.0*double(Angle); - float sine = sin(phi), cosine = cos(phi); + double phi = pi / 180.0 * double(Angle); + float sine = sin(phi), cosine = cos(phi); - fX -= float(cx); - fY -= float(cy); - int _x = int( fX*cosine - fY*sine ); - int _y = int( fY*cosine + fX*sine ); + fX -= float(cx); + fY -= float(cy); + int _x = int(fX * cosine - fY * sine); + int _y = int(fY * cosine + fX * sine); - if(_x >= 0) if(_y >= 0) if(_x <= x2) if(_y <= y2) - return true; + if (_x >= 0) + if (_y >= 0) + if (_x <= x2) + if (_y <= y2) + return true; - return false; + return false; } // ------------------------------------------------------------------------ -void GraphicText::Bounding(int& xmin, int& ymin, int& xmax, int& ymax) +void GraphicText::Bounding(int &xmin, int &ymin, int &xmax, int &ymax) { - double phi = pi/180.0*double(Angle); - double sine = sin(phi), cosine = cos(phi); - int dx = int( double(y2) * sine ); - int dy = int( double(y2) * cosine ); - xmin = dx; xmax = cx; - ymin = dy; ymax = cy; - if(xmin < 0) xmin += cx; - else { xmax += xmin; xmin = cx; } - if(ymin < 0) ymin += cy; - else { ymax += ymin; ymin = cy; } - - int x = cx + int( double(x2) * cosine ); - if(xmax < x) xmax = x; - else if(xmin > x) xmin = x; - x += dx; - if(xmax < x) xmax = x; - else if(xmin > x) xmin = x; - - int y = cy - int( double(x2) * sine ); - if(ymax < y) ymax = y; - else if(ymin > y) ymin = y; - y += dy; - if(ymax < y) ymax = y; - else if(ymin > y) ymin = y; + double phi = pi / 180.0 * double(Angle); + double sine = sin(phi), cosine = cos(phi); + int dx = int(double(y2) * sine); + int dy = int(double(y2) * cosine); + xmin = dx; + xmax = cx; + ymin = dy; + ymax = cy; + if (xmin < 0) + xmin += cx; + else { + xmax += xmin; + xmin = cx; + } + if (ymin < 0) + ymin += cy; + else { + ymax += ymin; + ymin = cy; + } + + int x = cx + int(double(x2) * cosine); + if (xmax < x) + xmax = x; + else if (xmin > x) + xmin = x; + x += dx; + if (xmax < x) + xmax = x; + else if (xmin > x) + xmin = x; + + int y = cy - int(double(x2) * sine); + if (ymax < y) + ymax = y; + else if (ymin > y) + ymin = y; + y += dy; + if (ymax < y) + ymax = y; + else if (ymin > y) + ymin = y; } // ----------------------------------------------------------------------- // Rotates around the center. -void GraphicText::rotate() +void GraphicText::rotate(int xc, int yc) { - Angle += 90; - Angle %= 360; - cx -= x2 >> 1; - cy -= y2 >> 1; + int xr1 = cx - xc; + int yr1 = cy - yc; + int xr2 = cx + x2 - xc; + int yr2 = cy + y2 - yc; + + int tmp = xr2; + xr2 = yr2; + yr2 = -tmp; + + tmp = xr1; + xr1 = yr1; + yr1 = -tmp; + + cx = xr1 + xc; + cy = yr1 + yc; + x2 = xr2 - xr1; + y2 = yr2 - yr1; + + Angle += 90; + Angle %= 360; } // ----------------------------------------------------------------------- // Mirrors about center line. void GraphicText::mirrorX() -{ // do not mirror, because unreadable +{ // do not mirror, because unreadable } // ----------------------------------------------------------------------- // Mirrors about center line. void GraphicText::mirrorY() -{ // do not mirror, because unreadable +{ // do not mirror, because unreadable } // ----------------------------------------------------------------------- @@ -324,54 +375,54 @@ void GraphicText::mirrorY() // If there were changes, it returns 'true'. bool GraphicText::Dialog() { - QFont f(QucsSettings.font); // to avoid wrong text width - bool changed = false; + QFont f(QucsSettings.font); // to avoid wrong text width + bool changed = false; - GraphicTextDialog *d = new GraphicTextDialog(); + GraphicTextDialog *d = new GraphicTextDialog(); - QPalette palette; - palette.setColor(d->ColorButt->backgroundRole(), Color); - d->ColorButt->setPalette(palette); + QPalette palette; + palette.setColor(d->ColorButt->backgroundRole(), Color); + d->ColorButt->setPalette(palette); - d->TextSize->setText(QString::number(Font.pointSize())); - d->Angle->setText(QString::number(Angle)); - QString _Text = Text; - decode_String(_Text); // replace special characters with LaTeX commands - d->text->setText(_Text); + d->TextSize->setText(QString::number(Font.pointSize())); + d->Angle->setText(QString::number(Angle)); + QString _Text = Text; + decode_String(_Text); // replace special characters with LaTeX commands + d->text->setText(_Text); - if(d->exec() == QDialog::Rejected) { - delete d; - return false; - } - - if(Color != d->ColorButt->palette().color(d->ColorButt->backgroundRole())) { - Color = d->ColorButt->palette().color(d->ColorButt->backgroundRole()); - changed = true; - } - f.setPointSize(d->TextSize->text().toInt()); // to avoid wrong text width - if(Font.pointSize() != d->TextSize->text().toInt()) { - Font.setPointSize(d->TextSize->text().toInt()); - changed = true; - } - int tmp = d->Angle->text().toInt(); - if(Angle != tmp) { - Angle = tmp % 360; - changed = true; - } - - encode_String(d->text->toPlainText(), _Text); // create special characters - if(!_Text.isEmpty()) - if(_Text != Text) { - Text = _Text; - changed = true; + if (d->exec() == QDialog::Rejected) { + delete d; + return false; } - // get font metric using the screen-compatible metric - QFontMetrics m(f, 0); - QSize s = m.size(0, Text); // get size of text - x2 = s.width(); - y2 = s.height(); + if (Color != d->ColorButt->palette().color(d->ColorButt->backgroundRole())) { + Color = d->ColorButt->palette().color(d->ColorButt->backgroundRole()); + changed = true; + } + f.setPointSize(d->TextSize->text().toInt()); // to avoid wrong text width + if (Font.pointSize() != d->TextSize->text().toInt()) { + Font.setPointSize(d->TextSize->text().toInt()); + changed = true; + } + int tmp = d->Angle->text().toInt(); + if (Angle != tmp) { + Angle = tmp % 360; + changed = true; + } + + encode_String(d->text->toPlainText(), _Text); // create special characters + if (!_Text.isEmpty()) + if (_Text != Text) { + Text = _Text; + changed = true; + } - delete d; - return changed; + // get font metric using the screen-compatible metric + QFontMetrics m(f, 0); + QSize s = m.size(0, Text); // get size of text + x2 = s.width(); + y2 = s.height(); + + delete d; + return changed; } diff --git a/qucs/paintings/graphictext.h b/qucs/paintings/graphictext.h index 0d9b5a595..2dce5c8cf 100644 --- a/qucs/paintings/graphictext.h +++ b/qucs/paintings/graphictext.h @@ -46,7 +46,7 @@ class GraphicText : public Painting { bool getSelected(float, float, float); void Bounding(int&, int&, int&, int&); - void rotate(); + void rotate(int, int); void mirrorX(); void mirrorY(); bool Dialog(); diff --git a/qucs/paintings/id_text.cpp b/qucs/paintings/id_text.cpp index 101d08e3c..983a7f71d 100644 --- a/qucs/paintings/id_text.cpp +++ b/qucs/paintings/id_text.cpp @@ -168,7 +168,7 @@ bool ID_Text::getSelected(float fX, float fY, float) // -------------------------------------------------------------------------- // Rotates around the center. -void ID_Text::rotate() +void ID_Text::rotate(int, int) { } diff --git a/qucs/paintings/id_text.h b/qucs/paintings/id_text.h index d25a5f331..e9a3fb8e5 100644 --- a/qucs/paintings/id_text.h +++ b/qucs/paintings/id_text.h @@ -51,7 +51,7 @@ class ID_Text : public Painting { void paint(ViewPainter*); bool getSelected(float, float, float); - void rotate(); + void rotate(int, int); void mirrorX(); void mirrorY(); bool Dialog(); diff --git a/qucs/paintings/painting.h b/qucs/paintings/painting.h index f60f29a77..45859c0be 100644 --- a/qucs/paintings/painting.h +++ b/qucs/paintings/painting.h @@ -43,7 +43,7 @@ class Painting : public Element { virtual bool resizeTouched(float, float, float) { return false; }; virtual void MouseResizeMoving(int, int, Schematic*) {}; - virtual void rotate() {}; + virtual void rotate(int, int) {}; virtual void mirrorX() {}; virtual void mirrorY() {}; virtual bool Dialog() { return false; }; diff --git a/qucs/paintings/portsymbol.cpp b/qucs/paintings/portsymbol.cpp index 0e3e60f41..6243027a6 100644 --- a/qucs/paintings/portsymbol.cpp +++ b/qucs/paintings/portsymbol.cpp @@ -204,7 +204,7 @@ void PortSymbol::Bounding(int& _x1, int& _y1, int& _x2, int& _y2) // -------------------------------------------------------------------------- // Rotates around the center. -void PortSymbol::rotate() +void PortSymbol::rotate(int, int) { if(Angel < 270) Angel += 90; else Angel = 0; diff --git a/qucs/paintings/portsymbol.h b/qucs/paintings/portsymbol.h index c80b0c11a..8b971f1a8 100644 --- a/qucs/paintings/portsymbol.h +++ b/qucs/paintings/portsymbol.h @@ -40,7 +40,7 @@ class PortSymbol : public Painting { bool getSelected(float, float, float); void Bounding(int&, int&, int&, int&); - void rotate(); + void rotate(int, int); void mirrorX(); void mirrorY(); diff --git a/qucs/paintings/rectangle.cpp b/qucs/paintings/rectangle.cpp index 443296320..17bf9820c 100644 --- a/qucs/paintings/rectangle.cpp +++ b/qucs/paintings/rectangle.cpp @@ -342,13 +342,25 @@ bool qucs::Rectangle::getSelected(float fX, float fY, float w) // -------------------------------------------------------------------------- // Rotates around the center. -void qucs::Rectangle::rotate() +void qucs::Rectangle::rotate(int xc, int yc) { - cy += (y2-x2) >> 1; - cx += (x2-y2) >> 1; - int tmp = x2; - x2 = y2; - y2 = tmp; + int xr1 = cx - xc; + int yr1 = cy - yc; + int xr2 = cx + x2 - xc; + int yr2 = cy + y2 - yc; + + int tmp = xr2; + xr2 = yr2; + yr2 = -tmp; + + tmp = xr1; + xr1 = yr1; + yr1 = -tmp; + + cx = xr1 + xc; + cy = yr1 + yc; + x2 = xr2 - xr1; + y2 = yr2 - yr1; } // -------------------------------------------------------------------------- diff --git a/qucs/paintings/rectangle.h b/qucs/paintings/rectangle.h index 77bb330b7..5f66e78cf 100644 --- a/qucs/paintings/rectangle.h +++ b/qucs/paintings/rectangle.h @@ -47,7 +47,7 @@ class Rectangle : public Painting { bool resizeTouched(float, float, float); void MouseResizeMoving(int, int, Schematic*); - void rotate(); + void rotate(int, int); void mirrorX(); void mirrorY(); bool Dialog(); diff --git a/qucs/schematic.cpp b/qucs/schematic.cpp index af7cbc36a..64d07d893 100644 --- a/qucs/schematic.cpp +++ b/qucs/schematic.cpp @@ -15,626 +15,641 @@ * * ***************************************************************************/ -#include #include +#include -#include -#include -#include +#include +#include +#include +#include #include -#include -#include -#include -#include #include +#include #include #include -#include #include -#include -#include -#include +#include #include -#include #include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#include "qucs.h" -#include "schematic.h" +#include "components/vafile.h" +#include "components/verilogfile.h" +#include "components/vhdlfile.h" +#include "diagrams/diagrams.h" #include "main.h" +#include "mouseactions.h" #include "node.h" +#include "paintings/paintings.h" +#include "qucs.h" +#include "schematic.h" #include "textdoc.h" #include "viewpainter.h" -#include "mouseactions.h" -#include "diagrams/diagrams.h" -#include "paintings/paintings.h" -#include "components/vhdlfile.h" -#include "components/verilogfile.h" -#include "components/vafile.h" #include "misc.h" // just dummies for empty lists -Q3PtrList SymbolWires; -Q3PtrList SymbolNodes; -Q3PtrList SymbolDiags; +Q3PtrList SymbolWires; +Q3PtrList SymbolNodes; +Q3PtrList SymbolDiags; Q3PtrList SymbolComps; - -Schematic::Schematic(QucsApp *App_, const QString& Name_) +Schematic::Schematic(QucsApp *App_, const QString &Name_) : QucsDoc(App_, Name_) { - symbolMode = false; - - setFont(QucsSettings.font); - // ........................................................... - GridX = GridY = 10; - ViewX1=ViewY1=0; - ViewX2=ViewY2=800; - UsedX1 = UsedY1 = INT_MAX; - UsedX2 = UsedY2 = INT_MIN; - - zx1 = zy1 = zx2 = zy2 = dx = dy = 0; - - tmpPosX = tmpPosY = -100; - tmpUsedX1 = tmpUsedY1 = tmpViewX1 = tmpViewY1 = -200; - tmpUsedX2 = tmpUsedY2 = tmpViewX2 = tmpViewY2 = 200; - tmpScale = 1.0; - - DocComps.setAutoDelete(true); - DocWires.setAutoDelete(true); - DocNodes.setAutoDelete(true); - DocDiags.setAutoDelete(true); - DocPaints.setAutoDelete(true); - SymbolPaints.setAutoDelete(true); - - // The 'i' means state for being unchanged. - undoActionIdx = 0; - undoAction.append(new QString(" i\n\n\n\n\n")); - undoSymbolIdx = 0; - undoSymbol.append(new QString(" i\n\n\n\n\n")); - - isVerilog = false; - creatingLib = false; - - showFrame = 0; // don't show - Frame_Text0 = tr("Title"); - Frame_Text1 = tr("Drawn By:"); - Frame_Text2 = tr("Date:"); - Frame_Text3 = tr("Revision:"); - - setVScrollBarMode(Q3ScrollView::AlwaysOn); - setHScrollBarMode(Q3ScrollView::AlwaysOn); - misc::setWidgetBackgroundColor(viewport(),QucsSettings.BGColor); - viewport()->setMouseTracking(true); - viewport()->setAcceptDrops(true); // enable drag'n drop - - // to repair some strange scrolling artefacts - connect(this, SIGNAL(horizontalSliderReleased()), - viewport(), SLOT(update())); - connect(this, SIGNAL(verticalSliderReleased()), - viewport(), SLOT(update())); - if (App_) { - connect(this, SIGNAL(signalCursorPosChanged(int, int)), - App_, SLOT(printCursorPosition(int, int))); - connect(this, SIGNAL(horizontalSliderPressed()), - App_, SLOT(slotHideEdit())); - connect(this, SIGNAL(verticalSliderPressed()), - App_, SLOT(slotHideEdit())); - connect(this, SIGNAL(signalUndoState(bool)), - App_, SLOT(slotUpdateUndo(bool))); - connect(this, SIGNAL(signalRedoState(bool)), - App_, SLOT(slotUpdateRedo(bool))); - connect(this, SIGNAL(signalFileChanged(bool)), - App_, SLOT(slotFileChanged(bool))); - } -} + symbolMode = false; -Schematic::~Schematic() -{ + setFont(QucsSettings.font); + // ........................................................... + GridX = GridY = 10; + ViewX1 = ViewY1 = 0; + ViewX2 = ViewY2 = 800; + UsedX1 = UsedY1 = INT_MAX; + UsedX2 = UsedY2 = INT_MIN; + + zx1 = zy1 = zx2 = zy2 = dx = dy = 0; + + tmpPosX = tmpPosY = -100; + tmpUsedX1 = tmpUsedY1 = tmpViewX1 = tmpViewY1 = -200; + tmpUsedX2 = tmpUsedY2 = tmpViewX2 = tmpViewY2 = 200; + tmpScale = 1.0; + + DocComps.setAutoDelete(true); + DocWires.setAutoDelete(true); + DocNodes.setAutoDelete(true); + DocDiags.setAutoDelete(true); + DocPaints.setAutoDelete(true); + SymbolPaints.setAutoDelete(true); + + // The 'i' means state for being unchanged. + undoActionIdx = 0; + undoAction.append(new QString(" i\n\n\n\n\n")); + undoSymbolIdx = 0; + undoSymbol.append(new QString(" i\n\n\n\n\n")); + + isVerilog = false; + creatingLib = false; + + showFrame = 0; // don't show + Frame_Text0 = tr("Title"); + Frame_Text1 = tr("Drawn By:"); + Frame_Text2 = tr("Date:"); + Frame_Text3 = tr("Revision:"); + + setVScrollBarMode(Q3ScrollView::AlwaysOn); + setHScrollBarMode(Q3ScrollView::AlwaysOn); + misc::setWidgetBackgroundColor(viewport(), QucsSettings.BGColor); + viewport()->setMouseTracking(true); + viewport()->setAcceptDrops(true); // enable drag'n drop + + // to repair some strange scrolling artefacts + connect(this, SIGNAL(horizontalSliderReleased()), viewport(), SLOT(update())); + connect(this, SIGNAL(verticalSliderReleased()), viewport(), SLOT(update())); + if (App_) { + connect(this, + SIGNAL(signalCursorPosChanged(int, int)), + App_, + SLOT(printCursorPosition(int, int))); + connect(this, SIGNAL(horizontalSliderPressed()), App_, SLOT(slotHideEdit())); + connect(this, SIGNAL(verticalSliderPressed()), App_, SLOT(slotHideEdit())); + connect(this, SIGNAL(signalUndoState(bool)), App_, SLOT(slotUpdateUndo(bool))); + connect(this, SIGNAL(signalRedoState(bool)), App_, SLOT(slotUpdateRedo(bool))); + connect(this, SIGNAL(signalFileChanged(bool)), App_, SLOT(slotFileChanged(bool))); + } } +Schematic::~Schematic() {} + // --------------------------------------------------- bool Schematic::createSubcircuitSymbol() { - // If the number of ports is not equal, remove or add some. - unsigned int countPort = adjustPortNumbers(); + // If the number of ports is not equal, remove or add some. + unsigned int countPort = adjustPortNumbers(); - // If a symbol does not yet exist, create one. - if(SymbolPaints.count() != countPort) - return false; + // If a symbol does not yet exist, create one. + if (SymbolPaints.count() != countPort) + return false; - int h = 30*((countPort-1)/2) + 10; - SymbolPaints.prepend(new ID_Text(-20, h+4)); - - SymbolPaints.append( - new GraphicLine(-20, -h, 40, 0, QPen(Qt::darkBlue,2))); - SymbolPaints.append( - new GraphicLine( 20, -h, 0,2*h, QPen(Qt::darkBlue,2))); - SymbolPaints.append( - new GraphicLine(-20, h, 40, 0, QPen(Qt::darkBlue,2))); - SymbolPaints.append( - new GraphicLine(-20, -h, 0,2*h, QPen(Qt::darkBlue,2))); - - unsigned int i=0, y = 10-h; - while(isetCenter(-30, y); - - if(i == countPort) break; - i++; - SymbolPaints.append( - new GraphicLine( 20, y, 10, 0, QPen(Qt::darkBlue,2))); - SymbolPaints.at(i)->setCenter(30, y); - y += 60; - } - return true; + int h = 30 * ((countPort - 1) / 2) + 10; + SymbolPaints.prepend(new ID_Text(-20, h + 4)); + + SymbolPaints.append(new GraphicLine(-20, -h, 40, 0, QPen(Qt::darkBlue, 2))); + SymbolPaints.append(new GraphicLine(20, -h, 0, 2 * h, QPen(Qt::darkBlue, 2))); + SymbolPaints.append(new GraphicLine(-20, h, 40, 0, QPen(Qt::darkBlue, 2))); + SymbolPaints.append(new GraphicLine(-20, -h, 0, 2 * h, QPen(Qt::darkBlue, 2))); + + unsigned int i = 0, y = 10 - h; + while (i < countPort) { + i++; + SymbolPaints.append(new GraphicLine(-30, y, 10, 0, QPen(Qt::darkBlue, 2))); + SymbolPaints.at(i)->setCenter(-30, y); + + if (i == countPort) + break; + i++; + SymbolPaints.append(new GraphicLine(20, y, 10, 0, QPen(Qt::darkBlue, 2))); + SymbolPaints.at(i)->setCenter(30, y); + y += 60; + } + return true; } // --------------------------------------------------- void Schematic::becomeCurrent(bool update) { - emit signalCursorPosChanged(0, 0); - - // update appropriate menu entry - if (symbolMode) { - if (DocName.right(4) == ".sym") { - App->symEdit->setText(tr("Edit Text")); - App->symEdit->setStatusTip(tr("Edits the Text")); - App->symEdit->setWhatsThis(tr("Edit Text\n\nEdits the text file")); + emit signalCursorPosChanged(0, 0); + + // update appropriate menu entry + if (symbolMode) { + if (DocName.right(4) == ".sym") { + App->symEdit->setText(tr("Edit Text")); + App->symEdit->setStatusTip(tr("Edits the Text")); + App->symEdit->setWhatsThis(tr("Edit Text\n\nEdits the text file")); + } else { + App->symEdit->setText(tr("Edit Schematic")); + App->symEdit->setStatusTip(tr("Edits the schematic")); + App->symEdit->setWhatsThis(tr("Edit Schematic\n\nEdits the schematic")); + } + } else { + App->symEdit->setText(tr("Edit Circuit Symbol")); + App->symEdit->setStatusTip(tr("Edits the symbol for this schematic")); + App->symEdit->setWhatsThis( + tr("Edit Circuit Symbol\n\nEdits the symbol for this schematic")); } - else { - App->symEdit->setText(tr("Edit Schematic")); - App->symEdit->setStatusTip(tr("Edits the schematic")); - App->symEdit->setWhatsThis(tr("Edit Schematic\n\nEdits the schematic")); - } - } - else { - App->symEdit->setText(tr("Edit Circuit Symbol")); - App->symEdit->setStatusTip(tr("Edits the symbol for this schematic")); - App->symEdit->setWhatsThis( - tr("Edit Circuit Symbol\n\nEdits the symbol for this schematic")); - } - - if(symbolMode) { - Nodes = &SymbolNodes; - Wires = &SymbolWires; - Diagrams = &SymbolDiags; - Paintings = &SymbolPaints; - Components = &SymbolComps; - - // if no symbol yet exists -> create one - if(createSubcircuitSymbol()) { - sizeOfAll(UsedX1, UsedY1, UsedX2, UsedY2); - setChanged(true, true); - } - - emit signalUndoState(undoSymbolIdx != 0); - emit signalRedoState(undoSymbolIdx != undoSymbol.size()-1); - } - else { - Nodes = &DocNodes; - Wires = &DocWires; - Diagrams = &DocDiags; - Paintings = &DocPaints; - Components = &DocComps; - emit signalUndoState(undoActionIdx != 0); - emit signalRedoState(undoActionIdx != undoAction.size()-1); - if(update) - reloadGraphs(); // load recent simulation data - } + if (symbolMode) { + Nodes = &SymbolNodes; + Wires = &SymbolWires; + Diagrams = &SymbolDiags; + Paintings = &SymbolPaints; + Components = &SymbolComps; + + // if no symbol yet exists -> create one + if (createSubcircuitSymbol()) { + sizeOfAll(UsedX1, UsedY1, UsedX2, UsedY2); + setChanged(true, true); + } + + emit signalUndoState(undoSymbolIdx != 0); + emit signalRedoState(undoSymbolIdx != undoSymbol.size() - 1); + } else { + Nodes = &DocNodes; + Wires = &DocWires; + Diagrams = &DocDiags; + Paintings = &DocPaints; + Components = &DocComps; + + emit signalUndoState(undoActionIdx != 0); + emit signalRedoState(undoActionIdx != undoAction.size() - 1); + if (update) + reloadGraphs(); // load recent simulation data + } } // --------------------------------------------------- -void Schematic::setName (const QString& Name_) +void Schematic::setName(const QString &Name_) { - DocName = Name_; - QFileInfo Info (DocName); - QString base = Info.completeBaseName (); - QString ext = Info.suffix(); - DataSet = base + ".dat"; - Script = base + ".m"; - if (ext != "dpl") - DataDisplay = base + ".dpl"; - else - DataDisplay = base + ".sch"; + DocName = Name_; + QFileInfo Info(DocName); + QString base = Info.completeBaseName(); + QString ext = Info.suffix(); + DataSet = base + ".dat"; + Script = base + ".m"; + if (ext != "dpl") + DataDisplay = base + ".dpl"; + else + DataDisplay = base + ".sch"; } // --------------------------------------------------- // Sets the document to be changed or not to be changed. void Schematic::setChanged(bool c, bool fillStack, char Op) { - if((!DocChanged) && c) - emit signalFileChanged(true); - else if(DocChanged && (!c)) - emit signalFileChanged(false); - DocChanged = c; + if ((!DocChanged) && c) + emit signalFileChanged(true); + else if (DocChanged && (!c)) + emit signalFileChanged(false); + DocChanged = c; - showBias = -1; // schematic changed => bias points may be invalid + showBias = -1; // schematic changed => bias points may be invalid - if(!fillStack) - return; + if (!fillStack) + return; + // ................................................ + if (symbolMode) { // for symbol edit mode + while (undoSymbol.size() > undoSymbolIdx + 1) { + delete undoSymbol.last(); + undoSymbol.pop_back(); + } - // ................................................ - if(symbolMode) { // for symbol edit mode - while(undoSymbol.size() > undoSymbolIdx + 1) { - delete undoSymbol.last(); - undoSymbol.pop_back(); + undoSymbol.append(new QString(createSymbolUndoString(Op))); + undoSymbolIdx++; + + emit signalUndoState(true); + emit signalRedoState(false); + + while (static_cast(undoSymbol.size()) + > QucsSettings.maxUndo) { // "while..." because + delete undoSymbol.first(); + undoSymbol.pop_front(); + undoSymbolIdx--; + } + return; } - undoSymbol.append(new QString(createSymbolUndoString(Op))); - undoSymbolIdx++; + // ................................................ + // for schematic edit mode + while (undoAction.size() > undoActionIdx + 1) { + delete undoAction.last(); + undoAction.pop_back(); + } + + if (Op == 'm') { // only one for move marker + if (undoAction.at(undoActionIdx)->at(0) == Op) { + delete undoAction.last(); + undoAction.pop_back(); + undoActionIdx--; + } + } + + undoAction.append(new QString(createUndoString(Op))); + undoActionIdx++; emit signalUndoState(true); emit signalRedoState(false); - while(static_cast(undoSymbol.size()) > QucsSettings.maxUndo) { // "while..." because - delete undoSymbol.first(); - undoSymbol.pop_front(); - undoSymbolIdx--; + while (static_cast(undoAction.size()) + > QucsSettings.maxUndo) { // "while..." because + delete undoAction.first(); // "maxUndo" could be decreased meanwhile + undoAction.pop_front(); + undoActionIdx--; } return; - } - - // ................................................ - // for schematic edit mode - while(undoAction.size() > undoActionIdx + 1) { - delete undoAction.last(); - undoAction.pop_back(); - } - - if(Op == 'm') { // only one for move marker - if (undoAction.at(undoActionIdx)->at(0) == Op) { - delete undoAction.last(); - undoAction.pop_back(); - undoActionIdx--; - } - } - - undoAction.append(new QString(createUndoString(Op))); - undoActionIdx++; - - emit signalUndoState(true); - emit signalRedoState(false); - - while(static_cast(undoAction.size()) > QucsSettings.maxUndo) { // "while..." because - delete undoAction.first(); // "maxUndo" could be decreased meanwhile - undoAction.pop_front(); - undoActionIdx--; - } - return; } // ----------------------------------------------------------- -bool Schematic::sizeOfFrame(int& xall, int& yall) +bool Schematic::sizeOfFrame(int &xall, int &yall) { - // Values exclude border of 1.5cm at each side. - switch(showFrame) { - case 1: xall = 1020; yall = 765; break; // DIN A5 landscape - case 2: xall = 765; yall = 1020; break; // DIN A5 portrait - case 3: xall = 1530; yall = 1020; break; // DIN A4 landscape - case 4: xall = 1020; yall = 1530; break; // DIN A4 portrait - case 5: xall = 2295; yall = 1530; break; // DIN A3 landscape - case 6: xall = 1530; yall = 2295; break; // DIN A3 portrait - case 7: xall = 1414; yall = 1054; break; // letter landscape - case 8: xall = 1054; yall = 1414; break; // letter portrait - default: return false; - } - - return true; + // Values exclude border of 1.5cm at each side. + switch (showFrame) { + case 1: + xall = 1020; + yall = 765; + break; // DIN A5 landscape + case 2: + xall = 765; + yall = 1020; + break; // DIN A5 portrait + case 3: + xall = 1530; + yall = 1020; + break; // DIN A4 landscape + case 4: + xall = 1020; + yall = 1530; + break; // DIN A4 portrait + case 5: + xall = 2295; + yall = 1530; + break; // DIN A3 landscape + case 6: + xall = 1530; + yall = 2295; + break; // DIN A3 portrait + case 7: + xall = 1414; + yall = 1054; + break; // letter landscape + case 8: + xall = 1054; + yall = 1414; + break; // letter portrait + default: + return false; + } + + return true; } // ----------------------------------------------------------- void Schematic::paintFrame(ViewPainter *p) { - // dimensions: X cm / 2.54 * 144 - int xall, yall; - if(!sizeOfFrame(xall, yall)) - return; - p->Painter->setPen(QPen(Qt::darkGray,1)); - //p->Painter->setPen(QPen(Qt::black,0)); - int d = p->LineSpacing + int(4.0 * p->Scale); - int x1_, y1_, x2_, y2_; - p->map(xall, yall, x1_, y1_); - x2_ = int(xall * p->Scale) + 1; - y2_ = int(yall * p->Scale) + 1; - p->Painter->drawRect(x1_, y1_, -x2_, -y2_); - p->Painter->drawRect(x1_-d, y1_-d, 2*d-x2_, 2*d-y2_); - - int z; - int step = xall / ((xall+127) / 255); - for(z=step; z<=xall-step; z+=step) { - p->map(z, 0, x2_, y2_); - p->Painter->drawLine(x2_, y2_, x2_, y2_+d); - p->Painter->drawLine(x2_, y1_-d, x2_, y1_); - } - char Letter[2] = "1"; - for(z=step/2+5; zdrawText(Letter, z, 3, 0); - p->map(z, yall+3, x2_, y2_); - p->Painter->drawText(x2_, y2_-d, 0, 0, Qt::TextDontClip, Letter); - Letter[0]++; - } - - step = yall / ((yall+127) / 255); - for(z=step; z<=yall-step; z+=step) { - p->map(0, z, x2_, y2_); - p->Painter->drawLine(x2_, y2_, x2_+d, y2_); - p->Painter->drawLine(x1_-d, y2_, x1_, y2_); - } - Letter[0] = 'A'; - for(z=step/2+5; zdrawText(Letter, 5, z, 0); - p->map(xall+5, z, x2_, y2_); - p->Painter->drawText(x2_-d, y2_, 0, 0, Qt::TextDontClip, Letter); - Letter[0]++; - } - - // draw text box with text - p->map(xall-340, yall-3, x1_, y1_); - p->map(xall-3, yall-3, x2_, y2_); - x1_ -= d; x2_ -= d; - y1_ -= d; y2_ -= d; - d = int(6.0 * p->Scale); - z = int(200.0 * p->Scale); - y1_ -= p->LineSpacing + d; - p->Painter->drawLine(x1_, y1_, x2_, y1_); - p->Painter->drawText(x1_+d, y1_+(d>>1), 0, 0, Qt::TextDontClip, Frame_Text2); - p->Painter->drawLine(x1_+z, y1_, x1_+z, y1_ + p->LineSpacing+d); - p->Painter->drawText(x1_+d+z, y1_+(d>>1), 0, 0, Qt::TextDontClip, Frame_Text3); - y1_ -= p->LineSpacing + d; - p->Painter->drawLine(x1_, y1_, x2_, y1_); - p->Painter->drawText(x1_+d, y1_+(d>>1), 0, 0, Qt::TextDontClip, Frame_Text1); - y1_ -= (Frame_Text0.count('\n')+1) * p->LineSpacing + d; - p->Painter->drawRect(x2_, y2_, x1_-x2_-1, y1_-y2_-1); - p->Painter->drawText(x1_+d, y1_+(d>>1), 0, 0, Qt::TextDontClip, Frame_Text0); + // dimensions: X cm / 2.54 * 144 + int xall, yall; + if (!sizeOfFrame(xall, yall)) + return; + p->Painter->setPen(QPen(Qt::darkGray, 1)); + //p->Painter->setPen(QPen(Qt::black,0)); + int d = p->LineSpacing + int(4.0 * p->Scale); + int x1_, y1_, x2_, y2_; + p->map(xall, yall, x1_, y1_); + x2_ = int(xall * p->Scale) + 1; + y2_ = int(yall * p->Scale) + 1; + p->Painter->drawRect(x1_, y1_, -x2_, -y2_); + p->Painter->drawRect(x1_ - d, y1_ - d, 2 * d - x2_, 2 * d - y2_); + + int z; + int step = xall / ((xall + 127) / 255); + for (z = step; z <= xall - step; z += step) { + p->map(z, 0, x2_, y2_); + p->Painter->drawLine(x2_, y2_, x2_, y2_ + d); + p->Painter->drawLine(x2_, y1_ - d, x2_, y1_); + } + char Letter[2] = "1"; + for (z = step / 2 + 5; z < xall; z += step) { + p->drawText(Letter, z, 3, 0); + p->map(z, yall + 3, x2_, y2_); + p->Painter->drawText(x2_, y2_ - d, 0, 0, Qt::TextDontClip, Letter); + Letter[0]++; + } + + step = yall / ((yall + 127) / 255); + for (z = step; z <= yall - step; z += step) { + p->map(0, z, x2_, y2_); + p->Painter->drawLine(x2_, y2_, x2_ + d, y2_); + p->Painter->drawLine(x1_ - d, y2_, x1_, y2_); + } + Letter[0] = 'A'; + for (z = step / 2 + 5; z < yall; z += step) { + p->drawText(Letter, 5, z, 0); + p->map(xall + 5, z, x2_, y2_); + p->Painter->drawText(x2_ - d, y2_, 0, 0, Qt::TextDontClip, Letter); + Letter[0]++; + } + + // draw text box with text + p->map(xall - 340, yall - 3, x1_, y1_); + p->map(xall - 3, yall - 3, x2_, y2_); + x1_ -= d; + x2_ -= d; + y1_ -= d; + y2_ -= d; + d = int(6.0 * p->Scale); + z = int(200.0 * p->Scale); + y1_ -= p->LineSpacing + d; + p->Painter->drawLine(x1_, y1_, x2_, y1_); + p->Painter->drawText(x1_ + d, y1_ + (d >> 1), 0, 0, Qt::TextDontClip, Frame_Text2); + p->Painter->drawLine(x1_ + z, y1_, x1_ + z, y1_ + p->LineSpacing + d); + p->Painter->drawText(x1_ + d + z, y1_ + (d >> 1), 0, 0, Qt::TextDontClip, Frame_Text3); + y1_ -= p->LineSpacing + d; + p->Painter->drawLine(x1_, y1_, x2_, y1_); + p->Painter->drawText(x1_ + d, y1_ + (d >> 1), 0, 0, Qt::TextDontClip, Frame_Text1); + y1_ -= (Frame_Text0.count('\n') + 1) * p->LineSpacing + d; + p->Painter->drawRect(x2_, y2_, x1_ - x2_ - 1, y1_ - y2_ - 1); + p->Painter->drawText(x1_ + d, y1_ + (d >> 1), 0, 0, Qt::TextDontClip, Frame_Text0); } // ----------------------------------------------------------- // Is called when the content (schematic or data display) has to be drawn. void Schematic::drawContents(QPainter *p, int, int, int, int) { - ViewPainter Painter; - - Painter.init(p, Scale, -ViewX1, -ViewY1, contentsX(), contentsY()); - - paintGrid(&Painter, contentsX(), contentsY(), - visibleWidth(), visibleHeight()); - - if(!symbolMode) - paintFrame(&Painter); - - for(Component *pc = Components->first(); pc != 0; pc = Components->next()) - pc->paint(&Painter); - - for(Wire *pw = Wires->first(); pw != 0; pw = Wires->next()) { - pw->paint(&Painter); - if(pw->Label) - pw->Label->paint(&Painter); // separate because of paintSelected - } - - Node *pn; - for(pn = Nodes->first(); pn != 0; pn = Nodes->next()) { - pn->paint(&Painter); - if(pn->Label) - pn->Label->paint(&Painter); // separate because of paintSelected - } - - // FIXME disable here, issue with select box goes away - // also, instead of red, line turns blue - for(Diagram *pd = Diagrams->first(); pd != 0; pd = Diagrams->next()) - pd->paint(&Painter); - - for(Painting *pp = Paintings->first(); pp != 0; pp = Paintings->next()) - pp->paint(&Painter); - - if(showBias > 0) { // show DC bias points in schematic ? - int x, y, z; - for(pn = Nodes->first(); pn != 0; pn = Nodes->next()) { - if(pn->Name.isEmpty()) continue; - x = pn->cx; - y = pn->cy + 4; - z = pn->x1; - if(z & 1) x -= Painter.Painter->fontMetrics().boundingRect(pn->Name).width(); - if(!(z & 2)) { - y -= (Painter.LineSpacing>>1) + 4; - if(z & 1) x -= 4; - else x += 4; - } - if(z & 0x10) - Painter.Painter->setPen(Qt::darkGreen); // green for currents - else - Painter.Painter->setPen(Qt::blue); // blue for voltages - Painter.drawText(pn->Name, x, y); - } - } - - /* + ViewPainter Painter; + + Painter.init(p, Scale, -ViewX1, -ViewY1, contentsX(), contentsY()); + + paintGrid(&Painter, contentsX(), contentsY(), visibleWidth(), visibleHeight()); + + if (!symbolMode) + paintFrame(&Painter); + + for (Component *pc = Components->first(); pc != 0; pc = Components->next()) + pc->paint(&Painter); + + for (Wire *pw = Wires->first(); pw != 0; pw = Wires->next()) { + pw->paint(&Painter); + if (pw->Label) + pw->Label->paint(&Painter); // separate because of paintSelected + } + + Node *pn; + for (pn = Nodes->first(); pn != 0; pn = Nodes->next()) { + pn->paint(&Painter); + if (pn->Label) + pn->Label->paint(&Painter); // separate because of paintSelected + } + + // FIXME disable here, issue with select box goes away + // also, instead of red, line turns blue + for (Diagram *pd = Diagrams->first(); pd != 0; pd = Diagrams->next()) + pd->paint(&Painter); + + for (Painting *pp = Paintings->first(); pp != 0; pp = Paintings->next()) + pp->paint(&Painter); + + if (showBias > 0) { // show DC bias points in schematic ? + int x, y, z; + for (pn = Nodes->first(); pn != 0; pn = Nodes->next()) { + if (pn->Name.isEmpty()) + continue; + x = pn->cx; + y = pn->cy + 4; + z = pn->x1; + if (z & 1) + x -= Painter.Painter->fontMetrics().boundingRect(pn->Name).width(); + if (!(z & 2)) { + y -= (Painter.LineSpacing >> 1) + 4; + if (z & 1) + x -= 4; + else + x += 4; + } + if (z & 0x10) + Painter.Painter->setPen(Qt::darkGreen); // green for currents + else + Painter.Painter->setPen(Qt::blue); // blue for voltages + Painter.drawText(pn->Name, x, y); + } + } + + /* * The following events used to be drawn from mouseactions.cpp, but since Qt4 * Paint actions can only be called from within the paint event, so they * are put into a QList (PostedPaintEvents) and processed here */ - for(auto p : PostedPaintEvents) - { - // QPainter painter2(viewport()); for if(p.PaintOnViewport) - QPen pen(Qt::black); - Painter.Painter->setPen(Qt::black); - switch(p.pe) - { - case _NotRop: - Painter.Painter->setCompositionMode(QPainter::RasterOp_SourceAndNotDestination); - break; - case _Rect: - Painter.drawRect(p.x1, p.y1, p.x2, p.y2); - break; - case _SelectionRect: - pen.setStyle(Qt::DashLine); - pen.setColor(QColor(50, 50, 50, 100)); - Painter.Painter->setPen(pen); - Painter.fillRect(p.x1, p.y1, p.x2, p.y2, QColor(200,220,240,100)); - Painter.drawRect(p.x1, p.y1, p.x2, p.y2); - break; - case _Line: - Painter.drawLine(p.x1, p.y1, p.x2, p.y2); - break; - case _Ellipse: - Painter.drawEllipse(p.x1, p.y1, p.x2, p.y2); - break; - case _Arc: - Painter.drawArc(p.x1, p.y1, p.x2, p.y2, p.a, p.b); - break; - case _DotLine: - Painter.Painter->setPen(Qt::DotLine); - break; - case _Translate: - ;//painter2.translate(p.x1, p.y1); - break; - case _Scale: - ;//painter2.scale(p.x1,p.y1); - break; - } - - } - PostedPaintEvents.clear(); - + for (auto p : PostedPaintEvents) { + // QPainter painter2(viewport()); for if(p.PaintOnViewport) + QPen pen(Qt::black); + Painter.Painter->setPen(Qt::black); + switch (p.pe) { + case _NotRop: + Painter.Painter->setCompositionMode(QPainter::RasterOp_SourceAndNotDestination); + break; + case _Rect: + Painter.drawRect(p.x1, p.y1, p.x2, p.y2); + break; + case _SelectionRect: + pen.setStyle(Qt::DashLine); + pen.setColor(QColor(50, 50, 50, 100)); + Painter.Painter->setPen(pen); + Painter.fillRect(p.x1, p.y1, p.x2, p.y2, QColor(200, 220, 240, 100)); + Painter.drawRect(p.x1, p.y1, p.x2, p.y2); + break; + case _Line: + Painter.drawLine(p.x1, p.y1, p.x2, p.y2); + break; + case _Ellipse: + Painter.drawEllipse(p.x1, p.y1, p.x2, p.y2); + break; + case _Arc: + Painter.drawArc(p.x1, p.y1, p.x2, p.y2, p.a, p.b); + break; + case _DotLine: + Painter.Painter->setPen(Qt::DotLine); + break; + case _Translate:; //painter2.translate(p.x1, p.y1); + break; + case _Scale:; //painter2.scale(p.x1,p.y1); + break; + } + } + PostedPaintEvents.clear(); } -void Schematic::PostPaintEvent (PE pe, int x1, int y1, int x2, int y2, int a, int b, bool PaintOnViewport) +void Schematic::PostPaintEvent( + PE pe, int x1, int y1, int x2, int y2, int a, int b, bool PaintOnViewport) { - PostedPaintEvent p = {pe, x1,y1,x2,y2,a,b,PaintOnViewport}; - PostedPaintEvents.push_back(p); - viewport()->update(); - update(); + PostedPaintEvent p = {pe, x1, y1, x2, y2, a, b, PaintOnViewport}; + PostedPaintEvents.push_back(p); + viewport()->update(); + update(); } - // --------------------------------------------------- void Schematic::contentsMouseMoveEvent(QMouseEvent *Event) { - emit signalCursorPosChanged(Event->pos().x(), Event->pos().y()); - if(App->MouseMoveAction) - (App->view->*(App->MouseMoveAction))(this, Event); + emit signalCursorPosChanged(Event->pos().x(), Event->pos().y()); + if (App->MouseMoveAction) + (App->view->*(App->MouseMoveAction))(this, Event); } // ----------------------------------------------------------- void Schematic::contentsMousePressEvent(QMouseEvent *Event) { - App->editText->setHidden(true); // disable text edit of component property - this->setFocus(); - if(App->MouseReleaseAction == &MouseActions::MReleasePaste) - return; - - float x = float(Event->pos().x())/Scale + float(ViewX1); - float y = float(Event->pos().y())/Scale + float(ViewY1); - - if(Event->button() != Qt::LeftButton) - if(App->MousePressAction != &MouseActions::MPressElement) - if(App->MousePressAction != &MouseActions::MPressWire2) { - // show menu on right mouse button - App->view->rightPressMenu(this, Event, x, y); - if(App->MouseReleaseAction) - // Is not called automatically because menu has focus. - (App->view->*(App->MouseReleaseAction))(this, Event); + App->editText->setHidden(true); // disable text edit of component property + this->setFocus(); + if (App->MouseReleaseAction == &MouseActions::MReleasePaste) return; - } - if(App->MousePressAction) - (App->view->*(App->MousePressAction))(this, Event, x, y); + float x = float(Event->pos().x()) / Scale + float(ViewX1); + float y = float(Event->pos().y()) / Scale + float(ViewY1); + + if (Event->button() != Qt::LeftButton) + if (App->MousePressAction != &MouseActions::MPressElement) + if (App->MousePressAction != &MouseActions::MPressWire2) { + // show menu on right mouse button + App->view->rightPressMenu(this, Event, x, y); + if (App->MouseReleaseAction) + // Is not called automatically because menu has focus. + (App->view->*(App->MouseReleaseAction))(this, Event); + return; + } + + if (App->MousePressAction) + (App->view->*(App->MousePressAction))(this, Event, x, y); } // ----------------------------------------------------------- void Schematic::contentsMouseReleaseEvent(QMouseEvent *Event) { - if(App->MouseReleaseAction) - (App->view->*(App->MouseReleaseAction))(this, Event); + if (App->MouseReleaseAction) + (App->view->*(App->MouseReleaseAction))(this, Event); } // ----------------------------------------------------------- void Schematic::contentsMouseDoubleClickEvent(QMouseEvent *Event) { - if(App->MouseDoubleClickAction) - (App->view->*(App->MouseDoubleClickAction))(this, Event); + if (App->MouseDoubleClickAction) + (App->view->*(App->MouseDoubleClickAction))(this, Event); } // ----------------------------------------------------------- -void Schematic::print(QPrinter*, QPainter *Painter, bool printAll, bool fitToPage) +void Schematic::print(QPrinter *, QPainter *Painter, bool printAll, bool fitToPage) { - QPaintDevice *pdevice = Painter->device(); - float printerDpiX = (float)pdevice->logicalDpiX(); - float printerDpiY = (float)pdevice->logicalDpiY(); - float printerW = (float)pdevice->width(); - float printerH = (float)pdevice->height(); - QPainter pa(viewport()); - float screenDpiX = (float)pa.device()->logicalDpiX(); - float screenDpiY = (float)pa.device()->logicalDpiY(); - float PrintScale = 0.5; - sizeOfAll(UsedX1, UsedY1, UsedX2, UsedY2); - int marginX = (int)(40 * printerDpiX / screenDpiX); - int marginY = (int)(40 * printerDpiY / screenDpiY); - - if(fitToPage) { - - float ScaleX = float((printerW - 2*marginX) / - float((UsedX2-UsedX1) * printerDpiX)) * screenDpiX; - float ScaleY = float((printerH - 2*marginY) / - float((UsedY2-UsedY1) * printerDpiY)) * screenDpiY; - - if(showFrame){ - int xall, yall; - sizeOfFrame(xall, yall); - ScaleX = ((float)(printerW - 2*marginX) / - (float)(xall * printerDpiX)) * screenDpiX; - ScaleY = ((float)(printerH - 2*marginY) / - (float)(yall * printerDpiY)) * screenDpiY; - } - - if(ScaleX > ScaleY) - PrintScale = ScaleY; - else - PrintScale = ScaleX; - } - - - //bool selected; - ViewPainter p; - int StartX = UsedX1; - int StartY = UsedY1; - if(showFrame) { - if(UsedX1 > 0) StartX = 0; - if(UsedY1 > 0) StartY = 0; - } - - float PrintRatio = printerDpiX / screenDpiX; - QFont oldFont = Painter->font(); - QFont printFont = Painter->font(); + QPaintDevice *pdevice = Painter->device(); + float printerDpiX = (float) pdevice->logicalDpiX(); + float printerDpiY = (float) pdevice->logicalDpiY(); + float printerW = (float) pdevice->width(); + float printerH = (float) pdevice->height(); + QPainter pa(viewport()); + float screenDpiX = (float) pa.device()->logicalDpiX(); + float screenDpiY = (float) pa.device()->logicalDpiY(); + float PrintScale = 0.5; + sizeOfAll(UsedX1, UsedY1, UsedX2, UsedY2); + int marginX = (int) (40 * printerDpiX / screenDpiX); + int marginY = (int) (40 * printerDpiY / screenDpiY); + + if (fitToPage) { + float ScaleX = float((printerW - 2 * marginX) / float((UsedX2 - UsedX1) * printerDpiX)) + * screenDpiX; + float ScaleY = float((printerH - 2 * marginY) / float((UsedY2 - UsedY1) * printerDpiY)) + * screenDpiY; + + if (showFrame) { + int xall, yall; + sizeOfFrame(xall, yall); + ScaleX = ((float) (printerW - 2 * marginX) / (float) (xall * printerDpiX)) * screenDpiX; + ScaleY = ((float) (printerH - 2 * marginY) / (float) (yall * printerDpiY)) * screenDpiY; + } + + if (ScaleX > ScaleY) + PrintScale = ScaleY; + else + PrintScale = ScaleX; + } + + //bool selected; + ViewPainter p; + int StartX = UsedX1; + int StartY = UsedY1; + if (showFrame) { + if (UsedX1 > 0) + StartX = 0; + if (UsedY1 > 0) + StartY = 0; + } + + float PrintRatio = printerDpiX / screenDpiX; + QFont oldFont = Painter->font(); + QFont printFont = Painter->font(); #ifdef __MINGW32__ - printFont.setPointSizeF(printFont.pointSizeF()/PrintRatio); - Painter->setFont(printFont); + printFont.setPointSizeF(printFont.pointSizeF() / PrintRatio); + Painter->setFont(printFont); #endif - p.init(Painter, PrintScale * PrintRatio, - -StartX, -StartY, -marginX, -marginY, PrintScale, PrintRatio); + p.init(Painter, + PrintScale * PrintRatio, + -StartX, + -StartY, + -marginX, + -marginY, + PrintScale, + PrintRatio); - if(!symbolMode) - paintFrame(&p); + if (!symbolMode) + paintFrame(&p); - paintSchToViewpainter(&p,printAll,false,screenDpiX,printerDpiX); + paintSchToViewpainter(&p, printAll, false, screenDpiX, printerDpiX); - Painter->setFont(oldFont); + Painter->setFont(oldFont); } - -void Schematic::paintSchToViewpainter(ViewPainter *p, bool printAll, bool toImage, int screenDpiX, int printerDpiX) { +void Schematic::paintSchToViewpainter( + ViewPainter *p, bool printAll, bool toImage, int screenDpiX, int printerDpiX) +{ bool selected; if (printAll) { int x2, y2; - if (sizeOfFrame(x2, y2)) paintFrame(p); + if (sizeOfFrame(x2, y2)) + paintFrame(p); } for (Component *pc = Components->first(); pc != 0; pc = Components->next()) @@ -653,7 +668,7 @@ void Schematic::paintSchToViewpainter(ViewPainter *p, bool printAll, bool toImag if (pw->isSelected || printAll) { selected = pw->isSelected; pw->isSelected = false; - pw->paint(p); // paint all selected wires + pw->paint(p); // paint all selected wires pw->isSelected = selected; } if (pw->Label) @@ -685,56 +700,64 @@ void Schematic::paintSchToViewpainter(ViewPainter *p, bool printAll, bool toImag if (pp->isSelected || printAll) { selected = pp->isSelected; pp->isSelected = false; - pp->paint(p); // paint all selected paintings + pp->paint(p); // paint all selected paintings pp->isSelected = selected; } for (Diagram *pd = Diagrams->first(); pd != 0; pd = Diagrams->next()) if (pd->isSelected || printAll) { // if graph or marker is selected, deselect during printing - for (Graph *pg: pd->Graphs) { - if (pg->isSelected) pg->Type |= 1; // remember selection + for (Graph *pg : pd->Graphs) { + if (pg->isSelected) + pg->Type |= 1; // remember selection pg->isSelected = false; - for (Marker *pm: pg->Markers) { - if (pm->isSelected) pm->Type |= 1; // remember selection + for (Marker *pm : pg->Markers) { + if (pm->isSelected) + pm->Type |= 1; // remember selection pm->isSelected = false; } } selected = pd->isSelected; pd->isSelected = false; - pd->paintDiagram(p); // paint all selected diagrams with graphs and markers + pd->paintDiagram(p); // paint all selected diagrams with graphs and markers pd->paintMarkers(p, printAll); pd->isSelected = selected; // revert selection of graphs and markers - for (Graph *pg: pd->Graphs) { - if (pg->Type & 1) pg->isSelected = true; + for (Graph *pg : pd->Graphs) { + if (pg->Type & 1) + pg->isSelected = true; pg->Type &= -2; - for (Marker *pm: pg->Markers) { - if (pm->Type & 1) pm->isSelected = true; + for (Marker *pm : pg->Markers) { + if (pm->Type & 1) + pm->isSelected = true; pm->Type &= -2; } } } - if (showBias > 0) { // show DC bias points in schematic ? + if (showBias > 0) { // show DC bias points in schematic ? int x, y, z; for (Node *pn = Nodes->first(); pn != 0; pn = Nodes->next()) { - if (pn->Name.isEmpty()) continue; + if (pn->Name.isEmpty()) + continue; x = pn->cx; y = pn->cy + 4; z = pn->x1; - if (z & 1) x -= p->Painter->fontMetrics().boundingRect(pn->Name).width(); + if (z & 1) + x -= p->Painter->fontMetrics().boundingRect(pn->Name).width(); if (!(z & 2)) { y -= (p->LineSpacing >> 1) + 4; - if (z & 1) x -= 4; - else x += 4; + if (z & 1) + x -= 4; + else + x += 4; } if (z & 0x10) - p->Painter->setPen(Qt::darkGreen); // green for currents + p->Painter->setPen(Qt::darkGreen); // green for currents else - p->Painter->setPen(Qt::blue); // blue for voltages + p->Painter->setPen(Qt::blue); // blue for voltages p->drawText(pn->Name, x, y); } } @@ -743,61 +766,64 @@ void Schematic::paintSchToViewpainter(ViewPainter *p, bool printAll, bool toImag // ----------------------------------------------------------- float Schematic::zoom(float s) { - Scale *= s; - if(Scale > 10.0) Scale = 10.0f; - if(Scale < 0.1) Scale = 0.1f; - - // "resizeContents()" performs an immediate repaint. So, set widget - // to hidden. This causes some flicker, but it is still nicer. - viewport()->setHidden(true); -// setHidden(true); - resizeContents(int(Scale*float(ViewX2 - ViewX1)), - int(Scale*float(ViewY2 - ViewY1))); -// setHidden(false); - viewport()->setHidden(false); - - viewport()->update(); - App->view->drawn = false; - return Scale; + Scale *= s; + if (Scale > 10.0) + Scale = 10.0f; + if (Scale < 0.1) + Scale = 0.1f; + + // "resizeContents()" performs an immediate repaint. So, set widget + // to hidden. This causes some flicker, but it is still nicer. + viewport()->setHidden(true); + // setHidden(true); + resizeContents(int(Scale * float(ViewX2 - ViewX1)), int(Scale * float(ViewY2 - ViewY1))); + // setHidden(false); + viewport()->setHidden(false); + + viewport()->update(); + App->view->drawn = false; + return Scale; } // ----------------------------------------------------------- float Schematic::zoomBy(float s) { - zoom(s); - s -= 1.0; - scrollBy( int(s * float(contentsX()+visibleWidth()/2)), - int(s * float(contentsY()+visibleHeight()/2)) ); - return Scale; + zoom(s); + s -= 1.0; + scrollBy(int(s * float(contentsX() + visibleWidth() / 2)), + int(s * float(contentsY() + visibleHeight() / 2))); + return Scale; } // --------------------------------------------------- void Schematic::showAll() { - sizeOfAll(UsedX1, UsedY1, UsedX2, UsedY2); - if(UsedX1 == 0) - if(UsedX2 == 0) - if(UsedY1 == 0) - if(UsedY2 == 0) { - UsedX1 = UsedY1 = INT_MAX; - UsedX2 = UsedY2 = INT_MIN; - return; - } - - float xScale = float(visibleWidth()) / float(UsedX2-UsedX1+80); - float yScale = float(visibleHeight()) / float(UsedY2-UsedY1+80); - if(xScale > yScale) xScale = yScale; - xScale /= Scale; - - ViewX1 = UsedX1 - 40; - ViewY1 = UsedY1 - 40; - ViewX2 = UsedX2 + 40; - ViewY2 = UsedY2 + 40; - zoom(xScale); + sizeOfAll(UsedX1, UsedY1, UsedX2, UsedY2); + if (UsedX1 == 0) + if (UsedX2 == 0) + if (UsedY1 == 0) + if (UsedY2 == 0) { + UsedX1 = UsedY1 = INT_MAX; + UsedX2 = UsedY2 = INT_MIN; + return; + } + + float xScale = float(visibleWidth()) / float(UsedX2 - UsedX1 + 80); + float yScale = float(visibleHeight()) / float(UsedY2 - UsedY1 + 80); + if (xScale > yScale) + xScale = yScale; + xScale /= Scale; + + ViewX1 = UsedX1 - 40; + ViewY1 = UsedY1 - 40; + ViewX2 = UsedX2 + 40; + ViewY2 = UsedY2 + 40; + zoom(xScale); } // ------------------------------------------------------ -void Schematic::zoomToSelection() { +void Schematic::zoomToSelection() +{ int x1, x2, y1, y2 = 0; sizeOfSelection(x1, y1, x2, y2); if (x1 == 0 && x2 == 0 && y1 == 0 && y2 == 0) { @@ -805,10 +831,8 @@ void Schematic::zoomToSelection() { return; } // - if (zx1 == contentsX() && zx2 == contentsWidth() && - zy1 == contentsY() && zy2 == contentsHeight() && - dx == x2 - x1 && - dy == y2 - y1) { + if (zx1 == contentsX() && zx2 == contentsWidth() && zy1 == contentsY() + && zy2 == contentsHeight() && dx == x2 - x1 && dy == y2 - y1) { return; } @@ -835,30 +859,34 @@ void Schematic::zoomToSelection() { // --------------------------------------------------- void Schematic::showNoZoom() { - Scale = 1.0; - - int x1 = UsedX1; - int y1 = UsedY1; - int x2 = UsedX2; - int y2 = UsedY2; - - if(x1 > x2) { // happens e.g. if untitled without changes - x1 = 0; - x2 = 800; - } - if(y1 > y2) { - y1 = 0; - y2 = 800; - } - if(x2==0) if(y2==0) if(x1==0) if(y1==0) x2 = y2 = 800; - - ViewX1 = x1-40; - ViewY1 = y1-40; - ViewX2 = x2+40; - ViewY2 = y2+40; - resizeContents(x2-x1+80, y2-y1+80); - viewport()->update(); - App->view->drawn = false; + Scale = 1.0; + + int x1 = UsedX1; + int y1 = UsedY1; + int x2 = UsedX2; + int y2 = UsedY2; + + if (x1 > x2) { // happens e.g. if untitled without changes + x1 = 0; + x2 = 800; + } + if (y1 > y2) { + y1 = 0; + y2 = 800; + } + if (x2 == 0) + if (y2 == 0) + if (x1 == 0) + if (y1 == 0) + x2 = y2 = 800; + + ViewX1 = x1 - 40; + ViewY1 = y1 - 40; + ViewX2 = x2 + 40; + ViewY2 = y2 + 40; + resizeContents(x2 - x1 + 80, y2 - y1 + 80); + viewport()->update(); + App->view->drawn = false; } // ----------------------------------------------------------- @@ -866,202 +894,243 @@ void Schematic::showNoZoom() // visible area. void Schematic::enlargeView(int x1, int y1, int x2, int y2) { - int dx=0, dy=0; - if(x1 < UsedX1) UsedX1 = x1; - if(y1 < UsedY1) UsedY1 = y1; - if(x2 > UsedX2) UsedX2 = x2; - if(y2 > UsedY2) UsedY2 = y2; - - if(x1 < ViewX1) { - dx = int(Scale * float(ViewX1-x1+40)); - ViewX1 = x1-40; - } - if(y1 < ViewY1) { - dy = int(Scale * float(ViewY1-y1+40)); - ViewY1 = y1-40; - } - if(x2 > ViewX2) ViewX2 = x2+40; - if(y2 > ViewY2) ViewY2 = y2+40; - - resizeContents(int(Scale*float(ViewX2 - ViewX1)), - int(Scale*float(ViewY2 - ViewY1))); - scrollBy(dx,dy); + int dx = 0, dy = 0; + if (x1 < UsedX1) + UsedX1 = x1; + if (y1 < UsedY1) + UsedY1 = y1; + if (x2 > UsedX2) + UsedX2 = x2; + if (y2 > UsedY2) + UsedY2 = y2; + + if (x1 < ViewX1) { + dx = int(Scale * float(ViewX1 - x1 + 40)); + ViewX1 = x1 - 40; + } + if (y1 < ViewY1) { + dy = int(Scale * float(ViewY1 - y1 + 40)); + ViewY1 = y1 - 40; + } + if (x2 > ViewX2) + ViewX2 = x2 + 40; + if (y2 > ViewY2) + ViewY2 = y2 + 40; + + resizeContents(int(Scale * float(ViewX2 - ViewX1)), int(Scale * float(ViewY2 - ViewY1))); + scrollBy(dx, dy); } // --------------------------------------------------- // Sets an arbitrary coordinate onto the next grid coordinate. -void Schematic::setOnGrid(int& x, int& y) +void Schematic::setOnGrid(int &x, int &y) { - if(x<0) x -= (GridX >> 1) - 1; - else x += GridX >> 1; - x -= x % GridX; + if (x < 0) + x -= (GridX >> 1) - 1; + else + x += GridX >> 1; + x -= x % GridX; - if(y<0) y -= (GridY >> 1) - 1; - else y += GridY >> 1; - y -= y % GridY; + if (y < 0) + y -= (GridY >> 1) - 1; + else + y += GridY >> 1; + y -= y % GridY; } // --------------------------------------------------- void Schematic::paintGrid(ViewPainter *p, int cX, int cY, int Width, int Height) { - if(!GridOn) return; - - p->Painter->setPen(QPen(Qt::black,0)); - int dx = -int(Scale*float(ViewX1)) - cX; - int dy = -int(Scale*float(ViewY1)) - cY; - p->Painter->drawLine(-3+dx, dy, 4+dx, dy); // small cross at origin - p->Painter->drawLine( dx,-3+dy, dx, 4+dy); - - - int x1 = int(float(cX)/Scale) + ViewX1; - int y1 = int(float(cY)/Scale) + ViewY1; - - /// \todo setting the center of rotation on the grid causes the center to move when doing multiple rotations when it is not already on the grid. Should not force the center but force the component alignment after rotation. - setOnGrid(x1, y1); - if(x1<0) x1 -= GridX - 1; - else x1 += GridX; - x1 -= x1 % (GridX << 1); + if (!GridOn) + return; - if(y1<0) y1 -= GridY - 1; - else y1 += GridY; - y1 -= y1 % (GridY << 1); + p->Painter->setPen(QPen(Qt::black, 0)); + int dx = -int(Scale * float(ViewX1)) - cX; + int dy = -int(Scale * float(ViewY1)) - cY; + p->Painter->drawLine(-3 + dx, dy, 4 + dx, dy); // small cross at origin + p->Painter->drawLine(dx, -3 + dy, dx, 4 + dy); - float X, Y, Y0, DX, DY; - X = float(x1)*Scale + p->DX; - Y = Y0 = float(y1)*Scale + p->DY; - x1 = X > 0.0 ? int(X + 0.5) : int(X - 0.5); - y1 = Y > 0.0 ? int(Y + 0.5) : int(Y - 0.5); + int x1 = int(float(cX) / Scale) + ViewX1; + int y1 = int(float(cY) / Scale) + ViewY1; + /// \todo setting the center of rotation on the grid causes the center to move when doing multiple rotations when it is not already on the grid. Should not force the center but force the component alignment after rotation. + setOnGrid(x1, y1); + if (x1 < 0) + x1 -= GridX - 1; + else + x1 += GridX; + x1 -= x1 % (GridX << 1); - int xEnd = x1 + Width; - int yEnd = y1 + Height; - DX = float(GridX << 1) * Scale; // every second grid a point - DY = float(GridY << 1) * Scale; - while(DX <= 8.0) DX *= 1.5; // if too narrow, every third grid a point - while(DY <= 8.0) DY *= 1.5; // if too narrow, every third grid a point + if (y1 < 0) + y1 -= GridY - 1; + else + y1 += GridY; + y1 -= y1 % (GridY << 1); - while(x1 < xEnd) { - Y = Y0; + float X, Y, Y0, DX, DY; + X = float(x1) * Scale + p->DX; + Y = Y0 = float(y1) * Scale + p->DY; + x1 = X > 0.0 ? int(X + 0.5) : int(X - 0.5); y1 = Y > 0.0 ? int(Y + 0.5) : int(Y - 0.5); - while(y1 < yEnd) { - p->Painter->drawPoint(x1, y1); // paint grid - Y += DY; - y1 = Y > 0.0 ? int(Y + 0.5) : int(Y - 0.5); + + int xEnd = x1 + Width; + int yEnd = y1 + Height; + DX = float(GridX << 1) * Scale; // every second grid a point + DY = float(GridY << 1) * Scale; + while (DX <= 8.0) + DX *= 1.5; // if too narrow, every third grid a point + while (DY <= 8.0) + DY *= 1.5; // if too narrow, every third grid a point + + while (x1 < xEnd) { + Y = Y0; + y1 = Y > 0.0 ? int(Y + 0.5) : int(Y - 0.5); + while (y1 < yEnd) { + p->Painter->drawPoint(x1, y1); // paint grid + Y += DY; + y1 = Y > 0.0 ? int(Y + 0.5) : int(Y - 0.5); + } + X += DX; + x1 = X > 0.0 ? int(X + 0.5) : int(X - 0.5); } - X += DX; - x1 = X > 0.0 ? int(X + 0.5) : int(X - 0.5); - } } // --------------------------------------------------- // Correction factor for unproportional font scaling. float Schematic::textCorr() { - QFont Font = QucsSettings.font; - Font.setPointSizeF( Scale * float(Font.pointSize()) ); - // use the screen-compatible metric - QFontMetrics metrics(Font, 0); - return (Scale / float(metrics.lineSpacing())); + QFont Font = QucsSettings.font; + Font.setPointSizeF(Scale * float(Font.pointSize())); + // use the screen-compatible metric + QFontMetrics metrics(Font, 0); + return (Scale / float(metrics.lineSpacing())); } // --------------------------------------------------- -void Schematic::sizeOfAll(int& xmin, int& ymin, int& xmax, int& ymax) +void Schematic::sizeOfAll(int &xmin, int &ymin, int &xmax, int &ymax) { - xmin=INT_MAX; - ymin=INT_MAX; - xmax=INT_MIN; - ymax=INT_MIN; - Component *pc; - Diagram *pd; - Wire *pw; - WireLabel *pl; - Painting *pp; - - if(Components->isEmpty()) - if(Wires->isEmpty()) - if(Diagrams->isEmpty()) - if(Paintings->isEmpty()) { - xmin = xmax = 0; - ymin = ymax = 0; - return; + xmin = INT_MAX; + ymin = INT_MAX; + xmax = INT_MIN; + ymax = INT_MIN; + Component *pc; + Diagram *pd; + Wire *pw; + WireLabel *pl; + Painting *pp; + + if (Components->isEmpty()) + if (Wires->isEmpty()) + if (Diagrams->isEmpty()) + if (Paintings->isEmpty()) { + xmin = xmax = 0; + ymin = ymax = 0; + return; + } + + float Corr = textCorr(); + int x1, y1, x2, y2; + // find boundings of all components + for (pc = Components->first(); pc != 0; pc = Components->next()) { + pc->entireBounds(x1, y1, x2, y2, Corr); + if (x1 < xmin) + xmin = x1; + if (x2 > xmax) + xmax = x2; + if (y1 < ymin) + ymin = y1; + if (y2 > ymax) + ymax = y2; + } + + // find boundings of all wires + for (pw = Wires->first(); pw != 0; pw = Wires->next()) { + if (pw->x1 < xmin) + xmin = pw->x1; + if (pw->x2 > xmax) + xmax = pw->x2; + if (pw->y1 < ymin) + ymin = pw->y1; + if (pw->y2 > ymax) + ymax = pw->y2; + + pl = pw->Label; + if (pl) { // check position of wire label + pl->getLabelBounding(x1, y1, x2, y2); + if (x1 < xmin) + xmin = x1; + if (x2 > xmax) + xmax = x2; + if (y1 < ymin) + ymin = y1; + if (y2 > ymax) + ymax = y2; + } + } + + // find boundings of all node labels + for (Node *pn = Nodes->first(); pn != 0; pn = Nodes->next()) { + pl = pn->Label; + if (pl) { // check position of node label + pl->getLabelBounding(x1, y1, x2, y2); + if (x1 < xmin) + xmin = x1; + if (x2 > xmax) + xmax = x2; + if (y1 < ymin) + ymin = y1; + if (y2 > ymax) + ymax = y2; } + } + // find boundings of all diagrams + for (pd = Diagrams->first(); pd != 0; pd = Diagrams->next()) { + pd->Bounding(x1, y1, x2, y2); + if (x1 < xmin) + xmin = x1; + if (x2 > xmax) + xmax = x2; + if (y1 < ymin) + ymin = y1; + if (y2 > ymax) + ymax = y2; - float Corr = textCorr(); - int x1, y1, x2, y2; - // find boundings of all components - for(pc = Components->first(); pc != 0; pc = Components->next()) { - pc->entireBounds(x1, y1, x2, y2, Corr); - if(x1 < xmin) xmin = x1; - if(x2 > xmax) xmax = x2; - if(y1 < ymin) ymin = y1; - if(y2 > ymax) ymax = y2; - } - - // find boundings of all wires - for(pw = Wires->first(); pw != 0; pw = Wires->next()) { - if(pw->x1 < xmin) xmin = pw->x1; - if(pw->x2 > xmax) xmax = pw->x2; - if(pw->y1 < ymin) ymin = pw->y1; - if(pw->y2 > ymax) ymax = pw->y2; - - pl = pw->Label; - if(pl) { // check position of wire label - pl->getLabelBounding(x1,y1,x2,y2); - if(x1 < xmin) xmin = x1; - if(x2 > xmax) xmax = x2; - if(y1 < ymin) ymin = y1; - if(y2 > ymax) ymax = y2; - } - } - - // find boundings of all node labels - for(Node *pn = Nodes->first(); pn != 0; pn = Nodes->next()) { - pl = pn->Label; - if(pl) { // check position of node label - pl->getLabelBounding(x1,y1,x2,y2); - if(x1 < xmin) xmin = x1; - if(x2 > xmax) xmax = x2; - if(y1 < ymin) ymin = y1; - if(y2 > ymax) ymax = y2; - } - } - - // find boundings of all diagrams - for(pd = Diagrams->first(); pd != 0; pd = Diagrams->next()) { - pd->Bounding(x1, y1, x2, y2); - if(x1 < xmin) xmin = x1; - if(x2 > xmax) xmax = x2; - if(y1 < ymin) ymin = y1; - if(y2 > ymax) ymax = y2; - - for (Graph *pg : pd->Graphs) - // test all markers of diagram - for (Marker *pm : pg->Markers) { - pm->Bounding(x1, y1, x2, y2); - if(x1 < xmin) xmin = x1; - if(x2 > xmax) xmax = x2; - if(y1 < ymin) ymin = y1; - if(y2 > ymax) ymax = y2; - } - } - - // find boundings of all Paintings - for(pp = Paintings->first(); pp != nullptr; pp = Paintings->next()) { - pp->Bounding(x1, y1, x2, y2); - if(x1 < xmin) xmin = x1; - if(x2 > xmax) xmax = x2; - if(y1 < ymin) ymin = y1; - if(y2 > ymax) ymax = y2; - } + for (Graph *pg : pd->Graphs) + // test all markers of diagram + for (Marker *pm : pg->Markers) { + pm->Bounding(x1, y1, x2, y2); + if (x1 < xmin) + xmin = x1; + if (x2 > xmax) + xmax = x2; + if (y1 < ymin) + ymin = y1; + if (y2 > ymax) + ymax = y2; + } + } + + // find boundings of all Paintings + for (pp = Paintings->first(); pp != nullptr; pp = Paintings->next()) { + pp->Bounding(x1, y1, x2, y2); + if (x1 < xmin) + xmin = x1; + if (x2 > xmax) + xmax = x2; + if (y1 < ymin) + ymin = y1; + if (y2 > ymax) + ymax = y2; + } } -void Schematic::sizeOfSelection(int& xmin, int& ymin, int& xmax, int& ymax) +void Schematic::sizeOfSelection(int &xmin, int &ymin, int &xmax, int &ymax) { - xmin=INT_MAX; - ymin=INT_MAX; - xmax=INT_MIN; - ymax=INT_MIN; + xmin = INT_MAX; + ymin = INT_MAX; + xmax = INT_MIN; + ymax = INT_MIN; Component *pc; Diagram *pd; Wire *pw; @@ -1070,102 +1139,129 @@ void Schematic::sizeOfSelection(int& xmin, int& ymin, int& xmax, int& ymax) bool isAnySelected = false; - if(Components->isEmpty()) - if(Wires->isEmpty()) - if(Diagrams->isEmpty()) - if(Paintings->isEmpty()) { + if (Components->isEmpty()) + if (Wires->isEmpty()) + if (Diagrams->isEmpty()) + if (Paintings->isEmpty()) { xmin = xmax = 0; ymin = ymax = 0; return; } - float Corr = textCorr(); int x1, y1, x2, y2; // find boundings of all components - for(pc = Components->first(); pc != 0; pc = Components->next()) { + for (pc = Components->first(); pc != 0; pc = Components->next()) { if (!pc->isSelected) { continue; } isAnySelected = true; pc->entireBounds(x1, y1, x2, y2, Corr); - if(x1 < xmin) xmin = x1; - if(x2 > xmax) xmax = x2; - if(y1 < ymin) ymin = y1; - if(y2 > ymax) ymax = y2; + if (x1 < xmin) + xmin = x1; + if (x2 > xmax) + xmax = x2; + if (y1 < ymin) + ymin = y1; + if (y2 > ymax) + ymax = y2; } // find boundings of all wires - for(pw = Wires->first(); pw != 0; pw = Wires->next()) { + for (pw = Wires->first(); pw != 0; pw = Wires->next()) { if (!pw->isSelected) { continue; } isAnySelected = true; - if(pw->x1 < xmin) xmin = pw->x1; - if(pw->x2 > xmax) xmax = pw->x2; - if(pw->y1 < ymin) ymin = pw->y1; - if(pw->y2 > ymax) ymax = pw->y2; + if (pw->x1 < xmin) + xmin = pw->x1; + if (pw->x2 > xmax) + xmax = pw->x2; + if (pw->y1 < ymin) + ymin = pw->y1; + if (pw->y2 > ymax) + ymax = pw->y2; pl = pw->Label; - if(pl) { // check position of wire label - pl->getLabelBounding(x1,y1,x2,y2); - if(x1 < xmin) xmin = x1; - if(x2 > xmax) xmax = x2; - if(y1 < ymin) ymin = y1; - if(y2 > ymax) ymax = y2; + if (pl) { // check position of wire label + pl->getLabelBounding(x1, y1, x2, y2); + if (x1 < xmin) + xmin = x1; + if (x2 > xmax) + xmax = x2; + if (y1 < ymin) + ymin = y1; + if (y2 > ymax) + ymax = y2; } } // find boundings of all node labels - for(Node *pn = Nodes->first(); pn != 0; pn = Nodes->next()) { + for (Node *pn = Nodes->first(); pn != 0; pn = Nodes->next()) { if (!pn->isSelected) { continue; } isAnySelected = true; pl = pn->Label; - if(pl) { // check position of node label - pl->getLabelBounding(x1,y1,x2,y2); - if(x1 < xmin) xmin = x1; - if(x2 > xmax) xmax = x2; - if(y1 < ymin) ymin = y1; - if(y2 > ymax) ymax = y2; + if (pl) { // check position of node label + pl->getLabelBounding(x1, y1, x2, y2); + if (x1 < xmin) + xmin = x1; + if (x2 > xmax) + xmax = x2; + if (y1 < ymin) + ymin = y1; + if (y2 > ymax) + ymax = y2; } } // find boundings of all diagrams - for(pd = Diagrams->first(); pd != 0; pd = Diagrams->next()) { + for (pd = Diagrams->first(); pd != 0; pd = Diagrams->next()) { if (!pd->isSelected) { continue; } isAnySelected = true; pd->Bounding(x1, y1, x2, y2); - if(x1 < xmin) xmin = x1; - if(x2 > xmax) xmax = x2; - if(y1 < ymin) ymin = y1; - if(y2 > ymax) ymax = y2; + if (x1 < xmin) + xmin = x1; + if (x2 > xmax) + xmax = x2; + if (y1 < ymin) + ymin = y1; + if (y2 > ymax) + ymax = y2; for (Graph *pg : pd->Graphs) // test all markers of diagram for (Marker *pm : pg->Markers) { pm->Bounding(x1, y1, x2, y2); - if(x1 < xmin) xmin = x1; - if(x2 > xmax) xmax = x2; - if(y1 < ymin) ymin = y1; - if(y2 > ymax) ymax = y2; + if (x1 < xmin) + xmin = x1; + if (x2 > xmax) + xmax = x2; + if (y1 < ymin) + ymin = y1; + if (y2 > ymax) + ymax = y2; } } // find boundings of all Paintings - for(pp = Paintings->first(); pp != nullptr; pp = Paintings->next()) { + for (pp = Paintings->first(); pp != nullptr; pp = Paintings->next()) { if (!pp->isSelected) { continue; } isAnySelected = true; pp->Bounding(x1, y1, x2, y2); - if(x1 < xmin) xmin = x1; - if(x2 > xmax) xmax = x2; - if(y1 < ymin) ymin = y1; - if(y2 > ymax) ymax = y2; + if (x1 < xmin) + xmin = x1; + if (x2 > xmax) + xmax = x2; + if (y1 < ymin) + ymin = y1; + if (y2 > ymax) + ymax = y2; } if (!isAnySelected) { @@ -1178,98 +1274,95 @@ void Schematic::sizeOfSelection(int& xmin, int& ymin, int& xmax, int& ymax) // Rotates all selected components around their midpoint. bool Schematic::rotateElements() { - Wires->setAutoDelete(false); - Components->setAutoDelete(false); - - int x1=INT_MAX, y1=INT_MAX; - int x2=INT_MIN, y2=INT_MIN; - QList ElementCache; - copyLabels(x1, y1, x2, y2, &ElementCache); // must be first of all ! - copyComponents(x1, y1, x2, y2, &ElementCache); - copyWires(x1, y1, x2, y2, &ElementCache); - copyPaintings(x1, y1, x2, y2, &ElementCache); - if(y1 == INT_MAX) return false; // no element selected - - Wires->setAutoDelete(true); - Components->setAutoDelete(true); - - x1 = (x1+x2) >> 1; // center for rotation - y1 = (y1+y2) >> 1; - //setOnGrid(x1, y1); - - - Wire *pw; - Painting *pp; - Component *pc; - WireLabel *pl; - // re-insert elements - for (Element *pe : ElementCache) - switch(pe->Type) { - case isComponent: - case isAnalogComponent: - case isDigitalComponent: - pc = (Component*)pe; - pc->rotate(); //rotate component !before! rotating its center - pc->setCenter(pc->cy - y1 + x1, x1 - pc->cx + y1); - insertRawComponent(pc); - break; - - case isWire: - pw = (Wire*)pe; - x2 = pw->x1; - pw->x1 = pw->y1 - y1 + x1; - pw->y1 = x1 - x2 + y1; - x2 = pw->x2; - pw->x2 = pw->y2 - y1 + x1; - pw->y2 = x1 - x2 + y1; - pl = pw->Label; - if(pl) { - x2 = pl->cx; - pl->cx = pl->cy - y1 + x1; - pl->cy = x1 - x2 + y1; - if(pl->Type == isHWireLabel) - pl->Type = isVWireLabel; - else pl->Type = isHWireLabel; + Wires->setAutoDelete(false); + Components->setAutoDelete(false); + + int x1 = INT_MAX, y1 = INT_MAX; + int x2 = INT_MIN, y2 = INT_MIN; + QList ElementCache; + copyLabels(x1, y1, x2, y2, &ElementCache); // must be first of all ! + copyComponents(x1, y1, x2, y2, &ElementCache); + copyWires(x1, y1, x2, y2, &ElementCache); + copyPaintings(x1, y1, x2, y2, &ElementCache); + if (y1 == INT_MAX) + return false; // no element selected + + Wires->setAutoDelete(true); + Components->setAutoDelete(true); + + x1 = (x1 + x2) >> 1; // center for rotation + y1 = (y1 + y2) >> 1; + //setOnGrid(x1, y1); + + Wire *pw; + Painting *pp; + Component *pc; + WireLabel *pl; + // re-insert elements + for (Element *pe : ElementCache) + switch (pe->Type) { + case isComponent: + case isAnalogComponent: + case isDigitalComponent: + pc = (Component *) pe; + pc->rotate(); //rotate component !before! rotating its center + pc->setCenter(pc->cy - y1 + x1, x1 - pc->cx + y1); + insertRawComponent(pc); + break; + + case isWire: + pw = (Wire *) pe; + x2 = pw->x1; + pw->x1 = pw->y1 - y1 + x1; + pw->y1 = x1 - x2 + y1; + x2 = pw->x2; + pw->x2 = pw->y2 - y1 + x1; + pw->y2 = x1 - x2 + y1; + pl = pw->Label; + if (pl) { + x2 = pl->cx; + pl->cx = pl->cy - y1 + x1; + pl->cy = x1 - x2 + y1; + if (pl->Type == isHWireLabel) + pl->Type = isVWireLabel; + else + pl->Type = isHWireLabel; + } + insertWire(pw); + break; + + case isHWireLabel: + case isVWireLabel: + pl = (WireLabel *) pe; + x2 = pl->x1; + pl->x1 = pl->y1 - y1 + x1; + pl->y1 = x1 - x2 + y1; + break; + case isNodeLabel: + pl = (WireLabel *) pe; + if (pl->pOwner == 0) { + x2 = pl->x1; + pl->x1 = pl->y1 - y1 + x1; + pl->y1 = x1 - x2 + y1; + } + x2 = pl->cx; + pl->cx = pl->cy - y1 + x1; + pl->cy = x1 - x2 + y1; + insertNodeLabel(pl); + break; + + case isPainting: + pp = (Painting *) pe; + pp->rotate(x1, y1); // rotate around the center x1 y1 + Paintings->append(pp); + break; + default:; } - insertWire(pw); - break; - - case isHWireLabel: - case isVWireLabel: - pl = (WireLabel*)pe; - x2 = pl->x1; - pl->x1 = pl->y1 - y1 + x1; - pl->y1 = x1 - x2 + y1; - break; - case isNodeLabel: - pl = (WireLabel*)pe; - if(pl->pOwner == 0) { - x2 = pl->x1; - pl->x1 = pl->y1 - y1 + x1; - pl->y1 = x1 - x2 + y1; - } - x2 = pl->cx; - pl->cx = pl->cy - y1 + x1; - pl->cy = x1 - x2 + y1; - insertNodeLabel(pl); - break; - - case isPainting: - pp = (Painting*)pe; - pp->rotate(); // rotate painting !before! rotating its center - pp->getCenter(x2, y2); - //qDebug("pp->getCenter(x2, y2): (%i,%i)\n", x2, y2); - //qDebug("(x1,y1) (x2,y2): (%i,%i) (%i,%i)\n", x1,y1,x2,y2); - pp->setCenter(y2-y1 + x1, x1-x2 + y1); - Paintings->append(pp); - break; - default: ; - } - - ElementCache.clear(); - - setChanged(true, true); - return true; + + ElementCache.clear(); + + setChanged(true, true); + return true; } // --------------------------------------------------- @@ -1277,255 +1370,261 @@ bool Schematic::rotateElements() // First copy them to 'ElementCache', then mirror and insert again. bool Schematic::mirrorXComponents() { - Wires->setAutoDelete(false); - Components->setAutoDelete(false); + Wires->setAutoDelete(false); + Components->setAutoDelete(false); - int x1, y1, x2, y2; - QList ElementCache; - if(!copyComps2WiresPaints(x1, y1, x2, y2, &ElementCache)) - return false; - Wires->setAutoDelete(true); - Components->setAutoDelete(true); - - y1 = (y1+y2) >> 1; // axis for mirroring - setOnGrid(y2, y1); - y1 <<= 1; - - - Wire *pw; - Painting *pp; - Component *pc; - WireLabel *pl; - // re-insert elements - for (Element *pe : ElementCache) - switch(pe->Type) { - case isComponent: - case isAnalogComponent: - case isDigitalComponent: - pc = (Component*)pe; - pc->mirrorX(); // mirror component !before! mirroring its center - pc->setCenter(pc->cx, y1 - pc->cy); - insertRawComponent(pc); - break; - case isWire: - pw = (Wire*)pe; - pw->y1 = y1 - pw->y1; - pw->y2 = y1 - pw->y2; - pl = pw->Label; - if(pl) pl->cy = y1 - pl->cy; - insertWire(pw); - break; - case isHWireLabel: - case isVWireLabel: - pl = (WireLabel*)pe; - pl->y1 = y1 - pl->y1; - break; - case isNodeLabel: - pl = (WireLabel*)pe; - if(pl->pOwner == 0) - pl->y1 = y1 - pl->y1; - pl->cy = y1 - pl->cy; - insertNodeLabel(pl); - break; - case isPainting: - pp = (Painting*)pe; - pp->getCenter(x2, y2); - pp->mirrorX(); // mirror painting !before! mirroring its center - pp->setCenter(x2, y1 - y2); - Paintings->append(pp); - break; - default: ; - } - - ElementCache.clear(); - setChanged(true, true); - return true; + int x1, y1, x2, y2; + QList ElementCache; + if (!copyComps2WiresPaints(x1, y1, x2, y2, &ElementCache)) + return false; + Wires->setAutoDelete(true); + Components->setAutoDelete(true); + + y1 = (y1 + y2) >> 1; // axis for mirroring + setOnGrid(y2, y1); + y1 <<= 1; + + Wire *pw; + Painting *pp; + Component *pc; + WireLabel *pl; + // re-insert elements + for (Element *pe : ElementCache) + switch (pe->Type) { + case isComponent: + case isAnalogComponent: + case isDigitalComponent: + pc = (Component *) pe; + pc->mirrorX(); // mirror component !before! mirroring its center + pc->setCenter(pc->cx, y1 - pc->cy); + insertRawComponent(pc); + break; + case isWire: + pw = (Wire *) pe; + pw->y1 = y1 - pw->y1; + pw->y2 = y1 - pw->y2; + pl = pw->Label; + if (pl) + pl->cy = y1 - pl->cy; + insertWire(pw); + break; + case isHWireLabel: + case isVWireLabel: + pl = (WireLabel *) pe; + pl->y1 = y1 - pl->y1; + break; + case isNodeLabel: + pl = (WireLabel *) pe; + if (pl->pOwner == 0) + pl->y1 = y1 - pl->y1; + pl->cy = y1 - pl->cy; + insertNodeLabel(pl); + break; + case isPainting: + pp = (Painting *) pe; + pp->getCenter(x2, y2); + pp->mirrorX(); // mirror painting !before! mirroring its center + pp->setCenter(x2, y1 - y2); + Paintings->append(pp); + break; + default:; + } + + ElementCache.clear(); + setChanged(true, true); + return true; } // --------------------------------------------------- // Mirrors all selected components. First copy them to 'ElementCache', then mirror and insert again. bool Schematic::mirrorYComponents() { - Wires->setAutoDelete(false); - Components->setAutoDelete(false); + Wires->setAutoDelete(false); + Components->setAutoDelete(false); - int x1, y1, x2, y2; - QList ElementCache; - if(!copyComps2WiresPaints(x1, y1, x2, y2, &ElementCache)) - return false; - Wires->setAutoDelete(true); - Components->setAutoDelete(true); - - x1 = (x1+x2) >> 1; // axis for mirroring - setOnGrid(x1, x2); - x1 <<= 1; - - Wire *pw; - Painting *pp; - Component *pc; - WireLabel *pl; - // re-insert elements - for (Element *pe : ElementCache) - switch(pe->Type) { - case isComponent: - case isAnalogComponent: - case isDigitalComponent: - pc = (Component*)pe; - pc->mirrorY(); // mirror component !before! mirroring its center - pc->setCenter(x1 - pc->cx, pc->cy); - insertRawComponent(pc); - break; - case isWire: - pw = (Wire*)pe; - pw->x1 = x1 - pw->x1; - pw->x2 = x1 - pw->x2; - pl = pw->Label; - if(pl) pl->cx = x1 - pl->cx; - insertWire(pw); - break; - case isHWireLabel: - case isVWireLabel: - pl = (WireLabel*)pe; - pl->x1 = x1 - pl->x1; - break; - case isNodeLabel: - pl = (WireLabel*)pe; - if(pl->pOwner == 0) - pl->x1 = x1 - pl->x1; - pl->cx = x1 - pl->cx; - insertNodeLabel(pl); - break; - case isPainting: - pp = (Painting*)pe; - pp->getCenter(x2, y2); - pp->mirrorY(); // mirror painting !before! mirroring its center - pp->setCenter(x1 - x2, y2); - Paintings->append(pp); - break; - default: ; - } - - ElementCache.clear(); - setChanged(true, true); - return true; + int x1, y1, x2, y2; + QList ElementCache; + if (!copyComps2WiresPaints(x1, y1, x2, y2, &ElementCache)) + return false; + Wires->setAutoDelete(true); + Components->setAutoDelete(true); + + x1 = (x1 + x2) >> 1; // axis for mirroring + setOnGrid(x1, x2); + x1 <<= 1; + + Wire *pw; + Painting *pp; + Component *pc; + WireLabel *pl; + // re-insert elements + for (Element *pe : ElementCache) + switch (pe->Type) { + case isComponent: + case isAnalogComponent: + case isDigitalComponent: + pc = (Component *) pe; + pc->mirrorY(); // mirror component !before! mirroring its center + pc->setCenter(x1 - pc->cx, pc->cy); + insertRawComponent(pc); + break; + case isWire: + pw = (Wire *) pe; + pw->x1 = x1 - pw->x1; + pw->x2 = x1 - pw->x2; + pl = pw->Label; + if (pl) + pl->cx = x1 - pl->cx; + insertWire(pw); + break; + case isHWireLabel: + case isVWireLabel: + pl = (WireLabel *) pe; + pl->x1 = x1 - pl->x1; + break; + case isNodeLabel: + pl = (WireLabel *) pe; + if (pl->pOwner == 0) + pl->x1 = x1 - pl->x1; + pl->cx = x1 - pl->cx; + insertNodeLabel(pl); + break; + case isPainting: + pp = (Painting *) pe; + pp->getCenter(x2, y2); + pp->mirrorY(); // mirror painting !before! mirroring its center + pp->setCenter(x1 - x2, y2); + Paintings->append(pp); + break; + default:; + } + + ElementCache.clear(); + setChanged(true, true); + return true; } // --------------------------------------------------- // Updates the graph data of all diagrams (load from data files). void Schematic::reloadGraphs() { - QFileInfo Info(DocName); - for(Diagram *pd = Diagrams->first(); pd != 0; pd = Diagrams->next()) - pd->loadGraphData(Info.path()+QDir::separator()+DataSet); + QFileInfo Info(DocName); + for (Diagram *pd = Diagrams->first(); pd != 0; pd = Diagrams->next()) + pd->loadGraphData(Info.path() + QDir::separator() + DataSet); } -// Copy function, +// Copy function, void Schematic::copy() { - QString s = createClipboardFile(); - QClipboard *cb = QApplication::clipboard(); // get system clipboard - if (!s.isEmpty()) { - cb->setText(s, QClipboard::Clipboard); - } + QString s = createClipboardFile(); + QClipboard *cb = QApplication::clipboard(); // get system clipboard + if (!s.isEmpty()) { + cb->setText(s, QClipboard::Clipboard); + } } // --------------------------------------------------- // Cut function, copy followed by deletion void Schematic::cut() { - copy(); - deleteElements(); //delete selected elements - viewport()->update(); + copy(); + deleteElements(); //delete selected elements + viewport()->update(); } // --------------------------------------------------- // Performs paste function from clipboard bool Schematic::paste(QTextStream *stream, Q3PtrList *pe) { - return pasteFromClipboard(stream, pe); + return pasteFromClipboard(stream, pe); } // --------------------------------------------------- // Loads this Qucs document. bool Schematic::load() { - DocComps.clear(); - DocWires.clear(); - DocNodes.clear(); - DocDiags.clear(); - DocPaints.clear(); - SymbolPaints.clear(); - - if(!loadDocument()) return false; - lastSaved = QDateTime::currentDateTime(); - - while(!undoAction.isEmpty()) { - delete undoAction.last(); - undoAction.pop_back(); - } - undoActionIdx = 0; - while(!undoSymbol.isEmpty()) { - delete undoSymbol.last(); - undoSymbol.pop_back(); - } - symbolMode = true; - setChanged(false, true); // "not changed" state, but put on undo stack - undoSymbolIdx = 0; - undoSymbol.at(undoSymbolIdx)->replace(1, 1, 'i'); - symbolMode = false; - setChanged(false, true); // "not changed" state, but put on undo stack - undoActionIdx = 0; - undoAction.at(undoActionIdx)->replace(1, 1, 'i'); - - // The undo stack of the circuit symbol is initialized when first - // entering its edit mode. - - // have to call this to avoid crash at sizeOfAll - becomeCurrent(false); - - sizeOfAll(UsedX1, UsedY1, UsedX2, UsedY2); - if(ViewX1 > UsedX1) ViewX1 = UsedX1; - if(ViewY1 > UsedY1) ViewY1 = UsedY1; - if(ViewX2 < UsedX2) ViewX2 = UsedX2; - if(ViewY2 < UsedY2) ViewY2 = UsedY2; - zoom(1.0f); - setContentsPos(tmpViewX1, tmpViewY1); - tmpViewX1 = tmpViewY1 = -200; // was used as temporary cache - return true; + DocComps.clear(); + DocWires.clear(); + DocNodes.clear(); + DocDiags.clear(); + DocPaints.clear(); + SymbolPaints.clear(); + + if (!loadDocument()) + return false; + lastSaved = QDateTime::currentDateTime(); + + while (!undoAction.isEmpty()) { + delete undoAction.last(); + undoAction.pop_back(); + } + undoActionIdx = 0; + while (!undoSymbol.isEmpty()) { + delete undoSymbol.last(); + undoSymbol.pop_back(); + } + symbolMode = true; + setChanged(false, true); // "not changed" state, but put on undo stack + undoSymbolIdx = 0; + undoSymbol.at(undoSymbolIdx)->replace(1, 1, 'i'); + symbolMode = false; + setChanged(false, true); // "not changed" state, but put on undo stack + undoActionIdx = 0; + undoAction.at(undoActionIdx)->replace(1, 1, 'i'); + + // The undo stack of the circuit symbol is initialized when first + // entering its edit mode. + + // have to call this to avoid crash at sizeOfAll + becomeCurrent(false); + + sizeOfAll(UsedX1, UsedY1, UsedX2, UsedY2); + if (ViewX1 > UsedX1) + ViewX1 = UsedX1; + if (ViewY1 > UsedY1) + ViewY1 = UsedY1; + if (ViewX2 < UsedX2) + ViewX2 = UsedX2; + if (ViewY2 < UsedY2) + ViewY2 = UsedY2; + zoom(1.0f); + setContentsPos(tmpViewX1, tmpViewY1); + tmpViewX1 = tmpViewY1 = -200; // was used as temporary cache + return true; } // --------------------------------------------------- // Saves this Qucs document. Returns the number of subcircuit ports. int Schematic::save() { - int result = adjustPortNumbers();// same port number for schematic and symbol - if(saveDocument() < 0) - return -1; + int result = adjustPortNumbers(); // same port number for schematic and symbol + if (saveDocument() < 0) + return -1; - QFileInfo Info(DocName); - lastSaved = Info.lastModified(); + QFileInfo Info(DocName); + lastSaved = Info.lastModified(); - if(result >= 0) { - setChanged(false); + if (result >= 0) { + setChanged(false); - QVector::iterator it; - for (it = undoAction.begin(); it != undoAction.end(); it++) { - (*it)->replace(1, 1, ' '); //at(1) = ' '; state of being changed - } - //(1) = 'i'; // state of being unchanged - undoAction.at(undoActionIdx)->replace(1, 1, 'i'); + QVector::iterator it; + for (it = undoAction.begin(); it != undoAction.end(); it++) { + (*it)->replace(1, 1, ' '); //at(1) = ' '; state of being changed + } + //(1) = 'i'; // state of being unchanged + undoAction.at(undoActionIdx)->replace(1, 1, 'i'); - for (it = undoSymbol.begin(); it != undoSymbol.end(); it++) { - (*it)->replace(1, 1, ' '); //at(1) = ' '; state of being changed + for (it = undoSymbol.begin(); it != undoSymbol.end(); it++) { + (*it)->replace(1, 1, ' '); //at(1) = ' '; state of being changed + } + //at(1) = 'i'; // state of being unchanged + undoSymbol.at(undoSymbolIdx)->replace(1, 1, 'i'); } - //at(1) = 'i'; // state of being unchanged - undoSymbol.at(undoSymbolIdx)->replace(1, 1, 'i'); - } - // update the subcircuit file lookup hashes - QucsMain->updateSchNameHash(); - QucsMain->updateSpiceNameHash(); + // update the subcircuit file lookup hashes + QucsMain->updateSchNameHash(); + QucsMain->updateSpiceNameHash(); - return result; + return result; } // --------------------------------------------------- @@ -1533,338 +1632,337 @@ int Schematic::save() // equal add or remove some in the symbol. int Schematic::adjustPortNumbers() { - int x1, x2, y1, y2; - // get size of whole symbol to know where to place new ports - if(symbolMode) sizeOfAll(x1, y1, x2, y2); - else { - Components = &SymbolComps; - Wires = &SymbolWires; - Nodes = &SymbolNodes; - Diagrams = &SymbolDiags; - Paintings = &SymbolPaints; - sizeOfAll(x1, y1, x2, y2); - Components = &DocComps; - Wires = &DocWires; - Nodes = &DocNodes; - Diagrams = &DocDiags; - Paintings = &DocPaints; - } - x1 += 40; - y2 += 20; - setOnGrid(x1, y2); - - - Painting *pp; - // delete all port names in symbol - for(pp = SymbolPaints.first(); pp!=0; pp = SymbolPaints.next()) - if(pp->Name == ".PortSym ") - ((PortSymbol*)pp)->nameStr = ""; - - QString Str; - int countPort = 0; - - QFileInfo Info (DataDisplay); - QString Suffix = Info.suffix(); - - // handle VHDL file symbol - if (Suffix == "vhd" || Suffix == "vhdl") { - QStringList::iterator it; - QStringList Names, GNames, GTypes, GDefs; - int Number; - - // get ports from VHDL file - QFileInfo Info(DocName); - QString Name = Info.path() + QDir::separator() + DataDisplay; - - // obtain VHDL information either from open text document or the - // file directly - VHDL_File_Info VInfo; - TextDoc * d = (TextDoc*)App->findDoc (Name); - if (d) - VInfo = VHDL_File_Info (d->document()->toPlainText()); - else - VInfo = VHDL_File_Info (Name, true); - - if (!VInfo.PortNames.isEmpty()) - Names = VInfo.PortNames.split(",", qucs::SkipEmptyParts); - - for(pp = SymbolPaints.first(); pp!=0; pp = SymbolPaints.next()) - if(pp->Name == ".ID ") { - ID_Text * id = (ID_Text *) pp; - id->Prefix = VInfo.EntityName.toUpper(); - id->Parameter.clear(); - if (!VInfo.GenNames.isEmpty()) - GNames = VInfo.GenNames.split(",", qucs::SkipEmptyParts); - if (!VInfo.GenTypes.isEmpty()) - GTypes = VInfo.GenTypes.split(",", qucs::SkipEmptyParts); - if (!VInfo.GenDefs.isEmpty()) - GDefs = VInfo.GenDefs.split(",", qucs::SkipEmptyParts);; - for(Number = 1, it = GNames.begin(); it != GNames.end(); ++it) { - id->Parameter.append(new SubParameter( - true, - *it+"="+GDefs[Number-1], - tr("generic")+" "+QString::number(Number), - GTypes[Number-1])); - Number++; - } - } - - for(Number = 1, it = Names.begin(); it != Names.end(); ++it, Number++) { - countPort++; - - Str = QString::number(Number); - // search for matching port symbol - for(pp = SymbolPaints.first(); pp!=0; pp = SymbolPaints.next()) - if(pp->Name == ".PortSym ") - if(((PortSymbol*)pp)->numberStr == Str) break; - - if(pp) - ((PortSymbol*)pp)->nameStr = *it; - else { - SymbolPaints.append(new PortSymbol(x1, y2, Str, *it)); - y2 += 40; - } - } - } - // handle Verilog-HDL file symbol - else if (Suffix == "v") { - - QStringList::iterator it; - QStringList Names; - int Number; - - // get ports from Verilog-HDL file - QFileInfo Info (DocName); - QString Name = Info.path() + QDir::separator() + DataDisplay; - - // obtain Verilog-HDL information either from open text document or the - // file directly - Verilog_File_Info VInfo; - TextDoc * d = (TextDoc*)App->findDoc (Name); - if (d) - VInfo = Verilog_File_Info (d->document()->toPlainText()); - else - VInfo = Verilog_File_Info (Name, true); - if (!VInfo.PortNames.isEmpty()) - Names = VInfo.PortNames.split(",", qucs::SkipEmptyParts); - - for(pp = SymbolPaints.first(); pp!=0; pp = SymbolPaints.next()) - if(pp->Name == ".ID ") { - ID_Text * id = (ID_Text *) pp; - id->Prefix = VInfo.ModuleName.toUpper(); - id->Parameter.clear(); - } - - for(Number = 1, it = Names.begin(); it != Names.end(); ++it, Number++) { - countPort++; - - Str = QString::number(Number); - // search for matching port symbol - for(pp = SymbolPaints.first(); pp!=0; pp = SymbolPaints.next()) - if(pp->Name == ".PortSym ") - if(((PortSymbol*)pp)->numberStr == Str) break; - - if(pp) - ((PortSymbol*)pp)->nameStr = *it; - else { - SymbolPaints.append(new PortSymbol(x1, y2, Str, *it)); - y2 += 40; - } - } - } - // handle Verilog-A file symbol - else if (Suffix == "va") { - - QStringList::iterator it; - QStringList Names; - int Number; - - // get ports from Verilog-A file - QFileInfo Info (DocName); - QString Name = Info.path() + QDir::separator() + DataDisplay; - - // obtain Verilog-A information either from open text document or the - // file directly - VerilogA_File_Info VInfo; - TextDoc * d = (TextDoc*)App->findDoc (Name); - if (d) - VInfo = VerilogA_File_Info (d->toPlainText()); - else - VInfo = VerilogA_File_Info (Name, true); - - if (!VInfo.PortNames.isEmpty()) - Names = VInfo.PortNames.split(",", qucs::SkipEmptyParts); - - for(pp = SymbolPaints.first(); pp!=0; pp = SymbolPaints.next()) - if(pp->Name == ".ID ") { - ID_Text * id = (ID_Text *) pp; - id->Prefix = VInfo.ModuleName.toUpper(); - id->Parameter.clear(); - } - - for(Number = 1, it = Names.begin(); it != Names.end(); ++it, Number++) { - countPort++; - - Str = QString::number(Number); - // search for matching port symbol - for(pp = SymbolPaints.first(); pp!=0; pp = SymbolPaints.next()) - if(pp->Name == ".PortSym ") - if(((PortSymbol*)pp)->numberStr == Str) break; - - if(pp) - ((PortSymbol*)pp)->nameStr = *it; - else { - SymbolPaints.append(new PortSymbol(x1, y2, Str, *it)); - y2 += 40; - } - } - } - // handle schematic symbol - else - { - // go through all components in a schematic - for(Component *pc = DocComps.first(); pc!=0; pc = DocComps.next()) - { - if(pc->Model == "Port") - { - countPort++; - - Str = pc->Props.getFirst()->Value; - // search for matching port symbol - for(pp = SymbolPaints.first(); pp!=0; pp = SymbolPaints.next()) - { - if(pp->Name == ".PortSym ") - { - if(((PortSymbol*)pp)->numberStr == Str) break; - } - } - - if(pp) - { - ((PortSymbol*)pp)->nameStr = pc->Name; - } - else - { - SymbolPaints.append(new PortSymbol(x1, y2, Str, pc->Name)); - y2 += 40; - } - } - } - } - - // delete not accounted port symbols - for(pp = SymbolPaints.first(); pp!=0; ) { - if(pp->Name == ".PortSym ") - if(((PortSymbol*)pp)->nameStr.isEmpty()) { - SymbolPaints.remove(); - pp = SymbolPaints.current(); - continue; - } - pp = SymbolPaints.next(); - } - - return countPort; -} - -// --------------------------------------------------- -bool Schematic::undo() -{ - if(symbolMode) { - if (undoSymbolIdx == 0) { return false; } - - rebuildSymbol(undoSymbol.at(--undoSymbolIdx)); - adjustPortNumbers(); // set port names - - emit signalUndoState(undoSymbolIdx != 0); - emit signalRedoState(undoSymbolIdx != undoSymbol.size()-1); - - if(undoSymbol.at(undoSymbolIdx)->at(1) == 'i' && - undoAction.at(undoActionIdx)->at(1) == 'i') { - setChanged(false, false); - return true; + int x1, x2, y1, y2; + // get size of whole symbol to know where to place new ports + if (symbolMode) + sizeOfAll(x1, y1, x2, y2); + else { + Components = &SymbolComps; + Wires = &SymbolWires; + Nodes = &SymbolNodes; + Diagrams = &SymbolDiags; + Paintings = &SymbolPaints; + sizeOfAll(x1, y1, x2, y2); + Components = &DocComps; + Wires = &DocWires; + Nodes = &DocNodes; + Diagrams = &DocDiags; + Paintings = &DocPaints; } + x1 += 40; + y2 += 20; + setOnGrid(x1, y2); - setChanged(true, false); - return true; - } - + Painting *pp; + // delete all port names in symbol + for (pp = SymbolPaints.first(); pp != 0; pp = SymbolPaints.next()) + if (pp->Name == ".PortSym ") + ((PortSymbol *) pp)->nameStr = ""; + + QString Str; + int countPort = 0; + + QFileInfo Info(DataDisplay); + QString Suffix = Info.suffix(); + + // handle VHDL file symbol + if (Suffix == "vhd" || Suffix == "vhdl") { + QStringList::iterator it; + QStringList Names, GNames, GTypes, GDefs; + int Number; + + // get ports from VHDL file + QFileInfo Info(DocName); + QString Name = Info.path() + QDir::separator() + DataDisplay; + + // obtain VHDL information either from open text document or the + // file directly + VHDL_File_Info VInfo; + TextDoc *d = (TextDoc *) App->findDoc(Name); + if (d) + VInfo = VHDL_File_Info(d->document()->toPlainText()); + else + VInfo = VHDL_File_Info(Name, true); + + if (!VInfo.PortNames.isEmpty()) + Names = VInfo.PortNames.split(",", qucs::SkipEmptyParts); + + for (pp = SymbolPaints.first(); pp != 0; pp = SymbolPaints.next()) + if (pp->Name == ".ID ") { + ID_Text *id = (ID_Text *) pp; + id->Prefix = VInfo.EntityName.toUpper(); + id->Parameter.clear(); + if (!VInfo.GenNames.isEmpty()) + GNames = VInfo.GenNames.split(",", qucs::SkipEmptyParts); + if (!VInfo.GenTypes.isEmpty()) + GTypes = VInfo.GenTypes.split(",", qucs::SkipEmptyParts); + if (!VInfo.GenDefs.isEmpty()) + GDefs = VInfo.GenDefs.split(",", qucs::SkipEmptyParts); + ; + for (Number = 1, it = GNames.begin(); it != GNames.end(); ++it) { + id->Parameter.append( + new SubParameter(true, + *it + "=" + GDefs[Number - 1], + tr("generic") + " " + QString::number(Number), + GTypes[Number - 1])); + Number++; + } + } - // ...... for schematic edit mode ....... - if (undoActionIdx == 0) { return false; } + for (Number = 1, it = Names.begin(); it != Names.end(); ++it, Number++) { + countPort++; + + Str = QString::number(Number); + // search for matching port symbol + for (pp = SymbolPaints.first(); pp != 0; pp = SymbolPaints.next()) + if (pp->Name == ".PortSym ") + if (((PortSymbol *) pp)->numberStr == Str) + break; + + if (pp) + ((PortSymbol *) pp)->nameStr = *it; + else { + SymbolPaints.append(new PortSymbol(x1, y2, Str, *it)); + y2 += 40; + } + } + } + // handle Verilog-HDL file symbol + else if (Suffix == "v") { + QStringList::iterator it; + QStringList Names; + int Number; + + // get ports from Verilog-HDL file + QFileInfo Info(DocName); + QString Name = Info.path() + QDir::separator() + DataDisplay; + + // obtain Verilog-HDL information either from open text document or the + // file directly + Verilog_File_Info VInfo; + TextDoc *d = (TextDoc *) App->findDoc(Name); + if (d) + VInfo = Verilog_File_Info(d->document()->toPlainText()); + else + VInfo = Verilog_File_Info(Name, true); + if (!VInfo.PortNames.isEmpty()) + Names = VInfo.PortNames.split(",", qucs::SkipEmptyParts); + + for (pp = SymbolPaints.first(); pp != 0; pp = SymbolPaints.next()) + if (pp->Name == ".ID ") { + ID_Text *id = (ID_Text *) pp; + id->Prefix = VInfo.ModuleName.toUpper(); + id->Parameter.clear(); + } - rebuild(undoAction.at(--undoActionIdx)); - reloadGraphs(); // load recent simulation data + for (Number = 1, it = Names.begin(); it != Names.end(); ++it, Number++) { + countPort++; + + Str = QString::number(Number); + // search for matching port symbol + for (pp = SymbolPaints.first(); pp != 0; pp = SymbolPaints.next()) + if (pp->Name == ".PortSym ") + if (((PortSymbol *) pp)->numberStr == Str) + break; + + if (pp) + ((PortSymbol *) pp)->nameStr = *it; + else { + SymbolPaints.append(new PortSymbol(x1, y2, Str, *it)); + y2 += 40; + } + } + } + // handle Verilog-A file symbol + else if (Suffix == "va") { + QStringList::iterator it; + QStringList Names; + int Number; + + // get ports from Verilog-A file + QFileInfo Info(DocName); + QString Name = Info.path() + QDir::separator() + DataDisplay; + + // obtain Verilog-A information either from open text document or the + // file directly + VerilogA_File_Info VInfo; + TextDoc *d = (TextDoc *) App->findDoc(Name); + if (d) + VInfo = VerilogA_File_Info(d->toPlainText()); + else + VInfo = VerilogA_File_Info(Name, true); + + if (!VInfo.PortNames.isEmpty()) + Names = VInfo.PortNames.split(",", qucs::SkipEmptyParts); + + for (pp = SymbolPaints.first(); pp != 0; pp = SymbolPaints.next()) + if (pp->Name == ".ID ") { + ID_Text *id = (ID_Text *) pp; + id->Prefix = VInfo.ModuleName.toUpper(); + id->Parameter.clear(); + } - emit signalUndoState(undoActionIdx != 0); - emit signalRedoState(undoActionIdx != undoAction.size()-1); + for (Number = 1, it = Names.begin(); it != Names.end(); ++it, Number++) { + countPort++; + + Str = QString::number(Number); + // search for matching port symbol + for (pp = SymbolPaints.first(); pp != 0; pp = SymbolPaints.next()) + if (pp->Name == ".PortSym ") + if (((PortSymbol *) pp)->numberStr == Str) + break; + + if (pp) + ((PortSymbol *) pp)->nameStr = *it; + else { + SymbolPaints.append(new PortSymbol(x1, y2, Str, *it)); + y2 += 40; + } + } + } + // handle schematic symbol + else { + // go through all components in a schematic + for (Component *pc = DocComps.first(); pc != 0; pc = DocComps.next()) { + if (pc->Model == "Port") { + countPort++; + + Str = pc->Props.getFirst()->Value; + // search for matching port symbol + for (pp = SymbolPaints.first(); pp != 0; pp = SymbolPaints.next()) { + if (pp->Name == ".PortSym ") { + if (((PortSymbol *) pp)->numberStr == Str) + break; + } + } - if(undoAction.at(undoActionIdx)->at(1) == 'i') { - if(undoSymbol.isEmpty()) { - setChanged(false, false); - return true; + if (pp) { + ((PortSymbol *) pp)->nameStr = pc->Name; + } else { + SymbolPaints.append(new PortSymbol(x1, y2, Str, pc->Name)); + y2 += 40; + } + } + } } - else if(undoSymbol.at(undoSymbolIdx)->at(1) == 'i') { - setChanged(false, false); - return true; + + // delete not accounted port symbols + for (pp = SymbolPaints.first(); pp != 0;) { + if (pp->Name == ".PortSym ") + if (((PortSymbol *) pp)->nameStr.isEmpty()) { + SymbolPaints.remove(); + pp = SymbolPaints.current(); + continue; + } + pp = SymbolPaints.next(); } - } - setChanged(true, false); - return true; + return countPort; } // --------------------------------------------------- -bool Schematic::redo() +bool Schematic::undo() { - if(symbolMode) { - if (undoSymbolIdx == undoSymbol.size() - 1) { return false; } + if (symbolMode) { + if (undoSymbolIdx == 0) { + return false; + } - rebuildSymbol(undoSymbol.at(++undoSymbolIdx)); - adjustPortNumbers(); // set port names + rebuildSymbol(undoSymbol.at(--undoSymbolIdx)); + adjustPortNumbers(); // set port names - emit signalUndoState(undoSymbolIdx != 0); - emit signalRedoState(undoSymbolIdx != undoSymbol.size()-1); + emit signalUndoState(undoSymbolIdx != 0); + emit signalRedoState(undoSymbolIdx != undoSymbol.size() - 1); - if(undoSymbol.at(undoSymbolIdx)->at(1) == 'i' - && undoAction.at(undoActionIdx)->at(1) == 'i') { - setChanged(false, false); - return true; + if (undoSymbol.at(undoSymbolIdx)->at(1) == 'i' + && undoAction.at(undoActionIdx)->at(1) == 'i') { + setChanged(false, false); + return true; + } + + setChanged(true, false); + return true; + } + + // ...... for schematic edit mode ....... + if (undoActionIdx == 0) { + return false; + } + + rebuild(undoAction.at(--undoActionIdx)); + reloadGraphs(); // load recent simulation data + + emit signalUndoState(undoActionIdx != 0); + emit signalRedoState(undoActionIdx != undoAction.size() - 1); + + if (undoAction.at(undoActionIdx)->at(1) == 'i') { + if (undoSymbol.isEmpty()) { + setChanged(false, false); + return true; + } else if (undoSymbol.at(undoSymbolIdx)->at(1) == 'i') { + setChanged(false, false); + return true; + } } setChanged(true, false); return true; - } +} +// --------------------------------------------------- +bool Schematic::redo() +{ + if (symbolMode) { + if (undoSymbolIdx == undoSymbol.size() - 1) { + return false; + } - // - // ...... for schematic edit mode ....... - if (undoActionIdx == undoAction.size()-1) { return false; } + rebuildSymbol(undoSymbol.at(++undoSymbolIdx)); + adjustPortNumbers(); // set port names - rebuild(undoAction.at(++undoActionIdx)); - reloadGraphs(); // load recent simulation data + emit signalUndoState(undoSymbolIdx != 0); + emit signalRedoState(undoSymbolIdx != undoSymbol.size() - 1); - emit signalUndoState(undoActionIdx != 0); - emit signalRedoState(undoActionIdx != undoAction.size()-1); + if (undoSymbol.at(undoSymbolIdx)->at(1) == 'i' + && undoAction.at(undoActionIdx)->at(1) == 'i') { + setChanged(false, false); + return true; + } - if (undoAction.at(undoActionIdx)->at(1) == 'i') { - if(undoSymbol.isEmpty()) { - setChanged(false, false); - return true; + setChanged(true, false); + return true; } - else if(undoSymbol.at(undoSymbolIdx)->at(1) == 'i') { - setChanged(false, false); - return true; + + // + // ...... for schematic edit mode ....... + if (undoActionIdx == undoAction.size() - 1) { + return false; } - - } - setChanged(true, false); - return true; + rebuild(undoAction.at(++undoActionIdx)); + reloadGraphs(); // load recent simulation data + + emit signalUndoState(undoActionIdx != 0); + emit signalRedoState(undoActionIdx != undoAction.size() - 1); + + if (undoAction.at(undoActionIdx)->at(1) == 'i') { + if (undoSymbol.isEmpty()) { + setChanged(false, false); + return true; + } else if (undoSymbol.at(undoSymbolIdx)->at(1) == 'i') { + setChanged(false, false); + return true; + } + } + + setChanged(true, false); + return true; } // --------------------------------------------------- // Sets selected elements on grid. -bool Schematic::elementsOnGrid() { +bool Schematic::elementsOnGrid() +{ int x, y, No; bool count = false; WireLabel *pl, *pLabel; @@ -1874,9 +1972,8 @@ bool Schematic::elementsOnGrid() { Components->setAutoDelete(false); for (Component *pc = Components->last(); pc != nullptr; pc = Components->prev()) if (pc->isSelected) { - // rescue non-selected node labels - for (Port *pp: pc->Ports) + for (Port *pp : pc->Ports) if (pp->Connection->Label) if (pp->Connection->Connections.count() < 2) { LabelCache.append(pp->Connection->Label); @@ -1890,12 +1987,12 @@ bool Schematic::elementsOnGrid() { deleteComp(pc); setOnGrid(pc->cx, pc->cy); insertRawComponent(pc); - Components->at(No); // restore current list position + Components->at(No); // restore current list position pc->isSelected = false; count = true; x -= pc->cx; - y -= pc->cy; // re-insert node labels and correct position + y -= pc->cy; // re-insert node labels and correct position for (pl = LabelCache.first(); pl != 0; pl = LabelCache.next()) { pl->cx -= x; pl->cy -= y; @@ -1931,7 +2028,7 @@ bool Schematic::elementsOnGrid() { setOnGrid(pw->x1, pw->y1); setOnGrid(pw->x2, pw->y2); insertWire(pw); - Wires->at(No); // restore current list position + Wires->at(No); // restore current list position pw->isSelected = false; count = true; if (pl) @@ -1971,9 +2068,9 @@ bool Schematic::elementsOnGrid() { count = true; } - for (Graph *pg: pd->Graphs) + for (Graph *pg : pd->Graphs) // test markers of diagram - for (Marker *pm: pg->Markers) + for (Marker *pm : pg->Markers) if (pm->isSelected) { x = pm->x1 + pd->cx; y = pm->y1 + pd->cy; @@ -1993,34 +2090,52 @@ bool Schematic::elementsOnGrid() { count = true; } - if (count) setChanged(true, true); + if (count) + setChanged(true, true); return count; } // --------------------------------------------------- void Schematic::switchPaintMode() { - symbolMode = !symbolMode; // change mode - - int tmp, t2; - float temp; - temp = Scale; Scale = tmpScale; tmpScale = temp; - tmp = contentsX(); - t2 = contentsY(); - setContentsPos(tmpPosX, tmpPosY); - tmpPosX = tmp; - tmpPosY = t2; - tmp = ViewX1; ViewX1 = tmpViewX1; tmpViewX1 = tmp; - tmp = ViewY1; ViewY1 = tmpViewY1; tmpViewY1 = tmp; - tmp = ViewX2; ViewX2 = tmpViewX2; tmpViewX2 = tmp; - tmp = ViewY2; ViewY2 = tmpViewY2; tmpViewY2 = tmp; - tmp = UsedX1; UsedX1 = tmpUsedX1; tmpUsedX1 = tmp; - tmp = UsedY1; UsedY1 = tmpUsedY1; tmpUsedY1 = tmp; - tmp = UsedX2; UsedX2 = tmpUsedX2; tmpUsedX2 = tmp; - tmp = UsedY2; UsedY2 = tmpUsedY2; tmpUsedY2 = tmp; + symbolMode = !symbolMode; // change mode + + int tmp, t2; + float temp; + temp = Scale; + Scale = tmpScale; + tmpScale = temp; + tmp = contentsX(); + t2 = contentsY(); + setContentsPos(tmpPosX, tmpPosY); + tmpPosX = tmp; + tmpPosY = t2; + tmp = ViewX1; + ViewX1 = tmpViewX1; + tmpViewX1 = tmp; + tmp = ViewY1; + ViewY1 = tmpViewY1; + tmpViewY1 = tmp; + tmp = ViewX2; + ViewX2 = tmpViewX2; + tmpViewX2 = tmp; + tmp = ViewY2; + ViewY2 = tmpViewY2; + tmpViewY2 = tmp; + tmp = UsedX1; + UsedX1 = tmpUsedX1; + tmpUsedX1 = tmp; + tmp = UsedY1; + UsedY1 = tmpUsedY1; + tmpUsedY1 = tmp; + tmp = UsedX2; + UsedX2 = tmpUsedX2; + tmpUsedX2 = tmp; + tmp = UsedY2; + UsedY2 = tmpUsedY2; + tmpUsedY2 = tmp; } - // ********************************************************************* // ********** ********** // ********** Function for serving mouse wheel moving ********** @@ -2028,46 +2143,55 @@ void Schematic::switchPaintMode() // ********************************************************************* void Schematic::contentsWheelEvent(QWheelEvent *Event) { - App->editText->setHidden(true); // disable edit of component property - // use smaller steps; typically the returned delta() is a multiple of 120 - //int delta = Event->delta() >> 1; - - // ................................................................... - if((Event->modifiers() & Qt::ShiftModifier) || - (Event->angleDelta().x() != 0)) { // scroll horizontally ? - int delta = Event->angleDelta().y() / 2; - if (Event->angleDelta().x() != 0) - delta = Event->angleDelta().x() / 2; - if(delta > 0) { if(scrollLeft(delta)) scrollBy(-delta, 0); } - else { if(scrollRight(delta)) scrollBy(-delta, 0); } - viewport()->update(); // because QScrollView thinks nothing has changed - App->view->drawn = false; - } - // ................................................................... - else if(Event->modifiers() & Qt::ControlModifier) { // use mouse wheel to zoom ? - // zoom factor scaled according to the wheel delta, to accommodate - // values different from 60 (slower or faster zoom) - int delta = Event->angleDelta().y(); - float Scaling = pow(1.1, delta/60.0); - zoom(Scaling); - Scaling -= 1.0; + App->editText->setHidden(true); // disable edit of component property + // use smaller steps; typically the returned delta() is a multiple of 120 + //int delta = Event->delta() >> 1; + + // ................................................................... + if ((Event->modifiers() & Qt::ShiftModifier) + || (Event->angleDelta().x() != 0)) { // scroll horizontally ? + int delta = Event->angleDelta().y() / 2; + if (Event->angleDelta().x() != 0) + delta = Event->angleDelta().x() / 2; + if (delta > 0) { + if (scrollLeft(delta)) + scrollBy(-delta, 0); + } else { + if (scrollRight(delta)) + scrollBy(-delta, 0); + } + viewport()->update(); // because QScrollView thinks nothing has changed + App->view->drawn = false; + } + // ................................................................... + else if (Event->modifiers() & Qt::ControlModifier) { // use mouse wheel to zoom ? + // zoom factor scaled according to the wheel delta, to accommodate + // values different from 60 (slower or faster zoom) + int delta = Event->angleDelta().y(); + float Scaling = pow(1.1, delta / 60.0); + zoom(Scaling); + Scaling -= 1.0; #if QT_VERSION >= 0x050f00 - scrollBy( int(Scaling * float(Event->position().x())), - int(Scaling * float(Event->position().y())) ); + scrollBy(int(Scaling * float(Event->position().x())), + int(Scaling * float(Event->position().y()))); #else - scrollBy( int(Scaling * float(Event->pos().x())), - int(Scaling * float(Event->pos().y())) ); + scrollBy(int(Scaling * float(Event->pos().x())), int(Scaling * float(Event->pos().y()))); #endif - } - // ................................................................... - else { // scroll vertically ! - int delta = Event->angleDelta().y() / 2; - if(delta > 0) { if(scrollUp(delta)) scrollBy(0, -delta); } - else { if(scrollDown(delta)) scrollBy(0, -delta); } - viewport()->update(); // because QScrollView thinks nothing has changed - App->view->drawn = false; - } - Event->accept(); // QScrollView must not handle this event + } + // ................................................................... + else { // scroll vertically ! + int delta = Event->angleDelta().y() / 2; + if (delta > 0) { + if (scrollUp(delta)) + scrollBy(0, -delta); + } else { + if (scrollDown(delta)) + scrollBy(0, -delta); + } + viewport()->update(); // because QScrollView thinks nothing has changed + App->view->drawn = false; + } + Event->accept(); // QScrollView must not handle this event } // ----------------------------------------------------------- @@ -2075,24 +2199,25 @@ void Schematic::contentsWheelEvent(QWheelEvent *Event) // area accordingly. bool Schematic::scrollUp(int step) { - int diff; + int diff; - diff = contentsY() - step; - if(diff < 0) { // scroll outside the active area ? (upwards) - resizeContents(contentsWidth(), contentsHeight()-diff); - ViewY1 += diff; - scrollBy(0, diff); - return false; - } + diff = contentsY() - step; + if (diff < 0) { // scroll outside the active area ? (upwards) + resizeContents(contentsWidth(), contentsHeight() - diff); + ViewY1 += diff; + scrollBy(0, diff); + return false; + } - diff = ViewY2 - UsedY2 - 20; // keep border of 20 - if(diff > 0) { // make active area smaller ? - if(step < diff) diff = step; - resizeContents(contentsWidth(), contentsHeight()-diff); - ViewY2 -= diff; - } + diff = ViewY2 - UsedY2 - 20; // keep border of 20 + if (diff > 0) { // make active area smaller ? + if (step < diff) + diff = step; + resizeContents(contentsWidth(), contentsHeight() - diff); + ViewY2 -= diff; + } - return true; + return true; } // ----------------------------------------------------------- @@ -2100,25 +2225,26 @@ bool Schematic::scrollUp(int step) // area accordingly. ("step" must be negative!) bool Schematic::scrollDown(int step) { - int diff; + int diff; - diff = contentsHeight() - contentsY()-visibleHeight() + step; - if(diff < 0) { // scroll outside the active area ? (downwards) - resizeContents(contentsWidth(), contentsHeight()-diff); - ViewY2 -= diff; - scrollBy(0, -step); - return false; - } + diff = contentsHeight() - contentsY() - visibleHeight() + step; + if (diff < 0) { // scroll outside the active area ? (downwards) + resizeContents(contentsWidth(), contentsHeight() - diff); + ViewY2 -= diff; + scrollBy(0, -step); + return false; + } - diff = ViewY1 - UsedY1 + 20; // keep border of 20 - if(diff < 0) { // make active area smaller ? - if(step > diff) diff = step; - resizeContents(contentsWidth(), contentsHeight()+diff); - ViewY1 -= diff; - return false; - } + diff = ViewY1 - UsedY1 + 20; // keep border of 20 + if (diff < 0) { // make active area smaller ? + if (step > diff) + diff = step; + resizeContents(contentsWidth(), contentsHeight() + diff); + ViewY1 -= diff; + return false; + } - return true; + return true; } // ----------------------------------------------------------- @@ -2126,24 +2252,25 @@ bool Schematic::scrollDown(int step) // area accordingly. bool Schematic::scrollLeft(int step) { - int diff; + int diff; - diff = contentsX() - step; - if(diff < 0) { // scroll outside the active area ? (to the left) - resizeContents(contentsWidth()-diff, contentsHeight()); - ViewX1 += diff; - scrollBy(diff, 0); - return false; - } + diff = contentsX() - step; + if (diff < 0) { // scroll outside the active area ? (to the left) + resizeContents(contentsWidth() - diff, contentsHeight()); + ViewX1 += diff; + scrollBy(diff, 0); + return false; + } - diff = ViewX2 - UsedX2 - 20; // keep border of 20 - if(diff > 0) { // make active area smaller ? - if(step < diff) diff = step; - resizeContents(contentsWidth()-diff, contentsHeight()); - ViewX2 -= diff; - } + diff = ViewX2 - UsedX2 - 20; // keep border of 20 + if (diff > 0) { // make active area smaller ? + if (step < diff) + diff = step; + resizeContents(contentsWidth() - diff, contentsHeight()); + ViewX2 -= diff; + } - return true; + return true; } // ----------------------------------------------------------- @@ -2151,68 +2278,68 @@ bool Schematic::scrollLeft(int step) // view area accordingly. ("step" must be negative!) bool Schematic::scrollRight(int step) { - int diff; + int diff; - diff = contentsWidth() - contentsX()-visibleWidth() + step; - if(diff < 0) { // scroll outside the active area ? (to the right) - resizeContents(contentsWidth()-diff, contentsHeight()); - ViewX2 -= diff; - scrollBy(-step, 0); - return false; - } + diff = contentsWidth() - contentsX() - visibleWidth() + step; + if (diff < 0) { // scroll outside the active area ? (to the right) + resizeContents(contentsWidth() - diff, contentsHeight()); + ViewX2 -= diff; + scrollBy(-step, 0); + return false; + } - diff = ViewX1 - UsedX1 + 20; // keep border of 20 - if(diff < 0) { // make active area smaller ? - if(step > diff) diff = step; - resizeContents(contentsWidth()+diff, contentsHeight()); - ViewX1 -= diff; - return false; - } + diff = ViewX1 - UsedX1 + 20; // keep border of 20 + if (diff < 0) { // make active area smaller ? + if (step > diff) + diff = step; + resizeContents(contentsWidth() + diff, contentsHeight()); + ViewX1 -= diff; + return false; + } - return true; + return true; } // ----------------------------------------------------------- // Is called if the scroll arrow of the ScrollBar is pressed. void Schematic::slotScrollUp() { - App->editText->setHidden(true); // disable edit of component property - scrollUp(verticalScrollBar()->singleStep()); - viewport()->update(); // because QScrollView thinks nothing has changed - App->view->drawn = false; + App->editText->setHidden(true); // disable edit of component property + scrollUp(verticalScrollBar()->singleStep()); + viewport()->update(); // because QScrollView thinks nothing has changed + App->view->drawn = false; } // ----------------------------------------------------------- // Is called if the scroll arrow of the ScrollBar is pressed. void Schematic::slotScrollDown() { - App->editText->setHidden(true); // disable edit of component property - scrollDown(-verticalScrollBar()->singleStep()); - viewport()->update(); // because QScrollView thinks nothing has changed - App->view->drawn = false; + App->editText->setHidden(true); // disable edit of component property + scrollDown(-verticalScrollBar()->singleStep()); + viewport()->update(); // because QScrollView thinks nothing has changed + App->view->drawn = false; } // ----------------------------------------------------------- // Is called if the scroll arrow of the ScrollBar is pressed. void Schematic::slotScrollLeft() { - App->editText->setHidden(true); // disable edit of component property - scrollLeft(horizontalScrollBar()->singleStep()); - viewport()->update(); // because QScrollView thinks nothing has changed - App->view->drawn = false; + App->editText->setHidden(true); // disable edit of component property + scrollLeft(horizontalScrollBar()->singleStep()); + viewport()->update(); // because QScrollView thinks nothing has changed + App->view->drawn = false; } // ----------------------------------------------------------- // Is called if the scroll arrow of the ScrollBar is pressed. void Schematic::slotScrollRight() { - App->editText->setHidden(true); // disable edit of component property - scrollRight(-horizontalScrollBar()->singleStep()); - viewport()->update(); // because QScrollView thinks nothing has changed - App->view->drawn = false; + App->editText->setHidden(true); // disable edit of component property + scrollRight(-horizontalScrollBar()->singleStep()); + viewport()->update(); // because QScrollView thinks nothing has changed + App->view->drawn = false; } - // ********************************************************************* // ********** ********** // ********** Function for serving drag'n drop ********** @@ -2222,167 +2349,166 @@ void Schematic::slotScrollRight() // Is called if an object is dropped (after drag'n drop). void Schematic::contentsDropEvent(QDropEvent *Event) { - if(dragIsOkay) { - QList urls = Event->mimeData()->urls(); - if (urls.isEmpty()) { - return; - } - - // do not close untitled document to avoid segfault - QucsDoc *d = QucsMain->getDoc(0); - bool changed = d->DocChanged; - d->DocChanged = true; + if (dragIsOkay) { + QList urls = Event->mimeData()->urls(); + if (urls.isEmpty()) { + return; + } - // URI: file:/home/linuxuser/Desktop/example.sch - for (QUrl url : urls) { - App->gotoPage(QDir::toNativeSeparators(url.toLocalFile())); - } + // do not close untitled document to avoid segfault + QucsDoc *d = QucsMain->getDoc(0); + bool changed = d->DocChanged; + d->DocChanged = true; - d->DocChanged = changed; - return; - } + // URI: file:/home/linuxuser/Desktop/example.sch + for (QUrl url : urls) { + App->gotoPage(QDir::toNativeSeparators(url.toLocalFile())); + } + d->DocChanged = changed; + return; + } #if QT_VERSION >= 0x060000 - auto ev_pos = Event->position(); + auto ev_pos = Event->position(); #else - auto ev_pos = Event->pos(); + auto ev_pos = Event->pos(); #endif - QMouseEvent e(QEvent::MouseButtonPress, ev_pos, - Qt::LeftButton, Qt::NoButton, Qt::NoModifier); - int x = int(ev_pos.x()/Scale) + ViewX1; - int y = int(ev_pos.y()/Scale) + ViewY1; + QMouseEvent e(QEvent::MouseButtonPress, ev_pos, Qt::LeftButton, Qt::NoButton, Qt::NoModifier); + int x = int(ev_pos.x() / Scale) + ViewX1; + int y = int(ev_pos.y() / Scale) + ViewY1; - App->view->MPressElement(this, &e, x, y); + App->view->MPressElement(this, &e, x, y); - delete App->view->selElem; - App->view->selElem = nullptr; // no component selected + delete App->view->selElem; + App->view->selElem = nullptr; // no component selected if (formerAction) { formerAction->setChecked(true); } else { - QucsMain->select->setChecked(true); // restore old action + QucsMain->select->setChecked(true); // restore old action } } // --------------------------------------------------- void Schematic::contentsDragEnterEvent(QDragEnterEvent *Event) { - //FIXME: the function of drag library component seems not working? - formerAction = nullptr; - dragIsOkay = false; + //FIXME: the function of drag library component seems not working? + formerAction = nullptr; + dragIsOkay = false; - // file dragged in ? - if(Event->mimeData()->hasUrls()) { - dragIsOkay = true; - Event->accept(); - return; - } - - // drag library component - if(Event->mimeData()->hasText()) { - QString s = Event->mimeData()->text(); - if(s.left(15) == "QucsComponent:<") { - s = s.mid(14); - App->view->selElem = getComponentFromName(s); - if(App->view->selElem) { + // file dragged in ? + if (Event->mimeData()->hasUrls()) { + dragIsOkay = true; Event->accept(); return; - } } - Event->ignore(); - return; - } + // drag library component + if (Event->mimeData()->hasText()) { + QString s = Event->mimeData()->text(); + if (s.left(15) == "QucsComponent:<") { + s = s.mid(14); + App->view->selElem = getComponentFromName(s); + if (App->view->selElem) { + Event->accept(); + return; + } + } + Event->ignore(); + return; + } -// if(Event->format(1) == 0) { // only one MIME type ? + // if(Event->format(1) == 0) { // only one MIME type ? // drag component from listview //if(Event->provides("application/x-qabstractitemmodeldatalist")) { if (Event->mimeData()->hasFormat("application/x-qabstractitemmodeldatalist")) { - QListWidgetItem *Item = App->CompComps->currentItem(); - if(Item) { - formerAction = App->activeAction; - App->slotSelectComponent(Item); // also sets drawn=false - App->MouseMoveAction = 0; - App->MousePressAction = 0; - - Event->accept(); - return; - } + QListWidgetItem *Item = App->CompComps->currentItem(); + if (Item) { + formerAction = App->activeAction; + App->slotSelectComponent(Item); // also sets drawn=false + App->MouseMoveAction = 0; + App->MousePressAction = 0; + + Event->accept(); + return; + } } -// } + // } - Event->ignore(); + Event->ignore(); } // --------------------------------------------------- -void Schematic::contentsDragLeaveEvent(QDragLeaveEvent*) +void Schematic::contentsDragLeaveEvent(QDragLeaveEvent *) { - if(App->view->selElem) - if(App->view->selElem->Type & isComponent) - if(App->view->drawn) { - - QPainter painter(viewport()); - App->view->setPainter(this); - ((Component*)App->view->selElem)->paintScheme(this); - App->view->drawn = false; - } + if (App->view->selElem) + if (App->view->selElem->Type & isComponent) + if (App->view->drawn) { + QPainter painter(viewport()); + App->view->setPainter(this); + ((Component *) App->view->selElem)->paintScheme(this); + App->view->drawn = false; + } - if(formerAction) - formerAction->setChecked(true); // restore old action + if (formerAction) + formerAction->setChecked(true); // restore old action } // --------------------------------------------------- void Schematic::contentsDragMoveEvent(QDragMoveEvent *Event) { - if(!dragIsOkay) { - if(App->view->selElem == 0) { - Event->ignore(); - return; - } + if (!dragIsOkay) { + if (App->view->selElem == 0) { + Event->ignore(); + return; + } #if QT_VERSION >= 0x060000 - QMouseEvent e(QEvent::MouseMove, Event->position(), Qt::NoButton, - Qt::NoButton, Qt::NoModifier); + QMouseEvent e(QEvent::MouseMove, + Event->position(), + Qt::NoButton, + Qt::NoButton, + Qt::NoModifier); #else - QMouseEvent e(QEvent::MouseMove, Event->pos(), Qt::NoButton, - Qt::NoButton, Qt::NoModifier); + QMouseEvent e(QEvent::MouseMove, Event->pos(), Qt::NoButton, Qt::NoButton, Qt::NoModifier); #endif - App->view->MMoveElement(this, &e); - } + App->view->MMoveElement(this, &e); + } - Event->accept(); + Event->accept(); } bool Schematic::checkDplAndDatNames() { QFileInfo Info(DocName); - if(!DocName.isEmpty() && - DataSet.size()>4 && - DataDisplay.size()>4) { - QString base = Info.completeBaseName(); - QString base_dat = DataSet; - base_dat.chop(4); - QString base_dpl = DataDisplay; - base_dpl.chop(4); - if (base != base_dat || base != base_dpl) { - QString msg = QObject::tr("The schematic name and dataset/display file name is not matching! " - "This may happen if schematic was copied using the file manager " - "instead of using File->SaveAs. Correct dataset and display names " - "automatically?\n\n"); - msg += QString(QObject::tr("Schematic file: ")) + base + ".sch\n"; - msg += QString(QObject::tr("Dataset file: ")) + DataSet + "\n"; - msg += QString(QObject::tr("Display file: ")) + DataDisplay + "\n"; - auto r = QMessageBox::information(this, - QObject::tr("Open document"), - msg, QMessageBox::Yes, QMessageBox::No); - if (r == QMessageBox::Yes) { - DataSet = base + ".dat"; - DataDisplay = base + ".dpl"; - return true; - } - } + if (!DocName.isEmpty() && DataSet.size() > 4 && DataDisplay.size() > 4) { + QString base = Info.completeBaseName(); + QString base_dat = DataSet; + base_dat.chop(4); + QString base_dpl = DataDisplay; + base_dpl.chop(4); + if (base != base_dat || base != base_dpl) { + QString msg = QObject::tr( + "The schematic name and dataset/display file name is not matching! " + "This may happen if schematic was copied using the file manager " + "instead of using File->SaveAs. Correct dataset and display names " + "automatically?\n\n"); + msg += QString(QObject::tr("Schematic file: ")) + base + ".sch\n"; + msg += QString(QObject::tr("Dataset file: ")) + DataSet + "\n"; + msg += QString(QObject::tr("Display file: ")) + DataDisplay + "\n"; + auto r = QMessageBox::information(this, + QObject::tr("Open document"), + msg, + QMessageBox::Yes, + QMessageBox::No); + if (r == QMessageBox::Yes) { + DataSet = base + ".dat"; + DataDisplay = base + ".dpl"; + return true; + } + } } else { return false; }