diff --git a/src/kftabdlg.cpp b/src/kftabdlg.cpp
index ad3d24c8a..b2e2eb17d 100644
--- a/src/kftabdlg.cpp
+++ b/src/kftabdlg.cpp
@@ -1,964 +1,960 @@
/*******************************************************************
* 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 .
*
******************************************************************/
#include "kftabdlg.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "kquery.h"
// Static utility functions
static void save_pattern(KComboBox *, const QString &, const QString &);
static const int specialMimeTypeCount = 10;
struct MimeTypes
{
QVector all;
QStringList image;
QStringList video;
QStringList audio;
};
KfindTabWidget::KfindTabWidget(QWidget *parent)
: QTabWidget(parent)
, regExpDialog(nullptr)
{
// This validator will be used for all numeric edit fields
//KDigitValidator *digitV = new KDigitValidator(this);
// ************ Page One ************
pages[0] = new QWidget;
pages[0]->setObjectName(QStringLiteral("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(QStringLiteral("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(QStringLiteral("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 (QStandardPaths::findExecutable(QStringLiteral("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("Enter the filename you are looking for.
"
"Alternatives may be separated by a semicolon \";\".
"
"
"
"The filename may contain the following special characters:"
""
"- ? matches any single character
"
"- * matches zero or more of any characters
"
"- [...] matches any of the characters between the braces
"
"
"
"
"
"Example searches:"
""
"- *.kwd;*.txt finds all files ending with .kwd or .txt
"
"- go[dt] finds god and got
"
"- Hel?o finds all files that start with \"Hel\" and end with \"o\", "
"having one character in between
"
"- My Document.kwd finds a file of exactly that name
"
"
");
nameBox->setWhatsThis(nameWhatsThis);
namedL->setWhatsThis(nameWhatsThis);
const QString whatsfileindex
= i18n("This lets you use the files' index created by the slocate "
"package to speed-up the search; remember to update the index from time to time "
"(using updatedb)."
"");
useLocateCb->setWhatsThis(whatsfileindex);
// Layout
QGridLayout *grid = new QGridLayout(pages[0]);
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, &QPushButton::clicked, this, &KfindTabWidget::getDirectory);
connect(nameBox, static_cast(&KComboBox::returnPressed), this, &KfindTabWidget::startSearch);
connect(dirBox, static_cast(&KUrlComboBox::returnPressed), this, &KfindTabWidget::startSearch);
// ************ Page Two
pages[1] = new QWidget;
pages[1]->setObjectName(QStringLiteral("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(QStringLiteral("and"));
betweenType = new KComboBox(pages[1]);
betweenType->setObjectName(QStringLiteral("comboBetweenType"));
betweenType->addItems(QVector(5).toList()); // texts set in updateDateLabels
betweenType->setCurrentIndex(1);
updateDateLabels(1, 1);
const QDate dt = QDate::currentDate().addYears(-1);
fromDate = new KDateComboBox(pages[1]);
fromDate->setObjectName(QStringLiteral("fromDate"));
fromDate->setDate(dt);
toDate = new KDateComboBox(pages[1]);
toDate->setObjectName(QStringLiteral("toDate"));
timeBox = new QSpinBox(pages[1]);
timeBox->setRange(1, 60);
timeBox->setSingleStep(1);
timeBox->setObjectName(QStringLiteral("timeBox"));
sizeBox = new KComboBox(pages[1]);
sizeBox->setObjectName(QStringLiteral("sizeBox"));
QLabel *sizeL = new QLabel(i18n("File &size is:"), pages[1]);
sizeL->setBuddy(sizeBox);
sizeEdit = new QSpinBox(pages[1]);
sizeEdit->setRange(0, INT_MAX);
sizeEdit->setSingleStep(1);
sizeEdit->setObjectName(QStringLiteral("sizeEdit"));
sizeEdit->setValue(1);
sizeUnitBox = new KComboBox(pages[1]);
sizeUnitBox->setObjectName(QStringLiteral("sizeUnitBox"));
m_usernameBox = new KComboBox(pages[1]);
m_usernameBox->setEditable(true);
m_usernameBox->setObjectName(QStringLiteral("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(QStringLiteral("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().boundingRect(QStringLiteral(" 000000000 ")).width();
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->addWidget(findCreated, 0, 0, 1, 3);
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, &QCheckBox::toggled, this, &KfindTabWidget::fixLayout);
connect(bg, static_cast(&QButtonGroup::buttonClicked), this, &KfindTabWidget::fixLayout);
connect(sizeBox, static_cast(&KComboBox::activated), this, &KfindTabWidget::slotSizeBoxChanged);
connect(timeBox, static_cast(&QSpinBox::valueChanged), this, &KfindTabWidget::slotUpdateDateLabelsForNumber);
-#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
connect(betweenType, static_cast(&KComboBox::currentIndexChanged), this, &KfindTabWidget::slotUpdateDateLabelsForType);
-#else
- connect(betweenType, static_cast(&KComboBox::currentIndexChanged), this, &KfindTabWidget::slotUpdateDateLabelsForType);
-#endif
connect(sizeEdit, static_cast(&QSpinBox::valueChanged), this, &KfindTabWidget::slotUpdateByteComboBox);
// ************ Page Three
pages[2] = new QWidget;
pages[2]->setObjectName(QStringLiteral("page3"));
typeBox = new KComboBox(pages[2]);
typeBox->setObjectName(QStringLiteral("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->setClearButtonEnabled(true);
textEdit->setObjectName(QStringLiteral("textEdit"));
QLabel *textL = new QLabel(i18n("C&ontaining text:"), pages[2]);
textL->setBuddy(textEdit);
connect(textEdit, &KLineEdit::returnPressed, this, &KfindTabWidget::startSearch);
const QString containingtext
= i18n("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."
"");
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("This lets you search in any type of file, "
"even those that usually do not contain text (for example "
"program files and images).");
binaryContextCb->setToolTip(binaryTooltip);
QPushButton *editRegExp = nullptr;
if (!KServiceTypeTrader::self()->query(QStringLiteral("KRegExpEditor/KRegExpEditor")).isEmpty()) {
// The editor is available, so lets use it.
editRegExp = new QPushButton(i18n("&Edit..."), pages[2]);
editRegExp->setObjectName(QStringLiteral("editRegExp"));
}
metainfokeyEdit = new KLineEdit(pages[2]);
metainfoEdit = new KLineEdit(pages[2]);
QLabel *textMetaInfo = new QLabel(i18nc("as in search for", "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"));
typeBox->insertSeparator(typeBox->count()); // append separator
auto mimeTypeFuture = QtConcurrent::run([] {
MimeTypes mimeTypes;
const auto types = QMimeDatabase().allMimeTypes();
foreach (const QMimeType &type, types) {
if ((!type.comment().isEmpty())
&& (!type.name().startsWith(QLatin1String("kdedevice/")))
&& (!type.name().startsWith(QLatin1String("all/")))) {
mimeTypes.all.append(type);
if (type.name().startsWith(QLatin1String("image/"))) {
mimeTypes.image.append(type.name());
} else if (type.name().startsWith(QLatin1String("video/"))) {
mimeTypes.video.append(type.name());
} else if (type.name().startsWith(QLatin1String("audio/"))) {
mimeTypes.audio.append(type.name());
}
}
}
std::sort(mimeTypes.all.begin(), mimeTypes.all.end(), [](const QMimeType &lhs, const QMimeType &rhs) {
return lhs.comment() < rhs.comment();
});
return mimeTypes;
});
auto *watcher = new QFutureWatcher(this);
watcher->setFuture(mimeTypeFuture);
connect(watcher, &QFutureWatcher::finished, this, [this, watcher] {
const MimeTypes &mimeTypes = watcher->result();
for (const auto &mime : qAsConst(mimeTypes.all)) {
typeBox->addItem(mime.comment());
}
m_types = mimeTypes.all;
m_ImageTypes = mimeTypes.image;
m_VideoTypes = mimeTypes.video;
m_AudioTypes = mimeTypes.audio;
watcher->deleteLater();
});
if (editRegExp) {
// The editor was available, so lets use it.
connect(regexpContentCb, &QCheckBox::toggled, editRegExp, &QPushButton::setEnabled);
editRegExp->setEnabled(false);
connect(editRegExp, &QPushButton::clicked, this, &KfindTabWidget::slotEditRegExp);
} else {
regexpContentCb->hide();
}
// Layout
tmp = sizeEdit->fontMetrics().boundingRect(QStringLiteral(" 00000 ")).width();
sizeEdit->setMinimumSize(tmp, sizeEdit->sizeHint().height());
QGridLayout *grid2 = new QGridLayout(pages[2]);
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(QStringLiteral("*"));
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("Search within files' specific comments/metainfo
"
"These are some examples:
"
""
"- Audio files (mp3...) Search in id3 tag for a title, an album
"
"- Images (png...) Search images with a special resolution, comment...
"
"
"
"");
const QString whatsmetainfokey
= i18n("If specified, search only in this field
"
""
"- Audio files (mp3...) This can be Title, Album...
"
"- Images (png...) Search only in Resolution, Bitdepth...
"
"
"
"");
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 QUrl &url)
{
KConfigGroup conf(KSharedConfig::openConfig(), "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.toDisplayString());
if (indx == -1) {
dirBox->insertItem(0, m_url.toDisplayString()); // make it the first one
dirBox->setCurrentIndex(0);
} else {
dirBox->setCurrentIndex(indx);
}
} else {
fillDirBox();
}
}
void KfindTabWidget::fillDirBox()
{
QDir m_dir(QStringLiteral("/lib"));
dirBox->insertItem(0, m_url.toDisplayString());
dirBox->addUrl(QUrl::fromLocalFile(QDir::homePath()));
dirBox->addUrl(QUrl::fromLocalFile(QStringLiteral("/")));
dirBox->addUrl(QUrl::fromLocalFile(QStringLiteral("/usr")));
if (m_dir.exists()) {
dirBox->addUrl(QUrl::fromLocalFile(QStringLiteral("lib")));
}
dirBox->addUrl(QUrl::fromLocalFile(QStringLiteral("/home")));
dirBox->addUrl(QUrl::fromLocalFile(QStringLiteral("/etc")));
dirBox->addUrl(QUrl::fromLocalFile(QStringLiteral("/var")));
dirBox->addUrl(QUrl::fromLocalFile(QStringLiteral("/mnt")));
dirBox->setCurrentIndex(0);
}
void KfindTabWidget::saveHistory()
{
save_pattern(nameBox, QStringLiteral("History"), QStringLiteral("Patterns"));
save_pattern(dirBox, QStringLiteral("History"), QStringLiteral("Directories"));
}
void KfindTabWidget::loadHistory()
{
// Load pattern history
KConfigGroup conf(KSharedConfig::openConfig(), QStringLiteral("History"));
QStringList sl = conf.readEntry(QStringLiteral("Patterns"), QStringList());
if (!sl.isEmpty()) {
nameBox->addItems(sl);
} else {
nameBox->addItem(QStringLiteral("*"));
}
sl = conf.readPathEntry(QStringLiteral("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.toDisplayString());
if (indx == -1) {
dirBox->insertItem(0, m_url.toDisplayString()); // make it the first one
dirBox->setCurrentIndex(0);
} else {
dirBox->setCurrentIndex(indx);
}
} else {
fillDirBox();
}
}
void KfindTabWidget::slotEditRegExp()
{
#if 0
if (!regExpDialog) {
regExpDialog = KServiceTypeTrader::createInstanceFromQuery(QStringLiteral("KRegExpEditor/KRegExpEditor"), QString(), this);
}
KRegExpEditorInterface *iface = qobject_cast(regExpDialog);
if (!iface) {
return;
}
iface->setRegExp(textEdit->text());
if (regExpDialog->exec()) {
textEdit->setText(iface->regExp());
}
#endif
}
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()
{
const QDate dt = QDate::currentDate().addYears(-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.
const QDate from = fromDate->date();
const QDate to = toDate->date();
QString str;
if (!from.isValid() || !to.isValid()) {
str = i18n("The date is not valid.");
} else if (from > to) {
str = i18n("Invalid date range.");
} else if (from > QDate::currentDate()) {
str = i18n("Unable to search dates in the future.");
}
if (!str.isEmpty()) {
KMessageBox::sorry(nullptr, 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;
}
const QString trimmedDirBoxText = dirBox->currentText().trimmed();
const QString tildeExpandedPath = KShell::tildeExpand(trimmedDirBoxText);
query->setPath(QUrl::fromUserInput(tildeExpandedPath, m_url.toLocalFile(), QUrl::AssumeLocalFile));
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() ? QStringLiteral("*") : 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.setSecsSinceEpoch(0);
// Add date predicate
if (findCreated->isChecked()) { // Modified
if (rb[0]->isChecked()) { // Between dates
const QDate &from = fromDate->date();
const QDate &to = toDate->date();
// do not generate negative numbers .. find doesn't handle that
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
time_t time1 = epoch.secsTo(QDateTime(from));
time_t time2 = epoch.secsTo(QDateTime(to.addDays(1))) - 1; // Include the last day
#else
time_t time1 = epoch.secsTo(QDateTime(from.startOfDay()));
time_t time2 = epoch.secsTo(QDateTime(to.addDays(1).startOfDay())) - 1; // Include the last day
#endif
query->setTimeRange(time1, time2);
} else {
time_t cur = time(nullptr);
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() - specialMimeTypeCount - 1 /*the separator*/;
if ((id >= -4) && (id < (int)m_types.count())) {
switch (id) {
case -4:
query->setMimeType(m_ImageTypes);
break;
case -3:
query->setMimeType(m_VideoTypes);
break;
case -2:
query->setMimeType(m_AudioTypes);
break;
default:
query->setMimeType(QStringList() += m_types.value(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());
}
void KfindTabWidget::getDirectory()
{
const QString result
= QFileDialog::getExistingDirectory(this, QString(), dirBox->currentText().trimmed());
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();
for(QWidget *page : pages) {
page->setEnabled(false);
}
}
void KfindTabWidget::endSearch()
{
for(QWidget *page : pages) {
page->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 ? QLatin1Char('i') : type == 1 ? QLatin1Char('h') : type == 2 ? QLatin1Char('d') : type == 3 ? QLatin1Char('m') : QLatin1Char('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(QStringLiteral("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(QStringLiteral("^[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(KSharedConfig::openConfig(), 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 = QTabWidget::sizeHint();
KfindTabWidget *me = const_cast(this);
const int screenWidth = qApp->desktop()->screenGeometry(me).width();
if (sz.width() > screenWidth / 2) {
sz.setWidth(screenWidth / 2);
}
return sz;
}