FreeCAD

Форк
0
/
CommandView.cpp 
4055 строк · 141.6 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2002 Jürgen Riegel <juergen.riegel@web.de>              *
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

24
#include "PreCompiled.h"
25

26
#ifndef _PreComp_
27
# include <sstream>
28
# include <Inventor/events/SoMouseButtonEvent.h>
29
# include <Inventor/nodes/SoOrthographicCamera.h>
30
# include <Inventor/nodes/SoPerspectiveCamera.h>
31
# include <QApplication>
32
# include <QDialog>
33
# include <QDomDocument>
34
# include <QDomElement>
35
# include <QFile>
36
# include <QFileInfo>
37
# include <QFont>
38
# include <QFontMetrics>
39
# include <QImageReader>
40
# include <QMessageBox>
41
# include <QPainter>
42
# include <QPointer>
43
# include <QTextStream>
44
#endif
45

46
#include <App/ComplexGeoDataPy.h>
47
#include <App/Document.h>
48
#include <App/DocumentObject.h>
49
#include <App/DocumentObjectGroup.h>
50
#include <App/GeoFeature.h>
51
#include <App/GeoFeatureGroupExtension.h>
52
#include <App/Part.h>
53
#include <App/Link.h>
54
#include <Base/Console.h>
55
#include <Base/Parameter.h>
56

57
#include "Command.h"
58
#include "Action.h"
59
#include "Application.h"
60
#include "BitmapFactory.h"
61
#include "Control.h"
62
#include "Clipping.h"
63
#include "DemoMode.h"
64
#include "DlgSettingsImageImp.h"
65
#include "Document.h"
66
#include "FileDialog.h"
67
#include "ImageView.h"
68
#include "Macro.h"
69
#include "MainWindow.h"
70
#include "NavigationStyle.h"
71
#include "OverlayParams.h"
72
#include "OverlayManager.h"
73
#include "SceneInspector.h"
74
#include "Selection.h"
75
#include "SelectionObject.h"
76
#include "SoAxisCrossKit.h"
77
#include "SoFCOffscreenRenderer.h"
78
#include "TextureMapping.h"
79
#include "Tools.h"
80
#include "Tree.h"
81
#include "TreeParams.h"
82
#include "Utilities.h"
83
#include "View3DInventor.h"
84
#include "View3DInventorViewer.h"
85
#include "ViewParams.h"
86
#include "ViewProviderGeometryObject.h"
87
#include "WaitCursor.h"
88

89
using namespace Gui;
90
using Gui::Dialog::DlgSettingsImageImp;
91
namespace sp = std::placeholders;
92

93
namespace {
94
// A helper class to open a transaction when changing properties of view providers.
95
// It uses the same parameter key as the PropertyView to control the behaviour.
96
class TransactionView {
97
    Gui::Document* document;
98

99
public:
100
    static bool getDefault() {
101
        auto hGrp = App::GetApplication().GetParameterGroupByPath(
102
                "User parameter:BaseApp/Preferences/PropertyView");
103
        return hGrp->GetBool("AutoTransactionView", false);
104
    }
105
    TransactionView(Gui::Document* doc, const char* name, bool enable = getDefault())
106
        : document(doc)
107
    {
108
        if (document && enable) {
109
            document->openCommand(name);
110
        }
111
        else {
112
            document = nullptr;
113
        }
114
    }
115

116
    ~TransactionView() {
117
        if (document) {
118
            document->commitCommand();
119
        }
120
    }
121
};
122
}
123

124
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
125

126
DEF_STD_CMD_AC(StdOrthographicCamera)
127

128
StdOrthographicCamera::StdOrthographicCamera()
129
  : Command("Std_OrthographicCamera")
130
{
131
    sGroup        = "Standard-View";
132
    sMenuText     = QT_TR_NOOP("Orthographic view");
133
    sToolTipText  = QT_TR_NOOP("Switches to orthographic view mode");
134
    sWhatsThis    = "Std_OrthographicCamera";
135
    sStatusTip    = QT_TR_NOOP("Switches to orthographic view mode");
136
    sPixmap       = "view-isometric";
137
    sAccel        = "V, O";
138
    eType         = Alter3DView;
139
}
140

141
void StdOrthographicCamera::activated(int iMsg)
142
{
143
    if (iMsg == 1) {
144
        auto view = qobject_cast<View3DInventor*>(getMainWindow()->activeWindow());
145
        SoCamera* cam = view->getViewer()->getSoRenderManager()->getCamera();
146
        if (!cam || cam->getTypeId() != SoOrthographicCamera::getClassTypeId())
147

148
            doCommand(Command::Gui,"Gui.activeDocument().activeView().setCameraType(\"Orthographic\")");
149
    }
150
}
151

152
bool StdOrthographicCamera::isActive()
153
{
154
    auto view = qobject_cast<View3DInventor*>(getMainWindow()->activeWindow());
155
    if (view) {
156
        // update the action group if needed
157
        bool check = _pcAction->isChecked();
158
        SoCamera* cam = view->getViewer()->getSoRenderManager()->getCamera();
159
        bool mode = cam ? cam->getTypeId() == SoOrthographicCamera::getClassTypeId() : false;
160

161
        if (mode != check)
162
            _pcAction->setChecked(mode);
163
        return true;
164
    }
165

166
    return false;
167
}
168

169
Action * StdOrthographicCamera::createAction()
170
{
171
    Action *pcAction = Command::createAction();
172
    pcAction->setCheckable(true);
173
    return pcAction;
174
}
175

176
DEF_STD_CMD_AC(StdPerspectiveCamera)
177

178
StdPerspectiveCamera::StdPerspectiveCamera()
179
  : Command("Std_PerspectiveCamera")
180
{
181
    sGroup        = "Standard-View";
182
    sMenuText     = QT_TR_NOOP("Perspective view");
183
    sToolTipText  = QT_TR_NOOP("Switches to perspective view mode");
184
    sWhatsThis    = "Std_PerspectiveCamera";
185
    sStatusTip    = QT_TR_NOOP("Switches to perspective view mode");
186
    sPixmap       = "view-perspective";
187
    sAccel        = "V, P";
188
    eType         = Alter3DView;
189
}
190

191
void StdPerspectiveCamera::activated(int iMsg)
192
{
193
    if (iMsg == 1) {
194
        auto view = qobject_cast<View3DInventor*>(getMainWindow()->activeWindow());
195
        SoCamera* cam = view->getViewer()->getSoRenderManager()->getCamera();
196
        if (!cam || cam->getTypeId() != SoPerspectiveCamera::getClassTypeId())
197

198
            doCommand(Command::Gui,"Gui.activeDocument().activeView().setCameraType(\"Perspective\")");
199
    }
200
}
201

202
bool StdPerspectiveCamera::isActive()
203
{
204
    auto view = qobject_cast<View3DInventor*>(getMainWindow()->activeWindow());
205
    if (view) {
206
        // update the action group if needed
207
        bool check = _pcAction->isChecked();
208
        SoCamera* cam = view->getViewer()->getSoRenderManager()->getCamera();
209
        bool mode = cam ? cam->getTypeId() == SoPerspectiveCamera::getClassTypeId() : false;
210

211
        if (mode != check)
212
            _pcAction->setChecked(mode);
213

214
        return true;
215
    }
216

217
    return false;
218
}
219

220
Action * StdPerspectiveCamera::createAction()
221
{
222
    Action *pcAction = Command::createAction();
223
    pcAction->setCheckable(true);
224
    return pcAction;
225
}
226

227
//===========================================================================
228

229
// The two commands below are provided for convenience so that they can be bound
230
// to a button of a spacemouse
231

232
//===========================================================================
233
// Std_ViewSaveCamera
234
//===========================================================================
235

236
DEF_3DV_CMD(StdCmdViewSaveCamera)
237

238
StdCmdViewSaveCamera::StdCmdViewSaveCamera()
239
  : Command("Std_ViewSaveCamera")
240
{
241
    sGroup        = "Standard-View";
242
    sMenuText     = QT_TR_NOOP("Save current camera");
243
    sToolTipText  = QT_TR_NOOP("Save current camera settings");
244
    sStatusTip    = QT_TR_NOOP("Save current camera settings");
245
    sWhatsThis    = "Std_ViewSaveCamera";
246
    eType         = Alter3DView;
247
}
248

249
void StdCmdViewSaveCamera::activated(int iMsg)
250
{
251
    Q_UNUSED(iMsg);
252

253
    auto view = qobject_cast<Gui::View3DInventor*>(Gui::getMainWindow()->activeWindow());
254
    if (view) {
255
        view->getViewer()->saveHomePosition();
256
    }
257
}
258

259
//===========================================================================
260
// Std_ViewRestoreCamera
261
//===========================================================================
262
DEF_3DV_CMD(StdCmdViewRestoreCamera)
263

264
StdCmdViewRestoreCamera::StdCmdViewRestoreCamera()
265
  : Command("Std_ViewRestoreCamera")
266
{
267
    sGroup        = "Standard-View";
268
    sMenuText     = QT_TR_NOOP("Restore saved camera");
269
    sToolTipText  = QT_TR_NOOP("Restore saved camera settings");
270
    sStatusTip    = QT_TR_NOOP("Restore saved camera settings");
271
    sWhatsThis    = "Std_ViewRestoreCamera";
272
    eType         = Alter3DView;
273
}
274

275
void StdCmdViewRestoreCamera::activated(int iMsg)
276
{
277
    Q_UNUSED(iMsg);
278

279
    auto view = qobject_cast<Gui::View3DInventor*>(Gui::getMainWindow()->activeWindow());
280
    if (view) {
281
        view->getViewer()->resetToHomePosition();
282
    }
283
}
284

285
//===========================================================================
286
// Std_FreezeViews
287
//===========================================================================
288
class StdCmdFreezeViews : public Gui::Command
289
{
290
public:
291
    StdCmdFreezeViews();
292
    ~StdCmdFreezeViews() override = default;
293
    const char* className() const override
294
    { return "StdCmdFreezeViews"; }
295

296
    void setShortcut (const QString &) override;
297
    QString getShortcut() const override;
298

299
protected:
300
    void activated(int iMsg) override;
301
    bool isActive() override;
302
    Action * createAction() override;
303
    void languageChange() override;
304

305
private:
306
    void onSaveViews();
307
    void onRestoreViews();
308

309
private:
310
    const int maxViews{50};
311
    int savedViews{0};
312
    int offset{0};
313
    QAction* saveView{nullptr};
314
    QAction* freezeView{nullptr};
315
    QAction* clearView{nullptr};
316
    QAction* separator{nullptr};
317
};
318

319
StdCmdFreezeViews::StdCmdFreezeViews()
320
  : Command("Std_FreezeViews")
321
{
322
    sGroup        = "Standard-View";
323
    sMenuText     = QT_TR_NOOP("Freeze display");
324
    sToolTipText  = QT_TR_NOOP("Freezes the current view position");
325
    sWhatsThis    = "Std_FreezeViews";
326
    sStatusTip    = QT_TR_NOOP("Freezes the current view position");
327
    sAccel        = "Shift+F";
328
    eType         = Alter3DView;
329
}
330

331
Action * StdCmdFreezeViews::createAction()
332
{
333
    auto pcAction = new ActionGroup(this, getMainWindow());
334
    pcAction->setDropDownMenu(true);
335
    applyCommandData(this->className(), pcAction);
336

337
    // add the action items
338
    saveView = pcAction->addAction(QObject::tr("Save views..."));
339
    saveView->setWhatsThis(QString::fromLatin1(getWhatsThis()));
340
    QAction* loadView = pcAction->addAction(QObject::tr("Load views..."));
341
    loadView->setWhatsThis(QString::fromLatin1(getWhatsThis()));
342
    pcAction->addAction(QString::fromLatin1(""))->setSeparator(true);
343
    freezeView = pcAction->addAction(QObject::tr("Freeze view"));
344
    freezeView->setShortcut(QString::fromLatin1(getAccel()));
345
    freezeView->setWhatsThis(QString::fromLatin1(getWhatsThis()));
346
    clearView = pcAction->addAction(QObject::tr("Clear views"));
347
    clearView->setWhatsThis(QString::fromLatin1(getWhatsThis()));
348
    separator = pcAction->addAction(QString::fromLatin1(""));
349
    separator->setSeparator(true);
350
    offset = pcAction->actions().count();
351

352
    // allow up to 50 views
353
    for (int i=0; i<maxViews; i++)
354
        pcAction->addAction(QString::fromLatin1(""))->setVisible(false);
355

356
    return pcAction;
357
}
358

359
void StdCmdFreezeViews::setShortcut(const QString &shortcut)
360
{
361
    if (freezeView)
362
        freezeView->setShortcut(shortcut);
363
}
364

365
QString StdCmdFreezeViews::getShortcut() const
366
{
367
    if (freezeView)
368
        return freezeView->shortcut().toString();
369
    return Command::getShortcut();
370
}
371

372
void StdCmdFreezeViews::activated(int iMsg)
373
{
374
    auto pcAction = qobject_cast<ActionGroup*>(_pcAction);
375

376
    if (iMsg == 0) {
377
        onSaveViews();
378
    }
379
    else if (iMsg == 1) {
380
        onRestoreViews();
381
    }
382
    else if (iMsg == 3) {
383
        // Create a new view
384
        const char* ppReturn=nullptr;
385
        getGuiApplication()->sendMsgToActiveView("GetCamera",&ppReturn);
386

387
        QList<QAction*> acts = pcAction->actions();
388
        int index = 1;
389
        for (QList<QAction*>::Iterator it = acts.begin()+offset; it != acts.end(); ++it, index++) {
390
            if (!(*it)->isVisible()) {
391
                savedViews++;
392
                QString viewnr = QString(QObject::tr("Restore view &%1")).arg(index);
393
                (*it)->setText(viewnr);
394
                (*it)->setToolTip(QString::fromLatin1(ppReturn));
395
                (*it)->setVisible(true);
396
                if (index < 10) {
397
                    (*it)->setShortcut(QKeySequence(QString::fromLatin1("CTRL+%1").arg(index)));
398
                }
399
                break;
400
            }
401
        }
402
    }
403
    else if (iMsg == 4) {
404
        savedViews = 0;
405
        QList<QAction*> acts = pcAction->actions();
406
        for (QList<QAction*>::Iterator it = acts.begin()+offset; it != acts.end(); ++it)
407
            (*it)->setVisible(false);
408
    }
409
    else if (iMsg >= offset) {
410
        // Activate a view
411
        QList<QAction*> acts = pcAction->actions();
412
        QString data = acts[iMsg]->toolTip();
413
        QString send = QString::fromLatin1("SetCamera %1").arg(data);
414
        getGuiApplication()->sendMsgToActiveView(send.toLatin1());
415
    }
416
}
417

418
void StdCmdFreezeViews::onSaveViews()
419
{
420
    // Save the views to an XML file
421
    QString fn = FileDialog::getSaveFileName(getMainWindow(), QObject::tr("Save frozen views"),
422
                                             QString(), QString::fromLatin1("%1 (*.cam)").arg(QObject::tr("Frozen views")));
423
    if (fn.isEmpty())
424
        return;
425
    QFile file(fn);
426
    if (file.open(QFile::WriteOnly))
427
    {
428
        QTextStream str(&file);
429
        auto pcAction = qobject_cast<ActionGroup*>(_pcAction);
430
        QList<QAction*> acts = pcAction->actions();
431
        str << "<?xml version='1.0' encoding='utf-8'?>\n"
432
            << "<FrozenViews SchemaVersion=\"1\">\n";
433
        str << "  <Views Count=\"" << savedViews <<"\">\n";
434

435
        for (QList<QAction*>::Iterator it = acts.begin()+offset; it != acts.end(); ++it) {
436
            if ( !(*it)->isVisible() )
437
                break;
438
            QString data = (*it)->toolTip();
439

440
            // remove the first line because it's a comment like '#Inventor V2.1 ascii'
441
            QString viewPos;
442
            if (!data.isEmpty()) {
443
                QStringList lines = data.split(QString::fromLatin1("\n"));
444
                if (lines.size() > 1) {
445
                    lines.pop_front();
446
                }
447
                viewPos = lines.join(QString::fromLatin1(" "));
448
            }
449

450
            str << "    <Camera settings=\"" << viewPos.toLatin1().constData() << "\"/>\n";
451
        }
452

453
        str << "  </Views>\n";
454
        str << "</FrozenViews>\n";
455
    }
456
}
457

458
void StdCmdFreezeViews::onRestoreViews()
459
{
460
    // Should we clear the already saved views
461
    if (savedViews > 0) {
462
        auto ret = QMessageBox::question(getMainWindow(), QObject::tr("Restore views"),
463
            QObject::tr("Importing the restored views would clear the already stored views.\n"
464
                        "Do you want to continue?"), QMessageBox::Yes | QMessageBox::No,
465
                                                     QMessageBox::Yes);
466
        if (ret != QMessageBox::Yes)
467
            return;
468
    }
469

470
    // Restore the views from an XML file
471
    QString fn = FileDialog::getOpenFileName(getMainWindow(), QObject::tr("Restore frozen views"),
472
                                             QString(), QString::fromLatin1("%1 (*.cam)").arg(QObject::tr("Frozen views")));
473
    if (fn.isEmpty())
474
        return;
475
    QFile file(fn);
476
    if (!file.open(QFile::ReadOnly)) {
477
        QMessageBox::critical(getMainWindow(), QObject::tr("Restore views"),
478
            QObject::tr("Cannot open file '%1'.").arg(fn));
479
        return;
480
    }
481

482
    QDomDocument xmlDocument;
483
    QString errorStr;
484
    int errorLine;
485
    int errorColumn;
486

487
    // evaluate the XML content
488
    if (!xmlDocument.setContent(&file, true, &errorStr, &errorLine, &errorColumn)) {
489
        std::cerr << "Parse error in XML content at line " << errorLine
490
                  << ", column " << errorColumn << ": "
491
                  << (const char*)errorStr.toLatin1() << std::endl;
492
        return;
493
    }
494

495
    // get the root element
496
    QDomElement root = xmlDocument.documentElement();
497
    if (root.tagName() != QLatin1String("FrozenViews")) {
498
        std::cerr << "Unexpected XML structure" << std::endl;
499
        return;
500
    }
501

502
    bool ok;
503
    int scheme = root.attribute(QString::fromLatin1("SchemaVersion")).toInt(&ok);
504
    if (!ok)
505
        return;
506
    // SchemeVersion "1"
507
    if (scheme == 1) {
508
        // read the views, ignore the attribute 'Count'
509
        QDomElement child = root.firstChildElement(QString::fromLatin1("Views"));
510
        QDomElement views = child.firstChildElement(QString::fromLatin1("Camera"));
511
        QStringList cameras;
512
        while (!views.isNull()) {
513
            QString setting = views.attribute(QString::fromLatin1("settings"));
514
            cameras << setting;
515
            views = views.nextSiblingElement(QString::fromLatin1("Camera"));
516
        }
517

518
        // use this rather than the attribute 'Count' because it could be
519
        // changed from outside
520
        int ct = cameras.count();
521
        auto pcAction = qobject_cast<ActionGroup*>(_pcAction);
522
        QList<QAction*> acts = pcAction->actions();
523

524
        int numRestoredViews = std::min<int>(ct, acts.size()-offset);
525
        savedViews = numRestoredViews;
526

527
        if (numRestoredViews > 0)
528
            separator->setVisible(true);
529
        for(int i=0; i<numRestoredViews; i++) {
530
            QString setting = cameras[i];
531
            QString viewnr = QString(QObject::tr("Restore view &%1")).arg(i+1);
532
            acts[i+offset]->setText(viewnr);
533
            acts[i+offset]->setToolTip(setting);
534
            acts[i+offset]->setVisible(true);
535
            if (i < 9) {
536
                acts[i+offset]->setShortcut(QKeySequence(QString::fromLatin1("CTRL+%1").arg(i+1)));
537
            }
538
        }
539

540
        // if less views than actions
541
        for (int index = numRestoredViews+offset; index < acts.count(); index++)
542
            acts[index]->setVisible(false);
543
    }
544
}
545

546
bool StdCmdFreezeViews::isActive()
547
{
548
    auto view = qobject_cast<View3DInventor*>(getMainWindow()->activeWindow());
549
    if (view) {
550
        saveView->setEnabled(savedViews > 0);
551
        freezeView->setEnabled(savedViews < maxViews);
552
        clearView->setEnabled(savedViews > 0);
553
        separator->setVisible(savedViews > 0);
554
        return true;
555
    }
556
    else {
557
        separator->setVisible(savedViews > 0);
558
    }
559

560
    return false;
561
}
562

563
void StdCmdFreezeViews::languageChange()
564
{
565
    Command::languageChange();
566

567
    if (!_pcAction)
568
        return;
569
    auto pcAction = qobject_cast<ActionGroup*>(_pcAction);
570
    QList<QAction*> acts = pcAction->actions();
571
    acts[0]->setText(QObject::tr("Save views..."));
572
    acts[1]->setText(QObject::tr("Load views..."));
573
    acts[3]->setText(QObject::tr("Freeze view"));
574
    acts[4]->setText(QObject::tr("Clear views"));
575
    int index=1;
576
    for (QList<QAction*>::Iterator it = acts.begin()+5; it != acts.end(); ++it, index++) {
577
        if ((*it)->isVisible()) {
578
            QString viewnr = QString(QObject::tr("Restore view &%1")).arg(index);
579
            (*it)->setText(viewnr);
580
        }
581
    }
582
}
583

584

585
//===========================================================================
586
// Std_ToggleClipPlane
587
//===========================================================================
588

589
DEF_STD_CMD_AC(StdCmdToggleClipPlane)
590

