]> Shamusworld >> Repos - architektonas/blob - src/base/rs_graphicview.cpp
Scrubbed out all references to RS2::qtToRsButton(). Gone!
[architektonas] / src / base / rs_graphicview.cpp
1 // rs_graphicview.cpp
2 //
3 // Part of the Architektonas Project
4 // Originally part of QCad Community Edition by Andrew Mustun
5 // Extensively rewritten and refactored by James L. Hammons
6 // (C) 2010 Underground Software
7 //
8 // JLH = James L. Hammons <jlhamm@acm.org>
9 //
10 // Who  When        What
11 // ---  ----------  -----------------------------------------------------------
12 // JLH  05/21/2010  Added this text. :-)
13 //
14
15 #include "rs_graphicview.h"
16
17 #include <stdio.h>
18 #include "rs_actioninterface.h"
19 #include "rs_block.h"
20 #include "rs_dialogfactory.h"
21 #include "drawing.h"
22 #include "rs_eventhandler.h"
23 #include "rs_grid.h"
24 #include "rs_insert.h"
25 #include "rs_layer.h"
26 #include "rs_line.h"
27 #include "rs_solid.h"
28 #include "rs_text.h"
29 #include "rs_units.h"
30 #include "paintintf.h"
31 #include "settings.h"
32
33 /**
34  * Constructor.
35  */
36 RS_GraphicView::RS_GraphicView(): background(), foreground(), previewMode(false),
37         previewOffset(Vector(0, 0)), snapperDraw(false)
38 {
39         drawingMode = RS2::ModeFull;
40         printing = false;
41         deleteMode = false;
42         factor = Vector(1.0, 1.0);
43         offsetX = 0;
44         offsetY = 0;
45         previousFactor = Vector(1.0, 1.0);
46         previousOffsetX = 0;
47         previousOffsetY = 0;
48         container = NULL;
49         eventHandler = new RS_EventHandler(this);
50         gridColor = Qt::gray;
51         metaGridColor = RS_Color(64, 64, 64);
52         grid = new RS_Grid(this);
53         updateEnabled = 0;
54         zoomFrozen = false;
55         //gridVisible = true;
56         draftMode = false;
57         painter = NULL;
58         //drawRecursion = 0;
59
60         borderLeft = 0;
61         borderTop = 0;
62         borderRight = 0;
63         borderBottom = 0;
64
65         relativeZero = Vector(false);
66         relativeZeroLocked = false;
67
68         mx = my = 0;
69
70         defaultSnapMode = RS2::SnapFree;
71         defaultSnapRes = RS2::RestrictNothing;
72
73         /*
74                 background = RS_Color(0,0,0);
75                 foreground = RS_Color(255,255,255);
76                 gridColor = RS_Color("gray");
77         metaGridColor = RS_Color("#404040");
78                 selectedColor = RS_Color("#a54747");
79                 highlightedColor = RS_Color("#739373");
80         */
81
82         settings.beginGroup("Appearance");
83         setBackground(QColor(settings.value("BackgroundColor", "#000000").toString()));
84         setGridColor(QColor(settings.value("GridColor", "#7F7F7F").toString()));
85         setMetaGridColor(QColor(settings.value("MetaGridColor", "#3F3F3F").toString()));
86         setSelectedColor(QColor(settings.value("SelectedColor", "#A54747").toString()));
87         setHighlightedColor(QColor(settings.value("HighlightedColor", "#739373").toString()));
88         settings.endGroup();
89
90         printPreview = false;
91
92         simulationSpeed = 100;
93         simulationSmooth = false;
94         simulationRapid = false;
95         simulationRunning = false;
96
97         //currentInsert = NULL;
98 }
99
100 /**
101  * Destructor.
102  */
103 RS_GraphicView::~RS_GraphicView()
104 {
105         //delete eventHandler;
106         if (painter != NULL)
107                 delete painter;
108
109         delete grid;
110 }
111
112 /**
113  * Must be called by any derrived class in the destructor.
114  */
115 void RS_GraphicView::cleanUp()
116 {
117         delete eventHandler;
118 }
119
120 /**
121  * @return Pointer to the graphic entity if the entity container
122  * connected to this view is a graphic and valid.
123  * NULL otherwise.
124  */
125 Drawing * RS_GraphicView::getGraphic()
126 {
127         if (container != NULL && container->rtti() == RS2::EntityGraphic)
128                 return (Drawing*)container;
129         else
130                 return NULL;
131 }
132
133 /**
134  * Sets the drawing mode.
135  */
136 void RS_GraphicView::setDrawingMode(RS2::DrawingMode m)
137 {
138         drawingMode = m;
139 }
140
141 /**
142  * @return Current drawing mode.
143  */
144 RS2::DrawingMode RS_GraphicView::getDrawingMode()
145 {
146         return drawingMode;
147 }
148
149 /**
150  * Activates or deactivates the delete mode.
151  */
152 void RS_GraphicView::setDeleteMode(bool m)
153 {
154         deleteMode = m;
155 }
156
157 /**
158  * @reval true Deleting instead of drawing.
159  *        false Normal drawing mode.
160  */
161 bool RS_GraphicView::getDeleteMode()
162 {
163         return deleteMode;
164 }
165
166 /** This virtual method must be overwritten and is then
167         called whenever the view changed */
168 void RS_GraphicView::adjustOffsetControls()
169 {
170 }
171
172 /** This virtual method must be overwritten and is then
173         called whenever the view changed */
174 void RS_GraphicView::adjustZoomControls()
175 {
176 }
177
178 /**
179  * Sets an external painter device.
180  */
181 //void RS_GraphicView::setPainter(RS_Painter * p)
182 void RS_GraphicView::setPainter(PaintInterface * p)
183 {
184         painter = p;
185 }
186
187 /**
188  * Sets the background color. Note that applying the background
189  * color for the widget is up to the implementing class.
190  */
191 void RS_GraphicView::setBackground(const RS_Color & bg)
192 {
193         background = bg;
194
195         // bright background:
196         if (bg.red() + bg.green() + bg.blue() > 380)
197 //              foreground = Qt::black;
198                 foreground = RS_Color(0, 0, 0);
199         else
200 //              foreground = Qt::white;
201                 foreground = RS_Color(255, 255, 255);
202 }
203
204 /**
205  * @return Current background color.
206  */
207 RS_Color RS_GraphicView::getBackground()
208 {
209         return background;
210 }
211
212 /**
213  * @return Current foreground color.
214  */
215 RS_Color RS_GraphicView::getForeground()
216 {
217         return foreground;
218 }
219
220 /**
221  * Sets the grid color.
222  */
223 void RS_GraphicView::setGridColor(const RS_Color & c)
224 {
225         gridColor = c;
226 }
227
228 /**
229  * Sets the meta grid color.
230  */
231 void RS_GraphicView::setMetaGridColor(const RS_Color & c)
232 {
233         metaGridColor = c;
234 }
235
236 /**
237  * Sets the selection color.
238  */
239 void RS_GraphicView::setSelectedColor(const RS_Color & c)
240 {
241         selectedColor = c;
242 }
243
244 /**
245  * Sets the highlight color.
246  */
247 void RS_GraphicView::setHighlightedColor(const RS_Color & c)
248 {
249         highlightedColor = c;
250 }
251
252 /**
253  * This virtual method can be overwritten to set the mouse
254  * cursor to the given type.
255  */
256 void RS_GraphicView::setMouseCursor(RS2::CursorType /*c*/)
257 {
258 }
259
260 RS_EntityContainer * RS_GraphicView::getContainer()
261 {
262         return container;
263 }
264
265 void RS_GraphicView::setFactor(double f)
266 {
267         setFactorX(f);
268         setFactorY(f);
269 }
270
271 Vector RS_GraphicView::getFactor()
272 {
273         return factor;
274 }
275
276 /**
277  * Sets the offset of the graphic.
278  */
279 void RS_GraphicView::setOffset(int ox, int oy)
280 {
281         setOffsetX(ox);
282         setOffsetY(oy);
283 }
284
285 void RS_GraphicView::setOffsetX(int ox)
286 {
287         offsetX = ox;
288 }
289
290 void RS_GraphicView::setOffsetY(int oy)
291 {
292         offsetY = oy;
293 }
294
295 int RS_GraphicView::getOffsetX()
296 {
297         return offsetX;
298 }
299
300 int RS_GraphicView::getOffsetY()
301 {
302         return offsetY;
303 }
304
305 /**
306  * Sets a fixed border in pixel around the graphic. This border
307  * specifies how far the user can scroll outside the graphic
308  * area.
309  */
310 void RS_GraphicView::setBorders(int left, int top, int right, int bottom)
311 {
312         borderLeft = left;
313         borderTop = top;
314         borderRight = right;
315         borderBottom = bottom;
316 }
317
318 int RS_GraphicView::getBorderLeft()
319 {
320         return borderLeft;
321 }
322
323 int RS_GraphicView::getBorderTop()
324 {
325         return borderTop;
326 }
327
328 int RS_GraphicView::getBorderRight()
329 {
330         return borderRight;
331 }
332
333 int RS_GraphicView::getBorderBottom()
334 {
335         return borderBottom;
336 }
337
338 void RS_GraphicView::disableUpdate()
339 {
340         updateEnabled--;
341 }
342
343 void RS_GraphicView::enableUpdate()
344 {
345         updateEnabled++;
346 }
347
348 bool RS_GraphicView::isUpdateEnabled()
349 {
350         return (updateEnabled == 0);
351 }
352
353 void RS_GraphicView::freezeZoom(bool freeze)
354 {
355         zoomFrozen = freeze;
356 }
357
358 bool RS_GraphicView::isZoomFrozen()
359 {
360         return zoomFrozen;
361 }
362
363 /**
364  * Sets the pointer to the graphic which contains the entities
365  * which are visualized by this widget.
366  */
367 void RS_GraphicView::setContainer(RS_EntityContainer * container)
368 {
369         this->container = container;
370         //adjustOffsetControls();
371 }
372
373 /**
374  * Sets the zoom factor in X for this visualization of the graphic.
375  */
376 void RS_GraphicView::setFactorX(double f)
377 {
378         if (!zoomFrozen)
379                 factor.x = fabs(f);
380 }
381
382 /**
383  * Sets the zoom factor in Y for this visualization of the graphic.
384  */
385 void RS_GraphicView::setFactorY(double f)
386 {
387         if (!zoomFrozen)
388                 factor.y = fabs(f);
389 }
390
391 /**
392  * @return true if the grid is switched on.
393  */
394 bool RS_GraphicView::isGridOn()
395 {
396         if (container != NULL)
397         {
398                 Drawing * g = container->getGraphic();
399
400                 if (g != NULL)
401                         return g->isGridOn();
402         }
403
404         return true;
405 }
406
407 /**
408  * Centers the drawing in x-direction.
409  */
410 void RS_GraphicView::centerOffsetX()
411 {
412         if (container != NULL && !zoomFrozen)
413                 offsetX = (int)(((getWidth() - borderLeft - borderRight)
414                         - (container->getSize().x * factor.x)) / 2.0
415                         - (container->getMin().x * factor.x)) + borderLeft;
416 }
417
418 /**
419  * Centers the drawing in y-direction.
420  */
421 void RS_GraphicView::centerOffsetY()
422 {
423         if (container != NULL && !zoomFrozen)
424                 offsetY = (int)((getHeight() - borderTop - borderBottom
425                         - (container->getSize().y * factor.y)) / 2.0
426                         - (container->getMin().y * factor.y)) + borderBottom;
427 }
428
429 /**
430  * Centers the given coordinate in the view in x-direction.
431  */
432 void RS_GraphicView::centerX(double v)
433 {
434         if (!zoomFrozen)
435                 offsetX = (int)((v * factor.x) - (double)(getWidth() - borderLeft - borderRight) / 2.0);
436 }
437
438 /**
439  * Centers the given coordinate in the view in y-direction.
440  */
441 void RS_GraphicView::centerY(double v)
442 {
443     if (!zoomFrozen)
444         offsetY = (int)((v * factor.y) - (double)(getHeight() - borderTop - borderBottom) / 2.0);
445 }
446
447 void RS_GraphicView::updateView()
448 {
449         static int running = 0;
450         running++;
451
452         if (running < 100)
453         {
454                 adjustZoomControls();
455                 adjustOffsetControls();
456         }
457
458         running--;
459
460         if (running == 0)
461                 redraw();
462 }
463
464 /**
465  * @return Current action or NULL.
466  */
467 RS_ActionInterface * RS_GraphicView::getDefaultAction()
468 {
469         if (eventHandler != NULL)
470                 return eventHandler->getDefaultAction();
471         else
472                 return NULL;
473 }
474
475 /**
476  * Sets the default action of the event handler.
477  */
478 void RS_GraphicView::setDefaultAction(RS_ActionInterface * action)
479 {
480     if (eventHandler != NULL)
481         eventHandler->setDefaultAction(action);
482 }
483
484 /**
485  * @return Current action or NULL.
486  */
487 RS_ActionInterface * RS_GraphicView::getCurrentAction()
488 {
489         if (eventHandler != NULL)
490                 return eventHandler->getCurrentAction();
491         else
492                 return NULL;
493 }
494
495 /**
496  * Sets the current action of the event handler.
497  */
498 void RS_GraphicView::setCurrentAction(RS_ActionInterface * action)
499 {
500         RS_DEBUG->print("RS_GraphicView::setCurrentAction");
501
502         if (eventHandler != NULL)
503                 eventHandler->setCurrentAction(action);
504
505         RS_DEBUG->print("RS_GraphicView::setCurrentAction: OK");
506 }
507
508 /**
509  * Kills all running selection actions. Called when a selection action
510  * is launched to reduce confusion.
511  */
512 void RS_GraphicView::killSelectActions()
513 {
514         if (eventHandler != NULL)
515                 eventHandler->killSelectActions();
516 }
517
518 /**
519  * Kills all running actions.
520  */
521 void RS_GraphicView::killAllActions()
522 {
523         if (eventHandler != NULL)
524                 eventHandler->killAllActions();
525 }
526
527 /**
528  * Go back in menu or current action.
529  */
530 void RS_GraphicView::back()
531 {
532         if (eventHandler != NULL && eventHandler->hasAction())
533                 eventHandler->back();
534         else
535                 if (RS_DIALOGFACTORY != NULL)
536                         RS_DIALOGFACTORY->requestPreviousMenu();
537 }
538
539 /**
540  * Go forward with the current action.
541  */
542 void RS_GraphicView::enter()
543 {
544         if (eventHandler != NULL && eventHandler->hasAction())
545                 eventHandler->enter();
546 }
547
548 /**
549  * Called by the actual GUI class which implements the RS_GraphicView
550  * interface to notify qcadlib about mouse events.
551  */
552 void RS_GraphicView::mousePressEvent(QMouseEvent * e)
553 {
554         if (eventHandler != NULL)
555                 eventHandler->mousePressEvent(e);
556 }
557
558 /**
559  * Called by the actual GUI class which implements the RS_GraphicView
560  * interface to notify qcadlib about mouse events.
561  */
562 void RS_GraphicView::mouseReleaseEvent(QMouseEvent * e)
563 {
564         RS_DEBUG->print("RS_GraphicView::mouseReleaseEvent");
565
566         if (eventHandler != NULL)
567         {
568                 if (e->button() != Qt::RightButton || eventHandler->hasAction())
569                 {
570                         eventHandler->mouseReleaseEvent(e);
571                         //e->accept();
572                 }
573                 else
574                 {
575                         back();
576                         e->accept();
577                 }
578         }
579
580         RS_DEBUG->print("RS_GraphicView::mouseReleaseEvent: OK");
581 }
582
583 /**
584  * Called by the actual GUI class which implements the RS_GraphicView
585  * interface to notify qcadlib about mouse events.
586  */
587 void RS_GraphicView::mouseMoveEvent(QMouseEvent * e)
588 {
589         RS_DEBUG->print("RS_GraphicView::mouseMoveEvent begin");
590
591         Drawing * graphic = NULL;
592
593         if (container->rtti() == RS2::EntityGraphic)
594                 graphic = (Drawing *)container;
595
596         RS_DEBUG->print("RS_GraphicView::mouseMoveEvent 001");
597
598         if (e != NULL)
599         {
600                 mx = e->x();
601                 my = e->y();
602         }
603
604         RS_DEBUG->print("RS_GraphicView::mouseMoveEvent 002");
605
606         if (eventHandler != NULL)
607                 eventHandler->mouseMoveEvent(e);
608
609         RS_DEBUG->print("RS_GraphicView::mouseMoveEvent 003");
610
611         if (eventHandler == NULL || !eventHandler->hasAction() && graphic != NULL)
612         {
613                 Vector mouse = toGraph(Vector(mx, my));
614                 Vector relMouse = mouse - getRelativeZero();
615
616                 if (RS_DIALOGFACTORY != NULL)
617                         RS_DIALOGFACTORY->updateCoordinateWidget(mouse, relMouse);
618         }
619
620         RS_DEBUG->print("RS_GraphicView::mouseMoveEvent end");
621 }
622
623 /**
624  * Called by the actual GUI class which implements the RS_GraphicView
625  * interface to notify qcadlib about mouse events.
626  */
627 void RS_GraphicView::mouseLeaveEvent()
628 {
629         if (eventHandler != NULL)
630                 eventHandler->mouseLeaveEvent();
631 }
632
633 /**
634  * Called by the actual GUI class which implements the RS_GraphicView
635  * interface to notify qcadlib about mouse events.
636  */
637 void RS_GraphicView::mouseEnterEvent()
638 {
639         if (eventHandler != NULL)
640                 eventHandler->mouseEnterEvent();
641 }
642
643 /**
644  * Called by the actual GUI class which implements the RS_GraphicView
645  * interface to notify qcadlib about key events.
646  */
647 void RS_GraphicView::keyPressEvent(QKeyEvent * e)
648 {
649         if (eventHandler != NULL)
650                 eventHandler->keyPressEvent(e);
651 }
652
653 /**
654  * Called by the actual GUI class which implements the RS_GraphicView
655  * interface to notify qcadlib about key events.
656  */
657 void RS_GraphicView::keyReleaseEvent(QKeyEvent * e)
658 {
659         if (eventHandler != NULL)
660                 eventHandler->keyReleaseEvent(e);
661 }
662
663 /**
664  * Called by the actual GUI class which implements a command line.
665  */
666 void RS_GraphicView::commandEvent(RS_CommandEvent * e)
667 {
668         if (eventHandler != NULL)
669                 eventHandler->commandEvent(e);
670 }
671
672 /**
673  * Enables coordinate input in the command line.
674  */
675 void RS_GraphicView::enableCoordinateInput()
676 {
677         if (eventHandler != NULL)
678                 eventHandler->enableCoordinateInput();
679 }
680
681 /**
682  * Disables coordinate input in the command line.
683  */
684 void RS_GraphicView::disableCoordinateInput()
685 {
686         if (eventHandler != NULL)
687                 eventHandler->disableCoordinateInput();
688 }
689
690 /**
691  * zooms in by factor f
692  */
693 void RS_GraphicView::zoomIn(double f, const Vector & center)
694 {
695         if (f < 1.0e-6)
696         {
697                 RS_DEBUG->print(RS_Debug::D_WARNING, "RS_GraphicView::zoomIn: invalid factor");
698                 return;
699         }
700
701         if (simulationRunning)
702                 return;
703
704         Vector c = center;
705         if (c.valid == false)
706                 c = toGraph(Vector(getWidth() / 2, getHeight() / 2));
707
708         zoomWindow(
709                 toGraph(Vector(0, 0)).scale(c, Vector(1.0 / f, 1.0 / f)),
710                 toGraph(Vector(getWidth(), getHeight())).scale(c, Vector(1.0 / f, 1.0 / f)));
711
712         //adjustOffsetControls();
713         //adjustZoomControls();
714         //updateGrid();
715         //redraw();
716 }
717
718 /**
719  * zooms in by factor f in x
720  */
721 void RS_GraphicView::zoomInX(double f)
722 {
723         if (simulationRunning)
724                 return;
725
726         factor.x *= f;
727         offsetX = (int)((offsetX - getWidth() / 2) * f) + getWidth() / 2;
728         adjustOffsetControls();
729         adjustZoomControls();
730         updateGrid();
731         redraw();
732 }
733
734 /**
735  * zooms in by factor f in y
736  */
737 void RS_GraphicView::zoomInY(double f)
738 {
739         if (simulationRunning)
740                 return;
741
742         factor.y *= f;
743         offsetY = (int)((offsetY - getHeight() / 2) * f)+getHeight() / 2;
744         adjustOffsetControls();
745         adjustZoomControls();
746         updateGrid();
747         redraw();
748 }
749
750 /**
751  * zooms out by factor f
752  */
753 void RS_GraphicView::zoomOut(double f, const Vector & center)
754 {
755         if (f < 1.0e-6)
756         {
757                 RS_DEBUG->print(RS_Debug::D_WARNING,
758                         "RS_GraphicView::zoomOut: invalid factor");
759                 return;
760         }
761
762         if (simulationRunning)
763                 return;
764
765         zoomIn(1/f, center);
766 }
767
768 /**
769  * zooms out by factor f in x
770  */
771 void RS_GraphicView::zoomOutX(double f)
772 {
773         if (f < 1.0e-6)
774         {
775                 RS_DEBUG->print(RS_Debug::D_WARNING,
776                         "RS_GraphicView::zoomOutX: invalid factor");
777                 return;
778         }
779
780         if (simulationRunning)
781                 return;
782
783         factor.x /= f;
784         offsetX = (int)(offsetX / f);
785         adjustOffsetControls();
786         adjustZoomControls();
787         updateGrid();
788         redraw();
789 }
790
791 /**
792  * zooms out by factor f y
793  */
794 void RS_GraphicView::zoomOutY(double f)
795 {
796         if (f < 1.0e-6)
797         {
798                 RS_DEBUG->print(RS_Debug::D_WARNING,
799                         "RS_GraphicView::zoomOutY: invalid factor");
800                 return;
801         }
802
803         if (simulationRunning)
804                 return;
805
806         factor.y /= f;
807         offsetY = (int)(offsetY / f);
808         adjustOffsetControls();
809         adjustZoomControls();
810         updateGrid();
811         redraw();
812 }
813
814 /**
815  * performs autozoom
816  *
817  * @param axis include axis in zoom
818  * @param keepAspectRatio true: keep aspect ratio 1:1
819  *                        false: factors in x and y are stretched to the max
820  */
821 void RS_GraphicView::zoomAuto(bool axis, bool keepAspectRatio)
822 {
823         RS_DEBUG->print("RS_GraphicView::zoomAuto");
824
825         if (simulationRunning)
826                 return;
827
828         saveView();
829
830         if (container != NULL)
831         {
832                 container->calculateBorders();
833
834                 double sx, sy;
835                 if (axis)
836                 {
837                         sx = std::max(container->getMax().x, 0.0) - std::min(container->getMin().x, 0.0);
838                         sy = std::max(container->getMax().y, 0.0) - std::min(container->getMin().y, 0.0);
839                 }
840                 else
841                 {
842                         sx = container->getSize().x;
843                         sy = container->getSize().y;
844                 }
845
846                 double fx, fy;
847
848                 if (sx > RS_TOLERANCE)
849                         fx = (getWidth() - borderLeft - borderRight) / sx;
850                 else
851                         fx = 1.0;
852
853                 if (sy > RS_TOLERANCE)
854                         fy = (getHeight() - borderTop - borderBottom) / sy;
855                 else
856                         fy = 1.0;
857
858                 RS_DEBUG->print("f: %f/%f", fx, fy);
859
860                 if (keepAspectRatio)
861                         fx = fy = std::min(fx, fy);
862
863                 RS_DEBUG->print("f: %f/%f", fx, fy);
864
865                 if (fx < RS_TOLERANCE)
866                         fx = fy = 1.0;
867
868                 setFactorX(fx);
869                 setFactorY(fy);
870
871                 RS_DEBUG->print("f: %f/%f", fx, fy);
872
873                 RS_DEBUG->print("adjustOffsetControls");
874                 adjustOffsetControls();
875                 RS_DEBUG->print("adjustZoomControls");
876                 adjustZoomControls();
877                 RS_DEBUG->print("centerOffsetX");
878                 centerOffsetX();
879                 RS_DEBUG->print("centerOffsetY");
880                 centerOffsetY();
881                 RS_DEBUG->print("updateGrid");
882                 updateGrid();
883                 redraw();
884         }
885
886         RS_DEBUG->print("RS_GraphicView::zoomAuto OK");
887 }
888
889 /**
890  * Shows previous view.
891  */
892 void RS_GraphicView::zoomPrevious()
893 {
894         RS_DEBUG->print("RS_GraphicView::zoomPrevious");
895
896         if (simulationRunning)
897                 return;
898
899         if (container != NULL)
900                 restoreView();
901 }
902
903 /**
904  * Saves the current view as previous view to which we can
905  * switch back later with @see restoreView().
906  */
907 void RS_GraphicView::saveView()
908 {
909         previousOffsetX = offsetX;
910         previousOffsetY = offsetY;
911         previousFactor = factor;
912 }
913
914 /**
915  * Restores the view previously saved with
916  * @see saveView().
917  */
918 void RS_GraphicView::restoreView()
919 {
920         int pox = previousOffsetX;
921         int poy = previousOffsetY;
922         Vector pf = previousFactor;
923
924         saveView();
925
926         offsetX = pox;
927         offsetY = poy;
928         factor = pf;
929
930         adjustOffsetControls();
931         adjustZoomControls();
932         updateGrid();
933         redraw();
934 }
935
936 /**
937  * performs autozoom in y only
938  *
939  * @param axis include axis in zoom
940  */
941 void RS_GraphicView::zoomAutoY(bool axis)
942 {
943         if (simulationRunning)
944                 return;
945
946         if (container != NULL)
947         {
948                 double visibleHeight = 0.0;
949                 double minY = RS_MAXDOUBLE;
950                 double maxY = RS_MINDOUBLE;
951                 bool noChange = false;
952
953                 for(RS_Entity * e=container->firstEntity(RS2::ResolveNone);
954                         e!=NULL; e = container->nextEntity(RS2::ResolveNone))
955                 {
956                         if (e->rtti() == RS2::EntityLine)
957                         {
958                                 RS_Line * l = (RS_Line *)e;
959                                 double x1, x2;
960                                 x1 = toGuiX(l->getStartpoint().x);
961                                 x2 = toGuiX(l->getEndpoint().x);
962
963                                 if (x1 > 0.0 && x1 < (double)getWidth() || x2 > 0.0 && x2 < (double)getWidth())
964                                 {
965                                         minY = std::min(minY, l->getStartpoint().y);
966                                         minY = std::min(minY, l->getEndpoint().y);
967                                         maxY = std::max(maxY, l->getStartpoint().y);
968                                         maxY = std::max(maxY, l->getEndpoint().y);
969                                 }
970                         }
971                 }
972
973                 if (axis)
974                         visibleHeight = std::max(maxY, 0.0) - std::min(minY, 0.0);
975                 else
976                         visibleHeight = maxY - minY;
977
978                 if (visibleHeight < 1.0)
979                         noChange = true;
980
981                 double fy = 1.0;
982
983                 if (visibleHeight > 1.0e-6)
984                 {
985                         fy = (getHeight() - borderTop - borderBottom) / visibleHeight;
986
987                         if (factor.y < 0.000001)
988                                 noChange = true;
989                 }
990
991                 if (noChange == false)
992                 {
993                         setFactorY(fy);
994                         //centerOffsetY();
995                         offsetY = (int)((getHeight() - borderTop - borderBottom - (visibleHeight * factor.y)) / 2.0
996                                 - (minY * factor.y)) + borderBottom;
997                         adjustOffsetControls();
998                         adjustZoomControls();
999                         updateGrid();
1000                 }
1001
1002                 RS_DEBUG->print("Auto zoom y ok");
1003         }
1004 }
1005
1006 /**
1007  * Zooms the area given by v1 and v2.
1008  *
1009  * @param keepAspectRatio true: keeps the aspect ratio 1:1
1010  *                        false: zooms exactly the selected range to the
1011  *                               current graphic view
1012  */
1013 void RS_GraphicView::zoomWindow(Vector v1, Vector v2, bool keepAspectRatio)
1014 {
1015         if (simulationRunning)
1016                 return;
1017
1018         saveView();
1019
1020         double zoomX = 480.0;    // Zoom for X-Axis
1021         double zoomY = 640.0;    // Zoom for Y-Axis   (Set smaller one)
1022         double dum;            // Dummy for switching values
1023         int zoomBorder = 0;
1024
1025         // Switch left/right and top/bottom is necessary:
1026         if (v1.x > v2.x)
1027         {
1028                 dum = v1.x;
1029                 v1.x = v2.x;
1030                 v2.x = dum;
1031         }
1032
1033         if (v1.y > v2.y)
1034         {
1035                 dum = v1.y;
1036                 v1.y = v2.y;
1037                 v2.y = dum;
1038         }
1039
1040         // Get zoom in X and zoom in Y:
1041         if (v2.x - v1.x > 1.0e-6)
1042                 zoomX = getWidth() / (v2.x - v1.x);
1043
1044         if (v2.y - v1.y > 1.0e-6)
1045                 zoomY = getHeight() / (v2.y - v1.y);
1046
1047         // Take smaller zoom:
1048         if (keepAspectRatio)
1049         {
1050                 if (zoomX < zoomY)
1051                 {
1052                         if (getWidth() != 0)
1053                         {
1054                                 zoomX = zoomY = ((double)(getWidth() - 2 * zoomBorder)) /
1055                                                                 (double)getWidth() * zoomX;
1056                         }
1057                 }
1058                 else
1059                 {
1060                         if (getHeight() != 0)
1061                         {
1062                                 zoomX = zoomY = ((double)(getHeight() - 2 * zoomBorder)) /
1063                                                                 (double)getHeight() * zoomY;
1064                         }
1065                 }
1066         }
1067
1068         if (zoomX < 0.0)
1069                 zoomX *= -1;
1070
1071         if (zoomY < 0.0)
1072                 zoomY *= -1;
1073
1074         // Borders in pixel after zoom
1075         int pixLeft   = (int)(v1.x * zoomX);
1076         int pixTop    = (int)(v2.y * zoomY);
1077         int pixRight  = (int)(v2.x * zoomX);
1078         int pixBottom = (int)(v1.y * zoomY);
1079
1080         // Set new offset for zero point:
1081         offsetX = - pixLeft + (getWidth() - pixRight + pixLeft) / 2;
1082         offsetY = - pixTop + (getHeight() - pixBottom + pixTop) / 2;
1083         factor.x = zoomX;
1084         factor.y = zoomY;
1085
1086         adjustOffsetControls();
1087         adjustZoomControls();
1088         updateGrid();
1089         redraw();
1090 }
1091
1092 /**
1093  * Centers the point v1.
1094  */
1095 void RS_GraphicView::zoomPan(int dx, int dy)
1096 {
1097         //offsetX+=(int)toGuiDX(v1.x);
1098         //offsetY+=(int)toGuiDY(v1.y);
1099         if (simulationRunning)
1100                 return;
1101
1102         offsetX += dx;
1103         offsetY -= dy;
1104
1105         disableUpdate();
1106         adjustOffsetControls();
1107         //adjustZoomControls();
1108         updateGrid();
1109         enableUpdate();
1110         redraw();
1111 }
1112
1113 /**
1114  * Scrolls in the given direction.
1115  */
1116 void RS_GraphicView::zoomScroll(RS2::Direction direction)
1117 {
1118         if (simulationRunning)
1119                 return;
1120
1121         switch (direction)
1122         {
1123         case RS2::Up:
1124                 offsetY -= 50;
1125                 break;
1126         case RS2::Down:
1127                 offsetY += 50;
1128                 break;
1129         case RS2::Right:
1130                 offsetX += 50;
1131                 break;
1132         case RS2::Left:
1133                 offsetX -= 50;
1134                 break;
1135         }
1136
1137         adjustOffsetControls();
1138         adjustZoomControls();
1139         updateGrid();
1140         redraw();
1141 }
1142
1143 /**
1144  * Zooms to page extends.
1145  */
1146 void RS_GraphicView::zoomPage()
1147 {
1148         RS_DEBUG->print("RS_GraphicView::zoomPage");
1149
1150         if (container == NULL)
1151                 return;
1152
1153         if (simulationRunning)
1154                 return;
1155
1156         Drawing * graphic = container->getGraphic();
1157
1158         if (graphic == NULL)
1159                 return;
1160
1161         Vector s = graphic->getPaperSize();
1162         Vector pinsbase = graphic->getPaperInsertionBase();
1163
1164         double fx, fy;
1165
1166         if (s.x > RS_TOLERANCE)
1167                 fx = (getWidth() - borderLeft - borderRight) / s.x;
1168         else
1169                 fx = 1.0;
1170
1171         if (s.y > RS_TOLERANCE)
1172                 fy = (getHeight() - borderTop - borderBottom) / s.y;
1173         else
1174                 fy = 1.0;
1175
1176         RS_DEBUG->print("f: %f/%f", fx, fy);
1177
1178         fx = fy = std::min(fx, fy);
1179
1180         RS_DEBUG->print("f: %f/%f", fx, fy);
1181
1182         if (fx < RS_TOLERANCE)
1183                 fx = fy = 1.0;
1184
1185         setFactorX(fx);
1186         setFactorY(fy);
1187
1188         RS_DEBUG->print("f: %f/%f", fx, fy);
1189
1190         centerOffsetX();
1191         centerOffsetY();
1192         adjustOffsetControls();
1193         adjustZoomControls();
1194         updateGrid();
1195         redraw();
1196 }
1197
1198 /**
1199  * Draws the entities within the given range.
1200  */
1201 void RS_GraphicView::drawWindow(Vector v1, Vector v2)
1202 {
1203         RS_DEBUG->print("RS_GraphicView::drawWindow() begin");
1204
1205         if (simulationRunning)
1206                 return;
1207
1208         if (container != NULL)
1209         {
1210                 for (RS_Entity * se=container->firstEntity(RS2::ResolveNone);
1211                         se!=NULL; se = container->nextEntity(RS2::ResolveNone))
1212                 {
1213                         if (se->isInWindow(v1, v2))
1214                                 drawEntity(se);
1215                 }
1216         }
1217
1218         RS_DEBUG->print("RS_GraphicView::drawWindow() end");
1219 }
1220
1221 /**
1222  * Draws the entities. If painter is NULL a new painter will
1223  * be created and destroyed.
1224  */
1225 void RS_GraphicView::drawIt()
1226 {
1227         if (!isUpdateEnabled())
1228 //{
1229 //printf("RS_GraphicView::drawIt(): isUpdateEnabled() == false!\n");
1230                 return;
1231 //}
1232
1233         if (simulationRunning)
1234 //{
1235 //printf("RS_GraphicView::drawIt(): simulationRunning == true!\n");
1236                 return;
1237 //}
1238
1239 //      bool painterCreated = false;
1240
1241         settings.beginGroup("Appearance");
1242         draftMode = settings.value("DraftMode", false).toBool();
1243         settings.endGroup();
1244
1245         //RS_DEBUG->print("RS_GraphicView::drawIt() begin");
1246         //RS_DEBUG->print("  factors: %f/%f", factor.x, factor.y);
1247         //RS_DEBUG->timestamp();
1248
1249         if (painter == NULL)
1250         {
1251 printf("RS_GraphicView::drawIt(): painter == NULL!\n");
1252                 return;
1253 //              createPainter();
1254 //              painterCreated = true;
1255         }
1256         else
1257                 painter->erase();
1258
1259         // drawing paper border:
1260         if (isPrintPreview())
1261                 drawPaper();
1262         // drawing meta grid:
1263         else
1264                 drawMetaGrid();
1265
1266         //if (draftMode) {
1267         //    painter->setPen(RS_Pen(foreground, RS2::Width00, RS2::SolidLine));
1268         //}
1269
1270         // drawing entities:
1271 //#warning "!!! This looks like a bug, no match for 'drawEntity(RS_Entity *, bool) !!!"
1272 // and indeed it *is* a bug... true is converted to 1.0 here. Dumb, dumb, dumb.
1273         drawEntity(container, true);
1274
1275         //RS_DEBUG->timestamp();
1276         //RS_DEBUG->print(" draw zero..");
1277
1278         // drawing zero points:
1279         if (!isPrintPreview())
1280         {
1281                 drawAbsoluteZero();
1282                 drawRelativeZero();
1283         }
1284
1285         //RS_DEBUG->timestamp();
1286         //RS_DEBUG->print(" draw grid..");
1287
1288         // drawing grid:
1289         if (!isPrintPreview())
1290                 drawGrid();
1291
1292         //RS_DEBUG->timestamp();
1293         //RS_DEBUG->print("RS_GraphicView::drawIt() end");
1294 //      if (painterCreated == true)
1295 //              destroyPainter();
1296 }
1297
1298 /**
1299  * Sets the pen of the painter object to the suitable pen for the given
1300  * entity.
1301  */
1302 void RS_GraphicView::setPenForEntity(RS_Entity * e)
1303 {
1304         if (drawingMode == RS2::ModePreview /*|| draftMode==true*/)
1305                 return;
1306
1307         // set color of entity
1308         if (painter != NULL && !painter->isPreviewMode())
1309         {
1310                 // Getting pen from entity (or layer)
1311                 RS_Pen pen = e->getPen(true);
1312
1313                 int w = pen.getWidth();
1314
1315                 if (w < 0)
1316                         w = 0;
1317
1318                 // scale pen width:
1319                 if (!draftMode)
1320                 {
1321                         double uf = 1.0;  // unit factor
1322                         double wf = 1.0;  // width factor
1323                         Drawing * graphic = container->getGraphic();
1324
1325                         if (graphic != NULL)
1326                         {
1327                                 uf = RS_Units::convert(1.0, RS2::Millimeter, graphic->getUnit());
1328
1329                                 if ((isPrinting() || isPrintPreview()) && graphic->getPaperScale() > 1.0e-6)
1330                                         wf = 1.0 / graphic->getPaperScale();
1331                         }
1332
1333                         pen.setScreenWidth(toGuiDX(w / 100.0 * uf * wf));
1334                 }
1335                 else
1336                 {
1337                         //pen.setWidth(RS2::Width00);
1338                         pen.setScreenWidth(0);
1339                 }
1340
1341                 // prevent drawing with 1-width which is slow:
1342                 if (RS_Math::round(pen.getScreenWidth()) == 1)
1343                         pen.setScreenWidth(0.0);
1344
1345                 // prevent background color on background drawing:
1346                 if (pen.getColor().stripFlags() == background.stripFlags())
1347                         pen.setColor(foreground);
1348
1349                 // this entity is selected:
1350                 if (e->isSelected())
1351                 {
1352                         pen.setLineType(RS2::DotLine);
1353                         //pen.setColor(RS_Color(0xa5,0x47,0x47));
1354                         pen.setColor(selectedColor);
1355                 }
1356
1357                 // this entity is highlighted:
1358                 if (e->isHighlighted())
1359                 {
1360                         //pen.setColor(RS_Color(0x73, 0x93, 0x73));
1361                         pen.setColor(highlightedColor);
1362                 }
1363
1364                 // deleting not drawing:
1365                 if (getDeleteMode())
1366                         pen.setColor(background);
1367
1368                 painter->setPen(pen);
1369         }
1370 }
1371
1372 /**
1373  * Draws an entity. Might be recusively called e.g. for polylines.
1374  * If the class wide painter is NULL a new painter will be created
1375  * and destroyed afterwards.
1376  *
1377  * @param patternOffset Offset of line pattern (used for connected
1378  *        lines e.g. in splines).
1379  * @param db Double buffering on (recommended) / off
1380  */
1381 void RS_GraphicView::drawEntity(RS_Entity * e, double patternOffset, bool db)
1382 {
1383         //RS_DEBUG->print("RS_GraphicView::drawEntity() begin");
1384
1385         // update is diabled:
1386         if (!isUpdateEnabled())
1387                 return;
1388
1389         // given entity is NULL:
1390         if (e == NULL)
1391                 return;
1392
1393         // entity is not visible:
1394         if (!e->isVisible())
1395                 return;
1396
1397         // test if the entity is in the viewport
1398         if (!e->isContainer() && !isPrinting()
1399                 && (painter == NULL || !painter->isPreviewMode())
1400                 && (toGuiX(e->getMax().x) < 0 || toGuiX(e->getMin().x) > getWidth()
1401                 || toGuiY(e->getMin().y) < 0 || toGuiY(e->getMax().y) > getHeight()))
1402 //{
1403 //printf("RS_GraphicView::drawEntity(): Bailing out of big test!!!\n");
1404                 return;
1405 //}
1406
1407         //drawRecursion++;
1408         //RS_DEBUG->print("recursion 1: %d", drawRecursion);
1409
1410         // set pen (color):
1411         setPenForEntity(e);
1412
1413         //RS_DEBUG->print("draw plain");
1414         if (draftMode)
1415         {
1416                 // large texts as rectangles:
1417                 if (e->rtti() == RS2::EntityText)
1418                 {
1419                         if (toGuiDX(((RS_Text *)e)->getHeight()) < 4 || e->countDeep() > 100)
1420                                 painter->drawRect(toGui(e->getMin()), toGui(e->getMax()));
1421                         else
1422                                 drawEntityPlain(e, patternOffset);
1423                 }
1424                 // all images as rectangles:
1425                 else if (e->rtti() == RS2::EntityImage)
1426                         painter->drawRect(toGui(e->getMin()), toGui(e->getMax()));
1427                 // hide hatches:
1428                 else if (e->rtti() == RS2::EntityHatch)
1429                 {
1430                         // nothing
1431                 }
1432                 else
1433                         drawEntityPlain(e, patternOffset);
1434         }
1435         else
1436                 drawEntityPlain(e, patternOffset);
1437
1438         // draw reference points:
1439         if (e->isSelected())
1440         {
1441                 if (!e->isParentSelected())
1442                 {
1443                         VectorSolutions s = e->getRefPoints();
1444
1445                         for(int i=0; i<s.getNumber(); ++i)
1446                         {
1447                                 int sz = -1;
1448                                 RS_Color col = RS_Color(0, 0, 255);
1449
1450                                 if (e->rtti() == RS2::EntityPolyline)
1451                                 {
1452                                         if (i == 0 || i == s.getNumber() - 1)
1453                                         {
1454                                                 if (i == 0)
1455                                                 {
1456                                                         sz = 4;
1457 //                                                      col = QColor(0, 64, 255);
1458                                                         col = RS_Color(0, 64, 255);
1459                                                 }
1460                                                 else
1461                                                 {
1462                                                         sz = 3;
1463 //                                                      col = QColor(0, 0, 128);
1464                                                         col = RS_Color(0, 0, 128);
1465                                                 }
1466                                         }
1467                                 }
1468
1469                                 if (getDeleteMode())
1470                                         painter->drawHandle(toGui(s.get(i)), background, sz);
1471                                 else
1472                                         painter->drawHandle(toGui(s.get(i)), col, sz);
1473                         }
1474                 }
1475         }
1476
1477         //RS_DEBUG->print("draw plain OK");
1478         //RS_DEBUG->print("RS_GraphicView::drawEntity() end");
1479 }
1480
1481 /**
1482  * Deletes an entity with the background color.
1483  * Might be recusively called e.g. for polylines.
1484  */
1485 void RS_GraphicView::deleteEntity(RS_Entity * e)
1486 {
1487         setDeleteMode(true);
1488         drawEntity(e);
1489         setDeleteMode(false);
1490 }
1491
1492 /**
1493  * Draws an entity.
1494  * The painter must be initialized and all the attributes (pen) must be set.
1495  */
1496 void RS_GraphicView::drawEntityPlain(RS_Entity * e, double patternOffset)
1497 {
1498         if (e == NULL)
1499 //{
1500 //printf("RS_GraphicView::drawEntityPlain(): Entity passed in is NULL!\n");
1501                 return;
1502 //}
1503
1504 //printf("RS_GraphicView::drawEntityPlain(): Passing in painter=%08X, view=%08X\n", painter, this);
1505         e->draw(painter, this, patternOffset);
1506 }
1507
1508 /**
1509  * Simulates this drawing in slow motion.
1510  */
1511 void RS_GraphicView::simulateIt()
1512 {
1513         if (simulationRunning)
1514                 return;
1515
1516         simulationRunning = true;
1517         simulationLast = Vector(0.0, 0.0);
1518
1519         destroyPainter();
1520
1521         createDirectPainter();
1522         painter->erase();
1523
1524         // drawing paper border:
1525         if (isPrintPreview())
1526                 drawPaper();
1527
1528         // drawing meta grid:
1529         if (!isPrintPreview())
1530                 drawMetaGrid();
1531
1532         // drawing grid:
1533         if (!isPrintPreview())
1534                 drawGrid();
1535
1536         //if (draftMode) {
1537         //painter->setPen(RS_Pen(foreground,
1538         //      RS2::Width00, RS2::SolidLine));
1539         //}
1540
1541         // drawing entities:
1542         RS_Pen pen(foreground, RS2::Width00, RS2::SolidLine);
1543         simulateEntity(container, pen);
1544
1545         //RS_DEBUG->timestamp();
1546         //RS_DEBUG->print(" draw zero..");
1547
1548         // drawing zero points:
1549         if (!isPrintPreview())
1550         {
1551                 drawAbsoluteZero();
1552                 drawRelativeZero();
1553         }
1554
1555         //RS_DEBUG->timestamp();
1556         //RS_DEBUG->print(" draw grid..");
1557
1558         //RS_DEBUG->timestamp();
1559         //RS_DEBUG->print("RS_GraphicView::drawIt() end");
1560         //if (painterCreated==true) {
1561         destroyPainter();
1562         //}
1563         simulationRunning = false;
1564 }
1565
1566 /**
1567  * Simulates the given entity.
1568  *
1569  * @param smooth If true, the entity will be drawn slowly (pixel by pixel).
1570  */
1571 void RS_GraphicView::simulateEntity(RS_Entity * e, const RS_Pen & pen)
1572 {
1573         if (painter == NULL || e == NULL)
1574                 return;
1575
1576         if (e->isContainer())
1577         {
1578                 RS_EntityContainer * ec = (RS_EntityContainer *)e;
1579
1580                 for(RS_Entity* en=ec->firstEntity(RS2::ResolveNone);
1581                                 en!=NULL; en = ec->nextEntity(RS2::ResolveNone))
1582                 {
1583                         if (en->isVisible() && en->isUndone() == false)
1584                         {
1585                                 // draw rapid move:
1586                                 if (en->isAtomic() && simulationRapid)
1587                                 {
1588                                         Vector sp = ((RS_AtomicEntity *)en)->getStartpoint();
1589
1590                                         if (sp.distanceTo(simulationLast) > 1.0e-4)
1591                                         {
1592                                                 createDirectPainter();
1593                                                 RS_Pen rpen(RS_Color(0, 0, 255), RS2::Width00, RS2::SolidLine);
1594                                                 //painter->setPen(pen);
1595                                                 RS_Line rapidLine(NULL, RS_LineData(simulationLast, sp));
1596                                                 simulateEntity(&rapidLine, rpen);
1597                                         }
1598                                 }
1599
1600                                 if (en->isHighlighted())
1601                                 {
1602                                         RS_Pen hpen(highlightedColor, RS2::Width00, RS2::SolidLine);
1603                                         simulateEntity(en, hpen);
1604                                 }
1605                                 else
1606                                         simulateEntity(en, pen);
1607
1608                                 if (en->isAtomic())
1609                                         simulationLast = ((RS_AtomicEntity *)en)->getEndpoint();
1610
1611                                 if (!simulationSmooth)
1612                                         simulationDelay(true);
1613                         }
1614                 }
1615         }
1616         else
1617         {
1618                 if (simulationSmooth)
1619                 {
1620                         switch (e->rtti())
1621                         {
1622                         case RS2::EntityLine:
1623                         {
1624                                 RS_Line * line = (RS_Line *)e;
1625                                 drawLineSmooth(toGui(line->getStartpoint()), toGui(line->getEndpoint()), pen);
1626                                         //simulationSpeed);
1627                         }
1628                                 break;
1629
1630                         case RS2::EntityArc:
1631                         {
1632                                 RS_Arc * arc = (RS_Arc *)e;
1633                                 drawArcSmooth(toGui(arc->getCenter()), toGuiDX(arc->getRadius()),
1634                                         arc->getAngle1(), arc->getAngle2(), arc->isReversed(), pen);
1635                         }
1636                                 break;
1637
1638                         case RS2::EntityCircle:
1639                         {
1640                                 RS_Circle * circle = (RS_Circle *)e;
1641                                 drawArcSmooth(toGui(circle->getCenter()), toGuiDX(circle->getRadius()),
1642                                         0.0, 2.0 * M_PI, false, pen);
1643                         }
1644                                 break;
1645
1646                         default:
1647                                 break;
1648                         }
1649                 }
1650                 else
1651                 {
1652                         createDirectPainter();
1653                         //RS_Pen pen(foreground, RS2::Width00, RS2::SolidLine);
1654                         painter->setPen(pen);
1655                         drawEntityPlain(e);
1656                 }
1657         }
1658 }
1659
1660 /**
1661  * Delay for slow motion simulation.
1662  *
1663  * @param step true: stepping mode (entity by entity simulation). adds a delay.
1664  */
1665 void RS_GraphicView::simulationDelay(bool step)
1666 {
1667         int delay;
1668         settings.beginGroup("CAM");
1669         double fact = settings.value("SimulationFactor", 12000.0).toDouble();
1670         settings.endGroup();
1671
1672         // simulationSpeed: 0..100
1673
1674 #ifdef __APPLE__
1675         delay = (int)(((1.0 / (simulationSpeed + 1.0)) * fact) - (fact / 100.0));
1676         if (step)
1677                 delay *= 16;
1678
1679         //usleep(delay);
1680         static int call = 0;
1681
1682         if (call >= (fact - delay) / 1000)
1683         {
1684                 call = 0;
1685                 for(int i=0; i<delay; ++i)
1686                         RS_APP->processEvents(10);
1687         }
1688         else
1689                 call++;
1690 #else
1691         delay = (int)(((1.0 / (simulationSpeed + 1.0)) * fact) - (fact / 100.0));
1692
1693         if (step)
1694         {
1695                 delay *= 16;
1696         }
1697
1698         for(int i=0; i<delay; ++i)
1699         {
1700 #warning "Qt3->4 conversion: commented out problem line... !!! FIX !!!"
1701 //        RS_APP->processEvents(10);
1702         }
1703 #endif
1704 }
1705
1706 /**
1707  * Draws a line slowly from (x1, y1) to (x2, y2). This is used for simulation only.
1708  */
1709 void RS_GraphicView::drawLineSmooth(const Vector & p1, const Vector & p2, const RS_Pen & pen)
1710 {
1711         double alpha = p1.angleTo(p2);
1712         double xStep, yStep;
1713         bool  xIsOne;
1714
1715         if (RS_Math::cmpDouble(alpha, 0.0) || RS_Math::cmpDouble(alpha, 2 * M_PI))
1716         {
1717                 xStep = 1.0;
1718                 yStep = 0.0;
1719                 xIsOne = true;
1720         }
1721         else if (RS_Math::cmpDouble(alpha, M_PI / 2.0))
1722         {
1723                 xStep = 0.0;
1724                 yStep = 1.0;
1725                 xIsOne = false;
1726         }
1727         else if (RS_Math::cmpDouble(alpha, M_PI))
1728         {
1729                 xStep = -1.0;
1730                 yStep = 0.0;
1731                 xIsOne = true;
1732         }
1733         else if (RS_Math::cmpDouble(alpha, M_PI / 2.0 * 3.0))
1734         {
1735                 xStep = 0.0;
1736                 yStep = -1.0;
1737                 xIsOne = false;
1738         }
1739         else if (fabs(p2.x - p1.x) > fabs(p2.y - p1.y))
1740         {
1741                 if (p2.x > p1.x)
1742                         xStep = 1.0;
1743                 else
1744                         xStep = -1.0;
1745
1746                 yStep = tan(alpha) * xStep;
1747                 xIsOne = true;
1748         }
1749         else
1750         {
1751                 if (p2.y > p1.y)
1752                         yStep = 1.0;
1753                 else
1754                         yStep = -1.0;
1755
1756                 xStep = yStep / tan(alpha);
1757                 xIsOne = false;
1758         }
1759
1760         double lx = p1.x;
1761         double ly = p1.y;
1762         //RS_Pen pen(foreground, RS2::Width00, RS2::SolidLine);
1763
1764         do
1765         {
1766                 if (lx >= 0.0 && lx <= (double)getWidth() && ly >= 0.0 && ly <= (double)getHeight())
1767                 {
1768                         //if (painter==NULL) {
1769                         createDirectPainter();
1770                         //}
1771                         painter->setPen(pen);
1772                         painter->drawGridPoint(Vector(lx, ly));
1773
1774                         simulationDelay();
1775                 }
1776
1777                 lx += xStep;
1778                 ly += yStep;
1779
1780         }
1781         while ((xIsOne && ((lx >= p1.x && lx <= p2.x) || (lx >= p2.x && lx <= p1.x)))
1782                 || (!xIsOne && ((ly >= p1.y && ly <= p2.y) || (ly >= p2.y && ly <= p1.y))));
1783 }
1784
1785 void RS_GraphicView::drawArcSmooth(const Vector & center, double radius, double a1, double a2, bool rev,
1786         const RS_Pen & pen)
1787 {
1788         //int icx = graphic->realToScreenX(cx);
1789         //int icy = graphic->realToScreenY(cy);
1790         //RS_Pen pen(foreground, RS2::Width00, RS2::SolidLine);
1791
1792         if (radius <= 1.4)
1793         {
1794                 createDirectPainter();
1795                 painter->setPen(pen);
1796                 painter->drawGridPoint(center);
1797         }
1798         else
1799         {
1800                 int ix1 = RS_Math::round(center.x + cos(a1) * radius);
1801                 int iy1 = RS_Math::round(center.y - sin(a1) * radius);
1802                 int ix2 = RS_Math::round(center.x + cos(a2) * radius);
1803                 int iy2 = RS_Math::round(center.y - sin(a2) * radius);
1804                 int k2x = 0;            // Next point on circle
1805                 int k2y = 0;            //
1806                 int k1x = ix1;          // Prev point on circle
1807                 int k1y = iy1;          //
1808                 double aStep;          // Angle Step (rad)
1809                 double a;              // Actual Angle (rad)
1810                 double a2cp = a2;      // Copy of a2
1811
1812                 if (1.0 / (radius * factor.x) <= 1.0)
1813                         aStep = asin(1.0 / (radius * factor.x));
1814                 else
1815                         aStep = 0.01;
1816
1817                 if (aStep < 0.01)
1818                         aStep = 0.01;
1819
1820                 if (!rev)
1821                 {
1822                         // Arc Counterclockwise:
1823                         //
1824                         if (a1 > a2cp - 0.01)
1825                                 a2cp += 2 * M_PI;
1826
1827                         //if (painter==NULL) {
1828                         //painter->setPen(pen);
1829                         //createDirectPainter();
1830                         //}
1831                         //painter->moveTo(ix1, iy1);
1832
1833                         for(a=a1+aStep; a<=a2cp; a+=aStep)
1834                         {
1835                                 k2x = RS_Math::round(center.x+cos(a)*radius);
1836                                 k2y = RS_Math::round(center.y-sin(a)*radius);
1837                                 //if(graphic->isPointOnScreen(k2x, k2y) ||
1838                                 //   graphic->isPointOnScreen(k1x, k1y)    ) {
1839                                 createDirectPainter();
1840                                 painter->setPen(pen);
1841                                 if ((k2x >= 0 && k2x <= painter->getWidth()
1842                                         && k2y >= 0 && k2y <= painter->getHeight())
1843                                         || (k1x >= 0 && k1x <= painter->getWidth()
1844                                         && k1y >= 0 && k1y <= painter->getHeight()))
1845                                 {
1846                                         //painter->lineTo(k2x, k2y);
1847                                         painter->drawLine(Vector(k1x, k1y), Vector(k2x, k2y));
1848                                         simulationDelay();
1849                                         //graphic->simulationDelay();
1850                                 }
1851                                 //createDirectPainter();
1852                                 //painter->setPen(pen);
1853                                 //painter->moveTo(k2x, k2y);
1854
1855                                 k1x = k2x;
1856                                 k1y = k2y;
1857                         }
1858
1859                         createDirectPainter();
1860                         painter->setPen(pen);
1861                         painter->drawLine(Vector(k2x, k2y), Vector(ix2, iy2));
1862                         //painter->lineTo(ix2, iy2);
1863                 }
1864                 else
1865                 {
1866                         // Arc Clockwise:
1867                         //
1868                         if (a1 < a2cp + 0.01)
1869                                 a2cp -= 2 * M_PI;
1870
1871                         //createDirectPainter();
1872                         //painter->setPen(pen);
1873                         //painter->moveTo(ix1, iy1);
1874                         for(a=a1-aStep; a>=a2cp; a-=aStep)
1875                         {
1876                                 k2x = RS_Math::round(center.x + cos(a) * radius);
1877                                 k2y = RS_Math::round(center.y - sin(a) * radius);
1878                                 //if(graphic->isPointOnScreen(k2x, k2y) ||
1879                                 //        graphic->isPointOnScreen(k1x, k1y)    ) {
1880                                 createDirectPainter();
1881                                 painter->setPen(pen);
1882                                 if ((k2x >=0 && k2x <= painter->getWidth()
1883                                         && k2y >= 0 && k2y <= painter->getHeight())
1884                                         || (k1x >= 0 && k1x <= painter->getWidth()
1885                                         && k1y >= 0 && k1y <= painter->getHeight()))
1886                                 {
1887                                         //painter->lineTo(k2x, k2y);
1888                                         painter->drawLine(Vector(k1x, k1y), Vector(k2x, k2y));
1889                                         simulationDelay();
1890                                 }
1891                                 //createDirectPainter();
1892                                 //painter->setPen(pen);
1893                                 //painter->moveTo(k2x, k2y);
1894                                 k1x = k2x;
1895                                 k1y = k2y;
1896                         }
1897
1898                         createDirectPainter();
1899                         painter->setPen(pen);
1900                         //painter->lineTo(ix2, iy2);
1901                         painter->drawLine(Vector(k2x, k2y), Vector(ix2, iy2));
1902                 }
1903         }
1904 }
1905
1906 /**
1907  * @return Pointer to the static pattern struct that belongs to the
1908  * given pattern type or NULL.
1909  */
1910 RS_LineTypePattern * RS_GraphicView::getPattern(RS2::LineType t)
1911 {
1912         switch (t)
1913         {
1914         case RS2::SolidLine:
1915                 return &patternSolidLine;
1916                 break;
1917
1918         case RS2::DotLine:
1919                 return &patternDotLine;
1920                 break;
1921         case RS2::DotLine2:
1922                 return &patternDotLine2;
1923                 break;
1924         case RS2::DotLineX2:
1925                 return &patternDotLineX2;
1926                 break;
1927
1928         case RS2::DashLine:
1929                 return &patternDashLine;
1930                 break;
1931         case RS2::DashLine2:
1932                 return &patternDashLine2;
1933                 break;
1934         case RS2::DashLineX2:
1935                 return &patternDashLineX2;
1936                 break;
1937
1938         case RS2::DashDotLine:
1939                 return &patternDashDotLine;
1940                 break;
1941         case RS2::DashDotLine2:
1942                 return &patternDashDotLine2;
1943                 break;
1944         case RS2::DashDotLineX2:
1945                 return &patternDashDotLineX2;
1946                 break;
1947
1948         case RS2::DivideLine:
1949                 return &patternDivideLine;
1950                 break;
1951         case RS2::DivideLine2:
1952                 return &patternDivideLine2;
1953                 break;
1954         case RS2::DivideLineX2:
1955                 return &patternDivideLineX2;
1956                 break;
1957
1958         case RS2::CenterLine:
1959                 return &patternCenterLine;
1960                 break;
1961         case RS2::CenterLine2:
1962                 return &patternCenterLine2;
1963                 break;
1964         case RS2::CenterLineX2:
1965                 return &patternCenterLineX2;
1966                 break;
1967
1968         case RS2::BorderLine:
1969                 return &patternBorderLine;
1970                 break;
1971         case RS2::BorderLine2:
1972                 return &patternBorderLine2;
1973                 break;
1974         case RS2::BorderLineX2:
1975                 return &patternBorderLineX2;
1976                 break;
1977
1978         case RS2::LineByLayer:
1979                 return &patternBlockLine;
1980                 break;
1981         case RS2::LineByBlock:
1982                 return &patternBlockLine;
1983                 break;
1984         default:
1985                 break;
1986         }
1987
1988         return NULL;
1989 }
1990
1991 /**
1992  * This virtual method can be overwritten to draw the absolute
1993  * zero. It's called from within drawIt(). The default implemetation
1994  * draws a simple red round zero point.
1995  *
1996  * @see drawIt()
1997  */
1998 void RS_GraphicView::drawAbsoluteZero()
1999 {
2000 //RS_DEBUG->print(RS_Debug::D_CRITICAL, "RS_GraphicView::drawAbsoluteZero (painter=%08X)", painter);
2001 //      bool painterCreated = false;
2002
2003         // create a temporary painter device
2004         if (painter == NULL)
2005         {
2006                 return;
2007 //Hrm.          createDirectPainter();
2008 //              createPainter();
2009 //              painterCreated = true;
2010         }
2011
2012         int zr = 20;
2013
2014 //      RS_Pen pen(metaGridColor, RS2::Width00, RS2::SolidLine);
2015 //      painter->setPen(pen);
2016 //      RS_Pen p(Qt::red, RS2::Width00, RS2::SolidLine);
2017 //Using Qt::red doesn't seem to work here...
2018 //It's because Qt colors and RS_Color are not 100% compatible...
2019         RS_Pen p(RS_Color(255, 0, 0), RS2::Width00, RS2::SolidLine);
2020 //      p.setScreenWidth(0);
2021         painter->setPen(p);
2022         //painter->setBrush(Qt::NoBrush);
2023
2024         painter->drawLine(Vector(toGuiX(0.0) - zr, toGuiY(0.0)),
2025                 Vector(toGuiX(0.0) + zr, toGuiY(0.0)));
2026
2027         painter->drawLine(Vector(toGuiX(0.0), toGuiY(0.0) - zr),
2028                 Vector(toGuiX(0.0), toGuiY(0.0) + zr));
2029
2030 //      if (painterCreated)
2031 //              destroyPainter();
2032 }
2033
2034 /**
2035  * This virtual method can be overwritten to draw the relative
2036  * zero point. It's called from within drawIt(). The default implemetation
2037  * draws a simple red round zero point.
2038  *
2039  * @see drawIt()
2040  */
2041 void RS_GraphicView::drawRelativeZero()
2042 {
2043 //#warning "!!! drawRelativeZero() not working AT ALL !!!"
2044 #if 1
2045 //      bool painterCreated = false;
2046
2047         if (relativeZero.valid == false)
2048                 return;
2049
2050         // create a temporary painter device
2051         if (painter == NULL)
2052         {
2053                 return;
2054 //hrm.          createDirectPainter();
2055 //              createPainter();
2056 //              painterCreated = true;
2057         }
2058
2059 //      RS_Pen p(Qt::red, RS2::Width00, RS2::SolidLine);
2060 //      p.setScreenWidth(0);
2061 //Using Qt::red doesn't seem to work here...
2062         RS_Pen p(RS_Color(255, 0, 0), RS2::Width00, RS2::SolidLine);
2063         painter->setPen(p);
2064         painter->setXORMode();
2065
2066         int zr = 5;
2067
2068         painter->drawLine(Vector(toGuiX(relativeZero.x) - zr, toGuiY(relativeZero.y)),
2069                 Vector(toGuiX(relativeZero.x) + zr, toGuiY(relativeZero.y)));
2070
2071         painter->drawLine(Vector(toGuiX(relativeZero.x), toGuiY(relativeZero.y) - zr),
2072                 Vector(toGuiX(relativeZero.x), toGuiY(relativeZero.y) + zr));
2073
2074         painter->drawCircle(toGui(relativeZero), zr);
2075
2076         painter->setNormalMode();
2077
2078 //      if (painterCreated)
2079 //              destroyPainter();
2080 #endif
2081 }
2082
2083 /**
2084  * Draws the paper border (for print previews).
2085  *
2086  * @see drawIt()
2087  */
2088 void RS_GraphicView::drawPaper()
2089 {
2090         bool painterCreated = false;
2091
2092         if (container == NULL)
2093                 return;
2094
2095         Drawing * graphic = container->getGraphic();
2096
2097         if (graphic == NULL)
2098                 return;
2099
2100         if (graphic->getPaperScale() < 1.0e-6)
2101                 return;
2102
2103         // create a temporary painter device
2104         if (painter == NULL)
2105         {
2106                 createDirectPainter();
2107                 painterCreated = true;
2108         }
2109
2110         // draw paper:
2111         painter->setPen(RS_Pen(Qt::gray));
2112
2113         Vector pinsbase = graphic->getPaperInsertionBase();
2114         Vector size = graphic->getPaperSize();
2115         double scale = graphic->getPaperScale();
2116
2117         Vector v1 = toGui((Vector(0, 0) - pinsbase) / scale);
2118         Vector v2 = toGui((size - pinsbase) / scale);
2119
2120         // gray background:
2121         painter->fillRect(0,0, getWidth(), getHeight(), RS_Color(200, 200, 200));
2122
2123         // shadow
2124         painter->fillRect((int)(v1.x) + 6, (int)(v1.y) + 6,
2125                 (int)((v2.x - v1.x)), (int)((v2.y - v1.y)),
2126                 RS_Color(64, 64, 64));
2127
2128         // border:
2129         painter->fillRect((int)(v1.x), (int)(v1.y),
2130                 (int)((v2.x - v1.x)), (int)((v2.y - v1.y)),
2131                 RS_Color(64, 64, 64));
2132
2133         // paper
2134         painter->fillRect((int)(v1.x) + 1, (int)(v1.y) - 1,
2135                 (int)((v2.x - v1.x)) - 2, (int)((v2.y - v1.y)) + 2,
2136                 RS_Color(255, 255, 255));
2137
2138         if (painterCreated)
2139                 destroyPainter();
2140 }
2141
2142 /**
2143  * Draws the grid.
2144  *
2145  * @see drawIt()
2146  */
2147 void RS_GraphicView::drawGrid()
2148 {
2149         if (grid == NULL || isGridOn() == false)
2150 //      {
2151 //              printf("RS_GraphicView::drawGrid(): Aborting: grid=%08X, isGridOn=%s\n", grid, (isGridOn() ? "true" : "false"));
2152                 return;
2153 //      }
2154
2155         // draw grid:
2156         //painter->setPen(Qt::gray);
2157         painter->setPen(gridColor);
2158 //      painter->setPen(RS_Pen(RS_Color(128, 128, 128), RS2::Width00, RS2::SolidLine));
2159
2160 //Problem here: pts is NULL!
2161         Vector * pts = grid->getPoints();
2162
2163         if (pts != NULL)
2164         {
2165                 for(int i=0; i<grid->count(); ++i)
2166                         painter->drawGridPoint(toGui(pts[i]));
2167         }
2168 //      else
2169 //              printf("RS_GraphicView::drawGrid(): pts == NULL!\n");
2170
2171         // draw grid info:
2172         //painter->setPen(Qt::white);
2173         QString info = grid->getInfo();
2174         //info = QString("%1 / %2")
2175         //       .arg(grid->getSpacing())
2176         //       .arg(grid->getMetaSpacing());
2177
2178         updateGridStatusWidget(info);
2179 }
2180
2181 /**
2182  * Draws the meta grid.
2183  *
2184  * @see drawIt()
2185  */
2186 void RS_GraphicView::drawMetaGrid()
2187 {
2188         if (grid == NULL || isGridOn() == false /*|| grid->getMetaSpacing()<0.0*/)
2189                 return;
2190
2191         bool painterCreated = false;
2192
2193         // create a temporary painter device
2194         if (painter == NULL)
2195         {
2196 //hrm           createDirectPainter();
2197                 createPainter();
2198                 painterCreated = true;
2199         }
2200
2201         RS_Pen pen(metaGridColor, RS2::Width00, RS2::DotLine);
2202         painter->setPen(pen);
2203
2204         // draw meta grid:
2205         double * mx = grid->getMetaX();
2206
2207         if (mx != NULL)
2208         {
2209                 for(int i=0; i<grid->countMetaX(); ++i)
2210                         painter->drawLine(Vector(toGuiX(mx[i]), 0), Vector(toGuiX(mx[i]), getHeight()));
2211         }
2212
2213         double * my = grid->getMetaY();
2214
2215         if (my != NULL)
2216         {
2217                 for(int i=0; i<grid->countMetaY(); ++i)
2218                         painter->drawLine(Vector(0, toGuiY(my[i])), Vector(getWidth(), toGuiY(my[i])));
2219         }
2220
2221         if (painterCreated)
2222                 destroyPainter();
2223 }
2224
2225 /**
2226  * Updates the grid if there is one.
2227  */
2228 void RS_GraphicView::updateGrid()
2229 {
2230         if (grid != NULL)
2231                 grid->update();
2232 }
2233
2234 RS_Grid * RS_GraphicView::getGrid()
2235 {
2236         return grid;
2237 }
2238
2239 void RS_GraphicView::updateGridStatusWidget(const QString & /*text*/)
2240 {
2241 }
2242
2243 RS2::SnapMode RS_GraphicView::getDefaultSnapMode()
2244 {
2245         return defaultSnapMode;
2246 }
2247
2248 RS2::SnapRestriction RS_GraphicView::getSnapRestriction()
2249 {
2250         return defaultSnapRes;
2251 }
2252
2253 /**
2254  * Sets the default snap mode used by newly created actions.
2255  */
2256 void RS_GraphicView::setDefaultSnapMode(RS2::SnapMode sm)
2257 {
2258         defaultSnapMode = sm;
2259
2260         if (eventHandler != NULL)
2261                 eventHandler->setSnapMode(sm);
2262 }
2263
2264 /**
2265  * Sets a snap restriction (e.g. orthogonal).
2266  */
2267 void RS_GraphicView::setSnapRestriction(RS2::SnapRestriction sr)
2268 {
2269         defaultSnapRes = sr;
2270
2271         if (eventHandler != NULL)
2272                 eventHandler->setSnapRestriction(sr);
2273 }
2274
2275 /**
2276  * Translates a vector in real coordinates to a vector in screen coordinates.
2277  */
2278 Vector RS_GraphicView::toGui(Vector v)
2279 {
2280         return Vector(toGuiX(v.x), toGuiY(v.y), 0.0);
2281 }
2282
2283 /**
2284  * Translates a real coordinate in X to a screen coordinate X.
2285  * @param visible Pointer to a boolean which will contain true
2286  * after the call if the coordinate is within the visible range.
2287  */
2288 double RS_GraphicView::toGuiX(double x, bool * visible)
2289 {
2290         if (visible != NULL)
2291         {
2292                 double res = x * factor.x + offsetX;
2293
2294                 if (res > 0.0 && res < getWidth())
2295                         *visible = true;
2296                 else
2297                         *visible = false;
2298         }
2299
2300         return x * factor.x + offsetX;
2301 }
2302
2303 /**
2304  * Translates a real coordinate in Y to a screen coordinate Y.
2305  */
2306 double RS_GraphicView::toGuiY(double y)
2307 {
2308         return -y * factor.y + getHeight() - offsetY;
2309 }
2310
2311 /**
2312  * Translates a real coordinate distance to a screen coordinate distance.
2313  */
2314 double RS_GraphicView::toGuiDX(double d)
2315 {
2316         return d * factor.x;
2317 }
2318
2319 /**
2320  * Translates a real coordinate distance to a screen coordinate distance.
2321  */
2322 double RS_GraphicView::toGuiDY(double d)
2323 {
2324         return d * factor.y;
2325 }
2326
2327 /**
2328  * Translates a vector in screen coordinates to a vector in real coordinates.
2329  */
2330 Vector RS_GraphicView::toGraph(Vector v)
2331 {
2332         return Vector(toGraphX(RS_Math::round(v.x)), toGraphY(RS_Math::round(v.y)), 0.0);
2333 }
2334
2335 /**
2336  * Translates two screen coordinates to a vector in real coordinates.
2337  */
2338 Vector RS_GraphicView::toGraph(int x, int y)
2339 {
2340         return Vector(toGraphX(x), toGraphY(y), 0.0);
2341 }
2342
2343 /**
2344  * Translates a screen coordinate in X to a real coordinate X.
2345  */
2346 double RS_GraphicView::toGraphX(int x)
2347 {
2348         return (x - offsetX) / factor.x;
2349 }
2350
2351 /**
2352  * Translates a screen coordinate in Y to a real coordinate Y.
2353  */
2354 double RS_GraphicView::toGraphY(int y)
2355 {
2356         return -(y - getHeight() + offsetY) / factor.y;
2357 }
2358
2359 /**
2360  * Translates a screen coordinate distance to a real coordinate distance.
2361  */
2362 double RS_GraphicView::toGraphDX(int d)
2363 {
2364         return d / factor.x;
2365 }
2366
2367 /**
2368  * Translates a screen coordinate distance to a real coordinate distance.
2369  */
2370 double RS_GraphicView::toGraphDY(int d)
2371 {
2372         return d / factor.y;
2373 }
2374
2375 /**
2376  * (Un-)Locks the position of the relative zero.
2377  *
2378  * @param lock true: lock, false: unlock
2379  */
2380 void RS_GraphicView::lockRelativeZero(bool lock)
2381 {
2382         relativeZeroLocked=lock;
2383 }
2384
2385 /**
2386  * @return true if the position of the realtive zero point is
2387  * locked.
2388  */
2389 bool RS_GraphicView::isRelativeZeroLocked()
2390 {
2391         return relativeZeroLocked;
2392 }
2393
2394 /**
2395  * @return Relative zero coordinate.
2396  */
2397 Vector RS_GraphicView::getRelativeZero()
2398 {
2399         return relativeZero;
2400 }
2401
2402 /**
2403  * Sets the relative zero coordinate (if not locked)
2404  * without deleting / drawing the point.
2405  */
2406 void RS_GraphicView::setRelativeZero(const Vector & pos)
2407 {
2408         if (!relativeZeroLocked)
2409                 relativeZero = pos;
2410 }
2411
2412 /**
2413  * Sets the relative zero coordinate, deletes the old position
2414  * on the screen and draws the new one.
2415  */
2416 void RS_GraphicView::moveRelativeZero(const Vector & pos)
2417 {
2418 //      bool painterCreated = false;
2419
2420         if (painter == NULL)
2421         {
2422                 return;
2423 //hrm           painter = createDirectPainter();
2424 //              painter = createPainter();
2425 //              painterCreated = true;
2426         }
2427
2428         //painter->setXORMode();
2429         drawRelativeZero();
2430
2431         setRelativeZero(pos);
2432
2433         drawRelativeZero();
2434
2435 //      if (painterCreated)
2436 //              destroyPainter();
2437 }
2438
2439 RS_EventHandler * RS_GraphicView::getEventHandler()
2440 {
2441         return eventHandler;
2442 }
2443
2444 /**
2445  * Enables or disables print preview.
2446  */
2447 void RS_GraphicView::setPrintPreview(bool pv)
2448 {
2449         printPreview = pv;
2450 }
2451
2452 /**
2453  * @retval true This is a print preview graphic view.
2454  * @retval false Otherwise.
2455  */
2456 bool RS_GraphicView::isPrintPreview()
2457 {
2458         return printPreview;
2459 }
2460
2461 /**
2462  * Enables or disables printing.
2463  */
2464 void RS_GraphicView::setPrinting(bool p)
2465 {
2466         printing = p;
2467 }
2468
2469 /**
2470  * @retval true This is a a graphic view for printing.
2471  * @retval false Otherwise.
2472  */
2473 bool RS_GraphicView::isPrinting()
2474 {
2475         return printing;
2476 }
2477
2478 /**
2479  * @retval true Draft mode is on for this view (all lines with 1 pixel / no style scaling).
2480  * @retval false Otherwise.
2481  */
2482 bool RS_GraphicView::isDraftMode()
2483 {
2484         return draftMode;
2485 }
2486
2487 /**
2488  * Sets the simulation speed in percentage.
2489  */
2490 void RS_GraphicView::setSimulationSpeed(int s)
2491 {
2492         simulationSpeed = s;
2493 }
2494
2495 /**
2496  * @return the simulation speed in percentage.
2497  */
2498 int RS_GraphicView::getSimulationSpeed()
2499 {
2500         return simulationSpeed;
2501 }
2502
2503 /**
2504  * Sets the simulation smooth mode.
2505  */
2506 void RS_GraphicView::setSimulationSmooth(bool s)
2507 {
2508         simulationSmooth = s;
2509 }
2510 /**
2511  * Sets the simulation rapid mode.
2512  */
2513 void RS_GraphicView::setSimulationRapid(bool r)
2514 {
2515         simulationRapid = r;
2516 }
2517
2518 /**
2519  * @return the simulation rapid mode.
2520  */
2521 bool RS_GraphicView::getSimulationRapid()
2522 {
2523         return simulationRapid;
2524 }
2525
2526 // These functions are here because of the focacta way that this
2527 // program set up its rendering...
2528 void RS_GraphicView::SetPreviewMode(bool mode/*= true*/)
2529 {
2530         previewMode = mode;
2531 }
2532
2533 void RS_GraphicView::SetPreviewEntity(RS_Preview * p)
2534 {
2535         previewEntity = p;
2536 }
2537
2538 void RS_GraphicView::SetPreviewOffset(Vector o)
2539 {
2540         previewOffset = o;
2541 }
2542
2543 void RS_GraphicView::SetSnapperDraw(bool mode)
2544 {
2545         snapperDraw = mode;
2546 }
2547
2548 void RS_GraphicView::SetSnapperVars(Vector snapSpot, Vector snapCoord, bool showCrosshairs)
2549 {
2550         snapSpot1 = snapSpot;
2551         snapCoord1 = snapCoord;
2552         showCrosshairs1 = showCrosshairs;
2553 }