======================================================== If the restore of Document.xml results in invalid Document.xml (because unhandled exceptions occurred), the document status Document::restoreError is set. The GUI or Mod/Web if a link was clicked, show a pop-up indicating this situation. This commit also shows an appropriate pop-up for the partialRestore when opening from the menu, that before only appeared when opening by clicking a link.
1815 lines
65 KiB
C++
1815 lines
65 KiB
C++
/***************************************************************************
|
|
* Copyright (c) 2002 Jürgen Riegel <juergen.riegel@web.de> *
|
|
* *
|
|
* This file is part of the FreeCAD CAx development system. *
|
|
* *
|
|
* This library is free software; you can redistribute it and/or *
|
|
* modify it under the terms of the GNU Library General Public *
|
|
* License as published by the Free Software Foundation; either *
|
|
* version 2 of the License, or (at your option) any later version. *
|
|
* *
|
|
* This library is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU Library General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU Library General Public *
|
|
* License along with this library; see the file COPYING.LIB. If not, *
|
|
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
|
* Suite 330, Boston, MA 02111-1307, USA *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
|
|
#include "PreCompiled.h"
|
|
#ifndef _PreComp_
|
|
# include <QApplication>
|
|
# include <QClipboard>
|
|
# include <QEventLoop>
|
|
# include <QFileDialog>
|
|
# include <QLabel>
|
|
# include <QTextStream>
|
|
# include <QStatusBar>
|
|
# include <QPointer>
|
|
# include <QProcess>
|
|
# include <sstream>
|
|
# include <Inventor/nodes/SoCamera.h>
|
|
#endif
|
|
#include <algorithm>
|
|
|
|
#include <boost/regex.hpp>
|
|
#include <boost/algorithm/string/replace.hpp>
|
|
|
|
#include <Base/Exception.h>
|
|
#include <Base/FileInfo.h>
|
|
#include <Base/Interpreter.h>
|
|
#include <Base/Sequencer.h>
|
|
#include <Base/Tools.h>
|
|
#include <Base/Console.h>
|
|
#include <App/AutoTransaction.h>
|
|
#include <App/Document.h>
|
|
#include <App/DocumentObjectGroup.h>
|
|
#include <App/DocumentObject.h>
|
|
#include <App/GeoFeature.h>
|
|
#include <App/Origin.h>
|
|
|
|
#include "Action.h"
|
|
#include "Application.h"
|
|
#include "Document.h"
|
|
#include "Command.h"
|
|
#include "Control.h"
|
|
#include "FileDialog.h"
|
|
#include "MainWindow.h"
|
|
#include "BitmapFactory.h"
|
|
#include "Selection.h"
|
|
#include "DlgProjectInformationImp.h"
|
|
#include "DlgProjectUtility.h"
|
|
#include "Transform.h"
|
|
#include "Placement.h"
|
|
#include "ManualAlignment.h"
|
|
#include "WaitCursor.h"
|
|
#include "ViewProvider.h"
|
|
#include <Gui/View3DInventor.h>
|
|
#include <Gui/View3DInventorViewer.h>
|
|
#include "MergeDocuments.h"
|
|
#include "NavigationStyle.h"
|
|
#include "GraphvizView.h"
|
|
#include "DlgObjectSelection.h"
|
|
|
|
FC_LOG_LEVEL_INIT("Command", false)
|
|
|
|
using namespace Gui;
|
|
|
|
|
|
//===========================================================================
|
|
// Std_Open
|
|
//===========================================================================
|
|
|
|
DEF_STD_CMD(StdCmdOpen)
|
|
|
|
StdCmdOpen::StdCmdOpen()
|
|
: Command("Std_Open")
|
|
{
|
|
// setting the
|
|
sGroup = QT_TR_NOOP("File");
|
|
sMenuText = QT_TR_NOOP("&Open...");
|
|
sToolTipText = QT_TR_NOOP("Open a document or import files");
|
|
sWhatsThis = "Std_Open";
|
|
sStatusTip = QT_TR_NOOP("Open a document or import files");
|
|
sPixmap = "document-open";
|
|
sAccel = keySequenceToAccel(QKeySequence::Open);
|
|
eType = NoTransaction;
|
|
}
|
|
|
|
void StdCmdOpen::activated(int iMsg)
|
|
{
|
|
Q_UNUSED(iMsg);
|
|
|
|
// fill the list of registered endings
|
|
QString formatList;
|
|
const char* supported = QT_TR_NOOP("Supported formats");
|
|
const char* allFiles = QT_TR_NOOP("All files (*.*)");
|
|
formatList = QObject::tr(supported);
|
|
formatList += QLatin1String(" (");
|
|
|
|
std::vector<std::string> filetypes = App::GetApplication().getImportTypes();
|
|
std::vector<std::string>::iterator it;
|
|
// Make sure FCStd is the very first fileformat
|
|
it = std::find(filetypes.begin(), filetypes.end(), "FCStd");
|
|
if (it != filetypes.end()) {
|
|
filetypes.erase(it);
|
|
filetypes.insert(filetypes.begin(), "FCStd");
|
|
}
|
|
for (it=filetypes.begin();it != filetypes.end();++it) {
|
|
formatList += QLatin1String(" *.");
|
|
formatList += QLatin1String(it->c_str());
|
|
}
|
|
|
|
formatList += QLatin1String(");;");
|
|
|
|
std::map<std::string, std::string> FilterList = App::GetApplication().getImportFilters();
|
|
std::map<std::string, std::string>::iterator jt;
|
|
// Make sure the format name for FCStd is the very first in the list
|
|
for (jt=FilterList.begin();jt != FilterList.end();++jt) {
|
|
if (jt->first.find("*.FCStd") != std::string::npos) {
|
|
formatList += QLatin1String(jt->first.c_str());
|
|
formatList += QLatin1String(";;");
|
|
FilterList.erase(jt);
|
|
break;
|
|
}
|
|
}
|
|
for (jt=FilterList.begin();jt != FilterList.end();++jt) {
|
|
formatList += QLatin1String(jt->first.c_str());
|
|
formatList += QLatin1String(";;");
|
|
}
|
|
formatList += QObject::tr(allFiles);
|
|
|
|
QString selectedFilter;
|
|
QStringList fileList = FileDialog::getOpenFileNames(getMainWindow(),
|
|
QObject::tr("Open document"), QString(), formatList, &selectedFilter);
|
|
if (fileList.isEmpty())
|
|
return;
|
|
|
|
// load the files with the associated modules
|
|
SelectModule::Dict dict = SelectModule::importHandler(fileList, selectedFilter);
|
|
if (dict.isEmpty()) {
|
|
QMessageBox::critical(getMainWindow(),
|
|
qApp->translate("StdCmdOpen", "Cannot open file"),
|
|
qApp->translate("StdCmdOpen", "Loading the file %1 is not supported").arg(fileList.front()));
|
|
}
|
|
else {
|
|
for (SelectModule::Dict::iterator it = dict.begin(); it != dict.end(); ++it) {
|
|
getGuiApplication()->open(it.key().toUtf8(), it.value().toLatin1());
|
|
|
|
App::Document *doc = App::GetApplication().getActiveDocument();
|
|
|
|
if(doc && doc->testStatus(App::Document::PartialRestore))
|
|
QMessageBox::critical(getMainWindow(), QObject::tr("Error"), 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."));
|
|
|
|
if(doc && doc->testStatus(App::Document::RestoreError))
|
|
QMessageBox::critical(getMainWindow(), QObject::tr("Error"), 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."));
|
|
}
|
|
}
|
|
}
|
|
|
|
//===========================================================================
|
|
// Std_Import
|
|
//===========================================================================
|
|
|
|
DEF_STD_CMD_A(StdCmdImport)
|
|
|
|
StdCmdImport::StdCmdImport()
|
|
: Command("Std_Import")
|
|
{
|
|
// setting the
|
|
sGroup = QT_TR_NOOP("File");
|
|
sMenuText = QT_TR_NOOP("&Import...");
|
|
sToolTipText = QT_TR_NOOP("Import a file in the active document");
|
|
sWhatsThis = "Std_Import";
|
|
sStatusTip = QT_TR_NOOP("Import a file in the active document");
|
|
sPixmap = "Std_Import";
|
|
sAccel = "Ctrl+I";
|
|
}
|
|
|
|
void StdCmdImport::activated(int iMsg)
|
|
{
|
|
Q_UNUSED(iMsg);
|
|
|
|
// fill the list of registered endings
|
|
QString formatList;
|
|
const char* supported = QT_TR_NOOP("Supported formats");
|
|
const char* allFiles = QT_TR_NOOP("All files (*.*)");
|
|
formatList = QObject::tr(supported);
|
|
formatList += QLatin1String(" (");
|
|
|
|
std::vector<std::string> filetypes = App::GetApplication().getImportTypes();
|
|
std::vector<std::string>::const_iterator it;
|
|
for (it=filetypes.begin();it != filetypes.end();++it) {
|
|
if (*it != "FCStd") {
|
|
// ignore the project file format
|
|
formatList += QLatin1String(" *.");
|
|
formatList += QLatin1String(it->c_str());
|
|
}
|
|
}
|
|
|
|
formatList += QLatin1String(");;");
|
|
|
|
std::map<std::string, std::string> FilterList = App::GetApplication().getImportFilters();
|
|
std::map<std::string, std::string>::const_iterator jt;
|
|
for (jt=FilterList.begin();jt != FilterList.end();++jt) {
|
|
// ignore the project file format
|
|
if (jt->first.find("(*.FCStd)") == std::string::npos) {
|
|
formatList += QLatin1String(jt->first.c_str());
|
|
formatList += QLatin1String(";;");
|
|
}
|
|
}
|
|
formatList += QObject::tr(allFiles);
|
|
|
|
Base::Reference<ParameterGrp> hPath = App::GetApplication().GetUserParameter().GetGroup("BaseApp")
|
|
->GetGroup("Preferences")->GetGroup("General");
|
|
QString selectedFilter = QString::fromStdString(hPath->GetASCII("FileImportFilter"));
|
|
QStringList fileList = FileDialog::getOpenFileNames(getMainWindow(),
|
|
QObject::tr("Import file"), QString(), formatList, &selectedFilter);
|
|
if (!fileList.isEmpty()) {
|
|
hPath->SetASCII("FileImportFilter", selectedFilter.toLatin1().constData());
|
|
SelectModule::Dict dict = SelectModule::importHandler(fileList, selectedFilter);
|
|
|
|
bool emptyDoc = (getActiveGuiDocument()->getDocument()->countObjects() == 0);
|
|
// load the files with the associated modules
|
|
for (SelectModule::Dict::iterator it = dict.begin(); it != dict.end(); ++it) {
|
|
getGuiApplication()->importFrom(it.key().toUtf8(),
|
|
getActiveGuiDocument()->getDocument()->getName(),
|
|
it.value().toLatin1());
|
|
}
|
|
|
|
if (emptyDoc) {
|
|
// only do a view fit if the document was empty before. See also parameter 'AutoFitToView' in importFrom()
|
|
std::list<Gui::MDIView*> views = getActiveGuiDocument()->getMDIViewsOfType(Gui::View3DInventor::getClassTypeId());
|
|
for (std::list<MDIView*>::iterator it = views.begin(); it != views.end(); ++it) {
|
|
(*it)->viewAll();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool StdCmdImport::isActive(void)
|
|
{
|
|
return (getActiveGuiDocument() ? true : false);
|
|
}
|
|
|
|
|
|
//===========================================================================
|
|
// Std_Export
|
|
//===========================================================================
|
|
|
|
DEF_STD_CMD_A(StdCmdExport)
|
|
|
|
StdCmdExport::StdCmdExport()
|
|
: Command("Std_Export")
|
|
{
|
|
// setting the
|
|
sGroup = QT_TR_NOOP("File");
|
|
sMenuText = QT_TR_NOOP("&Export...");
|
|
sToolTipText = QT_TR_NOOP("Export an object in the active document");
|
|
sWhatsThis = "Std_Export";
|
|
sStatusTip = QT_TR_NOOP("Export an object in the active document");
|
|
//sPixmap = "Open";
|
|
sAccel = "Ctrl+E";
|
|
sPixmap = "Std_Export";
|
|
eType = 0;
|
|
}
|
|
|
|
void StdCmdExport::activated(int iMsg)
|
|
{
|
|
Q_UNUSED(iMsg);
|
|
|
|
if (Gui::Selection().countObjectsOfType(App::DocumentObject::getClassTypeId()) == 0) {
|
|
QMessageBox::warning(Gui::getMainWindow(),
|
|
QString::fromUtf8(QT_TR_NOOP("No selection")),
|
|
QString::fromUtf8(QT_TR_NOOP("Please select first the objects you want to export.")));
|
|
return;
|
|
}
|
|
|
|
// fill the list of registered endings
|
|
QStringList filterList;
|
|
std::map<std::string, std::string> FilterList = App::GetApplication().getExportFilters();
|
|
std::map<std::string, std::string>::const_iterator jt;
|
|
for (jt=FilterList.begin();jt != FilterList.end();++jt) {
|
|
// ignore the project file format
|
|
if (jt->first.find("(*.FCStd)") == std::string::npos) {
|
|
filterList << QString::fromLatin1(jt->first.c_str());
|
|
}
|
|
}
|
|
|
|
QString formatList = filterList.join(QLatin1String(";;"));
|
|
Base::Reference<ParameterGrp> hPath = App::GetApplication().GetUserParameter().GetGroup("BaseApp")
|
|
->GetGroup("Preferences")->GetGroup("General");
|
|
QString selectedFilter = QString::fromStdString(hPath->GetASCII("FileExportFilter"));
|
|
|
|
QString fileName = FileDialog::getSaveFileName(getMainWindow(),
|
|
QObject::tr("Export file"), QString(), formatList, &selectedFilter);
|
|
if (!fileName.isEmpty()) {
|
|
hPath->SetASCII("FileExportFilter", selectedFilter.toLatin1().constData());
|
|
SelectModule::Dict dict = SelectModule::exportHandler(fileName, selectedFilter);
|
|
// export the files with the associated modules
|
|
for (SelectModule::Dict::iterator it = dict.begin(); it != dict.end(); ++it) {
|
|
getGuiApplication()->exportTo(it.key().toUtf8(),
|
|
getActiveGuiDocument()->getDocument()->getName(),
|
|
it.value().toLatin1());
|
|
}
|
|
}
|
|
}
|
|
|
|
bool StdCmdExport::isActive(void)
|
|
{
|
|
return (getActiveGuiDocument() ? true : false);
|
|
}
|
|
|
|
//===========================================================================
|
|
// Std_MergeProjects
|
|
//===========================================================================
|
|
|
|
DEF_STD_CMD_A(StdCmdMergeProjects)
|
|
|
|
StdCmdMergeProjects::StdCmdMergeProjects()
|
|
: Command("Std_MergeProjects")
|
|
{
|
|
sAppModule = "File";
|
|
sGroup = QT_TR_NOOP("File");
|
|
sMenuText = QT_TR_NOOP("Merge project...");
|
|
sToolTipText = QT_TR_NOOP("Merge project");
|
|
sWhatsThis = "Std_MergeProjects";
|
|
sStatusTip = QT_TR_NOOP("Merge project");
|
|
sPixmap = "Std_MergeProjects";
|
|
}
|
|
|
|
void StdCmdMergeProjects::activated(int iMsg)
|
|
{
|
|
Q_UNUSED(iMsg);
|
|
|
|
QString exe = qApp->applicationName();
|
|
QString project = FileDialog::getOpenFileName(Gui::getMainWindow(),
|
|
QString::fromUtf8(QT_TR_NOOP("Merge project")), FileDialog::getWorkingDirectory(),
|
|
QString::fromUtf8(QT_TR_NOOP("%1 document (*.FCStd)")).arg(exe));
|
|
if (!project.isEmpty()) {
|
|
FileDialog::setWorkingDirectory(project);
|
|
App::Document* doc = App::GetApplication().getActiveDocument();
|
|
QFileInfo info(QString::fromUtf8(doc->FileName.getValue()));
|
|
QFileInfo proj(project);
|
|
if (proj == info) {
|
|
QMessageBox::critical(Gui::getMainWindow(),
|
|
QString::fromUtf8(QT_TR_NOOP("Merge project")),
|
|
QString::fromUtf8(QT_TR_NOOP("Cannot merge project with itself.")));
|
|
return;
|
|
}
|
|
|
|
doc->openTransaction("Merge project");
|
|
Base::FileInfo fi((const char*)project.toUtf8());
|
|
Base::ifstream str(fi, std::ios::in | std::ios::binary);
|
|
MergeDocuments md(doc);
|
|
md.importObjects(str);
|
|
str.close();
|
|
doc->commitTransaction();
|
|
}
|
|
}
|
|
|
|
bool StdCmdMergeProjects::isActive(void)
|
|
{
|
|
return this->hasActiveDocument();
|
|
}
|
|
|
|
//===========================================================================
|
|
// Std_DependencyGraph
|
|
//===========================================================================
|
|
|
|
DEF_STD_CMD_A(StdCmdDependencyGraph)
|
|
|
|
StdCmdDependencyGraph::StdCmdDependencyGraph()
|
|
: Command("Std_DependencyGraph")
|
|
{
|
|
// setting the
|
|
sGroup = QT_TR_NOOP("Tools");
|
|
sMenuText = QT_TR_NOOP("Dependency graph...");
|
|
sToolTipText = QT_TR_NOOP("Show the dependency graph of the objects in the active document");
|
|
sStatusTip = QT_TR_NOOP("Show the dependency graph of the objects in the active document");
|
|
sWhatsThis = "Std_DependencyGraph";
|
|
eType = 0;
|
|
sPixmap = "Std_DependencyGraph";
|
|
}
|
|
|
|
void StdCmdDependencyGraph::activated(int iMsg)
|
|
{
|
|
Q_UNUSED(iMsg);
|
|
App::Document* doc = App::GetApplication().getActiveDocument();
|
|
Gui::GraphvizView* view = new Gui::GraphvizView(*doc);
|
|
view->setWindowTitle(qApp->translate("Std_DependencyGraph","Dependency graph"));
|
|
getMainWindow()->addWindow(view);
|
|
}
|
|
|
|
bool StdCmdDependencyGraph::isActive(void)
|
|
{
|
|
return (getActiveGuiDocument() ? true : false);
|
|
}
|
|
|
|
//===========================================================================
|
|
// Std_New
|
|
//===========================================================================
|
|
|
|
DEF_STD_CMD(StdCmdNew)
|
|
|
|
StdCmdNew::StdCmdNew()
|
|
:Command("Std_New")
|
|
{
|
|
sGroup = QT_TR_NOOP("File");
|
|
sMenuText = QT_TR_NOOP("&New");
|
|
sToolTipText = QT_TR_NOOP("Create a new empty document");
|
|
sWhatsThis = "Std_New";
|
|
sStatusTip = QT_TR_NOOP("Create a new empty document");
|
|
sPixmap = "document-new";
|
|
sAccel = keySequenceToAccel(QKeySequence::New);
|
|
}
|
|
|
|
void StdCmdNew::activated(int iMsg)
|
|
{
|
|
Q_UNUSED(iMsg);
|
|
QString cmd;
|
|
cmd = QString::fromLatin1("App.newDocument(\"%1\")")
|
|
.arg(qApp->translate("StdCmdNew","Unnamed"));
|
|
runCommand(Command::Doc,cmd.toUtf8());
|
|
doCommand(Command::Gui,"Gui.activeDocument().activeView().viewDefaultOrientation()");
|
|
|
|
ParameterGrp::handle hViewGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
|
|
if (hViewGrp->GetBool("ShowAxisCross"))
|
|
doCommand(Command::Gui,"Gui.ActiveDocument.ActiveView.setAxisCross(True)");
|
|
}
|
|
|
|
//===========================================================================
|
|
// Std_Save
|
|
//===========================================================================
|
|
DEF_STD_CMD_A(StdCmdSave)
|
|
|
|
StdCmdSave::StdCmdSave()
|
|
:Command("Std_Save")
|
|
{
|
|
sGroup = QT_TR_NOOP("File");
|
|
sMenuText = QT_TR_NOOP("&Save");
|
|
sToolTipText = QT_TR_NOOP("Save the active document");
|
|
sWhatsThis = "Std_Save";
|
|
sStatusTip = QT_TR_NOOP("Save the active document");
|
|
sPixmap = "document-save";
|
|
sAccel = keySequenceToAccel(QKeySequence::Save);
|
|
eType = 0;
|
|
}
|
|
|
|
void StdCmdSave::activated(int iMsg)
|
|
{
|
|
Q_UNUSED(iMsg);
|
|
#if 0
|
|
Gui::Document* pActiveDoc = getActiveGuiDocument();
|
|
if ( pActiveDoc )
|
|
pActiveDoc->save();
|
|
else
|
|
#endif
|
|
doCommand(Command::Gui,"Gui.SendMsgToActiveView(\"Save\")");
|
|
}
|
|
|
|
bool StdCmdSave::isActive(void)
|
|
{
|
|
#if 0
|
|
if( getActiveGuiDocument() )
|
|
return true;
|
|
else
|
|
#endif
|
|
return getGuiApplication()->sendHasMsgToActiveView("Save");
|
|
}
|
|
|
|
//===========================================================================
|
|
// Std_SaveAs
|
|
//===========================================================================
|
|
DEF_STD_CMD_A(StdCmdSaveAs)
|
|
|
|
StdCmdSaveAs::StdCmdSaveAs()
|
|
:Command("Std_SaveAs")
|
|
{
|
|
sGroup = QT_TR_NOOP("File");
|
|
sMenuText = QT_TR_NOOP("Save &As...");
|
|
sToolTipText = QT_TR_NOOP("Save the active document under a new file name");
|
|
sWhatsThis = "Std_SaveAs";
|
|
sStatusTip = QT_TR_NOOP("Save the active document under a new file name");
|
|
#if QT_VERSION >= 0x040200
|
|
sPixmap = "document-save-as";
|
|
#endif
|
|
sAccel = keySequenceToAccel(QKeySequence::SaveAs);
|
|
eType = 0;
|
|
}
|
|
|
|
void StdCmdSaveAs::activated(int iMsg)
|
|
{
|
|
Q_UNUSED(iMsg);
|
|
#if 0
|
|
Gui::Document* pActiveDoc = getActiveGuiDocument();
|
|
if ( pActiveDoc )
|
|
pActiveDoc->saveAs();
|
|
else
|
|
#endif
|
|
doCommand(Command::Gui,"Gui.SendMsgToActiveView(\"SaveAs\")");
|
|
}
|
|
|
|
bool StdCmdSaveAs::isActive(void)
|
|
{
|
|
#if 0
|
|
if( getActiveGuiDocument() )
|
|
return true;
|
|
else
|
|
#endif
|
|
return getGuiApplication()->sendHasMsgToActiveView("SaveAs");
|
|
}
|
|
|
|
//===========================================================================
|
|
// Std_SaveCopy
|
|
//===========================================================================
|
|
DEF_STD_CMD_A(StdCmdSaveCopy)
|
|
|
|
StdCmdSaveCopy::StdCmdSaveCopy()
|
|
:Command("Std_SaveCopy")
|
|
{
|
|
sGroup = QT_TR_NOOP("File");
|
|
sMenuText = QT_TR_NOOP("Save a &Copy...");
|
|
sToolTipText = QT_TR_NOOP("Save a copy of the active document under a new file name");
|
|
sWhatsThis = "Std_SaveCopy";
|
|
sStatusTip = QT_TR_NOOP("Save a copy of the active document under a new file name");
|
|
sPixmap = "Std_SaveCopy";
|
|
}
|
|
|
|
void StdCmdSaveCopy::activated(int iMsg)
|
|
{
|
|
Q_UNUSED(iMsg);
|
|
#if 0
|
|
Gui::Document* pActiveDoc = getActiveGuiDocument();
|
|
if ( pActiveDoc )
|
|
pActiveDoc->saveCopy();
|
|
else
|
|
#endif
|
|
doCommand(Command::Gui,"Gui.SendMsgToActiveView(\"SaveCopy\")");
|
|
}
|
|
|
|
bool StdCmdSaveCopy::isActive(void)
|
|
{
|
|
return ( getActiveGuiDocument() ? true : false );
|
|
}
|
|
|
|
//===========================================================================
|
|
// Std_SaveAll
|
|
//===========================================================================
|
|
DEF_STD_CMD_A(StdCmdSaveAll)
|
|
|
|
StdCmdSaveAll::StdCmdSaveAll()
|
|
:Command("Std_SaveAll")
|
|
{
|
|
sGroup = QT_TR_NOOP("File");
|
|
sMenuText = QT_TR_NOOP("Save All");
|
|
sToolTipText = QT_TR_NOOP("Save all opened document");
|
|
sWhatsThis = "Std_SaveAll";
|
|
sStatusTip = QT_TR_NOOP("Save all opened document");
|
|
sPixmap = "Std_SaveAll";
|
|
}
|
|
|
|
void StdCmdSaveAll::activated(int iMsg)
|
|
{
|
|
Q_UNUSED(iMsg);
|
|
Gui::Document::saveAll();
|
|
}
|
|
|
|
bool StdCmdSaveAll::isActive(void)
|
|
{
|
|
return ( getActiveGuiDocument() ? true : false );
|
|
}
|
|
|
|
|
|
//===========================================================================
|
|
// Std_Revert
|
|
//===========================================================================
|
|
DEF_STD_CMD_A(StdCmdRevert)
|
|
|
|
StdCmdRevert::StdCmdRevert()
|
|
:Command("Std_Revert")
|
|
{
|
|
sGroup = QT_TR_NOOP("File");
|
|
sMenuText = QT_TR_NOOP("Revert");
|
|
sToolTipText = QT_TR_NOOP("Reverts to the saved version of this file");
|
|
sWhatsThis = "Std_Revert";
|
|
sStatusTip = QT_TR_NOOP("Reverts to the saved version of this file");
|
|
sPixmap = "Std_Revert";
|
|
eType = NoTransaction;
|
|
}
|
|
|
|
void StdCmdRevert::activated(int iMsg)
|
|
{
|
|
Q_UNUSED(iMsg);
|
|
QMessageBox msgBox(Gui::getMainWindow());
|
|
msgBox.setIcon(QMessageBox::Question);
|
|
msgBox.setWindowTitle(qApp->translate("Std_Revert","Revert document"));
|
|
msgBox.setText(qApp->translate("Std_Revert","This will discard all the changes since last file save."));
|
|
msgBox.setInformativeText(qApp->translate("Std_Revert","Do you want to continue?"));
|
|
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
|
msgBox.setDefaultButton(QMessageBox::No);
|
|
int ret = msgBox.exec();
|
|
if (ret == QMessageBox::Yes)
|
|
doCommand(Command::App,"App.ActiveDocument.restore()");
|
|
}
|
|
|
|
bool StdCmdRevert::isActive(void)
|
|
{
|
|
return ( getActiveGuiDocument() ? true : false );
|
|
}
|
|
|
|
//===========================================================================
|
|
// Std_ProjectInfo
|
|
//===========================================================================
|
|
|
|
DEF_STD_CMD_A(StdCmdProjectInfo)
|
|
|
|
StdCmdProjectInfo::StdCmdProjectInfo()
|
|
:Command("Std_ProjectInfo")
|
|
{
|
|
// setting the
|
|
sGroup = QT_TR_NOOP("File");
|
|
sMenuText = QT_TR_NOOP("Project i&nformation...");
|
|
sToolTipText = QT_TR_NOOP("Show details of the currently active project");
|
|
sWhatsThis = "Std_ProjectInfo";
|
|
sStatusTip = QT_TR_NOOP("Show details of the currently active project");
|
|
#if QT_VERSION >= 0x040200
|
|
sPixmap = "document-properties";
|
|
#endif
|
|
}
|
|
|
|
void StdCmdProjectInfo::activated(int iMsg)
|
|
{
|
|
Q_UNUSED(iMsg);
|
|
Gui::Dialog::DlgProjectInformationImp dlg(getActiveGuiDocument()->getDocument(), getMainWindow());
|
|
dlg.exec();
|
|
}
|
|
|
|
bool StdCmdProjectInfo::isActive(void)
|
|
{
|
|
return ( getActiveGuiDocument() ? true : false );
|
|
}
|
|
|
|
//===========================================================================
|
|
// Std_ProjectUtil
|
|
//===========================================================================
|
|
|
|
DEF_STD_CMD_A(StdCmdProjectUtil)
|
|
|
|
StdCmdProjectUtil::StdCmdProjectUtil()
|
|
:Command("Std_ProjectUtil")
|
|
{
|
|
// setting the
|
|
sGroup = QT_TR_NOOP("Tools");
|
|
sWhatsThis = "Std_ProjectUtil";
|
|
sMenuText = QT_TR_NOOP("Project utility...");
|
|
sToolTipText = QT_TR_NOOP("Utility to extract or create project files");
|
|
sStatusTip = QT_TR_NOOP("Utility to extract or create project files");
|
|
sPixmap = "Std_ProjectUtil";
|
|
}
|
|
|
|
void StdCmdProjectUtil::activated(int iMsg)
|
|
{
|
|
Q_UNUSED(iMsg);
|
|
Gui::Dialog::DlgProjectUtility dlg(getMainWindow());
|
|
dlg.exec();
|
|
}
|
|
|
|
bool StdCmdProjectUtil::isActive(void)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
//===========================================================================
|
|
// Std_Print
|
|
//===========================================================================
|
|
DEF_STD_CMD_A(StdCmdPrint)
|
|
|
|
StdCmdPrint::StdCmdPrint()
|
|
:Command("Std_Print")
|
|
{
|
|
sGroup = QT_TR_NOOP("File");
|
|
sMenuText = QT_TR_NOOP("&Print...");
|
|
sToolTipText = QT_TR_NOOP("Print the document");
|
|
sWhatsThis = "Std_Print";
|
|
sStatusTip = QT_TR_NOOP("Print the document");
|
|
sPixmap = "document-print";
|
|
sAccel = keySequenceToAccel(QKeySequence::Print);
|
|
eType = 0;
|
|
}
|
|
|
|
void StdCmdPrint::activated(int iMsg)
|
|
{
|
|
Q_UNUSED(iMsg);
|
|
if (getMainWindow()->activeWindow()) {
|
|
getMainWindow()->showMessage(QObject::tr("Printing..."));
|
|
getMainWindow()->activeWindow()->print();
|
|
}
|
|
}
|
|
|
|
bool StdCmdPrint::isActive(void)
|
|
{
|
|
return getGuiApplication()->sendHasMsgToActiveView("Print");
|
|
}
|
|
|
|
//===========================================================================
|
|
// Std_PrintPreview
|
|
//===========================================================================
|
|
DEF_STD_CMD_A(StdCmdPrintPreview)
|
|
|
|
StdCmdPrintPreview::StdCmdPrintPreview()
|
|
:Command("Std_PrintPreview")
|
|
{
|
|
sGroup = QT_TR_NOOP("File");
|
|
sMenuText = QT_TR_NOOP("&Print preview...");
|
|
sToolTipText = QT_TR_NOOP("Print the document");
|
|
sWhatsThis = "Std_PrintPreview";
|
|
sStatusTip = QT_TR_NOOP("Print preview");
|
|
sPixmap = "document-print-preview";
|
|
eType = 0;
|
|
}
|
|
|
|
void StdCmdPrintPreview::activated(int iMsg)
|
|
{
|
|
Q_UNUSED(iMsg);
|
|
if (getMainWindow()->activeWindow()) {
|
|
getMainWindow()->activeWindow()->printPreview();
|
|
}
|
|
}
|
|
|
|
bool StdCmdPrintPreview::isActive(void)
|
|
{
|
|
return getGuiApplication()->sendHasMsgToActiveView("PrintPreview");
|
|
}
|
|
|
|
//===========================================================================
|
|
// Std_PrintPdf
|
|
//===========================================================================
|
|
DEF_STD_CMD_A(StdCmdPrintPdf)
|
|
|
|
StdCmdPrintPdf::StdCmdPrintPdf()
|
|
:Command("Std_PrintPdf")
|
|
{
|
|
sGroup = QT_TR_NOOP("File");
|
|
sMenuText = QT_TR_NOOP("&Export PDF...");
|
|
sToolTipText = QT_TR_NOOP("Export the document as PDF");
|
|
sWhatsThis = "Std_PrintPdf";
|
|
sStatusTip = QT_TR_NOOP("Export the document as PDF");
|
|
sPixmap = "Std_PrintPdf";
|
|
eType = 0;
|
|
}
|
|
|
|
void StdCmdPrintPdf::activated(int iMsg)
|
|
{
|
|
Q_UNUSED(iMsg);
|
|
if (getMainWindow()->activeWindow()) {
|
|
getMainWindow()->showMessage(QObject::tr("Exporting PDF..."));
|
|
getMainWindow()->activeWindow()->printPdf();
|
|
}
|
|
}
|
|
|
|
bool StdCmdPrintPdf::isActive(void)
|
|
{
|
|
return getGuiApplication()->sendHasMsgToActiveView("PrintPdf");
|
|
}
|
|
|
|
//===========================================================================
|
|
// Std_Quit
|
|
//===========================================================================
|
|
|
|
DEF_STD_CMD(StdCmdQuit)
|
|
|
|
StdCmdQuit::StdCmdQuit()
|
|
:Command("Std_Quit")
|
|
{
|
|
sGroup = QT_TR_NOOP("File");
|
|
sMenuText = QT_TR_NOOP("E&xit");
|
|
sToolTipText = QT_TR_NOOP("Quits the application");
|
|
sWhatsThis = "Std_Quit";
|
|
sStatusTip = QT_TR_NOOP("Quits the application");
|
|
#if QT_VERSION >= 0x040200
|
|
sPixmap = "application-exit";
|
|
#endif
|
|
sAccel = "Alt+F4";
|
|
eType = NoTransaction;
|
|
}
|
|
|
|
void StdCmdQuit::activated(int iMsg)
|
|
{
|
|
Q_UNUSED(iMsg);
|
|
// close the main window and exit the event loop
|
|
getMainWindow()->close();
|
|
}
|
|
|
|
//===========================================================================
|
|
// Std_Undo
|
|
//===========================================================================
|
|
|
|
DEF_STD_CMD_AC(StdCmdUndo)
|
|
|
|
StdCmdUndo::StdCmdUndo()
|
|
:Command("Std_Undo")
|
|
{
|
|
sGroup = QT_TR_NOOP("Edit");
|
|
sMenuText = QT_TR_NOOP("&Undo");
|
|
sToolTipText = QT_TR_NOOP("Undo exactly one action");
|
|
sWhatsThis = "Std_Undo";
|
|
sStatusTip = QT_TR_NOOP("Undo exactly one action");
|
|
sPixmap = "edit-undo";
|
|
sAccel = keySequenceToAccel(QKeySequence::Undo);
|
|
eType = ForEdit|NoTransaction;
|
|
}
|
|
|
|
void StdCmdUndo::activated(int iMsg)
|
|
{
|
|
Q_UNUSED(iMsg);
|
|
// Application::Instance->slotUndo();
|
|
getGuiApplication()->sendMsgToActiveView("Undo");
|
|
}
|
|
|
|
bool StdCmdUndo::isActive(void)
|
|
{
|
|
return getGuiApplication()->sendHasMsgToActiveView("Undo");
|
|
}
|
|
|
|
Action * StdCmdUndo::createAction(void)
|
|
{
|
|
Action *pcAction;
|
|
|
|
pcAction = new UndoAction(this,getMainWindow());
|
|
pcAction->setShortcut(QString::fromLatin1(sAccel));
|
|
applyCommandData(this->className(), pcAction);
|
|
if (sPixmap)
|
|
pcAction->setIcon(Gui::BitmapFactory().iconFromTheme(sPixmap));
|
|
|
|
return pcAction;
|
|
}
|
|
|
|
//===========================================================================
|
|
// Std_Redo
|
|
//===========================================================================
|
|
|
|
DEF_STD_CMD_AC(StdCmdRedo)
|
|
|
|
StdCmdRedo::StdCmdRedo()
|
|
:Command("Std_Redo")
|
|
{
|
|
sGroup = QT_TR_NOOP("Edit");
|
|
sMenuText = QT_TR_NOOP("&Redo");
|
|
sToolTipText = QT_TR_NOOP("Redoes a previously undone action");
|
|
sWhatsThis = "Std_Redo";
|
|
sStatusTip = QT_TR_NOOP("Redoes a previously undone action");
|
|
sPixmap = "edit-redo";
|
|
sAccel = keySequenceToAccel(QKeySequence::Redo);
|
|
eType = ForEdit|NoTransaction;
|
|
}
|
|
|
|
void StdCmdRedo::activated(int iMsg)
|
|
{
|
|
Q_UNUSED(iMsg);
|
|
// Application::Instance->slotRedo();
|
|
getGuiApplication()->sendMsgToActiveView("Redo");
|
|
}
|
|
|
|
bool StdCmdRedo::isActive(void)
|
|
{
|
|
return getGuiApplication()->sendHasMsgToActiveView("Redo");
|
|
}
|
|
|
|
Action * StdCmdRedo::createAction(void)
|
|
{
|
|
Action *pcAction;
|
|
|
|
pcAction = new RedoAction(this,getMainWindow());
|
|
pcAction->setShortcut(QString::fromLatin1(sAccel));
|
|
applyCommandData(this->className(), pcAction);
|
|
if (sPixmap)
|
|
pcAction->setIcon(Gui::BitmapFactory().iconFromTheme(sPixmap));
|
|
|
|
return pcAction;
|
|
}
|
|
|
|
//===========================================================================
|
|
// Std_Cut
|
|
//===========================================================================
|
|
DEF_STD_CMD_A(StdCmdCut)
|
|
|
|
StdCmdCut::StdCmdCut()
|
|
: Command("Std_Cut")
|
|
{
|
|
sGroup = QT_TR_NOOP("Edit");
|
|
sMenuText = QT_TR_NOOP("&Cut");
|
|
sToolTipText = QT_TR_NOOP("Cut out");
|
|
sWhatsThis = "Std_Cut";
|
|
sStatusTip = QT_TR_NOOP("Cut out");
|
|
sPixmap = "edit-cut";
|
|
sAccel = keySequenceToAccel(QKeySequence::Cut);
|
|
}
|
|
|
|
void StdCmdCut::activated(int iMsg)
|
|
{
|
|
Q_UNUSED(iMsg);
|
|
getGuiApplication()->sendMsgToActiveView("Cut");
|
|
}
|
|
|
|
bool StdCmdCut::isActive(void)
|
|
{
|
|
return getGuiApplication()->sendHasMsgToActiveView("Cut");
|
|
}
|
|
|
|
//===========================================================================
|
|
// Std_Copy
|
|
//===========================================================================
|
|
DEF_STD_CMD_A(StdCmdCopy)
|
|
|
|
StdCmdCopy::StdCmdCopy()
|
|
: Command("Std_Copy")
|
|
{
|
|
sGroup = QT_TR_NOOP("Edit");
|
|
sMenuText = QT_TR_NOOP("C&opy");
|
|
sToolTipText = QT_TR_NOOP("Copy operation");
|
|
sWhatsThis = "Std_Copy";
|
|
sStatusTip = QT_TR_NOOP("Copy operation");
|
|
sPixmap = "edit-copy";
|
|
sAccel = keySequenceToAccel(QKeySequence::Copy);
|
|
}
|
|
|
|
void StdCmdCopy::activated(int iMsg)
|
|
{
|
|
Q_UNUSED(iMsg);
|
|
bool done = getGuiApplication()->sendMsgToFocusView("Copy");
|
|
if (!done) {
|
|
QMimeData * mimeData = getMainWindow()->createMimeDataFromSelection();
|
|
QClipboard* cb = QApplication::clipboard();
|
|
cb->setMimeData(mimeData);
|
|
}
|
|
}
|
|
|
|
bool StdCmdCopy::isActive(void)
|
|
{
|
|
if (getGuiApplication()->sendHasMsgToFocusView("Copy"))
|
|
return true;
|
|
return Selection().hasSelection();
|
|
}
|
|
|
|
//===========================================================================
|
|
// Std_Paste
|
|
//===========================================================================
|
|
DEF_STD_CMD_A(StdCmdPaste)
|
|
|
|
StdCmdPaste::StdCmdPaste()
|
|
: Command("Std_Paste")
|
|
{
|
|
sGroup = QT_TR_NOOP("Edit");
|
|
sMenuText = QT_TR_NOOP("&Paste");
|
|
sToolTipText = QT_TR_NOOP("Paste operation");
|
|
sWhatsThis = "Std_Paste";
|
|
sStatusTip = QT_TR_NOOP("Paste operation");
|
|
sPixmap = "edit-paste";
|
|
sAccel = keySequenceToAccel(QKeySequence::Paste);
|
|
}
|
|
|
|
void StdCmdPaste::activated(int iMsg)
|
|
{
|
|
Q_UNUSED(iMsg);
|
|
bool done = getGuiApplication()->sendMsgToFocusView("Paste");
|
|
if (!done) {
|
|
QClipboard* cb = QApplication::clipboard();
|
|
const QMimeData* mimeData = cb->mimeData();
|
|
if (mimeData) {
|
|
WaitCursor wc;
|
|
getMainWindow()->insertFromMimeData(mimeData);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool StdCmdPaste::isActive(void)
|
|
{
|
|
if (getGuiApplication()->sendHasMsgToFocusView("Paste"))
|
|
return true;
|
|
QClipboard* cb = QApplication::clipboard();
|
|
const QMimeData* mime = cb->mimeData();
|
|
if (!mime) return false;
|
|
return getMainWindow()->canInsertFromMimeData(mime);
|
|
}
|
|
|
|
DEF_STD_CMD_A(StdCmdDuplicateSelection)
|
|
|
|
StdCmdDuplicateSelection::StdCmdDuplicateSelection()
|
|
:Command("Std_DuplicateSelection")
|
|
{
|
|
sAppModule = "Edit";
|
|
sGroup = QT_TR_NOOP("Edit");
|
|
sMenuText = QT_TR_NOOP("Duplicate selection");
|
|
sToolTipText = QT_TR_NOOP("Put duplicates of the selected objects to the active document");
|
|
sWhatsThis = "Std_DuplicateSelection";
|
|
sStatusTip = QT_TR_NOOP("Put duplicates of the selected objects to the active document");
|
|
sPixmap = "Std_DuplicateSelection";
|
|
}
|
|
|
|
void StdCmdDuplicateSelection::activated(int iMsg)
|
|
{
|
|
Q_UNUSED(iMsg);
|
|
std::vector<App::DocumentObject*> sel;
|
|
std::set<App::DocumentObject*> objSet;
|
|
for(auto &s : Selection().getCompleteSelection()) {
|
|
if(s.pObject && s.pObject->getNameInDocument() && objSet.insert(s.pObject).second)
|
|
sel.push_back(s.pObject);
|
|
}
|
|
if(sel.empty())
|
|
return;
|
|
|
|
bool hasXLink = false;
|
|
Base::FileInfo fi(App::Application::getTempFileName());
|
|
{
|
|
auto all = App::Document::getDependencyList(sel);
|
|
if (all.size() > sel.size()) {
|
|
DlgObjectSelection dlg(sel,getMainWindow());
|
|
if(dlg.exec()!=QDialog::Accepted)
|
|
return;
|
|
sel = dlg.getSelections();
|
|
if(sel.empty())
|
|
return;
|
|
}
|
|
std::vector<App::Document*> unsaved;
|
|
hasXLink = App::PropertyXLink::hasXLink(sel,&unsaved);
|
|
if(unsaved.size()) {
|
|
QMessageBox::critical(getMainWindow(), QObject::tr("Unsaved document"),
|
|
QObject::tr("The exported object contains external link. Please save the document"
|
|
"at least once before exporting."));
|
|
return;
|
|
}
|
|
|
|
// save stuff to file
|
|
Base::ofstream str(fi, std::ios::out | std::ios::binary);
|
|
App::Document* doc = sel.front()->getDocument();
|
|
MergeDocuments mimeView(doc);
|
|
doc->exportObjects(sel, str);
|
|
str.close();
|
|
}
|
|
App::Document* doc = App::GetApplication().getActiveDocument();
|
|
if (doc) {
|
|
bool proceed = true;
|
|
if(hasXLink && !doc->isSaved()) {
|
|
int ret = QMessageBox::question(getMainWindow(),
|
|
qApp->translate("Std_DuplicateSelection","Object dependencies"),
|
|
qApp->translate("Std_DuplicateSelection",
|
|
"To link to external objects, the document must be saved at least once.\n"
|
|
"Do you want to save the document now?"),
|
|
QMessageBox::Yes,QMessageBox::No);
|
|
if(ret == QMessageBox::Yes)
|
|
proceed = Application::Instance->getDocument(doc)->saveAs();
|
|
}
|
|
if(proceed) {
|
|
doc->openTransaction("Duplicate");
|
|
// restore objects from file and add to active document
|
|
Base::ifstream str(fi, std::ios::in | std::ios::binary);
|
|
MergeDocuments mimeView(doc);
|
|
mimeView.importObjects(str);
|
|
str.close();
|
|
doc->commitTransaction();
|
|
}
|
|
}
|
|
fi.deleteFile();
|
|
}
|
|
|
|
bool StdCmdDuplicateSelection::isActive(void)
|
|
{
|
|
return Gui::Selection().hasSelection();
|
|
}
|
|
|
|
//===========================================================================
|
|
// Std_SelectAll
|
|
//===========================================================================
|
|
|
|
DEF_STD_CMD_A(StdCmdSelectAll)
|
|
|
|
StdCmdSelectAll::StdCmdSelectAll()
|
|
: Command("Std_SelectAll")
|
|
{
|
|
sGroup = QT_TR_NOOP("Edit");
|
|
sMenuText = QT_TR_NOOP("Select &All");
|
|
sToolTipText = QT_TR_NOOP("Select all");
|
|
sWhatsThis = "Std_SelectAll";
|
|
sStatusTip = QT_TR_NOOP("Select all");
|
|
#if QT_VERSION >= 0x040200
|
|
sPixmap = "edit-select-all";
|
|
#endif
|
|
//sAccel = "Ctrl+A"; // superseeds shortcuts for text edits
|
|
}
|
|
|
|
void StdCmdSelectAll::activated(int iMsg)
|
|
{
|
|
Q_UNUSED(iMsg);
|
|
SelectionSingleton& rSel = Selection();
|
|
App::Document* doc = App::GetApplication().getActiveDocument();
|
|
std::vector<App::DocumentObject*> objs = doc->getObjectsOfType(App::DocumentObject::getClassTypeId());
|
|
rSel.setSelection(doc->getName(), objs);
|
|
}
|
|
|
|
bool StdCmdSelectAll::isActive(void)
|
|
{
|
|
return App::GetApplication().getActiveDocument() != 0;
|
|
}
|
|
|
|
//===========================================================================
|
|
// Std_Delete
|
|
//===========================================================================
|
|
DEF_STD_CMD_A(StdCmdDelete)
|
|
|
|
StdCmdDelete::StdCmdDelete()
|
|
:Command("Std_Delete")
|
|
{
|
|
sGroup = QT_TR_NOOP("Edit");
|
|
sMenuText = QT_TR_NOOP("&Delete");
|
|
sToolTipText = QT_TR_NOOP("Deletes the selected objects");
|
|
sWhatsThis = "Std_Delete";
|
|
sStatusTip = QT_TR_NOOP("Deletes the selected objects");
|
|
#if QT_VERSION >= 0x040200
|
|
sPixmap = "edit-delete";
|
|
#endif
|
|
sAccel = keySequenceToAccel(QKeySequence::Delete);
|
|
eType = ForEdit;
|
|
}
|
|
|
|
void StdCmdDelete::activated(int iMsg)
|
|
{
|
|
Q_UNUSED(iMsg);
|
|
|
|
std::set<App::Document*> docs;
|
|
try {
|
|
openCommand(QT_TRANSLATE_NOOP("Command", "Delete"));
|
|
if (getGuiApplication()->sendHasMsgToFocusView(getName())) {
|
|
commitCommand();
|
|
return;
|
|
}
|
|
|
|
App::TransactionLocker tlock;
|
|
|
|
Gui::getMainWindow()->setUpdatesEnabled(false);
|
|
auto editDoc = Application::Instance->editDocument();
|
|
ViewProviderDocumentObject *vpedit = 0;
|
|
if(editDoc)
|
|
vpedit = dynamic_cast<ViewProviderDocumentObject*>(editDoc->getInEdit());
|
|
if(vpedit) {
|
|
for(auto &sel : Selection().getSelectionEx(editDoc->getDocument()->getName())) {
|
|
if(sel.getObject() == vpedit->getObject()) {
|
|
if (!sel.getSubNames().empty()) {
|
|
vpedit->onDelete(sel.getSubNames());
|
|
docs.insert(editDoc->getDocument());
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
std::set<QString> affectedLabels;
|
|
bool more = false;
|
|
auto sels = Selection().getSelectionEx();
|
|
bool autoDeletion = true;
|
|
for(auto &sel : sels) {
|
|
auto obj = sel.getObject();
|
|
for(auto parent : obj->getInList()) {
|
|
if(!Selection().isSelected(parent)) {
|
|
ViewProvider* vp = Application::Instance->getViewProvider(parent);
|
|
if (vp && !vp->canDelete(obj)) {
|
|
autoDeletion = false;
|
|
QString label;
|
|
if(parent->getDocument() != obj->getDocument())
|
|
label = QLatin1String(parent->getFullName().c_str());
|
|
else
|
|
label = QLatin1String(parent->getNameInDocument());
|
|
if(parent->Label.getStrValue() != parent->getNameInDocument())
|
|
label += QString::fromLatin1(" (%1)").arg(
|
|
QString::fromUtf8(parent->Label.getValue()));
|
|
affectedLabels.insert(label);
|
|
if(affectedLabels.size()>=10) {
|
|
more = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if(more)
|
|
break;
|
|
}
|
|
|
|
// The check below is not needed because we now only get selection
|
|
// from the active document
|
|
#if 0
|
|
//check for inactive objects in selection Mantis #3477
|
|
std::set<QString> inactiveLabels;
|
|
App::Application& app = App::GetApplication();
|
|
App::Document* actDoc = app.getActiveDocument();
|
|
for (std::vector<Gui::SelectionObject>::iterator ft = sels.begin(); ft != sels.end(); ++ft) {
|
|
App::DocumentObject* obj = ft->getObject();
|
|
App::Document* objDoc = obj->getDocument();
|
|
if (actDoc != objDoc) {
|
|
inactiveLabels.insert(QString::fromUtf8(obj->Label.getValue()));
|
|
autoDeletion = false;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if (!autoDeletion) {
|
|
QString bodyMessage;
|
|
QTextStream bodyMessageStream(&bodyMessage);
|
|
bodyMessageStream << qApp->translate("Std_Delete",
|
|
"The following referencing objects might break.\n\n"
|
|
"Are you sure you want to continue?\n");
|
|
for (const auto ¤tLabel : affectedLabels)
|
|
bodyMessageStream << '\n' << currentLabel;
|
|
if(more)
|
|
bodyMessageStream << "\n...";
|
|
#if 0
|
|
//message for inactive items
|
|
if (!inactiveLabels.empty()) {
|
|
if (!affectedLabels.empty()) {
|
|
bodyMessageStream << "\n";
|
|
}
|
|
std::string thisDoc = pGuiDoc->getDocument()->getName();
|
|
bodyMessageStream << qApp->translate("Std_Delete",
|
|
"These items are selected for deletion, but are not in the active document.");
|
|
for (const auto ¤tLabel : inactiveLabels)
|
|
bodyMessageStream << currentLabel << " / " << Base::Tools::fromStdString(thisDoc) << '\n';
|
|
}
|
|
#endif
|
|
|
|
int ret = QMessageBox::warning(Gui::getMainWindow(),
|
|
qApp->translate("Std_Delete", "Object dependencies"), bodyMessage,
|
|
QMessageBox::Yes, QMessageBox::No);
|
|
if (ret == QMessageBox::Yes)
|
|
autoDeletion = true;
|
|
}
|
|
if (autoDeletion) {
|
|
for(auto &sel : sels) {
|
|
auto obj = sel.getObject();
|
|
Gui::ViewProvider* vp = Application::Instance->getViewProvider(obj);
|
|
if (vp) {
|
|
// ask the ViewProvider if it wants to do some clean up
|
|
if (vp->onDelete(sel.getSubNames())) {
|
|
FCMD_OBJ_DOC_CMD(obj,"removeObject('" << obj->getNameInDocument() << "')");
|
|
docs.insert(obj->getDocument());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if(docs.size()) {
|
|
const auto &outList = App::PropertyXLink::getDocumentOutList();
|
|
for(auto it=docs.begin();it!=docs.end();++it) {
|
|
auto itd = outList.find(*it);
|
|
if(itd!=outList.end()) {
|
|
for(auto doc : itd->second) {
|
|
if(doc != *it)
|
|
docs.erase(doc);
|
|
}
|
|
}
|
|
}
|
|
for(auto doc : docs) {
|
|
FCMD_DOC_CMD(doc,"recompute()");
|
|
}
|
|
}
|
|
} catch (const Base::Exception& e) {
|
|
QMessageBox::critical(getMainWindow(), QObject::tr("Delete failed"),
|
|
QString::fromLatin1(e.what()));
|
|
e.ReportException();
|
|
} catch (...) {
|
|
QMessageBox::critical(getMainWindow(), QObject::tr("Delete failed"),
|
|
QString::fromLatin1("Unknown error"));
|
|
}
|
|
commitCommand();
|
|
Gui::getMainWindow()->setUpdatesEnabled(true);
|
|
Gui::getMainWindow()->update();
|
|
}
|
|
|
|
bool StdCmdDelete::isActive(void)
|
|
{
|
|
return Selection().getCompleteSelection().size() > 0;
|
|
}
|
|
|
|
//===========================================================================
|
|
// Std_Refresh
|
|
//===========================================================================
|
|
DEF_STD_CMD_A(StdCmdRefresh)
|
|
|
|
StdCmdRefresh::StdCmdRefresh()
|
|
: Command("Std_Refresh")
|
|
{
|
|
sGroup = QT_TR_NOOP("Edit");
|
|
sMenuText = QT_TR_NOOP("&Refresh");
|
|
sToolTipText = QT_TR_NOOP("Recomputes the current active document");
|
|
sWhatsThis = "Std_Refresh";
|
|
sStatusTip = QT_TR_NOOP("Recomputes the current active document");
|
|
sPixmap = "view-refresh";
|
|
sAccel = keySequenceToAccel(QKeySequence::Refresh);
|
|
eType = AlterDoc | Alter3DView | AlterSelection | ForEdit;
|
|
bCanLog = false;
|
|
|
|
// Make it optional to create a transaction for a recompute.
|
|
// The new default behaviour is quite cumbersome in some cases because when
|
|
// undoing the last transaction the manual recompute will clear the redo stack.
|
|
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
|
|
"User parameter:BaseApp/Preferences/Document");
|
|
bool create = hGrp->GetBool("TransactionOnRecompute", false);
|
|
if (!create)
|
|
eType = eType | NoTransaction;
|
|
}
|
|
|
|
void StdCmdRefresh::activated(int iMsg)
|
|
{
|
|
Q_UNUSED(iMsg);
|
|
if (getActiveGuiDocument()) {
|
|
App::AutoTransaction trans((eType & NoTransaction) ? nullptr : "Recompute");
|
|
try {
|
|
doCommand(Doc,"App.activeDocument().recompute(None,True,True)");
|
|
}
|
|
catch (Base::Exception& /*e*/) {
|
|
int ret = QMessageBox::warning(getMainWindow(), QObject::tr("Dependency error"),
|
|
qApp->translate("Std_Refresh", "The document contains dependency cycles.\n"
|
|
"Please check the Report View for more details.\n\n"
|
|
"Do you still want to proceed?"),
|
|
QMessageBox::Yes, QMessageBox::No);
|
|
if(ret == QMessageBox::No)
|
|
return;
|
|
doCommand(Doc,"App.activeDocument().recompute(None,True)");
|
|
}
|
|
}
|
|
}
|
|
|
|
bool StdCmdRefresh::isActive(void)
|
|
{
|
|
return this->getDocument() && this->getDocument()->mustExecute();
|
|
}
|
|
|
|
//===========================================================================
|
|
// Std_Transform
|
|
//===========================================================================
|
|
DEF_STD_CMD_A(StdCmdTransform)
|
|
|
|
StdCmdTransform::StdCmdTransform()
|
|
: Command("Std_Transform")
|
|
{
|
|
sGroup = QT_TR_NOOP("Edit");
|
|
sMenuText = QT_TR_NOOP("Transform...");
|
|
sToolTipText = QT_TR_NOOP("Transform the geometry of selected objects");
|
|
sStatusTip = QT_TR_NOOP("Transform the geometry of selected objects");
|
|
sWhatsThis = "Std_Transform";
|
|
}
|
|
|
|
void StdCmdTransform::activated(int iMsg)
|
|
{
|
|
Q_UNUSED(iMsg);
|
|
Gui::Control().showDialog(new Gui::Dialog::TaskTransform());
|
|
}
|
|
|
|
bool StdCmdTransform::isActive(void)
|
|
{
|
|
return (Gui::Control().activeDialog()==0);
|
|
}
|
|
|
|
//===========================================================================
|
|
// Std_Placement
|
|
//===========================================================================
|
|
DEF_STD_CMD_A(StdCmdPlacement)
|
|
|
|
StdCmdPlacement::StdCmdPlacement()
|
|
: Command("Std_Placement")
|
|
{
|
|
sGroup = QT_TR_NOOP("Edit");
|
|
sMenuText = QT_TR_NOOP("Placement...");
|
|
sToolTipText = QT_TR_NOOP("Place the selected objects");
|
|
sStatusTip = QT_TR_NOOP("Place the selected objects");
|
|
sWhatsThis = "Std_Placement";
|
|
sPixmap = "Std_Placement";
|
|
}
|
|
|
|
void StdCmdPlacement::activated(int iMsg)
|
|
{
|
|
Q_UNUSED(iMsg);
|
|
std::vector<App::DocumentObject*> sel = Gui::Selection().getObjectsOfType(App::GeoFeature::getClassTypeId());
|
|
Gui::Dialog::TaskPlacement* plm = new Gui::Dialog::TaskPlacement();
|
|
if (!sel.empty()) {
|
|
App::Property* prop = sel.front()->getPropertyByName("Placement");
|
|
if (prop && prop->getTypeId() == App::PropertyPlacement::getClassTypeId())
|
|
plm->setPlacement(static_cast<App::PropertyPlacement*>(prop)->getValue());
|
|
}
|
|
Gui::Control().showDialog(plm);
|
|
}
|
|
|
|
bool StdCmdPlacement::isActive(void)
|
|
{
|
|
return (Gui::Control().activeDialog()==0);
|
|
}
|
|
|
|
//===========================================================================
|
|
// Std_TransformManip
|
|
//===========================================================================
|
|
DEF_STD_CMD_A(StdCmdTransformManip)
|
|
|
|
StdCmdTransformManip::StdCmdTransformManip()
|
|
: Command("Std_TransformManip")
|
|
{
|
|
sGroup = QT_TR_NOOP("Edit");
|
|
sMenuText = QT_TR_NOOP("Transform");
|
|
sToolTipText = QT_TR_NOOP("Transform the selected object in the 3d view");
|
|
sStatusTip = QT_TR_NOOP("Transform the selected object in the 3d view");
|
|
sWhatsThis = "Std_TransformManip";
|
|
}
|
|
|
|
void StdCmdTransformManip::activated(int iMsg)
|
|
{
|
|
Q_UNUSED(iMsg);
|
|
if (getActiveGuiDocument()->getInEdit())
|
|
getActiveGuiDocument()->resetEdit();
|
|
std::vector<App::DocumentObject*> sel = Gui::Selection().getObjectsOfType(App::GeoFeature::getClassTypeId());
|
|
Gui::ViewProvider* vp = Application::Instance->getViewProvider(sel.front());
|
|
// FIXME: Need a way to force 'Transform' edit mode
|
|
// #0000477: Proper interface for edit modes of view provider
|
|
if (vp)
|
|
getActiveGuiDocument()->setEdit(vp, Gui::ViewProvider::Transform);
|
|
}
|
|
|
|
bool StdCmdTransformManip::isActive(void)
|
|
{
|
|
return Gui::Selection().countObjectsOfType(App::GeoFeature::getClassTypeId()) == 1;
|
|
}
|
|
|
|
//===========================================================================
|
|
// Std_Alignment
|
|
//===========================================================================
|
|
DEF_STD_CMD_A(StdCmdAlignment)
|
|
|
|
StdCmdAlignment::StdCmdAlignment()
|
|
: Command("Std_Alignment")
|
|
{
|
|
sGroup = QT_TR_NOOP("Edit");
|
|
sMenuText = QT_TR_NOOP("Alignment...");
|
|
sToolTipText = QT_TR_NOOP("Align the selected objects");
|
|
sStatusTip = QT_TR_NOOP("Align the selected objects");
|
|
sWhatsThis = "Std_Alignment";
|
|
sPixmap = "Std_Alignment";
|
|
}
|
|
|
|
void StdCmdAlignment::activated(int iMsg)
|
|
{
|
|
Q_UNUSED(iMsg);
|
|
std::vector<App::DocumentObject*> sel = Gui::Selection().getObjectsOfType
|
|
(App::GeoFeature::getClassTypeId());
|
|
ManualAlignment* align = ManualAlignment::instance();
|
|
QObject::connect(align, SIGNAL(emitCanceled()), align, SLOT(deleteLater()));
|
|
QObject::connect(align, SIGNAL(emitFinished()), align, SLOT(deleteLater()));
|
|
|
|
// Get the fixed and moving meshes
|
|
FixedGroup fixedGroup;
|
|
std::map<int, MovableGroup> groupMap;
|
|
fixedGroup.addView(sel[0]);
|
|
groupMap[0].addView(sel[1]);
|
|
|
|
// add the fixed group
|
|
align->setFixedGroup(fixedGroup);
|
|
|
|
// create the model of movable groups
|
|
MovableGroupModel model;
|
|
model.addGroups(groupMap);
|
|
align->setModel(model);
|
|
Base::Type style = Base::Type::fromName("Gui::CADNavigationStyle");
|
|
Base::Vector3d upDir(0,1,0), viewDir(0,0,-1);
|
|
Gui::Document* doc = Application::Instance->activeDocument();
|
|
if (doc) {
|
|
View3DInventor* mdi = qobject_cast<View3DInventor*>(doc->getActiveView());
|
|
if (mdi) {
|
|
View3DInventorViewer* viewer = mdi->getViewer();
|
|
SoCamera* camera = viewer->getSoRenderManager()->getCamera();
|
|
if (camera) {
|
|
SbVec3f up(0,1,0), dir(0,0,-1);
|
|
camera->orientation.getValue().multVec(dir, dir);
|
|
viewDir.Set(dir[0],dir[1],dir[2]);
|
|
camera->orientation.getValue().multVec(up, up);
|
|
upDir.Set(up[0],up[1],up[2]);
|
|
}
|
|
style = viewer->navigationStyle()->getTypeId();
|
|
}
|
|
}
|
|
|
|
align->setMinPoints(1);
|
|
align->startAlignment(style);
|
|
align->setViewingDirections(viewDir,upDir, viewDir,upDir);
|
|
Gui::Selection().clearSelection();
|
|
}
|
|
|
|
bool StdCmdAlignment::isActive(void)
|
|
{
|
|
if (ManualAlignment::hasInstance())
|
|
return false;
|
|
return Gui::Selection().countObjectsOfType(App::GeoFeature::getClassTypeId()) == 2;
|
|
}
|
|
|
|
//===========================================================================
|
|
// Std_Edit
|
|
//===========================================================================
|
|
DEF_STD_CMD_A(StdCmdEdit)
|
|
|
|
StdCmdEdit::StdCmdEdit()
|
|
: Command("Std_Edit")
|
|
{
|
|
sGroup = QT_TR_NOOP("Edit");
|
|
sMenuText = QT_TR_NOOP("Toggle &Edit mode");
|
|
sToolTipText = QT_TR_NOOP("Toggles the selected object's edit mode");
|
|
sWhatsThis = "Std_Edit";
|
|
sStatusTip = QT_TR_NOOP("Activates or Deactivates the selected object's edit mode");
|
|
sAccel = "";
|
|
#if QT_VERSION >= 0x040200
|
|
sPixmap = "edit-edit";
|
|
#endif
|
|
eType = ForEdit;
|
|
}
|
|
|
|
void StdCmdEdit::activated(int iMsg)
|
|
{
|
|
Q_UNUSED(iMsg);
|
|
Gui::MDIView* view = Gui::getMainWindow()->activeWindow();
|
|
if (view && view->isDerivedFrom(Gui::View3DInventor::getClassTypeId())) {
|
|
Gui::View3DInventorViewer* viewer = static_cast<Gui::View3DInventor*>(view)->getViewer();
|
|
if (viewer->isEditingViewProvider()) {
|
|
doCommand(Command::Gui,"Gui.activeDocument().resetEdit()");
|
|
} else {
|
|
if (Selection().getCompleteSelection().size() > 0) {
|
|
SelectionSingleton::SelObj obj = Selection().getCompleteSelection()[0];
|
|
doCommand(Command::Gui,"Gui.activeDocument().setEdit(\"%s\",0)",obj.FeatName);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool StdCmdEdit::isActive(void)
|
|
{
|
|
return (Selection().getCompleteSelection().size() > 0) || (Gui::Control().activeDialog() != 0);
|
|
}
|
|
|
|
//======================================================================
|
|
// StdCmdExpression
|
|
//===========================================================================
|
|
class StdCmdExpression : public Gui::Command
|
|
{
|
|
public:
|
|
StdCmdExpression() : Command("Std_Expressions")
|
|
, pcActionCopyAll(nullptr)
|
|
, pcActionCopySel(nullptr)
|
|
, pcActionCopyActive(nullptr)
|
|
, pcActionPaste(nullptr)
|
|
{
|
|
sGroup = QT_TR_NOOP("Edit");
|
|
sMenuText = QT_TR_NOOP("Expression actions");
|
|
sToolTipText = QT_TR_NOOP("Expression actions");
|
|
sWhatsThis = "Std_Expressions";
|
|
sStatusTip = QT_TR_NOOP("Expression actions");
|
|
eType = ForEdit;
|
|
}
|
|
|
|
virtual const char* className() const {return "StdCmdExpression";}
|
|
protected:
|
|
|
|
virtual void activated(int iMsg) {
|
|
std::map<App::Document*, std::set<App::DocumentObject*> > objs;
|
|
switch(iMsg) {
|
|
case 0:
|
|
for(auto &sel : Selection().getCompleteSelection())
|
|
objs[sel.pObject->getDocument()].insert(sel.pObject);
|
|
break;
|
|
case 1:
|
|
if(App::GetApplication().getActiveDocument()) {
|
|
auto doc = App::GetApplication().getActiveDocument();
|
|
auto array = doc->getObjects();
|
|
auto &set = objs[doc];
|
|
set.insert(array.begin(),array.end());
|
|
}
|
|
break;
|
|
case 2:
|
|
for(auto doc : App::GetApplication().getDocuments()) {
|
|
auto &set = objs[doc];
|
|
auto array = doc->getObjects();
|
|
set.insert(array.begin(),array.end());
|
|
}
|
|
break;
|
|
case 3:
|
|
pasteExpressions();
|
|
break;
|
|
}
|
|
copyExpressions(objs);
|
|
}
|
|
|
|
virtual Gui::Action * createAction(void) {
|
|
ActionGroup* pcAction = new ActionGroup(this, getMainWindow());
|
|
pcAction->setDropDownMenu(true);
|
|
applyCommandData(this->className(), pcAction);
|
|
|
|
pcActionCopySel = pcAction->addAction(QObject::tr("Copy selected"));
|
|
pcActionCopyActive = pcAction->addAction(QObject::tr("Copy active document"));
|
|
pcActionCopyAll = pcAction->addAction(QObject::tr("Copy all documents"));
|
|
pcActionPaste = pcAction->addAction(QObject::tr("Paste"));
|
|
|
|
return pcAction;
|
|
}
|
|
|
|
void copyExpressions(const std::map<App::Document*, std::set<App::DocumentObject*> > &objs) {
|
|
std::ostringstream ss;
|
|
std::vector<App::Property*> props;
|
|
for(auto &v : objs) {
|
|
for(auto obj : v.second) {
|
|
props.clear();
|
|
obj->getPropertyList(props);
|
|
for(auto prop : props) {
|
|
auto p = dynamic_cast<App::PropertyExpressionContainer*>(prop);
|
|
if(!p) continue;
|
|
for(auto &v : p->getExpressions()) {
|
|
ss << "##@@ " << v.first.toString() << ' '
|
|
<< obj->getFullName() << '.' << p->getName()
|
|
<< " (" << obj->Label.getValue() << ')' << std::endl;
|
|
ss << "##@@";
|
|
if(v.second->comment.size()) {
|
|
if(v.second->comment[0] == '&'
|
|
|| v.second->comment.find('\n') != std::string::npos
|
|
|| v.second->comment.find('\r') != std::string::npos)
|
|
{
|
|
std::string comment = v.second->comment;
|
|
boost::replace_all(comment,"&","&");
|
|
boost::replace_all(comment,"\n"," ");
|
|
boost::replace_all(comment,"\r"," ");
|
|
ss << '&' << comment;
|
|
}else
|
|
ss << v.second->comment;
|
|
}
|
|
ss << std::endl << v.second->toString(true) << std::endl << std::endl;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
QApplication::clipboard()->setText(QString::fromUtf8(ss.str().c_str()));
|
|
}
|
|
|
|
void pasteExpressions() {
|
|
std::map<App::Document*, std::map<App::PropertyExpressionContainer*,
|
|
std::map<App::ObjectIdentifier, App::ExpressionPtr> > > exprs;
|
|
|
|
bool failed = false;
|
|
std::string txt = QApplication::clipboard()->text().toUtf8().constData();
|
|
const char *tstart = txt.c_str();
|
|
const char *tend = tstart + txt.size();
|
|
|
|
static boost::regex rule("^##@@ ([^ ]+) (\\w+)#(\\w+)\\.(\\w+) [^\n]+\n##@@([^\n]*)\n");
|
|
boost::cmatch m;
|
|
if(!boost::regex_search(tstart,m,rule)) {
|
|
FC_WARN("No expression header found");
|
|
return;
|
|
}
|
|
boost::cmatch m2;
|
|
bool found = true;
|
|
for(;found;m=m2) {
|
|
found = boost::regex_search(m[0].second,tend,m2,rule);
|
|
|
|
auto pathName = m.str(1);
|
|
auto docName = m.str(2);
|
|
auto objName = m.str(3);
|
|
auto propName = m.str(4);
|
|
auto comment = m.str(5);
|
|
|
|
App::Document *doc = App::GetApplication().getDocument(docName.c_str());
|
|
if(!doc) {
|
|
FC_WARN("Cannot find document '" << docName << "'");
|
|
continue;
|
|
}
|
|
|
|
auto obj = doc->getObject(objName.c_str());
|
|
if(!obj) {
|
|
FC_WARN("Cannot find object '" << docName << '#' << objName << "'");
|
|
continue;
|
|
}
|
|
|
|
auto prop = dynamic_cast<App::PropertyExpressionContainer*>(
|
|
obj->getPropertyByName(propName.c_str()));
|
|
if(!prop) {
|
|
FC_WARN("Invalid property '" << docName << '#' << objName << '.' << propName << "'");
|
|
continue;
|
|
}
|
|
|
|
size_t len = (found?m2[0].first:tend) - m[0].second;
|
|
try {
|
|
App::ExpressionPtr expr(App::Expression::parse(obj,std::string(m[0].second,len)));
|
|
if(expr && comment.size()) {
|
|
if(comment[0] == '&') {
|
|
expr->comment = comment.c_str()+1;
|
|
boost::replace_all(expr->comment,"&","&");
|
|
boost::replace_all(expr->comment," ","\n");
|
|
boost::replace_all(expr->comment," ","\r");
|
|
} else
|
|
expr->comment = comment;
|
|
}
|
|
exprs[doc][prop][App::ObjectIdentifier::parse(obj,pathName)] = std::move(expr);
|
|
} catch(Base::Exception &e) {
|
|
FC_ERR(e.what() << std::endl << m[0].str());
|
|
failed = true;
|
|
}
|
|
}
|
|
if(failed) {
|
|
QMessageBox::critical(getMainWindow(), QObject::tr("Expression error"),
|
|
QObject::tr("Failed to parse some of the expressions.\n"
|
|
"Please check the Report View for more details."));
|
|
return;
|
|
}
|
|
|
|
openCommand(QT_TRANSLATE_NOOP("Command", "Paste expressions"));
|
|
try {
|
|
for(auto &v : exprs) {
|
|
for(auto &v2 : v.second) {
|
|
auto &expressions = v2.second;
|
|
auto old = v2.first->getExpressions();
|
|
for(auto it=expressions.begin(),itNext=it;it!=expressions.end();it=itNext) {
|
|
++itNext;
|
|
auto iter = old.find(it->first);
|
|
if(iter != old.end() && it->second->isSame(*iter->second))
|
|
expressions.erase(it);
|
|
}
|
|
if(expressions.size())
|
|
v2.first->setExpressions(std::move(expressions));
|
|
}
|
|
}
|
|
commitCommand();
|
|
} catch (const Base::Exception& e) {
|
|
abortCommand();
|
|
QMessageBox::critical(getMainWindow(), QObject::tr("Failed to paste expressions"),
|
|
QString::fromLatin1(e.what()));
|
|
e.ReportException();
|
|
}
|
|
}
|
|
|
|
bool isActive() {
|
|
if(!App::GetApplication().getActiveDocument()) {
|
|
pcActionCopyAll->setEnabled(false);
|
|
pcActionCopySel->setEnabled(false);
|
|
pcActionCopyActive->setEnabled(false);
|
|
pcActionPaste->setEnabled(false);
|
|
return true;
|
|
}
|
|
pcActionCopyActive->setEnabled(true);
|
|
pcActionCopyAll->setEnabled(true);
|
|
pcActionCopySel->setEnabled(Selection().hasSelection());
|
|
|
|
pcActionPaste->setEnabled(
|
|
QApplication::clipboard()->text().startsWith(QLatin1String("##@@ ")));
|
|
return true;
|
|
}
|
|
|
|
QAction *pcActionCopyAll;
|
|
QAction *pcActionCopySel;
|
|
QAction *pcActionCopyActive;
|
|
QAction *pcActionPaste;
|
|
};
|
|
|
|
namespace Gui {
|
|
|
|
void CreateDocCommands(void)
|
|
{
|
|
CommandManager &rcCmdMgr = Application::Instance->commandManager();
|
|
|
|
rcCmdMgr.addCommand(new StdCmdNew());
|
|
rcCmdMgr.addCommand(new StdCmdOpen());
|
|
rcCmdMgr.addCommand(new StdCmdImport());
|
|
rcCmdMgr.addCommand(new StdCmdExport());
|
|
rcCmdMgr.addCommand(new StdCmdMergeProjects());
|
|
rcCmdMgr.addCommand(new StdCmdDependencyGraph());
|
|
|
|
rcCmdMgr.addCommand(new StdCmdSave());
|
|
rcCmdMgr.addCommand(new StdCmdSaveAs());
|
|
rcCmdMgr.addCommand(new StdCmdSaveCopy());
|
|
rcCmdMgr.addCommand(new StdCmdSaveAll());
|
|
rcCmdMgr.addCommand(new StdCmdRevert());
|
|
rcCmdMgr.addCommand(new StdCmdProjectInfo());
|
|
rcCmdMgr.addCommand(new StdCmdProjectUtil());
|
|
rcCmdMgr.addCommand(new StdCmdUndo());
|
|
rcCmdMgr.addCommand(new StdCmdRedo());
|
|
rcCmdMgr.addCommand(new StdCmdPrint());
|
|
rcCmdMgr.addCommand(new StdCmdPrintPreview());
|
|
rcCmdMgr.addCommand(new StdCmdPrintPdf());
|
|
rcCmdMgr.addCommand(new StdCmdQuit());
|
|
rcCmdMgr.addCommand(new StdCmdCut());
|
|
rcCmdMgr.addCommand(new StdCmdCopy());
|
|
rcCmdMgr.addCommand(new StdCmdPaste());
|
|
rcCmdMgr.addCommand(new StdCmdDuplicateSelection());
|
|
rcCmdMgr.addCommand(new StdCmdSelectAll());
|
|
rcCmdMgr.addCommand(new StdCmdDelete());
|
|
rcCmdMgr.addCommand(new StdCmdRefresh());
|
|
rcCmdMgr.addCommand(new StdCmdTransform());
|
|
rcCmdMgr.addCommand(new StdCmdPlacement());
|
|
rcCmdMgr.addCommand(new StdCmdTransformManip());
|
|
rcCmdMgr.addCommand(new StdCmdAlignment());
|
|
rcCmdMgr.addCommand(new StdCmdEdit());
|
|
rcCmdMgr.addCommand(new StdCmdExpression());
|
|
}
|
|
|
|
} // namespace Gui
|