[gnome-builder] add basic build items to project menu in sidebar



commit 6b21c9b0f755c4a8734dc4e4028609b1947dc0e2
Author: Christian Hergert <christian hergert me>
Date:   Sun Mar 22 13:42:07 2015 -0700

    add basic build items to project menu in sidebar

 data/ui/gb-editor-workspace.ui           |   33 ++++++++-
 src/editor/gb-editor-workspace-private.h |    1 +
 src/editor/gb-editor-workspace.c         |    6 ++
 src/workbench/gb-workbench-actions.c     |   97 ++++++------------------
 src/workbench/gb-workbench.c             |  122 ++++++++++++++++++++++++++++++
 src/workbench/gb-workbench.h             |    8 ++
 6 files changed, 192 insertions(+), 75 deletions(-)
---
diff --git a/data/ui/gb-editor-workspace.ui b/data/ui/gb-editor-workspace.ui
index 1017834..8bb62e9 100644
--- a/data/ui/gb-editor-workspace.ui
+++ b/data/ui/gb-editor-workspace.ui
@@ -21,9 +21,9 @@
                   <class name="header"/>
                 </style>
                 <child type="center">
-                  <object class="GtkMenuButton">
-                    <property name="label">Project</property>
+                  <object class="GtkMenuButton" id="project_button">
                     <property name="margin">3</property>
+                    <property name="popover">project_popover</property>
                     <property name="visible">true</property>
                     <style>
                       <class name="dim-label"/>
@@ -56,4 +56,33 @@
       </object>
     </child>
   </template>
+  <object class="GtkPopover" id="project_popover">
+    <property name="border-width">12</property>
+    <property name="visible">true</property>
+    <child>
+      <object class="GtkBox">
+        <property name="orientation">vertical</property>
+        <property name="spacing">6</property>
+        <property name="visible">true</property>
+        <child>
+          <object class="GtkModelButton">
+            <property name="action-name">workbench.build</property>
+            <property name="halign">fill</property>
+            <property name="hexpand">true</property>
+            <property name="text" translatable="yes">Build Project</property>
+            <property name="visible">true</property>
+          </object>
+        </child>
+        <child>
+          <object class="GtkModelButton">
+            <property name="action-name">workbench.rebuild</property>
+            <property name="halign">fill</property>
+            <property name="hexpand">true</property>
+            <property name="text" translatable="yes">Rebuild Project</property>
+            <property name="visible">true</property>
+          </object>
+        </child>
+      </object>
+    </child>
+  </object>
 </interface>
diff --git a/src/editor/gb-editor-workspace-private.h b/src/editor/gb-editor-workspace-private.h
index c0df98f..29e9777 100644
--- a/src/editor/gb-editor-workspace-private.h
+++ b/src/editor/gb-editor-workspace-private.h
@@ -31,6 +31,7 @@ struct _GbEditorWorkspace
 
   GtkPaned      *project_paned;
   GtkBox        *project_sidebar;
+  GtkMenuButton *project_button;
   GbTree        *project_tree;
   GbTreeBuilder *project_tree_builder;
   GbViewGrid    *view_grid;
