From 46cb4b079be113996214660020d6ef0c3d1f1e80 Mon Sep 17 00:00:00 2001 From: Javier Date: Sun, 14 Jun 2015 03:32:35 +0200 Subject: paperless replay also working --- mainwindow.cc | 41 +++++++++++++++--- mainwindow.h | 6 +++ mainwindow.ui | 90 +++++++++++++++++++++++++++++++++++---- notebookview.cc | 2 +- paperreplay.cc | 37 +++++++++++++++- paperreplay.h | 6 ++- paperreplaymodel.cc | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++ paperreplaymodel.h | 35 ++++++++++++++++ scribiu.pro | 6 ++- 9 files changed, 323 insertions(+), 19 deletions(-) create mode 100644 paperreplaymodel.cc create mode 100644 paperreplaymodel.h diff --git a/mainwindow.cc b/mainwindow.cc index e269c61..dd687a2 100644 --- a/mainwindow.cc +++ b/mainwindow.cc @@ -8,7 +8,9 @@ MainWindow::MainWindow(QWidget *parent) : _notebooks(new NotebookModel(this)), _manager(new SmartpenManager(this)), _media(new Phonon::MediaObject(this)), - _mediaOutput(new Phonon::AudioOutput(this)) + _mediaOutput(new Phonon::AudioOutput(this)), + _replay(new PaperReplay(this)), + _replayModel(new PaperReplayModel(_replay, this)) { ui->setupUi(this); ui->notebookTree->setModel(_notebooks); @@ -16,6 +18,11 @@ MainWindow::MainWindow(QWidget *parent) : ui->notebookTree->header()->setResizeMode(1, QHeaderView::Fixed); ui->notebookTree->header()->setResizeMode(2, QHeaderView::Fixed); ui->notebookTree->expandAll(); + ui->notebookView->setVisible(false); + ui->paperReplayView->setModel(_replayModel); + ui->paperReplayView->horizontalHeader()->setResizeMode(0, QHeaderView::Stretch); + ui->paperReplayView->horizontalHeader()->setResizeMode(1, QHeaderView::Fixed); + ui->paperReplayView->setVisible(false); Phonon::createPath(_media, _mediaOutput); ui->replaySlider->setMediaObject(_media); ui->pauseButton->setVisible(false); @@ -32,22 +39,38 @@ void MainWindow::closeNotebook() { _curPenName.clear(); _curNotebookName.clear(); + _replay->close(); ui->notebookView->setNotebook(QString()); + ui->notebookView->setVisible(false); + ui->paperReplayView->setVisible(false); } void MainWindow::openNotebook(const QString &pen, const QString ¬ebook) { if (_curPenName == pen && _curNotebookName == notebook) return; + closeNotebook(); + _curPenName = pen; _curNotebookName = notebook; - QString nbDir = _notebooks->notebookDirectory(_curPenName, _curNotebookName); + if (_curNotebookName == PAPER_REPLAY) { + QString replayDir = _notebooks->paperReplayDirectory(_curPenName); + + if (_replay->open(replayDir, 0)) { + _replayModel->refresh(); + } - qDebug() << "Opening notebook" << _curPenName << _curNotebookName << nbDir; + ui->paperReplayView->setVisible(true); + } else { + QString nbDir = _notebooks->notebookDirectory(_curPenName, _curNotebookName); - ui->notebookView->setPaperReplay(_notebooks->paperReplayDirectory(_curPenName)); - ui->notebookView->setNotebook(nbDir); + qDebug() << "Opening notebook" << _curPenName << _curNotebookName << nbDir; + + ui->notebookView->setPaperReplay(_notebooks->paperReplayDirectory(_curPenName)); + ui->notebookView->setNotebook(nbDir); + ui->notebookView->setVisible(true); + } } void MainWindow::handleNotebookSelected(const QModelIndex &index) @@ -56,6 +79,7 @@ void MainWindow::handleNotebookSelected(const QModelIndex &index) closeNotebook(); return; } + QModelIndex parent = index.parent(); if (!parent.isValid()) { closeNotebook(); @@ -73,6 +97,12 @@ void MainWindow::handleCurPageChanged() ui->pageEdit->setText(QString::number(ui->notebookView->curPage() + 1)); } +void MainWindow::handlePaperReplaySelected(const QModelIndex &index) +{ + QString file = _replayModel->sessionFilename(index); + handlePaperReplayRequested(file, 0); +} + void MainWindow::handlePaperReplayRequested(const QString &file, qint64 time) { QFileInfo finfo(file); @@ -113,7 +143,6 @@ void MainWindow::handlePaperReplayPause() void MainWindow::handleMediaStateChange(Phonon::State state) { - qDebug() << "Media state change:" << state; switch (state) { case Phonon::PlayingState: ui->playButton->setVisible(false); diff --git a/mainwindow.h b/mainwindow.h index 7a8fab4..cafec49 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -5,6 +5,7 @@ #include #include #include "notebookmodel.h" +#include "paperreplaymodel.h" #include "smartpenmanager.h" namespace Ui { @@ -26,6 +27,7 @@ public slots: private slots: void handleNotebookSelected(const QModelIndex &index); void handleCurPageChanged(); + void handlePaperReplaySelected(const QModelIndex &index); void handlePaperReplayRequested(const QString &file, qint64 time); void handlePaperReplayPlay(); void handlePaperReplayPause(); @@ -35,12 +37,16 @@ private: Ui::MainWindow *ui; NotebookModel *_notebooks; SmartpenManager *_manager; + Phonon::MediaObject *_media; Phonon::AudioOutput *_mediaOutput; qint64 _pendingSeek; QString _curPenName; QString _curNotebookName; + + PaperReplay *_replay; + PaperReplayModel *_replayModel; }; #endif // MAINWINDOW_H diff --git a/mainwindow.ui b/mainwindow.ui index 4a0e1ea..1662e7f 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -183,14 +183,53 @@ - - - Qt::ScrollBarAlwaysOn + + + 0 - - Qt::ScrollBarAlwaysOn - - + + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAlwaysOn + + + + + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + false + + + false + + + false + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + @@ -224,7 +263,9 @@ ... - + + + @@ -444,6 +485,38 @@ + + paperReplayView + activated(QModelIndex) + MainWindow + handlePaperReplaySelected(QModelIndex) + + + 597 + 193 + + + 358 + 192 + + + + + paperReplayView + doubleClicked(QModelIndex) + MainWindow + handlePaperReplaySelected(QModelIndex) + + + 597 + 193 + + + 358 + 192 + + + handleNotebookSelected(QModelIndex) @@ -452,5 +525,6 @@ handlePaperReplayRequested(QString,qint64) handlePaperReplayPlay() handlePaperReplayPause() + handlePaperReplaySelected(QModelIndex) diff --git a/notebookview.cc b/notebookview.cc index 9553451..2bca4f7 100644 --- a/notebookview.cc +++ b/notebookview.cc @@ -163,7 +163,7 @@ bool NotebookView::createPages() if (pens.isEmpty()) return false; // Failure to open paperreplay data is not fatal - bool haveReplay = _replay->open(_replayPath, pens[0], _nb->guid()); + bool haveReplay = _replay->open(_replayPath, _nb->guid()); QList pagesWithStrokes = _nb->pagesWithStrokes(pens.first()); Q_ASSERT(_pages.isEmpty()); diff --git a/paperreplay.cc b/paperreplay.cc index e0e654e..5baeac7 100644 --- a/paperreplay.cc +++ b/paperreplay.cc @@ -17,6 +17,17 @@ bool readUtfString(QDataStream &stream, QString &s) s = QString::fromUtf8(buffer); return true; } + +QString findPenSerial(const QString &path) +{ + QDir dir(path + "/userdata"); + QStringList entries = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); + if (entries.isEmpty()) { + return QString(); + } else { + return entries.first(); + } +} } PaperReplay::PaperReplay(QObject *parent) : @@ -47,6 +58,11 @@ quint64 PaperReplay::Session::id() const return d ? d->id : 0; } +QString PaperReplay::Session::name() const +{ + return d->name; +} + QString PaperReplay::Session::fileName() const { return d->file; @@ -62,6 +78,11 @@ qint64 PaperReplay::Session::endTime() const return d->end; } +bool PaperReplay::Session::startTimeLess(const Session &a, const Session &b) +{ + return a.d->start < b.d->start; +} + PaperReplay::SessionList::SessionList() { } @@ -90,8 +111,14 @@ QList PaperReplay::SessionList::sessionsDuringTime(qint64 return sessions; } -bool PaperReplay::open(const QString &path, const QString &penSerial, quint64 notebookGuid) +bool PaperReplay::open(const QString &path, quint64 notebookGuid) { + QString penSerial = findPenSerial(path); + if (penSerial.isEmpty()) { + qDebug() << "Cannot open paper replay:" << path << "does not contain any pen data"; + return false; + } + _dir.setPath(path + QString("/userdata/%1/Paper Replay/99/%2/sessions") .arg(penSerial) .arg(qulonglong(notebookGuid), notebookGuid == 0 ? 1 : 16, 16, QLatin1Char('0'))); @@ -123,6 +150,8 @@ bool PaperReplay::open(const QString &path, const QString &penSerial, quint64 no session.d->file = sessionDir.filePath(session.d->file); } + _sessions.insert(sessionId, session); + foreach (quint64 page, session.d->pages) { _byPageTime[page].insert(session.d->start, session); } @@ -133,9 +162,15 @@ bool PaperReplay::open(const QString &path, const QString &penSerial, quint64 no void PaperReplay::close() { _byPageTime.clear(); + _sessions.clear(); _dir.setPath(QString()); } +QList PaperReplay::sessions() const +{ + return _sessions.values(); +} + PaperReplay::SessionList PaperReplay::sessions(quint64 pageAddress) const { return SessionList(_byPageTime[pageAddress]); diff --git a/paperreplay.h b/paperreplay.h index c9eb6f2..a81e8a4 100644 --- a/paperreplay.h +++ b/paperreplay.h @@ -41,6 +41,8 @@ public: QString fileName() const; + static bool startTimeLess(const Session &a, const Session &b); + private: Session(quint64 id); QSharedDataPointer d; @@ -63,9 +65,10 @@ public: friend class PaperReplay; }; - bool open(const QString &path, const QString &penSerial, quint64 notebookGuid); + bool open(const QString &path, quint64 notebookGuid = 0); void close(); + QList sessions() const; SessionList sessions(quint64 pageAddress) const; private: @@ -79,6 +82,7 @@ private: private: QDir _dir; + QHash _sessions; QMap > _byPageTime; }; diff --git a/paperreplaymodel.cc b/paperreplaymodel.cc new file mode 100644 index 0000000..e818b9c --- /dev/null +++ b/paperreplaymodel.cc @@ -0,0 +1,119 @@ +#include "smartpen.h" +#include "notebookmodel.h" +#include "paperreplaymodel.h" + +PaperReplayModel::PaperReplayModel(PaperReplay *replay, QObject *parent) : + QAbstractTableModel(parent), _replay(replay) +{ +} + +QVariant PaperReplayModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) return QVariant(); + int row = index.row(); + int column = index.column(); + const PaperReplay::Session &session = _sessions.at(row); + switch (column) { + case 0: + switch (role) { + case Qt::DisplayRole: + return getSessionName(session); + } + break; + case 1: + switch (role) { + case Qt::DisplayRole: + return getSessionLength(session); + } + break; + } + + return QVariant(); +} + +QVariant PaperReplayModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + switch (orientation) { + case Qt::Horizontal: + switch (section) { + case 0: + switch (role) { + case Qt::DisplayRole: + return tr("Recording"); + } + break; + case 1: + switch (role) { + case Qt::DisplayRole: + return tr("Length"); + } + break; + } + break; + case Qt::Vertical: + break; + } + return QVariant(); +} + +int PaperReplayModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) return 0; + return _sessions.size(); +} + +int PaperReplayModel::columnCount(const QModelIndex &parent) const +{ + if (parent.isValid()) return 0; + return 2; +} + +QString PaperReplayModel::sessionFilename(const QModelIndex &index) const +{ + if (!index.isValid()) return QString(); + int row = index.row(); + const PaperReplay::Session &session = _sessions.at(row); + return session.fileName(); +} + +void PaperReplayModel::refresh() +{ + beginResetModel(); + _sessions = _replay->sessions(); + qSort(_sessions.begin(), _sessions.end(), PaperReplay::Session::startTimeLess); + endResetModel(); +} + +QString PaperReplayModel::getSessionName(const PaperReplay::Session &session) +{ + QString title = session.name(); + + if (title.isEmpty()) { + QDateTime date = Smartpen::fromPenTime(session.startTime()); + title = date.toString(Qt::DefaultLocaleLongDate); + } + + return title; +} + +QString PaperReplayModel::getSessionDate(const PaperReplay::Session &session) +{ + QDateTime date = Smartpen::fromPenTime(session.startTime()); + return date.toString(Qt::DefaultLocaleShortDate); +} + +QString PaperReplayModel::getSessionLength(const PaperReplay::Session &session) +{ + int secs = Smartpen::fromPenTime(session.startTime()).secsTo(Smartpen::fromPenTime(session.endTime())); + int mins = secs / 60; + secs %= 60; + int hours = mins / 60; + mins %= 60; + + const QChar fill('0'); + if (hours) { + return QString("%1:%2:%3").arg(hours).arg(mins, 2, 10, fill).arg(secs, 2, 10, fill); + } else { + return QString("%2:%3").arg(mins).arg(secs, 2, 10, fill); + } +} diff --git a/paperreplaymodel.h b/paperreplaymodel.h new file mode 100644 index 0000000..4184c8c --- /dev/null +++ b/paperreplaymodel.h @@ -0,0 +1,35 @@ +#ifndef PAPERREPLAYMODEL_H +#define PAPERREPLAYMODEL_H + +#include +#include "paperreplay.h" + +class PaperReplayModel : public QAbstractTableModel +{ + Q_OBJECT +public: + explicit PaperReplayModel(PaperReplay *replay, QObject *parent = 0); + + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, int role) const; + int rowCount(const QModelIndex &parent) const; + int columnCount(const QModelIndex &parent) const; + + QString sessionFilename(const QModelIndex &index) const; + +signals: + +public slots: + void refresh(); + +private: + static QString getSessionName(const PaperReplay::Session &session); + static QString getSessionDate(const PaperReplay::Session &session); + static QString getSessionLength(const PaperReplay::Session &session); + +private: + PaperReplay *_replay; + QList _sessions; +}; + +#endif // PAPERREPLAYMODEL_H diff --git a/scribiu.pro b/scribiu.pro index a49ef42..437e1ce 100644 --- a/scribiu.pro +++ b/scribiu.pro @@ -22,7 +22,8 @@ SOURCES += main.cc\ stfgraphicsitem.cc \ paperreplay.cc \ afdpageaddress.cc \ - stfstrokeitem.cc + stfstrokeitem.cc \ + paperreplaymodel.cc HEADERS += mainwindow.h \ smartpenmanager.h \ @@ -36,6 +37,7 @@ HEADERS += mainwindow.h \ stfgraphicsitem.h \ paperreplay.h \ afdpageaddress.h \ - stfstrokeitem.h + stfstrokeitem.h \ + paperreplaymodel.h FORMS += mainwindow.ui -- cgit v1.2.3