[california/wip/733760-caldav] Revamping of activators names and namespaces



commit f6dc488444b6906221b969225d3a9efd5c33f074
Author: Jim Nelson <jim yorba org>
Date:   Thu Aug 7 15:52:13 2014 -0700

    Revamping of activators names and namespaces
    
    Not as scary as it looks.

 src/Makefile.am                                    |   21 ++--
 src/activator/activator.vala                       |    6 +-
 ...-caldav.vala => caldav-activator-instance.vala} |   10 +-
 src/activator/caldav/caldav-subscribe.vala         |   31 ++++
 .../generic-subscribe.vala}                        |   48 +++---
 ...-google.vala => google-activator-instance.vala} |   14 +-
 ...g-pane.vala => google-authenticating-pane.vala} |    8 +-
 ...st-pane.vala => google-calendar-list-pane.vala} |    6 +-
 ...ogle-login-pane.vala => google-login-pane.vala} |   15 +-
 src/activator/webcal/activator-webcal-pane.vala    |  101 ------------
 ...-webcal.vala => webcal-activator-instance.vala} |   14 +-
 src/activator/webcal/webcal-subscribe.vala         |   31 ++++
 src/california-resources.xml                       |    9 +-
 src/host/host-create-update-event.vala             |    7 +-
 src/host/host-quick-create-event.vala              |    4 +-
 .../{caldav-subscribe.ui => generic-subscribe.ui}  |   44 +++++-
 src/rc/webcal-subscribe.ui                         |  172 --------------------
 .../toolkit-entry-clear-text-connector.vala        |   30 +++-
 src/util/util-uri.vala                             |   24 +--
 19 files changed, 210 insertions(+), 385 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index cb63ee0..6dde145 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -14,16 +14,18 @@ california_VALASOURCES = \
        activator/activator-instance-list.vala \
        activator/activator-window.vala \
        \
-       activator/caldav/activator-caldav.vala \
-       activator/caldav/activator-caldav-pane.vala \
+       activator/caldav/caldav-activator-instance.vala \
+       activator/caldav/caldav-subscribe.vala \
        \
-       activator/google/activator-google.vala \
-       activator/google/activator-google-authenticating-pane.vala \
-       activator/google/activator-google-calendar-list-pane.vala \
-       activator/google/activator-google-login-pane.vala \
+       activator/generic/generic-subscribe.vala \
        \
-       activator/webcal/activator-webcal.vala \
-       activator/webcal/activator-webcal-pane.vala \
+       activator/google/google-activator-instance.vala \
+       activator/google/google-authenticating-pane.vala \
+       activator/google/google-calendar-list-pane.vala \
+       activator/google/google-login-pane.vala \
+       \
+       activator/webcal/webcal-activator-instance.vala \
+       activator/webcal/webcal-subscribe.vala \
        \
        application/california-application.vala \
        application/california-commandline.vala \
@@ -182,7 +184,6 @@ california_SOURCES = \
 california_RC = \
        rc/activator-list.ui \
        rc/app-menu.interface \
-       rc/caldav-subscribe.ui \
        rc/calendar-import.ui \
        rc/calendar-list-item.ui \
        rc/calendar-manager-list.ui \
@@ -191,12 +192,12 @@ california_RC = \
        rc/create-update-recurring.ui \
        rc/date-time-widget.ui \
        rc/event-time-settings.ui \
+       rc/generic-subscribe.ui \
        rc/google-authenticating.ui \
        rc/google-calendar-list.ui \
        rc/google-login.ui \
        rc/quick-create-event.ui \
        rc/show-event.ui \
-       rc/webcal-subscribe.ui \
        rc/window-menu.interface \
        $(NULL)
 
