SelectModule is declared in FileDialog.h which was already included. The separate #include "SelectModule.h" referenced a header that doesn't exist, causing a fatal build error.
232 lines
7.5 KiB
C++
232 lines
7.5 KiB
C++
/***************************************************************************
|
|
* Copyright (c) 2025 Kindred Systems *
|
|
* *
|
|
* 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"
|
|
|
|
#include <algorithm>
|
|
|
|
#include <QApplication>
|
|
#include <QMessageBox>
|
|
|
|
#include <App/Application.h>
|
|
#include <App/Document.h>
|
|
#include <App/DocumentObject.h>
|
|
#include <App/PropertyStandard.h>
|
|
|
|
#include "FileOrigin.h"
|
|
#include "Application.h"
|
|
#include "BitmapFactory.h"
|
|
#include "Document.h"
|
|
#include "FileDialog.h"
|
|
#include "MainWindow.h"
|
|
|
|
|
|
namespace Gui {
|
|
|
|
// Property name used by PLM origins (Silo) to mark tracked documents
|
|
static const char* SILO_ITEM_ID_PROP = "SiloItemId";
|
|
|
|
|
|
//===========================================================================
|
|
// LocalFileOrigin
|
|
//===========================================================================
|
|
|
|
LocalFileOrigin::LocalFileOrigin()
|
|
{
|
|
}
|
|
|
|
QIcon LocalFileOrigin::icon() const
|
|
{
|
|
return BitmapFactory().iconFromTheme("document-new");
|
|
}
|
|
|
|
std::string LocalFileOrigin::documentIdentity(App::Document* doc) const
|
|
{
|
|
if (!doc || !ownsDocument(doc)) {
|
|
return {};
|
|
}
|
|
return doc->FileName.getValue();
|
|
}
|
|
|
|
std::string LocalFileOrigin::documentDisplayId(App::Document* doc) const
|
|
{
|
|
// For local files, identity and display ID are the same (file path)
|
|
return documentIdentity(doc);
|
|
}
|
|
|
|
bool LocalFileOrigin::ownsDocument(App::Document* doc) const
|
|
{
|
|
if (!doc) {
|
|
return false;
|
|
}
|
|
|
|
// Local origin owns documents that do NOT have PLM tracking properties.
|
|
// Check all objects for SiloItemId property - if any have it,
|
|
// this document is owned by a PLM origin, not local.
|
|
for (auto* obj : doc->getObjects()) {
|
|
if (obj->getPropertyByName(SILO_ITEM_ID_PROP)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
App::Document* LocalFileOrigin::newDocument(const std::string& name)
|
|
{
|
|
std::string docName = name.empty() ? "Unnamed" : name;
|
|
return App::GetApplication().newDocument(docName.c_str(), docName.c_str());
|
|
}
|
|
|
|
App::Document* LocalFileOrigin::openDocument(const std::string& identity)
|
|
{
|
|
if (identity.empty()) {
|
|
return nullptr;
|
|
}
|
|
|
|
return App::GetApplication().openDocument(identity.c_str());
|
|
}
|
|
|
|
App::Document* LocalFileOrigin::openDocumentInteractive()
|
|
{
|
|
// Build file filter list for Open dialog
|
|
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();
|
|
// Make sure FCStd is the very first fileformat
|
|
auto 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();
|
|
// Make sure the format name for FCStd is the very first in the list
|
|
for (auto 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 (const auto& filter : FilterList) {
|
|
formatList += QLatin1String(filter.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 nullptr;
|
|
}
|
|
|
|
// 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())
|
|
);
|
|
return nullptr;
|
|
}
|
|
|
|
App::Document* lastDoc = nullptr;
|
|
for (SelectModule::Dict::iterator it = dict.begin(); it != dict.end(); ++it) {
|
|
// Set flag indicating that this load/restore has been initiated by the user
|
|
Application::Instance->setStatus(Gui::Application::UserInitiatedOpenDocument, true);
|
|
|
|
Application::Instance->open(it.key().toUtf8(), it.value().toLatin1());
|
|
|
|
Application::Instance->setStatus(Gui::Application::UserInitiatedOpenDocument, false);
|
|
|
|
lastDoc = App::GetApplication().getActiveDocument();
|
|
|
|
Application::Instance->checkPartialRestore(lastDoc);
|
|
Application::Instance->checkRestoreError(lastDoc);
|
|
}
|
|
|
|
return lastDoc;
|
|
}
|
|
|
|
bool LocalFileOrigin::saveDocument(App::Document* doc)
|
|
{
|
|
if (!doc) {
|
|
return false;
|
|
}
|
|
|
|
// If document has never been saved, we need a path
|
|
const char* fileName = doc->FileName.getValue();
|
|
if (!fileName || fileName[0] == '\0') {
|
|
// No file name set - would need UI interaction for Save As
|
|
// This will be handled by the command layer
|
|
return false;
|
|
}
|
|
|
|
return doc->save();
|
|
}
|
|
|
|
bool LocalFileOrigin::saveDocumentAs(App::Document* doc, const std::string& newIdentity)
|
|
{
|
|
if (!doc || newIdentity.empty()) {
|
|
return false;
|
|
}
|
|
|
|
return doc->saveAs(newIdentity.c_str());
|
|
}
|
|
|
|
bool LocalFileOrigin::saveDocumentAsInteractive(App::Document* doc)
|
|
{
|
|
if (!doc) {
|
|
return false;
|
|
}
|
|
|
|
// Get Gui document for save dialog
|
|
Gui::Document* guiDoc = Application::Instance->getDocument(doc);
|
|
if (!guiDoc) {
|
|
return false;
|
|
}
|
|
|
|
// Use Gui::Document::saveAs() which handles the file dialog
|
|
return guiDoc->saveAs();
|
|
}
|
|
|
|
} // namespace Gui
|