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 /* -----------------------------------------------------------------------
7 Note: you no longer have to edit this file, you can change the preferences
9 --------------------------------------------------------------------------- */
11 <title>Coming Next
</title>
13 <style type=
"text/css">
14 .background { color:#ffffff; background-color:#
000000 } /* Defines the background of the widget. If you want to use a background image, set useBackgroundImage = true below */
15 /* for the default themes, black, gray, and light blue, codes are #
292029, #e7dfe7, #
009aef */
16 .weekDay { } /* Defines the appearance of all week day texts */
17 .date { } /* Defines the appearance of all date texts */
18 .today { color:#ff0000; } /* Defines the appearance of
"Today" text */
19 .tomorrow { color:#
0000ff; } /* Defines the appearance of
"Tomorrow" text */
20 .time { } /* Defines the appearance of all time texts */
21 .now { color:#ff00ff; } /* Defines the appearance of
"Now" text */
22 .description { } /* Defines the appearance of all event descriptions */
23 .icon { width:
15px; height:
15px; } /* Defines size and appearance of icons */
27 var monthRange =
2; // number of months to include in the event list
28 var includeTodos = true; // disable to remove ToDos from event list
29 var useBackgroundImage = true; // use background_portrait.png and background_landscape.png to fake transparency. Set to
"false" to use a solid background color
30 var showCombinedDateTime = false;// only show the time for events happening today, otherwise just show the date
31 var showLocation = true; // show the location for meeting events
32 var showTodayAsText = true; // if enabled, the current date will be shown as
"Today" instead of
"31.12"
33 var todayText = 'Today'; // text to display for
"Today"
34 var tomorrowText = 'Tomorrow'; // text to display for
"Tomorrow"
35 var showNowAsText = true; // if enabled, the appointment time will be shown as
"Now" instead of
"12:00"
36 var nowText = 'Now'; // text to display for
"Now"
37 var dateSeparator = '.'; // separator for dates. e.g.
"31.12" or
"31/12"
38 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
39 var weekDayLength =
2; // defines how many characters of the weekday will be shown. E.g.
2 will cut
"Friday" to
"Fr"
40 var updateDataInterval =
5; // how many minutes to wait before updating the displayed data. The higher the number, the less battery is used
41 var calendarApp =
0x10005901; // UID of the calendar app to run when clicking the widget.
0x10005901 = buildin calendar,
0x20004ec1 = Epocware Handy Calendar
42 var eventsPerWidget =
4; // number of events to show per widget. Default is
4
43 var showNothingText = true; // if set to
"true", show a text if no events are in the list
44 var nothingText = 'No further events within ' + monthRange + ' months'; // text to show when no events are in the list
45 var enableDaylightSaving = true;// enable this if you are in a timezone that has daylight saving time (+
1h)
47 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
48 var cssStyle_weekDay =
""; // Defines the appearance of all week day texts
49 var cssStyle_date =
""; // Defines the appearance of all date texts
50 var cssStyle_today =
"color:#ff0000"; // Defines the appearance of
"Today" text
51 var cssStyle_tomorrow =
"color:#0000ff"; // Defines the appearance of
"Tomorrow" text
52 var cssStyle_time =
""; // Defines the appearance of all time texts
53 var cssStyle_now =
"color:#ff00ff"; // Defines the appearance of
"Now" text
54 var cssStyle_description =
""; // Defines the appearance of all event descriptions
55 var cssStyle_icon =
"width:15px; height:15px"; // Defines size and appearance of icons
57 //-------------------------------------------------------
58 // Nothing of interest from here on...
59 //-------------------------------------------------------
60 var panelNum =
0; // use
1 for second panel
62 var calendarService = null;
63 var cacheEntriesHtml = [];
64 var months_translated = [];
67 var mode =
0; //
0 = homescreen,
1 = fullscreen,
2 = settings,
3 = about
69 // vars for daylight saving time
70 var daylightsavingWinter =
0;
71 var daylightsavingSummer =
0;
72 var summertime = false;
75 window.onresize = updateScreen;
76 window.onshow = updateScreen;
78 function isLeapYear( year ) {
79 if (( year %
4 ==
0 && year %
100 !=
0 ) || year %
400 ==
0 )
85 function calcLeapYear(year, days)
93 function subToSunday(myDate, year, days, prevMonthDays)
95 for (i = myDate.getDay(); i
> 0 ;i--)
97 days -= prevMonthDays;
98 days = isLeapYear(year) ? --days : days;
102 function calcDaylightSaving()
104 var thisYearS = new Date(now.getFullYear(),
3,
0,
0,
0,
0 );
105 var thisYearW = new Date(now.getFullYear(),
10,
0,
0,
0,
0 );
106 var nextYearS = new Date(now.getFullYear() +
1,
3,
0,
0,
0,
0 );
107 var nextYearW = new Date(now.getFullYear() +
1,
10,
0,
0,
0,
0 );
111 thisYearSDays = nextYearSDays =
90;
112 thisYearWDays = nextYearWDays =
304;
114 thisYearSDays = calcLeapYear(now.getFullYear(), thisYearSDays);
115 thisYearWDays = calcLeapYear(now.getFullYear(), thisYearWDays);
116 nextYearSDays = calcLeapYear(now.getFullYear() +
1, nextYearSDays);
117 nextYearWDays = calcLeapYear(now.getFullYear() +
1, nextYearWDays);
119 thisYearSDays = subToSunday(thisYearS, now.getFullYear(), thisYearSDays,
59);
120 thisYearWDays = subToSunday(thisYearW, now.getFullYear(), thisYearWDays,
273);
121 nextYearSDays = subToSunday(nextYearS, now.getFullYear() +
1, nextYearSDays,
59);
122 nextYearWDays = subToSunday(nextYearW, now.getFullYear() +
1, nextYearWDays,
273);
124 daylightsavingSummer = new Date (now.getFullYear(),
03-
1, thisYearSDays,
2,
0,
0);
125 daylightsavingWinter = new Date (now.getFullYear(),
10-
1, thisYearWDays,
2,
0,
0);
126 if (daylightsavingSummer < now) {
127 daylightsavingSummer = new Date (now.getFullYear()+
1,
03-
1, nextYearSDays,
2,
0,
0);
130 if (daylightsavingWinter < now) {
131 daylightsavingWinter = new Date (now.getFullYear()+
1,
10-
1, nextYearWDays,
2,
0,
0);
134 if (summer && !winter)
140 function error(message)
142 console.info('Error: ' + message);
143 document.getElementById(
"calendarList").innerHTML = 'Error: ' + message;
146 function isToday(date)
148 if (date.getDate() == now.getDate() && date.getMonth() == now.getMonth())
153 function isTomorrow(date)
155 if ((date.getDate() == now.getDate() +
1 && date.getMonth() == now.getMonth()) ||
156 (date.getDate() ==
0 && date.getMonth() == now.getMonth() +
1) ||
157 (date.getDate() ==
0 && date.getMonth() == now.getMonth() +
1 && date.getYear() == now.getYear() +
1))
162 function collectLocales()
164 var tmpyear = ((panelNum ==
0) ?
2000 :
2001);
167 if (months_translated.length
> 0)
169 for (month =
0; month <
12; month++) {
170 var startDate = new Date(tmpyear, month,
15);
172 var item = new Object();
173 item.Type =
"DayEvent";
174 item.StartTime = startDate;
175 item.Summary =
"__temp" + month;
177 var criteria = new Object();
178 criteria.Type =
"CalendarEntry";
179 criteria.Item = item;
182 var result = calendarService.IDataSource.Add(criteria);
183 if (result.ErrorCode)
184 error(result.ErrorMessage);
186 error(
"collectLocales: " + e + ', line ' + e.line);
190 var startTime = new Date(tmpyear,
0,
1);
191 var endTime = new Date(tmpyear,
11,
31);
192 var listFiltering = {
193 Type:'CalendarEntry',
195 StartRange: startTime,
197 SearchText: '__temp',
201 var result = calendarService.IDataSource.GetList(listFiltering);
202 if (result.ErrorCode) {
203 error(result.ErrorMessage);
206 var list = result.ReturnValue;
208 error(e + ', line ' + e.line);
211 var ids = new Array();
217 while (list && (entry = list.getNext()) != undefined) {
218 dateArr = entry.StartTime.replace(/,/g,'').replace(/\./g,':').replace(/ /g,' ').split(' ');
219 var day = dateArr[
1];
220 var month = dateArr[
2];
221 var year = dateArr[
3];
223 // make sure month is set properly
224 if (isNaN(parseInt(day))) {
228 } else if (isNaN(parseInt(year))) {
234 console.info(entry.StartTime + ' -
> ' + month + ' ' + counter);
235 ids[counter] = entry.id;
236 months_translated[month] = counter +
1;
240 error(e + ', line ' + e.line);
245 var criteria = new Object();
246 criteria.Type =
"CalendarEntry";
251 var result = calendarService.IDataSource.Delete(criteria);
252 if (result.ErrorCode)
253 error(result.ErrorMessage);
255 error('deleting temp calendar entries:' + e + ', line ' + e.line);
260 function requestNotification()
262 var criteria = new Object();
263 criteria.Type =
"CalendarEntry";
266 var result = calendarService.IDataSource.RequestNotification(criteria, callback);
267 if (result.ErrorCode)
268 error('loading Calendar items list');
270 error(
"requestNotification: " + e + ', line ' + e.line);
274 function callback(transId, eventCode, result)
279 function parseDate(dateString)
282 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:
283 Wednesday,
26 August,
2009 24:
00:
00
284 Wednesday,
26 August,
2009 12:
00:
00 am
285 Wednesday, August
26,
2009 12:
00:
00 am
286 Wednesday,
2009 August,
26 12:
00:
00 am
287 Wednesday,
2009 August,
28 8.00.00 pm
288 Wednesday,
2009 August,
28 08:
00:
00 PM
291 if (dateString ==
"" || dateString == null)
293 var dateArr = dateString.replace(/,/g,'').replace(/\./g,':').replace(/ /g,' ').split(' ');
294 if (dateArr.length !=
5 && dateArr.length !=
6)
298 var weekDay = dateArr[
0];
299 var day = dateArr[
1];
300 var month = dateArr[
2];
301 var year = dateArr[
3];
302 // make sure month is set properly
303 if (isNaN(parseInt(day))) {
307 } else if (isNaN(parseInt(year))) {
312 // make sure day and year are set properly
313 if (Number(day)
> Number(year)) {
318 month = months_translated[month];
321 var timeArr = dateArr[
4].split(':');
322 if (timeArr.length !=
3)
324 var hours = Number(timeArr[
0]);
325 var minutes = Number(timeArr[
1]);
326 var seconds = Number(timeArr[
2]);
327 if (dateArr.length ==
6 && dateArr[
5].toLowerCase() == 'pm' && hours <
12)
329 if (dateArr.length ==
6 && dateArr[
5].toLowerCase() == 'am' && hours ==
12)
332 console.info('year=' + year + ' month=' + month + ' day=' + day + ' hours=' + hours + ' minutes=' + minutes+ ' seconds=' + seconds);
334 // take care of daylight saving time
335 if (enableDaylightSaving) {
336 var date = new Date(year, month -
1, day, hours, minutes, seconds);
337 if (summertime && date
> daylightsavingWinter && date < daylightsavingSummer)
339 else if (!summertime && date
> daylightsavingSummer && date < daylightsavingWinter)
343 return new Date(year, month -
1, day, hours, minutes, seconds);
346 // 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"
347 function formatDate(date, format)
349 var day = date.getDate().toString();
350 var month = (date.getMonth() +
1).toString();
351 while (day.length <
2) { day = '
0' + day; }
352 while (month.length <
2) { month = '
0' + month; }
354 if (showTodayAsText && isToday(date))
355 return '
<span class=
"today">' + todayText + '
</span>';
356 if (showTodayAsText && isTomorrow(date))
357 return '
<span class=
"tomorrow">' + tomorrowText + '
</span>';
359 var dateArr = format.replace(/,/g,'').replace(/\./g,':').replace(/ /g,' ').split(' ');
360 if (dateArr.length !=
5 && dateArr.length !=
6) {
361 // we don't know how to format this
362 if (dateFormat == 'auto' || dateFormat == 'DDMM')
363 return day + dateSeparator + month;
365 return month + dateSeparator + day;
369 if (dateFormat == 'MMDD')
371 else if (dateFormat == 'DDMM')
374 // dateFormat == 'auto', try to detect system setting
376 var day_ = dateArr[
1];
377 var month_ = dateArr[
2];
378 var year_ = dateArr[
3];
379 // make sure month is set properly
380 if (isNaN(parseInt(day_))) {
385 } else if (isNaN(parseInt(year_))) {
391 // make sure day and year are set properly
392 if (Number(day_)
> Number(year_))
397 return day + dateSeparator + month;
399 return month + dateSeparator + day;
402 function formatTime(date)
404 // date is a Date() object
405 date.setSeconds(
0); // we don't care about seconds
406 var time = date.toLocaleTimeString().replace(/[\.:]
00/, ''); // remove seconds from string
407 if (time.replace(/\./, ':').split(':')[
0].length <
2)
409 if (showNowAsText && date.getTime() == now.getTime())
410 time = '
<span class=
"now">' + nowText + '
</span>';
414 function updateData()
416 calcDaylightSaving();
418 // meetings have time
419 // 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
421 var meetingListFiltering = {
422 Type:'CalendarEntry',
424 StartRange: (new Date(now.getFullYear(), now.getMonth(), now.getDate(),
0,
0,
0)),
425 EndRange: (new Date(now.getFullYear(), now.getMonth() + monthRange, now.getDate(),
0,
0,
0))
428 var meetingResult = calendarService.IDataSource.GetList(meetingListFiltering);
429 var meetingList = meetingResult.ReturnValue;
431 // todos don't, they start on
00:
00 hrs., but should be visible anyway
432 // this will generate a list of passed todos. We have to check if they have been marked as
"done" yet
434 var todayTodoListFiltering = {
435 Type:'CalendarEntry',
438 StartRange: (new Date(now.getFullYear() -
1, now.getMonth(), now.getDate(),
0,
0,
0)),
439 EndRange: (new Date(now.getFullYear(), now.getMonth(), now.getDate(),
0,
0,
1))
442 var todayTodoResult = calendarService.IDataSource.GetList(todayTodoListFiltering);
443 var todayTodoList = todayTodoResult.ReturnValue;
444 var entryLists = [todayTodoList, meetingList];
446 var entryLists = [meetingList];
449 error('loading Calendar items list:' + e + ', line ' + e.line);
458 var entriesHtml = '
<table>';
462 max = ((panelNum ==
0) ? eventsPerWidget :
2 * eventsPerWidget);
464 max =
30; // we can display a lot more events in fullscreen mode
466 // the first outer loop iteration is for passed ToDos, the second loop is for all upcomming events (may also include ToDos)
467 for (var i=
0; counter < max && i < entryLists.length; i++) {
468 while (counter < max && (entry = entryLists[i].getNext()) != undefined) {
471 // output event info for debugging
473 'event: Id=' + entry.id +
474 ',Type=' + entry.Type +
475 ',Summary=' + entry.Summary +
476 ',Location=' + entry.Location +
477 ',Status=' + entry.Status +
478 ',StartTime=' + entry.StartTime +
479 ',EndTime=' + entry.EndTime +
480 ',InstanceStartTime=' + entry.InstanceStartTime +
481 ',InstanceEndTime=' + entry.InstanceEndTime
484 // we don't want ToDos when includeTodos == false or when they are completed
485 if (entry.Type == 'ToDo' && (entry.Status ==
"TodoCompleted" || !includeTodos)) {
486 console.info('skipping ' + entry.id );
491 // make sure that we don't include an event twice (useful for ToDos that might come up twice)
492 if (eventIds[entry.id] ==
1) {
493 console.info('skipped (already included) ' + entry.id);
497 eventIds[entry.id] =
1;
499 // summary can be undefined!
500 var Summary = ((entry.Summary == null) ? '' : entry.Summary);
501 if (entry.Type == 'Meeting' && entry.Location != '' && showLocation)
502 Summary += ', ' + entry.Location;
504 // fix by yves: determine start and end dates/times
505 entryStartTime = ((entry.InstanceStartTime == null) ? entry.StartTime : entry.InstanceStartTime);
506 entryEndTime = ((entry.InstanceEndTime == null) ? entry.EndTime : entry.InstanceEndTime);
508 // there can be ToDos that have no date at all!
509 if (entry.Type == 'ToDo' && entry.EndTime == null)
510 entryDate =
""; // this will cause parseDate(entryDate) to return null;
512 entryDate = ((entry.Type == 'ToDo') ? entryEndTime : entryStartTime); // ToDo's use their EndTime, the rest use StartTime
514 // Convert date/time string to Date object
515 var date = parseDate(entryDate);
516 console.info('date: ' + date);
517 var endDate = ((entryEndTime == null) ? null : parseDate(entryEndTime));
518 console.info('endDate: ' + endDate);
520 // check if meeting event has already passed
521 if (entry.Type == 'Meeting') {
522 var compareTime = ((endDate == null) ? date.getTime() : endDate.getTime());
523 if (now.getTime()
> compareTime) {
524 console.info('skipping Meeting (already passed) ' + entry.id);
526 eventIds[entry.id] =
0;
531 // check if anniversary passed (not sure why they are in the list, the query was only for today - nokia?)
532 if (entry.Type == 'Anniversary') {
533 var tmp = new Date(now.getFullYear(), now.getMonth(), now.getDate(),
0,
0,
0);
534 if (date.getTime() < tmp.getTime()) {
535 console.info('skipping Anniversary (already passed) ' + entry.id);
537 eventIds[entry.id] =
0;
542 // fix DayEvents end time. End times are off by
1 Second. It's possible that the event has already passed
543 if (entry.Type == 'DayEvent' && endDate != null) {
544 endDate.setMinutes(endDate.getMinutes() -
1);
545 console.info('fixing DayEvent endDate: ' + endDate);
546 if (now.getTime()
> endDate.getTime()) {
547 console.info('event already passed ' + entry.id);
549 eventIds[entry.id] =
0;
554 // check if the event is currently taking place
555 if (entryStartTime != null && entryEndTime != null && date != null && endDate != null) {
556 // check if we are between start and endtime
557 if ((date.getTime() < now.getTime()) && (now.getTime() < endDate.getTime())) {
558 date = now; // change appointment date/time to now
559 console.info('event is currently taking place: ' + date);
563 // skip events for the first panel in case this is the second one and we're not in fullscreen mode
564 if (mode ==
0 && panelNum ==
1 && counter < eventsPerWidget +
1) {
565 console.info('skipping (already in first widget) ' + entry.id);
569 // generate html output
570 entriesHtml += '
<tr><td><img class=
"icon" src=
"' + entry.Type + '.png" /></td>';
572 // some languages have very strange locale date formats, can't parse all those. Also some todos don't have dates at all.
573 entriesHtml += '
<td colspan=
"4"><span class=
"date">' + entryDate + '
</span> ';
575 var weekDay = date.toLocaleDateString().substr(
0,weekDayLength);
576 var time = formatTime(date);
577 var dateStr = formatDate(date, entryDate);
578 if (entry.Type == 'ToDo' || entry.Type == 'Anniversary' || entry.Type == 'DayEvent' || entry.Type == 'Reminder') {
579 if ((isToday(date) || isTomorrow(date)) && showTodayAsText) // show weekday if the date string is not text. looks odd otherwise
580 entriesHtml += '
<td colspan=
"4" width=
"1px"><span class=
"date">' + dateStr + '
</span> ';
582 entriesHtml += '
<td class=
"weekDay" width=
"1px">' + weekDay + '
</td><td width=
"1px" class=
"date">' + dateStr + '
</td><td colspan=
"2">';
583 } else if (entry.Type == 'Meeting') {
584 if (showCombinedDateTime) {
586 entriesHtml += '
<td width=
"1px" colspan=
"4"><span class=
"today">' + time + '
</span> ';
587 else if (isTomorrow(date))
588 entriesHtml += '
<td width=
"1px" colspan=
"4"><span class=
"tomorrow">' + dateStr + '
</span> <span class=
"time">' + time + '
</span> ';
590 entriesHtml += '
<td width=
"1px" class=
"weekDay">' + weekDay + '
</td><td width=
"1px" class=
"date">' + dateStr + '
</td><td colspan=
"2">';
592 if ((isToday(date) || isTomorrow(date)) && showTodayAsText)
593 entriesHtml += '
<td colspan=
"4" width=
"1px"><span class=
"today">' + dateStr + '
</span> <span class=
"time">' + time + '
</span> ';
595 entriesHtml += '
<td width=
"1px" class=
"weekDay">' + weekDay + '
</td><td width=
"1px" class=
"date">' + dateStr + '
</td><td width=
"1px" class=
"time">' + time + '
</td><td>';
599 entriesHtml += '
<span class=
"description">' + Summary + '
</span></td></tr>';
602 entriesHtml += '
</table>';
603 if (showNothingText && entriesHtml == '
<table></table>')
604 entriesHtml = '
<div style=
"width:295px; height:75px; text-align:center; line-height:75px; overflow:visible;">' + nothingText + '
</div>';
605 if (cacheEntriesHtml != entriesHtml) {
607 document.getElementById('calendarList').innerHTML = entriesHtml;
609 document.getElementById('fullscreenCalendarList').innerHTML = entriesHtml;
610 cacheEntriesHtml = entriesHtml;
613 error('displaying list:' + e + ', line ' + e.line);
618 function updateScreen()
620 // check if opening fullscreen
621 if( window.innerHeight
> 91 && mode ==
0) {
623 cacheEntriesHtml = '';
626 else if (window.innerHeight <=
91 && mode !=
0) {
628 cacheEntriesHtml = '';
638 function launchCalendar()
641 widget.openApplication(calendarApp,
"");
644 error('starting Calendar App');
652 // call calendar service
653 calendarService = device.getServiceObject(
"Service.Calendar",
"IDataSource");
655 error('loading Calendar service');
663 requestNotification();
664 window.setInterval('updateData()',
1000 *
60 * updateDataInterval);
669 if (useBackgroundImage)
670 // check for screen rotation every
3 secs
671 window.setInterval('updateScreen()',
1000 *
3);
674 function createMenu()
676 window.menu.setLeftSoftkeyLabel(
"",null);
677 window.menu.setRightSoftkeyLabel(
"",null);
679 var menuSettings = new MenuItem(
"Settings", id++);
680 var menuCallApp = new MenuItem(
"Open Calendar App", id++);
681 var menuAbout = new MenuItem(
"About", id++);
682 menuSettings.onSelect = showSettings;
683 menuAbout.onSelect = showAbout;
684 menuCallApp.onSelect = launchCalendar;
686 window.menu.append(menuCallApp);
687 window.menu.append(menuSettings);
688 window.menu.append(menuAbout);
691 function showSettings()
694 document.getElementById(
"homescreenView").style.display =
"none";
695 document.getElementById(
"fullscreenView").style.display =
"none";
696 document.getElementById(
"aboutView").style.display =
"none";
697 document.getElementById(
"settingsView").style.display =
"block";
699 window.menu.setLeftSoftkeyLabel(
"Save", function()
701 //document.forms[
0].elements[
"settings.monthRange"].value = monthRange;
702 monthRange = parseInt(document.forms[
0].elements[
"settings.monthRange"].value);
703 if (monthRange <
0 || monthRange
> 100)
705 includeTodos = document.forms[
0].elements[
"settings.includeTodos"].checked;
706 useBackgroundImage = document.forms[
0].elements[
"settings.useBackgroundImage"].checked;
707 showCombinedDateTime = document.forms[
0].elements[
"settings.showCombinedDateTime"].checked;
708 showLocation = document.forms[
0].elements[
"settings.showLocation"].checked;
709 showTodayAsText = document.forms[
0].elements[
"settings.showTodayAsText"].checked;
710 todayText = document.forms[
0].elements[
"settings.todayText"].value;
711 tomorrowText = document.forms[
0].elements[
"settings.tomorrowText"].value;
712 showNowAsText = document.forms[
0].elements[
"settings.showNowAsText"].checked;
713 nowText = document.forms[
0].elements[
"settings.nowText"].value;
714 dateSeparator = document.forms[
0].elements[
"settings.dateSeparator"].value;
715 dateFormat = document.forms[
0].elements[
"settings.dateFormat"].value;
716 if (dateFormat != 'auto' && dateFormat != 'DDMM' && dateFormat != 'MMDD')
718 weekDayLength = Number(parseInt(document.forms[
0].elements[
"settings.weekDayLength"].value));
719 if (weekDayLength <
0 || weekDayLength
> 20)
721 updateDataInterval = parseInt(document.forms[
0].elements[
"settings.updateDataInterval"].value);
722 if (updateDataInterval <
1 || updateDataInterval
> 1000)
723 updateDataInterval =
5;
724 calendarApp = parseInt(document.forms[
0].elements[
"settings.calendarApp"].value);
725 eventsPerWidget = parseInt(document.forms[
0].elements[
"settings.eventsPerWidget"].value);
726 if (eventsPerWidget <
1 || eventsPerWidget
> 10)
728 showNothingText = document.forms[
0].elements[
"settings.showNothingText"].checked;
729 nothingText = document.forms[
0].elements[
"settings.nothingText"].value;
730 enableDaylightSaving = document.forms[
0].elements[
"settings.enableDaylightSaving"].checked;
732 cssStyle_background = document.forms[
0].elements[
"settings.cssStyle_background"].value;
733 cssStyle_weekDay = document.forms[
0].elements[
"settings.cssStyle_weekDay"].value;
734 cssStyle_date = document.forms[
0].elements[
"settings.cssStyle_date"].value;
735 cssStyle_today = document.forms[
0].elements[
"settings.cssStyle_today"].value;
736 cssStyle_tomorrow = document.forms[
0].elements[
"settings.cssStyle_tomorrow"].value;
737 cssStyle_time = document.forms[
0].elements[
"settings.cssStyle_time"].value;
738 cssStyle_now = document.forms[
0].elements[
"settings.cssStyle_now"].value;
739 cssStyle_description = document.forms[
0].elements[
"settings.cssStyle_description"].value;
740 cssStyle_icon = document.forms[
0].elements[
"settings.cssStyle_icon"].value;
749 window.menu.setRightSoftkeyLabel(
"Cancel", function()
755 document.getElementById(
"settingsList").innerHTML =
757 '
<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') +
758 '
<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') +
759 '
<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') +
760 '
<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') +
761 '
<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') +
762 '
<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"') +
763 '
<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>' +
764 '
<hr><table><tr><td>"Tomorrow" Text:
<br><input class=
"textInput" name=
"settings.tomorrowText" type=
"text" value=
"' + tomorrowText + '" /></td>' + printHintBox('text to display for
"Tomorrow"') +
765 '
<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"') +
766 '
<hr><table><tr><td>"Now" Text:
<br><input class=
"textInput" name=
"settings.nowText" type=
"text" value=
"' + nowText + '" /></td>' + printHintBox('text to display for
"Now"') +
767 '
<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"') +
768 '
<hr><table><tr><td>Date Format:
<br><select name=
"settings.dateFormat" size=
"1">' +
769 '
<option label=
"auto detect"' + (dateFormat == 'auto' ? '
selected=
"selected"' : '') + '
>auto
</option>' +
770 '
<option label=
"MMDD"' + (dateFormat == 'MMDD' ? '
selected=
"selected"' : '') + '
>MMDD
</option>' +
771 '
<option label=
"DDMM"' + (dateFormat == 'DDMM' ? '
selected=
"selected"' : '') + '
>DDMM
</option>' +
772 '
</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>' +
773 '
<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"') +
774 '
<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') +
775 '
<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') +
776 '
<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') +
777 '
<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') +
778 '
<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') +
779 '
<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)') +
780 '
<hr style=
"margin-bottom:60px;"><h1 class=
"title">CSS Styles
</h1>' +
781 '
<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') +
782 '
<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') +
783 '
<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') +
784 '
<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') +
785 '
<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') +
786 '
<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') +
787 '
<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') +
788 '
<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') +
789 '
<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') +
790 '
<hr style=
"margin-bottom:60px;"><input name=
"reset" type=
"button" value=
"Restore Defaults" onclick=
"javascript:restoreDefaultSettings();showSettings();" />' +
794 function changeCssClass(classname, properties)
796 for(var i =
0; i < document.styleSheets[
0]['cssRules'].length; i++)
798 if (document.styleSheets[
0]['cssRules'][i].selectorText == classname) {
799 //alert(document.styleSheets[
0]['cssRules'][i].cssText);
800 //document.styleSheets[
0]['cssRules'][i].cssText = classname + ' { ' + properties + ' }';
801 document.styleSheets[
0].deleteRule(i);
802 //document.styleSheets[
0].insertRule(classname + ' { ' + properties + ' }',
0);
803 document.styleSheets[
0].insertRule(classname + ' { ' + properties + ' }', document.styleSheets[
0]['cssRules'].length);
804 //document.styleSheets[
0]['cssRules'][i].style.cssText = classname + ' { ' + properties + ' }';
805 //alert(document.styleSheets[
0]['cssRules'][i].cssText);
806 //alert(document.styleSheets[
0]['cssRules'][i].cssText + '\n'+ classname + ' { ' + properties + ' }');
812 function updateCssClasses()
814 changeCssClass(
".background", cssStyle_background);
815 changeCssClass(
".weekDay", cssStyle_weekDay);
816 changeCssClass(
".date", cssStyle_date);
817 changeCssClass(
".today", cssStyle_today);
818 changeCssClass(
".tomorrow", cssStyle_tomorrow);
819 changeCssClass(
".time", cssStyle_time);
820 changeCssClass(
".now", cssStyle_now);
821 changeCssClass(
".description", cssStyle_description);
822 changeCssClass(
".icon", cssStyle_icon);
825 function restoreDefaultSettings()
829 useBackgroundImage = true;
830 showCombinedDateTime = false;
832 showTodayAsText = true;
834 tomorrowText = 'Tomorrow';
835 showNowAsText = true;
840 updateDataInterval =
5;
841 calendarApp =
0x10005901;
843 showNothingText = true;
844 nothingText = 'No further events within ' + monthRange + ' months';
845 enableDaylightSaving = true;
847 cssStyle_background =
"color:#ffffff; background-color:#000000";
848 cssStyle_weekDay =
"";
850 cssStyle_today =
"color:#ff0000";
851 cssStyle_tomorrow =
"color:#0000ff";
853 cssStyle_now =
"color:#ff00ff";
854 cssStyle_description =
"";
855 cssStyle_icon =
"width:15px; height:15px";
858 function loadSettings()
860 if (widget.preferenceForKey('monthRange'))
861 monthRange = Number(widget.preferenceForKey('monthRange'));
865 if (widget.preferenceForKey('includeTodos'))
866 includeTodos = (widget.preferenceForKey('includeTodos') == 'true');
870 if (widget.preferenceForKey('useBackgroundImage'))
871 useBackgroundImage = (widget.preferenceForKey('useBackgroundImage') == 'true');
873 useBackgroundImage = true;
875 if (widget.preferenceForKey('showCombinedDateTime'))
876 showCombinedDateTime = (widget.preferenceForKey('showCombinedDateTime') == 'true');
878 showCombinedDateTime = false;
880 if (widget.preferenceForKey('showLocation'))
881 showLocation = (widget.preferenceForKey('showLocation') == 'true');
885 if (widget.preferenceForKey('showTodayAsText'))
886 showTodayAsText = (widget.preferenceForKey('showTodayAsText') == 'true');
888 showTodayAsText = true;
890 if (widget.preferenceForKey('todayText'))
891 todayText = widget.preferenceForKey('todayText');
895 if (widget.preferenceForKey('tomorrowText'))
896 tomorrowText = widget.preferenceForKey('tomorrowText');
898 tomorrowText = 'Tomorrow';
900 if (widget.preferenceForKey('showNowAsText'))
901 showNowAsText = (widget.preferenceForKey('showNowAsText') == 'true');
903 showNowAsText = true;
905 if (widget.preferenceForKey('nowText'))
906 nowText = widget.preferenceForKey('nowText');
910 if (widget.preferenceForKey('dateSeparator'))
911 dateSeparator = widget.preferenceForKey('dateSeparator');
915 if (widget.preferenceForKey('dateFormat'))
916 dateFormat = widget.preferenceForKey('dateFormat');
920 if (widget.preferenceForKey('weekDayLength'))
921 weekDayLength = Number(widget.preferenceForKey('weekDayLength'));
925 if (widget.preferenceForKey('updateDataInterval'))
926 updateDataInterval = Number(widget.preferenceForKey('updateDataInterval'));
928 updateDataInterval =
5;
930 if (widget.preferenceForKey('calendarApp'))
931 calendarApp = Number(widget.preferenceForKey('calendarApp'));
933 calendarApp =
0x10005901;
935 if (widget.preferenceForKey('eventsPerWidget'))
936 eventsPerWidget = Number(widget.preferenceForKey('eventsPerWidget'));
940 if (widget.preferenceForKey('showNothingText'))
941 showNothingText = (widget.preferenceForKey('showNothingText') == 'true');
943 showNothingText = true;
945 if (widget.preferenceForKey('nothingText'))
946 nothingText = widget.preferenceForKey('nothingText');
948 nothingText = 'No further events within ' + monthRange + ' months';
950 if (widget.preferenceForKey('enableDaylightSaving'))
951 enableDaylightSaving = (widget.preferenceForKey('enableDaylightSaving') == 'true');
953 enableDaylightSaving = true;
957 if (widget.preferenceForKey('cssStyle_background'))
958 cssStyle_background = widget.preferenceForKey('cssStyle_background');
960 cssStyle_background =
"color:#ffffff; background-color:#000000";
962 if (widget.preferenceForKey('cssStyle_weekDay'))
963 cssStyle_weekDay = widget.preferenceForKey('cssStyle_weekDay');
965 cssStyle_weekDay =
"";
967 if (widget.preferenceForKey('cssStyle_date'))
968 cssStyle_date = widget.preferenceForKey('cssStyle_date');
972 if (widget.preferenceForKey('cssStyle_today'))
973 cssStyle_today = widget.preferenceForKey('cssStyle_today');
975 cssStyle_today =
"color:#ff0000";
977 if (widget.preferenceForKey('cssStyle_tomorrow'))
978 cssStyle_tomorrow = widget.preferenceForKey('cssStyle_tomorrow');
980 cssStyle_tomorrow =
"color:#0000ff";
982 if (widget.preferenceForKey('cssStyle_time'))
983 cssStyle_time = widget.preferenceForKey('cssStyle_time');
987 if (widget.preferenceForKey('cssStyle_now'))
988 cssStyle_now = widget.preferenceForKey('cssStyle_now');
990 cssStyle_now =
"color:#ff00ff";
992 if (widget.preferenceForKey('cssStyle_description'))
993 cssStyle_description = widget.preferenceForKey('cssStyle_description');
995 cssStyle_description =
"";
997 if (widget.preferenceForKey('cssStyle_icon'))
998 cssStyle_icon = widget.preferenceForKey('cssStyle_icon');
1000 cssStyle_icon =
"width:15px; height:15px";
1003 function saveSettings()
1005 widget.setPreferenceForKey(monthRange.toString(), 'monthRange');
1006 widget.setPreferenceForKey(includeTodos ? 'true' : 'false', 'includeTodos');
1007 widget.setPreferenceForKey(useBackgroundImage ? 'true' : 'false', 'useBackgroundImage');
1008 widget.setPreferenceForKey(showCombinedDateTime ? 'true' : 'false', 'showCombinedDateTime');
1009 widget.setPreferenceForKey(showLocation ? 'true' : 'false', 'showLocation');
1010 widget.setPreferenceForKey(showTodayAsText ? 'true' : 'false', 'showTodayAsText');
1011 widget.setPreferenceForKey(todayText, 'todayText');
1012 widget.setPreferenceForKey(tomorrowText, 'tomorrowText');
1013 widget.setPreferenceForKey(showNowAsText ? 'true' : 'false', 'showNowAsText');
1014 widget.setPreferenceForKey(nowText, 'nowText');
1015 widget.setPreferenceForKey(dateSeparator, 'dateSeparator');
1016 widget.setPreferenceForKey(dateFormat, 'dateFormat');
1017 widget.setPreferenceForKey(weekDayLength.toString(), 'weekDayLength');
1018 widget.setPreferenceForKey(updateDataInterval.toString(), 'updateDataInterval');
1019 widget.setPreferenceForKey(calendarApp.toString(), 'calendarApp');
1020 widget.setPreferenceForKey(eventsPerWidget.toString(), 'eventsPerWidget');
1021 widget.setPreferenceForKey(showNothingText ? 'true' : 'false', 'showNothingText');
1022 widget.setPreferenceForKey(nothingText, 'nothingText');
1023 widget.setPreferenceForKey(enableDaylightSaving ? 'true' : 'false', 'enableDaylightSaving');
1025 widget.setPreferenceForKey(cssStyle_background, 'cssStyle_background');
1026 widget.setPreferenceForKey(cssStyle_weekDay, 'cssStyle_weekDay');
1027 widget.setPreferenceForKey(cssStyle_date, 'cssStyle_date');
1028 widget.setPreferenceForKey(cssStyle_today, 'cssStyle_today');
1029 widget.setPreferenceForKey(cssStyle_tomorrow, 'cssStyle_tomorrow');
1030 widget.setPreferenceForKey(cssStyle_time, 'cssStyle_time');
1031 widget.setPreferenceForKey(cssStyle_now, 'cssStyle_now');
1032 widget.setPreferenceForKey(cssStyle_description, 'cssStyle_description');
1033 widget.setPreferenceForKey(cssStyle_icon, 'cssStyle_icon');
1036 function toggleVisibility(elementId)
1038 if (document.getElementById(elementId).style.display ==
"none")
1039 document.getElementById(elementId).style.display =
"block";
1041 document.getElementById(elementId).style.display =
"none";
1045 function printHintBox(text)
1048 return '
<td width=
"1%" align=
"right" onclick=
"javascript:toggleVisibility(\'info' + uniqueId + '\')">Help
</td></tr></table>'+
1049 '
<div class=
"settingsInfo" id=
"info' + uniqueId + '">' + text + '
</div>';
1052 function showAbout()
1055 document.getElementById(
"homescreenView").style.display =
"none";
1056 document.getElementById(
"fullscreenView").style.display =
"none";
1057 document.getElementById(
"aboutView").style.display =
"block";
1058 document.getElementById(
"settingsView").style.display =
"none";
1060 window.menu.setLeftSoftkeyLabel(
" ", function(){});
1061 window.menu.setRightSoftkeyLabel(
"Back", function()
1067 //document.getElementById(
"aboutView").innerHTML = 'aboutView';
1068 document.getElementById(
"name").innerHTML =
"Coming Next " + version;
1071 function updateFullscreen()
1075 function showFullscreen()
1077 document.getElementById(
"homescreenView").style.display =
"none";
1078 document.getElementById(
"fullscreenView").style.display =
"block";
1079 document.getElementById(
"aboutView").style.display =
"none";
1080 document.getElementById(
"settingsView").style.display =
"none";
1085 function updateHomescreen()
1087 if (useBackgroundImage) {
1088 // check for screen rotation
1089 if (orientation != 'portrait' && screen.width ==
360 && screen.height ==
640) {
1090 window.widget.prepareForTransition(
"fade");
1091 orientation = 'portrait';
1092 document.getElementById('body').style.backgroundImage = 'url(background_' + orientation + '.png)';
1093 document.getElementById('body').style.backgroundColor = 'none';
1094 window.widget.performTransition();
1095 } else if (orientation != 'landscape' && screen.width ==
640 && screen.height ==
360) {
1096 window.widget.prepareForTransition(
"fade");
1097 orientation = 'landscape';
1098 document.getElementById('body').style.backgroundImage = 'url(background_' + orientation + '.png)';
1099 document.getElementById('body').style.backgroundColor = 'none';
1100 window.widget.performTransition();
1105 function showHomescreen()
1107 document.getElementById(
"homescreenView").style.display =
"block";
1108 document.getElementById(
"fullscreenView").style.display =
"none";
1109 document.getElementById(
"aboutView").style.display =
"none";
1110 document.getElementById(
"settingsView").style.display =
"none";
1116 <style type=
"text/css">
1117 table { margin:
0px; padding:
0px; border-spacing:
0px; }
1118 td { padding:
0px
5px
0px
0px; white-space:nowrap; overflow:hidden; }
1119 hr { w_idth:
100%; color:#ffffff; background-color:#ffffff; height:
1px; text-align:left; border-style:none; }
1120 .settingsInfo { display:none; font-style:italic; }
1121 .title { font-weight:bold; font-size:
14pt; }
1122 .textInput { width:
90%; }
1123 #homescreenView { width:
315px; height:
91px; overflow:hidden; }
1124 #calendarList { position:absolute; left:
10px; top:
4px; width:
295px; height:
75px; overflow:hidden; }
1125 #name { text-align:center; }
1126 #appicon { display: block; margin-left: auto; margin-right: auto; margin-top:
50px; }
1127 #smallappicon { width:
22px; height:
22px; margin-right:
10px; float:left; }
1132 <body id=
"body" class=
"background">
1133 <div id=
"homescreenView">
1134 <div id=
"calendarList"></div>
1136 <div id=
"fullscreenView" style=
"display:none">
1137 <img src=
"Icon.png" id=
"smallappicon" onClick=
"javascript:launchCalendar()">
1138 <h1 class=
"title" onClick=
"javascript:launchCalendar()">Coming Next
</h1>
1140 <div id=
"fullscreenCalendarList">loading...
</div>
1142 <div id=
"settingsView" style=
"display:none">
1143 <img src=
"Icon.png" id=
"smallappicon">
1144 <h1 class=
"title">Settings
</h1>
1146 <div id=
"settingsList"></div>
1148 <div id=
"aboutView" style=
"display:none">
1149 <img src=
"Icon.png" id=
"appicon">
1150 <h1 id=
"name">Coming Next
</h1>
1152 <p>Created by Dr. Cochambre and Michael Prager.
</p>
1153 <p>This software is open source and licensed under the GPLv3.
</p>
1154 <p>Visit https://sourceforge.net/projects/comingnext/ for free updates.
</p>