Fix bug 377041 - Sorting should put tasks without date alway at the bottom. r=philipp
authorJulius Stroffek <julo@stroffek.net>
Sun, 12 Jul 2009 14:46:00 +0200
changeset 7263 c40723287a1c084487a268bd9b146489e4124162
parent 7262 d090538194d3576c089038848bd8550413524908
child 7264 e37c8c8ae90acd5867bac9fdaea246456acb43de
push idunknown
push userunknown
push dateunknown
reviewersphilipp
bugs377041
Fix bug 377041 - Sorting should put tasks without date alway at the bottom. r=philipp
calendar/base/content/calendar-task-tree.xml
calendar/base/modules/calUtils.jsm
--- a/calendar/base/content/calendar-task-tree.xml
+++ b/calendar/base/content/calendar-task-tree.xml
@@ -303,31 +303,45 @@
           this.mShowCompletedTasks = val;
           return val;
         ]]></setter>
       </property>
       <method name="duration">
         <parameter name="aTask"/>
         <body><![CDATA[
           if (aTask && aTask.dueDate && aTask.dueDate.isValid){
-              var dur = aTask.dueDate.subtractDate(now());
+              let dur = aTask.dueDate.subtractDate(cal.now());
               if (!dur.isNegative) {
-                  var minutes = Math.ceil(dur.inSeconds / 60);
+                  let minutes = Math.ceil(dur.inSeconds / 60);
                   if (minutes >= 1440) { // 1 day or more
                       let dueIn = PluralForm.get(dur.days, calGetString("calendar", "dueInDays"));
                       return dueIn.replace("#1", dur.days);
                   } else if (minutes >= 60) { // 1 hour or more
                       let dueIn = PluralForm.get(dur.hours, calGetString("calendar", "dueInHours"));
                       return dueIn.replace("#1", dur.hours);
                   } else {
                       // Less than one hour
                       return calGetString("calendar", "dueInLessThanOneHour");
                   }
+              } else if (!aTask.completedDate || !aTask.completedDate.isValid) {
+                  // Overdue task
+                  let minutes = Math.ceil( -dur.inSeconds / 60);
+                  if (minutes >= 1440) { // 1 day or more
+                      let dueIn = PluralForm.get(dur.days, calGetString("calendar", "dueInDays"));
+                      return "-" + dueIn.replace("#1", dur.days);
+                  } else if (minutes >= 60) { // 1 hour or more
+                      let dueIn = PluralForm.get(dur.hours, calGetString("calendar", "dueInHours"));
+                      return "-" + dueIn.replace("#1", dur.hours);
+                  } else {
+                      // Less than one hour
+                      return calGetString("calendar", "dueInLessThanOneHour");
+                  }
               }
           }
+          // No due date specified
           return null;
         ]]></body>
       </method>
       <method name="getTaskAtRow">
         <parameter name="aRow"/>
         <body><![CDATA[
           return (aRow > -1 ? this.mTaskArray[aRow] : null);
         ]]></body>
