@@ -242,33 +242,52 @@ def check_attachment_widget(self):
242242 for lid , layer in self .layers .items ():
243243 if lid not in self .editable :
244244 continue
245- fields = layer .fields ()
246- for i in range ( fields . count ()):
247- ws = layer . editorWidgetSetup ( i )
245+ for field in layer .fields ():
246+ ws = field . editorWidgetSetup ()
247+
248248 if ws and ws .type () == "ExternalResource" :
249249 cfg = ws .config ()
250- field_name = fields [i ].name ()
251- # check for relative paths
252- if "RelativeStorage" in cfg and cfg ["RelativeStorage" ] == QgsFileWidget .Absolute :
253- self .issues .append (SingleLayerWarning (lid , Warning .ATTACHMENT_ABSOLUTE_PATH , field_name ))
254- # check that correct expression is set
255- try :
256- is_expression_enabled = cfg ["PropertyCollection" ]["properties" ]["propertyRootPath" ]["active" ]
257- except (KeyError , TypeError ):
258- is_expression_enabled = False
259- if is_expression_enabled :
260- expression = cfg ["PropertyCollection" ]["properties" ]["propertyRootPath" ]["expression" ]
261- if not PROJECT_VARS .search (expression ):
250+ field_name = field .name ()
251+ prop_collection = cfg .get ("PropertyCollection" ) or {}
252+ properties = prop_collection .get ("properties" ) or {}
253+ root_path_prop = properties .get ("propertyRootPath" ) or {}
254+ storage_url_prop = properties .get ("storageUrl" ) or {}
255+
256+ is_root_active = root_path_prop .get ("active" , False )
257+ is_storage_active = storage_url_prop .get ("active" , False )
258+
259+ # Check for absolute paths
260+ if not (is_root_active or is_storage_active ):
261+ if (
262+ cfg .get ("RelativeStorage" ) == QgsFileWidget .Absolute
263+ ): # Absolute= 0, RelativeProject= 1, RelativeDefaultPath= 2
264+ self .issues .append (SingleLayerWarning (lid , Warning .ATTACHMENT_ABSOLUTE_PATH , field_name ))
265+
266+ # Check Data Defined Overrides
267+ if is_root_active :
268+ prop_type = root_path_prop .get (
269+ "type"
270+ ) # types are more reliable than keys which can be empty - QGIS decides based on type value
271+ if prop_type == 3 : # ExpressionBasedProperty
272+ expression = root_path_prop .get ("expression" , "" ).strip ()
273+ is_field_ref = expression .startswith ('"' ) and expression .endswith ('"' )
274+
275+ if not (PROJECT_VARS .search (expression ) or is_field_ref ):
276+ self .issues .append (
277+ SingleLayerWarning (lid , Warning .ATTACHMENT_WRONG_EXPRESSION , field_name )
278+ )
279+ elif prop_type == 2 : # FieldBasedProperty
280+ pass
281+ else : # 1 = StaticProperty or 0 = InvalidProperty
262282 self .issues .append (SingleLayerWarning (lid , Warning .ATTACHMENT_WRONG_EXPRESSION , field_name ))
263- # if expression-based path is not set with the data-defined override the app cannot resolve the path to save the photo
264- else :
283+
284+ # Fallback if expression-based path is not set
285+ elif not is_storage_active :
265286 if "DefaultRoot" in cfg :
266- # default root should not be set to the local path
267- if os .path .isabs (cfg ["DefaultRoot" ]):
287+ if os .path .isabs (cfg .get ("DefaultRoot" , "" )):
268288 self .issues .append (SingleLayerWarning (lid , Warning .ATTACHMENT_LOCAL_PATH , field_name ))
269289
270- # expression must be set with the data-defined override
271- expr = QgsExpression (cfg ["DefaultRoot" ])
290+ expr = QgsExpression (cfg .get ("DefaultRoot" , "" ))
272291 if expr .isValid ():
273292 self .issues .append (
274293 SingleLayerWarning (
0 commit comments