diff --git a/qucs/bitmaps/viewmagsel.png b/qucs/bitmaps/viewmagsel.png new file mode 100644 index 000000000..b2916194d Binary files /dev/null and b/qucs/bitmaps/viewmagsel.png differ diff --git a/qucs/qucs.cpp b/qucs/qucs.cpp index 16d127d63..6ea695bcb 100644 --- a/qucs/qucs.cpp +++ b/qucs/qucs.cpp @@ -2241,6 +2241,13 @@ void QucsApp::slotShowAll() getDoc()->showAll(); } +// -------------------------------------------------------------- +void QucsApp::slotZoomToSelection() +{ + slotHideEdit(); // disable text edit of component property + getDoc()->zoomToSelection(); +} + // ----------------------------------------------------------- // Sets the scale factor to 1. void QucsApp::slotShowOne() diff --git a/qucs/qucs.h b/qucs/qucs.h index 90889a70d..6918964c7 100644 --- a/qucs/qucs.h +++ b/qucs/qucs.h @@ -140,6 +140,7 @@ public slots: void slotPopHierarchy(); void slotShowAll(); + void slotZoomToSelection(); void slotShowOne(); void slotZoomOut(); // Zoom out by 2 @@ -220,7 +221,7 @@ private slots: QAction *fileNew, *textNew, *fileNewDpl, *fileOpen, *fileSave, *fileSaveAs, *fileSaveAll, *fileClose, *fileExamples, *fileSettings, *filePrint, *fileQuit, *projNew, *projOpen, *projDel, *projClose, *applSettings, *refreshSchPath, - *editCut, *editCopy, *magAll, *magOne, *magMinus, *filePrintFit, *tune, + *editCut, *editCopy, *magAll, *magSel, *magOne, *magMinus, *filePrintFit, *tune, *symEdit, *intoH, *popH, *simulate, *save_netlist, *dpl_sch, *undo, *redo, *dcbias; QAction *exportAsImage; diff --git a/qucs/qucs.qrc b/qucs/qucs.qrc index 0555244e8..425f5f2eb 100644 --- a/qucs/qucs.qrc +++ b/qucs/qucs.qrc @@ -201,6 +201,7 @@ bitmaps/viewmag+.png bitmaps/viewmag1.png bitmaps/viewmagfit.png + bitmaps/viewmagsel.png bitmaps/vprobe.png bitmaps/vpulse.png bitmaps/vrect.png diff --git a/qucs/qucs_init.cpp b/qucs/qucs_init.cpp index 9d85b619f..9e6c8939d 100644 --- a/qucs/qucs_init.cpp +++ b/qucs/qucs_init.cpp @@ -364,6 +364,12 @@ void QucsApp::initActions() magAll->setWhatsThis(tr("View All\n\nShows the whole page content")); connect(magAll, SIGNAL(triggered()), SLOT(slotShowAll())); + magSel = new QAction(QIcon((":/bitmaps/viewmagsel.png")), tr("Zoom to selection"), this); + magSel->setShortcut(tr("Z")); + magSel->setStatusTip(tr("Zoom to selected components")); + magSel->setWhatsThis(tr("Zoom to selection\n\nZoom to selected components")); + connect(magSel, SIGNAL(triggered()), SLOT(slotZoomToSelection())); + magOne = new QAction(QIcon((":/bitmaps/viewmag1.png")), tr("View 1:1"), this); magOne->setShortcut(Qt::Key_1); magOne->setStatusTip(tr("Views without magnification")); @@ -778,6 +784,7 @@ void QucsApp::initMenuBar() viewMenu = new QMenu(tr("&View")); // menuBar entry viewMenu viewMenu->addAction(magAll); + viewMenu->addAction(magSel); viewMenu->addAction(magOne); viewMenu->addAction(magPlus); viewMenu->addAction(magMinus); @@ -904,6 +911,7 @@ void QucsApp::initToolBar() viewToolbar = new QToolBar(tr("View")); this->addToolBar(viewToolbar); viewToolbar->addAction(magAll); + viewToolbar->addAction(magSel); viewToolbar->addAction(magOne); viewToolbar->addAction(magPlus); viewToolbar->addAction(magMinus); diff --git a/qucs/qucsdoc.h b/qucs/qucsdoc.h index 602e7b5f7..ad0cab953 100644 --- a/qucs/qucsdoc.h +++ b/qucs/qucsdoc.h @@ -37,6 +37,7 @@ class QucsDoc { virtual void becomeCurrent(bool) {}; virtual float zoomBy(float) { return 1.0; }; virtual void showAll() {}; + virtual void zoomToSelection() {}; virtual void showNoZoom() {}; static QString fileSuffix (const QString&); diff --git a/qucs/schematic.cpp b/qucs/schematic.cpp index 0b7838a84..ce4c2d4cf 100644 --- a/qucs/schematic.cpp +++ b/qucs/schematic.cpp @@ -794,6 +794,30 @@ void Schematic::showAll() zoom(xScale); } +// ------------------------------------------------------ +void Schematic::zoomToSelection() +{ + sizeOfSelection(UsedX1, UsedY1, UsedX2, UsedY2); + if(UsedX1 == 0) + if(UsedX2 == 0) + if(UsedY1 == 0) + if(UsedY2 == 0) { + showAll(); + 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::showNoZoom() { @@ -1018,6 +1042,124 @@ void Schematic::sizeOfAll(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; + Component *pc; + Diagram *pd; + Wire *pw; + WireLabel *pl; + Painting *pp; + + bool isAnySelected = false; + + 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()) { + 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; + } + + // find boundings of all wires + 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; + + 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()) { + 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; + } + } + + // find boundings of all diagrams + 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; + + 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()) { + 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 (!isAnySelected) { + xmin = xmax = 0; + ymin = ymax = 0; + } +} + // --------------------------------------------------- // Rotates all selected components around their midpoint. bool Schematic::rotateElements() diff --git a/qucs/schematic.h b/qucs/schematic.h index 328b8d31f..bdcd4c624 100644 --- a/qucs/schematic.h +++ b/qucs/schematic.h @@ -93,6 +93,7 @@ class Schematic : public Q3ScrollView, public QucsDoc { float textCorr(); bool sizeOfFrame(int&, int&); void sizeOfAll(int&, int&, int&, int&); + void sizeOfSelection(int&, int&, int&, int&); bool rotateElements(); bool mirrorXComponents(); bool mirrorYComponents(); @@ -102,6 +103,7 @@ class Schematic : public Q3ScrollView, public QucsDoc { float zoom(float); float zoomBy(float); void showAll(); + void zoomToSelection(); void showNoZoom(); void enlargeView(int, int, int, int); void switchPaintMode(); @@ -325,6 +327,7 @@ protected slots: bool isAnalog; bool isVerilog; bool creatingLib; + }; #endif