Compare commits

..

No commits in common. "14730ed20819093edec4b2fe8dd30fd7ac5c12ce" and "431abfe7c05ddf21bd5426c9562f60e003063f4a" have entirely different histories.

7 changed files with 25 additions and 208 deletions

View File

@ -1,22 +1,7 @@
# looqs: Release notes # looqs: Release notes
## 2022-08-14 - v0.6
This release features multiple fixes and enhancements.
Bad news first: It drops a trivial trigger that appeared to work quite fine, but silently may cause "unpredictability" of the sqlite FTS5 index ( [9422a5b494](https://github.com/quitesimpleorg/looqs/commit/9422a5b494dabd0f1324dc2f92a34c3036137414) ). As a result, FTS queries may return weird and unexplainable results. This is not reasonably automatically recoverable by looqs. I strongly recommend creating a clean, new database. All previous versions are affected. To do that, go to "Settings" -> checking "Remove old database on save" -> "Save settings and restart". Alternatively, specify a new path to keep the old database.
CHANGES:
- GUI: Add line numbers and context lines to plaintext previews
- GUI: Fix case where previews for old queries would have still been visible if new query would not create previews
- GUI: Add CTRL + F, CTRL+W, CTRL+Tab, CTRL+Shift+Tab shortcuts (see user manual)
- GUI: Add checkbox in "Settings" tab allowing to delete database.
- General: Fix wrong regexes that caused query errors with chars like -
- General: Drop trigger sending incomplete sqlite fts5 deletion command, causing undefined index behaviour
## 2022-07-30 - v0.5.1 ## 2022-07-30 - v0.5.1
CHANGES: CHANGES:
- gui: Fix regression in implicit paths queries introduced in previous version - gui: Fix regression in implicit paths queries introduced in previous version
## 2022-07-29 - v0.5 ## 2022-07-29 - v0.5

View File

@ -1,9 +1,10 @@
# looqs - Full-text search with previews for your files # looqs - Full-text search with previews for your files
looqs is a tool that creates a full-text search index for your files. It allows you to look at previews where your search terms have been found, as shown in the screenshots below. looqs is a tool that creates a full-text search index for your files. It allows you to look at previews where your
search terms have been found, as shown in the screenshots below.
## Screenshots ## Screenshots
### Preview ### Preview
looqs allows you to look inside files. It highlights what you have searched for. looqs allow you to look inside files. It marks what you have searched for.
![Screenshot looqs](https://garage.quitesimple.org/assets/looqs/orwell.png) ![Screenshot looqs](https://garage.quitesimple.org/assets/looqs/orwell.png)
![Screenshot looqs search fstream](https://garage.quitesimple.org/assets/looqs/fstream_write.png) ![Screenshot looqs search fstream](https://garage.quitesimple.org/assets/looqs/fstream_write.png)
@ -28,7 +29,7 @@ There is no need to write the long form of filters. There are also booleans avai
The screenshots in this section may occasionally be slightly outdated, but they are usually recent enough to get an overall impression of the current state of the GUI. The screenshots in this section may occasionally be slightly outdated, but they are usually recent enough to get an overall impression of the current state of the GUI.
## Current status ## Current status
Latest version: 2022-08-14, v0.6 Latest version: 2022-07-30, v0.5.1
Please see [Changelog](CHANGELOG.md) for a human readable list of changes. Please see [Changelog](CHANGELOG.md) for a human readable list of changes.

View File

@ -60,10 +60,6 @@ MainWindow::MainWindow(QWidget *parent, QString socketPath)
QString ignorePatterns = settings.value("ignorePatterns").toString(); QString ignorePatterns = settings.value("ignorePatterns").toString();
ui->txtIgnorePatterns->setText(ignorePatterns); ui->txtIgnorePatterns->setText(ignorePatterns);
QStringList searchHistoryList = settings.value(SETTINGS_KEY_SEARCHHISTORY).toStringList();
this->searchHistory = searchHistoryList.toVector();
this->currentSearchHistoryIndex = this->searchHistory.size();
ui->spinPreviewPage->setValue(1); ui->spinPreviewPage->setValue(1);
ui->spinPreviewPage->setMinimum(1); ui->spinPreviewPage->setMinimum(1);
@ -74,9 +70,6 @@ MainWindow::MainWindow(QWidget *parent, QString socketPath)
policy.setRetainSizeWhenHidden(true); policy.setRetainSizeWhenHidden(true);
ui->btnOpenFailed->setSizePolicy(policy); ui->btnOpenFailed->setSizePolicy(policy);
ui->txtSearch->installEventFilter(this);
ui->scrollArea->viewport()->installEventFilter(this);
this->ipcClientThread.start(); this->ipcClientThread.start();
} }
@ -444,86 +437,6 @@ void MainWindow::processShortcut(int key)
} }
} }
bool MainWindow::eventFilter(QObject *object, QEvent *event)
{
if(object == ui->txtSearch && !searchHistory.empty())
{
if(event->type() == QEvent::KeyPress)
{
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if(keyEvent->key() == Qt::Key_Up)
{
if(this->currentSavedSearchText.isEmpty())
{
this->currentSavedSearchText = ui->txtSearch->text();
}
if(this->currentSearchHistoryIndex <= 0)
{
return true;
}
--this->currentSearchHistoryIndex;
QString text = this->searchHistory.at(this->currentSearchHistoryIndex);
ui->txtSearch->setText(text);
return true;
}
else if(keyEvent->key() == Qt::Key_Down)
{
if(this->currentSearchHistoryIndex == searchHistory.size() - 1)
{
if(!this->currentSavedSearchText.isEmpty())
{
ui->txtSearch->setText(this->currentSavedSearchText);
this->currentSavedSearchText.clear();
++this->currentSearchHistoryIndex;
}
return true;
}
if(this->currentSearchHistoryIndex < searchHistory.size() - 1)
{
++this->currentSearchHistoryIndex;
QString text = this->searchHistory.at(this->currentSearchHistoryIndex);
ui->txtSearch->setText(text);
}
return true;
}
else
{
this->currentSavedSearchText.clear();
/* Off by one on purpose so Key_Up decrements it again and lands at
* the last entry */
this->currentSearchHistoryIndex = this->searchHistory.size();
}
}
}
if(object == ui->scrollArea->viewport())
{
if(event->type() == QEvent::Wheel)
{
QWheelEvent *wheelEvent = static_cast<QWheelEvent *>(event);
if(wheelEvent->modifiers() & Qt::ControlModifier)
{
if(wheelEvent->angleDelta().y() > 0)
{
if(ui->comboScale->currentIndex() < ui->comboScale->count() - 1)
{
ui->comboScale->setCurrentIndex(ui->comboScale->currentIndex() + 1);
}
}
else
{
if(ui->comboScale->currentIndex() > 0)
{
ui->comboScale->setCurrentIndex(ui->comboScale->currentIndex() - 1);
}
}
return true;
}
}
}
return QMainWindow::eventFilter(object, event);
}
void MainWindow::keyPressEvent(QKeyEvent *event) void MainWindow::keyPressEvent(QKeyEvent *event)
{ {
bool quit = bool quit =
@ -585,9 +498,6 @@ void MainWindow::initSettingsTabs()
ui->txtSettingMountPaths->setText(mountPaths); ui->txtSettingMountPaths->setText(mountPaths);
ui->spinSettingNumerPerPages->setValue(numPagesPerPreview); ui->spinSettingNumerPerPages->setValue(numPagesPerPreview);
ui->txtSettingDatabasePath->setText(databasePath); ui->txtSettingDatabasePath->setText(databasePath);
bool horizontalScroll = settings.value(SETTINGS_KEY_PREVIEWS_SCROLL_HORIZONTALLY).toBool();
ui->radioScrollHorizontally->setChecked(horizontalScroll);
ui->radioScrollVertically->setChecked(!horizontalScroll);
} }
void MainWindow::saveSettings() void MainWindow::saveSettings()
@ -615,7 +525,6 @@ void MainWindow::saveSettings()
settings.setValue(SETTINGS_KEY_MOUNTPATHS, mountPaths); settings.setValue(SETTINGS_KEY_MOUNTPATHS, mountPaths);
settings.setValue(SETTINGS_KEY_PREVIEWSPERPAGE, ui->spinSettingNumerPerPages->value()); settings.setValue(SETTINGS_KEY_PREVIEWSPERPAGE, ui->spinSettingNumerPerPages->value());
settings.setValue(SETTINGS_KEY_DBPATH, databasePath); settings.setValue(SETTINGS_KEY_DBPATH, databasePath);
settings.setValue(SETTINGS_KEY_PREVIEWS_SCROLL_HORIZONTALLY, ui->radioScrollHorizontally->isChecked());
settings.sync(); settings.sync();
@ -691,14 +600,6 @@ void MainWindow::lineEditReturnPressed()
ui->tabWidget->setCurrentIndex(0); ui->tabWidget->setCurrentIndex(0);
} }
// TODO: validate q; // TODO: validate q;
while(this->searchHistory.size() > 30)
{
this->searchHistory.removeFirst();
}
this->searchHistory.append(q);
this->currentSearchHistoryIndex = this->searchHistory.size();
this->currentSavedSearchText.clear();
ui->treeResultsList->clear(); ui->treeResultsList->clear();
ui->lblSearchResults->setText("Searching..."); ui->lblSearchResults->setText("Searching...");
this->ui->txtSearch->setEnabled(false); this->ui->txtSearch->setEnabled(false);
@ -870,17 +771,7 @@ void MainWindow::makePreviews(int page)
} }
qDeleteAll(ui->scrollAreaWidgetContents->children()); qDeleteAll(ui->scrollAreaWidgetContents->children());
QSettings settings;
bool horizontalScroll = settings.value(SETTINGS_KEY_PREVIEWS_SCROLL_HORIZONTALLY, false).toBool();
if(horizontalScroll)
{
ui->scrollAreaWidgetContents->setLayout(new QHBoxLayout()); ui->scrollAreaWidgetContents->setLayout(new QHBoxLayout());
}
else
{
ui->scrollAreaWidgetContents->setLayout(new QVBoxLayout());
ui->scrollAreaWidgetContents->layout()->setAlignment(Qt::AlignCenter);
}
ui->previewProcessBar->setMaximum(this->previewableSearchResults.size()); ui->previewProcessBar->setMaximum(this->previewableSearchResults.size());
processedPdfPreviews = 0; processedPdfPreviews = 0;
@ -1034,11 +925,3 @@ MainWindow::~MainWindow()
delete this->indexer; delete this->indexer;
delete ui; delete ui;
} }
void MainWindow::closeEvent(QCloseEvent *event)
{
QStringList list = this->searchHistory.toList();
QSettings settings;
settings.setValue(SETTINGS_KEY_SEARCHHISTORY, list);
settings.sync();
}

