diff --git a/krusader/FileSystem/krquery.h b/krusader/FileSystem/krquery.h --- a/krusader/FileSystem/krquery.h +++ b/krusader/FileSystem/krquery.h @@ -131,6 +131,10 @@ // gets whether to follow symbolic links bool followLinks() { return followLinksP; } + // sets the folder names which the searcher will exclude from traversing + void setExcludeFolderNames(const QStringList &urls); + // gets the folder names which the searcher excludes + const QStringList excludeFolderNames() { return excludedFolderNames; } // sets the folders where the searcher will search void setSearchInDirs(const QList &urls); // gets the folders where the searcher searches @@ -186,6 +190,7 @@ bool recurse; // if true recurse ob sub-dirs... bool followLinksP; + QStringList excludedFolderNames; // substrings of paths where not to search QList whereToSearch; // directories to search QList whereNotToSearch; // directories NOT to search diff --git a/krusader/FileSystem/krquery.cpp b/krusader/FileSystem/krquery.cpp --- a/krusader/FileSystem/krquery.cpp +++ b/krusader/FileSystem/krquery.cpp @@ -119,6 +119,7 @@ recurse = old.recurse; followLinksP = old.followLinksP; whereToSearch = old.whereToSearch; + excludedFolderNames = old.excludedFolderNames; whereNotToSearch = old.whereNotToSearch; origFilter = old.origFilter; @@ -741,12 +742,17 @@ bool KRQuery::isExcluded(const QUrl &url) { - for (int i = 0; i < whereNotToSearch.count(); ++i) - if (whereNotToSearch[i].isParentOf(url) || - url.matches(whereNotToSearch[i], QUrl::StripTrailingSlash)) + for (QUrl &item : whereNotToSearch) + if (item.isParentOf(url) || url.matches(item, QUrl::StripTrailingSlash)) return true; - if (!matchDirName(url.fileName())) + // Exclude folder names that are configured in settings + QString filename = url.fileName(); + for (QString &item : excludedFolderNames) + if (filename == item) + return true; + + if (!matchDirName(filename)) return true; return false; @@ -773,3 +779,8 @@ whereNotToSearch.append(completed); } } +void KRQuery::setExcludeFolderNames(const QStringList &paths) +{ + excludedFolderNames.clear(); + excludedFolderNames.append(paths); +} diff --git a/krusader/Filter/filtersettings.h b/krusader/Filter/filtersettings.h --- a/krusader/Filter/filtersettings.h +++ b/krusader/Filter/filtersettings.h @@ -98,6 +98,7 @@ bool followLinks; QList searchIn; QList dontSearchIn; + QStringList excludeFolderNames; QString contentEncoding; QString containsText; bool containsTextCase; diff --git a/krusader/Filter/filtersettings.cpp b/krusader/Filter/filtersettings.cpp --- a/krusader/Filter/filtersettings.cpp +++ b/krusader/Filter/filtersettings.cpp @@ -120,6 +120,7 @@ COPY(followLinks); COPY(searchIn); COPY(dontSearchIn); + COPY(excludeFolderNames); COPY(contentEncoding); COPY(containsText); COPY(containsTextCase); @@ -160,6 +161,7 @@ LOAD("FollowLinks", followLinks); searchIn = KrServices::toUrlList(cfg.readEntry("SearchIn", QStringList())); dontSearchIn = KrServices::toUrlList(cfg.readEntry("DontSearchIn", QStringList())); + excludeFolderNames = QStringList(); LOAD("ContentEncoding", contentEncoding); LOAD("ContainsText", containsText); LOAD("ContainsTextCase", containsTextCase); @@ -296,6 +298,8 @@ if (!dontSearchIn.isEmpty()) query.setDontSearchInDirs(dontSearchIn); + query.setExcludeFolderNames(excludeFolderNames); + ////////////// Advanced Options ////////////// if (minSizeEnabled) diff --git a/krusader/Filter/generalfilter.h b/krusader/Filter/generalfilter.h --- a/krusader/Filter/generalfilter.h +++ b/krusader/Filter/generalfilter.h @@ -85,6 +85,7 @@ QCheckBox* searchForCase; QCheckBox* containsTextCase; QCheckBox* containsWholeWord; + QCheckBox* useExcludeFolderNames; QCheckBox* searchInDirs; QCheckBox* searchInArchives; QCheckBox* followLinks; @@ -96,6 +97,7 @@ KHistoryComboBox* searchFor; KHistoryComboBox* containsText; + KHistoryComboBox* excludeFolderNames; QToolButton* containsRegExp; KComboBox* ofType; diff --git a/krusader/Filter/generalfilter.cpp b/krusader/Filter/generalfilter.cpp --- a/krusader/Filter/generalfilter.cpp +++ b/krusader/Filter/generalfilter.cpp @@ -232,7 +232,35 @@ dontSearchInLayout->setContentsMargins(11, 11, 11, 11); dontSearchIn = new KURLListRequester(KURLListRequester::RequestDirs, dontSearchInGroup); - dontSearchInLayout->addWidget(dontSearchIn, 0, 0); + dontSearchInLayout->addWidget(dontSearchIn, 0, 0, 1, 2); + + if (properties & FilterTabs::HasRecurseOptions) { + KConfigGroup group(krConfig, "Search"); + + useExcludeFolderNames = new QCheckBox(this); + useExcludeFolderNames->setText(i18n("Exclude Folder Names")); + useExcludeFolderNames->setToolTip(i18n("Filters out specified directory names from the results.")); + useExcludeFolderNames->setChecked(static_cast(group.readEntry("ExcludeFolderNamesUse", 0))); + dontSearchInLayout->addWidget(useExcludeFolderNames, 1, 0, 1, 1); + + excludeFolderNames = new KHistoryComboBox(false, dontSearchInGroup); + QSizePolicy excludeFolderNamesPolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + excludeFolderNamesPolicy.setHeightForWidth(excludeFolderNames->sizePolicy().hasHeightForWidth()); + excludeFolderNames->setSizePolicy(excludeFolderNamesPolicy); + excludeFolderNames->setEditable(true); + excludeFolderNames->setDuplicatesEnabled(false); + excludeFolderNames->setMaxCount(25); + excludeFolderNames->setMinimumContentsLength(10); + excludeFolderNames->lineEdit()->setPlaceholderText("Enter colon separated folder names"); + dontSearchInLayout->addWidget(excludeFolderNames, 1, 1, 1, 1); + excludeFolderNames->setHistoryItems(group.readEntry("ExcludeFolderNamesHistory", QStringList())); + excludeFolderNames->setEditText(group.readEntry("ExcludeFolderNames", "")); + if (!useExcludeFolderNames->isChecked()) { + excludeFolderNames->setDisabled(true); + } + + connect(useExcludeFolderNames, &QCheckBox::toggled, excludeFolderNames, &KHistoryComboBox::setEnabled); + } middleLayout->addWidget(dontSearchInGroup); } @@ -402,7 +430,14 @@ group.writeEntry("ContainsText Completion", list); list = containsText->historyItems(); group.writeEntry("ContainsText History", list); - + if (properties & FilterTabs::HasDontSearchIn) { + if (properties & FilterTabs::HasRecurseOptions) { + list = excludeFolderNames->historyItems(); + group.writeEntry("ExcludeFolderNamesHistory", list); + group.writeEntry("ExcludeFolderNames", excludeFolderNames->currentText()); + group.writeEntry("ExcludeFolderNamesUse", static_cast(useExcludeFolderNames->checkState())); + } + } krConfig->sync(); } @@ -423,6 +458,11 @@ { searchFor->addToHistory(searchFor->currentText()); containsText->addToHistory(containsText->currentText()); + if (properties & FilterTabs::HasDontSearchIn) { + if (properties & FilterTabs::HasRecurseOptions) { + excludeFolderNames->addToHistory(excludeFolderNames->currentText()); + } + } } void GeneralFilter::refreshProfileListBox() @@ -557,9 +597,16 @@ } } - if (properties & FilterTabs::HasDontSearchIn) + if (properties & FilterTabs::HasDontSearchIn) { s.dontSearchIn = dontSearchIn->urlList(); - + if (properties & FilterTabs::HasRecurseOptions) { + if(useExcludeFolderNames->isChecked()) { + s.excludeFolderNames = excludeFolderNames->currentText().split(':'); + } else { + s.excludeFolderNames = QStringList(); + } + } + } return true; }