diff --git a/src/App/Document.cpp b/src/App/Document.cpp index 7e14227cd9..bf07d270b8 100644 --- a/src/App/Document.cpp +++ b/src/App/Document.cpp @@ -1189,6 +1189,14 @@ Document::ExportStatus Document::isExporting(const DocumentObject* obj) const } return Document::NotExporting; } +ExportInfo Document::exportInfo() const +{ + return d->exportInfo; +} +void Document::setExportInfo(const ExportInfo& info) +{ + d->exportInfo = info; +} void Document::exportObjects(const std::vector& obj, std::ostream& out) { diff --git a/src/App/Document.h b/src/App/Document.h index e15978cd1c..e52fe993b9 100644 --- a/src/App/Document.h +++ b/src/App/Document.h @@ -33,6 +33,7 @@ #include "PropertyContainer.h" #include "PropertyLinks.h" #include "PropertyStandard.h" +#include "ExportInfo.h" #include #include @@ -246,6 +247,8 @@ public: Exporting, }; ExportStatus isExporting(const DocumentObject* obj) const; + ExportInfo exportInfo() const; + void setExportInfo(const ExportInfo& info); void exportObjects(const std::vector&, std::ostream&); void exportGraphviz(std::ostream&) const; std::vector importObjects(Base::XMLReader& reader); diff --git a/src/App/ExportInfo.h b/src/App/ExportInfo.h new file mode 100644 index 0000000000..3fedc0ccbe --- /dev/null +++ b/src/App/ExportInfo.h @@ -0,0 +1,26 @@ + +#ifndef SRC_APP_EXPORTINFO_H_ +#define SRC_APP_EXPORTINFO_H_ + +#include "DocumentObject.h" + +#include + +namespace App +{ + +/// Struct that holds information about the last +/// export so that the user does not have to reenter +/// them on each export. The export command either uses +/// the target document's export info +struct ExportInfo { + std::string location {}; + std::string filename {}; + std::string filter {}; + bool generatedName {false}; + App::DocumentObject* object {nullptr}; +}; + +} + +#endif diff --git a/src/App/private/DocumentP.h b/src/App/private/DocumentP.h index 924a1c5430..022f48c90b 100644 --- a/src/App/private/DocumentP.h +++ b/src/App/private/DocumentP.h @@ -42,6 +42,7 @@ #include #include #include +#include #include // using VertexProperty = boost::property; @@ -95,6 +96,7 @@ struct DocumentP mutable HasherMap hashers; std::multimap> _RecomputeLog; + ExportInfo exportInfo; StringHasherRef Hasher {new StringHasher}; diff --git a/src/Gui/CommandDoc.cpp b/src/Gui/CommandDoc.cpp index a2136170e3..60b5f6fc26 100644 --- a/src/Gui/CommandDoc.cpp +++ b/src/Gui/CommandDoc.cpp @@ -400,12 +400,6 @@ void StdCmdExport::activated(int iMsg) { Q_UNUSED(iMsg); - static QString lastExportFullPath = QString(); - static App::DocumentObject* lastExportedObject = nullptr; - static bool lastExportUsedGeneratedFilename = true; - static QString lastExportFilterUsed = QString(); - static Document* lastActiveDocument; - auto selection = Gui::Selection().getObjectsOfType(App::DocumentObject::getClassTypeId()); if (selection.empty()) { QMessageBox::warning(Gui::getMainWindow(), @@ -414,77 +408,82 @@ void StdCmdExport::activated(int iMsg) return; } + App::DocumentObject* toExport = selection.front(); + App::Document* doc = toExport->getDocument(); + App::ExportInfo exportInfo = doc->exportInfo(); + bool filenameWasGenerated = false; + // fill the list of registered suffixes QStringList filterList; std::map filterMap = App::GetApplication().getExportFilters(); for (const auto &filter : filterMap) { // ignore the project file format - if (filter.first.find("(*.FCStd)") == std::string::npos) + if (filter.first.find("(*.FCStd)") == std::string::npos) { filterList << QString::fromStdString(filter.first); + } } QString formatList = filterList.join(QLatin1String(";;")); Base::Reference hPath = App::GetApplication().GetUserParameter().GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("General"); - QString selectedFilter = QString::fromStdString(hPath->GetASCII("FileExportFilter")); - if (!lastExportFilterUsed.isEmpty()) - selectedFilter = lastExportFilterUsed; + QString selectedFilter; + + if (!exportInfo.filter.empty()) { + selectedFilter = QString::fromStdString(exportInfo.filter); + } else { + selectedFilter = QString::fromStdString(hPath->GetASCII("FileExportFilter")); + } // Create a default filename for the export - // * If this is the first export this session default, generate a new default. - // * If this is a repeated export during the same session and file: + // * If this is the first export (the ExportInfo object' fields are empty) + // * If this is a repeated export using a filled ExportInfo object: // * If the user accepted the default filename last time, regenerate a new // default, potentially updating the object label. // * If not, default to their previously-set export filename. // * If this is an export of a different object than last time - QString defaultFilename = lastExportFullPath; - - bool filenameWasGenerated = false; - bool didActiveDocumentChange = lastActiveDocument != getActiveGuiDocument(); - bool didExportedObjectChange = lastExportedObject != selection.front(); - // We want to generate a new default name in four cases: - if (defaultFilename.isEmpty() || lastExportUsedGeneratedFilename || didActiveDocumentChange || didExportedObjectChange) { + QString defaultFilename; + if (exportInfo.filename.empty() || exportInfo.generatedName || exportInfo.object != toExport) { // First, get the name and path of the current .FCStd file, if there is one: - QString docFilename = QString::fromUtf8( - App::GetApplication().getActiveDocument()->getFileName()); + QString docFilename = QString::fromStdString(doc->getFileName()); // Find the default location for our exported file. Three possibilities: - QString defaultExportPath; - if (!lastExportFullPath.isEmpty()) { - QFileInfo fi(lastExportFullPath); - defaultExportPath = fi.path(); + QString exportPath; + if (!exportInfo.filename.empty()) { + QFileInfo fi(QString::fromStdString(exportInfo.filename)); + exportPath = fi.path(); } else if (!docFilename.isEmpty()) { QFileInfo fi(docFilename); - defaultExportPath = fi.path(); + exportPath = fi.path(); } else { - defaultExportPath = Gui::FileDialog::getWorkingDirectory(); + exportPath = Gui::FileDialog::getWorkingDirectory(); } - if (lastExportUsedGeneratedFilename || didActiveDocumentChange || didExportedObjectChange) { /*<- static, true on first call*/ - defaultFilename = defaultExportPath + QLatin1Char('/') + createDefaultExportBasename(); + if (exportInfo.generatedName || exportInfo.object != toExport) { /*<- static, true on first call*/ + defaultFilename = exportPath + QLatin1Char('/') + createDefaultExportBasename(); // Append the last extension used, if there is one. - if (!lastExportFullPath.isEmpty()) { - QFileInfo lastExportFile(lastExportFullPath); + if (!exportInfo.filename.empty()) { + QFileInfo lastExportFile(QString::fromStdString(exportInfo.filename)); if (!lastExportFile.suffix().isEmpty()) defaultFilename += QLatin1String(".") + lastExportFile.suffix(); } filenameWasGenerated = true; } + } else { + defaultFilename = QString::fromStdString(exportInfo.filename); } - - // Launch the file selection modal dialog - QString fileName = FileDialog::getSaveFileName(getMainWindow(), + // Launch the file selection modal dialog + QString filename = FileDialog::getSaveFileName(getMainWindow(), QObject::tr("Export file"), defaultFilename, formatList, &selectedFilter); - if (!fileName.isEmpty()) { + if (!filename.isEmpty()) { hPath->SetASCII("FileExportFilter", selectedFilter.toLatin1().constData()); - lastExportFilterUsed = selectedFilter; // So we can select the same one next time - SelectModule::Dict dict = SelectModule::exportHandler(fileName, selectedFilter); + + 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(), + doc->getName(), it.value().toLatin1()); } @@ -492,16 +491,18 @@ void StdCmdExport::activated(int iMsg) // did, next time we can recreate it, which will update the object label if // there is one. QFileInfo defaultExportFI(defaultFilename); - QFileInfo thisExportFI(fileName); - if (filenameWasGenerated && - thisExportFI.completeBaseName() == defaultExportFI.completeBaseName()) - lastExportUsedGeneratedFilename = true; - else - lastExportUsedGeneratedFilename = false; + QFileInfo thisExportFI(filename); + + if (filenameWasGenerated && thisExportFI.completeBaseName() != defaultExportFI.completeBaseName()) { + filenameWasGenerated = false; + } - lastExportFullPath = fileName; - lastActiveDocument = getActiveGuiDocument(); - lastExportedObject = selection.front(); + exportInfo.filename = filename.toStdString(); + exportInfo.object = toExport; + exportInfo.filter = selectedFilter.toStdString(); + exportInfo.generatedName = filenameWasGenerated; + + doc->setExportInfo(exportInfo); } }