591
StdCmdToggleClipPlane::StdCmdToggleClipPlane()
592
  : Command("Std_ToggleClipPlane")
593
{
594
    sGroup        = "Standard-View";
595
    sMenuText     = QT_TR_NOOP("Clipping plane");
596
    sToolTipText  = QT_TR_NOOP("Toggles clipping plane for active view");
597
    sWhatsThis    = "Std_ToggleClipPlane";
598
    sStatusTip    = QT_TR_NOOP("Toggles clipping plane for active view");
599
    sPixmap       = "Std_ToggleClipPlane";
600
    eType         = Alter3DView;
601
}
602

603
Action * StdCmdToggleClipPlane::createAction()
604
{
605
    Action *pcAction = Command::createAction();
606
    return pcAction;
607
}
608

609
void StdCmdToggleClipPlane::activated(int iMsg)
610
{
611
    Q_UNUSED(iMsg);
612
    static QPointer<Gui::Dialog::Clipping> clipping = nullptr;
613
    if (!clipping) {
614
        auto view = qobject_cast<View3DInventor*>(getMainWindow()->activeWindow());
615
        if (view) {
616
            clipping = Gui::Dialog::Clipping::makeDockWidget(view);
617
        }
618
    }
619
}
620

621
bool StdCmdToggleClipPlane::isActive()
622
{
623
    auto view = qobject_cast<View3DInventor*>(getMainWindow()->activeWindow());
624
    return view ? true : false;
625
}
626

627
//===========================================================================
628
// StdCmdDrawStyle
629
//===========================================================================
630
class StdCmdDrawStyle : public Gui::Command
631
{
632
public:
633
    StdCmdDrawStyle();
634
    ~StdCmdDrawStyle() override = default;
635
    void languageChange() override;
636
    const char* className() const override {return "StdCmdDrawStyle";}
637
    void updateIcon(const Gui::MDIView* view);
638
protected:
639
    void activated(int iMsg) override;
640
    bool isActive() override;
641
    Gui::Action * createAction() override;
642
};
643

644
StdCmdDrawStyle::StdCmdDrawStyle()
645
  : Command("Std_DrawStyle")
646
{
647
    sGroup        = "Standard-View";
648
    sMenuText     = QT_TR_NOOP("Draw style");
649
    sToolTipText  = QT_TR_NOOP("Change the draw style of the objects");
650
    sStatusTip    = QT_TR_NOOP("Change the draw style of the objects");
651
    sWhatsThis    = "Std_DrawStyle";
652
    sPixmap       = "DrawStyleAsIs";
653
    eType         = Alter3DView;
654

655
    this->getGuiApplication()->signalActivateView.connect([this](auto view) {
656
        this->updateIcon(view);
657
    });
658
}
659

660
Gui::Action * StdCmdDrawStyle::createAction()
661
{
662
    auto pcAction = new Gui::ActionGroup(this, Gui::getMainWindow());
663
    pcAction->setDropDownMenu(true);
664
    pcAction->setIsMode(true);
665
    applyCommandData(this->className(), pcAction);
666

667
    QAction* a0 = pcAction->addAction(QString());
668
    a0->setCheckable(true);
669
    a0->setIcon(BitmapFactory().iconFromTheme("DrawStyleAsIs"));
670
    a0->setChecked(true);
671
    a0->setObjectName(QString::fromLatin1("Std_DrawStyleAsIs"));
672
    a0->setShortcut(QKeySequence(QString::fromUtf8("V,1")));
673
    a0->setWhatsThis(QString::fromLatin1(getWhatsThis()));
674
    QAction* a1 = pcAction->addAction(QString());
675
    a1->setCheckable(true);
676
    a1->setIcon(BitmapFactory().iconFromTheme("DrawStylePoints"));
677
    a1->setObjectName(QString::fromLatin1("Std_DrawStylePoints"));
678
    a1->setShortcut(QKeySequence(QString::fromUtf8("V,2")));
679
    a1->setWhatsThis(QString::fromLatin1(getWhatsThis()));
680
    QAction* a2 = pcAction->addAction(QString());
681
    a2->setCheckable(true);
682
    a2->setIcon(BitmapFactory().iconFromTheme("DrawStyleWireFrame"));
683
    a2->setObjectName(QString::fromLatin1("Std_DrawStyleWireframe"));
684
    a2->setShortcut(QKeySequence(QString::fromUtf8("V,3")));
685
    a2->setWhatsThis(QString::fromLatin1(getWhatsThis()));
686
    QAction* a3 = pcAction->addAction(QString());
687
    a3->setCheckable(true);
688
    a3->setIcon(BitmapFactory().iconFromTheme("DrawStyleHiddenLine"));
689
    a3->setObjectName(QString::fromLatin1("Std_DrawStyleHiddenLine"));
690
    a3->setShortcut(QKeySequence(QString::fromUtf8("V,4")));
691
    a3->setWhatsThis(QString::fromLatin1(getWhatsThis()));
692
    QAction* a4 = pcAction->addAction(QString());
693
    a4->setCheckable(true);
694
    a4->setIcon(BitmapFactory().iconFromTheme("DrawStyleNoShading"));
695
    a4->setObjectName(QString::fromLatin1("Std_DrawStyleNoShading"));
696
    a4->setShortcut(QKeySequence(QString::fromUtf8("V,5")));
697
    a4->setWhatsThis(QString::fromLatin1(getWhatsThis()));
698
    QAction* a5 = pcAction->addAction(QString());
699
    a5->setCheckable(true);
700
    a5->setIcon(BitmapFactory().iconFromTheme("DrawStyleShaded"));
701
    a5->setObjectName(QString::fromLatin1("Std_DrawStyleShaded"));
702
    a5->setShortcut(QKeySequence(QString::fromUtf8("V,6")));
703
    a5->setWhatsThis(QString::fromLatin1(getWhatsThis()));
704
    QAction* a6 = pcAction->addAction(QString());
705
    a6->setCheckable(true);
706
    a6->setIcon(BitmapFactory().iconFromTheme("DrawStyleFlatLines"));
707
    a6->setObjectName(QString::fromLatin1("Std_DrawStyleFlatLines"));
708
    a6->setShortcut(QKeySequence(QString::fromUtf8("V,7")));
709
    a6->setWhatsThis(QString::fromLatin1(getWhatsThis()));
710

711
    pcAction->setIcon(a0->icon());
712

713
    _pcAction = pcAction;
714
    languageChange();
715
    return pcAction;
716
}
717

718
void StdCmdDrawStyle::languageChange()
719
{
720
    Command::languageChange();
721

722
    if (!_pcAction)
723
        return;
724
    auto pcAction = qobject_cast<Gui::ActionGroup*>(_pcAction);
725
    QList<QAction*> a = pcAction->actions();
726

727
    a[0]->setText(QCoreApplication::translate(
728
        "Std_DrawStyle", "As is"));
729
    a[0]->setToolTip(QCoreApplication::translate(
730
        "Std_DrawStyle", "Normal mode"));
731

732
    a[1]->setText(QCoreApplication::translate(
733
        "Std_DrawStyle", "Points"));
734
    a[1]->setToolTip(QCoreApplication::translate(
735
        "Std_DrawStyle", "Points mode"));
736

737
    a[2]->setText(QCoreApplication::translate(
738
        "Std_DrawStyle", "Wireframe"));
739
    a[2]->setToolTip(QCoreApplication::translate(
740
        "Std_DrawStyle", "Wireframe mode"));
741

742
    a[3]->setText(QCoreApplication::translate(
743
        "Std_DrawStyle", "Hidden line"));
744
    a[3]->setToolTip(QCoreApplication::translate(
745
        "Std_DrawStyle", "Hidden line mode"));
746

747
    a[4]->setText(QCoreApplication::translate(
748
        "Std_DrawStyle", "No shading"));
749
    a[4]->setToolTip(QCoreApplication::translate(
750
        "Std_DrawStyle", "No shading mode"));
751

752
    a[5]->setText(QCoreApplication::translate(
753
        "Std_DrawStyle", "Shaded"));
754
    a[5]->setToolTip(QCoreApplication::translate(
755
        "Std_DrawStyle", "Shaded mode"));
756

757
    a[6]->setText(QCoreApplication::translate(
758
        "Std_DrawStyle", "Flat lines"));
759
    a[6]->setToolTip(QCoreApplication::translate(
760
        "Std_DrawStyle", "Flat lines mode"));
761
}
762

763
void StdCmdDrawStyle::updateIcon(const MDIView *view)
764
{
765
    const auto view3d = dynamic_cast<const Gui::View3DInventor *>(view);
766
    if (!view3d)
767
        return;
768
    Gui::View3DInventorViewer *viewer = view3d->getViewer();
769
    if (!viewer)
770
        return;
771
    std::string mode(viewer->getOverrideMode());
772
    auto actionGroup = dynamic_cast<Gui::ActionGroup *>(_pcAction);
773
    if (!actionGroup)
774
        return;
775

776
    if (mode == "Point")
777
    {
778
        actionGroup->setCheckedAction(1);
779
        return;
780
    }
781
    if (mode == "Wireframe")
782
    {
783
        actionGroup->setCheckedAction(2);
784
        return;
785
    }
786
    if (mode == "Hidden Line")
787
    {
788
        actionGroup->setCheckedAction(3);
789
        return;
790
    }
791
    if (mode == "No shading")
792
    {
793
        actionGroup->setCheckedAction(4);
794
        return;
795
    }
796
    if (mode == "Shaded")
797
    {
798
        actionGroup->setCheckedAction(5);
799
        return;
800
    }
801
    if (mode == "Flat Lines")
802
    {
803
        actionGroup->setCheckedAction(6);
804
        return;
805
    }
806
    actionGroup->setCheckedAction(0);
807
}
808

809
void StdCmdDrawStyle::activated(int iMsg)
810
{
811
    Gui::Document *doc = this->getActiveGuiDocument();
812
    std::list<MDIView*> views = doc->getMDIViews();
813
    std::list<MDIView*>::iterator viewIt;
814
    bool oneChangedSignal(false);
815
    for (viewIt = views.begin(); viewIt != views.end(); ++viewIt)
816
    {
817
        auto view = qobject_cast<View3DInventor*>(*viewIt);
818
        if (view)
819
        {
820
            View3DInventorViewer* viewer;
821
            viewer = view->getViewer();
822
            if (viewer)
823
            {
824
                switch (iMsg)
825
                {
826
                case 1:
827
                    (oneChangedSignal) ? viewer->updateOverrideMode("Point") : viewer->setOverrideMode("Point");
828
                    break;
829
                case 2:
830
                    (oneChangedSignal) ? viewer->updateOverrideMode("Wireframe") : viewer->setOverrideMode("Wireframe");
831
                    break;
832
                case 3:
833
                    (oneChangedSignal) ? viewer->updateOverrideMode("Hidden Line") : viewer->setOverrideMode("Hidden Line");
834
                    break;
835
                case 4:
836
                    (oneChangedSignal) ? viewer->updateOverrideMode("No Shading") : viewer->setOverrideMode("No Shading");
837
                    break;
838
                case 5:
839
                    (oneChangedSignal) ? viewer->updateOverrideMode("Shaded") : viewer->setOverrideMode("Shaded");
840
                    break;
841
                case 6:
842
                    (oneChangedSignal) ? viewer->updateOverrideMode("Flat Lines") : viewer->setOverrideMode("Flat Lines");
843
                    break;
844
                default:
845
                    (oneChangedSignal) ? viewer->updateOverrideMode("As Is") : viewer->setOverrideMode("As Is");
846
                    break;
847
                }
848
                oneChangedSignal = true;
849
            }
850
        }
851
    }
852
}
853

854
bool StdCmdDrawStyle::isActive()
855
{
856
    return Gui::Application::Instance->activeDocument();
857
}
858

859
//===========================================================================
860
// Std_ToggleVisibility
861
//===========================================================================
862
DEF_STD_CMD_A(StdCmdToggleVisibility)
863

864
StdCmdToggleVisibility::StdCmdToggleVisibility()
865
  : Command("Std_ToggleVisibility")
866
{
867
    sGroup        = "Standard-View";
868
    sMenuText     = QT_TR_NOOP("Toggle visibility");
869
    sToolTipText  = QT_TR_NOOP("Toggles visibility");
870
    sStatusTip    = QT_TR_NOOP("Toggles visibility");
871
    sWhatsThis    = "Std_ToggleVisibility";
872
    sPixmap       = "Std_ToggleVisibility";
873
    sAccel        = "Space";
874
    eType         = Alter3DView;
875
}
876

877

878
void StdCmdToggleVisibility::activated(int iMsg)
879
{
880
    Q_UNUSED(iMsg);
881
    TransactionView transaction(getActiveGuiDocument(), QT_TRANSLATE_NOOP("Command", "Toggle visibility"));
882
    Selection().setVisible(SelectionSingleton::VisToggle);
883
}
884

885
bool StdCmdToggleVisibility::isActive()
886
{
887
    return (Gui::Selection().size() != 0);
888
}
889

890
//===========================================================================
891
// Std_ToggleTransparency
892
//===========================================================================
893
DEF_STD_CMD_A(StdCmdToggleTransparency)
894

895
StdCmdToggleTransparency::StdCmdToggleTransparency()
896
    : Command("Std_ToggleTransparency")
897
{
898
    sGroup = "Standard-View";
899
    sMenuText = QT_TR_NOOP("Toggle transparency");
900
    static std::string toolTip = std::string("<p>")
901
        + QT_TR_NOOP("Toggles transparency of the selected objects. You can also fine tune transparency "
902
            "value in the Appearance taskbox (right click an object in the tree, Appearance).")
903
        + "</p>";
904
    sToolTipText = toolTip.c_str();
905
    sStatusTip = sToolTipText;
906
    sWhatsThis = "Std_ToggleTransparency";
907
    sPixmap = "Std_ToggleTransparency";
908
    sAccel = "V,T";
909
    eType = Alter3DView;
910
}
911

912
void StdCmdToggleTransparency::activated(int iMsg)
913
{
914
    Q_UNUSED(iMsg);
915
    getActiveGuiDocument()->openCommand(QT_TRANSLATE_NOOP("Command", "Toggle transparency"));
916

917
    std::vector<Gui::SelectionSingleton::SelObj> sels = Gui::Selection().getCompleteSelection();
918

919
    std::vector<Gui::ViewProvider*> viewsToToggle = {};
920

921
    for (Gui::SelectionSingleton::SelObj& sel : sels) {
922
        App::DocumentObject* obj = sel.pObject;
923
        if (!obj)
924
            continue;
925

926
        bool isGroup = dynamic_cast<App::Part*>(obj)
927
                || dynamic_cast<App::LinkGroup*>(obj)
928
                || dynamic_cast<App::DocumentObjectGroup*>(obj);
929

930
        auto addObjects = [](App::DocumentObject* obj, std::vector<Gui::ViewProvider*>& views) {
931
            App::Document* doc = obj->getDocument();
932
            Gui::ViewProvider* view = Application::Instance->getDocument(doc)->getViewProvider(obj);
933
            App::Property* prop = view->getPropertyByName("Transparency");
934
            if (prop && prop->getTypeId().isDerivedFrom(App::PropertyInteger::getClassTypeId())) {
935
                // To prevent toggling the tip of a PD body (see #11353), we check if the parent has a
936
                // Tip prop.
937
                const std::vector<App::DocumentObject*> parents = obj->getInList();
938
                if (!parents.empty()) {
939
                    App::Document* parentDoc = parents[0]->getDocument();
940
                    Gui::ViewProvider* parentView = Application::Instance->getDocument(parentDoc)->getViewProvider(parents[0]);
941
                    App::Property* parentProp = parents[0]->getPropertyByName("Tip");
942
                    if (parentProp) {
943
                        // Make sure it has a transparency prop too
944
                        parentProp = parentView->getPropertyByName("Transparency");
945
                        if (parentProp && parentProp->getTypeId().isDerivedFrom(App::PropertyInteger::getClassTypeId())) {
946
                            view = parentView;
947
                        }
948
                    }
949
                }
950

951
                if (std::find(views.begin(), views.end(), view) == views.end()) {
952
                    views.push_back(view);
953
                }
954
            }
955
        };
956

957
        if (isGroup) {
958
            for (App::DocumentObject* subobj : obj->getOutListRecursive()) {
959
                addObjects(subobj, viewsToToggle);
960
            }
961
        }
962
        else {
963
            addObjects(obj, viewsToToggle);
964
        }
965
    }
966

967
    bool oneTransparent = false;
968
    for (auto* view : viewsToToggle) {
969
        App::Property* prop = view->getPropertyByName("Transparency");
970
        if (prop && prop->getTypeId().isDerivedFrom(App::PropertyInteger::getClassTypeId())) {
971
            auto* transparencyProp = dynamic_cast<App::PropertyInteger*>(prop);
972
            int transparency = transparencyProp->getValue();
973
            if (transparency != 0) {
974
                oneTransparent = true;
975
            }
976
        }
977
    }
978

979
    int transparency = oneTransparent ? 0 : 70;
980

981
    for (auto* view : viewsToToggle) {
982
        App::Property* prop = view->getPropertyByName("Transparency");
983
        if (prop && prop->getTypeId().isDerivedFrom(App::PropertyInteger::getClassTypeId())) {
984
            auto* transparencyProp = dynamic_cast<App::PropertyInteger*>(prop);
985
            transparencyProp->setValue(transparency);
986
        }
987
    }
988

989
    getActiveGuiDocument()->commitCommand();
990
}
991

992
bool StdCmdToggleTransparency::isActive()
993
{
994
    return (Gui::Selection().size() != 0);
995
}
996

997
//===========================================================================
998
// Std_ToggleSelectability
999
//===========================================================================
1000
DEF_STD_CMD_A(StdCmdToggleSelectability)
1001

1002
StdCmdToggleSelectability::StdCmdToggleSelectability()
1003
  : Command("Std_ToggleSelectability")
1004
{
1005
    sGroup        = "Standard-View";
1006
    sMenuText     = QT_TR_NOOP("Toggle selectability");
1007
    sToolTipText  = QT_TR_NOOP("Toggles the property of the objects to get selected in the 3D-View");
1008
    sStatusTip    = QT_TR_NOOP("Toggles the property of the objects to get selected in the 3D-View");
1009
    sWhatsThis    = "Std_ToggleSelectability";
1010
    sPixmap       = "view-unselectable";
1011
    eType         = Alter3DView;
1012
}
1013

1014
void StdCmdToggleSelectability::activated(int iMsg)
1015
{
1016
    Q_UNUSED(iMsg);
1017
    // go through all documents
1018
    const std::vector<App::Document*> docs = App::GetApplication().getDocuments();
1019
    for (const auto & doc : docs) {
1020
        Document *pcDoc = Application::Instance->getDocument(doc);
1021
        std::vector<App::DocumentObject*> sel = Selection().getObjectsOfType
1022
            (App::DocumentObject::getClassTypeId(), doc->getName());
1023

1024
        if (sel.empty()) {
1025
            continue;
1026
        }
1027

1028
        TransactionView transaction(pcDoc, QT_TRANSLATE_NOOP("Command", "Toggle selectability"));
1029

1030
        for (const auto & ft : sel) {
1031
            ViewProvider *pr = pcDoc->getViewProviderByName(ft->getNameInDocument());
1032
            if (pr && pr->isDerivedFrom(ViewProviderGeometryObject::getClassTypeId())){
1033
                if (static_cast<ViewProviderGeometryObject*>(pr)->Selectable.getValue())
1034
                    doCommand(Gui,"Gui.getDocument(\"%s\").getObject(\"%s\").Selectable=False"
1035
                                 , doc->getName(), ft->getNameInDocument());
1036
                else
1037
                    doCommand(Gui,"Gui.getDocument(\"%s\").getObject(\"%s\").Selectable=True"
1038
                                 , doc->getName(), ft->getNameInDocument());
1039
            }
1040
        }
1041
    }
1042
}
1043

1044
bool StdCmdToggleSelectability::isActive()
1045
{
1046
    return (Gui::Selection().size() != 0);
1047
}
1048

1049
//===========================================================================
1050
// Std_ShowSelection
1051
//===========================================================================
1052
DEF_STD_CMD_A(StdCmdShowSelection)
1053

1054
StdCmdShowSelection::StdCmdShowSelection()
1055
  : Command("Std_ShowSelection")
1056
{
1057
    sGroup        = "Standard-View";
1058
    sMenuText     = QT_TR_NOOP("Show selection");
1059
    sToolTipText  = QT_TR_NOOP("Show all selected objects");
1060
    sStatusTip    = QT_TR_NOOP("Show all selected objects");
1061
    sWhatsThis    = "Std_ShowSelection";
1062
    sPixmap       = "Std_ShowSelection";
1063
    eType         = Alter3DView;
1064
}
1065

1066
void StdCmdShowSelection::activated(int iMsg)
1067
{
1068
    Q_UNUSED(iMsg);
1069
    Selection().setVisible(SelectionSingleton::VisShow);
1070
}
1071

1072
bool StdCmdShowSelection::isActive()
1073
{
1074
    return (Gui::Selection().size() != 0);
1075
}
1076

1077
//===========================================================================
1078
// Std_HideSelection
1079
//===========================================================================
1080
DEF_STD_CMD_A(StdCmdHideSelection)
1081

1082
StdCmdHideSelection::StdCmdHideSelection()
1083
  : Command("Std_HideSelection")
1084
{
1085
    sGroup        = "Standard-View";
1086
    sMenuText     = QT_TR_NOOP("Hide selection");
1087
    sToolTipText  = QT_TR_NOOP("Hide all selected objects");
1088
    sStatusTip    = QT_TR_NOOP("Hide all selected objects");
1089
    sWhatsThis    = "Std_HideSelection";
1090
    sPixmap       = "Std_HideSelection";
1091
    eType         = Alter3DView;
1092
}
1093