View File

@ -30,9 +30,6 @@ class MainWindow : public QMainWindow
void beginSearch(const QString &query); void beginSearch(const QString &query);
void startPdfPreviewGeneration(QVector<SearchResult> paths, double scalefactor); void startPdfPreviewGeneration(QVector<SearchResult> paths, double scalefactor);
protected:
void closeEvent(QCloseEvent *event) override;
private: private:
DatabaseFactory *dbFactory; DatabaseFactory *dbFactory;
SqliteDbService *dbService; SqliteDbService *dbService;
@ -67,10 +64,6 @@ class MainWindow : public QMainWindow
void initSettingsTabs(); void initSettingsTabs();
int currentSelectedScale(); int currentSelectedScale();
void processShortcut(int key); void processShortcut(int key);
bool eventFilter(QObject *object, QEvent *event);
QVector<QString> searchHistory;
int currentSearchHistoryIndex = 0;
QString currentSavedSearchText;
private slots: private slots:
void lineEditReturnPressed(); void lineEditReturnPressed();
void treeSearchItemActivated(QTreeWidgetItem *item, int i); void treeSearchItemActivated(QTreeWidgetItem *item, int i);

View File

@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1280</width> <width>1280</width>
<height>888</height> <height>855</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -27,7 +27,7 @@
<enum>QTabWidget::South</enum> <enum>QTabWidget::South</enum>
</property> </property>
<property name="currentIndex"> <property name="currentIndex">
<number>3</number> <number>1</number>
</property> </property>
<widget class="QWidget" name="resultsTab"> <widget class="QWidget" name="resultsTab">
<attribute name="title"> <attribute name="title">
@ -82,7 +82,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1244</width> <width>1244</width>
<height>598</height> <height>565</height>
</rect> </rect>
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout"/> <layout class="QHBoxLayout" name="horizontalLayout"/>
@ -542,19 +542,6 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item> <item>
<widget class="QGroupBox" name="Misc"> <widget class="QGroupBox" name="Misc">
<property name="title"> <property name="title">
@ -564,7 +551,7 @@
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_9"> <layout class="QHBoxLayout" name="horizontalLayout_9">
<item> <item>
<widget class="QLabel" name="lblMaxNumbersPreviewPages"> <widget class="QLabel" name="label_4">
<property name="text"> <property name="text">
<string>Max number of previews per 'page' in 'Previews' tab: </string> <string>Max number of previews per 'page' in 'Previews' tab: </string>
</property> </property>
@ -588,47 +575,22 @@
</item> </item>
</layout> </layout>
</item> </item>
<item> </layout>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item>
<widget class="QLabel" name="lblScrollModeForPreviews">
<property name="text">
<string>Scroll mode for previews:</string>
</property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QRadioButton" name="radioScrollVertically"> <spacer name="verticalSpacer">
<property name="text">
<string>Vertically</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioScrollHorizontally">
<property name="text">
<string>Horizontally</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_6">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Vertical</enum>
</property> </property>
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>
<width>40</width> <width>20</width>
<height>20</height> <height>40</height>
</size> </size>
</property> </property>
</spacer> </spacer>
</item> </item>
</layout>
</item>
</layout>
</widget>
</item>
<item> <item>
<widget class="QPushButton" name="btnSaveSettings"> <widget class="QPushButton" name="btnSaveSettings">
<property name="text"> <property name="text">

