Improve agenda view: add UI element to constrol listing options; localize sections texts

This commit is contained in:
Thomas 2011-09-09 14:37:19 +02:00
parent 8abc274092
commit 3921515c3b
12 changed files with 208 additions and 37 deletions

View file

@ -57,7 +57,8 @@ class calendar extends rcube_plugin
'calendar_work_start' => 6,
'calendar_work_end' => 18,
'calendar_agenda_range' => 60,
'calendar_event_coloring' => 0,
'calendar_agenda_sections' => 'smart',
'calendar_event_coloring' => 0,
);
private $default_categories = array(
@ -235,6 +236,7 @@ class calendar extends rcube_plugin
$this->register_handler('plugin.edit_attendees_notify', array($this->ui, 'edit_attendees_notify'));
$this->register_handler('plugin.edit_recurring_warning', array($this->ui, 'recurring_event_warning'));
$this->register_handler('plugin.event_rsvp_buttons', array($this->ui, 'event_rsvp_buttons'));
$this->register_handler('plugin.angenda_options', array($this->ui, 'angenda_options'));
$this->register_handler('plugin.searchform', array($this->rc->output, 'search_form')); // use generic method from rcube_template
$this->rc->output->add_label('low','normal','high','delete','cancel','uploading','noemailwarning');
@ -830,6 +832,7 @@ class calendar extends rcube_plugin
$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['agenda_sections'] = $this->rc->config->get('calendar_agenda_sections', $this->defaults['calendar_agenda_sections']);
$settings['event_coloring'] = (int)$this->rc->config->get('calendar_event_coloring', $this->defaults['calendar_event_coloring']);
$settings['timezone'] = $this->timezone;
@ -862,7 +865,7 @@ class calendar extends rcube_plugin
$this->rc->gettext('sep'), $this->rc->gettext('oct'),
$this->rc->gettext('nov'), $this->rc->gettext('dec')
);
$settings['today'] = rcube_label('today');
$settings['today'] = $this->rc->gettext('today');
// get user identity to create default attendee
if ($this->ui->screen == 'calendar') {
@ -1593,6 +1596,9 @@ class calendar extends rcube_plugin
if ($range = get_input_value('range', RCUBE_INPUT_GPC))
$this->rc->output->set_env('listRange', intval($range));
if (isset($_REQUEST['sections']))
$this->rc->output->set_env('listSections', get_input_value('sections', RCUBE_INPUT_GPC));
if ($search = get_input_value('search', RCUBE_INPUT_GPC)) {
$this->rc->output->set_env('search', $search);
$title .= ' "' . $search . '"';

View file

@ -40,6 +40,7 @@ function rcube_calendar_ui(settings)
var attendees_list;
var freebusy_ui = { workinhoursonly:false, needsupdate:false };
var freebusy_data = {};
var current_view = null;
var exec_deferred = bw.ie6 ? 5 : 1;
var sensitivitylabels = { 0:rcmail.gettext('public','calendar'), 1:rcmail.gettext('private','calendar'), 2:rcmail.gettext('confidential','calendar') };
var ui_loading = rcmail.set_busy(true, 'loading');
@ -1563,6 +1564,12 @@ function rcube_calendar_ui(settings)
return true;
};
var update_agenda_toolbar = function()
{
$('#agenda-listrange').val(fc.fullCalendar('option', 'listRange'));
$('#agenda-listsections').val(fc.fullCalendar('option', 'listSections'));
}
/*** fullcalendar event handlers ***/
var fc_event_render = function(event, element, view) {
@ -1691,7 +1698,8 @@ function rcube_calendar_ui(settings)
if (!view) view = fc.fullCalendar('getView').name;
var date = fc.fullCalendar('getDate') || new Date();
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");
var sections = fc.fullCalendar('option', 'listSections');
var printwin = window.open(rcmail.url('print', { view: view, date: date2unixtime(date), range: range, sections: sections, 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);
};
@ -1845,9 +1853,11 @@ function rcube_calendar_ui(settings)
this.search_query = q;
// change to list view
fc.fullCalendar('option', 'listSections', 'month');
fc.fullCalendar('option', 'listRange', Math.max(60, settings['agenda_range']));
fc.fullCalendar('changeView', 'table');
fc.fullCalendar('option', 'listSections', 'month')
.fullCalendar('option', 'listRange', Math.max(60, settings['agenda_range']))
.fullCalendar('changeView', 'table');
update_agenda_toolbar();
// refetch events with new url (if not already triggered by changeView)
if (!this.is_loading)
@ -1871,8 +1881,10 @@ function rcube_calendar_ui(settings)
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']);
fc.fullCalendar('option', 'listSections', settings['agenda_sections'])
.fullCalendar('option', 'listRange', settings['agenda_range']);
update_agenda_toolbar();
for (var sid in this.calendars) {
if (this.calendars[sid])
@ -1923,8 +1935,8 @@ function rcube_calendar_ui(settings)
$('<a>').attr('href', '#').html(rcmail.gettext('searchlaterdates', 'calendar')).appendTo(lc).click(function(){
var range = fc.fullCalendar('option', 'listRange');
if (range < 90) {
fc.fullCalendar('getView').start = null; // force re-render
fc.fullCalendar('option', 'listRange', fc.fullCalendar('option', 'listRange') + 30).fullCalendar('render');
update_agenda_toolbar();
}
else
fc.fullCalendar('incrementDate', 0, 1, 0);
@ -1944,6 +1956,13 @@ function rcube_calendar_ui(settings)
.dialog('option', 'position', ['center', 'center']); // only works in a separate call (!?)
};
// adjust calendar view size
this.view_resize = function()
{
var footer = fc.fullCalendar('getView').name == 'table' ? $('#agendaoptions').height() + 2 : 0;
fc.fullCalendar('option', 'height', $('#main').height() - footer);
};
/*** startup code ***/
@ -2051,9 +2070,9 @@ function rcube_calendar_ui(settings)
day: 'dddd ' + settings['date_long'],
table: settings['dates_long']
},
listSections: 'smart',
listPage: 1, // advance one day in agenda view
listRange: settings['agenda_range'],
listSections: settings['agenda_sections'],
tableCols: ['handle', 'date', 'time', 'title', 'location'],
defaultView: rcmail.env.view || settings['default_view'],
allDayText: rcmail.gettext('all-day', 'calendar'),
@ -2066,6 +2085,18 @@ function rcube_calendar_ui(settings)
month: rcmail.gettext('month', 'calendar'),
table: rcmail.gettext('agenda', 'calendar')
},
listTexts: {
until: rcmail.gettext('until', 'calendar'),
past: rcmail.gettext('pastevents', 'calendar'),
today: rcmail.gettext('today', 'calendar'),
tomorrow: rcmail.gettext('tomorrow', 'calendar'),
thisWeek: rcmail.gettext('thisweek', 'calendar'),
nextWeek: rcmail.gettext('nextweek', 'calendar'),
thisMonth: rcmail.gettext('thismonth', 'calendar'),
nextMonth: rcmail.gettext('nextmonth', 'calendar'),
future: rcmail.gettext('futureevents', 'calendar'),
week: rcmail.gettext('weekofyear', 'calendar')
},
selectable: true,
selectHelper: false,
loading: function(isLoading) {
@ -2169,8 +2200,13 @@ function rcube_calendar_ui(settings)
update_event_confirm('resize', event, data);
},
viewDisplay: function(view) {
if (minical)
$('#agendaoptions')[view.name == 'table' ? 'show' : 'hide']();
if (minical) {
window.setTimeout(function(){ minical.datepicker('setDate', fc.fullCalendar('getDate')); }, exec_deferred);
if (view.name != current_view)
me.view_resize();
current_view = view.name;
}
},
viewRender: function(view) {
view._maxevents = Math.floor((view.element.parent().height()-18) / 108) - 1;
@ -2415,6 +2451,18 @@ function rcube_calendar_ui(settings)
event_rsvp($(this).attr('rel'))
})
$('#agenda-listrange').change(function(e){
settings['agenda_range'] = parseInt($(this).val());
fc.fullCalendar('option', 'listRange', settings['agenda_range']).fullCalendar('render');
// TODO: save new settings in prefs
}).val(settings['agenda_range']);
$('#agenda-listsections').change(function(e){
settings['agenda_sections'] = $(this).val();
fc.fullCalendar('option', 'listSections', settings['agenda_sections']).fullCalendar('render');
// TODO: save new settings in prefs
}).val(fc.fullCalendar('option', 'listSections'));
// hide event dialog when clicking somewhere into document
$(document).bind('mousedown', dialog_check);
@ -2507,8 +2555,9 @@ window.rcmail && rcmail.addEventListener('init', function(evt) {
// check target due to bugs in jquery
// http://bugs.jqueryui.com/ticket/7514
// http://bugs.jquery.com/ticket/9841
if (e.target == window)
$('#calendar').fullCalendar('option', 'height', $('#main').height());
if (e.target == window) {
cal.view_resize();
}
}).resize();
// show calendars list when ready

View file

@ -178,6 +178,34 @@ class calendar_ui
return html::tag('ul', $attrib, $li, html::$common_attrib);
}
/**
*
*/
function angenda_options($attrib = array())
{
$attrib += array('id' => 'agendaoptions');
$attrib['style'] .= 'display:none';
$select_range = new html_select(array('name' => 'listrange', 'id' => 'agenda-listrange'));
$select_range->add(1 . ' ' . preg_replace('/\(.+\)/', '', $this->cal->gettext('days')), $days);
foreach (array(2,5,7,14,30,60,90) as $days)
$select_range->add($days . ' ' . preg_replace('/\(|\)/', '', $this->cal->gettext('days')), $days);
$html .= html::label('agenda-listrange', $this->cal->gettext('listrange'));
$html .= $select_range->show($this->rc->config->get('calendar_agenda_range', $this->cal->defaults['calendar_agenda_range']));
$select_sections = new html_select(array('name' => 'listsections', 'id' => 'agenda-listsections'));
$select_sections->add('---', '');
foreach (array('day' => 'days', 'week' => 'weeks', 'month' => 'months', 'smart' => 'smartsections') as $val => $label)
$select_sections->add(preg_replace('/\(|\)/', '', ucfirst($this->cal->gettext($label))), $val);
$html .= html::span('spacer', '&nbsp');
$html .= html::label('agenda-listsections', $this->cal->gettext('listsections'));
$html .= $select_sections->show($this->rc->config->get('calendar_agenda_sections', $this->cal->defaults['calendar_agenda_sections']));
return html::div($attrib, $html);
}
/**
* Render a HTML select box for calendar selection
*/

View file

@ -1,5 +1,5 @@
--- js/fullcalendar.js.orig 2011-04-09 14:13:16.000000000 +0200
+++ js/fullcalendar.js 2011-09-08 18:52:12.000000000 +0200
+++ js/fullcalendar.js 2011-09-09 14:13:07.000000000 +0200
@@ -47,12 +47,16 @@
titleFormat: {
month: 'MMMM yyyy',
@ -76,16 +76,17 @@
currentView.renderEvents(events, modifiedEventID);
currentView.eventsDirty = false;
}
@@ -632,6 +658,8 @@
@@ -632,6 +658,9 @@
if (name == 'height' || name == 'contentHeight' || name == 'aspectRatio') {
options[name] = value;
updateSize();
+ } else if (name.indexOf('list') == 0 || name == 'tableCols') {
+ options[name] = value;
+ currentView.start = null; // force re-render
}
}
@@ -897,15 +925,16 @@
@@ -897,15 +926,16 @@
}
@ -106,7 +107,7 @@
}
}
@@ -1579,10 +1608,23 @@
@@ -1579,10 +1609,23 @@
return 'th';
}
return ['st', 'nd', 'rd'][date%10-1] || 'th';
@ -131,7 +132,7 @@
fc.applyAll = applyAll;
@@ -3534,10 +3576,10 @@
@@ -3534,10 +3577,10 @@
function slotSelectionMousedown(ev) {
if (ev.which == 1 && opt('selectable')) { // ev.which==1 means left mouse button
unselect(ev);
@ -144,7 +145,7 @@
var d1 = cellDate(origCell);
var d2 = cellDate(cell);
dates = [
@@ -3762,7 +3804,8 @@
@@ -3762,7 +3805,8 @@
height,
slotSegmentContainer = getSlotSegmentContainer(),
rtl, dis, dit,
@ -154,7 +155,7 @@
if (rtl = opt('isRTL')) {
dis = -1;
@@ -3789,8 +3832,11 @@
@@ -3789,8 +3833,11 @@
outerWidth = availWidth / (levelI + forward + 1);
}else{
if (forward) {
@ -168,7 +169,7 @@
}else{
// can be entire width, aligned left
outerWidth = availWidth;
@@ -3801,7 +3847,7 @@
@@ -3801,7 +3848,7 @@
* dis + (rtl ? availWidth - outerWidth : 0); // rtl
seg.top = top;
seg.left = left;
@ -177,7 +178,7 @@
seg.outerHeight = bottom - top;
html += slotSegHtml(event, seg);
}
@@ -4260,7 +4306,7 @@
@@ -4260,7 +4307,7 @@
function opt(name, viewNameOverride) {
var v = options[name];
@ -186,7 +187,7 @@
return smartProperty(v, viewNameOverride || viewName);
}
return v;
@@ -4804,6 +4850,8 @@
@@ -4804,6 +4851,8 @@
}
seg.outerHeight = element[0].offsetHeight + val;
}
@ -195,7 +196,7 @@
}
}
@@ -5204,5 +5252,561 @@
@@ -5204,5 +5253,561 @@
};
}
@ -258,8 +259,8 @@
+ for (i=0; i < events.length; i++) {
+ event = events[i];
+
+ // skip events < t.start
+ if (event.end < t.start)
+ // skip events out of range
+ if (event.end < t.start || event.start > t.visEnd)
+ continue;
+
+ // define sections of this event
@ -484,7 +485,7 @@
+ }
+ t.start = t.visStart = cloneDate(date, true);
+ t.end = addDays(cloneDate(t.start), opt('listPage'));
+ t.visEnd = addDays(cloneDate(t.start), opt('listRange') + 1);
+ t.visEnd = addDays(cloneDate(t.start), opt('listRange'));
+ addMinutes(t.visEnd, -1); // set end to 23:59
+ t.title = formatDates(date, t.visEnd, opt('titleFormat'));
+
@ -706,9 +707,9 @@
+ }
+ t.start = t.visStart = cloneDate(date, true);
+ t.end = addDays(cloneDate(t.start), opt('listPage'));
+ t.visEnd = addDays(cloneDate(t.start), opt('listRange') + 1);
+ t.visEnd = addDays(cloneDate(t.start), opt('listRange'));
+ addMinutes(t.visEnd, -1); // set end to 23:59
+ t.title = formatDates(date, t.visEnd, opt('titleFormat'));
+ t.title = (t.visEnd.getTime() - t.visStart.getTime() < DAY_MS) ? formatDate(date, opt('titleFormat')) : formatDates(date, t.visEnd, opt('titleFormat'));
+
+ updateOptions();
+