diff --git a/src/activator/activator.vala b/src/activator/activator.vala
index c89ec25..d65725d 100644
--- a/src/activator/activator.vala
+++ b/src/activator/activator.vala
@@ -33,9 +33,9 @@ public void init() throws Error {
     Backing.EdsStore? eds_store = Backing.Manager.instance.get_store_of_type<Backing.EdsStore>()
         as Backing.EdsStore;
     assert(eds_store != null);
-    activators.add(new WebCalActivator(_("Web calendar (.ics)"), eds_store));
-    activators.add(new GoogleActivator(_("Google Calendar"), eds_store));
-    activators.add(new CalDAVActivator(_("CalDAV server"), eds_store));
+    activators.add(new WebCal.ActivatorInstance(_("Web calendar (.ics)"), eds_store));
+    activators.add(new Google.ActivatorInstance(_("Google Calendar"), eds_store));
+    activators.add(new CalDAV.ActivatorInstance(_("CalDAV"), eds_store));
 }
 
 public void terminate() {
diff --git a/src/activator/caldav/activator-caldav.vala b/src/activator/caldav/caldav-activator-instance.vala
similarity index 58%
rename from src/activator/caldav/activator-caldav.vala
rename to src/activator/caldav/caldav-activator-instance.vala
index 230f799..67a532b 100644
--- a/src/activator/caldav/activator-caldav.vala
+++ b/src/activator/caldav/caldav-activator-instance.vala
@@ -4,21 +4,21 @@
  * (version 2.1 or later).  See the COPYING file in this distribution.
  */
 
-namespace California.Activator {
+namespace California.Activator.CalDAV {
 
-internal class CalDAVActivator : Instance {
-    public override string first_card_id { get { return CalDAVActivatorPane.ID; } }
+internal class ActivatorInstance : Instance {
+    public override string first_card_id { get { return Subscribe.ID; } }
     
     private Backing.CalDAVSubscribable caldav_store;
     
-    public CalDAVActivator(string title, Backing.CalDAVSubscribable store) {
+    public ActivatorInstance(string title, Backing.CalDAVSubscribable store) {
         base (title, store);
         
         caldav_store = store;
     }
     
     public override Gee.List<Toolkit.Card> create_cards(Soup.URI? supplied_uri) {
-        return iterate<Toolkit.Card>(new CalDAVActivatorPane(caldav_store, supplied_uri))
+        return iterate<Toolkit.Card>(new Subscribe(caldav_store, supplied_uri))
             .to_array_list();
     }
 }
diff --git a/src/activator/caldav/caldav-subscribe.vala b/src/activator/caldav/caldav-subscribe.vala
new file mode 100644
index 0000000..2f664ad
--- /dev/null
+++ b/src/activator/caldav/caldav-subscribe.vala
@@ -0,0 +1,31 @@
+/* Copyright 2014 Yorba Foundation
+ *
+ * This software is licensed under the GNU Lesser General Public License
+ * (version 2.1 or later).  See the COPYING file in this distribution.
+ */
+
+namespace California.Activator.CalDAV {
+
+internal class Subscribe : California.Activator.Generic.Subscribe {
+    public const string ID = "CalDAVActivatorPane";
+    
+    public override string card_id { get { return ID; } }
+    
+    public override string? title { get { return null; } }
+    
+    private Backing.CalDAVSubscribable store;
+    
+    public Subscribe(Backing.CalDAVSubscribable store, Soup.URI? supplied_url) {
+        base (supplied_url, iterate<string>("http://";, "https://";).to_hash_set());
+        
+        this.store = store;
+    }
+    
+    protected override async void subscribe_async(string name, Soup.URI uri, string? username,
+        string color, Cancellable? cancellable) throws Error {
+        yield store.subscribe_caldav_async(name, uri, username, color, cancellable);
+    }
+}
+
+}
+
diff --git a/src/activator/caldav/activator-caldav-pane.vala b/src/activator/generic/generic-subscribe.vala
similarity index 57%
rename from src/activator/caldav/activator-caldav-pane.vala
rename to src/activator/generic/generic-subscribe.vala
index 370fd97..762f9dd 100644
--- a/src/activator/caldav/activator-caldav-pane.vala
+++ b/src/activator/generic/generic-subscribe.vala
@@ -4,15 +4,13 @@
  * (version 2.1 or later).  See the COPYING file in this distribution.
  */
 
-namespace California.Activator {
+namespace California.Activator.Generic {
 
-[GtkTemplate (ui = "/org/yorba/california/rc/caldav-subscribe.ui")]
-internal class CalDAVActivatorPane : Gtk.Grid, Toolkit.Card {
-    public const string ID = "CalDAVActivatorPane";
+[GtkTemplate (ui = "/org/yorba/california/rc/generic-subscribe.ui")]
+internal abstract class Subscribe : Gtk.Grid, Toolkit.Card {
+    public abstract string card_id { get; }
     
-    public string card_id { get { return ID; } }
-    
-    public string? title { get { return null; } }
+    public abstract string? title { get; }
     
     public Gtk.Widget? default_widget { get { return subscribe_button; } }
     
@@ -28,37 +26,42 @@ internal class CalDAVActivatorPane : Gtk.Grid, Toolkit.Card {
     private Gtk.Entry url_entry;
     
     [GtkChild]
+    private Gtk.Entry username_entry;
+    
+    [GtkChild]
     private Gtk.Button subscribe_button;
     
-    private Backing.CalDAVSubscribable store;
-    private Toolkit.EntryClearTextConnector name_clear_text_connector;
-    private Toolkit.EntryClearTextConnector url_clear_text_connector;
+    private Gee.Set<string> schemes;
+    private Toolkit.EntryClearTextConnector clear_text_connector = new Toolkit.EntryClearTextConnector();
     
-    public CalDAVActivatorPane(Backing.CalDAVSubscribable store, Soup.URI? supplied_url) {
-        this.store = store;
+    public Subscribe(Soup.URI? supplied_url, Gee.Set<string> schemes) {
+        this.schemes = schemes;
         
         if (supplied_url != null) {
             url_entry.text = supplied_url.to_string(false);
             url_entry.sensitive = false;
         }
         
-        name_clear_text_connector = new Toolkit.EntryClearTextConnector(name_entry);
+        clear_text_connector.connect_to(name_entry);
         name_entry.bind_property("text-length", subscribe_button, "sensitive",
             BindingFlags.SYNC_CREATE, on_entry_changed);
         
-        url_clear_text_connector = new Toolkit.EntryClearTextConnector(url_entry);
+        clear_text_connector.connect_to(url_entry);
         url_entry.bind_property("text-length", subscribe_button, "sensitive",
             BindingFlags.SYNC_CREATE, on_entry_changed);
+        
+        // user name is optional
+        clear_text_connector.connect_to(username_entry);
     }
     
-    public void jumped_to(Toolkit.Card? from, Toolkit.Card.Jump reason, Value? message) {
+    public virtual void jumped_to(Toolkit.Card? from, Toolkit.Card.Jump reason, Value? message) {
     }
     
     private bool on_entry_changed(Binding binding, Value source_value, ref Value target_value) {
         target_value =
             name_entry.text_length > 0 
             && url_entry.text_length > 0
-            && URI.is_valid(url_entry.text, { "http://";, "https://";, });
+            && URI.is_valid(url_entry.text, schemes);
         
         return true;
     }
@@ -72,16 +75,16 @@ internal class CalDAVActivatorPane : Gtk.Grid, Toolkit.Card {
     private void on_subscribe_button_clicked() {
         sensitive = false;
         
-        subscribe_async.begin();
+        do_subscribe_async.begin();
     }
     
-    private async void subscribe_async() {
+    private async void do_subscribe_async() {
         Gdk.Cursor? cursor = Toolkit.set_busy(this);
         
         Error? subscribe_err = null;
         try {
-            yield store.subscribe_caldav_async(name_entry.text, URI.parse(url_entry.text),
-                null, Gfx.rgba_to_uint8_rgb_string(color_button.rgba), null);
+            yield subscribe_async(name_entry.text, URI.parse(url_entry.text), username_entry.text,
+                Gfx.rgba_to_uint8_rgb_string(color_button.rgba), null);
         } catch (Error err) {
             subscribe_err = err;
         }
@@ -91,10 +94,13 @@ internal class CalDAVActivatorPane : Gtk.Grid, Toolkit.Card {
         if (subscribe_err == null) {
             notify_success();
         } else {
-            notify_failure(_("Unable to subscribe to CalDAV calendar at %s: %s").printf(url_entry.text,
+            notify_failure(_("Unable to subscribe to calendar at %s: %s").printf(url_entry.text,
                 subscribe_err.message));
         }
     }
+    
+    protected abstract async void subscribe_async(string name, Soup.URI uri, string? username,
+        string color, Cancellable? cancellable) throws Error;
 }
 
 }
diff --git a/src/activator/google/activator-google.vala b/src/activator/google/google-activator-instance.vala
similarity index 57%
rename from src/activator/google/activator-google.vala
rename to src/activator/google/google-activator-instance.vala
index e667e49..3f5a97e 100644
--- a/src/activator/google/activator-google.vala
+++ b/src/activator/google/google-activator-instance.vala
@@ -4,14 +4,14 @@
  * (version 2.1 or later).  See the COPYING file in this distribution.
  */
 
-namespace California.Activator {
+namespace California.Activator.Google {
 
-internal class GoogleActivator : Instance {
-    public override string first_card_id { get { return GoogleLoginPane.ID; } }
+internal class ActivatorInstance : Instance {
+    public override string first_card_id { get { return LoginPane.ID; } }
     
     private Backing.CalDAVSubscribable caldav_store;
     
-    public GoogleActivator(string title, Backing.CalDAVSubscribable store) {
+    public ActivatorInstance(string title, Backing.CalDAVSubscribable store) {
         base (title, store);
         
         caldav_store = store;
@@ -19,9 +19,9 @@ internal class GoogleActivator : Instance {
     
     public override Gee.List<Toolkit.Card> create_cards(Soup.URI? supplied_uri) {
         Gee.List<Toolkit.Card> cards = new Gee.ArrayList<Toolkit.Card>();
-        cards.add(new GoogleLoginPane());
-        cards.add(new GoogleAuthenticatingPane());
-        cards.add(new GoogleCalendarListPane(caldav_store));
+        cards.add(new LoginPane());
+        cards.add(new AuthenticatingPane());
+        cards.add(new CalendarListPane(caldav_store));
         
         return cards;
     }
diff --git a/src/activator/google/activator-google-authenticating-pane.vala 
b/src/activator/google/google-authenticating-pane.vala
similarity index 95%
rename from src/activator/google/activator-google-authenticating-pane.vala
rename to src/activator/google/google-authenticating-pane.vala
index 026b1d7..12c107e 100644
--- a/src/activator/google/activator-google-authenticating-pane.vala
+++ b/src/activator/google/google-authenticating-pane.vala
@@ -4,10 +4,10 @@
  * (version 2.1 or later).  See the COPYING file in this distribution.
  */
 
-namespace California.Activator {
+namespace California.Activator.Google {
 
 [GtkTemplate (ui = "/org/yorba/california/rc/google-authenticating.ui")]
-public class GoogleAuthenticatingPane : Gtk.Grid, Toolkit.Card {
+public class AuthenticatingPane : Gtk.Grid, Toolkit.Card {
     public const string ID = "GoogleAuthenticatingPane";
     
     private const int SUCCESS_DELAY_MSEC = 1500;
@@ -50,7 +50,7 @@ public class GoogleAuthenticatingPane : Gtk.Grid, Toolkit.Card {
     
     private Cancellable cancellable = new Cancellable();
     
-    public GoogleAuthenticatingPane() {
+    public AuthenticatingPane() {
         if (app_id == null)
             app_id = "yorba-california-%s".printf(Application.VERSION);
     }
@@ -134,7 +134,7 @@ public class GoogleAuthenticatingPane : Gtk.Grid, Toolkit.Card {
         // delay gives the user a chance to see what's transpired
         yield sleep_msec_async(SUCCESS_DELAY_MSEC);
         
-        jump_to_card_by_name(GoogleCalendarListPane.ID, new GoogleCalendarListPane.Message(
+        jump_to_card_by_name(CalendarListPane.ID, new CalendarListPane.Message(
             credentials.username, own_calendars, all_calendars));
     }
     
diff --git a/src/activator/google/activator-google-calendar-list-pane.vala 
b/src/activator/google/google-calendar-list-pane.vala
similarity index 97%
rename from src/activator/google/activator-google-calendar-list-pane.vala
rename to src/activator/google/google-calendar-list-pane.vala
index 6dc545f..234e2d4 100644
--- a/src/activator/google/activator-google-calendar-list-pane.vala
+++ b/src/activator/google/google-calendar-list-pane.vala
@@ -4,10 +4,10 @@
  * (version 2.1 or later).  See the COPYING file in this distribution.
  */
 
-namespace California.Activator {
+namespace California.Activator.Google {
 
 [GtkTemplate (ui = "/org/yorba/california/rc/google-calendar-list.ui")]
-public class GoogleCalendarListPane : Gtk.Grid, Toolkit.Card {
+public class CalendarListPane : Gtk.Grid, Toolkit.Card {
     public const string ID = "GoogleCalendarListPane";
     
     public class Message : BaseObject {
@@ -48,7 +48,7 @@ public class GoogleCalendarListPane : Gtk.Grid, Toolkit.Card {
     private Toolkit.ListBoxModel<GData.CalendarCalendar> own_calendars_model;
     private Toolkit.ListBoxModel<GData.CalendarCalendar> unowned_calendars_model;
     
-    public GoogleCalendarListPane(Backing.CalDAVSubscribable store) {
+    public CalendarListPane(Backing.CalDAVSubscribable store) {
         this.store = store;
         
         own_calendars_listbox.set_placeholder(create_placeholder());
diff --git a/src/activator/google/activator-google-login-pane.vala 
b/src/activator/google/google-login-pane.vala
similarity index 74%
rename from src/activator/google/activator-google-login-pane.vala
rename to src/activator/google/google-login-pane.vala
index a66b761..956bfab 100644
--- a/src/activator/google/activator-google-login-pane.vala
+++ b/src/activator/google/google-login-pane.vala
@@ -4,10 +4,10 @@
  * (version 2.1 or later).  See the COPYING file in this distribution.
  */
 
-namespace California.Activator {
+namespace California.Activator.Google {
 
 [GtkTemplate (ui = "/org/yorba/california/rc/google-login.ui")]
-internal class GoogleLoginPane : Gtk.Grid, Toolkit.Card {
+internal class LoginPane : Gtk.Grid, Toolkit.Card {
     public const string ID = "GoogleLoginPane";
     
     public string card_id { get { return ID; } }
@@ -27,15 +27,14 @@ internal class GoogleLoginPane : Gtk.Grid, Toolkit.Card {
     [GtkChild]
     private Gtk.Button login_button;
     
-    private Toolkit.EntryClearTextConnector account_clear_text_connector;
-    private Toolkit.EntryClearTextConnector password_clear_text_connector;
+    private Toolkit.EntryClearTextConnector clear_text_connector = new Toolkit.EntryClearTextConnector();
     
-    public GoogleLoginPane() {
-        account_clear_text_connector = new Toolkit.EntryClearTextConnector(account_entry);
+    public LoginPane() {
+        clear_text_connector.connect_to(account_entry);
         account_entry.bind_property("text-length", login_button, "sensitive",
             BindingFlags.SYNC_CREATE, on_entry_changed);
         
-        password_clear_text_connector = new Toolkit.EntryClearTextConnector(password_entry);
+        clear_text_connector.connect_to(password_entry);
         password_entry.bind_property("text-length", login_button, "sensitive",
             BindingFlags.SYNC_CREATE, on_entry_changed);
     }
@@ -57,7 +56,7 @@ internal class GoogleLoginPane : Gtk.Grid, Toolkit.Card {
     
     [GtkCallback]
     private void on_login_button_clicked() {
-        jump_to_card_by_name(GoogleAuthenticatingPane.ID, new GoogleAuthenticatingPane.Message(
+        jump_to_card_by_name(AuthenticatingPane.ID, new AuthenticatingPane.Message(
             account_entry.text, password_entry.text));
     }
 }
diff --git a/src/activator/webcal/activator-webcal.vala b/src/activator/webcal/webcal-activator-instance.vala
similarity index 50%
rename from src/activator/webcal/activator-webcal.vala
rename to src/activator/webcal/webcal-activator-instance.vala
index a74b301..aa742a3 100644
--- a/src/activator/webcal/activator-webcal.vala
+++ b/src/activator/webcal/webcal-activator-instance.vala
@@ -4,24 +4,22 @@
  * (version 2.1 or later).  See the COPYING file in this distribution.
  */
 
-namespace California.Activator {
+namespace California.Activator.WebCal {
 
-internal class WebCalActivator : Instance {
-    public override string first_card_id { get { return WebCalActivatorPane.ID; } }
+internal class ActivatorInstance : Instance {
+    public override string first_card_id { get { return Subscribe.ID; } }
     
     private Backing.WebCalSubscribable webcal_store;
     
-    public WebCalActivator(string title, Backing.WebCalSubscribable store) {
+    public ActivatorInstance(string title, Backing.WebCalSubscribable store) {
         base (title, store);
         
         webcal_store = store;
     }
     
     public override Gee.List<Toolkit.Card> create_cards(Soup.URI? supplied_uri) {
-        Gee.List<Toolkit.Card> cards = new Gee.ArrayList<Toolkit.Card>();
-        cards.add(new WebCalActivatorPane(webcal_store, supplied_uri));
-        
-        return cards;
+        return iterate<Toolkit.Card>(new Subscribe(webcal_store, supplied_uri))
+            .to_array_list();
     }
 }
 
diff --git a/src/activator/webcal/webcal-subscribe.vala b/src/activator/webcal/webcal-subscribe.vala
new file mode 100644
index 0000000..5b757db
--- /dev/null
+++ b/src/activator/webcal/webcal-subscribe.vala
@@ -0,0 +1,31 @@
+/* Copyright 2014 Yorba Foundation
+ *
+ * This software is licensed under the GNU Lesser General Public License
+ * (version 2.1 or later).  See the COPYING file in this distribution.
+ */
+
+namespace California.Activator.WebCal {
+
+internal class Subscribe : California.Activator.Generic.Subscribe {
+    public const string ID = "WebCalActivatorPane";
+    
+    public override string card_id { get { return ID; } }
+    
+    public override string? title { get { return null; } }
+    
+    private Backing.WebCalSubscribable store;
+    
+    public Subscribe(Backing.WebCalSubscribable store, Soup.URI? supplied_url) {
+        base (supplied_url, iterate<string>("http://";, "https://";, "webcal://").to_hash_set());
+        
+        this.store = store;
+    }
+    
+    protected override async void subscribe_async(string name, Soup.URI uri, string? username,
+        string color, Cancellable? cancellable) throws Error {
+        yield store.subscribe_webcal_async(name, uri, username, color, cancellable);
+    }
+}
+
+}
+
diff --git a/src/california-resources.xml b/src/california-resources.xml
index 7a1cc62..5cfdfe8 100644
--- a/src/california-resources.xml
+++ b/src/california-resources.xml
@@ -7,9 +7,6 @@
         <file compressed="true">rc/app-menu.interface</file>
     </gresource>
     <gresource prefix="/org/yorba/california">
-        <file compressed="true">rc/caldav-subscribe.ui</file>
-    </gresource>
-    <gresource prefix="/org/yorba/california">
         <file compressed="true">rc/calendar-import.ui</file>
     </gresource>
     <gresource prefix="/org/yorba/california">
@@ -34,6 +31,9 @@
         <file compressed="false">rc/event-time-settings.ui</file>
     </gresource>
     <gresource prefix="/org/yorba/california">
+        <file compressed="true">rc/generic-subscribe.ui</file>
+    </gresource>
+    <gresource prefix="/org/yorba/california">
         <file compressed="true">rc/google-authenticating.ui</file>
     </gresource>
     <gresource prefix="/org/yorba/california">
@@ -49,9 +49,6 @@
         <file compressed="false">rc/show-event.ui</file>
     </gresource>
     <gresource prefix="/org/yorba/california">
-        <file compressed="true">rc/webcal-subscribe.ui</file>
-    </gresource>
-    <gresource prefix="/org/yorba/california">
         <file compressed="true">rc/window-menu.interface</file>
     </gresource>
 </gresources>
diff --git a/src/host/host-create-update-event.vala b/src/host/host-create-update-event.vala
index 18afe62..dc927d7 100644
--- a/src/host/host-create-update-event.vala
+++ b/src/host/host-create-update-event.vala
@@ -58,8 +58,7 @@ public class CreateUpdateEvent : Gtk.Grid, Toolkit.Card {
     private Toolkit.ComboBoxTextModel<Backing.CalendarSource> calendar_model;
     
     private Toolkit.RotatingButtonBox rotating_button_box = new Toolkit.RotatingButtonBox();
-    private Toolkit.EntryClearTextConnector summary_clear_text_connector;
-    private Toolkit.EntryClearTextConnector location_clear_text_connector;
+    private Toolkit.EntryClearTextConnector clear_text_connector = new Toolkit.EntryClearTextConnector();
     
     private Gtk.Button accept_button = new Gtk.Button();
     private Gtk.Button cancel_button = new Gtk.Button.with_mnemonic(_("_Cancel"));
@@ -70,11 +69,11 @@ public class CreateUpdateEvent : Gtk.Grid, Toolkit.Card {
     public CreateUpdateEvent() {
         // create button is active only if summary is filled out; all other fields (so far)
         // guarantee valid values at all times
-        summary_clear_text_connector = new Toolkit.EntryClearTextConnector(summary_entry);
+        clear_text_connector.connect_to(summary_entry);
         summary_entry.bind_property("text", accept_button, "sensitive", BindingFlags.SYNC_CREATE,
             transform_summary_to_accept);
         
-        location_clear_text_connector = new Toolkit.EntryClearTextConnector(location_entry);
+        clear_text_connector.connect_to(location_entry);
         
         // use model to control calendars combo box
         calendar_model = new Toolkit.ComboBoxTextModel<Backing.CalendarSource>(calendar_combo,
diff --git a/src/host/host-quick-create-event.vala b/src/host/host-quick-create-event.vala
index 5d9c5a9..62834e2 100644
--- a/src/host/host-quick-create-event.vala
+++ b/src/host/host-quick-create-event.vala
@@ -39,7 +39,7 @@ public class QuickCreateEvent : Gtk.Grid, Toolkit.Card {
     private Gtk.Button create_button;
     
     private Toolkit.ComboBoxTextModel<Backing.CalendarSource> model;
-    private Toolkit.EntryClearTextConnector entry_clear_text_connector;
+    private Toolkit.EntryClearTextConnector clear_text_connector = new Toolkit.EntryClearTextConnector();
     
     public QuickCreateEvent() {
         // create and initialize combo box model
@@ -51,7 +51,7 @@ public class QuickCreateEvent : Gtk.Grid, Toolkit.Card {
                 model.add(calendar_source);
         }
         
-        entry_clear_text_connector = new Toolkit.EntryClearTextConnector(details_entry);
+        clear_text_connector.connect_to(details_entry);
         details_entry.bind_property("text", create_button, "sensitive", BindingFlags.SYNC_CREATE,
             transform_text_to_sensitivity);
     }
diff --git a/src/rc/caldav-subscribe.ui b/src/rc/generic-subscribe.ui
similarity index 80%
rename from src/rc/caldav-subscribe.ui
rename to src/rc/generic-subscribe.ui
index d308113..73af0bb 100644
--- a/src/rc/caldav-subscribe.ui
+++ b/src/rc/generic-subscribe.ui
@@ -2,7 +2,7 @@
 <!-- Generated with glade 3.16.1 -->
 <interface>
   <requires lib="gtk+" version="3.10"/>
-  <template class="CaliforniaActivatorCalDAVActivatorPane" parent="GtkGrid">
+  <template class="CaliforniaActivatorGenericSubscribe" parent="GtkGrid">
     <property name="visible">True</property>
     <property name="can_focus">False</property>
     <property name="row_spacing">8</property>
@@ -12,7 +12,7 @@
         <property name="visible">True</property>
         <property name="can_focus">False</property>
         <property name="halign">end</property>
-        <property name="label" translatable="yes">_Name</property>
+        <property name="label" translatable="yes">Calendar _name</property>
         <property name="use_underline">True</property>
         <style>
           <class name="dim-label"/>
@@ -67,9 +67,10 @@
             <property name="visible">True</property>
             <property name="can_focus">True</property>
             <property name="receives_default">True</property>
+            <property name="tooltip_text" translatable="yes">Calendar color</property>
             <property name="halign">end</property>
             <property name="valign">end</property>
-            <property name="title" translatable="yes">Select a color for the Web calendar</property>
+            <property name="title" translatable="yes">Select a color for the calendar</property>
             <property name="rgba">rgb(32,32,204)</property>
             <style>
               <class name="image-button"/>
@@ -99,7 +100,7 @@
             <property name="can_focus">True</property>
             <property name="hexpand">True</property>
             <property name="activates_default">True</property>
-            <property name="width_chars">40</property>
+            <property name="width_chars">32</property>
             <property name="input_purpose">url</property>
           </object>
           <packing>
@@ -165,10 +166,43 @@
       </object>
       <packing>
         <property name="left_attach">0</property>
-        <property name="top_attach">2</property>
+        <property name="top_attach">3</property>
         <property name="width">2</property>
         <property name="height">1</property>
       </packing>
     </child>
+    <child>
+      <object class="GtkLabel" id="username_label">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="halign">end</property>
+        <property name="xalign">1</property>
+        <property name="label" translatable="yes">User name</property>
+        <style>
+          <class name="dim-label"/>
+        </style>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">2</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkEntry" id="username_entry">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="tooltip_text" translatable="yes">If supplied, your password will be requested when 
calendar is first accessed</property>
+        <property name="width_chars">32</property>
+        <property name="placeholder_text" translatable="yes">optional</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">2</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
   </template>
 </interface>
diff --git a/src/toolkit/toolkit-entry-clear-text-connector.vala 
b/src/toolkit/toolkit-entry-clear-text-connector.vala
index 410ee32..da881ee 100644
--- a/src/toolkit/toolkit-entry-clear-text-connector.vala
+++ b/src/toolkit/toolkit-entry-clear-text-connector.vala
@@ -12,20 +12,32 @@ namespace California.Toolkit {
  */
 
 public class EntryClearTextConnector : BaseObject {
-    public Gtk.Entry entry { get; private set; }
+    private Gee.HashMap<Gtk.Entry, Binding> entries = new Gee.HashMap<Gtk.Entry, Binding>();
     
-    private Binding text_binding;
+    public EntryClearTextConnector() {
+    }
+    
+    ~EntryClearTextConnector() {
+        traverse_safely<Gtk.Entry>(entries.keys).iterate(disconnect_from);
+    }
     
-    public EntryClearTextConnector(Gtk.Entry entry) {
-        this.entry = entry;
+    public void connect_to(Gtk.Entry entry) {
+        if (entries.has_key(entry))
+            return;
         
-        text_binding = entry.bind_property("text", entry, "secondary-icon-name", BindingFlags.SYNC_CREATE,
+        Binding binding = entry.bind_property("text", entry, "secondary-icon-name", BindingFlags.SYNC_CREATE,
             transform_text_to_icon_name);
         entry.icon_release.connect(on_entry_icon_released);
+        
+        entries.set(entry, binding);
     }
     
-    ~EntryClearTextConnector() {
-        text_binding.unref();
+    public void disconnect_from(Gtk.Entry entry) {
+        Binding binding;
+        if (!entries.unset(entry, out binding))
+            return;
+        
+        binding.unbind();
         entry.icon_release.disconnect(on_entry_icon_released);
     }
     
@@ -33,14 +45,14 @@ public class EntryClearTextConnector : BaseObject {
         if (String.is_empty((string) source_value)) {
             target_value = "";
         } else {
-            target_value = entry.get_direction() == Gtk.TextDirection.RTL
+            target_value = ((Gtk.Entry) binding.source).get_direction() == Gtk.TextDirection.RTL
                 ? "edit-clear-rtl-symbolic" : "edit-clear-symbolic";
         }
         
         return true;
     }
     
-    private void on_entry_icon_released(Gtk.EntryIconPosition icon, Gdk.Event event) {
+    private void on_entry_icon_released(Gtk.Entry entry, Gtk.EntryIconPosition icon, Gdk.Event event) {
         if (icon == Gtk.EntryIconPosition.SECONDARY)
             entry.text = "";
     }
diff --git a/src/util/util-uri.vala b/src/util/util-uri.vala
index 3f9b004..83390ed 100644
--- a/src/util/util-uri.vala
+++ b/src/util/util-uri.vala
@@ -23,28 +23,18 @@ namespace California.URI {
  * If "supported_schemes" are specified, then the entire scheme (name and separator) should be
  * included, i.e. "http://";, "mailto:";, etc.
  */
-public bool is_valid(string? uri, string[]? supported_schemes) {
+public bool is_valid(string? uri, Gee.Set<string>? supported_schemes) {
     // strip leading and trailing whitespace
     string? stripped = (uri != null) ? uri.strip() : null;
     if (String.is_empty(stripped))
         return false;
     
-    if (supported_schemes == null || supported_schemes.length == 0) {
-        if (!stripped.contains(":"))
-            return false;
-    } else {
-        bool found = false;
-        foreach (string scheme in supported_schemes) {
-            if (stripped.has_prefix(scheme)) {
-                found = true;
-                
-                break;
-            }
-        }
-        
-        if (!found)
-            return false;
-    }
+    // gotta have this, at least
+    if (!stripped.contains(":"))
+        return false;
+    
+    if (!traverse<string>(supported_schemes).any(scheme => stripped.has_prefix(scheme)))
+        return false;
     
     // finally, let Soup.URI decide
     Soup.URI? parsed = new Soup.URI(uri);


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