[gnome-builder] genesis addin: create-project
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] genesis addin: create-project
- Date: Sun, 3 Apr 2016 03:23:37 +0000 (UTC)
commit 924b2b17cbd10dc94dbe7fdaa8e711b1f832523b
Author: Akshaya Kakkilaya <akshaya kakkilaya gmail com>
Date: Thu Mar 3 14:30:51 2016 +0530
genesis addin: create-project
GUI for creating new projects from templates
https://bugzilla.gnome.org/show_bug.cgi?id=763027
plugins/create-project/Makefile.am | 2 +
.../gbp-create-project-genesis-addin.c | 51 ++-
.../gbp-create-project-template-icon.c | 128 ++++++
.../gbp-create-project-template-icon.h | 33 ++
.../gbp-create-project-template-icon.ui | 31 ++
plugins/create-project/gbp-create-project-widget.c | 449 +++++++++++++++++++-
plugins/create-project/gbp-create-project-widget.h | 9 +
.../create-project/gbp-create-project-widget.ui | 151 +++++++-
.../gbp-create-project.gresource.xml | 1 +
.../library-template/library_template/__init__.py | 8 +-
10 files changed, 851 insertions(+), 12 deletions(-)
---
diff --git a/plugins/create-project/Makefile.am b/plugins/create-project/Makefile.am
index 2b55726..927c53f 100644
--- a/plugins/create-project/Makefile.am
+++ b/plugins/create-project/Makefile.am
@@ -13,6 +13,8 @@ libcreate_project_plugin_la_SOURCES = \
gbp-create-project-genesis-addin.c \
gbp-create-project-genesis-addin.h \
gbp-create-project-plugin.c \
+ gbp-create-project-template-icon.c \
+ gbp-create-project-template-icon.h \
gbp-create-project-tool.c \
gbp-create-project-tool.h \
gbp-create-project-widget.c \
diff --git a/plugins/create-project/gbp-create-project-genesis-addin.c
b/plugins/create-project/gbp-create-project-genesis-addin.c
index 8d51d57..2f09180 100644
--- a/plugins/create-project/gbp-create-project-genesis-addin.c
+++ b/plugins/create-project/gbp-create-project-genesis-addin.c
@@ -26,10 +26,7 @@ static void genesis_addin_iface_init (IdeGenesisAddinInterface *iface);
struct _GbpCreateProjectGenesisAddin
{
GObject parent;
-
GbpCreateProjectWidget *widget;
-
- guint is_ready : 1;
};
G_DEFINE_TYPE_EXTENDED (GbpCreateProjectGenesisAddin,
@@ -68,7 +65,10 @@ gbp_create_project_genesis_addin_get_property (GObject *object,
switch (prop_id)
{
case PROP_IS_READY:
- g_value_set_boolean (value, self->is_ready);
+ if (self->widget != NULL)
+ g_object_get_property (G_OBJECT (self->widget), "is-ready", value);
+ else
+ g_value_set_boolean (value, FALSE);
break;
default:
@@ -89,7 +89,7 @@ gbp_create_project_genesis_addin_class_init (GbpCreateProjectGenesisAddinClass *
"Is Ready",
"Is Ready",
FALSE,
- (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_properties (object_class, N_PROPS, properties);
}
@@ -99,6 +99,16 @@ gbp_create_project_genesis_addin_init (GbpCreateProjectGenesisAddin *self)
{
}
+static void
+widget_is_ready (GtkWidget *widget,
+ GParamSpec *pspec,
+ GbpCreateProjectGenesisAddin *self)
+{
+ g_assert (GBP_IS_CREATE_PROJECT_GENESIS_ADDIN (self));
+
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_IS_READY]);
+}
+
static GtkWidget *
gbp_create_project_genesis_addin_get_widget (IdeGenesisAddin *addin)
{
@@ -127,6 +137,10 @@ gbp_create_project_genesis_addin_get_widget (IdeGenesisAddin *addin)
* making the GbpCreateProjectGenesisAddin:is-ready property
* writable though.
*/
+ g_signal_connect (self->widget,
+ "notify::is-ready",
+ G_CALLBACK (widget_is_ready),
+ self);
}
return GTK_WIDGET (self->widget);
@@ -145,6 +159,24 @@ gbp_create_project_genesis_addin_get_title (IdeGenesisAddin *addin)
}
static void
+gbp_create_project_genesis_addin_run_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GbpCreateProjectWidget *widget = (GbpCreateProjectWidget *)object;
+ g_autoptr(GTask) task = user_data;
+ GError *error = NULL;
+
+ g_assert (G_IS_TASK (task));
+ g_assert (GBP_IS_CREATE_PROJECT_WIDGET (widget));
+
+ if (!gbp_create_project_widget_create_finish (widget, result, &error))
+ g_task_return_error (task, error);
+ else
+ g_task_return_boolean (task, TRUE);
+}
+
+static void
gbp_create_project_genesis_addin_run_async (IdeGenesisAddin *addin,
GCancellable *cancellable,
GAsyncReadyCallback callback,
@@ -162,7 +194,10 @@ gbp_create_project_genesis_addin_run_async (IdeGenesisAddin *addin,
* See gbp-create-project-tool.c for examples.
*/
- g_task_return_boolean (task, TRUE);
+ gbp_create_project_widget_create_async (self->widget,
+ cancellable,
+ gbp_create_project_genesis_addin_run_cb,
+ g_object_ref (task));
}
static gboolean
@@ -170,8 +205,8 @@ gbp_create_project_genesis_addin_run_finish (IdeGenesisAddin *addin,
GAsyncResult *result,
GError **error)
{
- g_assert (GBP_IS_CREATE_PROJECT_GENESIS_ADDIN (addin));
- g_assert (G_IS_TASK (result));
+ g_return_val_if_fail (GBP_IS_CREATE_PROJECT_GENESIS_ADDIN (addin), FALSE);
+ g_return_val_if_fail (G_IS_TASK (result), FALSE);
return g_task_propagate_boolean (G_TASK (result), error);
}
diff --git a/plugins/create-project/gbp-create-project-template-icon.c
b/plugins/create-project/gbp-create-project-template-icon.c
new file mode 100644
index 0000000..9007840
--- /dev/null
+++ b/plugins/create-project/gbp-create-project-template-icon.c
@@ -0,0 +1,128 @@
+/* gbp-create-project-template-icon.c
+ *
+ * Copyright (C) 2016 Akshaya Kakkilaya <akshaya kakkilaya gmail com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "gbp-create-project-template-icon.h"
+
+struct _GbpCreateProjectTemplateIcon
+{
+ GtkBin parent;
+
+ GtkImage *template_icon;
+ GtkLabel *template_name;
+
+ IdeProjectTemplate *template;
+};
+
+enum {
+ PROP_0,
+ PROP_TEMPLATE,
+ N_PROPS
+};
+
+static GParamSpec *properties [N_PROPS];
+
+G_DEFINE_TYPE (GbpCreateProjectTemplateIcon, gbp_create_project_template_icon, GTK_TYPE_BIN)
+
+static void
+gbp_create_project_template_icon_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GbpCreateProjectTemplateIcon *self = GBP_CREATE_PROJECT_TEMPLATE_ICON (object);
+
+ switch (prop_id)
+ {
+ case PROP_TEMPLATE:
+ g_value_set_object (value, self->template);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+static void
+gbp_create_project_template_icon_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GbpCreateProjectTemplateIcon *self = GBP_CREATE_PROJECT_TEMPLATE_ICON (object);
+ g_autofree gchar *icon_name;
+ g_autofree gchar *name;
+
+ switch (prop_id)
+ {
+ case PROP_TEMPLATE:
+ self->template = g_value_dup_object (value);
+
+ icon_name = ide_project_template_get_icon_name (self->template);
+ name = ide_project_template_get_name (self->template);
+
+ g_object_set (self->template_icon,
+ "icon-name", icon_name,
+ NULL);
+ gtk_label_set_text (self->template_name, name);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+gbp_create_project_template_icon_finalize (GObject *object)
+{
+ GbpCreateProjectTemplateIcon *self = GBP_CREATE_PROJECT_TEMPLATE_ICON (object);
+
+ g_object_unref (self->template);
+
+ G_OBJECT_CLASS (gbp_create_project_template_icon_parent_class)->finalize (object);
+}
+
+static void
+gbp_create_project_template_icon_class_init (GbpCreateProjectTemplateIconClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->set_property = gbp_create_project_template_icon_set_property;
+ object_class->get_property = gbp_create_project_template_icon_get_property;
+ object_class->finalize = gbp_create_project_template_icon_finalize;
+
+ properties [PROP_TEMPLATE] =
+ g_param_spec_object ("template",
+ "Template",
+ "Template",
+ IDE_TYPE_PROJECT_TEMPLATE,
+ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, N_PROPS, properties);
+
+ gtk_widget_class_set_template_from_resource (widget_class,
+
"/org/gnome/builder/plugins/create-project-plugin/gbp-create-project-template-icon.ui");
+ gtk_widget_class_set_css_name (widget_class, "createprojecttemplateicon");
+ gtk_widget_class_bind_template_child (widget_class, GbpCreateProjectTemplateIcon, template_icon);
+ gtk_widget_class_bind_template_child (widget_class, GbpCreateProjectTemplateIcon, template_name);
+}
+
+static void
+gbp_create_project_template_icon_init (GbpCreateProjectTemplateIcon *self)
+{
+ gtk_widget_init_template (GTK_WIDGET (self));
+}
diff --git a/plugins/create-project/gbp-create-project-template-icon.h
b/plugins/create-project/gbp-create-project-template-icon.h
new file mode 100644
index 0000000..a6246c4
--- /dev/null
+++ b/plugins/create-project/gbp-create-project-template-icon.h
@@ -0,0 +1,33 @@
+/* gbp-create-project-template-icon.h
+ *
+ * Copyright (C) 2016 Akshaya Kakkilaya <akshaya kakkilaya gmail com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GBP_CREATE_PROJECT_TEMPLATE_ICON_H
+#define GBP_CREATE_PROJECT_TEMPLATE_ICON_H
+
+#include <gtk/gtk.h>
+#include <ide.h>
+
+G_BEGIN_DECLS
+
+#define GBP_TYPE_CREATE_PROJECT_TEMPLATE_ICON (gbp_create_project_template_icon_get_type())
+
+G_DECLARE_FINAL_TYPE (GbpCreateProjectTemplateIcon, gbp_create_project_template_icon, GBP,
CREATE_PROJECT_TEMPLATE_ICON, GtkBin)
+
+G_END_DECLS
+
+#endif /* GBP_CREATE_PROJECT_TEMPLATE_ICON_H */
diff --git a/plugins/create-project/gbp-create-project-template-icon.ui
b/plugins/create-project/gbp-create-project-template-icon.ui
new file mode 100644
index 0000000..29183ed
--- /dev/null
+++ b/plugins/create-project/gbp-create-project-template-icon.ui
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <template class="GbpCreateProjectTemplateIcon" parent="GtkBin">
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">vertical</property>
+ <property name="expand">true</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkImage" id="template_icon">
+ <property name="expand">true</property>
+ <property name="pixel-size">48</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel" id="template_name">
+ <property name="expand">true</property>
+ <property name="visible">true</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/plugins/create-project/gbp-create-project-widget.c
b/plugins/create-project/gbp-create-project-widget.c
index 90b1bff..7d08822 100644
--- a/plugins/create-project/gbp-create-project-widget.c
+++ b/plugins/create-project/gbp-create-project-widget.c
@@ -16,26 +16,473 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <libpeas/peas.h>
+
+#include "ide-macros.h"
+#include "gbp-create-project-template-icon.h"
#include "gbp-create-project-widget.h"
struct _GbpCreateProjectWidget
{
- GtkBin parent;
+ GtkBin parent;
+
+ GtkEntry *project_name_entry;
+ GtkEntry *project_location_entry;
+ GtkFileChooserButton *project_location_button;
+ GtkComboBoxText *project_language_chooser;
+ GtkFlowBox *project_template_chooser;
};
+enum {
+ PROP_0,
+ PROP_IS_READY,
+ N_PROPS
+};
+
+static GParamSpec *properties [N_PROPS];
+
G_DEFINE_TYPE (GbpCreateProjectWidget, gbp_create_project_widget, GTK_TYPE_BIN)
static void
+gbp_create_project_widget_add_languages (GbpCreateProjectWidget *self,
+ GList *project_templates)
+{
+ const GList *iter;
+
+ g_assert (GBP_IS_CREATE_PROJECT_WIDGET (self));
+
+ for (iter = project_templates; iter != NULL; iter = iter->next)
+ {
+ IdeProjectTemplate *template = iter->data;
+ g_auto(GStrv) template_languages = NULL;
+ gint i;
+
+ g_assert (IDE_IS_PROJECT_TEMPLATE (template));
+
+ template_languages = ide_project_template_get_languages (template);
+
+ for (i = 0; template_languages [i]; i++)
+ gtk_combo_box_text_append (self->project_language_chooser, NULL, template_languages [i]);
+ }
+}
+
+static gboolean
+validate_name (const gchar *name)
+{
+ for (; *name; name = g_utf8_next_char (name))
+ {
+ gunichar ch = g_utf8_get_char (name);
+
+ if (ch == '/')
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+gbp_create_project_widget_name_changed (GbpCreateProjectWidget *self,
+ GtkEntry *entry)
+{
+ const gchar *text;
+ g_autofree gchar *project_name = NULL;
+ g_autofree gchar *project_dir = NULL;
+
+ g_assert (GBP_IS_CREATE_PROJECT_WIDGET (self));
+ g_assert (GTK_IS_ENTRY (entry));
+
+ text = gtk_entry_get_text (entry);
+ project_name = g_strstrip (g_strdup (text));
+
+ if (ide_str_empty0 (project_name) || !validate_name (project_name))
+ {
+ g_object_set (self->project_name_entry,
+ "secondary-icon-name", "dialog-warning-symbolic",
+ NULL);
+
+ gtk_entry_set_text (self->project_location_entry, "");
+ }
+ else
+ {
+ g_object_set (self->project_name_entry,
+ "secondary-icon-name", NULL,
+ NULL);
+
+ project_dir = g_ascii_strdown (g_strdelimit (project_name, " ", '-'), -1);
+ gtk_entry_set_text (self->project_location_entry, project_dir);
+ }
+
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_IS_READY]);
+}
+
+static gboolean
+gbp_create_project_widget_flow_box_filter (GtkFlowBoxChild *template_container,
+ gpointer object)
+{
+ GbpCreateProjectWidget *self = object;
+ GbpCreateProjectTemplateIcon *template_icon;
+ IdeProjectTemplate *template;
+ g_autofree gchar *language = NULL;
+ g_auto(GStrv) template_languages = NULL;
+ gint i;
+
+ g_assert (GTK_IS_FLOW_BOX_CHILD (template_container));
+ g_assert (GBP_IS_CREATE_PROJECT_WIDGET (self));
+
+ language = gtk_combo_box_text_get_active_text (self->project_language_chooser);
+
+ if (ide_str_empty0 (language))
+ return TRUE;
+
+ template_icon = GBP_CREATE_PROJECT_TEMPLATE_ICON (gtk_bin_get_child (GTK_BIN (template_container)));
+ g_object_get (template_icon,
+ "template", &template,
+ NULL);
+ template_languages = ide_project_template_get_languages (template);
+ g_object_unref (template);
+
+ for (i = 0; template_languages [i]; i++)
+ {
+ if (g_str_equal (language, template_languages [i]))
+ return TRUE;
+ }
+
+ gtk_flow_box_unselect_child (self->project_template_chooser, template_container);
+
+ return FALSE;
+}
+
+static void
+gbp_create_project_widget_language_changed (GbpCreateProjectWidget *self,
+ GtkComboBox *language_chooser)
+{
+ g_assert (GBP_IS_CREATE_PROJECT_WIDGET (self));
+
+ gtk_flow_box_invalidate_filter (self->project_template_chooser);
+
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_IS_READY]);
+}
+
+static void
+gbp_create_project_widget_template_selected (GbpCreateProjectWidget *self,
+ GtkFlowBox *box,
+ GtkFlowBoxChild *child)
+{
+ g_assert (GBP_IS_CREATE_PROJECT_WIDGET (self));
+
+ g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_IS_READY]);
+}
+
+static void
+gbp_create_project_widget_add_template_buttons (GbpCreateProjectWidget *self,
+ GList *project_templates)
+{
+ const GList *iter;
+
+ g_assert (GBP_IS_CREATE_PROJECT_WIDGET (self));
+
+ for (iter = project_templates; iter != NULL; iter = iter->next)
+ {
+ IdeProjectTemplate *template = iter->data;
+ GbpCreateProjectTemplateIcon *template_icon;
+ GtkFlowBoxChild *template_container;
+
+ g_assert (IDE_IS_PROJECT_TEMPLATE (template));
+
+ template_icon = g_object_new (GBP_TYPE_CREATE_PROJECT_TEMPLATE_ICON,
+ "visible", TRUE,
+ "template", template,
+ NULL);
+
+ template_container = g_object_new (GTK_TYPE_FLOW_BOX_CHILD,
+ "visible", TRUE,
+ NULL);
+ gtk_container_add (GTK_CONTAINER (template_container), GTK_WIDGET (template_icon));
+ gtk_flow_box_insert (self->project_template_chooser, GTK_WIDGET (template_container), -1);
+ }
+}
+
+static void
+template_providers_foreach_cb (PeasExtensionSet *set,
+ PeasPluginInfo *plugin_info,
+ PeasExtension *exten,
+ gpointer user_data)
+{
+ GbpCreateProjectWidget *self = user_data;
+ IdeTemplateProvider *provider = IDE_TEMPLATE_PROVIDER (exten);
+ GList *templates = ide_template_provider_get_project_templates (provider);
+
+ g_assert (GBP_IS_CREATE_PROJECT_WIDGET (self));
+
+ gbp_create_project_widget_add_template_buttons (self, templates);
+ gbp_create_project_widget_add_languages (self, templates);
+
+ g_list_foreach (templates, (GFunc)g_object_unref, NULL);
+ g_list_free (templates);
+}
+
+static void
+gbp_create_project_widget_constructed (GObject *object)
+{
+ GbpCreateProjectWidget *self = GBP_CREATE_PROJECT_WIDGET (object);
+ PeasEngine *engine;
+ PeasExtensionSet *extensions;
+
+ engine = peas_engine_get_default ();
+ extensions = peas_extension_set_new (engine,
+ IDE_TYPE_TEMPLATE_PROVIDER,
+ NULL);
+ peas_extension_set_foreach (extensions,
+ template_providers_foreach_cb,
+ self);
+
+ g_clear_object (&extensions);
+
+ G_OBJECT_CLASS (gbp_create_project_widget_parent_class)->constructed (object);
+}
+
+static void
+gbp_create_project_widget_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (gbp_create_project_widget_parent_class)->finalize (object);
+}
+
+static gboolean
+gbp_create_project_widget_is_ready (GbpCreateProjectWidget *self)
+{
+ const gchar *text;
+ g_autofree gchar *project_name = NULL;
+ g_autofree gchar *language = NULL;
+ GList *selected_template = NULL;
+
+ g_assert (GBP_IS_CREATE_PROJECT_WIDGET (self));
+
+ text = gtk_entry_get_text (self->project_name_entry);
+ project_name = g_strstrip (g_strdup (text));
+
+ if (ide_str_empty0 (project_name) || !validate_name (project_name))
+ return FALSE;
+
+ language = gtk_combo_box_text_get_active_text (self->project_language_chooser);
+
+ if (ide_str_empty0 (language))
+ return FALSE;
+
+ selected_template = gtk_flow_box_get_selected_children (self->project_template_chooser);
+
+ if (selected_template == NULL)
+ return FALSE;
+
+ g_list_free (selected_template);
+
+ return TRUE;
+}
+
+static void
+gbp_create_project_widget_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GbpCreateProjectWidget *self = GBP_CREATE_PROJECT_WIDGET(object);
+
+ switch (prop_id)
+ {
+ case PROP_IS_READY:
+ g_value_set_boolean (value, gbp_create_project_widget_is_ready (self));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ }
+}
+
+static void
gbp_create_project_widget_class_init (GbpCreateProjectWidgetClass *klass)
{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ object_class->constructed = gbp_create_project_widget_constructed;
+ object_class->finalize = gbp_create_project_widget_finalize;
+ object_class->get_property = gbp_create_project_widget_get_property;
+
+ properties [PROP_IS_READY] =
+ g_param_spec_boolean ("is-ready",
+ "Is Ready",
+ "Is Ready",
+ FALSE,
+ (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_properties (object_class, N_PROPS, properties);
+
+ gtk_widget_class_set_css_name (widget_class, "createprojectwidget");
gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/builder/plugins/create-project-plugin/gbp-create-project-widget.ui");
+ gtk_widget_class_bind_template_child (widget_class, GbpCreateProjectWidget, project_name_entry);
+ gtk_widget_class_bind_template_child (widget_class, GbpCreateProjectWidget, project_location_button);
+ gtk_widget_class_bind_template_child (widget_class, GbpCreateProjectWidget, project_location_entry);
+ gtk_widget_class_bind_template_child (widget_class, GbpCreateProjectWidget, project_language_chooser);
+ gtk_widget_class_bind_template_child (widget_class, GbpCreateProjectWidget, project_template_chooser);
}
static void
gbp_create_project_widget_init (GbpCreateProjectWidget *self)
{
+ g_autoptr(GSettings) settings = NULL;
+ g_autofree gchar *path = NULL;
+ g_autofree char *projects_dir = NULL;
+
gtk_widget_init_template (GTK_WIDGET (self));
+
+ settings = g_settings_new ("org.gnome.builder");
+ path = g_settings_get_string (settings, "projects-directory");
+
+ if (!ide_str_empty0 (path))
+ {
+ projects_dir = g_build_filename (g_get_home_dir (), path, NULL);
+ gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (self->project_location_button),
+ projects_dir);
+ }
+
+ gtk_flow_box_set_filter_func (self->project_template_chooser,
+ gbp_create_project_widget_flow_box_filter,
+ self,
+ NULL);
+
+ g_signal_connect_object (self->project_name_entry,
+ "changed",
+ G_CALLBACK (gbp_create_project_widget_name_changed),
+ self,
+ G_CONNECT_SWAPPED);
+
+
+ g_signal_connect_object (self->project_language_chooser,
+ "changed",
+ G_CALLBACK (gbp_create_project_widget_language_changed),
+ self,
+ G_CONNECT_SWAPPED);
+
+ g_signal_connect_object (self->project_template_chooser,
+ "child-activated",
+ G_CALLBACK (gbp_create_project_widget_template_selected),
+ self,
+ G_CONNECT_SWAPPED);
+}
+
+static void
+extract_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GbpCreateProjectWidget *self;
+ IdeWorkbench *workbench;
+ IdeProjectTemplate *template = (IdeProjectTemplate *)object;
+ g_autoptr(GTask) task = user_data;
+ GError *error = NULL;
+ const gchar *path;
+ g_autoptr(GFile) project_file = NULL;
+
+ g_assert (IDE_IS_PROJECT_TEMPLATE (template));
+ g_assert (G_IS_ASYNC_RESULT (result));
+ g_assert (G_IS_TASK (task));
+
+
+ if (!ide_project_template_expand_finish (template, result, &error))
+ {
+ g_object_unref (template);
+ g_task_return_error (task, error);
+ return;
+ }
+ else
+ {
+ self = g_task_get_source_object (task);
+ path = g_task_get_task_data (task);
+ project_file = g_file_new_for_path (path);
+ workbench = ide_widget_get_workbench (GTK_WIDGET (self));
+ ide_workbench_open_project_async (workbench, project_file, NULL, NULL, NULL);
+ }
+
+ g_object_unref (template);
+ g_task_return_boolean (task, TRUE);
+}
+
+void
+gbp_create_project_widget_create_async (GbpCreateProjectWidget *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_autoptr(GTask) task = NULL;
+ g_autoptr(GHashTable) params = NULL;
+ IdeProjectTemplate *template;
+ g_autofree gchar *name;
+ g_autofree gchar *location = NULL;
+ g_autofree gchar *path = NULL;
+ g_autofree gchar *language = NULL;
+ GtkFlowBoxChild *template_container;
+ GbpCreateProjectTemplateIcon *template_icon;
+ const gchar *text;
+ const gchar *child_name;
+ GList *selected_box_child = NULL;
+
+ g_return_if_fail (GBP_CREATE_PROJECT_WIDGET (self));
+ g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+ selected_box_child = gtk_flow_box_get_selected_children (self->project_template_chooser);
+ template_container = selected_box_child->data;
+ template_icon = GBP_CREATE_PROJECT_TEMPLATE_ICON (gtk_bin_get_child (GTK_BIN (template_container)));
+ g_object_get (template_icon,
+ "template", &template,
+ NULL);
+ g_list_free (selected_box_child);
+
+ params = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ g_free,
+ (GDestroyNotify)g_variant_unref);
+
+ text = gtk_entry_get_text (self->project_name_entry);
+ name = g_strdup (text);
+ g_hash_table_insert (params,
+ g_strdup ("name"),
+ g_variant_ref_sink (g_variant_new_string (g_strdelimit (name, " ", '-'))));
+
+ child_name = gtk_entry_get_text (self->project_location_entry);
+ location = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (self->project_location_button));
+
+ if (!ide_str_empty0 (child_name))
+ path = g_build_filename (location, child_name, NULL);
+ else
+ path = g_strdup (location);
+
+ g_hash_table_insert (params,
+ g_strdup ("path"),
+ g_variant_ref_sink (g_variant_new_string (path)));
+
+ language = gtk_combo_box_text_get_active_text (self->project_language_chooser);
+ g_hash_table_insert (params,
+ g_strdup ("language"),
+ g_variant_ref_sink (g_variant_new_string (language)));
+
+ task = g_task_new (self, cancellable, callback, user_data);
+ g_task_set_task_data (task, g_strdup (path), g_free);
+
+ ide_project_template_expand_async (g_object_ref (template),
+ params,
+ NULL,
+ extract_cb,
+ g_object_ref (task));
+ g_object_unref (template);
+}
+
+gboolean
+gbp_create_project_widget_create_finish (GbpCreateProjectWidget *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (GBP_IS_CREATE_PROJECT_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/create-project/gbp-create-project-widget.h
b/plugins/create-project/gbp-create-project-widget.h
index 4809bbc..0f69963 100644
--- a/plugins/create-project/gbp-create-project-widget.h
+++ b/plugins/create-project/gbp-create-project-widget.h
@@ -20,6 +20,7 @@
#define GBP_CREATE_PROJECT_WIDGET_H
#include <gtk/gtk.h>
+#include <ide.h>
G_BEGIN_DECLS
@@ -27,6 +28,14 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (GbpCreateProjectWidget, gbp_create_project_widget, GBP, CREATE_PROJECT_WIDGET, GtkBin)
+void gbp_create_project_widget_create_async (GbpCreateProjectWidget *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean gbp_create_project_widget_create_finish (GbpCreateProjectWidget *self,
+ GAsyncResult *result,
+ GError **error);
+
G_END_DECLS
#endif /* GBP_CREATE_PROJECT_WIDGET_H */
diff --git a/plugins/create-project/gbp-create-project-widget.ui
b/plugins/create-project/gbp-create-project-widget.ui
index ca74c32..84db7ef 100644
--- a/plugins/create-project/gbp-create-project-widget.ui
+++ b/plugins/create-project/gbp-create-project-widget.ui
@@ -2,9 +2,156 @@
<interface>
<template class="GbpCreateProjectWidget" parent="GtkBin">
<child>
- <object class="GtkBox">
- <property name="orientation">vertical</property>
+ <object class="GtkScrolledWindow">
<property name="visible">true</property>
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">vertical</property>
+ <property name="expand">true</property>
+ <property name="border-width">32</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">horizontal</property>
+ <property name="expand">true</property>
+ <property name="valign">end</property>
+ <property name="spacing">12</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">vertical</property>
+ <property name="expand">true</property>
+ <property name="halign">end</property>
+ <property name="spacing">12</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="label" translatable="yes">Name</property>
+ <property name="expand">true</property>
+ <property name="halign">end</property>
+ <property name="visible">true</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="label" translatable="yes">Location</property>
+ <property name="expand">true</property>
+ <property name="halign">end</property>
+ <property name="visible">true</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="label" translatable="yes">Language</property>
+ <property name="expand">true</property>
+ <property name="halign">end</property>
+ <property name="visible">true</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="center">
+ <object class="GtkBox">
+ <property name="orientation">vertical</property>
+ <property name="expand">false</property>
+ <property name="spacing">12</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkEntry" id="project_name_entry">
+ <property name="width-chars">50</property>
+ <property name="expand">true</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="expand">true</property>
+ <property name="visible">true</property>
+ <style>
+ <class name="linked"/>
+ </style>
+ <child>
+ <object class="GtkFileChooserButton" id="project_location_button">
+ <property name="action">select-folder</property>
+ <property name="local-only">true</property>
+ <property name="expand">true</property>
+ <property name="visible">true</property>
+ <style>
+ <class name="linked-on-right"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkEntry" id="project_location_entry">
+ <property name="expand">true</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="project_language_chooser">
+ <property name="expand">true</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">vertical</property>
+ <property name="expand">true</property>
+ <property name="valign">start</property>
+ <property name="spacing">12</property>
+ <property name="border-width">32</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="label" translatable="yes">Pattern</property>
+ <property name="visible">true</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkFlowBox" id="project_template_chooser">
+ <property name="expand">true</property>
+ <property name="halign">center</property>
+ <property name="valign">start</property>
+ <property name="visible">true</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
</object>
</child>
</template>
diff --git a/plugins/create-project/gbp-create-project.gresource.xml
b/plugins/create-project/gbp-create-project.gresource.xml
index c54dfca..3b370e4 100644
--- a/plugins/create-project/gbp-create-project.gresource.xml
+++ b/plugins/create-project/gbp-create-project.gresource.xml
@@ -2,5 +2,6 @@
<gresources>
<gresource prefix="/org/gnome/builder/plugins/create-project-plugin">
<file>gbp-create-project-widget.ui</file>
+ <file>gbp-create-project-template-icon.ui</file>
</gresource>
</gresources>
diff --git a/plugins/library-template/library_template/__init__.py
b/plugins/library-template/library_template/__init__.py
index a83a6a0..127839a 100644
--- a/plugins/library-template/library_template/__init__.py
+++ b/plugins/library-template/library_template/__init__.py
@@ -62,7 +62,13 @@ class LibraryProjectTemplate(Ide.TemplateBase, Ide.ProjectTemplate):
def do_expand_async(self, params, cancellable, callback, data):
name = params['name'].get_string().lower()
- directory = Gio.File.new_for_path(name)
+
+ if 'path' in params:
+ dir_path = params['path'].get_string();
+ else:
+ dir_path = name
+
+ directory = Gio.File.new_for_path(dir_path)
scope = Template.Scope.new()
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]