mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 11:55:49 +00:00
more work on #73868. converting ab from tree to outliner. NOT PART OF THE BUILD.
This commit is contained in:
parent
ecdc8de5e6
commit
59f6a27a62
@ -39,11 +39,13 @@
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIAbCard;
|
||||
interface nsIAbDirectory;
|
||||
|
||||
[scriptable, uuid(79ad5d6e-1dd2-11b2-addd-f547dab50d75)]
|
||||
interface nsIAbViewListener : nsISupports
|
||||
{
|
||||
void onSelectionChanged();
|
||||
void onCountChanged(in long total);
|
||||
};
|
||||
|
||||
[scriptable, uuid(e35c015c-1dd1-11b2-9494-f88326252aae)]
|
||||
@ -56,6 +58,7 @@ interface nsIAbView : nsISupports
|
||||
readonly attribute string URI;
|
||||
readonly attribute wstring sortColumn;
|
||||
readonly attribute wstring sortDirection;
|
||||
readonly attribute nsIAbDirectory directory;
|
||||
|
||||
nsIAbCard getCardFromRow(in long row);
|
||||
void selectAll();
|
||||
|
@ -21,6 +21,12 @@
|
||||
* Seth Spitzer <sspitzer@netscape.com>
|
||||
*/
|
||||
|
||||
function GetAbViewListener()
|
||||
{
|
||||
// the ab panel doesn't care if the total changes, or if the selection changes
|
||||
return null;
|
||||
}
|
||||
|
||||
function abPanelLoad()
|
||||
{
|
||||
InitCommonJS();
|
||||
|
@ -49,9 +49,22 @@
|
||||
#include "nsIAddrBookSession.h"
|
||||
#include "nsAbBaseCID.h"
|
||||
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsIPrefBranchInternal.h"
|
||||
|
||||
|
||||
#define CARD_NOT_FOUND -1
|
||||
#define ALL_ROWS -1
|
||||
|
||||
#define PREF_MAIL_ADDR_BOOK_LASTNAMEFIRST "mail.addr_book.lastnamefirst"
|
||||
|
||||
// also, our default primary sort
|
||||
#define DISPLAY_NAME_COLUMN_ID "DisplayName"
|
||||
|
||||
// also, our default secondary sort
|
||||
#define PRIMARY_EMAIL_COLUMN_ID "PrimaryEmail"
|
||||
|
||||
static NS_DEFINE_CID(kCollationFactoryCID, NS_COLLATIONFACTORY_CID);
|
||||
|
||||
NS_IMPL_ADDREF(nsAbView)
|
||||
@ -62,6 +75,7 @@ NS_INTERFACE_MAP_BEGIN(nsAbView)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIAbView)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIOutlinerView)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIAbListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
nsAbView::nsAbView()
|
||||
@ -69,6 +83,7 @@ nsAbView::nsAbView()
|
||||
NS_INIT_ISUPPORTS();
|
||||
mMailListAtom = getter_AddRefs(NS_NewAtom("MailList"));
|
||||
mSuppressSelectionChange = PR_FALSE;
|
||||
mSuppressCountChange = PR_FALSE;
|
||||
}
|
||||
|
||||
nsAbView::~nsAbView()
|
||||
@ -86,6 +101,10 @@ NS_IMETHODIMP nsAbView::Close()
|
||||
mAbViewListener = nsnull;
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
rv = RemovePrefObservers();
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
nsCOMPtr<nsIAddrBookSession> abSession = do_GetService(NS_ADDRBOOKSESSION_CONTRACTID, &rv);
|
||||
if(NS_SUCCEEDED(rv))
|
||||
abSession->RemoveAddressBookListener(this);
|
||||
@ -93,19 +112,28 @@ NS_IMETHODIMP nsAbView::Close()
|
||||
PRInt32 i = mCards.Count();
|
||||
while(i-- > 0)
|
||||
{
|
||||
RemoveCardAt(i);
|
||||
rv = RemoveCardAt(i);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "remove card failed\n");
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsAbView::RemoveCardAt(PRInt32 row)
|
||||
nsresult nsAbView::RemoveCardAt(PRInt32 row)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
AbCard *abcard = (AbCard*) (mCards.ElementAt(row));
|
||||
NS_IF_RELEASE(abcard->card);
|
||||
mCards.RemoveElementAt(row);
|
||||
PR_FREEIF(abcard->primaryCollationKey);
|
||||
PR_FREEIF(abcard->secondaryCollationKey);
|
||||
PR_FREEIF(abcard);
|
||||
|
||||
if (mAbViewListener && !mSuppressCountChange) {
|
||||
rv = mAbViewListener->OnCountChanged(mCards.Count());
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAbView::GetURI(char **aURI)
|
||||
@ -114,6 +142,46 @@ NS_IMETHODIMP nsAbView::GetURI(char **aURI)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsAbView::AddPrefObservers()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIPrefService> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
nsCOMPtr<nsIPrefBranch> prefBranch;
|
||||
rv = prefs->GetBranch(nsnull, getter_AddRefs(prefBranch));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
nsCOMPtr<nsIPrefBranchInternal> pbi = do_QueryInterface(prefBranch, &rv);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
rv = pbi->AddObserver(PREF_MAIL_ADDR_BOOK_LASTNAMEFIRST, this, PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsAbView::RemovePrefObservers()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIPrefService> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
nsCOMPtr<nsIPrefBranch> prefBranch;
|
||||
rv = prefs->GetBranch(nsnull, getter_AddRefs(prefBranch));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
nsCOMPtr<nsIPrefBranchInternal> pbi = do_QueryInterface(prefBranch, &rv);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
rv = pbi->RemoveObserver(PREF_MAIL_ADDR_BOOK_LASTNAMEFIRST, this);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAbView::Init(const char *aURI, nsIAbViewListener *abViewListener,
|
||||
const PRUnichar *colID, const PRUnichar *sortDirection)
|
||||
{
|
||||
@ -122,13 +190,8 @@ NS_IMETHODIMP nsAbView::Init(const char *aURI, nsIAbViewListener *abViewListener
|
||||
mURI = aURI;
|
||||
mAbViewListener = abViewListener;
|
||||
|
||||
/* todo:
|
||||
register as a listener of "mail.addr_book.lastnamefirst"
|
||||
const kDisplayName = 0;
|
||||
const kLastNameFirst = 1;
|
||||
const kFirstNameFirst = 2;
|
||||
if it changes, rebuild and invalidate
|
||||
*/
|
||||
rv = AddPrefObservers();
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
nsCOMPtr <nsIRDFService> rdfService = do_GetService("@mozilla.org/rdf/rdf-service;1",&rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -151,9 +214,22 @@ NS_IMETHODIMP nsAbView::Init(const char *aURI, nsIAbViewListener *abViewListener
|
||||
|
||||
rv = abSession->AddAddressBookListener(this);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
if (mAbViewListener && !mSuppressCountChange) {
|
||||
rv = mAbViewListener->OnCountChanged(mCards.Count());
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAbView::GetDirectory(nsIAbDirectory **aDirectory)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aDirectory);
|
||||
*aDirectory = mDirectory;
|
||||
NS_IF_ADDREF(*aDirectory);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsAbView::EnumerateCards()
|
||||
{
|
||||
nsresult rv;
|
||||
@ -439,15 +515,20 @@ NS_IMETHODIMP nsAbView::SortBy(const PRUnichar *colID, const PRUnichar *sortDir)
|
||||
|
||||
nsAutoString sortColumn;
|
||||
if (!colID)
|
||||
sortColumn = NS_LITERAL_STRING("DisplayName"); // default sort
|
||||
sortColumn = NS_LITERAL_STRING(DISPLAY_NAME_COLUMN_ID); // default sort
|
||||
else
|
||||
sortColumn = colID;
|
||||
|
||||
PRInt32 count = mCards.Count();
|
||||
PRInt32 i;
|
||||
|
||||
// if we are sorting by how we are already sorted, just reverse
|
||||
if (!nsCRT::strcmp(mSortColumn.get(),sortColumn.get())) {
|
||||
// if we are sorting by how we are already sorted,
|
||||
// and just the sort direction changes, just reverse
|
||||
//
|
||||
// note, we'll call SortBy() with the existing sort column and the
|
||||
// existing sort direction, and that needs to do a complete resort.
|
||||
// for example, we do that when the PREF_MAIL_ADDR_BOOK_LASTNAMEFIRST changes
|
||||
if (!nsCRT::strcmp(mSortColumn.get(),sortColumn.get()) && !nsCRT::strcmp(mSortDirection.get(), sortDir)) {
|
||||
PRInt32 halfPoint = count / 2;
|
||||
for (i=0; i < halfPoint; i++) {
|
||||
// swap the elements.
|
||||
@ -506,7 +587,7 @@ nsresult nsAbView::GenerateCollationKeysForCard(const PRUnichar *colID, AbCard *
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
// XXX fix me, do this with const to avoid the strcpy
|
||||
rv = abcard->card->GetCardUnicharValue(NS_LITERAL_STRING("PrimaryEmail").get(), getter_Copies(value));
|
||||
rv = abcard->card->GetCardUnicharValue(NS_LITERAL_STRING(PRIMARY_EMAIL_COLUMN_ID).get(), getter_Copies(value));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
// XXX be smarter about the key, from an arena
|
||||
@ -590,6 +671,41 @@ NS_IMETHODIMP nsAbView::OnItemAdded(nsISupports *parentDir, nsISupports *item)
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAbView::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *someData)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (!nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) {
|
||||
nsDependentString prefName(someData);
|
||||
|
||||
if (prefName.Equals(NS_LITERAL_STRING(PREF_MAIL_ADDR_BOOK_LASTNAMEFIRST))) {
|
||||
// the PREF_MAIL_ADDR_BOOK_LASTNAMEFIRST pref affects how the DisplayName column looks.
|
||||
// so if the DisplayName is our primary or secondary sort,
|
||||
// we need to resort.
|
||||
//
|
||||
// XXX optimize me
|
||||
// PrimaryEmail is always the secondary sort, unless it is currently the
|
||||
// primary sort. So, if PrimaryEmail is the primary sort,
|
||||
// DisplayName might be the secondary sort.
|
||||
//
|
||||
// one day, we can get fancy and remember what the secondary sort is.
|
||||
// we we do that, we can fix this code. at best, it will turn a sort into a invalidate.
|
||||
//
|
||||
// if neither the primary nor the secondary sorts are DisplayName, all we have to do is
|
||||
// invalidate (to show the new DisplayNames), but the sort will not change.
|
||||
if (!nsCRT::strcmp(mSortColumn.get(), NS_LITERAL_STRING(DISPLAY_NAME_COLUMN_ID).get()) ||
|
||||
!nsCRT::strcmp(mSortColumn.get(), NS_LITERAL_STRING(PRIMARY_EMAIL_COLUMN_ID).get())) {
|
||||
rv = SortBy(mSortColumn.get(), mSortDirection.get());
|
||||
}
|
||||
else {
|
||||
rv = InvalidateOutliner(ALL_ROWS);
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsAbView::AddCard(AbCard *abcard, PRBool selectCardAfterAdding, PRInt32 *index)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
@ -607,6 +723,11 @@ nsresult nsAbView::AddCard(AbCard *abcard, PRBool selectCardAfterAdding, PRInt32
|
||||
mOutlinerSelection->RangedSelect(*index, *index, PR_FALSE /* augment */);
|
||||
}
|
||||
|
||||
if (mAbViewListener && !mSuppressCountChange) {
|
||||
rv = mAbViewListener->OnCountChanged(mCards.Count());
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -636,6 +757,7 @@ NS_IMETHODIMP nsAbView::OnItemRemoved(nsISupports *parentDir, nsISupports *item)
|
||||
|
||||
if (directory.get() == mDirectory.get()) {
|
||||
rv = RemoveCardAndSelectNextCard(item);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
@ -647,7 +769,9 @@ nsresult nsAbView::RemoveCardAndSelectNextCard(nsISupports *item)
|
||||
if (card) {
|
||||
PRInt32 index = FindIndexForCard(card);
|
||||
if (index != CARD_NOT_FOUND) {
|
||||
RemoveCardAt(index);
|
||||
rv = RemoveCardAt(index);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
if (mOutliner)
|
||||
rv = mOutliner->RowCountChanged(index, -1);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
@ -731,14 +855,18 @@ NS_IMETHODIMP nsAbView::OnItemPropertyChanged(nsISupports *item, const char *pro
|
||||
}
|
||||
|
||||
mSuppressSelectionChange = PR_TRUE;
|
||||
|
||||
mSuppressCountChange = PR_TRUE;
|
||||
|
||||
// remove the old card
|
||||
RemoveCardAt(index);
|
||||
|
||||
rv = RemoveCardAt(index);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "remove card failed\n");
|
||||
|
||||
// add the card we created, and select it (to restore selection) if it was selected
|
||||
rv = AddCard(newCard, cardWasSelected /* select card */, &index);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "add card failed\n");
|
||||
|
||||
mSuppressSelectionChange = PR_FALSE;
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
mSuppressCountChange = PR_FALSE;
|
||||
|
||||
// ensure restored selection is visible
|
||||
if (cardWasSelected) {
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include "nsIAtom.h"
|
||||
#include "nsICollation.h"
|
||||
#include "nsIAbListener.h"
|
||||
#include "nsIObserver.h"
|
||||
|
||||
typedef struct AbCard
|
||||
{
|
||||
@ -59,7 +60,7 @@ typedef struct AbCard
|
||||
} AbCard;
|
||||
|
||||
|
||||
class nsAbView : public nsIAbView, public nsIOutlinerView, public nsIAbListener
|
||||
class nsAbView : public nsIAbView, public nsIOutlinerView, public nsIAbListener, public nsIObserver
|
||||
{
|
||||
public:
|
||||
nsAbView();
|
||||
@ -69,6 +70,7 @@ public:
|
||||
NS_DECL_NSIABVIEW
|
||||
NS_DECL_NSIOUTLINERVIEW
|
||||
NS_DECL_NSIABLISTENER
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIOutlinerBoxObject> mOutliner;
|
||||
@ -78,11 +80,12 @@ private:
|
||||
PRInt32 FindIndexForCard(nsIAbCard *card);
|
||||
nsresult GenerateCollationKeysForCard(const PRUnichar *colID, AbCard *abcard);
|
||||
nsresult InvalidateOutliner(PRInt32 row);
|
||||
void RemoveCardAt(PRInt32 row);
|
||||
nsresult RemoveCardAt(PRInt32 row);
|
||||
nsresult AddCard(AbCard *abcard, PRBool selectCardAfterAdding, PRInt32 *index);
|
||||
nsresult RemoveCardAndSelectNextCard(nsISupports *item);
|
||||
nsresult EnumerateCards();
|
||||
PRBool mSuppressSelectionChange;
|
||||
nsresult AddPrefObservers();
|
||||
nsresult RemovePrefObservers();
|
||||
|
||||
nsCString mURI;
|
||||
nsCOMPtr <nsIAbDirectory> mDirectory;
|
||||
@ -92,6 +95,9 @@ private:
|
||||
nsString mSortDirection;
|
||||
nsCOMPtr<nsICollation> mCollationKeyGenerator;
|
||||
nsCOMPtr<nsIAbViewListener> mAbViewListener;
|
||||
|
||||
PRPackedBool mSuppressSelectionChange;
|
||||
PRPackedBool mSuppressCountChange;
|
||||
};
|
||||
|
||||
#endif /* _nsAbView_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user