more work on #73868. converting ab from tree to outliner. NOT PART OF THE BUILD.

This commit is contained in:
sspitzer%netscape.com 2001-11-14 21:38:32 +00:00
parent ecdc8de5e6
commit 59f6a27a62
4 changed files with 164 additions and 21 deletions

View File

@ -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();

View File

@ -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();

View File

@ -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) {

View File

@ -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_ */