3 commits - plugins/calendar plugins/kolab_addressbook plugins/kolab_notes plugins/libkolab plugins/tasklist

Thomas Brüderli bruederli at kolabsys.com
Thu Sep 11 15:54:38 CEST 2014


 plugins/calendar/calendar_ui.js                             |    5 
 plugins/calendar/lib/calendar_ui.php                        |    7 -
 plugins/calendar/localization/en_US.inc                     |    2 
 plugins/calendar/skins/larry/calendar.css                   |   71 ++++++++----
 plugins/calendar/skins/larry/images/calendars.png           |binary
 plugins/calendar/skins/larry/templates/calendar.html        |    2 
 plugins/kolab_addressbook/kolab_addressbook.js              |   36 +++++-
 plugins/kolab_addressbook/kolab_addressbook.php             |    1 
 plugins/kolab_addressbook/lib/kolab_addressbook_ui.php      |    2 
 plugins/kolab_addressbook/localization/en_US.inc            |    1 
 plugins/kolab_addressbook/skins/larry/folder_icons.png      |binary
 plugins/kolab_addressbook/skins/larry/kolab_addressbook.css |    6 -
 plugins/kolab_notes/kolab_notes_ui.php                      |   12 +-
 plugins/kolab_notes/localization/en_US.inc                  |    2 
 plugins/kolab_notes/notes.js                                |    5 
 plugins/kolab_notes/skins/larry/notes.css                   |   60 ++++++++--
 plugins/kolab_notes/skins/larry/sprites.png                 |binary
 plugins/libkolab/js/folderlist.js                           |   25 +++-
 plugins/tasklist/localization/en_US.inc                     |    2 
 plugins/tasklist/skins/larry/sprites.png                    |binary
 plugins/tasklist/skins/larry/tasklist.css                   |   66 +++++++----
 plugins/tasklist/tasklist.js                                |    5 
 plugins/tasklist/tasklist_ui.php                            |    9 +
 23 files changed, 247 insertions(+), 72 deletions(-)

New commits:
commit 6b7fc6729d23e273f4e5a9cbbd2f6cd7ec8b9ba8
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date:   Thu Sep 11 15:54:15 2014 +0200

    Added 'actions' bar and new icons for groupware folders as suggested by the product feature description

diff --git a/plugins/calendar/calendar_ui.js b/plugins/calendar/calendar_ui.js
index ef40938..381e7e8 100644
--- a/plugins/calendar/calendar_ui.js
+++ b/plugins/calendar/calendar_ui.js
@@ -3411,6 +3411,11 @@ function rcube_calendar_ui(settings)
         rcmail.http_post('calendar', { action:'subscribe', c:{ id:p.id, active:cal.active?1:0, permanent:cal.subscribed?1:0 } });
       }
     });
