~librecad-dev/librecad/librecad

« back to all changes in this revision

Viewing changes to librecad/src/lib/gui/rs_graphicview.cpp

  • Committer: Scott Howard
  • Date: 2014-02-21 19:07:55 UTC
  • Revision ID: showard@debian.org-20140221190755-csjax9wb146hgdq4
first commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** This file is part of the LibreCAD project, a 2D CAD program
 
4
**
 
5
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
 
6
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
 
7
**
 
8
**
 
9
** This file may be distributed and/or modified under the terms of the
 
10
** GNU General Public License version 2 as published by the Free Software
 
11
** Foundation and appearing in the file gpl-2.0.txt included in the
 
12
** packaging of this file.
 
13
**
 
14
** This program is distributed in the hope that it will be useful,
 
15
** but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
** GNU General Public License for more details.
 
18
**
 
19
** You should have received a copy of the GNU General Public License
 
20
** along with this program; if not, write to the Free Software
 
21
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 
22
**
 
23
** This copyright notice MUST APPEAR in all copies of the script!
 
24
**
 
25
**********************************************************************/
 
26
 
 
27
#include <QAction>
 
28
#include <limits.h>
 
29
#include "qc_applicationwindow.h"
 
30
#include "rs_graphicview.h"
 
31
 
 
32
#include "rs_linetypepattern.h"
 
33
#include "rs_eventhandler.h"
 
34
#include "rs_graphic.h"
 
35
#include "rs_grid.h"
 
36
#include "rs_painter.h"
 
37
#include "rs_mtext.h"
 
38
#include "rs_text.h"
 
39
#include "rs_settings.h"
 
40
#include "rs_dialogfactory.h"
 
41
#include "rs_layer.h"
 
42
 
 
43
#ifdef EMU_C99
 
44
#include "emu_c99.h"
 
45
#endif
 
46
 
 
47
/**
 
48
 * Constructor.
 
49
 */
 
50
RS_GraphicView::RS_GraphicView()
 
51
    : background(), foreground(),
 
52
      savedViews(16), savedViewIndex(0),savedViewCount(0),previousViewTime(QDateTime::currentDateTime())
 
53
    ,m_bIsCleanUp(false)
 
54
{
 
55
    drawingMode = RS2::ModeFull;
 
56
    printing = false;
 
57
    deleteMode = false;
 
58
    factor = RS_Vector(1.0,1.0);
 
59
    offsetX = 0;
 
60
    offsetY = 0;
 
61
    container = NULL;
 
62
    eventHandler = new RS_EventHandler(this);
 
63
    gridColor = Qt::gray;
 
64
    metaGridColor = RS_Color(64,64,64);
 
65
    grid = new RS_Grid(this);
 
66
    zoomFrozen = false;
 
67
    //gridVisible = true;
 
68
    draftMode = false;
 
69
 
 
70
    borderLeft = 0;
 
71
    borderTop = 0;
 
72
    borderRight = 0;
 
73
    borderBottom = 0;
 
74
 
 
75
    relativeZero = RS_Vector(false);
 
76
    relativeZeroLocked=false;
 
77
 
 
78
    mx = my = 0;
 
79
 
 
80
    RS_SETTINGS->beginGroup("/Appearance");
 
81
    setBackground(QColor(RS_SETTINGS->readEntry("/BackgroundColor", "#000000")));
 
82
    setGridColor(QColor(RS_SETTINGS->readEntry("/GridColor", "#7F7F7F")));
 
83
    setMetaGridColor(QColor(RS_SETTINGS->readEntry("/MetaGridColor", "#3F3F3F")));
 
84
    setSelectedColor(QColor(RS_SETTINGS->readEntry("/SelectedColor", "#A54747")));
 
85
        setHighlightedColor(QColor(RS_SETTINGS->readEntry("/HighlightedColor", "#739373")));
 
86
        setStartHandleColor(QColor(RS_SETTINGS->readEntry("/StartHandleColor", "#00FFFF")));
 
87
        setHandleColor(QColor(RS_SETTINGS->readEntry("/HandleColor", "#0000FF")));
 
88
        setEndHandleColor(QColor(RS_SETTINGS->readEntry("/EndHandleColor", "#0000FF")));
 
89
 
 
90
    RS_SETTINGS->endGroup();
 
91
 
 
92
    printPreview = false;
 
93
 
 
94
    QC_ApplicationWindow::getAppWindow()->setPreviousZoomEnable(false);
 
95
    //currentInsert = NULL;
 
96
}
 
97
 
 
98
 
 
99
 
 
100
/**
 
101
 * Destructor.
 
102
 */
 
103
RS_GraphicView::~RS_GraphicView() {
 
104
    /*
 
105
    //@write default snap mode from prefrences.
 
106
    defaultSnapMode.restriction=defaultSnapRes;
 
107
    unsigned int snapFlags=RS_Snapper::snapModeToInt(defaultSnapMode);
 
108
    RS_SETTINGS->beginGroup("/Snap");
 
109
    RS_SETTINGS->writeEntry("/SnapMode",QString::number(snapFlags));
 
110
    RS_SETTINGS->endGroup();
 
111
    // no need to delete child widgets, Qt does it all for us
 
112
    */
 
113
    delete grid;
 
114
}
 
115
 
 
116
 
 
117
 
 
118
/**
 
119
 * Must be called by any derrived class in the destructor.
 
120
 */
 
121
void RS_GraphicView::cleanUp() {
 
122
    m_bIsCleanUp=true;
 
123
    //delete eventHandler;
 
124
    delete eventHandler;
 
125
}
 
126
 
 
127
/**
 
128
 * Sets the pointer to the graphic which contains the entities
 
129
 * which are visualized by this widget.
 
130
 */
 
131
void RS_GraphicView::setContainer(RS_EntityContainer* container) {
 
132
    this->container = container;
 
133
    //adjustOffsetControls();
 
134
}
 
135
 
 
136
 
 
137
 
 
138
/**
 
139
 * Sets the zoom factor in X for this visualization of the graphic.
 
140
 */
 
141
void RS_GraphicView::setFactorX(double f) {
 
142
    if (!zoomFrozen) {
 
143
        factor.x = fabs(f);
 
144
    }
 
145
}
 
146
 
 
147
 
 
148
 
 
149
/**
 
150
 * Sets the zoom factor in Y for this visualization of the graphic.
 
151
 */
 
152
void RS_GraphicView::setFactorY(double f) {
 
153
    if (!zoomFrozen) {
 
154
        factor.y = fabs(f);
 
155
    }
 
156
}
 
157
 
 
158
void RS_GraphicView::setOffset(int ox, int oy) {
 
159
//    DEBUG_HEADER();
 
160
//    RS_DEBUG->print(/*RS_Debug::D_WARNING, */"set offset from (%d, %d) to (%d, %d)", getOffsetX(), getOffsetY(), ox, oy);
 
161
    setOffsetX(ox);
 
162
    setOffsetY(oy);
 
163
}
 
164
 
 
165
/**
 
166
 * @return true if the grid is switched on.
 
167
 */
 
168
bool RS_GraphicView::isGridOn() {
 
169
    if (container!=NULL) {
 
170
        RS_Graphic* g = container->getGraphic();
 
171
        if (g!=NULL) {
 
172
            return g->isGridOn();
 
173
        }
 
174
    }
 
175
    return true;
 
176
}
 
177
 
 
178
/**
 
179
 * @return true if the grid is isometric
 
180
 *
 
181
 *@Author: Dongxu Li
 
182
 */
 
183
bool RS_GraphicView::isGridIsometric() {
 
184
    return grid->isIsometric();
 
185
}
 
186
 
 
187
 
 
188
void RS_GraphicView::setCrosshairType(RS2::CrosshairType chType){
 
189
    grid->setCrosshairType(chType);
 
190
}
 
191
 
 
192
RS2::CrosshairType RS_GraphicView::getCrosshairType(){
 
193
    return grid->getCrosshairType();
 
194
}
 
195
 
 
196
 
 
197
/**
 
198
 * Centers the drawing in x-direction.
 
199
 */
 
200
void RS_GraphicView::centerOffsetX() {
 
201
    if (container!=NULL && !zoomFrozen) {
 
202
        offsetX = (int)(((getWidth()-borderLeft-borderRight)
 
203
                         - (container->getSize().x*factor.x))/2.0
 
204
                        - (container->getMin().x*factor.x)) + borderLeft;
 
205
    }
 
206
}
 
207
 
 
208
 
 
209
 
 
210
/**
 
211
 * Centers the drawing in y-direction.
 
212
 */
 
213
void RS_GraphicView::centerOffsetY() {
 
214
    if (container!=NULL && !zoomFrozen) {
 
215
        offsetY = (int)((getHeight()-borderTop-borderBottom
 
216
                         - (container->getSize().y*factor.y))/2.0
 
217
                        - (container->getMin().y*factor.y)) + borderBottom;
 
218
    }
 
219
}
 
220
 
 
221
 
 
222
 
 
223
/**
 
224
 * Centers the given coordinate in the view in x-direction.
 
225
 */
 
226
void RS_GraphicView::centerX(double v) {
 
227
    if (!zoomFrozen) {
 
228
        offsetX = (int)((v*factor.x)
 
229
                        - (double)(getWidth()-borderLeft-borderRight)/2.0);
 
230
    }
 
231
}
 
232
 
 
233
 
 
234
 
 
235
/**
 
236
 * Centers the given coordinate in the view in y-direction.
 
237
 */
 
