Bug 526541 - Please add a "confirm on delete" option for address book entries...; r=bienvenu ui-r=bwinton

This commit is contained in:
Mike Conley 2011-05-24 22:07:12 +01:00
Родитель f29f9d1213
Коммит 03f86a149d
4 изменённых файлов: 245 добавлений и 24 удалений

Просмотреть файл

@ -302,20 +302,23 @@ function AbDelete()
var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
// If at least one mailing list is selected then prompt users for deletion.
if (types != kCardsOnly)
{
var confirmDeleteMessage;
if (types == kListsAndCards)
confirmDeleteMessage = gAddressBookBundle.getString("confirmDeleteListsAndContacts");
else if (types == kMultipleListsOnly)
confirmDeleteMessage = gAddressBookBundle.getString("confirmDeleteMailingLists");
var confirmDeleteMessage;
if (types == kListsAndCards)
confirmDeleteMessage = gAddressBookBundle.getString("confirmDeleteListsAndContacts");
else if (types == kMultipleListsOnly)
confirmDeleteMessage = gAddressBookBundle.getString("confirmDeleteMailingLists");
else if (types == kSingleListOnly)
confirmDeleteMessage = gAddressBookBundle.getString("confirmDeleteMailingList");
else if (types == kCardsOnly && gAbView && gAbView.selection) {
if (gAbView.selection.count < 2)
confirmDeleteMessage = gAddressBookBundle.getString("confirmDeleteContact");
else
confirmDeleteMessage = gAddressBookBundle.getString("confirmDeleteMailingList");
if (!promptService.confirm(window, null, confirmDeleteMessage))
return;
confirmDeleteMessage = gAddressBookBundle.getString("confirmDeleteContacts");
}
gAbView.deleteSelectedCards();
if (confirmDeleteMessage && promptService.confirm(window, null, confirmDeleteMessage))
gAbView.deleteSelectedCards();
}
function AbNewCard()

Просмотреть файл

@ -68,6 +68,8 @@ mailListNameExistsMessage=A Mailing List with that name already exists. Please c
# used in the addressbook
confirmDeleteMailingListTitle=Delete Mailing List
confirmDeleteAddressbookTitle=Delete Address Book
confirmDeleteContact=Are you sure you want to delete the selected contact?
confirmDeleteContacts=Are you sure you want to delete the selected contacts?
confirmDeleteAddressbook=Are you sure you want to delete the selected address book?
confirmDeleteCollectionAddressbook=If this address book is deleted, %S will no longer collect addresses. Are you sure you want to delete the selected address book?
confirmDeleteMailingList=Are you sure you want to delete the selected mailing list?

Просмотреть файл

