[gnome-calendar/gbsneto/gtk4: 30/46] importer: Port to GTK4




commit fcfb387f5ae0a2d05a471ae94f01a4de97a60e0e
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Fri Jan 21 18:20:51 2022 -0300

    importer: Port to GTK4

 src/core/gcal-manager.c                  |  58 +++++
 src/core/gcal-manager.h                  |   2 +
 src/gui/importer/gcal-import-dialog.c    | 362 +++++++++++--------------------
 src/gui/importer/gcal-import-dialog.h    |   4 +-
 src/gui/importer/gcal-import-dialog.ui   | 222 +++++--------------
 src/gui/importer/gcal-import-file-row.c  |  22 +-
 src/gui/importer/gcal-import-file-row.h  |   6 +-
 src/gui/importer/gcal-import-file-row.ui |  41 +---
 8 files changed, 253 insertions(+), 464 deletions(-)
---
diff --git a/src/core/gcal-manager.c b/src/core/gcal-manager.c
index e2a98653..c594829e 100644
--- a/src/core/gcal-manager.c
+++ b/src/core/gcal-manager.c
@@ -64,6 +64,7 @@ struct _GcalManager
    * And each key is the source uid
    */
   GHashTable         *clients;
+  GListStore         *calendars_model;
 
   ESourceRegistry    *source_registry;
   //ECredentialsPrompter *credentials_prompter;