238
void RS_GraphicView::centerY(double v) {
 
239
    if (!zoomFrozen) {
 
240
        offsetY = (int)((v*factor.y)
 
241
                        - (double)(getHeight()-borderTop-borderBottom)/2.0);
 
242
    }
 
243
}
 
244
 
 
245
/**
 
246
 * @return Current action or NULL.
 
247
 */
 
248
RS_ActionInterface* RS_GraphicView::getDefaultAction() {
 
249
    if (eventHandler!=NULL) {
 
250
        return eventHandler->getDefaultAction();
 
251
    } else {
 
252
        return NULL;
 
253
    }
 
254
}
 
255
 
 
256
 
 
257
 
 
258
/**
 
259
 * Sets the default action of the event handler.
 
260
 */
 
261
void RS_GraphicView::setDefaultAction(RS_ActionInterface* action) {
 
262
    if (eventHandler!=NULL) {
 
263
        eventHandler->setDefaultAction(action);
 
264
    }
 
265
}
 
266
 
 
267
 
 
268
 
 
269
/**
 
270
 * @return Current action or NULL.
 
271
 */
 
272
RS_ActionInterface* RS_GraphicView::getCurrentAction() {
 
273
    if (eventHandler!=NULL) {
 
274
        return eventHandler->getCurrentAction();
 
275
    } else {
 
276
        return NULL;
 
277
    }
 
278
}
 
279
 
 
280
 
 
281
 
 
282
/**
 
283
 * Sets the current action of the event handler.
 
284
 */
 
285
void RS_GraphicView::setCurrentAction(RS_ActionInterface* action) {
 
286
    RS_DEBUG->print("RS_GraphicView::setCurrentAction");
 
287
    if (eventHandler!=NULL) {
 
288
        eventHandler->setCurrentAction(action);
 
289
    }
 
290
    RS_DEBUG->print("RS_GraphicView::setCurrentAction: OK");
 
291
}
 
292
 
 
293
 
 
294
/**
 
295
 * Kills all running selection actions. Called when a selection action
 
296
 * is launched to reduce confusion.
 
297
 */
 
298
void RS_GraphicView::killSelectActions() {
 
299
    if (eventHandler!=NULL) {
 
300
        eventHandler->killSelectActions();
 
301
    }
 
302
}
 
303
 
 
304
 
 
305
 
 
306
/**
 
307
 * Kills all running actions.
 
308
 */
 
309
void RS_GraphicView::killAllActions() {
 
310
    if (eventHandler!=NULL) {
 
311
        eventHandler->killAllActions();
 
312
    }
 
313
}
 
314
 
 
315
 
 
316
 
 
317
/**
 
318
 * Go back in menu or current action.
 
319
 */
 
320
void RS_GraphicView::back() {
 
321
    if (eventHandler!=NULL && eventHandler->hasAction()) {
 
322
        eventHandler->back();
 
323
    } else {
 
324
        if (RS_DIALOGFACTORY!=NULL) {
 
325
            RS_DIALOGFACTORY->requestPreviousMenu();
 
326
        }
 
327
    }
 
328
}
 
329
 
 
330
 
 
331
 
 
332
/**
 
333
 * Go forward with the current action.
 
334
 */
 
335
void RS_GraphicView::enter() {
 
336
    if (eventHandler!=NULL && eventHandler->hasAction()) {
 
337
        eventHandler->enter();
 
338
    }
 
339
}
 
340
 
 
341
 
 
342
 
 
343
/**
 
344
 * Called by the actual GUI class which implements the RS_GraphicView
 
345
 * interface to notify LibreCAD about mouse events.
 
346
 */
 
347
void RS_GraphicView::mousePressEvent(QMouseEvent* e) {
 
348
    if (eventHandler!=NULL) {
 
349
        eventHandler->mousePressEvent(e);
 
350
    }
 
351
}
 
352
 
 
353
 
 
354
 
 
355
/**
 
356
 * Called by the actual GUI class which implements the RS_GraphicView
 
357
 * interface to notify LibreCAD about mouse events.
 
358
 */
 
359
void RS_GraphicView::mouseReleaseEvent(QMouseEvent* e) {
 
360
    RS_DEBUG->print("RS_GraphicView::mouseReleaseEvent");
 
361
    if (eventHandler!=NULL) {
 
362
        if (e->button()!=Qt::RightButton ||
 
363
                eventHandler->hasAction()) {
 
364
 
 
365
            eventHandler->mouseReleaseEvent(e);
 
366
            //e->accept();
 
367
        }
 
368
        else {
 
369
            back();
 
370
 
 
371
            e->accept();
 
372
        }
 
373
    }
 
374
    RS_DEBUG->print("RS_GraphicView::mouseReleaseEvent: OK");
 
375
}
 
376
 
 
377
 
 
378
/*      *
 
379
 *      Function name:
 
380
 *
 
381
 *      Description:            - Called by the actual GUI class which implements the
 
382
 *                                                        RS_GraphicView interface to notify LibreCAD about
 
383
 *                                                        mouse events.
 
384
 *
 
385
 *      Author(s):                      ..., Claude Sylvain
 
386
 *      Created:                                ?
 
387
 *      Last modified:          23 July 2011
 
388
 *
 
389
 *      Parameters:                     QMouseEvent* e:
 
390
 *                                                              ...
 
391
 *
 
392
 *      Returns:                                void
 
393
 *      */
 
394
 
 
395
void RS_GraphicView::mouseMoveEvent(QMouseEvent* e) {
 
396
    RS_DEBUG->print("RS_GraphicView::mouseMoveEvent begin");
 
397
 
 
398
    RS_Graphic* graphic = NULL;
 
399
 
 
400
    if (container->rtti()==RS2::EntityGraphic) {
 
401
        graphic = (RS_Graphic*)container;
 
402
    }
 
403
 
 
404
    RS_DEBUG->print("RS_GraphicView::mouseMoveEvent 001");
 
405
 
 
406
    if (e!=NULL) {
 
407
        mx = e->x();
 
408
        my = e->y();
 
409
    }
 
410
 
 
411
    RS_DEBUG->print("RS_GraphicView::mouseMoveEvent 002");
 
412
 
 
413
    if (eventHandler!=NULL) {
 
414
        eventHandler->mouseMoveEvent(e);
 
415
    }
 
416
 
 
417
    RS_DEBUG->print("RS_GraphicView::mouseMoveEvent 003");
 
418
 
 
419
    if (        ((eventHandler == NULL) || !eventHandler->hasAction()) &&
 
420
                (graphic != NULL))
 
421
    {
 
422
        RS_Vector       mouse           = toGraph(RS_Vector(mx, my));
 
423
        RS_Vector       relMouse        = mouse - getRelativeZero();
 
424
 
 
425
        if (RS_DIALOGFACTORY!=NULL)
 
426
            RS_DIALOGFACTORY->updateCoordinateWidget(mouse, relMouse);
 
427
    }
 
428
 
 
429
    RS_DEBUG->print("RS_GraphicView::mouseMoveEvent end");
 
430
}
 
431
 
 
432
 
 
433
 
 
434
/**
 
435
 * Called by the actual GUI class which implements the RS_GraphicView
 
436
 * interface to notify LibreCAD about mouse events.
 
437
 */
 
438
void RS_GraphicView::mouseLeaveEvent() {
 
439
    if (eventHandler!=NULL) {
 
440
        eventHandler->mouseLeaveEvent();
 
441
    }
 
442
}
 
443
 
 
444
 
 
445
 
 
446
/**
 
447
 * Called by the actual GUI class which implements the RS_GraphicView
 
448
 * interface to notify LibreCAD about mouse events.
 
449
 */
 
450
void RS_GraphicView::mouseEnterEvent() {
 
451
    if (eventHandler!=NULL) {
 
452
        eventHandler->mouseEnterEvent();
 
453
    }
 
454
}
 
455
 
 
456
 
 
457
 
 
458
/**
 
459
 * Called by the actual GUI class which implements the RS_GraphicView
 
460
 * interface to notify LibreCAD about key events.
 
461
 */
 
462
void RS_GraphicView::keyPressEvent(QKeyEvent* e) {
 
463
    if (eventHandler!=NULL) {
 
464
        eventHandler->keyPressEvent(e);
 
465
    }
 
466
}
 
467
 
 
468
 
 
469
 
 
470
/**
 
471
 * Called by the actual GUI class which implements the RS_GraphicView
 
472
 * interface to notify LibreCAD about key events.
 
473
 */
 
474
void RS_GraphicView::keyReleaseEvent(QKeyEvent* e) {
 
475
    if (eventHandler!=NULL) {
 
476
        eventHandler->keyReleaseEvent(e);
 
477
    }
 
478
}
 
479
 
 
480
 
 
481
 
 
482
/**
 
483
 * Called by the actual GUI class which implements a command line.
 
484
 */
 
485
void RS_GraphicView::commandEvent(RS_CommandEvent* e) {
 
486
    if (eventHandler!=NULL) {
 
487
        eventHandler->commandEvent(e);
 
488
    }
 
489
}
 
490
 
 
491
 
 
492
 
 
493
/**
 
494
 * Enables coordinate input in the command line.
 
495
 */
 
496
void RS_GraphicView::enableCoordinateInput() {
 
497
    if (eventHandler!=NULL) {
 
498
        eventHandler->enableCoordinateInput();
 
499
    }
 
500
}
 
