diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php index bef0d410..fb8099a1 100644 --- a/plugins/calendar/calendar.php +++ b/plugins/calendar/calendar.php @@ -55,6 +55,7 @@ class calendar extends rcube_plugin 'calendar_first_hour' => 6, 'calendar_work_start' => 6, 'calendar_work_end' => 18, + 'calendar_agenda_range' => 30, ); private $default_categories = array( @@ -685,6 +686,7 @@ class calendar extends rcube_plugin $settings['date_format'] = (string)$this->rc->config->get('calendar_date_format', $this->defaults['calendar_date_format']); $settings['date_short'] = (string)$this->rc->config->get('calendar_date_short', $this->defaults['calendar_date_short']); $settings['date_long'] = (string)$this->rc->config->get('calendar_date_long', $this->defaults['calendar_date_long']); + $settings['dates_long'] = str_replace(' yyyy', '[ yyyy]', $settings['date_long']) . "{ '—' " . $settings['date_long'] . '}'; $settings['date_agenda'] = (string)$this->rc->config->get('calendar_date_agenda', $this->defaults['calendar_date_agenda']); $settings['time_format'] = (string)$this->rc->config->get('calendar_time_format', $this->defaults['calendar_time_format']); $settings['timeslots'] = (int)$this->rc->config->get('calendar_timeslots', $this->defaults['calendar_timeslots']); @@ -692,6 +694,7 @@ class calendar extends rcube_plugin $settings['first_hour'] = (int)$this->rc->config->get('calendar_first_hour', $this->defaults['calendar_first_hour']); $settings['work_start'] = (int)$this->rc->config->get('calendar_work_start', $this->defaults['calendar_work_start']); $settings['work_end'] = (int)$this->rc->config->get('calendar_work_end', $this->defaults['calendar_work_end']); + $settings['agenda_range'] = (int)$this->rc->config->get('calendar_agenda_range', $this->defaults['calendar_agenda_range']); $settings['timezone'] = $this->timezone; // localization @@ -1476,6 +1479,9 @@ class calendar extends rcube_plugin if ($date = get_input_value('date', RCUBE_INPUT_GPC)) $this->rc->output->set_env('date', $date); + + if ($range = get_input_value('range', RCUBE_INPUT_GPC)) + $this->rc->output->set_env('listRange', intval($range)); if ($search = get_input_value('search', RCUBE_INPUT_GPC)) { $this->rc->output->set_env('search', $search); diff --git a/plugins/calendar/calendar_ui.js b/plugins/calendar/calendar_ui.js index 469fdf4b..b1951769 100644 --- a/plugins/calendar/calendar_ui.js +++ b/plugins/calendar/calendar_ui.js @@ -1390,7 +1390,8 @@ function rcube_calendar_ui(settings) { if (!view) view = fc.fullCalendar('getView').name; var date = fc.fullCalendar('getDate') || new Date(); - var printwin = window.open(rcmail.url('print', { view: view, date: date2unixtime(date), search: this.search_query }), "rc_print_calendars", "toolbar=no,location=yes,menubar=yes,resizable=yes,scrollbars=yes,width=800"); + var range = fc.fullCalendar('option', 'listRange'); + var printwin = window.open(rcmail.url('print', { view: view, date: date2unixtime(date), range: range, search: this.search_query }), "rc_print_calendars", "toolbar=no,location=yes,menubar=yes,resizable=yes,scrollbars=yes,width=800"); window.setTimeout(function(){ printwin.focus() }, 50); }; @@ -1543,6 +1544,7 @@ function rcube_calendar_ui(settings) // change to list view fc.fullCalendar('option', 'listSections', 'month'); + fc.fullCalendar('option', 'listRange', settings['agenda_range']); fc.fullCalendar('changeView', 'table'); // refetch events with new url (if not already triggered by changeView) @@ -1563,8 +1565,13 @@ function rcube_calendar_ui(settings) rcmail.hide_message(this._search_message); if (this.search_request) { + // hide bottom links of agenda view + fc.find('.fc-list-content > .fc-listappend').hide(); + // restore original event sources and view mode from fullcalendar fc.fullCalendar('option', 'listSections', 'smart'); + fc.fullCalendar('option', 'listRange', settings['agenda_range']); + for (var sid in this.calendars) { if (this.calendars[sid]) this.calendars[sid].url = this.calendars[sid].url.replace(/&q=.+/, ''); @@ -1582,8 +1589,49 @@ function rcube_calendar_ui(settings) // callback if all sources have been fetched from server this.events_loaded = function(count) { - if (this.search_request && !count) - this._search_message = rcmail.display_message(rcmail.gettext('searchnoresults', 'calendar'), 'notice'); + var addlinks, append = ''; + + // enhance list view when searching + if (this.search_request) { + if (!count) { + this._search_message = rcmail.display_message(rcmail.gettext('searchnoresults', 'calendar'), 'notice'); + append = '
' + rcmail.gettext('searchnoresults', 'calendar') + '
'; + } + append += ''; + addlinks = true; + } + + if (fc.fullCalendar('getView').name == 'table') { + var container = fc.find('.fc-list-content > .fc-listappend'); + if (append) { + if (!container.length) + container = $('
').appendTo(fc.find('.fc-list-content')); + container.html(append).show(); + } + else if (container.length) + container.hide(); + + // add links to adjust search date range + if (addlinks) { + var lc = container.find('.fc-bottomlinks'); + $('').attr('href', '#').html(rcmail.gettext('searchearlierdates', 'calendar')).appendTo(lc).click(function(){ + fc.fullCalendar('incrementDate', 0, -1, 0); + fullcalendar_update(); + }); + lc.append(" "); + $('').attr('href', '#').html(rcmail.gettext('searchlaterdates', 'calendar')).appendTo(lc).click(function(){ + var range = fc.fullCalendar('option', 'listRange'); + if (range < 60) { + fc.fullCalendar('getView').start = null; // force re-render + fc.fullCalendar('option', 'listRange', 60).fullCalendar('render'); + } + else + fc.fullCalendar('incrementDate', 0, 1, 0); + + fullcalendar_update(); + }); + } + } }; // resize and reposition (center) the dialog window @@ -1688,18 +1736,17 @@ function rcube_calendar_ui(settings) month: 'ddd', // Mon week: 'ddd ' + settings['date_short'], // Mon 9/7 day: 'dddd ' + settings['date_short'], // Monday 9/7 - list: settings['date_agenda'], table: settings['date_agenda'] }, titleFormat: { month: 'MMMM yyyy', - week: settings['date_long'].replace(/ yyyy/, '[ yyyy]') + "{ '—' " + settings['date_long'] + "}", + week: settings['dates_long'], day: 'dddd ' + settings['date_long'], - list: settings['date_long'], - table: settings['date_long'] + table: settings['dates_long'] }, listSections: 'smart', - listRange: 60, // show 60 days in list view + listPage: 1, // advance one day in agenda view + listRange: settings['agenda_range'], tableCols: ['handle', 'date', 'time', 'title', 'location'], defaultView: settings['default_view'], allDayText: rcmail.gettext('all-day', 'calendar'), @@ -1718,7 +1765,7 @@ function rcube_calendar_ui(settings) me.is_loading = isLoading; this._rc_loading = rcmail.set_busy(isLoading, 'loading', this._rc_loading); // trigger callback - if (!isLoading && me.search_request) + if (!isLoading) me.events_loaded($(this).fullCalendar('clientEvents').length); }, // event rendering diff --git a/plugins/calendar/config.inc.php.dist b/plugins/calendar/config.inc.php.dist index a6b23415..2a7dcf05 100644 --- a/plugins/calendar/config.inc.php.dist +++ b/plugins/calendar/config.inc.php.dist @@ -46,6 +46,9 @@ $rcmail_config['calendar_date_agenda'] = 'ddd MM-dd'; // timeslots per hour (1, 2, 3, 4, 6) $rcmail_config['calendar_timeslots'] = 2; +// show this number of days in agenda view +$rcmail_config['calendar_agenda_range'] = 30; + // first day of the week (0-6) $rcmail_config['calendar_first_day'] = 1; diff --git a/plugins/calendar/lib/js/fullcalendar.js b/plugins/calendar/lib/js/fullcalendar.js index b2e0d53d..dba0866f 100644 --- a/plugins/calendar/lib/js/fullcalendar.js +++ b/plugins/calendar/lib/js/fullcalendar.js @@ -82,7 +82,6 @@ var defaults = { table: 'table' }, listTexts: { - from: 'from', until: 'until', past: 'Past events', today: 'Today', @@ -5530,10 +5529,10 @@ function ListView(element, calendar) { if (delta) { addDays(date, opt('listPage') * delta); } - t.title = opt('listTexts', 'from') + ' ' + formatDate(date, opt('titleFormat')); t.start = t.visStart = cloneDate(date, true); t.end = addDays(cloneDate(t.start), opt('listPage')); t.visEnd = addDays(cloneDate(t.start), opt('listRange')); + t.title = formatDates(date, t.visEnd, opt('titleFormat')); updateOptions(); @@ -5751,10 +5750,10 @@ function TableView(element, calendar) { if (delta) { addDays(date, opt('listPage') * delta); } - t.title = opt('listTexts', 'from') + ' ' + formatDate(date, opt('titleFormat')); t.start = t.visStart = cloneDate(date, true); t.end = addDays(cloneDate(t.start), opt('listPage')); t.visEnd = addDays(cloneDate(t.start), opt('listRange')); + t.title = formatDates(date, t.visEnd, opt('titleFormat')); updateOptions(); diff --git a/plugins/calendar/localization/en_US.inc b/plugins/calendar/localization/en_US.inc index 674628d8..7a15ce6b 100644 --- a/plugins/calendar/localization/en_US.inc +++ b/plugins/calendar/localization/en_US.inc @@ -61,6 +61,8 @@ $labels['selectdate'] = 'Select date'; $labels['printdescriptions'] = 'Print descriptions'; $labels['parentcalendar'] = 'Superior calendar'; $labels['importtocalendar'] = 'Save to my calendar'; +$labels['searchearlierdates'] = '« Search for earlier events'; +$labels['searchlaterdates'] = 'Search for later events »'; // alarm/reminder settings $labels['alarmemail'] = 'Send Email'; diff --git a/plugins/calendar/print.js b/plugins/calendar/print.js index 03cd8860..4c48dea0 100644 --- a/plugins/calendar/print.js +++ b/plugins/calendar/print.js @@ -80,13 +80,13 @@ window.rcmail && rcmail.addEventListener('init', function(evt) { }, titleFormat: { month: 'MMMM yyyy', - week: settings['date_long'].replace(/ yyyy/, '[ yyyy]') + "{ '—' " + settings['date_long'] + "}", + week: settings['dates_long'], day: 'dddd ' + settings['date_long'], - list: settings['date_long'], - table: settings['date_long'] + list: settings['dates_long'], + table: settings['dates_long'] }, listSections: 'smart', - listRange: 60, // show 60 days in list view + listRange: rcmail.env.listRange || settings['agenda_range'], tableCols: ['handle', 'date', 'time', 'title', 'location'], allDayText: rcmail.gettext('all-day', 'calendar'), buttonText: { diff --git a/plugins/calendar/skins/default/calendar.css b/plugins/calendar/skins/default/calendar.css index 3354810c..c01409e1 100644 --- a/plugins/calendar/skins/default/calendar.css +++ b/plugins/calendar/skins/default/calendar.css @@ -1032,6 +1032,23 @@ div.fc-event-location { width: 20%; } +.fc-listappend { + text-align: center; + margin-top: 1em; +} + +.fc-listappend .message { + padding: 0.5em; + margin-bottom: 0.5em; + font-size: 150%; + color: #999; +} + +.fc-listappend .formlinks a { + font-size: 12px; + padding: 0 0.3em; +} + /* Settings section */ fieldset #calendarcategories div { diff --git a/plugins/calendar/skins/default/print.css b/plugins/calendar/skins/default/print.css index 28da23cb..eeb4fadb 100644 --- a/plugins/calendar/skins/default/print.css +++ b/plugins/calendar/skins/default/print.css @@ -2,7 +2,8 @@ body { margin: 0; - color: #000000; + color: #000; + background: #fff; } body, td, th, div, p, h3, select, input, textarea {