Logo Search packages:      
Sourcecode: ubuntuone-client-gnome version File versions  Download package

context-menu.c

/*
 * UbuntuOne Nautilus plugin
 *
 * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
 *
 * Copyright 2009-2010 Canonical Ltd.
 *
 * This program is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 3, as published
 * by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranties of
 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
 * PURPOSE.  See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <glib/gi18n-lib.h>
#include <libsyncdaemon/libsyncdaemon.h>
#include "context-menu.h"
#include "location-widget.h"
#include "share-dialog.h"

00032 typedef struct {
      UbuntuOneNautilus *uon;
      gchar *path;
      GtkWidget *parent;

      /* Whether to make a file public or private */
      gboolean make_public;
} MenuCallbackData;

static void
free_menu_cb_data (gpointer data, GObject *where_the_object_was)
{
      MenuCallbackData *cb_data = (MenuCallbackData *) data;

      g_free (cb_data->path);
      g_free (cb_data);
}

/* Menu callbacks */
static void
got_public_meta (SyncdaemonFilesystemInterface *interface,
             gboolean success,
             SyncdaemonMetadata *metadata,
             gpointer user_data)
{
      MenuCallbackData *data = (MenuCallbackData *) user_data;
      const gchar * share_id, * node_id;
      SyncdaemonInterface *public;

      if (!success) {
            g_warning ("ERROR: getting metadata for public file");
            return;
      }

      share_id = syncdaemon_metadata_get_share_id (metadata);
      node_id = syncdaemon_metadata_get_node_id (metadata);

      public = syncdaemon_daemon_get_publicfiles_interface (data->uon->syncdaemon);
      if (public != NULL) {
            syncdaemon_publicfiles_interface_change_public_access (SYNCDAEMON_PUBLICFILES_INTERFACE (public),
                                                       share_id, node_id, data->make_public);
      }
}

static void
unsubscribe_folder_cb (NautilusMenuItem *item, gpointer user_data)
{
      SyncdaemonInterface *interface;
      MenuCallbackData * data = (MenuCallbackData *) user_data;

      /* Perform the removal of this folder */
      interface = syncdaemon_daemon_get_folders_interface (data->uon->syncdaemon);
      if (interface != NULL) {
            SyncdaemonFolderInfo *folder_info;

            folder_info = syncdaemon_folders_interface_get_info (SYNCDAEMON_FOLDERS_INTERFACE (interface),
                                                     data->path);
            if (folder_info != NULL) {
                  if (ubuntuone_check_shares_and_public_files (data->uon, folder_info, data->parent)) {
                        syncdaemon_folders_interface_delete (SYNCDAEMON_FOLDERS_INTERFACE (interface),
                                                     syncdaemon_folder_info_get_volume_id (folder_info));
                  }
                  g_object_unref (G_OBJECT (folder_info));
            }
      }
}

static void
subscribe_folder_cb (NautilusMenuItem *item, gpointer user_data)
{
      SyncdaemonInterface *interface;
      MenuCallbackData * data = (MenuCallbackData *) user_data;

      /* Perform the addition of this folder */
      interface = syncdaemon_daemon_get_folders_interface (data->uon->syncdaemon);
      if (interface != NULL) {
            /* If there is no user authenticated, make Syncdaemon do so */
            if (!syncdaemon_authentication_has_credentials (syncdaemon_daemon_get_authentication (data->uon->syncdaemon)))
                  syncdaemon_daemon_connect (data->uon->syncdaemon);
            syncdaemon_folders_interface_create (SYNCDAEMON_FOLDERS_INTERFACE (interface),
                                         data->path);
      }
}

static void
copy_public_url_cb (NautilusMenuItem *item, gpointer user_data)
{
      MenuCallbackData * data = (MenuCallbackData *) user_data;
      gchar * url;

      url = g_hash_table_lookup (data->uon->public, data->path);
      gtk_clipboard_set_text (gtk_clipboard_get(GDK_SELECTION_CLIPBOARD),
                        url, strlen (url));
      gtk_clipboard_store (gtk_clipboard_get(GDK_SELECTION_CLIPBOARD));
}