+    calendars_list.addEventListener('remove', function(p) {
+      if (me.calendars[p.id] && me.calendars[p.id].removable) {
+        me.calendar_remove(me.calendars[p.id]);
+      }
+    });
     calendars_list.addEventListener('search-complete', function(data) {
       if (data.length)
         rcmail.display_message(rcmail.gettext('nrcalendarsfound','calendar').replace('$nr', data.length), 'voice');
diff --git a/plugins/calendar/lib/calendar_ui.php b/plugins/calendar/lib/calendar_ui.php
index 2693642..f80cce1 100644
--- a/plugins/calendar/lib/calendar_ui.php
+++ b/plugins/calendar/lib/calendar_ui.php
@@ -310,8 +310,11 @@ class calendar_ui
         html::span(array('class' => 'calname', 'id' => $label_id, 'title' => $title), $prop['editname'] ? Q($prop['editname']) : $prop['listname']) .
         ($prop['virtual'] ? '' :
           html::tag('input', array('type' => 'checkbox', 'name' => '_cal[]', 'value' => $id, 'checked' => $prop['active'], 'aria-labelledby' => $label_id), '') .
-          html::a(array('href' => '#', 'class' => 'quickview', 'title' => $this->cal->gettext('quickview'), 'role' => 'button'), '') .
-          (isset($prop['subscribed']) ? html::a(array('href' => '#', 'class' => 'subscribed', 'title' => $this->cal->gettext('calendarsubscribe'), 'role' => 'checkbox', 'aria-checked' => $prop['subscribed'] ? 'true' : 'false'), ' ') : '') .
+          html::span('actions', 
+            ($prop['removable'] ? html::a(array('href' => '#', 'class' => 'remove', 'title' => $this->cal->gettext('removelist')), ' ') : '') .
+            html::a(array('href' => '#', 'class' => 'quickview', 'title' => $this->cal->gettext('quickview'), 'role' => 'button'), '') .
+            (isset($prop['subscribed']) ? html::a(array('href' => '#', 'class' => 'subscribed', 'title' => $this->cal->gettext('calendarsubscribe'), 'role' => 'checkbox', 'aria-checked' => $prop['subscribed'] ? 'true' : 'false'), ' ') : '')
+          ) .
           html::span(array('class' => 'handle', 'style' => "background-color: #" . ($prop['color'] ?: 'f00')), ' ')
         )
       );
diff --git a/plugins/calendar/localization/en_US.inc b/plugins/calendar/localization/en_US.inc
index 6023366..76fbcee 100644
--- a/plugins/calendar/localization/en_US.inc
+++ b/plugins/calendar/localization/en_US.inc
@@ -51,7 +51,7 @@ $labels['new_event'] = 'New event';
 $labels['edit_event'] = 'Edit event';
 $labels['edit'] = 'Edit';
 $labels['save'] = 'Save';
-$labels['remove'] = 'Remove';
+$labels['removelist'] = 'Remove from list';
 $labels['cancel'] = 'Cancel';
 $labels['select'] = 'Select';
 $labels['print'] = 'Print';
diff --git a/plugins/calendar/skins/larry/calendar.css b/plugins/calendar/skins/larry/calendar.css
index e33f01a..54e0141 100644
--- a/plugins/calendar/skins/larry/calendar.css
+++ b/plugins/calendar/skins/larry/calendar.css
@@ -218,7 +218,7 @@ pre {
 	position: absolute;
 	top: 7px;
 	left: 38px;
-	right: 60px;
+	right: 45px;
 	cursor: default;
 	background: url(images/calendars.png) right 20px no-repeat;
 	overflow: hidden;
@@ -259,11 +259,36 @@ pre {
 	box-shadow: inset 0px 0 1px 1px rgba(0, 0, 0, 0.3);
 }
 
+#calendars .treelist div span.actions {
+	display: inline-block;
+	position: absolute;
+	top: 2px;
+	right: 22px;
+	padding: 5px 20px 0 6px;
+	min-width: 40px;
+	height: 19px;
+	text-align: right;
+}
+
+#calendars .treelist div:hover span.actions {
+	top: 1px;
+	right: 21px;
+	border: 1px solid #c6c6c6;
+	border-radius: 4px;
+	background: #f7f7f7;
+	background: -moz-linear-gradient(top, #f9f9f9 0%, #e6e6e6 100%);
+	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f9f9f9), color-stop(100%,#e6e6e6));
+	background: -o-linear-gradient(top, #f9f9f9 0%, #e6e6e6 100%);
+	background: -ms-linear-gradient(top, #f9f9f9 0%, #e6e6e6 100%);
+	background: linear-gradient(top, #f9f9f9 0%, #e6e6e6 100%);
+	filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f9f9f9', endColorstr='#e6e6e6', GradientType=0);
+}
+
 #calendars .treelist li a.subscribed {
 	display: inline-block;
 	position: absolute;
-	top: 7px;
-	right: 24px;
+	top: 5px;
+	right: 3px;
 	height: 16px;
 	width: 16px;
 	padding: 0;
@@ -273,14 +298,8 @@ pre {
 	cursor: pointer;
 }
 
-#calendars .treelist div > a.quickview:focus,
-#calendars .treelist div > a.subscribed:focus {
-	border-radius: 3px;
-	outline: 2px solid rgba(30,150,192, 0.5);
-}
-
-#calendars .treelist div:hover > a.subscribed,
-#calendars .treelist div > a.subscribed:focus {
+#calendars .treelist div:hover a.subscribed,
+#calendars .treelist div a.subscribed:focus {
 	background-position: 0 -110px;
 }
 
@@ -294,13 +313,19 @@ pre {
 	background-position: -16px -148px;
 }
 
-#calendars .treelist li a.quickview {
+#calendars .treelist div a.remove:focus,
+#calendars .treelist div a.quickview:focus,
+#calendars .treelist div a.subscribed:focus {
+	border-radius: 3px;
+	outline: 2px solid rgba(30,150,192, 0.5);
+}
+
+#calendars .treelist div a.remove,
+#calendars .treelist div a.quickview {
 	display: inline-block;
-	position: absolute;
-	top: 6px;
-	right: 42px;
 	width: 16px;
 	height: 16px;
+	margin-right: 4px;
 	padding: 0;
 	background: url(images/calendars.png) -100px 0 no-repeat;
 	overflow: hidden;
@@ -308,14 +333,20 @@ pre {
 	cursor: pointer;
 }
 
-#calendars .treelist div > a.quickview:focus,
-#calendars .treelist li div:hover > a.quickview {
-	background-position: 0 -128px;
+#calendars .treelist div a.quickview:focus,
+#calendars .treelist div:hover a.quickview {
+	background-position: 0 -148px;
+	background-color: transparent !important;
+}
+
+#calendars .treelist div a.remove:focus,
+#calendars .treelist div:hover a.remove {
+	background-position: -16px -168px;
 	background-color: transparent !important;
 }
 
