diff --git a/plugins/calendar/calendar.js b/plugins/calendar/calendar.js index 297c76d9..351ac6a3 100644 --- a/plugins/calendar/calendar.js +++ b/plugins/calendar/calendar.js @@ -730,7 +730,7 @@ function rcube_calendar(settings) editable: false }; - fc.fullCalendar('option', 'smartSections', false); + fc.fullCalendar('option', 'listSections', 'day'); fc.fullCalendar('addEventSource', this.search_source); fc.fullCalendar('changeView', 'table'); } @@ -750,7 +750,7 @@ function rcube_calendar(settings) if (this.search_request) { // restore original event sources and view mode from fullcalendar var fc = $(fcselector); - fc.fullCalendar('option', 'smartSections', true); + fc.fullCalendar('option', 'listSections', 'smart'); fc.fullCalendar('removeEventSource', this.search_source); for (var sid in this.calendars) { if (this.calendars[sid] && this.calendars[sid].active) @@ -870,7 +870,7 @@ function rcube_calendar(settings) list: settings['date_long'], table: settings['date_long'] }, - smartSections: true, + listSections: 'smart', defaultView: settings['default_view'], allDayText: rcmail.gettext('all-day', 'calendar'), buttonText: { diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php index 08308168..9089383a 100644 --- a/plugins/calendar/calendar.php +++ b/plugins/calendar/calendar.php @@ -418,7 +418,7 @@ class calendar extends rcube_plugin $reload = true; break; case "remove": - $success = $this->driver->remove_event($event); + $removed = $this->driver->remove_event($event); $reload = true; break; case "dismiss": @@ -429,11 +429,13 @@ class calendar extends rcube_plugin if ($success) $this->rc->output->show_message('successfullysaved', 'confirmation'); + else if ($removed) + $this->rc->output->show_message('calendar.successremoval', 'confirmation'); else $this->rc->output->show_message('calendar.errorsaving', 'error'); // FIXME: update a single event object on the client instead of reloading the entire source - if ($success && $reload) + if ($success && $reload || ($removed && $reload)) $this->rc->output->command('plugin.reload_calendar', array('source' => $event['calendar'])); } @@ -601,8 +603,8 @@ class calendar extends rcube_plugin $json[] = array( 'start' => date('c', $event['start']), // ISO 8601 date (added in PHP 5) 'end' => date('c', $event['end']), // ISO 8601 date (added in PHP 5) - 'description' => $event['description'], - 'location' => $event['location'], + 'description' => strval($event['description']), + 'location' => strval($event['location']), 'className' => ($addcss ? 'fc-event-cal-'.asciiwords($event['calendar'], true).' ' : '') . 'cat-' . asciiwords($event['categories'], true), 'allDay' => ($event['all_day'] == 1)?true:false, ) + $event; diff --git a/plugins/calendar/drivers/calendar_driver.php b/plugins/calendar/drivers/calendar_driver.php index b0687728..d4e732ce 100644 --- a/plugins/calendar/drivers/calendar_driver.php +++ b/plugins/calendar/drivers/calendar_driver.php @@ -46,7 +46,7 @@ * ), * 'recurrence_id' => 'ID of the recurrence group', // usually the ID of the starting event * 'categories' => 'Event category', - * 'free_busy' => 'free|busy|outofoffice', // Show time as + * 'free_busy' => 'free|busy|outofoffice|tentative', // Show time as * 'priority' => 1|0|2, // Event priority (0=low, 1=normal, 2=high) * 'sensitivity' => 0|1|2, // Event sensitivity (0=public, 1=private, 2=confidential) * 'alarms' => '-15M:DISPLAY', // Reminder settings inspired by valarm definition (e.g. display alert 15 minutes before event) diff --git a/plugins/calendar/drivers/database/database_driver.php b/plugins/calendar/drivers/database/database_driver.php index f79f5c63..319f859e 100644 --- a/plugins/calendar/drivers/database/database_driver.php +++ b/plugins/calendar/drivers/database/database_driver.php @@ -35,7 +35,7 @@ class database_driver extends calendar_driver private $cal; private $calendars = array(); private $calendar_ids = ''; - private $free_busy_map = array('free' => 0, 'busy' => 1, 'out-of-office' => 2, 'outofoffice' => 2); + private $free_busy_map = array('free' => 0, 'busy' => 1, 'out-of-office' => 2, 'outofoffice' => 2, 'tentative' => 3); private $db_events = 'events'; private $db_calendars = 'calendars'; diff --git a/plugins/calendar/drivers/kolab/kolab_calendar.php b/plugins/calendar/drivers/kolab/kolab_calendar.php index 8f85c619..0b6dbbf6 100644 --- a/plugins/calendar/drivers/kolab/kolab_calendar.php +++ b/plugins/calendar/drivers/kolab/kolab_calendar.php @@ -26,6 +26,7 @@ class kolab_calendar private $id2uid; private $imap_folder = 'INBOX/Calendar'; private $sensitivity_map = array('public', 'private', 'confidential'); + private $priority_map = array('low', 'normal', 'high'); private $fieldmap = array( @@ -69,7 +70,7 @@ class kolab_calendar { // @TODO: get namespace prefixes from IMAP $dispname = preg_replace(array('!INBOX/Calendar/!', '!^INBOX/!', '!^shared/!', '!^user/([^/]+)/!'), array('','','','(\\1) '), $this->imap_folder); - return strlen($dispname) ? $dispname : $this->imap_folder; + return rcube_charset_convert(strlen($dispname) ? $dispname : $this->imap_folder, "UTF7-IMAP"); } /** @@ -316,6 +317,7 @@ class kolab_calendar } $sensitivity_map = array_flip($this->sensitivity_map); + $priority_map = array_flip($this->priority_map); return array( 'id' => $rec['uid'], @@ -330,7 +332,7 @@ class kolab_calendar 'alarms' => $alarm_value . $alarm_unit, 'categories' => $rec['categories'], 'free_busy' => $rec['show-time-as'], - 'priority' => $rec['priority'], // normal + 'priority' => isset($priority_map[$rec['priority']]) ? $priority_map[$rec['priority']] : 1, 'sensitivity' => $sensitivity_map[$rec['sensitivity']], 'calendar' => $this->id, ); @@ -354,7 +356,7 @@ class kolab_calendar 'end-date'=>$event['end'], 'sensitivity'=>$this->sensitivity_map[$event['sensitivity']], 'show-time-as' => $event['free_busy'], - 'priority' => $event['priority'] + 'priority' => $this->priority_map[$event['priority']] ); diff --git a/plugins/calendar/drivers/kolab/kolab_driver.php b/plugins/calendar/drivers/kolab/kolab_driver.php index 3a54c455..e500a783 100644 --- a/plugins/calendar/drivers/kolab/kolab_driver.php +++ b/plugins/calendar/drivers/kolab/kolab_driver.php @@ -64,7 +64,7 @@ class kolab_driver extends calendar_driver } else { foreach ($folders as $c_folder) { - $calendar = new kolab_calendar($c_folder->name); + $calendar = new kolab_calendar($c_folder->name); $this->folders[$calendar->id] = $calendar; if ($calendar->ready) { $this->calendars[$calendar->id] = array( @@ -209,9 +209,8 @@ class kolab_driver extends calendar_driver public function remove_event($event) { if (($storage = $this->_get_storage($event['calendar'])) && ($ev = $storage->get_event($event['id']))) - $rt = $storage->delete_event($event + $ev); - if($rt==true) - $this->rc->output->show_message('calendar.successremoval', 'success'); return $rt; + return $storage->delete_event($event); + return false; } diff --git a/plugins/calendar/lib/js/fullcalendar.js b/plugins/calendar/lib/js/fullcalendar.js index ab14d202..2dcf33d1 100644 --- a/plugins/calendar/lib/js/fullcalendar.js +++ b/plugins/calendar/lib/js/fullcalendar.js @@ -91,11 +91,12 @@ var defaults = { nextWeek: 'Next week', thisMonth: 'This month', nextMonth: 'Next month', - future: 'Future events' + future: 'Future events', + week: 'W' }, // list options - smartSections: false, + listSections: 'month', // false|'day'|'week'|'month'|'smart' // jquery-ui theming theme: false, @@ -1533,8 +1534,8 @@ function formatDates(date1, date2, format, options) { for (i2=i+1; i2' + htmlEscape(seg.title) + '').appendTo(getListContainer()); + if (seg.title) + segHeader = $('
' + htmlEscape(seg.title) + '
').appendTo(getListContainer()); segContainer = $('
').addClass('fc-list-section ' + contentClass).appendTo(getListContainer()); s = ''; @@ -5408,28 +5428,31 @@ function ListEventRenderer() { function renderEventTime(event, seg) { var timeFormat = opt('timeFormat'); var dateFormat = opt('columnFormat'); + var segmode = opt('listSections'); var duration = event.end.getTime() - event.start.getTime(); var datestr = '', timestr = ''; - if (!opt('smartSections')) { - // no date display if grouped by day - } else if (event.start < seg.start) { - datestr = opt('listTexts', 'until') + ' ' + formatDate(event.end, (event.allDay || event.end.getDate() != seg.start.getDate()) ? dateFormat : timeFormat); - } else if (duration > DAY_MS) { - datestr = formatDates(event.start, event.end, dateFormat + '[ - ' + dateFormat + ']'); - } else if (seg.daydiff == 0) { - datestr = opt('listTexts', 'today'); - } else if (seg.daydiff == 1) { - datestr = opt('listTexts', 'tomorrow'); - } else if (seg.weekdiff == 0 || seg.weekdiff == 1) { - datestr = formatDate(event.start, 'dddd'); - } else if (seg.daydiff > 1 || seg.daydiff < 0) { - datestr = formatDate(event.start, dateFormat); + if (segmode == 'smart') { + if (event.start < seg.start) { + datestr = opt('listTexts', 'until') + ' ' + formatDate(event.end, (event.allDay || event.end.getDate() != seg.start.getDate()) ? dateFormat : timeFormat); + } else if (duration > DAY_MS) { + datestr = formatDates(event.start, event.end, dateFormat + '[ - ' + dateFormat + ']'); + } else if (seg.daydiff == 0) { + datestr = opt('listTexts', 'today'); + } else if (seg.daydiff == 1) { + datestr = opt('listTexts', 'tomorrow'); + } else if (seg.weekdiff == 0 || seg.weekdiff == 1) { + datestr = formatDate(event.start, 'dddd'); + } else if (seg.daydiff > 1 || seg.daydiff < 0) { + datestr = formatDate(event.start, dateFormat); + } + } else if (segmode != 'day') { + datestr = formatDates(event.start, event.end, dateFormat + (duration > DAY_MS ? '[ - ' + dateFormat + ']' : '')); } if (!datestr && event.allDay) { timestr = opt('allDayText'); - } else if (duration < DAY_MS && !event.allDay) { + } else if ((duration < DAY_MS || !datestr) && !event.allDay) { timestr = formatDates(event.start, event.end, timeFormat); } @@ -5581,7 +5604,7 @@ function TableEventRenderer() { events.sort(sortCmp); reportEvents(events); renderSegs(compileSegs(events), modifiedEventId); - getListContainer().removeClass('fc-list-smart fc-list-normal').addClass(opt('smartSections') ? 'fc-list-smart' : 'fc-list-normal'); + getListContainer().removeClass('fc-list-smart fc-list-day fc-list-month fc-list-week').addClass('fc-list-' + opt('listSections')); } function renderSegs(segs, modifiedEventId) { @@ -5594,7 +5617,8 @@ function TableEventRenderer() { for (j=0; j < segs.length; j++) { seg = segs[j]; - segHeader = $('' + htmlEscape(seg.title) + '').appendTo(table); + if (seg.title) + segHeader = $('' + htmlEscape(seg.title) + '').appendTo(table); segContainer = $('').addClass('fc-list-section ' + contentClass).appendTo(table); s = ''; @@ -5618,12 +5642,14 @@ function TableEventRenderer() { "
" + "" + "
" + - "" + + "" + htmlEscape(times[0]) + "" + - "" + - htmlEscape(times[1]) + - "" + + (times[1] ? + "" + + htmlEscape(times[1]) + + "" + : "") + "" + htmlEscape(event.title) + "" + diff --git a/plugins/calendar/skins/default/fullcalendar.css b/plugins/calendar/skins/default/fullcalendar.css index 8103fc8f..42df934c 100644 --- a/plugins/calendar/skins/default/fullcalendar.css +++ b/plugins/calendar/skins/default/fullcalendar.css @@ -629,11 +629,7 @@ table.fc-border-separate { .fc-view-table td.fc-list-header { border-width: 0; border-bottom-width: 1px; - padding: 3px; -} - -.fc-view-table .fc-list-smart td.fc-list-header { - text-align: center; + padding: 3px 5px; } .fc-view-table .fc-first td.fc-list-header { @@ -690,7 +686,7 @@ table.fc-border-separate { width: 7em; } -.fc-view-table .fc-list-normal col.fc-event-date { +.fc-view-table .fc-list-day col.fc-event-date { width: 1px; }