View File

@ -9,8 +9,6 @@
#define SETTINGS_KEY_EXCLUDEDPATHS "excludedpaths" #define SETTINGS_KEY_EXCLUDEDPATHS "excludedpaths"
#define SETTINGS_KEY_MOUNTPATHS "mountpaths" #define SETTINGS_KEY_MOUNTPATHS "mountpaths"
#define SETTINGS_KEY_PREVIEWSPERPAGE "previewsPerPage" #define SETTINGS_KEY_PREVIEWSPERPAGE "previewsPerPage"
#define SETTINGS_KEY_SEARCHHISTORY "searchhistory"
#define SETTINGS_KEY_PREVIEWS_SCROLL_HORIZONTALLY "horizontalscroll"
namespace Common namespace Common
{ {

View File

@ -78,17 +78,12 @@ QString SqliteSearch::escapeFtsArgument(QString ftsArg)
if(value.isEmpty()) if(value.isEmpty())
{ {
value = m.captured(2); value = m.captured(2);
if(value.endsWith('*'))
{
value = value.mid(0, value.size() - 1);
}
result += "\"" + value + "\"*";
} }
else else
{ {
value = "\"\"" + value + "\"\""; value = "\"\"" + value + "\"\"";
result += "\"" + value + "\" ";
} }
result += "\"" + value + "\" ";
} }
return result; return result;
} }