diff --git a/plugins/calendar/calendar_ui.js b/plugins/calendar/calendar_ui.js index a93f0504..1a5a38ba 100644 --- a/plugins/calendar/calendar_ui.js +++ b/plugins/calendar/calendar_ui.js @@ -253,6 +253,9 @@ function rcube_calendar_ui(settings) var calendar = event.calendar && me.calendars[event.calendar] ? me.calendars[event.calendar] : { editable:false }; me.selected_event = event; + // allow other plugins to do actions when event form is opened + rcmail.triggerEvent('calendar-event-init', {o: event}); + $dialog.find('div.event-section, div.event-line').hide(); $('#event-title').html(Q(event.title)).show(); @@ -298,7 +301,7 @@ function rcube_calendar_ui(settings) else if (calendar.attachments) { // fetch attachments, some drivers doesn't set 'attachments' prop of the event? } - + // list event attendees if (calendar.attendees && event.attendees) { var data, dispname, organizer = false, rsvp = false, html = ''; @@ -383,7 +386,7 @@ function rcube_calendar_ui(settings) { // close show dialog first $("#eventshow:ui-dialog").dialog('close'); - + var $dialog = $('
'); var calendar = event.calendar && me.calendars[event.calendar] ? me.calendars[event.calendar] : { editable:action=='new' }; me.selected_event = $.extend($.extend({}, event_defaults), event); // clone event object (with defaults) @@ -393,6 +396,9 @@ function rcube_calendar_ui(settings) // reset dialog first $('#eventtabs').get(0).reset(); + // allow other plugins to do actions when event form is opened + rcmail.triggerEvent('calendar-event-init', {o: event}); + // event details var title = $('#edit-title').val(event.title || ''); var location = $('#edit-location').val(event.location || ''); @@ -552,7 +558,6 @@ function rcube_calendar_ui(settings) } }; - // init dialog buttons var buttons = {}; @@ -1411,6 +1416,10 @@ function rcube_calendar_ui(settings) tr.find('a.deletelink').click({ id:(data.email || data.name) }, function(e) { remove_attendee(this, e.data.id); return false; }); tr.find('a.mailtolink').click(function(e) { rcmail.redirect(rcmail.url('mail/compose', { _to:this.href.substr(7) })); return false; }); + + // select organizer identity + if (data.identity_id) + $('#edit-identities-list').val(data.identity_id); // check free-busy status if (avail == 'loading') { @@ -2607,14 +2616,14 @@ function rcube_calendar_ui(settings) $('#event-rsvp input.button').click(function(){ 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'); diff --git a/plugins/kolab_delegation/kolab_delegation.js b/plugins/kolab_delegation/kolab_delegation.js index 75e77b87..1efa70bc 100644 --- a/plugins/kolab_delegation/kolab_delegation.js +++ b/plugins/kolab_delegation/kolab_delegation.js @@ -22,10 +22,18 @@ */ window.rcmail && rcmail.addEventListener('init', function(evt) { - if (rcmail.env.task == 'mail') { + if (rcmail.env.task == 'mail' || rcmail.env.task == 'calendar') { // set delegator context for calendar requests on invitation message rcmail.addEventListener('requestcalendar/event', function(o) { rcmail.event_delegator_request(o); }); rcmail.addEventListener('requestcalendar/mailimportevent', function(o) { rcmail.event_delegator_request(o); }); + + if (rcmail.env.delegators && window.rcube_calendar_ui) { + rcmail.calendar_identity_init(); + // delegator context for calendar event form + rcmail.addEventListener('calendar-event-init', function(o) { return rcmail.calendar_event_init(o); }); + // change organizer identity on calendar folder change + $('#edit-calendar').change(function() { rcmail.calendar_change(); }); + } } else if (rcmail.env.task != 'settings') return; @@ -190,7 +198,7 @@ rcube_webmail.prototype.delegate_save = function() this.http_post('plugin.delegation-save', data, lock); }; - // callback function when saving/deleting has completed successfully +// callback function when saving/deleting has completed successfully rcube_webmail.prototype.delegate_save_complete = function(p) { // delegate created @@ -239,3 +247,78 @@ rcube_webmail.prototype.event_delegator_request = function(data) return data; }; + +// callback for calendar event form initialization +rcube_webmail.prototype.calendar_event_init = function(data) +{ + // set identity for delegator context + this.env.calendar_settings.identity = this.calendar_folder_delegator(data.o.calendar); +}; + +// returns delegator's identity data according to selected calendar folder +rcube_webmail.prototype.calendar_folder_delegator = function(calendar) +{ + var d, delegator; + + $.each(this.env.namespace, function(i, v) { + var delim = v[v.length-1], pos; + if (calendar.indexOf(v) === 0 && (pos = calendar.indexOf(delim, v.length))) { + delegator = calendar.substr(v.length, pos - v.length) + return false; + } + }); + + if (delegator && (d = this.env.delegators[delegator])) { + // find delegator's identity id + if (!d.identity_id) + $.each(this.env.calendar_settings.identities, function(i, v) { + if (d.email == v) { + d.identity_id = i; + return false; + } + }); + + d.uid = delegator; + } + else + d = this.env.original_identity; + + this.env.delegator_context = d.uid; + + return d; +}; + +// handler for calendar folder change +rcube_webmail.prototype.calendar_change = function() +{ + var calendar = $('#edit-calendar').val(), + select = $('#edit-identities-list'), + old = this.env.calendar_settings.identity; + + this.env.calendar_settings.identity = this.calendar_folder_delegator(calendar); + + // change organizer identity in identity selector + if (select.length && old != this.env.calendar_settings.identity) { + // @TODO: run freebusy update? + var id = this.env.calendar_settings.identity.identity_id; + select.val(id ? id : ''); + } +}; + +// modify default identity of the user +rcube_webmail.prototype.calendar_identity_init = function() +{ + var identity = this.env.calendar_settings.identity, + emails = identity.emails.split(';'); + + // remove delegators' emails from list of emails of the current user + emails = $.map(emails, function(v) { + for (var n in rcmail.env.delegators) + if (rcmail.env.delegators[n].emails.indexOf(';'+v) > -1) + return null; + return v; + }); + + identity.emails = emails.join(';'); + this.env.original_identity = identity; +} diff --git a/plugins/kolab_delegation/kolab_delegation.php b/plugins/kolab_delegation/kolab_delegation.php index 6b37e3f3..0adb28ed 100644 --- a/plugins/kolab_delegation/kolab_delegation.php +++ b/plugins/kolab_delegation/kolab_delegation.php @@ -66,6 +66,10 @@ class kolab_delegation extends rcube_plugin $this->include_stylesheet($this->skin_path . '/style.css'); } } + // Calendar plugin UI bindings + else if ($this->rc->task == 'calendar' && empty($_REQUEST['_framed'])) { + $this->calendar_ui(); + } } /** @@ -207,6 +211,21 @@ class kolab_delegation extends rcube_plugin return $args; } + /** + * Delegation support in Calendar plugin UI + */ + public function calendar_ui() + { + // Initialize handling of delegators' identities in event form + + if (!empty($_SESSION['delegators'])) { + $engine = $this->engine(); + $this->rc->output->set_env('namespace', $engine->namespace_js()); + $this->rc->output->set_env('delegators', $engine->list_delegators_js()); + $this->include_script('kolab_delegation.js'); + } + } + /** * Delegation UI handler */ diff --git a/plugins/kolab_delegation/kolab_delegation_engine.php b/plugins/kolab_delegation/kolab_delegation_engine.php index f2a71253..9d100841 100644 --- a/plugins/kolab_delegation/kolab_delegation_engine.php +++ b/plugins/kolab_delegation/kolab_delegation_engine.php @@ -296,6 +296,51 @@ class kolab_delegation_engine return $result; } + /** + * List current user delegators in format compatible with Calendar plugin + * + * @return array List of delegators + */ + public function list_delegators_js() + { + $list = $this->list_delegators(); + $result = array(); + + foreach ($list as $delegator) { + $name = $delegator['name']; + if ($pos = strrpos($name, '(')) { + $name = trim(substr($name, 0, $pos)); + } + + $result[$delegator['imap_uid']] = array( + 'emails' => ';' . implode(';', $delegator['email']), + 'email' => $delegator['email'][0], + 'name' => $name, + ); + } + + return $result; + } + + /** + * Prepare namespace prefixes for JS environment + * + * @return array List of prefixes + */ + public function namespace_js() + { + $storage = $this->rc->get_storage(); + $ns = $storage->get_namespace('other'); + + if ($ns) { + foreach ($ns as $idx => $nsval) { + $ns[$idx] = kolab_storage::folder_id($nsval[0]); + } + } + + return $ns; + } + /** * Get all folders to which current user has admin access *