--- a/calendar/base/modules/calUtils.jsm
+++ b/calendar/base/modules/calUtils.jsm
@@ -214,51 +214,88 @@ let cal = {
     // The below functions will move to some different place once the
     // unifinder tress are consolidated.
 
     compareNativeTime: function cal_compareNativeTime(a, b) {
       return (a < b ? -1 :
               a > b ?  1 : 0);
     },
 
+    compareNativeTimeFilledAsc: function cal_compareNativeTimeFilledAsc(a, b) {
+      if (a == b)
+        return 0;
+
+      // In this filter, a zero time (not set) is always at the end.
+      if (a == -62168601600000000) // value for (0000/00/00 00:00:00)
+        return 1;
+      if (b == -62168601600000000) // value for (0000/00/00 00:00:00)
+        return -1;
+
+      return (a < b ? -1 : 1);
+    },
+
+    compareNativeTimeFilledDesc: function cal_compareNativeTimeFilledDesc(a, b) {
+      if (a == b)
+        return 0;
+
+      // In this filter, a zero time (not set) is always at the end.
+      if (a == -62168601600000000) // value for (0000/00/00 00:00:00)
+        return 1;
+      if (b == -62168601600000000) // value for (0000/00/00 00:00:00)
+        return -1;
+
+      return (a < b ? 1 : -1);
+    },
+
     compareNumber: function cal_compareNumber(a, b) {
       a = Number(a);
       b = Number(b);
       return ((a < b) ? -1 :      // avoid underflow problems of subtraction
               (a > b) ?  1 : 0);
     },
 
     sortEntryComparer: function cal_sortEntryComparer(sortType, modifier) {
       switch (sortType) {
         case "number":
           function compareNumbers(sortEntryA, sortEntryB) {
-            var nsA = cal.sortEntryKey(sortEntryA);
-            var nsB = cal.sortEntryKey(sortEntryB);
+            let nsA = cal.sortEntryKey(sortEntryA);
+            let nsB = cal.sortEntryKey(sortEntryB);
             return cal.compareNumber(nsA, nsB) * modifier;
           }
           return compareNumbers;
         case "date":
           function compareTimes(sortEntryA, sortEntryB) {
-            var nsA = cal.sortEntryKey(sortEntryA);
-            var nsB = cal.sortEntryKey(sortEntryB);
+            let nsA = cal.sortEntryKey(sortEntryA);
+            let nsB = cal.sortEntryKey(sortEntryB);
             return cal.compareNativeTime(nsA, nsB) * modifier;
           }
           return compareTimes;
+        case "date_filled":
+          function compareTimesFilled(sortEntryA, sortEntryB) {
+            let nsA = cal.sortEntryKey(sortEntryA);
+            let nsB = cal.sortEntryKey(sortEntryB);
+            if (modifier == 1) {
+              return cal.compareNativeTimeFilledAsc(nsA, nsB);
+            } else {
+              return cal.compareNativeTimeFilledDesc(nsA, nsB);
+            }
+          }
+          return compareTimesFilled
         case "string":
-          var collator = cal.createLocaleCollator();
+          let collator = cal.createLocaleCollator();
           function compareStrings(sortEntryA, sortEntryB) {
-            var sA = cal.sortEntryKey(sortEntryA);
-            var sB = cal.sortEntryKey(sortEntryB);
+            let sA = cal.sortEntryKey(sortEntryA);
+            let sB = cal.sortEntryKey(sortEntryB);
             if (sA.length == 0 || sB.length == 0) {
               // sort empty values to end (so when users first sort by a
               // column, they can see and find the desired values in that
               // column without scrolling past all the empty values).
               return -(sA.length - sB.length) * modifier;
             }
-            var comparison = collator.compareString(0, sA, sB);
+            let comparison = collator.compareString(0, sA, sB);
             return comparison * modifier;
           }
           return compareStrings;
 
         default:
           function compareOther(sortEntryA, sortEntryB) {
             return 0;
           }
@@ -270,28 +307,29 @@ let cal = {
       switch(aKey) {
         case "priority":
           return aItem.priority || 5;
 
         case "title":
           return aItem.title || "";
 
         case "entryDate":
-            return cal.nativeTimeOrNow(aItem.entryDate, aStartTime);
+            return cal.nativeTime(aItem.entryDate);
+
         case "startDate":
-            return cal.nativeTimeOrNow(aItem.startDate, aStartTime);
+            return cal.nativeTime(aItem.startDate);
 
         case "dueDate":
-          return cal.nativeTimeOrNow(aItem.dueDate, aStartTime);
+          return cal.nativeTime(aItem.dueDate);
 
         case "endDate":
-          return cal.nativeTimeOrNow(aItem.endDate, aStartTime);
+          return cal.nativeTime(aItem.endDate);
+
         case "completedDate":
-                  // XXX: is this right ??
-          return cal.nativeTimeOrNow(aItem.completedDate, aStartTime);
+          return cal.nativeTime(aItem.completedDate);
 
         case "percentComplete":
           return aItem.percentComplete;
 
         case "categories":
           return aItem.getCategories({}).join(", ");
 
         case "location":
@@ -314,22 +352,23 @@ let cal = {
     getSortTypeForSortKey: function cal_getSortTypeForSortKey(aSortKey) {
       switch(aSortKey) {
         case "title":
         case "categories":
         case "location":
         case "calendar":
           return "string";
 
+        // All dates use "date_filled"
         case "completedDate":
-        case "entryDate":
-        case "dueDate":
         case "startDate":
         case "endDate":
-          return "date";
+        case "dueDate":
+        case "entryDate":
+          return "date_filled";
 
         case "priority":
         case "percentComplete":
         case "status":
           return "number";
       }
     },
 
@@ -341,19 +380,26 @@ let cal = {
         }
         var ns = calDateTime.nativeTime;
         if (ns == -62168601600000000) { // ns value for (0000/00/00 00:00:00)
             return sortStartedTime;
         }
         return ns;
     },
 
+    nativeTime: function cal_nativeTime(calDateTime) {
+        if (calDateTime == null) {
+            return -62168601600000000; // ns value for (0000/00/00 00:00:00)
+        }
+        return calDateTime.nativeTime;
+    },
+
     sortEntry: function cal_sortEntry(aItem) {
-        var key = cal.getItemSortKey(aItem, this.mSortKey, this.mSortStartedDate);
-        return {mSortKey : key, mItem: aItem};
+        let key = cal.getItemSortKey(aItem, this.mSortKey, this.mSortStartedDate);
+        return { mSortKey : key, mItem: aItem };
     },
 
     sortEntryItem: function cal_sortEntryItem(sortEntry) {
         return sortEntry.mItem;
     },
 
     sortEntryKey: function cal_sortEntryKey(sortEntry) {
         return sortEntry.mSortKey;