163773 r=cavin sr=bienvenu Made quick search a separate subclass of nsMsgDBView

This commit is contained in:
naving%netscape.com 2002-08-30 04:20:06 +00:00
Родитель 78f830028e
Коммит 86c192ae93
19 изменённых файлов: 437 добавлений и 319 удалений

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

@ -398,6 +398,10 @@
#define NS_MSGSEARCHDBVIEW_CONTRACTID \
NS_MSGDBVIEW_CONTRACTID_PREFIX "search"
#define NS_MSGQUICKSEARCHDBVIEW_CONTRACTID \
NS_MSGDBVIEW_CONTRACTID_PREFIX "quicksearch"
/* 52f860e0-1dd2-11b2-aa72-bb751981bd00 */
#define NS_MSGTHREADEDDBVIEW_CID \
{0x52f860e0, 0x1dd2, 0x11b2, \
@ -418,6 +422,11 @@
{0xaeac118c, 0x0823, 0x11d5, \
{0xa5, 0xbf, 0x00, 0x60, 0xb0, 0xfc, 0x04, 0xb7}}
/* 2dd9d0fe-b609-11d6-bacc-00108335748d */
#define NS_MSGQUICKSEARCHDBVIEW_CID \
{0x2dd9d0fe, 0xb609, 0x11d6, \
{0xba, 0xcc, 0x00, 0x10, 0x83, 0x35, 0x74, 0x8d}}
//
// nsMsgAccountManager
//

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

@ -97,6 +97,7 @@
#include "nsMsgThreadedDBView.h"
#include "nsMsgSpecialViews.h"
#include "nsMsgSearchDBView.h"
#include "nsMsgQuickSearchDBView.h"
#include "nsMsgOfflineManager.h"
@ -144,6 +145,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsMsgThreadedDBView);
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMsgThreadsWithUnreadDBView);
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMsgWatchedThreadsWithUnreadDBView);
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMsgSearchDBView);
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMsgQuickSearchDBView);
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMsgOfflineManager);
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMsgProgress);
#ifdef XP_WIN
@ -312,6 +314,10 @@ static const nsModuleComponentInfo gComponents[] = {
NS_MSGSEARCHDBVIEW_CONTRACTID,
nsMsgSearchDBViewConstructor,
},
{ "quick search db view", NS_MSGQUICKSEARCHDBVIEW_CID,
NS_MSGQUICKSEARCHDBVIEW_CONTRACTID,
nsMsgQuickSearchDBViewConstructor,
},
{ "Messenger Offline Manager", NS_MSGOFFLINEMANAGER_CID,
NS_MSGOFFLINEMANAGER_CONTRACTID,
nsMsgOfflineManagerConstructor,

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

@ -1300,6 +1300,13 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsMsgQuickSearchDBView.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsMsgSpecialViews.cpp</PATH>
@ -1587,6 +1594,11 @@
<PATH>nsMsgSearchDBView.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsMsgQuickSearchDBView.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsMsgSpecialViews.cpp</PATH>
@ -2861,6 +2873,13 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsMsgQuickSearchDBView.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsMsgSpecialViews.cpp</PATH>
@ -3148,6 +3167,11 @@
<PATH>nsMsgSearchDBView.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsMsgQuickSearchDBView.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsMsgSpecialViews.cpp</PATH>
@ -3322,6 +3346,12 @@
<PATH>nsMsgSearchDBView.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>mailnewsDebug.shlb</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsMsgQuickSearchDBView.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>mailnewsDebug.shlb</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>

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

@ -64,6 +64,7 @@ interface nsMsgViewType {
const nsMsgViewTypeValue eShowAllThreads = 0;
const nsMsgViewTypeValue eShowThreadsWithUnread = 2;
const nsMsgViewTypeValue eShowWatchedThreadsWithUnread = 3;
const nsMsgViewTypeValue eShowQuickSearchResults = 4;
};
[scriptable, uuid(64852276-1dd2-11b2-8103-afe12002c053)]
@ -76,7 +77,6 @@ interface nsMsgViewFlagsType
const nsMsgViewFlagsTypeValue kThreadedDisplay = 0x1;
const nsMsgViewFlagsTypeValue kShowIgnored = 0x8;
const nsMsgViewFlagsTypeValue kUnreadOnly = 0x10;
const nsMsgViewFlagsTypeValue kDeferPopulatingView = 0x20;
};
[scriptable, uuid(b2f31bca-fd18-11d4-a5be-0060b0fc04b7)]
@ -280,7 +280,6 @@ interface nsIMsgDBView : nsISupports
void loadMessageByMsgKey (in nsMsgKey aMsgKey);
void reloadMessage();
void reloadMessageWithAllParts();
void reloadFolderAfterQuickSearch();
readonly attribute unsigned long numSelected;
readonly attribute nsMsgViewIndex msgToSelectAfterDelete;
@ -295,14 +294,13 @@ interface nsIMsgDBView : nsISupports
// we'll suppress command updating during folder loading
attribute boolean suppressCommandUpdating;
//to tell us if we are in the search view
attribute boolean isSearchView;
//to notify tree that rows are going away
void onDeleteCompleted(in boolean succeeded);
readonly attribute nsIMsgDatabase db;
readonly attribute boolean supportsThreading;
attribute nsIMsgSearchSession searchSession;
};

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

