[gnome-calendar] new-calendar-page: Implement new designs



commit 0f28e3fa536c1891fca5fbc4f5177c3fd2f39ea9
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Mon Jun 24 21:30:33 2019 -0300

    new-calendar-page: Implement new designs
    
    This looks soooooo much better =)
    
    https://gitlab.gnome.org/GNOME/gnome-calendar/issues/388

 data/ui/new-calendar-page.ui                       | 154 +++++++++++++++---
 .../calendar-management/gcal-new-calendar-page.c   | 172 ++++++++++++---------
 2 files changed, 237 insertions(+), 89 deletions(-)
---
diff --git a/data/ui/new-calendar-page.ui b/data/ui/new-calendar-page.ui
index 5c19659c..a609012a 100644
--- a/data/ui/new-calendar-page.ui
+++ b/data/ui/new-calendar-page.ui
@@ -2,20 +2,109 @@
 <interface>
   <template class="GcalNewCalendarPage" parent="GtkBox">
     <property name="visible">True</property>
+    <property name="orientation">vertical</property>
+    <property name="spacing">12</property>
+    <property name="margin-top">24</property>
+    <property name="margin-bottom">24</property>
+    <property name="margin-start">12</property>
+    <property name="margin-end">12</property>
+
+    <!-- Local calendar -->
+    <child>
+      <object class="GtkBox">
+        <property name="visible">True</property>
+        <property name="margin-bottom">18</property>
+        <property name="orientation">vertical</property>
+        <style>
+          <class name="view" />
+          <class name="frame" />
+        </style>
+
+        <!-- Calendar name -->
+        <child>
+          <object class="GtkBox">
+            <property name="visible">True</property>
+            <property name="margin">12</property>
+
+            <child>
+              <object class="GtkLabel">
+                <property name="visible">True</property>
+                <property name="hexpand">True</property>
+                <property name="label" translatable="yes">Calendar Name</property>
+                <property name="xalign">0.0</property>
+              </object>
+            </child>
+
+            <child>
+              <object class="GtkEntry" id="local_calendar_name_entry">
+                <property name="visible">True</property>
+                <property name="placeholder-text" translatable="yes">Calendar Name</property>
+                <signal name="notify::text" handler="on_local_calendar_name_entry_text_changed_cb" 
object="GcalNewCalendarPage" swapped="no" />
+              </object>
+            </child>
+
+          </object>
+        </child>
+
+        <child>
+          <object class="GtkSeparator">
+            <property name="visible">True</property>
+          </object>
+        </child>
+
+        <!-- Color -->
+        <child>
+          <object class="GtkBox">
+            <property name="visible">True</property>
+            <property name="margin">12</property>
+
+            <child>
+              <object class="GtkLabel">
+                <property name="visible">True</property>
+                <property name="hexpand">True</property>
+                <property name="label" translatable="yes">Color</property>
+                <property name="xalign">0.0</property>
+              </object>
+            </child>
+
+            <child>
+              <object class="GtkColorButton" id="local_calendar_color_button">
+                <property name="visible">True</property>
+              </object>
+            </child>
+
+          </object>
+        </child>
+
+      </object>
+    </child>
+
+    <child>
+      <object class="GtkLabel">
+        <property name="visible">True</property>
+        <property name="hexpand">True</property>
+        <property name="label" translatable="yes">Import a Calendar</property>
+        <property name="xalign">0.0</property>
+        <attributes>
+          <attribute name="scale" value="1.3" />
+          <attribute name="weight" value="bold" />
+        </attributes>
+      </object>
+    </child>
+
     <child>
       <object class="GtkGrid">
         <property name="visible">True</property>
-        <property name="border_width">18</property>
-        <property name="row_spacing">16</property>
+        <property name="row_spacing">12</property>
         <property name="column_spacing">12</property>
+
+        <!-- Online Accounts reference label-->
         <child>
-          <object class="GtkLabel" id="web_description_label">
+          <object class="GtkLabel">
             <property name="visible">True</property>
-            <property name="label" translatable="yes">Enter the address of the calendar that you want to 
add. If the calendar belongs to one of your online accounts, you can add it through the &lt;a 
href=&quot;GOA&quot;&gt;online account settings&lt;/a&gt;.</property>
-            <property name="use_markup">True</property>
+            <property name="label" translatable="yes">Alternatively, enter the web address of an online 
calendar you want to import, or open a supported calendar file.</property>
             <property name="wrap">True</property>
             <property name="xalign">0</property>
