This is an automated email from the git hooks/post-receive script. n o m a d p u s h e d a c o m m i t t o b r a n c h m a s t e r in repository apps/xfdashboard.
commit 15b5708e57cf54fa19fbc980ad24185f34031711 Author: Stephan Haller <no...@froevel.de> Date: Mon Oct 23 12:17:57 2017 +0200 Implemented actions into pop-up menu of application buttons at quicklaunch This commit finally closes issue GH #158 --- libxfdashboard/desktop-app-info.c | 152 ++++++++++++++++++++++++++++++++------ libxfdashboard/desktop-app-info.h | 11 +++ libxfdashboard/quicklaunch.c | 111 +++++++++++++++++++++++++++- 3 files changed, 249 insertions(+), 25 deletions(-) diff --git a/libxfdashboard/desktop-app-info.c b/libxfdashboard/desktop-app-info.c index b058ec6..0c21e1e 100644 --- a/libxfdashboard/desktop-app-info.c +++ b/libxfdashboard/desktop-app-info.c @@ -29,7 +29,6 @@ #include <glib/gi18n-lib.h> #include <libxfdashboard/desktop-app-info.h> -#include <libxfdashboard/desktop-app-info-action.h> #include <libxfdashboard/application-database.h> #include <libxfdashboard/compat.h> #include <libxfdashboard/debug.h> @@ -391,37 +390,35 @@ static void _xfdashboard_desktop_app_info_expand_macros_add_uri(const gchar *inU } static gboolean _xfdashboard_desktop_app_info_expand_macros(XfdashboardDesktopAppInfo *self, + const gchar *inCommand, GList *inURIs, GString *ioExpanded) { XfdashboardDesktopAppInfoPrivate *priv; - const gchar *command; gboolean filesOrUriAdded; g_return_val_if_fail(XFDASHBOARD_IS_DESKTOP_APP_INFO(self), FALSE); + g_return_val_if_fail(inCommand && *inCommand, FALSE); g_return_val_if_fail(ioExpanded, FALSE); priv=self->priv; - /* Get command-line whose macros to expand */ - command=garcon_menu_item_get_command(priv->item); - /* Iterate through command-line char by char and expand known macros */ filesOrUriAdded=FALSE; - while(*command) + while(*inCommand) { /* Check if character is '%' indicating that a macro could follow ... */ - if(*command=='%') + if(*inCommand=='%') { /* Move to next character to determin which macro to expand - * but check also that we have not reached end of command-line. + * but check also that we have not reached end of inCommand-line. */ - command++; - if(!*command) break; + inCommand++; + if(!*inCommand) break; /* Expand macro */ - switch(*command) + switch(*inCommand) { case 'f': if(inURIs) _xfdashboard_desktop_app_info_expand_macros_add_file(inURIs->data, ioExpanded); @@ -510,14 +507,14 @@ static gboolean _xfdashboard_desktop_app_info_expand_macros(XfdashboardDesktopAp } } /* ... otherwise just add the character */ - else g_string_append_c(ioExpanded, *command); + else g_string_append_c(ioExpanded, *inCommand); - /* Continue with next character in command-line */ - command++; + /* Continue with next character in inCommand-line */ + inCommand++; } /* If URIs was provided but not used (exec key does not contain %f, %F, %u, %U) - * append first URI to expanded command-line. + * append first URI to expanded inCommand-line. */ if(inURIs && !filesOrUriAdded) { @@ -567,6 +564,7 @@ static void _xfdashboard_desktop_app_info_on_child_spawned(gpointer inUserData) } static gboolean _xfdashboard_desktop_app_info_launch_appinfo_internal(XfdashboardDesktopAppInfo *self, + const gchar *inCommand, GList *inURIs, GAppLaunchContext *inContext, GError **outError) @@ -585,6 +583,7 @@ static gboolean _xfdashboard_desktop_app_info_launch_appinfo_internal(Xfdashboar XfdashboardDesktopAppInfoChildSetupData childSetup; g_return_val_if_fail(XFDASHBOARD_IS_DESKTOP_APP_INFO(self), FALSE); + g_return_val_if_fail(inCommand && *inCommand, FALSE); g_return_val_if_fail(!inContext || G_IS_APP_LAUNCH_CONTEXT(inContext), FALSE); g_return_val_if_fail(outError && *outError==NULL, FALSE); @@ -600,7 +599,7 @@ static gboolean _xfdashboard_desktop_app_info_launch_appinfo_internal(Xfdashboar /* Get command-line with expanded macros */ expanded=g_string_new(NULL); if(!expanded || - !_xfdashboard_desktop_app_info_expand_macros(self, inURIs, expanded)) + !_xfdashboard_desktop_app_info_expand_macros(self, inCommand, inURIs, expanded)) { /* Set error */ g_set_error_literal(outError, @@ -1042,17 +1041,19 @@ static gboolean _xfdashboard_desktop_app_info_gappinfo_launch(GAppInfo *inAppInf GAppLaunchContext *inContext, GError **outError) { - XfdashboardDesktopAppInfo *self; - GList *iter; - GList *uris; - gchar *uri; - gboolean result; + XfdashboardDesktopAppInfo *self; + XfdashboardDesktopAppInfoPrivate *priv; + GList *iter; + GList *uris; + gchar *uri; + gboolean result; g_return_val_if_fail(XFDASHBOARD_IS_DESKTOP_APP_INFO(inAppInfo), FALSE); g_return_val_if_fail(!inContext || G_IS_APP_LAUNCH_CONTEXT(inContext), FALSE); g_return_val_if_fail(outError && *outError==NULL, FALSE); self=XFDASHBOARD_DESKTOP_APP_INFO(inAppInfo); + priv=self->priv; uris=NULL; /* Create list of URIs for files */ @@ -1065,6 +1066,7 @@ static gboolean _xfdashboard_desktop_app_info_gappinfo_launch(GAppInfo *inAppInf /* Call function to launch application of XfdashboardDesktopAppInfo with URIs */ result=_xfdashboard_desktop_app_info_launch_appinfo_internal(self, + garcon_menu_item_get_command(priv->item), uris, inContext, outError); @@ -1082,17 +1084,20 @@ static gboolean _xfdashboard_desktop_app_info_gappinfo_launch_uris(GAppInfo *inA GAppLaunchContext *inContext, GError **outError) { - XfdashboardDesktopAppInfo *self; - gboolean result; + XfdashboardDesktopAppInfo *self; + XfdashboardDesktopAppInfoPrivate *priv; + gboolean result; g_return_val_if_fail(XFDASHBOARD_IS_DESKTOP_APP_INFO(inAppInfo), FALSE); g_return_val_if_fail(!inContext || G_IS_APP_LAUNCH_CONTEXT(inContext), FALSE); g_return_val_if_fail(outError && *outError==NULL, FALSE); self=XFDASHBOARD_DESKTOP_APP_INFO(inAppInfo); + priv=self->priv; /* Call function to launch application of XfdashboardDesktopAppInfo with URIs */ result=_xfdashboard_desktop_app_info_launch_appinfo_internal(self, + garcon_menu_item_get_command(priv->item), inURIs, inContext, outError); @@ -1100,7 +1105,6 @@ static gboolean _xfdashboard_desktop_app_info_gappinfo_launch_uris(GAppInfo *inA return(result); } - /* Check if the application info should be shown */ static gboolean _xfdashboard_desktop_app_info_gappinfo_should_show(GAppInfo *inAppInfo) { @@ -1521,3 +1525,103 @@ gboolean xfdashboard_desktop_app_info_reload(XfdashboardDesktopAppInfo *self) /* Return success result */ return(success); } + +/* Get list of application actions */ +GList* xfdashboard_desktop_app_info_get_actions(XfdashboardDesktopAppInfo *self) +{ + g_return_val_if_fail(XFDASHBOARD_IS_DESKTOP_APP_INFO(self), FALSE); + + /* Return the create copy of list of application actions */ + return(self->priv->actions); +} + +/* Launch application action at this application */ +gboolean xfdashboard_desktop_app_info_launch_action(XfdashboardDesktopAppInfo *self, + XfdashboardDesktopAppInfoAction *inAction, + GAppLaunchContext *inContext, + GError **outError) +{ + const gchar *actionName; + gboolean success; + + g_return_val_if_fail(XFDASHBOARD_IS_DESKTOP_APP_INFO(self), FALSE); + g_return_val_if_fail(XFDASHBOARD_IS_DESKTOP_APP_INFO_ACTION(inAction), FALSE); + g_return_val_if_fail(!inContext || G_IS_APP_LAUNCH_CONTEXT(inContext), FALSE); + g_return_val_if_fail(outError && *outError==NULL, FALSE); + + /* Launch by application action's name as it will lookup a maybe updated + * action, e.g. when reloaded in the meantime. + */ + actionName=xfdashboard_desktop_app_info_action_get_name(inAction); + success=xfdashboard_desktop_app_info_launch_action_by_name(self, + actionName, + inContext, + outError); + + /* Return success result */ + return(success); +} + +gboolean xfdashboard_desktop_app_info_launch_action_by_name(XfdashboardDesktopAppInfo *self, + const gchar *inActionName, + GAppLaunchContext *inContext, + GError **outError) +{ + XfdashboardDesktopAppInfoPrivate *priv; + XfdashboardDesktopAppInfoAction *action; + GList *iter; + gboolean success; + + g_return_val_if_fail(XFDASHBOARD_IS_DESKTOP_APP_INFO(self), FALSE); + g_return_val_if_fail(inActionName && *inActionName, FALSE); + g_return_val_if_fail(!inContext || G_IS_APP_LAUNCH_CONTEXT(inContext), FALSE); + g_return_val_if_fail(outError && *outError==NULL, FALSE); + + priv=self->priv; + + /* Find application action data by name */ + action=NULL; + for(iter=priv->actions; iter && !action; iter=g_list_next(iter)) + { + XfdashboardDesktopAppInfoAction *iterAction; + + iterAction=XFDASHBOARD_DESKTOP_APP_INFO_ACTION(iter->data); + if(!iterAction) continue; + + if(g_strcmp0(xfdashboard_desktop_app_info_action_get_name(iterAction), inActionName)==0) + { + action=iterAction; + } + } + + if(!action) + { + /* Set error */ + g_set_error(outError, + G_IO_ERROR, + G_IO_ERROR_NOT_FOUND, + _("Invalid application action '%s' to execute for desktop ID '%s'"), + inActionName, + priv->desktopID); + + /* Return fail status */ + return(FALSE); + } + + /* Launch application action found */ + success=_xfdashboard_desktop_app_info_launch_appinfo_internal(self, + xfdashboard_desktop_app_info_action_get_command(action), + NULL, + inContext, + outError); + if(!success) + { + g_warning(_("Could launch action '%s' for desktop ID '%s': %s"), + xfdashboard_desktop_app_info_action_get_name(action), + self->priv->desktopID, + (outError && *outError) ? (*outError)->message : _("Unknown error")); + } + + /* Return success result of launching action */ + return(success); +} diff --git a/libxfdashboard/desktop-app-info.h b/libxfdashboard/desktop-app-info.h index 193b917..5e69e0c 100644 --- a/libxfdashboard/desktop-app-info.h +++ b/libxfdashboard/desktop-app-info.h @@ -29,6 +29,7 @@ #error "Only <libxfdashboard/libxfdashboard.h> can be included directly." #endif +#include <libxfdashboard/desktop-app-info-action.h> #include <garcon/garcon.h> G_BEGIN_DECLS @@ -78,6 +79,16 @@ gboolean xfdashboard_desktop_app_info_is_valid(XfdashboardDesktopAppInfo *self); GFile* xfdashboard_desktop_app_info_get_file(XfdashboardDesktopAppInfo *self); gboolean xfdashboard_desktop_app_info_reload(XfdashboardDesktopAppInfo *self); +GList* xfdashboard_desktop_app_info_get_actions(XfdashboardDesktopAppInfo *self); +gboolean xfdashboard_desktop_app_info_launch_action(XfdashboardDesktopAppInfo *self, + XfdashboardDesktopAppInfoAction *inAction, + GAppLaunchContext *inContext, + GError **outError); +gboolean xfdashboard_desktop_app_info_launch_action_by_name(XfdashboardDesktopAppInfo *self, + const gchar *inActionName, + GAppLaunchContext *inContext, + GError **outError); + G_END_DECLS #endif /* __LIBXFDASHBOARD_DESKTOP_APP_INFO__ */ diff --git a/libxfdashboard/quicklaunch.c b/libxfdashboard/quicklaunch.c index f73bbbf..9f4e795 100644 --- a/libxfdashboard/quicklaunch.c +++ b/libxfdashboard/quicklaunch.c @@ -43,6 +43,7 @@ #include <libxfdashboard/focusable.h> #include <libxfdashboard/marshal.h> #include <libxfdashboard/desktop-app-info.h> +#include <libxfdashboard/desktop-app-info-action.h> #include <libxfdashboard/application-database.h> #include <libxfdashboard/application-tracker.h> #include <libxfdashboard/window-tracker.h> @@ -654,6 +655,73 @@ static void _xfdashboard_quicklaunch_on_favourite_popup_menu_item_add_to_favouri } } + +/* User selected to execute an application action */ +static void _xfdashboard_quicklaunch_on_favourite_popup_menu_item_application_action(XfdashboardPopupMenuItem *inMenuItem, + gpointer inUserData) +{ + XfdashboardQuicklaunch *self; + XfdashboardDesktopAppInfo *appInfo; + XfdashboardDesktopAppInfoAction *appAction; + GError *error; + + g_return_if_fail(XFDASHBOARD_IS_POPUP_MENU_ITEM(inMenuItem)); + g_return_if_fail(XFDASHBOARD_IS_QUICKLAUNCH(inUserData)); + + self=XFDASHBOARD_QUICKLAUNCH(inUserData); + error=NULL; + + /* Get application and action to execute */ + appInfo=XFDASHBOARD_DESKTOP_APP_INFO(g_object_get_data(G_OBJECT(inMenuItem), "popup-menu-item-app-info")); + if(!appInfo) + { + g_warning(_("Could not get application to execute action")); + return; + } + + appAction=XFDASHBOARD_DESKTOP_APP_INFO_ACTION(g_object_get_data(G_OBJECT(inMenuItem), "popup-menu-item-app-action")); + if(!appInfo) + { + g_warning(_("Could not get application action for application '%s'"), + g_app_info_get_display_name(G_APP_INFO(appInfo))); + return; + } + + /* Execute action */ + if(!xfdashboard_desktop_app_info_launch_action(appInfo, appAction, NULL, &error)) + { + /* Show notification about failed launch of action */ + xfdashboard_notify(CLUTTER_ACTOR(self), + "dialog-error", + _("Could not execute action '%s' for application '%s': %s"), + xfdashboard_desktop_app_info_action_get_name(appAction), + g_app_info_get_display_name(G_APP_INFO(appInfo)), + error ? error->message : _("Unknown error")); + g_error_free(error); + } + else + { + GIcon *gicon; + const gchar *iconName; + + /* Get icon of application */ + iconName=NULL; + + gicon=g_app_info_get_icon(appInfo); + if(gicon) iconName=g_icon_to_string(gicon); + + /* Show notification about successful launch of action */ + xfdashboard_notify(CLUTTER_ACTOR(self), + iconName, + _("Executed action '%s' for application '%s'"), + xfdashboard_desktop_app_info_action_get_name(appAction), + g_app_info_get_display_name(G_APP_INFO(appInfo))); + + /* Release allocated resources */ + g_object_unref(gicon); + } +} + /* A right-click might have happened on an application icon (favourite) in quicklaunch */ static void _xfdashboard_quicklaunch_on_favourite_popup_menu(XfdashboardQuicklaunch *self, ClutterActor *inActor, @@ -797,7 +865,48 @@ static void _xfdashboard_quicklaunch_on_favourite_popup_menu(XfdashboardQuicklau appInfo); } -// TODO: Add actions from GAppInfo + /* Add application actions */ + if(XFDASHBOARD_IS_DESKTOP_APP_INFO(appInfo)) + { + GList *appActions; + const GList *iter; + + appActions=xfdashboard_desktop_app_info_get_actions(XFDASHBOARD_DESKTOP_APP_INFO(appInfo)); + for(iter=appActions; iter; iter=g_list_next(iter)) + { + XfdashboardDesktopAppInfoAction *appAction; + const gchar *iconName; + + /* Get currently iterated application action */ + appAction=XFDASHBOARD_DESKTOP_APP_INFO_ACTION(iter->data); + if(!appAction) continue; + + /* Get icon name to determine style of pop-up menu item */ + iconName=xfdashboard_desktop_app_info_action_get_icon_name(appAction); + + /* Create pop-up menu item. If icon name is available then set + * style to both (text+icon) and set icon. If icon name is NULL + * then keep style at text-only. + */ + menuItem=xfdashboard_popup_menu_item_button_new(); + xfdashboard_label_set_text(XFDASHBOARD_LABEL(menuItem), xfdashboard_desktop_app_info_action_get_name(appAction)); + if(iconName) + { + xfdashboard_label_set_icon_name(XFDASHBOARD_LABEL(menuItem), iconName); + xfdashboard_label_set_style(XFDASHBOARD_LABEL(menuItem), XFDASHBOARD_LABEL_STYLE_BOTH); + } + clutter_actor_set_x_expand(menuItem, TRUE); + xfdashboard_popup_menu_add_item(XFDASHBOARD_POPUP_MENU(popup), XFDASHBOARD_POPUP_MENU_ITEM(menuItem)); + + g_object_set_data_full(G_OBJECT(menuItem), "popup-menu-item-app-info", g_object_ref(appInfo), g_object_unref); + g_object_set_data_full(G_OBJECT(menuItem), "popup-menu-item-app-action", g_object_ref(appAction), g_object_unref); + + g_signal_connect(menuItem, + "activated", + G_CALLBACK(_xfdashboard_quicklaunch_on_favourite_popup_menu_item_application_action), + self); + } + } /* Add "Remove from favourites" if application button is for a favourite application */ if(xfdashboard_stylable_has_class(XFDASHBOARD_STYLABLE(appButton), "favourite-app")) -- To stop receiving notification emails like this one, please contact the administrator of this repository. _______________________________________________ Xfce4-commits mailing list Xfce4-commits@xfce.org https://mail.xfce.org/mailman/listinfo/xfce4-commits