diff options
Diffstat (limited to 'libslab/application-tile.c')
-rw-r--r-- | libslab/application-tile.c | 886 |
1 files changed, 886 insertions, 0 deletions
diff --git a/libslab/application-tile.c b/libslab/application-tile.c new file mode 100644 index 00000000..81a1e373 --- /dev/null +++ b/libslab/application-tile.c @@ -0,0 +1,886 @@ +/* + * This file is part of libtile. + * + * Copyright (c) 2006, 2007 Novell, Inc. + * + * Libtile is free software; you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * Libtile is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + * more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libslab; if not, write to the Free Software Foundation, Inc., 51 + * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "application-tile.h" +#include "config.h" + +#include <string.h> +#include <glib.h> +#include <glib/gi18n-lib.h> +#include <glib/gstdio.h> +#include <mateconf/mateconf-client.h> +#include <unistd.h> + +#include "slab-mate-util.h" +#include "libslab-utils.h" +#include "bookmark-agent.h" +#include "themed-icon.h" + +G_DEFINE_TYPE (ApplicationTile, application_tile, NAMEPLATE_TILE_TYPE) + +typedef enum { + APP_IN_USER_STARTUP_DIR, + APP_NOT_IN_STARTUP_DIR, + APP_NOT_ELIGIBLE +} StartupStatus; + +static void application_tile_get_property (GObject *, guint, GValue *, GParamSpec *); +static void application_tile_set_property (GObject *, guint, const GValue *, GParamSpec *); +static void application_tile_finalize (GObject *); + +static void application_tile_setup (ApplicationTile *, const gchar *); + +static GtkWidget *create_header (const gchar *); +static GtkWidget *create_subheader (const gchar *); + +static void header_size_allocate_cb (GtkWidget *, GtkAllocation *, gpointer); + +static void start_trigger (Tile *, TileEvent *, TileAction *); +static void help_trigger (Tile *, TileEvent *, TileAction *); +static void user_apps_trigger (Tile *, TileEvent *, TileAction *); +static void startup_trigger (Tile *, TileEvent *, TileAction *); +static void upgrade_trigger (Tile *, TileEvent *, TileAction *); +static void uninstall_trigger (Tile *, TileEvent *, TileAction *); + +static void add_to_user_list (ApplicationTile *); +static void remove_from_user_list (ApplicationTile *); +static void add_to_startup_list (ApplicationTile *); +static void remove_from_startup_list (ApplicationTile *); + +static gboolean verify_package_management_command (const gchar *); +static void run_package_management_command (ApplicationTile *, gchar *); + +static void update_user_list_menu_item (ApplicationTile *); +static void agent_notify_cb (GObject *, GParamSpec *, gpointer); + +static StartupStatus get_desktop_item_startup_status (MateDesktopItem *); +static void update_startup_menu_item (ApplicationTile *); + +typedef struct { + MateDesktopItem *desktop_item; + + gchar *image_id; + gboolean image_is_broken; + GtkIconSize image_size; + + gboolean show_generic_name; + StartupStatus startup_status; + + BookmarkAgent *agent; + BookmarkStoreStatus agent_status; + gboolean is_bookmarked; + gulong notify_signal_id; +} ApplicationTilePrivate; + +#define APPLICATION_TILE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), APPLICATION_TILE_TYPE, ApplicationTilePrivate)) + +enum { + PROP_0, + PROP_APPLICATION_NAME, + PROP_APPLICATION_DESCRIPTION, + PROP_APPLICATION_MATECONF_PREFIX +}; + +static void +application_tile_class_init (ApplicationTileClass *app_tile_class) +{ + GObjectClass *g_obj_class = G_OBJECT_CLASS (app_tile_class); + + g_obj_class->get_property = application_tile_get_property; + g_obj_class->set_property = application_tile_set_property; + g_obj_class->finalize = application_tile_finalize; + + g_type_class_add_private (app_tile_class, sizeof (ApplicationTilePrivate)); + + g_object_class_install_property ( + g_obj_class, PROP_APPLICATION_NAME, + g_param_spec_string ( + "application-name", "application-name", + "the name of the application", NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + g_obj_class, PROP_APPLICATION_DESCRIPTION, + g_param_spec_string ( + "application-description", "application-description", + "the name of the application", NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + g_obj_class, PROP_APPLICATION_MATECONF_PREFIX, + g_param_spec_string ( + "mateconf-prefix", "mateconf-prefix", + "configuration prefix", NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); +} + +GtkWidget * +application_tile_new (const gchar *desktop_item_id) +{ + return application_tile_new_full (desktop_item_id, GTK_ICON_SIZE_DND, TRUE, NULL); +} + +GtkWidget * +application_tile_new_full (const gchar *desktop_item_id, + GtkIconSize image_size, gboolean show_generic_name, const gchar *mateconf_prefix) +{ + ApplicationTile *this; + ApplicationTilePrivate *priv; + + const gchar *uri = NULL; + + MateDesktopItem *desktop_item; + + + desktop_item = load_desktop_item_from_unknown (desktop_item_id); + + if ( + desktop_item && + mate_desktop_item_get_entry_type (desktop_item) == MATE_DESKTOP_ITEM_TYPE_APPLICATION + ) + uri = mate_desktop_item_get_location (desktop_item); + + if (! uri) { + if (desktop_item) + mate_desktop_item_unref (desktop_item); + + return NULL; + } + + this = g_object_new (APPLICATION_TILE_TYPE, "tile-uri", uri, NULL); + priv = APPLICATION_TILE_GET_PRIVATE (this); + + priv->image_size = image_size; + priv->desktop_item = desktop_item; + priv->show_generic_name = show_generic_name; + + application_tile_setup (this, mateconf_prefix); + + return GTK_WIDGET (this); +} + +static void +application_tile_init (ApplicationTile *tile) +{ + ApplicationTilePrivate *priv = APPLICATION_TILE_GET_PRIVATE (tile); + + priv->desktop_item = NULL; + priv->image_id = NULL; + priv->image_is_broken = TRUE; + + priv->agent = NULL; + priv->agent_status = BOOKMARK_STORE_ABSENT; + priv->is_bookmarked = FALSE; + priv->notify_signal_id = 0; + + tile->name = tile->description = tile->mateconf_prefix = NULL; +} + +static void +application_tile_finalize (GObject *g_object) +{ + ApplicationTile *tile = APPLICATION_TILE (g_object); + ApplicationTilePrivate *priv = APPLICATION_TILE_GET_PRIVATE (g_object); + + if (tile->name) { + g_free (tile->name); + tile->name = NULL; + } + if (tile->description) { + g_free (tile->description); + tile->description = NULL; + } + if (tile->mateconf_prefix) { + g_free (tile->mateconf_prefix); + tile->mateconf_prefix = NULL; + } + + if (priv->desktop_item) { + mate_desktop_item_unref (priv->desktop_item); + priv->desktop_item = NULL; + } + if (priv->image_id) { + g_free (priv->image_id); + priv->image_id = NULL; + } + + if (priv->notify_signal_id) + g_signal_handler_disconnect (priv->agent, priv->notify_signal_id); + + g_object_unref (G_OBJECT (priv->agent)); + + G_OBJECT_CLASS (application_tile_parent_class)->finalize (g_object); +} + +static void +application_tile_get_property (GObject *g_obj, guint prop_id, GValue *value, GParamSpec *param_spec) +{ + ApplicationTile *tile = APPLICATION_TILE (g_obj); + + switch (prop_id) { + case PROP_APPLICATION_NAME: + g_value_set_string (value, tile->name); + break; + + case PROP_APPLICATION_DESCRIPTION: + g_value_set_string (value, tile->description); + break; + + case PROP_APPLICATION_MATECONF_PREFIX: + g_value_set_string (value, tile->mateconf_prefix); + break; + + default: + break; + } +} + +static void +application_tile_set_property (GObject *g_obj, guint prop_id, const GValue *value, GParamSpec *param_spec) +{ + ApplicationTile *tile = APPLICATION_TILE (g_obj); + + switch (prop_id) { + case PROP_APPLICATION_NAME: + if (tile->name) + g_free (tile->name); + tile->name = g_strdup (g_value_get_string (value)); + break; + + case PROP_APPLICATION_DESCRIPTION: + if (tile->description) + g_free (tile->description); + tile->description = g_strdup (g_value_get_string (value)); + break; + + case PROP_APPLICATION_MATECONF_PREFIX: + if (tile->mateconf_prefix) + g_free (tile->mateconf_prefix); + tile->mateconf_prefix = g_strdup (g_value_get_string (value)); + break; + + default: + break; + } +} + +static void +application_tile_setup (ApplicationTile *this, const gchar *mateconf_prefix) +{ + ApplicationTilePrivate *priv = APPLICATION_TILE_GET_PRIVATE (this); + + GtkWidget *image; + GtkWidget *header; + GtkWidget *subheader; + GtkMenu *context_menu; + AtkObject *accessible; + + TileAction **actions; + TileAction *action; + GtkWidget *menu_item; + GtkContainer *menu_ctnr; + + const gchar *name; + const gchar *desc; + + const gchar *comment; + + const gchar *key; + gchar *markup; + gchar *str; + + /*Fixme - need to address the entire mateconf key location issue */ + /*Fixme - this is just a temporary stop gap */ + gboolean use_new_prefix; + + + if (! priv->desktop_item) { + priv->desktop_item = load_desktop_item_from_unknown (TILE (this)->uri); + + if (! priv->desktop_item) + return; + } + + priv->image_id = g_strdup (mate_desktop_item_get_localestring (priv->desktop_item, "Icon")); + image = themed_icon_new (priv->image_id, priv->image_size); + + name = mate_desktop_item_get_localestring (priv->desktop_item, "Name"); + desc = mate_desktop_item_get_localestring (priv->desktop_item, "GenericName"); + comment = mate_desktop_item_get_localestring (priv->desktop_item, "Comment"); + + accessible = gtk_widget_get_accessible (GTK_WIDGET (this)); + if (name) + atk_object_set_name (accessible, name); + if (desc) + atk_object_set_description (accessible, desc); + + header = create_header (name); + + /*if no GenericName then just show and center the Name */ + if (desc && priv->show_generic_name + && (!name || strcmp(name, desc) != 0)) + subheader = create_subheader (desc); + else + subheader = NULL; + + context_menu = GTK_MENU (gtk_menu_new ()); + + g_object_set ( + G_OBJECT (this), + "nameplate-image", image, + "nameplate-header", header, + "nameplate-subheader", subheader, + "context-menu", context_menu, + "application-name", name, + "application-description", desc, + "mateconf-prefix", mateconf_prefix, + NULL); + gtk_widget_set_tooltip_text (GTK_WIDGET (this), comment); + + priv->agent = bookmark_agent_get_instance (BOOKMARK_STORE_USER_APPS); + g_object_get (G_OBJECT (priv->agent), BOOKMARK_AGENT_STORE_STATUS_PROP, & priv->agent_status, NULL); + + priv->notify_signal_id = g_signal_connect ( + G_OBJECT (priv->agent), "notify", G_CALLBACK (agent_notify_cb), this); + + priv->startup_status = get_desktop_item_startup_status (priv->desktop_item); + + actions = g_new0 (TileAction *, 6); + + TILE (this)->actions = actions; + TILE (this)->n_actions = 6; + + menu_ctnr = GTK_CONTAINER (TILE (this)->context_menu); + +/* make start action */ + + str = g_strdup_printf (_("Start %s"), this->name); + markup = g_markup_printf_escaped ("<b>%s</b>", str); + action = tile_action_new (TILE (this), start_trigger, markup, TILE_ACTION_OPENS_NEW_WINDOW); + actions [APPLICATION_TILE_ACTION_START] = action; + g_free (markup); + g_free (str); + + menu_item = GTK_WIDGET (tile_action_get_menu_item (action)); + + gtk_container_add (menu_ctnr, menu_item); + + TILE (this)->default_action = action; + +/* insert separator */ + + gtk_container_add (menu_ctnr, gtk_separator_menu_item_new ()); + +/* make help action */ + + if (mate_desktop_item_get_string (priv->desktop_item, "DocPath")) { + action = tile_action_new ( + TILE (this), help_trigger, _("Help"), + TILE_ACTION_OPENS_NEW_WINDOW | TILE_ACTION_OPENS_HELP); + + menu_item = GTK_WIDGET (tile_action_get_menu_item (action)); + gtk_container_add (menu_ctnr, menu_item); + } + else { + action = NULL; + } + + actions [APPLICATION_TILE_ACTION_HELP] = action; + +/* insert separator */ + + if (action != NULL) + gtk_container_add (menu_ctnr, gtk_separator_menu_item_new ()); + +/* make "add/remove to favorites" action */ + + update_user_list_menu_item (this); + +/* make "add/remove to startup" action */ + + if (priv->startup_status != APP_NOT_ELIGIBLE) { + action = tile_action_new (TILE (this), startup_trigger, NULL, 0); + actions [APPLICATION_TILE_ACTION_UPDATE_STARTUP] = action; + + update_startup_menu_item (this); + + menu_item = GTK_WIDGET (tile_action_get_menu_item (action)); + + gtk_container_add (menu_ctnr, menu_item); + } + +/* make upgrade action */ + + if (this->mateconf_prefix && ! g_str_has_prefix (this->mateconf_prefix, "/desktop/")) + use_new_prefix = TRUE; + else + use_new_prefix = FALSE; + + if(!use_new_prefix) + key = SLAB_UPGRADE_PACKAGE_KEY; + else + key = "/apps/main-menu/upgrade_package_command"; + + if (verify_package_management_command (key)) { + action = tile_action_new (TILE (this), upgrade_trigger, _("Upgrade"), TILE_ACTION_OPENS_NEW_WINDOW); + actions [APPLICATION_TILE_ACTION_UPGRADE_PACKAGE] = action; + menu_item = GTK_WIDGET (tile_action_get_menu_item (action)); + gtk_container_add (menu_ctnr, menu_item); + } else + actions [APPLICATION_TILE_ACTION_UPGRADE_PACKAGE] = NULL; + +/* make uninstall action */ + + if(!use_new_prefix) + key = SLAB_UNINSTALL_PACKAGE_KEY; + else + key = "/apps/main-menu/uninstall_package_command"; + + if (verify_package_management_command (key)) { + action = tile_action_new (TILE (this), uninstall_trigger, _("Uninstall"), TILE_ACTION_OPENS_NEW_WINDOW); + actions [APPLICATION_TILE_ACTION_UNINSTALL_PACKAGE] = action; + menu_item = GTK_WIDGET (tile_action_get_menu_item (action)); + gtk_container_add (menu_ctnr, menu_item); + } else + actions [APPLICATION_TILE_ACTION_UNINSTALL_PACKAGE] = NULL; + + gtk_widget_show_all (GTK_WIDGET (TILE (this)->context_menu)); +} + +static GtkWidget * +create_header (const gchar *name) +{ + GtkWidget *header; + + + header = gtk_label_new (name); + gtk_label_set_line_wrap (GTK_LABEL (header), TRUE); + gtk_misc_set_alignment (GTK_MISC (header), 0.0, 0.5); + + g_signal_connect ( + G_OBJECT (header), + "size-allocate", + G_CALLBACK (header_size_allocate_cb), + NULL); + + return header; +} + +static GtkWidget * +create_subheader (const gchar *desc) +{ + GtkWidget *subheader; + + + subheader = gtk_label_new (desc); + gtk_label_set_ellipsize (GTK_LABEL (subheader), PANGO_ELLIPSIZE_END); + gtk_misc_set_alignment (GTK_MISC (subheader), 0.0, 0.5); + gtk_widget_modify_fg ( + subheader, + GTK_STATE_NORMAL, + & subheader->style->fg [GTK_STATE_INSENSITIVE]); + + return subheader; +} + +static void +start_trigger (Tile *tile, TileEvent *event, TileAction *action) +{ + open_desktop_item_exec (APPLICATION_TILE_GET_PRIVATE (tile)->desktop_item); +} + +static void +help_trigger (Tile *tile, TileEvent *event, TileAction *action) +{ + open_desktop_item_help (APPLICATION_TILE_GET_PRIVATE (tile)->desktop_item); +} + +static void +user_apps_trigger (Tile *tile, TileEvent *event, TileAction *action) +{ + ApplicationTile *this = APPLICATION_TILE (tile); + ApplicationTilePrivate *priv = APPLICATION_TILE_GET_PRIVATE (this); + + if (priv->is_bookmarked) + remove_from_user_list (this); + else + add_to_user_list (this); + + update_user_list_menu_item (this); +} + +static void +add_to_user_list (ApplicationTile *this) +{ + ApplicationTilePrivate *priv = APPLICATION_TILE_GET_PRIVATE (this); + + BookmarkItem *item; + + + item = g_new0 (BookmarkItem, 1); + item->uri = TILE (this)->uri; + item->mime_type = "application/x-desktop"; + + bookmark_agent_add_item (priv->agent, item); + g_free (item); + + priv->is_bookmarked = TRUE; +} + +static void +remove_from_user_list (ApplicationTile *this) +{ + ApplicationTilePrivate *priv = APPLICATION_TILE_GET_PRIVATE (this); + + bookmark_agent_remove_item (priv->agent, TILE (this)->uri); + + priv->is_bookmarked = FALSE; +} + +static void +upgrade_trigger (Tile *tile, TileEvent *event, TileAction *action) +{ + run_package_management_command (APPLICATION_TILE (tile), SLAB_UPGRADE_PACKAGE_KEY); +} + +static void +uninstall_trigger (Tile *tile, TileEvent *event, TileAction *action) +{ + run_package_management_command (APPLICATION_TILE (tile), SLAB_UNINSTALL_PACKAGE_KEY); +} + +static gboolean +verify_package_management_command (const gchar *mateconf_key) +{ + gchar *cmd; + gchar *path; + gchar *args; + + gboolean retval; + + cmd = get_slab_mateconf_string (mateconf_key); + if (!cmd) + return FALSE; + + args = strchr (cmd, ' '); + + if (args) + *args = '\0'; + + path = g_find_program_in_path (cmd); + + retval = (path != NULL); + + g_free (cmd); + g_free (path); + + return retval; +} + +static void +run_package_management_command (ApplicationTile *tile, gchar *mateconf_key) +{ + ApplicationTilePrivate *priv = APPLICATION_TILE_GET_PRIVATE (tile); + + gchar *cmd_precis; + gchar *package_name; + + GString *cmd; + gint pivot; + gchar **argv; + + GError *error = NULL; + + package_name = get_package_name_from_desktop_item (priv->desktop_item); + + if (!package_name) + return; + + cmd_precis = get_slab_mateconf_string (mateconf_key); + + g_assert (cmd_precis); + + pivot = strstr (cmd_precis, "PACKAGE_NAME") - cmd_precis; + + cmd = g_string_new_len (cmd_precis, pivot); + g_string_append (cmd, package_name); + g_string_append (cmd, & cmd_precis [pivot + 12]); + + argv = g_strsplit (cmd->str, " ", -1); + + g_string_free (cmd, TRUE); + + g_spawn_async (NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, &error); + + if (error) { + g_warning ("error: [%s]\n", error->message); + + g_error_free (error); + } + + g_free (cmd_precis); + g_free (package_name); + g_strfreev (argv); +} + +static void +startup_trigger (Tile *tile, TileEvent *event, TileAction *action) +{ + ApplicationTile *this = APPLICATION_TILE (tile); + ApplicationTilePrivate *priv = APPLICATION_TILE_GET_PRIVATE (this); + + switch (priv->startup_status) { + case APP_IN_USER_STARTUP_DIR: + remove_from_startup_list (this); + break; + + case APP_NOT_IN_STARTUP_DIR: + add_to_startup_list (this); + break; + + default: + break; + } + + update_startup_menu_item (this); +} + +static void +add_to_startup_list (ApplicationTile *this) +{ + ApplicationTilePrivate *priv = APPLICATION_TILE_GET_PRIVATE (this); + + gchar *desktop_item_filename; + gchar *desktop_item_basename; + + gchar *startup_dir; + gchar *dst_filename; + + const gchar *src_uri; + gchar *dst_uri; + + desktop_item_filename = + g_filename_from_uri (mate_desktop_item_get_location (priv->desktop_item), NULL, + NULL); + + g_return_if_fail (desktop_item_filename != NULL); + + desktop_item_basename = g_path_get_basename (desktop_item_filename); + + startup_dir = g_build_filename (g_get_user_config_dir (), "autostart", NULL); + + if (! g_file_test (startup_dir, G_FILE_TEST_EXISTS)) + g_mkdir_with_parents (startup_dir, 0700); + + dst_filename = g_build_filename (startup_dir, desktop_item_basename, NULL); + + src_uri = mate_desktop_item_get_location (priv->desktop_item); + dst_uri = g_filename_to_uri (dst_filename, NULL, NULL); + + copy_file (src_uri, dst_uri); + priv->startup_status = APP_IN_USER_STARTUP_DIR; + + g_free (desktop_item_filename); + g_free (desktop_item_basename); + g_free (startup_dir); + g_free (dst_filename); + g_free (dst_uri); +} + +static void +remove_from_startup_list (ApplicationTile *this) +{ + ApplicationTilePrivate *priv = APPLICATION_TILE_GET_PRIVATE (this); + + gchar *ditem_filename; + gchar *ditem_basename; + gchar *src_filename; + + ditem_filename = + g_filename_from_uri (mate_desktop_item_get_location (priv->desktop_item), NULL, + NULL); + + g_return_if_fail (ditem_filename != NULL); + + ditem_basename = g_path_get_basename (ditem_filename); + + src_filename = g_build_filename (g_get_user_config_dir (), "autostart", ditem_basename, NULL); + + priv->startup_status = APP_NOT_IN_STARTUP_DIR; + if (g_file_test (src_filename, G_FILE_TEST_EXISTS)) + { + if(g_file_test (src_filename, G_FILE_TEST_IS_DIR)) + g_assert_not_reached (); + g_unlink (src_filename); + } + + g_free (ditem_filename); + g_free (ditem_basename); + g_free (src_filename); +} + +MateDesktopItem * +application_tile_get_desktop_item (ApplicationTile *tile) +{ + return APPLICATION_TILE_GET_PRIVATE (tile)->desktop_item; +} + +static void +update_user_list_menu_item (ApplicationTile *this) +{ + ApplicationTilePrivate *priv = APPLICATION_TILE_GET_PRIVATE (this); + + TileAction *action; + GtkWidget *item; + + + if (priv->agent_status == BOOKMARK_STORE_ABSENT) { + if (TILE (this)->actions [APPLICATION_TILE_ACTION_UPDATE_MAIN_MENU]) + g_object_unref (TILE (this)->actions [APPLICATION_TILE_ACTION_UPDATE_MAIN_MENU]); + + TILE (this)->actions [APPLICATION_TILE_ACTION_UPDATE_MAIN_MENU] = NULL; + } + else if (! TILE (this)->actions [APPLICATION_TILE_ACTION_UPDATE_MAIN_MENU]) { + TILE (this)->actions [APPLICATION_TILE_ACTION_UPDATE_MAIN_MENU] = + tile_action_new (TILE (this), user_apps_trigger, NULL, 0); + + tile_action_set_menu_item_label ( + TILE (this)->actions [APPLICATION_TILE_ACTION_UPDATE_MAIN_MENU], "blah"); + + item = GTK_WIDGET (tile_action_get_menu_item ( + TILE (this)->actions [APPLICATION_TILE_ACTION_UPDATE_MAIN_MENU])); + gtk_menu_shell_insert (GTK_MENU_SHELL (TILE (this)->context_menu), item, 4); + + gtk_widget_show_all (item); + } + else + /* do nothing */ ; + + action = TILE (this)->actions [APPLICATION_TILE_ACTION_UPDATE_MAIN_MENU]; + + if (! action) + return; + + priv->is_bookmarked = bookmark_agent_has_item (priv->agent, TILE (this)->uri); + + if (priv->is_bookmarked) + tile_action_set_menu_item_label (action, _("Remove from Favorites")); + else + tile_action_set_menu_item_label (action, _("Add to Favorites")); + + item = GTK_WIDGET (tile_action_get_menu_item (action)); + + if (! GTK_IS_MENU_ITEM (item)) + return; + + g_object_get (G_OBJECT (priv->agent), BOOKMARK_AGENT_STORE_STATUS_PROP, & priv->agent_status, NULL); + + gtk_widget_set_sensitive (item, (priv->agent_status != BOOKMARK_STORE_DEFAULT_ONLY)); +} + +static StartupStatus +get_desktop_item_startup_status (MateDesktopItem *desktop_item) +{ + gchar *filename; + gchar *basename; + + const gchar * const * global_dirs; + gchar *global_target; + gchar *user_target; + + StartupStatus retval; + gint x; + + filename = g_filename_from_uri (mate_desktop_item_get_location (desktop_item), NULL, NULL); + if (!filename) + return APP_NOT_ELIGIBLE; + basename = g_path_get_basename (filename); + + retval = APP_NOT_IN_STARTUP_DIR; + global_dirs = g_get_system_config_dirs(); + for(x=0; global_dirs[x]; x++) + { + global_target = g_build_filename (global_dirs[x], "autostart", basename, NULL); + if (g_file_test (global_target, G_FILE_TEST_EXISTS)) + { + retval = APP_NOT_ELIGIBLE; + g_free (global_target); + break; + } + g_free (global_target); + } + + /* mate-session currently checks these dirs also. see startup-programs.c */ + if (retval != APP_NOT_ELIGIBLE) + { + global_dirs = g_get_system_data_dirs(); + for(x=0; global_dirs[x]; x++) + { + global_target = g_build_filename (global_dirs[x], "mate", "autostart", basename, NULL); + if (g_file_test (global_target, G_FILE_TEST_EXISTS)) + { + retval = APP_NOT_ELIGIBLE; + g_free (global_target); + break; + } + g_free (global_target); + } + } + + if (retval != APP_NOT_ELIGIBLE) + { + user_target = g_build_filename (g_get_user_config_dir (), "autostart", basename, NULL); + if (g_file_test (user_target, G_FILE_TEST_EXISTS)) + retval = APP_IN_USER_STARTUP_DIR; + g_free (user_target); + } + + g_free (basename); + g_free (filename); + + return retval; +} + +static void +update_startup_menu_item (ApplicationTile *this) +{ + TileAction *action = TILE (this)->actions [APPLICATION_TILE_ACTION_UPDATE_STARTUP]; + ApplicationTilePrivate *priv = APPLICATION_TILE_GET_PRIVATE (this); + + if (!action) + return; + + if (priv->startup_status == APP_IN_USER_STARTUP_DIR) + tile_action_set_menu_item_label (action, _("Remove from Startup Programs")); + else + tile_action_set_menu_item_label (action, _("Add to Startup Programs")); +} + +static void +header_size_allocate_cb (GtkWidget *widget, GtkAllocation *alloc, gpointer user_data) +{ + gtk_widget_set_size_request (widget, alloc->width, -1); +} + +static void +agent_notify_cb (GObject *g_obj, GParamSpec *pspec, gpointer user_data) +{ + update_user_list_menu_item (APPLICATION_TILE (user_data)); +} |