-            <signal name="activate-link" handler="description_label_link_activated" 
object="GcalNewCalendarPage" swapped="no" />
           </object>
           <packing>
             <property name="left_attach">0</property>
@@ -23,33 +112,37 @@
             <property name="width">2</property>
           </packing>
         </child>
+
+        <!-- URL entry -->
         <child>
-          <object class="GtkLabel" id="calendar_address_label">
+          <object class="GtkEntry" id="calendar_address_entry">
             <property name="visible">True</property>
-            <property name="label" translatable="yes">Calendar Address</property>
-            <property name="xalign">1</property>
-            <style>
-              <class name="dim-label" />
-            </style>
+            <property name="can_focus">True</property>
+            <property name="hexpand">True</property>
+            <property name="placeholder-text">https://example.com/calendar.ics</property>
+            <signal name="notify::text" handler="on_url_entry_text_changed_cb" object="GcalNewCalendarPage" 
swapped="no" />
+            <signal name="activate" handler="on_calendar_address_activated_cb" object="GcalNewCalendarPage" 
swapped="no" />
           </object>
           <packing>
             <property name="left_attach">0</property>
             <property name="top_attach">1</property>
           </packing>
         </child>
+
+        <!-- File Chooser button -->
         <child>
-          <object class="GtkEntry" id="calendar_address_entry">
+          <object class="GtkFileChooserButton" id="calendar_file_chooser_button">
             <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="hexpand">True</property>
-            <signal name="notify::text" handler="on_url_entry_text_changed_cb" object="GcalNewCalendarPage" 
swapped="no" />
-            <signal name="activate" handler="on_calendar_address_activated_cb" object="GcalNewCalendarPage" 
swapped="no" />
+            <!-- <property name="filter">calendar_file_filter</property> -->
+            <property name="title" translatable="yes">Open a File</property>
+            <signal name="file-set" handler="on_file_chooser_button_file_set_cb" 
object="GcalNewCalendarPage" swapped="no" />
           </object>
           <packing>
             <property name="left_attach">1</property>
             <property name="top_attach">1</property>
           </packing>
         </child>
+
         <child>
           <object class="GtkRevealer" id="web_sources_revealer">
             <property name="transition_type">crossfade</property>
@@ -103,14 +196,32 @@
             <property name="width">2</property>
           </packing>
         </child>
+
+        <!-- Online Accounts reference label-->
+        <child>
+          <object class="GtkLabel" id="web_description_label">
+            <property name="visible">True</property>
+            <property name="label" translatable="yes">If the calendar belongs to one of your online 
accounts, you can add it through the &lt;a href=&quot;GOA&quot;&gt;online account 
settings&lt;/a&gt;.</property>
+            <property name="use_markup">True</property>
+            <property name="wrap">True</property>
+            <property name="xalign">0</property>
+            <signal name="activate-link" handler="description_label_link_activated" 
object="GcalNewCalendarPage" swapped="no" />
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">3</property>
+            <property name="width">2</property>
+          </packing>
+        </child>
+
       </object>
     </child>
   </template>
 
   <!-- Credentials dialog -->
   <object class="GtkDialog" id="credentials_dialog">
+    <property name="modal">True</property>
     <property name="type_hint">dialog</property>
-    <property name="transient_for">GcalNewCalendarPage</property>
     <child type="titlebar">
       <object class="GtkHeaderBar" id="credentials_headerbar">
         <property name="visible">True</property>
@@ -211,6 +322,13 @@
     </child>
   </object>
 
+  <!-- Calendar file filter -->
+  <object class="GtkFileFilter" id="calendar_file_filter">
+    <mime-types>
+      <mime-type>text/calendar</mime-type>
+    </mime-types>
+  </object>
+
   <!-- Headerbar buttons -->
   <object class="GtkButton" id="cancel_button">
     <property name="visible">True</property>
diff --git a/src/gui/calendar-management/gcal-new-calendar-page.c 
b/src/gui/calendar-management/gcal-new-calendar-page.c
index 17c0c6c9..8d1162b5 100644
--- a/src/gui/calendar-management/gcal-new-calendar-page.c
+++ b/src/gui/calendar-management/gcal-new-calendar-page.c
@@ -35,12 +35,16 @@ struct _GcalNewCalendarPage
 
   GtkWidget          *add_button;
   GtkEntry           *calendar_address_entry;