-#calendars .treelist li div.focusview > a.quickview {
-	background-position: -18px -128px;
+#calendars .searchresults .treelist div a.remove {
+	display: none;
 }
 
 #calendars .treelist li input {
diff --git a/plugins/calendar/skins/larry/images/calendars.png b/plugins/calendar/skins/larry/images/calendars.png
index 88eba63..17e259a 100644
Binary files a/plugins/calendar/skins/larry/images/calendars.png and b/plugins/calendar/skins/larry/images/calendars.png differ
diff --git a/plugins/calendar/skins/larry/templates/calendar.html b/plugins/calendar/skins/larry/templates/calendar.html
index 1df1748..72e86c7 100644
--- a/plugins/calendar/skins/larry/templates/calendar.html
+++ b/plugins/calendar/skins/larry/templates/calendar.html
@@ -71,7 +71,7 @@
 		<li role="menuitem"><roundcube:button command="calendar-edit" label="calendar.edit" classAct="active" /></li>
 		<li role="menuitem"><roundcube:button command="calendar-delete" label="delete" classAct="active" /></li>
 		<roundcube:if condition="env:calendar_driver == 'kolab'" />
-		<li role="menuitem"><roundcube:button command="calendar-remove" label="calendar.remove" classAct="active" /></li>
+		<li role="menuitem"><roundcube:button command="calendar-remove" label="calendar.removelist" classAct="active" /></li>
 		<roundcube:endif />
 		<li role="menuitem"><roundcube:button command="calendar-showurl" label="calendar.showurl" classAct="active" /></li>
 		<roundcube:if condition="env:calendar_driver == 'kolab'" />
diff --git a/plugins/kolab_addressbook/skins/larry/folder_icons.png b/plugins/kolab_addressbook/skins/larry/folder_icons.png
index 07674ab..b9c59b5 100644
Binary files a/plugins/kolab_addressbook/skins/larry/folder_icons.png and b/plugins/kolab_addressbook/skins/larry/folder_icons.png differ
diff --git a/plugins/kolab_addressbook/skins/larry/kolab_addressbook.css b/plugins/kolab_addressbook/skins/larry/kolab_addressbook.css
index 8aeb0cb..5484807 100644
--- a/plugins/kolab_addressbook/skins/larry/kolab_addressbook.css
+++ b/plugins/kolab_addressbook/skins/larry/kolab_addressbook.css
@@ -76,9 +76,9 @@
 	cursor: pointer;
 }
 
-#directorylistbox ul.treelist div > span.subscribed:focus,
-#directorylistbox ul.treelist div:hover > span.subscribed {
-	background-position: 2px -160px;
+#directorylistbox ul.treelist div span.subscribed:focus,
+#directorylistbox ul.treelist div:hover span.subscribed {
+	background-position: 0px -160px;
 }
 
 #directorylistbox ul.treelist div.subscribed span.subscribed {
diff --git a/plugins/kolab_notes/kolab_notes_ui.php b/plugins/kolab_notes/kolab_notes_ui.php
index 527e89b..817a228 100644
--- a/plugins/kolab_notes/kolab_notes_ui.php
+++ b/plugins/kolab_notes/kolab_notes_ui.php
@@ -217,9 +217,15 @@ class kolab_notes_ui
                     ''
                 ) .
                 html::span('handle', '') .
-                (isset($prop['subscribed']) ?
-                    html::a(array('href' => '#', 'class' => 'subscribed', 'title' => $this->plugin->gettext('foldersubscribe'), 'role' => 'checkbox', 'aria-checked' => $prop['subscribed'] ? 'true' : 'false'), ' ') :
-                    ''
+                html::span('actions',
+                    (!$prop['default'] ?
+                        html::a(array('href' => '#', 'class' => 'remove', 'title' => $this->plugin->gettext('removelist')), ' ') :
+                        ''
+                    ) .
+                    (isset($prop['subscribed']) ?
+                        html::a(array('href' => '#', 'class' => 'subscribed', 'title' => $this->plugin->gettext('foldersubscribe'), 'role' => 'checkbox', 'aria-checked' => $prop['subscribed'] ? 'true' : 'false'), ' ') :
+                        ''
+                    )
                 )
             )
         );
