X-Git-Url: https://code.delx.au/comingnext/blobdiff_plain/631bc47f3e5b8f4d65a6c1f0d4d49ae7558427e2..3a8ae3ed904a6bccf63a4d694324d93e5f0a34fd:/comingNext/index.html diff --git a/comingNext/index.html b/comingNext/index.html index ad66566..459441c 100644 --- a/comingNext/index.html +++ b/comingNext/index.html @@ -67,7 +67,7 @@ var config = { // Nothing of interest from here on... //------------------------------------------------------- var panelNum = 0; // use 1 for second panel -var version = "1.26"; +var version = "1.28"; var versionURL = "http://comingnext.sourceforge.net/version.xml"; var calendarService = null; var cacheEntriesHtml = []; @@ -76,6 +76,11 @@ var orientation = ''; var now = new Date(); var mode = 0; // 0 = homescreen, 1 = fullscreen, 2 = settings, 3 = about, 4 = check for update var reqV = null; +var settingsCalEntryId = null; +var settingsCache = null; +var notificationRequest1; +var notificationRequest2; +var calendarList = []; // vars for daylight saving time var daylightsavingWinter = 0; @@ -277,9 +282,23 @@ function requestNotification() criteria.Type = "CalendarEntry"; try { - var result = calendarService.IDataSource.RequestNotification(criteria, callback); - if (result.ErrorCode) - error('loading Calendar items list'); + notificationRequest1 = calendarService.IDataSource.RequestNotification(criteria, callback); + if (notificationRequest1.ErrorCode) + error('requestNotification failed with error code ' + notificationRequest1.ErrorCode); + } catch (e) { + error("requestNotification: " + e + ', line ' + e.line); + } + + var criteria2 = new Object(); + criteria2.Type = "CalendarEntry"; + criteria2.Filter = new Object(); + criteria2.Filter.LocalIdList = new Array(); + criteria2.Filter.LocalIdList[0] = settingsCalEntryId; + + try { + notificationRequest2 = calendarService.IDataSource.RequestNotification(criteria2, settingsCallback); + if (notificationRequest2.ErrorCode) + error('requestNotification failed with error code ' + notificationRequest2.ErrorCode); } catch (e) { error("requestNotification: " + e + ', line ' + e.line); } @@ -287,9 +306,16 @@ function requestNotification() function callback(transId, eventCode, result) { + console.info("callback(): panelNum: %d transId: %d eventCode: %d result.ErrorCode: %d", panelNum, transId, eventCode, result.ErrorCode); updateData(); } +function settingsCallback(transId, eventCode, result) +{ + console.info("settingsCallback(): panelNum: %d transId: %d eventCode: %d result.ErrorCode: %d", panelNum, transId, eventCode, result.ErrorCode); + loadSettings(); +} + function parseDate(dateString) { /* @@ -433,31 +459,43 @@ function updateData() // meetings have time // 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 now = new Date(); - var meetingListFiltering = { - Type:'CalendarEntry', - Filter:{ - StartRange: (new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0)), - EndRange: (new Date(now.getFullYear(), now.getMonth() + config['monthRange'].Value, now.getDate(), 0, 0, 0)) + var meetingList = []; + for(var i=0; i < calendarList.length; i++) { + var meetingListFiltering = { + Type:'CalendarEntry', + Filter:{ + CalendarName: calendarList[i], + StartRange: (new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0)), + EndRange: (new Date(now.getFullYear(), now.getMonth() + config['monthRange'].Value, now.getDate(), 0, 0, 0)) + } } + var meetingResult = calendarService.IDataSource.GetList(meetingListFiltering); + if (meetingResult.ErrorCode != 0) + throw("Error fetching calendar data: " + meetingResult.ErrorCode + ': ' + meetingResult.ErrorMessage); + var list = meetingResult.ReturnValue; + meetingList = meetingList.concat(listToArray(list)); } - var meetingResult = calendarService.IDataSource.GetList(meetingListFiltering); - if (meetingResult.ErrorCode != 0) - throw("Error fetching calendar data: " + meetingResult.ErrorCode + ': ' + meetingResult.ErrorMessage); - var meetingList = meetingResult.ReturnValue; + meetingList.sort(sortCalendarEntries); // todos don't, they start on 00:00 hrs., but should be visible anyway // this will generate a list of passed todos. We have to check if they have been marked as "done" yet if (config['includeTodos'].Value) { - var todayTodoListFiltering = { - Type:'CalendarEntry', - Filter:{ - Type: 'ToDo', - StartRange: (new Date(now.getFullYear() - 1, now.getMonth(), now.getDate(), 0, 0, 0)), - EndRange: (new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 1)) + var todayTodoList = []; + for(var i=0; i < calendarList.length; i++) { + var todayTodoListFiltering = { + Type:'CalendarEntry', + Filter:{ + CalendarName: calendarList[i], + Type: 'ToDo', + StartRange: (new Date(now.getFullYear() - 1, now.getMonth(), now.getDate(), 0, 0, 0)), + EndRange: (new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 1)) + } } + var todayTodoResult = calendarService.IDataSource.GetList(todayTodoListFiltering); + var list = todayTodoResult.ReturnValue; + todayTodoList = todayTodoList.concat(listToArray(list)); } - var todayTodoResult = calendarService.IDataSource.GetList(todayTodoListFiltering); - var todayTodoList = todayTodoResult.ReturnValue; + todayTodoList.sort(sortCalendarEntries); var entryLists = [todayTodoList, meetingList]; } else { var entryLists = [meetingList]; @@ -472,7 +510,24 @@ function updateData() var counter = 0; var entryDate = ''; var dateArr = []; - var entriesHtml = ''; + var fontsize = 'normal'; + if (mode == 0) { + if (config['eventsPerWidget'].Value == 3) { + fontsize = '17pt'; + changeCssClass('.icon', 'width:20px; height:20px'); + } + else if (config['eventsPerWidget'].Value == 5) { + fontsize = '10pt'; + changeCssClass('.icon', 'width:10px; height:10px'); + } + else if (config['eventsPerWidget'].Value == 6) { + fontsize = '8pt'; + changeCssClass('.icon', 'width:8px; height:8px'); + } + } + else + changeCssClass('.icon', config['cssStyle_icon'].Value); + var entriesHtml = '
'; var eventIds = []; var max; if (mode == 0) @@ -482,7 +537,8 @@ function updateData() // the first outer loop iteration is for passed ToDos, the second loop is for all upcomming events (may also include ToDos) for (var i=0; counter < max && i < entryLists.length; i++) { - while (counter < max && (entry = entryLists[i].getNext()) != undefined) { + for (var j=0; (counter < max) && (j < entryLists[i].length); j++) { + entry = entryLists[i][j]; counter++; // output event info for debugging @@ -585,7 +641,7 @@ function updateData() // mark overdue todos var overdue = false; - if (entry.Type == 'ToDo') { + if (entry.Type == 'ToDo' && date != null) { var tmp1 = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0,0,0); var tmp2 = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0,0,0); if (tmp1.getTime() < tmp2.getTime()) { @@ -603,7 +659,7 @@ function updateData() var time = formatTime(date); var dateStr = formatDate(date, entryDate); if (entry.Type == 'ToDo' && overdue && config['markOverdueTodos'].Value) { - dateStr = 'Overdue'; + dateStr = '' + config['overdueText'].Value + ''; entriesHtml += '
' + dateStr + ' '; } else if (entry.Type == 'ToDo' || entry.Type == 'Anniversary' || entry.Type == 'DayEvent' || entry.Type == 'Reminder') { if ((isToday(date) || isTomorrow(date)) && config['showTodayAsText'].Value) // show weekday if the date string is not text. looks odd otherwise @@ -695,12 +751,13 @@ function init() return; } + calendarList = listCalendars(); loadSettings(); - updateCssClasses(); collectLocales(); //updateData(); requestNotification(); window.setInterval('updateData()', 1000 * 60 * config['updateDataInterval'].Value); + document.getElementById("settingsTitle").innerHTML = getLocalizedText('menu.settings'); mode = 0; showHomescreen(); @@ -773,8 +830,12 @@ function showSettings() var settingsHtml = '
'; for (var key in config) { - if (config[key].Type == 'String') - settingsHtml += '' + printHintBox(getLocalizedText('settings.info.' + key)) + '
'; + if (config[key].Type == 'String') { + var prefix = ""; + if (key.substring(0,9) == "cssStyle_") + prefix = getLocalizedText('settings.cssStyle_prefix'); + settingsHtml += '
' + getLocalizedText('settings.name.' + key) + '
' + printHintBox(getLocalizedText('settings.info.' + key)) + '
'; + } else if (config[key].Type == 'Int') settingsHtml += '
' + prefix + getLocalizedText('settings.name.' + key) + '
' + printHintBox(getLocalizedText('settings.info.' + key)) + '
'; else if (config[key].Type == 'Bool') @@ -812,6 +873,53 @@ function updateCssClasses() } } +function getSettingsCalEntryId() +{ + if (settingsCalEntryId == null) { + // check if entry already exists + var listFiltering = { + Type:'CalendarEntry', + Filter:{ + StartRange: new Date(2000, 0, 1), + EndRange: new Date(2000, 0, 1), + SearchText: 'ComingNext Settings|', + Type: 'DayEvent' + } + } + var result = calendarService.IDataSource.GetList(listFiltering); + if (result.ErrorCode) { + error(result.ErrorMessage); + return; + } + var list = result.ReturnValue; + var entry = list.getNext(); + if (entry != undefined) { + settingsCalEntryId = entry.LocalId; + console.info("settingsCalEntryId=" + settingsCalEntryId); + } + else { // create settings item + var item = new Object(); + item.Type = "DayEvent"; + item.StartTime = new Date(2000, 0, 1); + item.Summary = "ComingNext Settings|"; + + var criteria = new Object(); + criteria.Type = "CalendarEntry"; + criteria.Item = item; + + try { + var result = calendarService.IDataSource.Add(criteria); + if (result.ErrorCode) + error(result.ErrorMessage); + } catch (e) { + error("getSettingsCalEntryId: " + e + ', line ' + e.line); + } + + getSettingsCalEntryId(); + } + } +} + function restoreDefaultSettings() { for (var key in config) @@ -820,38 +928,85 @@ function restoreDefaultSettings() function loadSettings() { - for (var key in config) { - if (widget.preferenceForKey(key)) { - if (config[key].Type == 'Int') - config[key].Value = Number(widget.preferenceForKey(key)); - else if (config[key].Type == 'String') - config[key].Value = widget.preferenceForKey(key); - else if (config[key].Type == 'Bool') - config[key].Value = (widget.preferenceForKey(key) == 'true') - else if (config[key].Type == 'Enum') - config[key].Value = widget.preferenceForKey(key); - else if (config[key].Type == 'UID') - config[key].Value = Number(widget.preferenceForKey(key)); + getSettingsCalEntryId(); + var listFiltering = { + Type:'CalendarEntry', + Filter:{ + LocalId: settingsCalEntryId + } + } + var result = calendarService.IDataSource.GetList(listFiltering); + if (result.ErrorCode) { + error(result.ErrorMessage); + return; + } + var entry = result.ReturnValue.getNext(); + if (entry != undefined) { + // only reload settings if they chanced since the last reload + if (settingsCache != entry.Summary) + { + restoreDefaultSettings(); + var stringlist = entry.Summary.split("|"); + // skip the first two entries, those contain header and version info + for(var i = 2; i < stringlist.length - 1; i++) { + var pair = stringlist[i].split('='); + var key = pair[0]; + var value = pair[1]; + console.info('stringlist: ' + key + '=\'' + value + '\''); + if (config[key].Type == 'Int') + config[key].Value = Number(value); + else if (config[key].Type == 'String') + config[key].Value = value; + else if (config[key].Type == 'Bool') + config[key].Value = (value == 'true') + else if (config[key].Type == 'Enum') + config[key].Value = value; + else if (config[key].Type == 'UID') + config[key].Value = Number(value); + } + settingsCache = entry.Summary; + updateCssClasses(); } - else - config[key].Value = config[key].Default; - console.info('Settings: ' + key + '=\'' + config[key].Value + '\''); + } + else { + error("Failed to load settings, calendar entry could not be found"); } } function saveSettings() { + getSettingsCalEntryId(); + var item = new Object(); + item.Type = "DayEvent"; + item.StartTime = new Date(2000, 0, 1); + item.LocalId = settingsCalEntryId; + item.Summary = "ComingNext Settings|" + version + "|"; + for (var key in config) { if (config[key].Type == 'Int') - widget.setPreferenceForKey(config[key].Value.toString(), key); + item.Summary += key + "=" + config[key].Value.toString() + "|"; else if (config[key].Type == 'String') - widget.setPreferenceForKey(config[key].Value, key); + item.Summary += key + "=" + config[key].Value + "|"; else if (config[key].Type == 'Bool') - widget.setPreferenceForKey(config[key].Value ? 'true' : 'false', key); + item.Summary += key + "=" + (config[key].Value ? 'true' : 'false') + "|"; else if (config[key].Type == 'Enum') - widget.setPreferenceForKey(config[key].Value, key); + item.Summary += key + "=" + config[key].Value + "|"; else if (config[key].Type == 'UID') - widget.setPreferenceForKey(config[key].Value.toString(), key); + item.Summary += key + "=" + config[key].Value.toString() + "|"; + } + settingsCache = item.Summary; + + var criteria = new Object(); + criteria.Type = "CalendarEntry"; + criteria.Item = item; + + console.info("Saving settings to calendar entry: " + item.Summary); + try { + var result = calendarService.IDataSource.Add(criteria); + if (result.ErrorCode) + error(result.ErrorMessage); + } catch (e) { + error("saveSettings: " + e + ', line ' + e.line); } } @@ -1018,6 +1173,110 @@ function hideViews() document.getElementById("settingsView").style.display = "none"; document.getElementById("updateView").style.display = "none"; } + +function listCalendars() +{ + try { + var criteria = { + Type:'Calendar', + Filter:{ + DefaultCalendar: false + } + } + + var calendarsResult = calendarService.IDataSource.GetList(criteria); + if (calendarsResult.ErrorCode != 0) + throw("Error fetching list of calendars: " + calendarsResult.ErrorCode + ': ' + calendarsResult.ErrorMessage); + var calendarListIterator = calendarsResult.ReturnValue; + + var calendars = []; + var count = 0; + var item; + while (( item = calendarListIterator.getNext()) != undefined ) { + calendars[count++] = item; + } + console.info("Available Calendars: " + calendars.join(", ")); + return calendars; + } catch(e) { + error('listing calendars:' + e + ', line ' + e.line); + return null; + } +} + +function listToArray(list) +{ + var array = []; + var item; + while (( item = list.getNext()) != undefined ) { + array.push(item); + } + return array; +} + +function sortCalendarEntries(a, b) +{ + var atime, btime; + + if (a['InstanceStartTime'] != null) { + atime = a['InstanceStartTime']; + } + else if (a['StartTime'] != null) { + atime = a['StartTime']; + } + else if (a['InstanceEndTime'] != null) { + atime = a['InstanceEndTime']; + } + else if (a['EndTime'] != null) { + atime = a['EndTime']; + } + + if (b['InstanceStartTime'] != null) { + btime = b['InstanceStartTime']; + } + else if (b['StartTime'] != null) { + btime = b['StartTime']; + } + else if (b['InstanceEndTime'] != null) { + btime = b['InstanceEndTime']; + } + else if (b['EndTime'] != null) { + btime = b['EndTime']; + } + + if (atime && btime) { + + atime = parseDate(atime); + btime = parseDate(btime); + + // sort by date & time + if (atime < btime) { + return -1; + } + else if (atime > btime) { + return 1; + } + // sort by type + else if (a['Type'] != b['Type']) { + if (a['Type'] < b['Type']) { + return -1; + } + else if (a['Type'] > b['Type']) { + return 1; + } + } + // sort by description + else if (a['Summary'] && b['Summary'] && a['Summary'] != b['Summary']) { + if (a['Summary'] < b['Summary']) { + return -1; + } + else if (a['Summary'] > b['Summary']) { + return 1; + } + } + } + + return 0; +}
' + getLocalizedText('settings.name.' + key) + '