OSDN Git Service

refactoring.
[kita/kita.git] / kita / src / threadlistview.cpp
1 /***************************************************************************
2 *   Copyright (C) 2003 by Hideki Ikemoto                                  *
3 *   ikemo@wakaba.jp                                                       *
4 *                                                                         *
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 ***************************************************************************/
10
11 #include "threadlistview.h"
12
13 #include <kiconloader.h>
14 #include <klistview.h>
15 #include <klocale.h>
16 #include <kurl.h>
17
18 #include <qtoolbutton.h>
19 #include <qcombobox.h>
20 #include <qregexp.h>
21 #include <qheader.h>
22
23 #include "libkita/thread.h"
24 #include "libkita/kitaconfig.h"
25 #include "libkita/signalcollection.h"
26
27 using namespace Kita;
28
29 struct Col_Attr ThreadListView::s_colAttr[] = {
30     // labelName, itemName, keyName
31     {"", "Mark", "Col_Mark"},
32     {"No.", "ID", "Col_ID"},
33     {"", "Icon", "Col_Icon"},
34     {"Title", "Subject", "Col_Subject"},
35     {"ResNum", "ResNum", "Col_ResNum"},
36     {"ReadNum", "Read", "Col_Read"},
37     {"ViewPos", "ViewPos", "Col_ViewPos"},
38     {"Unread", "Unread", "Col_Unread"},
39     {"Since", "Since", "Col_Since"},
40     {"Thread's speed", "Speed", "Col_Speed"},
41     {"Board", "Board", "Col_Board"},
42     {"Dat URL", "DatURL", "Col_DatURL"},
43     {"Mark Order", "MarkOrder", "Col_MarkOrder"},
44     {"ID Order", "IDOrder", "Col_IDOrder"}
45 };
46
47 ThreadListView::ThreadListView( QWidget* parent, const char* name )
48         : ThreadListViewBase( parent, name )
49 {
50     SearchButton->setPixmap( SmallIcon( "find" ) );
51     HideButton->setPixmap( SmallIcon( "filter" ) );
52     ReloadButton->setPixmap( SmallIcon( "reload" ) );
53     closeButton->setPixmap( SmallIcon( "fileclose" ) );
54
55     // need to sync order with ThreadListViewRows.
56     subjectList->addColumn( "" ); // Col_Mark
57     subjectList->addColumn( i18n( "No." ) );
58     subjectList->addColumn( "" ); // Col_Icon
59     subjectList->addColumn( i18n( "Title" ) );
60     subjectList->addColumn( i18n( "ResNum" ) );
61     subjectList->addColumn( i18n( "ReadNum" ) );
62     subjectList->addColumn( i18n( "ViewPos" ) );
63     subjectList->addColumn( i18n( "Unread" ) );
64     subjectList->addColumn( i18n( "Since" ) );
65     subjectList->addColumn( i18n( "Thread's speed" ) );
66     subjectList->addColumn( i18n( "Board" ) );
67     subjectList->addColumn( i18n( "Dat URL" ) );
68     subjectList->addColumn( i18n( "Mark Order" ) );
69     subjectList->addColumn( i18n( "ID Order" ) );
70
71     subjectList->setColumnWidth( Col_DatURL, 0 );
72     subjectList->setColumnWidth( Col_MarkOrder, 0 );
73     subjectList->setColumnWidth( Col_IDOrder, 0 );
74
75     QHeader *h = subjectList->header();
76     h->setResizeEnabled( FALSE, Col_DatURL );
77     h->setResizeEnabled( FALSE, Col_MarkOrder );
78     h->setResizeEnabled( FALSE, Col_IDOrder );
79
80     h->setResizeEnabled( FALSE, Col_Mark );
81     h->setResizeEnabled( FALSE, Col_Icon );
82     h->setStretchEnabled( TRUE, Col_Subject );
83
84     //subjectList->setColumnWidth( Col_Subject, 400 );
85     subjectList->setColumnWidthMode( Col_Subject, QListView::Manual );
86     subjectList->setColumnWidthMode( Col_DatURL, QListView::Manual );
87     subjectList->setColumnWidthMode( Col_MarkOrder, QListView::Manual );
88     subjectList->setColumnWidthMode( Col_IDOrder, QListView::Manual );
89
90     connect( SearchButton, SIGNAL( clicked() ),
91              SLOT( slotSearchButton() ) );
92     connect( SearchCombo, SIGNAL( activated( int ) ),
93              SLOT( slotSearchButton() ) );
94     connect( HideButton, SIGNAL( toggled( bool ) ),
95              SLOT( slotHideButton( bool ) ) );
96     connect( subjectList, SIGNAL( mouseButtonClicked( int, QListViewItem*, const QPoint&, int ) ),
97              SLOT( slotMouseButtonClicked( int, QListViewItem* ) ) );
98     connect( this, SIGNAL( bookmarked( const QString&, bool ) ),
99              Kita::SignalCollection::getInstance(), SIGNAL( bookmarked( const QString&, bool ) ) );
100     connect( this, SIGNAL( openURLRequestExt(
101                                const KURL&, const KParts::URLArgs&, QString, int, int,
102                                const KURL&, const KURL&, const QString&, const QString& ) ),
103              Kita::SignalCollection::getInstance(), SIGNAL( openURLRequestExt(
104                          const KURL& , const KParts::URLArgs&, QString, int, int,
105                          const KURL&, const KURL&, const QString&, const QString& ) ) );
106 }
107
108 ThreadListView::~ThreadListView()
109 {}
110
111 void ThreadListView::slotSearchButton()
112 {
113     insertSearchCombo();
114     QStringList list = parseSearchQuery( SearchCombo->currentText() );
115     searchNext( list );
116 }
117
118 void ThreadListView::insertSearchCombo()
119 {
120     for ( int count = 0; count < SearchCombo->count(); ++count ) {
121         if ( SearchCombo->text( count ) == SearchCombo->currentText() ) {
122             return ;
123         }
124     }
125     SearchCombo->insertItem( SearchCombo->currentText() );
126 }
127
128 QStringList ThreadListView::parseSearchQuery( const QString &input )
129 {
130     QStringList tmp = QStringList::split( ' ', input );
131     QStringList ret_list;
132     QRegExp truncSpace( "\\s*$" );
133     QStringList::iterator it = tmp.begin();
134
135     for ( ; it != tmp.end(); ++it ) {
136         ret_list += ( *it ).replace( truncSpace, "" );
137     }
138     return ret_list;
139 }
140
141 void ThreadListView::searchNext( const QStringList &query )
142 {
143     if ( query.isEmpty() ) return ;
144
145     if ( query != m_prevquery ) {
146         searchAll( query );
147         slotHideButton( HideButton->isOn() );
148         m_nextHitIndex = 0; //A next jump-search target reset to '0'.
149         return ;
150     }
151
152     if ( m_nextHitIndex >= m_hitList.size() ) {
153         return ;
154     }
155
156     KListViewItem* item = m_hitList[ m_nextHitIndex ];
157     subjectList->ensureItemVisible( item );
158     subjectList->setSelected( item, true );
159     m_nextHitIndex++;
160     if ( m_nextHitIndex >= m_hitList.size() ) m_nextHitIndex = 0;
161 }
162
163 void ThreadListView::searchAll( const QStringList &query )
164 {
165     m_hitList.clear();
166     m_prevquery = query;
167
168     QListViewItemIterator listIt( subjectList );
169     while ( listIt.current() != 0 ) {
170         KListViewItem * item = static_cast<KListViewItem*>( listIt.current() );
171         item->setPixmap( Col_Icon, 0 );
172
173         QStringList::const_iterator queryIt = query.begin();
174         for ( ; queryIt != query.end(); ++queryIt ) {
175             if ( item->text( Col_Subject ).contains( *queryIt, false ) ) {
176                 item->setPixmap( Col_Icon, SmallIcon( "find" ) );
177                 m_hitList.append( item );
178                 break;
179             }
180         }
181         ++listIt;
182     }
183 }
184
185 void ThreadListView::slotHideButton( bool on )
186 {
187     if ( m_hitList.empty() ) return ;
188
189     QListViewItemIterator listIt( subjectList );
190     while ( listIt.current() != 0 ) {
191         KListViewItem * item = static_cast<KListViewItem *>( listIt.current() );
192         if ( on && ! item->pixmap( Col_Icon ) ) {
193             item->setVisible( false );
194         } else {
195             item->setVisible( true );
196         }
197         ++listIt;
198     }
199 }
200
201 void ThreadListView::slotMouseButtonClicked( int button, QListViewItem* item )
202 {
203     if ( ! item ) return ;
204
205     KURL datURL = item->text( Col_DatURL );
206
207     switch ( button ) {
208     case MidButton:
209         emit openURLRequestExt( datURL.prettyURL(), KParts::URLArgs(), "kita_open_2chthread", 1 );
210         break;
211     case LeftButton:
212         if ( KitaConfig::alwaysUseTab() ) {
213             emit openURLRequestExt( datURL.prettyURL(), KParts::URLArgs(), "kita_open_2chthread", 1 );
214         } else {
215             emit openURLRequestExt( datURL.prettyURL(), KParts::URLArgs(), "kita_open_2chthread", 0 );
216         }
217         break;
218     }
219 }
220
221 int ThreadListViewItem::compare( QListViewItem* i, int col, bool ascending ) const
222 {
223     switch ( col ) {
224     case Col_ResNum:
225     case Col_Read:
226     case Col_Unread:
227         return i->key( col, ascending ).toInt() - key( col, ascending ).toInt();
228     case Col_ID:
229         return key( Col_IDOrder, ascending ).toInt() - i->key( Col_IDOrder, ascending ).toInt();
230     case Col_Mark:
231         return QString::localeAwareCompare( i->key( Col_MarkOrder, ascending ), key( Col_MarkOrder, ascending ) );
232     case Col_Since:
233         return QString::localeAwareCompare( i->key( col, ascending ), key( col, ascending ) );
234     case Col_Speed:
235         return static_cast<int>( i->key( col, ascending ).toDouble() * 1000 - key( col, ascending ).toDouble() * 1000 );
236     default:
237         return QString::localeAwareCompare( key( col, ascending ), i->key( col, ascending ) );
238     }
239 }
240
241 #include "threadlistview.moc"