Commit 15b0789f authored by Harald Judt's avatar Harald Judt

Merge branch 'fix-bug-11008'

parents 3a53de78 b2012f58
......@@ -112,7 +112,6 @@ thunar/thunar-thumbnailer-proxy.h
thunar/Thunar
thunar/core.*
thunar/*.core
thunar/thunar-marshal.[ch]
thunar/thunar-*-ui.h
thunar/stamp-thunar-*.*
thunar/thunar-dbus-service-infos.h
......
......@@ -497,7 +497,7 @@ thunar_application_launch_finished (ThunarJob *job,
/* the job completed, refresh the interface
* directly to make it feel snappy */
thunar_view_reload (view);
thunar_view_reload (view, FALSE);
}
......
......@@ -682,22 +682,36 @@ thunar_file_monitor_update (GFile *path,
static void
thunar_file_monitor_moved (ThunarFile *file,
GFile *renamed_file)
thunar_file_move_thumbnail_cache_file (GFile *old_file,
GFile *new_file)
{
ThunarApplication *application;
ThunarThumbnailCache *thumbnail_cache;
GFile *previous_file;
/* ref the old location */
previous_file = g_object_ref (G_OBJECT (file->gfile));
_thunar_return_if_fail (G_IS_FILE (old_file));
_thunar_return_if_fail (G_IS_FILE (new_file));
/* notify the thumbnail cache that we can now also move the thumbnail */
application = thunar_application_get ();
thumbnail_cache = thunar_application_get_thumbnail_cache (application);
thunar_thumbnail_cache_move_file (thumbnail_cache, previous_file, renamed_file);
thunar_thumbnail_cache_move_file (thumbnail_cache, old_file, new_file);
g_object_unref (thumbnail_cache);
g_object_unref (application);
}
static void
thunar_file_monitor_moved (ThunarFile *file,
GFile *renamed_file)
{
GFile *previous_file;
/* ref the old location */
previous_file = g_object_ref (G_OBJECT (file->gfile));
/* notify the thumbnail cache that we can now also move the thumbnail */
thunar_file_move_thumbnail_cache_file (previous_file, renamed_file);
/* set the new file */
file->gfile = g_object_ref (G_OBJECT (renamed_file));
......@@ -724,34 +738,85 @@ thunar_file_monitor_moved (ThunarFile *file,
void
thunar_file_reload_parent (ThunarFile *file)
{
ThunarFile *parent = NULL;
_thunar_return_if_fail (THUNAR_IS_FILE (file));
if (thunar_file_has_parent (file))
{
GFile *parent_file;
/* only reload file if it is in cache */
parent_file = g_file_get_parent (file->gfile);
parent = thunar_file_cache_lookup (parent_file);
g_object_unref (parent_file);
}
if (parent)
{
thunar_file_reload (parent);
g_object_unref (parent);
}
}
static void
thunar_file_monitor (GFileMonitor *monitor,
GFile *path,
GFile *event_path,
GFile *other_path,
GFileMonitorEvent event_type,
gpointer user_data)
{
ThunarFile *file = THUNAR_FILE (user_data);
ThunarFile *other_file;
_thunar_return_if_fail (G_IS_FILE_MONITOR (monitor));
_thunar_return_if_fail (G_IS_FILE (event_path));
_thunar_return_if_fail (THUNAR_IS_FILE (file));
if (G_UNLIKELY (!G_IS_FILE (path)
|| !g_file_equal (path, file->gfile)))
return;
if (event_type == G_FILE_MONITOR_EVENT_MOVED)
if (g_file_equal (event_path, file->gfile))
{
if (G_IS_FILE (other_path))
thunar_file_monitor_moved (file, other_path);
return;
/* the event occurred for the monitored ThunarFile */
if (event_type == G_FILE_MONITOR_EVENT_MOVED)
{
thunar_file_monitor_moved (file, other_path);
return;
}
if (G_LIKELY (event_path))
thunar_file_monitor_update (event_path, event_type);
}
else
{
/* The event did not occur for the monitored ThunarFile, but for
a file that is contained in ThunarFile which is actually a
directory. */
if (event_type == G_FILE_MONITOR_EVENT_MOVED)
{
/* reload the target file if cached */
other_file = thunar_file_cache_lookup (other_path);
if (other_file)
thunar_file_reload (other_file);
else
other_file = thunar_file_get (other_path, NULL);
if (!other_file)
return;
if (G_LIKELY (G_IS_FILE (path)))
thunar_file_monitor_update (path, event_type);
/* notify the thumbnail cache that we can now also move the thumbnail */
thunar_file_move_thumbnail_cache_file (event_path, other_path);
if (G_UNLIKELY (G_IS_FILE (other_path)))
thunar_file_monitor_update (other_path, event_type);
/* reload the containing target folder */
thunar_file_reload_parent (other_file);
g_object_unref (other_file);
}
return;
}
}
......@@ -1230,22 +1295,6 @@ thunar_file_get_with_info (GFile *gfile,
{
/* return the file, it already has an additional ref set
* in thunar_file_cache_lookup */
/* The file might have changed while being cached.
* Use the info to update the file */
/* reset the file */
thunar_file_info_clear (file);
/* set the passed info */
file->info = g_object_ref (info);
/* update the file from the information */
thunar_file_info_reload (file, NULL);
/* update the mounted info */
if (not_mounted)
FLAG_UNSET (file, THUNAR_FILE_FLAG_IS_MOUNTED);
}
else
{
......@@ -3883,6 +3932,24 @@ thunar_file_reload (ThunarFile *file)
/**
* thunar_file_reload_idle:
* @file : a #ThunarFile instance.
*
* Schedules a reload of the @file by calling thunar_file_reload
* when idle.
*
**/
void
thunar_file_reload_idle (ThunarFile *file)
{
_thunar_return_if_fail (THUNAR_IS_FILE (file));
g_idle_add ((GSourceFunc) thunar_file_reload, file);
}
/**
* thunar_file_destroy:
* @file : a #ThunarFile instance.
......
......@@ -240,6 +240,8 @@ void thunar_file_watch (ThunarFile
void thunar_file_unwatch (ThunarFile *file);
void thunar_file_reload (ThunarFile *file);
void thunar_file_reload_idle (ThunarFile *file);
void thunar_file_reload_parent (ThunarFile *file);
void thunar_file_destroy (ThunarFile *file);
......
......@@ -109,6 +109,7 @@ struct _ThunarFolder
ThunarFile *corresponding_file;
GList *new_files;
GList *files;
gboolean reload_info;
GList *content_type_ptr;
guint content_type_idle_id;
......@@ -248,6 +249,7 @@ thunar_folder_init (ThunarFolder *folder)
g_signal_connect (G_OBJECT (folder->file_monitor), "file-destroyed", G_CALLBACK (thunar_folder_file_destroyed), folder);
folder->monitor = NULL;
folder->reload_info = FALSE;
}
......@@ -545,6 +547,18 @@ thunar_folder_finished (ExoJob *job,
}
}
/* schedule a reload of the file information of all files if requested */
if (folder->reload_info)
{
for (lp = folder->files; lp != NULL; lp = lp->next)
thunar_file_reload_idle (lp->data);
/* reload folder information too */
thunar_file_reload_idle (folder->corresponding_file);
folder->reload_info = FALSE;
}
/* we did it, the folder is loaded */
g_signal_handlers_disconnect_matched (folder->job, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, folder);
g_object_unref (folder->job);
......@@ -578,7 +592,7 @@ thunar_folder_file_changed (ThunarFileMonitor *file_monitor,
if (G_UNLIKELY (folder->corresponding_file == file))
{
/* ...and if so, reload the folder */
thunar_folder_reload (folder);
thunar_folder_reload (folder, FALSE);
}
}
......@@ -698,6 +712,7 @@ thunar_folder_monitor (GFileMonitor *monitor,
{
ThunarFolder *folder = THUNAR_FOLDER (user_data);
ThunarFile *file;
ThunarFile *other_parent;
GList *lp;
GList list;
gboolean restart = FALSE;
......@@ -738,12 +753,40 @@ thunar_folder_monitor (GFileMonitor *monitor,
}
else if (lp != NULL)
{
/* update/destroy the file */
if (event_type == G_FILE_MONITOR_EVENT_DELETED)
thunar_file_destroy (lp->data);
{
/* destroy the file */
thunar_file_destroy (lp->data);
}
else if (event_type == G_FILE_MONITOR_EVENT_MOVED)
{
/* destroy the old file and update the new one */
thunar_file_destroy (lp->data);
file = thunar_file_get(other_file, NULL);
if (file != NULL && THUNAR_IS_FILE (file))
{
thunar_file_reload (file);
/* if source and target folders are different, also tell
the target folder to reload for the changes */
if (thunar_file_has_parent (file))
{
other_parent = thunar_file_get_parent (file, NULL);
if (other_parent &&
!g_file_equal (thunar_file_get_file(folder->corresponding_file),
thunar_file_get_file(other_parent)))
{
thunar_file_reload (other_parent);
g_object_unref (other_parent);
}
}
/* drop reference on the other file */
g_object_unref (file);
}
/* reload the folder of the source file */
thunar_file_reload (folder->corresponding_file);
}
else
......@@ -826,7 +869,7 @@ thunar_folder_get_for_file (ThunarFile *file)
g_object_set_qdata (G_OBJECT (file), thunar_folder_quark, folder);
/* schedule the loading of the folder */
thunar_folder_reload (folder);
thunar_folder_reload (folder, FALSE);
}
return folder;
......@@ -894,15 +937,20 @@ thunar_folder_get_loading (const ThunarFolder *folder)
/**
* thunar_folder_reload:
* @folder : a #ThunarFolder instance.
* @reload_info : reload all information for the files too
*
* Tells the @folder object to reread the directory
* contents from the underlying media.
**/
void
thunar_folder_reload (ThunarFolder *folder)
thunar_folder_reload (ThunarFolder *folder,
gboolean reload_info)
{
_thunar_return_if_fail (THUNAR_IS_FOLDER (folder));
/* reload file info too? */
folder->reload_info = reload_info;
/* stop metadata collector */
if (folder->content_type_idle_id != 0)
g_source_remove (folder->content_type_idle_id);
......
......@@ -42,7 +42,8 @@ ThunarFile *thunar_folder_get_corresponding_file (const ThunarFolder *folder);
GList *thunar_folder_get_files (const ThunarFolder *folder);
gboolean thunar_folder_get_loading (const ThunarFolder *folder);
void thunar_folder_reload (ThunarFolder *folder);
void thunar_folder_reload (ThunarFolder *folder,
gboolean reload_info);
G_END_DECLS;
......
......@@ -564,11 +564,25 @@ void
thunar_job_new_files (ThunarJob *job,
const GList *file_list)
{
ThunarFile *file;
const GList *lp;
_thunar_return_if_fail (THUNAR_IS_JOB (job));
/* check if we have any files */
if (G_LIKELY (file_list != NULL))
{
/* schedule a reload of cached files when idle */
for (lp = file_list; lp != NULL; lp = lp->next)
{
file = thunar_file_cache_lookup (lp->data);
if (file != NULL)
{
thunar_file_reload_idle (file);
g_object_unref (file);
}
}
/* emit the "new-files" signal */
exo_job_emit (EXO_JOB (job), job_signals[NEW_FILES], 0, file_list);
}
......
#include <thunar/thunar-marshal.h>
#include <glib-object.h>
#ifdef G_ENABLE_DEBUG
#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v)
#define g_marshal_value_peek_char(v) g_value_get_schar (v)
#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v)
#define g_marshal_value_peek_int(v) g_value_get_int (v)
#define g_marshal_value_peek_uint(v) g_value_get_uint (v)
#define g_marshal_value_peek_long(v) g_value_get_long (v)
#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v)
#define g_marshal_value_peek_int64(v) g_value_get_int64 (v)
#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v)
#define g_marshal_value_peek_enum(v) g_value_get_enum (v)
#define g_marshal_value_peek_flags(v) g_value_get_flags (v)
#define g_marshal_value_peek_float(v) g_value_get_float (v)
#define g_marshal_value_peek_double(v) g_value_get_double (v)
#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v)
#define g_marshal_value_peek_param(v) g_value_get_param (v)
#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v)
#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v)
#define g_marshal_value_peek_object(v) g_value_get_object (v)
#define g_marshal_value_peek_variant(v) g_value_get_variant (v)
#else /* !G_ENABLE_DEBUG */
/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API.
* Do not access GValues directly in your code. Instead, use the
* g_value_get_*() functions
*/
#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int
#define g_marshal_value_peek_char(v) (v)->data[0].v_int
#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint
#define g_marshal_value_peek_int(v) (v)->data[0].v_int
#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint
#define g_marshal_value_peek_long(v) (v)->data[0].v_long
#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong
#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64
#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64
#define g_marshal_value_peek_enum(v) (v)->data[0].v_long
#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong
#define g_marshal_value_peek_float(v) (v)->data[0].v_float
#define g_marshal_value_peek_double(v) (v)->data[0].v_double
#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer
#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer
#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer
#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer
#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer
#define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer
#endif /* !G_ENABLE_DEBUG */
/* BOOLEAN:BOOLEAN (thunar-marshal.list:1) */
void
_thunar_marshal_BOOLEAN__BOOLEAN (GClosure *closure,
GValue *return_value G_GNUC_UNUSED,
guint n_param_values,
const GValue *param_values,
gpointer invocation_hint G_GNUC_UNUSED,
gpointer marshal_data)
{
typedef gboolean (*GMarshalFunc_BOOLEAN__BOOLEAN) (gpointer data1,
gboolean arg_1,
gpointer data2);
register GMarshalFunc_BOOLEAN__BOOLEAN callback;
register GCClosure *cc = (GCClosure*) closure;
register gpointer data1, data2;
gboolean v_return;
g_return_if_fail (return_value != NULL);
g_return_if_fail (n_param_values == 2);
if (G_CCLOSURE_SWAP_DATA (closure))
{
data1 = closure->data;
data2 = g_value_peek_pointer (param_values + 0);
}
else
{
data1 = g_value_peek_pointer (param_values + 0);
data2 = closure->data;
}
callback = (GMarshalFunc_BOOLEAN__BOOLEAN) (marshal_data ? marshal_data : cc->callback);
v_return = callback (data1,
g_marshal_value_peek_boolean (param_values + 1),
data2);
g_value_set_boolean (return_value, v_return);
}
/* BOOLEAN:POINTER (thunar-marshal.list:2) */
void
_thunar_marshal_BOOLEAN__POINTER (GClosure *closure,
GValue *return_value G_GNUC_UNUSED,
guint n_param_values,
const GValue *param_values,
gpointer invocation_hint G_GNUC_UNUSED,
gpointer marshal_data)
{
typedef gboolean (*GMarshalFunc_BOOLEAN__POINTER) (gpointer data1,
gpointer arg_1,
gpointer data2);
register GMarshalFunc_BOOLEAN__POINTER callback;
register GCClosure *cc = (GCClosure*) closure;
register gpointer data1, data2;
gboolean v_return;
g_return_if_fail (return_value != NULL);
g_return_if_fail (n_param_values == 2);
if (G_CCLOSURE_SWAP_DATA (closure))
{
data1 = closure->data;
data2 = g_value_peek_pointer (param_values + 0);
}
else
{
data1 = g_value_peek_pointer (param_values + 0);
data2 = closure->data;
}
callback = (GMarshalFunc_BOOLEAN__POINTER) (marshal_data ? marshal_data : cc->callback);
v_return = callback (data1,
g_marshal_value_peek_pointer (param_values + 1),
data2);
g_value_set_boolean (return_value, v_return);
}
/* BOOLEAN:VOID (thunar-marshal.list:3) */
void
_thunar_marshal_BOOLEAN__VOID (GClosure *closure,
GValue *return_value G_GNUC_UNUSED,
guint n_param_values,
const GValue *param_values,
gpointer invocation_hint G_GNUC_UNUSED,
gpointer marshal_data)
{
typedef gboolean (*GMarshalFunc_BOOLEAN__VOID) (gpointer data1,
gpointer data2);
register GMarshalFunc_BOOLEAN__VOID callback;
register GCClosure *cc = (GCClosure*) closure;
register gpointer data1, data2;
gboolean v_return;
g_return_if_fail (return_value != NULL);
g_return_if_fail (n_param_values == 1);
if (G_CCLOSURE_SWAP_DATA (closure))
{
data1 = closure->data;
data2 = g_value_peek_pointer (param_values + 0);
}
else
{
data1 = g_value_peek_pointer (param_values + 0);
data2 = closure->data;
}
callback = (GMarshalFunc_BOOLEAN__VOID) (marshal_data ? marshal_data : cc->callback);
v_return = callback (data1,
data2);
g_value_set_boolean (return_value, v_return);
}
/* BOOLEAN:INT (thunar-marshal.list:4) */
void
_thunar_marshal_BOOLEAN__INT (GClosure *closure,
GValue *return_value G_GNUC_UNUSED,
guint n_param_values,
const GValue *param_values,
gpointer invocation_hint G_GNUC_UNUSED,
gpointer marshal_data)
{
typedef gboolean (*GMarshalFunc_BOOLEAN__INT) (gpointer data1,
gint arg_1,
gpointer data2);
register GMarshalFunc_BOOLEAN__INT callback;
register GCClosure *cc = (GCClosure*) closure;
register gpointer data1, data2;
gboolean v_return;
g_return_if_fail (return_value != NULL);
g_return_if_fail (n_param_values == 2);
if (G_CCLOSURE_SWAP_DATA (closure))
{
data1 = closure->data;
data2 = g_value_peek_pointer (param_values + 0);
}
else
{
data1 = g_value_peek_pointer (param_values + 0);
data2 = closure->data;
}
callback = (GMarshalFunc_BOOLEAN__INT) (marshal_data ? marshal_data : cc->callback);
v_return = callback (data1,
g_marshal_value_peek_int (param_values + 1),
data2);
g_value_set_boolean (return_value, v_return);
}
/* FLAGS:OBJECT,OBJECT (thunar-marshal.list:5) */
void
_thunar_marshal_FLAGS__OBJECT_OBJECT (GClosure *closure,
GValue *return_value G_GNUC_UNUSED,
guint n_param_values,
const GValue *param_values,
gpointer invocation_hint G_GNUC_UNUSED,
gpointer marshal_data)
{
typedef guint (*GMarshalFunc_FLAGS__OBJECT_OBJECT) (gpointer data1,
gpointer arg_1,
gpointer arg_2,
gpointer data2);
register GMarshalFunc_FLAGS__OBJECT_OBJECT callback;
register GCClosure *cc = (GCClosure*) closure;
register gpointer data1, data2;
guint v_return;
g_return_if_fail (return_value != NULL);
g_return_if_fail (n_param_values == 3);
if (G_CCLOSURE_SWAP_DATA (closure))
{
data1 = closure->data;
data2 = g_value_peek_pointer (param_values + 0);
}
else
{
data1 = g_value_peek_pointer (param_values + 0);
data2 = closure->data;
}
callback = (GMarshalFunc_FLAGS__OBJECT_OBJECT) (marshal_data ? marshal_data : cc->callback);
v_return = callback (data1,
g_marshal_value_peek_object (param_values + 1),
g_marshal_value_peek_object (param_values + 2),
data2);
g_value_set_flags (return_value, v_return);
}
/* FLAGS:STRING,FLAGS (thunar-marshal.list:6) */
void
_thunar_marshal_FLAGS__STRING_FLAGS (GClosure *closure,
GValue *return_value G_GNUC_UNUSED,
guint n_param_values,
const GValue *param_values,
gpointer invocation_hint G_GNUC_UNUSED,
gpointer marshal_data)
{
typedef guint (*GMarshalFunc_FLAGS__STRING_FLAGS) (gpointer data1,
gpointer arg_1,
guint arg_2,
gpointer data2);
register GMarshalFunc_FLAGS__STRING_FLAGS callback;
register GCClosure *cc = (GCClosure*) closure;
register gpointer data1, data2;
guint v_return;
g_return_if_fail (return_value != NULL);
g_return_if_fail (n_param_values == 3);
if (G_CCLOSURE_SWAP_DATA (closure))
{
data1 = closure->data;
data2 = g_value_peek_pointer (param_values + 0);
}
else
{