@@ -96,6 +96,8 @@ typedef struct dt_lib_collect_t
9696 gboolean inited ;
9797
9898 GtkWidget * history_box ;
99+
100+ GSimpleActionGroup * action_group ;
99101} dt_lib_collect_t ;
100102
101103typedef struct dt_lib_collect_params_rule_t
@@ -2926,9 +2928,41 @@ static gboolean entry_focus_in_callback(GtkWidget *w,
29262928 return FALSE;
29272929}
29282930
2929- static void menuitem_mode (GtkMenuItem * menuitem ,
2930- dt_lib_collect_rule_t * d )
2931+ static gboolean _process_variant_params (GVariant * parameter ,
2932+ gpointer userdata ,
2933+ dt_lib_collect_mode_t * mode ,
2934+ dt_lib_collect_rule_t * * d )
2935+ {
2936+ const gsize nb = g_variant_n_children (parameter );
2937+
2938+ if (nb != 2 )
2939+ return FALSE;
2940+
2941+ dt_lib_collect_t * m = (dt_lib_collect_t * )userdata ;
2942+
2943+ GVariant * v = g_variant_get_child_value (parameter , 0 );
2944+ * mode = g_variant_get_int32 (v );
2945+ g_variant_unref (v );
2946+
2947+ v = g_variant_get_child_value (parameter , 1 );
2948+ const int rule_index = g_variant_get_int32 (v );
2949+ g_variant_unref (v );
2950+
2951+ * d = & m -> rule [rule_index ];
2952+
2953+ return TRUE;
2954+ }
2955+
2956+ static void _menuitem_mode (GSimpleAction * action ,
2957+ GVariant * parameter ,
2958+ gpointer userdata )
29312959{
2960+ dt_lib_collect_mode_t mode ;
2961+ dt_lib_collect_rule_t * d = NULL ;
2962+
2963+ if (!_process_variant_params (parameter , userdata , & mode , & d ))
2964+ return ;
2965+
29322966 // add next row with and operator
29332967 const int _a = dt_conf_get_int ("plugins/lighttable/collect/num_rules" );
29342968 const int active = CLAMP (_a , 1 , MAX_RULES );
@@ -2937,8 +2971,6 @@ static void menuitem_mode(GtkMenuItem *menuitem,
29372971 {
29382972 char confname [200 ] = { 0 };
29392973 snprintf (confname , sizeof (confname ), "plugins/lighttable/collect/mode%1d" , active );
2940- const dt_lib_collect_mode_t mode =
2941- GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menuitem ), "menuitem_mode" ));
29422974
29432975 dt_conf_set_int (confname , mode );
29442976 snprintf (confname , sizeof (confname ), "plugins/lighttable/collect/string%1d" , active );
@@ -2953,17 +2985,22 @@ static void menuitem_mode(GtkMenuItem *menuitem,
29532985 DT_COLLECTION_PROP_UNDEF , NULL );
29542986}
29552987
2956- static void menuitem_mode_change (GtkMenuItem * menuitem ,
2957- dt_lib_collect_rule_t * d )
2988+ static void _menuitem_mode_change (GSimpleAction * action ,
2989+ GVariant * parameter ,
2990+ gpointer userdata )
29582991{
2992+ dt_lib_collect_mode_t mode ;
2993+ dt_lib_collect_rule_t * d = NULL ;
2994+
2995+ if (!_process_variant_params (parameter , userdata , & mode , & d ))
2996+ return ;
2997+
29592998 // add next row with and operator
29602999 const int num = d -> num + 1 ;
29613000 if (num < MAX_RULES && num > 0 )
29623001 {
29633002 char confname [200 ] = { 0 };
29643003 snprintf (confname , sizeof (confname ), "plugins/lighttable/collect/mode%1d" , num );
2965- const dt_lib_collect_mode_t mode =
2966- GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menuitem ), "menuitem_mode" ));
29673004 dt_conf_set_int (confname , mode );
29683005 }
29693006 dt_lib_collect_t * c = get_collect (d );
@@ -3186,9 +3223,15 @@ static void _metadata_changed(gpointer instance,
31863223 }
31873224}
31883225
3189- static void menuitem_clear (GtkMenuItem * menuitem ,
3190- dt_lib_collect_rule_t * d )
3226+ static void _menuitem_clear (GSimpleAction * simple ,
3227+ GVariant * parameter ,
3228+ gpointer userdata )
31913229{
3230+ dt_lib_collect_t * m = (dt_lib_collect_t * ) userdata ;
3231+
3232+ const int index = g_variant_get_int32 (parameter );
3233+ dt_lib_collect_rule_t * d = & m -> rule [index ];
3234+
31923235 // remove this row, or if 1st, clear text entry box
31933236 const int _a = dt_conf_get_int ("plugins/lighttable/collect/num_rules" );
31943237 const int active = CLAMP (_a , 1 , MAX_RULES );
@@ -3233,72 +3276,58 @@ static void menuitem_clear(GtkMenuItem *menuitem,
32333276 DT_COLLECTION_PROP_UNDEF , NULL );
32343277}
32353278
3236- static gboolean popup_button_callback (GtkWidget * widget ,
3279+ static gboolean popup_button_callback (GtkWidget * button ,
32373280 GdkEventButton * event ,
32383281 dt_lib_collect_rule_t * d )
32393282{
32403283 if (event -> button != 1 )
32413284 return FALSE;
32423285
3243- GtkWidget * menu = gtk_menu_new ();
3244- GtkWidget * mi ;
3286+ GMenu * menu = g_menu_new ();
32453287 const int _a = dt_conf_get_int ("plugins/lighttable/collect/num_rules" );
32463288 const int active = CLAMP (_a , 1 , MAX_RULES );
32473289
3248- mi = gtk_menu_item_new_with_label (_ ("clear this rule" ));
3249- gtk_menu_shell_append (GTK_MENU_SHELL (menu ), mi );
3250- g_signal_connect (G_OBJECT (mi ), "activate" , G_CALLBACK (menuitem_clear ), d );
3251-
3290+ gchar * action ;
3291+
3292+ action = g_strdup_printf ("collect.clear(%d)" , d -> num );
3293+ g_menu_append (menu , _ ("clear this rule" ), action );
3294+ g_free (action );
3295+
32523296 if (d -> num == active - 1 )
32533297 {
3254- mi = gtk_menu_item_new_with_label (_ ("narrow down search" ));
3255- g_object_set_data (G_OBJECT (mi ), "menuitem_mode" ,
3256- GINT_TO_POINTER (DT_LIB_COLLECT_MODE_AND ));
3257- gtk_menu_shell_append (GTK_MENU_SHELL (menu ), mi );
3258- g_signal_connect (G_OBJECT (mi ), "activate" ,
3259- G_CALLBACK (menuitem_mode ), d );
3260-
3261- mi = gtk_menu_item_new_with_label (_ ("add more images" ));
3262- g_object_set_data (G_OBJECT (mi ), "menuitem_mode" ,
3263- GINT_TO_POINTER (DT_LIB_COLLECT_MODE_OR ));
3264- gtk_menu_shell_append (GTK_MENU_SHELL (menu ), mi );
3265- g_signal_connect (G_OBJECT (mi ), "activate" ,
3266- G_CALLBACK (menuitem_mode ), d );
3267-
3268- mi = gtk_menu_item_new_with_label (_ ("exclude images" ));
3269- g_object_set_data (G_OBJECT (mi ), "menuitem_mode" ,
3270- GINT_TO_POINTER (DT_LIB_COLLECT_MODE_AND_NOT ));
3271- gtk_menu_shell_append (GTK_MENU_SHELL (menu ), mi );
3272- g_signal_connect (G_OBJECT (mi ), "activate" ,
3273- G_CALLBACK (menuitem_mode ), d );
3298+ const char * fmt = "collect.mode((%d,%d))" ;
3299+
3300+ action = g_strdup_printf (fmt , DT_LIB_COLLECT_MODE_AND , d -> num );
3301+ g_menu_append (menu , _ ("narrow down search" ), action );
3302+ g_free (action );
3303+
3304+ action = g_strdup_printf (fmt , DT_LIB_COLLECT_MODE_OR , d -> num );
3305+ g_menu_append (menu , _ ("add more images" ), action );
3306+ g_free (action );
3307+
3308+ action = g_strdup_printf (fmt , DT_LIB_COLLECT_MODE_AND_NOT , d -> num );
3309+ g_menu_append (menu , _ ("exclude images" ), action );
3310+ g_free (action );
32743311 }
32753312 else if (d -> num < active - 1 )
32763313 {
3277- mi = gtk_menu_item_new_with_label (_ ("change to: and" ));
3278- g_object_set_data (G_OBJECT (mi ), "menuitem_mode" ,
3279- GINT_TO_POINTER (DT_LIB_COLLECT_MODE_AND ));
3280- gtk_menu_shell_append (GTK_MENU_SHELL (menu ), mi );
3281- g_signal_connect (G_OBJECT (mi ), "activate" ,
3282- G_CALLBACK (menuitem_mode_change ), d );
3314+ const char * fmt = "collect.modechange((%d,%d))" ;
32833315
3284- mi = gtk_menu_item_new_with_label (_ ("change to: or" ));
3285- g_object_set_data (G_OBJECT (mi ), "menuitem_mode" ,
3286- GINT_TO_POINTER (DT_LIB_COLLECT_MODE_OR ));
3287- gtk_menu_shell_append (GTK_MENU_SHELL (menu ), mi );
3288- g_signal_connect (G_OBJECT (mi ), "activate" ,
3289- G_CALLBACK (menuitem_mode_change ), d );
3316+ action = g_strdup_printf (fmt , DT_LIB_COLLECT_MODE_AND , d -> num );
3317+ g_menu_append (menu , _ ("change to: and" ), action );
3318+ g_free (action );
32903319
3291- mi = gtk_menu_item_new_with_label (_ ("change to: except" ));
3292- g_object_set_data (G_OBJECT (mi ), "menuitem_mode" ,
3293- GINT_TO_POINTER (DT_LIB_COLLECT_MODE_AND_NOT ));
3294- gtk_menu_shell_append (GTK_MENU_SHELL (menu ), mi );
3295- g_signal_connect (G_OBJECT (mi ), "activate" ,
3296- G_CALLBACK (menuitem_mode_change ), d );
3297- }
3320+ action = g_strdup_printf (fmt , DT_LIB_COLLECT_MODE_OR , d -> num );
3321+ g_menu_append (menu , _ ("change to: or" ), action );
3322+ g_free (action );
32983323
3299- gtk_widget_show_all (GTK_WIDGET (menu ));
3324+ action = g_strdup_printf (fmt , DT_LIB_COLLECT_MODE_AND_NOT , d -> num );
3325+ g_menu_append (menu , _ ("change to: except" ), action );
3326+ g_free (action );
3327+ }
33003328
3301- gtk_menu_popup_at_pointer (GTK_MENU (menu ), (GdkEvent * )event );
3329+ GtkWidget * popover_menu = dt_gui_popover_menu_from_model (button , menu );
3330+ gtk_popover_popup (GTK_POPOVER (popover_menu ));
33023331
33033332 return TRUE;
33043333}
@@ -3656,6 +3685,17 @@ void gui_init(dt_lib_module_t *self)
36563685 self -> widget = dt_gui_vbox ();
36573686 dt_gui_add_class (self -> widget , "dt_spacing_sw" );
36583687
3688+ // setup the actions for this module
3689+ const GActionEntry entries [] = {
3690+ { "clear" , _menuitem_clear , "i" },
3691+ { "mode" , _menuitem_mode , "(ii)" },
3692+ { "modechange" , _menuitem_mode_change , "(ii)" }
3693+ };
3694+
3695+ d -> action_group = g_simple_action_group_new ();
3696+ g_action_map_add_action_entries (G_ACTION_MAP (d -> action_group ), entries , G_N_ELEMENTS (entries ), d );
3697+ gtk_widget_insert_action_group (self -> widget , "collect" , G_ACTION_GROUP (d -> action_group ));
3698+
36593699 d -> active_rule = 0 ;
36603700 d -> nb_rules = 0 ;
36613701 d -> params = (dt_lib_collect_params_t * )malloc (sizeof (dt_lib_collect_params_t ));
@@ -3810,6 +3850,8 @@ void gui_cleanup(dt_lib_module_t *self)
38103850 g_object_unref (d -> listfilter );
38113851 g_object_unref (d -> vmonitor );
38123852
3853+ g_object_unref (d -> action_group );
3854+
38133855 /* TODO: Make sure we are cleaning up all allocations */
38143856
38153857 free (self -> data );
0 commit comments