]> code.delx.au - comingnext/blobdiff - comingNext/index.html
added more debug output to help fixing future sorting problems
[comingnext] / comingNext / index.html
index 5321d5a386d16a0306f26bf942839abd38d743d2..9b4b815a4b2524c8a1acaaee5b912cc1ce681d98 100644 (file)
@@ -67,7 +67,7 @@ var config = {
 // Nothing of interest from here on...\r
 //-------------------------------------------------------\r
 var panelNum = 0; // use 1 for second panel\r
-var version = "1.26";\r
+var version = "1.28";\r
 var versionURL = "http://comingnext.sourceforge.net/version.xml";\r
 var calendarService = null;\r
 var cacheEntriesHtml = [];\r
@@ -80,12 +80,26 @@ var settingsCalEntryId = null;
 var settingsCache = null;\r
 var notificationRequest1;\r
 var notificationRequest2;\r
+var calendarList = [];\r
 \r
 // vars for daylight saving time\r
 var daylightsavingWinter = 0;\r
 var daylightsavingSummer = 0;\r
 var summertime = false;\r
 \r
+// this is a list of data fields a calendar event can have\r
+var entryFields = [\r
+       "id",\r
+       "Type",\r
+       "Summary",\r
+       "Location",\r
+       "Status",\r
+       "StartTime",\r
+       "EndTime",\r
+       "InstanceStartTime",\r
+       "InstanceEndTime"\r
+];\r
+\r
 window.onload = init;\r
 window.onresize = updateScreen;\r
 window.onshow = updateScreen;\r
@@ -458,31 +472,45 @@ function updateData()
                // meetings have time\r
                // note: anniveraries have a start time of 12:00am. So since we want to include them, we have to query the whole day and check if events have passed later\r
                now = new Date();\r
-               var meetingListFiltering = {\r
-                       Type:'CalendarEntry',\r
-                       Filter:{\r
-                               StartRange: (new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0)),\r
-                               EndRange: (new Date(now.getFullYear(), now.getMonth() + config['monthRange'].Value, now.getDate(), 0, 0, 0))\r
+               var meetingList = [];\r
+               for(var i=0; i < calendarList.length; i++) {\r
+                       var meetingListFiltering = {\r
+                               Type:'CalendarEntry',\r
+                               Filter:{\r
+                                       CalendarName: calendarList[i],\r
+                                       StartRange: (new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0)),\r
+                                       EndRange: (new Date(now.getFullYear(), now.getMonth() + config['monthRange'].Value, now.getDate(), 0, 0, 0))\r
+                               }\r
                        }\r
+                       var meetingResult = calendarService.IDataSource.GetList(meetingListFiltering);\r
+                       if (meetingResult.ErrorCode != 0)\r
+                               throw("Error fetching calendar data: " + meetingResult.ErrorCode + ': ' + meetingResult.ErrorMessage);\r
+                       var list = meetingResult.ReturnValue;\r
+                       meetingList = meetingList.concat(listToArray(list));\r
                }\r
-               var meetingResult = calendarService.IDataSource.GetList(meetingListFiltering);\r
-               if (meetingResult.ErrorCode != 0)\r
-                       throw("Error fetching calendar data: " + meetingResult.ErrorCode + ': ' + meetingResult.ErrorMessage);\r
-               var meetingList = meetingResult.ReturnValue;\r
+               console.info("updateData(): meetingList.sort()");\r
+               meetingList.sort(sortCalendarEntries);\r
 \r
                // todos don't, they start on 00:00 hrs., but should be visible anyway\r
                // this will generate a list of passed todos. We have to check if they have been marked as "done" yet\r
                if (config['includeTodos'].Value) {\r
-                       var todayTodoListFiltering = {\r
-                               Type:'CalendarEntry',\r
-                               Filter:{\r
-                                       Type: 'ToDo',\r
-                                       StartRange: (new Date(now.getFullYear() - 1, now.getMonth(), now.getDate(), 0, 0, 0)),\r
-                                       EndRange: (new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 1))\r
+                       var todayTodoList = [];\r
+                       for(var i=0; i < calendarList.length; i++) {\r
+                               var todayTodoListFiltering = {\r
+                                       Type:'CalendarEntry',\r
+                                       Filter:{\r
+                                               CalendarName: calendarList[i],\r
+                                               Type: 'ToDo',\r
+                                               StartRange: (new Date(now.getFullYear() - 1, now.getMonth(), now.getDate(), 0, 0, 0)),\r
+                                               EndRange: (new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 1))\r
+                                       }\r
                                }\r
+                               var todayTodoResult = calendarService.IDataSource.GetList(todayTodoListFiltering);\r
+                               var list = todayTodoResult.ReturnValue;\r
+                               todayTodoList = todayTodoList.concat(listToArray(list));\r
                        }\r
-                       var todayTodoResult = calendarService.IDataSource.GetList(todayTodoListFiltering);\r
-                       var todayTodoList = todayTodoResult.ReturnValue;\r
+                       console.info("updateData(): todayTodoList.sort()");\r
+                       todayTodoList.sort(sortCalendarEntries);\r
                        var entryLists = [todayTodoList, meetingList];\r
                } else {\r
                        var entryLists = [meetingList];\r
@@ -522,23 +550,31 @@ function updateData()
                else\r
                        max = 30; // we can display a lot more events in fullscreen mode\r
 \r
+               var listinfo = "";\r
+               for (var i=0; i < entryLists.length; i++) {\r
+                       listinfo = listinfo + " " + entryLists[i].length;\r
+                       var entrieslist = "";\r
+                       for (var j=0; j < entryLists[i].length; j++) {\r
+                               entrieslist += entryLists[i][j].Summary + ", ";\r
+                       }\r
+                       console.info("updateData(): entrieslist: " + entrieslist);\r
+               }\r
+               console.info("updateData(): inner loop, " + entryLists.length + " lists, [" + listinfo + "] entries");\r
+               \r
                // the first outer loop iteration is for passed ToDos, the second loop is for all upcomming events (may also include ToDos)\r
                for (var i=0; counter < max && i < entryLists.length; i++) {\r
-                       while (counter < max && (entry = entryLists[i].getNext()) != undefined) {\r
+                       for (var j=0; (counter < max) && (j < entryLists[i].length); j++) {\r
+                               entry = entryLists[i][j];\r
                                counter++;\r
 \r
                                // output event info for debugging\r
-                               console.info(\r
-                                       'event: Id=' + entry.id + \r
-                                       ',Type=' + entry.Type + \r
-                                       ',Summary=' + entry.Summary + \r
-                                       ',Location=' + entry.Location + \r
-                                       ',Status=' + entry.Status + \r
-                                       ',StartTime=' + entry.StartTime +\r
-                                       ',EndTime=' + entry.EndTime +\r
-                                       ',InstanceStartTime=' + entry.InstanceStartTime +\r
-                                       ',InstanceEndTime=' + entry.InstanceEndTime\r
-                               );\r
+                               var entryInfo = "event: ";\r
+                               for(var k=0; k < entryFields.length; ++k) {\r
+                                       if (entry[entryFields[k]] != undefined) {\r
+                                               entryInfo += entryFields[k] + "=" + entry[entryFields[k]] + ",";\r
+                                       }\r
+                               }\r
+                               console.info(entryInfo);\r
 \r
                                // we don't want ToDos when includeTodos == false or when they are completed\r
                                if (entry.Type == 'ToDo' && (entry.Status == "TodoCompleted" || !config['includeTodos'].Value)) {\r
@@ -737,18 +773,26 @@ function init()
                return;\r
        }\r
 \r
+       calendarList = listCalendars();\r
        loadSettings();\r
        collectLocales();\r
        //updateData();\r
        requestNotification();\r
        window.setInterval('updateData()', 1000 * 60 * config['updateDataInterval'].Value);\r
+       document.getElementById("settingsTitle").innerHTML = getLocalizedText('menu.settings');\r
 \r
-       mode = 0;\r
-       showHomescreen();\r
+       if (window.innerHeight > 91) {\r
+               mode = 0; // we're starting fullscreen, we set mode to homescreen in order to let updateScreen() do all the work for us\r
+       }\r
+       else {\r
+               mode = 1;\r
+       }\r
+       console.info("init(): updateScreen()");\r
        updateScreen();\r
        if (config['useBackgroundImage'].Value)\r
                // check for screen rotation every 1 secs\r
                window.setInterval('updateScreen()', 1000 * 1);\r
+       console.info("init(): finished...");\r
 }\r
 \r
 function createMenu()\r
@@ -814,8 +858,12 @@ function showSettings()
        \r
        var settingsHtml = '<form>';\r
        for (var key in config) {\r
-               if (config[key].Type == 'String')\r
-                       settingsHtml += '<table><tr><td>' + getLocalizedText('settings.name.' + key) + '<br /><input class="textInput" name="settings.' + key + '" type="text" value="' + config[key].Value + '" /></td>' + printHintBox(getLocalizedText('settings.info.' + key)) + '<hr />';\r
+               if (config[key].Type == 'String') {\r
+                       var prefix = "";\r
+                       if (key.substring(0,9) == "cssStyle_")\r
+                               prefix = getLocalizedText('settings.cssStyle_prefix');\r
+                       settingsHtml += '<table><tr><td>' + prefix + getLocalizedText('settings.name.' + key) + '<br /><input class="textInput" name="settings.' + key + '" type="text" value="' + config[key].Value + '" /></td>' + printHintBox(getLocalizedText('settings.info.' + key)) + '<hr />';\r
+               }\r
                else if (config[key].Type == 'Int')\r
                        settingsHtml += '<table><tr><td>' + getLocalizedText('settings.name.' + key) + '<br /><input class="textInput" name="settings.' + key + '" type="text" value="' + config[key].Value + '" /></td>' + printHintBox(getLocalizedText('settings.info.' + key)) + '<hr />';\r
                else if (config[key].Type == 'Bool')\r
@@ -922,6 +970,7 @@ function loadSettings()
        }\r
        var entry = result.ReturnValue.getNext();\r
        if (entry != undefined) {\r
+               console.info("Loading Settings...");\r
                // only reload settings if they chanced since the last reload\r
                if (settingsCache != entry.Summary)\r
                {\r
@@ -947,6 +996,9 @@ function loadSettings()
                        settingsCache = entry.Summary;\r
                        updateCssClasses();\r
                }\r
+               else {\r
+                       console.info("Settings already cached and did not change");\r
+               }\r
        }\r
        else {\r
                error("Failed to load settings, calendar entry could not be found");\r
@@ -1030,6 +1082,7 @@ function updateFullscreen()
 \r
 function showFullscreen()\r
 {\r
+       console.info("showFullscreen()");\r
        hideViews();\r
        document.getElementById("fullscreenView").style.display = "block";\r
        document.getElementById('body').className = "backgroundFullscreen";\r
@@ -1074,6 +1127,7 @@ function updateHomescreen()
 \r
 function showHomescreen()\r
 {\r
+       console.info("showHomescreen()");\r
        hideViews();\r
        document.getElementById("homescreenView").style.display = "block";\r
        document.getElementById('body').className = "background";\r
@@ -1153,6 +1207,119 @@ function hideViews()
        document.getElementById("settingsView").style.display = "none";\r
        document.getElementById("updateView").style.display = "none";\r
 }\r
+\r
+function listCalendars()\r
+{\r
+       try {\r
+               var criteria = {\r
+                       Type:'Calendar', \r
+                       Filter:{\r
+                               DefaultCalendar: false\r
+                       }\r
+               }\r
+               \r
+               var calendarsResult = calendarService.IDataSource.GetList(criteria);\r
+               if (calendarsResult.ErrorCode != 0)\r
+                       throw("Error fetching list of calendars: " + calendarsResult.ErrorCode + ': ' + calendarsResult.ErrorMessage);\r
+               var calendarListIterator = calendarsResult.ReturnValue;\r
+               \r
+               var calendars = [];\r
+               var count = 0;\r
+               var item;\r
+               while (( item = calendarListIterator.getNext()) != undefined ) {\r
+                       calendars[count++] = item;\r
+               }\r
+               console.info("Available Calendars: " + calendars.join(", "));\r
+               return calendars;\r
+       } catch(e) {\r
+               error('listing calendars:' + e + ', line ' + e.line);\r
+               return null;\r
+       }\r
+}\r
+\r
+// Copies all objects and their properties to an array. Data is copied so nothing gets lost when the reference is removed\r
+function listToArray(list)\r
+{\r
+       var array = new Array();\r
+       var item;\r
+       var txt = "";\r
+       while (( item = list.getNext()) != undefined ) {\r
+               var itemCopy = new Object();\r
+               for(var i=0; i < entryFields.length; i++) {\r
+                       itemCopy[entryFields[i]] = item[entryFields[i]];\r
+               }\r
+               array.push(itemCopy);\r
+               txt += array[array.length - 1].Summary + ", ";\r
+       }\r
+       console.info("listToArray(): " + txt);\r
+       return array;\r
+}\r
+\r
+function sortCalendarEntries(a, b)\r
+{\r
+       var atime, btime;\r
+       console.info("sortCalendarEntries(" + a.Summary + "," + b.Summary + ")");\r
+       \r
+       if (a.InstanceStartTime != null) {\r
+               atime = a.InstanceStartTime;\r
+       }\r
+       else if (a.StartTime != null) {\r
+               atime = a.StartTime;\r
+       }\r
+       else if (a.InstanceEndTime != null) {\r
+               atime = a.InstanceEndTime;\r
+       }\r
+       else if (a.EndTime != null) {\r
+               atime = a.EndTime;\r
+       }\r
+       \r
+       if (b.InstanceStartTime != null) {\r
+               btime = b.InstanceStartTime;\r
+       }\r
+       else if (b.StartTime != null) {\r
+               btime = b.StartTime;\r
+       }\r
+       else if (b.InstanceEndTime != null) {\r
+               btime = b.InstanceEndTime;\r
+       }\r
+       else if (b.EndTime != null) {\r
+               btime = b.EndTime;\r
+       }\r
+       \r
+       if (atime && btime) {\r
+       \r
+               atime = parseDate(atime);\r
+               btime = parseDate(btime);\r
+       \r
+               // sort by date & time\r
+               if (atime < btime) {\r
+                       return -1;\r
+               }\r
+               else if (atime > btime) {\r
+                       return 1;\r
+               }\r
+               // sort by type\r
+               else if (a.Type != b.Type) {\r
+                       if (a.Type < b.Type) {\r
+                               return -1;\r
+                       }\r
+                       else if (a.Type > b.Type) {\r
+                               return 1;\r
+                       }\r
+               }\r
+               // sort by description\r
+               else if (a.Summary && b.Summary && a.Summary != b.Summary) {\r
+                       if (a.Summary < b.Summary) {\r
+                               return -1;\r
+                       }\r
+                       else if (a.Summary > b.Summary) {\r
+                               return 1;\r
+                       }\r
+               }\r
+       }\r
+\r
+       return 0;\r
+}\r
 </script>\r
 \r
 <style type="text/css">\r
@@ -1184,7 +1351,7 @@ hr { color:#ffffff; background-color:#ffffff; height:1px; text-align:left; borde
 </div>\r
 <div id="settingsView" style="display:none">\r
        <img src="Icon.png" id="smallappicon">\r
-       <h1 class="title">Settings</h1>\r
+       <h1 id="settingsTitle" class="title">Settings</h1>\r
        <hr />\r
        <div id="settingsList"></div>\r
 </div>\r
@@ -1196,8 +1363,9 @@ hr { color:#ffffff; background-color:#ffffff; height:1px; text-align:left; borde
        <p>Contributions:</p>\r
                <p class="credits">Paul Moore (bug fixes, new features and code cleanup)</p>\r
                <p class="credits">Manfred Hanselmann (DST support)</p>\r
-               <p class="credits">Christophe Milsent (translation support & french translation</p>\r
-               <p class="credits">Flavio Nathan (portuguese-brazilian translation</p>\r
+               <p class="credits">Christophe Milsent (translation support & french translation)</p>\r
+               <p class="credits">Flavio Nathan (portuguese-brazilian translation)</p>\r
+               <p class="credits">Tokeda (russian translation)</p>\r
        <p>This software is open source and licensed under the GPLv3.</p>\r
        <p>Visit sourceforge.net/projects/comingnext for free updates.</p>\r
        <hr />\r