diff --git a/plugins/calendar/calendar_ui.js b/plugins/calendar/calendar_ui.js index ef409380..381e7e8b 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 26936423..f80cce1f 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 6023366e..76fbceec 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 e33f01ad..54e0141d 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 li div.focusview > a.quickview { - background-position: -18px -128px; +#calendars .treelist div a.remove:focus, +#calendars .treelist div:hover a.remove { + background-position: -16px -168px; + background-color: transparent !important; +} + +#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 88eba63f..17e259ae 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 1df1748d..72e86c79 100644 --- a/plugins/calendar/skins/larry/templates/calendar.html +++ b/plugins/calendar/skins/larry/templates/calendar.html @@ -71,7 +71,7 @@
  • -
  • +
  • diff --git a/plugins/kolab_addressbook/skins/larry/folder_icons.png b/plugins/kolab_addressbook/skins/larry/folder_icons.png index 07674ab0..b9c59b5a 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 8aeb0cb5..5484807e 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 527e89bf..817a228e 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 21e6e1a7..939946ca 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 5f514c14..911e8a7c 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 b5efa37f..24daa9d5 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 ceead250..99ac3a24 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 617dc450..62a60ef2 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 288bd711..72759959 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 '; diff --git a/plugins/tasklist/skins/larry/sprites.png b/plugins/tasklist/skins/larry/sprites.png index fecbd589..36b48f53 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 246fea60..2b88c954 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 7743b847..218b8db0 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 8d4170af..b7bb4d43 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'), ' ') : '') + ) ) ); }