1094
void StdCmdHideSelection::activated(int iMsg)
1095
{
1096
    Q_UNUSED(iMsg);
1097
    Selection().setVisible(SelectionSingleton::VisHide);
1098
}
1099

1100
bool StdCmdHideSelection::isActive()
1101
{
1102
    return (Gui::Selection().size() != 0);
1103
}
1104

1105
//===========================================================================
1106
// Std_SelectVisibleObjects
1107
//===========================================================================
1108
DEF_STD_CMD_A(StdCmdSelectVisibleObjects)
1109

1110
StdCmdSelectVisibleObjects::StdCmdSelectVisibleObjects()
1111
  : Command("Std_SelectVisibleObjects")
1112
{
1113
    sGroup        = "Standard-View";
1114
    sMenuText     = QT_TR_NOOP("Select visible objects");
1115
    sToolTipText  = QT_TR_NOOP("Select visible objects in the active document");
1116
    sStatusTip    = QT_TR_NOOP("Select visible objects in the active document");
1117
    sWhatsThis    = "Std_SelectVisibleObjects";
1118
    sPixmap       = "Std_SelectVisibleObjects";
1119
    eType         = Alter3DView;
1120
}
1121

1122
void StdCmdSelectVisibleObjects::activated(int iMsg)
1123
{
1124
    Q_UNUSED(iMsg);
1125
    // go through active document
1126
    Gui::Document* doc = Application::Instance->activeDocument();
1127
    App::Document* app = doc->getDocument();
1128
    const std::vector<App::DocumentObject*> obj = app->getObjectsOfType
1129
        (App::DocumentObject::getClassTypeId());
1130

1131
    std::vector<App::DocumentObject*> visible;
1132
    visible.reserve(obj.size());
1133
    for (const auto & it : obj) {
1134
        if (doc->isShow(it->getNameInDocument()))
1135
            visible.push_back(it);
1136
    }
1137

1138
    SelectionSingleton& rSel = Selection();
1139
    rSel.setSelection(app->getName(), visible);
1140
}
1141

1142
bool StdCmdSelectVisibleObjects::isActive()
1143
{
1144
    return App::GetApplication().getActiveDocument();
1145
}
1146

1147
//===========================================================================
1148
// Std_ToggleObjects
1149
//===========================================================================
1150
DEF_STD_CMD_A(StdCmdToggleObjects)
1151

1152
StdCmdToggleObjects::StdCmdToggleObjects()
1153
  : Command("Std_ToggleObjects")
1154
{
1155
    sGroup        = "Standard-View";
1156
    sMenuText     = QT_TR_NOOP("Toggle all objects");
1157
    sToolTipText  = QT_TR_NOOP("Toggles visibility of all objects in the active document");
1158
    sStatusTip    = QT_TR_NOOP("Toggles visibility of all objects in the active document");
1159
    sWhatsThis    = "Std_ToggleObjects";
1160
    sPixmap       = "Std_ToggleObjects";
1161
    eType         = Alter3DView;
1162
}
1163

1164
void StdCmdToggleObjects::activated(int iMsg)
1165
{
1166
    Q_UNUSED(iMsg);
1167
    // go through active document
1168
    Gui::Document* doc = Application::Instance->activeDocument();
1169
    App::Document* app = doc->getDocument();
1170
    const std::vector<App::DocumentObject*> obj = app->getObjectsOfType
1171
        (App::DocumentObject::getClassTypeId());
1172

1173
    for (const auto & it : obj) {
1174
        if (doc->isShow(it->getNameInDocument()))
1175
            doCommand(Gui,"Gui.getDocument(\"%s\").getObject(\"%s\").Visibility=False"
1176
                         , app->getName(), it->getNameInDocument());
1177
        else
1178
            doCommand(Gui,"Gui.getDocument(\"%s\").getObject(\"%s\").Visibility=True"
1179
                         , app->getName(), it->getNameInDocument());
1180
    }
1181
}
1182

1183
bool StdCmdToggleObjects::isActive()
1184
{
1185
    return App::GetApplication().getActiveDocument();
1186
}
1187

1188
//===========================================================================
1189
// Std_ShowObjects
1190
//===========================================================================
1191
DEF_STD_CMD_A(StdCmdShowObjects)
1192

1193
StdCmdShowObjects::StdCmdShowObjects()
1194
  : Command("Std_ShowObjects")
1195
{
1196
    sGroup        = "Standard-View";
1197
    sMenuText     = QT_TR_NOOP("Show all objects");
1198
    sToolTipText  = QT_TR_NOOP("Show all objects in the document");
1199
    sStatusTip    = QT_TR_NOOP("Show all objects in the document");
1200
    sWhatsThis    = "Std_ShowObjects";
1201
    sPixmap       = "Std_ShowObjects";
1202
    eType         = Alter3DView;
1203
}
1204

1205
void StdCmdShowObjects::activated(int iMsg)
1206
{
1207
    Q_UNUSED(iMsg);
1208
    // go through active document
1209
    Gui::Document* doc = Application::Instance->activeDocument();
1210
    App::Document* app = doc->getDocument();
1211
    const std::vector<App::DocumentObject*> obj = app->getObjectsOfType
1212
        (App::DocumentObject::getClassTypeId());
1213

1214
    for (const auto & it : obj) {
1215
        doCommand(Gui,"Gui.getDocument(\"%s\").getObject(\"%s\").Visibility=True"
1216
                     , app->getName(), it->getNameInDocument());
1217
    }
1218
}
1219

1220
bool StdCmdShowObjects::isActive()
1221
{
1222
    return App::GetApplication().getActiveDocument();
1223
}
1224

1225
//===========================================================================
1226
// Std_HideObjects
1227
//===========================================================================
1228
DEF_STD_CMD_A(StdCmdHideObjects)
1229

1230
StdCmdHideObjects::StdCmdHideObjects()
1231
  : Command("Std_HideObjects")
1232
{
1233
    sGroup        = "Standard-View";
1234
    sMenuText     = QT_TR_NOOP("Hide all objects");
1235
    sToolTipText  = QT_TR_NOOP("Hide all objects in the document");
1236
    sStatusTip    = QT_TR_NOOP("Hide all objects in the document");
1237
    sWhatsThis    = "Std_HideObjects";
1238
    sPixmap       = "Std_HideObjects";
1239
    eType         = Alter3DView;
1240
}
1241

1242
void StdCmdHideObjects::activated(int iMsg)
1243
{
1244
    Q_UNUSED(iMsg);
1245
    // go through active document
1246
    Gui::Document* doc = Application::Instance->activeDocument();
1247
    App::Document* app = doc->getDocument();
1248
    const std::vector<App::DocumentObject*> obj = app->getObjectsOfType
1249
        (App::DocumentObject::getClassTypeId());
1250

1251
    for (const auto & it : obj) {
1252
        doCommand(Gui,"Gui.getDocument(\"%s\").getObject(\"%s\").Visibility=False"
1253
                     , app->getName(), it->getNameInDocument());
1254
    }
1255
}
1256

1257
bool StdCmdHideObjects::isActive()
1258
{
1259
    return App::GetApplication().getActiveDocument();
1260
}
1261

1262
//===========================================================================
1263
// Std_ViewHome
1264
//===========================================================================
1265
DEF_3DV_CMD(StdCmdViewHome)
1266

1267
StdCmdViewHome::StdCmdViewHome()
1268
  : Command("Std_ViewHome")
1269
{
1270
    sGroup        = "Standard-View";
1271
    sMenuText     = QT_TR_NOOP("Home");
1272
    sToolTipText  = QT_TR_NOOP("Set to default home view");
1273
    sWhatsThis    = "Std_ViewHome";
1274
    sStatusTip    = QT_TR_NOOP("Set to default home view");
1275
    sPixmap       = "Std_ViewHome";
1276
    sAccel        = "Home";
1277
    eType         = Alter3DView;
1278
}
1279

1280
void StdCmdViewHome::activated(int iMsg)
1281
{
1282
    Q_UNUSED(iMsg);
1283

1284
    auto hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
1285
    std::string default_view = hGrp->GetASCII("NewDocumentCameraOrientation","Top");
1286
    doCommand(Command::Gui,"Gui.activeDocument().activeView().viewDefaultOrientation('%s',0)",default_view.c_str());
1287
    doCommand(Command::Gui,"Gui.SendMsgToActiveView(\"ViewFit\")");
1288
}
1289

1290
//===========================================================================
1291
// Std_ViewBottom
1292
//===========================================================================
1293
DEF_3DV_CMD(StdCmdViewBottom)
1294

1295
StdCmdViewBottom::StdCmdViewBottom()
1296
  : Command("Std_ViewBottom")
1297
{
1298
    sGroup        = "Standard-View";
1299
    sMenuText     = QT_TR_NOOP("Bottom");
1300
    sToolTipText  = QT_TR_NOOP("Set to bottom view");
1301
    sWhatsThis    = "Std_ViewBottom";
1302
    sStatusTip    = QT_TR_NOOP("Set to bottom view");
1303
    sPixmap       = "view-bottom";
1304
    sAccel        = "5";
1305
    eType         = Alter3DView;
1306
}
1307

1308
void StdCmdViewBottom::activated(int iMsg)
1309
{
1310
    Q_UNUSED(iMsg);
1311
    doCommand(Command::Gui,"Gui.activeDocument().activeView().viewBottom()");
1312
}
1313

1314
//===========================================================================
1315
// Std_ViewFront
1316
//===========================================================================
1317
DEF_3DV_CMD(StdCmdViewFront)
1318

1319
StdCmdViewFront::StdCmdViewFront()
1320
  : Command("Std_ViewFront")
1321
{
1322
    sGroup        = "Standard-View";
1323
    sMenuText     = QT_TR_NOOP("Front");
1324
    sToolTipText  = QT_TR_NOOP("Set to front view");
1325
    sWhatsThis    = "Std_ViewFront";
1326
    sStatusTip    = QT_TR_NOOP("Set to front view");
1327
    sPixmap       = "view-front";
1328
    sAccel        = "1";
1329
    eType         = Alter3DView;
1330
}
1331

1332
void StdCmdViewFront::activated(int iMsg)
1333
{
1334
    Q_UNUSED(iMsg);
1335
    doCommand(Command::Gui,"Gui.activeDocument().activeView().viewFront()");
1336
}
1337

1338
//===========================================================================
1339
// Std_ViewLeft
1340
//===========================================================================
1341
DEF_3DV_CMD(StdCmdViewLeft)
1342

1343
StdCmdViewLeft::StdCmdViewLeft()
1344
  : Command("Std_ViewLeft")
1345
{
1346
    sGroup        = "Standard-View";
1347
    sMenuText     = QT_TR_NOOP("Left");
1348
    sToolTipText  = QT_TR_NOOP("Set to left view");
1349
    sWhatsThis    = "Std_ViewLeft";
1350
    sStatusTip    = QT_TR_NOOP("Set to left view");
1351
    sPixmap       = "view-left";
1352
    sAccel        = "6";
1353
    eType         = Alter3DView;
1354
}
1355

1356
void StdCmdViewLeft::activated(int iMsg)
1357
{
1358
    Q_UNUSED(iMsg);
1359
    doCommand(Command::Gui,"Gui.activeDocument().activeView().viewLeft()");
1360
}
1361

1362
//===========================================================================
1363
// Std_ViewRear
1364
//===========================================================================
1365
DEF_3DV_CMD(StdCmdViewRear)
1366

1367
StdCmdViewRear::StdCmdViewRear()
1368
  : Command("Std_ViewRear")
1369
{
1370
    sGroup        = "Standard-View";
1371
    sMenuText     = QT_TR_NOOP("Rear");
1372
    sToolTipText  = QT_TR_NOOP("Set to rear view");
1373
    sWhatsThis    = "Std_ViewRear";
1374
    sStatusTip    = QT_TR_NOOP("Set to rear view");
1375
    sPixmap       = "view-rear";
1376
    sAccel        = "4";
1377
    eType         = Alter3DView;
1378
}
1379

1380
void StdCmdViewRear::activated(int iMsg)
1381
{
1382
    Q_UNUSED(iMsg);
1383
    doCommand(Command::Gui,"Gui.activeDocument().activeView().viewRear()");
1384
}
1385

1386
//===========================================================================
1387
// Std_ViewRight
1388
//===========================================================================
1389
DEF_3DV_CMD(StdCmdViewRight)
1390

1391
StdCmdViewRight::StdCmdViewRight()
1392
  : Command("Std_ViewRight")
1393
{
1394
    sGroup        = "Standard-View";
1395
    sMenuText     = QT_TR_NOOP("Right");
1396
    sToolTipText  = QT_TR_NOOP("Set to right view");
1397
    sWhatsThis    = "Std_ViewRight";
1398
    sStatusTip    = QT_TR_NOOP("Set to right view");
1399
    sPixmap       = "view-right";
1400
    sAccel        = "3";
1401
    eType         = Alter3DView;
1402
}
1403

1404
void StdCmdViewRight::activated(int iMsg)
1405
{
1406
    Q_UNUSED(iMsg);
1407
    doCommand(Command::Gui,"Gui.activeDocument().activeView().viewRight()");
1408
}
1409

1410
//===========================================================================
1411
// Std_ViewTop
1412
//===========================================================================
1413
DEF_3DV_CMD(StdCmdViewTop)
1414

1415
StdCmdViewTop::StdCmdViewTop()
1416
  : Command("Std_ViewTop")
1417
{
1418
    sGroup        = "Standard-View";
1419
    sMenuText     = QT_TR_NOOP("Top");
1420
    sToolTipText  = QT_TR_NOOP("Set to top view");
1421
    sWhatsThis    = "Std_ViewTop";
1422
    sStatusTip    = QT_TR_NOOP("Set to top view");
1423
    sPixmap       = "view-top";
1424
    sAccel        = "2";
1425
    eType         = Alter3DView;
1426
}
1427

1428
void StdCmdViewTop::activated(int iMsg)
1429
{
1430
    Q_UNUSED(iMsg);
1431
    doCommand(Command::Gui,"Gui.activeDocument().activeView().viewTop()");
1432
}
1433

1434

1435
//===========================================================================
1436
// Std_ViewIsometric
1437
//===========================================================================
1438
DEF_3DV_CMD(StdCmdViewIsometric)
1439

1440
StdCmdViewIsometric::StdCmdViewIsometric()
1441
  : Command("Std_ViewIsometric")
1442
{
1443
    sGroup      = "Standard-View";
1444
    sMenuText   = QT_TR_NOOP("Isometric");
1445
    sToolTipText= QT_TR_NOOP("Set to isometric view");
1446
    sWhatsThis  = "Std_ViewIsometric";
1447
    sStatusTip  = QT_TR_NOOP("Set to isometric view");
1448
    sPixmap     = "view-axonometric";
1449
    sAccel      = "0";
1450
    eType         = Alter3DView;
1451
}
1452

1453
void StdCmdViewIsometric::activated(int iMsg)
1454
{
1455
    Q_UNUSED(iMsg);
1456
    doCommand(Command::Gui,"Gui.activeDocument().activeView().viewIsometric()");
1457
}
1458

1459
//===========================================================================
1460
// Std_ViewDimetric
1461
//===========================================================================
1462
DEF_3DV_CMD(StdCmdViewDimetric)
1463

1464
StdCmdViewDimetric::StdCmdViewDimetric()
1465
  : Command("Std_ViewDimetric")
1466
{
1467
    sGroup      = "Standard-View";
1468
    sMenuText   = QT_TR_NOOP("Dimetric");
1469
    sToolTipText= QT_TR_NOOP("Set to dimetric view");
1470
    sWhatsThis  = "Std_ViewDimetric";
1471
    sStatusTip  = QT_TR_NOOP("Set to dimetric view");
1472
    sPixmap       = "Std_ViewDimetric";
1473
    eType         = Alter3DView;
1474
}
1475

1476
void StdCmdViewDimetric::activated(int iMsg)
1477
{
1478
    Q_UNUSED(iMsg);
1479
    doCommand(Command::Gui,"Gui.activeDocument().activeView().viewDimetric()");
1480
}
1481

1482
//===========================================================================
1483
// Std_ViewTrimetric
1484
//===========================================================================
1485
DEF_3DV_CMD(StdCmdViewTrimetric)
1486

1487
StdCmdViewTrimetric::StdCmdViewTrimetric()
1488
  : Command("Std_ViewTrimetric")
1489
{
1490
    sGroup      = "Standard-View";
1491
    sMenuText   = QT_TR_NOOP("Trimetric");
1492
    sToolTipText= QT_TR_NOOP("Set to trimetric view");
1493
    sWhatsThis  = "Std_ViewTrimetric";
1494
    sStatusTip  = QT_TR_NOOP("Set to trimetric view");
1495
    sPixmap       = "Std_ViewTrimetric";
1496
    eType         = Alter3DView;
1497
}
1498

1499
void StdCmdViewTrimetric::activated(int iMsg)
1500
{
1501
    Q_UNUSED(iMsg);
1502
    doCommand(Command::Gui,"Gui.activeDocument().activeView().viewTrimetric()");
1503
}
1504

1505
//===========================================================================
1506
// Std_ViewRotateLeft
1507
//===========================================================================
1508
DEF_3DV_CMD(StdCmdViewRotateLeft)
1509

1510
StdCmdViewRotateLeft::StdCmdViewRotateLeft()
1511
  : Command("Std_ViewRotateLeft")
1512
{
1513
    sGroup        = "Standard-View";
1514
    sMenuText     = QT_TR_NOOP("Rotate Left");
1515
    sToolTipText  = QT_TR_NOOP("Rotate the view by 90\xc2\xb0 counter-clockwise");
1516
    sWhatsThis    = "Std_ViewRotateLeft";
1517
    sStatusTip    = QT_TR_NOOP("Rotate the view by 90\xc2\xb0 counter-clockwise");
1518
    sPixmap       = "view-rotate-left";
1519
    sAccel        = "Shift+Left";
1520
    eType         = Alter3DView;
1521
}
1522

1523
void StdCmdViewRotateLeft::activated(int iMsg)
1524
{
1525
    Q_UNUSED(iMsg);
1526
    doCommand(Command::Gui,"Gui.activeDocument().activeView().viewRotateLeft()");
1527
}
1528

1529

1530
//===========================================================================
1531
// Std_ViewRotateRight
1532
//===========================================================================
1533
DEF_3DV_CMD(StdCmdViewRotateRight)
1534

1535
StdCmdViewRotateRight::StdCmdViewRotateRight()
1536
  : Command("Std_ViewRotateRight")
1537
{
1538
    sGroup        = "Standard-View";
1539
    sMenuText     = QT_TR_NOOP("Rotate Right");
1540
    sToolTipText  = QT_TR_NOOP("Rotate the view by 90\xc2\xb0 clockwise");
1541
    sWhatsThis    = "Std_ViewRotateRight";
1542
    sStatusTip    = QT_TR_NOOP("Rotate the view by 90\xc2\xb0 clockwise");
1543
    sPixmap       = "view-rotate-right";
1544
    sAccel        = "Shift+Right";
1545
    eType         = Alter3DView;
1546
}
1547

1548
void StdCmdViewRotateRight::activated(int iMsg)
1549
{
1550
    Q_UNUSED(iMsg);
1551
    doCommand(Command::Gui,"Gui.activeDocument().activeView().viewRotateRight()");
1552
}
1553

1554

1555
//===========================================================================
1556
// Std_ViewFitAll
1557
//===========================================================================
1558
DEF_STD_CMD_A(StdCmdViewFitAll)
1559

1560
StdCmdViewFitAll::StdCmdViewFitAll()
1561
  : Command("Std_ViewFitAll")
1562
{
1563
    sGroup        = "Standard-View";
1564
    sMenuText     = QT_TR_NOOP("Fit all");
1565
    sToolTipText  = QT_TR_NOOP("Fits the whole content on the screen");
1566
    sWhatsThis    = "Std_ViewFitAll";
1567
    sStatusTip    = QT_TR_NOOP("Fits the whole content on the screen");
1568
    sPixmap       = "zoom-all";
1569
    sAccel        = "V, F";
1570
    eType         = Alter3DView;
1571
}
1572

1573
void StdCmdViewFitAll::activated(int iMsg)
1574
{
1575
    Q_UNUSED(iMsg);
1576
    //doCommand(Command::Gui,"Gui.activeDocument().activeView().fitAll()");
1577
    doCommand(Command::Gui,"Gui.SendMsgToActiveView(\"ViewFit\")");
1578
}
1579

1580
bool StdCmdViewFitAll::isActive()
1581
{
1582
    //return isViewOfType(Gui::View3DInventor::getClassTypeId());
1583
    return getGuiApplication()->sendHasMsgToActiveView("ViewFit");
1584
}
1585

1586
//===========================================================================
1587
// Std_ViewFitSelection
1588
//===========================================================================
1589
DEF_STD_CMD_A(StdCmdViewFitSelection)
1590

1591
StdCmdViewFitSelection::StdCmdViewFitSelection()
1592
  : Command("Std_ViewFitSelection")
1593
{
1594
    sGroup        = "Standard-View";
1595
    sMenuText     = QT_TR_NOOP("Fit selection");
1596
    sToolTipText  = QT_TR_NOOP("Fits the selected content on the screen");
1597
    sWhatsThis    = "Std_ViewFitSelection";
1598
    sStatusTip    = QT_TR_NOOP("Fits the selected content on the screen");
1599
    sAccel        = "V, S";
1600
    sPixmap       = "zoom-selection";
1601
    eType         = Alter3DView;
1602
}
1603