501
 
 
502
 
 
503
 
 
504
/**
 
505
 * Disables coordinate input in the command line.
 
506
 */
 
507
void RS_GraphicView::disableCoordinateInput() {
 
508
    if (eventHandler!=NULL) {
 
509
        eventHandler->disableCoordinateInput();
 
510
    }
 
511
}
 
512
 
 
513
 
 
514
 
 
515
/**
 
516
 * zooms in by factor f
 
517
 */
 
518
void RS_GraphicView::zoomIn(double f, const RS_Vector& center) {
 
519
 
 
520
    if (f<1.0e-6) {
 
521
        RS_DEBUG->print(RS_Debug::D_WARNING,
 
522
                        "RS_GraphicView::zoomIn: invalid factor");
 
523
        return;
 
524
    }
 
525
 
 
526
 
 
527
    RS_Vector c = center;
 
528
    if (c.valid==false) {
 
529
        c = toGraph(RS_Vector(getWidth()/2, getHeight()/2));
 
530
    }
 
531
 
 
532
    zoomWindow(
 
533
                toGraph(RS_Vector(0,0))
 
534
                .scale(c, RS_Vector(1.0/f,1.0/f)),
 
535
                toGraph(RS_Vector(getWidth(),getHeight()))
 
536
                .scale(c, RS_Vector(1.0/f,1.0/f)));
 
537
 
 
538
    //adjustOffsetControls();
 
539
    //adjustZoomControls();
 
540
    // updateGrid();
 
541
    redraw();
 
542
}
 
543
 
 
544
 
 
545
 
 
546
/**
 
547
 * zooms in by factor f in x
 
548
 */
 
549
void RS_GraphicView::zoomInX(double f) {
 
550
    factor.x*=f;
 
551
    offsetX=(int)((offsetX-getWidth()/2)*f)+getWidth()/2;
 
552
    adjustOffsetControls();
 
553
    adjustZoomControls();
 
554
    // updateGrid();
 
555
    redraw();
 
556
}
 
557
 
 
558
 
 
559
 
 
560
/**
 
561
 * zooms in by factor f in y
 
562
 */
 
563
void RS_GraphicView::zoomInY(double f) {
 
564
    factor.y*=f;
 
565
    offsetY=(int)((offsetY-getHeight()/2)*f)+getHeight()/2;
 
566
    adjustOffsetControls();
 
567
    adjustZoomControls();
 
568
    //    updateGrid();
 
569
    redraw();
 
570
}
 
571
 
 
572
 
 
573
 
 
574
/**
 
575
 * zooms out by factor f
 
576
 */
 
577
void RS_GraphicView::zoomOut(double f, const RS_Vector& center) {
 
578
    if (f<1.0e-6) {
 
579
        RS_DEBUG->print(RS_Debug::D_WARNING,
 
580
                        "RS_GraphicView::zoomOut: invalid factor");
 
581
        return;
 
582
    }
 
583
    zoomIn(1/f, center);
 
584
}
 
585
 
 
586
 
 
587
 
 
588
/**
 
589
 * zooms out by factor f in x
 
590
 */
 
591
void RS_GraphicView::zoomOutX(double f) {
 
592
    if (f<1.0e-6) {
 
593
        RS_DEBUG->print(RS_Debug::D_WARNING,
 
594
                        "RS_GraphicView::zoomOutX: invalid factor");
 
595
        return;
 
596
    }
 
597
    factor.x/=f;
 
598
    offsetX=(int)(offsetX/f);
 
599
    adjustOffsetControls();
 
600
    adjustZoomControls();
 
601
    //    updateGrid();
 
602
    redraw();
 
603
}
 
604
 
 
605
 
 
606
 
 
607
/**
 
608
 * zooms out by factor f y
 
609
 */
 
610
void RS_GraphicView::zoomOutY(double f) {
 
611
    if (f<1.0e-6) {
 
612
        RS_DEBUG->print(RS_Debug::D_WARNING,
 
613
                        "RS_GraphicView::zoomOutY: invalid factor");
 
614
        return;
 
615
    }
 
616
    factor.y/=f;
 
617
    offsetY=(int)(offsetY/f);
 
618
    adjustOffsetControls();
 
619
    adjustZoomControls();
 
620
    //    updateGrid();
 
621
    redraw();
 
622
}
 
623
 
 
624
/**
 
625
 * performs autozoom
 
626
 *
 
627
 * @param axis include axis in zoom
 
628
 * @param keepAspectRatio true: keep aspect ratio 1:1
 
629
 *                        false: factors in x and y are stretched to the max
 
630
 */
 
631
void RS_GraphicView::zoomAuto(bool axis, bool keepAspectRatio) {
 
632
 
 
633
    RS_DEBUG->print("RS_GraphicView::zoomAuto");
 
634
 
 
635
 
 
636
    if (container!=NULL) {
 
637
        container->calculateBorders();
 
638
 
 
639
        double sx, sy;
 
640
        if (axis) {
 
641
            sx = std::max(container->getMax().x, 0.0)
 
642
                    - std::min(container->getMin().x, 0.0);
 
643
            sy = std::max(container->getMax().y, 0.0)
 
644
                    - std::min(container->getMin().y, 0.0);
 
645
        } else {
 
646
            sx = container->getSize().x;
 
647
            sy = container->getSize().y;
 
648
        }
 
649
        //    std::cout<<" RS_GraphicView::zoomAuto("<<axis<<","<<keepAspectRatio<<")"<<std::endl;
 
650
 
 
651
        double fx=1., fy=1.;
 
652
        unsigned short fFlags=0;
 
653
 
 
654
        if (sx>RS_TOLERANCE) {
 
655
            fx = (getWidth()-borderLeft-borderRight) / sx;
 
656
        } else {
 
657
            fFlags += 1; //invalid x factor
 
658
        }
 
659
 
 
660
        if (sy>RS_TOLERANCE) {
 
661
            fy = (getHeight()-borderTop-borderBottom) / sy;
 
662
        } else {
 
663
            fFlags += 2; //invalid y factor
 
664
        }
 
665
        //    std::cout<<"0: fx= "<<fx<<"\tfy="<<fy<<std::endl;
 
666
 
 
667
        RS_DEBUG->print("f: %f/%f", fx, fy);
 
668
 
 
669
        switch(fFlags){
 
670
        case 1:
 
671
            fx=fy;
 
672
            break;
 
673
        case 2:
 
674
            fy=fx;
 
675
            break;
 
676
        case 3:
 
677
            return; //do not do anything, invalid factors
 
678
        default:
 
679
            if (keepAspectRatio) {
 
680
                fx = fy = std::min(fx, fy);
 
681
            }
 
682
            //                break;
 
683
        }
 
684
        //    std::cout<<"1: fx= "<<fx<<"\tfy="<<fy<<std::endl;
 
685
 
 
686
        RS_DEBUG->print("f: %f/%f", fx, fy);
 
687
        //exclude invalid factors
 
688
        fFlags=0;
 
689
        if (fx<RS_TOLERANCE||fx>RS_MAXDOUBLE) {
 
690
            fx=1.0;
 
691
            fFlags += 1;
 
692
        }
 
693
        if (fy<RS_TOLERANCE||fy>RS_MAXDOUBLE) {
 
694
            fy=1.0;
 
695
            fFlags += 2;
 
696
        }
 
697
        if(fFlags == 3 ) return;
 
698
        saveView();
 
699
        //        std::cout<<"2: fx= "<<fx<<"\tfy="<<fy<<std::endl;
 
700
        setFactorX(fx);
 
701
        setFactorY(fy);
 
702
 
 
703
        RS_DEBUG->print("f: %f/%f", fx, fy);
 
704
 
 
705
 
 
706
//        RS_DEBUG->print("adjustZoomControls");
 
707
        adjustZoomControls();
 
708
//        RS_DEBUG->print("centerOffsetX");
 
709
        centerOffsetX();
 
710
//        RS_DEBUG->print("centerOffsetY");
 
711
        centerOffsetY();
 
712
//        RS_DEBUG->print("adjustOffsetControls");
 
713
        adjustOffsetControls();
 
714
//        RS_DEBUG->print("updateGrid");
 
715
        //    updateGrid();
 
716
 
 
717
        redraw();
 
718
    }
 
719
    RS_DEBUG->print("RS_GraphicView::zoomAuto OK");
 
720
}
 
721
 
 
722
 
 
723
 
 
724
/**
 
725
 * Shows previous view.
 
726
 */
 
727
void RS_GraphicView::zoomPrevious() {
 
728
 
 
729
    RS_DEBUG->print("RS_GraphicView::zoomPrevious");
 
730
 
 
731
    if (container!=NULL) {
 
732
        restoreView();
 
733
    }
 
734
}
 
735
 
 
736
 
 
737
 
 
738
/**
 
739
 * Saves the current view as previous view to which we can
 
740
 * switch back later with @see restoreView().
 
741
 */
 
742
void RS_GraphicView::saveView() {
 
743
    QDateTime noUpdateWindow=QDateTime::currentDateTime().addMSecs(-500);
 
744
    //do not update view within 500 milliseconds
 
745
    if(previousViewTime > noUpdateWindow) return;
 
746
    previousViewTime = QDateTime::currentDateTime();
 
747
    savedViews[savedViewIndex]=std::make_tuple(offsetX,offsetY,factor);
 
748
    savedViewIndex = (savedViewIndex+1)%savedViews.size();
 
749
    if(savedViewCount<savedViews.size()) savedViewCount++;
 
750
 
 
751
    if(savedViewCount==1){
 
752
        QC_ApplicationWindow::getAppWindow()->setPreviousZoomEnable(true);
 
753
    }
 
754
}
 
