FreeCAD

Форк
0
/
TaskOrthoViews.cpp 
1445 строк · 42.6 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2014 Joe Dowsett <dowsettjoe[at]yahoo[dot]co[dot]uk>    *
3
 *                                                                         *
4
 *   This file is part of the FreeCAD CAx development system.              *
5
 *                                                                         *
6
 *   This library is free software; you can redistribute it and/or         *
7
 *   modify it under the terms of the GNU Library General Public           *
8
 *   License as published by the Free Software Foundation; either          *
9
 *   version 2 of the License, or (at your option) any later version.      *
10
 *                                                                         *
11
 *   This library  is distributed in the hope that it will be useful,      *
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14
 *   GNU Library General Public License for more details.                  *
15
 *                                                                         *
16
 *   You should have received a copy of the GNU Library General Public     *
17
 *   License along with this library; see the file COPYING.LIB. If not,    *
18
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
19
 *   Suite 330, Boston, MA  02111-1307, USA                                *
20
 *                                                                         *
21
 ***************************************************************************/
22

23
#include "PreCompiled.h"
24
#ifndef _PreComp_
25
#include <QLineEdit>
26
#include <QMenu>
27
#endif
28

29
#include <App/Document.h>
30
#include <Gui/Application.h>
31
#include <Gui/BitmapFactory.h>
32
#include <Gui/Control.h>
33
#include <Mod/Drawing/App/FeaturePage.h>
34
#include <Mod/Part/App/PartFeature.h>
35

36
#include "TaskOrthoViews.h"
37
#include "ui_TaskOrthoViews.h"
38

39

40
using namespace Gui;
41
using namespace DrawingGui;
42
using namespace std;
43
namespace bp = boost::placeholders;
44

45
#if 0  // needed for Qt's lupdate utility
46
    qApp->translate("QObject", "Make axonometric...");
47
    qApp->translate("QObject", "Edit axonometric settings...");
48
    qApp->translate("QObject", "Make orthographic");
49
#endif
50

51

52
void pagesize(string& page_template, int dims[4], int block[4])
53
{
54
    dims[0] = 10;  // default to A4_Landscape with 10mm margins
55
    dims[1] = 10;
56
    dims[2] = 287;
57
    dims[3] = 200;
58

59
    block[0] = block[1] = 0;  // default to no title block
60
    block[2] = block[3] = 0;
61

62
    int t0, t1, t2, t3 = 0;
63

64
    // code below copied from FeaturePage.cpp
65
    Base::FileInfo fi(page_template);
66
    if (!fi.isReadable()) {
67
        fi.setFile(App::Application::getResourceDir() + "Mod/Drawing/Templates/" + fi.fileName());
68
        if (!fi.isReadable()) {  // if so then really shouldn't have been able to get this far, but
69
                                 // just in case...
70
            return;
71
        }
72
    }
73

74
    // open Template file
75
    string line;
76
    ifstream file(fi.filePath().c_str());
77

78
    try {
79
        while (getline(file, line)) {
80
            if (line.find("<!-- Working space") != string::npos) {
81
                (void)sscanf(line.c_str(),
82
                             "%*s %*s %*s %d %d %d %d",
83
                             &dims[0],
84
                             &dims[1],
85
                             &dims[2],
86
                             &dims[3]);  // eg "    <!-- Working space 10 10 410 287 -->"
87
                getline(file, line);
88

89
                if (line.find("<!-- Title block") != string::npos) {
90
                    (void)sscanf(line.c_str(),
91
                                 "%*s %*s %*s %d %d %d %d",
92
                                 &t0,
93
                                 &t1,
94
                                 &t2,
95
                                 &t3);  // eg "    <!-- Working space 10 10 410 287 -->"
96
                }
97

98
                break;
99
            }
100

101
            if (line.find("metadata") != string::npos) {  // give up if we meet a metadata tag
102
                break;
103
            }
104
        }
105
    }
106
    catch (Standard_Failure&) {
107
    }
108

109

110
    if (t3 != 0) {
111
        block[2] = t2 - t0;  // block width
112
        block[3] = t3 - t1;  // block height
113

114
        if (t0 <= dims[0]) {  // title block on left
115
            block[0] = -1;
116
        }
117
        else if (t2 >= dims[2]) {  // title block on right
118
            block[0] = 1;
119
        }
120

121
        if (t1 <= dims[1]) {  // title block at top
122
            block[1] = 1;
123
        }
124
        else if (t3 >= dims[3]) {  // title block at bottom
125
            block[1] = -1;
126
        }
127
    }
128

129
    dims[2] -= dims[0];  // width
130
    dims[3] -= dims[1];  // height
131
}
132

133

134
///////////////////////////////////////////////////////////////////////////////////////////////
135
///////////////////////////////////////////////////////////////////////////////////////////////
136
///////////////////////////////////////////////////////////////////////////////////////////////
137

138
orthoview::orthoview(App::Document* parent,
139
                     App::DocumentObject* part,
140
                     App::DocumentObject* page,
141
                     Base::BoundBox3d* partbox)
142
{
143
    parent_doc = parent;
144
    myname = parent_doc->getUniqueObjectName("Ortho");
145

146
    x = 0;
147
    y = 0;
148
    cx = partbox->GetCenter().x;
149
    cy = partbox->GetCenter().y;
150
    cz = partbox->GetCenter().z;
151

152
    this_view = static_cast<Drawing::FeatureViewPart*>(
153
        parent_doc->addObject("Drawing::FeatureViewPart", myname.c_str()));
154
    static_cast<App::DocumentObjectGroup*>(page)->addObject(this_view);
155
    this_view->Source.setValue(part);
156

157
    pageX = 0;
158
    pageY = 0;
159
    scale = 1;
160

161
    rel_x = 0;
162
    rel_y = 0;
163
    ortho = true;
164
    auto_scale = true;
165

166
    away = false;
167
    tri = false;
168
    axo = 0;
169
}
170

171
orthoview::~orthoview()
172
{}
173

174
void orthoview::set_data(int r_x, int r_y)
175
{
176
    rel_x = r_x;
177
    rel_y = r_y;
178

179
    char label[15];
180
    sprintf(label, "Ortho_%i_%i", rel_x, rel_y);  // label name for view, based on relative position
181

182
    this_view->Label.setValue(label);
183
    ortho = ((rel_x * rel_y) == 0);
184
}
185

186
void orthoview::deleteme()
187
{
188
    parent_doc->removeObject(myname.c_str());
189
}
190

191
void orthoview::setPos(float px, float py)
192
{
193
    if (px != 0 && py != 0) {
194
        pageX = px;
195
        pageY = py;
196
    }
197

198
    float ox = pageX - scale * x;
199
    float oy = pageY + scale * y;
200

201
    this_view->X.setValue(ox);
202
    this_view->Y.setValue(oy);
203
}
204

