From e574f572beef16a6de749b74b92999c2e438d511 Mon Sep 17 00:00:00 2001 From: Bogomil Shopov Date: Tue, 14 Jun 2011 15:40:47 +0300 Subject: [PATCH 1/6] Moving the notification logic from driver to the calendar. --- plugins/calendar/calendar.php | 6 ++++-- plugins/calendar/drivers/kolab/kolab_driver.php | 5 ++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php index 08308168..3939ec2c 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 or ($removed && $reload)) $this->rc->output->command('plugin.reload_calendar', array('source' => $event['calendar'])); } diff --git a/plugins/calendar/drivers/kolab/kolab_driver.php b/plugins/calendar/drivers/kolab/kolab_driver.php index 3a54c455..3e9a1869 100644 --- a/plugins/calendar/drivers/kolab/kolab_driver.php +++ b/plugins/calendar/drivers/kolab/kolab_driver.php @@ -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; } From e00cc1e86a1d72c38b5dfd60566327b0835328e8 Mon Sep 17 00:00:00 2001 From: Bogomil Shopov Date: Tue, 14 Jun 2011 15:49:28 +0300 Subject: [PATCH 2/6] 0.Removing mixing of operators 1. Fixing encoding problem in calendar names --- plugins/calendar/calendar.php | 2 +- plugins/calendar/drivers/kolab/kolab_calendar.php | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php index 3939ec2c..fce626a4 100644 --- a/plugins/calendar/calendar.php +++ b/plugins/calendar/calendar.php @@ -435,7 +435,7 @@ class calendar extends rcube_plugin $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 or ($removed && $reload)) + if ($success && $reload || ($removed && $reload)) $this->rc->output->command('plugin.reload_calendar', array('source' => $event['calendar'])); } diff --git a/plugins/calendar/drivers/kolab/kolab_calendar.php b/plugins/calendar/drivers/kolab/kolab_calendar.php index ecb58939..11f0ab89 100644 --- a/plugins/calendar/drivers/kolab/kolab_calendar.php +++ b/plugins/calendar/drivers/kolab/kolab_calendar.php @@ -69,7 +69,8 @@ class kolab_calendar public function get_name() { $dispname = preg_replace(array('!INBOX/Calendar/!', '!^INBOX/!', '!^shared/!', '!^user/([^/]+)/!'), array('','','','(\\1) '), $this->imap_folder); - return strlen($dispname) ? $dispname : $this->imap_folder; + $toret = strlen($dispname) ? $dispname : $this->imap_folder; + return mb_convert_encoding($toret,"UTF8", "UTF7-IMAP"); } /** From 723dd5ffa498f5406f4123bb712c55916f5960df Mon Sep 17 00:00:00 2001 From: Thomas Bruederli Date: Tue, 14 Jun 2011 17:18:28 -0600 Subject: [PATCH 3/6] Use internal charset conversion (mbstring is not mandatory for Roundcube); fix event data output --- plugins/calendar/drivers/kolab/kolab_calendar.php | 15 ++++++++------- plugins/calendar/drivers/kolab/kolab_driver.php | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/plugins/calendar/drivers/kolab/kolab_calendar.php b/plugins/calendar/drivers/kolab/kolab_calendar.php index 11f0ab89..7610e6e9 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( @@ -49,7 +50,7 @@ class kolab_calendar { if ($imap_folder) $this->imap_folder = $imap_folder; - write_log('err_log',$imap_folder); + // ID is derrived from folder name $this->id = strtolower(asciiwords(strtr($this->imap_folder, '/.', '--'))); @@ -69,8 +70,7 @@ class kolab_calendar public function get_name() { $dispname = preg_replace(array('!INBOX/Calendar/!', '!^INBOX/!', '!^shared/!', '!^user/([^/]+)/!'), array('','','','(\\1) '), $this->imap_folder); - $toret = strlen($dispname) ? $dispname : $this->imap_folder; - return mb_convert_encoding($toret,"UTF8", "UTF7-IMAP"); + return rcube_charset_convert(strlen($dispname) ? $dispname : $this->imap_folder, "UTF7-IMAP"); } /** @@ -317,12 +317,13 @@ class kolab_calendar } $sensitivity_map = array_flip($this->sensitivity_map); + $priority_map = array_flip($this->priority_map); return array( 'id' => $rec['uid'], 'uid' => $rec['uid'], - 'title' => $rec['summary'], - 'location' => $rec['location'], + 'title' => strval($rec['summary']), + 'location' => strval($rec['location']), 'description' => $rec['body'], 'start' => $rec['start-date'], 'end' => $rec['end-date'], @@ -331,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, ); @@ -355,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 3e9a1869..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( From dfc86d6ffb42915c785d9e0a2d70cd20053adf23 Mon Sep 17 00:00:00 2001 From: Thomas Bruederli Date: Tue, 14 Jun 2011 17:19:16 -0600 Subject: [PATCH 4/6] Add 'tentative' to driver interface description and database backend --- plugins/calendar/drivers/calendar_driver.php | 2 +- plugins/calendar/drivers/database/database_driver.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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'; From 6ea6dd386b50a579b2ab4e70f89cb4f066c459cc Mon Sep 17 00:00:00 2001 From: Thomas Bruederli Date: Tue, 14 Jun 2011 17:27:19 -0600 Subject: [PATCH 5/6] Better fix: enforce types in wrapper class --- plugins/calendar/calendar.php | 4 ++-- plugins/calendar/drivers/kolab/kolab_calendar.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php index fce626a4..9089383a 100644 --- a/plugins/calendar/calendar.php +++ b/plugins/calendar/calendar.php @@ -603,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/kolab/kolab_calendar.php b/plugins/calendar/drivers/kolab/kolab_calendar.php index 7610e6e9..7b23b2cf 100644 --- a/plugins/calendar/drivers/kolab/kolab_calendar.php +++ b/plugins/calendar/drivers/kolab/kolab_calendar.php @@ -322,8 +322,8 @@ class kolab_calendar return array( 'id' => $rec['uid'], 'uid' => $rec['uid'], - 'title' => strval($rec['summary']), - 'location' => strval($rec['location']), + 'title' => $rec['summary'], + 'location' => $rec['location'], 'description' => $rec['body'], 'start' => $rec['start-date'], 'end' => $rec['end-date'], From 83869428c3a54c4e21fdec2b585612b80aded96e Mon Sep 17 00:00:00 2001 From: Thomas Bruederli Date: Tue, 14 Jun 2011 20:07:17 -0600 Subject: [PATCH 6/6] Fullcalendar: define different modes for list subdivision --- plugins/calendar/calendar.js | 6 +- plugins/calendar/lib/js/fullcalendar.js | 112 +++++++++++------- .../calendar/skins/default/fullcalendar.css | 8 +- 3 files changed, 74 insertions(+), 52 deletions(-) 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/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; }