~ubuntu-branches/ubuntu/karmic/choqok/karmic

« back to all changes in this revision

Viewing changes to choqok/searchwindow.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alessandro Ghersi, Alessandro Ghersi, Christian Mangold
  • Date: 2009-08-11 22:29:59 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20090811222959-7tnr98ptcnyx3pjg
Tags: 0.6.6-0ubuntu1
[Alessandro Ghersi]
* New upstream release
  - Bump Standards-Version to 3.8.2
  - Long description formatted to fit in 80 characters

[Christian Mangold]
* Improve long description
* Update Maintainer, package is in main now
* Add a watch file

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    This file is part of Choqok, the KDE micro-blogging client
 
3
 
 
4
    Copyright (C) 2008-2009 Mehrdad Momeny <mehrdad.momeny@gmail.com>
 
5
 
 
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.
 
13
 
 
14
 
 
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.
 
19
 
 
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/
 
22
 
 
23
*/
 
24
 
 
25
#include "searchwindow.h"
 
26
#include "statuswidget.h"
 
27
#include "settings.h"
 
28
#include <kdebug.h>
 
29
#include <QMap>
 
30
#include <QString>
 
31
#include <QScrollBar>
 
32
#include <KDE/KLocale>
 
33
#include <KMessageBox>
 
34
 
 
35
#include "twittersearch.h"
 
36
#include "identicasearch.h"
 
37
 
 
38
SearchWindow::SearchWindow( const Account &account, QWidget* parent ) :
 
39
        QWidget( parent )
 
40
{
 
41
    kDebug();
 
42
    mAccount = account;
 
43
 
 
44
    intValidator = new QIntValidator( 1, 1500 / Settings::countOfStatusesOnMain(), this );
 
45
 
 
46
    setAttribute( Qt::WA_DeleteOnClose );
 
47
 
 
48
    switch( mAccount.serviceType() )
 
49
    {
 
50
        case Account::Twitter:
 
51
            mSearch = new TwitterSearch( &mAccount, QString(), this );
 
52
            break;
 
53
        case Account::Identica:
 
54
        case Account::Laconica:
 
55
            mSearch = new IdenticaSearch( &mAccount, mAccount.homepage(), this );
 
56
            break;
 
57
        default:
 
58
            mSearch = 0;
 
59
            break;
 
60
    }
 
61
 
 
62
    ui.setupUi( this );
 
63
    resize( Settings::searchWindowSize() );
 
64
    move( Settings::searchWindowPosition() );
 
65
 
 
66
    setWindowTitle( i18nc( "Search in service", "%1 Search",
 
67
                           mAccount.alias() ) );
 
68
}
 
69
 
 
70
void SearchWindow::init(int type, const QString & query)
 
71
{
 
72
    kDebug();
 
73
 
 
74
    if( mSearch )
 
75
    {
 
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() ) );
 
81
 
 
82
        page = 1;
 
83
        lastValidPage = 1;
 
84
 
 
85
        ui.btnRefresh->setIcon( KIcon( "view-refresh" ) );
 
86
        ui.btnBack->setIcon( KIcon( "go-previous" ) );
 
87
        ui.btnForward->setIcon( KIcon( "go-next" ) );
 
88
 
 
89
        ui.btnRefresh->setEnabled( false );
 
90
        ui.btnBack->setEnabled( false );
 
91
        ui.btnForward->setEnabled( false );
 
92
 
 
93
        ui.txtPage->setValidator( intValidator );
 
94
 
 
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);
 
102
        show();
 
103
    }
 
104
    else
 
105
    {
 
106
        kDebug() << "Service has no search implementation";
 
107
        KMessageBox::error( this, i18n( "This service has no search feature." ) );
 
108
        close();
 
109
    }
 
110
}
 
111
 
 
112
SearchWindow::~SearchWindow()
 
113
{
 
114
    kDebug();
 
115
    Settings::setSearchWindowPosition(pos());
 
116
    Settings::setSearchWindowSize(size());
 
117
 
 
118
    if( mSearch )
 
119
        mSearch->deleteLater();
 
120
    intValidator->deleteLater();
 
121
}
 
122
 
 
123
void SearchWindow::error( QString message )
 
124
{
 
125
    ui.lblStatus->setText( i18n( "Failed: %1", message ) );
 
126
    lastSearchQuery.clear();
 
127
    ui.txtSearch->setEnabled( true );
 
128
}
 
129
 
 
130
void SearchWindow::searchResultsReceived(QList<Status> &statusList )
 
