--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>AboutDialog</class>
+ <widget class="QDialog" name="AboutDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>225</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>About</string>
+ </property>
+ <widget class="QTextEdit" name="textEdit">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>20</y>
+ <width>351</width>
+ <height>141</height>
+ </rect>
+ </property>
+ <property name="html">
+ <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;">
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">ReFind</span> for searching files in a directory tree</p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">This is a program of the project &quot;<span style=" font-weight:600;">Re</span>al <span style=" font-weight:600;">Pub</span>lic <span style=" font-weight:600;">Lib</span>rary&quot;.</p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Sources are public domain and available under https://github.com/republib</p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Implemented in QT (C++) 5.x</p></body></html></string>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="pushButton">
+ <property name="geometry">
+ <rect>
+ <x>280</x>
+ <y>180</y>
+ <width>93</width>
+ <height>27</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&OK</string>
+ </property>
+ </widget>
+ <action name="action_OK">
+ <property name="text">
+ <string>&OK</string>
+ </property>
+ </action>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>action_OK</sender>
+ <signal>triggered()</signal>
+ <receiver>AboutDialog</receiver>
+ <slot>close()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>-1</x>
+ <y>-1</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>199</x>
+ <y>112</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
--- /dev/null
+/*
+ * Licence:
+ * You can use and modify this file without any restriction.
+ * There is no warranty.
+ * You also can use the licence from http://www.wtfpl.net/.
+ * The original sources can be found on https://github.com/republib.
+ */
+
+#include "aboutdialog.hpp"
+#include "ui_aboutdialog.h"
+
+AboutDialog::AboutDialog(QWidget *parent) :
+ QDialog(parent), ui(new Ui::AboutDialog){
+ ui->setupUi(this);
+}
+
+AboutDialog::~AboutDialog(){
+ delete ui;
+}
--- /dev/null
+/*
+ * Licence:
+ * You can use and modify this file without any restriction.
+ * There is no warranty.
+ * You also can use the licence from http://www.wtfpl.net/.
+ * The original sources can be found on https://github.com/republib.
+ */
+
+#ifndef ABOUTDIALOG_HPP
+#define ABOUTDIALOG_HPP
+
+#include <QDialog>
+
+namespace Ui {
+class AboutDialog;
+}
+
+class AboutDialog: public QDialog {
+ Q_OBJECT
+
+public:
+ explicit AboutDialog(QWidget *parent = 0);
+ ~AboutDialog();
+
+private:
+ Ui::AboutDialog *ui;
+};
+
+#endif // ABOUTDIALOG_HPP
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>AboutDialog</class>
+ <widget class="QDialog" name="AboutDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>218</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <widget class="QTextEdit" name="textEdit">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>20</y>
+ <width>351</width>
+ <height>141</height>
+ </rect>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ <property name="html">
+ <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;">
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">ReFind</span> for searching files in a directory tree</p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">This is a program of the project &quot;<span style=" font-weight:600;">Re</span>al <span style=" font-weight:600;">Pub</span>lic <span style=" font-weight:600;">Lib</span>rary&quot;.</p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Sources are public domain and available under https://github.com/republib</p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Implemented in QT (C++) 5.x</p></body></html></string>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="pushButtonOK">
+ <property name="geometry">
+ <rect>
+ <x>150</x>
+ <y>170</y>
+ <width>93</width>
+ <height>27</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&OK</string>
+ </property>
+ </widget>
+ <action name="actionOk">
+ <property name="text">
+ <string>&Ok</string>
+ </property>
+ <property name="toolTip">
+ <string>Close the dialog</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+X</string>
+ </property>
+ </action>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>actionOk</sender>
+ <signal>triggered()</signal>
+ <receiver>AboutDialog</receiver>
+ <slot>close()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>-1</x>
+ <y>-1</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>199</x>
+ <y>108</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
#include "base/rebase.hpp"
#include "mainwindow.hpp"
#include "filefinder.hpp"
+#include "textfinder.hpp"
/**
* Constructor.
m_countFiles(0),
m_countDirs(0),
m_bytes(0),
- m_excludedDirs(){
+ m_excludedDirs(),
+ m_textFinder(NULL){
m_youngerThan.setMSecsSinceEpoch(0);
m_olderThan.setMSecsSinceEpoch(0);
}
+FileFinder::~FileFinder(){
+}
/**
* Returns the sum of sizes of the found files.
return rc;
}
+/**
+ * Sets the text finder parameter template.
+ *
+ * @param textFinder the text finder instance containing the search parameter
+ */
+void FileFinder::setTextFinder(TextFinder* textFinder){
+ m_textFinder = textFinder;
+}
+
/**
* Fills the table with the data of the filtered files of a given directory.
*
QList <QFileInfo>::iterator it;
QString relativePath = path.mid(1 + m_baseDir.length());
QString node, ext;
+
for (it = entries.begin(); it != entries.end(); ++it){
node = it->fileName();
if (node == "." || node == "..")
if (rc)
rc = m_olderThan.toMSecsSinceEpoch() == 0 || date <= m_olderThan;
}
+ if (rc && m_textFinder != NULL){
+ QString full = file.absoluteFilePath();
+ TextFinder textFinder(full, file.size());
+ textFinder.getSearchParameter(*m_textFinder);
+ rc = textFinder.contains();
+ }
return rc;
}
void FileFinder::setMaxDepth(int maxDepth){
m_maxDepth = maxDepth;
}
-/**
- * Sets the minimum subdirectory depth.
- *
- * @param minDepth 0: search in the base directory too<br>
- * otherwise: the minimum depth
- */
-void FileFinder::setMinDepth(int minDepth){
- m_minDepth = minDepth;
-}
/**
* Sets the maximum size.
m_maxSize = maxSize;
}
+/**
+ * Sets the minimum subdirectory depth.
+ *
+ * @param minDepth 0: search in the base directory too<br>
+ * otherwise: the minimum depth
+ */
+void FileFinder::setMinDepth(int minDepth){
+ m_minDepth = minDepth;
+}
+
/**
* Sets the minimum size.
*
#include <QDir>
#include <QDateTime>
+class TextFinder;
class FileFinder {
public:
FileFinder();
+ ~FileFinder();
public:
int64_t bytes() const;
void clear();
void fillTable(const QString& path, int depth, QTableWidget* table);
void setBaseDir(const QString& baseDir);
void setFiletypes(const QDir::Filters& filetypes);
+ void setExcludedDirs(const QStringList& excludedDirs);
void setMaxDepth(int maxDepth);
+ void setMaxSize(const int64_t& maxSize);
void setMinDepth(int minDepth);
- void setExcludedDirs(const QStringList& excludedDirs);
+ void setMinSize(const int64_t& minSize);
void setOlderThan(const QDateTime& olderThan);
void setPatterns(const QStringList& patterns);
- void setMaxSize(const int64_t& maxSize);
- void setMinSize(const int64_t& minSize);
+ void setTextFinder(TextFinder* textFinder);
void setYoungerThan(const QDateTime& youngerThan);
private:
int m_countDirs;
int64_t m_bytes;
QStringList m_excludedDirs;
+ // Only used to hold the search parameters:
+ TextFinder* m_textFinder;
};
#endif // FILEFINDER_HPP
#include <QDir>
#include <QFileDialog>
#include "base/rebase.hpp"
+#include "textfinder.hpp"
#include "mainwindow.hpp"
#include "ui_mainwindow.h"
#include "filefinder.hpp"
+#include "aboutdialog.hpp"
/**
* @brief Constructor.
ui(new Ui::MainWindow),
m_statusMessage(NULL),
m_stdLabelBackgroundRole(NULL),
- m_errors(0){
+ m_errors(0),
+ m_textFinder(){
ui->setupUi(this);
m_statusMessage = new QLabel(tr("Willkommen bei refind"));
ui->comboBoxDirectory->setCurrentText(
startDir.isEmpty() ? QDir::currentPath() : startDir);
statusBar()->addWidget(m_statusMessage);
+ connect(ui->actionSearch, SIGNAL(triggered()), this, SLOT(search()));
connect(ui->pushButtonSearch, SIGNAL(clicked()), this, SLOT(search()));
connect(ui->pushButtonSearch2, SIGNAL(clicked()), this, SLOT(search()));
+ connect(ui->actionUp, SIGNAL(triggered()), this, SLOT(up()));
connect(ui->pushButtonUp, SIGNAL(clicked()), this, SLOT(up()));
+ connect(ui->actionSelectDirectory, SIGNAL(triggered()), this,
+ SLOT(selectDirectory()));
connect(ui->pushButtonDirectory, SIGNAL(clicked()), this,
SLOT(selectDirectory()));
+ connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(about()));
ui->tableWidget->setColumnWidth(TC_NODE, 200);
ui->tableWidget->setColumnWidth(TC_EXT, 40);
ui->tableWidget->setColumnWidth(TC_SIZE, 125);
MainWindow::~MainWindow(){
delete ui;
}
+
+/**
+ * Starts the about dialog.
+ */
+void MainWindow::about(){
+ AboutDialog dialog;
+ dialog.setModal(true);
+ dialog.show();
+}
+
/**
* Returns the date given as formula in a combobox.
*
return rc;
}
+/**
+ * Prepares the text search.
+ */
+void MainWindow::prepareTextFind(){
+ m_textFinder.setSearchParameter(ui->comboBoxTextPattern->currentText(),
+ ui->checkBoxTextIgnoreCase->isChecked(), ui->checkBoxRegExpr,
+ !ui->checkBoxBinaryFiles);
+ QString error = m_textFinder.regExprError();
+ if (!error.isEmpty()){
+ guiError(ui->comboBoxTextPattern, error);
+ }
+}
+
/**
* Handles the "search" button.
*/
else if (!value.isEmpty())
patterns = value.split(",");
finder.setExcludedDirs(patterns);
+ prepareTextFind();
if (m_errors == 0){
+ if (!ui->comboBoxTextPattern->currentText().isEmpty())
+ finder.setTextFinder(&m_textFinder);
clock_t start = clock();
finder.fillTable(path, 0, ui->tableWidget);
QString msg;
#include <QComboBox>
#include <QLabel>
#include <QDir>
-
+#if ! defined TEXTFINDER_HPP
+#include "textfinder.hpp"
+#endif
namespace Ui {
class MainWindow;
}
~MainWindow();
private slots:
+ void about();
void search();
void up();
void selectDirectory();
int64_t comboSize(QComboBox* combo);
QString comboText(QComboBox* combo);
void guiError(QWidget* widget, const QString& message);
+ void prepareTextFind();
void setInHistory(QComboBox* combo, const QString& value);
void setStatusMessage(bool error, const QString& message);
private:
QLabel* m_statusMessage;
QPalette::ColorRole* m_stdLabelBackgroundRole;
int m_errors;
+ TextFinder m_textFinder;
};
#endif // MAINWINDOW_HPP
<string>Execute the search</string>
</property>
<property name="text">
- <string>Search</string>
+ <string>&Search</string>
</property>
<property name="shortcut">
<string>Ctrl+F</string>
<item row="2" column="4" colspan="2">
<widget class="QPushButton" name="pushButtonSearch2">
<property name="text">
- <string>Search</string>
+ <string>&Search</string>
</property>
</widget>
</item>
<x>0</x>
<y>0</y>
<width>1030</width>
- <height>26</height>
+ <height>23</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
<property name="title">
- <string>File</string>
+ <string>&File</string>
</property>
<addaction name="actionSearch"/>
<addaction name="separator"/>
<addaction name="actionExport"/>
<addaction name="separator"/>
+ <addaction name="separator"/>
<addaction name="actionExit"/>
<addaction name="separator"/>
</widget>
<widget class="QMenu" name="menuHelp">
<property name="title">
- <string>Help</string>
+ <string>&Help</string>
</property>
- <addaction name="actionAbout_2"/>
+ <addaction name="actionAbout"/>
+ </widget>
+ <widget class="QMenu" name="menuNavigation">
+ <property name="title">
+ <string>&Navigate</string>
+ </property>
+ <addaction name="actionUp"/>
+ <addaction name="actionSelectDirectory"/>
</widget>
<addaction name="menuFile"/>
+ <addaction name="menuNavigation"/>
<addaction name="menuHelp"/>
</widget>
<widget class="QToolBar" name="mainToolBar">
<widget class="QStatusBar" name="statusBar"/>
<action name="actionExit">
<property name="text">
- <string>Exit</string>
+ <string>E&xit</string>
</property>
<property name="toolTip">
<string>Exits the program</string>
</action>
<action name="actionSearch">
<property name="text">
- <string>Search</string>
+ <string>&Search</string>
</property>
<property name="toolTip">
<string>Search the files with the given properties</string>
</action>
<action name="actionAbout">
<property name="text">
- <string>About</string>
+ <string>&About</string>
</property>
- <property name="toolTip">
- <string>Informs about the author</string>
+ <property name="shortcut">
+ <string>Ctrl+A</string>
+ </property>
+ </action>
+ <action name="actionExport">
+ <property name="text">
+ <string>&Export</string>
</property>
<property name="shortcut">
- <string>Space</string>
+ <string>Ctrl+E</string>
</property>
</action>
- <action name="actionAbout_2">
+ <action name="actionUp">
<property name="text">
- <string>About</string>
+ <string>&Up</string>
+ </property>
+ <property name="toolTip">
+ <string>Change to the parent directory</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+U</string>
</property>
</action>
- <action name="actionExport">
+ <action name="actionSelectDirectory">
<property name="text">
- <string>Export</string>
+ <string>&Select directory</string>
+ </property>
+ <property name="toolTip">
+ <string>Select directory with a dialog</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+D</string>
</property>
</action>
</widget>
../../base/ReQStringUtil.cpp \
../../base/ReLogger.cpp \
filefinder.cpp \
- textfinder.cpp
+ textfinder.cpp \
+ aboutdialog.cpp
HEADERS += mainwindow.hpp \
../../base/rebase.hpp \
filefinder.hpp \
../../base/ReQStringUtil.hpp \
- textfinder.hpp
+ textfinder.hpp \
+ aboutdialog.hpp
-FORMS += mainwindow.ui
+FORMS += mainwindow.ui \
+ aboutdialog.ui
/**
* Constructor.
- *
- * @param fullName path and name of the file
- * @param length length of the file
- * @param ignoreBinary <code>true</code>: binary files will be ignored
*/
-TextFinder::TextFinder(const QString& fullName, int64_t length,
- bool ignoreBinary) :
- m_ignoreBinary(ignoreBinary),
+TextFinder::TextFinder() :
+ m_ignoreBinary(false),
+ m_filename(),
+ m_length(0),
+ m_file(),
+ m_valid(false),
+ m_regExpr(NULL),
+ m_isRegExpr(false),
+ m_ignoreCase(false),
+ m_ownsRegExpr(false),
+ m_text(){
+}
+
+TextFinder::TextFinder(const QString& fullName, int64_t length) :
+ m_ignoreBinary(false),
m_filename(fullName),
m_length(length),
m_file(fullName),
- m_valid(false){
+ m_valid(false),
+ m_regExpr(NULL),
+ m_isRegExpr(false),
+ m_ignoreCase(false),
+ m_ownsRegExpr(false),
+ m_text(){
m_valid = m_file.open(QIODevice::ReadOnly);
}
* @param isRegular <code>true</code>: the pattern is a regular expression
* @return <code>true</code>: the patter was found
*/
-bool TextFinder::contains(const QString& pattern, bool ignoreCase,
- bool isRegular){
+bool TextFinder::contains(){
bool rc = false;
if (!m_ignoreBinary || !isBinary()){
m_file.seek(0);
QTextStream stream(&m_file);
QString line;
- if (isRegular){
- QRegularExpression::PatternOption option =
- ignoreCase ?
- QRegularExpression::CaseInsensitiveOption :
- QRegularExpression::NoPatternOption;
- QRegularExpression expr(pattern, option);
+ if (m_regExpr != NULL){
QRegularExpressionMatch match;
while (!stream.atEnd()){
line = stream.readLine();
- match = expr.match(line);
+ match = m_regExpr->match(line);
if (match.hasMatch()){
rc = true;
break;
}
}else{
Qt::CaseSensitivity mode =
- ignoreCase ? Qt::CaseInsensitive : Qt::CaseSensitive;
+ m_ignoreCase ? Qt::CaseInsensitive : Qt::CaseSensitive;
while (!stream.atEnd()){
line = stream.readLine();
- if (line.indexOf(pattern, 0, mode) >= 0){
+ if (line.indexOf(m_text, 0, mode) >= 0){
rc = true;
break;
}
return rc;
}
+/**
+ * Gets the search specific parameters from another instance.
+ *
+ * @param source the source of the parameter
+ */
+void TextFinder::getSearchParameter(const TextFinder& source){
+ m_ignoreBinary = source.m_ignoreBinary;
+ m_regExpr = source.m_regExpr;
+ m_isRegExpr = source.m_isRegExpr;
+ m_ignoreCase = source.m_ignoreCase;
+}
+
/**
* Tests whether the file is a binary file.
*
return m_valid;
}
+/**
+ * Set the search parameters.
+ *
+ * @param text the text to search
+ * @param ignoreCase <code>true</code>: the search is case insensitive
+ * @param isRegExpr <code>true</code>: the search uses a regular expression
+ * @param ignoreBinary <code>true</code>: binary files will not processed
+ */
+void TextFinder::setSearchParameter(const QString& text, bool ignoreCase,
+ bool isRegExpr, bool ignoreBinary){
+ m_text = text;
+ m_ignoreCase = ignoreCase;
+ m_isRegExpr = isRegExpr;
+ m_ignoreBinary = ignoreBinary;
+ if (isRegExpr && !text.isEmpty()){
+ QRegularExpression::PatternOption option =
+ ignoreCase ?
+ QRegularExpression::CaseInsensitiveOption :
+ QRegularExpression::NoPatternOption;
+ m_ownsRegExpr = true;
+ m_regExpr = new QRegularExpression(text, option);
+ }
+}
+
+/**
+ * Returns the error text of a wrong regular expression.
+ *
+ * @return "": the regular expression is correct.
+ * otherwise: the error message
+ */
+QString TextFinder::regExprError(){
+ QString rc;
+ if (m_regExpr != NULL && m_regExpr->isValid())
+ rc = m_regExpr->errorString();
+ return rc;
+}
+
#ifndef TEXTFINDER_HPP
#define TEXTFINDER_HPP
+#include <QRegularExpression>
class TextFinder {
public:
- TextFinder(const QString& fullName, int64_t length, bool ignoreBinary);
+ TextFinder();
+ TextFinder(const QString& fullName, int64_t length);
~TextFinder();
public:
- bool contains(const QString& pattern, bool ignoreCase, bool isRegular);
+ void getSearchParameter(const TextFinder& source);
+ bool contains();
bool isBinary();
bool isText(const QByteArray& data, bool* trueAscii = NULL);
bool isUTF8(const QByteArray& data, bool* trueAscii) const;
bool isValid() const;
-
+ void setSearchParameter(const QString& text, bool ignoreCase, bool isRegExpr,
+ bool ignoreBinary);
+ QString regExprError();
private:
bool m_ignoreBinary;
QString m_filename;
int64_t m_length;
QFile m_file;
bool m_valid;
+ QRegularExpression* m_regExpr;
+ bool m_isRegExpr;
+ bool m_ignoreCase;
+ bool m_ownsRegExpr;
+ QString m_text;
};
#endif // TEXTFINDER_HPP