#include <qregexp.h>
#include <qstringlist.h>
#include <klocale.h>
+#include <dom/html_document.h>
+#include <dom/html_element.h>
+#include <dom/dom_text.h>
#include "datinfo.h"
#include "datmanager.h"
using namespace Kita;
#define KITA_MAXRES 1200
-#define KITA_RESDIGIT 4
/*------------------------------------------------------*/
resetResDat(resdat);
m_resDatVec.clear();
m_resDatVec.resize(KITA_MAXRES,resdat);
+
+ /* reset Abone */
+ resetAbone();
/* create dat loader */
m_access = new Kita::Access( m_thread );
return m_resDatVec[ num ].name;
}
-/* plain (i.e. parsed) strings of body text */
+/* plain (parsed) strings of body */
QString DatInfo::getPlainBody(int num)
{
QMutexLocker locker( &m_mutex );
if(!parseDat(num)) return QString::null;
- QString retstr = QString::null;
+ QString bodytext;
QString line = m_resDatVec[ num ].body;
- QRegExp rex1( " <[Bb][Rr]> " ); /* replace " <br> " with "\n" */
- QRegExp rex2( "<[^>]*>" ); /* remove HTML tags */
- line.replace(rex1,"\n").remove(rex2);
-
- /* replace special char */
- const QChar *chpt = line.unicode();
- unsigned int i,pos,head;
- unsigned int length = line.length();
- QString replacestr;
+ ParseMisc::parseBODYdatText(PARSEMODE_TEXT,line,bodytext);
- for ( i = 0,head = 0 ; i < length ; i++ ) {
-
- if( chpt[ i ] == '&' ){
-
- replacestr = ParseMisc::parseSpecialChar(chpt + i, pos );
- if(replacestr != QString::null){
-
- retstr += line.mid(head, i - head) + replacestr;
-
- head = i + pos;
- i = head -1;
- }
- }
- }
- retstr += line.mid(head, i - head);
-
- return retstr;
+ return bodytext;
}
-/* plain strings of title */
+
+/* plain (parsed) strings of title */
QString DatInfo::getPlainTitle(int num)
{
QMutexLocker locker( &m_mutex );
if(!parseDat(num)) return QString::null;
- QString retstr = linkedAddress(m_resDatVec[ num ], KitaConfig::showMailAddress())
- + " " + getDateId(m_resDatVec[ num ]) ;
-
- /* remove HTML tags */
- QRegExp rex( "<[^>]*>" );
- retstr.remove(rex);
+ bool showAddr = KitaConfig::showMailAddress();
+ QString titletext;
+ ParseMisc::parseTITLEdatText(PARSEMODE_TEXT,num,showAddr,m_resDatVec[ num ],titletext);
- return retstr;
+ return titletext;
}
for(int num = startnum; num <= endnum; num++){
if(!parseDat(num)) continue;
- if(checkAbonePrivate(num)) continue;
-
- retstr += toHtml(m_resDatVec[ num ], num, showAddr );
+ if(checkAbonePrivate(num)) retstr += aboneHTML( num );
+ else if(m_resDatVec[ num ].broken) retstr += brokenHTML( num );
+ else retstr += ParseMisc::ResDatToHtml(m_resDatVec[ num ], num, showAddr );
}
return retstr;
for ( int i = 1; i <= m_maxNum; i++ ){
if(!parseDat(i)) continue;
- if(checkAbonePrivate(i)) continue;
-
+
if(m_resDatVec[i].id == strid){
count ++;
- retstr += toHtml(m_resDatVec[i], i, showAddr);
+ if(checkAbonePrivate(i)) retstr += aboneHTML(i);
+ else if(m_resDatVec[ i ].broken) retstr += brokenHTML(i);
+ else retstr += ParseMisc::ResDatToHtml(m_resDatVec[i], i, showAddr);
}
}
}
+/* private */
+QString DatInfo::aboneHTML(int num){
+
+ QString tmpstr = QString( "<dl><dt>" );
+ tmpstr += QString().setNum( num ) + " " + ParseMisc::utf8ToUnicode( KITAUTF8_ABONE );
+ tmpstr += "</dt><dd>";
+ tmpstr += ParseMisc::utf8ToUnicode( KITAUTF8_ABONE );;
+ tmpstr += "<br/><br/></dd></dl>";
+
+ return tmpstr;
+}
+
+
+/* private */
+QString DatInfo::brokenHTML(int num){
+
+ QString tmpstr = QString( "<dl><dt>" );
+ tmpstr += QString().setNum( num ) + " " + ParseMisc::utf8ToUnicode( KITAUTF8_NAME );
+ tmpstr += "</dt><dd>";
+ tmpstr += ParseMisc::utf8ToUnicode( KITAUTF8_KOWARE );;
+ tmpstr += "<br/><br/></dd></dl>";
+
+ return tmpstr;
+}
+
/*-------------------------------*/
/* Get HTML document of res tree.*/
QString DatInfo::getTreeByRes(const int rootnum, int& count)
{
QMutexLocker locker( &m_mutex );
+ return getTreeByResPrivate(rootnum,FALSE,count);
+}
+
+/*---------------------------------------*/
+/* Get HTML document of reverse res tree.*/
+/* For example, when rootnum = 10,
+
+>>10
+|-->>5
+| |--->>2
+|
+|-->>6, and returns count = 3. */
+
+/* Note that this function checks Abone internally. */ /* public */
+QString DatInfo::getTreeByResReverse(const int rootnum, int& count)
+{
+ QMutexLocker locker( &m_mutex );
+ return getTreeByResPrivate(rootnum,TRUE,count);
+}
+
+
+/* private */
+QString DatInfo::getTreeByResPrivate(
+ const int rootnum,
+ bool reverse, /* reverse search */
+ int& count){
QString tmp = QString().setNum( rootnum );
QString retstr = "<a href=\"#" + tmp + "\">>>" + tmp + "</a><br>";
- retstr += getTreeByResPrivate(rootnum,count,"");
+ retstr += getTreeByResCore(rootnum,reverse,count,"");
- return retstr;
+ return retstr;
}
-
/* private */
-QString DatInfo::getTreeByResPrivate(const int rootnum, int& count, QString prestr)
+QString DatInfo::getTreeByResCore(
+ const int rootnum,
+ bool reverse, /* reverse search */
+ int& count, QString prestr)
{
if(!parseDat(rootnum)) return QString::null;
if( checkAbonePrivate(rootnum) ) return QString::null;
count = 0;
QStringList strlists;
- /* collect responses that have anchor to rootnum */
- for ( int i = rootnum+1; i <= m_maxNum; i++ ){
- if(checkAbonePrivate( i ) ) continue;
- if(checkRes(i,rootnum)){
- count ++;
- strlists += QString().setNum( i );
+ if( !reverse ){
+
+ /* collect responses that have anchor to rootnum */
+ for ( int i = rootnum+1; i <= m_maxNum; i++ ){
+ if(checkAbonePrivate( i ) ) continue;
+ if(checkRes(i,rootnum)){
+ count ++;
+ strlists += QString().setNum( i );
+ }
+ }
+
+ }
+ else { /* collect responses for which rootnum has anchors */
+
+ setAncList(rootnum);
+ AncList& anclist = m_resDatVec[ rootnum ].anclist;
+ for ( AncList::iterator it = anclist.begin(); it != anclist.end(); ++it ){
+ for( int i = (*it).from; i <= QMIN(rootnum-1,(*it).to) ; i++){
+ if(checkAbonePrivate(i) ) continue;
+ count ++;
+ strlists += QString().setNum( i );
+ }
}
}
tmpstr = prestr;
if((*it) == strlists.last()) tmpstr += m_spacestr + m_spacestr + m_spacestr; /* " " */
else tmpstr += m_framestr1 + m_spacestr; /* "| " */
- retstr += getTreeByResPrivate((*it).toInt(),tmpnum,tmpstr);
+ retstr += getTreeByResCore((*it).toInt(),reverse,tmpnum,tmpstr);
count += tmpnum;
}
}
}
+
/*----------------------------------------------*/
/* Check if No.num has anchors to No.target */
/* For exsample, if target = 4, and No.num have
AncList& anclist = m_resDatVec[ num ].anclist;
anclist.clear();
+ QString line = m_resDatVec[ num ].body;
+
/* remove HTML tags */
QRegExp rex( "<[^>]*>" );
- QString line = m_resDatVec[ num ].linestr;
line.remove(rex);
const QChar *chpt = line.unicode();
unsigned int i;
unsigned int length = line.length();
- /* parse */
+ /* parse body */
for ( i = 0 ; i < length ; i++ ) {
if( chpt[ i ].unicode() == UTF16_BRACKET || /* > */
i += (pos-1);
}
}
+
+ /* parse name */
+ line = m_resDatVec[ num ].name;
+ chpt = line.unicode();
+ i = 0;
+ length = line.length();
+
+ while(ParseMisc::parseResAnchor(chpt+i,length-i,linkstr,refNum,pos)){
+ if(refNum[1] < refNum[0]) refNum[1] = refNum[0];
+ anctmp.from = refNum[0];
+ anctmp.to = refNum[1];
+ anclist += anctmp;
+ i += pos;
+ }
+}
+
+
+
+/*----------------------------------*/
+/* Get DOM element */
+
+/* This function returns the element
+ of DOM.
+
+ This function checks Abone
+ internally. So, if the res is
+ aboned,the output is "abone" node.
+
+ If the res is broken, the output
+ is "broken" node.
+ */
+/* public */
+bool DatInfo::getDomElement(
+
+ /* input */
+ int num,
+ DOM::HTMLDocument& hdoc, /* root of HTML document */
+
+ /* output */
+ DOM::Element& retelm)
+{
+
+ QMutexLocker locker( &m_mutex );
+ if(!parseDat(num)) return FALSE;
+
+ QString tmpstr;
+ DOM::Element bodynode, titlenode, tmpelm;
+ bool showAddr = KitaConfig::showMailAddress();
+ bool showAA = KitaConfig::showAA();
+ bool abone = checkAbonePrivate( num );
+
+ RESDAT& resdat = m_resDatVec[ num ];
+
+ if ( !resdat.broken && !abone ){
+
+ /* title node */
+ titlenode = hdoc.createElement( "DT" );
+ ParseMisc::parseTITLEdat(PARSEMODE_DOM,hdoc,num,showAddr,resdat,titlenode,tmpstr);
+
+ /* body node */
+ bodynode = hdoc.createElement( "DD" );
+ {
+ /* put the span node at the head of each line */
+ if ( showAA ){
+
+ tmpelm = bodynode.appendChild( hdoc.createElement( "SPAN" ) );
+ {
+ tmpelm.setAttribute( "style", "color: white" );
+ tmpelm.appendChild( hdoc.createTextNode( "" ) );
+ }
+ }
+
+ ParseMisc::parseBODYdat(PARSEMODE_DOM,resdat.body,hdoc,showAA,bodynode,tmpstr);
+ }
+
+ } else { /* abone or data is broken */
+
+ QString namestr;
+ QString bodystr;
+
+ if(abone){ /* "abone" node */
+ namestr = ParseMisc::utf8ToUnicode( KITAUTF8_ABONE );
+ bodystr = ParseMisc::utf8ToUnicode( KITAUTF8_ABONE );
+ }
+ else{ /* "broken" node */
+ namestr = ParseMisc::utf8ToUnicode( KITAUTF8_NAME );
+ bodystr = ParseMisc::utf8ToUnicode( KITAUTF8_KOWARE );
+ }
+
+ /* title node */
+ titlenode = hdoc.createElement( "DT" );
+ titlenode.appendChild( hdoc.createTextNode(
+ QString().setNum( num ) + " " + namestr ) );
+
+ /* body node */
+ bodynode = hdoc.createElement( "DD" );
+ tmpelm = bodynode.appendChild( hdoc.createElement( "SPAN" ) );
+ {
+ tmpelm.setAttribute( "style", "color: red" );
+ tmpelm.appendChild( hdoc.createTextNode( bodystr ) );
+ }
+
+ }
+
+ bodynode.appendChild( hdoc.createElement( "BR" ) );
+ bodynode.appendChild( hdoc.createElement( "BR" ) );
+
+ /*-----------------------------*/
+
+ retelm = hdoc.createElement( "DIV" );
+ {
+ retelm.setAttribute( "kita_type", "res" );
+ retelm.setAttribute( "id", QString().setNum( num ) );
+ retelm.setAttribute( "kita_rname", resdat.name );
+ retelm.setAttribute( "kita_rid", resdat.id );
+
+ tmpelm = retelm.appendChild( hdoc.createElement( "DL" ) );
+ {
+ tmpelm.appendChild( titlenode );
+ tmpelm.appendChild( bodynode );
+ }
+ }
+
+ return TRUE;
}
}
-/*--------------------------*/
-/* abone checking functions */
-/* public */
+/*--------------------------------*/
+/* abone functions */
+
+
+/*-----------------------*/
+/* reset abone. */
+
+/* call this when config
+ of abone changed. */ /* public */
+void DatInfo::resetAbone()
+{
+ for ( int i = 1; i < KITA_MAXRES; i++ ) m_resDatVec[ i ].checkAbone = FALSE;
+
+ m_aboneByID = ( !KitaConfig::aboneIDList().empty() );
+ m_aboneByName = ( !KitaConfig::aboneNameList().empty() );
+ m_aboneByBody = ( !KitaConfig::aboneWordList().empty() );
+ m_aboneByRes = m_aboneByID | m_aboneByName | m_aboneByBody;
+}
+
+
+/*--------------*/
+/* check abone */ /* public */
+
bool DatInfo::checkAbone(int num)
{
QMutexLocker locker( &m_mutex );
return checkAbonePrivate(num);
}
+
/* private */
bool DatInfo::checkAbonePrivate(int num)
{
m_resDatVec[ num ].checkAbone = TRUE;
bool checktmp = FALSE;
-// if( KitaConfig::aboneByID() )
- checktmp = checkAboneCore(m_resDatVec[ num ].id,KitaConfig::aboneIDList());
+ if( m_aboneByID )
+ checktmp = checkAboneCore(m_resDatVec[ num ].id,KitaConfig::aboneIDList());
- if(!checktmp)
-// if( KitaConfig::aboneByName() )
- checktmp = checkAboneCore(m_resDatVec[ num ].name,KitaConfig::aboneNameList());
+ if(!checktmp && m_aboneByName )
+ checktmp = checkAboneCore(m_resDatVec[ num ].name,KitaConfig::aboneNameList());
- if(!checktmp)
-// if( KitaConfig::aboneByBody() )
- checktmp = checkAboneCore(m_resDatVec[ num ].body,KitaConfig::aboneWordList());
+ if(!checktmp && m_aboneByBody )
+ checktmp = checkAboneCore(m_resDatVec[ num ].body,KitaConfig::aboneWordList());
- if(!checktmp)
-// if( KitaConfig::aboneByRes() )
+ if(!checktmp && m_aboneByRes )
{
setAncList(num);
AncList& anclist = m_resDatVec[ num ].anclist;
+/*---------------------------------------*/
+/* simple parsing function */
-/*--------------------------------------------------*/
-/* parsing funtions */
+/* This function parses struct RESDAT by
+ ParseMisc::parseResDat. In short, this
+ splits the raw date into name, id,
+ date, and bodytext, etc.
-
-/* parsing function to get name, id, date
- and bodytext, etc. */ /* private */
+ Note that this function keeps data as
+ the raw data. So, you need to parse them
+ later by getPlainBody, getHtml,
+ getDomElement, etc.
+ */ /* private */
bool DatInfo::parseDat( int num ){
if ( num <= 0 || KITA_MAXRES <= num ) return FALSE;
if( m_resDatVec[ num ].parsed ) return TRUE;
- if ( ! m_resDatVec[ num ].set ) return FALSE;
-
- RESDAT& resdat = m_resDatVec[ num ];
- resdat.parsed = TRUE;
-
- /* split dat in order to get name, id, etc. */
- QString idstr = "none";
- QStringList list = QStringList::split( "<>", resdat.linestr, true );
-
- if ( list.size() == 5 ) {
-
- resdat.name = list[ 0 ];
- resdat.address = list[ 1 ];
- ParseMisc::parseDateId(list[ 2 ],resdat.id,resdat.dateId,resdat.dateTime );
- resdat.body = list[ 3 ].mid( 1 ); /* remove space after <> */
-
- /* get subject */
- if ( m_subject == QString::null
- && list[ 4 ] != QString::null ) {
-
- m_subject = list[ 4 ];
- Kita::Thread::setName( m_url.prettyURL(), m_subject );
- }
-
- }
-
- return TRUE;
-}
-
-
-/* simple HTML parsing function for popup */
-/* private */ /* copied from comment.cpp */
-QString DatInfo::toHtml(RESDAT& resdat, int num, bool showMailAddress ) const
-{
- QString result;
- result += QString( "<dl><dt><span id=\"%1\"/>%2 " ).arg( num ).arg( num );
- result += linkedAddress(resdat, showMailAddress );
- result += " " + getDateId(resdat) + "</dt><dd>" + linkedBody(resdat) + "<br/><br/></dd></dl>";
-
- return result;
-}
+ QString tmpstr;
+ if( !ParseMisc::parseResDat( m_resDatVec[ num ], tmpstr ) ) return FALSE;
-
-/* private */ /* copied from comment.cpp */
-QString DatInfo::linkedAddress(RESDAT& resdat, bool showMailAddress ) const
-{
- const QString& address = resdat.address;
- const QString& name = resdat.name;
-
- if ( address != "" && showMailAddress ) {
- return QString( "<b><a href=\"mailto:" ) + address + "\" title=\"" + address + "\">" + name + "</a></b> <span style='color: blue'>[" + address + "]</span>";
- } else if ( address != "" ) {
- return QString( "<b><a href=\"mailto:" ) + address + "\" title=\"" + address + "\">" + name + "</a></b>";
- } else {
- return QString( "<b>%1</b>" ).arg( name );
+ /* get subject */
+ if ( m_subject == QString::null && tmpstr != QString::null ){
+ m_subject = tmpstr;
+ Kita::Thread::setName( m_url.prettyURL(), m_subject );
}
-}
-
-/* private */ /* copied from comment.cpp */
-QString DatInfo::getDateId(RESDAT& resdat) const
-{
- if ( ! resdat.dateId.isEmpty() ) {
- return resdat.dateId;
- } else {
- QString dateTime = resdat.dateTime.toString( i18n( "yyyy/MM/dd hh:mm" ) );
- if ( ! resdat.id.isEmpty() ) {
- dateTime.append( QString( " ID:%1" ).arg( resdat.id ) );
- }
- return dateTime;
- }
+ return TRUE;
}
-/* private */ /* copied from comment.cpp */
-QString DatInfo::linkedBody(RESDAT& resdat) const
-{
- QString ret;
- QString str = resdat.body;
- // see RFC 1738.
- QRegExp url_rx( "(h?ttp://([-.0-9a-zA-Z]+(:[0-9]+)?(/[;:@&=$-_.+!*'(),%~/?#0-9a-zA-Z]*)?))" );
-
- int i;
- while ( ( i = str.find( url_rx ) ) != -1 ) {
- if ( i == 0 ) {
- // starts with URL.
- ret += QString( "<a href=\"http://" ) + url_rx.cap( 2 ) + "\">" + url_rx.cap( 1 ) + "</a>";
- str.remove( 0, url_rx.cap( 1 ).length() );
- } else {
- ret += str.left( i );
- str.remove( 0, i );
- }
- }
- ret += str;
-
- if ( resdat.broken ) {
- ret = QString::fromLocal8Bit( "<font color='red'>broken</font><br />" ) + ret;
- }
- return ret;
-}
class QStringList;
-namespace Kita
+namespace DOM
{
+class HTMLDocument;
+class Element;
+}
+
-class Access;
-class Thread;
-
enum{
ABONECHK_BY_ID,
ABONECHK_BY_NAME,
};
typedef QValueVector<RESDAT> ResDatVec;
-
+
+
+namespace Kita
+{
+
+class Access;
+class Thread;
/*-----------------------*/
Thread* m_thread;
QString m_lastLine;
bool m_nowLoading;
+
+ /* abone */
+ bool m_aboneByID;
+ bool m_aboneByName;
+ bool m_aboneByBody;
+ bool m_aboneByRes;
+
/* japanese strings */
QString m_spacestr;
QString getHtml(int startnum, int endnum);
QString getHtmlByID(const QString& strid, int &count );
QString getTreeByRes(const int rootnum, int& count );
+ QString getTreeByResReverse(const int rootnum, int& count );
+
+ /* DOM element */
+ bool getDomElement(int num, DOM::HTMLDocument& hdoc, DOM::Element& retelm);
/* numerical data */
int getMaxResNumber();
/* abone check */
bool checkAbone(int num);
-
+ void resetAbone();
+
/* Wrapper functions for Thread */
const QString thread_datID();
const QString& thread_name();
bool setDat( const QString& line, int num );
/* HTML data */
- QString getTreeByResPrivate(const int rootnum, int& count, QString prestr);
+ QString aboneHTML(int num);
+ QString brokenHTML(int num);
+ QString getTreeByResPrivate(const int rootnum,bool reverse,int& count);
+ QString getTreeByResCore(const int rootnum, bool reverse, int& count, QString prestr);
bool checkRes(const int num, const int target );
void setAncList(int num);
/* parsing funtions */
bool parseDat( int num );
- QString toHtml(RESDAT& resdat, int num, bool showMailAddress ) const;
- QString linkedAddress(RESDAT& resdat, bool showMailAddress ) const;
- QString linkedBody(RESDAT& resdat) const;
- QString getDateId(RESDAT&) const;
/*----------------------------*/
}
+/* public */
+QString DatManager::getPlainTitle( const KURL& url, int num )
+{
+ QMutexLocker locker( &m_mutex );
+
+ DatInfo * datInfo = getDatInfo( url );
+ if ( datInfo == NULL ) return QString::null;
+
+ return datInfo->getPlainTitle(num);
+}
+
/* public */
QString DatManager::getHtml( const KURL& url, int startnum, int endnum )
return datInfo->getTreeByRes(rootnum,count);
}
+/* Get HTML document of reverse res tree.*/ /* public */
+QString DatManager::getTreeByResReverse(const KURL& url, const int rootnum, int &count)
+{
+ QMutexLocker locker( &m_mutex );
+
+ DatInfo* datInfo = getDatInfo(url);
+ if(datInfo == NULL) return QString::null;
+
+ return datInfo->getTreeByResReverse(rootnum,count);
+}
+
+/* Get DOM element */ /* public */
+bool DatManager::getDomElement(const KURL& url, int num, DOM::HTMLDocument& hdoc, DOM::Element& retelm)
+{
+ QMutexLocker locker( &m_mutex );
+
+ DatInfo* datInfo = getDatInfo(url);
+ if(datInfo == NULL) return FALSE;
+
+ return datInfo->getDomElement(num,hdoc,retelm);
+}
+
/* public */
}
+/* public */
+void DatManager::resetAbone(const KURL& url)
+{
+ QMutexLocker locker( &m_mutex );
+
+ DatInfo* datInfo = getDatInfo(url);
+ if(datInfo == NULL) return;
+
+ datInfo->resetAbone();
+}
+
+
/*-----------------------------------*/
/* Wrapper functions for Thread class*/
class KURL;
class QObject;
+namespace DOM
+{
+class HTMLDocument;
+class Element;
+}
+
namespace Kita
{
static const QString& getSubject( const KURL& url );
static const QString& getRawDat( const KURL& url );
static const QString& getDat( const KURL& url, int num );
-
static QString getPlainBody( const KURL& url, int num );
-
+ static QString getPlainTitle( const KURL& url, int num );
/* HTML data */
static QString getHtml( const KURL& url, int startnum, int endnum);
static QString getHtmlByID(const KURL& url, const QString& strid, int &count );
static QString getTreeByRes(const KURL& url, const int rootnum, int &count);
+ static QString getTreeByResReverse(const KURL& url, const int rootnum, int &count);
+ /* DOM element */
+ static bool getDomElement(const KURL& url, int num, DOM::HTMLDocument& hdoc, DOM::Element& retelm);
+
/* numerical data */
static int getMaxResNumber( const KURL& url );
static int getNumByID( const KURL& url, const QString& strid );
/* abone check */
static bool checkAbone(const KURL& url, int num);
+ static void resetAbone(const KURL& url );
/* Wrapper functions for Thread class */
static const QString thread_datID( const KURL& url );
#define KITAUTF8_MAE100 "前100"
#define KITAUTF8_SAIGO "最後"
#define KITAUTF8_KOWARE "ここは壊れています。"
+#define KITAUTF8_ABONE "あぼ〜ん"
#define KITAUTF8_FRAME1 "│"
#define KITAUTF8_FRAME2 "├"
#define KITAUTF8_FRAME3 "└"
#include <qmutex.h>
#include <qregexp.h>
#include <qdatetime.h>
+#include <dom/html_document.h>
+#include <dom/html_element.h>
+#include <dom/dom_text.h>
+#include <klocale.h>
#include "qcp932codec.h"
#include "parsemisc.h"
+#include "datinfo.h" /* struct RESDAT is defined. */
#include "kita-utf8.h"
#include "kita-utf16.h"
+/*------------------------------------------------------------*/
+/*------------------------------------------------------------*/
+
+/* parsing functions */
+
+
+
+/*------------------------------------------*/
+/* */
+/* Parsing Engine for Title */
+/* */
+/*------------------------------------------*/
+
+/*
+ struct RESDAT resdat should be parsed by parseResDat before
+ calling this function. struct RESDAT is defined in datinfo.h
+
+ If mode = PARSEMODE_DOM, titlenode is DOM tree of title node.
+ titletext is ignored.
+
+ If mode = PARSEMODE_HTML, titletext is HTML text of title.
+ DOM tree is not created. Both hdoc and titlenode are ignored.
+
+ If mode = PARSEMODE_TEXT, titletext is plain text of title.
+ DOM tree is not created. Both hdoc and titlenode are ignored.
+*/
+
+/* public */
+void ParseMisc::parseTITLEdat(
+
+ /* input */
+ int mode, /* mode */
+ DOM::HTMLDocument& hdoc, /* root node of DOM document*/
+ int num, /* number of res */
+ bool showMailAddress,
+ const RESDAT& resdat, /* RESDAT is defined in datinfo.h */
+
+ /* output */
+ DOM::Element &titlenode, /* DOM tree of title */
+ QString& titletext /* HTML or plain text of title */
+
+ ){
+
+ /*-----------------------------*/
+ /* init */
+ /*-----------------------------*/
+
+ if( !resdat.parsed ){
+ titletext = QString::null;
+ return;
+ }
+
+ const QString& str_name = resdat.name;
+ const QString& str_address = resdat.address;
+ const QString& str_id = resdat.id;
+ const QString& str_dateId = resdat.dateId;
+ const QDateTime& dt_dateTime = resdat.dateTime;
+
+ unsigned int i;
+ DOM::Element tmpelm;
+ QString linkstr,linkstr2,linkurl,tmpstr;
+
+ QString colonstr = utf8ToUnicode( KITAUTF8_COLON );
+ QString colonnamestr = utf8ToUnicode( KITAUTF8_NAME );
+
+ titletext = QString::null;
+
+
+ /*-----------------------------*/
+ /* number */
+ /*-----------------------------*/
+
+ linkstr = QString( "%1" ).arg( num );
+ linkurl = "#write"+linkstr;
+
+ switch( mode ){
+
+ case PARSEMODE_DOM:
+
+ tmpelm = titlenode.appendChild( hdoc.createElement( "A" ) );
+ {
+ /* set anchor id = number */
+ tmpelm.setAttribute( "href", linkurl );
+ tmpelm.appendChild( hdoc.createTextNode( linkstr ));
+ }
+ break;
+
+ case PARSEMODE_HTML:
+ titletext += "<a href=\"" + linkurl +"\">";
+ titletext += linkstr;
+ titletext +="</a>";
+ break;
+
+ case PARSEMODE_TEXT:
+ titletext += linkstr;
+ break;
+
+ }
+
+
+ /*-----------------------------*/
+ /* name & mail address */
+ /*-----------------------------*/
+
+ DOM::Element namenode;
+ linkurl = QString::null;
+
+ /* parse name strings */
+ parseBODYdatText(PARSEMODE_TEXT,str_name,linkstr);
+
+ tmpstr = " " + colonnamestr;
+ switch( mode ){
+
+ case PARSEMODE_DOM:
+ titlenode.appendChild( hdoc.createTextNode( tmpstr ) );
+ namenode = titlenode.appendChild( hdoc.createElement( "B" ) );
+ break;
+
+ case PARSEMODE_HTML:
+ case PARSEMODE_TEXT:
+ titletext += tmpstr;
+ break;
+ }
+
+ /* show name with mail address, or show name only */
+ if ( showMailAddress || str_address == QString::null ){
+
+ const QChar *chpt = linkstr.unicode();
+ unsigned int length = linkstr.length();
+
+ unsigned int pos;
+ int refNum[2];
+ i = 0;
+
+ bool ancChain = TRUE;
+ /* ancChain is chain for anchor. For examle, if anchor "2"
+ appeared, ancChain is set to TRUE. Moreover, if next strings
+ are "=5", anchor for 5 is also set. Thus, we can obtain anchors
+ for strings "2=5" as follows:
+
+ <a href="#2">2</a><a href="#5">=5</a>
+ */
+
+ /* show name */
+ for(;;){
+
+ linkurl = QString::null;
+ linkstr2 = QString::null;
+
+ /* get strings & anchor for digits */
+ if(showMailAddress && ancChain){
+
+ if( ( ancChain = parseResAnchor(chpt+i,length-i,linkstr2,refNum,pos) ) ) {
+
+ linkurl = QString("#%1").arg(refNum[0]);
+ if(refNum[1]) linkurl += QString("-%1").arg(refNum[1]);
+ }
+
+ i += pos;
+ }
+
+ else{ /* get strings for non-digits */
+
+ while( i < length ) linkstr2 += chpt[ i++ ];
+ }
+
+ if( linkstr2 != QString::null){
+
+ switch(mode){
+
+ case PARSEMODE_DOM:
+
+ if( linkurl != QString::null){ /* create anchor */
+
+ tmpelm = namenode.appendChild( hdoc.createElement( "A" ) );
+ {
+ tmpelm.setAttribute( "href", linkurl );
+ tmpelm.appendChild( hdoc.createTextNode( linkstr2 ) );
+ }
+
+
+ } else {
+
+ tmpelm = namenode.appendChild( hdoc.createElement( "SPAN" ) );
+ {
+ tmpelm.setAttribute( "style", "color: green" );
+ tmpelm.appendChild( hdoc.createTextNode( linkstr2 ) );
+ }
+ }
+
+ break;
+
+ case PARSEMODE_HTML:
+ case PARSEMODE_TEXT:
+
+ if( mode == PARSEMODE_HTML
+ && linkurl != QString::null){ /* create anchor */
+
+ titletext += "<a href=\"" + linkurl +"\">";
+ titletext += linkstr2;
+ titletext +="</a>";
+
+ }
+ else titletext += linkstr2;
+
+ break;
+ }
+ }
+
+ if( i >= linkstr.length()) break;
+
+ } /* for(;;) */
+
+
+ /* show mail address */
+ switch(mode){
+
+ case PARSEMODE_DOM:
+
+ if ( showMailAddress && str_address != QString::null ) {
+ tmpstr = QString( " [" ) + str_address + "]";
+ titlenode.appendChild( hdoc.createTextNode( tmpstr ) );
+ }
+
+ break;
+
+ case PARSEMODE_HTML:
+ case PARSEMODE_TEXT:
+
+ if ( showMailAddress && str_address != QString::null ) {
+ tmpstr = QString( " [" ) + str_address + "]";
+ titletext += tmpstr;
+ }
+
+ break;
+ }
+
+ } /* if ( showMailAddress || str_address == QString::null ) */
+
+ /* don't show mail address (i.e. showMailAddress == FALSE) */
+ else {
+
+ linkurl = QString( "mailto:" ) + str_address;
+
+ switch(mode){
+
+ case PARSEMODE_DOM:
+ tmpelm = namenode.appendChild( hdoc.createElement( "A" ) );
+ {
+ tmpelm.setAttribute( "href", linkurl );
+ tmpelm.setAttribute( "title", str_address );
+ tmpelm.appendChild( hdoc.createTextNode( linkstr ) );
+ }
+ break;
+
+ case PARSEMODE_HTML:
+
+ titletext += "<a href=\"" + linkurl;
+ titletext += " title=\"" + str_address + "\">";
+ titletext += linkstr;
+ titletext +="</a>";
+
+ break;
+
+ case PARSEMODE_TEXT:
+ titletext += linkstr;
+ break;
+ }
+ }
+
+
+ /*-----------------------------*/
+ /* date & ID */
+ /*-----------------------------*/
+
+ if ( str_dateId != QString::null ) {
+
+ /* show date & ID */
+ tmpstr = colonstr + str_dateId;
+ }
+ else {
+
+ /* show date only */
+ tmpstr = " " + colonstr + dt_dateTime.toString( i18n( "yyyy/MM/dd hh:mm" ) ) + " ";
+ }
+
+ switch(mode){
+
+ case PARSEMODE_DOM:
+ titlenode.appendChild( hdoc.createTextNode( tmpstr ) );
+ break;
+
+ case PARSEMODE_HTML:
+ case PARSEMODE_TEXT:
+ titletext += tmpstr;
+ break;
+
+ }
+
+ /* show ID */
+ if ( str_id != QString::null){
+
+ if ( str_id == "???" ) tmpstr = "ID:" + str_id;
+ else tmpstr = ":" + str_id;
+
+ switch(mode){
+
+ case PARSEMODE_DOM:
+
+ if(tmpstr.left(3) != "ID:"){
+ tmpelm = titlenode.appendChild( hdoc.createElement( "A" ) );
+ {
+ tmpelm.setAttribute( "href", "#idpop" + str_id );
+ tmpelm.appendChild( hdoc.createTextNode( "ID" ) );
+ }
+ }
+
+ titlenode.appendChild( hdoc.createTextNode( tmpstr ) );
+ break;
+
+ case PARSEMODE_HTML:
+
+ if(tmpstr.left(3) != "ID:")
+ titletext += "<a href=\"#idpop" + str_id + "\">ID</a>";
+ titletext += tmpstr;
+ break;
+
+ case PARSEMODE_TEXT:
+ if(tmpstr.left(3) != "ID:") titletext += "ID";
+ titletext += tmpstr;
+ break;
+ }
+ }
+
+}
+
+
+/*-----------------------------------------------------*/
+/* For convenience.
+ mode can be set to PARSEMODE_HTML or PARSEMODE_TEXT */ /* public */
+void ParseMisc::parseTITLEdatText(
+
+ /* input */
+ int mode, /* mode = PARSEMODE_HTML or PARSEMODE_TEXT */
+ int num,
+ bool showMailAddress,
+ const RESDAT& resdat, /* RESDAT is defined in datinfo.h */
+
+ /* output */
+ QString& titletext /* HTML or plain text of title */
+
+ ){
+
+ /* dummy */
+ DOM::HTMLDocument hdoc;
+ DOM::Element titlenode;
+
+ parseTITLEdat(mode,hdoc,num,showMailAddress,resdat,titlenode,titletext);
+}
+
+
+
+
+
+/*------------------------------------------*/
+/* */
+/* Parsing Engine for Body */
+/* */
+/*------------------------------------------*/
+
+/*
+ If mode = PARSEMODE_DOM, bodynode is DOM tree of body.
+ bodytext is ignored.
+
+ If mode = PARSEMODE_HTML, bodytext is HTML text of body.
+ DOM tree is not created. Both hdoc and bodynode are ignored.
+
+ If mode = PARSEMODE_TEXT, bodytext is plain text of body.
+ DOM tree is not created. Both hdoc and bodynode are ignored.
+*/
+
+/* public */
+void ParseMisc::parseBODYdat(
+
+ /* input */
+ int mode, /* mode */
+ const QString &rawStr, /* raw strings of body text */
+ DOM::HTMLDocument& hdoc, /* root node of DOM document*/
+ bool showAA, /* show AA (for KDE3.1x) */
+
+ /* output */
+ DOM::Element &bodynode, /* DOM tree of body */
+ QString& bodytext /* HTML or plain text of body */
+
+ ){
+
+ /*-----------------------------------------*/
+ /* init */
+
+ unsigned int i, i2, index, pos, length = rawStr.length();
+ DOM::Element tmpelm;
+ QString linkstr, linkurl;
+
+ const QChar *chpt = rawStr.unicode();
+ QString lineStr = QString::null;
+ bodytext = QString::null;
+
+ bool ancChain = FALSE;
+ /* ancChain is chain for anchor. For examle, if anchor ">2"
+ appeared, ancChain is set to TRUE. Moreover, if next strings
+ are "=5", anchor for 5 is also set. Thus, we can obtain anchors
+ for strings ">2=5" as follows:
+
+ <a href="#2">>2</a><a href="#5">=5</a>
+ */
+
+
+ /*-----------------------------------------*/
+
+ for ( i = index = 0 ; i < length ; i++ ) {
+
+ switch ( chpt[ i ].unicode() ) {
+
+ case '<':
+
+ /* " <br> " */
+ if (chpt[i + 1] == 'b' && chpt[i + 2] == 'r' && chpt[i + 3] == '>'){
+
+ i2 = i - index;
+ if(i > 0 && chpt[i-1] == ' ') i2--; /* remove space before <br> */
+ lineStr += rawStr.mid( index, i2 );
+
+ switch ( mode ){
+
+ case PARSEMODE_DOM:
+
+ /* add BR node */
+ bodynode.appendChild( hdoc.createTextNode( lineStr ) );
+ bodynode.appendChild( hdoc.createElement( "BR" ) );
+
+ /* show Ascii Art (for KDE3.1*) */
+ if ( showAA ) {
+
+ /* put the span node after BR node */
+ tmpelm = bodynode.appendChild( hdoc.createElement( "SPAN" ) );
+ {
+ tmpelm.setAttribute( "style", "color: white" );
+ tmpelm.appendChild( hdoc.createTextNode( "" ) );
+ }
+ }
+
+ break;
+
+ case PARSEMODE_HTML:
+
+ bodytext += lineStr;
+ bodytext += "<br>";
+ /* show Ascii Art (for KDE3.1*) */
+ if ( showAA ) {
+ bodytext += "<span style=\"color: white\"></span>";
+ }
+ break;
+
+ case PARSEMODE_TEXT:
+
+ bodytext += lineStr;
+ bodytext += '\n';
+
+ break;
+ }
+
+ index = i + 4;
+ if( chpt[index] == ' ') index++; /* remove space after <br> */
+ i = index - 1;
+ lineStr = QString::null;
+ ancChain = FALSE;
+ }
+
+ /*----------------------------------------*/
+
+ /* remove HTML tags <[^>]*> */
+ else{
+ lineStr += rawStr.mid( index, i - index );
+ while( chpt[i] != '>' && i < length ) i++;
+ index = i+1;
+ }
+
+ break;
+
+ /*----------------------------------------*/
+
+ case 'h': /* "http://" or "ttp://" or "tp:" */
+ case 't':
+
+ if( mode != PARSEMODE_TEXT
+ && parseLink( chpt + i, length - i,linkstr, linkurl, pos) ){
+
+ lineStr += rawStr.mid( index, i - index );
+
+ switch ( mode ){
+
+ case PARSEMODE_DOM:
+
+ /* create A node */
+ bodynode.appendChild( hdoc.createTextNode( lineStr ) );
+
+ tmpelm = bodynode.appendChild( hdoc.createElement( "A" ) );
+ {
+ tmpelm.setAttribute( "href", linkurl );
+ tmpelm.appendChild( hdoc.createTextNode( linkurl ));
+ }
+
+ break;
+
+ case PARSEMODE_HTML:
+ bodytext += lineStr;
+ bodytext += "<a href=\"" + linkurl +"\">";
+ bodytext += linkstr;
+ bodytext +="</a>";
+ break;
+ }
+
+ index = i + pos;
+ i = index -1;
+ lineStr = QString::null;
+ }
+
+ break;
+
+ /*----------------------------------*/
+
+ case '&':
+
+ /* > */
+ if ( mode != PARSEMODE_TEXT
+ && chpt[i + 1] == 'g' && chpt[i + 2] == 't' && chpt[i + 3] == ';')
+ ancChain = createResAnchor( mode, rawStr, hdoc, bodynode, bodytext, chpt, i, index, lineStr);
+ /* special char */
+ else {
+
+ QString tmpstr;
+ tmpstr = parseSpecialChar(chpt + i, pos);
+
+ if ( tmpstr != QString::null ){
+ lineStr += rawStr.mid( index, i - index ) + tmpstr;
+ index = i + pos;
+ i = index - 1;
+ }
+ }
+
+ break;
+
+ /*----------------------------------------*/
+
+ /* unicode '>' */
+ case UTF16_BRACKET:
+ if( mode != PARSEMODE_TEXT )
+ ancChain = createResAnchor( mode, rawStr, hdoc, bodynode, bodytext, chpt, i, index, lineStr);
+ break;
+
+ /*----------------------------------*/
+
+ default:
+ if(mode != PARSEMODE_TEXT && ancChain)
+ ancChain = createResAnchor( mode, rawStr, hdoc, bodynode, bodytext, chpt, i, index, lineStr);
+ }
+ }
+
+
+ /*---------------------------*/
+
+ lineStr += rawStr.mid( index );
+
+ switch ( mode ){
+
+ case PARSEMODE_DOM:
+ bodynode.appendChild( hdoc.createTextNode( lineStr ) );
+ break;
+
+ case PARSEMODE_HTML:
+ case PARSEMODE_TEXT:
+ bodytext += lineStr;
+ break;
+ }
+
+}
+
+
+/*-----------------------------------------------------*/
+/* For convenience.
+ mode can be set to PARSEMODE_HTML or PARSEMODE_TEXT */ /* public */
+void ParseMisc::parseBODYdatText(
+
+ /* input */
+ int mode, /* mode = PARSEMODE_HTML or PARSEMODE_TEXT */
+ const QString &rawStr, /* raw strings of body text */
+
+ /* output */
+ QString& bodytext /* HTML or plain text of body */
+
+ ){
+
+ /* dummy */
+ DOM::HTMLDocument hdoc;
+ DOM::Element bodynode;
+
+ parseBODYdat(mode,rawStr,hdoc,FALSE,bodynode,bodytext);
+}
+
+
+
+/*--------------------------------------------*/
+/* get HTML from RESDAT */
+/*
+ resdat should be parsed by parseResDat before
+ calling this function.
+
+ struct RESDAT is defined in datinfo.h . */ /* public */
+QString ParseMisc::ResDatToHtml(const RESDAT& resdat, int num, bool showAddr )
+{
+ QString result,titletext,bodytext;
+
+ ParseMisc::parseTITLEdatText(PARSEMODE_HTML,num,showAddr,resdat,titletext);
+ ParseMisc::parseBODYdatText(PARSEMODE_HTML,resdat.body,bodytext);
+
+ result = QString( "<dl><dt>" );
+ result += titletext;
+ result += "</dt><dd>";
+ result += bodytext;
+ result += "<br/><br/></dd></dl>";
+
+ return result;
+}
+
+
+
+/*--------------------------------------------*/
+/* get HTML from raw data */ /* public */
+
+QString ParseMisc::DatToHtml(const QString& rawData, int num, bool showAddr )
+{
+ QString tmpstr;
+ RESDAT resdat;
+
+ resdat.linestr = rawData;
+ resdat.set = TRUE;
+ resdat.parsed = FALSE;
+ parseResDat(resdat,tmpstr);
+
+ return ResDatToHtml(resdat,num,showAddr);
+}
+
+
+
+
+/*-------------------------------------------------------*/
+/*-------------------------------------------------------*/
+
+/* public utils */
/*------------------------------------------*/
linkstr = ">12-20",
refNum[0] = 12,
refNum[1] = 20,
- pos = 9,
+ pos (= length of cdat ) = 9,
ret = TRUE;
- This function is called in
-
- DatInfo::setAncList and KitaDomTree::createResAnchor. */
+*/
bool ParseMisc::parseResAnchor(
/* check digits */
int hyphen = 0;
- if( pos ){
-
for ( i = 0 ; i < KITA_RESDIGIT + 1 && pos < length ; i++, pos++ ) {
unsigned short c = cdat[ pos ].unicode();
ret = TRUE;
}
- }
return ret;
}
/* For example, if cdat = "&", then
- pos = 5,
+ pos (= length of cdat) = 5,
retstr = "&".
-
- This function is called in
-
- DatInfo::getPlainBody and KitaDomTree::parseHTMLdat. */
+*/
QString ParseMisc::parseSpecialChar(
-/* copied from comment.cpp */
-/*
- This function is called in
-
- DatInfo::DatInfo::parseDat and KitaDomTree::parseRes */
+/* copied from comment.cpp */ /* public */
void ParseMisc::parseDateId( const QString& str ,
QString &idstr,
QString &dateIdstr, QDateTime &dTime )
dTime = dateTime;
idstr = regexp.cap( 7 );
}
+
+
+/*--------------------------------------*/
+/* split raw data, then get ID, name,
+ date, body text, subject, etc.
+
+ (input) "resdat.linestr","resdat.set"
+
+ "resdat.linestr" is raw data, and
+ "resdat.set" should be set to TRUE
+ before calling this.
+
+ struct RESDAT is defined in datinfo.h.
+ see also datinfo.h. */ /* public */
+bool ParseMisc::parseResDat(RESDAT& resdat, QString& subject)
+{
+ if( resdat.parsed ) return TRUE;
+ if( !resdat.set ) return FALSE;
+
+ resdat.parsed = TRUE;
+
+ /* split dat */
+ QString idstr = "none";
+ QStringList list = QStringList::split( "<>", resdat.linestr, true );
+
+ if ( list.size() == 5 ) {
+
+ resdat.broken = FALSE;
+
+ resdat.name = list[ 0 ];
+ resdat.address = list[ 1 ];
+ parseDateId(list[ 2 ],resdat.id,resdat.dateId,resdat.dateTime );
+ resdat.body = list[ 3 ].mid( 1 ); /* remove space after <> */
+
+ /* get subject */
+ if (list[ 4 ] != QString::null ) {
+ subject = list[ 4 ];
+ }
+
+ }
+ else resdat.broken = TRUE;
+
+ return TRUE;
+}
+
+
+
+/*-----------------------------*/
+/* parsing function for link */
+
+/* For example,
+
+ cdat = "ttp://foo.com",
+
+ then
+
+ linkstr = "ttp://foo.com",
+ linkurl = "http://foo.com",
+ pos (= length of cdat) = 13,
+
+ and return TRUE.
+ */ /* public */
+bool ParseMisc::parseLink(
+
+ /* input */
+ const QChar *cdat, const unsigned int length,
+
+ /* output */
+ QString& linkstr, QString& linkurl, unsigned int& pos
+ ){
+
+ /*-----------------------------*/
+
+ linkstr = QString::null;
+ linkurl = QString::null;
+
+ int i = isEqual( cdat , "http://" );
+ if(!i) i = isEqual( cdat , "ttp://" );
+ if(!i) i = isEqual( cdat , "tp://" );
+ if(!i) return FALSE;
+
+ linkurl = "http://";
+ pos = 0;
+
+ while ( cdat[ pos ] != '/' && pos < length ) linkstr += cdat[ pos++ ];
+ linkstr += "//"; pos += 2;
+ while ( cdat[ pos ] >= '!' && cdat[ pos ] <= '~' &&
+ cdat[ pos ] != ' ' && cdat[ pos ] != '<' && cdat[ pos ] != '>'
+ && pos < length ){
+ linkurl += cdat[ pos ];
+ linkstr += cdat[ pos++ ];
+ }
+ if ( pos >= length ) return FALSE;
+
+ return TRUE;
+}
+
+
+
+
+
+/*--------------------------------------------*/
+/* private functions */
+
+
+/* if cdat == str, return str.length() */ /* private */
+int ParseMisc::isEqual( const QChar *cdat, const QString& str)
+{
+ int i = 0;
+ while ( str.at( i ) != '\0' ) {
+ if ( *cdat != str.at( i ) ) return 0;
+ cdat++;i++;
+ }
+ return i;
+}
+
+
+
+
+
+/*------------------------*/
+/* create node of anchor */
+
+/* This function is called from parseBODYdat
+ internally. So, see also parseBODYdat */ /* private */
+bool ParseMisc::createResAnchor(
+
+ /* input */
+ int mode,
+ const QString &rawStr,
+ DOM::HTMLDocument& hdoc ,
+
+ /* output */
+ DOM::Element &bodynode,
+ QString& bodytext,
+
+ /* internal variables */
+ /* They are the same variables that ara used in parseBODYdat. */
+ const QChar *chpt, unsigned int &i, unsigned int &index, QString& lineStr
+ )
+{
+ /*-----------------------*/
+
+ QString linkstr,linkurl;
+ DOM::Element tmpelm;
+ int refNum[2];
+ unsigned int pos;
+ unsigned int length = rawStr.length();
+
+ /* parse anchor */
+ if( !parseResAnchor(chpt+i,length-i,linkstr,refNum,pos) ){
+ lineStr += rawStr.mid( index, i - index ) + linkstr;
+ index = i + pos;
+ i = index - 1;
+ return FALSE;
+ }
+
+ /* create anchor */
+ lineStr += rawStr.mid( index, i - index );
+ linkurl = QString("#%1").arg(refNum[0]);
+ if(refNum[1]) linkurl += QString("-%1").arg(refNum[1]);
+
+ switch ( mode ){
+
+ case PARSEMODE_DOM:
+
+ /* create 'A' element */
+ bodynode.appendChild( hdoc.createTextNode( lineStr ) );
+
+ tmpelm = bodynode.appendChild( hdoc.createElement( "A" ) );
+ {
+ tmpelm.setAttribute( "href", linkurl );
+ tmpelm.appendChild( hdoc.createTextNode( linkstr ) );
+ }
+
+ break;
+
+ case PARSEMODE_HTML:
+ bodytext += lineStr;
+ bodytext += "<a href=\"" + linkurl +"\">";
+ bodytext += linkstr;
+ bodytext +="</a>";
+ break;
+ }
+
+ index = i + pos;
+ i = index - 1;
+ lineStr = QString::null;
+
+ return TRUE;
+}
+
+
+
class QDateTime;
class QCp932Codec;
-namespace Kita
+namespace DOM
{
+class HTMLDocument;
+class Element;
+}
+
+struct RESDAT;
+
+/* mode */
+enum{
+PARSEMODE_DOM,
+PARSEMODE_HTML,
+PARSEMODE_TEXT
+};
+namespace Kita
+{
+
class ParseMisc
{
static QMutex m_codexMutex;
/* Text codec */
static QString qcpToUnicode( const QString& str );
static QString utf8ToUnicode( const QString& str );
+
+ /* parsing functions */
+ static void parseTITLEdat(int mode,DOM::HTMLDocument& hdoc, int num,
+ bool showMailAddress,const RESDAT& resdat,DOM::Element &titlenode,QString& titletext);
+
+ static void parseTITLEdatText(int mode,int num,bool showMailAddress,
+ const RESDAT& resdat,QString& titletext);
+ static void parseBODYdat(int mode,const QString &rawStr, DOM::HTMLDocument& hdoc,
+ bool showAA, DOM::Element &bodynode, QString& bodytext);
+
+ static void parseBODYdatText(int mode,const QString &rawStr,QString& bodytext);
+
+ static QString ResDatToHtml(const RESDAT& resdat, int num, bool showAddr);
+ static QString DatToHtml(const QString& rawData, int num, bool showAddr );
+
+
+ /* utils */
static bool parseResAnchor(const QChar *cdat,const unsigned int length,
QString& linkstr,int* refNum,unsigned int& pos);
static QString parseSpecialChar(const QChar *cdat, unsigned int& pos );
static void parseDateId( const QString& str,QString &idstr,
QString &dateIdstr, QDateTime &dTime);
+ static bool parseResDat(RESDAT& resdat, QString& subject);
+ static bool parseLink( const QChar *cdat, const unsigned int length,
+ QString& linkstr, QString& linkurl, unsigned int& pos );
+
+
+ /*-------------------------*/
+
+ private:
+
+ static bool createResAnchor(int mode,const QString &rawStr, DOM::HTMLDocument& hdoc ,
+ DOM::Element &bodynode, QString& bodytext,
+ const QChar *chpt, unsigned int &i, unsigned int &index, QString& lineStr );
+
+ static int isEqual( const QChar *cdat, const QString& str);
+
};
}
* (at your option) any later version. *
**************************************************************************/
-/* This class keeps information of the DOM tree, creates the node,
- and do parsing, rendering, etc. */
+/* This class manages the DOM tree */
+
+#include <kurl.h>
+#include <dom/html_element.h>
+#include <dom/dom_text.h>
+#include <qstringlist.h>
+#include <qmutex.h>
+#include <qsemaphore.h>
#include "kitadomtree.h"
#include "kitathreadview.h"
#include "libkita/kitaconfig.h"
+#include "libkita/datmanager.h"
+#include "libkita/datinfo.h"
#include "libkita/parsemisc.h"
-
-/* UTF-16 */
-#define KITADOM_BRACKET 0xFF1E /* > */
-#define KITADOM_0 0xFF10 /* 0 */
-#define KITADOM_9 0xFF19 /* 9 */
-#define KITADOM_EQ 0xFF1D /* = */
-#define KITADOM_COMMA 0xFF0C /* , */
-
-/* UTF-8 */
#include "libkita/kita-utf8.h"
KitaDomTree::KitaDomTree( KitaHTMLPart* threadPart )
{
- QTextCodec * codec = QTextCodec::codecForName( "utf8" );
- m_colonstr = codec->toUnicode( KITAUTF8_COLON );
- m_clnamestr = codec->toUnicode( KITAUTF8_NAME );
-
m_semap = new QSemaphore( 1 );
m_krt = new KitaRenderThread( this );
{
StopParseThread();
- m_thread = thread;
- if ( m_thread ) {
- m_url = m_thread->datURL();
+ if ( thread ) {
+ m_url = thread->datURL();
} else {
m_url = "";
}
- m_showaddr = KitaConfig::showMailAddress();
- m_imgsize = 50; /* initial width of inline image */
-
m_templateNum = 20; /* number of templates */
- m_namelist = KitaConfig::aboneNameList();
- m_idlist = KitaConfig::aboneIDList();
- m_wordlist = KitaConfig::aboneWordList();
- m_resAbone = FALSE;
-
/* style */
QString style = QString( "style=\"font-size: %1pt; "
"font-family: %2; "
createTugi100();
createMae100();
+ /* get pointer of DatInfo */
+ m_datInfo = Kita::DatManager::getDatInfoPointer( m_url );
+ m_datInfo->resetAbone();
+
resetAllVar();
}
/*------------------------------------*/
/* copy thread data to buffer */
/*------------------------------------*/
-void KitaDomTree::setDat( const QString& line, int num )
+void KitaDomTree::setDat( const QString& , int num )
{
if ( num < 1 || num >= KITADOM_MAXRES ) return ;
- m_linedat[ num ] = line;
- m_linedatset[ num ] = TRUE;
-
- /* get subject */
- if ( num == 1 ) {
- QStringList list = QStringList::split( "<>", m_linedat[ num ], true );
- if ( list[ 4 ] != NULL ) {
- m_subject = list[ 4 ];
- }
- }
-
- /* check if dat is broken */
- if ( line.contains( "<>" ) != 4 ) {
- m_broken = TRUE;
- }
-
if ( num > m_maxNum ) {
m_maxNum = num;
}
}
-
/*--------------------------------------------*/
/* DOM parsing function */
-/* */
-/* to show a res, call appendRes later. */
-/*--------------------------------------------*/
-void KitaDomTree::parseRes(
- int num, /* the number of buffer */
- int resnum /* the number of response , usually, num = resnum */
-)
-{
- if ( m_hdoc == NULL ) return ;
- if ( num < 1 || num > m_maxNum ) return ;
- if ( !m_linedatset[ num ] ) return ;
- if ( m_resparsed[ num ] ) return ; /* already parsed */
+/*
+ This function parses the res and gets the DOM
+ element by DatInfo::getDomElement.
+
+ This function does only parsing.
+ To show the res, call appendRes later. */ /* public */
+bool KitaDomTree::parseRes( int num, int )
+{
+ if ( m_hdoc == NULL ) return FALSE;
+ if ( !m_datInfo->isResValid( num ) ) return FALSE;
+ if ( m_resparsed[ num ] ) return TRUE; /* already parsed */
+
( *m_semap ) ++;
-
- DOM::Element rootnode, dlnode;
- DOM::Element bodynode, titlenode;
- QString str_name = "";
- QString str_address = "", str_body = "";
- QString str_id = "", str_dateId = "";
- QDateTime dt_dateTime;
-
- /* split 2ch dat */
- QStringList list = QStringList::split( "<>", m_linedat[ num ], true );
-
- if ( list.size() == 5 ) { /* valid data */
-
- str_name = list[ 0 ];
- str_address = list[ 1 ];
- parseDateId( list[ 2 ], str_id, str_dateId, dt_dateTime );
- str_body = list[ 3 ];
-
- /* create both title & body node */
- titlenode = createTitleNode( resnum,
- m_showaddr,
- str_name,
- str_address,
- str_id,
- str_dateId,
- dt_dateTime );
-
- bodynode = createBodyTextNode( str_body );
- } else { /* data is broken */
-
- titlenode = m_hdoc.createElement( "DT" );
- titlenode.appendChild( m_hdoc.createTextNode(
- QString().setNum( resnum ) + " " + m_clnamestr ) );
-
- bodynode = m_hdoc.createElement( "DD" );
- QString str = QTextCodec::codecForName( "utf8" ) ->toUnicode( KITAUTF8_KOWARE );
- appendColoredTextNode( bodynode, str, "color: red" );
- bodynode.appendChild( m_hdoc.createElement( "BR" ) );
- bodynode.appendChild( m_hdoc.createElement( "BR" ) );
- }
-
- /*-------------*/
- /* create node */
- rootnode = m_hdoc.createElement( "DIV" );
- {
- rootnode.setAttribute( "kita_type", "res" );
- rootnode.setAttribute( "id", QString().setNum( resnum ) );
- rootnode.setAttribute( "kita_rname", str_name );
- rootnode.setAttribute( "kita_rid", str_id );
-
- dlnode = rootnode.appendChild( m_hdoc.createElement( "DL" ) );
- {
- dlnode.appendChild( titlenode );
- dlnode.appendChild( bodynode );
- }
+
+ if(!m_datInfo->getDomElement(num,m_hdoc,m_res[ num ])){
+ ( *m_semap ) --;
+ return FALSE;
}
- m_res[ num ] = rootnode;
m_resparsed[ num ] = TRUE;
( *m_semap ) --;
+
+ return TRUE;
}
}
-/*-----------------------------------------------*/
-/* public utilities */
-
-/* get string data of res */
-QString KitaDomTree::getDat( int num )
-{
- if ( num < 1 || num > m_maxNum ) {
- return QString::null;
- }
-
- if ( m_linedatset[ num ] ) {
- return m_linedat[ num ];
- } else {
- return QString::null;
- }
-}
-
-
-/*------------------------------------*/
-/* get HTML documents for popup, etc. */
-/*------------------------------------*/
-QString KitaDomTree::getHtml( int startnum, int endnum )
-{
- QString str = QString::null;
-
- for ( int i = startnum; i <= endnum; i++ ) {
- if ( checkIsNumValid( i ) == DOM_RES_VALID ) {
- str += getHtmlCore( i );
- }
- }
- return str;
-}
-
-/* return html documents & number of resposes which have ID=strid */
-QString KitaDomTree::getHtmlByID( QString strid, int &num )
-{
-
- QString outstr = QString::null;
- num = 0;
- for ( int i = 1; i <= m_maxNum; i++ ) {
- if ( checkIsNumValid( i ) == DOM_RES_VALID ) {
- if ( CheckID( strid, i ) ) {
- outstr += getHtmlCore( i );
- num++;
- }
- }
- }
-
- return outstr;
-}
-
-
-/* return only number of resposes which have ID=strid */
-int KitaDomTree::getNumByID( QString strid )
-{
- int num = 0;
+bool KitaDomTree::isResDataSet( int num ) {
- for ( int i = 1; i <= m_maxNum; i++ ) {
- if ( CheckID( strid, i ) ) {
- if ( CheckID( strid, i ) ) num++;
- }
- }
-
- return num;
+ return m_datInfo->isResValid(num);
}
-
-/*--------------------------------------------------*/
-/* get strings of response for quotaion, copy, etc. */
/*--------------------------------------------------*/
+/* get strings of response for quotaion, copy, etc. */ /* public */
+
QString KitaDomTree::getResStr( int num,
QString qtstr /* quotation mark such as "> " */
)
{
- QString str, strtmp;
- QString str_id;
+ QString retstr, titlestr, bodystr;
if ( checkIsNumValid( num ) != DOM_RES_VALID ) return QString::null;
- DOM::Node node = m_res[ num ];
- DOM::Node titlenode = node.firstChild().firstChild();
- DOM::Node bodynode = node.firstChild().lastChild();
-
- strtmp = qtstr + extractText( bodynode, "dd", "\n" + qtstr );
-
- /* remove >\n>\n */
- strtmp = strtmp.left( strtmp.length() - ( qtstr.length() + 1 ) * 2 );
-
- str = qtstr + extractText( titlenode, "dt", QString::null ) + "\n";
- str += strtmp + "\n";
-
- return str;
-}
-
-
-
-/* check if ID == strid */
-bool KitaDomTree::CheckID( QString strid, int num )
-{
- if ( checkIsNumValid( num ) != DOM_RES_VALID ) return FALSE;
-
- QString str_rid
- = static_cast<DOM::Element>( m_res[ num ] ).getAttribute( "kita_rid" ).string();
-
- if ( strid == str_rid ) return TRUE;
-
- return FALSE;
-}
-
-
-/* check if this res includes some keywords */
-bool KitaDomTree::CheckWord( QStringList stlist, int num,
- bool checkOR /* AND or OR search */
- )
-{
- if ( stlist.size() == 0 ) return FALSE;
- if ( checkIsNumValid( num ) != DOM_RES_VALID ) return FALSE;
+ titlestr = m_datInfo->getPlainTitle(num);
+ bodystr = m_datInfo->getPlainBody(num);
+ if(qtstr != QString::null) bodystr.replace("\n","\n"+qtstr);
- DOM::Node node = m_res[ num ];
- QString str_text = extractText( node, "div", QString::null );
+ retstr = qtstr + titlestr + "\n";
+ retstr += qtstr + bodystr + "\n";
- for ( QStringList::iterator it = stlist.begin(); it != stlist.end(); ++it ) {
-
- if ( checkOR ) { /* OR */
- if ( str_text.find( ( *it ), 0, FALSE ) != -1 ) {
- return TRUE;
- }
- } else { /* AND */
- if ( str_text.find( ( *it ), 0, FALSE ) == -1 ) return FALSE;
- }
- }
-
- if ( checkOR ) return FALSE;
-
- return TRUE;
-}
-
-
-/* check if this res has an anchor for target */
-bool KitaDomTree::CheckRes( int target, int num )
-{
-
- if ( checkIsNumValid( num ) != DOM_RES_VALID ) return FALSE;
- if ( checkIsNumValid( target ) != DOM_RES_VALID ) return FALSE;
-
- DOM::Node node = m_res[ num ];
- DOM::Node bodytext = node.firstChild().lastChild();
-
- DOM::NodeList nodelist = bodytext.childNodes();
- for ( unsigned int i = 0; i < nodelist.length(); ++i ) {
-
- DOM::HTMLElement anode = nodelist.item( i );
- if ( anode.nodeName().string() == "a" ) {
- int refNum, refNum2;
- QString url = anode.getAttribute( "href" ).string();
- getRefNumber( url, m_thread, refNum, refNum2 );
- if ( target >= refNum && target <= refNum2 ) return TRUE;
- }
- }
-
- return FALSE;
+ return retstr;
}
-/*-------------------------------------------------------------------*/
-/*-------------------------------------------------------------------*/
-/*-------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
for ( int i = 0; i <= KITADOM_MAXRES; i++ ) {
m_resparsed[ i ] = FALSE;
m_resshown[ i ] = FALSE;
- m_linedatset[ i ] = FALSE;
- m_checkAbone[ i ] = FALSE;
- m_abone[ i ] = FALSE;
}
m_topNum = KITADOM_MAXRES + 2;
m_bottomNum = -1;
m_maxNum = 0;
- m_imgnum = 0;
m_kokoyonNum = 0;
m_appendtugi100 = FALSE;
m_appendmae100 = FALSE;
- m_broken = FALSE;
-}
-
-
-
-
-/*----------------------------------------*/
-/* create the node of name, date and id. */
-/* */
-/* called from KitaDomTree::parseRes */
-/*----------------------------------------*/
-DOM::Element KitaDomTree::createTitleNode(
- int num, bool showMailAddress,
- QString &str_name,
- QString &str_address,
- QString &str_id,
- QString &str_dateId,
- QDateTime &dt_dateTime )
-{
- DOM::Element titlenode = m_hdoc.createElement( "DT" );
- {
- /* number */
- DOM::Element numberLink = titlenode.appendChild( m_hdoc.createElement( "A" ) );
- {
- /* set anchor id = number */
- QString str = QString( "%1" ).arg( num );
- numberLink.setAttribute( "href", "#write" + str );
- numberLink.appendChild( m_hdoc.createTextNode( str ) );
- }
-
- /* name */
- titlenode.appendChild( m_hdoc.createTextNode( " " + m_clnamestr ) );
- DOM::Element namenode = titlenode.appendChild( m_hdoc.createElement( "B" ) );
- {
- /* remove </b> and <b> inside name */
- str_name.remove( "<b>" );
- str_name.remove( "</b>" );
-
- /* show mail address */
- if ( showMailAddress ) {
-
- /* when name is composed of only numbers, create link */
- unsigned int i;
- const QChar *chpt = str_name.unicode();
- char strlink[ KITADOM_RESDIGIT + 1 ];
- for ( i = 0;i < QMIN( str_name.length(), KITADOM_RESDIGIT ) ;i++ ) {
- unsigned short c = chpt[ i ].unicode();
- if ( ( c < KITADOM_0 || c > KITADOM_9 ) && ( c < '0' || c > '9' ) ) {
- i = 0;
- break;
- }
-
- if ( c >= KITADOM_0 ) {
- strlink[ i ] = '0' + chpt[ i ].unicode() - KITADOM_0;
- } else {
- strlink[ i ] = c;
- }
- }
- strlink[ i ] = '\0';
-
- if ( i ) {
- DOM::Element nameLink = namenode.appendChild( m_hdoc.createElement( "A" ) );
- {
- nameLink.setAttribute( "href", "#" + QString( strlink ) );
- nameLink.appendChild( m_hdoc.createTextNode( str_name ) );
- }
- } else appendColoredTextNode( titlenode, str_name, "color: green" );
- }
- /* not show mail address */
- else if ( str_address != "" ) {
-
- DOM::Element mailtoLink = namenode.appendChild( m_hdoc.createElement( "A" ) );
- {
- QString str = QString( "mailto:" ) + str_address;
- mailtoLink.setAttribute( "href", str );
- mailtoLink.setAttribute( "title", str_address );
- mailtoLink.appendChild( m_hdoc.createTextNode( str_name ) );
- }
- }
- /* show name only */
- else {
- appendColoredTextNode( titlenode, str_name, "color: green" );
- }
- }
-
- /* mail address */
- if ( str_address != "" && showMailAddress ) {
- QString str = QString( " [" ) + str_address + "]";
- titlenode.appendChild( m_hdoc.createTextNode( str ) );
- }
-
- /* date & id */
- if ( ! str_dateId.isEmpty() ) {
- QString str = m_colonstr + str_dateId;
- titlenode.appendChild( m_hdoc.createTextNode( str ) );
- } else {
- QString str = " " + m_colonstr + dt_dateTime.toString( i18n( "yyyy/MM/dd hh:mm" ) ) + " ";
- titlenode.appendChild( m_hdoc.createTextNode( str ) );
-
- /* id */
- if ( ! str_id.isEmpty() ) {
- if ( str_id == "???" ) {
- str = "ID:" + str_id;
- } else {
- DOM::Element idLink = titlenode.appendChild( m_hdoc.createElement( "A" ) );
- {
- idLink.setAttribute( "href", "#idpop" + str_id );
- idLink.appendChild( m_hdoc.createTextNode( "ID" ) );
- }
- str = ":" + str_id;
- }
-
- titlenode.appendChild( m_hdoc.createTextNode( str ) );
- }
- }
- }
-
- return titlenode;
-}
-
-
-
-/*-------------------------------------*/
-/* create the node of body text. */
-/* */
-/* called from KitaDomTree::parseRes */
-/*-------------------------------------*/
-DOM::Element KitaDomTree::createBodyTextNode(
- QString &str_body )
-{
- int i;
-
- /* remove space after <> & copy */
- // QString str = str_body;
- QString str = str_body.mid( 1 );
-
- // see RFC 1738.
- QRegExp url_rx( "(h?ttp://([-.0-9a-zA-Z]+(:[0-9]+)?(/[;:@&=$-_.+!*'(),%~/?#0-9a-zA-Z]*)?))" );
-
- DOM::Element bodynode = m_hdoc.createElement( "DD" );
- {
- /* put the span node at the head of each line */
- if ( KitaConfig::showAA() ) {
- appendColoredTextNode( bodynode, "", "color: white" );
- }
-
- while ( ( i = str.find( url_rx ) ) != -1 ) {
-
- if ( i == 0 ) {
- // starts with URL.
- DOM::Element linkElement = bodynode.appendChild( m_hdoc.createElement( "A" ) );
- {
- linkElement.setAttribute( "href", "http://" + url_rx.cap( 2 ) );
- linkElement.appendChild( m_hdoc.createTextNode( url_rx.cap( 1 ) ) );
- }
-
- str.remove( 0, url_rx.cap( 1 ).length() );
- } else {
-
- QString leftstr = str.left( i );
- parseHTMLdat( bodynode, leftstr );
-
- str.remove( 0, i );
- }
- }
-
- parseHTMLdat( bodynode, str );
-
- bodynode.appendChild( m_hdoc.createElement( "BR" ) );
- bodynode.appendChild( m_hdoc.createElement( "BR" ) );
- }
-
- return bodynode;
-}
-
-
-
-
-
-/*-----------------------------------*/
-/* parsing function of HTML document */
-/*-----------------------------------*/
-void KitaDomTree::parseHTMLdat(
- DOM::Element &bodynode, QString &str )
-{
-
- struct LocalFunc {
- static int isEqual( const QChar *chpt, const QString& str, const int ret )
- {
- int i = 0;
- while ( str.at( i ) != '\0' ) {
- if ( *chpt != str.at( i ) ) return 0;
- chpt++;i++;
- }
- return ret;
- }
- };
-
- unsigned int i, i2, index, index2, tail, length = str.length();
- QString urlstr, textstr;
- const QChar *chpt = str.unicode();
- QString replacestr;
- QTextCodec *codec = QTextCodec::codecForName( "utf-8" );
- bool bBodyisA = ( bodynode.nodeName().string() == "a" );
-
- DOM::Element tmpelm;
-
- m_linestr = "";
-
- for ( i = index = 0 ; i < length ; i++ ) {
-
- switch ( chpt[ i ].unicode() ) {
-
- case '<':
-
- /* <br> */
- if ( LocalFunc::isEqual( chpt + i + 1, "br>", 4 ) ) {
-
- /* remove space before <br> */
- // m_linestr += str.mid(index,i-index);
- m_linestr += str.mid( index, ( i - index > 0 ? i - index - 1 : 0 ) );
-
- bodynode.appendChild( m_hdoc.createTextNode( m_linestr ) );
- bodynode.appendChild( m_hdoc.createElement( "BR" ) );
-
- /* put the span node after br node */
- if ( KitaConfig::showAA() ) {
- appendColoredTextNode( bodynode, "", "color: white" );
- }
-
- m_linestr = "";
- index = i + 4;
-
- /* remove space after <br> */
- index++;
-
- i = index - 1;
- }
-
- /* <a href> */
- /* I don't consider the existence of space ' ' here... */
- else if ( LocalFunc::isEqual( chpt + i + 1, "a href", 7 ) ) {
-
- /* obtain URL */
- index2 = i + 9; tail = index2;
- while ( chpt[ tail ] != '"' && tail < length ) tail++;
- if ( tail >= length ) break;
- urlstr = str.mid( index2, tail - index2 );
-
- while ( chpt[ tail ] != '>' && tail < length ) tail++;
- if ( tail >= length ) break;
-
- /* obtain text */
- index2 = tail + 1; tail = index2;
- while ( chpt[ tail ] != '<' && tail < length ) tail++;
- if ( tail >= length ) break;
- textstr = str.mid( index2, tail - index2 );
-
- while ( chpt[ tail ] != '>' && tail < length ) tail++;
- if ( tail >= length ) break;
-
- /* create A node */
- m_linestr += str.mid( index, i - index );
- bodynode.appendChild( m_hdoc.createTextNode( m_linestr ) );
- m_linestr = "";
-
- tmpelm = bodynode.appendChild( m_hdoc.createElement( "A" ) );
- {
- tmpelm.setAttribute( "href", urlstr );
- tmpelm.setAttribute( "target", "_blank" );
- parseHTMLdat( tmpelm, textstr );
- }
-
- index = tail + 1;
- i = index;
- while ( createResAnchor( bodynode, str, chpt, i, index,bBodyisA ) );
- }
-
- break;
-
- /*----------------------------------*/
- case '&':
-
- i2 = 0;
-
- if ( LocalFunc::isEqual( chpt + i + 1, "gt;", 4 ) )
- while ( createResAnchor( bodynode, str, chpt, i, index,bBodyisA ) );
-
- else if ( ( i2 = LocalFunc::isEqual( chpt + i + 1, "lt;", 4 ) ) )
- replacestr = "<";
-
- else if ( ( i2 = LocalFunc::isEqual( chpt + i + 1, "nbsp;", 6 ) ) )
- replacestr = " ";
-
- else if ( ( i2 = LocalFunc::isEqual( chpt + i + 1, "amp;", 5 ) ) )
- replacestr = "&";
-
- else if ( ( i2 = LocalFunc::isEqual( chpt + i + 1, "quot;", 6 ) ) )
- replacestr = "\"";
-
- else if ( ( i2 = LocalFunc::isEqual( chpt + i + 1, "hearts;", 8 ) ) )
- replacestr = codec->toUnicode( KITAUTF8_HEART );
-
- else if ( ( i2 = LocalFunc::isEqual( chpt + i + 1, "diams;", 7 ) ) )
- replacestr = codec->toUnicode( KITAUTF8_DIA );
-
- else if ( ( i2 = LocalFunc::isEqual( chpt + i + 1, "clubs;", 7 ) ) )
- replacestr = codec->toUnicode( KITAUTF8_CLUB );
-
- else if ( ( i2 = LocalFunc::isEqual( chpt + i + 1, "spades;", 8 ) ) )
- replacestr = codec->toUnicode( KITAUTF8_SPADE );
-
- if ( i2 ) {
- m_linestr += str.mid( index, i - index ) + replacestr;
- index = i + i2;
- i = index - 1;
- }
-
- break;
-
- /*----------------------------------------*/
-
- /* unicode '>' */
- case KITADOM_BRACKET:
-
- while ( createResAnchor( bodynode, str, chpt, i, index,bBodyisA ) );
- break;
- }
- }
-
- m_linestr += str.mid( index, i - index );
- bodynode.appendChild( m_hdoc.createTextNode( m_linestr ) );
- m_linestr = "";
}
}
-
-/*---------------------------------*/
-/* create anchor (>>number) node */
-/*---------------------------------*/
-bool KitaDomTree::createResAnchor(
- DOM::Element &bodynode, QString &str, const QChar *chpt,
- unsigned int &i, unsigned int &index, bool bBodyisA )
-{
- QString linkstr;
- int refNum[2];
- unsigned int pos;
- unsigned int length = str.length();
-
- bool ret = Kita::ParseMisc::parseResAnchor(chpt+i,length-i,linkstr,refNum,pos);
-
- if ( !ret || bBodyisA ) { /* If body element is A, return here */
- m_linestr += str.mid( index, i - index ) + linkstr;
- index = i + pos;
- i = index - 1;
- return FALSE;
- }
-
- /* create 'A' element */
- m_linestr += str.mid( index, i - index );
- bodynode.appendChild( m_hdoc.createTextNode( m_linestr ) );
- m_linestr = "";
-
- DOM::Element tmpelm = bodynode.appendChild( m_hdoc.createElement( "A" ) );
- {
- QString tmp = QString("#%1").arg(refNum[0]);
- if(refNum[1]) tmp += QString("-%1").arg(refNum[1]);
-
- tmpelm.setAttribute( "href", tmp );
- tmpelm.appendChild( m_hdoc.createTextNode( linkstr ) );
- }
-
- index = i + pos;
- i = index; /* call this function again, so, don't set i = index-1 here ! */
-
- return TRUE;
-}
-
-
-
-/*!!! copied from comment.cpp !!!*/
-void KitaDomTree::parseDateId( const QString& str ,
- QString &str_id,
- QString &str_dateId, QDateTime &dt_dateTime )
-
-{
- QRegExp regexp( "(\\d\\d)/(\\d\\d)/(\\d\\d) (\\d\\d):(\\d\\d)( ID:(.*))?" );
-
- if ( regexp.search( str ) == -1 ) {
- str_dateId = str;
- return ;
- }
-
- int year = regexp.cap( 1 ).toInt();
- if ( year >= 70 ) {
- year += 1900;
- } else {
- year += 2000;
- }
-
- QDateTime
- dateTime( QDate( year, regexp.cap( 2 ).toInt(), regexp.cap( 3 ).toInt() ),
- QTime( regexp.cap( 4 ).toInt(), regexp.cap( 5 ).toInt() ) );
- dt_dateTime = dateTime;
- str_id = regexp.cap( 7 );
-}
-
-
-/*------------------------------------------------------------*/
-/*------------------------------------------------------------*/
-/*------------------------------------------------------------*/
-
-
-/*--------------------------------*/
-/* private utils */
-/*--------------------------------*/
-
-
-/*---------------------------------*/
-/* check if this response is valid */
-
-/* call this before appending
- or getting a res. */
/*---------------------------------*/
+/* check if this response is valid */ /* private */
int KitaDomTree::checkIsNumValid( int num )
{
- if ( m_hdoc == NULL ) return DOM_RES_NOTVALID;
- if ( num < 1 || num > m_maxNum ) return DOM_RES_NOTVALID;
m_krt->mywait();
- if ( !m_resparsed[ num ] ) parseRes( num, num ); /* do paring here */
- if ( !m_resparsed[ num ] ) return DOM_RES_NOTVALID;
- if ( checkAbone( num ) ) return DOM_RES_ABONED;
+
+ if ( !parseRes(num,num) ) return DOM_RES_NOTVALID;
return DOM_RES_VALID;
}
-/*----------------------------------------------------------------------*/
-/* extract all texts from the body text node for searchig , Abone & etc */
-/*----------------------------------------------------------------------*/
-QString KitaDomTree::extractText( DOM::Node rootnode,
- const char* termstr, /* name of terminating node, e.g. "div","dt","dd"... */
- const QString br_str /* strings to replace instead of <br> */
- )
-{
- QString str_ret = "";
- DOM::Node node = rootnode;
- DOM::Node nextnode;
-
- while ( node != NULL ) {
-
- if ( node.nodeType() == DOM::Node::TEXT_NODE
- || node.nodeType() == DOM::Node::CDATA_SECTION_NODE
- ) {
- DOM::DOMString nodeText = node.nodeValue();
- str_ret += nodeText.string();
- }
- /* replace <br> with str_ret */
- else if ( br_str != NULL && node.nodeName().string() == "br" ) {
- str_ret += br_str;
- }
-
- nextnode = node.firstChild();
- if ( nextnode == NULL ) nextnode = node.nextSibling();
- while ( node != NULL && nextnode == NULL ) {
- node = node.parentNode();
- if ( node != NULL ) {
-
- if ( node.nodeName().string() == termstr ) return str_ret;
-
- nextnode = node.nextSibling();
- }
- }
-
- node = nextnode;
- }
-
- return str_ret;
-}
-
-
-
-/*------------------------*/
-/* get html document */
-/*------------------------*/
-QString KitaDomTree::getHtmlCore( int num ) /* the number of response */
-{
- QString retstr = QString::null;
-
- DOM::Node node = m_res[ num ];
-
- /* get strings as HTML document */
- retstr = "<div>"
- + static_cast<DOM::HTMLElement>( node ).innerHTML().string()
- + "</div>";
-
- return retstr;
-}
-
-
-
-
-/*--------------*/
-/* check Abone */
-/*--------------*/
-
-/* !!! checkAbone should be always called from checkIsNumValid !!! */
-/* don't call from other functions. */
-
-bool KitaDomTree::checkAbone( int num )
-{
- struct LocalFunc {
- static int StrlistFind( QStringList &strlist, QString str )
- {
-
- int ret = -1;
-
- for ( QStringList::iterator it = strlist.begin();
- it != strlist.end(); ++it ) {
- ret = str.find( ( *it ) );
- if ( ret != -1 ) return ret;
- }
- return ret;
- }
- };
-
- if ( num == 1 ) return FALSE; /* Don't abone the first res. */
- if ( m_checkAbone[ num ] ) return m_abone[ num ]; /* already checkd */
-
- m_checkAbone[ num ] = TRUE;
- m_abone[ num ] = TRUE;
-
- DOM::Node node = m_res[ num ];
- DOM::Node bodytext = node.firstChild().lastChild();
- QString str_id = QString().setNum( num );
- QString str_rname, str_rid, str_text;
-
- /* id abone */
- str_rid = static_cast<DOM::Element>
- ( node ).getAttribute( "kita_rid" ).string();
- if ( LocalFunc::StrlistFind( m_idlist, str_rid ) != -1 ) {
- return TRUE;
- }
-
- /* name abone */
- str_rname = static_cast<DOM::Element>
- ( node ).getAttribute( "kita_rname" ).string();
- if ( LocalFunc::StrlistFind( m_namelist, str_rname ) != -1 ) {
- return TRUE;
- }
-
- /* word abone */
- str_text = extractText( bodytext, "dd", QString::null );
- if ( LocalFunc::StrlistFind( m_wordlist, str_text ) != -1 ) {
- return TRUE;
- }
-
- /* abone res to respond aboned res */
- if ( m_resAbone ) {
-
- DOM::NodeList nodelist = bodytext.childNodes();
- for ( int i = 0; i < ( int ) nodelist.length(); ++i ) {
-
- DOM::HTMLElement anode = nodelist.item( i );
- if ( anode.nodeName().string() == "a" ) {
-
- int refNum, refNum2;
- QString url = anode.getAttribute( "href" ).string();
- getRefNumber( url, m_thread, refNum, refNum2 );
-
- /* I don't want to enter loop... */
- if ( refNum >= num ) refNum = num - 1;
- if ( refNum2 >= num ) refNum = num - 1;
- if ( refNum2 < refNum ) refNum2 = refNum;
-
- if ( refNum ) {
- for ( i = refNum; i <= refNum2; i++ ) {
- if ( i != num ) {
- if ( checkIsNumValid( i ) == DOM_RES_ABONED ) {
- return TRUE;
- }
- }
- }
- }
- }
- }
- }
-
- m_abone[ num ] = FALSE;
-
- return FALSE;
-}
-
-
-/*----------------------------------*/
-/* get reference numbers */
-/* */
-/* ex) if url = ..../12345.dat#5-10 */
-/* then refNum = 5, refNum2 = 10 */
-/*----------------------------------*/
-void KitaDomTree::getRefNumber( const KURL& url, Kita::Thread* thread, /* input */
- int& refNum, int& refNum2 /* output */
- )
-{
- refNum = 0;
- refNum2 = 0;
- QString urlstr = url.prettyURL();
- QString refstr;
- int i;
-
- /* get ref */
- if ( urlstr.at( 0 ) == '#' ) {
- refstr = urlstr.mid( 1 );
- } else {
- KURL datURL = KitaThreadView::filterReadCGI(KURL( thread->datURL(), urlstr ), thread );
-
- if ( datURL.host() == KURL( thread->datURL() ).host()
- && datURL.path() == KURL( thread->datURL() ).path() )
- refstr = datURL.ref();
- else return ;
- }
-
- /* get numbers */
- i = refstr.find( "-" );
- if ( i != -1 ) {
- refNum = refstr.left( i ).toInt();
- refNum2 = refstr.mid( i + 1 ).toInt();
- if ( refNum2 < refNum ) refNum2 = refNum;
- } else {
- refNum = refstr.toInt();
- refNum2 = refNum;
- }
-}
-
-
-/*------------------------------------------------------------*/
-/*------------------------------------------------------------*/
-/*------------------------------------------------------------*/
-
/*---------------------------------------------*/
/* private functions for footer, header , etc. */
/*---------------------------------------------*/
{
rootnode.setAttribute( "kita_type", kitatype );
rootnode.setAttribute( "id", kitatype );
- str = QTextCodec::codecForName( "utf8" ) ->toUnicode( KITAUTF8_KOKOYON );
+ str = Kita::ParseMisc::utf8ToUnicode( KITAUTF8_KOKOYON );
LocalFunc::appendNode( m_hdoc, rootnode, "#kokomade_yonda", str );
rootnode.appendChild( m_hdoc.createTextNode( " " ) );
- str = QTextCodec::codecForName( "utf8" ) ->toUnicode( KITAUTF8_ZENBU );
+ str = Kita::ParseMisc::utf8ToUnicode( KITAUTF8_ZENBU );
LocalFunc::appendNode( m_hdoc, rootnode, "#zenbu", str );
rootnode.appendChild( m_hdoc.createTextNode( " " ) );
- str = QTextCodec::codecForName( "utf8" ) ->toUnicode( KITAUTF8_SAIGO );
+ str = Kita::ParseMisc::utf8ToUnicode( KITAUTF8_SAIGO );
LocalFunc::appendNode( m_hdoc, rootnode, "#tosaigo", str );
if ( kitatype == "header" ) {
QString str, style;
DOM::Element rootnode;
- str = QTextCodec::codecForName( "utf8" ) ->toUnicode( KITAUTF8_KOKOYON2 );
+ str = Kita::ParseMisc::utf8ToUnicode( KITAUTF8_KOKOYON2 );
style = "background-color: #CCCCCC; text-align: center";
rootnode = m_hdoc.createElement( "DIV" );
rootnode.setAttribute( "id", "tugi100" );
rootnode.setAttribute( "style", style );
- str = QTextCodec::codecForName( "utf8" ) ->toUnicode( KITAUTF8_TUGI100 );
+ str = Kita::ParseMisc::utf8ToUnicode( KITAUTF8_TUGI100 );
LocalFunc::appendNode( m_hdoc, rootnode, "#tugi100", str );
rootnode.appendChild( m_hdoc.createTextNode( " " ) );
- str = QTextCodec::codecForName( "utf8" ) ->toUnicode( KITAUTF8_ZENBUNOKORI );
+ str = Kita::ParseMisc::utf8ToUnicode( KITAUTF8_ZENBUNOKORI );
LocalFunc::appendNode( m_hdoc, rootnode, "#nokori", str );
rootnode.appendChild( m_hdoc.createElement( "BR" ) );
rootnode.setAttribute( "style", style );
/* ¼¡100 */
- QString tugi100 = QTextCodec::codecForName( "utf8" ) ->toUnicode( KITAUTF8_TUGI100 );
+ QString tugi100 = Kita::ParseMisc::utf8ToUnicode( KITAUTF8_TUGI100 );
LocalFunc::appendNode( m_hdoc, rootnode, "#tmp100", tugi100 );
/* */
DOM::Element divElement = rootnode.appendChild( m_hdoc.createElement( "DIV" ) );
{
divElement.setAttribute( "style", style );
- QString templateStr = QTextCodec::codecForName( "utf8" ) ->toUnicode( KITAUTF8_TEMPLATE );
+ QString templateStr = Kita::ParseMisc::utf8ToUnicode( KITAUTF8_TEMPLATE );
divElement.appendChild( m_hdoc.createTextNode( templateStr ) );
}
rootnode.appendChild( m_hdoc.createElement( "BR" ) );
/* Á°100 */
- QString mae100 = QTextCodec::codecForName( "utf8" ) ->toUnicode( KITAUTF8_MAE100 );
+ QString mae100 = Kita::ParseMisc::utf8ToUnicode( KITAUTF8_MAE100 );
LocalFunc::appendNode( m_hdoc, rootnode, "#mae100", mae100 );
/* */
rootnode.appendChild( m_hdoc.createTextNode( " " ) );
/* Á´ÉôÁ° */
- QString zenbumae = QTextCodec::codecForName( "utf8" ) ->toUnicode( KITAUTF8_ZENBUMAE );
+ QString zenbumae = Kita::ParseMisc::utf8ToUnicode( KITAUTF8_ZENBUMAE );
LocalFunc::appendNode( m_hdoc, rootnode, "#maezenbu", zenbumae );
/* */
/*----------------------------------------------------------------*/
/* for Search */
-/*
-You need to call findTextInit() before calling findText().
-For example, call findTextInit() in KitaThreadView::update_finish().
-
-Then call findText() in KitaThreadView::slotSearchButton()
-instead of calling searchNext().
-*/
-
/*-----------*/
-/* init find */
-/*-----------*/ /* public */
+/* init find */ /* public */
+
void KitaDomTree::findTextInit()
{
m_initFindText = TRUE;
}
+/*--------------------------------*/
+/* search */
+/*
+ You need to call findTextInit()
+ before calling this. */ /* public */
-/*-------------*/
-/* search text */
-/*-------------*/ /* public */
bool KitaDomTree::findText( const QString &str, bool reverse )
{
if ( m_hdoc == NULL ) return FALSE;
#ifndef KITADOMTREE_H
#define KITADOMTREE_H
-#include <kurl.h>
-#include <khtml_part.h>
-#include <dom/html_element.h>
-#include <dom/dom_text.h>
-#include <qstring.h>
-#include <qdatetime.h>
-#include <qstringlist.h>
-#include <qobject.h>
-#include <kglobal.h>
-#include <kprotocolmanager.h>
-#include <kstandarddirs.h>
-#include <qtextcodec.h>
-#include <klocale.h>
-#include <qsemaphore.h>
#include <qthread.h>
-#include <qmutex.h>
#include "kitahtmlpart.h"
#include "kitahtmlview.h"
#include "libkita/thread.h"
#include "libkita/cache.h"
+class KURL;
+class QMutex;
+class QSemaphore;
+
+namespace DOM
+{
+class HTMLDocument;
+class Element;
+}
+
namespace Kita
{
class Thread;
+ class DatInfo;
}
class KitaRenderThread;
-#define KITADOM_RESDIGIT 4
#define KITADOM_MAXRES 1200
class KitaDomTree
{
/* basic informations */
+ Kita::DatInfo* m_datInfo;
KitaHTMLPart* m_threadPart;
- Kita::Thread* m_thread;
KURL m_url;
- QString m_subject;
- bool m_showaddr;
- QString m_linedat[ KITADOM_MAXRES + 1 ]; /* string data */
- bool m_linedatset[ KITADOM_MAXRES + 1 ]; /* already set */
int m_templateNum;
int m_topNum;
int m_bottomNum;
- int m_maxNum; /* = KitaThreadInfo::readNum(m_thread->datURL()) */
- int m_kokoyonNum; /* where kokomade yonda is set */
- bool m_broken;
+ int m_maxNum;
+ int m_kokoyonNum; /* number of kokomade yonda */
/*
1 <-- show --> m_templateNum <-- not shown -->
DOM::Element m_mae100;
bool m_appendtugi100;
bool m_appendmae100;
- QString m_linestr;
QSemaphore* m_semap;
KitaRenderThread* m_krt;
- /* for image node */
- int m_imgnum;
- int m_imgsize;
-
- /* Japanese string */
- QString m_clnamestr;
- QString m_colonstr;
-
- /* for Abone */
- bool m_checkAbone[ KITADOM_MAXRES + 1 ];
- bool m_abone[ KITADOM_MAXRES + 1 ];
- QStringList m_namelist;
- QStringList m_idlist;
- QStringList m_wordlist;
- bool m_resAbone;
-
/* for searching */
bool m_initFindText;
DOM::Node m_findNode;
void parseResInit( Kita::Thread* thread );
void setDat( const QString& line, int num );
- void parseRes( int num, int resnum );
+ bool parseRes( int num, int resnum );
bool appendRes( int num, bool binsert );
bool removeRes( int num );
/* utilities */
- bool isResDataSet( int num ) { return m_linedat[ QMIN( num, KITADOM_MAXRES - 1 ) ];}
bool isResShown( int num ) { return m_resshown[ QMIN( num, KITADOM_MAXRES - 1 ) ]; }
- const QString& getSubject() { return m_subject;}
int getTopResNumber() { return m_topNum;}
int getBottomResNumber() { return m_bottomNum;}
int getMaxResNumber() { return m_maxNum;}
int getTemplateNumber() { return m_templateNum;}
void setTemplateNumber( int tmp ) {m_templateNum = tmp;}
- bool isBroken() { return m_broken;}
- QString getDat( int num );
- QString getHtml( int startnum, int endnum );
- QString getHtmlByID( QString strid, int &num );
- int getNumByID( QString strid );
+ bool isResDataSet( int num );
QString getResStr( int num, QString qtstr );
- bool CheckID( QString strid, int num );
- bool CheckWord( QStringList stlist, int num, bool checkOR );
- bool CheckRes( int target, int num );
-
/* header Node, footer Node, kokomadeyonda Node, etc... */
void appendTemplate();
void createHTMLDocument( const QString& style );
void resetAllVar();
- /* for parsing & rendering */
- DOM::Element createTitleNode(
- int num, bool showMailAddress,
- QString &str_name,
- QString &str_address,
- QString &str_id,
- QString &str_dateId,
- QDateTime &dt_dateTime );
-
- DOM::Element createBodyTextNode( QString &str_body );
-
- void parseHTMLdat( DOM::Element &bodynode, QString &str );
- void appendColoredTextNode( DOM::Element &root, QString str, QString style );
- bool createResAnchor(
- DOM::Element &bodynode, QString &str, const QChar *chpt,
- unsigned int &i, unsigned int &index, bool bBodyisA );
-
- /* copied from comment.cpp */
- void parseDateId( const QString& str ,
- QString &str_id,
- QString &str_dateId, QDateTime &dt_dateTime );
-
/* utils */
+ void appendColoredTextNode( DOM::Element &root, QString str, QString style );
int checkIsNumValid( int num );
- QString extractText( DOM::Node rootnode, const char* termstr, const QString br_str );
- QString getHtmlCore( int num );
- bool checkAbone( int num );
- void getRefNumber( const KURL& url, Kita::Thread* thread,
- int& renNum, int& refNum2 );
/* for footer,header node, etc.. */
DOM::Element createFooter( QString kitatype );
#include <kstdaccel.h>
#include <kpopupmenu.h>
#include <qmessagebox.h>
+#include <klocale.h>
#include "kitathreadtabwidget.h"
#include "libkita/kita_misc.h"
#include "libkita/thread.h"
#include "libkita/kita-utf8.h"
+#include "libkita/parsemisc.h"
#include "kitanavi.h"
#include "kitathreadview.h"
case KITANAVI_EXTBYID:
case KITANAVI_EXTBYWORD:
labelstr = query
- + " :"+ QTextCodec::codecForName("utf8")->toUnicode(KITAUTF8_EXTRACT);
+ + " :"+ Kita::ParseMisc::utf8ToUnicode(KITAUTF8_EXTRACT);
break;
case KITANAVI_SHOWRESTREE:
ext_OR = FALSE;
str = query;
}
- str.replace(QTextCodec::codecForName("utf8")->toUnicode(KITAUTF8_ZENSPACE)," ");
+ str.replace(Kita::ParseMisc::utf8ToUnicode(KITAUTF8_ZENSPACE)," ");
str.replace(qrx," "); /* pack space */
queries = QStringList::split(" ", str);
count++;
}
}
- headstr = QTextCodec::codecForName("utf8")->toUnicode(KITAUTF8_EXTRACT)
+ headstr = Kita::ParseMisc::utf8ToUnicode(KITAUTF8_EXTRACT)
+QString(": %1 : [%2]").arg(query).arg(count);
footstr = headstr;
anchor = "header";
#include "kitadomtree.h"
#include "libkita/access.h"
#include "libkita/datmanager.h"
+#include "libkita/parsemisc.h"
#include <ksqueezedtextlabel.h>
#include <klocale.h>
/*--------------------*/
/* init preview */
- m_bufnum = 0;
m_thread = const_cast<Kita::Thread *>( thread );
connect( qtw, SIGNAL( currentChanged ( QWidget * ) ),
int resnum = Kita::DatManager::getMaxResNumber( m_thread->datURL() ) + 1 ;
- m_preview->domDeleteRes( m_bufnum );
- m_bufnum++;
-
QDateTime now = QDateTime::currentDateTime();
QString bodystr = body();
bodystr.replace( ">", ">" ).replace( "\n", " <br> " );
QString namestr = name();
if ( namestr == NULL || namestr.length() == 0 ) namestr = "(default name)";
- QString str = namestr + "<>" + mail() + "<>"
+ QString rawData = namestr + "<>" + mail() + "<>"
+ now.toString( "yy/MM/dd hh:mm" )
+ "<> " + bodystr + " <>";
- m_preview->domAppendData( str, m_bufnum, resnum );
- m_preview->domApplyChange( QString::null,
- QString::null, QString::null, QString::null, QString::null );
+ QString htmlstr = Kita::ParseMisc::DatToHtml(rawData,resnum,KitaConfig::showMailAddress());
+ m_preview->domSetInnerHTML( htmlstr );
}
bool m_error;
static KitaWriteDialogPrivate* s_private;
KitaThreadView *m_preview;
- int m_bufnum;
int m_resnum;
Kita::Thread* m_thread;