realtime file monitor
authorVladimir Nadvornik <nadvornik@suse.cz>
Fri, 6 Jun 2008 21:50:09 +0000 (21:50 +0000)
committerVladimir Nadvornik <nadvornik@suse.cz>
Fri, 6 Jun 2008 21:50:09 +0000 (21:50 +0000)
src/filedata.c
src/filedata.h
src/layout.c
src/typedefs.h
src/view_file_icon.c
src/view_file_list.c

index 2ae5ab2..84d8cfb 100644 (file)
@@ -1443,17 +1443,28 @@ typedef struct _NotifyData NotifyData;
 struct _NotifyData {
        FileDataNotifyFunc func;
        gpointer data;
+       NotifyPriority priority;
        };
 
 static GList *notify_func_list = NULL;
 
-gint file_data_register_notify_func(FileDataNotifyFunc func, gpointer data)
+static gint file_data_notify_sort(gconstpointer a, gconstpointer b)
+{
+       NotifyData *nda = (NotifyData *)a;
+       NotifyData *ndb = (NotifyData *)b;
+       if (nda->priority < ndb->priority) return -1;
+       if (nda->priority > ndb->priority) return 1;
+       return 0;
+}
+
+gint file_data_register_notify_func(FileDataNotifyFunc func, gpointer data, NotifyPriority priority)
 {
        NotifyData *nd = g_new(NotifyData, 1);
        nd->func = func;
        nd->data = data;
-       notify_func_list = g_list_prepend(notify_func_list, nd);
-       DEBUG_1("Notify func registered: %p\n", nd);
+       nd->priority = priority;
+       notify_func_list = g_list_insert_sorted(notify_func_list, nd, file_data_notify_sort);
+       DEBUG_1("Notify func registered: %p", nd);
        return TRUE;
 }
 
@@ -1468,7 +1479,7 @@ gint file_data_unregister_notify_func(FileDataNotifyFunc func, gpointer data)
                        {
                        notify_func_list = g_list_delete_link(notify_func_list, work);
                        g_free(nd);
-                       DEBUG_1("Notify func unregistered: %p\n", nd);
+                       DEBUG_1("Notify func unregistered: %p", nd);
                        return TRUE;
                        }
                work = work->next;
@@ -1483,7 +1494,7 @@ void file_data_send_notification(FileData *fd)
        while(work)
                {
                NotifyData *nd = (NotifyData *)work->data;
-               DEBUG_1("Notify func calling: %p %s\n", nd, fd->path);
+               DEBUG_1("Notify func calling: %p %s", nd, fd->path);
                nd->func(fd, nd->data);
                work = work->next;
                }
@@ -1494,6 +1505,78 @@ void file_data_sc_send_notification(FileData *fd)
 }
 
 
+static GHashTable *file_data_monitor_pool = NULL;
+static gint realtime_monitor_id = -1;
+
+static void realtime_monitor_check_cb(gpointer key, gpointer value, gpointer data)
+{
+       FileData *fd = key;
+       struct stat st;
+
+       stat_utf8(fd->path, &st);
+       
+       file_data_check_changed_files(fd, &st);
+       
+       DEBUG_1("monitor %s", fd->path);
+}
+
+static gboolean realtime_monitor_cb(gpointer data)
+{
+       g_hash_table_foreach(file_data_monitor_pool, realtime_monitor_check_cb, NULL);
+       return TRUE;
+}
+
+gint file_data_register_real_time_monitor(FileData *fd)
+{
+       gint count = 0;
+       
+       file_data_ref(fd);
+       
+       if (!file_data_monitor_pool)
+               file_data_monitor_pool = g_hash_table_new(g_direct_hash, g_direct_equal);
+       
+       count = GPOINTER_TO_INT(g_hash_table_lookup(file_data_monitor_pool, fd));
+
+       DEBUG_1("Register realtime %d %s", count, fd->path);
+       
+       count++;
+       g_hash_table_insert(file_data_monitor_pool, fd, GINT_TO_POINTER(count));
+       
+       if (realtime_monitor_id == -1)
+               {
+               realtime_monitor_id = g_timeout_add(5000, realtime_monitor_cb, NULL);
+               }
+       return TRUE;
+}
+
+gint file_data_unregister_real_time_monitor(FileData *fd)
+{
+       gint count;
+       g_assert(file_data_monitor_pool);
+       
+       count = GPOINTER_TO_INT(g_hash_table_lookup(file_data_monitor_pool, fd));
+       
+       DEBUG_1("Unregister realtime %d %s", count, fd->path);
+       
+       g_assert(count > 0);
+       
+       count--;
+       
+       if (count == 0)
+               g_hash_table_remove(file_data_monitor_pool, fd);
+       else
+               g_hash_table_insert(file_data_monitor_pool, fd, GINT_TO_POINTER(count));
+
+       file_data_unref(fd);
+       
+       if (g_hash_table_size(file_data_monitor_pool) == 0)
+               {
+               g_source_remove(realtime_monitor_id);
+               realtime_monitor_id = -1;
+               return FALSE;
+               }
+       return TRUE;
+}
 
 
 