@@ -111,6 +112,7 @@ remove_source (GcalManager  *self,
                ESource      *source)
 {
   g_autoptr (GcalCalendar) calendar = NULL;
+  guint position;
 
   GCAL_ENTRY;
 
@@ -130,6 +132,10 @@ remove_source (GcalManager  *self,
 
   gcal_timeline_remove_calendar (self->timeline, calendar);
   g_hash_table_remove (self->clients, source);
+
+  g_list_store_find (self->calendars_model, calendar, &position);
+  g_list_store_remove (self->calendars_model, position);
+
   g_signal_emit (self, signals[CALENDAR_REMOVED], 0, calendar);
 
   GCAL_EXIT;
@@ -182,6 +188,37 @@ on_client_refreshed (GObject      *source_object,
   GCAL_EXIT;
 }
 
+static gint
+sort_calendar_by_name_cb (gconstpointer a,
+                          gconstpointer b,
+                          gpointer      user_data)
+{
+  GcalCalendar *calendar_a = GCAL_CALENDAR ((gpointer) a);
+  GcalCalendar *calendar_b = GCAL_CALENDAR ((gpointer) b);
+  g_autofree gchar *parent_name_a = NULL;
+  g_autofree gchar *parent_name_b = NULL;
+  GcalManager *self;
+  gint retval;
+
+  retval = g_utf8_collate (gcal_calendar_get_name (calendar_a), gcal_calendar_get_name (calendar_b));
+  if (retval != 0)
+    return retval;
+
+  self = GCAL_MANAGER (user_data);
+  get_source_parent_name_color (self, gcal_calendar_get_source (calendar_a), &parent_name_a, NULL);
+  get_source_parent_name_color (self, gcal_calendar_get_source (calendar_b), &parent_name_b, NULL);
+
+  return g_utf8_collate (parent_name_a, parent_name_b);
+}
+
+static void
+on_calendar_name_changed_cb (GcalCalendar *calendar,
+                             GParamSpec   *pspec,
+                             GcalManager  *self)
+{
+  g_list_store_sort (self->calendars_model, sort_calendar_by_name_cb, self);
+}
+
 static void
 on_calendar_created_cb (GObject      *source_object,
                         GAsyncResult *result,
@@ -219,6 +256,8 @@ on_calendar_created_cb (GObject      *source_object,
   source = gcal_calendar_get_source (calendar);
 
   g_hash_table_insert (self->clients, g_object_ref (source), calendar);
+  g_list_store_insert_sorted (self->calendars_model, calendar, sort_calendar_by_name_cb, self);
+  g_signal_connect (calendar, "notify::name", G_CALLBACK (on_calendar_name_changed_cb), self);
 
   gcal_timeline_add_calendar (self->timeline, calendar);
 
@@ -559,6 +598,7 @@ gcal_manager_finalize (GObject *object)
       self->context = NULL;
     }
 
+  g_clear_object (&self->calendars_model);
   g_clear_pointer (&self->clients, g_hash_table_destroy);
 
   G_OBJECT_CLASS (gcal_manager_parent_class)->finalize (object);
@@ -703,6 +743,7 @@ gcal_manager_class_init (GcalManagerClass *klass)
 static void
 gcal_manager_init (GcalManager *self)
 {
+  self->calendars_model = g_list_store_new (GCAL_TYPE_CALENDAR);
 }
 
 /* Public API */
@@ -750,6 +791,23 @@ gcal_manager_get_calendars (GcalManager *self)
   return g_hash_table_get_values (self->clients);
 }
 
+/**
+ * gcal_manager_get_calendars_model:
+ * @self: a #GcalManager
+ *
+ * Retrieves a model with all available #GcalCalendar. This is useful
+ * for binding to combo rows.
+ *
+ * Returns: (transfer none): a #GListModel with all available #GcalCalendar
+ */
+GListModel*
+gcal_manager_get_calendars_model (GcalManager *self)
+{
+  g_return_val_if_fail (GCAL_IS_MANAGER (self), NULL);
+
+  return G_LIST_MODEL (self->calendars_model);
+}
+
 /**
  * gcal_manager_get_default_calendar:
  * @self: a #GcalManager
diff --git a/src/core/gcal-manager.h b/src/core/gcal-manager.h
index 22684e86..e2dea5ce 100644
--- a/src/core/gcal-manager.h
+++ b/src/core/gcal-manager.h
@@ -37,6 +37,8 @@ ESource*             gcal_manager_get_source                     (GcalManager
 
 GList*               gcal_manager_get_calendars                  (GcalManager        *self);
 
+GListModel*          gcal_manager_get_calendars_model            (GcalManager        *self);
+
 GcalCalendar*        gcal_manager_get_default_calendar           (GcalManager        *self);
 
 void                 gcal_manager_set_default_calendar           (GcalManager        *self,
diff --git a/src/gui/importer/gcal-import-dialog.c b/src/gui/importer/gcal-import-dialog.c
index aa7dcb78..2614fb7b 100644
--- a/src/gui/importer/gcal-import-dialog.c
+++ b/src/gui/importer/gcal-import-dialog.c
@@ -27,6 +27,7 @@
 #include "gcal-import-file-row.h"
 #include "gcal-utils.h"
 
+#include <adwaita.h>
 #include <glib/gi18n.h>
 
 typedef struct
@@ -38,19 +39,19 @@ typedef struct
 
 struct _GcalImportDialog
 {
-  HdyWindow           parent;
+  GtkDialog           parent;
 
-  GtkImage           *calendar_color_image;
-  GtkLabel           *calendar_name_label;
-  GtkListBox         *calendars_listbox;
-  GtkPopover         *calendars_popover;
   GtkWidget          *cancel_button;
-  GtkListBox         *files_listbox;
-  HdyHeaderBar       *headerbar;
+  AdwComboRow        *calendar_combo_row;
+  AdwPreferencesGroup *files_group;
+  GtkHeaderBar       *headerbar;
   GtkWidget          *import_button;
+  GtkWidget          *placeholder_spinner;
+  AdwPreferencesPage *preferences_page;
   GtkSizeGroup       *title_sizegroup;
 
-  GtkWidget          *selected_row;
+  GList              *groups;
+  GcalCalendar       *selected_calendar;
 
   GCancellable       *cancellable;
   GcalContext        *context;
@@ -63,19 +64,7 @@ static void          on_import_row_file_loaded_cb                 (GcalImportFil
                                                                    GPtrArray         *events,
                                                                    GcalImportDialog  *self);
 
-static void          on_manager_calendar_added_cb                (GcalManager        *manager,
-                                                                  GcalCalendar       *calendar,
-                                                                  GcalImportDialog   *self);
-
-static void          on_manager_calendar_changed_cb              (GcalManager        *manager,
-                                                                  GcalCalendar       *calendar,
-                                                                  GcalImportDialog   *self);
-
-static void          on_manager_calendar_removed_cb              (GcalManager        *manager,
-                                                                  GcalCalendar       *calendar,
-                                                                  GcalImportDialog   *self);
-
-G_DEFINE_TYPE (GcalImportDialog, gcal_import_dialog, HDY_TYPE_WINDOW)
+G_DEFINE_TYPE (GcalImportDialog, gcal_import_dialog, GTK_TYPE_DIALOG)
 
 enum
 {
@@ -105,124 +94,37 @@ import_data_free (gpointer data)
   g_free (import_data);
 }
 
-static GtkWidget*
-create_calendar_row (GcalManager  *manager,
-                     GcalCalendar *calendar)
-{
-  g_autoptr (GdkPaintable) paintable = NULL;
-  g_autofree gchar *parent_name = NULL;
-  const GdkRGBA *color;
-  GtkWidget *icon;
-  GtkWidget *row;
-
-  color = gcal_calendar_get_color (calendar);
-  paintable = get_circle_paintable_from_color (color, 16);
-  get_source_parent_name_color (manager,
-                                gcal_calendar_get_source (calendar),
-                                &parent_name,
-                                NULL);
-
-  /* The icon with the source color */
-  icon = gtk_image_new_from_paintable (paintable);
-  gtk_style_context_add_class (gtk_widget_get_style_context (icon), "calendar-color-image");
-  gtk_widget_show (icon);
-
-  /* The row itself */
-  row = g_object_new (HDY_TYPE_ACTION_ROW,
-                      "title", gcal_calendar_get_name (calendar),
-                      "subtitle", parent_name,
-                      "sensitive", !gcal_calendar_is_read_only (calendar),
-                      "activatable", TRUE,
-                      "width-request", 300,
-                      NULL);
-  hdy_action_row_add_prefix (HDY_ACTION_ROW (row), icon);
-  gtk_widget_show (row);
-
-  g_object_set_data_full (G_OBJECT (row), "calendar", g_object_ref (calendar), g_object_unref);
-  g_object_set_data (G_OBJECT (row), "color-icon", icon);
-
-  return row;
-}
-
-static GtkWidget*
-get_row_for_calendar (GcalImportDialog *self,
-                      GcalCalendar     *calendar)
-{
-  g_autoptr (GList) children = NULL;
-  GtkWidget *row;
-  GList *l;
-
-  row = NULL;
-  children = gtk_container_get_children (GTK_CONTAINER (self->calendars_listbox));
-
-  for (l = children; l != NULL; l = g_list_next (l))
-    {
-      GcalCalendar *row_calendar = g_object_get_data (l->data, "calendar");
-
-      if (row_calendar == calendar)
-        {
-          row = l->data;
-          break;
-        }
-    }
-
-  return row;
-}
-
-static void
-select_row (GcalImportDialog *self,
-            GtkListBoxRow    *row)
-{
-  g_autoptr (GdkPaintable) paintable = NULL;
-  const GdkRGBA *color;
-  GcalCalendar *calendar;
-
-  self->selected_row = GTK_WIDGET (row);
-
-  /* Setup the event page's source name and color */
-  calendar = g_object_get_data (G_OBJECT (row), "calendar");
-
-  gtk_label_set_label (self->calendar_name_label, gcal_calendar_get_name (calendar));
-
-  color = gcal_calendar_get_color (calendar);
-  paintable = get_circle_paintable_from_color (color, 16);
-  gtk_image_set_from_paintable (self->calendar_color_image, paintable);
-}
-
 static void
-update_default_calendar_row (GcalImportDialog *self)
+update_default_calendar (GcalImportDialog *self)
 {
   GcalCalendar *default_calendar;
   GcalManager *manager;
-  GtkWidget *row;
+  GListModel *calendars;
+  guint position;
 
   manager = gcal_context_get_manager (self->context);
+  calendars = gcal_manager_get_calendars_model (manager);
   default_calendar = gcal_manager_get_default_calendar (manager);
 
-  row = get_row_for_calendar (self, default_calendar);
-  if (row != NULL)
-    select_row (self, GTK_LIST_BOX_ROW (row));
+  if (g_list_store_find (G_LIST_STORE (calendars), default_calendar, &position))
+    adw_combo_row_set_selected (self->calendar_combo_row, position);
 }
 
 static void
 setup_calendars (GcalImportDialog *self)
 {
-  g_autoptr (GList) calendars = NULL;
   GcalManager *manager;
-  GList *l;
+
+  g_assert (self->context != NULL);
 
   manager = gcal_context_get_manager (self->context);
-  calendars = gcal_manager_get_calendars (manager);
 
-  for (l = calendars; l; l = l->next)
-    on_manager_calendar_added_cb (manager, l->data, self);
+  // TODO: sort model
 
-  update_default_calendar_row (self);
+  adw_combo_row_set_model (self->calendar_combo_row, gcal_manager_get_calendars_model (manager));
+  update_default_calendar (self);
 
-  g_signal_connect_object (manager, "calendar-added", G_CALLBACK (on_manager_calendar_added_cb), self, 0);
-  g_signal_connect_object (manager, "calendar-changed", G_CALLBACK (on_manager_calendar_changed_cb), self, 
0);
-  g_signal_connect_object (manager, "calendar-removed", G_CALLBACK (on_manager_calendar_removed_cb), self, 
0);
-  g_signal_connect_object (manager, "notify::default-calendar", G_CALLBACK (update_default_calendar_row), 
self, G_CONNECT_SWAPPED);
+  g_signal_connect_object (manager, "notify::default-calendar", G_CALLBACK (update_default_calendar), self, 
G_CONNECT_SWAPPED);
 }
 
 static void
@@ -238,15 +140,25 @@ setup_files (GcalImportDialog  *self,
 
   for (i = 0; i < n_files; i++)
     {
+      AdwPreferencesGroup *group;
       GtkWidget *row;
 
       row = gcal_import_file_row_new (files[i], self->title_sizegroup);
       g_signal_connect (row, "file-loaded", G_CALLBACK (on_import_row_file_loaded_cb), self);
 
+      group = ADW_PREFERENCES_GROUP (adw_preferences_group_new ());
+      adw_preferences_group_add (group, row);
+
       if (n_files > 1)
-        gcal_import_file_row_show_filename (GCAL_IMPORT_FILE_ROW (row));
+        {
+          g_autofree gchar *basename = g_file_get_basename (files[i]);
+          adw_preferences_group_set_title (group, basename);
+        }
+
+      adw_preferences_page_add (self->preferences_page, group);
+      self->groups = g_list_prepend (self->groups, group);
 
-      gtk_list_box_insert (self->files_listbox, row, -1);
+      gtk_widget_hide (self->placeholder_spinner);
     }
 
   GCAL_EXIT;
@@ -273,20 +185,19 @@ on_events_created_cb (GObject      *source_object,
   if (error)
     g_warning ("Error creating events: %s", error->message);
 
-  gtk_widget_destroy (GTK_WIDGET (self));
+  gtk_window_destroy (GTK_WINDOW (self));
 
   GCAL_EXIT;
 }
 
 static void
-on_calendars_listbox_row_activated_cb (GtkListBox       *listbox,
-                                       GtkListBoxRow    *row,
-                                       GcalImportDialog *self)
+on_calendar_combo_row_selected_item_changed_cb (AdwComboRow      *combo_row,
+                                                GParamSpec       *pspec,
+                                                GcalImportDialog *self)
 {
   GCAL_ENTRY;
 
-  select_row (self, row);
-  gtk_popover_popdown (self->calendars_popover);
+  self->selected_calendar = adw_combo_row_get_selected_item (combo_row);
 
   GCAL_EXIT;
 }
@@ -295,7 +206,76 @@ static void
 on_cancel_button_clicked_cb (GtkButton        *button,
                              GcalImportDialog *self)
 {
-  gtk_widget_destroy (GTK_WIDGET (self));
+  gtk_window_destroy (GTK_WINDOW (self));
+}
+
+static void
+on_combo_row_signal_factory_setup_cb (GtkSignalListItemFactory *factory,
+                                      GtkListItem              *item,
+                                      GcalImportDialog         *self)
+{
+  GtkWidget *label;
+  GtkWidget *icon;
+  GtkWidget *grid;
+
+  grid = gtk_grid_new ();
+  gtk_grid_set_column_spacing (GTK_GRID (grid), 6);
+
+  icon = gtk_image_new ();
+  gtk_widget_add_css_class (icon, "calendar-color-image");
+  g_object_set_data (G_OBJECT (grid), "icon", icon);
+  gtk_grid_attach (GTK_GRID (grid), icon, 0, 0, 1, 2);
+
+  label = gtk_label_new (NULL);
+  gtk_label_set_xalign (GTK_LABEL (label), 0.0);
+  g_object_set_data (G_OBJECT (grid), "title", label);
+  gtk_grid_attach (GTK_GRID (grid), label, 1, 0, 1, 1);
+
+  label = gtk_label_new (NULL);
+  gtk_label_set_xalign (GTK_LABEL (label), 0.0);
+  gtk_widget_add_css_class (label, "caption");
+  gtk_widget_add_css_class (label, "dim-label");
+  g_object_set_data (G_OBJECT (grid), "subtitle", label);
+  gtk_grid_attach (GTK_GRID (grid), label, 1, 1, 1, 1);
+
+  gtk_list_item_set_child (item, grid);
+}
+
+static void
+on_combo_row_signal_factory_bind_cb (GtkSignalListItemFactory *factory,
+                                     GtkListItem              *item,
+                                     GcalImportDialog         *self)
+{
+  g_autoptr (GdkPaintable) color_paintable = NULL;
+  g_autofree gchar *parent_name = NULL;
+  GcalCalendar *calendar;
+  GtkWidget *label;
+  GtkWidget *icon;
+  GtkWidget *grid;
+
+  calendar = gtk_list_item_get_item (item);
+
+  grid = gtk_list_item_get_child (item);
+
+  color_paintable = get_circle_paintable_from_color (gcal_calendar_get_color (calendar), 16);
+  get_source_parent_name_color (gcal_context_get_manager (self->context),
+                                gcal_calendar_get_source (calendar),
+                                &parent_name,
+                                NULL);
+
+  icon = g_object_get_data (G_OBJECT (grid), "icon");
+  gtk_image_set_from_paintable (GTK_IMAGE (icon), color_paintable);
+
+  label = g_object_get_data (G_OBJECT (grid), "title");
+  gtk_label_set_label (GTK_LABEL (label), gcal_calendar_get_name (calendar));
+
+  label = g_object_get_data (G_OBJECT (grid), "subtitle");
+  gtk_label_set_label (GTK_LABEL (label), parent_name);
+
+  if (gtk_widget_get_ancestor (grid, GTK_TYPE_POPOVER) != NULL)
+    gtk_widget_set_size_request (grid, 250, -1);
+  else
+    gtk_widget_set_size_request (grid, -1, -1);
 }
 
 static void
@@ -339,9 +319,7 @@ static void
 on_import_button_clicked_cb (GtkButton        *button,
                              GcalImportDialog *self)
 {
-  g_autoptr (GList) children = NULL;
   g_autoptr (GTask) task = NULL;
-  GcalCalendar *calendar;
   ImportData *import_data;
   ECalClient *client;
   GSList *slist = NULL;
@@ -350,14 +328,12 @@ on_import_button_clicked_cb (GtkButton        *button,
 
   GCAL_ENTRY;
 
-  calendar = g_object_get_data (G_OBJECT (self->selected_row), "calendar");
-  g_assert (self->selected_row != NULL);
+  g_assert (self->selected_calendar != NULL);
 
   slist = NULL;
-  children = gtk_container_get_children (GTK_CONTAINER (self->files_listbox));
-  for (l = children; l; l = l->next)
+  for (l = self->groups; l; l = l->next)
     {
-      GcalImportFileRow *row = l->data;
+      GcalImportFileRow *row = GCAL_IMPORT_FILE_ROW (l->data);
       GPtrArray *ical_components;
       GPtrArray *ical_timezones;
       guint i;
@@ -390,7 +366,7 @@ on_import_button_clicked_cb (GtkButton        *button,
 
   gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE);
 
-  client = gcal_calendar_get_client (calendar);
+  client = gcal_calendar_get_client (self->selected_calendar);
 
   import_data = g_new0 (ImportData, 1);
   import_data->client = g_object_ref (client);
@@ -421,104 +397,13 @@ on_import_row_file_loaded_cb (GcalImportFileRow *row,
                                         "Import %d events",
                                         self->n_events),
                            self->n_events);
-  hdy_header_bar_set_title (self->headerbar, title);
+  gtk_window_set_title (GTK_WINDOW (self), title);
 
   gtk_widget_show (GTK_WIDGET (row));
 
   GCAL_EXIT;
 }
 
-static void
-on_manager_calendar_added_cb (GcalManager      *manager,
-                              GcalCalendar     *calendar,
-                              GcalImportDialog *self)
-{
-  if (gcal_calendar_is_read_only (calendar))
-    return;
-
-  gtk_container_add (GTK_CONTAINER (self->calendars_listbox),
-                     create_calendar_row (manager, calendar));
-}
-
-static void
-on_manager_calendar_changed_cb (GcalManager      *manager,
-                                GcalCalendar     *calendar,
-                                GcalImportDialog *self)
-{
-  g_autoptr (GdkPaintable) paintable = NULL;
-  const GdkRGBA *color;
-  GtkWidget *row, *color_icon;
-  gboolean read_only;
-
-  read_only = gcal_calendar_is_read_only (calendar);
-  row = get_row_for_calendar (self, calendar);
-
-  /* If the calendar changed from/to read-only, we add or remove it here */
-  if (read_only)
-    {
-      if (row)
-        gtk_container_remove (GTK_CONTAINER (self->calendars_listbox), row);
-      return;
-    }
-  else if (!row)
-    {
-      on_manager_calendar_added_cb (manager, calendar, self);
-      row = get_row_for_calendar (self, calendar);
-    }
-
-  hdy_preferences_row_set_title (HDY_PREFERENCES_ROW (row), gcal_calendar_get_name (calendar));
-  gtk_widget_set_sensitive (row, !read_only);
-
-  /* Setup the source color, in case it changed */
-  color = gcal_calendar_get_color (calendar);
-  paintable = get_circle_paintable_from_color (color, 16);
-  color_icon = g_object_get_data (G_OBJECT (row), "color-icon");
-  gtk_image_set_from_paintable (GTK_IMAGE (color_icon), paintable);
-
-  gtk_list_box_invalidate_sort (GTK_LIST_BOX (self->calendars_listbox));
-}
-
-static void
-on_manager_calendar_removed_cb (GcalManager      *manager,
-                                GcalCalendar     *calendar,
-                                GcalImportDialog *self)
-{
-  GtkWidget *row;
-
-  row = get_row_for_calendar (self, calendar);
-
-  if (!row)
-    return;
-
-  gtk_container_remove (GTK_CONTAINER (self->calendars_listbox), row);
-}
-
-static void
-on_select_calendar_row_activated_cb (GtkListBox       *listbox,
-                                     GtkListBoxRow    *row,
-                                     GcalImportDialog *self)
-{
-  gtk_popover_popup (self->calendars_popover);
-}
-
-static gint
-sort_func (GtkListBoxRow *row1,
-           GtkListBoxRow *row2,
-           gpointer       user_data)
-{
-  GcalCalendar *calendar1, *calendar2;
-  g_autofree gchar *name1 = NULL;
-  g_autofree gchar *name2 = NULL;
-
-  calendar1 = g_object_get_data (G_OBJECT (row1), "calendar");
-  calendar2 = g_object_get_data (G_OBJECT (row2), "calendar");
-
-  name1 = g_utf8_casefold (gcal_calendar_get_name (calendar1), -1);
-  name2 = g_utf8_casefold (gcal_calendar_get_name (calendar2), -1);
-
-  return g_strcmp0 (name1, name2);
-}
-
 
 /*
  * GObject overrides
@@ -533,6 +418,8 @@ gcal_import_dialog_finalize (GObject *object)
   g_clear_object (&self->cancellable);
   g_clear_object (&self->context);
 
+  g_clear_pointer (&self->groups, g_list_free);
+
   G_OBJECT_CLASS (gcal_import_dialog_parent_class)->finalize (object);
 }
 
@@ -601,28 +488,26 @@ gcal_import_dialog_class_init (GcalImportDialogClass *klass)
 
   gtk_widget_class_set_template_from_resource (widget_class, 
"/org/gnome/calendar/ui/gui/importer/gcal-import-dialog.ui");
 
-  gtk_widget_class_bind_template_child (widget_class, GcalImportDialog, calendar_color_image);
-  gtk_widget_class_bind_template_child (widget_class, GcalImportDialog, calendar_name_label);
-  gtk_widget_class_bind_template_child (widget_class, GcalImportDialog, calendars_listbox);
-  gtk_widget_class_bind_template_child (widget_class, GcalImportDialog, calendars_popover);
+  gtk_widget_class_bind_template_child (widget_class, GcalImportDialog, calendar_combo_row);
   gtk_widget_class_bind_template_child (widget_class, GcalImportDialog, cancel_button);
-  gtk_widget_class_bind_template_child (widget_class, GcalImportDialog, files_listbox);
+  gtk_widget_class_bind_template_child (widget_class, GcalImportDialog, files_group);
   gtk_widget_class_bind_template_child (widget_class, GcalImportDialog, headerbar);
   gtk_widget_class_bind_template_child (widget_class, GcalImportDialog, import_button);
+  gtk_widget_class_bind_template_child (widget_class, GcalImportDialog, placeholder_spinner);
+  gtk_widget_class_bind_template_child (widget_class, GcalImportDialog, preferences_page);
   gtk_widget_class_bind_template_child (widget_class, GcalImportDialog, title_sizegroup);
 
-  gtk_widget_class_bind_template_callback (widget_class, on_calendars_listbox_row_activated_cb);
+  gtk_widget_class_bind_template_callback (widget_class, on_calendar_combo_row_selected_item_changed_cb);
   gtk_widget_class_bind_template_callback (widget_class, on_cancel_button_clicked_cb);
   gtk_widget_class_bind_template_callback (widget_class, on_import_button_clicked_cb);
-  gtk_widget_class_bind_template_callback (widget_class, on_select_calendar_row_activated_cb);
+  gtk_widget_class_bind_template_callback (widget_class, on_combo_row_signal_factory_bind_cb);
+  gtk_widget_class_bind_template_callback (widget_class, on_combo_row_signal_factory_setup_cb);
 }
 
 static void
 gcal_import_dialog_init (GcalImportDialog *self)
 {
   gtk_widget_init_template (GTK_WIDGET (self));
-
-  gtk_list_box_set_sort_func (GTK_LIST_BOX (self->calendars_listbox), sort_func, NULL, NULL);
 }
 
 GtkWidget*
@@ -634,6 +519,7 @@ gcal_import_dialog_new_for_files (GcalContext  *context,
 
   self =  g_object_new (GCAL_TYPE_IMPORT_DIALOG,
                         "context", context,
+                        "use-header-bar", TRUE,
                         NULL);
 
   setup_files (self, files, n_files);
diff --git a/src/gui/importer/gcal-import-dialog.h b/src/gui/importer/gcal-import-dialog.h
index 89d70c5a..d2304834 100644
--- a/src/gui/importer/gcal-import-dialog.h
+++ b/src/gui/importer/gcal-import-dialog.h
@@ -22,12 +22,10 @@
 
 #include "gcal-context.h"
 
-#include <handy.h>
-
 G_BEGIN_DECLS
 
 #define GCAL_TYPE_IMPORT_DIALOG (gcal_import_dialog_get_type())
-G_DECLARE_FINAL_TYPE (GcalImportDialog, gcal_import_dialog, GCAL, IMPORT_DIALOG, HdyWindow)
+G_DECLARE_FINAL_TYPE (GcalImportDialog, gcal_import_dialog, GCAL, IMPORT_DIALOG, GtkDialog)
 
 GtkWidget*           gcal_import_dialog_new_for_files            (GcalContext        *context,
                                                                   GFile             **files,
diff --git a/src/gui/importer/gcal-import-dialog.ui b/src/gui/importer/gcal-import-dialog.ui
index 38e68ea6..c55bc209 100644
--- a/src/gui/importer/gcal-import-dialog.ui
+++ b/src/gui/importer/gcal-import-dialog.ui
@@ -1,194 +1,84 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
-  <template class="GcalImportDialog" parent="HdyWindow">
+  <template class="GcalImportDialog" parent="GtkDialog">
+    <property name="title" translatable="yes">Import Files…</property>
     <property name="width_request">500</property>
-    <property name="can_focus">False</property>
-    <property name="border_width">0</property>
     <property name="default_width">550</property>
     <property name="default_height">500</property>
     <property name="resizable">False</property>
-    <property name="type_hint">dialog</property>
     <property name="modal">True</property>
     <property name="destroy_with_parent">True</property>
-    <child>
-      <object class="HdyDeck">
-        <property name="visible">True</property>
-        <child>
-          <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="orientation">vertical</property>
-
-            <child>
-              <object class="HdyHeaderBar" id="headerbar">
-                <property name="visible">True</property>
-                <property name="title" translatable="yes">Import Files…</property>
-                <property name="show_close_button">False</property>
+    <property name="use-header-bar">1</property>
+
+    <child type="titlebar">
+      <object class="GtkHeaderBar" id="headerbar">
+        <property name="show-title-buttons">False</property>
+
+        <!-- Cancel button -->
+        <child type="start">
+          <object class="GtkButton" id="cancel_button">
+            <property name="label" translatable="yes">_Cancel</property>
+            <property name="use-underline">True</property>
+            <signal name="clicked" handler="on_cancel_button_clicked_cb" object="GcalImportDialog" 
swapped="no" />
+          </object>
+        </child>
 
-                <!-- Cancel button -->
-                <child>
-                  <object class="GtkButton" id="cancel_button">
-                    <property name="visible">True</property>
-                    <property name="label" translatable="yes">_Cancel</property>
-                    <property name="use-underline">True</property>
-                    <signal name="clicked" handler="on_cancel_button_clicked_cb" object="GcalImportDialog" 
swapped="no" />
-                  </object>
-                </child>
+        <!-- Import button -->
+        <child type="end">
+          <object class="GtkButton" id="import_button">
+            <property name="label" translatable="yes">_Import</property>
+            <property name="use-underline">True</property>
+            <signal name="clicked" handler="on_import_button_clicked_cb" object="GcalImportDialog" 
swapped="no" />
+            <style>
+              <class name="suggested-action" />
+            </style>
+          </object>
+        </child>
 
-                <!-- Import button -->
-                <child>
-                  <object class="GtkButton" id="import_button">
-                    <property name="visible">True</property>
-                    <property name="label" translatable="yes">_Import</property>
-                    <property name="use-underline">True</property>
-                    <signal name="clicked" handler="on_import_button_clicked_cb" object="GcalImportDialog" 
swapped="no" />
-                    <style>
-                      <class name="suggested-action" />
-                    </style>
-                  </object>
-                  <packing>
-                    <property name="pack-type">end</property>
-                  </packing>
-                </child>
+      </object>
+    </child>
 
-              </object>
-            </child>
+    <child>
+      <object class="AdwPreferencesPage" id="preferences_page">
 
+        <!-- Calendar -->
+        <child>
+          <object class="AdwPreferencesGroup">
             <child>
-              <object class="GtkScrolledWindow">
-                <property name="visible">True</property>
-                <property name="can-focus">False</property>
-                <property name="hscrollbar-policy">never</property>
-                <property name="propagate-natural-height">True</property>
-                <property name="min-content-height">400</property>
-                <property name="max-content-height">700</property>
-
-                <child>
-                  <object class="GtkBox">
-                    <property name="visible">True</property>
-                    <property name="can-focus">False</property>
-                    <property name="spacing">12</property>
-                    <property name="margin-top">24</property>
-                    <property name="margin-bottom">24</property>
-                    <property name="margin-start">36</property>
-                    <property name="margin-end">36</property>
-                    <property name="orientation">vertical</property>
-
-                    <!-- Calendar row -->
-                    <child>
-                      <object class="GtkListBox">
-                        <property name="visible">True</property>
-                        <property name="hexpand">True</property>
-                        <property name="selection-mode">none</property>
-                        <signal name="row-activated" handler="on_select_calendar_row_activated_cb" 
object="GcalImportDialog" swapped="no" />
-                        <style>
-                          <class name="content" />
-                        </style>
-
-                        <child>
-                          <object class="HdyActionRow" id="calendar_row">
-                            <property name="visible">True</property>
-                            <property name="activatable">True</property>
-                            <property name="title" translatable="yes">C_alendar</property>
-                            <property name="use-underline">True</property>
-
-                            <child>
-                              <object class="GtkBox" id="calendar_row_widgets_box">
-                                <property name="visible">True</property>
-                                <property name="can-focus">False</property>
-                                <property name="margin-start">12</property>
-                                <property name="spacing">12</property>
-
-                                <!-- Color -->
-                                <child>
-                                  <object class="GtkImage" id="calendar_color_image">
-                                    <property name="visible">True</property>
-                                    <property name="can-focus">False</property>
-                                  </object>
-                                </child>
-
-                                <!-- Calendar name -->
-                                <child>
-                                  <object class="GtkLabel" id="calendar_name_label">
-                                    <property name="visible">True</property>
-                                    <property name="can-focus">False</property>
-                                    <property name="can-focus">False</property>
-                                  </object>
-                                </child>
-
-                                <child>
-                                  <object class="GtkImage">
-                                    <property name="visible">True</property>
-                                    <property name="can-focus">False</property>
-                                    <property name="pixel-size">16</property>
-                                    <property name="icon-name">pan-down-symbolic</property>
-                                  </object>
-                                </child>
-
-                              </object>
-                            </child>
-
-                          </object>
-                        </child>
-                      </object>
-                    </child>
-
-                    <!-- Files overview -->
-                    <child>
-                      <object class="GtkListBox" id="files_listbox">
-                        <property name="visible">True</property>
-                        <property name="hexpand">True</property>
-                        <property name="selection-mode">none</property>
-
-                        <child type="placeholder">
-                          <object class="GtkSpinner">
-                            <property name="visible">True</property>
-                            <property name="halign">center</property>
-                            <property name="valign">center</property>
-                            <property name="active">True</property>
-                          </object>
-                        </child>
-
-                        <style>
-                          <class name="background" />
-                        </style>
-                      </object>
-                    </child>
-
+              <object class="AdwComboRow" id="calendar_combo_row">
+                <property name="activatable">True</property>
+                <property name="title" translatable="yes">C_alendar</property>
+                <property name="use-underline">True</property>
+                <property name="factory">
+                  <object class="GtkSignalListItemFactory">
+                    <signal name="bind" handler="on_combo_row_signal_factory_bind_cb" 
object="GcalImportDialog" swapped="no" />
+                    <signal name="setup" handler="on_combo_row_signal_factory_setup_cb" 
object="GcalImportDialog" swapped="no" />
                   </object>
-                </child>
-
+                </property>
+                <signal name="notify::selected-item" 
handler="on_calendar_combo_row_selected_item_changed_cb" object="GcalImportDialog" swapped="no" />
               </object>
             </child>
-
           </object>
         </child>
-      </object>
-    </child>
 
-  </template>
 
-  <!-- Calendars popover -->
-  <object class="GtkPopover" id="calendars_popover">
-    <property name="position">bottom</property>
-    <property name="relative-to">calendar_row_widgets_box</property>
-    <child>
-      <object class="GtkScrolledWindow">
-        <property name="visible">True</property>
-        <property name="hscrollbar-policy">never</property>
-        <property name="max-content-height">350</property>
-        <property name="propagate-natural-width">True</property>
-        <property name="propagate-natural-height">True</property>
+        <!-- Files overview -->
         <child>
-          <object class="GtkListBox" id="calendars_listbox">
-            <property name="visible">True</property>
-            <property name="hexpand">True</property>
-            <property name="selection-mode">none</property>
-            <signal name="row-activated" handler="on_calendars_listbox_row_activated_cb" 
object="GcalImportDialog" swapped="no" />
+          <object class="AdwPreferencesGroup" id="files_group">
+            <child>
+              <object class="GtkSpinner" id="placeholder_spinner">
+                <property name="halign">center</property>
+                <property name="valign">center</property>
+                <property name="spinning">True</property>
+              </object>
+            </child>
           </object>
         </child>
+
       </object>
     </child>
-  </object>
+
+  </template>
 
   <object class="GtkSizeGroup" id="title_sizegroup">
     <property name="mode">horizontal</property>
diff --git a/src/gui/importer/gcal-import-file-row.c b/src/gui/importer/gcal-import-file-row.c
index 0ed08bab..5a16eeb4 100644
--- a/src/gui/importer/gcal-import-file-row.c
+++ b/src/gui/importer/gcal-import-file-row.c
@@ -29,10 +29,9 @@
 
 struct _GcalImportFileRow
 {
-  GtkListBoxRow       parent;
+  AdwBin              parent;
 
   GtkListBox         *events_listbox;
-  GtkLabel           *filename_label;
   GtkSizeGroup       *title_sizegroup;
 
   GCancellable       *cancellable;
@@ -45,7 +44,7 @@ static void          read_calendar_finished_cb                   (GObject
                                                                   GAsyncResult       *res,
                                                                   gpointer            user_data);
 
-G_DEFINE_TYPE (GcalImportFileRow, gcal_import_file_row, GTK_TYPE_LIST_BOX_ROW)
+G_DEFINE_TYPE (GcalImportFileRow, gcal_import_file_row, ADW_TYPE_BIN)
 
 enum
 {
@@ -187,7 +186,7 @@ add_events_to_listbox (GcalImportFileRow *self,
                            "margin-end", 24,
                            NULL);
       fill_grid_with_event_data (self, GTK_GRID (grid), ical_component);
-      gtk_container_add (GTK_CONTAINER (row), grid);
+      gtk_list_box_row_set_child (GTK_LIST_BOX_ROW (row), grid);
 
       gtk_list_box_insert (self->events_listbox, row, -1);
     }
@@ -247,11 +246,6 @@ filter_timezones (ICalComponent *component)
 static void
 setup_file (GcalImportFileRow *self)
 {
-  g_autofree gchar *basename = NULL;
-
-  basename = g_file_get_basename (self->file);
-  gtk_label_set_label (self->filename_label, basename);
-
   gcal_importer_import_file (self->file,
                              self->cancellable,
                              read_calendar_finished_cb,
@@ -271,7 +265,6 @@ read_calendar_finished_cb (GObject      *source_object,
   g_autoptr (GPtrArray) event_components = NULL;
   g_autoptr (GPtrArray) timezones = NULL;
   g_autoptr (GError) error = NULL;
-  g_autofree gchar *subtitle = NULL;
   ICalComponent *component;
   GcalImportFileRow *self;
 
@@ -382,7 +375,6 @@ gcal_import_file_row_class_init (GcalImportFileRowClass *klass)
   gtk_widget_class_set_template_from_resource (widget_class, 
"/org/gnome/calendar/ui/gui/importer/gcal-import-file-row.ui");
 
   gtk_widget_class_bind_template_child (widget_class, GcalImportFileRow, events_listbox);
-  gtk_widget_class_bind_template_child (widget_class, GcalImportFileRow, filename_label);
 }
 
 static void
@@ -407,14 +399,6 @@ gcal_import_file_row_new (GFile        *file,
   return (GtkWidget*) self;
 }
 
-void
-gcal_import_file_row_show_filename (GcalImportFileRow *self)
-{
-  g_return_if_fail (GCAL_IS_IMPORT_FILE_ROW (self));
-
-  gtk_widget_show (GTK_WIDGET (self->filename_label));
-}
-
 GPtrArray*
 gcal_import_file_row_get_ical_components (GcalImportFileRow *self)
 {
diff --git a/src/gui/importer/gcal-import-file-row.h b/src/gui/importer/gcal-import-file-row.h
index e798997d..d98fa145 100644
--- a/src/gui/importer/gcal-import-file-row.h
+++ b/src/gui/importer/gcal-import-file-row.h
@@ -20,18 +20,16 @@
 
 #pragma once
 
-#include <gtk/gtk.h>
+#include <adwaita.h>
 
 G_BEGIN_DECLS
 
 #define GCAL_TYPE_IMPORT_FILE_ROW (gcal_import_file_row_get_type())
-G_DECLARE_FINAL_TYPE (GcalImportFileRow, gcal_import_file_row, GCAL, IMPORT_FILE_ROW, GtkListBoxRow)
+G_DECLARE_FINAL_TYPE (GcalImportFileRow, gcal_import_file_row, GCAL, IMPORT_FILE_ROW, AdwBin)
 
 GtkWidget*           gcal_import_file_row_new                    (GFile              *file,
                                                                   GtkSizeGroup       *title_sizegroup);
 
-void                 gcal_import_file_row_show_filename          (GcalImportFileRow  *self);
-
 GPtrArray*           gcal_import_file_row_get_ical_components    (GcalImportFileRow  *self);
 GPtrArray*           gcal_import_file_row_get_timezones          (GcalImportFileRow  *self);
 
diff --git a/src/gui/importer/gcal-import-file-row.ui b/src/gui/importer/gcal-import-file-row.ui
index 27bbd9f4..83f3a126 100644
--- a/src/gui/importer/gcal-import-file-row.ui
+++ b/src/gui/importer/gcal-import-file-row.ui
@@ -1,41 +1,14 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
-  <template class="GcalImportFileRow" parent="GtkListBoxRow">
-    <property name="visible">True</property>
-    <property name="can-focus">False</property>
-    <property name="activatable">False</property>
+  <template class="GcalImportFileRow" parent="AdwBin">
 
+    <!-- Event preview listbox -->
     <child>
-      <object class="GtkBox">
-        <property name="visible">True</property>
-        <property name="can-focus">False</property>
-        <property name="orientation">vertical</property>
-        <property name="spacing">6</property>
-
-        <!-- File name label -->
-        <child>
-          <object class="GtkLabel" id="filename_label">
-            <property name="can-focus">False</property>
-            <property name="margin-top">12</property>
-            <property name="xalign">0.0</property>
-            <attributes>
-              <attribute name="weight" value="bold" />
-            </attributes>
-          </object>
-        </child>
-
-        <!-- Event preview listbox -->
-        <child>
-          <object class="GtkListBox" id="events_listbox">
-            <property name="visible">True</property>
-            <property name="can-focus">False</property>
-            <property name="selection-mode">none</property>
-            <style>
-              <class name="content" />
-            </style>
-          </object>
-        </child>
-
+      <object class="GtkListBox" id="events_listbox">
+        <property name="selection-mode">none</property>
+        <style>
+          <class name="boxed-list" />
+        </style>
       </object>
     </child>
 


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