Add database indexing of FITS files
This commit is contained in:
@@ -18,6 +18,7 @@ find_library(RAW_LIB NAMES raw_r raw REQUIRED)
|
|||||||
|
|
||||||
set(TENMON_SRC
|
set(TENMON_SRC
|
||||||
database.cpp
|
database.cpp
|
||||||
|
databaseview.cpp
|
||||||
filesystemwidget.cpp
|
filesystemwidget.cpp
|
||||||
imageinfo.cpp
|
imageinfo.cpp
|
||||||
imageringlist.cpp
|
imageringlist.cpp
|
||||||
|
|||||||
+1
-1
@@ -48,7 +48,7 @@ bool Database::init()
|
|||||||
m_checkFile = QSqlQuery(m_database);
|
m_checkFile = QSqlQuery(m_database);
|
||||||
m_checkFile.prepare("SELECT id,mtime FROM fits_files WHERE file=?");
|
m_checkFile.prepare("SELECT id,mtime FROM fits_files WHERE file=?");
|
||||||
m_headerKeywords = QSqlQuery(m_database);
|
m_headerKeywords = QSqlQuery(m_database);
|
||||||
m_headerKeywords.prepare("SELECT DISTINCT key FROM fits_headers");
|
m_headerKeywords.prepare("SELECT DISTINCT key FROM fits_headers ORDER BY key");
|
||||||
m_deleteFile = QSqlQuery(m_database);
|
m_deleteFile = QSqlQuery(m_database);
|
||||||
m_deleteFile.prepare("DELETE FROM fits_files WHERE id=?");
|
m_deleteFile.prepare("DELETE FROM fits_files WHERE id=?");
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -0,0 +1,112 @@
|
|||||||
|
#include "databaseview.h"
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QDialogButtonBox>
|
||||||
|
#include <QHeaderView>
|
||||||
|
|
||||||
|
const QStringList DEFAULT_COLUMNS = {"EXPTIME", "OBJECT", "RA", "DEC"};
|
||||||
|
|
||||||
|
SelectColumnsDialog::SelectColumnsDialog(QWidget *parent) : QDialog(parent)
|
||||||
|
{
|
||||||
|
m_listWidget = new QListWidget(this);
|
||||||
|
m_listWidget->setSelectionMode(QAbstractItemView::MultiSelection);
|
||||||
|
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||||
|
setLayout(layout);
|
||||||
|
layout->addWidget(m_listWidget);
|
||||||
|
|
||||||
|
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||||
|
connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
||||||
|
connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||||
|
layout->addWidget(buttonBox);
|
||||||
|
|
||||||
|
setWindowTitle(tr("Select columns"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SelectColumnsDialog::setColumns(QStringList columns)
|
||||||
|
{
|
||||||
|
QSettings settings;
|
||||||
|
m_listWidget->addItems(columns);
|
||||||
|
QStringList selected = settings.value("databaseview/selectedColumns", DEFAULT_COLUMNS).toStringList();
|
||||||
|
for(auto &sel : selected)
|
||||||
|
{
|
||||||
|
int i = columns.indexOf(sel);
|
||||||
|
if(i>=0)
|
||||||
|
m_listWidget->item(i)->setSelected(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList SelectColumnsDialog::selectedColumns()
|
||||||
|
{
|
||||||
|
QStringList ret;
|
||||||
|
for(auto &sel : m_listWidget->selectedItems())
|
||||||
|
ret.append(sel->text());
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataBaseView::DataBaseView(Database *database, QWidget *parent) : QWidget(parent)
|
||||||
|
,m_database(database)
|
||||||
|
{
|
||||||
|
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||||
|
setLayout(layout);
|
||||||
|
|
||||||
|
m_tableView = new QTableView(this);
|
||||||
|
m_tableView->verticalHeader()->setDefaultSectionSize(1);
|
||||||
|
layout->addWidget(m_tableView);
|
||||||
|
|
||||||
|
m_model = new QSqlQueryModel(this);
|
||||||
|
|
||||||
|
QSettings settings;
|
||||||
|
m_tableView->setModel(m_model);
|
||||||
|
m_tableView->horizontalHeader()->restoreState(settings.value("databaseview/header").toByteArray());
|
||||||
|
|
||||||
|
QHBoxLayout *hlayout = new QHBoxLayout(this);
|
||||||
|
layout->addLayout(hlayout);
|
||||||
|
|
||||||
|
QPushButton *selectColumnsButton = new QPushButton(tr("Select columns"), this);
|
||||||
|
hlayout->addWidget(selectColumnsButton);
|
||||||
|
connect(selectColumnsButton, &QPushButton::pressed, this, &DataBaseView::selectColumns);
|
||||||
|
|
||||||
|
QPushButton *loadDatabaseButton = new QPushButton(tr("Load database"), this);
|
||||||
|
hlayout->addWidget(loadDatabaseButton);
|
||||||
|
connect(loadDatabaseButton, &QPushButton::pressed, this, &DataBaseView::loadDatabase);
|
||||||
|
}
|
||||||
|
|
||||||
|
DataBaseView::~DataBaseView()
|
||||||
|
{
|
||||||
|
QSettings settings;
|
||||||
|
settings.setValue("databaseview/header", m_tableView->horizontalHeader()->saveState());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataBaseView::selectColumns()
|
||||||
|
{
|
||||||
|
SelectColumnsDialog dialog;
|
||||||
|
QStringList columns = m_database->getFitsKeywords();
|
||||||
|
dialog.setColumns(columns);
|
||||||
|
if(dialog.exec() == QDialog::Accepted)
|
||||||
|
{
|
||||||
|
QSettings settings;
|
||||||
|
QStringList columns = dialog.selectedColumns();
|
||||||
|
settings.setValue("databaseview/selectedColumns", columns);
|
||||||
|
prepareQuery(columns);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataBaseView::loadDatabase()
|
||||||
|
{
|
||||||
|
QSettings settings;
|
||||||
|
prepareQuery(settings.value("databaseview/selectedColumns", DEFAULT_COLUMNS).toStringList());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataBaseView::prepareQuery(const QStringList &columns)
|
||||||
|
{
|
||||||
|
QString sql = "SELECT file,";
|
||||||
|
for(auto &column : columns)
|
||||||
|
{
|
||||||
|
sql += QString("GROUP_CONCAT(CASE WHEN key=\"%1\" THEN value END) AS \"%1\",").arg(column);
|
||||||
|
}
|
||||||
|
sql.chop(1);
|
||||||
|
sql += " FROM fits_files LEFT JOIN fits_headers ON fits_files.id=id_file GROUP BY fits_files.id";
|
||||||
|
m_model->setQuery(sql);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
#ifndef DATABASEVIEW_H
|
||||||
|
#define DATABASEVIEW_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QSqlQueryModel>
|
||||||
|
#include <QTableView>
|
||||||
|
#include <QListWidget>
|
||||||
|
#include "database.h"
|
||||||
|
|
||||||
|
class SelectColumnsDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
QListWidget *m_listWidget;
|
||||||
|
public:
|
||||||
|
SelectColumnsDialog(QWidget *parent = nullptr);
|
||||||
|
void setColumns(QStringList columns);
|
||||||
|
QStringList selectedColumns();
|
||||||
|
};
|
||||||
|
|
||||||
|
class DataBaseView : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Database *m_database;
|
||||||
|
QTableView *m_tableView;
|
||||||
|
QSqlQueryModel *m_model;
|
||||||
|
public:
|
||||||
|
explicit DataBaseView(Database *database, QWidget *parent = nullptr);
|
||||||
|
~DataBaseView();
|
||||||
|
public slots:
|
||||||
|
void selectColumns();
|
||||||
|
void loadDatabase();
|
||||||
|
protected:
|
||||||
|
void prepareQuery(const QStringList &columns);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DATABASEVIEW_H
|
||||||
+20
-4
@@ -51,6 +51,12 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
|
|||||||
m_filesystem = new FilesystemWidget(m_ringList, this);
|
m_filesystem = new FilesystemWidget(m_ringList, this);
|
||||||
connect(m_filesystem, SIGNAL(fileSelected(int)), this, SLOT(loadFile(int)));
|
connect(m_filesystem, SIGNAL(fileSelected(int)), this, SLOT(loadFile(int)));
|
||||||
|
|
||||||
|
m_database = new Database(this);
|
||||||
|
if(!m_database->init())
|
||||||
|
QMessageBox::critical(this, tr("Can't open DB"), tr("Can't open SQLITE database"));
|
||||||
|
|
||||||
|
m_databaseView = new DataBaseView(m_database, this);
|
||||||
|
|
||||||
QDockWidget *stretchDock = new QDockWidget(tr("Stretch"), this);
|
QDockWidget *stretchDock = new QDockWidget(tr("Stretch"), this);
|
||||||
stretchDock->setWidget(m_stretchPanel);
|
stretchDock->setWidget(m_stretchPanel);
|
||||||
stretchDock->setObjectName("strechDock");
|
stretchDock->setObjectName("strechDock");
|
||||||
@@ -61,6 +67,12 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
|
|||||||
filesystemDock->setObjectName("filesystemDock");
|
filesystemDock->setObjectName("filesystemDock");
|
||||||
addDockWidget(Qt::LeftDockWidgetArea, filesystemDock);
|
addDockWidget(Qt::LeftDockWidgetArea, filesystemDock);
|
||||||
|
|
||||||
|
QDockWidget *databaseViewDock = new QDockWidget(tr("FITS files database"), this);
|
||||||
|
databaseViewDock->setWidget(m_databaseView);
|
||||||
|
databaseViewDock->setObjectName("databaseViewDock");
|
||||||
|
databaseViewDock->hide();
|
||||||
|
addDockWidget(Qt::RightDockWidgetArea, databaseViewDock);
|
||||||
|
|
||||||
setWindowTitle(tr("Tenmon"));
|
setWindowTitle(tr("Tenmon"));
|
||||||
|
|
||||||
connect(m_ringList, SIGNAL(pixmapLoaded(Image*)), this, SLOT(pixmapLoaded(Image*)));
|
connect(m_ringList, SIGNAL(pixmapLoaded(Image*)), this, SLOT(pixmapLoaded(Image*)));
|
||||||
@@ -118,14 +130,11 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
|
|||||||
analyzeMenu->addActions({statsAction, peakAction, starAction});
|
analyzeMenu->addActions({statsAction, peakAction, starAction});
|
||||||
menuBar()->addMenu(analyzeMenu);
|
menuBar()->addMenu(analyzeMenu);
|
||||||
|
|
||||||
m_database = new Database(this);
|
|
||||||
if(!m_database->init())
|
|
||||||
QMessageBox::critical(this, tr("Can't open DB"), tr("Can't open SQLITE database"));
|
|
||||||
|
|
||||||
QMenu *dockMenu = new QMenu(tr("Docks"), this);
|
QMenu *dockMenu = new QMenu(tr("Docks"), this);
|
||||||
dockMenu->addAction(infoDock->toggleViewAction());
|
dockMenu->addAction(infoDock->toggleViewAction());
|
||||||
dockMenu->addAction(stretchDock->toggleViewAction());
|
dockMenu->addAction(stretchDock->toggleViewAction());
|
||||||
dockMenu->addAction(filesystemDock->toggleViewAction());
|
dockMenu->addAction(filesystemDock->toggleViewAction());
|
||||||
|
dockMenu->addAction(databaseViewDock->toggleViewAction());
|
||||||
menuBar()->addMenu(dockMenu);
|
menuBar()->addMenu(dockMenu);
|
||||||
|
|
||||||
setupSigterm();
|
setupSigterm();
|
||||||
@@ -267,6 +276,13 @@ void MainWindow::loadFile(int row)
|
|||||||
m_ringList->loadFile(row);
|
m_ringList->loadFile(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::indexDir()
|
||||||
|
{
|
||||||
|
QString dir = QFileDialog::getExistingDirectory(this, tr("Index directory"), _lastDir);
|
||||||
|
if(!dir.isEmpty())
|
||||||
|
m_database->indexDir(dir);
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::saveAs()
|
void MainWindow::saveAs()
|
||||||
{
|
{
|
||||||
QString file = QFileDialog::getSaveFileName(this, tr("Save as"), _lastDir, tr("Images (*.jpg *.png *.JPG *.PNG)"));
|
QString file = QFileDialog::getSaveFileName(this, tr("Save as"), _lastDir, tr("Images (*.jpg *.png *.JPG *.PNG)"));
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include "imagescrollareagl.h"
|
#include "imagescrollareagl.h"
|
||||||
#include "filesystemwidget.h"
|
#include "filesystemwidget.h"
|
||||||
#include "stretchpanel.h"
|
#include "stretchpanel.h"
|
||||||
|
#include "databaseview.h"
|
||||||
|
|
||||||
class MainWindow : public QMainWindow
|
class MainWindow : public QMainWindow
|
||||||
{
|
{
|
||||||
@@ -21,6 +22,7 @@ class MainWindow : public QMainWindow
|
|||||||
Database *m_database;
|
Database *m_database;
|
||||||
ImageInfo *m_info;
|
ImageInfo *m_info;
|
||||||
FilesystemWidget *m_filesystem;
|
FilesystemWidget *m_filesystem;
|
||||||
|
DataBaseView *m_databaseView;
|
||||||
static int socketPair[2];
|
static int socketPair[2];
|
||||||
QSocketNotifier *socketNotifier;
|
QSocketNotifier *socketNotifier;
|
||||||
QString _lastDir;
|
QString _lastDir;
|
||||||
@@ -41,6 +43,7 @@ protected slots:
|
|||||||
void loadFile();
|
void loadFile();
|
||||||
void loadFile(const QString path);
|
void loadFile(const QString path);
|
||||||
void loadFile(int row);
|
void loadFile(int row);
|
||||||
|
void indexDir();
|
||||||
void saveAs();
|
void saveAs();
|
||||||
void markImage();
|
void markImage();
|
||||||
void unmarkImage();
|
void unmarkImage();
|
||||||
|
|||||||
Reference in New Issue
Block a user