[california] Add calendar in Calendar Manager: Bug #733637



commit 5e63ec6f7a15df19c23b6c35393d21d78564a831
Author: Jim Nelson <jim yorba org>
Date:   Fri Aug 8 16:06:16 2014 -0700

    Add calendar in Calendar Manager: Bug #733637
    
    This also removes the "Add Calendar..." item from the application
    menu, leaving just "Calendars" to launch the Calendar Manager.

 src/Makefile.am                             |    1 -
 src/activator/activator-instance-list.vala  |    3 +-
 src/activator/activator-instance.vala       |    2 +-
 src/activator/activator-window.vala         |   47 ----------
 src/activator/activator.vala                |   14 +++
 src/application/california-application.vala |    8 --
 src/collection/collection-iterable.vala     |   13 +++
 src/manager/manager-calendar-list.vala      |   39 ++++++++
 src/manager/manager-window.vala             |    1 +
 src/rc/activator-list.ui                    |    2 +-
 src/rc/app-menu.interface                   |    4 -
 src/rc/calendar-manager-list-item.ui        |    2 +
 src/rc/calendar-manager-list.ui             |  126 +++++++++++++++++++++++----
 src/rc/generic-subscribe.ui                 |   47 ++++------
 src/toolkit/toolkit-listbox-model.vala      |   10 ++
 15 files changed, 209 insertions(+), 110 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 6dde145..dfd25be 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -12,7 +12,6 @@ california_VALASOURCES = \
        activator/activator.vala \
        activator/activator-instance.vala \
        activator/activator-instance-list.vala \
-       activator/activator-window.vala \
        \
        activator/caldav/caldav-activator-instance.vala \
        activator/caldav/caldav-subscribe.vala \
