summaryrefslogtreecommitdiff
path: root/src/file-manager/fm-annotation-window.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/file-manager/fm-annotation-window.c')
-rw-r--r--src/file-manager/fm-annotation-window.c400
1 files changed, 400 insertions, 0 deletions
diff --git a/src/file-manager/fm-annotation-window.c b/src/file-manager/fm-annotation-window.c
new file mode 100644
index 000000000..022cbb0c4
--- /dev/null
+++ b/src/file-manager/fm-annotation-window.c
@@ -0,0 +1,400 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+
+/* fm-annotation-window.c - window that lets user modify file annotations
+
+ Copyright (C) 2001 Eazel, Inc.
+
+ The Gnome Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Authors: Andy Hertzfeld <andy@eazel.com>
+*/
+
+#include <config.h>
+#include "fm-annotation-window.h"
+
+#include "fm-error-reporting.h"
+#include <gtk/gtkfilesel.h>
+#include <gtk/gtkhbox.h>
+#include <gtk/gtkhseparator.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtknotebook.h>
+#include <gtk/gtkoptionmenu.h>
+#include <gtk/gtkpixmap.h>
+#include <gtk/gtkscrolledwindow.h>
+#include <gtk/gtksignal.h>
+#include <gtk/gtktable.h>
+#include <gtk/gtktext.h>
+#include <gtk/gtkvbox.h>
+#include <libgnome/gnome-defs.h>
+#include <libgnome/gnome-i18n.h>
+#include <libgnomeui/gnome-dialog.h>
+#include <libgnomeui/gnome-uidefs.h>
+#include <libgnomevfs/gnome-vfs.h>
+#include <libnautilus-extensions/nautilus-annotation.h>
+#include <libnautilus-extensions/nautilus-customization-data.h>
+#include <eel/eel-ellipsizing-label.h>
+#include <libnautilus-extensions/nautilus-entry.h>
+#include <libnautilus-extensions/nautilus-file-attributes.h>
+#include <libnautilus-extensions/nautilus-file-utilities.h>
+#include <libnautilus-extensions/nautilus-font-factory.h>
+#include <eel/eel-gdk-pixbuf-extensions.h>
+#include <eel/eel-glib-extensions.h>
+#include <libnautilus-extensions/nautilus-global-preferences.h>
+#include <eel/eel-gnome-extensions.h>
+#include <eel/eel-gtk-extensions.h>
+#include <eel/eel-gtk-macros.h>
+#include <libnautilus-extensions/nautilus-icon-factory.h>
+#include <eel/eel-image.h>
+#include <libnautilus-extensions/nautilus-link.h>
+#include <libnautilus-extensions/nautilus-metadata.h>
+#include <eel/eel-stock-dialogs.h>
+#include <eel/eel-string.h>
+#include <libnautilus-extensions/nautilus-undo-signal-handlers.h>
+#include <libnautilus/nautilus-undo.h>
+#include <eel/eel-wrap-table.h>
+#include <eel/eel-labeled-image.h>
+#include <eel/eel-viewport.h>
+#include <string.h>
+
+struct FMAnnotationWindowDetails {
+ NautilusFile *file;
+ GtkWidget *file_icon;
+ GtkLabel *file_title;
+ GtkWidget *text_field;
+ char *access_mode;
+};
+
+
+static void real_destroy (GtkObject *object);
+static void fm_annotation_window_initialize_class (FMAnnotationWindowClass *class);
+static void fm_annotation_window_initialize (FMAnnotationWindow *window);
+static FMAnnotationWindow* create_annotation_window
+ (NautilusFile *file,
+ FMDirectoryView *directroy_view);
+
+EEL_DEFINE_CLASS_BOILERPLATE (FMAnnotationWindow, fm_annotation_window, GNOME_TYPE_DIALOG)
+
+static void
+fm_annotation_window_initialize_class (FMAnnotationWindowClass *class)
+{
+ GtkObjectClass *object_class;
+
+ object_class = GTK_OBJECT_CLASS (class);
+ object_class->destroy = real_destroy;
+}
+
+static void
+fm_annotation_window_initialize (FMAnnotationWindow *window)
+{
+ window->details = g_new0 (FMAnnotationWindowDetails, 1);
+ window->details->file = NULL;
+
+ /* default to local access only */
+ window->details->access_mode = g_strdup ("local");
+}
+
+static void
+real_destroy (GtkObject *object)
+{
+ FMAnnotationWindow *window;
+
+ window = FM_ANNOTATION_WINDOW (object);
+
+ nautilus_file_unref (window->details->file);
+
+ g_free (window->details->access_mode);
+ g_free (window->details);
+
+ EEL_CALL_PARENT (GTK_OBJECT_CLASS, destroy, (object));
+}
+
+static GdkPixbuf *
+get_pixbuf_for_annotation_window (NautilusFile *file)
+{
+ g_assert (NAUTILUS_IS_FILE (file));
+
+ return nautilus_icon_factory_get_pixbuf_for_file (file, NULL, NAUTILUS_ICON_SIZE_LARGE, TRUE);
+}
+
+
+static void
+update_annotation_window_icon (EelImage *image)
+{
+ GdkPixbuf *pixbuf;
+ NautilusFile *file;
+
+ g_assert (EEL_IS_IMAGE (image));
+
+ file = gtk_object_get_data (GTK_OBJECT (image), "nautilus_file");
+
+ g_assert (NAUTILUS_IS_FILE (file));
+
+ pixbuf = get_pixbuf_for_annotation_window (file);
+
+ eel_image_set_pixbuf (image, pixbuf);
+
+ gdk_pixbuf_unref (pixbuf);
+}
+
+static GtkWidget *
+create_image_widget_for_file (NautilusFile *file)
+{
+ GtkWidget *image;
+ GdkPixbuf *pixbuf;
+
+ pixbuf = get_pixbuf_for_annotation_window (file);
+
+ image = eel_image_new (NULL);
+
+ eel_image_set_pixbuf (EEL_IMAGE (image), pixbuf);
+
+ gdk_pixbuf_unref (pixbuf);
+
+ nautilus_file_ref (file);
+ gtk_object_set_data_full (GTK_OBJECT (image),
+ "nautilus_file",
+ file,
+ (GtkDestroyNotify) nautilus_file_unref);
+
+ gtk_signal_connect_object_while_alive (nautilus_icon_factory_get (),
+ "icons_changed",
+ update_annotation_window_icon,
+ GTK_OBJECT (image));
+
+ gtk_signal_connect_object_while_alive (GTK_OBJECT (file),
+ "changed",
+ update_annotation_window_icon,
+ GTK_OBJECT (image));
+ return image;
+}
+
+
+static void
+update_annotation_window_title (GtkWindow *window, NautilusFile *file)
+{
+ char *name, *title;
+
+ g_assert (NAUTILUS_IS_FILE (file));
+ g_assert (GTK_IS_WINDOW (window));
+
+ name = nautilus_file_get_name (file);
+ title = g_strdup_printf (_("%s Annotation"), name);
+ gtk_window_set_title (window, title);
+
+ g_free (name);
+ g_free (title);
+}
+
+/* callback for access menu items */
+static void
+set_access_mode (GtkWidget *menu_item, const char* access_mode)
+{
+ FMAnnotationWindow *window;
+ window = FM_ANNOTATION_WINDOW (gtk_object_get_user_data (GTK_OBJECT (menu_item)));
+ g_free (window->details->access_mode);
+ window->details->access_mode = g_strdup (access_mode);
+}
+
+/* utility to create and append an access menu item */
+static void
+add_access_menu_item (FMAnnotationWindow *window, GtkWidget *access_menu, const char *menu_label, const char *id)
+{
+ GtkWidget *menu_item;
+
+ menu_item = gtk_menu_item_new_with_label (menu_label);
+ gtk_widget_show (menu_item);
+ gtk_menu_append (GTK_MENU (access_menu), menu_item);
+
+ gtk_object_set_user_data (GTK_OBJECT (menu_item), window);
+
+ gtk_signal_connect_full (GTK_OBJECT (menu_item),
+ "activate",
+ GTK_SIGNAL_FUNC (set_access_mode),
+ NULL,
+ g_strdup (id),
+ g_free,
+ FALSE,
+ FALSE);
+
+}
+
+/* create the option table for the annotation window */
+static GtkWidget *
+create_options_table (FMAnnotationWindow *window)
+{
+ GtkWidget *table;
+ GtkWidget *label;
+ GtkWidget *type_menu_vbox;
+ GtkWidget *access_menu_vbox;
+ GtkWidget *option_menu;
+ GtkWidget *new_menu;
+ GtkWidget *menu_item;
+
+ table = gtk_table_new (2, 2, FALSE);
+
+ label = gtk_label_new (_("Type:"));
+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 4, 4);
+
+ /* type options will eventually be derived from an xml file, but there's only one
+ * for now
+ */
+ type_menu_vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
+ option_menu = gtk_option_menu_new ();
+ gtk_box_pack_end (GTK_BOX (type_menu_vbox), option_menu, TRUE, FALSE, 0);
+ gtk_table_attach(GTK_TABLE(table), type_menu_vbox, 1, 2, 0, 1, GTK_FILL, GTK_FILL, 4, 4);
+
+ new_menu = gtk_menu_new ();
+ menu_item = gtk_menu_item_new_with_label (_("free form note"));
+ gtk_widget_show (new_menu);
+ gtk_widget_show (menu_item);
+ gtk_menu_append (GTK_MENU (new_menu), menu_item);
+ gtk_option_menu_set_menu (GTK_OPTION_MENU (option_menu), new_menu);
+
+ /* now make the access option menu */
+ label = gtk_label_new (_("Access:"));
+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 4, 4);
+
+ access_menu_vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
+ option_menu = gtk_option_menu_new ();
+ gtk_box_pack_end (GTK_BOX (access_menu_vbox), option_menu, TRUE, FALSE, 0);
+ gtk_table_attach(GTK_TABLE(table), access_menu_vbox, 1, 2, 1, 2, GTK_FILL, GTK_FILL, 4, 4);
+
+ new_menu = gtk_menu_new ();
+ gtk_widget_show (new_menu);
+
+ add_access_menu_item (window, new_menu, _("local only"), "local");
+ gtk_option_menu_set_menu (GTK_OPTION_MENU (option_menu), new_menu);
+
+ add_access_menu_item (window, new_menu, _("share globally"), "global");
+ return table;
+}
+
+/* this callback is invoked when the OK or Cancel buttons are clicked, to add an annotation and dismiss the window */
+static void
+annotation_clicked_callback (GtkWidget *dialog, int which_button, gpointer user_data)
+{
+ char *notes_text;
+ FMAnnotationWindow *window;
+
+ window = FM_ANNOTATION_WINDOW (dialog);
+
+ if (which_button == GNOME_OK) {
+ notes_text = gtk_editable_get_chars (GTK_EDITABLE (window->details->text_field), 0 , -1);
+ /* type field is hard-wired for now */
+ nautilus_annotation_add_annotation (window->details->file,
+ "text",
+ notes_text,
+ window->details->access_mode);
+ g_free (notes_text);
+ }
+ gtk_widget_destroy (dialog);
+}
+
+/* create the annotation window, and allocate its widgets */
+static FMAnnotationWindow *
+create_annotation_window (NautilusFile *file, FMDirectoryView *directory_view)
+{
+ FMAnnotationWindow *window;
+ GtkWidget *hbox;
+ GtkBox *content_box;
+ GtkWidget *label;
+ GtkWidget *table;
+ char *file_name, *title;
+ GdkFont *font;
+ int position;
+ char *annotation_text;
+
+ window = FM_ANNOTATION_WINDOW (gtk_widget_new (fm_annotation_window_get_type (), NULL));
+
+ window->details->file = nautilus_file_ref (file);
+
+ gtk_container_set_border_width (GTK_CONTAINER (window), GNOME_PAD);
+ gtk_window_set_policy (GTK_WINDOW (window), FALSE, TRUE, FALSE);
+ gtk_window_set_wmclass (GTK_WINDOW (window), "file_annotation", "Nautilus");
+
+ /* add the buttons */
+ gnome_dialog_append_buttons (GNOME_DIALOG (window), GNOME_STOCK_BUTTON_OK, GNOME_STOCK_BUTTON_CANCEL, NULL);
+ gnome_dialog_set_default( GNOME_DIALOG (window), GNOME_OK);
+
+ gtk_signal_connect (GTK_OBJECT (window), "clicked", (GtkSignalFunc) annotation_clicked_callback, NULL);
+
+ /* get the container box of the dialog */
+ content_box = GTK_BOX (GNOME_DIALOG (window)->vbox);
+
+ /* allocate an hbox to hold the icon and the title */
+ hbox = gtk_hbox_new (FALSE, GNOME_PAD);
+ gtk_box_pack_start (GTK_BOX (content_box), hbox, FALSE, FALSE, GNOME_PAD);
+
+ /* allocate an icon and title */
+ window->details->file_icon = create_image_widget_for_file (window->details->file);
+ gtk_box_pack_start (GTK_BOX (hbox), window->details->file_icon, FALSE, FALSE, GNOME_PAD);
+
+ file_name = nautilus_file_get_name (window->details->file);
+ title = g_strdup_printf (_("Add Annotation to %s"), file_name);
+ label = gtk_label_new (title);
+ gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, GNOME_PAD);
+ g_free (file_name);
+ g_free (title);
+
+ /* now allocate a table to hold and populate the option boxes */
+ table = create_options_table (window);
+ gtk_box_pack_start (GTK_BOX (content_box), table, FALSE, FALSE, GNOME_PAD);
+
+ /* add the views as defined by the currently selected type */
+ /* at first, there is only one hardwired type, so just add it here */
+ window->details->text_field = gtk_text_new (NULL, NULL);
+
+ font = nautilus_font_factory_get_font_from_preferences (14);
+ eel_gtk_widget_set_font (window->details->text_field, font);
+ gdk_font_unref (font);
+
+ gtk_text_set_editable (GTK_TEXT (window->details->text_field), TRUE);
+ gtk_box_pack_start (GTK_BOX (content_box), window->details->text_field, TRUE, TRUE, 0);
+
+ /* set up the annotation field with the initial text, if any */
+ annotation_text = nautilus_annotation_get_annotation_for_display (window->details->file);
+ position = 0;
+ if (annotation_text) {
+ gtk_editable_insert_text (GTK_EDITABLE (window->details->text_field),
+ annotation_text,
+ strlen (annotation_text),
+ &position);
+
+ g_free (annotation_text);
+ }
+
+ update_annotation_window_title (GTK_WINDOW (window), window->details->file);
+
+ gtk_widget_show_all (GTK_WIDGET (window));
+ return window;
+}
+
+void
+fm_annotation_window_present (NautilusFile *file, FMDirectoryView *directory_view)
+{
+ g_return_if_fail (NAUTILUS_IS_FILE (file));
+ g_return_if_fail (FM_IS_DIRECTORY_VIEW (directory_view));
+
+ if (nautilus_file_is_directory (file)) {
+ eel_show_error_dialog (_("Sorry, but you currently can't add an annotation to a directory."), _("Can't annotate directory"), NULL);
+ return;
+ }
+
+ create_annotation_window (file, directory_view);
+}
+