205
void orthoview::setScale(float newScale)
206
{
207
    scale = newScale;
208
    this_view->Scale.setValue(scale);
209
}
210

211
float orthoview::getScale()
212
{
213
    return scale;
214
}
215

216
void orthoview::calcCentre()
217
{
218
    x = X_dir.X() * cx + X_dir.Y() * cy + X_dir.Z() * cz;
219
    y = Y_dir.X() * cx + Y_dir.Y() * cy + Y_dir.Z() * cz;
220
}
221

222
void orthoview::hidden(bool state)
223
{
224
    this_view->ShowHiddenLines.setValue(state);
225
}
226

227
void orthoview::smooth(bool state)
228
{
229
    this_view->ShowSmoothLines.setValue(state);
230
}
231

232
void orthoview::set_projection(const gp_Ax2& cs)
233
{
234
    gp_Ax2 actual_cs;
235
    gp_Dir actual_X;
236

237
    // coord system & directions for desired projection
238
    X_dir = cs.XDirection();
239
    Y_dir = cs.YDirection();
240
    Z_dir = cs.Direction();
241

242
    // coord system of created view - same code as used in projection algos
243
    // actual_cs = gp_Ax2(gp_Pnt(0,0,0), gp_Dir(Z_dir.X(),Z_dir.Y(),Z_dir.Z()));
244

245
    // but as the file gets saved the projection direction gets rounded.
246
    // this can lead to choosing a different normal x-direction when the file
247
    // gets reloaded see issue #1909
248
    // we anticipate the actual_cs after reloading by rounding the Z_dir now
249
    const double x = round(Z_dir.X() * 1e12) / 1e12;
250
    const double y = round(Z_dir.Y() * 1e12) / 1e12;
251
    const double z = round(Z_dir.Z() * 1e12) / 1e12;
252
    actual_cs = gp_Ax2(gp_Pnt(0, 0, 0), gp_Dir(x, y, z));
253

254
    actual_X = actual_cs.XDirection();
255

256
    // angle between desired projection and actual projection
257
    float rotation = X_dir.Angle(actual_X);
258

259
    if (rotation != 0 && abs(M_PI - rotation) > 0.05) {
260
        if (!Z_dir.IsEqual(actual_X.Crossed(X_dir), 0.05)) {
261
            rotation = -rotation;
262
        }
263
    }
264

265
    calcCentre();
266

267
    // this_view->Direction.setValue(Z_dir.X(), Z_dir.Y(), Z_dir.Z());
268
    this_view->Direction.setValue(x, y, z);
269
    this_view->Rotation.setValue(180 * rotation / M_PI);
270
}
271

272
///////////////////////////////////////////////////////////////////////////////////////////////
273
///////////////////////////////////////////////////////////////////////////////////////////////
274
///////////////////////////////////////////////////////////////////////////////////////////////
275

276
OrthoViews::OrthoViews(App::Document* doc, const char* pagename, const char* partname)
277
{
278
    horiz = nullptr;
279
    vert = nullptr;
280

281
    parent_doc = doc;
282
    parent_doc->openTransaction("Create view");
283

284
    part = parent_doc->getObject(partname);
285
    bbox.Add(static_cast<Part::Feature*>(part)->Shape.getBoundingBox());
286

287
    page = parent_doc->getObject(pagename);
288
    Gui::Application::Instance->showViewProvider(page);
289
    load_page();
290

291
    min_space = 15;  // should be preferenced
292

293
    min_r_x = max_r_x = 0;
294
    min_r_y = max_r_y = 0;
295

296
    rotate_coeff = 1;
297
    smooth = false;
298
    hidden = false;
299
    autodims = true;
300

301
    width = height = depth = 0;
302
    layout_width = layout_height = 0;
303
    gap_x = gap_y = 0;
304
    offset_x = offset_y = 0;
305
    scale = 0;
306
    num_gaps_x = num_gaps_y = 0;
307

308
    this->connectDocumentDeletedObject =
309
        doc->signalDeletedObject.connect(boost::bind(&OrthoViews::slotDeletedObject, this, bp::_1));
310
    this->connectApplicationDeletedDocument = App::GetApplication().signalDeleteDocument.connect(
311
        boost::bind(&OrthoViews::slotDeletedDocument, this, bp::_1));
312
}
313

314
OrthoViews::~OrthoViews()
315
{
316
    for (int i = views.size() - 1; i >= 0; i--) {
317
        delete views[i];
318
    }
319

320
    try {
321
        page->recomputeFeature();
322
    }
323
    catch (...) {
324
    }
325
}
326

327
void OrthoViews::slotDeletedDocument(const App::Document& Obj)
328
{
329
    if (parent_doc == &Obj) {
330
        Gui::Control().closeDialog();
331
    }
332
}
333

334
void OrthoViews::slotDeletedObject(const App::DocumentObject& Obj)
335
{
336
    if (page == &Obj || part == &Obj) {
337
        Gui::Control().closeDialog();
338
    }
339
    else {
340
        for (std::vector<orthoview*>::iterator it = views.begin(); it != views.end(); ++it) {
341
            if ((*it)->getViewPart() == &Obj) {
342
                views.erase(it);
343
                break;
344
            }
345
        }
346
    }
347
}
348

349
void OrthoViews::load_page()
350
{
351
    string template_name = static_cast<Drawing::FeaturePage*>(page)->Template.getValue();
352
    pagesize(template_name, large, block);
353
    page_dims = large;
354

355
    // process page dims for title block data
356
    if (block[0] != 0) {
357
        title = true;
358

359
        // max vertical space avoiding title block
360
        small_v[1] = large[1];             // y margin same as large page
361
        small_v[3] = large[3];             // y size same as large page
362
        small_v[2] = large[2] - block[2];  // x width same as large width - block width
363
        if (block[0] == -1) {
364
            small_v[0] = large[0] + block[2];  // x margin same as large + block width
365
            horiz = &min_r_x;
366
        }
367
        else {
368
            small_v[0] = large[0];  // x margin same as large
369
            horiz = &max_r_x;
370
        }
371

372
        // max horizontal space avoiding title block
373
        small_h[0] = large[0];
374
        small_h[2] = large[2];
375
        small_h[3] = large[3] - block[3];
376
        if (block[1] == 1) {
377
            small_h[1] = large[1] + block[3];
378
            vert = &max_r_y;
379
        }
380
        else {
381
            small_h[1] = large[1];
382
            vert = &min_r_y;
383
        }
384
    }
385
    else {
386
        title = false;
387
    }
388
}
389

390
void OrthoViews::calc_layout_size()  // calculate the real world size of given view layout, assuming
391
                                     // no space