@ -323,12 +323,7 @@ function RerootFolder(uri, newFolder, viewType, viewFlags, sortType, sortOrder)
oldFolder.setMsgDatabase(null);
}
// that should have initialized gDBView, now re-root the thread pane
var treeView = gDBView.QueryInterface(Components.interfaces.nsITreeView);
if (treeView)
{
var tree = GetThreadTree();
tree.boxObject.QueryInterface(Components.interfaces.nsITreeBoxObject).view = treeView;
}
RerootThreadPane();
SetUpToolbarButtons(uri);
@ -568,6 +563,9 @@ function CreateBareDBView(originalView, msgFolder, viewType, viewFlags, sortType
viewType = viewType - 0;
switch (viewType) {
case nsMsgViewType.eShowQuickSearchResults:
dbviewContractId += "quicksearch";
break;
case nsMsgViewType.eShowThreadsWithUnread:
dbviewContractId += "threadswithunread";
break;
@ -744,18 +742,22 @@ function FolderPaneSelectionChange()
dump("failed to get view & sort values. ex = " + ex +"\n");
}
}
if (gDBView && gDBView.isSearchView)
if (gDBView && gDBView.viewType == nsMsgViewType.eShowQuickSearchResults)
{
gDBView.isSearchView = false; //reset the search input on folder switch
var searchInput = document.getElementById("searchInput");
if (gPreQuickSearchView) //close cached view before quick search
{
gPreQuickSearchView.close();
gPreQuickSearchView = null;
}
var searchInput = document.getElementById("searchInput"); //reset the search input on folder switch
if (searchInput)
searchInput.value = "";
}
ClearMessagePane();
if (gSearchEmailAddress)
viewFlags |= nsMsgViewFlagsType.kDeferPopulatingView;
else
viewFlags &= ~nsMsgViewFlagsType.kDeferPopulatingView;
viewType = nsMsgViewType.eShowQuickSearchResults;
else if (viewType == nsMsgViewType.eShowQuickSearchResults)
viewType = nsMsgViewType.eShowAllThreads; //override viewType - we don't want to start w/ quick search
ChangeFolderByURI(folderResource.Value, viewType, viewFlags, sortType, sortOrder);
}
}

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

@ -395,8 +395,9 @@ var DefaultController =
if (GetNumSelectedMessages() <= 0) return false;
case "cmd_expandAllThreads":
case "cmd_collapseAllThreads":
if (!gDBView) return false;
return (gDBView.sortType == nsMsgViewSortType.byThread);
if (!gDBView || !gDBView.supportsThreading)
return false;
return (gDBView.sortType == nsMsgViewSortType.byThread);
break;
case "cmd_nextFlaggedMsg":
case "cmd_previousFlaggedMsg":
@ -1016,7 +1017,7 @@ function SearchBarToggled()
if (attribValue == "true")
{
/*come out of quick search view */
if (gDBView && gDBView.isSearchView)
if (gDBView && gDBView.viewType == nsMsgViewType.eShowQuickSearchResults)
onClearSearch();
}
else

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

