[gnome-builder] genesis: unify genesis of directory and git projects
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] genesis: unify genesis of directory and git projects
- Date: Mon, 21 Dec 2015 07:56:28 +0000 (UTC)
commit 1cd53ca754ffa7b14d27210c044f0a7c41aa57aa
Author: Christian Hergert <chergert redhat com>
Date: Tue Dec 1 17:32:26 2015 -0800
genesis: unify genesis of directory and git projects
This moves more plumbing to the header bar instead of individual workflows
for each genesis addin.
data/ui/ide-genesis-perspective.ui | 15 +++-
libide/directory/ide-directory-genesis-addin.c | 123 +++++++++++++++++++++++-
libide/genesis/ide-genesis-addin.c | 28 +++++
libide/genesis/ide-genesis-addin.h | 26 ++++-
libide/genesis/ide-genesis-perspective.c | 84 +++++++++++++++-
plugins/git/ide-git-clone-widget.c | 127 ++++++++++++++++--------
plugins/git/ide-git-clone-widget.h | 8 ++
plugins/git/ide-git-clone-widget.ui | 29 ------
plugins/git/ide-git-genesis-addin.c | 117 ++++++++++++++++++++--
9 files changed, 471 insertions(+), 86 deletions(-)
---
diff --git a/data/ui/ide-genesis-perspective.ui b/data/ui/ide-genesis-perspective.ui
index fd65884..d1c2937 100644
--- a/data/ui/ide-genesis-perspective.ui
+++ b/data/ui/ide-genesis-perspective.ui
@@ -36,7 +36,7 @@
<property name="show-close-button">true</property>
<property name="visible">true</property>
<child>
- <object class="GtkButton">
+ <object class="GtkButton" id="cancel_button">
<property name="action-name">perspective.go-previous</property>
<property name="visible">true</property>
<style>
@@ -56,5 +56,18 @@
<property name="visible">true</property>
</object>
</child>
+ <child>
+ <object class="GtkButton" id="continue_button">
+ <property name="label" translatable="yes">Co_ntinue</property>
+ <property name="use-underline">true</property>
+ <property name="sensitive">false</property>
+ <style>
+ <class name="suggested-action"/>
+ </style>
+ </object>
+ <packing>
+ <property name="pack-type">end</property>
+ </packing>
+ </child>
</object>
</interface>
diff --git a/libide/directory/ide-directory-genesis-addin.c b/libide/directory/ide-directory-genesis-addin.c
index 6c347df..7832a09 100644
--- a/libide/directory/ide-directory-genesis-addin.c
+++ b/libide/directory/ide-directory-genesis-addin.c
@@ -21,11 +21,13 @@
#include "ide-directory-genesis-addin.h"
#include "ide-genesis-addin.h"
+#include "ide-gtk.h"
+#include "ide-workbench.h"
struct _IdeDirectoryGenesisAddin
{
GObject parent_instance;
-
+ guint is_ready : 1;
GtkFileChooserWidget *widget;
};
@@ -34,9 +36,57 @@ static void genesis_addin_iface_init (IdeGenesisAddinInterface *iface);
G_DEFINE_TYPE_EXTENDED (IdeDirectoryGenesisAddin, ide_directory_genesis_addin, G_TYPE_OBJECT, 0,
G_IMPLEMENT_INTERFACE (IDE_TYPE_GENESIS_ADDIN, genesis_addin_iface_init))
+enum {
+ PROP_0,
+ PROP_IS_READY,
+ LAST_PROP
+};
+
+static gboolean
+ide_directory_genesis_addin_get_is_ready (IdeDirectoryGenesisAddin *self)
+{
+ g_autoptr(GFile) file = NULL;
+
+ g_assert (IDE_IS_DIRECTORY_GENESIS_ADDIN (self));
+
+ file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (self->widget));
+
+ return (file != NULL);
+}
+
+static void
+ide_directory_genesis_addin_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ IdeDirectoryGenesisAddin *self = IDE_DIRECTORY_GENESIS_ADDIN(object);
+
+ switch (prop_id)
+ {
+ case PROP_IS_READY:
+ g_value_set_boolean (value, ide_directory_genesis_addin_get_is_ready (self));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ }
+}
+
static void
ide_directory_genesis_addin_class_init (IdeDirectoryGenesisAddinClass *klass)
{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->get_property = ide_directory_genesis_addin_get_property;
+
+ g_object_class_install_property (object_class,
+ PROP_IS_READY,
+ g_param_spec_boolean ("is-ready",
+ "Is Ready",
+ "Is Ready",
+ FALSE,
+ (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)));
}
static void
@@ -57,6 +107,16 @@ ide_directory_genesis_addin_get_title (IdeGenesisAddin *addin)
}
static void
+ide_directory_genesis_addin_selection_changed (IdeDirectoryGenesisAddin *self,
+ GtkFileChooserWidget *chooser)
+{
+ g_assert (IDE_IS_DIRECTORY_GENESIS_ADDIN (self));
+ g_assert (GTK_IS_FILE_CHOOSER_WIDGET (chooser));
+
+ g_object_notify (G_OBJECT (self), "is-ready");
+}
+
+static void
ide_directory_genesis_addin_add_filters (GtkFileChooser *chooser)
{
PeasEngine *engine = peas_engine_get_default ();
@@ -125,6 +185,11 @@ ide_directory_genesis_addin_get_widget (IdeGenesisAddin *addin)
"action", GTK_FILE_CHOOSER_ACTION_OPEN,
"visible", TRUE,
NULL);
+ g_signal_connect_object (self->widget,
+ "selection-changed",
+ G_CALLBACK (ide_directory_genesis_addin_selection_changed),
+ self,
+ G_CONNECT_SWAPPED);
ide_directory_genesis_addin_add_filters (GTK_FILE_CHOOSER (self->widget));
}
@@ -132,9 +197,65 @@ ide_directory_genesis_addin_get_widget (IdeGenesisAddin *addin)
}
static void
+ide_directory_genesis_addin_run_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ IdeWorkbench *workbench = (IdeWorkbench *)object;
+ g_autoptr(GTask) task = user_data;
+ GError *error = NULL;
+
+ g_assert (IDE_IS_WORKBENCH (workbench));
+ g_assert (G_IS_TASK (task));
+
+ if (!ide_workbench_open_project_finish (workbench, result, &error))
+ g_task_return_error (task, error);
+ else
+ g_task_return_boolean (task, TRUE);
+}
+
+static void
+ide_directory_genesis_addin_run_async (IdeGenesisAddin *addin,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ IdeDirectoryGenesisAddin *self = (IdeDirectoryGenesisAddin *)addin;
+ g_autoptr(GTask) task = NULL;
+ g_autoptr(GFile) project_file = NULL;
+ IdeWorkbench *workbench;
+
+ g_assert (IDE_IS_DIRECTORY_GENESIS_ADDIN (self));
+ g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ task = g_task_new (self, cancellable, callback, user_data);
+ workbench = ide_widget_get_workbench (GTK_WIDGET (self->widget));
+ project_file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (self->widget));
+
+ ide_workbench_open_project_async (workbench,
+ project_file,
+ cancellable,
+ ide_directory_genesis_addin_run_cb,
+ g_object_ref (task));
+}
+
+static gboolean
+ide_directory_genesis_addin_run_finish (IdeGenesisAddin *addin,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (IDE_IS_DIRECTORY_GENESIS_ADDIN (addin), FALSE);
+ g_return_val_if_fail (G_IS_TASK (result), FALSE);
+
+ return g_task_propagate_boolean (G_TASK (result), error);
+}
+
+static void
genesis_addin_iface_init (IdeGenesisAddinInterface *iface)
{
iface->get_title = ide_directory_genesis_addin_get_title;
iface->get_icon_name = ide_directory_genesis_addin_get_icon_name;
iface->get_widget = ide_directory_genesis_addin_get_widget;
+ iface->run_async = ide_directory_genesis_addin_run_async;
+ iface->run_finish = ide_directory_genesis_addin_run_finish;
}
diff --git a/libide/genesis/ide-genesis-addin.c b/libide/genesis/ide-genesis-addin.c
index 14a0b8e..f5004a2 100644
--- a/libide/genesis/ide-genesis-addin.c
+++ b/libide/genesis/ide-genesis-addin.c
@@ -23,6 +23,12 @@ G_DEFINE_INTERFACE (IdeGenesisAddin, ide_genesis_addin, G_TYPE_OBJECT)
static void
ide_genesis_addin_default_init (IdeGenesisAddinInterface *iface)
{
+ g_object_interface_install_property (iface,
+ g_param_spec_boolean ("is-ready",
+ "Is Ready",
+ "If the project genesis can be executed",
+ FALSE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
}
gchar *
@@ -53,3 +59,25 @@ ide_genesis_addin_get_widget (IdeGenesisAddin *self)
return IDE_GENESIS_ADDIN_GET_IFACE (self)->get_widget (self);
}
+
+void
+ide_genesis_addin_run_async (IdeGenesisAddin *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail (IDE_IS_GENESIS_ADDIN (self));
+ g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ IDE_GENESIS_ADDIN_GET_IFACE (self)->run_async (self, cancellable, callback, user_data);
+}
+
+gboolean
+ide_genesis_addin_run_finish (IdeGenesisAddin *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (IDE_IS_GENESIS_ADDIN (self), FALSE);
+
+ return IDE_GENESIS_ADDIN_GET_IFACE (self)->run_finish (self, result, error);
+}
diff --git a/libide/genesis/ide-genesis-addin.h b/libide/genesis/ide-genesis-addin.h
index 34d030c..d7fefab 100644
--- a/libide/genesis/ide-genesis-addin.h
+++ b/libide/genesis/ide-genesis-addin.h
@@ -31,14 +31,28 @@ struct _IdeGenesisAddinInterface
{
GTypeInterface parent_interface;
- gchar *(*get_title) (IdeGenesisAddin *self);
- gchar *(*get_icon_name) (IdeGenesisAddin *self);
- GtkWidget *(*get_widget) (IdeGenesisAddin *self);
+ gchar *(*get_title) (IdeGenesisAddin *self);
+ gchar *(*get_icon_name) (IdeGenesisAddin *self);
+ GtkWidget *(*get_widget) (IdeGenesisAddin *self);
+ void (*run_async) (IdeGenesisAddin *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*run_finish) (IdeGenesisAddin *self,
+ GAsyncResult *result,
+ GError **error);
};
-gchar *ide_genesis_addin_get_title (IdeGenesisAddin *self);
-gchar *ide_genesis_addin_get_icon_name (IdeGenesisAddin *self);
-GtkWidget *ide_genesis_addin_get_widget (IdeGenesisAddin *self);
+gchar *ide_genesis_addin_get_title (IdeGenesisAddin *self);
+gchar *ide_genesis_addin_get_icon_name (IdeGenesisAddin *self);
+GtkWidget *ide_genesis_addin_get_widget (IdeGenesisAddin *self);
+void ide_genesis_addin_run_async (IdeGenesisAddin *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean ide_genesis_addin_run_finish (IdeGenesisAddin *self,
+ GAsyncResult *result,
+ GError **error);
G_END_DECLS
diff --git a/libide/genesis/ide-genesis-perspective.c b/libide/genesis/ide-genesis-perspective.c
index 55cd264..1d11c14 100644
--- a/libide/genesis/ide-genesis-perspective.c
+++ b/libide/genesis/ide-genesis-perspective.c
@@ -22,6 +22,7 @@
#include "ide-genesis-addin.h"
#include "ide-genesis-perspective.h"
#include "ide-gtk.h"
+#include "ide-macros.h"
#include "ide-workbench.h"
struct _IdeGenesisPerspective
@@ -30,11 +31,15 @@ struct _IdeGenesisPerspective
GActionGroup *actions;
PeasExtensionSet *addins;
+ GBinding *continue_binding;
+ IdeGenesisAddin *current_addin;
GtkHeaderBar *header_bar;
GtkListBox *list_box;
GtkWidget *main_page;
GtkStack *stack;
+ GtkButton *continue_button;
+ GtkButton *cancel_button;
};
static void perspective_iface_init (IdePerspectiveInterface *iface);
@@ -145,6 +150,7 @@ ide_genesis_perspective_row_activated (IdeGenesisPerspective *self,
{
IdeGenesisAddin *addin;
GtkWidget *child;
+ GBinding *binding;
g_assert (GTK_IS_LIST_BOX (list_box));
g_assert (GTK_IS_LIST_BOX_ROW (row));
@@ -158,7 +164,65 @@ ide_genesis_perspective_row_activated (IdeGenesisPerspective *self,
if (child == NULL)
return;
+ binding = g_object_bind_property (addin, "is-ready",
+ self->continue_button, "sensitive",
+ G_BINDING_SYNC_CREATE);
+ ide_set_weak_pointer (&self->continue_binding, binding);
+
+ gtk_widget_show (GTK_WIDGET (self->continue_button));
+ gtk_header_bar_set_show_close_button (self->header_bar, FALSE);
+
gtk_stack_set_visible_child (self->stack, child);
+
+ self->current_addin = addin;
+}
+
+static void
+ide_genesis_perspective_run_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ IdeGenesisAddin *addin = (IdeGenesisAddin *)object;
+ g_autoptr(IdeGenesisPerspective) self = user_data;
+ g_autoptr(GError) error = NULL;
+
+ g_assert (IDE_IS_GENESIS_ADDIN (addin));
+ g_assert (IDE_IS_GENESIS_PERSPECTIVE (self));
+
+ if (!ide_genesis_addin_run_finish (addin, result, &error))
+ {
+ GtkWidget *dialog;
+
+ dialog = gtk_message_dialog_new (NULL,
+ GTK_DIALOG_USE_HEADER_BAR,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ _("Failed to load the project"));
+ g_object_set (dialog,
+ "secondary-text", error->message,
+ NULL);
+
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+
+ /*
+ * TODO: Destroy workbench.
+ */
+ }
+}
+
+static void
+ide_genesis_perspective_continue_clicked (IdeGenesisPerspective *self,
+ GtkButton *button)
+{
+ g_assert (IDE_IS_GENESIS_PERSPECTIVE (self));
+ g_assert (GTK_IS_BUTTON (button));
+ g_assert (self->current_addin != NULL);
+
+ ide_genesis_addin_run_async (self->current_addin,
+ NULL,
+ ide_genesis_perspective_run_cb,
+ g_object_ref (self));
}
static void
@@ -178,10 +242,17 @@ ide_genesis_perspective_constructed (GObject *object)
"extension-added",
G_CALLBACK (ide_genesis_perspective_addin_added),
self);
+
g_signal_connect (self->addins,
"extension-removed",
G_CALLBACK (ide_genesis_perspective_addin_removed),
self);
+
+ g_signal_connect_object (self->continue_button,
+ "clicked",
+ G_CALLBACK (ide_genesis_perspective_continue_clicked),
+ self,
+ G_CONNECT_SWAPPED);
}
static void
@@ -207,10 +278,12 @@ ide_genesis_perspective_class_init (IdeGenesisPerspectiveClass *klass)
gtk_widget_class_set_css_name (widget_class, "genesisperspective");
gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/builder/ui/ide-genesis-perspective.ui");
+ gtk_widget_class_bind_template_child (widget_class, IdeGenesisPerspective, cancel_button);
+ gtk_widget_class_bind_template_child (widget_class, IdeGenesisPerspective, continue_button);
+ gtk_widget_class_bind_template_child (widget_class, IdeGenesisPerspective, header_bar);
gtk_widget_class_bind_template_child (widget_class, IdeGenesisPerspective, list_box);
gtk_widget_class_bind_template_child (widget_class, IdeGenesisPerspective, main_page);
gtk_widget_class_bind_template_child (widget_class, IdeGenesisPerspective, stack);
- gtk_widget_class_bind_template_child (widget_class, IdeGenesisPerspective, header_bar);
}
static void
@@ -256,6 +329,15 @@ go_previous (GSimpleAction *action,
g_assert (IDE_IS_GENESIS_PERSPECTIVE (self));
+ if (self->continue_binding)
+ {
+ g_binding_unbind (self->continue_binding);
+ ide_clear_weak_pointer (&self->continue_binding);
+ }
+
+ gtk_widget_hide (GTK_WIDGET (self->continue_button));
+ gtk_header_bar_set_show_close_button (self->header_bar, TRUE);
+
visible_child = gtk_stack_get_visible_child (self->stack);
if (visible_child != self->main_page)
diff --git a/plugins/git/ide-git-clone-widget.c b/plugins/git/ide-git-clone-widget.c
index 404d780..29f55bb 100644
--- a/plugins/git/ide-git-clone-widget.c
+++ b/plugins/git/ide-git-clone-widget.c
@@ -34,21 +34,26 @@ struct _IdeGitCloneWidget
GtkFileChooserButton *clone_location_button;
GtkEntry *clone_location_entry;
GtkEntry *clone_uri_entry;
- GtkButton *clone_button;
GtkLabel *clone_error_label;
GtkProgressBar *clone_progress;
- GtkSpinner *clone_spinner;
+
+ guint is_ready : 1;
};
typedef struct
{
gchar *uri;
GFile *location;
+ GFile *project_file;
} CloneRequest;
-G_DEFINE_TYPE (IdeGitCloneWidget, ide_git_clone_widget, GTK_TYPE_BIN)
+enum {
+ PROP_0,
+ PROP_IS_READY,
+ LAST_PROP
+};
-static void ide_git_clone_widget_begin_clone (IdeGitCloneWidget *self);
+G_DEFINE_TYPE (IdeGitCloneWidget, ide_git_clone_widget, GTK_TYPE_BIN)
static void
clone_request_free (gpointer data)
@@ -59,6 +64,7 @@ clone_request_free (gpointer data)
{
g_clear_pointer (&req->uri, g_free);
g_clear_object (&req->location);
+ g_clear_object (&req->project_file);
g_slice_free (CloneRequest, req);
}
}
@@ -75,6 +81,7 @@ clone_request_new (const gchar *uri,
req = g_slice_new0 (CloneRequest);
req->uri = g_strdup (uri);
req->location = g_object_ref (location);
+ req->project_file = NULL;
return req;
}
@@ -85,6 +92,7 @@ ide_git_clone_widget_uri_changed (IdeGitCloneWidget *self,
{
g_autoptr(IdeVcsUri) uri = NULL;
const gchar *text;
+ gboolean is_ready = FALSE;
g_assert (IDE_IS_GIT_CLONE_WIDGET (self));
g_assert (GTK_IS_ENTRY (entry));
@@ -113,6 +121,8 @@ ide_git_clone_widget_uri_changed (IdeGitCloneWidget *self,
gtk_entry_set_text (self->clone_location_entry, name);
g_free (name);
}
+
+ is_ready = TRUE;
}
else
{
@@ -121,22 +131,37 @@ ide_git_clone_widget_uri_changed (IdeGitCloneWidget *self,
"secondary-icon-tooltip-text", _("A valid Git URL is required"),
NULL);
}
+
+ if (is_ready != self->is_ready)
+ {
+ self->is_ready = is_ready;
+ g_object_notify (G_OBJECT (self), "is-ready");
+ }
}
static void
-ide_git_clone_widget_clone_button_clicked (IdeGitCloneWidget *self,
- GtkButton *button)
+ide_git_clone_widget_finalize (GObject *object)
{
- g_assert (IDE_IS_GIT_CLONE_WIDGET (self));
- g_assert (GTK_IS_BUTTON (button));
-
- ide_git_clone_widget_begin_clone (self);
+ G_OBJECT_CLASS (ide_git_clone_widget_parent_class)->finalize (object);
}
static void
-ide_git_clone_widget_finalize (GObject *object)
+ide_git_clone_widget_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- G_OBJECT_CLASS (ide_git_clone_widget_parent_class)->finalize (object);
+ IdeGitCloneWidget *self = IDE_GIT_CLONE_WIDGET(object);
+
+ switch (prop_id)
+ {
+ case PROP_IS_READY:
+ g_value_set_boolean (value, self->is_ready);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ }
}
static void
@@ -146,15 +171,22 @@ ide_git_clone_widget_class_init (IdeGitCloneWidgetClass *klass)
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->finalize = ide_git_clone_widget_finalize;
+ object_class->get_property = ide_git_clone_widget_get_property;
+
+ g_object_class_install_property (object_class,
+ PROP_IS_READY,
+ g_param_spec_boolean ("is-ready",
+ "Is Ready",
+ "If the widget is ready to continue.",
+ FALSE,
+ (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)));
gtk_widget_class_set_css_name (widget_class, "gitclonewidget");
gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/builder/plugins/git/ide-git-clone-widget.ui");
- gtk_widget_class_bind_template_child (widget_class, IdeGitCloneWidget, clone_button);
gtk_widget_class_bind_template_child (widget_class, IdeGitCloneWidget, clone_error_label);
gtk_widget_class_bind_template_child (widget_class, IdeGitCloneWidget, clone_location_button);
gtk_widget_class_bind_template_child (widget_class, IdeGitCloneWidget, clone_location_entry);
gtk_widget_class_bind_template_child (widget_class, IdeGitCloneWidget, clone_progress);
- gtk_widget_class_bind_template_child (widget_class, IdeGitCloneWidget, clone_spinner);
gtk_widget_class_bind_template_child (widget_class, IdeGitCloneWidget, clone_uri_entry);
}
@@ -175,12 +207,6 @@ ide_git_clone_widget_init (IdeGitCloneWidget *self)
G_CALLBACK (ide_git_clone_widget_uri_changed),
self,
G_CONNECT_SWAPPED);
-
- g_signal_connect_object (self->clone_button,
- "clicked",
- G_CALLBACK (ide_git_clone_widget_clone_button_clicked),
- self,
- G_CONNECT_SWAPPED);
}
static gboolean
@@ -191,19 +217,20 @@ open_after_timeout (gpointer user_data)
g_autoptr(GTask) task = user_data;
g_autoptr(GFile) file = NULL;
g_autoptr(GError) error = NULL;
+ CloneRequest *req;
+
+ IDE_ENTRY;
g_assert (G_IS_TASK (task));
self = g_task_get_source_object (task);
+ req = g_task_get_task_data (task);
workbench = ide_widget_get_workbench (GTK_WIDGET (self));
+ g_assert (req != NULL);
g_assert (IDE_IS_GIT_CLONE_WIDGET (self));
g_assert (IDE_IS_WORKBENCH (workbench));
- gtk_widget_hide (GTK_WIDGET (self->clone_spinner));
-
- file = g_task_propagate_pointer (task, &error);
-
if (error)
{
g_warning ("%s", error->message);
@@ -212,22 +239,25 @@ open_after_timeout (gpointer user_data)
}
else
{
- ide_workbench_open_project_async (workbench, file, NULL, NULL, NULL);
+ ide_workbench_open_project_async (workbench, req->project_file, NULL, NULL, NULL);
}
- return G_SOURCE_REMOVE;
+ g_task_return_boolean (task, TRUE);
+
+ IDE_RETURN (G_SOURCE_REMOVE);
}
-static void
-ide_git_clone_widget_clone_cb (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
+static gboolean
+finish_animation_in_idle (gpointer data)
{
- IdeGitCloneWidget *self = (IdeGitCloneWidget *)object;
- GTask *task = (GTask *)result;
+ g_autoptr(GTask) task = data;
+ IdeGitCloneWidget *self;
+
+ IDE_ENTRY;
- g_assert (IDE_IS_GIT_CLONE_WIDGET (self));
g_assert (G_IS_TASK (task));
+ self = g_task_get_source_object (task);
+ g_assert (IDE_IS_GIT_CLONE_WIDGET (self));
egg_object_animate_full (self->clone_progress,
EGG_ANIMATION_EASE_IN_OUT_QUAD,
@@ -243,6 +273,8 @@ ide_git_clone_widget_clone_cb (GObject *object,
* the project. Otherwise, it's pretty jarring to the user.
*/
g_timeout_add (ANIMATION_DURATION_MSEC, open_after_timeout, g_object_ref (task));
+
+ IDE_RETURN (G_SOURCE_REMOVE);
}
static void
@@ -290,14 +322,17 @@ ide_git_clone_widget_worker (GTask *task,
return;
}
- workdir = ggit_repository_get_workdir (repository);
- g_task_return_pointer (task, g_object_ref (workdir), g_object_unref);
+ req->project_file = ggit_repository_get_workdir (repository);
+ g_timeout_add (0, finish_animation_in_idle, g_object_ref (task));
g_clear_object (&repository);
}
-static void
-ide_git_clone_widget_begin_clone (IdeGitCloneWidget *self)
+void
+ide_git_clone_widget_clone_async (IdeGitCloneWidget *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
g_autoptr(GTask) task = NULL;
g_autoptr(GFile) location = NULL;
@@ -306,11 +341,10 @@ ide_git_clone_widget_begin_clone (IdeGitCloneWidget *self)
const gchar *uri;
const gchar *child_name;
- g_assert (IDE_IS_GIT_CLONE_WIDGET (self));
+ g_return_if_fail (IDE_IS_GIT_CLONE_WIDGET (self));
+ g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
- gtk_widget_set_sensitive (GTK_WIDGET (self->clone_button), FALSE);
gtk_label_set_label (self->clone_error_label, NULL);
- gtk_widget_show (GTK_WIDGET (self->clone_spinner));
uri = gtk_entry_get_text (self->clone_uri_entry);
child_name = gtk_entry_get_text (self->clone_location_entry);
@@ -326,7 +360,18 @@ ide_git_clone_widget_begin_clone (IdeGitCloneWidget *self)
req = clone_request_new (uri, location);
}
- task = g_task_new (self, NULL, ide_git_clone_widget_clone_cb, self);
+ task = g_task_new (self, cancellable, callback, user_data);
g_task_set_task_data (task, req, clone_request_free);
g_task_run_in_thread (task, ide_git_clone_widget_worker);
}
+
+gboolean
+ide_git_clone_widget_clone_finish (IdeGitCloneWidget *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (IDE_IS_GIT_CLONE_WIDGET (self), FALSE);
+ g_return_val_if_fail (G_IS_TASK (result), FALSE);
+
+ return g_task_propagate_boolean (G_TASK (result), error);
+}
diff --git a/plugins/git/ide-git-clone-widget.h b/plugins/git/ide-git-clone-widget.h
index 53e6eed..01f88b8 100644
--- a/plugins/git/ide-git-clone-widget.h
+++ b/plugins/git/ide-git-clone-widget.h
@@ -27,6 +27,14 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (IdeGitCloneWidget, ide_git_clone_widget, IDE, GIT_CLONE_WIDGET, GtkBin)
+void ide_git_clone_widget_clone_async (IdeGitCloneWidget *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean ide_git_clone_widget_clone_finish (IdeGitCloneWidget *self,
+ GAsyncResult *result,
+ GError **error);
+
G_END_DECLS
#endif /* IDE_GIT_CLONE_WIDGET_H */
diff --git a/plugins/git/ide-git-clone-widget.ui b/plugins/git/ide-git-clone-widget.ui
index a7a2882..be90425 100644
--- a/plugins/git/ide-git-clone-widget.ui
+++ b/plugins/git/ide-git-clone-widget.ui
@@ -152,35 +152,6 @@
<property name="pack-type">end</property>
</packing>
</child>
- <child>
- <object class="GtkSpinner" id="clone_spinner">
- <property name="vexpand">false</property>
- <property name="active">true</property>
- <property name="margin">24</property>
- <property name="width-request">24</property>
- <property name="height-request">24</property>
- </object>
- <packing>
- <property name="pack-type">end</property>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="clone_button">
- <property name="halign">center</property>
- <property name="visible">true</property>
- <property name="margin-top">24</property>
- <property name="label" translatable="yes">Cl_one Repository</property>
- <property name="use-underline">true</property>
- <style>
- <class name="suggested-action"/>
- </style>
- </object>
- <packing>
- <property name="pack-type">end</property>
- <property name="position">3</property>
- </packing>
- </child>
</object>
</child>
</object>
diff --git a/plugins/git/ide-git-genesis-addin.c b/plugins/git/ide-git-genesis-addin.c
index e738b26..54be903 100644
--- a/plugins/git/ide-git-genesis-addin.c
+++ b/plugins/git/ide-git-genesis-addin.c
@@ -24,9 +24,8 @@
struct _IdeGitGenesisAddin
{
- GObject parent_instance;
-
- GtkWidget *clone_widget;
+ GObject parent_instance;
+ IdeGitCloneWidget *clone_widget;
};
static void genesis_addin_iface_init (IdeGenesisAddinInterface *iface);
@@ -34,9 +33,47 @@ static void genesis_addin_iface_init (IdeGenesisAddinInterface *iface);
G_DEFINE_TYPE_EXTENDED (IdeGitGenesisAddin, ide_git_genesis_addin, G_TYPE_OBJECT, 0,
G_IMPLEMENT_INTERFACE (IDE_TYPE_GENESIS_ADDIN, genesis_addin_iface_init))
+enum {
+ PROP_0,
+ PROP_IS_READY
+};
+
+static void
+ide_git_genesis_addin_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ IdeGitGenesisAddin *self = IDE_GIT_GENESIS_ADDIN(object);
+
+ switch (prop_id)
+ {
+ case PROP_IS_READY:
+ if (self->clone_widget != NULL)
+ g_object_get_property (G_OBJECT (self->clone_widget), "is-ready", value);
+ else
+ g_value_set_boolean (value, FALSE);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ }
+}
+
static void
ide_git_genesis_addin_class_init (IdeGitGenesisAddinClass *klass)
{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->get_property = ide_git_genesis_addin_get_property;
+
+ g_object_class_install_property (object_class,
+ PROP_IS_READY,
+ g_param_spec_boolean ("is-ready",
+ "Is Ready",
+ "If the widget is ready to continue.",
+ FALSE,
+ (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)));
}
static void
@@ -56,6 +93,16 @@ ide_git_genesis_addin_get_title (IdeGenesisAddin *addin)
return g_strdup (_("From a existing project in a Git repository"));
}
+static void
+widget_is_ready (GtkWidget *widget,
+ GParamSpec *pspec,
+ IdeGitGenesisAddin *self)
+{
+ g_assert (IDE_IS_GIT_GENESIS_ADDIN (self));
+
+ g_object_notify (G_OBJECT (self), "is-ready");
+}
+
static GtkWidget *
ide_git_genesis_addin_get_widget (IdeGenesisAddin *addin)
{
@@ -64,11 +111,65 @@ ide_git_genesis_addin_get_widget (IdeGenesisAddin *addin)
g_assert (IDE_IS_GIT_GENESIS_ADDIN (self));
if (self->clone_widget == NULL)
- self->clone_widget = g_object_new (IDE_TYPE_GIT_CLONE_WIDGET,
- "visible", TRUE,
- NULL);
+ {
+ self->clone_widget = g_object_new (IDE_TYPE_GIT_CLONE_WIDGET,
+ "visible", TRUE,
+ NULL);
+ g_signal_connect (self->clone_widget,
+ "notify::is-ready",
+ G_CALLBACK (widget_is_ready),
+ self);
+ }
+
+ return GTK_WIDGET (self->clone_widget);
+}
+
+static void
+ide_git_genesis_addin_run_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ IdeGitCloneWidget *widget = (IdeGitCloneWidget *)object;
+ g_autoptr(GTask) task = user_data;
+ GError *error = NULL;
+
+ g_assert (G_IS_TASK (task));
+ g_assert (IDE_IS_GIT_CLONE_WIDGET (widget));
+
+ if (!ide_git_clone_widget_clone_finish (widget, result, &error))
+ g_task_return_error (task, error);
+ else
+ g_task_return_boolean (task, TRUE);
+}
+
+static void
+ide_git_genesis_addin_run_async (IdeGenesisAddin *addin,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ IdeGitGenesisAddin *self = (IdeGitGenesisAddin *)addin;
+ GTask *task;
+
+ g_return_if_fail (IDE_IS_GIT_GENESIS_ADDIN (addin));
+ g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ task = g_task_new (self, cancellable, callback, user_data);
+ ide_git_clone_widget_clone_async (self->clone_widget,
+ cancellable,
+ ide_git_genesis_addin_run_cb,
+ task);
+}
+
+static gboolean
+ide_git_genesis_addin_run_finish (IdeGenesisAddin *addin,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (IDE_IS_GIT_GENESIS_ADDIN (addin), FALSE);
+ g_return_val_if_fail (G_IS_TASK (result), FALSE);
- return self->clone_widget;
+ return g_task_propagate_boolean (G_TASK (result), error);
}
static void
@@ -77,4 +178,6 @@ genesis_addin_iface_init (IdeGenesisAddinInterface *iface)
iface->get_title = ide_git_genesis_addin_get_title;
iface->get_icon_name = ide_git_genesis_addin_get_icon_name;
iface->get_widget = ide_git_genesis_addin_get_widget;
+ iface->run_async = ide_git_genesis_addin_run_async;
+ iface->run_finish = ide_git_genesis_addin_run_finish;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]