392
{
393
    // note that views in relative positions x = -4, -2, 0 , 2 etc etc
394
    // have width = orientated part width
395
    // while those in relative positions x = -3, -1, 1 etc
396
    // have width = orientated part depth
397

398
    // similarly in y positions, height = part height or depth
399

400
    layout_width = (1 + floor(max_r_x / 2.0) + floor(-min_r_x / 2.0)) * width;
401
    layout_width += (ceil(max_r_x / 2.0) + ceil(-min_r_x / 2.0)) * depth;
402
    layout_height = (1 + floor(max_r_y / 2.0) + floor(-min_r_y / 2.0)) * height;
403
    layout_height += (ceil(max_r_y / 2.0) + ceil(-min_r_y / 2.0)) * depth;
404
}
405

406
void OrthoViews::choose_page()  // chooses which bit of page space to use depending upon layout &
407
                                // titleblock
408
{
409
    int h = abs(*horiz);  // how many views in direction of title block  (horiz points to min_r_x or
410
                          // max_r_x)
411
    int v = abs(*vert);
412
    float layout_corner_width = (1 + floor(h / 2.0)) * width
413
        + ceil(h / 2.0) * depth;  // from (0, 0) view inclusively, how wide and tall is the layout
414
                                  // in the direction of the title block
415
    float layout_corner_height = (1 + floor(v / 2.0)) * height + ceil(v / 2.0) * depth;
416
    float rel_space_x = layout_corner_width / layout_width
417
        - 1.0 * block[2] / large[2];  // relative to respective sizes, how much space between (0, 0)
418
                                      // and title block,
419
    float rel_space_y = layout_corner_height / layout_height
420
        - 1.0 * block[3] / large[3];  //                      can be -ve if block extends into /
421
                                      //                      beyond (0, 0) view
422
    float view_x, view_y, v_x_r, v_y_r;
423
    bool interferes = false;
424
    float a, b;
425

426
    for (int i = min_r_x; i <= max_r_x; i++) {
427
        for (int j = min_r_y; j <= max_r_y; j++) {
428
            if (index(i, j) != -1)  // is there a view in this position?
429
            {
430
                a = i * block[0]
431
                    * 0.5;  // reflect i and j so as +ve is in direction of title block ##
432
                b = j * block[1] * 0.5;
433
                view_x = ceil(a + 0.5) * width
434
                    + ceil(a) * depth;  // extreme coords of view in direction of block, measured
435
                                        // from far corner of (0, 0) view,
436
                view_y = ceil(b + 0.5) * height
437
                    + ceil(b) * depth;  //                      can be -ve if view is on opposite
438
                                        //                      side of (0, 0) from title block
439
                v_x_r = view_x / layout_width;  // make relative
440
                v_y_r = view_y / layout_height;
441
                if (v_x_r > rel_space_x
442
                    && v_y_r > rel_space_y) {  // ## so that can use > in this condition regardless
443
                                               // of position of block
444
                    interferes = true;
445
                }
446
            }
447
        }
448
    }
449

450
    if (!interferes) {
451
        page_dims = large;
452
    }
453
    else {
454
        if (min(small_h[2] / layout_width, small_h[3] / layout_height)
455
            > min(small_v[2] / layout_width, small_v[3] / layout_height)) {
456
            page_dims = small_h;
457
        }
458
        else {
459
            page_dims = small_v;
460
        }
461
    }
462
}
463

464
void OrthoViews::calc_scale()  // compute scale required to meet minimum space requirements
465
{
466
    float scale_x, scale_y, working_scale;
467

468
    scale_x = (page_dims[2] - num_gaps_x * min_space) / layout_width;
469
    scale_y = (page_dims[3] - num_gaps_y * min_space) / layout_height;
470

471
    working_scale = min(scale_x, scale_y);
472

473
    // which gives the largest scale for which the min_space requirements can be met, but we want a
474
    // 'sensible' scale, rather than 0.28457239... eg if working_scale = 0.115, then we want to use
475
    // 0.1, similarly 7.65 -> 5, and 76.5 -> 50
476

477
    float exponent = floor(log10(working_scale));  // if working_scale = a * 10^b, what is b?
478
    working_scale *= pow(10, -exponent);           // now find what 'a' is.
479

480
    float valid_scales[2][8] = {
481
        {1, 1.25, 2, 2.5, 3.75, 5, 7.5, 10},  // equate to 1:10, 1:8, 1:5, 1:4, 3:8, 1:2, 3:4, 1:1
482
        {1, 1.5, 2, 3, 4, 5, 8, 10}};         // equate to 1:1, 3:2, 2:1, 3:1, 4:1, 5:1, 8:1, 10:1
483

484
    int i = 7;
485
    while (valid_scales[(exponent >= 0)][i]
486
           > working_scale) {  // choose closest value smaller than 'a' from list.
487
        i -= 1;                // choosing top list if exponent -ve, bottom list for +ve exponent
488
    }
489

490
    scale = valid_scales[(exponent >= 0)][i]
491
        * pow(10, exponent);  // now have the appropriate scale, reapply the *10^b
492
}
493

494
void OrthoViews::calc_offsets()  // calcs SVG coords for centre of upper left view
495
{
496
    // space_x is the empty clear white space between views
497
    // gap_x is the centre - centre distance between views
498

499
    float space_x = (page_dims[2] - scale * layout_width) / num_gaps_x;
500
    float space_y = (page_dims[3] - scale * layout_height) / num_gaps_y;
501

502
    gap_x = space_x + scale * (width + depth) * 0.5;
503
    gap_y = space_y + scale * (height + depth) * 0.5;
504

505
    if (min_r_x % 2 == 0) {
506
        offset_x = page_dims[0] + space_x + 0.5 * scale * width;
507
    }
508
    else {
509
        offset_x = page_dims[0] + space_x + 0.5 * scale * depth;
510
    }
511

512
    if (max_r_y % 2 == 0) {
513
        offset_y = page_dims[1] + space_y + 0.5 * scale * height;
514
    }
515
    else {
516
        offset_y = page_dims[1] + space_y + 0.5 * scale * depth;
517
    }
518
}
519

520
void OrthoViews::set_views()  // process all views - scale & positions
521
{
522
    float x;
523
    float y;
524

525
    for (unsigned int i = 0; i < views.size(); i++) {
526
        x = offset_x + (views[i]->rel_x - min_r_x) * gap_x;
527
        y = offset_y + (max_r_y - views[i]->rel_y) * gap_y;
528

529
        if (views[i]->auto_scale) {
530
            views[i]->setScale(scale);
531
        }
532

533
        views[i]->setPos(x, y);
534
    }
535
}
536

