~ubuntu-branches/ubuntu/karmic/amarok/karmic

« back to all changes in this revision

Viewing changes to src/widgets/ProgressiveSearchWidget.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2009-09-03 23:49:07 UTC
  • mfrom: (1.77.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20090903234907-rk4lt6hnxwckvuon
Tags: 2:2.1.80-0ubuntu1
New upstream beta release

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/***************************************************************************
2
 
 *   Copyright (c) 2008  Nikolaj Hald Nielsen <nhnFreespirit@gmail.com>    *
3
 
 *                                                                         *
4
 
 *   This program is free software; you can redistribute it and/or modify  *
5
 
 *   it under the terms of the GNU General Public License as published by  *
6
 
 *   the Free Software Foundation; either version 2 of the License, or     *
7
 
 *   (at your option) any later version.                                   *
8
 
 *                                                                         *
9
 
 *   This program is distributed in the hope that it will be useful,       *
10
 
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
11
 
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
12
 
 *   GNU General Public License for more details.                          *
13
 
 *                                                                         *
14
 
 *   You should have received a copy of the GNU General Public License     *
15
 
 *   along with this program; if not, write to the                         *
16
 
 *   Free Software Foundation, Inc.,                                       *
17
 
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
18
 
 ***************************************************************************/
19
 
 
20
 
#include "ProgressiveSearchWidget.h"
21
 
 
22
 
#include "Debug.h"
23
 
#include "playlist/PlaylistModel.h"
24
 
 
25
 
#include <KAction>
26
 
#include <KColorScheme>
27
 
#include <KHBox>
28
 
#include <KLocale>
29
 
 
30
 
#include <QKeyEvent>
31
 
#include <QLabel>
32
 
#include <QMenu>
33
 
#include <QToolBar>
34
 
#include <QToolButton>
35
 
 
36
 
ProgressiveSearchWidget::ProgressiveSearchWidget( QWidget * parent )
37
 
    : KVBox( parent )
38
 
{
39
 
    DEBUG_BLOCK
40
 
 
41
 
    readConfig();
42
 
 
43
 
    KHBox *searchBox = new KHBox( this );
44
 
    m_warningLabel = new QLabel( i18n("Warning: tracks have been hidden in the playlist"), this );
45
 
    hideHiddenTracksWarning();
46
 
 
47
 
    m_searchEdit = new Amarok::LineEdit( searchBox );
48
 
    m_searchEdit->setClickMessage( i18n( "Search playlist" ) );
49
 
    m_searchEdit->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
50
 
    m_searchEdit->setClearButtonShown( true );
51
 
    m_searchEdit->setFrame( true );
52
 
    m_searchEdit->setToolTip( i18n( "Start typing to progressively search through the playlist" ) );
53
 
    m_searchEdit->setFocusPolicy( Qt::ClickFocus ); // Without this, the widget goes into text input mode directly on startup
54
 
 
55
 
    connect( m_searchEdit, SIGNAL( textChanged( const QString & ) ), this, SLOT( slotFilterChanged(  const QString &  ) ) );
56
 
    connect( m_searchEdit, SIGNAL( returnPressed( const QString & ) ), this, SIGNAL( activateFilterResult() ) );
57
 
    connect( m_searchEdit, SIGNAL( downPressed() ), this, SIGNAL( downPressed() ) );
58
 
 
59
 
    QToolBar *toolbar = new QToolBar( searchBox );
60
 
 
61
 
    m_nextAction = new KAction( KIcon( "go-down" ), i18n( "&Next" ), this );
62
 
    connect( m_nextAction, SIGNAL( triggered() ), this, SLOT( slotNext() ) );
63
 
    
64
 
    m_previousAction = new KAction( KIcon( "go-up" ), i18n( "&Previous" ), this );
65
 
    connect( m_previousAction, SIGNAL( triggered() ), this, SLOT( slotPrevious() ) );
66
 
 
67
 
    toolbar->addAction( m_nextAction );
68
 
    toolbar->addAction( m_previousAction );
69
 
 
70
 
    m_nextAction->setEnabled( false );
71
 
    m_previousAction->setEnabled( false );
72
 
 
73
 
    m_menu = new QMenu( this );
74
 
 
75
 
    KAction * searchTracksAction = new KAction( i18n( "Tracks" ), this );
76
 
    searchTracksAction->setCheckable( true );
77
 
    connect( searchTracksAction, SIGNAL( toggled( bool ) ), this, SLOT( slotSearchTracks( bool ) ) );
78
 
    if( m_searchFieldsMask & Playlist::MatchTrack )
79
 
        searchTracksAction->setChecked( true );
80
 
    m_menu->addAction( searchTracksAction );
81
 
 
82
 
    KAction * searchAlbumsAction = new KAction( i18n( "Albums" ), this );
83
 
    searchAlbumsAction->setCheckable( true );
84
 
    connect( searchAlbumsAction, SIGNAL( toggled( bool ) ), this, SLOT( slotSearchAlbums( bool ) ) );
85
 
    if( m_searchFieldsMask & Playlist::MatchAlbum )
86
 
        searchAlbumsAction->setChecked( true );
87
 
    m_menu->addAction( searchAlbumsAction );
88
 
    
89
 
    KAction * searchArtistsAction = new KAction( i18n( "Artists" ), this );
90
 
    searchArtistsAction->setCheckable( true );
91
 
    connect( searchArtistsAction, SIGNAL( toggled( bool ) ), this, SLOT( slotSearchArtists( bool ) ) );
92
 
    if( m_searchFieldsMask & Playlist::MatchArtist )
93
 
        searchArtistsAction->setChecked( true );
94
 
    m_menu->addAction( searchArtistsAction );
95
 
 
96
 
    KAction * searchGenreAction = new KAction( i18n( "Genre" ), this );
97
 
    searchGenreAction->setCheckable( true );
98
 
    connect( searchGenreAction, SIGNAL( toggled( bool ) ), this, SLOT( slotSearchGenre( bool ) ) );
99
 
    if( m_searchFieldsMask & Playlist::MatchGenre )
100
 
        searchGenreAction->setChecked( true );
101
 
    m_menu->addAction( searchGenreAction );
102
 
 
103
 
    KAction * searchComposersAction = new KAction( i18n( "Composers" ), this );
104
 
    searchComposersAction->setCheckable( true );
105
 
    connect( searchComposersAction, SIGNAL( toggled( bool ) ), this, SLOT( slotSearchComposers( bool ) ) );
106
 
    if( m_searchFieldsMask & Playlist::MatchComposer )
107
 
        searchComposersAction->setChecked( true );
108
 
    m_menu->addAction( searchComposersAction );
109
 
 
110
 
    KAction * searchYearsAction = new KAction( i18n( "Years" ), this );
111
 
    searchYearsAction->setCheckable( true );
112
 
    connect( searchYearsAction, SIGNAL( toggled( bool ) ), this, SLOT( slotSearchYears( bool ) ) );
113
 
    if( m_searchFieldsMask & Playlist::MatchYear)
114
 
        searchYearsAction->setChecked( true );
115
 
    m_menu->addAction( searchYearsAction );
116
 
 
117
 
    m_menu->addSeparator();
118
 
 
119
 
    KAction * showOnlyMatchesAction = new KAction( i18n( "Show only matches" ), this );
120
 
    showOnlyMatchesAction->setCheckable( true );
121
 
    connect( showOnlyMatchesAction, SIGNAL( toggled( bool ) ), this, SLOT( slotShowOnlyMatches( bool ) ) );
122
 
 
123
 
    showOnlyMatchesAction->setChecked( m_showOnlyMatches );
124
 
    m_menu->addAction( showOnlyMatchesAction );
125
 
 
126
 
    m_nextAction->setVisible( !m_showOnlyMatches );
127
 
    m_previousAction->setVisible( !m_showOnlyMatches );
128
 
 
129
 
    KAction *searchMenuAction = new KAction( KIcon( "preferences-other" ), i18n( "Search Preferences" ), this );
130
 
    searchMenuAction->setMenu( m_menu );
131
 
    toolbar->addAction( searchMenuAction );
132
 
    
133
 
    QToolButton *tbutton = qobject_cast<QToolButton*>(toolbar->widgetForAction( searchMenuAction ) );
134
 
    if( tbutton )
135
 
        tbutton->setPopupMode( QToolButton::InstantPopup );
136
 
    
137
 
    toolbar->setFixedHeight( m_searchEdit->sizeHint().height() );
138
 
 
139
 
    //make sure that this edit is cleared when the playlist is cleared:
140
 
    connect( Amarok::actionCollection()->action( "playlist_clear" ), SIGNAL( triggered() ), this, SLOT( slotFilterClear() ) );
141
 
}
142
 
 
143
 
 
144
 
ProgressiveSearchWidget::~ProgressiveSearchWidget()
145
 
{}
146
 
 
147
 
void ProgressiveSearchWidget::slotFilterChanged( const QString & filter )
148
 
{
149
 
    DEBUG_BLOCK
150
 
 
151
 
    //when the clear button is pressed, we get 2 calls to this slot... filter this out  as it messes with
152
 
    //resetting the view:
153
 
    if ( filter == m_lastFilter )
154
 
        return;
155
 
    
156
 
    debug() << "New filter: " << filter;
157
 
 
158
 
    m_lastFilter = filter;
159
 
 
160
 
    if( filter.isEmpty() )
161
 
    {
162
 
        m_nextAction->setEnabled( false );
163
 
        m_previousAction->setEnabled( false );
164
 
 
165
 
        QPalette p = m_searchEdit->palette();
166
 
        p.setColor( QPalette::Base, palette().color( QPalette::Base ) );
167
 
        m_searchEdit->setPalette( p );
168
 
 
169
 
        if( m_showOnlyMatches )
170
 
            hideHiddenTracksWarning();
171
 
 
172
 
        emit( filterCleared() );
173
 
 
174
 
        return;
175
 
    }
176
 
 
177
 
    emit( filterChanged( filter, m_searchFieldsMask, m_showOnlyMatches ) );
178
 
}
179
 
 
180
 
void ProgressiveSearchWidget::slotNext()
181
 
{
182
 
    DEBUG_BLOCK
183
 
    emit( next( m_searchEdit->text(), m_searchFieldsMask ) );
184
 
}
185
 
 
186
 
void ProgressiveSearchWidget::slotPrevious()
187
 
{
188
 
    DEBUG_BLOCK
189
 
    emit( previous( m_searchEdit->text(), m_searchFieldsMask ) );
190
 
}
191
 
 
192
 
void ProgressiveSearchWidget::match()
193
 
{
194
 
    m_nextAction->setEnabled( true );
195
 
    m_previousAction->setEnabled( true );
196
 
 
197
 
    QPalette p = m_searchEdit->palette();
198
 
    p.setColor( QPalette::Base, palette().color( QPalette::Base ) );
199
 
    m_searchEdit->setPalette( p );
200
 
 
201
 
    if( m_showOnlyMatches )
202
 
        hideHiddenTracksWarning();
203
 
}
204
 
 
205
 
void ProgressiveSearchWidget::noMatch()
206
 
{
207
 
    m_nextAction->setEnabled( false );
208
 
    m_previousAction->setEnabled( false );
209
 
 
210
 
    const KStatefulBrush backgroundBrush( KColorScheme::View, KColorScheme::NegativeBackground );
211
 
 
212
 
    QPalette p = m_searchEdit->palette();
213
 
    p.setColor( QPalette::Base, backgroundBrush.brush( m_searchEdit ).color() );
214
 
    m_searchEdit->setPalette( p );
215
 
 
216
 
    if( m_showOnlyMatches )
217
 
        showHiddenTracksWarning();
218
 
}
219
 
 
220
 
void ProgressiveSearchWidget::showHiddenTracksWarning()
221
 
{
222
 
    m_warningLabel->show();
223
 
}
224
 
 
225
 
void ProgressiveSearchWidget::hideHiddenTracksWarning()
226
 
{
227
 
    m_warningLabel->hide();
228
 
}
229
 
 
230
 
void ProgressiveSearchWidget::slotSearchTracks( bool search )
231
 
{
232
 
    if( search )
233
 
        m_searchFieldsMask |= Playlist::MatchTrack;
234
 
    else
235
 
        m_searchFieldsMask ^= Playlist::MatchTrack;
236
 
 
237
 
    Amarok::config( "Playlist Search" ).writeEntry( "MatchTrack", search );
238
 
 
239
 
    if( !m_searchEdit->text().isEmpty() )
240
 
        emit( filterChanged( m_searchEdit->text(), m_searchFieldsMask, m_showOnlyMatches ) );
241
 
}
242
 
 
243
 
void ProgressiveSearchWidget::slotSearchArtists( bool search )
244
 
{
245
 
    if( search )
246
 
        m_searchFieldsMask |= Playlist::MatchArtist;
247
 
    else
248
 
        m_searchFieldsMask ^= Playlist::MatchArtist;
249
 
 
250
 
    Amarok::config( "Playlist Search" ).writeEntry( "MatchArtist", search );
251
 
 
252
 
    if( !m_searchEdit->text().isEmpty() )
253
 
        emit( filterChanged( m_searchEdit->text(), m_searchFieldsMask, m_showOnlyMatches ) );
254
 
}
255
 
 
256
 
void ProgressiveSearchWidget::slotSearchAlbums( bool search )
257
 
{
258
 
    if( search )
259
 
        m_searchFieldsMask |= Playlist::MatchAlbum;
260
 
    else
261
 
        m_searchFieldsMask ^= Playlist::MatchAlbum;
262
 
 
263
 
    Amarok::config( "Playlist Search" ).writeEntry( "MatchAlbum", search );
264
 
    
265
 
    if( !m_searchEdit->text().isEmpty() )
266
 
        emit( filterChanged( m_searchEdit->text(), m_searchFieldsMask, m_showOnlyMatches ) );
267
 
}
268
 
 
269
 
void ProgressiveSearchWidget::slotSearchGenre( bool search )
270
 
{
271
 
    if( search )
272
 
        m_searchFieldsMask |= Playlist::MatchGenre;
273
 
    else
274
 
        m_searchFieldsMask ^= Playlist::MatchGenre;
275
 
 
276
 
    Amarok::config( "Playlist Search" ).writeEntry( "MatchGenre", search );
277
 
 
278
 
    if( !m_searchEdit->text().isEmpty() )
279
 
        emit( filterChanged( m_searchEdit->text(), m_searchFieldsMask, m_showOnlyMatches ) );
280
 
}
281
 
 
282
 
void ProgressiveSearchWidget::slotSearchComposers( bool search )
283
 
{
284
 
    if( search )
285
 
        m_searchFieldsMask |= Playlist::MatchComposer;
286
 
    else
287
 
        m_searchFieldsMask ^= Playlist::MatchComposer;
288
 
 
289
 
    Amarok::config( "Playlist Search" ).writeEntry( "MatchComposer", search );
290
 
 
291
 
    if( !m_searchEdit->text().isEmpty() )
292
 
        emit( filterChanged( m_searchEdit->text(), m_searchFieldsMask, m_showOnlyMatches ) );
293
 
}
294
 
 
295
 
void ProgressiveSearchWidget::slotSearchYears( bool search )
296
 
{
297
 
    if( search )
298
 
        m_searchFieldsMask |= Playlist::MatchYear;
299
 
    else
300
 
        m_searchFieldsMask ^= Playlist::MatchYear;
301
 
 
302
 
    Amarok::config( "Playlist Search" ).writeEntry( "MatchYear", search );
303
 
 
304
 
    if( !m_searchEdit->text().isEmpty() )
305
 
        emit( filterChanged( m_searchEdit->text(), m_searchFieldsMask, m_showOnlyMatches ) );
306
 
}
307
 
 
308
 
void ProgressiveSearchWidget::readConfig()
309
 
{
310
 
    m_searchFieldsMask = 0;
311
 
    
312
 
    KConfigGroup config = Amarok::config("Playlist Search");
313
 
 
314
 
    if( config.readEntry( "MatchTrack", true ) )
315
 
        m_searchFieldsMask |= Playlist::MatchTrack;
316
 
    if( config.readEntry( "MatchArtist", true ) )
317
 
        m_searchFieldsMask |= Playlist::MatchArtist;
318
 
    if( config.readEntry( "MatchAlbum", true ) )
319
 
        m_searchFieldsMask |= Playlist::MatchAlbum;
320
 
    if( config.readEntry( "MatchGenre", false ) )
321
 
        m_searchFieldsMask |= Playlist::MatchGenre;
322
 
    if( config.readEntry( "MatchComposer", false ) )
323
 
        m_searchFieldsMask |= Playlist::MatchComposer;
324
 
    if( config.readEntry( "MatchYear", false ) )
325
 
        m_searchFieldsMask |= Playlist::MatchYear;
326
 
 
327
 
    m_showOnlyMatches = config.readEntry( "ShowOnlyMatches", false );
328
 
}
329
 
 
330
 
void ProgressiveSearchWidget::slotShowOnlyMatches( bool onlyMatches )
331
 
{
332
 
    KConfigGroup config = Amarok::config( "Playlist Search" );
333
 
    config.writeEntry( "ShowOnlyMatches", onlyMatches );
334
 
 
335
 
    m_showOnlyMatches = onlyMatches;
336
 
 
337
 
    m_nextAction->setVisible( !onlyMatches );
338
 
    m_previousAction->setVisible( !onlyMatches );
339
 
    
340
 
    emit( showOnlyMatches( onlyMatches ) );
341
 
}
342
 
 
343
 
void
344
 
ProgressiveSearchWidget::keyPressEvent( QKeyEvent *event )
345
 
{
346
 
    if( event->matches( QKeySequence::FindNext ) )
347
 
    {
348
 
        event->accept();
349
 
        slotNext();
350
 
    }
351
 
    else if( event->matches( QKeySequence::FindPrevious ) )
352
 
    {
353
 
        event->accept();
354
 
        slotPrevious();
355
 
    }
356
 
    else
357
 
    {
358
 
        event->ignore();
359
 
        KHBox::keyPressEvent( event );
360
 
    }
361
 
}
362
 
 
363
 
void ProgressiveSearchWidget::slotFilterClear()
364
 
{
365
 
    m_searchEdit->setText( QString() );
366
 
}
367
 
 
368
 
#include "ProgressiveSearchWidget.moc"