diff --git a/plugins/kolab_notes/localization/en_US.inc b/plugins/kolab_notes/localization/en_US.inc
index 21e6e1a..939946c 100644
--- a/plugins/kolab_notes/localization/en_US.inc
+++ b/plugins/kolab_notes/localization/en_US.inc
@@ -33,7 +33,7 @@ $labels['findnotebooks'] = 'Find notebooks...';
 $labels['listsearchresults'] = 'Additional notebooks';
 $labels['nrnotebooksfound'] = '$nr notebooks found';
 $labels['nonotebooksfound'] = 'No notebooks found';
-$labels['removelist'] = 'Remove';
+$labels['removelist'] = 'Remove from list';
 
 $labels['savingdata'] = 'Saving data...';
 $labels['recordnotfound'] = 'Record not found';
diff --git a/plugins/kolab_notes/notes.js b/plugins/kolab_notes/notes.js
index 5f514c1..911e8a7 100644
--- a/plugins/kolab_notes/notes.js
+++ b/plugins/kolab_notes/notes.js
@@ -130,6 +130,11 @@ function rcube_kolab_notes_ui(settings)
                 rcmail.http_post('list', { _do:'subscribe', _list:{ id:p.id, permanent:list.subscribed?1:0 } });
             }
         });
+        notebookslist.addEventListener('remove', function(p) {
+            if (me.notebooks[p.id] && !me.notebooks[p.id].default) {
+                list_remove(p.id);
+            }
+        });
         notebookslist.addEventListener('insert-item', function(p) {
             var list = p.data;
             if (list && list.id && !list.virtual) {
diff --git a/plugins/kolab_notes/skins/larry/notes.css b/plugins/kolab_notes/skins/larry/notes.css
index b5efa37..24daa9d 100644
--- a/plugins/kolab_notes/skins/larry/notes.css
+++ b/plugins/kolab_notes/skins/larry/notes.css
@@ -325,7 +325,8 @@
 	position: relative;
 }
 
-.notesview #notebooks li > div.folder {
+.notesview #notebooks li > div.folder,
+.notesview #notebooksbox .searchresults li > div.folder {
 	position: relative;
 	padding: 0;
 	height: 28px;
@@ -354,11 +355,37 @@
 	padding-top: 3px;
 }
 
-.notesview #notebooksbox .treelist li a.subscribed {
+.notesview #notebooksbox .treelist div span.actions {
 	display: inline-block;
 	position: absolute;
-	top: 6px;
-	right: 5px;
+	top: 2px;
+	right: 2px;
+	padding: 5px 20px 0 6px;
+	min-width: 20px;
+	height: 19px;
+	text-align: right;
+}
+
+.notesview #notebooksbox .treelist div:hover span.actions {
+	top: 1px;
+	right: 1px;
+	border: 1px solid #c6c6c6;
+	border-radius: 4px;
+	background: #f7f7f7;
+	background: -moz-linear-gradient(top, #f9f9f9 0%, #e6e6e6 100%);
+	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f9f9f9), color-stop(100%,#e6e6e6));
+	background: -o-linear-gradient(top, #f9f9f9 0%, #e6e6e6 100%);
+	background: -ms-linear-gradient(top, #f9f9f9 0%, #e6e6e6 100%);
+	background: linear-gradient(top, #f9f9f9 0%, #e6e6e6 100%);
+	filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f9f9f9', endColorstr='#e6e6e6', GradientType=0);
+}
+
+.notesview #notebooksbox .treelist div a.remove,
+.notesview #notebooksbox .treelist div a.subscribed {
+	display: inline-block;
+	position: absolute;
+	top: 5px;
+	right: 4px;
 	height: 16px;
 	width: 16px;
 	padding: 0;
@@ -368,20 +395,37 @@
 	cursor: pointer;
 }
 
-.notesview #notebooksbox .treelist div > a.subscribed:focus,
-.notesview #notebooksbox .treelist div:hover > a.subscribed {
-	background-position: 2px -266px;
+.notesview #notebooksbox .treelist div a.subscribed:focus,
+.notesview #notebooksbox .treelist div:hover a.subscribed {
+	background-position: 0 -266px;
 }
 
 .notesview #notebooksbox .treelist div.subscribed a.subscribed {
 	background-position: -16px -266px;
 }
 