+  GtkFileChooser     *calendar_file_chooser_button;
+  GtkFileFilter      *calendar_file_filter;
   GtkWidget          *cancel_button;
   GtkWidget          *credentials_cancel_button;
   GtkWidget          *credentials_connect_button;
   GtkWidget          *credentials_dialog;
   GtkEntry           *credentials_password_entry;
   GtkEntry           *credentials_user_entry;
+  GtkColorChooser    *local_calendar_color_button;
+  GtkEntry           *local_calendar_name_entry;
   GtkWidget          *web_sources_listbox;
   GtkWidget          *web_sources_revealer;
 
@@ -49,6 +53,8 @@ struct _GcalNewCalendarPage
   GList              *remote_sources;
   guint               validate_url_resource_id;
 
+  ESource            *local_source;
+
   GcalContext        *context;
 };
 
@@ -152,11 +158,6 @@ prompt_credentials (GcalNewCalendarPage  *self,
   return response;
 }
 
-
-/*
- * Callbacks
- */
-
 static gchar*
 calendar_path_to_name_suggestion (GFile *file)
 {
@@ -199,78 +200,71 @@ calendar_path_to_name_suggestion (GFile *file)
 }
 
 static void
-calendar_file_selected (GtkFileChooser *button,
-                        gpointer        user_data)
+update_add_button (GcalNewCalendarPage *self)
 {
-  g_autofree gchar *display_name = NULL;
-  g_autoptr (ESource) source = NULL;
-  g_autoptr (GFile) file = NULL;
-  ESourceExtension *ext;
-
-  file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (button));
+  gboolean valid;
 
-  if (!file)
-    return;
-
-  /**
-   * Create the new source and add the needed
-   * extensions.
-   */
-  source = e_source_new (NULL, NULL, NULL);
-  e_source_set_parent (source, "local-stub");
-
-  ext = e_source_get_extension (source, E_SOURCE_EXTENSION_CALENDAR);
-  e_source_backend_set_backend_name (E_SOURCE_BACKEND (ext), "local");
-
-  ext = e_source_get_extension (source, E_SOURCE_EXTENSION_LOCAL_BACKEND);
-  e_source_local_set_custom_file (E_SOURCE_LOCAL (ext), file);
-
-  /* update the source properties */
-  display_name = calendar_path_to_name_suggestion (file);
-  e_source_set_display_name (source, display_name);
+  valid = self->local_source != NULL || self->remote_sources != NULL;
+  gtk_widget_set_sensitive (self->add_button, valid);
 }
 
 static void
-on_file_activated (GSimpleAction *action,
-                   GVariant      *param,
-                   gpointer       user_data)
+update_local_source (GcalNewCalendarPage *self)
 {
-  GtkWidget *dialog;
-  GtkFileFilter *filter;
-  gint response;
+  g_autofree gchar *calendar_name = NULL;
 
-  /* Dialog */
-  dialog = gtk_file_chooser_dialog_new (_("Select a calendar file"),
-                                        GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (user_data))),
-                                        GTK_FILE_CHOOSER_ACTION_OPEN,
-                                        _("Cancel"), GTK_RESPONSE_CANCEL,
-                                        _("Open"), GTK_RESPONSE_OK,
-                                        NULL);
+  g_clear_object (&self->local_source);
 
-  g_signal_connect (dialog, "file-activated", G_CALLBACK (calendar_file_selected), user_data);
+  calendar_name = g_strdup (gtk_entry_get_text (self->local_calendar_name_entry));
+  calendar_name = g_strstrip (calendar_name);
 
-  /* File filter */
-  filter = gtk_file_filter_new ();
-  gtk_file_filter_set_name (filter, _("Calendar files"));
-  gtk_file_filter_add_mime_type (filter, "text/calendar");
+  if (calendar_name && g_utf8_strlen (calendar_name, -1) > 0)
+    {
+      g_autofree gchar *color_string = NULL;
+      ESourceExtension *ext;
+      ESource *source;
+      GdkRGBA color;
 
-  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
+      gtk_color_chooser_get_rgba (self->local_calendar_color_button, &color);
+      color_string = gdk_rgba_to_string (&color);
 
-  response = gtk_dialog_run (GTK_DIALOG (dialog));
+      /* Create the new source and add the needed extensions */
+      source = e_source_new (NULL, NULL, NULL);
+      e_source_set_parent (source, "local-stub");
+      e_source_set_display_name (source, calendar_name);
 
-  if (response == GTK_RESPONSE_OK)
-    calendar_file_selected (GTK_FILE_CHOOSER (dialog), user_data);
+      ext = e_source_get_extension (source, E_SOURCE_EXTENSION_CALENDAR);
+      e_source_backend_set_backend_name (E_SOURCE_BACKEND (ext), "local");
+      e_source_selectable_set_color (E_SOURCE_SELECTABLE (ext), color_string);
+
+      e_source_backend_set_backend_name (E_SOURCE_BACKEND (ext), "local");
+
+      self->local_source = source;
+    }
 
-  gtk_widget_destroy (dialog);
+  update_add_button (self);
 }
 
+
+/*
+ * Callbacks
+ */
+
 static void
-on_local_activated (GSimpleAction *action,
-                    GVariant      *param,
-                    gpointer       user_data)
+on_file_chooser_button_file_set_cb (GtkFileChooser      *chooser,
+                                    GcalNewCalendarPage *self)
 {
+  g_autofree gchar *display_name = NULL;
+  g_autoptr (ESource) source = NULL;
+  g_autoptr (GFile) file = NULL;
   ESourceExtension *ext;
-  ESource *source;
+
+  GCAL_ENTRY;
+
+  file = gtk_file_chooser_get_file (chooser);
+
+  if (!file)
+    GCAL_RETURN ();
 
   /* Create the new source and add the needed extensions */
   source = e_source_new (NULL, NULL, NULL);
@@ -279,8 +273,23 @@ on_local_activated (GSimpleAction *action,
   ext = e_source_get_extension (source, E_SOURCE_EXTENSION_CALENDAR);
   e_source_backend_set_backend_name (E_SOURCE_BACKEND (ext), "local");
 
+  ext = e_source_get_extension (source, E_SOURCE_EXTENSION_LOCAL_BACKEND);
+  e_source_local_set_custom_file (E_SOURCE_LOCAL (ext), file);
+
   /* update the source properties */
-  e_source_set_display_name (source, _("Unnamed Calendar"));
+  display_name = calendar_path_to_name_suggestion (file);
+  e_source_set_display_name (source, display_name);
+
+  /* TODO: report errors */
+  gcal_manager_save_source (gcal_context_get_manager (self->context), source);
+
+  gcal_calendar_management_page_switch_page (GCAL_CALENDAR_MANAGEMENT_PAGE (self),
+                                             "calendars",
+                                             NULL);
+
+  gtk_file_chooser_unselect_all (self->calendar_file_chooser_button);
+
+  GCAL_EXIT;
 }
 
 static gboolean
@@ -309,7 +318,7 @@ on_check_activated_cb (GtkWidget           *check,
   else
     self->remote_sources = g_list_remove (self->remote_sources, source);
 
-  //gtk_widget_set_sensitive (self->add_button, g_list_length (self->remote_sources) > 0);
+  update_add_button (self);
 }
 
 static void
@@ -447,6 +456,8 @@ validate_url_cb (GcalNewCalendarPage *self)
   const gchar *host, *path;
   gboolean is_file;
 
+  GCAL_ENTRY;
+
   self->validate_url_resource_id = 0;
   soup_uri = NULL;
   host = path = NULL;
@@ -471,7 +482,7 @@ validate_url_cb (GcalNewCalendarPage *self)
   uri = gtk_entry_get_text (self->calendar_address_entry);
   soup_uri = soup_uri_new (uri);
   if (!soup_uri)
-    return FALSE;
+    GCAL_RETURN (G_SOURCE_REMOVE);
 
   host = soup_uri_get_host (soup_uri);
   path = soup_uri_get_path (soup_uri);
@@ -504,16 +515,15 @@ validate_url_cb (GcalNewCalendarPage *self)
     {
       self->remote_sources = g_list_append (self->remote_sources, source);
       gtk_widget_set_sensitive (self->add_button, source != NULL);
-      return FALSE;
+      GCAL_RETURN (G_SOURCE_REMOVE);
     }
 
   /* Pulse the entry while it performs the check */
   self->calendar_address_id = g_timeout_add (ENTRY_PROGRESS_TIMEOUT, (GSourceFunc) pulse_web_entry, self);
 
   /*
-   * Try to retrieve the sources without prompting
-   * username and password. If we get any error,
-   * then it prompts and retry.
+   * Try to retrieve the sources without prompting username and password. If
+   * we get any error, then it prompts and retry.
    */
   credentials = e_named_parameters_new ();
 
@@ -541,9 +551,10 @@ validate_url_cb (GcalNewCalendarPage *self)
 
       g_debug ("No credentials failed, retrying with user credentials...");
 
-      user = password = NULL;
       response = prompt_credentials (self, &user, &password);
 
+      g_message ("lalala");
+
       if (response == GTK_RESPONSE_OK)
         {
           e_named_parameters_set (credentials, E_SOURCE_CREDENTIAL_USERNAME, user);
@@ -561,7 +572,7 @@ validate_url_cb (GcalNewCalendarPage *self)
 
   e_named_parameters_free (credentials);
 
-  return FALSE;
+  GCAL_RETURN (G_SOURCE_REMOVE);
 }
 
 static void
@@ -573,11 +584,11 @@ on_add_button_clicked_cb (GtkWidget           *button,
   manager = gcal_context_get_manager (self->context);
 
   /* Commit the new source */
-  //if (self->source != NULL)
-  //  gcal_manager_save_source (manager, self->source);
+  if (self->local_source)
+    gcal_manager_save_source (manager, self->local_source);
 
   /* Commit each new remote source */
-  if (self->remote_sources != NULL)
+  if (self->remote_sources)
     {
       GList *l;
 
@@ -661,6 +672,14 @@ on_cancel_button_clicked_cb (GtkWidget                  *button,
   gcal_calendar_management_page_switch_page (page, "calendars", NULL);
 }
 
+static void
+on_local_calendar_name_entry_text_changed_cb (GtkEntry            *entry,
+                                              GParamSpec          *pspec,
+                                              GcalNewCalendarPage *self)
+{
+  update_local_source (self);
+}
+
 
 /*
  * GcalCalendarManagementPage iface
@@ -717,6 +736,9 @@ gcal_new_calendar_page_deactivate (GcalCalendarManagementPage *page)
       self->remote_sources = NULL;
     }
 
+  gtk_entry_set_text (self->local_calendar_name_entry, "");
+  gtk_entry_set_text (self->calendar_address_entry, "");
+
   GCAL_EXIT;
 }
 
@@ -798,12 +820,16 @@ gcal_new_calendar_page_class_init (GcalNewCalendarPageClass *klass)
 
   gtk_widget_class_bind_template_child (widget_class, GcalNewCalendarPage, add_button);
   gtk_widget_class_bind_template_child (widget_class, GcalNewCalendarPage, calendar_address_entry);
+  gtk_widget_class_bind_template_child (widget_class, GcalNewCalendarPage, calendar_file_chooser_button);
+  gtk_widget_class_bind_template_child (widget_class, GcalNewCalendarPage, calendar_file_filter);
   gtk_widget_class_bind_template_child (widget_class, GcalNewCalendarPage, cancel_button);
   gtk_widget_class_bind_template_child (widget_class, GcalNewCalendarPage, credentials_cancel_button);
   gtk_widget_class_bind_template_child (widget_class, GcalNewCalendarPage, credentials_connect_button);
   gtk_widget_class_bind_template_child (widget_class, GcalNewCalendarPage, credentials_dialog);
   gtk_widget_class_bind_template_child (widget_class, GcalNewCalendarPage, credentials_password_entry);
   gtk_widget_class_bind_template_child (widget_class, GcalNewCalendarPage, credentials_user_entry);
+  gtk_widget_class_bind_template_child (widget_class, GcalNewCalendarPage, local_calendar_color_button);
+  gtk_widget_class_bind_template_child (widget_class, GcalNewCalendarPage, local_calendar_name_entry);
   gtk_widget_class_bind_template_child (widget_class, GcalNewCalendarPage, web_sources_listbox);
   gtk_widget_class_bind_template_child (widget_class, GcalNewCalendarPage, web_sources_revealer);
 
@@ -812,6 +838,8 @@ gcal_new_calendar_page_class_init (GcalNewCalendarPageClass *klass)
   gtk_widget_class_bind_template_callback (widget_class, on_cancel_button_clicked_cb);
   gtk_widget_class_bind_template_callback (widget_class, on_credential_button_clicked_cb);
   gtk_widget_class_bind_template_callback (widget_class, on_credential_entry_activate_cb);
+  gtk_widget_class_bind_template_callback (widget_class, on_file_chooser_button_file_set_cb);
+  gtk_widget_class_bind_template_callback (widget_class, on_local_calendar_name_entry_text_changed_cb);
   gtk_widget_class_bind_template_callback (widget_class, on_url_entry_text_changed_cb);
 }
 
@@ -819,4 +847,6 @@ static void
 gcal_new_calendar_page_init (GcalNewCalendarPage *self)
 {
   gtk_widget_init_template (GTK_WIDGET (self));
+
+  gtk_file_filter_set_name (self->calendar_file_filter, _("Calendar files"));
 }


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