1604
void StdCmdViewFitSelection::activated(int iMsg)
1605
{
1606
    Q_UNUSED(iMsg);
1607
    doCommand(Command::Gui,"Gui.SendMsgToActiveView(\"ViewSelection\")");
1608
}
1609

1610
bool StdCmdViewFitSelection::isActive()
1611
{
1612
  return getGuiApplication()->sendHasMsgToActiveView("ViewSelection");
1613
}
1614

1615
//===========================================================================
1616
// Std_ViewCommandGroup
1617
//===========================================================================
1618
class StdCmdViewGroup: public Gui::GroupCommand
1619
{
1620
public:
1621
    StdCmdViewGroup()
1622
        : GroupCommand("Std_ViewGroup")
1623
    {
1624
        sGroup = "Standard-View";
1625
        sMenuText = QT_TR_NOOP("Standard views");
1626
        sToolTipText = QT_TR_NOOP("Change to a standard view");
1627
        sStatusTip = QT_TR_NOOP("Change to a standard view");
1628
        sWhatsThis = "Std_ViewGroup";
1629
        sPixmap = "view-isometric";
1630
        eType = Alter3DView;
1631

1632
        setCheckable(false);
1633
        setRememberLast(true);
1634

1635
        addCommand("Std_ViewIsometric");
1636
        addCommand("Std_ViewFront");
1637
        addCommand("Std_ViewTop");
1638
        addCommand("Std_ViewRight");
1639
        addCommand("Std_ViewRear");
1640
        addCommand("Std_ViewBottom");
1641
        addCommand("Std_ViewLeft");
1642
    }
1643

1644
    const char* className() const override
1645
    {
1646
        return "StdCmdViewGroup";
1647
    }
1648

1649
    bool isActive() override
1650
    {
1651
        return hasActiveDocument();
1652
    }
1653
};
1654

1655
//===========================================================================
1656
// Std_ViewDock
1657
//===========================================================================
1658
DEF_STD_CMD_A(StdViewDock)
1659

1660
StdViewDock::StdViewDock()
1661
  : Command("Std_ViewDock")
1662
{
1663
    sGroup       = "Standard-View";
1664
    sMenuText    = QT_TR_NOOP("Docked");
1665
    sToolTipText = QT_TR_NOOP("Display the active view either in fullscreen, in undocked or docked mode");
1666
    sWhatsThis   = "Std_ViewDock";
1667
    sStatusTip   = QT_TR_NOOP("Display the active view either in fullscreen, in undocked or docked mode");
1668
    sAccel       = "V, D";
1669
    eType        = Alter3DView;
1670
    bCanLog       = false;
1671
}
1672

1673
void StdViewDock::activated(int iMsg)
1674
{
1675
    Q_UNUSED(iMsg);
1676
}
1677

1678
bool StdViewDock::isActive()
1679
{
1680
    MDIView* view = getMainWindow()->activeWindow();
1681
    return (qobject_cast<View3DInventor*>(view) ? true : false);
1682
}
1683

1684
//===========================================================================
1685
// Std_ViewUndock
1686
//===========================================================================
1687
DEF_STD_CMD_A(StdViewUndock)
1688

1689
StdViewUndock::StdViewUndock()
1690
  : Command("Std_ViewUndock")
1691
{
1692
    sGroup       = "Standard-View";
1693
    sMenuText    = QT_TR_NOOP("Undocked");
1694
    sToolTipText = QT_TR_NOOP("Display the active view either in fullscreen, in undocked or docked mode");
1695
    sWhatsThis   = "Std_ViewUndock";
1696
    sStatusTip   = QT_TR_NOOP("Display the active view either in fullscreen, in undocked or docked mode");
1697
    sAccel       = "V, U";
1698
    eType        = Alter3DView;
1699
    bCanLog       = false;
1700
}
1701

1702
void StdViewUndock::activated(int iMsg)
1703
{
1704
    Q_UNUSED(iMsg);
1705
}
1706

1707
bool StdViewUndock::isActive()
1708
{
1709
    MDIView* view = getMainWindow()->activeWindow();
1710
    return (qobject_cast<View3DInventor*>(view) ? true : false);
1711
}
1712

1713
//===========================================================================
1714
// Std_MainFullscreen
1715
//===========================================================================
1716
DEF_STD_CMD(StdMainFullscreen)
1717

1718
StdMainFullscreen::StdMainFullscreen()
1719
  : Command("Std_MainFullscreen")
1720
{
1721
    sGroup       = "Standard-View";
1722
    sMenuText    = QT_TR_NOOP("Fullscreen");
1723
    sToolTipText = QT_TR_NOOP("Display the main window in fullscreen mode");
1724
    sWhatsThis   = "Std_MainFullscreen";
1725
    sStatusTip   = QT_TR_NOOP("Display the main window in fullscreen mode");
1726
    sPixmap      = "view-fullscreen";
1727
    sAccel       = "Alt+F11";
1728
    eType        = Alter3DView;
1729
}
1730

1731
void StdMainFullscreen::activated(int iMsg)
1732
{
1733
    Q_UNUSED(iMsg);
1734
    MDIView* view = getMainWindow()->activeWindow();
1735

1736
    if (view)
1737
        view->setCurrentViewMode(MDIView::Child);
1738

1739
    if (getMainWindow()->isFullScreen())
1740
        getMainWindow()->showNormal();
1741
    else
1742
        getMainWindow()->showFullScreen();
1743
}
1744

1745
//===========================================================================
1746
// Std_ViewFullscreen
1747
//===========================================================================
1748
DEF_STD_CMD_A(StdViewFullscreen)
1749

1750
StdViewFullscreen::StdViewFullscreen()
1751
  : Command("Std_ViewFullscreen")
1752
{
1753
    sGroup       = "Standard-View";
1754
    sMenuText    = QT_TR_NOOP("Fullscreen");
1755
    sToolTipText = QT_TR_NOOP("Display the active view either in fullscreen, in undocked or docked mode");
1756
    sWhatsThis   = "Std_ViewFullscreen";
1757
    sStatusTip   = QT_TR_NOOP("Display the active view either in fullscreen, in undocked or docked mode");
1758
    sPixmap      = "view-fullscreen";
1759
    sAccel       = "F11";
1760
    eType        = Alter3DView;
1761
    bCanLog       = false;
1762
}
1763

1764
void StdViewFullscreen::activated(int iMsg)
1765
{
1766
    Q_UNUSED(iMsg);
1767
}
1768

1769
bool StdViewFullscreen::isActive()
1770
{
1771
    MDIView* view = getMainWindow()->activeWindow();
1772
    return (qobject_cast<View3DInventor*>(view) ? true : false);
1773
}
1774

1775
//===========================================================================
1776
// Std_ViewDockUndockFullscreen
1777
//===========================================================================
1778
DEF_STD_CMD_AC(StdViewDockUndockFullscreen)
1779

1780
StdViewDockUndockFullscreen::StdViewDockUndockFullscreen()
1781
  : Command("Std_ViewDockUndockFullscreen")
1782
{
1783
    sGroup       = "Standard-View";
1784
    sMenuText    = QT_TR_NOOP("Document window");
1785
    sToolTipText = QT_TR_NOOP("Display the active view either in fullscreen, in undocked or docked mode");
1786
    sWhatsThis   = "Std_ViewDockUndockFullscreen";
1787
    sStatusTip   = QT_TR_NOOP("Display the active view either in fullscreen, in undocked or docked mode");
1788
    eType        = Alter3DView;
1789

1790
    CommandManager &rcCmdMgr = Application::Instance->commandManager();
1791
    rcCmdMgr.addCommand(new StdViewDock());
1792
    rcCmdMgr.addCommand(new StdViewUndock());
1793
    rcCmdMgr.addCommand(new StdViewFullscreen());
1794
}
1795

1796
Action * StdViewDockUndockFullscreen::createAction()
1797
{
1798
    auto pcAction = new ActionGroup(this, getMainWindow());
1799
    pcAction->setDropDownMenu(true);
1800
    pcAction->setText(QCoreApplication::translate(
1801
        this->className(), getMenuText()));
1802

1803
    CommandManager &rcCmdMgr = Application::Instance->commandManager();
1804
    Command* cmdD = rcCmdMgr.getCommandByName("Std_ViewDock");
1805
    Command* cmdU = rcCmdMgr.getCommandByName("Std_ViewUndock");
1806
    Command* cmdF = rcCmdMgr.getCommandByName("Std_ViewFullscreen");
1807
    cmdD->addToGroup(pcAction, true);
1808
    cmdU->addToGroup(pcAction, true);
1809
    cmdF->addToGroup(pcAction, true);
1810

1811
    return pcAction;
1812
}
1813

1814
void StdViewDockUndockFullscreen::activated(int iMsg)
1815
{
1816
    // Check if main window is in fullscreen mode.
1817
    if (getMainWindow()->isFullScreen())
1818
        getMainWindow()->showNormal();
1819

1820
    MDIView* view = getMainWindow()->activeWindow();
1821
    if (!view) // no active view
1822
        return;
1823

1824
    // nothing to do when the view is docked and 'Docked' is pressed
1825
    if (iMsg == 0 && view->currentViewMode() == MDIView::Child)
1826
        return;
1827
    // Change the view mode after an mdi view was already visible doesn't
1828
    // work well with Qt5 any more because of some strange OpenGL behaviour.
1829
    // A workaround is to clone the mdi view, set its view mode and delete
1830
    // the original view.
1831
    Gui::Document* doc = Gui::Application::Instance->activeDocument();
1832
    if (doc) {
1833
        Gui::MDIView* clone = doc->cloneView(view);
1834
        if (!clone)
1835
            return;
1836

1837
        const char* ppReturn = nullptr;
1838
        if (view->onMsg("GetCamera", &ppReturn)) {
1839
            std::string sMsg = "SetCamera ";
1840
            sMsg += ppReturn;
1841

1842
            const char** pReturnIgnore=nullptr;
1843
            clone->onMsg(sMsg.c_str(), pReturnIgnore);
1844
        }
1845

1846
        if (iMsg==0) {
1847
            getMainWindow()->addWindow(clone);
1848
        }
1849
        else if (iMsg==1) {
1850
            if (view->currentViewMode() == MDIView::TopLevel)
1851
                getMainWindow()->addWindow(clone);
1852
            else
1853
                clone->setCurrentViewMode(MDIView::TopLevel);
1854
        }
1855
        else if (iMsg==2) {
1856
            if (view->currentViewMode() == MDIView::FullScreen)
1857
                getMainWindow()->addWindow(clone);
1858
            else
1859
                clone->setCurrentViewMode(MDIView::FullScreen);
1860
        }
1861
        // destroy the old view
1862
        view->deleteSelf();
1863
    }
1864
}
1865

1866
bool StdViewDockUndockFullscreen::isActive()
1867
{
1868
    MDIView* view = getMainWindow()->activeWindow();
1869
    if (qobject_cast<View3DInventor*>(view)) {
1870
        // update the action group if needed
1871
        auto pActGrp = qobject_cast<ActionGroup*>(_pcAction);
1872
        if (pActGrp) {
1873
            int index = pActGrp->checkedAction();
1874
            int mode = (int)(view->currentViewMode());
1875
            if (index != mode) {
1876
                // active window has changed with another view mode
1877
                pActGrp->setCheckedAction(mode);
1878
            }
1879
        }
1880

1881
        return true;
1882
    }
1883

1884
    return false;
1885
}
1886

1887

1888
//===========================================================================
1889
// Std_ViewVR
1890
//===========================================================================
1891
DEF_STD_CMD_A(StdCmdViewVR)
1892

1893
StdCmdViewVR::StdCmdViewVR()
1894
  : Command("Std_ViewVR")
1895
{
1896
    sGroup        = "Standard-View";
1897
    sMenuText     = QT_TR_NOOP("FreeCAD-VR");
1898
    sToolTipText  = QT_TR_NOOP("Extend the FreeCAD 3D Window to a Oculus Rift");
1899
    sWhatsThis    = "Std_ViewVR";
1900
    sStatusTip    = QT_TR_NOOP("Extend the FreeCAD 3D Window to a Oculus Rift");
1901
    eType         = Alter3DView;
1902
}
1903

1904
void StdCmdViewVR::activated(int iMsg)
1905
{
1906
   Q_UNUSED(iMsg);
1907
   doCommand(Command::Gui,"Gui.SendMsgToActiveView(\"ViewVR\")");
1908
}
1909

1910
bool StdCmdViewVR::isActive()
1911
{
1912
   return getGuiApplication()->sendHasMsgToActiveView("ViewVR");
1913
}
1914

1915

1916

1917
//===========================================================================
1918
// Std_ViewScreenShot
1919
//===========================================================================
1920
DEF_STD_CMD_A(StdViewScreenShot)
1921

1922
StdViewScreenShot::StdViewScreenShot()
1923
  : Command("Std_ViewScreenShot")
1924
{
1925
    sGroup      = "Standard-View";
1926
    sMenuText   = QT_TR_NOOP("Save image...");
1927
    sToolTipText= QT_TR_NOOP("Creates a screenshot of the active view");
1928
    sWhatsThis  = "Std_ViewScreenShot";
1929
    sStatusTip  = QT_TR_NOOP("Creates a screenshot of the active view");
1930
    sPixmap     = "Std_ViewScreenShot";
1931
    eType       = Alter3DView;
1932
}
1933

1934
void StdViewScreenShot::activated(int iMsg)
1935
{
1936
    Q_UNUSED(iMsg);
1937
    auto view = qobject_cast<View3DInventor*>(getMainWindow()->activeWindow());
1938
    if (view) {
1939
        QStringList formats;
1940
        SbViewportRegion vp(view->getViewer()->getSoRenderManager()->getViewportRegion());
1941
        {
1942
            SoQtOffscreenRenderer rd(vp);
1943
            formats = rd.getWriteImageFiletypeInfo();
1944
        }
1945

1946
        Base::Reference<ParameterGrp> hExt = App::GetApplication().GetUserParameter().GetGroup("BaseApp")
1947
                                   ->GetGroup("Preferences")->GetGroup("General");
1948
        QString ext = QString::fromLatin1(hExt->GetASCII("OffscreenImageFormat").c_str());
1949
        int backtype = hExt->GetInt("OffscreenImageBackground", 0);
1950

1951
        Base::Reference<ParameterGrp> methodGrp = App::GetApplication().GetParameterGroupByPath
1952
            ("User parameter:BaseApp/Preferences/View");
1953
        QByteArray method = methodGrp->GetASCII("SavePicture").c_str();
1954

1955
        QStringList filter;
1956
        QString selFilter;
1957
        for (QStringList::Iterator it = formats.begin(); it != formats.end(); ++it) {
1958
            filter << QString::fromLatin1("%1 %2 (*.%3)").arg((*it).toUpper(),
1959
                QObject::tr("files"), (*it).toLower());
1960
            if (ext == *it)
1961
                selFilter = filter.last();
1962
        }
1963

1964
        FileOptionsDialog fd(getMainWindow(), Qt::WindowFlags());
1965
        fd.setFileMode(QFileDialog::AnyFile);
1966
        fd.setAcceptMode(QFileDialog::AcceptSave);
1967
        fd.setWindowTitle(QObject::tr("Save image"));
1968
        fd.setNameFilters(filter);
1969
        if (!selFilter.isEmpty())
1970
            fd.selectNameFilter(selFilter);
1971

1972
        // create the image options widget
1973
        auto opt = new DlgSettingsImageImp(&fd);
1974
        SbVec2s sz = vp.getWindowSize();
1975
        opt->setImageSize((int)sz[0], (int)sz[1]);
1976
        opt->setBackgroundType(backtype);
1977
        opt->setMethod(method);
1978

1979
        fd.setOptionsWidget(FileOptionsDialog::ExtensionRight, opt);
1980
        fd.setOption(QFileDialog::DontConfirmOverwrite, false);
1981
        opt->onSelectedFilter(fd.selectedNameFilter());
1982
        QObject::connect(&fd, &FileOptionsDialog::filterSelected,
1983
                         opt, &DlgSettingsImageImp::onSelectedFilter);
1984

1985
        if (fd.exec() == QDialog::Accepted) {
1986
            selFilter = fd.selectedNameFilter();
1987
            QString fn = fd.selectedFiles().constFirst();
1988
            // We must convert '\' path separators to '/' before otherwise
1989
            // Python would interpret them as escape sequences.
1990
            fn.replace(QLatin1Char('\\'), QLatin1Char('/'));
1991

1992
            Gui::WaitCursor wc;
1993

1994
            // get the defined values
1995
            int w = opt->imageWidth();
1996
            int h = opt->imageHeight();
1997

1998
            // search for the matching format
1999
            QString format = formats.front(); // take the first as default
2000
            for (QStringList::Iterator it = formats.begin(); it != formats.end(); ++it) {
2001
                if (selFilter.startsWith((*it).toUpper())) {
2002
                    format = *it;
2003
                    break;
2004
                }
2005
            }
2006

2007
            hExt->SetASCII("OffscreenImageFormat", (const char*)format.toLatin1());
2008

2009
            method = opt->method();
2010
            methodGrp->SetASCII("SavePicture", method.constData());
2011

2012
            // which background chosen
2013
            const char* background;
2014
            switch (opt->backgroundType()) {
2015
            case 0:  background = "Current"; break;
2016
            case 1:  background = "White"; break;
2017
            case 2:  background = "Black"; break;
2018
            case 3:  background = "Transparent"; break;
2019
            default: background = "Current"; break;
2020
            }
2021
            hExt->SetInt("OffscreenImageBackground", opt->backgroundType());
2022

2023
            QString comment = opt->comment();
2024
            if (!comment.isEmpty()) {
2025
                // Replace newline escape sequence through '\\n' string to build one big string,
2026
                // otherwise Python would interpret it as an invalid command.
2027
                // Python does the decoding for us.
2028
#if QT_VERSION >= QT_VERSION_CHECK(5,15,0)
2029
                QStringList lines = comment.split(QLatin1String("\n"), Qt::KeepEmptyParts);
2030
#else
2031
                QStringList lines = comment.split(QLatin1String("\n"), QString::KeepEmptyParts);
2032
#endif
2033
                comment = lines.join(QLatin1String("\\n"));
2034
                doCommand(Gui, "Gui.activeDocument().activeView().saveImage('%s',%d,%d,'%s','%s')",
2035
                          fn.toUtf8().constData(), w, h, background, comment.toUtf8().constData());
2036
            }
2037
            else {
2038
                doCommand(Gui, "Gui.activeDocument().activeView().saveImage('%s',%d,%d,'%s')",
2039
                          fn.toUtf8().constData(), w, h, background);
2040
            }
2041

2042
            // When adding a watermark check if the image could be created
2043
            if (opt->addWatermark()) {
2044
                QFileInfo fi(fn);
2045
                QPixmap pixmap;
2046
                if (fi.exists() && pixmap.load(fn)) {
2047
                    QString name = qApp->applicationName();
2048
                    std::map<std::string, std::string>& config = App::Application::Config();
2049
                    QString url = QString::fromLatin1(config["MaintainerUrl"].c_str());
2050
                    url = QUrl(url).host();
2051

2052
                    QPixmap appicon = Gui::BitmapFactory().pixmap(config["AppIcon"].c_str());
2053

2054
                    QPainter painter;
2055
                    painter.begin(&pixmap);
2056

2057
                    painter.drawPixmap(8, h - 15 - appicon.height(), appicon);
2058

2059
                    QFont font = painter.font();
2060
                    font.setPointSize(20);
2061

2062
                    QFontMetrics fm(font);
2063
                    int n = QtTools::horizontalAdvance(fm, name);
2064
                    int h = pixmap.height();
2065

2066
                    painter.setFont(font);
2067
                    painter.drawText(8 + appicon.width(), h - 24, name);
2068

2069
                    font.setPointSize(12);
2070
                    QFontMetrics fm2(font);
2071
                    int u = QtTools::horizontalAdvance(fm2, url);
2072
                    painter.setFont(font);
2073
                    painter.drawText(8 + appicon.width() + n - u, h - 6, url);
2074

2075
                    painter.end();
2076
                    pixmap.save(fn);
2077
                }
2078
            }
2079
        }
2080
    }
2081
}
2082

2083
bool StdViewScreenShot::isActive()
2084
{
2085
    return isViewOfType(Gui::View3DInventor::getClassTypeId());
2086
}
2087

2088
//===========================================================================
2089
// Std_ViewLoadImage
2090
//===========================================================================
2091
DEF_STD_CMD(StdViewLoadImage)
2092

2093
StdViewLoadImage::StdViewLoadImage()
2094
  : Command("Std_ViewLoadImage")
2095
{
2096
    sGroup      = "Standard-View";
2097
    sMenuText   = QT_TR_NOOP("Load image...");
2098
    sToolTipText= QT_TR_NOOP("Loads an image");
2099
    sWhatsThis  = "Std_ViewLoadImage";
2100
    sStatusTip  = QT_TR_NOOP("Loads an image");
2101
    sPixmap     = "image-open";
2102
    eType       = 0;
2103
}
2104

