summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Camp <dave@ximian.com>2003-11-20 19:51:32 +0000
committerDave Camp <campd@src.gnome.org>2003-11-20 19:51:32 +0000
commit5b9f3fc0a5e6cf5324434b901dbb3d9bdcf39d67 (patch)
treee2a6f64f2783b103c56e44d5fbe8d221ed3f74eb
parenta7cdc64a52cd715755e11d8a6a9e5d506fd50b10 (diff)
downloadnautilus-5b9f3fc0a5e6cf5324434b901dbb3d9bdcf39d67.tar.gz
New library for nautilus extensions.
2003-11-20 Dave Camp <dave@ximian.com> * Makefile.am: * configure.in: * libnautilus-extension/Makefile.am: * libnautilus-extension/libnautilus-extension.pc.in: * libnautilus-extension/nautilus-extension-types.c: * libnautilus-extension/nautilus-extension-types.h: * libnautilus-extension/nautilus-file-info.c: * libnautilus-extension/nautilus-file-info.h: * libnautilus-extension/nautilus-info-provider.c: * libnautilus-extension/nautilus-info-provider.h: New library for nautilus extensions. * libnautilus-private/nautilus-marshal.list: * libnautilus-private/Makefile.am: * libnautilus-private/nautilus-directory-async.c: (nautilus_directory_set_up_request), (lacks_extension_info), (wants_extension_info), (extension_info_cancel), (extension_info_stop), (finish_info_provider), (info_provider_idle_callback), (info_provider_callback), (extension_info_start), (start_or_stop_io), (nautilus_directory_cancel), (cancel_loading_attributes), (file_needs_extension_work_done), (file_needs_work_done), (nautilus_directory_remove_file_from_work_queue), (move_file_to_low_priority_queue), (move_file_to_extension_queue): * libnautilus-private/nautilus-directory-private.h: * libnautilus-private/nautilus-directory.c: (nautilus_directory_init), (nautilus_directory_finalize), (nautilus_directory_notify_files_changed): Add a third queue for extension info, that runs after the high and low priority queues. * libnautilus-private/nautilus-file-attributes.h: * libnautilus-private/nautilus-file-operations.c: * libnautilus-private/nautilus-file-private.h: * libnautilus-private/nautilus-file.c: (nautilus_file_invalidate_extension_info_internal), (nautilus_file_invalidate_attributes_internal): * libnautilus-private/nautilus-file.c: (nautilus_file_get_type), (nautilus_file_instance_init), (nautilus_file_get_keywords), (nautilus_file_get_type), (nautilus_file_class_init), (nautilus_file_get_vfs_file_info), (nautilus_file_add_emblem), (nautilus_file_info_providers_done), (nautilus_file_info_iface_init): Implement the NautilusFileInfo interface for extensions to use. * libnautilus-private/nautilus-module.c: (nautilus_module_load), * libnautilus-private/nautilus-module.h: Module loading code. * src/file-manager/fm-directory-view.c: (finish_loading): Request extension info. * src/nautilus-application.c: (finish_startup): Initialize the module interface.
-rw-r--r--ChangeLog58
-rw-r--r--Makefile.am1
-rw-r--r--components/services/nautilus-dependent-shared/shared-service-widgets.c212
-rw-r--r--configure.in9
-rw-r--r--libnautilus-extension/Makefile.am38
-rw-r--r--libnautilus-extension/libnautilus-extension.pc.in11
-rw-r--r--libnautilus-extension/nautilus-extension-types.c57
-rw-r--r--libnautilus-extension/nautilus-extension-types.h67
-rw-r--r--libnautilus-extension/nautilus-file-info.c140
-rw-r--r--libnautilus-extension/nautilus-file-info.h102
-rw-r--r--libnautilus-extension/nautilus-info-provider.c120
-rw-r--r--libnautilus-extension/nautilus-info-provider.h80
-rw-r--r--libnautilus-private/Makefile.am7
-rw-r--r--libnautilus-private/nautilus-directory-async.c231
-rw-r--r--libnautilus-private/nautilus-directory-private.h7
-rw-r--r--libnautilus-private/nautilus-directory.c3
-rw-r--r--libnautilus-private/nautilus-file-attributes.h1
-rw-r--r--libnautilus-private/nautilus-file-operations.c7
-rw-r--r--libnautilus-private/nautilus-file-private.h25
-rw-r--r--libnautilus-private/nautilus-file.c124
-rw-r--r--libnautilus-private/nautilus-marshal.list1
-rw-r--r--libnautilus-private/nautilus-module.c243
-rw-r--r--libnautilus-private/nautilus-module.h37
-rw-r--r--src/file-manager/fm-directory-view.c3
-rw-r--r--src/nautilus-application.c4
25 files changed, 1348 insertions, 240 deletions
diff --git a/ChangeLog b/ChangeLog
index 3f65e630e..afb8336db 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,61 @@
+2003-11-20 Dave Camp <dave@ximian.com>
+
+ * Makefile.am:
+ * configure.in:
+ * libnautilus-extension/Makefile.am:
+ * libnautilus-extension/libnautilus-extension.pc.in:
+ * libnautilus-extension/nautilus-extension-types.c:
+ * libnautilus-extension/nautilus-extension-types.h:
+ * libnautilus-extension/nautilus-file-info.c:
+ * libnautilus-extension/nautilus-file-info.h:
+ * libnautilus-extension/nautilus-info-provider.c:
+ * libnautilus-extension/nautilus-info-provider.h:
+ New library for nautilus extensions.
+
+ * libnautilus-private/nautilus-marshal.list:
+ * libnautilus-private/Makefile.am:
+ * libnautilus-private/nautilus-directory-async.c:
+ (nautilus_directory_set_up_request), (lacks_extension_info),
+ (wants_extension_info), (extension_info_cancel),
+ (extension_info_stop), (finish_info_provider),
+ (info_provider_idle_callback), (info_provider_callback),
+ (extension_info_start), (start_or_stop_io),
+ (nautilus_directory_cancel), (cancel_loading_attributes),
+ (file_needs_extension_work_done), (file_needs_work_done),
+ (nautilus_directory_remove_file_from_work_queue),
+ (move_file_to_low_priority_queue), (move_file_to_extension_queue):
+ * libnautilus-private/nautilus-directory-private.h:
+ * libnautilus-private/nautilus-directory.c:
+ (nautilus_directory_init), (nautilus_directory_finalize),
+ (nautilus_directory_notify_files_changed):
+ Add a third queue for extension info, that runs after the high
+ and low priority queues.
+
+ * libnautilus-private/nautilus-file-attributes.h:
+ * libnautilus-private/nautilus-file-operations.c:
+ * libnautilus-private/nautilus-file-private.h:
+ * libnautilus-private/nautilus-file.c:
+ (nautilus_file_invalidate_extension_info_internal),
+ (nautilus_file_invalidate_attributes_internal):
+
+ * libnautilus-private/nautilus-file.c:
+ (nautilus_file_get_type), (nautilus_file_instance_init),
+ (nautilus_file_get_keywords), (nautilus_file_get_type),
+ (nautilus_file_class_init), (nautilus_file_get_vfs_file_info),
+ (nautilus_file_add_emblem), (nautilus_file_info_providers_done),
+ (nautilus_file_info_iface_init): Implement the NautilusFileInfo
+ interface for extensions to use.
+
+ * libnautilus-private/nautilus-module.c: (nautilus_module_load),
+ * libnautilus-private/nautilus-module.h:
+ Module loading code.
+
+ * src/file-manager/fm-directory-view.c: (finish_loading):
+ Request extension info.
+
+ * src/nautilus-application.c: (finish_startup): Initialize the
+ module interface.
+
2003-11-19 James Willcox <jwillcox@gnome.org>
* libnautilus-private/nautilus-icon-canvas-item.c:
diff --git a/Makefile.am b/Makefile.am
index 871ece7e5..3ad326b2c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -16,6 +16,7 @@ DESKTOP_SETTINGS_FILES= \
SUBDIRS = \
libnautilus \
+ libnautilus-extension \
cut-n-paste-code \
libbackground \
libnautilus-private \
diff --git a/components/services/nautilus-dependent-shared/shared-service-widgets.c b/components/services/nautilus-dependent-shared/shared-service-widgets.c
deleted file mode 100644
index c88adcbd9..000000000
--- a/components/services/nautilus-dependent-shared/shared-service-widgets.c
+++ /dev/null
@@ -1,212 +0,0 @@
-/* -*- 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.
- *
- * Authors: Ramiro Estrugo <ramiro@eazel.com>
- * J Shane Culpepper <pepper@eazel.com>
- *
- */
-
-#include <config.h>
-
-#include "shared-service-widgets.h"
-
-#include <libnautilus-extensions/nautilus-background.h>
-#include <libnautilus-extensions/nautilus-gdk-pixbuf-extensions.h>
-#include <libnautilus-extensions/nautilus-gtk-extensions.h>
-#include <libnautilus-extensions/nautilus-gtk-macros.h>
-#include <libnautilus-extensions/nautilus-glib-extensions.h>
-#include <libnautilus-extensions/nautilus-global-preferences.h>
-#include <libnautilus-extensions/nautilus-file-utilities.h>
-#include <libnautilus-extensions/nautilus-string.h>
-#include <libnautilus-extensions/nautilus-font-factory.h>
-#include <libnautilus-extensions/nautilus-gdk-extensions.h>
-#include <libnautilus-extensions/nautilus-theme.h>
-
-#include <stdio.h>
-
-/* private shared helper routine to create an image widget from a pixbuf */
-static GtkWidget*
-create_image_widget_from_pixbuf (GdkPixbuf *icon_pixbuf,
- const char *tile_icon_name)
-{
- GtkWidget *image_widget;
-
- g_return_val_if_fail (icon_pixbuf || tile_icon_name, NULL);
-
- image_widget = nautilus_image_new ();
-
- if (icon_pixbuf != NULL) {
- nautilus_image_set_pixbuf (NAUTILUS_IMAGE (image_widget), icon_pixbuf);
- }
-
- if (tile_icon_name != NULL) {
- char *tile_icon_path;
-
- tile_icon_path = nautilus_pixmap_file (tile_icon_name);
-
- if (tile_icon_path != NULL) {
- GdkPixbuf *tile_icon_pixbuf;
- tile_icon_pixbuf = gdk_pixbuf_new_from_file (tile_icon_path);
- g_free (tile_icon_path);
-
- if (tile_icon_pixbuf != NULL) {
- nautilus_buffered_widget_set_tile_pixbuf (NAUTILUS_BUFFERED_WIDGET (image_widget), tile_icon_pixbuf);
- gdk_pixbuf_unref (tile_icon_pixbuf);
- }
- else {
- g_warning ("Could not find the requested tile_icon: %s", tile_icon_path);
- }
- }
- }
-
- return image_widget;
-}
-
-/* create and return an image widget using a themed nautilus icon name and a tiled background */
-GtkWidget*
-create_image_widget (const char *icon_name, const char *tile_icon_name)
-{
- GtkWidget *image_widget;
- GdkPixbuf *pixbuf;
-
- g_return_val_if_fail (icon_name || tile_icon_name, NULL);
-
- pixbuf = NULL;
- if (icon_name != NULL) {
- char *icon_path;
-
- icon_path = nautilus_theme_get_image_path (icon_name);
- if (icon_path != NULL) {
- pixbuf = gdk_pixbuf_new_from_file (icon_path);
- g_free (icon_path);
-
- if (pixbuf == NULL) {
- g_warning ("Could not find the requested icon: %s", icon_path);
- }
- }
- }
-
- /* create the image widget then release the pixbuf*/
- image_widget = create_image_widget_from_pixbuf (pixbuf, tile_icon_name);
- if (pixbuf != NULL) {
- gdk_pixbuf_unref (pixbuf);
- }
- return image_widget;
-}
-
-/* create and return an image widget from a uri and a tiled background.
- It also pins the image to the specified dimensions */
-
-/* FIXME bugzilla.eazel.com 5138
- * this calls gnome-vfs synchronously for an HTTP uri and thus can block
- * the UI indefinitely
- */
-GtkWidget*
-create_image_widget_from_uri (const char *uri, const char *tile_icon_name,
- int max_width, int max_height)
-{
- GtkWidget *image_widget;
- GdkPixbuf *pixbuf, *scaled_pixbuf;
-
- g_return_val_if_fail (uri || tile_icon_name, NULL);
-
- /* as an optimization, it can be a local file. If it doesn't start with http://,
- just pass it on to create_image_widget */
- if (!nautilus_istr_has_prefix (uri, "http://")) {
- return create_image_widget (uri, tile_icon_name);
- }
-
- /* load the image - synchronously, at least at first */
- pixbuf = nautilus_gdk_pixbuf_load (uri);
-
- /* pin the image to the specified dimensions if necessary */
- if (pixbuf && max_width > 0 && max_height > 0) {
- scaled_pixbuf = nautilus_gdk_pixbuf_scale_down_to_fit (pixbuf, max_width, max_height);
- gdk_pixbuf_unref (pixbuf);
- pixbuf = scaled_pixbuf;
- }
-
- /* create the image widget then release the pixbuf*/
- image_widget = create_image_widget_from_pixbuf (pixbuf, tile_icon_name);
- if (pixbuf != NULL) {
- gdk_pixbuf_unref (pixbuf);
- }
-
- return image_widget;
-}
-
-/* create a label widget with anti-aliased text and a tiled image background */
-GtkWidget*
-create_label_widget (const char *text,
- guint font_size,
- const char *tile_icon_name,
- guint xpad,
- guint ypad,
- gint horizontal_offset,
- gint vertical_offset)
-{
- GtkWidget *label;
-
- g_return_val_if_fail (text != NULL, NULL);
- g_return_val_if_fail (font_size > 0, NULL);
-
- label = nautilus_label_new (text);
-
- nautilus_label_set_font_from_components (NAUTILUS_LABEL (label), "helvetica", "bold", NULL, NULL);
- nautilus_label_set_font_size (NAUTILUS_LABEL (label), font_size);
- nautilus_label_set_text_color (NAUTILUS_LABEL (label), NAUTILUS_RGB_COLOR_WHITE);
-
- if (tile_icon_name != NULL) {
- char *tile_icon_path;
-
- tile_icon_path = nautilus_pixmap_file (tile_icon_name);
-
- if (tile_icon_path != NULL) {
- GdkPixbuf *tile_icon_pixbuf;
- tile_icon_pixbuf = gdk_pixbuf_new_from_file (tile_icon_path);
- g_free (tile_icon_path);
-
- if (tile_icon_pixbuf != NULL) {
- nautilus_buffered_widget_set_tile_pixbuf (NAUTILUS_BUFFERED_WIDGET (label), tile_icon_pixbuf);
- gdk_pixbuf_unref (tile_icon_pixbuf);
- }
- else {
- g_warning ("Could not find the requested tile_icon: %s", tile_icon_path);
- }
- }
- }
-
- gtk_misc_set_padding (GTK_MISC (label), xpad, ypad);
-
- nautilus_buffered_widget_set_vertical_offset (NAUTILUS_BUFFERED_WIDGET (label), vertical_offset);
- nautilus_buffered_widget_set_horizontal_offset (NAUTILUS_BUFFERED_WIDGET (label), horizontal_offset);
-
- return label;
-}
-
-/* utility routine to show an error message */
-void
-show_feedback (GtkWidget *widget,
- char *error_message)
-{
- nautilus_label_set_text (NAUTILUS_LABEL (widget), error_message);
- gtk_widget_show (widget);
-}
-
diff --git a/configure.in b/configure.in
index 8c8ebf023..75145e199 100644
--- a/configure.in
+++ b/configure.in
@@ -325,6 +325,13 @@ AC_SUBST(LIBNAUTILUS_LIBS)
LIBNAUTILUS_IDL_INCLUDES="`$PKG_CONFIG --variable=idldir $LIBNAUTILUS_MODULES | $srcdir/add-include-prefix`"
AC_SUBST(LIBNAUTILUS_IDL_INCLUDES)
+dnl libnautilus-extension
+LIBNAUTILUS_EXTENSION_MODULES="glib-2.0 gtk+-2.0 gnome-vfs-2.0"
+LIBNAUTILUS_EXTENSION_CFLAGS="`$PKG_CONFIG --cflags $LIBNAUTILUS_EXTENSION_MODULES`"
+AC_SUBST(LIBNAUTILUS_EXTENSION_CFLAGS)
+LIBNAUTILUS_EXTENSION_LIBS="`$PKG_CONFIG --libs $LIBNAUTILUS_EXTENSION_MODULES`"
+AC_SUBST(LIBNAUTILUS_EXTENSION_LIBS)
+
dnl core nautilus (must list bonobo-activation and libbonobo because idldir does not respect "requires")
CORE_MODULES="eel-2.0 librsvg-2.0 bonobo-activation-2.0 libbonobo-2.0 libbonoboui-2.0 esound gnome-desktop-2.0 $EXTRA_CORE_MODULES"
CORE_CFLAGS="`$PKG_CONFIG --cflags $CORE_MODULES` $x_cflags"
@@ -425,6 +432,8 @@ libnautilus-adapter/Makefile
libnautilus-private/Makefile
libnautilus/Makefile
libnautilus/libnautilus.pc
+libnautilus-extension/Makefile
+libnautilus-extension/libnautilus-extension.pc
nautilus.spec
po/Makefile.in
src/Makefile
diff --git a/libnautilus-extension/Makefile.am b/libnautilus-extension/Makefile.am
new file mode 100644
index 000000000..4d79b380f
--- /dev/null
+++ b/libnautilus-extension/Makefile.am
@@ -0,0 +1,38 @@
+include $(top_srcdir)/Makefile.shared
+
+lib_LTLIBRARIES=libnautilus-extension.la
+
+INCLUDES=\
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(LIBNAUTILUS_EXTENSION_CFLAGS) \
+ $(DISABLE_DEPRECATED_CFLAGS) \
+ -DDATADIR=\""$(datadir)"\" \
+ $(NULL)
+
+libnautilus_extension_la_LDFLAGS=\
+ -version-info 1:0:0 \
+ $(LIBNAUTILUS_EXTENSION_LIBS) \
+ -no-undefined \
+ $(NULL)
+
+libnautilus_extension_includedir=$(includedir)/nautilus/libnautilus-extension
+
+libnautilus_extension_include_HEADERS= \
+ nautilus-extension-types.h \
+ nautilus-file-info.h \
+ nautilus-info-provider.h \
+ $(NULL)
+
+libnautilus_extension_la_SOURCES= \
+ nautilus-extension-types.c \
+ nautilus-file-info.c \
+ nautilus-info-provider.c \
+ $(NULL)
+
+pkgconfigdir=$(libdir)/pkgconfig
+pkgconfig_DATA=libnautilus-extension.pc
+
+EXTRA_DIST = \
+ libnautilus-extension.pc.in \
+ $(NULL)
diff --git a/libnautilus-extension/libnautilus-extension.pc.in b/libnautilus-extension/libnautilus-extension.pc.in
new file mode 100644
index 000000000..5286e9b9b
--- /dev/null
+++ b/libnautilus-extension/libnautilus-extension.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libnautilus-extension
+Description: A library to create Nautilus view extensions
+Version: @VERSION@
+Requires: glib-2.0 gtk+-2.0 gnome-vfs-2.0
+Libs: -L${libdir} -lnautilus-extension
+Cflags: -I${includedir}/nautilus
diff --git a/libnautilus-extension/nautilus-extension-types.c b/libnautilus-extension/nautilus-extension-types.c
new file mode 100644
index 000000000..ee815fc10
--- /dev/null
+++ b/libnautilus-extension/nautilus-extension-types.c
@@ -0,0 +1,57 @@
+/*
+ * nautilus-extension-types.c - Type definitions for Nautilus extensions
+ *
+ * Copyright (C) 2003 Novell, Inc.
+ *
+ * This 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.
+ *
+ * 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Author: Dave Camp <dave@ximian.com>
+ *
+ */
+
+#include <config.h>
+#include "nautilus-extension-types.h"
+
+
+GType
+nautilus_operation_result_get_type (void)
+{
+ static GType type = 0;
+ if (type == 0) {
+ static const GEnumValue values[] = {
+ {
+ NAUTILUS_OPERATION_COMPLETE,
+ "NAUTILUS_OPERATION_COMPLETE",
+ "complete",
+ },
+ {
+ NAUTILUS_OPERATION_FAILED,
+ "NAUTILUS_OPERATION_FAILED",
+ "failed",
+ },
+ {
+ NAUTILUS_OPERATION_IN_PROGRESS,
+ "NAUTILUS_OPERATION_IN_PROGRESS",
+ "in_progress",
+ },
+ { 0, NULL, NULL }
+ };
+
+ type = g_enum_register_static ("NautilusOperationResult",
+ values);
+ }
+
+ return type;
+}
diff --git a/libnautilus-extension/nautilus-extension-types.h b/libnautilus-extension/nautilus-extension-types.h
new file mode 100644
index 000000000..806d17118
--- /dev/null
+++ b/libnautilus-extension/nautilus-extension-types.h
@@ -0,0 +1,67 @@
+/*
+ * nautilus-info-provider.h - Type definitions for Nautilus extensions
+ *
+ * Copyright (C) 2003 Novell, Inc.
+ *
+ * This 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.
+ *
+ * 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Author: Dave Camp <dave@ximian.com>
+ *
+ */
+
+/* This interface is implemented by Nautilus extensions that want to
+ * provide information about files. Extensions are called when Nautilus
+ * needs information about a file. They are passed a NautilusFileInfo
+ * object which should be filled with relevant information */
+
+#ifndef NAUTILUS_EXTENSION_TYPES_H
+#define NAUTILUS_EXTENSION_TYPES_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define NAUTILUS_TYPE_OPERATION_RESULT (nautilus_operation_result_get_type ())
+
+/* Handle for asynchronous interfaces. These are opaque handles that must
+ * be unique within an extension object. These are returned by operations
+ * that return NAUTILUS_OPERATION_IN_PROGRESS */
+typedef struct _NautilusOperationHandle NautilusOperationHandle;
+
+typedef enum {
+ /* Returned if the call succeeded, and the extension is done
+ * with the request */
+ NAUTILUS_OPERATION_COMPLETE,
+
+ /* Returned if the call failed */
+ NAUTILUS_OPERATION_FAILED,
+
+ /* Returned if the extension has begun an async operation.
+ * If this is returned, the extension must set the handle
+ * parameter and call the callback closure when the
+ * operation is complete. */
+ NAUTILUS_OPERATION_IN_PROGRESS,
+} NautilusOperationResult;
+
+GType nautilus_operation_result_get_type (void);
+
+void nautilus_module_initialize (GTypeModule *module);
+void nautilus_module_shutdown (void);
+void nautilus_module_list_types (const GType **types,
+ int *num_types);
+
+G_END_DECLS
+
+#endif
diff --git a/libnautilus-extension/nautilus-file-info.c b/libnautilus-extension/nautilus-file-info.c
new file mode 100644
index 000000000..2bbc2f4ec
--- /dev/null
+++ b/libnautilus-extension/nautilus-file-info.c
@@ -0,0 +1,140 @@
+/*
+ * nautilus-file-info.c - Information about a file
+ *
+ * Copyright (C) 2003 Novell, Inc.
+ *
+ * This 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.
+ *
+ * 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <config.h>
+#include "nautilus-file-info.h"
+
+static void
+nautilus_file_info_base_init (gpointer g_class)
+{
+}
+
+GType
+nautilus_file_info_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ static const GTypeInfo info = {
+ sizeof (NautilusFileInfoIface),
+ nautilus_file_info_base_init,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ 0,
+ 0,
+ NULL
+ };
+
+ type = g_type_register_static (G_TYPE_INTERFACE,
+ "NautilusFileInfo",
+ &info, 0);
+ g_type_interface_add_prerequisite (type, G_TYPE_OBJECT);
+ }
+
+ return type;
+}
+
+gboolean
+nautilus_file_info_is_gone (NautilusFileInfo *file)
+{
+ g_return_val_if_fail (NAUTILUS_IS_FILE_INFO (file), FALSE);
+ g_return_val_if_fail (NAUTILUS_FILE_INFO_GET_IFACE (file)->is_gone != NULL, FALSE);
+
+ return NAUTILUS_FILE_INFO_GET_IFACE (file)->is_gone (file);
+}
+
+char *
+nautilus_file_info_get_name (NautilusFileInfo *file)
+{
+ g_return_val_if_fail (NAUTILUS_IS_FILE_INFO (file), NULL);
+ g_return_val_if_fail (NAUTILUS_FILE_INFO_GET_IFACE (file)->get_name != NULL, NULL);
+
+ return NAUTILUS_FILE_INFO_GET_IFACE (file)->get_name (file);
+}
+
+char *
+nautilus_file_info_get_uri (NautilusFileInfo *file)
+{
+ g_return_val_if_fail (NAUTILUS_IS_FILE_INFO (file), NULL);
+ g_return_val_if_fail (NAUTILUS_FILE_INFO_GET_IFACE (file)->get_uri != NULL, NULL);
+
+ return NAUTILUS_FILE_INFO_GET_IFACE (file)->get_uri (file);
+}
+
+char *
+nautilus_file_info_get_parent_uri (NautilusFileInfo *file)
+{
+ g_return_val_if_fail (NAUTILUS_IS_FILE_INFO (file), NULL);
+ g_return_val_if_fail (NAUTILUS_FILE_INFO_GET_IFACE (file)->get_uri != NULL, NULL);
+
+ return NAUTILUS_FILE_INFO_GET_IFACE (file)->get_parent_uri (file);
+}
+
+char *
+nautilus_file_info_get_mime_type (NautilusFileInfo *file)
+{
+ g_return_val_if_fail (NAUTILUS_IS_FILE_INFO (file), NULL);
+ g_return_val_if_fail (NAUTILUS_FILE_INFO_GET_IFACE (file)->get_mime_type != NULL, NULL);
+
+ return NAUTILUS_FILE_INFO_GET_IFACE (file)->get_mime_type (file);
+}
+
+gboolean
+nautilus_file_info_is_mime_type (NautilusFileInfo *file,
+ const char *mime_type)
+{
+ g_return_val_if_fail (NAUTILUS_IS_FILE_INFO (file), FALSE);
+ g_return_val_if_fail (mime_type != NULL, FALSE);
+ g_return_val_if_fail (NAUTILUS_FILE_INFO_GET_IFACE (file)->is_mime_type != NULL, FALSE);
+
+ return NAUTILUS_FILE_INFO_GET_IFACE (file)->is_mime_type (file,
+ mime_type);
+}
+
+gboolean
+nautilus_file_info_is_directory (NautilusFileInfo *file)
+{
+ g_return_val_if_fail (NAUTILUS_IS_FILE_INFO (file), FALSE);
+ g_return_val_if_fail (NAUTILUS_FILE_INFO_GET_IFACE (file)->is_directory != NULL, FALSE);
+
+ return NAUTILUS_FILE_INFO_GET_IFACE (file)->is_directory (file);
+}
+
+GnomeVFSFileInfo *
+nautilus_file_info_get_vfs_file_info (NautilusFileInfo *file)
+{
+ g_return_val_if_fail (NAUTILUS_IS_FILE_INFO (file), NULL);
+ g_return_val_if_fail (NAUTILUS_FILE_INFO_GET_IFACE (file)->get_vfs_file_info != NULL, NULL);
+
+ return NAUTILUS_FILE_INFO_GET_IFACE (file)->get_vfs_file_info (file);
+}
+
+void
+nautilus_file_info_add_emblem (NautilusFileInfo *file,
+ const char *emblem_name)
+{
+ g_return_if_fail (NAUTILUS_IS_FILE_INFO (file));
+ g_return_if_fail (NAUTILUS_FILE_INFO_GET_IFACE (file)->get_vfs_file_info != NULL);
+
+ NAUTILUS_FILE_INFO_GET_IFACE (file)->add_emblem (file, emblem_name);
+}
diff --git a/libnautilus-extension/nautilus-file-info.h b/libnautilus-extension/nautilus-file-info.h
new file mode 100644
index 000000000..fc73e8648
--- /dev/null
+++ b/libnautilus-extension/nautilus-file-info.h
@@ -0,0 +1,102 @@
+/*
+ * nautilus-file-info.h - Information about a file
+ *
+ * Copyright (C) 2003 Novell, Inc.
+ *
+ * This 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.
+ *
+ * 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+/* NautilusFileInfo is an interface to the NautilusFile object. It
+ * provides access to the asynchronous data in the NautilusFile.
+ * Extensions are passed objects of this type for operations. */
+
+#ifndef NAUTILUS_FILE_INFO_H
+#define NAUTILUS_FILE_INFO_H
+
+#include <glib-object.h>
+#include <libgnomevfs/gnome-vfs-file-info.h>
+
+G_BEGIN_DECLS
+
+#define NAUTILUS_TYPE_FILE_INFO (nautilus_file_info_get_type ())
+#define NAUTILUS_FILE_INFO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_FILE_INFO, NautilusFileInfo))
+#define NAUTILUS_IS_FILE_INFO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NAUTILUS_TYPE_FILE_INFO))
+#define NAUTILUS_FILE_INFO_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NAUTILUS_TYPE_FILE_INFO, NautilusFileInfoIface))
+
+
+#ifndef NAUTILUS_FILE_DEFINED
+#define NAUTILUS_FILE_DEFINED
+/* Using NautilusFile for the vtable to make implementing this in
+ * NautilusFile easier */
+typedef struct NautilusFile NautilusFile;
+#endif
+
+typedef NautilusFile NautilusFileInfo;
+typedef struct _NautilusFileInfoIface NautilusFileInfoIface;
+
+
+struct _NautilusFileInfoIface
+{
+ gboolean (*is_gone) (NautilusFileInfo *file);
+
+ char * (*get_name) (NautilusFileInfo *file);
+ char * (*get_uri) (NautilusFileInfo *file);
+ char * (*get_parent_uri) (NautilusFileInfo *file);
+
+ char * (*get_mime_type) (NautilusFileInfo *file);
+ gboolean (*is_mime_type) (NautilusFileInfo *file,
+ const char *mime_Type);
+ gboolean (*is_directory) (NautilusFileInfo *file);
+
+ GnomeVFSFileInfo *(*get_vfs_file_info) (NautilusFileInfo *file);
+
+ void (*add_emblem) (NautilusFileInfo *file,
+ const char *emblem_name);
+
+};
+
+GType nautilus_file_info_get_type (void);
+
+
+/* Return true if the file has been deleted */
+gboolean nautilus_file_info_is_gone (NautilusFileInfo *file);
+
+
+/* Name and Location */
+char * nautilus_file_info_get_name (NautilusFileInfo *file);
+char * nautilus_file_info_get_uri (NautilusFileInfo *file);
+char * nautilus_file_info_get_parent_uri (NautilusFileInfo *file);
+
+
+/* File Type */
+char * nautilus_file_info_get_mime_type (NautilusFileInfo *file);
+gboolean nautilus_file_info_is_mime_type (NautilusFileInfo *file,
+ const char *mime_type);
+gboolean nautilus_file_info_is_directory (NautilusFileInfo *file);
+
+
+/* Other File Info */
+GnomeVFSFileInfo *nautilus_file_info_get_vfs_file_info (NautilusFileInfo *file);
+
+
+/* Modifying the NautilusFileInfo */
+void nautilus_file_info_add_emblem (NautilusFileInfo *file,
+ const char *emblem_name);
+
+
+G_END_DECLS
+
+#endif
diff --git a/libnautilus-extension/nautilus-info-provider.c b/libnautilus-extension/nautilus-info-provider.c
new file mode 100644
index 000000000..942245190
--- /dev/null
+++ b/libnautilus-extension/nautilus-info-provider.c
@@ -0,0 +1,120 @@
+/*
+ * nautilus-info-provider.c - Interface for Nautilus extensions that
+ * provide info about files.
+ *
+ * Copyright (C) 2003 Novell, Inc.
+ *
+ * This 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.
+ *
+ * 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Author: Dave Camp <dave@ximian.com>
+ *
+ */
+
+#include <config.h>
+#include "nautilus-info-provider.h"
+
+#include <glib-object.h>
+
+static void
+nautilus_info_provider_base_init (gpointer g_class)
+{
+}
+
+GType
+nautilus_info_provider_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ static const GTypeInfo info = {
+ sizeof (NautilusInfoProviderIface),
+ nautilus_info_provider_base_init,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ 0,
+ 0,
+ NULL
+ };
+
+ type = g_type_register_static (G_TYPE_INTERFACE,
+ "NautilusInfoProvider",
+ &info, 0);
+ g_type_interface_add_prerequisite (type, G_TYPE_OBJECT);
+ }
+
+ return type;
+}
+
+NautilusOperationResult
+nautilus_info_provider_update_file_info (NautilusInfoProvider *provider,
+ NautilusFileInfo *file,
+ GClosure *update_complete,
+ NautilusOperationHandle **handle)
+{
+ g_return_val_if_fail (NAUTILUS_IS_INFO_PROVIDER (provider),
+ NAUTILUS_OPERATION_FAILED);
+ g_return_val_if_fail (NAUTILUS_INFO_PROVIDER_GET_IFACE (provider)->update_file_info != NULL,
+ NAUTILUS_OPERATION_FAILED);
+ g_return_val_if_fail (update_complete != NULL,
+ NAUTILUS_OPERATION_FAILED);
+ g_return_val_if_fail (handle != NULL, NAUTILUS_OPERATION_FAILED);
+
+ return NAUTILUS_INFO_PROVIDER_GET_IFACE (provider)->update_file_info
+ (provider, file, update_complete, handle);
+}
+
+void
+nautilus_info_provider_cancel_update (NautilusInfoProvider *provider,
+ NautilusOperationHandle *handle)
+{
+ g_return_if_fail (NAUTILUS_IS_INFO_PROVIDER (provider));
+ g_return_if_fail (NAUTILUS_INFO_PROVIDER_GET_IFACE (provider)->cancel_update != NULL);
+ g_return_if_fail (NAUTILUS_INFO_PROVIDER_GET_IFACE (provider)->cancel_update != NULL);
+ g_return_if_fail (handle != NULL);
+
+ NAUTILUS_INFO_PROVIDER_GET_IFACE (provider)->cancel_update (provider,
+ handle);
+}
+
+void
+nautilus_info_provider_update_complete_invoke (GClosure *update_complete,
+ NautilusInfoProvider *provider,
+ NautilusOperationHandle *handle,
+ NautilusOperationResult result)
+{
+ GValue args[3] = { { 0, } };
+ GValue return_val = { 0, };
+
+ g_return_if_fail (update_complete != NULL);
+ g_return_if_fail (NAUTILUS_IS_INFO_PROVIDER (provider));
+
+ g_value_init (&args[0], NAUTILUS_TYPE_INFO_PROVIDER);
+ g_value_init (&args[1], G_TYPE_POINTER);
+ g_value_init (&args[2], NAUTILUS_TYPE_OPERATION_RESULT);
+
+ g_value_set_object (&args[0], provider);
+ g_value_set_pointer (&args[1], handle);
+ g_value_set_enum (&args[2], result);
+
+ g_closure_invoke (update_complete, &return_val, 3, args, NULL);
+
+ g_value_unset (&args[0]);
+ g_value_unset (&args[1]);
+ g_value_unset (&args[2]);
+}
+
+
diff --git a/libnautilus-extension/nautilus-info-provider.h b/libnautilus-extension/nautilus-info-provider.h
new file mode 100644
index 000000000..50e01d4c0
--- /dev/null
+++ b/libnautilus-extension/nautilus-info-provider.h
@@ -0,0 +1,80 @@
+/*
+ * nautilus-info-provider.h - Interface for Nautilus extensions that
+ * provide info about files.
+ *
+ * Copyright (C) 2003 Novell, Inc.
+ *
+ * This 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.
+ *
+ * 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Author: Dave Camp <dave@ximian.com>
+ *
+ */
+
+/* This interface is implemented by Nautilus extensions that want to
+ * provide information about files. Extensions are called when Nautilus
+ * needs information about a file. They are passed a NautilusFileInfo
+ * object which should be filled with relevant information */
+
+#ifndef NAUTILUS_INFO_PROVIDER_H
+#define NAUTILUS_INFO_PROVIDER_H
+
+#include <glib-object.h>
+#include "nautilus-extension-types.h"
+#include "nautilus-file-info.h"
+
+G_BEGIN_DECLS
+
+#define NAUTILUS_TYPE_INFO_PROVIDER (nautilus_info_provider_get_type ())
+#define NAUTILUS_INFO_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_INFO_PROVIDER, NautilusInfoProvider))
+#define NAUTILUS_IS_INFO_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NAUTILUS_TYPE_INFO_PROVIDER))
+#define NAUTILUS_INFO_PROVIDER_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NAUTILUS_TYPE_INFO_PROVIDER, NautilusInfoProviderIface))
+
+typedef struct _NautilusInfoProvider NautilusInfoProvider;
+typedef struct _NautilusInfoProviderIface NautilusInfoProviderIface;
+
+typedef void (*NautilusInfoProviderUpdateComplete) (NautilusInfoProvider *provider,
+ NautilusOperationHandle *handle,
+ NautilusOperationResult result,
+ gpointer user_data);
+
+struct _NautilusInfoProviderIface {
+ NautilusOperationResult (*update_file_info) (NautilusInfoProvider *provider,
+ NautilusFileInfo *file,
+ GClosure *update_complete,
+ NautilusOperationHandle **handle);
+ void (*cancel_update) (NautilusInfoProvider *provider,
+ NautilusOperationHandle *handle);
+};
+
+/* Interface Functions */
+GType nautilus_info_provider_get_type (void);
+NautilusOperationResult nautilus_info_provider_update_file_info (NautilusInfoProvider *provider,
+ NautilusFileInfo *file,
+ GClosure *update_complete,
+ NautilusOperationHandle **handle);
+void nautilus_info_provider_cancel_update (NautilusInfoProvider *provider,
+ NautilusOperationHandle *handle);
+
+
+
+/* Helper functions for implementations */
+void nautilus_info_provider_update_complete_invoke (GClosure *update_complete,
+ NautilusInfoProvider *provider,
+ NautilusOperationHandle *handle,
+ NautilusOperationResult result);
+
+G_END_DECLS
+
+#endif
diff --git a/libnautilus-private/Makefile.am b/libnautilus-private/Makefile.am
index 8d66a8601..06e425617 100644
--- a/libnautilus-private/Makefile.am
+++ b/libnautilus-private/Makefile.am
@@ -2,7 +2,9 @@ include $(top_srcdir)/Makefile.shared
lib_LTLIBRARIES=libnautilus-private.la
-libnautilus_private_la_LIBADD = ../libnautilus/libnautilus.la
+libnautilus_private_la_LIBADD = \
+ ../libnautilus/libnautilus.la \
+ ../libnautilus-extension/libnautilus-extension.la
INCLUDES = \
-I$(top_srcdir) \
@@ -13,6 +15,7 @@ INCLUDES = \
-DDATADIR=\""$(datadir)"\" \
-DSYSCONFDIR=\""$(sysconfdir)"\" \
-DNAUTILUS_DATADIR=\""$(datadir)/nautilus"\" \
+ -DNAUTILUS_EXTENSIONDIR=\""$(libdir)/nautilus/extensions-1.0"\" \
$(NULL)
dependency_static_libs = \
@@ -138,6 +141,8 @@ libnautilus_private_la_SOURCES = \
nautilus-metafile.h \
nautilus-mime-actions.c \
nautilus-mime-actions.h \
+ nautilus-module.c \
+ nautilus-module.h \
nautilus-monitor.c \
nautilus-monitor.h \
nautilus-program-chooser.c \
diff --git a/libnautilus-private/nautilus-directory-async.c b/libnautilus-private/nautilus-directory-async.c
index 343dd4db3..ab6394dd7 100644
--- a/libnautilus-private/nautilus-directory-async.c
+++ b/libnautilus-private/nautilus-directory-async.c
@@ -32,6 +32,7 @@
#include "nautilus-file-utilities.h"
#include "nautilus-global-preferences.h"
#include "nautilus-link.h"
+#include "nautilus-marshal.h"
#include "nautilus-metafile.h"
#include "nautilus-search-uri.h"
#include <eel/eel-glib-extensions.h>
@@ -94,6 +95,13 @@ typedef struct {
Request request;
} Monitor;
+typedef struct {
+ NautilusDirectory *directory;
+ NautilusInfoProvider *provider;
+ NautilusOperationHandle *handle;
+ NautilusOperationResult result;
+} InfoProviderResponse;
+
typedef gboolean (* RequestCheck) (const Request *);
typedef gboolean (* FileCheck) (NautilusFile *);
@@ -127,8 +135,12 @@ static gboolean file_needs_high_priority_work_done (NautilusDirectory *directory
NautilusFile *file);
static gboolean file_needs_low_priority_work_done (NautilusDirectory *directory,
NautilusFile *file);
+static gboolean file_needs_extension_work_done (NautilusDirectory *directory,
+ NautilusFile *file);
static void move_file_to_low_priority_queue (NautilusDirectory *directory,
NautilusFile *file);
+static void move_file_to_extension_queue (NautilusDirectory *directory,
+ NautilusFile *file);
void
@@ -571,6 +583,8 @@ nautilus_directory_set_up_request (Request *request,
request->metafile |= (file_attributes &
NAUTILUS_FILE_ATTRIBUTE_METADATA) != FALSE;
+
+ request->extension_info = (file_attributes & NAUTILUS_FILE_ATTRIBUTE_EXTENSION_INFO) != FALSE;
}
static void
@@ -1748,6 +1762,17 @@ wants_link_info (const Request *request)
return request->link_info;
}
+static gboolean
+lacks_extension_info (NautilusFile *file)
+{
+ return file->details->pending_info_providers != NULL;
+}
+
+static gboolean
+wants_extension_info (const Request *request)
+{
+ return request->extension_info;
+}
static gboolean
has_problem (NautilusDirectory *directory, NautilusFile *file, FileCheck problem)
@@ -3136,6 +3161,153 @@ link_info_start (NautilusDirectory *directory,
}
static void
+extension_info_cancel (NautilusDirectory *directory)
+{
+ if (directory->details->extension_info_in_progress != NULL) {
+ nautilus_info_provider_cancel_update
+ (directory->details->extension_info_provider,
+ directory->details->extension_info_in_progress);
+
+ directory->details->extension_info_in_progress = NULL;
+ directory->details->extension_info_file = NULL;
+ directory->details->extension_info_provider = NULL;
+
+ async_job_end (directory, "extension info");
+ }
+}
+
+static void
+extension_info_stop (NautilusDirectory *directory)
+{
+ if (directory->details->extension_info_in_progress != NULL) {
+ NautilusFile *file;
+
+ file = directory->details->extension_info_file;
+ if (file != NULL) {
+ g_assert (NAUTILUS_IS_FILE (file));
+ g_assert (file->details->directory == directory);
+ if (is_needy (file, lacks_extension_info, wants_extension_info)) {
+ return;
+ }
+ }
+
+ /* The info is not wanted, so stop it. */
+ extension_info_cancel (directory);
+ }
+}
+
+static void
+finish_info_provider (NautilusDirectory *directory,
+ NautilusFile *file,
+ NautilusInfoProvider *provider)
+{
+ file->details->pending_info_providers =
+ g_list_remove (file->details->pending_info_providers,
+ provider);
+ g_object_unref (provider);
+
+ nautilus_directory_async_state_changed (directory);
+
+ if (file->details->pending_info_providers == NULL) {
+ nautilus_file_info_providers_done (file);
+ }
+}
+
+
+static gboolean
+info_provider_idle_callback (gpointer user_data)
+{
+ InfoProviderResponse *response;
+ NautilusDirectory *directory;
+
+ response = user_data;
+ directory = response->directory;
+
+ if (response->handle != directory->details->extension_info_in_progress
+ || response->provider != directory->details->extension_info_provider) {
+ g_warning ("Unexpected plugin response. This probably indicates a bug in a Nautilus extension: handle=%p", response->handle);
+ } else {
+ NautilusFile *file;
+ async_job_end (directory, "extension info");
+
+ file = directory->details->extension_info_file;
+
+ directory->details->extension_info_file = NULL;
+ directory->details->extension_info_provider = NULL;
+ directory->details->extension_info_in_progress = NULL;
+
+ finish_info_provider (directory, file, response->provider);
+ }
+
+ return FALSE;
+}
+
+static void
+info_provider_callback (NautilusInfoProvider *provider,
+ NautilusOperationHandle *handle,
+ NautilusOperationResult result,
+ gpointer user_data)
+{
+ InfoProviderResponse *response;
+
+ response = g_new0 (InfoProviderResponse, 1);
+ response->provider = provider;
+ response->handle = handle;
+ response->result = result;
+ response->directory = NAUTILUS_DIRECTORY (user_data);
+
+ g_idle_add (info_provider_idle_callback, response);
+}
+
+static void
+extension_info_start (NautilusDirectory *directory,
+ NautilusFile *file)
+{
+ NautilusInfoProvider *provider;
+ NautilusOperationResult result;
+ NautilusOperationHandle *handle;
+ GClosure *update_complete;
+
+ if (directory->details->extension_info_in_progress != NULL) {
+ return;
+ }
+
+ if (!is_needy (file, lacks_extension_info, wants_extension_info)) {
+ return;
+ }
+
+ if (!async_job_start (directory, "extension info")) {
+ return;
+ }
+
+ provider = file->details->pending_info_providers->data;
+
+ update_complete = g_cclosure_new (G_CALLBACK (info_provider_callback),
+ directory,
+ NULL);
+ g_closure_set_marshal (update_complete,
+ nautilus_marshal_VOID__POINTER_ENUM);
+
+ result = nautilus_info_provider_update_file_info
+ (provider,
+ NAUTILUS_FILE_INFO (file),
+ update_complete,
+ &handle);
+
+ g_closure_unref (update_complete);
+
+ if (result == NAUTILUS_OPERATION_COMPLETE ||
+ result == NAUTILUS_OPERATION_FAILED) {
+ finish_info_provider (directory, file, provider);
+ async_job_end (directory, "extension info");
+ } else {
+ directory->details->extension_info_in_progress = handle;
+ directory->details->extension_info_provider = provider;
+ directory->details->extension_info_file = file;
+ }
+}
+
+static void
start_or_stop_io (NautilusDirectory *directory)
{
NautilusFile *file;
@@ -3150,6 +3322,7 @@ start_or_stop_io (NautilusDirectory *directory)
mime_list_stop (directory);
top_left_stop (directory);
link_info_stop (directory);
+ extension_info_stop (directory);
/* Take files that are all done off the queue. */
while (!nautilus_file_queue_is_empty (directory->details->high_priority_queue)) {
@@ -3177,6 +3350,20 @@ start_or_stop_io (NautilusDirectory *directory)
top_left_start (directory, file);
return;
} else {
+ move_file_to_extension_queue (directory, file);
+
+ }
+ }
+
+ /* Low priority queue must be empty */
+ while (!nautilus_file_queue_is_empty (directory->details->extension_queue)) {
+ file = nautilus_file_queue_head (directory->details->extension_queue);
+
+ if (file_needs_extension_work_done (directory, file)) {
+ /* Start getting attributes if possible */
+ extension_info_start (directory, file);
+ return;
+ } else {
nautilus_directory_remove_file_from_work_queue (directory, file);
}
@@ -3228,6 +3415,7 @@ nautilus_directory_cancel (NautilusDirectory *directory)
link_info_cancel (directory);
mime_list_cancel (directory);
top_left_cancel (directory);
+ extension_info_cancel (directory);
/* We aren't waiting for anything any more. */
if (waiting_directories != NULL) {
@@ -3322,6 +3510,10 @@ cancel_loading_attributes (NautilusDirectory *directory,
if (request.link_info) {
link_info_cancel (directory);
}
+
+ if (request.extension_info) {
+ extension_info_cancel (directory);
+ }
/* FIXME bugzilla.gnome.org 45064: implement cancelling metadata when we
implement invalidating metadata */
@@ -3407,11 +3599,23 @@ file_needs_low_priority_work_done (NautilusDirectory *directory,
}
static gboolean
+file_needs_extension_work_done (NautilusDirectory *directory,
+ NautilusFile *file)
+{
+ if (is_needy (file, lacks_extension_info, wants_extension_info)) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
file_needs_work_done (NautilusDirectory *directory,
NautilusFile *file)
{
return (file_needs_high_priority_work_done (directory, file) ||
- file_needs_low_priority_work_done (directory, file));
+ file_needs_low_priority_work_done (directory, file) ||
+ file_needs_extension_work_done (directory, file));
}
@@ -3451,6 +3655,8 @@ nautilus_directory_remove_file_from_work_queue (NautilusDirectory *directory,
file);
nautilus_file_queue_remove (directory->details->low_priority_queue,
file);
+ nautilus_file_queue_remove (directory->details->extension_queue,
+ file);
}
@@ -3458,15 +3664,32 @@ static void
move_file_to_low_priority_queue (NautilusDirectory *directory,
NautilusFile *file)
{
+ /* Must add before removing to avoid ref underflow */
+ nautilus_file_queue_enqueue (directory->details->low_priority_queue,
+ file);
+ nautilus_file_queue_remove (directory->details->high_priority_queue,
+ file);
+
if (!file_needs_low_priority_work_done (directory, file)) {
- nautilus_file_queue_remove (directory->details->high_priority_queue,
+ move_file_to_extension_queue (directory, file);
+
+ return;
+ }
+}
+
+static void
+move_file_to_extension_queue (NautilusDirectory *directory,
+ NautilusFile *file)
+{
+ if (!file_needs_extension_work_done (directory, file)) {
+ nautilus_file_queue_remove (directory->details->low_priority_queue,
file);
return;
}
/* Must add before removing to avoid ref underflow */
- nautilus_file_queue_enqueue (directory->details->low_priority_queue,
+ nautilus_file_queue_enqueue (directory->details->extension_queue,
file);
- nautilus_file_queue_remove (directory->details->high_priority_queue,
+ nautilus_file_queue_remove (directory->details->low_priority_queue,
file);
}
diff --git a/libnautilus-private/nautilus-directory-private.h b/libnautilus-private/nautilus-directory-private.h
index fc4cd5d72..9dc3bae98 100644
--- a/libnautilus-private/nautilus-directory-private.h
+++ b/libnautilus-private/nautilus-directory-private.h
@@ -33,6 +33,7 @@
#include <libnautilus-private/nautilus-metafile-server.h>
#include <libnautilus-private/nautilus-monitor.h>
#include <libnautilus/nautilus-idle-queue.h>
+#include <libnautilus-extension/nautilus-info-provider.h>
#include <libxml/tree.h>
typedef struct LinkInfoReadState LinkInfoReadState;
@@ -53,6 +54,7 @@ struct NautilusDirectoryDetails
/* Queues of files needing some I/O done. */
NautilusFileQueue *high_priority_queue;
NautilusFileQueue *low_priority_queue;
+ NautilusFileQueue *extension_queue;
/* These lists are going to be pretty short. If we think they
* are going to get big, we can use hash tables instead.
@@ -100,6 +102,10 @@ struct NautilusDirectoryDetails
NautilusFile *get_info_file;
GnomeVFSAsyncHandle *get_info_in_progress;
+ NautilusFile *extension_info_file;
+ NautilusInfoProvider *extension_info_provider;
+ NautilusOperationHandle *extension_info_in_progress;
+
TopLeftTextReadState *top_left_read_state;
LinkInfoReadState *link_info_read_state;
@@ -119,6 +125,7 @@ typedef struct {
gboolean metafile;
gboolean mime_list;
gboolean top_left_text;
+ gboolean extension_info;
} Request;
NautilusDirectory *nautilus_directory_get_existing (const char *uri);
diff --git a/libnautilus-private/nautilus-directory.c b/libnautilus-private/nautilus-directory.c
index 1c20e942f..7c2fd2e19 100644
--- a/libnautilus-private/nautilus-directory.c
+++ b/libnautilus-private/nautilus-directory.c
@@ -133,6 +133,7 @@ nautilus_directory_init (gpointer object, gpointer klass)
directory->details->file_hash = g_hash_table_new (g_str_hash, g_str_equal);
directory->details->high_priority_queue = nautilus_file_queue_new ();
directory->details->low_priority_queue = nautilus_file_queue_new ();
+ directory->details->extension_queue = nautilus_file_queue_new ();
directory->details->idle_queue = nautilus_idle_queue_new ();
directory->details->hidden_file_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
@@ -207,6 +208,7 @@ nautilus_directory_finalize (GObject *object)
nautilus_file_queue_destroy (directory->details->high_priority_queue);
nautilus_file_queue_destroy (directory->details->low_priority_queue);
+ nautilus_file_queue_destroy (directory->details->extension_queue);
nautilus_idle_queue_destroy (directory->details->idle_queue);
g_assert (directory->details->directory_load_in_progress == NULL);
g_assert (directory->details->count_in_progress == NULL);
@@ -1023,6 +1025,7 @@ nautilus_directory_notify_files_changed (GList *uris)
file->details->file_info_is_up_to_date = FALSE;
file->details->top_left_text_is_up_to_date = FALSE;
file->details->link_info_is_up_to_date = FALSE;
+ nautilus_file_invalidate_extension_info_internal (file);
hash_table_list_prepend (changed_lists,
file->details->directory,
diff --git a/libnautilus-private/nautilus-file-attributes.h b/libnautilus-private/nautilus-file-attributes.h
index 38e1da94f..ba02bd426 100644
--- a/libnautilus-private/nautilus-file-attributes.h
+++ b/libnautilus-private/nautilus-file-attributes.h
@@ -43,6 +43,7 @@ typedef enum {
NAUTILUS_FILE_ATTRIBUTE_TOP_LEFT_TEXT = 1 << 10,
NAUTILUS_FILE_ATTRIBUTE_DISPLAY_NAME = 1 << 11,
NAUTILUS_FILE_ATTRIBUTE_VOLUMES = 1 << 12,
+ NAUTILUS_FILE_ATTRIBUTE_EXTENSION_INFO = 1 << 13,
} NautilusFileAttributes;
#endif /* NAUTILUS_FILE_ATTRIBUTES_H */
diff --git a/libnautilus-private/nautilus-file-operations.c b/libnautilus-private/nautilus-file-operations.c
index 3f9586caf..2278f8771 100644
--- a/libnautilus-private/nautilus-file-operations.c
+++ b/libnautilus-private/nautilus-file-operations.c
@@ -37,14 +37,19 @@
#include <eel/eel-stock-dialogs.h>
#include <eel/eel-vfs-extensions.h>
-#include <gnome.h>
+#include <libgnome/gnome-i18n.h>
#include <gtk/gtklabel.h>
+#include <gtk/gtkstock.h>
+#include <gtk/gtkhbox.h>
+#include <gtk/gtkimage.h>
+#include <gtk/gtkvbox.h>
#include <libgnomevfs/gnome-vfs-async-ops.h>
#include <libgnomevfs/gnome-vfs-find-directory.h>
#include <libgnomevfs/gnome-vfs-ops.h>
#include <libgnomevfs/gnome-vfs-result.h>
#include <libgnomevfs/gnome-vfs-uri.h>
#include <libgnomevfs/gnome-vfs-utils.h>
+#include <stdio.h>
#include "nautilus-file-changes-queue.h"
#include "nautilus-file-private.h"
#include "nautilus-desktop-icon-file.h"
diff --git a/libnautilus-private/nautilus-file-private.h b/libnautilus-private/nautilus-file-private.h
index 443f57da7..b7aae13db 100644
--- a/libnautilus-private/nautilus-file-private.h
+++ b/libnautilus-private/nautilus-file-private.h
@@ -93,7 +93,14 @@ struct NautilusFileDetails
/* We use this to cache automatic emblems and emblem keywords
to speed up compare_by_emblems. */
NautilusFileSortByEmblemCache *compare_by_emblem_cache;
-
+
+ /* NautilusInfoProviders that need to be run for this file */
+ GList *pending_info_providers;
+
+ /* Emblems provided by extensions */
+ GList *extension_emblems;
+ GList *pending_extension_emblems;
+
/* boolean fields: bitfield to save space, since there can be
many NautilusFile objects. */
@@ -171,13 +178,15 @@ gboolean nautilus_file_should_get_top_left_text (NautilusFile
/* Mark specified attributes for this file out of date without canceling current
* I/O or kicking off new I/O.
*/
-void nautilus_file_invalidate_attributes_internal (NautilusFile *file,
- NautilusFileAttributes file_attributes);
-NautilusFileAttributes nautilus_file_get_all_attributes (void);
-gboolean nautilus_file_is_self_owned (NautilusFile *file);
-void nautilus_file_invalidate_count_and_mime_list (NautilusFile *file);
-gboolean nautilus_file_rename_in_progress (NautilusFile *file);
-GnomeVFSFileInfo * nautilus_file_peek_vfs_file_info (NautilusFile *file);
+void nautilus_file_invalidate_attributes_internal (NautilusFile *file,
+ NautilusFileAttributes file_attributes);
+NautilusFileAttributes nautilus_file_get_all_attributes (void);
+gboolean nautilus_file_is_self_owned (NautilusFile *file);
+void nautilus_file_invalidate_count_and_mime_list (NautilusFile *file);
+gboolean nautilus_file_rename_in_progress (NautilusFile *file);
+GnomeVFSFileInfo * nautilus_file_peek_vfs_file_info (NautilusFile *file);
+void nautilus_file_invalidate_extension_info_internal (NautilusFile *file);
+void nautilus_file_info_providers_done (NautilusFile *file);
/* Thumbnailing: */
diff --git a/libnautilus-private/nautilus-file.c b/libnautilus-private/nautilus-file.c
index 1dee388cc..77d5fc121 100644
--- a/libnautilus-private/nautilus-file.c
+++ b/libnautilus-private/nautilus-file.c
@@ -39,6 +39,7 @@
#include "nautilus-link.h"
#include "nautilus-link-desktop-file.h"
#include "nautilus-metadata.h"
+#include "nautilus-module.h"
#include "nautilus-thumbnails.h"
#include "nautilus-trash-directory.h"
#include "nautilus-trash-file.h"
@@ -59,6 +60,7 @@
#include <libgnomevfs/gnome-vfs-volume.h>
#include <libgnomevfs/gnome-vfs-volume-monitor.h>
#include <libgnomevfs/gnome-vfs-drive.h>
+#include <libnautilus-extension/nautilus-file-info.h>
#include <libxml/parser.h>
#include <pwd.h>
#include <stdlib.h>
@@ -110,24 +112,62 @@ enum {
static guint signals[LAST_SIGNAL];
-static GHashTable *symbolic_links;
-
-static char * nautilus_file_get_owner_as_string (NautilusFile *file,
- gboolean include_real_name);
-static char * nautilus_file_get_type_as_string (NautilusFile *file);
-static gboolean update_info_and_name (NautilusFile *file,
- GnomeVFSFileInfo *info);
-static char * nautilus_file_get_display_name_nocopy (NautilusFile *file);
-static char * nautilus_file_get_display_name_collation_key (NautilusFile *file);
+static GObjectClass *parent_class = NULL;
+static GHashTable *symbolic_links;
-GNOME_CLASS_BOILERPLATE (NautilusFile, nautilus_file,
- GObject, G_TYPE_OBJECT)
+static void nautilus_file_instance_init (NautilusFile *file);
+static void nautilus_file_class_init (NautilusFileClass *class);
+static void nautilus_file_info_iface_init (NautilusFileInfoIface *iface);
+static char * nautilus_file_get_owner_as_string (NautilusFile *file,
+ gboolean include_real_name);
+static char * nautilus_file_get_type_as_string (NautilusFile *file);
+static gboolean update_info_and_name (NautilusFile *file,
+ GnomeVFSFileInfo *info);
+static char * nautilus_file_get_display_name_nocopy (NautilusFile *file);
+static char * nautilus_file_get_display_name_collation_key (NautilusFile *file);
+
+GType
+nautilus_file_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ static const GTypeInfo info = {
+ sizeof (NautilusFileClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) nautilus_file_class_init,
+ NULL,
+ NULL,
+ sizeof (NautilusFile),
+ 0,
+ (GInstanceInitFunc) nautilus_file_instance_init,
+ };
+
+ static const GInterfaceInfo file_info_iface_info = {
+ (GInterfaceInitFunc) nautilus_file_info_iface_init,
+ NULL,
+ NULL
+ };
+
+ type = g_type_register_static (G_TYPE_OBJECT,
+ "NautilusFile",
+ &info, 0);
+ g_type_add_interface_static (type,
+ NAUTILUS_TYPE_FILE_INFO,
+ &file_info_iface_info);
+ }
+
+ return type;
+}
static void
nautilus_file_instance_init (NautilusFile *file)
{
file->details = g_new0 (NautilusFileDetails, 1);
+
+ nautilus_file_invalidate_extension_info_internal (file);
}
static NautilusFile *
@@ -4695,7 +4735,10 @@ nautilus_file_get_keywords (NautilusFile *file)
/* Put all the keywords into a list. */
keywords = nautilus_file_get_metadata_list
(file, "keyword", "name");
-
+
+ keywords = g_list_concat (keywords, eel_g_str_list_copy (file->details->extension_emblems));
+ keywords = g_list_concat (keywords, eel_g_str_list_copy (file->details->pending_extension_emblems));
+
return sort_keyword_list_and_remove_duplicates (keywords);
}
@@ -5279,7 +5322,6 @@ invalidate_directory_count (NautilusFile *file)
file->details->directory_count_is_up_to_date = FALSE;
}
-
static void
invalidate_deep_counts (NautilusFile *file)
{
@@ -5311,6 +5353,13 @@ invalidate_link_info (NautilusFile *file)
}
void
+nautilus_file_invalidate_extension_info_internal (NautilusFile *file)
+{
+ file->details->pending_info_providers =
+ nautilus_module_get_extensions_for_type (NAUTILUS_TYPE_INFO_PROVIDER);
+}
+
+void
nautilus_file_invalidate_attributes_internal (NautilusFile *file,
NautilusFileAttributes file_attributes)
{
@@ -5348,6 +5397,9 @@ nautilus_file_invalidate_attributes_internal (NautilusFile *file,
if (request.link_info) {
invalidate_link_info (file);
}
+ if (request.extension_info) {
+ nautilus_file_invalidate_extension_info_internal (file);
+ }
/* FIXME bugzilla.gnome.org 45075: implement invalidating metadata */
}
@@ -5619,6 +5671,8 @@ nautilus_extract_top_left_text (const char *text,
static void
nautilus_file_class_init (NautilusFileClass *class)
{
+ parent_class = g_type_class_peek_parent (class);
+
G_OBJECT_CLASS (class)->finalize = finalize;
signals[CHANGED] =
@@ -5640,6 +5694,50 @@ nautilus_file_class_init (NautilusFileClass *class)
G_TYPE_NONE, 0);
}
+static GnomeVFSFileInfo *
+nautilus_file_get_vfs_file_info (NautilusFile *file)
+{
+ return gnome_vfs_file_info_dup (file->details->info);
+}
+
+static void
+nautilus_file_add_emblem (NautilusFile *file,
+ const char *emblem_name)
+{
+ if (file->details->pending_info_providers) {
+ file->details->pending_extension_emblems = g_list_prepend (file->details->pending_extension_emblems,
+ g_strdup (emblem_name));
+ } else {
+ file->details->extension_emblems = g_list_prepend (file->details->extension_emblems,
+ g_strdup (emblem_name));
+ }
+
+ nautilus_file_changed (file);
+}
+
+void
+nautilus_file_info_providers_done (NautilusFile *file)
+{
+ eel_g_list_free_deep (file->details->extension_emblems);
+ file->details->extension_emblems = file->details->pending_extension_emblems;
+ file->details->pending_extension_emblems = NULL;
+ nautilus_file_changed (file);
+}
+
+static void
+nautilus_file_info_iface_init (NautilusFileInfoIface *iface)
+{
+ iface->is_gone = nautilus_file_is_gone;
+ iface->get_name = nautilus_file_get_name;
+ iface->get_uri = nautilus_file_get_uri;
+ iface->get_parent_uri = nautilus_file_get_parent_uri;
+ iface->get_mime_type = nautilus_file_get_mime_type;
+ iface->is_mime_type = nautilus_file_is_mime_type;
+ iface->is_directory = nautilus_file_is_directory;
+ iface->get_vfs_file_info = nautilus_file_get_vfs_file_info;
+ iface->add_emblem = nautilus_file_add_emblem;
+}
+
#if !defined (NAUTILUS_OMIT_SELF_CHECK)
void
diff --git a/libnautilus-private/nautilus-marshal.list b/libnautilus-private/nautilus-marshal.list
index c0d617827..3261b785f 100644
--- a/libnautilus-private/nautilus-marshal.list
+++ b/libnautilus-private/nautilus-marshal.list
@@ -13,3 +13,4 @@ VOID:POINTER,STRING
VOID:STRING,STRING
VOID:POINTER,POINTER,POINTER,INT,INT,INT
VOID:POINTER,STRING,UINT,INT,INT
+VOID:POINTER,ENUM
diff --git a/libnautilus-private/nautilus-module.c b/libnautilus-private/nautilus-module.c
new file mode 100644
index 000000000..b61269dd0
--- /dev/null
+++ b/libnautilus-private/nautilus-module.c
@@ -0,0 +1,243 @@
+/*
+ * nautilus-module.h - Interface to nautilus extensions
+ *
+ * Copyright (C) 2003 Novell, Inc.
+ *
+ * This 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.
+ *
+ * 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Author: Dave Camp <dave@ximian.com>
+ *
+ */
+
+#include <config.h>
+#include "nautilus-module.h"
+
+#include <eel/eel-gtk-macros.h>
+#include <gmodule.h>
+#include <libgnome/gnome-macros.h>
+
+
+#define NAUTILUS_TYPE_MODULE (nautilus_module_get_type ())
+#define NAUTILUS_MODULE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_MODULE, NautilusModule))
+#define NAUTILUS_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_MODULE, NautilusModule))
+#define NAUTILUS_IS_MODULE(obj) (G_TYPE_INSTANCE_CHECK_TYPE ((obj), NAUTILUS_TYPE_MODULE))
+#define NAUTILUS_IS_MODULE_CLASS(klass) (G_TYPE_CLASS_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_MODULE))
+
+typedef struct _NautilusModule NautilusModule;
+typedef struct _NautilusModuleClass NautilusModuleClass;
+
+struct _NautilusModule {
+ GTypeModule parent;
+
+ GModule *library;
+
+ char *path;
+
+ void (*initialize) (GTypeModule *module);
+ void (*shutdown) (void);
+
+ void (*list_types) (const GType **types,
+ int *num_types);
+
+};
+
+struct _NautilusModuleClass {
+ GTypeModuleClass parent;
+};
+
+static GType nautilus_module_get_type (void);
+
+static GList *module_objects = NULL;
+
+GNOME_CLASS_BOILERPLATE (NautilusModule,
+ nautilus_module,
+ GTypeModule,
+ G_TYPE_TYPE_MODULE);
+
+static gboolean
+nautilus_module_load (GTypeModule *gmodule)
+{
+ NautilusModule *module;
+
+ module = NAUTILUS_MODULE (gmodule);
+
+ module->library = g_module_open (module->path, 0);
+
+ if (!module->library) {
+ g_warning (g_module_error ());
+ return FALSE;
+ }
+
+ if (!g_module_symbol (module->library,
+ "nautilus_module_initialize",
+ (gpointer *)&module->initialize) ||
+ !g_module_symbol (module->library,
+ "nautilus_module_shutdown",
+ (gpointer *)&module->shutdown) ||
+ !g_module_symbol (module->library,
+ "nautilus_module_list_types",
+ (gpointer *)&module->list_types)) {
+
+ g_warning (g_module_error ());
+ g_module_close (module->library);
+
+ return FALSE;
+ }
+
+ module->initialize (gmodule);
+
+ return TRUE;
+}
+
+static void
+nautilus_module_unload (GTypeModule *gmodule)
+{
+ NautilusModule *module;
+
+ module = NAUTILUS_MODULE (gmodule);
+
+ module->shutdown ();
+
+ g_module_close (module->library);
+
+ module->initialize = NULL;
+ module->shutdown = NULL;
+ module->list_types = NULL;
+}
+
+static void
+nautilus_module_finalize (GObject *object)
+{
+ NautilusModule *module;
+
+ module = NAUTILUS_MODULE (object);
+
+ g_free (module->path);
+
+ EEL_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
+}
+
+static void
+nautilus_module_instance_init (NautilusModule *module)
+{
+}
+
+static void
+nautilus_module_class_init (NautilusModuleClass *class)
+{
+ G_OBJECT_CLASS (class)->finalize = nautilus_module_finalize;
+ G_TYPE_MODULE_CLASS (class)->load = nautilus_module_load;
+ G_TYPE_MODULE_CLASS (class)->unload = nautilus_module_unload;
+}
+
+static void
+module_object_weak_notify (gpointer user_data, GObject *object)
+{
+ module_objects = g_list_remove (module_objects, object);
+}
+
+static void
+add_module_objects (NautilusModule *module)
+{
+ const GType *types;
+ int num_types;
+ int i;
+
+ module->list_types (&types, &num_types);
+
+ for (i = 0; i < num_types; i++) {
+ GObject *object;
+
+ object = g_object_new (types[i], NULL);
+ g_object_weak_ref (object,
+ (GWeakNotify)module_object_weak_notify,
+ NULL);
+
+ module_objects = g_list_prepend (module_objects, object);
+ }
+}
+
+static NautilusModule *
+nautilus_module_load_file (const char *filename)
+{
+ NautilusModule *module;
+
+ g_print ("loading %s\n", filename);
+ module = g_object_new (NAUTILUS_TYPE_MODULE, NULL);
+ module->path = g_strdup (filename);
+
+ if (g_type_module_use (G_TYPE_MODULE (module))) {
+ add_module_objects (module);
+ g_type_module_unuse (G_TYPE_MODULE (module));
+ return module;
+ } else {
+ g_object_unref (module);
+ return NULL;
+ }
+}
+
+static void
+load_module_dir (const char *dirname)
+{
+ GDir *dir;
+
+ dir = g_dir_open (dirname, 0, NULL);
+
+ if (dir) {
+ const char *name;
+
+ while ((name = g_dir_read_name (dir))) {
+ if (g_str_has_suffix (name, "." G_MODULE_SUFFIX)) {
+ char *filename;
+
+ filename = g_build_filename (dirname,
+ name,
+ NULL);
+ nautilus_module_load_file (filename);
+ }
+ }
+
+ g_dir_close (dir);
+ }
+}
+
+void
+nautilus_module_init (void)
+{
+ static gboolean initialized = FALSE;
+
+ if (!initialized) {
+ initialized = TRUE;
+
+ load_module_dir (NAUTILUS_EXTENSIONDIR);
+ }
+}
+
+GList *
+nautilus_module_get_extensions_for_type (GType type)
+{
+ GList *l;
+ GList *ret = NULL;
+
+ for (l = module_objects; l != NULL; l = l->next) {
+ if (G_TYPE_CHECK_INSTANCE_TYPE (G_OBJECT (l->data),
+ type)) {
+ g_object_ref (l->data);
+ ret = g_list_prepend (ret, l->data);
+ }
+ }
+
+ return ret;
+}
diff --git a/libnautilus-private/nautilus-module.h b/libnautilus-private/nautilus-module.h
new file mode 100644
index 000000000..ef3f20408
--- /dev/null
+++ b/libnautilus-private/nautilus-module.h
@@ -0,0 +1,37 @@
+/*
+ * nautilus-module.h - Interface to nautilus extensions
+ *
+ * Copyright (C) 2003 Novell, Inc.
+ *
+ * This 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.
+ *
+ * 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Author: Dave Camp <dave@ximian.com>
+ *
+ */
+
+#ifndef NAUTILUS_MODULE_H
+#define NAUTILUS_MODULE_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+void nautilus_module_init (void);
+GList *nautilus_module_get_extensions_for_type (GType type);
+
+
+G_END_DECLS
+
+#endif
diff --git a/src/file-manager/fm-directory-view.c b/src/file-manager/fm-directory-view.c
index 18a124655..717e8e8e8 100644
--- a/src/file-manager/fm-directory-view.c
+++ b/src/file-manager/fm-directory-view.c
@@ -5908,7 +5908,8 @@ finish_loading (FMDirectoryView *view)
attributes |= NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_COUNT |
NAUTILUS_FILE_ATTRIBUTE_METADATA |
NAUTILUS_FILE_ATTRIBUTE_MIME_TYPE |
- NAUTILUS_FILE_ATTRIBUTE_DISPLAY_NAME;
+ NAUTILUS_FILE_ATTRIBUTE_DISPLAY_NAME |
+ NAUTILUS_FILE_ATTRIBUTE_EXTENSION_INFO;
nautilus_directory_file_monitor_add (view->details->model,
&view->details->model,
diff --git a/src/nautilus-application.c b/src/nautilus-application.c
index aab7fe3f6..cb1d7a23a 100644
--- a/src/nautilus-application.c
+++ b/src/nautilus-application.c
@@ -70,6 +70,7 @@
#include <libnautilus-private/nautilus-global-preferences.h>
#include <libnautilus-private/nautilus-icon-factory.h>
#include <libnautilus-private/nautilus-metafile-factory.h>
+#include <libnautilus-private/nautilus-module.h>
#include <libnautilus-private/nautilus-sound.h>
#include <libnautilus-private/nautilus-bonobo-extensions.h>
#include <libnautilus-private/nautilus-undo-manager.h>
@@ -390,6 +391,9 @@ create_starthere_link_callback (gpointer data)
static void
finish_startup (NautilusApplication *application)
{
+ /* initialize nautilus modules */
+ nautilus_module_init ();
+
/* initialize the sound machinery */
nautilus_sound_init ();