-.notesview #notebooksbox .treelist li a.subscribed:focus {
+.notesview #notebooksbox .treelist div a.remove {
+	position: relative;
+	top: 0;
+	left: 0;
+	margin-right: 4px;
+}
+
+.notesview #notebooksbox .treelist div a.remove:focus,
+.notesview #notebooksbox .treelist div:hover a.remove {
+	background-position: 0 -284px;
+}
+
+.notesview #notebooksbox .treelist div a.remove:focus,
+.notesview #notebooksbox .treelist div a.subscribed:focus {
 	border-radius: 3px;
 	outline: 2px solid rgba(30,150,192, 0.5);
 }
 
+.notesview #notebooksbox .searchresults .treelist div a.remove {
+	display: none;
+}
+
 .notesview #notebooksbox .treelist input {
 	position: absolute;
 	top: 4px;
diff --git a/plugins/kolab_notes/skins/larry/sprites.png b/plugins/kolab_notes/skins/larry/sprites.png
index ceead25..99ac3a2 100644
Binary files a/plugins/kolab_notes/skins/larry/sprites.png and b/plugins/kolab_notes/skins/larry/sprites.png differ
diff --git a/plugins/libkolab/js/folderlist.js b/plugins/libkolab/js/folderlist.js
index 617dc45..62a60ef 100644
--- a/plugins/libkolab/js/folderlist.js
+++ b/plugins/libkolab/js/folderlist.js
@@ -290,16 +290,16 @@ function kolab_folderlist(node, p)
         }
     });
 
-    this.container.on('click', 'a.subscribed, span.subscribed', function(e){
+    this.container.on('click', 'a.subscribed, span.subscribed', function(e) {
         var li = $(this).closest('li'),
             id = li.attr('id').replace(new RegExp('^'+p.id_prefix), ''),
             div = li.children().first(),
             is_subscribed;
 
         if (me.is_search()) {
-          id = id.replace(/--xsR$/, '');
-          li = $(me.get_item(id, true));
-          div = $(div).add(li.children().first());
+            id = id.replace(/--xsR$/, '');
+            li = $(me.get_item(id, true));
+            div = $(div).add(li.children().first());
         }
 
         if (p.id_decode)
@@ -327,6 +327,23 @@ function kolab_folderlist(node, p)
         return false;
     });
 
+    this.container.on('click', 'a.remove', function(e) {
+      var li = $(this).closest('li'),
+          id = li.attr('id').replace(new RegExp('^'+p.id_prefix), '');
+
+      if (me.is_search()) {
+          id = id.replace(/--xsR$/, '');
+          li = $(me.get_item(id, true));
+      }
+
+      if (p.id_decode)
+          id = p.id_decode(id);
+
+      me.triggerEvent('remove', { id: id, item: li });
+
+      e.stopPropagation();
+      return false;
+    });
 }
 
 // link prototype from base class
diff --git a/plugins/tasklist/localization/en_US.inc b/plugins/tasklist/localization/en_US.inc
index 288bd71..7275995 100644
--- a/plugins/tasklist/localization/en_US.inc
+++ b/plugins/tasklist/localization/en_US.inc
@@ -19,7 +19,7 @@ $labels['findlists'] = 'Find tasklists...';
 $labels['searchterms'] = 'Search terms';
 $labels['notasklistsfound'] = 'No tasklists found';
 $labels['nrtasklistsfound'] = '$nr tasklists found';
-$labels['removelist'] = 'Remove';
+$labels['removelist'] = 'Remove from list';
 
 $labels['newtask'] = 'New Task';
 $labels['createtask'] = 'Create Task <Enter>';
diff --git a/plugins/tasklist/skins/larry/sprites.png b/plugins/tasklist/skins/larry/sprites.png
index fecbd58..36b48f5 100644
Binary files a/plugins/tasklist/skins/larry/sprites.png and b/plugins/tasklist/skins/larry/sprites.png differ
diff --git a/plugins/tasklist/skins/larry/tasklist.css b/plugins/tasklist/skins/larry/tasklist.css
index 246fea6..2b88c95 100644
--- a/plugins/tasklist/skins/larry/tasklist.css
+++ b/plugins/tasklist/skins/larry/tasklist.css
@@ -302,36 +302,54 @@ body.tasklist.attachmentwin #mainscreen {
 	background: url(sprites.png) right 20px no-repeat;
 }
 
-#tasklistsbox .treelist li a.quickview {
+#tasklistsbox .treelist div span.actions {
 	display: inline-block;
 	position: absolute;
