')
+ .addClass('fc-event-more')
+ .css({ position:'absolute', left:element.css('left'), width:element.css('width') })
+ .appendTo(element.parent())
+ .data('overflow', 1);
+ }
+ else {
+ view._morelink[sday].data('overflow', view._eventcount[sday] - view._maxevents);
+ return false;
+ }
+ }
+ else if (view._eventcount[eday] >= view._maxevents || view._morelink[event.id]) {
+ return false;
+ }
+ }
+ else {
+ if (event.location) {
+ element.find('div.fc-event-title').after('
');
+ }
+ if (event.sensitivity != 0)
+ element.find('div.fc-event-time').append('
');
+ if (event.recurrence)
+ element.find('div.fc-event-time').append('
');
+ if (event.alarms)
+ element.find('div.fc-event-time').append('
');
+ }
+ };
+
/*** public methods ***/
-
+
+ // opens calendar day-view in a popup
+ this.fisheye_view = function(date)
+ {
+ $('#fish-eye-view').dialog('close');
+
+ // create list of active event sources
+ var src, cals = {}, sources = [];
+ for (var id in this.calendars) {
+ src = $.extend({}, this.calendars[id]);
+ src.editable = false;
+ src.url = null;
+ src.events = [];
+
+ if (cal.active) {
+ cals[id] = src;
+ sources.push(src);
+ }
+ }
+
+ // copy events already loaded
+ var events = fc.fullCalendar('clientEvents');
+ for (var event, i=0; i< events.length; i++) {
+ event = events[i];
+ if (event.source && (src = cals[event.source.id])) {
+ src.events.push(event);
+ }
+ }
+
+ var h = $(window).height() - 50;
+ var dialog = $('
')
+ .attr('id', 'fish-eye-view')
+ .dialog({
+ modal: true,
+ width: 680,
+ height: h,
+ title: $.fullCalendar.formatDate(date, 'dddd ' + settings['date_long']),
+ close: function(){
+ dialog.dialog("destroy");
+ me.fisheye_date = null;
+ }
+ })
+ .fullCalendar({
+ header: { left: '', center: '', right: '' },
+ height: h - 50,
+ defaultView: 'agendaDay',
+ date: date.getDate(),
+ month: date.getMonth(),
+ year: date.getFullYear(),
+ ignoreTimezone: true, // will treat the given date strings as in local (browser's) timezone
+ eventSources: sources,
+ monthNames : settings['months'],
+ monthNamesShort : settings['months_short'],
+ dayNames : settings['days'],
+ dayNamesShort : settings['days_short'],
+ firstDay : settings['first_day'],
+ firstHour : settings['first_hour'],
+ slotMinutes : 60/settings['timeslots'],
+ timeFormat: { '': settings['time_format'] },
+ axisFormat : settings['time_format'],
+ columnFormat: { day: 'dddd ' + settings['date_short'] },
+ titleFormat: { day: 'dddd ' + settings['date_long'] },
+ allDayText: rcmail.gettext('all-day', 'calendar'),
+ eventRender: fc_event_render,
+ eventClick: function(event) {
+ event_show_dialog(event);
+ }
+ });
+
+ this.fisheye_date = date;
+ };
+
//public method to show the print dialog.
this.print_calendars = function(view)
{
@@ -1813,6 +1929,9 @@ function rcube_calendar_ui(settings)
});
}
}
+
+ if (this.fisheye_date)
+ this.fisheye_view(this.fisheye_date);
};
// resize and reposition (center) the dialog window
@@ -1955,37 +2074,19 @@ function rcube_calendar_ui(settings)
me.events_loaded($(this).fullCalendar('clientEvents').length);
},
// event rendering
- eventRender: function(event, element, view) {
- if (view.name != 'list' && view.name != 'table') {
- var prefix = event.sensitivity != 0 ? String(sensitivitylabels[event.sensitivity]).toUpperCase()+': ' : '';
- element.attr('title', prefix + event.title);
- }
- if (view.name == 'month') {
-/* attempt to limit the number of events displayed
- (could also be used to init fish-eye-view)
- var max = 4; // to be derrived from window size
- var sday = event.start.getMonth()*12 + event.start.getDate();
- var eday = event.end.getMonth()*12 + event.end.getDate();
- if (!me.eventcount[sday]) me.eventcount[sday] = 1;
- else me.eventcount[sday]++;
- if (!me.eventcount[eday]) me.eventcount[eday] = 1;
- else if (eday != sday) me.eventcount[eday]++;
-
- if (me.eventcount[sday] > max || me.eventcount[eday] > max)
- return false;
-*/
- }
- else {
- if (event.location) {
- element.find('div.fc-event-title').after('
@ ' + Q(event.location) + '
');
- }
- if (event.sensitivity != 0)
- element.find('div.fc-event-time').append('
');
- if (event.recurrence)
- element.find('div.fc-event-time').append('
');
- if (event.alarms)
- element.find('div.fc-event-time').append('
');
+ eventRender: fc_event_render,
+ eventAfterRender: function(event, element, view) {
+ // adjust position of the more... element
+ var link;
+ if (view.name == 'month' && (link = view._morelink[event.id]) && !link.data('date') && link.data('overflow') > 1) {
+ link.html(rcmail.gettext('andnmore', 'calendar').replace('$nr', link.data('overflow')))
+ .css({ left:element.css('left'), top:element.css('top') })
+ .data('date', new Date(event.start.getTime()))
+ .click(function(e){ me.fisheye_view($(this).data('date')); });
+ element.remove();
}
+ else if (link)
+ link.remove();
},
// callback for date range selection
select: function(start, end, allDay, e, view) {
@@ -2066,14 +2167,13 @@ function rcube_calendar_ui(settings)
update_event_confirm('resize', event, data);
},
viewDisplay: function(view) {
- me.eventcount = [];
- if (!bw.ie)
- window.setTimeout(function(){ $('div.fc-content').css('overflow', view.name == 'month' ? 'auto' : 'hidden') }, 10);
if (minical)
window.setTimeout(function(){ minical.datepicker('setDate', fc.fullCalendar('getDate')); }, exec_deferred);
},
- windowResize: function(view) {
- me.eventcount = [];
+ viewRender: function(view) {
+ view._maxevents = Math.floor((view.element.parent().height()-18) / 108) - 1;
+ view._eventcount = [];
+ view._morelink = [];
}
});
@@ -2387,6 +2487,10 @@ window.rcmail && rcmail.addEventListener('init', function(evt) {
event.source = source; // link with source
fc.fullCalendar('renderEvent', event);
}
+
+ // refresh fish-eye view
+ if (cal.fisheye_date)
+ cal.fisheye_view(cal.fisheye_date);
}
// remove temp events
diff --git a/plugins/calendar/lib/fullcalendar-rc.patch b/plugins/calendar/lib/fullcalendar-rc.patch
index e821ce4a..cf723b38 100644
--- a/plugins/calendar/lib/fullcalendar-rc.patch
+++ b/plugins/calendar/lib/fullcalendar-rc.patch
@@ -1,5 +1,5 @@
--- js/fullcalendar.js.orig 2011-04-09 14:13:16.000000000 +0200
-+++ js/fullcalendar.js 2011-08-07 18:43:34.000000000 +0200
++++ js/fullcalendar.js 2011-09-07 11:53:03.000000000 +0200
@@ -47,12 +47,16 @@
titleFormat: {
month: 'MMMM yyyy',
@@ -49,7 +49,15 @@
// jquery-ui theming
theme: false,
-@@ -500,8 +524,8 @@
+@@ -424,6 +448,7 @@
+ setSize();
+ unselect();
+ currentView.clearEvents();
++ currentView.trigger('viewRender', currentView);
+ currentView.renderEvents(events);
+ currentView.sizeDirty = false;
+ }
+@@ -500,8 +525,8 @@
}
@@ -60,7 +68,15 @@
}
-@@ -632,6 +656,8 @@
+@@ -523,6 +548,7 @@
+ markEventsDirty();
+ if (elementVisible()) {
+ currentView.clearEvents();
++ currentView.trigger('viewRender', currentView);
+ currentView.renderEvents(events, modifiedEventID);
+ currentView.eventsDirty = false;
+ }
+@@ -632,6 +658,8 @@
if (name == 'height' || name == 'contentHeight' || name == 'aspectRatio') {
options[name] = value;
updateSize();
@@ -69,7 +85,7 @@
}
}
-@@ -897,15 +923,16 @@
+@@ -897,15 +925,16 @@
}
@@ -90,7 +106,7 @@
}
}
-@@ -1579,10 +1606,23 @@
+@@ -1579,10 +1608,23 @@
return 'th';
}
return ['st', 'nd', 'rd'][date%10-1] || 'th';
@@ -115,7 +131,7 @@
fc.applyAll = applyAll;
-@@ -3534,10 +3574,10 @@
+@@ -3534,10 +3576,10 @@
function slotSelectionMousedown(ev) {
if (ev.which == 1 && opt('selectable')) { // ev.which==1 means left mouse button
unselect(ev);
@@ -128,7 +144,7 @@
var d1 = cellDate(origCell);
var d2 = cellDate(cell);
dates = [
-@@ -3762,7 +3802,8 @@
+@@ -3762,7 +3804,8 @@
height,
slotSegmentContainer = getSlotSegmentContainer(),
rtl, dis, dit,
@@ -138,7 +154,7 @@
if (rtl = opt('isRTL')) {
dis = -1;
-@@ -3789,8 +3830,11 @@
+@@ -3789,8 +3832,11 @@
outerWidth = availWidth / (levelI + forward + 1);
}else{
if (forward) {
@@ -152,7 +168,7 @@
}else{
// can be entire width, aligned left
outerWidth = availWidth;
-@@ -3801,7 +3845,7 @@
+@@ -3801,7 +3847,7 @@
* dis + (rtl ? availWidth - outerWidth : 0); // rtl
seg.top = top;
seg.left = left;
@@ -161,7 +177,7 @@
seg.outerHeight = bottom - top;
html += slotSegHtml(event, seg);
}
-@@ -4260,7 +4304,7 @@
+@@ -4260,7 +4306,7 @@
function opt(name, viewNameOverride) {
var v = options[name];
@@ -170,7 +186,7 @@
return smartProperty(v, viewNameOverride || viewName);
}
return v;
-@@ -5204,5 +5248,561 @@
+@@ -5204,5 +5250,561 @@
};
}
diff --git a/plugins/calendar/lib/js/fullcalendar.js b/plugins/calendar/lib/js/fullcalendar.js
index fe387c8b..9874ee07 100644
--- a/plugins/calendar/lib/js/fullcalendar.js
+++ b/plugins/calendar/lib/js/fullcalendar.js
@@ -448,6 +448,7 @@ function Calendar(element, options, eventSources) {
setSize();
unselect();
currentView.clearEvents();
+ currentView.trigger('viewRender', currentView);
currentView.renderEvents(events);
currentView.sizeDirty = false;
}
@@ -547,6 +548,7 @@ function Calendar(element, options, eventSources) {
markEventsDirty();
if (elementVisible()) {
currentView.clearEvents();
+ currentView.trigger('viewRender', currentView);
currentView.renderEvents(events, modifiedEventID);
currentView.eventsDirty = false;
}
diff --git a/plugins/calendar/localization/de_CH.inc b/plugins/calendar/localization/de_CH.inc
index 44afacc6..3c4b91a5 100644
--- a/plugins/calendar/localization/de_CH.inc
+++ b/plugins/calendar/localization/de_CH.inc
@@ -64,7 +64,7 @@ $labels['printdescriptions'] = 'Beschrieb drucken';
$labels['parentcalendar'] = 'Übergeordneter Kalender';
$labels['searchearlierdates'] = '« Frühere Termine suchen';
$labels['searchlaterdates'] = 'Spätere Termine suchen »';
-$labels['andnmore'] = 'und $nr weitere';
+$labels['andnmore'] = '$nr weitere...';
$labels['togglerole'] = 'Klick zum Ändern der Rolle';
// alarm/reminder settings
diff --git a/plugins/calendar/localization/de_DE.inc b/plugins/calendar/localization/de_DE.inc
index 42ea4c1b..e15784dd 100644
--- a/plugins/calendar/localization/de_DE.inc
+++ b/plugins/calendar/localization/de_DE.inc
@@ -64,7 +64,7 @@ $labels['printdescriptions'] = 'Beschrieb drucken';
$labels['parentcalendar'] = 'Übergeordneter Kalender';
$labels['searchearlierdates'] = '« Frühere Termine suchen';
$labels['searchlaterdates'] = 'Spätere Termine suchen »';
-$labels['andnmore'] = 'und $nr weitere';
+$labels['andnmore'] = '$nr weitere...';
// alarm/reminder settings
$labels['showalarms'] = 'Erinnerungen anzeigen';
diff --git a/plugins/calendar/localization/en_US.inc b/plugins/calendar/localization/en_US.inc
index 986068db..2103fac3 100644
--- a/plugins/calendar/localization/en_US.inc
+++ b/plugins/calendar/localization/en_US.inc
@@ -64,7 +64,7 @@ $labels['printdescriptions'] = 'Print descriptions';
$labels['parentcalendar'] = 'Superior calendar';
$labels['searchearlierdates'] = '« Search for earlier events';
$labels['searchlaterdates'] = 'Search for later events »';
-$labels['andnmore'] = 'and $nr more';
+$labels['andnmore'] = '$nr more...';
$labels['togglerole'] = 'Click to toggle role';
// alarm/reminder settings
diff --git a/plugins/calendar/skins/default/calendar.css b/plugins/calendar/skins/default/calendar.css
index febc8b03..a8b9a09a 100644
--- a/plugins/calendar/skins/default/calendar.css
+++ b/plugins/calendar/skins/default/calendar.css
@@ -1026,6 +1026,13 @@ div.fc-event-location {
font-size: 90%;
}
+.fc-event-more {
+ color: #999;
+ font-size: 90%;
+ padding-top: 1px;
+ cursor: pointer;
+}
+
.fc-agenda-slots td div {
height: 22px;
}