#include <ktextedit.h>
-#include "kitaconfig.h"
+#include "libkita/kitaconfig.h"
using namespace Kita;
#include "libkita/thread.h"
#include "libkita/favoritethreads.h"
#include "libkita/kita_misc.h"
+#include "libkita/kitaconfig.h"
#include <qdragobject.h>
#include <qtextcodec.h>
#include <kapplication.h>
#include <kdockwidget.h>
-#include "kitaconfig.h"
-
-#include "libkita/thread.h"
-
class KPrinter;
class KToggleAction;
class KURL;
class URLArgs;
}
+namespace Kita
+{
+ class Thread;
+}
+
/**
* This class serves as the main window for Kita. It handles the
* menus, toolbars, and status bars.
#include <kdebug.h>
#include <qvaluelist.h>
-#include "libkita/qcp932codec.h"
-#include "libkita/favoriteboards.h"
-#include "part/kita2ch.h"
#include "kitaboardview.h"
#include "kita.h"
+#include "part/kita2ch.h"
+#include "libkita/qcp932codec.h"
+#include "libkita/favoriteboards.h"
#include "libkita/board.h"
#include "libkita/category.h"
+#include "libkita/kitaconfig.h"
KitaBoardView::KitaBoardView( QWidget *parent, const char *name )
#include "libkita/threadinfo.h"
#include "libkita/thread.h"
#include "libkita/kita_misc.h"
-#include "part/kita2ch.h"
-#include "kitaconfig.h"
+#include "libkita/kitaconfig.h"
#include "libkita/favoritethreads.h"
+#include "part/kita2ch.h"
KitaSubjectView::KitaSubjectView( QWidget* parent, const char* name )
: Kita::ThreadListView( parent, name )
*.la
*.lo
*.moc
+*.moc.cpp
.deps
.libs
lib_LTLIBRARIES = libkita.la
-libkita_la_SOURCES = comment.cpp comment.h thread.h thread.cpp qcp932codec.cpp qcp932codec.h board.h board.cpp bbs.h bbs.cpp category.h category.cpp favoritethreads.h favoritethreads.cpp k2ch_articlefile.h k2ch_articlefile.cpp kita_misc.cpp threadinfo.h threadinfo.cpp access.cpp cache.cpp favoriteboards.cpp
+libkita_la_SOURCES = thread.h thread.cpp qcp932codec.cpp qcp932codec.h board.h board.cpp bbs.h bbs.cpp category.h category.cpp favoritethreads.h favoritethreads.cpp k2ch_articlefile.h k2ch_articlefile.cpp kita_misc.cpp threadinfo.h threadinfo.cpp access.cpp cache.cpp favoriteboards.cpp parsemisc.cpp kitaconfig.cpp datmanager.cpp datinfo.cpp
METASOURCES = AUTO
SUBDIRS = tests
-noinst_HEADERS = kita_misc.h access.h cache.h favoriteboards.h
+noinst_HEADERS = kita_misc.h access.h cache.h favoriteboards.h parsemisc.h kitaconfig.h datmanager.h datinfo.h
#include "access.h"
#include "thread.h"
-#include "qcp932codec.h"
#include "cache.h"
#include "threadinfo.h"
QString( "Monazilla/1.00 (Kita/%1)" ).arg( VERSION ) );
}
- KIO::TransferJob* job = KIO::get( m_thread->datURL(), true, true );
+ KIO::TransferJob* job = KIO::get( m_thread->datURL(), true, false );
m_currentJob = job;
connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ),
job->addMetaData( "AllowCompressedPage", "false" );
}
- enter_loop();
+ return QString::null; /* dummy */
+}
+void Access::slotThreadResult( KIO::Job* job )
+{
+ QString retstr;
+
+ m_currentJob = 0;
+ if ( job->error() ) {
+ job->showErrorDialog();
+ } else {
+ m_header = job->queryMetaData( "HTTP-Headers" );
+ }
+
if ( m_threadData.length() ) {
- QCp932Codec codec;
- retstr = codec.toUnicode( m_threadData );
KURL url = m_thread->datURL();
} else retstr = "";
if ( responseCode() != 200 && responseCode() != 206 ) retstr = QString::null;
- return retstr;
+ emit finishLoad();
}
// from netaccess.cpp
void Access::slotReceiveThreadData( KIO::Job*, const QByteArray& data )
{
- QCString cstr( data.data(), data.size() + 1 );
+ QString cstr( data );
m_threadData.append( cstr );
+ emit receiveData( cstr );
}
-void Access::slotThreadResult( KIO::Job* job )
-{
- m_currentJob = 0;
- if ( job->error() ) {
- job->showErrorDialog();
- } else {
- m_header = job->queryMetaData( "HTTP-Headers" );
- }
- qApp->exit_loop();
-}
void Access::killJob()
{
if ( m_currentJob ) m_currentJob->kill();
}
+void Access::stopJob()
+{
+ if ( m_currentJob ) m_currentJob->kill( FALSE ); /* emit result signal */
+}
+
int Access::serverTime()
{
+ if(m_currentJob) m_header = m_currentJob->queryMetaData( "HTTP-Headers" );
// parse HTTP headers
QStringList headerList = QStringList::split( "\n", m_header );
QRegExp regexp( "Date: (...), (..) (...) (....) (..:..:..) .*" );
int Access::responseCode()
{
+ if(m_currentJob) m_header = m_currentJob->queryMetaData( "HTTP-Headers" );
// parse HTTP headers
QStringList headerList = QStringList::split( "\n", m_header );
QRegExp regexp( "HTTP/1\\.[01] ([0-9]+) .*" );
m_orgData = getCacheData( url );
- QCp932Codec codec;
- return codec.toUnicode( m_orgData );
+ return m_orgData;
}
QString get();
void killJob();
+ void stopJob();
int serverTime();
QString getcache();
QString getupdate();
signals:
void redirection( const QString& );
+ void receiveData( const QString& );
+ void finishLoad();
};
}
--- /dev/null
+/**************************************************************************
+* Copyright (C) 2003 by Hideki Ikemoto , (c)2004 by 421 *
+* ikemo@wakaba.jp *
+* *
+* 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. *
+***************************************************************************/
+
+#include <qregexp.h>
+#include <qstringlist.h>
+#include <klocale.h>
+
+#include "datinfo.h"
+#include "datmanager.h"
+#include "parsemisc.h"
+#include "access.h"
+#include "thread.h"
+#include "threadinfo.h"
+#include "kitaconfig.h"
+#include "kita-utf8.h"
+#include "kita-utf16.h"
+
+using namespace Kita;
+
+#define KITA_MAXRES 1200
+#define KITA_RESDIGIT 4
+
+
+/*------------------------------------------------------*/
+/* DatInfo stores & handles all information about *.dat */
+
+DatInfo::DatInfo( const KURL& url ) : m_url( url ), m_access ( 0 )
+{
+ m_thread = Kita::Thread::getByURL( m_url.prettyURL() );
+
+ m_spacestr = ". ";
+ m_framestr1 = ParseMisc::utf8ToUnicode( KITAUTF8_FRAME1 ); /* | */
+ m_framestr2 = ParseMisc::utf8ToUnicode( KITAUTF8_FRAME2 ); /* |- */
+ m_framestr3 = ParseMisc::utf8ToUnicode( KITAUTF8_FRAME3 ); /* L */
+
+ initPrivate();
+}
+
+DatInfo::~DatInfo(){
+ deleteAccessJob();
+}
+
+
+/* Init */
+/* Usually, don't call this. */ /* public */
+void DatInfo::init()
+{
+ QMutexLocker locker( &m_mutex );
+
+ return initPrivate();
+}
+
+/* private */
+void DatInfo::initPrivate(){
+
+ /* stop & delete dat loader */
+ deleteAccessJob();
+
+ /* init variables */
+ m_maxNum = 0;
+ m_rawData = QString::null;
+ m_subject = QString::null;
+ m_broken = FALSE;
+ m_lock = 0;
+ m_nowLoading = FALSE;
+ m_lastLine = QString::null;
+ m_kokoyonNum = KitaThreadInfo::readNum( m_url.prettyURL() );
+
+ /* clear & resize ResDatVec */
+ RESDAT resdat;
+ resetResDat(resdat);
+ m_resDatVec.clear();
+ m_resDatVec.resize(KITA_MAXRES,resdat);
+
+ /* create dat loader */
+ m_access = new Kita::Access( m_thread );
+
+ connect( m_access, SIGNAL( receiveData( const QString& ) ),
+ SLOT( slotReceiveData( const QString& ) ) );
+ connect( m_access, SIGNAL( finishLoad() ),SLOT( slotFinishLoad() ) );
+
+ /* get dat from cahce & copy it to buffer */
+ copyRawDataToBuffer(m_access->getcache());
+ copyRawDataToBuffer(QString::null); /* copy the last line */
+}
+
+
+/* private */
+void DatInfo::resetResDat(RESDAT& resdat){
+
+ resdat.set = FALSE;
+ resdat.parsed = FALSE;
+ resdat.broken = FALSE;
+ resdat.setAnclist = FALSE;
+ resdat.anclist.clear();
+ resdat.checkAbone = FALSE;
+ resdat.abone = FALSE;
+}
+
+
+
+/* delete dat loader */ /* private */
+void DatInfo::deleteAccessJob()
+{
+ if ( m_access ) {
+ m_access->killJob();
+ delete m_access;
+ m_access = NULL;
+ }
+}
+
+
+
+
+/* copy raw lines to buffer */
+
+/* !! NOTICE!!
+ You need to call this function last
+ with rawData = QString::null in order
+ to copy the last line to buffer. */ /* private */
+void DatInfo::copyRawDataToBuffer(const QString& rawData)
+{
+ QStringList linelist;
+ int basenum = m_maxNum + 1;
+
+ if ( rawData != QString::null ){
+
+ /* split the raw data */
+ m_lastLine += rawData;
+ linelist = QStringList::split( "\n", m_lastLine );
+
+ /* backup the last line */
+ QStringList::iterator lastit = linelist.end();
+ lastit--;
+ if( lastit != linelist.end() ){
+ m_lastLine = (*lastit);
+ linelist.remove(lastit);
+ }
+ else m_lastLine = QString::null;
+
+ }
+ else{ /* If rawData == null, then copy the last line */
+
+ if( m_lastLine != QString::null ){
+
+ /* The last line is broken. ( maybe due to
+ having canceled loading. ) */
+ if ( m_lastLine.contains( "<>" ) != 4 ) {
+
+ /* Truncate the last line here. The reason is:
+
+ job->addMetaData( "resume", QString::number( m_orgData.length() - 1 ) );
+ ~~~~~~~~~~~~~~~~~~~~~~
+ in Access::getupdate().
+
+ */
+ m_lastLine.truncate(m_lastLine.length()-1);
+
+ }
+ else{
+
+ linelist += m_lastLine;
+ m_lastLine = QString::null;
+ }
+ }
+ }
+
+ /* copy lines to buffer */
+ for ( QStringList::iterator it = linelist.begin();
+ it != linelist.end(); ++it, ++basenum ) {
+ if((*it) != QString::null){
+ QString line = ParseMisc::qcpToUnicode((*it));
+ setDat(line,basenum);
+ }
+ }
+
+ /* update thread info */
+ m_thread->setResNum( m_maxNum );
+ KitaThreadInfo::setReadNum( m_url.prettyURL(), m_maxNum );
+}
+
+
+
+/* private */
+bool DatInfo::setDat( const QString& line, int num ){
+
+ if ( num <= 0 || (int) m_resDatVec.size() <= num ) return FALSE;
+ if ( line == QString::null ) return FALSE;
+
+ /* reset and set new data */
+ RESDAT& resdat = m_resDatVec[ num ];
+ resetResDat(resdat);
+
+ resdat.set = TRUE;
+ resdat.linestr = line;
+ if(m_maxNum < num) m_maxNum = num;
+ m_rawData += line;
+
+ if(num == 1) parseDat ( num ); /* to get subject */
+
+ /* is this dat file broken ? */
+ if ( line.contains( "<>" ) != 4 ) {
+ resdat.broken = TRUE;
+ m_broken = TRUE;
+ }
+
+ return TRUE;
+}
+
+
+
+/* public */
+const KURL& DatInfo::url()
+{
+ QMutexLocker locker( &m_mutex );
+
+ return m_url;
+}
+
+
+
+/*--------------------------------------*/
+/* cache handling functions */
+
+/* Update cache */
+
+/* When Kita::Access received new data,
+ slotReceiveData is called. */
+
+/* When Kita::Access fineshed loading,
+ slotFinishLoad is called, and
+ DatInfo emits the finishLoad signal to the parent object */ /* public */
+bool DatInfo::updateCache(const QObject* parent)
+{
+ QMutexLocker locker( &m_mutex );
+ if ( m_access == NULL ) return FALSE;
+ if ( m_nowLoading ) return FALSE;
+
+ m_nowLoading = TRUE;
+ m_lock++; /* By locking, DatManager can't delete this while loading. */
+
+ connect( this, SIGNAL( receiveData() ),
+ parent,SLOT( slotReceiveData() ) );
+
+ connect( this, SIGNAL( finishLoad() ),
+ parent,SLOT( slotFinishLoad() ) );
+
+ m_access->getupdate();
+
+ return TRUE;
+}
+
+
+/* slot called when Kita::Access
+ received new data */ /* private slot */
+void DatInfo::slotReceiveData(const QString& newLine){
+
+ int rescode = m_access->responseCode();
+
+ if(rescode != 200 && rescode != 206) return;
+ if(newLine.length() == 1 && newLine.at(0) == '\n') return; /* EOF */
+
+ copyRawDataToBuffer(newLine);
+
+ emit receiveData();
+}
+
+
+/* slot called when Kita::Access
+ finished loading new dat */ /* private slot */
+void DatInfo::slotFinishLoad(){
+
+ /* copy the last line */
+ copyRawDataToBuffer(QString::null);
+
+ /* finish loading session & emit signal to the parent object */
+ m_kokoyonNum = KitaThreadInfo::readNum( m_url.prettyURL() );
+ m_nowLoading = FALSE;
+ emit finishLoad();
+ if(m_lock) m_lock--;
+}
+
+
+/* public */
+int DatInfo::getResponseCode()
+{
+ QMutexLocker locker( &m_mutex );
+ if ( m_access == NULL ) return 0;
+
+ return m_access->responseCode();
+}
+
+
+/* public */
+int DatInfo::getServerTime()
+{
+ QMutexLocker locker( &m_mutex );
+ if ( m_access == NULL ) return 0;
+
+ return m_access->serverTime();
+}
+
+
+/* public */
+bool DatInfo::deleteCache(QWidget* parent){
+
+ QMutexLocker locker( &m_mutex );
+ if ( m_access == NULL ) return FALSE;
+ if ( m_nowLoading ) return FALSE;
+
+ int ret = Kita::Access::deleteLog( m_thread, parent );
+ if(ret) initPrivate();
+
+ return ret;
+}
+
+
+/* public */
+bool DatInfo::isLoadingNow(){
+
+ QMutexLocker locker( &m_mutex );
+
+ return m_nowLoading;
+}
+
+
+
+/* public */
+void DatInfo::stopLoading(){
+
+ /* Don't lock the mutex here !!!
+ It will cause deadlock , because
+ Kita::Access::stopJob() calls KitaThreadView::slotFinishLoad() back,
+ then slotFinishLoad calls another functions in DatInfo. */
+ if ( m_access == NULL ) return;
+ if (! m_nowLoading ) return;
+
+ m_access->stopJob();
+}
+
+
+
+
+/*---------------------------------------------------*/
+/* locking , unlocking functions */
+/* */
+/* If m_lock is not 0, DatManager can't delete this. */
+/* Don't forget to call unlock() after locking this. */
+
+/* They are public */
+
+void DatInfo::lock()
+{
+ QMutexLocker locker( &m_mutex );
+
+ m_lock++;
+}
+
+void DatInfo::unlock()
+{
+ QMutexLocker locker( &m_mutex );
+
+ if(m_lock) m_lock--;
+}
+
+int DatInfo::isLocked()
+{
+ QMutexLocker locker( &m_mutex );
+
+ return m_lock;
+}
+
+
+/*------------------------------------------------------*/
+/* get subject, linedata, id, body, name, HTML, etc. */
+
+/* They are public */
+
+const QString& DatInfo::getSubject()
+{
+ QMutexLocker locker( &m_mutex );
+
+ return m_subject;
+}
+
+const QString& DatInfo::getRawDat()
+{
+ QMutexLocker locker( &m_mutex );
+
+ return m_rawData;
+}
+
+const QString& DatInfo::getDat( int num )
+{
+ QMutexLocker locker( &m_mutex );
+
+ if ( num <= 0 || KITA_MAXRES <= num ) return QString::null;
+ if ( ! m_resDatVec[ num ].set ) return QString::null;
+
+ return m_resDatVec[ num ].linestr;
+}
+
+const QString& DatInfo::getId( int num )
+{
+ QMutexLocker locker( &m_mutex );
+ if(!parseDat(num)) return QString::null;
+
+ return m_resDatVec[ num ].id;
+}
+
+const QString& DatInfo::getBody( int num )
+{
+ QMutexLocker locker( &m_mutex );
+ if(!parseDat(num)) return QString::null;
+
+ return m_resDatVec[ num ].body;
+}
+
+const QString& DatInfo::getName( int num )
+{
+ QMutexLocker locker( &m_mutex );
+ if(!parseDat(num)) return QString::null;
+
+ return m_resDatVec[ num ].name;
+}
+
+/* plain (i.e. parsed) strings of body text */
+QString DatInfo::getPlainBody(int num)
+{
+ QMutexLocker locker( &m_mutex );
+ if(!parseDat(num)) return QString::null;
+
+ QString retstr = QString::null;
+ 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;
+
+ 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;
+}
+
+/* plain 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);
+
+ return retstr;
+}
+
+
+/*-----------------------------------------*/
+/* HTML data */
+
+/* HTML strings */
+/* Note that this function checks Abone internally. */ /* public */
+QString DatInfo::getHtml(int startnum, int endnum)
+{
+ QMutexLocker locker( &m_mutex );
+
+ QString retstr = QString::null;
+ bool showAddr = KitaConfig::showMailAddress();
+
+ for(int num = startnum; num <= endnum; num++){
+
+ if(!parseDat(num)) continue;
+ if(checkAbonePrivate(num)) continue;
+
+ retstr += toHtml(m_resDatVec[ num ], num, showAddr );
+ }
+
+ return retstr;
+}
+
+
+/* return HTML strings that have ID = strid. */
+/* Note that this function checks Abone internally. */ /* public */
+QString DatInfo::getHtmlByID(const QString& strid, int &count )
+{
+ QMutexLocker locker( &m_mutex );
+
+ QString retstr = QString::null;
+ bool showAddr = KitaConfig::showMailAddress();
+
+ count = 0;
+
+ 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);
+ }
+ }
+
+ return retstr;
+}
+
+
+
+/*-------------------------------*/
+/* Get HTML document of res tree.*/
+/* For example, when rootnum = 1,
+
+>>1
+|-->>4
+| |--->>10
+|
+|-->>20, and return count = 3. */
+
+/* Note that this function checks Abone internally. */ /* public */
+QString DatInfo::getTreeByRes(const int rootnum, int& count)
+{
+ QMutexLocker locker( &m_mutex );
+
+ QString tmp = QString().setNum( rootnum );
+ QString retstr = "<a href=\"#" + tmp + "\">>>" + tmp + "</a><br>";
+
+ retstr += getTreeByResPrivate(rootnum,count,"");
+
+ return retstr;
+}
+
+
+/* private */
+QString DatInfo::getTreeByResPrivate(const int rootnum, int& count, QString prestr)
+{
+ if(!parseDat(rootnum)) return QString::null;
+ if( checkAbonePrivate(rootnum) ) return QString::null;
+
+ QString retstr = 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 );
+ }
+ }
+
+ /* make HTML document */
+ if(count){
+
+ for ( QStringList::iterator it = strlists.begin(); it != strlists.end(); ++it ){
+ QString tmpstr;
+ if((*it) == strlists.last()) tmpstr = m_framestr3; /* 'L' */
+ else tmpstr = m_framestr2; /* '|-' */
+
+ retstr += prestr + tmpstr + "<a href=\"#" + (*it) + "\">>>" + (*it) + "</a><br>";
+
+ /* call myself recursively */
+ int tmpnum;
+ 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);
+ count += tmpnum;
+ }
+ }
+
+ return retstr;
+}
+
+
+/*----------------------------------------------*/
+/* Check if No.num has anchors to No.target */
+/* For exsample, if target = 4, and No.num have
+ an anchor >>4, or >>2-6, etc.,
+ then return TRUE. */ /* private */
+bool DatInfo::checkRes(const int num, const int target )
+{
+ if(! parseDat(num)) return FALSE;
+
+ setAncList(num);
+ AncList& anclist = m_resDatVec[ num ].anclist;
+
+ for ( AncList::iterator it = anclist.begin(); it != anclist.end(); ++it ){
+ if ( target >= (*it).from && target <= (*it).to ) return TRUE;
+ }
+
+ return FALSE;
+
+}
+
+
+/*--------------------------*/
+/* set AncList */ /* private */
+
+/* This function sets anchor list.
+ For example, a res has anchors >>2-3 and >>4, then
+
+ anclist[0].from = 2,
+ anclist[0].to = 3,
+ anclist[1].from = 4,
+ anclist[1].to = 4.
+*/
+void DatInfo::setAncList(int num){
+
+ if(! parseDat(num)) return;
+ if( m_resDatVec[ num ].setAnclist ) return;
+
+ m_resDatVec[ num ].setAnclist = TRUE;
+
+ QString linkstr;
+ int refNum[2];
+ unsigned int pos;
+ ANCNUM anctmp;
+
+ AncList& anclist = m_resDatVec[ num ].anclist;
+ anclist.clear();
+
+ /* 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 */
+ for ( i = 0 ; i < length ; i++ ) {
+
+ if( chpt[ i ].unicode() == UTF16_BRACKET || /* > */
+ (chpt[ i] == '&' && chpt[ i+1] == 'g' && chpt[ i+2] == 't' && chpt[ i+3] == ';') /* ">" */
+ ){
+ 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;
+ }
+
+ i += (pos-1);
+ }
+ }
+}
+
+
+
+/*-----------------------*/
+/* several information */
+
+/* public */
+int DatInfo::getMaxResNumber()
+{
+ QMutexLocker locker( &m_mutex );
+
+ return m_maxNum;
+}
+
+
+/* return number of responses that have ID = strid. */
+/* Note that this function checks Abone internally. */ /* public */
+int DatInfo::getNumByID( const QString& strid )
+{
+ QMutexLocker locker( &m_mutex );
+
+ int count = 0;
+
+ for ( int i = 1; i <= m_maxNum; i++ ) {
+
+ if( !parseDat(i) ) continue;
+ if( checkAbonePrivate( i ) ) continue;
+
+ if ( m_resDatVec[i].id == strid ) count++;
+ }
+
+ return count;
+}
+
+/* public */
+int DatInfo::getKokoyonNum()
+{
+ QMutexLocker locker( &m_mutex );
+
+ return QMIN(m_kokoyonNum, m_maxNum);
+}
+
+/* public */
+void DatInfo::setKokoyonNum(int num)
+{
+ QMutexLocker locker( &m_mutex );
+
+ num = QMIN(num, m_maxNum);
+
+ m_kokoyonNum = num;
+ KitaThreadInfo::setReadNum( m_url.prettyURL(), num );
+}
+
+/* public */
+int DatInfo::getDatSize()
+{
+ QMutexLocker locker( &m_mutex );
+
+ return m_rawData.length();
+}
+
+
+/* public */
+bool DatInfo::isResValid(int num)
+{
+ QMutexLocker locker( &m_mutex );
+
+ return parseDat(num);
+}
+
+/* public */
+bool DatInfo::isBroken()
+{
+ QMutexLocker locker( &m_mutex );
+
+ return m_broken;
+}
+
+/* public */
+bool DatInfo::isResBroken(int num)
+{
+ QMutexLocker locker( &m_mutex );
+ if(!parseDat(num)) return FALSE;
+
+ return m_resDatVec[ num ].broken;
+}
+
+/* ID = strid ? */ /* public */
+bool DatInfo::checkID(const QString& strid, int num )
+{
+ QMutexLocker locker( &m_mutex );
+ if(!parseDat(num)) return FALSE;
+
+ if(m_resDatVec[num].id == strid) return TRUE;
+
+ return FALSE;
+}
+
+
+/* Are keywords included ? */ /* public */
+bool DatInfo::checkWord(QStringList& stlist, /* list of keywords */
+ int num,
+ bool checkOR /* AND or OR search */
+ )
+{
+ QMutexLocker locker( &m_mutex );
+ if(!parseDat(num)) return FALSE;
+
+ QString str_text = m_resDatVec[ num ].linestr;
+
+ 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;
+}
+
+
+/*--------------------------*/
+/* abone checking functions */
+
+/* public */
+bool DatInfo::checkAbone(int num)
+{
+ QMutexLocker locker( &m_mutex );
+
+ return checkAbonePrivate(num);
+}
+
+/* private */
+bool DatInfo::checkAbonePrivate(int num)
+{
+ if(!parseDat(num)) return FALSE;
+
+ if ( m_resDatVec[ num ].checkAbone ) return m_resDatVec[ num ].abone;
+
+ m_resDatVec[ num ].checkAbone = TRUE;
+ bool checktmp = FALSE;
+
+// if( KitaConfig::aboneByID() )
+ checktmp = checkAboneCore(m_resDatVec[ num ].id,KitaConfig::aboneIDList());
+
+ if(!checktmp)
+// if( KitaConfig::aboneByName() )
+ checktmp = checkAboneCore(m_resDatVec[ num ].name,KitaConfig::aboneNameList());
+
+ if(!checktmp)
+// if( KitaConfig::aboneByBody() )
+ checktmp = checkAboneCore(m_resDatVec[ num ].body,KitaConfig::aboneWordList());
+
+ if(!checktmp)
+// if( KitaConfig::aboneByRes() )
+ {
+ setAncList(num);
+ AncList& anclist = m_resDatVec[ num ].anclist;
+
+ for ( AncList::iterator it = anclist.begin();
+ it != anclist.end() && !checktmp ; ++it ){
+
+ int refNum = (*it).from;
+ int refNum2 = (*it).to;
+
+ /* I don't want to enter loop... */
+ if ( refNum >= num ) continue;
+ if ( refNum2 >= num ) refNum2 = num - 1;
+
+ for (int i = refNum; i <= refNum2; i++ ){
+ if (checkAbonePrivate(i)){
+ checktmp = TRUE;
+ break;
+ }
+ }
+ }
+ }
+
+ m_resDatVec[ num ].abone = checktmp;
+
+ return m_resDatVec[ num ].abone;
+}
+
+/* private */
+bool DatInfo::checkAboneCore(const QString& str, QStringList& strlist)
+{
+ if(strlist.count()){
+
+ int i;
+ for ( QStringList::iterator it = strlist.begin();
+ it != strlist.end(); ++it ) {
+ i = str.find( ( *it ) );
+ if ( i != -1 ) {
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+
+/*-----------------------------------------*/
+/* Wrapper functions for Thread class */
+
+/* they are public */
+
+const QString DatInfo::thread_datID(){
+
+ QMutexLocker locker( &m_mutex );
+
+ return m_thread->datID();
+
+}
+
+const QString& DatInfo::thread_name(){
+
+ QMutexLocker locker( &m_mutex );
+
+ return m_thread->name();
+
+}
+
+const QString& DatInfo::thread_boardName(){
+
+ QMutexLocker locker( &m_mutex );
+
+ return m_thread->boardName();
+
+}
+
+const QString DatInfo::thread_url(){
+
+ QMutexLocker locker( &m_mutex );
+
+ return m_thread->url();
+
+}
+
+const QString DatInfo::thread_boardURL(){
+
+ QMutexLocker locker( &m_mutex );
+
+ return m_thread->boardURL();
+
+}
+
+const QString DatInfo::thread_boardID(){
+
+ QMutexLocker locker( &m_mutex );
+
+ return m_thread->boardID();
+
+}
+
+
+
+
+/*--------------------------------------------------*/
+/* parsing funtions */
+
+
+/* parsing function to get name, id, date
+ and bodytext, 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;
+}
+
+
+/* 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 );
+ }
+}
+
+
+/* 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;
+ }
+}
+
+
+/* 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;
+}
+
--- /dev/null
+/**************************************************************************
+ * Copyright (C) 2003 by Hideki Ikemoto , (c)2004 by 421 *
+ * ikemo@wakaba.jp *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef KITADATINFO_H
+#define KITADATINFO_H
+
+#include <qobject.h>
+#include <kurl.h>
+#include <qvaluevector.h>
+#include <qdatetime.h>
+#include <qmutex.h>
+
+class QStringList;
+
+namespace Kita
+{
+
+class Access;
+class Thread;
+
+enum{
+ ABONECHK_BY_ID,
+ ABONECHK_BY_NAME,
+ ABONECHK_BY_WORD
+};
+
+/* ResDatVec is the Database for responses. */
+/* For example, No.5 res has name = "foo", id "id1234", and anchors >>2-3 and >>4,
+ then,
+
+ m_resDatVec[5].name = "foo",
+ m_resDatVec[5].id = "id1234",
+ m_resDatVec[5].anclist[0].from = 2,
+ m_resDatVec[5].anclist[0].to = 3,
+ m_resDatVec[5].anclist[1].from = 4,
+ m_resDatVec[5].anclist[1].to = 4.
+
+*/
+struct ANCNUM{
+ int from;
+ int to;
+};
+typedef QValueList<ANCNUM> AncList;
+
+/* Data of one response */
+struct RESDAT{
+
+ bool set; /* Is linestr set ? */
+
+ QString linestr; /* raw line strings */
+
+ /*-------*/
+
+ bool parsed; /* Is dat parsed ? */
+
+ bool broken; /* This dat is broken */
+
+ QString name;
+ QString address;
+ QString body;
+ QString id;
+ QDateTime dateTime;
+ QString dateId;
+
+ /*-------*/
+
+ bool setAnclist; /* Is anclist set ? */
+
+ AncList anclist; /* anchor list. See also setAncList() */
+
+ /*-------*/
+
+ bool checkAbone; /* Is abone checked ? */
+
+ bool abone;
+};
+
+typedef QValueVector<RESDAT> ResDatVec;
+
+
+/*-----------------------*/
+
+class DatInfo : public QObject
+ {
+ Q_OBJECT
+
+ QMutex m_mutex;
+
+ /* basic information */
+ int m_maxNum;
+ QString m_rawData;
+ KURL m_url;
+ QString m_subject;
+ bool m_broken;
+ ResDatVec m_resDatVec;
+ int m_lock;
+ int m_kokoyonNum; /* kokomade yonda */
+
+ /* for caching */
+ Access* m_access;
+ Thread* m_thread;
+ QString m_lastLine;
+ bool m_nowLoading;
+
+ /* japanese strings */
+ QString m_spacestr;
+ QString m_framestr1; /* '|' */
+ QString m_framestr2; /* '|-' */
+ QString m_framestr3; /* 'L' */
+
+ /*-------------------------------*/
+
+ public:
+
+ DatInfo();
+ DatInfo( const KURL& url );
+ ~DatInfo();
+ void init();
+ const KURL& url();
+
+ /* for caching */
+ bool updateCache(const QObject* parent);
+ int getResponseCode();
+ int getServerTime();
+ bool deleteCache(QWidget* parent);
+ bool isLoadingNow();
+ void stopLoading();
+
+ /* lock, unlock */
+ void lock();
+ void unlock();
+ int isLocked();
+
+ /* string data */
+ const QString& getSubject();
+ const QString& getRawDat();
+ const QString& getDat( int num );
+ const QString& getId( int num );
+ const QString& getName( int num );
+ const QString& getBody( int num );
+ QString getPlainBody(int num);
+ QString getPlainTitle(int num);
+
+ /* HTML data */
+ QString getHtml(int startnum, int endnum);
+ QString getHtmlByID(const QString& strid, int &count );
+ QString getTreeByRes(const int rootnum, int& count );
+
+ /* numerical data */
+ int getMaxResNumber();
+ int getNumByID( const QString& strid );
+ int getKokoyonNum();
+ void setKokoyonNum(int num);
+ int getDatSize();
+
+ /* several informations */
+ bool isResValid(int num);
+ bool isBroken();
+ bool isResBroken(int num);
+ bool checkID(const QString& strid, int num );
+ bool checkWord(QStringList& stlist, int num, bool checkOR);
+
+ /* abone check */
+ bool checkAbone(int num);
+
+ /* Wrapper functions for Thread */
+ const QString thread_datID();
+ const QString& thread_name();
+ const QString& thread_boardName();
+ const QString thread_url();
+ const QString thread_boardURL();
+ const QString thread_boardID();
+
+ /*-------------------------*/
+
+ private:
+
+ void initPrivate();
+ void resetResDat(RESDAT& resdat);
+ void deleteAccessJob();
+
+ /* copy data */
+ void copyRawDataToBuffer(const QString& rawData);
+ bool setDat( const QString& line, int num );
+
+ /* HTML data */
+ QString getTreeByResPrivate(const int rootnum, int& count, QString prestr);
+ bool checkRes(const int num, const int target );
+ void setAncList(int num);
+
+ /* for abone */
+ bool checkAbonePrivate(int num);
+ bool checkAboneCore(const QString& str, QStringList& strlist);
+
+ /* 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;
+
+ /*----------------------------*/
+
+ private slots:
+
+ void slotReceiveData(const QString& newLine);
+ void slotFinishLoad();
+
+ signals:
+ void receiveData();
+ void finishLoad();
+ };
+
+}
+
+#endif
--- /dev/null
+/**************************************************************************
+* Copyright (C) 2003 by Hideki Ikemoto , (c)2004 by 421 *
+* ikemo@wakaba.jp *
+* *
+* 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. *
+***************************************************************************/
+
+#include <qobject.h>
+#include <qmutex.h>
+#include <qstringlist.h>
+
+#include "datmanager.h"
+#include "datinfo.h"
+#include "kita-utf8.h"
+#include "kita-utf16.h"
+
+using namespace Kita;
+
+#define DMANAGER_MAXQUEUE 16
+
+/*-------------------------------------------------*/
+/* DatManager manages all information about *.dat. */
+
+DatInfoList DatManager::m_datInfo;
+QMutex DatManager::m_mutex;
+
+/* This function searches instance of DatInfo specified by url.
+ If instance does not exist, create instance. */ /* private */
+DatInfo* DatManager::getDatInfo( const KURL& url )
+{
+ if ( url.isEmpty() ) {
+ return NULL;
+ }
+
+ int i = 0;
+ DatInfoList::Iterator it;
+ DatInfo* datInfo;
+
+ KURL inurl = url.protocol() + "://" + url.host() + url.path();
+
+ /* search */
+ if ( m_datInfo.count() ) {
+ for ( it = m_datInfo.begin(); it != m_datInfo.end(); ++it, i++ ) {
+
+ datInfo = ( *it );
+
+ if ( inurl == datInfo->url() ){
+
+ /* LRU */
+ if ( i ) {
+ m_datInfo.remove( it );
+ m_datInfo.prepend( datInfo );
+ }
+
+ return datInfo;
+ }
+ }
+ }
+
+ /* not found */
+
+ /*create new DatInfo and insert it into list. */
+ KURL daturl = url.protocol() + "://" + url.host() + url.path();
+
+ datInfo = new DatInfo( daturl );
+ if ( datInfo->getRawDat() == QString::null ) { /* cache does not exist */
+ delete( datInfo );
+
+ return NULL;
+ }
+
+ m_datInfo.prepend( datInfo );
+
+ /* delete the last items of list */
+ if ( m_datInfo.count() > DMANAGER_MAXQUEUE ) {
+
+ /* collect unlocked datInfos */
+ typedef QValueList<KURL> DELETELIST;
+ DELETELIST deleteList;
+
+ for ( it = m_datInfo.at(DMANAGER_MAXQUEUE); it != m_datInfo.end(); ++it )
+ if(! (*it)->isLocked() ) deleteList += ( *it ) ->url();
+
+ /* delete unlocked datInfos */
+ for (DELETELIST::Iterator itdel = deleteList.begin(); itdel != deleteList.end(); ++itdel )
+ deleteDatInfoPrivate( (*itdel) );
+ }
+
+ return datInfo;
+}
+
+
+/* get pointer of DatInfo */
+
+/* !!! NOTICE !!! */
+/* It is very dangerous to access to DatInfo directly. */
+/* Usually, access to it through DatManager. */ /* public */
+DatInfo * DatManager::getDatInfoPointer( const KURL& url )
+{
+ QMutexLocker locker( &m_mutex );
+
+ return getDatInfo( url );
+}
+
+
+
+/* public */
+void DatManager::deleteDatInfo( const KURL& url )
+{
+ QMutexLocker locker( &m_mutex );
+
+ deleteDatInfoPrivate(url);
+}
+
+
+/* private */
+void DatManager::deleteDatInfoPrivate( const KURL& url ){
+
+ DatInfoList::Iterator it;
+
+ for ( it = m_datInfo.begin(); it != m_datInfo.end(); ++it ) {
+ if ( url == ( *it )->url() ){
+
+ if(! (*it)->isLocked() ){
+ m_datInfo.remove( it );
+ delete( *it );
+ }
+
+ return ;
+ }
+ }
+
+}
+
+
+
+
+/*-------------------------------------------------------------*/
+
+
+
+/*--------------------------------------*/
+/* update cache, then return new lines */
+
+/* If cache does not exist, then create
+ the new instance. */ /* public */
+bool DatManager::updateCache( const KURL& url , const QObject* parent )
+{
+ QMutexLocker locker( &m_mutex );
+
+ DatInfo * datInfo = getDatInfo( url );
+
+ /* create new DatInfo */
+ if ( datInfo == NULL ){
+ datInfo = new DatInfo( url );
+ m_datInfo.prepend( datInfo );
+ }
+
+ return datInfo->updateCache(parent);
+}
+
+
+/* public */
+int DatManager::getResponseCode( const KURL& url )
+{
+ QMutexLocker locker( &m_mutex );
+
+ DatInfo * datInfo = getDatInfo( url );
+ if ( datInfo == NULL ) return 0;
+
+ return datInfo->getResponseCode();
+}
+
+/* public */
+int DatManager::getServerTime( const KURL& url )
+{
+ QMutexLocker locker( &m_mutex );
+
+ DatInfo * datInfo = getDatInfo( url );
+ if ( datInfo == NULL ) return 0;
+
+ return datInfo->getServerTime();
+}
+
+
+/* public */
+bool DatManager::deleteCache( const KURL& url, QWidget* parent )
+{
+ QMutexLocker locker( &m_mutex );
+
+ DatInfo * datInfo = getDatInfo( url );
+ if ( datInfo == NULL ) return FALSE;
+
+ return datInfo->deleteCache(parent);
+}
+
+
+/* public */
+bool DatManager::isLoadingNow( const KURL& url )
+{
+ QMutexLocker locker( &m_mutex );
+
+ DatInfo * datInfo = getDatInfo( url );
+ if ( datInfo == NULL ) return FALSE;
+
+ return datInfo->isLoadingNow();
+}
+
+
+/* public */
+void DatManager::stopLoading( const KURL& url )
+{
+
+ /* Don't use QMutexLocker here !!
+ It will cause deadlock , because
+ Kita::Access::stopJob() calls KitaThreadView::slotFinishLoad() back. */
+ m_mutex.lock();
+ DatInfo * datInfo = getDatInfo( url );
+ m_mutex.unlock();
+ if ( datInfo == NULL ) return;
+
+ return datInfo->stopLoading();
+}
+
+
+
+/*----------------------*/
+/* lock, unlock DatInfo */
+
+/* If cache does not exist, then create
+ the new instance and lock it.
+
+ Don't forget to unlock it. */ /* public */
+
+void DatManager::lock( const KURL& url )
+{
+ QMutexLocker locker( &m_mutex );
+
+ DatInfo * datInfo = getDatInfo( url );
+
+ /* create new DatInfo */
+ if ( datInfo == NULL ){
+ datInfo = new DatInfo( url );
+ m_datInfo.prepend( datInfo );
+ }
+
+ datInfo->lock();
+}
+
+void DatManager::unlock( const KURL& url )
+{
+ QMutexLocker locker( &m_mutex );
+
+ DatInfo * datInfo = getDatInfo( url );
+ if ( datInfo == NULL ) return;
+
+ datInfo->unlock();
+}
+
+
+
+/* public */
+const QString& DatManager::getSubject( const KURL& url )
+{
+ QMutexLocker locker( &m_mutex );
+
+ DatInfo * datInfo = getDatInfo( url );
+ if ( datInfo == NULL ) return QString::null;
+
+ return datInfo->getSubject();
+}
+
+
+/* public */
+const QString& DatManager::getRawDat( const KURL& url )
+{
+ QMutexLocker locker( &m_mutex );
+
+ DatInfo * datInfo = getDatInfo( url );
+ if ( datInfo == NULL ) return QString::null;
+
+ return datInfo->getRawDat();
+}
+
+
+/* public */
+const QString& DatManager::getDat( const KURL& url, int num )
+{
+ QMutexLocker locker( &m_mutex );
+
+ DatInfo * datInfo = getDatInfo( url );
+ if ( datInfo == NULL ) return QString::null;
+
+ return datInfo->getDat( num );
+}
+
+
+
+/* public */
+QString DatManager::getPlainBody( const KURL& url, int num )
+{
+ QMutexLocker locker( &m_mutex );
+
+ DatInfo * datInfo = getDatInfo( url );
+ if ( datInfo == NULL ) return QString::null;
+
+ return datInfo->getPlainBody(num);
+}
+
+
+
+/* public */
+QString DatManager::getHtml( const KURL& url, int startnum, int endnum )
+{
+ QMutexLocker locker( &m_mutex );
+
+ DatInfo * datInfo = getDatInfo( url );
+ if ( datInfo == NULL ) return QString::null;
+
+ return datInfo->getHtml(startnum,endnum);
+}
+
+
+
+/* public */
+QString DatManager::getHtmlByID(const KURL& url, const QString& strid, int &count )
+{
+ QMutexLocker locker( &m_mutex );
+
+ DatInfo* datInfo = getDatInfo(url);
+ if(datInfo == NULL) return QString::null;
+
+ return datInfo->getHtmlByID(strid,count);
+}
+
+
+
+/* Get HTML document of res tree.*/ /* public */
+QString DatManager::getTreeByRes(const KURL& url, const int rootnum, int &count)
+{
+ QMutexLocker locker( &m_mutex );
+
+ DatInfo* datInfo = getDatInfo(url);
+ if(datInfo == NULL) return QString::null;
+
+ return datInfo->getTreeByRes(rootnum,count);
+}
+
+
+
+/* public */
+int DatManager::getMaxResNumber( const KURL& url )
+{
+ QMutexLocker locker( &m_mutex );
+
+ DatInfo * datInfo = getDatInfo( url );
+ if ( datInfo == NULL ) return 0;
+
+ return datInfo->getMaxResNumber();
+}
+
+
+
+/* public */
+int DatManager::getNumByID( const KURL& url, const QString& strid )
+{
+ QMutexLocker locker( &m_mutex );
+
+ DatInfo * datInfo = getDatInfo( url );
+ if ( datInfo == NULL ) return 0;
+
+ return datInfo->getNumByID(strid);
+}
+
+
+
+/* public */
+int DatManager::getKokoyonNum( const KURL& url )
+{
+ QMutexLocker locker( &m_mutex );
+
+ DatInfo * datInfo = getDatInfo( url );
+ if ( datInfo == NULL ) return 0;
+
+ return datInfo->getKokoyonNum();
+}
+
+
+/* public */
+void DatManager::setKokoyonNum( const KURL& url , int num )
+{
+ QMutexLocker locker( &m_mutex );
+
+ DatInfo * datInfo = getDatInfo( url );
+ if ( datInfo == NULL ) return;
+
+ return datInfo->setKokoyonNum(num);
+}
+
+
+/* public */
+int DatManager::getDatSize( const KURL& url )
+{
+ QMutexLocker locker( &m_mutex );
+
+ DatInfo * datInfo = getDatInfo( url );
+ if ( datInfo == NULL ) return 0;
+
+ return datInfo->getDatSize();
+}
+
+
+
+
+/* public */
+bool DatManager::isResValid( const KURL& url,int num )
+{
+ QMutexLocker locker( &m_mutex );
+
+ DatInfo * datInfo = getDatInfo( url );
+ if ( datInfo == NULL ) return FALSE;
+
+ return datInfo->isResValid(num);
+}
+
+
+/* public */
+bool DatManager::isBroken( const KURL& url )
+{
+ QMutexLocker locker( &m_mutex );
+
+ DatInfo * datInfo = getDatInfo( url );
+ if ( datInfo == NULL ) return FALSE;
+
+ return datInfo->isBroken();
+}
+
+/* public */
+bool DatManager::isResBroken( const KURL& url,int num )
+{
+ QMutexLocker locker( &m_mutex );
+
+ DatInfo * datInfo = getDatInfo( url );
+ if ( datInfo == NULL ) return FALSE;
+
+ return datInfo->isResBroken(num);
+}
+
+
+
+/* public */
+bool DatManager::checkID(const KURL& url, const QString& strid, int num )
+{
+ QMutexLocker locker( &m_mutex );
+
+ DatInfo* datInfo = getDatInfo(url);
+ if(datInfo == NULL) return FALSE;
+
+ return datInfo->checkID(strid,num);
+}
+
+
+/* check keywords */ /* public */
+bool DatManager::checkWord(const KURL& url,
+ QStringList& strlist, int num,
+ bool checkOR /* AND or OR search */
+ )
+{
+ QMutexLocker locker( &m_mutex );
+
+ DatInfo* datInfo = getDatInfo(url);
+ if(datInfo == NULL) return FALSE;
+
+ return datInfo->checkWord(strlist,num,checkOR);
+}
+
+
+/* public */
+bool DatManager::checkAbone(const KURL& url, int num)
+{
+ QMutexLocker locker( &m_mutex );
+
+ DatInfo* datInfo = getDatInfo(url);
+ if(datInfo == NULL) return FALSE;
+
+ return datInfo->checkAbone(num);
+}
+
+
+
+/*-----------------------------------*/
+/* Wrapper functions for Thread class*/
+
+/* They ara public */
+
+const QString DatManager::thread_datID( const KURL& url )
+{
+ QMutexLocker locker( &m_mutex );
+
+ DatInfo* datInfo = getDatInfo(url);
+ if(datInfo == NULL) return QString::null;
+
+ return datInfo->thread_datID();
+}
+
+const QString& DatManager::thread_name( const KURL& url )
+{
+ QMutexLocker locker( &m_mutex );
+
+ DatInfo* datInfo = getDatInfo(url);
+ if(datInfo == NULL) return QString::null;
+
+ return datInfo->thread_name();
+}
+
+const QString& DatManager::thread_boardName( const KURL& url )
+{
+ QMutexLocker locker( &m_mutex );
+
+ DatInfo* datInfo = getDatInfo(url);
+ if(datInfo == NULL) return QString::null;
+
+ return datInfo->thread_boardName();
+}
+
+const QString DatManager::thread_url( const KURL& url )
+{
+ QMutexLocker locker( &m_mutex );
+
+ DatInfo* datInfo = getDatInfo(url);
+ if(datInfo == NULL) return QString::null;
+
+ return datInfo->thread_url();
+}
+
+const QString DatManager::thread_boardURL( const KURL& url )
+{
+ QMutexLocker locker( &m_mutex );
+
+ DatInfo* datInfo = getDatInfo(url);
+ if(datInfo == NULL) return QString::null;
+
+ return datInfo->thread_boardURL();
+}
+
+const QString DatManager::thread_boardID( const KURL& url )
+{
+ QMutexLocker locker( &m_mutex );
+
+ DatInfo* datInfo = getDatInfo(url);
+ if(datInfo == NULL) return QString::null;
+
+ return datInfo->thread_boardID();
+}
+
+
+
+
--- /dev/null
+/**************************************************************************
+* Copyright (C) 2003 by Hideki Ikemoto , (c)2004 by 421 *
+* ikemo@wakaba.jp *
+* *
+* 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. *
+***************************************************************************/
+
+#ifndef KITADATMG_H
+#define KITADATMG_H
+
+#include <qvaluelist.h>
+
+class QMutex;
+class QStringList;
+class KURL;
+class QObject;
+
+namespace Kita
+{
+
+class DatInfo;
+typedef QValueList<DatInfo*> DatInfoList;
+
+class DatManager
+ {
+ static DatInfoList m_datInfo;
+ static QMutex m_mutex;
+
+ public:
+
+ static DatInfo* getDatInfoPointer( const KURL& url );
+ static void deleteDatInfo( const KURL& url );
+
+ /* caching */
+ static bool updateCache( const KURL& url , const QObject* parent);
+ static int getResponseCode( const KURL& url );
+ static int getServerTime( const KURL& url );
+ static bool deleteCache( const KURL& url , QWidget* parent);
+ static bool isLoadingNow( const KURL& url );
+ static void stopLoading( const KURL& url );
+
+
+ /* lock, unlock */
+ static void lock( const KURL& url );
+ static void unlock( const KURL& url );
+
+ /* string data */
+ 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 );
+
+
+ /* 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);
+
+ /* numerical data */
+ static int getMaxResNumber( const KURL& url );
+ static int getNumByID( const KURL& url, const QString& strid );
+ static int getKokoyonNum( const KURL& url );
+ static void setKokoyonNum( const KURL& url, int num);
+ static int getDatSize( const KURL& url );
+
+ /* another information */
+ static bool isResValid( const KURL& url , int num);
+ static bool isBroken( const KURL& url );
+ static bool isResBroken( const KURL& url , int num);
+ static bool checkID(const KURL& url, const QString& strid, int num );
+ static bool checkWord(const KURL& url,QStringList& stlist, int num, bool checkOR);
+
+ /* abone check */
+ static bool checkAbone(const KURL& url, int num);
+
+ /* Wrapper functions for Thread class */
+ static const QString thread_datID( const KURL& url );
+ static const QString& thread_name( const KURL& url );
+ static const QString& thread_boardName( const KURL& url );
+ static const QString thread_url( const KURL& url );
+ static const QString thread_boardURL( const KURL& url );
+ static const QString thread_boardID( const KURL& url );
+
+ private:
+
+ static DatInfo* getDatInfo( const KURL& url );
+ static void deleteDatInfoPrivate( const KURL& url );
+ };
+
+}
+
+#endif
--- /dev/null
+/**************************************************************************
+* Copyright (C) 2003 by Hideki Ikemoto , (c)2004 by 421 *
+* ikemo@wakaba.jp *
+* *
+* 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. *
+**************************************************************************/
+
+/* UTF-16 */
+#define UTF16_BRACKET 0xFF1E /* > */
+#define UTF16_0 0xFF10 /* 0 */
+#define UTF16_9 0xFF19 /* 9 */
+#define UTF16_EQ 0xFF1D /* = */
+#define UTF16_COMMA 0xFF0C /* , */
--- /dev/null
+/**************************************************************************
+* Copyright (C) 2003 by Hideki Ikemoto , (c)2004 by 421 *
+* ikemo@wakaba.jp *
+* *
+* 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. *
+***************************************************************************/
+
+/*--------------------------------------*/
+/* miscellaneous utilities for parsing */
+
+#include <qmutex.h>
+#include <qregexp.h>
+#include <qdatetime.h>
+
+#include "qcp932codec.h"
+#include "parsemisc.h"
+#include "kita-utf8.h"
+#include "kita-utf16.h"
+
+#define KITA_RESDIGIT 4
+
+using namespace Kita;
+
+
+/*---------------------------------------------------*/
+
+/* Text codec */
+
+QCp932Codec* ParseMisc::m_qcpCodec = NULL;
+QTextCodec* ParseMisc::m_utf8Codec = NULL;
+QMutex ParseMisc:: m_codexMutex;
+
+QString ParseMisc::qcpToUnicode( const QString& str ){
+
+ QMutexLocker locker( & m_codexMutex ); /* QTextCodec is not reentrant. */
+
+ if(!m_qcpCodec) m_qcpCodec = new QCp932Codec();
+
+ return m_qcpCodec->toUnicode( str );
+}
+
+
+QString ParseMisc::utf8ToUnicode( const QString& str ){
+
+ QMutexLocker locker( & m_codexMutex ); /* QTextCodec is not reentrant. */
+
+ if(!m_utf8Codec) m_utf8Codec = QTextCodec::codecForName( "utf8" );
+
+ return m_utf8Codec->toUnicode( str );
+}
+
+
+
+
+
+/*------------------------------------------*/
+/* parsing function for anchor (>>digits) */
+/*------------------------------------------*/ /* public */
+
+/* This fuction parses res anchor.
+
+ For example, if cdat = ">12-20", then
+
+ linkstr = ">12-20",
+ refNum[0] = 12,
+ refNum[1] = 20,
+ pos = 9,
+ ret = TRUE;
+
+ This function is called in
+
+ DatInfo::setAncList and KitaDomTree::createResAnchor. */
+
+bool ParseMisc::parseResAnchor(
+
+ /* input */
+ const QChar *cdat, const unsigned int length,
+
+ /* output */
+ QString& linkstr, int* refNum, unsigned int& pos ){
+
+ struct LocalFunc {
+ static bool isHYPHEN( unsigned short c )
+ {
+
+ /* UTF-16 */
+ if ( c == '-'
+ || ( c >= 0x2010 && c <= 0x2015 )
+ || ( c == 0x2212 )
+ || ( c == 0xFF0D ) /* UTF8: 0xEFBC8D */
+ ) {
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+ };
+
+ bool ret = FALSE;
+ int i;
+
+ linkstr = QString::null;
+ refNum[0] = 0;
+ refNum[1] = 0;
+ pos = 0;
+
+ /* check '>' twice */
+ for ( i = 0;i < 2;i++ ) {
+
+ if ( cdat[ pos ].unicode() == UTF16_BRACKET ) {
+ linkstr += cdat[ pos ];
+ pos++;
+ } else if ( cdat[ pos ] == '&' && cdat[ pos + 1 ] == 'g' /* > */
+ && cdat[ pos + 2 ] == 't' && cdat[ pos + 3 ] == ';' ) {
+ linkstr += ">";
+ pos += 4;
+ }
+
+ }
+
+ /* check ',' */
+ if ( !pos ) {
+ if ( cdat[ pos ] == ',' || cdat[ pos ].unicode() == UTF16_COMMA ) {
+ linkstr += ",";
+ pos ++;
+ }
+ }
+
+ /* check '=' */
+ if ( !pos ) {
+ if ( cdat[ pos ] == '=' || cdat[ pos ].unicode() == UTF16_EQ ) {
+ linkstr += "=";
+ pos ++;
+ }
+ }
+
+ /* check digits */
+ int hyphen = 0;
+
+ if( pos ){
+
+ for ( i = 0 ; i < KITA_RESDIGIT + 1 && pos < length ; i++, pos++ ) {
+
+ unsigned short c = cdat[ pos ].unicode();
+
+ if ( ( c < UTF16_0 || c > UTF16_9 )
+ && ( c < '0' || c > '9' )
+ && ( !LocalFunc::isHYPHEN( c )
+ || ( i == 0 && LocalFunc::isHYPHEN( c ) )
+ || ( hyphen && LocalFunc::isHYPHEN( c ) ) )
+ ) break;
+
+ linkstr += cdat[ pos ];
+
+ if ( LocalFunc::isHYPHEN( c ) ) {
+ hyphen = 1;
+ i = -1;
+ } else {
+ if ( c >= UTF16_0 ) c = '0' + cdat[ pos ].unicode() - UTF16_0;
+ refNum[hyphen] *= 10;
+ refNum[hyphen] += c - '0';
+ }
+
+ ret = TRUE;
+ }
+ }
+
+ return ret;
+}
+
+
+/*-----------------------------------------------------*/
+/* parsing function for special char (such as ♥ */
+/*-----------------------------------------------------*/ /* public */
+
+/* For example, if cdat = "&", then
+
+ pos = 5,
+ retstr = "&".
+
+ This function is called in
+
+ DatInfo::getPlainBody and KitaDomTree::parseHTMLdat. */
+
+QString ParseMisc::parseSpecialChar(
+
+ /* input */
+ const QChar *cdat,
+
+ /* output */
+ unsigned int& pos ){
+
+ struct LocalFunc {
+ static int 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;
+ }
+ };
+
+ QString retstr = QString::null;
+
+ if ( ( pos = LocalFunc::isEqual( cdat , ">" ) ) ) retstr = ">";
+ else if ( ( pos = LocalFunc::isEqual( cdat , "<" ) ) ) retstr = "<";
+ else if ( ( pos = LocalFunc::isEqual( cdat , " " ) ) ) retstr = " ";
+ else if ( ( pos = LocalFunc::isEqual( cdat , "&" ) ) ) retstr = "&";
+ else if ( ( pos = LocalFunc::isEqual( cdat , """ ) ) ) retstr = "\"";
+
+ else if ( ( pos = LocalFunc::isEqual( cdat , "♥" ) ) )
+ retstr = utf8ToUnicode( KITAUTF8_HEART );
+
+ else if ( ( pos = LocalFunc::isEqual( cdat , "♦" ) ) )
+ retstr = utf8ToUnicode( KITAUTF8_DIA );
+
+ else if ( ( pos = LocalFunc::isEqual( cdat , "♣" ) ) )
+ retstr = utf8ToUnicode( KITAUTF8_CLUB );
+
+ else if ( ( pos = LocalFunc::isEqual( cdat , "♠" ) ) )
+ retstr = utf8ToUnicode( KITAUTF8_SPADE );
+
+ return retstr;
+}
+
+
+
+/* copied from comment.cpp */
+/*
+ This function is called in
+
+ DatInfo::DatInfo::parseDat and KitaDomTree::parseRes */
+void ParseMisc::parseDateId( const QString& str ,
+ QString &idstr,
+ QString &dateIdstr, QDateTime &dTime )
+
+{
+ QRegExp regexp( "(\\d\\d)/(\\d\\d)/(\\d\\d) (\\d\\d):(\\d\\d)( ID:(.*))?" );
+
+ if ( regexp.search( str ) == -1 ) {
+ dateIdstr = 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() ) );
+
+ dTime = dateTime;
+ idstr = regexp.cap( 7 );
+}
--- /dev/null
+/**************************************************************************
+* Copyright (C) 2003 by Hideki Ikemoto , (c)2004 by 421 *
+* ikemo@wakaba.jp *
+* *
+* 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. *
+***************************************************************************/
+
+#ifndef KITAPARMISC_H
+#define KITAPARMISC_H
+
+class QMutex;
+class QTextCodec;
+class QDateTime;
+class QCp932Codec;
+
+namespace Kita
+{
+
+class ParseMisc
+ {
+ static QMutex m_codexMutex;
+ static QCp932Codec* m_qcpCodec;
+ static QTextCodec* m_utf8Codec;
+
+ public:
+
+ /* Text codec */
+ static QString qcpToUnicode( const QString& str );
+ static QString utf8ToUnicode( const QString& str );
+
+
+ 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);
+ };
+
+}
+
+#endif
+
#include <kcmdlineargs.h>
#include <klocale.h>
+#include "libkita/kitaconfig.h"
+
static const char *description =
I18N_NOOP("Kita - 2ch client for KDE");
libkitapart_la_LIBADD = $(LIB_KPARTS) $(LIB_KHTML) -lkita
-libkitapart_la_SOURCES = kitathreadview.cpp kitathreadviewbase.ui kitathreadpart.cpp kitawritedialogbase.ui kitawritedialog.cpp kita2ch.cpp kitahtmlpart.cpp kitaconfig.cpp kitahtmlview.cpp kitadomtree.cpp datmanager.cpp kitanavi.cpp
+libkitapart_la_SOURCES = kitathreadview.cpp kitathreadviewbase.ui kitathreadpart.cpp kitawritedialogbase.ui kitawritedialog.cpp kita2ch.cpp kitahtmlpart.cpp kitahtmlview.cpp kitadomtree.cpp kitanavi.cpp
-noinst_HEADERS = kitathreadview.h kitathreadpart.h kitawritedialog.h kita2ch.h kitahtmlpart.h kitaconfig.h kitahtmlview.h kitadomtree.h datmanager.h kitanavi.h
+noinst_HEADERS = kitathreadview.h kitathreadpart.h kitawritedialog.h kita2ch.h kitahtmlpart.h kitahtmlview.h kitadomtree.h kitanavi.h
METASOURCES = AUTO
+++ /dev/null
-/**************************************************************************
-* Copyright (C) 2003 by Hideki Ikemoto , (c)2004 by 421 *
-* ikemo@wakaba.jp *
-* *
-* 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. *
-***************************************************************************/
-
-#include "datmanager.h"
-#include "libkita/qcp932codec.h"
-#include "libkita/comment.h"
-#include "libkita/access.h"
-#include "kitaconfig.h"
-#include "kita-utf8.h"
-#include <qregexp.h>
-#include <qsemaphore.h>
-
-using namespace Kita;
-
-/* UTF-16 */
-#define UTF16_BRACKET 0xFF1E /* > */
-#define UTF16_0 0xFF10 /* 0 */
-#define UTF16_9 0xFF19 /* 9 */
-#define UTF16_EQ 0xFF1D /* = */
-#define UTF16_COMMA 0xFF0C /* , */
-
-#define KITA_RESDIGIT 4
-
-/*---------------------------------------------------*/
-
-/* DatInfo stores information of *.dat */
-
-DatInfo::DatInfo( const KURL& url ) : m_url( url )
-{
-
- QString idstr;
- KURL logurl = url;
- logurl.setProtocol( "k2ch" );
- QString rawdata = Kita::Access::getCacheData( logurl );
- m_linedat.clear();
- m_subject = QString::null;
- m_maxNum = 0;
- m_spacestr = QString::null;
- m_anclistmap.clear();
-
- if ( rawdata.length() ) {
- QCp932Codec codec;
- QString linedata = codec.toUnicode( rawdata );
-
- QStringList lines = QStringList::split( "\n", linedata );
- for ( QStringList::iterator it = lines.begin(); it != lines.end(); ++it, ++m_maxNum ) {
-
- /* copy dat */
- m_linedat += ( *it );
-
- /* get id & copy */
- idstr = "none";
- QStringList list = QStringList::split( "<>", ( *it ), true );
- if ( list.size() == 5 ) {
- /* copied from Comment::parseDateId */
- QRegExp regexp( "(\\d\\d)/(\\d\\d)/(\\d\\d) (\\d\\d):(\\d\\d)( ID:(.*))?" );
- if ( regexp.search( list[ 2 ] ) != -1 ) idstr = regexp.cap( 7 );
-
- /* get subject */
- if ( m_subject == QString::null && list[ 4 ] != QString::null ) m_subject = list[ 4 ];
- }
- m_idlist += idstr;
- }
- }
-}
-
-
-const QString& DatInfo::getDat( int num )
-{
-
- if ( num > m_maxNum ) return QString::null;
-
- if ( m_linedat.at( num - 1 ) == m_linedat.end() ) return QString::null;
-
- return *( m_linedat.at( num - 1 ) );
-}
-
-
-const QString& DatInfo::getId( int num )
-{
-
- if ( num > m_maxNum ) return QString::null;
-
- if ( m_idlist.at( num - 1 ) == m_linedat.end() ) return QString::null;
-
- return *( m_idlist.at( num - 1 ) );
-}
-
-/* convert dat to HTML */
-QString DatInfo::getHtml(int num){
-
- QString retstr = QString::null;
- QString line = getDat(num);
- bool showAddr = KitaConfig::showMailAddress();
-
- if(line != QString::null){
-
- Kita::Comment comment( line );
-
- /* check abone */
- if(DatManager::checkAbone(getId(num),ABONECHK_BY_ID)) return retstr;
- if(DatManager::checkAbone(comment.getName(),ABONECHK_BY_NAME)) return retstr;
- if(DatManager::checkAbone(comment.getBody(),ABONECHK_BY_WORD)) return retstr;
-
- retstr = comment.toHtml( num, showAddr );
- }
-
- return retstr;
-}
-
-
-/* Check if No.num has anchors to No.target */
-/* For exsample, if No.num has an anchor ">>target",
- then return TRUE. */
-bool DatInfo::checkRes(const int target, const int num )
-{
- AncList anclist;
- AncListMap::Iterator ancmapit = m_anclistmap.find(num);
-
- /* If map is not set, then do parsing */
- if(ancmapit == m_anclistmap.end() ){
-
- QString line = getDat(num);
- if(line == QString::null) return FALSE;
-
- ANCNUM anctmp;
- QString linkstr;
- int refNum[2];
- unsigned int pos;
-
- /* dummy */
- anclist.clear();
- anctmp.from = 0;
- anctmp.to = 0;
- anclist += anctmp;
-
- /* remove HTML tags */
- QRegExp rex( "<[^>]*>" );
- line.remove(rex);
-
- const QChar *chpt = line.unicode();
- unsigned int i;
- unsigned int length = line.length();
-
- for ( i = 0 ; i < length ; i++ ) {
-
- if( chpt[ i ].unicode() == UTF16_BRACKET ||
- (chpt[ i] == '&' && chpt[ i+1] == 'g' && chpt[ i+2] == 't' && chpt[ i+3] == ';')){
-
- while(DatManager::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;
- }
-
- i += (pos-1);
- }
- }
-
- ancmapit = m_anclistmap.insert(num,anclist);
- }
- /* end parsing */
-
- for ( AncList::iterator it = (*ancmapit).begin(); it != (*ancmapit).end(); ++it ){
- if ( target >= (*it).from && target <= (*it).to ) return TRUE;
- }
-
- return FALSE;
-}
-
-
-/* Get HTML document of res tree.*/
-/* For example,
-
->>1
-|-->>4
-| |--->>10
-|
-|-->>20
-
-*/
-QString DatInfo::getTreeByRes(const int rootnum, int& num, QString prestr )
-{
- QString retstr = QString::null ;
- num = 0;
- int maxNum = getMaxResNumber();
- QStringList strlists;
-
- if(m_spacestr == QString::null){
- QTextCodec * codec = QTextCodec::codecForName( "utf8" );
- m_spacestr = ". ";
- m_framestr1 = codec->toUnicode( KITAUTF8_FRAME1 ); /* | */
- m_framestr2 = codec->toUnicode( KITAUTF8_FRAME2 ); /* |- */
- m_framestr3 = codec->toUnicode( KITAUTF8_FRAME3 ); /* L */
- }
-
- /* find responses that refer to rootnum */
- for ( int i = rootnum+1; i <= maxNum; i++ ){
- if(checkRes(rootnum,i)){
- num ++;
- strlists += QString().setNum( i );
- }
- }
-
- /* make HTML document */
- if(num){
-
- for ( QStringList::iterator it = strlists.begin(); it != strlists.end(); ++it ){
- QString tmpstr;
- if((*it) == strlists.last()) tmpstr = m_framestr3;
- else tmpstr = m_framestr2;
- retstr += prestr + tmpstr + "<a href=\"#" + (*it) + "\">>>" + (*it) + "</a><br>";
-
- /* call myself recursively */
- if((*it) == strlists.last()) tmpstr = prestr + m_spacestr + m_spacestr + m_spacestr;
- else tmpstr = prestr + m_framestr1 + m_spacestr;
- int tmpnum;
- retstr += getTreeByRes((*it).toInt(),tmpnum,tmpstr);
- num += tmpnum;
- }
- }
-
- return retstr;
-}
-
-
-/*---------------------------------------------------*/
-
-/* DatManager manages all information about *.dat. */
-
-DatInfoList DatManager::m_datInfo;
-QSemaphore DatManager::m_semap( 1 );
-
-/* private */
-/* This function searches instance of DatInfo specified by url.
- If instance does not exist, create instance. */
-DatInfo* DatManager::getDatInfo( const KURL& url )
-{
-
- m_semap++;
-
- if ( url.isEmpty() ) {
- m_semap--;
- return NULL;
- }
-
- int i = 0;
- DatInfoList::Iterator it;
-
- /* search */
- if ( m_datInfo.count() ) {
- for ( it = m_datInfo.begin(); it != m_datInfo.end(); ++it, i++ ) {
-
- if ( url.host() == ( *it ) ->url().host() &&
- url.path() == ( *it ) ->url().path() ) {
-
- /* LRU */
- if ( i ) {
- m_datInfo.remove( it );
- m_datInfo.prepend( ( *it ) );
- }
-
- m_semap--;
- return ( *it );
- }
- }
- }
-
- /* not found */
-
- /*create new DatInfo and insert it into list. */
- KURL daturl = url.protocol() + "://" + url.host() + url.path();
-
- DatInfo* datInfo;
- datInfo = new DatInfo( daturl );
- if ( datInfo->getMaxResNumber() == 0 ) { /* cache does not exist */
- delete( datInfo );
-
- m_semap--;
- return NULL;
- }
-
- m_datInfo.prepend( datInfo );
-
- /* delete the last item of list */
- if ( m_datInfo.count() > DMANAGER_MAXQUEUE ) {
- it = m_datInfo.fromLast();
- m_datInfo.remove( it );
-
- delete( *it );
- }
-
- m_semap--;
- return datInfo;
-}
-
-
-/* public */
-void DatManager::deleteDat( const KURL& url )
-{
- m_semap++;
-
- DatInfoList::Iterator it;
-
- for ( it = m_datInfo.begin(); it != m_datInfo.end(); ++it ) {
- if ( url.host() == ( *it ) ->url().host() &&
- url.path() == ( *it ) ->url().path() ) {
- m_datInfo.remove( it );
- delete( *it );
-
- m_semap--;
- return ;
- }
- }
-
- m_semap--;
-}
-
-
-/* public */
-const QString& DatManager::getDat( const KURL& url, int num )
-{
- DatInfo * datInfo = getDatInfo( url );
- if ( datInfo == NULL ) return QString::null;
-
- return datInfo->getDat( num );
-}
-
-/* public */
-const QString& DatManager::getSubject( const KURL& url )
-{
- DatInfo * datInfo = getDatInfo( url );
- if ( datInfo == NULL ) return QString::null;
-
- return datInfo->getSubject();
-}
-
-
-/* public */
-int DatManager::getNumByID( const KURL& url, const QString& strid )
-{
-
- DatInfo * datInfo = getDatInfo( url );
- if ( datInfo == NULL ) return 0;
-
- int num = 0;
- int maxNum = datInfo->getMaxResNumber();
-
- for ( int i = 1; i <= maxNum; i++ ) {
- if ( datInfo->getId( i ) == strid ) num ++;
- }
-
- return num;
-}
-
-
-/* public */
-int DatManager::getMaxResNumber( const KURL& url )
-{
- DatInfo * datInfo = getDatInfo( url );
- if ( datInfo == NULL ) return 0;
-
- return datInfo->getMaxResNumber();
-}
-
-
-/* public */
-QString DatManager::getHtml( const KURL& url, int startnum, int endnum )
-{
-
- DatInfo * datInfo = getDatInfo( url );
- if ( datInfo == NULL ) return QString::null;
-
- QString retstr = QString::null ;
-
- for(int num = startnum; num <= endnum; num++)
- retstr += datInfo->getHtml(num);
-
- return retstr;
-}
-
-
-/* public */ /* This function is also called by kitadomtree. */
-bool DatManager::checkAbone( const QString& str, int mode )
-{
-
- QStringList & strlist = KitaConfig::aboneIDList();
- switch ( mode ) {
- case ABONECHK_BY_ID: break;
- case ABONECHK_BY_NAME: strlist = KitaConfig::aboneNameList(); break;
- case ABONECHK_BY_WORD: strlist = KitaConfig::aboneWordList(); break;
- default: return FALSE;
- }
-
- int i = -1;
- for ( QStringList::iterator it = strlist.begin();
- it != strlist.end(); ++it ) {
- i = str.find( ( *it ) );
- if ( i != -1 ) {
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-
-/* public */
-QString DatManager::getHtmlByID(const KURL& url, const QString& strid, int &num ){
-
- DatInfo* datInfo = getDatInfo(url);
- if(datInfo == NULL) return QString::null;
-
- QString retstr = QString::null ;
- num = 0;
- int maxNum = datInfo->getMaxResNumber();
-
- for ( int i = 1; i <= maxNum; i++ ) {
- if(datInfo->getId(i) == strid){
- num ++;
- retstr += datInfo->getHtml(i);
- }
- }
-
- return retstr;
-}
-
-
-/* public */
-bool DatManager::checkID(const KURL& url, const QString& strid, int num ){
-
- DatInfo* datInfo = getDatInfo(url);
- if(datInfo == NULL) return FALSE;
-
- if(datInfo->getId(num) == strid) return TRUE;
-
- return FALSE;
-}
-
-
-/* check keywords */ /* public */
-bool DatManager::checkWord(const KURL& url,
- QStringList& stlist, int num,
- bool checkOR /* AND or OR search */
- )
-{
- DatInfo* datInfo = getDatInfo(url);
- if(datInfo == NULL) return FALSE;
-
- QString str_text = datInfo->getDat(num);
- if(str_text == QString::null) return FALSE;
-
- 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;
-}
-
-
-/*------------------------------------------*/
-/* parsing function for anchor (>>number) */
-/*------------------------------------------*/ /* public */
-
-/* This fuction parses res-anchor.
-
- For example, if cdat = ">12-20", then
-
- linkstr = ">12-20",
- refNum[0] = 12,
- refNum[1] = 20,
- pos = 9.
-
- This function is also called in KitaDomTree::createResAnchor. */
-
-bool DatManager::parseResAnchor(
-
- /* input */
- const QChar *cdat, const unsigned int length,
-
- /* output */
- QString& linkstr, int* refNum, unsigned int& pos ){
-
- struct LocalFunc {
- static bool isHYPHEN( unsigned short c )
- {
-
- /* UTF-16 */
- if ( c == '-'
- || ( c >= 0x2010 && c <= 0x2015 )
- || ( c == 0x2212 )
- || ( c == 0xFF0D ) /* UTF8: 0xEFBC8D */
- ) {
- return TRUE;
- }
-
- return FALSE;
- }
- };
-
- bool ret = FALSE;
- int i;
-
- linkstr = QString::null;
- refNum[0] = 0;
- refNum[1] = 0;
- pos = 0;
-
- /* check '>' twice */
- for ( i = 0;i < 2;i++ ) {
-
- if ( cdat[ pos ].unicode() == UTF16_BRACKET ) {
- linkstr += cdat[ pos ];
- pos++;
- } else if ( cdat[ pos ] == '&' && cdat[ pos + 1 ] == 'g' /* > */
- && cdat[ pos + 2 ] == 't' && cdat[ pos + 3 ] == ';' ) {
- linkstr += ">";
- pos += 4;
- }
-
- }
-
- /* check ',' */
- if ( !pos ) {
- if ( cdat[ pos ] == ',' || cdat[ pos ].unicode() == UTF16_COMMA ) {
- linkstr += ",";
- pos ++;
- }
- }
-
- /* check '=' */
- if ( !pos ) {
- if ( cdat[ pos ] == '=' || cdat[ pos ].unicode() == UTF16_EQ ) {
- linkstr += "=";
- pos ++;
- }
- }
-
- /* check numbers */
- int hyphen = 0;
-
- if( pos ){
-
- for ( i = 0 ; i < KITA_RESDIGIT + 1 && pos < length ; i++, pos++, ret = TRUE ) {
-
- unsigned short c = cdat[ pos ].unicode();
-
- if ( ( c < UTF16_0 || c > UTF16_9 )
- && ( c < '0' || c > '9' )
- && ( !LocalFunc::isHYPHEN( c )
- || ( i == 0 && LocalFunc::isHYPHEN( c ) )
- || ( hyphen && LocalFunc::isHYPHEN( c ) ) )
- ) break;
-
- linkstr += cdat[ pos ];
-
- if ( LocalFunc::isHYPHEN( c ) ) {
- hyphen = 1;
- i = -1;
- } else {
- if ( c >= UTF16_0 ) c = '0' + cdat[ pos ].unicode() - UTF16_0;
- refNum[hyphen] *= 10;
- refNum[hyphen] += c - '0';
- }
- }
- }
-
- return ret;
-}
-
-/* public */
-bool DatManager::checkRes(const KURL& url,const int target,const int num )
-{
- DatInfo* datInfo = getDatInfo(url);
- if(datInfo == NULL) return FALSE;
-
- return datInfo->checkRes(target,num);
-}
-
-
-/* public */
-QString DatManager::getTreeByRes(const KURL& url, const int resNum, int &num ){
-
- DatInfo* datInfo = getDatInfo(url);
- if(datInfo == NULL) return QString::null;
-
- QString retstr = QString::null ;
- num = 0;
-
- QString tmp = QString().setNum( resNum );
- retstr = "<a href=\"#" + tmp + "\">>>" + tmp + "</a><br>";
- retstr += datInfo->getTreeByRes(resNum,num,"");
-
- return retstr;
-}
-
+++ /dev/null
-/**************************************************************************
-* Copyright (C) 2003 by Hideki Ikemoto , (c)2004 by 421 *
-* ikemo@wakaba.jp *
-* *
-* 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. *
-***************************************************************************/
-
-#ifndef KITADATMG_H
-#define KITADATMG_H
-
-#include <qstringlist.h>
-#include <kurl.h>
-#include <qmap.h>
-
-class QSemaphore;
-
-namespace Kita
-{
-
-#define DMANAGER_MAXQUEUE 15
-
- enum{
- ABONECHK_BY_ID,
- ABONECHK_BY_NAME,
- ABONECHK_BY_WORD
- };
-
-/* Database for anchor information */
-/* For example, 5-th res has anchors >>2-3 and >>4, then,
-
- m_anclistmap[5].at(0).from = 2,
- m_anclistmap[5].at(0).to = 3,
- m_anclistmap[5].at(1).from = 4,
- m_anclistmap[5].at(1).from = 4.
-
-*/
-struct ANCNUM{
- int from;
- int to;
-};
-typedef QValueList<ANCNUM> AncList;
-typedef QMap<int,AncList> AncListMap;
-
- /*-----------------------*/
-
- class DatInfo
- {
- int m_maxNum;
- KURL m_url;
- QString m_subject;
- QStringList m_linedat;
- QStringList m_idlist;
- AncListMap m_anclistmap;
-
- QString m_spacestr;
- QString m_framestr1; /* '|' */
- QString m_framestr2; /* '|-' */
- QString m_framestr3; /* 'L' */
-
- public:
- DatInfo();
- DatInfo( const KURL& url );
- const QString& getDat( int num );
- const QString& getId( int num );
- const QString& getSubject() { return m_subject;}
- KURL& url() { return m_url;};
- int getMaxResNumber() { return m_maxNum;}
- QString getHtml(int num);
- bool checkRes(const int target, const int num );
- QString getTreeByRes(const int rootnum, int& num, QString prestr );
- };
-
- /*-----------------------*/
- typedef QValueList<DatInfo*> DatInfoList;
-
- class DatManager
- {
- static DatInfoList m_datInfo;
- static QSemaphore m_semap;
-
- public:
- static void deleteDat( const KURL& url );
- static const QString& getDat( const KURL& url, int num );
- static const QString& getSubject( const KURL& url );
- static QString getHtml( const KURL& url, int startnum, int endnum );
- static int getMaxResNumber( const KURL& url );
- static int getNumByID(const KURL& url, const QString& strid );
- static QString getHtmlByID(const KURL& url, const QString& strid, int &num );
- static QString getTreeByRes(const KURL& url, const int resNum, int &num );
- static bool checkID(const KURL& url, const QString& strid, int num );
- static bool checkWord(const KURL& url,QStringList& stlist, int num, bool checkOR);
- static bool checkRes(const KURL& url, const int target,const int num );
-
- static bool checkAbone( const QString& str, int mode );
- static bool parseResAnchor(const QChar *cdat,const unsigned int length,QString& linkstr,int* refNum,unsigned int& pos);
- private:
- static DatInfo* getDatInfo( const KURL& url );
- };
-
-
-}
-
-#endif
/* This class keeps information of the DOM tree, creates the node,
and do parsing, rendering, etc. */
-#include "kitaconfig.h"
#include "kitadomtree.h"
#include "kitathreadview.h"
-#include "datmanager.h"
+#include "libkita/kitaconfig.h"
+#include "libkita/parsemisc.h"
/* UTF-16 */
#define KITADOM_BRACKET 0xFF1E /* > */
#define KITADOM_COMMA 0xFF0C /* , */
/* UTF-8 */
-#include "kita-utf8.h"
+#include "libkita/kita-utf8.h"
enum{
unsigned int pos;
unsigned int length = str.length();
- bool ret = Kita::DatManager::parseResAnchor(chpt+i,length-i,linkstr,refNum,pos);
+ 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;
#include "kitathreadview.h"
#include "kitahtmlview.h"
#include "kitadomtree.h"
-#include "kitaconfig.h"
+#include "libkita/kitaconfig.h"
#include <kpopupmenu.h>
#include <klocale.h>
#include <qmessagebox.h>
#include "kitathreadtabwidget.h"
-#include "datmanager.h"
+#include "libkita/datmanager.h"
#include "libkita/kita_misc.h"
#include "libkita/thread.h"
+#include "libkita/kita-utf8.h"
#include "kitanavi.h"
#include "kitathreadview.h"
-#include "kita-utf8.h"
#define MAX_TABLABEL_LEN 8
bool KitaThreadPart::closeURL()
{
- m_threadview->killJob();
return true;
}
#include <kmessagebox.h>
#include <kdebug.h>
-#include <kio/netaccess.h>
#include <dom/html_inline.h>
#include <dom/html_base.h>
#include "kitahtmlpart.h"
#include "kitawritedialog.h"
#include "kita2ch.h"
-#include "kitaconfig.h"
-#include "kita-utf8.h"
-#include "datmanager.h"
#include "kitanavi.h"
-#include "libkita/access.h"
+#include "libkita/kitaconfig.h"
+#include "libkita/kita-utf8.h"
#include "libkita/threadinfo.h"
#include "libkita/qcp932codec.h"
#include "libkita/favoritethreads.h"
+#include "libkita/datmanager.h"
+#include "libkita/parsemisc.h"
#define MAX_LABEL_LENGTH 60
KitaThreadView::KitaThreadView( QWidget* parent, const char* name )
: KitaThreadViewBase( parent, name )
- , m_access( 0 )
, m_popup( 0 )
{
m_thread = new Kita::NullThread();
m_viewmode = VIEWMODE_PARENT;
m_rescode = 200;
m_serverTime = 0;
+ m_datURL = QString::null;
}
KitaThreadView::~KitaThreadView()
delete m_popup;
m_popup = NULL;
}
-
- killJob();
+
+ /* unlock URL */
+ Kita::DatManager::unlock(m_datURL);
/* don't delete m_threadPart before deleting m_domtree */
if ( m_domtree ) {
emit bookmarked( m_thread->datURL(), on );
}
-void KitaThreadView::killJob()
-{
- if ( m_access ) {
- m_access->killJob();
- delete m_access;
- m_access = NULL;
- }
- m_serverTime = 0;
-}
void KitaThreadView::focusSearchCombo()
{
/*---------------------------------------*/
/* setup */
- killJob();
+ /* unlock previous URL */
+ Kita::DatManager::unlock(m_datURL);
m_thread = const_cast<Kita::Thread *>( thread );
+ m_datURL = m_thread->datURL();
+
+ /* lock new URL */
+ Kita::DatManager::lock(m_datURL);
/* setup HTMLPart */
m_threadPart->setupEx( this, m_domtree, m_thread );
/* Show thread */
/* This function is called from KitaThreadTabWidget class */
/*--------------------------------------------------------*/
-void KitaThreadView::showThread( const Kita::Thread* thread )
+void KitaThreadView::showThread( const Kita::Thread* thread2h )
{
/* If this widget is not parent, then do nothing. */
setActiveWindow();
/* setup */
- setupEx( thread , 0, VIEWMODE_PARENT );
+ setupEx( thread2h , 0, VIEWMODE_PARENT );
- /* read cache */
- update_readCache();
+ /* get log from cahce */
+ int maxnum = Kita::DatManager::getMaxResNumber(m_datURL);
+ m_rescode = 200;
+ if ( maxnum ) {
+
+ /* copy data to dom */
+ for(int i = 1; i <= maxnum; i++){
+ const QString& line = Kita::DatManager::getDat(m_datURL,i);
+ if(line != QString::null) m_domtree->setDat( line , i );
+ }
- /* update cahce & do rendering */
- update_rendering( m_online );
+ /* show templates (No.1->No.KitaDomTree::m_templateNum) */
+ m_domtree->appendTemplate();
+ /* rendering */
+ m_kokoyonNum = Kita::DatManager::getKokoyonNum(m_datURL);
+ for ( int i = m_kokoyonNum - m_preShowNum ; i <= m_kokoyonNum ; i++ )
+ m_domtree->appendRes( i, FALSE );
+ updateScreen();
+
+ m_threadPart->gotoKokoyon();
+ }
+ else {
+ m_kokoyonNum = 0;
+ showStatusBar( "" );
+ }
+
+ /* update data */
+ m_firstReceive = TRUE;
+ if( m_online ) slotReloadButton();
+ else updateInfo();
+
topLevelWidget() ->raise();
setActiveWindow();
}
case VIEWMODE_PREVIEW: break;
- case VIEWMODE_PARENT: update_rendering( m_online ); break;
+ case VIEWMODE_PARENT:
+
+ /* update cache */
+ /* After updating cache, DatManager will call slotFinishLoad.*/
+ if( m_online ){
+ m_showNum = m_domtree->getBottomResNumber() + m_afterShowNum;
+ Kita::DatManager::updateCache(m_datURL,this);
+ m_threadPart->view()->setFocus();
+ showStatusBar( Kita::ParseMisc::utf8ToUnicode( KITAUTF8_NOWRENEW ) );
+ }
+ break;
default:
}
}
+/*-----------------------------------*/
+/* slot called when Kita::DatManager
+ received new data. */ /* public slot */
+void KitaThreadView::slotReceiveData(){
+
+ int bottomNum = m_domtree->getBottomResNumber();
+ int beforeNum = m_domtree->getMaxResNumber();
+ int afterNum = Kita::DatManager::getMaxResNumber(m_datURL);
+
+ m_rescode = Kita::DatManager::getResponseCode(m_datURL);
+ m_serverTime = Kita::DatManager::getServerTime(m_datURL);
+
+ /* copy new data to DOM */
+ for(int i = beforeNum+1; i <= afterNum; i++){
+ const QString& line = Kita::DatManager::getDat(m_datURL,i);
+ if(line != QString::null){
+ m_domtree->setDat( line , i );
+ m_domtree->parseRes( i, i );
+ }
+ }
+
+ /* rendering */
+ if(bottomNum < m_showNum ){
+ for ( int i = bottomNum+1 ; i <= m_showNum; i++ ) m_domtree->appendRes( i, FALSE );
+ updateScreen();
+ if(m_firstReceive && m_kokoyonNum < afterNum ){
+ m_threadPart->gotoKokoyon();
+ m_firstReceive = FALSE;
+ }
+ }
+}
+
+/*-----------------------------------*/
+/* slot called when Kita::DatManager
+ finished updating new data. */ /* public slot */
+void KitaThreadView::slotFinishLoad(){
+
+ m_firstReceive = FALSE;
+ slotReceiveData();
+ updateScreen();
+ updateInfo();
+}
case 2:
delete popupMenu;
- m_domtree->setKokoyonNum( resNum );
- KitaThreadInfo::setReadNum( m_thread->datURL(), resNum );
- update_finish();
- gotoAnchor( datURL.ref().mid( 5 ) );
+ m_kokoyonNum = resNum;
+ Kita::DatManager::setKokoyonNum(m_datURL,resNum);
+ updateScreen();
+ gotoAnchor( QString().setNum( resNum ) );
return ;
case 3:
/*-----------------------------------------*/
void KitaThreadView::showStatusBar( QString info )
{
- int prevNum = 0;
- int totalNum = 0;
+ int totalNum = 0, datSize = 0;;
bool broken = FALSE;
QString infostr = QString::null;
QString errstr = QString::null;
case VIEWMODE_PARENT:
- prevNum = m_domtree->getKokoyonNum();
- totalNum = m_domtree->getMaxResNumber();
- broken = m_domtree->isBroken();
+ totalNum = Kita::DatManager::getMaxResNumber(m_datURL);
+ broken = Kita::DatManager::isBroken(m_datURL);
+ datSize = Kita::DatManager::getDatSize(m_datURL);
errstr = QString::null;
if ( m_rescode != 200 && m_rescode != 206 )
errstr = QString( "Error %1" ).arg( m_rescode );
if ( broken ) info += " This thread is broken.";
- if ( totalNum ) {
/* show status bar */
infostr = m_thread->name() +
- QString( " [Total: %1 New: %2]" ).arg( totalNum ).arg( totalNum - prevNum )
+ QString( " [Total: %1 New: %2] %3 k" ).arg( totalNum ).arg( totalNum - m_kokoyonNum ).arg( datSize / 1024 )
+ info + " " + errstr;
emit signalChangeStatusbar( infostr );
emit showThreadCompleted( m_thread->url() );
topLevelWidget() ->setCaption( m_thread->name() );
- } else { /* DOM tree is not initialized */
- emit signalChangeStatusbar( errstr );
- topLevelWidget() ->setCaption( "" );
- }
+
return;
break;
int top = m_domtree->getTopResNumber();
int bottom = m_domtree->getBottomResNumber();
- int maxres = m_domtree->getMaxResNumber();
int res = anc.toInt();
if ( res == 1 ) {
/* data is not set */
if ( !m_domtree->isResDataSet( res ) ) return ;
- if ( res > maxres ) return ;
/* show res if it is not shown */
if ( !m_domtree->isResShown( res ) ) {
m_threadPart->gotoAnchor( anc );
}
-/*------------*/
-/* read cache */
-/*------------*/
-void KitaThreadView::update_readCache()
-{
-
- /* create dat loader */
- if ( m_access == NULL ) {
- m_access = new Kita::Access( m_thread );
- connect( m_access, SIGNAL( redirection( const QString& ) ),
- SIGNAL( setLocationBarURL( const QString& ) ) );
- m_serverTime = m_access->serverTime();
- }
-
- /* get log from cahce & copy to dom */
- QString logline = m_access->getcache();
- if ( logline.length() ) {
- update_copydata( logline, 1 );
- m_domtree->parseAllRes();
- }
-}
-
-/*-----------------------*/
-/* copy data to dom tree */
-/*-----------------------*/
-void KitaThreadView::update_copydata( const QString& linedata,
- int basenum )
-{
- int num = basenum;
- QStringList lines = QStringList::split( "\n", linedata );
-
- m_domtree->StopParseThread();
- for ( QStringList::iterator it = lines.begin(); it != lines.end(); ++it ) {
- m_domtree->setDat( ( *it ) , num );
- num++;
- }
-}
-
-/*-------------------------*/
-/* update & rendering */
-/*-------------------------*/
-void KitaThreadView::update_rendering( bool breload )
-{
- if ( topLevelWidget() ->isMinimized() ) {
- topLevelWidget() ->showNormal();
- }
- topLevelWidget() ->raise();
- setActiveWindow();
-
- /* show clock cursor */
- QCursor qc; qc.setShape( Qt::WaitCursor );
- QApplication::setOverrideCursor( qc );
-
- showStatusBar( QTextCodec::codecForName( "utf8" ) ->toUnicode( KITAUTF8_NOWRENEW ) );
-
- /* get new data from server & copy */
- int maxres = m_domtree->getMaxResNumber();
- m_rescode = 200;
- if ( breload && m_access != NULL ) {
- QString updateline = m_access->getupdate();
-
- m_rescode = m_access->responseCode();
- if ( m_rescode == 200 || m_rescode == 206 ) {
- if ( updateline.length() > 1 ) {
- update_copydata( updateline, maxres + 1 );
- Kita::DatManager::deleteDat( m_thread->datURL() );
- }
- }
- }
- m_domtree->StopParseThread();
-
- maxres = m_domtree->getMaxResNumber();
- int prevReadNum = KitaThreadInfo::readNum( m_thread->datURL() );
- int bottom = m_domtree->getBottomResNumber();
-
- /* prevReadNum is equal to kokomade yonda. */
- /* If bottom = -1, this thread is not shown yet. */
- /* If maxres = prevReadNum, no new data was obtained. */
- /* See also kitadomtree.h */
-
- /* Data is not set */
- if ( maxres == 0 ) {
- showStatusBar( "" );
- QApplication::restoreOverrideCursor();
- return ;
- }
-
- /* Data is broken */
- if ( maxres < prevReadNum ) {
- prevReadNum = maxres;
- bottom = -1; /* reset & redraw */
- }
-
- /* This thread is not shown */
- if ( bottom < 0 ) {
- bottom = QMAX( 0, prevReadNum - m_preShowNum );
- /* show templates (No.1->No.KitaDomTree::m_templateNum) */
- m_domtree->appendTemplate();
- }
-
- /* show resposes from No.bottom to No.prevReadNum */
- if ( bottom < prevReadNum ) {
- for ( int i = bottom + 1 ; i <= prevReadNum ; i++ )
- m_domtree->appendRes( i, FALSE );
- }
-
- /* At this point,
-
- No.1 -> No.KitaDomTree::m_templateNum,
- No.(prevReadNum-m_preShowNum) -> No.prevReadNum,
-
- are shown. */
-
- /* show kokomade yonda */
- m_domtree->setKokoyonNum( prevReadNum );
-
- /* show new responses */
- if ( prevReadNum < maxres ) {
- for ( int i = prevReadNum + 1 ; i <= QMIN( prevReadNum + m_afterShowNum, maxres ); i++ )
- m_domtree->appendRes( i, FALSE );
- }
-
- /* At this point,
-
- No.1 -> No.KitaDomTree::m_templateNum,
- No.(prevReadNum-m_preShowNum) -> No.(prevReadNum+m_afterShowNum)
-
- are shown. */
-
- /* finish rendering */
- m_thread->setResNum( maxres );
- KitaThreadInfo::setReadNum( m_thread->datURL(), maxres );
- update_finish();
-
- m_threadPart->gotoKokoyon();
- m_domtree->parseAllRes();
-
- QApplication::restoreOverrideCursor();
-}
/*-------------------*/
-/* finish rendering */
-/*-------------------*/
-void KitaThreadView::update_finish()
+/* update screen */ /* public */
+void KitaThreadView::updateScreen()
{
int totalNum = m_domtree->getMaxResNumber();
/* set header, footer , etc. */
m_domtree->appendMae100();
m_domtree->appendTugi100();
+ m_domtree->setKokoyonNum( m_kokoyonNum );
m_domtree->appendKokoyon();
m_domtree->appendFooter( totalNum );
m_threadPart->view() ->layout();
m_threadPart->view() ->setVScrollBarMode( QScrollView::AlwaysOn );
+}
+
+
+/*--------------------*/
+/* update information */ /* public */
+void KitaThreadView::updateInfo(){
+
/* uptate informations */
- showStatusBar( "" );
- Kita::Thread::setName( m_thread->datURL(), m_domtree->getSubject() );
- emit thread( m_thread );
- setSubjectLabel( m_thread->boardName(), m_thread->name() + QString( " (%1)" ).arg( m_thread->resNum() ) );
+ setSubjectLabel(Kita::DatManager::thread_boardName(m_datURL),
+ Kita::DatManager::thread_name(m_datURL)
+ + QString( " (%1)" )
+ .arg( Kita::DatManager::getMaxResNumber(m_datURL) ) );
+ emit showThreadCompleted( Kita::DatManager::thread_url(m_datURL) );
m_domtree->findTextInit();
updateButton();
- emit showThreadCompleted( m_thread->url() );
+ emit thread( m_thread );
+ showStatusBar( "" );
m_threadPart->view() ->setFocus();
+ m_domtree->parseAllRes();
}
+
+
/*-------------------*/
/* append responses */
/*-------------------*/
void KitaThreadView::appendRes( int startnum, int endnum )
{
- showStatusBar( QTextCodec::codecForName( "utf8" ) ->toUnicode( KITAUTF8_NOWEXPAND ) );
-
- startnum = QMAX( 1, startnum );
- endnum = QMIN( m_domtree->getMaxResNumber(), endnum );
+ showStatusBar( Kita::ParseMisc::utf8ToUnicode( KITAUTF8_NOWEXPAND ) );
/* show clock cursor */
QCursor qc; qc.setShape( Qt::WaitCursor );
for ( int i = startnum ; i <= endnum; i++ ) m_domtree->appendRes( i, FALSE );
- update_finish();
+ updateScreen();
+ showStatusBar( "" );
QApplication::restoreOverrideCursor();
}
{
if ( m_viewmode == VIEWMODE_PREVIEW ) return ;
- if ( m_serverTime == 0 ) return ; /* Nothing is shown on the screen.*/
+ if ( m_datURL == QString::null ) return ; /* Nothing is shown on the screen.*/
/* jump */
QString str = SearchCombo->currentText();
~KitaThreadView();
const QString threadName() const;
const KURL threadURL() const;
- void killJob();
void focusSearchCombo();
void setupEx( const Kita::Thread* thread, int serverTime, int mode );
void setFont( const QFont& font );
void slotReloadButton();
void slotOpenURLRequest( const KURL&, const KParts::URLArgs& );
+ void slotReceiveData();
+ void slotFinishLoad();
+
protected slots:
void slotDOMNodeActivated( const DOM::Node& node );
void slotPopupMenu( KXMLGUIClient*, const QPoint&, const KURL&, const QString&, mode_t );
private: // Private attributes
- Kita::Access* m_access;
int m_serverTime;
Kita::Thread* m_thread;
+ QString m_datURL;
KitaHTMLPart* m_threadPart;
Kita::PostInfo m_postInfo;
Kita::ResPopup* m_popup;
bool m_revsearch;
int m_viewmode;
int m_rescode;
+ int m_kokoyonNum;
+ int m_showNum;
/* for config */
int m_preShowNum;
QString m_mailaddr;
int m_maxpopup;
bool m_online;
+ bool m_firstReceive;
- void update_readCache();
- void update_rendering( bool breload );
- void update_finish();
- void update_copydata( const QString& linedata, int basenum );
+ void updateScreen();
+ void updateInfo();
void appendRes( int startnum, int endnum );
void showPopup( QString innerHTML, QString imgfile );
#include "kitawritedialog.h"
#include "libkita/qcp932codec.h"
#include "libkita/thread.h"
-#include "kitaconfig.h"
+#include "libkita/kitaconfig.h"
#include "kita2ch.h"
#include "kitathreadview.h"
#include "kitadomtree.h"
#include "libkita/access.h"
-#include "datmanager.h"
+#include "libkita/datmanager.h"
#include <ksqueezedtextlabel.h>
#include <klocale.h>
#include <qspinbox.h>
#include <qbuttongroup.h>
+#include "libkita/kitaconfig.h"
#include "kitafontprefbase.h"
-#include "kitaconfig.h"
#include "debugprefbase.h"
#include "aboneprefpage.h"
#include <qheader.h>
#include "libkita/thread.h"
-#include "part/kitaconfig.h"
+#include "libkita/kitaconfig.h"
using namespace Kita;