Removed search functionality ( this is covered by qss now).
This commit is contained in:
parent
7a82cdd31b
commit
3970019fac
1
BUGS
1
BUGS
@ -1,2 +1 @@
|
||||
SearchWorker: isPending etc. may need proper locking (with mutexes)
|
||||
Memory leaks(ignored for now due to short-running nature of the application)
|
||||
|
16
README.md
16
README.md
@ -1,9 +1,7 @@
|
||||
qsRunner
|
||||
========
|
||||
qsRunner is a launcher. It contains user defined entries for applications and also searches
|
||||
system-applications. Using libcalculate, it can also be used as a calculator. It
|
||||
can also search for files (and their contents) by querying a sqlite database, although it itself does
|
||||
not index files.
|
||||
system-applications. Using libcalculate, it can also be used as a calculator.
|
||||
|
||||
If you run a desktop environment like KDE it is questionable whether you will
|
||||
find this useful, since they usually bring applications that are more or less
|
||||
@ -16,7 +14,6 @@ Dependencies
|
||||
It has been only tested for Qt 5.7.
|
||||
|
||||
For the calculation engine, libqalculate is needed.
|
||||
For file search, easyindex is necessary.
|
||||
|
||||
Currently no conditional compile flags are supported...
|
||||
|
||||
@ -33,9 +30,6 @@ Config format
|
||||
Path: $HOME/.config/qsRunner/qsrunner.config
|
||||
|
||||
```
|
||||
[Search]
|
||||
dbpath="/path/to/database.sqlite"
|
||||
|
||||
[General]
|
||||
systemApplicationsPath="/usr/share/applications/"
|
||||
```
|
||||
@ -80,11 +74,3 @@ terminal.
|
||||
Calculator
|
||||
----------
|
||||
Start by typing "=", followed by your expression, e. g: "=(2+3)^2"
|
||||
|
||||
File searches
|
||||
-------------
|
||||
It only queries a sqlite database. It does not index files, this is beyond the
|
||||
scope a launcher. For the file searches functionality, easyindex is necessary.
|
||||
See: git.quitesimple.org/easyindex.
|
||||
|
||||
|
||||
|
3
main.cpp
3
main.cpp
@ -44,7 +44,6 @@ int main(int argc, char *argv[])
|
||||
return 1;
|
||||
}
|
||||
QSettings settings(configDirectoryPath + "qsrun.config", QSettings::NativeFormat);
|
||||
QString dbpath = settings.value("Search/dbpath").toString();
|
||||
QString systemApplicationsPath = settings.value("General/systemApplicationsPath", "/usr/share/applications/").toString();
|
||||
|
||||
QVector<EntryConfig> configs;
|
||||
@ -59,7 +58,7 @@ int main(int argc, char *argv[])
|
||||
std::cerr << e.what() << std::endl;
|
||||
}
|
||||
|
||||
Window w(configs, dbpath);
|
||||
Window w(configs);
|
||||
|
||||
/*
|
||||
* TODO: Reconsider the need
|
||||
|
@ -9,12 +9,10 @@ INCLUDEPATH += .
|
||||
# Input
|
||||
HEADERS += config.h window.h \
|
||||
entrypushbutton.h \
|
||||
calculationengine.h \
|
||||
searchworker.h
|
||||
calculationengine.h
|
||||
SOURCES += config.cpp main.cpp window.cpp \
|
||||
entrypushbutton.cpp \
|
||||
calculationengine.cpp \
|
||||
searchworker.cpp
|
||||
calculationengine.cpp
|
||||
QT += widgets sql
|
||||
QT_CONFIG -= no-pkg-config
|
||||
LIBS += -lcln
|
||||
|
@ -1,74 +0,0 @@
|
||||
#include "searchworker.h"
|
||||
#include <QDebug>
|
||||
#include <QSqlError>
|
||||
//TODO: we have code duplication in the search functions currently.
|
||||
SearchWorker::SearchWorker(const QString &dbpath)
|
||||
{
|
||||
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
|
||||
db.setDatabaseName(dbpath);
|
||||
if(!db.open())
|
||||
{
|
||||
qDebug() << "failed to open database";
|
||||
}
|
||||
queryContent = new QSqlQuery(db);
|
||||
queryFile = new QSqlQuery(db);
|
||||
queryFile->prepare("SELECT path FROM file WHERE path LIKE ? ORDER BY mtime DESC");
|
||||
|
||||
queryContent->prepare("SELECT DISTINCT file.path FROM file INNER JOIN content ON file.id = content.fileid INNER JOIN content_fts ON content.id = content_fts.ROWID WHERE content_fts.content MATCH ? ORDER By file.mtime DESC");
|
||||
}
|
||||
|
||||
void SearchWorker::searchForFile(const QString &query)
|
||||
{
|
||||
this->isPending = true;
|
||||
this->cancelCurrent = false;
|
||||
QVector<QString> results;
|
||||
queryFile->addBindValue("%" + query + "%");
|
||||
queryFile->exec();
|
||||
while(queryFile->next())
|
||||
{
|
||||
if(cancelCurrent)
|
||||
{
|
||||
this->isPending = false;
|
||||
emit searchCancelled();
|
||||
return;
|
||||
}
|
||||
QString result = queryFile->value(0).toString();
|
||||
qDebug() << "result" << result;
|
||||
results.append(queryFile->value(0).toString());
|
||||
}
|
||||
this->isPending = false;
|
||||
emit searchResultsReady(results);
|
||||
}
|
||||
|
||||
void SearchWorker::requestCancellation()
|
||||
{
|
||||
this->cancelCurrent = true;
|
||||
}
|
||||
|
||||
void SearchWorker::searchForContent(const QString &query)
|
||||
{
|
||||
this->isPending = true;
|
||||
this->cancelCurrent = false;
|
||||
QVector<QString> results;
|
||||
queryContent->addBindValue(query);
|
||||
queryContent->exec();
|
||||
while(queryContent->next())
|
||||
{
|
||||
if(cancelCurrent)
|
||||
{
|
||||
this->isPending = false;
|
||||
emit searchCancelled();
|
||||
return;
|
||||
}
|
||||
QString result = queryContent->value(0).toString();
|
||||
qDebug() << "result" << result;
|
||||
results.append(queryContent->value(0).toString());
|
||||
}
|
||||
this->isPending = false;
|
||||
emit searchResultsReady(results);
|
||||
}
|
||||
|
||||
bool SearchWorker::isOperationPending()
|
||||
{
|
||||
return this->isPending;
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
#ifndef SEARCHWORKER_H
|
||||
#define SEARCHWORKER_H
|
||||
#include <QObject>
|
||||
#include <QSqlDatabase>
|
||||
#include <QSqlQuery>
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
|
||||
class SearchWorker : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
QSqlQuery *queryFile;
|
||||
QSqlQuery *queryContent;
|
||||
bool isPending = false;
|
||||
bool cancelCurrent = false;
|
||||
public:
|
||||
SearchWorker(const QString &dbpath);
|
||||
bool isOperationPending();
|
||||
void requestCancellation();
|
||||
|
||||
|
||||
public slots:
|
||||
void searchForFile(const QString &query);
|
||||
void searchForContent(const QString &query);
|
||||
signals:
|
||||
void searchResultsReady(const QVector<QString> &results);
|
||||
void searchCancelled();
|
||||
|
||||
};
|
||||
|
||||
#endif // SEARCHWORKER_H
|
124
window.cpp
124
window.cpp
@ -26,19 +26,11 @@
|
||||
#include <QFileIconProvider>
|
||||
#include <QMenu>
|
||||
#include <QClipboard>
|
||||
Window::Window(const QVector<EntryConfig> &configs, const QString &dbpath)
|
||||
Window::Window(const QVector<EntryConfig> &configs)
|
||||
{
|
||||
this->userEntryButtons = generateEntryButtons(configs);
|
||||
createGui();
|
||||
populateGrid(this->userEntryButtons);
|
||||
searchWorker = new SearchWorker(dbpath);
|
||||
searchWorker->moveToThread(&searchThread);
|
||||
connect(this, &Window::beginFileSearch, searchWorker, &SearchWorker::searchForFile);
|
||||
connect(this, &Window::beginContentSearch, searchWorker, &SearchWorker::searchForContent);
|
||||
connect(searchWorker, &SearchWorker::searchResultsReady, this, &Window::handleSearchResults);
|
||||
connect(searchWorker, &SearchWorker::searchCancelled, this, &Window::handleCancelledSearch);
|
||||
searchThread.start();
|
||||
initTreeWidgets();
|
||||
this->lineEdit->installEventFilter(this);
|
||||
QFont font;
|
||||
font.setPointSize(48);
|
||||
@ -55,43 +47,14 @@ Window::Window(const QVector<EntryConfig> &configs, const QString &dbpath)
|
||||
|
||||
Window::~Window()
|
||||
{
|
||||
searchThread.quit();
|
||||
searchThread.wait();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Window::initTreeWidgets()
|
||||
{
|
||||
QStringList headers;
|
||||
headers << "Filename";
|
||||
headers << "Path";
|
||||
headers << "Modification time";
|
||||
treeFileSearchResults.setHeaderLabels(headers);
|
||||
treeFileSearchResults.header()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
||||
connect(&treeFileSearchResults, &QTreeWidget::itemActivated, this, &Window::treeSearchItemActivated);
|
||||
treeFileSearchResults.setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu);
|
||||
connect(&treeFileSearchResults, &QTreeWidget::customContextMenuRequested, this, &Window::showSearchResultsContextMenu);
|
||||
}
|
||||
|
||||
|
||||
void Window::showSearchResultsContextMenu(const QPoint &point)
|
||||
{
|
||||
QTreeWidgetItem *item = treeFileSearchResults.itemAt(point);
|
||||
if(item == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
QMenu menu("SearchResult", this);
|
||||
menu.addAction("Copy filename to clipboard", [&] { QGuiApplication::clipboard()->setText(item->text(0));});
|
||||
menu.addAction("Copy full path to clipboard", [&] { QGuiApplication::clipboard()->setText(item->text(1)); });
|
||||
menu.addAction("Open containing folder", [&] {
|
||||
QFileInfo pathinfo(item->text(1));
|
||||
QString dir = pathinfo.absolutePath();
|
||||
QDesktopServices::openUrl(QUrl::fromLocalFile(dir));
|
||||
|
||||
});
|
||||
menu.exec(QCursor::pos());
|
||||
}
|
||||
|
||||
|
||||
void Window::showCalculationResultContextMenu(const QPoint &point)
|
||||
{
|
||||
@ -218,34 +181,6 @@ void Window::lineEditTextChanged(QString text)
|
||||
addCalcResult(input);
|
||||
return;
|
||||
}
|
||||
if(text[0] == '/')
|
||||
{
|
||||
if(searchWorker->isOperationPending())
|
||||
{
|
||||
this->queuedFileSearch = input;
|
||||
searchWorker->requestCancellation();
|
||||
}
|
||||
else
|
||||
{
|
||||
this->queuedFileSearch = "";
|
||||
emit beginFileSearch(input);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(text[0] == '|')
|
||||
{
|
||||
if(searchWorker->isOperationPending())
|
||||
{
|
||||
this->queuedContentSearch = input;
|
||||
searchWorker->requestCancellation();
|
||||
}
|
||||
else
|
||||
{
|
||||
this->queuedContentSearch = "";
|
||||
emit beginContentSearch(input);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
filterGridFor(text);
|
||||
@ -384,10 +319,6 @@ void Window::lineEditReturnPressed()
|
||||
buttonClick(*buttonsInGrid[0]);
|
||||
return;
|
||||
}
|
||||
if(this->isSearchMode())
|
||||
{
|
||||
treeSearchItemActivated(treeFileSearchResults.topLevelItem(0), 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Window::setSystemConfig(const QVector<EntryConfig> &config)
|
||||
@ -395,51 +326,7 @@ void Window::setSystemConfig(const QVector<EntryConfig> &config)
|
||||
this->systemEntryButtons = generateEntryButtons(config);
|
||||
}
|
||||
|
||||
void Window::handleSearchResults(const QVector<QString> &results)
|
||||
{
|
||||
clearGrid();
|
||||
treeFileSearchResults.clear();
|
||||
QFileIconProvider provider;
|
||||
for(const QString &path : results)
|
||||
{
|
||||
QFileInfo pathInfo(path);
|
||||
QString fileName =pathInfo.fileName();
|
||||
QString absPath = path;
|
||||
QString datestr = pathInfo.lastModified().toString(Qt::ISODate);
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem(&treeFileSearchResults);
|
||||
item->setText(0, fileName);
|
||||
item->setIcon(0, provider.icon(pathInfo));
|
||||
item->setText(1, absPath);
|
||||
item->setText(2, datestr);
|
||||
|
||||
}
|
||||
treeFileSearchResults.resizeColumnToContents(0);
|
||||
treeFileSearchResults.resizeColumnToContents(2);
|
||||
treeFileSearchResults.setVisible(true);
|
||||
|
||||
this->grid->addWidget(&treeFileSearchResults, 0, 0);
|
||||
}
|
||||
|
||||
void Window::handleCancelledSearch()
|
||||
{
|
||||
if(this->queuedFileSearch != "")
|
||||
{
|
||||
QString searchFor = this->queuedFileSearch;
|
||||
this->queuedFileSearch = "";
|
||||
emit beginFileSearch(searchFor);
|
||||
}
|
||||
if(this->queuedContentSearch != "")
|
||||
{
|
||||
QString searchFor = this->queuedContentSearch;
|
||||
this->queuedContentSearch = "";
|
||||
emit beginContentSearch(searchFor);
|
||||
}
|
||||
}
|
||||
|
||||
void Window::treeSearchItemActivated(QTreeWidgetItem *item, int i)
|
||||
{
|
||||
QDesktopServices::openUrl(QUrl::fromLocalFile(item->text(1)));
|
||||
}
|
||||
|
||||
|
||||
bool Window::eventFilter(QObject *obj, QEvent *event)
|
||||
@ -468,8 +355,3 @@ bool Window::eventFilter(QObject *obj, QEvent *event)
|
||||
|
||||
}
|
||||
|
||||
bool Window::isSearchMode()
|
||||
{
|
||||
QChar c = this->lineEdit->text()[0];
|
||||
return c == '/' || c == '|';
|
||||
}
|
||||
|
14
window.h
14
window.h
@ -33,20 +33,16 @@
|
||||
#include "config.h"
|
||||
#include "entrypushbutton.h"
|
||||
#include "calculationengine.h"
|
||||
#include "searchworker.h"
|
||||
|
||||
class Window : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
QThread searchThread;
|
||||
SearchWorker *searchWorker;
|
||||
CalculationEngine calcEngine;
|
||||
QString calculationresult;
|
||||
QVector<EntryPushButton*> userEntryButtons;
|
||||
QVector<EntryPushButton*> systemEntryButtons;
|
||||
QVector<EntryPushButton *> buttonsInGrid;
|
||||
QTreeWidget treeFileSearchResults;
|
||||
QLabel calculationResultLabel;
|
||||
QString currentCalculationResult;
|
||||
QString queuedFileSearch;
|
||||
@ -67,19 +63,11 @@ class Window : public QWidget
|
||||
void addCalcResult(const QString & expression);
|
||||
void initTreeWidgets();
|
||||
QStringList generatePATHSuggestions(const QString &text);
|
||||
bool isSearchMode();
|
||||
private slots:
|
||||
void lineEditReturnPressed();
|
||||
void handleSearchResults(const QVector<QString> &results);
|
||||
void handleCancelledSearch();
|
||||
void treeSearchItemActivated(QTreeWidgetItem *item, int i);
|
||||
void showSearchResultsContextMenu(const QPoint &point);
|
||||
void showCalculationResultContextMenu(const QPoint &point);
|
||||
signals:
|
||||
void beginFileSearch(const QString &query);
|
||||
void beginContentSearch(const QString &query);
|
||||
public:
|
||||
Window(const QVector<EntryConfig> &userEntryButtons, const QString &dbpath);
|
||||
Window(const QVector<EntryConfig> &userEntryButtons);
|
||||
void setSystemConfig(const QVector<EntryConfig> &config);
|
||||
bool eventFilter(QObject *obj, QEvent *event);
|
||||
~Window();
|
||||
|
Caricamento…
Fai riferimento in un nuovo problema
Block a user