diff --git a/libs/librepcb/projecteditor/boardeditor/boardeditor.cpp b/libs/librepcb/projecteditor/boardeditor/boardeditor.cpp
index 02c10cf21b..f6c7d31fe2 100644
--- a/libs/librepcb/projecteditor/boardeditor/boardeditor.cpp
+++ b/libs/librepcb/projecteditor/boardeditor/boardeditor.cpp
@@ -208,6 +208,8 @@ BoardEditor::BoardEditor(ProjectEditor& projectEditor, Project& project)
// connect some actions which are created with the Qt Designer
connect(mUi->actionProjectSave, &QAction::triggered, &mProjectEditor,
&ProjectEditor::saveProject);
+ connect(mUi->actionProjectSaveAs, &QAction::triggered,
+ [this]() { mProjectEditor.saveProjectAs(this); });
connect(mUi->actionQuit, &QAction::triggered, this, &BoardEditor::close);
connect(mUi->actionOpenWebsite, &QAction::triggered,
[]() { QDesktopServices::openUrl(QUrl("https://librepcb.org")); });
diff --git a/libs/librepcb/projecteditor/boardeditor/boardeditor.ui b/libs/librepcb/projecteditor/boardeditor/boardeditor.ui
index c8a15d0e1b..09ef6ea41c 100644
--- a/libs/librepcb/projecteditor/boardeditor/boardeditor.ui
+++ b/libs/librepcb/projecteditor/boardeditor/boardeditor.ui
@@ -78,6 +78,7 @@
&File
+
@@ -304,6 +305,15 @@
Ctrl+S
+
+
+
+ :/img/actions/save.png:/img/actions/save.png
+
+
+ &Save Project
+
+
diff --git a/libs/librepcb/projecteditor/projecteditor.cpp b/libs/librepcb/projecteditor/projecteditor.cpp
index a4955872ca..38910c8d3c 100644
--- a/libs/librepcb/projecteditor/projecteditor.cpp
+++ b/libs/librepcb/projecteditor/projecteditor.cpp
@@ -211,6 +211,46 @@ bool ProjectEditor::saveProject() noexcept {
}
}
+bool ProjectEditor::saveProjectAs(QWidget* parent) noexcept {
+ try {
+ qDebug() << "Saving project as...";
+
+ FilePath defaultDirectory = mProject.getPath().getParentDir(); // can throw
+ QString directoryName = FileDialog::getSaveFileName(
+ parent, tr("Save project as *"), defaultDirectory.toStr(), "*");
+ if (directoryName.isEmpty()) return false;
+
+ // Copy project directory to 'directoryName' directory
+ // create file system
+ FilePath chosenDir = FilePath(directoryName);
+ std::shared_ptr fs = TransactionalFileSystem::openRW(
+ chosenDir);
+ TransactionalDirectory transdir(fs);
+
+ // Create a new project
+ Project* project = Project::create(
+ std::unique_ptr(new TransactionalDirectory(fs)),
+ directoryName);
+
+ // Save project to its own transactional directory, and then copies it to the
+ // newly created transactional directory
+ mProject.save();
+ mProject.getDirectory().copyTo(transdir);
+
+ project->save();
+ fs->save();
+
+ // Do not clean the undo stack for saving as copy, could be useful?
+
+ qDebug() << "Project successfully saved";
+ return true;
+ } catch (Exception& exc) {
+ QMessageBox::critical(0, tr("Error while saving the project"),
+ exc.getMsg());
+ return false;
+ }
+}
+
bool ProjectEditor::autosaveProject() noexcept {
if (mUndoStack->isClean())
return false; // do not save if there are no changes
diff --git a/libs/librepcb/projecteditor/projecteditor.h b/libs/librepcb/projecteditor/projecteditor.h
index 6e842ebddd..9b5f4a8ede 100644
--- a/libs/librepcb/projecteditor/projecteditor.h
+++ b/libs/librepcb/projecteditor/projecteditor.h
@@ -168,6 +168,17 @@ public slots:
*/
bool saveProject() noexcept;
+ /**
+ * @brief Save the whole project as a copy to the harddisc
+ *
+ * @note The whole save procedere is described in @ref doc_project_save.
+ *
+ * @param parent parent widget of the dialog (optional)
+ *
+ * @return true on success, false on failure
+ */
+ bool saveProjectAs(QWidget* parent = nullptr) noexcept;
+
/**
* @brief Make a automatic backup of the project (save to temporary files)
*
diff --git a/libs/librepcb/projecteditor/schematiceditor/schematiceditor.cpp b/libs/librepcb/projecteditor/schematiceditor/schematiceditor.cpp
index 93701a5289..f865354855 100644
--- a/libs/librepcb/projecteditor/schematiceditor/schematiceditor.cpp
+++ b/libs/librepcb/projecteditor/schematiceditor/schematiceditor.cpp
@@ -122,6 +122,8 @@ SchematicEditor::SchematicEditor(ProjectEditor& projectEditor, Project& project)
&SchematicEditor::addSchematic);
connect(mUi->actionSave_Project, &QAction::triggered, &mProjectEditor,
&ProjectEditor::saveProject);
+ connect(mUi->actionSave_Project_As, &QAction::triggered,
+ [this]() { mProjectEditor.saveProjectAs(this); });
connect(mUi->actionQuit, &QAction::triggered, this, &SchematicEditor::close);
connect(mUi->actionOpenWebsite, &QAction::triggered,
[]() { QDesktopServices::openUrl(QUrl("https://librepcb.org")); });
diff --git a/libs/librepcb/projecteditor/schematiceditor/schematiceditor.ui b/libs/librepcb/projecteditor/schematiceditor/schematiceditor.ui
index 39cc0f1e24..ccfe9bcdbb 100644
--- a/libs/librepcb/projecteditor/schematiceditor/schematiceditor.ui
+++ b/libs/librepcb/projecteditor/schematiceditor/schematiceditor.ui
@@ -48,6 +48,7 @@
+
@@ -296,6 +297,15 @@
Ctrl+S
+
+
+
+ :/img/actions/save.png:/img/actions/save.png
+
+
+ &Save Project As
+
+