@ -44,11 +44,50 @@ var MODULE_NAME = 'test-address-book';
var RELATIVE_ROOT = '../shared-modules';
var MODULE_REQUIRES = ['address-book-helpers', 'folder-display-helpers'];
let abController = null;
const kPromptServiceUUID = "{6cc9c9fe-bc0b-432b-a410-253ef8bcc699}";
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource:///modules/Services.jsm");
let abController = null;
var addrBook1, addrBook2, addrBook3, addrBook4;
var mListA, mListB, mListC, mListD, mListE;
var gMockPromptService = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPromptService]),
_will_return: null,
_did_confirm: false,
_confirm_msg: null,
confirm: function(aParent, aDialogTitle, aText) {
this._did_confirm = true;
this._confirm_msg = aText;
return this._will_return;
},
_return: function(aReturn) {
this._will_return = aReturn;
},
_reset: function() {
this._will_return = null;
this._did_confirm = false;
this._confirm_msg = null;
},
};
var gMockPromptServiceFactory = {
createInstance: function(aOuter, aIID) {
if (aOuter != null)
throw Cr.NS_ERROR_NO_AGGREGATION;
if (!aIID.equals(Ci.nsIPromptService))
throw Cr.NS_ERROR_NO_INTERFACE;
return gMockPromptService;
}
};
function setupModule(module)
{
let fdh = collector.getModule('folder-display-helpers');
@ -154,3 +193,130 @@ function test_persist_collapsed_and_expanded_states()
assert_true(is_address_book_collapsed(addrBook3));
}
/* Test that if we try to delete a contact, that we are given
* a confirm prompt.
*/
function test_deleting_contact_causes_confirm_prompt()
{
// Register the Mock Prompt Service
Components.manager.QueryInterface(Ci.nsIComponentRegistrar)
.registerFactory(Components.ID(kPromptServiceUUID),
"Mock Prompt Service",
"@mozilla.org/embedcomp/prompt-service;1",
gMockPromptServiceFactory);
// Create a contact that we'll try to delete
let contact1 = create_contact("test@nobody.com", "Sammy Jenkis", true);
let toDelete = [contact1];
let bundle = Services.strings
.createBundle("chrome://messenger/locale/addressbook/addressBook.properties")
let confirmSingle = bundle.GetStringFromName("confirmDeleteContact");
// Add some contacts to the address book
load_contacts_into_address_book(addrBook1, toDelete);
select_address_book(addrBook1);
let totalEntries = abController.window.gAbView.rowCount;
// Set the mock prompt to return false, so that the
// contact should not be deleted.
gMockPromptService._return(false);
// Now attempt to delete the contact
select_contact(toDelete);
abController.keypress(null, "VK_DELETE", {});
// Was a confirm displayed?
assert_true(gMockPromptService._did_confirm);
// Was the right message displayed?
assert_equals(gMockPromptService._confirm_msg, confirmSingle);
// The contact should not have been deleted.
assert_equals(abController.window.gAbView.rowCount, totalEntries);
gMockPromptService._reset();
// Now we'll return true on confirm so that
// the contact is deleted.
gMockPromptService._return(true);
select_contact(toDelete);
abController.keypress(null, "VK_DELETE", {});
// Was a confirm displayed?
assert_true(gMockPromptService._did_confirm);
// Was the right message displayed?
assert_equals(gMockPromptService._confirm_msg, confirmSingle);
// The contact should have been deleted.
assert_equals(abController.window.gAbView.rowCount,
totalEntries - toDelete.length);
Components.manager.QueryInterface(Ci.nsIComponentRegistrar)
.unregisterFactory(Components.ID(kPromptServiceUUID),
gMockPromptServiceFactory);
}
/* Test that if we try to delete multiple contacts, that we are give
* a confirm prompt.
*/
function test_deleting_contacts_causes_confirm_prompt()
{
// Register the Mock Prompt Service
Components.manager.QueryInterface(Ci.nsIComponentRegistrar)
.registerFactory(Components.ID(kPromptServiceUUID),
"Mock Prompt Service",
"@mozilla.org/embedcomp/prompt-service;1",
gMockPromptServiceFactory);
// Create some contacts that we'll try to delete.
let contact2 = create_contact("test2@nobody.com", "Leonard Shelby", true);
let contact3 = create_contact("test3@nobody.com", "John Edward Gammell", true);
let contact4 = create_contact("test4@nobody.com", "Natalie", true);
let toDelete = [contact2, contact3, contact4];
let bundle = Services.strings
.createBundle("chrome://messenger/locale/addressbook/addressBook.properties")
let confirmMultiple = bundle.GetStringFromName("confirmDeleteContacts");
// Add some contacts to the address book
load_contacts_into_address_book(addrBook1, toDelete);
select_address_book(addrBook1);
let totalEntries = abController.window.gAbView.rowCount;
// Set the mock prompt to return false, so that the
// contact should not be deleted.
gMockPromptService._return(false);
// Now attempt to delete the contact
select_contacts(toDelete);
abController.keypress(null, "VK_DELETE", {});
// Was a confirm displayed?
assert_true(gMockPromptService._did_confirm);
// Was the right message displayed?
assert_equals(gMockPromptService._confirm_msg, confirmMultiple);
// The contact should not have been deleted.
assert_equals(abController.window.gAbView.rowCount, totalEntries);
gMockPromptService._reset();
// Now we'll return true on confirm so that
// the contact is deleted.
gMockPromptService._return(true);
select_contacts(toDelete);
abController.keypress(null, "VK_DELETE", {});
// Was a confirm displayed?
assert_true(gMockPromptService._did_confirm);
// Was the right message displayed?
assert_equals(gMockPromptService._confirm_msg, confirmMultiple);
// The contact should have been deleted.
assert_equals(abController.window.gAbView.rowCount,
totalEntries - toDelete.length);
Components.manager.QueryInterface(Ci.nsIComponentRegistrar)
.unregisterFactory(Components.ID(kPromptServiceUUID),
gMockPromptServiceFactory);
}