537
void OrthoViews::process_views()  // update scale and positions of views
538
{
539
    if (autodims) {
540
        calc_layout_size();
541

542
        if (title) {
543
            choose_page();
544
        }
545

546
        calc_scale();
547
        calc_offsets();
548
    }
549

550
    set_views();
551
    parent_doc->recompute();
552
}
553

554
void OrthoViews::set_hidden(bool state)
555
{
556
    hidden = state;
557

558
    for (unsigned int i = 0; i < views.size(); i++) {
559
        views[i]->hidden(hidden);
560
    }
561

562
    parent_doc->recompute();
563
}
564

565
void OrthoViews::set_smooth(bool state)
566
{
567
    smooth = state;
568

569
    for (unsigned int i = 0; i < views.size(); i++) {
570
        views[i]->smooth(smooth);
571
    }
572

573
    parent_doc->recompute();
574
}
575

576
void OrthoViews::set_primary(gp_Dir facing,
577
                             gp_Dir right)  // set the orientation of the primary view
578
{
579
    primary.SetDirection(facing);
580
    primary.SetXDirection(right);
581
    gp_Dir up = primary.YDirection();
582

583
    // compute dimensions of part when orientated according to primary view
584
    width =
585
        abs(right.X() * bbox.LengthX() + right.Y() * bbox.LengthY() + right.Z() * bbox.LengthZ());
586
    height = abs(up.X() * bbox.LengthX() + up.Y() * bbox.LengthY() + up.Z() * bbox.LengthZ());
587
    depth = abs(facing.X() * bbox.LengthX() + facing.Y() * bbox.LengthY()
588
                + facing.Z() * bbox.LengthZ());
589

590
    if (views.size() == 0) {
591
        add_view(0, 0);
592
    }
593
    else {
594
        views[0]->set_projection(primary);
595
        set_all_orientations();  // reorient all other views appropriately
596
        process_views();
597
    }
598
}
599

600
void OrthoViews::set_orientation(int index)  // set orientation of single view
601
{
602
    double rotation;
603
    int n;       // how many 90* rotations from primary view?
604
    gp_Dir dir;  // rotate about primary x axis (if in a relative y position) or y axis?
605
    gp_Ax2 cs;
606

607
    if (views[index]->ortho) {
608
        if (views[index]->rel_x != 0) {
609
            dir = primary.YDirection();
610
            n = views[index]->rel_x;
611
        }
612
        else {
613
            dir = primary.XDirection();
614
            n = -views[index]->rel_y;
615
        }
616

617
        rotation = n * rotate_coeff * M_PI / 2;  // rotate_coeff is -1 or 1 for 1st or 3rd angle
618
        cs = primary.Rotated(gp_Ax1(gp_Pnt(0, 0, 0), dir), rotation);
619
        views[index]->set_projection(cs);
620
    }
621
}
622

623
void OrthoViews::set_all_orientations()  // set orientations of all views (ie projection or primary
624
                                         // changed)
625
{
626
    for (unsigned int i = 1; i < views.size(); i++)  // start from 1 - the 0 is the primary view
627
    {
628
        if (views[i]->ortho) {
629
            set_orientation(i);
630
        }
631
        else {
632
            set_Axo(views[i]->rel_x, views[i]->rel_y);
633
        }
634
    }
635
}
636

637
void OrthoViews::set_projection(int proj)  // 1 = 1st angle, 3 = 3rd angle
638
{
639
    if (proj == 3) {
640
        rotate_coeff = 1;
641
    }
642
    else if (proj == 1) {
643
        rotate_coeff = -1;
644
    }
645

646
    set_all_orientations();
647
    process_views();
648
}
649

650
void OrthoViews::add_view(int rel_x, int rel_y)  // add a new view to the layout
651
{
652
    if (index(rel_x, rel_y) == -1) {
653
        orthoview* view = new orthoview(parent_doc, part, page, &bbox);
654
        view->set_data(rel_x, rel_y);
655
        views.push_back(view);
656

657
        max_r_x = max(max_r_x, rel_x);
658
        min_r_x = min(min_r_x, rel_x);
659
        max_r_y = max(max_r_y, rel_y);
660
        min_r_y = min(min_r_y, rel_y);
661

662
        num_gaps_x = max_r_x - min_r_x + 2;
663
        num_gaps_y = max_r_y - min_r_y + 2;
664

665
        int i = views.size() - 1;
666
        views[i]->hidden(hidden);
667
        views[i]->smooth(smooth);
668

669
        if (views[i]->ortho) {
670
            set_orientation(i);
671
        }
672
        else {
673
            set_Axo(rel_x, rel_y);
674
        }
675

676
        process_views();
677
    }
678
}
679

680
void OrthoViews::del_view(int rel_x, int rel_y)  // remove a view from the layout
681
{
682
    int num = index(rel_x, rel_y);
683

684
    if (num > 0) {
685
        {
686
            boost::signals2::shared_connection_block blocker(connectDocumentDeletedObject);
687
            views[num]->deleteme();
688
            delete views[num];
689
            views.erase(views.begin() + num);
690
        }
691

692
        min_r_x = max_r_x = 0;
693
        min_r_y = max_r_y = 0;
694

695
        for (unsigned int i = 1; i < views.size(); i++)  // start from 1 - the 0 is the primary view
696
        {
697
            min_r_x = min(min_r_x, views[i]->rel_x);  // calculate extremes from remaining views
698
            max_r_x = max(max_r_x, views[i]->rel_x);
699
            min_r_y = min(min_r_y, views[i]->rel_y);
700
            max_r_y = max(max_r_y, views[i]->rel_y);
701
        }
702

703
        num_gaps_x = max_r_x - min_r_x + 2;
704
        num_gaps_y = max_r_y - min_r_y + 2;
705

706
        process_views();
707
    }
708
}
709

710
void OrthoViews::del_all()
711
{
712
    boost::signals2::shared_connection_block blocker(connectDocumentDeletedObject);
713
    for (int i = views.size() - 1; i >= 0; i--)  // count downwards to delete from back
714
    {
715
        views[i]->deleteme();
716
        delete views[i];
717
        views.pop_back();
718
    }
719
}
720

721
int OrthoViews::is_Ortho(int rel_x, int rel_y)  // is the view at r_x, r_y an ortho or axo one?
722
{
723
    int result = index(rel_x, rel_y);
724

725
    if (result != -1) {
726
        result = views[result]->ortho;
727
    }
728

729
    return result;
730
}
731

732
int OrthoViews::index(int rel_x, int rel_y)  // index in vector of view, -1 if doesn't exist
733
{
734
    int index = -1;
735

736
    for (unsigned int i = 0; i < views.size(); i++) {
737
        if (views[i]->rel_x == rel_x && views[i]->rel_y == rel_y) {
738
            index = i;
739
            break;
740
        }
741
    }
742

743
    return index;
744
}
745