755
 
 
756
 
 
757
 
 
758
/**
 
759
 * Restores the view previously saved with
 
760
 * @see saveView().
 
761
 */
 
762
void RS_GraphicView::restoreView() {
 
763
    if(savedViewCount == 0) return;
 
764
    savedViewCount --;
 
765
    if(savedViewCount==0){
 
766
        QC_ApplicationWindow::getAppWindow()->setPreviousZoomEnable(false);
 
767
    }
 
768
    savedViewIndex = (savedViewIndex + savedViews.size() - 1)%savedViews.size();
 
769
 
 
770
    offsetX = std::get<0>(savedViews[savedViewIndex]);
 
771
    offsetY = std::get<1>(savedViews[savedViewIndex]);
 
772
    factor = std::get<2>(savedViews[savedViewIndex]);
 
773
 
 
774
    adjustOffsetControls();
 
775
    adjustZoomControls();
 
776
    //    updateGrid();
 
777
 
 
778
    redraw();
 
779
}
 
780
 
 
781
 
 
782
/*      *
 
783
 *      Function name:
 
784
 *      Description:            Performs autozoom in Y axis only.
 
785
 *      Author(s):                      ..., Claude Sylvain
 
786
 *      Created:                                ?
 
787
 *      Last modified:          23 July 2011
 
788
 *
 
789
 *      Parameters:                     bool axis:
 
790
 *                                                              Axis in zoom.
 
791
 *
 
792
 *      Returns:                                void
 
793
 *      */
 
794
 
 
795
void RS_GraphicView::zoomAutoY(bool axis) {
 
796
    if (container!=NULL) {
 
797
        double visibleHeight = 0.0;
 
798
        double minY = RS_MAXDOUBLE;
 
799
        double maxY = RS_MINDOUBLE;
 
800
        bool noChange = false;
 
801
 
 
802
        for (RS_Entity* e=container->firstEntity(RS2::ResolveNone);
 
803
             e!=NULL;
 
804
             e = container->nextEntity(RS2::ResolveNone)) {
 
805
 
 
806
            if (e->rtti()==RS2::EntityLine) {
 
807
                RS_Line* l = (RS_Line*)e;
 
808
                double x1, x2;
 
809
                x1 = toGuiX(l->getStartpoint().x);
 
810
                x2 = toGuiX(l->getEndpoint().x);
 
811
 
 
812
                if (    ((x1 > 0.0) && (x1 < (double) getWidth())) ||
 
813
                        ((x2 > 0.0) && (x2 < (double) getWidth())))
 
814
                {
 
815
                    minY = std::min(minY, l->getStartpoint().y);
 
816
                    minY = std::min(minY, l->getEndpoint().y);
 
817
                    maxY = std::max(maxY, l->getStartpoint().y);
 
818
                    maxY = std::max(maxY, l->getEndpoint().y);
 
819
                }
 
820
            }
 
821
        }
 
822
 
 
823
        if (axis) {
 
824
            visibleHeight = std::max(maxY, 0.0) - std::min(minY, 0.0);
 
825
        } else {
 
826
            visibleHeight = maxY-minY;
 
827
        }
 
828
 
 
829
        if (visibleHeight<1.0) {
 
830
            noChange = true;
 
831
        }
 
832
 
 
833
        double fy = 1.0;
 
834
        if (visibleHeight>1.0e-6) {
 
835
            fy = (getHeight()-borderTop-borderBottom)
 
836
                    / visibleHeight;
 
837
            if (factor.y<0.000001) {
 
838
                noChange = true;
 
839
            }
 
840
        }
 
841
 
 
842
        if (noChange==false) {
 
843
            setFactorY(fy);
 
844
            //centerOffsetY();
 
845
            offsetY = (int)((getHeight()-borderTop-borderBottom
 
846
                             - (visibleHeight*factor.y))/2.0
 
847
                            - (minY*factor.y)) + borderBottom;
 
848
            adjustOffsetControls();
 
849
            adjustZoomControls();
 
850
            //    updateGrid();
 
851
 
 
852
        }
 
853
        RS_DEBUG->print("Auto zoom y ok");
 
854
    }
 
855
}
 
856
 
 
857
 
 
858
 
 
859
/**
 
860
 * Zooms the area given by v1 and v2.
 
861
 *
 
862
 * @param keepAspectRatio true: keeps the aspect ratio 1:1
 
863
 *                        false: zooms exactly the selected range to the
 
864
 *                               current graphic view
 
865
 */
 
866
void RS_GraphicView::zoomWindow(RS_Vector v1, RS_Vector v2,
 
867
                                bool keepAspectRatio) {
 
868
 
 
869
 
 
870
 
 
871
    double zoomX=480.0;    // Zoom for X-Axis
 
872
    double zoomY=640.0;    // Zoom for Y-Axis   (Set smaller one)
 
873
    int zoomBorder = 0;
 
874
 
 
875
    // Switch left/right and top/bottom is necessary:
 
876
    if(v1.x>v2.x) {
 
877
        std::swap(v1.x,v2.x);
 
878
    }
 
879
    if(v1.y>v2.y) {
 
880
        std::swap(v1.y,v2.y);
 
881
    }
 
882
 
 
883
    // Get zoom in X and zoom in Y:
 
884
    if(v2.x-v1.x>1.0e-6) {
 
885
        zoomX = getWidth() / (v2.x-v1.x);
 
886
    }
 
887
    if(v2.y-v1.y>1.0e-6) {
 
888
        zoomY = getHeight() / (v2.y-v1.y);
 
889
    }
 
890
 
 
891
    // Take smaller zoom:
 
892
    if (keepAspectRatio) {
 
893
        if(zoomX<zoomY) {
 
894
            if(getWidth()!=0) {
 
895
                zoomX = zoomY = ((double)(getWidth()-2*zoomBorder)) /
 
896
                        (double)getWidth()*zoomX;
 
897
            }
 
898
        } else {
 
899
            if(getHeight()!=0) {
 
900
                zoomX = zoomY = ((double)(getHeight()-2*zoomBorder)) /
 
901
                        (double)getHeight()*zoomY;
 
902
            }
 
903
        }
 
904
    }
 
905
 
 
906
    zoomX=fabs(zoomX);
 
907
    zoomY=fabs(zoomY);
 
908
 
 
909
    // Borders in pixel after zoom
 
910
    int pixLeft  =(int)(v1.x*zoomX);
 
911
    int pixTop   =(int)(v2.y*zoomY);
 
912
    int pixRight =(int)(v2.x*zoomX);
 
913
    int pixBottom=(int)(v1.y*zoomY);
 
914
    if(  pixLeft == INT_MIN || pixLeft== INT_MAX ||
 
915
         pixRight == INT_MIN || pixRight== INT_MAX ||
 
916
         pixTop == INT_MIN || pixTop== INT_MAX ||
 
917
         pixBottom == INT_MIN || pixBottom== INT_MAX ) {
 
918
        RS_DIALOGFACTORY->commandMessage("Requested zooming factor out of range. Zooming not changed");
 
919
        return;
 
920
    }
 
921
    saveView();
 
922
 
 
923
    // Set new offset for zero point:
 
924
    offsetX = - pixLeft + (getWidth() -pixRight +pixLeft)/2;
 
925
    offsetY = - pixTop + (getHeight() -pixBottom +pixTop)/2;
 
926
    factor.x = zoomX;
 
927
    factor.y = zoomY;
 
928
 
 
929
    adjustOffsetControls();
 
930
    adjustZoomControls();
 
931
    //    updateGrid();
 
932
 
 
933
    redraw();
 
934
}
 
935
 
 
936
 
 
937
 
 
938
/**
 
939
 * Centers the point v1.
 
940
 */
 
941
void RS_GraphicView::zoomPan(int dx, int dy) {
 
942
    //offsetX+=(int)toGuiDX(v1.x);
 
943
    //offsetY+=(int)toGuiDY(v1.y);
 
944
 
 
945
    offsetX += dx;
 
946
    offsetY -= dy;
 
947
 
 
948
    adjustOffsetControls();
 
949
    //adjustZoomControls();
 
950
    //    updateGrid();
 
951
 
 
952
    redraw();
 
953
}
 
954
 
 
955
 
 
956
 
 
957
/**
 
958
 * Scrolls in the given direction.
 
959
 */
 
960
void RS_GraphicView::zoomScroll(RS2::Direction direction) {
 
961
    switch (direction) {
 
962
    case RS2::Up:
 
963
        offsetY-=50;
 
964
        break;
 
965
    case RS2::Down:
 
966
        offsetY+=50;
 
967
        break;
 
968
    case RS2::Right:
 
969
        offsetX+=50;
 
970
        break;
 
971
    case RS2::Left:
 
972
        offsetX-=50;
 
973
        break;
 
974
    }
 
975
    adjustOffsetControls();
 
976
    adjustZoomControls();
 
977
    //    updateGrid();
 
978
 
 
979
    redraw();
 
980
}
 
981
 
 
982
 
 
983
 
 
984
/**
 
985
 * Zooms to page extends.
 
986
 */
 
