From 1ba07f070998d32d115d90d0d73db2dca59c4690 Mon Sep 17 00:00:00 2001
From: thomascube <thomas@roundcube.net>
Date: Wed, 11 Apr 2012 08:52:51 -0400
Subject: [PATCH] Allow mass-removal of addresses from a group (#1487748)

---
 CHANGELOG                                |    3 ++-
 skins/larry/templates/addressbook.html   |    2 +-
 program/localization/de_CH/labels.inc    |    1 +
 skins/larry/addressbook.css              |    4 ++--
 program/localization/de_DE/labels.inc    |    1 +
 skins/larry/images/buttons.gif           |    0 
 program/steps/addressbook/groups.inc     |    6 ++++--
 program/localization/en_US/labels.inc    |    1 +
 skins/default/templates/addressbook.html |    1 +
 skins/larry/styles.css                   |    6 +++++-
 skins/larry/images/buttons.png           |    0 
 program/js/app.js                        |   26 ++++++++++++++++++++++++++
 skins/larry/mail.css                     |    4 ++--
 skins/larry/ui.js                        |    2 +-
 14 files changed, 47 insertions(+), 10 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 31ab964..17375a4 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,7 +1,8 @@
 CHANGELOG Roundcube Webmail
 ===========================
 
-- Fix removing all folders on import to LDAP addressbook
+- Allow mass-removal of addresses from a group (#1487748)
+- Fix removing all contacts on import to LDAP addressbook
 - Fix so "Back" from compose/show doesn't reset search request (#1488238)
 - Add option to delete messages instead of moving to Trash when in Junk folder (#1486686)
 - Fix invisible cursor when replying to a html message (#1487073)
diff --git a/program/js/app.js b/program/js/app.js
index 025a366..963049b 100644
--- a/program/js/app.js
+++ b/program/js/app.js
@@ -4016,6 +4016,10 @@
       }
     }
 
+    // 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-remove-selected', typeof this.env.group != 'undefined' && list.selection.length > 0);
+
     this.enable_command('compose', this.env.group || list.selection.length > 0);
     this.enable_command('edit', id && writable);
     this.enable_command('delete', list.selection.length && writable);
@@ -4375,6 +4379,28 @@
     this.name_input.select().focus();
   };
 
+  //remove selected contacts from current active group
+  this.group_remove_selected = function()
+  {
+    ref.http_post('group-delmembers','_cid='+urlencode(this.contact_list.selection)
+		  + '&_source='+urlencode(this.env.source)
+		  + '&_gid='+urlencode(this.env.group));
+  };
+
+  //callback after deleting contact(s) from current group
+  this.remove_group_contacts = function(props)
+  {
+    if('undefined' != typeof this.env.group && (this.env.group === props.gid)){
+      var selection = this.contact_list.get_selection();
+      for (var n=0; n<selection.length; n++) {
+	id = selection[n];
+	this.contact_list.remove_row(id, (n == selection.length-1));
+      }
+    }
+  }
+
+
+
   // handler for keyboard events on the input field
   this.add_input_keydown = function(e)
   {
diff --git a/program/localization/de_CH/labels.inc b/program/localization/de_CH/labels.inc
index 792fb8d..7ff3ae7 100644
--- a/program/localization/de_CH/labels.inc
+++ b/program/localization/de_CH/labels.inc
@@ -284,6 +284,7 @@
 $labels['newcontactgroup'] = 'Neue Adressgruppe erstellen';
 $labels['grouprename'] = 'Gruppe umbenennen';
 $labels['groupdelete'] = 'Gruppe löschen';
+$labels['groupremoveselected'] = 'Gewählte Kontakte aus Gruppe entfernen';
 $labels['previouspage'] = 'Eine Seite zurück';
 $labels['firstpage'] = 'Erste Seite';
 $labels['nextpage'] = 'Nächste Seite';
diff --git a/program/localization/de_DE/labels.inc b/program/localization/de_DE/labels.inc
index bb90aed..470af7d 100644
--- a/program/localization/de_DE/labels.inc
+++ b/program/localization/de_DE/labels.inc
@@ -284,6 +284,7 @@
 $labels['newcontactgroup'] = 'Neue Kontaktgruppe erstellen';
 $labels['grouprename'] = 'Gruppe umbenennen';
 $labels['groupdelete'] = 'Gruppe löschen';
+$labels['groupremoveselected'] = 'Gewählte Kontakte aus Gruppe entfernen';
 $labels['previouspage'] = 'Seite zurück';
 $labels['firstpage'] = 'Erste Seite';
 $labels['nextpage'] = 'Nächste Seite';
diff --git a/program/localization/en_US/labels.inc b/program/localization/en_US/labels.inc
index 4c71208..277f1a9 100644
--- a/program/localization/en_US/labels.inc
+++ b/program/localization/en_US/labels.inc
@@ -334,6 +334,7 @@
 $labels['newcontactgroup'] = 'Create new contact group';
 $labels['grouprename']    = 'Rename group';
 $labels['groupdelete']    = 'Delete group';
+$labels['groupremoveselected'] = 'Remove selected contacts from group';
 
 $labels['previouspage']   = 'Show previous page';
 $labels['firstpage']      = 'Show first page';
diff --git a/program/steps/addressbook/groups.inc b/program/steps/addressbook/groups.inc
index 415cd07..3bdd89f 100644
--- a/program/steps/addressbook/groups.inc
+++ b/program/steps/addressbook/groups.inc
@@ -64,10 +64,12 @@
     else
       $result = $plugin['result'];
 
-    if ($result)
+    if ($result){
       $OUTPUT->show_message('contactremovedfromgroup');
-    else
+      $OUTPUT->command('remove_group_contacts',array('source' => $source, 'gid' => $gid));
+    }else{
       $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'errorsaving', 'error');
+    }
   }
 }
 
