1 /***************************************************************************
2 * Copyright (C) 2003 by Hideki Ikemoto *
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 #include "kitasubjectview.h"
13 // include files for Qt
14 #include <qtoolbutton.h>
15 #include <qtextbrowser.h>
16 #include <qtextcodec.h>
19 #include <qclipboard.h>
20 #include <qapplication.h>
21 #include <qdatetime.h>
23 #include <qmessagebox.h>
24 #include <qcombobox.h>
27 #include <kio/slaveconfig.h>
28 #include <kio/netaccess.h>
30 // include files for KDE
32 #include <kfilterdev.h>
33 #include <klistview.h>
34 #include <kiconloader.h>
36 #include <kpopupmenu.h>
40 #include "libkita/threadinfo.h"
41 #include "libkita/thread.h"
42 #include "libkita/kita_misc.h"
43 #include "libkita/kitaconfig.h"
44 #include "libkita/favoritethreads.h"
45 #include "libkita/datmanager.h"
46 #include "libkita/parsemisc.h"
47 #include "libkita/signalcollection.h"
48 #include "part/kita2ch.h"
50 #include "threadproperty.h"
52 KitaSubjectView::KitaSubjectView( QWidget* parent, const char* name )
53 : Kita::ThreadListView( parent, name )
54 , m_unreadNum( 0 ), m_readNum( 0 ), m_newNum( 0 )
56 connect( subjectList, SIGNAL( contextMenuRequested( QListViewItem*, const QPoint&, int ) ),
57 SLOT( slotContextMenuRequested( QListViewItem*, const QPoint&, int ) ) );
58 connect( subjectList, SIGNAL( returnPressed( QListViewItem* ) ),
59 SLOT( loadThread( QListViewItem* ) ) );
60 connect( ReloadButton, SIGNAL( clicked() ),
61 SLOT( reloadSubject() ) );
63 Kita::SignalCollection* signalCollection = Kita::SignalCollection::getInstance();
64 connect( signalCollection, SIGNAL( updateSubjectTab( const KURL& ) ),
65 SLOT( slotUpdateSubject( const KURL& ) ) );
66 connect( this, SIGNAL( closeThreadTab( const KURL& ) ),
67 signalCollection, SIGNAL( closeThreadTab( const KURL& ) ) );
68 connect( this, SIGNAL( loadBoardCompleted( const KURL& ) ),
69 signalCollection, SIGNAL( setMainURLLine( const KURL& ) ) );
72 KitaSubjectView::~KitaSubjectView()
75 void KitaSubjectView::reloadSubject()
77 if ( ! m_boardURL.isEmpty() ) {
78 loadBoard( m_boardURL );
84 void KitaSubjectView::slotCloseButton()
86 emit closeCurrentTab();
90 const KURL KitaSubjectView::boardURL()
95 const QString KitaSubjectView::boardName()
97 return Kita::Board::getName( m_boardURL );
100 void KitaSubjectView::loadThread( QListViewItem* item )
102 if ( ! item ) return ;
104 KURL datURL = item->text( Col_DatURL );
106 if ( KitaConfig::alwaysUseTab() ) {
107 emit openURLRequestExt( datURL.prettyURL(), KParts::URLArgs(), "kita_open_2chthread", 1 );
109 emit openURLRequestExt( datURL.prettyURL(), KParts::URLArgs(), "kita_open_2chthread", 0 );
114 ts_readed : ´ûÆɤÇ1000Ķ¤¨¤Æ¤¤¤ë¤â¤Î
115 ts_normal : ̤¼èÆÀ¤Ç1Æü°Ê¾å·Ð¤Ã¤Æ¤¤¤ë¤â¤Î
116 ts_new : ̤¼èÆÀ¤Ç1Æü°ÊÆâ¤Î¤â¤Î
117 ts_read : ´ûÆɤÇ1000°Ê²¼¤Î¤â¤Î
118 ts_hasunread: ̤Æɤ¢¤ê
129 void KitaSubjectView::loadBoard( const QString& boardURL )
132 topLevelWidget() ->raise();
133 QDateTime currentdat = QDateTime::currentDateTime();
135 // reset member variables.
136 // FIXME: FavoriteListView::update()¤Ë¥³¥Ô¡¼
143 m_boardURL = boardURL;
148 KitaThreadInfo* cache = KitaThreadInfo::getInstance();
149 QPtrList<Kita::Thread> threadList = Kita::Board::getThreadList( boardURL );
152 subjectList->clear();
154 for ( unsigned i = 0; i < threadList.count(); i++ ) {
155 Kita::Thread* thread = threadList.at( i );
156 QString datURL = thread->datURL();
159 since.setTime_t( Kita::datToSince( datURL ) );
160 QDateTime current = QDateTime::currentDateTime();
162 int readNum = KitaThreadInfo::readNum( datURL );
163 int resNum = KitaThreadInfo::resNum( datURL );
164 double speed = resNum / ( since.secsTo( current ) / ( 60.0 * 60.0 * 24.0 ) );
166 Kita::ThreadListViewItem* item = new Kita::ThreadListViewItem( subjectList );
167 item->setText( Col_ID, QString( "%1" ).arg( i + 1, 4 ) );
168 item->setText( Col_Subject, Kita::unescape( Kita::Thread::getName( datURL ) ) );
169 item->setText( Col_ResNum, QString( "%1" ).arg( resNum, 4 ) );
170 item->setText( Col_Read, ( readNum > 0 ) ? QString( "%1" ).arg( readNum, 4 ) : QString( "" ) );
171 item->setText( Col_Unread, ( readNum > 0 && resNum != readNum ) ? QString( "%1" ).arg( resNum - readNum, 4 ) : QString( "" ) );
172 item->setText( Col_Board, Kita::DatManager::boardName( datURL ) );
173 item->setText( Col_Since, since.toString( "yy/MM/dd hh:mm" ) );
174 item->setText( Col_DatURL, datURL );
175 item->setText( Col_Speed, QString( " %1 " ).arg( speed, 0, 'f', 2 ) );
177 // FIXME: updateThread¤Ë¥³¥Ô¡¼¤·¤Æ¤¤¤ë
178 // TODO: 'N'¤Î¥¢¥¤¥³¥ó¤òºîÀ®
179 if ( readNum > 0 && resNum != readNum ) {
181 item->setPixmap( Col_Mark, SmallIcon( "unread" ) );
183 item->setText( Col_MarkOrder, QString::number( ts_hasunread ) );
184 } else if ( readNum > 0 ) {
186 item->setPixmap( Col_Mark, SmallIcon( "read" ) );
188 //if( readNum > 1000) item->setText( Col_MarkOrder, "0" );
189 //else item->setText( Col_MarkOrder, "3" );
190 item->setText( Col_MarkOrder, QString::number( ( readNum > 1000 ) ? ts_readed : ts_read ) );
191 } else if ( since.secsTo( currentdat ) < 3600 * KitaConfig::MarkTime() ) {
192 item->setPixmap( Col_Mark, SmallIcon( "newthread" ) );
194 item->setText( Col_MarkOrder, QString::number( ts_new ) );
196 item->setText( Col_MarkOrder, QString::number( ts_normal ) );
200 if ( HideButton->isOn() ) {
201 HideButton->toggle();
203 emit loadBoardCompleted( boardURL );
205 switch ( KitaConfig::sortOrder() ) {
206 case KitaConfig::Order_Mark:
207 subjectList->setSorting( Col_Mark );
209 case KitaConfig::Order_ID:
210 subjectList->setSorting( Col_ID );
217 subjectList->setSelected( subjectList->firstChild(), TRUE );
218 subjectList->setFocus();
222 /* public slot */ /* virtual */
223 void KitaSubjectView::setFocus()
225 subjectList->setFocus();
229 void KitaSubjectView::slotFocusSearchCombo()
231 if ( ! SearchCombo->hasFocus() ) {
232 SearchCombo->setFocus();
238 void KitaSubjectView::UpdateKindLabel()
241 fmtstr += QString( "<font color=#C50000>%1</font>" ).arg( m_unreadNum );
242 fmtstr += QString( "/<font color=#00C200>%1</font>" ).arg( m_readNum );
243 fmtstr += QString( "/<font color=#5AAAFF>%1</font>" ).arg( m_newNum );
244 KindLabel->setText( fmtstr );
247 void KitaSubjectView::setFont( const QFont& font )
249 subjectList->setFont( font );
252 void KitaSubjectView::slotUpdateSubject( const KURL& url )
254 QDateTime currentdat = QDateTime::currentDateTime();
256 KURL datURL = Kita::ParseMisc::parseURLonly( url );
257 Kita::Thread* updated_thread = Kita::Thread::getByURLNew( datURL );
258 for ( QListViewItem * item = subjectList->firstChild(); item; item = item->nextSibling() ) {
259 if ( item->text( Col_DatURL ) == datURL.prettyURL() ) {
261 since.setTime_t( Kita::datToSince( datURL.prettyURL() ) );
263 int resNum = KitaThreadInfo::resNum( datURL.prettyURL() );
264 int readNum = KitaThreadInfo::readNum( datURL.prettyURL() );
265 item->setText( Col_ResNum, QString( "%1" ).arg( resNum, 4 ) );
266 item->setText( Col_Read, ( readNum > 0 ) ? QString( "%1" ).arg( readNum, 4 ) : QString( "" ) );
267 item->setText( Col_Unread, readNum > 0 && resNum != readNum ? QString( "%1" ).arg( resNum - readNum, 4 ) : QString( "" ) );
269 switch ( item->text( Col_MarkOrder ).toInt() ) {
271 case ts_read : m_readNum--; break;
272 case ts_new : m_newNum--; break;
273 case ts_hasunread : m_unreadNum--; break;
276 if ( readNum > 0 && resNum != readNum ) {
278 item->setPixmap( Col_Mark, SmallIcon( "unread" ) );
280 item->setText( Col_MarkOrder, QString::number( ts_hasunread ) );
281 } else if ( readNum > 0 ) {
283 item->setPixmap( Col_Mark, SmallIcon( "read" ) );
285 //if( readNum > 1000) item->setText( Col_MarkOrder, "0" );
286 //else item->setText( Col_MarkOrder, "3" );
287 item->setText( Col_MarkOrder, QString::number( ( readNum > 1000 ) ? ts_readed : ts_read ) );
288 } else if ( since.secsTo( currentdat ) < 3600 * KitaConfig::MarkTime() ) {
289 item->setPixmap( Col_Mark, SmallIcon( "newthread" ) );
291 item->setText( Col_MarkOrder, QString::number( ts_new ) );
293 item->setPixmap( Col_Mark, NULL );
294 item->setText( Col_MarkOrder, QString::number( ts_normal ) );
301 void KitaSubjectView::slotContextMenuRequested( QListViewItem* item, const QPoint& point, int )
304 Menu_OpenWithBrowser,
306 Menu_CopyTitleAndURL,
316 QString datURL = item->text( Col_DatURL );
317 Kita::Thread* thread = Kita::Thread::getByURL( datURL );
318 QString threadURL = Kita::DatManager::threadURL( datURL );
319 bool isFavorites = FavoriteThreads::getInstance() ->contains( datURL );
321 KPopupMenu popup( 0 );
322 popup.insertItem( i18n( "Open with Web Browser" ), Menu_OpenWithBrowser );
323 popup.insertItem( i18n( "Open with new tab" ), Menu_OpenWithNewTab );
324 popup.insertItem( i18n( "Copy title and URL" ), Menu_CopyTitleAndURL );
326 popup.insertItem( i18n( "Remove from Favorites" ), Menu_Favorites );
328 popup.insertItem( i18n( "Add to Favorites" ), Menu_Favorites );
330 popup.insertSeparator();
331 popup.insertItem( i18n( "Delete Log" ), Menu_DeleteLog );
332 popup.insertSeparator();
333 popup.insertItem( i18n( "Property" ), Menu_Property );
335 QClipboard* clipboard = QApplication::clipboard();
337 switch ( popup.exec( point ) ) {
338 case Menu_OpenWithBrowser:
339 KRun::runURL( threadURL, "text/html" );
341 case Menu_OpenWithNewTab:
342 emit openURLRequestExt( datURL, KParts::URLArgs(), "kita_open_2chthread", 1 );
344 case Menu_CopyTitleAndURL:
345 clipboard->setText( Kita::Thread::getName( datURL ) + "\n" + threadURL );
349 emit bookmarked( datURL, false );
351 emit bookmarked( datURL, true );
355 deleteLog( threadURL );
359 // FIXME: memory leak
360 Kita::ThreadProperty* propertyWidget = new Kita::ThreadProperty( 0 );
361 propertyWidget->threadURLLabel->setText( threadURL );
362 propertyWidget->datURLLabel->setText( datURL );
363 propertyWidget->threadNameLabel->setText( Kita::DatManager::threadName( datURL ) );
364 propertyWidget->cachePathLabel->setText( Kita::DatManager::getCachePath( datURL ) );
365 propertyWidget->indexPathLabel->setText( Kita::DatManager::getCacheIndexPath( datURL ) );
366 propertyWidget->show();
374 void KitaSubjectView::deleteLog( const KURL& url )
376 if ( QMessageBox::warning( this,
378 i18n( "Do you want to delete Log ?" ),
379 QMessageBox::Ok, QMessageBox::Cancel | QMessageBox::Default )
380 == QMessageBox::Ok ) {
381 Kita::DatManager::deleteCache( url );
382 emit closeThreadTab( url );
383 slotUpdateSubject( url );