adding new nsNNTPNewsgroupList and nsNNTPArticleList objects

git-svn-id: svn://10.0.0.236/trunk@17510 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
alecf%netscape.com
1999-01-11 20:56:39 +00:00
parent aa16127a53
commit 3e9bd176d9
3 changed files with 897 additions and 0 deletions

View File

@@ -0,0 +1,138 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsNNTPNewsgroupListState.h"
#include "nsMsgNewsHost.h"
class ListNewsGroupArticleKeysState
#ifdef HAVE_CHANGELISTENER
: public ChangeListener
#endif
{
public:
nsNNTPArticleList();
/* , MSG_Pane *pane); */
~nsNNTPArticleList();
// nsINNTPArticleKeysState
NS_IMETHOD Init(const char *newsHost, const nsIMsgNewsgroup *newsgroup);
NS_IMETHOD AddArticleKey(PRInt32 key);
NS_IMETHOD FinishAddingArticleKeys();
// other stuff
protected:
struct MSG_NewsKnown m_idsOnServer;
#ifdef HAVE_PANES
MSG_Pane *m_pane;
#endif
const char * m_groupName;
nsIMsgNewsHost *m_host;
#ifdef HAVE_NEWSDB
NewsGroupDB *m_newsDB;
#endif
IDArray m_idsInDB;
#ifdef DEBUG_bienvenu
IDArray m_idsDeleted;
#endif
int32 m_dbIndex;
MessageKey m_highwater;
};
nsNNTPArticleList::nsNNTPArticleList(const char* newshost,
const nsIMsgNewsgroup* newsgroup)
{
NS_INIT_REFCNT();
Initialize(newsHost, newsgroup);
}
ListNewsgroupArticleKeysState::Initialize(const char* newsHost,
const nsIMsgNewsgroup* newsgroup)
{
m_host = host;
m_groupName = groupName;
#ifdef HAVE_PANES
m_pane = pane;
#endif
#ifdef HAVE_NEWSDB
m_newsDB = NULL;
#endif
m_idsOnServer.set = msg_NewsArtSet::Create();
#ifdef HAVE_PANES
MSG_FolderInfoNews *newsFolder = m_pane->GetMaster()->FindNewsFolder(host, groupName, FALSE);
if (newsFolder)
{
char *url = newsFolder->BuildUrl(NULL, MSG_MESSAGEKEYNONE);
#ifdef HAVE_NEWSDB
if (url)
NewsGroupDB::Open(url, m_pane->GetMaster(), &m_newsDB);
if (m_newsDB)
m_newsDB->ListAllIds(m_idsInDB);
#endif
m_dbIndex = 0;
FREEIF(url);
}
#endif
}
nsNNTPArticleList::~nsNNTPArticleList()
{
#ifdef HAVE_NEWSDB
if (m_newsDB)
m_newsDB->Close();
#endif
}
int nsNNTPArticleList::AddArticleKey(int32 key)
{
m_idsOnServer.set->Add(key);
if (m_dbIndex < m_idsInDB.GetSize())
{
int32 idInDBToCheck = m_idsInDB.GetAt(m_dbIndex);
// if there are keys in the database that aren't in the newsgroup
// on the server, remove them. We probably shouldn't do this if
// we have a copy of the article offline.
while (idInDBToCheck < key)
{
#ifdef HAVE_NEWSDB
m_newsDB->DeleteMessage(idInDBToCheck, NULL, FALSE);
#endif
#ifdef DEBUG_bienvenu
m_idsDeleted.Add(idInDBToCheck);
#endif
if (m_dbIndex >= m_idsInDB.GetSize())
break;
idInDBToCheck = m_idsInDB.GetAt(++m_dbIndex);
}
if (idInDBToCheck == key)
m_dbIndex++;
}
return 0;
}
int nsNNTPArticleList::FinishAddingArticleKeys()
{
// make sure none of the deleted turned up on the idsOnServer list
#ifdef DEBUG_bienvenu
for (int32 i = 0; i < m_idsDeleted.GetSize(); i++)
XP_ASSERT (!m_idsOnServer.set->IsMember(m_idsDeleted.GetAt(i)));
#endif
return 0;
}