index 32510c0..ece237e 100644 (file)
@@ -78,7 +78,11 @@ void file_data_sc_free_ci(FileData *fd);
 void file_data_sc_free_ci_list(GList *fd_list);
 
 typedef void (*FileDataNotifyFunc)(FileData *fd, gpointer data);
-gint file_data_register_notify_func(FileDataNotifyFunc func, gpointer data);
+gint file_data_register_notify_func(FileDataNotifyFunc func, gpointer data, NotifyPriority priority);
 gint file_data_unregister_notify_func(FileDataNotifyFunc func, gpointer data);
 void file_data_send_notification(FileData *fd);
+
+gint file_data_register_real_time_monitor(FileData *fd);
+gint file_data_unregister_real_time_monitor(FileData *fd);
+
 #endif
index a56d4a6..29489c5 100644 (file)
@@ -937,8 +937,13 @@ gint layout_set_fd(LayoutWindow *lw, FileData *fd)
 
        if (isdir(fd->path))
                {
-               file_data_unref(lw->dir_fd);
+               if (lw->dir_fd)
+                       {
+                       file_data_unregister_real_time_monitor(lw->dir_fd);
+                       file_data_unref(lw->dir_fd);
+                       }
                lw->dir_fd = file_data_ref(fd);
+               file_data_register_real_time_monitor(fd);
                }
        else
                {
@@ -951,8 +956,13 @@ gint layout_set_fd(LayoutWindow *lw, FileData *fd)
                        }
                else if (isdir(base))
                        {
-                       file_data_unref(lw->dir_fd);
+                       if (lw->dir_fd)
+                               {
+                               file_data_unregister_real_time_monitor(lw->dir_fd);
+                               file_data_unref(lw->dir_fd);
+                               }
                        lw->dir_fd = file_data_new_simple(base);
+                       file_data_register_real_time_monitor(lw->dir_fd);
                        g_free(base);
                        }
                else
@@ -1608,6 +1618,7 @@ void layout_style_set(LayoutWindow *lw, gint style, const gchar *order)
        layout_image_full_screen_stop(lw);
 
        dir_fd = lw->dir_fd;
+       file_data_unregister_real_time_monitor(lw->dir_fd);
        lw->dir_fd = NULL;
        lw->image = NULL;
        lw->utility_box = NULL;
@@ -1826,16 +1837,16 @@ void layout_free(LayoutWindow *lw)
 
        layout_window_list = g_list_remove(layout_window_list, lw);
 
-       if (lw->last_time_id != -1)
-               {
-               g_source_remove(lw->last_time_id);
-               }
-
+       
        layout_bars_close(lw);
 
        gtk_widget_destroy(lw->window);
 
-       file_data_unref(lw->dir_fd);
+       if (lw->dir_fd) 
+               {
+               file_data_unregister_real_time_monitor(lw->dir_fd);
+               file_data_unref(lw->dir_fd);
+               }
 
        g_free(lw);
 }
