Guest User

panel-menu-item.c

a guest
Aug 1st, 2015
234
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
  2. *
  3. * Copyright (C) 2005 Vincent Untz
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  18. * 02111-1307, USA.
  19. *
  20. * Authors:
  21. * Vincent Untz <vincent@vuntz.net>
  22. *
  23. * Based on code from panel-menu-bar.c
  24. */
  25.  
  26. /*
  27. * TODO:
  28. * + drag and drop loses icon for URIs
  29. * + drag and drop of bookmarks/network places/removable media should create
  30. * a menu button
  31. * + if a menu is open and gets updated, it should reappear and not just
  32. * disappear
  33. */
  34.  
  35. #include <config.h>
  36.  
  37. #include "panel-menu-items.h"
  38.  
  39. #include <string.h>
  40. #include <glib/gi18n.h>
  41. #include <gio/gio.h>
  42.  
  43. #include <libpanel-util/panel-error.h>
  44. #include <libpanel-util/panel-glib.h>
  45. #include <libpanel-util/panel-keyfile.h>
  46. #include <libpanel-util/panel-launch.h>
  47. #include <libpanel-util/panel-show.h>
  48.  
  49. #include "menu.h"
  50. #include "panel-action-button.h"
  51. #include "panel-globals.h"
  52. #include "panel-icon-names.h"
  53. #include "panel-lockdown.h"
  54. #include "panel-recent.h"
  55. #include "panel-stock-icons.h"
  56. #include "panel-util.h"
  57.  
  58. #define BOOKMARKS_FILENAME ".gtk-bookmarks"
  59. #define DESKTOP_IS_HOME_DIR_DIR "/apps/nautilus/preferences"
  60. #define DESKTOP_IS_HOME_DIR_KEY "/apps/nautilus/preferences/desktop_is_home_dir"
  61. #define NAMES_DIR "/apps/nautilus/desktop"
  62. #define HOME_NAME_KEY "/apps/nautilus/desktop/home_icon_name"
  63. #define COMPUTER_NAME_KEY "/apps/nautilus/desktop/computer_icon_name"
  64. #define MAX_ITEMS_OR_SUBMENU 5
  65. #define MAX_BOOKMARK_ITEMS 100
  66.  
  67. G_DEFINE_TYPE (PanelPlaceMenuItem, panel_place_menu_item, GTK_TYPE_IMAGE_MENU_ITEM)
  68. G_DEFINE_TYPE (PanelDesktopMenuItem, panel_desktop_menu_item, GTK_TYPE_IMAGE_MENU_ITEM)
  69.  
  70. #define PANEL_PLACE_MENU_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PANEL_TYPE_PLACE_MENU_ITEM, PanelPlaceMenuItemPrivate))
  71. #define PANEL_DESKTOP_MENU_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PANEL_TYPE_DESKTOP_MENU_ITEM, PanelDesktopMenuItemPrivate))
  72.  
  73. struct _PanelPlaceMenuItemPrivate {
  74. GtkWidget *menu;
  75. PanelWidget *panel;
  76.  
  77. GtkRecentManager *recent_manager;
  78.  
  79. GFileMonitor *bookmarks_monitor;
  80.  
  81. GVolumeMonitor *volume_monitor;
  82. gulong drive_changed_id;
  83. gulong drive_connected_id;
  84. gulong drive_disconnected_id;
  85. gulong volume_added_id;
  86. gulong volume_changed_id;
  87. gulong volume_removed_id;
  88. gulong mount_added_id;
  89. gulong mount_changed_id;
  90. gulong mount_removed_id;
  91.  
  92. guint use_image : 1;
  93. };
  94.  
  95. struct _PanelDesktopMenuItemPrivate {
  96. GtkWidget *menu;
  97. PanelWidget *panel;
  98.  
  99. guint use_image : 1;
  100. guint append_lock_logout : 1;
  101. };
  102.  
  103. static void
  104. activate_uri_on_screen (const char *uri,
  105. GdkScreen *screen)
  106. {
  107. panel_show_uri (screen, uri, gtk_get_current_event_time (), NULL);
  108. }
  109.  
  110. static void
  111. activate_uri (GtkWidget *menuitem,
  112. const char *uri)
  113. {
  114. activate_uri_on_screen (uri, menuitem_to_screen (menuitem));
  115. }
  116.  
  117. static void
  118. activate_path (GtkWidget *menuitem,
  119. const char *path)
  120. {
  121. char *uri;
  122.  
  123. uri = g_filename_to_uri (path, NULL, NULL);
  124. activate_uri_on_screen (uri, menuitem_to_screen (menuitem));
  125. g_free (uri);
  126. }
  127.  
  128. static void
  129. activate_home_uri (GtkWidget *menuitem,
  130. gpointer data)
  131. {
  132. activate_path (menuitem, g_get_home_dir ());
  133. }
  134.  
  135. static void
  136. activate_desktop_uri (GtkWidget *menuitem,
  137. gpointer data)
  138. {
  139. activate_path (menuitem,
  140. g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP));
  141. }
  142.  
  143. static void
  144. panel_menu_items_append_from_desktop (GtkWidget *menu,
  145. char *path,
  146. char *force_name,
  147. gboolean use_icon)
  148. {
  149. GKeyFile *key_file;
  150. gboolean loaded;
  151. GtkWidget *item;
  152. char *path_freeme;
  153. char *full_path;
  154. char *uri;
  155. char *type;
  156. gboolean is_application;
  157. char *tryexec;
  158. char *icon;
  159. char *name;
  160. char *comment;
  161.  
  162. path_freeme = NULL;
  163.  
  164. key_file = g_key_file_new ();
  165.  
  166. if (g_path_is_absolute (path)) {
  167. loaded = g_key_file_load_from_file (key_file, path,
  168. G_KEY_FILE_NONE, NULL);
  169. full_path = path;
  170. } else {
  171. char *lookup_file;
  172. char *desktop_path;
  173.  
  174. if (!g_str_has_suffix (path, ".desktop")) {
  175. desktop_path = g_strconcat (path, ".desktop", NULL);
  176. } else {
  177. desktop_path = path;
  178. }
  179.  
  180. lookup_file = g_strconcat ("applications", G_DIR_SEPARATOR_S,
  181. desktop_path, NULL);
  182. loaded = g_key_file_load_from_data_dirs (key_file, lookup_file,
  183. &path_freeme,
  184. G_KEY_FILE_NONE,
  185. NULL);
  186. full_path = path_freeme;
  187. g_free (lookup_file);
  188.  
  189. if (desktop_path != path)
  190. g_free (desktop_path);
  191. }
  192.  
  193. if (!loaded) {
  194. g_key_file_free (key_file);
  195. if (path_freeme)
  196. g_free (path_freeme);
  197. return;
  198. }
  199.  
  200. /* For Application desktop files, respect TryExec */
  201. type = panel_key_file_get_string (key_file, "Type");
  202. if (!type) {
  203. g_key_file_free (key_file);
  204. if (path_freeme)
  205. g_free (path_freeme);
  206. return;
  207. }
  208. is_application = (strcmp (type, "Application") == 0);
  209. g_free (type);
  210.  
  211. if (is_application) {
  212. tryexec = panel_key_file_get_string (key_file, "TryExec");
  213. if (tryexec) {
  214. char *prog;
  215.  
  216. prog = g_find_program_in_path (tryexec);
  217. g_free (tryexec);
  218.  
  219. if (!prog) {
  220. /* FIXME: we could add some file monitor magic,
  221. * so that the menu items appears when the
  222. * program appears, but that's really complex
  223. * for not a huge benefit */
  224. g_key_file_free (key_file);
  225. if (path_freeme)
  226. g_free (path_freeme);
  227. return;
  228. }
  229.  
  230. g_free (prog);
  231. }
  232. }
  233.  
  234. /* Now, simply build the menu item */
  235. icon = panel_key_file_get_locale_string (key_file, "Icon");
  236. comment = panel_key_file_get_locale_string (key_file, "Comment");
  237.  
  238. if (PANEL_GLIB_STR_EMPTY (force_name))
  239. name = panel_key_file_get_locale_string (key_file, "Name");
  240. else
  241. name = g_strdup (force_name);
  242.  
  243. if (use_icon) {
  244. item = panel_image_menu_item_new ();
  245. } else {
  246. item = gtk_image_menu_item_new ();
  247. }
  248.  
  249. setup_menu_item_with_icon (item, panel_menu_icon_get_size (),
  250. icon, NULL, NULL, name);
  251.  
  252. panel_util_set_tooltip_text (item, comment);
  253.  
  254. gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
  255. g_signal_connect_data (item, "activate",
  256. G_CALLBACK (panel_menu_item_activate_desktop_file),
  257. g_strdup (full_path),
  258. (GClosureNotify) g_free, 0);
  259. g_signal_connect (G_OBJECT (item), "button_press_event",
  260. G_CALLBACK (menu_dummy_button_press_event), NULL);
  261.  
  262. uri = g_filename_to_uri (full_path, NULL, NULL);
  263.  
  264. setup_uri_drag (item, uri, icon);
  265. g_free (uri);
  266.  
  267. g_key_file_free (key_file);
  268.  
  269. if (icon)
  270. g_free (icon);
  271.  
  272. if (name)
  273. g_free (name);
  274.  
  275. if (comment)
  276. g_free (comment);
  277.  
  278. if (path_freeme)
  279. g_free (path_freeme);
  280. }
  281.  
  282. static void
  283. panel_menu_items_append_place_item (const char *icon_name,
  284. GIcon *gicon,
  285. const char *title,
  286. const char *tooltip,
  287. GtkWidget *menu,
  288. GCallback callback,
  289. const char *uri)
  290. {
  291. GtkWidget *item;
  292. char *user_data;
  293.  
  294. item = panel_image_menu_item_new ();
  295. setup_menu_item_with_icon (item,
  296. panel_menu_icon_get_size (),
  297. icon_name, NULL, gicon,
  298. title);
  299.  
  300. panel_util_set_tooltip_text (item, tooltip);
  301.  
  302. gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
  303.  
  304. user_data = g_strdup (uri);
  305. g_signal_connect_data (item, "activate", callback, user_data,
  306. (GClosureNotify) g_free, 0);
  307.  
  308. g_signal_connect (G_OBJECT (item), "button_press_event",
  309. G_CALLBACK (menu_dummy_button_press_event), NULL);
  310.  
  311. setup_uri_drag (item, uri, icon_name);
  312. }
  313.  
  314. static GtkWidget *
  315. panel_menu_items_create_action_item_full (PanelActionButtonType action_type,
  316. const char *label,
  317. const char *tooltip)
  318. {
  319. GtkWidget *item;
  320.  
  321. if (panel_action_get_is_disabled (action_type))
  322. return NULL;
  323.  
  324. item = gtk_image_menu_item_new ();
  325. setup_menu_item_with_icon (item,
  326. panel_menu_icon_get_size (),
  327. panel_action_get_icon_name (action_type),
  328. NULL, NULL,
  329. label ? label : panel_action_get_text (action_type));
  330.  
  331. panel_util_set_tooltip_text (item,
  332. tooltip ?
  333. tooltip :
  334. panel_action_get_tooltip (action_type));
  335.  
  336. g_signal_connect (item, "activate",
  337. panel_action_get_invoke (action_type), NULL);
  338. g_signal_connect (G_OBJECT (item), "button_press_event",
  339. G_CALLBACK (menu_dummy_button_press_event), NULL);
  340. setup_internal_applet_drag (item, action_type);
  341.  
  342. return item;
  343. }
  344.  
  345. static GtkWidget *
  346. panel_menu_items_create_action_item (PanelActionButtonType action_type)
  347. {
  348. return panel_menu_items_create_action_item_full (action_type,
  349. NULL, NULL);
  350. }
  351.  
  352. static void
  353. panel_place_menu_item_append_gtk_bookmarks (GtkWidget *menu)
  354. {
  355. typedef struct {
  356. char *full_uri;
  357. char *label;
  358. } PanelBookmark;
  359.  
  360. GtkWidget *add_menu;
  361. char *filename;
  362. GIOChannel *io_channel;
  363. GHashTable *table;
  364. int i;
  365. GSList *lines = NULL;
  366. GSList *add_bookmarks, *l;
  367. PanelBookmark *bookmark;
  368.  
  369. filename = g_build_filename (g_get_home_dir (),
  370. BOOKMARKS_FILENAME, NULL);
  371.  
  372. io_channel = g_io_channel_new_file (filename, "r", NULL);
  373. g_free (filename);
  374.  
  375. if (!io_channel)
  376. return;
  377.  
  378. /* We use a hard limit to avoid having users shooting their
  379. * own feet, and to avoid crashing the system if a misbehaving
  380. * application creates a big bookmars file.
  381. */
  382. for (i = 0; i < MAX_BOOKMARK_ITEMS; i++) {
  383. char *contents;
  384. gsize length;
  385. gsize terminator_pos;
  386. GIOStatus status;
  387.  
  388. status = g_io_channel_read_line (io_channel, &contents, &length, &terminator_pos, NULL);
  389.  
  390. if (status != G_IO_STATUS_NORMAL)
  391. break;
  392.  
  393. if (length == 0)
  394. break;
  395.  
  396. /* Clear the line terminator (\n), if any */
  397. if (terminator_pos > 0)
  398. contents[terminator_pos] = '\0';
  399.  
  400. lines = g_slist_prepend (lines, contents);
  401. }
  402.  
  403. g_io_channel_shutdown (io_channel, FALSE, NULL);
  404. g_io_channel_unref (io_channel);
  405.  
  406. if (!lines)
  407. return;
  408.  
  409. lines = g_slist_reverse (lines);
  410.  
  411. table = g_hash_table_new (g_str_hash, g_str_equal);
  412. add_bookmarks = NULL;
  413.  
  414. for (l = lines; l; l = l->next) {
  415. char *line = (char*) l->data;
  416.  
  417. if (line[0] && !g_hash_table_lookup (table, line)) {
  418. GFile *file;
  419. char *space;
  420. char *label;
  421. gboolean keep;
  422.  
  423. g_hash_table_insert (table, line, line);
  424.  
  425. space = strchr (line, ' ');
  426. if (space) {
  427. *space = '\0';
  428. label = g_strdup (space + 1);
  429. } else {
  430. label = NULL;
  431. }
  432.  
  433. keep = FALSE;
  434.  
  435. if (g_str_has_prefix (line, "x-nautilus-search:"))
  436. keep = TRUE;
  437.  
  438. if (!keep) {
  439. file = g_file_new_for_uri (line);
  440. keep = !g_file_is_native (file) ||
  441. g_file_query_exists (file, NULL);
  442. g_object_unref (file);
  443. }
  444.  
  445. if (!keep) {
  446. if (label)
  447. g_free (label);
  448. continue;
  449. }
  450.  
  451. bookmark = g_malloc (sizeof (PanelBookmark));
  452. bookmark->full_uri = g_strdup (line);
  453. bookmark->label = label;
  454. add_bookmarks = g_slist_prepend (add_bookmarks, bookmark);
  455. }
  456. }
  457.  
  458. g_hash_table_destroy (table);
  459. g_slist_foreach (lines, (GFunc) g_free, NULL);
  460. g_slist_free (lines);
  461.  
  462. add_bookmarks = g_slist_reverse (add_bookmarks);
  463.  
  464. if (g_slist_length (add_bookmarks) <= MAX_ITEMS_OR_SUBMENU) { /* MÓDOSÍTOTTAM: '20' */
  465. add_menu = menu;
  466. } else {
  467. GtkWidget *item;
  468.  
  469. item = gtk_image_menu_item_new ();
  470. setup_menu_item_with_icon (item, panel_menu_icon_get_size (),
  471. PANEL_ICON_BOOKMARKS, NULL, NULL,
  472. _("Bookmarks"));
  473.  
  474. gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
  475. gtk_widget_show (item);
  476.  
  477. add_menu = create_empty_menu ();
  478. gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), add_menu);
  479. }
  480.  
  481. for (l = add_bookmarks; l; l = l->next) {
  482. char *display_name;
  483. char *tooltip;
  484. char *label;
  485. char *icon;
  486. GFile *file;
  487. GIcon *gicon;
  488.  
  489. bookmark = l->data;
  490.  
  491. file = g_file_new_for_uri (bookmark->full_uri);
  492. display_name = g_file_get_parse_name (file);
  493. g_object_unref (file);
  494. /* Translators: %s is a URI */
  495. tooltip = g_strdup_printf (_("Open '%s'"), display_name);
  496. g_free (display_name);
  497.  
  498. label = NULL;
  499. if (bookmark->label) {
  500. label = g_strdup (g_strstrip (bookmark->label));
  501. if (!label [0]) {
  502. g_free (label);
  503. label = NULL;
  504. }
  505. }
  506.  
  507. if (!label) {
  508. label = panel_util_get_label_for_uri (bookmark->full_uri);
  509.  
  510. if (!label) {
  511. g_free (tooltip);
  512. g_free (bookmark->full_uri);
  513. if (bookmark->label)
  514. g_free (bookmark->label);
  515. g_free (bookmark);
  516. continue;
  517. }
  518. }
  519.  
  520. icon = panel_util_get_icon_for_uri (bookmark->full_uri);
  521. /*FIXME: we should probably get a GIcon if possible, so that we
  522. * have customized icons for cd-rom, eg */
  523. if (!icon)
  524. icon = g_strdup (PANEL_ICON_FOLDER);
  525.  
  526. gicon = g_themed_icon_new_with_default_fallbacks (icon);
  527.  
  528. //FIXME: drag and drop will be broken for x-nautilus-search uris
  529. panel_menu_items_append_place_item (icon, gicon,
  530. label,
  531. tooltip,
  532. add_menu,
  533. G_CALLBACK (activate_uri),
  534. bookmark->full_uri);
  535.  
  536. g_free (icon);
  537. g_object_unref (gicon);
  538. g_free (tooltip);
  539. g_free (label);
  540. g_free (bookmark->full_uri);
  541. if (bookmark->label)
  542. g_free (bookmark->label);
  543. g_free (bookmark);
  544. }
  545.  
  546. g_slist_free (add_bookmarks);
  547. }
  548.  
  549. static void
  550. drive_poll_for_media_cb (GObject *source_object,
  551. GAsyncResult *res,
  552. gpointer user_data)
  553. {
  554. GdkScreen *screen;
  555. GError *error;
  556. char *primary;
  557. char *name;
  558.  
  559. error = NULL;
  560. if (!g_drive_poll_for_media_finish (G_DRIVE (source_object),
  561. res, &error)) {
  562. if (error->code != G_IO_ERROR_FAILED_HANDLED) {
  563. screen = GDK_SCREEN (user_data);
  564.  
  565. name = g_drive_get_name (G_DRIVE (source_object));
  566. primary = g_strdup_printf (_("Unable to scan %s for media changes"),
  567. name);
  568. g_free (name);
  569. panel_error_dialog (NULL, screen,
  570. "cannot_scan_drive", TRUE,
  571. primary, error->message);
  572. g_free (primary);
  573. }
  574. g_error_free (error);
  575. }
  576.  
  577. //FIXME: should we mount the volume and activate the root of the new
  578. //mount?
  579. }
  580.  
  581. static void
  582. panel_menu_item_rescan_drive (GtkWidget *menuitem,
  583. GDrive *drive)
  584. {
  585. g_drive_poll_for_media (drive, NULL,
  586. drive_poll_for_media_cb,
  587. menuitem_to_screen (menuitem));
  588. }
  589.  
  590. static void
  591. panel_menu_item_append_drive (GtkWidget *menu,
  592. GDrive *drive)
  593. {
  594. GtkWidget *item;
  595. GIcon *icon;
  596. char *title;
  597. char *tooltip;
  598.  
  599. icon = g_drive_get_icon (drive);
  600. title = g_drive_get_name (drive);
  601.  
  602. item = panel_image_menu_item_new ();
  603. setup_menu_item_with_icon (item,
  604. panel_menu_icon_get_size (),
  605. NULL, NULL, icon,
  606. title);
  607. g_object_unref (icon);
  608.  
  609. tooltip = g_strdup_printf (_("Rescan %s"), title);
  610. panel_util_set_tooltip_text (item, tooltip);
  611. g_free (tooltip);
  612.  
  613. g_free (title);
  614.  
  615. gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
  616.  
  617. g_signal_connect_data (item, "activate",
  618. G_CALLBACK (panel_menu_item_rescan_drive),
  619. g_object_ref (drive),
  620. (GClosureNotify) g_object_unref, 0);
  621.  
  622. g_signal_connect (G_OBJECT (item), "button_press_event",
  623. G_CALLBACK (menu_dummy_button_press_event), NULL);
  624. }
  625.  
  626. typedef struct {
  627. GdkScreen *screen;
  628. GMountOperation *mount_op;
  629. } PanelVolumeMountData;
  630.  
  631. static void
  632. volume_mount_cb (GObject *source_object,
  633. GAsyncResult *res,
  634. gpointer user_data)
  635. {
  636. PanelVolumeMountData *mount_data = user_data;
  637. GError *error;
  638.  
  639. error = NULL;
  640. if (!g_volume_mount_finish (G_VOLUME (source_object), res, &error)) {
  641. char *primary;
  642. char *name;
  643.  
  644. if (error->code != G_IO_ERROR_FAILED_HANDLED) {
  645. name = g_volume_get_name (G_VOLUME (source_object));
  646. primary = g_strdup_printf (_("Unable to mount %s"),
  647. name);
  648. g_free (name);
  649.  
  650. panel_error_dialog (NULL, mount_data->screen,
  651. "cannot_mount_volume", TRUE,
  652. primary, error->message);
  653. g_free (primary);
  654. }
  655. g_error_free (error);
  656. } else {
  657. GMount *mount;
  658. GFile *root;
  659. char *rooturi;
  660.  
  661. mount = g_volume_get_mount (G_VOLUME (source_object));
  662. root = g_mount_get_root (mount);
  663. rooturi = g_file_get_uri (root);
  664. activate_uri_on_screen (rooturi, mount_data->screen);
  665. g_object_unref (mount);
  666. g_object_unref (root);
  667. g_free (rooturi);
  668. }
  669.  
  670. g_object_unref (mount_data->mount_op);
  671. g_slice_free (PanelVolumeMountData, mount_data);
  672. }
  673.  
  674. static void
  675. panel_menu_item_mount_volume (GtkWidget *menuitem,
  676. GVolume *volume)
  677. {
  678. PanelVolumeMountData *mount_data;
  679.  
  680. mount_data = g_slice_new (PanelVolumeMountData);
  681. mount_data->screen = menuitem_to_screen (menuitem);
  682. mount_data->mount_op = gtk_mount_operation_new (NULL);
  683. gtk_mount_operation_set_screen (GTK_MOUNT_OPERATION (mount_data->mount_op),
  684. mount_data->screen);
  685.  
  686. g_volume_mount (volume, G_MOUNT_MOUNT_NONE, mount_data->mount_op, NULL,
  687. volume_mount_cb, mount_data);
  688. }
  689.  
  690. static void
  691. panel_menu_item_append_volume (GtkWidget *menu,
  692. GVolume *volume)
  693. {
  694. GtkWidget *item;
  695. GIcon *icon;
  696. char *title;
  697. char *tooltip;
  698.  
  699. icon = g_volume_get_icon (volume);
  700. title = g_volume_get_name (volume);
  701.  
  702. item = panel_image_menu_item_new ();
  703. setup_menu_item_with_icon (item,
  704. panel_menu_icon_get_size (),
  705. NULL, NULL, icon,
  706. title);
  707. g_object_unref (icon);
  708.  
  709. tooltip = g_strdup_printf (_("Mount %s"), title);
  710. panel_util_set_tooltip_text (item, tooltip);
  711. g_free (tooltip);
  712.  
  713. g_free (title);
  714.  
  715. gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
  716.  
  717. g_signal_connect_data (item, "activate",
  718. G_CALLBACK (panel_menu_item_mount_volume),
  719. g_object_ref (volume),
  720. (GClosureNotify) g_object_unref, 0);
  721.  
  722. g_signal_connect (G_OBJECT (item), "button_press_event",
  723. G_CALLBACK (menu_dummy_button_press_event), NULL);
  724. }
  725.  
  726. static void
  727. panel_menu_item_append_mount (GtkWidget *menu,
  728. GMount *mount)
  729. {
  730. GFile *root;
  731. GIcon *icon;
  732. char *display_name;
  733. char *activation_uri;
  734.  
  735. icon = g_mount_get_icon (mount);
  736. display_name = g_mount_get_name (mount);
  737.  
  738. root = g_mount_get_root (mount);
  739. activation_uri = g_file_get_uri (root);
  740. g_object_unref (root);
  741.  
  742. panel_menu_items_append_place_item (NULL, icon,
  743. display_name,
  744. display_name, //FIXME tooltip
  745. menu,
  746. G_CALLBACK (activate_uri),
  747. activation_uri);
  748.  
  749. g_object_unref (icon);
  750. g_free (display_name);
  751. g_free (activation_uri);
  752. }
  753.  
  754. typedef enum {
  755. PANEL_GIO_DRIVE,
  756. PANEL_GIO_VOLUME,
  757. PANEL_GIO_MOUNT
  758. } PanelGioItemType;
  759.  
  760. typedef struct {
  761. PanelGioItemType type;
  762. union {
  763. GDrive *drive;
  764. GVolume *volume;
  765. GMount *mount;
  766. } u;
  767. } PanelGioItem;
  768.  
  769. /* this is loosely based on update_places() from nautilus-places-sidebar.c */
  770. static void
  771. panel_place_menu_item_append_local_gio (PanelPlaceMenuItem *place_item,
  772. GtkWidget *menu)
  773. {
  774. GList *l;
  775. GList *ll;
  776. GList *drives;
  777. GDrive *drive;
  778. GList *volumes;
  779. GVolume *volume;
  780. GList *mounts;
  781. GMount *mount;
  782. GSList *items;
  783. GSList *sl;
  784. PanelGioItem *item;
  785. GtkWidget *add_menu;
  786.  
  787. items = NULL;
  788.  
  789. /* first go through all connected drives */
  790. drives = g_volume_monitor_get_connected_drives (place_item->priv->volume_monitor);
  791. for (l = drives; l != NULL; l = l->next) {
  792. drive = l->data;
  793.  
  794. volumes = g_drive_get_volumes (drive);
  795. if (volumes != NULL) {
  796. for (ll = volumes; ll != NULL; ll = ll->next) {
  797. volume = ll->data;
  798. mount = g_volume_get_mount (volume);
  799. item = g_slice_new (PanelGioItem);
  800. if (mount != NULL) {
  801. item->type = PANEL_GIO_MOUNT;
  802. item->u.mount = mount;
  803. } else {
  804. /* Do show the unmounted volumes; this
  805. * is so the user can mount it (in case
  806. * automounting is off).
  807. *
  808. * Also, even if automounting is
  809. * enabled, this gives a visual cue
  810. * that the user should remember to
  811. * yank out the media if he just
  812. * unmounted it.
  813. */
  814. item->type = PANEL_GIO_VOLUME;
  815. item->u.volume = g_object_ref (volume);
  816. }
  817. items = g_slist_prepend (items, item);
  818. g_object_unref (volume);
  819. }
  820. g_list_free (volumes);
  821. } else {
  822. if (g_drive_is_media_removable (drive) &&
  823. !g_drive_is_media_check_automatic (drive)) {
  824. /* If the drive has no mountable volumes and we
  825. * cannot detect media change.. we display the
  826. * drive so the user can manually poll the
  827. * drive by clicking on it..."
  828. *
  829. * This is mainly for drives like floppies
  830. * where media detection doesn't work.. but
  831. * it's also for human beings who like to turn
  832. * off media detection in the OS to save
  833. * battery juice.
  834. */
  835. item = g_slice_new (PanelGioItem);
  836. item->type = PANEL_GIO_DRIVE;
  837. item->u.drive = g_object_ref (drive);
  838. items = g_slist_prepend (items, item);
  839. }
  840. }
  841. g_object_unref (drive);
  842. }
  843. g_list_free (drives);
  844.  
  845. /* add all volumes that is not associated with a drive */
  846. volumes = g_volume_monitor_get_volumes (place_item->priv->volume_monitor);
  847. for (l = volumes; l != NULL; l = l->next) {
  848. volume = l->data;
  849. drive = g_volume_get_drive (volume);
  850. if (drive != NULL) {
  851. g_object_unref (volume);
  852. g_object_unref (drive);
  853. continue;
  854. }
  855. mount = g_volume_get_mount (volume);
  856. item = g_slice_new (PanelGioItem);
  857. if (mount != NULL) {
  858. item->type = PANEL_GIO_MOUNT;
  859. item->u.mount = mount;
  860. } else {
  861. /* see comment above in why we add an icon for an
  862. * unmounted mountable volume */
  863. item->type = PANEL_GIO_VOLUME;
  864. item->u.volume = g_object_ref (volume);
  865. }
  866. items = g_slist_prepend (items, item);
  867. g_object_unref (volume);
  868. }
  869. g_list_free (volumes);
  870.  
  871. /* add mounts that has no volume (/etc/mtab mounts, ftp, sftp,...) */
  872. mounts = g_volume_monitor_get_mounts (place_item->priv->volume_monitor);
  873. for (l = mounts; l != NULL; l = l->next) {
  874. GFile *root;
  875.  
  876. mount = l->data;
  877.  
  878. if (g_mount_is_shadowed (mount)) {
  879. g_object_unref (mount);
  880. continue;
  881. }
  882.  
  883. volume = g_mount_get_volume (mount);
  884. if (volume != NULL) {
  885. g_object_unref (volume);
  886. g_object_unref (mount);
  887. continue;
  888. }
  889.  
  890. root = g_mount_get_root (mount);
  891. if (!g_file_is_native (root)) {
  892. g_object_unref (root);
  893. g_object_unref (mount);
  894. continue;
  895. }
  896. g_object_unref (root);
  897.  
  898. item = g_slice_new (PanelGioItem);
  899. item->type = PANEL_GIO_MOUNT;
  900. item->u.mount = mount;
  901. items = g_slist_prepend (items, item);
  902. }
  903. g_list_free (mounts);
  904.  
  905. /* now that we have everything, add the items inline or in a submenu */
  906. items = g_slist_reverse (items);
  907.  
  908. if (g_slist_length (items) <= MAX_ITEMS_OR_SUBMENU) {
  909. add_menu = menu;
  910. } else {
  911. GtkWidget *item;
  912.  
  913. item = gtk_image_menu_item_new ();
  914. setup_menu_item_with_icon (item, panel_menu_icon_get_size (),
  915. PANEL_ICON_REMOVABLE_MEDIA,
  916. NULL, NULL,
  917. _("Removable Media"));
  918.  
  919. gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
  920. gtk_widget_show (item);
  921.  
  922. add_menu = create_empty_menu ();
  923. gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), add_menu);
  924. }
  925.  
  926. for (sl = items; sl; sl = sl->next) {
  927. item = sl->data;
  928. switch (item->type) {
  929. case PANEL_GIO_DRIVE:
  930. panel_menu_item_append_drive (add_menu, item->u.drive);
  931. g_object_unref (item->u.drive);
  932. break;
  933. case PANEL_GIO_VOLUME:
  934. panel_menu_item_append_volume (add_menu, item->u.volume);
  935. g_object_unref (item->u.volume);
  936. break;
  937. case PANEL_GIO_MOUNT:
  938. panel_menu_item_append_mount (add_menu, item->u.mount);
  939. g_object_unref (item->u.mount);
  940. break;
  941. default:
  942. g_assert_not_reached ();
  943. }
  944. g_slice_free (PanelGioItem, item);
  945. }
  946.  
  947. g_slist_free (items);
  948. }
  949.  
  950. /* this is loosely based on update_places() from nautilus-places-sidebar.c */
  951. static void
  952. panel_place_menu_item_append_remote_gio (PanelPlaceMenuItem *place_item,
  953. GtkWidget *menu)
  954. {
  955. GtkWidget *add_menu;
  956. GList *mounts, *l;
  957. GMount *mount;
  958. GSList *add_mounts, *sl;
  959.  
  960. /* add mounts that has no volume (/etc/mtab mounts, ftp, sftp,...) */
  961. mounts = g_volume_monitor_get_mounts (place_item->priv->volume_monitor);
  962. add_mounts = NULL;
  963.  
  964. for (l = mounts; l; l = l->next) {
  965. GVolume *volume;
  966. GFile *root;
  967.  
  968. mount = l->data;
  969.  
  970. if (g_mount_is_shadowed (mount)) {
  971. g_object_unref (mount);
  972. continue;
  973. }
  974.  
  975. volume = g_mount_get_volume (mount);
  976. if (volume != NULL) {
  977. g_object_unref (volume);
  978. g_object_unref (mount);
  979. continue;
  980. }
  981.  
  982. root = g_mount_get_root (mount);
  983. if (g_file_is_native (root)) {
  984. g_object_unref (root);
  985. g_object_unref (mount);
  986. continue;
  987. }
  988. g_object_unref (root);
  989.  
  990.  
  991. add_mounts = g_slist_prepend (add_mounts, mount);
  992. }
  993. add_mounts = g_slist_reverse (add_mounts);
  994.  
  995. if (g_slist_length (add_mounts) <= MAX_ITEMS_OR_SUBMENU) {
  996. add_menu = menu;
  997. } else {
  998. GtkWidget *item;
  999.  
  1000. item = panel_image_menu_item_new ();
  1001. setup_menu_item_with_icon (item, panel_menu_icon_get_size (),
  1002. PANEL_ICON_NETWORK_SERVER,
  1003. NULL, NULL,
  1004. _("Network Places"));
  1005.  
  1006. gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
  1007. gtk_widget_show (item);
  1008.  
  1009. add_menu = create_empty_menu ();
  1010. gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), add_menu);
  1011. }
  1012.  
  1013. for (sl = add_mounts; sl; sl = sl->next) {
  1014. mount = sl->data;
  1015. panel_menu_item_append_mount (add_menu, mount);
  1016. g_object_unref (mount);
  1017. }
  1018.  
  1019. g_slist_free (add_mounts);
  1020. g_list_free (mounts);
  1021. }
  1022.  
  1023.  
  1024. static GtkWidget *
  1025. panel_place_menu_item_create_menu (PanelPlaceMenuItem *place_item)
  1026. {
  1027. GtkWidget *places_menu;
  1028. GtkWidget *item;
  1029. char *gconf_name;
  1030. char *name;
  1031. char *uri;
  1032. GFile *file;
  1033.  
  1034. places_menu = panel_create_menu ();
  1035.  
  1036. file = g_file_new_for_path (g_get_home_dir ());
  1037. uri = g_file_get_uri (file);
  1038. name = panel_util_get_label_for_uri (uri);
  1039. g_object_unref (file);
  1040.  
  1041. panel_menu_items_append_place_item (PANEL_ICON_HOME, NULL,
  1042. name,
  1043. _("Open your personal folder"),
  1044. places_menu,
  1045. G_CALLBACK (activate_home_uri),
  1046. uri);
  1047. g_free (name);
  1048. g_free (uri);
  1049.  
  1050. if (!gconf_client_get_bool (panel_gconf_get_client (),
  1051. DESKTOP_IS_HOME_DIR_KEY,
  1052. NULL)) {
  1053. file = g_file_new_for_path (g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP));
  1054. uri = g_file_get_uri (file);
  1055. g_object_unref (file);
  1056.  
  1057. panel_menu_items_append_place_item (
  1058. PANEL_ICON_DESKTOP, NULL,
  1059. /* Translators: Desktop is used here as in
  1060. * "Desktop Folder" (this is not the Desktop
  1061. * environment). */
  1062. C_("Desktop Folder", "Desktop"),
  1063. _("Open the contents of your desktop in a folder"),
  1064. places_menu,
  1065. G_CALLBACK (activate_desktop_uri),
  1066. /* FIXME: if the dir changes, we'd need to update the drag data since the uri is not the same */
  1067. uri);
  1068. g_free (uri);
  1069. }
  1070.  
  1071. panel_place_menu_item_append_gtk_bookmarks (places_menu);
  1072. add_menu_separator (places_menu);
  1073.  
  1074. gconf_name = gconf_client_get_string (panel_gconf_get_client (),
  1075. COMPUTER_NAME_KEY,
  1076. NULL);
  1077. panel_menu_items_append_from_desktop (places_menu,
  1078. "nautilus-computer.desktop",
  1079. gconf_name,
  1080. TRUE);
  1081. if (gconf_name)
  1082. g_free (gconf_name);
  1083.  
  1084. panel_place_menu_item_append_local_gio (place_item, places_menu);
  1085. add_menu_separator (places_menu);
  1086.  
  1087. panel_menu_items_append_from_desktop (places_menu,
  1088. "network-scheme.desktop",
  1089. NULL,
  1090. TRUE);
  1091. panel_place_menu_item_append_remote_gio (place_item, places_menu);
  1092.  
  1093. if (panel_is_program_in_path ("nautilus-connect-server")) {
  1094. item = panel_menu_items_create_action_item (PANEL_ACTION_CONNECT_SERVER);
  1095. if (item != NULL)
  1096. gtk_menu_shell_append (GTK_MENU_SHELL (places_menu),
  1097. item);
  1098. }
  1099.  
  1100. add_menu_separator (places_menu);
  1101.  
  1102. panel_menu_items_append_from_desktop (places_menu,
  1103. "gnome-search-tool.desktop",
  1104. NULL,
  1105. FALSE);
  1106.  
  1107. panel_recent_append_documents_menu (places_menu,
  1108. place_item->priv->recent_manager);
  1109.  
  1110. return places_menu;
  1111. }
  1112.  
  1113. static void
  1114. panel_place_menu_item_recreate_menu (GtkWidget *widget)
  1115. {
  1116. PanelPlaceMenuItem *place_item;
  1117.  
  1118. place_item = PANEL_PLACE_MENU_ITEM (widget);
  1119.  
  1120. if (place_item->priv->menu) {
  1121. gtk_widget_destroy (place_item->priv->menu);
  1122. place_item->priv->menu = panel_place_menu_item_create_menu (place_item);
  1123. gtk_menu_item_set_submenu (GTK_MENU_ITEM (place_item),
  1124. place_item->priv->menu);
  1125. panel_applet_menu_set_recurse (GTK_MENU (place_item->priv->menu),
  1126. "menu_panel",
  1127. place_item->priv->panel);
  1128. }
  1129. }
  1130.  
  1131. static void
  1132. panel_place_menu_item_key_changed (GConfClient *client,
  1133. guint cnxn_id,
  1134. GConfEntry *entry,
  1135. GtkWidget *place_item)
  1136. {
  1137. panel_place_menu_item_recreate_menu (place_item);
  1138. }
  1139.  
  1140. static void
  1141. panel_place_menu_item_gtk_bookmarks_changed (GFileMonitor *handle,
  1142. GFile *file,
  1143. GFile *other_file,
  1144. GFileMonitorEvent event,
  1145. gpointer user_data)
  1146. {
  1147. panel_place_menu_item_recreate_menu (GTK_WIDGET (user_data));
  1148. }
  1149.  
  1150. static void
  1151. panel_place_menu_item_drives_changed (GVolumeMonitor *monitor,
  1152. GDrive *drive,
  1153. GtkWidget *place_menu)
  1154. {
  1155. panel_place_menu_item_recreate_menu (place_menu);
  1156. }
  1157.  
  1158. static void
  1159. panel_place_menu_item_volumes_changed (GVolumeMonitor *monitor,
  1160. GVolume *volume,
  1161. GtkWidget *place_menu)
  1162. {
  1163. panel_place_menu_item_recreate_menu (place_menu);
  1164. }
  1165.  
  1166. static void
  1167. panel_place_menu_item_mounts_changed (GVolumeMonitor *monitor,
  1168. GMount *mount,
  1169. GtkWidget *place_menu)
  1170. {
  1171. panel_place_menu_item_recreate_menu (place_menu);
  1172. }
  1173.  
  1174. static void
  1175. panel_desktop_menu_item_append_menu (GtkWidget *menu,
  1176. gpointer data)
  1177. {
  1178. PanelDesktopMenuItem *parent;
  1179. gboolean add_separator;
  1180. GList *children;
  1181. GList *last;
  1182.  
  1183. parent = PANEL_DESKTOP_MENU_ITEM (data);
  1184.  
  1185. add_separator = FALSE;
  1186. children = gtk_container_get_children (GTK_CONTAINER (menu));
  1187. last = g_list_last (children);
  1188.  
  1189. if (last != NULL)
  1190. add_separator = !GTK_IS_SEPARATOR (GTK_WIDGET (last->data));
  1191.  
  1192. g_list_free (children);
  1193.  
  1194. if (add_separator)
  1195. add_menu_separator (menu);
  1196.  
  1197. panel_menu_items_append_from_desktop (menu, "yelp.desktop", NULL, FALSE);
  1198. panel_menu_items_append_from_desktop (menu, "gnome-about.desktop", NULL, FALSE);
  1199.  
  1200. if (parent->priv->append_lock_logout)
  1201. panel_menu_items_append_lock_logout (menu); /* MÓDOSÍTOTTAM: 'return;' */
  1202. }
  1203.  
  1204. static GtkWidget *
  1205. panel_desktop_menu_item_create_menu (PanelDesktopMenuItem *desktop_item)
  1206. {
  1207. GtkWidget *desktop_menu;
  1208.  
  1209. desktop_menu = create_applications_menu ("settings.menu", NULL, FALSE);
  1210.  
  1211. g_object_set_data (G_OBJECT (desktop_menu),
  1212. "panel-menu-append-callback",
  1213. panel_desktop_menu_item_append_menu);
  1214. g_object_set_data (G_OBJECT (desktop_menu),
  1215. "panel-menu-append-callback-data",
  1216. desktop_item);
  1217.  
  1218. return desktop_menu;
  1219. }
  1220.  
  1221. static void
  1222. panel_desktop_menu_item_recreate_menu (PanelDesktopMenuItem *desktop_item)
  1223. {
  1224. if (desktop_item->priv->menu) {
  1225. gtk_widget_destroy (desktop_item->priv->menu);
  1226. desktop_item->priv->menu = panel_desktop_menu_item_create_menu (desktop_item);
  1227. gtk_menu_item_set_submenu (GTK_MENU_ITEM (desktop_item),
  1228. desktop_item->priv->menu);
  1229. panel_applet_menu_set_recurse (GTK_MENU (desktop_item->priv->menu),
  1230. "menu_panel",
  1231. desktop_item->priv->panel);
  1232. }
  1233. }
  1234.  
  1235. static void
  1236. panel_place_menu_item_finalize (GObject *object)
  1237. {
  1238. PanelPlaceMenuItem *menuitem = (PanelPlaceMenuItem *) object;
  1239.  
  1240. gconf_client_remove_dir (panel_gconf_get_client (),
  1241. DESKTOP_IS_HOME_DIR_DIR,
  1242. NULL);
  1243. gconf_client_remove_dir (panel_gconf_get_client (),
  1244. NAMES_DIR,
  1245. NULL);
  1246.  
  1247. if (menuitem->priv->bookmarks_monitor != NULL) {
  1248. g_file_monitor_cancel (menuitem->priv->bookmarks_monitor);
  1249. g_object_unref (menuitem->priv->bookmarks_monitor);
  1250. }
  1251. menuitem->priv->bookmarks_monitor = NULL;
  1252.  
  1253. if (menuitem->priv->drive_changed_id)
  1254. g_signal_handler_disconnect (menuitem->priv->volume_monitor,
  1255. menuitem->priv->drive_changed_id);
  1256. menuitem->priv->drive_changed_id = 0;
  1257.  
  1258. if (menuitem->priv->drive_connected_id)
  1259. g_signal_handler_disconnect (menuitem->priv->volume_monitor,
  1260. menuitem->priv->drive_connected_id);
  1261. menuitem->priv->drive_connected_id = 0;
  1262.  
  1263. if (menuitem->priv->drive_disconnected_id)
  1264. g_signal_handler_disconnect (menuitem->priv->volume_monitor,
  1265. menuitem->priv->drive_disconnected_id);
  1266. menuitem->priv->drive_disconnected_id = 0;
  1267.  
  1268. if (menuitem->priv->volume_added_id)
  1269. g_signal_handler_disconnect (menuitem->priv->volume_monitor,
  1270. menuitem->priv->volume_added_id);
  1271. menuitem->priv->volume_added_id = 0;
  1272.  
  1273. if (menuitem->priv->volume_changed_id)
  1274. g_signal_handler_disconnect (menuitem->priv->volume_monitor,
  1275. menuitem->priv->volume_changed_id);
  1276. menuitem->priv->volume_changed_id = 0;
  1277.  
  1278. if (menuitem->priv->volume_removed_id)
  1279. g_signal_handler_disconnect (menuitem->priv->volume_monitor,
  1280. menuitem->priv->volume_removed_id);
  1281. menuitem->priv->volume_removed_id = 0;
  1282.  
  1283. if (menuitem->priv->mount_added_id)
  1284. g_signal_handler_disconnect (menuitem->priv->volume_monitor,
  1285. menuitem->priv->mount_added_id);
  1286. menuitem->priv->mount_added_id = 0;
  1287.  
  1288. if (menuitem->priv->mount_changed_id)
  1289. g_signal_handler_disconnect (menuitem->priv->volume_monitor,
  1290. menuitem->priv->mount_changed_id);
  1291. menuitem->priv->mount_changed_id = 0;
  1292.  
  1293. if (menuitem->priv->mount_removed_id)
  1294. g_signal_handler_disconnect (menuitem->priv->volume_monitor,
  1295. menuitem->priv->mount_removed_id);
  1296. menuitem->priv->mount_removed_id = 0;
  1297.  
  1298. if (menuitem->priv->volume_monitor != NULL)
  1299. g_object_unref (menuitem->priv->volume_monitor);
  1300. menuitem->priv->volume_monitor = NULL;
  1301.  
  1302. G_OBJECT_CLASS (panel_place_menu_item_parent_class)->finalize (object);
  1303. }
  1304.  
  1305. static void
  1306. panel_desktop_menu_item_finalize (GObject *object)
  1307. {
  1308. PanelDesktopMenuItem *menuitem = (PanelDesktopMenuItem *) object;
  1309.  
  1310. if (menuitem->priv->append_lock_logout)
  1311. panel_lockdown_notify_remove (G_CALLBACK (panel_desktop_menu_item_recreate_menu),
  1312. menuitem); /* MÓDOSÍTOTTAM: 'return;' */
  1313. G_OBJECT_CLASS (panel_desktop_menu_item_parent_class)->finalize (object);
  1314. }
  1315.  
  1316. static void
  1317. panel_place_menu_item_init (PanelPlaceMenuItem *menuitem)
  1318. {
  1319. GFile *bookmark;
  1320. char *bookmarks_filename;
  1321. GError *error;
  1322.  
  1323. menuitem->priv = PANEL_PLACE_MENU_ITEM_GET_PRIVATE (menuitem);
  1324.  
  1325. gconf_client_add_dir (panel_gconf_get_client (),
  1326. DESKTOP_IS_HOME_DIR_DIR,
  1327. GCONF_CLIENT_PRELOAD_NONE,
  1328. NULL);
  1329. gconf_client_add_dir (panel_gconf_get_client (),
  1330. NAMES_DIR,
  1331. GCONF_CLIENT_PRELOAD_NONE,
  1332. NULL);
  1333.  
  1334. panel_gconf_notify_add_while_alive (HOME_NAME_KEY,
  1335. (GConfClientNotifyFunc) panel_place_menu_item_key_changed,
  1336. G_OBJECT (menuitem));
  1337. panel_gconf_notify_add_while_alive (DESKTOP_IS_HOME_DIR_KEY,
  1338. (GConfClientNotifyFunc) panel_place_menu_item_key_changed,
  1339. G_OBJECT (menuitem));
  1340. panel_gconf_notify_add_while_alive (COMPUTER_NAME_KEY,
  1341. (GConfClientNotifyFunc) panel_place_menu_item_key_changed,
  1342. G_OBJECT (menuitem));
  1343.  
  1344. menuitem->priv->recent_manager = gtk_recent_manager_get_default ();
  1345.  
  1346. bookmarks_filename = g_build_filename (g_get_home_dir (),
  1347. BOOKMARKS_FILENAME, NULL);
  1348. bookmark = g_file_new_for_path (bookmarks_filename);
  1349.  
  1350. error = NULL;
  1351. menuitem->priv->bookmarks_monitor = g_file_monitor_file
  1352. (bookmark,
  1353. G_FILE_MONITOR_NONE,
  1354. NULL,
  1355. &error);
  1356. if (error) {
  1357. g_warning ("Failed to add file monitor for %s: %s\n",
  1358. bookmarks_filename, error->message);
  1359. g_error_free (error);
  1360. } else {
  1361. g_signal_connect (G_OBJECT (menuitem->priv->bookmarks_monitor),
  1362. "changed",
  1363. (GCallback) panel_place_menu_item_gtk_bookmarks_changed,
  1364. menuitem);
  1365. }
  1366.  
  1367. g_object_unref (bookmark);
  1368. g_free (bookmarks_filename);
  1369.  
  1370. menuitem->priv->volume_monitor = g_volume_monitor_get ();
  1371.  
  1372. menuitem->priv->drive_changed_id = g_signal_connect (menuitem->priv->volume_monitor,
  1373. "drive-changed",
  1374. G_CALLBACK (panel_place_menu_item_drives_changed),
  1375. menuitem);
  1376. menuitem->priv->drive_connected_id = g_signal_connect (menuitem->priv->volume_monitor,
  1377. "drive-connected",
  1378. G_CALLBACK (panel_place_menu_item_drives_changed),
  1379. menuitem);
  1380. menuitem->priv->drive_disconnected_id = g_signal_connect (menuitem->priv->volume_monitor,
  1381. "drive-disconnected",
  1382. G_CALLBACK (panel_place_menu_item_drives_changed),
  1383. menuitem);
  1384. menuitem->priv->volume_added_id = g_signal_connect (menuitem->priv->volume_monitor,
  1385. "volume-added",
  1386. G_CALLBACK (panel_place_menu_item_volumes_changed),
  1387. menuitem);
  1388. menuitem->priv->volume_changed_id = g_signal_connect (menuitem->priv->volume_monitor,
  1389. "volume-changed",
  1390. G_CALLBACK (panel_place_menu_item_volumes_changed),
  1391. menuitem);
  1392. menuitem->priv->volume_removed_id = g_signal_connect (menuitem->priv->volume_monitor,
  1393. "volume-removed",
  1394. G_CALLBACK (panel_place_menu_item_volumes_changed),
  1395. menuitem);
  1396. menuitem->priv->mount_added_id = g_signal_connect (menuitem->priv->volume_monitor,
  1397. "mount-added",
  1398. G_CALLBACK (panel_place_menu_item_mounts_changed),
  1399. menuitem);
  1400. menuitem->priv->mount_changed_id = g_signal_connect (menuitem->priv->volume_monitor,
  1401. "mount-changed",
  1402. G_CALLBACK (panel_place_menu_item_mounts_changed),
  1403. menuitem);
  1404. menuitem->priv->mount_removed_id = g_signal_connect (menuitem->priv->volume_monitor,
  1405. "mount-removed",
  1406. G_CALLBACK (panel_place_menu_item_mounts_changed),
  1407. menuitem);
  1408.  
  1409. }
  1410.  
  1411. static void
  1412. panel_desktop_menu_item_init (PanelDesktopMenuItem *menuitem)
  1413. {
  1414. menuitem->priv = PANEL_DESKTOP_MENU_ITEM_GET_PRIVATE (menuitem);
  1415. }
  1416.  
  1417. static void
  1418. panel_place_menu_item_class_init (PanelPlaceMenuItemClass *klass)
  1419. {
  1420. GObjectClass *gobject_class = (GObjectClass *) klass;
  1421.  
  1422. gobject_class->finalize = panel_place_menu_item_finalize;
  1423.  
  1424. g_type_class_add_private (klass, sizeof (PanelPlaceMenuItemPrivate));
  1425. }
  1426.  
  1427. static void
  1428. panel_desktop_menu_item_class_init (PanelDesktopMenuItemClass *klass)
  1429. {
  1430. GObjectClass *gobject_class = (GObjectClass *) klass;
  1431.  
  1432. gobject_class->finalize = panel_desktop_menu_item_finalize;
  1433.  
  1434. g_type_class_add_private (klass, sizeof (PanelDesktopMenuItemPrivate));
  1435. }
  1436.  
  1437. GtkWidget *
  1438. panel_place_menu_item_new (gboolean use_image)
  1439. {
  1440. PanelPlaceMenuItem *menuitem;
  1441. GtkWidget *image;
  1442.  
  1443. menuitem = g_object_new (PANEL_TYPE_PLACE_MENU_ITEM, NULL);
  1444.  
  1445. if (use_image)
  1446. image = gtk_image_new_from_icon_name (PANEL_ICON_FOLDER,
  1447. panel_menu_icon_get_size ());
  1448. else
  1449. image = NULL;
  1450.  
  1451. setup_menuitem (GTK_WIDGET (menuitem),
  1452. image ? panel_menu_icon_get_size () : GTK_ICON_SIZE_INVALID,
  1453. image,
  1454. _("Places"));
  1455.  
  1456. menuitem->priv->use_image = use_image;
  1457.  
  1458. menuitem->priv->menu = panel_place_menu_item_create_menu (menuitem);
  1459. gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem),
  1460. menuitem->priv->menu);
  1461.  
  1462. return GTK_WIDGET (menuitem);
  1463. }
  1464.  
  1465. GtkWidget *
  1466. panel_desktop_menu_item_new (gboolean use_image,
  1467. gboolean append_lock_logout)
  1468. {
  1469. PanelDesktopMenuItem *menuitem;
  1470. GtkWidget *image;
  1471.  
  1472. menuitem = g_object_new (PANEL_TYPE_DESKTOP_MENU_ITEM, NULL);
  1473.  
  1474. if (use_image)
  1475. image = gtk_image_new_from_icon_name ("computer",
  1476. panel_menu_icon_get_size ());
  1477. else
  1478. image = NULL;
  1479.  
  1480. setup_menuitem (GTK_WIDGET (menuitem),
  1481. image ? panel_menu_icon_get_size () : GTK_ICON_SIZE_INVALID,
  1482. image,
  1483. _("System"));
  1484.  
  1485. menuitem->priv->use_image = use_image;
  1486.  
  1487. menuitem->priv->append_lock_logout = append_lock_logout;
  1488. if (append_lock_logout)
  1489. panel_lockdown_notify_add (G_CALLBACK (panel_desktop_menu_item_recreate_menu),
  1490. menuitem);
  1491.  
  1492. menuitem->priv->menu = panel_desktop_menu_item_create_menu (menuitem);
  1493. gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem),
  1494. menuitem->priv->menu);
  1495.  
  1496. return GTK_WIDGET (menuitem);
  1497. }
  1498.  
  1499. void
  1500. panel_place_menu_item_set_panel (GtkWidget *item,
  1501. PanelWidget *panel)
  1502. {
  1503. PanelPlaceMenuItem *place_item;
  1504.  
  1505. place_item = PANEL_PLACE_MENU_ITEM (item);
  1506.  
  1507. place_item->priv->panel = panel;
  1508. panel_applet_menu_set_recurse (GTK_MENU (place_item->priv->menu),
  1509. "menu_panel", panel);
  1510. }
  1511.  
  1512. void
  1513. panel_desktop_menu_item_set_panel (GtkWidget *item,
  1514. PanelWidget *panel)
  1515. {
  1516. PanelDesktopMenuItem *desktop_item;
  1517.  
  1518. desktop_item = PANEL_DESKTOP_MENU_ITEM (item);
  1519.  
  1520. desktop_item->priv->panel = panel;
  1521. panel_applet_menu_set_recurse (GTK_MENU (desktop_item->priv->menu),
  1522. "menu_panel", panel);
  1523. }
  1524.  
  1525. void
  1526. panel_menu_items_append_lock_logout (GtkWidget *menu)
  1527. {
  1528. gboolean separator_inserted;
  1529. GList *children;
  1530. GList *last;
  1531. GtkWidget *item;
  1532. const char *translate;
  1533. char *label;
  1534. char *tooltip;
  1535.  
  1536. separator_inserted = FALSE;
  1537. children = gtk_container_get_children (GTK_CONTAINER (menu));
  1538. last = g_list_last (children);
  1539. if (last != NULL) {
  1540. separator_inserted = GTK_IS_SEPARATOR (GTK_WIDGET (last->data));
  1541. }
  1542. g_list_free (children);
  1543.  
  1544. if (panel_lock_screen_action_available ("lock")) {
  1545. item = panel_menu_items_create_action_item (PANEL_ACTION_LOCK);
  1546. if (item != NULL) {
  1547. if (!separator_inserted) {
  1548. add_menu_separator (menu);
  1549. separator_inserted = TRUE;
  1550. }
  1551.  
  1552. gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
  1553. }
  1554. }
  1555.  
  1556. if (panel_lockdown_get_disable_log_out ())
  1557. return;
  1558. /* Below this, we only have log out/shutdown items */
  1559.  
  1560. /* Translators: translate "1" (msgctxt: "panel:showusername") to anything
  1561. * but "1" if "Log Out %s" doesn't make any sense in your
  1562. * language (where %s is a username).
  1563. */
  1564. translate = C_("panel:showusername", "1");
  1565. if (strcmp (translate, "1") == 0) {
  1566. const char *user_name;
  1567.  
  1568. user_name = g_get_real_name ();
  1569. if (!user_name || !user_name [0])
  1570. user_name = g_get_user_name ();
  1571.  
  1572. /* keep those strings in sync with the ones in
  1573. * panel-action-button.c */
  1574. /* Translators: this string is used ONLY if you translated
  1575. * "1" (msgctxt: "panel:showusername") to "1" */
  1576. label = g_strdup_printf (_("Log Out %s..."),
  1577. g_get_user_name ());
  1578. /* Translators: this string is used ONLY if you translated
  1579. * "1" (msgctxt: "panel:showusername") to "1" */
  1580. tooltip = g_strdup_printf (_("Log out %s of this session to "
  1581. "log in as a different user"),
  1582. user_name);
  1583. } else {
  1584. label = NULL;
  1585. tooltip = NULL;
  1586. }
  1587.  
  1588. item = panel_menu_items_create_action_item_full (PANEL_ACTION_LOGOUT,
  1589. label, tooltip);
  1590. g_free (label);
  1591. g_free (tooltip);
  1592.  
  1593. if (item != NULL) {
  1594. if (!separator_inserted) {
  1595. add_menu_separator (menu);
  1596. separator_inserted = TRUE;
  1597. }
  1598.  
  1599. gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
  1600. }
  1601.  
  1602. item = panel_menu_items_create_action_item (PANEL_ACTION_SHUTDOWN);
  1603. if (item != NULL) {
  1604. if (!separator_inserted)
  1605. add_menu_separator (menu);
  1606.  
  1607. gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
  1608. }
  1609. }
  1610.  
  1611. void
  1612. panel_menu_item_activate_desktop_file (GtkWidget *menuitem,
  1613. const char *path)
  1614. {
  1615. panel_launch_desktop_file (path, menuitem_to_screen (menuitem), NULL);
  1616. }
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×