static void
toggle_publicity_cb (NautilusMenuItem * item, gpointer user_data)
{
      SyncdaemonFilesystemInterface *interface;
      MenuCallbackData * data = (MenuCallbackData *) user_data;

      interface = (SyncdaemonFilesystemInterface *) syncdaemon_daemon_get_filesystem_interface (data->uon->syncdaemon);
      if (interface != NULL) {
            /* we know this will not be a directory (so no need for _and_quick_tree_synced) */
            syncdaemon_filesystem_interface_get_metadata_async (interface, data->path, FALSE,
                                                    (SyncdaemonGotMetadataFunc) got_public_meta, data);
      }

      g_hash_table_replace (data->uon->public, g_strdup (data->path), g_strdup (UPDATE_PENDING));
      file_watcher_update_path (data->uon->file_watcher, data->path);
}

static void
share_folder_cb (NautilusMenuItem *item, gpointer user_data)
{
      MenuCallbackData * data = (MenuCallbackData *) user_data;
      GtkWidget * dialog;

      dialog = share_dialog_new (data->parent, data->uon, data->path);
      gtk_widget_show (dialog);
}

static void
unshare_folder_cb (NautilusMenuItem *item, gpointer user_data)
{
      MenuCallbackData * data = (MenuCallbackData *) user_data;
      SyncdaemonSharesInterface *interface;

      interface = (SyncdaemonSharesInterface *) syncdaemon_daemon_get_shares_interface (data->uon->syncdaemon);
      if (interface != NULL)
            syncdaemon_shares_interface_delete (interface, data->path);
}

static void
toggle_location_cb (NautilusMenuItem *item, gpointer user_data)
{
#ifdef HAVE_NAUTILUS_30
    GSettings *settings;
    settings = g_settings_new (SETTINGS_DOMAIN);
    g_settings_set_boolean (settings, SETTINGS_SHOWN_KEY, !ubuntuone_is_location_bar_enabled ());
    g_object_unref (settings);
#else
      GConfClient *conf_client;

      conf_client = gconf_client_get_default ();
      gconf_client_set_bool (conf_client, EXPANDER_SHOWN_KEY, !ubuntuone_is_location_bar_enabled (), NULL);
    g_object_unref (conf_client);
#endif
}

gboolean
check_share_offer_pending (UbuntuOneNautilus *uon, const gchar *path)
{
      GSList *shares, *l;
      SyncdaemonInterface *interface;
      gboolean is_share_offer_pending = FALSE;
      const gchar *node_id;

      interface = syncdaemon_daemon_get_shares_interface (uon->syncdaemon);
      if (SYNCDAEMON_IS_SHARES_INTERFACE (interface)) {
            shares = syncdaemon_shares_interface_get_shared (SYNCDAEMON_SHARES_INTERFACE (interface));
            for (l = shares; l != NULL; l = l->next) {
                  SyncdaemonShareInfo *share_info = SYNCDAEMON_SHARE_INFO (l->data);

                  if (g_strcmp0 (syncdaemon_share_info_get_path (share_info), path) == 0) {
                        node_id = syncdaemon_share_info_get_node_id (share_info);
                        if (node_id == NULL)
                              is_share_offer_pending = TRUE;
                        break;
                  }
            }

            g_slist_free (shares);
      }

      return is_share_offer_pending;
}

