* The original sources can be found on https://github.com/republib.
*/
+#include <QDir>
#include "mainwindow.hpp"
#include "filefinder.hpp"
m_maxDepth(512),
m_baseDir(""),
m_checkDates(false),
- m_countDirs(0),
m_countFiles(0),
- m_bytes(0){
+ m_countDirs(0),
+ m_bytes(0),
+ m_excludedDirs()
+{
m_youngerThan.setMSecsSinceEpoch(0);
m_olderThan.setMSecsSinceEpoch(0);
}
void FileFinder::fillTable(const QString& path, int depth, QTableWidget* table){
QDir dir(path);
QFileInfoList entries;
- if (m_patterns.count() == 0)
- entries = dir.entryInfoList(m_fileTypes | QDir::NoDotAndDotDot,
- QDir::NoSort);
- else
- entries = dir.entryInfoList(m_patterns, m_fileTypes, QDir::NoSort);
+ if (m_patterns.count() > 0)
+ dir.setNameFilters(m_patterns);
+ QDir::Filters filters = m_fileTypes | QDir::NoDotAndDotDot;
+ dir.setFilter(filters);
+ dir.setFilter(m_fileTypes);
QList <QFileInfo>::iterator it;
QString relativePath = path.mid(1 + m_baseDir.length());
QString node, ext;
if (depth < m_maxDepth){
entries = dir.entryInfoList(
QDir::NoSymLinks | QDir::NoDotAndDotDot | QDir::AllDirs, QDir::NoSort);
+ bool filtered = m_excludedDirs.length() > 0;
for (it = entries.begin(); it != entries.end(); ++it){
QString node = it->fileName();
- fillTable(path + QDir::separator() + node, depth + 1, table);
+ if (! filtered || !isExcludedDir(node))
+ fillTable(path + QDir::separator() + node, depth + 1, table);
}
}
table->setRowCount(m_lines);
}
+/**
+ * Checks whether a filename matches the list of excluded directories.
+ *
+ * @param node filename to check
+ * @return <code>true</code>: the node is part of the excluded dirs
+ */
+bool FileFinder::isExcludedDir(const QString& node){
+ bool rc = false;
+ QList <QString>::iterator it;
+ for (it = m_excludedDirs.begin(); it != m_excludedDirs.end(); ++it){
+ if (QString::compare(node, *it, Qt::CaseInsensitive) == 0){
+ rc = true;
+ break;
+ }
+ }
+ return rc;
+}
+
/**
* Tests whether a file matches the filter conditions.
*
* @param baseDir the directory where the search starts
*/
void FileFinder::setBaseDir(const QString& baseDir){
- m_baseDir = baseDir;
+ m_baseDir = baseDir;
+}
+
+/**
+ * Sets the list of excluded directories.
+ * @param excludedDirs each entry of this list will not be entered for search
+ */
+void FileFinder::setExcludedDirs(const QStringList& excludedDirs)
+{
+ m_excludedDirs = excludedDirs;
}
/**
void setFiletypes(const QDir::Filters& filetypes);
void setMaxDepth(int maxDepth);
void setMinDepth(int minDepth);
+ void setExcludedDirs(const QStringList& excludedDirs);
void setOlderThan(const QDateTime& olderThan);
void setPatterns(const QStringList& patterns);
void setMaxSize(const int64_t& maxSize);
void setMinSize(const int64_t& minSize);
void setYoungerThan(const QDateTime& youngerThan);
+
private:
+ bool isExcludedDir(const QString& node);
bool isValid(const QFileInfo& file);
private:
int m_lines;
int m_countFiles;
int m_countDirs;
int64_t m_bytes;
+ QStringList m_excludedDirs;
};
#endif // FILEFINDER_HPP
/*
* main.cpp
- *
+ *
* License: Public Domain
* You can use and modify this file without any restriction.
* Do what you want.
* The latest sources: https://github.com/republib
*/
-#include "mainwindow.hpp"
#include <QApplication>
+#include <QDir>
+#include "mainwindow.hpp"
int main(int argc, char *argv[]){
QApplication a(argc, argv);
*/
#include <QDir>
+#include <QFileDialog>
#include "base/rebase.hpp"
#include "mainwindow.hpp"
#include "ui_mainwindow.h"
connect(ui->pushButtonSearch, SIGNAL(clicked()), this, SLOT(search()));
connect(ui->pushButtonSearch2, SIGNAL(clicked()), this, SLOT(search()));
connect(ui->pushButtonUp, SIGNAL(clicked()), this, SLOT(up()));
+ connect(ui->pushButtonDirectory, SIGNAL(clicked()), this, SLOT(selectDirectory()));
ui->tableWidget->setColumnWidth(TC_NODE, 200);
ui->tableWidget->setColumnWidth(TC_EXT, 40);
ui->tableWidget->setColumnWidth(TC_SIZE, 125);
rc = parser.asInt64(-1);
if (rc >= 0){
setInHistory(combo, value);
- combo->setCurrentText(QString("").sprintf("%lld", rc));
+ combo->setCurrentText(QString("").sprintf("%ld", rc));
}else
guiError(combo, parser.errorMessage());
}
return rc;
}
+/**
+ * Converts the checkbox states to a filetype mask.
+ * @return the filetypes selected by the checkboxes
+ */
+QDir::Filters MainWindow::buildFileTypes(){
+ QDir::Filters rc = 0;
+ if (ui->checkBoxDirs->isChecked())
+ rc |= QDir::Dirs;
+ if (ui->checkBoxFiles->isChecked())
+ rc |= QDir::Files;
+ if (rc == 0)
+ rc |= QDir::Dirs | QDir::Files;
+ if (! ui->checkBoxLinks->isChecked())
+ rc |= QDir::NoSymLinks;
+ if (ui->checkBoxHidden)
+ rc |= QDir::Hidden | QDir::System;
+ QDir::Filters mask = 0;
+ if (ui->checkBoxWritable->isChecked())
+ mask |= QDir::Writable;
+ if (ui->checkBoxReadable->isChecked())
+ mask |= QDir::Readable;
+ if (ui->checkBoxExecutable->isChecked())
+ mask |= QDir::Executable;
+ if (mask == 0)
+ mask |= QDir::PermissionMask;
+ rc |= mask;
+ return rc;
+}
+
/**
* Handles the "search" button.
*/
finder.setYoungerThan(comboDate(ui->comboBoxYounger));
finder.setMinDepth(comboInt(ui->comboBoxMinDepth, 0));
finder.setMaxDepth(comboInt(ui->comboBoxMaxDepth, -1));
+ finder.setFiletypes(buildFileTypes());
QStringList patterns;
QString value = ui->comboBoxFilePatterns->currentText();
if (!value.isEmpty())
- patterns = value.split(";");
+ patterns = value.split(",");
finder.setPatterns(patterns);
+ value = ui->comboBoxExcludedDirs->currentText();
+ if (value.indexOf('/')>= 0 || value.indexOf('\\') >= 0)
+ guiError(ui->comboBoxExcludedDirs, tr("no path delimiter allowed"));
+ else if (value.indexOf('*')>= 0)
+ guiError(ui->comboBoxExcludedDirs, tr("no patterns allowed. Do not use '*"));
+ else if (!value.isEmpty())
+ patterns = value.split(",");
+ finder.setExcludedDirs(patterns);
if (m_errors == 0){
clock_t start = clock();
finder.fillTable(path, 0, ui->tableWidget);
setStatusMessage(false, msg);
}
}
+/**
+ * Handles the push of the button "select directory".
+ */
+void MainWindow::selectDirectory(){
+ QString dir = QFileDialog::getExistingDirectory(this,
+ tr("Select Directory"), ui->comboBoxDirectory->currentText(),
+ QFileDialog::ShowDirsOnly| QFileDialog::DontResolveSymlinks);
+ if (! dir.isEmpty())
+ ui->comboBoxDirectory->setCurrentText(dir);
+}
/**
* @brief Sets a text in a combobox uses as history.
private slots:
void search();
void up();
+ void selectDirectory();
+
private:
+ QDir::Filters buildFileTypes();
QDateTime comboDate(QComboBox* combo);
int comboInt(QComboBox* combo, int defaultValue);
int64_t comboSize(QComboBox* combo);
</size>
</property>
<property name="currentIndex">
- <number>1</number>
+ <number>0</number>
</property>
<widget class="QWidget" name="tabMain">
<attribute name="title">
<item row="2" column="5" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
- <widget class="QCheckBox" name="checkBox">
+ <widget class="QCheckBox" name="checkBoxFiles">
<property name="minimumSize">
<size>
<width>75</width>
</widget>
</item>
<item>
- <widget class="QCheckBox" name="checkBox_4">
+ <widget class="QCheckBox" name="checkBoxLinks">
<property name="minimumSize">
<size>
<width>75</width>
</widget>
</item>
<item>
- <widget class="QCheckBox" name="checkBox_3">
+ <widget class="QCheckBox" name="checkBoxHidden">
<property name="minimumSize">
<size>
<width>75</width>
</widget>
</item>
<item>
- <widget class="QCheckBox" name="checkBox_5">
+ <widget class="QCheckBox" name="checkBoxWritable">
<property name="minimumSize">
<size>
<width>75</width>
</size>
</property>
<property name="text">
- <string>Specials</string>
+ <string>Write</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="checkBoxReadable">
+ <property name="text">
+ <string>Read</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="checkBoxExecutable">
+ <property name="text">
+ <string>Exec.</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
</property>
</widget>
</item>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="comboBoxFilePatterns">
+ <property name="toolTip">
+ <string><html><head/><body><p>a comma (',') separated list of filename patterns</p><p>Example: *.txt,*.odt</p></body></html></string>
+ </property>
<property name="editable">
<bool>true</bool>
</property>
<widget class="QCheckBox" name="checkBoxRegExpr">
<property name="minimumSize">
<size>
- <width>157</width>
+ <width>130</width>
<height>0</height>
</size>
</property>
<height>16777215</height>
</size>
</property>
+ <property name="toolTip">
+ <string>change to parent directory</string>
+ </property>
<property name="text">
- <string>Up</string>
+ <string>⇑</string>
</property>
</widget>
</item>
<height>16777215</height>
</size>
</property>
+ <property name="toolTip">
+ <string>select directory by a dialog box</string>
+ </property>
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item row="2" column="2">
- <widget class="QCheckBox" name="checkBox_2">
+ <widget class="QCheckBox" name="checkBoxDirs">
<property name="text">
<string>Files</string>
</property>
<attribute name="title">
<string>Size, Date, Depth, Excluded Dirs</string>
</attribute>
- <widget class="QWidget" name="">
+ <widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>10</x>
</item>
<item row="2" column="1" colspan="3">
<widget class="QComboBox" name="comboBoxExcludedDirs">
+ <property name="toolTip">
+ <string><html><head/><body><p>a comma (',') separated list of directory names not entered for the search</p><p>Example: .git,.cache</p></body></html></string>
+ </property>
<property name="editable">
<bool>true</bool>
</property>
<tabstop>pushButtonUp</tabstop>
<tabstop>pushButtonDirectory</tabstop>
<tabstop>comboBoxFilePatterns</tabstop>
- <tabstop>checkBox_2</tabstop>
- <tabstop>checkBox</tabstop>
- <tabstop>checkBox_4</tabstop>
- <tabstop>checkBox_3</tabstop>
- <tabstop>checkBox_5</tabstop>
+ <tabstop>checkBoxDirs</tabstop>
+ <tabstop>checkBoxFiles</tabstop>
+ <tabstop>checkBoxLinks</tabstop>
+ <tabstop>checkBoxHidden</tabstop>
+ <tabstop>checkBoxWritable</tabstop>
<tabstop>comboBoxTextPattern</tabstop>
<tabstop>checkBoxTextIgnoreCase</tabstop>
<tabstop>checkBoxRegExpr</tabstop>