From b3f1ec7f855d1e470e13c06e6c4dd58433bccc3e Mon Sep 17 00:00:00 2001
From: Pascal Obry <pascal@obry.net>
Date: Sat, 28 Dec 2024 17:51:41 +0100
Subject: [PATCH] darktable: Call dt_iop_set_darktable_iop_table when iop list
 is set.

This is important as the list of all iop must be known to populate the
memory.darktable_iop_names table for the 'module' collection filter.

Fixes #18093.
---
 src/common/darktable.c |  3 ---
 src/develop/imageop.c  | 58 +++++++++++++++++++++++-------------------
 src/develop/imageop.h  |  3 ---
 3 files changed, 32 insertions(+), 32 deletions(-)

diff --git a/src/common/darktable.c b/src/common/darktable.c
index 18915a048581..2942901e4889 100644
--- a/src/common/darktable.c
+++ b/src/common/darktable.c
@@ -1731,9 +1731,6 @@ int dt_init(int argc, char *argv[], const gboolean init_gui, const gboolean load
   darktable.mipmap_cache = (dt_mipmap_cache_t *)calloc(1, sizeof(dt_mipmap_cache_t));
   dt_mipmap_cache_init(darktable.mipmap_cache);
 
-  // set up memory.darktable_iop_names table
-  dt_iop_set_darktable_iop_table();
-
   // set up the list of exiv2 metadata
   dt_exif_set_exiv2_taglist();
 
diff --git a/src/develop/imageop.c b/src/develop/imageop.c
index 4ef8b781d709..9b484aeaddc8 100644
--- a/src/develop/imageop.c
+++ b/src/develop/imageop.c
@@ -1729,6 +1729,35 @@ static void _init_module_so(void *m)
   }
 }
 
+// to be called before issuing any query based on memory.darktable_iop_names
+void _iop_set_darktable_iop_table()
+{
+  // the iop list must have been set, so after dt_iop_load_modules_so()
+  assert(darktable.iop && g_list_length(darktable.iop) > 0);
+
+  sqlite3_stmt *stmt;
+  gchar *module_list = NULL;
+  for(GList *iop = darktable.iop; iop; iop = g_list_next(iop))
+  {
+    dt_iop_module_so_t *module = iop->data;
+    dt_util_str_cat(&module_list, "(\"%s\",\"%s\"),",
+                                  module->op, module->name());
+  }
+
+  if(module_list)
+  {
+    module_list[strlen(module_list) - 1] = '\0';
+    gchar *query =
+      g_strdup_printf("INSERT INTO memory.darktable_iop_names (operation, name)"
+                      " VALUES %s", module_list);
+    DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), query, -1, &stmt, NULL);
+    sqlite3_step(stmt);
+    sqlite3_finalize(stmt);
+    g_free(query);
+    g_free(module_list);
+  }
+}
+
 void dt_iop_load_modules_so(void)
 {
   darktable.iop = dt_module_load_modules
@@ -1736,6 +1765,9 @@ void dt_iop_load_modules_so(void)
      dt_iop_load_module_so, _init_module_so, NULL);
 
   DT_CONTROL_SIGNAL_CONNECT(DT_SIGNAL_PREFERENCES_CHANGE, _iop_preferences_changed, darktable.iop);
+
+  // set up memory.darktable_iop_names table
+  _iop_set_darktable_iop_table();
 }
 
 gboolean dt_iop_load_module(dt_iop_module_t *module,
@@ -3348,32 +3380,6 @@ static void _enable_module_callback(dt_iop_module_t *module)
   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(module->off), !active);
 }
 
-// to be called before issuing any query based on memory.darktable_iop_names
-void dt_iop_set_darktable_iop_table()
-{
-  sqlite3_stmt *stmt;
-  gchar *module_list = NULL;
-  for(GList *iop = darktable.iop; iop; iop = g_list_next(iop))
-  {
-    dt_iop_module_so_t *module = iop->data;
-    dt_util_str_cat(&module_list, "(\"%s\",\"%s\"),",
-                                  module->op, module->name());
-  }
-
-  if(module_list)
-  {
-    module_list[strlen(module_list) - 1] = '\0';
-    gchar *query =
-      g_strdup_printf("INSERT INTO memory.darktable_iop_names (operation, name)"
-                      " VALUES %s", module_list);
-    DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), query, -1, &stmt, NULL);
-    sqlite3_step(stmt);
-    sqlite3_finalize(stmt);
-    g_free(query);
-    g_free(module_list);
-  }
-}
-
 const gchar *dt_iop_get_localized_name(const gchar *op)
 {
   // Prepare mapping op -> localized name
diff --git a/src/develop/imageop.h b/src/develop/imageop.h
index c78fa5c7244a..9dba65b69544 100644
--- a/src/develop/imageop.h
+++ b/src/develop/imageop.h
@@ -489,9 +489,6 @@ dt_iop_module_t *dt_iop_gui_get_previous_visible_module(const dt_iop_module_t *m
 /** returns the next visible module on the module list */
 dt_iop_module_t *dt_iop_gui_get_next_visible_module(const dt_iop_module_t *module);
 
-// initializes memory.darktable_iop_names
-void dt_iop_set_darktable_iop_table();
-
 /** adds keyboard accels to the first module in the pipe to handle
  * where there are multiple instances */
 void dt_iop_connect_accels_multi(dt_iop_module_so_t *module);