diff --git a/program/js/app.js b/program/js/app.js index da7e7f920..c3012fc7b 100644 --- a/program/js/app.js +++ b/program/js/app.js @@ -47,6 +47,7 @@ function rcube_webmail() this.group2expand = {}; this.http_request_jobs = {}; this.menu_stack = []; + this.entity_selectors = []; // webmail client settings this.dblclick_time = 500; @@ -979,14 +980,14 @@ function rcube_webmail() if (this.task == 'mail') this.move_messages(props, event); else if (this.task == 'addressbook') - this.move_contacts(props); + this.move_contacts(props, event); break; case 'copy': if (this.task == 'mail') this.copy_messages(props, event); else if (this.task == 'addressbook') - this.copy_contacts(props); + this.copy_contacts(props, event); break; case 'mark': @@ -5903,10 +5904,15 @@ function rcube_webmail() } this.env.selection_sources = $.unique(this.env.selection_sources); + + var groupcount = 0; + if (source.groups) + $.each(this.env.contactgroups, function(){ if (this.source === ref.env.source) groupcount++ }); } // if a group is currently selected, and there is at least one contact selected // thend we can enable the group-remove-selected command + this.enable_command('group-assign-selected', groupcount > 0 && selected && writable); this.enable_command('group-remove-selected', this.env.group && selected && writable); this.enable_command('print', selected == 1); this.enable_command('export-selected', 'copy', selected > 0); @@ -5953,6 +5959,9 @@ function rcube_webmail() this.env.address_group_stack = index < 0 ? [] : this.env.address_group_stack.slice(0, index); + // remove cached contact group selector + this.destroy_entity_selector('contactgroup-selector'); + // make sure the current group is on top of the stack if (this.env.group) { if (!search) search = {}; @@ -6130,8 +6139,15 @@ function rcube_webmail() }; // copy contact(s) to the specified target (group or directory) - this.copy_contacts = function(to) + this.copy_contacts = function(to, event) { + if (!to) { + return this.addressbook_selector(event, function(to, obj) { + var to = $(obj).data('source') ? ref.env.contactgroups['G' + $(obj).data('source') + $(obj).data('gid')] : ref.env.address_sources[to]; + ref.command('copy', to); + }); + } + var dest = to.type == 'group' ? to.source : to.id, source = this.env.source, group = this.env.group ? this.env.group : '', @@ -6164,8 +6180,15 @@ function rcube_webmail() }; // move contact(s) to the specified target (group or directory) - this.move_contacts = function(to) + this.move_contacts = function(to, event) { + if (!to) { + return this.addressbook_selector(event, function(to, obj) { + var to = $(obj).data('source') ? ref.env.contactgroups['G' + $(obj).data('source') + $(obj).data('gid')] : ref.env.address_sources[to]; + ref.command('move', to); + }); + } + var dest = to.type == 'group' ? to.source : to.id, source = this.env.source, group = this.env.group ? this.env.group : ''; @@ -6392,6 +6415,10 @@ function rcube_webmail() var key = 'G'+prop.source+prop.id; if (this.treelist.remove(key)) { + // make sure there is no cached address book or contact group selectors + this.destroy_entity_selector('addressbook-selector'); + this.destroy_entity_selector('contactgroup-selector'); + this.triggerEvent('group_delete', { source:prop.source, id:prop.id }); delete this.env.contactfolders[key]; delete this.env.contactgroups[key]; @@ -6401,6 +6428,12 @@ function rcube_webmail() this.list_contacts(prop.source, 0); }; + //assign selected contacts to a group + this.group_assign_selected = function(props, obj, event) + { + this.contactgroup_selector(event, function(to) { ref.group_member_change('add', ref.contact_list.get_selection(), ref.env.source, to); }); + }; + //remove selected contacts from current active group this.group_remove_selected = function() { @@ -6416,6 +6449,7 @@ function rcube_webmail() for (n=0; n'); - if (!container) { - var rows = [], - delim = this.env.delimiter, - ul = $(' +
+ +
+
@@ -107,7 +120,6 @@
  • -
  • diff --git a/skins/larry/addressbook.css b/skins/larry/addressbook.css index da4ef193f..4f5d385ee 100644 --- a/skins/larry/addressbook.css +++ b/skins/larry/addressbook.css @@ -403,3 +403,37 @@ a.deletebutton { #import-box .propform { max-width: 50em; } + +ul.toolbarmenu li span.assigngroup { + background-position: 0 -2358px; +} + +ul.toolbarmenu li span.removegroup { + background-position: 0 -2384px; +} + +#addressbook-selector li a, +#contactgroup-selector li a { + padding-left: 2px; +} + +#addressbook-selector li a span, +#contactgroup-selector li a span { + background: url(images/listicons.png) 4px 20px no-repeat; + display: block; + height: 17px; + min-height: 14px; + padding: 4px 4px 1px 28px; + overflow: hidden; + max-width: 120px; + text-overflow: ellipsis; +} + +#addressbook-selector li a.addressbook span { + background-position: 4px -2222px; +} + +#addressbook-selector li a.contactgroup span, +#contactgroup-selector li a.contactgroup span { + background-position: 4px -2245px; +} diff --git a/skins/larry/images/listicons.png b/skins/larry/images/listicons.png index 29b382653..8995af19b 100644 Binary files a/skins/larry/images/listicons.png and b/skins/larry/images/listicons.png differ diff --git a/skins/larry/templates/addressbook.html b/skins/larry/templates/addressbook.html index 1968d1ead..4b1b03653 100644 --- a/skins/larry/templates/addressbook.html +++ b/skins/larry/templates/addressbook.html @@ -26,6 +26,7 @@ +
+
@@ -103,7 +116,7 @@
- +