Mercurial > retraceit
changeset 2:97d2c8869c39
First prototype implementation of table view and player
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Mon, 23 Mar 2015 16:34:42 +0100 |
parents | 7a2637c3eb83 |
children | 248d5d1cdb38 |
files | src/CMakeLists.txt src/l10n/main_de_DE.ts src/mainwindow.cpp src/mainwindow.h src/metadataview.cpp src/metadataview.h src/pngplayer.cpp src/pngplayer.h |
diffstat | 8 files changed, 308 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/src/CMakeLists.txt Mon Mar 23 16:33:26 2015 +0100 +++ b/src/CMakeLists.txt Mon Mar 23 16:34:42 2015 +0100 @@ -17,6 +17,8 @@ strhelp.c util_win.c util_linux.c + metadataview.cpp + pngplayer.cpp ) find_package(Qt5LinguistTools)
--- a/src/l10n/main_de_DE.ts Mon Mar 23 16:33:26 2015 +0100 +++ b/src/l10n/main_de_DE.ts Mon Mar 23 16:34:42 2015 +0100 @@ -4,15 +4,51 @@ <context> <name>MainWindow</name> <message> - <location filename="../mainwindow.cpp" line="50"/> + <location filename="../mainwindow.cpp" line="54"/> + <source>Player</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../mainwindow.cpp" line="55"/> + <source>Filter/Details</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../mainwindow.cpp" line="67"/> <source>Error!</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../mainwindow.cpp" line="112"/> + <location filename="../mainwindow.cpp" line="129"/> <source>Failed to access directory: '%1'</source> <translation type="unfinished"></translation> </message> + <message> + <location filename="../mainwindow.cpp" line="134"/> + <source>Failed to access meta data file: '%1'</source> + <translation type="unfinished"></translation> + </message> + <message> + <location filename="../mainwindow.cpp" line="143"/> + <source>Parsed: '%1'</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>MetaDataView</name> + <message> + <location filename="../metadataview.cpp" line="47"/> + <source>Failed to parse file: '%1'</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>PNGPlayer</name> + <message> + <location filename="../pngplayer.cpp" line="32"/> + <source>Failed to load picture: '%1'</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>main</name>
--- a/src/mainwindow.cpp Mon Mar 23 16:33:26 2015 +0100 +++ b/src/mainwindow.cpp Mon Mar 23 16:34:42 2015 +0100 @@ -9,6 +9,8 @@ #include "mainwindow.h" #include "constants.h" +#include "metadataview.h" +#include "pngplayer.h" #include <QDebug> #include <QDialog> @@ -28,11 +30,13 @@ #include <QStandardPaths> #include <QStyle> #include <QStatusBar> +#include <QTabWidget> +#include <QVBoxLayout> MainWindow::MainWindow() : - mHasValidFolder(false) -{ + mDataView(NULL) { setStatusBar(new QStatusBar()); + resize(1190, 500); setupGUI(); readSettings(); @@ -42,8 +46,21 @@ } -void MainWindow::setupGUI() -{ +void MainWindow::setupGUI() { + QTabWidget *tabWidget = new QTabWidget; + mDataView = new MetaDataView(this); + mPlayer = new PNGPlayer(this); + + tabWidget->addTab(mPlayer, tr("Player")); + tabWidget->addTab(mDataView, tr("Filter/Details")); + tabWidget->setMovable(true); + + setCentralWidget(tabWidget); + + connect (mPlayer, &PNGPlayer::error, this, &MainWindow::showErrorMessage); + connect (mPlayer, &PNGPlayer::advance, mDataView, &MetaDataView::selectNextRow); + connect (mDataView, &MetaDataView::selectionChanged, mPlayer, + &PNGPlayer::showPicture); } void MainWindow::showErrorMessage(const QString& errMsg) { @@ -61,7 +78,7 @@ restoreGeometry(mSettings.value("geometry").toByteArray()); restoreState(mSettings.value("windowState").toByteArray()); } - +/* void MainWindow::dragEnterEvent(QDragEnterEvent *event) { if (event->mimeData()->hasUrls()) { @@ -104,7 +121,7 @@ { event->accept(); } - +*/ void MainWindow::setFolder(const QString& folder) { QFileInfo fi(folder); @@ -112,6 +129,19 @@ showErrorMessage(tr("Failed to access directory: '%1'").arg(folder)); } QDir dir = QDir(folder); + QFileInfo metaData = dir.absoluteFilePath("metadata.csv"); + if (!metaData.exists() || !metaData.isReadable()) { + showErrorMessage(tr("Failed to access meta data file: '%1'").arg( + metaData.filePath())); - // TODO; + } + QString errorMsg = mDataView->parseMetaData(metaData.filePath()); + if (!errorMsg.isEmpty()) { + showErrorMessage(errorMsg); + return; + } + statusBar()->showMessage(tr("Parsed: '%1'").arg(metaData.filePath())); + qDebug() << "Parsed: " << metaData.filePath(); + mCurFolder = folder; + mPlayer->setBaseDir(folder); }
--- a/src/mainwindow.h Mon Mar 23 16:33:26 2015 +0100 +++ b/src/mainwindow.h Mon Mar 23 16:34:42 2015 +0100 @@ -18,6 +18,8 @@ class QDragLeaveEvent; class QDragMoveEvent; class QDragEnterEvent; +class MetaDataView; +class PNGPlayer; class MainWindow : public QMainWindow { @@ -36,12 +38,12 @@ /** @brief Restores the last window state */ void readSettings(); - /* The drag drop actions */ + /* The drag drop actions void dragEnterEvent(QDragEnterEvent *event); void dragMoveEvent(QDragMoveEvent *event); void dragLeaveEvent(QDragLeaveEvent *event); void dropEvent(QDropEvent *event); - + */ public slots: /** @brief set an absolute folder to read a metadata.csv from. */ void setFolder(const QString &folder); @@ -53,6 +55,7 @@ private: QSettings mSettings; - bool mHasValidFolder; QString mCurFolder; + MetaDataView *mDataView; + PNGPlayer *mPlayer; };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/metadataview.cpp Mon Mar 23 16:34:42 2015 +0100 @@ -0,0 +1,86 @@ +#include "metadataview.h" +#include "qxtcsvmodel.h" + +#include <QTextCodec> +#include <QTableView> +#include <QSortFilterProxyModel> +#include <QVBoxLayout> +#include <QLabel> +#include <QDebug> +#include <QHeaderView> +#include <QModelIndex> +#include <QItemSelectionModel> + +MetaDataView::MetaDataView(QWidget *parent, Qt::WindowFlags f) : + QWidget(parent, f) { + /* Create models */ + mSortModel = new QSortFilterProxyModel; + mCSVModel = new QxtCsvModel; + setupGUI(); + + connect(mView->selectionModel(), &QItemSelectionModel::selectionChanged, + this, &MetaDataView::viewSelectionChanged); + return; +} + +void MetaDataView::setupGUI() { + QVBoxLayout *baseLayout = new QVBoxLayout; + mView = new QTableView; + mView->setModel(mSortModel); + + mView->horizontalHeader()->setStretchLastSection(true); + mView->resizeColumnsToContents(); +// mView->setColumnWidth(0, 60); + mView->setSelectionBehavior(QAbstractItemView::SelectRows); + mView->setSelectionMode(QAbstractItemView::SingleSelection); + mView->setSortingEnabled(true); + mView->setEditTriggers(QAbstractItemView::NoEditTriggers); + + baseLayout->addWidget(mView); + + setLayout(baseLayout); +} + +QString MetaDataView::parseMetaData(const QString& filePath) { + mCSVModel->setSource(filePath, true, ';', QTextCodec::codecForName("UTF8")); + if (!mCSVModel->rowCount()) { + return tr("Failed to parse file: '%1'").arg(filePath); + } + + mSortModel->setSourceModel(mCSVModel); + qDebug() << "Parsed: " << mCSVModel->rowCount() << " rows."; + return QString(); +} + +void MetaDataView::viewSelectionChanged(const QItemSelection& selected, + const QItemSelection& deselected) { + /* One row selected */ + Q_ASSERT(selected.indexes().count() == mCSVModel->columnCount()); + const QModelIndex idx = selected.indexes()[0]; + emit selectionChanged(idx.data().toString(), QString()); + qDebug() << "Selection changed: " << idx.data(); +} + +void MetaDataView::selectNextRow() { + QItemSelectionModel *selection = mView->selectionModel(); + QModelIndexList selected = selection->selectedIndexes(); + int row = 0, + col = 0; + if (selected.isEmpty()) { + qDebug() << "Selection empty. Start at row 0"; + if (!mSortModel->hasIndex(row, col)) { + qDebug() << "Empty model. Failed to advance."; + return; + } + } else { + QModelIndex old = selection->selectedIndexes().first(); + if (!mSortModel->hasIndex(old.row() + 1, old.column())) { + qDebug() << "No more rows."; + return; + } + row = old.row() + 1; + col = old.column(); + } + QModelIndex newIdx = mSortModel->index(row, col); + selection->select(newIdx, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/metadataview.h Mon Mar 23 16:34:42 2015 +0100 @@ -0,0 +1,53 @@ +#ifndef METADATAVIEW_H +#define METADATAVIEW_H +/* Copyright (C) 2014 by Intevation GmbH + * + * This file is Free Software under the GNU GPL (v>=2) + * and comes with ABSOLUTELY NO WARRANTY! + * See LICENSE.txt for details. + */ +#include <QWidget> +#include <QItemSelection> + +class QTableView; +class QSortFilterProxyModel; +class QxtCsvModel; +class MetaDataView: public QWidget +{ + Q_OBJECT + +public: + MetaDataView(QWidget * parent = 0, Qt::WindowFlags f = 0); + +protected: + void setupGUI(); + +public: + /**@brief parse a metadata file and set up the model accordingly. + * + * @returns a localized error message in case of parsing errors. Or + * an empty string on success. */ + QString parseMetaData(const QString& fileName); + +Q_SIGNALS: + /**@brief emited when the selection changed. + * + * @param pictureFile: The file that is now selected. + * @param info: Additional info to show with the file.*/ + void selectionChanged(const QString& pictureFile, const QString& info); + +protected slots: + void viewSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected); + +public slots: + /**@brief selects the next row and emits a selection changed signal */ + void selectNextRow(); + +protected: + QxtCsvModel *mCSVModel; + QSortFilterProxyModel *mSortModel; + QTableView *mView; +}; + + +#endif // METADATAVIEW_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pngplayer.cpp Mon Mar 23 16:34:42 2015 +0100 @@ -0,0 +1,36 @@ +/* Copyright (C) 2014 by Intevation GmbH + * + * This file is Free Software under the GNU GPL (v>=2) + * and comes with ABSOLUTELY NO WARRANTY! + * See LICENSE.txt for details. + */ +#include "pngplayer.h" +#include <QVBoxLayout> +#include <QPixmap> +#include <QLabel> + +PNGPlayer::PNGPlayer(QWidget *parent, Qt::WindowFlags f) : QWidget(parent, f) { + setupGUI(); + return; +} + +void PNGPlayer::setupGUI() { + QVBoxLayout *baseLayout = new QVBoxLayout; + mPNGLabel = new QLabel; + baseLayout->addWidget(mPNGLabel); + connect(&mAdvanceTimer, SIGNAL(timeout()), this, SIGNAL(advance())); + setLayout(baseLayout); + mAdvanceTimer.setInterval(2000); + mAdvanceTimer.start(); +} + +void PNGPlayer::showPicture(const QString& fileName, const QString& info) { + QPixmap pic(mBaseDir.filePath(fileName)); + /* If this is too slow we could use a pixmap cache here and do + * some intelligent preloading */ + if (pic.isNull()) { + emit error(tr("Failed to load picture: '%1'").arg(fileName)); + return; + } + mPNGLabel->setPixmap(pic); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pngplayer.h Mon Mar 23 16:34:42 2015 +0100 @@ -0,0 +1,50 @@ +#ifndef PNGPLAYER_H +#define PNGPLAYER_H +/* Copyright (C) 2014 by Intevation GmbH + * + * This file is Free Software under the GNU GPL (v>=2) + * and comes with ABSOLUTELY NO WARRANTY! + * See LICENSE.txt for details. + */ +#include <QWidget> +#include <QDir> +#include <QTimer> + +class QLabel; + +class PNGPlayer: public QWidget +{ + Q_OBJECT + +public: + PNGPlayer (QWidget * parent = 0, Qt::WindowFlags f = 0); + +protected: + void setupGUI(); + +public slots: + /**@brief show a PNG in the viewer. + * + * @param fileName: The picture file to show. + * @param info: Additional meta data to show with the image. + */ + void showPicture(const QString& fileName, const QString& info); + + void setBaseDir(const QString& dirName) { mBaseDir.setPath(dirName); } + +Q_SIGNALS: + /** @brief Emited if something went wrong. e.g. file not readable */ + void error(const QString& msg); + + /** @brief Emited if the player wants to advance to the next picture */ + void advance(); + +protected: + QLabel * mPNGLabel; + QDir mBaseDir; + QTimer mAdvanceTimer; +}; + + + +#endif // PNGPLAYER_H