summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Hertzfeld <andy@src.gnome.org>2001-01-03 00:45:34 +0000
committerAndy Hertzfeld <andy@src.gnome.org>2001-01-03 00:45:34 +0000
commit82473e05df72f68affb44c951b18a82257139c11 (patch)
tree6db160fa93945dd00140c9bb70907a8ed657869e
parent0f3e5e583e6b8ebc1e981955d7e2ea63659a144e (diff)
downloadnautilus-82473e05df72f68affb44c951b18a82257139c11.tar.gz
first check-in to post-1_0 branch.
first check-in to post-1_0 branch. add ability to embed Bonobo controls in the icon view. created a new bonobo control that fetches and displays rss weblogs plus miscellaneous optimizations and improvements * components/Makefile.am: * configure.in: added new rss-control component * components/hardware/nautilus-hardware-view.c: (get_RAM_description), (get_IDE_description): incorporated Bud's disk size calculation, plus tweaked the RAM size calculation * components/rss-control/.cvsignore: * components/rss-control/Makefile.am: * components/rss-control/nautilus-rss-control.oafinfo: files for the new rss-control component * components/rss-control/main.c: (rss_control_object_destroyed), (rss_control_make_object), (main): factory for the rss-control Bonobo component * components/rss-control/nautilus-rss-control.c,h: (nautilus_rss_control_initialize_class), (get_bonobo_properties), (set_bonobo_properties), (nautilus_rss_control_initialize), (nautilus_rss_control_clear_items), (nautilus_rss_control_destroy), (nautilus_rss_control_get_control), (nautilus_rss_control_set_title), (rss_logo_callback), (rss_read_done_callback), (load_rss_file), (nautilus_rss_control_set_uri), (draw_rss_logo_image), (draw_rss_title), (draw_blue_line), (draw_rss_items), (nautilus_rss_control_draw), (nautilus_rss_control_expose), (nautilus_rss_control_button_press_event): new bonobo control to fetch an rss file and display it. * icons/Makefile.am: * icons/bullet.png: added a "bullet" image used in rss control, but it's generally useful enough that I added it to the main icons * libnautilus-extensions/nautilus-file-utilities.c: (nautilus_get_user_main_directory): deleted some code that's no longer relevant * libnautilus-extensions/nautilus-icon-canvas-item.c,h: (nautilus_icon_canvas_item_destroy), (nautilus_icon_canvas_item_get_icon_width), (nautilus_icon_canvas_item_get_icon_height), (nautilus_icon_canvas_item_set_arg), (do_control_destroy), (nautilus_icon_canvas_item_get_arg), (nautilus_icon_canvas_item_get_image), (recompute_bounding_box), (nautilus_icon_canvas_item_update_bounds), (draw_or_measure_label_text), (emblem_layout_next), (draw_pixbuf_aa), (nautilus_icon_canvas_item_draw), (draw_or_measure_label_text_aa), (nautilus_icon_canvas_item_render), (nautilus_icon_canvas_item_bounds), (nautilus_icon_canvas_item_get_icon_rectangle), (get_icon_canvas_rectangle), (nautilus_icon_canvas_item_set_smooth_font), (nautilus_icon_canvas_item_get_control), (nautilus_icon_canvas_item_set_control): added support for widgets embedded in icon canvas items * libnautilus-extensions/nautilus-icon-container.c,h: (nautilus_icon_container_initialize_class), (nautilus_icon_container_update_icon): taught the icon container to ask for the control associated with a file, and configured the canvas item with it if there is one. * libnautilus-extensions/nautilus-icon-dnd.c: (nautilus_icon_dnd_begin_drag): made it unref the image it fetches from the canvas item, so the canvas item can generate custom images for controls. * libnautilus-extensions/nautilus-link.c,h: (nautilus_link_local_get_component_info): fetch the activation and configuration strings associated with a link file for string embedding. * libnautilus-extensions/nautilus-metadata.h: added metadata types for the activation and configuration data * src/file-manager/fm-icon-view.c: (get_icon_control_callback), (create_icon_container): added signal to create a bonobo control associated with a file and configure it, if there is one * src/nautilus-sidebar-tabs.c: (nautilus_sidebar_tabs_hit_test), (nautilus_sidebar_tabs_select_tab): hit test invisible tabs to support the change below. * src/nautilus-sidebar.c: (nautilus_sidebar_release_event): implemented Bud's idea of toggling the visibility of the active view by clicking on the tab again.
-rw-r--r--ChangeLog100
-rw-r--r--components/Makefile.am1
-rw-r--r--components/hardware/nautilus-hardware-view.c40
-rw-r--r--components/rss-control/.cvsignore5
-rw-r--r--components/rss-control/Makefile.am45
-rw-r--r--components/rss-control/main.c120
-rw-r--r--components/rss-control/nautilus-rss-control.c594
-rw-r--r--components/rss-control/nautilus-rss-control.h54
-rw-r--r--components/rss-control/nautilus-rss-control.oafinfo20
-rw-r--r--configure.in1
-rw-r--r--icons/Makefile.am1
-rw-r--r--icons/bullet.pngbin0 -> 853 bytes
-rw-r--r--libnautilus-extensions/nautilus-file-utilities.c17
-rw-r--r--libnautilus-extensions/nautilus-icon-canvas-item.c238
-rw-r--r--libnautilus-extensions/nautilus-icon-canvas-item.h4
-rw-r--r--libnautilus-extensions/nautilus-icon-container.c34
-rw-r--r--libnautilus-extensions/nautilus-icon-container.h4
-rw-r--r--libnautilus-extensions/nautilus-icon-dnd.c1
-rw-r--r--libnautilus-extensions/nautilus-link.c29
-rw-r--r--libnautilus-extensions/nautilus-link.h11
-rw-r--r--libnautilus-extensions/nautilus-metadata.h3
-rw-r--r--libnautilus-private/nautilus-file-utilities.c17
-rw-r--r--libnautilus-private/nautilus-icon-canvas-item.c238
-rw-r--r--libnautilus-private/nautilus-icon-canvas-item.h4
-rw-r--r--libnautilus-private/nautilus-icon-container.c34
-rw-r--r--libnautilus-private/nautilus-icon-container.h4
-rw-r--r--libnautilus-private/nautilus-icon-dnd.c1
-rw-r--r--libnautilus-private/nautilus-link.c29
-rw-r--r--libnautilus-private/nautilus-link.h11
-rw-r--r--libnautilus-private/nautilus-metadata.h3
-rw-r--r--src/file-manager/fm-icon-view.c38
-rw-r--r--src/nautilus-information-panel.c10
-rw-r--r--src/nautilus-sidebar-tabs.c8
-rw-r--r--src/nautilus-sidebar.c10
34 files changed, 1530 insertions, 199 deletions
diff --git a/ChangeLog b/ChangeLog
index 85b16a2da..908eaad6d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,103 @@
+2001-01-02 Andy Hertzfeld <andy@eazel.com>
+
+ first check-in to post-1_0 branch.
+
+ add ability to embed Bonobo controls in the icon view.
+ created a new bonobo control that fetches and displays rss weblogs
+ plus miscellaneous optimizations and improvements
+
+ * components/Makefile.am:
+ * configure.in:
+ added new rss-control component
+
+ * components/hardware/nautilus-hardware-view.c:
+ (get_RAM_description), (get_IDE_description):
+ incorporated Bud's disk size calculation, plus tweaked the
+ RAM size calculation
+
+ * components/rss-control/.cvsignore:
+ * components/rss-control/Makefile.am:
+ * components/rss-control/nautilus-rss-control.oafinfo:
+ files for the new rss-control component
+
+ * components/rss-control/main.c: (rss_control_object_destroyed),
+ (rss_control_make_object), (main):
+ factory for the rss-control Bonobo component
+
+ * components/rss-control/nautilus-rss-control.c,h:
+ (nautilus_rss_control_initialize_class), (get_bonobo_properties),
+ (set_bonobo_properties), (nautilus_rss_control_initialize),
+ (nautilus_rss_control_clear_items), (nautilus_rss_control_destroy),
+ (nautilus_rss_control_get_control),
+ (nautilus_rss_control_set_title), (rss_logo_callback),
+ (rss_read_done_callback), (load_rss_file),
+ (nautilus_rss_control_set_uri), (draw_rss_logo_image),
+ (draw_rss_title), (draw_blue_line), (draw_rss_items),
+ (nautilus_rss_control_draw), (nautilus_rss_control_expose),
+ (nautilus_rss_control_button_press_event):
+ new bonobo control to fetch an rss file and display it.
+
+ * icons/Makefile.am:
+ * icons/bullet.png:
+ added a "bullet" image used in rss control, but it's generally
+ useful enough that I added it to the main icons
+
+ * libnautilus-extensions/nautilus-file-utilities.c:
+ (nautilus_get_user_main_directory):
+ deleted some code that's no longer relevant
+
+ * libnautilus-extensions/nautilus-icon-canvas-item.c,h:
+ (nautilus_icon_canvas_item_destroy),
+ (nautilus_icon_canvas_item_get_icon_width),
+ (nautilus_icon_canvas_item_get_icon_height),
+ (nautilus_icon_canvas_item_set_arg), (do_control_destroy),
+ (nautilus_icon_canvas_item_get_arg),
+ (nautilus_icon_canvas_item_get_image), (recompute_bounding_box),
+ (nautilus_icon_canvas_item_update_bounds),
+ (draw_or_measure_label_text), (emblem_layout_next),
+ (draw_pixbuf_aa), (nautilus_icon_canvas_item_draw),
+ (draw_or_measure_label_text_aa),
+ (nautilus_icon_canvas_item_render),
+ (nautilus_icon_canvas_item_bounds),
+ (nautilus_icon_canvas_item_get_icon_rectangle),
+ (get_icon_canvas_rectangle),
+ (nautilus_icon_canvas_item_set_smooth_font),
+ (nautilus_icon_canvas_item_get_control),
+ (nautilus_icon_canvas_item_set_control):
+ added support for widgets embedded in icon canvas items
+
+ * libnautilus-extensions/nautilus-icon-container.c,h:
+ (nautilus_icon_container_initialize_class),
+ (nautilus_icon_container_update_icon):
+ taught the icon container to ask for the control associated
+ with a file, and configured the canvas item with it if there
+ is one.
+
+ * libnautilus-extensions/nautilus-icon-dnd.c:
+ (nautilus_icon_dnd_begin_drag):
+ made it unref the image it fetches from the canvas item, so the
+ canvas item can generate custom images for controls.
+
+ * libnautilus-extensions/nautilus-link.c,h:
+ (nautilus_link_local_get_component_info):
+ fetch the activation and configuration strings associated with
+ a link file for string embedding.
+
+ * libnautilus-extensions/nautilus-metadata.h:
+ added metadata types for the activation and configuration data
+
+ * src/file-manager/fm-icon-view.c: (get_icon_control_callback),
+ (create_icon_container):
+ added signal to create a bonobo control associated with a file
+ and configure it, if there is one
+
+ * src/nautilus-sidebar-tabs.c: (nautilus_sidebar_tabs_hit_test),
+ (nautilus_sidebar_tabs_select_tab):
+ hit test invisible tabs to support the change below.
+ * src/nautilus-sidebar.c: (nautilus_sidebar_release_event):
+ implemented Bud's idea of toggling the visibility of the active
+ view by clicking on the tab again.
+
2001-01-02 Darin Adler <darin@eazel.com>
reviewed by: John Sullivan <sullivan@eazel.com>
diff --git a/components/Makefile.am b/components/Makefile.am
index c26cb7f68..03ab50ca8 100644
--- a/components/Makefile.am
+++ b/components/Makefile.am
@@ -26,6 +26,7 @@ SUBDIRS = \
loser \
music \
notes \
+ rss-control \
sample \
text \
tree \
diff --git a/components/hardware/nautilus-hardware-view.c b/components/hardware/nautilus-hardware-view.c
index e08543f79..ecd93911d 100644
--- a/components/hardware/nautilus-hardware-view.c
+++ b/components/hardware/nautilus-hardware-view.c
@@ -258,6 +258,7 @@ get_RAM_description (void)
{
char *temp_str, *num_str, *result;
char* proc_data;
+ GnomeVFSFileSize ram_size;
proc_data = read_proc_info("meminfo");
@@ -270,8 +271,14 @@ get_RAM_description (void)
/* strip kbyte suffix */
temp_str[strlen(temp_str) - 3] = '\0';
- num_str = gnome_vfs_format_file_size_for_display (1024 * atol (temp_str));
- g_free (temp_str);
+ ram_size = (strtoul (temp_str, NULL, 10) + 500) / 1000;
+ if (ram_size > 1000) {
+ num_str = g_strdup_printf ("%Lu GB", ram_size / 1000);
+ } else {
+ num_str = g_strdup_printf ("%Lu MB", ram_size);
+ }
+
+ g_free (temp_str);
g_free (proc_data);
@@ -311,10 +318,31 @@ get_IDE_description (const char *device)
temp_str = read_proc_info(proc_file);
temp_str[strlen(temp_str) - 1] = '\0';
- /* This converts & calcs the sectors into MB's */
- capacity = strtoul (temp_str, NULL, 10);
- num_str = gnome_vfs_format_file_size_for_display (512 * capacity);
- g_string_append(string_data, "\n");
+ /* NOTE: this should be
+ * capacity = strtoul (...)
+ * num_str = gnome_vfs_format_file_size_for_display (512 * numsectors);
+ *
+ * (512 bytes per sector)
+ *
+ * but with large disks we overflow an unsigned long, which is the
+ * the type that gnome_vfs uses.
+ *
+ * ALSO, in keeping with disk manufacturer convention, disk sizes
+ * are quoted in powers of 10 (i.e., MB is 10^6, GB is 10^9).
+ * (see http://www.maxtor.com/technology/Digi_vs_Deci.html
+ * So as to not confuse the user too much, we will follow the
+ * same convention.)
+ *
+ */
+
+ capacity = (512 * (strtoul (temp_str, NULL, 10) / 1000)) / 1000;
+ if (capacity > 1000) {
+ num_str = g_strdup_printf ("%Lu GB", capacity / 1000);
+ } else {
+ num_str = g_strdup_printf ("%Lu MB", capacity);
+ }
+
+ g_string_append(string_data, "\n");
g_string_append(string_data, num_str);
g_free(temp_str);
g_free(proc_file);
diff --git a/components/rss-control/.cvsignore b/components/rss-control/.cvsignore
new file mode 100644
index 000000000..9eeb873c6
--- /dev/null
+++ b/components/rss-control/.cvsignore
@@ -0,0 +1,5 @@
+.deps
+.libs
+Makefile
+Makefile.in
+nautilus-rss-control
diff --git a/components/rss-control/Makefile.am b/components/rss-control/Makefile.am
new file mode 100644
index 000000000..99ae8d1f8
--- /dev/null
+++ b/components/rss-control/Makefile.am
@@ -0,0 +1,45 @@
+NULL =
+
+SUBDIRS =
+
+INCLUDES = \
+ -DPREFIX=\"$(prefix)\" \
+ -DG_LOG_DOMAIN=\"Nautilus-RSS-Control\" \
+ -DDATADIR=\""$(datadir)"\" \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ -I$(top_builddir)/libnautilus \
+ -DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
+ $(GNOMEUI_CFLAGS) \
+ $(GCONF_CFLAGS) \
+ $(OAF_CFLAGS) \
+ $(BONOBO_CFLAGS) \
+ $(VFS_CFLAGS)
+
+oafdir = $(datadir)/oaf
+oaf_DATA = \
+ nautilus-rss-control.oafinfo
+
+
+bin_PROGRAMS = \
+ nautilus-rss-control
+
+nautilus_rss_control_SOURCES = \
+ nautilus-rss-control.c \
+ nautilus-rss-control.h \
+ main.c
+
+nautilus_rss_control_LDADD = \
+ $(top_builddir)/libnautilus/libnautilus.la \
+ $(top_builddir)/libnautilus-extensions/libnautilus-extensions.la \
+ $(BONOBO_LIBS) \
+ $(GNOMEUI_LIBS) \
+ $(GCONF_LIBS) \
+ $(VFS_LIBS) \
+ $(GNORBA_LIBS)
+
+OBJECT_DIRECTORY_LIBS = $(GNOME_LIBS) $(OAF_LIBS)
+
+EXTRA_DIST = \
+ $(oaf_DATA) \
+ $(NULL)
diff --git a/components/rss-control/main.c b/components/rss-control/main.c
new file mode 100644
index 000000000..5af15140c
--- /dev/null
+++ b/components/rss-control/main.c
@@ -0,0 +1,120 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * Copyright (C) 2000 Eazel, Inc
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Andy Hertzfeld
+ */
+
+/* main.c - main function and object activation function for the rss control component. */
+
+#include <config.h>
+#include "nautilus-rss-control.h"
+
+#include <bonobo.h>
+#include <gnome.h>
+#include <libgnomevfs/gnome-vfs.h>
+#include <libnautilus-extensions/nautilus-debug.h>
+#include <liboaf/liboaf.h>
+
+static int object_count = 0;
+
+static void
+rss_control_object_destroyed(GtkObject *obj)
+{
+ object_count--;
+ if (object_count <= 0) {
+ gtk_main_quit ();
+ }
+}
+
+static BonoboObject *
+rss_control_make_object (BonoboGenericFactory *factory,
+ const char *iid,
+ void *closure)
+{
+ NautilusRSSControl *rss_control;
+ BonoboObject *bonobo_control;
+
+ if (strcmp (iid, "OAFIID:nautilus_rss_control:1230")) {
+ return NULL;
+ }
+
+ rss_control = NAUTILUS_RSS_CONTROL (gtk_object_new (NAUTILUS_TYPE_RSS_CONTROL, NULL));
+
+ object_count++;
+
+ bonobo_control = nautilus_rss_control_get_control (rss_control);
+
+ gtk_signal_connect (GTK_OBJECT (bonobo_control), "destroy", rss_control_object_destroyed, NULL);
+ return bonobo_control;
+}
+
+int
+main (int argc, char *argv[])
+{
+ BonoboGenericFactory *factory;
+ CORBA_ORB orb;
+ char *registration_id;
+
+ /* Make criticals and warnings stop in the debugger if
+ * NAUTILUS_DEBUG is set. Unfortunately, this has to be done
+ * explicitly for each domain.
+ */
+ if (g_getenv ("NAUTILUS_DEBUG") != NULL) {
+ nautilus_make_warnings_and_criticals_stop_in_debugger
+ (G_LOG_DOMAIN, g_log_domain_glib,
+ "Bonobo",
+ "Gdk",
+ "GnomeUI",
+ "GnomeVFS",
+ "GnomeVFS-CORBA",
+ "GnomeVFS-pthread",
+ "Gtk",
+ "GdkPixbuf",
+ "Nautilus",
+ "Nautilus-Authenticate",
+ "Nautilus-Tree",
+ "ORBit",
+ NULL);
+ }
+
+ gnome_init_with_popt_table("nautilus-rss-control", VERSION,
+ argc, argv,
+ oaf_popt_options, 0, NULL);
+
+ orb = oaf_init (argc, argv);
+
+ bonobo_init (orb, CORBA_OBJECT_NIL, CORBA_OBJECT_NIL);
+
+ /* initialize gnome-vfs, etc */
+ g_thread_init (NULL);
+ gnome_vfs_init ();
+
+ registration_id = oaf_make_registration_id ("OAFIID:nautilus_rss_control_factory:1230", getenv ("DISPLAY"));
+ factory = bonobo_generic_factory_new_multi (registration_id,
+ rss_control_make_object,
+ NULL);
+ g_free (registration_id);
+
+
+ do {
+ bonobo_main ();
+ } while (object_count > 0);
+
+ return 0;
+}
diff --git a/components/rss-control/nautilus-rss-control.c b/components/rss-control/nautilus-rss-control.c
new file mode 100644
index 000000000..c128589b1
--- /dev/null
+++ b/components/rss-control/nautilus-rss-control.c
@@ -0,0 +1,594 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+
+/*
+ * Copyright (C) 2000 Eazel, Inc.
+ *
+ * This library 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 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Author: Andy Hertzfeld <andy@eazel.com>
+ *
+ */
+
+/* this is the implementation of the rss control, which fetches an rss file through a uri, and
+ * displays it in the widget.
+ */
+
+#include <config.h>
+#include <gnome.h>
+#include <liboaf/liboaf.h>
+
+#include <bonobo.h>
+
+#include "nautilus-rss-control.h"
+#include <ghttp.h>
+
+#include <gnome-xml/parser.h>
+#include <gnome-xml/xmlmemory.h>
+
+#include <libgnomevfs/gnome-vfs.h>
+
+#include <libnautilus-extensions/nautilus-file-utilities.h>
+#include <libnautilus-extensions/nautilus-gdk-extensions.h>
+#include <libnautilus-extensions/nautilus-gdk-pixbuf-extensions.h>
+#include <libnautilus-extensions/nautilus-glib-extensions.h>
+#include <libnautilus-extensions/nautilus-gtk-extensions.h>
+#include <libnautilus-extensions/nautilus-gtk-macros.h>
+#include <libnautilus-extensions/nautilus-scalable-font.h>
+#include <libnautilus-extensions/nautilus-string.h>
+#include <libnautilus-extensions/nautilus-xml-extensions.h>
+#include <libnautilus-extensions/nautilus-font-factory.h>
+
+struct _NautilusRSSControlDetails {
+ char* rss_uri;
+ BonoboObject *control;
+ NautilusScalableFont *font;
+
+ char* title;
+ GdkPixbuf *logo;
+ GdkPixbuf *bullet;
+ GList *items;
+};
+
+
+static void nautilus_rss_control_initialize_class (NautilusRSSControlClass *klass);
+static void nautilus_rss_control_initialize (NautilusRSSControl *view);
+static void nautilus_rss_control_destroy (GtkObject *object);
+
+static void nautilus_rss_control_draw (GtkWidget *widget, GdkRectangle *box);
+static int nautilus_rss_control_expose (GtkWidget *widget, GdkEventExpose *event);
+static gboolean nautilus_rss_control_button_press_event (GtkWidget *widget, GdkEventButton *event);
+static void nautilus_rss_control_set_uri (NautilusRSSControl *rss_control, const char *uri);
+
+
+
+NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusRSSControl,
+ nautilus_rss_control,
+ GTK_TYPE_EVENT_BOX)
+
+
+static void
+nautilus_rss_control_initialize_class (NautilusRSSControlClass *klass)
+{
+ GtkObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+
+ object_class = GTK_OBJECT_CLASS (klass);
+ widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->destroy = nautilus_rss_control_destroy;
+
+ widget_class->draw = nautilus_rss_control_draw;
+ widget_class->expose_event = nautilus_rss_control_expose;
+ widget_class->button_press_event = nautilus_rss_control_button_press_event;
+}
+
+/* routines to handle setting and getting the configuration properties of the Bonobo control */
+
+enum {
+ PLACEHOLDER,
+ CONFIGURATION
+} MyArgs;
+
+
+static void
+get_bonobo_properties (BonoboPropertyBag *bag,
+ BonoboArg *arg,
+ guint arg_id,
+ gpointer user_data)
+{
+ NautilusRSSControl *rss_control = NAUTILUS_RSS_CONTROL (user_data);
+
+ switch (arg_id) {
+
+ case CONFIGURATION:
+ {
+ BONOBO_ARG_SET_STRING (arg, rss_control->details->rss_uri);
+ break;
+ }
+
+ default:
+ g_warning ("Unhandled arg %d", arg_id);
+ break;
+ }
+}
+
+static void
+set_bonobo_properties (BonoboPropertyBag *bag,
+ const BonoboArg *arg,
+ guint arg_id,
+ gpointer user_data)
+{
+ NautilusRSSControl *rss_control = NAUTILUS_RSS_CONTROL (user_data);
+
+ switch (arg_id) {
+
+ case CONFIGURATION:
+ {
+ char *uri;
+
+ uri = BONOBO_ARG_GET_STRING (arg);
+ nautilus_rss_control_set_uri (rss_control, uri);
+
+ break;
+ }
+
+ default:
+ g_warning ("Unhandled arg %d", arg_id);
+ break;
+ }
+}
+
+/* initialize ourselves by connecting to the location change signal and allocating our subviews */
+static void
+nautilus_rss_control_initialize (NautilusRSSControl *rss_control)
+{
+ GtkWidget *frame;
+ char *bullet_path;
+ BonoboPropertyBag *property_bag;
+
+ rss_control->details = g_new0 (NautilusRSSControlDetails, 1);
+
+ /* set up the font */
+ rss_control->details->font = NAUTILUS_SCALABLE_FONT (nautilus_scalable_font_new ("helvetica", "medium", NULL, NULL));
+
+ /* load the bullet used to display the items */
+ bullet_path = nautilus_pixmap_file ("bullet.png");
+ rss_control->details->bullet = gdk_pixbuf_new_from_file (bullet_path);
+ g_free (bullet_path);
+
+ /* make the bonobo control */
+ frame = gtk_frame_new (NULL);
+ gtk_frame_set_shadow_type(GTK_FRAME (frame), GTK_SHADOW_OUT);
+ gtk_widget_show (frame);
+ gtk_container_add (GTK_CONTAINER (frame), GTK_WIDGET (rss_control));
+
+ rss_control->details->control = (BonoboObject*) bonobo_control_new (GTK_WIDGET (frame));
+
+ /* attach a property bag with the configure property */
+ property_bag = bonobo_property_bag_new (get_bonobo_properties, set_bonobo_properties, rss_control);
+ bonobo_control_set_properties (BONOBO_CONTROL(rss_control->details->control), property_bag);
+
+ bonobo_property_bag_add (property_bag, "configuration", 1, BONOBO_ARG_STRING, NULL,
+ "RSS Configuration", 0);
+ bonobo_object_unref (BONOBO_OBJECT (property_bag));
+
+ /* show the view itself */
+ gtk_widget_show (GTK_WIDGET (rss_control));
+
+ /* set up the rss file (initially hardwired) */
+ /*
+ nautilus_rss_control_set_uri (rss_control, "http://www.slashdot.org/slashdot.rdf");
+ */
+}
+
+static void
+nautilus_rss_control_clear_items (NautilusRSSControl *rss_control)
+{
+ if (rss_control->details->items != NULL) {
+ nautilus_g_list_free_deep (rss_control->details->items);
+ rss_control->details->items = NULL;
+ }
+}
+
+static void
+nautilus_rss_control_destroy (GtkObject *object)
+{
+ NautilusRSSControl *rss_control;
+
+ rss_control = NAUTILUS_RSS_CONTROL (object);
+ g_free (rss_control->details->rss_uri);
+ g_free (rss_control->details->title);
+
+ if (rss_control->details->logo != NULL) {
+ gdk_pixbuf_unref (rss_control->details->logo);
+ }
+
+ if (rss_control->details->bullet != NULL) {
+ gdk_pixbuf_unref (rss_control->details->bullet);
+ }
+
+ if (rss_control->details->items != NULL) {
+ nautilus_rss_control_clear_items (rss_control);
+ }
+
+ if (rss_control->details->font) {
+ gtk_object_unref (GTK_OBJECT (rss_control->details->font));
+ }
+
+ g_free (rss_control->details);
+
+ NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object));
+}
+
+
+/* Component embedding support */
+BonoboObject *
+nautilus_rss_control_get_control (NautilusRSSControl *rss_control)
+{
+ return rss_control->details->control;
+}
+
+static void
+nautilus_rss_control_set_title (NautilusRSSControl *rss_control, const char *title)
+{
+ if (nautilus_strcmp (rss_control->details->title, title) == 0) {
+ return;
+ }
+
+ if (rss_control->details->title) {
+ g_free (rss_control->details->title);
+ }
+ if (title != NULL) {
+ rss_control->details->title = g_strdup (title);
+ } else {
+ rss_control->details->title = NULL;
+
+ }
+ gtk_widget_queue_draw (GTK_WIDGET (rss_control));
+}
+
+
+static void
+rss_logo_callback (GnomeVFSResult error, GdkPixbuf *pixbuf, gpointer callback_data)
+{
+ NautilusRSSControl *rss_control;
+
+ rss_control = NAUTILUS_RSS_CONTROL (callback_data);
+ if (rss_control->details->logo) {
+ gdk_pixbuf_unref (rss_control->details->logo);
+ }
+
+ if (pixbuf != NULL) {
+ gdk_pixbuf_ref (pixbuf);
+ rss_control->details->logo = pixbuf;
+ gtk_widget_queue_draw (GTK_WIDGET (rss_control));
+ }
+}
+
+/* completion routine invoked when we've loaded the rss file uri. Parse the xml document, and
+ * then extract the various elements that we require */
+
+static void
+rss_read_done_callback (GnomeVFSResult result,
+ GnomeVFSFileSize file_size,
+ char *file_contents,
+ gpointer callback_data)
+{
+ xmlDocPtr rss_document;
+ xmlNodePtr image_node, channel_node;
+ xmlNodePtr current_node, title_node, uri_node;
+ char *image_uri, *title;
+ NautilusRSSControl *rss_control;
+ NautilusPixbufLoadHandle *load_image_handle;
+
+ char *buffer;
+
+ /* make sure the read was successful */
+ if (result != GNOME_VFS_OK) {
+ g_assert (file_contents == NULL);
+ return;
+ }
+
+ rss_control = NAUTILUS_RSS_CONTROL (callback_data);
+
+ /* Parse the rss file with gnome-xml. The gnome-xml parser requires a zero-terminated array. */
+ buffer = g_realloc (file_contents, file_size + 1);
+ buffer[file_size] = '\0';
+ rss_document = xmlParseMemory (buffer, file_size);
+ g_free (buffer);
+
+ /* extract the title and set it */
+ channel_node = nautilus_xml_get_child_by_name (xmlDocGetRootElement (rss_document), "channel");
+ if (channel_node != NULL) {
+ title_node = nautilus_xml_get_child_by_name (channel_node, "title");
+ if (title_node != NULL) {
+ title = xmlNodeGetContent (title_node);
+ if (title != NULL) {
+ nautilus_rss_control_set_title (rss_control, title);
+ xmlFree (title);
+ }
+ }
+ }
+
+ /* extract the image uri and, if found, load it asynchronously */
+ image_node = nautilus_xml_get_child_by_name (xmlDocGetRootElement (rss_document), "image");
+ if (image_node != NULL) {
+ uri_node = nautilus_xml_get_child_by_name (image_node, "url");
+ if (uri_node != NULL) {
+ image_uri = xmlNodeGetContent (uri_node);
+ if (image_uri != NULL) {
+ load_image_handle = nautilus_gdk_pixbuf_load_async (image_uri, rss_logo_callback, rss_control);
+ xmlFree (image_uri);
+ }
+ }
+ }
+
+ /* extract the items in a loop */
+ nautilus_rss_control_clear_items (rss_control);
+ current_node = rss_document->root->childs;
+ while (current_node != NULL) {
+ if (nautilus_strcmp (current_node->name, "item") == 0) {
+ title_node = nautilus_xml_get_child_by_name (current_node, "title");
+ if (title_node) {
+ title = xmlNodeGetContent (title_node);
+ rss_control->details->items = g_list_append (rss_control->details->items, g_strdup (title));
+ xmlFree (title);
+ }
+ }
+ current_node = current_node->next;
+ }
+
+ /* we're done, so free everything up */
+ xmlFreeDoc (rss_document);
+
+ /* schedule a redraw to reflect the new contents */
+ gtk_widget_queue_draw (GTK_WIDGET (rss_control));
+}
+
+/* load the rs file asynchronously */
+static void
+load_rss_file (NautilusRSSControl *rss_control)
+{
+ char *title;
+ /* load the uri asynchrounously, calling a completion routine when completed */
+ nautilus_read_entire_file_async (rss_control->details->rss_uri, rss_read_done_callback, rss_control);
+
+ /* put up a title that's displayed while we wait */
+ title = g_strdup_printf ("Loading %s", rss_control->details->rss_uri);
+ nautilus_rss_control_set_title (rss_control, title);
+ g_free (title);
+}
+
+/* set the uri and load it */
+static void
+nautilus_rss_control_set_uri (NautilusRSSControl *rss_control, const char *uri)
+{
+
+ if (nautilus_strcmp (rss_control->details->rss_uri, uri) == 0) {
+ return;
+ }
+
+ if (rss_control->details->rss_uri != NULL) {
+ g_free (rss_control->details->rss_uri);
+ rss_control->details->rss_uri = NULL;
+ }
+
+ if (uri != NULL) {
+ rss_control->details->rss_uri = g_strdup (uri);
+ load_rss_file (rss_control);
+ }
+}
+
+
+
+/* draw the logo image */
+static int
+draw_rss_logo_image (NautilusRSSControl *rss_control, GdkPixbuf *pixbuf, int offset)
+{
+ GtkWidget *widget;
+ int logo_width, logo_height;
+ int v_offset;
+
+ widget = GTK_WIDGET (rss_control);
+ v_offset = offset;
+
+ if (rss_control->details->logo != NULL) {
+ logo_width = gdk_pixbuf_get_width (rss_control->details->logo);
+ logo_height = gdk_pixbuf_get_height (rss_control->details->logo);
+
+ gdk_pixbuf_composite (rss_control->details->logo, pixbuf, 2, v_offset, logo_width, logo_height,
+ 2, v_offset, 1.0, 1.0, GDK_PIXBUF_ALPHA_BILEVEL, 255);
+ v_offset += logo_height + 2;
+ }
+
+ return v_offset;
+}
+
+/* draw the title */
+static int
+draw_rss_title (NautilusRSSControl *rss_control, GdkPixbuf *pixbuf, int v_offset)
+{
+ int title_width, title_height;
+ GtkWidget *widget;
+
+ if (rss_control->details->title == NULL || rss_control->details->font == NULL) {
+ return v_offset;
+ }
+
+ widget = GTK_WIDGET (rss_control);
+
+ /* first, measure the text */
+ nautilus_scalable_font_measure_text (rss_control->details->font,
+ 18, 18,
+ rss_control->details->title, strlen (rss_control->details->title),
+ &title_width,
+ &title_height);
+
+ /* draw the name into the pixbuf using anti-aliased text */
+ nautilus_scalable_font_draw_text (rss_control->details->font, pixbuf,
+ 4, v_offset,
+ NULL,
+ 18, 18,
+ rss_control->details->title, strlen (rss_control->details->title),
+ NAUTILUS_RGB_COLOR_BLACK,
+ NAUTILUS_OPACITY_NONE);
+
+ return v_offset + title_height;
+}
+
+/* utility for underlining an item - assumes the pixbuf has an alpha channel */
+static void
+draw_blue_line (GdkPixbuf *pixbuf, int x, int y, int width)
+{
+ guchar *pixels_ptr;
+ int row_stride, line_width, pixbuf_width, i;
+
+ line_width = width;
+ pixbuf_width = gdk_pixbuf_get_width (pixbuf);
+ if ((x + line_width) > pixbuf_width) {
+ line_width = pixbuf_width - x - 1;
+ }
+ row_stride = gdk_pixbuf_get_rowstride (pixbuf);
+ pixels_ptr = gdk_pixbuf_get_pixels (pixbuf);
+
+ pixels_ptr += (4 * x) + (row_stride * y);
+ for (i = 0; i < line_width; i++) {
+ *pixels_ptr++ = 0;
+ *pixels_ptr++ = 0;
+ *pixels_ptr++ = 159;
+ *pixels_ptr++ = 255;
+
+ }
+}
+
+/* draw the items */
+static int
+draw_rss_items (NautilusRSSControl *rss_control, GdkPixbuf *pixbuf, int v_offset)
+{
+ GList *current_item;
+ int bullet_width, bullet_height;
+ int text_width, text_height, maximum_height;
+
+ maximum_height = GTK_WIDGET (rss_control)->allocation.height - 16;
+
+ if (rss_control->details->bullet) {
+ bullet_width = gdk_pixbuf_get_width (rss_control->details->bullet);
+ bullet_height = gdk_pixbuf_get_height (rss_control->details->bullet);
+ } else {
+ bullet_width = 0;
+ bullet_height = 0;
+ }
+
+ current_item = rss_control->details->items;
+
+ while (current_item != NULL) {
+ /* draw the text */
+
+ nautilus_scalable_font_measure_text (rss_control->details->font,
+ 12, 12,
+ current_item->data, strlen (current_item->data),
+ &text_width,
+ &text_height);
+
+ nautilus_scalable_font_draw_text (rss_control->details->font, pixbuf,
+ 20, v_offset,
+ NULL,
+ 12, 12,
+ current_item->data, strlen (current_item->data),
+ NAUTILUS_RGB_COLOR_BLACK,
+ NAUTILUS_OPACITY_NONE);
+
+ /* draw a blue underline to make it look like a link */
+ draw_blue_line (pixbuf, 20, v_offset + 11, text_width);
+
+ /* draw the bullet */
+ if (rss_control->details->bullet) {
+ gdk_pixbuf_composite (rss_control->details->bullet, pixbuf, 2, v_offset - 2, bullet_width, bullet_height,
+ 2, v_offset - 2, 1.0, 1.0, GDK_PIXBUF_ALPHA_BILEVEL, 192);
+ }
+
+ v_offset += 15;
+ current_item = current_item->next;
+ if (v_offset > maximum_height) {
+ break;
+ }
+
+ }
+
+ return v_offset;
+}
+
+/* handle drawing the control */
+static void
+nautilus_rss_control_draw (GtkWidget *widget, GdkRectangle *box)
+{
+ NautilusRSSControl *control;
+ GdkPixbuf *temp_pixbuf;
+ int width, height, v_offset;
+
+ /* allocate a pixbuf to draw into */
+ width = widget->allocation.width;
+ height = widget->allocation.height;
+
+ temp_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, width, height);
+ nautilus_gdk_pixbuf_fill_rectangle_with_color (temp_pixbuf, NULL, 0xFFEFEFEF);
+
+ g_return_if_fail (widget != NULL);
+ g_return_if_fail (NAUTILUS_IS_RSS_CONTROL (widget));
+
+ control = NAUTILUS_RSS_CONTROL (widget);
+
+ v_offset = draw_rss_logo_image (control, temp_pixbuf, 2);
+ v_offset = draw_rss_title (control, temp_pixbuf, v_offset);
+ v_offset += 6;
+ v_offset = draw_rss_items (control, temp_pixbuf, v_offset);
+
+ /* blit the pixbuf to the drawable, then release it */
+ gdk_pixbuf_render_to_drawable_alpha (temp_pixbuf,
+ widget->window,
+ 0, 0,
+ widget->allocation.x, widget->allocation.y,
+ width, height,
+ GDK_PIXBUF_ALPHA_BILEVEL, 128,
+ GDK_RGB_DITHER_MAX,
+ 0, 0);
+
+ gdk_pixbuf_unref (temp_pixbuf);
+}
+
+/* handle expose events */
+static int
+nautilus_rss_control_expose (GtkWidget *widget, GdkEventExpose *event)
+{
+ GdkRectangle box;
+ g_return_val_if_fail (widget != NULL, FALSE);
+ g_return_val_if_fail (NAUTILUS_IS_RSS_CONTROL (widget), FALSE);
+
+ box.x = 0; box.y = 0;
+ box.width = widget->allocation.width;
+ box.height = widget->allocation.height;
+
+ nautilus_rss_control_draw (widget, &box);
+ return FALSE;
+}
+
+/* handle button press events */
+static gboolean
+nautilus_rss_control_button_press_event (GtkWidget *widget, GdkEventButton *event)
+{
+ g_message ("button press");
+ return FALSE;
+}
+
diff --git a/components/rss-control/nautilus-rss-control.h b/components/rss-control/nautilus-rss-control.h
new file mode 100644
index 000000000..e73c31bbc
--- /dev/null
+++ b/components/rss-control/nautilus-rss-control.h
@@ -0,0 +1,54 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * Copyright (C) 2000 Eazel, Inc
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Andy Hertzfeld
+ */
+
+/* header file for the rss control component */
+
+#ifndef NAUTILUS_RSS_CONTROL_H
+#define NAUTILUS_RSS_CONTROL_H
+
+#include <bonobo.h>
+#include <gtk/gtkeventbox.h>
+typedef struct _NautilusRSSControl NautilusRSSControl;
+typedef struct _NautilusRSSControlClass NautilusRSSControlClass;
+
+#define NAUTILUS_TYPE_RSS_CONTROL (nautilus_rss_control_get_type ())
+#define NAUTILUS_RSS_CONTROL(obj) (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_RSS_CONTROL, NautilusRSSControl))
+#define NAUTILUS_RSS_CONTROL_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_RSS_CONTROL, NautilusRSSControlClass))
+#define NAUTILUS_IS_RSS_CONTROL(obj) (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_RSS_CONTROL))
+#define NAUTILUS_IS_RSS_CONTROL_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_RSS_CONTROL))
+
+typedef struct _NautilusRSSControlDetails NautilusRSSControlDetails;
+
+struct _NautilusRSSControl {
+ GtkEventBox parent;
+ NautilusRSSControlDetails *details;
+};
+
+struct _NautilusRSSControlClass {
+ GtkEventBoxClass parent_class;
+};
+
+/* GtkObject support */
+GtkType nautilus_rss_control_get_type (void);
+BonoboObject* nautilus_rss_control_get_control (NautilusRSSControl *rss_control);
+
+#endif /* NAUTILUS_RSS_CONTROL_H */
diff --git a/components/rss-control/nautilus-rss-control.oafinfo b/components/rss-control/nautilus-rss-control.oafinfo
new file mode 100644
index 000000000..9d21acf6a
--- /dev/null
+++ b/components/rss-control/nautilus-rss-control.oafinfo
@@ -0,0 +1,20 @@
+<oaf_info>
+
+<oaf_server iid="OAFIID:nautilus_rss_control_factory:1230" type="exe" location="nautilus-rss-control">
+<oaf_attribute name="repo_ids" type="stringv">
+<item value="IDL:Bonobo/GenericFactory:1.0"/>
+</oaf_attribute>
+<oaf_attribute name="name" type="string" value="rss control factory"/>
+<oaf_attribute name="description" type="string" value="rss control object factory"/>
+</oaf_server>
+
+<oaf_server iid="OAFIID:nautilus_rss_control:1230" type="factory" location="OAFIID:nautilus_rss_control_factory:1230">
+<oaf_attribute name="repo_ids" type="stringv">
+<item value="IDL:Bonobo/Control:1.0"/>
+<item value="IDL:Bonobo/Unknown:1.0"/>
+</oaf_attribute>
+<oaf_attribute name="name" type="string" value="rss control"/>
+<oaf_attribute name="description" type="string" value="nautilus rss control object"/>
+</oaf_server>
+
+</oaf_info>
diff --git a/configure.in b/configure.in
index b820f87fc..0a353e521 100644
--- a/configure.in
+++ b/configure.in
@@ -795,6 +795,7 @@ components/notes/Makefile
components/rpmview/Makefile
components/sample/Makefile
components/mozilla/Makefile
+components/rss-control/Makefile
components/services/Makefile
components/services/trilobite/Makefile
components/services/trilobite/idl/Makefile
diff --git a/icons/Makefile.am b/icons/Makefile.am
index 45e8f5579..ebf5909c0 100644
--- a/icons/Makefile.am
+++ b/icons/Makefile.am
@@ -11,6 +11,7 @@ icon_DATA =\
about_background.png \
audio.png \
backgrounds.png \
+ bullet.png \
chit_frame.png \
colors.png \
computer.png \
diff --git a/icons/bullet.png b/icons/bullet.png
new file mode 100644
index 000000000..b488acd55
--- /dev/null
+++ b/icons/bullet.png
Binary files differ
diff --git a/libnautilus-extensions/nautilus-file-utilities.c b/libnautilus-extensions/nautilus-file-utilities.c
index 2eb762eed..66f773338 100644
--- a/libnautilus-extensions/nautilus-file-utilities.c
+++ b/libnautilus-extensions/nautilus-file-utilities.c
@@ -614,22 +614,7 @@ nautilus_get_user_main_directory (void)
image_uri);
nautilus_file_unref (file);
}
-
- /* now do the same for the about file */
- temp_str = g_strdup_printf ("%s/About.html", user_main_directory);
- file_uri = gnome_vfs_get_uri_from_local_path (temp_str);
- g_free (temp_str);
-
- file = nautilus_file_get (file_uri);
- if (file != NULL) {
- nautilus_file_set_metadata (file,
- NAUTILUS_METADATA_KEY_CUSTOM_ICON,
- NULL,
- image_uri);
- nautilus_file_unref (file);
- }
- g_free (file_uri);
-
+
g_free (image_uri);
/* install the default link set */
diff --git a/libnautilus-extensions/nautilus-icon-canvas-item.c b/libnautilus-extensions/nautilus-icon-canvas-item.c
index d7c091785..ec61082aa 100644
--- a/libnautilus-extensions/nautilus-icon-canvas-item.c
+++ b/libnautilus-extensions/nautilus-icon-canvas-item.c
@@ -76,6 +76,10 @@ struct NautilusIconCanvasItemDetails {
GdkFont *font;
NautilusEmblemAttachPoints *attach_points;
+ /* stuff for controls; if this gets too big, we've put it in a separate struct */
+ GtkWidget *control; /* optional Bonobo control*/
+ guint control_destroy_id;
+
/* Size of the text at current font. */
int text_width;
int text_height;
@@ -89,7 +93,7 @@ struct NautilusIconCanvasItemDetails {
guint is_highlighted_for_drop : 1;
guint show_stretch_handles : 1;
guint is_prelit : 1;
-
+ guint in_control_destroy : 1;
gboolean is_renaming;
/* Font stuff whilst in smooth mode */
@@ -103,7 +107,7 @@ enum {
ARG_EDITABLE_TEXT,
ARG_ADDITIONAL_TEXT,
ARG_FONT,
- ARG_HIGHLIGHTED_FOR_SELECTION,
+ ARG_HIGHLIGHTED_FOR_SELECTION,
ARG_HIGHLIGHTED_AS_KEYBOARD_FOCUS,
ARG_HIGHLIGHTED_FOR_DROP,
ARG_MODIFIER,
@@ -318,6 +322,11 @@ nautilus_icon_canvas_item_destroy (GtkObject *object)
gdk_font_unref (details->font);
}
+ if (details->control && !details->in_control_destroy) {
+ gtk_signal_disconnect (GTK_OBJECT (details->control), details->control_destroy_id);
+ gtk_widget_destroy (details->control);
+ }
+
gtk_object_unref (GTK_OBJECT (icon_item->details->smooth_font));
icon_item->details->smooth_font = NULL;
@@ -351,6 +360,28 @@ invalidate_text_dimensions (NautilusIconCanvasItem *item)
item->details->text_height = -1;
}
+/* abstraction layer for icon width and height, to separate it from pixbuf with and height */
+static int
+nautilus_icon_canvas_item_get_icon_width (NautilusIconCanvasItem *item)
+{
+ if (item->details->pixbuf == NULL) {
+ return NAUTILUS_ICON_SIZE_STANDARD;
+ }
+
+ return gdk_pixbuf_get_width (item->details->pixbuf);
+}
+
+static int
+nautilus_icon_canvas_item_get_icon_height (NautilusIconCanvasItem *item)
+{
+ if (item->details->pixbuf == NULL) {
+ return NAUTILUS_ICON_SIZE_STANDARD;
+ }
+
+ return gdk_pixbuf_get_height (item->details->pixbuf);
+}
+
+
/* Set_arg handler for the icon item. */
static void
nautilus_icon_canvas_item_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
@@ -433,8 +464,7 @@ nautilus_icon_canvas_item_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
case ARG_SMOOTH_FONT_SIZE:
nautilus_icon_canvas_item_set_smooth_font_size (NAUTILUS_ICON_CANVAS_ITEM (object),
GTK_VALUE_UINT (*arg));
- break;
-
+ break;
default:
g_warning ("nautilus_icons_view_item_item_set_arg on unknown argument");
return;
@@ -443,12 +473,27 @@ nautilus_icon_canvas_item_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (object));
}
+/* handler for the control's destroy signal */
+static void
+do_control_destroy (GtkObject *object, gpointer data)
+{
+ NautilusIconCanvasItemDetails *details;
+
+ details = NAUTILUS_ICON_CANVAS_ITEM (data)->details;
+
+ details->in_control_destroy = TRUE;
+
+ gtk_object_destroy (GTK_OBJECT (data));
+}
+
/* Get_arg handler for the icon item */
static void
nautilus_icon_canvas_item_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
{
NautilusIconCanvasItemDetails *details;
+ GnomeCanvasItem *item;
+ item = GNOME_CANVAS_ITEM (object);
details = NAUTILUS_ICON_CANVAS_ITEM (object)->details;
switch (arg_id) {
@@ -496,12 +541,27 @@ GdkPixbuf *
nautilus_icon_canvas_item_get_image (NautilusIconCanvasItem *item)
{
NautilusIconCanvasItemDetails *details;
-
+ int width, height;
+ GdkPixbuf *pixbuf;
+
g_return_val_if_fail (NAUTILUS_IS_ICON_CANVAS_ITEM (item), NULL);
details = item->details;
- return details->pixbuf;
+ if (details->control) {
+ width = details->control->allocation.width;
+ height = details->control->allocation.height;
+ pixbuf = nautilus_gdk_pixbuf_get_from_window_safe (details->control->window,
+ details->control->allocation.x,
+ details->control->allocation.y,
+ details->control->allocation.width,
+ details->control->allocation.height);
+ } else {
+ pixbuf = details->pixbuf;
+ gdk_pixbuf_ref (pixbuf);
+ }
+
+ return pixbuf;
}
void
@@ -603,6 +663,12 @@ recompute_bounding_box (NautilusIconCanvasItem *icon_item)
item->y1 = top_left.y;
item->x2 = bottom_right.x;
item->y2 = bottom_right.y;
+
+ if (icon_item->details->control)
+ gtk_layout_move (GTK_LAYOUT (item->canvas), icon_item->details->control,
+ item->x1 + item->canvas->zoom_xofs,
+ item->y1 + item->canvas->zoom_yofs);
+
}
void
@@ -622,6 +688,16 @@ nautilus_icon_canvas_item_update_bounds (NautilusIconCanvasItem *item)
return;
}
+ /* if there is an embedded control, resize it appropriately */
+ if (item->details->control) {
+ /* for now, size it the same as the underlying image */
+ int image_width = nautilus_icon_canvas_item_get_icon_width (item);
+ int image_height = nautilus_icon_canvas_item_get_icon_height (item);
+
+ gtk_widget_set_usize (item->details->control,
+ image_width, image_height);
+ }
+
/* Send out the bounds_changed signal and queue a redraw. */
nautilus_gnome_canvas_request_redraw_rectangle
(GNOME_CANVAS_ITEM (item)->canvas, &before);
@@ -766,7 +842,7 @@ draw_or_measure_label_text (NautilusIconCanvasItem *item,
canvas_item = GNOME_CANVAS_ITEM (item);
if (drawable != NULL) {
- icon_width = details->pixbuf == NULL ? 0 : gdk_pixbuf_get_width (details->pixbuf);
+ icon_width = details->pixbuf == NULL ? 0 : nautilus_icon_canvas_item_get_icon_width (item);
gc = gdk_gc_new (canvas_item->canvas->layout.bin_window);
gdk_gc_get_values (gc, &save_gc);
}
@@ -1171,11 +1247,17 @@ emblem_layout_next (EmblemLayout *layout,
/* Return the rectangle and pixbuf. */
*emblem_pixbuf = pixbuf;
- emblem_rect->x0 = x - width / 2;
- emblem_rect->y0 = y - height / 2;
+ if (layout->icon_item->details->control) {
+ emblem_rect->x0 = x;
+ emblem_rect->y0 = y;
+ } else {
+ emblem_rect->x0 = x - width / 2;
+ emblem_rect->y0 = y - height / 2;
+ }
+
emblem_rect->x1 = emblem_rect->x0 + width;
emblem_rect->y1 = emblem_rect->y0 + height;
-
+
return TRUE;
}
@@ -1214,35 +1296,7 @@ draw_pixbuf (GdkPixbuf *pixbuf, GdkDrawable *drawable, int x, int y)
static void
draw_pixbuf_aa (GdkPixbuf *pixbuf, GnomeCanvasBuf *buf, double affine[6], int x_offset, int y_offset)
{
- void (* affine_function)
- (art_u8 *dst, int x0, int y0, int x1, int y1, int dst_rowstride,
- const art_u8 *src, int src_width, int src_height, int src_rowstride,
- const double affine[6],
- ArtFilterLevel level,
- ArtAlphaGamma *alpha_gamma);
-
- affine[4] += x_offset;
- affine[5] += y_offset;
-
- affine_function = gdk_pixbuf_get_has_alpha (pixbuf)
- ? art_rgb_rgba_affine
- : art_rgb_affine;
-
- (* affine_function)
- (buf->buf,
- buf->rect.x0, buf->rect.y0,
- buf->rect.x1, buf->rect.y1,
- buf->buf_rowstride,
- gdk_pixbuf_get_pixels (pixbuf),
- gdk_pixbuf_get_width (pixbuf),
- gdk_pixbuf_get_height (pixbuf),
- gdk_pixbuf_get_rowstride (pixbuf),
- affine,
- ART_FILTER_NEAREST,
- NULL);
-
- affine[4] -= x_offset;
- affine[5] -= y_offset;
+ nautilus_gnome_canvas_draw_pixbuf (buf, pixbuf, affine[4] + x_offset, affine[5] + y_offset);
}
/* shared code to highlight or dim the passed-in pixbuf */
@@ -1324,23 +1378,30 @@ nautilus_icon_canvas_item_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
icon_item = NAUTILUS_ICON_CANVAS_ITEM (item);
details = icon_item->details;
- /* Draw the pixbuf. */
- if (details->pixbuf == NULL) {
- return;
- }
- /* Compute icon rectangle in drawable coordinates. */
- get_icon_canvas_rectangle (icon_item, &icon_rect);
- icon_rect.x0 -= x;
- icon_rect.y0 -= y;
- icon_rect.x1 -= x;
- icon_rect.y1 -= y;
+ /* draw the icon or widget */
+ if (icon_item->details->control) {
+ gtk_widget_queue_draw (icon_item->details->control);
+ } else {
+ if (details->pixbuf != NULL) {
+
+ /* Compute icon rectangle in drawable coordinates. */
+ get_icon_canvas_rectangle (icon_item, &icon_rect);
+ icon_rect.x0 -= x;
+ icon_rect.y0 -= y;
+ icon_rect.x1 -= x;
+ icon_rect.y1 -= y;
+
+ /* if the pre-lit or selection flag is set, make a pre-lit or darkened pixbuf and draw that instead */
+ temp_pixbuf = map_pixbuf (icon_item);
+ draw_pixbuf (temp_pixbuf, drawable, icon_rect.x0, icon_rect.y0);
+
+ if (temp_pixbuf != details->pixbuf) {
+ gdk_pixbuf_unref (temp_pixbuf);
+ }
+
+ }
- /* if the pre-lit or selection flag is set, make a pre-lit or darkened pixbuf and draw that instead */
- temp_pixbuf = map_pixbuf (icon_item);
- draw_pixbuf (temp_pixbuf, drawable, icon_rect.x0, icon_rect.y0);
- if (temp_pixbuf != details->pixbuf) {
- gdk_pixbuf_unref (temp_pixbuf);
}
/* Draw the emblem pixbufs. */
@@ -1425,7 +1486,7 @@ draw_or_measure_label_text_aa (NautilusIconCanvasItem *item,
if (destination_pixbuf == NULL ) {
icon_width = 0;
} else {
- icon_width = details->pixbuf == NULL ? 0 : gdk_pixbuf_get_width (details->pixbuf);
+ icon_width = details->pixbuf == NULL ? 0 : nautilus_icon_canvas_item_get_icon_width (item);
}
max_text_width = floor (nautilus_icon_canvas_item_get_max_text_width (item));
@@ -1670,9 +1731,6 @@ nautilus_icon_canvas_item_render (GnomeCanvasItem *item, GnomeCanvasBuf *buf)
icon_item = NAUTILUS_ICON_CANVAS_ITEM (item);
- /* map the pixbuf for selection or other effects */
- temp_pixbuf = map_pixbuf (icon_item);
-
/* Compute the affine transform, but force the scale to 1.0
* because the icon factory does the scaling for us.
*/
@@ -1689,13 +1747,19 @@ nautilus_icon_canvas_item_render (GnomeCanvasItem *item, GnomeCanvasBuf *buf)
buf->is_bg = FALSE;
}
- /* draw the icon */
- draw_pixbuf_aa (temp_pixbuf, buf, i2c, 0, 0);
+ /* draw the icon or widget */
+ if (icon_item->details->control) {
+ gtk_widget_queue_draw (icon_item->details->control);
+ } else {
+ /* map the pixbuf for selection or other effects */
+ temp_pixbuf = map_pixbuf (icon_item);
+ draw_pixbuf_aa (temp_pixbuf, buf, i2c, 0, 0);
- if (temp_pixbuf != icon_item->details->pixbuf) {
- gdk_pixbuf_unref (temp_pixbuf);
+ if (temp_pixbuf != icon_item->details->pixbuf) {
+ gdk_pixbuf_unref (temp_pixbuf);
+ }
}
-
+
/* draw the emblems */
get_icon_canvas_rectangle (icon_item, &icon_rect);
@@ -1926,8 +1990,8 @@ nautilus_icon_canvas_item_bounds (GnomeCanvasItem *item,
icon_rect.x1 = 0;
icon_rect.y1 = 0;
} else {
- icon_rect.x1 = gdk_pixbuf_get_width (details->pixbuf);
- icon_rect.y1 = gdk_pixbuf_get_height (details->pixbuf);
+ icon_rect.x1 = nautilus_icon_canvas_item_get_icon_width (icon_item);
+ icon_rect.y1 = nautilus_icon_canvas_item_get_icon_height (icon_item);
}
/* Compute text rectangle. */
@@ -1973,8 +2037,8 @@ nautilus_icon_canvas_item_get_icon_rectangle (NautilusIconCanvasItem *item,
pixbuf = item->details->pixbuf;
pixels_per_unit = GNOME_CANVAS_ITEM (item)->canvas->pixels_per_unit;
- rect->x1 = rect->x0 + (pixbuf == NULL ? 0 : gdk_pixbuf_get_width (pixbuf)) / pixels_per_unit;
- rect->y1 = rect->y0 + (pixbuf == NULL ? 0 : gdk_pixbuf_get_height (pixbuf)) / pixels_per_unit;
+ rect->x1 = rect->x0 + (pixbuf == NULL ? 0 : nautilus_icon_canvas_item_get_icon_width (item)) / pixels_per_unit;
+ rect->y1 = rect->y0 + (pixbuf == NULL ? 0 : nautilus_icon_canvas_item_get_icon_height (item)) / pixels_per_unit;
}
/* Get the rectangle of the icon only, in canvas coordinates. */
@@ -2000,8 +2064,8 @@ get_icon_canvas_rectangle (NautilusIconCanvasItem *item,
pixbuf = item->details->pixbuf;
- rect->x1 = rect->x0 + (pixbuf == NULL ? 0 : gdk_pixbuf_get_width (pixbuf));
- rect->y1 = rect->y0 + (pixbuf == NULL ? 0 : gdk_pixbuf_get_height (pixbuf));
+ rect->x1 = rect->x0 + (pixbuf == NULL ? 0 : nautilus_icon_canvas_item_get_icon_width (item));
+ rect->y1 = rect->y0 + (pixbuf == NULL ? 0 : nautilus_icon_canvas_item_get_icon_height (item));
}
void
@@ -2158,6 +2222,42 @@ nautilus_icon_canvas_item_set_smooth_font (NautilusIconCanvasItem *icon_item,
}
}
+GtkWidget *
+nautilus_icon_canvas_item_get_control (NautilusIconCanvasItem *icon_item)
+{
+ return icon_item->details->control;
+}
+
+void
+nautilus_icon_canvas_item_set_control (NautilusIconCanvasItem *icon_item, GtkWidget *control)
+{
+ GnomeCanvasItem *item;
+
+ if (icon_item->details->control == control) {
+ return;
+ }
+
+ item = GNOME_CANVAS_ITEM (icon_item);
+ if (icon_item->details->control) {
+ gtk_signal_disconnect (GTK_OBJECT (icon_item->details->control), icon_item->details->control_destroy_id);
+ gtk_container_remove (GTK_CONTAINER (item->canvas), icon_item->details->control);
+ icon_item->details->control = NULL;
+ }
+
+ if (control) {
+ g_message ("adding control...");
+ icon_item->details->control = control;
+ icon_item->details->control_destroy_id = gtk_signal_connect (GTK_OBJECT (control),
+ "destroy",
+ (GtkSignalFunc) do_control_destroy,
+ item);
+ gtk_widget_show (control);
+ gtk_layout_put (GTK_LAYOUT (item->canvas), control,
+ item->x1 + item->canvas->zoom_xofs,
+ item->y1 + item->canvas->zoom_yofs);
+ }
+}
+
void
nautilus_icon_canvas_item_set_smooth_font_size (NautilusIconCanvasItem *icon_item,
guint font_size)
diff --git a/libnautilus-extensions/nautilus-icon-canvas-item.h b/libnautilus-extensions/nautilus-icon-canvas-item.h
index 8de5c8f23..c9d44375b 100644
--- a/libnautilus-extensions/nautilus-icon-canvas-item.h
+++ b/libnautilus-extensions/nautilus-icon-canvas-item.h
@@ -80,6 +80,10 @@ const char *nautilus_icon_canvas_item_get_editable_text (NautilusIconCanv
void nautilus_icon_canvas_item_set_renaming (NautilusIconCanvasItem *icon_item,
gboolean state);
+GtkWidget * nautilus_icon_canvas_item_get_control (NautilusIconCanvasItem *icon_item);
+void nautilus_icon_canvas_item_set_control (NautilusIconCanvasItem *icon_item,
+ GtkWidget *control);
+
/* geometry and hit testing */
gboolean nautilus_icon_canvas_item_hit_test_rectangle (NautilusIconCanvasItem *item,
diff --git a/libnautilus-extensions/nautilus-icon-container.c b/libnautilus-extensions/nautilus-icon-container.c
index c14dd664c..95e3852bf 100644
--- a/libnautilus-extensions/nautilus-icon-container.c
+++ b/libnautilus-extensions/nautilus-icon-container.c
@@ -160,6 +160,7 @@ enum {
CONTEXT_CLICK_SELECTION,
MIDDLE_CLICK,
GET_CONTAINER_URI,
+ GET_ICON_CONTROL,
GET_ICON_IMAGES,
GET_ICON_TEXT,
GET_ICON_URI,
@@ -2974,6 +2975,16 @@ nautilus_icon_container_initialize_class (NautilusIconContainerClass *class)
gtk_marshal_NONE__POINTER,
GTK_TYPE_NONE, 1,
GTK_TYPE_POINTER);
+ signals[GET_ICON_CONTROL]
+ = gtk_signal_new ("get_icon_control",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (NautilusIconContainerClass,
+ get_icon_control),
+ gtk_marshal_NONE__POINTER_POINTER,
+ GTK_TYPE_NONE, 2,
+ GTK_TYPE_POINTER,
+ GTK_TYPE_POINTER);
signals[GET_ICON_IMAGES]
= gtk_signal_new ("get_icon_images",
GTK_RUN_LAST,
@@ -3528,9 +3539,10 @@ nautilus_icon_container_update_icon (NautilusIconContainer *container,
GdkPixbuf *pixbuf, *emblem_pixbuf, *saved_pixbuf;
GList *emblem_scalable_icons, *emblem_pixbufs, *p;
char *editable_text, *additional_text;
+ GtkWidget *embedded_control;
GdkFont *font;
guint smooth_font_size;
-
+
if (icon == NULL) {
return;
}
@@ -3562,8 +3574,7 @@ nautilus_icon_container_update_icon (NautilusIconContainer *container,
nautilus_scalable_icon_unref (scalable_icon);
- /* in the rare case an image is too small, scale it up */
-
+ /* in the rare case an image is too small, scale it up */
width = gdk_pixbuf_get_width (pixbuf);
height = gdk_pixbuf_get_height (pixbuf);
if (width < min_image_size || height < min_image_size) {
@@ -3571,9 +3582,11 @@ nautilus_icon_container_update_icon (NautilusIconContainer *container,
/* don't let it exceed the maximum width in the other dimension */
scale_factor = MIN (scale_factor, max_image_size / width);
scale_factor = MIN (scale_factor, max_image_size / height);
-
+
scaled_width = floor (width * scale_factor + .5);
scaled_height = floor (height * scale_factor + .5);
+
+ /* scale the image to the calculated size */
saved_pixbuf = pixbuf;
pixbuf = gdk_pixbuf_scale_simple (pixbuf, scaled_width, scaled_height, GDK_INTERP_BILINEAR);
gdk_pixbuf_unref (saved_pixbuf);
@@ -3608,13 +3621,22 @@ nautilus_icon_container_update_icon (NautilusIconContainer *container,
emblem_pixbufs = g_list_reverse (emblem_pixbufs);
nautilus_scalable_icon_list_free (emblem_scalable_icons);
+ /* get the embedded control, if any */
+ embedded_control = nautilus_icon_canvas_item_get_control (icon->item);
+ if (embedded_control == NULL) {
+ gtk_signal_emit (GTK_OBJECT (container),
+ signals[GET_ICON_CONTROL],
+ icon->data,
+ &embedded_control);
+ }
+
/* Get both editable and non-editable icon text */
gtk_signal_emit (GTK_OBJECT (container),
signals[GET_ICON_TEXT],
icon->data,
&editable_text,
&additional_text);
-
+
/* If name of icon being renamed was changed from elsewhere, end renaming mode.
* Alternatively, we could replace the characters in the editable text widget
* with the new name, but that could cause timing problems if the user just
@@ -3639,6 +3661,8 @@ nautilus_icon_container_update_icon (NautilusIconContainer *container,
"smooth_font", details->smooth_label_font,
NULL);
+ nautilus_icon_canvas_item_set_control (icon->item, embedded_control);
+
nautilus_icon_canvas_item_set_image (icon->item, pixbuf);
nautilus_icon_canvas_item_set_attach_points (icon->item, &attach_points);
nautilus_icon_canvas_item_set_emblems (icon->item, emblem_pixbufs);
diff --git a/libnautilus-extensions/nautilus-icon-container.h b/libnautilus-extensions/nautilus-icon-container.h
index a16d99e30..e551f184f 100644
--- a/libnautilus-extensions/nautilus-icon-container.h
+++ b/libnautilus-extensions/nautilus-icon-container.h
@@ -107,6 +107,10 @@ typedef struct {
gboolean (* get_stored_icon_position) (NautilusIconContainer *container,
NautilusIconData *data,
NautilusIconPosition *position);
+ void
+ (* get_icon_control) (NautilusIconContainer *container,
+ NautilusIconData *data,
+ GtkWidget **control);
NautilusScalableIcon *
(* get_icon_images) (NautilusIconContainer *container,
NautilusIconData *data,
diff --git a/libnautilus-extensions/nautilus-icon-dnd.c b/libnautilus-extensions/nautilus-icon-dnd.c
index 4098056b7..9eb050891 100644
--- a/libnautilus-extensions/nautilus-icon-dnd.c
+++ b/libnautilus-extensions/nautilus-icon-dnd.c
@@ -1257,6 +1257,7 @@ nautilus_icon_dnd_begin_drag (NautilusIconContainer *container,
&pixmap_for_dragged_file,
&mask_for_dragged_file,
NAUTILUS_STANDARD_ALPHA_THRESHHOLD);
+ gdk_pixbuf_unref (pixbuf);
/* compute the image's offset */
nautilus_icon_canvas_item_get_icon_rectangle
diff --git a/libnautilus-extensions/nautilus-link.c b/libnautilus-extensions/nautilus-link.c
index 407a29540..10edebecc 100644
--- a/libnautilus-extensions/nautilus-link.c
+++ b/libnautilus-extensions/nautilus-link.c
@@ -287,6 +287,35 @@ nautilus_link_local_get_additional_text (const char *path)
(path, NAUTILUS_METADATA_KEY_EXTRA_TEXT);
}
+void nautilus_link_local_get_component_info (const char *path,
+ char **control_moniker, char **control_data)
+{
+ xmlDoc *document;
+ const char *mime_type;
+
+ *control_moniker = NULL;
+ *control_data = NULL;
+
+ /* Check mime type. Exit if it is not a nautilus link */
+ mime_type = gnome_vfs_get_file_mime_type (path, NULL, FALSE);
+ if (strcmp (mime_type, "application/x-nautilus-link") != 0) {
+ return;
+ }
+
+ document = xmlParseFile (path);
+ if (document != NULL) {
+ *control_moniker = xml_get_root_property (document,
+ NAUTILUS_METADATA_KEY_CONTROL_MONIKER);
+
+ *control_data = xml_get_root_property (document,
+ NAUTILUS_METADATA_KEY_CONTROL_DATA);
+
+ xmlFreeDoc (document);
+ }
+}
+
+
+
/* utility to return the local pathname of a cached icon, given the leaf name */
/* if the icons directory hasn't been created yet, create it */
static char *
diff --git a/libnautilus-extensions/nautilus-link.h b/libnautilus-extensions/nautilus-link.h
index 1f707f0c7..6a6df0852 100644
--- a/libnautilus-extensions/nautilus-link.h
+++ b/libnautilus-extensions/nautilus-link.h
@@ -72,14 +72,21 @@ gboolean nautilus_link_local_set_link_uri (const char
* none. Despite the fact that it takes a URI parameter, works only if
* the file is local and does sync. I/O.
*/
-char * nautilus_link_local_get_additional_text (const char *path);
+char * nautilus_link_local_get_additional_text (const char *path);
/* Returns the image associated with a link file. Despite the fact
* that it takes a URI parameter, works only if the file is local and
* does sync. I/O on the link, although it does async. on the image
* and caches if the image is remote.
*/
-char * nautilus_link_local_get_image_uri (const char *path);
+char * nautilus_link_local_get_image_uri (const char *path);
+
+/* returns the moniker of the component associated with a link file, as well as configuration data.
+ * It works only if the file is local and does sync. I/O.
+ */
+void nautilus_link_local_get_component_info (const char *path,
+ char **control_moniker,
+ char **control_data);
/* Returns the link type of a link file.
* Works only if the file is local and does sync. I/O
diff --git a/libnautilus-extensions/nautilus-metadata.h b/libnautilus-extensions/nautilus-metadata.h
index 3de64b564..18f8a75e3 100644
--- a/libnautilus-extensions/nautilus-metadata.h
+++ b/libnautilus-extensions/nautilus-metadata.h
@@ -72,6 +72,9 @@
#define NAUTILUS_METADATA_KEY_ICON_SCALE "ICON_SCALE"
#define NAUTILUS_METADATA_KEY_CUSTOM_ICON "CUSTOM_ICON"
+#define NAUTILUS_METADATA_KEY_CONTROL_MONIKER "CONTROL_MONIKER"
+#define NAUTILUS_METADATA_KEY_CONTROL_DATA "CONTROL_DATA"
+
/* per link file */
#define NAUTILUS_METADATA_KEY_EXTRA_TEXT "EXTRA_TEXT"
diff --git a/libnautilus-private/nautilus-file-utilities.c b/libnautilus-private/nautilus-file-utilities.c
index 2eb762eed..66f773338 100644
--- a/libnautilus-private/nautilus-file-utilities.c
+++ b/libnautilus-private/nautilus-file-utilities.c
@@ -614,22 +614,7 @@ nautilus_get_user_main_directory (void)
image_uri);
nautilus_file_unref (file);
}
-
- /* now do the same for the about file */
- temp_str = g_strdup_printf ("%s/About.html", user_main_directory);
- file_uri = gnome_vfs_get_uri_from_local_path (temp_str);
- g_free (temp_str);
-
- file = nautilus_file_get (file_uri);
- if (file != NULL) {
- nautilus_file_set_metadata (file,
- NAUTILUS_METADATA_KEY_CUSTOM_ICON,
- NULL,
- image_uri);
- nautilus_file_unref (file);
- }
- g_free (file_uri);
-
+
g_free (image_uri);
/* install the default link set */
diff --git a/libnautilus-private/nautilus-icon-canvas-item.c b/libnautilus-private/nautilus-icon-canvas-item.c
index d7c091785..ec61082aa 100644
--- a/libnautilus-private/nautilus-icon-canvas-item.c
+++ b/libnautilus-private/nautilus-icon-canvas-item.c
@@ -76,6 +76,10 @@ struct NautilusIconCanvasItemDetails {
GdkFont *font;
NautilusEmblemAttachPoints *attach_points;
+ /* stuff for controls; if this gets too big, we've put it in a separate struct */
+ GtkWidget *control; /* optional Bonobo control*/
+ guint control_destroy_id;
+
/* Size of the text at current font. */
int text_width;
int text_height;
@@ -89,7 +93,7 @@ struct NautilusIconCanvasItemDetails {
guint is_highlighted_for_drop : 1;
guint show_stretch_handles : 1;
guint is_prelit : 1;
-
+ guint in_control_destroy : 1;
gboolean is_renaming;
/* Font stuff whilst in smooth mode */
@@ -103,7 +107,7 @@ enum {
ARG_EDITABLE_TEXT,
ARG_ADDITIONAL_TEXT,
ARG_FONT,
- ARG_HIGHLIGHTED_FOR_SELECTION,
+ ARG_HIGHLIGHTED_FOR_SELECTION,
ARG_HIGHLIGHTED_AS_KEYBOARD_FOCUS,
ARG_HIGHLIGHTED_FOR_DROP,
ARG_MODIFIER,
@@ -318,6 +322,11 @@ nautilus_icon_canvas_item_destroy (GtkObject *object)
gdk_font_unref (details->font);
}
+ if (details->control && !details->in_control_destroy) {
+ gtk_signal_disconnect (GTK_OBJECT (details->control), details->control_destroy_id);
+ gtk_widget_destroy (details->control);
+ }
+
gtk_object_unref (GTK_OBJECT (icon_item->details->smooth_font));
icon_item->details->smooth_font = NULL;
@@ -351,6 +360,28 @@ invalidate_text_dimensions (NautilusIconCanvasItem *item)
item->details->text_height = -1;
}
+/* abstraction layer for icon width and height, to separate it from pixbuf with and height */
+static int
+nautilus_icon_canvas_item_get_icon_width (NautilusIconCanvasItem *item)
+{
+ if (item->details->pixbuf == NULL) {
+ return NAUTILUS_ICON_SIZE_STANDARD;
+ }
+
+ return gdk_pixbuf_get_width (item->details->pixbuf);
+}
+
+static int
+nautilus_icon_canvas_item_get_icon_height (NautilusIconCanvasItem *item)
+{
+ if (item->details->pixbuf == NULL) {
+ return NAUTILUS_ICON_SIZE_STANDARD;
+ }
+
+ return gdk_pixbuf_get_height (item->details->pixbuf);
+}
+
+
/* Set_arg handler for the icon item. */
static void
nautilus_icon_canvas_item_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
@@ -433,8 +464,7 @@ nautilus_icon_canvas_item_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
case ARG_SMOOTH_FONT_SIZE:
nautilus_icon_canvas_item_set_smooth_font_size (NAUTILUS_ICON_CANVAS_ITEM (object),
GTK_VALUE_UINT (*arg));
- break;
-
+ break;
default:
g_warning ("nautilus_icons_view_item_item_set_arg on unknown argument");
return;
@@ -443,12 +473,27 @@ nautilus_icon_canvas_item_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (object));
}
+/* handler for the control's destroy signal */
+static void
+do_control_destroy (GtkObject *object, gpointer data)
+{
+ NautilusIconCanvasItemDetails *details;
+
+ details = NAUTILUS_ICON_CANVAS_ITEM (data)->details;
+
+ details->in_control_destroy = TRUE;
+
+ gtk_object_destroy (GTK_OBJECT (data));
+}
+
/* Get_arg handler for the icon item */
static void
nautilus_icon_canvas_item_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
{
NautilusIconCanvasItemDetails *details;
+ GnomeCanvasItem *item;
+ item = GNOME_CANVAS_ITEM (object);
details = NAUTILUS_ICON_CANVAS_ITEM (object)->details;
switch (arg_id) {
@@ -496,12 +541,27 @@ GdkPixbuf *
nautilus_icon_canvas_item_get_image (NautilusIconCanvasItem *item)
{
NautilusIconCanvasItemDetails *details;
-
+ int width, height;
+ GdkPixbuf *pixbuf;
+
g_return_val_if_fail (NAUTILUS_IS_ICON_CANVAS_ITEM (item), NULL);
details = item->details;
- return details->pixbuf;
+ if (details->control) {
+ width = details->control->allocation.width;
+ height = details->control->allocation.height;
+ pixbuf = nautilus_gdk_pixbuf_get_from_window_safe (details->control->window,
+ details->control->allocation.x,
+ details->control->allocation.y,
+ details->control->allocation.width,
+ details->control->allocation.height);
+ } else {
+ pixbuf = details->pixbuf;
+ gdk_pixbuf_ref (pixbuf);
+ }
+
+ return pixbuf;
}
void
@@ -603,6 +663,12 @@ recompute_bounding_box (NautilusIconCanvasItem *icon_item)
item->y1 = top_left.y;
item->x2 = bottom_right.x;
item->y2 = bottom_right.y;
+
+ if (icon_item->details->control)
+ gtk_layout_move (GTK_LAYOUT (item->canvas), icon_item->details->control,
+ item->x1 + item->canvas->zoom_xofs,
+ item->y1 + item->canvas->zoom_yofs);
+
}
void
@@ -622,6 +688,16 @@ nautilus_icon_canvas_item_update_bounds (NautilusIconCanvasItem *item)
return;
}
+ /* if there is an embedded control, resize it appropriately */
+ if (item->details->control) {
+ /* for now, size it the same as the underlying image */
+ int image_width = nautilus_icon_canvas_item_get_icon_width (item);
+ int image_height = nautilus_icon_canvas_item_get_icon_height (item);
+
+ gtk_widget_set_usize (item->details->control,
+ image_width, image_height);
+ }
+
/* Send out the bounds_changed signal and queue a redraw. */
nautilus_gnome_canvas_request_redraw_rectangle
(GNOME_CANVAS_ITEM (item)->canvas, &before);
@@ -766,7 +842,7 @@ draw_or_measure_label_text (NautilusIconCanvasItem *item,
canvas_item = GNOME_CANVAS_ITEM (item);
if (drawable != NULL) {
- icon_width = details->pixbuf == NULL ? 0 : gdk_pixbuf_get_width (details->pixbuf);
+ icon_width = details->pixbuf == NULL ? 0 : nautilus_icon_canvas_item_get_icon_width (item);
gc = gdk_gc_new (canvas_item->canvas->layout.bin_window);
gdk_gc_get_values (gc, &save_gc);
}
@@ -1171,11 +1247,17 @@ emblem_layout_next (EmblemLayout *layout,
/* Return the rectangle and pixbuf. */
*emblem_pixbuf = pixbuf;
- emblem_rect->x0 = x - width / 2;
- emblem_rect->y0 = y - height / 2;
+ if (layout->icon_item->details->control) {
+ emblem_rect->x0 = x;
+ emblem_rect->y0 = y;
+ } else {
+ emblem_rect->x0 = x - width / 2;
+ emblem_rect->y0 = y - height / 2;
+ }
+
emblem_rect->x1 = emblem_rect->x0 + width;
emblem_rect->y1 = emblem_rect->y0 + height;
-
+
return TRUE;
}
@@ -1214,35 +1296,7 @@ draw_pixbuf (GdkPixbuf *pixbuf, GdkDrawable *drawable, int x, int y)
static void
draw_pixbuf_aa (GdkPixbuf *pixbuf, GnomeCanvasBuf *buf, double affine[6], int x_offset, int y_offset)
{
- void (* affine_function)
- (art_u8 *dst, int x0, int y0, int x1, int y1, int dst_rowstride,
- const art_u8 *src, int src_width, int src_height, int src_rowstride,
- const double affine[6],
- ArtFilterLevel level,
- ArtAlphaGamma *alpha_gamma);
-
- affine[4] += x_offset;
- affine[5] += y_offset;
-
- affine_function = gdk_pixbuf_get_has_alpha (pixbuf)
- ? art_rgb_rgba_affine
- : art_rgb_affine;
-
- (* affine_function)
- (buf->buf,
- buf->rect.x0, buf->rect.y0,
- buf->rect.x1, buf->rect.y1,
- buf->buf_rowstride,
- gdk_pixbuf_get_pixels (pixbuf),
- gdk_pixbuf_get_width (pixbuf),
- gdk_pixbuf_get_height (pixbuf),
- gdk_pixbuf_get_rowstride (pixbuf),
- affine,
- ART_FILTER_NEAREST,
- NULL);
-
- affine[4] -= x_offset;
- affine[5] -= y_offset;
+ nautilus_gnome_canvas_draw_pixbuf (buf, pixbuf, affine[4] + x_offset, affine[5] + y_offset);
}
/* shared code to highlight or dim the passed-in pixbuf */
@@ -1324,23 +1378,30 @@ nautilus_icon_canvas_item_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
icon_item = NAUTILUS_ICON_CANVAS_ITEM (item);
details = icon_item->details;
- /* Draw the pixbuf. */
- if (details->pixbuf == NULL) {
- return;
- }
- /* Compute icon rectangle in drawable coordinates. */
- get_icon_canvas_rectangle (icon_item, &icon_rect);
- icon_rect.x0 -= x;
- icon_rect.y0 -= y;
- icon_rect.x1 -= x;
- icon_rect.y1 -= y;
+ /* draw the icon or widget */
+ if (icon_item->details->control) {
+ gtk_widget_queue_draw (icon_item->details->control);
+ } else {
+ if (details->pixbuf != NULL) {
+
+ /* Compute icon rectangle in drawable coordinates. */
+ get_icon_canvas_rectangle (icon_item, &icon_rect);
+ icon_rect.x0 -= x;
+ icon_rect.y0 -= y;
+ icon_rect.x1 -= x;
+ icon_rect.y1 -= y;
+
+ /* if the pre-lit or selection flag is set, make a pre-lit or darkened pixbuf and draw that instead */
+ temp_pixbuf = map_pixbuf (icon_item);
+ draw_pixbuf (temp_pixbuf, drawable, icon_rect.x0, icon_rect.y0);
+
+ if (temp_pixbuf != details->pixbuf) {
+ gdk_pixbuf_unref (temp_pixbuf);
+ }
+
+ }
- /* if the pre-lit or selection flag is set, make a pre-lit or darkened pixbuf and draw that instead */
- temp_pixbuf = map_pixbuf (icon_item);
- draw_pixbuf (temp_pixbuf, drawable, icon_rect.x0, icon_rect.y0);
- if (temp_pixbuf != details->pixbuf) {
- gdk_pixbuf_unref (temp_pixbuf);
}
/* Draw the emblem pixbufs. */
@@ -1425,7 +1486,7 @@ draw_or_measure_label_text_aa (NautilusIconCanvasItem *item,
if (destination_pixbuf == NULL ) {
icon_width = 0;
} else {
- icon_width = details->pixbuf == NULL ? 0 : gdk_pixbuf_get_width (details->pixbuf);
+ icon_width = details->pixbuf == NULL ? 0 : nautilus_icon_canvas_item_get_icon_width (item);
}
max_text_width = floor (nautilus_icon_canvas_item_get_max_text_width (item));
@@ -1670,9 +1731,6 @@ nautilus_icon_canvas_item_render (GnomeCanvasItem *item, GnomeCanvasBuf *buf)
icon_item = NAUTILUS_ICON_CANVAS_ITEM (item);
- /* map the pixbuf for selection or other effects */
- temp_pixbuf = map_pixbuf (icon_item);
-
/* Compute the affine transform, but force the scale to 1.0
* because the icon factory does the scaling for us.
*/
@@ -1689,13 +1747,19 @@ nautilus_icon_canvas_item_render (GnomeCanvasItem *item, GnomeCanvasBuf *buf)
buf->is_bg = FALSE;
}
- /* draw the icon */
- draw_pixbuf_aa (temp_pixbuf, buf, i2c, 0, 0);
+ /* draw the icon or widget */
+ if (icon_item->details->control) {
+ gtk_widget_queue_draw (icon_item->details->control);
+ } else {
+ /* map the pixbuf for selection or other effects */
+ temp_pixbuf = map_pixbuf (icon_item);
+ draw_pixbuf_aa (temp_pixbuf, buf, i2c, 0, 0);
- if (temp_pixbuf != icon_item->details->pixbuf) {
- gdk_pixbuf_unref (temp_pixbuf);
+ if (temp_pixbuf != icon_item->details->pixbuf) {
+ gdk_pixbuf_unref (temp_pixbuf);
+ }
}
-
+
/* draw the emblems */
get_icon_canvas_rectangle (icon_item, &icon_rect);
@@ -1926,8 +1990,8 @@ nautilus_icon_canvas_item_bounds (GnomeCanvasItem *item,
icon_rect.x1 = 0;
icon_rect.y1 = 0;
} else {
- icon_rect.x1 = gdk_pixbuf_get_width (details->pixbuf);
- icon_rect.y1 = gdk_pixbuf_get_height (details->pixbuf);
+ icon_rect.x1 = nautilus_icon_canvas_item_get_icon_width (icon_item);
+ icon_rect.y1 = nautilus_icon_canvas_item_get_icon_height (icon_item);
}
/* Compute text rectangle. */
@@ -1973,8 +2037,8 @@ nautilus_icon_canvas_item_get_icon_rectangle (NautilusIconCanvasItem *item,
pixbuf = item->details->pixbuf;
pixels_per_unit = GNOME_CANVAS_ITEM (item)->canvas->pixels_per_unit;
- rect->x1 = rect->x0 + (pixbuf == NULL ? 0 : gdk_pixbuf_get_width (pixbuf)) / pixels_per_unit;
- rect->y1 = rect->y0 + (pixbuf == NULL ? 0 : gdk_pixbuf_get_height (pixbuf)) / pixels_per_unit;
+ rect->x1 = rect->x0 + (pixbuf == NULL ? 0 : nautilus_icon_canvas_item_get_icon_width (item)) / pixels_per_unit;
+ rect->y1 = rect->y0 + (pixbuf == NULL ? 0 : nautilus_icon_canvas_item_get_icon_height (item)) / pixels_per_unit;
}
/* Get the rectangle of the icon only, in canvas coordinates. */
@@ -2000,8 +2064,8 @@ get_icon_canvas_rectangle (NautilusIconCanvasItem *item,
pixbuf = item->details->pixbuf;
- rect->x1 = rect->x0 + (pixbuf == NULL ? 0 : gdk_pixbuf_get_width (pixbuf));
- rect->y1 = rect->y0 + (pixbuf == NULL ? 0 : gdk_pixbuf_get_height (pixbuf));
+ rect->x1 = rect->x0 + (pixbuf == NULL ? 0 : nautilus_icon_canvas_item_get_icon_width (item));
+ rect->y1 = rect->y0 + (pixbuf == NULL ? 0 : nautilus_icon_canvas_item_get_icon_height (item));
}
void
@@ -2158,6 +2222,42 @@ nautilus_icon_canvas_item_set_smooth_font (NautilusIconCanvasItem *icon_item,
}
}
+GtkWidget *
+nautilus_icon_canvas_item_get_control (NautilusIconCanvasItem *icon_item)
+{
+ return icon_item->details->control;
+}
+
+void
+nautilus_icon_canvas_item_set_control (NautilusIconCanvasItem *icon_item, GtkWidget *control)
+{
+ GnomeCanvasItem *item;
+
+ if (icon_item->details->control == control) {
+ return;
+ }
+
+ item = GNOME_CANVAS_ITEM (icon_item);
+ if (icon_item->details->control) {
+ gtk_signal_disconnect (GTK_OBJECT (icon_item->details->control), icon_item->details->control_destroy_id);
+ gtk_container_remove (GTK_CONTAINER (item->canvas), icon_item->details->control);
+ icon_item->details->control = NULL;
+ }
+
+ if (control) {
+ g_message ("adding control...");
+ icon_item->details->control = control;
+ icon_item->details->control_destroy_id = gtk_signal_connect (GTK_OBJECT (control),
+ "destroy",
+ (GtkSignalFunc) do_control_destroy,
+ item);
+ gtk_widget_show (control);
+ gtk_layout_put (GTK_LAYOUT (item->canvas), control,
+ item->x1 + item->canvas->zoom_xofs,
+ item->y1 + item->canvas->zoom_yofs);
+ }
+}
+
void
nautilus_icon_canvas_item_set_smooth_font_size (NautilusIconCanvasItem *icon_item,
guint font_size)
diff --git a/libnautilus-private/nautilus-icon-canvas-item.h b/libnautilus-private/nautilus-icon-canvas-item.h
index 8de5c8f23..c9d44375b 100644
--- a/libnautilus-private/nautilus-icon-canvas-item.h
+++ b/libnautilus-private/nautilus-icon-canvas-item.h
@@ -80,6 +80,10 @@ const char *nautilus_icon_canvas_item_get_editable_text (NautilusIconCanv
void nautilus_icon_canvas_item_set_renaming (NautilusIconCanvasItem *icon_item,
gboolean state);
+GtkWidget * nautilus_icon_canvas_item_get_control (NautilusIconCanvasItem *icon_item);
+void nautilus_icon_canvas_item_set_control (NautilusIconCanvasItem *icon_item,
+ GtkWidget *control);
+
/* geometry and hit testing */
gboolean nautilus_icon_canvas_item_hit_test_rectangle (NautilusIconCanvasItem *item,
diff --git a/libnautilus-private/nautilus-icon-container.c b/libnautilus-private/nautilus-icon-container.c
index c14dd664c..95e3852bf 100644
--- a/libnautilus-private/nautilus-icon-container.c
+++ b/libnautilus-private/nautilus-icon-container.c
@@ -160,6 +160,7 @@ enum {
CONTEXT_CLICK_SELECTION,
MIDDLE_CLICK,
GET_CONTAINER_URI,
+ GET_ICON_CONTROL,
GET_ICON_IMAGES,
GET_ICON_TEXT,
GET_ICON_URI,
@@ -2974,6 +2975,16 @@ nautilus_icon_container_initialize_class (NautilusIconContainerClass *class)
gtk_marshal_NONE__POINTER,
GTK_TYPE_NONE, 1,
GTK_TYPE_POINTER);
+ signals[GET_ICON_CONTROL]
+ = gtk_signal_new ("get_icon_control",
+ GTK_RUN_LAST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (NautilusIconContainerClass,
+ get_icon_control),
+ gtk_marshal_NONE__POINTER_POINTER,
+ GTK_TYPE_NONE, 2,
+ GTK_TYPE_POINTER,
+ GTK_TYPE_POINTER);
signals[GET_ICON_IMAGES]
= gtk_signal_new ("get_icon_images",
GTK_RUN_LAST,
@@ -3528,9 +3539,10 @@ nautilus_icon_container_update_icon (NautilusIconContainer *container,
GdkPixbuf *pixbuf, *emblem_pixbuf, *saved_pixbuf;
GList *emblem_scalable_icons, *emblem_pixbufs, *p;
char *editable_text, *additional_text;
+ GtkWidget *embedded_control;
GdkFont *font;
guint smooth_font_size;
-
+
if (icon == NULL) {
return;
}
@@ -3562,8 +3574,7 @@ nautilus_icon_container_update_icon (NautilusIconContainer *container,
nautilus_scalable_icon_unref (scalable_icon);
- /* in the rare case an image is too small, scale it up */
-
+ /* in the rare case an image is too small, scale it up */
width = gdk_pixbuf_get_width (pixbuf);
height = gdk_pixbuf_get_height (pixbuf);
if (width < min_image_size || height < min_image_size) {
@@ -3571,9 +3582,11 @@ nautilus_icon_container_update_icon (NautilusIconContainer *container,
/* don't let it exceed the maximum width in the other dimension */
scale_factor = MIN (scale_factor, max_image_size / width);
scale_factor = MIN (scale_factor, max_image_size / height);
-
+
scaled_width = floor (width * scale_factor + .5);
scaled_height = floor (height * scale_factor + .5);
+
+ /* scale the image to the calculated size */
saved_pixbuf = pixbuf;
pixbuf = gdk_pixbuf_scale_simple (pixbuf, scaled_width, scaled_height, GDK_INTERP_BILINEAR);
gdk_pixbuf_unref (saved_pixbuf);
@@ -3608,13 +3621,22 @@ nautilus_icon_container_update_icon (NautilusIconContainer *container,
emblem_pixbufs = g_list_reverse (emblem_pixbufs);
nautilus_scalable_icon_list_free (emblem_scalable_icons);
+ /* get the embedded control, if any */
+ embedded_control = nautilus_icon_canvas_item_get_control (icon->item);
+ if (embedded_control == NULL) {
+ gtk_signal_emit (GTK_OBJECT (container),
+ signals[GET_ICON_CONTROL],
+ icon->data,
+ &embedded_control);
+ }
+
/* Get both editable and non-editable icon text */
gtk_signal_emit (GTK_OBJECT (container),
signals[GET_ICON_TEXT],
icon->data,
&editable_text,
&additional_text);
-
+
/* If name of icon being renamed was changed from elsewhere, end renaming mode.
* Alternatively, we could replace the characters in the editable text widget
* with the new name, but that could cause timing problems if the user just
@@ -3639,6 +3661,8 @@ nautilus_icon_container_update_icon (NautilusIconContainer *container,
"smooth_font", details->smooth_label_font,
NULL);
+ nautilus_icon_canvas_item_set_control (icon->item, embedded_control);
+
nautilus_icon_canvas_item_set_image (icon->item, pixbuf);
nautilus_icon_canvas_item_set_attach_points (icon->item, &attach_points);
nautilus_icon_canvas_item_set_emblems (icon->item, emblem_pixbufs);
diff --git a/libnautilus-private/nautilus-icon-container.h b/libnautilus-private/nautilus-icon-container.h
index a16d99e30..e551f184f 100644
--- a/libnautilus-private/nautilus-icon-container.h
+++ b/libnautilus-private/nautilus-icon-container.h
@@ -107,6 +107,10 @@ typedef struct {
gboolean (* get_stored_icon_position) (NautilusIconContainer *container,
NautilusIconData *data,
NautilusIconPosition *position);
+ void
+ (* get_icon_control) (NautilusIconContainer *container,
+ NautilusIconData *data,
+ GtkWidget **control);
NautilusScalableIcon *
(* get_icon_images) (NautilusIconContainer *container,
NautilusIconData *data,
diff --git a/libnautilus-private/nautilus-icon-dnd.c b/libnautilus-private/nautilus-icon-dnd.c
index 4098056b7..9eb050891 100644
--- a/libnautilus-private/nautilus-icon-dnd.c
+++ b/libnautilus-private/nautilus-icon-dnd.c
@@ -1257,6 +1257,7 @@ nautilus_icon_dnd_begin_drag (NautilusIconContainer *container,
&pixmap_for_dragged_file,
&mask_for_dragged_file,
NAUTILUS_STANDARD_ALPHA_THRESHHOLD);
+ gdk_pixbuf_unref (pixbuf);
/* compute the image's offset */
nautilus_icon_canvas_item_get_icon_rectangle
diff --git a/libnautilus-private/nautilus-link.c b/libnautilus-private/nautilus-link.c
index 407a29540..10edebecc 100644
--- a/libnautilus-private/nautilus-link.c
+++ b/libnautilus-private/nautilus-link.c
@@ -287,6 +287,35 @@ nautilus_link_local_get_additional_text (const char *path)
(path, NAUTILUS_METADATA_KEY_EXTRA_TEXT);
}
+void nautilus_link_local_get_component_info (const char *path,
+ char **control_moniker, char **control_data)
+{
+ xmlDoc *document;
+ const char *mime_type;
+
+ *control_moniker = NULL;
+ *control_data = NULL;
+
+ /* Check mime type. Exit if it is not a nautilus link */
+ mime_type = gnome_vfs_get_file_mime_type (path, NULL, FALSE);
+ if (strcmp (mime_type, "application/x-nautilus-link") != 0) {
+ return;
+ }
+
+ document = xmlParseFile (path);
+ if (document != NULL) {
+ *control_moniker = xml_get_root_property (document,
+ NAUTILUS_METADATA_KEY_CONTROL_MONIKER);
+
+ *control_data = xml_get_root_property (document,
+ NAUTILUS_METADATA_KEY_CONTROL_DATA);
+
+ xmlFreeDoc (document);
+ }
+}
+
+
+
/* utility to return the local pathname of a cached icon, given the leaf name */
/* if the icons directory hasn't been created yet, create it */
static char *
diff --git a/libnautilus-private/nautilus-link.h b/libnautilus-private/nautilus-link.h
index 1f707f0c7..6a6df0852 100644
--- a/libnautilus-private/nautilus-link.h
+++ b/libnautilus-private/nautilus-link.h
@@ -72,14 +72,21 @@ gboolean nautilus_link_local_set_link_uri (const char
* none. Despite the fact that it takes a URI parameter, works only if
* the file is local and does sync. I/O.
*/
-char * nautilus_link_local_get_additional_text (const char *path);
+char * nautilus_link_local_get_additional_text (const char *path);
/* Returns the image associated with a link file. Despite the fact
* that it takes a URI parameter, works only if the file is local and
* does sync. I/O on the link, although it does async. on the image
* and caches if the image is remote.
*/
-char * nautilus_link_local_get_image_uri (const char *path);
+char * nautilus_link_local_get_image_uri (const char *path);
+
+/* returns the moniker of the component associated with a link file, as well as configuration data.
+ * It works only if the file is local and does sync. I/O.
+ */
+void nautilus_link_local_get_component_info (const char *path,
+ char **control_moniker,
+ char **control_data);
/* Returns the link type of a link file.
* Works only if the file is local and does sync. I/O
diff --git a/libnautilus-private/nautilus-metadata.h b/libnautilus-private/nautilus-metadata.h
index 3de64b564..18f8a75e3 100644
--- a/libnautilus-private/nautilus-metadata.h
+++ b/libnautilus-private/nautilus-metadata.h
@@ -72,6 +72,9 @@
#define NAUTILUS_METADATA_KEY_ICON_SCALE "ICON_SCALE"
#define NAUTILUS_METADATA_KEY_CUSTOM_ICON "CUSTOM_ICON"
+#define NAUTILUS_METADATA_KEY_CONTROL_MONIKER "CONTROL_MONIKER"
+#define NAUTILUS_METADATA_KEY_CONTROL_DATA "CONTROL_DATA"
+
/* per link file */
#define NAUTILUS_METADATA_KEY_EXTRA_TEXT "EXTRA_TEXT"
diff --git a/src/file-manager/fm-icon-view.c b/src/file-manager/fm-icon-view.c
index cedf700ff..c285d7a7f 100644
--- a/src/file-manager/fm-icon-view.c
+++ b/src/file-manager/fm-icon-view.c
@@ -28,6 +28,7 @@
#include "fm-desktop-icon-view.h"
#include "fm-error-reporting.h"
#include "fm-icon-text-window.h"
+#include <bonobo/bonobo-widget.h>
#include <bonobo/bonobo-ui-util.h>
#include <ctype.h>
#include <errno.h>
@@ -1638,6 +1639,39 @@ get_icon_images_callback (NautilusIconContainer *container,
return nautilus_icon_factory_get_icon_for_file (file, modifier, smooth_graphics);
}
+/* return the Bonobo control associated with the icon, if any */
+static void
+get_icon_control_callback (NautilusIconContainer *container,
+ NautilusFile *file,
+ GtkWidget **control,
+ FMIconView *icon_view)
+{
+ Bonobo_UIContainer ui_container;
+ char *control_moniker, *control_data;
+ char *uri, *path;
+ *control = NULL;
+
+ if (nautilus_file_is_nautilus_link (file)) {
+ uri = nautilus_file_get_uri (file);
+ path = gnome_vfs_get_local_path_from_uri (uri);
+ if (path != NULL) {
+ nautilus_link_local_get_component_info (path, &control_moniker, &control_data);
+ if (control_moniker) {
+ g_message ("got moniker %s", control_moniker);
+ ui_container = fm_directory_view_get_bonobo_ui_container (FM_DIRECTORY_VIEW (icon_view));
+ *control = bonobo_widget_new_control (control_moniker, ui_container);
+ g_free (control_moniker);
+ }
+ if (control_data && strlen (control_data) > 0) {
+ bonobo_widget_set_property (BONOBO_WIDGET (*control), "configuration", control_data, NULL);
+ g_free (control_data);
+ }
+ g_free (path);
+ }
+ g_free (uri);
+ }
+}
+
static char *
get_icon_uri_callback (NautilusIconContainer *container,
NautilusFile *file,
@@ -2011,6 +2045,10 @@ create_icon_container (FMIconView *icon_view)
GTK_SIGNAL_FUNC (get_icon_images_callback),
icon_view);
gtk_signal_connect (GTK_OBJECT (icon_container),
+ "get_icon_control",
+ GTK_SIGNAL_FUNC (get_icon_control_callback),
+ icon_view);
+ gtk_signal_connect (GTK_OBJECT (icon_container),
"get_icon_uri",
GTK_SIGNAL_FUNC (get_icon_uri_callback),
icon_view);
diff --git a/src/nautilus-information-panel.c b/src/nautilus-information-panel.c
index 6cf041618..50d45549a 100644
--- a/src/nautilus-information-panel.c
+++ b/src/nautilus-information-panel.c
@@ -1018,9 +1018,13 @@ nautilus_sidebar_release_event (GtkWidget *widget, GdkEventButton *event)
if (rounded_y >= GTK_WIDGET (sidebar->details->sidebar_tabs)->allocation.y) {
which_tab = nautilus_sidebar_tabs_hit_test (sidebar_tabs, event->x, event->y);
if (which_tab >= 0) {
- nautilus_sidebar_tabs_select_tab (sidebar_tabs, which_tab);
- nautilus_sidebar_activate_panel (sidebar, which_tab);
- gtk_widget_queue_draw (widget);
+ if (which_tab == sidebar->details->selected_index) {
+ nautilus_sidebar_deactivate_panel (sidebar);
+ } else {
+ nautilus_sidebar_tabs_select_tab (sidebar_tabs, which_tab);
+ nautilus_sidebar_activate_panel (sidebar, which_tab);
+ gtk_widget_queue_draw (widget);
+ }
}
}
diff --git a/src/nautilus-sidebar-tabs.c b/src/nautilus-sidebar-tabs.c
index 95b13d4d7..1b93179a9 100644
--- a/src/nautilus-sidebar-tabs.c
+++ b/src/nautilus-sidebar-tabs.c
@@ -403,16 +403,17 @@ int nautilus_sidebar_tabs_hit_test (NautilusSidebarTabs *sidebar_tabs, int x, in
/* loop through the items, seeing it the passed in point is in one of the rectangles */
tab_item = (TabItem*) current_item->data;
+ /*
if (!tab_item->visible && current_item->next) {
tab_item = (TabItem*) current_item->next->data;
}
-
+ */
result = -1;
while (current_item != NULL) {
tab_item = (TabItem*) current_item->data;
rect_ptr = &tab_item->tab_rect;
- if (tab_item->visible) {
+ if (TRUE /*tab_item->visible*/) {
if ((x >= rect_ptr->x) && (x < rect_ptr->x + rect_ptr->width) &&
(y >= rect_ptr->y) && (y< rect_ptr->y + rect_ptr->height))
result = tab_item->notebook_page;
@@ -1291,8 +1292,9 @@ nautilus_sidebar_tabs_select_tab (NautilusSidebarTabs *sidebar_tabs, int which_t
for (next_tab = sidebar_tabs->details->tab_items; next_tab != NULL; next_tab = next_tab->next) {
TabItem *item = next_tab->data;
+
item->visible = (item->notebook_page != which_tab);
- item->prelit = FALSE;
+ item->prelit = FALSE;
}
recalculate_size(sidebar_tabs);
diff --git a/src/nautilus-sidebar.c b/src/nautilus-sidebar.c
index 6cf041618..50d45549a 100644
--- a/src/nautilus-sidebar.c
+++ b/src/nautilus-sidebar.c
@@ -1018,9 +1018,13 @@ nautilus_sidebar_release_event (GtkWidget *widget, GdkEventButton *event)
if (rounded_y >= GTK_WIDGET (sidebar->details->sidebar_tabs)->allocation.y) {
which_tab = nautilus_sidebar_tabs_hit_test (sidebar_tabs, event->x, event->y);
if (which_tab >= 0) {
- nautilus_sidebar_tabs_select_tab (sidebar_tabs, which_tab);
- nautilus_sidebar_activate_panel (sidebar, which_tab);
- gtk_widget_queue_draw (widget);
+ if (which_tab == sidebar->details->selected_index) {
+ nautilus_sidebar_deactivate_panel (sidebar);
+ } else {
+ nautilus_sidebar_tabs_select_tab (sidebar_tabs, which_tab);
+ nautilus_sidebar_activate_panel (sidebar, which_tab);
+ gtk_widget_queue_draw (widget);
+ }
}
}