*/
void FileCache::remove(const QString &filename)
{
+ FileCacheItem* item = m_cache.value(filename);
+ delete item;
m_cache.remove(filename);
}
* @param table table containing the files
* @param list list widget to store the filtered lines
*/
-FileFilter::FileFilter(QTableWidget &table, QListWidget &list, FileCache& cache) :
+FileFilter::FileFilter(QTableWidget &table, QListWidget &list, FileCache& cache,
+ HitPosition& lastHitPosition) :
m_table(table),
m_list(list),
m_cache(cache),
m_fromHit(0),
m_toHit(0),
m_linesAbove(0),
- m_linesBelow(0)
-
+ m_linesBelow(0),
+ m_lastHitPosition(lastHitPosition)
{
}
+/**
+ * Destructor.
+ */
+FileFilter::~FileFilter()
+{
+ delete m_excludeExpr;
+ delete m_includeExpr;
+ m_includeExpr = m_excludeExpr = NULL;
+}
+
/**
* Puts all filtered lines from the files in the table into the list.
*
hitNo = filterOneFile(full, hitNo);
}
+ if (hitNo <= toHit){
+ m_lastHitPosition.m_hitCount = m_lastHitPosition.m_hitNo;
+ }
}
/**
* Filters the lines of one file.
*
- * @param filename filename with path
- * @param lastHit the last found hit in the previous files
+ * @param filename filename with path
+ * @param lastHit the last found hit in the previous files
* @return the number of hits including the hits in the file
*/
int FileFilter::filterOneFile(const QString& filename, int lastHit)
m_cache.addOrUpdate(filename);
const QStringList& lines = m_cache.lines(filename);
- int lineNo = 0;
+ int lineNo = -1;
int lastLine = -1;
- int count = lines.size();
+ int lastIx = lines.size() - 1;
QString prefixHit = filename + "-";
QString prefixOther = prefixHit;
if (m_linesAbove + m_linesBelow > 0){
prefixHit = ">" + prefixHit;
prefixOther = " " + prefixOther;
}
- while(lastHit <= m_toHit && lineNo < count){
- QString line = lines[lineNo++];
+ bool first = true;
+ if (m_lastHitPosition.m_filename == filename
+ && m_fromHit + 1 == m_lastHitPosition.m_hitNo){
+ // we start from the stored position
+ first = false;
+ lastHit = m_lastHitPosition.m_hitNo;
+ lineNo = m_lastHitPosition.m_line;
+ }
+ while(lastHit <= m_toHit && lineNo < lastIx){
+ QString line = lines[++lineNo];
if (m_includeExpr != NULL && ! m_includeExpr->match(line).hasMatch())
continue;
if (m_excludeExpr != NULL && m_excludeExpr->match(line).hasMatch())
continue;
- if (++lastHit >= m_fromHit){
+ if (first){
+ m_lastHitPosition.m_filename = filename;
+ first = false;
+ }
+ m_lastHitPosition.m_line = lineNo;
+ m_lastHitPosition.m_hitNo = ++lastHit;
+ if (lastHit >= m_fromHit){
for (int ix = max(lastLine + 1, max(0, lineNo - m_linesAbove));
- ix <= min(lineNo + m_linesBelow, count - 1);
+ ix <= min(lineNo + m_linesBelow, lastIx);
ix++){
m_list.addItem((ix == lineNo ? prefixHit : prefixOther)
+ QString::number(ix + 1) + ": " + lines[ix]);
#define FILEFILTER_H
+class HitPosition {
+public:
+ HitPosition() :
+ m_filename(),
+ m_line(0),
+ m_hitNo(0),
+ m_hitCount(-1)
+ {}
+public:
+ QString m_filename;
+ int m_line;
+ int m_hitNo;
+ int m_hitCount;
+};
+
class FileFilter
{
public:
- FileFilter(QTableWidget& table, QListWidget& list, FileCache& cache);
+ FileFilter(QTableWidget& table, QListWidget& list, FileCache& cache,
+ HitPosition& lastHitPosition);
+ virtual ~FileFilter();
public:
void filter(const QString& includePattern, const QString& excludePattern,
int fromHit, int toHit, int linesAbove, int linesBelow,
int m_toHit;
int m_linesAbove;
int m_linesBelow;
+ HitPosition& m_lastHitPosition;
};
#endif // FILEFILTER_H
*/
FileFinder::~FileFinder()
{
-
+ delete m_regularExpression;
+ delete m_text;
+ m_regularExpression = NULL;
+ m_text = NULL;
}
/**
bool FileFinder::handleFile(const QString &full, const QString &path,
const QString &node, const QFileInfo& info)
{
- bool found = false;
+ bool found = true;
if (m_regularExpression != NULL){
found = searchWithRegExpr(full);
} else if (m_text != NULL){
m_cache.addOrUpdate(filename);
const QStringList& lines = m_cache.lines(filename);
bool rc = false;
- if (m_caseSensitive){
- if (m_inverseSearch){
- rc = true;
- for (int ix = 0; ix < lines.size(); ++ix){
- if (lines[ix].indexOf(m_text) < 0){
- rc = false;
- break;
- }
- }
- } else {
- rc = false;
- for (int ix = 0; ix < lines.size(); ++ix){
- if (lines[ix].indexOf(m_text) >= 0){
- rc = true;
- break;
- }
- }
- }
+ Qt::CaseSensitivity mode = m_caseSensitive
+ ? Qt::CaseSensitive : Qt::CaseInsensitive;
+ if (m_inverseSearch){
+ rc = true;
+ for (int ix = 0; ix < lines.size(); ++ix){
+ if (lines[ix].indexOf(m_text, mode) >= 0){
+ rc = false;
+ break;
+ }
+ }
} else {
- if (m_inverseSearch){
-
- } else {
-
+ rc = false;
+ for (int ix = 0; ix < lines.size(); ++ix){
+ if (lines[ix].indexOf(m_text, mode) >= 0){
+ rc = true;
+ break;
+ }
}
}
if (! rc)
ui(new Ui::MainWindow),
m_fileFinder(NULL),
m_fileCache(new FileCache()),
- m_test(true)
+ m_test(true),
+ m_lastHitPosition(new HitPosition())
{
ReComboBox::setDefaultHistorySize(20);
initializeGui();
delete ui;
delete m_fileCache;
delete m_fileFinder;
+ delete m_lastHitPosition;
}
/**
connect(ui->pushButtonClear, SIGNAL(clicked()), this, SLOT(onClear()));
connect(ui->pushButtonFilter, SIGNAL(clicked()), this, SLOT(onFilter()));
connect(ui->pushButtonDetach, SIGNAL(clicked()), this, SLOT(onDetach()));
+ connect(ui->pushButtonPrevious, SIGNAL(clicked()), this, SLOT(onPrevious()));
+ connect(ui->pushButtonNext, SIGNAL(clicked()), this, SLOT(onNext()));
+ connect(ui->comboBoxExcludingPattern, SIGNAL(textEdited(QString,QString)),
+ this, SLOT(clearLastHitPosition(const QString&, const QString&)));
+ connect(ui->comboBoxIncludingPattern, SIGNAL(textEdited(QString,QString)),
+ this, SLOT(clearLastHitPosition(const QString&, const QString&)));
+ connect(ui->comboBoxLinesAbove, SIGNAL(textEdited(QString,QString)),
+ this, SLOT(clearLastHitPosition(const QString&, const QString&)));
+ connect(ui->comboBoxLinesBelow, SIGNAL(textEdited(QString,QString)),
+ this, SLOT(clearLastHitPosition(const QString&, const QString&)));
delete m_fileFinder;
m_fileFinder = new FileFinder(*ui->tableWidget, *m_fileCache);
if (m_test){
ui->comboBoxBaseDirectory->setCurrentText("/etc");
ui->comboBoxFilePatterns->setCurrentText("*asu*");
- ui->comboBoxIncludingPattern->setCurrentText("e");
+ ui->comboBoxIncludingPattern->setCurrentText("#!");
onAdd();
}
}
+void MainWindow::clearLastHitPosition(const QString&, const QString&)
+{
+ m_lastHitPosition->m_filename.clear();
+ m_lastHitPosition->m_hitCount = -1;
+ m_lastHitPosition->m_hitNo = -1;
+}
+
/**
* Shows the "about" window.
*/
*/
void MainWindow::onFilter()
{
- FileFilter filter(*ui->tableWidget, *ui->listWidgetHits, *m_fileCache);
+ FileFilter filter(*ui->tableWidget, *ui->listWidgetHits, *m_fileCache,
+ *m_lastHitPosition);
int from = comboboxToInt(*ui->comboBoxFromHit, 0);
int to = comboboxToInt(*ui->comboBoxToHit, from + 100);
int above = comboboxToInt(*ui->comboBoxLinesAbove, 0);
initializeGui();
}
+/**
+ * Shows the next page of filtered lines.
+ */
+void MainWindow::onNext()
+{
+ int first = comboInt(ui->comboBoxFromHit, 1);
+ int last = comboInt(ui->comboBoxToHit, first + 100);
+ int pageSize = last - first + 1;
+ first = first + pageSize;
+ ui->comboBoxFromHit->setCurrentText(QString::number(first));
+ ui->comboBoxToHit->setCurrentText(QString::number(first + pageSize - 1));
+ onFilter();
+}
+/**
+ * Shows the previous page of filtered lines.
+ */
+void MainWindow::onPrevious()
+{
+ int first = comboInt(ui->comboBoxFromHit, 1);
+ int last = comboInt(ui->comboBoxToHit, first + 100);
+ int pageSize = last - first + 1;
+ first = max(1, first - pageSize);
+ ui->comboBoxFromHit->setCurrentText(QString::number(first));
+ ui->comboBoxToHit->setCurrentText(QString::number(first + pageSize - 1));
+ onFilter();
+}
+
/**
* Handles the push of the button "select directory".
*/
} else {
QDateTime olderThan = comboDate(ui->comboBoxOlder);
QDateTime youngerThan = comboDate(ui->comboBoxYounger);
- m_fileFinder->setOlderThan(olderThan.currentMSecsSinceEpoch() <= 0
+ m_fileFinder->setOlderThan(olderThan.toMSecsSinceEpoch() <= 0
? NULL : new QDateTime(olderThan));
- m_fileFinder->setYoungerThan(olderThan.currentMSecsSinceEpoch() <= 0
+ m_fileFinder->setYoungerThan(olderThan.toMSecsSinceEpoch() <= 0
? NULL : new QDateTime(youngerThan));
m_fileFinder->setTextToSearch(ui->comboBoxTextPattern->currentText(),
ui->checkBoxCaseSensitiv->isChecked(),
class FileFinder;
class FileCache;
+class HitPosition;
namespace Ui {
class MainWindow;
}
virtual void onLanguageChange();
void searchFiles(bool addNotDetach);
private slots:
+ void clearLastHitPosition(const QString &, const QString &);
void onAbout();
void onAdd();
void onClear();
void onDetach();
void onFilter();
+ void onNext();
+ void onPrevious();
void onSelectBaseDirectory();
void textEdited(const QString& oldString, const QString& newString);
private:
FileFinder* m_fileFinder;
FileCache* m_fileCache;
bool m_test;
+ HitPosition* m_lastHitPosition;
};
#endif // MAINWINDOW_H
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
- <number>0</number>
+ <number>1</number>
</property>
<widget class="QWidget" name="tabFiles">
<attribute name="title">
<string notr="true"/>
</property>
</widget>
- <widget class="QWidget" name="">
+ <widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>19</x>
<property name="autoDefault">
<bool>true</bool>
</property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
</widget>
</item>
<item>
<height>16777215</height>
</size>
</property>
+ <property name="toolTip">
+ <string>Show the previous page of hits</string>
+ </property>
<property name="text">
<string notr="true"><</string>
</property>
<height>16777215</height>
</size>
</property>
+ <property name="toolTip">
+ <string>Show the next page of hits</string>
+ </property>
<property name="text">
- <string>></string>
+ <string notr="true">></string>
</property>
</widget>
</item>
<bool>true</bool>
</property>
<property name="currentText">
- <string>0</string>
+ <string notr="true">1</string>
</property>
</widget>
</item>
<bool>true</bool>
</property>
<property name="currentText">
- <string>100</string>
+ <string notr="true">10</string>
</property>
</widget>
</item>
*/
ReFileSearch::ReFileSearch() :
m_minDepth(0),
- m_maxDepth(9999),
+ m_maxDepth(100),
m_searchMode(smFilesAndDirs),
m_matcher(),
m_processedDirs(0),
*/
ReFileSearch::~ReFileSearch()
{
+ delete m_youngerThan;
+ delete m_olderThan;
+ m_youngerThan = m_olderThan = NULL;
}
/**
full += OS_SEPARATOR;
full += node;
QFileInfo info(full);
+ QDateTime current = info.lastModified();
if (m_olderThan != NULL && info.lastModified() > *m_olderThan)
continue;
if (m_youngerThan != NULL && info.lastModified() < *m_youngerThan)
*/
void ReFileSearch::setOlderThan(QDateTime *olderThan)
{
+ delete m_olderThan;
m_olderThan = olderThan;
}
*/
void ReFileSearch::setYoungerThan(QDateTime *youngerThan)
{
+ delete m_youngerThan;
m_youngerThan = youngerThan;
}
const char* mode) {
FILE* fp = fopen(file, mode);
if (fp != NULL) {
- fputs(content, fp);
+ if (content != NULL)
+ fputs(content, fp);
fclose(fp);
}
return fp != NULL;
setPatterns("*.txt,-*1*,-*2*,-*4*,-file5.txt,dir*,-dir2");
setMinDepth(1);
setMaxDepth(3);
+ setOlderThan(NULL);
+ setYoungerThan(NULL);
setSearchMode(smFilesAndDirs);
oneDirectory(m_baseDir, 0);
checkEqu(4, m_found.size());
checkT(m_found.contains("dir1/dir2/dir3"));
}
+ void testYoungerThan(){
+ m_found.clear();
+ setPatterns("file2.txt");
+ setMinDepth(0);
+ setMaxDepth(2);
+ setSearchMode(smFiles);
+ setOlderThan(NULL);
+
+ setYoungerThan(NULL);
+ oneDirectory(m_baseDir, 0);
+ checkEqu(3, m_found.size());
+ checkT(m_found.contains("file2.txt"));
+ checkT(m_found.contains("dir1/file2.txt"));
+ checkT(m_found.contains("dir1/dir2/file2.txt"));
+
+ QDateTime now = QDateTime::currentDateTime();
+
+ m_found.clear();
+ setYoungerThan(new QDateTime(now.addDays(-1)));
+ oneDirectory(m_baseDir, 0);
+ checkEqu(3, m_found.size());
+ checkT(m_found.contains("file2.txt"));
+ checkT(m_found.contains("dir1/file2.txt"));
+ checkT(m_found.contains("dir1/dir2/file2.txt"));
+
+ m_found.clear();
+ setYoungerThan(new QDateTime(now.addDays(1)));
+ oneDirectory(m_baseDir, 0);
+ checkEqu(0, m_found.size());
+ }
+
+ void testOlderThan(){
+ m_found.clear();
+ setPatterns("*1.txt");
+ setMinDepth(0);
+ setMaxDepth(1);
+ setSearchMode(smFiles);
+ setYoungerThan(NULL);
+ setOlderThan(NULL);
+ oneDirectory(m_baseDir, 0);
+ checkEqu(2, m_found.size());
+ checkT(m_found.contains("file1.txt"));
+ checkT(m_found.contains("dir1/file1.txt"));
+
+ QDateTime now = QDateTime::currentDateTime();
+
+ m_found.clear();
+ setOlderThan(new QDateTime(now.addDays(1)));
+ oneDirectory(m_baseDir, 0);
+ checkEqu(2, m_found.size());
+ checkT(m_found.contains("file1.txt"));
+ checkT(m_found.contains("dir1/file1.txt"));
+
+ m_found.clear();
+ setOlderThan(new QDateTime(now.addDays(-1)));
+ oneDirectory(m_baseDir, 0);
+ checkEqu(0, m_found.size());
+ }
+
virtual bool handleFile(const QString& full, const QString& path,
const QString& node, const QFileInfo& info){
ReUseParameter(info);
virtual void runTests() {
makeTree();
+ testOlderThan();
+ testYoungerThan();
testOneDirectoryDepthExclude();
testBasic();
}
void testReadableDuration(){
#define clf(sec) clock_t(clock_t((sec) * CLOCKS_PER_SEC))
checkEqu("0.000 sec", ReQStringUtils::readableDuration(clf(0.0)));
- checkEqu("1.234 sec", ReQStringUtils::readableDuration(clf(1.234)));
+ QString value = ReQStringUtils::readableDuration(clf(1.234));
+ checkEqu("1.234 sec", value);
checkEqu("59.250 sec", ReQStringUtils::readableDuration(clf(59.250)));
checkEqu("1:01", ReQStringUtils::readableDuration(clf(61.251)));
checkEqu("59:59", ReQStringUtils::readableDuration(clf(59*60+59.499)));