-	top: 6px;
-	right: 24px;
+	top: 2px;
+	right: 2px;
+	padding: 5px 20px 0 6px;
+	min-width: 40px;
+	height: 19px;
+	text-align: right;
+}
+
+#tasklistsbox .treelist div:hover span.actions {
+	top: 1px;
+	right: 1px;
+	border: 1px solid #c6c6c6;
+	border-radius: 4px;
+	background: #f7f7f7;
+	background: -moz-linear-gradient(top, #f9f9f9 0%, #e6e6e6 100%);
+	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f9f9f9), color-stop(100%,#e6e6e6));
+	background: -o-linear-gradient(top, #f9f9f9 0%, #e6e6e6 100%);
+	background: -ms-linear-gradient(top, #f9f9f9 0%, #e6e6e6 100%);
+	background: linear-gradient(top, #f9f9f9 0%, #e6e6e6 100%);
+	filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f9f9f9', endColorstr='#e6e6e6', GradientType=0);
+}
+
+#tasklistsbox .treelist div a.remove,
+#tasklistsbox .treelist div a.quickview,
+#tasklistsbox .treelist div a.subscribed {
+	display: inline-block;
 	width: 16px;
 	height: 16px;
 	padding: 0;
+	margin-right: 4px;
 	background: url(sprites.png) -200px 0 no-repeat;
 	overflow: hidden;
 	text-indent: -5000px;
 	cursor: pointer;
 }
 
-#tasklistsbox .treelist li a.subscribed {
-	display: inline-block;
+#tasklistsbox .treelist div a.subscribed {
 	position: absolute;
-	top: 6px;
-	right: 5px;
-	height: 16px;
-	width: 16px;
-	padding: 0;
-	background: url(sprites.png) -100px 0 no-repeat;
-	overflow: hidden;
-	text-indent: -5000px;
-	cursor: pointer;
+	top: 5px;
+	right: 4px;
+	margin: 0;
 }
 
-#tasklistsbox .treelist div > a.subscribed:focus,
-#tasklistsbox .treelist div:hover > a.subscribed {
+#tasklistsbox .treelist div a.subscribed:focus,
+#tasklistsbox .treelist div:hover a.subscribed {
 	background-position: -2px -215px;
 }
 
@@ -339,20 +357,28 @@ body.tasklist.attachmentwin #mainscreen {
 	background-position: -20px -215px;
 }
 
-#tasklistsbox .treelist div > a.quickview:focus,
-#tasklistsbox .treelist li div:hover > a.quickview {
+#tasklistsbox .treelist div a.quickview:focus,
+#tasklistsbox .treelist div:hover a.quickview {
 	background-position: -20px -101px;
 	background-color: transparent !important;
 }
 
-#tasklistsbox .treelist li div.focusview > a.quickview {
+#tasklistsbox .treelist div a.remove:focus,
+#tasklistsbox .treelist div:hover a.remove {
+	background-position: -2px -371px;
+	background-color: transparent !important;
+}
+
+#tasklistsbox .treelist div.focusview a.quickview {
 	background-position: -2px -101px;
 }
 
-#tasklistsbox .searchresults .treelist li a.quickview {
+#tasklistsbox .searchresults .treelist div a.remove,
+#tasklistsbox .searchresults .treelist div a.quickview {
 	display: none;
 }
 
+#tasklistsbox .treelist div a.remove:focus,
 #tasklistsbox .treelist div a.quickview:focus,
 #tasklistsbox .treelist div a.subscribed:focus {
 	border-radius: 3px;
diff --git a/plugins/tasklist/tasklist.js b/plugins/tasklist/tasklist.js
index 7743b84..218b8db 100644
--- a/plugins/tasklist/tasklist.js
+++ b/plugins/tasklist/tasklist.js
@@ -166,6 +166,11 @@ function rcube_tasklist_ui(settings)
                 rcmail.http_post('tasklist', { action:'subscribe', l:{ id:p.id, active:list.active?1:0, permanent:list.subscribed?1:0 } });
             }
         });
