24
#include "PreCompiled.h"
26
# include <Inventor/nodes/SoCamera.h>
27
# include <QApplication>
30
# include <QMessageBox>
31
# include <QTextStream>
32
# include <QTreeWidgetItem>
35
#include <boost/regex.hpp>
36
#include <boost/algorithm/string/replace.hpp>
38
#include <App/AutoTransaction.h>
39
#include <App/Document.h>
40
#include <App/DocumentObject.h>
41
#include <App/Expression.h>
42
#include <App/GeoFeature.h>
43
#include <Base/Exception.h>
44
#include <Base/FileInfo.h>
45
#include <Base/Stream.h>
46
#include <Base/Tools.h>
49
#include "Application.h"
50
#include "BitmapFactory.h"
53
#include "DockWindowManager.h"
54
#include "FileDialog.h"
55
#include "MainWindow.h"
57
#include "DlgObjectSelection.h"
58
#include "DlgProjectInformationImp.h"
59
#include "DlgProjectUtility.h"
60
#include "GraphvizView.h"
61
#include "ManualAlignment.h"
62
#include "MergeDocuments.h"
63
#include "NavigationStyle.h"
66
#include "View3DInventor.h"
67
#include "View3DInventorViewer.h"
68
#include "ViewProvider.h"
69
#include "WaitCursor.h"
71
FC_LOG_LEVEL_INIT("Command", false)
80
DEF_STD_CMD(StdCmdOpen)
82
StdCmdOpen::StdCmdOpen()
87
sMenuText = QT_TR_NOOP("&Open...");
88
sToolTipText = QT_TR_NOOP("Open a document or import files");
89
sWhatsThis = "Std_Open";
90
sStatusTip = QT_TR_NOOP("Open a document or import files");
91
sPixmap = "document-open";
92
sAccel = keySequenceToAccel(QKeySequence::Open);
93
eType = NoTransaction;
96
void StdCmdOpen::activated(int iMsg)
102
const char* supported = QT_TR_NOOP("Supported formats");
103
const char* allFiles = QT_TR_NOOP("All files (*.*)");
104
formatList = QObject::tr(supported);
105
formatList += QLatin1String(" (");
107
std::vector<std::string> filetypes = App::GetApplication().getImportTypes();
108
std::vector<std::string>::iterator it;
110
it = std::find(filetypes.begin(), filetypes.end(), "FCStd");
111
if (it != filetypes.end()) {
113
filetypes.insert(filetypes.begin(), "FCStd");
115
for (it=filetypes.begin();it != filetypes.end();++it) {
116
formatList += QLatin1String(" *.");
117
formatList += QLatin1String(it->c_str());
120
formatList += QLatin1String(");;");
122
std::map<std::string, std::string> FilterList = App::GetApplication().getImportFilters();
123
std::map<std::string, std::string>::iterator jt;
125
for (jt=FilterList.begin();jt != FilterList.end();++jt) {
126
if (jt->first.find("*.FCStd") != std::string::npos) {
127
formatList += QLatin1String(jt->first.c_str());
128
formatList += QLatin1String(";;");
129
FilterList.erase(jt);
133
for (jt=FilterList.begin();jt != FilterList.end();++jt) {
134
formatList += QLatin1String(jt->first.c_str());
135
formatList += QLatin1String(";;");
137
formatList += QObject::tr(allFiles);
139
QString selectedFilter;
140
QStringList fileList = FileDialog::getOpenFileNames(getMainWindow(),
141
QObject::tr("Open document"), QString(), formatList, &selectedFilter);
142
if (fileList.isEmpty())
146
SelectModule::Dict dict = SelectModule::importHandler(fileList, selectedFilter);
147
if (dict.isEmpty()) {
148
QMessageBox::critical(getMainWindow(),
149
qApp->translate("StdCmdOpen", "Cannot open file"),
150
qApp->translate("StdCmdOpen", "Loading the file %1 is not supported").arg(fileList.front()));
153
for (SelectModule::Dict::iterator it = dict.begin(); it != dict.end(); ++it) {
156
getGuiApplication()->setStatus(Gui::Application::UserInitiatedOpenDocument, true);
158
getGuiApplication()->open(it.key().toUtf8(), it.value().toLatin1());
160
getGuiApplication()->setStatus(Gui::Application::UserInitiatedOpenDocument, false);
162
App::Document *doc = App::GetApplication().getActiveDocument();
164
if(doc && doc->testStatus(App::Document::PartialRestore)) {
165
QMessageBox::critical(getMainWindow(), QObject::tr("Error"),
166
QObject::tr("There were errors while loading the file. Some data might have been modified or not recovered at all. Look in the report view for more specific information about the objects involved."));
169
if(doc && doc->testStatus(App::Document::RestoreError)) {
170
QMessageBox::critical(getMainWindow(), QObject::tr("Error"),
171
QObject::tr("There were serious errors while loading the file. Some data might have been modified or not recovered at all. Saving the project will most likely result in loss of data."));
181
DEF_STD_CMD_A(StdCmdImport)
183
StdCmdImport::StdCmdImport()
184
: Command("Std_Import")
188
sMenuText = QT_TR_NOOP("&Import...");
189
sToolTipText = QT_TR_NOOP("Import a file in the active document");
190
sWhatsThis = "Std_Import";
191
sStatusTip = QT_TR_NOOP("Import a file in the active document");
192
sPixmap = "Std_Import";
196
void StdCmdImport::activated(int iMsg)
202
const char* supported = QT_TR_NOOP("Supported formats");
203
const char* allFiles = QT_TR_NOOP("All files (*.*)");
204
formatList = QObject::tr(supported);
205
formatList += QLatin1String(" (");
207
std::vector<std::string> filetypes = App::GetApplication().getImportTypes();
208
std::vector<std::string>::const_iterator it;
209
for (it=filetypes.begin();it != filetypes.end();++it) {
210
if (*it != "FCStd") {
212
formatList += QLatin1String(" *.");
213
formatList += QLatin1String(it->c_str());
217
formatList += QLatin1String(");;");
219
std::map<std::string, std::string> FilterList = App::GetApplication().getImportFilters();
220
std::map<std::string, std::string>::const_iterator jt;
221
for (jt=FilterList.begin();jt != FilterList.end();++jt) {
223
if (jt->first.find("(*.FCStd)") == std::string::npos) {
224
formatList += QLatin1String(jt->first.c_str());
225
formatList += QLatin1String(";;");
228
formatList += QObject::tr(allFiles);
230
Base::Reference<ParameterGrp> hPath = App::GetApplication().GetUserParameter().GetGroup("BaseApp")
231
->GetGroup("Preferences")->GetGroup("General");
232
QString selectedFilter = QString::fromStdString(hPath->GetASCII("FileImportFilter"));
233
QStringList fileList = FileDialog::getOpenFileNames(getMainWindow(),
234
QObject::tr("Import file"), QString(), formatList, &selectedFilter);
235
if (!fileList.isEmpty()) {
236
hPath->SetASCII("FileImportFilter", selectedFilter.toLatin1().constData());
237
SelectModule::Dict dict = SelectModule::importHandler(fileList, selectedFilter);
239
bool emptyDoc = (getActiveGuiDocument()->getDocument()->countObjects() == 0);
241
for (SelectModule::Dict::iterator it = dict.begin(); it != dict.end(); ++it) {
242
getGuiApplication()->importFrom(it.key().toUtf8(),
243
getActiveGuiDocument()->getDocument()->getName(),
244
it.value().toLatin1());
249
std::list<Gui::MDIView*> views = getActiveGuiDocument()->getMDIViewsOfType(Gui::View3DInventor::getClassTypeId());
250
for (const auto & view : views) {
257
bool StdCmdImport::isActive()
259
return (getActiveGuiDocument() ? true : false);
267
DEF_STD_CMD_A(StdCmdExport)
269
StdCmdExport::StdCmdExport()
270
: Command("Std_Export")
274
sMenuText = QT_TR_NOOP("&Export...");
275
sToolTipText = QT_TR_NOOP("Export an object in the active document");
276
sWhatsThis = "Std_Export";
277
sStatusTip = QT_TR_NOOP("Export an object in the active document");
280
sPixmap = "Std_Export";
300
QString createDefaultExportBasename()
302
QString defaultFilename;
304
auto selection = Gui::Selection().getObjectsOfType(App::DocumentObject::getClassTypeId());
305
QString exportFormatString;
306
if (selection.size() == 1) {
307
exportFormatString = QString::fromStdString (App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/General")->
308
GetASCII("ExportDefaultFilenameSingle", "%F-%P-"));
311
exportFormatString = QString::fromStdString (App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/General")->
312
GetASCII("ExportDefaultFilenameMultiple", "%F"));
318
QString docFilename = QString::fromUtf8(App::GetApplication().getActiveDocument()->getFileName());
319
QFileInfo fi(docFilename);
320
QString fcstdBasename = fi.completeBaseName();
321
if (fcstdBasename.isEmpty())
322
fcstdBasename = QString::fromStdString(App::GetApplication().getActiveDocument()->Label.getStrValue());
325
QStringList objectLabels;
326
for (const auto& object : selection)
327
objectLabels.push_back(QString::fromStdString(object->Label.getStrValue()));
330
QStringList parentLabels;
331
for (const auto& object : selection) {
332
auto parents = object->getParents();
334
if (!parents.empty())
335
firstParent = QString::fromStdString(parents.front().first->Label.getStrValue());
336
parentLabels.append(firstParent + QString::fromStdString(object->Label.getStrValue()));
340
QDateTime utc = QDateTime(QDateTime::currentDateTimeUtc());
341
QString utcISO8601 = utc.toString(Qt::ISODate);
344
QDateTime local = utc.toLocalTime();
345
QString localISO8601 = local.toString(Qt::ISODate);
348
for (int i = 0; i < exportFormatString.size(); ++i) {
349
auto c = exportFormatString.at(i);
350
if (c != QLatin1Char('%')) {
352
defaultFilename.append(c);
357
if (i < exportFormatString.size() - 1) {
359
auto formatChar = exportFormatString.at(i);
360
QChar separatorChar = QLatin1Char('-');
363
if (formatChar == QLatin1Char('L') ||
364
formatChar == QLatin1Char('P')) {
365
if (i < exportFormatString.size() - 1) {
367
separatorChar = exportFormatString.at(i);
372
if (formatChar == QLatin1Char('F')) {
373
defaultFilename.append(fcstdBasename);
375
else if (formatChar == QLatin1Char('L')) {
376
defaultFilename.append(objectLabels.join(separatorChar));
378
else if (formatChar == QLatin1Char('P')) {
379
defaultFilename.append(parentLabels.join(separatorChar));
381
else if (formatChar == QLatin1Char('U')) {
382
defaultFilename.append(utcISO8601);
384
else if (formatChar == QLatin1Char('D')) {
385
defaultFilename.append(localISO8601);
388
FC_WARN("When parsing default export filename format string, %"
389
<< QString(formatChar).toStdString()
390
<< " is not a known format string.");
397
QString invalidCharacters = QLatin1String("/\\?%*:|\"<>");
398
for (const auto &c : invalidCharacters)
399
defaultFilename.replace(c,QLatin1String("_"));
401
return defaultFilename;
404
void StdCmdExport::activated(int iMsg)
408
static QString lastExportFullPath = QString();
409
static bool lastExportUsedGeneratedFilename = true;
410
static QString lastExportFilterUsed = QString();
412
auto selection = Gui::Selection().getObjectsOfType(App::DocumentObject::getClassTypeId());
413
if (selection.empty()) {
414
QMessageBox::warning(Gui::getMainWindow(),
415
QCoreApplication::translate("StdCmdExport", "No selection"),
416
QCoreApplication::translate("StdCmdExport", "Select the objects to export before choosing Export."));
421
QStringList filterList;
422
std::map<std::string, std::string> filterMap = App::GetApplication().getExportFilters();
423
for (const auto &filter : filterMap) {
425
if (filter.first.find("(*.FCStd)") == std::string::npos)
426
filterList << QString::fromStdString(filter.first);
428
QString formatList = filterList.join(QLatin1String(";;"));
429
Base::Reference<ParameterGrp> hPath =
430
App::GetApplication().GetUserParameter().GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("General");
431
QString selectedFilter = QString::fromStdString(hPath->GetASCII("FileExportFilter"));
432
if (!lastExportFilterUsed.isEmpty())
433
selectedFilter = lastExportFilterUsed;
441
QString defaultFilename = lastExportFullPath;
443
bool filenameWasGenerated = false;
445
if (defaultFilename.isEmpty() || lastExportUsedGeneratedFilename) {
447
QString docFilename = QString::fromUtf8(
448
App::GetApplication().getActiveDocument()->getFileName());
451
QString defaultExportPath;
452
if (!lastExportFullPath.isEmpty()) {
453
QFileInfo fi(lastExportFullPath);
454
defaultExportPath = fi.path();
456
else if (!docFilename.isEmpty()) {
457
QFileInfo fi(docFilename);
458
defaultExportPath = fi.path();
461
defaultExportPath = Gui::FileDialog::getWorkingDirectory();
464
if (lastExportUsedGeneratedFilename ) {
465
defaultFilename = defaultExportPath + QLatin1Char('/') + createDefaultExportBasename();
468
if (!lastExportFullPath.isEmpty()) {
469
QFileInfo lastExportFile(lastExportFullPath);
470
if (!lastExportFile.suffix().isEmpty())
471
defaultFilename += QLatin1String(".") + lastExportFile.suffix();
473
filenameWasGenerated = true;
478
QString fileName = FileDialog::getSaveFileName(getMainWindow(),
479
QObject::tr("Export file"), defaultFilename, formatList, &selectedFilter);
480
if (!fileName.isEmpty()) {
481
hPath->SetASCII("FileExportFilter", selectedFilter.toLatin1().constData());
482
lastExportFilterUsed = selectedFilter;
483
SelectModule::Dict dict = SelectModule::exportHandler(fileName, selectedFilter);
485
for (SelectModule::Dict::iterator it = dict.begin(); it != dict.end(); ++it) {
486
getGuiApplication()->exportTo(it.key().toUtf8(),
487
getActiveGuiDocument()->getDocument()->getName(),
488
it.value().toLatin1());
494
QFileInfo defaultExportFI(defaultFilename);
495
QFileInfo thisExportFI(fileName);
496
if (filenameWasGenerated &&
497
thisExportFI.completeBaseName() == defaultExportFI.completeBaseName())
498
lastExportUsedGeneratedFilename = true;
500
lastExportUsedGeneratedFilename = false;
501
lastExportFullPath = fileName;
505
bool StdCmdExport::isActive()
507
return (getActiveGuiDocument() ? true : false);
514
DEF_STD_CMD_A(StdCmdMergeProjects)
516
StdCmdMergeProjects::StdCmdMergeProjects()
517
: Command("Std_MergeProjects")
521
sMenuText = QT_TR_NOOP("Merge document...");
522
sToolTipText = QT_TR_NOOP("Merge document");
523
sWhatsThis = "Std_MergeProjects";
524
sStatusTip = QT_TR_NOOP("Merge document");
525
sPixmap = "Std_MergeProjects";
528
void StdCmdMergeProjects::activated(int iMsg)
532
QString exe = qApp->applicationName();
533
QString project = FileDialog::getOpenFileName(Gui::getMainWindow(),
534
QString::fromUtf8(QT_TR_NOOP("Merge document")), FileDialog::getWorkingDirectory(),
535
QString::fromUtf8(QT_TR_NOOP("%1 document (*.FCStd)")).arg(exe));
536
if (!project.isEmpty()) {
537
FileDialog::setWorkingDirectory(project);
538
App::Document* doc = App::GetApplication().getActiveDocument();
539
QFileInfo info(QString::fromUtf8(doc->FileName.getValue()));
540
QFileInfo proj(project);
542
QMessageBox::critical(Gui::getMainWindow(),
543
QString::fromUtf8(QT_TR_NOOP("Merge document")),
544
QString::fromUtf8(QT_TR_NOOP("Cannot merge document with itself.")));
548
doc->openTransaction("Merge document");
549
Base::FileInfo fi((const char*)project.toUtf8());
550
Base::ifstream str(fi, std::ios::in | std::ios::binary);
551
MergeDocuments md(doc);
552
md.importObjects(str);
554
doc->commitTransaction();
558
bool StdCmdMergeProjects::isActive()
560
return this->hasActiveDocument();
567
DEF_STD_CMD_A(StdCmdDependencyGraph)
569
StdCmdDependencyGraph::StdCmdDependencyGraph()
570
: Command("Std_DependencyGraph")
574
sMenuText = QT_TR_NOOP("Dependency graph...");
575
sToolTipText = QT_TR_NOOP("Show the dependency graph of the objects in the active document");
576
sStatusTip = QT_TR_NOOP("Show the dependency graph of the objects in the active document");
577
sWhatsThis = "Std_DependencyGraph";
579
sPixmap = "Std_DependencyGraph";
582
void StdCmdDependencyGraph::activated(int iMsg)
585
App::Document* doc = App::GetApplication().getActiveDocument();
586
auto view = new Gui::GraphvizView(*doc);
587
view->setWindowTitle(qApp->translate("Std_DependencyGraph","Dependency graph"));
588
getMainWindow()->addWindow(view);
591
bool StdCmdDependencyGraph::isActive()
593
return (getActiveGuiDocument() ? true : false);
600
DEF_STD_CMD_A(StdCmdExportDependencyGraph)
602
StdCmdExportDependencyGraph::StdCmdExportDependencyGraph()
603
: Command("Std_ExportDependencyGraph")
606
sMenuText = QT_TR_NOOP("Export dependency graph...");
607
sToolTipText = QT_TR_NOOP("Export the dependency graph to a file");
608
sStatusTip = QT_TR_NOOP("Export the dependency graph to a file");
609
sWhatsThis = "Std_ExportDependencyGraph";
614
void StdCmdExportDependencyGraph::activated(int iMsg)
617
App::Document* doc = App::GetApplication().getActiveDocument();
618
QString format = QString::fromLatin1("%1 (*.gv)").arg(Gui::GraphvizView::tr("Graphviz format"));
619
QString fn = Gui::FileDialog::getSaveFileName(Gui::getMainWindow(), Gui::GraphvizView::tr("Export graph"), QString(), format);
622
if (file.open(QFile::WriteOnly)) {
623
std::stringstream str;
624
doc->exportGraphviz(str);
625
QByteArray buffer = QByteArray::fromStdString(str.str());
632
bool StdCmdExportDependencyGraph::isActive()
634
return (getActiveGuiDocument() ? true : false);
641
DEF_STD_CMD(StdCmdNew)
643
StdCmdNew::StdCmdNew()
647
sMenuText = QT_TR_NOOP("&New");
648
sToolTipText = QT_TR_NOOP("Create a new empty document");
649
sWhatsThis = "Std_New";
650
sStatusTip = QT_TR_NOOP("Create a new empty document");
651
sPixmap = "document-new";
652
sAccel = keySequenceToAccel(QKeySequence::New);
655
void StdCmdNew::activated(int iMsg)
659
cmd = QString::fromLatin1("App.newDocument()");
660
runCommand(Command::Doc,cmd.toUtf8());
661
doCommand(Command::Gui,"Gui.activeDocument().activeView().viewDefaultOrientation()");
663
ParameterGrp::handle hViewGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
664
if (hViewGrp->GetBool("ShowAxisCross"))
665
doCommand(Command::Gui,"Gui.ActiveDocument.ActiveView.setAxisCross(True)");
671
DEF_STD_CMD_A(StdCmdSave)
673
StdCmdSave::StdCmdSave()
677
sMenuText = QT_TR_NOOP("&Save");
678
sToolTipText = QT_TR_NOOP("Save the active document");
679
sWhatsThis = "Std_Save";
680
sStatusTip = QT_TR_NOOP("Save the active document");
681
sPixmap = "document-save";
682
sAccel = keySequenceToAccel(QKeySequence::Save);
686
void StdCmdSave::activated(int iMsg)
689
doCommand(Command::Gui,"Gui.SendMsgToActiveView(\"Save\")");
692
bool StdCmdSave::isActive()
694
return getGuiApplication()->sendHasMsgToActiveView("Save");
700
DEF_STD_CMD_A(StdCmdSaveAs)
702
StdCmdSaveAs::StdCmdSaveAs()
703
:Command("Std_SaveAs")
706
sMenuText = QT_TR_NOOP("Save &As...");
707
sToolTipText = QT_TR_NOOP("Save the active document under a new file name");
708
sWhatsThis = "Std_SaveAs";
709
sStatusTip = QT_TR_NOOP("Save the active document under a new file name");
710
sPixmap = "document-save-as";
711
sAccel = keySequenceToAccel(QKeySequence::SaveAs);
715
void StdCmdSaveAs::activated(int iMsg)
718
doCommand(Command::Gui,"Gui.SendMsgToActiveView(\"SaveAs\")");
721
bool StdCmdSaveAs::isActive()
723
return getGuiApplication()->sendHasMsgToActiveView("SaveAs");
729
DEF_STD_CMD_A(StdCmdSaveCopy)
731
StdCmdSaveCopy::StdCmdSaveCopy()
732
:Command("Std_SaveCopy")
735
sMenuText = QT_TR_NOOP("Save a &Copy...");
736
sToolTipText = QT_TR_NOOP("Save a copy of the active document under a new file name");
737
sWhatsThis = "Std_SaveCopy";
738
sStatusTip = QT_TR_NOOP("Save a copy of the active document under a new file name");
739
sPixmap = "Std_SaveCopy";
742
void StdCmdSaveCopy::activated(int iMsg)
745
doCommand(Command::Gui,"Gui.SendMsgToActiveView(\"SaveCopy\")");
748
bool StdCmdSaveCopy::isActive()
750
return ( getActiveGuiDocument() ? true : false );
756
DEF_STD_CMD_A(StdCmdSaveAll)
758
StdCmdSaveAll::StdCmdSaveAll()
759
:Command("Std_SaveAll")
762
sMenuText = QT_TR_NOOP("Save All");
763
sToolTipText = QT_TR_NOOP("Save all opened document");
764
sWhatsThis = "Std_SaveAll";
765
sStatusTip = QT_TR_NOOP("Save all opened document");
766
sPixmap = "Std_SaveAll";
769
void StdCmdSaveAll::activated(int iMsg)
772
Gui::Document::saveAll();
775
bool StdCmdSaveAll::isActive()
777
return ( getActiveGuiDocument() ? true : false );
784
DEF_STD_CMD_A(StdCmdRevert)
786
StdCmdRevert::StdCmdRevert()
787
:Command("Std_Revert")
790
sMenuText = QT_TR_NOOP("Revert");
791
sToolTipText = QT_TR_NOOP("Reverts to the saved version of this file");
792
sWhatsThis = "Std_Revert";
793
sStatusTip = QT_TR_NOOP("Reverts to the saved version of this file");
794
sPixmap = "Std_Revert";
795
eType = NoTransaction;
798
void StdCmdRevert::activated(int iMsg)
801
QMessageBox msgBox(Gui::getMainWindow());
802
msgBox.setIcon(QMessageBox::Question);
803
msgBox.setWindowTitle(qApp->translate("Std_Revert","Revert document"));
804
msgBox.setText(qApp->translate("Std_Revert","This will discard all the changes since last file save."));
805
msgBox.setInformativeText(qApp->translate("Std_Revert","Do you want to continue?"));
806
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
807
msgBox.setDefaultButton(QMessageBox::No);
808
int ret = msgBox.exec();
809
if (ret == QMessageBox::Yes)
810
doCommand(Command::App,"App.ActiveDocument.restore()");
813
bool StdCmdRevert::isActive()
815
return ( getActiveGuiDocument() ? true : false );
822
DEF_STD_CMD_A(StdCmdProjectInfo)
824
StdCmdProjectInfo::StdCmdProjectInfo()
825
:Command("Std_ProjectInfo")
829
sMenuText = QT_TR_NOOP("Document i&nformation...");
830
sToolTipText = QT_TR_NOOP("Show details of the currently active document");
831
sWhatsThis = "Std_ProjectInfo";
832
sStatusTip = QT_TR_NOOP("Show details of the currently active document");
833
sPixmap = "document-properties";
836
void StdCmdProjectInfo::activated(int iMsg)
839
Gui::Dialog::DlgProjectInformationImp dlg(getActiveGuiDocument()->getDocument(), getMainWindow());
843
bool StdCmdProjectInfo::isActive()
845
return ( getActiveGuiDocument() ? true : false );
852
DEF_STD_CMD_A(StdCmdProjectUtil)
854
StdCmdProjectUtil::StdCmdProjectUtil()
855
:Command("Std_ProjectUtil")
859
sWhatsThis = "Std_ProjectUtil";
860
sMenuText = QT_TR_NOOP("Document utility...");
861
sToolTipText = QT_TR_NOOP("Utility to extract or create document files");
862
sStatusTip = QT_TR_NOOP("Utility to extract or create document files");
863
sPixmap = "Std_ProjectUtil";
866
void StdCmdProjectUtil::activated(int iMsg)
869
Gui::Dialog::DlgProjectUtility dlg(getMainWindow());
873
bool StdCmdProjectUtil::isActive()
881
DEF_STD_CMD_A(StdCmdPrint)
883
StdCmdPrint::StdCmdPrint()
884
:Command("Std_Print")
887
sMenuText = QT_TR_NOOP("&Print...");
888
sToolTipText = QT_TR_NOOP("Print the document");
889
sWhatsThis = "Std_Print";
890
sStatusTip = QT_TR_NOOP("Print the document");
891
sPixmap = "document-print";
892
sAccel = keySequenceToAccel(QKeySequence::Print);
896
void StdCmdPrint::activated(int iMsg)
899
if (getMainWindow()->activeWindow()) {
900
getMainWindow()->showMessage(QObject::tr("Printing..."));
901
getMainWindow()->activeWindow()->print();
905
bool StdCmdPrint::isActive()
907
return getGuiApplication()->sendHasMsgToActiveView("Print");
913
DEF_STD_CMD_A(StdCmdPrintPreview)
915
StdCmdPrintPreview::StdCmdPrintPreview()
916
:Command("Std_PrintPreview")
919
sMenuText = QT_TR_NOOP("&Print preview...");
920
sToolTipText = QT_TR_NOOP("Print the document");
921
sWhatsThis = "Std_PrintPreview";
922
sStatusTip = QT_TR_NOOP("Print preview");
923
sPixmap = "document-print-preview";
927
void StdCmdPrintPreview::activated(int iMsg)
930
if (getMainWindow()->activeWindow()) {
931
getMainWindow()->activeWindow()->printPreview();
935
bool StdCmdPrintPreview::isActive()
937
return getGuiApplication()->sendHasMsgToActiveView("PrintPreview");
943
DEF_STD_CMD_A(StdCmdPrintPdf)
945
StdCmdPrintPdf::StdCmdPrintPdf()
946
:Command("Std_PrintPdf")
949
sMenuText = QT_TR_NOOP("&Export PDF...");
950
sToolTipText = QT_TR_NOOP("Export the document as PDF");
951
sWhatsThis = "Std_PrintPdf";
952
sStatusTip = QT_TR_NOOP("Export the document as PDF");
953
sPixmap = "Std_PrintPdf";
957
void StdCmdPrintPdf::activated(int iMsg)
960
if (getMainWindow()->activeWindow()) {
961
getMainWindow()->showMessage(QObject::tr("Exporting PDF..."));
962
getMainWindow()->activeWindow()->printPdf();
966
bool StdCmdPrintPdf::isActive()
968
return getGuiApplication()->sendHasMsgToActiveView("PrintPdf");
975
DEF_STD_CMD(StdCmdQuit)
977
StdCmdQuit::StdCmdQuit()
981
sMenuText = QT_TR_NOOP("E&xit");
982
sToolTipText = QT_TR_NOOP("Quits the application");
983
sWhatsThis = "Std_Quit";
984
sStatusTip = QT_TR_NOOP("Quits the application");
985
sPixmap = "application-exit";
986
sAccel = keySequenceToAccel(QKeySequence::Quit);
987
eType = NoTransaction;
990
void StdCmdQuit::activated(int iMsg)
994
getMainWindow()->close();
1001
DEF_STD_CMD_AC(StdCmdUndo)
1003
StdCmdUndo::StdCmdUndo()
1004
:Command("Std_Undo")
1007
sMenuText = QT_TR_NOOP("&Undo");
1008
sToolTipText = QT_TR_NOOP("Undo exactly one action");
1009
sWhatsThis = "Std_Undo";
1010
sStatusTip = QT_TR_NOOP("Undo exactly one action");
1011
sPixmap = "edit-undo";
1012
sAccel = keySequenceToAccel(QKeySequence::Undo);
1013
eType = ForEdit|NoTransaction;
1016
void StdCmdUndo::activated(int iMsg)
1020
getGuiApplication()->sendMsgToActiveView("Undo");
1023
bool StdCmdUndo::isActive()
1025
return getGuiApplication()->sendHasMsgToActiveView("Undo");
1028
Action * StdCmdUndo::createAction()
1032
pcAction = new UndoAction(this,getMainWindow());
1033
pcAction->setShortcut(QString::fromLatin1(getAccel()));
1034
applyCommandData(this->className(), pcAction);
1036
pcAction->setIcon(Gui::BitmapFactory().iconFromTheme(getPixmap()));
1045
DEF_STD_CMD_AC(StdCmdRedo)
1047
StdCmdRedo::StdCmdRedo()
1048
:Command("Std_Redo")
1051
sMenuText = QT_TR_NOOP("&Redo");
1052
sToolTipText = QT_TR_NOOP("Redoes a previously undone action");
1053
sWhatsThis = "Std_Redo";
1054
sStatusTip = QT_TR_NOOP("Redoes a previously undone action");
1055
sPixmap = "edit-redo";
1056
sAccel = keySequenceToAccel(QKeySequence::Redo);
1057
eType = ForEdit|NoTransaction;
1060
void StdCmdRedo::activated(int iMsg)
1064
getGuiApplication()->sendMsgToActiveView("Redo");
1067
bool StdCmdRedo::isActive()
1069
return getGuiApplication()->sendHasMsgToActiveView("Redo");
1072
Action * StdCmdRedo::createAction()
1076
pcAction = new RedoAction(this,getMainWindow());
1077
pcAction->setShortcut(QString::fromLatin1(getAccel()));
1078
applyCommandData(this->className(), pcAction);
1080
pcAction->setIcon(Gui::BitmapFactory().iconFromTheme(getPixmap()));
1088
DEF_STD_CMD_A(StdCmdCut)
1090
StdCmdCut::StdCmdCut()
1091
: Command("Std_Cut")
1094
sMenuText = QT_TR_NOOP("&Cut");
1095
sToolTipText = QT_TR_NOOP("Cut out");
1096
sWhatsThis = "Std_Cut";
1097
sStatusTip = QT_TR_NOOP("Cut out");
1098
sPixmap = "edit-cut";
1099
sAccel = keySequenceToAccel(QKeySequence::Cut);
1102
void StdCmdCut::activated(int iMsg)
1105
getGuiApplication()->sendMsgToActiveView("Cut");
1108
bool StdCmdCut::isActive()
1110
return getGuiApplication()->sendHasMsgToActiveView("Cut");
1116
DEF_STD_CMD_A(StdCmdCopy)
1118
StdCmdCopy::StdCmdCopy()
1119
: Command("Std_Copy")
1122
sMenuText = QT_TR_NOOP("C&opy");
1123
sToolTipText = QT_TR_NOOP("Copy operation");
1124
sWhatsThis = "Std_Copy";
1125
sStatusTip = QT_TR_NOOP("Copy operation");
1126
sPixmap = "edit-copy";
1127
sAccel = keySequenceToAccel(QKeySequence::Copy);
1130
void StdCmdCopy::activated(int iMsg)
1133
bool done = getGuiApplication()->sendMsgToFocusView("Copy");
1135
QMimeData * mimeData = getMainWindow()->createMimeDataFromSelection();
1136
QClipboard* cb = QApplication::clipboard();
1137
cb->setMimeData(mimeData);
1141
bool StdCmdCopy::isActive()
1143
if (getGuiApplication()->sendHasMsgToFocusView("Copy"))
1145
return Selection().hasSelection();
1151
DEF_STD_CMD_A(StdCmdPaste)
1153
StdCmdPaste::StdCmdPaste()
1154
: Command("Std_Paste")
1157
sMenuText = QT_TR_NOOP("&Paste");
1158
sToolTipText = QT_TR_NOOP("Paste operation");
1159
sWhatsThis = "Std_Paste";
1160
sStatusTip = QT_TR_NOOP("Paste operation");
1161
sPixmap = "edit-paste";
1162
sAccel = keySequenceToAccel(QKeySequence::Paste);
1165
void StdCmdPaste::activated(int iMsg)
1168
bool done = getGuiApplication()->sendMsgToFocusView("Paste");
1170
QClipboard* cb = QApplication::clipboard();
1171
const QMimeData* mimeData = cb->mimeData();
1174
getMainWindow()->insertFromMimeData(mimeData);
1179
bool StdCmdPaste::isActive()
1181
if (getGuiApplication()->sendHasMsgToFocusView("Paste"))
1183
QClipboard* cb = QApplication::clipboard();
1184
const QMimeData* mime = cb->mimeData();
1187
return getMainWindow()->canInsertFromMimeData(mime);
1190
DEF_STD_CMD_A(StdCmdDuplicateSelection)
1192
StdCmdDuplicateSelection::StdCmdDuplicateSelection()
1193
:Command("Std_DuplicateSelection")
1195
sAppModule = "Edit";
1197
sMenuText = QT_TR_NOOP("Duplicate selection");
1198
sToolTipText = QT_TR_NOOP("Put duplicates of the selected objects to the active document");
1199
sWhatsThis = "Std_DuplicateSelection";
1200
sStatusTip = QT_TR_NOOP("Put duplicates of the selected objects to the active document");
1201
sPixmap = "Std_DuplicateSelection";
1204
void StdCmdDuplicateSelection::activated(int iMsg)
1207
std::vector<App::DocumentObject*> sel;
1208
std::set<App::DocumentObject*> objSet;
1209
for(auto &s : Selection().getCompleteSelection()) {
1210
if(s.pObject && s.pObject->isAttachedToDocument() && objSet.insert(s.pObject).second)
1211
sel.push_back(s.pObject);
1216
bool hasXLink = false;
1217
Base::FileInfo fi(App::Application::getTempFileName());
1219
auto all = App::Document::getDependencyList(sel);
1220
if (all.size() > sel.size()) {
1221
DlgObjectSelection dlg(sel,getMainWindow());
1222
if(dlg.exec()!=QDialog::Accepted)
1224
sel = dlg.getSelections();
1228
std::vector<App::Document*> unsaved;
1229
hasXLink = App::PropertyXLink::hasXLink(sel,&unsaved);
1230
if(!unsaved.empty()) {
1231
QMessageBox::critical(getMainWindow(), QObject::tr("Unsaved document"),
1232
QObject::tr("The exported object contains external link. Please save the document"
1233
"at least once before exporting."));
1238
Base::ofstream str(fi, std::ios::out | std::ios::binary);
1239
App::Document* doc = sel.front()->getDocument();
1240
MergeDocuments mimeView(doc);
1241
doc->exportObjects(sel, str);
1244
App::Document* doc = App::GetApplication().getActiveDocument();
1246
bool proceed = true;
1247
if(hasXLink && !doc->isSaved()) {
1248
auto ret = QMessageBox::question(getMainWindow(),
1249
qApp->translate("Std_DuplicateSelection","Object dependencies"),
1250
qApp->translate("Std_DuplicateSelection",
1251
"To link to external objects, the document must be saved at least once.\n"
1252
"Do you want to save the document now?"),
1253
QMessageBox::Yes,QMessageBox::No);
1254
if(ret == QMessageBox::Yes)
1255
proceed = Application::Instance->getDocument(doc)->saveAs();
1258
doc->openTransaction("Duplicate");
1260
Base::ifstream str(fi, std::ios::in | std::ios::binary);
1261
MergeDocuments mimeView(doc);
1262
mimeView.importObjects(str);
1264
doc->commitTransaction();
1270
bool StdCmdDuplicateSelection::isActive()
1272
return Gui::Selection().hasSelection();
1279
DEF_STD_CMD_A(StdCmdSelectAll)
1281
StdCmdSelectAll::StdCmdSelectAll()
1282
: Command("Std_SelectAll")
1285
sMenuText = QT_TR_NOOP("Select &All");
1286
sToolTipText = QT_TR_NOOP("Select all");
1287
sWhatsThis = "Std_SelectAll";
1288
sStatusTip = QT_TR_NOOP("Select all");
1289
sPixmap = "edit-select-all";
1293
void StdCmdSelectAll::activated(int iMsg)
1296
SelectionSingleton& rSel = Selection();
1297
App::Document* doc = App::GetApplication().getActiveDocument();
1298
std::vector<App::DocumentObject*> objs = doc->getObjectsOfType(App::DocumentObject::getClassTypeId());
1299
rSel.setSelection(doc->getName(), objs);
1302
bool StdCmdSelectAll::isActive()
1304
return App::GetApplication().getActiveDocument() != nullptr;
1310
DEF_STD_CMD_A(StdCmdDelete)
1312
StdCmdDelete::StdCmdDelete()
1313
:Command("Std_Delete")
1316
sMenuText = QT_TR_NOOP("&Delete");
1317
sToolTipText = QT_TR_NOOP("Deletes the selected objects");
1318
sWhatsThis = "Std_Delete";
1319
sStatusTip = QT_TR_NOOP("Deletes the selected objects");
1320
sPixmap = "edit-delete";
1321
sAccel = keySequenceToAccel(QKeySequence::Delete);
1325
void StdCmdDelete::activated(int iMsg)
1329
std::set<App::Document*> docs;
1331
openCommand(QT_TRANSLATE_NOOP("Command", "Delete"));
1332
if (getGuiApplication()->sendHasMsgToFocusView(getName())) {
1337
App::TransactionLocker tlock;
1339
Gui::getMainWindow()->setUpdatesEnabled(false);
1340
auto editDoc = Application::Instance->editDocument();
1341
ViewProviderDocumentObject *vpedit = nullptr;
1343
vpedit = dynamic_cast<ViewProviderDocumentObject*>(editDoc->getInEdit());
1344
if(vpedit && !vpedit->acceptDeletionsInEdit()) {
1345
for(auto &sel : Selection().getSelectionEx(editDoc->getDocument()->getName())) {
1346
if(sel.getObject() == vpedit->getObject()) {
1347
if (!sel.getSubNames().empty()) {
1348
vpedit->onDelete(sel.getSubNames());
1349
docs.insert(editDoc->getDocument());
1355
std::set<QString> affectedLabels;
1357
auto sels = Selection().getSelectionEx();
1358
bool autoDeletion = true;
1359
for(auto &sel : sels) {
1360
auto obj = sel.getObject();
1361
for(auto parent : obj->getInList()) {
1362
if(!Selection().isSelected(parent)) {
1363
ViewProvider* vp = Application::Instance->getViewProvider(parent);
1364
if (vp && !vp->canDelete(obj)) {
1365
autoDeletion = false;
1367
if(parent->getDocument() != obj->getDocument())
1368
label = QLatin1String(parent->getFullName().c_str());
1370
label = QLatin1String(parent->getNameInDocument());
1371
if(parent->Label.getStrValue() != parent->getNameInDocument())
1372
label += QString::fromLatin1(" (%1)").arg(
1373
QString::fromUtf8(parent->Label.getValue()));
1374
affectedLabels.insert(label);
1375
if(affectedLabels.size()>=10) {
1386
if (!autoDeletion) {
1387
QString bodyMessage;
1388
QTextStream bodyMessageStream(&bodyMessage);
1389
bodyMessageStream << qApp->translate("Std_Delete",
1390
"The following referencing objects might break.\n\n"
1391
"Are you sure you want to continue?\n");
1392
for (const auto ¤tLabel : affectedLabels)
1393
bodyMessageStream << '\n' << currentLabel;
1395
bodyMessageStream << "\n...";
1397
auto ret = QMessageBox::warning(Gui::getMainWindow(),
1398
qApp->translate("Std_Delete", "Object dependencies"), bodyMessage,
1399
QMessageBox::Yes, QMessageBox::No);
1400
if (ret == QMessageBox::Yes)
1401
autoDeletion = true;
1404
for(auto &sel : sels) {
1405
auto obj = sel.getObject();
1406
Gui::ViewProvider* vp = Application::Instance->getViewProvider(obj);
1409
if (vp->onDelete(sel.getSubNames())) {
1410
docs.insert(obj->getDocument());
1411
FCMD_OBJ_DOC_CMD(obj,"removeObject('" << obj->getNameInDocument() << "')");
1418
const auto &outList = App::PropertyXLink::getDocumentOutList();
1419
for(auto it=docs.begin();it!=docs.end();++it) {
1420
auto itd = outList.find(*it);
1421
if(itd!=outList.end()) {
1422
for(auto doc : itd->second) {
1428
for(auto doc : docs) {
1429
FCMD_DOC_CMD(doc,"recompute()");
1432
} catch (const Base::Exception& e) {
1433
QMessageBox::critical(getMainWindow(), QObject::tr("Delete failed"),
1434
QString::fromLatin1(e.what()));
1435
e.ReportException();
1437
QMessageBox::critical(getMainWindow(), QObject::tr("Delete failed"),
1438
QString::fromLatin1("Unknown error"));
1441
Gui::getMainWindow()->setUpdatesEnabled(true);
1442
Gui::getMainWindow()->update();
1445
bool StdCmdDelete::isActive()
1447
return !Selection().getCompleteSelection().empty();
1453
DEF_STD_CMD_A(StdCmdRefresh)
1455
StdCmdRefresh::StdCmdRefresh()
1456
: Command("Std_Refresh")
1459
sMenuText = QT_TR_NOOP("&Refresh");
1460
sToolTipText = QT_TR_NOOP("Recomputes the current active document");
1461
sWhatsThis = "Std_Refresh";
1462
sStatusTip = QT_TR_NOOP("Recomputes the current active document");
1463
sPixmap = "view-refresh";
1464
sAccel = keySequenceToAccel(QKeySequence::Refresh);
1465
eType = AlterDoc | Alter3DView | AlterSelection | ForEdit;
1471
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
1472
"User parameter:BaseApp/Preferences/Document");
1473
bool create = hGrp->GetBool("TransactionOnRecompute", false);
1475
eType = eType | NoTransaction;
1478
void StdCmdRefresh::activated(int iMsg)
1481
if (getActiveGuiDocument()) {
1482
App::AutoTransaction trans((eType & NoTransaction) ? nullptr : "Recompute");
1484
doCommand(Doc,"App.activeDocument().recompute(None,True,True)");
1486
catch (Base::Exception& ) {
1487
auto ret = QMessageBox::warning(getMainWindow(), QObject::tr("Dependency error"),
1488
qApp->translate("Std_Refresh", "The document contains dependency cycles.\n"
1489
"Please check the Report View for more details.\n\n"
1490
"Do you still want to proceed?"),
1491
QMessageBox::Yes, QMessageBox::No);
1492
if(ret == QMessageBox::No)
1494
doCommand(Doc,"App.activeDocument().recompute(None,True)");
1499
bool StdCmdRefresh::isActive()
1501
return this->getDocument() && this->getDocument()->mustExecute();
1507
DEF_STD_CMD_A(StdCmdTransform)
1509
StdCmdTransform::StdCmdTransform()
1510
: Command("Std_Transform")
1513
sMenuText = QT_TR_NOOP("Transform...");
1514
sToolTipText = QT_TR_NOOP("Transform the geometry of selected objects");
1515
sStatusTip = QT_TR_NOOP("Transform the geometry of selected objects");
1516
sWhatsThis = "Std_Transform";
1519
void StdCmdTransform::activated(int iMsg)
1522
Gui::Control().showDialog(new Gui::Dialog::TaskTransform());
1525
bool StdCmdTransform::isActive()
1527
return (Gui::Control().activeDialog() == nullptr);
1533
DEF_STD_CMD_A(StdCmdPlacement)
1535
StdCmdPlacement::StdCmdPlacement()
1536
: Command("Std_Placement")
1539
sMenuText = QT_TR_NOOP("Placement...");
1540
sToolTipText = QT_TR_NOOP("Place the selected objects");
1541
sStatusTip = QT_TR_NOOP("Place the selected objects");
1542
sWhatsThis = "Std_Placement";
1543
sPixmap = "Std_Placement";
1546
void StdCmdPlacement::activated(int iMsg)
1549
std::vector<App::DocumentObject*> sel = Gui::Selection().getObjectsOfType(App::GeoFeature::getClassTypeId());
1550
auto plm = new Gui::Dialog::TaskPlacement();
1552
App::Property* prop = sel.front()->getPropertyByName("Placement");
1553
if (prop && prop->is<App::PropertyPlacement>()) {
1554
plm->setPlacement(static_cast<App::PropertyPlacement*>(prop)->getValue());
1556
std::vector<Gui::SelectionObject> selection;
1557
selection.reserve(sel.size());
1558
std::transform(sel.cbegin(), sel.cend(), std::back_inserter(selection), [](App::DocumentObject* obj) {
1559
return Gui::SelectionObject(obj);
1562
plm->setPropertyName(QLatin1String("Placement"));
1563
plm->setSelection(selection);
1565
plm->clearSelection();
1568
Gui::Control().showDialog(plm);
1571
bool StdCmdPlacement::isActive()
1573
return Gui::Selection().countObjectsOfType(App::GeoFeature::getClassTypeId()) >= 1;
1579
DEF_STD_CMD_A(StdCmdTransformManip)
1581
StdCmdTransformManip::StdCmdTransformManip()
1582
: Command("Std_TransformManip")
1585
sMenuText = QT_TR_NOOP("Transform");
1586
sToolTipText = QT_TR_NOOP("Transform the selected object in the 3d view");
1587
sStatusTip = QT_TR_NOOP("Transform the selected object in the 3d view");
1588
sWhatsThis = "Std_TransformManip";
1589
sPixmap = "Std_TransformManip";
1592
void StdCmdTransformManip::activated(int iMsg)
1595
if (getActiveGuiDocument()->getInEdit())
1596
getActiveGuiDocument()->resetEdit();
1597
std::vector<App::DocumentObject*> sel = Gui::Selection().getObjectsOfType(App::GeoFeature::getClassTypeId());
1598
Gui::ViewProvider* vp = Application::Instance->getViewProvider(sel.front());
1602
getActiveGuiDocument()->setEdit(vp, Gui::ViewProvider::Transform);
1605
bool StdCmdTransformManip::isActive()
1607
return Gui::Selection().countObjectsOfType(App::GeoFeature::getClassTypeId()) == 1;
1613
DEF_STD_CMD_A(StdCmdAlignment)
1615
StdCmdAlignment::StdCmdAlignment()
1616
: Command("Std_Alignment")
1619
sMenuText = QT_TR_NOOP("Alignment...");
1620
sToolTipText = QT_TR_NOOP("Align the selected objects");
1621
sStatusTip = QT_TR_NOOP("Align the selected objects");
1622
sWhatsThis = "Std_Alignment";
1623
sPixmap = "Std_Alignment";
1626
void StdCmdAlignment::activated(int iMsg)
1629
std::vector<App::DocumentObject*> sel = Gui::Selection().getObjectsOfType
1630
(App::GeoFeature::getClassTypeId());
1631
ManualAlignment* align = ManualAlignment::instance();
1632
QObject::connect(align, &ManualAlignment::emitCanceled, align, &QObject::deleteLater);
1633
QObject::connect(align, &ManualAlignment::emitFinished, align, &QObject::deleteLater);
1636
FixedGroup fixedGroup;
1637
std::map<int, MovableGroup> groupMap;
1638
fixedGroup.addView(sel[0]);
1639
groupMap[0].addView(sel[1]);
1642
align->setFixedGroup(fixedGroup);
1645
MovableGroupModel model;
1646
model.addGroups(groupMap);
1647
align->setModel(model);
1648
Base::Type style = Base::Type::fromName("Gui::CADNavigationStyle");
1649
Base::Vector3d upDir(0,1,0), viewDir(0,0,-1);
1650
Gui::Document* doc = Application::Instance->activeDocument();
1652
auto mdi = qobject_cast<View3DInventor*>(doc->getActiveView());
1654
View3DInventorViewer* viewer = mdi->getViewer();
1655
SoCamera* camera = viewer->getSoRenderManager()->getCamera();
1657
SbVec3f up(0,1,0), dir(0,0,-1);
1658
camera->orientation.getValue().multVec(dir, dir);
1659
viewDir.Set(dir[0],dir[1],dir[2]);
1660
camera->orientation.getValue().multVec(up, up);
1661
upDir.Set(up[0],up[1],up[2]);
1663
style = viewer->navigationStyle()->getTypeId();
1667
align->setMinPoints(1);
1668
align->startAlignment(style);
1669
align->setViewingDirections(viewDir,upDir, viewDir,upDir);
1670
Gui::Selection().clearSelection();
1673
bool StdCmdAlignment::isActive()
1675
if (ManualAlignment::hasInstance())
1677
return Gui::Selection().countObjectsOfType(App::GeoFeature::getClassTypeId()) == 2;
1683
DEF_STD_CMD_A(StdCmdEdit)
1685
StdCmdEdit::StdCmdEdit()
1686
: Command("Std_Edit")
1689
sMenuText = QT_TR_NOOP("Toggle &Edit mode");
1690
sToolTipText = QT_TR_NOOP("Toggles the selected object's edit mode");
1691
sWhatsThis = "Std_Edit";
1692
sStatusTip = QT_TR_NOOP("Activates or Deactivates the selected object's edit mode");
1694
sPixmap = "edit-edit";
1698
void StdCmdEdit::activated(int iMsg)
1701
Gui::MDIView* view = Gui::getMainWindow()->activeWindow();
1702
if (view && view->isDerivedFrom(Gui::View3DInventor::getClassTypeId())) {
1703
Gui::View3DInventorViewer* viewer = static_cast<Gui::View3DInventor*>(view)->getViewer();
1704
if (viewer->isEditingViewProvider()) {
1705
doCommand(Command::Gui,"Gui.activeDocument().resetEdit()");
1707
if (!Selection().getCompleteSelection().empty()) {
1708
SelectionSingleton::SelObj obj = Selection().getCompleteSelection()[0];
1709
doCommand(Command::Gui,"Gui.activeDocument().setEdit(\"%s\",0)",obj.FeatName);
1715
bool StdCmdEdit::isActive()
1717
return (!Selection().getCompleteSelection().empty()) || (Gui::Control().activeDialog() != nullptr);
1723
DEF_STD_CMD_A(StdCmdProperties)
1725
StdCmdProperties::StdCmdProperties()
1726
: Command("Std_Properties")
1729
sMenuText = QT_TR_NOOP("Properties");
1730
sToolTipText = QT_TR_NOOP("Show the property view, which displays the properties of the selected object.");
1731
sWhatsThis = "Std_Properties";
1732
sStatusTip = sToolTipText;
1733
sAccel = "Alt+Return";
1734
sPixmap = "document-properties";
1735
eType = Alter3DView;
1738
void StdCmdProperties::activated(int iMsg)
1741
QWidget* propertyView = Gui::DockWindowManager::instance()->getDockWindow("Property view");
1743
QWidget* parent = propertyView->parentWidget();
1744
if (parent && !parent->isVisible()) {
1750
bool StdCmdProperties::isActive()
1752
return !Selection().getCompleteSelection().empty();
1758
class StdCmdExpression : public Gui::Command
1761
StdCmdExpression() : Command("Std_Expressions")
1764
sMenuText = QT_TR_NOOP("Expression actions");
1765
sToolTipText = QT_TR_NOOP("Actions that apply to expressions");
1766
sWhatsThis = "Std_Expressions";
1767
sStatusTip = QT_TR_NOOP("Actions that apply to expressions");
1771
const char* className() const override {return "StdCmdExpression";}
1774
void activated(int iMsg) override {
1775
std::map<App::Document*, std::set<App::DocumentObject*> > objs;
1778
for(auto &sel : Selection().getCompleteSelection())
1779
objs[sel.pObject->getDocument()].insert(sel.pObject);
1782
if(App::GetApplication().getActiveDocument()) {
1783
auto doc = App::GetApplication().getActiveDocument();
1784
auto array = doc->getObjects();
1785
auto &set = objs[doc];
1786
set.insert(array.begin(),array.end());
1790
for(auto doc : App::GetApplication().getDocuments()) {
1791
auto &set = objs[doc];
1792
auto array = doc->getObjects();
1793
set.insert(array.begin(),array.end());
1800
copyExpressions(objs);
1803
Gui::Action * createAction() override {
1804
auto pcAction = new ActionGroup(this, getMainWindow());
1805
pcAction->setDropDownMenu(true);
1806
applyCommandData(this->className(), pcAction);
1808
pcActionCopySel = pcAction->addAction(QObject::tr("Copy selected"));
1809
pcActionCopyActive = pcAction->addAction(QObject::tr("Copy active document"));
1810
pcActionCopyAll = pcAction->addAction(QObject::tr("Copy all documents"));
1811
pcActionPaste = pcAction->addAction(QObject::tr("Paste"));
1816
void copyExpressions(const std::map<App::Document*, std::set<App::DocumentObject*> > &objs) {
1817
std::ostringstream ss;
1818
std::vector<App::Property*> props;
1819
for(auto &v : objs) {
1820
for(auto obj : v.second) {
1822
obj->getPropertyList(props);
1823
for(auto prop : props) {
1824
auto p = dynamic_cast<App::PropertyExpressionContainer*>(prop);
1826
for(auto &v : p->getExpressions()) {
1827
ss << "##@@ " << v.first.toString() << ' '
1828
<< obj->getFullName() << '.' << p->getName()
1829
<< " (" << obj->Label.getValue() << ')' << std::endl;
1831
if(!v.second->comment.empty()) {
1832
if(v.second->comment[0] == '&'
1833
|| v.second->comment.find('\n') != std::string::npos
1834
|| v.second->comment.find('\r') != std::string::npos)
1836
std::string comment = v.second->comment;
1837
boost::replace_all(comment,"&","&");
1838
boost::replace_all(comment,"\n"," ");
1839
boost::replace_all(comment,"\r"," ");
1840
ss << '&' << comment;
1842
ss << v.second->comment;
1844
ss << std::endl << v.second->toString(true) << std::endl << std::endl;
1849
QApplication::clipboard()->setText(QString::fromUtf8(ss.str().c_str()));
1852
void pasteExpressions() {
1853
std::map<App::Document*, std::map<App::PropertyExpressionContainer*,
1854
std::map<App::ObjectIdentifier, App::ExpressionPtr> > > exprs;
1856
bool failed = false;
1857
std::string txt = QApplication::clipboard()->text().toUtf8().constData();
1858
const char *tstart = txt.c_str();
1859
const char *tend = tstart + txt.size();
1861
static boost::regex rule("^##@@ ([^ ]+) (\\w+)#(\\w+)\\.(\\w+) [^\n]+\n##@@([^\n]*)\n");
1863
if(!boost::regex_search(tstart,m,rule)) {
1864
FC_WARN("No expression header found");
1870
found = boost::regex_search(m[0].second,tend,m2,rule);
1872
auto pathName = m.str(1);
1873
auto docName = m.str(2);
1874
auto objName = m.str(3);
1875
auto propName = m.str(4);
1876
auto comment = m.str(5);
1878
App::Document *doc = App::GetApplication().getDocument(docName.c_str());
1880
FC_WARN("Cannot find document '" << docName << "'");
1884
auto obj = doc->getObject(objName.c_str());
1886
FC_WARN("Cannot find object '" << docName << '#' << objName << "'");
1890
auto prop = dynamic_cast<App::PropertyExpressionContainer*>(
1891
obj->getPropertyByName(propName.c_str()));
1893
FC_WARN("Invalid property '" << docName << '#' << objName << '.' << propName << "'");
1897
size_t len = (found?m2[0].first:tend) - m[0].second;
1899
App::ExpressionPtr expr(App::Expression::parse(obj,std::string(m[0].second,len)));
1900
if(expr && !comment.empty()) {
1901
if(comment[0] == '&') {
1902
expr->comment = comment.c_str()+1;
1903
boost::replace_all(expr->comment,"&","&");
1904
boost::replace_all(expr->comment," ","\n");
1905
boost::replace_all(expr->comment," ","\r");
1907
expr->comment = comment;
1909
exprs[doc][prop][App::ObjectIdentifier::parse(obj,pathName)] = std::move(expr);
1910
} catch(Base::Exception &e) {
1911
FC_ERR(e.what() << std::endl << m[0].str());
1916
QMessageBox::critical(getMainWindow(), QObject::tr("Expression error"),
1917
QObject::tr("Failed to parse some of the expressions.\n"
1918
"Please check the Report View for more details."));
1922
openCommand(QT_TRANSLATE_NOOP("Command", "Paste expressions"));
1924
for(auto &v : exprs) {
1925
for(auto &v2 : v.second) {
1926
auto &expressions = v2.second;
1927
auto old = v2.first->getExpressions();
1928
for(auto it=expressions.begin(),itNext=it;it!=expressions.end();it=itNext) {
1930
auto iter = old.find(it->first);
1931
if(iter != old.end() && it->second->isSame(*iter->second))
1932
expressions.erase(it);
1934
if(!expressions.empty())
1935
v2.first->setExpressions(std::move(expressions));
1939
} catch (const Base::Exception& e) {
1941
QMessageBox::critical(getMainWindow(), QObject::tr("Failed to paste expressions"),
1942
QString::fromLatin1(e.what()));
1943
e.ReportException();
1947
bool isActive() override {
1948
if(!App::GetApplication().getActiveDocument()) {
1949
pcActionCopyAll->setEnabled(false);
1950
pcActionCopySel->setEnabled(false);
1951
pcActionCopyActive->setEnabled(false);
1952
pcActionPaste->setEnabled(false);
1955
pcActionCopyActive->setEnabled(true);
1956
pcActionCopyAll->setEnabled(true);
1957
pcActionCopySel->setEnabled(Selection().hasSelection());
1959
pcActionPaste->setEnabled(
1960
QApplication::clipboard()->text().startsWith(QLatin1String("##@@ ")));
1964
QAction *pcActionCopyAll{nullptr};
1965
QAction *pcActionCopySel{nullptr};
1966
QAction *pcActionCopyActive{nullptr};
1967
QAction *pcActionPaste{nullptr};
1972
void CreateDocCommands()
1974
CommandManager &rcCmdMgr = Application::Instance->commandManager();
1976
rcCmdMgr.addCommand(new StdCmdNew());
1977
rcCmdMgr.addCommand(new StdCmdOpen());
1978
rcCmdMgr.addCommand(new StdCmdImport());
1979
rcCmdMgr.addCommand(new StdCmdExport());
1980
rcCmdMgr.addCommand(new StdCmdMergeProjects());
1981
rcCmdMgr.addCommand(new StdCmdDependencyGraph());
1982
rcCmdMgr.addCommand(new StdCmdExportDependencyGraph());
1984
rcCmdMgr.addCommand(new StdCmdSave());
1985
rcCmdMgr.addCommand(new StdCmdSaveAs());
1986
rcCmdMgr.addCommand(new StdCmdSaveCopy());
1987
rcCmdMgr.addCommand(new StdCmdSaveAll());
1988
rcCmdMgr.addCommand(new StdCmdRevert());
1989
rcCmdMgr.addCommand(new StdCmdProjectInfo());
1990
rcCmdMgr.addCommand(new StdCmdProjectUtil());
1991
rcCmdMgr.addCommand(new StdCmdUndo());
1992
rcCmdMgr.addCommand(new StdCmdRedo());
1993
rcCmdMgr.addCommand(new StdCmdPrint());
1994
rcCmdMgr.addCommand(new StdCmdPrintPreview());
1995
rcCmdMgr.addCommand(new StdCmdPrintPdf());
1996
rcCmdMgr.addCommand(new StdCmdQuit());
1997
rcCmdMgr.addCommand(new StdCmdCut());
1998
rcCmdMgr.addCommand(new StdCmdCopy());
1999
rcCmdMgr.addCommand(new StdCmdPaste());
2000
rcCmdMgr.addCommand(new StdCmdDuplicateSelection());
2001
rcCmdMgr.addCommand(new StdCmdSelectAll());
2002
rcCmdMgr.addCommand(new StdCmdDelete());
2003
rcCmdMgr.addCommand(new StdCmdRefresh());
2004
rcCmdMgr.addCommand(new StdCmdTransform());
2005
rcCmdMgr.addCommand(new StdCmdPlacement());
2006
rcCmdMgr.addCommand(new StdCmdTransformManip());
2007
rcCmdMgr.addCommand(new StdCmdAlignment());
2008
rcCmdMgr.addCommand(new StdCmdEdit());
2009
rcCmdMgr.addCommand(new StdCmdProperties());
2010
rcCmdMgr.addCommand(new StdCmdExpression());