987
void RS_GraphicView::zoomPage() {
 
988
 
 
989
    RS_DEBUG->print("RS_GraphicView::zoomPage");
 
990
    if (container==NULL) {
 
991
        return;
 
992
    }
 
993
 
 
994
    RS_Graphic* graphic = container->getGraphic();
 
995
    if (graphic==NULL) {
 
996
        return;
 
997
    }
 
998
 
 
999
    RS_Vector s = graphic->getPaperSize()/graphic->getPaperScale();
 
1000
 
 
1001
    double fx, fy;
 
1002
 
 
1003
    if (s.x>RS_TOLERANCE) {
 
1004
        fx = (getWidth()-borderLeft-borderRight) / s.x;
 
1005
    } else {
 
1006
        fx = 1.0;
 
1007
    }
 
1008
 
 
1009
    if (s.y>RS_TOLERANCE) {
 
1010
        fy = (getHeight()-borderTop-borderBottom) / s.y;
 
1011
    } else {
 
1012
        fy = 1.0;
 
1013
    }
 
1014
 
 
1015
    RS_DEBUG->print("f: %f/%f", fx, fy);
 
1016
 
 
1017
    fx = fy = std::min(fx, fy);
 
1018
 
 
1019
    RS_DEBUG->print("f: %f/%f", fx, fy);
 
1020
 
 
1021
    if (fx<RS_TOLERANCE) {
 
1022
        fx=fy=1.0;
 
1023
    }
 
1024
 
 
1025
    setFactorX(fx);
 
1026
    setFactorY(fy);
 
1027
 
 
1028
    RS_DEBUG->print("f: %f/%f", fx, fy);
 
1029
 
 
1030
    centerOffsetX();
 
1031
    centerOffsetY();
 
1032
    adjustOffsetControls();
 
1033
    adjustZoomControls();
 
1034
    //    updateGrid();
 
1035
 
 
1036
    redraw();
 
1037
}
 
1038
 
 
1039
 
 
1040
 
 
1041
/**
 
1042
 * Draws the entities within the given range.
 
1043
 */
 
1044
void RS_GraphicView::drawWindow_DEPRECATED(RS_Vector v1, RS_Vector v2) {
 
1045
    RS_DEBUG->print("RS_GraphicView::drawWindow() begin");
 
1046
    if (container!=NULL) {
 
1047
        for (RS_Entity* se=container->firstEntity(RS2::ResolveNone);
 
1048
             se!=NULL;
 
1049
             se = container->nextEntity(RS2::ResolveNone)) {
 
1050
            if (se->isInWindow(v1, v2)) {
 
1051
                drawEntity(NULL, se);
 
1052
            }
 
1053
        }
 
1054
    }
 
1055
    RS_DEBUG->print("RS_GraphicView::drawWindow() end");
 
1056
}
 
1057
 
 
1058
/**
 
1059
 * Draws the entities.
 
1060
 * This function can only be called from within the paint event
 
1061
 *
 
1062
 */
 
1063
void RS_GraphicView::drawLayer1(RS_Painter *painter) {
 
1064
 
 
1065
    // drawing paper border:
 
1066
    if (isPrintPreview()) {
 
1067
        drawPaper(painter);
 
1068
    }
 
1069
 
 
1070
    // drawing meta grid:
 
1071
    if (!isPrintPreview()) {
 
1072
 
 
1073
        //only drawGrid updates the grid layout (updatePointArray())
 
1074
        drawMetaGrid(painter);
 
1075
        //draw grid after metaGrid to avoid overwriting grid points by metaGrid lines
 
1076
        //bug# 3430258
 
1077
        drawGrid(painter);
 
1078
 
 
1079
    }
 
1080
 
 
1081
}
 
1082
 
 
1083
 
 
1084
/*      *
 
1085
 *      Function name:
 
1086
 *      Description:            Do the drawing, step 2/3.
 
1087
 *      Author(s):                      ..., Claude Sylvain
 
1088
 *      Created:                                ?
 
1089
 *      Last modified:          23 July 2011
 
1090
 *
 
1091
 *      Parameters:                     RS_Painter *painter:
 
1092
 *                                                              ...
 
1093
 *
 
1094
 *      Returns:                                void
 
1095
 *      */
 
1096
 
 
1097
void RS_GraphicView::drawLayer2(RS_Painter *painter)
 
1098
{
 
1099
    drawEntity(painter, container);     //      Draw all entities.
 
1100
 
 
1101
    //  If not in print preview, draw the absolute zero reference.
 
1102
    //  ----------------------------------------------------------
 
1103
    if (!isPrintPreview())
 
1104
        drawAbsoluteZero(painter);
 
1105
}
 
1106
 
 
1107
 
 
1108
void RS_GraphicView::drawLayer3(RS_Painter *painter) {
 
1109
    // drawing zero points:
 
1110
    if (!isPrintPreview()) {
 
1111
        drawRelativeZero(painter);
 
1112
        drawOverlay(painter);
 
1113
    }
 
1114
}
 
1115
 
 
1116
 
 
1117
/*      *
 
1118
 *      Function name:
 
1119
 *
 
1120
 *      Description:    - Sets the pen of the painter object to the suitable pen
 
1121
 *                                                for the given entity.
 
1122
 *
 
1123
 *      Author(s):              ..., Claude Sylvain
 
1124
 *      Created:                        ?
 
1125
 *      Last modified:  17 November 2011
 
1126
 *
 
1127
 *      Parameters:             RS_Painter *painter:
 
1128
 *                                                      ...
 
1129
 *
 
1130
 *                                              RS_Entity *e:
 
1131
 *                                                      ...
 
1132
 *
 
1133
 *      Returns:                        void
 
1134
 */
 
1135
 
 
1136
void RS_GraphicView::setPenForEntity(RS_Painter *painter,RS_Entity *e)
 
1137
{
 
1138
    if (draftMode) {
 
1139
        painter->setPen(RS_Pen(foreground,
 
1140
                               RS2::Width00, RS2::SolidLine));
 
1141
    }
 
1142
 
 
1143
    // Getting pen from entity (or layer)
 
1144
    RS_Pen pen = e->getPen(true);
 
1145
 
 
1146
    int w = pen.getWidth();
 
1147
    if (w<0) {
 
1148
        w = 0;
 
1149
    }
 
1150
 
 
1151
#if 1 /*TRUE*/
 
1152
        // - Scale pen width.
 
1153
        // - Notes: pen width is not scaled on print and print preview.
 
1154
        //   This is the standard (AutoCAD like) behaviour.
 
1155
    // bug# 3437941
 
1156
    // ------------------------------------------------------------
 
1157
    if (!draftMode)
 
1158
    {
 
1159
        double  uf = 1.0;       // Unit factor.
 
1160
        double  wf = 1.0;       // Width factor.
 
1161
 
 
1162
        RS_Graphic* graphic = container->getGraphic();
 
1163
 
 
1164
        if (graphic != NULL)
 
1165
        {
 
1166
            uf = RS_Units::convert(1.0, RS2::Millimeter, graphic->getUnit());
 
1167
 
 
1168
            if (        (isPrinting() || isPrintPreview()) &&
 
1169
                                        graphic->getPaperScale() > RS_TOLERANCE )
 
1170
            {
 
1171
                wf = 1.0 / graphic->getPaperScale();
 
1172
            }
 
1173
        }
 
1174
 
 
1175
        pen.setScreenWidth(toGuiDX(w / 100.0 * uf * wf));
 
1176
    }
 
1177
    else
 
1178
    {
 
1179
//              pen.setWidth(RS2::Width00);
 
1180
        pen.setScreenWidth(0);
 
1181
    }
 
1182
 
 
1183
#else
 
1184
 
 
1185
    // - Scale pen width.
 
1186
    // - Notes: pen width is scaled on print and print preview.
 
1187
    //   This is not the standard (AutoCAD like) behaviour.
 
1188
    // --------------------------------------------------------
 
1189
    if (!draftMode)
 
1190
    {
 
1191
        double  uf = 1.0;       //      Unit factor.
 
1192
 
 
1193
        RS_Graphic* graphic = container->getGraphic();
 
1194
 
 
1195
        if (graphic != NULL)
 
1196
            uf = RS_Units::convert(1.0, RS2::Millimeter, graphic->getUnit());
 
1197
 
 
1198
        pen.setScreenWidth(toGuiDX(w / 100.0 * uf));
 
1199
    }
 
1200
    else
 
1201
        pen.setScreenWidth(0);
 
1202
#endif
 
1203
 
 
1204
    // prevent drawing with 1-width which is slow:
 
1205
    if (RS_Math::round(pen.getScreenWidth())==1) {
 
1206
        pen.setScreenWidth(0.0);
 
1207
    }
 
1208
 
 
1209
    // prevent background color on background drawing:
 
1210
    if (pen.getColor().stripFlags()==background.stripFlags()) {
 
1211
        pen.setColor(foreground);
 
1212
    }
 
1213
 
 
1214
    // this entity is selected:
 
1215
    if (e->isSelected()) {
 
1216
        pen.setLineType(RS2::DotLine);
 
1217
        pen.setColor(selectedColor);
 
1218
    }
 
1219
 
 
1220
    // this entity is highlighted:
 
1221
    if (e->isHighlighted()) {
 
1222
        pen.setColor(highlightedColor);
 
1223
    }
 
1224
 
 
1225
    // deleting not drawing:
 
1226
    if (getDeleteMode()) {
 
1227
        pen.setColor(background);
 
1228
    }
 
1229
 
 
1230
    painter->setPen(pen);
 
1231
}
 