2105
void StdViewLoadImage::activated(int iMsg)
2106
{
2107
    Q_UNUSED(iMsg);
2108

2109
    // add all supported QImage formats
2110
    QStringList mimeTypeFilters;
2111
    QList<QByteArray> supportedMimeTypes = QImageReader::supportedMimeTypes();
2112
    for (const auto& mimeTypeName : supportedMimeTypes) {
2113
        mimeTypeFilters.append(QString::fromLatin1(mimeTypeName));
2114
    }
2115

2116
    // Reading an image
2117
    QFileDialog dialog(Gui::getMainWindow());
2118
    dialog.setWindowTitle(QObject::tr("Choose an image file to open"));
2119
    dialog.setMimeTypeFilters(mimeTypeFilters);
2120
    dialog.selectMimeTypeFilter(QString::fromLatin1("image/png"));
2121
    dialog.setDefaultSuffix(QString::fromLatin1("png"));
2122
    dialog.setAcceptMode(QFileDialog::AcceptOpen);
2123
    dialog.setOption(QFileDialog::DontUseNativeDialog);
2124

2125
    if (dialog.exec()) {
2126
        QString fileName = dialog.selectedFiles().constFirst();
2127
        ImageView* view = new ImageView(Gui::getMainWindow());
2128
        view->loadFile(fileName);
2129
        view->resize(400, 300);
2130
        Gui::getMainWindow()->addWindow(view);
2131
    }
2132
}
2133

2134
//===========================================================================
2135
// Std_ViewCreate
2136
//===========================================================================
2137
DEF_STD_CMD_A(StdCmdViewCreate)
2138

2139
StdCmdViewCreate::StdCmdViewCreate()
2140
  : Command("Std_ViewCreate")
2141
{
2142
    sGroup      = "Standard-View";
2143
    sMenuText   = QT_TR_NOOP("Create new view");
2144
    sToolTipText= QT_TR_NOOP("Creates a new view window for the active document");
2145
    sWhatsThis  = "Std_ViewCreate";
2146
    sStatusTip  = QT_TR_NOOP("Creates a new view window for the active document");
2147
    sPixmap     = "window-new";
2148
    eType         = Alter3DView;
2149
}
2150

2151
void StdCmdViewCreate::activated(int iMsg)
2152
{
2153
    Q_UNUSED(iMsg);
2154
    getActiveGuiDocument()->createView(View3DInventor::getClassTypeId());
2155
    getActiveGuiDocument()->getActiveView()->viewAll();
2156
}
2157

2158
bool StdCmdViewCreate::isActive()
2159
{
2160
    return (getActiveGuiDocument() != nullptr);
2161
}
2162

2163
//===========================================================================
2164
// Std_ToggleNavigation
2165
//===========================================================================
2166
DEF_STD_CMD_A(StdCmdToggleNavigation)
2167

2168
StdCmdToggleNavigation::StdCmdToggleNavigation()
2169
  : Command("Std_ToggleNavigation")
2170
{
2171
    sGroup        = "Standard-View";
2172
    sMenuText     = QT_TR_NOOP("Toggle navigation/Edit mode");
2173
    sToolTipText  = QT_TR_NOOP("Toggle between navigation and edit mode");
2174
    sStatusTip    = QT_TR_NOOP("Toggle between navigation and edit mode");
2175
    sWhatsThis    = "Std_ToggleNavigation";
2176
  //iAccel        = Qt::SHIFT+Qt::Key_Space;
2177
    sAccel        = "Esc";
2178
    sPixmap       = "Std_ToggleNavigation";
2179
    eType         = Alter3DView;
2180
}
2181

2182
void StdCmdToggleNavigation::activated(int iMsg)
2183
{
2184
    Q_UNUSED(iMsg);
2185
    Gui::MDIView* view = Gui::getMainWindow()->activeWindow();
2186
    if (view && view->isDerivedFrom(Gui::View3DInventor::getClassTypeId())) {
2187
        Gui::View3DInventorViewer* viewer = static_cast<Gui::View3DInventor*>(view)->getViewer();
2188
        SbBool toggle = viewer->isRedirectedToSceneGraph();
2189
        viewer->setRedirectToSceneGraph(!toggle);
2190
    }
2191
}
2192

2193
bool StdCmdToggleNavigation::isActive()
2194
{
2195
    //#0001087: Inventor Navigation continues with released Mouse Button
2196
    //This happens because 'Esc' is also used to close the task dialog.
2197
    //Add also new method 'isRedirectToSceneGraphEnabled' to explicitly
2198
    //check if this is allowed.
2199
    if (Gui::Control().activeDialog())
2200
        return false;
2201
    Gui::MDIView* view = Gui::getMainWindow()->activeWindow();
2202
    if (view && view->isDerivedFrom(Gui::View3DInventor::getClassTypeId())) {
2203
        Gui::View3DInventorViewer* viewer = static_cast<Gui::View3DInventor*>(view)->getViewer();
2204
        return viewer->isEditing() && viewer->isRedirectToSceneGraphEnabled();
2205
    }
2206
    return false;
2207
}
2208

2209

2210

2211

2212
//===========================================================================
2213
// Std_ViewExample1
2214
//===========================================================================
2215
DEF_STD_CMD_A(StdCmdAxisCross)
2216

2217
StdCmdAxisCross::StdCmdAxisCross()
2218
  : Command("Std_AxisCross")
2219
{
2220
        sGroup        = "Standard-View";
2221
        sMenuText     = QT_TR_NOOP("Toggle axis cross");
2222
        sToolTipText  = QT_TR_NOOP("Turns on or off the axis cross at the origin");
2223
        sStatusTip    = QT_TR_NOOP("Turns on or off the axis cross at the origin");
2224
        sWhatsThis    = "Std_AxisCross";
2225
        sPixmap       = "Std_AxisCross";
2226
        sAccel        = "A,C";
2227
}
2228

2229
void StdCmdAxisCross::activated(int iMsg)
2230
{
2231
    Q_UNUSED(iMsg);
2232
    auto view = qobject_cast<View3DInventor*>(Gui::getMainWindow()->activeWindow());
2233
    if (view) {
2234
        if (!view->getViewer()->hasAxisCross())
2235
            doCommand(Command::Gui,"Gui.ActiveDocument.ActiveView.setAxisCross(True)");
2236
        else
2237
            doCommand(Command::Gui,"Gui.ActiveDocument.ActiveView.setAxisCross(False)");
2238
    }
2239
}
2240

2241
bool StdCmdAxisCross::isActive()
2242
{
2243
    auto view = qobject_cast<View3DInventor*>(Gui::getMainWindow()->activeWindow());
2244
    if (view && view->getViewer()->hasAxisCross()) {
2245
        if (!_pcAction->isChecked())
2246
            _pcAction->setChecked(true);
2247
    }
2248
    else {
2249
        if (_pcAction->isChecked())
2250
            _pcAction->setChecked(false);
2251
    }
2252
    if (view)
2253
        return true;
2254
    return false;
2255

2256
}
2257

2258
//===========================================================================
2259
// Std_ViewExample1
2260
//===========================================================================
2261
DEF_STD_CMD_A(StdCmdViewExample1)
2262

2263
StdCmdViewExample1::StdCmdViewExample1()
2264
  : Command("Std_ViewExample1")
2265
{
2266
    sGroup        = "Standard-View";
2267
    sMenuText     = QT_TR_NOOP("Inventor example #1");
2268
    sToolTipText  = QT_TR_NOOP("Shows a 3D texture with manipulator");
2269
    sWhatsThis    = "Std_ViewExample1";
2270
    sStatusTip    = QT_TR_NOOP("Shows a 3D texture with manipulator");
2271
    sPixmap       = "Std_Tool1";
2272
    eType         = Alter3DView;
2273
}
2274

2275
void StdCmdViewExample1::activated(int iMsg)
2276
{
2277
    Q_UNUSED(iMsg);
2278
    doCommand(Command::Gui,"Gui.SendMsgToActiveView(\"Example1\")");
2279
}
2280

2281
bool StdCmdViewExample1::isActive()
2282
{
2283
    return getGuiApplication()->sendHasMsgToActiveView("Example1");
2284
}
2285

2286
//===========================================================================
2287
// Std_ViewExample2
2288
//===========================================================================
2289
DEF_STD_CMD_A(StdCmdViewExample2)
2290

2291
StdCmdViewExample2::StdCmdViewExample2()
2292
  : Command("Std_ViewExample2")
2293
{
2294
    sGroup        = "Standard-View";
2295
    sMenuText     = QT_TR_NOOP("Inventor example #2");
2296
    sToolTipText  = QT_TR_NOOP("Shows spheres and drag-lights");
2297
    sWhatsThis    = "Std_ViewExample2";
2298
    sStatusTip    = QT_TR_NOOP("Shows spheres and drag-lights");
2299
    sPixmap       = "Std_Tool2";
2300
    eType         = Alter3DView;
2301
}
2302

2303
void StdCmdViewExample2::activated(int iMsg)
2304
{
2305
    Q_UNUSED(iMsg);
2306
    doCommand(Command::Gui,"Gui.SendMsgToActiveView(\"Example2\")");
2307
}
2308

2309
bool StdCmdViewExample2::isActive()
2310
{
2311
    return getGuiApplication()->sendHasMsgToActiveView("Example2");
2312
}
2313

2314
//===========================================================================
2315
// Std_ViewExample3
2316
//===========================================================================
2317
DEF_STD_CMD_A(StdCmdViewExample3)
2318

2319
StdCmdViewExample3::StdCmdViewExample3()
2320
  : Command("Std_ViewExample3")
2321
{
2322
    sGroup        = "Standard-View";
2323
    sMenuText     = QT_TR_NOOP("Inventor example #3");
2324
    sToolTipText  = QT_TR_NOOP("Shows a animated texture");
2325
    sWhatsThis    = "Std_ViewExample3";
2326
    sStatusTip    = QT_TR_NOOP("Shows a animated texture");
2327
    sPixmap       = "Std_Tool3";
2328
    eType         = Alter3DView;
2329
}
2330

2331
void StdCmdViewExample3::activated(int iMsg)
2332
{
2333
    Q_UNUSED(iMsg);
2334
    doCommand(Command::Gui,"Gui.SendMsgToActiveView(\"Example3\")");
2335
}
2336

2337
bool StdCmdViewExample3::isActive()
2338
{
2339
    return getGuiApplication()->sendHasMsgToActiveView("Example3");
2340
}
2341

2342

2343
//===========================================================================
2344
// Std_ViewIvStereoOff
2345
//===========================================================================
2346
DEF_STD_CMD_A(StdCmdViewIvStereoOff)
2347

2348
StdCmdViewIvStereoOff::StdCmdViewIvStereoOff()
2349
  : Command("Std_ViewIvStereoOff")
2350
{
2351
    sGroup        = "Standard-View";
2352
    sMenuText     = QT_TR_NOOP("Stereo Off");
2353
    sToolTipText  = QT_TR_NOOP("Switch stereo viewing off");
2354
    sWhatsThis    = "Std_ViewIvStereoOff";
2355
    sStatusTip    = QT_TR_NOOP("Switch stereo viewing off");
2356
    sPixmap       = "Std_ViewIvStereoOff";
2357
    eType         = Alter3DView;
2358
}
2359

2360
void StdCmdViewIvStereoOff::activated(int iMsg)
2361
{
2362
    Q_UNUSED(iMsg);
2363
    doCommand(Command::Gui,"Gui.activeDocument().activeView().setStereoType(\"Mono\")");
2364
}
2365

2366
bool StdCmdViewIvStereoOff::isActive()
2367
{
2368
    return getGuiApplication()->sendHasMsgToActiveView("SetStereoOff");
2369
}
2370

2371

2372
//===========================================================================
2373
// Std_ViewIvStereoRedGreen
2374
//===========================================================================
2375
DEF_STD_CMD_A(StdCmdViewIvStereoRedGreen)
2376

2377
StdCmdViewIvStereoRedGreen::StdCmdViewIvStereoRedGreen()
2378
  : Command("Std_ViewIvStereoRedGreen")
2379
{
2380
    sGroup        = "Standard-View";
2381
    sMenuText     = QT_TR_NOOP("Stereo red/cyan");
2382
    sToolTipText  = QT_TR_NOOP("Switch stereo viewing to red/cyan");
2383
    sWhatsThis    = "Std_ViewIvStereoRedGreen";
2384
    sStatusTip    = QT_TR_NOOP("Switch stereo viewing to red/cyan");
2385
    sPixmap       = "Std_ViewIvStereoRedGreen";
2386
    eType         = Alter3DView;
2387
}
2388

2389
void StdCmdViewIvStereoRedGreen::activated(int iMsg)
2390
{
2391
    Q_UNUSED(iMsg);
2392
    doCommand(Command::Gui,"Gui.activeDocument().activeView().setStereoType(\"Anaglyph\")");
2393
}
2394

2395
bool StdCmdViewIvStereoRedGreen::isActive()
2396
{
2397
    return getGuiApplication()->sendHasMsgToActiveView("SetStereoRedGreen");
2398
}
2399

2400
//===========================================================================
2401
// Std_ViewIvStereoQuadBuff
2402
//===========================================================================
2403
DEF_STD_CMD_A(StdCmdViewIvStereoQuadBuff)
2404

2405
StdCmdViewIvStereoQuadBuff::StdCmdViewIvStereoQuadBuff()
2406
  : Command("Std_ViewIvStereoQuadBuff")
2407
{
2408
    sGroup        = "Standard-View";
2409
    sMenuText     = QT_TR_NOOP("Stereo quad buffer");
2410
    sToolTipText  = QT_TR_NOOP("Switch stereo viewing to quad buffer");
2411
    sWhatsThis    = "Std_ViewIvStereoQuadBuff";
2412
    sStatusTip    = QT_TR_NOOP("Switch stereo viewing to quad buffer");
2413
    sPixmap       = "Std_ViewIvStereoQuadBuff";
2414
    eType         = Alter3DView;
2415
}
2416

2417
void StdCmdViewIvStereoQuadBuff::activated(int iMsg)
2418
{
2419
    Q_UNUSED(iMsg);
2420
    doCommand(Command::Gui,"Gui.activeDocument().activeView().setStereoType(\"QuadBuffer\")");
2421
}
2422

2423
bool StdCmdViewIvStereoQuadBuff::isActive()
2424
{
2425
    return getGuiApplication()->sendHasMsgToActiveView("SetStereoQuadBuff");
2426
}
2427

2428
//===========================================================================
2429
// Std_ViewIvStereoInterleavedRows
2430
//===========================================================================
2431
DEF_STD_CMD_A(StdCmdViewIvStereoInterleavedRows)
2432

2433
StdCmdViewIvStereoInterleavedRows::StdCmdViewIvStereoInterleavedRows()
2434
  : Command("Std_ViewIvStereoInterleavedRows")
2435
{
2436
    sGroup        = "Standard-View";
2437
    sMenuText     = QT_TR_NOOP("Stereo Interleaved Rows");
2438
    sToolTipText  = QT_TR_NOOP("Switch stereo viewing to Interleaved Rows");
2439
    sWhatsThis    = "Std_ViewIvStereoInterleavedRows";
2440
    sStatusTip    = QT_TR_NOOP("Switch stereo viewing to Interleaved Rows");
2441
    sPixmap       = "Std_ViewIvStereoInterleavedRows";
2442
    eType         = Alter3DView;
2443
}
2444

2445
void StdCmdViewIvStereoInterleavedRows::activated(int iMsg)
2446
{
2447
    Q_UNUSED(iMsg);
2448
    doCommand(Command::Gui,"Gui.activeDocument().activeView().setStereoType(\"InterleavedRows\")");
2449
}
2450

2451
bool StdCmdViewIvStereoInterleavedRows::isActive()
2452
{
2453
    return getGuiApplication()->sendHasMsgToActiveView("SetStereoInterleavedRows");
2454
}
2455

2456
//===========================================================================
2457
// Std_ViewIvStereoInterleavedColumns
2458
//===========================================================================
2459
DEF_STD_CMD_A(StdCmdViewIvStereoInterleavedColumns)
2460

2461
StdCmdViewIvStereoInterleavedColumns::StdCmdViewIvStereoInterleavedColumns()
2462
  : Command("Std_ViewIvStereoInterleavedColumns")
2463
{
2464
    sGroup        = "Standard-View";
2465
    sMenuText     = QT_TR_NOOP("Stereo Interleaved Columns");
2466
    sToolTipText  = QT_TR_NOOP("Switch stereo viewing to Interleaved Columns");
2467
    sWhatsThis    = "Std_ViewIvStereoInterleavedColumns";
2468
    sStatusTip    = QT_TR_NOOP("Switch stereo viewing to Interleaved Columns");
2469
    sPixmap       = "Std_ViewIvStereoInterleavedColumns";
2470
    eType         = Alter3DView;
2471
}
2472

2473
void StdCmdViewIvStereoInterleavedColumns::activated(int iMsg)
2474
{
2475
    Q_UNUSED(iMsg);
2476
    doCommand(Command::Gui,"Gui.activeDocument().activeView().setStereoType(\"InterleavedColumns\")");
2477
}
2478

2479
bool StdCmdViewIvStereoInterleavedColumns::isActive()
2480
{
2481
    return getGuiApplication()->sendHasMsgToActiveView("SetStereoInterleavedColumns");
2482
}
2483

2484

2485
//===========================================================================
2486
// Std_ViewIvIssueCamPos
2487
//===========================================================================
2488
DEF_STD_CMD_A(StdCmdViewIvIssueCamPos)
2489

2490
StdCmdViewIvIssueCamPos::StdCmdViewIvIssueCamPos()
2491
  : Command("Std_ViewIvIssueCamPos")
2492
{
2493
    sGroup        = "Standard-View";
2494
    sMenuText     = QT_TR_NOOP("Issue camera position");
2495
    sToolTipText  = QT_TR_NOOP("Issue the camera position to the console and to a macro, to easily recall this position");
2496
    sWhatsThis    = "Std_ViewIvIssueCamPos";
2497
    sStatusTip    = QT_TR_NOOP("Issue the camera position to the console and to a macro, to easily recall this position");
2498
    sPixmap       = "Std_ViewIvIssueCamPos";
2499
    eType         = Alter3DView;
2500
}
2501

2502
void StdCmdViewIvIssueCamPos::activated(int iMsg)
2503
{
2504
    Q_UNUSED(iMsg);
2505
    std::string Temp,Temp2;
2506
    std::string::size_type pos;
2507

2508
    const char* ppReturn=nullptr;
2509
    getGuiApplication()->sendMsgToActiveView("GetCamera",&ppReturn);
2510

2511
    // remove the #inventor line...
2512
    Temp2 = ppReturn;
2513
    pos = Temp2.find_first_of("\n");
2514
    Temp2.erase(0,pos);
2515

2516
    // remove all returns
2517
    while((pos=Temp2.find('\n')) != std::string::npos)
2518
        Temp2.replace(pos,1," ");
2519

2520
    // build up the command string
2521
    Temp += "Gui.SendMsgToActiveView(\"SetCamera ";
2522
    Temp += Temp2;
2523
    Temp += "\")";
2524

2525
    Base::Console().Message("%s\n",Temp2.c_str());
2526
    getGuiApplication()->macroManager()->addLine(MacroManager::Gui,Temp.c_str());
2527
}
2528

2529
bool StdCmdViewIvIssueCamPos::isActive()
2530
{
2531
    return getGuiApplication()->sendHasMsgToActiveView("GetCamera");
2532
}
2533

2534

2535
//===========================================================================
2536
// Std_ViewZoomIn
2537
//===========================================================================
2538
DEF_STD_CMD_A(StdViewZoomIn)
2539

2540
StdViewZoomIn::StdViewZoomIn()
2541
  : Command("Std_ViewZoomIn")
2542
{
2543
    sGroup        = "Standard-View";
2544
    sMenuText     = QT_TR_NOOP("Zoom In");
2545
    sToolTipText  = QT_TR_NOOP("Increase the zoom factor by a fixed amount");
2546
    sWhatsThis    = "Std_ViewZoomIn";
2547
    sStatusTip    = QT_TR_NOOP("Increase the zoom factor by a fixed amount");
2548
    sPixmap       = "zoom-in";
2549
    sAccel        = keySequenceToAccel(QKeySequence::ZoomIn);
2550
    eType         = Alter3DView;
2551
}
2552

2553
void StdViewZoomIn::activated(int iMsg)
2554
{
2555
    Q_UNUSED(iMsg);
2556
    getGuiApplication()->sendMsgToFocusView("ZoomIn");
2557
}
2558

2559
bool StdViewZoomIn::isActive()
2560
{
2561
    return getGuiApplication()->sendHasMsgToActiveView("ZoomIn");
2562
}
2563

2564
//===========================================================================
2565
// Std_ViewZoomOut
2566
//===========================================================================
2567
DEF_STD_CMD_A(StdViewZoomOut)
2568

2569
StdViewZoomOut::StdViewZoomOut()
2570
  : Command("Std_ViewZoomOut")
2571
{
2572
    sGroup        = "Standard-View";
2573
    sMenuText     = QT_TR_NOOP("Zoom Out");
2574
    sToolTipText  = QT_TR_NOOP("Decrease the zoom factor by a fixed amount");
2575
    sWhatsThis    = "Std_ViewZoomOut";
2576
    sStatusTip    = QT_TR_NOOP("Decrease the zoom factor by a fixed amount");
2577
    sPixmap       = "zoom-out";
2578
    sAccel        = keySequenceToAccel(QKeySequence::ZoomOut);
2579
    eType         = Alter3DView;
2580
}
2581

2582
void StdViewZoomOut::activated(int iMsg)
2583
{
2584
    Q_UNUSED(iMsg);
2585
    getGuiApplication()->sendMsgToFocusView("ZoomOut");
2586
}
2587

2588
bool StdViewZoomOut::isActive()
2589
{
2590
    return getGuiApplication()->sendHasMsgToActiveView("ZoomOut");
2591
}
2592