@ -77,13 +77,17 @@ function OnMailWindowUnload()
var searchSession = GetSearchSession();
if (searchSession)
{
removeGlobalListeners();
if (gPreQuickSearchView) //close the cached pre quick search view
gPreQuickSearchView.close();
}
var dbview = GetDBView();
if (dbview) {
dbview.close();
}
var mailSession = Components.classes[mailSessionContractID].getService();
if(mailSession)
{

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

@ -1055,7 +1055,7 @@ function FolderPaneOnClick(event)
else if (event.detail == 2) {
FolderPaneDoubleClick(row.value, event);
}
else if (gDBView && gDBView.isSearchView)
else if (gDBView && gDBView.viewType == nsMsgViewType.eShowQuickSearchResults)
{
onClearSearch();
}

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

@ -25,6 +25,7 @@
*/
var gSearchSession = null;
var gPreQuickSearchView = null;
var gSearchTimer = null;
var gViewSearchListener;
var gNumOfSearchHits = 0;
@ -94,11 +95,35 @@ function removeListeners()
gSearchSession.unregisterListener(gViewSearchListener);
}
function removeGlobalListeners()
{
removeListeners();
gSearchSession.removeFolderListener(folderListener);
gSearchSession.unregisterListener(gSearchNotificationListener);
}
function initializeGlobalListeners()
{
gSearchSession.addFolderListener(folderListener);
// Setup the javascript object as a listener on the search results
gSearchSession.registerListener(gSearchNotificationListener);
}
function createQuickSearchView()
{
if(gDBView.viewType != nsMsgViewType.eShowQuickSearchResults) //otherwise we are already in quick search view
{
var treeView = gDBView.QueryInterface(Components.interfaces.nsITreeView); //clear selection
treeView.selection.clearSelection();
gPreQuickSearchView = gDBView;
CreateDBView(gDBView.msgFolder, nsMsgViewType.eShowQuickSearchResults, nsMsgViewFlagsType.kNone, gDBView.sortType, gDBView.sortOrder);
}
}
function initializeSearchBar()
{
if (!gDBView)
return;
createQuickSearchView();
if (!gSearchSession)
{
getDocumentElements();
@ -115,27 +140,25 @@ function initializeSearchBar()
}
removeListeners();
}
addListeners();
}
function onEnterInSearchBar()
{
initializeSearchBar();
if (gSearchInput.value == "")
{
var searchView = gDBView.isSearchView;
if (searchView)
if (gDBView.viewType == nsMsgViewType.eShowQuickSearchResults)
{
statusFeedback.showStatusString("");
disableQuickSearchClearButton();
gDBView.reloadFolderAfterQuickSearch(); // that should have initialized gDBView
restorePreSearchView();
}
return;
}
else
gClearButton.setAttribute("disabled", false); //coming into search enable clear button
initializeSearchBar();
gClearButton.setAttribute("disabled", false); //coming into search enable clear button
ClearThreadPaneSelection();
ClearMessagePane();
@ -143,28 +166,61 @@ function onEnterInSearchBar()
onSearch(null);
}
function initializeGlobalListeners()
function restorePreSearchView()
{
gSearchSession.addFolderListener(folderListener);
// Setup the javascript object as a listener on the search results
gSearchSession.registerListener(gSearchNotificationListener);
var selectedHdr = null;
//save selection
try
{
selectedHdr = gDBView.hdrForFirstSelectedMessage;
}
catch (ex)
{}
//we might have to sort the view coming out of quick search
var sortType = gDBView.sortType;
var sortOrder = gDBView.sortOrder;
var viewFlags = gDBView.viewFlags;
var folder = gDBView.msgFolder;
gDBView.close();
gDBView = null;
if (gPreQuickSearchView)
{
gDBView = gPreQuickSearchView;
if (sortType != gDBView.sortType || sortOrder != gDBView.sortOrder)
{
gDBView.sort(sortType, sortOrder);
UpdateSortIndicators(sortType, sortOrder);
}
gPreQuickSearchView = null;
}
else //create default view type
CreateDBView(folder, nsMsgViewType.eShowAllThreads, viewFlags, sortType, sortOrder);
RerootThreadPane();
//now restore selection
if (selectedHdr)
{
gDBView.selectMsgByKey(selectedHdr.messageKey);
var treeView = gDBView.QueryInterface(Components.interfaces.nsITreeView);
var selectedIndex = treeView.selection.currentIndex;
if (selectedIndex >= 0) //scroll
EnsureRowInThreadTreeIsVisible(selectedIndex);
else
ClearMessagePane();
}
else
ScrollToMessage(nsMsgNavigationType.firstNew, true, false /* selectMessage */);
}
function removeGlobalListeners()
{
removeListeners();
gSearchSession.removeFolderListener(folderListener);
gSearchSession.unregisterListener(gSearchNotificationListener);
}
function onSearch(aSearchTerms)
{
var treeView = gDBView.QueryInterface(Components.interfaces.nsITreeView);
if (treeView)
{
var tree = GetThreadTree();
tree.boxObject.QueryInterface(Components.interfaces.nsITreeBoxObject).view = treeView;
}
RerootThreadPane();
if (aSearchTerms)
createSearchTermsWithList(aSearchTerms);

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

@ -105,10 +105,8 @@ function HandleColumnClick(columnID)
}
var dbview = GetDBView();
if (sortType == nsMsgViewSortType.byThread)
{ //do not allow sorting by thread in search view.
if (dbview && dbview.isSearchView) return;
}
if (sortType == nsMsgViewSortType.byThread && !dbview.supportsThreading)
return;
if (dbview.sortType == sortType) {
MsgReverseSortThreadPane();
}
@ -216,7 +214,7 @@ function MsgSortByTotal()
function MsgSortByThread()
{
var dbview = GetDBView();
if(dbview && dbview.isSearchView) //do not allow sorting by thread in search view.
if(dbview && !dbview.supportsThreading)
return;
MsgSortThreadPane(nsMsgViewSortType.byThread);
}
@ -313,6 +311,16 @@ function EnsureRowInThreadTreeIsVisible(index)
tree.treeBoxObject.ensureRowIsVisible(index);
}
function RerootThreadPane()
{
var treeView = gDBView.QueryInterface(Components.interfaces.nsITreeView);
if (treeView)
{
var tree = GetThreadTree();
tree.boxObject.QueryInterface(Components.interfaces.nsITreeBoxObject).view = treeView;
}
}
function ThreadPaneOnLoad()
{
var tree = GetThreadTree();

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

@ -99,6 +99,7 @@ CPPSRCS = \
nsMsgDBView.cpp \
nsMsgThreadedDBView.cpp \
nsMsgSpecialViews.cpp \
nsMsgQuickSearchDBView.cpp \
nsMsgSearchDBView.cpp \
nsMsgOfflineManager.cpp \
nsMsgProgress.cpp \

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

@ -111,7 +111,6 @@ NS_INTERFACE_MAP_BEGIN(nsMsgDBView)
NS_INTERFACE_MAP_ENTRY(nsIMsgDBView)
NS_INTERFACE_MAP_ENTRY(nsIDBChangeListener)
NS_INTERFACE_MAP_ENTRY(nsITreeView)
NS_INTERFACE_MAP_ENTRY(nsIMsgSearchNotify)
NS_INTERFACE_MAP_ENTRY(nsIObserver)
NS_INTERFACE_MAP_END
@ -136,9 +135,7 @@ nsMsgDBView::nsMsgDBView()
mCommandsNeedDisablingBecauseOffline = PR_FALSE;
mRemovingRow = PR_FALSE;
mIsSearchView = PR_FALSE;
m_saveRestoreSelectionDepth = 0;
m_searchSession = nsnull;
// initialize any static atoms or unicode strings
if (gInstanceCount == 0)
{
@ -1592,7 +1589,6 @@ NS_IMETHODIMP nsMsgDBView::Open(nsIMsgFolder *folder, nsMsgViewSortTypeValue sor
NS_ENSURE_SUCCESS(rv,rv);
m_db->AddListener(this);
m_folder = folder;
mIsSearchView = PR_FALSE;
// save off sort type and order, view type and flags
folderInfo->SetSortType(sortType);
folderInfo->SetSortOrder(sortOrder);
@ -1623,11 +1619,6 @@ NS_IMETHODIMP nsMsgDBView::Open(nsIMsgFolder *folder, nsMsgViewSortTypeValue sor
return NS_OK;
}
NS_IMETHODIMP nsMsgDBView::ReloadFolderAfterQuickSearch()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsMsgDBView::Close()
{
RemoveLabelPrefObservers();
@ -1704,18 +1695,6 @@ NS_IMETHODIMP nsMsgDBView::GetSuppressMsgDisplay(PRBool * aSuppressDisplay)
return NS_OK;
}
NS_IMETHODIMP nsMsgDBView::GetIsSearchView(PRBool * aResult)
{
NS_ENSURE_ARG(aResult);
*aResult = mIsSearchView;
return NS_OK;
}
NS_IMETHODIMP nsMsgDBView::SetIsSearchView(PRBool aResult)
{
mIsSearchView = aResult;
return NS_OK;
}
nsresult nsMsgDBView::AddKeys(nsMsgKey *pKeys, PRInt32 *pFlags, const char *pLevels, nsMsgViewSortTypeValue sortType, PRInt32 numKeysToAdd)
{
return NS_ERROR_NOT_IMPLEMENTED;
@ -1902,22 +1881,16 @@ NS_IMETHODIMP nsMsgDBView::DoCommand(nsMsgViewCommandTypeValue command)
rv = ToggleWatched(indices, numIndices);
break;
case nsMsgViewCommandType::expandAll:
if (!mIsSearchView) //ignore for search view
{
rv = ExpandAll();
NS_ASSERTION(mTree, "no tree, see bug #114956");
if(mTree)
mTree->Invalidate();
}
rv = ExpandAll();
NS_ASSERTION(mTree, "no tree, see bug #114956");
if(mTree)
mTree->Invalidate();
break;
case nsMsgViewCommandType::collapseAll:
if (!mIsSearchView) //ignore for search view
{
rv = CollapseAll();
NS_ASSERTION(mTree, "no tree, see bug #114956");
if(mTree)
mTree->Invalidate();
}
rv = CollapseAll();
NS_ASSERTION(mTree, "no tree, see bug #114956");
if(mTree)
mTree->Invalidate();
break;
default:
NS_ASSERTION(PR_FALSE, "invalid command type");
@ -5191,40 +5164,6 @@ NS_IMETHODIMP nsMsgDBView::SelectMsgByKey(nsMsgKey aKey)
return NS_OK;
}
NS_IMETHODIMP
nsMsgDBView::OnSearchHit(nsIMsgDBHdr* aMsgHdr, nsIMsgFolder *folder)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsMsgDBView::OnSearchDone(nsresult status)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsMsgDBView::OnNewSearch()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsMsgDBView::GetSearchSession(nsIMsgSearchSession* *aSession)
{
NS_ASSERTION(0, "GetSearchSession method is not implemented");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsMsgDBView::SetSearchSession(nsIMsgSearchSession *aSession)
{
m_searchSession = getter_AddRefs(NS_GetWeakReference(aSession));
return NS_OK;
}
NS_IMETHODIMP
nsMsgDBView::CloneDBView(nsIMessenger *aMessengerInstance, nsIMsgWindow *aMsgWindow, nsIMsgDBViewCommandUpdater *aCmdUpdater, nsIMsgDBView **_retval)
{
@ -5265,3 +5204,25 @@ nsresult nsMsgDBView::CopyDBView(nsMsgDBView *aNewMsgDBView, nsIMessenger *aMess
return NS_OK;
}
NS_IMETHODIMP
nsMsgDBView::GetSearchSession(nsIMsgSearchSession* *aSession)
{
NS_ASSERTION(PR_FALSE, "should be overriden by child class");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsMsgDBView::SetSearchSession(nsIMsgSearchSession *aSession)
{
NS_ASSERTION(PR_FALSE, "should be overriden by child class");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsMsgDBView::GetSupportsThreading(PRBool *aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
*aResult = PR_FALSE;
return NS_OK;
}

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

@ -57,7 +57,6 @@
#include "nsIDOMElement.h"
#include "nsIAtom.h"
#include "nsIImapIncomingServer.h"
#include "nsIMsgSearchNotify.h"
#include "nsIPref.h"
#include "nsIWeakReference.h"
#include "nsIObserver.h"
@ -88,7 +87,7 @@ enum eFieldType {
// I think this will be an abstract implementation class.
// The classes that implement the tree support will probably
// inherit from this class.
class nsMsgDBView : public nsIMsgDBView, public nsIDBChangeListener, public nsITreeView, public nsIMsgSearchNotify, public nsIObserver
class nsMsgDBView : public nsIMsgDBView, public nsIDBChangeListener, public nsITreeView, public nsIObserver
{
public:
nsMsgDBView();
@ -98,7 +97,6 @@ public:
NS_DECL_NSIMSGDBVIEW
NS_DECL_NSIDBCHANGELISTENER
NS_DECL_NSITREEVIEW
NS_DECL_NSIMSGSEARCHNOTIFY
NS_DECL_NSIOBSERVER
protected:
@ -144,7 +142,6 @@ protected:
PRUint32 mNumSelectedRows; // we cache this to determine when to push command status notifications.
PRPackedBool mSuppressMsgDisplay; // set when the message pane is collapsed
PRPackedBool mSuppressCommandUpdating;
PRPackedBool mIsSearchView; // tells if the search view is loaded.
PRPackedBool mRemovingRow; // set when we're telling the outline a row is being removed. used to suppress msg loading.
// during delete/move operations.
PRPackedBool mCommandsNeedDisablingBecauseOffline;
@ -333,7 +330,6 @@ protected:
nsCOMPtr <nsIMsgDatabase> m_db;
nsCOMPtr <nsIMsgFolder> m_folder;
nsCOMPtr <nsIAtom> mRedirectorTypeAtom;
nsWeakPtr m_searchSession;
nsMsgViewSortTypeValue m_sortType;
nsMsgViewSortOrderValue m_sortOrder;
nsMsgViewFlagsTypeValue m_viewFlags;

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

@ -0,0 +1,141 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Navin Gupta <naving@netscape.com> (Original Author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "msgCore.h"
#include "nsMsgQuickSearchDBView.h"
#include "nsIMsgHdr.h"
#include "nsMsgBaseCID.h"
nsMsgQuickSearchDBView::nsMsgQuickSearchDBView()
{
}
nsMsgQuickSearchDBView::~nsMsgQuickSearchDBView()
{
/* destructor code */
}
NS_IMPL_ISUPPORTS_INHERITED2(nsMsgQuickSearchDBView, nsMsgDBView, nsIMsgDBView, nsIMsgSearchNotify)
NS_IMETHODIMP nsMsgQuickSearchDBView::GetViewType(nsMsgViewTypeValue *aViewType)
{
NS_ENSURE_ARG_POINTER(aViewType);
*aViewType = nsMsgViewType::eShowQuickSearchResults;
return NS_OK;
}
nsresult nsMsgQuickSearchDBView::OnNewHeader(nsMsgKey newKey, nsMsgKey aParentKey, PRBool ensureListed)
{
nsresult rv;
nsCOMPtr <nsIMsgDBHdr> msgHdr;
rv = m_db->GetMsgHdrForKey(newKey, getter_AddRefs(msgHdr));
if (NS_SUCCEEDED(rv) && msgHdr != nsnull)
{
PRBool match=PR_FALSE;
nsCOMPtr <nsIMsgSearchSession> searchSession = do_QueryReferent(m_searchSession);
if (searchSession)
searchSession->MatchHdr(msgHdr, m_db, &match);
if (match)
AddHdr(msgHdr); // do not add a new message if there isn't a match.
}
return NS_OK;
}
NS_IMETHODIMP
nsMsgQuickSearchDBView::GetSearchSession(nsIMsgSearchSession* *aSession)
{
NS_ASSERTION(PR_FALSE, "GetSearchSession method is not implemented");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsMsgQuickSearchDBView::SetSearchSession(nsIMsgSearchSession *aSession)
{
m_searchSession = getter_AddRefs(NS_GetWeakReference(aSession));
return NS_OK;
}
NS_IMETHODIMP
nsMsgQuickSearchDBView::OnSearchHit(nsIMsgDBHdr* aMsgHdr, nsIMsgFolder *folder)
{
NS_ENSURE_ARG(aMsgHdr);
NS_ENSURE_ARG(folder);
nsMsgKey msgKey;
PRUint32 msgFlags;
aMsgHdr->GetMessageKey(&msgKey);
aMsgHdr->GetFlags(&msgFlags);
m_keys.Add(msgKey);
m_levels.Add(0);
m_flags.Add(msgFlags);
// this needs to happen after we add the key, as RowCountChanged() will call our GetRowCount()
if (mTree)
mTree->RowCountChanged(GetSize() - 1, 1);
return NS_OK;
}
NS_IMETHODIMP
nsMsgQuickSearchDBView::OnSearchDone(nsresult status)
{
if (m_sortType != nsMsgViewSortType::byThread)//we do not find levels for the results.
{
m_sortValid = PR_FALSE; //sort the results
Sort(m_sortType, m_sortOrder);
}
return NS_OK;
}
NS_IMETHODIMP
nsMsgQuickSearchDBView::OnNewSearch()
{
PRInt32 oldSize = GetSize();
m_keys.RemoveAll();
m_levels.RemoveAll();
m_flags.RemoveAll();
// this needs to happen after we remove all the keys, since RowCountChanged() will call our GetRowCount()
if (mTree)
mTree->RowCountChanged(0, -oldSize);
return NS_OK;
}

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

@ -0,0 +1,68 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Navin Gupta <naving@netscape.com> (Original Author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef _nsMsgQuickSearchDBViewsH_
#define _nsMsgQuickSearchDBView_H_
#include "nsMsgDBView.h"
#include "nsIMsgSearchNotify.h"
#include "nsIMsgSearchSession.h"
class nsMsgQuickSearchDBView : public nsMsgDBView, public nsIMsgSearchNotify
{
public:
nsMsgQuickSearchDBView();
virtual ~nsMsgQuickSearchDBView();
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIMSGSEARCHNOTIFY
virtual const char * GetViewName(void) {return "QuickSearchView"; }
NS_IMETHOD GetViewType(nsMsgViewTypeValue *aViewType);
NS_IMETHOD SetSearchSession(nsIMsgSearchSession *aSearchSession);
NS_IMETHOD GetSearchSession(nsIMsgSearchSession* *aSearchSession);
protected:
nsWeakPtr m_searchSession;
virtual nsresult OnNewHeader(nsMsgKey newKey, nsMsgKey aParentKey, PRBool ensureListed);
void SavePreSearchInfo();
void ClearPreSearchInfo();
};
#endif

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

@ -61,7 +61,7 @@ nsMsgSearchDBView::~nsMsgSearchDBView()
/* destructor code */
}
NS_IMPL_ISUPPORTS_INHERITED2(nsMsgSearchDBView, nsMsgDBView, nsIMsgDBView, nsIMsgCopyServiceListener)
NS_IMPL_ISUPPORTS_INHERITED3(nsMsgSearchDBView, nsMsgDBView, nsIMsgDBView, nsIMsgCopyServiceListener, nsIMsgSearchNotify)
NS_IMETHODIMP nsMsgSearchDBView::Open(nsIMsgFolder *folder, nsMsgViewSortTypeValue sortType, nsMsgViewSortOrderValue sortOrder, nsMsgViewFlagsTypeValue viewFlags, PRBool aTreatRecipientAsAuthor, PRInt32 *pCount)
{

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

@ -40,8 +40,9 @@
#include "nsMsgDBView.h"
#include "nsIMsgCopyServiceListener.h"
#include "nsIMsgSearchNotify.h"
class nsMsgSearchDBView : public nsMsgDBView, public nsIMsgCopyServiceListener
class nsMsgSearchDBView : public nsMsgDBView, public nsIMsgCopyServiceListener, public nsIMsgSearchNotify
{
public:
nsMsgSearchDBView();

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

@ -61,9 +61,6 @@ NS_IMETHODIMP nsMsgThreadedDBView::Open(nsIMsgFolder *folder, nsMsgViewSortTypeV
nsresult rv = nsMsgDBView::Open(folder, sortType, sortOrder, viewFlags, aTreatRecipientAsAuthor, pCount);
NS_ENSURE_SUCCESS(rv, rv);
if (viewFlags & nsMsgViewFlagsType::kDeferPopulatingView)
return NS_OK;
// Preset msg hdr cache size for performance reason.
if (m_db)
{
@ -101,60 +98,6 @@ NS_IMETHODIMP nsMsgThreadedDBView::Close()
return nsMsgDBView::Close();
}
NS_IMETHODIMP nsMsgThreadedDBView::ReloadFolderAfterQuickSearch()
{
mIsSearchView = PR_FALSE;
m_viewFlags &= ~nsMsgViewFlagsType::kDeferPopulatingView; //clearing out this flag, only used to load folder w/ quick search view
m_searchSession = nsnull;
m_sortValid = PR_FALSE; //force a sort
nsresult rv = NS_OK;
nsMsgKeyArray preservedSelection;
SaveAndClearSelection(&preservedSelection);
// restore saved id array and flags array
// first, remove all the search hits
PRInt32 oldSize = GetSize();
m_keys.RemoveAll();
m_flags.RemoveAll();
m_levels.RemoveAll();
// this needs to happen after we remove all the keys, since RowCountChanged() will call our GetRowCount()
if (mTree)
mTree->RowCountChanged(0, -oldSize);
if (m_preSearchKeys.GetSize())
{
m_keys.InsertAt(0, &m_preSearchKeys);
m_flags.InsertAt(0, &m_preSearchFlags);
m_levels.InsertAt(0, &m_preSearchLevels);
ClearPreSearchInfo();
ClearPrevIdArray(); // previous cached info about non threaded display is not useful
Sort(m_sortType, m_sortOrder);
}
else
{
rv = InitThreadedView(nsnull);
}
// now, account for adding all the pre search items back.
// this needs to happen after we add back the keys, as RowCountChanged() will call our GetRowCount()
if (mTree)
mTree->RowCountChanged(0, GetSize());
RestoreSelection(&preservedSelection);
if (preservedSelection.GetSize() == 0)
{
nsMsgViewIndex resultIndex;
nsMsgKey resultKey;
nsMsgViewIndex threadIndex;
ViewNavigate(nsMsgNavigationType::firstNew, &resultKey, &resultIndex, &threadIndex, PR_TRUE);
if (mTree && resultKey != nsMsgKey_None && resultIndex != nsMsgViewIndex_None)
mTree->EnsureRowIsVisible(resultIndex);
}
return rv;
}
nsresult nsMsgThreadedDBView::InitThreadedView(PRInt32 *pCount)
{
nsresult rv;
@ -460,7 +403,6 @@ void nsMsgThreadedDBView::OnExtraFlagChanged(nsMsgViewIndex index, PRUint32 extr
{
if (IsValidIndex(index))
{
UpdatePreSearchFlagInfo(index, extraFlag);
if (m_havePrevView)
{
nsMsgKey keyChanged = m_keys[index];
@ -469,7 +411,18 @@ void nsMsgThreadedDBView::OnExtraFlagChanged(nsMsgViewIndex index, PRUint32 extr
{
PRUint32 prevFlag = m_prevFlags.GetAt(prevViewIndex);
// don't want to change the elided bit, or has children or is thread
UpdateCachedFlag(prevFlag, &extraFlag);
if (prevFlag & MSG_FLAG_ELIDED)
extraFlag |= MSG_FLAG_ELIDED;
else
extraFlag &= ~MSG_FLAG_ELIDED;
if (prevFlag & MSG_VIEW_FLAG_ISTHREAD)
extraFlag |= MSG_VIEW_FLAG_ISTHREAD;
else
extraFlag &= ~MSG_VIEW_FLAG_ISTHREAD;
if (prevFlag & MSG_VIEW_FLAG_HASCHILDREN)
extraFlag |= MSG_VIEW_FLAG_HASCHILDREN;
else
extraFlag &= ~MSG_VIEW_FLAG_HASCHILDREN;
m_prevFlags.SetAt(prevViewIndex, extraFlag); // will this be right?
}
}
@ -481,45 +434,9 @@ void nsMsgThreadedDBView::OnExtraFlagChanged(nsMsgViewIndex index, PRUint32 extr
m_sortValid = PR_FALSE;
}
void nsMsgThreadedDBView::UpdatePreSearchFlagInfo(nsMsgViewIndex index, PRUint32 extraFlag)
{
if (mIsSearchView)
{
nsMsgKey keyChanged = m_keys[index];
nsMsgViewIndex preSearchViewIndex = m_preSearchKeys.FindIndex(keyChanged);
if (preSearchViewIndex != nsMsgViewIndex_None)
{
PRUint32 preSearchFlag = m_preSearchFlags.GetAt(preSearchViewIndex);
UpdateCachedFlag(preSearchFlag, &extraFlag);
// don't want to change the elided bit, or has children or is thread
m_preSearchFlags.SetAt(preSearchViewIndex, extraFlag);
}
}
}
void nsMsgThreadedDBView::UpdateCachedFlag(PRUint32 aFlag, PRUint32 *extraFlag)
{
NS_ASSERTION(extraFlag,"extraFlag is null");
if(!extraFlag)
return;
if (aFlag & MSG_FLAG_ELIDED)
*extraFlag |= MSG_FLAG_ELIDED;
else
*extraFlag &= ~MSG_FLAG_ELIDED;
if (aFlag & MSG_VIEW_FLAG_ISTHREAD)
*extraFlag |= MSG_VIEW_FLAG_ISTHREAD;
else
*extraFlag &= ~MSG_VIEW_FLAG_ISTHREAD;
if (aFlag & MSG_VIEW_FLAG_HASCHILDREN)
*extraFlag |= MSG_VIEW_FLAG_HASCHILDREN;
else
*extraFlag &= ~MSG_VIEW_FLAG_HASCHILDREN;
}
void nsMsgThreadedDBView::OnHeaderAddedOrDeleted()
{
ClearPrevIdArray();
ClearPreSearchInfo();
}
void nsMsgThreadedDBView::ClearPrevIdArray()
@ -564,16 +481,6 @@ nsresult nsMsgThreadedDBView::OnNewHeader(nsMsgKey newKey, nsMsgKey aParentKey,
rv = m_db->GetMsgHdrForKey(newKey, getter_AddRefs(msgHdr));
if (NS_SUCCEEDED(rv) && msgHdr != nsnull)
{
if (mIsSearchView)
{
PRBool match=PR_FALSE;
OnHeaderAddedOrDeleted(); //db has changed, so clear the cached info..
nsCOMPtr <nsIMsgSearchSession> searchSession = do_QueryReferent(m_searchSession);
if (searchSession)
searchSession->MatchHdr(msgHdr, m_db, &match);
if (!match)
return NS_OK; // do not add a new message if there isn't a match.
}
PRUint32 msgFlags;
msgHdr->GetFlags(&msgFlags);
if ((m_viewFlags & nsMsgViewFlagsType::kUnreadOnly) && !ensureListed && (msgFlags & MSG_FLAG_READ))
@ -583,7 +490,7 @@ nsresult nsMsgThreadedDBView::OnNewHeader(nsMsgKey newKey, nsMsgKey aParentKey,
// a bit harder in the unreadOnly view. But we'll catch it below.
// for search view we don't support threaded display so just add it to the view.
if (! (m_viewFlags & nsMsgViewFlagsType::kThreadedDisplay) || mIsSearchView)// || msgHdr->GetMessageKey() == m_messageDB->GetKeyOfFirstMsgInThread(msgHdr->GetMessageKey()))
if (!(m_viewFlags & nsMsgViewFlagsType::kThreadedDisplay)) // || msgHdr->GetMessageKey() == m_messageDB->GetKeyOfFirstMsgInThread(msgHdr->GetMessageKey()))
rv = AddHdr(msgHdr);
else // need to find the thread we added this to so we can change the hasnew flag
// added message to existing thread, but not to view
@ -707,8 +614,7 @@ nsresult nsMsgThreadedDBView::RemoveByIndex(nsMsgViewIndex index)
flags = m_flags[index];
//we don't support threaded view in quick search
if (! (m_viewFlags & nsMsgViewFlagsType::kThreadedDisplay) || mIsSearchView)
if (! (m_viewFlags & nsMsgViewFlagsType::kThreadedDisplay))
return nsMsgDBView::RemoveByIndex(index);
nsCOMPtr <nsIMsgThread> threadHdr;
@ -819,76 +725,6 @@ NS_IMETHODIMP nsMsgThreadedDBView::GetViewType(nsMsgViewTypeValue *aViewType)
return NS_OK;
}
NS_IMETHODIMP
nsMsgThreadedDBView::OnSearchHit(nsIMsgDBHdr* aMsgHdr, nsIMsgFolder *folder)
{
NS_ENSURE_ARG(aMsgHdr);
NS_ENSURE_ARG(folder);
nsMsgKey msgKey;
PRUint32 msgFlags;
aMsgHdr->GetMessageKey(&msgKey);
aMsgHdr->GetFlags(&msgFlags);
m_keys.Add(msgKey);
m_levels.Add(0);
m_flags.Add(msgFlags);
// this needs to happen after we add the key, as RowCountChanged() will call our GetRowCount()
if (mTree)
mTree->RowCountChanged(GetSize() - 1, 1);
return NS_OK;
}
NS_IMETHODIMP
nsMsgThreadedDBView::OnSearchDone(nsresult status)
{
if (m_sortType != nsMsgViewSortType::byThread)//we do not find levels for the results.
{
m_sortValid = PR_FALSE; //sort the results
Sort(m_sortType, m_sortOrder);
}
return NS_OK;
}
NS_IMETHODIMP
nsMsgThreadedDBView::OnNewSearch()
{
if (!mIsSearchView)
SavePreSearchInfo(); //save the folder view to reload it later.
PRInt32 oldSize = GetSize();
m_keys.RemoveAll();
m_levels.RemoveAll();
m_flags.RemoveAll();
m_currentlyDisplayedMsgKey = nsMsgKey_None; // need to clear this, so we won't restore it.
// this needs to happen after we remove all the keys, since RowCountChanged() will call our GetRowCount()
if (mTree)
mTree->RowCountChanged(0, -oldSize);
ClearPrevIdArray(); // previous cached info about non threaded display is not useful
mIsSearchView = PR_TRUE;
return NS_OK;
}
void nsMsgThreadedDBView::SavePreSearchInfo()
{
ClearPreSearchInfo();
m_preSearchKeys.InsertAt(0, &m_keys);
m_preSearchLevels.InsertAt(0, &m_levels);
m_preSearchFlags.InsertAt(0, &m_flags);
}
void nsMsgThreadedDBView::ClearPreSearchInfo()
{
m_preSearchKeys.RemoveAll();
m_preSearchLevels.RemoveAll();
m_preSearchFlags.RemoveAll();
}
NS_IMETHODIMP
nsMsgThreadedDBView::CloneDBView(nsIMessenger *aMessengerInstance, nsIMsgWindow *aMsgWindow, nsIMsgDBViewCommandUpdater *aCmdUpdater, nsIMsgDBView **_retval)
{
@ -904,3 +740,11 @@ nsMsgThreadedDBView::CloneDBView(nsIMessenger *aMessengerInstance, nsIMsgWindow
NS_IF_ADDREF(*_retval = newMsgDBView);
return NS_OK;
}
NS_IMETHODIMP
nsMsgThreadedDBView::GetSupportsThreading(PRBool *aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
*aResult = PR_TRUE;
return NS_OK;
}

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

@ -55,8 +55,7 @@ public:
virtual nsresult AddKeys(nsMsgKey *pKeys, PRInt32 *pFlags, const char *pLevels, nsMsgViewSortTypeValue sortType, PRInt32 numKeysToAdd);
NS_IMETHOD Sort(nsMsgViewSortTypeValue sortType, nsMsgViewSortOrderValue sortOrder);
NS_IMETHOD GetViewType(nsMsgViewTypeValue *aViewType);
NS_IMETHOD ReloadFolderAfterQuickSearch();
NS_DECL_NSIMSGSEARCHNOTIFY
NS_IMETHOD GetSupportsThreading(PRBool *aResult);
protected:
virtual const char * GetViewName(void) {return "ThreadedDBView"; }
@ -70,10 +69,6 @@ protected:
virtual void OnExtraFlagChanged(nsMsgViewIndex index, PRUint32 extraFlag);
virtual void OnHeaderAddedOrDeleted();
void ClearPrevIdArray();
void SavePreSearchInfo();
void ClearPreSearchInfo();
void UpdateCachedFlag(PRUint32 aFlag, PRUint32 *extraFlag);
void UpdatePreSearchFlagInfo(nsMsgViewIndex index, PRUint32 extraFlag);
virtual nsresult RemoveByIndex(nsMsgViewIndex index);
nsMsgViewIndex GetInsertInfoForNewHdr(nsIMsgDBHdr *newHdr, nsMsgViewIndex threadIndex, PRInt32 targetLevel);
@ -83,9 +78,6 @@ protected:
nsMsgKeyArray m_prevKeys; //this is used for caching non-threaded view.
nsUInt32Array m_prevFlags;
nsUint8Array m_prevLevels;
nsMsgKeyArray m_preSearchKeys; //this is used for caching view before issuing search.
nsUInt32Array m_preSearchFlags;
nsUint8Array m_preSearchLevels;
nsCOMPtr <nsISimpleEnumerator> m_threadEnumerator;
};