diff --git a/src/editor/gb-editor-workspace.c b/src/editor/gb-editor-workspace.c
index e778de9..01a5f8e 100644
--- a/src/editor/gb-editor-workspace.c
+++ b/src/editor/gb-editor-workspace.c
@@ -89,6 +89,7 @@ gb_editor_workspace_context_changed (GtkWidget  *workspace,
   if (context)
     {
       IdeBufferManager *bufmgr;
+      IdeProject *project;
       g_autoptr(GPtrArray) buffers = NULL;
       gsize i;
 
@@ -112,6 +113,10 @@ gb_editor_workspace_context_changed (GtkWidget  *workspace,
           gb_editor_workspace__load_buffer_cb (self, buffer, bufmgr);
         }
 
+      project = ide_context_get_project (context);
+      g_object_bind_property (project, "name", self->project_button, "label",
+                              G_BINDING_SYNC_CREATE);
+
       root = gb_tree_get_root (self->project_tree);
       gb_tree_node_set_item (root, G_OBJECT (context));
 
@@ -165,6 +170,7 @@ gb_editor_workspace_class_init (GbEditorWorkspaceClass *klass)
 
   GB_WIDGET_CLASS_TEMPLATE (klass, "gb-editor-workspace.ui");
 
+  GB_WIDGET_CLASS_BIND (klass, GbEditorWorkspace, project_button);
   GB_WIDGET_CLASS_BIND (klass, GbEditorWorkspace, project_paned);
   GB_WIDGET_CLASS_BIND (klass, GbEditorWorkspace, project_sidebar);
   GB_WIDGET_CLASS_BIND (klass, GbEditorWorkspace, project_tree);
diff --git a/src/workbench/gb-workbench-actions.c b/src/workbench/gb-workbench-actions.c
index 56812a5..eeda7b5 100644
--- a/src/workbench/gb-workbench-actions.c
+++ b/src/workbench/gb-workbench-actions.c
@@ -26,87 +26,27 @@
 #include "gb-workbench-private.h"
 
 static void
-gb_workbench_actions__build_cb (GObject      *object,
-                                GAsyncResult *result,
-                                gpointer      user_data)
+gb_workbench_actions_build (GSimpleAction *action,
+                            GVariant      *parameter,
+                            gpointer       user_data)
 {
-  g_autoptr(GbWorkbench) workbench = user_data;
-  g_autoptr(IdeBuildResult) build_result = NULL;
-  g_autoptr(GError) error = NULL;
-  IdeBuilder *builder = (IdeBuilder *)object;
-
-  g_assert (GB_IS_WORKBENCH (workbench));
+  GbWorkbench *self = user_data;
 
-  build_result = ide_builder_build_finish (builder, result, &error);
+  g_assert (GB_IS_WORKBENCH (self));
 
-  if (error)
-    {
-      GtkWidget *dialog;
-
-      dialog = gtk_message_dialog_new (GTK_WINDOW (workbench),
-                                       GTK_DIALOG_MODAL | GTK_DIALOG_USE_HEADER_BAR,
-                                       GTK_MESSAGE_ERROR,
-                                       GTK_BUTTONS_CLOSE,
-                                       _("Build Failure"));
-      gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", error->message);
-      g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
-      gtk_window_present (GTK_WINDOW (dialog));
-    }
+  gb_workbench_build_async (self, FALSE, NULL, NULL, NULL);
 }
 
 static void
-gb_workbench_actions_build (GSimpleAction *action,
-                            GVariant      *parameter,
-                            gpointer       user_data)
+gb_workbench_actions_rebuild (GSimpleAction *action,
+                              GVariant      *parameter,
+                              gpointer       user_data)
 {
-  GbWorkbench *workbench = user_data;
-  IdeDeviceManager *device_manager;
-  IdeBuildSystem *build_system;
-  IdeContext *context;
-  IdeDevice *device;
-  g_autoptr(IdeBuilder) builder = NULL;
-  g_autoptr(GKeyFile) config = NULL;
-  g_autoptr(GError) error = NULL;
-
-  /*
-   * TODO: We want to have the ability to choose the device we want to build for.  The simple answer
-   * here is to just have a combo of sorts to choose the target device. But that is going to be left
-   * to the designers to figure out the right way to go about it.
-   *
-   * For now, we will just automatically build with the "local" device.
-   */
-
-  g_assert (GB_IS_WORKBENCH (workbench));
-
-  context = gb_workbench_get_context (workbench);
-  device_manager = ide_context_get_device_manager (context);
-  device = ide_device_manager_get_device (device_manager, "local");
-  build_system = ide_context_get_build_system (context);
-  config = g_key_file_new ();
-  builder = ide_build_system_get_builder (build_system, config, device, &error);
-
-  if (builder == NULL)
-    {
-      GtkWidget *dialog;
-
-      dialog = gtk_message_dialog_new (GTK_WINDOW (workbench),
-                                       GTK_DIALOG_MODAL | GTK_DIALOG_USE_HEADER_BAR,
-                                       GTK_MESSAGE_ERROR,
-                                       GTK_BUTTONS_CLOSE,
-                                       _("Project build system does not support building"));
-      if (error && error->message)
-        gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
-                                                  "%s", error->message);
-      g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
-      gtk_window_present (GTK_WINDOW (dialog));
-      return;
-    }
+  GbWorkbench *self = user_data;
 
-  ide_builder_build_async (builder,
-                           NULL,
-                           NULL, /* todo: cancellable */
-                           gb_workbench_actions__build_cb,
-                           g_object_ref (workbench));
+  g_assert (GB_IS_WORKBENCH (self));
+
+  gb_workbench_build_async (self, TRUE, NULL, NULL, NULL);
 }
 
 static void
@@ -325,6 +265,7 @@ static const GActionEntry GbWorkbenchActions[] = {
   { "nighthack",        gb_workbench_actions_nighthack },
   { "open",             gb_workbench_actions_open },
   { "open-uri-list",    gb_workbench_actions_open_uri_list, "as" },
+  { "rebuild",          gb_workbench_actions_rebuild },
   { "save-all",         gb_workbench_actions_save_all },
   { "search-docs",      gb_workbench_actions_search_docs, "s" },
   { "show-command-bar", gb_workbench_actions_show_command_bar },
@@ -334,11 +275,21 @@ void
 gb_workbench_actions_init (GbWorkbench *self)
 {
   GSimpleActionGroup *actions;
+  GAction *action;
 
   g_assert (GB_IS_WORKBENCH (self));
 
   actions = g_simple_action_group_new ();
   g_action_map_add_action_entries (G_ACTION_MAP (actions), GbWorkbenchActions,
                                    G_N_ELEMENTS (GbWorkbenchActions), self);
+
+  action = g_action_map_lookup_action (G_ACTION_MAP (actions), "build");
+  g_object_bind_property (self, "building", action, "enabled",
+                          (G_BINDING_SYNC_CREATE | G_BINDING_INVERT_BOOLEAN));
+
+  action = g_action_map_lookup_action (G_ACTION_MAP (actions), "rebuild");
+  g_object_bind_property (self, "building", action, "enabled",
+                          (G_BINDING_SYNC_CREATE | G_BINDING_INVERT_BOOLEAN));
+
   gtk_widget_insert_action_group (GTK_WIDGET (self), "workbench", G_ACTION_GROUP (actions));
 }
diff --git a/src/workbench/gb-workbench.c b/src/workbench/gb-workbench.c
index 2b987bf..406fc8a 100644
--- a/src/workbench/gb-workbench.c
+++ b/src/workbench/gb-workbench.c
@@ -35,6 +35,7 @@ G_DEFINE_TYPE (GbWorkbench, gb_workbench, GTK_TYPE_APPLICATION_WINDOW)
 enum {
   PROP_0,
   PROP_ACTIVE_WORKSPACE,
+  PROP_BUILDING,
   PROP_COMMAND_MANAGER,
   PROP_CONTEXT,
   LAST_PROP
@@ -291,6 +292,10 @@ gb_workbench_get_property (GObject    *object,
       g_value_set_object (value, gb_workbench_get_active_workspace (self));
       break;
 
+    case PROP_BUILDING:
+      g_value_set_boolean (value, self->building);
+      break;
+
     case PROP_COMMAND_MANAGER:
       g_value_set_object (value, gb_workbench_get_command_manager (self));
       break;
@@ -356,6 +361,14 @@ gb_workbench_class_init (GbWorkbenchClass *klass)
   g_object_class_install_property (object_class, PROP_ACTIVE_WORKSPACE,
                                    gParamSpecs [PROP_ACTIVE_WORKSPACE]);
 
+  gParamSpecs [PROP_BUILDING] =
+    g_param_spec_boolean ("building",
+                          _("Building"),
+                          _("If the project is currently building."),
+                          FALSE,
+                          (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (object_class, PROP_BUILDING, gParamSpecs [PROP_BUILDING]);
+
   gParamSpecs [PROP_COMMAND_MANAGER] =
     g_param_spec_object ("command-manager",
                          _("Command Manager"),
@@ -625,3 +638,112 @@ gb_workbench_get_workspace_typed (GbWorkbench *self,
 
   return NULL;
 }
+
+static void
+gb_workbench__builder_build_cb (GObject      *object,
+                                GAsyncResult *result,
+                                gpointer      user_data)
+{
+  g_autoptr(GbWorkbench) self = user_data;
+  g_autoptr(IdeBuildResult) build_result = NULL;
+  g_autoptr(GError) error = NULL;
+  IdeBuilder *builder = (IdeBuilder *)object;
+
+  g_assert (IDE_IS_BUILDER (builder));
+  g_assert (GB_IS_WORKBENCH (self));
+
+  self->building = FALSE;
+  g_object_notify_by_pspec (G_OBJECT (self), gParamSpecs [PROP_BUILDING]);
+
+  build_result = ide_builder_build_finish (builder, result, &error);
+
+  if (error)
+    {
+      GtkWidget *dialog;
+
+      dialog = gtk_message_dialog_new (GTK_WINDOW (self),
+                                       GTK_DIALOG_MODAL | GTK_DIALOG_USE_HEADER_BAR,
+                                       GTK_MESSAGE_ERROR,
+                                       GTK_BUTTONS_CLOSE,
+                                       _("Build Failure"));
+      gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", error->message);
+      g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
+      gtk_window_present (GTK_WINDOW (dialog));
+    }
+}
+
+void
+gb_workbench_build_async (GbWorkbench         *self,
+                          gboolean             force_rebuild,
+                          GCancellable        *cancellable,
+                          GAsyncReadyCallback  callback,
+                          gpointer             user_data)
+{
+  IdeDeviceManager *device_manager;
+  IdeBuildSystem *build_system;
+  IdeContext *context;
+  IdeDevice *device;
+  g_autoptr(IdeBuilder) builder = NULL;
+  g_autoptr(GKeyFile) config = NULL;
+  g_autoptr(GError) error = NULL;
+
+  g_return_if_fail (GB_IS_WORKBENCH (self));
+  g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  context = gb_workbench_get_context (self);
+
+  /* TODO: Get build device from workbench combo? */
+  device_manager = ide_context_get_device_manager (context);
+  device = ide_device_manager_get_device (device_manager, "local");
+
+  build_system = ide_context_get_build_system (context);
+
+  config = g_key_file_new ();
+
+  if (force_rebuild)
+    {
+      /* TODO: we should make this type of operation build system agnostic. */
+      g_key_file_set_boolean (config, "autotools", "rebuild", TRUE);
+    }
+
+  builder = ide_build_system_get_builder (build_system, config, device, &error);
+
+  if (builder == NULL)
+    {
+      GtkWidget *dialog;
+
+      dialog = gtk_message_dialog_new (GTK_WINDOW (self),
+                                       GTK_DIALOG_MODAL | GTK_DIALOG_USE_HEADER_BAR,
+                                       GTK_MESSAGE_ERROR,
+                                       GTK_BUTTONS_CLOSE,
+                                       _("Project build system does not support building"));
+      if (error && error->message)
+        gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+                                                  "%s", error->message);
+      g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
+      gtk_window_present (GTK_WINDOW (dialog));
+      return;
+    }
+
+  self->building = TRUE;
+  g_object_notify_by_pspec (G_OBJECT (self), gParamSpecs [PROP_BUILDING]);
+
+  ide_builder_build_async (builder,
+                           NULL, /* &IdeProgress */
+                           cancellable,
+                           gb_workbench__builder_build_cb,
+                           g_object_ref (self));
+}
+
+gboolean
+gb_workbench_build_finish (GbWorkbench   *self,
+                           GAsyncResult  *result,
+                           GError       **error)
+{
+  GTask *task = (GTask *)result;
+
+  g_return_val_if_fail (GB_IS_WORKBENCH (self), FALSE);
+  g_return_val_if_fail (G_IS_TASK (task), FALSE);
+
+  return g_task_propagate_boolean (task, error);
+}
diff --git a/src/workbench/gb-workbench.h b/src/workbench/gb-workbench.h
index 17e6182..8f0d65e 100644
--- a/src/workbench/gb-workbench.h
+++ b/src/workbench/gb-workbench.h
@@ -31,6 +31,14 @@ G_BEGIN_DECLS
 
 G_DECLARE_FINAL_TYPE (GbWorkbench, gb_workbench, GB, WORKBENCH, GtkApplicationWindow)
 
+void              gb_workbench_build_async          (GbWorkbench         *self,
+                                                     gboolean             force_rebuild,
+                                                     GCancellable        *cancellable,
+                                                     GAsyncReadyCallback  callback,
+                                                     gpointer             user_data);
+gboolean          gb_workbench_build_finish         (GbWorkbench         *self,
+                                                     GAsyncResult        *result,
+                                                     GError             **error);
 IdeContext       *gb_workbench_get_context          (GbWorkbench         *self);
 GbWorkspace      *gb_workbench_get_active_workspace (GbWorkbench         *self);
 void              gb_workbench_set_active_workspace (GbWorkbench         *self,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]