2593
namespace {
2594
class SelectionCallbackHandler {
2595

2596
private:
2597
    static std::unique_ptr<SelectionCallbackHandler> currentSelectionHandler;
2598
    QCursor prevSelectionCursor;
2599
    using FnCb = void (*)(void * userdata, SoEventCallback * node);
2600
    FnCb fnCb;
2601
    void* userData;
2602
    bool prevSelectionEn;
2603

2604
public:
2605
    // Creates a selection handler used to implement the common behaviour of BoxZoom, BoxSelection and BoxElementSelection.
2606
    // Takes the viewer, a selection mode, a cursor, a function pointer to be called on success and a void pointer for user data to be passed to the given function.
2607
    // The selection handler class stores all necessary previous states, registers a event callback and starts the selection in the given mode.
2608
    // If there is still a selection handler active, this call will generate a message and returns.
2609
    static void Create(View3DInventorViewer* viewer, View3DInventorViewer::SelectionMode selectionMode,
2610
                       const QCursor& cursor, FnCb doFunction= nullptr, void* ud=nullptr)
2611
    {
2612
        if (currentSelectionHandler)
2613
        {
2614
            Base::Console().Message("SelectionCallbackHandler: A selection handler already active.");
2615
            return;
2616
        }
2617

2618
        currentSelectionHandler = std::make_unique<SelectionCallbackHandler>();
2619
        if (viewer)
2620
        {
2621
            currentSelectionHandler->userData = ud;
2622
            currentSelectionHandler->fnCb = doFunction;
2623
            currentSelectionHandler->prevSelectionCursor = viewer->cursor();
2624
            viewer->setEditingCursor(cursor);
2625
            viewer->addEventCallback(SoEvent::getClassTypeId(),
2626
                SelectionCallbackHandler::selectionCallback, currentSelectionHandler.get());
2627
            currentSelectionHandler->prevSelectionEn = viewer->isSelectionEnabled();
2628
            viewer->setSelectionEnabled(false);
2629
            viewer->startSelection(selectionMode);
2630
        }
2631
    }
2632

2633
    void* getUserData() const {
2634
        return userData;
2635
    }
2636

2637
    // Implements the event handler. In the normal case the provided function is called.
2638
    // Also supports aborting the selection mode by pressing (releasing) the Escape key.
2639
    static void selectionCallback(void * ud, SoEventCallback * n)
2640
    {
2641
        auto selectionHandler = static_cast<SelectionCallbackHandler*>(ud);
2642
        auto view = static_cast<Gui::View3DInventorViewer*>(n->getUserData());
2643
        const SoEvent* ev = n->getEvent();
2644
        if (ev->isOfType(SoKeyboardEvent::getClassTypeId())) {
2645

2646
            n->setHandled();
2647
            n->getAction()->setHandled();
2648

2649
            const auto ke = static_cast<const SoKeyboardEvent*>(ev);
2650
            const SbBool press = ke->getState() == SoButtonEvent::DOWN ? true : false;
2651
            if (ke->getKey() == SoKeyboardEvent::ESCAPE) {
2652

2653
                if (!press) {
2654
                    view->abortSelection();
2655
                    restoreState(selectionHandler, view);
2656
                }
2657
            }
2658
        }
2659
        else if (ev->isOfType(SoMouseButtonEvent::getClassTypeId())) {
2660
            const auto mbe = static_cast<const SoMouseButtonEvent*>(ev);
2661

2662
            // Mark all incoming mouse button events as handled, especially, to deactivate the selection node
2663
            n->getAction()->setHandled();
2664

2665
            if (mbe->getButton() == SoMouseButtonEvent::BUTTON1 && mbe->getState() == SoButtonEvent::UP)
2666
            {
2667
                if (selectionHandler && selectionHandler->fnCb)
2668
                    selectionHandler->fnCb(selectionHandler->getUserData(), n);
2669
                restoreState(selectionHandler, view);
2670
            }
2671
            // No other mouse events available from Coin3D to implement right mouse up abort
2672
        }
2673
    }
2674

2675
    static void restoreState(SelectionCallbackHandler * selectionHandler, View3DInventorViewer* view)
2676
    {
2677
        if (selectionHandler)
2678
        {
2679
            selectionHandler->fnCb = nullptr;
2680
            view->setEditingCursor(selectionHandler->prevSelectionCursor);
2681
            view->removeEventCallback(SoEvent::getClassTypeId(), SelectionCallbackHandler::selectionCallback, selectionHandler);
2682
            view->setSelectionEnabled(selectionHandler->prevSelectionEn);
2683
        }
2684
        Application::Instance->commandManager().testActive();
2685
        currentSelectionHandler = nullptr;
2686
    }
2687

2688
    static QCursor makeCursor(QWidget* widget, const QSize& size, const char* svgFile, int hotX, int hotY)
2689
    {
2690
        qreal pRatio = widget->devicePixelRatioF();
2691
        qreal hotXF = hotX;
2692
        qreal hotYF = hotY;
2693
#if !defined(Q_OS_WIN32) && !defined(Q_OS_MACOS)
2694
        if (qApp->platformName() == QLatin1String("xcb")) {
2695
            hotXF *= pRatio;
2696
            hotYF *= pRatio;
2697
        }
2698
#endif
2699
        qreal cursorWidth = size.width() * pRatio;
2700
        qreal cursorHeight = size.height() * pRatio;
2701
        QPixmap px(Gui::BitmapFactory().pixmapFromSvg(svgFile, QSizeF(cursorWidth, cursorHeight)));
2702
        px.setDevicePixelRatio(pRatio);
2703
        return QCursor(px, hotXF, hotYF);
2704
    }
2705
};
2706
}
2707

2708
std::unique_ptr<SelectionCallbackHandler> SelectionCallbackHandler::currentSelectionHandler = std::unique_ptr<SelectionCallbackHandler>();
2709
//===========================================================================
2710
// Std_ViewBoxZoom
2711
//===========================================================================
2712

2713
DEF_3DV_CMD(StdViewBoxZoom)
2714

2715
StdViewBoxZoom::StdViewBoxZoom()
2716
  : Command("Std_ViewBoxZoom")
2717
{
2718
    sGroup        = "Standard-View";
2719
    sMenuText     = QT_TR_NOOP("Box zoom");
2720
    sToolTipText  = QT_TR_NOOP("Activate the box zoom tool");
2721
    sWhatsThis    = "Std_ViewBoxZoom";
2722
    sStatusTip    = QT_TR_NOOP("Activate the box zoom tool");
2723
    sPixmap       = "zoom-border";
2724
    sAccel        = "Ctrl+B";
2725
    eType         = Alter3DView;
2726
}
2727

2728
void StdViewBoxZoom::activated(int iMsg)
2729
{
2730
    Q_UNUSED(iMsg);
2731
    auto view = qobject_cast<View3DInventor*>(getMainWindow()->activeWindow());
2732
    if ( view ) {
2733
        View3DInventorViewer* viewer = view->getViewer();
2734
        if (!viewer->isSelecting()) {
2735
            // NOLINTBEGIN
2736
            QCursor cursor = SelectionCallbackHandler::makeCursor(viewer, QSize(32, 32),
2737
                                                                  "zoom-border-cross", 6, 6);
2738
            SelectionCallbackHandler::Create(viewer, View3DInventorViewer::BoxZoom, cursor);
2739
            // NOLINTEND
2740
        }
2741
    }
2742
}
2743

2744
//===========================================================================
2745
// Std_BoxSelection
2746
//===========================================================================
2747
DEF_3DV_CMD(StdBoxSelection)
2748

2749
StdBoxSelection::StdBoxSelection()
2750
  : Command("Std_BoxSelection")
2751
{
2752
    sGroup        = "Standard-View";
2753
    sMenuText     = QT_TR_NOOP("Box selection");
2754
    sToolTipText  = QT_TR_NOOP("Activate the box selection tool");
2755
    sWhatsThis    = "Std_BoxSelection";
2756
    sStatusTip    = QT_TR_NOOP("Activate the box selection tool");
2757
    sPixmap       = "edit-select-box";
2758
    sAccel        = "Shift+B";
2759
    eType         = AlterSelection;
2760
}
2761

2762
using SelectionMode = enum { CENTER, INTERSECT };
2763

2764
static std::vector<std::string> getBoxSelection(
2765
        ViewProviderDocumentObject *vp, SelectionMode mode, bool selectElement,
2766
        const Base::ViewProjMethod &proj, const Base::Polygon2d &polygon,
2767
        const Base::Matrix4D &mat, bool transform=true, int depth=0)
2768
{
2769
    std::vector<std::string> ret;
2770
    auto obj = vp->getObject();
2771
    if(!obj || !obj->isAttachedToDocument())
2772
        return ret;
2773

2774
    // DO NOT check this view object Visibility, let the caller do this. Because
2775
    // we may be called by upper object hierarchy that manages our visibility.
2776

2777
    auto bbox3 = vp->getBoundingBox(nullptr,transform);
2778
    if(!bbox3.IsValid())
2779
        return ret;
2780

2781
    auto bbox = bbox3.Transformed(mat).ProjectBox(&proj);
2782

2783
    // check if both two boundary points are inside polygon, only
2784
    // valid since we know the given polygon is a box.
2785
    if(polygon.Contains(Base::Vector2d(bbox.MinX,bbox.MinY)) &&
2786
       polygon.Contains(Base::Vector2d(bbox.MaxX,bbox.MaxY)))
2787
    {
2788
        ret.emplace_back("");
2789
        return ret;
2790
    }
2791

2792
    if(!bbox.Intersect(polygon))
2793
        return ret;
2794

2795
    const auto &subs = obj->getSubObjects(App::DocumentObject::GS_SELECT);
2796
    if(subs.empty()) {
2797
        if(!selectElement) {
2798
            if(mode==INTERSECT || polygon.Contains(bbox.GetCenter()))
2799
                ret.emplace_back("");
2800
            return ret;
2801
        }
2802
        Base::PyGILStateLocker lock;
2803
        PyObject *pyobj = nullptr;
2804
        Base::Matrix4D matCopy(mat);
2805
        obj->getSubObject(nullptr,&pyobj,&matCopy,transform,depth);
2806
        if(!pyobj)
2807
            return ret;
2808
        Py::Object pyobject(pyobj,true);
2809
        if(!PyObject_TypeCheck(pyobj,&Data::ComplexGeoDataPy::Type))
2810
            return ret;
2811
        auto data = static_cast<Data::ComplexGeoDataPy*>(pyobj)->getComplexGeoDataPtr();
2812
        for(auto type : data->getElementTypes()) {
2813
            size_t count = data->countSubElements(type);
2814
            if(!count)
2815
                continue;
2816
            for(size_t i=1;i<=count;++i) {
2817
                std::string element(type);
2818
                element += std::to_string(i);
2819
                std::unique_ptr<Data::Segment> segment(data->getSubElementByName(element.c_str()));
2820
                if(!segment)
2821
                    continue;
2822
                std::vector<Base::Vector3d> points;
2823
                std::vector<Data::ComplexGeoData::Line> lines;
2824
                data->getLinesFromSubElement(segment.get(),points,lines);
2825
                if(lines.empty()) {
2826
                    if(points.empty())
2827
                        continue;
2828
                    auto v = proj(points[0]);
2829
                    if(polygon.Contains(Base::Vector2d(v.x,v.y)))
2830
                        ret.push_back(element);
2831
                    continue;
2832
                }
2833
                Base::Polygon2d loop;
2834
                // TODO: can we assume the line returned above are in proper
2835
                // order if the element is a face?
2836
                auto v = proj(points[lines.front().I1]);
2837
                loop.Add(Base::Vector2d(v.x,v.y));
2838
                for(auto &line : lines) {
2839
                    for(auto i=line.I1;i<line.I2;++i) {
2840
                        auto v = proj(points[i+1]);
2841
                        loop.Add(Base::Vector2d(v.x,v.y));
2842
                    }
2843
                }
2844
                if(!polygon.Intersect(loop))
2845
                    continue;
2846
                if(mode==CENTER && !polygon.Contains(loop.CalcBoundBox().GetCenter()))
2847
                    continue;
2848
                ret.push_back(element);
2849
            }
2850
            break;
2851
        }
2852
        return ret;
2853
    }
2854

2855
    size_t count = 0;
2856
    for(auto &sub : subs) {
2857
        App::DocumentObject *parent = nullptr;
2858
        std::string childName;
2859
        Base::Matrix4D smat(mat);
2860
        auto sobj = obj->resolve(sub.c_str(),&parent,&childName,nullptr,nullptr,&smat,transform,depth+1);
2861
        if(!sobj)
2862
            continue;
2863
        int vis;
2864
        if(!parent || (vis=parent->isElementVisible(childName.c_str()))<0)
2865
            vis = sobj->Visibility.getValue()?1:0;
2866

2867
        if(!vis)
2868
            continue;
2869

2870
        auto svp = dynamic_cast<ViewProviderDocumentObject*>(Application::Instance->getViewProvider(sobj));
2871
        if(!svp)
2872
            continue;
2873

2874
        const auto &sels = getBoxSelection(svp,mode,selectElement,proj,polygon,smat,false,depth+1);
2875
        if(sels.size()==1 && sels[0].empty())
2876
            ++count;
2877
        for(auto &sel : sels)
2878
            ret.emplace_back(sub+sel);
2879
    }
2880
    if(count==subs.size()) {
2881
        ret.resize(1);
2882
        ret[0].clear();
2883
    }
2884
    return ret;
2885
}
2886

2887
static void doSelect(void* ud, SoEventCallback * cb)
2888
{
2889
    bool selectElement = ud ? true : false;
2890
    auto viewer = static_cast<Gui::View3DInventorViewer*>(cb->getUserData());
2891

2892
    viewer->setSelectionEnabled(true);
2893

2894
    SelectionMode selectionMode = CENTER;
2895

2896
    std::vector<SbVec2f> picked = viewer->getGLPolygon();
2897
    SoCamera* cam = viewer->getSoRenderManager()->getCamera();
2898
    SbViewVolume vv = cam->getViewVolume();
2899
    Gui::ViewVolumeProjection proj(vv);
2900
    Base::Polygon2d polygon;
2901
    if (picked.size() == 2) {
2902
        SbVec2f pt1 = picked[0];
2903
        SbVec2f pt2 = picked[1];
2904
        polygon.Add(Base::Vector2d(pt1[0], pt1[1]));
2905
        polygon.Add(Base::Vector2d(pt1[0], pt2[1]));
2906
        polygon.Add(Base::Vector2d(pt2[0], pt2[1]));
2907
        polygon.Add(Base::Vector2d(pt2[0], pt1[1]));
2908

2909
        // when selecting from right to left then select by intersection
2910
        // otherwise if the center is inside the rectangle
2911
        if (picked[0][0] > picked[1][0])
2912
            selectionMode = INTERSECT;
2913
    }
2914
    else {
2915
        for (const auto & it : picked)
2916
            polygon.Add(Base::Vector2d(it[0],it[1]));
2917
    }
2918

2919
    App::Document* doc = App::GetApplication().getActiveDocument();
2920
    if (doc) {
2921
        cb->setHandled();
2922

2923
        const SoEvent* ev = cb->getEvent();
2924
        if (ev && !ev->wasCtrlDown()) {
2925
            Gui::Selection().clearSelection(doc->getName());
2926
        }
2927

2928
        const std::vector<App::DocumentObject*> objects = doc->getObjects();
2929
        for(auto obj : objects) {
2930
            if(App::GeoFeatureGroupExtension::getGroupOfObject(obj))
2931
                continue;
2932

2933
            auto vp = dynamic_cast<ViewProviderDocumentObject*>(Application::Instance->getViewProvider(obj));
2934
            if (!vp || !vp->isVisible())
2935
                continue;
2936

2937
            Base::Matrix4D mat;
2938
            for(auto &sub : getBoxSelection(vp,selectionMode,selectElement,proj,polygon,mat))
2939
                Gui::Selection().addSelection(doc->getName(), obj->getNameInDocument(), sub.c_str());
2940
        }
2941
    }
2942
}
2943

2944
void StdBoxSelection::activated(int iMsg)
2945
{
2946
    Q_UNUSED(iMsg);
2947
    auto view = qobject_cast<View3DInventor*>(getMainWindow()->activeWindow());
2948
    if (view) {
2949
        View3DInventorViewer* viewer = view->getViewer();
2950
        if (!viewer->isSelecting()) {
2951
            // #0002931: Box select misbehaves with touchpad navigation style
2952
            // Notify the navigation style to cleanup internal states
2953
            int mode = viewer->navigationStyle()->getViewingMode();
2954
            if (mode != Gui::NavigationStyle::IDLE) {
2955
                SoKeyboardEvent ev;
2956
                viewer->navigationStyle()->processEvent(&ev);
2957
            }
2958

2959
            // NOLINTBEGIN
2960
            QCursor cursor = SelectionCallbackHandler::makeCursor(viewer, QSize(32, 32),
2961
                                                                  "edit-select-box-cross", 6, 6);
2962
            SelectionCallbackHandler::Create(viewer, View3DInventorViewer::Rubberband, cursor, doSelect, nullptr);
2963
            viewer->setSelectionEnabled(false);
2964
            // NOLINTEND
2965
        }
2966
    }
2967
}
2968

2969
//===========================================================================
2970
// Std_BoxElementSelection
2971
//===========================================================================
2972

2973
DEF_3DV_CMD(StdBoxElementSelection)
2974

2975
StdBoxElementSelection::StdBoxElementSelection()
2976
  : Command("Std_BoxElementSelection")
2977
{
2978
    sGroup        = "Standard-View";
2979
    sMenuText     = QT_TR_NOOP("Box element selection");
2980
    sToolTipText  = QT_TR_NOOP("Box element selection");
2981
    sWhatsThis    = "Std_BoxElementSelection";
2982
    sStatusTip    = QT_TR_NOOP("Box element selection");
2983
    sPixmap       = "edit-element-select-box";
2984
    sAccel        = "Shift+E";
2985
    eType         = AlterSelection;
2986
}
2987

2988
void StdBoxElementSelection::activated(int iMsg)
2989
{
2990
    Q_UNUSED(iMsg);
2991
    auto view = qobject_cast<View3DInventor*>(getMainWindow()->activeWindow());
2992
    if (view) {
2993
        View3DInventorViewer* viewer = view->getViewer();
2994
        if (!viewer->isSelecting()) {
2995
            // #0002931: Box select misbehaves with touchpad navigation style
2996
            // Notify the navigation style to cleanup internal states
2997
            int mode = viewer->navigationStyle()->getViewingMode();
2998
            if (mode != Gui::NavigationStyle::IDLE) {
2999
                SoKeyboardEvent ev;
3000
                viewer->navigationStyle()->processEvent(&ev);
3001
            }
3002

3003
            // NOLINTBEGIN
3004
            QCursor cursor = SelectionCallbackHandler::makeCursor(viewer, QSize(32, 32),
3005
                                                                  "edit-element-select-box-cross", 6, 6);
3006
            SelectionCallbackHandler::Create(viewer, View3DInventorViewer::Rubberband, cursor, doSelect, this);
3007
            viewer->setSelectionEnabled(false);
3008
            // NOLINTEND
3009
        }
3010
    }
3011
}
3012

3013

3014
//===========================================================================
3015
// Std_TreeSelection
3016
//===========================================================================
3017

3018
DEF_STD_CMD(StdTreeSelection)
3019

3020
StdTreeSelection::StdTreeSelection()
3021
  : Command("Std_TreeSelection")
3022
{
3023
    sGroup        = "TreeView";
3024
    sMenuText     = QT_TR_NOOP("Go to selection");
3025
    sToolTipText  = QT_TR_NOOP("Scroll to first selected item");
3026
    sWhatsThis    = "Std_TreeSelection";
3027
    sStatusTip    = QT_TR_NOOP("Scroll to first selected item");
3028
    eType         = Alter3DView;
3029
    sPixmap       = "tree-goto-sel";
3030
    sAccel        = "T,G";
3031
}
3032

3033
void StdTreeSelection::activated(int iMsg)
3034
{
3035
    Q_UNUSED(iMsg);
3036
    TreeWidget::scrollItemToTop();
3037
}
3038

3039
//===========================================================================
3040
// Std_TreeCollapse
3041
//===========================================================================
3042

3043
DEF_STD_CMD(StdCmdTreeCollapse)
3044

3045
StdCmdTreeCollapse::StdCmdTreeCollapse()
3046
  : Command("Std_TreeCollapse")
3047
{
3048
    sGroup        = "View";
3049
    sMenuText     = QT_TR_NOOP("Collapse selected item");
3050
    sToolTipText  = QT_TR_NOOP("Collapse currently selected tree items");
3051
    sWhatsThis    = "Std_TreeCollapse";
3052
    sStatusTip    = QT_TR_NOOP("Collapse currently selected tree items");
3053
    eType         = Alter3DView;
3054
}
3055

3056
void StdCmdTreeCollapse::activated(int iMsg)
3057
{
3058
    Q_UNUSED(iMsg);
3059
    QList<TreeWidget*> tree = Gui::getMainWindow()->findChildren<TreeWidget*>();
3060
    for (QList<TreeWidget*>::iterator it = tree.begin(); it != tree.end(); ++it)
3061
        (*it)->expandSelectedItems(TreeItemMode::CollapseItem);
3062
}
3063

3064
//===========================================================================
3065
// Std_TreeExpand
3066
//===========================================================================
3067

3068
DEF_STD_CMD(StdCmdTreeExpand)
3069

3070
StdCmdTreeExpand::StdCmdTreeExpand()
3071
  : Command("Std_TreeExpand")
3072
{
3073
    sGroup        = "View";
3074
    sMenuText     = QT_TR_NOOP("Expand selected item");
3075
    sToolTipText  = QT_TR_NOOP("Expand currently selected tree items");
3076
    sWhatsThis    = "Std_TreeExpand";
3077
    sStatusTip    = QT_TR_NOOP("Expand currently selected tree items");
3078
    eType         = Alter3DView;
3079
}
3080