+        tasklists_widget.addEventListener('remove', function(p) {
+            if (me.tasklists[p.id] && me.tasklists[p.id].removable) {
+                list_remove(p.id);
+            }
+        });
         tasklists_widget.addEventListener('insert-item', function(p) {
             var list = p.data;
             if (list && list.id && !list.virtual) {
diff --git a/plugins/tasklist/tasklist_ui.php b/plugins/tasklist/tasklist_ui.php
index 8d4170a..b7bb4d4 100644
--- a/plugins/tasklist/tasklist_ui.php
+++ b/plugins/tasklist/tasklist_ui.php
@@ -248,9 +248,12 @@ class tasklist_ui
             return html::div(join(' ', $classes),
                 html::span(array('class' => 'listname', 'title' => $title, 'id' => $label_id), $prop['listname'] ?: $prop['name']) .
                   ($prop['virtual'] ? '' :
-                    html::tag('input', array('type' => 'checkbox', 'name' => '_list[]', 'value' => $id, 'checked' => $prop['active'], 'aria-labelledby' => $label_id)) .
-                    html::a(array('href' => '#', 'class' => 'quickview', 'title' => $this->plugin->gettext('focusview'), 'role' => 'checkbox', 'aria-checked' => 'false'), ' ') .
-                    (isset($prop['subscribed']) ? html::a(array('href' => '#', 'class' => 'subscribed', 'title' => $this->plugin->gettext('tasklistsubscribe'), 'role' => 'checkbox', 'aria-checked' => $prop['subscribed'] ? 'true' : 'false'), ' ') : '')
+                      html::tag('input', array('type' => 'checkbox', 'name' => '_list[]', 'value' => $id, 'checked' => $prop['active'], 'aria-labelledby' => $label_id)) .
+                      html::span('actions', 
+                          ($prop['removable'] ? html::a(array('href' => '#', 'class' => 'remove', 'title' => $this->plugin->gettext('removelist')), ' ') : '') .
+                          html::a(array('href' => '#', 'class' => 'quickview', 'title' => $this->plugin->gettext('focusview'), 'role' => 'checkbox', 'aria-checked' => 'false'), ' ') .
+                          (isset($prop['subscribed']) ? html::a(array('href' => '#', 'class' => 'subscribed', 'title' => $this->plugin->gettext('tasklistsubscribe'), 'role' => 'checkbox', 'aria-checked' => $prop['subscribed'] ? 'true' : 'false'), ' ') : '')
+                      )
                 )
             );
         }


commit c3151bea8aaea994ba4cb98a95ee15eb64194ed5
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date:   Thu Sep 11 14:45:34 2014 +0200

    Add book-remove item to address book actions menu

diff --git a/plugins/kolab_addressbook/kolab_addressbook.php b/plugins/kolab_addressbook/kolab_addressbook.php
index 418eca3..421125b 100644
--- a/plugins/kolab_addressbook/kolab_addressbook.php
+++ b/plugins/kolab_addressbook/kolab_addressbook.php
@@ -164,6 +164,7 @@ class kolab_addressbook extends rcube_plugin
                 'group'    => $abook->get_namespace(),
                 'subscribed' => $abook->is_subscribed(),
                 'carddavurl' => $abook->get_carddav_url(),
+                'removable' => true,
                 'kolab'    => true,
             );
         }
diff --git a/plugins/kolab_addressbook/lib/kolab_addressbook_ui.php b/plugins/kolab_addressbook/lib/kolab_addressbook_ui.php
index 10d49f6..e8f7c03 100644
--- a/plugins/kolab_addressbook/lib/kolab_addressbook_ui.php
+++ b/plugins/kolab_addressbook/lib/kolab_addressbook_ui.php
@@ -60,7 +60,7 @@ class kolab_addressbook_ui
             }
 
             // Add actions on address books
-            $options = array('book-create', 'book-edit', 'book-delete');
+            $options = array('book-create', 'book-edit', 'book-delete', 'book-remove');
             $idx     = 0;
 
             if ($this->rc->config->get('kolab_addressbook_carddav_url')) {
diff --git a/plugins/kolab_addressbook/localization/en_US.inc b/plugins/kolab_addressbook/localization/en_US.inc
index ed9e367..b636d4d 100644
--- a/plugins/kolab_addressbook/localization/en_US.inc
+++ b/plugins/kolab_addressbook/localization/en_US.inc
@@ -30,6 +30,7 @@ $labels['settings'] = 'Settings';
 $labels['bookcreate'] = 'Create address book';
 $labels['bookedit'] = 'Edit address book';
 $labels['bookdelete'] = 'Delete address book';
+$labels['bookremove'] = 'Remove from list';
 $labels['bookproperties'] = 'Address book properties';
 $labels['bookname'] = 'Book name';
 $labels['parentbook'] = 'Superior book';


commit 109044c87ba861cd068e9ec70f355716bf10e0d9
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date:   Thu Sep 11 14:44:12 2014 +0200

    Add command to remove a Kolab address book from the list (-> unsubscribe); fix contextmenu for abooks and contact groups

diff --git a/plugins/kolab_addressbook/kolab_addressbook.js b/plugins/kolab_addressbook/kolab_addressbook.js
index b9edb42..c837030 100644
--- a/plugins/kolab_addressbook/kolab_addressbook.js
+++ b/plugins/kolab_addressbook/kolab_addressbook.js
@@ -107,6 +107,11 @@ if (window.rcmail) {
                         rcmail.http_post('plugin.book-subscribe', { _source:node.id, _permanent:source.subscribed?1:0 });
                     }
                 })
