Merge branch 'master' of ssh://git.kolabsys.com/git/roundcube
This commit is contained in:
commit
b80e40805f
8 changed files with 90 additions and 65 deletions
|
@ -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: {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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']]
|
||||
|
||||
);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<len; i2++) {
|
||||
if (format.charAt(i2) == ']') {
|
||||
var subformat = format.substring(i+1, i2);
|
||||
var subres = formatDate(date, subformat, options);
|
||||
if (subres != formatDate(otherDate, subformat, options)) {
|
||||
var subres = formatDate(otherDate, subformat, options);
|
||||
if (subres != formatDate(date, subformat, options)) {
|
||||
res += subres;
|
||||
}
|
||||
i = i2;
|
||||
|
@ -1605,6 +1606,18 @@ var dateFormatters = {
|
|||
};
|
||||
|
||||
|
||||
// Determine the week of the year based on the ISO 8601 definition.
|
||||
// copied from jquery UI Datepicker
|
||||
var iso8601Week = function(date) {
|
||||
var checkDate = cloneDate(date);
|
||||
// Find Thursday of this week starting on Monday
|
||||
checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
|
||||
var time = checkDate.getTime();
|
||||
checkDate.setMonth(0); // Compare with Jan 1
|
||||
checkDate.setDate(1);
|
||||
return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
|
||||
};
|
||||
|
||||
|
||||
fc.applyAll = applyAll;
|
||||
|
||||
|
@ -5276,7 +5289,7 @@ function ListEventRenderer() {
|
|||
var segs = [];
|
||||
var colFormat = opt('titleFormat', 'day');
|
||||
var firstDay = opt('firstDay');
|
||||
var smartSegs = opt('smartSections');
|
||||
var segmode = opt('listSections');
|
||||
var event, i, dd, wd, md, seg, segHash, curSegHash, segDate, curSeg = -1;
|
||||
var today = clearTime(new Date());
|
||||
var weekstart = addDays(cloneDate(today), -((today.getDay() - firstDay + 7) % 7));
|
||||
|
@ -5296,24 +5309,30 @@ function ListEventRenderer() {
|
|||
md = segDate.getMonth() + ((segDate.getYear() - today.getYear()) * 12) - today.getMonth();
|
||||
|
||||
// build section title
|
||||
if (!smartSegs) {
|
||||
if (segmode == 'smart') {
|
||||
if (dd < 0) {
|
||||
segHash = opt('listTexts', 'past');
|
||||
} else if (dd == 0) {
|
||||
segHash = opt('listTexts', 'today');
|
||||
} else if (dd == 1) {
|
||||
segHash = opt('listTexts', 'tomorrow');
|
||||
} else if (wd == 0) {
|
||||
segHash = opt('listTexts', 'thisWeek');
|
||||
} else if (wd == 1) {
|
||||
segHash = opt('listTexts', 'nextWeek');
|
||||
} else if (md == 0) {
|
||||
segHash = opt('listTexts', 'thisMonth');
|
||||
} else if (md == 1) {
|
||||
segHash = opt('listTexts', 'nextMonth');
|
||||
}
|
||||
} else if (segmode == 'month') {
|
||||
segHash = formatDate(segDate, 'MMMM yyyy');
|
||||
} else if (segmode == 'week') {
|
||||
segHash = opt('listTexts', 'week') + ' ' + iso8601Week(segDate);
|
||||
} else if (segmode == 'day') {
|
||||
segHash = formatDate(segDate, colFormat);
|
||||
} else if (dd < 0) {
|
||||
segHash = opt('listTexts', 'past');
|
||||
} else if (dd == 0) {
|
||||
segHash = opt('listTexts', 'today');
|
||||
} else if (dd == 1) {
|
||||
segHash = opt('listTexts', 'tomorrow');
|
||||
} else if (wd == 0) {
|
||||
segHash = opt('listTexts', 'thisWeek');
|
||||
} else if (wd == 1) {
|
||||
segHash = opt('listTexts', 'nextWeek');
|
||||
} else if (md == 0) {
|
||||
segHash = opt('listTexts', 'thisMonth');
|
||||
} else if (md == 1) {
|
||||
segHash = opt('listTexts', 'nextMonth');
|
||||
} else {
|
||||
segHash = formatDate(segDate, colFormat);
|
||||
segHash = '';
|
||||
}
|
||||
|
||||
// start new segment
|
||||
|
@ -5341,7 +5360,8 @@ function ListEventRenderer() {
|
|||
for (j=0; j < segs.length; j++) {
|
||||
seg = segs[j];
|
||||
|
||||
segHeader = $('<div class="fc-list-header ' + headerClass + '">' + htmlEscape(seg.title) + '</div>').appendTo(getListContainer());
|
||||
if (seg.title)
|
||||
segHeader = $('<div class="fc-list-header ' + headerClass + '">' + htmlEscape(seg.title) + '</div>').appendTo(getListContainer());
|
||||
segContainer = $('<div>').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 = $('<tbody class="fc-list-header"><tr><td class="fc-list-header ' + headerClass + '" colspan="5">' + htmlEscape(seg.title) + '</td></tr></tbody>').appendTo(table);
|
||||
if (seg.title)
|
||||
segHeader = $('<tbody class="fc-list-header"><tr><td class="fc-list-header ' + headerClass + '" colspan="5">' + htmlEscape(seg.title) + '</td></tr></tbody>').appendTo(table);
|
||||
segContainer = $('<tbody>').addClass('fc-list-section ' + contentClass).appendTo(table);
|
||||
s = '';
|
||||
|
||||
|
@ -5618,12 +5642,14 @@ function TableEventRenderer() {
|
|||
"<div class='" + skinClasses.join(' ') + "'" + skinCssAttr + ">" +
|
||||
"<span class='fc-event-inner'></span>" +
|
||||
"</div></td>" +
|
||||
"<td class='fc-event-date'>" +
|
||||
"<td class='fc-event-date' colspan='" + (times[1] ? 1 : 2) + "'>" +
|
||||
htmlEscape(times[0]) +
|
||||
"</td>" +
|
||||
"<td class='fc-event-time'>" +
|
||||
htmlEscape(times[1]) +
|
||||
"</td>" +
|
||||
(times[1] ?
|
||||
"<td class='fc-event-time'>" +
|
||||
htmlEscape(times[1]) +
|
||||
"</td>"
|
||||
: "") +
|
||||
"<td class='fc-event-title'>" +
|
||||
htmlEscape(event.title) +
|
||||
"</td>" +
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue