diff --git a/Mergin/images/default/tabler_icons/revert-changes.svg b/Mergin/images/default/tabler_icons/revert-changes.svg
new file mode 100644
index 0000000..bc0abbe
--- /dev/null
+++ b/Mergin/images/default/tabler_icons/revert-changes.svg
@@ -0,0 +1,7 @@
+
\ No newline at end of file
diff --git a/Mergin/images/white/tabler_icons/revert-changes.svg b/Mergin/images/white/tabler_icons/revert-changes.svg
new file mode 100644
index 0000000..8358565
--- /dev/null
+++ b/Mergin/images/white/tabler_icons/revert-changes.svg
@@ -0,0 +1,6 @@
+
\ No newline at end of file
diff --git a/Mergin/project_status_dialog.py b/Mergin/project_status_dialog.py
index bb8fc51..ed143cb 100644
--- a/Mergin/project_status_dialog.py
+++ b/Mergin/project_status_dialog.py
@@ -33,6 +33,9 @@ class ProjectStatusDialog(QDialog):
"table": "table.svg",
}
+ # custom return value
+ RESET_CHANGES = 3
+
def __init__(
self,
pull_changes,
@@ -83,6 +86,14 @@ def __init__(
self.validate_project()
+ self.btn_reset_local_changes.setIcon(QIcon(icon_path("revert-changes.svg")))
+ self.btn_reset_local_changes.clicked.connect(self.reset_local_changes)
+
+ if len(push_changes["added"]) > 0 or len(push_changes["removed"]) > 0 or len(push_changes["updated"]) > 0:
+ self.btn_reset_local_changes.setEnabled(True)
+ else:
+ self.btn_reset_local_changes.setEnabled(False)
+
def _get_info_text(self, has_files_to_replace, has_write_permissions, has_unfinished_pull):
msg = []
if not has_write_permissions:
@@ -231,3 +242,15 @@ def validate_project(self):
else:
self.show_validation_results(results)
self.btn_sync.setStyleSheet("background-color: #ffc800")
+
+ def reset_local_changes(self):
+ btn_reply = QMessageBox.question(
+ None,
+ "Reset changes",
+ "All changes in your project directory will be reverted. Do you want to proceed?",
+ QMessageBox.Yes | QMessageBox.No,
+ QMessageBox.Yes,
+ )
+ if btn_reply != QMessageBox.Yes:
+ return
+ return self.done(self.RESET_CHANGES)
diff --git a/Mergin/projects_manager.py b/Mergin/projects_manager.py
index bc9667c..3a28a70 100644
--- a/Mergin/projects_manager.py
+++ b/Mergin/projects_manager.py
@@ -177,8 +177,12 @@ def project_status(self, project_dir):
# Sync button in the status dialog returns QDialog.Accepted
# and Close button retuns QDialog::Rejected, so it dialog was
# accepted we start sync
- if dlg.exec_():
+ return_value = dlg.exec_()
+
+ if return_value == ProjectStatusDialog.Accepted:
self.sync_project(project_dir)
+ elif return_value == ProjectStatusDialog.RESET_CHANGES:
+ self.reset_local_changes(project_dir)
except (URLError, ClientError, InvalidProject) as e:
msg = f"Failed to get status for project {project_name}:\n\n{str(e)}"
@@ -215,6 +219,25 @@ def check_project_server(self, project_dir, inform_user=True):
QMessageBox.critical(None, "Mergin Maps", info)
return False
+ def reset_local_changes(self, project_dir: str):
+ if not project_dir:
+ return
+ if not self.check_project_server(project_dir):
+ return
+
+ current_project_filename = QgsProject.instance().fileName()
+ current_project_path = os.path.normpath(QgsProject.instance().absolutePath())
+ if current_project_path == os.path.normpath(project_dir):
+ QgsProject.instance().clear()
+
+ try:
+ self.mc.reset_local_changes(project_dir)
+ except Exception as e:
+ msg = f"Failed to reset local changes:\n\n{str(e)}"
+ QMessageBox.critical(None, "Project reset local changes", msg, QMessageBox.Close)
+
+ self.open_project(os.path.dirname(current_project_filename))
+
def sync_project(self, project_dir, project_name=None):
if not project_dir:
return
diff --git a/Mergin/ui/ui_status_dialog.ui b/Mergin/ui/ui_status_dialog.ui
index 3750c43..1a8cf3f 100644
--- a/Mergin/ui/ui_status_dialog.ui
+++ b/Mergin/ui/ui_status_dialog.ui
@@ -14,7 +14,7 @@
Project status
- -
+
-
QFrame::StyledPanel
@@ -24,7 +24,7 @@
- -
+
-
QAbstractItemView::NoEditTriggers
@@ -41,7 +41,7 @@
- -
+
-
true
@@ -62,6 +62,16 @@
-
+
+
+ This will revert all changes in your local project directory.
+
+
+ Reset Changes
+
+
+
+ -
Qt::Horizontal