+                .addEventListener('remove', function(node) {
+                    if (rcmail.env.address_sources[node.id]) {
+                        rcmail.book_remove(node.id);
+                    }
+                })
                 .addEventListener('insert-item', function(data) {
                     // register new address source
                     rcmail.env.address_sources[data.id] = rcmail.env.contactfolders[data.id] = data.data;
@@ -131,11 +136,12 @@ if (window.rcmail) {
 // (De-)activates address book management commands
 rcube_webmail.prototype.set_book_actions = function()
 {
-    var source = this.env.source,
+    var source = !this.env.group ? this.env.source : null,
         sources = this.env.address_sources;
 
     this.enable_command('book-create', true);
     this.enable_command('book-edit', 'book-delete', source && sources[source] && sources[source].kolab && sources[source].editable);
+    this.enable_command('book-remove', source && sources[source] && sources[source].kolab && sources[source].removable);
     this.enable_command('book-showurl', source && sources[source] && sources[source].carddavurl);
 };
 
@@ -149,6 +155,15 @@ rcube_webmail.prototype.book_edit = function()
     this.book_show_contentframe('edit');
 };
 
+rcube_webmail.prototype.book_remove = function(id)
+{
+    if (!id) id = this.env.source;
+    if (id != '' && rcmail.env.address_sources[id]) {
+        rcmail.book_delete_done(id, true);
+        rcmail.http_post('plugin.book-subscribe', { _source:id, _permanent:0, _recursive:1 });
+    }
+};
+
 rcube_webmail.prototype.book_delete = function()
 {
     if (this.env.source != '' && confirm(this.get_label('kolab_addressbook.bookdeleteconfirm'))) {
@@ -343,7 +358,7 @@ function kolab_addressbook_contextmenu()
             menu_source: ['#directorylist-footer', '#groupoptionsmenu']
         }, {
             'activate': function(p) {
-                var source = rcmail.env.source,
+                var source = !rcmail.env.group ? rcmail.env.source : null,
                     sources = rcmail.env.address_sources;
 
                 if (p.command == 'book-create') {
@@ -354,10 +369,18 @@ function kolab_addressbook_contextmenu()
                     return !!(source && sources[source] && sources[source].kolab && sources[source].editable);
                 }
 
+                if (p.command == 'book-remove') {
+                    return !!(source && sources[source] && sources[source].kolab && sources[source].removable);
+                }
+
                 if (p.command == 'book-showurl') {
                     return !!(source && sources[source] && sources[source].carddavurl);
                 }
 
+                if (p.command == 'group-rename' || p.command == 'group-delete') {
+                    return !!(rcmail.env.group && sources[rcmail.env.source] && sources[rcmail.env.source].editable);
+                }
+
                 return false;
             },
             'beforeactivate': function(p) {
@@ -367,11 +390,16 @@ function kolab_addressbook_contextmenu()
                 rcmail.env.kolab_old_source = rcmail.env.source;
                 rcmail.env.kolab_old_group = rcmail.env.group;
 
-                var onclick = $(p.source).attr('onclick');
+                var elem = $(p.source), onclick = elem.attr('onclick');
                 if (onclick && onclick.match(rcmail.context_menu_command_pattern)) {
                     rcmail.env.source = RegExp.$2;
                     rcmail.env.group = null;
                 }
+                else if (elem.parent().hasClass('contactgroup')) {
+                    var grp = String(elem.attr('rel')).split(':');
+                    rcmail.env.source = grp[0];
+                    rcmail.env.group = grp[1];
+                }
             },
             'aftercommand': function(p) {
                 rcmail.env.source = rcmail.env.kolab_old_source;
@@ -380,7 +408,7 @@ function kolab_addressbook_contextmenu()
         }
     );
 
-    $('#directorylist div > a').off('contextmenu').on('contextmenu', function(e) {
+    $('#directorylist').off('contextmenu').on('contextmenu', 'div > a, li.contactgroup > a', function(e) {
         $(this).blur();
         rcm_show_menu(e, this, $(this).attr('rel'), menu);
     });




More information about the commits mailing list