diff --git a/Mergin/attachment_fields_model.py b/Mergin/attachment_fields_model.py
new file mode 100644
index 0000000..aff2332
--- /dev/null
+++ b/Mergin/attachment_fields_model.py
@@ -0,0 +1,33 @@
+from qgis.PyQt.QtGui import QStandardItemModel, QStandardItem
+from qgis.PyQt.QtCore import Qt
+from qgis.core import QgsProject, QgsMapLayer
+
+
+class AttachmentFieldsModel(QStandardItemModel):
+
+ LAYER_ID = Qt.UserRole + 1
+ FIELD_NAME = Qt.UserRole + 2
+ EXPRESSION = Qt.UserRole + 3
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+ layers = QgsProject.instance().mapLayers()
+ for layer_id, layer in layers.items():
+ if layer.type() != QgsMapLayer.VectorLayer:
+ continue
+
+ for field in layer.fields():
+ widget_setup = field.editorWidgetSetup()
+ if widget_setup.type() != "ExternalResource":
+ continue
+
+ if not widget_setup.config().get("DocumentViewer", 1):
+ continue
+
+ item = QStandardItem(f"{layer.name()} - {field.name()}")
+ item.setData(layer_id, AttachmentFieldsModel.LAYER_ID)
+ item.setData(field.name(), AttachmentFieldsModel.FIELD_NAME)
+ exp, ok = QgsProject.instance().readEntry("Mergin", f"PhotoNaming/{layer_id}/{field.name()}")
+ item.setData(exp, AttachmentFieldsModel.EXPRESSION)
+ self.appendRow(item)
diff --git a/Mergin/project_settings_widget.py b/Mergin/project_settings_widget.py
index ae3bbf9..e33827f 100644
--- a/Mergin/project_settings_widget.py
+++ b/Mergin/project_settings_widget.py
@@ -5,6 +5,7 @@
from qgis.PyQt.QtWidgets import QFileDialog
from qgis.core import QgsProject
from qgis.gui import QgsOptionsWidgetFactory, QgsOptionsPageWidget
+from .attachment_fields_model import AttachmentFieldsModel
from .utils import icon_path, mergin_project_local_path
ui_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), "ui", "ui_project_config.ui")
@@ -56,6 +57,11 @@ def __init__(self, parent=None):
else:
self.selective_sync_group.setEnabled(False)
+ self.model = AttachmentFieldsModel()
+ self.list_fields.setModel(self.model)
+ self.list_fields.selectionModel().currentChanged.connect(self.update_expression_edit)
+ self.edit_photo_expression.expressionChanged.connect(self.save_expression)
+
def get_sync_dir(self):
abs_path = QFileDialog.getExistingDirectory(
None, "Select directory", self.local_project_dir, QFileDialog.ShowDirsOnly
@@ -90,7 +96,36 @@ def save_config_file(self):
with open(self.config_file, "w") as f:
json.dump(config, f, indent=2)
+ def save_expression(self, expression):
+ if not self.list_fields.selectionModel().hasSelection():
+ return
+ index = self.list_fields.selectionModel().selectedIndexes()[0]
+ if index.isValid():
+ item = self.model.itemFromIndex(index)
+ item.setData(self.edit_photo_expression.expression(), AttachmentFieldsModel.EXPRESSION)
+
+ def update_expression_edit(self, current, previous):
+ item = self.model.itemFromIndex(current)
+ exp = item.data(AttachmentFieldsModel.EXPRESSION)
+ layer_id = item.data(AttachmentFieldsModel.LAYER_ID)
+ layer = QgsProject.instance().mapLayer(layer_id)
+ if layer and layer.isValid():
+ self.edit_photo_expression.setLayer(layer)
+
+ self.edit_photo_expression.blockSignals(True)
+ self.edit_photo_expression.setExpression(exp if exp else "")
+ self.edit_photo_expression.blockSignals(False)
+
def apply(self):
QgsProject.instance().writeEntry("Mergin", "PhotoQuality", self.cmb_photo_quality.currentData())
QgsProject.instance().writeEntry("Mergin", "Snapping", self.cmb_snapping_mode.currentData())
+ for i in range(self.model.rowCount()):
+ index = self.model.index(i, 0)
+ if index.isValid():
+ item = self.model.itemFromIndex(index)
+ layer_id = item.data(AttachmentFieldsModel.LAYER_ID)
+ field_name = item.data(AttachmentFieldsModel.FIELD_NAME)
+ expression = item.data(AttachmentFieldsModel.EXPRESSION)
+ QgsProject.instance().writeEntry("Mergin", f"PhotoNaming/{layer_id}/{field_name}", expression)
+
self.save_config_file()
diff --git a/Mergin/ui/ui_project_config.ui b/Mergin/ui/ui_project_config.ui
index f29e4ea..494cfe1 100644
--- a/Mergin/ui/ui_project_config.ui
+++ b/Mergin/ui/ui_project_config.ui
@@ -9,8 +9,8 @@
0
0
- 495
- 367
+ 535
+ 516
@@ -82,19 +82,6 @@
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
-
@@ -127,6 +114,19 @@
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
-
@@ -159,8 +159,72 @@
+ -
+
+
+ Photo attachment
+
+
+
-
+
+
+ <html><head/><body><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua</p></body></html>
+
+
+ true
+
+
+ true
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+
+
+
+
+
+ QgsExpressionLineEdit
+ QWidget
+
+ 1
+
+
+
+ chk_sync_enabled
+ edit_sync_dir
+ btn_get_sync_dir
+ cmb_photo_quality
+ cmb_snapping_mode
+ list_fields
+