add mp3 and ogg torrent url info to JamendoAlbum
[amarok.git] / src / editfilterdialog.cpp
blobe3350eb9631cd29cb09e21e28c783ea57c863a01
1 // (c) 2006 Giovanni Venturi <giovanni@kde-it.org>
2 // See COPYING file for licensing information.
4 #include "editfilterdialog.h"
6 #include "amarokconfig.h"
7 #include "collectiondb.h"
8 #include "debug.h"
9 #include "metabundle.h"
11 #include <KGlobal>
12 #include <KLineEdit>
13 #include <KLocale>
14 #include <KMessageBox>
15 #include <KPushButton>
17 #include <QLayout>
18 #include <QDateTime>
19 #include <QLabel>
20 #include <q3groupbox.h>
21 #include <QRadioButton>
22 #include <QLineEdit>
23 #include <QComboBox>
24 #include <QCheckBox>
25 #include <QSpinBox>
26 #include <QToolTip>
29 EditFilterDialog::EditFilterDialog( QWidget* parent, bool metaBundleKeywords, const QString &text )
30 : KDialog( parent ),
31 m_minMaxRadio(0),
32 m_filterText(text)
34 setCaption( i18n("Edit Filter") );
35 setModal( true );
36 setButtons( User1|User2|Default|Ok|Cancel );
37 setDefaultButton( Cancel );
38 showButtonSeparator( true );
41 // Redefine "Default" button
42 KGuiItem defaultButton( i18n("&Append"), "add" );
43 setButtonWhatsThis( Default, i18n( "<qt><p>By clicking here you can add the defined condition. The \"OK\" button will "
44 "close the dialog and apply the defined filter. With this button you can add more than "
45 "one condition to create a more complex filtering condition.</p></qt>" ) );
46 setButtonToolTip(Default, i18n( "Add this filter condition to the list" ) );
47 setButtonGuiItem( Default, defaultButton );
49 // define "User1" button
50 KGuiItem user1Button( i18n("&Clear"), "remove" );
51 setButtonWhatsThis( User1, i18n( "<p>By clicking here you will clear the filter. If you intend to "
52 "undo the last appending just click on the \"Undo\" button.</p>" ) );
53 setButtonToolTip(User1, i18n( "Clear the filter" ) );
54 setButtonGuiItem( User1, user1Button );
56 // define "User2" button
57 KGuiItem user2Button( i18nc("this \"undo\" will undo the last appended filter... be careful how you will translate it "
58 "to avoid two buttons (\"Cancel\" and \"Undo\") with same label in the same dialog", "&Undo"), "undo" );
59 setButtonWhatsThis( User2, i18n( "<p>Clicking here will remove the last appended filter. "
60 "You cannot undo more than one action.</p>" ) );
61 setButtonToolTip(User2, i18n( "Remove last appended filter" ) );
62 setButtonGuiItem( User2, user2Button );
64 setMainWidget( new QWidget( this ) );
66 m_mainLay = new QVBoxLayout( mainWidget() );
67 m_mainLay->activate();
69 // no filter rule available
70 m_appended = false;
72 // text explanation of this dialog
73 QLabel *label1 = new QLabel( mainWidget() );
74 label1->setObjectName( "label1" );
75 label1->setText( i18n("<p>Edit the filter for finding tracks with specific attributes"
76 ", e.g. you can look for a track that has a length of three minutes.</p>") );
77 m_mainLay->addWidget( label1 );
78 m_mainLay->addItem( new QSpacerItem( 10, 10, QSizePolicy::Expanding, QSizePolicy::Minimum ) );
80 // choosing keyword filtering
81 QHBoxLayout *keywordLayout = new QHBoxLayout( mainWidget() );
82 QLabel *label3 = new QLabel( i18n("Attribute:"), mainWidget() );
83 label3->setObjectName( "label3" );
84 label3->setWhatsThis(
85 i18nc("you can translate the keyword as you will do for the combobox",
86 "<p>Here you can choose to <i>Simple Search</i> directly or to use "
87 "some keywords to specify some attributes, such as the artist name "
88 "and so on. The keywords selectable are divided by their specific value. "
89 "Some keywords are numeric and others are alphanumeric. You do not need "
90 "to know it directly. When a keyword is numeric it will be used to search "
91 "the numeric data for each track.</p><p>The alphanumeric "
92 "keywords are the following: <b>album</b>, <b>artist</b>, <b>filename</b> "
93 " (including path), <b>mountpoint</b> (e.g. /home/user1), <b>filetype</b> "
94 " (you can specify mp3, ogg, flac, ... and the file extensions will be matched), "
95 "<b>genre</b>, <b>comment</b>, <b>composer</b>, <b>directory</b>, <b>lyrics</b>, "
96 "<b>title</b>, and <b>label</b>.</p>"
97 "<p>The numeric keywords are: <b>bitrate</b>, <b>disc/discnumber</b>, "
98 "<b>length</b> (expressed in seconds), <b>playcount</b>, <b>rating</b>, "
99 "<b>samplerate</b>, <b>score</b>, <b>size/filesize</b> (expressed in bytes, "
100 "kbytes, and megabytes as specified in the unit for the filesize keyword), "
101 "<b>track</b> (i.e. the track number), and <b>year</b>.</p>") );
102 keywordLayout->addWidget( label3 );
103 keywordLayout->addItem( new QSpacerItem( 5, 10, QSizePolicy::Minimum, QSizePolicy::Minimum ) );
104 m_comboKeyword = new QComboBox( mainWidget() );
105 m_comboKeyword->setObjectName( "keywordComboBox" );
106 m_comboKeyword->setToolTip( i18n("Select an attribute for the filter") );
107 label3->setBuddy( m_comboKeyword );
109 m_comboKeyword->addItem( i18n("Simple Search") );
110 m_vector.push_back("Simple Search");
111 if( metaBundleKeywords )
113 for( int i=0; i < MetaBundle::NUM_COLUMNS; ++i )
115 if( i == MetaBundle::Mood )
116 continue;
117 if( !AmarokConfig::useRatings() && i == MetaBundle::Rating )
118 continue;
119 if( !AmarokConfig::useScores() && i == MetaBundle::Score )
120 continue;
122 m_comboKeyword->addItem( MetaBundle::prettyColumnName( i ) );
123 m_vector.push_back( MetaBundle::exactColumnName( i ).toLower() );
126 else
128 m_comboKeyword->addItem( i18n("Album") );
129 m_vector.push_back( "album" );
130 m_comboKeyword->addItem( i18n("Artist") );
131 m_vector.push_back( "artist" );
132 m_comboKeyword->addItem( i18n("Bitrate") );
133 m_vector.push_back( "bitrate" );
134 m_comboKeyword->addItem( i18n("BPM") );
135 m_vector.push_back( "bpm" );
136 m_comboKeyword->addItem( i18n("Comment") );
137 m_vector.push_back( "comment" );
138 m_comboKeyword->addItem( i18n("Composer") );
139 m_vector.push_back( "composer" );
140 m_comboKeyword->addItem( i18n("Directory") );
141 m_vector.push_back( "directory" );
142 m_comboKeyword->addItem( i18n("Disc Number") );
143 m_vector.push_back( "disc" );
144 m_comboKeyword->addItem( i18n("Filename") );
145 m_vector.push_back( "filename" );
146 m_comboKeyword->addItem( i18n("Mount Point") );
147 m_vector.push_back( "mountpoint" );
148 m_comboKeyword->addItem( i18n("Filetype") );
149 m_vector.push_back( "filetype" );
150 m_comboKeyword->addItem( i18n("Genre") );
151 m_vector.push_back( "genre" );
152 m_comboKeyword->addItem( i18n("Length") );
153 m_vector.push_back( "length" );
154 m_comboKeyword->addItem( i18n("Label") );
155 m_vector.push_back( "label" );
156 m_comboKeyword->addItem( i18n("Lyrics") );
157 m_vector.push_back( "lyrics" );
158 m_comboKeyword->addItem( i18n("Play Count") );
159 m_vector.push_back( "playcount" );
160 if( AmarokConfig::useRatings() )
162 m_comboKeyword->addItem( i18n("Rating") );
163 m_vector.push_back( "rating" );
165 m_comboKeyword->addItem( i18n("Sample Rate") );
166 m_vector.push_back( "samplerate" );
167 if( AmarokConfig::useScores() )
169 m_comboKeyword->addItem( i18n("Score") );
170 m_vector.push_back( "score" );
172 m_comboKeyword->addItem( i18n("File Size") );
173 m_vector.push_back( "size" );
174 m_comboKeyword->addItem( i18n("Title") );
175 m_vector.push_back( "title" );
176 m_comboKeyword->addItem( i18n("Track") );
177 m_vector.push_back( "track" );
178 m_comboKeyword->addItem( i18n("Year") );
179 m_vector.push_back( "year" );
182 // the "Simple Search" text is selected in the comboKeyword
183 m_selectedIndex = 0;
185 keywordLayout->addWidget( m_comboKeyword );
186 keywordLayout->addItem( new QSpacerItem( 5, 10, QSizePolicy::Minimum, QSizePolicy::Minimum ) );
187 m_editKeyword = new KLineEdit( mainWidget() );
188 m_editKeyword->setObjectName( "editKeywordBox" );
189 m_editKeyword->setWhatsThis( i18n("<p>Type the attribute value or the text to look for here.</p>") );
190 keywordLayout->addWidget( m_editKeyword );
191 m_mainLay->addLayout( keywordLayout );
192 m_mainLay->addItem( new QSpacerItem( 10, 10, QSizePolicy::Expanding, QSizePolicy::Minimum ) );
193 connect(m_comboKeyword, SIGNAL(activated(int)), this, SLOT(selectedKeyword(int)));
195 // group of options on numeric attribute keywords: a value <,>,= ... or a value between Min and Max
196 m_groupBox = new Q3GroupBox( mainWidget(), "groupBox" );
197 m_groupBox->setTitle( i18n( "Attribute value is" ) );
198 m_mainLay->addWidget( m_groupBox );
199 m_mainLay->addItem( new QSpacerItem( 10, 10, QSizePolicy::Minimum, QSizePolicy::Minimum ) );
201 QVBoxLayout *vertLayout = new QVBoxLayout( m_groupBox );
202 vertLayout->setMargin( 15 );
203 vertLayout->setSpacing( 5 );
205 // choose other keyword parameters: smaller than, greater than, equal to...
206 QHBoxLayout *paramLayout = new QHBoxLayout();
207 vertLayout->addLayout( paramLayout );
209 m_comboCondition = new QComboBox( m_groupBox );
210 m_comboCondition->setObjectName( "valuecondition" );
211 m_comboCondition->addItem( i18n("smaller than") );
212 m_comboCondition->addItem( i18n("larger than") );
213 m_comboCondition->addItem( i18n("equal to") );
214 m_comboCondition->addItem( i18n("between") );
215 paramLayout->addWidget( m_comboCondition );
216 paramLayout->addItem( new QSpacerItem( 5, 10, QSizePolicy::Fixed, QSizePolicy::Minimum ) );
218 m_spinMin1 = new QSpinBox( m_groupBox );
219 m_spinMin1->setObjectName( "minimum1" );
220 paramLayout->addWidget( m_spinMin1 );
221 paramLayout->addItem( new QSpacerItem( 5, 10, QSizePolicy::Minimum, QSizePolicy::Minimum ) );
223 m_spinMin2 = new QSpinBox( m_groupBox );
224 m_spinMin2->setObjectName( "minimum2" );
225 paramLayout->addWidget( m_spinMin2 );
226 paramLayout->addItem( new QSpacerItem( 5, 10, QSizePolicy::Minimum, QSizePolicy::Minimum ) );
228 connect(m_spinMin1, SIGNAL(valueChanged(int)), this, SLOT(minSpinChanged(int)));
230 m_andLabel = new QLabel( i18n("and"), m_groupBox );
231 m_andLabel->setObjectName( "andLabel" );
232 paramLayout->addWidget( m_andLabel );
233 paramLayout->addItem( new QSpacerItem( 5, 10, QSizePolicy::Minimum, QSizePolicy::Minimum ) );
235 m_spinMax1 = new QSpinBox( m_groupBox );
236 m_spinMax1->setObjectName( "maximum1" );
237 paramLayout->addWidget( m_spinMax1 );
238 paramLayout->addItem( new QSpacerItem( 5, 10, QSizePolicy::Minimum, QSizePolicy::Minimum ) );
240 m_spinMax2 = new QSpinBox( m_groupBox );
241 m_spinMax2->setObjectName( "maximum2" );
242 paramLayout->addWidget( m_spinMax2 );
244 connect(m_spinMax1, SIGNAL(valueChanged(int)), this, SLOT(maxSpinChanged(int)));
246 QHBoxLayout *filesizeLayout = new QHBoxLayout();
247 vertLayout->addLayout( filesizeLayout );
248 filesizeLayout->setAlignment( Qt::AlignLeft );
249 m_filesizeLabel = new QLabel( i18n("Unit:"), m_groupBox );
250 m_filesizeLabel->setObjectName( "filesizeLabel" );
251 filesizeLayout->addWidget( m_filesizeLabel );
252 filesizeLayout->addItem( new QSpacerItem( 5, 10, QSizePolicy::Fixed, QSizePolicy::Minimum ) );
253 m_comboUnitSize = new QComboBox( m_groupBox );
254 m_comboUnitSize->setObjectName( "comboUnitSize" );
255 m_filesizeLabel->setBuddy( m_comboUnitSize );
256 m_comboUnitSize->addItem( i18n("B (1 Byte)") );
257 m_comboUnitSize->addItem( i18n("KB (1024 Bytes)") );
258 m_comboUnitSize->addItem( i18n("MB (1024 KB)") );
259 filesizeLayout->addWidget( m_comboUnitSize );
261 // type text selected
262 textWanted();
264 // check the "One Value Choosing" by default
265 chooseOneValue();
267 connect( m_comboCondition, SIGNAL(activated(int)), SLOT(chooseCondition(int)) );
269 QHBoxLayout *otherOptionsLayout = new QHBoxLayout( mainWidget() );
270 otherOptionsLayout->setAlignment( Qt::AlignHCenter );
271 m_mainLay->addLayout( otherOptionsLayout );
273 // the groupbox to select the action filter
274 m_groupBox2 = new Q3GroupBox( mainWidget(), "groupBox2" );
275 m_groupBox2->setTitle( i18n( "Filter action" ) );
276 otherOptionsLayout->addWidget( m_groupBox2 );
278 QVBoxLayout* ratioLay = new QVBoxLayout( m_groupBox2 );
279 ratioLay->setMargin( 15 );
280 ratioLay->setSpacing( 0 );
282 m_checkALL = new QRadioButton( i18n("Match all words"), m_groupBox2 );
283 m_checkALL->setObjectName( "checkall" );
284 m_checkALL->setToolTip(
285 i18n("<p>Check this box to look for the tracks that contain all the words you typed "
286 "in the related Simple Search edit box</p>"));
287 ratioLay->addWidget( m_checkALL );
289 m_checkAtLeastOne = new QRadioButton( i18n("Match any word"), m_groupBox2 );
290 m_checkAtLeastOne->setObjectName( "checkor" );
291 m_checkAtLeastOne->setToolTip(
292 i18n("<p>Check this box to look for the tracks that contain at least one of the words "
293 "you typed in the related Simple Search edit box</p>"));
294 ratioLay->addWidget( m_checkAtLeastOne );
296 m_checkExactly = new QRadioButton( i18n("Exact match"), m_groupBox2 );
297 m_checkExactly->setObjectName( "checkexactly" );
298 m_checkExactly->setToolTip(
299 i18n("<p>Check this box to look for all the tracks that contain exactly the words you typed "
300 "in the related Simple Search edit box</p>"));
301 ratioLay->addWidget( m_checkExactly );
303 m_checkExclude = new QRadioButton( i18n("Exclude"), m_groupBox2 );
304 m_checkExclude->setObjectName( "checkexclude" );
305 m_checkExclude->setToolTip(
306 i18n("<p>Check this box to look for all the tracks that do not contain the words you typed "
307 "in the related Simple Search edit box</p>"));
308 ratioLay->addWidget( m_checkExclude );
310 m_actionCheck << m_checkALL;
311 m_actionCheck << m_checkAtLeastOne;
312 m_actionCheck << m_checkExactly;
313 m_actionCheck << m_checkExclude;
315 connect( m_checkALL, SIGNAL(clicked()), this, SLOT(slotCheckAll()) );
316 connect( m_checkAtLeastOne, SIGNAL(clicked()), this, SLOT(slotCheckAtLeastOne()) );
317 connect( m_checkExactly, SIGNAL(clicked()), this, SLOT(slotCheckExactly()) );
318 connect( m_checkExclude, SIGNAL(clicked()), this, SLOT(slotCheckExclude()) );
320 // check "select all words" as default
321 slotCheckAll();
323 // some vertical space
324 otherOptionsLayout->addItem( new QSpacerItem( 50, 5, QSizePolicy::Minimum, QSizePolicy::Minimum ) );
326 QVBoxLayout* verticalCondLay = new QVBoxLayout();
327 otherOptionsLayout->addLayout( verticalCondLay );
328 verticalCondLay->setMargin(15);
329 verticalCondLay->setSpacing(0);
331 m_groupBox3 = new Q3GroupBox( mainWidget(), "groupBox3" );
332 m_groupBox3->setTitle( i18n( "Appending condition" ) );
333 verticalCondLay->addWidget( m_groupBox3 );
335 QVBoxLayout* ratioLay2 = new QVBoxLayout( m_groupBox3 );
336 ratioLay2->setMargin(15);
337 ratioLay2->setSpacing(0);
340 m_checkAND = new QRadioButton( i18nc("AND logic condition", "AND"), m_groupBox3 );
341 m_checkAND->setObjectName( "checkAND" );
342 m_checkAND->setToolTip(
343 i18n("<p>Check this box if you want to add another condition and you want that the filter "
344 "to match both the previous conditions and this new one</p>"));
345 ratioLay2->addWidget( m_checkAND );
347 m_checkOR = new QRadioButton( i18nc("OR logic condition", "OR"), m_groupBox3 );
348 m_checkOR->setObjectName( "checkOR" );
349 m_checkOR->setToolTip(
350 i18n("<p>Check this box if you want to add another condition and you want that the filter "
351 "to match either the previous conditions or this new one</p>"));
352 ratioLay2->addWidget( m_checkOR );
354 otherOptionsLayout->addItem( new QSpacerItem( 10, 10, QSizePolicy::Minimum, QSizePolicy::Minimum ) );
356 m_prefixNOT = new QCheckBox( i18n("Invert condition"), mainWidget() );
357 m_prefixNOT->setObjectName( "prefixNOT" );
358 m_prefixNOT->setToolTip(
359 i18n("Check this box to negate the defined filter condition"));
360 m_prefixNOT->setWhatsThis(
361 i18n("<p>If this option is checked the defined filter condition will be negated. "
362 "This means that, for example, you can define a filter that looks for all "
363 "tracks that are not of a specific album, artist, and so on.</p>"));
364 verticalCondLay->addWidget( m_prefixNOT );
365 m_prefixNOT->setEnabled( false );
367 connect(m_prefixNOT, SIGNAL(clicked()), SLOT(assignPrefixNOT()));
369 m_mainLay->addItem( new QSpacerItem( 10, 20, QSizePolicy::Minimum, QSizePolicy::Minimum ) );
371 // you need to append at least one filter condition to specify if do
372 // an "AND" or an "OR" with the next condition if the filter is empty
373 if (m_filterText.isEmpty())
374 m_groupBox3->setEnabled( false );
376 connect( m_checkAND, SIGNAL(clicked()), SLOT(slotCheckAND()) );
377 connect( m_checkOR, SIGNAL(clicked()), SLOT(slotCheckOR()) );
379 // check "AND" condition as default
380 slotCheckAND();
382 // setup Min Max Value spin
383 setMinMaxValueSpins();
384 connect(this,SIGNAL(okClicked()),this,SLOT(slotOk()));
385 connect(this,SIGNAL(defaultClicked()),this,SLOT(slotDefault()));
386 connect(this,SIGNAL(user1Clicked()),this,SLOT(slotUser1()));
387 connect(this,SIGNAL(user2Clicked()),this,SLOT(slotUser2()));
390 EditFilterDialog::~EditFilterDialog()
392 delete m_editKeyword;
395 QString EditFilterDialog::filter() const
397 return m_filterText;
400 void EditFilterDialog::exclusiveSelectOf( int which )
402 int size = static_cast<int>( m_actionCheck.count() );
404 for ( int i = 0; i < size; i++ )
405 if ( i != which )
406 m_actionCheck[i]->setChecked( false );
407 else
408 m_actionCheck[i]->setChecked( true );
411 QString EditFilterDialog::keywordConditionString(const QString& keyword) const
413 // this member is called when there is a keyword that needs numeric attributes
414 QString result, unit;
416 if (m_vector.at(m_selectedIndex) == "size")
417 switch (m_comboUnitSize->currentIndex())
419 case 1:
420 // kbytes
421 unit = "k";
422 break;
423 case 2:
424 // mbytes
425 unit = "m";
426 break;
429 switch(m_comboCondition->currentIndex())
431 case 0:
432 // less than...
433 result = m_strPrefixNOT + keyword + ":<";
434 if (keyword == "length")
435 result += QString::number( m_spinMin1->value() * 60 + m_spinMin2->value() ) + unit;
436 else
437 result += m_spinMin1->text() + unit;
438 break;
439 case 1:
440 // greater than...
441 result = m_strPrefixNOT + keyword + ":>";
442 if (keyword == "length")
443 result += QString::number( m_spinMin1->value() * 60 + m_spinMin2->value() ) + unit;
444 else
445 result += m_spinMin1->text() + unit;
446 break;
447 case 2:
448 // equal to...
449 if (keyword == "length")
450 result = m_strPrefixNOT + "length:" + QString::number( m_spinMin1->value() * 60
451 + m_spinMin2->value() ) + unit;
452 else
454 if (m_strPrefixNOT.isEmpty())
455 result = keyword + ":>" + QString::number(m_spinMin1->value() - 1) + unit +
456 ' ' + keyword + ":<" + QString::number(m_spinMin1->value() + 1) + unit;
457 else
458 result = keyword + ":<" + QString::number(m_spinMin1->value()) + unit +
459 " OR " + keyword + ":>" + QString::number(m_spinMin1->value()) + unit;
461 break;
462 case 3:
463 // between...
464 if (keyword == "length")
466 if (m_strPrefixNOT.isEmpty())
467 result = "length:>" + QString::number( m_spinMin1->value() * 60 + m_spinMin2->value() - 1) + unit
468 + " length:<" + QString::number( m_spinMax1->value() * 60 + m_spinMax2->value() + 1) + unit;
469 else
470 result = "length:<" + QString::number( m_spinMin1->value() * 60 + m_spinMin2->value()) + unit
471 + " OR length:>" + QString::number( m_spinMax1->value() * 60 + m_spinMax2->value()) + unit;
473 else
475 if (m_strPrefixNOT.isEmpty())
476 result = keyword + ":>" + QString::number(m_spinMin1->value() - 1) + unit +
477 ' ' + keyword + ":<" + QString::number(m_spinMax1->value() + 1) + unit;
478 else
479 result = keyword + ":<" + QString::number(m_spinMin1->value() - 1) + unit +
480 " OR " + keyword + ":>" + QString::number(m_spinMax1->value() + 1) + unit;
482 break;
485 return result;
488 void EditFilterDialog::setMinMaxValueSpins()
490 // setting some spin box options and limit values
491 m_spinMin1->setValue( 0 );
492 m_spinMin1->setMinimum( 0 );
493 m_spinMin1->setMaximum( 100000000 );
495 m_spinMin2->setMinimum( 0 );
496 m_spinMin2->setMaximum( 59 );
497 m_spinMin2->hide();
499 m_spinMax1->setValue( 0 );
500 m_spinMax1->setMinimum( 0 );
501 m_spinMax1->setMaximum( 100000000 );
503 m_spinMax2->setMinimum( 0 );
504 m_spinMax2->setMaximum( 59 );
505 m_spinMax2->hide();
507 // fix tooltip
508 m_spinMin1->setToolTip( "" );
509 m_spinMin2->setToolTip( i18n("Seconds") );
511 m_spinMax1->setToolTip( "" );
512 m_spinMax2->setToolTip( i18n("Seconds") );
515 // SLOTS
516 void EditFilterDialog::selectedKeyword(int index) // SLOT
518 debug() << "you selected index " << index << ": '" << m_comboKeyword->currentText() << "'";
519 m_groupBox2->setEnabled( false );
520 m_comboUnitSize->setEnabled( false );
521 m_filesizeLabel->setEnabled( false );
522 m_prefixNOT->setEnabled( true );
524 setMinMaxValueSpins();
526 const QString key = m_vector[index];
527 if( index == 0 )
529 // Simple Search
530 m_groupBox2->setEnabled( true );
531 m_prefixNOT->setEnabled( false );
532 textWanted();
534 else if( key=="bitrate" )
536 // bitrate: set useful values for the spinboxes
537 m_spinMin1->setValue( 128 );
538 m_spinMax1->setValue( 384 );
539 valueWanted();
541 else if( key=="samplerate" )
543 // samplerate: set useful values for the spinboxes
544 m_spinMin1->setValue( 8000 );
545 m_spinMax1->setValue( 48000 );
546 valueWanted();
548 else if( key=="length" )
550 // length: set useful values for the spinboxes
551 m_spinMin2->show();
552 m_spinMax2->show();
553 m_spinMin1->setValue( 1 );
554 m_spinMax1->setValue( 5 );
555 m_spinMin1->setToolTip( i18n("Minutes") );
556 m_spinMax1->setToolTip( i18n("Minutes") );
558 // fix the maximum values to reduce spinboxes size
559 m_spinMin1->setMaximum( 240 );
560 m_spinMax1->setMaximum( 240 );
562 valueWanted();
564 else if( key=="size" || key=="filesize" )
566 // size: set useful values for the spinboxes
567 m_filesizeLabel->setEnabled( true );
568 m_comboUnitSize->setEnabled( true );
569 m_spinMin1->setValue( 1 );
570 m_spinMax1->setValue( 3 );
571 m_comboUnitSize->setCurrentIndex( 2 );
572 valueWanted();
574 else if( key=="year" )
576 // year: set useful values for the spinboxes
577 m_spinMin1->setValue( 1900 );
578 m_spinMax1->setValue( QDate::currentDate().year() );
579 valueWanted();
581 else if( key=="track" || key=="disc" || key=="discnumber" )
583 // track/disc: set useful values for the spinboxes
584 m_spinMin1->setValue( 1 );
585 m_spinMax1->setValue( 15 );
586 valueWanted();
588 else if( key=="playcount"
589 || key=="lastplayed"
590 || key=="rating"
591 || key=="score"
592 || key=="bpm" )
594 valueWanted();
596 else if( key=="label" )
597 textWanted( CollectionDB::instance()->labelList() );
598 else if( key=="album" )
599 textWanted( CollectionDB::instance()->albumList() );
600 else if( key=="artist" )
601 textWanted( CollectionDB::instance()->artistList() );
602 else if( key=="composer" )
603 textWanted( CollectionDB::instance()->composerList() );
604 else if( key=="genre" )
605 textWanted( CollectionDB::instance()->genreList() );
606 else if( key=="type" || key=="filetype" )
608 QStringList types;
609 types << "mp3" << "flac" << "ogg" << "aac" << "m4a" << "mp4" << "mp2" << "ac3"
610 << "wav" << "asf" << "wma";
611 textWanted( types );
613 else
614 textWanted();
616 // assign the correct value to the m_strPrefixNOT
617 assignPrefixNOT();
619 // assign the right index
620 m_selectedIndex = index;
623 void EditFilterDialog::minSpinChanged(int value) // SLOT
625 if (value > m_spinMax1->value())
626 m_spinMax1->setValue(value);
629 void EditFilterDialog::maxSpinChanged(int value) // SLOT
631 if (m_spinMin1->value() > value)
632 m_spinMin1->setValue(value);
635 void EditFilterDialog::textWanted() // SLOT
637 m_editKeyword->setEnabled( true );
638 m_groupBox->setEnabled( false );
640 m_editKeyword->completionObject()->clear();
643 void EditFilterDialog::textWanted( const QStringList &completion ) // SLOT
645 m_editKeyword->setEnabled( true );
646 m_groupBox->setEnabled( false );
648 m_editKeyword->completionObject()->clear();
649 m_editKeyword->completionObject()->insertItems( completion );
650 m_editKeyword->completionObject()->setIgnoreCase( true );
651 m_editKeyword->setCompletionMode( KGlobalSettings::CompletionPopup );
654 void EditFilterDialog::valueWanted() // SLOT
656 m_editKeyword->setEnabled( false );
657 m_groupBox->setEnabled( true );
660 void EditFilterDialog::chooseCondition( int condition ) // SLOT
662 if( condition == 3 ) // included between
663 chooseMinMaxValue();
664 else
665 chooseOneValue();
668 void EditFilterDialog::chooseOneValue() // SLOT
670 m_andLabel->setEnabled( false);
671 m_spinMax1->setEnabled( false );
672 m_spinMax2->setEnabled( false );
675 void EditFilterDialog::chooseMinMaxValue() // SLOT
677 m_andLabel->setEnabled( true );
678 m_spinMax1->setEnabled( true );
679 m_spinMax2->setEnabled( true );
682 void EditFilterDialog::slotCheckAll() // SLOT
684 exclusiveSelectOf( 0 );
687 void EditFilterDialog::slotCheckAtLeastOne() // SLOT
689 exclusiveSelectOf( 1 );
692 void EditFilterDialog::slotCheckExactly() // SLOT
694 exclusiveSelectOf( 2 );
697 void EditFilterDialog::slotCheckExclude() // SLOT
699 exclusiveSelectOf( 3 );
702 void EditFilterDialog::slotCheckAND() // SLOT
704 m_checkAND->setChecked( true );
705 m_checkOR->setChecked( false );
708 void EditFilterDialog::slotCheckOR() // SLOT
710 m_checkAND->setChecked( false );
711 m_checkOR->setChecked( true );
714 void EditFilterDialog::assignPrefixNOT() // SLOT
716 if (m_prefixNOT->isChecked())
717 m_strPrefixNOT = "-";
718 else
719 m_strPrefixNOT = "";
722 void EditFilterDialog::slotDefault() // SLOT
724 // now append the filter rule if not empty
725 if (m_editKeyword->text().isEmpty() && (m_selectedIndex == 0))
727 KMessageBox::sorry( 0, i18n("<p>Sorry but the filter rule cannot be set. The text field is empty. "
728 "Please type something into it and retry.</p>"), i18n("Empty Text Field"));
729 m_editKeyword->setFocus();
730 return;
732 if (!m_appended)
734 // it's the first rule
735 m_appended = true;
736 m_groupBox3->setEnabled( true );
739 m_previousFilterText = m_filterText;
740 if (!m_filterText.isEmpty())
742 m_filterText += ' ';
743 if (m_checkOR->isChecked())
744 m_filterText += "OR ";
746 QStringList list = m_editKeyword->text().split( " " );
747 const QString key = m_vector[m_selectedIndex];
748 if( m_selectedIndex == 0 )
750 // Simple Search
751 debug() << "selected text: '" << m_editKeyword->text() << "'";
752 if (m_actionCheck[0]->isChecked())
754 // all words
755 m_filterText += m_editKeyword->text();
757 else if (m_actionCheck[1]->isChecked())
759 // at least one word
760 m_filterText += *(list.begin());
761 for ( QStringList::Iterator it = ++list.begin(); it != list.end(); ++it )
762 m_filterText += " OR " + *it;
764 else if (m_actionCheck[2]->isChecked())
766 // exactly the words
767 m_filterText += "\"" + m_editKeyword->text() + "\"";
769 else if (m_actionCheck[3]->isChecked())
771 // exclude words
772 for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it )
773 m_filterText += " -" + *it;
776 else if( key=="bitrate"
777 || key=="disc" || key=="discnumber"
778 || key=="length"
779 || key=="playcount"
780 || key=="rating"
781 || key=="samplerate"
782 || key=="score"
783 || key=="filesize" || key=="size"
784 || key=="track"
785 || key=="year" )
787 m_filterText += keywordConditionString( m_vector[m_selectedIndex] );
789 else
791 m_filterText += m_vector[m_selectedIndex] + ":\"" + m_editKeyword->text() + "\"";
793 emit filterChanged( m_filterText );
795 m_editKeyword->clear();
798 void EditFilterDialog::slotUser1() // SLOT
800 m_previousFilterText = m_filterText;
801 m_filterText = "";
803 // no filter appended cause all cleared
804 m_appended = false;
805 m_groupBox3->setEnabled( false );
807 emit filterChanged( m_filterText );
810 void EditFilterDialog::slotUser2() // SLOT
812 m_filterText = m_previousFilterText;
813 if (m_filterText.isEmpty())
815 // no filter appended cause all cleared
816 m_appended = false;
817 m_groupBox3->setEnabled( false );
819 emit filterChanged( m_filterText );
822 void EditFilterDialog::slotOk() // SLOT
824 // If there's a filter typed in but unadded, add it.
825 // This makes it easier to just add one condition - you only need to press OK.
826 if ( !m_editKeyword->text().isEmpty() )
827 slotDefault();
829 // Don't let OK do anything if they haven't set any filters.
830 if (m_appended)
831 accept();
834 #include "editfilterdialog.moc"