1 /***************************************************************************
2 * Copyright (C) 2004, 2007 by Kita Developers *
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 ***************************************************************************/
11 /* This class manages the DOM elements */
17 #include <dom/dom_text.h>
19 #include "libkita/datmanager.h"
20 #include "libkita/datinfo.h"
21 #include "libkita/kita-utf8.h"
22 #include "libkita/kita_misc.h"
24 KitaDomTree::KitaDomTree( const DOM::HTMLDocument& hdoc, const KURL& datURL )
30 /* create the nodes of footer, header, etc. */
35 /* get pointer of DatInfo */
36 /* Note that m_datURL is already locked in the KitaHTMLPart. */
37 m_datInfo = Kita::DatManager::getDatInfoPointer( datURL );
40 KitaDomTree::~KitaDomTree() {}
43 * This function creates DOM elements of both title and body.
44 * To show the res, call appendRes()
46 bool KitaDomTree::createResElement( int num )
49 Q_ASSERT( m_datInfo != NULL );
51 if ( num < m_bufSize && m_resStatus[ num ] != KITA_HTML_NOTPARSED ) {
56 if ( num >= m_bufSize ) {
57 /* resize buffer size */
58 if ( m_bufSize == 0 ) m_bufSize = 100;
59 while ( num >= m_bufSize ) m_bufSize += 500;
61 m_titleElm.resize( m_bufSize );
62 m_bodyElm.resize( m_bufSize );
63 m_resStatus.resize( m_bufSize, FALSE );
64 m_coloredNum.resize( m_bufSize, FALSE );
68 QString titleHTML, bodyHTML;
69 m_resStatus[ num ] = m_datInfo->getHTML( num, TRUE, titleHTML, bodyHTML );
71 if ( m_resStatus[ num ] == KITA_HTML_NOTPARSED ) {
75 m_titleElm[ num ] = m_hdoc.createElement( "DIV" );
76 m_titleElm[ num ].setAttribute( "class", "res_title" );
77 m_titleElm[ num ].setAttribute( "id", QString().setNum( num ) );
78 m_titleElm[ num ].setInnerHTML( titleHTML );
80 m_bodyElm[ num ] = m_hdoc.createElement( "DIV" );
81 m_bodyElm[ num ].setAttribute( "class", "res_body" );
82 m_bodyElm[ num ].setAttribute( "id", QString().setNum( num ) );
83 m_bodyElm[ num ].setInnerHTML( bodyHTML );
91 bool KitaDomTree::appendRes( int num )
93 if ( !createResElement( num ) ) return FALSE;
95 m_hdoc.body().appendChild( m_titleElm[ num ] );
96 m_hdoc.body().appendChild( m_bodyElm[ num ] );
98 if ( num > m_bottomNum ) m_bottomNum = num;
106 void KitaDomTree::redraw( bool force )
108 Q_ASSERT( m_datInfo != NULL );
110 int readNum = m_datInfo->getReadNum();
112 /* don't forget to reset abone here... */
113 m_datInfo->resetAbone();
115 for ( int i = 1; i <= readNum; i++ ) {
116 QString titleHTML, bodyHTML;
118 int oldStatus = m_resStatus[ i ];
119 m_resStatus[ i ] = m_datInfo->getHTML( i , TRUE, titleHTML, bodyHTML );
121 if ( force || oldStatus != m_resStatus[ i ] ) {
122 m_titleElm[ i ].setInnerHTML( titleHTML );
123 m_bodyElm[ i ].setInnerHTML( bodyHTML );
130 * change color of number of the res which is responsed.
132 * See also KitaDomTree::changeColorOfNumber() ,
133 * DatInfo::copyOneLineToResDat(),
134 * and DatInfo::collectResponsedRes().
136 void KitaDomTree::changeColorOfAllResponsedNumber()
138 for ( int i = 1; i <= m_bottomNum; ++i ) {
139 if ( m_datInfo->isResponsed( i ) ) {
140 changeColorOfNumber( i );
145 const int KitaDomTree::getBottomResNumber() const
151 * append footer & header
153 void KitaDomTree::appendFooterAndHeader()
155 Q_ASSERT( m_datInfo != NULL );
157 int readNum = m_datInfo->getReadNum();
158 if ( !readNum ) return ;
160 updateHeader( m_header );
161 updateFooter( m_footer );
163 m_hdoc.body().insertBefore( m_header, m_hdoc.body().firstChild() );
164 m_hdoc.body().appendChild( m_footer );
168 * append kokomadeyonda
170 void KitaDomTree::appendKokoyon()
172 Q_ASSERT( m_datInfo != NULL );
174 int readNum = m_datInfo->getReadNum();
175 if ( !readNum ) return ;
177 int viewPos = m_datInfo->getViewPos();
178 if ( viewPos == 0 ) return ;
182 if ( i <= readNum ) m_hdoc.body().insertBefore( m_kokoyon, m_titleElm[ i ] );
183 else m_hdoc.body().appendChild( m_kokoyon );
191 * append "A" Node to rootnode
193 void KitaDomTree::appendAnchorNode( DOM::Element rootnode, const QString& href, const QString& linkstr )
195 DOM::Element element;
197 element = rootnode.appendChild( m_hdoc.createElement( "A" ) );
199 element.setAttribute( "href", href );
200 element.appendChild( m_hdoc.createTextNode( linkstr ) );
209 * before: #KokomadeYonda 1- 101- 201- #ToSaigo<br><br>
210 * after : #KokomadeYonda 1- 101- 201- 301- 401- #ToSaigo<br><br>
212 void KitaDomTree::updateHeader( DOM::Element& headerElement )
214 if ( ! m_datInfo ) return ;
216 DOM::Element backupElement1, backupElement2, backupElement3;
217 int readNum = m_datInfo->getReadNum();
219 /* remove <a href="#tosaigo"> and <BR> */
220 backupElement1 = headerElement.removeChild( headerElement.lastChild() ); /* BR */
221 backupElement2 = headerElement.removeChild( headerElement.lastChild() ); /* BR */
222 backupElement3 = headerElement.removeChild( headerElement.lastChild() ); /* "#tosaigo" */
224 DOM::Node node = headerElement.firstChild(); /* node is now "#kokomade_yonda" */
225 node = node.nextSibling(); /* " " */
226 node = node.nextSibling();
228 /* '1-', '101-' などのリンクを作成 */
229 for ( int num = 1; num < readNum ; num += 100 ) {
230 if ( node == NULL ) {
231 QString href = QString( "#%1" ).arg( num );
232 QString linkStr = QString( "%1-" ).arg( num );
234 appendAnchorNode( headerElement, href, linkStr );
235 node = headerElement.appendChild( m_hdoc.createTextNode( " " ) );
236 node = node.nextSibling();
238 // 既にリンクが作られている場合は飛ばす
239 node = node.nextSibling();
240 if ( node != NULL ) node = node.nextSibling();
244 /* restore <a href="#tosaigo"> and <BR> */
245 headerElement.appendChild( backupElement3 ); /* "#tosaigo" */
246 headerElement.appendChild( backupElement2 ); /* BR */
247 headerElement.appendChild( backupElement1 ); /* BR */
254 * before: #KokomadeYonda 1- 101- 201- #ToSaigo
255 * after : #KokomadeYonda 1- 101- 201- 301- 401- #ToSaigo
257 void KitaDomTree::updateFooter( DOM::Element& footerElement )
259 Q_ASSERT( m_datInfo != NULL );
261 DOM::Element backupElement;
262 int readNum = m_datInfo->getReadNum();
264 backupElement = footerElement.removeChild( footerElement.lastChild() ); /* "#tosaigo" */
266 DOM::Node node = footerElement.firstChild(); /* node is now "#kokomade_yonda" */
267 node = node.nextSibling(); /* " " */
268 node = node.nextSibling();
270 /* '1-', '101-' などのリンクを作成 */
271 for ( int num = 1; num < readNum ; num += 100 ) {
272 if ( node == NULL ) {
273 QString href = QString( "#%1" ).arg( num );
274 QString linkStr = QString( "%1-" ).arg( num );
276 appendAnchorNode( footerElement, href, linkStr );
277 node = footerElement.appendChild( m_hdoc.createTextNode( " " ) );
278 node = node.nextSibling();
280 // 既にリンクが作られている場合は飛ばす
281 node = node.nextSibling();
282 if ( node != NULL ) node = node.nextSibling();
286 footerElement.appendChild( backupElement ); /* "#tosaigo" */
292 void KitaDomTree::createHeader()
295 DOM::Element rootnode;
297 rootnode = m_hdoc.createElement( "DIV" );
299 rootnode.setAttribute( "kita_type", "header" );
300 rootnode.setAttribute( "id", "header" );
302 str = Kita::utf8ToUnicode( KITAUTF8_KOKOYON );
303 appendAnchorNode( rootnode, "#kokomade_yonda", str );
304 rootnode.appendChild( m_hdoc.createTextNode( " " ) );
306 str = Kita::utf8ToUnicode( KITAUTF8_SAIGO );
307 appendAnchorNode( rootnode, "#tosaigo", str );
309 rootnode.appendChild( m_hdoc.createElement( "BR" ) );
310 rootnode.appendChild( m_hdoc.createElement( "BR" ) );
320 void KitaDomTree::createFooter()
323 DOM::Element rootnode;
325 rootnode = m_hdoc.createElement( "DIV" );
327 rootnode.setAttribute( "kita_type", "footer" );
328 rootnode.setAttribute( "id", "footer" );
330 str = Kita::utf8ToUnicode( KITAUTF8_KOKOYON );
331 appendAnchorNode( rootnode, "#kokomade_yonda", str );
332 rootnode.appendChild( m_hdoc.createTextNode( " " ) );
334 str = Kita::utf8ToUnicode( KITAUTF8_SAIGO );
335 appendAnchorNode( rootnode, "#tosaigo", str );
342 * create kokomadeyonda node
344 void KitaDomTree::createKokoyon()
347 DOM::Element rootnode;
349 str = Kita::utf8ToUnicode( KITAUTF8_KOKOYON2 );
351 rootnode = m_hdoc.createElement( "DIV" );
353 rootnode.setAttribute( "class", "kokoyon" );
354 rootnode.setAttribute( "kita_type", "kokoyon" );
355 rootnode.setAttribute( "id", "kokomade_yonda" );
356 rootnode.appendChild( m_hdoc.createTextNode( str ) );
359 m_kokoyon = rootnode;
363 * change color of number
364 * specify color like this: "a.coloredLink:link{ color: red; }"
366 void KitaDomTree::changeColorOfNumber( int num )
368 if ( m_coloredNum[ num ] ) return ;
370 m_coloredNum[ num ] = TRUE;
372 DOM::Node node = m_titleElm[ num ];
373 node = node.firstChild();
375 static_cast<DOM::HTMLElement>( node ).setAttribute( "class", "coloredLink" );