diff --git a/filesystemwidget.cpp b/filesystemwidget.cpp new file mode 100644 index 0000000..804acc2 --- /dev/null +++ b/filesystemwidget.cpp @@ -0,0 +1,36 @@ +#include "filesystemwidget.h" +#include +#include + +FilesystemWidget::FilesystemWidget(QAbstractItemModel *model, QWidget *parent) : QWidget(parent) + , m_model(model) +{ + m_listView = new QListView(this); + m_listView->setModel(model); + + QVBoxLayout *layout = new QVBoxLayout(this); + layout->addWidget(m_listView); + + setLayout(layout); + + connect(m_listView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(fileClicked(QModelIndex))); +} + +void FilesystemWidget::setDir(const QString &dir) +{ + //m_model->setRootPath(dir); + //m_treeView->setRootIndex(m_model->index(m_model->rootPath())); +} + +void FilesystemWidget::selectFile(int row) +{ + QModelIndex index = m_model->index(row, 0); + m_listView->selectionModel()->clearSelection(); + m_listView->selectionModel()->select(index, QItemSelectionModel::SelectCurrent); + m_listView->scrollTo(index); +} + +void FilesystemWidget::fileClicked(const QModelIndex &index) +{ + emit fileSelected(index.row()); +} diff --git a/filesystemwidget.h b/filesystemwidget.h new file mode 100644 index 0000000..ae455b7 --- /dev/null +++ b/filesystemwidget.h @@ -0,0 +1,23 @@ +#ifndef FILESYSTEMWIDGET_H +#define FILESYSTEMWIDGET_H + +#include +#include +#include + +class FilesystemWidget : public QWidget +{ + Q_OBJECT + QListView *m_listView; + QAbstractItemModel *m_model; +public: + explicit FilesystemWidget(QAbstractItemModel *model, QWidget *parent = nullptr); + void setDir(const QString &dir); +private slots: + void selectFile(int row); + void fileClicked(const QModelIndex &index); +signals: + void fileSelected(int row); +}; + +#endif // FILESYSTEMWIDGET_H diff --git a/imageringlist.cpp b/imageringlist.cpp index 721b730..4973e49 100644 --- a/imageringlist.cpp +++ b/imageringlist.cpp @@ -78,7 +78,7 @@ void Image::imageLoaded(QImage img, void *rawImage, ImageInfoData info) } } -ImageRingList::ImageRingList(QObject *parent) : QObject(parent) +ImageRingList::ImageRingList(QObject *parent) : QAbstractItemModel(parent) , m_liveMode(false) , m_analyzeLevel(None) { @@ -118,7 +118,10 @@ bool ImageRingList::setDir(const QString path, const QString ¤tFile) void ImageRingList::setFile(const QString &file) { QFileInfo info(file); - setDir(info.absolutePath(), file); + if(info.isDir()) + setDir(file); + else + setDir(info.absolutePath(), file); } ImagePtr ImageRingList::currentImage() @@ -180,10 +183,90 @@ AnalyzeLevel ImageRingList::analyzeLevel() const return m_analyzeLevel; } +void ImageRingList::loadFile(int row) +{ + if(row < m_images.size()) + { + m_firstImage = m_currImage = m_lastImage = m_images.begin()+row; + if(m_images.empty()) + return; + + (*m_currImage)->load(); + + m_width = DEFAULT_WIDTHload(); + m_lastImage = increment(m_lastImage); + (*m_lastImage)->load(); + } + if(m_lastImage != m_firstImage) + { + QList::iterator iter = increment(m_lastImage); + while(m_firstImage != iter) + { + (*iter)->release(); + iter = increment(iter); + } + } + } +} + +QModelIndex ImageRingList::index(int row, int column, const QModelIndex &parent) const +{ + return createIndex(row, column, m_images.at(row).get()); +} + +QModelIndex ImageRingList::parent(const QModelIndex &child) const +{ + return QModelIndex(); +} + +int ImageRingList::rowCount(const QModelIndex &parent) const +{ + if(parent == QModelIndex()) + return m_images.size(); + else + return 0; +} + +int ImageRingList::columnCount(const QModelIndex &parent) const +{ + return 1; +} + +QVariant ImageRingList::data(const QModelIndex &index, int role) const +{ + switch(role) + { + case Qt::DisplayRole: + { + QFileInfo info(m_images.at(index.row())->name()); + return info.fileName(); + } + default: + return QVariant(); + } +} + +QVariant ImageRingList::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(section==0 && orientation==Qt::Horizontal && role==Qt::DisplayRole) + { + return tr("Name"); + } + return QVariant(); +} + void ImageRingList::setFiles(const QStringList files, const QString ¤tFile) { QThreadPool::globalInstance()->clear(); QThreadPool::globalInstance()->waitForDone(); + beginResetModel(); m_images.clear(); foreach(const QString &file, files) { @@ -196,23 +279,8 @@ void ImageRingList::setFiles(const QStringList files, const QString ¤tFile if(index < 0) index = 0; - m_firstImage = m_currImage = m_lastImage = m_images.begin()+index; - if(m_images.empty()) - return; - - (*m_currImage)->load(); - - m_width = DEFAULT_WIDTHload(); - m_lastImage = increment(m_lastImage); - (*m_lastImage)->load(); - } + endResetModel(); + loadFile(index); } QList::iterator ImageRingList::increment(QList::iterator iter) @@ -237,6 +305,7 @@ void ImageRingList::imageLoaded(Image *image) { emit pixmapLoaded(image); emit infoLoaded(image->info()); + emit currentImageChanged(m_currImage-m_images.begin()); } } @@ -248,5 +317,5 @@ void ImageRingList::dirChanged(QString dir) currentFile = (*m_currImage)->name(); setDir(dir, currentFile); - emit currentImageChanged(); + emit currentImageChanged(m_currImage-m_images.begin()); } diff --git a/imageringlist.h b/imageringlist.h index cf88838..890621b 100644 --- a/imageringlist.h +++ b/imageringlist.h @@ -39,7 +39,7 @@ protected slots: typedef std::shared_ptr ImagePtr; -class ImageRingList : public QObject +class ImageRingList : public QAbstractItemModel { Q_OBJECT int m_width; @@ -63,6 +63,14 @@ public: void setFindPeaks(bool findPeaks); void setFindStars(bool findStars); AnalyzeLevel analyzeLevel() const; + void loadFile(int row); + + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; + QModelIndex parent(const QModelIndex &child) const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; protected: void setFiles(const QStringList files, const QString ¤tFile = QString()); QList::iterator increment(QList::iterator iter); @@ -70,7 +78,7 @@ protected: signals: void pixmapLoaded(Image *image); void infoLoaded(ImageInfoData info); - void currentImageChanged(); + void currentImageChanged(int index); protected slots: void imageLoaded(Image *image); void dirChanged(QString dir); diff --git a/mainwindow.cpp b/mainwindow.cpp index 2f1a537..54c8980 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -48,20 +48,29 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) connect(stretchPanel, SIGNAL(stretchChanged(int)), m_imageGL->imageWidget(), SLOT(setStrech(int))); connect(stretchPanel, SIGNAL(paramChanged(float)), m_imageGL->imageWidget(), SLOT(setStretchParam(float))); + m_ringList = new ImageRingList(this); + m_filesystem = new FilesystemWidget(m_ringList, this); + connect(m_filesystem, SIGNAL(fileSelected(int)), this, SLOT(loadFile(int))); + QDockWidget *stretchDock = new QDockWidget(tr("Stretch"), this); stretchDock->setWidget(stretchPanel); stretchDock->setObjectName("strechDock"); - addDockWidget(Qt::LeftDockWidgetArea, stretchDock); + addDockWidget(Qt::TopDockWidgetArea, stretchDock); + + QDockWidget *filesystemDock = new QDockWidget(tr("Filesystem"), this); + filesystemDock->setWidget(m_filesystem); + filesystemDock->setObjectName("filesystemDock"); + addDockWidget(Qt::LeftDockWidgetArea, filesystemDock); setWindowTitle(tr("Tenmon")); - m_ringList = new ImageRingList(this); connect(m_ringList, SIGNAL(pixmapLoaded(Image*)), this, SLOT(pixmapLoaded(Image*))); - connect(m_ringList, SIGNAL(currentImageChanged()), this, SLOT(updateWindowTitle())); + connect(m_ringList, SIGNAL(currentImageChanged(int)), this, SLOT(updateWindowTitle())); connect(m_ringList, SIGNAL(infoLoaded(ImageInfoData)), m_info, SLOT(setInfo(ImageInfoData))); + connect(m_ringList, SIGNAL(currentImageChanged(int)), m_filesystem, SLOT(selectFile(int))); QMenu *fileMenu = new QMenu(tr("File"), this); - fileMenu->addAction(tr("Open"), this, SLOT(openFile()), QKeySequence("Ctrl+O")); + fileMenu->addAction(tr("Open"), this, SLOT(loadFile()), QKeySequence("Ctrl+O")); fileMenu->addAction(tr("Copy marked files"), this, SLOT(copyMarked())); fileMenu->addAction(tr("Save as"), this, SLOT(saveAs()), QKeySequence("Ctrl+S")); QAction *liveModeAction = fileMenu->addAction(tr("Live mode"), this, SLOT(liveMode(bool))); @@ -117,6 +126,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) QMenu *dockMenu = new QMenu(tr("Docks"), this); dockMenu->addAction(infoDock->toggleViewAction()); dockMenu->addAction(stretchDock->toggleViewAction()); + dockMenu->addAction(filesystemDock->toggleViewAction()); menuBar()->addMenu(dockMenu); setupSigterm(); @@ -128,6 +138,9 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) if(standardLocations.size()) _lastDir = standardLocations.first(); + _lastDir = settings.value("mainwindow/lastdir", _lastDir).toString(); + m_filesystem->setDir(_lastDir); + QStringList args = QCoreApplication::arguments(); args.removeFirst(); for(auto &arg : args) @@ -138,6 +151,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) m_ringList->setFile(info.canonicalFilePath()); updateWindowTitle(); _lastDir = info.absoluteDir().absolutePath(); + settings.setValue("mainwindow/lastdir", _lastDir); break; } } @@ -229,18 +243,34 @@ void MainWindow::pixmapLoaded(Image *image) } } -void MainWindow::openFile() +void MainWindow::loadFile() { QString file = QFileDialog::getOpenFileName(this, tr("Open file"), _lastDir, tr("Images (*.jpg *.jpeg *.png *.cr2 *.fit *.fits *.JPG *.JPEG *.PNG *.CR2 *.FIT *.FITS)")); - if(!file.isEmpty()) + loadFile(file); +} + +void MainWindow::loadFile(const QString path) +{ + if(!path.isEmpty()) { - QFileInfo info(file); + QFileInfo info(path); m_ringList->setFile(info.canonicalFilePath()); updateWindowTitle(); - _lastDir = QFileInfo(file).absoluteDir().absolutePath(); + if(info.isDir()) + _lastDir = info.absolutePath(); + else + _lastDir = info.canonicalPath(); + QSettings settings; + settings.setValue("mainwindow/lastdir", _lastDir); + m_filesystem->setDir(_lastDir); } } +void MainWindow::loadFile(int row) +{ + m_ringList->loadFile(row); +} + void MainWindow::saveAs() { QString file = QFileDialog::getSaveFileName(this, tr("Save as"), _lastDir, tr("Images (*.jpg *.png *.JPG *.PNG)")); diff --git a/mainwindow.h b/mainwindow.h index 565ea85..e9401bd 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -8,6 +8,7 @@ #include "database.h" #include "imageinfo.h" #include "imagescrollareagl.h" +#include "filesystemwidget.h" class MainWindow : public QMainWindow { @@ -17,6 +18,7 @@ class MainWindow : public QMainWindow ImageRingList *m_ringList; Database *m_database; ImageInfo *m_info; + FilesystemWidget *m_filesystem; static int socketPair[2]; QSocketNotifier *socketNotifier; QString _lastDir; @@ -34,7 +36,9 @@ protected slots: void socketNotify(); void updateWindowTitle(); void pixmapLoaded(Image *image); - void openFile(); + void loadFile(); + void loadFile(const QString path); + void loadFile(int row); void saveAs(); void markImage(); void unmarkImage(); diff --git a/tenmon.pro b/tenmon.pro index d664770..b711a09 100644 --- a/tenmon.pro +++ b/tenmon.pro @@ -23,6 +23,7 @@ win32:LIBS += -LC:\msys64\mingw64\lib -LC:\msys64\mingw64\bin win32:INCLUDEPATH += C:\msys64\mingw64\include\ C:\msys64\mingw64\include\cfitsio SOURCES += main.cpp\ + filesystemwidget.cpp \ mainwindow.cpp \ imagescrollarea.cpp \ imageringlist.cpp \ @@ -35,6 +36,7 @@ SOURCES += main.cpp\ rawimage.cpp HEADERS += mainwindow.h \ + filesystemwidget.h \ imagescrollarea.h \ imageringlist.h \ database.h \