1232
 
 
1233
 
 
1234
/**
 
1235
 * Draws an entity. Might be recusively called e.g. for polylines.
 
1236
 * If the class wide painter is NULL a new painter will be created
 
1237
 * and destroyed afterwards.
 
1238
 *
 
1239
 * @param patternOffset Offset of line pattern (used for connected
 
1240
 *        lines e.g. in splines).
 
1241
 * @param db Double buffering on (recommended) / off
 
1242
 */
 
1243
void RS_GraphicView::drawEntity(RS_Entity* /*e*/, double& /*patternOffset*/) {
 
1244
    RS_DEBUG->print("RS_GraphicView::drawEntity(RS_Entity*,patternOffset) not supported anymore");
 
1245
    // RVT_PORT this needs to be optimized
 
1246
    // ONe way to do is to send a RS2::RedrawSelected, then teh draw routine will onyl draw all selected entities
 
1247
    // Dis-advantage is that we still need to iterate over all entities, but
 
1248
    // this might be very fast
 
1249
    // For now we just redraw the drawing untill we are going to optmize drawing
 
1250
    redraw(RS2::RedrawDrawing);
 
1251
}
 
1252
void RS_GraphicView::drawEntity(RS_Entity* /*e*/ /*patternOffset*/) {
 
1253
    RS_DEBUG->print("RS_GraphicView::drawEntity(RS_Entity*,patternOffset) not supported anymore");
 
1254
    // RVT_PORT this needs to be optimized
 
1255
    // ONe way to do is to send a RS2::RedrawSelected, then teh draw routine will onyl draw all selected entities
 
1256
    // Dis-advantage is that we still need to iterate over all entities, but
 
1257
    // this might be very fast
 
1258
    // For now we just redraw the drawing untill we are going to optmize drawing
 
1259
    redraw(RS2::RedrawDrawing);
 
1260
}
 
1261
void RS_GraphicView::drawEntity(RS_Painter *painter, RS_Entity* e) {
 
1262
    double offset(0.);
 
1263
    drawEntity(painter,e,offset);
 
1264
}
 
1265
void RS_GraphicView::drawEntity(RS_Painter *painter, RS_Entity* e, double& patternOffset) {
 
1266
 
 
1267
    // update is diabled:
 
1268
    // given entity is NULL:
 
1269
    if (e==NULL) {
 
1270
        return;
 
1271
    }
 
1272
 
 
1273
    // entity is not visible:
 
1274
    if (!e->isVisible()) {
 
1275
        return;
 
1276
    }
 
1277
    if( isPrintPreview() || isPrinting() ) {
 
1278
        //do not draw help layer on print preview or print
 
1279
            if(e->isHelpLayer()) return;
 
1280
    }
 
1281
 
 
1282
    // test if the entity is in the viewport
 
1283
    /* temporary disabled so rs_overlaylien can be drawn
 
1284
    if (!e->isContainer() && !isPrinting() &&
 
1285
            (painter==NULL || !painter->isPreviewMode()) &&
 
1286
            (toGuiX(e->getMax().x)<0 || toGuiX(e->getMin().x)>getWidth() ||
 
1287
             toGuiY(e->getMin().y)<0 || toGuiY(e->getMax().y)>getHeight())) {
 
1288
        return;
 
1289
    } */
 
1290
 
 
1291
    // set pen (color):
 
1292
    setPenForEntity(painter, e );
 
1293
 
 
1294
    //RS_DEBUG->print("draw plain");
 
1295
    if (isDraftMode()) {
 
1296
        // large mtexts as rectangles:
 
1297
        if (e->rtti()==RS2::EntityMText) {
 
1298
            if (toGuiDX(((RS_MText*)e)->getHeight())<4 || e->countDeep()>100) {
 
1299
                painter->drawRect(toGui(e->getMin()), toGui(e->getMax()));
 
1300
            } else {
 
1301
                drawEntityPlain(painter, e, patternOffset);
 
1302
            }
 
1303
        }
 
1304
        // large texts as rectangles:
 
1305
        else if (e->rtti()==RS2::EntityText) {
 
1306
            if (toGuiDX(((RS_Text*)e)->getHeight())<4 || e->countDeep()>100) {
 
1307
                painter->drawRect(toGui(e->getMin()), toGui(e->getMax()));
 
1308
            } else {
 
1309
                drawEntityPlain(painter, e, patternOffset);
 
1310
            }
 
1311
        }
 
1312
 
 
1313
        // all images as rectangles:
 
1314
        else if (e->rtti()==RS2::EntityImage) {
 
1315
            painter->drawRect(toGui(e->getMin()), toGui(e->getMax()));
 
1316
        }
 
1317
 
 
1318
        // hide hatches:
 
1319
        else if (e->rtti()==RS2::EntityHatch) {
 
1320
            // nothing
 
1321
        }
 
1322
 
 
1323
        else {
 
1324
            drawEntityPlain(painter, e, patternOffset);
 
1325
        }
 
1326
    } else {
 
1327
        drawEntityPlain(painter, e, patternOffset);
 
1328
    }
 
1329
 
 
1330
    // draw reference points:
 
1331
    if (e->isSelected()) {
 
1332
        if (!e->isParentSelected()) {
 
1333
            RS_VectorSolutions s = e->getRefPoints();
 
1334
 
 
1335
            for (int i=0; i<s.getNumber(); ++i) {
 
1336
                int sz = -1;
 
1337
                                RS_Color col = handleColor;
 
1338
                                if (i == 0) {
 
1339
                                        col = startHandleColor;
 
1340
                                }
 
1341
                                else if (i == s.getNumber() - 1) {
 
1342
                                        col = endHandleColor;
 
1343
                                }
 
1344
                if (getDeleteMode()) {
 
1345
                    painter->drawHandle(toGui(s.get(i)), background, sz);
 
1346
                } else {
 
1347
                    painter->drawHandle(toGui(s.get(i)), col, sz);
 
1348
                }
 
1349
            }
 
1350
        }
 
1351
    }
 
1352
 
 
1353
    //RS_DEBUG->print("draw plain OK");
 
1354
 
 
1355
 
 
1356
    //RS_DEBUG->print("RS_GraphicView::drawEntity() end");
 
1357
}
 
1358
 
 
1359
 
 
1360
/**
 
1361
 * Draws an entity.
 
1362
 * The painter must be initialized and all the attributes (pen) must be set.
 
1363
 */
 
1364
void RS_GraphicView::drawEntityPlain(RS_Painter *painter, RS_Entity* e, double& patternOffset) {
 
1365
    if (e==NULL) {
 
1366
        return;
 
1367
    }
 
1368
 
 
1369
    if (!e->isContainer() && (e->isSelected()!=painter->shouldDrawSelected())) {
 
1370
        return;
 
1371
    }
 
1372
 
 
1373
    e->draw(painter, this, patternOffset);
 
1374
 
 
1375
}
 
1376
void RS_GraphicView::drawEntityPlain(RS_Painter *painter, RS_Entity* e) {
 
1377
    if (e==NULL) {
 
1378
        return;
 
1379
    }
 
1380
 
 
1381
    if (!e->isContainer() && (e->isSelected()!=painter->shouldDrawSelected())) {
 
1382
        return;
 
1383
    }
 
1384
    double patternOffset(0.);
 
1385
    e->draw(painter, this, patternOffset);
 
1386
 
 
1387
}
 
1388
/**
 
1389
 * Deletes an entity with the background color.
 
1390
 * Might be recusively called e.g. for polylines.
 
1391
 */
 
1392
void RS_GraphicView::deleteEntity(RS_Entity* e) {
 
1393
 
 
1394
    // RVT_PORT When we delete a single entoty, we can do this but we need to remove this then also from containerEntities
 
1395
    RS_DEBUG->print("RS_GraphicView::deleteEntity will for now redraw the whole screen instead of just deleting the entity");
 
1396
    setDeleteMode(true);
 
1397
    drawEntity(e);
 
1398
    setDeleteMode(false);
 
1399
    redraw(RS2::RedrawDrawing);
 
1400
}
 
1401
 
 
1402
 
 
1403
 
 
1404
 
 
1405
/**
 
1406
 * @return Pointer to the static pattern struct that belongs to the
 
1407
 * given pattern type or NULL.
 
1408
 */
 
