[gnome-disk-utility] Introduce local jobs and use it in create/restore disk image operations
- From: David Zeuthen <davidz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-disk-utility] Introduce local jobs and use it in create/restore disk image operations
- Date: Thu, 13 Dec 2012 18:38:58 +0000 (UTC)
commit 992ce822069dfdb50706c9a788803920c9f96999
Author: David Zeuthen <zeuthen gmail com>
Date: Thu Dec 13 13:31:42 2012 -0500
Introduce local jobs and use it in create/restore disk image operations
This way we can avoid the non-modal dialogs as seen here
http://people.freedesktop.org/~david/gnome-disks-multiple-disk-image-dialogs.png
since creating or restoring a disk image is now like any other
long-running operation, see
http://people.freedesktop.org/~david/gnome-disks-disk-image-ops-as-jobs-1.png
http://people.freedesktop.org/~david/gnome-disks-disk-image-ops-as-jobs-2.png
Signed-off-by: David Zeuthen <zeuthen gmail com>
data/ui/create-disk-image-dialog.ui | 120 +----------
data/ui/restore-disk-image-dialog.ui | 104 +---------
src/disks/Makefile.am | 1 +
src/disks/gduapplication.c | 103 +++++++++
src/disks/gduapplication.h | 7 +
src/disks/gducreatediskimagedialog.c | 323 ++++++++++----------------
src/disks/gdudevicetreemodel.c | 102 +++++----
src/disks/gdudevicetreemodel.h | 4 +-
src/disks/gdulocaljob.c | 224 ++++++++++++++++++
src/disks/gdulocaljob.h | 35 +++
src/disks/gdurestorediskimagedialog.c | 245 +++++++++-----------
src/disks/gdutypes.h | 3 +
src/disks/gduvolumegrid.c | 30 ++-
src/disks/gduvolumegrid.h | 2 +-
src/disks/gduwindow.c | 404 +++++++++++++++++++-------------
15 files changed, 923 insertions(+), 784 deletions(-)
---
diff --git a/data/ui/create-disk-image-dialog.ui b/data/ui/create-disk-image-dialog.ui
index 66e0452..0948b69 100644
--- a/data/ui/create-disk-image-dialog.ui
+++ b/data/ui/create-disk-image-dialog.ui
@@ -7,6 +7,7 @@
<property name="border_width">12</property>
<property name="title" translatable="yes">Create Disk Image</property>
<property name="resizable">False</property>
+ <property name="modal">True</property>
<property name="type_hint">dialog</property>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox1">
@@ -91,38 +92,6 @@
</packing>
</child>
<child>
- <object class="GtkLabel" id="destination-key-label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">Destination</property>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">3</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="destination-label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="selectable">True</property>
- <property name="ellipsize">middle</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">3</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
<object class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="can_focus">False</property>
@@ -154,61 +123,6 @@
<property name="height">1</property>
</packing>
</child>
- <child>
- <object class="GtkVBox" id="copying-vbox">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkProgressBar" id="copying-progressbar">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="hexpand">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="copying-label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">4</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="copying-key-label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">1</property>
- <property name="yalign">0</property>
- <property name="label" translatable="yes">Progress</property>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">4</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
</object>
<packing>
<property name="expand">False</property>
@@ -249,36 +163,6 @@
<property name="position">1</property>
</packing>
</child>
- <child>
- <object class="GtkButton" id="close-button">
- <property name="label">gtk-close</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_stock">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="show-in-folder-button">
- <property name="label" translatable="yes">_Show in Folder</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="can_default">True</property>
- <property name="receives_default">True</property>
- <property name="use_underline">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">3</property>
- <property name="secondary">True</property>
- </packing>
- </child>
</object>
<packing>
<property name="expand">False</property>
@@ -292,8 +176,6 @@
<action-widgets>
<action-widget response="-6">cancel-button</action-widget>
<action-widget response="-5">start-copying-button</action-widget>
- <action-widget response="-7">close-button</action-widget>
- <action-widget response="1">show-in-folder-button</action-widget>
</action-widgets>
</object>
</interface>
diff --git a/data/ui/restore-disk-image-dialog.ui b/data/ui/restore-disk-image-dialog.ui
index 2e79e79..6ba5e95 100644
--- a/data/ui/restore-disk-image-dialog.ui
+++ b/data/ui/restore-disk-image-dialog.ui
@@ -7,6 +7,7 @@
<property name="border_width">12</property>
<property name="title" translatable="yes">Restore Disk Image</property>
<property name="resizable">False</property>
+ <property name="modal">True</property>
<property name="type_hint">dialog</property>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox1">
@@ -80,7 +81,7 @@
</object>
<packing>
<property name="left_attach">0</property>
- <property name="top_attach">2</property>
+ <property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
@@ -96,92 +97,6 @@
</object>
<packing>
<property name="left_attach">1</property>
- <property name="top_attach">2</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkVBox" id="copying-vbox">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkProgressBar" id="copying-progressbar">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- </object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="copying-label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- </object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">3</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="copying-key-label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">1</property>
- <property name="yalign">0</property>
- <property name="label" translatable="yes">Progress</property>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">3</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="source-key-label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">1</property>
- <property name="label" translatable="yes">Source</property>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">1</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="source-label">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="selectable">True</property>
- <property name="ellipsize">middle</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
@@ -227,20 +142,6 @@
<property name="position">1</property>
</packing>
</child>
- <child>
- <object class="GtkButton" id="close-button">
- <property name="label">gtk-close</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_stock">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">2</property>
- </packing>
- </child>
</object>
<packing>
<property name="expand">False</property>
@@ -254,7 +155,6 @@
<action-widgets>
<action-widget response="-6">cancel-button</action-widget>
<action-widget response="-5">start-copying-button</action-widget>
- <action-widget response="-7">close-button</action-widget>
</action-widgets>
</object>
</interface>
diff --git a/src/disks/Makefile.am b/src/disks/Makefile.am
index a109aac..0c76be9 100644
--- a/src/disks/Makefile.am
+++ b/src/disks/Makefile.am
@@ -51,6 +51,7 @@ gnome_disks_SOURCES = \
gducreateraidarraydialog.h gducreateraidarraydialog.c \
gduerasemultipledisksdialog.h gduerasemultipledisksdialog.c \
gdudvdsupport.h gdudvdsupport.c \
+ gdulocaljob.h gdulocaljob.c \
$(enum_built_sources) \
$(NULL)
diff --git a/src/disks/gduapplication.c b/src/disks/gduapplication.c
index 8bc37eb..85ad31d 100644
--- a/src/disks/gduapplication.c
+++ b/src/disks/gduapplication.c
@@ -17,6 +17,7 @@
#include "gduapplication.h"
#include "gduwindow.h"
+#include "gdulocaljob.h"
struct _GduApplication
{
@@ -26,6 +27,9 @@ struct _GduApplication
UDisksClient *client;
GduWindow *window;
+
+ /* Maps from UDisksObject* -> GList<GduLocalJob*> */
+ GHashTable *local_jobs;
};
typedef struct
@@ -38,6 +42,7 @@ G_DEFINE_TYPE (GduApplication, gdu_application, GTK_TYPE_APPLICATION);
static void
gdu_application_init (GduApplication *app)
{
+ app->local_jobs = g_hash_table_new (g_direct_hash, g_direct_equal);
}
static void
@@ -45,6 +50,20 @@ gdu_application_finalize (GObject *object)
{
GduApplication *app = GDU_APPLICATION (object);
+ if (app->local_jobs != NULL)
+ {
+ GHashTableIter iter;
+ GList *local_jobs, *jobs_to_destroy = NULL, *l;
+
+ g_hash_table_iter_init (&iter, app->local_jobs);
+ while (g_hash_table_iter_next (&iter, NULL /* object*/, (gpointer) &local_jobs))
+ jobs_to_destroy = g_list_concat (jobs_to_destroy, g_list_copy (local_jobs));
+ for (l = jobs_to_destroy; l != NULL; l = l->next)
+ gdu_application_destroy_local_job (app, GDU_LOCAL_JOB (l->data));
+ g_list_free (jobs_to_destroy);
+ g_hash_table_destroy (app->local_jobs);
+ }
+
if (app->client != NULL)
g_object_unref (app->client);
@@ -380,3 +399,87 @@ gdu_application_new_widget (GduApplication *application,
}
return ret;
}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+on_local_job_notify (GObject *object,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ GduApplication *app = GDU_APPLICATION (user_data);
+ udisks_client_queue_changed (app->client);
+}
+
+
+GduLocalJob *
+gdu_application_create_local_job (GduApplication *application,
+ UDisksObject *object)
+{
+ GduLocalJob *job = NULL;
+ GList *local_jobs;
+
+ g_return_val_if_fail (GDU_IS_APPLICATION (application), NULL);
+ g_return_val_if_fail (UDISKS_IS_OBJECT (object), NULL);
+
+ job = gdu_local_job_new (object);
+
+ local_jobs = g_hash_table_lookup (application->local_jobs, object);
+ local_jobs = g_list_prepend (local_jobs, job);
+ g_hash_table_insert (application->local_jobs, object, local_jobs);
+
+ g_signal_connect (job, "notify", G_CALLBACK (on_local_job_notify), application);
+
+ udisks_client_queue_changed (application->client);
+
+ return job;
+}
+
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+void
+gdu_application_destroy_local_job (GduApplication *application,
+ GduLocalJob *job)
+{
+ GList *local_jobs;
+ UDisksObject *object;
+
+ g_return_if_fail (GDU_IS_APPLICATION (application));
+ g_return_if_fail (GDU_IS_LOCAL_JOB (job));
+
+ object = gdu_local_job_get_object (job);
+
+ local_jobs = g_hash_table_lookup (application->local_jobs, object);
+ g_warn_if_fail (g_list_find (local_jobs, job) != NULL);
+ local_jobs = g_list_remove (local_jobs, job);
+ g_signal_handlers_disconnect_by_func (job, G_CALLBACK (on_local_job_notify), application);
+
+ if (local_jobs != NULL)
+ g_hash_table_insert (application->local_jobs, object, local_jobs);
+ else
+ g_hash_table_remove (application->local_jobs, object);
+
+ g_object_unref (job);
+
+ udisks_client_queue_changed (application->client);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+GList *
+gdu_application_get_local_jobs_for_object (GduApplication *application,
+ UDisksObject *object)
+{
+ GList *ret;
+
+ g_return_val_if_fail (GDU_IS_APPLICATION (application), NULL);
+ g_return_val_if_fail (UDISKS_IS_OBJECT (object), NULL);
+
+ ret = g_list_copy_deep (g_hash_table_lookup (application->local_jobs, object),
+ (GCopyFunc) g_object_ref,
+ NULL);
+ return ret;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
diff --git a/src/disks/gduapplication.h b/src/disks/gduapplication.h
index 2749939..b010845 100644
--- a/src/disks/gduapplication.h
+++ b/src/disks/gduapplication.h
@@ -27,6 +27,13 @@ GObject *gdu_application_new_widget (GduApplication *application,
const gchar *name,
GtkBuilder **out_builder);
+GduLocalJob *gdu_application_create_local_job (GduApplication *application,
+ UDisksObject *object);
+void gdu_application_destroy_local_job (GduApplication *application,
+ GduLocalJob *job);
+GList *gdu_application_get_local_jobs_for_object (GduApplication *application,
+ UDisksObject *object);
+
G_END_DECLS
diff --git a/src/disks/gducreatediskimagedialog.c b/src/disks/gducreatediskimagedialog.c
index 822f8db..f9321eb 100644
--- a/src/disks/gducreatediskimagedialog.c
+++ b/src/disks/gducreatediskimagedialog.c
@@ -25,6 +25,7 @@
#include "gduvolumegrid.h"
#include "gducreatefilesystemwidget.h"
#include "gduestimator.h"
+#include "gdulocaljob.h"
#include "gdudvdsupport.h"
@@ -58,18 +59,9 @@ typedef struct
GtkWidget *name_entry;
GtkWidget *folder_label;
GtkWidget *folder_fcbutton;
- GtkWidget *destination_key_label;
- GtkWidget *destination_label;
-
- GtkWidget *copying_key_label;
- GtkWidget *copying_vbox;
- GtkWidget *copying_progressbar;
- GtkWidget *copying_label;
GtkWidget *start_copying_button;
GtkWidget *cancel_button;
- GtkWidget *close_button;
- GtkWidget *show_in_folder_button;
GCancellable *cancellable;
GFile *output_file;
@@ -91,6 +83,8 @@ typedef struct
gboolean completed;
guint inhibit_cookie;
+
+ GduLocalJob *local_job;
} DialogData;
static const struct {
@@ -102,18 +96,9 @@ static const struct {
{G_STRUCT_OFFSET (DialogData, name_entry), "name-entry"},
{G_STRUCT_OFFSET (DialogData, folder_label), "folder-label"},
{G_STRUCT_OFFSET (DialogData, folder_fcbutton), "folder-fcbutton"},
- {G_STRUCT_OFFSET (DialogData, destination_key_label), "destination-key-label"},
- {G_STRUCT_OFFSET (DialogData, destination_label), "destination-label"},
-
- {G_STRUCT_OFFSET (DialogData, copying_key_label), "copying-key-label"},
- {G_STRUCT_OFFSET (DialogData, copying_vbox), "copying-vbox"},
- {G_STRUCT_OFFSET (DialogData, copying_progressbar), "copying-progressbar"},
- {G_STRUCT_OFFSET (DialogData, copying_label), "copying-label"},
{G_STRUCT_OFFSET (DialogData, start_copying_button), "start-copying-button"},
{G_STRUCT_OFFSET (DialogData, cancel_button), "cancel-button"},
- {G_STRUCT_OFFSET (DialogData, close_button), "close-button"},
- {G_STRUCT_OFFSET (DialogData, show_in_folder_button), "show-in-folder-button"},
{0, NULL}
};
@@ -127,21 +112,51 @@ dialog_data_ref (DialogData *data)
}
static void
+dialog_data_terminate_job (DialogData *data)
+{
+ if (data->local_job != NULL)
+ {
+ gdu_application_destroy_local_job (gdu_window_get_application (data->window), data->local_job);
+ data->local_job = NULL;
+ }
+}
+
+static void
+dialog_data_uninhibit (DialogData *data)
+{
+ if (data->inhibit_cookie > 0)
+ {
+ gtk_application_uninhibit (GTK_APPLICATION (gdu_window_get_application (data->window)),
+ data->inhibit_cookie);
+ data->inhibit_cookie = 0;
+ }
+}
+
+static void
+dialog_data_hide (DialogData *data)
+{
+ if (data->dialog != NULL)
+ {
+ GtkWidget *dialog;
+ if (data->response_signal_handler_id != 0)
+ g_signal_handler_disconnect (data->dialog, data->response_signal_handler_id);
+ dialog = data->dialog;
+ data->dialog = NULL;
+ gtk_widget_hide (dialog);
+ gtk_widget_destroy (dialog);
+ data->dialog = NULL;
+ }
+}
+
+static void
dialog_data_unref (DialogData *data)
{
if (g_atomic_int_dec_and_test (&data->ref_count))
{
- /* hide the dialog */
- if (data->dialog != NULL)
- {
- GtkWidget *dialog;
- if (data->response_signal_handler_id != 0)
- g_signal_handler_disconnect (data->dialog, data->response_signal_handler_id);
- dialog = data->dialog;
- data->dialog = NULL;
- gtk_widget_hide (dialog);
- gtk_widget_destroy (dialog);
- }
+ dialog_data_terminate_job (data);
+ dialog_data_uninhibit (data);
+ dialog_data_hide (data);
+
g_clear_object (&data->cancellable);
g_clear_object (&data->output_file_stream);
g_object_unref (data->window);
@@ -180,13 +195,8 @@ dialog_data_complete_and_unref (DialogData *data)
data->completed = TRUE;
g_cancellable_cancel (data->cancellable);
}
- if (data->inhibit_cookie > 0)
- {
- gtk_application_uninhibit (GTK_APPLICATION (gdu_window_get_application (data->window)),
- data->inhibit_cookie);
- data->inhibit_cookie = 0;
- }
- gtk_widget_hide (data->dialog);
+ dialog_data_uninhibit (data);
+ dialog_data_hide (data);
dialog_data_unref (data);
}
@@ -279,16 +289,17 @@ create_disk_image_populate (DialogData *data)
/* ---------------------------------------------------------------------------------------------------- */
static void
-update_gui (DialogData *data,
+update_job (DialogData *data,
gboolean done)
{
+ gchar *extra_markup = NULL;
guint64 bytes_completed = 0;
- guint64 bytes_target = 1;
+ guint64 bytes_target = 0;
guint64 bytes_per_sec = 0;
- guint64 usec_remaining = 1;
+ guint64 usec_remaining = 0;
guint64 num_error_bytes = 0;
- gchar *s, *s2, *s3, *s4, *s5;
- gdouble progress;
+ gdouble progress = 0.0;
+ gchar *s2, *s3;
g_mutex_lock (&data->copy_lock);
if (data->estimator != NULL)
@@ -302,55 +313,9 @@ update_gui (DialogData *data,
data->update_id = 0;
g_mutex_unlock (&data->copy_lock);
- if (done)
- {
- gint64 duration_usec = data->end_time_usec - data->start_time_usec;
- s2 = g_format_size (bytes_target);
- s3 = gdu_utils_format_duration_usec (duration_usec, GDU_FORMAT_DURATION_FLAGS_SUBSECOND_PRECISION);
- s4 = g_format_size (G_USEC_PER_SEC * bytes_target / duration_usec);
- /* Translators: string used for conveying how long the copy took.
- * The first %s is the amount of bytes copied (ex. "650 MB").
- * The second %s is the time it took to copy (ex. "1 minute", or "Less than a minute").
- * The third %s is the average amount of bytes transfered per second (ex. "8.9 MB").
- */
- s = g_strdup_printf (_("%s copied in %s (%s/sec)"), s2, s3, s4);
- g_free (s4);
- g_free (s3);
- g_free (s2);
- }
- else if (data->retrieving_dvd_keys)
+ if (data->retrieving_dvd_keys)
{
- s = g_strdup (_("Retrieving DVD keys"));
- }
- else if (bytes_per_sec > 0 && usec_remaining > 0)
- {
- s2 = g_format_size (bytes_completed);
- s3 = g_format_size (bytes_target);
- s4 = gdu_utils_format_duration_usec (usec_remaining,
- GDU_FORMAT_DURATION_FLAGS_NO_SECONDS);
- s5 = g_format_size (bytes_per_sec);
- /* Translators: string used for conveying progress of copy operation when there are no errors.
- * The first %s is the amount of bytes copied (ex. "650 MB").
- * The second %s is the size of the device (ex. "8.5 GB").
- * The third %s is the estimated amount of time remaining (ex. "1 minute" or "5 minutes").
- * The fourth %s is the average amount of bytes transfered per second (ex. "8.9 MB").
- */
- s = g_strdup_printf (_("%s of %s copied â %s remaining (%s/sec)"), s2, s3, s4, s5);
- g_free (s5);
- g_free (s4);
- g_free (s3);
- g_free (s2);
- }
- else
- {
- s2 = g_format_size (bytes_completed);
- s3 = g_format_size (bytes_target);
- /* Translators: string used for convey progress of a copy operation where we don't know time remaining / speed.
- * The first two %s are strings with the amount of bytes (ex. "3.4 MB" and "300 MB").
- */
- s = g_strdup_printf (_("%s of %s copied"), s2, s3);
- g_free (s2);
- g_free (s3);
+ extra_markup = g_strdup (_("Retrieving DVD keys"));
}
if (num_error_bytes > 0)
@@ -363,53 +328,63 @@ update_gui (DialogData *data,
/* TODO: once https://bugzilla.gnome.org/show_bug.cgi?id=657194 is resolved, use that instead
* of hard-coding the color
*/
- s4 = g_strdup_printf ("%s\n<span foreground=\"#ff0000\">%s</span>", s, s3);
+ g_free (extra_markup);
+ extra_markup = g_strdup_printf ("<span foreground=\"#ff0000\">%s</span>", s3);
g_free (s3);
g_free (s2);
- g_free (s);
- s = s4;
}
- s2 = g_strconcat ("<small>", s, "</small>", NULL);
- gtk_label_set_markup (GTK_LABEL (data->copying_label), s2);
- g_free (s);
+ if (data->local_job != NULL)
+ {
+ udisks_job_set_bytes (UDISKS_JOB (data->local_job), bytes_target);
+ udisks_job_set_rate (UDISKS_JOB (data->local_job), bytes_per_sec);
+
+ if (done)
+ {
+ progress = 1.0;
+ }
+ else
+ {
+ if (bytes_target != 0)
+ progress = ((gdouble) bytes_completed) / ((gdouble) bytes_target);
+ else
+ progress = 0.0;
+ }
+ udisks_job_set_progress (UDISKS_JOB (data->local_job), progress);
- if (done)
- progress = 1.0;
- else
- progress = ((gdouble) bytes_completed) / ((gdouble) bytes_target);
- gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (data->copying_progressbar), progress);
+ if (usec_remaining == 0)
+ udisks_job_set_expected_end_time (UDISKS_JOB (data->local_job), 0);
+ else
+ udisks_job_set_expected_end_time (UDISKS_JOB (data->local_job), usec_remaining + g_get_real_time ());
+
+ gdu_local_job_set_extra_markup (data->local_job, extra_markup);
+ }
+
+ g_free (extra_markup);
}
/* ---------------------------------------------------------------------------------------------------- */
static void
-play_complete_sound_and_uninhibit (DialogData *data)
+play_complete_sound (DialogData *data)
{
const gchar *sound_message;
/* Translators: A descriptive string for the 'complete' sound, see CA_PROP_EVENT_DESCRIPTION */
sound_message = _("Disk image copying complete");
- ca_gtk_play_for_widget (GTK_WIDGET (data->dialog), 0,
+ ca_gtk_play_for_widget (GTK_WIDGET (data->window), 0,
CA_PROP_EVENT_ID, "complete",
CA_PROP_EVENT_DESCRIPTION, sound_message,
NULL);
-
- if (data->inhibit_cookie > 0)
- {
- gtk_application_uninhibit (GTK_APPLICATION (gdu_window_get_application (data->window)),
- data->inhibit_cookie);
- data->inhibit_cookie = 0;
- }
}
/* ---------------------------------------------------------------------------------------------------- */
static gboolean
-on_update_ui (gpointer user_data)
+on_update_job (gpointer user_data)
{
DialogData *data = user_data;
- update_gui (data, FALSE);
+ update_job (data, FALSE);
dialog_data_unref (data);
return FALSE; /* remove source */
}
@@ -421,10 +396,10 @@ on_show_error (gpointer user_data)
{
DialogData *data = user_data;
- play_complete_sound_and_uninhibit (data);
+ dialog_data_uninhibit (data);
g_assert (data->copy_error != NULL);
- gdu_utils_show_error (GTK_WINDOW (data->dialog),
+ gdu_utils_show_error (GTK_WINDOW (data->window),
_("Error creating disk image"),
data->copy_error);
g_clear_error (&data->copy_error);
@@ -442,13 +417,11 @@ on_success (gpointer user_data)
{
DialogData *data = user_data;
- update_gui (data, TRUE);
-
- gtk_widget_hide (data->cancel_button);
- gtk_widget_show (data->close_button);
- gtk_widget_show (data->show_in_folder_button);
+ update_job (data, TRUE);
- play_complete_sound_and_uninhibit (data);
+ play_complete_sound (data);
+ dialog_data_uninhibit (data);
+ dialog_data_complete_and_unref (data);
dialog_data_unref (data);
return FALSE; /* remove source */
@@ -610,14 +583,14 @@ copy_thread_func (gpointer user_data)
g_mutex_lock (&data->copy_lock);
data->retrieving_dvd_keys = TRUE;
g_mutex_unlock (&data->copy_lock);
- g_idle_add (on_update_ui, dialog_data_ref (data));
+ g_idle_add (on_update_job, dialog_data_ref (data));
dvd_support = gdu_dvd_support_new (device_file, udisks_block_get_size (data->block));
g_mutex_lock (&data->copy_lock);
data->retrieving_dvd_keys = FALSE;
g_mutex_unlock (&data->copy_lock);
- g_idle_add (on_update_ui, dialog_data_ref (data));
+ g_idle_add (on_update_job, dialog_data_ref (data));
}
}
@@ -702,7 +675,7 @@ copy_thread_func (gpointer user_data)
if (num_bytes_completed > 0)
gdu_estimator_add_sample (data->estimator, num_bytes_completed);
if (data->update_id == 0)
- data->update_id = g_idle_add (on_update_ui, dialog_data_ref (data));
+ data->update_id = g_idle_add (on_update_job, dialog_data_ref (data));
last_update_usec = now_usec;
}
g_mutex_unlock (&data->copy_lock);
@@ -844,6 +817,19 @@ check_overwrite (DialogData *data)
return ret;
}
+static void
+on_local_job_canceled (GduLocalJob *job,
+ gpointer user_data)
+{
+ DialogData *data = user_data;
+ if (!data->completed)
+ {
+ dialog_data_terminate_job (data);
+ dialog_data_complete_and_unref (data);
+ update_job (data, FALSE);
+ }
+}
+
static gboolean
start_copying (DialogData *data)
{
@@ -851,7 +837,6 @@ start_copying (DialogData *data)
const gchar *name;
GFile *folder;
GError *error;
- gchar *uri = NULL;
name = gtk_entry_get_text (GTK_ENTRY (data->name_entry));
folder = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (data->folder_fcbutton));
@@ -874,9 +859,6 @@ start_copying (DialogData *data)
goto out;
}
- uri = gdu_utils_get_pretty_uri (data->output_file);
- gtk_label_set_text (GTK_LABEL (data->destination_label), uri);
-
/* now that we know the user picked a folder, update file chooser settings */
gdu_utils_file_chooser_for_disk_images_update_settings (GTK_FILE_CHOOSER (data->folder_fcbutton));
@@ -887,67 +869,29 @@ start_copying (DialogData *data)
/* Translators: Reason why suspend/logout is being inhibited */
C_("create-inhibit-message", "Copying device to disk image"));
+ data->local_job = gdu_application_create_local_job (gdu_window_get_application (data->window),
+ data->object);
+ udisks_job_set_operation (UDISKS_JOB (data->local_job), "x-gdu-create-disk-image");
+ /* Translators: this is the description of the job */
+ gdu_local_job_set_description (data->local_job, _("Creating Disk Image"));
+ udisks_job_set_progress_valid (UDISKS_JOB (data->local_job), TRUE);
+ udisks_job_set_cancelable (UDISKS_JOB (data->local_job), TRUE);
+ g_signal_connect (data->local_job, "canceled",
+ G_CALLBACK (on_local_job_canceled),
+ data);
+
+ dialog_data_hide (data);
+
g_thread_new ("copy-disk-image-thread",
copy_thread_func,
dialog_data_ref (data));
out:
g_clear_object (&folder);
- g_free (uri);
return ret;
}
static void
-show_items_cb (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
-{
- DialogData *data = user_data;
- GError *error;
- error = NULL;
- if (!g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object),
- res,
- &error))
- {
- gdu_utils_show_error (GTK_WINDOW (data->dialog), _("Error showing item"), error);
- g_error_free (error);
- }
- dialog_data_unref (data);
-}
-
-/* http://www.freedesktop.org/wiki/Specifications/file-manager-interface */
-static void
-show_in_folder (DialogData *data)
-{
- gchar *uris[2] = {NULL, NULL};
- GDBusConnection *session_bus;
- const gchar *startup_id;
-
- /* TODO: figure out how to set this */
- startup_id = "";
-
- uris[0] = g_file_get_uri (data->output_file);
-
- session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
- g_dbus_connection_call (session_bus,
- "org.freedesktop.FileManager1",
- "/org/freedesktop/FileManager1",
- "org.freedesktop.FileManager1",
- "ShowItems",
- g_variant_new ("(^ass)", uris, startup_id),
- NULL, /* reply-type */
- G_DBUS_CALL_FLAGS_NONE,
- -1, /* timeout */
- NULL,
- show_items_cb,
- dialog_data_ref (data));
- g_clear_object (&session_bus);
- g_free (uris[0]);
-}
-
-
-
-static void
ensure_unused_cb (GduWindow *window,
GAsyncResult *res,
gpointer user_data)
@@ -975,18 +919,6 @@ on_dialog_response (GtkDialog *dialog,
case GTK_RESPONSE_OK:
if (check_overwrite (data))
{
- /* Hide name, entry widgets, "Start Creating" button and show destination, progress widgets */
- gtk_widget_hide (data->name_label);
- gtk_widget_hide (data->name_entry);
- gtk_widget_hide (data->folder_label);
- gtk_widget_hide (data->folder_fcbutton);
- gtk_widget_show (data->destination_key_label);
- gtk_widget_show (data->destination_label);
- gtk_widget_show (data->copying_key_label);
- gtk_widget_show (data->copying_vbox);
-
- gtk_widget_hide (data->start_copying_button);
-
/* ensure the device is unused (e.g. unmounted) before copying data from it... */
gdu_window_ensure_unused (data->window,
data->object,
@@ -1000,10 +932,6 @@ on_dialog_response (GtkDialog *dialog,
dialog_data_complete_and_unref (data);
break;
- case 1: /* show_in_folder */
- show_in_folder (data);
- break;
-
default: /* explicit fallthrough */
case GTK_RESPONSE_CANCEL:
dialog_data_complete_and_unref (data);
@@ -1049,14 +977,7 @@ gdu_create_disk_image_dialog_show (GduWindow *window,
G_CALLBACK (on_dialog_response),
data);
- /* initially hide the destination, errors and progress widgets + close buttons */
- gtk_widget_hide (data->destination_key_label);
- gtk_widget_hide (data->destination_label);
- gtk_widget_hide (data->copying_key_label);
- gtk_widget_hide (data->copying_vbox);
- gtk_widget_show (data->dialog);
- gtk_widget_hide (data->close_button);
- gtk_widget_hide (data->show_in_folder_button);
+ gtk_window_set_transient_for (GTK_WINDOW (data->dialog), GTK_WINDOW (window));
gtk_window_present (GTK_WINDOW (data->dialog));
/* Only select the precomputed filename, not the .img / .iso extension */
diff --git a/src/disks/gdudevicetreemodel.c b/src/disks/gdudevicetreemodel.c
index 122351d..ec2abef 100644
--- a/src/disks/gdudevicetreemodel.c
+++ b/src/disks/gdudevicetreemodel.c
@@ -13,6 +13,7 @@
#include <glib/gi18n.h>
#include "gdudevicetreemodel.h"
+#include "gduapplication.h"
#include "gduatasmartdialog.h"
#include "gduenumtypes.h"
@@ -20,6 +21,7 @@ struct _GduDeviceTreeModel
{
GtkTreeStore parent_instance;
+ GduApplication *application;
UDisksClient *client;
GList *current_drives;
@@ -50,7 +52,7 @@ typedef struct
enum
{
PROP_0,
- PROP_CLIENT
+ PROP_APPLICATION
};
G_DEFINE_TYPE (GduDeviceTreeModel, gdu_device_tree_model, GTK_TYPE_TREE_STORE);
@@ -113,8 +115,8 @@ gdu_device_tree_model_get_property (GObject *object,
switch (prop_id)
{
- case PROP_CLIENT:
- g_value_set_object (value, gdu_device_tree_model_get_client (model));
+ case PROP_APPLICATION:
+ g_value_set_object (value, gdu_device_tree_model_get_application (model));
break;
default:
@@ -133,8 +135,9 @@ gdu_device_tree_model_set_property (GObject *object,
switch (prop_id)
{
- case PROP_CLIENT:
- model->client = g_value_dup_object (value);
+ case PROP_APPLICATION:
+ model->application = g_value_dup_object (value);
+ model->client = gdu_application_get_client (model->application);
break;
default:
@@ -496,16 +499,14 @@ gdu_device_tree_model_class_init (GduDeviceTreeModelClass *klass)
gobject_class->set_property = gdu_device_tree_model_set_property;
/**
- * GduDeviceTreeModel:client:
+ * GduDeviceTreeModel:application:
*
- * The #UDisksClient used by the #GduDeviceTreeModel instance.
+ * The #GduApplication used by the #GduDeviceTreeModel instance.
*/
g_object_class_install_property (gobject_class,
- PROP_CLIENT,
- g_param_spec_object ("client",
- "Client",
- "The client used by the tree model",
- UDISKS_TYPE_CLIENT,
+ PROP_APPLICATION,
+ g_param_spec_object ("application", NULL, NULL,
+ GDU_TYPE_APPLICATION,
G_PARAM_READABLE |
G_PARAM_WRITABLE |
G_PARAM_CONSTRUCT_ONLY |
@@ -514,35 +515,35 @@ gdu_device_tree_model_class_init (GduDeviceTreeModelClass *klass)
/**
* gdu_device_tree_model_new:
- * @client: A #UDisksClient.
+ * @application: A #GduApplication.
*
* Creates a new #GduDeviceTreeModel for viewing the devices belonging to
- * @client.
+ * @application.
*
* Returns: A #GduDeviceTreeModel. Free with g_object_unref().
*/
GduDeviceTreeModel *
-gdu_device_tree_model_new (UDisksClient *client)
+gdu_device_tree_model_new (GduApplication *application)
{
return GDU_DEVICE_TREE_MODEL (g_object_new (GDU_TYPE_DEVICE_TREE_MODEL,
- "client", client,
- NULL));
+ "application", application,
+ NULL));
}
/**
- * gdu_device_tree_model_get_client:
+ * gdu_device_tree_model_get_application:
* @model: A #GduDeviceTreeModel.
*
- * Gets the #UDisksClient used by @model.
+ * Gets the #GduApplication used by @model.
*
- * Returns: (transfer none): A #UDisksClient. Do not free, the object
- * belongs to @model.
+ * Returns: (transfer none): A #GduApplication. Do not free, the
+ * object belongs to @model.
*/
-UDisksClient *
-gdu_device_tree_model_get_client (GduDeviceTreeModel *model)
+GduApplication *
+gdu_device_tree_model_get_application (GduDeviceTreeModel *model)
{
g_return_val_if_fail (GDU_IS_DEVICE_TREE_MODEL (model), NULL);
- return model->client;
+ return model->application;
}
/* ---------------------------------------------------------------------------------------------------- */
@@ -694,13 +695,14 @@ remove_mdraid (GduDeviceTreeModel *model,
/* ---------------------------------------------------------------------------------------------------- */
static gboolean
-object_has_jobs (UDisksClient *client,
- UDisksObject *object)
+object_has_jobs (GduDeviceTreeModel *model,
+ UDisksObject *object)
{
GList *jobs;
gboolean ret;
- jobs = udisks_client_get_jobs_for_object (client, object);
+ jobs = udisks_client_get_jobs_for_object (model->client, object);
+ jobs = g_list_concat (jobs, gdu_application_get_local_jobs_for_object (model->application, object));
ret = (jobs != NULL);
g_list_foreach (jobs, (GFunc) g_object_unref, NULL);
g_list_free (jobs);
@@ -709,20 +711,20 @@ object_has_jobs (UDisksClient *client,
}
static gboolean
-iface_has_jobs (UDisksClient *client,
- GDBusInterface *iface)
+iface_has_jobs (GduDeviceTreeModel *model,
+ GDBusInterface *iface)
{
GDBusObject *object;
object = g_dbus_interface_get_object (G_DBUS_INTERFACE (iface));
if (object != NULL)
- return object_has_jobs (client, UDISKS_OBJECT (object));
+ return object_has_jobs (model, UDISKS_OBJECT (object));
else
return FALSE;
}
static gboolean
-block_has_jobs (UDisksClient *client,
- UDisksBlock *block)
+block_has_jobs (GduDeviceTreeModel *model,
+ UDisksBlock *block)
{
gboolean ret = FALSE;
GDBusObject *block_object;
@@ -731,7 +733,7 @@ block_has_jobs (UDisksClient *client,
GList *partitions = NULL, *l;
UDisksBlock *cleartext_block = NULL;
- if (iface_has_jobs (client, G_DBUS_INTERFACE (block)))
+ if (iface_has_jobs (model, G_DBUS_INTERFACE (block)))
{
ret = TRUE;
goto out;
@@ -744,7 +746,7 @@ block_has_jobs (UDisksClient *client,
part_table = udisks_object_get_partition_table (UDISKS_OBJECT (block_object));
if (part_table != NULL)
{
- partitions = udisks_client_get_partitions (client, part_table);
+ partitions = udisks_client_get_partitions (model->client, part_table);
for (l = partitions; l != NULL; l = l->next)
{
UDisksPartition *partition = UDISKS_PARTITION (l->data);
@@ -755,7 +757,7 @@ block_has_jobs (UDisksClient *client,
if (partition_object != NULL)
{
partition_block = udisks_object_get_block (UDISKS_OBJECT (partition_object));
- if (block_has_jobs (client, partition_block))
+ if (block_has_jobs (model, partition_block))
{
ret = TRUE;
goto out;
@@ -767,10 +769,10 @@ block_has_jobs (UDisksClient *client,
encrypted = udisks_object_get_encrypted (UDISKS_OBJECT (block_object));
if (encrypted != NULL)
{
- cleartext_block = udisks_client_get_cleartext_block (client, block);
+ cleartext_block = udisks_client_get_cleartext_block (model->client, block);
if (cleartext_block != NULL)
{
- if (block_has_jobs (client, cleartext_block))
+ if (block_has_jobs (model, cleartext_block))
{
ret = TRUE;
goto out;
@@ -790,20 +792,20 @@ block_has_jobs (UDisksClient *client,
/* ---------------------------------------------------------------------------------------------------- */
static gboolean
-drive_has_jobs (UDisksClient *client,
- UDisksDrive *drive)
+drive_has_jobs (GduDeviceTreeModel *model,
+ UDisksDrive *drive)
{
gboolean ret = FALSE;
UDisksBlock *block = NULL;
- if (iface_has_jobs (client, G_DBUS_INTERFACE (drive)))
+ if (iface_has_jobs (model, G_DBUS_INTERFACE (drive)))
{
ret = TRUE;
goto out;
}
- block = udisks_client_get_block_for_drive (client, drive, FALSE); /* get_physical */
- if (block_has_jobs (client, block))
+ block = udisks_client_get_block_for_drive (model->client, drive, FALSE); /* get_physical */
+ if (block_has_jobs (model, block))
{
ret = TRUE;
goto out;
@@ -817,20 +819,20 @@ drive_has_jobs (UDisksClient *client,
/* ---------------------------------------------------------------------------------------------------- */
static gboolean
-mdraid_has_jobs (UDisksClient *client,
- UDisksMDRaid *mdraid)
+mdraid_has_jobs (GduDeviceTreeModel *model,
+ UDisksMDRaid *mdraid)
{
gboolean ret = FALSE;
UDisksBlock *block = NULL;
- if (iface_has_jobs (client, G_DBUS_INTERFACE (mdraid)))
+ if (iface_has_jobs (model, G_DBUS_INTERFACE (mdraid)))
{
ret = TRUE;
goto out;
}
- block = udisks_client_get_block_for_mdraid (client, mdraid);
- if (block != NULL && block_has_jobs (client, block))
+ block = udisks_client_get_block_for_mdraid (model->client, mdraid);
+ if (block != NULL && block_has_jobs (model, block))
{
ret = TRUE;
goto out;
@@ -940,7 +942,7 @@ update_drive (GduDeviceTreeModel *model,
udisks_object_info_get_name (info));
}
- jobs_running = drive_has_jobs (model->client, drive);
+ jobs_running = drive_has_jobs (model, drive);
size = udisks_drive_get_size (drive);
@@ -1142,7 +1144,7 @@ update_mdraid (GduDeviceTreeModel *model,
if (block != NULL)
size = udisks_block_get_size (block);
- jobs_running = mdraid_has_jobs (model->client, mdraid);
+ jobs_running = mdraid_has_jobs (model, mdraid);
gtk_tree_model_get (GTK_TREE_MODEL (model),
&iter,
@@ -1375,7 +1377,7 @@ update_block (GduDeviceTreeModel *model,
preferred_device);
}
- jobs_running = block_has_jobs (model->client, block);
+ jobs_running = block_has_jobs (model, block);
gtk_tree_model_get (GTK_TREE_MODEL (model),
&iter,
diff --git a/src/disks/gdudevicetreemodel.h b/src/disks/gdudevicetreemodel.h
index 99768db..6b46dc7 100644
--- a/src/disks/gdudevicetreemodel.h
+++ b/src/disks/gdudevicetreemodel.h
@@ -38,8 +38,8 @@ enum
};
GType gdu_device_tree_model_get_type (void) G_GNUC_CONST;
-GduDeviceTreeModel *gdu_device_tree_model_new (UDisksClient *client);
-UDisksClient *gdu_device_tree_model_get_client (GduDeviceTreeModel *model);
+GduDeviceTreeModel *gdu_device_tree_model_new (GduApplication *application);
+GduApplication *gdu_device_tree_model_get_application (GduDeviceTreeModel *model);
gboolean gdu_device_tree_model_get_iter_for_object (GduDeviceTreeModel *model,
UDisksObject *object,
GtkTreeIter *iter);
diff --git a/src/disks/gdulocaljob.c b/src/disks/gdulocaljob.c
new file mode 100644
index 0000000..4392df2
--- /dev/null
+++ b/src/disks/gdulocaljob.c
@@ -0,0 +1,224 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008-2012 Red Hat, Inc.
+ *
+ * Licensed under GPL version 2 or later.
+ *
+ * Author: David Zeuthen <zeuthen gmail com>
+ */
+
+#include "config.h"
+#include <glib/gi18n.h>
+
+#include "gduenums.h"
+#include "gdulocaljob.h"
+
+typedef struct GduLocalJobClass GduLocalJobClass;
+
+struct GduLocalJob
+{
+ UDisksJobSkeleton parent;
+
+ UDisksObject *object;
+ gchar *description;
+ gchar *extra_markup;
+};
+
+struct GduLocalJobClass
+{
+ UDisksJobSkeletonClass parent_class;
+
+ /* signals */
+ void (*canceled) (GduLocalJob *job);
+};
+
+enum
+{
+ PROP_0,
+ PROP_OBJECT,
+ PROP_DESCRIPTION,
+ PROP_EXTRA_MARKUP,
+};
+
+enum
+{
+ CANCELED_SIGNAL,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = {0};
+
+G_DEFINE_TYPE (GduLocalJob, gdu_local_job, UDISKS_TYPE_JOB_SKELETON)
+
+static void
+gdu_local_job_finalize (GObject *object)
+{
+ GduLocalJob *job = GDU_LOCAL_JOB (object);
+
+ g_object_unref (job->object);
+ g_free (job->description);
+ g_free (job->extra_markup);
+
+ G_OBJECT_CLASS (gdu_local_job_parent_class)->finalize (object);
+}
+
+static void
+gdu_local_job_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GduLocalJob *job = GDU_LOCAL_JOB (object);
+
+ switch (property_id)
+ {
+ case PROP_OBJECT:
+ g_value_set_object (value, gdu_local_job_get_object (job));
+ break;
+
+ case PROP_DESCRIPTION:
+ g_value_set_string (value, gdu_local_job_get_description (job));
+ break;
+
+ case PROP_EXTRA_MARKUP:
+ g_value_set_string (value, gdu_local_job_get_extra_markup (job));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gdu_local_job_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GduLocalJob *job = GDU_LOCAL_JOB (object);
+
+ switch (property_id)
+ {
+ case PROP_OBJECT:
+ g_assert (job->object == NULL);
+ job->object = g_value_dup_object (value);
+ break;
+
+ case PROP_DESCRIPTION:
+ gdu_local_job_set_description (job, g_value_get_string (value));
+ break;
+
+ case PROP_EXTRA_MARKUP:
+ gdu_local_job_set_extra_markup (job, g_value_get_string (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+gdu_local_job_class_init (GduLocalJobClass *klass)
+{
+ GObjectClass *gobject_class;
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->get_property = gdu_local_job_get_property;
+ gobject_class->set_property = gdu_local_job_set_property;
+ gobject_class->finalize = gdu_local_job_finalize;
+
+ g_object_class_install_property (gobject_class, PROP_DESCRIPTION,
+ g_param_spec_string ("description", NULL, NULL,
+ NULL,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (gobject_class, PROP_EXTRA_MARKUP,
+ g_param_spec_string ("extra-markup", NULL, NULL,
+ NULL,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (gobject_class, PROP_OBJECT,
+ g_param_spec_object ("object", NULL, NULL,
+ UDISKS_TYPE_OBJECT,
+ G_PARAM_READABLE |
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ signals[CANCELED_SIGNAL] = g_signal_new ("canceled",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GduLocalJobClass, canceled),
+ NULL,
+ NULL,
+ g_cclosure_marshal_generic,
+ G_TYPE_NONE,
+ 0);
+}
+
+static void
+gdu_local_job_init (GduLocalJob *widget)
+{
+}
+
+GduLocalJob *
+gdu_local_job_new (UDisksObject *object)
+{
+ return GDU_LOCAL_JOB (g_object_new (GDU_TYPE_LOCAL_JOB,
+ "object", object,
+ NULL));
+}
+
+void
+gdu_local_job_set_description (GduLocalJob *job,
+ const gchar *description)
+{
+ g_return_if_fail (GDU_IS_LOCAL_JOB (job));
+ g_free (job->description);
+ job->description = g_strdup (description);
+ g_object_notify (G_OBJECT (job), "description");
+}
+
+const gchar *
+gdu_local_job_get_description (GduLocalJob *job)
+{
+ g_return_val_if_fail (GDU_IS_LOCAL_JOB (job), NULL);
+ return job->description;
+}
+
+void
+gdu_local_job_set_extra_markup (GduLocalJob *job,
+ const gchar *markup)
+{
+ g_return_if_fail (GDU_IS_LOCAL_JOB (job));
+ g_free (job->extra_markup);
+ job->extra_markup = g_strdup (markup);
+ g_object_notify (G_OBJECT (job), "extra-markup");
+}
+
+const gchar *
+gdu_local_job_get_extra_markup (GduLocalJob *job)
+{
+ g_return_val_if_fail (GDU_IS_LOCAL_JOB (job), NULL);
+ return job->extra_markup;
+}
+
+UDisksObject *
+gdu_local_job_get_object (GduLocalJob *job)
+{
+ g_return_val_if_fail (GDU_IS_LOCAL_JOB (job), NULL);
+ return job->object;
+}
+
+void
+gdu_local_job_canceled (GduLocalJob *job)
+{
+ g_return_if_fail (GDU_IS_LOCAL_JOB (job));
+ g_signal_emit (job, signals[CANCELED_SIGNAL], 0);
+}
+
+
diff --git a/src/disks/gdulocaljob.h b/src/disks/gdulocaljob.h
new file mode 100644
index 0000000..6f24442
--- /dev/null
+++ b/src/disks/gdulocaljob.h
@@ -0,0 +1,35 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2008-2012 Red Hat, Inc.
+ *
+ * Licensed under GPL version 2 or later.
+ *
+ * Author: David Zeuthen <zeuthen gmail com>
+ */
+
+#ifndef __GDU_LOCAL_JOB_H__
+#define __GDU_LOCAL_JOB_H__
+
+#include <gtk/gtk.h>
+#include "gdutypes.h"
+
+G_BEGIN_DECLS
+
+#define GDU_TYPE_LOCAL_JOB (gdu_local_job_get_type())
+#define GDU_LOCAL_JOB(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDU_TYPE_LOCAL_JOB, GduLocalJob))
+#define GDU_IS_LOCAL_JOB(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDU_TYPE_LOCAL_JOB))
+
+GType gdu_local_job_get_type (void) G_GNUC_CONST;
+GduLocalJob *gdu_local_job_new (UDisksObject *object);
+UDisksObject *gdu_local_job_get_object (GduLocalJob *job);
+void gdu_local_job_set_description (GduLocalJob *job,
+ const gchar *description);
+const gchar *gdu_local_job_get_description (GduLocalJob *job);
+void gdu_local_job_set_extra_markup (GduLocalJob *job,
+ const gchar *markup);
+const gchar *gdu_local_job_get_extra_markup (GduLocalJob *job);
+void gdu_local_job_canceled (GduLocalJob *job);
+
+G_END_DECLS
+
+#endif /* __GDU_LOCAL_JOB_H__ */
diff --git a/src/disks/gdurestorediskimagedialog.c b/src/disks/gdurestorediskimagedialog.c
index 2c7c90e..5389c57 100644
--- a/src/disks/gdurestorediskimagedialog.c
+++ b/src/disks/gdurestorediskimagedialog.c
@@ -24,6 +24,7 @@
#include "gdurestorediskimagedialog.h"
#include "gduvolumegrid.h"
#include "gduestimator.h"
+#include "gdulocaljob.h"
/* ---------------------------------------------------------------------------------------------------- */
@@ -48,18 +49,10 @@ typedef struct
GtkWidget *image_key_label;
GtkWidget *image_fcbutton;
- GtkWidget *source_key_label;
- GtkWidget *source_label;
GtkWidget *destination_key_label;
GtkWidget *destination_label;
- GtkWidget *copying_key_label;
- GtkWidget *copying_vbox;
- GtkWidget *copying_progressbar;
- GtkWidget *copying_label;
-
GtkWidget *start_copying_button;
- GtkWidget *close_button;
GtkWidget *cancel_button;
guint64 block_size;
@@ -84,7 +77,10 @@ typedef struct
guint inhibit_cookie;
+ gulong response_signal_handler_id;
gboolean completed;
+
+ GduLocalJob *local_job;
} DialogData;
@@ -96,19 +92,11 @@ static const struct {
{G_STRUCT_OFFSET (DialogData, image_key_label), "image-key-label"},
{G_STRUCT_OFFSET (DialogData, image_fcbutton), "image-fcbutton"},
- {G_STRUCT_OFFSET (DialogData, source_key_label), "source-key-label"},
- {G_STRUCT_OFFSET (DialogData, source_label), "source-label"},
{G_STRUCT_OFFSET (DialogData, destination_key_label), "destination-key-label"},
{G_STRUCT_OFFSET (DialogData, destination_label), "destination-label"},
- {G_STRUCT_OFFSET (DialogData, copying_key_label), "copying-key-label"},
- {G_STRUCT_OFFSET (DialogData, copying_vbox), "copying-vbox"},
- {G_STRUCT_OFFSET (DialogData, copying_progressbar), "copying-progressbar"},
- {G_STRUCT_OFFSET (DialogData, copying_label), "copying-label"},
-
{G_STRUCT_OFFSET (DialogData, start_copying_button), "start-copying-button"},
{G_STRUCT_OFFSET (DialogData, cancel_button), "cancel-button"},
- {G_STRUCT_OFFSET (DialogData, close_button), "close-button"},
{0, NULL}
};
@@ -122,22 +110,53 @@ dialog_data_ref (DialogData *data)
}
static void
+dialog_data_terminate_job (DialogData *data)
+{
+ if (data->local_job != NULL)
+ {
+ gdu_application_destroy_local_job (gdu_window_get_application (data->window), data->local_job);
+ data->local_job = NULL;
+ }
+}
+
+static void
+dialog_data_uninhibit (DialogData *data)
+{
+ if (data->inhibit_cookie > 0)
+ {
+ gtk_application_uninhibit (GTK_APPLICATION (gdu_window_get_application (data->window)),
+ data->inhibit_cookie);
+ data->inhibit_cookie = 0;
+ }
+}
+
+static void
+dialog_data_hide (DialogData *data)
+{
+ if (data->dialog != NULL)
+ {
+ GtkWidget *dialog;
+ if (data->response_signal_handler_id != 0)
+ g_signal_handler_disconnect (data->dialog, data->response_signal_handler_id);
+ dialog = data->dialog;
+ data->dialog = NULL;
+ gtk_widget_hide (dialog);
+ gtk_widget_destroy (dialog);
+ data->dialog = NULL;
+ }
+}
+
+static void
dialog_data_unref (DialogData *data)
{
if (g_atomic_int_dec_and_test (&data->ref_count))
{
- /* hide the dialog */
- if (data->dialog != NULL)
- {
- GtkWidget *dialog;
- dialog = data->dialog;
- data->dialog = NULL;
- gtk_widget_hide (dialog);
- gtk_widget_destroy (dialog);
- }
+ dialog_data_terminate_job (data);
+ dialog_data_uninhibit (data);
+ dialog_data_hide (data);
+
g_object_unref (data->warning_infobar);
g_object_unref (data->error_infobar);
-
g_object_unref (data->window);
g_object_unref (data->object);
g_object_unref (data->block);
@@ -181,13 +200,8 @@ dialog_data_complete_and_unref (DialogData *data)
data->completed = TRUE;
g_cancellable_cancel (data->cancellable);
}
- if (data->inhibit_cookie > 0)
- {
- gtk_application_uninhibit (GTK_APPLICATION (gdu_window_get_application (data->window)),
- data->inhibit_cookie);
- data->inhibit_cookie = 0;
- }
- gtk_widget_hide (data->dialog);
+ dialog_data_uninhibit (data);
+ dialog_data_hide (data);
dialog_data_unref (data);
}
@@ -328,15 +342,14 @@ restore_disk_image_populate (DialogData *data)
/* ---------------------------------------------------------------------------------------------------- */
static void
-update_gui (DialogData *data,
+update_job (DialogData *data,
gboolean done)
{
guint64 bytes_completed = 0;
- guint64 bytes_target = 1;
+ guint64 bytes_target = 0;
guint64 bytes_per_sec = 0;
- guint64 usec_remaining = 1;
- gchar *s, *s2, *s3, *s4, *s5;
- gdouble progress;
+ guint64 usec_remaining = 0;
+ gdouble progress = 0.0;
g_mutex_lock (&data->copy_lock);
if (data->estimator != NULL)
@@ -349,68 +362,35 @@ update_gui (DialogData *data,
data->update_id = 0;
g_mutex_unlock (&data->copy_lock);
- if (done)
- {
- gint64 duration_usec = data->end_time_usec - data->start_time_usec;
- s2 = g_format_size (bytes_target);
- s3 = gdu_utils_format_duration_usec (duration_usec, GDU_FORMAT_DURATION_FLAGS_SUBSECOND_PRECISION);
- s4 = g_format_size (G_USEC_PER_SEC * bytes_target / duration_usec);
- /* Translators: string used for conveying how long the copy took.
- * The first %s is the amount of bytes copied (ex. "650 MB").
- * The second %s is the time it took to copy (ex. "1 minute", or "Less than a minute").
- * The third %s is the average amount of bytes transfered per second (ex. "8.9 MB").
- */
- s = g_strdup_printf (_("%s copied in %s (%s/sec)"), s2, s3, s4);
- g_free (s4);
- g_free (s3);
- g_free (s2);
- }
- else if (bytes_per_sec > 0 && usec_remaining > 0)
+ if (data->local_job != NULL)
{
- s2 = g_format_size (bytes_completed);
- s3 = g_format_size (bytes_target);
- s4 = gdu_utils_format_duration_usec (usec_remaining,
- GDU_FORMAT_DURATION_FLAGS_NO_SECONDS);
- s5 = g_format_size (bytes_per_sec);
- /* Translators: string used for conveying progress of copy operation when there are no errors.
- * The first %s is the amount of bytes copied (ex. "650 MB").
- * The second %s is the size of the device (ex. "8.5 GB").
- * The third %s is the estimated amount of time remaining (ex. "1 minute" or "5 minutes").
- * The fourth %s is the average amount of bytes transfered per second (ex. "8.9 MB").
- */
- s = g_strdup_printf (_("%s of %s copied â %s remaining (%s/sec)"), s2, s3, s4, s5);
- g_free (s5);
- g_free (s4);
- g_free (s3);
- g_free (s2);
- }
- else
- {
- s2 = g_format_size (bytes_completed);
- s3 = g_format_size (bytes_target);
- /* Translators: string used for convey progress of a copy operation where we don't know time remaining / speed.
- * The first two %s are strings with the amount of bytes (ex. "3.4 MB" and "300 MB").
- */
- s = g_strdup_printf (_("%s of %s copied"), s2, s3);
- g_free (s2);
- g_free (s3);
- }
+ udisks_job_set_bytes (UDISKS_JOB (data->local_job), bytes_target);
+ udisks_job_set_rate (UDISKS_JOB (data->local_job), bytes_per_sec);
- s2 = g_strconcat ("<small>", s, "</small>", NULL);
- gtk_label_set_markup (GTK_LABEL (data->copying_label), s2);
- g_free (s);
+ if (done)
+ {
+ progress = 1.0;
+ }
+ else
+ {
+ if (bytes_target != 0)
+ progress = ((gdouble) bytes_completed) / ((gdouble) bytes_target);
+ else
+ progress = 0.0;
+ }
+ udisks_job_set_progress (UDISKS_JOB (data->local_job), progress);
- if (done)
- progress = 1.0;
- else
- progress = ((gdouble) bytes_completed) / ((gdouble) bytes_target);
- gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (data->copying_progressbar), progress);
+ if (usec_remaining == 0)
+ udisks_job_set_expected_end_time (UDISKS_JOB (data->local_job), 0);
+ else
+ udisks_job_set_expected_end_time (UDISKS_JOB (data->local_job), usec_remaining + g_get_real_time ());
+ }
}
/* ---------------------------------------------------------------------------------------------------- */
static void
-play_complete_sound_and_uninhibit (DialogData *data)
+play_complete_sound (DialogData *data)
{
const gchar *sound_message;
@@ -432,10 +412,10 @@ play_complete_sound_and_uninhibit (DialogData *data)
/* ---------------------------------------------------------------------------------------------------- */
static gboolean
-on_update_ui (gpointer user_data)
+on_update_job (gpointer user_data)
{
DialogData *data = user_data;
- update_gui (data, FALSE);
+ update_job (data, FALSE);
dialog_data_unref (data);
return FALSE; /* remove source */
}
@@ -447,10 +427,11 @@ on_show_error (gpointer user_data)
{
DialogData *data = user_data;
- play_complete_sound_and_uninhibit (data);
+ play_complete_sound (data);
+ dialog_data_uninhibit (data);
g_assert (data->copy_error != NULL);
- gdu_utils_show_error (GTK_WINDOW (data->dialog),
+ gdu_utils_show_error (GTK_WINDOW (data->window),
_("Error restoring disk image"),
data->copy_error);
g_clear_error (&data->copy_error);
@@ -468,12 +449,11 @@ on_success (gpointer user_data)
{
DialogData *data = user_data;
- update_gui (data, TRUE);
-
- gtk_widget_hide (data->cancel_button);
- gtk_widget_show (data->close_button);
+ update_job (data, TRUE);
- play_complete_sound_and_uninhibit (data);
+ play_complete_sound (data);
+ dialog_data_uninhibit (data);
+ dialog_data_complete_and_unref (data);
dialog_data_unref (data);
return FALSE; /* remove source */
@@ -594,7 +574,7 @@ copy_thread_func (gpointer user_data)
if (num_bytes_completed > 0)
gdu_estimator_add_sample (data->estimator, num_bytes_completed);
if (data->update_id == 0)
- data->update_id = g_idle_add (on_update_ui, dialog_data_ref (data));
+ data->update_id = g_idle_add (on_update_job, dialog_data_ref (data));
last_update_usec = now_usec;
}
g_mutex_unlock (&data->copy_lock);
@@ -710,6 +690,19 @@ copy_thread_func (gpointer user_data)
/* ---------------------------------------------------------------------------------------------------- */
+static void
+on_local_job_canceled (GduLocalJob *job,
+ gpointer user_data)
+{
+ DialogData *data = user_data;
+ if (!data->completed)
+ {
+ dialog_data_terminate_job (data);
+ dialog_data_complete_and_unref (data);
+ update_job (data, FALSE);
+ }
+}
+
static gboolean
start_copying (DialogData *data)
{
@@ -717,7 +710,6 @@ start_copying (DialogData *data)
gboolean ret = FALSE;
GFileInfo *info;
GError *error;
- gchar *uri = NULL;
error = NULL;
file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (data->image_fcbutton));
@@ -749,9 +741,6 @@ start_copying (DialogData *data)
data->file_size = g_file_info_get_size (info);
g_object_unref (info);
- uri = gdu_utils_get_pretty_uri (file);
- gtk_label_set_text (GTK_LABEL (data->source_label), uri);
-
data->inhibit_cookie = gtk_application_inhibit (GTK_APPLICATION (gdu_window_get_application (data->window)),
GTK_WINDOW (data->dialog),
GTK_APPLICATION_INHIBIT_SUSPEND |
@@ -759,6 +748,19 @@ start_copying (DialogData *data)
/* Translators: Reason why suspend/logout is being inhibited */
C_("restore-inhibit-message", "Copying disk image to device"));
+ data->local_job = gdu_application_create_local_job (gdu_window_get_application (data->window),
+ data->object);
+ udisks_job_set_operation (UDISKS_JOB (data->local_job), "x-gdu-restore-disk-image");
+ /* Translators: this is the description of the job */
+ gdu_local_job_set_description (data->local_job, _("Restoring Disk Image"));
+ udisks_job_set_progress_valid (UDISKS_JOB (data->local_job), TRUE);
+ udisks_job_set_cancelable (UDISKS_JOB (data->local_job), TRUE);
+ g_signal_connect (data->local_job, "canceled",
+ G_CALLBACK (on_local_job_canceled),
+ data);
+
+ dialog_data_hide (data);
+
g_thread_new ("copy-disk-image-thread",
copy_thread_func,
dialog_data_ref (data));
@@ -766,7 +768,6 @@ start_copying (DialogData *data)
out:
g_clear_object (&file);
- g_free (uri);
return ret;
}
@@ -816,16 +817,6 @@ on_dialog_response (GtkDialog *dialog,
/* now that we know the user picked a folder, update file chooser settings */
gdu_utils_file_chooser_for_disk_images_update_settings (GTK_FILE_CHOOSER (data->image_fcbutton));
- /* now that we advance to the "copy stage", hide/show some more widgets */
- gtk_widget_hide (data->image_key_label);
- gtk_widget_hide (data->image_fcbutton);
- gtk_widget_hide (data->start_copying_button);
- gtk_widget_show (data->source_key_label);
- gtk_widget_show (data->source_label);
- gtk_widget_show (data->copying_key_label);
- gtk_widget_show (data->copying_vbox);
- gtk_widget_hide (data->infobar_vbox);
-
/* ensure the device is unused (e.g. unmounted) before copying data to it... */
gdu_window_ensure_unused (data->window,
data->object,
@@ -834,10 +825,6 @@ on_dialog_response (GtkDialog *dialog,
data);
break;
- case GTK_RESPONSE_CLOSE:
- dialog_data_complete_and_unref (data);
- break;
-
default: /* explicit fallthrough */
case GTK_RESPONSE_CANCEL:
dialog_data_complete_and_unref (data);
@@ -897,18 +884,12 @@ gdu_restore_disk_image_dialog_show (GduWindow *window,
g_signal_connect (data->image_fcbutton, "notify",
G_CALLBACK (on_notify), data);
- /* hide widgets not to be shown initially */
- gtk_widget_hide (data->source_key_label);
- gtk_widget_hide (data->source_label);
- gtk_widget_hide (data->copying_key_label);
- gtk_widget_hide (data->copying_vbox);
- gtk_widget_hide (data->close_button);
+ data->response_signal_handler_id = g_signal_connect (data->dialog,
+ "response",
+ G_CALLBACK (on_dialog_response),
+ data);
- g_signal_connect (data->dialog,
- "response",
- G_CALLBACK (on_dialog_response),
- data);
- gtk_widget_show (data->dialog);
+ gtk_window_set_transient_for (GTK_WINDOW (data->dialog), GTK_WINDOW (window));
gtk_window_present (GTK_WINDOW (data->dialog));
}
diff --git a/src/disks/gdutypes.h b/src/disks/gdutypes.h
index ec62f36..4d0e75b 100644
--- a/src/disks/gdutypes.h
+++ b/src/disks/gdutypes.h
@@ -43,6 +43,9 @@ typedef struct _GduEstimator GduEstimator;
struct GduDVDSupport;
typedef struct GduDVDSupport GduDVDSupport;
+struct GduLocalJob;
+typedef struct GduLocalJob GduLocalJob;
+
G_END_DECLS
#endif /* __GDU_TYPES_H__ */
diff --git a/src/disks/gduvolumegrid.c b/src/disks/gduvolumegrid.c
index 3ba5c62..effde28 100644
--- a/src/disks/gduvolumegrid.c
+++ b/src/disks/gduvolumegrid.c
@@ -16,6 +16,7 @@
#include <stdlib.h>
#include "gduvolumegrid.h"
+#include "gduapplication.h"
/* ---------------------------------------------------------------------------------------------------- */
@@ -83,6 +84,7 @@ struct _GduVolumeGrid
{
GtkWidget parent;
+ GduApplication *application;
UDisksClient *client;
UDisksObject *block_object;
@@ -107,7 +109,7 @@ struct _GduVolumeGridClass
enum
{
PROP_0,
- PROP_CLIENT,
+ PROP_APPLICATION,
PROP_BLOCK_OBJECT,
PROP_NO_MEDIA_STRING,
};
@@ -173,8 +175,8 @@ gdu_volume_grid_get_property (GObject *object,
switch (property_id)
{
- case PROP_CLIENT:
- g_value_set_object (value, grid->client);
+ case PROP_APPLICATION:
+ g_value_set_object (value, grid->application);
break;
case PROP_BLOCK_OBJECT:
@@ -201,8 +203,9 @@ gdu_volume_grid_set_property (GObject *object,
switch (property_id)
{
- case PROP_CLIENT:
- grid->client = g_value_dup_object (value);
+ case PROP_APPLICATION:
+ grid->application = g_value_dup_object (value);
+ grid->client = gdu_application_get_client (grid->application);
break;
case PROP_BLOCK_OBJECT:
@@ -504,11 +507,11 @@ gdu_volume_grid_class_init (GduVolumeGridClass *klass)
gtkwidget_class->draw = gdu_volume_grid_draw;
g_object_class_install_property (gobject_class,
- PROP_CLIENT,
- g_param_spec_object ("client",
- "Client",
- "The UDisksClient to use",
- UDISKS_TYPE_CLIENT,
+ PROP_APPLICATION,
+ g_param_spec_object ("application",
+ "Application",
+ "The GduApplication to use",
+ GDU_TYPE_APPLICATION,
G_PARAM_READABLE |
G_PARAM_WRITABLE |
G_PARAM_CONSTRUCT_ONLY |
@@ -554,11 +557,11 @@ gdu_volume_grid_init (GduVolumeGrid *grid)
}
GtkWidget *
-gdu_volume_grid_new (UDisksClient *client)
+gdu_volume_grid_new (GduApplication *application)
{
- g_return_val_if_fail (UDISKS_IS_CLIENT (client), NULL);
+ g_return_val_if_fail (GDU_IS_APPLICATION (application), NULL);
return GTK_WIDGET (g_object_new (GDU_TYPE_VOLUME_GRID,
- "client", client,
+ "application", application,
NULL));
}
@@ -1613,6 +1616,7 @@ grid_element_set_details (GduVolumeGrid *grid,
element->show_configured = TRUE;
jobs = udisks_client_get_jobs_for_object (grid->client, element->object);
+ jobs = g_list_concat (jobs, gdu_application_get_local_jobs_for_object (grid->application, element->object));
element->show_spinner = (jobs != NULL);
g_list_foreach (jobs, (GFunc) g_object_unref, NULL);
g_list_free (jobs);
diff --git a/src/disks/gduvolumegrid.h b/src/disks/gduvolumegrid.h
index 0489d48..de24e64 100644
--- a/src/disks/gduvolumegrid.h
+++ b/src/disks/gduvolumegrid.h
@@ -20,7 +20,7 @@ G_BEGIN_DECLS
#define GDU_IS_VOLUME_GRID(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDU_TYPE_VOLUME_GRID))
GType gdu_volume_grid_get_type (void) G_GNUC_CONST;
-GtkWidget* gdu_volume_grid_new (UDisksClient *client);
+GtkWidget* gdu_volume_grid_new (GduApplication *application);
void gdu_volume_grid_set_block_object (GduVolumeGrid *grid,
UDisksObject *block_device);
UDisksObject *gdu_volume_grid_get_block_object (GduVolumeGrid *grid);
diff --git a/src/disks/gduwindow.c b/src/disks/gduwindow.c
index 821a0a7..d0840f7 100644
--- a/src/disks/gduwindow.c
+++ b/src/disks/gduwindow.c
@@ -40,6 +40,7 @@
#include "gdumdraiddisksdialog.h"
#include "gducreateraidarraydialog.h"
#include "gduerasemultipledisksdialog.h"
+#include "gdulocaljob.h"
struct _GduWindow
{
@@ -1287,7 +1288,7 @@ gdu_window_constructed (GObject *object)
//gtk_style_context_add_class (context, GTK_STYLE_CLASS_INLINE_TOOLBAR);
gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM);
- window->model = gdu_device_tree_model_new (window->client);
+ window->model = gdu_device_tree_model_new (window->application);
gtk_tree_view_set_model (GTK_TREE_VIEW (window->device_tree_treeview), GTK_TREE_MODEL (window->model));
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (window->model),
@@ -1398,7 +1399,7 @@ gdu_window_constructed (GObject *object)
/* set up non-standard widgets that isn't in the .ui file */
- window->volume_grid = gdu_volume_grid_new (window->client);
+ window->volume_grid = gdu_volume_grid_new (window->application);
gtk_widget_show (window->volume_grid);
gtk_box_pack_start (GTK_BOX (window->devtab_grid_hbox),
window->volume_grid,
@@ -1574,13 +1575,13 @@ gdu_window_constructed (GObject *object)
/* cancel-button for drive job */
g_signal_connect (window->devtab_drive_job_cancel_button,
- "clicked",
+ "pressed",
G_CALLBACK (on_drive_job_cancel_button_clicked),
window);
/* cancel-button for job */
g_signal_connect (window->devtab_job_cancel_button,
- "clicked",
+ "pressed",
G_CALLBACK (on_job_cancel_button_clicked),
window);
@@ -1982,41 +1983,84 @@ static gchar *
get_job_progress_text (GduWindow *window,
UDisksJob *job)
{
- gchar *s;
- gchar *desc;
+ gchar *s = NULL, *tmp;
gint64 expected_end_time_usec;
-
- desc = udisks_client_get_job_description (window->client, job);
+ guint64 rate;
+ guint64 bytes;
expected_end_time_usec = udisks_job_get_expected_end_time (job);
+ rate = udisks_job_get_rate (job);
+ bytes = udisks_job_get_bytes (job);
if (expected_end_time_usec > 0)
{
gint64 usec_left;
gchar *s2, *s3;
usec_left = expected_end_time_usec - g_get_real_time ();
- if (usec_left < 0)
+ if (usec_left < 1)
+ usec_left = 1;
+ s2 = gdu_utils_format_duration_usec (usec_left, GDU_FORMAT_DURATION_FLAGS_NO_SECONDS);
+ if (rate > 0)
{
- /* Translators: Shown instead of e.g. "10 seconds remaining" when we've passed
- * the expected end time...
+ s3 = g_format_size (rate);
+ /* Translators: Used for job progress.
+ * The first %s is the estimated amount of time remaining (ex. "1 minute" or "5 minutes").
+ * The second %s is the average amount of bytes transfered per second (ex. "8.9 MB").
*/
- s3 = g_strdup_printf (C_("job-remaining-exceeded", "Almost doneâ"));
+ s = g_strdup_printf (C_("job-remaining-with-rate", "%s remaining (%s/sec)"), s2, s3);
+ g_free (s3);
}
else
{
- s2 = gdu_utils_format_duration_usec (usec_left, GDU_FORMAT_DURATION_FLAGS_NONE);
- s3 = g_strdup_printf (C_("job-remaining", "%s remaining"), s2);
+ /* Translators: Used for job progress.
+ * The first %s is the estimated amount of time remaining (ex. "1 minute" or "5 minutes").
+ */
+ s = g_strdup_printf (C_("job-remaining", "%s remaining"), s2);
+ }
+ g_free (s2);
+
+ if (bytes > 0 && udisks_job_get_progress_valid (job))
+ {
+ guint64 bytes_done = bytes * udisks_job_get_progress (job);
+ s2 = g_format_size (bytes_done);
+ s3 = g_format_size (bytes);
+ tmp = s;
+ /* Translators: Used to convey job progress where the amount of bytes to process is known.
+ * The first %s is the amount of bytes processed (ex. "650 MB").
+ * The second %s is the total amount of bytes to process (ex. "8.5 GB").
+ * The third %s is the estimated amount of time remaining including speed (if known) (ex. "1 minute remaining", "5 minutes remaining (42.3 MB/s)", "Less than a minute remaining").
+ */
+ s = g_strdup_printf (_("%s of %s â %s"), s2, s3, s);
+ g_free (tmp);
+ g_free (s3);
g_free (s2);
}
- s = g_strdup_printf ("<small>%s â %s</small>", desc, s3);
- g_free (s3);
}
- else
+
+ if (GDU_IS_LOCAL_JOB (job))
{
- s = g_strdup_printf ("<small>%s</small>", desc);
+ const gchar *extra_markup = gdu_local_job_get_extra_markup (GDU_LOCAL_JOB (job));
+ if (extra_markup != NULL)
+ {
+ if (s != NULL)
+ {
+ tmp = s;
+ s = g_strdup_printf ("%s\n%s", s, extra_markup);
+ g_free (tmp);
+ }
+ else
+ {
+ s = g_strdup (extra_markup);
+ }
+ }
}
- g_free (desc);
+ if (s != NULL)
+ {
+ tmp = s;
+ s = g_strdup_printf ("<small>%s</small>", s);
+ g_free (tmp);
+ }
return s;
}
@@ -2024,108 +2068,178 @@ get_job_progress_text (GduWindow *window,
/* ---------------------------------------------------------------------------------------------------- */
static void
-update_drive_jobs (GduWindow *window,
- GList *jobs)
+update_jobs (GduWindow *window,
+ GList *jobs,
+ gboolean is_volume)
{
+ GtkWidget *label = window->devtab_drive_job_label;
+ GtkWidget *grid = window->devtab_drive_job_grid;
+ GtkWidget *progressbar = window->devtab_drive_job_progressbar;
+ GtkWidget *remaining_label = window->devtab_drive_job_remaining_label;
+ GtkWidget *no_progress_label = window->devtab_drive_job_no_progress_label;
+ GtkWidget *cancel_button = window->devtab_drive_job_cancel_button;
+
+ if (is_volume)
+ {
+ label = window->devtab_job_label;
+ grid = window->devtab_job_grid;
+ progressbar = window->devtab_job_progressbar;
+ remaining_label = window->devtab_job_remaining_label;
+ no_progress_label = window->devtab_job_no_progress_label;
+ cancel_button = window->devtab_job_cancel_button;
+ }
+
if (jobs == NULL)
{
- gtk_widget_hide (window->devtab_drive_job_label);
- gtk_widget_hide (window->devtab_drive_job_grid);
+ gtk_widget_hide (label);
+ gtk_widget_hide (grid);
}
else
{
UDisksJob *job = UDISKS_JOB (jobs->data);
- gchar *s;
+ gchar *s, *s2;
- gtk_widget_show (window->devtab_drive_job_label);
- gtk_widget_show (window->devtab_drive_job_grid);
+ gtk_widget_show (label);
+ gtk_widget_show (grid);
if (udisks_job_get_progress_valid (job))
{
gdouble progress = udisks_job_get_progress (job);
- gtk_widget_show (window->devtab_drive_job_progressbar);
- gtk_widget_show (window->devtab_drive_job_remaining_label);
- gtk_widget_hide (window->devtab_drive_job_no_progress_label);
+ gtk_widget_show (progressbar);
+ gtk_widget_hide (no_progress_label);
- gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (window->devtab_drive_job_progressbar), progress);
+ gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progressbar), progress);
- s = g_strdup_printf ("%2.1f%%", 100.0 * progress);
- gtk_progress_bar_set_show_text (GTK_PROGRESS_BAR (window->devtab_drive_job_progressbar), TRUE);
- gtk_progress_bar_set_text (GTK_PROGRESS_BAR (window->devtab_drive_job_progressbar), s);
+ if (GDU_IS_LOCAL_JOB (job))
+ s2 = g_strdup (gdu_local_job_get_description (GDU_LOCAL_JOB (job)));
+ else
+ s2 = udisks_client_get_job_description (window->client, job);
+ /* Translators: Used in job progress bar.
+ * The %s is the job description (e.g. "Erasing Device").
+ * The %f is the completion percentage (between 0.0 and 100.0).
+ */
+ s = g_strdup_printf (_("%s: %2.1f%%"),
+ s2,
+ 100.0 * progress);
+ g_free (s2);
+ gtk_progress_bar_set_show_text (GTK_PROGRESS_BAR (progressbar), TRUE);
+ gtk_progress_bar_set_text (GTK_PROGRESS_BAR (progressbar), s);
g_free (s);
s = get_job_progress_text (window, job);
- gtk_label_set_markup (GTK_LABEL (window->devtab_drive_job_remaining_label), s);
- g_free (s);
+ if (s != NULL)
+ {
+ gtk_widget_show (remaining_label);
+ gtk_label_set_markup (GTK_LABEL (remaining_label), s);
+ g_free (s);
+ }
+ else
+ {
+ gtk_widget_hide (remaining_label);
+ }
}
else
{
- gtk_widget_hide (window->devtab_drive_job_progressbar);
- gtk_widget_hide (window->devtab_drive_job_remaining_label);
- gtk_widget_show (window->devtab_drive_job_no_progress_label);
- s = udisks_client_get_job_description (window->client, job);
- gtk_label_set_text (GTK_LABEL (window->devtab_drive_job_no_progress_label), s);
+ gtk_widget_hide (progressbar);
+ gtk_widget_hide (remaining_label);
+ gtk_widget_show (no_progress_label);
+ if (GDU_IS_LOCAL_JOB (job))
+ s = g_strdup (gdu_local_job_get_description (GDU_LOCAL_JOB (job)));
+ else
+ s = udisks_client_get_job_description (window->client, job);
+ gtk_label_set_text (GTK_LABEL (no_progress_label), s);
g_free (s);
}
if (udisks_job_get_cancelable (job))
- gtk_widget_show (window->devtab_drive_job_cancel_button);
+ gtk_widget_show (cancel_button);
else
- gtk_widget_hide (window->devtab_drive_job_cancel_button);
+ gtk_widget_hide (cancel_button);
}
}
+static void
+update_drive_jobs (GduWindow *window,
+ GList *jobs)
+{
+ update_jobs (window, jobs, FALSE);
+}
+
+static void
+update_volume_jobs (GduWindow *window,
+ GList *jobs)
+{
+ update_jobs (window, jobs, TRUE);
+}
+
/* ---------------------------------------------------------------------------------------------------- */
static void
-update_drive_part_for_block (GduWindow *window,
- UDisksBlock *block, /* should be the whole disk */
- ShowFlags *show_flags)
+update_generic_drive_bits (GduWindow *window,
+ UDisksBlock *block, /* should be the whole disk */
+ GList *jobs, /* jobs not specific to @block */
+ ShowFlags *show_flags)
{
- gchar *s = NULL;
- guint64 size = 0;
- UDisksObject *object = NULL;
- UDisksPartitionTable *partition_table = NULL;
+ if (block != NULL)
+ {
+ gchar *s = NULL;
+ guint64 size = 0;
+ UDisksObject *object = NULL;
+ UDisksPartitionTable *partition_table = NULL;
- object = (UDisksObject *) g_dbus_interface_get_object (G_DBUS_INTERFACE (block));
- if (object == NULL)
- goto out;
- partition_table = udisks_object_get_partition_table (object);
+ object = (UDisksObject *) g_dbus_interface_get_object (G_DBUS_INTERFACE (block));
+ partition_table = udisks_object_get_partition_table (object);
- gdu_volume_grid_set_no_media_string (GDU_VOLUME_GRID (window->volume_grid),
- _("Block device is empty"));
+ gdu_volume_grid_set_no_media_string (GDU_VOLUME_GRID (window->volume_grid),
+ _("Block device is empty"));
- size = udisks_block_get_size (block);
+ size = udisks_block_get_size (block);
- /* -------------------------------------------------- */
- /* 'Size' field */
+ /* -------------------------------------------------- */
+ /* 'Size' field */
- set_size (window,
- "devtab-drive-size-label",
- "devtab-drive-size-value-label",
- size, SET_MARKUP_FLAGS_HYPHEN_IF_EMPTY);
+ set_size (window,
+ "devtab-drive-size-label",
+ "devtab-drive-size-value-label",
+ size, SET_MARKUP_FLAGS_HYPHEN_IF_EMPTY);
- /* -------------------------------------------------- */
- /* 'Partitioning' field - only show if actually partitioned */
+ /* -------------------------------------------------- */
+ /* 'Partitioning' field - only show if actually partitioned */
- s = NULL;
- if (partition_table != NULL)
- {
- const gchar *table_type = udisks_partition_table_get_type_ (partition_table);
- s = g_strdup (udisks_client_get_partition_table_type_for_display (window->client, table_type));
- if (s == NULL)
+ s = NULL;
+ if (partition_table != NULL)
{
- /* Translators: Shown for unknown partitioning type. The first %s is the low-level type. */
- s = g_strdup_printf (C_("partitioning", "Unknown (%s)"), table_type);
+ const gchar *table_type = udisks_partition_table_get_type_ (partition_table);
+ s = g_strdup (udisks_client_get_partition_table_type_for_display (window->client, table_type));
+ if (s == NULL)
+ {
+ /* Translators: Shown for unknown partitioning type. The first %s is the low-level type. */
+ s = g_strdup_printf (C_("partitioning", "Unknown (%s)"), table_type);
+ }
}
+ set_markup (window,
+ "devtab-drive-partitioning-label",
+ "devtab-drive-partitioning-value-label",
+ s, SET_MARKUP_FLAGS_NONE);
+ g_free (s);
+
+ g_clear_object (&partition_table);
}
- set_markup (window,
- "devtab-drive-partitioning-label",
- "devtab-drive-partitioning-value-label",
- s, SET_MARKUP_FLAGS_NONE);
- g_free (s);
- out:
- /* cleanup */
- g_clear_object (&partition_table);
+ /* -------------------------------------------------- */
+ /* 'Job' field - only shown if a job is running */
+
+ /* if there are no given jobs, look at the block object */
+ if (jobs == NULL && block != NULL)
+ {
+ UDisksObject *block_object = (UDisksObject *) g_dbus_interface_get_object (G_DBUS_INTERFACE (block));
+ jobs = udisks_client_get_jobs_for_object (window->client, block_object);
+ jobs = g_list_concat (jobs, gdu_application_get_local_jobs_for_object (window->application, block_object));
+ update_drive_jobs (window, jobs);
+ g_list_free_full (jobs, g_object_unref);
+ }
+ else
+ {
+ update_drive_jobs (window, jobs);
+ }
}
/* ---------------------------------------------------------------------------------------------------- */
@@ -2232,8 +2346,9 @@ update_device_page_for_mdraid (GduWindow *window,
show_flags->drive_buttons |= SHOW_FLAGS_DRIVE_BUTTONS_RAID_START;
}
- if (block != NULL)
- update_drive_part_for_block (window, block, show_flags);
+ jobs = udisks_client_get_jobs_for_object (window->client, object);
+ jobs = g_list_concat (jobs, gdu_application_get_local_jobs_for_object (window->application, object));
+ update_generic_drive_bits (window, block, jobs, show_flags);
gtk_image_set_from_gicon (GTK_IMAGE (window->devtab_drive_image),
udisks_object_info_get_icon (info),
@@ -2511,23 +2626,6 @@ update_device_page_for_mdraid (GduWindow *window,
}
/* -------------------------------------------------- */
- /* 'Job' field - only shown if a job is running */
-
- jobs = udisks_client_get_jobs_for_object (window->client, object);
- /* if there are no jobs on the RAID array, look at the block object if it's partitioned
- * (because: if it's not partitioned, we'll see the job in Volumes below so no need to show it here)
- */
- if (jobs == NULL && block != NULL)
- {
- UDisksObject *block_object = (UDisksObject *) g_dbus_interface_get_object (G_DBUS_INTERFACE (block));
- if (udisks_object_peek_partition_table (block_object) != NULL)
- {
- jobs = udisks_client_get_jobs_for_object (window->client, block_object);
- }
- }
- update_drive_jobs (window, jobs);
-
- /* -------------------------------------------------- */
/* Show MDRaid-specific items */
gtk_widget_show (GTK_WIDGET (window->generic_drive_menu_item_mdraid_sep_1));
@@ -2583,8 +2681,9 @@ update_device_page_for_drive (GduWindow *window,
if (blocks != NULL)
block = udisks_object_peek_block (UDISKS_OBJECT (blocks->data));
- if (block != NULL)
- update_drive_part_for_block (window, block, show_flags);
+ jobs = udisks_client_get_jobs_for_object (window->client, object);
+ jobs = g_list_concat (jobs, gdu_application_get_local_jobs_for_object (window->application, object));
+ update_generic_drive_bits (window, block, jobs, show_flags);
gdu_volume_grid_set_no_media_string (GDU_VOLUME_GRID (window->volume_grid),
_("No Media"));
@@ -2782,14 +2881,6 @@ update_device_page_for_drive (GduWindow *window,
SET_MARKUP_FLAGS_HYPHEN_IF_EMPTY);
}
- jobs = udisks_client_get_jobs_for_object (window->client, object);
- if (jobs != NULL)
- {
- update_drive_jobs (window, jobs);
- g_list_foreach (jobs, (GFunc) g_object_unref, NULL);
- g_list_free (jobs);
- }
-
if (udisks_drive_get_ejectable (drive))
{
show_flags->drive_buttons |= SHOW_FLAGS_DRIVE_BUTTONS_EJECT;
@@ -2821,6 +2912,9 @@ update_device_page_for_drive (GduWindow *window,
g_list_foreach (blocks, (GFunc) g_object_unref, NULL);
g_list_free (blocks);
g_clear_object (&info);
+
+ g_list_foreach (jobs, (GFunc) g_object_unref, NULL);
+ g_list_free (jobs);
}
/* ---------------------------------------------------------------------------------------------------- */
@@ -2861,7 +2955,7 @@ update_device_page_for_loop (GduWindow *window,
gtk_widget_show (window->devtab_drive_buttonbox);
gtk_widget_show (window->devtab_drive_generic_button);
- update_drive_part_for_block (window, block, show_flags);
+ update_generic_drive_bits (window, block, NULL, show_flags);
/* -------------------------------------------------- */
/* 'Auto-clear' and 'Backing File' fields */
@@ -2928,7 +3022,7 @@ update_device_page_for_fake_block (GduWindow *window,
gtk_widget_show (window->devtab_drive_buttonbox);
gtk_widget_show (window->devtab_drive_generic_button);
- update_drive_part_for_block (window, block, show_flags);
+ update_generic_drive_bits (window, block, NULL, show_flags);
/* cleanup */
g_clear_object (&info);
@@ -2991,7 +3085,7 @@ update_device_page_for_block (GduWindow *window,
gchar *in_use_markup = NULL;
UDisksObject *drive_object;
UDisksDrive *drive = NULL;
- GList *jobs;
+ GList *jobs = NULL;
read_only = udisks_block_get_read_only (block);
partition = udisks_object_peek_partition (object);
@@ -3238,50 +3332,15 @@ update_device_page_for_block (GduWindow *window,
show_flags->drive_buttons |= SHOW_FLAGS_DRIVE_BUTTONS_EJECT;
}
- jobs = udisks_client_get_jobs_for_object (window->client, object);
- if (jobs == NULL)
- {
- gtk_widget_hide (window->devtab_job_label);
- gtk_widget_hide (window->devtab_job_grid);
- }
- else
+ /* Only show jobs if the volume is a partition (if it's not, we're already showing
+ * the jobs in the drive section)
+ */
+ if (partition != NULL)
{
- UDisksJob *job = UDISKS_JOB (jobs->data);
-
- gtk_widget_show (window->devtab_job_label);
- gtk_widget_show (window->devtab_job_grid);
- if (udisks_job_get_progress_valid (job))
- {
- gdouble progress = udisks_job_get_progress (job);
- gtk_widget_show (window->devtab_job_progressbar);
- gtk_widget_show (window->devtab_job_remaining_label);
- gtk_widget_hide (window->devtab_job_no_progress_label);
-
- gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (window->devtab_job_progressbar), progress);
-
- s = g_strdup_printf ("%2.1f%%", 100.0 * progress);
- gtk_progress_bar_set_show_text (GTK_PROGRESS_BAR (window->devtab_job_progressbar), TRUE);
- gtk_progress_bar_set_text (GTK_PROGRESS_BAR (window->devtab_job_progressbar), s);
- g_free (s);
-
- s = get_job_progress_text (window, job);
- gtk_label_set_markup (GTK_LABEL (window->devtab_job_remaining_label), s);
- g_free (s);
- }
- else
- {
- gtk_widget_hide (window->devtab_job_progressbar);
- gtk_widget_hide (window->devtab_job_remaining_label);
- gtk_widget_show (window->devtab_job_no_progress_label);
- s = udisks_client_get_job_description (window->client, job);
- gtk_label_set_text (GTK_LABEL (window->devtab_job_no_progress_label), s);
- g_free (s);
- }
- if (udisks_job_get_cancelable (job))
- gtk_widget_show (window->devtab_job_cancel_button);
- else
- gtk_widget_hide (window->devtab_job_cancel_button);
+ jobs = udisks_client_get_jobs_for_object (window->client, object);
+ jobs = g_list_concat (jobs, gdu_application_get_local_jobs_for_object (window->application, object));
}
+ update_volume_jobs (window, jobs);
g_list_foreach (jobs, (GFunc) g_object_unref, NULL);
g_list_free (jobs);
g_clear_object (&partition_table);
@@ -4651,6 +4710,7 @@ on_drive_job_cancel_button_clicked (GtkButton *button,
GList *jobs;
jobs = udisks_client_get_jobs_for_object (window->client, window->current_object);
+ jobs = g_list_concat (jobs, gdu_application_get_local_jobs_for_object (window->application, window->current_object));
/* if there are no jobs on the drive, look at the first block object */
if (jobs == NULL)
{
@@ -4661,6 +4721,7 @@ on_drive_job_cancel_button_clicked (GtkButton *button,
{
UDisksObject *block_object = UDISKS_OBJECT (blocks->data);
jobs = udisks_client_get_jobs_for_object (window->client, block_object);
+ jobs = g_list_concat (jobs, gdu_application_get_local_jobs_for_object (window->application, block_object));
}
g_list_foreach (blocks, (GFunc) g_object_unref, NULL);
g_list_free (blocks);
@@ -4668,11 +4729,18 @@ on_drive_job_cancel_button_clicked (GtkButton *button,
if (jobs != NULL)
{
UDisksJob *job = UDISKS_JOB (jobs->data);
- udisks_job_call_cancel (job,
- g_variant_new ("a{sv}", NULL), /* options */
- NULL, /* cancellable */
- (GAsyncReadyCallback) drive_job_cancel_cb,
- g_object_ref (window));
+ if (GDU_IS_LOCAL_JOB (job))
+ {
+ gdu_local_job_canceled (GDU_LOCAL_JOB (job));
+ }
+ else
+ {
+ udisks_job_call_cancel (job,
+ g_variant_new ("a{sv}", NULL), /* options */
+ NULL, /* cancellable */
+ (GAsyncReadyCallback) drive_job_cancel_cb,
+ g_object_ref (window));
+ }
}
g_list_foreach (jobs, (GFunc) g_object_unref, NULL);
g_list_free (jobs);
@@ -4710,14 +4778,22 @@ on_job_cancel_button_clicked (GtkButton *button,
g_assert (object != NULL);
jobs = udisks_client_get_jobs_for_object (window->client, object);
+ jobs = g_list_concat (jobs, gdu_application_get_local_jobs_for_object (window->application, object));
if (jobs != NULL)
{
UDisksJob *job = UDISKS_JOB (jobs->data);
- udisks_job_call_cancel (job,
- g_variant_new ("a{sv}", NULL), /* options */
- NULL, /* cancellable */
- (GAsyncReadyCallback) job_cancel_cb,
- g_object_ref (window));
+ if (GDU_IS_LOCAL_JOB (job))
+ {
+ gdu_local_job_canceled (GDU_LOCAL_JOB (job));
+ }
+ else
+ {
+ udisks_job_call_cancel (job,
+ g_variant_new ("a{sv}", NULL), /* options */
+ NULL, /* cancellable */
+ (GAsyncReadyCallback) job_cancel_cb,
+ g_object_ref (window));
+ }
}
g_list_foreach (jobs, (GFunc) g_object_unref, NULL);
g_list_free (jobs);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]