1 /**************************************************************************
2 * Copyright (C) 2003 by Hideki Ikemoto , (c)2004 by 421 *
3 * ikemo@users.sourceforge.jp *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 ***************************************************************************/
12 #include <qstringlist.h>
14 #include <dom/html_document.h>
15 #include <dom/html_element.h>
16 #include <dom/html_table.h>
17 #include <dom/dom_text.h>
20 #include "datmanager.h"
21 #include "parsemisc.h"
24 #include "threadinfo.h"
25 #include "kitaconfig.h"
26 #include "kita-utf8.h"
27 #include "kita-utf16.h"
28 #include "kita_misc.h"
34 #define RESDAT_DEFAULTSIZE 10
35 #define RESDAT_DELTA 1000
38 /*------------------------------------------------------*/
39 /* DatInfo stores & handles all information about *.dat */
41 DatInfo::DatInfo( const KURL& url ) : m_access ( 0 ), m_access2( 0 )
44 m_datURL = Kita::ParseMisc::parseURL( url, refstr );
45 m_thread = Kita::Thread::getByURLNew( m_datURL );
47 /* japanese strings */
49 m_framestr1 = ParseMisc::utf8ToUnicode( KITAUTF8_FRAME1 ); /* | */
50 m_framestr2 = ParseMisc::utf8ToUnicode( KITAUTF8_FRAME2 ); /* |- */
51 m_framestr3 = ParseMisc::utf8ToUnicode( KITAUTF8_FRAME3 ); /* L */
63 /* Usually, don't call this. */ /* public */
66 QMutexLocker locker( &m_mutex );
72 void DatInfo::initPrivate()
75 /* stop & delete dat loader */
80 m_rawData = QString::null;
81 m_subject = QString::null;
85 m_lastLine = QString::null;
86 m_kokoyonNum = KitaThreadInfo::readNum( m_datURL.prettyURL() );
90 increaseResDatVec( RESDAT_DEFAULTSIZE );
95 /* create dat loader */
96 m_access = new Kita::Access( m_datURL );
98 connect( m_access, SIGNAL( receiveData( const QString& ) ),
99 SLOT( slotReceiveData( const QString& ) ) );
100 connect( m_access, SIGNAL( finishLoad() ), SLOT( slotFinishLoad() ) );
102 /* get dat from cahce & copy it to buffer */
103 copyRawDataToBuffer( m_access->getcache() );
104 copyRawDataToBuffer( QString::null ); /* copy the last line */
109 void DatInfo::resetResDat( RESDAT& resdat )
113 resdat.parsed = FALSE;
114 resdat.broken = FALSE;
115 resdat.setAnclist = FALSE;
116 resdat.anclist.clear();
117 resdat.checkAbone = FALSE;
118 resdat.abone = FALSE;
119 resdat.marked = FALSE;
124 void DatInfo::increaseResDatVec( int delta )
126 int size = m_resDatVec.size();
128 resetResDat( resdat );
129 m_resDatVec.resize( size + delta, resdat );
133 /* delete dat loader */ /* private */
134 void DatInfo::deleteAccessJob()
142 m_access2->killJob();
148 /* copy raw lines to buffer */
151 You need to call this function last
152 with rawData = QString::null in order
153 to copy the last line to buffer. */ /* private */
154 void DatInfo::copyRawDataToBuffer( const QString& rawData )
156 QStringList linelist;
157 int basenum = m_readNum + 1;
160 if ( Kita::boardType( m_datURL.url() ) == Board_MachiBBS && m_lastLine == QString::null && m_access->responseCode() == 200 ) {
165 bool endIsLF = FALSE;
166 if ( rawData != QString::null ) {
168 if ( rawData.at( rawData.length() - 1 ) == '\n' ) endIsLF = TRUE;
170 /* split the raw data */
171 m_lastLine += rawData;
172 linelist = QStringList::split( "\n", m_lastLine );
174 /* backup the last line */
175 QStringList::iterator lastit = linelist.end();
177 if ( lastit != linelist.end() ) {
178 m_lastLine = ( *lastit );
179 linelist.remove( lastit );
181 /* If the last char of rawData is LF, then
182 add LF to m_lastLine, because LF was
183 removed by above QStringList::split(). */
184 if ( endIsLF ) m_lastLine += '\n';
185 } else m_lastLine = QString::null;
187 } else { /* If rawData == null, then copy the last line */
189 if ( m_lastLine != QString::null
190 && m_lastLine.contains( "<>" ) == 4
191 && m_lastLine.at( m_lastLine.length() - 1 ) == '\n' ) {
193 m_lastLine.truncate( m_lastLine.length() - 1 ); /* remove LF */
194 linelist += m_lastLine;
195 m_lastLine = QString::null;
199 /* copy lines to buffer */
200 for ( QStringList::iterator it = linelist.begin();
201 it != linelist.end(); ++it, ++basenum ) {
202 if ( ( *it ) != QString::null ) {
203 QString line = ParseMisc::qcpToUnicode( ( *it ) );
204 copyOneLineToResDat( line, basenum );
211 void DatInfo::updateThreadInfo()
213 /* update thread info */
214 if ( !m_thread && m_readNum ) {
215 m_thread = Kita::Thread::getByURL( m_datURL.prettyURL() );
218 if ( m_thread->resNum() < m_readNum ) {
219 KitaThreadInfo::setResNum( m_datURL.prettyURL(), m_readNum );
221 KitaThreadInfo::setReadNum( m_datURL.prettyURL(), m_readNum );
227 /* copy one line to resdat. */
228 /* This private function is called in
229 copyRawDataToBuffer. */ /* private */
230 bool DatInfo::copyOneLineToResDat( const QString& line, int num )
233 if ( num <= 0 ) return FALSE;
234 if ( line == QString::null ) return FALSE;
236 /* If resdat vector is short, then resize the vector. */
237 while ( ( int ) m_resDatVec.size() <= num ) increaseResDatVec( RESDAT_DELTA );
239 /* reset and set new data */
240 RESDAT& resdat = m_resDatVec[ num ];
241 resetResDat( resdat );
244 resdat.linestr = line;
245 if ( m_readNum < num ) m_readNum = num;
246 m_rawData += line + '\n';
248 if ( num == 1 ) parseDat ( num ); /* to get subject */
250 /* is this dat file broken ? */
251 if ( line.contains( "<>" ) != 4 ) {
252 resdat.broken = TRUE;
262 const KURL& DatInfo::url()
264 QMutexLocker locker( &m_mutex );
271 /*--------------------------------------*/
272 /* cache handling functions */
276 /* When Kita::Access received new data,
277 slotReceiveData is called. */
279 /* When Kita::Access fineshed loading,
280 slotFinishLoad is called, and
281 DatInfo emits the finishLoad signal to the parent object */ /* public */
282 bool DatInfo::updateCache( const QObject* parent )
284 QMutexLocker locker( &m_mutex );
285 if ( m_access == NULL ) return FALSE;
286 if ( m_nowLoading ) return FALSE;
289 m_lock++; /* By locking, DatManager can't delete this while loading. */
291 connect( this, SIGNAL( receiveData() ),
292 parent, SLOT( slotReceiveData() ) );
294 connect( this, SIGNAL( finishLoad() ),
295 parent, SLOT( slotFinishLoad() ) );
297 m_access->getupdate();
303 /* slot called when Kita::Access
304 received new data */ /* private slot */
305 void DatInfo::slotReceiveData( const QString& newLine )
307 int rescode = m_access->responseCode();
309 rescode = m_access2->responseCode();
312 if ( rescode != 200 && rescode != 206 ) return ;
314 copyRawDataToBuffer( newLine );
320 /* slot called when Kita::Access
321 finished loading new dat */ /* private slot */
322 void DatInfo::slotFinishLoad()
325 /* copy the last line */
326 copyRawDataToBuffer( QString::null );
328 if ( m_readNum == 0 && m_access2 == NULL && Kita::is2ch( m_datURL ) ) {
329 if ( Account::isLogged() ) {
331 m_access2 = new OfflawAccess( m_datURL );
332 connect( m_access2, SIGNAL( receiveData( const QString& ) ),
333 SLOT( slotReceiveData( const QString& ) ) );
334 connect( m_access2, SIGNAL( finishLoad() ), SLOT( slotFinishLoad() ) );
339 /* finish loading session & emit signal to the parent object */
340 m_nowLoading = FALSE;
343 /* disconnect signals */
344 disconnect( SIGNAL( receiveData() ) );
345 disconnect( SIGNAL( finishLoad() ) );
347 if ( m_lock ) m_lock--;
352 int DatInfo::getResponseCode()
354 QMutexLocker locker( &m_mutex );
355 if ( m_access == NULL ) return 0;
357 return m_access->responseCode();
362 int DatInfo::getServerTime()
364 QMutexLocker locker( &m_mutex );
365 if ( m_access == NULL ) return 0;
367 return m_access->serverTime();
372 bool DatInfo::deleteCache()
374 QMutexLocker locker( &m_mutex );
375 if ( m_access == NULL ) return FALSE;
376 if ( m_nowLoading ) return FALSE;
379 if ( m_thread ) ret = Kita::Access::deleteLog( m_thread );
380 KitaThreadInfo::removeThreadInfo( m_datURL.prettyURL() );
381 if ( ret ) initPrivate();
388 bool DatInfo::isLoadingNow()
391 QMutexLocker locker( &m_mutex );
399 void DatInfo::stopLoading()
402 /* Don't lock the mutex here !!!
403 It will cause deadlock , because
404 Kita::Access::stopJob() calls KitaThreadView::slotFinishLoad() back,
405 then slotFinishLoad calls another functions in DatInfo. */
406 if ( m_access == NULL ) return ;
407 if ( ! m_nowLoading ) return ;
415 /*---------------------------------------------------*/
416 /* locking , unlocking functions */
418 /* If m_lock is not 0, DatManager can't delete this. */
419 /* Don't forget to call unlock() after locking this. */
421 /* They are public */
423 void DatInfo::lock ()
425 QMutexLocker locker( &m_mutex );
430 void DatInfo::unlock()
432 QMutexLocker locker( &m_mutex );
434 if ( m_lock ) m_lock--;
437 int DatInfo::isLocked()
439 QMutexLocker locker( &m_mutex );
445 /*------------------------------------------------------*/
446 /* get subject, linedata, id, body, name, HTML, etc. */
448 /* They are public */
450 const QString& DatInfo::getSubject()
452 QMutexLocker locker( &m_mutex );
457 const QString& DatInfo::getRawDat()
459 QMutexLocker locker( &m_mutex );
464 const QString& DatInfo::getDat( int num )
466 QMutexLocker locker( &m_mutex );
468 if ( num <= 0 || ( int ) m_resDatVec.size() <= num ) return QString::null;
469 if ( ! m_resDatVec[ num ].set ) return QString::null;
471 return m_resDatVec[ num ].linestr;
474 const QString& DatInfo::getId( int num )
476 QMutexLocker locker( &m_mutex );
477 if ( !parseDat( num ) ) return QString::null;
479 return m_resDatVec[ num ].id;
482 const QString& DatInfo::getBody( int num )
484 QMutexLocker locker( &m_mutex );
485 if ( !parseDat( num ) ) return QString::null;
487 return m_resDatVec[ num ].body;
490 const QString& DatInfo::getName( int num )
492 QMutexLocker locker( &m_mutex );
493 if ( !parseDat( num ) ) return QString::null;
495 return m_resDatVec[ num ].name;
498 /* plain (parsed) strings of name */
499 QString DatInfo::getPlainName( int num )
501 QMutexLocker locker( &m_mutex );
502 if ( !parseDat( num ) ) return QString::null;
504 return m_resDatVec[ num ].parsedName;
508 /* plain (parsed) strings of body */
509 QString DatInfo::getPlainBody( int num )
511 QMutexLocker locker( &m_mutex );
512 if ( !parseDat( num ) ) return QString::null;
515 QString line = m_resDatVec[ num ].body;
517 ParseMisc::parseBODYdatText( PARSEMODE_TEXT, line, bodytext );
523 /* plain (parsed) strings of title */
524 QString DatInfo::getPlainTitle( int num )
526 QMutexLocker locker( &m_mutex );
527 if ( !parseDat( num ) ) return QString::null;
529 bool showAddr = KitaConfig::showMailAddress();
531 ParseMisc::parseTITLEdatText( PARSEMODE_TEXT, num, showAddr, m_resDatVec[ num ], titletext );
537 /*-----------------------------------------*/
541 /* Note that this function checks Abone internally. */ /* public */
542 QString DatInfo::getHtml( int startnum, int endnum )
544 QMutexLocker locker( &m_mutex );
546 QString retstr = QString::null;
547 bool showAddr = KitaConfig::showMailAddress();
549 for ( int num = startnum; num <= endnum; num++ ) {
551 if ( !parseDat( num ) ) continue;
552 if ( checkAbonePrivate( num ) ) retstr += aboneHTML( num );
553 else if ( m_resDatVec[ num ].broken ) retstr += brokenHTML( num );
554 else retstr += ParseMisc::ResDatToHtml( m_resDatVec[ num ], num, showAddr );
561 /* return HTML strings that have ID = strid. */
562 /* Note that this function checks Abone internally. */ /* public */
563 QString DatInfo::getHtmlByID( const QString& strid, int &count )
565 QMutexLocker locker( &m_mutex );
567 QString retstr = QString::null;
568 bool showAddr = KitaConfig::showMailAddress();
572 for ( int i = 1; i <= m_readNum; i++ ) {
574 if ( !parseDat( i ) ) continue;
576 if ( m_resDatVec[ i ].id == strid ) {
578 if ( checkAbonePrivate( i ) ) retstr += aboneHTML( i );
579 else if ( m_resDatVec[ i ].broken ) retstr += brokenHTML( i );
580 else retstr += ParseMisc::ResDatToHtml( m_resDatVec[ i ], i, showAddr );
589 QString DatInfo::aboneHTML( int num )
592 QString tmpstr = QString( "<dl><dt>" );
593 tmpstr += QString().setNum( num ) + " " + ParseMisc::utf8ToUnicode( KITAUTF8_ABONE );
594 tmpstr += "</dt><dd>";
595 tmpstr += ParseMisc::utf8ToUnicode( KITAUTF8_ABONE );;
596 tmpstr += "<br/><br/></dd></dl>";
603 QString DatInfo::brokenHTML( int num )
606 QString tmpstr = QString( "<dl><dt>" );
607 tmpstr += QString().setNum( num ) + " " + ParseMisc::utf8ToUnicode( KITAUTF8_NAME );
608 tmpstr += "</dt><dd>";
609 tmpstr += ParseMisc::utf8ToUnicode( KITAUTF8_KOWARE );;
610 tmpstr += "<br/><br/></dd></dl>";
616 /*-------------------------------*/
617 /* Get HTML document of res tree.*/
618 /* For example, when rootnum = 1,
624 |-->>20, and return count = 3. */
626 /* Note that this function checks Abone internally. */ /* public */
627 QString DatInfo::getTreeByRes( const int rootnum, int& count )
629 QMutexLocker locker( &m_mutex );
630 return getTreeByResPrivate( rootnum, FALSE, count );
633 /*---------------------------------------*/
634 /* Get HTML document of reverse res tree.*/
635 /* For example, when rootnum = 10,
641 |-->>6, and returns count = 3. */
643 /* Note that this function checks Abone internally. */ /* public */
644 QString DatInfo::getTreeByResReverse( const int rootnum, int& count )
646 QMutexLocker locker( &m_mutex );
647 return getTreeByResPrivate( rootnum, TRUE, count );
652 QString DatInfo::getTreeByResPrivate(
654 bool reverse, /* reverse search */
658 QString tmp = QString().setNum( rootnum );
659 QString retstr = "<a href=\"#" + tmp + "\">>>" + tmp + "</a><br>";
661 retstr += getTreeByResCore( rootnum, reverse, count, "" );
667 QString DatInfo::getTreeByResCore(
669 bool reverse, /* reverse search */
670 int& count, QString prestr )
672 if ( !parseDat( rootnum ) ) return QString::null;
673 if ( checkAbonePrivate( rootnum ) ) return QString::null;
675 QString retstr = QString::null ;
677 QStringList strlists;
681 /* collect responses that have anchor to rootnum */
682 for ( int i = rootnum + 1; i <= m_readNum; i++ ) {
683 if ( checkAbonePrivate( i ) ) continue;
684 if ( checkRes( i, rootnum ) ) {
686 strlists += QString().setNum( i );
690 } else { /* collect responses for which rootnum has anchors */
692 setAncList( rootnum );
693 AncList& anclist = m_resDatVec[ rootnum ].anclist;
694 for ( AncList::iterator it = anclist.begin(); it != anclist.end(); ++it ) {
695 for ( int i = ( *it ).from; i <= QMIN( rootnum - 1, ( *it ).to ) ; i++ ) {
696 if ( checkAbonePrivate( i ) ) continue;
698 strlists += QString().setNum( i );
703 /* make HTML document */
706 for ( QStringList::iterator it = strlists.begin(); it != strlists.end(); ++it ) {
708 if ( ( *it ) == strlists.last() ) tmpstr = m_framestr3; /* 'L' */
709 else tmpstr = m_framestr2; /* '|-' */
711 retstr += prestr + tmpstr + "<a href=\"#" + ( *it ) + "\">>>" + ( *it ) + "</a><br>";
713 /* call myself recursively */
716 if ( ( *it ) == strlists.last() ) tmpstr += m_spacestr + m_spacestr + m_spacestr; /* " " */
717 else tmpstr += m_framestr1 + m_spacestr; /* "| " */
718 retstr += getTreeByResCore( ( *it ).toInt(), reverse, tmpnum, tmpstr );
728 /*----------------------------------------------*/
729 /* Check if No.num has anchors to No.target */
730 /* For exsample, if target = 4, and No.num have
731 an anchor >>4, or >>2-6, etc.,
732 then return TRUE. */ /* private */
733 bool DatInfo::checkRes( const int num, const int target )
735 if ( ! parseDat( num ) ) return FALSE;
738 AncList& anclist = m_resDatVec[ num ].anclist;
740 for ( AncList::iterator it = anclist.begin(); it != anclist.end(); ++it ) {
741 if ( target >= ( *it ).from && target <= ( *it ).to ) return TRUE;
749 /*--------------------------*/
750 /* set AncList */ /* private */
752 /* This function sets anchor list.
753 For example, a res has anchors >>2-3 and >>4, then
760 void DatInfo::setAncList( int num )
763 if ( ! parseDat( num ) ) return ;
764 if ( m_resDatVec[ num ].setAnclist ) return ;
766 m_resDatVec[ num ].setAnclist = TRUE;
773 AncList& anclist = m_resDatVec[ num ].anclist;
776 QString line = m_resDatVec[ num ].body;
778 /* remove HTML tags */
779 QRegExp rex( "<[^>]*>" );
782 const QChar *chpt = line.unicode();
784 unsigned int length = line.length();
787 for ( i = 0 ; i < length ; i++ ) {
789 if ( chpt[ i ].unicode() == UTF16_BRACKET || /* > */
790 ( chpt[ i ] == '&' && chpt[ i + 1 ] == 'g' && chpt[ i + 2 ] == 't' && chpt[ i + 3 ] == ';' ) /* ">" */
792 while ( ParseMisc::parseResAnchor( chpt + i, length - i, linkstr, refNum, pos ) ) {
793 if ( refNum[ 1 ] < refNum[ 0 ] ) refNum[ 1 ] = refNum[ 0 ];
794 anctmp.from = refNum[ 0 ];
795 anctmp.to = refNum[ 1 ];
805 line = m_resDatVec[ num ].name;
806 chpt = line.unicode();
808 length = line.length();
810 while ( ParseMisc::parseResAnchor( chpt + i, length - i, linkstr, refNum, pos ) ) {
811 if ( refNum[ 1 ] < refNum[ 0 ] ) refNum[ 1 ] = refNum[ 0 ];
812 anctmp.from = refNum[ 0 ];
813 anctmp.to = refNum[ 1 ];
821 /*----------------------------------*/
822 /* Get DOM element */
824 /* This function returns the element
827 This function checks Abone
828 internally. So, if the res is
829 aboned,the output is "abone" node.
831 If the res is broken, the output
835 bool DatInfo::getDomElement(
839 DOM::HTMLDocument& hdoc, /* root of HTML document */
842 DOM::Element& retelm )
845 QMutexLocker locker( &m_mutex );
846 if ( !parseDat( num ) ) return FALSE;
849 QString status = "normal";
850 DOM::Element bodynode, titlenode, tmpelm;
851 DOM::HTMLTableElement table;
852 bool showAddr = KitaConfig::showMailAddress();
853 bool showAA = KitaConfig::showAA();
854 bool abone = checkAbonePrivate( num );
856 RESDAT& resdat = m_resDatVec[ num ];
858 if ( !resdat.broken && !abone ) {
861 table = hdoc.createElement( "TABLE" );
863 tmpelm = table.insertRow( 0 );
864 ParseMisc::parseTITLEdat( PARSEMODE_DOM, hdoc, num, showAddr, resdat, tmpelm, tmpstr );
867 bodynode = hdoc.createElement( "DIV" );
869 /* put the span node at the head of each line */
872 tmpelm = bodynode.appendChild( hdoc.createElement( "SPAN" ) );
874 tmpelm.setAttribute( "style", "color: white" );
875 tmpelm.appendChild( hdoc.createTextNode( "" ) );
879 ParseMisc::parseBODYdat( PARSEMODE_DOM, resdat.body, hdoc, showAA, bodynode, tmpstr );
882 } else { /* abone or data is broken */
887 if ( abone ) { /* "abone" node */
888 namestr = ParseMisc::utf8ToUnicode( KITAUTF8_ABONE );
889 bodystr = ParseMisc::utf8ToUnicode( KITAUTF8_ABONE );
891 } else { /* "broken" node */
892 namestr = ParseMisc::utf8ToUnicode( KITAUTF8_NAME );
893 bodystr = ParseMisc::utf8ToUnicode( KITAUTF8_KOWARE );
898 table = hdoc.createElement( "TABLE" );
900 tmpelm = table.insertRow( 0 );
901 tmpelm = tmpelm.appendChild( hdoc.createElement( "TD" ) );
902 tmpelm.appendChild( hdoc.createTextNode(
903 QString().setNum( num ) + " " + namestr ) );
906 bodynode = hdoc.createElement( "DIV" );
907 tmpelm = bodynode.appendChild( hdoc.createElement( "SPAN" ) );
909 tmpelm.setAttribute( "style", "color: red" );
910 tmpelm.appendChild( hdoc.createTextNode( bodystr ) );
916 /*-----------------------------*/
918 retelm = hdoc.createElement( "DIV" );
919 retelm.setAttribute( "class", "res_block" );
921 retelm.setAttribute( "kita_type", "res" );
922 retelm.setAttribute( "kita_status", status );
923 retelm.setAttribute( "id", QString().setNum( num ) );
924 retelm.setAttribute( "kita_rname", resdat.name );
925 retelm.setAttribute( "kita_rid", resdat.id );
927 titlenode.setAttribute( "class", "res_title" );
928 bodynode.setAttribute( "class", "res_body" );
929 retelm.appendChild( titlenode );
930 retelm.appendChild( bodynode );
938 /*-----------------------*/
939 /* several information */
942 int DatInfo::getReadNum()
944 QMutexLocker locker( &m_mutex );
950 /* return number of responses that have ID = strid. */
951 /* Note that this function checks Abone internally. */ /* public */
952 int DatInfo::getNumByID( const QString& strid )
954 QMutexLocker locker( &m_mutex );
958 for ( int i = 1; i <= m_readNum; i++ ) {
960 if ( !parseDat( i ) ) continue;
961 if ( checkAbonePrivate( i ) ) continue;
963 if ( m_resDatVec[ i ].id == strid ) count++;
970 int DatInfo::getKokoyonNum()
972 QMutexLocker locker( &m_mutex );
974 return QMIN( m_kokoyonNum, m_readNum );
978 void DatInfo::setKokoyonNum( int num )
980 QMutexLocker locker( &m_mutex );
982 num = QMIN( num, m_readNum );
985 KitaThreadInfo::setReadNum( m_datURL.prettyURL(), num );
989 int DatInfo::getDatSize()
991 QMutexLocker locker( &m_mutex );
993 return m_rawData.length();
998 bool DatInfo::isResValid( int num )
1000 QMutexLocker locker( &m_mutex );
1002 return parseDat( num );
1006 bool DatInfo::isBroken()
1008 QMutexLocker locker( &m_mutex );
1014 bool DatInfo::isResBroken( int num )
1016 QMutexLocker locker( &m_mutex );
1017 if ( !parseDat( num ) ) return FALSE;
1019 return m_resDatVec[ num ].broken;
1022 /* ID = strid ? */ /* public */
1023 bool DatInfo::checkID( const QString& strid, int num )
1025 QMutexLocker locker( &m_mutex );
1026 if ( !parseDat( num ) ) return FALSE;
1028 if ( m_resDatVec[ num ].id == strid ) return TRUE;
1034 /* Are keywords included ? */ /* public */
1035 bool DatInfo::checkWord( QStringList& stlist, /* list of keywords */
1037 bool checkOR /* AND or OR search */
1040 QMutexLocker locker( &m_mutex );
1041 if ( !parseDat( num ) ) return FALSE;
1043 QString str_text = m_resDatVec[ num ].body;
1045 for ( QStringList::iterator it = stlist.begin(); it != stlist.end(); ++it ) {
1047 QRegExp regexp( ( *it ) );
1048 regexp.setCaseSensitive( FALSE );
1050 if ( checkOR ) { /* OR */
1051 if ( str_text.find( regexp, 0 ) != -1 ) {
1055 if ( str_text.find( regexp, 0 ) == -1 ) return FALSE;
1059 if ( checkOR ) return FALSE;
1065 bool DatInfo::isMarked( int num )
1067 QMutexLocker locker( &m_mutex );
1069 return m_resDatVec[ num ].marked;
1074 void DatInfo::setMark( int num, bool mark )
1076 QMutexLocker locker( &m_mutex );
1078 m_resDatVec[ num ].marked = mark;
1084 /*--------------------------------*/
1085 /* abone functions */
1088 /*-----------------------*/
1091 /* call this when config
1092 of abone changed. */ /* public */
1094 void DatInfo::resetAbone()
1096 QMutexLocker locker( &m_mutex );
1098 return resetAbonePrivate();
1102 void DatInfo::resetAbonePrivate()
1104 for ( int i = 1; i < ( int ) m_resDatVec.size(); i++ ) m_resDatVec[ i ].checkAbone = FALSE;
1106 m_aboneByID = ( !KitaConfig::aboneIDList().empty() );
1107 m_aboneByName = ( !KitaConfig::aboneNameList().empty() );
1108 m_aboneByBody = ( !KitaConfig::aboneWordList().empty() );
1109 m_aboneByRes = m_aboneByID | m_aboneByName | m_aboneByBody;
1114 /* check abone */ /* public */
1116 bool DatInfo::checkAbone( int num )
1118 QMutexLocker locker( &m_mutex );
1120 return checkAbonePrivate( num );
1125 bool DatInfo::checkAbonePrivate( int num )
1127 if ( !parseDat( num ) ) return FALSE;
1129 if ( m_resDatVec[ num ].checkAbone ) return m_resDatVec[ num ].abone;
1131 m_resDatVec[ num ].checkAbone = TRUE;
1132 bool checktmp = FALSE;
1135 checktmp = checkAboneCore( m_resDatVec[ num ].id, KitaConfig::aboneIDList() );
1137 if ( !checktmp && m_aboneByName )
1138 checktmp = checkAboneCore( m_resDatVec[ num ].parsedName, KitaConfig::aboneNameList() );
1140 if ( !checktmp && m_aboneByBody )
1141 checktmp = checkAboneCore( m_resDatVec[ num ].body, KitaConfig::aboneWordList() );
1143 if ( !checktmp && m_aboneByRes ) {
1145 AncList& anclist = m_resDatVec[ num ].anclist;
1147 for ( AncList::iterator it = anclist.begin();
1148 it != anclist.end() && !checktmp ; ++it ) {
1150 int refNum = ( *it ).from;
1151 int refNum2 = ( *it ).to;
1153 /* I don't want to enter loop... */
1154 if ( refNum >= num ) continue;
1155 if ( refNum2 >= num ) refNum2 = num - 1;
1157 for ( int i = refNum; i <= refNum2; i++ ) {
1158 if ( checkAbonePrivate( i ) ) {
1166 m_resDatVec[ num ].abone = checktmp;
1168 return m_resDatVec[ num ].abone;
1172 bool DatInfo::checkAboneCore( const QString& str, QStringList& strlist )
1174 if ( strlist.count() ) {
1177 for ( QStringList::iterator it = strlist.begin();
1178 it != strlist.end(); ++it ) {
1179 i = str.find( ( *it ) );
1191 /*---------------------------------------*/
1192 /* simple parsing function */
1194 /* This function parses struct RESDAT by
1195 ParseMisc::parseResDat. In short, this
1196 splits the raw date into name, id,
1197 date, and bodytext, etc.
1199 Note that this function keeps data as
1200 the raw data. So, you need to parse them
1201 later by getPlainBody, getHtml,
1204 bool DatInfo::parseDat( int num )
1207 if ( num <= 0 || ( int ) m_resDatVec.size() <= num ) return FALSE;
1208 if ( m_resDatVec[ num ].parsed ) return TRUE;
1211 if ( !ParseMisc::parseResDat( m_resDatVec[ num ], tmpstr ) ) return FALSE;
1214 if ( m_subject == QString::null && tmpstr != QString::null ) {
1216 Kita::Thread::setName( m_datURL.prettyURL(), m_subject );