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 if (device !=
"undefined")
666 calendarService = device.getServiceObject(
"Service.Calendar",
"IDataSource");
668 throw('device object does not exist');
670 error('loading Calendar service: ' + e + ', line ' + e.line);
678 requestNotification();
679 window.setInterval('updateData()',
1000 *
60 * config['updateDataInterval'].Value);
684 if (config['useBackgroundImage'].Value)
685 // check for screen rotation every
1 secs
686 window.setInterval('updateScreen()',
1000 *
1);
689 function createMenu()
691 window.menu.setLeftSoftkeyLabel(
"",null);
692 window.menu.setRightSoftkeyLabel(
"",null);
694 var menuSettings = new MenuItem(getLocalizedText('menu.settings'), id++);
695 var menuCallApp = new MenuItem(getLocalizedText('menu.openCalendarApp'), id++);
696 var menuAbout = new MenuItem(getLocalizedText('menu.about'), id++);
697 menuSettings.onSelect = showSettings;
698 menuAbout.onSelect = showAbout;
699 menuCallApp.onSelect = launchCalendar;
701 window.menu.append(menuCallApp);
702 window.menu.append(menuSettings);
703 window.menu.append(menuAbout);
706 function showSettings()
709 document.getElementById(
"homescreenView").style.display =
"none";
710 document.getElementById(
"fullscreenView").style.display =
"none";
711 document.getElementById(
"aboutView").style.display =
"none";
712 document.getElementById(
"settingsView").style.display =
"block";
713 document.onclick = null;
715 window.menu.setLeftSoftkeyLabel(getLocalizedText('settings.save'), function()
717 for (var key in config) {
718 if (config[key].Type == 'String')
719 config[key].Value = document.forms[
0].elements[
"settings." + key].value;
720 else if (config[key].Type == 'Int') {
721 config[key].Value = parseInt(document.forms[
0].elements[
"settings." + key].value);
722 if (config[key].Value <
0)
723 config[key].Value = config[key].Default;
725 else if (config[key].Type == 'Bool')
726 config[key].Value = document.forms[
0].elements[
"settings." + key].checked;
727 else if (config[key].Type == 'UID')
728 config[key].Value = parseInt(document.forms[
0].elements[
"settings." + key].value);
729 else if (config[key].Type == 'Enum') {
730 config[key].Value = document.forms[
0].elements[
"settings." + key].value;
731 if (config[key].ValidValues.indexOf(config[key].Value) == -
1)
732 config[key].Value = config[key].Default;
743 window.menu.setRightSoftkeyLabel(getLocalizedText('settings.cancel'), function()
749 var settingsHtml = '
<form>';
750 for (var key in config) {
751 if (config[key].Type == 'String')
752 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 />';
753 else if (config[key].Type == 'Int')
754 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 />';
755 else if (config[key].Type == 'Bool')
756 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 />';
757 else if (config[key].Type == 'UID')
758 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 />';
759 else if (config[key].Type == 'Enum') {
760 settingsHtml += '
<table><tr><td>' + getLocalizedText('settings.name.' + key) + '
<br /><select name=
"settings.' + key + '" size=
"1">';
761 for(var i =
0; i < config[key].ValidValues.length; i++)
762 settingsHtml += '
<option label=
"' + config[key].ValidValues[i] + '"' + (config[key].Value == config[key].ValidValues[i] ? '
selected=
"selected"' : '') + '
>' + config[key].ValidValues[i] + '
</option>';
763 settingsHtml += '
</select></div></td>' + printHintBox(getLocalizedText('settings.info.' + key)) + '
<hr />';
766 settingsHtml += '
<input name=
"reset" type=
"button" value=
"' + getLocalizedText('settings.restoreDefaults') + '" onclick=
"javascript:restoreDefaultSettings();showSettings();" />';
767 settingsHtml += '
</form>';
768 document.getElementById(
"settingsList").innerHTML = settingsHtml;
771 function changeCssClass(classname, properties)
773 for(var i =
0; i < document.styleSheets[
0]['cssRules'].length; i++)
775 if (document.styleSheets[
0]['cssRules'][i].selectorText == classname) {
776 document.styleSheets[
0].deleteRule(i);
777 document.styleSheets[
0].insertRule(classname + ' { ' + properties + ' }', document.styleSheets[
0]['cssRules'].length);
783 function updateCssClasses()
785 for(var key in config) {
786 changeCssClass(getLocalizedText('settings.name.' + key), config[key].Value);
790 function restoreDefaultSettings()
792 for (var key in config)
793 config[key].Value = config[key].Default;
796 function loadSettings()
798 for (var key in config) {
799 if (widget.preferenceForKey(key)) {
800 if (config[key].Type == 'Int')
801 config[key].Value = Number(widget.preferenceForKey(key));
802 else if (config[key].Type == 'String')
803 config[key].Value = widget.preferenceForKey(key);
804 else if (config[key].Type == 'Bool')
805 config[key].Value = (widget.preferenceForKey(key) == 'true')
806 else if (config[key].Type == 'Enum')
807 config[key].Value = widget.preferenceForKey(key);
808 else if (config[key].Type == 'UID')
809 config[key].Value = Number(widget.preferenceForKey(key));
812 config[key].Value = config[key].Default;
813 console.info('Settings: ' + key + '=\'' + config[key].Value + '\'');
817 function saveSettings()
819 for (var key in config) {
820 if (config[key].Type == 'Int')
821 widget.setPreferenceForKey(config[key].Value.toString(), key);
822 else if (config[key].Type == 'String')
823 widget.setPreferenceForKey(config[key].Value, key);
824 else if (config[key].Type == 'Bool')
825 widget.setPreferenceForKey(config[key].Value ? 'true' : 'false', key);
826 else if (config[key].Type == 'Enum')
827 widget.setPreferenceForKey(config[key].Value, key);
828 else if (config[key].Type == 'UID')
829 widget.setPreferenceForKey(config[key].Value.toString(), key);
833 function toggleVisibility(elementId)
835 if (document.getElementById(elementId).style.display ==
"none")
836 document.getElementById(elementId).style.display =
"block";
838 document.getElementById(elementId).style.display =
"none";
842 function printHintBox(text)
845 return '
<td width=
"1%" align=
"right" onclick=
"javascript:toggleVisibility(\'info' + uniqueId + '\')">' + getLocalizedText('settings.help') + '
</td></tr></table>'+
846 '
<div class=
"settingsInfo" id=
"info' + uniqueId + '">' + text + '
</div>';
852 document.getElementById(
"homescreenView").style.display =
"none";
853 document.getElementById(
"fullscreenView").style.display =
"none";
854 document.getElementById(
"aboutView").style.display =
"block";
855 document.getElementById(
"settingsView").style.display =
"none";
856 document.onclick = null;
858 window.menu.setLeftSoftkeyLabel(
" ", function(){});
859 window.menu.setRightSoftkeyLabel(
"Back", function()
865 //document.getElementById(
"aboutView").innerHTML = 'aboutView';
866 document.getElementById(
"name").innerHTML =
"Coming Next " + version;
869 function updateFullscreen()
873 function showFullscreen()
875 document.getElementById(
"homescreenView").style.display =
"none";
876 document.getElementById(
"fullscreenView").style.display =
"block";
877 document.getElementById(
"aboutView").style.display =
"none";
878 document.getElementById(
"settingsView").style.display =
"none";
879 document.getElementById('body').className =
"backgroundFullscreen";
880 document.onclick = launchCalendar;
885 function updateHomescreen()
887 if (config['useBackgroundImage'].Value) {
888 // check for screen rotation
889 if (orientation != 'portrait' && screen.width ==
360 && screen.height ==
640) {
890 window.widget.prepareForTransition(
"fade");
891 orientation = 'portrait';
892 document.getElementById('body').style.backgroundImage = 'url(background_' + orientation + '.png)';
893 document.getElementById('body').style.backgroundColor = 'none';
894 window.widget.performTransition();
895 } else if (orientation != 'landscape' && screen.width ==
640 && screen.height ==
360) {
896 window.widget.prepareForTransition(
"fade");
897 orientation = 'landscape';
898 document.getElementById('body').style.backgroundImage = 'url(background_' + orientation + '.png)';
899 document.getElementById('body').style.backgroundColor = 'none';
900 window.widget.performTransition();
902 else if (document.getElementById('body').style.backgroundImage ==
"")
904 document.getElementById('body').style.backgroundImage = 'url(background_' + orientation + '.png)';
909 function showHomescreen()
911 document.getElementById(
"homescreenView").style.display =
"block";
912 document.getElementById(
"fullscreenView").style.display =
"none";
913 document.getElementById(
"aboutView").style.display =
"none";
914 document.getElementById(
"settingsView").style.display =
"none";
915 document.getElementById('body').className =
"background";
916 document.onclick = null;
920 function getLocalizedText(p_Txt)
922 if (localizedText[p_Txt])
923 return localizedText[p_Txt];
925 return 'ERROR: missing translation for ' + p_Txt;
929 <style type=
"text/css">
930 table { margin:
0px; padding:
0px; border-spacing:
0px; }
931 td { padding:
0px
5px
0px
0px; white-space:nowrap; overflow:hidden; }
932 hr { color:#ffffff; background-color:#ffffff; height:
1px; text-align:left; border-style:none; }
933 .settingsInfo { display:none; font-style:italic; }
934 .title { font-weight:bold; font-size:
14pt; }
935 .textInput { width:
90%; }
936 .credits { margin-left:
40px; text-indent: -
20px; margin-bottom:
0px; }
937 #homescreenView { width:
315px; height:
91px; overflow:hidden; }
938 #calendarList { position:absolute; left:
10px; top:
4px; width:
295px; height:
75px; overflow:hidden; }
939 #name { text-align:center; }
940 #appicon { display: block; margin-left: auto; margin-right: auto; margin-top:
10px; }
941 #smallappicon { width:
22px; height:
22px; margin-right:
10px; float:left; }
946 <body id=
"body" class=
"background">
947 <div id=
"homescreenView">
948 <div id=
"calendarList"></div>
950 <div id=
"fullscreenView" style=
"display:none;">
951 <img src=
"Icon.png" id=
"smallappicon">
952 <h1 class=
"title">Coming Next
</h1>
954 <div id=
"fullscreenCalendarList">loading...
</div>
956 <div id=
"settingsView" style=
"display:none">
957 <img src=
"Icon.png" id=
"smallappicon">
958 <h1 class=
"title">Settings
</h1>
960 <div id=
"settingsList"></div>
962 <div id=
"aboutView" style=
"display:none">
963 <img src=
"Icon.png" id=
"appicon">
964 <h1 id=
"name">Coming Next
</h1>
966 <p>Created by Dr. Cochambre and Michael Prager.
</p>
967 <p>Contributions:
</p>
968 <p class=
"credits">Paul Moore (bug fixes, new features and code cleanup)
</p>
969 <p class=
"credits">Manfred Hanselmann (DST support)
</p>
970 <p class=
"credits">Christophe Milsent (translation support & french translation
</p>
971 <p>This software is open source and licensed under the GPLv3.
</p>
972 <p>Visit sourceforge.net/projects/comingnext for free updates.
</p>