18744N/Adiff -Nrup -x '*.orig' -x '*.rej' -x '*.*~' ../SUNWgnome-file-mgr-2.30.0-b4/nautilus-2.30.1/configure.in nautilus-2.30.1/configure.in
18744N/A--- ../SUNWgnome-file-mgr-2.30.0-b4/nautilus-2.30.1/configure.in 2010-05-14 17:16:20.583765747 +0200
18744N/A+++ nautilus-2.30.1/configure.in 2010-05-14 17:16:39.539580939 +0200
18556N/A@@ -232,6 +232,52 @@ if test "x$enable_packagekit" != "xno";
18556N/A msg_packagekit=yes
18556N/A AC_DEFINE(ENABLE_PACKAGEKIT, 1, [define to enable PackageKit mimetype installer])
18556N/A fi
18556N/A+dnl ==========================================================================
18556N/A+
18556N/A+dnl ********************
18556N/A+dnl * Check for libzfs *
18556N/A+dnl ********************
18556N/A+ZFS_LIBS=
18556N/A+msg_zfs=no
18556N/A+AC_CHECK_LIB(zfs, zfs_iter_root,
18556N/A+ [AC_CHECK_HEADER(libzfs.h,
18556N/A+ [AC_DEFINE(HAVE_ZFS, 1, [Define to 1 if ZFS is available])
18556N/A+ ZFS_LIBS="-lzfs"
18556N/A+ msg_zfs=yes])
18556N/A+ ])
18556N/A+AC_SUBST(ZFS_LIBS)
18556N/A+
18556N/A+dnl ==========================================================================
18556N/A+
18556N/A+dnl ********************
18556N/A+dnl * Check for libscf*
18556N/A+dnl ********************
18556N/A+SCF_LIBS=
18556N/A+msg_scf=no
18556N/A+AC_CHECK_LIB(scf, scf_handle_bind,
18556N/A+ [AC_CHECK_HEADER(libscf.h,
18556N/A+ [AC_DEFINE(HAVE_SCF, 1, [Define to 1 if SCF is available])
18556N/A+ SCF_LIBS="-lscf"
18556N/A+ msg_scf=yes])
18556N/A+ ])
18556N/A+AC_SUBST(SCF_LIBS)
18556N/A+
18556N/A+dnl ==========================================================================
18556N/A+
18556N/A+dnl ********************
18556N/A+dnl * Check for libscf*
18556N/A+dnl ********************
18556N/A+NVPAIR_LIBS=
18556N/A+msg_nvpair=no
18556N/A+AC_CHECK_LIB(nvpair, nvpair_value_match,
18556N/A+ [AC_CHECK_HEADER(libscf.h,
18556N/A+ [AC_DEFINE(NVPAIR_LIBS, 1, [Define to 1 if nvpair is available])
18556N/A+ NVPAIR_LIBS="-lnvpair"
18556N/A+ msg_nvpair=yes])
18556N/A+ ])
18556N/A+AC_SUBST(NVPAIR_LIBS)
18556N/A+
18556N/A+
18556N/A
18556N/A dnl ==========================================================================
18556N/A
20808N/A--- nautilus-3.1.3/icons/Makefile.am.orig 2011-04-04 19:01:22.000000000 +0100
20808N/A+++ nautilus-3.1.3/icons/Makefile.am 2011-07-22 09:20:35.708887571 +0100
20808N/A@@ -4,7 +4,11 @@
20808N/A
20808N/A icon_DATA =\
20808N/A audio.svg \
20808N/A+ camera.png \
18556N/A knob.png \
18556N/A+ restore.png \
20808N/A+ restore-no.png \
18556N/A+ restore-search.png \
20808N/A thumbnail_frame.png \
18556N/A $(NULL)
18556N/A
20808N/A--- nautilus-3.1.3/libnautilus-private/Makefile.am.orig 2011-07-22 09:23:13.721321695 +0100
20808N/A+++ nautilus-3.1.3/libnautilus-private/Makefile.am 2011-07-22 09:27:45.285633388 +0100
20808N/A@@ -49,6 +49,9 @@
20808N/A $(BASE_LIBS) \
20808N/A $(COMMON_LIBS) \
20808N/A $(NAUTILUS_LIBS) \
18556N/A+ $(ZFS_LIBS) \
18556N/A+ $(SCF_LIBS) \
18556N/A+ $(NVPAIR_LIBS) \
18556N/A $(NULL)
18556N/A
20808N/A libnautilus_private_la_SOURCES = \
20808N/A@@ -192,6 +195,8 @@
20808N/A nautilus-vfs-directory.h \
20808N/A nautilus-vfs-file.c \
20808N/A nautilus-vfs-file.h \
18556N/A+ nautilus-zfs.c \
20808N/A+ nautilus-zfs.h \
18556N/A $(NULL)
18556N/A
20808N/A nodist_libnautilus_private_la_SOURCES =\
20808N/A--- nautilus-3.1.3/libnautilus-private/org.gnome.nautilus.gschema.xml.in.orig 2011-07-22 09:34:01.449051792 +0100
20808N/A+++ nautilus-3.1.3/libnautilus-private/org.gnome.nautilus.gschema.xml.in 2011-07-22 09:38:31.164878925 +0100
20808N/A@@ -72,6 +72,11 @@
20808N/A <_summary>Where to position newly open tabs in browser windows.</_summary>
20808N/A <_description>If set to "after-current-tab", then new tabs are inserted after the current tab. If set to "end", then new tabs are appended to the end of the tab list.</_description>
20808N/A </key>
20808N/A+ <key name="enable-time-slider" type="b">
20808N/A+ <default>true</default>
20808N/A+ <_summary>Enables the visualization of ZFS snapshots timeline</_summary>
20808N/A+ <_description>If set to true, the visualization of the ZFS snapshots timeline is enabled.</_description>
20808N/A+ </key>
20808N/A <key name="always-use-browser" type="b">
20808N/A <default>true</default>
20808N/A <_summary>Enables the classic Nautilus behavior, where all windows are browsers</_summary>
20808N/A--- nautilus-3.1.3/libnautilus-private/nautilus-column-utilities.c.orig 2011-04-04 19:01:22.000000000 +0100
20808N/A+++ nautilus-3.1.3/libnautilus-private/nautilus-column-utilities.c 2011-07-22 09:46:21.698069053 +0100
20808N/A@@ -129,6 +129,15 @@
20808N/A "label", _("Location"),
20808N/A "description", _("The location of the file."),
18556N/A NULL));
20808N/A+ columns = g_list_append (columns,
20808N/A+ g_object_new (NAUTILUS_TYPE_COLUMN,
20808N/A+ "name", "restore_info",
20808N/A+ "attribute", "restore_info",
20808N/A+ /* SUN_BRANDING */
20808N/A+ "label", _("Restore information"),
20808N/A+ /* SUN_BRANDING */
20808N/A+ "description", _("Restore information of the file."),
20808N/A+ NULL));
18556N/A
18556N/A return columns;
18556N/A }
18744N/Adiff -Nrup -x '*.orig' -x '*.rej' -x '*.*~' ../SUNWgnome-file-mgr-2.30.0-b4/nautilus-2.30.1/libnautilus-private/nautilus-directory-async.c nautilus-2.30.1/libnautilus-private/nautilus-directory-async.c
18744N/A--- ../SUNWgnome-file-mgr-2.30.0-b4/nautilus-2.30.1/libnautilus-private/nautilus-directory-async.c 2010-05-14 17:16:20.620971445 +0200
18744N/A+++ nautilus-2.30.1/libnautilus-private/nautilus-directory-async.c 2010-05-14 17:16:39.543203000 +0200
18556N/A@@ -658,6 +658,7 @@ remove_monitor_link (NautilusDirectory *
18556N/A g_list_free_1 (link);
18556N/A }
18556N/A }
18556N/A+
18556N/A
18556N/A static void
18556N/A remove_monitor (NautilusDirectory *directory,
18556N/A@@ -722,6 +723,10 @@ nautilus_directory_set_up_request (Nauti
18556N/A REQUEST_SET_TYPE (request, REQUEST_FILESYSTEM_INFO);
18556N/A }
18556N/A
18556N/A+ if (file_attributes & NAUTILUS_FILE_ATTRIBUTE_RESTORE_INFO) {
18556N/A+ REQUEST_SET_TYPE (request, REQUEST_RESTORE_INFO);
18556N/A+ }
18556N/A+
18556N/A return request;
18556N/A }
18556N/A
18556N/A@@ -4759,6 +4764,18 @@ cancel_link_info_for_file (NautilusDirec
18556N/A }
18556N/A }
18556N/A
18556N/A+void nautilus_directory_cancel_restore_info (NautilusDirectory *directory)
18556N/A+{
18556N/A+ if (NAUTILUS_IS_DIRECTORY (directory))
18556N/A+ {
18556N/A+ if (directory->details->restore_cancel)
18556N/A+ {
18556N/A+ g_cancellable_cancel (directory->details->restore_cancel);
18556N/A+ directory->details->restore_cancel = NULL;
18556N/A+ }
18556N/A+ }
18556N/A+}
18556N/A+
18556N/A
18556N/A static void
18556N/A cancel_loading_attributes (NautilusDirectory *directory,
18556N/A@@ -4801,7 +4818,9 @@ cancel_loading_attributes (NautilusDirec
18556N/A if (REQUEST_WANTS_TYPE (request, REQUEST_MOUNT)) {
18556N/A mount_cancel (directory);
18556N/A }
18556N/A-
18556N/A+ if (REQUEST_WANTS_TYPE (request, REQUEST_RESTORE_INFO)) {
18556N/A+ nautilus_directory_cancel_restore_info (directory);
18556N/A+ }
18556N/A nautilus_directory_async_state_changed (directory);
18556N/A }
18556N/A
18556N/A@@ -4843,7 +4862,9 @@ nautilus_directory_cancel_loading_file_a
18556N/A if (REQUEST_WANTS_TYPE (request, REQUEST_MOUNT)) {
18556N/A cancel_mount_for_file (directory, file);
18556N/A }
18556N/A-
18556N/A+ if (REQUEST_WANTS_TYPE (request, REQUEST_RESTORE_INFO)) {
18556N/A+ nautilus_directory_cancel_restore_info (directory);
18556N/A+ }
18556N/A nautilus_directory_async_state_changed (directory);
18556N/A }
18556N/A
18744N/Adiff -Nrup -x '*.orig' -x '*.rej' -x '*.*~' ../SUNWgnome-file-mgr-2.30.0-b4/nautilus-2.30.1/libnautilus-private/nautilus-directory-private.h nautilus-2.30.1/libnautilus-private/nautilus-directory-private.h
18744N/A--- ../SUNWgnome-file-mgr-2.30.0-b4/nautilus-2.30.1/libnautilus-private/nautilus-directory-private.h 2009-12-09 12:03:51.000000000 +0100
18744N/A+++ nautilus-2.30.1/libnautilus-private/nautilus-directory-private.h 2010-05-14 17:16:39.543661242 +0200
18556N/A@@ -58,6 +58,7 @@ typedef enum {
18556N/A REQUEST_THUMBNAIL,
18556N/A REQUEST_MOUNT,
18556N/A REQUEST_FILESYSTEM_INFO,
18556N/A+ REQUEST_RESTORE_INFO,
18556N/A REQUEST_TYPE_LAST
18556N/A } RequestType;
18556N/A
18556N/A@@ -140,6 +141,9 @@ struct NautilusDirectoryDetails
18556N/A
18556N/A guint64 free_space; /* (guint)-1 for unknown */
18556N/A time_t free_space_read; /* The time free_space was updated, or 0 for never */
18556N/A+ GCancellable *restore_cancel;
18556N/A+ /* zfs snapshot info */
18556N/A+ GList *zfs_snapshots;
18556N/A };
18556N/A
18556N/A NautilusDirectory *nautilus_directory_get_existing (GFile *location);
20808N/A--- nautilus-3.1.3/libnautilus-private/nautilus-directory.c.orig 2011-07-22 15:39:09.879596935 +0100
20808N/A+++ nautilus-3.1.3/libnautilus-private/nautilus-directory.c 2011-07-22 15:46:56.201033321 +0100
20808N/A@@ -35,6 +35,7 @@
18556N/A #include "nautilus-metadata.h"
18556N/A #include "nautilus-desktop-directory.h"
18556N/A #include "nautilus-vfs-directory.h"
18556N/A+#include "nautilus-zfs.h"
18556N/A #include <eel/eel-glib-extensions.h>
18556N/A #include <eel/eel-gtk-macros.h>
18556N/A #include <eel/eel-string.h>
20808N/A@@ -129,6 +130,8 @@
18556N/A directory->details->low_priority_queue = nautilus_file_queue_new ();
18556N/A directory->details->extension_queue = nautilus_file_queue_new ();
18556N/A directory->details->free_space = (guint64)-1;
18556N/A+ directory->details->zfs_snapshots = NULL;
18556N/A+ directory->details->restore_cancel = NULL;
18556N/A }
18556N/A
18556N/A NautilusDirectory *
20808N/A@@ -160,7 +163,7 @@
18556N/A nautilus_directory_finalize (GObject *object)
18556N/A {
18556N/A NautilusDirectory *directory;
18556N/A-
18556N/A+
18556N/A directory = NAUTILUS_DIRECTORY (object);
18556N/A
18556N/A g_hash_table_remove (directories, directory->details->location);
20808N/A@@ -196,7 +199,13 @@
18556N/A if (directory->details->hidden_file_hash) {
18556N/A g_hash_table_destroy (directory->details->hidden_file_hash);
18556N/A }
18556N/A-
18556N/A+
18556N/A+ if (directory->details->zfs_snapshots) {
18556N/A+ ts_free_snapshots (directory->details->zfs_snapshots);
18556N/A+ }
18556N/A+ if (directory->details->restore_cancel)
18556N/A+ g_cancellable_cancel (directory->details->restore_cancel);
18556N/A+
18556N/A nautilus_file_queue_destroy (directory->details->high_priority_queue);
18556N/A nautilus_file_queue_destroy (directory->details->low_priority_queue);
18556N/A nautilus_file_queue_destroy (directory->details->extension_queue);
20808N/A@@ -308,11 +317,26 @@
18556N/A g_hash_table_foreach (directories, async_state_changed_one, NULL);
18556N/A }
18556N/A
18556N/A+static gboolean time_slider_enabled = TRUE;
18556N/A+
20808N/A+gboolean is_time_slider_enabled ()
18556N/A+{
20808N/A+ return time_slider_enabled;
18556N/A+}
18556N/A+
18556N/A+static void time_slider_pref_changed_callback (gpointer callback_data)
18556N/A+{
20808N/A+ time_slider_enabled = g_settings_get_boolean(nautilus_preferences,
20808N/A+ NAUTILUS_PREFERENCES_ENABLE_TIME_SLIDER);
18556N/A+}
18556N/A+
18556N/A static void
18556N/A add_preferences_callbacks (void)
18556N/A {
18556N/A nautilus_global_preferences_init ();
18556N/A
20808N/A+ time_slider_enabled = g_settings_get_boolean(nautilus_preferences,
20808N/A+ NAUTILUS_PREFERENCES_ENABLE_TIME_SLIDER);
20808N/A g_signal_connect_swapped (nautilus_preferences,
20808N/A "changed::" NAUTILUS_PREFERENCES_SHOW_HIDDEN_FILES,
20808N/A G_CALLBACK(filtering_changed_callback),
20808N/A@@ -330,6 +354,10 @@
20808N/A "changed::" NAUTILUS_PREFERENCES_DATE_FORMAT,
20808N/A G_CALLBACK(async_data_preference_changed_callback),
20808N/A NULL);
20808N/A+ g_signal_connect_swapped (nautilus_preferences,
20808N/A+ "changed::" NAUTILUS_PREFERENCES_ENABLE_TIME_SLIDER,
20808N/A+ G_CALLBACK(time_slider_pref_changed_callback),
20808N/A+ NULL);
18556N/A }
18556N/A
20808N/A static void
20808N/A@@ -534,6 +562,7 @@
18556N/A {
18556N/A NautilusDirectory *directory;
18556N/A char *uri;
18556N/A+ char *path;
18556N/A
18556N/A uri = g_file_get_uri (location);
18556N/A
20808N/A@@ -545,10 +574,13 @@
18556N/A directory = NAUTILUS_DIRECTORY (nautilus_search_directory_new_from_saved_search (uri));
18556N/A } else {
18556N/A directory = NAUTILUS_DIRECTORY (g_object_new (NAUTILUS_TYPE_VFS_DIRECTORY, NULL));
18556N/A+ path = g_file_get_path (location);
18556N/A+ g_free (path);
18556N/A }
18556N/A
18556N/A set_directory_location (directory, location);
18556N/A
18556N/A+
18556N/A g_free (uri);
18556N/A
18556N/A return directory;
20808N/A@@ -567,6 +599,201 @@
18556N/A g_file_is_native (directory->details->location);
18556N/A }
18556N/A
18556N/A+typedef struct {
18556N/A+ NautilusDirectory *dir;
18556N/A+ GCancellable *cancel;
18556N/A+ TsReadyCallback callback;
18556N/A+ gpointer callback_user_data;
18556N/A+} QuerySnapshotsAsyncData;
18556N/A+
18556N/A+
18556N/A+static void snapshot_list_ready_callback (GObject *source_object,
18556N/A+ GAsyncResult *res,
18556N/A+ gpointer user_data)
18556N/A+{
18556N/A+ GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
18556N/A+ QuerySnapshotsAsyncData *data = (QuerySnapshotsAsyncData*) user_data;
18556N/A+
18556N/A+ if (!g_cancellable_is_cancelled (data->cancel))
18556N/A+ {
18556N/A+ data->dir->details->zfs_snapshots = g_simple_async_result_get_op_res_gpointer (simple);
18556N/A+ }
18556N/A+
18556N/A+ data->callback (data->dir, data->cancel, data->callback_user_data);
18556N/A+}
18556N/A+
18556N/A+void
18556N/A+nautilus_directory_get_snapshots_async (NautilusDirectory *directory,
18556N/A+ TsReadyCallback ready_callback,
18556N/A+ GCancellable *cancel,
18556N/A+ gpointer callback_user_data)
18556N/A+{
18556N/A+ g_assert (NAUTILUS_IS_DIRECTORY (directory));
18556N/A+
18556N/A+ if (directory->details->location == NULL)
18556N/A+ return;
18556N/A+
18556N/A+ if (directory->details->zfs_snapshots) {
18556N/A+ ts_free_snapshots (directory->details->zfs_snapshots);
18556N/A+ directory->details->zfs_snapshots = NULL;
18556N/A+ }
18556N/A+
18556N/A+ if (is_time_slider_enabled ())
18556N/A+ {
18556N/A+ QuerySnapshotsAsyncData *data;
18556N/A+ data = g_new0 (QuerySnapshotsAsyncData,1);
18556N/A+ data->dir = directory;
18556N/A+ data->cancel = cancel;
18556N/A+ data->callback = ready_callback;
18556N/A+ data->callback_user_data = callback_user_data;
18556N/A+
18556N/A+ ts_get_snapshots_for_dir_async (directory->details->location,
18556N/A+ snapshot_list_ready_callback,
18556N/A+ cancel,
18556N/A+ data);
18556N/A+ }
18556N/A+}
18556N/A+
18556N/A+gboolean
18556N/A+nautilus_directory_has_snapshots (NautilusDirectory *directory)
18556N/A+{
18556N/A+ g_assert (NAUTILUS_IS_DIRECTORY (directory));
18556N/A+
18556N/A+ if (directory->details->zfs_snapshots)
18556N/A+ return TRUE;
18556N/A+
18556N/A+ return FALSE;
18556N/A+}
18556N/A+int
18556N/A+nautilus_directory_get_num_snapshots (NautilusDirectory *directory)
18556N/A+{
18556N/A+ g_assert (NAUTILUS_IS_DIRECTORY (directory));
18556N/A+
18556N/A+ if (directory->details->zfs_snapshots)
18556N/A+ {
18556N/A+ int i = 0;
18556N/A+ GList *tmp;
18556N/A+ for (tmp = directory->details->zfs_snapshots;tmp;tmp = tmp->next)
18556N/A+ i++;
18556N/A+ return i;
18556N/A+ }
18556N/A+ return 0;
18556N/A+}
18556N/A+
18556N/A+gboolean
18556N/A+nautilus_directory_is_in_snapshot (NautilusDirectory *directory)
18556N/A+{
18556N/A+ char *directory_uri;
18556N/A+ gboolean result = FALSE;
18556N/A+
18556N/A+ g_return_val_if_fail (NAUTILUS_IS_DIRECTORY (directory), FALSE);
18556N/A+
18556N/A+ directory_uri = nautilus_directory_get_uri (directory);
18556N/A+
18556N/A+ result = ts_is_in_snapshot (directory_uri);
18556N/A+
18556N/A+ g_free (directory_uri);
18556N/A+
18556N/A+ return result;
18556N/A+}
18556N/A+
18556N/A+GList *
18556N/A+nautilus_directory_get_snapshots (NautilusDirectory *directory)
18556N/A+{
18556N/A+ g_assert (NAUTILUS_IS_DIRECTORY (directory));
18556N/A+
18556N/A+ return directory->details->zfs_snapshots;
18556N/A+}
18556N/A+
18556N/A+void nautilus_directory_remove_snapshot (NautilusDirectory *directory,
18556N/A+ ZfsDataSet *snap)
18556N/A+{
18556N/A+ if (directory->details->zfs_snapshots)
18556N/A+ {
18556N/A+ directory->details->zfs_snapshots = g_list_remove (directory->details->zfs_snapshots, snap);
18556N/A+ ts_free_zfs_dataset (snap);
18556N/A+ }
18556N/A+}
18556N/A+/* return true if snapdir dir path is a dir or subdir of refdir */
18556N/A+gboolean
18556N/A+nautilus_directory_is_a_snapshot_dir_of (NautilusDirectory *snapdir,
18556N/A+ NautilusDirectory *refdir)
18556N/A+{
18556N/A+
18556N/A+ gboolean result = FALSE;
18556N/A+
18556N/A+ if (nautilus_directory_is_in_snapshot (snapdir))
18556N/A+ {
18556N/A+ char snapdir_root_real_path [PATH_MAX+1];
18556N/A+ char refdir_real_path [PATH_MAX+1];
18556N/A+ NautilusDirectory *snapdir_root = nautilus_directory_get_snap_root (snapdir);
18556N/A+ GFile *snapdir_root_file = nautilus_directory_get_location (snapdir_root);
18556N/A+ GFile *refdir_file = nautilus_directory_get_location (refdir);
18556N/A+ char* snapdir_root_path = g_file_get_path (snapdir_root_file);
18556N/A+ char* refdir_path = g_file_get_path (refdir_file);
18556N/A+
18556N/A+ if (ts_realpath (snapdir_root_path, snapdir_root_real_path) &&
18556N/A+ ts_realpath (refdir_path, refdir_real_path))
18556N/A+ {
18556N/A+ if (g_strrstr (snapdir_root_real_path,refdir_real_path))
18556N/A+ result = TRUE;
18556N/A+ }
18556N/A+
18556N/A+ g_free (snapdir_root_path);
18556N/A+ g_free (refdir_path);
18556N/A+ g_object_unref (snapdir_root_file);
18556N/A+ g_object_unref (refdir_file);
18556N/A+ g_object_unref (snapdir_root);
18556N/A+ }
18556N/A+
18556N/A+ return result;
18556N/A+}
18556N/A+
18556N/A+NautilusDirectory *nautilus_directory_get_snap_root (NautilusDirectory *directory)
18556N/A+{
18556N/A+ char *directory_uri, *snap_root;
18556N/A+ char *zfs, *iter;
18556N/A+ int count = 0;
18556N/A+ NautilusDirectory *new_dir;
18556N/A+
18556N/A+ g_assert (NAUTILUS_IS_DIRECTORY (directory));
18556N/A+
18556N/A+ directory_uri = nautilus_directory_get_uri (directory);
18556N/A+
18556N/A+
18556N/A+ if (!nautilus_directory_is_in_snapshot (directory))
18556N/A+ {
18556N/A+ g_free (directory_uri);
18556N/A+ return directory;
18556N/A+ }
18556N/A+
18556N/A+ /*remove .zfs/snapshot/blah/ */
18556N/A+ zfs = g_strrstr (directory_uri, ".zfs/snapshot/");
18556N/A+ iter = zfs;
18556N/A+
18556N/A+ if (iter)
18556N/A+ {
18556N/A+ iter += sizeof (".zfs/snapshot/");
18556N/A+ while (*iter != '/' && *iter != '\0')
18556N/A+ iter++;
18556N/A+
18556N/A+ if (*iter == '/')
18556N/A+ iter++;
18556N/A+
18556N/A+ *zfs = '\0';
18556N/A+ snap_root = g_strdup_printf ("%s%s", directory_uri, iter);
18556N/A+
18556N/A+ *zfs = 'a';
18556N/A+ g_free (directory_uri);
18556N/A+ new_dir = nautilus_directory_get_by_uri (snap_root);
18556N/A+ g_free (snap_root);
18556N/A+ return new_dir;
18556N/A+ }
18556N/A+ return directory;
18556N/A+}
18556N/A+
18556N/A+
18556N/A+
18556N/A gboolean
18556N/A nautilus_directory_is_in_trash (NautilusDirectory *directory)
18556N/A {
18744N/Adiff -Nrup -x '*.orig' -x '*.rej' -x '*.*~' ../SUNWgnome-file-mgr-2.30.0-b4/nautilus-2.30.1/libnautilus-private/nautilus-directory.h nautilus-2.30.1/libnautilus-private/nautilus-directory.h
18744N/A--- ../SUNWgnome-file-mgr-2.30.0-b4/nautilus-2.30.1/libnautilus-private/nautilus-directory.h 2009-12-08 16:17:07.000000000 +0100
18744N/A+++ nautilus-2.30.1/libnautilus-private/nautilus-directory.h 2010-05-14 17:16:39.545571596 +0200
18556N/A@@ -28,6 +28,7 @@
18556N/A #include <gtk/gtk.h>
18556N/A #include <gio/gio.h>
18556N/A #include <libnautilus-private/nautilus-file-attributes.h>
18556N/A+#include <libnautilus-private/nautilus-zfs.h>
18556N/A
18556N/A /* NautilusDirectory is a class that manages the model for a directory,
18556N/A real or virtual, for Nautilus, mainly the file-manager component. The directory is
18556N/A@@ -219,6 +220,24 @@ gboolean nautilus_directory_ar
18556N/A gboolean nautilus_directory_is_local (NautilusDirectory *directory);
18556N/A
18556N/A gboolean nautilus_directory_is_in_trash (NautilusDirectory *directory);
18556N/A+typedef void (*TsReadyCallback) (NautilusDirectory *directory,
18556N/A+ GCancellable *cancellable,
18556N/A+ gpointer callback_data);
18556N/A+
18556N/A+void nautilus_directory_get_snapshots_async (NautilusDirectory *directory,
18556N/A+ TsReadyCallback ready_callback,
18556N/A+ GCancellable *cancel,
18556N/A+ gpointer callback_user_data);
18556N/A+gboolean nautilus_directory_has_snapshots (NautilusDirectory *directory);
18556N/A+gboolean nautilus_directory_is_in_snapshot (NautilusDirectory *directory);
18556N/A+int nautilus_directory_get_num_snapshots (NautilusDirectory *directory);
18556N/A+GList * nautilus_directory_get_snapshots (NautilusDirectory *directory);
18556N/A+void nautilus_directory_remove_snapshot (NautilusDirectory *directory,
18556N/A+ ZfsDataSet *snap);
18556N/A+NautilusDirectory *nautilus_directory_get_snap_root (NautilusDirectory *directory);
18556N/A+gboolean nautilus_directory_is_a_snapshot_dir_of (NautilusDirectory *snapdir,
18556N/A+ NautilusDirectory *refdir);
18556N/A+void nautilus_directory_cancel_restore_info (NautilusDirectory *directory);
18556N/A
18556N/A /* Return false if directory contains anything besides a Nautilus metafile.
18556N/A * Only valid if directory is monitored. Used by the Trash monitor.
18556N/A@@ -239,6 +258,7 @@ GList * nautilus_directory_li
18556N/A gboolean nautilus_directory_is_desktop_directory (NautilusDirectory *directory);
18556N/A
18556N/A gboolean nautilus_directory_is_editable (NautilusDirectory *directory);
18556N/A+gboolean is_time_slider_enabled ();
18556N/A
18556N/A
18556N/A #endif /* NAUTILUS_DIRECTORY_H */
18744N/Adiff -Nrup -x '*.orig' -x '*.rej' -x '*.*~' ../SUNWgnome-file-mgr-2.30.0-b4/nautilus-2.30.1/libnautilus-private/nautilus-file-attributes.h nautilus-2.30.1/libnautilus-private/nautilus-file-attributes.h
18744N/A--- ../SUNWgnome-file-mgr-2.30.0-b4/nautilus-2.30.1/libnautilus-private/nautilus-file-attributes.h 2009-12-09 12:03:51.000000000 +0100
18744N/A+++ nautilus-2.30.1/libnautilus-private/nautilus-file-attributes.h 2010-05-14 17:16:39.545856449 +0200
18556N/A@@ -41,6 +41,7 @@ typedef enum {
18556N/A NAUTILUS_FILE_ATTRIBUTE_THUMBNAIL = 1 << 8,
18556N/A NAUTILUS_FILE_ATTRIBUTE_MOUNT = 1 << 9,
18556N/A NAUTILUS_FILE_ATTRIBUTE_FILESYSTEM_INFO = 1 << 10,
18556N/A+ NAUTILUS_FILE_ATTRIBUTE_RESTORE_INFO = 1 << 12,
18556N/A } NautilusFileAttributes;
18556N/A
18556N/A #endif /* NAUTILUS_FILE_ATTRIBUTES_H */
18744N/Adiff -Nrup -x '*.orig' -x '*.rej' -x '*.*~' ../SUNWgnome-file-mgr-2.30.0-b4/nautilus-2.30.1/libnautilus-private/nautilus-file-private.h nautilus-2.30.1/libnautilus-private/nautilus-file-private.h
18744N/A--- ../SUNWgnome-file-mgr-2.30.0-b4/nautilus-2.30.1/libnautilus-private/nautilus-file-private.h 2009-12-09 12:03:51.000000000 +0100
18744N/A+++ nautilus-2.30.1/libnautilus-private/nautilus-file-private.h 2010-05-14 17:16:39.546288851 +0200
18556N/A@@ -146,6 +146,15 @@ struct NautilusFileDetails
18556N/A
18556N/A /* Mount for mountpoint or the references GMount for a "mountable" */
18556N/A GMount *mount;
18556N/A+
18556N/A+ /* time slider file difference information */
18556N/A+
18556N/A+ char *restore_info;
18556N/A+
18556N/A+ /* snapshot directory for versions */
18556N/A+
18556N/A+ char *snapshot_directory;
18556N/A+ GCancellable *has_snapshot_cancel;
18556N/A
18556N/A /* boolean fields: bitfield to save space, since there can be
18556N/A many NautilusFile objects. */
18556N/A@@ -194,6 +203,13 @@ struct NautilusFileDetails
18556N/A
18556N/A eel_boolean_bit is_thumbnailing : 1;
18556N/A
18556N/A+ eel_boolean_bit restore_info_is_up_to_date : 1;
18556N/A+ eel_boolean_bit restore_info_in_progress : 1;
18556N/A+
18556N/A+ eel_boolean_bit has_snap_versions_is_up_to_date : 1;
18556N/A+ eel_boolean_bit has_snap_versions_in_progress : 1;
18556N/A+ eel_boolean_bit has_snap_versions : 1;
18556N/A+
18556N/A /* TRUE if the file is open in a spatial window */
18556N/A eel_boolean_bit has_open_window : 1;
18556N/A
20808N/A--- nautilus-3.1.3/libnautilus-private/nautilus-file.c.orig 2011-07-22 15:55:37.274869941 +0100
20808N/A+++ nautilus-3.1.3/libnautilus-private/nautilus-file.c 2011-07-22 16:05:34.306574660 +0100
18556N/A@@ -47,6 +47,7 @@
18556N/A #include "nautilus-vfs-file.h"
18556N/A #include "nautilus-saved-search-file.h"
18556N/A #include "nautilus-lockdown.h"
18556N/A+#include "nautilus-zfs.h"
18556N/A #include <eel/eel-debug.h>
18556N/A #include <eel/eel-glib-extensions.h>
18556N/A #include <eel/eel-gtk-extensions.h>
20808N/A@@ -142,7 +143,8 @@
18556N/A attribute_where_q,
18556N/A attribute_link_target_q,
18556N/A attribute_volume_q,
18556N/A- attribute_free_space_q;
18556N/A+ attribute_free_space_q,
18556N/A+ attribute_restore_info_q;
18556N/A
18556N/A static void nautilus_file_info_iface_init (NautilusFileInfoIface *iface);
18556N/A static char * nautilus_file_get_owner_as_string (NautilusFile *file,
20808N/A@@ -152,6 +154,7 @@
18556N/A GFileInfo *info);
18556N/A static const char * nautilus_file_peek_display_name (NautilusFile *file);
18556N/A static const char * nautilus_file_peek_display_name_collation_key (NautilusFile *file);
18556N/A+static void invalidate_restore_info (NautilusFile *file);
18556N/A static void file_mount_unmounted (GMount *mount, gpointer data);
18556N/A static void metadata_hash_free (GHashTable *hash);
18556N/A
20808N/A@@ -486,7 +489,14 @@
18556N/A
18556N/A eel_ref_str_unref (file->details->filesystem_id);
18556N/A file->details->filesystem_id = NULL;
18556N/A-
18556N/A+ g_free (file->details->restore_info);
18556N/A+ file->details->restore_info = NULL;
18556N/A+ invalidate_restore_info (file);
18556N/A+ g_free (file->details->snapshot_directory);
18556N/A+ file->details->snapshot_directory = NULL;
18556N/A+ file->details->has_snap_versions_in_progress = FALSE;
18556N/A+ file->details->has_snap_versions_is_up_to_date = FALSE;
18556N/A+ file->details->has_snap_versions = FALSE;
18556N/A clear_metadata (file);
18556N/A }
18556N/A
20808N/A@@ -804,6 +814,10 @@
18556N/A g_free (file->details->activation_uri);
20808N/A g_clear_object (&file->details->custom_icon);
18556N/A
20808N/A+ g_free (file->details->restore_info);
20808N/A+ if (file->details->snapshot_directory)
20808N/A+ g_free (file->details->snapshot_directory);
18556N/A+
18556N/A if (file->details->thumbnail) {
18556N/A g_object_unref (file->details->thumbnail);
18556N/A }
20808N/A@@ -4423,6 +4437,76 @@
18556N/A NULL
18556N/A };
18556N/A
18556N/A+char *
18556N/A+nautilus_date_as_string (time_t time_raw, gboolean use_smallest)
18556N/A+{
18556N/A+ struct tm *ttime;
18556N/A+ const char **formats;
18556N/A+ const char *width_template;
18556N/A+ const char *format;
18556N/A+ char *date_string;
18556N/A+ char *result;
18556N/A+ GDate *today;
18556N/A+ GDate *date;
18556N/A+ guint32 date_age;
20808N/A+ int i, date_format_pref;
18556N/A+
18556N/A+ ttime = localtime (&time_raw);
18556N/A+
18556N/A+ if (!use_smallest)
18556N/A+ {
20808N/A+ date_format_pref = g_settings_get_enum (nautilus_preferences,
20808N/A+ NAUTILUS_PREFERENCES_DATE_FORMAT);
18556N/A+ if (date_format_pref == NAUTILUS_DATE_FORMAT_LOCALE) {
18556N/A+ return eel_strdup_strftime ("%c", ttime);
18556N/A+ } else if (date_format_pref == NAUTILUS_DATE_FORMAT_ISO) {
18556N/A+ return eel_strdup_strftime ("%Y-%m-%d %H:%M:%S",ttime);
18556N/A+ }
18556N/A+ }
18556N/A+
18556N/A+ date = eel_g_date_new_tm (ttime);
18556N/A+
18556N/A+ today = g_date_new ();
18556N/A+ g_date_set_time_t (today, time (NULL));
18556N/A+
18556N/A+ /* Overflow results in a large number; fine for our purposes. */
18556N/A+ date_age = (g_date_get_julian (today) -
18556N/A+ g_date_get_julian (date));
18556N/A+
18556N/A+ g_date_free (date);
18556N/A+ g_date_free (today);
18556N/A+
18556N/A+ /* Format varies depending on how old the date is. This minimizes
18556N/A+ * the length (and thus clutter & complication) of typical dates
18556N/A+ * while providing sufficient detail for recent dates to make
18556N/A+ * them maximally understandable at a glance. Keep all format
18556N/A+ * strings separate rather than combining bits & pieces for
18556N/A+ * internationalization's sake.
18556N/A+ */
18556N/A+
18556N/A+ if (date_age == 0) {
18556N/A+ formats = TODAY_TIME_FORMATS;
18556N/A+ } else if (date_age == 1) {
18556N/A+ formats = YESTERDAY_TIME_FORMATS;
18556N/A+ } else if (date_age < 7) {
18556N/A+ formats = CURRENT_WEEK_TIME_FORMATS;
18556N/A+ } else {
18556N/A+ formats = CURRENT_WEEK_TIME_FORMATS;
18556N/A+ }
18556N/A+
18556N/A+
18556N/A+ if (!use_smallest)
18556N/A+ format = _(formats[1]);
18556N/A+ else
18556N/A+ {
18556N/A+ int i=0;
18556N/A+ while (formats[i] != NULL)
18556N/A+ i++;
18556N/A+ format = _(formats[i-3]);
18556N/A+ }
18556N/A+ return eel_strdup_strftime (format, ttime);
18556N/A+}
18556N/A+
18556N/A static char *
18556N/A nautilus_file_fit_date_as_string (NautilusFile *file,
18556N/A NautilusDateType date_type,
20808N/A@@ -6103,7 +6187,9 @@
18556N/A if (attribute_q == attribute_free_space_q) {
18556N/A return nautilus_file_get_volume_free_space (file);
18556N/A }
18556N/A-
18556N/A+ if (attribute_q == attribute_restore_info_q) {
18556N/A+ return nautilus_file_get_restore_info_async (file);
18556N/A+ }
18556N/A extension_attribute = NULL;
18556N/A
18556N/A if (file->details->pending_extension_attributes) {
20808N/A@@ -7037,6 +7123,616 @@
18556N/A
18556N/A }
18556N/A
18556N/A+gboolean
18556N/A+nautilus_file_is_in_snapshot (NautilusFile *file)
18556N/A+{
18556N/A+ char *file_uri = nautilus_file_get_uri (file);
18556N/A+ gboolean result = ts_is_in_snapshot (file_uri);
18556N/A+ g_free (file_uri);
18556N/A+ return result;
18556N/A+}
18556N/A+
18556N/A+static gboolean nautilus_file_in_snap_exist_in_current (NautilusFile *file, GCancellable *cancel)
18556N/A+{
18556N/A+ /* get path without /.zfs/snapshot/blah/ */
18556N/A+ /* test is file exist */
18556N/A+ char *file_uri = nautilus_file_get_uri (file);
18556N/A+ char *file_uri_without_snap = NULL;
18556N/A+ gboolean result = FALSE;
18556N/A+
18556N/A+ if (g_cancellable_is_cancelled (cancel))
18556N/A+ {
18556N/A+ g_free (file_uri);
18556N/A+ return FALSE;
18556N/A+ }
18556N/A+
18556N/A+ file_uri_without_snap = ts_remove_snapshot_dir (file_uri);
18556N/A+
18556N/A+ if (file_uri_without_snap)
18556N/A+ {
18556N/A+ GFile* root_file = g_file_new_for_uri (file_uri_without_snap);
18556N/A+ char *path = g_file_get_path (root_file);
18556N/A+
18556N/A+ if (path)
18556N/A+ {
18556N/A+ result = g_file_test (path, G_FILE_TEST_EXISTS);
18556N/A+ g_free (path);
18556N/A+ }
18556N/A+ g_object_unref (root_file);
18556N/A+ g_free (file_uri_without_snap);
18556N/A+
18556N/A+ }
18556N/A+
18556N/A+ g_free (file_uri);
18556N/A+
18556N/A+ return result;
18556N/A+}
18556N/A+
18556N/A+
18556N/A+char * nautilus_file_in_snapshot_get_info (NautilusFile *file, GCancellable *cancel)
18556N/A+{
18556N/A+ char *info = NULL;
18556N/A+ GFile *then_gfile = nautilus_file_get_location (file);
18556N/A+ char *then_path = g_file_get_path (then_gfile);
18556N/A+ g_object_unref (then_gfile);
18556N/A+
18556N/A+ if (g_cancellable_is_cancelled (cancel))
18556N/A+ {
18556N/A+ g_free (then_gfile);
18556N/A+ g_free (then_path);
18556N/A+ return g_strdup ("cancelled");
18556N/A+ }
18556N/A+ if (then_path)
18556N/A+ {
18556N/A+ struct stat64 now;
18556N/A+ struct stat64 then;
18556N/A+ char *now_path = ts_remove_snapshot_dir (then_path);
18556N/A+
18556N/A+ if (lstat64 (now_path, &now) == 0)
18556N/A+ {
18556N/A+ if (lstat64 (then_path, &then) == 0)
18556N/A+ {
18556N/A+
18556N/A+ if (now.st_mtime != then.st_mtime)
18556N/A+ {
18556N/A+ if (now.st_size == then.st_size)
18556N/A+ /* SUN_BRANDING */
18556N/A+ info = g_strdup (_("different date, same size as latest version"));
18556N/A+ else if (now.st_size > then.st_size)
18556N/A+ /* SUN_BRANDING */
18556N/A+ info = g_strdup (_("different date, smaller than latest version"));
18556N/A+ else if ( now.st_size < then.st_size)
18556N/A+ /* SUN_BRANDING */
18556N/A+ info = g_strdup (_("different date, bigger than latest version"));
18556N/A+ }
18556N/A+ else
18556N/A+ /* SUN_BRANDING */
18556N/A+ info = g_strdup (_("identical to latest version"));
18556N/A+ }
18556N/A+ else
18556N/A+ info = g_strdup_printf ("FIXME no then %s", then_path);
18556N/A+ }
18556N/A+ else
18556N/A+ /* SUN_BRANDING */
18556N/A+ info = g_strdup (_("not present in latest version"));
18556N/A+
18556N/A+ g_free (now_path);
18556N/A+ g_free (then_path);
18556N/A+ }
18556N/A+
18556N/A+ return info;
18556N/A+}
18556N/A+
18556N/A+static char * restore_string (char *str, GCancellable *cancel)
18556N/A+{
18556N/A+ if (g_cancellable_is_cancelled (cancel))
18556N/A+ {
18556N/A+ g_free (str);
18556N/A+ return g_strdup (_("unknown"));
18556N/A+ }
18556N/A+ else
18556N/A+ return str;
18556N/A+}
18556N/A+
18556N/A+gint time_cmp (time_t *a,
18556N/A+ time_t *b)
18556N/A+{
18556N/A+ if (*a == *b)
18556N/A+ return 0;
18556N/A+ if (*a > *b)
18556N/A+ return 1;
18556N/A+ if (*a < *b)
18556N/A+ return -1;
18556N/A+
18556N/A+}
18556N/A+
18556N/A+char *
18556N/A+nautilus_file_get_num_snapshot_version (NautilusFile *file,
18556N/A+ GCancellable *cancel,
18556N/A+ gboolean stop_at_first)
18556N/A+{
18556N/A+ GList *tmp = NULL;
18556N/A+ GList *tmp2 = NULL;
18556N/A+ GList *time = NULL;
18556N/A+ time_t* now_time = NULL;
18556N/A+ char *result = NULL;
18556N/A+ int version = 0;
18556N/A+ NautilusFile *parent = NULL;
18556N/A+ NautilusDirectory *dir = NULL;
18556N/A+ char *snapdir = NULL;
18556N/A+
18556N/A+ if (NAUTILUS_IS_FILE (file))
18556N/A+ {
18556N/A+ parent = nautilus_file_get_parent (file);
18556N/A+ if (parent)
18556N/A+ {
18556N/A+ dir = nautilus_directory_get_for_file (parent);
18556N/A+ g_object_unref (parent);
18556N/A+ }
18556N/A+ }
18556N/A+ if (dir)
18556N/A+ {
18556N/A+ struct stat64 now;
18556N/A+ struct stat64 then;
18556N/A+ char snap_name[PATH_MAX+1];
18556N/A+ char *name = nautilus_file_get_name (file);
18556N/A+
18556N/A+ g_object_ref (dir);
18556N/A+ tmp = nautilus_directory_get_snapshots (dir);
18556N/A+
18556N/A+ GFile *now_gfile = nautilus_file_get_location (file);
18556N/A+ char *now_path = g_file_get_path (now_gfile);
18556N/A+ g_object_unref (now_gfile);
18556N/A+
18556N/A+ if (now_path)
18556N/A+ {
18556N/A+ if (lstat64 (now_path, &now) != 0)
18556N/A+ {
18556N/A+ g_free (now_path);
18556N/A+ g_object_unref (dir);
18556N/A+ return NULL;
18556N/A+ }
18556N/A+ }
18556N/A+
18556N/A+ g_free (now_path);
18556N/A+
18556N/A+ time = NULL;
18556N/A+
18556N/A+ /* get list of mtime for all files in snapshots */
18556N/A+
18556N/A+ now_time = g_new0 (time_t, 1);
18556N/A+ *now_time = now.st_mtim.tv_sec;
18556N/A+ time = g_list_prepend (time, now_time);
18556N/A+
18556N/A+
18556N/A+ for (tmp; tmp; tmp = tmp->next)
18556N/A+ {
18556N/A+ g_sprintf (snap_name, "%s/%s",
18556N/A+ ((ZfsDataSet *) tmp->data)->mountpoint,
18556N/A+ name);
18556N/A+ if (g_cancellable_is_cancelled (cancel))
18556N/A+ goto cancel;
18556N/A+ if (lstat64 (snap_name, &then) == 0)
18556N/A+ {
18556N/A+ if (g_list_find_custom (time, &then.st_mtim.tv_sec, (GCompareFunc) time_cmp) == NULL)
18556N/A+ { /*insert in list only is unique */
18556N/A+ time_t* snap_time = g_new0 (time_t, 1);
18556N/A+ *snap_time = then.st_mtim.tv_sec;
18556N/A+ time = g_list_prepend (time, snap_time);
18556N/A+ if (stop_at_first)
18556N/A+ {
18556N/A+ snapdir = g_strdup (((ZfsDataSet *) tmp->data)->mountpoint);
18556N/A+ goto cancel;
18556N/A+ }
18556N/A+ }
18556N/A+ }
18556N/A+
18556N/A+ }
18556N/A+cancel:
18556N/A+ g_free (name);
18556N/A+ g_object_unref (dir);
18556N/A+ }
18556N/A+
18556N/A+
18556N/A+ for (tmp = time; tmp; tmp = tmp->next)
18556N/A+ {
18556N/A+ g_free ((time_t*) tmp->data);
18556N/A+ version++;
18556N/A+ }
18556N/A+
18556N/A+ /* remove current version */
18556N/A+ version--;
18556N/A+
18556N/A+ g_list_free (time);
18556N/A+
18556N/A+ if (version == 0)
18556N/A+ {
18556N/A+ if (stop_at_first)
18556N/A+ return NULL;
18556N/A+ else /*SUN_BRANDING*/
18556N/A+ return restore_string (g_strdup_printf (_("no other version")), cancel);
18556N/A+ }
18556N/A+
18556N/A+ if (stop_at_first)
18556N/A+ return snapdir;
18556N/A+ else
18556N/A+ return restore_string (g_strdup_printf ("%d %s", version,
18556N/A+ /* SUN_BRANDING */
18556N/A+ version > 1 ? _("other versions") : /* SUN_BRANDING */ _("other version")),
18556N/A+ cancel);
18556N/A+}
18556N/A+
18556N/A+static gboolean worker_thread_started = FALSE;
18556N/A+
18556N/A+typedef void (*ReadyCallback) (gpointer data,
18556N/A+ GCancellable *cancellable);
18556N/A+typedef void (*WorkerFunction) (gpointer data,
18556N/A+ GCancellable *cancellable);
18556N/A+typedef struct {
18556N/A+ gpointer data;
18556N/A+ gpointer return_data;
18556N/A+ ReadyCallback ready_callback;
18556N/A+ WorkerFunction worker_func;
18556N/A+ GCancellable *cancellable;
18556N/A+} QueryData;
18556N/A+
18556N/A+static void
18556N/A+nautilus_file_get_restore_info (gpointer data,
18556N/A+ GCancellable *cancellable)
18556N/A+{
18556N/A+ QueryData *qdata = (QueryData*) data;
18556N/A+ NautilusFile *file = NAUTILUS_FILE (qdata->data);
18556N/A+ char *result = NULL;
18556N/A+
18556N/A+ /*{
18556N/A+ struct timespec ts;
18556N/A+ ts.tv_sec = 1;
18556N/A+ ts.tv_nsec = 0;
18556N/A+ nanosleep (&ts, NULL);
18556N/A+ }
18556N/A+
18556N/A+ {
18556N/A+ GFile *f = nautilus_file_get_location (file);
18556N/A+ char *path = g_file_get_uri (f);
18556N/A+ printf ("start restore info for %s", path);
18556N/A+ g_free (path);
18556N/A+ g_object_unref (f);
18556N/A+ }*/
18556N/A+ if (!g_cancellable_is_cancelled (cancellable))
18556N/A+ {
18556N/A+
18556N/A+ if (nautilus_file_is_directory (file))
18556N/A+ {
18556N/A+ NautilusDirectory *dir = nautilus_directory_get_for_file (file);
18556N/A+ g_object_ref (dir);
18556N/A+ if (nautilus_directory_is_in_snapshot (dir))
18556N/A+ {
18556N/A+ if (!nautilus_file_in_snap_exist_in_current (file, cancellable))
18556N/A+ /* SUN_BRANDING */
18556N/A+ result = g_strdup (_("not present in latest version"));
18556N/A+ else
18556N/A+ /* SUN_BRANDING */
18556N/A+ result = g_strdup (_("present in latest version"));
18556N/A+ }
18556N/A+ else
18556N/A+ {
18556N/A+ int version = nautilus_directory_get_num_snapshots (dir);
18556N/A+
18556N/A+ if (version == 0)
18556N/A+ /* SUN_BRANDING */
18556N/A+ result = g_strdup (_("no version"));
18556N/A+ else
18556N/A+ result = g_strdup_printf ("%d %s",version,
18556N/A+ /* SUN_BRANDING */
18556N/A+ version > 1 ? _("versions") : /* SUN_BRANDING */ _("version"));
18556N/A+ }
18556N/A+ g_object_unref (dir);
18556N/A+ }
18556N/A+ else
18556N/A+ {
18556N/A+ if (nautilus_file_is_in_snapshot (file))
18556N/A+ result = nautilus_file_in_snapshot_get_info (file, cancellable);
18556N/A+ else
18556N/A+ result = nautilus_file_get_num_snapshot_version (file, cancellable, FALSE);
18556N/A+ }
18556N/A+ }
18556N/A+
18556N/A+/* {
18556N/A+ printf ("is %s\n", result);
18556N/A+ }*/
18556N/A+
18556N/A+
18556N/A+ qdata->return_data = restore_string (result, cancellable);
18556N/A+}
18556N/A+
18556N/A+
18556N/A+static void restore_information_ready_callback (gpointer data,
18556N/A+ GCancellable *cancellable)
18556N/A+{
18556N/A+ QueryData *qdata = (QueryData*) data;
18556N/A+ NautilusFile *file = (NautilusFile*) qdata->data;
18556N/A+ char *return_data = qdata->return_data;
18556N/A+
18556N/A+ if (!NAUTILUS_IS_FILE (file))
18556N/A+ return;
18556N/A+
18556N/A+ file->details->restore_info_in_progress = FALSE;
18556N/A+
18556N/A+ if (g_cancellable_is_cancelled (cancellable))
18556N/A+ {
18556N/A+ file->details->restore_info = g_strdup (_("unknown"));
18556N/A+ invalidate_restore_info (file);
18556N/A+ if (return_data)
18556N/A+ g_free (return_data);
18556N/A+ }
18556N/A+ else
18556N/A+ {
18556N/A+ file->details->restore_info_is_up_to_date = TRUE;
18556N/A+ file->details->restore_info = return_data;
18556N/A+ }
18556N/A+
18556N/A+ nautilus_file_changed (file);
18556N/A+ nautilus_file_unref (file);
18556N/A+}
18556N/A+
18556N/A+
18556N/A+static gboolean
18556N/A+complete_in_idle_cb (gpointer data)
18556N/A+{
18556N/A+ QueryData *qdata = (QueryData*)data;
18556N/A+ qdata->ready_callback (data, qdata->cancellable);
18556N/A+ g_free (qdata);
18556N/A+ return FALSE;
18556N/A+}
18556N/A+
18556N/A+static void
18556N/A+worker_queue_finished_callback (GObject *source_object,
18556N/A+ GAsyncResult *res,
18556N/A+ gpointer user_data)
18556N/A+{
18556N/A+ GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
18556N/A+ GCancellable *cancel = (GCancellable*) user_data;
18556N/A+
18556N/A+ worker_thread_started = FALSE;
18556N/A+
18556N/A+ if (g_cancellable_is_cancelled (cancel))
18556N/A+ {
18556N/A+ return;
18556N/A+ }
18556N/A+
18556N/A+ g_simple_async_result_get_op_res_gpointer (simple);
18556N/A+
18556N/A+}
18556N/A+
18556N/A+static void
18556N/A+worker_queue_func (GSimpleAsyncResult *res,
18556N/A+ GObject *object,
18556N/A+ GCancellable *cancellable)
18556N/A+{
18556N/A+ QueryData *data = NULL;
18556N/A+
18556N/A+ GTimeVal timeout;
18556N/A+ GAsyncQueue *queue = (GAsyncQueue*) g_simple_async_result_get_op_res_gpointer (res);
18556N/A+ g_async_queue_ref (queue);
18556N/A+
18556N/A+ g_get_current_time (&timeout);
18556N/A+ g_time_val_add (&timeout, 3000000);
18556N/A+
18556N/A+ data = g_async_queue_timed_pop (queue, &timeout);
18556N/A+
18556N/A+ while (data)
18556N/A+ {
18556N/A+ GSource *source;
18556N/A+
18556N/A+ /* only call the worker fct if not cancel
18556N/A+ * but execute ready function anyway */
18556N/A+ if (!g_cancellable_is_cancelled (data->cancellable))
18556N/A+ data->worker_func (data, data->cancellable);
18556N/A+
18556N/A+ /*call ready callback in main loop/thread */
18556N/A+ source = g_idle_source_new ();
18556N/A+ g_source_set_priority (source, G_PRIORITY_DEFAULT);
18556N/A+ g_source_set_callback (source, complete_in_idle_cb, data, NULL);
18556N/A+ g_source_attach (source, NULL);
18556N/A+ g_source_unref (source);
18556N/A+
18556N/A+ /* pop next one */
18556N/A+ g_get_current_time (&timeout);
18556N/A+ g_time_val_add (&timeout, 3000000);
18556N/A+ data = g_async_queue_timed_pop (queue, &timeout);
18556N/A+ }
18556N/A+
18556N/A+ g_async_queue_unref (queue);
18556N/A+}
18556N/A+
18556N/A+char * nautilus_file_get_restore_info_async (NautilusFile *file)
18556N/A+{
18556N/A+ if (!is_time_slider_enabled ())
18556N/A+ return NULL;
18556N/A+
18556N/A+ if (!ts_is_restore_column_enabled ())
18556N/A+ return NULL;
18556N/A+
18556N/A+ if (file->details->restore_info_is_up_to_date)
18556N/A+ {
18556N/A+ /*if ( file->details->restore_info == NULL)
18556N/A+ return g_strdup ("null cached info");*/
18556N/A+ return g_strdup (file->details->restore_info);
18556N/A+ }
18556N/A+
18556N/A+ if (file->details->restore_info_in_progress)
18556N/A+ return g_strdup ("...");
18556N/A+ else
18556N/A+ {
18556N/A+ static GAsyncQueue *queue = NULL;
18556N/A+ QueryData *data = NULL;
18556N/A+
18556N/A+ if (!file->details->directory)
18556N/A+ return g_strdup ("no directory element\n");
18556N/A+
18556N/A+ if (!nautilus_directory_has_snapshots (file->details->directory) && !nautilus_file_is_in_snapshot (file))
18556N/A+ return g_strdup ("doesn't have snap nor is in snap\n");
18556N/A+
18556N/A+ if (!file->details->directory->details->restore_cancel)
18556N/A+ {
18556N/A+ file->details->directory->details->restore_cancel = g_cancellable_new ();
18556N/A+ }
18556N/A+ else
18556N/A+ {
18556N/A+ if (g_cancellable_is_cancelled (file->details->directory->details->restore_cancel))
18556N/A+ return NULL;
18556N/A+ }
18556N/A+
18556N/A+ g_free (file->details->restore_info);
18556N/A+ file->details->restore_info = NULL;
18556N/A+ file->details->restore_info_in_progress = TRUE;
18556N/A+
18556N/A+ if (!queue)
18556N/A+ queue = g_async_queue_new ();
18556N/A+
18556N/A+ data = g_new0 (QueryData, 1);
18556N/A+ data->data = file;
18556N/A+ nautilus_file_ref (file);
18556N/A+ data->cancellable = file->details->directory->details->restore_cancel;
18556N/A+ data->ready_callback = restore_information_ready_callback;
18556N/A+ data->worker_func = nautilus_file_get_restore_info;
18556N/A+
18556N/A+ g_async_queue_push (queue, data);
18556N/A+
18556N/A+ if (!worker_thread_started)
18556N/A+ {
18556N/A+ GSimpleAsyncResult *res;
18556N/A+ worker_thread_started = TRUE;
18556N/A+
18556N/A+ res = g_simple_async_result_new (G_OBJECT (file),
18556N/A+ worker_queue_finished_callback,
18556N/A+ NULL,
18556N/A+ (gpointer) worker_queue_func);
18556N/A+
18556N/A+ g_simple_async_result_set_op_res_gpointer (res, queue, NULL);
18556N/A+ g_simple_async_result_run_in_thread (res,
18556N/A+ worker_queue_func,
18556N/A+ G_PRIORITY_DEFAULT,
18556N/A+ data->cancellable);
18556N/A+ }
18556N/A+
18556N/A+ return g_strdup ("...");
18556N/A+ }
18556N/A+}
18556N/A+
18556N/A+HasSnapshotResult
18556N/A+nautilus_file_has_snapshot_version (NautilusFile *file)
18556N/A+{
18556N/A+ if (file->details->has_snap_versions_is_up_to_date)
18556N/A+ return (file->details->has_snap_versions);
18556N/A+ return UNKNOWN_STATE;
18556N/A+}
18556N/A+
18556N/A+typedef struct {
18556N/A+ NautilusFile *file;
18556N/A+ GCancellable *cancel;
18556N/A+ FileHasSnapshotCallback callback;
18556N/A+ gpointer callback_user_data;
18556N/A+ char *snap_dir;
18556N/A+} HasSnapshotAsyncData;
18556N/A+
18556N/A+typedef void (*HasSnapReadyCallback) (NautilusDirectory *file,
18556N/A+ GCancellable *cancel,
18556N/A+ gpointer callback_data);
18556N/A+
18556N/A+
18556N/A+static void has_snapshot_ready_callback (GObject *source_object,
18556N/A+ GAsyncResult *res,
18556N/A+ gpointer user_data)
18556N/A+{
18556N/A+ GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
18556N/A+ HasSnapshotAsyncData *data = (HasSnapshotAsyncData*) user_data;
18556N/A+
18556N/A+ if (g_cancellable_is_cancelled (data->cancel))
18556N/A+ {
18556N/A+ data->file->details->has_snap_versions_in_progress = FALSE;
18556N/A+ data->file->details->has_snap_versions_is_up_to_date = FALSE;
18556N/A+ if (data->file->details->snapshot_directory)
18556N/A+ g_free (data->file->details->snapshot_directory);
18556N/A+
18556N/A+ data->file->details->has_snapshot_cancel = NULL;
18556N/A+ }
18556N/A+ else
18556N/A+ {
18556N/A+ data->file->details->has_snap_versions_in_progress = FALSE;
18556N/A+ data->file->details->has_snap_versions_is_up_to_date = TRUE;
18556N/A+ if (data->file->details->snapshot_directory)
18556N/A+ g_free (data->file->details->snapshot_directory);
18556N/A+ data->file->details->snapshot_directory = g_simple_async_result_get_op_res_gpointer (simple);
18556N/A+ if (data->file->details->snapshot_directory)
18556N/A+ data->file->details->has_snap_versions = TRUE;
18556N/A+ else
18556N/A+ data->file->details->has_snap_versions = FALSE;
18556N/A+ }
18556N/A+ data->callback (data->callback_user_data);
18556N/A+}
18556N/A+char *
18556N/A+nautilus_file_get_snapshot_dir (NautilusFile *file)
18556N/A+{
18556N/A+ return file->details->snapshot_directory;
18556N/A+}
18556N/A+void nautilus_file_real_get_snapshot_version (GSimpleAsyncResult *res,
18556N/A+ GObject *object,
18556N/A+ GCancellable *cancellable)
18556N/A+{
18556N/A+ NautilusFile *file = NAUTILUS_FILE (object);
18556N/A+ char *snap_info = nautilus_file_get_num_snapshot_version (file, cancellable, TRUE);
18556N/A+
18556N/A+ if (!snap_info) /* scan for .zfs directory*/
18556N/A+ snap_info = ts_get_not_zfs_snapshot_dir (nautilus_file_get_location (file));
18556N/A+/*
18556N/A+ {
18556N/A+ struct timespec ts;
18556N/A+ ts.tv_sec = 4;
18556N/A+ ts.tv_nsec = 0;
18556N/A+ nanosleep (&ts, NULL);
18556N/A+ }
18556N/A+*/
18556N/A+ if (snap_info)
18556N/A+ g_simple_async_result_set_op_res_gpointer (res, snap_info, (GDestroyNotify) NULL);
18556N/A+ else
18556N/A+ g_simple_async_result_set_op_res_gpointer (res, NULL, (GDestroyNotify) NULL);
18556N/A+}
18556N/A+
18556N/A+void nautilus_file_get_snapshot_version (NautilusFile *file,
18556N/A+ FileHasSnapshotCallback callback,
18556N/A+ GCancellable *cancel,
18556N/A+ gpointer user_data)
18556N/A+{
18556N/A+ HasSnapshotAsyncData *data;
18556N/A+ GSimpleAsyncResult *res;
18556N/A+
18556N/A+ if (file->details->has_snap_versions_in_progress)
18556N/A+ {
18556N/A+ g_cancellable_cancel(file->details->has_snapshot_cancel);
18556N/A+ file->details->has_snapshot_cancel = NULL;
18556N/A+ file->details->has_snap_versions_in_progress = FALSE;
18556N/A+ }
18556N/A+
18556N/A+ file->details->has_snapshot_cancel = cancel;
18556N/A+ file->details->has_snap_versions_in_progress = TRUE;
18556N/A+ file->details->has_snap_versions_is_up_to_date = FALSE;
18556N/A+
18556N/A+ data = g_new0 (HasSnapshotAsyncData, 1);
18556N/A+ data->file = file;
18556N/A+ data->cancel = cancel;
18556N/A+ data->callback = callback;
18556N/A+ data->callback_user_data = user_data;
18556N/A+
18556N/A+ res = g_simple_async_result_new (G_OBJECT (file),
18556N/A+ has_snapshot_ready_callback,
18556N/A+ data,
18556N/A+ (gpointer) nautilus_file_real_get_snapshot_version);
18556N/A+ g_simple_async_result_run_in_thread (res, nautilus_file_real_get_snapshot_version,
18556N/A+ G_PRIORITY_DEFAULT, cancel);
18556N/A+}
18556N/A+
18556N/A+
18556N/A void
18556N/A nautilus_file_mark_gone (NautilusFile *file)
18556N/A {
20808N/A@@ -7296,6 +7992,12 @@
18556N/A file->details->mount_is_up_to_date = FALSE;
18556N/A }
18556N/A
18556N/A+static void
18556N/A+invalidate_restore_info (NautilusFile *file)
18556N/A+{
18556N/A+ file->details->restore_info_is_up_to_date = FALSE;
18556N/A+}
18556N/A+
18556N/A void
18556N/A nautilus_file_invalidate_extension_info_internal (NautilusFile *file)
18556N/A {
20808N/A@@ -7350,6 +8052,9 @@
18556N/A if (REQUEST_WANTS_TYPE (request, REQUEST_THUMBNAIL)) {
18556N/A invalidate_thumbnail (file);
18556N/A }
18556N/A+ if (REQUEST_WANTS_TYPE (request, REQUEST_RESTORE_INFO)) {
18556N/A+ invalidate_restore_info (file);
18556N/A+ }
18556N/A if (REQUEST_WANTS_TYPE (request, REQUEST_MOUNT)) {
18556N/A invalidate_mount (file);
18556N/A }
20808N/A@@ -7432,7 +8137,8 @@
18556N/A NAUTILUS_FILE_ATTRIBUTE_LARGE_TOP_LEFT_TEXT |
18556N/A NAUTILUS_FILE_ATTRIBUTE_EXTENSION_INFO |
18556N/A NAUTILUS_FILE_ATTRIBUTE_THUMBNAIL |
18556N/A- NAUTILUS_FILE_ATTRIBUTE_MOUNT;
18556N/A+ NAUTILUS_FILE_ATTRIBUTE_MOUNT |
18556N/A+ NAUTILUS_FILE_ATTRIBUTE_RESTORE_INFO ;
18556N/A }
18556N/A
18556N/A void
20808N/A@@ -8011,6 +8717,7 @@
18556N/A attribute_link_target_q = g_quark_from_static_string ("link_target");
18556N/A attribute_volume_q = g_quark_from_static_string ("volume");
18556N/A attribute_free_space_q = g_quark_from_static_string ("free_space");
18556N/A+ attribute_restore_info_q = g_quark_from_static_string ("restore_info");
18556N/A
18556N/A G_OBJECT_CLASS (class)->finalize = finalize;
18556N/A G_OBJECT_CLASS (class)->constructor = nautilus_file_constructor;
18744N/Adiff -Nrup -x '*.orig' -x '*.rej' -x '*.*~' ../SUNWgnome-file-mgr-2.30.0-b4/nautilus-2.30.1/libnautilus-private/nautilus-file.h nautilus-2.30.1/libnautilus-private/nautilus-file.h
18744N/A--- ../SUNWgnome-file-mgr-2.30.0-b4/nautilus-2.30.1/libnautilus-private/nautilus-file.h 2009-12-09 12:03:51.000000000 +0100
18744N/A+++ nautilus-2.30.1/libnautilus-private/nautilus-file.h 2010-05-14 17:16:39.550338308 +0200
18556N/A@@ -173,6 +173,7 @@ gboolean nautilus_file_is
18556N/A const char *mime_type);
18556N/A gboolean nautilus_file_is_launchable (NautilusFile *file);
18556N/A gboolean nautilus_file_is_symbolic_link (NautilusFile *file);
18556N/A+gboolean nautilus_file_is_in_snapshot (NautilusFile *file);
18556N/A gboolean nautilus_file_is_mountpoint (NautilusFile *file);
18556N/A GMount * nautilus_file_get_mount (NautilusFile *file);
18556N/A char * nautilus_file_get_volume_free_space (NautilusFile *file);
18556N/A@@ -228,6 +229,26 @@ char * nautilus_file_ge
18556N/A
18556N/A NautilusFile * nautilus_file_get_trash_original_file (NautilusFile *file);
18556N/A
18556N/A+char * nautilus_file_get_num_snapshot_version (NautilusFile *file,
18556N/A+ GCancellable *cancel,
18556N/A+ gboolean stop_at_first);
18556N/A+char * nautilus_file_get_restore_info_async (NautilusFile *file);
18556N/A+
18556N/A+typedef enum {
18556N/A+ NO,
18556N/A+ YES,
18556N/A+ UNKNOWN_STATE
18556N/A+} HasSnapshotResult;
18556N/A+
18556N/A+HasSnapshotResult nautilus_file_has_snapshot_version (NautilusFile *file);
18556N/A+char * nautilus_file_get_snapshot_dir (NautilusFile *file);
18556N/A+typedef void (*FileHasSnapshotCallback) (gpointer user_data);
18556N/A+
18556N/A+void nautilus_file_get_snapshot_version (NautilusFile *file,
18556N/A+ FileHasSnapshotCallback callback,
18556N/A+ GCancellable *cancel,
18556N/A+ gpointer user_data);
18556N/A+
18556N/A /* Permissions. */
18556N/A gboolean nautilus_file_can_get_permissions (NautilusFile *file);
18556N/A gboolean nautilus_file_can_set_permissions (NautilusFile *file);
20808N/A--- nautilus-3.1.3/libnautilus-private/nautilus-global-preferences.h.orig 2011-07-22 10:33:34.400109504 +0100
20808N/A+++ nautilus-3.1.3/libnautilus-private/nautilus-global-preferences.h 2011-07-22 10:37:38.055064000 +0100
20808N/A@@ -42,6 +42,7 @@
20808N/A #define NAUTILUS_PREFERENCES_SHOW_HIDDEN_FILES "show-hidden-files"
20808N/A #define NAUTILUS_PREFERENCES_SHOW_ADVANCED_PERMISSIONS "show-advanced-permissions"
20808N/A #define NAUTILUS_PREFERENCES_DATE_FORMAT "date-format"
20808N/A+#define NAUTILUS_PREFERENCES_ENABLE_TIME_SLIDER "enable-time-slider"
18556N/A
18556N/A /* Mouse */
20808N/A #define NAUTILUS_PREFERENCES_MOUSE_USE_EXTRA_BUTTONS "mouse-use-extra-buttons"
20808N/A--- /dev/null 2011-07-25 14:19:16.000000000 +0100
20808N/A+++ nautilus-3.1.3/libnautilus-private/nautilus-zfs.c 2011-07-25 14:19:15.457833851 +0100
20808N/A@@ -0,0 +1,1221 @@
18556N/A+/*
18556N/A+ * Copyright (C) 2010 Sun Microsystems (Erwann Chenede)
18556N/A+ *
18556N/A+ */
18556N/A+
18556N/A+
18556N/A+#include <stdio.h>
18556N/A+#include <strings.h>
18556N/A+#include <stdlib.h>
18556N/A+#include <unistd.h>
18556N/A+#include "nautilus-zfs.h"
18556N/A+#include <time.h>
18556N/A+#include <locale.h>
18556N/A+#include <langinfo.h>
18556N/A+#include <stdint.h>
18556N/A+#include <glib.h>
18556N/A+#include <glib/gi18n.h>
18556N/A+#include <glib/gstdio.h>
18556N/A+#include <eel/eel-glib-extensions.h>
18556N/A+#include <sys/mnttab.h>
18556N/A+#include <sys/mkdev.h>
18556N/A+#include <libscf.h>
18556N/A+#include <dirent.h>
18592N/A+#include <sys/utsname.h>
18556N/A+#include "nautilus-global-preferences.h"
18556N/A+#define ZFS_SNAPSHOT_DIR ".zfs/snapshot/"
18556N/A+#define ZFS_BACKUP_DIR ".time-slider/rsync"
18556N/A+
18556N/A+char* ts_realpath (char * dir, char *resolved_name)
18556N/A+{
18556N/A+ char real_dir[PATH_MAX+1];
18556N/A+ char real_path[PATH_MAX+1];
18556N/A+ gboolean found = FALSE;
18556N/A+ struct stat64 dir_stat64;
18556N/A+ char *result;
18556N/A+
18556N/A+ result = realpath(dir, real_dir);
18556N/A+
18556N/A+ if (!result)
18556N/A+ return NULL;
18556N/A+
18556N/A+ if (stat64 (real_dir, &dir_stat64) == 0)
18556N/A+ {
18556N/A+ if (strcmp (dir_stat64.st_fstype, "lofs") == 0)
18556N/A+ {
18556N/A+ FILE *fp;
18556N/A+ struct extmnttab mtab;
18556N/A+ int status;
18556N/A+ fp = fopen (MNTTAB,"r");
18556N/A+
18556N/A+ resetmnttab(fp);
18556N/A+ while ((status = getextmntent(fp, &mtab, sizeof (struct extmnttab))) == 0)
18556N/A+ {
18556N/A+ if (strcmp (mtab.mnt_fstype, "lofs") == 0)
18556N/A+ {
18556N/A+ dev_t dev = NODEV;
18556N/A+ dev = makedev(mtab.mnt_major, mtab.mnt_minor);
18556N/A+ if (dev == dir_stat64.st_dev)
18556N/A+ {
18556N/A+ if (strcmp (real_dir, mtab.mnt_mountp) == 0)
18556N/A+ strcpy (real_path, mtab.mnt_special);
18556N/A+ else
18556N/A+ {
18556N/A+ gchar **split;
18556N/A+ split = g_strsplit (real_dir, mtab.mnt_mountp, 2);
18556N/A+ /*split 2nd part contains path without mount point */
18556N/A+ sprintf (real_path,"%s%s",mtab.mnt_special,split[1]);
18556N/A+ g_strfreev (split);
18556N/A+ }
18556N/A+ found = TRUE;
18556N/A+ break;
18556N/A+ }
18556N/A+ }
18556N/A+ }
18556N/A+ (void) fclose(fp);
18556N/A+ }
18556N/A+ }
18556N/A+ if (found)
18556N/A+ return strcpy (resolved_name, real_path);
18556N/A+ else
18556N/A+ return strcpy (resolved_name, real_dir);
18556N/A+}
18556N/A+
18556N/A+static void ts_set_snapshot_used_space (zfs_handle_t *zhp, ZfsDataSet *snap)
18556N/A+{
18556N/A+ gchar buf[ZFS_MAXNAMELEN];
18556N/A+ if (zfs_prop_get(zhp, ZFS_PROP_USED, buf, sizeof (buf), NULL, NULL, 0, B_FALSE) == 0)
18556N/A+ {
18556N/A+ char unit[10];
18556N/A+ char format_float[5] = "%f%s";
18556N/A+ char format_int[5] = "%d%s";
18556N/A+ char *format = format_int;
18556N/A+ int used_space_int = 0;
18556N/A+ gboolean success = FALSE;
18556N/A+
18556N/A+ snap->used_space_str = g_strdup (buf);
18556N/A+
18556N/A+ if (strchr (buf, '.'))
18556N/A+ {
18556N/A+ format = format_float;
18556N/A+ if (sscanf(buf, format,&snap->used_space,unit) == 2)
18556N/A+ success = TRUE;
18556N/A+ }
18556N/A+ else
18556N/A+ {
18556N/A+ if (sscanf(buf, format,&used_space_int,unit) == 2)
18556N/A+ {
18556N/A+ success = TRUE;
18556N/A+ snap->used_space = (float) used_space_int;
18556N/A+ }
18556N/A+ }
18556N/A+ if (strcmp (buf, "0") == 0)
18556N/A+ {
18556N/A+ g_free (snap->used_space_str);
18556N/A+ snap->used_space_str = g_strdup ("0 K");
18556N/A+ success = TRUE;
18556N/A+ }
18556N/A+
18556N/A+ if (success)
18556N/A+ {
18556N/A+ if (strcmp (unit, "M") == 0)
18556N/A+ snap->used_space *= 1024;
18556N/A+ if (strcmp (unit, "G") == 0)
18556N/A+ snap->used_space *= 1024 * 1024;
18556N/A+ }
18556N/A+ else
18556N/A+ {
18556N/A+ g_free (snap->used_space_str);
18556N/A+ /* SUN_BRANDING */
18556N/A+ snap->used_space_str = g_strdup (_("Unknown"));
18556N/A+ }
18556N/A+ }
18556N/A+ else
18556N/A+ {
18556N/A+ g_free (snap->used_space_str);
18556N/A+ /* SUN_BRANDING */
18556N/A+ snap->used_space_str = g_strdup (_("Unknown"));
18556N/A+ }
18556N/A+}
18556N/A+
18556N/A+static void ts_set_snapshot_mtime_and_time_diff (zfs_handle_t *zhp, ZfsDataSet *snap)
18556N/A+{
18556N/A+ GDate now;
18556N/A+ GDate then;
18556N/A+ time_t time_now;
18556N/A+ gint days_diff;
18556N/A+ const gchar *format;
18556N/A+ gchar *locale_format = NULL;
18556N/A+ gchar buf[ZFS_MAXNAMELEN];
18556N/A+ gchar *date_str = NULL;
18556N/A+
18556N/A+ if (zfs_prop_get(zhp, ZFS_PROP_CREATION, buf, sizeof (buf), NULL, NULL, 0, B_TRUE) == 0)
18556N/A+ {
18556N/A+ struct tm tms;
18556N/A+
18556N/A+ sscanf (buf, "%llu", &snap->mtime);
18556N/A+ snap->mtime_str = nautilus_date_as_string (snap->mtime, FALSE);
18556N/A+ }
18556N/A+
18556N/A+}
18556N/A+
18556N/A+void print_snap_list (char *dir, GList *snap_list)
18556N/A+{
18556N/A+ GList *tmp;
18556N/A+ printf ("list of snapshots for %s :\n", dir);
18556N/A+ for (tmp = snap_list; tmp->next; tmp = tmp->next)
18556N/A+ {
18556N/A+ ZfsDataSet *snap = (ZfsDataSet*) tmp->data;
18556N/A+ printf (" name: %s\n mountpoint: %s\n mtime_str :%s\n space used : %s\n size in kilobytes : %f\n",
18556N/A+ snap->name, snap->mountpoint, snap->mtime_str, snap->used_space_str, snap->used_space);
18556N/A+
18556N/A+ }
18556N/A+ printf ("\n");
18556N/A+}
18556N/A+
18556N/A+static GString *
18556N/A+dump_zds (ZfsDataSet *zds)
18556N/A+{
18556N/A+ GString *msg;
18556N/A+ gchar *type;
18556N/A+
18556N/A+ if (!zds)
18556N/A+ return NULL;
18556N/A+
18556N/A+ msg = g_string_new ("");
18556N/A+ g_string_printf (msg,
18556N/A+ "\tname: %s\n"
18556N/A+ "\tmountpoint: %s\n"
18556N/A+ "\ttype: %s\n",
18556N/A+ zds->name,zds->mountpoint, zfs_type_to_name(zds->type));
18556N/A+ if (zds->snapshots)
18556N/A+ {
18556N/A+ GList *tmp;
18556N/A+ g_string_append_printf(msg,"\tsnapshots :\n");
18556N/A+ for (tmp=zds->snapshots;tmp;tmp = tmp->next)
18556N/A+ {
18556N/A+ ZfsDataSet *tmp_zds= (ZfsDataSet*) tmp->data;
18556N/A+ g_string_append_printf (msg,"\t\tname: %s\n\t\tpath: %s\n",
18556N/A+ tmp_zds->name,
18556N/A+ tmp_zds->mountpoint);
18556N/A+ }
18556N/A+ }
18556N/A+ g_string_append_printf (msg, "\n");
18556N/A+ return msg;
18556N/A+}
18556N/A+
18556N/A+
18556N/A+static void
18556N/A+dump_sds (SearchDataSet *sds)
18556N/A+{
18556N/A+ GString *msg;
18556N/A+ gchar *type;
18556N/A+ GList *tmp;
18556N/A+
18556N/A+ if (!sds)
18556N/A+ {
18556N/A+ printf ("Search DataSet is empty\n");
18556N/A+ return;
18556N/A+ }
18556N/A+
18556N/A+ msg = g_string_new ("");
18556N/A+ g_string_printf (msg, "DDS Dump:\n"
18556N/A+ "\tsearched_path: %s\n",
18556N/A+ sds->searched_path);
18556N/A+
18556N/A+ g_string_append_printf (msg, "Zfs Data set :\n");
18556N/A+ for (tmp=sds->datasets;tmp;tmp=tmp->next)
18556N/A+ {
18556N/A+ GString * zds_dump = dump_zds ((ZfsDataSet *)tmp->data);
18556N/A+ g_string_append_printf (msg,"%s",zds_dump->str);
18556N/A+ g_string_free (zds_dump, TRUE);
18556N/A+ }
18556N/A+ g_string_append_printf (msg, "\n");
18556N/A+ printf ("%s", msg->str);
18556N/A+ g_string_free (msg, TRUE);
18556N/A+}
18556N/A+
18556N/A+static ZfsDataSet*
18556N/A+ts_new_zfs_dataset (SearchDataSet* sds)
18556N/A+{
18556N/A+ ZfsDataSet *zds;
18556N/A+ zds = g_new0 (ZfsDataSet, 1);
18556N/A+ zds->search_dataset = sds;
18556N/A+ return zds;
18556N/A+}
18556N/A+
18556N/A+void
18556N/A+ts_free_zfs_dataset (ZfsDataSet* zds)
18556N/A+{
18556N/A+ if (!zds)
18556N/A+ return;
18556N/A+ if (zds->name)
18556N/A+ g_free (zds->name);
18556N/A+ if (zds->mountpoint)
18556N/A+ g_free (zds->mountpoint);
18556N/A+ if (zds->mtime_str)
18556N/A+ g_free (zds->mtime_str);
18556N/A+ if (zds->used_space_str)
18556N/A+ g_free (zds->used_space_str);
18556N/A+
18556N/A+ if (zds->snapshots)
18556N/A+ {
18556N/A+ GList *tmp;
18556N/A+ for (tmp = zds->snapshots;tmp;tmp = tmp->next)
18556N/A+ ts_free_zfs_dataset ((ZfsDataSet*)tmp->data);
18556N/A+ }
18556N/A+ g_free (zds);
18556N/A+}
18556N/A+
18556N/A+static SearchDataSet *
18556N/A+ts_new_search_dataset (GCancellable *cancel)
18556N/A+{
18556N/A+ SearchDataSet *sds;
18556N/A+ sds = g_new0 (SearchDataSet, 1);
18556N/A+ sds->cancel = cancel;
18556N/A+ return sds;
18556N/A+}
18556N/A+static void
18556N/A+ts_free_search_dataset (SearchDataSet *sds)
18556N/A+{
18556N/A+ if (!sds)
18556N/A+ return;
18556N/A+ if (sds->searched_path)
18556N/A+ g_free (sds->searched_path);
18556N/A+ if (sds->mountpoint)
18556N/A+ g_free (sds->mountpoint);
18556N/A+ if (sds->datasets)
18556N/A+ {
18556N/A+ GList *tmp;
18556N/A+ for (tmp = sds->datasets;tmp;tmp = tmp->next)
18556N/A+ ts_free_zfs_dataset ((ZfsDataSet*)tmp->data);
18556N/A+ }
18556N/A+ g_free (sds);
18556N/A+}
18556N/A+
18556N/A+static char* construct_check_snapshot_path (SearchDataSet *sds, char* mountpoint, const char *name, char *searched_path)
18556N/A+{
18556N/A+ gchar *result = NULL;
18556N/A+ gchar **split;
18556N/A+ gchar **split2;
18556N/A+
18556N/A+ gchar *snap_name = NULL;
18556N/A+ gchar *remaining_path = NULL;
18556N/A+
18556N/A+ /* get the snapshot name part pool@snap-name we are only interested in snap-name split[1] */
18556N/A+ split = g_strsplit (name,"@",2);
18556N/A+ /* get the path after the mountpoint */
18556N/A+ split2 = g_strsplit (searched_path, mountpoint, 2);
18556N/A+
18556N/A+ if (split && split[1])
18556N/A+ snap_name = split[1];
18556N/A+
18556N/A+ if (split2 && split2[1])
18556N/A+ remaining_path = split2[1];
18556N/A+
18556N/A+/* printf ("mountpoint : %s \nname : %s \nsearched_path: %s\n", mountpoint, name, searched_path);
18556N/A+ printf ("split %s at @ = [%s] [%s]\n", name, split[0],split[1]);
18556N/A+ printf ("split %s at [%s] = [%s] [%s]\n", searched_path, mountpoint, split2[0],split2[1]);
18556N/A+ printf ("%s/.zfs/snapshot/%s/%s\n\n", mountpoint, split[1], split2[1]);*/
18556N/A+
18556N/A+ if (snap_name && remaining_path)
18556N/A+ result = g_strdup_printf ("%s/.zfs/snapshot/%s/%s", mountpoint, snap_name, remaining_path);
18556N/A+
18556N/A+ g_strfreev (split);
18556N/A+ g_strfreev (split2);
18556N/A+
18556N/A+ /* don't test for file presence if searched path is the same as the mount point */
18556N/A+ if (sds->searched_path_match_mp)
18556N/A+ return result;
18556N/A+
18556N/A+ if (result && g_file_test (result, G_FILE_TEST_IS_DIR))
18556N/A+ {
18556N/A+ char real_dir[PATH_MAX+1];
18556N/A+ if (!ts_realpath(result, real_dir))
18556N/A+ {
18556N/A+ g_free (result);
18556N/A+ result = NULL;
18556N/A+ }
18556N/A+ else
18556N/A+ {
18556N/A+ g_free (result);
18556N/A+ result = g_strdup (real_dir);
18556N/A+ }
18556N/A+ return result;
18556N/A+ }
18556N/A+
18556N/A+ g_free (result);
18556N/A+ return NULL;
18556N/A+}
18556N/A+
18556N/A+static int
18556N/A+snapshot_callback (zfs_handle_t *zhp, void *data)
18556N/A+{
18556N/A+ ZfsDataSet *main_zds = (ZfsDataSet*) data;
18556N/A+
18556N/A+ /* only add snapshot dir that exist */
18556N/A+
18556N/A+ if (zfs_get_type (zhp) == ZFS_TYPE_SNAPSHOT && !g_cancellable_is_cancelled (main_zds->search_dataset->cancel))
18556N/A+ {
18556N/A+ const char* name = zfs_get_name (zhp);
18556N/A+ char *snap_path = construct_check_snapshot_path (main_zds->search_dataset,
18556N/A+ main_zds->mountpoint,
18556N/A+ name,
18556N/A+ main_zds->search_dataset->searched_path);
18556N/A+ if (snap_path)
18556N/A+ {
18556N/A+ ZfsDataSet *zds = ts_new_zfs_dataset (main_zds->search_dataset);
18556N/A+ zds->name = g_strdup (name);
18556N/A+ zds->type = ZFS_TYPE_SNAPSHOT;
18556N/A+ zds->mountpoint = snap_path;
18556N/A+ ts_set_snapshot_mtime_and_time_diff (zhp, zds);
18556N/A+ ts_set_snapshot_used_space (zhp, zds);
18556N/A+ main_zds->snapshots = g_list_append (main_zds->snapshots,zds);
18556N/A+ }
18556N/A+ }
18556N/A+ zfs_close (zhp);
18556N/A+ return 0;
18556N/A+}
18556N/A+
18556N/A+
18556N/A+static struct mnttab *
18556N/A+mygetmntent(FILE *f)
18556N/A+{
18556N/A+ static struct mnttab mt;
18556N/A+ int status;
18556N/A+
18556N/A+ if ((status = getmntent(f, &mt)) == 0)
18556N/A+ return (&mt);
18556N/A+
18556N/A+ return (NULL);
18556N/A+}
18556N/A+
18556N/A+static char *
18556N/A+is_fs_mounted (const char *fs_name)
18556N/A+{
18556N/A+ FILE *mnttab;
18556N/A+ struct mnttab *mntp;
18556N/A+
18556N/A+
18556N/A+ mnttab = fopen (MNTTAB,"r");
18556N/A+
18556N/A+ while ((mntp = mygetmntent(mnttab)) != NULL)
18556N/A+ {
18556N/A+ if (mntp->mnt_fstype == (char *)0 || strcmp(mntp->mnt_fstype, "zfs") != 0)
18556N/A+ continue;
18556N/A+ if (strcmp (mntp->mnt_special, fs_name) == 0)
18556N/A+ {
18556N/A+ fclose (mnttab);
18556N/A+ return g_strdup (mntp->mnt_mountp);
18556N/A+ }
18556N/A+ }
18556N/A+ fclose (mnttab);
18556N/A+ return NULL;
18556N/A+}
18556N/A+
18556N/A+static char* rsync_get_smf_dir()
18556N/A+{
18556N/A+ char data_store[MAXPATHLEN];
18556N/A+
18556N/A+ int retval = -1;
18556N/A+
18556N/A+ scf_handle_t *handle = NULL;
18556N/A+ scf_scope_t *sc = NULL;
18556N/A+ scf_service_t *svc = NULL;
18556N/A+ scf_instance_t *inst = NULL;
18556N/A+ scf_propertygroup_t *pg = NULL;
18556N/A+ scf_property_t *prop = NULL;
18556N/A+ scf_value_t *value = NULL;
18556N/A+ scf_iter_t *value_iter = NULL;
18556N/A+
18556N/A+
18556N/A+ /* connect to the current SMF global repository */
18556N/A+ handle = scf_handle_create(SCF_VERSION);
18556N/A+
18556N/A+ /* allocate scf resources */
18556N/A+ sc = scf_scope_create(handle);
18556N/A+ svc = scf_service_create(handle);
18556N/A+ inst = scf_instance_create (handle);
18556N/A+ pg = scf_pg_create(handle);
18556N/A+ prop = scf_property_create(handle);
18556N/A+ value = scf_value_create(handle);
18556N/A+ value_iter = scf_iter_create(handle);
18556N/A+
18556N/A+ char *result = NULL;
18556N/A+
18556N/A+ /* if failed to allocate resources, exit */
18556N/A+ if (handle == NULL || sc == NULL || svc == NULL || pg == NULL ||
18556N/A+ prop == NULL || value == NULL || value_iter == NULL) {
18556N/A+ /* scf handles allocation failed. */
18556N/A+ goto out;
18556N/A+ }
18556N/A+
18556N/A+ /* bind scf handle to the running svc.configd daemon */
18556N/A+ if (scf_handle_bind(handle) == -1) {
18556N/A+ /* scf binding failed. */
18556N/A+ goto out;
18556N/A+ }
18556N/A+
18556N/A+ /* get the scope of the localhost in the current repository */
18556N/A+ if (scf_handle_get_scope(handle, SCF_SCOPE_LOCAL, sc) == -1) {
18556N/A+ /* Getting scf scope failed.*/
18556N/A+ goto out;
18556N/A+ }
18556N/A+
18556N/A+ /* get the service within the scope */
18556N/A+ if (scf_scope_get_service(sc, "application/time-slider/plugin", svc) == -1) {
18556N/A+ /* failed getting service */
18556N/A+ goto out;
18556N/A+ }
18556N/A+
18556N/A+ /* get the instance within the service */
18556N/A+ if (scf_service_get_instance(svc, "rsync", inst) == -1)
18556N/A+ goto out;
18556N/A+
18556N/A+
18556N/A+ /* get the property group within the instance */
18556N/A+ if (scf_instance_get_pg(inst, "rsync", pg) == -1) {
18556N/A+ /* Getting property group failed. */
18556N/A+ goto out;
18556N/A+ }
18556N/A+
18556N/A+ /*
18556N/A+ * Now get the properties.
18556N/A+ */
18556N/A+ if (scf_pg_get_property(pg, "target_dir", prop) == -1) {
18556N/A+ goto out;
18556N/A+ }
18556N/A+
18556N/A+ if (scf_property_get_value(prop, value) == -1) {
18556N/A+ goto out;
18556N/A+ }
18556N/A+
18556N/A+ data_store[0] = 0;
18556N/A+ if (scf_value_get_astring(value, data_store, MAXPATHLEN) == -1) {
18556N/A+ goto out;
18556N/A+ }
18556N/A+ else {
18556N/A+ result = strdup (data_store);
18556N/A+ }
18556N/A+
18556N/A+out:
18556N/A+ /* destroy scf pointers */
18556N/A+ if (value != NULL)
18556N/A+ scf_value_destroy(value);
18556N/A+ if (value_iter != NULL)
18556N/A+ scf_iter_destroy(value_iter);
18556N/A+ if (prop != NULL)
18556N/A+ scf_property_destroy(prop);
18556N/A+ if (pg != NULL)
18556N/A+ scf_pg_destroy(pg);
18556N/A+ if (inst != NULL)
18556N/A+ scf_instance_destroy (inst);
18556N/A+ if (svc != NULL)
18556N/A+ scf_service_destroy(svc);
18556N/A+ if (sc != NULL)
18556N/A+ scf_scope_destroy(sc);
18556N/A+ if (handle != NULL)
18556N/A+ scf_handle_destroy(handle);
18556N/A+
18556N/A+ return result;
18556N/A+}
18556N/A+
18556N/A+static char *rsync_get_dir (zfs_handle_t *zhp)
18556N/A+{
18556N/A+ nvlist_t *propval;
18556N/A+
18556N/A+ if (nvlist_lookup_nvlist(zfs_get_user_props(zhp),
18556N/A+ "org.opensolaris:time-slider-rsync", &propval) == 0)
18556N/A+ {
18556N/A+ boolean_t ret_bool = FALSE;
18556N/A+ char *strval;
18556N/A+ char *dir;
18556N/A+ nvlist_lookup_string(propval, ZPROP_VALUE, &strval);
18556N/A+
18556N/A+ if (strcmp (strval, "true") == 0)
18556N/A+ {
18556N/A+ dir = rsync_get_smf_dir ();
18556N/A+ if (dir)
18556N/A+ return dir;
18556N/A+ }
18556N/A+ }
18556N/A+ return NULL;
18556N/A+}
18556N/A+
18556N/A+void sync_backups_add (zfs_handle_t *zhp, ZfsDataSet *main_zds)
18556N/A+{
18556N/A+ char *rsync_dir = rsync_get_dir (zhp);
18556N/A+ DIR *d;
18556N/A+ struct dirent *dir;
18556N/A+ char *fs_rsync_dir;
18592N/A+ struct utsname machine;
18556N/A+
18556N/A+ if (!rsync_dir)
18556N/A+ return;
18556N/A+
18592N/A+ /* format SMF backup dir , TIMESLIDER, nodename from uname, path, .time-slider/rsync */
18592N/A+ if (uname (&machine) == -1)
18592N/A+ return;
18592N/A+
18744N/A+ fs_rsync_dir = g_strdup_printf ("%s/TIMESLIDER/%s/%s/%s/",
18592N/A+ rsync_dir,
18592N/A+ machine.nodename,
18744N/A+ main_zds->name,
18744N/A+ ZFS_BACKUP_DIR);
18556N/A+
18556N/A+ if (!g_file_test (fs_rsync_dir, G_FILE_TEST_IS_DIR))
18556N/A+ {
18556N/A+ g_free (rsync_dir);
18556N/A+ g_free (fs_rsync_dir);
18556N/A+ return;
18556N/A+ }
18556N/A+
18556N/A+ d = opendir (fs_rsync_dir);
18556N/A+
18556N/A+ if (!d)
18556N/A+ {
18556N/A+ g_free (rsync_dir);
18556N/A+ g_free (fs_rsync_dir);
18556N/A+ return;
18556N/A+ }
18556N/A+
18556N/A+ while ((dir = readdir (d)))
18556N/A+ {
18556N/A+ if (strstr (dir->d_name, "zfs-auto-snap_"))
18556N/A+ { /* got a snap copy dir */
18556N/A+ char **comma_split = NULL;
18556N/A+ char **freq_split = NULL;
18556N/A+ struct tm tms;
18556N/A+ ZfsDataSet *zds = NULL;
18556N/A+
18556N/A+ /* extract creation time from dir name */
18556N/A+ comma_split = g_strsplit (dir->d_name, "_", 2);
18556N/A+ /* printf ("comma_split[1] = %s\n", comma_split[1]); */
18556N/A+ freq_split = g_strsplit (comma_split[1], "-", 2);
18556N/A+ /* printf ("freq_split[1] = %s\n", freq_split[1]); */
18556N/A+
18556N/A+ /* parse time string */
18556N/A+ if (strptime (freq_split[1], "%Y-%m-%d-%Hh%M", &tms) != NULL)
18556N/A+ {
18556N/A+ zds = ts_new_zfs_dataset (main_zds->search_dataset);
18556N/A+ zds->name = g_strdup (dir->d_name);
18556N/A+ zds->type = NULL;
18592N/A+ zds->mountpoint = g_strdup_printf ("%s%s/", fs_rsync_dir, dir->d_name);
18556N/A+ zds->mtime = mktime (&tms);
18556N/A+ zds->mtime_str = nautilus_date_as_string (zds->mtime, FALSE);
18556N/A+ zds->used_space_str = g_strdup (_("Separate Backup"));
18556N/A+ main_zds->snapshots = g_list_append (main_zds->snapshots,zds);
18556N/A+ /* printf ("in sync_backups_add adding %s %s\n", zds->name, zds->mountpoint); */
18556N/A+ }
18556N/A+ if (comma_split)
18556N/A+ g_strfreev (comma_split);
18556N/A+ if (freq_split)
18556N/A+ g_strfreev (freq_split);
18556N/A+ }
18556N/A+ }
18556N/A+
18556N/A+ closedir (d);
18556N/A+ g_free (rsync_dir);
18556N/A+}
18556N/A+
18556N/A+static int
18556N/A+zfs_callback (zfs_handle_t *zhp, void *data)
18556N/A+{
18556N/A+ char buf[ZFS_MAXPROPLEN];
18556N/A+ SearchDataSet *sds = (SearchDataSet*) data;
18556N/A+
18556N/A+ if (sds->match_found)
18556N/A+ {
18556N/A+ zfs_close (zhp);
18556N/A+ return 0;
18556N/A+ }
18556N/A+
18556N/A+ if (zfs_get_type (zhp) & sds->type & !g_cancellable_is_cancelled (sds->cancel))
18556N/A+ {
18556N/A+/* struct timespec ts;
18556N/A+ ts.tv_sec = 3;
18556N/A+ ts.tv_nsec = 100000000;
18556N/A+ nanosleep (&ts, NULL);*/
18556N/A+
18556N/A+ if (sds->prop >= ZFS_PROP_TYPE && sds->prop < ZFS_NUM_PROPS)
18556N/A+ {
18556N/A+ zfs_prop_get(zhp, sds->prop, buf, sizeof (buf), NULL, NULL, 0, TRUE);
18556N/A+
18556N/A+ if (strcmp (sds->mountpoint, buf) == 0)
18556N/A+ {
18556N/A+ ZfsDataSet *zds = ts_new_zfs_dataset (sds);
18556N/A+ zds->type = zfs_get_type (zhp);
18556N/A+ zds->name = g_strdup (zfs_get_name(zhp));
18556N/A+ zds->mountpoint = g_strdup (buf);
18556N/A+ zfs_iter_snapshots (zhp, snapshot_callback, zds);
18556N/A+ sync_backups_add (zhp, zds);
18556N/A+ sds->datasets = g_list_append (sds->datasets, zds);
18556N/A+ sds->match_found = TRUE;
18556N/A+ }
18556N/A+ else if (strcmp ("legacy", buf) == 0)
18556N/A+ { /* parse /etc/mnttab to get the mount point */
18556N/A+ char *mountp = is_fs_mounted (zfs_get_name(zhp));
18556N/A+ if (mountp)
18556N/A+ {
18556N/A+ if (strcmp (sds->mountpoint, mountp) == 0)
18556N/A+ {
18556N/A+ ZfsDataSet *zds = ts_new_zfs_dataset (sds);
18556N/A+ zds->type = zfs_get_type (zhp);
18556N/A+ zds->name = g_strdup (zfs_get_name(zhp));
18556N/A+ zds->mountpoint = mountp;
18556N/A+ zfs_iter_snapshots (zhp, snapshot_callback, zds);
18556N/A+ sync_backups_add (zhp, zds);
18556N/A+ sds->datasets = g_list_append (sds->datasets, zds);
18556N/A+ sds->match_found = TRUE;
18556N/A+ }
18556N/A+ else
18556N/A+ g_free (mountp);
18556N/A+ }
18556N/A+ }
18556N/A+ }
18556N/A+ if (!sds->match_found)
18556N/A+ zfs_iter_filesystems (zhp, zfs_callback, sds);
18556N/A+ }
18556N/A+ zfs_close (zhp);
18556N/A+ return 0;
18556N/A+}
18556N/A+
18556N/A+static SearchDataSet *
18556N/A+ts_get_data_from_mountpoint (const char* searched_path, const char *mountpoint, GCancellable *cancel)
18556N/A+{
18556N/A+ static libzfs_handle_t *zfs_handle = NULL;
18556N/A+ SearchDataSet *sds;
18556N/A+
18556N/A+ sds = ts_new_search_dataset (cancel);
18556N/A+
18556N/A+ sds->prop = ZFS_PROP_MOUNTPOINT;
18556N/A+ sds->type = ZFS_TYPE_FILESYSTEM;
18556N/A+ sds->searched_path = g_strdup (searched_path);
18556N/A+ sds->mountpoint = g_strdup (mountpoint);
18556N/A+
18556N/A+ if (strcmp (searched_path, mountpoint) == 0)
18556N/A+ sds->searched_path_match_mp = TRUE;
18556N/A+
18556N/A+ if (!zfs_handle)
18556N/A+ {
18556N/A+ if ((zfs_handle = libzfs_init()) == NULL) {
18556N/A+ g_warning ("internal error: failed to initialize ZFS library\n");
18556N/A+ ts_free_search_dataset (sds);
18556N/A+ return NULL;
18556N/A+ }
18556N/A+ }
18556N/A+ zfs_iter_root (zfs_handle, zfs_callback, sds);
18556N/A+
18556N/A+ return sds;
18556N/A+}
18556N/A+static gint
18556N/A+snap_sort_by_age (gconstpointer a,
18556N/A+ gconstpointer b)
18556N/A+{
18556N/A+ const ZfsDataSet *snap1 = a;
18556N/A+ const ZfsDataSet *snap2 = b;
18556N/A+
18556N/A+ if (snap1->mtime == snap2->mtime)
18556N/A+ return 0;
18556N/A+ if (snap1->mtime < snap2->mtime)
18556N/A+ return -1;
18556N/A+ if (snap1->mtime > snap2->mtime)
18556N/A+ return 1;
18556N/A+
18556N/A+}
18556N/A+
18556N/A+char*
18556N/A+ts_get_zfs_filesystem (char *dir)
18556N/A+{
18556N/A+ char real_dir[PATH_MAX+1];
18556N/A+ char filesystem[PATH_MAX+1];
18556N/A+ gboolean found_fs= FALSE;
18556N/A+ struct stat64 dir_stat64;
18556N/A+
18556N/A+ if (!ts_realpath(dir, real_dir))
18556N/A+ {
18556N/A+ return NULL;
18556N/A+ }
18556N/A+ if (stat64 (real_dir, &dir_stat64) == 0)
18556N/A+ { /* check is fs is zfs */
18556N/A+ if (strcmp (dir_stat64.st_fstype, "zfs") == 0)
18556N/A+ {
18556N/A+ FILE *fp;
18556N/A+ struct extmnttab mtab;
18556N/A+ int status;
18556N/A+
18556N/A+ /* get mount point */
18556N/A+
18556N/A+ fp = fopen (MNTTAB,"r");
18556N/A+
18556N/A+ resetmnttab(fp);
18556N/A+ while ((status = getextmntent(fp, &mtab, sizeof (struct extmnttab))) == 0)
18556N/A+ {
18556N/A+ dev_t dev = NODEV;
18556N/A+ dev = makedev(mtab.mnt_major, mtab.mnt_minor);
18556N/A+ if (dev == dir_stat64.st_dev)
18556N/A+ {
18556N/A+ strcpy (filesystem, mtab.mnt_special);
18556N/A+ found_fs = TRUE;
18556N/A+ break;
18556N/A+ }
18556N/A+ }
18556N/A+ (void) fclose(fp);
18556N/A+ }
18556N/A+ }
18556N/A+ if (found_fs)
18556N/A+ return g_strdup(filesystem);
18556N/A+
18556N/A+ return NULL;
18556N/A+}
18556N/A+
18556N/A+static char * get_zfs_mountpoint (char *dir)
18556N/A+{
18556N/A+ char real_dir[PATH_MAX+1];
18556N/A+ char mountpoint[PATH_MAX+1];
18556N/A+ gboolean found_mount_point = FALSE;
18556N/A+ struct stat64 dir_stat64;
18556N/A+
18556N/A+ if (!ts_realpath(dir, real_dir))
18556N/A+ {
18556N/A+ return NULL;
18556N/A+ }
18556N/A+ if (stat64 (real_dir, &dir_stat64) == 0)
18556N/A+ { /* check is fs is zfs */
18556N/A+ if (strcmp (dir_stat64.st_fstype, "zfs") == 0)
18556N/A+ {
18556N/A+ FILE *fp;
18556N/A+ struct extmnttab mtab;
18556N/A+ int status;
18556N/A+
18556N/A+ /* get mount point */
18556N/A+
18556N/A+ fp = fopen (MNTTAB,"r");
18556N/A+
18556N/A+ resetmnttab(fp);
18556N/A+ while ((status = getextmntent(fp, &mtab, sizeof (struct extmnttab))) == 0)
18556N/A+ {
18556N/A+ dev_t dev = NODEV;
18556N/A+ dev = makedev(mtab.mnt_major, mtab.mnt_minor);
18556N/A+ if (dev == dir_stat64.st_dev)
18556N/A+ {
18556N/A+ strcpy (mountpoint, mtab.mnt_mountp);
18556N/A+ found_mount_point = TRUE;
18556N/A+ break;
18556N/A+ }
18556N/A+ }
18556N/A+ (void) fclose(fp);
18556N/A+ }
18556N/A+ }
18556N/A+ if (found_mount_point)
18556N/A+ return g_strdup(mountpoint);
18556N/A+
18556N/A+ return NULL;
18556N/A+}
18556N/A+
18556N/A+
18556N/A+char *ts_get_snapshot_dir (char *dir)
18556N/A+{
18556N/A+ char *zfs_dir = get_zfs_mountpoint (dir);
18556N/A+ if (zfs_dir)
18556N/A+ {
18556N/A+ char *snapshot_dir = g_strdup_printf ("%s/.zfs/snapshot", zfs_dir);
18556N/A+ g_free (zfs_dir);
18556N/A+ return snapshot_dir;
18556N/A+ }
18556N/A+ else
18556N/A+ return NULL;
18556N/A+}
18556N/A+
18556N/A+
18556N/A+
18556N/A+static void ts_get_snapshots_for_dir (GSimpleAsyncResult *res,
18556N/A+ GObject *object,
18556N/A+ GCancellable *cancellable)
18556N/A+{
18556N/A+ char *mountpoint = NULL;
18556N/A+ char real_dir[PATH_MAX+1];
18556N/A+ SearchDataSet *sds;
18556N/A+ GList* snap_result = NULL;
18556N/A+ GFile *file = G_FILE (object);
18556N/A+ char *dir = g_file_get_path (file);
18556N/A+
18556N/A+ mountpoint = get_zfs_mountpoint (dir);
18556N/A+
18556N/A+
18556N/A+ if (!mountpoint)
18556N/A+ {
18556N/A+ g_simple_async_result_set_op_res_gpointer (res, snap_result, (GDestroyNotify) NULL);
18556N/A+ g_free (dir);
18556N/A+ return;
18556N/A+ }
18556N/A+
18556N/A+ ts_realpath(dir, real_dir);
18556N/A+
18556N/A+ sds = ts_get_data_from_mountpoint (real_dir, mountpoint, cancellable);
18556N/A+
18556N/A+ g_free (mountpoint);
18556N/A+
18556N/A+ if (g_cancellable_is_cancelled (cancellable))
18556N/A+ {
18556N/A+ /* printf ("ts_get_snapshots_for_dir %s cancelled\n", dir); */
18556N/A+ if (sds)
18556N/A+ {
18556N/A+ ts_free_search_dataset (sds);
18556N/A+ sds = NULL;
18556N/A+ }
18556N/A+ }
18556N/A+
18556N/A+ if (sds)
18556N/A+ {
18556N/A+ GList *tmp;
18556N/A+ for (tmp=sds->datasets;tmp;tmp=tmp->next)
18556N/A+ {
18556N/A+ ZfsDataSet *zds = (ZfsDataSet*) tmp->data;
18556N/A+ if (zds->snapshots)
18556N/A+ {
18556N/A+ snap_result = g_list_concat (snap_result, zds->snapshots);
18556N/A+ zds->snapshots = NULL;
18556N/A+ }
18556N/A+ }
18556N/A+ ts_free_search_dataset (sds);
18556N/A+ }
18556N/A+
18556N/A+ if (snap_result)
18556N/A+ {
18556N/A+ snap_result = g_list_sort (snap_result, (GCompareFunc)snap_sort_by_age);
18556N/A+ /* print_snap_list (dir, snap_result); */
18556N/A+ }
18556N/A+
18556N/A+ g_free (dir);
18556N/A+ g_simple_async_result_set_op_res_gpointer (res, snap_result, (GDestroyNotify) NULL);
18556N/A+}
18556N/A+
18556N/A+
18556N/A+GList *ts_get_snapshots_for_dir_async (GFile *file,
18556N/A+ GAsyncReadyCallback result_ready,
18556N/A+ GCancellable *cancel,
18556N/A+ gpointer user_data)
18556N/A+{
18556N/A+ GSimpleAsyncResult *res;
18556N/A+
18556N/A+ res = g_simple_async_result_new (G_OBJECT (file), result_ready, user_data, (gpointer) ts_get_snapshots_for_dir);
18556N/A+ g_simple_async_result_run_in_thread (res, ts_get_snapshots_for_dir, G_PRIORITY_DEFAULT, cancel);
18556N/A+ return NULL;
18556N/A+}
18556N/A+
18556N/A+
18556N/A+void ts_free_snapshots (GList *snaps)
18556N/A+{
18556N/A+ if (snaps)
18556N/A+ {
18556N/A+ GList *tmp;
18556N/A+ for (tmp=snaps;tmp;tmp=tmp->next)
18556N/A+ ts_free_zfs_dataset ((ZfsDataSet*) tmp->data);
18556N/A+ g_list_free (snaps);
18556N/A+ }
18556N/A+}
18556N/A+
18556N/A+gboolean ts_is_in_remote_backup (char *str)
18556N/A+{
18556N/A+ if (str != NULL)
18556N/A+ {
18556N/A+ if (g_strrstr (str, ZFS_BACKUP_DIR))
18556N/A+ return TRUE;
18556N/A+ }
18556N/A+ return FALSE;
18556N/A+}
18556N/A+
18556N/A+
18556N/A+gboolean ts_is_in_snapshot (char * str)
18556N/A+{
18556N/A+ if (str != NULL)
18556N/A+ {
18556N/A+ if (g_strrstr (str, ZFS_SNAPSHOT_DIR))
18556N/A+ return TRUE;
18556N/A+ if (g_strrstr (str, ZFS_BACKUP_DIR))
18556N/A+ return TRUE;
18556N/A+ }
18556N/A+ return FALSE;
18556N/A+}
18556N/A+
18556N/A+char* ts_remove_snapshot_dir (char *str)
18556N/A+{
18556N/A+ if (ts_is_in_snapshot (str))
18556N/A+ {
18556N/A+ char *snap_root;
18556N/A+ char *zfs, *iter, point;
18556N/A+ int count = 0;
18556N/A+
18556N/A+ /*remove .zfs/snapshot/blah/ */
18556N/A+ zfs = g_strrstr (str, ZFS_SNAPSHOT_DIR);
18556N/A+ iter = zfs;
18556N/A+
18556N/A+ if (iter)
18556N/A+ {
18556N/A+ iter += sizeof (ZFS_SNAPSHOT_DIR);
18556N/A+ while (*iter != '/' && *iter != '\0')
18556N/A+ iter++;
18556N/A+
18556N/A+ if (*iter == '/')
18556N/A+ iter++;
18556N/A+
18556N/A+ point = *zfs;
18556N/A+ *zfs = '\0';
18556N/A+ snap_root = g_strdup_printf ("%s%s", str, iter);
18556N/A+
18556N/A+ *zfs = point;
18556N/A+ return snap_root;
18556N/A+ }
18556N/A+ }
18556N/A+ return NULL;
18556N/A+}
18556N/A+
18556N/A+
18556N/A+static gboolean restore_col_enabled = FALSE;
18556N/A+
18556N/A+gboolean
18556N/A+ts_is_restore_column_enabled ()
18556N/A+{
18556N/A+ return restore_col_enabled;
18556N/A+}
18556N/A+
18556N/A+void ts_is_restore_column_enabled_init ();
18556N/A+
18556N/A+static void
18556N/A+visible_columns_changed (gpointer callback_data)
18556N/A+{
18556N/A+ ts_is_restore_column_enabled_init ();
18556N/A+}
18556N/A+
18556N/A+
18556N/A+void ts_is_restore_column_enabled_init ()
18556N/A+{
18556N/A+ char **visible_columns;
18556N/A+ static gboolean init = FALSE;
18556N/A+ int i = 0;
18556N/A+
18556N/A+ if (!init)
18556N/A+ {
20808N/A+ g_signal_connect_swapped(nautilus_preferences,
20808N/A+ "changed::" NAUTILUS_PREFERENCES_LIST_VIEW_DEFAULT_VISIBLE_COLUMNS,
20808N/A+ G_CALLBACK(visible_columns_changed), NULL);
18556N/A+ init = TRUE;
18556N/A+ }
18556N/A+
18556N/A+ restore_col_enabled = FALSE;
18556N/A+
20808N/A+ visible_columns = g_settings_get_strv (nautilus_preferences, NAUTILUS_PREFERENCES_LIST_VIEW_DEFAULT_VISIBLE_COLUMNS);
18556N/A+
18556N/A+ while (visible_columns[i])
18556N/A+ {
18556N/A+ if (strcmp (visible_columns [i], "restore_info") == 0)
18556N/A+ {
18556N/A+ restore_col_enabled = TRUE;
18556N/A+ break;
18556N/A+ }
18556N/A+ i++;
18556N/A+ }
18556N/A+ g_strfreev (visible_columns);
18556N/A+}
18556N/A+
18556N/A+
18556N/A+static GList * get_dir_entries (char *dir_path)
18556N/A+{
18556N/A+ const char *entry_name;
18556N/A+ GDir *dir;
18556N/A+ GList *dir_entries = NULL;
18556N/A+ dir = g_dir_open (dir_path, 0, NULL);
18556N/A+
18556N/A+ while ((entry_name = g_dir_read_name (dir)) != NULL)
18556N/A+ dir_entries = g_list_prepend (dir_entries, g_strdup (entry_name));
18556N/A+
18556N/A+ g_dir_close (dir);
18556N/A+
18556N/A+ return dir_entries;
18556N/A+}
18556N/A+
18556N/A+static void free_dir_entries (GList *entries)
18556N/A+{
18556N/A+ g_list_foreach (entries, (GFunc)g_free, NULL);
18556N/A+ g_list_free (entries);
18556N/A+}
18556N/A+
18556N/A+static gboolean are_entries_identical (GList *old, GList *new)
18556N/A+{
18556N/A+ if (g_list_length (old) != g_list_length (new))
18556N/A+ return FALSE;
18556N/A+
18556N/A+ for (old; old; old = old->next)
18556N/A+ {
18556N/A+ gboolean found = FALSE;
18556N/A+ for (new; new; new = new->next)
18556N/A+ {
18556N/A+ if (strcmp (old->data, new->data) == 0)
18556N/A+ {
18556N/A+ found = TRUE;
18556N/A+ break;
18556N/A+ }
18556N/A+ }
18556N/A+ if (!found)
18556N/A+ return FALSE;
18556N/A+ }
18556N/A+ return TRUE;
18556N/A+}
18556N/A+
18556N/A+void monitor_zfs_snap_directory_cancel (ZfsSnapDirMonitor *monitor_data)
18556N/A+{
18556N/A+ if (monitor_data)
18556N/A+ {
18556N/A+ /* printf ("in monitor_zfs_snap_directory_cancel %s\n", monitor_data->path); */
18556N/A+ g_source_remove (monitor_data->timeout_id);
18556N/A+ free_dir_entries (monitor_data->entries);
18556N/A+ g_free (monitor_data->path);
18556N/A+ g_free (monitor_data);
18556N/A+ }
18556N/A+}
18556N/A+
18556N/A+static gboolean
18556N/A+monitor_snap_dir (ZfsSnapDirMonitor *monitor_data)
18556N/A+{
18556N/A+ GList *new_entries;
18556N/A+
18556N/A+ if (!g_file_test (monitor_data->path, G_FILE_TEST_IS_DIR))
18556N/A+ {
18556N/A+ monitor_zfs_snap_directory_cancel (monitor_data);
18556N/A+ return TRUE;
18556N/A+ }
18556N/A+
18556N/A+ new_entries = get_dir_entries (monitor_data->path);
18556N/A+
18556N/A+ if (are_entries_identical (monitor_data->entries, new_entries))
18556N/A+ {
18556N/A+ free_dir_entries (new_entries);
18556N/A+ }
18556N/A+ else
18556N/A+ {
18556N/A+ free_dir_entries (monitor_data->entries);
18556N/A+ monitor_data->entries = new_entries;
18556N/A+ monitor_data->change_callback (monitor_data, monitor_data->user_data);
18556N/A+ }
18744N/A+
18744N/A+ if (monitor_data->backup_path)
18744N/A+ {
18744N/A+ if (!g_file_test (monitor_data->backup_path, G_FILE_TEST_IS_DIR))
18744N/A+ {
18744N/A+ monitor_zfs_snap_directory_cancel (monitor_data);
18744N/A+ return TRUE;
18744N/A+ }
18744N/A+
18744N/A+ new_entries = get_dir_entries (monitor_data->backup_path);
18744N/A+
18744N/A+ if (are_entries_identical (monitor_data->backup_entries, new_entries))
18744N/A+ {
18744N/A+ free_dir_entries (new_entries);
18744N/A+ }
18744N/A+ else
18744N/A+ {
18744N/A+ free_dir_entries (monitor_data->backup_entries);
18744N/A+ monitor_data->backup_entries = new_entries;
18744N/A+ monitor_data->change_callback (monitor_data, monitor_data->user_data);
18744N/A+ }
18744N/A+ }
18556N/A+ return TRUE;
18556N/A+}
18556N/A+
18556N/A+
18556N/A+ZfsSnapDirMonitor *monitor_zfs_snap_directory (char *path,
18744N/A+ char *backup_path,
18556N/A+ ZfsDirChangeCallback change_callback,
18556N/A+ gpointer data)
18556N/A+{
18556N/A+ ZfsSnapDirMonitor *monitor_data = g_new0 (ZfsSnapDirMonitor, 1);
18556N/A+
18556N/A+ /* printf ("start monitoring %s\n", path); */
18556N/A+
18556N/A+ monitor_data->path = g_strdup (path);
18556N/A+ monitor_data->entries = get_dir_entries (path);
18744N/A+ if (backup_path)
18744N/A+ {
18744N/A+ monitor_data->backup_path = g_strdup (backup_path);
18744N/A+ monitor_data->backup_entries = get_dir_entries (backup_path);
18744N/A+ }
18556N/A+ monitor_data->change_callback = change_callback;
18556N/A+ monitor_data->user_data = data;
18556N/A+
18556N/A+ monitor_data->timeout_id = g_timeout_add_seconds (5, (GSourceFunc)monitor_snap_dir, monitor_data);
18556N/A+ return monitor_data;
18556N/A+}
18556N/A+
18556N/A+char *
18556N/A+ts_get_not_zfs_snapshot_dir (GFile *file)
18556N/A+{
18556N/A+ char tmp_path[PATH_MAX + 1];
18556N/A+ gboolean found = FALSE;
18556N/A+ gboolean end_path = FALSE;
18556N/A+ GFile *d = g_file_get_parent(file);
18556N/A+ GFile *tmp;
18556N/A+ char *full_path = g_file_get_path (file);
18556N/A+ char *stripped_path = g_file_get_path (d);
18556N/A+ struct stat64 dir_stat64;
18556N/A+
18556N/A+ if (!full_path)
18556N/A+ return NULL;
18556N/A+
18556N/A+ if (stat64 (full_path, &dir_stat64) == 0)
18556N/A+ { /* check is fs is zfs if so don't try to check for nfs mounted .zfs dir*/
18556N/A+ if (strcmp (dir_stat64.st_fstype, "zfs") == 0)
18556N/A+ end_path = TRUE;
18556N/A+ }
18556N/A+
18556N/A+ while (!found && !end_path)
18556N/A+ {
18556N/A+ g_sprintf (tmp_path, "%s/.zfs/snapshot", stripped_path);
18556N/A+ if (g_file_test (tmp_path, G_FILE_TEST_IS_DIR))
18556N/A+ {
18556N/A+ GList *entries = get_dir_entries (tmp_path);
18556N/A+ if (entries != NULL)
18556N/A+ {
18556N/A+ char *after_snap_path = full_path + strlen (stripped_path);
18556N/A+
18556N/A+ for (entries; entries; entries = entries->next)
18556N/A+ {
18556N/A+ char test_path[PATH_MAX +1];
18556N/A+ g_sprintf (test_path, "%s/%s/%s", tmp_path,
18556N/A+ entries->data,
18556N/A+ after_snap_path);
18556N/A+ if (g_file_test (test_path, G_FILE_TEST_EXISTS))
18556N/A+ {
18556N/A+ found = TRUE;
18556N/A+ break;
18556N/A+ }
18556N/A+ }
18556N/A+ free_dir_entries (entries);
18556N/A+ }
18556N/A+ }
18556N/A+ tmp = d;
18556N/A+ d = g_file_get_parent (tmp);
18556N/A+ g_object_unref (tmp);
18556N/A+ g_free (stripped_path);
18556N/A+ stripped_path=NULL;
18556N/A+ if (d == NULL)
18556N/A+ {
18556N/A+ end_path = TRUE;
18556N/A+ }
18556N/A+ else
18556N/A+ {
18556N/A+ stripped_path = g_file_get_path (d);
18556N/A+ }
18556N/A+ }
18556N/A+
18556N/A+ g_free (full_path);
18556N/A+
18556N/A+ if (stripped_path)
18556N/A+ g_free (stripped_path);
18556N/A+
18556N/A+ if (found)
18556N/A+ return g_strdup (tmp_path);
18556N/A+ else
18556N/A+ return NULL;
18556N/A+
18556N/A+}
18744N/Adiff -Nrup -x '*.orig' -x '*.rej' -x '*.*~' ../SUNWgnome-file-mgr-2.30.0-b4/nautilus-2.30.1/libnautilus-private/nautilus-zfs.h nautilus-2.30.1/libnautilus-private/nautilus-zfs.h
18744N/A--- ../SUNWgnome-file-mgr-2.30.0-b4/nautilus-2.30.1/libnautilus-private/nautilus-zfs.h 1970-01-01 01:00:00.000000000 +0100
18744N/A+++ nautilus-2.30.1/libnautilus-private/nautilus-zfs.h 2010-05-14 17:17:27.383965864 +0200
18744N/A@@ -0,0 +1,77 @@
18556N/A+/* #include <config.h> */
18556N/A+#ifndef NAUTILUS_ZFS_H
18556N/A+#define NAUTILUS_ZFS_H
18556N/A+
18556N/A+#include <glib.h>
18556N/A+#include <libzfs.h>
18556N/A+#include <gio/gio.h>
18556N/A+
18556N/A+typedef struct
18556N/A+{
18556N/A+ zfs_type_t type;
18556N/A+ zfs_prop_t prop;
18556N/A+ char *searched_path;
18556N/A+ char *mountpoint;
18556N/A+ GList *datasets;
18556N/A+ GCancellable *cancel;
18556N/A+ gboolean match_found;
18556N/A+ gboolean searched_path_match_mp;
18556N/A+
18556N/A+} SearchDataSet;
18556N/A+
18556N/A+typedef struct
18556N/A+{
18556N/A+ char *name;
18556N/A+ char *mountpoint;
18556N/A+ char *mtime_str;
18556N/A+ time_t mtime;
18556N/A+ float used_space;
18556N/A+ char *used_space_str;
18556N/A+ zfs_type_t type;
18556N/A+ GList *snapshots;
18556N/A+ SearchDataSet *search_dataset;
18556N/A+} ZfsDataSet;
18556N/A+
18556N/A+
18556N/A+GList *ts_get_snapshots_for_dir_async (GFile *file,
18556N/A+ GAsyncReadyCallback result_ready,
18556N/A+ GCancellable *cancel,
18556N/A+ gpointer user_data);
18556N/A+void ts_free_snapshots (GList *snaps);
18556N/A+void ts_free_zfs_dataset (ZfsDataSet* zds);
18556N/A+
18556N/A+gboolean ts_is_in_snapshot (char * str);
18556N/A+gboolean ts_is_in_remote_backup (char *str);
18556N/A+char* ts_remove_snapshot_dir (char *str);
18556N/A+char *ts_get_snapshot_dir (char *dir);
18556N/A+char *ts_get_zfs_filesystem (char *dir);
18556N/A+char * ts_get_not_zfs_snapshot_dir (GFile *file);
18556N/A+gboolean ts_is_restore_column_enabled ();
18556N/A+void ts_is_restore_column_enabled_init ();
18556N/A+void print_snap_list (char *dir, GList *snap_list);
18556N/A+char* ts_realpath (char * dir, char *resolved_name);
18556N/A+
18556N/A+char *
18556N/A+nautilus_date_as_string (time_t time_raw, gboolean use_smallest);
18556N/A+
18556N/A+typedef void (*ZfsDirChangeCallback) (gpointer monitor_data,
18556N/A+ gpointer user_data);
18556N/A+
18556N/A+typedef struct
18556N/A+{
18556N/A+ char * path;
18556N/A+ GList *entries;
18744N/A+ char * backup_path;
18744N/A+ GList *backup_entries;
18556N/A+ guint timeout_id;
18556N/A+ ZfsDirChangeCallback change_callback;
18556N/A+ gpointer user_data;
18556N/A+} ZfsSnapDirMonitor;
18556N/A+
18556N/A+void monitor_zfs_snap_directory_cancel (ZfsSnapDirMonitor *monitor_data);
18556N/A+ZfsSnapDirMonitor *monitor_zfs_snap_directory (char *path,
18744N/A+ char *backup_path,
18556N/A+ ZfsDirChangeCallback change_callback,
18556N/A+ gpointer data);
18556N/A+#endif /* NAUTILUS_ZFS_H */
18556N/A+
20808N/A--- nautilus-3.1.3/src/Makefile.am.orig 2011-07-01 17:50:32.000000000 +0100
20808N/A+++ nautilus-3.1.3/src/Makefile.am 2011-07-22 10:47:37.617231822 +0100
20808N/A@@ -41,6 +41,8 @@
18556N/A $(EXIF_LIBS) \
18556N/A $(EXEMPI_LIBS) \
18556N/A $(POPT_LIBS) \
18556N/A+ $(SCF_LIBS) \
18556N/A+ $(NVPAIR_LIBS) \
18556N/A $(NULL)
18556N/A
20808N/A nautilus_SOURCES = \
20808N/A@@ -142,6 +144,10 @@
20808N/A nautilus-window-types.h \
20808N/A nautilus-x-content-bar.c \
20808N/A nautilus-x-content-bar.h \
18556N/A+ nautilus-zfs-bar.c \
18556N/A+ nautilus-zfs-bar.h \
20808N/A+ timescale.c \
18556N/A+ timescale.h \
18556N/A $(NULL)
18556N/A
20808N/A EMPTY_VIEW_SOURCES = \
20808N/A--- nautilus-3.1.3/src/nautilus-actions.h.orig 2011-07-22 10:54:06.075754016 +0100
20808N/A+++ nautilus-3.1.3/src/nautilus-actions.h 2011-07-22 10:56:03.673858543 +0100
20808N/A@@ -85,6 +85,9 @@
20808N/A #define NAUTILUS_ACTION_NEW_LAUNCHER "New Launcher"
20808N/A #define NAUTILUS_ACTION_NEW_LAUNCHER_DESKTOP "New Launcher Desktop"
20808N/A #define NAUTILUS_ACTION_RENAME "Rename"
20808N/A+#define NAUTILUS_ACTION_RESTORE_TO "Restore to"
20808N/A+#define NAUTILUS_ACTION_HAS_SNAPSHOT "View Snap"
20808N/A+#define NAUTILUS_ACTION_SNAP_NOW "Snap Now"
20808N/A #define NAUTILUS_ACTION_DUPLICATE "Duplicate"
20808N/A #define NAUTILUS_ACTION_CREATE_LINK "Create Link"
20808N/A #define NAUTILUS_ACTION_SELECT_ALL "Select All"
20808N/A--- nautilus-3.1.3/src/nautilus-view.c.orig 2011-07-25 14:46:18.267955464 +0100
20808N/A+++ nautilus-3.1.3/src/nautilus-view.c 2011-07-25 14:45:21.541051018 +0100
20808N/A@@ -1366,6 +1366,73 @@
18556N/A }
18556N/A
18556N/A static void
18556N/A+action_snap_now (GtkAction *action,
20808N/A+ gpointer callback_data)
18556N/A+{
20808N/A+ NautilusView *view = NAUTILUS_VIEW (callback_data);
20808N/A+ GList *selection = nautilus_view_get_selection_for_file_transfer (view);
20808N/A+ GFile *file = nautilus_file_get_location (NAUTILUS_FILE (selection->data));
20808N/A+ char *path = g_file_get_path (file);
20808N/A+ char *fs = ts_get_zfs_filesystem (path);
20808N/A+ char *cmd = g_strdup_printf ("/usr/lib/time-slider-snapshot '%s' '%s'", path, fs);
20808N/A+ nautilus_launch_application_from_command (gtk_window_get_screen (GTK_WIDGET(callback_data)), cmd, FALSE, NULL);
20808N/A+
20808N/A+ g_free (cmd);
20808N/A+ g_free (fs);
20808N/A+ g_free (path);
20808N/A+ g_object_unref (file);
18556N/A+}
18556N/A+
18556N/A+static void
18556N/A+action_restore_to_desktop_callback (GtkAction *action,
20808N/A+ gpointer callback_data)
18556N/A+{
20808N/A+ GList *locations = NULL;
20808N/A+ GList *node;
20808N/A+ NautilusView *view = NAUTILUS_VIEW (callback_data);
20808N/A+ char *desktop_directory = nautilus_get_desktop_directory_uri();
20808N/A+ GList *selection = nautilus_view_get_selection_for_file_transfer (view);
20808N/A+
20808N/A+ if (selection == NULL)
20808N/A+ return;
20808N/A+
20808N/A+ if (desktop_directory == NULL)
20808N/A+ return;
20808N/A+
20808N/A+
20808N/A+ for (node = selection; node != NULL; node = node->next) {
20808N/A+ locations = g_list_prepend (locations,
20808N/A+ nautilus_file_get_uri ((NautilusFile *) node->data));
20808N/A+ }
20808N/A+
20808N/A+ nautilus_view_move_copy_items (locations, NULL, desktop_directory,
20808N/A+ GDK_ACTION_COPY, 0, 0, view);
20808N/A+
20808N/A+ nautilus_file_list_free (selection);
18556N/A+}
18556N/A+
18556N/A+static void
18556N/A+action_show_snapshot_versions_callback (GtkAction *action,
18556N/A+ gpointer callback_data)
18556N/A+{
20808N/A+ NautilusView *view = NAUTILUS_VIEW (callback_data);
20808N/A+ GList *selection = nautilus_view_get_selection_for_file_transfer (view);
20808N/A+ GFile *file = nautilus_file_get_location (NAUTILUS_FILE (selection->data));
20808N/A+ char *dir = nautilus_file_get_snapshot_dir (NAUTILUS_FILE (selection->data));
20808N/A+ char *file_path = g_file_get_path (file);
20808N/A+ char real_file_path [PATH_MAX + 1];
20808N/A+ if (ts_realpath (file_path, real_file_path)) {
20808N/A+ char *cmd = g_strdup_printf ("/usr/lib/time-slider-version '%s' '%s'", dir,
20808N/A+ real_file_path);
20808N/A+ nautilus_launch_application_from_command (gtk_window_get_screen (GTK_WIDGET(callback_data)), cmd, FALSE, NULL);
20808N/A+ g_free (cmd);
20808N/A+ }
20808N/A+
20808N/A+ g_free (file_path);
20808N/A+ g_object_unref (file);
18556N/A+}
18556N/A+
18556N/A+static void
18556N/A action_trash_callback (GtkAction *action,
18556N/A gpointer callback_data)
18556N/A {
20808N/A@@ -7076,6 +7143,24 @@
18556N/A /* label, accelerator */ "RenameSelectAll", "<shift>F2",
18556N/A /* tooltip */ NULL,
20808N/A G_CALLBACK (action_rename_select_all_callback) },
18556N/A+ /* name, stock id */ { "Restore to", NULL,
18556N/A+ /* SUN_BRANDING */
18556N/A+ /* label, accelerator */ N_("Restore to Desktop"), NULL,
18556N/A+ /* SUN_BRANDING */
18556N/A+ /* tooltip */ N_("Move each selected item to the Desktop"),
18556N/A+ G_CALLBACK (action_restore_to_desktop_callback) },
18556N/A+ /* name, stock id */ { "View Snap", NULL,
18556N/A+ /* SUN_BRANDING */
18556N/A+ /* label, accelerator */ N_("View versions"), NULL,
18556N/A+ /* SUN_BRANDING */
18556N/A+ /* tooltip */ N_("View the versions of this file available in ZFS snapshots"),
18556N/A+ G_CALLBACK (action_show_snapshot_versions_callback) },
18556N/A+ /* name, stock id */ { "Snap Now", NULL,
18556N/A+ /* SUN_BRANDING */
18556N/A+ /* label, accelerator */ N_("Snapshot now"), NULL,
18556N/A+ /* SUN_BRANDING */
18556N/A+ /* tooltip */ N_("Take a ZFS snapshot of this directory now"),
18556N/A+ G_CALLBACK (action_snap_now) },
18556N/A /* name, stock id */ { "Trash", NULL,
20808N/A /* label, accelerator */ N_("Mo_ve to Trash"), "<control>Delete",
18556N/A /* tooltip */ N_("Move each selected item to the Trash"),
20808N/A@@ -8294,6 +8379,41 @@
18556N/A return FALSE;
18556N/A }
18556N/A
18556N/A+typedef struct {
18556N/A+ NautilusFile *file;
18556N/A+ GCancellable *cancel;
18556N/A+ GtkAction *action;
18556N/A+} HasSnapshotData;
18556N/A+
18556N/A+static void
18556N/A+has_snapshot_ready_callback (gpointer user_data)
18556N/A+{
18556N/A+ GValue name = {0,};
18556N/A+ HasSnapshotData *data = (HasSnapshotData*) user_data;
18556N/A+ HasSnapshotResult result = nautilus_file_has_snapshot_version (data->file);
18556N/A+
18556N/A+ switch (result)
18556N/A+ {
18556N/A+ case UNKNOWN_STATE:
18556N/A+ case NO:
18556N/A+ gtk_action_set_sensitive (data->action, FALSE);
18556N/A+ g_value_init (&name, G_TYPE_STRING);
18556N/A+ /* SUN_BRANDING */
18556N/A+ g_value_set_static_string (&name, _("No versions"));
18556N/A+ g_object_set_property (G_OBJECT (data->action), "label", &name);
18556N/A+ break;
18556N/A+ case YES:
18556N/A+ gtk_action_set_sensitive (data->action, TRUE);
18556N/A+ g_value_init (&name, G_TYPE_STRING);
18556N/A+ /* SUN_BRANDING */
18556N/A+ g_value_set_static_string (&name, _("Explore versions"));
18556N/A+ g_object_set_property (G_OBJECT (data->action), "label", &name);
18556N/A+ break;
18556N/A+ }
18556N/A+ g_free (data);
18556N/A+ }
18556N/A+
18556N/A+
18556N/A static void
20808N/A real_update_menus (NautilusView *view)
18556N/A {
20808N/A@@ -8609,6 +8729,74 @@
20808N/A NAUTILUS_ACTION_COPY);
18556N/A gtk_action_set_sensitive (action, can_copy_files);
18556N/A
18556N/A+ action = gtk_action_group_get_action (view->details->dir_action_group,
20808N/A+ NAUTILUS_ACTION_RESTORE_TO);
18556N/A+ gtk_action_set_visible (action, can_copy_files &&
18556N/A+ nautilus_directory_is_in_snapshot (view->details->model));
20808N/A+
18556N/A+ action = gtk_action_group_get_action (view->details->dir_action_group,
20808N/A+ NAUTILUS_ACTION_SNAP_NOW);
20808N/A+
18556N/A+ if (selection_count == 1 && nautilus_file_is_directory (NAUTILUS_FILE (selection->data)))
18556N/A+ {
18556N/A+ GFile *file = nautilus_file_get_location (NAUTILUS_FILE (selection->data));
18556N/A+ char *path = g_file_get_path (file);
18556N/A+ char *fs = ts_get_zfs_filesystem (path);
18556N/A+ if (fs)
18556N/A+ {
18556N/A+ gtk_action_set_visible (action, TRUE);
18556N/A+ g_free (fs);
18556N/A+ }
18556N/A+ g_free (path);
18556N/A+ g_object_unref (file);
18556N/A+ }
18556N/A+ else
18556N/A+ gtk_action_set_visible (action, FALSE);
20808N/A+
18556N/A+ action = gtk_action_group_get_action (view->details->dir_action_group,
20808N/A+ NAUTILUS_ACTION_HAS_SNAPSHOT);
18556N/A+ if (selection_count == 1)
18556N/A+ {
18556N/A+ GValue name = { 0, };
18556N/A+ int result = nautilus_file_has_snapshot_version (NAUTILUS_FILE (selection->data));
20808N/A+
18556N/A+ switch (result)
18556N/A+ {
18556N/A+ case NO:
18556N/A+ gtk_action_set_visible (action, FALSE);
18556N/A+ break;
18556N/A+ case YES:
18556N/A+ gtk_action_set_visible (action, TRUE);
18556N/A+ gtk_action_set_sensitive (action, TRUE);
18556N/A+ g_value_init (&name,G_TYPE_STRING);
18556N/A+ /* SUN_BRANDING */
18556N/A+ g_value_set_static_string (&name, _("Explore versions"));
18556N/A+ g_object_set_property (G_OBJECT (action), "label", &name);
18556N/A+ break;
18556N/A+ case UNKNOWN_STATE:
18556N/A+ gtk_action_set_visible (action, TRUE);
18556N/A+ gtk_action_set_sensitive (action, FALSE);
18556N/A+ g_value_init (&name,G_TYPE_STRING);
18556N/A+ /* SUN_BRANDING */
18556N/A+ g_value_set_static_string (&name, _("Scanning for versions"));
18556N/A+ g_object_set_property (G_OBJECT (action), "label", &name);
18556N/A+ break;
18556N/A+ }
18556N/A+ if (result == UNKNOWN_STATE)
18556N/A+ {
18556N/A+ HasSnapshotData *data = g_new0 (HasSnapshotData, 1);
18556N/A+ data->action = action;
18556N/A+ data->file = NAUTILUS_FILE (selection->data);
18556N/A+ data->cancel = g_cancellable_new ();
18556N/A+ nautilus_file_get_snapshot_version (NAUTILUS_FILE (selection->data),
18556N/A+ has_snapshot_ready_callback,
18556N/A+ data->cancel,
18556N/A+ data);
18556N/A+ }
18556N/A+ }
18556N/A+ else
18556N/A+ gtk_action_set_visible (action, FALSE);
18556N/A+
18556N/A real_update_paste_menu (view, selection, selection_count);
18556N/A
20808N/A disable_command_line = g_settings_get_boolean (gnome_lockdown_preferences, NAUTILUS_PREFERENCES_LOCKDOWN_COMMAND_LINE);
20808N/A--- nautilus-3.1.3/src/nautilus-directory-view-ui.xml.orig 2011-07-22 11:25:04.446118499 +0100
20808N/A+++ nautilus-3.1.3/src/nautilus-directory-view-ui.xml 2011-07-22 11:32:36.728336937 +0100
20808N/A@@ -66,6 +66,9 @@
18556N/A <menuitem name="Duplicate" action="Duplicate"/>
18556N/A <menuitem name="Create Link" action="Create Link"/>
18556N/A <menuitem name="Rename" action="Rename"/>
20808N/A+ <menuitem name="Restore to" action="Restore to"/>
20808N/A+ <menuitem name="Snapshot now" action="Snap Now"/>
20808N/A+ <menuitem name="Scanning...." action="View Snap"/>
18556N/A <menu action="CopyToMenu">
18556N/A <menuitem name="Copy to next pane" action="Copy to next pane"/>
18556N/A <menuitem name="Copy to Home" action="Copy to Home"/>
20808N/A@@ -161,6 +164,9 @@
18556N/A <menuitem name="Create Link" action="Create Link"/>
18556N/A <menuitem name="Rename" action="Rename"/>
20808N/A <menu action="CopyToMenu">
20808N/A+ <menuitem name="Restore to" action="Restore to"/>
20808N/A+ <menuitem name="Snapshot now" action="Snap Now"/>
20808N/A+ <menuitem name="Scanning...." action="View Snap"/>
18556N/A <menuitem name="Copy to next pane" action="Copy to next pane"/>
18556N/A <menuitem name="Copy to Home" action="Copy to Home"/>
18556N/A <menuitem name="Copy to Desktop" action="Copy to Desktop"/>
20808N/A@@ -173,6 +179,7 @@
18556N/A </placeholder>
20808N/A <separator name="Dangerous separator"/>
18556N/A <placeholder name="Dangerous File Actions">
18556N/A+ <menuitem name="Restore" action="Restore"/>
20808N/A <menuitem name="Trash" action="Trash"/>
20808N/A <menuitem name="Delete" action="Delete"/>
20808N/A <menuitem name="Restore From Trash" action="Restore From Trash"/>
18744N/Adiff -Nrup -x '*.orig' -x '*.rej' -x '*.*~' ../SUNWgnome-file-mgr-2.30.0-b4/nautilus-2.30.1/src/nautilus-actions.h nautilus-2.30.1/src/nautilus-actions.h
18744N/A--- ../SUNWgnome-file-mgr-2.30.0-b4/nautilus-2.30.1/src/nautilus-actions.h 2010-01-22 16:45:17.000000000 +0100
18744N/A+++ nautilus-2.30.1/src/nautilus-actions.h 2010-05-14 17:16:39.557199636 +0200
18556N/A@@ -28,6 +28,7 @@
18556N/A
18556N/A #define NAUTILUS_ACTION_STOP "Stop"
18556N/A #define NAUTILUS_ACTION_RELOAD "Reload"
18556N/A+#define NAUTILUS_ACTION_RESTORE "Restore"
18556N/A #define NAUTILUS_ACTION_BACK "Back"
18556N/A #define NAUTILUS_ACTION_UP "Up"
18556N/A #define NAUTILUS_ACTION_UP_ACCEL "UpAccel"
20808N/A--- nautilus-3.1.3/src/nautilus-file-management-properties.c.orig 2011-04-25 18:02:09.000000000 +0100
20808N/A+++ nautilus-3.1.3/src/nautilus-file-management-properties.c 2011-07-22 11:42:27.957358494 +0100
20808N/A@@ -62,6 +62,7 @@
20808N/A #define NAUTILUS_FILE_MANAGEMENT_PROPERTIES_OPEN_NEW_WINDOW_WIDGET "new_window_checkbutton"
20808N/A #define NAUTILUS_FILE_MANAGEMENT_PROPERTIES_SHOW_HIDDEN_WIDGET "hidden_files_checkbutton"
18556N/A #define NAUTILUS_FILE_MANAGEMENT_PROPERTIES_TREE_VIEW_FOLDERS_WIDGET "treeview_folders_checkbutton"
18556N/A+#define NAUTILUS_FILE_MANAGEMENT_PROPERTIES_ENABLE_TIME_SLIDER "time_slider_enabled_checkbutton"
18556N/A
18556N/A /* int enums */
18556N/A #define NAUTILUS_FILE_MANAGEMENT_PROPERTIES_THUMBNAIL_LIMIT_WIDGET "preview_image_size_combobox"
20808N/A@@ -749,6 +750,10 @@
20808N/A NAUTILUS_FILE_MANAGEMENT_PROPERTIES_TREE_VIEW_FOLDERS_WIDGET,
20808N/A NAUTILUS_PREFERENCES_TREE_SHOW_ONLY_DIRECTORIES);
18556N/A
20808N/A+ bind_builder_bool (builder, nautilus_tree_sidebar_preferences,
20808N/A+ NAUTILUS_FILE_MANAGEMENT_PROPERTIES_ENABLE_TIME_SLIDER,
20808N/A+ NAUTILUS_PREFERENCES_ENABLE_TIME_SLIDER);
20808N/A+
20808N/A bind_builder_enum (builder, nautilus_preferences,
20808N/A NAUTILUS_FILE_MANAGEMENT_PROPERTIES_DEFAULT_VIEW_WIDGET,
20808N/A NAUTILUS_PREFERENCES_DEFAULT_FOLDER_VIEWER,
20808N/A--- nautilus-3.1.3/src/nautilus-shell-ui.xml.orig 2011-07-22 13:50:25.148071442 +0100
20808N/A+++ nautilus-3.1.3/src/nautilus-shell-ui.xml 2011-07-22 13:57:43.720949058 +0100
20808N/A@@ -53,6 +53,7 @@
18556N/A <menu action="View">
18556N/A <menuitem name="Stop" action="Stop"/>
18556N/A <menuitem name="Reload" action="Reload"/>
18556N/A+ <menuitem name="Restore" action="Restore"/>
18556N/A <separator/>
20808N/A <placeholder name="Show Hide Placeholder">
20808N/A <menu action="Sidebar List">
20808N/A--- nautilus-3.1.3/src/nautilus-window-manage-views.c.orig 2011-07-25 08:16:41.926463390 +0100
20808N/A+++ nautilus-3.1.3/src/nautilus-window-manage-views.c 2011-07-25 08:49:32.039217259 +0100
20808N/A@@ -39,6 +39,7 @@
20808N/A #include "nautilus-trash-bar.h"
20808N/A #include "nautilus-view-factory.h"
18556N/A #include "nautilus-x-content-bar.h"
18556N/A+#include "nautilus-zfs-bar.h"
18556N/A #include <eel/eel-accessibility.h>
18556N/A #include <eel/eel-debug.h>
18556N/A #include <eel/eel-gdk-extensions.h>
20808N/A@@ -50,6 +51,7 @@
18556N/A #include <gtk/gtk.h>
18556N/A #include <gdk/gdkx.h>
18556N/A #include <glib/gi18n.h>
18556N/A+#include <stdlib.h>
18556N/A #include <libnautilus-extension/nautilus-location-widget-provider.h>
18556N/A #include <libnautilus-private/nautilus-file-attributes.h>
20808N/A #include <libnautilus-private/nautilus-file-utilities.h>
20808N/A@@ -693,7 +695,9 @@
18556N/A NautilusFile *file;
18556N/A gboolean force_reload;
18556N/A char *current_pos;
18556N/A+ GFile *old_file = NULL;
20808N/A GFile *from_folder, *parent;
20808N/A+ NautilusWindow *window;
18556N/A
18556N/A g_assert (slot != NULL);
18556N/A g_assert (location != NULL);
20808N/A@@ -722,12 +726,43 @@
18556N/A
18556N/A end_location_change (slot);
18556N/A
18556N/A+ old_file = nautilus_window_slot_get_location (slot);
20808N/A+ if (old_file) {
20808N/A+ directory = nautilus_directory_get (old_file);
20808N/A+ if (directory) {
20808N/A+ nautilus_directory_cancel_restore_info (directory);
20808N/A+ g_object_unref (directory);
20808N/A+ directory = NULL;
20808N/A+ }
20808N/A+ g_object_unref (old_file);
20808N/A+ old_file = NULL;
20808N/A+ }
18556N/A+
18556N/A nautilus_window_slot_set_allow_stop (slot, TRUE);
20808N/A nautilus_window_slot_set_status (slot, " ", NULL);
18556N/A
18556N/A g_assert (slot->pending_location == NULL);
18556N/A g_assert (slot->pending_selection == NULL);
20808N/A
18556N/A+ directory = nautilus_directory_get (location);
18556N/A+
20808N/A+ window = slot->pane->window;
20808N/A+ g_assert (NAUTILUS_IS_WINDOW (window));
18556N/A+ /* if snap and (ts is enabled and displayed )
20808N/A+ * check if the directory exist
18556N/A+ * if it doesn't move to the next available one */
20808N/A+ if (nautilus_directory_is_in_snapshot (directory) && is_time_slider_enabled ()) {
20808N/A+ if (gtk_widget_get_visible (window->details->zfs_bar)) {
20808N/A+ char *path = g_file_get_path (location);
20808N/A+ if (!g_file_test (path, G_FILE_TEST_IS_DIR)) {
20808N/A+ nautilus_zfs_bar_remove_and_skip_snap (NAUTILUS_ZFS_BAR (window->details->zfs_bar), path);
20808N/A+ g_free (path);
20808N/A+ return;
20808N/A+ }
20808N/A+ g_free (path);
20808N/A+ }
20808N/A+ }
20808N/A+
18556N/A slot->pending_location = g_object_ref (location);
18556N/A slot->location_change_type = type;
20808N/A slot->location_change_distance = distance;
20808N/A@@ -739,8 +774,6 @@
20808N/A slot->open_callback = callback;
20808N/A slot->open_callback_user_data = user_data;
18556N/A
18556N/A- directory = nautilus_directory_get (location);
20808N/A-
18556N/A /* The code to force a reload is here because if we do it
18556N/A * after determining an initial view (in the components), then
20808N/A * we end up fetching things twice.
20808N/A@@ -919,8 +952,17 @@
18556N/A /* If fallback, don't use view from metadata */
18556N/A if (slot->location_change_type != NAUTILUS_LOCATION_CHANGE_FALLBACK) {
18556N/A /* Look in metadata for view */
18556N/A- view_id = nautilus_file_get_metadata
18556N/A- (file, NAUTILUS_METADATA_KEY_DEFAULT_VIEW, NULL);
18556N/A+ if (nautilus_file_is_in_snapshot (file))
18556N/A+ {
20808N/A+ NautilusDirectory* root_dir = nautilus_zfs_bar_get_dir (NAUTILUS_ZFS_BAR (window->details->zfs_bar));
18556N/A+ if (root_dir)
18556N/A+ view_id = nautilus_file_get_metadata (nautilus_directory_get_corresponding_file (root_dir),
18556N/A+ NAUTILUS_METADATA_KEY_DEFAULT_VIEW, NULL);
18556N/A+ }
18556N/A+ if (view_id == NULL)
18556N/A+ view_id = nautilus_file_get_metadata
18556N/A+ (file, NAUTILUS_METADATA_KEY_DEFAULT_VIEW, NULL);
18556N/A+
18556N/A if (view_id != NULL &&
18556N/A !nautilus_view_factory_view_supports_uri (view_id,
18556N/A location,
20808N/A@@ -1495,6 +1537,30 @@
18556N/A /* Load menus from nautilus extensions for this location */
18556N/A nautilus_window_load_extension_menus (window);
18556N/A }
18556N/A+
18556N/A+ /* time slider pref can be just enabled so we need
18556N/A+ * to rescan for snapshots */
18556N/A+ directory = nautilus_directory_get (slot->location);
18556N/A+
20808N/A+ if (window)
18556N/A+ {
18556N/A+ if (slot->find_zfs_snapshots_cancellable != NULL)
18556N/A+ {
18556N/A+ g_cancellable_cancel (slot->find_zfs_snapshots_cancellable);
18556N/A+ slot->find_zfs_snapshots_cancellable = NULL;
18556N/A+ }
18556N/A+ slot->find_zfs_snapshots_cancellable = g_cancellable_new ();
20808N/A+ nautilus_zfs_bar_display (NAUTILUS_ZFS_BAR (window->details->zfs_bar),
18556N/A+ window,
18556N/A+ directory,
18556N/A+ slot->find_zfs_snapshots_cancellable);
18556N/A+
18556N/A+ }
18556N/A+ else
18556N/A+ nautilus_window_allow_restore (window, FALSE);
18556N/A+
18556N/A+ nautilus_directory_unref (directory);
18556N/A+
18556N/A
18556N/A if (location_really_changed) {
18556N/A nautilus_window_slot_remove_extra_location_widgets (slot);
20808N/A@@ -1833,11 +1899,19 @@
18556N/A nautilus_window_slot_stop_loading (NautilusWindowSlot *slot)
18556N/A {
18556N/A NautilusWindow *window;
18556N/A+ NautilusDirectory *directory;
18556N/A
18556N/A window = NAUTILUS_WINDOW (slot->pane->window);
18556N/A g_assert (NAUTILUS_IS_WINDOW (window));
18556N/A
18556N/A nautilus_view_stop_loading (slot->content_view);
18556N/A+
18556N/A+ if (slot->find_zfs_snapshots_cancellable)
18556N/A+ g_cancellable_cancel (slot->find_zfs_snapshots_cancellable);
18556N/A+
18556N/A+ directory = nautilus_directory_get (slot->location);
18556N/A+ nautilus_directory_cancel_restore_info (directory);
18556N/A+ nautilus_directory_unref (directory);
18556N/A
18556N/A if (slot->new_content_view != NULL) {
18556N/A window->details->temporarily_ignore_view_signals = TRUE;
20808N/A@@ -1898,6 +1972,8 @@
20808N/A nautilus_window_disconnect_content_view (slot->pane->window, slot->content_view);
18556N/A }
18556N/A
18556N/A+ nautilus_window_slot_stop_loading (slot);
18556N/A+
18556N/A free_location_change (slot);
18556N/A cancel_viewed_file_changed_callback (slot);
18556N/A }
20808N/A--- nautilus-3.1.3/src/nautilus-window-menus.c.orig 2011-07-25 10:08:19.966466156 +0100
20808N/A+++ nautilus-3.1.3/src/nautilus-window-menus.c 2011-07-25 10:08:46.797184803 +0100
20808N/A@@ -40,6 +40,7 @@
18556N/A #include "nautilus-window-private.h"
18556N/A #include "nautilus-desktop-window.h"
18556N/A #include "nautilus-search-bar.h"
18556N/A+#include "nautilus-zfs-bar.h"
18556N/A #include <gtk/gtk.h>
18556N/A #include <gio/gio.h>
18556N/A #include <glib/gi18n.h>
20808N/A@@ -257,6 +258,33 @@
18556N/A }
18556N/A
18556N/A static void
18556N/A+action_restore_callback (GtkToggleAction *action,
18556N/A+ gpointer user_data)
18556N/A+{
18556N/A+ NautilusWindowSlot *slot;
18556N/A+ GFile *directory;
18556N/A+ NautilusDirectory *n_dir;
20808N/A+ GtkWidget *bar = NAUTILUS_WINDOW (user_data)->details->zfs_bar;
18556N/A+
18556N/A+ slot = nautilus_window_get_active_slot (NAUTILUS_WINDOW (user_data));
18556N/A+ directory = nautilus_window_slot_get_location (slot);
18556N/A+ n_dir = nautilus_directory_get (directory);
18556N/A+
18556N/A+ if (gtk_toggle_action_get_active (action))
18556N/A+ {
18556N/A+ nautilus_zfs_bar_setup (NAUTILUS_ZFS_BAR (bar), n_dir, slot, action);
18556N/A+ gtk_widget_show (bar);
18556N/A+ }
18556N/A+ else
18556N/A+ {
18556N/A+ nautilus_zfs_bar_hide (NAUTILUS_ZFS_BAR (bar));
18556N/A+ nautilus_window_reload (NAUTILUS_WINDOW (user_data));
18556N/A+ }
18556N/A+ g_object_unref (n_dir);
18556N/A+ g_object_unref (directory);
18556N/A+}
18556N/A+
18556N/A+static void
18556N/A action_zoom_in_callback (GtkAction *action,
18556N/A gpointer user_data)
18556N/A {
20808N/A@@ -1113,6 +1141,12 @@
18556N/A };
18556N/A
18556N/A static const GtkToggleActionEntry main_toggle_entries[] = {
18556N/A+ /* name, stock id */ { "Restore", "stock_help",
18556N/A+ /* SUN_BRANDING */
18556N/A+ /* label, accelerator */ N_("R_estore"), "<control>E",
18556N/A+ /* SUN_BRANDING */
18556N/A+ /* tooltip */ N_("Browse the current location snapshot history"),
18556N/A+ G_CALLBACK (action_restore_callback) },
18556N/A /* name, stock id */ { "Show Hidden Files", NULL,
18556N/A /* label, accelerator */ N_("Show _Hidden Files"), "<control>H",
18556N/A /* tooltip */ N_("Toggle the display of hidden files in the current window"),
18744N/Adiff -Nrup -x '*.orig' -x '*.rej' -x '*.*~' ../SUNWgnome-file-mgr-2.30.0-b4/nautilus-2.30.1/src/nautilus-window-slot.c nautilus-2.30.1/src/nautilus-window-slot.c
18744N/A--- ../SUNWgnome-file-mgr-2.30.0-b4/nautilus-2.30.1/src/nautilus-window-slot.c 2009-12-16 17:53:51.000000000 +0100
18744N/A+++ nautilus-2.30.1/src/nautilus-window-slot.c 2010-05-14 17:16:39.566465378 +0200
18556N/A@@ -650,6 +650,13 @@ nautilus_window_slot_dispose (GObject *o
18556N/A slot->find_mount_cancellable = NULL;
18556N/A }
18556N/A
18556N/A+ if (slot->find_zfs_snapshots_cancellable)
18556N/A+ {
18556N/A+ g_cancellable_cancel (slot->find_zfs_snapshots_cancellable);
18556N/A+ g_object_unref (slot->find_zfs_snapshots_cancellable);
18556N/A+ slot->find_zfs_snapshots_cancellable = NULL;
18556N/A+ }
18556N/A+
18556N/A slot->pane = NULL;
18556N/A
18556N/A g_free (slot->title);
20808N/A--- nautilus-3.1.3/src/nautilus-window-slot.h.orig 2011-06-28 14:41:41.000000000 +0100
20808N/A+++ nautilus-3.1.3/src/nautilus-window-slot.h 2011-07-22 14:33:49.936636702 +0100
20808N/A@@ -113,6 +113,7 @@
20808N/A gpointer open_callback_user_data;
18556N/A
18556N/A GCancellable *find_mount_cancellable;
18556N/A+ GCancellable *find_zfs_snapshots_cancellable;
18556N/A
18556N/A gboolean visible;
20808N/A
20808N/A--- nautilus-3.1.3/src/nautilus-window.c.orig 2011-07-25 14:28:16.524301501 +0100
20808N/A+++ nautilus-3.1.3/src/nautilus-window.c 2011-07-25 14:28:29.183307666 +0100
20808N/A@@ -44,6 +44,7 @@
20808N/A #include "nautilus-window-manage-views.h"
20808N/A #include "nautilus-window-bookmarks.h"
20808N/A #include "nautilus-window-slot.h"
20808N/A+#include "nautilus-zfs-bar.h"
18556N/A
20808N/A #include <eel/eel-debug.h>
20808N/A #include <eel/eel-gtk-extensions.h>
20808N/A@@ -95,6 +96,7 @@
20808N/A static void mouse_back_button_changed (gpointer callback_data);
20808N/A static void mouse_forward_button_changed (gpointer callback_data);
20808N/A static void use_extra_mouse_buttons_changed (gpointer callback_data);
20808N/A+static void restore_pref_changed (gpointer callback_data);
20808N/A
20808N/A /* Sanity check: highest mouse button value I could find was 14. 5 is our
20808N/A * lower threshold (well-documented to be the one of the button events for the
20808N/A@@ -269,6 +271,18 @@
20808N/A gtk_action_set_sensitive (action, allow);
18556N/A }
18556N/A
20808N/A+void
20808N/A+nautilus_window_allow_restore (NautilusWindow *window, gboolean enable)
18556N/A+{
18556N/A+ GtkAction *action;
20808N/A+
20808N/A+ g_assert (NAUTILUS_IS_WINDOW (window));
18556N/A+
18556N/A+ action = gtk_action_group_get_action (window->details->main_action_group,
18556N/A+ NAUTILUS_ACTION_RESTORE);
18556N/A+ gtk_action_set_sensitive (action, enable);
18556N/A+}
18556N/A+
18556N/A static void
18556N/A update_cursor (NautilusWindow *window)
18556N/A {
20808N/A@@ -277,7 +291,7 @@
18556N/A
18556N/A slot = window->details->active_pane->active_slot;
18556N/A
18556N/A- if (slot->allow_stop) {
18556N/A+ if (slot && slot->allow_stop) {
18556N/A cursor = gdk_cursor_new (GDK_WATCH);
20808N/A gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (window)), cursor);
20808N/A g_object_unref (cursor);
20808N/A@@ -303,8 +317,14 @@
18556N/A if (slot != window->details->active_pane->active_slot ||
18556N/A allow_stop != slot->allow_stop) {
18556N/A if (slot == window->details->active_pane->active_slot) {
18556N/A- gtk_action_set_sensitive (action, slot->allow_stop);
18556N/A- }
20808N/A+ if (!slot->allow_stop && slot->find_zfs_snapshots_cancellable != NULL) {
20808N/A+ /* if slot want to stop and snap find is finished/cancel then disable */
20808N/A+ if (g_cancellable_is_cancelled (slot->find_zfs_snapshots_cancellable))
20808N/A+ gtk_action_set_sensitive (action, slot->allow_stop);
20808N/A+ } else {
20808N/A+ gtk_action_set_sensitive (action, slot->allow_stop);
20808N/A+ }
20808N/A+ }
18556N/A
18556N/A if (gtk_widget_get_realized (GTK_WIDGET (window))) {
18556N/A update_cursor (window);
20808N/A@@ -575,7 +595,7 @@
20808N/A
20808N/A G_OBJECT_CLASS (nautilus_window_parent_class)->constructed (self);
20808N/A
20808N/A- table = gtk_table_new (1, 6, FALSE);
20808N/A+ table = gtk_table_new (1, 7, FALSE);
20808N/A window->details->table = table;
20808N/A gtk_widget_show (table);
20808N/A gtk_container_add (GTK_CONTAINER (window), table);
20808N/A@@ -592,6 +612,7 @@
20808N/A menu = gtk_ui_manager_get_widget (window->details->ui_manager, "/MenuBar");
20808N/A window->details->menubar = menu;
20808N/A gtk_widget_show (menu);
20808N/A+
20808N/A gtk_table_attach (GTK_TABLE (table),
20808N/A menu,
20808N/A /* X direction */ /* Y direction */
20808N/A@@ -607,7 +628,7 @@
20808N/A gtk_table_attach (GTK_TABLE (window->details->table),
20808N/A window->details->content_paned,
20808N/A /* X direction */ /* Y direction */
20808N/A- 0, 1, 3, 4,
20808N/A+ 0, 1, 4, 5,
20808N/A GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_EXPAND | GTK_FILL | GTK_SHRINK,
20808N/A 0, 0);
20808N/A gtk_widget_show (window->details->content_paned);
20808N/A@@ -632,6 +653,15 @@
20808N/A nautilus_window_disable_chrome_mapping, NULL,
20808N/A window, NULL);
20808N/A
20808N/A+ /* add custom icon */
20808N/A+
20808N/A+ nautilus_window_set_restore_icon (window, RESTORE_SEARCH);
20808N/A+ /* add preference callback */
20808N/A+ g_signal_connect_swapped (nautilus_preferences,
20808N/A+ "changed::" NAUTILUS_PREFERENCES_ENABLE_TIME_SLIDER,
20808N/A+ G_CALLBACK(restore_pref_changed),
20808N/A+ (gpointer) window);
20808N/A+
20808N/A pane = nautilus_window_pane_new (window);
20808N/A window->details->panes = g_list_prepend (window->details->panes, pane);
20808N/A
20808N/A@@ -656,6 +686,15 @@
20808N/A slot = nautilus_window_open_slot (window->details->active_pane, 0);
20808N/A nautilus_window_set_active_slot (window, slot);
20808N/A nautilus_window_menus_lockdown_notify_add (window);
20808N/A+
20808N/A+ window->details->zfs_bar = nautilus_zfs_bar_new ();
20808N/A+
20808N/A+ gtk_table_attach (GTK_TABLE (NAUTILUS_WINDOW (window)->details->table),
20808N/A+ window->details->zfs_bar,
20808N/A+ /* X direction */ /* Y direction */
20808N/A+ 0, 1, 3, 4,
20808N/A+ GTK_EXPAND | GTK_FILL | GTK_SHRINK, 0,
20808N/A+ 0, 0);
20808N/A }
20808N/A
20808N/A static void
20808N/A@@ -1913,7 +1952,7 @@
20808N/A return slot;
20808N/A }
20808N/A
20808N/A-static void
20808N/A+void
20808N/A nautilus_window_reload (NautilusWindow *window)
20808N/A {
20808N/A NautilusWindowSlot *active_slot;
20808N/A@@ -1997,6 +2036,13 @@
20808N/A }
20808N/A
20808N/A static void
20808N/A+restore_pref_changed (gpointer callback_data)
20808N/A+{
20808N/A+ g_assert (NAUTILUS_IS_WINDOW (callback_data));
20808N/A+ nautilus_window_reload (NAUTILUS_WINDOW(callback_data));
20808N/A+}
20808N/A+
20808N/A+static void
20808N/A mouse_back_button_changed (gpointer callback_data)
20808N/A {
20808N/A int new_back_button;
20808N/A@@ -2030,7 +2076,6 @@
20808N/A mouse_extra_buttons = g_settings_get_boolean (nautilus_preferences, NAUTILUS_PREFERENCES_MOUSE_USE_EXTRA_BUTTONS);
20808N/A }
20808N/A
18556N/A-
20808N/A /*
20808N/A * Main API
20808N/A */
20808N/A@@ -2249,3 +2294,47 @@
20808N/A {
20808N/A return g_list_length (NAUTILUS_WINDOW (window)->details->panes) > 1;
20808N/A }
20808N/A+
20808N/A+void nautilus_window_set_restore_icon (NautilusWindow* window,
20808N/A+ NautilusRestoreIconType type)
20808N/A+{
20808N/A+ static gboolean init = 0;
20808N/A+ static GdkPixbuf *normal = NULL;
20808N/A+ static GdkPixbuf *search = NULL;
20808N/A+ static GdkPixbuf *no = NULL;
20808N/A+ GdkPixbuf *pb = NULL;
20808N/A+ GtkWidget *image = NULL;
20808N/A+ GtkAction* action = gtk_ui_manager_get_action (nautilus_window_get_ui_manager (NAUTILUS_WINDOW (window)), "/Toolbar/Restore");
20808N/A+
20808N/A+ if (!init) {
20808N/A+ char *path = nautilus_pixmap_file ("restore.png");
20808N/A+ normal = gdk_pixbuf_new_from_file (path, NULL);
20808N/A+ g_free (path);
20808N/A+ path = nautilus_pixmap_file ("restore-search.png");
20808N/A+ search = gdk_pixbuf_new_from_file (path, NULL);
20808N/A+ g_free (path);
20808N/A+ init = TRUE;
20808N/A+ }
20808N/A+
20808N/A+ switch (type) {
20808N/A+ case RESTORE_NORMAL :
20808N/A+ pb = normal;
20808N/A+ break;
20808N/A+ case RESTORE_SEARCH:
20808N/A+ pb = search;
20808N/A+ break;
20808N/A+ case RESTORE_NO:
20808N/A+ pb = no;
20808N/A+ break;
20808N/A+ }
20808N/A+
20808N/A+ image = gtk_image_new_from_pixbuf (pb);
20808N/A+ g_object_ref (image);
20808N/A+ gtk_widget_show (image);
20808N/A+ GSList *tmp = gtk_action_get_proxies (action);
20808N/A+ for (tmp; tmp ; tmp = tmp->next) {
20808N/A+ GtkWidget *proxy = (GtkWidget *)tmp->data;
20808N/A+ if (GTK_IS_TOOL_BUTTON (proxy))
20808N/A+ gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (proxy), image);
20808N/A+ }
20808N/A+}
20808N/A--- nautilus-3.1.3/src/nautilus-window-private.h.orig 2011-07-25 10:54:12.777383655 +0100
20808N/A+++ nautilus-3.1.3/src/nautilus-window-private.h 2011-07-25 11:06:58.227055497 +0100
20808N/A@@ -94,6 +94,8 @@
20808N/A GtkWidget *sidebar;
20808N/A gchar *sidebar_id;
20808N/A
20808N/A+ GtkWidget *zfs_bar;
20808N/A+
20808N/A /* Toolbar */
20808N/A GtkWidget *toolbar;
20808N/A
20808N/A@@ -111,6 +113,12 @@
20808N/A guint sidebar_width_handler_id;
20808N/A };
20808N/A
20808N/A+typedef enum {
20808N/A+ RESTORE_NORMAL,
20808N/A+ RESTORE_SEARCH,
20808N/A+ RESTORE_NO
20808N/A+} NautilusRestoreIconType;
20808N/A+
20808N/A /* window geometry */
20808N/A /* Min values are very small, and a Nautilus window at this tiny size is *almost*
20808N/A * completely unusable. However, if all the extra bits (sidebar, location bar, etc)
20808N/A@@ -176,6 +184,9 @@
20808N/A void nautilus_window_update_show_hide_menu_items (NautilusWindow *window);
20808N/A void nautilus_window_menus_lockdown_notify_add (NautilusWindow *window);
20808N/A void nautilus_window_menus_lockdown_notify_remove (NautilusWindow *window);
20808N/A+gboolean nautilus_window_zfs_bar_showing (NautilusWindow *window);
20808N/A+void nautilus_window_set_restore_icon (NautilusWindow *window,
20808N/A+ NautilusRestoreIconType type);
20808N/A
20808N/A /* window toolbar */
20808N/A void nautilus_window_close_pane (NautilusWindowPane *pane);
20808N/A--- nautilus-3.1.3/src/nautilus-window.h.orig 2011-06-28 14:41:41.000000000 +0100
20808N/A+++ nautilus-3.1.3/src/nautilus-window.h 2011-07-22 14:56:24.534238012 +0100
20808N/A@@ -152,6 +152,8 @@
20808N/A gboolean allow);
20808N/A void nautilus_window_allow_forward (NautilusWindow *window,
20808N/A gboolean allow);
20808N/A+void nautilus_window_allow_restore (NautilusWindow *window,
20808N/A+ gboolean allow);
20808N/A void nautilus_window_clear_back_list (NautilusWindow *window);
20808N/A void nautilus_window_clear_forward_list (NautilusWindow *window);
20808N/A void nautilus_forget_history (void);
20808N/A--- /dev/null 2011-07-25 11:57:58.000000000 +0100
20808N/A+++ nautilus-3.1.3/src/nautilus-zfs-bar.c 2011-07-25 11:55:15.960654076 +0100
20808N/A@@ -0,0 +1,841 @@
18556N/A+/*
18556N/A+ * Copyright (C) 2008 Sun Microsystems (Erwann Chenede)
18556N/A+ *
18556N/A+ */
18556N/A+
18556N/A+#include "config.h"
18556N/A+#include <strings.h>
18556N/A+#include <glib/gi18n-lib.h>
18556N/A+#include <gtk/gtk.h>
18556N/A+
18556N/A+#include "nautilus-zfs-bar.h"
18556N/A+#include "nautilus-window.h"
18556N/A+#include "nautilus-window-private.h"
18556N/A+#include "nautilus-file-utilities.h"
18556N/A+#include "timescale.h"
18556N/A+#include <libnautilus-private/nautilus-zfs.h>
18556N/A+#include <libnautilus-private/nautilus-file.h>
18556N/A+#include <libnautilus-private/nautilus-global-preferences.h>
18556N/A+#include "nautilus-window-slot.h"
18556N/A+
18556N/A+#define NAUTILUS_ZFS_BAR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NAUTILUS_TYPE_ZFS_BAR, NautilusZfsBarPrivate))
18556N/A+
18556N/A+struct NautilusZfsBarPrivate
18556N/A+{
18556N/A+ NautilusDirectory *dir;
18556N/A+ GtkWidget *scale;
18556N/A+ GtkWidget *delete_button;
18556N/A+ GdkColor in_snapshot;
18556N/A+ GtkToggleAction *action;
18556N/A+ NautilusWindowSlot *slot;
18556N/A+ int num_range_items;
18556N/A+ gboolean is_setup;
18556N/A+ gboolean set_only;
18556N/A+ char *current_path;
18556N/A+ ZfsSnapDirMonitor *zfs_dir_monitor_data;
18556N/A+ gboolean in_snapshot_dir;
18556N/A+ GtkWidget *camera_image;
18556N/A+ GtkWidget *delete_image;
18556N/A+ gboolean explicit_user_hide;
18556N/A+};
18556N/A+
18556N/A+G_DEFINE_TYPE (NautilusZfsBar, nautilus_zfs_bar, GTK_TYPE_EVENT_BOX)
18556N/A+
18556N/A+static void
18556N/A+close_clicked_callback (GtkWidget *widget,
18556N/A+ NautilusZfsBar *bar);
18556N/A+static void
18556N/A+slider_moved_callback (TimeScale *ts,
18556N/A+ NautilusZfsBar *bar);
19017N/A+static void
19017N/A+update_delete_or_snap_button (NautilusZfsBar *bar,
19017N/A+ gboolean in_snap);
18556N/A+
18556N/A+static void
18556N/A+nautilus_zfs_bar_class_init (NautilusZfsBarClass *klass)
18556N/A+{
18556N/A+ GObjectClass *object_class;
18556N/A+
18556N/A+ object_class = G_OBJECT_CLASS (klass);
18556N/A+
18556N/A+ g_type_class_add_private (klass, sizeof (NautilusZfsBarPrivate));
18556N/A+}
18556N/A+
18556N/A+static void
18556N/A+set_scale_range (NautilusZfsBar *bar, gboolean set_initial_position)
18556N/A+{
18556N/A+ int i;
18556N/A+ GList *tmp;
18556N/A+
18556N/A+ if (bar->priv->dir)
18556N/A+ {
18556N/A+ i = nautilus_directory_get_num_snapshots (bar->priv->dir);
18556N/A+
18556N/A+ if (i==0)
18556N/A+ return;
18556N/A+
18556N/A+ bar->priv->num_range_items = i;
18556N/A+
18556N/A+ tmp = nautilus_directory_get_snapshots (bar->priv->dir);
18556N/A+
18556N/A+ if (set_initial_position)
18556N/A+ timescale_set_snapshots (TIMESCALE (bar->priv->scale), tmp, -1);
18556N/A+ else
18556N/A+ timescale_set_snapshots (TIMESCALE (bar->priv->scale), tmp, bar->priv->num_range_items);
18556N/A+ }
18556N/A+}
18556N/A+
18556N/A+static void
18556N/A+update_range (NautilusZfsBar *bar)
18556N/A+{
18556N/A+ if (nautilus_directory_get_snapshots (bar->priv->dir))
18556N/A+ {
18556N/A+ set_scale_range (bar, FALSE);
18556N/A+ slider_moved_callback (TIMESCALE (bar->priv->scale), bar);
18556N/A+ }
18556N/A+ else
18556N/A+ close_clicked_callback (NULL, bar);
18556N/A+}
18556N/A+
18556N/A+static int match_func (ZfsDataSet *set, char *dir)
18556N/A+{
18556N/A+ /* remove trailing slash from dir */
18556N/A+ char mountp[PATH_MAX+1];
18556N/A+ int length = strlen (set->mountpoint);
18556N/A+
18556N/A+ if (set->mountpoint[length-1] == '/')
18556N/A+ {
18556N/A+ memcpy (mountp, set->mountpoint, length - 1);
18556N/A+ mountp[length-1] = NULL;
18556N/A+ return strcmp (mountp, dir);
18556N/A+ }
18556N/A+ else
18556N/A+ return strcmp (set->mountpoint, dir);
18556N/A+}
18556N/A+
18556N/A+void
18556N/A+nautilus_zfs_bar_remove_and_skip_snap (NautilusZfsBar *bar, char *path)
18556N/A+{
18556N/A+ GList* match = NULL;
18556N/A+ GList* snap_list = NULL;
18556N/A+ ZfsDataSet *snap;
18556N/A+
18556N/A+ snap_list = nautilus_directory_get_snapshots (bar->priv->dir);
18556N/A+ match = g_list_find_custom (snap_list, path, (GCompareFunc)match_func);
18556N/A+
18556N/A+ if (match)
18556N/A+ {
18556N/A+ snap = (ZfsDataSet*) match->data;
18556N/A+ nautilus_directory_remove_snapshot (bar->priv->dir, snap);
18556N/A+ update_range (bar);
18556N/A+ }
18556N/A+}
18556N/A+
18556N/A+static void
19017N/A+update_delete_or_snap_button (NautilusZfsBar *bar, gboolean in_snap)
19017N/A+{
19017N/A+ if (in_snap)
19017N/A+ {
19017N/A+ if (!bar->priv->in_snapshot_dir)
19017N/A+ { /*in main dir to snap */
19017N/A+ bar->priv->in_snapshot_dir = TRUE;
19017N/A+ g_object_ref (bar->priv->camera_image);
19017N/A+ gtk_button_set_image (GTK_BUTTON (bar->priv->delete_button),
19017N/A+ bar->priv->delete_image);
19017N/A+ gtk_widget_set_tooltip_text (bar->priv->delete_button,
19017N/A+ /* SUN_BRANDING */
19017N/A+ _("Delete this snapshot"));
19017N/A+ }
19017N/A+ }
19017N/A+ else
19017N/A+ {
19017N/A+ if (bar->priv->in_snapshot_dir)
19017N/A+ { /* in snap to main dir */
19017N/A+ bar->priv->in_snapshot_dir = FALSE;
19017N/A+ g_object_ref (bar->priv->delete_image);
19017N/A+ gtk_button_set_image (GTK_BUTTON (bar->priv->delete_button),
19017N/A+ bar->priv->camera_image);
19017N/A+ gtk_widget_set_tooltip_text (bar->priv->delete_button,
19017N/A+ /* SUN_BRANDING */
19017N/A+ _("Take a zfs snapshot of this directory now"));
19017N/A+ }
19017N/A+ }
19017N/A+}
19017N/A+
19017N/A+static void
18556N/A+slider_moved_callback (TimeScale *ts,
18556N/A+ NautilusZfsBar *bar)
18556N/A+{
18556N/A+ GList *tmp;
18556N/A+ ZfsDataSet *snap;
18556N/A+ GFile *snap_file;
18556N/A+ int pos = timescale_get_position (ts);
18556N/A+
18556N/A+ if (pos < bar->priv->num_range_items)
18556N/A+ {
18556N/A+ tmp = nautilus_directory_get_snapshots (bar->priv->dir);
18556N/A+
18556N/A+ snap = g_list_nth_data (tmp, pos);
18556N/A+
18556N/A+ snap_file = g_file_new_for_path (snap->mountpoint);
18556N/A+ }
18556N/A+ else
18556N/A+ {
18556N/A+ snap_file = nautilus_directory_get_location (bar->priv->dir);
18556N/A+ pos = bar->priv->num_range_items;
18556N/A+ }
18556N/A+
18556N/A+ if (!bar->priv->set_only)
18556N/A+ {
18556N/A+ gboolean in_snap = FALSE;
18556N/A+ char *path = g_file_get_path (snap_file);
18556N/A+
18556N/A+ if (g_file_test (path, G_FILE_TEST_IS_DIR))
18556N/A+ {
18556N/A+ nautilus_window_slot_go_to (bar->priv->slot,
18556N/A+ snap_file,
18556N/A+ FALSE);
18556N/A+ if (bar->priv->current_path)
18556N/A+ g_free (bar->priv->current_path);
18556N/A+ bar->priv->current_path = path;
18556N/A+ }
18556N/A+ else
18556N/A+ { /* the snapshot diappeared try the next one */
18556N/A+ g_free (path);
18556N/A+ g_object_unref (snap_file);
18556N/A+ /* remove snap from list */
18556N/A+ nautilus_directory_remove_snapshot (bar->priv->dir, snap);
18556N/A+ update_range (bar);
18556N/A+ return;
18556N/A+ }
18556N/A+
18556N/A+ in_snap = ts_is_in_snapshot (path);
19017N/A+ update_delete_or_snap_button (bar, ts_is_in_snapshot (path));
19017N/A+
19017N/A+ }
18556N/A+
18556N/A+g_object_unref (snap_file);
18556N/A+
18556N/A+}
18556N/A+
18556N/A+
18556N/A+static void
18556N/A+delete_clicked_callback (GtkWidget *widget,
18556N/A+ NautilusZfsBar *bar)
18556N/A+{
18556N/A+ GList *tmp;
18556N/A+ ZfsDataSet *snap;
18556N/A+ GFile *snap_file;
18556N/A+ char *path;
18556N/A+ char *full_command;
18744N/A+ int pos = timescale_get_position (TIMESCALE (bar->priv->scale));
18556N/A+
18556N/A+ if (bar->priv->in_snapshot_dir)
18556N/A+ {
18556N/A+ tmp = nautilus_directory_get_snapshots (bar->priv->dir);
18556N/A+ snap = g_list_nth_data (tmp, pos);
18556N/A+ snap_file = g_file_new_for_path (snap->mountpoint);
18556N/A+ path = g_file_get_path (snap_file);
18556N/A+
18556N/A+ g_object_unref (snap_file);
18744N/A+ if (snap->type)
18744N/A+ {
18744N/A+ /*printf ("path %s snapshot to delete %s\n", path, snap->name);*/
18744N/A+ full_command = g_strdup_printf ("/usr/lib/time-slider-delete '%s'", snap->name);
18744N/A+ }
18744N/A+ else
18744N/A+ {
18744N/A+ /*printf ("path %s backup to delete %s\n", path, snap->name);*/
18744N/A+ full_command = g_strdup_printf ("/usr/lib/time-slider-delete '%s'", path);
18744N/A+ }
18744N/A+
20808N/A+ nautilus_launch_application_from_command (gtk_widget_get_screen (widget),
18556N/A+ full_command, NULL);
18556N/A+ }
18556N/A+ else
18556N/A+ {
18556N/A+ path = g_file_get_path (nautilus_directory_get_location (bar->priv->dir));
18556N/A+ char *fs = ts_get_zfs_filesystem (path);
18556N/A+ /* printf ("take a snapshot of zfs fs %s for dir %s\n", fs, path); */
18556N/A+ full_command = g_strdup_printf ("/usr/lib/time-slider-snapshot '%s' '%s'", path, fs);
20808N/A+ nautilus_launch_application_from_command (gtk_widget_get_screen (widget),
18556N/A+ full_command, NULL);
18556N/A+ g_free (fs);
18556N/A+ }
18556N/A+
18556N/A+ g_free (full_command);
18556N/A+ g_free (path);
18556N/A+}
18556N/A+
18556N/A+static void
18556N/A+close_clicked_callback (GtkWidget *widget,
18556N/A+ NautilusZfsBar *bar)
18556N/A+{
18556N/A+ GFile *snap_file = nautilus_directory_get_location (bar->priv->dir);
18556N/A+
18556N/A+ nautilus_window_slot_go_to (bar->priv->slot,
18556N/A+ snap_file,
18556N/A+ FALSE);
18556N/A+ g_object_unref (snap_file);
18556N/A+
18556N/A+ bar->priv->is_setup = FALSE;
18556N/A+
18556N/A+ gtk_widget_hide (GTK_WIDGET (bar));
18556N/A+ gtk_toggle_action_set_active (bar->priv->action, FALSE);
18556N/A+
18556N/A+}
18556N/A+
18556N/A+static void
18556N/A+nautilus_zfs_bar_init (NautilusZfsBar *bar)
18556N/A+{
18556N/A+ GtkWidget *hbox, *toolbar, *close, *delete, *image, *button_vbox;
18556N/A+ GtkToolItem *item;
18556N/A+ char *path;
18556N/A+
18556N/A+ bar->priv = NAUTILUS_ZFS_BAR_GET_PRIVATE (bar);
18556N/A+
18556N/A+ bar->priv->dir = NULL;
18556N/A+ bar->priv->num_range_items = 0;
18556N/A+ bar->priv->action = NULL;
18556N/A+ bar->priv->slot = NULL;
18556N/A+ bar->priv->is_setup = FALSE;
18556N/A+ bar->priv->set_only = FALSE;
18556N/A+
18556N/A+ /* GUI init */
18556N/A+
18556N/A+ toolbar = gtk_toolbar_new ();
18556N/A+ gtk_widget_show (toolbar);
18556N/A+
18556N/A+ item = gtk_tool_item_new ();
18556N/A+ gtk_widget_show (GTK_WIDGET (item));
18556N/A+ gtk_tool_item_set_expand (item, TRUE);
18556N/A+
18556N/A+ hbox = gtk_hbox_new (FALSE, 2);
18556N/A+ gtk_widget_show (GTK_WIDGET (hbox));
18556N/A+
18556N/A+ gtk_container_add (GTK_CONTAINER (item),hbox);
18556N/A+
18556N/A+ gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);
18556N/A+ gtk_container_add (GTK_CONTAINER (bar),toolbar);
18556N/A+ gtk_container_set_border_width (GTK_CONTAINER (bar), 0);
18556N/A+
18556N/A+ /* buttons */
18556N/A+
18556N/A+ button_vbox = gtk_vbox_new (FALSE, 0);
18556N/A+ gtk_widget_show (button_vbox);
18556N/A+
18556N/A+ close = gtk_button_new ();
18556N/A+ gtk_button_set_relief (GTK_BUTTON (close), GTK_RELIEF_NONE);
18556N/A+ gtk_widget_set_tooltip_text (close,
18556N/A+ /* SUN_BRANDING */
18556N/A+ _("Close Time Slider and return to original directory"));
18556N/A+ gtk_widget_show (close);
18556N/A+
18556N/A+ g_signal_connect (close,
18556N/A+ "clicked",
18556N/A+ G_CALLBACK (close_clicked_callback),
18556N/A+ bar);
18556N/A+
18556N/A+ image = gtk_image_new_from_stock (GTK_STOCK_CLOSE,
18556N/A+ GTK_ICON_SIZE_MENU);
18556N/A+ gtk_widget_show (image);
18556N/A+
18556N/A+ gtk_container_add (GTK_CONTAINER (close), image);
18556N/A+
18556N/A+ gtk_box_pack_start (GTK_BOX (button_vbox), close, FALSE, FALSE, 0);
18556N/A+
18556N/A+ delete = gtk_button_new ();
18556N/A+ gtk_button_set_relief (GTK_BUTTON (delete), GTK_RELIEF_NONE);
18556N/A+ gtk_widget_set_tooltip_text (delete,
18556N/A+ /* SUN_BRANDING */
18556N/A+ _("Take a zfs snapshot of this directory now"));
18556N/A+ gtk_widget_show (delete);
18556N/A+
18556N/A+ g_signal_connect (delete,
18556N/A+ "clicked",
18556N/A+ G_CALLBACK (delete_clicked_callback),
18556N/A+ bar);
18556N/A+
18556N/A+ {
18556N/A+ GtkIconTheme *it = gtk_icon_theme_get_default ();
18556N/A+ GdkPixbuf * pb = gtk_icon_theme_load_icon (it,
18556N/A+ "user-trash-full.png",
18556N/A+ 16,
18556N/A+ GTK_ICON_LOOKUP_GENERIC_FALLBACK,
18556N/A+ NULL);
18556N/A+ bar->priv->delete_image = gtk_image_new_from_pixbuf (pb);
18556N/A+ g_object_unref (pb);
18556N/A+ }
18556N/A+
18556N/A+ path = nautilus_pixmap_file ("camera.png");
18556N/A+ bar->priv->camera_image = gtk_image_new_from_file (path);
18556N/A+ g_free (path);
18556N/A+
18556N/A+ gtk_widget_show (bar->priv->delete_image);
18556N/A+ gtk_widget_show (bar->priv->camera_image);
18556N/A+
18556N/A+ gtk_container_add (GTK_CONTAINER (delete), bar->priv->camera_image);
18556N/A+
18556N/A+ gtk_box_pack_end (GTK_BOX (button_vbox), delete, FALSE, FALSE, 0);
18556N/A+ gtk_box_pack_end (GTK_BOX (hbox), button_vbox, FALSE, FALSE, 0);
18556N/A+
18556N/A+ bar->priv->delete_button = delete;
18556N/A+
18556N/A+ bar->priv->scale = timescale_new();
18556N/A+
18556N/A+ g_signal_connect (bar->priv->scale,
18556N/A+ "value-changed",
18556N/A+ G_CALLBACK (slider_moved_callback),
18556N/A+ bar);
18556N/A+
18556N/A+ gtk_widget_show (bar->priv->scale);
18556N/A+
18556N/A+ gtk_box_pack_start (GTK_BOX (hbox), bar->priv->scale, TRUE, TRUE, 0);
18556N/A+
18556N/A+}
18556N/A+
18556N/A+NautilusDirectory *
18556N/A+nautilus_zfs_bar_get_dir (NautilusZfsBar* bar)
18556N/A+{
18556N/A+ g_return_val_if_fail (NAUTILUS_IS_ZFS_BAR (bar), NULL);
18556N/A+ return bar->priv->dir;
18556N/A+}
18556N/A+
18556N/A+static void snapshot_data_ready (NautilusDirectory *dir,
18556N/A+ GCancellable *cancellable,
18556N/A+ gpointer callback_data)
18556N/A+{
18556N/A+ NautilusWindowSlot *slot;
18556N/A+ GFile *location;
18556N/A+ GFile *dir_location;
18556N/A+ NautilusWindow *window = (NautilusWindow*)callback_data;
18556N/A+
18556N/A+ g_return_if_fail (NAUTILUS_IS_WINDOW (window));
18556N/A+
18556N/A+ slot = nautilus_window_get_active_slot (window);
18556N/A+ location = nautilus_window_slot_get_location (slot);
18556N/A+ dir_location = nautilus_directory_get_location (dir);
18556N/A+
18556N/A+ if (g_cancellable_is_cancelled (cancellable) && g_file_equal (location, dir_location))
18556N/A+ {
20808N/A+ nautilus_window_set_restore_icon (window, RESTORE_NO);
18556N/A+ }
18556N/A+ else if (g_file_equal (location, dir_location))
18556N/A+ {
18556N/A+ char *path = g_file_get_path (dir_location);
18556N/A+ g_cancellable_cancel (cancellable);
18556N/A+ nautilus_window_slot_set_allow_stop (slot, FALSE);
20808N/A+ nautilus_window_set_restore_icon (window,
20808N/A+ nautilus_directory_has_snapshots (dir) ? RESTORE_NORMAL : RESTORE_NO);
18556N/A+ if (nautilus_directory_has_snapshots (dir))
18556N/A+ nautilus_window_allow_restore (window, TRUE);
18556N/A+ else
18556N/A+ nautilus_window_allow_restore (window, FALSE);
18556N/A+ g_free (path);
18556N/A+ }
18556N/A+ g_object_unref (location);
18556N/A+ g_object_unref (dir_location);
18556N/A+}
18556N/A+
18556N/A+
18556N/A+void nautilus_zfs_bar_cancel_tasks (NautilusWindow *window)
18556N/A+{
18556N/A+ if (NAUTILUS_IS_WINDOW (window))
18556N/A+ {
18744N/A+ if (NAUTILUS_IS_WINDOW_SLOT (window->details->active_pane->active_slot))
18556N/A+ {
18556N/A+ NautilusDirectory *directory = NULL;
18744N/A+ g_cancellable_cancel (window->details->active_pane->active_slot->find_zfs_snapshots_cancellable);
18744N/A+ g_object_unref (window->details->active_pane->active_slot->find_zfs_snapshots_cancellable);
18744N/A+ window->details->active_pane->active_slot->find_zfs_snapshots_cancellable = NULL;
18744N/A+ directory = nautilus_directory_get (window->details->active_pane->active_slot->location);
18556N/A+ if (directory)
18556N/A+ {
18556N/A+ nautilus_directory_cancel_restore_info (directory);
18556N/A+ nautilus_directory_unref (directory);
18556N/A+ }
18556N/A+ }
20808N/A+ if (NAUTILUS_WINDOW (window))
18556N/A+ {
20808N/A+ NautilusZfsBar *bar = NAUTILUS_ZFS_BAR (window->details->zfs_bar);
18556N/A+ monitor_zfs_snap_directory_cancel (bar->priv->zfs_dir_monitor_data);
18556N/A+ bar->priv->zfs_dir_monitor_data = NULL;
18556N/A+ }
18556N/A+ }
18556N/A+}
18556N/A+
18556N/A+void nautilus_zfs_bar_hide (NautilusZfsBar *bar)
18556N/A+{
18556N/A+ bar->priv->explicit_user_hide = TRUE;
18556N/A+ close_clicked_callback (NULL, bar);
18556N/A+}
18556N/A+
18556N/A+
18556N/A+/* Display AND Scan */
18556N/A+
18556N/A+void
18556N/A+nautilus_zfs_bar_display (NautilusZfsBar *bar,
18556N/A+ NautilusWindow *window,
18556N/A+ NautilusDirectory *new_dir,
18556N/A+ GCancellable *cancellable)
18556N/A+{
18556N/A+ gboolean show = FALSE;
20808N/A+ gboolean time_slider_enabled = g_settings_get_boolean (nautilus_preferences, NAUTILUS_PREFERENCES_ENABLE_TIME_SLIDER);
20808N/A+ gboolean visible = gtk_widget_get_visible (GTK_WIDGET (bar));
18556N/A+ gboolean enable_button = FALSE;
18556N/A+ gboolean do_scan = FALSE;
18556N/A+ gboolean do_cancel = FALSE;
18556N/A+
18556N/A+
18556N/A+ /* if bar visible
18556N/A+ * if feature disabled
18556N/A+ * close bar
18556N/A+ * disable button
18556N/A+ * if in root dir
18556N/A+ * enable button
18556N/A+ * else
18556N/A+ * if bar was previously displayed and in same tab
18556N/A+ * if in snapshot
18556N/A+ * redisplay
18556N/A+ * re-align
18556N/A+ * disable button
18556N/A+ * if root dir
18556N/A+ * redisplay
18556N/A+ * re-align
18556N/A+ * enable button
18556N/A+ * else
18556N/A+ * scan
18556N/A+ * else
18556N/A+ * if feature enabled
18556N/A+ * scan
18556N/A+ * disable button
18556N/A+ *
18556N/A+ *
18556N/A+ * NOTE : action_restore_callback display bar when enabled
18556N/A+ */
18556N/A+
18556N/A+ if (visible)
18556N/A+ {
18556N/A+ if (!time_slider_enabled)
18556N/A+ {
18556N/A+ close_clicked_callback (NULL, bar);
18556N/A+ return;
18556N/A+ }
18556N/A+ if (new_dir == bar->priv->dir)
18556N/A+ enable_button = TRUE;
18556N/A+ if (nautilus_directory_is_a_snapshot_dir_of (new_dir, bar->priv->dir) || new_dir == bar->priv->dir)
18556N/A+ {
18556N/A+ show = TRUE;
18556N/A+ do_cancel = TRUE;
18556N/A+ enable_button = TRUE;
18556N/A+ }
18556N/A+ else
18556N/A+ do_scan = TRUE;
18556N/A+ }
18556N/A+ else
18556N/A+ { /* bar is not visible */
18556N/A+ NautilusWindowSlot *slot = nautilus_window_get_active_slot (window);
18556N/A+
18556N/A+ if (bar->priv->is_setup && slot == bar->priv->slot && time_slider_enabled) /* check if we can redisplay the bar */
18556N/A+ {
18556N/A+ if (nautilus_directory_is_a_snapshot_dir_of (new_dir, bar->priv->dir) && !bar->priv->explicit_user_hide)
18556N/A+ show = TRUE;
18556N/A+
18556N/A+ if (bar->priv->explicit_user_hide)
18556N/A+ enable_button = FALSE;
18556N/A+
18556N/A+ if (new_dir == bar->priv->dir)
18556N/A+ {
18556N/A+ show = TRUE;
18556N/A+ enable_button = TRUE;
18556N/A+ }
18556N/A+ else
18556N/A+ do_scan = TRUE;
18556N/A+ }
18556N/A+ else
18556N/A+ { /* icon and throbber set is snapshot_data_ready */
18556N/A+ if (time_slider_enabled)
18556N/A+ do_scan = TRUE;
18556N/A+ }
18556N/A+
18556N/A+ }
18556N/A+
18556N/A+ if (enable_button) /* if button enabled set the icon to normal */
20808N/A+ nautilus_window_set_restore_icon (window, RESTORE_NORMAL);
18556N/A+
18556N/A+ nautilus_window_allow_restore (window, enable_button);
18556N/A+
18556N/A+
18556N/A+ if (show)
18556N/A+ {
18556N/A+ gtk_widget_show (GTK_WIDGET (bar));
18556N/A+ nautilus_zfs_set_snap (bar, new_dir);
18556N/A+ }
18556N/A+ else
18556N/A+ {
18556N/A+ gtk_widget_hide (GTK_WIDGET (bar));
18556N/A+ if (bar->priv->action)
18556N/A+ gtk_toggle_action_set_active (bar->priv->action, FALSE);
18556N/A+ }
18556N/A+
18556N/A+ if (do_cancel)
18556N/A+ g_cancellable_cancel (cancellable);
18556N/A+
18556N/A+ if (do_scan)
18556N/A+ {
18556N/A+ g_cancellable_reset (cancellable);
20808N/A+ nautilus_window_set_restore_icon (window, RESTORE_SEARCH);
18556N/A+ nautilus_window_slot_set_allow_stop (nautilus_window_get_active_slot (window), TRUE);
18556N/A+ nautilus_directory_get_snapshots_async (new_dir,
18556N/A+ snapshot_data_ready,
18556N/A+ cancellable,
18556N/A+ window);
18556N/A+ }
18556N/A+
18556N/A+ /* {
18556N/A+ GFile *file = nautilus_directory_get_location (new_dir);
18556N/A+ char *path = g_file_get_path (file);
18556N/A+
18556N/A+ printf ("nautilus_zfs_bar_display %s\nenable_button : %s, show : %s, do_cancel : %s, do_scan : %s\n\n",
18556N/A+ path,
18556N/A+ enable_button ? "true" : "false",
18556N/A+ show ? "true" : "false",
18556N/A+ do_cancel ? "true" : "false",
18556N/A+ do_scan ? "true" : "false");
18556N/A+ g_free (path);
18556N/A+ }*/
18556N/A+
18556N/A+}
18556N/A+
18556N/A+
18556N/A+void nautilus_zfs_set_snap (NautilusZfsBar *bar,
18556N/A+ NautilusDirectory *dir)
18556N/A+{
18556N/A+ GList* match = NULL;
18556N/A+ GList* snap_list = NULL;
19017N/A+ gboolean in_snap = FALSE;
18556N/A+ char real_path [PATH_MAX+1];
18556N/A+ GFile *file;
18556N/A+ char* path;
18556N/A+ int pos;
18556N/A+ int set_pos = -2;
18556N/A+
18556N/A+ if (!bar->priv->is_setup)
18556N/A+ return;
18556N/A+
18556N/A+ file = nautilus_directory_get_location (dir);
18556N/A+ path = g_file_get_path (file);
18556N/A+ ts_realpath (path, real_path);
18556N/A+
18556N/A+
18556N/A+ if (ts_is_in_remote_backup (real_path))
18556N/A+ { /* hmmm */
20808N/A+ /*gnome_vfs_init();*/
18556N/A+ g_object_ref (dir);
18556N/A+ }
18556N/A+
19017N/A+ in_snap = ts_is_in_snapshot (real_path);
19017N/A+
19017N/A+ if (in_snap)
18556N/A+ {
18556N/A+ snap_list = nautilus_directory_get_snapshots (bar->priv->dir);
18556N/A+ match = g_list_find_custom (snap_list, real_path, (GCompareFunc)match_func);
18556N/A+ }
18556N/A+ g_free (path);
18556N/A+ g_object_unref (file);
18556N/A+
18556N/A+ timescale_set_position (TIMESCALE (bar->priv->scale), match ? ((ZfsDataSet*)match->data)->mountpoint : NULL);
19017N/A+ update_delete_or_snap_button (bar, in_snap);
18556N/A+
18556N/A+/* printf ("nautilus_zfs_set_snap current_path %s real_path %s match %s\n", bar->priv->current_path, real_path,
18556N/A+ match ? "found" : "not found");*/
18556N/A+
18556N/A+ if (bar->priv->current_path && (strcmp (bar->priv->current_path, real_path) != 0))
18556N/A+ {
18556N/A+ bar->priv->set_only = TRUE;
18556N/A+ bar->priv->set_only = FALSE;
18556N/A+
18556N/A+ }
18556N/A+}
18556N/A+
18556N/A+static void snapshot_data_ready_from_change (NautilusDirectory *dir,
18556N/A+ GCancellable *cancellable,
18556N/A+ gpointer callback_data)
18556N/A+{
18556N/A+ NautilusZfsBar *bar = NAUTILUS_ZFS_BAR (callback_data);
18556N/A+
18744N/A+ snapshot_data_ready (dir, cancellable, bar->priv->slot->pane->window);
18556N/A+ update_range (bar);
18556N/A+ gtk_widget_set_sensitive (bar->priv->scale, TRUE);
18556N/A+}
18556N/A+
18556N/A+
18556N/A+static void zfs_dir_change_callback (ZfsSnapDirMonitor *monitor_data,
18556N/A+ NautilusZfsBar *bar)
18556N/A+{
18556N/A+ gtk_widget_set_sensitive (bar->priv->scale, FALSE);
18556N/A+
18556N/A+ g_cancellable_reset (bar->priv->slot->find_zfs_snapshots_cancellable);
20808N/A+ nautilus_window_set_restore_icon (bar->priv->slot->pane->window, RESTORE_SEARCH);
18556N/A+ nautilus_window_slot_set_allow_stop (bar->priv->slot, TRUE);
18556N/A+ nautilus_directory_get_snapshots_async (bar->priv->dir,
18556N/A+ snapshot_data_ready_from_change,
18556N/A+ bar->priv->slot->find_zfs_snapshots_cancellable,
18556N/A+ bar);
18556N/A+}
18556N/A+
18744N/A+static char*
18744N/A+get_backup_dir (GList *snaplist)
18744N/A+{
18744N/A+ GList *tmp = snaplist;
18744N/A+
18744N/A+ while (tmp)
18744N/A+ {
18744N/A+ ZfsDataSet *snap = (ZfsDataSet*) tmp->data;
18744N/A+ if (snap->type == 0)
18744N/A+ {
18744N/A+ char **root_split = NULL;
18744N/A+ char *result = NULL;
18744N/A+ root_split = g_strsplit (snap->mountpoint, snap->name, 2);
18744N/A+ /*printf (" name: %s\n mountpoint: %s\n mtime_str :%s\n space used : %s\n size in kilobytes : %f\n",
18744N/A+ snap->name, snap->mountpoint, snap->mtime_str, snap->used_space_str, snap->used_space); */
18744N/A+ result = g_strdup (root_split[0]);
18744N/A+ if (root_split)
18744N/A+ g_strfreev (root_split);
18744N/A+ return result;
18744N/A+ }
18744N/A+ tmp = tmp->next;
18744N/A+ }
18744N/A+ return NULL;
18744N/A+
18744N/A+
18744N/A+}
18744N/A+
18556N/A+void
18556N/A+nautilus_zfs_bar_setup (NautilusZfsBar* bar,
18556N/A+ NautilusDirectory *dir,
18556N/A+ NautilusWindowSlot *active_slot,
18556N/A+ GtkToggleAction* action)
18556N/A+{
18556N/A+ GFile *file;
18744N/A+ char *path, *zfs_dir, *backup_dir = NULL;
18556N/A+ bar->priv->dir = dir;
18556N/A+ g_object_ref (dir);
18556N/A+ bar->priv->slot = active_slot;
18556N/A+ g_object_ref (active_slot);
18556N/A+
18556N/A+ bar->priv->action = action;
18556N/A+ set_scale_range (bar, TRUE);
18556N/A+ bar->priv->is_setup = TRUE;
18556N/A+ bar->priv->explicit_user_hide = FALSE;
18556N/A+
18556N/A+ file = nautilus_directory_get_location (dir);
18556N/A+ path = g_file_get_path (file);
18556N/A+ zfs_dir = ts_get_snapshot_dir (path);
18744N/A+ backup_dir = get_backup_dir (nautilus_directory_get_snapshots (dir));
18744N/A+
18744N/A+ bar->priv->zfs_dir_monitor_data = monitor_zfs_snap_directory (zfs_dir,
18744N/A+ backup_dir,
18744N/A+ (ZfsDirChangeCallback) zfs_dir_change_callback,
18744N/A+ bar);
18556N/A+ nautilus_zfs_set_snap (bar, dir);
18556N/A+ g_free (path);
18556N/A+ g_free (zfs_dir);
18744N/A+ if (backup_dir)
18744N/A+ g_free(backup_dir);
18556N/A+ g_object_unref (file);
18556N/A+}
18556N/A+
18556N/A+static void
18556N/A+zfs_bar_show_column (GtkWidget *widget, gpointer user_data)
18556N/A+{
18556N/A+ char **visible_columns;
18556N/A+ gboolean restore_col_visible = FALSE;
18556N/A+ int i = 0;
18556N/A+ GPtrArray *ret = NULL;
18556N/A+
20808N/A+ visible_columns = g_settings_get_strv (nautilus_list_view_preferences,
20808N/A+ NAUTILUS_PREFERENCES_LIST_VIEW_DEFAULT_VISIBLE_COLUMNS);
18556N/A+
18556N/A+ ret = g_ptr_array_new ();
18556N/A+
18556N/A+ /* convert visible_columns in ptr array without "restore_info" */
18556N/A+ while (visible_columns[i])
18556N/A+ {
18556N/A+ if (strcmp (visible_columns [i], "restore_info") == 0)
18556N/A+ {
18556N/A+ restore_col_visible = TRUE;
18556N/A+ break;
18556N/A+ }
18556N/A+ else
18556N/A+ g_ptr_array_add (ret, g_strdup (visible_columns [i]));
18556N/A+ i++;
18556N/A+ }
18556N/A+
18556N/A+ g_strfreev (visible_columns);
18556N/A+
18556N/A+ if (restore_col_visible)
18556N/A+ {
20808N/A+ if (!gtk_widget_get_visible (widget)) /* hide bar remove pref */
18556N/A+ {
18556N/A+ char **col_array;
18556N/A+ g_ptr_array_add (ret, NULL);
18556N/A+ col_array = (char **)g_ptr_array_free (ret, FALSE);
20808N/A+ g_settings_set_strv (nautilus_list_view_preferences,
20808N/A+ NAUTILUS_PREFERENCES_LIST_VIEW_DEFAULT_VISIBLE_COLUMNS,
20808N/A+ (const char * const *) col_array);
18556N/A+ g_strfreev (col_array);
18556N/A+ ret = NULL;
18556N/A+ }
18556N/A+ }
18556N/A+ else
18556N/A+ {
20808N/A+ if (gtk_widget_get_visible (widget))
18556N/A+ {
18556N/A+ char **col_array;
18556N/A+ g_ptr_array_add (ret,strdup ("restore_info"));
18556N/A+ g_ptr_array_add (ret,NULL);
18556N/A+ col_array = (char **)g_ptr_array_free (ret, FALSE);
20808N/A+ g_settings_set_strv (nautilus_list_view_preferences,
20808N/A+ NAUTILUS_PREFERENCES_LIST_VIEW_DEFAULT_VISIBLE_COLUMNS,
20808N/A+ (const char * const *) col_array);
18556N/A+ g_strfreev (col_array);
18556N/A+ ret = NULL;
18556N/A+ }
18556N/A+
18556N/A+ }
18556N/A+
18556N/A+ if (ret)
18556N/A+ g_ptr_array_free (ret, TRUE);
18556N/A+
18556N/A+}
18556N/A+
18556N/A+static void
18556N/A+zfs_bar_hidden (GtkWidget *widget, gpointer user_data)
18556N/A+{
18556N/A+ NautilusZfsBar *bar = NAUTILUS_ZFS_BAR (user_data);
18556N/A+ monitor_zfs_snap_directory_cancel (bar->priv->zfs_dir_monitor_data);
18556N/A+ bar->priv->zfs_dir_monitor_data = NULL;
18556N/A+ nautilus_directory_cancel_restore_info (bar->priv->dir);
18556N/A+}
18556N/A+
18556N/A+GtkWidget *
18556N/A+nautilus_zfs_bar_new ()
18556N/A+{
18556N/A+ GObject *bar;
18556N/A+ NautilusZfsBar *zfs_bar;
18556N/A+
18556N/A+ bar = g_object_new (NAUTILUS_TYPE_ZFS_BAR, NULL);
18556N/A+
18556N/A+ g_signal_connect_object (bar, "show", G_CALLBACK (zfs_bar_show_column), bar, NULL);
18556N/A+ g_signal_connect_object (bar, "hide", G_CALLBACK (zfs_bar_show_column), bar, NULL);
18556N/A+ g_signal_connect_object (bar, "hide", G_CALLBACK (zfs_bar_hidden), bar, NULL);
18556N/A+
18556N/A+ zfs_bar_show_column (GTK_WIDGET (bar), NULL);
18556N/A+
18556N/A+ ts_is_restore_column_enabled_init ();
18556N/A+
18556N/A+ zfs_bar = NAUTILUS_ZFS_BAR (bar);
18556N/A+
18556N/A+ return GTK_WIDGET (bar);
18556N/A+}
18744N/Adiff -Nrup -x '*.orig' -x '*.rej' -x '*.*~' ../SUNWgnome-file-mgr-2.30.0-b4/nautilus-2.30.1/src/nautilus-zfs-bar.h nautilus-2.30.1/src/nautilus-zfs-bar.h
18744N/A--- ../SUNWgnome-file-mgr-2.30.0-b4/nautilus-2.30.1/src/nautilus-zfs-bar.h 1970-01-01 01:00:00.000000000 +0100
18744N/A+++ nautilus-2.30.1/src/nautilus-zfs-bar.h 2010-05-14 17:16:39.568719551 +0200
18556N/A@@ -0,0 +1,57 @@
18556N/A+#ifndef __NAUTILUS_ZFS_BAR_H
18556N/A+#define __NAUTILUS_ZFS_BAR_H
18556N/A+
18556N/A+#include <gtk/gtk.h>
18556N/A+#include <libnautilus-private/nautilus-directory.h>
18556N/A+#include "nautilus-window-slot.h"
18556N/A+
18556N/A+G_BEGIN_DECLS
18556N/A+
18556N/A+#define NAUTILUS_TYPE_ZFS_BAR (nautilus_zfs_bar_get_type ())
18556N/A+#define NAUTILUS_ZFS_BAR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), NAUTILUS_TYPE_ZFS_BAR, NautilusZfsBar))
18556N/A+#define NAUTILUS_ZFS_BAR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), NAUTILUS_TYPE_ZFS_BAR, NautilusZfsBarClass))
18556N/A+#define NAUTILUS_IS_ZFS_BAR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), NAUTILUS_TYPE_ZFS_BAR))
18556N/A+#define NAUTILUS_IS_ZFS_BAR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), NAUTILUS_TYPE_ZFS_BAR))
18556N/A+#define NAUTILUS_ZFS_BAR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), NAUTILUS_TYPE_ZFS_BAR, NautilusZfsBarClass))
18556N/A+
18556N/A+typedef struct NautilusZfsBarPrivate NautilusZfsBarPrivate;
18556N/A+
18556N/A+typedef struct
18556N/A+{
18556N/A+ GtkEventBox eventbox;
18556N/A+ NautilusZfsBarPrivate *priv;
18556N/A+} NautilusZfsBar;
18556N/A+
18556N/A+typedef struct
18556N/A+{
18556N/A+ GtkEventBoxClass parent_class;
18556N/A+} NautilusZfsBarClass;
18556N/A+
18556N/A+GType nautilus_zfs_bar_get_type (void) G_GNUC_CONST;
18556N/A+
18556N/A+GtkWidget *nautilus_zfs_bar_new ();
18556N/A+
18556N/A+void nautilus_zfs_bar_setup (NautilusZfsBar* bar,
18556N/A+ NautilusDirectory *dir,
18556N/A+ NautilusWindowSlot *active_slot,
18556N/A+ GtkToggleAction* action);
18556N/A+
18556N/A+void nautilus_zfs_bar_display (NautilusZfsBar *bar,
18556N/A+ NautilusWindow *window,
18556N/A+ NautilusDirectory *new_dir,
18556N/A+ GCancellable* cancellable);
18556N/A+
18556N/A+void nautilus_zfs_set_snap (NautilusZfsBar *bar,
18556N/A+ NautilusDirectory *dir);
18556N/A+void nautilus_zfs_bar_remove_and_skip_snap
18556N/A+ (NautilusZfsBar *bar, char *path);
18556N/A+
18556N/A+void nautilus_zfs_bar_hide (NautilusZfsBar *bar);
18556N/A+
18556N/A+void nautilus_zfs_bar_cancel_tasks (NautilusWindow *window);
18556N/A+NautilusDirectory * nautilus_zfs_bar_get_dir (NautilusZfsBar* bar);
18556N/A+G_END_DECLS
18556N/A+
18556N/A+
18556N/A+
18556N/A+#endif /* __NAUTILUS_ZFS_BAR_H */
20808N/A--- /dev/null 2011-07-25 13:54:15.000000000 +0100
20808N/A+++ nautilus-3.1.3/src/timescale.c 2011-07-25 13:53:42.519729725 +0100
20808N/A@@ -0,0 +1,1278 @@
18556N/A+/*
18556N/A+ * Copyright (C) 2010 Sun Microsystems (Erwann Chenede)
18556N/A+ *
18556N/A+ */
18556N/A+
18556N/A+#include "config.h"
18556N/A+#include "timescale.h"
18556N/A+#include <math.h>
18556N/A+#include <stdlib.h>
18556N/A+#include <libnautilus-private/nautilus-zfs.h>
18556N/A+#include <glib/gi18n-lib.h>
18556N/A+#include <gdk/gdkkeysyms.h>
18556N/A+
18556N/A+#define BAR_W_MAX 20
18556N/A+#define BAR_SPACE 2
18556N/A+
18556N/A+
18556N/A+typedef struct
18556N/A+{
18556N/A+ char *name;
18556N/A+ char *mountpoint;
18556N/A+ char *mtime_str;
18556N/A+ char *mtime_short_str;
18556N/A+ time_t mtime;
18556N/A+ float used_space;
18556N/A+ char *used_space_str;
18556N/A+ SnapType type;
18556N/A+ char *type_str;
18556N/A+} Snap;
18556N/A+
18556N/A+
18556N/A+struct TimeScalePrivate
18556N/A+{
18556N/A+ GList* all_snaps;
18556N/A+ GList* snaps;
18556N/A+ int* bar_x_end;
18556N/A+ int current_pos;
18556N/A+ int num_snaps;
18556N/A+ char *num_rev_string;
18556N/A+ int current_period;
18556N/A+ GList *today;
18556N/A+ GList *yesterday;
18556N/A+ GList *this_week;
18556N/A+ GList *last_week;
18556N/A+ GList *this_month;
18556N/A+ GList *last_month;
18556N/A+ gboolean scrollbar_set;
18556N/A+ gboolean key_pressed;
18556N/A+ GtkWidget *darea;
18556N/A+ GtkWidget *period;
18556N/A+ GtkWidget *info;
18556N/A+ GtkWidget *scrolled;
18556N/A+ GtkWidget *label_tip;
18556N/A+};
18556N/A+
18556N/A+enum {
18556N/A+ VALUE_CHANGED,
18556N/A+ LAST_SIGNAL
18556N/A+};
18556N/A+
18556N/A+enum {
18556N/A+ ALL,
18556N/A+ TODAY,
18556N/A+ YESTERDAY,
18556N/A+ THIS_WEEK,
18556N/A+ LAST_WEEK,
18556N/A+ THIS_MONTH,
18556N/A+ LAST_MONTH
18556N/A+};
18556N/A+
18556N/A+enum {
18556N/A+ COLUMN_INDEX,
18556N/A+ COLUMN_STRING
18556N/A+};
18556N/A+
18556N/A+
18556N/A+static guint signals[LAST_SIGNAL];
18556N/A+
18556N/A+G_DEFINE_TYPE (TimeScale, timescale, GTK_TYPE_HBOX)
18556N/A+
18556N/A+#define TIMESCALE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_TIMESCALE, TimeScalePrivate))
18556N/A+
18556N/A+static gboolean
18556N/A+timescale_expose (GtkWidget *widget,
18556N/A+ GdkEventExpose *event, TimeScale *ts);
18556N/A+static gboolean
18556N/A+query_tooltip (GtkWidget *widget,
18556N/A+ gint x,
18556N/A+ gint y,
18556N/A+ gboolean keyboard_tip,
18556N/A+ GtkTooltip *tooltip,
18556N/A+ gpointer data);
18556N/A+static int
18556N/A+key_pressed (GtkWidget *widget, GdkEventKey *event, TimeScale *ts);
18556N/A+static void
18556N/A+button_pressed (GtkWidget *widget, GdkEventButton *event, TimeScale *ts);
18556N/A+
18556N/A+static void print_snaps (GList *list)
18556N/A+{
18556N/A+ GList* tmp = list;
18556N/A+ int i = 0;
18556N/A+
18556N/A+ while (tmp)
18556N/A+ {
18556N/A+ Snap *snap = (Snap*) tmp->data;
18556N/A+ printf ("=-= %d =-=\nname: %s\nmountpoint: %s\nmtime: %s\nused_space: %s\n",i,
18556N/A+ snap->name, snap->mountpoint, snap->mtime_str, snap->used_space_str);
18556N/A+ i++;
18556N/A+ tmp = tmp->next;
18556N/A+ }
18556N/A+}
18556N/A+
18556N/A+static char * get_num_snap_string (GList *snap_list)
18556N/A+{
18556N/A+ goffset total = 0;
18556N/A+ int i = 0;
18556N/A+ GList *tmp = snap_list;
18556N/A+ char *num_rev;
18556N/A+
18556N/A+ char *size_str = NULL;
18556N/A+
18556N/A+ for (tmp; tmp; tmp = tmp->next)
18556N/A+ {
18556N/A+ Snap *snap = ((Snap*) tmp->data);
18556N/A+ total += snap->used_space;
18556N/A+ i++;
18556N/A+ }
18556N/A+
18556N/A+ total *= 1024;
18556N/A+
18556N/A+ size_str = g_format_size_for_display (total);
18556N/A+
18556N/A+ /* SUN_BRANDING */
18556N/A+ num_rev = g_strdup_printf (_("%d %s\n%s"),
18556N/A+ i,
18556N/A+ /* SUN_BRANDING */
18556N/A+ ngettext ("snapshot", "snapshots", i),
18556N/A+ size_str);
18556N/A+ g_free (size_str);
18556N/A+
18556N/A+ return num_rev;
18556N/A+}
18556N/A+
18556N/A+
18556N/A+static char * get_date (GDate *date)
18556N/A+{
18556N/A+ return g_strdup_printf ("%d/%d/%d", g_date_get_day (date),
18556N/A+ g_date_get_month (date),
18556N/A+ g_date_get_year (date));
18556N/A+}
18556N/A+
18556N/A+static GList *trim_list_by_date (GList *list, int type)
18556N/A+{
18556N/A+ GDate then;
18556N/A+ GDate now;
18556N/A+ GDate range_min;
18556N/A+ GDate range_max;
18556N/A+ GDateWeekday weekday;
18556N/A+
18556N/A+ time_t time_now;
18556N/A+ int diff = 0;
18556N/A+ time_now = time (NULL);
18556N/A+ g_date_set_time_t (&now, time_now);
18556N/A+ g_date_set_time_t (&range_min, time_now);
18556N/A+ GList *return_list = NULL;
18556N/A+ int days_diff = 0;
18556N/A+ gboolean range = FALSE;
18556N/A+
18556N/A+ switch (type)
18556N/A+ {
18556N/A+ case TODAY:
18556N/A+ days_diff = 0;
18556N/A+ break;
18556N/A+ case YESTERDAY:
18556N/A+ days_diff = 1;
18556N/A+ break;
18556N/A+ case THIS_WEEK:
18556N/A+ weekday = g_date_get_weekday(&now);
18556N/A+ days_diff = weekday - G_DATE_MONDAY;
18556N/A+ memcpy (&range_max, &range_min, sizeof (GDate));
18556N/A+ g_date_subtract_days (&range_min, days_diff);
18556N/A+ range = TRUE;
18556N/A+ break;
18556N/A+ case LAST_WEEK:
18556N/A+ g_date_subtract_days (&range_min, 7);
18556N/A+ weekday = g_date_get_weekday(&range_min);
18556N/A+ days_diff = weekday - G_DATE_MONDAY;
18556N/A+ g_date_subtract_days (&range_min, days_diff);
18556N/A+ memcpy (&range_max, &range_min, sizeof (GDate));
18556N/A+ g_date_add_days (&range_max, 6);
18556N/A+ range = TRUE;
18556N/A+ break;
18556N/A+ case THIS_MONTH:
18556N/A+ g_date_set_dmy (&range_min, 1, g_date_get_month (&now),
18556N/A+ g_date_get_year (&now));
18556N/A+ g_date_set_time_t (&range_max, time_now);
18556N/A+ range = TRUE;
18556N/A+ break;
18556N/A+ case LAST_MONTH:
18556N/A+ g_date_subtract_months (&range_min, 1);
18556N/A+ g_date_set_dmy (&range_min, 1,
18556N/A+ g_date_get_month (&range_min),
18556N/A+ g_date_get_year (&range_min));
18556N/A+ memcpy (&range_max, &range_min, sizeof (GDate));
18556N/A+ g_date_add_days (&range_max, g_date_get_days_in_month (g_date_get_month (&range_min), g_date_get_year (&range_min)) - 1);
18556N/A+ range = TRUE;
18556N/A+ break;
18556N/A+ }
18556N/A+
18556N/A+ while (list)
18556N/A+ {
18556N/A+ Snap* snap = (Snap*) list->data;
18556N/A+
18556N/A+ if (snap->mtime != 0)
18556N/A+ {
18556N/A+ g_date_set_time_t (&then, snap->mtime);
18556N/A+
18556N/A+ if (!range)
18556N/A+ {
18556N/A+ if (g_date_get_julian (&now) - g_date_get_julian (&then) == days_diff)
18556N/A+ return_list = g_list_append (return_list, snap);
18556N/A+ }
18556N/A+ else
18556N/A+ {
18556N/A+ if (g_date_compare (&then, &range_min) >= 0 && g_date_compare (&then, &range_max) <= 0)
18556N/A+ return_list = g_list_append (return_list, snap);
18556N/A+ }
18556N/A+ }
18556N/A+ list = list->next;
18556N/A+ }
18556N/A+ return return_list;
18556N/A+}
18556N/A+
18556N/A+
18556N/A+static void
18556N/A+free_periods (TimeScale *ts)
18556N/A+{
18556N/A+ if (ts->priv->today)
18556N/A+ {
18556N/A+ g_list_free (ts->priv->today);
18556N/A+ ts->priv->today = NULL;
18556N/A+ }
18556N/A+ if (ts->priv->yesterday)
18556N/A+ {
18556N/A+ g_list_free (ts->priv->yesterday);
18556N/A+ ts->priv->yesterday = NULL;
18556N/A+ }
18556N/A+ if (ts->priv->this_week)
18556N/A+ {
18556N/A+ g_list_free (ts->priv->this_week);
18556N/A+ ts->priv->this_week = NULL;
18556N/A+ }
18556N/A+ if (ts->priv->last_week)
18556N/A+ {
18556N/A+ g_list_free (ts->priv->last_week);
18556N/A+ ts->priv->last_week = NULL;
18556N/A+ }
18556N/A+ if (ts->priv->this_month)
18556N/A+ {
18556N/A+ g_list_free (ts->priv->this_month);
18556N/A+ ts->priv->this_month = NULL;
18556N/A+ }
18556N/A+ if (ts->priv->last_month)
18556N/A+ {
18556N/A+ g_list_free (ts->priv->last_month);
18556N/A+ ts->priv->last_month = NULL;
18556N/A+ }
18556N/A+}
18556N/A+
18556N/A+static GtkListStore *
18556N/A+create_periods (TimeScale *ts)
18556N/A+{
18556N/A+ GtkTreeIter iter;
18556N/A+ GtkListStore* periods = gtk_list_store_new (3, G_TYPE_INT, G_TYPE_STRING, G_TYPE_POINTER);
18556N/A+
18556N/A+ free_periods (ts);
18556N/A+
18556N/A+ gtk_list_store_append (periods, &iter);
18556N/A+ gtk_list_store_set (periods, &iter, 0, ALL, 1, _("All"), 2, ts->priv->all_snaps, -1);
18556N/A+
18556N/A+ ts->priv->today = trim_list_by_date (ts->priv->all_snaps, TODAY);
18556N/A+
18556N/A+ if (ts->priv->today)
18556N/A+ {
18556N/A+ gtk_list_store_append (periods, &iter);
18556N/A+ gtk_list_store_set (periods, &iter, 0, TODAY, 1, _("Today"), 2, ts->priv->today, -1);
18556N/A+ }
18556N/A+
18556N/A+ ts->priv->yesterday = trim_list_by_date (ts->priv->all_snaps, YESTERDAY);
18556N/A+ if (ts->priv->yesterday)
18556N/A+ {
18556N/A+ gtk_list_store_append (periods, &iter);
18556N/A+ gtk_list_store_set (periods, &iter, 0, YESTERDAY, 1, _("Yesterday"), 2, ts->priv->yesterday, -1);
18556N/A+ }
18556N/A+
18556N/A+ ts->priv->this_week = trim_list_by_date (ts->priv->all_snaps, THIS_WEEK);
18556N/A+ if (ts->priv->this_week)
18556N/A+ {
18556N/A+ gtk_list_store_append (periods, &iter);
18556N/A+ gtk_list_store_set (periods, &iter, 0, THIS_WEEK, 1, _("This Week"), 2, ts->priv->this_week, -1);
18556N/A+ }
18556N/A+
18556N/A+ ts->priv->last_week = trim_list_by_date (ts->priv->all_snaps, LAST_WEEK);
18556N/A+ if (ts->priv->last_week)
18556N/A+ {
18556N/A+ gtk_list_store_append (periods, &iter);
18556N/A+ gtk_list_store_set (periods, &iter, 0, LAST_WEEK, 1, _("Last Week"), 2, ts->priv->last_week, -1);
18556N/A+ }
18556N/A+
18556N/A+ ts->priv->this_month = trim_list_by_date (ts->priv->all_snaps, THIS_MONTH);
18556N/A+ if (ts->priv->this_month)
18556N/A+ {
18556N/A+ gtk_list_store_append (periods, &iter);
18556N/A+ gtk_list_store_set (periods, &iter, 0, THIS_MONTH, 1, _("This Month"), 2, ts->priv->this_month, -1);
18556N/A+ }
18556N/A+
18556N/A+ ts->priv->last_month = trim_list_by_date (ts->priv->all_snaps, LAST_MONTH);
18556N/A+ if (ts->priv->last_month)
18556N/A+ {
18556N/A+ gtk_list_store_append (periods, &iter);
18556N/A+ gtk_list_store_set (periods, &iter, 0, LAST_MONTH, 1, _("Last Month"), 2, ts->priv->last_month, -1);
18556N/A+ }
18556N/A+
18556N/A+ return periods;
18556N/A+}
18556N/A+
18556N/A+static void
18556N/A+period_changed (GtkComboBox *combo,
18556N/A+ TimeScale *ts)
18556N/A+{
18556N/A+ gint type;
18556N/A+ GtkTreePath *path;
18556N/A+ GtkTreeModel *model;
18556N/A+ GtkTreeIter iter;
18556N/A+ GList *period;
18556N/A+
18556N/A+ if (!gtk_combo_box_get_active_iter (combo, &iter))
18556N/A+ return;
18556N/A+
18556N/A+ model = gtk_combo_box_get_model (combo);
18556N/A+
18556N/A+ gtk_tree_model_get (model, &iter, 0, &type, 2, &period, -1);
18556N/A+
18556N/A+ if (ts->priv->current_period == type)
18556N/A+ return;
18556N/A+
18556N/A+ ts->priv->current_period = type;
18556N/A+
18556N/A+ ts->priv->snaps = period;
18556N/A+
18556N/A+ ts->priv->num_snaps = g_list_length (ts->priv->snaps);
18556N/A+ if (ts->priv->bar_x_end)
18556N/A+ g_free (ts->priv->bar_x_end);
18556N/A+
18556N/A+ ts->priv->bar_x_end = g_new (int, g_list_length (ts->priv->snaps));
18556N/A+
18556N/A+ ts->priv->current_pos = -1;
18556N/A+
18556N/A+ if (ts->priv->num_rev_string)
18556N/A+ g_free (ts->priv->num_rev_string);
18556N/A+
18556N/A+ ts->priv->num_rev_string = get_num_snap_string (ts->priv->snaps);
18556N/A+ gtk_label_set_label (GTK_LABEL (ts->priv->info), ts->priv->num_rev_string);
18556N/A+
18556N/A+ gtk_widget_set_size_request (ts->priv->darea, ((BAR_SPACE + BAR_W_MAX ) * ts->priv->num_snaps) + PADDING * 2, 60);
18556N/A+
18556N/A+ gtk_widget_queue_draw (ts->priv->darea);
18556N/A+}
18556N/A+
18556N/A+static void
18556N/A+timescale_init (TimeScale *ts)
18556N/A+{
18556N/A+ GtkWidget *vbox;
18556N/A+ GtkCellRenderer *renderer;
18556N/A+
18556N/A+ ts->priv = TIMESCALE_GET_PRIVATE (ts);
18556N/A+ ts->priv->snaps = NULL;
18556N/A+ ts->priv->all_snaps = NULL;
18556N/A+ ts->priv->num_snaps = 0;
18556N/A+ ts->priv->bar_x_end = NULL;
18556N/A+ ts->priv->current_pos = 0;
18556N/A+ ts->priv->num_rev_string = NULL;
18556N/A+ ts->priv->current_period = ALL;
18556N/A+ ts->priv->today = NULL;
18556N/A+ ts->priv->yesterday = NULL;
18556N/A+ ts->priv->this_week = NULL;
18556N/A+ ts->priv->last_week = NULL;
18556N/A+ ts->priv->this_month = NULL;
18556N/A+ ts->priv->last_month = NULL;
18556N/A+ ts->priv->key_pressed = FALSE;
18556N/A+
18556N/A+ gtk_box_set_homogeneous (GTK_BOX (ts), FALSE);
18556N/A+
18556N/A+ /* setup drawing area */
18556N/A+
18556N/A+ ts->priv->darea = gtk_drawing_area_new ();
18556N/A+
18556N/A+ g_signal_connect(ts->priv->darea, "expose-event",
18556N/A+ G_CALLBACK(timescale_expose), ts);
18556N/A+
18556N/A+ g_signal_connect (ts->priv->darea, "query-tooltip",
18556N/A+ G_CALLBACK (query_tooltip), ts);
18556N/A+
18556N/A+ g_signal_connect(ts->priv->darea, "key-press-event",
18556N/A+ G_CALLBACK(key_pressed), ts);
18556N/A+ g_signal_connect(ts->priv->darea, "button_press_event",
18556N/A+ G_CALLBACK(button_pressed), ts);
20808N/A+ gtk_widget_set_can_focus (GTK_WIDGET (ts->priv->darea), TRUE);
18556N/A+ gtk_widget_add_events (GTK_WIDGET (ts->priv->darea), GDK_BUTTON_PRESS_MASK | GDK_KEY_PRESS_MASK);
18556N/A+ g_object_set (G_OBJECT (ts->priv->darea), "has-tooltip", TRUE, NULL);
18556N/A+ gtk_widget_set_size_request (GTK_WIDGET (ts->priv->darea), -1, 60);
18556N/A+
18556N/A+ ts->priv->scrolled = gtk_scrolled_window_new (NULL, NULL);
18556N/A+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (ts->priv->scrolled),
18556N/A+ GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER);
18556N/A+ gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (ts->priv->scrolled),
18556N/A+ ts->priv->darea);
18556N/A+ gtk_viewport_set_shadow_type (GTK_VIEWPORT (gtk_bin_get_child (GTK_BIN (ts->priv->scrolled))), GTK_SHADOW_NONE);
18556N/A+ gtk_widget_show (ts->priv->scrolled);
18556N/A+
18556N/A+ ts->priv->label_tip = gtk_label_new ("Hello");
18556N/A+ gtk_widget_set_name (ts->priv->label_tip, "gtk-tooltip");
18556N/A+ g_object_ref_sink (ts->priv->label_tip);
18556N/A+ gtk_label_set_justify (GTK_LABEL (ts->priv->label_tip), GTK_JUSTIFY_CENTER);
18556N/A+
18556N/A+ /* setup period combo and snap info */
18556N/A+
18556N/A+ vbox = gtk_vbox_new (FALSE, 5);
18556N/A+ ts->priv->period = gtk_combo_box_new ();
18556N/A+ renderer = gtk_cell_renderer_text_new ();
18556N/A+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (ts->priv->period),
18556N/A+ renderer,
18556N/A+ TRUE);
18556N/A+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (ts->priv->period), renderer,
18556N/A+ "text", 1,
18556N/A+ NULL);
18556N/A+ g_signal_connect (ts->priv->period, "changed", G_CALLBACK (period_changed), ts);
18556N/A+
18556N/A+ ts->priv->info = gtk_label_new ("info\ninfo");
18556N/A+ gtk_label_set_justify (GTK_LABEL (ts->priv->info), GTK_JUSTIFY_CENTER);
18556N/A+ gtk_box_pack_start (GTK_BOX (vbox), ts->priv->period, FALSE, FALSE, 5);
18556N/A+ gtk_box_pack_end (GTK_BOX (vbox), ts->priv->info, FALSE, FALSE, 5);
18556N/A+
18556N/A+ /* setup container */
18556N/A+
18556N/A+ gtk_box_pack_start (GTK_BOX (ts), vbox, FALSE, FALSE, 0);
18556N/A+ gtk_box_pack_start (GTK_BOX (ts), ts->priv->scrolled, TRUE, TRUE, 0);
18556N/A+
20808N/A+ gtk_widget_set_can_focus (GTK_WIDGET (ts), TRUE);
18556N/A+ gtk_widget_show_all (GTK_WIDGET (ts));
18556N/A+}
18556N/A+
18556N/A+static float
18556N/A+get_max_snap_size (GList *snaps)
18556N/A+{
18556N/A+ Snap *snap;
18556N/A+ float max_size = 0;
18556N/A+ while (snaps)
18556N/A+ {
18556N/A+ GList *next = snaps->next;
18556N/A+ snap = (Snap*) snaps->data;
18556N/A+ if (snap->used_space > max_size)
18556N/A+ max_size = snap->used_space;
18556N/A+ snaps = next;
18556N/A+ }
18556N/A+ return max_size;
18556N/A+}
18556N/A+
18556N/A+
18556N/A+static Snap*
18556N/A+get_now_snap (TimeScale* ts)
18556N/A+{
18556N/A+ Snap *last_snap;
18556N/A+ last_snap = g_new0 (Snap, 1);
18556N/A+ last_snap->name = g_strdup (_("Now"));
18556N/A+ last_snap->mountpoint = g_strdup (_("None"));
18556N/A+ last_snap->mtime_str = g_strdup (_("Now"));
18556N/A+ last_snap->mtime_short_str = g_strdup (_("Now"));
18556N/A+ last_snap->used_space_str = g_strdup (_("-"));
18556N/A+ last_snap->used_space = 0.0;
18556N/A+ last_snap->type = NOW;
18556N/A+ last_snap->type_str = g_strdup (_("Current Directory"));
18556N/A+ return last_snap;
18556N/A+}
18556N/A+
18556N/A+static char *get_type_str (SnapType type)
18556N/A+{
18556N/A+ switch (type)
18556N/A+ {
18556N/A+ case LOCAL_AUTOMATIC:
18556N/A+ return g_strdup (_("Automatic Snapshot"));
18556N/A+ break;
18556N/A+ case LOCAL_MANUAL:
18556N/A+ return g_strdup (_("Manual Snapshot"));
18556N/A+ break;
18556N/A+ case REMOTE_AUTOMATIC:
18556N/A+ return g_strdup (_("Automatic Remote Backup"));
18556N/A+ break;
18556N/A+ case REMOTE_MANUAL:
18556N/A+ return g_strdup (_("Manual Remote Backup"));
18556N/A+ break;
18556N/A+ default:
18556N/A+ break;
18556N/A+ }
18556N/A+ return NULL;
18556N/A+}
18556N/A+
18556N/A+static SnapType
18556N/A+get_type (ZfsDataSet* snap)
18556N/A+{
18556N/A+ if (snap->type)
18556N/A+ {
18556N/A+ if (strstr (snap->name, "zfs-auto-snap"))
18556N/A+ return LOCAL_AUTOMATIC;
18556N/A+ else
18556N/A+ return LOCAL_MANUAL;
18556N/A+ }
18556N/A+ else
18556N/A+ {
18556N/A+ if (strstr (snap->name, "zfs-auto-snap"))
18556N/A+ return REMOTE_AUTOMATIC;
18556N/A+ else
18556N/A+ return REMOTE_MANUAL;
18556N/A+ }
18556N/A+}
18556N/A+
18556N/A+static GList *
18556N/A+copy_zfs_list (GList *list)
18556N/A+{
18556N/A+ ZfsDataSet *snap;
18556N/A+ GList *new_list = NULL;
18556N/A+ Snap *ts_shot;
18556N/A+ GList *tmp_list = list;
18556N/A+ while (tmp_list)
18556N/A+ {
18556N/A+ snap = (ZfsDataSet*) tmp_list->data;
18556N/A+ ts_shot = g_new0 (Snap, 1);
18556N/A+ ts_shot->name = g_strdup (snap->name);
18556N/A+ ts_shot->mountpoint = g_strdup (snap->mountpoint);
18556N/A+ ts_shot->mtime_str = g_strdup (snap->mtime_str);
18556N/A+ ts_shot->mtime_short_str = nautilus_date_as_string (snap->mtime, TRUE);
18556N/A+ ts_shot->used_space_str = g_strdup (snap->used_space_str);
18556N/A+ ts_shot->used_space = snap->used_space;
18556N/A+ ts_shot->mtime = snap->mtime;
18556N/A+ ts_shot->type = get_type (snap);
18556N/A+ ts_shot->type_str = get_type_str (ts_shot->type);
18556N/A+ new_list = g_list_append (new_list, ts_shot);
18556N/A+ tmp_list = tmp_list->next;
18556N/A+ }
18556N/A+ return new_list;
18556N/A+}
18556N/A+
18556N/A+static void
18556N/A+free_snap (Snap *snap)
18556N/A+{
18556N/A+ if (snap->name)
18556N/A+ g_free (snap->name);
18556N/A+ if (snap->mountpoint)
18556N/A+ g_free (snap->mountpoint);
18556N/A+ if (snap->mtime_str)
18556N/A+ g_free (snap->mtime_str);
18556N/A+ if (snap->mtime_short_str)
18556N/A+ g_free (snap->mtime_short_str);
18556N/A+ if (snap->used_space_str)
18556N/A+ g_free (snap->used_space_str);
18556N/A+ if (snap->type_str)
18556N/A+ g_free (snap->type_str);
18556N/A+
18556N/A+ g_free (snap);
18556N/A+}
18556N/A+
18556N/A+static void
18556N/A+free_snap_list (GList *list)
18556N/A+{
18556N/A+ GList *tmp_list = list;
18556N/A+ while (tmp_list)
18556N/A+ {
18556N/A+ free_snap ((Snap*) tmp_list->data);
18556N/A+ tmp_list = tmp_list->next;
18556N/A+ }
18556N/A+}
18556N/A+
18556N/A+
18556N/A+void
18556N/A+timescale_set_snapshots (TimeScale* ts, GList *list, int init_position)
18556N/A+{
18556N/A+ if (ts->priv->bar_x_end)
18556N/A+ g_free (ts->priv->bar_x_end);
18556N/A+
18556N/A+ if (ts->priv->num_rev_string)
18556N/A+ g_free (ts->priv->num_rev_string);
18556N/A+
18556N/A+ if (ts->priv->all_snaps)
18556N/A+ free_snap_list (ts->priv->all_snaps);
18556N/A+
18556N/A+ ts->priv->all_snaps = copy_zfs_list (list);
18556N/A+ ts->priv->all_snaps = g_list_append (ts->priv->all_snaps, get_now_snap(ts));
18556N/A+ ts->priv->snaps = ts->priv->all_snaps;
18556N/A+ ts->priv->num_snaps = g_list_length (ts->priv->snaps);
18556N/A+
18556N/A+ ts->priv->bar_x_end = g_new (int, g_list_length (ts->priv->snaps));
18556N/A+ ts->priv->current_pos = ts->priv->num_snaps - 1;
18556N/A+
18556N/A+ if (init_position >= 0 && init_position <= ts->priv->num_snaps - 1)
18556N/A+ ts->priv->current_pos = init_position;
18556N/A+
18556N/A+ ts->priv->num_rev_string = get_num_snap_string (ts->priv->snaps);
18556N/A+
18556N/A+ gtk_label_set_label (GTK_LABEL (ts->priv->info), ts->priv->num_rev_string);
18556N/A+ ts->priv->current_period = ALL;
18556N/A+
18556N/A+ gtk_combo_box_set_model (GTK_COMBO_BOX (ts->priv->period), GTK_TREE_MODEL (create_periods (ts)));
18556N/A+ gtk_combo_box_set_active (GTK_COMBO_BOX (ts->priv->period), ALL);
18556N/A+
18556N/A+ gtk_widget_set_size_request (ts->priv->darea, ((BAR_SPACE + BAR_W_MAX) * ts->priv->num_snaps) + PADDING * 2, 60);
18556N/A+ ts->priv->scrollbar_set = FALSE;
18556N/A+}
18556N/A+
18556N/A+GtkWidget*
18556N/A+timescale_new ()
18556N/A+{
18556N/A+ return g_object_new (TYPE_TIMESCALE, NULL);
18556N/A+}
18556N/A+
18556N/A+static void draw_type (cairo_t *cr, int x_c, int y_c, int w, SnapType type)
18556N/A+{
18556N/A+ int x = x_c - w/2;
18556N/A+ int y = y_c - w/2;
18556N/A+
18556N/A+
18556N/A+
18556N/A+ switch (type)
18556N/A+ {
18556N/A+ case LOCAL_MANUAL:
18556N/A+ cairo_move_to (cr,x,y_c);
18556N/A+ cairo_line_to (cr,x+w/2,y_c-w/2);
18556N/A+ cairo_line_to (cr,x+w,y_c);
18556N/A+ /*y = y_c - w/4;
18556N/A+ cairo_rectangle (cr, x, y, w, w/2);*/
18556N/A+ break;
18556N/A+ case LOCAL_AUTOMATIC:
18556N/A+ cairo_arc (cr, x_c, y_c, w/2, M_PI, M_PI*2);
18556N/A+ break;
18556N/A+ case REMOTE_MANUAL:
18556N/A+ /* cairo_rectangle (cr, x, y, w, w); */
18556N/A+ cairo_move_to (cr,x,y_c);
18556N/A+ cairo_line_to (cr,x+w/2,y_c+w/2);
18556N/A+ cairo_line_to (cr,x+w,y_c);
18556N/A+ cairo_line_to (cr,x+w/2,y_c-w/2);
18556N/A+ break;
18556N/A+ case REMOTE_AUTOMATIC:
18556N/A+ cairo_arc (cr, x_c, y_c, w/2, 0.0, M_PI*2);
18556N/A+ break;
18556N/A+ default:
18556N/A+ break;
18556N/A+ }
18556N/A+}
18556N/A+
18556N/A+static void draw_rounded_bar (cairo_t *cr, int x, int y, double w, double h, int r)
18556N/A+{
18556N/A+ /* bottom y instead of top */
18556N/A+ y -= h;
18556N/A+
18556N/A+ if (h == 0 || h < (w / 2) + r)
18556N/A+ {
18556N/A+ y += h;
18556N/A+ cairo_arc (cr, x+(w/2), y+.5, w/2, M_PI, M_PI*2);
18556N/A+ cairo_line_to (cr,x,y+.5);
18556N/A+ return;
18556N/A+ }
18556N/A+
18556N/A+ /* A****BQ
18556N/A+ H C
18556N/A+ * *
18556N/A+ G D
18556N/A+ F****E */
18556N/A+
18556N/A+
18556N/A+ cairo_arc (cr, x+(w/2), y+(w/2), w/2, M_PI, M_PI*2); /* arc from H to C */
18556N/A+ cairo_line_to (cr,x+w,y+h-r); /* Move to D */
18556N/A+ cairo_curve_to(cr, x+w,y+h,x+w,y+h,x+w-r,y+h); /* Curve to E */
18556N/A+ cairo_line_to(cr, x+r,y+h); /* Line to F */
18556N/A+ cairo_curve_to(cr, x,y+h,x,y+h,x,y+h-r); /* Curve to G */
18556N/A+ cairo_line_to(cr, x,y+(w/2)); /* Line to H */
18556N/A+
18556N/A+}
18556N/A+
18556N/A+
18556N/A+
18556N/A+static void draw_rounded_rec (cairo_t *cr, int x, int y, double w, double h, int r)
18556N/A+{
18556N/A+ /* bottom y instead of top */
18556N/A+ y -= h;
18556N/A+
18556N/A+ if (h == 0)
18556N/A+ {
18556N/A+ cairo_set_line_width (cr, 1);
18556N/A+ cairo_move_to (cr,x,y - .5);
18556N/A+ cairo_line_to (cr, x + w, y -.5);
18556N/A+ return;
18556N/A+ }
18556N/A+
18556N/A+ if (h < r * 2)
18556N/A+ r = h / 2;
18556N/A+
18556N/A+ /* A****BQ
18556N/A+ H C
18556N/A+ * *
18556N/A+ G D
18556N/A+ F****E */
18556N/A+
18556N/A+ cairo_move_to (cr,x+r,y); /* Move to A */
18556N/A+ cairo_line_to (cr,x+w-r,y); /* Straight line to B */
18556N/A+ cairo_curve_to (cr,x+w,y,x+w,y,x+w,y+r); /* Curve to C, Control points are both at Q */
18556N/A+ cairo_line_to (cr,x+w,y+h-r); /* Move to D */
18556N/A+ cairo_curve_to(cr, x+w,y+h,x+w,y+h,x+w-r,y+h); /* Curve to E */
18556N/A+ cairo_line_to(cr, x+r,y+h); /* Line to F */
18556N/A+ cairo_curve_to(cr, x,y+h,x,y+h,x,y+h-r); /* Curve to G */
18556N/A+ cairo_line_to(cr, x,y+r); /* Line to H */
18556N/A+ cairo_curve_to(cr, x,y,x,y,x+r,y); /* Curve to A */
18556N/A+}
18556N/A+
18556N/A+static void
18556N/A+set_cr_color (GtkWidget *widget, cairo_t* cr, SnapType type, double alpha)
18556N/A+{
20808N/A+ GtkStyle *style = gtk_widget_get_style(widget);
18556N/A+ switch (type)
18556N/A+ {
18556N/A+ case LOCAL_MANUAL:
18556N/A+ case REMOTE_MANUAL:
20808N/A+ gdk_cairo_set_source_color (cr, &style->dark[GTK_STATE_SELECTED]);
20808N/A+ gdk_cairo_set_source_color (cr, &style->dark[GTK_STATE_SELECTED]);
18556N/A+ break;
18556N/A+ case LOCAL_AUTOMATIC:
18556N/A+ case REMOTE_AUTOMATIC:
20808N/A+ gdk_cairo_set_source_color (cr, &style->light[GTK_STATE_SELECTED]);
18556N/A+ break;
18556N/A+ case NOW:
20808N/A+ gdk_cairo_set_source_color (cr, &style->black);
18556N/A+ break;
18556N/A+ default:
18556N/A+ break;
18556N/A+ }
18556N/A+}
18556N/A+
18556N/A+int get_snap_index_from_coord (TimeScale* ts, gdouble x, gdouble y)
18556N/A+{
18556N/A+ int i;
18556N/A+
18556N/A+ for (i = 0; i < ts->priv->num_snaps; i++)
18556N/A+ {
18556N/A+ if (x < ts->priv->bar_x_end[i])
18556N/A+ return i;
18556N/A+ }
18556N/A+ return -1;
18556N/A+}
18556N/A+
18556N/A+static gboolean
18556N/A+timescale_expose (GtkWidget *widget,
18556N/A+ GdkEventExpose *event, TimeScale* ts)
18556N/A+{
18556N/A+ PangoContext *context;
18556N/A+ PangoFontMetrics *metrics;
18556N/A+ PangoRectangle logical_rect;
18556N/A+ gint ascent, descent;
20808N/A+ cairo_t *cr = gdk_cairo_create (gtk_widget_get_window(widget));
18556N/A+ int i = 0;
18556N/A+ double x;
18556N/A+ int y;
18556N/A+ int selected_x = -1;
18556N/A+ int remaining_timeline_space;
18556N/A+ int remaining_x_start;
18556N/A+ int remaining_x_end;
18556N/A+ int bar_space = BAR_SPACE;
18556N/A+ int bar_w = BAR_W_MAX;
18556N/A+ int line_padding = 3;
18556N/A+ float bar_max_h_inc;
18556N/A+ float bar_max_h;
18556N/A+ int last_bar_x;
18556N/A+ int line_height = 0;
18556N/A+ int timeline_line_height = 0;
18556N/A+ float max_size = 0;
18556N/A+ GList *view_snaps = NULL;
18556N/A+ int num_view_snaps = 0;
18556N/A+ PangoLayout *layout = pango_cairo_create_layout (cr);
18556N/A+ Snap *tmp_snap = NULL;
18556N/A+ gboolean space_left = TRUE;
18556N/A+ PangoFontDescription *timeline_font = NULL;
20808N/A+ GtkStyle *style = gtk_widget_get_style(widget);
20808N/A+ GtkAllocation allocation;
20808N/A+
20808N/A+ gtk_widget_get_allocation(widget, &allocation);
18556N/A+
18556N/A+ if (gtk_widget_has_focus (widget))
20808N/A+ gtk_paint_focus (style, cr, gtk_widget_get_state (widget),
20808N/A+ widget, NULL,
18556N/A+ 0, 0,
20808N/A+ allocation.width-1, allocation.height-1);
18556N/A+
18556N/A+ if (!ts->priv->snaps)
18556N/A+ goto end;
18556N/A+
18556N/A+ /* smaller font for timeline */
18556N/A+
20808N/A+ timeline_font = pango_font_description_copy_static(style->font_desc);
18556N/A+ pango_font_description_set_size (timeline_font, pango_font_description_get_size (timeline_font) - (PANGO_SCALE*2));
18556N/A+
18556N/A+ /* determine space needed for 2 lines of text + padding with
18556N/A+ * current widget->style->font_desc
18556N/A+ * and widget->style->font_desc - 1*/
18556N/A+
18556N/A+ context = gtk_widget_get_pango_context (widget);
20808N/A+ metrics = pango_context_get_metrics (context, style->font_desc,
18556N/A+ pango_context_get_language (context));
18556N/A+ ascent = pango_font_metrics_get_ascent (metrics);
18556N/A+ descent = pango_font_metrics_get_descent (metrics);
18556N/A+ pango_font_metrics_unref (metrics);
18556N/A+
18556N/A+ line_height = PANGO_PIXELS (ascent + descent);
18556N/A+
18556N/A+ metrics = pango_context_get_metrics (context, timeline_font,
18556N/A+ pango_context_get_language (context));
18556N/A+ ascent = pango_font_metrics_get_ascent (metrics);
18556N/A+ descent = pango_font_metrics_get_descent (metrics);
18556N/A+ pango_font_metrics_unref (metrics);
18556N/A+
18556N/A+ timeline_line_height = PANGO_PIXELS (ascent + descent);
18556N/A+
18556N/A+
18556N/A+ x = PADDING;
20808N/A+ bar_max_h = allocation.height - ((line_height + timeline_line_height) + PADDING * 4);
20808N/A+ y = allocation.height - (line_height + (PADDING * 2));
18556N/A+
18556N/A+ num_view_snaps = ts->priv->num_snaps;
18556N/A+ view_snaps = ts->priv->snaps;
18556N/A+
18556N/A+ max_size = log ((float)get_max_snap_size (view_snaps));
18556N/A+
18556N/A+ bar_max_h_inc = max_size / bar_max_h;
18556N/A+
18556N/A+ if (!ts->priv->scrollbar_set)
18556N/A+ {
18556N/A+ GtkAdjustment *adj;
18556N/A+ adj = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (ts->priv->scrolled));
20808N/A+ gtk_adjustment_set_value (adj, gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj));
18556N/A+ gtk_adjustment_set_step_increment(adj, BAR_W_MAX + BAR_SPACE);
18556N/A+ gtk_scrolled_window_set_hadjustment (GTK_SCROLLED_WINDOW (ts->priv->scrolled), adj);
18556N/A+ ts->priv->scrollbar_set = TRUE;
18556N/A+ }
18556N/A+
18556N/A+ /* draw the bars */
18556N/A+
18556N/A+ cairo_set_line_width (cr, 1);
18556N/A+
18556N/A+ for (i = 0; i < num_view_snaps; i++)
18556N/A+ {
18556N/A+ tmp_snap = g_list_nth_data (view_snaps, i);
18556N/A+ int rounded_radius = ROUNDED_RADIUS;
18556N/A+ int height = 0;
18556N/A+ gboolean draw_bar = TRUE;
18556N/A+ double alpha = 1.0;
18556N/A+
18556N/A+ if (tmp_snap->used_space != 0)
18556N/A+ height = (int) log (tmp_snap->used_space) / bar_max_h_inc;
18556N/A+
18556N/A+ /*printf ("drawing %d height %d size %f log of size %f\n", i,
18556N/A+ height,
18556N/A+ tmp_snap->used_space, log (tmp_snap->used_space));*/
18556N/A+
18556N/A+ if (height == 0 & tmp_snap->used_space != 0)
18556N/A+ height = 1;
18556N/A+
18556N/A+ if (tmp_snap->type == REMOTE_AUTOMATIC ||
18556N/A+ tmp_snap->type == REMOTE_MANUAL)
18556N/A+ height = bar_max_h - bar_max_h_inc; /* placeholder until we get rsync size */
18556N/A+
18556N/A+ if (height < ROUNDED_RADIUS)
18556N/A+ height = 0;
18556N/A+
18556N/A+ /* printf ("height %d name %s size %s\n", height, tmp_snap->name, tmp_snap->used_space_str); */
18556N/A+
18556N/A+ if (i == ts->priv->current_pos)
18556N/A+ {
18556N/A+
18556N/A+ cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 1);
18556N/A+ draw_rounded_rec (cr, x-1, y+2, bar_w+2, bar_max_h+8, ROUNDED_RADIUS);
18556N/A+
18556N/A+ cairo_fill (cr);
18556N/A+ cairo_stroke(cr);
18556N/A+
18556N/A+ alpha = 0.5;
18556N/A+ selected_x = x-1 + ((bar_w+2) / 2);
18556N/A+
18556N/A+ if (tmp_snap->type != NOW)
18556N/A+ {
18556N/A+ char *selected_time_size = g_strdup_printf ("%s - %s",
18556N/A+ tmp_snap->mtime_str,
18556N/A+ tmp_snap->used_space_str);
20808N/A+ gdk_cairo_set_source_color (cr, style->text);
20808N/A+ pango_layout_set_font_description (layout, style->font_desc);
18556N/A+ pango_layout_set_text (layout, selected_time_size, -1);
18556N/A+ g_free (selected_time_size);
18556N/A+ }
18556N/A+ else
18556N/A+ pango_layout_set_text (layout, tmp_snap->mtime_str, -1);
18556N/A+ }
18556N/A+
18556N/A+ cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.8);
18556N/A+
18556N/A+ ts->priv->bar_x_end[i] = x + bar_w;
18556N/A+
18556N/A+ if (draw_bar)
18556N/A+ {
18556N/A+ int tmp_y = y;
18556N/A+ float tmp_w = bar_w;
18556N/A+ set_cr_color (widget, cr, tmp_snap->type, 1.0);
18556N/A+ if (tmp_snap->type == LOCAL_AUTOMATIC || tmp_snap->type == LOCAL_MANUAL)
18556N/A+ {
18556N/A+ tmp_y -= 1;
18556N/A+ tmp_w -= 1;
18556N/A+ }
18556N/A+
18556N/A+ if (tmp_snap->type == LOCAL_AUTOMATIC || tmp_snap->type == REMOTE_AUTOMATIC)
18556N/A+ draw_rounded_bar (cr, x, tmp_y, tmp_w, height, rounded_radius);
18556N/A+ else if (tmp_snap->type == LOCAL_MANUAL || tmp_snap->type == REMOTE_MANUAL)
18556N/A+ draw_rounded_rec (cr, x, tmp_y, tmp_w, height, rounded_radius);
18556N/A+ else /* Now Shape */
18556N/A+ draw_type (cr, (x + ((bar_w+bar_space)/2)) - .5, y - (bar_max_h/2), bar_w - 4, REMOTE_MANUAL);
18556N/A+
18556N/A+ if (tmp_snap->type == REMOTE_MANUAL || tmp_snap->type == REMOTE_AUTOMATIC || tmp_snap->type == NOW)
18556N/A+ cairo_fill (cr);
18556N/A+ }
18556N/A+
18556N/A+ cairo_stroke(cr);
18556N/A+
18556N/A+ x += bar_w + bar_space;
18556N/A+ }
18556N/A+
18556N/A+ last_bar_x = x;
18556N/A+
18556N/A+ /* ensure selected bar is visible on key press when scrollbar is enabled */
18556N/A+
18556N/A+ if (ts->priv->current_pos != -1 && ts->priv->key_pressed)
18556N/A+ {
18556N/A+
18556N/A+ GtkAdjustment *adj;
18556N/A+ adj = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (ts->priv->scrolled));
18556N/A+ ts->priv->key_pressed = FALSE;
18556N/A+
20808N/A+ if (gtk_adjustment_get_value(adj) > selected_x)
18556N/A+ {
18556N/A+ gtk_adjustment_set_value (adj, selected_x - BAR_W_MAX);
18556N/A+ gtk_scrolled_window_set_hadjustment (GTK_SCROLLED_WINDOW (ts->priv->scrolled), adj);
18556N/A+ }
20808N/A+ if (gtk_adjustment_get_value(adj) + gtk_adjustment_get_page_size(adj) < selected_x)
18556N/A+ {
20808N/A+ gtk_adjustment_set_value (adj, (selected_x + BAR_W_MAX) - gtk_adjustment_get_page_size(adj));
18556N/A+ gtk_scrolled_window_set_hadjustment (GTK_SCROLLED_WINDOW (ts->priv->scrolled), adj);
18556N/A+ }
18556N/A+ }
18556N/A+
20808N/A+ pango_layout_set_font_description (layout, style->font_desc);
18556N/A+
18556N/A+ /* try to center the selected text */
18556N/A+
18556N/A+ pango_layout_get_pixel_extents (layout,NULL, &logical_rect);
18556N/A+
18556N/A+ if (ts->priv->current_pos != -1 && selected_x != -1)
18556N/A+ {
18556N/A+
18556N/A+ int right_space = last_bar_x - selected_x;
18556N/A+
18556N/A+ if (logical_rect.width /2 > selected_x)
18556N/A+ /* no space on the left, left align */
18556N/A+ selected_x = PADDING;
18556N/A+ else if (logical_rect.width /2 > right_space)
18556N/A+ /* no space on the right, right align */
18556N/A+ selected_x = last_bar_x - logical_rect.width;
18556N/A+ else
18556N/A+ selected_x -= logical_rect.width /2;
18556N/A+
18556N/A+ if (selected_x < 0)
18556N/A+ selected_x = PADDING;
18556N/A+
18556N/A+ /* draw background */
18556N/A+ cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 1);
18556N/A+ draw_rounded_rec (cr, selected_x-2, line_height + 3 , logical_rect.width + 4, line_height+1, ROUNDED_RADIUS);
18556N/A+ cairo_fill (cr);
18556N/A+ cairo_stroke(cr);
18556N/A+
18556N/A+ /* then selected text */
20808N/A+ gdk_cairo_set_source_color (cr, style->text);
18556N/A+ cairo_move_to(cr, selected_x, PADDING);
18556N/A+ pango_cairo_show_layout (cr, layout);
18556N/A+ }
18556N/A+
18556N/A+ /* timeline */
18556N/A+
18556N/A+ /* what to do
18556N/A+ * try to draw oldest
18556N/A+ * then "now" first
18556N/A+ * then in between dates
18556N/A+ * draw additional is possible starting with newest first */
18556N/A+
18556N/A+ x = PADDING;
18556N/A+
18556N/A+
18556N/A+ /* Can the oldest time fit ? */
18556N/A+ tmp_snap = g_list_nth_data (view_snaps, 0);
18556N/A+ pango_layout_set_text (layout, tmp_snap->mtime_short_str, -1);
18556N/A+ pango_layout_set_font_description (layout, timeline_font);
18556N/A+ pango_layout_get_pixel_extents (layout,NULL, &logical_rect);
18556N/A+
20808N/A+ if (logical_rect.width > allocation.width)
18556N/A+ goto end;
18556N/A+
18556N/A+ /* draw anchor line */
18556N/A+
18556N/A+ x += bar_w/2 + .5;
18556N/A+
18556N/A+ cairo_set_line_width (cr, 1);
20808N/A+ gdk_cairo_set_source_color (cr, style->text_aa);
20808N/A+ cairo_move_to (cr, x, allocation.height - ((line_height + PADDING*2)-1));
20808N/A+ cairo_line_to (cr, x, allocation.height - (line_height/2 + PADDING)-.5);
20808N/A+ cairo_line_to (cr, x+2.5, allocation.height - (line_height/2 + PADDING)-.5);
18556N/A+ cairo_stroke(cr);
18556N/A+
18556N/A+ x += 3;
18556N/A+
20808N/A+ gdk_cairo_set_source_color (cr, style->text_aa);
20808N/A+ cairo_move_to(cr, x, allocation.height - (line_height + PADDING));
18556N/A+ pango_cairo_show_layout (cr, layout);
18556N/A+
18556N/A+ remaining_timeline_space = last_bar_x - (x + logical_rect.width);
18556N/A+
18556N/A+ remaining_x_start = x + logical_rect.width;
18556N/A+
18556N/A+ /* try to draw last item */
18556N/A+
18556N/A+ tmp_snap = g_list_nth_data (view_snaps, num_view_snaps-1);
18556N/A+ pango_layout_set_text (layout, tmp_snap->mtime_short_str, -1);
18556N/A+ pango_layout_get_pixel_extents (layout,NULL, &logical_rect);
18556N/A+
18556N/A+ if (remaining_timeline_space < (logical_rect.width + bar_w))
18556N/A+ goto end;
18556N/A+
18556N/A+ remaining_timeline_space -= logical_rect.width + bar_w;
18556N/A+
18556N/A+ x = last_bar_x;
18556N/A+
18556N/A+
18556N/A+ x -= bar_space + bar_w/2 + 0.5;
18556N/A+
20808N/A+ cairo_move_to (cr, x, allocation.height - ((line_height + PADDING*2)-2));
20808N/A+ cairo_line_to (cr, x, allocation.height - (line_height/2 + PADDING)-.5);
20808N/A+ cairo_line_to (cr, x-2.5, allocation.height - (line_height/2 + PADDING)-.5);
18556N/A+ cairo_stroke(cr);
18556N/A+
18556N/A+ cairo_move_to(cr, x - (logical_rect.width + 3.5),
20808N/A+ allocation.height - (line_height + PADDING));
18556N/A+ pango_cairo_show_layout (cr, layout);
18556N/A+
18556N/A+ remaining_x_end = x - (logical_rect.width + 3.5);
18556N/A+
18556N/A+ /* now find the next bar that we can to the timeline and loop */
18556N/A+
18556N/A+
18556N/A+ while (space_left)
18556N/A+ {
18556N/A+ int bar = get_snap_index_from_coord (ts, remaining_x_start, 0);
18556N/A+ /* get the next snap */
18556N/A+ bar++;
18556N/A+ if (bar >= num_view_snaps)
18556N/A+ goto end;
18556N/A+
18556N/A+ tmp_snap = g_list_nth_data (view_snaps, bar);
18556N/A+ pango_layout_set_text (layout, tmp_snap->mtime_short_str, -1);
18556N/A+
18556N/A+ pango_layout_get_pixel_extents (layout,NULL, &logical_rect);
18556N/A+
18556N/A+ if (remaining_timeline_space < logical_rect.width + 4)
18556N/A+ goto end;
18556N/A+
18556N/A+ /* get middle x coord of current bar */
18556N/A+
18556N/A+ x = PADDING + ((bar_w + bar_space) * bar) + bar_w / 2;
18556N/A+
18556N/A+ if ( x + 4 + logical_rect.width > remaining_x_end)
18556N/A+ goto end;
18556N/A+
18556N/A+ /* draw anchor and text */
18556N/A+ x += 0.5;
18556N/A+
20808N/A+ cairo_move_to (cr, x, allocation.height - ((line_height + PADDING*2)-1));
20808N/A+ cairo_line_to (cr, x, allocation.height - (line_height/2 + PADDING)-.5);
20808N/A+ cairo_line_to (cr, x+2.5, allocation.height - (line_height/2 + PADDING)-.5);
18556N/A+ cairo_stroke(cr);
18556N/A+
18556N/A+ x += 3;
18556N/A+
20808N/A+ cairo_move_to(cr, x, allocation.height - (line_height + PADDING));
18556N/A+ pango_cairo_show_layout (cr, layout);
18556N/A+
18556N/A+ remaining_x_start = x + logical_rect.width;
18556N/A+
18556N/A+ remaining_timeline_space = remaining_x_end - remaining_x_start;
18556N/A+
18556N/A+ if (remaining_timeline_space <= 0)
18556N/A+ space_left = FALSE;
18556N/A+ }
18556N/A+end:
18556N/A+ if (timeline_font)
18556N/A+ pango_font_description_free(timeline_font);
18556N/A+ cairo_destroy(cr);
18556N/A+
18556N/A+ return FALSE;
18556N/A+}
18556N/A+
18556N/A+static int
18556N/A+key_pressed (GtkWidget *widget, GdkEventKey *event, TimeScale* ts)
18556N/A+{
18556N/A+ switch (event->keyval)
18556N/A+ {
20808N/A+ case GDK_KEY_KP_Left:
20808N/A+ case GDK_KEY_KP_Up:
20808N/A+ case GDK_KEY_Left:
20808N/A+ case GDK_KEY_Up:
18556N/A+
18556N/A+ if (ts->priv->current_pos >= 1)
18556N/A+ {
18556N/A+ ts->priv->current_pos -= 1;
18556N/A+ gtk_widget_queue_draw (widget);
18556N/A+ ts->priv->key_pressed = TRUE;
18556N/A+ g_signal_emit (ts, signals[VALUE_CHANGED], 0);
18556N/A+ /* printf ("key_pressed back %d\n", ts->priv->current_pos); */
18556N/A+ }
18556N/A+ return TRUE;
20808N/A+ case GDK_KEY_KP_Right:
20808N/A+ case GDK_KEY_KP_Down:
20808N/A+ case GDK_KEY_Right:
20808N/A+ case GDK_KEY_Down:
18556N/A+ if (ts->priv->current_pos <= ts->priv->num_snaps - 2)
18556N/A+ {
18556N/A+ ts->priv->current_pos += 1;
18556N/A+ gtk_widget_queue_draw (widget);
18556N/A+ ts->priv->key_pressed = TRUE;
18556N/A+ g_signal_emit (ts, signals[VALUE_CHANGED], 0);
18556N/A+ /* printf ("key_pressed forward %d\n", ts->priv->current_pos); */
18556N/A+ }
18556N/A+ return TRUE;
18556N/A+
18556N/A+ default:
18556N/A+ return FALSE;
18556N/A+ }
18556N/A+}
18556N/A+
18556N/A+int timescale_get_position (TimeScale* ts)
18556N/A+{
18556N/A+ /* translate into all_snaps position */
18556N/A+ gconstpointer data;
18556N/A+ data = g_list_nth_data (ts->priv->snaps, ts->priv->current_pos);
18556N/A+ return g_list_index (ts->priv->all_snaps, data);
18556N/A+}
18556N/A+
18556N/A+static int match_func (ZfsDataSet *set, char *dir)
18556N/A+{
18556N/A+ return strcmp (set->mountpoint, dir);
18556N/A+}
18556N/A+
18556N/A+void
18556N/A+timescale_set_position (TimeScale* ts, char *mountpoint)
18556N/A+{
18556N/A+ gboolean redraw = FALSE;
18556N/A+ int num_snaps = g_list_length (ts->priv->all_snaps);
18556N/A+ if (mountpoint)
18556N/A+ {
18556N/A+ int pos;
18556N/A+ GList* match = NULL;
18556N/A+ match = g_list_find_custom (ts->priv->all_snaps, mountpoint, (GCompareFunc)match_func);
18556N/A+ pos = g_list_index (ts->priv->all_snaps, match->data);
18556N/A+ if (pos != -1 && ts->priv->current_pos != pos)
18556N/A+ {
18556N/A+ redraw = TRUE;
18556N/A+ ts->priv->current_pos = pos;
18556N/A+ }
18556N/A+ }
18556N/A+ else
18556N/A+ { /* Now special case */
18556N/A+ if (ts->priv->current_pos != num_snaps - 1)
18556N/A+ {
18556N/A+ redraw = TRUE;
18556N/A+ ts->priv->current_pos = num_snaps - 1;
18556N/A+ }
18556N/A+ }
18556N/A+
18556N/A+ if (redraw)
18556N/A+ gtk_widget_queue_draw (GTK_WIDGET (ts));
18556N/A+}
18556N/A+
18556N/A+static void
18556N/A+button_pressed (GtkWidget *widget, GdkEventButton *event, TimeScale* ts)
18556N/A+{
18556N/A+ int new_pos;
18556N/A+
18556N/A+ gtk_widget_grab_focus (widget);
18556N/A+ new_pos = get_snap_index_from_coord (ts, event->x, event->y);
18556N/A+
18556N/A+ if (new_pos == -1)
18556N/A+ return;
18556N/A+
18556N/A+ if (new_pos != ts->priv->current_pos)
18556N/A+ {
18556N/A+ ts->priv->current_pos = new_pos;
18556N/A+ /* printf ("button_pressed (%g,%g) selected %d\n", event->x, event->y, ts->priv->current_pos); */
18556N/A+ g_signal_emit (ts, signals[VALUE_CHANGED], 0);
18556N/A+ gtk_widget_queue_draw (widget);
18556N/A+ }
18556N/A+}
18556N/A+
18556N/A+static gboolean
18556N/A+query_tooltip (GtkWidget *widget,
18556N/A+ gint x,
18556N/A+ gint y,
18556N/A+ gboolean keyboard_tip,
18556N/A+ GtkTooltip *tooltip,
18556N/A+ gpointer data)
18556N/A+{
18556N/A+ static gboolean set = FALSE;
18556N/A+ static int old_pos = -1;
18556N/A+ TimeScale* ts = TIMESCALE (data);
18556N/A+ int new_pos = get_snap_index_from_coord (ts, x, y);
18556N/A+ /* printf ("in query_tooltip new_pos %d total %d num_snap %d\n", new_pos, g_list_length (ts->priv->snaps), ts->priv->num_snaps); */
18556N/A+ Snap *tmp_snap = NULL;
18556N/A+ char *tip = NULL;
18556N/A+
18556N/A+ if (new_pos == -1)
18556N/A+ return FALSE;
18556N/A+
18556N/A+ if (new_pos != old_pos)
18556N/A+ {
18556N/A+ old_pos = new_pos;
18556N/A+ return FALSE;
18556N/A+ }
18556N/A+
18556N/A+ if (new_pos >= ts->priv->num_snaps)
18556N/A+ return FALSE;
18556N/A+
18556N/A+ tmp_snap = g_list_nth_data (ts->priv->snaps, new_pos);
18556N/A+
18556N/A+ tip = g_strdup_printf ("%s\nCreated: %s\nSize: %s\nName: %s", tmp_snap->type_str, tmp_snap->mtime_str, tmp_snap->used_space_str, tmp_snap->name);
18556N/A+ gtk_label_set_text (GTK_LABEL(ts->priv->label_tip), tip);
18556N/A+ gtk_tooltip_set_custom (tooltip, ts->priv->label_tip);
18556N/A+ g_free (tip);
18556N/A+ return TRUE;
18556N/A+}
18556N/A+
18556N/A+static void
18556N/A+timescale_class_init (TimeScaleClass *class)
18556N/A+{
18556N/A+ GtkWidgetClass *widget_class;
18556N/A+ GtkScaleClass *scale_class;
18556N/A+ GObjectClass *object_class;
18556N/A+
18556N/A+ object_class = G_OBJECT_CLASS (class);
18556N/A+ g_type_class_add_private (class, sizeof (TimeScalePrivate));
18556N/A+
18556N/A+ widget_class = GTK_WIDGET_CLASS (class);
18556N/A+
18556N/A+ signals[VALUE_CHANGED] =
18556N/A+ g_signal_new ("value-changed",
18556N/A+ G_TYPE_FROM_CLASS (object_class),
18556N/A+ G_SIGNAL_RUN_LAST,
18556N/A+ G_STRUCT_OFFSET (TimeScaleClass, value_changed),
18556N/A+ NULL, NULL,
18556N/A+ g_cclosure_marshal_VOID__VOID,
18556N/A+ G_TYPE_NONE, 0);
18556N/A+}
18556N/A+
18744N/Adiff -Nrup -x '*.orig' -x '*.rej' -x '*.*~' ../SUNWgnome-file-mgr-2.30.0-b4/nautilus-2.30.1/src/timescale.h nautilus-2.30.1/src/timescale.h
18744N/A--- ../SUNWgnome-file-mgr-2.30.0-b4/nautilus-2.30.1/src/timescale.h 1970-01-01 01:00:00.000000000 +0100
18744N/A+++ nautilus-2.30.1/src/timescale.h 2010-05-14 17:16:39.569612048 +0200
18556N/A@@ -0,0 +1,58 @@
18556N/A+#ifndef __TIMESCALE_H__
18556N/A+#define __TIMESCALE_H__
18556N/A+
18556N/A+
18556N/A+#include <gdk/gdk.h>
18556N/A+#include <gtk/gtk.h>
18556N/A+
18556N/A+
18556N/A+G_BEGIN_DECLS
18556N/A+
18556N/A+#define TYPE_TIMESCALE (timescale_get_type ())
18556N/A+#define TIMESCALE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_TIMESCALE, TimeScale))
18556N/A+#define TIMESCALE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_TIMESCALE, TimeScaleClass))
18556N/A+#define IS_TIMESCALE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_TIMESCALE))
18556N/A+#define IS_TIMESCALE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_TIMESCALE))
18556N/A+#define TIMESCALE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_TIMESCALE, TimeScaleClass))
18556N/A+
18556N/A+
18556N/A+typedef struct _TimeScale TimeScale;
18556N/A+typedef struct _TimeScaleClass TimeScaleClass;
18556N/A+typedef struct TimeScalePrivate TimeScalePrivate;
18556N/A+
18556N/A+struct _TimeScale
18556N/A+{
18556N/A+ GtkHBox hbox;
18556N/A+ TimeScalePrivate *priv;
18556N/A+};
18556N/A+
18556N/A+struct _TimeScaleClass
18556N/A+{
18556N/A+ GtkHBoxClass parent_class;
18556N/A+ void (* value_changed) (TimeScale *timescale);
18556N/A+
18556N/A+};
18556N/A+
18556N/A+
18556N/A+GType timescale_get_type (void) G_GNUC_CONST;
18556N/A+GtkWidget* timescale_new ();
18556N/A+void timescale_set_snapshots (TimeScale* ts, GList *list, int init_position);
18556N/A+int timescale_get_position (TimeScale* ts);
18556N/A+void timescale_set_position (TimeScale* ts, char *mountpoint);
18556N/A+
18556N/A+
18556N/A+#define ROUNDED_RADIUS 6
18556N/A+#define PADDING 3
18556N/A+
18556N/A+typedef enum {
18556N/A+ LOCAL_MANUAL,
18556N/A+ LOCAL_AUTOMATIC,
18556N/A+ REMOTE_MANUAL,
18556N/A+ REMOTE_AUTOMATIC,
18556N/A+ NOW
18556N/A+} SnapType;
18556N/A+
18556N/A+
18556N/A+G_END_DECLS
18556N/A+
18556N/A+#endif /* __TIMESCALE_H__ */
20808N/A--- nautilus-3.1.3/src/nautilus-toolbar-ui.xml.orig 2011-04-04 19:01:24.000000000 +0100
20808N/A+++ nautilus-3.1.3/src/nautilus-toolbar-ui.xml 2011-07-25 09:50:58.998044977 +0100
20808N/A@@ -2,6 +2,7 @@
20808N/A <toolbar name="Toolbar">
20808N/A <toolitem name="Back" action="Back"/>
20808N/A <toolitem name="Forward" action="Forward"/>
20808N/A+ <toolitem name="Restore" action="Restore"/>
20808N/A <toolitem name="Search" action="Search"/>
20808N/A </toolbar>
20808N/A-</ui>
20808N/A\ No newline at end of file
20808N/A+</ui>