[california/wip/732930-explain] Fleshing it out



commit ca0b9acef5db8d8daed890c081a00d903a9d46ae
Author: Jim Nelson <jim yorba org>
Date:   Thu Sep 4 19:31:40 2014 -0700

    Fleshing it out

 src/component/component-recurrence-rule.vala |  109 ++++++++++++++++++++++---
 1 files changed, 96 insertions(+), 13 deletions(-)
---
diff --git a/src/component/component-recurrence-rule.vala b/src/component/component-recurrence-rule.vala
index ee0b293..16774cb 100644
--- a/src/component/component-recurrence-rule.vala
+++ b/src/component/component-recurrence-rule.vala
@@ -583,46 +583,129 @@ public class RecurrenceRule : BaseObject {
      * Returns null if the RRULE is beyond the comprehension of this parser.
      */
     public string? explain() {
-        string unit;
         switch (freq) {
             case iCal.icalrecurrencetype_frequency.DAILY_RECURRENCE:
-                unit = ngettext("day", "%d days", interval);
-            break;
+                return explain_simple(ngettext("day", "%d days", interval).printf(interval));
             
             case iCal.icalrecurrencetype_frequency.WEEKLY_RECURRENCE:
-                unit = ngettext("week", "%d weeks", interval);
-            break;
+                return explain_weekly(ngettext("week", "%d weeks", interval).printf(interval));
             
             case iCal.icalrecurrencetype_frequency.MONTHLY_RECURRENCE:
-                unit = ngettext("month", "%d months", interval);
-            break;
+                Gee.Set<ByRule> active = get_active_by_rules();
+                bool has_byday = active.contains(ByRule.DAY);
+                bool has_bymonthday = active.contains(ByRule.MONTH_DAY);
+                
+                // requires one and only one
+                if (has_byday == has_bymonthday || active.size > 1)
+                    return null;
+                
+                string unit = ngettext("month", "%d months", interval).printf(interval);
+                
+                if (has_byday)
+                    return explain_monthly_byday(unit);
+                else
+                    return explain_monthly_bymonthday(unit);
             
             case iCal.icalrecurrencetype_frequency.YEARLY_RECURRENCE:
-                unit = ngettext("year", "%d years", interval);
-            break;
+                return explain_simple(ngettext("year", "%d years", interval).printf(interval));
             
             default:
                 return null;
         }
         
+    }
+    
+    private string explain_simple(string unit) {
+        if (count > 0) {
+            // As in, "Repeats every day, 2 times"
+            return _("Repeats every %s, %s").printf(units,
+                ngettext("%d time", "%d times").printf(count)
+            );
+        }
+        
+        if (until_date != null) {
+            // As in, "Repeats every week until Sept. 2, 2014"
+            return _("Repeats every %s until %s").printf(units,
+                until_date.to_pretty_string(Calendar.Date.PrettyFlag.INCLUDE_YEAR)
+            );
+        }
+        
+        if (until_exact_time != null) {
+            // As in, "Repeats every month until Sept. 2, 2014, 8:00pm"
+            return _("Repeats every %s until %s, %s").printf(units,
+                until_exact_time.to_pretty_date_string(Calendar.Date.PrettyFlag.INCLUDE_YEAR),
+                until_exact_time.to_pretty_time_string(Calendar.WallTime.PrettyFlag.NONE)
+            );
+        }
+        
+        // As in, "Repeats every day"
+        return _("Repeats every %s").printf(units);
+    }
+    
+    private string? explain_weekly(string unit) {
+        // can only explain BYDAY rules
+        Gee.Set<ByRule> active = get_active_by_rules();
+        if (!active.contains(ByRule.DAY) || active.size == 0)
+            return null;
+        
+        // Gather all the DayOfWeeks in the WEEKLY RRULE into a sorted set
+        // TODO: Need start-of-week comparator
+        Gee.TreeSet<Calendar.DayOfWeek> dows = new Gee.TreeSet<Calendar.DayOfWeek>();
+        foreach (int day in get_by_rule(ByRule.DAY)) {
+            Calendar.DayOfWeek dow;
+            if (!decode_day(day, out dow, null))
+                return null;
+            
+            dows.add(dow);
+        }
+        
+        // must be one to work
+        if (dows.size == 0)
+            return null;
+        
+        // assemble a list of days
+        StringBuilder days_of_the_week = new StringBuilder();
+        bool first = true;
+        foreach (Calendar.DayOfWeek dow in dows) {
+            if (!first) {
+                // Separator between days of the week, i.e. "Monday, Tuesday, Wednesday"
+                days_of_the_week.append(_(", "));
+            }
+            
+            days_of_the_week.append(dow.full_name);
+            first = false;
+        }
+        
         if (count > 0) {
-            return _("Repeats every %s for %s").printf(unit.printf(interval), unit.printf(count));
+            // As in, "Repeats every week on Monday, Tuesday, 3 times"
+            return _("Repeats every %s on %s, %s").printf(units, days_of_the_week.str,
+                ngettext("%d time", "%d times").printf(count)
+            );
         }
         
         if (until_date != null) {
-            return _("Repeats every %s until %s").printf(unit.printf(interval),
+            // As in, "Repeats every week on Thursday until Sept. 2, 2014"
+            return _("Repeats every %s on %s until %s").printf(units, days_of_the_week.str,
                 until_date.to_pretty_string(Calendar.Date.PrettyFlag.INCLUDE_YEAR)
             );
         }
         
         if (until_exact_time != null) {
-            return _("Repeats every %s until %s, %s").printf(unit.printf(interval),
+            // As in, "Repeats every week on Friday, Saturday until Sept. 2, 2014, 8:00pm"
+            return _("Repeats every %s on %s until %s, %s").printf(units, days_of_the_week.str,
                 until_exact_time.to_pretty_date_string(Calendar.Date.PrettyFlag.INCLUDE_YEAR),
                 until_exact_time.to_pretty_time_string(Calendar.WallTime.PrettyFlag.NONE)
             );
         }
         
-        return _("Repeats every %s").printf(unit.printf(interval));
+        // As in, "Repeats every week on Monday, Wednesday, Friday"
+        return _("Repeats every %s on %s").printf(units, days_of_the_week.str);
+    }
+    
+    private string? explain_monthly_byday(string unit) {
+    }
+    
+    private string? explain_monthly_bymonthday(string unit) {
     }
     
     public override string to_string() {


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