From 6c5c22b877f6a91b4046433e13588cd3c679dc3f Mon Sep 17 00:00:00 2001
From: Aleksander Machniak <alec@alec.pl>
Date: Sat, 26 Jul 2014 03:54:11 -0400
Subject: [PATCH] Create/rename groups in UI dialogs (#1489951)

---
 CHANGELOG                          |    1 
 program/steps/addressbook/func.inc |    4 
 skins/classic/common.css           |    6 +
 skins/larry/styles.css             |    4 +
 program/js/app.js                  |  179 +++++++++++++++++---------------------------
 5 files changed, 81 insertions(+), 113 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 125d045..6ca2847 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,7 @@
 CHANGELOG Roundcube Webmail
 ===========================
 
+- Create/rename groups in UI dialogs (#1489951)
 - Added 'contact_search_name' option to define autocompletion entry format
 - Display quota information for current folder not INBOX only (#1487993)
 - Support images in HTML signatures (#1488676)
diff --git a/program/js/app.js b/program/js/app.js
index f25b808..28df384 100644
--- a/program/js/app.js
+++ b/program/js/app.js
@@ -5156,29 +5156,55 @@
         .submit(function() { $('input.mainaction').click(); return false; });
   };
 
+  // group creation dialog
   this.group_create = function()
   {
-    this.add_input_row('contactgroup');
+    var input = $('<input>').attr('type', 'text'),
+      content = $('<label>').text(this.get_label('namex')).append(input);
+
+    this.show_popup_dialog(content, this.get_label('newgroup'),
+      [{
+        text: this.get_label('save'),
+        click: function() {
+          var name;
+
+          if (name = input.val()) {
+            ref.http_post('group-create', {_source: ref.env.source, _name: name},
+              ref.set_busy(true, 'loading'));
+          }
+
+          $(this).dialog('close');
+        }
+      }]
+    );
   };
 
+  // group rename dialog
   this.group_rename = function()
   {
-    if (!this.env.group || !this.gui_objects.folderlist)
+    if (!this.env.group)
       return;
 
-    if (!this.name_input) {
-      this.enable_command('list', 'listgroup', false);
-      this.name_input = $('<input>').attr('type', 'text').val(this.env.contactgroups['G'+this.env.source+this.env.group].name);
-      this.name_input.bind('keydown', function(e) { return ref.add_input_keydown(e); });
-      this.env.group_renaming = true;
+    var group_name = this.env.contactgroups['G' + this.env.source + this.env.group].name,
+      input = $('<input>').attr('type', 'text').val(group_name),
+      content = $('<label>').text(this.get_label('namex')).append(input);
 
-      var link, li = this.get_folder_li('G'+this.env.source+this.env.group,'',true);
-      if (li && (link = li.firstChild)) {
-        $(link).hide().before(this.name_input);
-      }
-    }
+    this.show_popup_dialog(content, this.get_label('grouprename'),
+      [{
+        text: this.get_label('save'),
+        click: function() {
+          var name;
 
-    this.name_input.select().focus();
+          if ((name = input.val()) && name != group_name) {
+            ref.http_post('group-rename', {_source: ref.env.source, _gid: ref.env.group, _name: name},
+              ref.set_busy(true, 'loading'));
+          }
+
+          $(this).dialog('close');
+        }
+      }],
+      {open: function() { input.select(); }}
+    );
   };
 
   this.group_delete = function()
@@ -5203,38 +5229,6 @@
     this.list_contacts(prop.source, 0);
   };
 
-  // @TODO: maybe it would be better to use popup instead of inserting input to the list?
-  this.add_input_row = function(type)
-  {
-    if (!this.gui_objects.folderlist)
-      return;
-
-    if (!this.name_input) {
-      this.name_input = $('<input>').attr('type', 'text').data('tt', type);
-      this.name_input.bind('keydown', function(e) { return ref.add_input_keydown(e); });
-      this.name_input_li = $('<li>').addClass(type).append(this.name_input);
-
-      var ul, li;
-
-      // find list (UL) element
-      if (type == 'contactsearch')
-        ul = this.gui_objects.savedsearchlist;
-      else
-        ul = $('ul.groups', this.get_folder_li(this.env.source,'',true));
-
-      // append to the list
-      li = $('li:last', ul);
-      if (li.length)
-        this.name_input_li.insertAfter(li);
-      else {
-        this.name_input_li.appendTo(ul);
-        ul.show(); // make sure the list is visible
-      }
-    }
-
-    this.name_input.select().focus();
-  };
-
   //remove selected contacts from current active group
   this.group_remove_selected = function()
   {
@@ -5254,62 +5248,9 @@
     }
   };
 
-  // handler for keyboard events on the input field
-  this.add_input_keydown = function(e)
-  {
-    var key = rcube_event.get_keycode(e),
-      input = $(e.target), itype = input.data('tt');
-
-    // enter
-    if (key == 13) {
-      var newname = input.val();
-
-      if (newname) {
-        var lock = this.set_busy(true, 'loading');
-
-        if (itype == 'contactsearch')
-          this.http_post('search-create', {_search: this.env.search_request, _name: newname}, lock);
-        else if (this.env.group_renaming)
-          this.http_post('group-rename', {_source: this.env.source, _gid: this.env.group, _name: newname}, lock);
-        else
-          this.http_post('group-create', {_source: this.env.source, _name: newname}, lock);
-      }
-      return false;
-    }
-    // escape
-    else if (key == 27)
-      this.reset_add_input();
-
-    return true;
-  };
-
-  this.reset_add_input = function()
-  {
-    if (this.name_input) {
-      var li = this.name_input.parent();
-      if (this.env.group_renaming) {
-        li.children().last().show();
-        this.env.group_renaming = false;
-      }
-      else if ($('li', li.parent()).length == 1)
-        li.parent().hide();
-
-      this.name_input.remove();
-
-      if (this.name_input_li)
-        this.name_input_li.remove();
-
-      this.name_input = this.name_input_li = null;
-    }
-
-    this.enable_command('list', 'listgroup', true);
-  };
-
   // callback for creating a new contact group
   this.insert_contact_group = function(prop)
   {
-    this.reset_add_input();
-
     prop.type = 'group';
 
     var key = 'G'+prop.source+prop.id,
@@ -5327,8 +5268,6 @@
   // callback for renaming a contact group
   this.update_contact_group = function(prop)
   {
-    this.reset_add_input();
-
     var key = 'G'+prop.source+prop.id,
       newnode = {};
 
@@ -5592,8 +5531,6 @@
   // callback for creating a new saved search record
   this.insert_saved_search = function(name, id)
   {
-    this.reset_add_input();
-
     var key = 'S'+id,
       link = $('<a>').attr('href', '#')
         .attr('rel', id)
@@ -5609,10 +5546,27 @@
     this.triggerEvent('abook_search_insert', prop);
   };
 
-  // creates an input for saved search name
+  // creates a dialog for saved search
   this.search_create = function()
   {
-    this.add_input_row('contactsearch');
+    var input = $('<input>').attr('type', 'text'),
+      content = $('<label>').text(this.get_label('namex')).append(input);
+
+    this.show_popup_dialog(content, this.get_label('searchsave'),
+      [{
+        text: this.get_label('save'),
+        click: function() {
+          var name;
+
+          if (name = input.val()) {
+            ref.http_post('search-create', {_search: ref.env.search_request, _name: name},
+              ref.set_busy(true, 'loading'));
+          }
+
+          $(this).dialog('close');
+        }
+      }]
+    );
   };
 
   this.search_delete = function()
@@ -6470,22 +6424,27 @@
   };
 
   // open a jquery UI dialog with the given content
-  this.show_popup_dialog = function(html, title, buttons, options)
+  this.show_popup_dialog = function(content, title, buttons, options)
   {
     // forward call to parent window
     if (this.is_framed()) {
-      return parent.rcmail.show_popup_dialog(html, title, buttons, options);
+      return parent.rcmail.show_popup_dialog(content, title, buttons, options);
     }
 
-    var popup = $('<div class="popup">')
-      .html(html)
-      .dialog($.extend({
+    var popup = $('<div class="popup">');
+
+    if (typeof content == 'object')
+      popup.append(content);
+    else
+      popup.html(html);
+
+    popup.dialog($.extend({
         title: title,
         buttons: buttons,
         modal: true,
         resizable: true,
         width: 500,
-        close: function(event, ui) { $(this).remove() }
+        close: function(event, ui) { $(this).remove(); }
       }, options || {}));
 
     // resize and center popup
diff --git a/program/steps/addressbook/func.inc b/program/steps/addressbook/func.inc
index f09deeb..f56e071 100644
--- a/program/steps/addressbook/func.inc
+++ b/program/steps/addressbook/func.inc
@@ -257,7 +257,9 @@
     $OUTPUT->include_script('treelist.js');
 
     // add some labels to client
-    $OUTPUT->add_label('deletegroupconfirm', 'groupdeleting', 'addingmember', 'removingmember');
+    $OUTPUT->add_label('deletegroupconfirm', 'groupdeleting', 'addingmember', 'removingmember',
+        'newgroup', 'grouprename', 'searchsave', 'namex'
+    );
 
     return html::tag('ul', $attrib, $out, html::$common_attrib);
 }
diff --git a/skins/classic/common.css b/skins/classic/common.css
index c50d1c7..74de5e4 100644
--- a/skins/classic/common.css
+++ b/skins/classic/common.css
@@ -617,6 +617,9 @@
   height: 16px;
 }
 
+.popup label > input {
+  margin-left: 10px;
+}
 
 /***** common table settings ******/
 
@@ -643,7 +646,7 @@
   border-bottom: 1px solid #EBEBEB;
   overflow: hidden;
   text-align: left;
-	outline: none;
+  outline: none;
 }
 
 table.records-table tr
@@ -701,7 +704,6 @@
 {
   background: url(images/icons/expanded.png) bottom right no-repeat;
 }
-
 
 ul.treelist,
 ul.treelist li ul
diff --git a/skins/larry/styles.css b/skins/larry/styles.css
index 5b76a4f..720b21e 100644
--- a/skins/larry/styles.css
+++ b/skins/larry/styles.css
@@ -2569,6 +2569,10 @@
 	z-index: 255;
 }
 
+.popup label > input {
+	margin-left: 10px;
+}
+
 /*** folder selector ***/
 
 #folder-selector {

--
Gitblit v1.9.1