View file

@ -660,6 +660,7 @@ function Calendar(element, options, eventSources) {
updateSize();
} else if (name.indexOf('list') == 0 || name == 'tableCols') {
options[name] = value;
currentView.start = null; // force re-render
}
}
@ -5310,8 +5311,8 @@ function ListEventRenderer() {
for (i=0; i < events.length; i++) {
event = events[i];
// skip events < t.start
if (event.end < t.start)
// skip events out of range
if (event.end < t.start || event.start > t.visEnd)
continue;
// define sections of this event
@ -5536,7 +5537,7 @@ function ListView(element, calendar) {
}
t.start = t.visStart = cloneDate(date, true);
t.end = addDays(cloneDate(t.start), opt('listPage'));
t.visEnd = addDays(cloneDate(t.start), opt('listRange') + 1);
t.visEnd = addDays(cloneDate(t.start), opt('listRange'));
addMinutes(t.visEnd, -1); // set end to 23:59
t.title = formatDates(date, t.visEnd, opt('titleFormat'));
@ -5758,9 +5759,9 @@ function TableView(element, calendar) {
}
t.start = t.visStart = cloneDate(date, true);
t.end = addDays(cloneDate(t.start), opt('listPage'));
t.visEnd = addDays(cloneDate(t.start), opt('listRange') + 1);
t.visEnd = addDays(cloneDate(t.start), opt('listRange'));
addMinutes(t.visEnd, -1); // set end to 23:59
t.title = formatDates(date, t.visEnd, opt('titleFormat'));
t.title = (t.visEnd.getTime() - t.visStart.getTime() < DAY_MS) ? formatDate(date, opt('titleFormat')) : formatDates(date, t.visEnd, opt('titleFormat'));
updateOptions();

View file

@ -67,6 +67,21 @@ $labels['searchlaterdates'] = 'Spätere Termine suchen »';
$labels['andnmore'] = '$nr weitere...';
$labels['togglerole'] = 'Klick zum Ändern der Rolle';
// agenda view
$labels['listrange'] = 'Angezeigter Bereich:';
$labels['listsections'] = 'Unterteilung:';
$labels['smartsections'] = 'Intelligent';
$labels['until'] = 'bis';
$labels['today'] = 'Heute';
$labels['tomorrow'] = 'Morgen';
$labels['thisweek'] = 'Diese Woche';
$labels['nextweek'] = 'Nächste Woche';
$labels['thismonth'] = 'Diesen Monat';
$labels['nextmonth'] = 'Nächsten Monat';
$labels['weekofyear'] = 'KW';
$labels['pastevents'] = 'Vergangene';
$labels['futureevents'] = 'Zukünftige';
// alarm/reminder settings
$labels['showalarms'] = 'Erinnerungen anzeigen';
$labels['alarmemail'] = 'E-Mail senden';

View file

@ -65,6 +65,22 @@ $labels['parentcalendar'] = 'Übergeordneter Kalender';
$labels['searchearlierdates'] = '« Frühere Termine suchen';
$labels['searchlaterdates'] = 'Spätere Termine suchen »';
$labels['andnmore'] = '$nr weitere...';
$labels['togglerole'] = 'Klick zum Ändern der Rolle';
// agenda view
$labels['listrange'] = 'Angezeigter Bereich:';
$labels['listsections'] = 'Unterteilung:';
$labels['smartsections'] = 'Intelligent';
$labels['until'] = 'bis';
$labels['today'] = 'Heute';
$labels['tomorrow'] = 'Morgen';
$labels['thisweek'] = 'Diese Woche';
$labels['nextweek'] = 'Nächste Woche';
$labels['thismonth'] = 'Diesen Monat';
$labels['nextmonth'] = 'Nächsten Monat';
$labels['weekofyear'] = 'Woche';
$labels['pastevents'] = 'Vergangene';
$labels['futureevents'] = 'Zukünftige';
// alarm/reminder settings
$labels['showalarms'] = 'Erinnerungen anzeigen';

View file

@ -67,6 +67,21 @@ $labels['searchlaterdates'] = 'Search for later events »';
$labels['andnmore'] = '$nr more...';
$labels['togglerole'] = 'Click to toggle role';
// agenda view
$labels['listrange'] = 'Range to display:';
$labels['listsections'] = 'Divide into:';
$labels['smartsections'] = 'Smart sections';
$labels['until'] = 'until';
$labels['today'] = 'Today';
$labels['tomorrow'] = 'Tomorrow';
$labels['thisweek'] = 'This week';
$labels['nextweek'] = 'Next week';
$labels['thismonth'] = 'This month';
$labels['nextmonth'] = 'Next month';
$labels['weekofyear'] = 'Week';
$labels['pastevents'] = 'Past';
$labels['futureevents'] = 'Future';
// alarm/reminder settings
$labels['showalarms'] = 'Show alarms';
$labels['alarmemail'] = 'Send Email';

View file

@ -84,7 +84,7 @@ window.rcmail && rcmail.addEventListener('init', function(evt) {
list: settings['dates_long'],
table: settings['dates_long']
},
listSections: 'smart',
listSections: rcmail.env.listSections !== undefined ? rcmail.env.listSections : settings['agenda_sections'],
listRange: rcmail.env.listRange || settings['agenda_range'],
tableCols: ['handle', 'date', 'time', 'title', 'location'],
allDayText: rcmail.gettext('all-day', 'calendar'),
@ -94,6 +94,18 @@ window.rcmail && rcmail.addEventListener('init', function(evt) {
month: rcmail.gettext('month', 'calendar'),
table: rcmail.gettext('agenda', 'calendar')
},
listTexts: {
until: rcmail.gettext('until', 'calendar'),
past: rcmail.gettext('pastevents', 'calendar'),
today: rcmail.gettext('today', 'calendar'),
tomorrow: rcmail.gettext('tomorrow', 'calendar'),
thisWeek: rcmail.gettext('thisweek', 'calendar'),
nextWeek: rcmail.gettext('nextweek', 'calendar'),
thisMonth: rcmail.gettext('thismonth', 'calendar'),
nextMonth: rcmail.gettext('nextmonth', 'calendar'),
future: rcmail.gettext('futureevents', 'calendar'),
week: rcmail.gettext('weekofyear', 'calendar')
},
loading: function(isLoading) {
rc_loading = rcmail.set_busy(isLoading, 'loading', rc_loading);
},

View file

@ -942,6 +942,28 @@ a.alarm-action-snooze:after {
height: 160px;
}
span.spacer {
padding-left: 3em;
}
#agendaoptions {
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: auto;
z-index: 200;
border: 1px solid #ccc;
padding: 2px 5px 1px;
font-size: 90%;
}
#agendaoptions label {
color: #444;
text-shadow: 1px 1px #eee;
padding-right: 0.5em;
}
#calendar-kolabform {
position: relative;
padding-top: 24px;

View file

@ -19,6 +19,10 @@
height: expression((parseInt(this.parentNode.offsetHeight)-220)+'px');
}
#agendaoptions {
width: expression((parseInt(this.parentNode.offsetWidth)-12)+'px');
}
#calendartoolbar a.buttonPas {
filter: alpha(opacity=35);
}

View file

@ -26,7 +26,9 @@
</div>
</div>
<div id="sidebartoggle"></div>
<div id="calendar"></div>
<div id="calendar">
<roundcube:object name="plugin.angenda_options" class="boxfooter" id="agendaoptions" />
</div>
</div>
<div id="calendaroptionsmenu" class="popupmenu">