[gnome-builder] greeter: add newcomer projects to greeter



commit 0c3ed8e06e4ca58cedff016095dd15426c84c2d3
Author: Christian Hergert <chergert redhat com>
Date:   Fri Nov 10 00:15:19 2017 -0800

    greeter: add newcomer projects to greeter
    
    This adds the newcomer projects to the greeter ui. I chose to
    just use GtkBuilder UI XML instead of a description file so
    that we could take advantage of our translators without having
    to come up with some alternate i18n integration for gettext.
    
    We probably still need some more info like programming
    language and tooltip-text.

 src/libide/greeter/ide-greeter-perspective.c  |  168 ++++++++++++++++++++++++-
 src/libide/greeter/ide-greeter-perspective.ui |  171 +++++++++++++++++++-----
 2 files changed, 301 insertions(+), 38 deletions(-)
---
diff --git a/src/libide/greeter/ide-greeter-perspective.c b/src/libide/greeter/ide-greeter-perspective.c
index 32cc8e3..f516484 100644
--- a/src/libide/greeter/ide-greeter-perspective.c
+++ b/src/libide/greeter/ide-greeter-perspective.c
@@ -22,12 +22,14 @@
 #include <glib/gi18n.h>
 #include <libpeas/peas.h>
 
+#include "ide-debug.h"
 #include "ide-macros.h"
 
 #include "application/ide-application.h"
 #include "genesis/ide-genesis-addin.h"
 #include "greeter/ide-greeter-perspective.h"
 #include "greeter/ide-greeter-project-row.h"
+#include "greeter/ide-newcomer-project.h"
 #include "util/ide-gtk.h"
 #include "workbench/ide-perspective.h"
 #include "workbench/ide-workbench-private.h"
@@ -65,6 +67,7 @@ struct _IdeGreeterPerspective
   DzlStateMachine      *state_machine;
   GtkScrolledWindow    *scrolled_window;
   DzlPriorityBox       *genesis_buttons;
+  GtkFlowBox           *newcomer_projects;
 
   gint                  selected_count;
 };
@@ -1067,6 +1070,158 @@ ide_greeter_perspective_info_bar_response (IdeGreeterPerspective *self,
 }
 
 static void
