1 <?xml version=
"1.0" encoding=
"UTF-8"?>
2 <!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3 <html xmlns=
"http://www.w3.org/1999/xhtml">
6 <title>Coming Next
</title>
8 <style type=
"text/css">
9 /* The following classes can be modified by widget settings */
11 .backgroundFullscreen { }
22 <script type=
"text/javascript" src=
"localizedTextStrings.js" charset=
"utf-8" />
25 // valid types for the config object are 'Int', 'Bool', 'String', 'Enum', 'UID'
27 monthRange: { Type: 'Int', Default:
2, Value:
2,},
28 includeTodos: { Type: 'Bool', Default: true, Value: true,},
29 useBackgroundImage: { Type: 'Bool', Default: true, Value: true,},
30 showCombinedDateTime: { Type: 'Bool', Default: false, Value: false,},
31 showLocation: { Type: 'Bool', Default: true, Value: true,},
32 showTodayAsText: { Type: 'Bool', Default: true, Value: true,},
33 todayText: { Type: 'String', Default: getLocalizedText('settings.default.todayText'), Value: getLocalizedText('settings.default.todayText'),},
34 tomorrowText: { Type: 'String', Default: getLocalizedText('settings.default.tomorrowText'), Value: getLocalizedText('settings.default.tomorrowText'),},
35 showNowAsText: { Type: 'Bool', Default: true, Value: true,},
36 nowText: { Type: 'String', Default: getLocalizedText('settings.default.nowText'), Value: getLocalizedText('settings.default.nowText'),},
37 dateSeparator: { Type: 'String', Default: getLocalizedText('settings.default.dateSeparator'), Value: getLocalizedText('settings.default.dateSeparator'),},
38 dateFormat: { Type: 'Enum', Default: 'auto', Value: 'auto', ValidValues: ['auto', 'DDMM', 'MMDD'],},
39 weekDayLength: { Type: 'Int', Default:
2, Value:
2,},
40 updateDataInterval: { Type: 'Int', Default:
5, Value:
5,},
41 calendarApp: { Type: 'UID', Default:
0x10005901, Value:
0x10005901,},
42 eventsPerWidget: { Type: 'Int', Default:
4, Value:
4,},
43 showNothingText: { Type: 'Bool', Default: true, Value: true,},
44 nothingText: { Type: 'String', Default: getLocalizedText('settings.default.nothingText'), Value: getLocalizedText('settings.default.nothingText'),},
45 enableDaylightSaving: { Type: 'Bool', Default: true, Value: true,},
46 hideWidgetOnCalendarOpen: { Type: 'Bool', Default: false, Value: false,},
47 cssStyle_background: { Type: 'String', Default: 'color:#ffffff; background-color:#
000000', Value: 'color:#ffffff; background-color:#
000000',},
48 cssStyle_backgroundFullscreen: { Type: 'String', Default: 'color:#ffffff; background-color:#
000000', Value: 'color:#ffffff; background-color:#
000000',},
49 cssStyle_weekDay: { Type: 'String', Default: '', Value: '',},
50 cssStyle_date: { Type: 'String', Default: '', Value: '',},
51 cssStyle_today: { Type: 'String', Default: 'color:#ff0000', Value: 'color:#ff0000',},
52 cssStyle_tomorrow: { Type: 'String', Default: 'color:#
0000ff', Value: 'color:#
0000ff',},
53 cssStyle_time: { Type: 'String', Default: '', Value: '',},
54 cssStyle_now: { Type: 'String', Default: 'color:#ff00ff', Value: 'color:#ff00ff',},
55 cssStyle_description: { Type: 'String', Default: '', Value: '',},
56 cssStyle_icon: { Type: 'String', Default: 'width:
15px; height:
15px', Value: 'width:
15px; height:
15px',},
60 //-------------------------------------------------------
61 // Nothing of interest from here on...
62 //-------------------------------------------------------
63 var panelNum =
1; // use
1 for second panel
65 var calendarService = null;
66 var cacheEntriesHtml = [];
67 var months_translated = [];
70 var mode =
0; //
0 = homescreen,
1 = fullscreen,
2 = settings,
3 = about
72 // vars for daylight saving time
73 var daylightsavingWinter =
0;
74 var daylightsavingSummer =
0;
75 var summertime = false;
78 window.onresize = updateScreen;
79 window.onshow = updateScreen;
81 function isLeapYear( year ) {
82 if (( year %
4 ==
0 && year %
100 !=
0 ) || year %
400 ==
0 )
88 function calcLeapYear(year, days)
96 function subToSunday(myDate, year, days, prevMonthDays)
98 for (i = myDate.getDay(); i
> 0 ;i--)
100 days -= prevMonthDays;
101 days = isLeapYear(year) ? --days : days;
105 function calcDaylightSaving()
107 var thisYearS = new Date(now.getFullYear(),
3,
0,
0,
0,
0 );
108 var thisYearW = new Date(now.getFullYear(),
10,
0,
0,
0,
0 );
109 var nextYearS = new Date(now.getFullYear() +
1,
3,
0,
0,
0,
0 );
110 var nextYearW = new Date(now.getFullYear() +
1,
10,
0,
0,
0,
0 );
114 thisYearSDays = nextYearSDays =
90;
115 thisYearWDays = nextYearWDays =
304;
117 thisYearSDays = calcLeapYear(now.getFullYear(), thisYearSDays);
118 thisYearWDays = calcLeapYear(now.getFullYear(), thisYearWDays);
119 nextYearSDays = calcLeapYear(now.getFullYear() +
1, nextYearSDays);
120 nextYearWDays = calcLeapYear(now.getFullYear() +
1, nextYearWDays);
122 thisYearSDays = subToSunday(thisYearS, now.getFullYear(), thisYearSDays,
59);
123 thisYearWDays = subToSunday(thisYearW, now.getFullYear(), thisYearWDays,
273);
124 nextYearSDays = subToSunday(nextYearS, now.getFullYear() +
1, nextYearSDays,
59);
125 nextYearWDays = subToSunday(nextYearW, now.getFullYear() +
1, nextYearWDays,
273);
127 daylightsavingSummer = new Date (now.getFullYear(),
03-
1, thisYearSDays,
2,
0,
0);
128 daylightsavingWinter = new Date (now.getFullYear(),
10-
1, thisYearWDays,
2,
0,
0);
129 if (daylightsavingSummer < now) {
130 daylightsavingSummer = new Date (now.getFullYear()+
1,
03-
1, nextYearSDays,
2,
0,
0);
133 if (daylightsavingWinter < now) {
134 daylightsavingWinter = new Date (now.getFullYear()+
1,
10-
1, nextYearWDays,
2,
0,
0);
137 if (summer && !winter)
143 function error(message)
145 console.info('Error: ' + message);
146 document.getElementById(
"calendarList").innerHTML = 'Error: ' + message;
149 function isToday(date)
151 if (date.getDate() == now.getDate() && date.getMonth() == now.getMonth())
156 function isTomorrow(date)
158 if ((date.getDate() == now.getDate() +
1 && date.getMonth() == now.getMonth()) ||
159 (date.getDate() ==
0 && date.getMonth() == now.getMonth() +
1) ||
160 (date.getDate() ==
0 && date.getMonth() == now.getMonth() +
1 && date.getYear() == now.getYear() +
1))
165 function collectLocales()
167 var tmpyear = ((panelNum ==
0) ?
2000 :
2001);
170 if (months_translated.length
> 0)
172 for (month =
0; month <
12; month++) {
173 var startDate = new Date(tmpyear, month,
15);
175 var item = new Object();
176 item.Type =
"DayEvent";
177 item.StartTime = startDate;
178 item.Summary =
"__temp" + month;
180 var criteria = new Object();
181 criteria.Type =
"CalendarEntry";
182 criteria.Item = item;
185 var result = calendarService.IDataSource.Add(criteria);
186 if (result.ErrorCode)
187 error(result.ErrorMessage);
189 error(
"collectLocales: " + e + ', line ' + e.line);
193 var startTime = new Date(tmpyear,
0,
1);
194 var endTime = new Date(tmpyear,
11,
31);
195 var listFiltering = {
196 Type:'CalendarEntry',
198 StartRange: startTime,
200 SearchText: '__temp',
204 var result = calendarService.IDataSource.GetList(listFiltering);
205 if (result.ErrorCode) {
206 error(result.ErrorMessage);
209 var list = result.ReturnValue;
211 error(e + ', line ' + e.line);
214 var ids = new Array();
220 while (list && (entry = list.getNext()) != undefined) {
221 dateArr = entry.StartTime.replace(/,/g,'').replace(/\./g,':').replace(/ /g,' ').split(' ');
222 var day = dateArr[
1];
223 var month = dateArr[
2];
224 var year = dateArr[
3];
226 // make sure month is set properly
227 if (isNaN(parseInt(day))) {
231 } else if (isNaN(parseInt(year))) {
237 console.info(entry.StartTime + ' -
> ' + month + ' ' + counter);
238 ids[counter] = entry.id;
239 months_translated[month] = counter +
1;
243 error(e + ', line ' + e.line);
248 var criteria = new Object();
249 criteria.Type =
"CalendarEntry";
254 var result = calendarService.IDataSource.Delete(criteria);
255 if (result.ErrorCode)
256 error(result.ErrorMessage);
258 error('deleting temp calendar entries:' + e + ', line ' + e.line);
263 function requestNotification()
265 var criteria = new Object();
266 criteria.Type =
"CalendarEntry";
269 var result = calendarService.IDataSource.RequestNotification(criteria, callback);
270 if (result.ErrorCode)
271 error('loading Calendar items list');
273 error(
"requestNotification: " + e + ', line ' + e.line);
277 function callback(transId, eventCode, result)
282 function parseDate(dateString)
285 Dates my look very differently. Also keep in mind that the names are localized!!! These are the possibilities depending on the users date format setting:
286 Wednesday,
26 August,
2009 24:
00:
00
287 Wednesday,
26 August,
2009 12:
00:
00 am
288 Wednesday, August
26,
2009 12:
00:
00 am
289 Wednesday,
2009 August,
26 12:
00:
00 am
290 Wednesday,
2009 August,
28 8.00.00 pm
291 Wednesday,
2009 August,
28 08:
00:
00 PM
294 if (dateString ==
"" || dateString == null)
296 var dateArr = dateString.replace(/,/g,'').replace(/\./g,':').replace(/ /g,' ').split(' ');
297 if (dateArr.length !=
5 && dateArr.length !=
6)
301 var weekDay = dateArr[
0];
302 var day = dateArr[
1];
303 var month = dateArr[
2];
304 var year = dateArr[
3];
305 // make sure month is set properly
306 if (isNaN(parseInt(day))) {
310 } else if (isNaN(parseInt(year))) {
315 // make sure day and year are set properly
316 if (Number(day)
> Number(year)) {
321 month = months_translated[month];
324 var timeArr = dateArr[
4].split(':');
325 if (timeArr.length !=
3)
327 var hours = Number(timeArr[
0]);
328 var minutes = Number(timeArr[
1]);
329 var seconds = Number(timeArr[
2]);
330 if (dateArr.length ==
6 && dateArr[
5].toLowerCase() == 'pm' && hours <
12)
332 if (dateArr.length ==
6 && dateArr[
5].toLowerCase() == 'am' && hours ==
12)
335 console.info('year=' + year + ' month=' + month + ' day=' + day + ' hours=' + hours + ' minutes=' + minutes+ ' seconds=' + seconds);
337 // take care of daylight saving time
338 if (config['enableDaylightSaving'].Value) {
339 var date = new Date(year, month -
1, day, hours, minutes, seconds);
340 if (summertime && date
> daylightsavingWinter && date < daylightsavingSummer)
342 else if (!summertime && date
> daylightsavingSummer && date < daylightsavingWinter)
346 return new Date(year, month -
1, day, hours, minutes, seconds);
349 // returns a short date as string (
"31.12" or
"12.31") based on the format string which should look like
"Wednesday, 26 August, 2009 12:00:00 am"
350 function formatDate(date, format)
352 var day = date.getDate().toString();
353 var month = (date.getMonth() +
1).toString();
354 while (day.length <
2) { day = '
0' + day; }
355 while (month.length <
2) { month = '
0' + month; }
357 if (config['showTodayAsText'].Value && isToday(date))
358 return '
<span class=
"today">' + config['todayText'].Value + '
</span>';
359 if (config['showTodayAsText'].Value && isTomorrow(date))
360 return '
<span class=
"tomorrow">' + config['tomorrowText'].Value + '
</span>';
362 var dateArr = format.replace(/,/g,'').replace(/\./g,':').replace(/ /g,' ').split(' ');
363 if (dateArr.length !=
5 && dateArr.length !=
6) {
364 // we don't know how to format this
365 if (config['dateFormat'].Value == 'auto' || config['dateFormat'].Value == 'DDMM')
366 return day + config['dateSeparator'].Value + month;
368 return month + config['dateSeparator'].Value + day;
372 if (config['dateFormat'].Value == 'MMDD')
374 else if (config['dateFormat'].Value == 'DDMM')
377 // config['dateFormat'].Value == 'auto', try to detect system setting
379 var day_ = dateArr[
1];
380 var month_ = dateArr[
2];
381 var year_ = dateArr[
3];
382 // make sure month is set properly
383 if (isNaN(parseInt(day_))) {
388 } else if (isNaN(parseInt(year_))) {
394 // make sure day and year are set properly
395 if (Number(day_)
> Number(year_))
400 return day + config['dateSeparator'].Value + month;
402 return month + config['dateSeparator'].Value + day;
405 function formatTime(date)
407 // date is a Date() object
408 date.setSeconds(
0); // we don't care about seconds
409 var time = date.toLocaleTimeString().replace(/[\.:]
00/, ''); // remove seconds from string
410 if (time.replace(/\./, ':').split(':')[
0].length <
2)
412 if (config['showNowAsText'].Value && date.getTime() == now.getTime())
413 time = '
<span class=
"now">' + config['nowText'].Value + '
</span>';
417 function updateData()
419 console.info('updateData()');
420 calcDaylightSaving();
422 // meetings have time
423 // 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
425 var meetingListFiltering = {
426 Type:'CalendarEntry',
428 StartRange: (new Date(now.getFullYear(), now.getMonth(), now.getDate(),
0,
0,
0)),
429 EndRange: (new Date(now.getFullYear(), now.getMonth() + config['monthRange'].Value, now.getDate(),
0,
0,
0))
432 var meetingResult = calendarService.IDataSource.GetList(meetingListFiltering);
433 if (meetingResult.ErrorCode !=
0)
434 throw(
"Error fetching calendar data: " + meetingResult.ErrorCode + ': ' + meetingResult.ErrorMessage);
435 var meetingList = meetingResult.ReturnValue;
437 // todos don't, they start on
00:
00 hrs., but should be visible anyway
438 // this will generate a list of passed todos. We have to check if they have been marked as
"done" yet
439 if (config['includeTodos'].Value) {
440 var todayTodoListFiltering = {
441 Type:'CalendarEntry',
444 StartRange: (new Date(now.getFullYear() -
1, now.getMonth(), now.getDate(),
0,
0,
0)),
445 EndRange: (new Date(now.getFullYear(), now.getMonth(), now.getDate(),
0,
0,
1))
448 var todayTodoResult = calendarService.IDataSource.GetList(todayTodoListFiltering);
449 var todayTodoList = todayTodoResult.ReturnValue;
450 var entryLists = [todayTodoList, meetingList];
452 var entryLists = [meetingList];
455 error('loading Calendar items list:' + e + ', line ' + e.line);
464 var entriesHtml = '
<table>';
468 max = ((panelNum ==
0) ? config['eventsPerWidget'].Value :
2 * config['eventsPerWidget'].Value);
470 max =
30; // we can display a lot more events in fullscreen mode
472 // the first outer loop iteration is for passed ToDos, the second loop is for all upcomming events (may also include ToDos)
473 for (var i=
0; counter < max && i < entryLists.length; i++) {
474 while (counter < max && (entry = entryLists[i].getNext()) != undefined) {
477 // output event info for debugging
479 'event: Id=' + entry.id +
480 ',Type=' + entry.Type +
481 ',Summary=' + entry.Summary +
482 ',Location=' + entry.Location +
483 ',Status=' + entry.Status +
484 ',StartTime=' + entry.StartTime +
485 ',EndTime=' + entry.EndTime +
486 ',InstanceStartTime=' + entry.InstanceStartTime +
487 ',InstanceEndTime=' + entry.InstanceEndTime
490 // we don't want ToDos when includeTodos == false or when they are completed
491 if (entry.Type == 'ToDo' && (entry.Status ==
"TodoCompleted" || !config['includeTodos'].Value)) {
492 console.info('skipping ' + entry.id );
497 // make sure that we don't include an event twice (useful for ToDos that might come up twice)
498 if (eventIds[entry.id] ==
1 && entry.Type == 'ToDo') {
499 console.info('skipped (already included) ' + entry.id);
503 eventIds[entry.id] =
1;
505 // summary can be undefined!
506 var Summary = ((entry.Summary == null) ? '' : entry.Summary);
507 if (entry.Type == 'Meeting' && entry.Location != '' && config['showLocation'].Value)
508 Summary += ', ' + entry.Location;
510 // fix by yves: determine start and end dates/times
511 entryStartTime = ((entry.InstanceStartTime == null) ? entry.StartTime : entry.InstanceStartTime);
512 entryEndTime = ((entry.InstanceEndTime == null) ? entry.EndTime : entry.InstanceEndTime);
514 // there can be ToDos that have no date at all!
515 if (entry.Type == 'ToDo' && entry.EndTime == null)
516 entryDate =
""; // this will cause parseDate(entryDate) to return null;
518 entryDate = ((entry.Type == 'ToDo') ? entryEndTime : entryStartTime); // ToDo's use their EndTime, the rest use StartTime
520 // Convert date/time string to Date object
521 var date = parseDate(entryDate);
522 console.info('date: ' + date);
523 var endDate = ((entryEndTime == null) ? null : parseDate(entryEndTime));
524 console.info('endDate: ' + endDate);
526 // check if meeting event has already passed
527 if (entry.Type == 'Meeting') {
528 var compareTime = ((endDate == null) ? date.getTime() : endDate.getTime());
529 if (now.getTime()
> compareTime) {
530 console.info('skipping Meeting (already passed) ' + entry.id);
532 eventIds[entry.id] =
0;
537 // check if anniversary passed (not sure why they are in the list, the query was only for today - nokia?)
538 if (entry.Type == 'Anniversary') {
539 var tmp = new Date(now.getFullYear(), now.getMonth(), now.getDate(),
0,
0,
0);
540 if (date.getTime() < tmp.getTime()) {
541 console.info('skipping Anniversary (already passed) ' + entry.id);
543 eventIds[entry.id] =
0;
548 // fix DayEvents end time. End times are off by
1 Second. It's possible that the event has already passed
549 if (entry.Type == 'DayEvent' && endDate != null) {
550 endDate.setMinutes(endDate.getMinutes() -
1);
551 console.info('fixing DayEvent endDate: ' + endDate);
552 if (now.getTime()
> endDate.getTime()) {
553 console.info('event already passed ' + entry.id);
555 eventIds[entry.id] =
0;
560 // check if the event is currently taking place
561 if (entryStartTime != null && entryEndTime != null && date != null && endDate != null) {
562 // check if we are between start and endtime
563 if ((date.getTime() < now.getTime()) && (now.getTime() < endDate.getTime())) {
564 date = now; // change appointment date/time to now
565 console.info('event is currently taking place: ' + date);
569 // skip events for the first panel in case this is the second one and we're not in fullscreen mode
570 if (mode ==
0 && panelNum ==
1 && counter < config['eventsPerWidget'].Value +
1) {
571 console.info('skipping (already in first widget) ' + entry.id);
575 // generate html output
576 entriesHtml += '
<tr><td><img class=
"icon" src=
"' + entry.Type + '.png" /></td>';
578 // some languages have very strange locale date formats, can't parse all those. Also some todos don't have dates at all.
579 entriesHtml += '
<td colspan=
"4"><span class=
"date">' + entryDate + '
</span> ';
581 var weekDay = date.toLocaleDateString().substr(
0,config['weekDayLength'].Value);
582 var time = formatTime(date);
583 var dateStr = formatDate(date, entryDate);
584 if (entry.Type == 'ToDo' || entry.Type == 'Anniversary' || entry.Type == 'DayEvent' || entry.Type == 'Reminder') {
585 if ((isToday(date) || isTomorrow(date)) && config['showTodayAsText'].Value) // show weekday if the date string is not text. looks odd otherwise
586 entriesHtml += '
<td colspan=
"4" width=
"1px"><span class=
"date">' + dateStr + '
</span> ';
588 entriesHtml += '
<td class=
"weekDay" width=
"1px">' + weekDay + '
</td><td width=
"1px" class=
"date">' + dateStr + '
</td><td colspan=
"2">';
589 } else if (entry.Type == 'Meeting') {
590 if (config['showCombinedDateTime'].Value) {
592 entriesHtml += '
<td width=
"1px" colspan=
"4"><span class=
"today">' + time + '
</span> ';
593 else if (isTomorrow(date))
594 entriesHtml += '
<td width=
"1px" colspan=
"4"><span class=
"tomorrow">' + dateStr + '
</span> <span class=
"time">' + time + '
</span> ';
596 entriesHtml += '
<td width=
"1px" class=
"weekDay">' + weekDay + '
</td><td width=
"1px" class=
"date">' + dateStr + '
</td><td colspan=
"2">';
598 if ((isToday(date) || isTomorrow(date)) && config['showTodayAsText'].Value)
599 entriesHtml += '
<td colspan=
"4" width=
"1px"><span class=
"today">' + dateStr + '
</span> <span class=
"time">' + time + '
</span> ';
601 entriesHtml += '
<td width=
"1px" class=
"weekDay">' + weekDay + '
</td><td width=
"1px" class=
"date">' + dateStr + '
</td><td width=
"1px" class=
"time">' + time + '
</td><td>';
605 entriesHtml += '
<span class=
"description">' + Summary + '
</span></td></tr>';
608 entriesHtml += '
</table>';
609 if (config['showNothingText'].Value && entriesHtml == '
<table></table>') {
610 var text = config['nothingText'].Value.replace(/%d/, config['monthRange'].Value);
611 entriesHtml = '
<div style=
"width:295px; height:75px; text-align:center; line-height:75px; overflow:visible;">' + text + '
</div>';
613 if (cacheEntriesHtml != entriesHtml) {
615 document.getElementById('calendarList').innerHTML = entriesHtml;
617 document.getElementById('fullscreenCalendarList').innerHTML = entriesHtml;
618 cacheEntriesHtml = entriesHtml;
621 error('displaying list:' + e + ', line ' + e.line);
626 function updateScreen()
628 // check if opening fullscreen
629 if( window.innerHeight
> 91 && mode ==
0) {
631 cacheEntriesHtml = '';
632 document.getElementById('body').style.backgroundImage =
"";
635 else if (window.innerHeight <=
91 && mode !=
0) {
637 cacheEntriesHtml = '';
647 function launchCalendar()
650 widget.openApplication(config['calendarApp'].Value,
"");
651 if (config['hideWidgetOnCalendarOpen'].Value)
654 error('starting Calendar App');
661 console.info('New widget instance starting up...');
664 // call calendar service
665 calendarService = device.getServiceObject(
"Service.Calendar",
"IDataSource");
667 error('loading Calendar service: ' + e + ', line ' + e.line);
675 requestNotification();
676 window.setInterval('updateData()',
1000 *
60 * config['updateDataInterval'].Value);
681 if (config['useBackgroundImage'].Value)
682 // check for screen rotation every
1 secs
683 window.setInterval('updateScreen()',
1000 *
1);
686 function createMenu()
688 window.menu.setLeftSoftkeyLabel(
"",null);
689 window.menu.setRightSoftkeyLabel(
"",null);
691 var menuSettings = new MenuItem(getLocalizedText('menu.settings'), id++);
692 var menuCallApp = new MenuItem(getLocalizedText('menu.openCalendarApp'), id++);
693 var menuAbout = new MenuItem(getLocalizedText('menu.about'), id++);
694 menuSettings.onSelect = showSettings;
695 menuAbout.onSelect = showAbout;
696 menuCallApp.onSelect = launchCalendar;
698 window.menu.append(menuCallApp);
699 window.menu.append(menuSettings);
700 window.menu.append(menuAbout);
703 function showSettings()
706 document.getElementById(
"homescreenView").style.display =
"none";
707 document.getElementById(
"fullscreenView").style.display =
"none";
708 document.getElementById(
"aboutView").style.display =
"none";
709 document.getElementById(
"settingsView").style.display =
"block";
710 document.onclick = null;
712 window.menu.setLeftSoftkeyLabel(getLocalizedText('settings.save'), function()
714 for (var key in config) {
715 if (config[key].Type == 'String')
716 config[key].Value = document.forms[
0].elements[
"settings." + key].value;
717 else if (config[key].Type == 'Int') {
718 config[key].Value = parseInt(document.forms[
0].elements[
"settings." + key].value);
719 if (config[key].Value <
0)
720 config[key].Value = config[key].Default;
722 else if (config[key].Type == 'Bool')
723 config[key].Value = document.forms[
0].elements[
"settings." + key].checked;
724 else if (config[key].Type == 'UID')
725 config[key].Value = parseInt(document.forms[
0].elements[
"settings." + key].value);
726 else if (config[key].Type == 'Enum') {
727 config[key].Value = document.forms[
0].elements[
"settings." + key].value;
728 if (config[key].ValidValues.indexOf(config[key].Value) == -
1)
729 config[key].Value = config[key].Default;
740 window.menu.setRightSoftkeyLabel(getLocalizedText('settings.cancel'), function()
746 var settingsHtml = '
<form>';
747 for (var key in config) {
748 if (config[key].Type == 'String')
749 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 />';
750 else if (config[key].Type == 'Int')
751 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 />';
752 else if (config[key].Type == 'Bool')
753 settingsHtml += '
<table><tr><td>' + getLocalizedText('settings.name.' + key) + '
<br /><input name=
"settings.' + key + '" type=
"checkbox" value=
"true" ' + (config[key].Value ? '
checked=
"checked"' : '') + '
/></td>' + printHintBox(getLocalizedText('settings.info.' + key)) + '
<hr />';
754 else if (config[key].Type == 'UID')
755 settingsHtml += '
<table><tr><td>' + getLocalizedText('settings.name.' + key) + '
<br /><input class=
"textInput" name=
"settings.' + key + '" type=
"text" value=
"0x' + config[key].Value.toString(16) + '" /></td>' + printHintBox(getLocalizedText('settings.info.' + key)) + '
<hr />';
756 else if (config[key].Type == 'Enum') {
757 settingsHtml += '
<table><tr><td>' + getLocalizedText('settings.name.' + key) + '
<br /><select name=
"settings.' + key + '" size=
"1">';
758 for(var i =
0; i < config[key].ValidValues.length; i++)
759 settingsHtml += '
<option label=
"' + config[key].ValidValues[i] + '"' + (config[key].Value == config[key].ValidValues[i] ? '
selected=
"selected"' : '') + '
>' + config[key].ValidValues[i] + '
</option>';
760 settingsHtml += '
</select></div></td>' + printHintBox(getLocalizedText('settings.info.' + key)) + '
<hr />';
763 settingsHtml += '
<input name=
"reset" type=
"button" value=
"' + getLocalizedText('settings.restoreDefaults') + '" onclick=
"javascript:restoreDefaultSettings();showSettings();" />';
764 settingsHtml += '
</form>';
765 document.getElementById(
"settingsList").innerHTML = settingsHtml;
768 function changeCssClass(classname, properties)
770 for(var i =
0; i < document.styleSheets[
0]['cssRules'].length; i++)
772 if (document.styleSheets[
0]['cssRules'][i].selectorText == classname) {
773 document.styleSheets[
0].deleteRule(i);
774 document.styleSheets[
0].insertRule(classname + ' { ' + properties + ' }', document.styleSheets[
0]['cssRules'].length);
780 function updateCssClasses()
782 for(var key in config) {
783 changeCssClass(getLocalizedText('settings.name.' + key), config[key].Value);
787 function restoreDefaultSettings()
789 for (var key in config)
790 config[key].Value = config[key].Default;
793 function loadSettings()
795 for (var key in config) {
796 if (widget.preferenceForKey(key)) {
797 if (config[key].Type == 'Int')
798 config[key].Value = Number(widget.preferenceForKey(key));
799 else if (config[key].Type == 'String')
800 config[key].Value = widget.preferenceForKey(key);
801 else if (config[key].Type == 'Bool')
802 config[key].Value = (widget.preferenceForKey(key) == 'true')
803 else if (config[key].Type == 'Enum')
804 config[key].Value = widget.preferenceForKey(key);
805 else if (config[key].Type == 'UID')
806 config[key].Value = Number(widget.preferenceForKey(key));
809 config[key].Value = config[key].Default;
810 console.info('Settings: ' + key + '=\'' + config[key].Value + '\'');
814 function saveSettings()
816 for (var key in config) {
817 if (config[key].Type == 'Int')
818 widget.setPreferenceForKey(config[key].Value.toString(), key);
819 else if (config[key].Type == 'String')
820 widget.setPreferenceForKey(config[key].Value, key);
821 else if (config[key].Type == 'Bool')
822 widget.setPreferenceForKey(config[key].Value ? 'true' : 'false', key);
823 else if (config[key].Type == 'Enum')
824 widget.setPreferenceForKey(config[key].Value, key);
825 else if (config[key].Type == 'UID')
826 widget.setPreferenceForKey(config[key].Value.toString(), key);
830 function toggleVisibility(elementId)
832 if (document.getElementById(elementId).style.display ==
"none")
833 document.getElementById(elementId).style.display =
"block";
835 document.getElementById(elementId).style.display =
"none";
839 function printHintBox(text)
842 return '
<td width=
"1%" align=
"right" onclick=
"javascript:toggleVisibility(\'info' + uniqueId + '\')">' + getLocalizedText('settings.help') + '
</td></tr></table>'+
843 '
<div class=
"settingsInfo" id=
"info' + uniqueId + '">' + text + '
</div>';
849 document.getElementById(
"homescreenView").style.display =
"none";
850 document.getElementById(
"fullscreenView").style.display =
"none";
851 document.getElementById(
"aboutView").style.display =
"block";
852 document.getElementById(
"settingsView").style.display =
"none";
853 document.onclick = null;
855 window.menu.setLeftSoftkeyLabel(
" ", function(){});
856 window.menu.setRightSoftkeyLabel(
"Back", function()
862 //document.getElementById(
"aboutView").innerHTML = 'aboutView';
863 document.getElementById(
"name").innerHTML =
"Coming Next " + version;
866 function updateFullscreen()
870 function showFullscreen()
872 document.getElementById(
"homescreenView").style.display =
"none";
873 document.getElementById(
"fullscreenView").style.display =
"block";
874 document.getElementById(
"aboutView").style.display =
"none";
875 document.getElementById(
"settingsView").style.display =
"none";
876 document.getElementById('body').className =
"backgroundFullscreen";
877 document.onclick = launchCalendar;
882 function updateHomescreen()
884 if (config['useBackgroundImage'].Value) {
885 // check for screen rotation
886 if (orientation != 'portrait' && screen.width ==
360 && screen.height ==
640) {
887 window.widget.prepareForTransition(
"fade");
888 orientation = 'portrait';
889 document.getElementById('body').style.backgroundImage = 'url(background_' + orientation + '.png)';
890 document.getElementById('body').style.backgroundColor = 'none';
891 window.widget.performTransition();
892 } else if (orientation != 'landscape' && screen.width ==
640 && screen.height ==
360) {
893 window.widget.prepareForTransition(
"fade");
894 orientation = 'landscape';
895 document.getElementById('body').style.backgroundImage = 'url(background_' + orientation + '.png)';
896 document.getElementById('body').style.backgroundColor = 'none';
897 window.widget.performTransition();
899 else if (document.getElementById('body').style.backgroundImage ==
"")
901 document.getElementById('body').style.backgroundImage = 'url(background_' + orientation + '.png)';
906 function showHomescreen()
908 document.getElementById(
"homescreenView").style.display =
"block";
909 document.getElementById(
"fullscreenView").style.display =
"none";
910 document.getElementById(
"aboutView").style.display =
"none";
911 document.getElementById(
"settingsView").style.display =
"none";
912 document.getElementById('body').className =
"background";
913 document.onclick = null;
917 function getLocalizedText(p_Txt)
919 if (localizedText[p_Txt])
920 return localizedText[p_Txt];
922 return 'ERROR: missing translation for ' + p_Txt;
926 <style type=
"text/css">
927 table { margin:
0px; padding:
0px; border-spacing:
0px; }
928 td { padding:
0px
5px
0px
0px; white-space:nowrap; overflow:hidden; }
929 hr { color:#ffffff; background-color:#ffffff; height:
1px; text-align:left; border-style:none; }
930 .settingsInfo { display:none; font-style:italic; }
931 .title { font-weight:bold; font-size:
14pt; }
932 .textInput { width:
90%; }
933 .credits { margin-left:
40px; text-indent: -
20px; margin-bottom:
0px; }
934 #homescreenView { width:
315px; height:
91px; overflow:hidden; }
935 #calendarList { position:absolute; left:
10px; top:
4px; width:
295px; height:
75px; overflow:hidden; }
936 #name { text-align:center; }
937 #appicon { display: block; margin-left: auto; margin-right: auto; margin-top:
10px; }
938 #smallappicon { width:
22px; height:
22px; margin-right:
10px; float:left; }
943 <body id=
"body" class=
"background">
944 <div id=
"homescreenView">
945 <div id=
"calendarList"></div>
947 <div id=
"fullscreenView" style=
"display:none;">
948 <img src=
"Icon.png" id=
"smallappicon">
949 <h1 class=
"title">Coming Next
</h1>
951 <div id=
"fullscreenCalendarList">loading...
</div>
953 <div id=
"settingsView" style=
"display:none">
954 <img src=
"Icon.png" id=
"smallappicon">
955 <h1 class=
"title">Settings
</h1>
957 <div id=
"settingsList"></div>
959 <div id=
"aboutView" style=
"display:none">
960 <img src=
"Icon.png" id=
"appicon">
961 <h1 id=
"name">Coming Next
</h1>
963 <p>Created by Dr. Cochambre and Michael Prager.
</p>
964 <p>Contributions:
</p>
965 <p class=
"credits">Paul Moore (bug fixes, new features and code cleanup)
</p>
966 <p class=
"credits">Manfred Hanselmann (DST support)
</p>
967 <p class=
"credits">Christophe Milsent (translation support & french translation
</p>
968 <p>This software is open source and licensed under the GPLv3.
</p>
969 <p>Visit sourceforge.net/projects/comingnext for free updates.
</p>