3081
void StdCmdTreeExpand::activated(int iMsg)
3082
{
3083
    Q_UNUSED(iMsg);
3084
    QList<TreeWidget*> tree = Gui::getMainWindow()->findChildren<TreeWidget*>();
3085
    for (QList<TreeWidget*>::iterator it = tree.begin(); it != tree.end(); ++it)
3086
        (*it)->expandSelectedItems(TreeItemMode::ExpandItem);
3087
}
3088

3089
//===========================================================================
3090
// Std_TreeSelectAllInstance
3091
//===========================================================================
3092

3093
DEF_STD_CMD_A(StdCmdTreeSelectAllInstances)
3094

3095
StdCmdTreeSelectAllInstances::StdCmdTreeSelectAllInstances()
3096
  : Command("Std_TreeSelectAllInstances")
3097
{
3098
    sGroup        = "View";
3099
    sMenuText     = QT_TR_NOOP("Select all instances");
3100
    sToolTipText  = QT_TR_NOOP("Select all instances of the current selected object");
3101
    sWhatsThis    = "Std_TreeSelectAllInstances";
3102
    sStatusTip    = QT_TR_NOOP("Select all instances of the current selected object");
3103
    sPixmap       = "sel-instance";
3104
    eType         = AlterSelection;
3105
}
3106

3107
bool StdCmdTreeSelectAllInstances::isActive()
3108
{
3109
    const auto &sels = Selection().getSelectionEx("*",App::DocumentObject::getClassTypeId(), ResolveMode::OldStyleElement, true);
3110
    if(sels.empty())
3111
        return false;
3112
    auto obj = sels[0].getObject();
3113
    if(!obj || !obj->isAttachedToDocument())
3114
        return false;
3115
    return dynamic_cast<ViewProviderDocumentObject*>(
3116
            Application::Instance->getViewProvider(obj)) != nullptr;
3117
}
3118

3119
void StdCmdTreeSelectAllInstances::activated(int iMsg)
3120
{
3121
    Q_UNUSED(iMsg);
3122
    const auto &sels = Selection().getSelectionEx("*",App::DocumentObject::getClassTypeId(), ResolveMode::OldStyleElement, true);
3123
    if(sels.empty())
3124
        return;
3125
    auto obj = sels[0].getObject();
3126
    if(!obj || !obj->isAttachedToDocument())
3127
        return;
3128
    auto vpd = dynamic_cast<ViewProviderDocumentObject*>(
3129
            Application::Instance->getViewProvider(obj));
3130
    if(!vpd)
3131
        return;
3132
    Selection().selStackPush();
3133
    Selection().clearCompleteSelection();
3134
    const auto trees = getMainWindow()->findChildren<TreeWidget*>();
3135
    for(auto tree : trees)
3136
        tree->selectAllInstances(*vpd);
3137
    Selection().selStackPush();
3138
}
3139

3140

3141
//===========================================================================
3142
// Std_SceneInspector
3143
//===========================================================================
3144

3145
DEF_3DV_CMD(StdCmdSceneInspector)
3146

3147
StdCmdSceneInspector::StdCmdSceneInspector()
3148
  : Command("Std_SceneInspector")
3149
{
3150
    // setting the
3151
    sGroup        = "Tools";
3152
    sMenuText     = QT_TR_NOOP("Scene inspector...");
3153
    sToolTipText  = QT_TR_NOOP("Scene inspector");
3154
    sWhatsThis    = "Std_SceneInspector";
3155
    sStatusTip    = QT_TR_NOOP("Scene inspector");
3156
    eType         = Alter3DView;
3157
    sPixmap       = "Std_SceneInspector";
3158
}
3159

3160
void StdCmdSceneInspector::activated(int iMsg)
3161
{
3162
    Q_UNUSED(iMsg);
3163
    Gui::Document* doc = Application::Instance->activeDocument();
3164
    if (doc) {
3165
        static QPointer<Gui::Dialog::DlgInspector> dlg = nullptr;
3166
        if (!dlg)
3167
            dlg = new Gui::Dialog::DlgInspector(getMainWindow());
3168
        dlg->setDocument(doc);
3169
        dlg->setAttribute(Qt::WA_DeleteOnClose);
3170
        dlg->show();
3171
    }
3172
}
3173

3174
//===========================================================================
3175
// Std_TextureMapping
3176
//===========================================================================
3177

3178
DEF_STD_CMD_A(StdCmdTextureMapping)
3179

3180
StdCmdTextureMapping::StdCmdTextureMapping()
3181
  : Command("Std_TextureMapping")
3182
{
3183
    // setting the
3184
    sGroup        = "Tools";
3185
    sMenuText     = QT_TR_NOOP("Texture mapping...");
3186
    sToolTipText  = QT_TR_NOOP("Texture mapping");
3187
    sWhatsThis    = "Std_TextureMapping";
3188
    sStatusTip    = QT_TR_NOOP("Texture mapping");
3189
    sPixmap       = "Std_TextureMapping";
3190
    eType         = Alter3DView;
3191
}
3192

3193
void StdCmdTextureMapping::activated(int iMsg)
3194
{
3195
    Q_UNUSED(iMsg);
3196
    Gui::Control().showDialog(new Gui::Dialog::TaskTextureMapping);
3197
}
3198

3199
bool StdCmdTextureMapping::isActive()
3200
{
3201
    Gui::MDIView* view = getMainWindow()->activeWindow();
3202
    return view && view->isDerivedFrom(Gui::View3DInventor::getClassTypeId())
3203
                && (!(Gui::Control().activeDialog()));
3204
}
3205

3206
DEF_STD_CMD(StdCmdDemoMode)
3207

3208
StdCmdDemoMode::StdCmdDemoMode()
3209
  : Command("Std_DemoMode")
3210
{
3211
    sGroup        = "Standard-View";
3212
    sMenuText     = QT_TR_NOOP("View turntable...");
3213
    sToolTipText  = QT_TR_NOOP("View turntable");
3214
    sWhatsThis    = "Std_DemoMode";
3215
    sStatusTip    = QT_TR_NOOP("View turntable");
3216
    eType         = Alter3DView;
3217
    sPixmap       = "Std_DemoMode";
3218
}
3219

3220
void StdCmdDemoMode::activated(int iMsg)
3221
{
3222
    Q_UNUSED(iMsg);
3223
    static QPointer<QDialog> dlg = nullptr;
3224
    if (!dlg)
3225
        dlg = new Gui::Dialog::DemoMode(getMainWindow());
3226
    dlg->setAttribute(Qt::WA_DeleteOnClose);
3227
    dlg->show();
3228
}
3229

3230

3231
//===========================================================================
3232
// Std_SelBack
3233
//===========================================================================
3234

3235
DEF_STD_CMD_A(StdCmdSelBack)
3236

3237
StdCmdSelBack::StdCmdSelBack()
3238
  :Command("Std_SelBack")
3239
{
3240
  sGroup        = "View";
3241
  sMenuText     = QT_TR_NOOP("Selection back");
3242
  static std::string toolTip = std::string("<p>")
3243
      + QT_TR_NOOP("Restore the previous Tree view selection. "
3244
      "Only works if Tree RecordSelection mode is switched on.")
3245
      + "</p>";
3246
  sToolTipText = toolTip.c_str();
3247
  sWhatsThis    = "Std_SelBack";
3248
  sStatusTip    = sToolTipText;
3249
  sPixmap       = "sel-back";
3250
  sAccel        = "S, B";
3251
  eType         = AlterSelection;
3252
}
3253

3254
void StdCmdSelBack::activated(int iMsg)
3255
{
3256
    Q_UNUSED(iMsg);
3257
    Selection().selStackGoBack();
3258
}
3259

3260
bool StdCmdSelBack::isActive()
3261
{
3262
  return Selection().selStackBackSize()>1;
3263
}
3264

3265
//===========================================================================
3266
// Std_SelForward
3267
//===========================================================================
3268

3269
DEF_STD_CMD_A(StdCmdSelForward)
3270

3271
StdCmdSelForward::StdCmdSelForward()
3272
  :Command("Std_SelForward")
3273
{
3274
  sGroup        = "View";
3275
  sMenuText     = QT_TR_NOOP("Selection forward");
3276
  static std::string toolTip = std::string("<p>")
3277
      + QT_TR_NOOP("Restore the next Tree view selection. "
3278
      "Only works if Tree RecordSelection mode is switched on.")
3279
      + "</p>";
3280
  sToolTipText = toolTip.c_str();
3281
  sWhatsThis    = "Std_SelForward";
3282
  sStatusTip    = sToolTipText;
3283
  sPixmap       = "sel-forward";
3284
  sAccel        = "S, F";
3285
  eType         = AlterSelection;
3286
}
3287

3288
void StdCmdSelForward::activated(int iMsg)
3289
{
3290
    Q_UNUSED(iMsg);
3291
    Selection().selStackGoForward();
3292
}
3293

3294
bool StdCmdSelForward::isActive()
3295
{
3296
  return !!Selection().selStackForwardSize();
3297
}
3298

3299
//=======================================================================
3300
// Std_TreeSingleDocument
3301
//===========================================================================
3302
#define TREEVIEW_DOC_CMD_DEF(_name,_v) \
3303
DEF_STD_CMD_AC(StdTree##_name) \
3304
void StdTree##_name::activated(int){ \
3305
    TreeParams::setDocumentMode(_v);\
3306
    if(_pcAction) _pcAction->setChecked(true,true);\
3307
}\
3308
Action * StdTree##_name::createAction(void) {\
3309
    Action *pcAction = Command::createAction();\
3310
    pcAction->setCheckable(true);\
3311
    pcAction->setIcon(QIcon());\
3312
    _pcAction = pcAction;\
3313
    isActive();\
3314
    return pcAction;\
3315
}\
3316
bool StdTree##_name::isActive() {\
3317
    bool checked = TreeParams::getDocumentMode()==_v;\
3318
    if(_pcAction && _pcAction->isChecked()!=checked)\
3319
        _pcAction->setChecked(checked,true);\
3320
    return true;\
3321
}
3322

3323
TREEVIEW_DOC_CMD_DEF(SingleDocument,0)
3324

3325
StdTreeSingleDocument::StdTreeSingleDocument()
3326
  : Command("Std_TreeSingleDocument")
3327
{
3328
    sGroup       = "TreeView";
3329
    sMenuText    = QT_TR_NOOP("Single document");
3330
    sToolTipText = QT_TR_NOOP("Only display the active document in the tree view");
3331
    sWhatsThis   = "Std_TreeSingleDocument";
3332
    sStatusTip   = QT_TR_NOOP("Only display the active document in the tree view");
3333
    sPixmap      = "tree-doc-single";
3334
    eType        = 0;
3335
}
3336

3337
//===========================================================================
3338
// Std_TreeMultiDocument
3339
//===========================================================================
3340
TREEVIEW_DOC_CMD_DEF(MultiDocument,1)
3341

3342
StdTreeMultiDocument::StdTreeMultiDocument()
3343
  : Command("Std_TreeMultiDocument")
3344
{
3345
    sGroup       = "TreeView";
3346
    sMenuText    = QT_TR_NOOP("Multi document");
3347
    sToolTipText = QT_TR_NOOP("Display all documents in the tree view");
3348
    sWhatsThis   = "Std_TreeMultiDocument";
3349
    sStatusTip   = QT_TR_NOOP("Display all documents in the tree view");
3350
    sPixmap      = "tree-doc-multi";
3351
    eType        = 0;
3352
}
3353

3354
//===========================================================================
3355
// Std_TreeCollapseDocument
3356
//===========================================================================
3357
TREEVIEW_DOC_CMD_DEF(CollapseDocument,2)
3358

3359
StdTreeCollapseDocument::StdTreeCollapseDocument()
3360
  : Command("Std_TreeCollapseDocument")
3361
{
3362
    sGroup       = "TreeView";
3363
    sMenuText    = QT_TR_NOOP("Collapse/Expand");
3364
    sToolTipText = QT_TR_NOOP("Expand active document and collapse all others");
3365
    sWhatsThis   = "Std_TreeCollapseDocument";
3366
    sStatusTip   = QT_TR_NOOP("Expand active document and collapse all others");
3367
    sPixmap      = "tree-doc-collapse";
3368
    eType        = 0;
3369
}
3370

3371
//===========================================================================
3372
// Std_TreeSyncView
3373
//===========================================================================
3374
#define TREEVIEW_CMD_DEF(_name) \
3375
DEF_STD_CMD_AC(StdTree##_name) \
3376
void StdTree##_name::activated(int){ \
3377
    auto checked = !TreeParams::get##_name();\
3378
    TreeParams::set##_name(checked);\
3379
    if(_pcAction) _pcAction->setChecked(checked,true);\
3380
}\
3381
Action * StdTree##_name::createAction(void) {\
3382
    Action *pcAction = Command::createAction();\
3383
    pcAction->setCheckable(true);\
3384
    pcAction->setIcon(QIcon());\
3385
    _pcAction = pcAction;\
3386
    isActive();\
3387
    return pcAction;\
3388
}\
3389
bool StdTree##_name::isActive() {\
3390
    bool checked = TreeParams::get##_name();\
3391
    if(_pcAction && _pcAction->isChecked()!=checked)\
3392
        _pcAction->setChecked(checked,true);\
3393
    return true;\
3394
}
3395

3396
TREEVIEW_CMD_DEF(SyncView)
3397

3398
StdTreeSyncView::StdTreeSyncView()
3399
  : Command("Std_TreeSyncView")
3400
{
3401
    sGroup       = "TreeView";
3402
    sMenuText    = QT_TR_NOOP("Sync view");
3403
    sToolTipText = QT_TR_NOOP("Auto switch to the 3D view containing the selected item");
3404
    sStatusTip   = sToolTipText;
3405
    sWhatsThis   = "Std_TreeSyncView";
3406
    sPixmap      = "tree-sync-view";
3407
    sAccel       = "T,1";
3408
    eType        = 0;
3409
}
3410

3411
//===========================================================================
3412
// Std_TreeSyncSelection
3413
//===========================================================================
3414
TREEVIEW_CMD_DEF(SyncSelection)
3415

3416
StdTreeSyncSelection::StdTreeSyncSelection()
3417
  : Command("Std_TreeSyncSelection")
3418
{
3419
    sGroup       = "TreeView";
3420
    sMenuText    = QT_TR_NOOP("Sync selection");
3421
    sToolTipText = QT_TR_NOOP("Auto expand tree item when the corresponding object is selected in 3D view");
3422
    sStatusTip   = sToolTipText;
3423
    sWhatsThis   = "Std_TreeSyncSelection";
3424
    sPixmap      = "tree-sync-sel";
3425
    sAccel       = "T,2";
3426
    eType        = 0;
3427
}
3428

3429
//===========================================================================
3430
// Std_TreeSyncPlacement
3431
//===========================================================================
3432
TREEVIEW_CMD_DEF(SyncPlacement)
3433

3434
StdTreeSyncPlacement::StdTreeSyncPlacement()
3435
  : Command("Std_TreeSyncPlacement")
3436
{
3437
    sGroup       = "TreeView";
3438
    sMenuText    = QT_TR_NOOP("Sync placement");
3439
    sToolTipText = QT_TR_NOOP("Auto adjust placement on drag and drop objects across coordinate systems");
3440
    sStatusTip   = sToolTipText;
3441
    sWhatsThis   = "Std_TreeSyncPlacement";
3442
    sPixmap      = "tree-sync-pla";
3443
    sAccel       = "T,3";
3444
    eType        = 0;
3445
}
3446

3447
//===========================================================================
3448
// Std_TreePreSelection
3449
//===========================================================================
3450
TREEVIEW_CMD_DEF(PreSelection)
3451

3452
StdTreePreSelection::StdTreePreSelection()
3453
  : Command("Std_TreePreSelection")
3454
{
3455
    sGroup       = "TreeView";
3456
    sMenuText    = QT_TR_NOOP("Pre-selection");
3457
    sToolTipText = QT_TR_NOOP("Preselect the object in 3D view when hovering the cursor over the tree item");
3458
    sStatusTip   = sToolTipText;
3459
    sWhatsThis   = "Std_TreePreSelection";
3460
    sPixmap      = "tree-pre-sel";
3461
    sAccel       = "T,4";
3462
    eType        = 0;
3463
}
3464

3465
//===========================================================================
3466
// Std_TreeRecordSelection
3467
//===========================================================================
3468
TREEVIEW_CMD_DEF(RecordSelection)
3469

3470
StdTreeRecordSelection::StdTreeRecordSelection()
3471
  : Command("Std_TreeRecordSelection")
3472
{
3473
    sGroup       = "TreeView";
3474
    sMenuText    = QT_TR_NOOP("Record selection");
3475
    sToolTipText = QT_TR_NOOP("Record selection in tree view in order to go back/forward using navigation button");
3476
    sStatusTip   = sToolTipText;
3477
    sWhatsThis   = "Std_TreeRecordSelection";
3478
    sPixmap      = "tree-rec-sel";
3479
    sAccel       = "T,5";
3480
    eType        = 0;
3481
}
3482

3483
//===========================================================================
3484
// Std_TreeDrag
3485
//===========================================================================
3486
DEF_STD_CMD(StdTreeDrag)
3487

3488
StdTreeDrag::StdTreeDrag()
3489
  : Command("Std_TreeDrag")
3490
{
3491
    sGroup       = "TreeView";
3492
    sMenuText    = QT_TR_NOOP("Initiate dragging");
3493
    sToolTipText = QT_TR_NOOP("Initiate dragging of current selected tree items");
3494
    sStatusTip   = sToolTipText;
3495
    sWhatsThis   = "Std_TreeDrag";
3496
    sPixmap      = "tree-item-drag";
3497
    sAccel       = "T,D";
3498
    eType        = 0;
3499
}
3500

3501
void StdTreeDrag::activated(int)
3502
{
3503
    if(Gui::Selection().hasSelection()) {
3504
        const auto trees = getMainWindow()->findChildren<TreeWidget*>();
3505
        for(auto tree : trees) {
3506
            if(tree->isVisible()) {
3507
                tree->startDragging();
3508
                break;
3509
            }
3510
        }
3511
    }
3512
}
3513

3514
//======================================================================
3515
// Std_TreeViewActions
3516
//===========================================================================
3517
//
3518
class StdCmdTreeViewActions : public GroupCommand
3519
{
3520
public:
3521
    StdCmdTreeViewActions()
3522
        :GroupCommand("Std_TreeViewActions")
3523
    {
3524
        sGroup        = "TreeView";
3525
        sMenuText     = QT_TR_NOOP("TreeView actions");
3526
        sToolTipText  = QT_TR_NOOP("TreeView behavior options and actions");
3527
        sWhatsThis    = "Std_TreeViewActions";
3528
        sStatusTip    = QT_TR_NOOP("TreeView behavior options and actions");
3529
        eType         = 0;
3530
        bCanLog       = false;
3531

3532
        addCommand(new StdTreeSyncView());
3533
        addCommand(new StdTreeSyncSelection());
3534
        addCommand(new StdTreeSyncPlacement());
3535
        addCommand(new StdTreePreSelection());
3536
        addCommand(new StdTreeRecordSelection());
3537

3538
        addCommand();
3539

3540
        addCommand(new StdTreeSingleDocument());
3541
        addCommand(new StdTreeMultiDocument());
3542
        addCommand(new StdTreeCollapseDocument());
3543

3544
        addCommand();
3545

3546
        addCommand(new StdTreeDrag(),!cmds.empty());
3547
        addCommand(new StdTreeSelection(),!cmds.empty());
3548

3549
        addCommand();
3550

3551
        addCommand(new StdCmdSelBack());
3552
        addCommand(new StdCmdSelForward());
3553
    }
3554
    const char* className() const override {return "StdCmdTreeViewActions";}
3555
};
3556

3557

3558
//======================================================================
3559
// Std_SelBoundingBox
3560
//===========================================================================
3561
DEF_STD_CMD_AC(StdCmdSelBoundingBox)
3562

3563
StdCmdSelBoundingBox::StdCmdSelBoundingBox()
3564
  :Command("Std_SelBoundingBox")
3565
{
3566
  sGroup        = "View";
3567
  sMenuText     = QT_TR_NOOP("&Bounding box");
3568
  sToolTipText  = QT_TR_NOOP("Show selection bounding box");
3569
  sWhatsThis    = "Std_SelBoundingBox";
3570
  sStatusTip    = QT_TR_NOOP("Show selection bounding box");
3571
  sPixmap       = "sel-bbox";
3572
  eType         = Alter3DView;
3573
}
3574

3575
void StdCmdSelBoundingBox::activated(int iMsg)
3576
{
3577
    bool checked = !!iMsg;
3578
    if(checked != ViewParams::instance()->getShowSelectionBoundingBox()) {
3579
        ViewParams::instance()->setShowSelectionBoundingBox(checked);
3580
        if(_pcAction)
3581
            _pcAction->setChecked(checked,true);
3582
    }
3583
}
3584

3585
bool StdCmdSelBoundingBox::isActive()
3586
{
3587
    if(_pcAction) {
3588
        bool checked = _pcAction->isChecked();
3589
        if(checked != ViewParams::instance()->getShowSelectionBoundingBox())
3590
            _pcAction->setChecked(!checked,true);
3591
    }
3592
    return true;
3593
}
3594

3595
Action * StdCmdSelBoundingBox::createAction()
3596
{
3597
    Action *pcAction = Command::createAction();
3598
    pcAction->setCheckable(true);
3599
    return pcAction;
3600
}
3601

3602
//===========================================================================
3603
// Std_DockOverlayAll
3604
//===========================================================================
3605

3606
DEF_STD_CMD(StdCmdDockOverlayAll)
3607

