2
This file is part of Choqok, the KDE micro-blogging client
4
Copyright (C) 2008-2009 Mehrdad Momeny <mehrdad.momeny@gmail.com>
6
This program is free software; you can redistribute it and/or
7
modify it under the terms of the GNU General Public License as
8
published by the Free Software Foundation; either version 2 of
9
the License or (at your option) version 3 or any later version
10
accepted by the membership of KDE e.V. (or its successor approved
11
by the membership of KDE e.V.), which shall act as a proxy
12
defined in Section 14 of version 3 of the license.
15
This program is distributed in the hope that it will be useful,
16
but WITHOUT ANY WARRANTY; without even the implied warranty of
17
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
GNU General Public License for more details.
20
You should have received a copy of the GNU General Public License
21
along with this program; if not, see http://www.gnu.org/licenses/
25
#include "searchwindow.h"
26
#include "statuswidget.h"
32
#include <KDE/KLocale>
33
#include <KMessageBox>
35
#include "twittersearch.h"
36
#include "identicasearch.h"
38
SearchWindow::SearchWindow( const Account &account, QWidget* parent ) :
44
intValidator = new QIntValidator( 1, 1500 / Settings::countOfStatusesOnMain(), this );
46
setAttribute( Qt::WA_DeleteOnClose );
48
switch( mAccount.serviceType() )
50
case Account::Twitter:
51
mSearch = new TwitterSearch( &mAccount, QString(), this );
53
case Account::Identica:
54
case Account::Laconica:
55
mSearch = new IdenticaSearch( &mAccount, mAccount.homepage(), this );
63
resize( Settings::searchWindowSize() );
64
move( Settings::searchWindowPosition() );
66
setWindowTitle( i18nc( "Search in service", "%1 Search",
70
void SearchWindow::init(int type, const QString & query)
76
connect( mSearch, SIGNAL( searchResultsReceived( QList< Status>& ) ),
77
this, SLOT( searchResultsReceived ( QList< Status >& ) ) );
78
connect( mSearch, SIGNAL( error( QString ) ), this, SLOT( error( QString ) ) );
79
connect( ui.txtSearch, SIGNAL( returnPressed() ), this, SLOT( search() ) );
80
connect( ui.txtPage, SIGNAL( returnPressed() ), this, SLOT( pageChange() ) );
85
ui.btnRefresh->setIcon( KIcon( "view-refresh" ) );
86
ui.btnBack->setIcon( KIcon( "go-previous" ) );
87
ui.btnForward->setIcon( KIcon( "go-next" ) );
89
ui.btnRefresh->setEnabled( false );
90
ui.btnBack->setEnabled( false );
91
ui.btnForward->setEnabled( false );
93
ui.txtPage->setValidator( intValidator );
95
connect( ui.btnRefresh, SIGNAL( clicked( bool ) ), this, SLOT( refresh() ) );
96
connect( ui.btnBack, SIGNAL( clicked( bool ) ), this, SLOT( goBack() ) );
97
connect( ui.btnForward, SIGNAL( clicked( bool ) ), this, SLOT( goForward() ) );
98
connect( ui.comboSearchType, SIGNAL(currentIndexChanged(int)), SLOT(slotSearchTypeChanged(int)));
99
showNavigation( false );
100
resetSearchArea(type,query);
101
ui.txtSearch->setFocus(Qt::OtherFocusReason);
106
kDebug() << "Service has no search implementation";
107
KMessageBox::error( this, i18n( "This service has no search feature." ) );
112
SearchWindow::~SearchWindow()
115
Settings::setSearchWindowPosition(pos());
116
Settings::setSearchWindowSize(size());
119
mSearch->deleteLater();
120
intValidator->deleteLater();
123
void SearchWindow::error( QString message )
125
ui.lblStatus->setText( i18n( "Failed: %1", message ) );
126
lastSearchQuery.clear();
127
ui.txtSearch->setEnabled( true );
130
void SearchWindow::searchResultsReceived(QList<Status> &statusList )
134
int count = statusList.count();
136
kDebug() << "Status list is empty";
137
ui.lblStatus->setText( i18n( "No search results on page %1.", QString::number( page ) ) );
138
ui.btnForward->setEnabled( false );
140
page = lastValidPage;
141
ui.btnRefresh->setEnabled( false );
144
// Sets up the navigation for the current page
145
if( mSearch->getSearchTypes()[lastSearchType].second ) {
146
showNavigation( true );
149
ui.chkAutoUpdate->setEnabled( true );
150
ui.btnBack->setEnabled( false );
151
ui.btnForward->setEnabled( true );
154
if ( (int)page == intValidator->top() )
155
ui.btnForward->setEnabled( false );
157
ui.btnForward->setEnabled( true );
158
ui.chkAutoUpdate->setEnabled( false );
159
clearSearchResults();
160
ui.btnBack->setEnabled( true );
163
showNavigation( false );
166
ui.lblStatus->setText( i18n( "Search results for page %1.", QString::number( page ) ) );
167
addNewStatusesToUi( statusList );
168
ui.searchScroll->verticalScrollBar()->setSliderPosition( 0 );
169
lastValidPage = page;
170
ui.btnRefresh->setEnabled( true );
173
ui.txtPage->setText( QString::number( lastValidPage ) );
174
ui.txtSearch->setEnabled( true );
177
void SearchWindow::search()
183
if ( ui.txtSearch->text().size() > 140 )
185
ui.lblStatus->setText( i18n( "Search text size is more than 140 characters." ) );
189
clearSearchResults();
191
ui.txtSearch->setEnabled( false );
192
ui.lblStatus->setText( i18n( "Searching..." ) );
193
ui.chkAutoUpdate->setCheckState( Qt::Unchecked );
194
mSearch->requestSearchResults( ui.txtSearch->text(),
195
ui.comboSearchType->currentIndex(),
197
Settings::countOfStatusesOnMain() );
199
lastSearchQuery = ui.txtSearch->text();
200
lastSearchType = ui.comboSearchType->currentIndex();
202
setWindowTitle( i18nc( "Search in service", "%1 Search (%2)",
203
mAccount.serviceName(), lastSearchQuery ) );
206
void SearchWindow::updateSearchResults()
209
if( isVisible() && !lastSearchQuery.isNull() && page == 1 )
211
qulonglong sinceStatusId = 0;
212
if( listResults.count() )
213
sinceStatusId = listResults.last()->currentStatus().statusId;
215
ui.lblStatus->setText( i18n( "Searching..." ) );
216
mSearch->requestSearchResults( lastSearchQuery,
219
Settings::countOfStatusesOnMain(),
224
void SearchWindow::autoUpdateSearchResults()
227
if( ui.chkAutoUpdate->isChecked() )
228
updateSearchResults();
231
void SearchWindow::addNewStatusesToUi( QList<Status> &statusList )
235
// This will make all statuses prior to the update marked as read
236
// and deleted if there are more than Settings::countOfStatusesOnMain.
237
// The reasoning for this is that there's a distinct possibility of
238
// a searching racking up thousands of unread messages depending on
239
// the query which would go undeleted as unread messages. The other
240
// option to avoid this would be to enforce a strict message limit
241
// regardless of whether or not they were marked as read.
242
markStatusesAsRead();
244
QList<Status>::const_iterator it = statusList.constBegin();
245
QList<Status>::const_iterator endIt = statusList.constEnd();
247
for( ; it != endIt; ++it ) {
248
StatusWidget *wt = new StatusWidget( &mAccount, this );
250
connect( wt, SIGNAL( sigReply( const QString&, qulonglong, bool ) ),
251
this, SIGNAL( forwardReply( const QString&, qulonglong, bool ) ) );
252
connect( wt, SIGNAL(sigReTweet(const QString&)), SIGNAL(forwardReTweet(const QString&)));
253
connect( wt, SIGNAL( sigFavorite( qulonglong, bool ) ),
254
this, SIGNAL( forwardFavorited( qulonglong, bool ) ) );
255
connect (wt,SIGNAL(sigSearch(int,QString)),this,SLOT(updateSearchArea(int,QString)));
257
wt->setAttribute( Qt::WA_DeleteOnClose );
258
wt->setCurrentStatus( *it );
259
wt->setUnread( StatusWidget::WithoutNotify );
261
listResults.append( wt );
262
ui.searchLayout->insertWidget( 0, wt );
267
void SearchWindow::updateStatusList()
270
int toBeDelete = listResults.count() - Settings::countOfStatusesOnMain();
272
if ( toBeDelete > 0 ) {
273
for ( int i = 0; i < toBeDelete; ++i ) {
274
StatusWidget* wt = listResults.at( i );
279
listResults.removeAt( i );
290
void SearchWindow::clearSearchResults()
293
int count = listResults.count();
295
for ( int i = 0; i < count; ++i ) {
296
StatusWidget* wt = listResults.first();
297
listResults.removeFirst();
302
void SearchWindow::markStatusesAsRead()
305
int count = listResults.count();
306
for ( int i = 0;i < count; ++i ) {
307
listResults[i]->setRead();
309
// qApp->setStyleSheet( qApp->styleSheet() );
312
void SearchWindow::setAccount( const Account &account )
314
disconnect( mSearch, SIGNAL( searchResultsReceived( QList< Status>& ) ),
315
this, SLOT( searchResultsReceived ( QList< Status >& ) ) );
316
disconnect( mSearch, SIGNAL( error( QString ) ), this, SLOT( error( QString ) ) );
321
connect( mSearch, SIGNAL( searchResultsReceived( QList< Status>& ) ),
322
this, SLOT( searchResultsReceived ( QList< Status >& ) ) );
323
connect( mSearch, SIGNAL( error( QString ) ), this, SLOT( error( QString ) ) );
326
void SearchWindow::resetSearchArea(int type, const QString & query)
329
ui.txtSearch->setText( query );
330
ui.txtSearch->setEnabled( true );
331
ui.comboSearchType->clear();
332
ui.chkAutoUpdate->setChecked( false );
333
ui.lblStatus->setText( i18n( "No Search Results" ) );
335
QMap<int, QPair<QString, bool> > searchTypes = mSearch->getSearchTypes();
336
for( int i = 0; i < searchTypes.count(); ++i ) {
337
ui.comboSearchType->insertItem( i, searchTypes[i].first );
340
if(!query.isEmpty()) {
342
ui.comboSearchType->setCurrentIndex(type);
347
void SearchWindow::updateSearchArea(int type, const QString& query)
349
ui.txtSearch->setText(query);
350
if(!query.isEmpty()) {
351
ui.comboSearchType->setCurrentIndex(type);
356
void SearchWindow::keyPressEvent( QKeyEvent* e )
358
if ( e->key() == Qt::Key_F5 ) {
359
// emit updateTimeLines();
362
} else if ( e->modifiers() == Qt::CTRL && e->key() == Qt::Key_R ) {
363
markStatusesAsRead();
365
QWidget::keyPressEvent( e );
369
void SearchWindow::refresh()
372
clearSearchResults();
373
updateSearchResults();
376
void SearchWindow::goForward()
380
ui.lblStatus->setText( i18n( "Fetching Next Page..." ) );
381
mSearch->requestSearchResults( lastSearchQuery,
384
Settings::countOfStatusesOnMain(),
388
void SearchWindow::goBack()
391
ui.btnBack->setEnabled( false );
396
ui.lblStatus->setText( i18n( "Fetching Previous Page..." ) );
397
mSearch->requestSearchResults( lastSearchQuery,
400
Settings::countOfStatusesOnMain(),
404
void SearchWindow::pageChange()
406
page = ui.txtPage->text().toULongLong();
407
ui.lblStatus->setText( i18n( "Fetching Page %1...", QString::number( page ) ) );
408
mSearch->requestSearchResults( lastSearchQuery,
411
Settings::countOfStatusesOnMain(),
415
void SearchWindow::showNavigation( bool showNav )
417
ui.btnBack->setVisible( showNav );
418
ui.btnForward->setVisible( showNav );
419
ui.txtPage->setVisible( showNav );
422
void SearchWindow::updateNumPages()
424
intValidator->setTop( 1500 / Settings::countOfStatusesOnMain() );
427
updateSearchResults();
430
void SearchWindow::slotSearchTypeChanged(int)
432
ui.txtSearch->setFocus(Qt::OtherFocusReason);
435
#include "searchwindow.moc"