summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Soriano <csoriano@gnome.org>2016-04-13 18:13:51 +0200
committerCarlos Soriano <csoriano@gnome.org>2016-04-13 18:13:51 +0200
commitca856bdd290835c66237553d81001454a6cf0803 (patch)
treea624e248b2ecc3816e7740900fafd2c0ba88a709
parentb57716c80b1b5b55b6a8c05aa6bf21242b0afc8b (diff)
downloadnautilus-ca856bdd290835c66237553d81001454a6cf0803.tar.gz
directory: use gio extensions for directory dispatching
We needed to do some hackish code in order to allow types that are not included in nautilus-directory to dispatch the correct subclass. Instead of that, we can just create a "plugabble" system that allows directory types to be registered in the system, and implement a class vfunc that queries if the class handles a specific type of uri, falling back if none can handle it to the usual nautilus-directory. We can do this for the desktop directory and the search directory.
-rw-r--r--libnautilus-private/nautilus-desktop-directory.c20
-rw-r--r--libnautilus-private/nautilus-desktop-directory.h2
-rw-r--r--libnautilus-private/nautilus-directory.c80
-rw-r--r--libnautilus-private/nautilus-directory.h8
-rw-r--r--libnautilus-private/nautilus-file-utilities.c22
-rw-r--r--libnautilus-private/nautilus-file-utilities.h3
-rw-r--r--libnautilus-private/nautilus-search-directory.c19
-rw-r--r--libnautilus-private/nautilus-search-directory.h2
-rw-r--r--src/nautilus-application.c3
-rw-r--r--src/nautilus-desktop-application.c17
10 files changed, 131 insertions, 45 deletions
diff --git a/libnautilus-private/nautilus-desktop-directory.c b/libnautilus-private/nautilus-desktop-directory.c
index 2b610c20e..9f97baaa9 100644
--- a/libnautilus-private/nautilus-desktop-directory.c
+++ b/libnautilus-private/nautilus-desktop-directory.c
@@ -60,9 +60,12 @@ typedef struct {
static void desktop_directory_changed_callback (gpointer data);
-G_DEFINE_TYPE (NautilusDesktopDirectory, nautilus_desktop_directory,
- NAUTILUS_TYPE_DIRECTORY);
-
+G_DEFINE_TYPE_WITH_CODE (NautilusDesktopDirectory, nautilus_desktop_directory, NAUTILUS_TYPE_DIRECTORY,
+ nautilus_ensure_extension_points ();
+ g_io_extension_point_implement (NAUTILUS_DIRECTORY_PROVIDER_EXTENSION_POINT_NAME,
+ g_define_type_id,
+ NAUTILUS_DESKTOP_DIRECTORY_PROVIDER_NAME,
+ 0));
static gboolean
desktop_contains_file (NautilusDirectory *directory,
NautilusFile *file)
@@ -509,6 +512,16 @@ real_new_file_from_filename (NautilusDirectory *directory,
return file;
}
+static gboolean
+real_handles_location (GFile *location)
+{
+ g_autofree gchar *uri;
+
+ uri = g_file_get_uri (location);
+
+ return eel_uri_is_desktop (uri);
+}
+
static void
desktop_directory_changed_callback (gpointer data)
{
@@ -548,6 +561,7 @@ nautilus_desktop_directory_class_init (NautilusDesktopDirectoryClass *class)
directory_class->are_all_files_seen = desktop_are_all_files_seen;
directory_class->is_not_empty = desktop_is_not_empty;
directory_class->new_file_from_filename = real_new_file_from_filename;
+ directory_class->handles_location = real_handles_location;
/* Override get_file_list so that we can return the list of files
* in NautilusDesktopDirectory->details->real_directory,
* in addition to the list of standard desktop icons on the desktop.
diff --git a/libnautilus-private/nautilus-desktop-directory.h b/libnautilus-private/nautilus-desktop-directory.h
index bd7c173f7..9e9dc4949 100644
--- a/libnautilus-private/nautilus-desktop-directory.h
+++ b/libnautilus-private/nautilus-desktop-directory.h
@@ -38,6 +38,8 @@
#define NAUTILUS_DESKTOP_DIRECTORY_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), NAUTILUS_TYPE_DESKTOP_DIRECTORY, NautilusDesktopDirectoryClass))
+#define NAUTILUS_DESKTOP_DIRECTORY_PROVIDER_NAME "desktop-directory-provider"
+
typedef struct NautilusDesktopDirectoryDetails NautilusDesktopDirectoryDetails;
typedef struct {
diff --git a/libnautilus-private/nautilus-directory.c b/libnautilus-private/nautilus-directory.c
index f28d713b0..8b4f63b7e 100644
--- a/libnautilus-private/nautilus-directory.c
+++ b/libnautilus-private/nautilus-directory.c
@@ -66,6 +66,7 @@ static void set_directory_location (NautilusDirectory
static NautilusFile * real_new_file_from_filename (NautilusDirectory *directory,
const char *filename,
gboolean self_owned);
+static gboolean real_handles_location (GFile *location);
G_DEFINE_TYPE (NautilusDirectory, nautilus_directory, G_TYPE_OBJECT);
@@ -160,6 +161,7 @@ nautilus_directory_class_init (NautilusDirectoryClass *klass)
klass->get_file_list = real_get_file_list;
klass->is_editable = real_is_editable;
+ klass->handles_location = real_handles_location;
g_type_class_add_private (klass, sizeof (NautilusDirectoryDetails));
g_object_class_install_properties (object_class, NUM_PROPERTIES, properties);
@@ -453,25 +455,6 @@ nautilus_directory_get_for_file (NautilusFile *file)
return directory;
}
-void
-nautilus_directory_add_to_cache (NautilusDirectory *directory)
-{
- NautilusDirectory *existing_directory;
- GFile *location;
-
- location = nautilus_directory_get_location (directory);
- existing_directory = nautilus_directory_get_existing (location);
- if (existing_directory == NULL) {
- /* Put it in the hash table. */
- g_hash_table_insert (directories,
- directory->details->location,
- directory);
- } else {
- nautilus_directory_unref (existing_directory);
- }
-}
-
-
/* Returns a reffed NautilusFile object for this directory.
*/
NautilusFile *
@@ -564,6 +547,13 @@ nautilus_directory_get_location (NautilusDirectory *directory)
return g_object_ref (directory->details->location);
}
+static gboolean
+real_handles_location (GFile *location)
+{
+ /* This class is the fallback on handling any location */
+ return TRUE;
+}
+
NautilusFile *
nautilus_directory_new_file_from_filename (NautilusDirectory *directory,
const char *filename,
@@ -601,26 +591,52 @@ real_new_file_from_filename (NautilusDirectory *directory,
return file;
}
+static GList*
+nautilus_directory_provider_get_all (void)
+{
+ GIOExtensionPoint *extension_point;
+ GList *extensions;
+
+ extension_point = g_io_extension_point_lookup (NAUTILUS_DIRECTORY_PROVIDER_EXTENSION_POINT_NAME);
+ extensions = g_io_extension_point_get_extensions (extension_point);
+
+ return extensions;
+}
+
static NautilusDirectory *
nautilus_directory_new (GFile *location)
{
- NautilusDirectory *directory;
- GType type;
- char *uri;
-
- uri = g_file_get_uri (location);
+ GList *extensions;
+ GList *l;
+ GIOExtension *gio_extension;
+ GType handling_provider_type;
+ gboolean handled = FALSE;
+ NautilusDirectoryClass *current_provider_class;
+ NautilusDirectory *handling_instance;
+
+ extensions = nautilus_directory_provider_get_all ();
+
+ for (l = extensions; l != NULL; l = l->next) {
+ gio_extension = l->data;
+ current_provider_class = NAUTILUS_DIRECTORY_CLASS (g_io_extension_ref_class (gio_extension));
+ if (current_provider_class->handles_location (location)) {
+ handling_provider_type = g_io_extension_get_type (gio_extension);
+ handled = TRUE;
+ break;
+ }
+ }
- if (eel_uri_is_search (uri)) {
- type = NAUTILUS_TYPE_SEARCH_DIRECTORY;
- } else {
- type = NAUTILUS_TYPE_VFS_DIRECTORY;
- }
+ if (!handled) {
+ /* This class is the fallback for any location */
+ handling_provider_type = NAUTILUS_TYPE_VFS_DIRECTORY;
+ }
- g_free (uri);
+ handling_instance = g_object_new (handling_provider_type,
+ "location", location,
+ NULL);
- directory = g_object_new (type, "location", location, NULL);
- return directory;
+ return handling_instance;
}
gboolean
diff --git a/libnautilus-private/nautilus-directory.h b/libnautilus-private/nautilus-directory.h
index 3fa92f25e..ef5d00c4a 100644
--- a/libnautilus-private/nautilus-directory.h
+++ b/libnautilus-private/nautilus-directory.h
@@ -38,6 +38,8 @@
operations on files.
*/
+#define NAUTILUS_DIRECTORY_PROVIDER_EXTENSION_POINT_NAME "nautilus-directory-provider"
+
#define NAUTILUS_TYPE_DIRECTORY nautilus_directory_get_type()
#define NAUTILUS_DIRECTORY(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_DIRECTORY, NautilusDirectory))
@@ -143,6 +145,10 @@ typedef struct
NautilusFile * (* new_file_from_filename) (NautilusDirectory *directory,
const char *filename,
gboolean self_owned);
+ /* Subclasses can say if they handle the location provided or should the
+ * nautilus file class handle it.
+ */
+ gboolean (* handles_location) (GFile *location);
} NautilusDirectoryClass;
/* Basic GObject requirements. */
@@ -238,8 +244,6 @@ gboolean nautilus_directory_is_editable (NautilusDirector
void nautilus_directory_dump (NautilusDirectory *directory);
-void nautilus_directory_add_to_cache (NautilusDirectory *directory);
-
NautilusFile * nautilus_directory_new_file_from_filename (NautilusDirectory *directory,
const char *filename,
gboolean self_owned);
diff --git a/libnautilus-private/nautilus-file-utilities.c b/libnautilus-private/nautilus-file-utilities.c
index 80303b6ac..df4aa534e 100644
--- a/libnautilus-private/nautilus-file-utilities.c
+++ b/libnautilus-private/nautilus-file-utilities.c
@@ -1147,4 +1147,26 @@ nautilus_self_check_file_utilities (void)
{
}
+void
+nautilus_ensure_extension_builtins (void)
+{
+ g_type_ensure (NAUTILUS_TYPE_SEARCH_DIRECTORY);
+}
+
+void
+nautilus_ensure_extension_points (void)
+{
+ static gsize once_init_value = 0;
+
+ if (g_once_init_enter (&once_init_value))
+ {
+ GIOExtensionPoint *extension_point;
+
+ extension_point = g_io_extension_point_register (NAUTILUS_DIRECTORY_PROVIDER_EXTENSION_POINT_NAME);
+ g_io_extension_point_set_required_type (extension_point, NAUTILUS_TYPE_DIRECTORY);
+
+ g_once_init_leave (&once_init_value, 1);
+ }
+}
+
#endif /* !NAUTILUS_OMIT_SELF_CHECK */
diff --git a/libnautilus-private/nautilus-file-utilities.h b/libnautilus-private/nautilus-file-utilities.h
index d93c40e57..ee5f62498 100644
--- a/libnautilus-private/nautilus-file-utilities.h
+++ b/libnautilus-private/nautilus-file-utilities.h
@@ -95,4 +95,7 @@ gboolean should_handle_content_types (const char * const *content_type);
gboolean nautilus_file_selection_equal (GList *selection_a, GList *selection_b);
+void nautilus_ensure_extension_points (void);
+void nautilus_ensure_extension_builtins (void);
+
#endif /* NAUTILUS_FILE_UTILITIES_H */
diff --git a/libnautilus-private/nautilus-search-directory.c b/libnautilus-private/nautilus-search-directory.c
index 01d07ce9b..ed03ec03d 100644
--- a/libnautilus-private/nautilus-search-directory.c
+++ b/libnautilus-private/nautilus-search-directory.c
@@ -95,8 +95,12 @@ enum {
NUM_PROPERTIES
};
-G_DEFINE_TYPE (NautilusSearchDirectory, nautilus_search_directory,
- NAUTILUS_TYPE_DIRECTORY);
+G_DEFINE_TYPE_WITH_CODE (NautilusSearchDirectory, nautilus_search_directory, NAUTILUS_TYPE_DIRECTORY,
+ nautilus_ensure_extension_points ();
+ g_io_extension_point_implement (NAUTILUS_DIRECTORY_PROVIDER_EXTENSION_POINT_NAME,
+ g_define_type_id,
+ NAUTILUS_SEARCH_DIRECTORY_PROVIDER_NAME,
+ 0));
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
@@ -687,6 +691,16 @@ search_is_editable (NautilusDirectory *directory)
return FALSE;
}
+static gboolean
+real_handles_location (GFile *location)
+{
+ g_autofree gchar *uri;
+
+ uri = g_file_get_uri (location);
+
+ return eel_uri_is_search (uri);
+}
+
static void
search_set_property (GObject *object,
guint property_id,
@@ -859,6 +873,7 @@ nautilus_search_directory_class_init (NautilusSearchDirectoryClass *class)
directory_class->get_file_list = search_get_file_list;
directory_class->is_editable = search_is_editable;
+ directory_class->handles_location = real_handles_location;
properties[PROP_BASE_MODEL] =
g_param_spec_object ("base-model",
diff --git a/libnautilus-private/nautilus-search-directory.h b/libnautilus-private/nautilus-search-directory.h
index dd67f2d04..48f53cc18 100644
--- a/libnautilus-private/nautilus-search-directory.h
+++ b/libnautilus-private/nautilus-search-directory.h
@@ -25,6 +25,8 @@
#include <libnautilus-private/nautilus-directory.h>
#include <libnautilus-private/nautilus-query.h>
+#define NAUTILUS_SEARCH_DIRECTORY_PROVIDER_NAME "search-directory-provider"
+
#define NAUTILUS_TYPE_SEARCH_DIRECTORY nautilus_search_directory_get_type()
#define NAUTILUS_SEARCH_DIRECTORY(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), NAUTILUS_TYPE_SEARCH_DIRECTORY, NautilusSearchDirectory))
diff --git a/src/nautilus-application.c b/src/nautilus-application.c
index c9f4213f4..a84052c85 100644
--- a/src/nautilus-application.c
+++ b/src/nautilus-application.c
@@ -946,6 +946,9 @@ nautilus_application_init (NautilusApplication *self)
NULL);
g_application_add_main_option_entries (G_APPLICATION (self), options);
+
+ nautilus_ensure_extension_points ();
+ nautilus_ensure_extension_builtins ();
}
static void
diff --git a/src/nautilus-desktop-application.c b/src/nautilus-desktop-application.c
index 47af210a9..31ff6e603 100644
--- a/src/nautilus-desktop-application.c
+++ b/src/nautilus-desktop-application.c
@@ -21,6 +21,7 @@
#include "nautilus-desktop-application.h"
#include "nautilus-desktop-window.h"
#include "nautilus-desktop-directory.h"
+#include "nautilus-file-utilities.h"
#include "nautilus-freedesktop-generated.h"
@@ -29,7 +30,6 @@
#include <gdk/gdkx.h>
static NautilusFreedesktopFileManager1 *freedesktop_proxy = NULL;
-static NautilusDirectory *desktop_directory = NULL;
struct _NautilusDesktopApplication
{
@@ -219,13 +219,18 @@ nautilus_desktop_application_class_init (NautilusDesktopApplicationClass *klass)
}
static void
-nautilus_desktop_application_init (NautilusDesktopApplication *self)
+nautilus_desktop_ensure_builtins (void)
{
- g_autoptr (GFile) desktop_location;
+ /* Ensure the type so it can be registered early as a directory extension provider*/
+ g_type_ensure (NAUTILUS_TYPE_DESKTOP_DIRECTORY);
+}
- desktop_location = g_file_new_for_uri (EEL_DESKTOP_URI);
- desktop_directory = g_object_new (NAUTILUS_TYPE_DESKTOP_DIRECTORY, "location", desktop_location, NULL);
- nautilus_directory_add_to_cache (NAUTILUS_DIRECTORY (desktop_directory));
+static void
+nautilus_desktop_application_init (NautilusDesktopApplication *self)
+{
+ nautilus_ensure_extension_points ();
+ nautilus_ensure_extension_builtins ();
+ nautilus_desktop_ensure_builtins ();
}
NautilusDesktopApplication *