static void panel_context_menu_build_edition (PanelWidget *panel_widget, GtkWidget *menu) { GtkWidget *menuitem; GtkWidget *image; menuitem = gtk_image_menu_item_new_with_mnemonic (_("_Add to Panel...")); image = gtk_image_new_from_stock (GTK_STOCK_ADD, GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image); gtk_widget_show (menuitem); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); g_signal_connect (G_OBJECT (menuitem), "activate", G_CALLBACK (panel_addto_present), panel_widget); if (!panel_layout_is_writable ()) gtk_widget_set_sensitive (menuitem, FALSE); menuitem = gtk_image_menu_item_new_with_mnemonic (_("_Properties")); image = gtk_image_new_from_stock (GTK_STOCK_PROPERTIES, GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image); gtk_widget_show (menuitem); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); g_signal_connect_swapped (menuitem, "activate", G_CALLBACK (panel_properties_dialog_present), panel_widget->toplevel); menuitem = gtk_image_menu_item_new_with_mnemonic (_("_Delete This Panel")); image = gtk_image_new_from_stock (GTK_STOCK_DELETE, GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image); gtk_widget_show (menuitem); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); g_signal_connect_swapped (G_OBJECT (menuitem), "activate", G_CALLBACK (panel_context_menu_delete_panel), panel_widget->toplevel); g_signal_connect (G_OBJECT (menu), "show", G_CALLBACK (panel_context_menu_setup_delete_panel_item), menuitem); add_menu_separator (menu); menuitem = gtk_image_menu_item_new_with_mnemonic (_("_New Panel")); image = gtk_image_new_from_stock (GTK_STOCK_NEW, GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image); gtk_widget_show (menuitem); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); g_signal_connect (menuitem, "activate", G_CALLBACK (panel_context_menu_create_new_panel), NULL); gtk_widget_set_sensitive (menuitem, panel_layout_is_writable ()); }
static void panel_context_menu_build_edition (PanelWidget *panel_widget, GtkWidget *menu) { GtkWidget *menuitem; menuitem = gtk_menu_item_new_with_mnemonic (_("_Add to Panel...")); gtk_widget_show (menuitem); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); g_signal_connect (G_OBJECT (menuitem), "activate", G_CALLBACK (panel_addto_present), panel_widget); if (!panel_layout_is_writable ()) gtk_widget_set_sensitive (menuitem, FALSE); menuitem = gtk_menu_item_new_with_mnemonic (_("_Properties")); gtk_widget_show (menuitem); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); g_signal_connect (menuitem, "activate", G_CALLBACK (present_properties_dialog), panel_widget->toplevel); menuitem = gtk_menu_item_new_with_mnemonic (_("_Delete This Panel")); gtk_widget_show (menuitem); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); g_signal_connect_swapped (G_OBJECT (menuitem), "activate", G_CALLBACK (panel_context_menu_delete_panel), panel_widget->toplevel); g_signal_connect (G_OBJECT (menuitem), "show", G_CALLBACK (panel_context_menu_setup_delete_panel_item), panel_widget->toplevel); add_menu_separator (menu); menuitem = gtk_menu_item_new_with_mnemonic (_("_New Panel")); gtk_widget_show (menuitem); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); g_signal_connect (menuitem, "activate", G_CALLBACK (panel_context_menu_create_new_panel), NULL); gtk_widget_set_sensitive (menuitem, panel_layout_is_writable ()); }
static void panel_context_menu_setup_delete_panel_item (GtkWidget *menuitem, PanelToplevel *toplevel) { gboolean sensitive; g_assert (PANEL_IS_TOPLEVEL (toplevel)); sensitive = !panel_toplevel_is_last (toplevel) && !panel_lockdown_get_panels_locked_down_s () && panel_layout_is_writable (); gtk_widget_set_sensitive (menuitem, sensitive); }
static GtkWidget * panel_applet_get_edit_menu (AppletInfo *info) { GtkWidget *menu; GtkWidget *menuitem; GtkWidget *image; gboolean movable; gboolean removable; if (info->edit_menu) return info->edit_menu; if (panel_lockdown_get_panels_locked_down_s ()) return NULL; menu = panel_applet_create_bare_menu (info); movable = panel_applet_can_freely_move (info); removable = panel_layout_is_writable (); menuitem = gtk_menu_item_new_with_mnemonic (_("_Move")); g_signal_connect (menuitem, "activate", G_CALLBACK (move_applet_callback), info); gtk_widget_show (menuitem); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); gtk_widget_set_sensitive (menuitem, movable); menuitem = gtk_image_menu_item_new_with_mnemonic (_("_Remove From Panel")); image = gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image); g_signal_connect (menuitem, "activate", G_CALLBACK (applet_remove_callback), info); gtk_widget_show (menuitem); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); gtk_widget_set_sensitive (menuitem, removable); info->edit_menu = menu; panel_lockdown_on_notify (panel_lockdown_get (), "panels-locked-down", G_OBJECT (info->edit_menu), panel_applet_edit_menu_lockdown_changed, info); return info->edit_menu; }
static gboolean drop_menu (PanelWidget *panel, PanelObjectPackType pack_type, int pack_index, const char *menu_filename, const char *menu_path) { if (!panel_layout_is_writable ()) return FALSE; return panel_menu_button_create (panel->toplevel, pack_type, pack_index, menu_filename, menu_path, NULL); }
static gboolean drop_uri (PanelWidget *panel, PanelObjectPackType pack_type, int pack_index, const char *uri, const char *fallback_icon) { char *name; char *comment; char *buf; char *icon; GFile *file; if (!panel_layout_is_writable ()) return FALSE; name = panel_util_get_label_for_uri (uri); icon = panel_util_get_icon_for_uri (uri); if (!icon) icon = g_strdup (fallback_icon); /* FIXME: we might get icons like "folder-music" that might not exist in * the icon theme. This would usually be okay if we could use fallback * icons (and get "folder" this way). However, this is not possible for * launchers: this could be an application that uses an icon named * folder-magic-app, for which we don't want fallbacks. We just want to * go to hicolor. */ file = g_file_new_for_uri (uri); buf = g_file_get_parse_name (file); g_object_unref (file); /* Translators: %s is a URI */ comment = g_strdup_printf (_("Open '%s'"), buf); g_free (buf); panel_launcher_create_from_info (panel->toplevel, pack_type, pack_index, FALSE, uri, name, comment, icon); g_free (name); g_free (comment); g_free (icon); return TRUE; }
static gboolean drop_url (PanelWidget *panel, PanelObjectPackType pack_type, int pack_index, const char *url) { enum { NETSCAPE_URL_URL, NETSCAPE_URL_NAME }; char **netscape_url; char *name; char *comment; g_return_val_if_fail (url != NULL, FALSE); if (!panel_layout_is_writable ()) return FALSE; netscape_url = g_strsplit (url, "\n", 2); if (!netscape_url || PANEL_GLIB_STR_EMPTY (netscape_url[NETSCAPE_URL_URL])) { g_strfreev (netscape_url); return FALSE; } comment = g_strdup_printf (_("Open URL: %s"), netscape_url[NETSCAPE_URL_URL]); if (PANEL_GLIB_STR_EMPTY (netscape_url[NETSCAPE_URL_NAME])) name = netscape_url[NETSCAPE_URL_URL]; else name = netscape_url[NETSCAPE_URL_NAME]; panel_launcher_create_from_info (panel->toplevel, pack_type, pack_index, FALSE, netscape_url[NETSCAPE_URL_URL], name, comment, PANEL_ICON_REMOTE); g_free (comment); g_strfreev (netscape_url); return TRUE; }
static void panel_context_menu_setup_delete_panel_item (GtkWidget *menu, GtkWidget *menuitem) { PanelWidget *panel_widget; gboolean sensitive; panel_context_menu_check_for_screen (NULL, NULL, NULL); panel_widget = menu_get_panel (menu); g_assert (PANEL_IS_TOPLEVEL (panel_widget->toplevel)); sensitive = !panel_toplevel_is_last (panel_widget->toplevel) && !panel_lockdown_get_panels_locked_down_s () && panel_layout_is_writable (); gtk_widget_set_sensitive (menuitem, sensitive); }
static gboolean drop_internal_icon (PanelWidget *panel, PanelObjectPackType pack_type, int pack_index, const char *icon_name, int action) { Launcher *old_launcher = NULL; if (!icon_name) return FALSE; if (!panel_layout_is_writable ()) return FALSE; if (action == GDK_ACTION_MOVE) old_launcher = find_launcher (icon_name); if (!panel_launcher_create_copy (panel->toplevel, pack_type, pack_index, icon_name)) return FALSE; if (old_launcher && old_launcher->button) { const char *object_id; if (old_launcher->prop_dialog) { g_signal_handler_disconnect (old_launcher->button, old_launcher->destroy_handler); launcher_properties_destroy (old_launcher); } object_id = panel_applet_get_id (old_launcher->info); panel_layout_delete_object (object_id); } return TRUE; }
static GtkWidget * panel_applet_get_menu (AppletInfo *info) { GtkWidget *menu; GList *l; gboolean added_anything = FALSE; /** * Separator to split the menu * * APPLET ITEMS * ------------- * Move * Remove From Panel */ GtkSeparatorMenuItem *separator; /** * Variables for the edit menu */ GtkWidget *menuitem; GtkWidget *image; gboolean movable; gboolean removable; if (info->menu) return info->menu; menu = panel_applet_create_bare_menu (info); /** * Moved the panel_applet_get_edit_menu code to here * to recombine the menu as seen in the traditional * Gnome 2 setup */ movable = panel_applet_can_freely_move (info); removable = panel_layout_is_writable (); // Hack. We always added something now :P added_anything = TRUE; for (l = info->user_menu; l; l = l->next) { AppletUserMenu *user_menu = l->data; if (user_menu->is_enabled_func && !user_menu->is_enabled_func ()) continue; add_to_submenus (info, "", user_menu->name, user_menu, menu, info->user_menu); added_anything = TRUE; } // Add the separator before we add the move/remove items (less confusion) separator = gtk_separator_menu_item_new (); gtk_widget_show (separator); gtk_menu_shell_append (GTK_MENU_SHELL(menu), separator); menuitem = gtk_menu_item_new_with_mnemonic (_("_Move")); g_signal_connect (menuitem, "activate", G_CALLBACK (move_applet_callback), info); gtk_widget_show (menuitem); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); gtk_widget_set_sensitive (menuitem, movable); // TODO: Add a seperator menuitem = gtk_image_menu_item_new_with_mnemonic (_("_Remove From Panel")); image = gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image); g_signal_connect (menuitem, "activate", G_CALLBACK (applet_remove_callback), info); gtk_widget_show (menuitem); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); gtk_widget_set_sensitive (menuitem, removable); if ( ! added_anything) { g_signal_handlers_disconnect_by_func (menu, G_CALLBACK (applet_menu_show), info); g_signal_handlers_disconnect_by_func (menu, G_CALLBACK (applet_menu_deactivate), info); g_object_unref (menu); return NULL; } info->menu = menu; panel_lockdown_on_notify (panel_lockdown_get (), NULL, G_OBJECT (info->menu), panel_applet_menu_lockdown_changed, info); return info->menu; }
static gboolean drop_internal_applet (PanelWidget *panel, PanelObjectPackType pack_type, int pack_index, const char *applet_type, int action) { int applet_index = -1; gboolean remove_applet = FALSE; gboolean success = FALSE; if (applet_type == NULL) return FALSE; if (sscanf (applet_type, "MENU:%d", &applet_index) == 1) { if (action != GDK_ACTION_MOVE) g_warning ("Only MOVE supported for menus"); success = move_applet (panel, pack_type, pack_index, applet_index); } else if (strncmp (applet_type, "MENU:", strlen ("MENU:")) == 0) { const char *menu; const char *menu_path; menu = &applet_type[strlen ("MENU:")]; menu_path = strchr (menu, '/'); if (!menu_path) { if (strncmp (menu, "MAIN", strlen ("MAIN")) == 0) success = drop_menu (panel, pack_type, pack_index, NULL, NULL); else success = drop_menu (panel, pack_type, pack_index, menu, NULL); } else { char *menu_filename; menu_filename = g_strndup (menu, menu_path - menu); menu_path++; success = drop_menu (panel, pack_type, pack_index, menu_filename, menu_path); g_free (menu_filename); } } else if (!strncmp (applet_type, "ACTION:", strlen ("ACTION:"))) { if (panel_layout_is_writable ()) { remove_applet = panel_action_button_load_from_drag ( panel->toplevel, pack_type, pack_index, applet_type, &applet_index); success = TRUE; } else { success = FALSE; } } else if (!strcmp (applet_type, "MENUBAR:NEW")) { if (panel_layout_is_writable ()) { panel_menu_bar_create (panel->toplevel, pack_type, pack_index); success = TRUE; } else { success = FALSE; } } else if (!strcmp(applet_type,"SEPARATOR:NEW")) { if (panel_layout_is_writable ()) { panel_separator_create (panel->toplevel, pack_type, pack_index); success = TRUE; } else { success = FALSE; } } else if (!strcmp (applet_type, "USERMENU:NEW")) { if (panel_layout_is_writable ()) { panel_user_menu_create (panel->toplevel, pack_type, pack_index); success = TRUE; } else { success = FALSE; } } else if (!strcmp(applet_type,"LAUNCHER:ASK")) { if (panel_layout_is_writable ()) { ask_about_launcher (NULL, panel, pack_type); success = TRUE; } else { success = FALSE; } } if (remove_applet && action == GDK_ACTION_MOVE) { AppletInfo *info; GSList *applet_list; applet_list = panel_applet_list_applets (); info = g_slist_nth_data (applet_list, applet_index); if (info) panel_layout_delete_object (panel_applet_get_id (info)); } return success; }
static gboolean drop_urilist (PanelWidget *panel, PanelObjectPackType pack_type, int pack_index, char *urilist) { char **uris; GFile *home; GFile *trash; GFile *computer; GFile *network; gboolean success; int i; uris = g_uri_list_extract_uris (urilist); home = g_file_new_for_path (g_get_home_dir ()); trash = g_file_new_for_uri ("trash://"); computer = g_file_new_for_uri ("computer://"); network = g_file_new_for_uri ("network://"); success = TRUE; for (i = 0; uris[i]; i++) { GFile *file; GFileInfo *info; const char *uri; uri = uris[i]; if (g_ascii_strncasecmp (uri, "http:", strlen ("http:")) == 0 || g_ascii_strncasecmp (uri, "https:", strlen ("https:")) == 0 || g_ascii_strncasecmp (uri, "ftp:", strlen ("ftp:")) == 0 || g_ascii_strncasecmp (uri, "gopher:", strlen ("gopher:")) == 0 || g_ascii_strncasecmp (uri, "ghelp:", strlen ("ghelp:")) == 0 || g_ascii_strncasecmp (uri, "man:", strlen ("man:")) == 0 || g_ascii_strncasecmp (uri, "info:", strlen ("info:")) == 0) { /* FIXME: probably do this only on link, * in fact, on link always set up a link, * on copy do all the other stuff. Or something. */ if ( ! drop_url (panel, pack_type, pack_index, uri)) success = FALSE; continue; } if (g_ascii_strncasecmp (uri, "x-nautilus-desktop:", strlen ("x-nautilus-desktop:")) == 0) { success = drop_nautilus_desktop_uri (panel, pack_type, pack_index, uri); continue; } file = g_file_new_for_uri (uri); if (g_file_equal (home, file)) { success = drop_nautilus_desktop_uri (panel, pack_type, pack_index, "x-nautilus-desktop:///home"); g_object_unref (file); continue; } else if (g_file_equal (trash, file)) { success = drop_nautilus_desktop_uri (panel, pack_type, pack_index, "x-nautilus-desktop:///trash"); g_object_unref (file); continue; } else if (g_file_equal (computer, file)) { success = drop_nautilus_desktop_uri (panel, pack_type, pack_index, "x-nautilus-desktop:///computer"); g_object_unref (file); continue; } else if (g_file_equal (network, file)) { success = drop_nautilus_desktop_uri (panel, pack_type, pack_index, "x-nautilus-desktop:///network"); g_object_unref (file); continue; } info = g_file_query_info (file, "standard::type," "standard::content-type," "access::can-execute", G_FILE_QUERY_INFO_NONE, NULL, NULL); if (info) { const char *mime; GFileType type; gboolean can_exec; mime = g_file_info_get_content_type (info); type = g_file_info_get_file_type (info); can_exec = g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE); if (mime && g_str_has_prefix (mime, "image")) { if (!set_background_image_from_uri (panel->toplevel, uri)) success = FALSE; } else if (mime && (!strcmp (mime, "application/x-gnome-app-info") || !strcmp (mime, "application/x-desktop") || !strcmp (mime, "application/x-kde-app-info"))) { if (panel_layout_is_writable ()) panel_launcher_create (panel->toplevel, pack_type, pack_index, uri); else success = FALSE; } else if (type != G_FILE_TYPE_DIRECTORY && can_exec) { char *filename; filename = g_file_get_path (file); if (panel_layout_is_writable ()) /* executable and local, so add a * launcher with it */ ask_about_launcher (filename, panel, pack_type); else success = FALSE; g_free (filename); } else { if (!drop_uri (panel, pack_type, pack_index, uri, PANEL_ICON_UNKNOWN)) success = FALSE; } } else { if (!drop_uri (panel, pack_type, pack_index, uri, PANEL_ICON_UNKNOWN)) success = FALSE; } g_object_unref (info); g_object_unref (file); } g_object_unref (home); g_object_unref (trash); g_object_unref (computer); g_object_unref (network); g_strfreev (uris); return success; }
static void panel_receive_dnd_data (PanelWidget *panel, guint info, PanelObjectPackType pack_type, int pack_index, GtkSelectionData *selection_data, GdkDragContext *context, guint time_) { const guchar *data; gboolean success = FALSE; if (panel_lockdown_get_panels_locked_down_s ()) { gtk_drag_finish (context, FALSE, FALSE, time_); return; } data = gtk_selection_data_get_data (selection_data); switch (info) { case TARGET_URL: success = drop_urilist (panel, pack_type, pack_index, (char *)data); break; case TARGET_NETSCAPE_URL: success = drop_url (panel, pack_type, pack_index, (char *)data); break; case TARGET_COLOR: success = set_background_color (panel->toplevel, (guint16 *) data); break; case TARGET_BGIMAGE: success = set_background_image_from_uri (panel->toplevel, (char *) data); break; case TARGET_BACKGROUND_RESET: success = reset_background (panel->toplevel); break; case TARGET_DIRECTORY: success = drop_uri (panel, pack_type, pack_index, (char *)data, PANEL_ICON_FOLDER); break; case TARGET_APPLET: if (!gtk_selection_data_get_data (selection_data)) { gtk_drag_finish (context, FALSE, FALSE, time_); return; } if (panel_layout_is_writable ()) { panel_applet_frame_create (panel->toplevel, pack_type, pack_index, (char *) data); success = TRUE; } else { success = FALSE; } break; case TARGET_APPLET_INTERNAL: success = drop_internal_applet (panel, pack_type, pack_index, (char *)data, gdk_drag_context_get_selected_action (context)); break; case TARGET_ICON_INTERNAL: success = drop_internal_icon (panel, pack_type, pack_index, (char *)data, gdk_drag_context_get_selected_action (context)); break; default: gtk_drag_finish (context, FALSE, FALSE, time_); return; } gtk_drag_finish (context, success, FALSE, time_); }