2 commits - plugins/calendar plugins/libkolab plugins/tasklist
Thomas Brüderli
bruederli at kolabsys.com
Wed Mar 25 11:59:28 CET 2015
plugins/calendar/calendar.php | 8
plugins/calendar/calendar_ui.js | 5
plugins/calendar/lib/calendar_ui.php | 18
plugins/calendar/localization/bg_BG.inc | 4
plugins/calendar/localization/ca_ES.inc | 6
plugins/calendar/localization/cs_CZ.inc | 6
plugins/calendar/localization/da_DK.inc | 6
plugins/calendar/localization/de_CH.inc | 2
plugins/calendar/localization/de_DE.inc | 12
plugins/calendar/localization/en_US.inc | 12
plugins/calendar/localization/es_AR.inc | 6
plugins/calendar/localization/es_ES.inc | 2
plugins/calendar/localization/et_EE.inc | 14
plugins/calendar/localization/fi_FI.inc | 13
plugins/calendar/localization/fr_FR.inc | 6
plugins/calendar/localization/it_IT.inc | 6
plugins/calendar/localization/pl_PL.inc | 6
plugins/calendar/localization/pt_PT.inc | 274 ++++++++++++++
plugins/calendar/localization/ru_RU.inc | 9
plugins/calendar/localization/sl_SI.inc | 6
plugins/calendar/localization/sv_SE.inc | 6
plugins/calendar/localization/th_TH.inc | 6
plugins/calendar/localization/uk_UA.inc | 2
plugins/calendar/skins/larry/calendar.css | 4
plugins/calendar/skins/larry/templates/calendar.html | 2
plugins/libkolab/js/audittrail.js | 4
plugins/libkolab/libkolab.php | 18
plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php | 286 ++++++++++++++-
plugins/tasklist/drivers/tasklist_driver.php | 76 +++
plugins/tasklist/localization/en_US.inc | 22 +
plugins/tasklist/skins/larry/tasklist.css | 59 ++-
plugins/tasklist/skins/larry/templates/mainview.html | 79 ++++
plugins/tasklist/tasklist.js | 219 +++++++++++
plugins/tasklist/tasklist.php | 111 +++++
plugins/tasklist/tasklist_ui.php | 2
35 files changed, 1189 insertions(+), 128 deletions(-)
New commits:
commit 548d1d93b70ceb213d2693ab4520e861f9f5b0d9
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Wed Mar 25 11:59:10 2015 +0100
Display object history for tasks (#3271)
diff --git a/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php b/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php
index 4fccf7e..4a192c6 100644
--- a/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php
+++ b/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php
@@ -38,6 +38,7 @@ class tasklist_kolab_driver extends tasklist_driver
private $folders = array();
private $tasks = array();
private $tags = array();
+ private $bonnie_api = false;
/**
@@ -55,6 +56,11 @@ class tasklist_kolab_driver extends tasklist_driver
// tasklist use fully encoded identifiers
kolab_storage::$encode_ids = true;
+ // get configuration for the Bonnie API
+ if ($bonnie_config = $this->rc->config->get('kolab_bonnie_api', false)) {
+ $this->bonnie_api = new kolab_bonnie_api($bonnie_config);
+ }
+
$this->_read_lists();
$this->plugin->register_action('folder-acl', array($this, 'folder_acl'));
@@ -152,6 +158,7 @@ class tasklist_kolab_driver extends tasklist_driver
'group' => $folder->default ? 'default' : $folder->get_namespace(),
'class' => trim($folder->get_namespace() . ($folder->default ? ' default' : '')),
'caldavuid' => $folder->get_uid(),
+ 'history' => !empty($this->bonnie_api),
);
}
@@ -659,6 +666,250 @@ class tasklist_kolab_driver extends tasklist_driver
}
/**
+ * Provide a list of revisions for the given task
+ *
+ * @param array $task Hash array with task properties
+ * @return array List of changes, each as a hash array
+ * @see tasklist_driver::get_task_changelog()
+ */
+ public function get_task_changelog($prop)
+ {
+ if (empty($this->bonnie_api)) {
+ return false;
+ }
+
+ list($uid, $mailbox, $msguid) = $this->_resolve_task_identity($prop);
+
+ $result = $uid && $mailbox ? $this->bonnie_api->changelog('task', $uid, $mailbox, $msguid) : null;
+ if (is_array($result) && $result['uid'] == $uid) {
+ return $result['changes'];
+ }
+
+ return false;
+ }
+
+ /**
+ * Return full data of a specific revision of an event
+ *
+ * @param mixed $task UID string or hash array with task properties
+ * @param mixed $rev Revision number
+ *
+ * @return array Task object as hash array
+ * @see tasklist_driver::get_task_revision()
+ */
+ public function get_task_revison($prop, $rev)
+ {
+ if (empty($this->bonnie_api)) {
+ return false;
+ }
+
+ $this->_parse_id($prop);
+ $uid = $prop['uid'];
+ $list_id = $prop['list'];
+ list($uid, $mailbox, $msguid) = $this->_resolve_task_identity($prop);
+
+ // call Bonnie API
+ $result = $this->bonnie_api->get('task', $uid, $rev, $mailbox, $msguid);
+ if (is_array($result) && $result['uid'] == $uid && !empty($result['xml'])) {
+ $format = kolab_format::factory('task');
+ $format->load($result['xml']);
+ $rec = $format->to_array();
+ $format->get_attachments($rec, true);
+
+ if ($format->is_valid()) {
+ $rec['rev'] = $result['rev'];
+ return self::_to_rcube_task($rec, $list_id, false);
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Command the backend to restore a certain revision of a task.
+ * This shall replace the current object with an older version.
+ *
+ * @param mixed $task UID string or hash array with task properties
+ * @param mixed $rev Revision number
+ *
+ * @return boolean True on success, False on failure
+ * @see tasklist_driver::restore_task_revision()
+ */
+ public function restore_task_revision($prop, $rev)
+ {
+ if (empty($this->bonnie_api)) {
+ return false;
+ }
+
+ $this->_parse_id($prop);
+ $uid = $prop['uid'];
+ $list_id = $prop['list'];
+ list($uid, $mailbox, $msguid) = $this->_resolve_task_identity($prop);
+
+ $folder = $this->get_folder($list_id);
+ $success = false;
+
+ if ($folder && ($raw_msg = $this->bonnie_api->rawdata('task', $uid, $rev, $mailbox))) {
+ $imap = $this->rc->get_storage();
+
+ // insert $raw_msg as new message
+ if ($imap->save_message($folder->name, $raw_msg, null, false)) {
+ $success = true;
+
+ // delete old revision from imap and cache
+ $imap->delete_message($msguid, $folder->name);
+ $folder->cache->set($msguid, false);
+ }
+ }
+
+ return $success;
+ }
+
+ /**
+ * Get a list of property changes beteen two revisions of a task object
+ *
+ * @param array $task Hash array with task properties
+ * @param mixed $rev Revisions: "from:to"
+ *
+ * @return array List of property changes, each as a hash array
+ * @see tasklist_driver::get_task_diff()
+ */
+ public function get_task_diff($prop, $rev1, $rev2)
+ {
+ $this->_parse_id($prop);
+ $uid = $prop['uid'];
+ $list_id = $prop['list'];
+ list($uid, $mailbox, $msguid) = $this->_resolve_task_identity($prop);
+
+ // call Bonnie API
+ $result = $this->bonnie_api->diff('task', $uid, $rev1, $rev2, $mailbox, $msguid, $instance_id);
+ if (is_array($result) && $result['uid'] == $uid) {
+ $result['rev1'] = $rev1;
+ $result['rev2'] = $rev2;
+
+ $keymap = array(
+ 'start' => 'start',
+ 'due' => 'date',
+ 'dstamp' => 'changed',
+ 'summary' => 'title',
+ 'alarm' => 'alarms',
+ 'attendee' => 'attendees',
+ 'attach' => 'attachments',
+ 'rrule' => 'recurrence',
+ 'percent-complete' => 'complete',
+ 'lastmodified-date' => 'changed',
+ );
+ $prop_keymaps = array(
+ 'attachments' => array('fmttype' => 'mimetype', 'label' => 'name'),
+ 'attendees' => array('partstat' => 'status'),
+ );
+ $special_changes = array();
+
+ // map kolab event properties to keys the client expects
+ array_walk($result['changes'], function(&$change, $i) use ($keymap, $prop_keymaps, $special_changes) {
+ if (array_key_exists($change['property'], $keymap)) {
+ $change['property'] = $keymap[$change['property']];
+ }
+ if ($change['property'] == 'priority') {
+ $change['property'] = 'flagged';
+ $change['old'] = $change['old'] == 1 ? $this->plugin->gettext('yes') : null;
+ $change['new'] = $change['new'] == 1 ? $this->plugin->gettext('yes') : null;
+ }
+ // map alarms trigger value
+ if ($change['property'] == 'alarms') {
+ if (is_array($change['old']) && is_array($change['old']['trigger']))
+ $change['old']['trigger'] = $change['old']['trigger']['value'];
+ if (is_array($change['new']) && is_array($change['new']['trigger']))
+ $change['new']['trigger'] = $change['new']['trigger']['value'];
+ }
+ // make all property keys uppercase
+ if ($change['property'] == 'recurrence') {
+ $special_changes['recurrence'] = $i;
+ foreach (array('old','new') as $m) {
+ if (is_array($change[$m])) {
+ $props = array();
+ foreach ($change[$m] as $k => $v) {
+ $props[strtoupper($k)] = $v;
+ }
+ $change[$m] = $props;
+ }
+ }
+ }
+ // map property keys names
+ if (is_array($prop_keymaps[$change['property']])) {
+ foreach ($prop_keymaps[$change['property']] as $k => $dest) {
+ if (is_array($change['old']) && array_key_exists($k, $change['old'])) {
+ $change['old'][$dest] = $change['old'][$k];
+ unset($change['old'][$k]);
+ }
+ if (is_array($change['new']) && array_key_exists($k, $change['new'])) {
+ $change['new'][$dest] = $change['new'][$k];
+ unset($change['new'][$k]);
+ }
+ }
+ }
+
+ if ($change['property'] == 'exdate') {
+ $special_changes['exdate'] = $i;
+ }
+ else if ($change['property'] == 'rdate') {
+ $special_changes['rdate'] = $i;
+ }
+ });
+
+ // merge some recurrence changes
+ foreach (array('exdate','rdate') as $prop) {
+ if (array_key_exists($prop, $special_changes)) {
+ $exdate = $result['changes'][$special_changes[$prop]];
+ if (array_key_exists('recurrence', $special_changes)) {
+ $recurrence = &$result['changes'][$special_changes['recurrence']];
+ }
+ else {
+ $i = count($result['changes']);
+ $result['changes'][$i] = array('property' => 'recurrence', 'old' => array(), 'new' => array());
+ $recurrence = &$result['changes'][$i]['recurrence'];
+ }
+ $key = strtoupper($prop);
+ $recurrence['old'][$key] = $exdate['old'];
+ $recurrence['new'][$key] = $exdate['new'];
+ unset($result['changes'][$special_changes[$prop]]);
+ }
+ }
+
+ return $result;
+ }
+
+ return false;
+ }
+
+ /**
+ * Helper method to resolved the given task identifier into uid and folder
+ *
+ * @return array (uid,folder,msguid) tuple
+ */
+ private function _resolve_task_identity($prop)
+ {
+ $mailbox = $msguid = null;
+
+ $this->_parse_id($prop);
+ $uid = $prop['uid'];
+ $list_id = $prop['list'];
+
+ if ($folder = $this->get_folder($list_id)) {
+ $mailbox = $folder->get_mailbox_id();
+
+ // get task object from storage in order to get the real object uid an msguid
+ if ($rec = $folder->get_object($uid)) {
+ $msguid = $rec['_msguid'];
+ $uid = $rec['uid'];
+ }
+ }
+
+ return array($uid, $mailbox, $msguid);
+ }
+
+
+ /**
* Get a list of pending alarms to be displayed to the user
*
* @param integer Current time (unix timestamp)
@@ -1232,6 +1483,7 @@ class tasklist_kolab_driver extends tasklist_driver
* @param array $task Hash array with event properties:
* id: Task identifier
* list: List identifier
+ * rev: Revision (optional)
*
* @return array Hash array with attachment properties:
* id: Attachment identifier
@@ -1241,7 +1493,13 @@ class tasklist_kolab_driver extends tasklist_driver
*/
public function get_attachment($id, $task)
{
- $task = $this->get_task($task);
+ // get old revision of the object
+ if ($task['rev']) {
+ $task = $this->get_task_revison($task, $task['rev']);
+ }
+ else {
+ $task = $this->get_task($task);
+ }
if ($task && !empty($task['attachments'])) {
foreach ($task['attachments'] as $att) {
@@ -1260,12 +1518,38 @@ class tasklist_kolab_driver extends tasklist_driver
* @param array $task Hash array with event properties:
* id: Task identifier
* list: List identifier
+ * rev: Revision (optional)
*
* @return string Attachment body
*/
public function get_attachment_body($id, $task)
{
$this->_parse_id($task);
+
+ // get old revision of event
+ if ($task['rev']) {
+ if (empty($this->bonnie_api)) {
+ return false;
+ }
+
+ $cid = substr($id, 4);
+
+ // call Bonnie API and get the raw mime message
+ list($uid, $mailbox, $msguid) = $this->_resolve_task_identity($task);
+ if ($msg_raw = $this->bonnie_api->rawdata('task', $uid, $task['rev'], $mailbox, $msguid)) {
+ // parse the message and find the part with the matching content-id
+ $message = rcube_mime::parse_message($msg_raw);
+ foreach ((array)$message->parts as $part) {
+ if ($part->headers['content-id'] && trim($part->headers['content-id'], '<>') == $cid) {
+ return $part->body;
+ }
+ }
+ }
+
+ return false;
+ }
+
+
if ($storage = $this->get_folder($task['list'])) {
return $storage->get_attachment($task['uid'], $id);
}
diff --git a/plugins/tasklist/drivers/tasklist_driver.php b/plugins/tasklist/drivers/tasklist_driver.php
index 3362e7f..be82344 100644
--- a/plugins/tasklist/drivers/tasklist_driver.php
+++ b/plugins/tasklist/drivers/tasklist_driver.php
@@ -242,6 +242,7 @@ abstract class tasklist_driver
*
* @param array Hash array with task properties:
* id: Task identifier
+ * list: Tasklist identifer
* @param boolean Remove record irreversible (mark as deleted otherwise, if supported by the backend)
* @return boolean True on success, False on error
*/
@@ -266,6 +267,7 @@ abstract class tasklist_driver
* @param array $task Hash array with event properties:
* id: Task identifier
* list: List identifier
+ * rev: Revision (optional)
*
* @return array Hash array with attachment properties:
* id: Attachment identifier
@@ -282,6 +284,7 @@ abstract class tasklist_driver
* @param array $task Hash array with event properties:
* id: Task identifier
* list: List identifier
+ * rev: Revision (optional)
*
* @return string Attachment body
*/
@@ -319,7 +322,7 @@ abstract class tasklist_driver
/**
* Helper method to determine whether the given task is considered "complete"
*
- * @param array $task Hash array with event properties:
+ * @param array $task Hash array with event properties
* @return boolean True if complete, False otherwiese
*/
public function is_complete($task)
@@ -328,13 +331,74 @@ abstract class tasklist_driver
}
/**
- * List availabale categories
- * The default implementation reads them from config/user prefs
+ * Provide a list of revisions for the given task
+ *
+ * @param array $task Hash array with task properties:
+ * id: Task identifier
+ * list: List identifier
+ *
+ * @return array List of changes, each as a hash array:
+ * rev: Revision number
+ * type: Type of the change (create, update, move, delete)
+ * date: Change date
+ * user: The user who executed the change
+ * ip: Client IP
+ * mailbox: Destination list for 'move' type
*/
- public function list_categories()
+ public function get_task_changelog($task)
{
- $rcmail = rcube::get_instance();
- return $rcmail->config->get('tasklist_categories', array());
+ return false;
+ }
+
+ /**
+ * Get a list of property changes beteen two revisions of a task object
+ *
+ * @param array $task Hash array with task properties:
+ * id: Task identifier
+ * list: List identifier
+ * @param mixed $rev1 Old Revision
+ * @param mixed $rev2 New Revision
+ *
+ * @return array List of property changes, each as a hash array:
+ * property: Revision number
+ * old: Old property value
+ * new: Updated property value
+ */
+ public function get_task_diff($task, $rev1, $rev2)
+ {
+ return false;
+ }
+
+ /**
+ * Return full data of a specific revision of an event
+ *
+ * @param mixed $task UID string or hash array with task properties:
+ * id: Task identifier
+ * list: List identifier
+ * @param mixed $rev Revision number
+ *
+ * @return array Task object as hash array
+ * @see self::get_task()
+ */
+ public function get_task_revison($task, $rev)
+ {
+ return false;
+ }
+
+ /**
+ * Command the backend to restore a certain revision of a task.
+ * This shall replace the current object with an older version.
+ *
+ * @param mixed $task UID string or hash array with task properties:
+ * id: Task identifier
+ * list: List identifier
+ * @param mixed $rev Revision number
+ *
+ * @return boolean True on success, False on failure
+ */
+ public function restore_task_revision($task, $rev)
+ {
+ return false;
}
/**
diff --git a/plugins/tasklist/localization/en_US.inc b/plugins/tasklist/localization/en_US.inc
index ee66759..8dc2929 100644
--- a/plugins/tasklist/localization/en_US.inc
+++ b/plugins/tasklist/localization/en_US.inc
@@ -50,6 +50,9 @@ $labels['status-cancelled'] = 'Cancelled';
$labels['assignedto'] = 'Assigned to';
$labels['created'] = 'Created';
$labels['changed'] = 'Last Modified';
+$labels['taskoptions'] = 'Options';
+$labels['taskhistory'] = 'History';
+$labels['compare'] = 'Compare';
$labels['all'] = 'All';
$labels['flagged'] = 'Flagged';
@@ -101,6 +104,7 @@ $labels['on'] = 'on';
$labels['at'] = 'at';
$labels['this'] = 'this';
$labels['next'] = 'next';
+$labels['yes'] = 'yes';
// messages
$labels['savingdata'] = 'Saving data...';
@@ -150,6 +154,24 @@ $labels['itipcancelsubject'] = '"$title" has been canceled';
$labels['itipcancelmailbody'] = "*\$title*\n\nDue: \$date\n\nAssignees: \$attendees\n\nThe task has been cancelled by \$organizer.\n\nPlease find attached an iCalendar file with the updated task details.";
$labels['saveintasklist'] = 'save in ';
+// history dialog
+$labels['objectchangelog'] = 'Change History';
+$labels['objectdiff'] = 'Changes from $rev1 to $rev2';
+
+$labels['actionappend'] = 'Saved';
+$labels['actionmove'] = 'Moved';
+$labels['actiondelete'] = 'Deleted';
+$labels['compare'] = 'Compare';
+$labels['showrevision'] = 'Show this version';
+$labels['restore'] = 'Restore this version';
+
+$labels['objectnotfound'] = 'Failed to load task data';
+$labels['objectchangelognotavailable'] = 'Change history is not available for this task';
+$labels['objectdiffnotavailable'] = 'No comparison possible for the selected revisions';
+$labels['revisionrestoreconfirm'] = 'Do you really want to restore revision $rev of this task? This will replace the current task with the old version.';
+$labels['objectrestoresuccess'] = 'Revision $rev successfully restored';
+$labels['objectrestoreerror'] = 'Failed to restore the old revision';
+
// invitation handling (overrides labels from libcalendaring)
$labels['itipobjectnotfound'] = 'The task referred by this message was not found in your tasks list.';
diff --git a/plugins/tasklist/skins/larry/tasklist.css b/plugins/tasklist/skins/larry/tasklist.css
index bd5ec60..a39c1f2 100644
--- a/plugins/tasklist/skins/larry/tasklist.css
+++ b/plugins/tasklist/skins/larry/tasklist.css
@@ -642,7 +642,8 @@ ul.toolbarmenu li span.icon.taskadd,
font-size: 12px;
}
-.taskhead .flagged {
+.taskhead .flagged,
+.taskshow.status-flagged h2:after {
display: inline-block;
width: 16px;
height: 16px;
@@ -657,7 +658,8 @@ ul.toolbarmenu li span.icon.taskadd,
background-position: -2px -3px;
}
-.taskhead.flagged .flagged {
+.taskhead.flagged .flagged,
+.taskshow.status-flagged h2:after {
background-position: -2px -23px;
}
@@ -839,8 +841,9 @@ ul.toolbarmenu .sortcol.by-auto a {
/*** task edit form ***/
#taskedit,
-#taskshow {
- display:none;
+#taskshow,
+#taskdiff {
+ display: none;
}
#taskedit {
@@ -850,15 +853,32 @@ ul.toolbarmenu .sortcol.by-auto a {
margin: 0 -0.2em;
}
-#taskshow h2 {
+.taskshow h2 {
margin-top: -0.5em;
}
-#taskshow label {
+#taskdiff h2 {
+ font-size: 18px;
+ margin: -0.3em 0 0.4em 0;
+}
+
+.taskshow.status-completed h2 {
+ text-decoration: line-through;
+}
+
+.taskshow.status-flagged h2:after {
+ content: " ";
+ position: relative;
+ margin-left: 0.6em;
+ top: 1px;
+ cursor: default;
+}
+
+.taskshow label {
color: #999;
}
-#taskshow.status-cancelled {
+.taskshow.status-cancelled {
background: url(images/badge_cancelled.png) top right no-repeat;
}
@@ -1048,10 +1068,33 @@ label.block {
margin-bottom: 0.3em;
}
-#task-description {
+.task-description {
margin-bottom: 1em;
}
+.taskshow .task-text-old,
+.taskshow .task-text-new,
+.taskshow .task-text-diff {
+ padding: 2px;
+}
+
+.taskshow .task-text-diff del,
+.taskshow .task-text-diff ins {
+ text-decoration: none;
+ color: inherit;
+}
+
+.taskshow .task-text-old,
+.taskshow .task-text-diff del {
+ background-color: #fdd;
+ /* text-decoration: line-through; */
+}
+
+.taskshow .task-text-new,
+.taskshow .task-text-diff ins {
+ background-color: #dfd;
+}
+
#taskedit-completeness-slider {
display: inline-block;
margin-left: 2em;
diff --git a/plugins/tasklist/skins/larry/templates/mainview.html b/plugins/tasklist/skins/larry/templates/mainview.html
index f80b2f7..dd38409 100644
--- a/plugins/tasklist/skins/larry/templates/mainview.html
+++ b/plugins/tasklist/skins/larry/templates/mainview.html
@@ -149,6 +149,9 @@
<li role="menuitem"><roundcube:button name="edit" type="link" onclick="rctasks.edit_task(rctasks.selected_task.id, 'edit'); return false" label="edit" class="icon active" innerclass="icon edit" /></li>
<li role="menuitem"><roundcube:button name="delete" type="link" onclick="rctasks.delete_task(rctasks.selected_task.id); return false" label="delete" class="icon active" innerclass="icon delete" /></li>
<li role="menuitem"><roundcube:button name="addchild" type="link" onclick="rctasks.add_childtask(rctasks.selected_task.id); return false" label="tasklist.addsubtask" class="icon active" innerclass="icon add" /></li>
+ <roundcube:if condition="env:tasklist_driver == 'kolab' && config:kolab_bonnie_api" />
+ <li role="menuitem"><roundcube:button command="task-history" type="link" label="tasklist.taskhistory" class="icon" classAct="icon active" innerclass="icon history" /></li>
+ <roundcube:endif />
</ul>
</div>
@@ -159,12 +162,12 @@
<roundcube:object name="message" id="messagestack" />
-<div id="taskshow">
+<div id="taskshow" class="taskshow">
<div class="form-section" id="task-parent-title"></div>
<div class="form-section">
<h2 id="task-title"></h2>
</div>
- <div id="task-description" class="form-section">
+ <div id="task-description" class="form-section task-description">
</div>
<div id="task-tags" class="form-section">
<label><roundcube:label name="tasklist.tags" /></label>
@@ -239,6 +242,78 @@
<roundcube:object name="plugin.task_rsvp_buttons" id="task-rsvp" class="task-dialog-message" style="display:none" />
</div>
+<roundcube:if condition="env:tasklist_driver == 'kolab' && config:kolab_bonnie_api" />
+<div id="taskhistory" class="uidialog" aria-hidden="true">
+ <roundcube:object name="plugin.object_changelog_table" class="records-table changelog-table" domain="calendar" />
+ <div class="compare-button"><input type="button" class="button" value="â³ <roundcube:label name='tasklist.compare' />" /></div>
+</div>
+
+<div id="taskdiff" class="uidialog taskshow" aria-hidden="true">
+ <h2 class="task-title">Task Title</h2>
+ <h2 class="task-title-new task-text-new"></h2>
+ <div class="form-section task-description">
+ <label><roundcube:label name="calendar.description" /></label>
+ <div class="task-text-diff" style="white-space:pre-wrap"></div>
+ <div class="task-text-old"></div>
+ <div class="task-text-new"></div>
+ </div>
+ <div class="form-section task-flagged">
+ <label><roundcube:label name="tasklist.flagged" /></label>
+ <span class="task-text-old"></span> ⇢
+ <span class="task-text-new"></span>
+ </div>
+ <div class="form-section task-start">
+ <label><roundcube:label name="tasklist.start" /></label>
+ <span class="task-text-old"></span> ⇢
+ <span class="task-text-new"></span>
+ </div>
+ <div class="form-section task-date">
+ <label><roundcube:label name="tasklist.datetime" /></label>
+ <span class="task-text-old"></span> ⇢
+ <span class="task-text-new"></span>
+ </div>
+ <div class="form-section task-recurrence">
+ <label><roundcube:label name="tasklist.repeat" /></label>
+ <span class="task-text-old"></span> ⇢
+ <span class="task-text-new"></span>
+ </div>
+ <div class="form-section task-alarms">
+ <label><roundcube:label name="tasklist.alarms" /></label>
+ <span class="task-text-old"></span> ⇢
+ <span class="task-text-new"></span>
+ </div>
+ <div class="form-section task-attendees">
+ <label><roundcube:label name="tasklist.assignedto" /></label>
+ <span class="task-text-old"></span> ⇢
+ <span class="task-text-new"></span>
+ </div>
+ <div class="form-section task-organizer">
+ <label><roundcube:label name="tasklist.roleorganizer" /></label>
+ <span class="task-text-old"></span> ⇢
+ <span class="task-text-new"></span>
+ </div>
+ <div class="form-section task-complete">
+ <label><roundcube:label name="tasklist.complete" /></label>
+ <span class="task-text-old"></span> ⇢
+ <span class="task-text-new"></span>
+ </div>
+ <div class="form-section task-status">
+ <label><roundcube:label name="tasklist.status" /></label>
+ <span class="task-text-old"></span> ⇢
+ <span class="task-text-new"></span>
+ </div>
+ <div class="form-section task-links">
+ <label><roundcube:label name="tasklist.links" /></label>
+ <span class="task-text"></span>
+ </div>
+ <div class="form-section task-attachments">
+ <label><roundcube:label name="attachments" /></label>
+ <div class="task-text-old"></div>
+ <div class="task-text-new"></div>
+ </div>
+</div>
+<roundcube:endif />
+
<roundcube:include file="/templates/taskedit.html" />
<div id="tasklistform" class="uidialog">
diff --git a/plugins/tasklist/tasklist.js b/plugins/tasklist/tasklist.js
index a01689f..514d060 100644
--- a/plugins/tasklist/tasklist.js
+++ b/plugins/tasklist/tasklist.js
@@ -282,8 +282,14 @@ function rcube_tasklist_ui(settings)
setTimeout(fetch_counts, 200);
});
+ rcmail.addEventListener('plugin.task_render_changelog', task_render_changelog);
+ rcmail.addEventListener('plugin.task_show_diff', task_show_diff);
+ rcmail.addEventListener('plugin.task_show_revision', function(data){ task_show_dialog(null, data, true); });
+ rcmail.addEventListener('plugin.close_history_dialog', close_history_dialog);
+
rcmail.register_command('list-sort', list_set_sort, true);
rcmail.register_command('list-order', list_set_order, (settings.sort_col || 'auto') != 'auto');
+ rcmail.register_command('task-history', task_history_dialog, false);
$('#taskviewsortmenu .by-' + (settings.sort_col || 'auto')).attr('aria-checked', 'true').addClass('selected');
$('#taskviewsortmenu .sortorder.' + (settings.sort_order || 'asc')).attr('aria-checked', 'true').addClass('selected');
@@ -459,6 +465,7 @@ function rcube_tasklist_ui(settings)
rcmail.command('menu-close', 'taskitemmenu');
}
else {
+ rcmail.enable_command('task-history', me.tasklists[rec.list] && !!me.tasklists[rec.list].history);
rcmail.command('menu-open', { menu: 'taskitemmenu', show: true }, e.target, e);
menu.data('refid', id);
me.selected_task = rec;
@@ -1835,7 +1842,7 @@ function rcube_tasklist_ui(settings)
/**
* Show task details in a dialog
*/
- function task_show_dialog(id)
+ function task_show_dialog(id, data, temp)
{
var $dialog = $('#taskshow'), rec, list;
@@ -1848,7 +1855,7 @@ function rcube_tasklist_ui(settings)
return $.grep(oldies, function(cls) { return cls.indexOf('status-') === 0 }).join(' ');
});
- if (!(rec = listdata[id]) || (rcmail.menu_stack && rcmail.menu_stack.length > 0))
+ if (!(rec = (data || listdata[id])) || (rcmail.menu_stack && rcmail.menu_stack.length > 0))
return;
me.selected_task = rec;
@@ -1892,6 +1899,10 @@ function rcube_tasklist_ui(settings)
$dialog.addClass('status-' + String(rec.status).toLowerCase());
}
+ if (rec.flagged) {
+ $dialog.addClass('status-flagged');
+ }
+
if (rec.recurrence && rec.recurrence_text) {
$('#task-recurrence').show().children('.task-text').html(Q(rec.recurrence_text));
}
@@ -1986,7 +1997,7 @@ function rcube_tasklist_ui(settings)
.html(Q(rcmail.gettext('itip' + mystatus, 'libcalendaring')));
}
*/
- var show_rsvp = rsvp && list.editable && !is_organizer(rec) && rec.status != 'CANCELLED';
+ var show_rsvp = !temp && rsvp && list.editable && !is_organizer(rec) && rec.status != 'CANCELLED';
$('#task-rsvp')[(show_rsvp ? 'show' : 'hide')]();
$('#task-rsvp .rsvp-buttons input').prop('disabled', false).filter('input[rel='+mystatus+']').prop('disabled', true);
@@ -2036,6 +2047,13 @@ function rcube_tasklist_ui(settings)
},
close: function() {
$dialog.dialog('destroy').appendTo(document.body);
+ $('.libcal-rsvp-replymode').hide();
+ },
+ dragStart: function() {
+ $('.libcal-rsvp-replymode').hide();
+ },
+ resizeStart: function() {
+ $('.libcal-rsvp-replymode').hide();
},
buttons: buttons,
minWidth: 500,
@@ -2065,6 +2083,190 @@ function rcube_tasklist_ui(settings)
}
/**
+ *
+ */
+ function task_history_dialog()
+ {
+ var dialog, rec = me.selected_task;
+ if (!rec || !rec.id || !window.libkolab_audittrail) {
+ return false;
+ }
+
+ // render dialog
+ $dialog = libkolab_audittrail.object_history_dialog({
+ module: 'tasklist',
+ container: '#taskhistory',
+ title: rcmail.gettext('objectchangelog','tasklist') + ' - ' + rec.title,
+
+ // callback function for list actions
+ listfunc: function(action, rev) {
+ var rec = $dialog.data('rec');
+ saving_lock = rcmail.set_busy(true, 'loading', saving_lock);
+ rcmail.http_post('task', { action: action, t: { id: rec.id, list:rec.list, rev: rev } }, saving_lock);
+ },
+
+ // callback function for comparing two object revisions
+ comparefunc: function(rev1, rev2) {
+ var rec = $dialog.data('rec');
+ saving_lock = rcmail.set_busy(true, 'loading', saving_lock);
+ rcmail.http_post('task', { action:'diff', t: { id: rec.id, list: rec.list, rev1: rev1, rev2: rev2 } }, saving_lock);
+ }
+ });
+
+ $dialog.data('rec', rec);
+
+ // fetch changelog data
+ saving_lock = rcmail.set_busy(true, 'loading', saving_lock);
+ rcmail.http_post('task', { action: 'changelog', t: { id: rec.id, list: rec.list } }, saving_lock);
+ }
+
+ /**
+ *
+ */
+ function task_render_changelog(data)
+ {
+ var $dialog = $('#taskhistory'),
+ rec = $dialog.data('rec');
+
+ if (data === false || !data.length || !event) {
+ // display 'unavailable' message
+ $('<div class="notfound-message task-dialog-message warning">' + rcmail.gettext('objectchangelognotavailable','tasklist') + '</div>')
+ .insertBefore($dialog.find('.changelog-table').hide());
+ return;
+ }
+
+ data.module = 'tasklist';
+ libkolab_audittrail.render_changelog(data, rec, me.tasklists[rec.list]);
+
+ // set dialog size according to content
+ me.dialog_resize($dialog.get(0), $dialog.height(), 600);
+ }
+
+ /**
+ *
+ */
+ function task_show_diff(data)
+ {
+ var rec = me.selected_task,
+ $dialog = $("#taskdiff");
+
+ $dialog.find('div.form-section, h2.task-title-new').hide().data('set', false).find('.index').html('');
+ $dialog.find('div.form-section.clone').remove();
+
+ // always show event title and date
+ $('.task-title', $dialog).text(rec.title).removeClass('task-text-old').show();
+
+ // show each property change
+ $.each(data.changes, function(i, change) {
+ var prop = change.property, r2, html = false,
+ row = $('div.task-' + prop, $dialog).first();
+
+ // special case: title
+ if (prop == 'title') {
+ $('.task-title', $dialog).addClass('task-text-old').text(change['old'] || '--');
+ $('.task-title-new', $dialog).text(change['new'] || '--').show();
+ }
+
+ // no display container for this property
+ if (!row.length) {
+ return true;
+ }
+
+ // clone row if already exists
+ if (row.data('set')) {
+ r2 = row.clone().addClass('clone').insertAfter(row);
+ row = r2;
+ }
+
+ // render description text
+ if (prop == 'description') {
+ if (!change.diff_ && change['old']) change.old_ = text2html(change['old']);
+ if (!change.diff_ && change['new']) change.new_ = text2html(change['new']);
+ html = true;
+ }
+ // format attendees struct
+ else if (prop == 'attendees') {
+ if (change['old']) change.old_ = task_attendee_html(change['old']);
+ if (change['new']) change.new_ = task_attendee_html($.extend({}, change['old'] || {}, change['new']));
+ html = true;
+ }
+ // localize status
+ else if (prop == 'status') {
+ if (change['old']) change.old_ = rcmail.gettext('status-'+String(change['old']).toLowerCase(), 'tasklist');
+ if (change['new']) change.new_ = rcmail.gettext('status-'+String(change['new']).toLowerCase(), 'tasklist');
+ }
+
+ // format attachments struct
+ if (prop == 'attachments') {
+ if (change['old']) task_show_attachments([change['old']], row.children('.task-text-old'), rec, false);
+ else row.children('.task-text-old').text('--');
+ if (change['new']) task_show_attachments([$.extend({}, change['old'] || {}, change['new'])], row.children('.task-text-new'), rec, false);
+ else row.children('.task-text-new').text('--');
+ // remove click handler in diff view
+ $('.attachmentslist li a', row).unbind('click').removeAttr('href');
+ }
+ else if (change.diff_) {
+ row.children('.task-text-diff').html(change.diff_);
+ row.children('.task-text-old, .task-text-new').hide();
+ }
+ else {
+ if (!html) {
+ // escape HTML characters
+ change.old_ = Q(change.old_ || change['old'] || '--')
+ change.new_ = Q(change.new_ || change['new'] || '--')
+ }
+ row.children('.task-text-old').html(change.old_ || change['old'] || '--').show();
+ row.children('.task-text-new').html(change.new_ || change['new'] || '--').show();
+ }
+
+ // display index number
+ if (typeof change.index != 'undefined') {
+ row.find('.index').html('(' + change.index + ')');
+ }
+
+ row.show().data('set', true);
+ });
+
+ var buttons = {};
+ buttons[rcmail.gettext('close')] = function() {
+ $dialog.dialog('close');
+ };
+
+ // open jquery UI dialog
+ $dialog.dialog({
+ modal: false,
+ resizable: true,
+ closeOnEscape: true,
+ title: rcmail.gettext('objectdiff','tasklist').replace('$rev1', data.rev1).replace('$rev2', data.rev2) + ' - ' + rec.title,
+ open: function() {
+ $dialog.attr('aria-hidden', 'false');
+ setTimeout(function(){
+ $dialog.parent().find('.ui-button:not(.ui-dialog-titlebar-close)').first().focus();
+ }, 5);
+ },
+ close: function() {
+ $dialog.dialog('destroy').attr('aria-hidden', 'true').hide();
+ },
+ buttons: buttons,
+ minWidth: 320,
+ width: 450
+ }).show();
+
+ // set dialog size according to content
+ me.dialog_resize($dialog.get(0), $dialog.height(), 400);
+ }
+
+ // close the event history dialog
+ function close_history_dialog()
+ {
+ $('#taskhistory, #taskdiff').each(function(i, elem) {
+ var $dialog = $(elem);
+ if ($dialog.is(':ui-dialog'))
+ $dialog.dialog('close');
+ });
+ };
+
+ /**
* Opens the dialog to edit a task
*/
function task_edit_dialog(id, action, presets)
@@ -2371,17 +2573,22 @@ function rcube_tasklist_ui(settings)
if (!rec.id || rec.id < 0)
return false;
- var qstring = '_id='+urlencode(att.id)+'&_t='+urlencode(rec.recurrence_id||rec.id)+'&_list='+urlencode(rec.list);
+ var query = { _id: att.id, _t: rec.recurrence_id||rec.id, _list:rec.list, _frame: 1 };
+ if (rec.rev)
+ query._rev = event.rev;
+
// open attachment in frame if it's of a supported mimetype
// similar as in app.js and calendar_ui.js
if (att.id && att.mimetype && $.inArray(att.mimetype, settings.mimetypes)>=0) {
- if (rcmail.open_window(rcmail.env.comm_path+'&_action=get-attachment&'+qstring+'&_frame=1', true, true)) {
+ if (rcmail.open_window(rcmail.url('get-attachment', query), true, true)) {
return;
}
}
- rcmail.goto_url('get-attachment', qstring+'&_download=1', false);
+ query._frame = null;
+ query._download = 1;
+ rcmail.goto_url('get-attachment', query, false);
};
/**
diff --git a/plugins/tasklist/tasklist.php b/plugins/tasklist/tasklist.php
index 780602c..449f43c 100644
--- a/plugins/tasklist/tasklist.php
+++ b/plugins/tasklist/tasklist.php
@@ -208,7 +208,7 @@ class tasklist extends rcube_plugin
$action = rcube_utils::get_input_value('action', rcube_utils::INPUT_GPC);
$rec = rcube_utils::get_input_value('t', rcube_utils::INPUT_POST, true);
$oldrec = $rec;
- $success = $refresh = false;
+ $success = $refresh = $got_msg = false;
// force notify if hidden + active
$itip_send_option = (int)$this->rc->config->get('calendar_itip_send_option', 3);
@@ -385,13 +385,115 @@ class tasklist extends rcube_plugin
}
}
break;
+
+ case 'changelog':
+ $data = $this->driver->get_task_changelog($rec);
+ if (is_array($data) && !empty($data)) {
+ $lib = $this->lib;
+ $dtformat = $this->rc->config->get('date_format') . ' ' . $this->rc->config->get('time_format');
+ array_walk($data, function(&$change) use ($lib, $dtformat) {
+ if ($change['date']) {
+ $dt = $lib->adjust_timezone($change['date']);
+ if ($dt instanceof DateTime)
+ $change['date'] = $this->rc->format_date($dt, $dtformat, false);
+ }
+ });
+ $this->rc->output->command('plugin.task_render_changelog', $data);
+ }
+ else {
+ $this->rc->output->command('plugin.task_render_changelog', false);
+ }
+ $got_msg = true;
+ break;
+
+ case 'diff':
+ $data = $this->driver->get_task_diff($rec, $rec['rev1'], $rec['rev2']);
+ if (is_array($data)) {
+ // convert some properties, similar to self::_client_event()
+ $lib = $this->lib;
+ $date_format = $this->rc->config->get('date_format', 'Y-m-d');
+ $time_format = $this->rc->config->get('time_format', 'H:i');
+ array_walk($data['changes'], function(&$change, $i) use ($lib, $date_format, $time_format) {
+ // convert date cols
+ if (in_array($change['property'], array('date','start','created','changed'))) {
+ if (!empty($change['old'])) {
+ $dtformat = strlen($change['old']) == 10 ? $date_format : $date_format . ' ' . $time_format;
+ $change['old_'] = $lib->adjust_timezone($change['old'], strlen($change['old']) == 10)->format($dtformat);
+ }
+ if (!empty($change['new'])) {
+ $dtformat = strlen($change['new']) == 10 ? $date_format : $date_format . ' ' . $time_format;
+ $change['new_'] = $lib->adjust_timezone($change['new'], strlen($change['new']) == 10)->format($dtformat);
+ }
+ }
+ // create textual representation for alarms and recurrence
+ if ($change['property'] == 'alarms') {
+ if (is_array($change['old']))
+ $change['old_'] = libcalendaring::alarm_text($change['old']);
+ if (is_array($change['new']))
+ $change['new_'] = libcalendaring::alarm_text(array_merge((array)$change['old'], $change['new']));
+ }
+ if ($change['property'] == 'recurrence') {
+ if (is_array($change['old']))
+ $change['old_'] = $lib->recurrence_text($change['old']);
+ if (is_array($change['new']))
+ $change['new_'] = $lib->recurrence_text(array_merge((array)$change['old'], $change['new']));
+ }
+ if ($change['property'] == 'complete') {
+ $change['old_'] = intval($change['old']) . '%';
+ $change['new_'] = intval($change['new']) . '%';
+ }
+ if ($change['property'] == 'attachments') {
+ if (is_array($change['old']))
+ $change['old']['classname'] = rcube_utils::file2class($change['old']['mimetype'], $change['old']['name']);
+ if (is_array($change['new'])) {
+ $change['new'] = array_merge((array)$change['old'], $change['new']);
+ $change['new']['classname'] = rcube_utils::file2class($change['new']['mimetype'], $change['new']['name']);
+ }
+ }
+ // compute a nice diff of description texts
+ if ($change['property'] == 'description') {
+ $change['diff_'] = libkolab::html_diff($change['old'], $change['new']);
+ }
+ });
+ $this->rc->output->command('plugin.task_show_diff', $data);
+ }
+ else {
+ $this->rc->output->command('display_message', $this->gettext('objectdiffnotavailable'), 'error');
+ }
+ $got_msg = true;
+ break;
+
+ case 'show':
+ if ($rec = $this->driver->get_task_revison($rec, $rec['rev'])) {
+ $this->encode_task($rec);
+ $rec['readonly'] = 1;
+ $this->rc->output->command('plugin.task_show_revision', $rec);
+ }
+ else {
+ $this->rc->output->command('display_message', $this->gettext('objectnotfound'), 'error');
+ }
+ $got_msg = true;
+ break;
+
+ case 'restore':
+ if ($success = $this->driver->restore_task_revision($rec, $rec['rev'])) {
+ $refresh = $this->driver->get_task($rec);
+ $this->rc->output->command('display_message', $this->gettext(array('name' => 'objectrestoresuccess', 'vars' => array('rev' => $rec['rev']))), 'confirmation');
+ $this->rc->output->command('plugin.close_history_dialog');
+ }
+ else {
+ $this->rc->output->command('display_message', $this->gettext('objectrestoreerror'), 'error');
+ }
+ $got_msg = true;
+ break;
+
}
if ($success) {
$this->rc->output->show_message('successfullysaved', 'confirmation');
$this->update_counts($oldrec, $refresh);
}
- else {
+ else if (!$got_msg) {
$this->rc->output->show_message('tasklist.errorsaving', 'error');
}
@@ -1268,7 +1370,7 @@ class tasklist extends rcube_plugin
$this->rc->output->set_env('autocomplete_threads', (int)$this->rc->config->get('autocomplete_threads', 0));
$this->rc->output->set_env('autocomplete_max', (int)$this->rc->config->get('autocomplete_max', 15));
$this->rc->output->set_env('autocomplete_min_length', $this->rc->config->get('autocomplete_min_length'));
- $this->rc->output->add_label('autocompletechars', 'autocompletemore', 'delete', 'libcalendaring.expandattendeegroup', 'libcalendaring.expandattendeegroupnodata');
+ $this->rc->output->add_label('autocompletechars', 'autocompletemore', 'delete', 'close', 'libcalendaring.expandattendeegroup', 'libcalendaring.expandattendeegroupnodata');
$this->rc->output->set_pagetitle($this->gettext('navtitle'));
$this->rc->output->send('tasklist.mainview');
@@ -1396,8 +1498,9 @@ class tasklist extends rcube_plugin
$task = rcube_utils::get_input_value('_t', rcube_utils::INPUT_GPC);
$list = rcube_utils::get_input_value('_list', rcube_utils::INPUT_GPC);
$id = rcube_utils::get_input_value('_id', rcube_utils::INPUT_GPC);
+ $rev = rcube_utils::get_input_value('_rev', rcube_utils::INPUT_GPC);
- $task = array('id' => $task, 'list' => $list);
+ $task = array('id' => $task, 'list' => $list, 'rev' => $rev);
$attachment = $this->driver->get_attachment($id, $task);
// show part page
diff --git a/plugins/tasklist/tasklist_ui.php b/plugins/tasklist/tasklist_ui.php
index a46aa1e..97b1633 100644
--- a/plugins/tasklist/tasklist_ui.php
+++ b/plugins/tasklist/tasklist_ui.php
@@ -156,6 +156,7 @@ class tasklist_ui
$this->plugin->register_handler('plugin.identity_select', array($this, 'identity_select'));
$this->plugin->register_handler('plugin.edit_attendees_notify', array($this, 'edit_attendees_notify'));
$this->plugin->register_handler('plugin.task_rsvp_buttons', array($this->plugin->itip, 'itip_rsvp_buttons'));
+ $this->plugin->register_handler('plugin.object_changelog_table', array('libkolab', 'object_changelog_table'));
jqueryui::tagedit();
@@ -165,6 +166,7 @@ class tasklist_ui
// include kolab folderlist widget if available
if (in_array('libkolab', $this->plugin->api->loaded_plugins())) {
$this->plugin->api->include_script('libkolab/js/folderlist.js');
+ $this->plugin->api->include_script('libkolab/js/audittrail.js');
}
}
commit dcb60dbee171a5b732bbdd289d3aa7f29f5c16ae
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Wed Mar 25 11:55:21 2015 +0100
Move more audit trail code to libkolab; unify text labels
diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php
index 53d3f20..81ca66e 100644
--- a/plugins/calendar/calendar.php
+++ b/plugins/calendar/calendar.php
@@ -1114,7 +1114,7 @@ class calendar extends rcube_plugin
$this->rc->output->command('plugin.event_show_diff', $data);
}
else {
- $this->rc->output->command('display_message', $this->gettext('eventdiffnotavailable'), 'error');
+ $this->rc->output->command('display_message', $this->gettext('objectdiffnotavailable'), 'error');
}
$got_msg = true;
$reload = false;
@@ -1125,7 +1125,7 @@ class calendar extends rcube_plugin
$this->rc->output->command('plugin.event_show_revision', $this->_client_event($event));
}
else {
- $this->rc->output->command('display_message', $this->gettext('eventnotfound'), 'error');
+ $this->rc->output->command('display_message', $this->gettext('objectnotfound'), 'error');
}
$got_msg = true;
$reload = false;
@@ -1135,11 +1135,11 @@ class calendar extends rcube_plugin
if ($success = $this->driver->restore_event_revision($event, $event['rev'])) {
$_event = $this->driver->get_event($event);
$reload = $_event['recurrence'] ? 2 : 1;
- $this->rc->output->command('display_message', $this->gettext(array('name' => 'eventrestoresuccess', 'vars' => array('rev' => $event['rev']))), 'confirmation');
+ $this->rc->output->command('display_message', $this->gettext(array('name' => 'objectrestoresuccess', 'vars' => array('rev' => $event['rev']))), 'confirmation');
$this->rc->output->command('plugin.close_history_dialog');
}
else {
- $this->rc->output->command('display_message', $this->gettext('eventrestoreerror'), 'error');
+ $this->rc->output->command('display_message', $this->gettext('objectrestoreerror'), 'error');
$reload = 0;
}
$got_msg = true;
diff --git a/plugins/calendar/calendar_ui.js b/plugins/calendar/calendar_ui.js
index 6c26e5a..84c5adb 100644
--- a/plugins/calendar/calendar_ui.js
+++ b/plugins/calendar/calendar_ui.js
@@ -1025,7 +1025,7 @@ function rcube_calendar_ui(settings)
var $dialog = libkolab_audittrail.object_history_dialog({
module: 'calendar',
container: '#eventhistory',
- title: rcmail.gettext('eventchangelog','calendar') + ' - ' + event.title + ', ' + me.event_date_text(event),
+ title: rcmail.gettext('objectchangelog','calendar') + ' - ' + event.title + ', ' + me.event_date_text(event),
// callback function for list actions
listfunc: function(action, rev) {
@@ -1060,6 +1060,7 @@ function rcube_calendar_ui(settings)
return;
}
+ data.module = 'calendar';
libkolab_audittrail.render_changelog(data, event, me.calendars[event.calendar]);
// set dialog size according to content
@@ -1177,7 +1178,7 @@ function rcube_calendar_ui(settings)
modal: false,
resizable: true,
closeOnEscape: true,
- title: rcmail.gettext('eventdiff','calendar').replace('$rev1', data.rev1).replace('$rev2', data.rev2) + ' - ' + event.title,
+ title: rcmail.gettext('objectdiff','calendar').replace('$rev1', data.rev1).replace('$rev2', data.rev2) + ' - ' + event.title,
open: function() {
$dialog.attr('aria-hidden', 'false');
setTimeout(function(){
diff --git a/plugins/calendar/lib/calendar_ui.php b/plugins/calendar/lib/calendar_ui.php
index 5a1f41e..2912bdf 100644
--- a/plugins/calendar/lib/calendar_ui.php
+++ b/plugins/calendar/lib/calendar_ui.php
@@ -96,7 +96,7 @@ class calendar_ui
$this->cal->register_handler('plugin.angenda_options', array($this, 'angenda_options'));
$this->cal->register_handler('plugin.events_import_form', array($this, 'events_import_form'));
$this->cal->register_handler('plugin.events_export_form', array($this, 'events_export_form'));
- $this->cal->register_handler('plugin.event_changelog_table', array($this, 'event_changelog_table'));
+ $this->cal->register_handler('plugin.object_changelog_table', array('libkolab', 'object_changelog_table'));
$this->cal->register_handler('plugin.searchform', array($this->rc->output, 'search_form')); // use generic method from rcube_template
}
@@ -855,22 +855,6 @@ class calendar_ui
}
/**
- * Table oultine for event changelog display
- */
- function event_changelog_table($attrib = array())
- {
- $table = new html_table(array('cols' => 5, 'border' => 0, 'cellspacing' => 0));
- $table->add_header('diff', '');
- $table->add_header('revision', $this->cal->gettext('revision'));
- $table->add_header('date', $this->cal->gettext('date'));
- $table->add_header('user', $this->cal->gettext('user'));
- $table->add_header('operation', $this->cal->gettext('operation'));
- $table->add_header('actions', ' ');
-
- return $table->show($attrib);
- }
-
- /**
*
*/
function event_invitebox($attrib = array())
diff --git a/plugins/calendar/localization/bg_BG.inc b/plugins/calendar/localization/bg_BG.inc
index 76d1d84..afbdfe1 100644
--- a/plugins/calendar/localization/bg_BG.inc
+++ b/plugins/calendar/localization/bg_BG.inc
@@ -1,5 +1,4 @@
<?php
-
/**
* Localizations for Kolab Calendar plugin
*
@@ -7,7 +6,6 @@
*
* For translation see https://www.transifex.com/projects/p/kolab/resource/calendar/
*/
-
$labels['default_view'] = 'Ðзглед по подÑазбиÑане';
$labels['time_format'] = 'ФоÑÐ¼Ð°Ñ Ð½Ð° ÑаÑовеÑе';
$labels['first_day'] = 'ÐÑÑви ден Ð¾Ñ ÑедмиÑаÑа';
@@ -120,5 +118,5 @@ $labels['deleteventconfirm'] = 'ÐаиÑÑина ли иÑкаÑе да пÑем
$labels['deletecalendarconfirm'] = 'ÐаиÑÑина ли иÑкаÑе да пÑемаÑ
неÑе Ñози ÐºÐ°Ð»ÐµÐ½Ð´Ð°Ñ Ñ Ð²ÑиÑкиÑе Ð¼Ñ ÑÑбиÑиÑ?';
$labels['savingdata'] = 'Ðапазване на данни...';
$labels['errorsaving'] = 'ÐеÑÑпеÑно запиÑванеÑо на пÑомениÑе.';
-
+$labels['futurevents'] = 'ÐÑдеÑи';
?>
diff --git a/plugins/calendar/localization/ca_ES.inc b/plugins/calendar/localization/ca_ES.inc
index d3c5ff9..9226ef5 100644
--- a/plugins/calendar/localization/ca_ES.inc
+++ b/plugins/calendar/localization/ca_ES.inc
@@ -239,7 +239,7 @@ $labels['displaybirthdayscalendar'] = 'Mostra el calendari d\'aniversaris';
$labels['birthdayscalendarsources'] = 'D\'aquestes llibretes d\'adreces';
$labels['birthdayeventtitle'] = 'Aniversari de $name';
$labels['birthdayage'] = 'Edat $age';
-$labels['eventchangelog'] = 'Canvia historial';
+$labels['objectchangelog'] = 'Canvia historial';
$labels['revision'] = 'Revisió';
$labels['user'] = 'Usuari';
$labels['operation'] = 'Acció';
@@ -249,9 +249,9 @@ $labels['actiondelete'] = 'Suprimit';
$labels['compare'] = 'Compara';
$labels['showrevision'] = 'Mostra aquesta versió';
$labels['restore'] = 'Restaura aquesta versió';
-$labels['eventnotfound'] = 'No s\'han pogut carregar les dades d\'aquest esdeveniment';
+$labels['objectnotfound'] = 'No s\'han pogut carregar les dades d\'aquest esdeveniment';
$labels['objectchangelognotavailable'] = 'No està disponible canviar l\'historial d\'aquest esdeveniment';
-$labels['eventdiffnotavailable'] = 'No és possible comparar les revisions seleccionades';
+$labels['objectdiffnotavailable'] = 'No és possible comparar les revisions seleccionades';
$labels['revisionrestoreconfirm'] = 'Esteu segurs de voler restaurar la revisió $rev d\'aquest esdeveniment? Això substituirà l\'actual esdeveniment per una versió antiga.';
$labels['arialabelminical'] = 'Selecció de la data del calendari';
$labels['arialabelcalendarview'] = 'Vista del calendari';
diff --git a/plugins/calendar/localization/cs_CZ.inc b/plugins/calendar/localization/cs_CZ.inc
index 1ed6cf3..8f47574 100644
--- a/plugins/calendar/localization/cs_CZ.inc
+++ b/plugins/calendar/localization/cs_CZ.inc
@@ -246,7 +246,7 @@ $labels['displaybirthdayscalendar'] = 'Zobrazit kalendáŠnarozenin';
$labels['birthdayscalendarsources'] = 'Z tÄchto adresáÅů';
$labels['birthdayeventtitle'] = 'Narozeniny $name';
$labels['birthdayage'] = 'VÄk $age';
-$labels['eventchangelog'] = 'Historie zmÄn';
+$labels['objectchangelog'] = 'Historie zmÄn';
$labels['revision'] = 'Verze';
$labels['user'] = 'Uživatel';
$labels['operation'] = 'Äinnost';
@@ -256,9 +256,9 @@ $labels['actiondelete'] = 'Smazáno';
$labels['compare'] = 'Porovnat';
$labels['showrevision'] = 'Ukázat tuto verzi';
$labels['restore'] = 'Obnovit tuto verzi';
-$labels['eventnotfound'] = 'NepodaÅilo se nahrát data události';
+$labels['objectnotfound'] = 'NepodaÅilo se nahrát data události';
$labels['objectchangelognotavailable'] = 'Historie zmÄn nenà pro tuto událost dostupná';
-$labels['eventdiffnotavailable'] = 'Pro vybrané verze nenà žádné srovnánà možné';
+$labels['objectdiffnotavailable'] = 'Pro vybrané verze nenà žádné srovnánà možné';
$labels['revisionrestoreconfirm'] = 'Opravdu chcete obnovit zmÄnu $rev této události? TÃmto dojde k nahrazenà nynÄjšà události starou verzÃ.';
$labels['arialabelminical'] = 'VýbÄr data v kalendáÅi';
$labels['arialabelcalendarview'] = 'Pohled na kalendáÅ';
diff --git a/plugins/calendar/localization/da_DK.inc b/plugins/calendar/localization/da_DK.inc
index 05c9b71..e44851e 100644
--- a/plugins/calendar/localization/da_DK.inc
+++ b/plugins/calendar/localization/da_DK.inc
@@ -247,7 +247,7 @@ $labels['displaybirthdayscalendar'] = 'Vis fødselsdagskalender';
$labels['birthdayscalendarsources'] = 'Fra disse adressebøger';
$labels['birthdayeventtitle'] = '$name har fødselsdag';
$labels['birthdayage'] = '$age år';
-$labels['eventchangelog'] = 'Ãndringshistorik';
+$labels['objectchangelog'] = 'Ãndringshistorik';
$labels['revision'] = 'Revision';
$labels['user'] = 'Bruger';
$labels['operation'] = 'Handling';
@@ -257,9 +257,9 @@ $labels['actiondelete'] = 'Slettet';
$labels['compare'] = 'Sammenlign';
$labels['showrevision'] = 'Vis denne version';
$labels['restore'] = 'Genskab denne version';
-$labels['eventnotfound'] = 'Kunne ikke indlæse begivenhedsdata';
+$labels['objectnotfound'] = 'Kunne ikke indlæse begivenhedsdata';
$labels['objectchangelognotavailable'] = 'Ãndringshistorikken er ikke tilgængelig for denne begivenhed';
-$labels['eventdiffnotavailable'] = 'Det er ikke muligt at sammenligne de valgte revisioner';
+$labels['objectdiffnotavailable'] = 'Det er ikke muligt at sammenligne de valgte revisioner';
$labels['revisionrestoreconfirm'] = 'Sikker på at du vil genskabe revision $rev af denne begivenhed? Dette vil erstatte den nuværende begivenhed med den tidligere version.';
$labels['arialabelminical'] = 'Valg af kalenderdato';
$labels['arialabelcalendarview'] = 'Kalendervisning';
diff --git a/plugins/calendar/localization/de_CH.inc b/plugins/calendar/localization/de_CH.inc
index 1bbf464..91726ca 100644
--- a/plugins/calendar/localization/de_CH.inc
+++ b/plugins/calendar/localization/de_CH.inc
@@ -36,7 +36,6 @@ $labels['new_event'] = 'Neuer Termin';
$labels['edit_event'] = 'Termin bearbeiten';
$labels['edit'] = 'Bearbeiten';
$labels['save'] = 'Speichern';
-$labels['removelist'] = 'Remove from list';
$labels['cancel'] = 'Abbrechen';
$labels['select'] = 'Auswählen';
$labels['print'] = 'Drucken';
@@ -165,7 +164,6 @@ $labels['itipsendsuccess'] = 'Einladung an Teilnehmer versendet.';
$labels['itipresponseerror'] = 'Die Antwort auf diese Einladung konnte nicht versendet werden';
$labels['itipinvalidrequest'] = 'Diese Einladung ist nicht mehr gültig';
$labels['sentresponseto'] = 'Antwort auf diese Einladung erfolgreich an $mailto gesendet';
-$labels['localchangeswarning'] = 'You are about to make changes that will only be reflected on your calendar and not be sent to the organizer of the event.';
$labels['importsuccess'] = 'Es wurden $nr Termine erfolgreich importiert';
$labels['importnone'] = 'Keine Termine zum Importieren gefunden';
$labels['importerror'] = 'Fehler beim Importieren';
diff --git a/plugins/calendar/localization/de_DE.inc b/plugins/calendar/localization/de_DE.inc
index ab5a5af..8d72985 100644
--- a/plugins/calendar/localization/de_DE.inc
+++ b/plugins/calendar/localization/de_DE.inc
@@ -247,8 +247,8 @@ $labels['displaybirthdayscalendar'] = 'Geburtstags-Kalender anzeigen';
$labels['birthdayscalendarsources'] = 'Für diese Adressbücher';
$labels['birthdayeventtitle'] = '$names Geburtstag';
$labels['birthdayage'] = 'Alter $age';
-$labels['eventchangelog'] = 'Ãnderungshistorie';
-$labels['eventdiff'] = 'Ãnderungen aus $rev1 nach $rev2';
+$labels['objectchangelog'] = 'Ãnderungshistorie';
+$labels['objectdiff'] = 'Ãnderungen aus $rev1 nach $rev2';
$labels['revision'] = 'Version';
$labels['user'] = 'Benutzer';
$labels['operation'] = 'Aktion';
@@ -258,12 +258,12 @@ $labels['actiondelete'] = 'Gelöscht';
$labels['compare'] = 'Vergleichen';
$labels['showrevision'] = 'Diese Version anzeigen';
$labels['restore'] = 'Diese Version wiederherstellen';
-$labels['eventnotfound'] = 'Termindaten sind leider nicht vergübar';
+$labels['objectnotfound'] = 'Termindaten sind leider nicht vergübar';
$labels['objectchangelognotavailable'] = 'Ãnderungshistorie ist nicht verfügbar für diesen Termin';
-$labels['eventdiffnotavailable'] = 'Vergleich für die gewählten Versionen nicht möglich';
+$labels['objectdiffnotavailable'] = 'Vergleich für die gewählten Versionen nicht möglich';
$labels['revisionrestoreconfirm'] = 'Wollen Sie wirklich die Version $rev dieses Termins wiederherstellen? Diese Aktion wird die aktuelle Kopie mit der älteren Version ersetzen.';
-$labels['eventrestoresuccess'] = 'Revision $rev erfolgreich wiederhergestellt';
-$labels['eventrestoreerror'] = 'Fehler beim Wiederherstellen der alten Revision';
+$labels['objectrestoresuccess'] = 'Revision $rev erfolgreich wiederhergestellt';
+$labels['objectrestoreerror'] = 'Fehler beim Wiederherstellen der alten Revision';
$labels['arialabelminical'] = 'Kalender Datumswahl';
$labels['arialabelcalendarview'] = 'Kalender Ansicht';
$labels['arialabelsearchform'] = 'Suchformular für Termine';
diff --git a/plugins/calendar/localization/en_US.inc b/plugins/calendar/localization/en_US.inc
index 3a15b6f..d967fc7 100644
--- a/plugins/calendar/localization/en_US.inc
+++ b/plugins/calendar/localization/en_US.inc
@@ -276,8 +276,8 @@ $labels['birthdayeventtitle'] = '$name\'s Birthday';
$labels['birthdayage'] = 'Age $age';
// history dialog
-$labels['eventchangelog'] = 'Change History';
-$labels['eventdiff'] = 'Changes from $rev1 to $rev2';
+$labels['objectchangelog'] = 'Change History';
+$labels['objectdiff'] = 'Changes from $rev1 to $rev2';
$labels['revision'] = 'Revision';
$labels['user'] = 'User';
$labels['operation'] = 'Action';
@@ -287,12 +287,12 @@ $labels['actiondelete'] = 'Deleted';
$labels['compare'] = 'Compare';
$labels['showrevision'] = 'Show this version';
$labels['restore'] = 'Restore this version';
-$labels['eventnotfound'] = 'Failed to load event data';
+$labels['objectnotfound'] = 'Failed to load event data';
$labels['objectchangelognotavailable'] = 'Change history is not available for this event';
-$labels['eventdiffnotavailable'] = 'No comparison possible for the selected revisions';
+$labels['objectdiffnotavailable'] = 'No comparison possible for the selected revisions';
$labels['revisionrestoreconfirm'] = 'Do you really want to restore revision $rev of this event? This will replace the current event with the old version.';
-$labels['eventrestoresuccess'] = 'Revision $rev successfully restored';
-$labels['eventrestoreerror'] = 'Failed to restore the old revision';
+$labels['objectrestoresuccess'] = 'Revision $rev successfully restored';
+$labels['objectrestoreerror'] = 'Failed to restore the old revision';
// (hidden) titles and labels for accessibility annotations
diff --git a/plugins/calendar/localization/es_AR.inc b/plugins/calendar/localization/es_AR.inc
index 1bb9b51..2a66a0f 100644
--- a/plugins/calendar/localization/es_AR.inc
+++ b/plugins/calendar/localization/es_AR.inc
@@ -242,7 +242,7 @@ $labels['displaybirthdayscalendar'] = 'Mostrar calendario de cumpleaños';
$labels['birthdayscalendarsources'] = 'De estas libretas de direcciones';
$labels['birthdayeventtitle'] = 'Cumpleaños de $name';
$labels['birthdayage'] = 'Edad $age';
-$labels['eventchangelog'] = 'Cambiar Historial';
+$labels['objectchangelog'] = 'Cambiar Historial';
$labels['revision'] = 'Revisión';
$labels['user'] = 'Usuario';
$labels['operation'] = 'Acción';
@@ -252,9 +252,9 @@ $labels['actiondelete'] = 'Eliminado';
$labels['compare'] = 'Comparar';
$labels['showrevision'] = 'Mostrar esta versión';
$labels['restore'] = 'Recuperar esta versión';
-$labels['eventnotfound'] = 'Fallo al cargar datos del evento';
+$labels['objectnotfound'] = 'Fallo al cargar datos del evento';
$labels['objectchangelognotavailable'] = 'Cambiar historial no esta disponible para este evento';
-$labels['eventdiffnotavailable'] = 'No es posible comparar las revisiones seleccionadas';
+$labels['objectdiffnotavailable'] = 'No es posible comparar las revisiones seleccionadas';
$labels['revisionrestoreconfirm'] = 'Confirme que quiere recuperar la revisión $rev de este evento. Esta acción reemplazará el evento actual con la versión anterior.';
$labels['arialabelminical'] = 'Selección de fecha del calendario';
$labels['arialabelcalendarview'] = 'Vista del calendario';
diff --git a/plugins/calendar/localization/es_ES.inc b/plugins/calendar/localization/es_ES.inc
index 6dc876b..1b025fb 100644
--- a/plugins/calendar/localization/es_ES.inc
+++ b/plugins/calendar/localization/es_ES.inc
@@ -11,8 +11,6 @@ $labels['name'] = 'Nombre';
$labels['edit'] = 'Editar';
$labels['save'] = 'Guardar';
$labels['cancel'] = 'Cancelar';
-$labels['description'] = 'Descripción';
-$labels['confidential'] = 'confidential';
$labels['comment'] = 'Comentario';
$labels['eventoptions'] = 'Opciones';
$labels['rolerequired'] = 'Requerido';
diff --git a/plugins/calendar/localization/et_EE.inc b/plugins/calendar/localization/et_EE.inc
deleted file mode 100644
index 55b92a0..0000000
--- a/plugins/calendar/localization/et_EE.inc
+++ /dev/null
@@ -1,14 +0,0 @@
-<?php
-/**
- * Localizations for Kolab Calendar plugin
- *
- * Copyright (C) 2014, Kolab Systems AG
- *
- * For translation see https://www.transifex.com/projects/p/kolab/resource/calendar/
- */
-$labels['name'] = 'Nimi';
-$labels['save'] = 'Salvesta';
-$labels['confidential'] = 'confidential';
-$labels['rolerequired'] = 'Kohustuslik';
-$labels['operation'] = 'Toiming';
-?>
diff --git a/plugins/calendar/localization/fi_FI.inc b/plugins/calendar/localization/fi_FI.inc
index 35d1065..2d67e4e 100644
--- a/plugins/calendar/localization/fi_FI.inc
+++ b/plugins/calendar/localization/fi_FI.inc
@@ -89,6 +89,7 @@ $labels['generated'] = 'generoitu';
$labels['eventhistory'] = 'Historia';
$labels['removelink'] = 'Poista sähköpostiviittaus';
$labels['printdescriptions'] = 'Tulosta kuvaukset';
+$labels['parentcalendar'] = 'Aseta sisään';
$labels['searchearlierdates'] = '« Etsi aiempia tapahtumia';
$labels['searchlaterdates'] = 'Etsi myöhempiä tapahtumia »';
$labels['andnmore'] = '$nr lisää...';
@@ -243,8 +244,8 @@ $labels['displaybirthdayscalendar'] = 'Näytä syntymäpäivät kalenterissa';
$labels['birthdayscalendarsources'] = 'Näistä osoitekirjoista';
$labels['birthdayeventtitle'] = 'Syntymäpäivä: $name';
$labels['birthdayage'] = 'Ikä $age';
-$labels['eventchangelog'] = 'Muuta historiaa';
-$labels['eventdiff'] = 'Muutokset versiosta $rev1 versioon $rev2';
+$labels['objectchangelog'] = 'Muuta historiaa';
+$labels['objectdiff'] = 'Muutokset versiosta $rev1 versioon $rev2';
$labels['revision'] = 'Versio';
$labels['user'] = 'Käyttäjä';
$labels['operation'] = 'Toiminto';
@@ -254,12 +255,12 @@ $labels['actiondelete'] = 'Poistettu';
$labels['compare'] = 'Vertaa';
$labels['showrevision'] = 'Näytä tämä versio';
$labels['restore'] = 'Palauta tämä versio';
-$labels['eventnotfound'] = 'Tapahtumadatan lataus epäonnistui';
+$labels['objectnotfound'] = 'Tapahtumadatan lataus epäonnistui';
$labels['objectchangelognotavailable'] = 'Tapahtuman muutoshistoria ei ole saatavilla';
-$labels['eventdiffnotavailable'] = 'Vertailu ei ole saatavilla valittujen versioiden välillä';
+$labels['objectdiffnotavailable'] = 'Vertailu ei ole saatavilla valittujen versioiden välillä';
$labels['revisionrestoreconfirm'] = 'Haluatko varmasti palauttaa tämän tapahtuman version $rev? Nykyinen tapahtuma korvataan vanhalla versiolla.';
-$labels['eventrestoresuccess'] = 'Versio $rev palautettiin onnistuneesti';
-$labels['eventrestoreerror'] = 'Vanhan version palauttaminen epäonnistui';
+$labels['objectrestoresuccess'] = 'Versio $rev palautettiin onnistuneesti';
+$labels['objectrestoreerror'] = 'Vanhan version palauttaminen epäonnistui';
$labels['arialabelminical'] = 'Kalenterin ajankohdan valinta';
$labels['arialabelcalendarview'] = 'Kalenterinäkymä';
$labels['arialabelsearchform'] = 'Tapahtumahaun lomake';
diff --git a/plugins/calendar/localization/fr_FR.inc b/plugins/calendar/localization/fr_FR.inc
index 076a7d6..1c89721 100644
--- a/plugins/calendar/localization/fr_FR.inc
+++ b/plugins/calendar/localization/fr_FR.inc
@@ -244,7 +244,7 @@ $labels['displaybirthdayscalendar'] = 'Afficher le calendrier des anniversaires'
$labels['birthdayscalendarsources'] = 'Depuis ces carnets d\'adresses';
$labels['birthdayeventtitle'] = 'Anniversaire de $name';
$labels['birthdayage'] = 'Age $age';
-$labels['eventchangelog'] = 'Historique des modifications';
+$labels['objectchangelog'] = 'Historique des modifications';
$labels['revision'] = 'Version';
$labels['user'] = 'Utilisateur';
$labels['operation'] = 'Action';
@@ -254,9 +254,9 @@ $labels['actiondelete'] = 'Supprimé';
$labels['compare'] = 'Comparer';
$labels['showrevision'] = 'Afficher cette version';
$labels['restore'] = 'Restaurer cette version';
-$labels['eventnotfound'] = 'Impossible de charger les données de lâévènement';
+$labels['objectnotfound'] = 'Impossible de charger les données de lâévènement';
$labels['objectchangelognotavailable'] = 'Il n\'y a pas d\'historique des modifications pour cet évènement';
-$labels['eventdiffnotavailable'] = 'La comparaison des versions sélectionnées est impossible';
+$labels['objectdiffnotavailable'] = 'La comparaison des versions sélectionnées est impossible';
$labels['revisionrestoreconfirm'] = 'Voulez-vous vraiment restaurer le version $rev de cet évènement ? Cette action va remplacer l\'évènement courent par l\'ancienne version.';
$labels['arialabelminical'] = 'Sélection de la date du calendrier';
$labels['arialabelcalendarview'] = 'Vue du calendrier';
diff --git a/plugins/calendar/localization/it_IT.inc b/plugins/calendar/localization/it_IT.inc
index 78b6a05..2cc3ce7 100644
--- a/plugins/calendar/localization/it_IT.inc
+++ b/plugins/calendar/localization/it_IT.inc
@@ -246,7 +246,7 @@ $labels['displaybirthdayscalendar'] = 'Mostra il calendario compleanni';
$labels['birthdayscalendarsources'] = 'Da queste rubriche';
$labels['birthdayeventtitle'] = 'Compleanno di $name';
$labels['birthdayage'] = 'Età : $age anni';
-$labels['eventchangelog'] = 'Storico modifiche';
+$labels['objectchangelog'] = 'Storico modifiche';
$labels['revision'] = 'Revisione';
$labels['user'] = 'Utente';
$labels['operation'] = 'Azione';
@@ -256,9 +256,9 @@ $labels['actiondelete'] = 'Cancellato';
$labels['compare'] = 'Confronta';
$labels['showrevision'] = 'Mostra questa versione';
$labels['restore'] = 'Rirpistina questa versione';
-$labels['eventnotfound'] = 'Caricamento dati dell\'evento fallito';
+$labels['objectnotfound'] = 'Caricamento dati dell\'evento fallito';
$labels['objectchangelognotavailable'] = 'Lo storico modifiche non è disponibile per questo evento';
-$labels['eventdiffnotavailable'] = 'Nessun confronto possibile tra le revisioni selezionate';
+$labels['objectdiffnotavailable'] = 'Nessun confronto possibile tra le revisioni selezionate';
$labels['revisionrestoreconfirm'] = 'Vuoi veramente ripristinare la revisione $rev di questo evento? L\'evento corrente verrà sostituito dalla vecchia versione.';
$labels['arialabelminical'] = 'Selezione della data del calendario';
$labels['arialabelcalendarview'] = 'Vista calendario';
diff --git a/plugins/calendar/localization/pl_PL.inc b/plugins/calendar/localization/pl_PL.inc
index 4495e2f..7e6d5ac 100644
--- a/plugins/calendar/localization/pl_PL.inc
+++ b/plugins/calendar/localization/pl_PL.inc
@@ -245,7 +245,7 @@ $labels['displaybirthdayscalendar'] = 'WyÅwietl kalendarz urodzin';
$labels['birthdayscalendarsources'] = 'Z tych ksiÄ
żek adresowych';
$labels['birthdayeventtitle'] = 'Urodziny $name\'s';
$labels['birthdayage'] = 'Wiek $age';
-$labels['eventchangelog'] = 'Historia zmian';
+$labels['objectchangelog'] = 'Historia zmian';
$labels['revision'] = 'Wersja';
$labels['user'] = 'Użytkownik';
$labels['operation'] = 'Akcja';
@@ -255,9 +255,9 @@ $labels['actiondelete'] = 'UsuniÄte';
$labels['compare'] = 'Porównaj';
$labels['showrevision'] = 'Pokaż tÄ
wersjÄ';
$labels['restore'] = 'PrzywrÃ³Ä tÄ
wersjÄ';
-$labels['eventnotfound'] = 'Nie udaÅo siÄ wczytaÄ zdarzenia';
+$labels['objectnotfound'] = 'Nie udaÅo siÄ wczytaÄ zdarzenia';
$labels['objectchangelognotavailable'] = 'Historia zmian jest niedostÄpna dla tego zdarzenia';
-$labels['eventdiffnotavailable'] = 'Nie można porównaÄ wybranych wersji';
+$labels['objectdiffnotavailable'] = 'Nie można porównaÄ wybranych wersji';
$labels['revisionrestoreconfirm'] = 'Czy na pewno chcesz przywróciÄ wersjÄ $rev tego zdarzenia? BierzÄ
ce zdarzenie zostanie zastÄ
pione starszÄ
wersjÄ
.';
$labels['arialabelminical'] = 'Wybór daty kalendarza';
$labels['arialabelcalendarview'] = 'PodglÄ
d kalendarza';
diff --git a/plugins/calendar/localization/pt_PT.inc b/plugins/calendar/localization/pt_PT.inc
new file mode 100644
index 0000000..d6b38ab
--- /dev/null
+++ b/plugins/calendar/localization/pt_PT.inc
@@ -0,0 +1,274 @@
+<?php
+/**
+ * Localizations for Kolab Calendar plugin
+ *
+ * Copyright (C) 2014, Kolab Systems AG
+ *
+ * For translation see https://www.transifex.com/projects/p/kolab/resource/calendar/
+ */
+$labels['default_view'] = 'Visualização padrão';
+$labels['time_format'] = 'Formato da hora';
+$labels['timeslots'] = 'Entradas por hora';
+$labels['first_day'] = 'Primeiro dia da semana';
+$labels['first_hour'] = 'Primeira hora a mostrar';
+$labels['workinghours'] = 'Horário de trabalho';
+$labels['add_category'] = 'Adicionar categoria';
+$labels['remove_category'] = 'Remover categoria';
+$labels['defaultcalendar'] = 'Criar novos eventos em';
+$labels['eventcoloring'] = 'Cores dos eventos';
+$labels['coloringmode0'] = 'De acordo com o calendário';
+$labels['coloringmode1'] = 'De acordo com a categoria';
+$labels['coloringmode2'] = 'Calendário para esboço, categoria para conteúdo';
+$labels['coloringmode3'] = 'Categoria para esboço, calendário para conteúdo';
+$labels['afternothing'] = 'Manter';
+$labels['aftertrash'] = 'Enviar para o lixo';
+$labels['afterdelete'] = 'Eliminar a mensagem';
+$labels['afterflagdeleted'] = 'Marcar como eliminada';
+$labels['aftermoveto'] = 'Mover para...';
+$labels['itipoptions'] = 'Convites de eventos';
+$labels['afteraction'] = 'Depois do processamento de um convite ou mensagem de alteração';
+$labels['calendar'] = 'Calendário';
+$labels['calendars'] = 'Calendários';
+$labels['category'] = 'Categoria';
+$labels['categories'] = 'Categorias';
+$labels['createcalendar'] = 'Criar um novo calendário';
+$labels['editcalendar'] = 'Alterar propriedades do calendário';
+$labels['name'] = 'Nome';
+$labels['color'] = 'Cor';
+$labels['day'] = 'Dia';
+$labels['week'] = 'Semana';
+$labels['month'] = 'Mês';
+$labels['agenda'] = 'Agenda';
+$labels['new'] = 'Novo';
+$labels['new_event'] = 'Novo evento';
+$labels['edit_event'] = 'Alterar evento';
+$labels['edit'] = 'Alterar';
+$labels['save'] = 'Guardar';
+$labels['removelist'] = 'Remover da lista';
+$labels['cancel'] = 'Cancelar';
+$labels['select'] = 'Selecionar';
+$labels['print'] = 'Imprimir';
+$labels['printtitle'] = 'Imprimir calendários';
+$labels['title'] = 'Sumário';
+$labels['description'] = 'Descrição';
+$labels['all-day'] = 'dia todo';
+$labels['export'] = 'Exportar';
+$labels['exporttitle'] = 'Exportar para iCalendar';
+$labels['exportrange'] = 'Eventos de';
+$labels['exportattachments'] = 'Incluir anexos';
+$labels['customdate'] = 'Definir data';
+$labels['location'] = 'Local';
+$labels['url'] = 'Endereço web';
+$labels['date'] = 'Data';
+$labels['start'] = 'InÃcio';
+$labels['starttime'] = 'Hora de inÃcio';
+$labels['end'] = 'Fim';
+$labels['endtime'] = 'Hora de fim';
+$labels['repeat'] = 'Repetir';
+$labels['selectdate'] = 'Escolher data';
+$labels['freebusy'] = 'Mostrar-me como';
+$labels['free'] = 'Livre';
+$labels['busy'] = 'Ocupado';
+$labels['outofoffice'] = 'Ausente';
+$labels['tentative'] = 'Tentativa';
+$labels['mystatus'] = 'O meu estado';
+$labels['status'] = 'Estado';
+$labels['status-confirmed'] = 'Confirmado';
+$labels['status-cancelled'] = 'Cancelado';
+$labels['priority'] = 'Prioridade';
+$labels['sensitivity'] = 'Privacidade';
+$labels['public'] = 'público';
+$labels['private'] = 'privado';
+$labels['confidential'] = 'confidencial';
+$labels['links'] = 'Referência';
+$labels['alarms'] = 'Lembrete';
+$labels['comment'] = 'Comentário';
+$labels['created'] = 'Criado em';
+$labels['changed'] = 'Alterado em';
+$labels['unknown'] = 'Desconhecido';
+$labels['eventoptions'] = 'Opções';
+$labels['generated'] = 'produzido a';
+$labels['eventhistory'] = 'Histórico';
+$labels['removelink'] = 'Remover referência de email ';
+$labels['printdescriptions'] = 'Descrições de impressão';
+$labels['parentcalendar'] = 'Inserir dentro';
+$labels['searchearlierdates'] = '« Procurar eventos anteriores';
+$labels['searchlaterdates'] = 'Procurar eventos posteriores »';
+$labels['andnmore'] = '$nr mais...';
+$labels['togglerole'] = 'Clique para alternar o papel';
+$labels['createfrommail'] = 'Salvar como evento';
+$labels['importevents'] = 'Importar eventos';
+$labels['importrange'] = 'Eventos de';
+$labels['onemonthback'] = '1 mês atrás';
+$labels['nmonthsback'] = '$nr meses atrás';
+$labels['showurl'] = 'Mostrar URL do calendário';
+$labels['showurldescription'] = 'Use o seguinte endereço para obter acesso (somente leitura) ao seu calendário com outras aplicações. Para isso pode copiar e colar este endereço em qualquer software que suporte o formato iCal.';
+$labels['caldavurldescription'] = 'Para sincronizar este calendário com o seu computador ou dispositivos móveis deverá copiar este endereço <a href="http://en.wikipedia.org/wiki/CalDAV" target="_blank">CalDAV</a> para a aplicação cliente. (ex. Evolution ou Mozilla Thunderbird)';
+$labels['findcalendars'] = 'Procurar calendários...';
+$labels['searchterms'] = 'Procurar termos';
+$labels['calsearchresults'] = 'Calendários disponÃveis';
+$labels['calendarsubscribe'] = 'Listar sempre';
+$labels['nocalendarsfound'] = 'Não foram encontrados calendários';
+$labels['nrcalendarsfound'] = '$nr calendários encontrados';
+$labels['quickview'] = 'Só mostrar este calendário';
+$labels['invitationspending'] = 'Convites pendentes';
+$labels['invitationsdeclined'] = 'Convites recusados';
+$labels['changepartstat'] = 'Mudar estado de participante';
+$labels['rsvpcomment'] = 'Mensagem de convite';
+$labels['listrange'] = 'Intervalo para exibir:';
+$labels['listsections'] = 'Dividir em:';
+$labels['smartsections'] = 'Seções inteligentes';
+$labels['until'] = 'até';
+$labels['today'] = 'Hoje';
+$labels['tomorrow'] = 'Amanhã';
+$labels['thisweek'] = 'Esta semana';
+$labels['nextweek'] = 'Próxima semana';
+$labels['prevweek'] = 'Semana anterior';
+$labels['thismonth'] = 'Este mês';
+$labels['nextmonth'] = 'Próximo mês';
+$labels['weekofyear'] = 'Semana';
+$labels['pastevents'] = 'Passado';
+$labels['futureevents'] = 'Futuro';
+$labels['showalarms'] = 'Mostrar lembretes';
+$labels['defaultalarmtype'] = 'Configuração padrão de lembrete';
+$labels['defaultalarmoffset'] = 'Horário padrão de lembrete';
+$labels['attendee'] = 'Participante';
+$labels['role'] = 'Papel';
+$labels['availability'] = 'Disp.';
+$labels['confirmstate'] = 'Estado';
+$labels['addattendee'] = 'Adicionar participante';
+$labels['roleorganizer'] = 'Organizador';
+$labels['rolerequired'] = 'Obrigatório';
+$labels['roleoptional'] = 'Facultativo';
+$labels['rolechair'] = 'Responsável';
+$labels['rolenonparticipant'] = 'Ausente';
+$labels['cutypeindividual'] = 'Individual';
+$labels['cutypegroup'] = 'Grupo';
+$labels['cutyperesource'] = 'Recurso';
+$labels['cutyperoom'] = 'Sala';
+$labels['availfree'] = 'DisponÃvel';
+$labels['availbusy'] = 'Ocupado';
+$labels['availunknown'] = 'Desconhecido';
+$labels['availtentative'] = 'Tentativa';
+$labels['availoutofoffice'] = 'Ausente';
+$labels['delegatedto'] = 'Delegado a:';
+$labels['delegatedfrom'] = 'Delegado de:';
+$labels['scheduletime'] = 'Procurar disponibilidade';
+$labels['sendinvitations'] = 'Enviar convites';
+$labels['sendnotifications'] = 'Avisar os participantes sobre as alterações';
+$labels['sendcancellation'] = 'Avisar os participantes sobre o cancelamento do evento';
+$labels['onlyworkinghours'] = 'Procurar disponibilidade dentro do meu horário de trabalho';
+$labels['reqallattendees'] = 'Necessário/todos os participantes';
+$labels['prevslot'] = 'Espaço anterior';
+$labels['nextslot'] = 'Próximo espaço';
+$labels['suggestedslot'] = 'Espaço sugerido';
+$labels['noslotfound'] = 'Incapaz de encontrar um horário disponÃvel';
+$labels['invitationsubject'] = 'Foi convidado para "$title"';
+$labels['invitationmailbody'] = "*\$title*\n\nQuando: \$date\n\nConvidados: \$attendees\n\nSegue em anexo um arquivo iCalendar com todos os detalhes de um evento, o qual pode importar para o seu calendário.";
+$labels['invitationattendlinks'] = "No caso do seu cliente de e-mail não suportar pedidos do tipo iTIP, pode usar o seguinte link para aceitar ou recusar este convite:\n\$url";
+$labels['eventupdatesubject'] = '"$title" foi atualizado.';
+$labels['eventupdatesubjectempty'] = 'Um evento do seu interesse foi atualizado';
+$labels['eventupdatemailbody'] = "*\$title*\n\nQuando: \$date\n\nConvidados: \$attendees\n\nSegue em anexo um arquivo iCalendar atualizado com os detalhes de um evento, o qual pode importar para o seu calendário.";
+$labels['eventcancelsubject'] = '"$title" foi cancelado.';
+$labels['eventcancelmailbody'] = "*\$title*\n\nQuando: \$date\n\nConvidados: \$attendees\n\nO evento foi cancelado por \$organizer.\n\nSegue em anexo um arquivo iCalendar com os detalhes atualizados do evento.";
+$labels['itipobjectnotfound'] = 'O evento citado nesta mensagem não foi encontrado no seu calendário.';
+$labels['itipmailbodyaccepted'] = "\$sender aceitou o convite para o seguinte evento:\n\n*\$title*\n\nQuando: \$date\n\nConvidados: \$attendees";
+$labels['itipmailbodytentative'] = "\$sender aceitou o convite como \"tentativa\" para o seguinte evento:\n\n*\$title*\n\nQuando: \$date\n\nConvidados: \$attendees";
+$labels['itipmailbodydeclined'] = "\$sender recusou o convite para o seguinte evento:\n\n*\$title*\n\nQuando: \$date\n\nConvidados: \$attendees";
+$labels['itipmailbodycancel'] = "\$sender rejeitou a sua participação no seguinte evento:\n\n*\$title*\n\nQuando: \$date";
+$labels['itipmailbodydelegated'] = "\$sender delegou a participação no seguinte evento:\n\n*\$title*\n\nWhen: \$date";
+$labels['itipmailbodydelegatedto'] = "\$sender delegou a sua participação no seguinte evento:\n\n*\$title*\n\nWhen: \$date";
+$labels['itipdeclineevent'] = 'Deseja recusar o convite para este evento?';
+$labels['declinedeleteconfirm'] = 'Também deseja apagar o evento recusado do seu calendário?';
+$labels['itipcomment'] = 'Observações â Convite/notificação';
+$labels['itipcommenttitle'] = 'Estas observações serão enviadas com o convite/notificação aos participantes.';
+$labels['notanattendee'] = 'Não está listado como participante neste evento';
+$labels['eventcancelled'] = 'O evento foi cancelado';
+$labels['saveincalendar'] = 'guardar em';
+$labels['updatemycopy'] = 'Atualizar no meu calendário';
+$labels['savetocalendar'] = 'Guardar no calendário';
+$labels['openpreview'] = 'Verificar calendário';
+$labels['noearlierevents'] = 'Sem eventos anteriores';
+$labels['nolaterevents'] = 'Sem eventos posteriores';
+$labels['resource'] = 'Recurso';
+$labels['addresource'] = 'Livro de recursos';
+$labels['findresources'] = 'Encontrar recursos';
+$labels['resourcedetails'] = 'Detalhes';
+$labels['resourceavailability'] = 'Disponibilidade';
+$labels['resourceowner'] = 'Dono';
+$labels['resourceadded'] = 'O recurso foi adicionado ao seu evento';
+$labels['tabsummary'] = 'Sumário';
+$labels['tabrecurrence'] = 'Repetição';
+$labels['tabattendees'] = 'Participantes';
+$labels['tabresources'] = 'Recursos';
+$labels['tabattachments'] = 'Anexos';
+$labels['tabsharing'] = 'Partilha';
+$labels['deleteobjectconfirm'] = 'Tem a certeza que quer eliminar este evento?';
+$labels['deleteventconfirm'] = 'Tem a certeza que quer eliminar este evento?';
+$labels['deletecalendarconfirm'] = 'Tem a certeza que quer eliminar este calendário e todos os seus eventos?';
+$labels['deletecalendarconfirmrecursive'] = 'Tem a certeza que quer eliminar este calendário com todos os seus eventos e sub-calendários?';
+$labels['savingdata'] = 'A guardar os dados...';
+$labels['errorsaving'] = 'Falha ao guardar as alterações.';
+$labels['operationfailed'] = 'A operação pedida falhou.';
+$labels['invalideventdates'] = 'As datas são inválidas! Por favor, verifique novamente.';
+$labels['invalidcalendarproperties'] = 'Propriedades de calendário inválidas! Por favor defina um nome válido.';
+$labels['searchnoresults'] = 'Nenhum evento encontrado nos calendários selecionados.';
+$labels['successremoval'] = 'O evento foi excluÃdo com sucesso.';
+$labels['successrestore'] = 'O evento foi restaurado com sucesso.';
+$labels['errornotifying'] = 'Falha ao enviar notificações para os participantes do evento.';
+$labels['errorimportingevent'] = 'Falha ao importar evento';
+$labels['importwarningexists'] = 'Uma cópia deste evento já existe em seu calendário.';
+$labels['newerversionexists'] = 'Já existe uma nova versão deste evento! Abortado.';
+$labels['nowritecalendarfound'] = 'Nenhum calendário encontrado para salvar o evento';
+$labels['importedsuccessfully'] = 'O evento foi adicionado com sucesso em \'$calendar\'';
+$labels['updatedsuccessfully'] = 'O evento foi atualizado com sucesso em \'$calendar\'.';
+$labels['attendeupdateesuccess'] = 'O status do participante foi atualizado com sucesso.';
+$labels['itipsendsuccess'] = 'Convite enviado aos participantes.';
+$labels['itipresponseerror'] = 'Falha ao enviar a resposta para este convite de evento';
+$labels['itipinvalidrequest'] = 'Este convite já não é válido';
+$labels['sentresponseto'] = 'Resposta de convite enviada com sucesso para $mailto';
+$labels['localchangeswarning'] = 'As alterações que pretende efetuar só serão válidas no seu calendário e não serão enviadas ao organizador do evento.';
+$labels['importsuccess'] = 'Importado com sucesso $nr eventos';
+$labels['importnone'] = 'Não há eventos a serem importados';
+$labels['importerror'] = 'Ocorreu um erro na importação';
+$labels['aclnorights'] = 'Não tem permissão de administrador neste calendário.';
+$labels['changeeventconfirm'] = 'Alterar evento';
+$labels['removeeventconfirm'] = 'Eliminar evento';
+$labels['changerecurringeventwarning'] = 'Este evento é recorrente. Deseja alterar a ocorrência atual, esta e todas as futuras ocorrências ou guardar como um novo evento?';
+$labels['removerecurringeventwarning'] = 'Este evento é recorrente. Deseja eliminar a ocorrência atual, esta e todas as futuras ocorrências ou todas as ocorrências do evento?';
+$labels['removerecurringallonly'] = 'Este evento é recorrente. Como participante, só pode apagar apagar o evento com todas as ocorrências.';
+$labels['currentevent'] = 'Atual';
+$labels['futurevents'] = 'Futuro';
+$labels['allevents'] = 'Todos';
+$labels['saveasnew'] = 'Guardar como';
+$labels['birthdays'] = 'Aniversários';
+$labels['birthdayscalendar'] = 'Calendário de aniversários';
+$labels['displaybirthdayscalendar'] = 'Mostrar calendário de aniversários';
+$labels['birthdayscalendarsources'] = 'From these address books';
+$labels['birthdayeventtitle'] = 'Aniversário de $name';
+$labels['birthdayage'] = 'Idade $age';
+$labels['objectchangelog'] = 'Alterar histórico';
+$labels['revision'] = 'Revisão';
+$labels['user'] = 'Utilizador';
+$labels['operation'] = 'Ação';
+$labels['actionappend'] = 'Guardado';
+$labels['actionmove'] = 'Movido';
+$labels['actiondelete'] = 'Eliminado';
+$labels['compare'] = 'Comparar';
+$labels['showrevision'] = 'Mostrar esta versão';
+$labels['restore'] = 'Restaurar esta versão';
+$labels['objectnotfound'] = 'Falha ao ler os dados do evento';
+$labels['objectchangelognotavailable'] = 'Não é possÃvel alterar o histórico deste evento';
+$labels['objectdiffnotavailable'] = 'Não é possÃvel comparar as revisões selecionadas';
+$labels['revisionrestoreconfirm'] = 'Confirma o restauro da revisão $rev deste evento? Os dados atuais serão substituÃdos pelos da versão anterior.';
+$labels['arialabelminical'] = 'Seleção da data do calendário';
+$labels['arialabelcalendarview'] = 'Vista do calendário';
+$labels['arialabelsearchform'] = 'Quadro de pesquisa de eventos';
+$labels['arialabelquicksearchbox'] = 'Pesquisa de eventos';
+$labels['arialabelcalsearchform'] = 'Quadro de pesquisa de calendários';
+$labels['calendaractions'] = 'Ações do calendário';
+$labels['arialabeleventattendees'] = 'Lista de participantes do evento';
+$labels['arialabeleventresources'] = 'Lista de recursos para eventos';
+$labels['arialabelresourcesearchform'] = 'Quadro de pesquisa de recursos';
+$labels['arialabelresourceselection'] = 'Recursos disponÃveis';
+?>
diff --git a/plugins/calendar/localization/ru_RU.inc b/plugins/calendar/localization/ru_RU.inc
index a7b0918..b5c3c1d 100644
--- a/plugins/calendar/localization/ru_RU.inc
+++ b/plugins/calendar/localization/ru_RU.inc
@@ -247,7 +247,8 @@ $labels['displaybirthdayscalendar'] = 'ÐоказÑваÑÑ ÐºÐ°Ð»ÐµÐ½Ð´Ð°ÑÑ
$labels['birthdayscalendarsources'] = 'Ðз ÑÑиÑ
адÑеÑнÑÑ
книг';
$labels['birthdayeventtitle'] = 'ÐÐµÐ½Ñ ÑÐ¾Ð¶Ð´ÐµÐ½Ð¸Ñ $name';
$labels['birthdayage'] = 'ÐозÑаÑÑ $age';
-$labels['eventchangelog'] = 'ÐÑÑоÑÐ¸Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹';
+$labels['objectchangelog'] = 'ÐÑÑоÑÐ¸Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹';
+$labels['objectdiff'] = 'ÐÐ·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ñ $rev1 до $rev2';
$labels['revision'] = 'РевизиÑ';
$labels['user'] = 'ÐолÑзоваÑелÑ';
$labels['operation'] = 'ÐейÑÑвие';
@@ -257,10 +258,12 @@ $labels['actiondelete'] = 'Удалено';
$labels['compare'] = 'СÑавниÑÑ';
$labels['showrevision'] = 'ÐоказаÑÑ ÑÑÑ Ð²ÐµÑÑиÑ';
$labels['restore'] = 'ÐоÑÑÑановиÑÑ ÑÑÑ Ð²ÐµÑÑиÑ';
-$labels['eventnotfound'] = 'Ðе ÑдалоÑÑ Ð·Ð°Ð³ÑÑзиÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾ меÑопÑиÑÑиÑÑ
';
+$labels['objectnotfound'] = 'Ðе ÑдалоÑÑ Ð·Ð°Ð³ÑÑзиÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾ меÑопÑиÑÑиÑÑ
';
$labels['objectchangelognotavailable'] = 'ÐÑÑоÑÐ¸Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹ Ð´Ð»Ñ ÑÑого ÑобÑÑÐ¸Ñ Ð½ÐµÐ´Ð¾ÑÑÑпна';
-$labels['eventdiffnotavailable'] = 'Ðевозможно пÑовеÑÑи ÑÑавнение вÑбÑаннÑÑ
Ñевизий ';
+$labels['objectdiffnotavailable'] = 'Ðевозможно пÑовеÑÑи ÑÑавнение вÑбÑаннÑÑ
Ñевизий ';
$labels['revisionrestoreconfirm'] = 'ÐÑ ÑвеÑеннÑ, ÑÑо Ñ
оÑиÑе воÑÑÑановиÑÑ ÑÑо ÑобÑÑие из Ñевизии $rev? Ðно Ð·Ð°Ð¼ÐµÐ½Ð¸Ñ ÑекÑÑее ÑобÑÑие ÑÑаÑой веÑÑией. ';
+$labels['objectrestoresuccess'] = 'Ð ÐµÐ²Ð¸Ð·Ð¸Ñ $rev ÑÑпеÑно воÑÑÑановлена';
+$labels['objectrestoreerror'] = 'Ðе ÑдалоÑÑ Ð²Ð¾ÑÑÑановиÑÑ ÑÑаÑÑÑ ÑевизиÑ';
$labels['arialabelminical'] = 'ÐÑÐ±Ð¾Ñ Ð´Ð°ÑÑ';
$labels['arialabelcalendarview'] = 'Ðид календаÑÑ';
$labels['arialabelsearchform'] = 'ФоÑма поиÑка ÑобÑÑий';
diff --git a/plugins/calendar/localization/sl_SI.inc b/plugins/calendar/localization/sl_SI.inc
index 9ab874b..0691d42 100644
--- a/plugins/calendar/localization/sl_SI.inc
+++ b/plugins/calendar/localization/sl_SI.inc
@@ -246,7 +246,7 @@ $labels['displaybirthdayscalendar'] = 'Prikaži koledar rojstnih dnevov';
$labels['birthdayscalendarsources'] = 'Iz teh imenikov';
$labels['birthdayeventtitle'] = 'Rojstni dan osebe $name';
$labels['birthdayage'] = 'Starost $age';
-$labels['eventchangelog'] = 'Spremeni Zgodovino';
+$labels['objectchangelog'] = 'Spremeni Zgodovino';
$labels['revision'] = 'Verzija';
$labels['user'] = 'Uporabnik';
$labels['operation'] = 'Dejanje';
@@ -256,9 +256,9 @@ $labels['actiondelete'] = 'Izbrisano';
$labels['compare'] = 'Primerjaj';
$labels['showrevision'] = 'Prikaži to verzijo';
$labels['restore'] = 'Obnovi to verzijo';
-$labels['eventnotfound'] = 'Napaka pri nalaganju podatkov o dogodku';
+$labels['objectnotfound'] = 'Napaka pri nalaganju podatkov o dogodku';
$labels['objectchangelognotavailable'] = 'Sprememba zgodovine za ta dogodek ni na voljo';
-$labels['eventdiffnotavailable'] = 'Primerjava za izbrane verzije ni na voljo';
+$labels['objectdiffnotavailable'] = 'Primerjava za izbrane verzije ni na voljo';
$labels['revisionrestoreconfirm'] = 'Ali želite obnoviti verzijo $rev tega dogodka? To bo nadomestilo trenutni dogodek s starejšo verzijo.';
$labels['arialabelminical'] = 'Izbira datuma v koledarju';
$labels['arialabelcalendarview'] = 'Prikaz koledarja';
diff --git a/plugins/calendar/localization/sv_SE.inc b/plugins/calendar/localization/sv_SE.inc
index 94e7213..edf1db6 100644
--- a/plugins/calendar/localization/sv_SE.inc
+++ b/plugins/calendar/localization/sv_SE.inc
@@ -246,7 +246,7 @@ $labels['displaybirthdayscalendar'] = 'Visa födelsedagskalender';
$labels['birthdayscalendarsources'] = 'Från dessa adressböcker';
$labels['birthdayeventtitle'] = '$name\s födelsedag';
$labels['birthdayage'] = '$age år';
-$labels['eventchangelog'] = 'Ãndringshistorik';
+$labels['objectchangelog'] = 'Ãndringshistorik';
$labels['revision'] = 'Revision';
$labels['user'] = 'Användare';
$labels['operation'] = 'Ã
tgärd';
@@ -256,9 +256,9 @@ $labels['actiondelete'] = 'Borttagen';
$labels['compare'] = 'Jämför';
$labels['showrevision'] = 'Visa denna version';
$labels['restore'] = 'Ã
terställ denna verson';
-$labels['eventnotfound'] = 'Det gick inte att läsa in data för händelsen';
+$labels['objectnotfound'] = 'Det gick inte att läsa in data för händelsen';
$labels['objectchangelognotavailable'] = 'Ãndringshistorik är inte tillgänglig för denna händelse';
-$labels['eventdiffnotavailable'] = 'Ingen jämförelse möjlig för valda revisioner';
+$labels['objectdiffnotavailable'] = 'Ingen jämförelse möjlig för valda revisioner';
$labels['revisionrestoreconfirm'] = 'Vill du verkligen återställa revision $rev för denna händelse? Det kommer att ersätta den aktuella händelsen med den gamla versionen.';
$labels['arialabelminical'] = 'Kalender datumurval';
$labels['arialabelcalendarview'] = 'Kalender vy';
diff --git a/plugins/calendar/localization/th_TH.inc b/plugins/calendar/localization/th_TH.inc
index f157543..c9933fc 100644
--- a/plugins/calendar/localization/th_TH.inc
+++ b/plugins/calendar/localization/th_TH.inc
@@ -233,7 +233,7 @@ $labels['displaybirthdayscalendar'] = 'à¹à¸ªà¸à¸à¸à¸à¸´à¸à¸´à¸à¸§à¸±à¸
$labels['birthdayscalendarsources'] = 'à¸à¸²à¸à¸ªà¸¡à¸¸à¸à¸à¸µà¹à¸à¸¢à¸¹à¹à¹à¸«à¸¥à¹à¸²à¸à¸µà¹';
$labels['birthdayeventtitle'] = 'วัà¸à¹à¸à¸´à¸à¸à¸à¸ $name';
$labels['birthdayage'] = 'à¸à¸²à¸¢à¸¸ $age à¸à¸µ';
-$labels['eventchangelog'] = 'à¸à¸£à¸°à¸§à¸±à¸à¸´à¸à¸²à¸£à¸à¸£à¸±à¸à¹à¸à¸¥à¸µà¹à¸¢à¸';
+$labels['objectchangelog'] = 'à¸à¸£à¸°à¸§à¸±à¸à¸´à¸à¸²à¸£à¸à¸£à¸±à¸à¹à¸à¸¥à¸µà¹à¸¢à¸';
$labels['revision'] = 'รุà¹à¸à¸à¸²à¸£à¸à¸£à¸±à¸à¸à¸£à¸¸à¸';
$labels['user'] = 'à¸à¸¹à¹à¹à¸à¹';
$labels['operation'] = 'à¸à¸²à¸£à¸à¸£à¸°à¸à¸³';
@@ -243,9 +243,9 @@ $labels['actiondelete'] = 'ลà¸à¹à¸£à¸µà¸¢à¸à¸£à¹à¸à¸¢';
$labels['compare'] = 'à¹à¸à¸£à¸µà¸¢à¸à¹à¸à¸µà¸¢à¸';
$labels['showrevision'] = 'à¹à¸ªà¸à¸à¸£à¸¸à¹à¸à¸à¸²à¸£à¸à¸£à¸±à¸à¸à¸£à¸¸à¸à¸à¸µà¹';
$labels['restore'] = 'ยà¹à¸à¸à¸à¸¥à¸±à¸à¹à¸à¸¢à¸±à¸à¸£à¸¸à¹à¸à¸à¸²à¸£à¸à¸£à¸±à¸à¸à¸£à¸¸à¸à¸à¸µà¹';
-$labels['eventnotfound'] = 'à¸à¸²à¸£à¹à¸«à¸¥à¸à¸à¹à¸à¸¡à¸¹à¸¥à¸à¸à¸à¹à¸«à¸à¸¸à¸à¸²à¸£à¸à¹à¸¥à¹à¸¡à¹à¸«à¸¥à¸§';
+$labels['objectnotfound'] = 'à¸à¸²à¸£à¹à¸«à¸¥à¸à¸à¹à¸à¸¡à¸¹à¸¥à¸à¸à¸à¹à¸«à¸à¸¸à¸à¸²à¸£à¸à¹à¸¥à¹à¸¡à¹à¸«à¸¥à¸§';
$labels['objectchangelognotavailable'] = 'à¹à¸¡à¹à¸¡à¸µà¸à¸£à¸°à¸§à¸±à¸à¸´à¸à¸²à¸£à¸à¸£à¸±à¸à¹à¸à¸¥à¸µà¹à¸¢à¸à¸ªà¸³à¸«à¸£à¸±à¸à¹à¸«à¸à¸¸à¸à¸²à¸£à¸à¹à¸à¸µà¹';
-$labels['eventdiffnotavailable'] = 'à¹à¸¡à¹à¸ªà¸²à¸¡à¸²à¸£à¸à¹à¸à¸£à¸µà¸¢à¸à¹à¸à¸µà¸¢à¸à¸£à¸¸à¹à¸à¸à¸²à¸£à¸à¸£à¸±à¸à¸à¸£à¸¸à¸à¸à¸µà¹à¹à¸¥à¸·à¸à¸à¹à¸à¹';
+$labels['objectdiffnotavailable'] = 'à¹à¸¡à¹à¸ªà¸²à¸¡à¸²à¸£à¸à¹à¸à¸£à¸µà¸¢à¸à¹à¸à¸µà¸¢à¸à¸£à¸¸à¹à¸à¸à¸²à¸£à¸à¸£à¸±à¸à¸à¸£à¸¸à¸à¸à¸µà¹à¹à¸¥à¸·à¸à¸à¹à¸à¹';
$labels['revisionrestoreconfirm'] = 'à¸à¸¸à¸à¸à¹à¸à¸à¸à¸²à¸£à¸à¸¹à¹à¸à¸·à¸à¸£à¸¸à¹à¸à¸à¸²à¸£à¸à¸£à¸±à¸à¸à¸£à¸¸à¸ $rev à¸à¸à¸à¹à¸«à¸à¸¸à¸à¸²à¸£à¸à¹à¸à¸µà¹à¸«à¸£à¸·à¸ à¸à¸µà¹à¸à¸°à¹à¸à¹à¸à¸à¸²à¸£à¹à¸à¸µà¸¢à¸à¸à¸±à¸à¸à¹à¸à¸¡à¸¹à¸¥à¸à¸±à¸à¸à¸¸à¸à¸±à¸à¸à¹à¸§à¸¢à¸à¹à¸à¸¡à¸¹à¸¥à¸à¸µà¹à¹à¸à¹à¸²à¸à¸§à¹à¸²';
$labels['arialabelcalendarview'] = 'มุมมà¸à¸à¸à¸à¸´à¸à¸´à¸';
$labels['arialabelquicksearchbox'] = 'à¸à¹à¸à¸à¸à¹à¸à¸¡à¸¹à¸¥à¹à¸à¸·à¹à¸à¸à¹à¸à¸«à¸²à¹à¸«à¸à¸¸à¸à¸²à¸£à¸à¹';
diff --git a/plugins/calendar/localization/uk_UA.inc b/plugins/calendar/localization/uk_UA.inc
index aac583a..f430667 100644
--- a/plugins/calendar/localization/uk_UA.inc
+++ b/plugins/calendar/localization/uk_UA.inc
@@ -205,7 +205,7 @@ $labels['displaybirthdayscalendar'] = 'ÐоказÑваÑи ÐºÐ°Ð»ÐµÐ½Ð´Ð°Ñ Ð
$labels['birthdayscalendarsources'] = 'РданиÑ
адÑеÑниÑ
книг';
$labels['birthdayeventtitle'] = 'ÐÐµÐ½Ñ ÐаÑÐ¾Ð´Ð¶ÐµÐ½Ð½Ñ $name';
$labels['birthdayage'] = 'ÐÑк $age';
-$labels['eventchangelog'] = 'ÐÑÑоÑÑÑ Ð·Ð¼Ñн';
+$labels['objectchangelog'] = 'ÐÑÑоÑÑÑ Ð·Ð¼Ñн';
$labels['revision'] = 'РевÑзÑÑ';
$labels['user'] = 'ÐоÑиÑÑÑваÑ';
$labels['operation'] = 'ÐÑÑ';
diff --git a/plugins/calendar/skins/larry/calendar.css b/plugins/calendar/skins/larry/calendar.css
index b0a8660..0669a8f 100644
--- a/plugins/calendar/skins/larry/calendar.css
+++ b/plugins/calendar/skins/larry/calendar.css
@@ -837,14 +837,14 @@ a.miniColors-trigger {
text-decoration: none;
}
-#eventhistory .loading {
+.changelog-table .loading {
color: #666;
margin: 1em 0;
padding: 1px 0 2px 24px;
background: url(images/loading_blue.gif) top left no-repeat;
}
-#eventhistory .compare-button {
+.changelog-dialog .compare-button {
margin: 4px 0;
}
diff --git a/plugins/calendar/skins/larry/templates/calendar.html b/plugins/calendar/skins/larry/templates/calendar.html
index b9ea905..8d8e010 100644
--- a/plugins/calendar/skins/larry/templates/calendar.html
+++ b/plugins/calendar/skins/larry/templates/calendar.html
@@ -335,7 +335,7 @@
</div>
<div id="eventhistory" class="uidialog" aria-hidden="true">
- <roundcube:object name="plugin.event_changelog_table" id="event-changelog-table" class="records-table changelog-table" />
+ <roundcube:object name="plugin.object_changelog_table" id="event-changelog-table" class="records-table changelog-table" domain="calendar" />
<div class="compare-button"><input type="button" class="button" value="â³ <roundcube:label name='calendar.compare' />" /></div>
</div>
diff --git a/plugins/libkolab/js/audittrail.js b/plugins/libkolab/js/audittrail.js
index 5c9eec0..0fe7bcb 100644
--- a/plugins/libkolab/js/audittrail.js
+++ b/plugins/libkolab/js/audittrail.js
@@ -44,7 +44,7 @@ libkolab_audittrail.object_history_dialog = function(p)
$dialog.dialog('close');
var buttons = {};
- buttons[rcmail.gettext('close', 'calendar')] = function() {
+ buttons[rcmail.gettext('close')] = function() {
$dialog.dialog('close');
};
@@ -189,7 +189,7 @@ libkolab_audittrail.render_changelog = function(data, object, folder)
.append('<td class="revision">' + Q(i+1) + '</td>')
.append('<td class="date">' + Q(change.date || '') + '</td>')
.append('<td class="user">' + Q(change.user || 'undisclosed') + '</td>')
- .append('<td class="operation" title="' + op_append + '">' + Q(rcmail.gettext(op_labels[change.op] || '', 'calendar') + (op_append ? ' ...' : '')) + '</td>')
+ .append('<td class="operation" title="' + op_append + '">' + Q(rcmail.gettext(op_labels[change.op] || '', data.module) + (op_append ? ' ...' : '')) + '</td>')
.append('<td class="actions">' + (accessible && change.op != 'DELETE' ? actions.replace(/\{rev\}/g, change.rev) : '') + '</td>')
.appendTo(tbody);
}
diff --git a/plugins/libkolab/libkolab.php b/plugins/libkolab/libkolab.php
index f1c2c87..4aa1ce5 100644
--- a/plugins/libkolab/libkolab.php
+++ b/plugins/libkolab/libkolab.php
@@ -130,6 +130,24 @@ class libkolab extends rcube_plugin
}
/**
+ * Table oultine for object changelog display
+ */
+ public static function object_changelog_table($attrib = array())
+ {
+ $rcube = rcube::get_instance();
+
+ $table = new html_table(array('cols' => 5, 'border' => 0, 'cellspacing' => 0));
+ $table->add_header('diff', '');
+ $table->add_header('revision', $rcube->gettext('revision', $attrib['domain']));
+ $table->add_header('date', $rcube->gettext('date', $attrib['domain']));
+ $table->add_header('user', $rcube->gettext('user', $attrib['domain']));
+ $table->add_header('operation', $rcube->gettext('operation', $attrib['domain']));
+ $table->add_header('actions', ' ');
+
+ return $table->show($attrib);
+ }
+
+ /**
* Wrapper function for generating a html diff using the FineDiff class by Raymond Hill
*/
public static function html_diff($from, $to)
More information about the commits
mailing list