131
{
 
132
    kDebug();
 
133
 
 
134
    int count = statusList.count();
 
135
    if ( count == 0 ) {
 
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 );
 
139
        if( page > 1 )
 
140
            page = lastValidPage;
 
141
        ui.btnRefresh->setEnabled( false );
 
142
    } else {
 
143
 
 
144
        // Sets up the navigation for the current page
 
145
        if( mSearch->getSearchTypes()[lastSearchType].second ) {
 
146
            showNavigation( true );
 
147
            if( page == 1 )
 
148
            {
 
149
                ui.chkAutoUpdate->setEnabled( true );
 
150
                ui.btnBack->setEnabled( false );
 
151
                ui.btnForward->setEnabled( true );
 
152
            }
 
153
            else {
 
154
                if ( (int)page == intValidator->top() )
 
155
                    ui.btnForward->setEnabled( false );
 
156
                else
 
157
                    ui.btnForward->setEnabled( true );
 
158
                ui.chkAutoUpdate->setEnabled( false );
 
159
                clearSearchResults();
 
160
                ui.btnBack->setEnabled( true );
 
161
            }
 
162
        } else {
 
163
            showNavigation( false );
 
164
        }
 
165
 
 
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 );
 
171
    }
 
172
 
 
173
    ui.txtPage->setText( QString::number( lastValidPage ) );
 
174
    ui.txtSearch->setEnabled( true );
 
175
}
 
176
 
 
177
void SearchWindow::search()
 
178
{
 
179
    kDebug();
 
180
 
 
181
    page = 1;
 
182
 
 
183
    if ( ui.txtSearch->text().size() > 140 )
 
184
    {
 
185
        ui.lblStatus->setText( i18n( "Search text size is more than 140 characters." ) );
 
186
        return;
 
187
    }
 
188
 
 
189
    clearSearchResults();
 
190
 
 
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(),
 
196
                                   0,
 
197
                                   Settings::countOfStatusesOnMain() );
 
198
 
 
199
    lastSearchQuery = ui.txtSearch->text();
 
200
    lastSearchType = ui.comboSearchType->currentIndex();
 
201
 
 
202
    setWindowTitle( i18nc( "Search in service", "%1 Search (%2)",
 
203
                           mAccount.serviceName(), lastSearchQuery ) );
 
204
}
 
205
 
 
206
void SearchWindow::updateSearchResults()
 
207
{
 
208
    kDebug();
 
209
    if( isVisible() && !lastSearchQuery.isNull() && page == 1 )
 
210
    {
 
211
        qulonglong sinceStatusId = 0;
 
212
        if( listResults.count() )
 
213
            sinceStatusId = listResults.last()->currentStatus().statusId;
 
214
 
 
215
        ui.lblStatus->setText( i18n( "Searching..." ) );
 
216
        mSearch->requestSearchResults( lastSearchQuery,
 
217
                                       lastSearchType,
 
218
                                       sinceStatusId,
 
219
                                       Settings::countOfStatusesOnMain(),
 
220
                                       page );
 
221
    }
 
222
}
 
223
 
 
224
void SearchWindow::autoUpdateSearchResults()
 
225
{
 
226
    kDebug();
 
227
    if( ui.chkAutoUpdate->isChecked() )
 
228
        updateSearchResults();
 
229
}
 
230
 
 
231
void SearchWindow::addNewStatusesToUi( QList<Status> &statusList )
 
232
{
 
233
    kDebug();
 
234
 
 
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();
 
243
 
 
244
    QList<Status>::const_iterator it = statusList.constBegin();
 
245
    QList<Status>::const_iterator endIt = statusList.constEnd();
 
246
 
 
247
    for( ; it != endIt; ++it ) {
 
248
        StatusWidget *wt = new StatusWidget( &mAccount, this );
 
249
 
 
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)));
 
256
 
 
257
        wt->setAttribute( Qt::WA_DeleteOnClose );
 
258
        wt->setCurrentStatus( *it );
 
259
        wt->setUnread( StatusWidget::WithoutNotify );
 
260
 
 
261
        listResults.append( wt );
 
262
        ui.searchLayout->insertWidget( 0, wt );
 
263
    }
 
264
    updateStatusList();
 
265
}
 
266
 
 
267
void SearchWindow::updateStatusList()
 
268
{
 
269
    kDebug();
 
270
    int toBeDelete = listResults.count() - Settings::countOfStatusesOnMain();
 
271
 
 
272
    if ( toBeDelete > 0 ) {
 
273
        for ( int i = 0; i < toBeDelete; ++i ) {
 
274
            StatusWidget* wt = listResults.at( i );
 
275
 
 
276
            if ( !wt->isRead() )
 
277
                break;
 
278
 
 
279
            listResults.removeAt( i );
 
280
 
 
281
            --i;
 
282
 
 
283
            --toBeDelete;
 
284
 
 
285
            wt->close();
 
286
        }
 
287
    }
 
288
}
 
289
 
 
290
void SearchWindow::clearSearchResults()
 
291
{
 
292
    kDebug();
 
293
    int count = listResults.count();
 
294
 
 
295
    for ( int i = 0; i < count; ++i ) {
 
296
        StatusWidget* wt = listResults.first();
 
297
        listResults.removeFirst();
 
298
        wt->close();
 
299
    }
 
300
}
 
301
 
 
302
void SearchWindow::markStatusesAsRead()
 
