|
|
|
/*
|
|
|
|
KNode, the KDE newsreader
|
|
|
|
Copyright (c) 1999-2005 the KNode authors.
|
|
|
|
See file AUTHORS for details
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software Foundation,
|
|
|
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, US
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef KNARTICLE_H
|
|
|
|
#define KNARTICLE_H
|
|
|
|
|
|
|
|
#include <tqstringlist.h>
|
|
|
|
#include <textstream.h>
|
|
|
|
#include <tqfile.h>
|
|
|
|
#include <tqfont.h>
|
|
|
|
#include <tqcolor.h>
|
|
|
|
#include <tqasciidict.h>
|
|
|
|
#include <tqvaluelist.h>
|
|
|
|
|
|
|
|
#include <kmime_headers.h>
|
|
|
|
#include <kmime_newsarticle.h>
|
|
|
|
#include <boolflags.h>
|
|
|
|
|
|
|
|
#include "knjobdata.h"
|
|
|
|
|
|
|
|
//forward declarations
|
|
|
|
class KNLoadHelper;
|
|
|
|
class KNHdrViewItem;
|
|
|
|
class KNArticleCollection;
|
|
|
|
|
|
|
|
/** This class encapsulates a generic article. It provides all the
|
|
|
|
usual headers of a RFC822-message. Further more it contains an
|
|
|
|
unique id and can store a pointer to a @ref TQListViewItem. It is
|
|
|
|
used as a base class for all visible articles. */
|
|
|
|
|
|
|
|
class KNArticle : public KMime::NewsArticle, public KNJobItem {
|
|
|
|
|
|
|
|
public:
|
|
|
|
typedef TQValueList<KNArticle*> List;
|
|
|
|
|
|
|
|
KNArticle(KNArticleCollection *c);
|
|
|
|
~KNArticle();
|
|
|
|
|
|
|
|
//id
|
|
|
|
int id() const { return i_d; }
|
|
|
|
void setId(int i) { i_d=i; }
|
|
|
|
|
|
|
|
//list item handling
|
|
|
|
KNHdrViewItem* listItem() const { return i_tem; }
|
|
|
|
void setListItem(KNHdrViewItem *i);
|
|
|
|
virtual void updateListItem() {}
|
|
|
|
|
|
|
|
//network lock (reimplemented from KNJobItem)
|
|
|
|
bool isLocked() { return f_lags.get(0); }
|
|
|
|
void setLocked(bool b=true);
|
|
|
|
|
|
|
|
//prevent that the article is unloaded automatically
|
|
|
|
bool isNotUnloadable() { return f_lags.get(1); }
|
|
|
|
void setNotUnloadable(bool b=true) { f_lags.set(1, b); }
|
|
|
|
|
|
|
|
//article-collection
|
|
|
|
KNArticleCollection* collection() const { return c_ol; }
|
|
|
|
void setCollection(KNArticleCollection *c) { c_ol=c; }
|
|
|
|
bool isOrphant() const { return (i_d==-1); }
|
|
|
|
|
|
|
|
protected:
|
|
|
|
int i_d; //unique in the given collection
|
|
|
|
KNArticleCollection *c_ol;
|
|
|
|
KNHdrViewItem *i_tem;
|
|
|
|
|
|
|
|
}; // KNArticle
|
|
|
|
|
|
|
|
|
|
|
|
class KNGroup;
|
|
|
|
|
|
|
|
/** KNRemoteArticle represents an article, whos body has to be
|
|
|
|
retrieved from a remote host or from the local cache.
|
|
|
|
All articles in a newsgroup are stored in instances
|
|
|
|
of this class. */
|
|
|
|
|
|
|
|
class KNRemoteArticle : public KNArticle {
|
|
|
|
|
|
|
|
public:
|
|
|
|
typedef TQValueList<KNRemoteArticle*> List;
|
|
|
|
|
|
|
|
KNRemoteArticle(KNGroup *g);
|
|
|
|
~KNRemoteArticle();
|
|
|
|
|
|
|
|
// type
|
|
|
|
articleType type() { return ATremote; }
|
|
|
|
|
|
|
|
// content handling
|
|
|
|
virtual void parse();
|
|
|
|
virtual void assemble() {} //assembling is disabled for remote articles
|
|
|
|
virtual void clear();
|
|
|
|
|
|
|
|
// header access
|
|
|
|
KMime::Headers::Base* getHeaderByType(const char *type);
|
|
|
|
void setHeader(KMime::Headers::Base *h);
|
|
|
|
bool removeHeader(const char *type);
|
|
|
|
KMime::Headers::MessageID* messageID(bool create=true) { if(!create && m_essageID.isEmpty()) return 0; return &m_essageID; }
|
|
|
|
KMime::Headers::From* from(bool create=true) { if(!create && f_rom.isEmpty()) return 0; return &f_rom; }
|
|
|
|
KMime::Headers::References* references(bool create=true) { if(!create && r_eferences.isEmpty()) return 0; return &r_eferences; }
|
|
|
|
|
|
|
|
// article number
|
|
|
|
int articleNumber() const { return a_rticleNumber; }
|
|
|
|
void setArticleNumber(int number) { a_rticleNumber = number; }
|
|
|
|
|
|
|
|
// status
|
|
|
|
bool isNew() { return f_lags.get(2); }
|
|
|
|
void setNew(bool b=true) { f_lags.set(2, b); }
|
|
|
|
bool getReadFlag() { return f_lags.get(3); }
|
|
|
|
bool isRead() { return f_lags.get(7) || f_lags.get(3); } // ignored articles == read
|
|
|
|
void setRead(bool b=true) { f_lags.set(3, b); }
|
|
|
|
bool isExpired() { return f_lags.get(4); }
|
|
|
|
void setExpired(bool b=true) { f_lags.set(4, b); }
|
|
|
|
bool isKept() { return f_lags.get(5); }
|
|
|
|
void setKept(bool b=true) { f_lags.set(5, b); }
|
|
|
|
bool hasChanged() { return f_lags.get(6); }
|
|
|
|
void setChanged(bool b=true) { f_lags.set(6, b); }
|
|
|
|
bool isIgnored() { return f_lags.get(7); }
|
|
|
|
void setIgnored(bool b=true) { f_lags.set(7, b); }
|
|
|
|
bool isWatched() { return f_lags.get(8); }
|
|
|
|
void setWatched(bool b=true) { f_lags.set(8, b); }
|
|
|
|
|
|
|
|
// thread info
|
|
|
|
int idRef() { return i_dRef; }
|
|
|
|
void setIdRef(int i) { if (i != id())
|
|
|
|
i_dRef=i;
|
|
|
|
else
|
|
|
|
i_dRef=0; }
|
|
|
|
KNRemoteArticle* displayedReference() { return d_ref; }
|
|
|
|
void setDisplayedReference(KNRemoteArticle *dr) { d_ref=dr; }
|
|
|
|
bool threadMode() { return f_lags.get(9); }
|
|
|
|
void setThreadMode(bool b=true) { f_lags.set(9, b); }
|
|
|
|
unsigned char threadingLevel() { return t_hrLevel; }
|
|
|
|
void setThreadingLevel(unsigned char l) { t_hrLevel=l; }
|
|
|
|
short score() { return s_core; }
|
|
|
|
void setScore(short s) { s_core=s; }
|
|
|
|
unsigned short newFollowUps() { return n_ewFups; }
|
|
|
|
bool hasNewFollowUps() { return (n_ewFups>0); }
|
|
|
|
void setNewFollowUps(unsigned short s) { n_ewFups=s; }
|
|
|
|
void incNewFollowUps(unsigned short s=1) { n_ewFups+=s; }
|
|
|
|
void decNewFollowUps(unsigned short s=1) { n_ewFups-=s; }
|
|
|
|
unsigned short unreadFollowUps() { return u_nreadFups; }
|
|
|
|
bool hasUnreadFollowUps() { return (u_nreadFups>0); }
|
|
|
|
void setUnreadFollowUps(unsigned short s) { u_nreadFups=s; }
|
|
|
|
void incUnreadFollowUps(unsigned short s=1) { u_nreadFups+=s; }
|
|
|
|
void decUnreadFollowUps(unsigned short s=1) { u_nreadFups-=s; }
|
|
|
|
void thread(List &f);
|
|
|
|
|
|
|
|
//filtering
|
|
|
|
bool filterResult() { return f_lags.get(10); }
|
|
|
|
void setFilterResult(bool b=true) { f_lags.set(10, b); }
|
|
|
|
bool isFiltered() { return f_lags.get(11); }
|
|
|
|
void setFiltered(bool b=true) { f_lags.set(11, b); }
|
|
|
|
bool hasVisibleFollowUps() { return f_lags.get(12); }
|
|
|
|
void setVisibleFollowUps(bool b=true) { f_lags.set(12, b); }
|
|
|
|
|
|
|
|
// list item handling
|
|
|
|
void initListItem();
|
|
|
|
void updateListItem();
|
|
|
|
|
|
|
|
void setForceDefaultCS(bool b);
|
|
|
|
|
|
|
|
TQColor color() const { return c_olor; }
|
|
|
|
void setColor(const TQColor& c) { c_olor = c; }
|
|
|
|
|
|
|
|
time_t subThreadChangeDate() { return s_ubThreadChangeDate; }
|
|
|
|
void setSubThreadChangeDate(time_t date) { s_ubThreadChangeDate = date; }
|
|
|
|
// propagate the change date to the root article
|
|
|
|
void propagateThreadChangedDate();
|
|
|
|
|
|
|
|
protected:
|
|
|
|
// hardcoded headers
|
|
|
|
KMime::Headers::MessageID m_essageID;
|
|
|
|
KMime::Headers::From f_rom;
|
|
|
|
KMime::Headers::References r_eferences;
|
|
|
|
|
|
|
|
int a_rticleNumber;
|
|
|
|
int i_dRef; // id of a reference-article (0 == none)
|
|
|
|
KNRemoteArticle *d_ref; // displayed reference-article (may differ from i_dRef)
|
|
|
|
unsigned char t_hrLevel; // quality of threading
|
|
|
|
short s_core; // guess what ;-)
|
|
|
|
TQColor c_olor; // color for the header list
|
|
|
|
unsigned short u_nreadFups, // number of the article's unread follow-ups
|
|
|
|
n_ewFups; // number of the article's new follow-ups
|
|
|
|
time_t s_ubThreadChangeDate; // the last time the sub-thread of this article changed
|
|
|
|
// i.e. when the last article arrived...
|
|
|
|
|
|
|
|
}; // KNRemoteArticle
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* This class encapsulates an article, that is
|
|
|
|
stored locally in an MBOX-file. All own and
|
|
|
|
saved articles are represented by instances
|
|
|
|
of this class. */
|
|
|
|
|
|
|
|
|
|
|
|
class KNLocalArticle : public KNArticle {
|
|
|
|
|
|
|
|
public:
|
|
|
|
typedef TQValueList<KNLocalArticle*> List;
|
|
|
|
|
|
|
|
KNLocalArticle(KNArticleCollection *c=0);
|
|
|
|
~KNLocalArticle();
|
|
|
|
|
|
|
|
//type
|
|
|
|
articleType type() { return ATlocal; }
|
|
|
|
|
|
|
|
//content handling
|
|
|
|
void parse();
|
|
|
|
void clear();
|
|
|
|
|
|
|
|
// header access
|
|
|
|
KMime::Headers::Base* getHeaderByType(const char *type);
|
|
|
|
void setHeader(KMime::Headers::Base *h);
|
|
|
|
bool removeHeader(const char *type);
|
|
|
|
KMime::Headers::Newsgroups* newsgroups(bool create=true) { if ( (!create && n_ewsgroups.isEmpty()) ||
|
|
|
|
(!create && !isSavedRemoteArticle() && !doPost()) )
|
|
|
|
return 0;
|
|
|
|
return &n_ewsgroups; }
|
|
|
|
KMime::Headers::To* to(bool create=true) { if ( (!create && t_o.isEmpty()) ||
|
|
|
|
(!create && !isSavedRemoteArticle() && !doMail()) )
|
|
|
|
return 0;
|
|
|
|
return &t_o; }
|
|
|
|
|
|
|
|
//send article as mail
|
|
|
|
bool doMail() { return f_lags.get(2); }
|
|
|
|
void setDoMail(bool b=true) { f_lags.set(2, b); }
|
|
|
|
bool mailed() { return f_lags.get(3); }
|
|
|
|
void setMailed(bool b=true) { f_lags.set(3, b); }
|
|
|
|
|
|
|
|
//post article to a newsgroup
|
|
|
|
bool doPost() { return f_lags.get(4); }
|
|
|
|
void setDoPost(bool b=true) { f_lags.set(4, b); }
|
|
|
|
bool posted() { return f_lags.get(5); }
|
|
|
|
void setPosted(bool b=true) { f_lags.set(5, b); }
|
|
|
|
bool canceled() { return f_lags.get(6); }
|
|
|
|
void setCanceled(bool b=true) { f_lags.set(6, b); }
|
|
|
|
|
|
|
|
// status
|
|
|
|
bool pending() { return ( (doPost() && !posted()) || (doMail() && !mailed()) ); }
|
|
|
|
bool isSavedRemoteArticle() { return ( !doPost() && !doMail() && editDisabled() ); }
|
|
|
|
|
|
|
|
//edit
|
|
|
|
bool editDisabled() { return f_lags.get(7); }
|
|
|
|
void setEditDisabled(bool b=true) { f_lags.set(7, b); }
|
|
|
|
|
|
|
|
//search
|
|
|
|
bool filterResult() { return f_lags.get(8); }
|
|
|
|
void setFilterResult(bool b=true) { f_lags.set(8, b); }
|
|
|
|
|
|
|
|
//MBOX infos
|
|
|
|
int startOffset() const { return s_Offset; }
|
|
|
|
void setStartOffset(int so) { s_Offset=so; }
|
|
|
|
int endOffset() const { return e_Offset; }
|
|
|
|
void setEndOffset(int eo) { e_Offset=eo; }
|
|
|
|
|
|
|
|
//nntp-server id
|
|
|
|
int serverId() { if(!doPost()) return -1; else return s_erverId; }
|
|
|
|
void setServerId(int i) { s_erverId=i; }
|
|
|
|
|
|
|
|
//list item handling
|
|
|
|
void updateListItem();
|
|
|
|
|
|
|
|
void setForceDefaultCS(bool b);
|
|
|
|
|
|
|
|
protected:
|
|
|
|
//hardcoded headers
|
|
|
|
KMime::Headers::Newsgroups n_ewsgroups;
|
|
|
|
KMime::Headers::To t_o;
|
|
|
|
int s_Offset, //position in mbox-file : start
|
|
|
|
e_Offset, //position in mbox-file : end
|
|
|
|
s_erverId; //id of the nntp-server this article is posted to
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* KNAttachment represents a file that is
|
|
|
|
or will be attached to an article. */
|
|
|
|
|
|
|
|
class KNAttachment {
|
|
|
|
|
|
|
|
public:
|
|
|
|
KNAttachment(KMime::Content *c);
|
|
|
|
KNAttachment(KNLoadHelper *helper);
|
|
|
|
~KNAttachment();
|
|
|
|
|
|
|
|
//name (used as a Content-Type parameter and as filename)
|
|
|
|
const TQString& name() { return n_ame; }
|
|
|
|
void setName(const TQString &s) { n_ame=s; h_asChanged=true; }
|
|
|
|
|
|
|
|
//mime type
|
|
|
|
const TQCString& mimeType() { return m_imeType; }
|
|
|
|
void setMimeType(const TQString &s);
|
|
|
|
|
|
|
|
//Content-Description
|
|
|
|
const TQString& description() { return d_escription; }
|
|
|
|
void setDescription(const TQString &s) { d_escription=s; h_asChanged=true; }
|
|
|
|
|
|
|
|
//Encoding
|
|
|
|
int cte() { return e_ncoding.cte(); }
|
|
|
|
void setCte(int e) { e_ncoding.setCte( (KMime::Headers::contentEncoding)(e) );
|
|
|
|
h_asChanged=true; }
|
|
|
|
bool isFixedBase64()const { return f_b64; }
|
|
|
|
TQString encoding() { return e_ncoding.asUnicodeString(); }
|
|
|
|
|
|
|
|
//content handling
|
|
|
|
KMime::Content* content()const { return c_ontent; }
|
|
|
|
TQString contentSize() const;
|
|
|
|
bool isAttached() const { return i_sAttached; }
|
|
|
|
bool hasChanged() const { return h_asChanged; }
|
|
|
|
void updateContentInfo();
|
|
|
|
void attach(KMime::Content *c);
|
|
|
|
void detach(KMime::Content *c);
|
|
|
|
|
|
|
|
protected:
|
|
|
|
KMime::Content *c_ontent;
|
|
|
|
KNLoadHelper *l_oadHelper;
|
|
|
|
TQFile *f_ile;
|
|
|
|
TQCString m_imeType;
|
|
|
|
TQString n_ame,
|
|
|
|
d_escription;
|
|
|
|
KMime::Headers::CTEncoding e_ncoding;
|
|
|
|
bool i_sAttached,
|
|
|
|
h_asChanged,
|
|
|
|
f_b64;
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif //KNARTICLE_H
|