@@ -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
@@ -2924,9 +2926,41 @@ static gboolean entry_focus_in_callback(GtkWidget *w,
29242926 return FALSE;
29252927}
29262928
2927- static void menuitem_mode (GtkMenuItem * menuitem ,
2928- dt_lib_collect_rule_t * d )
2929+ static gboolean _process_variant_params (GVariant * parameter ,
2930+ gpointer userdata ,
2931+ dt_lib_collect_mode_t * mode ,
2932+ dt_lib_collect_rule_t * * d )
2933+ {
2934+ const gsize nb = g_variant_n_children (parameter );
2935+
2936+ if (nb != 2 )
2937+ return FALSE;
2938+
2939+ dt_lib_collect_t * m = (dt_lib_collect_t * )userdata ;
2940+
2941+ GVariant * v = g_variant_get_child_value (parameter , 0 );
2942+ * mode = g_variant_get_int32 (v );
2943+ g_variant_unref (v );
2944+
2945+ v = g_variant_get_child_value (parameter , 1 );
2946+ const int rule_index = g_variant_get_int32 (v );
2947+ g_variant_unref (v );
2948+
2949+ * d = & m -> rule [rule_index ];
2950+
2951+ return TRUE;
2952+ }
2953+
2954+ static void _menuitem_mode (GSimpleAction * action ,
2955+ GVariant * parameter ,
2956+ gpointer userdata )
29292957{
2958+ dt_lib_collect_mode_t mode ;
2959+ dt_lib_collect_rule_t * d = NULL ;
2960+
2961+ if (!_process_variant_params (parameter , userdata , & mode , & d ))
2962+ return ;
2963+
29302964 // add next row with and operator
29312965 const int _a = dt_conf_get_int ("plugins/lighttable/collect/num_rules" );
29322966 const int active = CLAMP (_a , 1 , MAX_RULES );
@@ -2935,8 +2969,6 @@ static void menuitem_mode(GtkMenuItem *menuitem,
29352969 {
29362970 char confname [200 ] = { 0 };
29372971 snprintf (confname , sizeof (confname ), "plugins/lighttable/collect/mode%1d" , active );
2938- const dt_lib_collect_mode_t mode =
2939- GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menuitem ), "menuitem_mode" ));
29402972
29412973 dt_conf_set_int (confname , mode );
29422974 snprintf (confname , sizeof (confname ), "plugins/lighttable/collect/string%1d" , active );
@@ -2951,17 +2983,22 @@ static void menuitem_mode(GtkMenuItem *menuitem,
29512983 DT_COLLECTION_PROP_UNDEF , NULL );
29522984}
29532985
2954- static void menuitem_mode_change (GtkMenuItem * menuitem ,
2955- dt_lib_collect_rule_t * d )
2986+ static void _menuitem_mode_change (GSimpleAction * action ,
2987+ GVariant * parameter ,
2988+ gpointer userdata )
29562989{
2990+ dt_lib_collect_mode_t mode ;
2991+ dt_lib_collect_rule_t * d = NULL ;
2992+
2993+ if (!_process_variant_params (parameter , userdata , & mode , & d ))
2994+ return ;
2995+
29572996 // add next row with and operator
29582997 const int num = d -> num + 1 ;
29592998 if (num < MAX_RULES && num > 0 )
29602999 {
29613000 char confname [200 ] = { 0 };
29623001 snprintf (confname , sizeof (confname ), "plugins/lighttable/collect/mode%1d" , num );
2963- const dt_lib_collect_mode_t mode =
2964- GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menuitem ), "menuitem_mode" ));
29653002 dt_conf_set_int (confname , mode );
29663003 }
29673004 dt_lib_collect_t * c = get_collect (d );
@@ -3184,9 +3221,15 @@ static void _metadata_changed(gpointer instance,
31843221 }
31853222}
31863223
3187- static void menuitem_clear (GtkMenuItem * menuitem ,
3188- dt_lib_collect_rule_t * d )
3224+ static void _menuitem_clear (GSimpleAction * simple ,
3225+ GVariant * parameter ,
3226+ gpointer userdata )
31893227{
3228+ dt_lib_collect_t * m = (dt_lib_collect_t * ) userdata ;
3229+
3230+ const int index = g_variant_get_int32 (parameter );
3231+ dt_lib_collect_rule_t * d = & m -> rule [index ];
3232+
31903233 // remove this row, or if 1st, clear text entry box
31913234 const int _a = dt_conf_get_int ("plugins/lighttable/collect/num_rules" );
31923235 const int active = CLAMP (_a , 1 , MAX_RULES );
@@ -3231,72 +3274,58 @@ static void menuitem_clear(GtkMenuItem *menuitem,
32313274 DT_COLLECTION_PROP_UNDEF , NULL );
32323275}
32333276
3234- static gboolean popup_button_callback (GtkWidget * widget ,
3277+ static gboolean popup_button_callback (GtkWidget * button ,
32353278 GdkEventButton * event ,
32363279 dt_lib_collect_rule_t * d )
32373280{
32383281 if (event -> button != 1 )
32393282 return FALSE;
32403283
3241- GtkWidget * menu = gtk_menu_new ();
3242- GtkWidget * mi ;
3284+ GMenu * menu = g_menu_new ();
32433285 const int _a = dt_conf_get_int ("plugins/lighttable/collect/num_rules" );
32443286 const int active = CLAMP (_a , 1 , MAX_RULES );
32453287
3246- mi = gtk_menu_item_new_with_label (_ ("clear this rule" ));
3247- gtk_menu_shell_append (GTK_MENU_SHELL (menu ), mi );
3248- g_signal_connect (G_OBJECT (mi ), "activate" , G_CALLBACK (menuitem_clear ), d );
3249-
3288+ gchar * action ;
3289+
3290+ action = g_strdup_printf ("collect.clear(%d)" , d -> num );
3291+ g_menu_append (menu , _ ("clear this rule" ), action );
3292+ g_free (action );
3293+
32503294 if (d -> num == active - 1 )
32513295 {
3252- mi = gtk_menu_item_new_with_label (_ ("narrow down search" ));
3253- g_object_set_data (G_OBJECT (mi ), "menuitem_mode" ,
3254- GINT_TO_POINTER (DT_LIB_COLLECT_MODE_AND ));
3255- gtk_menu_shell_append (GTK_MENU_SHELL (menu ), mi );
3256- g_signal_connect (G_OBJECT (mi ), "activate" ,
3257- G_CALLBACK (menuitem_mode ), d );
3258-
3259- mi = gtk_menu_item_new_with_label (_ ("add more images" ));
3260- g_object_set_data (G_OBJECT (mi ), "menuitem_mode" ,
3261- GINT_TO_POINTER (DT_LIB_COLLECT_MODE_OR ));
3262- gtk_menu_shell_append (GTK_MENU_SHELL (menu ), mi );
3263- g_signal_connect (G_OBJECT (mi ), "activate" ,
3264- G_CALLBACK (menuitem_mode ), d );
3265-
3266- mi = gtk_menu_item_new_with_label (_ ("exclude images" ));
3267- g_object_set_data (G_OBJECT (mi ), "menuitem_mode" ,
3268- GINT_TO_POINTER (DT_LIB_COLLECT_MODE_AND_NOT ));
3269- gtk_menu_shell_append (GTK_MENU_SHELL (menu ), mi );
3270- g_signal_connect (G_OBJECT (mi ), "activate" ,
3271- G_CALLBACK (menuitem_mode ), d );
3296+ const char * fmt = "collect.mode((%d,%d))" ;
3297+
3298+ action = g_strdup_printf (fmt , DT_LIB_COLLECT_MODE_AND , d -> num );
3299+ g_menu_append (menu , _ ("narrow down search" ), action );
3300+ g_free (action );
3301+
3302+ action = g_strdup_printf (fmt , DT_LIB_COLLECT_MODE_OR , d -> num );
3303+ g_menu_append (menu , _ ("add more images" ), action );
3304+ g_free (action );
3305+
3306+ action = g_strdup_printf (fmt , DT_LIB_COLLECT_MODE_AND_NOT , d -> num );
3307+ g_menu_append (menu , _ ("exclude images" ), action );
3308+ g_free (action );
32723309 }
32733310 else if (d -> num < active - 1 )
32743311 {
3275- mi = gtk_menu_item_new_with_label (_ ("change to: and" ));
3276- g_object_set_data (G_OBJECT (mi ), "menuitem_mode" ,
3277- GINT_TO_POINTER (DT_LIB_COLLECT_MODE_AND ));
3278- gtk_menu_shell_append (GTK_MENU_SHELL (menu ), mi );
3279- g_signal_connect (G_OBJECT (mi ), "activate" ,
3280- G_CALLBACK (menuitem_mode_change ), d );
3312+ const char * fmt = "collect.modechange((%d,%d))" ;
32813313
3282- mi = gtk_menu_item_new_with_label (_ ("change to: or" ));
3283- g_object_set_data (G_OBJECT (mi ), "menuitem_mode" ,
3284- GINT_TO_POINTER (DT_LIB_COLLECT_MODE_OR ));
3285- gtk_menu_shell_append (GTK_MENU_SHELL (menu ), mi );
3286- g_signal_connect (G_OBJECT (mi ), "activate" ,
3287- G_CALLBACK (menuitem_mode_change ), d );
3314+ action = g_strdup_printf (fmt , DT_LIB_COLLECT_MODE_AND , d -> num );
3315+ g_menu_append (menu , _ ("change to: and" ), action );
3316+ g_free (action );
32883317
3289- mi = gtk_menu_item_new_with_label (_ ("change to: except" ));
3290- g_object_set_data (G_OBJECT (mi ), "menuitem_mode" ,
3291- GINT_TO_POINTER (DT_LIB_COLLECT_MODE_AND_NOT ));
3292- gtk_menu_shell_append (GTK_MENU_SHELL (menu ), mi );
3293- g_signal_connect (G_OBJECT (mi ), "activate" ,
3294- G_CALLBACK (menuitem_mode_change ), d );
3295- }
3318+ action = g_strdup_printf (fmt , DT_LIB_COLLECT_MODE_OR , d -> num );
3319+ g_menu_append (menu , _ ("change to: or" ), action );
3320+ g_free (action );
32963321
3297- gtk_widget_show_all (GTK_WIDGET (menu ));
3322+ action = g_strdup_printf (fmt , DT_LIB_COLLECT_MODE_AND_NOT , d -> num );
3323+ g_menu_append (menu , _ ("change to: except" ), action );
3324+ g_free (action );
3325+ }
32983326
3299- gtk_menu_popup_at_pointer (GTK_MENU (menu ), (GdkEvent * )event );
3327+ GtkWidget * popover_menu = dt_gui_popover_menu_from_model (button , menu );
3328+ gtk_popover_popup (GTK_POPOVER (popover_menu ));
33003329
33013330 return TRUE;
33023331}
@@ -3654,6 +3683,17 @@ void gui_init(dt_lib_module_t *self)
36543683 self -> widget = dt_gui_vbox ();
36553684 dt_gui_add_class (self -> widget , "dt_spacing_sw" );
36563685
3686+ // setup the actions for this module
3687+ const GActionEntry entries [] = {
3688+ { "clear" , _menuitem_clear , "i" },
3689+ { "mode" , _menuitem_mode , "(ii)" },
3690+ { "modechange" , _menuitem_mode_change , "(ii)" }
3691+ };
3692+
3693+ d -> action_group = g_simple_action_group_new ();
3694+ g_action_map_add_action_entries (G_ACTION_MAP (d -> action_group ), entries , G_N_ELEMENTS (entries ), d );
3695+ gtk_widget_insert_action_group (self -> widget , "collect" , G_ACTION_GROUP (d -> action_group ));
3696+
36573697 d -> active_rule = 0 ;
36583698 d -> nb_rules = 0 ;
36593699 d -> params = (dt_lib_collect_params_t * )malloc (sizeof (dt_lib_collect_params_t ));
@@ -3808,6 +3848,8 @@ void gui_cleanup(dt_lib_module_t *self)
38083848 g_object_unref (d -> listfilter );
38093849 g_object_unref (d -> vmonitor );
38103850
3851+ g_object_unref (d -> action_group );
3852+
38113853 /* TODO: Make sure we are cleaning up all allocations */
38123854
38133855 free (self -> data );
0 commit comments