Qucs-GUI
0.0.19
|
00001 /*************************************************************************** 00002 mouseactions.cpp 00003 ------------------ 00004 begin : Thu Aug 28 2003 00005 copyright : (C) 2003 by Michael Margraf 00006 email : michael.margraf@alumni.tu-berlin.de 00007 ***************************************************************************/ 00008 00009 /* Copyright (C) 2014 Guilherme Brondani Torri <guitorri@gmail.com> */ 00010 00011 /*************************************************************************** 00012 * * 00013 * This program is free software; you can redistribute it and/or modify * 00014 * it under the terms of the GNU General Public License as published by * 00015 * the Free Software Foundation; either version 2 of the License, or * 00016 * (at your option) any later version. * 00017 * * 00018 ***************************************************************************/ 00019 #include "qucs.h" 00020 #include "main.h" 00021 #include "node.h" 00022 #include "schematic.h" 00023 #include "mouseactions.h" 00024 #include "module.h" 00025 #include "components/component.h" 00026 #include "components/spicedialog.h" 00027 #include "components/spicefile.h" 00028 #include "components/optimizedialog.h" 00029 #include "components/componentdialog.h" 00030 #include "components/vacomponent.h" 00031 #include "diagrams/diagramdialog.h" 00032 #include "diagrams/markerdialog.h" 00033 #include "diagrams/tabdiagram.h" 00034 #include "diagrams/timingdiagram.h" 00035 #include "dialogs/labeldialog.h" 00036 00037 #include <QTextStream> 00038 #include <Q3PtrList> 00039 #include <QMouseEvent> 00040 #include <QClipboard> 00041 #include <QApplication> 00042 #include <QMessageBox> 00043 #include <QMenu> 00044 #include <QEvent> 00045 #include <QAction> 00046 #include <QLineEdit> 00047 #include <QDebug> 00048 00049 #include <limits.h> 00050 #include <stdlib.h> 00051 00052 00053 #define DOC_X_POS(x) (int(float(x)/Doc->Scale) + Doc->ViewX1) 00054 #define DOC_Y_POS(y) (int(float(y)/Doc->Scale) + Doc->ViewY1) 00055 #define DOC_X_FPOS (float(Event->pos().x())/Doc->Scale + float(Doc->ViewX1)) 00056 #define DOC_Y_FPOS (float(Event->pos().y())/Doc->Scale + float(Doc->ViewY1)) 00057 00058 #define SCR_X_POS(x) int(float(x - Doc->ViewX1) * Doc->Scale) 00059 #define SCR_Y_POS(y) int(float(y - Doc->ViewY1) * Doc->Scale) 00060 00061 QAction *formerAction; // remember action before drag n'drop etc. 00062 00063 00064 MouseActions::MouseActions(QucsApp* App_) 00065 { 00066 App = App_; // pointer to main app 00067 selElem = 0; // no component/diagram is selected 00068 isMoveEqual = false; // mouse cursor move x and y the same way 00069 focusElement = 0; //element being interacted with mouse 00070 00071 // ............................................................... 00072 // initialize menu appearing by right mouse button click on component 00073 ComponentMenu = new QMenu(QucsMain); 00074 focusMEvent = new QMouseEvent(QEvent::MouseButtonPress, QPoint(0,0), 00075 Qt::NoButton, Qt::NoButton); 00076 } 00077 00078 00079 MouseActions::~MouseActions() 00080 { 00081 delete ComponentMenu; 00082 delete focusMEvent; 00083 } 00084 00085 // ----------------------------------------------------------- 00086 void MouseActions::setPainter(Schematic *Doc) 00087 { 00088 // contents to viewport transformation 00089 00090 Doc->PostPaintEvent(_Translate,-Doc->contentsX(), -Doc->contentsY()); 00091 Doc->PostPaintEvent(_Scale,Doc->Scale, Doc->Scale); 00092 Doc->PostPaintEvent(_Translate,-Doc->ViewX1, -Doc->ViewY1); 00093 Doc->PostPaintEvent(_DotLine); 00094 Doc->PostPaintEvent(_NotRop); 00095 00096 } 00097 00098 // ----------------------------------------------------------- 00099 bool MouseActions::pasteElements(Schematic *Doc) 00100 { 00101 QClipboard *cb = QApplication::clipboard(); // get system clipboard 00102 QString s = cb->text(QClipboard::Clipboard); 00103 QTextStream stream(&s, QIODevice::ReadOnly); 00104 movingElements.clear(); 00105 if(!Doc->paste(&stream, &movingElements)) return false; 00106 00107 Element *pe; 00108 int xmax, xmin, ymax, ymin; 00109 xmin = ymin = INT_MAX; 00110 xmax = ymax = INT_MIN; 00111 // First, get the max and min coordinates of all selected elements. 00112 for(pe = movingElements.first(); pe != 0; pe = movingElements.next()) { 00113 if(pe->Type == isWire) { 00114 if(pe->x1 < xmin) xmin = pe->x1; 00115 if(pe->x2 > xmax) xmax = pe->x2; 00116 if(pe->y1 < ymin) ymin = pe->y1; 00117 if(pe->y2 > ymax) ymax = pe->y2; 00118 } 00119 else { 00120 if(pe->cx < xmin) xmin = pe->cx; 00121 if(pe->cx > xmax) xmax = pe->cx; 00122 if(pe->cy < ymin) ymin = pe->cy; 00123 if(pe->cy > ymax) ymax = pe->cy; 00124 } 00125 } 00126 00127 xmin = -((xmax+xmin) >> 1); // calculate midpoint 00128 ymin = -((ymax+ymin) >> 1); 00129 Doc->setOnGrid(xmin, ymin); 00130 00131 // moving with mouse cursor in the midpoint 00132 for(pe = movingElements.first(); pe != 0; pe = movingElements.next()) 00133 if(pe->Type & isLabel) { 00134 pe->cx += xmin; pe->x1 += xmin; 00135 pe->cy += ymin; pe->y1 += ymin; 00136 } 00137 else 00138 pe->setCenter(xmin, ymin, true); 00139 00140 return true; 00141 } 00142 00143 // ----------------------------------------------------------- 00144 void MouseActions::editLabel(Schematic *Doc, WireLabel *pl) 00145 { 00146 LabelDialog *Dia = new LabelDialog(pl, Doc); 00147 int Result = Dia->exec(); 00148 if(Result == 0) return; 00149 00150 QString Name = Dia->NodeName->text(); 00151 QString Value = Dia->InitValue->text(); 00152 delete Dia; 00153 00154 if(Name.isEmpty() && Value.isEmpty()) { // if nothing entered, delete label 00155 pl->pOwner->Label = 0; // delete name of wire 00156 delete pl; 00157 } 00158 else { 00159 /* Name.replace(' ', '_'); // label must not contain spaces 00160 while(Name.at(0) == '_') Name.remove(0,1); // must not start with '_' 00161 if(Name.isEmpty()) return; 00162 if(Name == pl->Name) return;*/ 00163 if(Result == 1) return; // nothing changed 00164 00165 int old_x2 = pl->x2; 00166 pl->setName(Name); // set new name 00167 pl->initValue = Value; 00168 if(pl->cx > (pl->x1+(pl->x2>>1))) 00169 pl->x1 -= pl->x2 - old_x2; // don't change position due to text width 00170 } 00171 00172 Doc->sizeOfAll(Doc->UsedX1, Doc->UsedY1, Doc->UsedX2, Doc->UsedY2); 00173 Doc->viewport()->update(); 00174 drawn = false; 00175 Doc->setChanged(true, true); 00176 } 00177 00178 // ----------------------------------------------------------- 00179 // Reinserts all elements (moved by the user) back into the schematic. 00180 void MouseActions::endElementMoving(Schematic *Doc, Q3PtrList<Element> *movElements) 00181 { 00182 Element *pe; 00183 for(pe = movElements->first(); pe!=0; pe = movElements->next()) { 00184 // pe->isSelected = false; // deselect first (maybe afterwards pe == NULL) 00185 switch(pe->Type) { // FIXME: use casts. 00186 case isWire: 00187 if(pe->x1 == pe->x2) 00188 if(pe->y1 == pe->y2) { 00189 // Delete wires with zero length, but preserve label. 00190 if(((Wire*)pe)->Label) { 00191 Doc->insertNodeLabel((WireLabel*)((Wire*)pe)->Label); 00192 ((Wire*)pe)->Label = 0; 00193 } 00194 delete (Wire*)pe; 00195 break; 00196 } 00197 00198 Doc->insertWire((Wire*)pe); 00199 break; 00200 case isDiagram: 00201 Doc->Diagrams->append((Diagram*)pe); 00202 break; 00203 case isPainting: 00204 Doc->Paintings->append((Painting*)pe); 00205 break; 00206 case isComponent: 00207 case isAnalogComponent: 00208 case isDigitalComponent: 00209 Doc->insertRawComponent((Component*)pe, false); 00210 break; 00211 case isMovingLabel: 00212 case isHMovingLabel: 00213 case isVMovingLabel: 00214 Doc->insertNodeLabel((WireLabel*)pe); 00215 break; 00216 case isMarker: 00217 assert(dynamic_cast<Marker*>(pe)); 00218 break; 00219 } 00220 } 00221 00222 movElements->clear(); 00223 if((MAx3 != 0) || (MAy3 != 0)) // moved or put at the same place ? 00224 Doc->setChanged(true, true); 00225 00226 // enlarge viewarea if components lie outside the view 00227 Doc->sizeOfAll(Doc->UsedX1, Doc->UsedY1, Doc->UsedX2, Doc->UsedY2); 00228 Doc->enlargeView(Doc->UsedX1, Doc->UsedY1, Doc->UsedX2, Doc->UsedY2); 00229 Doc->viewport()->update(); 00230 drawn = false; 00231 } 00232 00233 // ----------------------------------------------------------- 00234 // Moves elements in "movElements" by x/y 00235 void MouseActions::moveElements(Q3PtrList<Element> *movElements, int x, int y) 00236 { 00237 Wire *pw; 00238 Element *pe; 00239 for(pe = movElements->first(); pe != 0; pe = movElements->next()) { 00240 if(pe->Type == isWire) { 00241 pw = (Wire*)pe; // connected wires are not moved completely 00242 00243 if(((uintptr_t)pw->Port1) > 3) { 00244 pw->x1 += x; pw->y1 += y; 00245 if(pw->Label) { pw->Label->cx += x; pw->Label->cy += y; } 00246 } 00247 else { if((uintptr_t)(pw->Port1) & 1) { pw->x1 += x; } 00248 if((uintptr_t)(pw->Port1) & 2) { pw->y1 += y; } } 00249 00250 if(((uintptr_t)pw->Port2) > 3) { pw->x2 += x; pw->y2 += y; } 00251 else { if((uintptr_t)(pw->Port2) & 1) pw->x2 += x; 00252 if((uintptr_t)(pw->Port2) & 2) pw->y2 += y; } 00253 00254 if(pw->Label) { // root of node label must lie on wire 00255 if(pw->Label->cx < pw->x1) pw->Label->cx = pw->x1; 00256 if(pw->Label->cy < pw->y1) pw->Label->cy = pw->y1; 00257 if(pw->Label->cx > pw->x2) pw->Label->cx = pw->x2; 00258 if(pw->Label->cy > pw->y2) pw->Label->cy = pw->y2; 00259 } 00260 00261 } 00262 else pe->setCenter(x, y, true); 00263 } 00264 } 00265 00266 00267 // *********************************************************************** 00268 // ********** ********** 00269 // ********** Functions for serving mouse moving ********** 00270 // ********** ********** 00271 // *********************************************************************** 00272 void MouseActions::MMoveElement(Schematic *Doc, QMouseEvent *Event) 00273 { 00274 if(selElem == 0) return; 00275 00276 // qDebug() << "MMoveElement got selElem"; 00277 00278 int x = Event->pos().x(); 00279 int y = Event->pos().y(); 00280 int fx = DOC_X_POS(x); 00281 int fy = DOC_Y_POS(y); 00282 int gx = fx; 00283 int gy = fy; 00284 Doc->setOnGrid(gx, gy); 00285 00286 00287 //QPainter painter(Doc->viewport()); 00288 setPainter(Doc); 00289 00290 if(selElem->Type == isPainting) { 00291 Doc->PostPaintEvent (_NotRop, 0,0,0,0); 00292 x -= Doc->contentsX(); 00293 y -= Doc->contentsY(); 00294 ((Painting*)selElem)->MouseMoving(Doc, x, y, gx, gy, 00295 Doc, x, y, drawn); 00296 drawn = true; 00297 Doc->viewport()->update(); 00298 return; 00299 } // of "if(isPainting)" 00300 00301 00302 // ********** it is a component or diagram 00303 if(drawn) selElem->paintScheme(Doc); // erase old scheme 00304 drawn = true; 00305 00306 // Component *comp = (Component*)selElem; 00307 //qDebug() << "desc" << comp->Description << "gx" << gx << "gy" << gy; 00308 00309 selElem->setCenter(gx, gy); 00310 selElem->paintScheme(Doc); // paint scheme at new position 00311 Doc->viewport()->update(); 00312 } 00313 00314 // ----------------------------------------------------------- 00320 void MouseActions::MMoveWire2(Schematic *Doc, QMouseEvent *Event) 00321 { 00322 MAx2 = DOC_X_POS(Event->pos().x()); 00323 MAy2 = DOC_Y_POS(Event->pos().y()); 00324 Doc->setOnGrid(MAx2, MAy2); 00325 00326 if(MAx1 == 0) { 00327 Doc->PostPaintEvent (_Line, MAx3, MAy3, MAx3, MAy2); // paint 00328 Doc->PostPaintEvent (_Line, MAx3, MAy2, MAx2, MAy2); // paint 00329 } 00330 else { 00331 Doc->PostPaintEvent (_Line, MAx3, MAy3, MAx2, MAy3); // paint 00332 Doc->PostPaintEvent (_Line, MAx2, MAy3, MAx2, MAy2); // paint 00333 } 00334 00335 QucsMain->MouseDoubleClickAction = &MouseActions::MDoubleClickWire2; 00336 Doc->viewport()->update(); 00337 } 00338 00339 00345 void MouseActions::MMoveWire1(Schematic *Doc, QMouseEvent *Event) 00346 { 00347 MAx3 = DOC_X_POS(Event->pos().x()); 00348 MAy3 = DOC_Y_POS(Event->pos().y()); 00349 Doc->setOnGrid(MAx3, MAy3); 00350 00351 MAx2 = DOC_X_POS(Doc->viewport()->width()); 00352 MAy2 = DOC_Y_POS(Doc->viewport()->height()); 00353 00354 Doc->PostPaintEvent (_Line, Doc->ViewX1, MAy3, MAx2, MAy3); 00355 Doc->PostPaintEvent (_Line, MAx3, Doc->ViewY1, MAx3, MAy2); 00356 Doc->viewport()->update(); 00357 } 00358 00359 00365 void MouseActions::MMoveSelect(Schematic *Doc, QMouseEvent *Event) 00366 { 00367 //qDebug() << "MMoveSelect " << "select area"; 00368 MAx2 = DOC_X_POS(Event->pos().x()) - MAx1; 00369 MAy2 = DOC_Y_POS(Event->pos().y()) - MAy1; 00370 if(isMoveEqual) { // x and y size must be equal ? 00371 if(abs(MAx2) > abs(MAy2)) { 00372 if(MAx2<0) MAx2 = -abs(MAy2); else MAx2 = abs(MAy2); 00373 } 00374 else { if(MAy2<0) MAy2 = -abs(MAx2); else MAy2 = abs(MAx2); } 00375 } 00376 00377 Doc->PostPaintEvent (_Rect, MAx1, MAy1, MAx2, MAy2); 00378 } 00379 00380 // ----------------------------------------------------------- 00381 void MouseActions::MMoveResizePainting(Schematic *Doc, QMouseEvent *Event) 00382 { 00383 setPainter(Doc); 00384 00385 MAx1 = DOC_X_POS(Event->pos().x()); 00386 MAy1 = DOC_Y_POS(Event->pos().y()); 00387 Doc->setOnGrid(MAx1, MAy1); 00388 ((Painting*)focusElement)->MouseResizeMoving(MAx1, MAy1, Doc); 00389 } 00390 00391 // ----------------------------------------------------------- 00392 // Moves components by keeping the mouse button pressed. 00393 void MouseActions::MMoveMoving(Schematic *Doc, QMouseEvent *Event) 00394 { 00395 00396 setPainter(Doc); 00397 00398 MAx2 = DOC_X_POS(Event->pos().x()); 00399 MAy2 = DOC_Y_POS(Event->pos().y()); 00400 00401 Doc->setOnGrid(MAx2, MAy2); 00402 MAx3 = MAx1 = MAx2 - MAx1; 00403 MAy3 = MAy1 = MAy2 - MAy1; 00404 00405 movingElements.clear(); 00406 Doc->copySelectedElements(&movingElements); 00407 Doc->viewport()->repaint(); 00408 00409 Wire *pw; 00410 // Changes the position of all moving elements by dx/dy 00411 for(Element *pe=movingElements.first(); pe!=0; pe=movingElements.next()) { 00412 if(pe->Type == isWire) { 00413 pw = (Wire*)pe; // connecting wires are not moved completely 00414 00415 if(((uintptr_t)pw->Port1) > 3) { pw->x1 += MAx1; pw->y1 += MAy1; } 00416 else { if((uintptr_t)(pw->Port1) & 1) { pw->x1 += MAx1; } 00417 if((uintptr_t)(pw->Port1) & 2) { pw->y1 += MAy1; } } 00418 00419 if(((uintptr_t)pw->Port2) > 3) { pw->x2 += MAx1; pw->y2 += MAy1; } 00420 else { if((uintptr_t)(pw->Port2) & 1) pw->x2 += MAx1; 00421 if((uintptr_t)(pw->Port2) & 2) pw->y2 += MAy1; } 00422 00423 if(pw->Label) { // root of node label must lie on wire 00424 if(pw->Label->cx < pw->x1) pw->Label->cx = pw->x1; 00425 if(pw->Label->cy < pw->y1) pw->Label->cy = pw->y1; 00426 if(pw->Label->cx > pw->x2) pw->Label->cx = pw->x2; 00427 if(pw->Label->cy > pw->y2) pw->Label->cy = pw->y2; 00428 } 00429 00430 } 00431 else pe->setCenter(MAx1, MAy1, true); 00432 00433 pe->paintScheme(Doc); 00434 } 00435 00436 drawn = true; 00437 MAx1 = MAx2; 00438 MAy1 = MAy2; 00439 QucsMain->MouseMoveAction = &MouseActions::MMoveMoving2; 00440 QucsMain->MouseReleaseAction = &MouseActions::MReleaseMoving; 00441 00442 } 00443 00444 // ----------------------------------------------------------- 00445 // Moves components by keeping the mouse button pressed. 00446 void MouseActions::MMoveMoving2(Schematic *Doc, QMouseEvent *Event) 00447 { 00448 setPainter(Doc); 00449 00450 MAx2 = DOC_X_POS(Event->pos().x()); 00451 MAy2 = DOC_Y_POS(Event->pos().y()); 00452 00453 Element *pe; 00454 if(drawn) // erase old scheme 00455 for(pe = movingElements.first(); pe != 0; pe = movingElements.next()) 00456 pe->paintScheme(Doc); 00457 // if(pe->Type == isWire) if(((Wire*)pe)->Label) 00458 // if(!((Wire*)pe)->Label->isSelected) 00459 // ((Wire*)pe)->Label->paintScheme(&painter); 00460 00461 drawn = true; 00462 if((Event->state() & Qt::ControlModifier) == 0) 00463 Doc->setOnGrid(MAx2, MAy2); // use grid only if CTRL key not pressed 00464 MAx1 = MAx2 - MAx1; 00465 MAy1 = MAy2 - MAy1; 00466 MAx3 += MAx1; MAy3 += MAy1; // keep track of the complete movement 00467 00468 moveElements(&movingElements, MAx1, MAy1); // moves elements by MAx1/MAy1 00469 00470 // paint afterwards to avoid conflict between wire and label painting 00471 for(pe = movingElements.first(); pe != 0; pe = movingElements.next()) 00472 pe->paintScheme(Doc); 00473 // if(pe->Type == isWire) if(((Wire*)pe)->Label) 00474 // if(!((Wire*)pe)->Label->isSelected) 00475 // ((Wire*)pe)->Label->paintScheme(&painter); 00476 00477 MAx1 = MAx2; 00478 MAy1 = MAy2; 00479 } 00480 00481 00487 void MouseActions::MMovePaste(Schematic *Doc, QMouseEvent *Event) 00488 { 00489 MAx1 = DOC_X_POS(Event->pos().x()); 00490 MAy1 = DOC_Y_POS(Event->pos().y()); 00491 moveElements(Doc,MAx1,MAy1); 00492 paintElementsScheme(Doc); 00493 00494 drawn = true; 00495 QucsMain->MouseMoveAction = &MouseActions::MMoveMoving2; 00496 QucsMain->MouseReleaseAction = &MouseActions::MReleasePaste; 00497 } 00498 00499 // ----------------------------------------------------------- 00500 // Moves scroll bar of diagram (e.g. tabular) according the mouse cursor. 00501 void MouseActions::MMoveScrollBar(Schematic *Doc, QMouseEvent *Event) 00502 { 00503 TabDiagram *d = (TabDiagram*)focusElement; 00504 int x = DOC_X_POS(Event->pos().x()); 00505 int y = DOC_Y_POS(Event->pos().y()); 00506 00507 if(d->scrollTo(MAx2, x - MAx1, y - MAy1)) { 00508 Doc->setChanged(true, true, 'm'); // 'm' = only the first time 00509 00510 // FIXME #warning QPainter p(Doc->viewport()); 00511 // FIXME #warning ViewPainter Painter; 00512 // FIXME #warning Painter.init(&p, Doc->Scale, -Doc->ViewX1, -Doc->ViewY1, 00513 // FIXME #warning Doc->contentsX(), Doc->contentsY()); 00514 // FIXME #warning Painter.fillRect(d->cx-d->x1, d->cy-d->y2, d->x2+d->x1, d->y2+d->y1, 00515 // FIXME #warning QucsSettings.BGColor); 00516 // FIXME #warning d->paint(&Painter); 00517 } 00518 } 00519 00520 00527 void MouseActions::MMoveDelete(Schematic *Doc, QMouseEvent *Event) 00528 { 00529 MAx3 = DOC_X_POS(Event->pos().x()); 00530 MAy3 = DOC_Y_POS(Event->pos().y()); 00531 00532 // cannot draw on the viewport, it is displaced by the size of dock and toolbar 00533 Doc->PostPaintEvent (_Line, MAx3-15, MAy3-15, MAx3+15, MAy3+15,0,0,false); 00534 Doc->PostPaintEvent (_Line, MAx3-15, MAy3+15, MAx3+15, MAy3-15,0,0,false); 00535 } 00536 00537 00543 void MouseActions::MMoveLabel(Schematic *Doc, QMouseEvent *Event) 00544 { 00545 MAx3 = DOC_X_POS(Event->pos().x()); 00546 MAy3 = DOC_Y_POS(Event->pos().y()); 00547 00548 // paint marker 00549 Doc->PostPaintEvent (_Line, MAx3, MAy3, MAx3+10, MAy3-10); 00550 Doc->PostPaintEvent (_Line, MAx3+10, MAy3-10, MAx3+20, MAy3-10); 00551 Doc->PostPaintEvent (_Line, MAx3+10, MAy3-10, MAx3+10, MAy3-17); 00552 00553 // paint A 00554 Doc->PostPaintEvent (_Line, MAx3+12, MAy3-12, MAx3+15, MAy3-23); 00555 Doc->PostPaintEvent (_Line, MAx3+14, MAy3-17, MAx3+17, MAy3-17); 00556 Doc->PostPaintEvent (_Line, MAx3+19, MAy3-12, MAx3+16, MAy3-23); 00557 } 00558 00559 00565 void MouseActions::MMoveMarker(Schematic *Doc, QMouseEvent *Event) 00566 { 00567 MAx3 = DOC_X_POS(Event->pos().x()); 00568 MAy3 = DOC_Y_POS(Event->pos().y()); 00569 00570 Doc->PostPaintEvent (_Line, MAx3, MAy3-2, MAx3-8, MAy3-10); 00571 Doc->PostPaintEvent (_Line, MAx3+1, MAy3-3, MAx3+8, MAy3-10); 00572 Doc->PostPaintEvent (_Line, MAx3-7, MAy3-10, MAx3+7, MAy3-10); 00573 } 00574 00575 00581 void MouseActions::MMoveMirrorY(Schematic *Doc, QMouseEvent *Event) 00582 { 00583 MAx3 = DOC_X_POS(Event->pos().x()); 00584 MAy3 = DOC_Y_POS(Event->pos().y()); 00585 00586 Doc->PostPaintEvent (_Line, MAx3-11, MAy3-4, MAx3-9, MAy3-9); 00587 Doc->PostPaintEvent (_Line, MAx3-11, MAy3-3, MAx3-6, MAy3-3); 00588 Doc->PostPaintEvent (_Line, MAx3+11, MAy3-4, MAx3+9, MAy3-9); 00589 Doc->PostPaintEvent (_Line, MAx3+11, MAy3-3, MAx3+6, MAy3-3); 00590 Doc->PostPaintEvent (_Arc, MAx3-10, MAy3-8, 21, 10, 16*20, 16*140,false); 00591 } 00592 00593 00599 void MouseActions::MMoveMirrorX(Schematic *Doc, QMouseEvent *Event) 00600 { 00601 MAx3 = DOC_X_POS(Event->pos().x()); 00602 MAy3 = DOC_Y_POS(Event->pos().y()); 00603 00604 Doc->PostPaintEvent (_Line, MAx3-4, MAy3-11, MAx3-9, MAy3-9); 00605 Doc->PostPaintEvent (_Line, MAx3-3, MAy3-11, MAx3-3, MAy3-6); 00606 Doc->PostPaintEvent (_Line, MAx3-4, MAy3+11, MAx3-9, MAy3+9); 00607 Doc->PostPaintEvent (_Line, MAx3-3, MAy3+11, MAx3-3, MAy3+6); 00608 Doc->PostPaintEvent (_Arc, MAx3-8, MAy3-10, 10, 21, 16*110, 16*140,false); 00609 } 00610 00616 void MouseActions::MMoveRotate(Schematic *Doc, QMouseEvent *Event) 00617 { 00618 MAx3 = DOC_X_POS(Event->pos().x()); 00619 MAy3 = DOC_Y_POS(Event->pos().y()); 00620 00621 Doc->PostPaintEvent (_Line, MAx3-6, MAy3+8, MAx3-6, MAy3+1); 00622 Doc->PostPaintEvent (_Line, MAx3-7, MAy3+8, MAx3-12, MAy3+8); 00623 Doc->PostPaintEvent (_Arc, MAx3-10, MAy3-10, 21, 21, -16*20, 16*240,false); 00624 } 00625 00626 00632 void MouseActions::MMoveActivate(Schematic *Doc, QMouseEvent *Event) 00633 { 00634 MAx3 = DOC_X_POS(Event->pos().x()); 00635 MAy3 = DOC_Y_POS(Event->pos().y()); 00636 00637 Doc->PostPaintEvent (_Rect, MAx3, MAy3-9, 14, 10); 00638 Doc->PostPaintEvent (_Line, MAx3, MAy3-9, MAx3+13, MAy3); 00639 Doc->PostPaintEvent (_Line, MAx3, MAy3, MAx3+13, MAy3-9); 00640 } 00641 00642 00648 void MouseActions::MMoveOnGrid(Schematic *Doc, QMouseEvent *Event) 00649 { 00650 MAx3 = DOC_X_POS(Event->pos().x()); 00651 MAy3 = DOC_Y_POS(Event->pos().y()); 00652 00653 Doc->PostPaintEvent (_Line, MAx3+10, MAy3+ 3, MAx3+25, MAy3+3); 00654 Doc->PostPaintEvent (_Line, MAx3+10, MAy3+ 7, MAx3+25, MAy3+7); 00655 Doc->PostPaintEvent (_Line, MAx3+10, MAy3+11, MAx3+25, MAy3+11); 00656 Doc->PostPaintEvent (_Line, MAx3+13, MAy3, MAx3+13, MAy3+15); 00657 Doc->PostPaintEvent (_Line, MAx3+17, MAy3, MAx3+17, MAy3+15); 00658 Doc->PostPaintEvent (_Line, MAx3+21, MAy3, MAx3+21, MAy3+15); 00659 } 00660 00661 00667 void MouseActions::MMoveMoveTextB(Schematic *Doc, QMouseEvent *Event) 00668 { 00669 MAx3 = DOC_X_POS(Event->pos().x()); 00670 MAy3 = DOC_Y_POS(Event->pos().y()); 00671 00672 Doc->PostPaintEvent (_Line, MAx3+14, MAy3 , MAx3+16, MAy3); 00673 Doc->PostPaintEvent (_Line, MAx3+23, MAy3 , MAx3+25, MAy3); 00674 Doc->PostPaintEvent (_Line, MAx3+13, MAy3 , MAx3+13, MAy3+ 3); 00675 Doc->PostPaintEvent (_Line, MAx3+13, MAy3+ 7, MAx3+13, MAy3+10); 00676 Doc->PostPaintEvent (_Line, MAx3+14, MAy3+10, MAx3+16, MAy3+10); 00677 Doc->PostPaintEvent (_Line, MAx3+23, MAy3+10, MAx3+25, MAy3+10); 00678 Doc->PostPaintEvent (_Line, MAx3+26, MAy3 , MAx3+26, MAy3+ 3); 00679 Doc->PostPaintEvent (_Line, MAx3+26, MAy3+ 7, MAx3+26, MAy3+10); 00680 } 00681 00682 00688 void MouseActions::MMoveMoveText(Schematic *Doc, QMouseEvent *Event) 00689 { 00690 int newX = DOC_X_POS(Event->pos().x()); 00691 int newY = DOC_Y_POS(Event->pos().y()); 00692 MAx1 += newX - MAx3; 00693 MAy1 += newY - MAy3; 00694 MAx3 = newX; 00695 MAy3 = newY; 00696 00697 Doc->PostPaintEvent (_Rect, MAx1, MAy1, MAx2, MAy2); 00698 } 00699 00700 00706 void MouseActions::MMoveZoomIn(Schematic *Doc, QMouseEvent *Event) 00707 { 00708 MAx3 = DOC_X_POS(Event->pos().x()); 00709 MAy3 = DOC_Y_POS(Event->pos().y()); 00710 00711 Doc->PostPaintEvent (_Line, MAx3+14, MAy3 , MAx3+22, MAy3); 00712 Doc->PostPaintEvent (_Line, MAx3+18, MAy3-4 , MAx3+18, MAy3+4); 00713 Doc->PostPaintEvent (_Ellipse, MAx3+12, MAy3-6, 13, 13,0,0,false); 00714 Doc->viewport()->update(); 00715 } 00716 00717 00718 // ************************************************************************ 00719 // ********** ********** 00720 // ********** Functions for serving mouse button clicking ********** 00721 // ********** ********** 00722 // ************************************************************************ 00723 00724 // Is called from several MousePress functions to show right button menu. 00725 void MouseActions::rightPressMenu(Schematic *Doc, QMouseEvent *Event, float fX, float fY) 00726 { 00727 MAx1 = int(fX); 00728 MAy1 = int(fY); 00729 focusElement = Doc->selectElement(fX, fY, false); 00730 00731 if(focusElement) // remove special function (4 least significant bits) 00732 focusElement->Type &= isSpecialMask; 00733 00734 00735 // define menu 00736 ComponentMenu->clear(); 00737 while(true) { 00738 if(focusElement) { 00739 focusElement->isSelected = true; 00740 ComponentMenu->insertItem( 00741 QObject::tr("Edit Properties"), QucsMain, SLOT(slotEditElement())); 00742 00743 if((focusElement->Type & isComponent) == 0) break; 00744 } 00745 else { 00747 //ComponentMenu->addAction(QucsMain->symEdit); 00748 //to QucsMain->symEdit->addTo(ComponentMenu); 00749 // see http://qt-project.org/doc/qt-4.8/qaction-qt3.html#addTo 00750 QucsMain->symEdit->addTo(ComponentMenu); 00751 QucsMain->fileSettings->addTo(ComponentMenu); 00752 } 00753 if(!QucsMain->moveText->isOn()) 00754 QucsMain->moveText->addTo(ComponentMenu); 00755 break; 00756 } 00757 while(true) { 00758 if(focusElement) 00759 if(focusElement->Type == isGraph) break; 00760 if(!QucsMain->onGrid->isOn()) 00761 QucsMain->onGrid->addTo(ComponentMenu); 00762 QucsMain->editCopy->addTo(ComponentMenu); 00763 if(!QucsMain->editPaste->isOn()) 00764 QucsMain->editPaste->addTo(ComponentMenu); 00765 break; 00766 } 00767 00768 while (true) { 00769 if (focusElement) { 00770 if (focusElement->Type == isDiagram) { 00771 ComponentMenu->insertItem(QObject::tr("Export as image"), QucsMain, 00772 SLOT(slotSaveDiagramToGraphicsFile())); 00773 } 00774 } 00775 break; 00776 } 00777 00778 if(!QucsMain->editDelete->isOn()) 00779 QucsMain->editDelete->addTo(ComponentMenu); 00780 if(focusElement) if(focusElement->Type == isMarker) { 00781 ComponentMenu->insertSeparator(); 00782 QString s = QObject::tr("power matching"); 00783 if( ((Marker*)focusElement)->pGraph->Var == "Sopt" ) 00784 s = QObject::tr("noise matching"); 00785 ComponentMenu->insertItem(s, QucsMain, SLOT(slotPowerMatching())); 00786 if( ((Marker*)focusElement)->pGraph->Var.left(2) == "S[" ) 00787 ComponentMenu->insertItem(QObject::tr("2-port matching"), QucsMain, 00788 SLOT(slot2PortMatching())); 00789 } 00790 do { 00791 if(focusElement) { 00792 if(focusElement->Type == isDiagram) break; 00793 if(focusElement->Type == isGraph) { 00794 QucsMain->graph2csv->addTo(ComponentMenu); 00795 break; 00796 } 00797 } 00798 ComponentMenu->insertSeparator(); 00799 if(focusElement) if(focusElement->Type & isComponent) 00800 if(!QucsMain->editActivate->isOn()) 00801 QucsMain->editActivate->addTo(ComponentMenu); 00802 if(!QucsMain->editRotate->isOn()) 00803 QucsMain->editRotate->addTo(ComponentMenu); 00804 if(!QucsMain->editMirror->isOn()) 00805 QucsMain->editMirror->addTo(ComponentMenu); 00806 if(!QucsMain->editMirrorY->isOn()) 00807 QucsMain->editMirrorY->addTo(ComponentMenu); 00808 00809 // right-click menu to go into hierarchy 00810 if(focusElement) { 00811 if(focusElement->Type & isComponent) 00812 if(((Component*)focusElement)->Model == "Sub") 00813 if(!QucsMain->intoH->isOn()) 00814 QucsMain->intoH->addTo(ComponentMenu); 00815 } 00816 // right-click menu to pop out of hierarchy 00817 if(!focusElement) 00818 if(!QucsMain->popH->isOn()) 00819 QucsMain->popH->addTo(ComponentMenu); 00820 } while(false); 00821 00822 *focusMEvent = *Event; // remember event for "edit component" action 00823 ComponentMenu->popup(Event->globalPos()); 00824 Doc->viewport()->update(); 00825 drawn = false; 00826 } 00827 00828 // ----------------------------------------------------------- 00829 void MouseActions::MPressLabel(Schematic *Doc, QMouseEvent*, float fX, float fY) 00830 { 00831 int x = int(fX), y = int(fY); 00832 Wire *pw = 0; 00833 WireLabel *pl=0; 00834 Node *pn = Doc->selectedNode(x, y); 00835 if(!pn) { 00836 pw = Doc->selectedWire(x, y); 00837 if(!pw) return; 00838 } 00839 00840 QString Name, Value; 00841 Element *pe=0; 00842 // is wire line already labeled ? 00843 if(pw) pe = Doc->getWireLabel(pw->Port1); 00844 else pe = Doc->getWireLabel(pn); 00845 if(pe) { 00846 if(pe->Type & isComponent) { 00847 QMessageBox::information(0, QObject::tr("Info"), 00848 QObject::tr("The ground potential cannot be labeled!")); 00849 return; 00850 } 00851 pl = ((Conductor*)pe)->Label; 00852 } 00853 00854 LabelDialog *Dia = new LabelDialog(pl, Doc); 00855 if(Dia->exec() == 0) return; 00856 00857 Name = Dia->NodeName->text(); 00858 Value = Dia->InitValue->text(); 00859 delete Dia; 00860 00861 if(Name.isEmpty() && Value.isEmpty() ) { // if nothing entered, delete name 00862 if(pe) { 00863 if(((Conductor*)pe)->Label) 00864 delete ((Conductor*)pe)->Label; // delete old name 00865 ((Conductor*)pe)->Label = 0; 00866 } 00867 else { 00868 if(pw) pw->setName("", ""); // delete name of wire 00869 else pn->setName("", ""); 00870 } 00871 } 00872 else { 00873 /* Name.replace(' ', '_'); // label must not contain spaces 00874 while(Name.at(0) == '_') Name.remove(0,1); // must not start with '_' 00875 if(Name.isEmpty()) return; 00876 */ 00877 if(pe) { 00878 if(((Conductor*)pe)->Label) 00879 delete ((Conductor*)pe)->Label; // delete old name 00880 ((Conductor*)pe)->Label = 0; 00881 } 00882 00883 int xl = x+30; 00884 int yl = y-30; 00885 Doc->setOnGrid(xl, yl); 00886 // set new name 00887 if(pw) pw->setName(Name, Value, x-pw->x1 + y-pw->y1, xl, yl); 00888 else pn->setName(Name, Value, xl, yl); 00889 } 00890 00891 Doc->sizeOfAll(Doc->UsedX1, Doc->UsedY1, Doc->UsedX2, Doc->UsedY2); 00892 Doc->viewport()->update(); 00893 drawn = false; 00894 Doc->setChanged(true, true); 00895 } 00896 00897 // ----------------------------------------------------------- 00898 void MouseActions::MPressSelect(Schematic *Doc, QMouseEvent *Event, float fX, float fY) 00899 { 00900 bool Ctrl; 00901 if(Event->state() & Qt::ControlModifier) Ctrl = true; 00902 else Ctrl = false; 00903 00904 int No=0; 00905 MAx1 = int(fX); 00906 MAy1 = int(fY); 00907 focusElement = Doc->selectElement(fX, fY, Ctrl, &No); 00908 isMoveEqual = false; // moving not neccessarily square 00909 00910 if(focusElement) 00911 // print define value in hex, see element.h 00912 qDebug() << "MPressSelect: focusElement->Type" << QString("0x%1").arg(focusElement->Type, 0, 16); 00913 else 00914 qDebug() << "MPressSelect"; 00915 00916 if(focusElement) 00917 switch(focusElement->Type) 00918 { 00919 case isPaintingResize: // resize painting ? 00920 focusElement->Type = isPainting; 00921 QucsMain->MouseReleaseAction = &MouseActions::MReleaseResizePainting; 00922 QucsMain->MouseMoveAction = &MouseActions::MMoveResizePainting; 00923 QucsMain->MousePressAction = 0; 00924 QucsMain->MouseDoubleClickAction = 0; 00925 Doc->grabKeyboard(); // no keyboard inputs during move actions 00926 // Update matching wire label highlighting 00927 Doc->highlightWireLabels (); 00928 return; 00929 00930 case isDiagramResize: // resize diagram ? 00931 if(((Diagram*)focusElement)->Name.left(4) != "Rect") 00932 if(((Diagram*)focusElement)->Name.at(0) != 'T') 00933 if(((Diagram*)focusElement)->Name != "Curve") 00934 isMoveEqual = true; // diagram must be square 00935 00936 focusElement->Type = isDiagram; 00937 MAx1 = focusElement->cx; 00938 MAx2 = focusElement->x2; 00939 if(((Diagram*)focusElement)->State & 1) { 00940 MAx1 += MAx2; 00941 MAx2 *= -1; 00942 } 00943 MAy1 = focusElement->cy; 00944 MAy2 = -focusElement->y2; 00945 if(((Diagram*)focusElement)->State & 2) { 00946 MAy1 += MAy2; 00947 MAy2 *= -1; 00948 } 00949 00950 QucsMain->MouseReleaseAction = &MouseActions::MReleaseResizeDiagram; 00951 QucsMain->MouseMoveAction = &MouseActions::MMoveSelect; 00952 QucsMain->MousePressAction = 0; 00953 QucsMain->MouseDoubleClickAction = 0; 00954 Doc->grabKeyboard(); // no keyboard inputs during move actions 00955 // Update matching wire label highlighting 00956 Doc->highlightWireLabels (); 00957 return; 00958 00959 case isDiagramHScroll: // scroll in tabular ? 00960 MAy1 = MAx1; 00961 00962 case isDiagramVScroll: 00963 focusElement->Type = isDiagram; 00964 00965 No = ((TabDiagram*)focusElement)->scroll(MAy1); 00966 00967 switch(No) 00968 { 00969 case 1: 00970 Doc->setChanged(true, true, 'm'); // 'm' = only the first time 00971 break; 00972 case 2: // move scroll bar with mouse cursor 00973 QucsMain->MouseMoveAction = &MouseActions::MMoveScrollBar; 00974 QucsMain->MousePressAction = 0; 00975 QucsMain->MouseDoubleClickAction = 0; 00976 Doc->grabKeyboard(); // no keyboard inputs during move actions 00977 00978 // Remember inital scroll bar position. 00979 MAx2 = int(((TabDiagram*)focusElement)->xAxis.limit_min); 00980 // Update matching wire label highlighting 00981 Doc->highlightWireLabels (); 00982 return; 00983 } 00984 // Update matching wire label highlighting 00985 Doc->highlightWireLabels (); 00986 Doc->viewport()->update(); 00987 drawn = false; 00988 return; 00989 00990 case isComponentText: // property text of component ? 00991 focusElement->Type &= (~isComponentText) | isComponent; 00992 00993 MAx3 = No; 00994 QucsMain->slotApplyCompText(); 00995 // Update matching wire label highlighting 00996 Doc->highlightWireLabels (); 00997 return; 00998 00999 case isNode: 01000 if (QucsSettings.NodeWiring) 01001 { 01002 MAx1 = 0; // paint wire corner first up, then left/right 01003 MAx3 = focusElement->cx; // works even if node is not on grid 01004 MAy3 = focusElement->cy; 01005 QucsMain->MouseMoveAction = &MouseActions::MMoveWire2; 01006 QucsMain->MousePressAction = &MouseActions::MPressWire2; 01007 QucsMain->MouseReleaseAction = 0; // if function is called from elsewhere 01008 QucsMain->MouseDoubleClickAction = 0; 01009 01010 formerAction = QucsMain->select; // to restore action afterwards 01011 QucsMain->activeAction = QucsMain->insWire; 01012 01013 QucsMain->select->blockSignals(true); 01014 QucsMain->select->setChecked(false); 01015 QucsMain->select->blockSignals(false); 01016 01017 QucsMain->insWire->blockSignals(true); 01018 QucsMain->insWire->setChecked(true); 01019 QucsMain->insWire->blockSignals(false); 01020 // Update matching wire label highlighting 01021 Doc->highlightWireLabels (); 01022 return; 01023 } 01024 } 01025 01026 QucsMain->MousePressAction = 0; 01027 QucsMain->MouseDoubleClickAction = 0; 01028 Doc->grabKeyboard(); // no keyboard inputs during move actions 01029 Doc->viewport()->update(); 01030 drawn = false; 01031 01032 if(focusElement == 0) { 01033 MAx2 = 0; // if not clicking on an element => open a rectangle 01034 MAy2 = 0; 01035 QucsMain->MouseReleaseAction = &MouseActions::MReleaseSelect2; 01036 QucsMain->MouseMoveAction = &MouseActions::MMoveSelect; 01037 } 01038 else 01039 { 01040 // element could be moved 01041 if(!Ctrl) 01042 { 01043 if(!focusElement->isSelected)// Don't move selected elements if clicked 01044 Doc->deselectElements(focusElement); // element was not selected. 01045 focusElement->isSelected = true; 01046 } 01047 Doc->setOnGrid(MAx1, MAy1); 01048 QucsMain->MouseMoveAction = &MouseActions::MMoveMoving; 01049 } 01050 // Update matching wire label highlighting 01051 Doc->highlightWireLabels (); 01052 } 01053 01054 // ----------------------------------------------------------- 01055 void MouseActions::MPressDelete(Schematic *Doc, QMouseEvent*, float fX, float fY) 01056 { 01057 Element *pe = Doc->selectElement(fX, fY, false); 01058 if(pe) 01059 { 01060 pe->isSelected = true; 01061 Doc->deleteElements(); 01062 01063 Doc->sizeOfAll(Doc->UsedX1, Doc->UsedY1, Doc->UsedX2, Doc->UsedY2); 01064 Doc->viewport()->update(); 01065 drawn = false; 01066 } 01067 } 01068 01069 // ----------------------------------------------------------- 01070 void MouseActions::MPressActivate(Schematic *Doc, QMouseEvent*, float fX, float fY) 01071 { 01072 MAx1 = int(fX); 01073 MAy1 = int(fY); 01074 if(!Doc->activateSpecifiedComponent(MAx1, MAy1)) { 01075 // if(Event->button() != Qt::LeftButton) return; 01076 MAx2 = 0; // if not clicking on a component => open a rectangle 01077 MAy2 = 0; 01078 QucsMain->MousePressAction = 0; 01079 QucsMain->MouseReleaseAction = &MouseActions::MReleaseActivate; 01080 QucsMain->MouseMoveAction = &MouseActions::MMoveSelect; 01081 } 01082 Doc->viewport()->update(); 01083 drawn = false; 01084 } 01085 01086 // ----------------------------------------------------------- 01087 void MouseActions::MPressMirrorX(Schematic *Doc, QMouseEvent*, float fX, float fY) 01088 { 01089 // no use in mirroring wires or diagrams 01090 Component *c = Doc->selectedComponent(int(fX), int(fY)); 01091 if(c) { 01092 if(c->Ports.count() < 1) return; // only mirror components with ports 01093 c->mirrorX(); 01094 Doc->setCompPorts(c); 01095 } 01096 else { 01097 Painting *p = Doc->selectedPainting(fX, fY); 01098 if(p == 0) return; 01099 p->mirrorX(); 01100 } 01101 01102 Doc->viewport()->update(); 01103 drawn = false; 01104 Doc->setChanged(true, true); 01105 } 01106 01107 // ----------------------------------------------------------- 01108 void MouseActions::MPressMirrorY(Schematic *Doc, QMouseEvent*, float fX, float fY) 01109 { 01110 // no use in mirroring wires or diagrams 01111 Component *c = Doc->selectedComponent(int(fX), int(fY)); 01112 if(c) { 01113 if(c->Ports.count() < 1) return; // only mirror components with ports 01114 c->mirrorY(); 01115 Doc->setCompPorts(c); 01116 } 01117 else { 01118 Painting *p = Doc->selectedPainting(fX, fY); 01119 if(p == 0) return; 01120 p->mirrorY(); 01121 } 01122 01123 Doc->viewport()->update(); 01124 drawn = false; 01125 Doc->setChanged(true, true); 01126 } 01127 01128 // ----------------------------------------------------------- 01129 void MouseActions::MPressRotate(Schematic *Doc, QMouseEvent*, float fX, float fY) 01130 { 01131 Element *e = Doc->selectElement(int(fX), int(fY), false); 01132 if(e == 0) return; 01133 e->Type &= isSpecialMask; // remove special functions 01134 01135 01136 WireLabel *pl; 01137 int x1, y1, x2, y2; 01138 // e->isSelected = false; 01139 switch(e->Type) { 01140 case isComponent: 01141 case isAnalogComponent: 01142 case isDigitalComponent: 01143 if(((Component*)e)->Ports.count() < 1) 01144 break; // do not rotate components without ports 01145 ((Component*)e)->rotate(); 01146 Doc->setCompPorts((Component*)e); 01147 // enlarge viewarea if component lies outside the view 01148 ((Component*)e)->entireBounds(x1,y1,x2,y2, Doc->textCorr()); 01149 Doc->enlargeView(x1, y1, x2, y2); 01150 break; 01151 01152 case isWire: 01153 pl = ((Wire*)e)->Label; 01154 ((Wire*)e)->Label = 0; // prevent label to be deleted 01155 Doc->Wires->setAutoDelete(false); 01156 Doc->deleteWire((Wire*)e); 01157 ((Wire*)e)->Label = pl; 01158 ((Wire*)e)->rotate(); 01159 Doc->setOnGrid(e->x1, e->y1); 01160 Doc->setOnGrid(e->x2, e->y2); 01161 if(pl) Doc->setOnGrid(pl->cx, pl->cy); 01162 Doc->insertWire((Wire*)e); 01163 Doc->Wires->setAutoDelete(true); 01164 if (Doc->Wires->containsRef ((Wire*)e)) 01165 Doc->enlargeView(e->x1, e->y1, e->x2, e->y2); 01166 break; 01167 01168 case isPainting: 01169 ((Painting*)e)->rotate(); 01170 // enlarge viewarea if component lies outside the view 01171 ((Painting*)e)->Bounding(x1,y1,x2,y2); 01172 Doc->enlargeView(x1, y1, x2, y2); 01173 break; 01174 01175 default: 01176 return; 01177 } 01178 Doc->viewport()->update(); 01179 drawn = false; 01180 Doc->setChanged(true, true); 01181 } 01182 01183 // ----------------------------------------------------------- 01184 // insert component, diagram, painting into schematic ?! 01185 void MouseActions::MPressElement(Schematic *Doc, QMouseEvent *Event, float, float) 01186 { 01187 if(selElem == 0) return; 01188 //QPainter painter(Doc->viewport()); 01189 //setPainter(Doc, &painter); 01190 01191 01192 int x1, y1, x2, y2, rot; 01193 if(selElem->Type & isComponent) { 01194 Component *Comp = (Component*)selElem; 01195 // qDebug() << "+-+ got to switch:" << Comp->Name; 01196 QString entryName = Comp->Name; 01197 01198 switch(Event->button()) { 01199 case Qt::LeftButton : 01200 // left mouse button inserts component into the schematic 01201 // give the component a pointer to the schematic it's a 01202 // part of 01203 Comp->setSchematic (Doc); 01204 Comp->textSize(x1, y1); 01205 Doc->insertComponent(Comp); 01206 Comp->textSize(x2, y2); 01207 if(Comp->tx < Comp->x1) Comp->tx -= x2 - x1; 01208 01209 // Note: insertCopmponents does increment name1 -> name2 01210 // qDebug() << " +-+ got to insert:" << Comp->Name; 01211 01212 // enlarge viewarea if component lies outside the view 01213 Comp->entireBounds(x1,y1,x2,y2, Doc->textCorr()); 01214 Doc->enlargeView(x1, y1, x2, y2); 01215 01216 drawn = false; 01217 Doc->viewport()->update(); 01218 Doc->setChanged(true, true); 01219 rot = Comp->rotated; 01220 01221 // handle static and dynamic components 01222 // QucsApp::CompChoose; 01223 if (Module::vaComponents.contains(entryName)){ 01224 QString filename = Module::vaComponents[entryName]; 01225 // qDebug() << " ===+ recast"; 01226 Comp = dynamic_cast<vacomponent*>(Comp)->newOne(filename); //va component 01227 qDebug() << " => recast = Comp;" << Comp->Name << "filename: " << filename; 01228 } 01229 else { 01230 Comp = Comp->newOne(); // static component is used, so create a new one 01231 } 01232 rot -= Comp->rotated; 01233 rot &= 3; 01234 while(rot--) Comp->rotate(); // keep last rotation for single component 01235 break; 01236 01237 case Qt::RightButton : // right mouse button rotates the component 01238 if(Comp->Ports.count() == 0) 01239 break; // do not rotate components without ports 01240 Comp->paintScheme(Doc); // erase old component scheme 01241 Comp->rotate(); 01242 Comp->paintScheme(Doc); // paint new component scheme 01243 break; 01244 01245 default: ; // avoids compiler warnings 01246 } 01247 // qDebug() << " => selElem = Comp;" << Comp->Name; 01248 // comp it geting empty 01249 selElem = Comp; 01250 return; 01251 01252 } // of "if(isComponent)" 01253 else if(selElem->Type == isDiagram) { 01254 if(Event->button() != Qt::LeftButton) return; 01255 01256 Diagram *Diag = (Diagram*)selElem; 01257 QFileInfo Info(Doc->DocName); 01258 // dialog is Qt::WDestructiveClose !!! 01259 DiagramDialog *dia = 01260 new DiagramDialog(Diag, Doc); 01261 if(dia->exec() == QDialog::Rejected) { // don't insert if dialog canceled 01262 Doc->viewport()->update(); 01263 drawn = false; 01264 return; 01265 } 01266 01267 Doc->Diagrams->append(Diag); 01268 Doc->enlargeView(Diag->cx, Diag->cy-Diag->y2, Diag->cx+Diag->x2, Diag->cy); 01269 Doc->setChanged(true, true); // document has been changed 01270 01271 Doc->viewport()->repaint(); 01272 Diag = Diag->newOne(); // the component is used, so create a new one 01273 Diag->paintScheme(Doc); 01274 selElem = Diag; 01275 return; 01276 } // of "if(isDiagram)" 01277 01278 01279 // *********** it is a painting !!! 01280 if(((Painting*)selElem)->MousePressing()) { 01281 Doc->Paintings->append((Painting*)selElem); 01282 ((Painting*)selElem)->Bounding(x1,y1,x2,y2); 01283 //Doc->enlargeView(x1, y1, x2, y2); 01284 selElem = ((Painting*)selElem)->newOne(); 01285 01286 Doc->viewport()->update(); 01287 Doc->setChanged(true, true); 01288 01289 MMoveElement(Doc, Event); // needed before next mouse pressing 01290 drawn = false; 01291 } 01292 } 01293 01294 01301 void MouseActions::MPressWire1(Schematic *Doc, QMouseEvent*, float fX, float fY) 01302 { 01303 //Doc->PostPaintEvent (_DotLine); 01304 //Doc->PostPaintEvent (_NotRop); 01305 //if(drawn) { 01306 Doc->PostPaintEvent (_Line, 0, MAy3, MAx2, MAy3); // erase old mouse cross 01307 Doc->PostPaintEvent (_Line, MAx3, 0, MAx3, MAy2); 01308 //} 01309 //drawn = false; 01310 01311 MAx1 = 0; // paint wire corner first up, then left/right 01312 MAx3 = int(fX); 01313 MAy3 = int(fY); 01314 Doc->setOnGrid(MAx3, MAy3); 01315 01316 formerAction = 0; // keep wire action active after first wire finished 01317 QucsMain->MouseMoveAction = &MouseActions::MMoveWire2; 01318 QucsMain->MousePressAction = &MouseActions::MPressWire2; 01319 // Double-click action is set in "MMoveWire2" to not initiate it 01320 // during "Wire1" actions. 01321 Doc->viewport()->update(); 01322 } 01323 01324 01332 void MouseActions::MPressWire2(Schematic *Doc, QMouseEvent *Event, float fX, float fY) 01333 { 01334 01335 int set1 = 0, set2 = 0; 01336 switch(Event->button()) { 01337 case Qt::LeftButton : 01338 if(MAx1 == 0) { // which wire direction first ? 01339 if(MAy2 != MAy3) 01340 set1 = Doc->insertWire(new Wire(MAx3, MAy3, MAx3, MAy2)); 01341 if(MAx2 != MAx3) { 01342 set2 = set1; 01343 set1 = Doc->insertWire(new Wire(MAx3, MAy2, MAx2, MAy2)); 01344 } 01345 } 01346 else { 01347 if(MAx2 != MAx3) 01348 set1 = Doc->insertWire(new Wire(MAx3, MAy3, MAx2, MAy3)); 01349 if(MAy2 != MAy3) { 01350 set2 = set1; 01351 set1 = Doc->insertWire(new Wire(MAx2, MAy3, MAx2, MAy2)); 01352 } 01353 } 01354 01355 if(set1 & 2) { 01356 // if last port is connected, then... 01357 if(formerAction) { 01358 // ...restore old action 01359 QucsMain->select->setChecked(true); 01360 } 01361 else { 01362 // ...start a new wire 01363 QucsMain->MouseMoveAction = &MouseActions::MMoveWire1; 01364 QucsMain->MousePressAction = &MouseActions::MPressWire1; 01365 QucsMain->MouseDoubleClickAction = 0; 01366 } 01367 } 01368 01369 Doc->viewport()->update(); 01370 drawn = false; 01371 if(set1 | set2) Doc->setChanged(true, true); 01372 MAx3 = MAx2; 01373 MAy3 = MAy2; 01374 break; 01375 01377 case Qt::RightButton : 01378 if(MAx1 == 0) { 01379 Doc->PostPaintEvent (_Line, MAx3, MAy3, MAx3, MAy2); // erase old 01380 Doc->PostPaintEvent (_Line, MAx3, MAy2, MAx2, MAy2); // erase old 01381 } 01382 else { 01383 Doc->PostPaintEvent (_Line, MAx3, MAy3, MAx2, MAy3); // erase old 01384 Doc->PostPaintEvent (_Line, MAx2, MAy3, MAx2, MAy2); // erase old 01385 } 01386 01387 MAx2 = int(fX); 01388 MAy2 = int(fY); 01389 Doc->setOnGrid(MAx2, MAy2); 01390 01391 MAx1 ^= 1; // change the painting direction of wire corner 01392 if(MAx1 == 0) { 01393 Doc->PostPaintEvent (_Line, MAx3, MAy3, MAx3, MAy2); // paint 01394 Doc->PostPaintEvent (_Line, MAx3, MAy2, MAx2, MAy2); // paint 01395 } 01396 else { 01397 Doc->PostPaintEvent (_Line, MAx3, MAy3, MAx2, MAy3); // paint 01398 Doc->PostPaintEvent (_Line, MAx2, MAy3, MAx2, MAy2); // paint 01399 } 01400 break; 01401 01402 default: ; // avoids compiler warnings 01403 } 01404 Doc->viewport()->update(); 01405 } 01406 01407 // ----------------------------------------------------------- 01408 // Is called for setting a marker on a diagram's graph 01409 void MouseActions::MPressMarker(Schematic *Doc, QMouseEvent*, float fX, float fY) 01410 { 01411 MAx1 = int(fX); 01412 MAy1 = int(fY); 01413 Marker *pm = Doc->setMarker(MAx1, MAy1); 01414 01415 if(pm) { 01416 assert(pm->diag()); 01417 int x0 = pm->diag()->cx; 01418 int y0 = pm->diag()->cy; 01419 Doc->enlargeView(x0+pm->x1, y0-pm->y1-pm->y2, x0+pm->x1+pm->x2, y0-pm->y1); 01420 } 01421 Doc->viewport()->update(); 01422 drawn = false; 01423 } 01424 01425 // ----------------------------------------------------------- 01426 void MouseActions::MPressOnGrid(Schematic *Doc, QMouseEvent*, float fX, float fY) 01427 { 01428 Element *pe = Doc->selectElement(fX, fY, false); 01429 if(pe) 01430 { 01431 pe->Type &= isSpecialMask; // remove special functions (4 lowest bits) 01432 01433 // onGrid is toggle action -> no other element can be selected 01434 pe->isSelected = true; 01435 Doc->elementsOnGrid(); 01436 01437 Doc->sizeOfAll(Doc->UsedX1, Doc->UsedY1, Doc->UsedX2, Doc->UsedY2); 01438 // Update matching wire label highlighting 01439 Doc->highlightWireLabels (); 01440 Doc->viewport()->update(); 01441 drawn = false; 01442 } 01443 01444 } 01445 01446 // ----------------------------------------------------------- 01447 void MouseActions::MPressMoveText(Schematic *Doc, QMouseEvent*, float fX, float fY) 01448 { 01449 MAx1 = int(fX); 01450 MAy1 = int(fY); 01451 focusElement = Doc->selectCompText(MAx1, MAy1, MAx2, MAy2); 01452 01453 if(focusElement) { 01454 MAx3 = MAx1; 01455 MAy3 = MAy1; 01456 MAx1 = ((Component*)focusElement)->cx + ((Component*)focusElement)->tx; 01457 MAy1 = ((Component*)focusElement)->cy + ((Component*)focusElement)->ty; 01458 Doc->viewport()->update(); 01459 drawn = false; 01460 QucsMain->MouseMoveAction = &MouseActions::MMoveMoveText; 01461 QucsMain->MouseReleaseAction = &MouseActions::MReleaseMoveText; 01462 Doc->grabKeyboard(); // no keyboard inputs during move actions 01463 } 01464 } 01465 01466 // ----------------------------------------------------------- 01467 void MouseActions::MPressZoomIn(Schematic *Doc, QMouseEvent*, float fX, float fY) 01468 { 01469 qDebug() << "zoom into box"; 01470 MAx1 = int(fX); 01471 MAy1 = int(fY); 01472 MAx2 = 0; // rectangle size 01473 MAy2 = 0; 01474 01475 QucsMain->MouseMoveAction = &MouseActions::MMoveSelect; 01476 QucsMain->MouseReleaseAction = &MouseActions::MReleaseZoomIn; 01477 Doc->grabKeyboard(); // no keyboard inputs during move actions 01478 Doc->viewport()->update(); 01479 drawn = false; 01480 } 01481 01482 01483 // *********************************************************************** 01484 // ********** ********** 01485 // ********** Functions for serving mouse button releasing ********** 01486 // ********** ********** 01487 // *********************************************************************** 01488 void MouseActions::MReleaseSelect(Schematic *Doc, QMouseEvent *Event) 01489 { 01490 bool ctrl; 01491 if(Event->state() & Qt::ControlModifier) ctrl = true; 01492 else ctrl = false; 01493 01494 if(!ctrl) Doc->deselectElements(focusElement); 01495 01496 if(focusElement) if(Event->button() == Qt::LeftButton) 01497 if(focusElement->Type == isWire) { 01498 Doc->selectWireLine(focusElement, ((Wire*)focusElement)->Port1, ctrl); 01499 Doc->selectWireLine(focusElement, ((Wire*)focusElement)->Port2, ctrl); 01500 } 01501 01502 Doc->releaseKeyboard(); // allow keyboard inputs again 01503 QucsMain->MousePressAction = &MouseActions::MPressSelect; 01504 QucsMain->MouseReleaseAction = &MouseActions::MReleaseSelect; 01505 QucsMain->MouseDoubleClickAction = &MouseActions::MDoubleClickSelect; 01506 QucsMain->MouseMoveAction = 0; // no element moving 01507 Doc->highlightWireLabels (); 01508 Doc->viewport()->update(); 01509 drawn = false; 01510 } 01511 01512 // ----------------------------------------------------------- 01513 // Is called after the rectangle for selection is released. 01514 void MouseActions::MReleaseSelect2(Schematic *Doc, QMouseEvent *Event) 01515 { 01516 if(Event->button() != Qt::LeftButton) return; 01517 01518 bool Ctrl; 01519 if(Event->state() & Qt::ControlModifier) Ctrl = true; 01520 else Ctrl = false; 01521 01522 // selects all elements within the rectangle 01523 Doc->selectElements(MAx1, MAy1, MAx1+MAx2, MAy1+MAy2, Ctrl); 01524 01525 Doc->releaseKeyboard(); // allow keyboard inputs again 01526 QucsMain->MouseMoveAction = 0; 01527 QucsMain->MousePressAction = &MouseActions::MPressSelect; 01528 QucsMain->MouseReleaseAction = &MouseActions::MReleaseSelect; 01529 QucsMain->MouseDoubleClickAction = &MouseActions::MDoubleClickSelect; 01530 Doc->highlightWireLabels (); 01531 Doc->viewport()->update(); 01532 drawn = false; 01533 } 01534 01535 // ----------------------------------------------------------- 01536 void MouseActions::MReleaseActivate(Schematic *Doc, QMouseEvent *Event) 01537 { 01538 if(Event->button() != Qt::LeftButton) return; 01539 01540 // activates all components within the rectangle 01541 Doc->activateCompsWithinRect(MAx1, MAy1, MAx1+MAx2, MAy1+MAy2); 01542 01543 QucsMain->MouseMoveAction = &MouseActions::MMoveActivate; 01544 QucsMain->MousePressAction = &MouseActions::MPressActivate; 01545 QucsMain->MouseReleaseAction = 0; 01546 QucsMain->MouseDoubleClickAction = 0; 01547 Doc->highlightWireLabels (); 01548 Doc->viewport()->update(); 01549 drawn = false; 01550 } 01551 01552 // ----------------------------------------------------------- 01553 // Is called after moving selected elements. 01554 void MouseActions::MReleaseMoving(Schematic *Doc, QMouseEvent*) 01555 { 01556 // Allow all mouse buttons, because for others than the left one, 01557 // a menu has already created. 01558 endElementMoving(Doc, &movingElements); 01559 Doc->releaseKeyboard(); // allow keyboard inputs again 01560 01561 QucsMain->MouseMoveAction = 0; 01562 QucsMain->MousePressAction = &MouseActions::MPressSelect; 01563 QucsMain->MouseReleaseAction = &MouseActions::MReleaseSelect; 01564 QucsMain->MouseDoubleClickAction = &MouseActions::MDoubleClickSelect; 01565 } 01566 01567 // ----------------------------------------------------------- 01568 void MouseActions::MReleaseResizeDiagram(Schematic *Doc, QMouseEvent *Event) 01569 { 01570 if(Event->button() != Qt::LeftButton) return; 01571 01572 MAx3 = focusElement->cx; 01573 MAy3 = focusElement->cy; 01574 if(MAx2 < 0) { // resize diagram 01575 if(MAx2 > -10) MAx2 = -10; // not smaller than 10 pixels 01576 focusElement->x2 = -MAx2; 01577 focusElement->cx = MAx1+MAx2; 01578 } 01579 else { 01580 if(MAx2 < 10) MAx2 = 10; 01581 focusElement->x2 = MAx2; 01582 focusElement->cx = MAx1; 01583 } 01584 if(MAy2 < 0) { 01585 if(MAy2 > -10) MAy2 = -10; 01586 focusElement->y2 = -MAy2; 01587 focusElement->cy = MAy1; 01588 } 01589 else { 01590 if(MAy2 < 10) MAy2 = 10; 01591 focusElement->y2 = MAy2; 01592 focusElement->cy = MAy1+MAy2; 01593 } 01594 MAx3 -= focusElement->cx; 01595 MAy3 -= focusElement->cy; 01596 01597 Diagram *pd = (Diagram*)focusElement; 01598 pd->updateGraphData(); 01599 foreach(Graph *pg, pd->Graphs) 01600 foreach(Marker *pm, pg->Markers) { 01601 pm->x1 += MAx3; // correct changes due to move of diagram corner 01602 pm->y1 += MAy3; 01603 } 01604 01605 int x1, x2, y1, y2; 01606 pd->Bounding(x1, x2, y1, y2); 01607 Doc->enlargeView(x1, x2, y1, y2); 01608 01609 QucsMain->MouseMoveAction = 0; 01610 QucsMain->MousePressAction = &MouseActions::MPressSelect; 01611 QucsMain->MouseReleaseAction = &MouseActions::MReleaseSelect; 01612 QucsMain->MouseDoubleClickAction = &MouseActions::MDoubleClickSelect; 01613 Doc->releaseKeyboard(); // allow keyboard inputs again 01614 01615 Doc->viewport()->update(); 01616 drawn = false; 01617 Doc->setChanged(true, true); 01618 } 01619 01620 // ----------------------------------------------------------- 01621 void MouseActions::MReleaseResizePainting(Schematic *Doc, QMouseEvent *Event) 01622 { 01623 if(Event->button() != Qt::LeftButton) return; 01624 01625 QucsMain->MouseMoveAction = 0; 01626 QucsMain->MousePressAction = &MouseActions::MPressSelect; 01627 QucsMain->MouseReleaseAction = &MouseActions::MReleaseSelect; 01628 QucsMain->MouseDoubleClickAction = &MouseActions::MDoubleClickSelect; 01629 Doc->releaseKeyboard(); // allow keyboard inputs again 01630 01631 Doc->viewport()->update(); 01632 drawn = false; 01633 Doc->setChanged(true, true); 01634 } 01635 01636 // ----------------------------------------------------------- 01637 void MouseActions::paintElementsScheme(Schematic *p) 01638 { 01639 Element *pe; 01640 for(pe = movingElements.first(); pe != 0; pe = movingElements.next()) 01641 pe->paintScheme(p); 01642 } 01643 01644 // ----------------------------------------------------------- 01645 void MouseActions::moveElements(Schematic *Doc, int& x1, int& y1) 01646 { 01647 Element *pe; 01648 Doc->setOnGrid(x1, y1); 01649 01650 for(pe=movingElements.first(); pe!=0; pe=movingElements.next()) { 01651 if(pe->Type & isLabel) { 01652 pe->cx += x1; pe->x1 += x1; 01653 pe->cy += y1; pe->y1 += y1; 01654 } 01655 else 01656 pe->setCenter(x1, y1, true); 01657 } 01658 } 01659 01660 // ----------------------------------------------------------- 01661 void MouseActions::rotateElements(Schematic *Doc, int& x1, int& y1) 01662 { 01663 int x2, y2; 01664 Element *pe; 01665 Doc->setOnGrid(x1, y1); 01666 01667 for(pe = movingElements.first(); pe != 0; pe = movingElements.next()) { 01668 switch(pe->Type) { 01669 case isComponent: 01670 case isAnalogComponent: 01671 case isDigitalComponent: 01672 ((Component*)pe)->rotate(); // rotate !before! rotating the center 01673 x2 = x1 - pe->cx; 01674 pe->setCenter(pe->cy - y1 + x1, x2 + y1); 01675 break; 01676 case isWire: 01677 x2 = pe->x1; 01678 pe->x1 = pe->y1 - y1 + x1; 01679 pe->y1 = x1 - x2 + y1; 01680 x2 = pe->x2; 01681 pe->x2 = pe->y2 - y1 + x1; 01682 pe->y2 = x1 - x2 + y1; 01683 break; 01684 case isPainting: 01685 ((Painting*)pe)->rotate(); // rotate !before! rotating the center 01686 ((Painting*)pe)->getCenter(x2, y2); 01687 pe->setCenter(y2 - y1 + x1, x1 - x2 + y1); 01688 break; 01689 default: 01690 x2 = x1 - pe->cx; // if diagram -> only rotate cx/cy 01691 pe->setCenter(pe->cy - y1 + x1, x2 + y1); 01692 break; 01693 } 01694 } 01695 } 01696 01697 // ----------------------------------------------------------- 01698 void MouseActions::MReleasePaste(Schematic *Doc, QMouseEvent *Event) 01699 { 01700 int x1, y1, x2, y2, rot; 01701 QFileInfo Info(Doc->DocName); 01702 //QPainter painter(Doc->viewport()); 01703 01704 Element *pe; 01705 switch(Event->button()) { 01706 case Qt::LeftButton : 01707 // insert all moved elements into document 01708 for(pe = movingElements.first(); pe!=0; pe = movingElements.next()) { 01709 pe->isSelected = false; 01710 switch(pe->Type) { 01711 case isWire: 01712 if(pe->x1 == pe->x2) if(pe->y1 == pe->y2) break; 01713 Doc->insertWire((Wire*)pe); 01714 if (Doc->Wires->containsRef ((Wire*)pe)) 01715 Doc->enlargeView(pe->x1, pe->y1, pe->x2, pe->y2); 01716 else pe = NULL; 01717 break; 01718 case isDiagram: 01719 Doc->Diagrams->append((Diagram*)pe); 01720 ((Diagram*)pe)->loadGraphData(Info.dirPath() + QDir::separator() + 01721 Doc->DataSet); 01722 Doc->enlargeView(pe->cx, pe->cy-pe->y2, pe->cx+pe->x2, pe->cy); 01723 break; 01724 case isPainting: 01725 Doc->Paintings->append((Painting*)pe); 01726 ((Painting*)pe)->Bounding(x1,y1,x2,y2); 01727 Doc->enlargeView(x1, y1, x2, y2); 01728 break; 01729 case isMovingLabel: 01730 pe->Type = isNodeLabel; 01731 Doc->placeNodeLabel((WireLabel*)pe); 01732 break; 01733 case isComponent: 01734 case isAnalogComponent: 01735 case isDigitalComponent: 01736 Doc->insertComponent((Component*)pe); 01737 ((Component*)pe)->entireBounds(x1,y1,x2,y2, Doc->textCorr()); 01738 Doc->enlargeView(x1, y1, x2, y2); 01739 break; 01740 } 01741 } 01742 01743 pasteElements(Doc); 01744 // keep rotation sticky for pasted elements 01745 rot = movingRotated; 01746 x1 = y1 = 0; 01747 while(rot--) rotateElements(Doc,x1,y1); 01748 01749 QucsMain->MouseMoveAction = &MouseActions::MMovePaste; 01750 QucsMain->MousePressAction = 0; 01751 QucsMain->MouseReleaseAction = 0; 01752 QucsMain->MouseDoubleClickAction = 0; 01753 01754 drawn = false; 01755 Doc->viewport()->update(); 01756 Doc->setChanged(true, true); 01757 break; 01758 01759 // ............................................................ 01760 case Qt::RightButton : // right button rotates the elements 01761 //setPainter(Doc, &painter); 01762 01763 if(drawn) // erase old scheme 01764 paintElementsScheme(Doc); 01765 drawn = true; 01766 01767 x1 = DOC_X_POS(Event->pos().x()); 01768 y1 = DOC_Y_POS(Event->pos().y()); 01769 rotateElements(Doc,x1,y1); 01770 paintElementsScheme(Doc); 01771 // save rotation 01772 movingRotated++; 01773 movingRotated &= 3; 01774 break; 01775 01776 default: ; // avoids compiler warnings 01777 } 01778 } 01779 01780 // ----------------------------------------------------------- 01781 void MouseActions::MReleaseMoveText(Schematic *Doc, QMouseEvent *Event) 01782 { 01783 if(Event->button() != Qt::LeftButton) return; 01784 01785 QucsMain->MouseMoveAction = &MouseActions::MMoveMoveTextB; 01786 QucsMain->MouseReleaseAction = 0; 01787 Doc->releaseKeyboard(); // allow keyboard inputs again 01788 01789 ((Component*)focusElement)->tx = MAx1 - ((Component*)focusElement)->cx; 01790 ((Component*)focusElement)->ty = MAy1 - ((Component*)focusElement)->cy; 01791 Doc->viewport()->update(); 01792 drawn = false; 01793 Doc->setChanged(true, true); 01794 } 01795 01796 // ----------------------------------------------------------- 01797 void MouseActions::MReleaseZoomIn(Schematic *Doc, QMouseEvent *Event) 01798 { 01799 if(Event->button() != Qt::LeftButton) return; 01800 01801 MAx1 = Event->pos().x(); 01802 MAy1 = Event->pos().y(); 01803 float DX = float(MAx2); 01804 float DY = float(MAy2); 01805 01806 float initialScale = Doc->Scale; 01807 float scale = 1; 01808 float xShift = 0; 01809 float yShift = 0; 01810 if((Doc->Scale * DX) < 6.0) { 01811 // a simple click zooms by constant factor 01812 scale = Doc->zoom(1.5)/initialScale; 01813 01814 xShift = scale * Event->pos().x(); 01815 yShift = scale * Event->pos().y(); 01816 } else { 01817 float xScale = float(Doc->visibleWidth()) / std::abs(DX); 01818 float yScale = float(Doc->visibleHeight()) / std::abs(DY); 01819 scale = qMin(xScale, yScale)/initialScale; 01820 scale = Doc->zoom(scale)/initialScale; 01821 01822 xShift = scale * (MAx1 - 0.5*DX); 01823 yShift = scale * (MAy1 - 0.5*DY); 01824 } 01825 xShift -= (0.5*Doc->visibleWidth() + Doc->contentsX()); 01826 yShift -= (0.5*Doc->visibleHeight() + Doc->contentsY()); 01827 Doc->scrollBy(xShift, yShift); 01828 01829 QucsMain->MouseMoveAction = &MouseActions::MMoveZoomIn; 01830 QucsMain->MouseReleaseAction = 0; 01831 Doc->releaseKeyboard(); // allow keyboard inputs again 01832 } 01833 01834 01835 // *********************************************************************** 01836 // ********** ********** 01837 // ********** Functions for mouse button double clicking ********** 01838 // ********** ********** 01839 // *********************************************************************** 01840 void MouseActions::editElement(Schematic *Doc, QMouseEvent *Event) 01841 { 01842 // qDebug() << "+double click, editElement"; 01843 01844 if(focusElement == 0) return; 01845 01846 // qDebug() << "+focusElement->Type" << focusElement->Type; 01847 01848 Graph *pg; 01849 Component *c; 01850 Diagram *dia; 01851 DiagramDialog *ddia; 01852 MarkerDialog *mdia; 01853 int x1, y1, x2, y2; 01854 01855 QFileInfo Info(Doc->DocName); 01856 float fX = DOC_X_FPOS, fY = DOC_Y_FPOS; 01857 01858 switch(focusElement->Type) { 01859 case isComponent: 01860 case isAnalogComponent: 01861 case isDigitalComponent: 01862 c = (Component*)focusElement; 01863 // qDebug() << "cast focusElement into" << c->Name; 01864 if(c->Model == "GND") return; 01865 01866 if(c->Model == "SPICE") { 01867 SpiceDialog *sd = new SpiceDialog(App, (SpiceFile*)c, Doc); 01868 if(sd->exec() != 1) break; // dialog is WDestructiveClose 01869 } 01870 else if(c->Model == ".Opt") { 01871 OptimizeDialog *od = new OptimizeDialog((Optimize_Sim*)c, Doc); 01872 if(od->exec() != 1) break; // dialog is WDestructiveClose 01873 } 01874 else { 01875 ComponentDialog * cd = new ComponentDialog(c, Doc); 01876 if(cd->exec() != 1) break; // dialog is WDestructiveClose 01877 01878 Doc->Components->findRef(c); 01879 Doc->Components->take(); 01880 Doc->setComponentNumber(c); // for ports/power sources 01881 Doc->Components->append(c); 01882 } 01883 01884 Doc->setChanged(true, true); 01885 c->entireBounds(x1,y1,x2,y2, Doc->textCorr()); 01886 Doc->enlargeView(x1,y1,x2,y2); 01887 break; 01888 01889 case isDiagram : 01890 dia = (Diagram*)focusElement; 01891 if(dia->Name.at(0) == 'T') { // don't open dialog on scrollbar 01892 if(dia->Name == "Time") { 01893 if(dia->cy < int(fY)) { 01894 if(((TimingDiagram*)focusElement)->scroll(MAx1)) 01895 Doc->setChanged(true, true, 'm'); // 'm' = only the first time 01896 break; 01897 } 01898 } 01899 else { 01900 if(dia->cx > int(fX)) { 01901 if(((TabDiagram*)focusElement)->scroll(MAy1)) 01902 Doc->setChanged(true, true, 'm'); // 'm' = only the first time 01903 break; 01904 } 01905 } 01906 } 01907 01908 ddia = new DiagramDialog(dia, Doc); 01909 if(ddia->exec() != QDialog::Rejected) // is WDestructiveClose 01910 Doc->setChanged(true, true); 01911 01912 dia->Bounding(x1, x2, y1, y2); 01913 Doc->enlargeView(x1, x2, y1, y2); 01914 break; 01915 01916 case isGraph : 01917 pg = (Graph*)focusElement; 01918 // searching diagram for this graph 01919 for(dia = Doc->Diagrams->last(); dia != 0; dia = Doc->Diagrams->prev()) 01920 if(dia->Graphs.indexOf(pg) >= 0) 01921 break; 01922 if(!dia) break; 01923 01924 01925 ddia = new DiagramDialog(dia, Doc, pg); 01926 if(ddia->exec() != QDialog::Rejected) // is WDestructiveClose 01927 Doc->setChanged(true, true); 01928 break; 01929 01930 case isWire: 01931 MPressLabel(Doc, Event, fX, fY); 01932 break; 01933 01934 case isNodeLabel: 01935 case isHWireLabel: 01936 case isVWireLabel: 01937 editLabel(Doc, (WireLabel*)focusElement); 01938 break; 01939 01940 case isPainting: 01941 if( ((Painting*)focusElement)->Dialog() ) 01942 Doc->setChanged(true, true); 01943 break; 01944 01945 case isMarker: 01946 mdia = new MarkerDialog((Marker*)focusElement, Doc); 01947 if(mdia->exec() > 1) 01948 Doc->setChanged(true, true); 01949 break; 01950 } 01951 01952 // Very strange: Now an open VHDL editor gets all the keyboard input !?! 01953 // I don't know why it only happens here, nor am I sure whether it only 01954 // happens here. Anyway, I hope the best and give the focus back to the 01955 // current document. 01956 Doc->setFocus(); 01957 01958 Doc->viewport()->update(); 01959 drawn = false; 01960 } 01961 01962 // ----------------------------------------------------------- 01963 void MouseActions::MDoubleClickSelect(Schematic *Doc, QMouseEvent *Event) 01964 { 01965 Doc->releaseKeyboard(); // allow keyboard inputs again 01966 QucsMain->editText->setHidden(true); 01967 editElement(Doc, Event); 01968 } 01969 01970 01976 void MouseActions::MDoubleClickWire2(Schematic *Doc, QMouseEvent *Event) 01977 { 01978 MPressWire2(Doc, Event, DOC_X_FPOS, DOC_Y_FPOS); 01979 01980 if(formerAction) 01981 QucsMain->select->setChecked(true); // restore old action 01982 else { 01983 QucsMain->MouseMoveAction = &MouseActions::MMoveWire1; 01984 QucsMain->MousePressAction = &MouseActions::MPressWire1; 01985 QucsMain->MouseDoubleClickAction = 0; 01986 } 01987 } 01988 01989 // vim:ts=8:sw=2:noet