746
void OrthoViews::set_Axo_scale(int rel_x,
747
                               int rel_y,
748
                               float axo_scale)  // set an axo scale independent of ortho ones
749
{
750
    int num = index(rel_x, rel_y);
751

752
    if (num != -1 && !views[num]->ortho) {
753
        views[num]->auto_scale = false;
754
        views[num]->setScale(axo_scale);
755
        views[num]->setPos();
756
        parent_doc->recompute();
757
    }
758
}
759

760
void OrthoViews::set_Axo(int rel_x,
761
                         int rel_y,
762
                         gp_Dir up,
763
                         gp_Dir right,
764
                         bool away,
765
                         int axo,
766
                         bool tri)  // set custom axonometric view
767
{
768
    double rotations[2];
769

770
    if (axo == 0) {
771
        rotations[0] = -0.7853981633974476;
772
        rotations[1] = -0.6154797086703873;
773
    }
774
    else if (axo == 1) {
775
        rotations[0] = -0.7853981633974476;
776
        rotations[1] = -0.2712637537260206;
777
    }
778
    else if (tri) {
779
        rotations[0] = -1.3088876392502007;
780
        rotations[1] = -0.6156624905260762;
781
    }
782
    else {
783
        rotations[0] = 1.3088876392502007 - M_PI / 2;
784
        rotations[1] = -0.6156624905260762;
785
    }
786

787
    if (away) {
788
        rotations[1] = -rotations[1];
789
    }
790

791
    gp_Ax2 cs = gp_Ax2(gp_Pnt(0, 0, 0), right);
792
    cs.SetYDirection(up);
793
    cs.Rotate(gp_Ax1(gp_Pnt(0, 0, 0), up), rotations[0]);
794
    gp_Dir dir;
795
    dir = cs.XDirection();
796
    cs.Rotate(gp_Ax1(gp_Pnt(0, 0, 0), dir), rotations[1]);
797

798
    int num = index(rel_x, rel_y);
799
    if (num != -1) {
800
        views[num]->ortho = false;
801
        views[num]->away = away;
802
        views[num]->tri = tri;
803
        views[num]->axo = axo;
804

805
        views[num]->up = up;
806
        views[num]->right = right;
807
        views[num]->set_projection(cs);
808
        views[num]->setPos();
809
    }
810

811
    parent_doc->recompute();
812
}
813

814
void OrthoViews::set_Axo(int rel_x, int rel_y)  // set view to default axo projection
815
{
816
    int num = index(rel_x, rel_y);
817

818
    if (num != -1) {
819
        gp_Dir up = primary.YDirection();  // default to view from up and right
820
        gp_Dir right = primary.XDirection();
821
        bool away = false;
822

823
        if (rel_x * rel_y != 0)  // but change default if it's a diagonal position
824
        {
825
            if (rotate_coeff == 1)  // third angle
826
            {
827
                away = (rel_y < 0);
828

829
                if (rel_x < 0) {
830
                    right = primary.Direction();
831
                }
832
                else {
833
                    right = primary.XDirection();
834
                }
835
            }
836
            else  // first angle
837
            {
838
                away = (rel_y > 0);
839

840
                if (rel_x > 0) {
841
                    right = primary.Direction();
842
                }
843
                else {
844
                    right = primary.XDirection();
845
                }
846
            }
847
        }
848
        set_Axo(rel_x, rel_y, up, right, away);
849
    }
850
}
851

852
void OrthoViews::set_Ortho(int rel_x, int rel_y)  // return view to orthographic
853
{
854
    int num = index(rel_x, rel_y);
855

856
    if (num != -1 && rel_x * rel_y == 0) {
857
        views[num]->ortho = true;
858
        views[num]->setScale(scale);
859
        views[num]->auto_scale = true;
860
        set_orientation(num);
861
        views[num]->setPos();
862

863
        parent_doc->recompute();
864
    }
865
}
866

867
bool OrthoViews::get_Axo(int rel_x,
868
                         int rel_y,
869
                         int& axo,
870
                         gp_Dir& up,
871
                         gp_Dir& right,
872
                         bool& away,
873
                         bool& tri,
874
                         float& axo_scale)
875
{
876
    int num = index(rel_x, rel_y);
877

878
    if (num != -1 && !views[num]->ortho) {
879
        axo = views[num]->axo;
880
        up = views[num]->up;
881
        right = views[num]->right;
882
        away = views[num]->away;
883
        tri = views[num]->tri;
884
        axo_scale = views[num]->getScale();
885
        return true;
886
    }
887
    else {
888
        return false;
889
    }
890
}
891

892
void OrthoViews::auto_dims(bool setting)
893
{
894
    autodims = setting;
895
    if (autodims) {
896
        process_views();
897
    }
898
}
899

900
void OrthoViews::set_configs(float configs[5])  // for autodims off, set scale & positionings
901
{
902
    if (!autodims) {
903
        scale = configs[0];
904
        offset_x = configs[1];
905
        offset_y = configs[2];
906
        gap_x = configs[3];
907
        gap_y = configs[4];
908
        process_views();
909
    }
910
}
911

912
void OrthoViews::get_configs(float configs[5])  // get scale & positionings
913
{
914
    configs[0] = scale;
915
    configs[1] = offset_x;
916
    configs[2] = offset_y;
917
    configs[3] = gap_x;
918
    configs[4] = gap_y;
919
}
920

921
///////////////////////////////////////////////////////////////////////////////////////////////
922
///////////////////////////////////////////////////////////////////////////////////////////////
923
///////////////////////////////////////////////////////////////////////////////////////////////
924

925
TaskOrthoViews::TaskOrthoViews(QWidget* parent)
926
    : ui(new Ui_TaskOrthoViews)
