Add filemanager
This commit is contained in:
@@ -0,0 +1,178 @@
|
||||
#include "filemanager.h"
|
||||
#include "ui_filemanager.h"
|
||||
|
||||
#include <QSettings>
|
||||
#include <QStandardPaths>
|
||||
#include <QDesktopServices>
|
||||
#include "loadimage.h"
|
||||
|
||||
FileManager::FileManager(const QSet<QString> &openFilter, QWidget *parent) : QMainWindow(parent)
|
||||
,ui(new Ui::FileManager)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->leftTab->setOpenFilter(openFilter);
|
||||
ui->rightTab->setOpenFilter(openFilter);
|
||||
|
||||
connect(ui->leftTab, &DirView::dirChanged, ui->leftPath, &QLineEdit::setText);
|
||||
connect(ui->rightTab, &DirView::dirChanged, ui->rightPath, &QLineEdit::setText);
|
||||
connect(ui->leftTab, &DirView::openFile, this, &FileManager::openFile);
|
||||
connect(ui->rightTab, &DirView::openFile, this, &FileManager::openFile);
|
||||
|
||||
QStringList standardLocations = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation);
|
||||
QString picturesPath;
|
||||
if(standardLocations.size())
|
||||
picturesPath = standardLocations.first();
|
||||
|
||||
QSettings settings;
|
||||
ui->leftTab->setDir(settings.value("filemanager/leftTabPath", picturesPath).toString());
|
||||
ui->leftTab->header()->restoreState(settings.value("filemanager/leftTabHeader").toByteArray());
|
||||
ui->rightTab->setDir(settings.value("filemanager/rightTabPath", picturesPath).toString());
|
||||
ui->rightTab->header()->restoreState(settings.value("filemanager/rightTabHeader").toByteArray());
|
||||
restoreGeometry(settings.value("filemanager/geometry").toByteArray());
|
||||
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
}
|
||||
|
||||
FileManager::~FileManager()
|
||||
{
|
||||
QSettings settings;
|
||||
settings.setValue("filemanager/leftTabPath", ui->leftTab->dir());
|
||||
settings.setValue("filemanager/leftTabHeader", ui->leftTab->header()->saveState());
|
||||
settings.setValue("filemanager/rightTabPath", ui->rightTab->dir());
|
||||
settings.setValue("filemanager/rightTabHeader", ui->leftTab->header()->saveState());
|
||||
settings.setValue("filemanager/geometry", saveGeometry());
|
||||
delete ui;
|
||||
}
|
||||
|
||||
QCache<QString, ImageInfoData>* DirFileSystemModel::getCacheInstance()
|
||||
{
|
||||
static bool init = true;
|
||||
static QCache<QString, ImageInfoData> cache;
|
||||
if(!init)
|
||||
{
|
||||
cache.setMaxCost(10000);
|
||||
init = false;
|
||||
}
|
||||
return &cache;
|
||||
}
|
||||
|
||||
DirFileSystemModel::DirFileSystemModel(QObject *parent) : QFileSystemModel(parent)
|
||||
{
|
||||
_cache = getCacheInstance();
|
||||
setFilter(QDir::AllEntries | QDir::NoDot);
|
||||
}
|
||||
|
||||
void DirFileSystemModel::setDir(const QString &path)
|
||||
{
|
||||
_dir = index(path);
|
||||
}
|
||||
|
||||
QString DirFileSystemModel::dir() const
|
||||
{
|
||||
return fileInfo(_dir).canonicalFilePath();
|
||||
}
|
||||
|
||||
Qt::ItemFlags DirFileSystemModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
return QFileSystemModel::flags(index) & ~Qt::ItemIsEditable;
|
||||
}
|
||||
|
||||
int DirFileSystemModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
return QFileSystemModel::columnCount(parent) + 1;
|
||||
}
|
||||
|
||||
QVariant DirFileSystemModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if(index.column() >= QFileSystemModel::columnCount() && role == Qt::DisplayRole)
|
||||
{
|
||||
QFileInfo info = fileInfo(index);
|
||||
QString path = info.canonicalFilePath();
|
||||
QString suffix = info.suffix();
|
||||
ImageInfoData *infoData;
|
||||
if(_cache->contains(path))
|
||||
{
|
||||
infoData = _cache->object(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
infoData = new ImageInfoData;
|
||||
if(isFITS(suffix))
|
||||
readFITSHeader(path, *infoData);
|
||||
else if(isXISF(suffix))
|
||||
readXISFHeader(path, *infoData);
|
||||
_cache->insert(path, infoData);
|
||||
}
|
||||
for(auto &record : infoData->fitsHeader)
|
||||
if(record.key == "OBJECT")
|
||||
return record.value;
|
||||
|
||||
return "";
|
||||
}
|
||||
return QFileSystemModel::data(index, role);
|
||||
}
|
||||
|
||||
QVariant DirFileSystemModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if(orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= QFileSystemModel::columnCount())
|
||||
return "FITS";
|
||||
|
||||
return QFileSystemModel::headerData(section, orientation, role);
|
||||
}
|
||||
|
||||
bool DirFileSystemModel::hasChildren(const QModelIndex &parent) const
|
||||
{
|
||||
if(parent.parent() == _dir)return false;
|
||||
|
||||
return QFileSystemModel::hasChildren(parent);
|
||||
}
|
||||
|
||||
DirView::DirView(QWidget *parent) : QTreeView(parent)
|
||||
{
|
||||
_dirFileSystemModel = new DirFileSystemModel(this);
|
||||
#ifdef Q_OS_LINUX
|
||||
_dirFileSystemModel->setRootPath("/");
|
||||
#elif defined(Q_OS_WIN64)
|
||||
_dirFileSystemModel->setRootPath("C:/");
|
||||
#endif
|
||||
_dirFileSystemModel->setReadOnly(false);
|
||||
setDragEnabled(true);
|
||||
setAcceptDrops(true);
|
||||
|
||||
setModel(_dirFileSystemModel);
|
||||
setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
|
||||
connect(this, &QTreeView::doubleClicked, [this](const QModelIndex &index){
|
||||
QFileInfo info = _dirFileSystemModel->fileInfo(index);
|
||||
if(_dirFileSystemModel->isDir(index))
|
||||
{
|
||||
setDir(info.canonicalFilePath());
|
||||
}
|
||||
else if(info.isFile())
|
||||
{
|
||||
if(_openFilter.contains(info.suffix()))
|
||||
emit openFile(info.absoluteFilePath());
|
||||
else
|
||||
QDesktopServices::openUrl(QUrl::fromLocalFile(info.absoluteFilePath()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void DirView::setDir(const QString &path)
|
||||
{
|
||||
_dirFileSystemModel->setDir(path);
|
||||
setRootIndex(_dirFileSystemModel->index(path, 0));
|
||||
clearSelection();
|
||||
emit dirChanged(path);
|
||||
}
|
||||
|
||||
QString DirView::dir() const
|
||||
{
|
||||
return _dirFileSystemModel->dir();
|
||||
}
|
||||
|
||||
void DirView::setOpenFilter(const QSet<QString> &openFilter)
|
||||
{
|
||||
_openFilter = openFilter;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
#ifndef FILEMANAGER_H
|
||||
#define FILEMANAGER_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QCache>
|
||||
#include <QFileSystemModel>
|
||||
#include <QTreeView>
|
||||
#include "imageinfodata.h"
|
||||
|
||||
namespace Ui {
|
||||
class FileManager;
|
||||
}
|
||||
|
||||
class FileManager : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FileManager(const QSet<QString> &openFilter, QWidget *parent = nullptr);
|
||||
~FileManager();
|
||||
signals:
|
||||
void openFile(const QString &path);
|
||||
private:
|
||||
Ui::FileManager *ui;
|
||||
};
|
||||
|
||||
class DirFileSystemModel : public QFileSystemModel
|
||||
{
|
||||
mutable QCache<QString, ImageInfoData> *_cache = nullptr;
|
||||
static QCache<QString, ImageInfoData>* getCacheInstance();
|
||||
QModelIndex _dir;
|
||||
public:
|
||||
explicit DirFileSystemModel(QObject *parent = nullptr);
|
||||
void setDir(const QString &path);
|
||||
QString dir() const;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
int columnCount(const QModelIndex &parent) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||
bool hasChildren(const QModelIndex &parent) const override;
|
||||
};
|
||||
|
||||
class DirView : public QTreeView
|
||||
{
|
||||
Q_OBJECT
|
||||
DirFileSystemModel *_dirFileSystemModel = nullptr;
|
||||
QSet<QString> _openFilter;
|
||||
public:
|
||||
explicit DirView(QWidget *parent = nullptr);
|
||||
void setDir(const QString &path);
|
||||
QString dir() const;
|
||||
void setOpenFilter(const QSet<QString> &openFilter);
|
||||
signals:
|
||||
void dirChanged(const QString &path);
|
||||
void openFile(const QString &path);
|
||||
};
|
||||
|
||||
#endif // FILEMANAGER_H
|
||||
@@ -0,0 +1,68 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>FileManager</class>
|
||||
<widget class="QMainWindow" name="FileManager">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1282</width>
|
||||
<height>858</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>File Manager</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="leftPath">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="DirView" name="leftTab"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="rightPath">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="DirView" name="rightTab"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menubar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1282</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>DirView</class>
|
||||
<extends>QTreeView</extends>
|
||||
<header>filemanager.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <QMenu>
|
||||
#include <QSettings>
|
||||
#include <QHeaderView>
|
||||
#include <QMimeDatabase>
|
||||
|
||||
FilesystemWidget::FilesystemWidget(QAbstractItemModel *model, QWidget *parent) : QWidget(parent)
|
||||
, m_model(model)
|
||||
@@ -117,6 +118,7 @@ void Filetree::contextMenuEvent(QContextMenuEvent *event)
|
||||
{
|
||||
setRootIndex(index);
|
||||
m_rootDir = m_fileSystemModel->filePath(index);
|
||||
m_fileSystemModel->setRootPath(m_rootDir);
|
||||
}
|
||||
else if(a == resetRoot)
|
||||
{
|
||||
@@ -127,6 +129,7 @@ void Filetree::contextMenuEvent(QContextMenuEvent *event)
|
||||
{
|
||||
setRootIndex(rootIndex().parent());
|
||||
m_rootDir = m_fileSystemModel->filePath(rootIndex().parent());
|
||||
m_fileSystemModel->setRootPath(m_rootDir);
|
||||
}
|
||||
else if(a == copy)
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <QWidget>
|
||||
#include <QFileSystemModel>
|
||||
#include <QIdentityProxyModel>
|
||||
#include <QListView>
|
||||
#include <QTreeView>
|
||||
|
||||
|
||||
+13
-2
@@ -409,18 +409,19 @@ bool loadImage(const QString &path, ImageInfoData &info, std::shared_ptr<RawImag
|
||||
{
|
||||
bool ret = false;
|
||||
QElapsedTimer timer;
|
||||
QFileInfo fileInfo(path);
|
||||
timer.start();
|
||||
if(path.endsWith(".CR2", Qt::CaseInsensitive) || path.endsWith(".CR3", Qt::CaseInsensitive) || path.endsWith(".NEF", Qt::CaseInsensitive) || path.endsWith(".DNG", Qt::CaseInsensitive))
|
||||
{
|
||||
ret = loadRAW(path, info, rawImage);
|
||||
qDebug() << "LoadRAW" << timer.elapsed();
|
||||
}
|
||||
else if(path.endsWith(".FIT", Qt::CaseInsensitive) || path.endsWith(".FITS", Qt::CaseInsensitive) || path.endsWith(".FZ", Qt::CaseInsensitive) || path.endsWith(".FTS", Qt::CaseInsensitive))
|
||||
else if(isFITS(fileInfo.suffix()))
|
||||
{
|
||||
ret = loadFITS(path, info, rawImage, planar, index);
|
||||
qDebug() << "LoadFITS" << timer.elapsed();
|
||||
}
|
||||
else if(path.endsWith(".XISF", Qt::CaseInsensitive))
|
||||
else if(isXISF(fileInfo.suffix()))
|
||||
{
|
||||
ret = loadXISF(path, info, rawImage, planar, index);
|
||||
qDebug() << "LoadXISF" << timer.elapsed();
|
||||
@@ -444,3 +445,13 @@ bool loadImage(const QString &path, ImageInfoData &info, std::shared_ptr<RawImag
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool isFITS(const QString &suffix)
|
||||
{
|
||||
return suffix.compare("fits", Qt::CaseInsensitive) == 0 || suffix.compare("fit", Qt::CaseInsensitive) == 0 || suffix.compare("fts", Qt::CaseInsensitive) == 0 || suffix.compare("fz", Qt::CaseInsensitive) == 0;
|
||||
}
|
||||
|
||||
bool isXISF(const QString &suffix)
|
||||
{
|
||||
return suffix.compare("xisf", Qt::CaseInsensitive) == 0;
|
||||
}
|
||||
|
||||
@@ -10,5 +10,7 @@ QString makeUNCPath(const QString &path);
|
||||
bool readFITSHeader(const QString &path, ImageInfoData &info);
|
||||
bool readXISFHeader(const QString &path, ImageInfoData &info);
|
||||
bool loadImage(const QString &path, ImageInfoData &info, std::shared_ptr<RawImage> &rawImage, int index, bool planar = false);
|
||||
bool isFITS(const QString &suffix);
|
||||
bool isXISF(const QString &suffix);
|
||||
|
||||
#endif // LOADIMAGE_H
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "settingsdialog.h"
|
||||
#include "histogram.h"
|
||||
#include "batchprocessing.h"
|
||||
#include "filemanager.h"
|
||||
|
||||
#ifdef __linux__
|
||||
#include <sys/ioctl.h>
|
||||
@@ -66,6 +67,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
|
||||
_openFilter.append(tr(";;All files (*)"));
|
||||
nameFilter.append({"fit", "fits", "fts", "fz", "xisf", "cr2", "cr3", "nef", "dng"});
|
||||
QImageReader::setAllocationLimit(0);
|
||||
_openSuffix = {nameFilter.constBegin(), nameFilter.constEnd()};
|
||||
|
||||
m_info = new ImageInfo(this);
|
||||
QDockWidget *infoDock = new QDockWidget(tr("Image info"), this);
|
||||
@@ -176,6 +178,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
|
||||
fileMenu->addAction(tr("Open directory recursively"), this, &MainWindow::loadDir);
|
||||
QAction *saveAs = fileMenu->addAction(tr("Save as"), QKeySequence::Save, this, &MainWindow::saveAs);
|
||||
fileMenu->addSeparator();
|
||||
fileMenu->addAction(tr("File manager"), this, &MainWindow::openFileManager);
|
||||
fileMenu->addAction(tr("Copy marked files"), Qt::Key_F5, this, &MainWindow::copyMarked);
|
||||
fileMenu->addAction(tr("Move marked files"), Qt::Key_F6, this, &MainWindow::moveMarked);
|
||||
fileMenu->addAction(tr("Move marked files to trash"), QKeySequence::Delete, this, &MainWindow::deleteMarked);
|
||||
@@ -808,6 +811,13 @@ void MainWindow::checkNewVersion()
|
||||
});
|
||||
}
|
||||
|
||||
void MainWindow::openFileManager()
|
||||
{
|
||||
FileManager *filemanager = new FileManager(_openSuffix);
|
||||
connect(filemanager, &FileManager::openFile, this, static_cast<void (MainWindow::*)(const QString&)>(&MainWindow::loadFile));
|
||||
filemanager->show();
|
||||
}
|
||||
|
||||
void MainWindow::updateWindowTitle()
|
||||
{
|
||||
ImagePtr ptr = m_ringList->currentImage();
|
||||
|
||||
@@ -30,6 +30,7 @@ class MainWindow : public QMainWindow
|
||||
bool _maximized;
|
||||
QString _openFilter;
|
||||
QString _saveFilter;
|
||||
QSet<QString> _openSuffix;
|
||||
public:
|
||||
MainWindow(QWidget *parent = 0);
|
||||
~MainWindow() override;
|
||||
@@ -67,6 +68,7 @@ public slots:
|
||||
void showSettingsDialog();
|
||||
void exportCSV();
|
||||
void checkNewVersion();
|
||||
void openFileManager();
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
||||
@@ -455,11 +455,11 @@ void File::loadFitsKeywords()
|
||||
{
|
||||
_fitsKeywordsLoaded = true;
|
||||
ImageInfoData info;
|
||||
if(suffix().toLower() == "xisf")
|
||||
if(isXISF(suffix()))
|
||||
{
|
||||
readXISFHeader(_path, info);
|
||||
}
|
||||
else if(suffix().toLower() == "fits" || suffix().toLower() == "fit" || suffix().toLower() == "fz")
|
||||
else if(isFITS(suffix()))
|
||||
{
|
||||
readFITSHeader(_path, info);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user