@@ -1979,7 +1990,7 @@ LayoutWindow *layout_new_with_geometry(FileData *dir_fd, gint popped, gint hidde
 
        /* set up the time stat timeout */
        lw->last_version = 0;
-       lw->last_time_id = g_timeout_add(5000, layout_check_for_update_cb, lw);
+//     lw->last_time_id = g_timeout_add(5000, layout_check_for_update_cb, lw);
 
        if (geometry)
                {
index 3801a0e..a848978 100644 (file)
@@ -131,6 +131,13 @@ typedef enum {
        SS_ERR_OTHER,
 } SecureSaveErrno;
 
+typedef enum {
+       NOTIFY_PRIORITY_HIGH = 0,
+       NOTIFY_PRIORITY_MEDIUM,
+       NOTIFY_PRIORITY_LOW
+} NotifyPriority;
+       
+
 
 #define MAX_SPLIT_IMAGES 4
 
@@ -539,7 +546,6 @@ struct _LayoutWindow
 
        /* directory update check */
 
-       gint last_time_id;
        gint last_version;
 
        /* misc */
index 440daf8..3921886 100644 (file)
@@ -2301,7 +2301,7 @@ ViewFile *vficon_new(ViewFile *vf, FileData *dir_fd)
        /* force VFICON_INFO(vf, columns) to be at least 1 (sane) - this will be corrected in the size_cb */
        vficon_populate_at_new_size(vf, 1, 1, FALSE);
 
-       file_data_register_notify_func(vficon_notify_cb, vf);
+       file_data_register_notify_func(vficon_notify_cb, vf, NOTIFY_PRIORITY_MEDIUM);
 
        return vf;
 }
index 3197ce5..90e464e 100644 (file)
@@ -1463,7 +1463,7 @@ void vflist_selection_to_mark(ViewFile *vf, gint mark, SelectionToMarkMode mode)
                
                file_data_unregister_notify_func(vflist_notify_cb, vf); /* we don't need the notification */
                file_data_increment_version(fd);
-               file_data_register_notify_func(vflist_notify_cb, vf);
+               file_data_register_notify_func(vflist_notify_cb, vf, NOTIFY_PRIORITY_MEDIUM);
 
                gtk_tree_store_set(GTK_TREE_STORE(store), &iter, FILE_COLUMN_MARKS + n, fd->marks[n], -1);
 
@@ -1570,7 +1570,7 @@ gint vflist_refresh(ViewFile *vf)
 
                ret = filelist_read(vf->dir_fd, &vf->list, NULL);
 
-               file_data_register_notify_func(vflist_notify_cb, vf);
+               file_data_register_notify_func(vflist_notify_cb, vf, NOTIFY_PRIORITY_MEDIUM);
 
                DEBUG_1("%s vflist_refresh: sort", get_exec_time());
                vf->list = filelist_sort(vf->list, vf->sort_method, vf->sort_ascend);
@@ -1711,7 +1711,7 @@ static void vflist_listview_mark_toggled_cb(GtkCellRendererToggle *cell, gchar *
        fd->marks[col_idx - FILE_COLUMN_MARKS] = mark;
        file_data_unregister_notify_func(vflist_notify_cb, vf); /* we don't need the notification */
        file_data_increment_version(fd);
-       file_data_register_notify_func(vflist_notify_cb, vf);
+       file_data_register_notify_func(vflist_notify_cb, vf, NOTIFY_PRIORITY_MEDIUM);
 
        gtk_tree_store_set(store, &iter, col_idx, mark, -1);
        gtk_tree_path_free(path);
@@ -1832,7 +1832,7 @@ ViewFile *vflist_new(ViewFile *vf, FileData *dir_fd)
        vflist_listview_add_column(vf, FILE_COLUMN_SIZE, _("Size"), FALSE, TRUE, FALSE);
        vflist_listview_add_column(vf, FILE_COLUMN_DATE, _("Date"), FALSE, TRUE, FALSE);
 
-       file_data_register_notify_func(vflist_notify_cb, vf);
+       file_data_register_notify_func(vflist_notify_cb, vf, NOTIFY_PRIORITY_MEDIUM);
        return vf;
 }