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 .background { color:#ffffff; background-color:#
000000 } /* Defines the background of the widget. If you want to use a background image, set useBackgroundImage = true below */
10 /* for the default themes, black, gray, and light blue, codes are #
292029, #e7dfe7, #
009aef */
11 .weekDay { } /* Defines the appearance of all week day texts */
12 .date { } /* Defines the appearance of all date texts */
13 .today { color:#ff0000; } /* Defines the appearance of
"Today" text */
14 .tomorrow { color:#
0000ff; } /* Defines the appearance of
"Tomorrow" text */
15 .time { } /* Defines the appearance of all time texts */
16 .now { color:#ff00ff; } /* Defines the appearance of
"Now" text */
17 .description { } /* Defines the appearance of all event descriptions */
18 .icon { width:
15px; height:
15px; } /* Defines size and appearance of icons */
22 var monthRange =
2; // number of months to include in the event list
23 var includeTodos = true; // disable to remove ToDos from event list
24 var useBackgroundImage = true; // use background_portrait.png and background_landscape.png to fake transparency. Set to
"false" to use a solid background color
25 var showCombinedDateTime = false;// only show the time for events happening today, otherwise just show the date
26 var showLocation = true; // show the location for meeting events
27 var showTodayAsText = true; // if enabled, the current date will be shown as
"Today" instead of
"31.12"
28 var todayText = 'Today'; // text to display for
"Today"
29 var tomorrowText = 'Tomorrow'; // text to display for
"Tomorrow"
30 var showNowAsText = true; // if enabled, the appointment time will be shown as
"Now" instead of
"12:00"
31 var nowText = 'Now'; // text to display for
"Now"
32 var dateSeparator = '.'; // separator for dates. e.g.
"31.12" or
"31/12"
33 var dateFormat = 'auto' // how dates will be displayed. 'auto' will autodetect your phone's date format setting. 'MMDD' will write month first, 'DDMM' will write day first
34 var weekDayLength =
2; // defines how many characters of the weekday will be shown. E.g.
2 will cut
"Friday" to
"Fr"
35 var updateDataInterval =
5; // how many minutes to wait before updating the displayed data. The higher the number, the less battery is used
36 var calendarApp =
0x10005901; // UID of the calendar app to run when clicking the widget.
0x10005901 = buildin calendar,
0x20004ec1 = Epocware Handy Calendar
37 var eventsPerWidget =
4; // number of events to show per widget. Default is
4
38 var showNothingText = true; // if set to
"true", show a text if no events are in the list
39 var nothingText = 'No further events within ' + monthRange + ' months'; // text to show when no events are in the list
40 var enableDaylightSaving = true;// enable this if you are in a timezone that has daylight saving time (+
1h)
42 var cssStyle_background =
"color:#ffffff; background-color:#000000"; // Defines the background of the widget. If you want to use a background image, set useBackgroundImage = true below. For the default themes, black, gray, and light blue, codes are #
292029, #e7dfe7, #
009aef
43 var cssStyle_weekDay =
""; // Defines the appearance of all week day texts
44 var cssStyle_date =
""; // Defines the appearance of all date texts
45 var cssStyle_today =
"color:#ff0000"; // Defines the appearance of
"Today" text
46 var cssStyle_tomorrow =
"color:#0000ff"; // Defines the appearance of
"Tomorrow" text
47 var cssStyle_time =
""; // Defines the appearance of all time texts
48 var cssStyle_now =
"color:#ff00ff"; // Defines the appearance of
"Now" text
49 var cssStyle_description =
""; // Defines the appearance of all event descriptions
50 var cssStyle_icon =
"width:15px; height:15px"; // Defines size and appearance of icons
52 //-------------------------------------------------------
53 // Nothing of interest from here on...
54 //-------------------------------------------------------
55 var panelNum =
0; // use
1 for second panel
57 var calendarService = null;
58 var cacheEntriesHtml = [];
59 var months_translated = [];
62 var mode =
0; //
0 = homescreen,
1 = fullscreen,
2 = settings,
3 = about
64 // vars for daylight saving time
65 var daylightsavingWinter =
0;
66 var daylightsavingSummer =
0;
67 var summertime = false;
70 window.onresize = updateScreen;
71 window.onshow = updateScreen;
73 function isLeapYear( year ) {
74 if (( year %
4 ==
0 && year %
100 !=
0 ) || year %
400 ==
0 )
80 function calcLeapYear(year, days)
88 function subToSunday(myDate, year, days, prevMonthDays)
90 for (i = myDate.getDay(); i
> 0 ;i--)
92 days -= prevMonthDays;
93 days = isLeapYear(year) ? --days : days;
97 function calcDaylightSaving()
99 var thisYearS = new Date(now.getFullYear(),
3,
0,
0,
0,
0 );
100 var thisYearW = new Date(now.getFullYear(),
10,
0,
0,
0,
0 );
101 var nextYearS = new Date(now.getFullYear() +
1,
3,
0,
0,
0,
0 );
102 var nextYearW = new Date(now.getFullYear() +
1,
10,
0,
0,
0,
0 );
106 thisYearSDays = nextYearSDays =
90;
107 thisYearWDays = nextYearWDays =
304;
109 thisYearSDays = calcLeapYear(now.getFullYear(), thisYearSDays);
110 thisYearWDays = calcLeapYear(now.getFullYear(), thisYearWDays);
111 nextYearSDays = calcLeapYear(now.getFullYear() +
1, nextYearSDays);
112 nextYearWDays = calcLeapYear(now.getFullYear() +
1, nextYearWDays);
114 thisYearSDays = subToSunday(thisYearS, now.getFullYear(), thisYearSDays,
59);
115 thisYearWDays = subToSunday(thisYearW, now.getFullYear(), thisYearWDays,
273);
116 nextYearSDays = subToSunday(nextYearS, now.getFullYear() +
1, nextYearSDays,
59);
117 nextYearWDays = subToSunday(nextYearW, now.getFullYear() +
1, nextYearWDays,
273);
119 daylightsavingSummer = new Date (now.getFullYear(),
03-
1, thisYearSDays,
2,
0,
0);
120 daylightsavingWinter = new Date (now.getFullYear(),
10-
1, thisYearWDays,
2,
0,
0);
121 if (daylightsavingSummer < now) {
122 daylightsavingSummer = new Date (now.getFullYear()+
1,
03-
1, nextYearSDays,
2,
0,
0);
125 if (daylightsavingWinter < now) {
126 daylightsavingWinter = new Date (now.getFullYear()+
1,
10-
1, nextYearWDays,
2,
0,
0);
129 if (summer && !winter)
135 function error(message)
137 console.info('Error: ' + message);
138 document.getElementById(
"calendarList").innerHTML = 'Error: ' + message;
141 function isToday(date)
143 if (date.getDate() == now.getDate() && date.getMonth() == now.getMonth())
148 function isTomorrow(date)
150 if ((date.getDate() == now.getDate() +
1 && date.getMonth() == now.getMonth()) ||
151 (date.getDate() ==
0 && date.getMonth() == now.getMonth() +
1) ||
152 (date.getDate() ==
0 && date.getMonth() == now.getMonth() +
1 && date.getYear() == now.getYear() +
1))
157 function collectLocales()
159 var tmpyear = ((panelNum ==
0) ?
2000 :
2001);
162 if (months_translated.length
> 0)
164 for (month =
0; month <
12; month++) {
165 var startDate = new Date(tmpyear, month,
15);
167 var item = new Object();
168 item.Type =
"DayEvent";
169 item.StartTime = startDate;
170 item.Summary =
"__temp" + month;
172 var criteria = new Object();
173 criteria.Type =
"CalendarEntry";
174 criteria.Item = item;
177 var result = calendarService.IDataSource.Add(criteria);
178 if (result.ErrorCode)
179 error(result.ErrorMessage);
181 error(
"collectLocales: " + e + ', line ' + e.line);
185 var startTime = new Date(tmpyear,
0,
1);
186 var endTime = new Date(tmpyear,
11,
31);
187 var listFiltering = {
188 Type:'CalendarEntry',
190 StartRange: startTime,
192 SearchText: '__temp',
196 var result = calendarService.IDataSource.GetList(listFiltering);
197 if (result.ErrorCode) {
198 error(result.ErrorMessage);
201 var list = result.ReturnValue;
203 error(e + ', line ' + e.line);
206 var ids = new Array();
212 while (list && (entry = list.getNext()) != undefined) {
213 dateArr = entry.StartTime.replace(/,/g,'').replace(/\./g,':').replace(/ /g,' ').split(' ');
214 var day = dateArr[
1];
215 var month = dateArr[
2];
216 var year = dateArr[
3];
218 // make sure month is set properly
219 if (isNaN(parseInt(day))) {
223 } else if (isNaN(parseInt(year))) {
229 console.info(entry.StartTime + ' -
> ' + month + ' ' + counter);
230 ids[counter] = entry.id;
231 months_translated[month] = counter +
1;
235 error(e + ', line ' + e.line);
240 var criteria = new Object();
241 criteria.Type =
"CalendarEntry";
246 var result = calendarService.IDataSource.Delete(criteria);
247 if (result.ErrorCode)
248 error(result.ErrorMessage);
250 error('deleting temp calendar entries:' + e + ', line ' + e.line);
255 function requestNotification()
257 var criteria = new Object();
258 criteria.Type =
"CalendarEntry";
261 var result = calendarService.IDataSource.RequestNotification(criteria, callback);
262 if (result.ErrorCode)
263 error('loading Calendar items list');
265 error(
"requestNotification: " + e + ', line ' + e.line);
269 function callback(transId, eventCode, result)
274 function parseDate(dateString)
277 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:
278 Wednesday,
26 August,
2009 24:
00:
00
279 Wednesday,
26 August,
2009 12:
00:
00 am
280 Wednesday, August
26,
2009 12:
00:
00 am
281 Wednesday,
2009 August,
26 12:
00:
00 am
282 Wednesday,
2009 August,
28 8.00.00 pm
283 Wednesday,
2009 August,
28 08:
00:
00 PM
286 if (dateString ==
"" || dateString == null)
288 var dateArr = dateString.replace(/,/g,'').replace(/\./g,':').replace(/ /g,' ').split(' ');
289 if (dateArr.length !=
5 && dateArr.length !=
6)
293 var weekDay = dateArr[
0];
294 var day = dateArr[
1];
295 var month = dateArr[
2];
296 var year = dateArr[
3];
297 // make sure month is set properly
298 if (isNaN(parseInt(day))) {
302 } else if (isNaN(parseInt(year))) {
307 // make sure day and year are set properly
308 if (Number(day)
> Number(year)) {
313 month = months_translated[month];
316 var timeArr = dateArr[
4].split(':');
317 if (timeArr.length !=
3)
319 var hours = Number(timeArr[
0]);
320 var minutes = Number(timeArr[
1]);
321 var seconds = Number(timeArr[
2]);
322 if (dateArr.length ==
6 && dateArr[
5].toLowerCase() == 'pm' && hours <
12)
324 if (dateArr.length ==
6 && dateArr[
5].toLowerCase() == 'am' && hours ==
12)
327 console.info('year=' + year + ' month=' + month + ' day=' + day + ' hours=' + hours + ' minutes=' + minutes+ ' seconds=' + seconds);
329 // take care of daylight saving time
330 if (enableDaylightSaving) {
331 var date = new Date(year, month -
1, day, hours, minutes, seconds);
332 if (summertime && date
> daylightsavingWinter && date < daylightsavingSummer)
334 else if (!summertime && date
> daylightsavingSummer && date < daylightsavingWinter)
338 return new Date(year, month -
1, day, hours, minutes, seconds);
341 // 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"
342 function formatDate(date, format)
344 var day = date.getDate().toString();
345 var month = (date.getMonth() +
1).toString();
346 while (day.length <
2) { day = '
0' + day; }
347 while (month.length <
2) { month = '
0' + month; }
349 if (showTodayAsText && isToday(date))
350 return '
<span class=
"today">' + todayText + '
</span>';
351 if (showTodayAsText && isTomorrow(date))
352 return '
<span class=
"tomorrow">' + tomorrowText + '
</span>';
354 var dateArr = format.replace(/,/g,'').replace(/\./g,':').replace(/ /g,' ').split(' ');
355 if (dateArr.length !=
5 && dateArr.length !=
6) {
356 // we don't know how to format this
357 if (dateFormat == 'auto' || dateFormat == 'DDMM')
358 return day + dateSeparator + month;
360 return month + dateSeparator + day;
364 if (dateFormat == 'MMDD')
366 else if (dateFormat == 'DDMM')
369 // dateFormat == 'auto', try to detect system setting
371 var day_ = dateArr[
1];
372 var month_ = dateArr[
2];
373 var year_ = dateArr[
3];
374 // make sure month is set properly
375 if (isNaN(parseInt(day_))) {
380 } else if (isNaN(parseInt(year_))) {
386 // make sure day and year are set properly
387 if (Number(day_)
> Number(year_))
392 return day + dateSeparator + month;
394 return month + dateSeparator + day;
397 function formatTime(date)
399 // date is a Date() object
400 date.setSeconds(
0); // we don't care about seconds
401 var time = date.toLocaleTimeString().replace(/[\.:]
00/, ''); // remove seconds from string
402 if (time.replace(/\./, ':').split(':')[
0].length <
2)
404 if (showNowAsText && date.getTime() == now.getTime())
405 time = '
<span class=
"now">' + nowText + '
</span>';
409 function updateData()
411 calcDaylightSaving();
413 // meetings have time
414 // 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
416 var meetingListFiltering = {
417 Type:'CalendarEntry',
419 StartRange: (new Date(now.getFullYear(), now.getMonth(), now.getDate(),
0,
0,
0)),
420 EndRange: (new Date(now.getFullYear(), now.getMonth() + monthRange, now.getDate(),
0,
0,
0))
423 var meetingResult = calendarService.IDataSource.GetList(meetingListFiltering);
424 var meetingList = meetingResult.ReturnValue;
426 // todos don't, they start on
00:
00 hrs., but should be visible anyway
427 // this will generate a list of passed todos. We have to check if they have been marked as
"done" yet
429 var todayTodoListFiltering = {
430 Type:'CalendarEntry',
433 StartRange: (new Date(now.getFullYear() -
1, now.getMonth(), now.getDate(),
0,
0,
0)),
434 EndRange: (new Date(now.getFullYear(), now.getMonth(), now.getDate(),
0,
0,
1))
437 var todayTodoResult = calendarService.IDataSource.GetList(todayTodoListFiltering);
438 var todayTodoList = todayTodoResult.ReturnValue;
439 var entryLists = [todayTodoList, meetingList];
441 var entryLists = [meetingList];
444 error('loading Calendar items list:' + e + ', line ' + e.line);
453 var entriesHtml = '
<table>';
457 max = ((panelNum ==
0) ? eventsPerWidget :
2 * eventsPerWidget);
459 max =
30; // we can display a lot more events in fullscreen mode
461 // the first outer loop iteration is for passed ToDos, the second loop is for all upcomming events (may also include ToDos)
462 for (var i=
0; counter < max && i < entryLists.length; i++) {
463 while (counter < max && (entry = entryLists[i].getNext()) != undefined) {
466 // output event info for debugging
468 'event: Id=' + entry.id +
469 ',Type=' + entry.Type +
470 ',Summary=' + entry.Summary +
471 ',Location=' + entry.Location +
472 ',Status=' + entry.Status +
473 ',StartTime=' + entry.StartTime +
474 ',EndTime=' + entry.EndTime +
475 ',InstanceStartTime=' + entry.InstanceStartTime +
476 ',InstanceEndTime=' + entry.InstanceEndTime
479 // we don't want ToDos when includeTodos == false or when they are completed
480 if (entry.Type == 'ToDo' && (entry.Status ==
"TodoCompleted" || !includeTodos)) {
481 console.info('skipping ' + entry.id );
486 // make sure that we don't include an event twice (useful for ToDos that might come up twice)
487 if (eventIds[entry.id] ==
1) {
488 console.info('skipped (already included) ' + entry.id);
492 eventIds[entry.id] =
1;
494 // summary can be undefined!
495 var Summary = ((entry.Summary == null) ? '' : entry.Summary);
496 if (entry.Type == 'Meeting' && entry.Location != '' && showLocation)
497 Summary += ', ' + entry.Location;
499 // fix by yves: determine start and end dates/times
500 entryStartTime = ((entry.InstanceStartTime == null) ? entry.StartTime : entry.InstanceStartTime);
501 entryEndTime = ((entry.InstanceEndTime == null) ? entry.EndTime : entry.InstanceEndTime);
503 // there can be ToDos that have no date at all!
504 if (entry.Type == 'ToDo' && entry.EndTime == null)
505 entryDate =
""; // this will cause parseDate(entryDate) to return null;
507 entryDate = ((entry.Type == 'ToDo') ? entryEndTime : entryStartTime); // ToDo's use their EndTime, the rest use StartTime
509 // Convert date/time string to Date object
510 var date = parseDate(entryDate);
511 console.info('date: ' + date);
512 var endDate = ((entryEndTime == null) ? null : parseDate(entryEndTime));
513 console.info('endDate: ' + endDate);
515 // check if meeting event has already passed
516 if (entry.Type == 'Meeting') {
517 var compareTime = ((endDate == null) ? date.getTime() : endDate.getTime());
518 if (now.getTime()
> compareTime) {
519 console.info('skipping Meeting (already passed) ' + entry.id);
521 eventIds[entry.id] =
0;
526 // check if anniversary passed (not sure why they are in the list, the query was only for today - nokia?)
527 if (entry.Type == 'Anniversary') {
528 var tmp = new Date(now.getFullYear(), now.getMonth(), now.getDate(),
0,
0,
0);
529 if (date.getTime() < tmp.getTime()) {
530 console.info('skipping Anniversary (already passed) ' + entry.id);
532 eventIds[entry.id] =
0;
537 // fix DayEvents end time. End times are off by
1 Second. It's possible that the event has already passed
538 if (entry.Type == 'DayEvent' && endDate != null) {
539 endDate.setMinutes(endDate.getMinutes() -
1);
540 console.info('fixing DayEvent endDate: ' + endDate);
541 if (now.getTime()
> endDate.getTime()) {
542 console.info('event already passed ' + entry.id);
544 eventIds[entry.id] =
0;
549 // check if the event is currently taking place
550 if (entryStartTime != null && entryEndTime != null && date != null && endDate != null) {
551 // check if we are between start and endtime
552 if ((date.getTime() < now.getTime()) && (now.getTime() < endDate.getTime())) {
553 date = now; // change appointment date/time to now
554 console.info('event is currently taking place: ' + date);
558 // skip events for the first panel in case this is the second one and we're not in fullscreen mode
559 if (mode ==
0 && panelNum ==
1 && counter < eventsPerWidget +
1) {
560 console.info('skipping (already in first widget) ' + entry.id);
564 // generate html output
565 entriesHtml += '
<tr><td><img class=
"icon" src=
"' + entry.Type + '.png" /></td>';
567 // some languages have very strange locale date formats, can't parse all those. Also some todos don't have dates at all.
568 entriesHtml += '
<td colspan=
"4"><span class=
"date">' + entryDate + '
</span> ';
570 var weekDay = date.toLocaleDateString().substr(
0,weekDayLength);
571 var time = formatTime(date);
572 var dateStr = formatDate(date, entryDate);
573 if (entry.Type == 'ToDo' || entry.Type == 'Anniversary' || entry.Type == 'DayEvent' || entry.Type == 'Reminder') {
574 if ((isToday(date) || isTomorrow(date)) && showTodayAsText) // show weekday if the date string is not text. looks odd otherwise
575 entriesHtml += '
<td colspan=
"4" width=
"1px"><span class=
"date">' + dateStr + '
</span> ';
577 entriesHtml += '
<td class=
"weekDay" width=
"1px">' + weekDay + '
</td><td width=
"1px" class=
"date">' + dateStr + '
</td><td colspan=
"2">';
578 } else if (entry.Type == 'Meeting') {
579 if (showCombinedDateTime) {
581 entriesHtml += '
<td width=
"1px" colspan=
"4"><span class=
"today">' + time + '
</span> ';
582 else if (isTomorrow(date))
583 entriesHtml += '
<td width=
"1px" colspan=
"4"><span class=
"tomorrow">' + dateStr + '
</span> <span class=
"time">' + time + '
</span> ';
585 entriesHtml += '
<td width=
"1px" class=
"weekDay">' + weekDay + '
</td><td width=
"1px" class=
"date">' + dateStr + '
</td><td colspan=
"2">';
587 if ((isToday(date) || isTomorrow(date)) && showTodayAsText)
588 entriesHtml += '
<td colspan=
"4" width=
"1px"><span class=
"today">' + dateStr + '
</span> <span class=
"time">' + time + '
</span> ';
590 entriesHtml += '
<td width=
"1px" class=
"weekDay">' + weekDay + '
</td><td width=
"1px" class=
"date">' + dateStr + '
</td><td width=
"1px" class=
"time">' + time + '
</td><td>';
594 entriesHtml += '
<span class=
"description">' + Summary + '
</span></td></tr>';
597 entriesHtml += '
</table>';
598 if (showNothingText && entriesHtml == '
<table></table>')
599 entriesHtml = '
<div style=
"width:295px; height:75px; text-align:center; line-height:75px; overflow:visible;">' + nothingText + '
</div>';
600 if (cacheEntriesHtml != entriesHtml) {
602 document.getElementById('calendarList').innerHTML = entriesHtml;
604 document.getElementById('fullscreenCalendarList').innerHTML = entriesHtml;
605 cacheEntriesHtml = entriesHtml;
608 error('displaying list:' + e + ', line ' + e.line);
613 function updateScreen()
615 // check if opening fullscreen
616 if( window.innerHeight
> 91 && mode ==
0) {
618 cacheEntriesHtml = '';
621 else if (window.innerHeight <=
91 && mode !=
0) {
623 cacheEntriesHtml = '';
633 function launchCalendar()
636 widget.openApplication(calendarApp,
"");
639 error('starting Calendar App');
647 // call calendar service
648 calendarService = device.getServiceObject(
"Service.Calendar",
"IDataSource");
650 error('loading Calendar service');
658 requestNotification();
659 window.setInterval('updateData()',
1000 *
60 * updateDataInterval);
664 if (useBackgroundImage)
665 // check for screen rotation every
3 secs
666 window.setInterval('updateScreen()',
1000 *
3);
669 function createMenu()
671 window.menu.setLeftSoftkeyLabel(
"",null);
672 window.menu.setRightSoftkeyLabel(
"",null);
674 var menuSettings = new MenuItem(
"Settings", id++);
675 var menuCallApp = new MenuItem(
"Open Calendar App", id++);
676 var menuAbout = new MenuItem(
"About", id++);
677 menuSettings.onSelect = showSettings;
678 menuAbout.onSelect = showAbout;
679 menuCallApp.onSelect = launchCalendar;
681 window.menu.append(menuCallApp);
682 window.menu.append(menuSettings);
683 window.menu.append(menuAbout);
686 function showSettings()
689 document.getElementById(
"homescreenView").style.display =
"none";
690 document.getElementById(
"fullscreenView").style.display =
"none";
691 document.getElementById(
"aboutView").style.display =
"none";
692 document.getElementById(
"settingsView").style.display =
"block";
694 window.menu.setLeftSoftkeyLabel(
"Save", function()
696 //document.forms[
0].elements[
"settings.monthRange"].value = monthRange;
697 monthRange = parseInt(document.forms[
0].elements[
"settings.monthRange"].value);
698 if (monthRange <
0 || monthRange
> 100)
700 includeTodos = document.forms[
0].elements[
"settings.includeTodos"].checked;
701 useBackgroundImage = document.forms[
0].elements[
"settings.useBackgroundImage"].checked;
702 showCombinedDateTime = document.forms[
0].elements[
"settings.showCombinedDateTime"].checked;
703 showLocation = document.forms[
0].elements[
"settings.showLocation"].checked;
704 showTodayAsText = document.forms[
0].elements[
"settings.showTodayAsText"].checked;
705 todayText = document.forms[
0].elements[
"settings.todayText"].value;
706 tomorrowText = document.forms[
0].elements[
"settings.tomorrowText"].value;
707 showNowAsText = document.forms[
0].elements[
"settings.showNowAsText"].checked;
708 nowText = document.forms[
0].elements[
"settings.nowText"].value;
709 dateSeparator = document.forms[
0].elements[
"settings.dateSeparator"].value;
710 dateFormat = document.forms[
0].elements[
"settings.dateFormat"].value;
711 if (dateFormat != 'auto' && dateFormat != 'DDMM' && dateFormat != 'MMDD')
713 weekDayLength = Number(parseInt(document.forms[
0].elements[
"settings.weekDayLength"].value));
714 if (weekDayLength <
0 || weekDayLength
> 20)
716 updateDataInterval = parseInt(document.forms[
0].elements[
"settings.updateDataInterval"].value);
717 if (updateDataInterval <
1 || updateDataInterval
> 1000)
718 updateDataInterval =
5;
719 calendarApp = parseInt(document.forms[
0].elements[
"settings.calendarApp"].value);
720 eventsPerWidget = parseInt(document.forms[
0].elements[
"settings.eventsPerWidget"].value);
721 if (eventsPerWidget <
1 || eventsPerWidget
> 10)
723 showNothingText = document.forms[
0].elements[
"settings.showNothingText"].checked;
724 nothingText = document.forms[
0].elements[
"settings.nothingText"].value;
725 enableDaylightSaving = document.forms[
0].elements[
"settings.enableDaylightSaving"].checked;
727 cssStyle_background = document.forms[
0].elements[
"settings.cssStyle_background"].value;
728 cssStyle_weekDay = document.forms[
0].elements[
"settings.cssStyle_weekDay"].value;
729 cssStyle_date = document.forms[
0].elements[
"settings.cssStyle_date"].value;
730 cssStyle_today = document.forms[
0].elements[
"settings.cssStyle_today"].value;
731 cssStyle_tomorrow = document.forms[
0].elements[
"settings.cssStyle_tomorrow"].value;
732 cssStyle_time = document.forms[
0].elements[
"settings.cssStyle_time"].value;
733 cssStyle_now = document.forms[
0].elements[
"settings.cssStyle_now"].value;
734 cssStyle_description = document.forms[
0].elements[
"settings.cssStyle_description"].value;
735 cssStyle_icon = document.forms[
0].elements[
"settings.cssStyle_icon"].value;
744 window.menu.setRightSoftkeyLabel(
"Cancel", function()
750 document.getElementById(
"settingsList").innerHTML =
752 '
<table><tr><td>Month Range:
<br><input class=
"textInput" name=
"settings.monthRange" type=
"text" value=
"' + monthRange + '" /></td>' + printHintBox('number of months to include in the event list') +
753 '
<hr><table><tr><td>Include ToDos:
<br><input name=
"settings.includeTodos" type=
"checkbox" value=
"true" ' + (includeTodos ? '
checked=
"checked"' : '') + '
/></td>' + printHintBox('disable to remove ToDos from event list') +
754 '
<hr><table><tr><td>Use Background Image:
<br><input name=
"settings.useBackgroundImage" type=
"checkbox" value=
"true" ' + (useBackgroundImage ? '
checked=
"checked"' : '') + '
/></td>' + printHintBox('use background_portrait.png and background_landscape.png to fake transparency. Disable to use a solid background color') +
755 '
<hr><table><tr><td>Show Combined Date & Time:
<br><input name=
"settings.showCombinedDateTime" type=
"checkbox" value=
"true" ' + (showCombinedDateTime ? '
checked=
"checked"' : '') + '
/></td>' + printHintBox('only show the time for events happening today, otherwise just show the date') +
756 '
<hr><table><tr><td>Show Location:
<br><input name=
"settings.showLocation" type=
"checkbox" value=
"true" ' + (showLocation ? '
checked=
"checked"' : '') + '
/></td>' + printHintBox('show the location for meeting events') +
757 '
<hr><table><tr><td>Show Today As Text:
<br><input name=
"settings.showTodayAsText" type=
"checkbox" value=
"true" ' + (showTodayAsText ? '
checked=
"checked"' : '') + '
/></td>' + printHintBox('if enabled, the current date will be shown as
"Today" instead of
"31.12"') +
758 '
<hr><table><tr><td>"Today" Text:
<br><input class=
"textInput" name=
"settings.todayText" type=
"text" value=
"' + todayText + '" /></td>' + printHintBox('text to display for
"Today"') + '
</tr>' +
759 '
<hr><table><tr><td>"Tomorrow" Text:
<br><input class=
"textInput" name=
"settings.tomorrowText" type=
"text" value=
"' + tomorrowText + '" /></td>' + printHintBox('text to display for
"Tomorrow"') +
760 '
<hr><table><tr><td>Show
"Now" As Text:
<br><input name=
"settings.showNowAsText" type=
"checkbox" value=
"true" ' + (showNowAsText ? '
checked=
"checked"' : '') + '
/></td>' + printHintBox('if enabled, the appointment time will be shown as
"Now" instead of
"12:00"') +
761 '
<hr><table><tr><td>"Now" Text:
<br><input class=
"textInput" name=
"settings.nowText" type=
"text" value=
"' + nowText + '" /></td>' + printHintBox('text to display for
"Now"') +
762 '
<hr><table><tr><td>Date Separator:
<br><input class=
"textInput" name=
"settings.dateSeparator" type=
"text" value=
"' + dateSeparator + '" /></td>' + printHintBox('separator for dates. e.g.
"31.12" or
"31/12"') +
763 '
<hr><table><tr><td>Date Format:
<br><select name=
"settings.dateFormat" size=
"1">' +
764 '
<option label=
"auto detect"' + (dateFormat == 'auto' ? '
selected=
"selected"' : '') + '
>auto
</option>' +
765 '
<option label=
"MMDD"' + (dateFormat == 'MMDD' ? '
selected=
"selected"' : '') + '
>MMDD
</option>' +
766 '
<option label=
"DDMM"' + (dateFormat == 'DDMM' ? '
selected=
"selected"' : '') + '
>DDMM
</option>' +
767 '
</select></div>' + printHintBox('how dates will be displayed. \'auto\' will autodetect your phone\'s date format setting. \'MMDD\' will write month first, \'DDMM\' will write day first') + '
</tr>' +
768 '
<hr><table><tr><td>Weekday Length:
<br><input class=
"textInput" name=
"settings.weekDayLength" type=
"text" value=
"' + weekDayLength + '" /></td>' + printHintBox('defines how many characters of the weekday will be shown. E.g.
2 will cut
"Friday" to
"Fr"') +
769 '
<hr><table><tr><td>Update Data Interval:
<br><input class=
"textInput" name=
"settings.updateDataInterval" type=
"text" value=
"' + updateDataInterval + '" /></td>' + printHintBox('how many minutes to wait before updating the displayed data. The higher the number, the less battery is used') +
770 '
<hr><table><tr><td>Calendar Application UID:
<br><input class=
"textInput" name=
"settings.calendarApp" type=
"text" value=
"0x' + calendarApp.toString(16) + '" /></td>' + printHintBox('UID of the calendar app to run when clicking the widget.
0x10005901 = buildin calendar,
0x20004ec1 = Epocware Handy Calendar') +
771 '
<hr><table><tr><td>Events Per Widget:
<br><input class=
"textInput" name=
"settings.eventsPerWidget" type=
"text" value=
"' + eventsPerWidget + '" /></td>' + printHintBox('number of events to show per widget. Default is
4') +
772 '
<hr><table><tr><td>Show Nothing Text:
<br><input name=
"settings.showNothingText" type=
"checkbox" value=
"true" ' + (showNothingText ? '
checked=
"checked"' : '') + '
/></td>' + printHintBox('if enabled, show a text if no events are in the list') +
773 '
<hr><table><tr><td>"nothing" Text:
<br><input class=
"textInput" name=
"settings.nothingText" type=
"text" value=
"' + nothingText + '" /></td>' + printHintBox('text to show when no events are in the list') +
774 '
<hr><table><tr><td>Enable Daylight Saving:
<br><input name=
"settings.enableDaylightSaving" type=
"checkbox" value=
"true" ' + (enableDaylightSaving ? '
checked=
"checked"' : '') + '
/></td>' + printHintBox('enable this if you are in a timezone that has daylight saving time (+
1h)') +
775 '
<hr style=
"margin-bottom:60px;"><h1 class=
"title">CSS Styles
</h1>' +
776 '
<hr><table><tr><td>.background:
<br><input class=
"textInput" name=
"settings.cssStyle_background" type=
"text" value=
"' + cssStyle_background + '" /></td>' + printHintBox('Defines the background of the widget. If you want to use a background image, enable
"useBackgroundImage" instead. For the default themes, black, gray, and light blue, codes are #
292029, #e7dfe7, #
009aef') +
777 '
<hr><table><tr><td>.weekDay:
<br><input class=
"textInput" name=
"settings.cssStyle_weekDay" type=
"text" value=
"' + cssStyle_weekDay + '" /></td>' + printHintBox('Defines the appearance of all week day texts') +
778 '
<hr><table><tr><td>.date:
<br><input class=
"textInput" name=
"settings.cssStyle_date" type=
"text" value=
"' + cssStyle_date + '" /></td>' + printHintBox('Defines the appearance of all date texts') +
779 '
<hr><table><tr><td>.today:
<br><input class=
"textInput" name=
"settings.cssStyle_today" type=
"text" value=
"' + cssStyle_today + '" /></td>' + printHintBox('Defines the appearance of
"Today" text') +
780 '
<hr><table><tr><td>.tomorrow:
<br><input class=
"textInput" name=
"settings.cssStyle_tomorrow" type=
"text" value=
"' + cssStyle_tomorrow + '" /></td>' + printHintBox('Defines the appearance of
"Tomorrow" text') +
781 '
<hr><table><tr><td>.time:
<br><input class=
"textInput" name=
"settings.cssStyle_time" type=
"text" value=
"' + cssStyle_time + '" /></td>' + printHintBox('Defines the appearance of all time texts') +
782 '
<hr><table><tr><td>.now:
<br><input class=
"textInput" name=
"settings.cssStyle_now" type=
"text" value=
"' + cssStyle_now + '" /></td>' + printHintBox('Defines the appearance of
"Now" text') +
783 '
<hr><table><tr><td>.description:
<br><input class=
"textInput" name=
"settings.cssStyle_description" type=
"text" value=
"' + cssStyle_description + '" /></td>' + printHintBox('Defines the appearance of all event descriptions') +
784 '
<hr><table><tr><td>.icon:
<br><input class=
"textInput" name=
"settings.cssStyle_icon" type=
"text" value=
"' + cssStyle_icon + '" /></td>' + printHintBox('Defines size and appearance of icons') +
785 '
<hr style=
"margin-bottom:60px;"><input name=
"reset" type=
"button" value=
"Restore Defaults" onclick=
"javascript:restoreDefaultSettings();showSettings();" />' +
789 function changeCssClass(classname, properties)
791 for(var i =
0; i < document.styleSheets[
0]['cssRules'].length; i++)
793 if (document.styleSheets[
0]['cssRules'][i].selectorText == classname) {
794 //alert(document.styleSheets[
0]['cssRules'][i].cssText);
795 //document.styleSheets[
0]['cssRules'][i].cssText = classname + ' { ' + properties + ' }';
796 document.styleSheets[
0].deleteRule(i);
797 //document.styleSheets[
0].insertRule(classname + ' { ' + properties + ' }',
0);
798 document.styleSheets[
0].insertRule(classname + ' { ' + properties + ' }', document.styleSheets[
0]['cssRules'].length);
799 //document.styleSheets[
0]['cssRules'][i].style.cssText = classname + ' { ' + properties + ' }';
800 //alert(document.styleSheets[
0]['cssRules'][i].cssText);
801 //alert(document.styleSheets[
0]['cssRules'][i].cssText + '\n'+ classname + ' { ' + properties + ' }');
807 function updateCssClasses()
809 changeCssClass(
".background", cssStyle_background);
810 changeCssClass(
".weekDay", cssStyle_weekDay);
811 changeCssClass(
".date", cssStyle_date);
812 changeCssClass(
".today", cssStyle_today);
813 changeCssClass(
".tomorrow", cssStyle_tomorrow);
814 changeCssClass(
".time", cssStyle_time);
815 changeCssClass(
".now", cssStyle_now);
816 changeCssClass(
".description", cssStyle_description);
817 changeCssClass(
".icon", cssStyle_icon);
820 function restoreDefaultSettings()
824 useBackgroundImage = true;
825 showCombinedDateTime = false;
827 showTodayAsText = true;
829 tomorrowText = 'Tomorrow';
830 showNowAsText = true;
835 updateDataInterval =
5;
836 calendarApp =
0x10005901;
838 showNothingText = true;
839 nothingText = 'No further events within ' + monthRange + ' months';
840 enableDaylightSaving = true;
842 cssStyle_background =
"color:#ffffff; background-color:#000000";
843 cssStyle_weekDay =
"";
845 cssStyle_today =
"color:#ff0000";
846 cssStyle_tomorrow =
"color:#0000ff";
848 cssStyle_now =
"color:#ff00ff";
849 cssStyle_description =
"";
850 cssStyle_icon =
"width:15px; height:15px";
853 function loadSettings()
855 if (widget.preferenceForKey('monthRange'))
856 monthRange = Number(widget.preferenceForKey('monthRange'));
860 if (widget.preferenceForKey('includeTodos'))
861 includeTodos = (widget.preferenceForKey('includeTodos') == 'true');
865 if (widget.preferenceForKey('useBackgroundImage'))
866 useBackgroundImage = (widget.preferenceForKey('useBackgroundImage') == 'true');
868 useBackgroundImage = true;
870 if (widget.preferenceForKey('showCombinedDateTime'))
871 showCombinedDateTime = (widget.preferenceForKey('showCombinedDateTime') == 'true');
873 showCombinedDateTime = false;
875 if (widget.preferenceForKey('showLocation'))
876 showLocation = (widget.preferenceForKey('showLocation') == 'true');
880 if (widget.preferenceForKey('showTodayAsText'))
881 showTodayAsText = (widget.preferenceForKey('showTodayAsText') == 'true');
883 showTodayAsText = true;
885 if (widget.preferenceForKey('todayText'))
886 todayText = widget.preferenceForKey('todayText');
890 if (widget.preferenceForKey('tomorrowText'))
891 tomorrowText = widget.preferenceForKey('tomorrowText');
893 tomorrowText = 'Tomorrow';
895 if (widget.preferenceForKey('showNowAsText'))
896 showNowAsText = (widget.preferenceForKey('showNowAsText') == 'true');
898 showNowAsText = true;
900 if (widget.preferenceForKey('nowText'))
901 nowText = widget.preferenceForKey('nowText');
905 if (widget.preferenceForKey('dateSeparator'))
906 dateSeparator = widget.preferenceForKey('dateSeparator');
910 if (widget.preferenceForKey('dateFormat'))
911 dateFormat = widget.preferenceForKey('dateFormat');
915 if (widget.preferenceForKey('weekDayLength'))
916 weekDayLength = Number(widget.preferenceForKey('weekDayLength'));
920 if (widget.preferenceForKey('updateDataInterval'))
921 updateDataInterval = Number(widget.preferenceForKey('updateDataInterval'));
923 updateDataInterval =
5;
925 if (widget.preferenceForKey('calendarApp'))
926 calendarApp = Number(widget.preferenceForKey('calendarApp'));
928 calendarApp =
0x10005901;
930 if (widget.preferenceForKey('eventsPerWidget'))
931 eventsPerWidget = Number(widget.preferenceForKey('eventsPerWidget'));
935 if (widget.preferenceForKey('showNothingText'))
936 showNothingText = (widget.preferenceForKey('showNothingText') == 'true');
938 showNothingText = true;
940 if (widget.preferenceForKey('nothingText'))
941 nothingText = widget.preferenceForKey('nothingText');
943 nothingText = 'No further events within ' + monthRange + ' months';
945 if (widget.preferenceForKey('enableDaylightSaving'))
946 enableDaylightSaving = (widget.preferenceForKey('enableDaylightSaving') == 'true');
948 enableDaylightSaving = true;
952 if (widget.preferenceForKey('cssStyle_background'))
953 cssStyle_background = widget.preferenceForKey('cssStyle_background');
955 cssStyle_background =
"color:#ffffff; background-color:#000000";
957 if (widget.preferenceForKey('cssStyle_weekDay'))
958 cssStyle_weekDay = widget.preferenceForKey('cssStyle_weekDay');
960 cssStyle_weekDay =
"";
962 if (widget.preferenceForKey('cssStyle_date'))
963 cssStyle_date = widget.preferenceForKey('cssStyle_date');
967 if (widget.preferenceForKey('cssStyle_today'))
968 cssStyle_today = widget.preferenceForKey('cssStyle_today');
970 cssStyle_today =
"color:#ff0000";
972 if (widget.preferenceForKey('cssStyle_tomorrow'))
973 cssStyle_tomorrow = widget.preferenceForKey('cssStyle_tomorrow');
975 cssStyle_tomorrow =
"color:#0000ff";
977 if (widget.preferenceForKey('cssStyle_time'))
978 cssStyle_time = widget.preferenceForKey('cssStyle_time');
982 if (widget.preferenceForKey('cssStyle_now'))
983 cssStyle_now = widget.preferenceForKey('cssStyle_now');
985 cssStyle_now =
"color:#ff00ff";
987 if (widget.preferenceForKey('cssStyle_description'))
988 cssStyle_description = widget.preferenceForKey('cssStyle_description');
990 cssStyle_description =
"";
992 if (widget.preferenceForKey('cssStyle_icon'))
993 cssStyle_icon = widget.preferenceForKey('cssStyle_icon');
995 cssStyle_icon =
"width:15px; height:15px";
998 function saveSettings()
1000 widget.setPreferenceForKey(monthRange.toString(), 'monthRange');
1001 widget.setPreferenceForKey(includeTodos ? 'true' : 'false', 'includeTodos');
1002 widget.setPreferenceForKey(useBackgroundImage ? 'true' : 'false', 'useBackgroundImage');
1003 widget.setPreferenceForKey(showCombinedDateTime ? 'true' : 'false', 'showCombinedDateTime');
1004 widget.setPreferenceForKey(showLocation ? 'true' : 'false', 'showLocation');
1005 widget.setPreferenceForKey(showTodayAsText ? 'true' : 'false', 'showTodayAsText');
1006 widget.setPreferenceForKey(todayText, 'todayText');
1007 widget.setPreferenceForKey(tomorrowText, 'tomorrowText');
1008 widget.setPreferenceForKey(showNowAsText ? 'true' : 'false', 'showNowAsText');
1009 widget.setPreferenceForKey(nowText, 'nowText');
1010 widget.setPreferenceForKey(dateSeparator, 'dateSeparator');
1011 widget.setPreferenceForKey(dateFormat, 'dateFormat');
1012 widget.setPreferenceForKey(weekDayLength.toString(), 'weekDayLength');
1013 widget.setPreferenceForKey(updateDataInterval.toString(), 'updateDataInterval');
1014 widget.setPreferenceForKey(calendarApp.toString(), 'calendarApp');
1015 widget.setPreferenceForKey(eventsPerWidget.toString(), 'eventsPerWidget');
1016 widget.setPreferenceForKey(showNothingText ? 'true' : 'false', 'showNothingText');
1017 widget.setPreferenceForKey(nothingText, 'nothingText');
1018 widget.setPreferenceForKey(enableDaylightSaving ? 'true' : 'false', 'enableDaylightSaving');
1020 widget.setPreferenceForKey(cssStyle_background, 'cssStyle_background');
1021 widget.setPreferenceForKey(cssStyle_weekDay, 'cssStyle_weekDay');
1022 widget.setPreferenceForKey(cssStyle_date, 'cssStyle_date');
1023 widget.setPreferenceForKey(cssStyle_today, 'cssStyle_today');
1024 widget.setPreferenceForKey(cssStyle_tomorrow, 'cssStyle_tomorrow');
1025 widget.setPreferenceForKey(cssStyle_time, 'cssStyle_time');
1026 widget.setPreferenceForKey(cssStyle_now, 'cssStyle_now');
1027 widget.setPreferenceForKey(cssStyle_description, 'cssStyle_description');
1028 widget.setPreferenceForKey(cssStyle_icon, 'cssStyle_icon');
1031 function toggleVisibility(elementId)
1033 if (document.getElementById(elementId).style.display ==
"none")
1034 document.getElementById(elementId).style.display =
"block";
1036 document.getElementById(elementId).style.display =
"none";
1040 function printHintBox(text)
1043 return '
<td width=
"1%" align=
"right" onclick=
"javascript:toggleVisibility(\'info' + uniqueId + '\')">Help
</td></tr></table>'+
1044 '
<div class=
"settingsInfo" id=
"info' + uniqueId + '">' + text + '
</div>';
1047 function showAbout()
1050 document.getElementById(
"homescreenView").style.display =
"none";
1051 document.getElementById(
"fullscreenView").style.display =
"none";
1052 document.getElementById(
"aboutView").style.display =
"block";
1053 document.getElementById(
"settingsView").style.display =
"none";
1055 window.menu.setLeftSoftkeyLabel(
" ", function(){});
1056 window.menu.setRightSoftkeyLabel(
"Back", function()
1062 //document.getElementById(
"aboutView").innerHTML = 'aboutView';
1063 document.getElementById(
"name").innerHTML =
"Coming Next " + version;
1066 function updateFullscreen()
1070 function showFullscreen()
1072 document.getElementById(
"homescreenView").style.display =
"none";
1073 document.getElementById(
"fullscreenView").style.display =
"block";
1074 document.getElementById(
"aboutView").style.display =
"none";
1075 document.getElementById(
"settingsView").style.display =
"none";
1080 function updateHomescreen()
1082 if (useBackgroundImage) {
1083 // check for screen rotation
1084 if (orientation != 'portrait' && screen.width ==
360 && screen.height ==
640) {
1085 window.widget.prepareForTransition(
"fade");
1086 orientation = 'portrait';
1087 document.getElementById('body').style.backgroundImage = 'url(background_' + orientation + '.png)';
1088 document.getElementById('body').style.backgroundColor = 'none';
1089 window.widget.performTransition();
1090 } else if (orientation != 'landscape' && screen.width ==
640 && screen.height ==
360) {
1091 window.widget.prepareForTransition(
"fade");
1092 orientation = 'landscape';
1093 document.getElementById('body').style.backgroundImage = 'url(background_' + orientation + '.png)';
1094 document.getElementById('body').style.backgroundColor = 'none';
1095 window.widget.performTransition();
1100 function showHomescreen()
1102 document.getElementById(
"homescreenView").style.display =
"block";
1103 document.getElementById(
"fullscreenView").style.display =
"none";
1104 document.getElementById(
"aboutView").style.display =
"none";
1105 document.getElementById(
"settingsView").style.display =
"none";
1111 <style type=
"text/css">
1112 table { margin:
0px; padding:
0px; border-spacing:
0px; }
1113 td { padding:
0px
5px
0px
0px; white-space:nowrap; overflow:hidden; }
1114 hr { w_idth:
100%; color:#ffffff; background-color:#ffffff; height:
1px; text-align:left; border-style:none; }
1115 .settingsInfo { display:none; font-style:italic; }
1116 .title { font-weight:bold; font-size:
14pt; }
1117 .textInput { width:
90%; }
1118 #homescreenView { width:
315px; height:
91px; overflow:hidden; }
1119 #calendarList { position:absolute; left:
10px; top:
4px; width:
295px; height:
75px; overflow:hidden; }
1120 #name { text-align:center; }
1121 #appicon { display: block; margin-left: auto; margin-right: auto; margin-top:
50px; }
1122 #smallappicon { width:
22px; height:
22px; margin-right:
10px; float:left; }
1127 <body id=
"body" class=
"background">
1128 <div id=
"homescreenView">
1129 <div id=
"calendarList"></div>
1131 <div id=
"fullscreenView" style=
"display:none">
1132 <img src=
"Icon.png" id=
"smallappicon" onClick=
"javascript:launchCalendar()">
1133 <h1 class=
"title" onClick=
"javascript:launchCalendar()">Coming Next
</h1>
1135 <div id=
"fullscreenCalendarList">loading...
</div>
1137 <div id=
"settingsView" style=
"display:none">
1138 <img src=
"Icon.png" id=
"smallappicon">
1139 <h1 class=
"title">Settings
</h1>
1141 <div id=
"settingsList"></div>
1143 <div id=
"aboutView" style=
"display:none">
1144 <img src=
"Icon.png" id=
"appicon">
1145 <h1 id=
"name">Coming Next
</h1>
1147 <p>Created by Dr. Cochambre and Michael Prager.
</p>
1148 <p>This software is open source and licensed under the GPLv3.
</p>
1149 <p>Visit https://sourceforge.net/projects/comingnext/ for free updates.
</p>