delay a few things on startup, such as setting the visibility mode, which ensures...
[personal-kdebase.git] / apps / kfind / kftabdlg.cpp
blobd4bed65b83c1ce5e32c0616e291ac29e24be7716
1 /***********************************************************************
3 * kftabdlg.cpp
5 **********************************************************************/
6 #include "kftabdlg.h"
8 #include <QtGui/QButtonGroup>
9 #include <QtGui/QRadioButton>
10 #include <QtGui/QLabel>
11 #include <QtGui/QLayout>
12 #include <QtGui/QCheckBox>
13 #include <QtGui/QWhatsThis>
15 #include <QtGui/QComboBox>
16 #include <QtGui/QSpinBox>
17 #include <QtGui/QPushButton>
18 #include <QtGui/QApplication>
19 #include <QtGui/QDesktopWidget>
21 #include <kcalendarsystem.h>
22 #include <kglobal.h>
23 #include <kcombobox.h>
24 #include <klineedit.h>
25 #include <klocale.h>
26 #include <kmessagebox.h>
27 #include <kfiledialog.h>
28 #include <kregexpeditorinterface.h>
29 #include <kservicetypetrader.h>
30 #include <kparts/componentfactory.h>
31 #include <kstandarddirs.h>
32 #include "kquery.h"
33 // Static utility functions
34 static void save_pattern(QComboBox *, const QString &, const QString &);
36 #define SPECIAL_TYPES 7
38 struct LessMimeType_ByComment
40 bool operator()(const KMimeType::Ptr& lhs, const KMimeType::Ptr& rhs) const
42 return lhs->comment() < rhs->comment();
46 KfindTabWidget::KfindTabWidget(QWidget *parent)
47 : QTabWidget( parent ), regExpDialog(0)
49 // This validator will be used for all numeric edit fields
50 //KDigitValidator *digitV = new KDigitValidator(this);
52 // ************ Page One ************
54 pages[0] = new QWidget;
55 pages[0]->setObjectName( "page1" );
57 nameBox = new KComboBox(pages[0]);
58 nameBox->setEditable( true );
59 nameBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); // allow smaller than widest entry
60 QLabel * namedL = new QLabel(i18n("&Named:"), pages[0]);
61 namedL->setBuddy( nameBox );
62 namedL->setObjectName( "named" );
63 namedL->setToolTip( i18n("You can use wildcard matching and \";\" for separating multiple names") );
64 dirBox = new KComboBox(pages[0]);
65 dirBox->setEditable( true );
66 dirBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); // allow smaller than widest entry
67 QLabel * lookinL = new QLabel(i18n("Look &in:"), pages[0]);
68 lookinL->setBuddy( dirBox );
69 lookinL->setObjectName( "lookin" );
70 subdirsCb = new QCheckBox(i18n("Include &subfolders"), pages[0]);
71 caseSensCb = new QCheckBox(i18n("Case s&ensitive search"), pages[0]);
72 browseB = new QPushButton(i18n("&Browse..."), pages[0]);
73 useLocateCb = new QCheckBox(i18n("&Use files index"), pages[0]);
75 // Setup
77 subdirsCb->setChecked(true);
78 caseSensCb->setChecked(false);
79 useLocateCb->setChecked(false);
80 if(KStandardDirs::findExe("locate").isEmpty())
81 useLocateCb->setEnabled(false);
83 nameBox->setDuplicatesEnabled(false);
84 nameBox->setFocus();
85 dirBox->setDuplicatesEnabled(false);
87 nameBox->setInsertPolicy(QComboBox::AtTop);
88 dirBox->setInsertPolicy(QComboBox::AtTop);
90 const QString nameWhatsThis
91 = i18n("<qt>Enter the filename you are looking for. <br />"
92 "Alternatives may be separated by a semicolon \";\".<br />"
93 "<br />"
94 "The filename may contain the following special characters:"
95 "<ul>"
96 "<li><b>?</b> matches any single character</li>"
97 "<li><b>*</b> matches zero or more of any characters</li>"
98 "<li><b>[...]</b> matches any of the characters between the braces</li>"
99 "</ul>"
100 "<br />"
101 "Example searches:"
102 "<ul>"
103 "<li><b>*.kwd;*.txt</b> finds all files ending with .kwd or .txt</li>"
104 "<li><b>go[dt]</b> finds god and got</li>"
105 "<li><b>Hel?o</b> finds all files that start with \"Hel\" and end with \"o\", "
106 "having one character in between</li>"
107 "<li><b>My Document.kwd</b> finds a file of exactly that name</li>"
108 "</ul></qt>");
109 nameBox->setWhatsThis(nameWhatsThis);
110 namedL->setWhatsThis(nameWhatsThis);
111 const QString whatsfileindex
112 = i18n("<qt>This lets you use the files' index created by the <i>slocate</i> "
113 "package to speed-up the search; remember to update the index from time to time "
114 "(using <i>updatedb</i>)."
115 "</qt>");
116 useLocateCb->setWhatsThis(whatsfileindex);
118 // Layout
120 QGridLayout *grid = new QGridLayout( pages[0] );
121 grid->setMargin( KDialog::marginHint() );
122 grid->setSpacing( KDialog::spacingHint() );
123 QBoxLayout *subgrid = new QVBoxLayout();
124 grid->addWidget( namedL, 0, 0 );
125 grid->addWidget( nameBox, 0, 1, 1, 3 );
126 grid->addWidget( lookinL, 1, 0 );
127 grid->addWidget( dirBox, 1, 1 );
128 grid->addWidget( browseB, 1, 2);
129 grid->setColumnStretch(1,1);
130 grid->addLayout( subgrid, 2, 1, 1, 2 );
131 subgrid->addWidget( subdirsCb );
132 subgrid->addWidget( caseSensCb);
133 subgrid->addWidget( useLocateCb );
134 subgrid->addStretch(1);
136 // Signals
138 connect( browseB, SIGNAL(clicked()),
139 this, SLOT(getDirectory()) );
141 connect( nameBox, SIGNAL(activated(int)),
142 this, SIGNAL(startSearch()));
144 // ************ Page Two
146 pages[1] = new QWidget;
147 pages[1]->setObjectName( "page2" );
149 findCreated = new QCheckBox(i18n("Find all files created or &modified:"), pages[1]);
150 bg = new QButtonGroup();
151 rb[0] = new QRadioButton(i18n("&between"), pages[1] );
152 rb[1] = new QRadioButton(i18n("&during the previous"), pages[1] );
153 andL = new QLabel(i18n("and"), pages[1]);
154 andL->setObjectName( "and" );
155 betweenType = new KComboBox( pages[1] );
156 betweenType->setEditable( false );
157 betweenType->setObjectName( "comboBetweenType" );
158 betweenType->addItem(i18n("minute(s)"));
159 betweenType->addItem(i18n("hour(s)"));
160 betweenType->addItem(i18n("day(s)"));
161 betweenType->addItem(i18n("month(s)"));
162 betweenType->addItem(i18n("year(s)"));
163 betweenType->setCurrentIndex(1);
166 QDate dt = KGlobal::locale()->calendar()->addYears(QDate::currentDate(), -1);
168 fromDate = new KDateCombo(dt, pages[1] );
169 fromDate->setObjectName( "fromDate" );
170 toDate = new KDateCombo(pages[1] );
171 toDate->setObjectName( "toDate" );
172 timeBox = new QSpinBox( pages[1] );
173 timeBox->setRange( 1, 60 );
174 timeBox->setSingleStep( 1 );
175 timeBox->setObjectName( "timeBox" );
177 sizeBox =new KComboBox( pages[1] );
178 sizeBox->setEditable( false );
179 sizeBox->setObjectName( "sizeBox" );
180 QLabel * sizeL =new QLabel(i18n("File &size is:"), pages[1]);
181 sizeL->setBuddy( sizeBox );
182 sizeEdit=new QSpinBox(pages[1] );
183 sizeEdit->setRange( 0, INT_MAX );
184 sizeEdit->setSingleStep( 1 );
185 sizeEdit->setObjectName( "sizeEdit" );
186 sizeEdit->setValue(1);
187 sizeUnitBox =new KComboBox( pages[1] );
188 sizeUnitBox->setEditable( false );
189 sizeUnitBox->setObjectName( "sizeUnitBox" );
191 m_usernameBox = new KComboBox( pages[1] );
192 m_usernameBox->setEditable( true );
193 m_usernameBox->setObjectName( "m_combo1");
194 QLabel *usernameLabel= new QLabel(i18n("Files owned by &user:"),pages[1]);
195 usernameLabel->setBuddy( m_usernameBox );
196 m_groupBox = new KComboBox( pages[1] );
197 m_groupBox->setEditable( true );
198 m_groupBox->setObjectName( "m_combo2" );
199 QLabel *groupLabel= new QLabel(i18n("Owned by &group:"),pages[1]);
200 groupLabel->setBuddy( m_groupBox );
202 sizeBox ->addItem( i18n("(none)") );
203 sizeBox ->addItem( i18n("At Least") );
204 sizeBox ->addItem( i18n("At Most") );
205 sizeBox ->addItem( i18n("Equal To") );
207 sizeUnitBox ->addItem( i18n("Bytes") );
208 sizeUnitBox ->addItem( i18n("KiB") );
209 sizeUnitBox ->addItem( i18n("MiB") );
210 sizeUnitBox ->addItem( i18n("GiB") );
211 sizeUnitBox ->setCurrentIndex(1);
213 int tmp = sizeEdit->fontMetrics().width(" 000000000 ");
214 sizeEdit->setMinimumSize(tmp, sizeEdit->sizeHint().height());
216 m_usernameBox->setDuplicatesEnabled(false);
217 m_groupBox->setDuplicatesEnabled(false);
218 m_usernameBox->setInsertPolicy(QComboBox::AtTop);
219 m_groupBox->setInsertPolicy(QComboBox::AtTop);
222 // Setup
223 rb[0]->setChecked(true);
224 bg->addButton( rb[0] );
225 bg->addButton( rb[1] );
227 // Layout
229 QGridLayout *grid1 = new QGridLayout( pages[1] );
230 grid1->setMargin( KDialog::marginHint() );
231 grid1->setSpacing( KDialog::spacingHint() );
233 grid1->addWidget(findCreated, 0, 0, 1, 3 );
234 grid1->addItem( new QSpacerItem(KDialog::spacingHint(), 0), 0, 0 );
236 grid1->addWidget(rb[0], 1, 1 );
237 grid1->addWidget(fromDate, 1, 2 );
238 grid1->addWidget(andL, 1, 3, Qt::AlignHCenter );
239 grid1->addWidget(toDate, 1, 4 );
241 grid1->addWidget(rb[1], 2, 1 );
242 grid1->addWidget(timeBox, 2, 2, 1, 2);
243 grid1->addWidget(betweenType, 2, 4 );
245 grid1->addWidget(sizeL,3,0,1,2);
246 grid1->addWidget(sizeBox,3,2);
247 grid1->addWidget(sizeEdit,3,3);
248 grid1->addWidget(sizeUnitBox,3,4);
250 grid1->addWidget(usernameLabel,4,0,1,2);
251 grid1->addWidget(m_usernameBox,4,2);
252 grid1->addWidget(groupLabel,4,3);
253 grid1->addWidget(m_groupBox,4,4);
255 for (int c=1; c<=4; c++)
256 grid1->setColumnStretch(c,1);
258 grid1->setRowStretch(6,1);
260 // Connect
261 connect( findCreated, SIGNAL(toggled(bool)), SLOT(fixLayout()) );
262 connect( bg, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(fixLayout()) );
263 connect( sizeBox, SIGNAL(activated(int)), this, SLOT(slotSizeBoxChanged(int)));
266 // ************ Page Three
268 pages[2] = new QWidget;
269 pages[2]->setObjectName( "page3" );
271 typeBox =new KComboBox( pages[2] );
272 typeBox->setEditable( false );
273 typeBox->setObjectName( "typeBox" );
274 typeBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); // allow smaller than widest entry
275 QLabel * typeL =new QLabel( i18n("File &type:"), pages[2] );
276 typeL->setBuddy( typeBox );
277 textEdit=new KLineEdit(pages[2]);
278 textEdit->setClearButtonShown(true);
279 textEdit->setObjectName( "textEdit" );
280 QLabel * textL =new QLabel(i18n("C&ontaining text:"), pages[2]);
281 textL->setBuddy( textEdit );
283 connect( textEdit, SIGNAL(returnPressed(const QString &)), SIGNAL( startSearch()));
285 const QString containingtext
286 = i18n("<qt>If specified, only files that contain this text"
287 " are found. Note that not all file types from the list"
288 " above are supported. Please refer to the documentation"
289 " for a list of supported file types."
290 "</qt>");
291 textEdit->setToolTip(containingtext);
292 textL->setWhatsThis(containingtext);
294 caseContextCb =new QCheckBox(i18n("Case s&ensitive"), pages[2]);
295 binaryContextCb =new QCheckBox(i18n("Include &binary files"), pages[2]);
296 regexpContentCb =new QCheckBox(i18n("Regular e&xpression"), pages[2]);
298 const QString binaryTooltip
299 = i18n("<qt>This lets you search in any type of file, "
300 "even those that usually do not contain text (for example "
301 "program files and images).</qt>");
302 binaryContextCb->setToolTip(binaryTooltip);
304 QPushButton* editRegExp = 0;
305 if ( !KServiceTypeTrader::self()->query("KRegExpEditor/KRegExpEditor").isEmpty() ) {
306 // The editor is available, so lets use it.
307 editRegExp = new QPushButton(i18n("&Edit..."), pages[2]);
308 editRegExp->setObjectName( "editRegExp" );
311 metainfokeyEdit=new KLineEdit(pages[2]);
312 metainfoEdit=new KLineEdit(pages[2]);
313 QLabel * textMetaInfo = new QLabel(i18n("fo&r:"), pages[2]);
314 textMetaInfo->setBuddy( metainfoEdit );
315 QLabel * textMetaKey = new QLabel(i18n("Search &metainfo sections:"), pages[2]);
316 textMetaKey->setBuddy( metainfokeyEdit );
318 // Setup
319 typeBox->addItem(i18n("All Files & Folders"));
320 typeBox->addItem(i18n("Files"));
321 typeBox->addItem(i18n("Folders"));
322 typeBox->addItem(i18n("Symbolic Links"));
323 typeBox->addItem(i18n("Special Files (Sockets, Device Files, ...)"));
324 typeBox->addItem(i18n("Executable Files"));
325 typeBox->addItem(i18n("SUID Executable Files"));
326 typeBox->addItem(i18n("All Images"));
327 typeBox->addItem(i18n("All Video"));
328 typeBox->addItem(i18n("All Sounds"));
330 initMimeTypes();
331 initSpecialMimeTypes();
333 for ( KMimeType::List::ConstIterator it = m_types.constBegin();
334 it != m_types.constEnd(); ++it )
336 KMimeType::Ptr typ = *it;
337 // TODO: needs to move to thread (increases startup time to bizzare amount)
338 // and replaced with a better concept 16x16 icons don't cut the cheese
339 // typeBox->addItem(KIconLoader::global()->loadMimeTypeIcon( typ->iconName(), KIconLoader::Small ), typ->comment());
340 typeBox->addItem(typ->comment());
343 if ( editRegExp ) {
344 // The editor was available, so lets use it.
345 connect( regexpContentCb, SIGNAL(toggled(bool) ), editRegExp, SLOT(setEnabled(bool)) );
346 editRegExp->setEnabled(false);
347 connect( editRegExp, SIGNAL(clicked()), this, SLOT( slotEditRegExp() ) );
349 else
350 regexpContentCb->hide();
352 // Layout
353 tmp = sizeEdit->fontMetrics().width(" 00000 ");
354 sizeEdit->setMinimumSize(tmp, sizeEdit->sizeHint().height());
356 QGridLayout *grid2 = new QGridLayout( pages[2] );
357 grid2->setMargin( KDialog::marginHint() );
358 grid2->setSpacing( KDialog::spacingHint() );
359 grid2->addWidget( typeL, 0, 0 );
360 grid2->addWidget( textL, 1, 0 );
361 grid2->addWidget( typeBox, 0, 1, 1, 3 );
362 grid2->addWidget( textEdit, 1, 1, 1, 3 );
363 grid2->addWidget( regexpContentCb, 2, 2);
364 grid2->addWidget( caseContextCb, 2, 1 );
365 grid2->addWidget( binaryContextCb, 3, 1);
367 grid2->addWidget( textMetaKey, 4, 0 );
368 grid2->addWidget( metainfokeyEdit, 4, 1 );
369 grid2->addWidget( textMetaInfo, 4, 2, Qt::AlignHCenter );
370 grid2->addWidget( metainfoEdit, 4, 3 );
372 metainfokeyEdit->setText("*");
374 if ( editRegExp ) {
375 // The editor was available, so lets use it.
376 grid2->addWidget( editRegExp, 2, 3 );
379 addTab( pages[0], i18n("Name/&Location") );
380 addTab( pages[2], i18n("C&ontents") );
381 addTab( pages[1], i18n("&Properties") );
384 // Setup
385 const QString whatsmetainfo
386 = i18n("<qt>Search within files' specific comments/metainfo<br />"
387 "These are some examples:<br />"
388 "<ul>"
389 "<li><b>Audio files (mp3...)</b> Search in id3 tag for a title, an album</li>"
390 "<li><b>Images (png...)</b> Search images with a special resolution, comment...</li>"
391 "</ul>"
392 "</qt>");
393 const QString whatsmetainfokey
394 = i18n("<qt>If specified, search only in this field<br />"
395 "<ul>"
396 "<li><b>Audio files (mp3...)</b> This can be Title, Album...</li>"
397 "<li><b>Images (png...)</b> Search only in Resolution, Bitdepth...</li>"
398 "</ul>"
399 "</qt>");
400 textMetaInfo->setWhatsThis(whatsmetainfo);
401 metainfoEdit->setToolTip(whatsmetainfo);
402 textMetaKey->setWhatsThis(whatsmetainfokey);
403 metainfokeyEdit->setToolTip(whatsmetainfokey);
406 fixLayout();
407 loadHistory();
410 KfindTabWidget::~KfindTabWidget()
412 delete pages[0];
413 delete pages[1];
414 delete pages[2];
415 delete bg;
418 void KfindTabWidget::setURL( const KUrl & url )
420 KConfigGroup conf(KGlobal::config(), "History");
421 m_url = url;
422 QStringList sl = conf.readPathEntry("Directories", QStringList());
423 dirBox->clear(); // make sure there is no old Stuff in there
425 if(!sl.isEmpty()) {
426 dirBox->addItems(sl);
427 // If the _searchPath already exists in the list we do not
428 // want to add it again
429 int indx = sl.indexOf(m_url.prettyUrl());
430 if(indx == -1) {
431 dirBox->insertItem(0, m_url.prettyUrl()); // make it the first one
432 dirBox->setCurrentIndex(0);
434 else
435 dirBox->setCurrentIndex(indx);
437 else {
438 QDir m_dir("/lib");
439 dirBox ->insertItem( 0, m_url.prettyUrl() );
440 dirBox ->addItem( "file:" + QDir::homePath() );
441 dirBox ->addItem( "file:/" );
442 dirBox ->addItem( "file:/usr" );
443 if (m_dir.exists())
444 dirBox ->addItem( "file:/lib" );
445 dirBox ->addItem( "file:/home" );
446 dirBox ->addItem( "file:/etc" );
447 dirBox ->addItem( "file:/var" );
448 dirBox ->addItem( "file:/mnt" );
449 dirBox->setCurrentIndex(0);
453 void KfindTabWidget::initMimeTypes()
455 KMimeType::List sortedList;
456 foreach ( KMimeType::Ptr type, KMimeType::allMimeTypes() )
458 if ( (!type->comment().isEmpty())
459 && (!type->name().startsWith("kdedevice/"))
460 && (!type->name().startsWith("all/")) )
461 sortedList.append(type);
463 qSort( sortedList.begin(), sortedList.end(), LessMimeType_ByComment() );
464 m_types += sortedList;
467 void KfindTabWidget::initSpecialMimeTypes()
469 const KMimeType::List tmp = KMimeType::allMimeTypes();
471 for ( KMimeType::List::ConstIterator it = tmp.constBegin(); it != tmp.constEnd(); ++it )
473 const KMimeType* type = (*it).data();
475 if(!type->comment().isEmpty()) {
476 if(type->name().startsWith("image/"))
477 m_ImageTypes.append(type->name());
478 else if(type->name().startsWith("video/"))
479 m_VideoTypes.append(type->name());
480 else if(type->name().startsWith("audio/"))
481 m_AudioTypes.append(type->name());
486 void KfindTabWidget::saveHistory()
488 save_pattern(nameBox, "History", "Patterns");
489 save_pattern(dirBox, "History", "Directories");
492 void KfindTabWidget::loadHistory()
494 // Load pattern history
495 KConfigGroup conf(KGlobal::config(), "History");
496 QStringList sl = conf.readEntry("Patterns", QStringList());
497 if(!sl.isEmpty())
498 nameBox->addItems(sl);
499 else
500 nameBox->addItem("*");
502 sl = conf.readPathEntry("Directories", QStringList());
503 if(!sl.isEmpty()) {
504 dirBox->addItems(sl);
505 // If the _searchPath already exists in the list we do not
506 // want to add it again
507 int indx = sl.indexOf(m_url.prettyUrl());
508 if(indx == -1) {
509 dirBox->insertItem(0, m_url.prettyUrl()); // make it the first one
510 dirBox->setCurrentIndex(0);
512 else
513 dirBox->setCurrentIndex(indx);
515 else {
516 QDir m_dir("/lib");
517 dirBox ->insertItem( 0, m_url.prettyUrl() );
518 dirBox ->addItem( "file:" + QDir::homePath() );
519 dirBox ->addItem( "file:/" );
520 dirBox ->addItem( "file:/usr" );
521 if (m_dir.exists())
522 dirBox ->addItem( "file:/lib" );
523 dirBox ->addItem( "file:/home" );
524 dirBox ->addItem( "file:/etc" );
525 dirBox ->addItem( "file:/var" );
526 dirBox ->addItem( "file:/mnt" );
527 dirBox ->setCurrentIndex(0);
531 void KfindTabWidget::slotEditRegExp()
533 if ( ! regExpDialog )
534 regExpDialog = KServiceTypeTrader::createInstanceFromQuery<QDialog>( "KRegExpEditor/KRegExpEditor", QString(), this );
536 KRegExpEditorInterface *iface = qobject_cast<KRegExpEditorInterface *>( regExpDialog );
537 if ( !iface )
538 return;
540 iface->setRegExp( textEdit->text() );
541 bool ok = regExpDialog->exec();
542 if ( ok )
543 textEdit->setText( iface->regExp() );
546 void KfindTabWidget::setFocus()
548 nameBox->setFocus();
549 nameBox->lineEdit()->selectAll();
552 void KfindTabWidget::slotSizeBoxChanged(int index)
554 sizeEdit->setEnabled((bool)(index != 0));
555 sizeUnitBox->setEnabled((bool)(index != 0));
558 void KfindTabWidget::setDefaults()
560 QDate dt = KGlobal::locale()->calendar()->addYears(QDate::currentDate(), -1);
562 fromDate ->setDate(dt);
563 toDate ->setDate(QDate::currentDate());
565 timeBox->setValue(1);
566 betweenType->setCurrentIndex(1);
568 typeBox ->setCurrentIndex(0);
569 sizeBox ->setCurrentIndex(0);
570 sizeUnitBox ->setCurrentIndex(1);
571 sizeEdit->setValue(1);
575 Checks if dates are correct and popups a error box
576 if they are not.
578 bool KfindTabWidget::isDateValid()
580 // All files
581 if ( !findCreated->isChecked() ) return true;
583 if (rb[1]->isChecked())
585 if (timeBox->value() > 0 ) return true;
587 KMessageBox::sorry(this, i18n("Unable to search within a period which is less than a minute."));
588 return false;
591 // If we can not parse either of the dates or
592 // "from" date is bigger than "to" date return false.
593 QDate hi1, hi2;
595 QString str;
596 if ( ! fromDate->getDate(&hi1).isValid() ||
597 ! toDate->getDate(&hi2).isValid() )
598 str = i18n("The date is not valid.");
599 else if ( hi1 > hi2 )
600 str = i18n("Invalid date range.");
601 else if ( QDate::currentDate() < hi1 )
602 str = i18n("Unable to search dates in the future.");
604 if (!str.isNull()) {
605 KMessageBox::sorry(0, str);
606 return false;
608 return true;
611 void KfindTabWidget::setQuery(KQuery *query)
613 KIO::filesize_t size;
614 KIO::filesize_t sizeunit;
615 bool itemAlreadyContained(false);
616 // only start if we have valid dates
617 if (!isDateValid()) return;
619 query->setPath(KUrl(dirBox->currentText().trimmed()));
621 for (int idx=0; idx<dirBox->count(); idx++)
622 if (dirBox->itemText(idx)==dirBox->currentText())
623 itemAlreadyContained=true;
625 if (!itemAlreadyContained)
626 dirBox->addItem(dirBox->currentText().trimmed(),0);
628 QString regex = nameBox->currentText().isEmpty() ? "*" : nameBox->currentText();
629 query->setRegExp(regex, caseSensCb->isChecked());
630 itemAlreadyContained=false;
631 for (int idx=0; idx<nameBox->count(); idx++)
632 if (nameBox->itemText(idx)==nameBox->currentText())
633 itemAlreadyContained=true;
635 if (!itemAlreadyContained)
636 nameBox->addItem(nameBox->currentText(),0);
638 query->setRecursive(subdirsCb->isChecked());
640 switch (sizeUnitBox->currentIndex())
642 case 0:
643 sizeunit = 1; //one byte
644 break;
645 case 2:
646 sizeunit = 1048576; //1Mi
647 break;
648 case 3:
649 sizeunit = 1073741824; //1Gi
650 break;
651 case 1: // fall to default case
652 default:
653 sizeunit=1024; //1Ki
654 break;
656 size = sizeEdit->value() * sizeunit;
658 // TODO: troeder: do we need this check since it is very unlikely
659 // to exceed ULLONG_MAX with INT_MAX * 1024^3.
660 // Or is there an arch where this can happen?
661 #if 0
662 if (size < 0) // overflow
664 if (KMessageBox::warningYesNo(this, i18n("Size is too big. Set maximum size value?"), i18n("Error"),i18n("Set"),i18n("Do Not Set"))
665 == KMessageBox::Yes)
667 sizeEdit->setValue(INT_MAX);
668 sizeUnitBox->setCurrentIndex(0);
669 size = INT_MAX;
671 else
672 return;
674 #endif
676 // set range mode and size value
677 query->setSizeRange(sizeBox->currentIndex(),size,0);
679 // dates
680 QDateTime epoch;
681 epoch.setTime_t(0);
683 // Add date predicate
684 if (findCreated->isChecked()) { // Modified
685 if (rb[0]->isChecked()) { // Between dates
686 QDate q1, q2;
687 fromDate->getDate(&q1);
688 toDate->getDate(&q2);
690 // do not generate negative numbers .. find doesn't handle that
691 time_t time1 = epoch.secsTo(QDateTime(q1));
692 time_t time2 = epoch.secsTo(QDateTime(q2.addDays(1))) - 1; // Include the last day
694 query->setTimeRange(time1, time2);
696 else
698 time_t cur = time(NULL);
699 time_t minutes = cur;
701 switch (betweenType->currentIndex())
703 case 0: // minutes
704 minutes = timeBox->value();
705 break;
706 case 1: // hours
707 minutes = 60 * timeBox->value();
708 break;
709 case 2: // days
710 minutes = 60 * 24 * timeBox->value();
711 break;
712 case 3: // months
713 minutes = 60 * 24 * (time_t)(timeBox->value() * 30.41667);
714 break;
715 case 4: // years
716 minutes = 12 * 60 * 24 * (time_t)(timeBox->value() * 30.41667);
717 break;
720 query->setTimeRange(cur - minutes * 60, 0);
723 else
724 query->setTimeRange(0, 0);
726 query->setUsername( m_usernameBox->currentText() );
727 query->setGroupname( m_groupBox->currentText() );
729 query->setFileType(typeBox->currentIndex());
731 int id = typeBox->currentIndex()-10;
733 if ((id >= -3) && (id < (int) m_types.count()))
735 switch(id)
737 case -3:
738 query->setMimeType( m_ImageTypes );
739 break;
740 case -2:
741 query->setMimeType( m_VideoTypes );
742 break;
743 case -1:
744 query->setMimeType( m_AudioTypes );
745 break;
746 default:
747 query->setMimeType( QStringList() += m_types[id]->name() );
750 else
752 query->setMimeType( QStringList() );
755 //Metainfo
756 query->setMetaInfo(metainfoEdit->text(), metainfokeyEdit->text());
758 //Use locate to speed-up search ?
759 query->setUseFileIndex(useLocateCb->isChecked());
761 query->setContext(textEdit->text(), caseContextCb->isChecked(),
762 binaryContextCb->isChecked(), regexpContentCb->isChecked());
765 QString KfindTabWidget::date2String(const QDate & date) {
766 return(KGlobal::locale()->formatDate(date, KLocale::ShortDate));
769 QDate &KfindTabWidget::string2Date(const QString & str, QDate *qd) {
770 return *qd = KGlobal::locale()->readDate(str);
773 void KfindTabWidget::getDirectory()
775 QString result =
776 KFileDialog::getExistingDirectory( dirBox->currentText().trimmed(),
777 this );
779 if (!result.isEmpty())
781 for (int i = 0; i < dirBox->count(); i++)
782 if (result == dirBox->itemText(i)) {
783 dirBox->setCurrentIndex(i);
784 return;
786 dirBox->insertItem(0, result);
787 dirBox->setCurrentIndex(0);
791 void KfindTabWidget::beginSearch()
793 /// dirlister->openUrl(KUrl(dirBox->currentText().trimmed()));
795 saveHistory();
796 setEnabled( false );
799 void KfindTabWidget::endSearch()
801 setEnabled( true );
805 Disables/enables all edit fields depending on their
806 respective check buttons.
808 void KfindTabWidget::fixLayout()
810 int i;
811 // If "All files" is checked - disable all edits
812 // and second radio group on page two
814 if(! findCreated->isChecked()) {
815 fromDate->setEnabled(false);
816 toDate->setEnabled(false);
817 andL->setEnabled(false);
818 timeBox->setEnabled(false);
819 for(i=0; i<2; i++)
820 rb[i]->setEnabled(false);
821 betweenType->setEnabled(false);
823 else {
824 for(i=0; i<2; i++)
825 rb[i]->setEnabled(true);
827 fromDate->setEnabled(rb[0]->isChecked());
828 toDate->setEnabled(rb[0]->isChecked());
829 andL->setEnabled(rb[0]->isEnabled());
830 timeBox->setEnabled(rb[1]->isChecked());
831 betweenType->setEnabled(rb[1]->isChecked());
834 // Size box on page three
835 sizeEdit->setEnabled(sizeBox->currentIndex() != 0);
836 sizeUnitBox->setEnabled(sizeBox->currentIndex() != 0);
839 bool KfindTabWidget::isSearchRecursive()
841 return subdirsCb->isChecked();
846 Digit validator. Allows only digits to be typed.
848 KDigitValidator::KDigitValidator( QWidget * parent )
849 : QValidator( parent )
851 r = new QRegExp("^[0-9]*$");
854 KDigitValidator::~KDigitValidator()
856 delete r;
859 QValidator::State KDigitValidator::validate( QString & input, int & ) const
861 if (r->indexIn(input) < 0) {
862 // Beep on user if he enters non-digit
863 QApplication::beep();
864 return QValidator::Invalid;
866 else
867 return QValidator::Acceptable;
870 //*******************************************************
871 // Static utility functions
872 //*******************************************************
873 static void save_pattern(QComboBox *obj,
874 const QString & group, const QString & entry)
876 // QComboBox allows insertion of items more than specified by
877 // maxCount() (QT bug?). This API call will truncate list if needed.
878 obj->setMaxCount(15);
880 // make sure the current item is saved first so it will be the
881 // default when started next time
882 QStringList sl;
883 QString cur = obj->itemText(obj->currentIndex());
884 sl.append(cur);
885 for (int i = 0; i < obj->count(); i++) {
886 if( cur != obj->itemText(i) ) {
887 sl.append(obj->itemText(i));
891 KConfigGroup conf(KGlobal::config(), group);
892 conf.writePathEntry(entry, sl);
895 QSize KfindTabWidget::sizeHint() const
897 // #44662: avoid a huge default size when the comboboxes have very large items
898 // Like in minicli, we changed the combobox size policy so that they can resize down,
899 // and then we simply provide a reasonable size hint for the whole window, depending
900 // on the screen width.
901 QSize sz = QTabWidget::sizeHint();
902 KfindTabWidget* me = const_cast<KfindTabWidget*>( this );
903 const int screenWidth = qApp->desktop()->screenGeometry(me).width();
904 if ( sz.width() > screenWidth / 2 )
905 sz.setWidth( screenWidth / 2 );
906 return sz;
909 #include "kftabdlg.moc"