303
{
 
304
    kDebug();
 
305
    int count = listResults.count();
 
306
    for ( int i = 0;i < count; ++i ) {
 
307
        listResults[i]->setRead();
 
308
    }
 
309
//     qApp->setStyleSheet( qApp->styleSheet() );
 
310
}
 
311
 
 
312
void SearchWindow::setAccount( const Account &account )
 
313
{
 
314
    disconnect( mSearch, SIGNAL( searchResultsReceived( QList< Status>& ) ),
 
315
                this, SLOT( searchResultsReceived ( QList< Status >& ) ) );
 
316
    disconnect( mSearch, SIGNAL( error( QString ) ), this, SLOT( error( QString ) ) );
 
317
 
 
318
    mAccount = account;
 
319
    resetSearchArea();
 
320
 
 
321
    connect( mSearch, SIGNAL( searchResultsReceived( QList< Status>& ) ),
 
322
             this, SLOT( searchResultsReceived ( QList< Status >& ) ) );
 
323
    connect( mSearch, SIGNAL( error( QString ) ), this, SLOT( error( QString ) ) );
 
324
}
 
325
 
 
326
void SearchWindow::resetSearchArea(int type, const QString & query)
 
327
{
 
328
    kDebug();
 
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" ) );
 
334
 
 
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 );
 
338
    }
 
339
 
 
340
    if(!query.isEmpty()) {
 
341
        kDebug()<<type;
 
342
        ui.comboSearchType->setCurrentIndex(type);
 
343
        search();
 
344
    }
 
345
}
 
346
 
 
347
void SearchWindow::updateSearchArea(int type, const QString& query)
 
348
{
 
349
  ui.txtSearch->setText(query);
 
350
  if(!query.isEmpty()) {
 
351
    ui.comboSearchType->setCurrentIndex(type);
 
352
    search();
 
353
  }
 
354
}
 
355
 
 
356
void SearchWindow::keyPressEvent( QKeyEvent* e )
 
357
{
 
358
    if ( e->key() == Qt::Key_F5 ) {
 
359
//         emit updateTimeLines();
 
360
        refresh();
 
361
        e->accept();
 
362
    } else if ( e->modifiers() == Qt::CTRL && e->key() == Qt::Key_R ) {
 
363
        markStatusesAsRead();
 
364
    } else {
 
365
        QWidget::keyPressEvent( e );
 
366
    }
 
367
}
 
368
 
 
369
void SearchWindow::refresh()
 
370
{
 
371
    page = 1;
 
372
    clearSearchResults();
 
373
    updateSearchResults();
 
374
}
 
375
 
 
376
void SearchWindow::goForward()
 
377
{
 
378
    ++page;
 
379
 
 
380
    ui.lblStatus->setText( i18n( "Fetching Next Page..." ) );
 
381
    mSearch->requestSearchResults( lastSearchQuery,
 
382
                                    lastSearchType,
 
383
                                    0,
 
384
                                    Settings::countOfStatusesOnMain(),
 
385
                                    page );
 
386
}
 
387
 
 
388
void SearchWindow::goBack()
 
389
{
 
390
    if (page == 1 ) {
 
391
        ui.btnBack->setEnabled( false );
 
392
        return;
 
393
    }
 
394
    --page;
 
395
 
 
396
    ui.lblStatus->setText( i18n( "Fetching Previous Page..." ) );
 
397
    mSearch->requestSearchResults( lastSearchQuery,
 
398
                                    lastSearchType,
 
399
                                    0,
 
400
                                    Settings::countOfStatusesOnMain(),
 
401
                                    page );
 
402
}
 
403
 
 
404
void SearchWindow::pageChange()
 
405
{
 
406
    page = ui.txtPage->text().toULongLong();
 
407
    ui.lblStatus->setText( i18n( "Fetching Page %1...", QString::number( page ) ) );
 
408
    mSearch->requestSearchResults( lastSearchQuery,
 
409
                                    lastSearchType,
 
410
                                    0,
 
411
                                    Settings::countOfStatusesOnMain(),
 
412
                                    page );
 
413
}
 
414
 
 
415
void SearchWindow::showNavigation( bool showNav )
 
416
{
 
417
    ui.btnBack->setVisible( showNav );
 
418
    ui.btnForward->setVisible( showNav );
 
419
    ui.txtPage->setVisible( showNav );
 
420
}
 
421
 
 
422
void SearchWindow::updateNumPages()
 
423
{
 
424
    intValidator->setTop( 1500 / Settings::countOfStatusesOnMain() );
 
425
    page = 1;
 
426
    lastValidPage = 1;
 
427
    updateSearchResults();
 
428
}
 
429
 
 
430
void SearchWindow::slotSearchTypeChanged(int)
 
431
{
 
432
    ui.txtSearch->setFocus(Qt::OtherFocusReason);
 
433
}
 
434
 
 
435
#include "searchwindow.moc"