1409
RS_LineTypePattern* RS_GraphicView::getPattern(RS2::LineType t) {
 
1410
    switch (t) {
 
1411
    case RS2::SolidLine:
 
1412
        return &patternSolidLine;
 
1413
        break;
 
1414
 
 
1415
    case RS2::DotLine:
 
1416
        return &patternDotLine;
 
1417
        break;
 
1418
    case RS2::DotLine2:
 
1419
        return &patternDotLine2;
 
1420
        break;
 
1421
    case RS2::DotLineX2:
 
1422
        return &patternDotLineX2;
 
1423
        break;
 
1424
 
 
1425
    case RS2::DashLine:
 
1426
        return &patternDashLine;
 
1427
        break;
 
1428
    case RS2::DashLine2:
 
1429
        return &patternDashLine2;
 
1430
        break;
 
1431
    case RS2::DashLineX2:
 
1432
        return &patternDashLineX2;
 
1433
        break;
 
1434
 
 
1435
    case RS2::DashDotLine:
 
1436
        return &patternDashDotLine;
 
1437
        break;
 
1438
    case RS2::DashDotLine2:
 
1439
        return &patternDashDotLine2;
 
1440
        break;
 
1441
    case RS2::DashDotLineX2:
 
1442
        return &patternDashDotLineX2;
 
1443
        break;
 
1444
 
 
1445
    case RS2::DivideLine:
 
1446
        return &patternDivideLine;
 
1447
        break;
 
1448
    case RS2::DivideLine2:
 
1449
        return &patternDivideLine2;
 
1450
        break;
 
1451
    case RS2::DivideLineX2:
 
1452
        return &patternDivideLineX2;
 
1453
        break;
 
1454
 
 
1455
    case RS2::CenterLine:
 
1456
        return &patternCenterLine;
 
1457
        break;
 
1458
    case RS2::CenterLine2:
 
1459
        return &patternCenterLine2;
 
1460
        break;
 
1461
    case RS2::CenterLineX2:
 
1462
        return &patternCenterLineX2;
 
1463
        break;
 
1464
 
 
1465
    case RS2::BorderLine:
 
1466
        return &patternBorderLine;
 
1467
        break;
 
1468
    case RS2::BorderLine2:
 
1469
        return &patternBorderLine2;
 
1470
        break;
 
1471
    case RS2::BorderLineX2:
 
1472
        return &patternBorderLineX2;
 
1473
        break;
 
1474
 
 
1475
    case RS2::LineByLayer:
 
1476
        return &patternBlockLine;
 
1477
        break;
 
1478
    case RS2::LineByBlock:
 
1479
        return &patternBlockLine;
 
1480
        break;
 
1481
    default:
 
1482
        break;
 
1483
    }
 
1484
    return NULL;
 
1485
}
 
1486
 
 
1487
 
 
1488
 
 
1489
/**
 
1490
 * This virtual method can be overwritten to draw the absolute
 
1491
 * zero. It's called from within drawIt(). The default implemetation
 
1492
 * draws a simple red cross on the zero of thge sheet
 
1493
 * THis function can ONLY be called from within a paintEvent because it will
 
1494
 * use the painter
 
1495
 *
 
1496
 * @see drawIt()
 
1497
 */
 
1498
void RS_GraphicView::drawAbsoluteZero(RS_Painter *painter) {
 
1499
 
 
1500
    int zr = 20;
 
1501
 
 
1502
    RS_Pen p(QColor(255,0,0), RS2::Width00, RS2::SolidLine);
 
1503
    p.setScreenWidth(0);
 
1504
    painter->setPen(p);
 
1505
    //painter->setBrush(Qt::NoBrush);
 
1506
 
 
1507
    painter->drawLine(RS_Vector(toGuiX(0.0)-zr,
 
1508
                                toGuiY(0.0)),
 
1509
                      RS_Vector(toGuiX(0.0)+zr,
 
1510
                                toGuiY(0.0)));
 
1511
 
 
1512
    painter->drawLine(RS_Vector(toGuiX(0.0),
 
1513
                                toGuiY(0.0)-zr),
 
1514
                      RS_Vector(toGuiX(0.0),
 
1515
                                toGuiY(0.0)+zr));
 
1516
 
 
1517
}
 
1518
 
 
1519
 
 
1520
 
 
1521
/**
 
1522
 * This virtual method can be overwritten to draw the relative
 
1523
 * zero point. It's called from within drawIt(). The default implemetation
 
1524
 * draws a simple red round zero point. This is the point that was last created by the user, end of a line for example
 
1525
 * THis function can ONLY be called from within a paintEvent because it will
 
1526
 * use the painter
 
1527
 *
 
1528
 * @see drawIt()
 
1529
 */
 
1530
void RS_GraphicView::drawRelativeZero(RS_Painter *painter) {
 
1531
 
 
1532
    if (relativeZero.valid==false) {
 
1533
        return;
 
1534
    }
 
1535
 
 
1536
    RS_Pen p(RS_Color(255, 0, 0), RS2::Width00, RS2::SolidLine);
 
1537
    p.setScreenWidth(0);
 
1538
    painter->setPen(p);
 
1539
 
 
1540
    int zr=5;
 
1541
 
 
1542
    painter->drawLine(RS_Vector(toGuiX(relativeZero.x)-zr,
 
1543
                                toGuiY(relativeZero.y)),
 
1544
                      RS_Vector(toGuiX(relativeZero.x)+zr,
 
1545
                                toGuiY(relativeZero.y)));
 
1546
 
 
1547
    painter->drawLine(RS_Vector(toGuiX(relativeZero.x),
 
1548
                                toGuiY(relativeZero.y)-zr),
 
1549
                      RS_Vector(toGuiX(relativeZero.x),
 
1550
                                toGuiY(relativeZero.y)+zr));
 
1551
 
 
1552
    painter->drawCircle(toGui(relativeZero), 5);
 
1553
}
 
1554
 
 
1555
 
 
1556
 
 
1557
/**
 
1558
 * Draws the paper border (for print previews).
 
1559
 * This function can ONLY be called from within a paintEvent because it will
 
1560
 * use the painter
 
1561
 *
 
1562
 * @see drawIt()
 
1563
 */
 
1564
void RS_GraphicView::drawPaper(RS_Painter *painter) {
 
1565
 
 
1566
    if (container==NULL) {
 
1567
        return;
 
1568
    }
 
1569
 
 
1570
    RS_Graphic* graphic = container->getGraphic();
 
1571
    if (graphic->getPaperScale()<1.0e-6) {
 
1572
        return;
 
1573
    }
 
1574
 
 
1575
    // draw paper:
 
1576
    // RVT_PORT rewritten from     painter->setPen(Qt::gray);
 
1577
    painter->setPen(QColor(Qt::gray));
 
1578
 
 
1579
    RS_Vector pinsbase = graphic->getPaperInsertionBase();
 
1580
    RS_Vector size = graphic->getPaperSize();
 
1581
    double scale = graphic->getPaperScale();
 
1582
 
 
1583
    RS_Vector v1 = toGui((RS_Vector(0,0)-pinsbase)/scale);
 
1584
    RS_Vector v2 = toGui((size-pinsbase)/scale);
 
1585
 
 
1586
    // gray background:
 
1587
    painter->fillRect(0,0, getWidth(), getHeight(),
 
1588
                      RS_Color(200,200,200));
 
1589
 
 
1590
    // shadow
 
1591
    painter->fillRect(
 
1592
                (int)(v1.x)+6, (int)(v1.y)+6,
 
1593
                (int)((v2.x-v1.x)), (int)((v2.y-v1.y)),
 
1594
                RS_Color(64,64,64));
 
1595
 
 
1596
    // border:
 
1597
    painter->fillRect(
 
1598
                (int)(v1.x), (int)(v1.y),
 
1599
                (int)((v2.x-v1.x)), (int)((v2.y-v1.y)),
 
1600
                RS_Color(64,64,64));
 
1601
 
 
1602
    // paper
 
1603
    painter->fillRect(
 
1604
                (int)(v1.x)+1, (int)(v1.y)-1,
 
1605
                (int)((v2.x-v1.x))-2, (int)((v2.y-v1.y))+2,
 
1606
                RS_Color(255,255,255));
 
1607
 
 
1608
}
 
1609
 
 
1610
 
 
1611
/**
 
1612
 * Draws the grid.
 
1613
 *
 
1614
 * @see drawIt()
 
1615
 */
 
1616
void RS_GraphicView::drawGrid(RS_Painter *painter) {
 
1617
 
 
1618
    if (grid==NULL || isGridOn()==false) {
 
1619
        return;
 
1620
    }
 
1621
 
 
1622
 
 
1623
    // draw grid:
 
1624
    //painter->setPen(Qt::gray);
 
1625
    painter->setPen(gridColor);
 
1626
 
 
1627
//    grid->updatePointArray();
 
1628
    RS_Vector* pts = grid->getPoints();
 
1629
    if (pts!=NULL) {
 
1630
        for (int i=0; i<grid->count(); ++i) {
 
1631
            painter->drawGridPoint(toGui(pts[i]));
 
1632
        }
 
1633
    }
 
1634
 
 
1635
    // draw grid info:
 
1636
    //painter->setPen(Qt::white);
 
1637
    QString info = grid->getInfo();
 
1638
    //info = QString("%1 / %2")
 
1639
    //       .arg(grid->getSpacing())
 
1640
    //       .arg(grid->getMetaSpacing());
 
1641
 
 
1642
    updateGridStatusWidget(info);
 
1643
 
 
1644
 
 
1645
}
 
1646
 
 
1647
 
 
1648
 
 
1649
/**
 
1650
 * Draws the meta grid.
 
1651
 *
 
1652
 * @see drawIt()
 
1653
 */
 