927
{
928
    Q_UNUSED(parent);
929
    ui->setupUi(this);
930
    std::vector<App::DocumentObject*> obj =
931
        Gui::Selection().getObjectsOfType(Part::Feature::getClassTypeId());
932
    const char* part = obj.front()->getNameInDocument();
933

934
    App::Document* doc = App::GetApplication().getActiveDocument();
935
    std::vector<App::DocumentObject*> pages =
936
        Gui::Selection().getObjectsOfType(Drawing::FeaturePage::getClassTypeId());
937
    if (pages.empty()) {
938
        pages = doc->getObjectsOfType(Drawing::FeaturePage::getClassTypeId());
939
    }
940

941
    std::string PageName = pages.front()->getNameInDocument();
942
    const char* page = PageName.c_str();
943

944

945
    // **********************************************************************
946
    // note that checkboxes are numbered increasing right & down
947
    // while OrthoViews relative positions are increasing right & up
948
    // doh!  I should renumber the checkboxes for clarity
949
    // **********************************************************************
950

951
    //   [x+2][y+2]
952
    c_boxes[0][2] = ui->cb02;  // left most, x = -2, y = 0
953
    c_boxes[1][1] = ui->cb11;
954
    c_boxes[1][2] = ui->cb12;
955
    c_boxes[1][3] = ui->cb13;
956
    c_boxes[2][0] = ui->cb20;  // top most, x = 0, y = -2
957
    c_boxes[2][1] = ui->cb21;
958
    c_boxes[2][2] = ui->cb22;  // centre (primary view) checkbox x = y = 0.
959
    c_boxes[2][3] = ui->cb23;
960
    c_boxes[2][4] = ui->cb24;  // bottom most, x = 0, y = 2
961
    c_boxes[3][1] = ui->cb31;
962
    c_boxes[3][2] = ui->cb32;
963
    c_boxes[3][3] = ui->cb33;
964
    c_boxes[4][2] = ui->cb42;  // right most, x = 2, y = 0
965

966
    for (int i = 0; i < 5; i++) {
967
        for (int j = 0; j < 5; j++) {
968
            if ((abs(i - 2) + abs(j - 2))
969
                < 3)  // if i,j combination corresponds to valid check box, then proceed with:
970
            {
971
                connect(c_boxes[i][j], SIGNAL(toggled(bool)), this, SLOT(cb_toggled(bool)));
972
                connect(c_boxes[i][j],
973
                        SIGNAL(customContextMenuRequested(const QPoint&)),
974
                        this,
975
                        SLOT(ShowContextMenu(const QPoint&)));
976
            }
977
        }
978
    }
979

980
    // access scale / position QLineEdits via array
981
    inputs[0] = ui->scale_0;
982
    inputs[1] = ui->x_1;
983
    inputs[2] = ui->y_2;
984
    inputs[3] = ui->spacing_h_3;
985
    inputs[4] = ui->spacing_v_4;
986

987
    for (int i = 0; i < 5; i++) {
988
        connect(inputs[i],
989
                SIGNAL(textEdited(const QString&)),
990
                this,
991
                SLOT(data_entered(const QString&)));
992
        connect(inputs[i], SIGNAL(returnPressed()), this, SLOT(text_return()));
993
    }
994

995
    connect(ui->projection, SIGNAL(currentIndexChanged(int)), this, SLOT(projectionChanged(int)));
996
    connect(ui->smooth, SIGNAL(stateChanged(int)), this, SLOT(smooth(int)));
997
    connect(ui->hidden, SIGNAL(stateChanged(int)), this, SLOT(hidden(int)));
998
    connect(ui->auto_tog, SIGNAL(stateChanged(int)), this, SLOT(toggle_auto(int)));
999

1000
    connect(ui->view_from, SIGNAL(currentIndexChanged(int)), this, SLOT(setPrimary(int)));
1001
    connect(ui->axis_right, SIGNAL(currentIndexChanged(int)), this, SLOT(setPrimary(int)));
1002

1003
    connect(ui->axoProj, SIGNAL(activated(int)), this, SLOT(change_axo(int)));
1004
    connect(ui->axoUp, SIGNAL(activated(int)), this, SLOT(change_axo(int)));
1005
    connect(ui->axoRight, SIGNAL(activated(int)), this, SLOT(change_axo(int)));
1006
    connect(ui->vert_flip, SIGNAL(clicked()), this, SLOT(axo_button()));
1007
    connect(ui->tri_flip, SIGNAL(clicked()), this, SLOT(axo_button()));
1008
    connect(ui->axoScale,
1009
            SIGNAL(textEdited(const QString&)),
1010
            this,
1011
            SLOT(axo_scale(const QString&)));
1012
    connect(ui->axoScale, SIGNAL(returnPressed()), this, SLOT(text_return()));
1013

1014
    ui->tabWidget->setTabEnabled(1, false);
1015

1016
    gp_Dir facing = gp_Dir(1, 0, 0);
1017
    gp_Dir right = gp_Dir(0, 1, 0);
1018
    orthos = new OrthoViews(doc, page, part);
1019
    orthos->set_primary(facing, right);
1020

1021
    txt_return = false;
1022
}  // end of constructor
1023

1024
TaskOrthoViews::~TaskOrthoViews()
1025
{
1026
    delete orthos;
1027
    delete ui;
1028
}
1029

1030
void TaskOrthoViews::ShowContextMenu(const QPoint& pos)
1031
{
1032
    QString name = sender()->objectName().right(2);
1033
    char letter = name.toStdString()[0];
1034
    int dx = letter - '0' - 2;
1035

1036
    letter = name.toStdString()[1];
1037
    int dy = letter - '0' - 2;
1038

1039
    if (c_boxes[dx + 2][dy + 2]->isChecked()) {
1040
        QString str_1 = QObject::tr("Make axonometric...");
1041
        QString str_2 = QObject::tr("Edit axonometric settings...");
1042
        QString str_3 = QObject::tr("Make orthographic");
1043

1044
        QPoint globalPos = c_boxes[dx + 2][dy + 2]->mapToGlobal(pos);
1045
        QMenu myMenu;
1046
        if (orthos->is_Ortho(dx, -dy)) {
1047
            myMenu.addAction(str_1);
1048
        }
1049
        else {
1050
            myMenu.addAction(str_2);
1051
            if (dx * dy == 0) {
1052
                myMenu.addAction(str_3);
1053
            }
1054
        }
1055

1056
        QAction* selectedItem = myMenu.exec(globalPos);
1057
        if (selectedItem) {
1058
            QString text = selectedItem->text();
1059

1060
            if (text == str_1)  // make axo
1061
            {
1062
                orthos->set_Axo(dx, -dy);
1063
                axo_r_x = dx;
1064
                axo_r_y = dy;
1065
                ui->tabWidget->setTabEnabled(1, true);
1066
                ui->tabWidget->setCurrentIndex(1);
1067
                setup_axo_tab();
1068
            }
1069
            else if (text == str_2)  // edit axo
1070
            {
1071
                axo_r_x = dx;
1072
                axo_r_y = dy;
1073
                ui->tabWidget->setTabEnabled(1, true);
1074
                ui->tabWidget->setCurrentIndex(1);
1075
                setup_axo_tab();
1076
            }
1077
            else if (text == str_3)  // make ortho
1078
            {
1079
                orthos->set_Ortho(dx, -dy);
1080
                if (dx == axo_r_x && dy == axo_r_y) {
1081
                    axo_r_x = 0;
1082
                    axo_r_y = 0;
1083
                    ui->tabWidget->setTabEnabled(1, false);
1084
                }
1085
            }
1086
        }
1087
    }
1088
}
1089

1090
void TaskOrthoViews::changeEvent(QEvent* e)
1091
{
1092
    if (e->type() == QEvent::LanguageChange) {
1093
        ui->retranslateUi(this);
1094
    }
1095
}
1096

