[libpanel/wip/chergert/fix-14] save-delegate: add close signal
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libpanel/wip/chergert/fix-14] save-delegate: add close signal
- Date: Tue, 13 Sep 2022 18:25:16 +0000 (UTC)
commit 120af7ac9bec650ef3c253661ac0fbc5fa7207f2
Author: Christian Hergert <chergert redhat com>
Date: Tue Sep 13 11:20:46 2022 -0700
save-delegate: add close signal
This is similar to discard but only requests the page be closed, it does
not request that the contents be dropped.
src/panel-save-delegate.c | 29 ++++++++++++++
src/panel-save-delegate.h | 3 ++
src/panel-save-dialog.c | 96 ++++++++++++++++++++++++++++++++++++++++++++---
3 files changed, 122 insertions(+), 6 deletions(-)
---
diff --git a/src/panel-save-delegate.c b/src/panel-save-delegate.c
index 1821ac7..9d4a9dd 100644
--- a/src/panel-save-delegate.c
+++ b/src/panel-save-delegate.c
@@ -47,6 +47,7 @@ enum {
};
enum {
+ CLOSE,
DISCARD,
SAVE,
N_SIGNALS
@@ -330,6 +331,26 @@ panel_save_delegate_class_init (PanelSaveDelegateClass *klass)
NULL,
G_TYPE_BOOLEAN, 1, G_TYPE_TASK);
+ /**
+ * PanelSaveDelegate::close:
+ * @self: a #PanelSaveDelegate
+ *
+ * This signal is emitted when the save delegate should close
+ * the widget it is related to. This can happen after saving as
+ * part of a close request and it is now save for the delegate to
+ * close.
+ *
+ * Implementations are encouraged to connect to this signal (or
+ * implement the virtual method) and call panel_widget_force_close().
+ */
+ signals [CLOSE] = g_signal_new ("close",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (PanelSaveDelegateClass, close),
+ NULL, NULL,
+ NULL,
+ G_TYPE_NONE, 0);
+
/**
* PanelSaveDelegate::discard:
* @self: a #PanelSaveDelegate
@@ -593,6 +614,14 @@ panel_save_delegate_set_is_draft (PanelSaveDelegate *self,
}
}
+void
+panel_save_delegate_close (PanelSaveDelegate *self)
+{
+ g_return_if_fail (PANEL_IS_SAVE_DELEGATE (self));
+
+ g_signal_emit (self, signals [CLOSE], 0);
+}
+
void
panel_save_delegate_discard (PanelSaveDelegate *self)
{
diff --git a/src/panel-save-delegate.h b/src/panel-save-delegate.h
index 2a5d2a3..9242cdb 100644
--- a/src/panel-save-delegate.h
+++ b/src/panel-save-delegate.h
@@ -45,6 +45,7 @@ struct _PanelSaveDelegateClass
gboolean (*save) (PanelSaveDelegate *self,
GTask *task);
void (*discard) (PanelSaveDelegate *self);
+ void (*close) (PanelSaveDelegate *self);
/*< private >*/
gpointer _reserved[8];
@@ -92,6 +93,8 @@ gboolean panel_save_delegate_save_finish (PanelSaveDelegate *self
GAsyncResult *result,
GError **error);
PANEL_AVAILABLE_IN_ALL
+void panel_save_delegate_close (PanelSaveDelegate *self);
+PANEL_AVAILABLE_IN_ALL
void panel_save_delegate_discard (PanelSaveDelegate *self);
G_END_DECLS
diff --git a/src/panel-save-dialog.c b/src/panel-save-dialog.c
index d795df7..0ca68cf 100644
--- a/src/panel-save-dialog.c
+++ b/src/panel-save-dialog.c
@@ -37,8 +37,23 @@ struct _PanelSaveDialog
GTask *task;
};
+typedef struct
+{
+ GPtrArray *delegates;
+ guint n_active;
+} Save;
+
G_DEFINE_FINAL_TYPE (PanelSaveDialog, panel_save_dialog, ADW_TYPE_MESSAGE_DIALOG)
+static void
+save_free (gpointer data)
+{
+ Save *save = data;
+
+ g_clear_pointer (&save->delegates, g_ptr_array_unref);
+ g_slice_free (Save, save);
+}
+
/**
* panel_save_dialog_new:
*
@@ -95,22 +110,73 @@ panel_save_dialog_response_discard_cb (PanelSaveDialog *self,
g_clear_object (&task);
}
+static void
+panel_save_dialog_save_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ PanelSaveDelegate *delegate = (PanelSaveDelegate *)object;
+ GTask *task = user_data;
+ GError *error = NULL;
+ Save *save;
+
+ g_assert (PANEL_IS_SAVE_DELEGATE (delegate));
+ g_assert (G_IS_ASYNC_RESULT (result));
+ g_assert (G_IS_TASK (task));
+
+ save = g_task_get_task_data (task);
+ save->n_active--;
+
+ if (!panel_save_delegate_save_finish (delegate, result, &error))
+ {
+ if (!g_task_had_error (task))
+ g_task_return_error (task, g_steal_pointer (&error));
+ }
+
+ if (save->n_active == 0)
+ {
+ if (!g_task_had_error (task))
+ g_task_return_boolean (task, TRUE);
+ }
+
+ g_clear_object (&task);
+ g_clear_error (&error);
+}
+
static void
panel_save_dialog_response_save_cb (PanelSaveDialog *self,
const char *response)
{
- GTask *task;
+ Save *save;
g_assert (PANEL_IS_SAVE_DIALOG (self));
+ g_assert (self->task != NULL);
- task = g_steal_pointer (&self->task);
+ adw_message_dialog_set_response_enabled (ADW_MESSAGE_DIALOG (self), "save", FALSE);
+ adw_message_dialog_set_response_enabled (ADW_MESSAGE_DIALOG (self), "discard", FALSE);
- /* TODO: Save using delegates */
- g_task_return_boolean (task, TRUE);
+ save = g_slice_new0 (Save);
+ save->delegates = g_ptr_array_new_with_free_func (g_object_unref);
+ g_task_set_task_data (self->task, save, save_free);
- gtk_window_destroy (GTK_WINDOW (self));
+ for (guint i = 0; i < self->rows->len; i++)
+ {
+ PanelSaveDialogRow *row = g_ptr_array_index (self->rows, i);
+ PanelSaveDelegate *delegate = panel_save_dialog_row_get_delegate (row);
- g_clear_object (&task);
+ if (!panel_save_dialog_row_get_selected (row))
+ continue;
+
+ g_ptr_array_add (save->delegates, g_object_ref (delegate));
+
+ panel_save_delegate_save_async (delegate,
+ g_task_get_cancellable (self->task),
+ panel_save_dialog_save_cb,
+ g_object_ref (self->task));
+ }
+
+ if (save->delegates->len == 0)
+ g_task_return_boolean (self->task, TRUE);
}
static void
@@ -328,6 +394,18 @@ panel_save_dialog_add_delegate (PanelSaveDialog *self,
panel_save_dialog_update (self);
}
+static void
+task_completed_cb (PanelSaveDialog *self,
+ GParamSpec *pspec,
+ GTask *task)
+{
+ g_assert (PANEL_IS_SAVE_DIALOG (self));
+ g_assert (G_IS_TASK (task));
+
+ if (self->task == task)
+ g_clear_object (&self->task);
+}
+
void
panel_save_dialog_run_async (PanelSaveDialog *self,
GCancellable *cancellable,
@@ -344,6 +422,12 @@ panel_save_dialog_run_async (PanelSaveDialog *self,
task = g_task_new (self, cancellable, callback, user_data);
g_task_set_source_tag (task, panel_save_dialog_run_async);
+ g_signal_connect_object (task,
+ "notify::complete",
+ G_CALLBACK (task_completed_cb),
+ self,
+ G_CONNECT_SWAPPED);
+
if (self->rows->len == 0)
{
gtk_window_destroy (GTK_WINDOW (self));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]