1654
void RS_GraphicView::drawMetaGrid(RS_Painter *painter) {
 
1655
 
 
1656
    if (grid==NULL || isGridOn()==false /*|| grid->getMetaSpacing()<0.0*/) {
 
1657
        return;
 
1658
    }
 
1659
 
 
1660
    //draw grid after metaGrid to avoid overwriting grid points by metaGrid lines
 
1661
    //bug# 3430258
 
1662
    grid->updatePointArray();
 
1663
    RS_Pen pen(metaGridColor,
 
1664
               RS2::Width00,
 
1665
               RS2::DotLine);
 
1666
    painter->setPen(pen);
 
1667
 
 
1668
        RS_Vector dv=grid->getMetaGridWidth().scale(factor);
 
1669
        double dx=fabs(dv.x);
 
1670
        double dy=fabs(dv.y); //potential bug, need to recover metaGrid.width
 
1671
    // draw meta grid:
 
1672
        double* mx = grid->getMetaX();
 
1673
        if (mx!=NULL) {
 
1674
            for (int i=0; i<grid->countMetaX(); ++i) {
 
1675
                painter->drawLine(RS_Vector(toGuiX(mx[i]), 0),
 
1676
                                  RS_Vector(toGuiX(mx[i]), getHeight()));
 
1677
                if(grid->isIsometric()){
 
1678
                    painter->drawLine(RS_Vector(toGuiX(mx[i])+0.5*dx, 0),
 
1679
                                      RS_Vector(toGuiX(mx[i])+0.5*dx, getHeight()));
 
1680
                }
 
1681
            }
 
1682
        }
 
1683
    double* my = grid->getMetaY();
 
1684
    if(grid->isIsometric()){//isometric metaGrid
 
1685
        dx=fabs(dx);
 
1686
        dy=fabs(dy);
 
1687
        if(my==NULL || dx<1||dy<1) return;
 
1688
        RS_Vector baseMeta(toGui(RS_Vector(mx[0],my[0])));
 
1689
        // x-x0=k*dx, x-remainder(x-x0,dx)
 
1690
        RS_Vector vp0(-remainder(-baseMeta.x,dx)-dx,getHeight()-remainder(getHeight()-baseMeta.y,dy)+dy);
 
1691
        RS_Vector vp1(vp0);
 
1692
        RS_Vector vp2(getWidth()-remainder(getWidth()-baseMeta.x,dx)+dx,vp0.y);
 
1693
        RS_Vector vp3(vp2);
 
1694
        int cmx = round((vp2.x - vp0.x)/dx);
 
1695
        int cmy = round((vp0.y +remainder(-baseMeta.y,dy)+dy)/dy);
 
1696
        for(int i=cmx+cmy+2;i>=0;i--){
 
1697
            if ( i <= cmx ) {
 
1698
                vp0.x += dx;
 
1699
                vp2.y -= dy;
 
1700
            }else{
 
1701
                vp0.y -= dy;
 
1702
                vp2.x -= dx;
 
1703
            }
 
1704
            if ( i <= cmy ) {
 
1705
                vp1.y -= dy;
 
1706
                vp3.x -= dx;
 
1707
            }else{
 
1708
                vp1.x += dx;
 
1709
                vp3.y -= dy;
 
1710
            }
 
1711
            painter->drawLine(vp0,vp1);
 
1712
            painter->drawLine(vp2,vp3);
 
1713
        }
 
1714
 
 
1715
    }else{//orthogonal
 
1716
 
 
1717
        if (my!=NULL) {
 
1718
            for (int i=0; i<grid->countMetaY(); ++i) {
 
1719
                painter->drawLine(RS_Vector(0, toGuiY(my[i])),
 
1720
                                  RS_Vector(getWidth(), toGuiY(my[i])));
 
1721
            }
 
1722
        }
 
1723
    }
 
1724
 
 
1725
 
 
1726
}
 
1727
 
 
1728
void RS_GraphicView::drawOverlay(RS_Painter *painter) {
 
1729
    QList<int> keys=overlayEntities.keys();
 
1730
    for (int i = 0; i < keys.size(); ++i) {
 
1731
        if (overlayEntities[i] != NULL) {
 
1732
            setPenForEntity(painter, overlayEntities[i] );
 
1733
            drawEntityPlain(painter, overlayEntities[i]);
 
1734
        }
 
1735
    }
 
1736
}
 
1737
 
 
1738
/**
 
1739
 * Sets the default snap mode used by newly created actions.
 
1740
 */
 
1741
void RS_GraphicView::setDefaultSnapMode(RS_SnapMode sm) {
 
1742
    defaultSnapMode = sm;
 
1743
    if (eventHandler!=NULL) {
 
1744
        eventHandler->setSnapMode(sm);
 
1745
    }
 
1746
}
 
1747
 
 
1748
 
 
1749
 
 
1750
/**
 
1751
 * Sets a snap restriction (e.g. orthogonal).
 
1752
 */
 
1753
void RS_GraphicView::setSnapRestriction(RS2::SnapRestriction sr) {
 
1754
    defaultSnapRes = sr;
 
1755
 
 
1756
    if (eventHandler!=NULL) {
 
1757
        eventHandler->setSnapRestriction(sr);
 
1758
    }
 
1759
}
 
1760
 
 
1761
 
 
1762
 
 
1763
/**
 
1764
 * Translates a vector in real coordinates to a vector in screen coordinates.
 
1765
 */
 
1766
RS_Vector RS_GraphicView::toGui(RS_Vector v) {
 
1767
    return RS_Vector(toGuiX(v.x), toGuiY(v.y));
 
1768
}
 
1769
 
 
1770
 
 
1771
 
 
1772
/**
 
1773
 * Translates a real coordinate in X to a screen coordinate X.
 
1774
 * @param visible Pointer to a boolean which will contain true
 
1775
 * after the call if the coordinate is within the visible range.
 
1776
 */
 
1777
double RS_GraphicView::toGuiX(double x) {
 
1778
    return x*factor.x + offsetX;
 
1779
}
 
1780
 
 
1781
 
 
1782
 
 
1783
/**
 
1784
 * Translates a real coordinate in Y to a screen coordinate Y.
 
1785
 */
 
1786
double RS_GraphicView::toGuiY(double y) {
 
1787
    return -y*factor.y + getHeight() - offsetY;
 
1788
}
 
1789
 
 
1790
 
 
1791
 
 
1792
/**
 
1793
 * Translates a real coordinate distance to a screen coordinate distance.
 
1794
 */
 
1795
double RS_GraphicView::toGuiDX(double d) {
 
1796
    return d*factor.x;
 
1797
}
 
1798
 
 
1799
 
 
1800
 
 
1801
/**
 
1802
 * Translates a real coordinate distance to a screen coordinate distance.
 
1803
 */
 
1804
double RS_GraphicView::toGuiDY(double d) {
 
1805
    return d*factor.y;
 
1806
}
 
1807
 
 
1808
 
 
1809
 
 
1810
/**
 
1811
 * Translates a vector in screen coordinates to a vector in real coordinates.
 
1812
 */
 
1813
RS_Vector RS_GraphicView::toGraph(RS_Vector v) {
 
1814
    return RS_Vector(toGraphX(RS_Math::round(v.x)),
 
1815
                     toGraphY(RS_Math::round(v.y)));
 
1816
}
 
1817
 
 
1818
 
 
1819
 
 
1820
/**
 
1821
 * Translates two screen coordinates to a vector in real coordinates.
 
1822
 */
 
1823
RS_Vector RS_GraphicView::toGraph(int x, int y) {
 
1824
    return RS_Vector(toGraphX(x), toGraphY(y));
 
1825
}
 
1826
 
 
1827
 
 
1828
/**
 
1829
 * Translates a screen coordinate in X to a real coordinate X.
 
1830
 */
 
1831
double RS_GraphicView::toGraphX(int x) {
 
1832
    return (x - offsetX)/factor.x;
 
1833
}
 
1834
 
 
1835
 
 
1836
 
 
1837
/**
 
1838
 * Translates a screen coordinate in Y to a real coordinate Y.
 
1839
 */
 
1840
double RS_GraphicView::toGraphY(int y) {
 
1841
    return -(y - getHeight() + offsetY)/factor.y;
 
1842
}
 
1843
 
 
1844
 
 
1845
 
 
1846
/**
 
1847
 * Translates a screen coordinate distance to a real coordinate distance.
 
1848
 */
 
1849
double RS_GraphicView::toGraphDX(int d) {
 
1850
    return d/factor.x;
 
1851
}
 
1852
 
 
1853
 
 
1854
 
 
1855
/**
 
1856
 * Translates a screen coordinate distance to a real coordinate distance.
 
1857
 */
 
1858
double RS_GraphicView::toGraphDY(int d) {
 
1859
    return d/factor.y;
 
1860
}
 
1861
 
 
1862
 
 
1863
/**
 
1864
 * Sets the relative zero coordinate (if not locked)
 
1865
 * without deleting / drawing the point.
 
1866
 */
 
1867
void RS_GraphicView::setRelativeZero(const RS_Vector& pos) {
 
1868
    if (relativeZeroLocked==false) {
 
1869
        relativeZero = pos;
 
1870
    }
 
1871
}
 
1872
 
 
1873
 
 
1874
 
 
1875
/**
 
1876
 * Sets the relative zero coordinate, deletes the old position
 
1877
 * on the screen and draws the new one.
 
1878
 */
 
1879
void RS_GraphicView::moveRelativeZero(const RS_Vector& pos) {
 
1880
    setRelativeZero(pos);
 
1881
    redraw(RS2::RedrawGrid);
 
1882
}
 
1883
 
 
1884
 
 
1885
/**
 
1886
 * Remove all overlay entities
 
1887
 */
 
1888
RS_EntityContainer* RS_GraphicView::getOverlayContainer(RS2::OverlayGraphics position)
 
1889
{
 
1890
    if (overlayEntities[position]!=NULL) {
 
1891
        return overlayEntities[position];
 
1892
    }
 
1893
    overlayEntities[position]=new RS_EntityContainer(NULL);
 
1894
 
 
1895
    return overlayEntities[position];
 
1896
 
 
1897
}
 
1898
 
 
1899