1097
void TaskOrthoViews::cb_toggled(bool toggle)
1098
{
1099
    QString name = sender()->objectName().right(2);
1100
    char letter = name.toStdString()[0];
1101
    int dx = letter - '0' - 2;
1102

1103
    letter = name.toStdString()[1];
1104
    int dy = letter - '0' - 2;
1105

1106
    if (toggle) {
1107
        orthos->add_view(dx, -dy);
1108
        if (dx * dy != 0)  // adding an axo view
1109
        {
1110
            axo_r_x = dx;
1111
            axo_r_y = dy;
1112
            ui->tabWidget->setTabEnabled(1, true);
1113
            ui->tabWidget->setCurrentIndex(1);
1114
            setup_axo_tab();
1115
        }
1116
    }
1117
    else  // removing a view
1118
    {
1119
        if (!orthos->is_Ortho(dx, -dy))  // is it an axo one?
1120
        {
1121
            if (dx == axo_r_x && dy == axo_r_y)  // is it the one currently being edited?
1122
            {
1123
                axo_r_x = 0;
1124
                axo_r_y = 0;
1125
                ui->tabWidget->setTabEnabled(1, false);
1126
            }
1127
        }
1128
        orthos->del_view(dx, -dy);
1129
    }
1130

1131
    set_configs();
1132
}
1133

1134
void TaskOrthoViews::projectionChanged(int index)
1135
{
1136
    int proj = 3 - 2 * index;  // index = 0 = third angle
1137
    orthos->set_projection(proj);
1138

1139
    set_configs();
1140
}
1141

1142
void TaskOrthoViews::setPrimary(int /*dir*/)
1143
{
1144
    int p_sel = ui->view_from->currentIndex();   // index for entry selected for 'view from'
1145
    int r_sel = ui->axis_right->currentIndex();  // index for entry selected for 'rightwards axis'
1146

1147
    int p_vec[3] = {0, 0, 0};  // will be the vector for 'view from'
1148
    int r_vec[3] = {0, 0, 0};  // will be vector for 'rightwards axis'
1149
    int r[2] = {0, 1};
1150

1151
    int pos = 1 - 2 * int(p_sel / 3);  // 1 if p_sel = 0, 1, 2  or -1 if p_sel = 3, 4, 5
1152
    p_sel = p_sel % 3;                 // p_sel = 0, 1, 2
1153
    p_vec[p_sel] = pos;
1154

1155
    for (int i = p_sel; i < 2;
1156
         i++) {  // make r[2] to be, {0, 1}, {0, 2}, or {1, 2} depending upon p_sel
1157
        r[i] += 1;
1158
    }
1159

1160
    pos = 1 - 2 * int(r_sel / 2);  // 1 if r_sel = 0, 1  or -1 if r_sel = 3, 4
1161
    r_sel = r_sel % 2;             // r_sel = 0, 1
1162
    r_vec[r[r_sel]] = pos;
1163

1164
    gp_Dir facing = gp_Dir(p_vec[0], p_vec[1], p_vec[2]);
1165
    gp_Dir right = gp_Dir(r_vec[0], r_vec[1], r_vec[2]);
1166

1167
    orthos->set_primary(facing, right);
1168

1169
    // update rightwards combobox in case of 'view from' change
1170
    if (sender() == ui->view_from) {
1171
        disconnect(ui->axis_right, SIGNAL(currentIndexChanged(int)), this, SLOT(setPrimary(int)));
1172

1173
        QStringList items;
1174
        items << QString::fromUtf8("X +ve") << QString::fromUtf8("Y +ve")
1175
              << QString::fromUtf8("Z +ve");
1176
        items << QString::fromUtf8("X -ve") << QString::fromUtf8("Y -ve")
1177
              << QString::fromUtf8("Z -ve");
1178
        items.removeAt(p_sel + 3);
1179
        items.removeAt(p_sel);
1180

1181
        ui->axis_right->clear();
1182
        ui->axis_right->addItems(items);
1183
        ui->axis_right->setCurrentIndex(r_sel - pos + 1);
1184

1185
        connect(ui->axis_right, SIGNAL(currentIndexChanged(int)), this, SLOT(setPrimary(int)));
1186
    }
1187

1188
    set_configs();
1189
}
1190

1191
void TaskOrthoViews::hidden(int i)
1192
{
1193
    orthos->set_hidden(i == 2);
1194
}
1195

1196

1197
void TaskOrthoViews::smooth(int i)
1198
{
1199
    orthos->set_smooth(i == 2);
1200
}
1201

1202
void TaskOrthoViews::toggle_auto(int i)
1203
{
1204
    if (i == 2)  // auto scale switched on
1205
    {
1206
        orthos->auto_dims(true);
1207
        ui->label_4->setEnabled(false);
1208
        ui->label_5->setEnabled(false);
1209
        ui->label_6->setEnabled(false);
1210

1211
        for (int j = 0; j < 5; j++) {
1212
            inputs[j]->setEnabled(false);  // disable user input boxes
1213
        }
1214
    }
1215
    else {
1216
        orthos->auto_dims(false);
1217
        ui->label_4->setEnabled(true);
1218
        ui->label_5->setEnabled(true);
1219
        ui->label_6->setEnabled(true);
1220

1221
        for (int j = 0; j < 5; j++) {
1222
            inputs[j]->setEnabled(true);  // enable user input boxes
1223
        }
1224
        set_configs();
1225
    }
1226
}
1227

1228
void TaskOrthoViews::data_entered(const QString& text)
1229
{
1230
    bool ok;
1231
    QString name = sender()->objectName().right(1);
1232
    char letter = name.toStdString()[0];
1233
    int index = letter - '0';
1234

1235
    float value = text.toFloat(&ok);
1236

1237
    if (ok) {
1238
        data[index] = value;
1239
        orthos->set_configs(data);
1240
    }
1241
    else {
1242
        inputs[index]->setText(QString::number(data[index]));
1243
        return;
1244
    }
1245
}
1246

1247
void TaskOrthoViews::clean_up()
1248
{
1249
    orthos->del_all();
1250
}
1251