View File

@@ -0,0 +1,695 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* formerly listngst.cpp
* This class should ultimately be part of a news group listing
* state machine - either by inheritance or delegation.
* Currently, a folder pane owns one and libnet news group listing
* related messages get passed to this object.
*/
#ifdef HAVE_PANES
class MSG_Master;
#endif
#ifdef HAVE_NEWSDB
class NewsGroupDB;
#endif
#ifdef HAVE_DBVIEW
class MessageDBView;
#endif
class msg_NewsArtSet;
#include "nsNNTPNewsgroupList.h"
#ifdef HAVE_NEWSDB
#include "newsdb.h"
#endif
#ifdef HAVE_DBVIEW
#include "msgdbvw.h"
#endif
#include "newsset.h"
#ifdef HAVE_PANES
#include "msgpane.h"
#endif
extern "C"
{
extern int MK_OUT_OF_MEMORY;
extern int MK_DISK_FULL;
extern int MK_HDR_DOWNLOAD_COUNT;
extern int MK_NO_NEW_DISC_MSGS;
}
// This class should ultimately be part of a news group listing
// state machine - either by inheritance or delegation.
// Currently, a folder pane owns one and libnet news group listing
// related messages get passed to this object.
class nsNNTPNewsgroupList : public nsIMsgNewsArticleList
#ifdef HAVE_CHANGELISTENER
,public ChangeListener
#endif
{
public:
nsNNTPNewsgroupList();
~nsNNTPNewsgroupList();
// nsIMsgNewsArticleList
NS_IMETHOD GetRangeOfArtsToDownload(MSG_NewsHost* host,
const char* group_name,
int32 first_possible,
int32 last_possible,
int32 maxextra,
int32* first,
int32* lastprotected);
NS_IMETHOD AddToKnownArticles(MSG_NewsHost* host,
const char* group_name,
int32 first, int32 last);
// nsIMsgXOVERParser
NS_IMETHOD InitXOVER(MSG_NewsHost* host,
const char *group_name,
uint32 first_msg, uint32 last_msg,
uint32 oldest_msg, uint32 youngest_msg);
NS_IMETHOD ProcessXOVER(char *line);
NS_IMETHOD ResetXOVER();
NS_IMETHOD ProcessNonXOVER(char *line);
NS_IMETHOD FinishXOVER(int status);
MSG_Master *GetMaster() {return m_master;}
void SetMaster(MSG_Master *master) {m_master = master;}
#ifdef HAVE_DBVIEW
void SetView(MessageDBView *view);
#endif
#ifdef HAVE_PANES
void SetPane(MSG_Pane *pane) {m_pane = pane;}
#endif
PRBool m_finishingXover;
MSG_NewsHost* GetHost() {return m_host;}
const char * GetGroupName() {return m_groupName;}
const char * GetURL() {return m_url;}
#ifdef HAVE_CHANGELISTENER
virtual void OnAnnouncerGoingAway (ChangeAnnouncer *instigator);
#endif
void SetGetOldMessages(XP_Bool getOldMessages) {m_getOldMessages = getOldMessages;}
XP_Bool GetGetOldMessages() {return m_getOldMessages;}
protected:
#ifdef HAVE_NEWSDB
NewsGroupDB *m_newsDB;
#endif
#ifdef HAVE_DBVIEW
MessageDBView *m_msgDBView; // open view on current download, if any
#endif
#ifdef HAVE_PANES
MSG_Pane *m_pane;
#endif
XP_Bool m_startedUpdate;
XP_Bool m_getOldMessages;
XP_Bool m_promptedAlready;
XP_Bool m_downloadAll;
int32 m_maxArticles;
char *m_groupName;
MSG_NewsHost *m_host;
char *m_url; // url we're retrieving
MSG_Master *m_master;
MessageKey m_lastProcessedNumber;
MessageKey m_firstMsgNumber;
MessageKey m_lastMsgNumber;
int32 m_firstMsgToDownload;
int32 m_lastMsgToDownload;
struct MSG_NewsKnown m_knownArts;
msg_NewsArtSet *m_set;
};
nsNNTPNewsgroupList::nsNNTPNewsgroupList()
{
NS_INIT_REFCNT();
}
nsNNTPNewsgroupList::~nsNNTPNewsgroupList()
{
}
NS_IMPL_ADDREF(nsNNTPNewsgroupList);
NS_IMPL_RELEASE(nsNNTPNewsgroupList);
NS_IMPL_QUERYINTERFACE(nsNNTPNewsgroupList);
nsNNTPNewsgroupList::InitnsNNTPNewsgroupList(const char *url, const char *groupName, MSG_Pane *pane);
{
#ifdef HAVE_NEWSDB
m_newsDB = NULL;
#endif
#ifdef HAVE_DBVIEW
m_msgDBView = NULL;
#endif
m_groupName = XP_STRDUP(groupName);
m_host = NULL;
m_url = XP_STRDUP(url);
m_lastProcessedNumber = 0;
m_lastMsgNumber = 0;
m_set = NULL;
#ifdef HAVE_PANES
XP_ASSERT(pane);
m_pane = pane;
m_master = pane->GetMaster();
#endif
m_finishingXover = PR_FALSE;
m_startedUpdate = FALSE;
XP_MEMSET(&m_knownArts, 0, sizeof(m_knownArts));
m_knownArts.group_name = m_groupName;
char* host_and_port = NET_ParseURL(url, GET_HOST_PART);
m_host = m_master->FindHost(host_and_port,
(url[0] == 's' || url[0] == 'S'),
-1);
FREEIF(host_and_port);
m_knownArts.host = m_host;
m_getOldMessages = FALSE;
m_promptedAlready = FALSE;
m_downloadAll = FALSE;
m_maxArticles = 0;
m_firstMsgToDownload = 0;
m_lastMsgToDownload = 0;
}
nsNNTPNewsgroupList::~nsNNTPNewsgroupList()
{
XP_FREE(m_url);
XP_FREE(m_groupName);
#ifdef HAVE_DBVIEW
if (m_msgDBView != NULL)
m_msgDBView->Remove(this);
#endif
#ifdef HAVE_NEWSDB
if (m_newsDB)
m_newsDB->Close();
#endif
delete m_knownArts.set;
}
void nsNNTPNewsgroupList::SetView(MessageDBView *view)
{
#ifdef HAVE_DBVIEW
m_msgDBView = view;
if (view)
view->Add(this);
#endif
}
#ifdef HAVE_CHANGELISTENER
void nsNNTPNewsgroupList::OnAnnouncerGoingAway (ChangeAnnouncer *instigator)
{
#ifdef HAVE_DBVIEW
if (m_msgDBView != NULL)
{
m_msgDBView->Remove(this);
m_msgDBView->NotifyAnnouncerGoingAway(instigator); // shout it to the world!
m_msgDBView = NULL;
}
#endif
}
#endif
int nsNNTPNewsgroupList::GetRangeOfArtsToDownload(MSG_NewsHost* host,
const char* group_name,
int32 first_possible,
int32 last_possible,
int32 maxextra,
int32* first,
int32* last)
{
int status = 0;
XP_Bool emptyGroup_p = FALSE;
MsgERR err;
XP_ASSERT(first && last);
if (!first || !last) return -1;
*first = 0;
*last = 0;
#ifdef HAVE_PANES
if (m_pane != NULL && !m_finishingXover && !m_startedUpdate)
{
m_startedUpdate = TRUE;
m_pane->StartingUpdate(MSG_NotifyNone, 0, 0);
}
#endif
#ifdef HAVE_NEWSDB
if (!m_newsDB)
{
if ((err = NewsGroupDB::Open(m_url, m_master, &m_newsDB)) != eSUCCESS)
return ConvertMsgErrToMKErr(err);
else
{
m_set = m_newsDB->GetNewsArtSet();
m_set->SetLastMember(last_possible); // make sure highwater mark is valid.
NewsFolderInfo *newsGroupInfo = m_newsDB->GetNewsFolderInfo();
if (newsGroupInfo)
{
ENeoString knownArtsString;
newsGroupInfo->GetKnownArtsSet(knownArtsString);
if (last_possible < newsGroupInfo->GetHighWater())
newsGroupInfo->SetHighWater(last_possible, TRUE);
m_knownArts.set = msg_NewsArtSet::Create(knownArtsString);
}
else
{
m_knownArts.set = msg_NewsArtSet::Create();
m_knownArts.set->AddRange(m_newsDB->GetLowWaterArticleNum(), m_newsDB->GetHighwaterArticleNum());
}
#ifdef HAVE_PANES
m_pane->StartingUpdate(MSG_NotifyNone, 0, 0);
m_newsDB->ExpireUpTo(first_possible, m_pane->GetContext());
m_pane->EndingUpdate(MSG_NotifyNone, 0, 0);
#endif
if (m_knownArts.set->IsMember(last_possible)) // will this be progress pane?
{
char *noNewMsgs = XP_GetString(MK_NO_NEW_DISC_MSGS);
#ifdef HAVE_PANES
MWContext *context = m_pane->GetContext();
MSG_Pane* parentpane = m_pane->GetParentPane();
// send progress to parent pane, if any, because progress pane is going down.
if (parentpane)
context = parentpane->GetContext();
FE_Progress (context, noNewMsgs);
#endif
}
}
}
#endif
if (maxextra <= 0 || last_possible < first_possible || last_possible < 1)
{
emptyGroup_p = TRUE;
}
if (m_knownArts.host != host ||
m_knownArts.group_name == NULL ||
XP_STRCMP(m_knownArts.group_name, group_name) != 0 ||
!m_knownArts.set)
{
/* We're displaying some other group. Clear out that display, and set up
everything to return the proper first chunk. */
XP_ASSERT(FALSE); // ### dmb todo - need nwo way of doing this
if (emptyGroup_p)
return 0;
}
else
{
if (emptyGroup_p)
return 0;
}
m_knownArts.first_possible = first_possible;
m_knownArts.last_possible = last_possible;
/* Determine if we only want to get just new articles or more messages.
If there are new articles at the end we haven't seen, we always want to get those first.
Otherwise, we get the newest articles we haven't gotten, if we're getting more.
My thought for now is that opening a newsgroup should only try to get new articles.
Selecting "More Messages" will first try to get unseen messages, then old messages. */
if (m_getOldMessages || !m_knownArts.set->IsMember(last_possible))
{
#ifdef HAVE_PANES
XP_Bool notifyMaxExceededOn = (m_pane && !m_finishingXover && m_pane->GetPrefs() && m_pane->GetPrefs()->GetNewsNotifyOn());
#else
XP_Bool notifyMaxExceededOn = FALSE;
#endif
// if the preference to notify when downloading more than x headers is not on,
// and we're downloading new headers, set maxextra to a very large number.
if (!m_getOldMessages && !notifyMaxExceededOn)
maxextra = 0x7FFFFFFFL;
status = m_knownArts.set->LastMissingRange(first_possible, last_possible,
first, last);
if (status < 0)
return status;
if (*first > 0 && *last - *first >= maxextra)
{
if (!m_getOldMessages && !m_promptedAlready && notifyMaxExceededOn)
{
#ifdef HAVE_PANES
MSG_FolderInfoNews *newsFolder = m_pane->GetMaster()->FindNewsFolder(m_host, m_groupName, FALSE);
XP_Bool result = FE_NewsDownloadPrompt(m_pane->GetContext(),
*last - *first + 1,
&m_downloadAll, newsFolder);
#endif
if (result)
{
m_maxArticles = 0;
PREF_GetIntPref("news.max_articles", &m_maxArticles);
NET_SetNumberOfNewsArticlesInListing(m_maxArticles);
maxextra = m_maxArticles;
if (!m_downloadAll)
{
XP_Bool markOldRead = FALSE;
PREF_GetBoolPref("news.mark_old_read", &markOldRead);
if (markOldRead && m_set)
m_set->AddRange(*first, *last - maxextra);
*first = *last - maxextra + 1;
}
}
else
*first = *last = 0;
m_promptedAlready = TRUE;
}
else if (m_promptedAlready && !m_downloadAll)
*first = *last - m_maxArticles + 1;
else if (!m_downloadAll)
*first = *last - maxextra + 1;
}
}
#ifdef DEBUG_bienvenu
XP_Trace("GetRangeOfArtsToDownload(first possible = %ld, last possible = %ld, first = %ld, last = %ld maxextra = %ld\n",
first_possible, last_possible, *first, *last, maxextra);
#endif
m_firstMsgToDownload = *first;
m_lastMsgToDownload = *last;
return 0;
}
int nsNNTPNewsgroupList::AddToKnownArticles(MSG_NewsHost* host,
const char* group_name,
int32 first, int32 last)
{
int status;
if (m_knownArts.host != host ||
m_knownArts.group_name == NULL ||
XP_STRCMP(m_knownArts.group_name, group_name) != 0 ||
!m_knownArts.set)
{
m_knownArts.host = host;
FREEIF(m_knownArts.group_name);
m_knownArts.group_name = XP_STRDUP(group_name);
delete m_knownArts.set;
m_knownArts.set = msg_NewsArtSet::Create();
if (!m_knownArts.group_name || !m_knownArts.set) {
return MK_OUT_OF_MEMORY;
}
}
status = m_knownArts.set->AddRange(first, last);
#ifdef HAVE_NEWSDB
if (m_newsDB)
{
NeoDBStack dbStack(m_newsDB->GetDB());
NewsFolderInfo *newsGroupInfo = m_newsDB->GetNewsFolderInfo();
if (newsGroupInfo)
{
char *output = m_knownArts.set->Output();
if (output)
newsGroupInfo->SetKnownArtsSet(output);
delete[] output;
}
}
#endif
return status;
}
nsIM
nsresult
nsNNTPNewsgroupList::InitXOVER(MSG_NewsHost* /*host*/,
const char * /*group_name*/,
uint32 first_msg, uint32 last_msg,
uint32 /*oldest_msg*/, uint32 /*youngest_msg*/)
{
int status = 0;
// Tell the FE to show the GetNewMessages progress dialog
#ifdef HAVE_PANES
FE_PaneChanged (m_pane, FALSE, MSG_PanePastPasswordCheck, 0);
#endif
/* Consistency checks, not that I know what to do if it fails (it will
probably handle it OK...) */
XP_ASSERT(first_msg <= last_msg);
/* If any XOVER lines from the last time failed to come in, mark those
messages as read. */
if (m_lastProcessedNumber < m_lastMsgNumber)
{
m_set->AddRange(m_lastProcessedNumber + 1, m_lastMsgNumber);
}
m_firstMsgNumber = first_msg;
m_lastMsgNumber = last_msg;
m_lastProcessedNumber = first_msg > 1 ? first_msg - 1 : 1;
return status;
}
#define NEWS_ART_DISPLAY_FREQ 10
nsresult
nsNNTPNewsgroupList::ProcessXOVER(char *line)
{
int status = 0;
char *next;
uint32 message_number;
// int32 lines;
XP_Bool read_p = FALSE;
XP_ASSERT (line);
if (!line)
return -1;
#ifdef HAVE_DBVIEW
if (m_msgDBView != NULL)
{
status = ConvertMsgErrToMKErr( m_msgDBView->AddHdrFromServerLine(line, &message_number));
if (status < 0)
{
#ifdef HAVE_PANES
if (status == MK_DISK_FULL || status == MK_OUT_OF_MEMORY)
FE_Alert(m_pane->GetContext(), XP_GetString(status));
#endif
return status;
}
}
else
#endif
#ifdef HAVE_NEWSDB
if (m_newsDB != NULL)
{
status = ConvertMsgErrToMKErr(m_newsDB->AddHdrFromXOver(line, &message_number));
}
else
return -1;
#endif
next = line;
XP_ASSERT(message_number > m_lastProcessedNumber ||
message_number == 1);
if (m_set && message_number > m_lastProcessedNumber + 1)
{
/* There are some articles that XOVER skipped; they must no longer
exist. Mark them as read in the newsrc, so we don't include them
next time in our estimated number of unread messages. */
if (m_set->AddRange(m_lastProcessedNumber + 1, message_number - 1))
{
/* This isn't really an important enough change to warrant causing
the newsrc file to be saved; we haven't gathered any information
that won't also be gathered for free next time.
*/
}
}
m_lastProcessedNumber = message_number;
if (m_knownArts.set)
{
status = m_knownArts.set->Add(message_number);
if (status < 0) return status;
}
if (message_number > m_lastMsgNumber)
m_lastMsgNumber = message_number;
else if (message_number < m_firstMsgNumber)
m_firstMsgNumber = message_number;
if (m_set) {
read_p = m_set->IsMember(message_number);
}
/* Update the thermometer with a percentage of articles retrieved.
*/
if (m_lastMsgNumber > m_firstMsgNumber)
{
int32 totToDownload = m_lastMsgToDownload - m_firstMsgToDownload;
int32 lastIndex = m_lastProcessedNumber - m_firstMsgNumber + 1;
int32 numDownloaded = lastIndex;
int32 totIndex = m_lastMsgNumber - m_firstMsgNumber + 1;
int32 percent = (totIndex) ? (int32)(100.0 * (double)numDownloaded / (double)totToDownload) : 0;
#ifdef HAVE_PANES
FE_SetProgressBarPercent (m_pane->GetContext(), percent);
#endif
/* only update every 10 articles for speed */
if ( (totIndex <= NEWS_ART_DISPLAY_FREQ) || ((lastIndex % NEWS_ART_DISPLAY_FREQ) == 0) || (lastIndex == totIndex))
{
char *statusTemplate = XP_GetString (MK_HDR_DOWNLOAD_COUNT);
char *statusString = PR_smprintf (statusTemplate, numDownloaded, totToDownload);
#ifdef HAVE_PANES
FE_Progress (m_pane->GetContext(), statusString);
#endif
XP_FREE(statusString);
}
}
return status;
}
nsresult
nsNNTPNewsgroupList::XOVERReset()
{
m_lastMsgNumber = m_firstMsgNumber;
m_lastProcessedNumber = m_lastMsgNumber;
return 0;
}
/* When we don't have XOVER, but use HEAD, this is called instead.
It reads lines until it has a whole header block, then parses the
headers; then takes selected headers and creates an XOVER line
from them. This is more for simplicity and code sharing than
anything else; it means we end up parsing some things twice.
But if we don't have XOVER, things are going to be so horribly
slow anyway that this just doesn't matter.
*/
nsresult
nsNNTPNewsgroupList::ProcessNonXOVER (char * /*line*/)
{
// ### dmb write me
int status = 0;
return status;
}
nsresult
nsNNTPNewsgroupList::FinishXOVER (int status)
{
struct MSG_NewsKnown* k;
/* If any XOVER lines from the last time failed to come in, mark those
messages as read. */
if (status >= 0 && m_lastProcessedNumber < m_lastMsgNumber)
{
m_set->AddRange(m_lastProcessedNumber + 1, m_lastMsgNumber);
}
#ifdef HAVE_DBVIEW
if (m_msgDBView != NULL)
{
// we should think about not doing this if status != MK_INTERRUPTED, but we'd need to still clean up the view.
m_msgDBView->AddNewMessages();
m_msgDBView->Remove(this);
m_msgDBView = NULL;
}
#endif
#ifdef HAVE_NEWSDB
if (m_newsDB)
{
m_newsDB->Close();
m_newsDB = NULL;
}
#endif
k = &m_knownArts;
if (k->set)
{
int32 n = k->set->FirstNonMember();
if (n < k->first_possible || n > k->last_possible)
{
/* We know we've gotten all there is to know. Take advantage of that to
update our counts... */
// ### dmb
}
}
if (m_finishingXover)
{
// turn on m_finishingXover - this is a horrible hack to avoid recursive
// calls which happen when the fe selects a message as a result of getting EndingUpdate,
// which interrupts this url right before it was going to finish and causes FinishXOver
// to get called again.
m_finishingXover = TRUE;
// if we haven't started an update, start one so the fe
// will know to update the size of the view.
if (!m_startedUpdate)
{
#ifdef HAVE_PANES
m_pane->StartingUpdate(MSG_NotifyNone, 0, 0);
#endif
m_startedUpdate = TRUE;
}
#ifdef HAVE_PANES
m_pane->EndingUpdate(MSG_NotifyNone, 0, 0);
#endif
m_startedUpdate = FALSE;
if (m_lastMsgNumber > 0)
{
#ifdef HAVE_PANES
MWContext *context = m_pane->GetContext();
MSG_Pane* parentpane = m_pane->GetParentPane();
// send progress to parent pane, if any, because progress pane is going down.
if (parentpane)
context = parentpane->GetContext();
char *statusTemplate = XP_GetString (MK_HDR_DOWNLOAD_COUNT);
char *statusString = PR_smprintf (statusTemplate, m_lastProcessedNumber - m_firstMsgNumber + 1, m_lastMsgNumber - m_firstMsgNumber + 1);
if (statusString)
{
FE_Progress (context, statusString);
XP_FREE(statusString);
}
#endif
}
MSG_FolderInfoNews *newsFolder = NULL;
#ifdef HAVE_PANES
newsFolder = (m_pane) ? savePane->GetMaster()->FindNewsFolder(m_host, m_groupName, FALSE) : 0;
FE_PaneChanged(m_pane, FALSE, MSG_PaneNotifyFolderLoaded, (uint32)newsFolder);
#endif
}
return 0;
// nsNNTPNewsgroupList object gets deleted by the master when a new one is created.
}

