dolphin/kfind/kftabdlg.cpp
Sebastian Sauer e194f67ae1 * make pressing return in dirBox do startSearch() too (same as with nameBox and containingText)
* proper redirect the tabwidget's startSearch with the dialogs startSearch. This fixes the before unused connect(nameBox,SIGNAL(activated(int)) which got removed and makes using user3 not needed any longer cause we are handling returnPressed() direct now (same like it was done at containingText).


svn path=/trunk/KDE/kdebase/apps/; revision=1196288
2010-11-12 22:55:58 +00:00

966 lines
31 KiB
C++

/*******************************************************************
* kftabdlg.cpp
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************/
#include "kftabdlg.h"
#include <QtGui/QButtonGroup>
#include <QtGui/QRadioButton>
#include <QtGui/QLabel>
#include <QtGui/QLayout>
#include <QtGui/QCheckBox>
#include <QtGui/QWhatsThis>
#include <QtGui/QPushButton>
#include <QtGui/QApplication>
#include <QtGui/QDesktopWidget>
#include <kcalendarsystem.h>
#include <kglobal.h>
#include <kcombobox.h>
#include <kurlcombobox.h>
#include <kurlcompletion.h>
#include <klineedit.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <KNumInput>
#include <kfiledialog.h>
#include <kregexpeditorinterface.h>
#include <kservicetypetrader.h>
#include <kparts/componentfactory.h>
#include <kstandarddirs.h>
#include "kdatecombo.h"
#include "kquery.h"
// Static utility functions
static void save_pattern(KComboBox *, const QString &, const QString &);
#define SPECIAL_TYPES 7
struct LessMimeType_ByComment
{
bool operator()(const KMimeType::Ptr& lhs, const KMimeType::Ptr& rhs) const
{
return lhs->comment() < rhs->comment();
}
};
KfindTabWidget::KfindTabWidget(QWidget *parent)
: KTabWidget( parent ), regExpDialog(0)
{
// This validator will be used for all numeric edit fields
//KDigitValidator *digitV = new KDigitValidator(this);
// ************ Page One ************
pages[0] = new QWidget;
pages[0]->setObjectName( QLatin1String( "page1" ) );
nameBox = new KComboBox(pages[0]);
nameBox->setEditable( true );
nameBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); // allow smaller than widest entry
QLabel * namedL = new QLabel(i18nc("this is the label for the name textfield","&Named:"), pages[0]);
namedL->setBuddy( nameBox );
namedL->setObjectName( QLatin1String( "named" ) );
namedL->setToolTip( i18n("You can use wildcard matching and \";\" for separating multiple names") );
dirBox = new KUrlComboBox(KUrlComboBox::Directories, pages[0]);
dirBox->setEditable( true );
dirBox->setCompletionObject(new KUrlCompletion(KUrlCompletion::DirCompletion));
dirBox->setAutoDeleteCompletionObject(true);
dirBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); // allow smaller than widest entry
QLabel * lookinL = new QLabel(i18n("Look &in:"), pages[0]);
lookinL->setBuddy( dirBox );
lookinL->setObjectName( QLatin1String( "lookin" ) );
subdirsCb = new QCheckBox(i18n("Include &subfolders"), pages[0]);
caseSensCb = new QCheckBox(i18n("Case s&ensitive search"), pages[0]);
browseB = new QPushButton(i18n("&Browse..."), pages[0]);
useLocateCb = new QCheckBox(i18n("&Use files index"), pages[0]);
hiddenFilesCb = new QCheckBox(i18n("Show &hidden files"), pages[0]);
// Setup
subdirsCb->setChecked(true);
caseSensCb->setChecked(false);
useLocateCb->setChecked(false);
hiddenFilesCb->setChecked(false);
if(KStandardDirs::findExe("locate").isEmpty())
useLocateCb->setEnabled(false);
nameBox->setDuplicatesEnabled(false);
nameBox->setFocus();
dirBox->setDuplicatesEnabled(false);
nameBox->setInsertPolicy(QComboBox::InsertAtTop);
dirBox->setInsertPolicy(QComboBox::InsertAtTop);
const QString nameWhatsThis
= i18n("<qt>Enter the filename you are looking for. <br />"
"Alternatives may be separated by a semicolon \";\".<br />"
"<br />"
"The filename may contain the following special characters:"
"<ul>"
"<li><b>?</b> matches any single character</li>"
"<li><b>*</b> matches zero or more of any characters</li>"
"<li><b>[...]</b> matches any of the characters between the braces</li>"
"</ul>"
"<br />"
"Example searches:"
"<ul>"
"<li><b>*.kwd;*.txt</b> finds all files ending with .kwd or .txt</li>"
"<li><b>go[dt]</b> finds god and got</li>"
"<li><b>Hel?o</b> finds all files that start with \"Hel\" and end with \"o\", "
"having one character in between</li>"
"<li><b>My Document.kwd</b> finds a file of exactly that name</li>"
"</ul></qt>");
nameBox->setWhatsThis(nameWhatsThis);
namedL->setWhatsThis(nameWhatsThis);
const QString whatsfileindex
= i18n("<qt>This lets you use the files' index created by the <i>slocate</i> "
"package to speed-up the search; remember to update the index from time to time "
"(using <i>updatedb</i>)."
"</qt>");
useLocateCb->setWhatsThis(whatsfileindex);
// Layout
QGridLayout *grid = new QGridLayout( pages[0] );
grid->setMargin( KDialog::marginHint() );
grid->setSpacing( KDialog::spacingHint() );
QVBoxLayout *subgrid = new QVBoxLayout();
grid->addWidget( namedL, 0, 0 );
grid->addWidget( nameBox, 0, 1, 1, 3 );
grid->addWidget( lookinL, 1, 0 );
grid->addWidget( dirBox, 1, 1 );
grid->addWidget( browseB, 1, 2);
grid->setColumnStretch(1,1);
grid->addLayout( subgrid, 2, 1, 1, 2 );
QHBoxLayout * layoutOne = new QHBoxLayout();
layoutOne->addWidget( subdirsCb );
layoutOne->addWidget( hiddenFilesCb );
QHBoxLayout * layoutTwo = new QHBoxLayout();
layoutTwo->addWidget( caseSensCb);
layoutTwo->addWidget( useLocateCb );
subgrid->addLayout( layoutOne );
subgrid->addLayout( layoutTwo );
subgrid->addStretch(1);
// Signals
connect( browseB, SIGNAL(clicked()),
this, SLOT(getDirectory()) );
connect( nameBox, SIGNAL(returnPressed()),
this, SIGNAL(startSearch()));
connect( dirBox, SIGNAL(returnPressed()),
this, SIGNAL(startSearch()));
// ************ Page Two
pages[1] = new QWidget;
pages[1]->setObjectName( QLatin1String( "page2" ) );
findCreated = new QCheckBox(i18n("Find all files created or &modified:"), pages[1]);
bg = new QButtonGroup();
rb[0] = new QRadioButton(i18n("&between"), pages[1] );
rb[1] = new QRadioButton(pages[1]); // text set in updateDateLabels
andL = new QLabel(i18n("and"), pages[1]);
andL->setObjectName( QLatin1String( "and" ) );
betweenType = new KComboBox( pages[1] );
betweenType->setObjectName( QLatin1String( "comboBetweenType" ) );
betweenType->addItems(QVector<QString>(5).toList()); // texts set in updateDateLabels
betweenType->setCurrentIndex(1);
updateDateLabels(1, 1);
QDate dt = KGlobal::locale()->calendar()->addYears(QDate::currentDate(), -1);
fromDate = new KDateCombo(dt, pages[1] );
fromDate->setObjectName( QLatin1String( "fromDate" ) );
toDate = new KDateCombo(pages[1] );
toDate->setObjectName( QLatin1String( "toDate" ) );
timeBox = new KIntSpinBox( pages[1] );
timeBox->setRange( 1, 60 );
timeBox->setSingleStep( 1 );
timeBox->setObjectName( QLatin1String( "timeBox" ) );
sizeBox =new KComboBox( pages[1] );
sizeBox->setObjectName( QLatin1String( "sizeBox" ) );
QLabel * sizeL =new QLabel(i18n("File &size is:"), pages[1]);
sizeL->setBuddy( sizeBox );
sizeEdit=new KIntSpinBox(pages[1] );
sizeEdit->setRange( 0, INT_MAX );
sizeEdit->setSingleStep( 1 );
sizeEdit->setObjectName( QLatin1String( "sizeEdit" ) );
sizeEdit->setValue(1);
sizeUnitBox =new KComboBox( pages[1] );
sizeUnitBox->setObjectName( QLatin1String( "sizeUnitBox" ) );
m_usernameBox = new KComboBox( pages[1] );
m_usernameBox->setEditable( true );
m_usernameBox->setObjectName( QLatin1String( "m_combo1" ));
QLabel *usernameLabel= new QLabel(i18n("Files owned by &user:"),pages[1]);
usernameLabel->setBuddy( m_usernameBox );
m_groupBox = new KComboBox( pages[1] );
m_groupBox->setEditable( true );
m_groupBox->setObjectName( QLatin1String( "m_combo2" ) );
QLabel *groupLabel= new QLabel(i18n("Owned by &group:"),pages[1]);
groupLabel->setBuddy( m_groupBox );
sizeBox ->addItem( i18nc("file size isn't considered in the search","(none)") );
sizeBox ->addItem( i18n("At Least") );
sizeBox ->addItem( i18n("At Most") );
sizeBox ->addItem( i18n("Equal To") );
sizeUnitBox ->addItem( i18np("Byte", "Bytes", 1) );
sizeUnitBox ->addItem( i18n("KiB") );
sizeUnitBox ->addItem( i18n("MiB") );
sizeUnitBox ->addItem( i18n("GiB") );
sizeUnitBox ->setCurrentIndex(1);
int tmp = sizeEdit->fontMetrics().width(" 000000000 ");
sizeEdit->setMinimumSize(tmp, sizeEdit->sizeHint().height());
m_usernameBox->setDuplicatesEnabled(false);
m_groupBox->setDuplicatesEnabled(false);
m_usernameBox->setInsertPolicy(QComboBox::InsertAtTop);
m_groupBox->setInsertPolicy(QComboBox::InsertAtTop);
// Setup
rb[0]->setChecked(true);
bg->addButton( rb[0] );
bg->addButton( rb[1] );
// Layout
QGridLayout *grid1 = new QGridLayout( pages[1] );
grid1->setMargin( KDialog::marginHint() );
grid1->setSpacing( KDialog::spacingHint() );
grid1->addWidget(findCreated, 0, 0, 1, 3 );
grid1->addItem( new QSpacerItem(KDialog::spacingHint(), 0), 0, 0 );
grid1->addWidget(rb[0], 1, 1 );
grid1->addWidget(fromDate, 1, 2 );
grid1->addWidget(andL, 1, 3, Qt::AlignHCenter );
grid1->addWidget(toDate, 1, 4 );
grid1->addWidget(rb[1], 2, 1 );
grid1->addWidget(timeBox, 2, 2, 1, 2);
grid1->addWidget(betweenType, 2, 4 );
grid1->addWidget(sizeL,3,0,1,2);
grid1->addWidget(sizeBox,3,2);
grid1->addWidget(sizeEdit,3,3);
grid1->addWidget(sizeUnitBox,3,4);
grid1->addWidget(usernameLabel,4,0,1,2);
grid1->addWidget(m_usernameBox,4,2);
grid1->addWidget(groupLabel,4,3);
grid1->addWidget(m_groupBox,4,4);
for (int c=1; c<=4; c++)
grid1->setColumnStretch(c,1);
grid1->setRowStretch(6,1);
// Connect
connect( findCreated, SIGNAL(toggled(bool)), SLOT(fixLayout()) );
connect( bg, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(fixLayout()) );
connect( sizeBox, SIGNAL(activated(int)), this, SLOT(slotSizeBoxChanged(int)));
connect( timeBox, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateDateLabelsForNumber(int)));
connect( betweenType, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUpdateDateLabelsForType(int)));
connect( sizeEdit, SIGNAL(valueChanged(int)), this, SLOT(slotUpdateByteComboBox(int)));
// ************ Page Three
pages[2] = new QWidget;
pages[2]->setObjectName( QLatin1String( "page3" ) );
typeBox =new KComboBox( pages[2] );
typeBox->setObjectName( QLatin1String( "typeBox" ) );
typeBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); // allow smaller than widest entry
QLabel * typeL =new QLabel( i18nc("label for the file type combobox","File &type:"), pages[2] );
typeL->setBuddy( typeBox );
textEdit=new KLineEdit(pages[2]);
textEdit->setClearButtonShown(true);
textEdit->setObjectName( QLatin1String( "textEdit" ) );
QLabel * textL =new QLabel(i18n("C&ontaining text:"), pages[2]);
textL->setBuddy( textEdit );
connect( textEdit, SIGNAL(returnPressed(const QString &)), SIGNAL( startSearch()));
const QString containingtext
= i18n("<qt>If specified, only files that contain this text"
" are found. Note that not all file types from the list"
" above are supported. Please refer to the documentation"
" for a list of supported file types."
"</qt>");
textEdit->setToolTip(containingtext);
textL->setWhatsThis(containingtext);
caseContextCb =new QCheckBox(i18n("Case s&ensitive"), pages[2]);
binaryContextCb =new QCheckBox(i18n("Include &binary files"), pages[2]);
regexpContentCb =new QCheckBox(i18n("Regular e&xpression"), pages[2]);
const QString binaryTooltip
= i18n("<qt>This lets you search in any type of file, "
"even those that usually do not contain text (for example "
"program files and images).</qt>");
binaryContextCb->setToolTip(binaryTooltip);
QPushButton* editRegExp = 0;
if ( !KServiceTypeTrader::self()->query("KRegExpEditor/KRegExpEditor").isEmpty() ) {
// The editor is available, so lets use it.
editRegExp = new QPushButton(i18n("&Edit..."), pages[2]);
editRegExp->setObjectName( QLatin1String( "editRegExp" ) );
}
metainfokeyEdit=new KLineEdit(pages[2]);
metainfoEdit=new KLineEdit(pages[2]);
QLabel * textMetaInfo = new QLabel(i18n("fo&r:"), pages[2]);
textMetaInfo->setBuddy( metainfoEdit );
QLabel * textMetaKey = new QLabel(i18n("Search &metainfo sections:"), pages[2]);
textMetaKey->setBuddy( metainfokeyEdit );
// Setup
typeBox->addItem(i18n("All Files & Folders"));
typeBox->addItem(i18n("Files"));
typeBox->addItem(i18n("Folders"));
typeBox->addItem(i18n("Symbolic Links"));
typeBox->addItem(i18n("Special Files (Sockets, Device Files, ...)"));
typeBox->addItem(i18n("Executable Files"));
typeBox->addItem(i18n("SUID Executable Files"));
typeBox->addItem(i18n("All Images"));
typeBox->addItem(i18n("All Video"));
typeBox->addItem(i18n("All Sounds"));
initMimeTypes();
initSpecialMimeTypes();
for ( KMimeType::List::ConstIterator it = m_types.constBegin();
it != m_types.constEnd(); ++it )
{
KMimeType::Ptr typ = *it;
// TODO: needs to move to thread (increases startup time to bizzare amount)
// and replaced with a better concept 16x16 icons don't cut the cheese
// typeBox->addItem(KIconLoader::global()->loadMimeTypeIcon( typ->iconName(), KIconLoader::Small ), typ->comment());
typeBox->addItem(typ->comment());
}
if ( editRegExp ) {
// The editor was available, so lets use it.
connect( regexpContentCb, SIGNAL(toggled(bool) ), editRegExp, SLOT(setEnabled(bool)) );
editRegExp->setEnabled(false);
connect( editRegExp, SIGNAL(clicked()), this, SLOT( slotEditRegExp() ) );
}
else
regexpContentCb->hide();
// Layout
tmp = sizeEdit->fontMetrics().width(" 00000 ");
sizeEdit->setMinimumSize(tmp, sizeEdit->sizeHint().height());
QGridLayout *grid2 = new QGridLayout( pages[2] );
grid2->setMargin( KDialog::marginHint() );
grid2->setSpacing( KDialog::spacingHint() );
grid2->addWidget( typeL, 0, 0 );
grid2->addWidget( textL, 1, 0 );
grid2->addWidget( typeBox, 0, 1, 1, 3 );
grid2->addWidget( textEdit, 1, 1, 1, 3 );
grid2->addWidget( regexpContentCb, 2, 2);
grid2->addWidget( caseContextCb, 2, 1 );
grid2->addWidget( binaryContextCb, 3, 1);
grid2->addWidget( textMetaKey, 4, 0 );
grid2->addWidget( metainfokeyEdit, 4, 1 );
grid2->addWidget( textMetaInfo, 4, 2, Qt::AlignHCenter );
grid2->addWidget( metainfoEdit, 4, 3 );
metainfokeyEdit->setText("*");
if ( editRegExp ) {
// The editor was available, so lets use it.
grid2->addWidget( editRegExp, 2, 3 );
}
addTab( pages[0], i18n("Name/&Location") );
addTab( pages[2], i18nc("tab name: search by contents","C&ontents") );
addTab( pages[1], i18n("&Properties") );
// Setup
const QString whatsmetainfo
= i18n("<qt>Search within files' specific comments/metainfo<br />"
"These are some examples:<br />"
"<ul>"
"<li><b>Audio files (mp3...)</b> Search in id3 tag for a title, an album</li>"
"<li><b>Images (png...)</b> Search images with a special resolution, comment...</li>"
"</ul>"
"</qt>");
const QString whatsmetainfokey
= i18n("<qt>If specified, search only in this field<br />"
"<ul>"
"<li><b>Audio files (mp3...)</b> This can be Title, Album...</li>"
"<li><b>Images (png...)</b> Search only in Resolution, Bitdepth...</li>"
"</ul>"
"</qt>");
textMetaInfo->setWhatsThis(whatsmetainfo);
metainfoEdit->setToolTip(whatsmetainfo);
textMetaKey->setWhatsThis(whatsmetainfokey);
metainfokeyEdit->setToolTip(whatsmetainfokey);
fixLayout();
loadHistory();
}
KfindTabWidget::~KfindTabWidget()
{
delete pages[0];
delete pages[1];
delete pages[2];
delete bg;
}
void KfindTabWidget::setURL( const KUrl & url )
{
KConfigGroup conf(KGlobal::config(), "History");
m_url = url;
QStringList sl = conf.readPathEntry("Directories", QStringList());
dirBox->clear(); // make sure there is no old Stuff in there
if(!sl.isEmpty()) {
dirBox->addItems(sl);
// If the _searchPath already exists in the list we do not
// want to add it again
int indx = sl.indexOf(m_url.prettyUrl());
if(indx == -1) {
dirBox->insertItem(0, m_url.prettyUrl()); // make it the first one
dirBox->setCurrentIndex(0);
}
else
dirBox->setCurrentIndex(indx);
}
else {
QDir m_dir("/lib");
dirBox ->insertItem( 0, m_url.prettyUrl() );
dirBox ->addItem( "file:" + QDir::homePath() );
dirBox ->addItem( "file:/" );
dirBox ->addItem( "file:/usr" );
if (m_dir.exists())
dirBox ->addItem( "file:/lib" );
dirBox ->addItem( "file:/home" );
dirBox ->addItem( "file:/etc" );
dirBox ->addItem( "file:/var" );
dirBox ->addItem( "file:/mnt" );
dirBox->setCurrentIndex(0);
}
}
void KfindTabWidget::initMimeTypes()
{
KMimeType::List sortedList;
foreach ( const KMimeType::Ptr &type, KMimeType::allMimeTypes() )
{
if ( (!type->comment().isEmpty())
&& (!type->name().startsWith( QString("kdedevice/") ))
&& (!type->name().startsWith( QString("all/") )) )
sortedList.append(type);
}
qSort( sortedList.begin(), sortedList.end(), LessMimeType_ByComment() );
m_types += sortedList;
}
void KfindTabWidget::initSpecialMimeTypes()
{
const KMimeType::List tmp = KMimeType::allMimeTypes();
for ( KMimeType::List::ConstIterator it = tmp.constBegin(); it != tmp.constEnd(); ++it )
{
const KMimeType* type = (*it).data();
if(!type->comment().isEmpty()) {
if(type->name().startsWith( QString("image/") ))
m_ImageTypes.append(type->name());
else if(type->name().startsWith( QString("video/") ))
m_VideoTypes.append(type->name());
else if(type->name().startsWith( QString("audio/") ))
m_AudioTypes.append(type->name());
}
}
}
void KfindTabWidget::saveHistory()
{
save_pattern(nameBox, "History", "Patterns");
save_pattern(dirBox, "History", "Directories");
}
void KfindTabWidget::loadHistory()
{
// Load pattern history
KConfigGroup conf(KGlobal::config(), "History");
QStringList sl = conf.readEntry("Patterns", QStringList());
if(!sl.isEmpty())
nameBox->addItems(sl);
else
nameBox->addItem("*");
sl = conf.readPathEntry("Directories", QStringList());
if(!sl.isEmpty()) {
dirBox->addItems(sl);
// If the _searchPath already exists in the list we do not
// want to add it again
int indx = sl.indexOf(m_url.prettyUrl());
if(indx == -1) {
dirBox->insertItem(0, m_url.prettyUrl()); // make it the first one
dirBox->setCurrentIndex(0);
}
else
dirBox->setCurrentIndex(indx);
}
else {
QDir m_dir("/lib");
dirBox ->insertItem( 0, m_url.prettyUrl() );
dirBox ->addItem( "file:" + QDir::homePath() );
dirBox ->addItem( "file:/" );
dirBox ->addItem( "file:/usr" );
if (m_dir.exists())
dirBox ->addItem( "file:/lib" );
dirBox ->addItem( "file:/home" );
dirBox ->addItem( "file:/etc" );
dirBox ->addItem( "file:/var" );
dirBox ->addItem( "file:/mnt" );
dirBox ->setCurrentIndex(0);
}
}
void KfindTabWidget::slotEditRegExp()
{
if ( ! regExpDialog )
regExpDialog = KServiceTypeTrader::createInstanceFromQuery<KDialog>( "KRegExpEditor/KRegExpEditor", QString(), this );
KRegExpEditorInterface *iface = qobject_cast<KRegExpEditorInterface *>( regExpDialog );
if ( !iface )
return;
iface->setRegExp( textEdit->text() );
bool ok = regExpDialog->exec();
if ( ok )
textEdit->setText( iface->regExp() );
}
void KfindTabWidget::setFocus()
{
nameBox->setFocus();
nameBox->lineEdit()->selectAll();
}
void KfindTabWidget::slotSizeBoxChanged(int index)
{
sizeEdit->setEnabled((bool)(index != 0));
sizeUnitBox->setEnabled((bool)(index != 0));
}
void KfindTabWidget::setDefaults()
{
QDate dt = KGlobal::locale()->calendar()->addYears(QDate::currentDate(), -1);
fromDate ->setDate(dt);
toDate ->setDate(QDate::currentDate());
timeBox->setValue(1);
betweenType->setCurrentIndex(1);
typeBox ->setCurrentIndex(0);
sizeBox ->setCurrentIndex(0);
sizeUnitBox ->setCurrentIndex(1);
sizeEdit->setValue(1);
}
/*
Checks if dates are correct and popups a error box
if they are not.
*/
bool KfindTabWidget::isDateValid()
{
// All files
if ( !findCreated->isChecked() ) return true;
if (rb[1]->isChecked())
{
if (timeBox->value() > 0 ) return true;
KMessageBox::sorry(this, i18n("Unable to search within a period which is less than a minute."));
return false;
}
// If we can not parse either of the dates or
// "from" date is bigger than "to" date return false.
QDate hi1, hi2;
QString str;
if ( ! fromDate->getDate(&hi1).isValid() ||
! toDate->getDate(&hi2).isValid() )
str = i18n("The date is not valid.");
else if ( hi1 > hi2 )
str = i18n("Invalid date range.");
else if ( QDate::currentDate() < hi1 )
str = i18n("Unable to search dates in the future.");
if (!str.isEmpty()) {
KMessageBox::sorry(0, str);
return false;
}
return true;
}
void KfindTabWidget::setQuery(KQuery *query)
{
KIO::filesize_t size;
KIO::filesize_t sizeunit;
bool itemAlreadyContained(false);
// only start if we have valid dates
if (!isDateValid()) return;
query->setPath(KUrl(dirBox->currentText().trimmed()));
for (int idx=0; idx<dirBox->count(); idx++)
if (dirBox->itemText(idx)==dirBox->currentText())
itemAlreadyContained=true;
if (!itemAlreadyContained)
dirBox->addItem(dirBox->currentText().trimmed(),0);
QString regex = nameBox->currentText().isEmpty() ? "*" : nameBox->currentText();
query->setRegExp(regex, caseSensCb->isChecked());
itemAlreadyContained=false;
for (int idx=0; idx<nameBox->count(); idx++)
if (nameBox->itemText(idx)==nameBox->currentText())
itemAlreadyContained=true;
if (!itemAlreadyContained)
nameBox->addItem(nameBox->currentText(),0);
query->setRecursive(subdirsCb->isChecked());
switch (sizeUnitBox->currentIndex())
{
case 0:
sizeunit = 1; //one byte
break;
case 2:
sizeunit = 1048576; //1Mi
break;
case 3:
sizeunit = 1073741824; //1Gi
break;
case 1: // fall to default case
default:
sizeunit=1024; //1Ki
break;
}
size = sizeEdit->value() * sizeunit;
// TODO: troeder: do we need this check since it is very unlikely
// to exceed ULLONG_MAX with INT_MAX * 1024^3.
// Or is there an arch where this can happen?
#if 0
if (size < 0) // overflow
{
if (KMessageBox::warningYesNo(this, i18n("Size is too big. Set maximum size value?"), i18n("Error"),i18n("Set"),i18n("Do Not Set"))
== KMessageBox::Yes)
{
sizeEdit->setValue(INT_MAX);
sizeUnitBox->setCurrentIndex(0);
size = INT_MAX;
}
else
return;
}
#endif
// set range mode and size value
query->setSizeRange(sizeBox->currentIndex(),size,0);
// dates
QDateTime epoch;
epoch.setTime_t(0);
// Add date predicate
if (findCreated->isChecked()) { // Modified
if (rb[0]->isChecked()) { // Between dates
QDate q1, q2;
fromDate->getDate(&q1);
toDate->getDate(&q2);
// do not generate negative numbers .. find doesn't handle that
time_t time1 = epoch.secsTo(QDateTime(q1));
time_t time2 = epoch.secsTo(QDateTime(q2.addDays(1))) - 1; // Include the last day
query->setTimeRange(time1, time2);
}
else
{
time_t cur = time(NULL);
time_t minutes = cur;
switch (betweenType->currentIndex())
{
case 0: // minutes
minutes = timeBox->value();
break;
case 1: // hours
minutes = 60 * timeBox->value();
break;
case 2: // days
minutes = 60 * 24 * timeBox->value();
break;
case 3: // months
minutes = 60 * 24 * (time_t)(timeBox->value() * 30.41667);
break;
case 4: // years
minutes = 12 * 60 * 24 * (time_t)(timeBox->value() * 30.41667);
break;
}
query->setTimeRange(cur - minutes * 60, 0);
}
}
else
query->setTimeRange(0, 0);
query->setUsername( m_usernameBox->currentText() );
query->setGroupname( m_groupBox->currentText() );
query->setFileType(typeBox->currentIndex());
int id = typeBox->currentIndex()-10;
if ((id >= -3) && (id < (int) m_types.count()))
{
switch(id)
{
case -3:
query->setMimeType( m_ImageTypes );
break;
case -2:
query->setMimeType( m_VideoTypes );
break;
case -1:
query->setMimeType( m_AudioTypes );
break;
default:
query->setMimeType( QStringList() += m_types[id]->name() );
}
}
else
{
query->setMimeType( QStringList() );
}
//Metainfo
query->setMetaInfo(metainfoEdit->text(), metainfokeyEdit->text());
//Use locate to speed-up search ?
query->setUseFileIndex(useLocateCb->isChecked());
query->setShowHiddenFiles(hiddenFilesCb->isChecked());
query->setContext(textEdit->text(), caseContextCb->isChecked(),
binaryContextCb->isChecked(), regexpContentCb->isChecked());
}
QString KfindTabWidget::date2String(const QDate & date) {
return(KGlobal::locale()->formatDate(date, KLocale::ShortDate));
}
QDate &KfindTabWidget::string2Date(const QString & str, QDate *qd) {
return *qd = KGlobal::locale()->readDate(str);
}
void KfindTabWidget::getDirectory()
{
QString result =
KFileDialog::getExistingDirectory( dirBox->currentText().trimmed(),
this );
if (!result.isEmpty())
{
for (int i = 0; i < dirBox->count(); i++)
if (result == dirBox->itemText(i)) {
dirBox->setCurrentIndex(i);
return;
}
dirBox->insertItem(0, result);
dirBox->setCurrentIndex(0);
}
}
void KfindTabWidget::beginSearch()
{
/// dirlister->openUrl(KUrl(dirBox->currentText().trimmed()));
saveHistory();
setEnabled( false );
}
void KfindTabWidget::endSearch()
{
setEnabled( true );
}
/*
Disables/enables all edit fields depending on their
respective check buttons.
*/
void KfindTabWidget::fixLayout()
{
int i;
// If "All files" is checked - disable all edits
// and second radio group on page two
if(! findCreated->isChecked()) {
fromDate->setEnabled(false);
toDate->setEnabled(false);
andL->setEnabled(false);
timeBox->setEnabled(false);
for(i=0; i<2; ++i)
rb[i]->setEnabled(false);
betweenType->setEnabled(false);
}
else {
for(i=0; i<2; ++i)
rb[i]->setEnabled(true);
fromDate->setEnabled(rb[0]->isChecked());
toDate->setEnabled(rb[0]->isChecked());
andL->setEnabled(rb[0]->isEnabled());
timeBox->setEnabled(rb[1]->isChecked());
betweenType->setEnabled(rb[1]->isChecked());
}
// Size box on page three
sizeEdit->setEnabled(sizeBox->currentIndex() != 0);
sizeUnitBox->setEnabled(sizeBox->currentIndex() != 0);
}
bool KfindTabWidget::isSearchRecursive()
{
return subdirsCb->isChecked();
}
void KfindTabWidget::slotUpdateDateLabelsForNumber(int value)
{
updateDateLabels(betweenType->currentIndex(), value);
}
void KfindTabWidget::slotUpdateDateLabelsForType(int index)
{
updateDateLabels(index, timeBox->value());
}
void KfindTabWidget::updateDateLabels(int type, int value)
{
QString typeKey(type == 0 ? 'i' : type == 1 ? 'h' : type == 2 ? 'd' : type == 3 ? 'm' : 'y');
rb[1]->setText(ki18ncp("during the previous minute(s)/hour(s)/...; "
"dynamic context 'type': 'i' minutes, 'h' hours, 'd' days, 'm' months, 'y' years",
"&during the previous", "&during the previous").subs(value).inContext("type", typeKey).toString());
betweenType->setItemText(0, i18ncp("use date ranges to search files by modified time", "minute", "minutes", value));
betweenType->setItemText(1, i18ncp("use date ranges to search files by modified time", "hour", "hours", value));
betweenType->setItemText(2, i18ncp("use date ranges to search files by modified time", "day", "days", value));
betweenType->setItemText(3, i18ncp("use date ranges to search files by modified time", "month", "months", value));
betweenType->setItemText(4, i18ncp("use date ranges to search files by modified time", "year", "years", value));
}
void KfindTabWidget::slotUpdateByteComboBox(int value)
{
sizeUnitBox->setItemText(0, i18np("Byte", "Bytes", value) );
}
/**
Digit validator. Allows only digits to be typed.
**/
KDigitValidator::KDigitValidator( QWidget * parent )
: QValidator( parent )
{
r = new QRegExp("^[0-9]*$");
}
KDigitValidator::~KDigitValidator()
{
delete r;
}
QValidator::State KDigitValidator::validate( QString & input, int & ) const
{
if (r->indexIn(input) < 0) {
// Beep on user if he enters non-digit
QApplication::beep();
return QValidator::Invalid;
}
else
return QValidator::Acceptable;
}
//*******************************************************
// Static utility functions
//*******************************************************
static void save_pattern(KComboBox *obj,
const QString & group, const QString & entry)
{
// QComboBox allows insertion of items more than specified by
// maxCount() (QT bug?). This API call will truncate list if needed.
obj->setMaxCount(15);
// make sure the current item is saved first so it will be the
// default when started next time
QStringList sl;
QString cur = obj->itemText(obj->currentIndex());
sl.append(cur);
for (int i = 0; i < obj->count(); i++) {
if( cur != obj->itemText(i) ) {
sl.append(obj->itemText(i));
}
}
KConfigGroup conf(KGlobal::config(), group);
conf.writePathEntry(entry, sl);
}
QSize KfindTabWidget::sizeHint() const
{
// #44662: avoid a huge default size when the comboboxes have very large items
// Like in minicli, we changed the combobox size policy so that they can resize down,
// and then we simply provide a reasonable size hint for the whole window, depending
// on the screen width.
QSize sz = KTabWidget::sizeHint();
KfindTabWidget* me = const_cast<KfindTabWidget*>( this );
const int screenWidth = qApp->desktop()->screenGeometry(me).width();
if ( sz.width() > screenWidth / 2 )
sz.setWidth( screenWidth / 2 );
return sz;
}
#include "kftabdlg.moc"