@@ -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,28 @@ 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 void menuitem_mode (GSimpleAction * simple ,
2930+ GVariant * parameter ,
2931+ gpointer userdata )
29292932{
2933+ dt_lib_collect_t * m = (dt_lib_collect_t * ) userdata ;
2934+
2935+ gsize nb = g_variant_n_children (parameter );
2936+
2937+ if (nb != 2 )
2938+ return ;
2939+
2940+ GVariant * v ;
2941+ v = g_variant_get_child_value (parameter , 0 );
2942+ const dt_lib_collect_mode_t 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+ dt_lib_collect_rule_t * d = & m -> rule [rule_index ];
2950+
29302951 // add next row with and operator
29312952 const int _a = dt_conf_get_int ("plugins/lighttable/collect/num_rules" );
29322953 const int active = CLAMP (_a , 1 , MAX_RULES );
@@ -2935,8 +2956,6 @@ static void menuitem_mode(GtkMenuItem *menuitem,
29352956 {
29362957 char confname [200 ] = { 0 };
29372958 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" ));
29402959
29412960 dt_conf_set_int (confname , mode );
29422961 snprintf (confname , sizeof (confname ), "plugins/lighttable/collect/string%1d" , active );
@@ -2951,17 +2970,34 @@ static void menuitem_mode(GtkMenuItem *menuitem,
29512970 DT_COLLECTION_PROP_UNDEF , NULL );
29522971}
29532972
2954- static void menuitem_mode_change (GtkMenuItem * menuitem ,
2955- dt_lib_collect_rule_t * d )
2973+ static void menuitem_mode_change (GSimpleAction * simple ,
2974+ GVariant * parameter ,
2975+ gpointer userdata )
29562976{
2977+ dt_lib_collect_t * m = (dt_lib_collect_t * ) userdata ;
2978+
2979+ gsize nb = g_variant_n_children (parameter );
2980+
2981+ if (nb != 2 )
2982+ return ;
2983+
2984+ GVariant * v ;
2985+ v = g_variant_get_child_value (parameter , 0 );
2986+ const dt_lib_collect_mode_t mode = g_variant_get_int32 (v );
2987+ g_variant_unref (v );
2988+
2989+ v = g_variant_get_child_value (parameter , 1 );
2990+ const int rule_index = g_variant_get_int32 (v );
2991+ g_variant_unref (v );
2992+
2993+ dt_lib_collect_rule_t * d = & m -> rule [rule_index ];
2994+
29572995 // add next row with and operator
29582996 const int num = d -> num + 1 ;
29592997 if (num < MAX_RULES && num > 0 )
29602998 {
29612999 char confname [200 ] = { 0 };
29623000 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" ));
29653001 dt_conf_set_int (confname , mode );
29663002 }
29673003 dt_lib_collect_t * c = get_collect (d );
@@ -3184,9 +3220,15 @@ static void _metadata_changed(gpointer instance,
31843220 }
31853221}
31863222
3187- static void menuitem_clear (GtkMenuItem * menuitem ,
3188- dt_lib_collect_rule_t * d )
3223+ static void menuitem_clear (GSimpleAction * simple ,
3224+ GVariant * parameter ,
3225+ gpointer userdata )
31893226{
3227+ dt_lib_collect_t * m = (dt_lib_collect_t * ) userdata ;
3228+
3229+ const int index = g_variant_get_int32 (parameter );
3230+ dt_lib_collect_rule_t * d = & m -> rule [index ];
3231+
31903232 // remove this row, or if 1st, clear text entry box
31913233 const int _a = dt_conf_get_int ("plugins/lighttable/collect/num_rules" );
31923234 const int active = CLAMP (_a , 1 , MAX_RULES );
@@ -3231,72 +3273,58 @@ static void menuitem_clear(GtkMenuItem *menuitem,
32313273 DT_COLLECTION_PROP_UNDEF , NULL );
32323274}
32333275
3234- static gboolean popup_button_callback (GtkWidget * widget ,
3276+ static gboolean popup_button_callback (GtkWidget * button ,
32353277 GdkEventButton * event ,
32363278 dt_lib_collect_rule_t * d )
32373279{
32383280 if (event -> button != 1 )
32393281 return FALSE;
32403282
3241- GtkWidget * menu = gtk_menu_new ();
3242- GtkWidget * mi ;
3283+ GMenu * menu = g_menu_new ();
32433284 const int _a = dt_conf_get_int ("plugins/lighttable/collect/num_rules" );
32443285 const int active = CLAMP (_a , 1 , MAX_RULES );
32453286
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-
3287+ gchar * action ;
3288+
3289+ action = g_strdup_printf ("collect.clear(%d)" , d -> num );
3290+ g_menu_append (menu , _ ("clear this rule" ), action );
3291+ g_free (action );
3292+
32503293 if (d -> num == active - 1 )
32513294 {
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 );
3295+ const char * fmt = "collect.mode((%d,%d))" ;
3296+
3297+ action = g_strdup_printf (fmt , DT_LIB_COLLECT_MODE_AND , d -> num );
3298+ g_menu_append (menu , _ ("narrow down search" ), action );
3299+ g_free (action );
3300+
3301+ action = g_strdup_printf (fmt , DT_LIB_COLLECT_MODE_OR , d -> num );
3302+ g_menu_append (menu , _ ("add more images" ), action );
3303+ g_free (action );
3304+
3305+ action = g_strdup_printf (fmt , DT_LIB_COLLECT_MODE_AND_NOT , d -> num );
3306+ g_menu_append (menu , _ ("exclude images" ), action );
3307+ g_free (action );
32723308 }
32733309 else if (d -> num < active - 1 )
32743310 {
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 );
3311+ const char * fmt = "collect.modechange((%d,%d))" ;
32813312
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 );
3313+ action = g_strdup_printf (fmt , DT_LIB_COLLECT_MODE_AND , d -> num );
3314+ g_menu_append (menu , _ ("change to: and" ), action );
3315+ g_free (action );
32883316
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- }
3317+ action = g_strdup_printf (fmt , DT_LIB_COLLECT_MODE_OR , d -> num );
3318+ g_menu_append (menu , _ ("change to: or" ), action );
3319+ g_free (action );
32963320
3297- gtk_widget_show_all (GTK_WIDGET (menu ));
3321+ action = g_strdup_printf (fmt , DT_LIB_COLLECT_MODE_AND_NOT , d -> num );
3322+ g_menu_append (menu , _ ("change to: except" ), action );
3323+ g_free (action );
3324+ }
32983325
3299- gtk_menu_popup_at_pointer (GTK_MENU (menu ), (GdkEvent * )event );
3326+ GtkWidget * popover_menu = dt_gui_popover_menu_from_model (button , menu );
3327+ gtk_popover_popup (GTK_POPOVER (popover_menu ));
33003328
33013329 return TRUE;
33023330}
@@ -3654,6 +3682,17 @@ void gui_init(dt_lib_module_t *self)
36543682 self -> widget = dt_gui_vbox ();
36553683 dt_gui_add_class (self -> widget , "dt_spacing_sw" );
36563684
3685+ // setup the actions for this module
3686+ const GActionEntry entries [] = {
3687+ { "clear" , menuitem_clear , "i" },
3688+ { "mode" , menuitem_mode , "(ii)" },
3689+ { "modechange" , menuitem_mode_change , "(ii)" }
3690+ };
3691+
3692+ d -> action_group = g_simple_action_group_new ();
3693+ g_action_map_add_action_entries (G_ACTION_MAP (d -> action_group ), entries , G_N_ELEMENTS (entries ), d );
3694+ gtk_widget_insert_action_group (self -> widget , "collect" , G_ACTION_GROUP (d -> action_group ));
3695+
36573696 d -> active_rule = 0 ;
36583697 d -> nb_rules = 0 ;
36593698 d -> params = (dt_lib_collect_params_t * )malloc (sizeof (dt_lib_collect_params_t ));
@@ -3808,6 +3847,8 @@ void gui_cleanup(dt_lib_module_t *self)
38083847 g_object_unref (d -> listfilter );
38093848 g_object_unref (d -> vmonitor );
38103849
3850+ g_object_unref (d -> action_group );
3851+
38113852 /* TODO: Make sure we are cleaning up all allocations */
38123853
38133854 free (self -> data );
0 commit comments