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; @@ -746,6 +747,12 @@ url.matches(whereNotToSearch[i], QUrl::StripTrailingSlash)) return true; + // Exclude folder names that are configured in settings + QString filename = url.fileName(); + for (int i = 0; i < excludedFolderNames.count(); ++i) + if (filename == excludedFolderNames[i]) + return true; + if (!matchDirName(url.fileName())) return true; @@ -773,3 +780,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 = cfg.readEntry("ExcludeFolderNames", QString()).split(':'); LOAD("ContentEncoding", contentEncoding); LOAD("ContainsText", containsText); LOAD("ContainsTextCase", containsTextCase); @@ -212,6 +214,7 @@ cfg.writeEntry("FollowLinks", followLinks); cfg.writeEntry("SearchIn", KrServices::toStringList(searchIn)); cfg.writeEntry("DontSearchIn", KrServices::toStringList(dontSearchIn)); + cfg.writeEntry("ExcludeFolderNames", excludeFolderNames.join(':')); cfg.writeEntry("ContentEncoding", contentEncoding); cfg.writeEntry("ContainsText", containsText); cfg.writeEntry("ContainsTextCase", containsTextCase); @@ -296,6 +299,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,32 @@ 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) { + useExcludeFolderNames = new QCheckBox(this); + useExcludeFolderNames->setText(i18n("Exclude Folder Names")); + useExcludeFolderNames->setToolTip(i18n("Filters out specified directory names from the results.")); + useExcludeFolderNames->setChecked(true); + 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); + + KConfigGroup group(krConfig, "Search"); + QStringList list = group.readEntry("Exclude Folder Names History", QStringList()); + excludeFolderNames->setHistoryItems(list); + + connect(useExcludeFolderNames, &QCheckBox::toggled, excludeFolderNames, &KHistoryComboBox::setEnabled); + } middleLayout->addWidget(dontSearchInGroup); } @@ -402,7 +427,12 @@ 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("Exclude Folder Names History", list); + } + } krConfig->sync(); } @@ -423,6 +453,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 +592,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; } @@ -582,6 +624,9 @@ searchInDirs->setChecked(s.recursive); searchInArchives->setChecked(s.searchInArchives); followLinks->setChecked(s.followLinks); + if (properties & FilterTabs::HasDontSearchIn) { + excludeFolderNames->setEditText(s.excludeFolderNames.join(':')); + } } if (properties & FilterTabs::HasSearchIn) { diff --git a/krusader/Search/krsearchdialog.h b/krusader/Search/krsearchdialog.h --- a/krusader/Search/krsearchdialog.h +++ b/krusader/Search/krsearchdialog.h @@ -130,6 +130,8 @@ static bool lastSearchInArchives; static bool lastFollowSymLinks; static bool lastContainsRegExp; + static bool lastUseExcludeFolderNames; + static QString lastExcludeFolderNames; int sizeX; int sizeY; diff --git a/krusader/Search/krsearchdialog.cpp b/krusader/Search/krsearchdialog.cpp --- a/krusader/Search/krsearchdialog.cpp +++ b/krusader/Search/krsearchdialog.cpp @@ -132,6 +132,8 @@ bool KrSearchDialog::lastContainsWholeWord = false; bool KrSearchDialog::lastContainsWithCase = false; bool KrSearchDialog::lastSearchInSubDirs = true; +bool KrSearchDialog::lastUseExcludeFolderNames = false; +QString KrSearchDialog::lastExcludeFolderNames = NULL; bool KrSearchDialog::lastSearchInArchives = false; bool KrSearchDialog::lastFollowSymLinks = false; bool KrSearchDialog::lastContainsRegExp = false; @@ -319,6 +321,9 @@ generalFilter->containsTextCase->setChecked(lastContainsWithCase); generalFilter->containsRegExp->setChecked(lastContainsRegExp); generalFilter->searchInDirs->setChecked(lastSearchInSubDirs); + generalFilter->useExcludeFolderNames->setChecked(lastUseExcludeFolderNames); + if(lastExcludeFolderNames != NULL) + generalFilter->excludeFolderNames->setEditText(lastExcludeFolderNames); generalFilter->searchInArchives->setChecked(lastSearchInArchives); generalFilter->followLinks->setChecked(lastFollowSymLinks); // the path in the active panel should be the default search location @@ -365,6 +370,8 @@ lastContainsWithCase = generalFilter->containsTextCase->isChecked(); lastContainsRegExp = generalFilter->containsRegExp->isChecked(); lastSearchInSubDirs = generalFilter->searchInDirs->isChecked(); + lastUseExcludeFolderNames = generalFilter->useExcludeFolderNames->isChecked(); + lastExcludeFolderNames = generalFilter->excludeFolderNames->currentText(); lastSearchInArchives = generalFilter->searchInArchives->isChecked(); lastFollowSymLinks = generalFilter->followLinks->isChecked(); hide();