OSDN Git Service

>>787
authorikemo <ikemo@56b19765-1e22-0410-a548-a0f45d66c51a>
Sat, 22 May 2004 04:33:13 +0000 (04:33 +0000)
committerikemo <ikemo@56b19765-1e22-0410-a548-a0f45d66c51a>
Sat, 22 May 2004 04:33:13 +0000 (04:33 +0000)
git-svn-id: svn+ssh://svn.sourceforge.jp/svnroot/kita/kita/trunk@1095 56b19765-1e22-0410-a548-a0f45d66c51a

32 files changed:
kita/src/aboneprefpage.cpp
kita/src/kita.cpp
kita/src/kita.h
kita/src/kitaboardview.cpp
kita/src/kitasubjectview.cpp
kita/src/libkita/.cvsignore
kita/src/libkita/Makefile.am
kita/src/libkita/access.cpp
kita/src/libkita/access.h
kita/src/libkita/datinfo.cpp [new file with mode: 0644]
kita/src/libkita/datinfo.h [new file with mode: 0644]
kita/src/libkita/datmanager.cpp [new file with mode: 0644]
kita/src/libkita/datmanager.h [new file with mode: 0644]
kita/src/libkita/kita-utf16.h [new file with mode: 0644]
kita/src/libkita/kita-utf8.h [moved from kita/src/part/kita-utf8.h with 100% similarity]
kita/src/libkita/kitaconfig.cpp [moved from kita/src/part/kitaconfig.cpp with 100% similarity]
kita/src/libkita/kitaconfig.h [moved from kita/src/part/kitaconfig.h with 100% similarity]
kita/src/libkita/parsemisc.cpp [new file with mode: 0644]
kita/src/libkita/parsemisc.h [new file with mode: 0644]
kita/src/main.cpp
kita/src/part/Makefile.am
kita/src/part/datmanager.cpp [deleted file]
kita/src/part/datmanager.h [deleted file]
kita/src/part/kitadomtree.cpp
kita/src/part/kitahtmlpart.cpp
kita/src/part/kitanavi.cpp
kita/src/part/kitathreadpart.cpp
kita/src/part/kitathreadview.cpp
kita/src/part/kitathreadview.h
kita/src/part/kitawritedialog.cpp
kita/src/pref.cpp
kita/src/threadlistview.cpp

index 2be39cd..e3f1257 100644 (file)
@@ -11,7 +11,7 @@
 
 #include <ktextedit.h>
 
-#include "kitaconfig.h"
+#include "libkita/kitaconfig.h"
 
 using namespace Kita;
 
index f738509..e01b982 100644 (file)
@@ -22,6 +22,7 @@
 #include "libkita/thread.h"
 #include "libkita/favoritethreads.h"
 #include "libkita/kita_misc.h"
+#include "libkita/kitaconfig.h"
 
 #include <qdragobject.h>
 #include <qtextcodec.h>
index 115beab..59bfc90 100644 (file)
 #include <kapplication.h>
 #include <kdockwidget.h>
 
-#include "kitaconfig.h"
-
-#include "libkita/thread.h"
-
 class KPrinter;
 class KToggleAction;
 class KURL;
@@ -35,6 +31,11 @@ namespace KParts
     class URLArgs;
 }
 
