summaryrefslogtreecommitdiff
path: root/share/caja-share.c
diff options
context:
space:
mode:
Diffstat (limited to 'share/caja-share.c')
-rw-r--r--share/caja-share.c1284
1 files changed, 0 insertions, 1284 deletions
diff --git a/share/caja-share.c b/share/caja-share.c
deleted file mode 100644
index 986f48d..0000000
--- a/share/caja-share.c
+++ /dev/null
@@ -1,1284 +0,0 @@
-/* mate-file-manager-share -- Caja File Sharing Extension
- *
- * Sebastien Estienne <[email protected]>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * (C) Copyright 2005 Ethium, Inc.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <libcaja-extension/caja-extension-types.h>
-#include <libcaja-extension/caja-column-provider.h>
-#include <libcaja-extension/caja-extension-types.h>
-#include <libcaja-extension/caja-file-info.h>
-#include <libcaja-extension/caja-info-provider.h>
-#include <libcaja-extension/caja-menu-provider.h>
-#include <libcaja-extension/caja-property-page-provider.h>
-
-#include "mate-file-manager-share.h"
-
-#include <glib/gi18n-lib.h>
-
-#include <gio/gio.h>
-
-#include <gtk/gtk.h>
-
-#include <string.h>
-#include <time.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-#include "shares.h"
-
-
-#define NEED_IF_GUESTOK_MASK (S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) /* need go+rx for guest enabled usershares */
-#define NEED_IF_WRITABLE_MASK (S_IWGRP | S_IWOTH) /* writable usershares need go+w additionally*/
-#define NEED_ALL_MASK (NEED_IF_GUESTOK_MASK | NEED_IF_WRITABLE_MASK)
-
-static GObjectClass *parent_class;
-
-/* Structure to hold all the information for a share's property page. If
- * you add stuff to this, add it to free_property_page_cb() as well.
- */
-typedef struct {
- char *path; /* Full path which is being shared */
- CajaFileInfo *fileinfo; /* Caja file to which this page refers */
-
- GtkBuilder *xml;
-
- GtkWidget *main; /* Widget that holds all the rest. Its "PropertyPage" GObject-data points to this PropertyPage structure */
-
- GtkWidget *checkbutton_share_folder;
- GtkWidget *hbox_share_name;
- GtkWidget *hbox_share_comment;
- GtkWidget *entry_share_name;
- GtkWidget *checkbutton_share_rw_ro;
- GtkWidget *checkbutton_share_guest_ok;
- GtkWidget *entry_share_comment;
- GtkWidget *label_status;
- GtkWidget *button_cancel;
- GtkWidget *button_apply;
-
- GtkWidget *standalone_window;
-
- gboolean was_initially_shared;
- gboolean was_writable;
- gboolean is_dirty;
-} PropertyPage;
-
-static void property_page_set_warning (PropertyPage *page);
-static void property_page_set_error (PropertyPage *page, const char *message);
-static void property_page_set_normal (PropertyPage *page);
-
-static void
-property_page_validate_fields (PropertyPage *page)
-{
- const char *name;
-
- name = gtk_entry_get_text (GTK_ENTRY (page->entry_share_name));
-
- if (g_utf8_strlen (name, -1) <= 12)
- property_page_set_normal (page);
- else
- property_page_set_warning (page);
-}
-
-static gboolean
-message_confirm_missing_permissions (GtkWidget *widget, const char *path, mode_t need_mask)
-{
- GtkWidget *toplevel;
- GtkWidget *dialog;
- char *display_name;
- gboolean result;
-
- toplevel = gtk_widget_get_toplevel (widget);
- if (!GTK_IS_WINDOW (toplevel))
- toplevel = NULL;
-
- display_name = g_filename_display_basename (path);
-
- dialog = gtk_message_dialog_new (toplevel ? GTK_WINDOW (toplevel) : NULL,
- 0,
- GTK_MESSAGE_QUESTION,
- GTK_BUTTONS_NONE,
- _("Caja needs to add some permissions to your folder \"%s\" in order to share it"),
- display_name);
-
- /* FIXME: the following message only mentions "permission by others". We
- * should probably be more explicit and mention group/other permissions.
- * We'll be able to do that after the period of string freeze.
- */
- gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
- _("The folder \"%s\" needs the following extra permissions for sharing to work:\n"
- "%s%s%s"
- "Do you want Caja to add these permissions to the folder automatically?"),
- display_name,
- (need_mask & (S_IRGRP | S_IROTH)) ? _(" - read permission by others\n") : "",
- (need_mask & (S_IWGRP | S_IWOTH)) ? _(" - write permission by others\n") : "",
- (need_mask & (S_IXGRP | S_IXOTH)) ? _(" - execute permission by others\n") : "");
- g_free (display_name);
-
- gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
- gtk_dialog_add_button (GTK_DIALOG (dialog), _("Add the permissions automatically"), GTK_RESPONSE_ACCEPT);
- gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
-
- result = gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT;
- gtk_widget_destroy (dialog);
-
- return result;
-}
-
-static void
-error_when_changing_permissions (GtkWidget *widget, const char *path)
-{
- GtkWidget *toplevel;
- GtkWidget *dialog;
- char *display_name;
-
- toplevel = gtk_widget_get_toplevel (widget);
- if (!GTK_IS_WINDOW (toplevel))
- toplevel = NULL;
-
- display_name = g_filename_display_basename (path);
-
- dialog = gtk_message_dialog_new (toplevel ? GTK_WINDOW (toplevel) : NULL,
- 0,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_OK,
- _("Could not change the permissions of folder \"%s\""),
- display_name);
- g_free (display_name);
-
- gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (dialog);
-}
-
-static char *
-get_key_file_path (void)
-{
- return g_build_filename (g_get_home_dir (), ".mate2", "mate-file-manager-share-modified-permissions", NULL);
-}
-
-static void
-save_key_file (const char *filename, GKeyFile *key_file)
-{
- char *contents;
- gsize length;
-
- /* NULL GError */
- contents = g_key_file_to_data (key_file, &length, NULL);
- if (!contents)
- return;
-
- /* NULL GError */
- g_file_set_contents (filename, contents, length, NULL);
-
- g_free (contents);
-}
-
-static void
-save_changed_permissions (const char *path, mode_t need_mask)
-{
- GKeyFile *key_file;
- char *key_file_path;
- char str[50];
-
- key_file = g_key_file_new ();
- key_file_path = get_key_file_path ();
-
- /* NULL GError
- *
- * We don't check the return value of this. If the file doesn't exist, we'll
- * simply want to create it.
- */
- g_key_file_load_from_file (key_file, key_file_path, 0, NULL);
-
- g_snprintf (str, sizeof (str), "%o", (guint) need_mask); /* octal, baby */
- g_key_file_set_string (key_file, path, "need_mask", str);
-
- save_key_file (key_file_path, key_file);
-
- g_key_file_free (key_file);
- g_free (key_file_path);
-}
-
-static void
-remove_permissions (const char *path, mode_t need_mask)
-{
- struct stat st;
- mode_t new_mode;
-
- if (need_mask == 0)
- return;
-
- if (stat (path, &st) != 0)
- return;
-
- new_mode = st.st_mode & ~need_mask;
-
- /* Bleah, no error checking */
- chmod (path, new_mode);
-}
-
-static void
-remove_from_saved_permissions (const char *path, mode_t remove_mask)
-{
- GKeyFile *key_file;
- char *key_file_path;
-
- if (remove_mask == 0)
- return;
-
- key_file = g_key_file_new ();
- key_file_path = get_key_file_path ();
-
- if (g_key_file_load_from_file (key_file, key_file_path, 0, NULL))
- {
- mode_t need_mask;
- mode_t remove_from_current_mask;
- char *str;
-
- need_mask = 0;
-
- /* NULL GError */
- str = g_key_file_get_string (key_file, path, "need_mask", NULL);
-
- if (str)
- {
- guint i;
-
- if (sscanf (str, "%o", &i) == 1) /* octal */
- need_mask = i;
-
- g_free (str);
- }
-
- remove_from_current_mask = need_mask & remove_mask;
- remove_permissions (path, remove_from_current_mask);
-
- need_mask &= ~remove_mask;
-
- if (need_mask == 0)
- {
- /* NULL GError */
- g_key_file_remove_group (key_file, path, NULL);
- }
- else
- {
- char buf[50];
-
- g_snprintf (buf, sizeof (buf), "%o", (guint) need_mask); /* octal */
- g_key_file_set_string (key_file, path, "need_mask", buf);
- }
-
- save_key_file (key_file_path, key_file);
- }
-
- g_key_file_free (key_file);
- g_free (key_file_path);
-}
-
-static void
-restore_saved_permissions (const char *path)
-{
- remove_from_saved_permissions (path, NEED_ALL_MASK);
-}
-
-static void
-restore_write_permissions (const char *path)
-{
- remove_from_saved_permissions (path, NEED_IF_WRITABLE_MASK);
-}
-
-typedef enum {
- CONFIRM_CANCEL_OR_ERROR,
- CONFIRM_NO_MODIFICATIONS,
- CONFIRM_MODIFIED
-} ConfirmPermissionsStatus;
-
-static ConfirmPermissionsStatus
-confirm_sharing_permissions (GtkWidget *widget, const char *path, gboolean is_shared, gboolean guest_ok, gboolean is_writable)
-{
- struct stat st;
- mode_t mode, new_mode, need_mask;
-
- if (!is_shared)
- return CONFIRM_NO_MODIFICATIONS;
-
- if (stat (path, &st) != 0)
- return CONFIRM_NO_MODIFICATIONS; /* We'll just let "net usershare" give back an error if the file disappears */
-
- new_mode = mode = st.st_mode;
-
- if (guest_ok)
- new_mode |= NEED_IF_GUESTOK_MASK;
- if (is_writable)
- new_mode |= NEED_IF_WRITABLE_MASK;
-
- need_mask = new_mode & ~mode;
-
- if (need_mask != 0)
- {
- g_assert (mode != new_mode);
-
- if (!message_confirm_missing_permissions (widget, path, need_mask))
- return CONFIRM_CANCEL_OR_ERROR;
-
- if (chmod (path, new_mode) != 0)
- {
- error_when_changing_permissions (widget, path);
- return CONFIRM_CANCEL_OR_ERROR;
- }
-
- save_changed_permissions (path, need_mask);
-
- return CONFIRM_MODIFIED;
- }
- else
- {
- g_assert (mode == new_mode);
- return CONFIRM_NO_MODIFICATIONS;
- }
-
- g_assert_not_reached ();
- return CONFIRM_CANCEL_OR_ERROR;
-}
-
-static gboolean
-property_page_commit (PropertyPage *page)
-{
- gboolean is_shared;
- ShareInfo share_info;
- ConfirmPermissionsStatus status;
- GError *error;
- gboolean retval;
-
- is_shared = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (page->checkbutton_share_folder));
-
- share_info.path = page->path;
- share_info.share_name = (char *) gtk_entry_get_text (GTK_ENTRY (page->entry_share_name));
- share_info.comment = (char *) gtk_entry_get_text (GTK_ENTRY (page->entry_share_comment));
- share_info.is_writable = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (page->checkbutton_share_rw_ro));
- share_info.guest_ok = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (page->checkbutton_share_guest_ok));
-
- /* Do we need to unset the write permissions that we added in the past? */
- if (is_shared && page->was_writable && !share_info.is_writable)
- restore_write_permissions (page->path);
-
- status = confirm_sharing_permissions (page->main, page->path, is_shared, share_info.guest_ok, share_info.is_writable);
- if (status == CONFIRM_CANCEL_OR_ERROR)
- return FALSE; /* the user didn't want us to change his folder's permissions */
-
- error = NULL;
- retval = shares_modify_share (share_info.path, is_shared ? &share_info : NULL, &error);
-
- if (!retval)
- {
- property_page_set_error (page, error->message);
- g_error_free (error);
-
- /* Since the operation failed, we restore things to the way they were */
- if (status == CONFIRM_MODIFIED)
- restore_saved_permissions (page->path);
- }
- else
- {
- property_page_validate_fields (page);
- caja_file_info_invalidate_extension_info (page->fileinfo);
- }
-
- if (!is_shared)
- restore_saved_permissions (page->path);
-
- /* update initially shared state, so that we may undo later on */
- if (retval)
- {
- page->was_initially_shared = is_shared;
- page->is_dirty = FALSE;
- }
-
- return retval;
-}
-
-/*--------------------------------------------------------------------------*/
-static gchar *
-get_fullpath_from_fileinfo(CajaFileInfo *fileinfo)
-{
- GFile *file;
- gchar *fullpath;
-
- g_assert (fileinfo != NULL);
-
- file = caja_file_info_get_location(fileinfo);
- fullpath = g_file_get_path(file);
- g_assert (fullpath != NULL && g_file_is_native(file)); /* In the beginning we checked that this was a local URI */
- g_object_unref(file);
-
- return(fullpath);
-}
-
-
-/*--------------------------------------------------------------------------*/
-static void
-property_page_set_warning (PropertyPage *page)
-{
- GdkColor colorYellow;
-
- gtk_label_set_text (GTK_LABEL (page->label_status), _("Share name is too long"));
-
- gdk_color_parse ("#ECDF62", &colorYellow);
- gtk_widget_modify_base (page->entry_share_name, GTK_STATE_NORMAL, &colorYellow);
-}
-
-
-static void
-property_page_set_error (PropertyPage *page, const char *message)
-{
- GdkColor colorRed;
-
- gtk_label_set_text (GTK_LABEL (page->label_status), message);
-
- gdk_color_parse ("#C1665A", &colorRed);
- gtk_widget_modify_base (page->entry_share_name, GTK_STATE_NORMAL, &colorRed);
-}
-
-static void
-property_page_set_normal (PropertyPage *page)
-{
- gtk_label_set_text (GTK_LABEL (page->label_status), "");
- gtk_widget_modify_base (page->entry_share_name, GTK_STATE_NORMAL, NULL);
-}
-
-static gboolean
-property_page_share_name_is_valid (PropertyPage *page)
-{
- const char *newname;
-
- newname = gtk_entry_get_text (GTK_ENTRY (page->entry_share_name));
-
- if (strlen (newname) == 0)
- {
- property_page_set_error (page, _("The share name cannot be empty"));
- return FALSE;
- }
- else
- {
- GError *error;
- gboolean exists;
-
- error = NULL;
- if (!shares_get_share_name_exists (newname, &exists, &error))
- {
- char *str;
-
- str = g_strdup_printf (_("Error while getting share information: %s"), error->message);
- property_page_set_error (page, str);
- g_free (str);
- g_error_free (error);
-
- return FALSE;
- }
-
- if (exists)
- {
- property_page_set_error (page, _("Another share has the same name"));
- return FALSE;
- }
- else
- {
- property_page_set_normal (page);
- return TRUE;
- }
- }
-}
-
-static void
-property_page_set_controls_sensitivity (PropertyPage *page,
- gboolean sensitive)
-{
- gtk_widget_set_sensitive (page->entry_share_name, sensitive);
- gtk_widget_set_sensitive (page->entry_share_comment, sensitive);
- gtk_widget_set_sensitive (page->hbox_share_comment, sensitive);
- gtk_widget_set_sensitive (page->hbox_share_name, sensitive);
- gtk_widget_set_sensitive (page->checkbutton_share_rw_ro, sensitive);
-
- if (sensitive)
- {
- gboolean guest_ok_allowed;
- shares_supports_guest_ok (&guest_ok_allowed, NULL);
- gtk_widget_set_sensitive (page->checkbutton_share_guest_ok, guest_ok_allowed);
- }
- else
- gtk_widget_set_sensitive (page->checkbutton_share_guest_ok, FALSE);
-}
-
-static void
-property_page_check_sensitivity (PropertyPage *page)
-{
- gboolean enabled;
- gboolean apply_is_sensitive;
-
- enabled = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (page->checkbutton_share_folder));
- property_page_set_controls_sensitivity (page, enabled);
-
- if (enabled)
- apply_is_sensitive = page->is_dirty || !page->was_initially_shared;
- else
- apply_is_sensitive = page->was_initially_shared;
-
- gtk_widget_set_sensitive (page->button_apply, apply_is_sensitive);
- gtk_button_set_label (GTK_BUTTON(page->button_apply),
- page->was_initially_shared ? _("Modify _Share") : _("Create _Share"));
-}
-
-static void
-modify_share_name_text_entry (GtkEditable *editable,
- gpointer user_data)
-{
- PropertyPage *page;
-
- page = user_data;
-
- page->is_dirty = TRUE;
-
- /* This function does simple validation on the share name and sets the error
- * label; just let it run and ignore the result value.
- */
- property_page_share_name_is_valid (page);
-
- property_page_check_sensitivity (page);
-}
-
-static void
-modify_share_comment_text_entry (GtkEditable *editable,
- gpointer user_data)
-{
- PropertyPage *page;
-
- page = user_data;
-
- page->is_dirty = TRUE;
- property_page_check_sensitivity (page);
-}
-
-/*--------------------------------------------------------------------------*/
-static void
-on_checkbutton_share_folder_toggled (GtkToggleButton *togglebutton,
- gpointer user_data)
-{
- PropertyPage *page;
-
- page = user_data;
-
- property_page_check_sensitivity (page);
-}
-
-static void
-on_checkbutton_rw_ro_toggled (GtkToggleButton *togglebutton,
- gpointer user_data)
-{
- PropertyPage *page;
-
- page = user_data;
-
- page->is_dirty = TRUE;
-
- property_page_check_sensitivity (page);
-}
-
-static void
-on_checkbutton_guest_ok_toggled (GtkToggleButton *togglebutton,
- gpointer user_data)
-{
- PropertyPage *page;
-
- page = user_data;
-
- page->is_dirty = TRUE;
-
- property_page_check_sensitivity (page);
-}
-
-static void
-free_property_page_cb (gpointer data)
-{
- PropertyPage *page;
-
- page = data;
-
- g_free (page->path);
- g_object_unref (page->fileinfo);
- g_object_unref (page->xml);
-
- g_free (page);
-}
-
-static void
-button_apply_clicked_cb (GtkButton *button,
- gpointer data)
-{
- PropertyPage *page;
-
- page = data;
-
- if (property_page_commit (page))
- {
- if (page->standalone_window)
- gtk_widget_destroy (page->standalone_window);
- else
- property_page_check_sensitivity (page);
- }
-}
-
-/*--------------------------------------------------------------------------*/
-static PropertyPage *
-create_property_page (CajaFileInfo *fileinfo)
-{
- PropertyPage *page;
- GError *error;
- ShareInfo *share_info;
- char *share_name;
- gboolean free_share_name;
- const char *comment;
- char *apply_button_label;
-
- page = g_new0 (PropertyPage, 1);
-
- page->path = get_fullpath_from_fileinfo(fileinfo);
- page->fileinfo = g_object_ref (fileinfo);
-
- error = NULL;
- if (!shares_get_share_info_for_path (page->path, &share_info, &error))
- {
- /* We'll assume that there is no share for that path, but we'll still
- * bring up an error dialog.
- */
- GtkWidget *message;
-
- message = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
- _("There was an error while getting the sharing information"));
- gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message), "%s", error->message);
- gtk_widget_show (message);
-
- share_info = NULL;
- g_error_free (error);
- error = NULL;
- }
-
-
- page->xml = gtk_builder_new ();
- gtk_builder_set_translation_domain (page->xml, "mate-file-manager-share");
- g_assert (gtk_builder_add_from_file (page->xml,
- INTERFACES_DIR"/share-dialog.ui", &error));
-
- page->main = GTK_WIDGET (gtk_builder_get_object (page->xml, "vbox1"));
- g_assert (page->main != NULL);
-
- g_object_set_data_full (G_OBJECT (page->main),
- "PropertyPage",
- page,
- free_property_page_cb);
-
- page->checkbutton_share_folder = GTK_WIDGET (gtk_builder_get_object (page->xml,"checkbutton_share_folder"));
- page->hbox_share_comment = GTK_WIDGET (gtk_builder_get_object (page->xml,"hbox_share_comment"));
- page->hbox_share_name = GTK_WIDGET (gtk_builder_get_object (page->xml,"hbox_share_name"));
- page->checkbutton_share_rw_ro = GTK_WIDGET (gtk_builder_get_object (page->xml,"checkbutton_share_rw_ro"));
- page->checkbutton_share_guest_ok = GTK_WIDGET (gtk_builder_get_object (page->xml,"checkbutton_share_guest_ok"));
- page->entry_share_name = GTK_WIDGET (gtk_builder_get_object (page->xml,"entry_share_name"));
- page->entry_share_comment = GTK_WIDGET (gtk_builder_get_object (page->xml,"entry_share_comment"));
- page->label_status = GTK_WIDGET (gtk_builder_get_object (page->xml,"label_status"));
- page->button_cancel = GTK_WIDGET (gtk_builder_get_object (page->xml,"button_cancel"));
- page->button_apply = GTK_WIDGET (gtk_builder_get_object (page->xml,"button_apply"));
-
- /* Sanity check so that we don't screw up the Glade file */
- g_assert (page->checkbutton_share_folder != NULL
- && page->hbox_share_comment != NULL
- && page->hbox_share_name != NULL
- && page->checkbutton_share_rw_ro != NULL
- && page->checkbutton_share_guest_ok != NULL
- && page->entry_share_name != NULL
- && page->entry_share_comment != NULL
- && page->label_status != NULL
- && page->button_cancel != NULL
- && page->button_apply != NULL);
-
- if (share_info)
- {
- page->was_initially_shared = TRUE;
- page->was_writable = share_info->is_writable;
- }
-
- /* Share name */
-
- if (share_info)
- {
- share_name = share_info->share_name;
- free_share_name = FALSE;
- }
- else
- {
- share_name = g_filename_display_basename (page->path);
- free_share_name = TRUE;
- }
-
- gtk_entry_set_text (GTK_ENTRY (page->entry_share_name), share_name);
-
- if (free_share_name)
- g_free (share_name);
-
- /* Comment */
-
- if (share_info == NULL || share_info->comment == NULL)
- comment = "";
- else
- comment = share_info->comment;
-
- gtk_entry_set_text (GTK_ENTRY (page->entry_share_comment), comment);
-
- /* Share toggle */
-
- if (share_info)
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (page->checkbutton_share_folder), TRUE);
- else
- {
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (page->checkbutton_share_folder), FALSE);
- }
-
- /* Share name */
-
- if (g_utf8_strlen(gtk_entry_get_text (GTK_ENTRY (page->entry_share_name)), -1) > 12)
- property_page_set_warning (page);
-
- /* Permissions */
- if (share_info != NULL && share_info->is_writable)
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (page->checkbutton_share_rw_ro), TRUE);
- else
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (page->checkbutton_share_rw_ro), FALSE);
-
- /* Guest access */
- if (share_info != NULL && share_info->guest_ok)
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (page->checkbutton_share_guest_ok), TRUE);
- else
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (page->checkbutton_share_guest_ok), FALSE);
-
- /* Apply button */
-
- if (share_info)
- apply_button_label = _("Modify _Share");
- else
- apply_button_label = _("Create _Share");
-
- gtk_button_set_label (GTK_BUTTON (page->button_apply), apply_button_label);
- gtk_button_set_use_underline (GTK_BUTTON (page->button_apply), TRUE);
- gtk_button_set_image (GTK_BUTTON (page->button_apply), gtk_image_new_from_stock (GTK_STOCK_SAVE, GTK_ICON_SIZE_BUTTON));
-
- gtk_widget_set_sensitive (page->button_apply, FALSE);
-
- /* Sensitivity */
-
- property_page_check_sensitivity (page);
-
- /* Signal handlers */
-
- g_signal_connect (page->checkbutton_share_folder, "toggled",
- G_CALLBACK (on_checkbutton_share_folder_toggled),
- page);
-
- g_signal_connect (page->checkbutton_share_rw_ro, "toggled",
- G_CALLBACK (on_checkbutton_rw_ro_toggled),
- page);
-
- g_signal_connect (page->checkbutton_share_guest_ok, "toggled",
- G_CALLBACK (on_checkbutton_guest_ok_toggled),
- page);
-
- g_signal_connect (page->entry_share_name, "changed",
- G_CALLBACK (modify_share_name_text_entry),
- page);
-
- g_signal_connect (page->entry_share_comment, "changed",
- G_CALLBACK (modify_share_comment_text_entry),
- page);
-
- g_signal_connect (page->button_apply, "clicked",
- G_CALLBACK (button_apply_clicked_cb), page);
-
- if (share_info != NULL)
- shares_free_share_info (share_info);
-
- return page;
-}
-
-/* Implementation of the CajaInfoProvider interface */
-
-/* caja_info_provider_update_file_info
- * This function is called by Caja when it wants the extension to
- * fill in data about the file. It passes a CajaFileInfo object,
- * which the extension can use to read data from the file, and which
- * the extension should add data to.
- *
- * If the data can be added immediately (without doing blocking IO),
- * the extension can do so, and return CAJA_OPERATION_COMPLETE.
- * In this case the 'update_complete' and 'handle' parameters can be
- * ignored.
- *
- * If waiting for the deata would block the UI, the extension should
- * perform the task asynchronously, and return
- * CAJA_OPERATION_IN_PROGRESS. The function must also set the
- * 'handle' pointer to a value unique to the object, and invoke the
- * 'update_complete' closure when the update is done.
- *
- * If the extension encounters an error, it should return
- * CAJA_OPERATION_FAILED.
- */
-typedef struct {
- gboolean cancelled;
- CajaInfoProvider *provider;
- CajaFileInfo *file;
- GClosure *update_complete;
-} CajaShareHandle;
-
-static CajaShareStatus
-get_share_status_and_free_share_info (ShareInfo *share_info)
-{
- CajaShareStatus result;
-
- if (!share_info)
- result = CAJA_SHARE_NOT_SHARED;
- else
- {
- if (share_info->is_writable)
- result = CAJA_SHARE_SHARED_RW;
- else
- result = CAJA_SHARE_SHARED_RO;
-
- shares_free_share_info (share_info);
- }
-
- return result;
-}
-
-
-/*--------------------------------------------------------------------------*/
-static void
-get_share_info_for_file_info (CajaFileInfo *file, ShareInfo **share_info, gboolean *is_shareable)
-{
- char *uri;
- char *local_path = NULL;
- GFile *f;
-
- *share_info = NULL;
- *is_shareable = FALSE;
-
- uri = caja_file_info_get_uri (file);
- f = caja_file_info_get_location(file);
- if (!uri)
- goto out;
-
-#define NETWORK_SHARE_PREFIX "network:///share-"
-
- if (g_str_has_prefix (uri, NETWORK_SHARE_PREFIX))
- {
- const char *share_name;
-
- share_name = uri + strlen (NETWORK_SHARE_PREFIX);
-
- /* FIXME: NULL GError */
- if (!shares_get_share_info_for_share_name (share_name, share_info, NULL))
- {
- *share_info = NULL;
- *is_shareable = TRUE; /* it *has* the prefix, anyway... we are just unsynchronized with what mate-vfs thinks */
- }
- else
- {
- *is_shareable = TRUE;
- }
-
- goto out;
- }
-
- if (!caja_file_info_is_directory(file))
- goto out;
-
- local_path = g_file_get_path(f);
- if (!local_path || !g_file_is_native(f))
- goto out;
-
- /* FIXME: NULL GError */
- if (!shares_get_share_info_for_path (local_path, share_info, NULL))
- goto out;
-
- *is_shareable = TRUE;
-
- out:
-
- g_object_unref(f);
- g_free (uri);
- g_free (local_path);
-}
-
-/*--------------------------------------------------------------------------*/
-static CajaShareStatus
-file_get_share_status_file(CajaFileInfo *file)
-{
- ShareInfo *share_info;
- gboolean is_shareable;
-
- get_share_info_for_file_info (file, &share_info, &is_shareable);
-
- if (!is_shareable)
- return CAJA_SHARE_NOT_SHARED;
-
- return get_share_status_and_free_share_info (share_info);
-}
-
-static CajaOperationResult
-caja_share_update_file_info (CajaInfoProvider *provider,
- CajaFileInfo *file,
- GClosure *update_complete,
- CajaOperationHandle **handle)
-{
-/* gchar *share_status = NULL; */
-
- switch (file_get_share_status_file (file)) {
-
- case CAJA_SHARE_SHARED_RO:
- caja_file_info_add_emblem (file, "shared");
-/* share_status = _("shared (read only)"); */
- break;
-
- case CAJA_SHARE_SHARED_RW:
- caja_file_info_add_emblem (file, "shared");
-/* share_status = _("shared (read and write)"); */
- break;
-
- case CAJA_SHARE_NOT_SHARED:
-/* share_status = _("not shared"); */
- break;
-
- default:
- g_assert_not_reached ();
- break;
- }
-
-/* caja_file_info_add_string_attribute (file, */
-/* "CajaShare::share_status", */
-/* share_status); */
- return CAJA_OPERATION_COMPLETE;
-}
-
-
-static void
-caja_share_cancel_update (CajaInfoProvider *provider,
- CajaOperationHandle *handle)
-{
- CajaShareHandle *share_handle;
-
- share_handle = (CajaShareHandle*)handle;
- share_handle->cancelled = TRUE;
-}
-
-static void
-caja_share_info_provider_iface_init (CajaInfoProviderIface *iface)
-{
- iface->update_file_info = caja_share_update_file_info;
- iface->cancel_update = caja_share_cancel_update;
-}
-
-/*--------------------------------------------------------------------------*/
-/* caja_property_page_provider_get_pages
- *
- * This function is called by Caja when it wants property page
- * items from the extension.
- *
- * This function is called in the main thread before a property page
- * is shown, so it should return quickly.
- *
- * The function should return a GList of allocated CajaPropertyPage
- * items.
- */
-static GList *
-caja_share_get_property_pages (CajaPropertyPageProvider *provider,
- GList *files)
-{
- PropertyPage *page;
- GList *pages;
- CajaPropertyPage *np_page;
- CajaFileInfo *fileinfo;
- ShareInfo *share_info;
- gboolean is_shareable;
-
- /* Only show the property page if 1 file is selected */
- if (!files || files->next != NULL) {
- return NULL;
- }
-
- fileinfo = CAJA_FILE_INFO (files->data);
-
- get_share_info_for_file_info (fileinfo, &share_info, &is_shareable);
- if (!is_shareable)
- return NULL;
-
- page = create_property_page (fileinfo);
- gtk_widget_hide (page->button_cancel);
-
- if (share_info)
- shares_free_share_info (share_info);
-
- pages = NULL;
- np_page = caja_property_page_new
- ("CajaShare::property_page",
- gtk_label_new (_("Share")),
- page->main);
- pages = g_list_append (pages, np_page);
-
- return pages;
-}
-
-/*--------------------------------------------------------------------------*/
-static void
-caja_share_property_page_provider_iface_init (CajaPropertyPageProviderIface *iface)
-{
- iface->get_pages = caja_share_get_property_pages;
-}
-
-/*--------------------------------------------------------------------------*/
-static void
-caja_share_instance_init (CajaShare *share)
-{
-}
-
-/*--------------------------------------------------------------------------*/
-static void
-caja_share_class_init (CajaShareClass *class)
-{
- parent_class = g_type_class_peek_parent (class);
-}
-
-/* caja_menu_provider_get_file_items
- *
- * This function is called by Caja when it wants context menu
- * items from the extension.
- *
- * This function is called in the main thread before a context menu
- * is shown, so it should return quickly.
- *
- * The function should return a GList of allocated CajaMenuItem
- * items.
- */
-
-static void
-button_cancel_clicked_cb (GtkButton *button, gpointer data)
-{
- GtkWidget *window;
-
- window = GTK_WIDGET (data);
- gtk_widget_destroy (window);
-}
-
-static void
-share_this_folder_callback (CajaMenuItem *item,
- gpointer user_data)
-{
- CajaFileInfo *fileinfo;
- PropertyPage *page;
- GtkWidget * window;
-
- fileinfo = CAJA_FILE_INFO (user_data);
- g_assert (fileinfo != NULL);
-
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_window_set_title (GTK_WINDOW (window), _("Folder Sharing"));
- page = create_property_page (fileinfo);
- page->standalone_window = window;
- g_signal_connect (page->button_cancel, "clicked",
- G_CALLBACK (button_cancel_clicked_cb), window);
-
- gtk_container_add (GTK_CONTAINER (window), page->main);
- gtk_widget_show (window);
-}
-
-static GList *
-caja_share_get_file_items (CajaMenuProvider *provider,
- GtkWidget *window,
- GList *files)
-{
- GList *items;
- CajaMenuItem *item;
- CajaFileInfo *fileinfo;
- ShareInfo *share_info;
- gboolean is_shareable;
-
- /* Only show the property page if 1 file is selected */
- if (!files || files->next != NULL) {
- return NULL;
- }
-
- fileinfo = CAJA_FILE_INFO (files->data);
-
- get_share_info_for_file_info (fileinfo, &share_info, &is_shareable);
-
- if (!is_shareable)
- return NULL;
-
- if (share_info)
- shares_free_share_info (share_info);
-
- /* We don't own a reference to the file info to keep it around, so acquire one */
- g_object_ref (fileinfo);
-
- /* FMQ: change the label to "Share with Windows users"? */
- item = caja_menu_item_new ("CajaShare::share",
- _("Sharing Options"),
- _("Share this Folder"),
- "folder-remote");
- g_signal_connect (item, "activate",
- G_CALLBACK (share_this_folder_callback),
- fileinfo);
- g_object_set_data_full (G_OBJECT (item),
- "files",
- fileinfo,
- g_object_unref); /* Release our reference when the menu item goes away */
-
- items = g_list_append (NULL, item);
- return items;
-}
-
-/*--------------------------------------------------------------------------*/
-static void
-caja_share_menu_provider_iface_init (CajaMenuProviderIface *iface)
-{
- iface->get_file_items = caja_share_get_file_items;
-}
-
-/*--------------------------------------------------------------------------*/
-/* Type registration. Because this type is implemented in a module
- * that can be unloaded, we separate type registration from get_type().
- * the type_register() function will be called by the module's
- * initialization function. */
-static GType share_type = 0;
-
-#define CAJA_TYPE_SHARE (caja_share_get_type ())
-
-static GType
-caja_share_get_type (void)
-{
- return share_type;
-}
-
-static void
-caja_share_register_type (GTypeModule *module)
-{
- static const GTypeInfo info = {
- sizeof (CajaShareClass),
- (GBaseInitFunc) NULL,
- (GBaseFinalizeFunc) NULL,
- (GClassInitFunc) caja_share_class_init,
- NULL,
- NULL,
- sizeof (CajaShare),
- 0,
- (GInstanceInitFunc) caja_share_instance_init,
- };
-
- share_type = g_type_module_register_type (module,
- G_TYPE_OBJECT,
- "CajaShare",
- &info, 0);
-
- /* onglet share propri�t� */
- static const GInterfaceInfo property_page_provider_iface_info = {
- (GInterfaceInitFunc) caja_share_property_page_provider_iface_init,
- NULL,
- NULL
- };
-
- g_type_module_add_interface (module,
- share_type,
- CAJA_TYPE_PROPERTY_PAGE_PROVIDER,
- &property_page_provider_iface_info);
-
-
- /* premier page propri�t� ? */
- static const GInterfaceInfo info_provider_iface_info = {
- (GInterfaceInitFunc) caja_share_info_provider_iface_init,
- NULL,
- NULL
- };
-
- g_type_module_add_interface (module,
- share_type,
- CAJA_TYPE_INFO_PROVIDER,
- &info_provider_iface_info);
-
- /* Menu right clik */
- static const GInterfaceInfo menu_provider_iface_info = {
- (GInterfaceInitFunc) caja_share_menu_provider_iface_init,
- NULL,
- NULL
- };
-
- g_type_module_add_interface (module,
- share_type,
- CAJA_TYPE_MENU_PROVIDER,
- &menu_provider_iface_info);
-
-}
-
-/* Extension module functions. These functions are defined in
- * caja-extensions-types.h, and must be implemented by all
- * extensions. */
-
-/* Initialization function. In addition to any module-specific
- * initialization, any types implemented by the module should
- * be registered here. */
-void
-caja_module_initialize (GTypeModule *module)
-{
- /*g_print ("Initializing mate-file-manager-share extension\n");*/
-
- bindtextdomain("mate-file-manager-share", CAJA_SHARE_LOCALEDIR);
- bind_textdomain_codeset("mate-file-manager-share", "UTF-8");
-
- caja_share_register_type (module);
-}
-
-/* Perform module-specific shutdown. */
-void
-caja_module_shutdown (void)
-{
- /*g_print ("Shutting down mate-file-manager-share extension\n");*/
- /* FIXME freeing */
-}
-
-/* List all the extension types. */
-void
-caja_module_list_types (const GType **types,
- int *num_types)
-{
- static GType type_list[1];
-
- type_list[0] = CAJA_TYPE_SHARE;
-
- *types = type_list;
- *num_types = 1;
-}