[Xfce4-commits] <thunar:jannis/new-shortcuts-pane> Implement lazy loading of regular and network file shortcuts.
Jannis Pohlmann
noreply at xfce.org
Fri Jul 15 21:10:33 CEST 2011
Updating branch refs/heads/jannis/new-shortcuts-pane
to e3bf9971d0478ec2c89531e42eb358e25f3b1e5a (commit)
from adab1506c51f450b95f58160a80a70d3981474da (commit)
commit e3bf9971d0478ec2c89531e42eb358e25f3b1e5a
Author: Jannis Pohlmann <jannis at xfce.org>
Date: Thu Jun 9 18:16:28 2011 +0200
Implement lazy loading of regular and network file shortcuts.
File shortcuts are now created with a GFile that is asynchronously
resolved into a ThunarFile in the background. The ThunarShortcut and its
corresponding ThunarShortcutRow are updated as soon as ThunarFile is
available.
This required several changes to the model, the synchronization between
shortcuts, the model and the rows as well as additional properties for
custom names to override file display names etc.
The next step will be to create file shortcuts with URIs only and
resolve those into GFiles before those are resolved into ThunarFiles.
This will perhaps fix the startup delay issues with current versions of
Thunar.
thunar/thunar-file.c | 70 ++++++++--
thunar/thunar-file.h | 13 +-
thunar/thunar-shortcut-row.c | 118 ++++++++++++----
thunar/thunar-shortcut-row.h | 3 +
thunar/thunar-shortcut.c | 280 ++++++++++++++++++++++++++++++++++-----
thunar/thunar-shortcut.h | 6 +
thunar/thunar-shortcuts-model.c | 78 +++++------
thunar/thunar-shortcuts-view.c | 13 +-
8 files changed, 448 insertions(+), 133 deletions(-)
diff --git a/thunar/thunar-file.c b/thunar/thunar-file.c
index a4e4f79..50564e8 100644
--- a/thunar/thunar-file.c
+++ b/thunar/thunar-file.c
@@ -92,6 +92,11 @@ enum
+/* type definition for asynchronous file loading */
+typedef struct _ThunarFileGetData ThunarFileGetData;
+
+
+
static void thunar_file_info_init (ThunarxFileInfoIface *iface);
static void thunar_file_dispose (GObject *object);
static void thunar_file_finalize (GObject *object);
@@ -127,6 +132,14 @@ static void thunar_file_finish_reload (ThunarFile
+struct _ThunarFileGetData
+{
+ ThunarFileGetFunc func;
+ gpointer user_data;
+};
+
+
+
G_LOCK_DEFINE_STATIC (file_cache_mutex);
@@ -695,11 +708,11 @@ thunar_file_get_async_finish (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
- ThunarFileGetAsyncFunc func = user_data;
- ThunarFile *file;
- GFileInfo *file_info;
- GError *error = NULL;
- GFile *location = G_FILE (object);
+ ThunarFileGetData *data = user_data;
+ ThunarFile *file;
+ GFileInfo *file_info;
+ GError *error = NULL;
+ GFile *location = G_FILE (object);
_thunar_return_if_fail (G_IS_FILE (location));
_thunar_return_if_fail (G_IS_ASYNC_RESULT (result));
@@ -727,7 +740,7 @@ thunar_file_get_async_finish (GObject *object,
G_UNLOCK (file_cache_mutex);
/* pass the loaded file and possible errors to the return function */
- (func) (location, file, error);
+ (data->func) (location, file, error, data->user_data);
/* free the error, if there is any */
if (error != NULL)
@@ -735,6 +748,9 @@ thunar_file_get_async_finish (GObject *object,
/* release the file */
g_object_unref (file);
+
+ /* release the get data */
+ g_slice_free (ThunarFileGetData, data);
}
@@ -743,23 +759,31 @@ thunar_file_get_async_finish (GObject *object,
* thunar_file_get_async:
**/
void
-thunar_file_get_async (GFile *location,
- GCancellable *cancellable,
- ThunarFileGetAsyncFunc func)
+thunar_file_get_async (GFile *location,
+ GCancellable *cancellable,
+ ThunarFileGetFunc func,
+ gpointer user_data)
{
- ThunarFile *file;
+ ThunarFileGetData *data;
+ ThunarFile *file;
_thunar_return_if_fail (G_IS_FILE (location));
+ _thunar_return_if_fail (func != NULL);
/* check if we already have a cached version of that file */
file = thunar_file_cache_lookup (location);
if (G_UNLIKELY (file != NULL))
{
/* call the return function with the file from the cache */
- (func) (location, file, NULL);
+ (func) (location, file, NULL, user_data);
}
else
{
+ /* allocate get data */
+ data = g_slice_new0 (ThunarFileGetData);
+ data->user_data = user_data;
+ data->func = func;
+
/* load the file information asynchronously */
g_file_query_info_async (location,
THUNARX_FILE_INFO_NAMESPACE,
@@ -767,7 +791,7 @@ thunar_file_get_async (GFile *location,
0,
cancellable,
thunar_file_get_async_finish,
- func);
+ data);
}
}
@@ -2957,6 +2981,28 @@ thunar_file_get_custom_icon (const ThunarFile *file)
/**
+ * thunar_file_get_icon:
+ * @file : a #ThunarFile instance.
+ *
+ * Returns the icon for @file if any, else %NULL is returned.
+ *
+ * Return value: the icon for @file or %NULL, the GIcon is owner
+ * by the file, so do not unref it.
+ **/
+GIcon *
+thunar_file_get_icon (const ThunarFile *file)
+{
+ _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL);
+
+ if (file->info == NULL)
+ return NULL;
+
+ return g_file_info_get_icon (file->info);
+}
+
+
+
+/**
* thunar_file_get_preview_icon:
* @file : a #ThunarFile instance.
*
diff --git a/thunar/thunar-file.h b/thunar/thunar-file.h
index 34b970e..ff424ce 100644
--- a/thunar/thunar-file.h
+++ b/thunar/thunar-file.h
@@ -100,13 +100,14 @@ typedef enum /*< flags >*/
#define THUNAR_FILE_EMBLEM_NAME_DESKTOP "emblem-desktop"
/**
- * ThunarFileGetAsyncFunc:
+ * ThunarFileGetFunc:
*
* Callback type for loading #ThunarFile<!---->s asynchronously.
**/
-typedef void (*ThunarFileGetAsyncFunc) (GFile *location,
- ThunarFile *file,
- GError *error);
+typedef void (*ThunarFileGetFunc) (GFile *location,
+ ThunarFile *file,
+ GError *error,
+ gpointer user_data);
struct _ThunarFileClass
{
@@ -142,7 +143,8 @@ ThunarFile *thunar_file_get_for_uri (const gchar *uri,
void thunar_file_get_async (GFile *location,
GCancellable *cancellable,
- ThunarFileGetAsyncFunc func);
+ ThunarFileGetFunc func,
+ gpointer user_data);
gboolean thunar_file_load (ThunarFile *file,
GCancellable *cancellable,
@@ -240,6 +242,7 @@ const gchar *thunar_file_get_thumbnail_path (const ThunarFile *fil
gboolean thunar_file_is_thumbnail (const ThunarFile *file);
void thunar_file_set_thumb_state (ThunarFile *file,
ThunarFileThumbState state);
+GIcon *thunar_file_get_icon (const ThunarFile *file);
GIcon *thunar_file_get_preview_icon (const ThunarFile *file);
gchar *thunar_file_get_icon_name (const ThunarFile *file,
ThunarFileIconState icon_state,
diff --git a/thunar/thunar-shortcut-row.c b/thunar/thunar-shortcut-row.c
index de93e6e..932df87 100644
--- a/thunar/thunar-shortcut-row.c
+++ b/thunar/thunar-shortcut-row.c
@@ -52,6 +52,7 @@ enum
PROP_LABEL,
PROP_EJECT_ICON,
PROP_LOCATION,
+ PROP_FILE,
PROP_VOLUME,
PROP_MOUNT,
PROP_SHORTCUT_TYPE,
@@ -132,6 +133,7 @@ static void thunar_shortcut_row_resolve_and_activate (ThunarShortcutRow
static void thunar_shortcut_row_icon_changed (ThunarShortcutRow *row);
static void thunar_shortcut_row_label_changed (ThunarShortcutRow *row);
static void thunar_shortcut_row_location_changed (ThunarShortcutRow *row);
+static void thunar_shortcut_row_file_changed (ThunarShortcutRow *row);
static void thunar_shortcut_row_eject_icon_changed (ThunarShortcutRow *row);
static void thunar_shortcut_row_volume_changed (ThunarShortcutRow *row);
static void thunar_shortcut_row_mount_changed (ThunarShortcutRow *row);
@@ -160,6 +162,7 @@ struct _ThunarShortcutRow
GIcon *eject_icon;
GFile *location;
+ ThunarFile *file;
GVolume *volume;
GMount *mount;
@@ -248,6 +251,14 @@ thunar_shortcut_row_class_init (ThunarShortcutRowClass *klass)
EXO_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
+ PROP_FILE,
+ g_param_spec_object ("file",
+ "file",
+ "file",
+ THUNAR_TYPE_FILE,
+ EXO_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class,
PROP_VOLUME,
g_param_spec_object ("volume",
"volume",
@@ -411,6 +422,9 @@ thunar_shortcut_row_finalize (GObject *object)
if (row->location != NULL)
g_object_unref (row->location);
+ if (row->file != NULL)
+ g_object_unref (row->file);
+
if (row->volume != NULL)
g_object_unref (row->volume);
@@ -455,6 +469,10 @@ thunar_shortcut_row_get_property (GObject *object,
g_value_set_object (value, row->location);
break;
+ case PROP_FILE:
+ g_value_set_object (value, row->file);
+ break;
+
case PROP_VOLUME:
g_value_set_object (value, row->volume);
break;
@@ -505,6 +523,10 @@ thunar_shortcut_row_set_property (GObject *object,
thunar_shortcut_row_set_location (row, g_value_get_object (value));
break;
+ case PROP_FILE:
+ thunar_shortcut_row_set_file (row, g_value_get_object (value));
+ break;
+
case PROP_VOLUME:
thunar_shortcut_row_set_volume (row, g_value_get_object (value));
break;
@@ -1112,6 +1134,8 @@ thunar_shortcut_row_label_changed (ThunarShortcutRow *row)
{
_thunar_return_if_fail (THUNAR_IS_SHORTCUT_ROW (row));
+ g_debug ("label changed: %s", row->label);
+
/* update the label widget */
gtk_label_set_markup (GTK_LABEL (row->label_widget), row->label);
gtk_widget_set_visible (row->label_widget, row->label != NULL && *row->label != '\0');
@@ -1172,11 +1196,38 @@ thunar_shortcut_row_location_changed (ThunarShortcutRow *row)
static void
-thunar_shortcut_row_volume_changed (ThunarShortcutRow *row)
+thunar_shortcut_row_file_changed (ThunarShortcutRow *row)
{
- GIcon *icon;
- gchar *name;
+ _thunar_return_if_fail (THUNAR_IS_SHORTCUT_ROW (row));
+
+ /* don't update the row based on the file if it's not
+ * a regular or network file */
+ if (row->shortcut_type != THUNAR_SHORTCUT_REGULAR_FILE
+ && row->shortcut_type != THUNAR_SHORTCUT_NETWORK_FILE)
+ {
+ return;
+ }
+
+ if (row->file != NULL)
+ {
+ /* update the visibility of the eject button */
+ if (thunar_file_is_mountable (row->file) && thunar_file_is_mounted (row->file))
+ gtk_widget_set_visible (row->action_button, TRUE);
+ else
+ gtk_widget_set_visible (row->action_button, FALSE);
+ }
+ else
+ {
+ /* update the row based on the location alone */
+ thunar_shortcut_row_location_changed (row);
+ }
+}
+
+
+static void
+thunar_shortcut_row_volume_changed (ThunarShortcutRow *row)
+{
_thunar_return_if_fail (THUNAR_IS_SHORTCUT_ROW (row));
/* don't update the information based on the volume unless
@@ -1189,18 +1240,6 @@ thunar_shortcut_row_volume_changed (ThunarShortcutRow *row)
if (row->volume != NULL)
{
- /* update the label widget */
- name = g_volume_get_name (row->volume);
- gtk_label_set_markup (GTK_LABEL (row->label_widget), name);
- gtk_widget_set_visible (row->label_widget, name != NULL && *name != '\0');
- g_free (name);
-
- /* update the icon image */
- icon = g_volume_get_icon (row->volume);
- gtk_image_set_from_gicon (GTK_IMAGE (row->icon_image), icon, row->icon_size);
- gtk_widget_set_visible (row->icon_image, icon != NULL);
- g_object_unref (icon);
-
/* update the action button */
if (thunar_g_volume_is_removable (row->volume)
&& thunar_g_volume_is_mounted (row->volume))
@@ -1227,9 +1266,6 @@ thunar_shortcut_row_volume_changed (ThunarShortcutRow *row)
static void
thunar_shortcut_row_mount_changed (ThunarShortcutRow *row)
{
- GIcon *icon;
- gchar *name;
-
_thunar_return_if_fail (THUNAR_IS_SHORTCUT_ROW (row));
/* don't update the row based on the mount unless we have
@@ -1239,18 +1275,6 @@ thunar_shortcut_row_mount_changed (ThunarShortcutRow *row)
if (row->mount != NULL)
{
- /* update the label widget */
- name = g_mount_get_name (row->mount);
- gtk_label_set_markup (GTK_LABEL (row->label_widget), name);
- gtk_widget_set_visible (row->label_widget, name != NULL && *name != '\0');
- g_free (name);
-
- /* update the icon image */
- icon = g_mount_get_icon (row->mount);
- gtk_image_set_from_gicon (GTK_IMAGE (row->icon_image), icon, row->icon_size);
- gtk_widget_set_visible (row->icon_image, icon != NULL);
- g_object_unref (icon);
-
/* update the action button */
if (g_mount_can_unmount (row->mount) || g_mount_can_eject (row->mount))
gtk_widget_set_visible (row->action_button, TRUE);
@@ -1454,6 +1478,40 @@ thunar_shortcut_row_get_location (ThunarShortcutRow *row)
void
+thunar_shortcut_row_set_file (ThunarShortcutRow *row,
+ ThunarFile *file)
+{
+ _thunar_return_if_fail (THUNAR_IS_SHORTCUT_ROW (row));
+ _thunar_return_if_fail (file == NULL || THUNAR_IS_FILE (file));
+
+ if (row->file == file)
+ return;
+
+ if (row->file != NULL)
+ g_object_unref (row->file);
+
+ if (file != NULL)
+ row->file = g_object_ref (file);
+ else
+ row->file = NULL;
+
+ thunar_shortcut_row_file_changed (row);
+
+ g_object_notify (G_OBJECT (row), "file");
+}
+
+
+
+ThunarFile *
+thunar_shortcut_row_get_file (ThunarShortcutRow *row)
+{
+ _thunar_return_val_if_fail (THUNAR_IS_SHORTCUT_ROW (row), NULL);
+ return row->file;
+}
+
+
+
+void
thunar_shortcut_row_set_volume (ThunarShortcutRow *row,
GVolume *volume)
{
diff --git a/thunar/thunar-shortcut-row.h b/thunar/thunar-shortcut-row.h
index 3c53e42..23dfa04 100644
--- a/thunar/thunar-shortcut-row.h
+++ b/thunar/thunar-shortcut-row.h
@@ -48,6 +48,9 @@ void thunar_shortcut_row_set_label (ThunarShortcutRow *row
GFile *thunar_shortcut_row_get_location (ThunarShortcutRow *row);
void thunar_shortcut_row_set_location (ThunarShortcutRow *row,
GFile *location);
+ThunarFile *thunar_shortcut_row_get_file (ThunarShortcutRow *row);
+void thunar_shortcut_row_set_file (ThunarShortcutRow *row,
+ ThunarFile *file);
GVolume *thunar_shortcut_row_get_volume (ThunarShortcutRow *row);
void thunar_shortcut_row_set_volume (ThunarShortcutRow *row,
GVolume *volume);
diff --git a/thunar/thunar-shortcut.c b/thunar/thunar-shortcut.c
index 96170c7..5f6741b 100644
--- a/thunar/thunar-shortcut.c
+++ b/thunar/thunar-shortcut.c
@@ -43,8 +43,10 @@ enum
PROP_VOLUME,
PROP_MOUNT,
PROP_ICON,
+ PROP_CUSTOM_ICON,
PROP_EJECT_ICON,
PROP_NAME,
+ PROP_CUSTOM_NAME,
PROP_SHORTCUT_TYPE,
PROP_HIDDEN,
PROP_MUTABLE,
@@ -54,23 +56,26 @@ enum
/* signal identifiers */
enum
{
- SIGNAL_CHANGED,
LAST_SIGNAL,
};
-static void thunar_shortcut_constructed (GObject *object);
-static void thunar_shortcut_finalize (GObject *object);
-static void thunar_shortcut_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec);
-static void thunar_shortcut_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec);
-static void thunar_shortcut_load_file (ThunarShortcut *shortcut);
+static void thunar_shortcut_constructed (GObject *object);
+static void thunar_shortcut_finalize (GObject *object);
+static void thunar_shortcut_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void thunar_shortcut_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void thunar_shortcut_load_file_finish (GFile *location,
+ ThunarFile *file,
+ GError *error,
+ gpointer user_data);
+static void thunar_shortcut_load_file (ThunarShortcut *shortcut);
@@ -90,9 +95,11 @@ struct _ThunarShortcut
GMount *mount;
GIcon *icon;
+ GIcon *custom_icon;
GIcon *eject_icon;
gchar *name;
+ gchar *custom_name;
ThunarShortcutType type;
@@ -100,6 +107,7 @@ struct _ThunarShortcut
guint mutable : 1;
guint persistent : 1;
+ guint constructed : 1;
};
@@ -108,10 +116,6 @@ G_DEFINE_TYPE (ThunarShortcut, thunar_shortcut, G_TYPE_OBJECT)
-static guint shortcut_signals[LAST_SIGNAL];
-
-
-
static void
thunar_shortcut_class_init (ThunarShortcutClass *klass)
{
@@ -171,6 +175,15 @@ thunar_shortcut_class_init (ThunarShortcutClass *klass)
G_PARAM_CONSTRUCT));
g_object_class_install_property (gobject_class,
+ PROP_CUSTOM_ICON,
+ g_param_spec_object ("custom-icon",
+ "custom-icon",
+ "custom-icon",
+ G_TYPE_ICON,
+ EXO_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property (gobject_class,
PROP_EJECT_ICON,
g_param_spec_object ("eject-icon",
"eject-icon",
@@ -188,6 +201,15 @@ thunar_shortcut_class_init (ThunarShortcutClass *klass)
G_PARAM_CONSTRUCT));
g_object_class_install_property (gobject_class,
+ PROP_CUSTOM_NAME,
+ g_param_spec_string ("custom-name",
+ "custom-name",
+ "custom-name",
+ NULL,
+ EXO_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property (gobject_class,
PROP_SHORTCUT_TYPE,
g_param_spec_enum ("shortcut-type",
"shortcut-type",
@@ -223,12 +245,6 @@ thunar_shortcut_class_init (ThunarShortcutClass *klass)
FALSE,
EXO_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
-
- shortcut_signals[SIGNAL_CHANGED] = g_signal_new ("changed",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0, NULL, NULL, NULL,
- G_TYPE_NONE, 0);
}
@@ -245,11 +261,8 @@ thunar_shortcut_constructed (GObject *object)
{
ThunarShortcut *shortcut = THUNAR_SHORTCUT (object);
- if (shortcut->type == THUNAR_SHORTCUT_REGULAR_FILE
- || shortcut->type == THUNAR_SHORTCUT_NETWORK_FILE)
- {
- thunar_shortcut_load_file (shortcut);
- }
+ /* mark as constructed so now all properties can be changed as usual */
+ shortcut->constructed = TRUE;
}
@@ -274,10 +287,14 @@ thunar_shortcut_finalize (GObject *object)
if (shortcut->icon != NULL)
g_object_unref (shortcut->icon);
+ if (shortcut->custom_icon != NULL)
+ g_object_unref (shortcut->custom_icon);
+
if (shortcut->eject_icon != NULL)
g_object_unref (shortcut->eject_icon);
g_free (shortcut->name);
+ g_free (shortcut->custom_name);
(*G_OBJECT_CLASS (thunar_shortcut_parent_class)->finalize) (object);
}
@@ -314,6 +331,10 @@ thunar_shortcut_get_property (GObject *object,
g_value_set_object (value, thunar_shortcut_get_icon (shortcut));
break;
+ case PROP_CUSTOM_ICON:
+ g_value_set_object (value, thunar_shortcut_get_custom_icon (shortcut));
+ break;
+
case PROP_EJECT_ICON:
g_value_set_object (value, thunar_shortcut_get_eject_icon (shortcut));
break;
@@ -322,6 +343,10 @@ thunar_shortcut_get_property (GObject *object,
g_value_set_string (value, thunar_shortcut_get_name (shortcut));
break;
+ case PROP_CUSTOM_NAME:
+ g_value_set_string (value, thunar_shortcut_get_custom_name (shortcut));
+ break;
+
case PROP_SHORTCUT_TYPE:
g_value_set_enum (value, thunar_shortcut_get_shortcut_type (shortcut));
break;
@@ -376,6 +401,10 @@ thunar_shortcut_set_property (GObject *object,
thunar_shortcut_set_icon (shortcut, g_value_get_object (value));
break;
+ case PROP_CUSTOM_ICON:
+ thunar_shortcut_set_custom_icon (shortcut, g_value_get_object (value));
+ break;
+
case PROP_EJECT_ICON:
thunar_shortcut_set_eject_icon (shortcut, g_value_get_object (value));
break;
@@ -384,6 +413,10 @@ thunar_shortcut_set_property (GObject *object,
thunar_shortcut_set_name (shortcut, g_value_get_string (value));
break;
+ case PROP_CUSTOM_NAME:
+ thunar_shortcut_set_custom_name (shortcut, g_value_get_string (value));
+ break;
+
case PROP_SHORTCUT_TYPE:
thunar_shortcut_set_shortcut_type (shortcut, g_value_get_enum (value));
break;
@@ -408,22 +441,31 @@ thunar_shortcut_set_property (GObject *object,
-#if 0
static void
thunar_shortcut_load_file_finish (GFile *location,
ThunarFile *file,
- GError *error)
+ GError *error,
+ gpointer user_data)
{
+ ThunarShortcut *shortcut = THUNAR_SHORTCUT (user_data);
+
+ _thunar_return_if_fail (G_IS_FILE (location));
+ _thunar_return_if_fail (file == NULL || THUNAR_IS_FILE (file));
+ _thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut));
+
if (error != NULL)
{
- g_debug ("error: %s", error->message);
+ g_debug ("file load error: %s", error->message);
}
else
{
- g_debug ("file loaded: %s", thunar_file_get_display_name (file));
+ /* set the file and update the shortcut */
+ thunar_shortcut_set_file (shortcut, file);
}
+
+ /* release the shortcut */
+ g_object_unref (shortcut);
}
-#endif
@@ -435,12 +477,11 @@ thunar_shortcut_load_file (ThunarShortcut *shortcut)
if (shortcut->file != NULL)
return;
-#if 0
/* load the ThunarFile asynchronously */
/* TODO pass a cancellable here */
thunar_file_get_async (shortcut->location, NULL,
- thunar_shortcut_load_file_finish);
-#endif
+ thunar_shortcut_load_file_finish,
+ g_object_ref (shortcut));
}
@@ -458,9 +499,16 @@ void
thunar_shortcut_set_location (ThunarShortcut *shortcut,
GFile *location)
{
+ GIcon *icon;
+ gchar *base_name;
+ gchar *uri;
+
_thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut));
_thunar_return_if_fail (location == NULL || G_IS_FILE (location));
+ if (location == NULL && !shortcut->constructed)
+ return;
+
if (shortcut->location == location)
return;
@@ -472,6 +520,33 @@ thunar_shortcut_set_location (ThunarShortcut *shortcut,
else
shortcut->location = NULL;
+ /* check if we have a file shortcut */
+ if (shortcut->type == THUNAR_SHORTCUT_REGULAR_FILE
+ || shortcut->type == THUNAR_SHORTCUT_NETWORK_FILE)
+ {
+ /* check whether we have a location */
+ if (shortcut->location != NULL)
+ {
+ /* use the location base name as the default name */
+ uri = g_file_get_uri (shortcut->location);
+ base_name = g_filename_display_basename (uri);
+ thunar_shortcut_set_name (shortcut, base_name);
+ g_free (base_name);
+ g_free (uri);
+
+ /* use the folder icon as the default icon */
+ if (shortcut->custom_icon == NULL)
+ {
+ icon = g_themed_icon_new ("folder");
+ thunar_shortcut_set_custom_icon (shortcut, icon);
+ g_object_unref (icon);
+ }
+
+ /* load file asynchronously */
+ thunar_shortcut_load_file (shortcut);
+ }
+ }
+
g_object_notify (G_OBJECT (shortcut), "location");
}
@@ -493,6 +568,9 @@ thunar_shortcut_set_file (ThunarShortcut *shortcut,
_thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut));
_thunar_return_if_fail (file == NULL || THUNAR_IS_FILE (file));
+ if (file == NULL && !shortcut->constructed)
+ return;
+
if (shortcut->file == file)
return;
@@ -504,6 +582,20 @@ thunar_shortcut_set_file (ThunarShortcut *shortcut,
else
shortcut->file = NULL;
+ /* check whether we have a file shortcut */
+ if (shortcut->type == THUNAR_SHORTCUT_REGULAR_FILE
+ || shortcut->type == THUNAR_SHORTCUT_NETWORK_FILE)
+ {
+ /* update only if we have a file */
+ if (shortcut->file != NULL)
+ {
+ /* update the name and icon of the shortcut */
+ thunar_shortcut_set_name (shortcut,
+ thunar_file_get_display_name (shortcut->file));
+ thunar_shortcut_set_custom_icon (shortcut, thunar_file_get_icon (shortcut->file));
+ }
+ }
+
g_object_notify (G_OBJECT (shortcut), "file");
}
@@ -522,9 +614,15 @@ void
thunar_shortcut_set_volume (ThunarShortcut *shortcut,
GVolume *volume)
{
+ GIcon *icon;
+ gchar *name;
+
_thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut));
_thunar_return_if_fail (volume == NULL || G_IS_VOLUME (volume));
+ if (volume == NULL && !shortcut->constructed)
+ return;
+
if (shortcut->volume == volume)
return;
@@ -536,6 +634,23 @@ thunar_shortcut_set_volume (ThunarShortcut *shortcut,
else
shortcut->volume = NULL;
+ /* check if we have a regular or ejectable volume */
+ if (shortcut->type == THUNAR_SHORTCUT_REGULAR_VOLUME
+ || shortcut->type == THUNAR_SHORTCUT_EJECTABLE_VOLUME)
+ {
+ /* only update if we have a volume */
+ if (shortcut->volume != NULL)
+ {
+ /* update the name and icon of the shortcut */
+ name = g_volume_get_name (shortcut->volume);
+ icon = g_volume_get_icon (shortcut->volume);
+ thunar_shortcut_set_name (shortcut, name);
+ thunar_shortcut_set_custom_icon (shortcut, icon);
+ g_object_unref (icon);
+ g_free (name);
+ }
+ }
+
g_object_notify (G_OBJECT (shortcut), "volume");
}
@@ -554,9 +669,15 @@ void
thunar_shortcut_set_mount (ThunarShortcut *shortcut,
GMount *mount)
{
+ GIcon *icon;
+ gchar *name;
+
_thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut));
_thunar_return_if_fail (mount == NULL || G_IS_MOUNT (mount));
+ if (mount == NULL && !shortcut->constructed)
+ return;
+
if (shortcut->mount == mount)
return;
@@ -568,6 +689,21 @@ thunar_shortcut_set_mount (ThunarShortcut *shortcut,
else
shortcut->mount = NULL;
+ /* check if we have a standalone mount */
+ if (shortcut->type == THUNAR_SHORTCUT_STANDALONE_MOUNT)
+ {
+ /* only update if we have a mount */
+ if (shortcut->mount != NULL)
+ {
+ /* update the name and icon of the shortcut */
+ name = g_mount_get_name (shortcut->mount);
+ icon = g_mount_get_icon (shortcut->mount);
+ thunar_shortcut_set_name (shortcut, name);
+ thunar_shortcut_set_custom_icon (shortcut, icon);
+ g_object_unref (icon);
+ g_free (name);
+ }
+ }
g_object_notify (G_OBJECT (shortcut), "mount");
}
@@ -589,6 +725,9 @@ thunar_shortcut_set_icon (ThunarShortcut *shortcut,
_thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut));
_thunar_return_if_fail (icon == NULL || G_IS_ICON (icon));
+ if (icon == NULL && !shortcut->constructed)
+ return;
+
if (shortcut->icon == icon)
return;
@@ -606,6 +745,41 @@ thunar_shortcut_set_icon (ThunarShortcut *shortcut,
GIcon *
+thunar_shortcut_get_custom_icon (ThunarShortcut *shortcut)
+{
+ _thunar_return_val_if_fail (THUNAR_IS_SHORTCUT (shortcut), NULL);
+ return shortcut->custom_icon;
+}
+
+
+
+void
+thunar_shortcut_set_custom_icon (ThunarShortcut *shortcut,
+ GIcon *custom_icon)
+{
+ _thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut));
+ _thunar_return_if_fail (custom_icon == NULL || G_IS_ICON (custom_icon));
+
+ if (custom_icon == NULL && !shortcut->constructed)
+ return;
+
+ if (shortcut->custom_icon == custom_icon)
+ return;
+
+ if (shortcut->custom_icon != NULL)
+ g_object_unref (shortcut->custom_icon);
+
+ if (custom_icon != NULL)
+ shortcut->custom_icon = g_object_ref (custom_icon);
+ else
+ shortcut->custom_icon = NULL;
+
+ g_object_notify (G_OBJECT (shortcut), "custom-icon");
+}
+
+
+
+GIcon *
thunar_shortcut_get_eject_icon (ThunarShortcut *shortcut)
{
_thunar_return_val_if_fail (THUNAR_IS_SHORTCUT (shortcut), NULL);
@@ -621,6 +795,9 @@ thunar_shortcut_set_eject_icon (ThunarShortcut *shortcut,
_thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut));
_thunar_return_if_fail (eject_icon == NULL || G_IS_ICON (eject_icon));
+ if (eject_icon == NULL && !shortcut->constructed)
+ return;
+
if (shortcut->eject_icon == eject_icon)
return;
@@ -652,6 +829,9 @@ thunar_shortcut_set_name (ThunarShortcut *shortcut,
{
_thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut));
+ if (name == NULL && !shortcut->constructed)
+ return;
+
if (g_strcmp0 (shortcut->name, name) == 0)
return;
@@ -664,6 +844,36 @@ thunar_shortcut_set_name (ThunarShortcut *shortcut,
+const gchar *
+thunar_shortcut_get_custom_name (ThunarShortcut *shortcut)
+{
+ _thunar_return_val_if_fail (THUNAR_IS_SHORTCUT (shortcut), NULL);
+ return shortcut->custom_name;
+}
+
+
+
+void
+thunar_shortcut_set_custom_name (ThunarShortcut *shortcut,
+ const gchar *custom_name)
+{
+ _thunar_return_if_fail (THUNAR_IS_SHORTCUT (shortcut));
+
+ if (custom_name == NULL && !shortcut->constructed)
+ return;
+
+ if (g_strcmp0 (shortcut->custom_name, custom_name) == 0)
+ return;
+
+ g_free (shortcut->custom_name);
+
+ shortcut->custom_name = g_strdup (custom_name);
+
+ g_object_notify (G_OBJECT (shortcut), "custom-name");
+}
+
+
+
ThunarShortcutType
thunar_shortcut_get_shortcut_type (ThunarShortcut *shortcut)
{
diff --git a/thunar/thunar-shortcut.h b/thunar/thunar-shortcut.h
index 4a1c8d6..1a8d6a7 100644
--- a/thunar/thunar-shortcut.h
+++ b/thunar/thunar-shortcut.h
@@ -54,12 +54,18 @@ void thunar_shortcut_set_mount (ThunarShortcut *shortcu
GIcon *thunar_shortcut_get_icon (ThunarShortcut *shortcut);
void thunar_shortcut_set_icon (ThunarShortcut *shortcut,
GIcon *icon);
+GIcon *thunar_shortcut_get_custom_icon (ThunarShortcut *shortcut);
+void thunar_shortcut_set_custom_icon (ThunarShortcut *shortcut,
+ GIcon *custom_icon);
GIcon *thunar_shortcut_get_eject_icon (ThunarShortcut *shortcut);
void thunar_shortcut_set_eject_icon (ThunarShortcut *shortcut,
GIcon *eject_icon);
const gchar *thunar_shortcut_get_name (ThunarShortcut *shortcut);
void thunar_shortcut_set_name (ThunarShortcut *shortcut,
const gchar *name);
+const gchar *thunar_shortcut_get_custom_name (ThunarShortcut *shortcut);
+void thunar_shortcut_set_custom_name (ThunarShortcut *shortcut,
+ const gchar *custom_name);
ThunarShortcutType thunar_shortcut_get_shortcut_type (ThunarShortcut *shortcut);
void thunar_shortcut_set_shortcut_type (ThunarShortcut *shortcut,
ThunarShortcutType shortcut_type);
diff --git a/thunar/thunar-shortcuts-model.c b/thunar/thunar-shortcuts-model.c
index cbbded6..69e2c6a 100644
--- a/thunar/thunar-shortcuts-model.c
+++ b/thunar/thunar-shortcuts-model.c
@@ -126,6 +126,7 @@ static gboolean thunar_shortcuts_model_find_mount (Thu
static void thunar_shortcuts_model_add_shortcut (ThunarShortcutsModel *model,
ThunarShortcut *shortcut);
static void thunar_shortcuts_model_shortcut_changed (ThunarShortcutsModel *model,
+ GParamSpec *pspec,
ThunarShortcut *shortcut);
static gboolean thunar_shortcuts_model_load_system_shortcuts (gpointer user_data);
static gboolean thunar_shortcuts_model_load_user_dirs (gpointer user_data);
@@ -400,6 +401,8 @@ thunar_shortcuts_model_get_value (GtkTreeModel *tree_model,
ThunarShortcutCategory *category;
ThunarShortcutsModel *model = THUNAR_SHORTCUTS_MODEL (tree_model);
ThunarShortcut *shortcut;
+ const gchar *name;
+ GIcon *icon;
gint category_index;
gint shortcut_index;
@@ -419,17 +422,33 @@ thunar_shortcuts_model_get_value (GtkTreeModel *tree_model,
case THUNAR_SHORTCUTS_MODEL_COLUMN_ICON:
g_value_init (value, G_TYPE_ICON);
if (shortcut != NULL)
- g_value_set_object (value, thunar_shortcut_get_icon (shortcut));
+ {
+ icon = thunar_shortcut_get_custom_icon (shortcut);
+ if (icon == NULL)
+ icon = thunar_shortcut_get_icon (shortcut);
+
+ g_value_set_object (value, icon);
+ }
else
- g_value_set_object (value, NULL);
+ {
+ g_value_set_object (value, NULL);
+ }
break;
case THUNAR_SHORTCUTS_MODEL_COLUMN_NAME:
g_value_init (value, G_TYPE_STRING);
if (shortcut != NULL)
- g_value_set_static_string (value, thunar_shortcut_get_name (shortcut));
+ {
+ name = thunar_shortcut_get_custom_name (shortcut);
+ if (name == NULL)
+ name = thunar_shortcut_get_name (shortcut);
+
+ g_value_set_static_string (value, name);
+ }
else
- g_value_set_static_string (value, category->name);
+ {
+ g_value_set_static_string (value, category->name);
+ }
break;
case THUNAR_SHORTCUTS_MODEL_COLUMN_LOCATION:
@@ -1143,7 +1162,7 @@ thunar_shortcuts_model_add_shortcut (ThunarShortcutsModel *model,
gtk_tree_path_free (path);
/* be notified whenever the shortcut changes */
- g_signal_connect_swapped (shortcut, "changed",
+ g_signal_connect_swapped (shortcut, "notify",
G_CALLBACK (thunar_shortcuts_model_shortcut_changed),
model);
}
@@ -1152,6 +1171,7 @@ thunar_shortcuts_model_add_shortcut (ThunarShortcutsModel *model,
static void
thunar_shortcuts_model_shortcut_changed (ThunarShortcutsModel *model,
+ GParamSpec *pspec,
ThunarShortcut *shortcut)
{
GtkTreePath *path;
@@ -1190,7 +1210,7 @@ thunar_shortcuts_model_load_system_shortcuts (gpointer user_data)
GFile *home_file;
GFile *location;
GIcon *icon;
- gchar *name;
+ gchar *name = NULL;
gchar *path;
_thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model), FALSE);
@@ -1201,15 +1221,13 @@ thunar_shortcuts_model_load_system_shortcuts (gpointer user_data)
/* create $HOME information */
icon = g_themed_icon_new ("user-home");
path = g_file_get_path (home_file);
- name = g_filename_display_basename (path);
/* create the $HOME shortcut */
shortcut = g_object_new (THUNAR_TYPE_SHORTCUT,
"shortcut-type", THUNAR_SHORTCUT_REGULAR_FILE,
"location", home_file,
"icon", icon,
- "eject-icon", NULL,
- "name", name,
+ "custom-name", NULL,
"hidden", FALSE,
"mutable", FALSE,
"persistent", TRUE,
@@ -1219,7 +1237,6 @@ thunar_shortcuts_model_load_system_shortcuts (gpointer user_data)
thunar_shortcuts_model_add_shortcut (model, shortcut);
/* release $HOME information */
- g_free (name);
g_free (path);
g_object_unref (icon);
@@ -1238,8 +1255,7 @@ thunar_shortcuts_model_load_system_shortcuts (gpointer user_data)
"shortcut-type", THUNAR_SHORTCUT_REGULAR_FILE,
"location", location,
"icon", icon,
- "eject-icon", NULL,
- "name", name,
+ "custom-name", name,
"hidden", FALSE,
"mutable", FALSE,
"persistent", TRUE,
@@ -1267,8 +1283,7 @@ thunar_shortcuts_model_load_system_shortcuts (gpointer user_data)
"shortcut-type", THUNAR_SHORTCUT_REGULAR_FILE,
"location", location,
"icon", icon,
- "eject-icon", NULL,
- "name", name,
+ "custom-name", name,
"hidden", FALSE,
"mutable", FALSE,
"persistent", TRUE,
@@ -1295,8 +1310,7 @@ thunar_shortcuts_model_load_system_shortcuts (gpointer user_data)
"shortcut-type", THUNAR_SHORTCUT_NETWORK_FILE,
"location", location,
"icon", icon,
- "eject-icon", NULL,
- "name", name,
+ "custom-name", name,
"hidden", FALSE,
"mutable", FALSE,
"persistent", TRUE,
@@ -1348,7 +1362,6 @@ thunar_shortcuts_model_load_bookmarks (gpointer user_data)
gchar *bookmarks_path;
gchar line[2048];
gchar *name;
- gchar *unescaped_uri;
FILE *fp;
_thunar_return_val_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model), FALSE);
@@ -1389,17 +1402,8 @@ thunar_shortcuts_model_load_bookmarks (gpointer user_data)
/* parse the URI */
location = g_file_new_for_uri (line);
- /* use the base name as a fallback for the display name */
- if (*name != '\0')
- {
- name = g_strdup (name);
- }
- else
- {
- unescaped_uri = g_uri_unescape_string (line, NULL);
- name = g_filename_display_basename (unescaped_uri);
- g_free (unescaped_uri);
- }
+ /* only set the name property if the name is not empty */
+ name = *name != '\0' ? g_strdup (name) : NULL;
/* set initial icon and type based on the URI scheme */
is_local = g_file_has_uri_scheme (location, "file");
@@ -1420,7 +1424,7 @@ thunar_shortcuts_model_load_bookmarks (gpointer user_data)
"location", location,
"icon", icon,
"eject-icon", eject_icon,
- "name", name,
+ "custom-name", name,
"hidden", FALSE,
"mutable", TRUE,
"persistent", TRUE,
@@ -1521,17 +1525,13 @@ thunar_shortcuts_model_volume_added (ThunarShortcutsModel *model,
ThunarShortcut *shortcut;
gboolean hidden = FALSE;
GIcon *eject_icon;
- GIcon *icon;
- gchar *name;
_thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
_thunar_return_if_fail (G_IS_VOLUME (volume));
_thunar_return_if_fail (G_IS_VOLUME_MONITOR (monitor));
/* read information from the volume */
- icon = g_volume_get_icon (volume);
eject_icon = g_themed_icon_new ("media-eject");
- name = g_volume_get_name (volume);
/* hide the volume if there is no media */
if (!thunar_g_volume_is_present (volume))
@@ -1546,9 +1546,7 @@ thunar_shortcuts_model_volume_added (ThunarShortcutsModel *model,
shortcut = g_object_new (THUNAR_TYPE_SHORTCUT,
"shortcut-type", THUNAR_SHORTCUT_REGULAR_VOLUME,
"volume", volume,
- "icon", icon,
"eject-icon", eject_icon,
- "name", name,
"hidden", hidden,
"mutable", FALSE,
"persistent", FALSE,
@@ -1558,9 +1556,7 @@ thunar_shortcuts_model_volume_added (ThunarShortcutsModel *model,
thunar_shortcuts_model_add_shortcut (model, shortcut);
/* release volume information */
- g_free (name);
g_object_unref (eject_icon);
- g_object_unref (icon);
}
@@ -1609,8 +1605,6 @@ thunar_shortcuts_model_mount_added (ThunarShortcutsModel *model,
GVolume *volume;
GFile *location;
GIcon *eject_icon;
- GIcon *icon;
- gchar *name;
_thunar_return_if_fail (THUNAR_IS_SHORTCUTS_MODEL (model));
_thunar_return_if_fail (G_IS_MOUNT (mount));
@@ -1627,18 +1621,14 @@ thunar_shortcuts_model_mount_added (ThunarShortcutsModel *model,
{
/* read information from the mount */
location = g_mount_get_root (mount);
- icon = g_mount_get_icon (mount);
eject_icon = g_themed_icon_new ("media-eject");
- name = g_mount_get_name (mount);
/* create a shortcut for the mount */
shortcut = g_object_new (THUNAR_TYPE_SHORTCUT,
"shortcut-type", THUNAR_SHORTCUT_STANDALONE_MOUNT,
"location", location,
"mount", mount,
- "icon", icon,
"eject-icon", eject_icon,
- "name", name,
"hidden", FALSE,
"mutable", FALSE,
"persistent", FALSE,
@@ -1648,9 +1638,7 @@ thunar_shortcuts_model_mount_added (ThunarShortcutsModel *model,
thunar_shortcuts_model_add_shortcut (model, shortcut);
/* release volume information */
- g_free (name);
g_object_unref (eject_icon);
- g_object_unref (icon);
g_object_unref (location);
}
}
diff --git a/thunar/thunar-shortcuts-view.c b/thunar/thunar-shortcuts-view.c
index 217bac0..553a9d1 100644
--- a/thunar/thunar-shortcuts-view.c
+++ b/thunar/thunar-shortcuts-view.c
@@ -514,6 +514,7 @@ thunar_shortcuts_view_row_changed (ThunarShortcutsView *view,
GtkTreeModel *model)
{
ThunarShortcutRow *row;
+ ThunarFile *file;
GtkWidget *expander;
GtkWidget *box;
GIcon *icon;
@@ -550,21 +551,21 @@ thunar_shortcuts_view_row_changed (ThunarShortcutsView *view,
row = THUNAR_SHORTCUT_ROW (row_element->data);
/* read updated information from the tree row */
- /* TODO also read the ThunarFile if we have one etc. */
gtk_tree_model_get (model, iter,
THUNAR_SHORTCUTS_MODEL_COLUMN_NAME, &name,
THUNAR_SHORTCUTS_MODEL_COLUMN_ICON, &icon,
+ THUNAR_SHORTCUTS_MODEL_COLUMN_FILE, &file,
-1);
/* update the row */
- g_object_set (row,
- "name", name,
- "icon", icon,
- NULL);
+ g_object_set (row, "label", name, "icon", icon, "file", file, NULL);
/* release the values */
g_free (name);
- g_object_unref (icon);
+ if (icon != NULL)
+ g_object_unref (icon);
+ if (file != NULL)
+ g_object_unref (file);
}
/* free the row list */
More information about the Xfce4-commits
mailing list