1252
void TaskOrthoViews::setup_axo_tab()
1253
{
1254
    int axo;
1255
    gp_Dir up, right;
1256
    bool away, tri;
1257
    float axo_scale;
1258
    int up_n, right_n;
1259

1260
    orthos->get_Axo(axo_r_x, -axo_r_y, axo, up, right, away, tri, axo_scale);
1261

1262
    // convert gp_Dirs into selections of comboboxes
1263
    if (up.X() != 0) {
1264
        up_n = (up.X() == -1) ? 3 : 0;
1265
    }
1266
    else if (up.Y() != 0) {
1267
        up_n = (up.Y() == -1) ? 4 : 1;
1268
    }
1269
    else {
1270
        up_n = (up.Z() == -1) ? 5 : 2;
1271
    }
1272

1273
    if (right.X() != 0) {
1274
        right_n = (right.X() == -1) ? 3 : 0;
1275
    }
1276
    else if (right.Y() != 0) {
1277
        right_n = (right.Y() == -1) ? 4 : 1;
1278
    }
1279
    else {
1280
        right_n = (right.Z() == -1) ? 5 : 2;
1281
    }
1282

1283
    if (right_n > (up_n % 3 + 3)) {
1284
        right_n -= 2;
1285
    }
1286
    else if (right_n > up_n) {
1287
        right_n -= 1;
1288
    }
1289

1290
    QStringList items;
1291
    items << QString::fromUtf8("X +ve") << QString::fromUtf8("Y +ve") << QString::fromUtf8("Z +ve");
1292
    items << QString::fromUtf8("X -ve") << QString::fromUtf8("Y -ve") << QString::fromUtf8("Z -ve");
1293
    items.removeAt(up_n % 3 + 3);
1294
    items.removeAt(up_n % 3);
1295

1296
    ui->axoUp->setCurrentIndex(up_n);
1297
    ui->axoRight->clear();
1298
    ui->axoRight->addItems(items);
1299
    ui->axoRight->setCurrentIndex(right_n);
1300

1301
    ui->vert_flip->setChecked(away);
1302
    ui->tri_flip->setChecked(tri);
1303
    ui->axoProj->setCurrentIndex(axo);
1304
    ui->axoScale->setText(QString::number(axo_scale));
1305
}
1306

1307
void TaskOrthoViews::change_axo(int /*p*/)
1308
{
1309
    int u_sel = ui->axoUp->currentIndex();     // index for entry selected for 'view from'
1310
    int r_sel = ui->axoRight->currentIndex();  // index for entry selected for 'rightwards axis'
1311

1312
    int u_vec[3] = {0, 0, 0};  // will be the vector for 'view from'
1313
    int r_vec[3] = {0, 0, 0};  // will be vector for 'rightwards axis'
1314
    int r[2] = {0, 1};
1315

1316
    int pos = 1 - 2 * int(u_sel / 3);  // 1 if p_sel = 0,1,2  or -1 if p_sel = 3,4,5
1317
    u_sel = u_sel % 3;                 // p_sel = 0,1,2
1318
    u_vec[u_sel] = pos;
1319

1320
    for (int i = u_sel; i < 2; i++) {
1321
        r[i] += 1;
1322
    }
1323

1324
    pos = 1 - 2 * int(r_sel / 2);
1325
    r_sel = r_sel % 2;
1326
    r_vec[r[r_sel]] = pos;
1327

1328
    gp_Dir up = gp_Dir(u_vec[0], u_vec[1], u_vec[2]);
1329
    gp_Dir right = gp_Dir(r_vec[0], r_vec[1], r_vec[2]);
1330

1331
    orthos->set_Axo(axo_r_x,
1332
                    -axo_r_y,
1333
                    up,
1334
                    right,
1335
                    ui->vert_flip->isChecked(),
1336
                    ui->axoProj->currentIndex(),
1337
                    ui->tri_flip->isChecked());
1338

1339
    if (ui->axoProj->currentIndex() == 2) {
1340
        ui->tri_flip->setEnabled(true);
1341
    }
1342
    else {
1343
        ui->tri_flip->setEnabled(false);
1344
    }
1345

1346

1347
    QStringList items;
1348
    items << QString::fromUtf8("X +ve") << QString::fromUtf8("Y +ve") << QString::fromUtf8("Z +ve");
1349
    items << QString::fromUtf8("X -ve") << QString::fromUtf8("Y -ve") << QString::fromUtf8("Z -ve");
1350
    items.removeAt(u_sel % 3 + 3);
1351
    items.removeAt(u_sel % 3);
1352

1353
    ui->axoRight->clear();
1354
    ui->axoRight->addItems(items);
1355
    ui->axoRight->setCurrentIndex(r_sel - pos + 1);
1356
}
1357

1358
void TaskOrthoViews::axo_button()
1359
{
1360
    change_axo();
1361
}
1362

1363
void TaskOrthoViews::axo_scale(const QString& text)
1364
{
1365
    bool ok;
1366
    float value = text.toFloat(&ok);
1367

1368
    if (ok) {
1369
        orthos->set_Axo_scale(axo_r_x, -axo_r_y, value);
1370
    }
1371
}
1372

1373
void TaskOrthoViews::set_configs()
1374
{
1375
    orthos->get_configs(data);
1376

1377
    for (int i = 0; i < 5; i++) {
1378
        inputs[i]->setText(QString::number(data[i]));
1379
    }
1380
}
1381

1382
bool TaskOrthoViews::user_input()
1383
{
1384
    if (txt_return) {
1385
        txt_return = false;       // return was pressed while text box had focus
1386
        ui->label_7->setFocus();  // move focus out of text box
1387
        return true;              // return that we were editing
1388
    }
1389
    else {
1390
        return false;  // return that we weren't editing ---> treat as clicking OK... we can close
1391
                       // the GUI
1392
    }
1393
}
1394

1395
void TaskOrthoViews::text_return()
1396
{
1397
    txt_return = true;
1398
}
1399

1400
//**************************************************************************
1401
//**************************************************************************
1402
// TaskDialog
1403
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1404

1405
TaskDlgOrthoViews::TaskDlgOrthoViews()
1406
    : TaskDialog()
1407
{
1408
    widget = new TaskOrthoViews();
1409
    addTaskBox(Gui::BitmapFactory().pixmap("actions/drawing-orthoviews"), widget, true, nullptr);
1410
}
1411

1412
TaskDlgOrthoViews::~TaskDlgOrthoViews()
1413
{}
1414

1415
//==== calls from the TaskView ===============================================================
1416

1417

1418
void TaskDlgOrthoViews::open()
1419
{}
1420

1421
void TaskDlgOrthoViews::clicked(int)
1422
{}
1423

1424
bool TaskDlgOrthoViews::accept()
1425
{
1426
    bool check = widget->user_input();
1427
    App::Document* doc = App::GetApplication().getDocument(this->getDocumentName().c_str());
1428
    if (doc) {
1429
        doc->commitTransaction();
1430
    }
1431
    return !check;
1432
}
1433

1434
bool TaskDlgOrthoViews::reject()
1435
{
1436
    widget->clean_up();
1437
    App::Document* doc = App::GetApplication().getDocument(this->getDocumentName().c_str());
1438
    if (doc) {
1439
        doc->abortTransaction();
1440
    }
1441
    return true;
1442
}
1443

1444

1445
#include "moc_TaskOrthoViews.cpp"
1446

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.