+namespace Kita
+{
+    class Thread;
+}
+
 /**
  * This class serves as the main window for Kita.  It handles the
  * menus, toolbars, and status bars.
index 2bc68b2..06cedb4 100644 (file)
 #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 )
index e67dba4..fa30f25 100644 (file)
@@ -37,9 +37,9 @@
 #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 )
index aa1187b..bff2b9d 100644 (file)
@@ -3,5 +3,6 @@ Makefile.in
 *.la
 *.lo
 *.moc
+*.moc.cpp
 .deps
 .libs
index ca5da04..1a3228f 100644 (file)
@@ -2,9 +2,9 @@ INCLUDES = $(all_includes)
 
 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
index c464741..84459d9 100644 (file)
@@ -10,7 +10,6 @@
 #include "access.h"
 
 #include "thread.h"
-#include "qcp932codec.h"
 #include "cache.h"
 #include "threadinfo.h"
 
@@ -100,7 +99,7 @@ QString Access::getupdate()
                 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& ) ),
@@ -114,11 +113,21 @@ QString Access::getupdate()
         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();
 
@@ -145,7 +154,7 @@ QString Access::getupdate()
     } else retstr = "";
 
     if ( responseCode() != 200 && responseCode() != 206 ) retstr = QString::null;
-    return retstr;
+    emit finishLoad();
 }
 
 // from netaccess.cpp
@@ -163,28 +172,25 @@ void Access::enter_loop()
 
 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: (...), (..) (...) (....) (..:..:..) .*" );
@@ -206,6 +212,7 @@ int Access::serverTime()
 
 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]+) .*" );
@@ -225,8 +232,7 @@ QString Access::getcache()
 
     m_orgData = getCacheData( url );
 
-    QCp932Codec codec;
-    return codec.toUnicode( m_orgData );
+    return m_orgData;
 
 }
 
index 13665ff..1fccaee 100644 (file)
@@ -37,6 +37,7 @@ namespace Kita
 
         QString get();
         void killJob();
+       void stopJob();
         int serverTime();
         QString getcache();
         QString getupdate();
@@ -60,6 +61,8 @@ namespace Kita
 
     signals:
         void redirection( const QString& );
+       void receiveData( const QString& );
+       void finishLoad();
     };
 
 }
diff --git a/kita/src/libkita/datinfo.cpp b/kita/src/libkita/datinfo.cpp
new file mode 100644 (file)
index 0000000..25e99a3
--- /dev/null
@@ -0,0 +1,1056 @@
+/**************************************************************************
+*   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 + "\">&gt;&gt;" + 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) + "\">&gt;&gt;" + (*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] == ';') /* "&gt;" */
+           ){
+           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;
+}
+
diff --git a/kita/src/libkita/datinfo.h b/kita/src/libkita/datinfo.h
new file mode 100644 (file)
index 0000000..eccc105
--- /dev/null
@@ -0,0 +1,223 @@
+/**************************************************************************
+ *   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
diff --git a/kita/src/libkita/datmanager.cpp b/kita/src/libkita/datmanager.cpp
new file mode 100644 (file)
index 0000000..1592d29
--- /dev/null
@@ -0,0 +1,561 @@
+/**************************************************************************
+*   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();
+}
+
+
+
+
diff --git a/kita/src/libkita/datmanager.h b/kita/src/libkita/datmanager.h
new file mode 100644 (file)
index 0000000..d6f8c6a
--- /dev/null
@@ -0,0 +1,96 @@
+/**************************************************************************
+*   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
diff --git a/kita/src/libkita/kita-utf16.h b/kita/src/libkita/kita-utf16.h
new file mode 100644 (file)
index 0000000..a08c301
--- /dev/null
@@ -0,0 +1,16 @@
+/**************************************************************************
+*   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 /* , */
diff --git a/kita/src/libkita/parsemisc.cpp b/kita/src/libkita/parsemisc.cpp
new file mode 100644 (file)
index 0000000..60e66c0
--- /dev/null
@@ -0,0 +1,263 @@
+/**************************************************************************
+*   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 = "&gt;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'  /* &gt; */
+                    && 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 &hearts; */
+/*-----------------------------------------------------*/ /* public */
+
+/* For example, if cdat = "&amp;", 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 , "&gt;" ) ) ) retstr = ">";
+    else if ( ( pos = LocalFunc::isEqual( cdat , "&lt;" ) ) ) retstr = "<";
+    else if ( ( pos = LocalFunc::isEqual( cdat , "&nbsp;" ) ) ) retstr = " ";
+    else if ( ( pos = LocalFunc::isEqual( cdat , "&amp;" ) ) ) retstr = "&";
+    else if ( ( pos = LocalFunc::isEqual( cdat , "&quot;" ) ) ) retstr = "\"";
+
+    else if ( ( pos = LocalFunc::isEqual( cdat , "&hearts;" ) ) )
+       retstr = utf8ToUnicode( KITAUTF8_HEART );
+
+    else if ( ( pos = LocalFunc::isEqual( cdat , "&diams;" ) ) )
+       retstr = utf8ToUnicode( KITAUTF8_DIA );
+
+    else if ( ( pos = LocalFunc::isEqual( cdat , "&clubs;" ) ) )
+       retstr = utf8ToUnicode( KITAUTF8_CLUB );
+
+    else if ( ( pos = LocalFunc::isEqual( cdat , "&spades;" ) ) )
+       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 );
+}
diff --git a/kita/src/libkita/parsemisc.h b/kita/src/libkita/parsemisc.h
new file mode 100644 (file)
index 0000000..e4ca2f1
--- /dev/null
@@ -0,0 +1,45 @@
+/**************************************************************************
+*   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
+
index 7e25251..b444cec 100644 (file)
@@ -18,6 +18,8 @@
 #include <kcmdlineargs.h>
 #include <klocale.h>
 
+#include "libkita/kitaconfig.h"
+
 static const char *description =
     I18N_NOOP("Kita - 2ch client for KDE");
 
index 87a8c90..6a032ec 100644 (file)
@@ -9,9 +9,9 @@ libkitapart_la_LDFLAGS = -L../libkita $(all_libraries) -module -avoid-version -n
 
 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
 
diff --git a/kita/src/part/datmanager.cpp b/kita/src/part/datmanager.cpp
deleted file mode 100644 (file)
index bc9ec03..0000000
+++ /dev/null
@@ -1,614 +0,0 @@
-/**************************************************************************
-*   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) + "\">&gt;&gt;" + (*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 = "&gt;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'  /* &gt; */
-                    && 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 + "\">&gt;&gt;" + tmp + "</a><br>";
-    retstr += datInfo->getTreeByRes(resNum,num,"");
-
-    return retstr;
-}
-
diff --git a/kita/src/part/datmanager.h b/kita/src/part/datmanager.h
deleted file mode 100644 (file)
index 24dd08d..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/**************************************************************************
-*   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
index e2003c5..45cb1a0 100644 (file)
 /* 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 /* > */