+ide_greeter_perspective_maybe_clone (PeasExtensionSet *set,
+                                     PeasPluginInfo   *plugin_info,
+                                     PeasExtension    *exten,
+                                     gpointer          user_data)
+{
+  IdeGenesisAddin *addin = (IdeGenesisAddin *)exten;
+  struct {
+    IdeGreeterPerspective *self;
+    IdeVcsUri *uri;
+    gboolean found;
+  } *lookup = user_data;
+
+  g_assert (PEAS_IS_EXTENSION_SET (set));
+  g_assert (plugin_info != NULL);
+  g_assert (IDE_IS_GENESIS_ADDIN (addin));
+  g_assert (lookup != NULL);
+
+  if (lookup->found)
+    return;
+
+  lookup->found = ide_genesis_addin_apply_uri (addin, lookup->uri);
+
+  if (lookup->found)
+    {
+      GtkWidget *child = ide_genesis_addin_get_widget (addin);
+
+      if (child != NULL)
+        {
+          gtk_stack_set_visible_child (lookup->self->genesis_stack, child);
+          dzl_state_machine_set_state (lookup->self->state_machine, "genesis");
+          gtk_widget_hide (GTK_WIDGET (lookup->self->genesis_continue_button));
+          ide_greeter_perspective_genesis_continue (lookup->self);
+        }
+    }
+}
+
+static gchar *
+get_project_directory (const gchar *name)
+{
+  g_autoptr(GSettings) settings = NULL;
+  g_autofree gchar *projects = NULL;
+
+  settings = g_settings_new ("org.gnome.builder");
+  projects = g_settings_get_string (settings, "projects-directory");
+
+  if (!g_path_is_absolute (projects))
+    return g_build_filename (g_get_home_dir (), projects, name, NULL);
+  else
+    return g_build_filename (projects, name, NULL);
+}
+
+static gboolean
+ide_greeter_perspective_load_project (IdeGreeterPerspective *self,
+                                      IdeNewcomerProject    *project)
+{
+  g_autofree gchar *dir = NULL;
+  g_autofree gchar *maybe_project = NULL;
+  g_autofree gchar *relocated = NULL;
+  IdeRecentProjects *projects;
+  const gchar *path;
+  const gchar *str;
+  IdeVcsUri *uri;
+
+  g_assert (IDE_IS_GREETER_PERSPECTIVE (self));
+  g_assert (IDE_IS_NEWCOMER_PROJECT (project));
+
+  projects = ide_application_get_recent_projects (IDE_APPLICATION_DEFAULT);
+  str = ide_newcomer_project_get_uri (project);
+  uri = ide_vcs_uri_new (str);
+  path = ide_vcs_uri_get_path (uri);
+  dir = g_path_get_basename (path);
+
+  if (g_str_has_suffix (dir, ".git"))
+    dir[strlen (dir) - 4] = '\0';
+
+  maybe_project = get_project_directory (dir);
+  relocated = ide_recent_projects_find_by_directory (projects, maybe_project);
+
+  if (relocated != NULL)
+    {
+      g_autoptr(GFile) file = g_file_new_for_path (relocated);
+      IdeWorkbench *workbench = ide_widget_get_workbench (GTK_WIDGET (self));
+
+      ide_workbench_open_project_async (workbench, file, NULL, NULL, NULL);
+
+      return TRUE;
+    }
+
+  /* If the test exists, we probably should just open that
+   * instead of trying to reclone, which would fail anyway since
+   * this directory already exists.
+   */
+  if (g_file_test (maybe_project, G_FILE_TEST_IS_DIR))
+    {
+      g_autoptr(GFile) file = g_file_new_for_path (maybe_project);
+      IdeWorkbench *workbench = ide_widget_get_workbench (GTK_WIDGET (self));
+
+      ide_workbench_open_project_async (workbench, file, NULL, NULL, NULL);
+
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+static void
+ide_greeter_perspective__newcomer_activated (IdeGreeterPerspective *self,
+                                             GtkFlowBoxChild       *child,
+                                             GtkFlowBox            *flow_box)
+{
+  g_autoptr(IdeVcsUri) vcs_uri = NULL;
+  IdeNewcomerProject *project;
+  const gchar *uri;
+  struct {
+    IdeGreeterPerspective *self;
+    IdeVcsUri *uri;
+    gboolean found;
+  } lookup;
+
+  IDE_ENTRY;
+
+  g_return_if_fail (IDE_IS_GREETER_PERSPECTIVE (self));
+  g_return_if_fail (GTK_IS_FLOW_BOX_CHILD (child));
+  g_return_if_fail (GTK_IS_FLOW_BOX (flow_box));
+
+  project = IDE_NEWCOMER_PROJECT (gtk_bin_get_child (GTK_BIN (child)));
+
+  /* Try to reload the project if they've already opened
+   * this one before. Look at our recent projects and if not
+   * there, the Projects directory for a matching project
+   * directory name from the uri.
+   */
+  if (ide_greeter_perspective_load_project (self, project))
+    IDE_EXIT;
+
+  uri = ide_newcomer_project_get_uri (project);
+  vcs_uri = ide_vcs_uri_new (uri);
+
+  IDE_TRACE_MSG ("Looking for genesis addin to handle %s", uri);
+
+  lookup.self = self;
+  lookup.uri = vcs_uri;
+  lookup.found = FALSE;
+
+  peas_extension_set_foreach (self->genesis_set,
+                              ide_greeter_perspective_maybe_clone,
+                              &lookup);
+
+  IDE_EXIT;
+}
+
+static void
 ide_greeter_perspective_constructed (GObject *object)
 {
   IdeGreeterPerspective *self = (IdeGreeterPerspective *)object;
@@ -1167,9 +1322,10 @@ ide_greeter_perspective_class_init (IdeGreeterPerspectiveClass *klass)
 
   gtk_widget_class_set_template_from_resource (widget_class, 
"/org/gnome/builder/ui/ide-greeter-perspective.ui");
   gtk_widget_class_set_css_name (widget_class, "greeter");
+  gtk_widget_class_bind_template_child (widget_class, IdeGreeterPerspective, cancel_button);
   gtk_widget_class_bind_template_child (widget_class, IdeGreeterPerspective, genesis_buttons);
-  gtk_widget_class_bind_template_child (widget_class, IdeGreeterPerspective, genesis_continue_button);
   gtk_widget_class_bind_template_child (widget_class, IdeGreeterPerspective, genesis_cancel_button);
+  gtk_widget_class_bind_template_child (widget_class, IdeGreeterPerspective, genesis_continue_button);
   gtk_widget_class_bind_template_child (widget_class, IdeGreeterPerspective, genesis_stack);
   gtk_widget_class_bind_template_child (widget_class, IdeGreeterPerspective, genesis_title);
   gtk_widget_class_bind_template_child (widget_class, IdeGreeterPerspective, info_bar);
@@ -1177,8 +1333,8 @@ ide_greeter_perspective_class_init (IdeGreeterPerspectiveClass *klass)
   gtk_widget_class_bind_template_child (widget_class, IdeGreeterPerspective, info_bar_revealer);
   gtk_widget_class_bind_template_child (widget_class, IdeGreeterPerspective, my_projects_container);
   gtk_widget_class_bind_template_child (widget_class, IdeGreeterPerspective, my_projects_list_box);
+  gtk_widget_class_bind_template_child (widget_class, IdeGreeterPerspective, newcomer_projects);
   gtk_widget_class_bind_template_child (widget_class, IdeGreeterPerspective, open_button);
-  gtk_widget_class_bind_template_child (widget_class, IdeGreeterPerspective, cancel_button);
   gtk_widget_class_bind_template_child (widget_class, IdeGreeterPerspective, remove_button);
   gtk_widget_class_bind_template_child (widget_class, IdeGreeterPerspective, scrolled_window);
   gtk_widget_class_bind_template_child (widget_class, IdeGreeterPerspective, search_entry);
@@ -1187,6 +1343,8 @@ ide_greeter_perspective_class_init (IdeGreeterPerspectiveClass *klass)
   gtk_widget_class_bind_template_child (widget_class, IdeGreeterPerspective, titlebar);
   gtk_widget_class_bind_template_child (widget_class, IdeGreeterPerspective, top_stack);
   gtk_widget_class_bind_template_child (widget_class, IdeGreeterPerspective, viewport);
+
+  g_type_ensure (IDE_TYPE_NEWCOMER_PROJECT);
 }
 
 static const GActionEntry actions[] = {
@@ -1237,6 +1395,12 @@ ide_greeter_perspective_init (IdeGreeterPerspective *self)
                            self,
                            G_CONNECT_SWAPPED);
 
+  g_signal_connect_object (self->newcomer_projects,
+                           "child-activated",
+                           G_CALLBACK (ide_greeter_perspective__newcomer_activated),
+                           self,
+                           G_CONNECT_SWAPPED);
+
   g_signal_connect_object (self->top_stack,
                            "notify::visible-child",
                            G_CALLBACK (ide_greeter_perspective_genesis_changed),
diff --git a/src/libide/greeter/ide-greeter-perspective.ui b/src/libide/greeter/ide-greeter-perspective.ui
index 15653dc..6e9587b 100644
--- a/src/libide/greeter/ide-greeter-perspective.ui
+++ b/src/libide/greeter/ide-greeter-perspective.ui
@@ -71,66 +71,165 @@
                                 <property name="expand">true</property>
                                 <property name="visible">true</property>
                                 <child>
-                                  <object class="DzlBox">
-                                    <property name="halign">center</property>
-                                    <property name="hexpand">false</property>
-                                    <property name="margin-bottom">32</property>
-                                    <property name="margin-top">32</property>
+                                  <object class="GtkBox">
                                     <property name="orientation">vertical</property>
                                     <property name="spacing">32</property>
                                     <property name="visible">true</property>
-                                    <property name="max-width-request">600</property>
+                                    <property name="margin">32</property>
                                     <child>
-                                      <object class="GtkSearchEntry" id="search_entry">
-                                        <property name="width-chars">45</property>
+                                      <object class="DzlBox">
                                         <property name="halign">center</property>
+                                        <property name="hexpand">false</property>
+                                        <property name="orientation">vertical</property>
+                                        <property name="spacing">32</property>
                                         <property name="visible">true</property>
+                                        <property name="max-width-request">600</property>
+                                        <child>
+                                          <object class="GtkSearchEntry" id="search_entry">
+                                            <property name="width-chars">45</property>
+                                            <property name="halign">center</property>
+                                            <property name="visible">true</property>
+                                          </object>
+                                        </child>
+                                        <child>
+                                          <object class="GtkBox" id="my_projects_container">
+                                            <property name="orientation">vertical</property>
+                                            <property name="spacing">6</property>
+                                            <property name="visible">true</property>
+                                            <child>
+                                              <object class="GtkBox">
+                                                <property name="visible">true</property>
+                                                <child>
+                                                  <object class="GtkLabel" id="my_projects_label">
+                                                    <property name="label" translatable="yes">Recent 
Projects</property>
+                                                    <property name="visible">true</property>
+                                                    <property name="xalign">0.0</property>
+                                                    <property name="hexpand">true</property>
+                                                    <style>
+                                                      <class name="dim-label"/>
+                                                    </style>
+                                                    <attributes>
+                                                      <attribute name="weight" value="bold"/>
+                                                    </attributes>
+                                                  </object>
+                                                </child>
+                                                <child>
+                                                  <object class="GtkLabel">
+                                                    <property name="visible">true</property>
+                                                    <property name="label" 
translatable="yes">Updated</property>
+                                                    <property name="margin-end">10</property>
+                                                    <property name="halign">end</property>
+                                                    <style>
+                                                      <class name="dim-label"/>
+                                                    </style>
+                                                  </object>
+                                                </child>
+                                              </object>
+                                            </child>
+                                            <child>
+                                              <object class="GtkFrame">
+                                                <property name="halign">center</property>
+                                                <property name="visible">true</property>
+                                                <property name="width-request">600</property>
+                                                <child>
+                                                  <object class="GtkListBox" id="my_projects_list_box">
+                                                    <property name="visible">true</property>
+                                                    <property name="selection-mode">none</property>
+                                                  </object>
+                                                </child>
+                                              </object>
+                                            </child>
+                                          </object>
+                                        </child>
                                       </object>
                                     </child>
                                     <child>
-                                      <object class="GtkBox" id="my_projects_container">
+                                      <object class="GtkBox">
                                         <property name="orientation">vertical</property>
                                         <property name="spacing">6</property>
                                         <property name="visible">true</property>
                                         <child>
-                                          <object class="GtkBox">
+                                          <object class="GtkLabel">
+                                            <property name="label" translatable="yes">Newcomer 
Projects</property>
                                             <property name="visible">true</property>
+                                            <style>
+                                              <class name="dim-label"/>
+                                            </style>
+                                            <attributes>
+                                              <attribute name="weight" value="bold"/>
+                                            </attributes>
+                                          </object>
+                                        </child>
+                                        <child>
+                                          <object class="GtkFlowBox" id="newcomer_projects">
+                                            <property name="visible">true</property>
+                                            <property name="halign">center</property>
+                                            <property name="valign">start</property>
+                                            <property name="selection-mode">browse</property>
+                                            <property name="min-children-per-line">3</property>
+                                            <property name="max-children-per-line">5</property>
                                             <child>
-                                              <object class="GtkLabel" id="my_projects_label">
-                                                <property name="label" translatable="yes">Recent 
Projects</property>
+                                              <object class="IdeNewcomerProject">
+                                                <property name="name" translatable="yes">Polari</property>
+                                                <property name="icon-name">org.gnome.Polari</property>
+                                                <property 
name="uri">https://gitlab.gnome.org/GNOME/polari.git</property>
                                                 <property name="visible">true</property>
-                                                <property name="xalign">0.0</property>
-                                                <property name="hexpand">true</property>
-                                                <style>
-                                                  <class name="dim-label"/>
-                                                </style>
-                                                <attributes>
-                                                  <attribute name="weight" value="bold"/>
-                                                </attributes>
                                               </object>
                                             </child>
                                             <child>
-                                              <object class="GtkLabel">
+                                              <object class="IdeNewcomerProject">
+                                                <property name="name" translatable="yes">Games</property>
+                                                <property name="icon-name">org.gnome.Games</property>
+                                                <property 
name="uri">https://git.gnome.org/browse/gnome-games</property>
+                                                <property name="visible">true</property>
+                                              </object>
+                                            </child>
+                                            <child>
+                                              <object class="IdeNewcomerProject">
+                                                <property name="name" translatable="yes">Maps</property>
+                                                <property name="icon-name">org.gnome.Maps</property>
+                                                <property 
name="uri">https://git.gnome.org/browse/gnome-maps</property>
+                                                <property name="visible">true</property>
+                                              </object>
+                                            </child>
+                                            <child>
+                                              <object class="IdeNewcomerProject">
+                                                <property name="name" translatable="yes">Todo</property>
+                                                <property name="icon-name">org.gnome.Todo</property>
+                                                <property 
name="uri">https://gitlab.gnome.org/GNOME/gnome-todo.git</property>
+                                                <property name="visible">true</property>
+                                              </object>
+                                            </child>
+                                            <child>
+                                              <object class="IdeNewcomerProject">
+                                                <property name="name" translatable="yes">Music</property>
+                                                <property name="icon-name">org.gnome.Music</property>
+                                                <property 
name="uri">https://git.gnome.org/browse/gnome-music</property>
+                                                <property name="visible">true</property>
+                                              </object>
+                                            </child>
+                                            <child>
+                                              <object class="IdeNewcomerProject">
+                                                <property name="name" translatable="yes">Nautilus</property>
+                                                <property name="icon-name">org.gnome.Nautilus</property>
+                                                <property 
name="uri">https://gitlab.gnome.org/GNOME/nautilus.git</property>
+                                                <property name="visible">true</property>
+                                              </object>
+                                            </child>
+                                            <child>
+                                              <object class="IdeNewcomerProject">
+                                                <property name="name" translatable="yes">Photos</property>
+                                                <property name="icon-name">org.gnome.Photos</property>
+                                                <property 
name="uri">https://git.gnome.org/browse/gnome-photos</property>
                                                 <property name="visible">true</property>
-                                                <property name="label" translatable="yes">Updated</property>
-                                                <property name="margin-end">10</property>
-                                                <property name="halign">end</property>
-                                                <style>
-                                                  <class name="dim-label"/>
-                                                </style>
                                               </object>
                                             </child>
-                                          </object>
-                                        </child>
-                                        <child>
-                                          <object class="GtkFrame">
-                                            <property name="halign">center</property>
-                                            <property name="visible">true</property>
-                                            <property name="width-request">600</property>
                                             <child>
-                                              <object class="GtkListBox" id="my_projects_list_box">
+                                              <object class="IdeNewcomerProject">
+                                                <property name="name" translatable="yes">Calendar</property>
+                                                <property name="icon-name">org.gnome.Calendar</property>
+                                                <property 
name="uri">https://git.gnome.org/browse/gnome-calendar.git</property>
                                                 <property name="visible">true</property>
-                                                <property name="selection-mode">none</property>
                                               </object>
                                             </child>
                                           </object>


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