Просмотреть файл

@ -89,6 +89,11 @@ function installInto(module) {
module.is_address_book_collapsible = is_address_book_collapsible;
module.get_name_of_address_book_element_at = get_name_of_address_book_element_at;
module.select_address_book = select_address_book;
module.get_contact_ab_view_index = get_contact_ab_view_index;
// select_contact is aliased for select_contacts, since they
// share the same code.
module.select_contact = select_contacts;
module.select_contacts = select_contacts;
}
/**
@ -236,8 +241,9 @@ function get_mailing_list_from_address_book(aAddressBook, aDirName)
/* Given some address book, adds a collection of contacts to that
* address book.
* @param aAddressBook an address book to add the contacts to
* @param aContacts a collection of contacts, where each contact has
* members "email" and "displayName"
* @param aContacts a collection of nsIAbCards, or contacts,
* where each contact has members "email"
* and "displayName"
*
* Example:
* [{email: 'test@test.com', displayName: 'Sammy Jenkis'}]
@ -245,8 +251,14 @@ function get_mailing_list_from_address_book(aAddressBook, aDirName)
function load_contacts_into_address_book(aAddressBook, aContacts)
{
for each (contact_info in aContacts) {
let contact = create_contact(contact_info.email,
let contact;
if (contact_info instanceof Ci.nsIAbCard)
contact = contact_info.QueryInterface(Ci.nsIAbCard);
else
contact = create_contact(contact_info.email,
contact_info.displayName, true);
aAddressBook.addCard(contact);
}
}
@ -269,21 +281,41 @@ function load_contacts_into_mailing_list(aMailingList, aContacts)
}
}
/* Given some address book, return the row index for that address book
* in the tree view. Throws an error if it cannot find the address book.
* @param aAddrBook an address book to search for
/* given some address book, return the row index for that address book
* in the tree view. throws an error if it cannot find the address book.
* @param aaddrbook an address book to search for
* @return the row index for that address book
*/
function get_address_book_tree_view_index(aAddrBook)
function get_address_book_tree_view_index(aaddrbook)
{
let addrBooks = abController.window.gDirectoryTreeView._rowMap;
for (let i = 0; i < addrBooks.length; i++) {
if (addrBooks[i]._directory == aAddrBook) {
let addrbooks = abController.window.gDirectoryTreeView._rowMap;
for (let i = 0; i < addrbooks.length; i++) {
if (addrbooks[i]._directory == aaddrbook) {
return i;
}
}
throw Error("Could not find the index for the address book named "
+ aAddrbook.dirName);
throw error("could not find the index for the address book named "
+ aaddrbook.dirname);
}
/* Given some contact, return the row index for that contact in the
* address book view. Assumes that the address book that the contact
* belongs to is currently selected. Throws an error if it cannot
* find the contact.
* @param aContact a contact to search for
* @return the row index for that contact
*/
function get_contact_ab_view_index(aContact)
{
let contacts = abController.window.gAbView;
for (let i = 0; i < contacts.rowCount; i++) {
let contact = contacts.getCardFromRow(i);
if (contact.localId == aContact.localId &&
!contact.isMailList)
return i;
}
throw Error("Could not find the index for the contact named "
+ aContact.displayName);
}
/* Determines whether or not an address book is collapsed in
@ -374,3 +406,21 @@ function select_address_book(aAddrBook)
let aIndex = get_address_book_tree_view_index(aAddrBook);
abController.window.gDirectoryTreeView.selection.select(aIndex);
}
/* Selects one or more contacts in an address book, assuming that
* the address book is already selected. Pass a single nsIAbCard
* to select one contact, or an array of nsIAbCards to select
* multiple.
*/
function select_contacts(aContacts)
{
if (!Array.isArray(aContacts))
aContacts = [aContacts];
abController.window.gAbView.selection.clearSelection();
for (let i = 0; i < aContacts.length; i++) {
let aIndex = get_contact_ab_view_index(aContacts[i]);
abController.window.gAbView.selection.toggleSelect(aIndex);
}
}