NautilusMenuItem *
context_menu_new (UbuntuOneNautilus *uon,
              GtkWidget *window,
              GList *files)
{
      NautilusFileInfo *file;
      NautilusMenu *submenu;
      NautilusMenuItem *root_item, *menu_item, *urlitem;
      gchar *path, *item, *homedir_path, *path_uri;
      gboolean is_managed, is_root, is_udf, is_public, is_shared, is_pending;
      gboolean is_shared_to_me, is_inhome, is_dir, is_regular, is_symlink;
      gboolean is_share_offer_pending;
      MenuCallbackData *cb_data;

      is_managed = is_root = is_udf = is_public = is_shared = is_pending = FALSE;
      is_shared_to_me = is_inhome = is_dir = is_regular = is_symlink = FALSE;
      is_share_offer_pending = FALSE;

      if (g_list_length (files) != 1)
            return NULL;

      file = NAUTILUS_FILE_INFO (g_list_nth_data (files, 0));
      path_uri = nautilus_file_info_get_uri (file);
      path = g_filename_from_uri (path_uri, NULL, NULL);
      g_free (path_uri);

      if (path == NULL)
            return NULL;

      if (syncdaemon_daemon_is_folder_enabled (uon->syncdaemon, path, &is_root))
            is_managed = TRUE;

      homedir_path = g_strdup_printf ("%s/", g_get_home_dir());
      if (strncmp (path, homedir_path, strlen (homedir_path)) == 0)
            is_inhome = TRUE;
      g_free (homedir_path);

      if ((item = g_hash_table_lookup (uon->udfs, path)) != NULL) {
            is_udf = TRUE;
            if (strcmp (item, UPDATE_PENDING) == 0)
                  is_pending = TRUE;
      } else if ((item = g_hash_table_lookup (uon->public, path)) != NULL) {
            is_public = TRUE;
            if (strcmp (item, UPDATE_PENDING) == 0)
                  is_pending = TRUE;
      }

      if (ubuntuone_is_folder_shared (uon, path)) {
            is_shared = TRUE;
            if (check_share_offer_pending (uon, path))
                  is_share_offer_pending = TRUE;
      }

      if (ubuntuone_is_inside_shares (uon, path))
            is_shared_to_me = TRUE;

      is_dir = nautilus_file_info_is_directory (file);
      is_regular = nautilus_file_info_get_file_type (file) == G_FILE_TYPE_REGULAR;

      is_symlink = g_file_test (path, G_FILE_TEST_IS_SYMLINK);

      cb_data = g_new0 (MenuCallbackData, 1);
      cb_data->uon = uon;
      cb_data->parent = window;
      cb_data->path = g_strdup (path);

      /* Create the root item */
      root_item = nautilus_menu_item_new ("ubuntuone",
                                  _("_Ubuntu One"),
                                  _("Ubuntu One options"),
                                  "ubuntuone");
      submenu = nautilus_menu_new ();
      nautilus_menu_item_set_submenu (root_item, submenu);

      g_object_weak_ref (G_OBJECT (root_item), (GWeakNotify) free_menu_cb_data, cb_data);

      /* Share/unshare */
      if ((is_managed || is_udf) && !is_root && is_dir && !is_symlink) {

            menu_item = nautilus_menu_item_new ("ubuntuone-share",
                                        _("_Share..."),
                                        _("Share this folder on Ubuntu One"),
                                        "ubuntuone");
            if (is_pending)
                  g_object_set (menu_item, "sensitive", FALSE, NULL);

            g_signal_connect (menu_item, "activate",
                          G_CALLBACK (share_folder_cb), cb_data);
      } else {
            /* the different tooltips will probably do us no good */
            if (is_root) {
                  menu_item = nautilus_menu_item_new ("ubuntuone-noshare-root",
                                              _("_Share..."),
                                              _("Sorry, you can't share the root of a Ubuntu One volume"),
                                              "ubuntuone");
            } else if (!(is_managed || is_udf)) {
                  menu_item = nautilus_menu_item_new ("ubuntuone-noshare-unmanaged",
                                              _("_Share..."),
                                              _("Sorry, you can't share folders not managed by Ubuntu One"),
                                              "ubuntuone");
            } else {
                  menu_item = nautilus_menu_item_new ("ubuntuone-noshare-unmanaged",
                                              _("_Share..."),
                                              _("Sorry, you can only share folders"),
                                              "ubuntuone");
            }
            g_object_set (menu_item, "sensitive", FALSE, NULL);
      }

      nautilus_menu_append_item (submenu, menu_item);

      if ((is_managed && is_shared) && !is_root && is_dir && !is_symlink) {
            menu_item = nautilus_menu_item_new ("ubuntuone-unshare",
                                        _("Stop _Sharing"),
                                        _("Stop sharing this folder on Ubuntu One"),
                                        "ubuntuone");
            if (is_pending || is_share_offer_pending)
                  g_object_set (menu_item, "sensitive", FALSE, NULL);

            g_signal_connect (menu_item, "activate",
                          G_CALLBACK (unshare_folder_cb), cb_data);
            nautilus_menu_append_item (submenu, menu_item);
      }

      /* UDF logic
       *
       * XXX: clean this up and separate the logic out and reuse this
       * and locationbar somewhere (libsd?)
       */
      menu_item = NULL;

      if (is_dir && is_inhome && !is_symlink) {
            /* UDFs could be happening */
            if (is_managed) {
                  if (strcmp (path, uon->managed) == 0) {
                        /* the Ubuntu One directory, no UDFs */
                        menu_item = nautilus_menu_item_new ("ubuntuone-no-disable-u1",
                                                    _("Stop Synchronizing This _Folder"),
                                                    _("Sorry, you can't stop synchronizing ~/Ubuntu One"),
                                                    "ubuntuone");
                        g_object_set (menu_item, "sensitive", FALSE, NULL);
                  } else if (is_root) {
                        /* the root of a UDF: disabling possible */

                        menu_item = nautilus_menu_item_new ("ubuntuone-disable-udf",
                                                    _("Stop Synchronizing This _Folder"),
                                                    _("Stop synchronizing this folder with Ubuntu One"),
                                                    "ubuntuone");

                        g_signal_connect (menu_item, "activate",
                                      G_CALLBACK (unsubscribe_folder_cb), cb_data);
                  }
            } else {
                  /* unmanaged */
                  menu_item = nautilus_menu_item_new ("ubuntuone-enable-udf",
                                              _("Synchronize This _Folder"),
                                              _("Start synchronizing this folder with Ubuntu One"),
                                              "ubuntuone");

                  g_signal_connect (menu_item, "activate",
                                G_CALLBACK (subscribe_folder_cb), cb_data);
            }
      } else {
            if (is_dir) {
                  menu_item = nautilus_menu_item_new ("ubuntuone-no-disable-u1",
                                              _("Synchronize This _Folder"),
                                              _("Sorry, you can only synchronize folders within your home folder"),
                                              "ubuntuone");
            } else {
                  menu_item = nautilus_menu_item_new ("ubuntuone-no-disable-u1",
                                              _("Synchronize This _Folder"),
                                              _("Sorry, you can only synchronize folders"),
                                              "ubuntuone");
            }

            g_object_set (menu_item, "sensitive", FALSE, NULL);
      }

      if (!menu_item) {
            menu_item = nautilus_menu_item_new ("ubuntuone-no-udf-operation-possible",
                                        _("Synchronize This _Folder"),
                                        _("Synchronization not possible for this folder"),
                                        "ubuntuone");
            g_object_set (menu_item, "sensitive", FALSE, NULL);
      }

      nautilus_menu_append_item (submenu, menu_item);

      /* public files */
      menu_item = urlitem = NULL;

      if (!is_shared_to_me && is_managed && is_regular && !is_symlink) {
            if (is_public) {
                  urlitem = nautilus_menu_item_new ("ubuntuone-geturl",
                                            _("Copy Web _Link"),
                                            _("Copy the Ubuntu One public URL for this file to the clipboard."),
                                            "ubuntuone");
                  if (is_pending)
                        g_object_set (urlitem, "sensitive", FALSE, NULL);
                  g_signal_connect (urlitem, "activate",
                                G_CALLBACK (copy_public_url_cb), cb_data);

                  menu_item = nautilus_menu_item_new ("ubuntuone-unpublish",
                                              _("Stop _Publishing"),
                                              _("No longer share this file with everyone via Ubuntu One."),
                                              "ubuntuone");
                  if (is_pending)
                        g_object_set (menu_item, "sensitive", FALSE, NULL);

                  cb_data->make_public = FALSE;
            } else {
                  menu_item = nautilus_menu_item_new ("ubuntuone-publish",
                                              _("_Publish"),
                                              _("Make this file available to anyone via Ubuntu One."),
                                              "ubuntuone");
                  cb_data->make_public = TRUE;
            }
            g_signal_connect (menu_item, "activate",
                          G_CALLBACK (toggle_publicity_cb), cb_data);
      }

      if (!urlitem) {
            urlitem = nautilus_menu_item_new ("ubuntuone-geturl",
                                      _("Copy Web _Link"),
                                      _("Sorry, no public URL for this file via Ubuntu One."),
                                      "ubuntuone");
            g_object_set (urlitem, "sensitive", FALSE, NULL);
      }

      if (!menu_item) {
            menu_item = nautilus_menu_item_new ("ubuntuone-publish",
                                        _("_Publish"),
                                        _("Sorry, unable to publish via Ubuntu One."),
                                        "ubuntuone");
            g_object_set (menu_item, "sensitive", FALSE, NULL);
      }

      nautilus_menu_append_item (submenu, menu_item);
      nautilus_menu_append_item (submenu, urlitem);

      /* location bar enable/disable */
      if (ubuntuone_is_location_bar_enabled ()) {
            menu_item = nautilus_menu_item_new ("ubuntuone-location-hide",
                                        _("Hide _Ribbon"),
                                        _("Do not show the Ubuntu One ribbon"
                                          " in selected folders"),
                                        "ubuntuone");
      } else {
            menu_item = nautilus_menu_item_new ("ubuntuone-location-show",
                                        _("Show _Ribbon in Some Folders"),
                                        _("Show the Ubuntu One ribbon"
                                          " in selected folders"),
                                        "ubuntuone");
      }

      g_signal_connect (menu_item, "activate",
                    G_CALLBACK (toggle_location_cb), cb_data);
      nautilus_menu_append_item (submenu, menu_item);

      g_free (path);
      return root_item;
}

Generated by  Doxygen 1.6.0   Back to index