diff --git a/skins/default/templates/addressbook.html b/skins/default/templates/addressbook.html
index 4cab511..d8b7a3a 100644
--- a/skins/default/templates/addressbook.html
+++ b/skins/default/templates/addressbook.html
@@ -99,6 +99,7 @@
   <ul>
     <li><roundcube:button command="group-rename" label="grouprename" classAct="active" /></li>
     <li><roundcube:button command="group-delete" label="groupdelete" classAct="active" /></li>
+    <li><roundcube:button command="group-remove-selected" label="group-remove-selected" classAct="active" /></li>
     <li class="separator_above"><roundcube:button command="search-create" label="searchsave" classAct="active" /></li>
     <li><roundcube:button command="search-delete" label="searchdelete" classAct="active" /></li>
     <roundcube:container name="groupoptions" id="groupoptionsmenu" />
diff --git a/skins/larry/addressbook.css b/skins/larry/addressbook.css
index 4ad6d34..5181c22 100644
--- a/skins/larry/addressbook.css
+++ b/skins/larry/addressbook.css
@@ -49,14 +49,14 @@
 	position: absolute;
 	top: 42px;
 	left: 0;
-	width: 260px;
+	width: 280px;
 	bottom: 0;
 }
 
 #contacts-box {
 	position: absolute;
 	top: 42px;
-	left: 272px;
+	left: 292px;
 	right: 0;
 	bottom: 0;
 }
diff --git a/skins/larry/images/buttons.gif b/skins/larry/images/buttons.gif
index d597065..f73e093 100644
--- a/skins/larry/images/buttons.gif
+++ b/skins/larry/images/buttons.gif
Binary files differ
diff --git a/skins/larry/images/buttons.png b/skins/larry/images/buttons.png
index cbd2bd8..0e395ab 100644
--- a/skins/larry/images/buttons.png
+++ b/skins/larry/images/buttons.png
Binary files differ
diff --git a/skins/larry/mail.css b/skins/larry/mail.css
index 1310c30..8573895 100644
--- a/skins/larry/mail.css
+++ b/skins/larry/mail.css
@@ -748,11 +748,11 @@
 div.more-headers {
 	cursor: pointer;
 	height: 10px;
-	background: url(images/buttons.png) center -1539px no-repeat;
+	background: url(images/buttons.png) center -1579px no-repeat;
 }
 
 div.hide-headers {
-	background-position: center -1549px;
+	background-position: center -1589px;
 }
 
 #all-headers {
diff --git a/skins/larry/styles.css b/skins/larry/styles.css
index c61a3f3..1511d43 100644
--- a/skins/larry/styles.css
+++ b/skins/larry/styles.css
@@ -860,6 +860,10 @@
 	background-position: 2px -1502px;
 }
 
+.boxfooter .listbutton.removegroup .inner {
+	background-position: 5px -1540px;
+}
+
 .boxfooter .listbutton.disabled .inner {
 	opacity: 0.4;
 	filter: alpha(opacity=40);
@@ -1411,7 +1415,7 @@
 }
 
 .toolbar a.button.spellcheck.selected {
-	background-position: left -1570px;
+	background-position: left -1610px;
 	color: #1978a1;
 }
 
diff --git a/skins/larry/templates/addressbook.html b/skins/larry/templates/addressbook.html
index 522f321..ea11e61 100644
--- a/skins/larry/templates/addressbook.html
+++ b/skins/larry/templates/addressbook.html
@@ -50,7 +50,7 @@
 <roundcube:object name="addresslist" id="contacts-table" class="listing" noheader="true" />
 </div>
 <div class="boxfooter">
-	<roundcube:button command="add" type="link" title="newcontact" class="listbutton add disabled" classAct="listbutton add" innerClass="inner" content="+" /><roundcube:button command="delete" type="link" title="deletecontact" class="listbutton delete disabled" classAct="listbutton delete" innerClass="inner" content="x" />
+	<roundcube:button command="add" type="link" title="newcontact" class="listbutton add disabled" classAct="listbutton add" innerClass="inner" content="+" /><roundcube:button command="delete" type="link" title="deletecontact" class="listbutton delete disabled" classAct="listbutton delete" innerClass="inner" content="x" /><roundcube:button command="group-remove-selected" type="link" title="groupremoveselected"  class="listbutton removegroup disabled" classAct="listbutton removegroup" innerClass="inner" content="-" />
 	<roundcube:object name="recordsCountDisplay" class="countdisplay" label="fromtoshort" />
 </div>
 <div class="boxpagenav">
diff --git a/skins/larry/ui.js b/skins/larry/ui.js
index 89c7ba0..dda5abd 100644
--- a/skins/larry/ui.js
+++ b/skins/larry/ui.js
@@ -155,7 +155,7 @@
         new rcube_splitter({ id:'addressviewsplitterd', p1:'#addressview-left', p2:'#addressview-right',
           orientation:'v', relative:true, start:226, min:150, size:12, render:resize_leftcol }).init();
         new rcube_splitter({ id:'addressviewsplitter', p1:'#addresslist', p2:'#contacts-box',
-          orientation:'v', relative:true, start:266, min:220, size:12 }).init();
+          orientation:'v', relative:true, start:286, min:270, size:12 }).init();
 
         new rcube_scroller('#directorylist-content', '#directorylist-header', '#directorylist-footer');
       }

--
Gitblit v1.9.1