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