3608
StdCmdDockOverlayAll::StdCmdDockOverlayAll()
3609
  :Command("Std_DockOverlayAll")
3610
{
3611
  sGroup        = "View";
3612
  sMenuText     = QT_TR_NOOP("Toggle overlay for all");
3613
  sToolTipText  = QT_TR_NOOP("Toggle overlay mode for all docked windows");
3614
  sWhatsThis    = "Std_DockOverlayAll";
3615
  sStatusTip    = sToolTipText;
3616
  sAccel        = "F4";
3617
  eType         = 0;
3618
}
3619

3620
void StdCmdDockOverlayAll::activated(int iMsg)
3621
{
3622
    Q_UNUSED(iMsg);
3623
    OverlayManager::instance()->setOverlayMode(OverlayManager::OverlayMode::ToggleAll);
3624
}
3625

3626
//===========================================================================
3627
// Std_DockOverlayTransparentAll
3628
//===========================================================================
3629

3630
DEF_STD_CMD(StdCmdDockOverlayTransparentAll)
3631

3632
StdCmdDockOverlayTransparentAll::StdCmdDockOverlayTransparentAll()
3633
  :Command("Std_DockOverlayTransparentAll")
3634
{
3635
  sGroup        = "View";
3636
  sMenuText     = QT_TR_NOOP("Toggle transparent for all");
3637
  sToolTipText  = QT_TR_NOOP("Toggle transparent mode for all docked overlay windows.\n"
3638
                             "This makes the docked windows stay transparent at all times.");
3639
  sWhatsThis    = "Std_DockOverlayTransparentAll";
3640
  sStatusTip    = sToolTipText;
3641
  sAccel        = "SHIFT+F4";
3642
  eType         = 0;
3643
}
3644

3645
void StdCmdDockOverlayTransparentAll::activated(int iMsg)
3646
{
3647
    Q_UNUSED(iMsg);
3648
    OverlayManager::instance()->setOverlayMode(OverlayManager::OverlayMode::ToggleTransparentAll);
3649
}
3650

3651
//===========================================================================
3652
// Std_DockOverlayToggle
3653
//===========================================================================
3654

3655
DEF_STD_CMD(StdCmdDockOverlayToggle)
3656

3657
StdCmdDockOverlayToggle::StdCmdDockOverlayToggle()
3658
  :Command("Std_DockOverlayToggle")
3659
{
3660
  sGroup        = "View";
3661
  sMenuText     = QT_TR_NOOP("Toggle overlay");
3662
  sToolTipText  = QT_TR_NOOP("Toggle overlay mode for the docked window under the cursor");
3663
  sWhatsThis    = "Std_DockOverlayToggle";
3664
  sStatusTip    = sToolTipText;
3665
  sAccel        = "F3";
3666
  eType         = 0;
3667
}
3668

3669
void StdCmdDockOverlayToggle::activated(int iMsg)
3670
{
3671
    Q_UNUSED(iMsg);
3672
    OverlayManager::instance()->setOverlayMode(OverlayManager::OverlayMode::ToggleActive);
3673
}
3674

3675
//===========================================================================
3676
// Std_DockOverlayToggleTransparent
3677
//===========================================================================
3678

3679
DEF_STD_CMD(StdCmdDockOverlayToggleTransparent)
3680

3681
StdCmdDockOverlayToggleTransparent::StdCmdDockOverlayToggleTransparent()
3682
  :Command("Std_DockOverlayToggleTransparent")
3683
{
3684
    sGroup        = "Standard-View";
3685
    sMenuText     = QT_TR_NOOP("Toggle transparent mode");
3686
    sToolTipText  = QT_TR_NOOP("Toggle transparent mode for the docked window under cursor.\n"
3687
                               "This makes the docked window stay transparent at all times.");
3688
    sWhatsThis    = "Std_DockOverlayToggleTransparent";
3689
    sStatusTip    = sToolTipText;
3690
    sAccel        = "SHIFT+F3";
3691
    eType         = 0;
3692
}
3693

3694
void StdCmdDockOverlayToggleTransparent::activated(int iMsg)
3695
{
3696
    Q_UNUSED(iMsg);
3697
    OverlayManager::instance()->setOverlayMode(OverlayManager::OverlayMode::ToggleTransparent);
3698
}
3699

3700
//===========================================================================
3701
// Std_DockOverlayToggleLeft
3702
//===========================================================================
3703

3704
DEF_STD_CMD(StdCmdDockOverlayToggleLeft)
3705

3706
StdCmdDockOverlayToggleLeft::StdCmdDockOverlayToggleLeft()
3707
  :Command("Std_DockOverlayToggleLeft")
3708
{
3709
    sGroup        = "Standard-View";
3710
    sMenuText     = QT_TR_NOOP("Toggle left");
3711
    sToolTipText  = QT_TR_NOOP("Show/hide left overlay panel");
3712
    sWhatsThis    = "Std_DockOverlayToggleLeft";
3713
    sStatusTip    = sToolTipText;
3714
    sAccel        = "Ctrl+Left";
3715
    sPixmap       = "qss:overlay/icons/close.svg";
3716
    eType         = 0;
3717
}
3718

3719
void StdCmdDockOverlayToggleLeft::activated(int iMsg)
3720
{
3721
    Q_UNUSED(iMsg);
3722
    OverlayManager::instance()->setOverlayMode(OverlayManager::OverlayMode::ToggleLeft);
3723
}
3724

3725
//===========================================================================
3726
// Std_DockOverlayToggleRight
3727
//===========================================================================
3728

3729
DEF_STD_CMD(StdCmdDockOverlayToggleRight)
3730

3731
StdCmdDockOverlayToggleRight::StdCmdDockOverlayToggleRight()
3732
  :Command("Std_DockOverlayToggleRight")
3733
{
3734
    sGroup        = "Standard-View";
3735
    sMenuText     = QT_TR_NOOP("Toggle right");
3736
    sToolTipText  = QT_TR_NOOP("Show/hide right overlay panel");
3737
    sWhatsThis    = "Std_DockOverlayToggleRight";
3738
    sStatusTip    = sToolTipText;
3739
    sAccel        = "Ctrl+Right";
3740
    sPixmap       = "qss:overlay/icons/close.svg";
3741
    eType         = 0;
3742
}
3743

3744
void StdCmdDockOverlayToggleRight::activated(int iMsg)
3745
{
3746
    Q_UNUSED(iMsg);
3747
    OverlayManager::instance()->setOverlayMode(OverlayManager::OverlayMode::ToggleRight);
3748
}
3749

3750
//===========================================================================
3751
// Std_DockOverlayToggleTop
3752
//===========================================================================
3753

3754
DEF_STD_CMD(StdCmdDockOverlayToggleTop)
3755

3756
StdCmdDockOverlayToggleTop::StdCmdDockOverlayToggleTop()
3757
  :Command("Std_DockOverlayToggleTop")
3758
{
3759
    sGroup        = "Standard-View";
3760
    sMenuText     = QT_TR_NOOP("Toggle top");
3761
    sToolTipText  = QT_TR_NOOP("Show/hide top overlay panel");
3762
    sWhatsThis    = "Std_DockOverlayToggleTop";
3763
    sStatusTip    = sToolTipText;
3764
    sAccel        = "Ctrl+Up";
3765
    sPixmap       = "qss:overlay/icons/close.svg";
3766
    eType         = 0;
3767
}
3768

3769
void StdCmdDockOverlayToggleTop::activated(int iMsg)
3770
{
3771
    Q_UNUSED(iMsg);
3772
    OverlayManager::instance()->setOverlayMode(OverlayManager::OverlayMode::ToggleTop);
3773
}
3774

3775
//===========================================================================
3776
// Std_DockOverlayToggleBottom
3777
//===========================================================================
3778

3779
DEF_STD_CMD(StdCmdDockOverlayToggleBottom)
3780

3781
StdCmdDockOverlayToggleBottom::StdCmdDockOverlayToggleBottom()
3782
  :Command("Std_DockOverlayToggleBottom")
3783
{
3784
    sGroup        = "Standard-View";
3785
    sMenuText     = QT_TR_NOOP("Toggle bottom");
3786
    sToolTipText  = QT_TR_NOOP("Show/hide bottom overlay panel");
3787
    sWhatsThis    = "Std_DockOverlayToggleBottom";
3788
    sStatusTip    = sToolTipText;
3789
    sAccel        = "Ctrl+Down";
3790
    sPixmap       = "qss:overlay/icons/close.svg";
3791
    eType         = 0;
3792
}
3793

3794
void StdCmdDockOverlayToggleBottom::activated(int iMsg)
3795
{
3796
    Q_UNUSED(iMsg);
3797
    OverlayManager::instance()->setOverlayMode(OverlayManager::OverlayMode::ToggleBottom);
3798
}
3799

3800
//===========================================================================
3801
// Std_DockOverlayMouseTransparent
3802
//===========================================================================
3803

3804
DEF_STD_CMD_AC(StdCmdDockOverlayMouseTransparent)
3805

3806
StdCmdDockOverlayMouseTransparent::StdCmdDockOverlayMouseTransparent()
3807
  :Command("Std_DockOverlayMouseTransparent")
3808
{
3809
  sGroup        = "View";
3810
  sMenuText     = QT_TR_NOOP("Bypass mouse events in docked overlay windows");
3811
  sToolTipText  = QT_TR_NOOP("Bypass all mouse events in docked overlay windows");
3812
  sWhatsThis    = "Std_DockOverlayMouseTransparent";
3813
  sStatusTip    = sToolTipText;
3814
  sAccel        = "T, T";
3815
  eType         = NoTransaction;
3816
}
3817

3818
void StdCmdDockOverlayMouseTransparent::activated(int iMsg)
3819
{
3820
    (void)iMsg;
3821
    bool checked = !OverlayManager::instance()->isMouseTransparent();
3822
    OverlayManager::instance()->setMouseTransparent(checked);
3823
    if(_pcAction)
3824
        _pcAction->setChecked(checked,true);
3825
}
3826

3827
Action * StdCmdDockOverlayMouseTransparent::createAction(void) {
3828
    Action *pcAction = Command::createAction();
3829
    pcAction->setCheckable(true);
3830
    pcAction->setIcon(QIcon());
3831
    _pcAction = pcAction;
3832
    isActive();
3833
    return pcAction;
3834
}
3835

3836
bool StdCmdDockOverlayMouseTransparent::isActive() {
3837
    bool checked = OverlayManager::instance()->isMouseTransparent();
3838
    if(_pcAction && _pcAction->isChecked()!=checked)
3839
        _pcAction->setChecked(checked,true);
3840
    return true;
3841
}
3842

3843
// ============================================================================
3844

3845
class StdCmdDockOverlay : public GroupCommand
3846
{
3847
public:
3848
    StdCmdDockOverlay()
3849
        :GroupCommand("Std_DockOverlay")
3850
    {
3851
        sGroup        = "View";
3852
        sMenuText     = QT_TR_NOOP("Dock window overlay");
3853
        sToolTipText  = QT_TR_NOOP("Setting docked window overlay mode");
3854
        sWhatsThis    = "Std_DockOverlay";
3855
        sStatusTip    = sToolTipText;
3856
        eType         = 0;
3857
        bCanLog       = false;
3858

3859
        addCommand(new StdCmdDockOverlayAll());
3860
        addCommand(new StdCmdDockOverlayTransparentAll());
3861
        addCommand();
3862
        addCommand(new StdCmdDockOverlayToggle());
3863
        addCommand(new StdCmdDockOverlayToggleTransparent());
3864
        addCommand();
3865
        addCommand(new StdCmdDockOverlayMouseTransparent());
3866
        addCommand();
3867
        addCommand(new StdCmdDockOverlayToggleLeft());
3868
        addCommand(new StdCmdDockOverlayToggleRight());
3869
        addCommand(new StdCmdDockOverlayToggleTop());
3870
        addCommand(new StdCmdDockOverlayToggleBottom());
3871
    };
3872
    virtual const char* className() const {return "StdCmdDockOverlay";}
3873
};
3874

3875
//===========================================================================
3876
// Std_StoreWorkingView
3877
//===========================================================================
3878
DEF_STD_CMD_A(StdStoreWorkingView)
3879

3880
StdStoreWorkingView::StdStoreWorkingView()
3881
  : Command("Std_StoreWorkingView")
3882
{
3883
    sGroup        = "Standard-View";
3884
    sMenuText     = QT_TR_NOOP("Store working view");
3885
    sToolTipText  = QT_TR_NOOP("Store a document-specific temporary working view");
3886
    sStatusTip    = QT_TR_NOOP("Store a document-specific temporary working view");
3887
    sWhatsThis    = "Std_StoreWorkingView";
3888
    sAccel        = "Shift+End";
3889
    eType         = NoTransaction;
3890
}
3891

3892
void StdStoreWorkingView::activated(int iMsg)
3893
{
3894
    Q_UNUSED(iMsg);
3895
    if (auto view = dynamic_cast<Gui::View3DInventor*>(Gui::getMainWindow()->activeWindow())) {
3896
        view->getViewer()->saveHomePosition();
3897
    }
3898
}
3899

3900
bool StdStoreWorkingView::isActive()
3901
{
3902
    return dynamic_cast<Gui::View3DInventor*>(Gui::getMainWindow()->activeWindow());
3903
}
3904

3905
//===========================================================================
3906
// Std_RecallWorkingView
3907
//===========================================================================
3908
DEF_STD_CMD_A(StdRecallWorkingView)
3909

3910
StdRecallWorkingView::StdRecallWorkingView()
3911
  : Command("Std_RecallWorkingView")
3912
{
3913
    sGroup        = "Standard-View";
3914
    sMenuText     = QT_TR_NOOP("Recall working view");
3915
    sToolTipText  = QT_TR_NOOP("Recall previously stored temporary working view");
3916
    sStatusTip    = QT_TR_NOOP("Recall previously stored temporary working view");
3917
    sWhatsThis    = "Std_RecallWorkingView";
3918
    sAccel        = "End";
3919
    eType         = NoTransaction;
3920
}
3921

3922
void StdRecallWorkingView::activated(int iMsg)
3923
{
3924
    Q_UNUSED(iMsg);
3925
    if (auto view = dynamic_cast<Gui::View3DInventor*>(Gui::getMainWindow()->activeWindow())) {
3926
        if (view->getViewer()->hasHomePosition())
3927
            view->getViewer()->resetToHomePosition();
3928
    }
3929
}
3930

3931
bool StdRecallWorkingView::isActive()
3932
{
3933
    auto view = dynamic_cast<Gui::View3DInventor*>(Gui::getMainWindow()->activeWindow());
3934
    return view && view->getViewer()->hasHomePosition();
3935
}
3936

3937
//===========================================================================
3938
// Std_AlignToSelection
3939
//===========================================================================
3940
DEF_STD_CMD_A(StdCmdAlignToSelection)
3941

3942
StdCmdAlignToSelection::StdCmdAlignToSelection()
3943
  : Command("Std_AlignToSelection")
3944
{
3945
    sGroup        = "View";
3946
    sMenuText     = QT_TR_NOOP("Align to selection");
3947
    sToolTipText  = QT_TR_NOOP("Align the view with the selection");
3948
    sWhatsThis    = "Std_AlignToSelection";
3949
    sPixmap       = "align-to-selection";
3950
    eType         = Alter3DView;
3951
}
3952

3953
void StdCmdAlignToSelection::activated(int iMsg)
3954
{
3955
    Q_UNUSED(iMsg);
3956
    doCommand(Command::Gui,"Gui.SendMsgToActiveView(\"AlignToSelection\")");
3957
}
3958

3959
bool StdCmdAlignToSelection::isActive()
3960
{
3961
    return getGuiApplication()->sendHasMsgToActiveView("AlignToSelection");
3962
}
3963

3964
//===========================================================================
3965
// Instantiation
3966
//===========================================================================
3967

3968

3969
namespace Gui {
3970

3971
void CreateViewStdCommands()
3972
{
3973
    // NOLINTBEGIN
3974
    CommandManager &rcCmdMgr = Application::Instance->commandManager();
3975

3976
    // views
3977
    rcCmdMgr.addCommand(new StdCmdViewBottom());
3978
    rcCmdMgr.addCommand(new StdCmdViewHome());
3979
    rcCmdMgr.addCommand(new StdCmdViewFront());
3980
    rcCmdMgr.addCommand(new StdCmdViewLeft());
3981
    rcCmdMgr.addCommand(new StdCmdViewRear());
3982
    rcCmdMgr.addCommand(new StdCmdViewRight());
3983
    rcCmdMgr.addCommand(new StdCmdViewTop());
3984
    rcCmdMgr.addCommand(new StdCmdViewIsometric());
3985
    rcCmdMgr.addCommand(new StdCmdViewDimetric());
3986
    rcCmdMgr.addCommand(new StdCmdViewTrimetric());
3987
    rcCmdMgr.addCommand(new StdCmdViewFitAll());
3988
    rcCmdMgr.addCommand(new StdCmdViewVR());
3989
    rcCmdMgr.addCommand(new StdCmdViewFitSelection());
3990
    rcCmdMgr.addCommand(new StdCmdViewRotateLeft());
3991
    rcCmdMgr.addCommand(new StdCmdViewRotateRight());
3992
    rcCmdMgr.addCommand(new StdStoreWorkingView());
3993
    rcCmdMgr.addCommand(new StdRecallWorkingView());
3994
    rcCmdMgr.addCommand(new StdCmdViewGroup());
3995
    rcCmdMgr.addCommand(new StdCmdAlignToSelection());
3996

3997
    rcCmdMgr.addCommand(new StdCmdViewExample1());
3998
    rcCmdMgr.addCommand(new StdCmdViewExample2());
3999
    rcCmdMgr.addCommand(new StdCmdViewExample3());
4000

4001
    rcCmdMgr.addCommand(new StdCmdViewIvStereoQuadBuff());
4002
    rcCmdMgr.addCommand(new StdCmdViewIvStereoRedGreen());
4003
    rcCmdMgr.addCommand(new StdCmdViewIvStereoInterleavedColumns());
4004
    rcCmdMgr.addCommand(new StdCmdViewIvStereoInterleavedRows());
4005
    rcCmdMgr.addCommand(new StdCmdViewIvStereoOff());
4006

4007
    rcCmdMgr.addCommand(new StdCmdViewIvIssueCamPos());
4008

4009
    rcCmdMgr.addCommand(new StdCmdViewCreate());
4010
    rcCmdMgr.addCommand(new StdViewScreenShot());
4011
    rcCmdMgr.addCommand(new StdViewLoadImage());
4012
    rcCmdMgr.addCommand(new StdMainFullscreen());
4013
    rcCmdMgr.addCommand(new StdViewDockUndockFullscreen());
4014
    rcCmdMgr.addCommand(new StdCmdToggleVisibility());
4015
    rcCmdMgr.addCommand(new StdCmdToggleTransparency());
4016
    rcCmdMgr.addCommand(new StdCmdToggleSelectability());
4017
    rcCmdMgr.addCommand(new StdCmdShowSelection());
4018
    rcCmdMgr.addCommand(new StdCmdHideSelection());
4019
    rcCmdMgr.addCommand(new StdCmdSelectVisibleObjects());
4020
    rcCmdMgr.addCommand(new StdCmdToggleObjects());
4021
    rcCmdMgr.addCommand(new StdCmdShowObjects());
4022
    rcCmdMgr.addCommand(new StdCmdHideObjects());
4023
    rcCmdMgr.addCommand(new StdOrthographicCamera());
4024
    rcCmdMgr.addCommand(new StdPerspectiveCamera());
4025
    rcCmdMgr.addCommand(new StdCmdToggleClipPlane());
4026
    rcCmdMgr.addCommand(new StdCmdDrawStyle());
4027
    rcCmdMgr.addCommand(new StdCmdViewSaveCamera());
4028
    rcCmdMgr.addCommand(new StdCmdViewRestoreCamera());
4029
    rcCmdMgr.addCommand(new StdCmdFreezeViews());
4030
    rcCmdMgr.addCommand(new StdViewZoomIn());
4031
    rcCmdMgr.addCommand(new StdViewZoomOut());
4032
    rcCmdMgr.addCommand(new StdViewBoxZoom());
4033
    rcCmdMgr.addCommand(new StdBoxSelection());
4034
    rcCmdMgr.addCommand(new StdBoxElementSelection());
4035
    rcCmdMgr.addCommand(new StdCmdTreeExpand());
4036
    rcCmdMgr.addCommand(new StdCmdTreeCollapse());
4037
    rcCmdMgr.addCommand(new StdCmdTreeSelectAllInstances());
4038
    rcCmdMgr.addCommand(new StdCmdSceneInspector());
4039
    rcCmdMgr.addCommand(new StdCmdTextureMapping());
4040
    rcCmdMgr.addCommand(new StdCmdDemoMode());
4041
    rcCmdMgr.addCommand(new StdCmdToggleNavigation());
4042
    rcCmdMgr.addCommand(new StdCmdAxisCross());
4043
    rcCmdMgr.addCommand(new StdCmdSelBoundingBox());
4044
    rcCmdMgr.addCommand(new StdCmdTreeViewActions());
4045
    rcCmdMgr.addCommand(new StdCmdDockOverlay());
4046

4047
    auto hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
4048
    if(hGrp->GetASCII("GestureRollFwdCommand").empty())
4049
        hGrp->SetASCII("GestureRollFwdCommand","Std_SelForward");
4050
    if(hGrp->GetASCII("GestureRollBackCommand").empty())
4051
        hGrp->SetASCII("GestureRollBackCommand","Std_SelBack");
4052
    // NOLINTEND
4053
}
4054

4055
} // namespace Gui
4056

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

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

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

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