diff --git a/src/activator/activator-instance-list.vala b/src/activator/activator-instance-list.vala
index 324deed..f3bf575 100644
--- a/src/activator/activator-instance-list.vala
+++ b/src/activator/activator-instance-list.vala
@@ -44,6 +44,7 @@ public class InstanceList : Gtk.Grid, Toolkit.Card {
     }
     
     public void jumped_to(Toolkit.Card? from, Toolkit.Card.Jump reason, Value? message) {
+        listbox.select_row(listbox.get_row_at_index(0));
     }
     
     private void on_item_activated(Instance activator) {
@@ -58,7 +59,7 @@ public class InstanceList : Gtk.Grid, Toolkit.Card {
     
     [GtkCallback]
     private void on_cancel_button_clicked() {
-        notify_user_closed();
+        jump_home();
     }
     
     private void start(Instance activator) {
diff --git a/src/activator/activator-instance.vala b/src/activator/activator-instance.vala
index 5926d25..b2a0932 100644
--- a/src/activator/activator-instance.vala
+++ b/src/activator/activator-instance.vala
@@ -47,7 +47,7 @@ public abstract class Instance : BaseObject {
      * Return a collection of { link Cards} that guides the user through the steps to create a
      * { link Backing.Source}.
      *
-     * The first Card will be jumped to initially.
+     * The process can be started by jumping to the { link first_card_id}.
      */
     public abstract Gee.List<Toolkit.Card> create_cards(Soup.URI? supplied_uri);
     
diff --git a/src/activator/activator.vala b/src/activator/activator.vala
index d65725d..810fbc6 100644
--- a/src/activator/activator.vala
+++ b/src/activator/activator.vala
@@ -48,5 +48,19 @@ public void terminate() {
     Toolkit.terminate();
 }
 
+/**
+ * Adds all known { link Instance}s to the supplied { link Toolkit.Deck} (each having their own set
+ * of { link Toolkit.Card}s) as well as an { link InstanceList} Card.
+ */
+public Toolkit.Deck prepare_deck(Toolkit.Deck deck, Soup.URI? supplied_uri) {
+    deck.add_card(new InstanceList());
+    deck.add_cards(traverse<Instance>(activators)
+        .bloom<Toolkit.Card>(instance => instance.create_cards(supplied_uri))
+        .to_array_list()
+    );
+    
+    return deck;
+}
+
 }
 
diff --git a/src/application/california-application.vala b/src/application/california-application.vala
index 321dae2..bae0c14 100644
--- a/src/application/california-application.vala
+++ b/src/application/california-application.vala
@@ -33,9 +33,6 @@ public class Application : Gtk.Application {
     
     // public application menu actions; note their "app." prefix which does not
     // match the actions in the action_entries table
-    public const string DETAILED_ACTION_NEW_CALENDAR = "app.new-calendar";
-    public const string ACTION_NEW_CALENDAR = "new-calendar";
-    
     public const string DETAILED_ACTION_CALENDAR_MANAGER = "app.calendar-manager";
     public const string ACTION_CALENDAR_MANAGER = "calendar-manager";
     
@@ -57,7 +54,6 @@ public class Application : Gtk.Application {
     
     private static const ActionEntry[] action_entries = {
         // public actions
-        { ACTION_NEW_CALENDAR, on_new_calendar },
         { ACTION_CALENDAR_MANAGER, on_calendar_manager },
         { ACTION_ABOUT, on_about },
         { ACTION_QUIT, on_quit },
@@ -211,10 +207,6 @@ public class Application : Gtk.Application {
         dialog.destroy();
     }
     
-    private void on_new_calendar() {
-        Activator.Window.display(main_window);
-    }
-    
     private void on_calendar_manager() {
         Manager.Window.display(main_window);
     }
diff --git a/src/collection/collection-iterable.vala b/src/collection/collection-iterable.vala
index 5648456..66a1e79 100644
--- a/src/collection/collection-iterable.vala
+++ b/src/collection/collection-iterable.vala
@@ -109,6 +109,11 @@ public class Iterable<G> : Object {
     public delegate void Iterate<G>(G element);
     
     /**
+     * For mapping a single value of one type to multiple values of another.
+     */
+    public delegate Gee.Collection<A> Bloom<A, G>(G element);
+    
+    /**
      * A private class that lets us take a California.Iterable and convert it back
      * into a Gee.Iterable.
      */
@@ -163,6 +168,14 @@ public class Iterable<G> : Object {
         return new Iterable<A>(i.map<A>(f));
     }
     
+    public Iterable<A> bloom<A>(Bloom<A, G> bloom_cb) {
+        Gee.ArrayList<A> list = new Gee.ArrayList<A>();
+        foreach (G element in this)
+            list.add_all(bloom_cb(element));
+        
+        return new Iterable<A>(list.iterator());
+    }
+    
     public Iterable<A> scan<A>(Gee.FoldFunc<A, G> f, owned A seed) {
         return new Iterable<A>(i.scan<A>(f, seed));
     }
diff --git a/src/manager/manager-calendar-list.vala b/src/manager/manager-calendar-list.vala
index be48193..42c0493 100644
--- a/src/manager/manager-calendar-list.vala
+++ b/src/manager/manager-calendar-list.vala
@@ -29,6 +29,12 @@ internal class CalendarList : Gtk.Grid, Toolkit.Card {
     [GtkChild]
     private Gtk.ListBox calendar_list_box;
     
+    [GtkChild]
+    private Gtk.Button edit_button;
+    
+    [GtkChild]
+    private Gtk.Button remove_button;
+    
     private Toolkit.ListBoxModel<Backing.CalendarSource> model;
     
     public CalendarList() {
@@ -44,6 +50,15 @@ internal class CalendarList : Gtk.Grid, Toolkit.Card {
         
         // otherwise, initialize when it does open
         Backing.Manager.instance.notify[Backing.Manager.PROP_IS_OPEN].connect(on_manager_opened_closed);
+        
+        model.bind_property(Toolkit.ListBoxModel.PROP_SELECTED, edit_button, "sensitive",
+            BindingFlags.SYNC_CREATE, transform_selected_to_sensitive);
+        model.bind_property(Toolkit.ListBoxModel.PROP_SELECTED, remove_button, "sensitive",
+            BindingFlags.SYNC_CREATE, transform_selected_to_sensitive);
+        
+        // TODO: Remove this when deleting a calendar is implemented
+        remove_button.visible = false;
+        remove_button.no_show_all = true;
     }
     
     ~CalendarList() {
@@ -53,6 +68,12 @@ internal class CalendarList : Gtk.Grid, Toolkit.Card {
         Backing.Manager.instance.notify[Backing.Manager.PROP_IS_OPEN].disconnect(on_manager_opened_closed);
     }
     
+    private bool transform_selected_to_sensitive(Binding binding, Value source_value, ref Value 
target_value) {
+        target_value = model.selected != null;
+        
+        return true;
+    }
+    
     public void jumped_to(Toolkit.Card? from, Toolkit.Card.Jump reason, Value? message) {
     }
     
@@ -104,6 +125,24 @@ internal class CalendarList : Gtk.Grid, Toolkit.Card {
     }
     
     [GtkCallback]
+    private void on_add_button_clicked() {
+        jump_to_card_by_name(Activator.InstanceList.ID, null);
+    }
+    
+    [GtkCallback]
+    private void on_edit_button_clicked() {
+        if (model.selected == null)
+            return;
+        
+        CalendarListItem item = (CalendarListItem) model.get_widget_for_item(model.selected);
+        item.rename();
+    }
+    
+    [GtkCallback]
+    private void on_remove_button_clicked() {
+    }
+    
+    [GtkCallback]
     private void on_close_button_clicked() {
         notify_user_closed();
     }
diff --git a/src/manager/manager-window.vala b/src/manager/manager-window.vala
index 64bf98c..fe61b5e 100644
--- a/src/manager/manager-window.vala
+++ b/src/manager/manager-window.vala
@@ -19,6 +19,7 @@ public class Window : Toolkit.DeckWindow {
         base (parent, null);
         
         deck.add_cards(iterate<Toolkit.Card>(calendar_list).to_array_list());
+        Activator.prepare_deck(deck, null);
     }
     
     public static void display(Gtk.Window? parent) {
diff --git a/src/rc/activator-list.ui b/src/rc/activator-list.ui
index 37d5cba..da4bb6b 100644
--- a/src/rc/activator-list.ui
+++ b/src/rc/activator-list.ui
@@ -42,7 +42,7 @@
         <property name="layout_style">end</property>
         <child>
           <object class="GtkButton" id="cancel_button">
-            <property name="label" translatable="yes">_Close</property>
+            <property name="label" translatable="yes">_Cancel</property>
             <property name="visible">True</property>
             <property name="can_focus">True</property>
             <property name="receives_default">True</property>
diff --git a/src/rc/app-menu.interface b/src/rc/app-menu.interface
index a4c5501..564080b 100644
--- a/src/rc/app-menu.interface
+++ b/src/rc/app-menu.interface
@@ -3,10 +3,6 @@
     <menu id="app-menu">
         <section>
             <item>
-                <attribute name="label" translatable="yes">_Add Calendar…</attribute>
-                <attribute name="action">app.new-calendar</attribute>
-            </item>
-            <item>
                 <attribute name="label" translatable="yes">_Calendars</attribute>
                 <attribute name="action">app.calendar-manager</attribute>
                 <attribute name="accel">&lt;Primary&gt;l</attribute>
diff --git a/src/rc/calendar-manager-list-item.ui b/src/rc/calendar-manager-list-item.ui
index 6b5f2d7..6558999 100644
--- a/src/rc/calendar-manager-list-item.ui
+++ b/src/rc/calendar-manager-list-item.ui
@@ -11,6 +11,7 @@
         <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">center</property>
         <property name="valign">center</property>
         <property name="title" translatable="yes">Calendar color</property>
@@ -27,6 +28,7 @@
         <property name="visible">True</property>
         <property name="can_focus">True</property>
         <property name="receives_default">False</property>
+        <property name="tooltip_text" translatable="yes">Calendar visibility</property>
         <property name="halign">start</property>
         <property name="valign">center</property>
         <property name="xalign">0.50999999046325684</property>
diff --git a/src/rc/calendar-manager-list.ui b/src/rc/calendar-manager-list.ui
index 65d2a74..32eaa06 100644
--- a/src/rc/calendar-manager-list.ui
+++ b/src/rc/calendar-manager-list.ui
@@ -6,6 +6,41 @@
     <property name="visible">True</property>
     <property name="can_focus">False</property>
     <child>
+      <object class="GtkScrolledWindow" id="calendar_list_scrolledwindow">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="hexpand">True</property>
+        <property name="vexpand">True</property>
+        <property name="hscrollbar_policy">never</property>
+        <property name="shadow_type">in</property>
+        <property name="min_content_width">200</property>
+        <property name="min_content_height">300</property>
+        <child>
+          <object class="GtkViewport" id="calendar_list_viewport">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <child>
+              <object class="GtkListBox" id="calendar_list_box">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="hexpand">True</property>
+                <property name="vexpand">True</property>
+                <property name="activate_on_single_click">False</property>
+                <signal name="row-activated" handler="on_calendar_list_box_row_activated" 
object="CaliforniaManagerCalendarList" swapped="no"/>
+                <signal name="row-selected" handler="on_calendar_list_box_row_selected" 
object="CaliforniaManagerCalendarList" swapped="no"/>
+              </object>
+            </child>
+          </object>
+        </child>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">0</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
+    <child>
       <object class="GtkButtonBox" id="calendar_list_button_box">
         <property name="visible">True</property>
         <property name="can_focus">False</property>
@@ -34,42 +69,97 @@
       </object>
       <packing>
         <property name="left_attach">0</property>
-        <property name="top_attach">1</property>
+        <property name="top_attach">2</property>
         <property name="width">1</property>
         <property name="height">1</property>
       </packing>
     </child>
     <child>
-      <object class="GtkScrolledWindow" id="calendar_list_scrolledwindow">
+      <object class="GtkBox" id="box1">
         <property name="visible">True</property>
-        <property name="can_focus">True</property>
-        <property name="hexpand">True</property>
-        <property name="vexpand">True</property>
-        <property name="hscrollbar_policy">never</property>
-        <property name="shadow_type">in</property>
-        <property name="min_content_width">200</property>
-        <property name="min_content_height">300</property>
+        <property name="can_focus">False</property>
         <child>
-          <object class="GtkViewport" id="calendar_list_viewport">
+          <object class="GtkButton" id="add_button">
             <property name="visible">True</property>
-            <property name="can_focus">False</property>
+            <property name="can_focus">True</property>
+            <property name="receives_default">True</property>
+            <property name="tooltip_text" translatable="yes">Add calendar</property>
+            <property name="halign">center</property>
+            <property name="valign">start</property>
+            <property name="hexpand">False</property>
+            <property name="vexpand">False</property>
+            <signal name="clicked" handler="on_add_button_clicked" object="CaliforniaManagerCalendarList" 
swapped="no"/>
             <child>
-              <object class="GtkListBox" id="calendar_list_box">
+              <object class="GtkImage" id="image1">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-                <property name="hexpand">True</property>
-                <property name="vexpand">True</property>
-                <property name="activate_on_single_click">False</property>
-                <signal name="row-activated" handler="on_calendar_list_box_row_activated" 
object="CaliforniaManagerCalendarList" swapped="no"/>
-                <signal name="row-selected" handler="on_calendar_list_box_row_selected" 
object="CaliforniaManagerCalendarList" swapped="no"/>
+                <property name="pixel_size">12</property>
+                <property name="icon_name">list-add-symbolic</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkButton" id="edit_button">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="receives_default">True</property>
+            <property name="tooltip_text" translatable="yes">Rename calendar</property>
+            <property name="halign">start</property>
+            <property name="valign">center</property>
+            <property name="hexpand">False</property>
+            <property name="vexpand">False</property>
+            <signal name="clicked" handler="on_edit_button_clicked" object="CaliforniaManagerCalendarList" 
swapped="no"/>
+            <child>
+              <object class="GtkImage" id="image2">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="pixel_size">12</property>
+                <property name="icon_name">accessories-text-editor-symbolic</property>
               </object>
             </child>
           </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkButton" id="remove_button">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="receives_default">True</property>
+            <property name="tooltip_text" translatable="yes">Delete calendar</property>
+            <property name="halign">start</property>
+            <property name="valign">center</property>
+            <property name="hexpand">False</property>
+            <property name="vexpand">False</property>
+            <signal name="clicked" handler="on_remove_button_clicked" object="CaliforniaManagerCalendarList" 
swapped="no"/>
+            <child>
+              <object class="GtkImage" id="image3">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="pixel_size">12</property>
+                <property name="icon_name">list-remove-symbolic</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">2</property>
+          </packing>
         </child>
       </object>
       <packing>
         <property name="left_attach">0</property>
-        <property name="top_attach">0</property>
+        <property name="top_attach">1</property>
         <property name="width">1</property>
         <property name="height">1</property>
       </packing>
diff --git a/src/rc/generic-subscribe.ui b/src/rc/generic-subscribe.ui
index 9c12e0b..a1af185 100644
--- a/src/rc/generic-subscribe.ui
+++ b/src/rc/generic-subscribe.ui
@@ -53,7 +53,7 @@
             <property name="visible">True</property>
             <property name="can_focus">True</property>
             <property name="activates_default">True</property>
-            <property name="width_chars">40</property>
+            <property name="width_chars">24</property>
           </object>
           <packing>
             <property name="expand">True</property>
@@ -91,33 +91,6 @@
       </packing>
     </child>
     <child>
-      <object class="GtkBox" id="box3">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <child>
-          <object class="GtkEntry" id="url_entry">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="hexpand">True</property>
-            <property name="activates_default">True</property>
-            <property name="width_chars">32</property>
-            <property name="input_purpose">url</property>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
-          </packing>
-        </child>
-      </object>
-      <packing>
-        <property name="left_attach">1</property>
-        <property name="top_attach">1</property>
-        <property name="width">1</property>
-        <property name="height">1</property>
-      </packing>
-    </child>
-    <child>
       <object class="GtkButtonBox" id="button_box">
         <property name="visible">True</property>
         <property name="can_focus">False</property>
@@ -194,7 +167,7 @@
         <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="width_chars">24</property>
         <property name="placeholder_text" translatable="yes">optional</property>
       </object>
       <packing>
@@ -204,5 +177,21 @@
         <property name="height">1</property>
       </packing>
     </child>
+    <child>
+      <object class="GtkEntry" id="url_entry">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="hexpand">True</property>
+        <property name="activates_default">True</property>
+        <property name="width_chars">24</property>
+        <property name="input_purpose">url</property>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">1</property>
+        <property name="width">1</property>
+        <property name="height">1</property>
+      </packing>
+    </child>
   </template>
 </interface>
diff --git a/src/toolkit/toolkit-listbox-model.vala b/src/toolkit/toolkit-listbox-model.vala
index aca1582..951b8ad 100644
--- a/src/toolkit/toolkit-listbox-model.vala
+++ b/src/toolkit/toolkit-listbox-model.vala
@@ -197,6 +197,16 @@ public class ListBoxModel<G> : BaseObject {
     }
     
     /**
+     * Returns the { link ModelPresentation} widget for the item.
+     */
+    public Gtk.Widget? get_widget_for_item(G item) {
+        if (!items.has_key(item))
+            return null;
+        
+        return items.get(item).get_child();
+    }
+    
+    /**
      * Call to indicate that the contents of the item has mutated, i.e. changed or been altered,
      * in such a way to affect sorting or filtering.
      */


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