@@ -24,7 +24,7 @@
 #define KITADOM_COMMA 0xFF0C /* , */
 
 /* UTF-8 */
-#include "kita-utf8.h"
+#include "libkita/kita-utf8.h"
 
 
 enum{
@@ -1099,7 +1099,7 @@ bool KitaDomTree::createResAnchor(
     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;
index b224b5a..b292da3 100644 (file)
@@ -13,7 +13,7 @@
 #include "kitathreadview.h"
 #include "kitahtmlview.h"
 #include "kitadomtree.h"
-#include "kitaconfig.h"
+#include "libkita/kitaconfig.h"
 
 #include <kpopupmenu.h>
 #include <klocale.h>
index 26b954b..4206f1a 100644 (file)
 #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
 
index fb339e2..26c86f7 100644 (file)
@@ -71,7 +71,6 @@ bool KitaThreadPart::openURL( const KURL& _url )
 
 bool KitaThreadPart::closeURL()
 {
-    m_threadview->killJob();
     return true;
 }
 
index 1fc73d5..a67f161 100644 (file)
@@ -21,7 +21,6 @@
 #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
 
@@ -64,7 +63,6 @@ static const char* cookie_message =
 
 KitaThreadView::KitaThreadView( QWidget* parent, const char* name )
         : KitaThreadViewBase( parent, name )
-        , m_access( 0 )
         , m_popup( 0 )
 {
     m_thread = new Kita::NullThread();
@@ -123,6 +121,7 @@ KitaThreadView::KitaThreadView( QWidget* parent, const char* name )
     m_viewmode = VIEWMODE_PARENT;
     m_rescode = 200;
     m_serverTime = 0;
+    m_datURL = QString::null;
 }
 
 KitaThreadView::~KitaThreadView()
@@ -132,8 +131,9 @@ 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 ) {
@@ -331,15 +331,6 @@ void KitaThreadView::slotBookmarkButtonClicked( bool on )
     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()
 {
@@ -416,9 +407,14 @@ void KitaThreadView::setupEx( const Kita::Thread* thread, int serverTime, int mo
     /*---------------------------------------*/
     /* 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 );
@@ -447,7 +443,7 @@ void KitaThreadView::setupEx( const Kita::Thread* thread, int serverTime, int mo
 /* 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. */
@@ -458,14 +454,40 @@ void KitaThreadView::showThread( const Kita::Thread* thread )
     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();
 }
@@ -481,7 +503,17 @@ void KitaThreadView::slotReloadButton()
 
     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:
 
@@ -493,6 +525,48 @@ void KitaThreadView::slotReloadButton()
     }
 }
 
+/*-----------------------------------*/
+/* 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();
+}
 
 
 
@@ -574,10 +648,10 @@ void KitaThreadView::slotOpenURLRequest( const KURL& urlin, const KParts::URLArg
 
         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:
@@ -740,8 +814,7 @@ void KitaThreadView::slotOpenURLRequest( const KURL& urlin, const KParts::URLArg
 /*-----------------------------------------*/
 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;
@@ -750,28 +823,24 @@ void KitaThreadView::showStatusBar( QString info )
 
     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;
 
@@ -828,7 +897,6 @@ void KitaThreadView::gotoAnchor( QString anc )
 
     int top = m_domtree->getTopResNumber();
     int bottom = m_domtree->getBottomResNumber();
-    int maxres = m_domtree->getMaxResNumber();
     int res = anc.toInt();
 
     if ( res == 1 ) {
@@ -837,7 +905,6 @@ void KitaThreadView::gotoAnchor( QString anc )
 
         /* 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 ) ) {
@@ -863,156 +930,17 @@ void KitaThreadView::gotoAnchor( QString anc )
     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 );
 
@@ -1021,27 +949,36 @@ void KitaThreadView::update_finish()
     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 );
@@ -1049,7 +986,8 @@ void KitaThreadView::appendRes( int startnum, int endnum )
 
     for ( int i = startnum ; i <= endnum; i++ ) m_domtree->appendRes( i, FALSE );
 
-    update_finish();
+    updateScreen();
+    showStatusBar( "" );
     QApplication::restoreOverrideCursor();
 }
 
@@ -1195,7 +1133,7 @@ void KitaThreadView::slotSearchButton()
 {
     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();
index f9d3673..140cf8a 100644 (file)
@@ -62,7 +62,6 @@ public:
     ~KitaThreadView();
     const QString threadName() const;
     const KURL threadURL() const;
-    void killJob();
     void focusSearchCombo();
 
     void setupEx( const Kita::Thread* thread, int serverTime, int mode );
@@ -86,15 +85,18 @@ public slots:
     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;
@@ -103,6 +105,8 @@ private:        // Private attributes
     bool m_revsearch;
     int m_viewmode;
     int m_rescode;
+    int m_kokoyonNum;
+    int m_showNum;
 
     /* for config */
     int m_preShowNum;
@@ -110,11 +114,10 @@ private:        // Private attributes
     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 );
index f433e08..be7aef1 100644 (file)
 #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>
index 85d1e12..016144f 100644 (file)
@@ -26,8 +26,8 @@
 #include <qspinbox.h>
 #include <qbuttongroup.h>
 
+#include "libkita/kitaconfig.h"
 #include "kitafontprefbase.h"
-#include "kitaconfig.h"
 #include "debugprefbase.h"
 #include "aboneprefpage.h"
 
index 9292c10..d6a9520 100644 (file)
@@ -21,7 +21,7 @@
 #include <qheader.h>
 
 #include "libkita/thread.h"
-#include "part/kitaconfig.h"
+#include "libkita/kitaconfig.h"
 
 using namespace Kita;