View File

@@ -0,0 +1,64 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* formerly listngst.h
* This class should ultimately be part of a news group listing
* state machine - either by inheritance or delegation.
* Currently, a folder pane owns one and libnet news group listing
* related messages get passed to this object.
*/
#ifndef nsNNTPNewsgroupListState_h___
#define nsNNTPNewsgroupListState_h___
/* The below is all stuff that we remember for netlib about which
articles we've already seen in the current newsgroup. */
typedef struct MSG_NewsKnown {
MSG_NewsHost* host;
char* group_name;
msg_NewsArtSet* set; /* Set of articles we've already gotten
from the newsserver (if it's marked
"read", then we've already gotten it).
If an article is marked "read", it
doesn't mean we're actually displaying
it; it may be an article that no longer
exists, or it may be one that we've
marked read and we're only viewing
unread messages. */
int32 first_possible; /* The oldest article in this group. */
int32 last_possible; /* The newest article in this group. */
XP_Bool shouldGetOldest;
} MSG_NewsKnown;
extern NS_COM nsresult
NS_NewMsgXOVERParser(nsIMsgXOVERParser **aInstancePtrResult,
nsIMsgNewsHost *newsHost,
PRInt32 m_firstArticle,
PRInt32 m_lastArticle,
PRInt32 m_firstPossibleArticle,
PRInt32 m_lastPossibleArticle);
extern NS_COM nsresult
NS_NewMsgNewsArticleList(nsIMsgNewsArticleList **aInstancePtrResult,
nsIMsgNewsHost *newsHost,
nsIMsgNewsgroup *newsgroup);
#endif