Bug 562266 - "Apply columns to..." should honor special folders. r=aceman, ui-r=Paenglab a=jorgk
authorsquib
Wed, 25 May 2016 19:37:08 +0200
changeset 24906 48057fe33922cfeee008fdc2395da001ae1531e9
parent 24905 d76850acd5981bb362d6fe1c01b393d0fc9064ff
child 24907 a6ed57f2c0e11d7ec287f2312c913b0375404db5
push id1657
push userclokep@gmail.com
push dateMon, 06 Jun 2016 19:50:21 +0000
treeherdercomm-beta@9fac989284b5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaceman, Paenglab, jorgk
bugs562266
Bug 562266 - "Apply columns to..." should honor special folders. r=aceman, ui-r=Paenglab a=jorgk
mail/base/content/threadPaneColumnPicker.xml
mail/base/modules/MailUtils.js
mail/test/mozmill/folder-display/test-columns.js
--- a/mail/base/content/threadPaneColumnPicker.xml
+++ b/mail/base/content/threadPaneColumnPicker.xml
@@ -138,36 +138,61 @@
           return parent == yesChildrenPopup;
         ]]></body>
       </method>
 
       <method name="_applyColumns">
         <parameter name="aDestFolder"/>
         <parameter name="aUseChildren"/>
         <body><![CDATA[
-          // Get the current folder's column state.
-          let propName = gFolderDisplay.PERSISTED_COLUMN_PROPERTY_NAME;
-          let dbFolderInfo = gFolderDisplay.displayedFolder.msgDatabase
-                                           .dBFolderInfo;
-          let columnStateString = dbFolderInfo.getCharProperty(propName);
+          // Get the current folder's column state, plus the "swapped" column
+          // state, which swaps "From" and "Recipient" if only one is shown.
+          // This is useful for copying an incoming folder's columns to an
+          // outgoing folder, or vice versa.
+          let colState = gFolderDisplay.getColumnStates();
+
+          let myColStateString = JSON.stringify(colState);
+          let swappedColStateString;
+          if (colState.senderCol.visible != colState.recipientCol.visible) {
+            let tmp = colState.senderCol;
+            colState.senderCol = colState.recipientCol;
+            colState.recipientCol = tmp;
+            swappedColStateString = JSON.stringify(colState);
+          } else {
+            swappedColStateString = myColStateString;
+          }
+
+          function isOutgoing(folder) {
+            return folder.isSpecialFolder(
+              DBViewWrapper.prototype.OUTGOING_FOLDER_FLAGS, true
+            );
+          }
+
+          let amIOutgoing = isOutgoing(gFolderDisplay.displayedFolder);
+          function colStateString(folder) {
+            return (isOutgoing(folder) == amIOutgoing ? myColStateString :
+                    swappedColStateString);
+          }
 
           // Now propagate appropriately...
+          const propName = gFolderDisplay.PERSISTED_COLUMN_PROPERTY_NAME;
           if (aUseChildren) {
             // Generate an observer notification when we have finished
             // configuring all folders.  This is currently done for the benefit
             // of our mozmill tests.
             let observerCallback = function() {
               Services.obs.notifyObservers(gFolderDisplay.displayedFolder,
                                            "msg-folder-columns-propagated", "");
             };
             MailUtils.setStringPropertyOnFolderAndDescendents(
-              propName, columnStateString, aDestFolder, observerCallback
+              propName, colStateString, aDestFolder, observerCallback
             );
           } else {
-            aDestFolder.setStringProperty(propName, columnStateString);
+            aDestFolder.setStringProperty(propName,
+                                          colStateString(aDestFolder));
             // null out to avoid memory bloat
             aDestFolder.msgDatabase = null;
           }
         ]]></body>
       </method>
     </implementation>
     <handlers>
       <handler event="command"><![CDATA[
--- a/mail/base/modules/MailUtils.js
+++ b/mail/base/modules/MailUtils.js
@@ -326,16 +326,18 @@ var MailUtils =
    * the nsIMsgDatabase and then the nsIDbFolderInfo.  You would want to avoid
    * that as much as possible because once those are exposed to you, XPConnect
    * is going to hold onto them creating a situation where you are going to be
    * in severe danger of extreme memory bloat unless you force garbage
    * collections after every time you close a database.
    *
    * @param aPropertyName The name of the property to set.
    * @param aPropertyValue The (string) value of the property to set.
+   *     Alternately, you can pass a function that takes the nsIMsgFolder and
+   *     returns a string value.
    * @param aFolder The parent folder; we set the string property on it and all
    *     of its descendents.
    * @param [aCallback] The optional callback to invoke once we finish our work.
    *     The callback is provided a boolean success value; true means we
    *     managed to set the values on all folders, false means we encountered a
    *     problem.
    */
   setStringPropertyOnFolderAndDescendents:
@@ -347,17 +349,19 @@ var MailUtils =
     let allFolders = toXPCOMArray([aFolder], Ci.nsIMutableArray);
     // - get all the descendants
     aFolder.ListDescendants(allFolders);
 
     // - worker function
     function folder_string_setter_worker() {
       for (let folder in fixIterator(allFolders, Ci.nsIMsgFolder)) {
         // set the property; this may open the database...
-        folder.setStringProperty(aPropertyName, aPropertyValue);
+        let value = (typeof aPropertyValue == "function" ?
+                     aPropertyValue(folder) : aPropertyValue);
+        folder.setStringProperty(aPropertyName, value);
         // force the reference to be forgotten.
         folder.msgDatabase = null;
         yield undefined;
       }
     }
     let worker = folder_string_setter_worker();
 
     // - driver logic
--- a/mail/test/mozmill/folder-display/test-columns.js
+++ b/mail/test/mozmill/folder-display/test-columns.js
@@ -380,27 +380,27 @@ function test_reset_to_inbox() {
   // reset!
   invoke_column_picker_option([{anonid: "reset"}]);
 }
 
 function subtest_say_yes(cwc) {
   cwc.window.document.documentElement.getButton('accept').doCommand();
 }
 
-function _apply_to_folder_common(aChildrenToo) {
+function _apply_to_folder_common(aChildrenToo, folder) {
   if (aChildrenToo)
     plan_for_observable_event("msg-folder-columns-propagated");
   plan_for_modal_dialog("commonDialog", subtest_say_yes);
   invoke_column_picker_option([{anonid: "applyTo-menu"},
                                {anonid: aChildrenToo ?
                                   "applyToFolderAndChildren-menu" :
                                   "applyToFolder-menu"},
                                {label: "Local Folders"},
-                               {label: "ColumnsApplyParent"},
-                               {label: "ColumnsApplyParent"}]);
+                               {label: folder.name},
+                               {label: folder.name}]);
   wait_for_modal_dialog("commonDialog");
   if (aChildrenToo)
     wait_for_observable_event("msg-folder-columns-propagated");
 }
 
 /**
  * Change settings in a folder, apply them to another folder that also has
  *  children.  Make sure the folder changes but the children do not.
@@ -418,17 +418,17 @@ function test_apply_to_folder_no_childre
   invoke_column_picker_option([{anonid: "reset"}]);
 
   // permute!
   let conExtra = INBOX_DEFAULTS.concat(["sizeCol"]);
   show_column("sizeCol");
   assert_visible_columns(conExtra);
 
   // apply to the one dude
-  _apply_to_folder_common(false);
+  _apply_to_folder_common(false, folderParent);
 
   // make sure it copied to the parent
   be_in_folder(folderParent);
   assert_visible_columns(conExtra);
 
   // but not the children
   be_in_folder(folderChild1);
   assert_visible_columns(INBOX_DEFAULTS);
@@ -450,29 +450,105 @@ function test_apply_to_folder_and_childr
   invoke_column_picker_option([{anonid: "reset"}]);
 
   // permute!
   let conExtra = INBOX_DEFAULTS.concat(["tagsCol"]);
   show_column("tagsCol");
   assert_visible_columns(conExtra);
 
   // apply to the dude and his offspring
-  _apply_to_folder_common(true);
+  _apply_to_folder_common(true, folderParent);
 
   // make sure it copied to the parent and his children
   be_in_folder(folderParent);
   assert_visible_columns(conExtra);
   be_in_folder(folderChild1);
   assert_visible_columns(conExtra);
   be_in_folder(folderChild2);
   assert_visible_columns(conExtra);
 }
 test_apply_to_folder_and_children.EXCLUDED_PLATFORMS = ["linux"];
 
 /**
+ * Change settings in an incoming folder, apply them to an outgoing folder that
+ * also has children. Make sure the folder changes but the children do not.
+ */
+function test_apply_to_folder_no_children_swapped() {
+  folderParent = create_folder("ColumnsApplyParentOutgoing");
+  folderParent.setFlag(Ci.nsMsgFolderFlags.SentMail);
+  folderParent.createSubfolder("Child1", null);
+  folderChild1 = folderParent.getChildNamed("Child1");
+  folderParent.createSubfolder("Child2", null);
+  folderChild2 = folderParent.getChildNamed("Child2");
+
+  be_in_folder(folderSource);
+
+  // reset!
+  invoke_column_picker_option([{anonid: "reset"}]);
+
+  // permute!
+  let conExtra = [...INBOX_DEFAULTS];
+  conExtra[5] = "senderCol";
+  hide_column("correspondentCol");
+  show_column("senderCol");
+  assert_visible_columns(conExtra);
+
+  // Apply to the one dude.
+  _apply_to_folder_common(false, folderParent);
+
+  // Make sure it copied to the parent.
+  let conExtraSwapped = [...INBOX_DEFAULTS];
+  conExtraSwapped[5] = "recipientCol";
+  be_in_folder(folderParent);
+  assert_visible_columns(conExtraSwapped);
+
+  // But not the children.
+  be_in_folder(folderChild1);
+  assert_visible_columns(INBOX_DEFAULTS);
+  be_in_folder(folderChild2);
+  assert_visible_columns(INBOX_DEFAULTS);
+}
+
+/**
+ * Change settings in an incoming folder, apply them to an outgoing folder and
+ * its children. Make sure the folder and its children change.
+ */
+function test_apply_to_folder_and_children_swapped() {
+  // No need to throttle ourselves during testing.
+  MailUtils.INTER_FOLDER_PROCESSING_DELAY_MS = 0;
+
+  be_in_folder(folderSource);
+
+  // reset!
+  invoke_column_picker_option([{anonid: "reset"}]);
+
+  // permute!
+  let conExtra = [...INBOX_DEFAULTS];
+  conExtra[5] = "senderCol";
+  hide_column("correspondentCol");
+  show_column("senderCol");
+  assert_visible_columns(conExtra);
+
+  // Apply to the dude and his offspring.
+  _apply_to_folder_common(true, folderParent);
+
+  // Make sure it copied to the parent and his children.
+  let conExtraSwapped = [...INBOX_DEFAULTS];
+  conExtraSwapped[5] = "recipientCol";
+  be_in_folder(folderParent);
+  assert_visible_columns(conExtraSwapped);
+  be_in_folder(folderChild1);
+  assert_visible_columns(conExtraSwapped);
+  be_in_folder(folderChild2);
+  assert_visible_columns(conExtraSwapped);
+}
+test_apply_to_folder_and_children_swapped.EXCLUDED_PLATFORMS = ["linux"];
+
+
+/**
  * Create a fake gloda collection.
  */
 function FakeCollection() {
   this.items = [];
 }
 
 function plan_for_columns_state_update() {
   gColumnStateUpdated = false;