diff options
-rw-r--r-- | afdnotebook.cc | 6 | ||||
-rw-r--r-- | afdnotebook.h | 41 | ||||
-rw-r--r-- | mainwindow.cc | 1 | ||||
-rw-r--r-- | mainwindow.ui | 30 | ||||
-rw-r--r-- | notebookmodel.cc | 15 | ||||
-rw-r--r-- | notebookmodel.h | 1 | ||||
-rw-r--r-- | notebookview.cc | 41 | ||||
-rw-r--r-- | notebookview.h | 9 | ||||
-rw-r--r-- | paperreplay.cc (renamed from replaydata.cc) | 61 | ||||
-rw-r--r-- | paperreplay.h (renamed from replaydata.h) | 30 | ||||
-rw-r--r-- | scribiu.pro | 4 | ||||
-rw-r--r-- | stfgraphicsitem.cc | 9 |
12 files changed, 171 insertions, 77 deletions
diff --git a/afdnotebook.cc b/afdnotebook.cc index 38f1fdc..e3b024a 100644 --- a/afdnotebook.cc +++ b/afdnotebook.cc @@ -49,6 +49,11 @@ QString AfdNotebook::title() const return _title; } +quint64 AfdNotebook::guid() const +{ + return _guid; +} + int AfdNotebook::numPages() const { return _pages.size(); @@ -232,6 +237,7 @@ bool AfdNotebook::parseMainInfo() } _title = info["title"]; + _guid = info["guid"].mid(3).toULongLong(0, 16); _firstPage = PageAddress(info["pagestart"]); _lastPage = PageAddress(info["pagestop"]); _pagesPerBook = info.value("segment-pages-per-book", "108").toUInt(); diff --git a/afdnotebook.h b/afdnotebook.h index 38f926f..737196e 100644 --- a/afdnotebook.h +++ b/afdnotebook.h @@ -15,10 +15,31 @@ public: AfdNotebook(QObject *parent = 0); ~AfdNotebook(); + struct PageAddress { + PageAddress(); + explicit PageAddress(uint shelf, uint segment, uint book, uint page); + explicit PageAddress(uint series, uint shelf, uint segment, uint book, uint page); + explicit PageAddress(quint64 addr); + explicit PageAddress(const QString &str); + + QString toString() const; + quint64 toUInt64() const; + + bool operator<(const PageAddress& o) const; + bool operator==(const PageAddress& o) const; + + uint series : 12; + uint shelf : 12; + uint segment : 16; + uint book : 12; + uint page : 12; + }; + bool open(const QString &path); void close(); QString title() const; + quint64 guid() const; int numPages() const; @@ -36,25 +57,6 @@ public: bool readStrokes(const QString &penSerial, int page, StfReader::StrokeHandler *handler); private: - struct PageAddress { - PageAddress(); - explicit PageAddress(uint shelf, uint segment, uint book, uint page); - explicit PageAddress(uint series, uint shelf, uint segment, uint book, uint page); - explicit PageAddress(quint64 addr); - explicit PageAddress(const QString &str); - - QString toString() const; - - bool operator<(const PageAddress& o) const; - bool operator==(const PageAddress& o) const; - - uint series : 12; - uint shelf : 12; - uint segment : 16; - uint book : 12; - uint page : 12; - }; - struct Gfx { QString basename; }; @@ -89,6 +91,7 @@ private: private: QDir _dir; QString _title; + quint64 _guid; PageAddress _firstPage, _lastPage; uint _pagesPerBook; QMap<QString, Gfx> _gfx; diff --git a/mainwindow.cc b/mainwindow.cc index 793a722..c509d4e 100644 --- a/mainwindow.cc +++ b/mainwindow.cc @@ -39,6 +39,7 @@ void MainWindow::openNotebook(const QString &pen, const QString ¬ebook) qDebug() << "Opening notebook" << _curPenName << _curNotebookName << nbDir; + ui->notebookView->setPaperReplay(_notebooks->paperReplayDirectory(_curPenName)); ui->notebookView->setNotebook(nbDir); } diff --git a/mainwindow.ui b/mainwindow.ui index dceeadc..ac3dce3 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -192,6 +192,36 @@ </property> </widget> </item> + <item> + <layout class="QHBoxLayout" name="paperReplayTools"> + <item> + <widget class="QToolButton" name="playButton"> + <property name="maximumSize"> + <size> + <width>30</width> + <height>30</height> + </size> + </property> + <property name="text"> + <string>...</string> + </property> + <property name="icon"> + <iconset theme="media-playback-start"/> + </property> + </widget> + </item> + <item> + <widget class="QSlider" name="replaySlider"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="replayLabel"/> + </item> + </layout> + </item> </layout> </widget> </widget> diff --git a/notebookmodel.cc b/notebookmodel.cc index 13e3b21..2b7c99f 100644 --- a/notebookmodel.cc +++ b/notebookmodel.cc @@ -3,7 +3,7 @@ #include <QtGui/QIcon> #include <QtGui/QDesktopServices> #include <QtGui/QStyle> -#include "replaydata.h" +#include "paperreplay.h" #include "notebookmodel.h" #define NUM_COLUMNS 3 @@ -47,6 +47,11 @@ QString NotebookModel::notebookDirectory(const QModelIndex &index) const return QString(); } +QString NotebookModel::paperReplayDirectory(const QString &name) const +{ + return _dataDir.filePath(name + ".pen" + "/"+ PAPER_REPLAY); +} + QVariant NotebookModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); @@ -231,6 +236,7 @@ void NotebookModel::refreshPen(const QString &name) for (int i = 0; i < diskNotebooks.size(); i++) { diskNotebooks[i].chop(4); } + if (penDir.exists(PAPER_REPLAY)) diskNotebooks.append(PAPER_REPLAY); QModelIndex penIndex = index(indexOfPen(name), 0, QModelIndex()); @@ -265,13 +271,6 @@ void NotebookModel::refreshPen(const QString &name) } qDebug() << "Found" << curNotebooks.size() << "notebooks for pen" << name; - - ReplayData replay; - if (replay.open(penDir.filePath("PaperReplay"))) { - qDebug() << "Paper replay opened"; - } else { - qDebug() << "No paper replay for pen" << name; - } } int NotebookModel::indexOfPen(const QString &name) diff --git a/notebookmodel.h b/notebookmodel.h index 83bb004..1f52088 100644 --- a/notebookmodel.h +++ b/notebookmodel.h @@ -14,6 +14,7 @@ public: QString penDirectory(const QString &name) const; QString notebookDirectory(const QString &penName, const QString &nbName) const; QString notebookDirectory(const QModelIndex &index) const; + QString paperReplayDirectory(const QString &name) const; QVariant data(const QModelIndex &index, int role) const; Qt::ItemFlags flags(const QModelIndex &index) const; diff --git a/notebookview.cc b/notebookview.cc index 2605792..aa37ac9 100644 --- a/notebookview.cc +++ b/notebookview.cc @@ -6,7 +6,7 @@ #define PAGE_SEPARATION 100 NotebookView::NotebookView(QWidget *parent) : - QGraphicsView(parent), _nb(new AfdNotebook(this)), + QGraphicsView(parent), _nb(new AfdNotebook(this)), _replay(new PaperReplay(this)), _zoom(100), _curPage(0) { setScene(new QGraphicsScene(this)); @@ -18,14 +18,11 @@ NotebookView::NotebookView(QWidget *parent) : void NotebookView::setNotebook(const QString &path) { removePages(); + + _nbPath = path; + if (!path.isEmpty()) { - if (_nb->open(path)) { - _nbPath = path; - if (_zoom > 100) { - _zoom = 100; - emit zoomChanged(); - } - createPages(); + if (createPages()) { emit pageNumbersChanged(); if (!_pages.isEmpty()) { _curPage = _pages.begin().key(); @@ -43,6 +40,17 @@ QString NotebookView::notebook() const return _nbPath; } +void NotebookView::setPaperReplay(const QString &path) +{ + _replayPath = path; + // TODO reload; for now, please set this before the notebook +} + +QString NotebookView::paperReplay() const +{ + return _replayPath; +} + QList<int> NotebookView::pageNumbers() const { return _pages.keys(); @@ -132,16 +140,25 @@ void NotebookView::removePages() scene()->clear(); scene()->setSceneRect(QRectF()); _nb->close(); - _nbPath.clear(); + _replay->close(); _maxPageSize.setWidth(0); _maxPageSize.setHeight(0); + if (_zoom > 100) { + _zoom = 100; + emit zoomChanged(); + } resetTransform(); } -void NotebookView::createPages() +bool NotebookView::createPages() { + if (!_nb->open(_nbPath)) return false; + QStringList pens = _nb->penSerials(); - if (pens.isEmpty()) return; + if (pens.isEmpty()) return false; + + // Failure to open paperreplay data is not fatal + _replay->open(_replayPath, pens[0], _nb->guid()); QList<int> pagesWithStrokes = _nb->pagesWithStrokes(pens.first()); Q_ASSERT(_pages.isEmpty()); @@ -173,6 +190,8 @@ void NotebookView::createPages() } scene()->setSceneRect(0, 0, _maxPageSize.width(), curY); + + return true; } void NotebookView::calculateScale() diff --git a/notebookview.h b/notebookview.h index e51afa3..567d5cf 100644 --- a/notebookview.h +++ b/notebookview.h @@ -4,12 +4,14 @@ #include <QtGui/QGraphicsView> #include <QtGui/QGraphicsItem> #include "afdnotebook.h" +#include "paperreplay.h" #include "pageitem.h" class NotebookView : public QGraphicsView { Q_OBJECT Q_PROPERTY(QString notebook WRITE setNotebook READ notebook) + Q_PROPERTY(QString paperReplay WRITE setPaperReplay READ paperReplay) Q_PROPERTY(QList<int> pageNumbers READ pageNumbers NOTIFY pageNumbersChanged) Q_PROPERTY(int curPage READ curPage WRITE setCurPage NOTIFY curPageChanged) Q_PROPERTY(int zoom READ zoom WRITE setZoom NOTIFY zoomChanged) @@ -20,6 +22,9 @@ public: void setNotebook(const QString &path); QString notebook() const; + void setPaperReplay(const QString &path); + QString paperReplay() const; + QList<int> pageNumbers() const; int curPage() const; @@ -44,12 +49,14 @@ protected: private: void removePages(); - void createPages(); + bool createPages(); void calculateScale(); private: AfdNotebook *_nb; + PaperReplay *_replay; QString _nbPath; + QString _replayPath; QMap<int, PageItem*> _pages; QSizeF _maxPageSize; int _zoom; diff --git a/replaydata.cc b/paperreplay.cc index 021a79f..8bfb20e 100644 --- a/replaydata.cc +++ b/paperreplay.cc @@ -2,7 +2,7 @@ #include <QtCore/QDataStream> #include <QtCore/QDirIterator> #include "smartpen.h" -#include "replaydata.h" +#include "paperreplay.h" namespace { @@ -19,25 +19,32 @@ bool readUtfString(QDataStream &stream, QString &s) } } -ReplayData::ReplayData(QObject *parent) : +PaperReplay::PaperReplay(QObject *parent) : QObject(parent) { } -bool ReplayData::open(const QString &path) +bool PaperReplay::open(const QString &path, const QString &penSerial, quint64 notebookGuid) { - _dir.setPath(path); + _dir.setPath(path + QString("/userdata/%1/Paper Replay/99/%2/sessions") + .arg(penSerial) + .arg(qulonglong(notebookGuid), notebookGuid == 0 ? 1 : 16, 16, QLatin1Char('0'))); if (!_dir.exists()) { + qDebug() << "Cannot open paper replay:" << _dir.absolutePath() << "does not exist"; return false; } - QDirIterator iter(_dir.path(), QStringList("session.info"), QDir::Files, QDirIterator::Subdirectories); + QDirIterator iter(_dir.path(), QStringList("PRS-*"), QDir::Dirs | QDir::NoDotAndDotDot); while (iter.hasNext()) { - QFileInfo finfo(iter.next()); - QDir sessionDir(finfo.path()); - Session session; - if (!parseSessionInfo(session, finfo.filePath())) { - qWarning() << "Could not parse:" << finfo.absoluteFilePath(); + QDir sessionDir(iter.next()); + bool ok; + quint64 sessionId = sessionDir.dirName().mid(4).toULongLong(&ok, 16); + if (!ok) { + qWarning() << "Invalid session identifier:" << sessionDir.dirName(); + } + Session &session = _sessions[sessionId]; + if (!parseSessionInfo(session, sessionDir.filePath("session.info"))) { + qWarning() << "Could not parse:" << sessionDir.absoluteFilePath("session.info"); } if (!parseSessionPages(session, sessionDir.filePath("session.pages"))) { qWarning() << "Could not parse:" << sessionDir.absoluteFilePath("session.pages"); @@ -47,7 +54,29 @@ bool ReplayData::open(const QString &path) return true; } -bool ReplayData::parseSessionInfo(Session &session, const QString &path) +void PaperReplay::close() +{ + _sessions.clear(); + _byPage.clear(); + _dir.setPath(QString()); +} + +QList<PaperReplay::Session> PaperReplay::sessions() +{ + return _sessions.values(); +} + +QList<PaperReplay::Session> PaperReplay::sessions(quint64 pageAddress) +{ + QList<Session> sessions; + QMultiMap<quint64, quint64>::iterator it = _byPage.find(pageAddress); + while (it != _byPage.end() && it.key() == pageAddress) { + sessions.append(_sessions[it.value()]); + } + return sessions; +} + +bool PaperReplay::parseSessionInfo(Session &session, const QString &path) { QFile f(path); if (f.open(QIODevice::ReadOnly)) { @@ -57,7 +86,7 @@ bool ReplayData::parseSessionInfo(Session &session, const QString &path) } } -bool ReplayData::parseSessionInfo(Session &session, QIODevice *dev) +bool PaperReplay::parseSessionInfo(Session &session, QIODevice *dev) { unsigned char magic[2]; if (dev->read(reinterpret_cast<char*>(magic), 2) != 2 || @@ -81,7 +110,7 @@ bool ReplayData::parseSessionInfo(Session &session, QIODevice *dev) } } -bool ReplayData::parseSessionInfoV3(Session &session, QIODevice *dev) +bool PaperReplay::parseSessionInfoV3(Session &session, QIODevice *dev) { QDataStream s(dev); if (s.skipRawData(5) != 5) return false; @@ -128,7 +157,7 @@ bool ReplayData::parseSessionInfoV3(Session &session, QIODevice *dev) return true; } -bool ReplayData::parseSessionPages(Session &session, const QString &path) +bool PaperReplay::parseSessionPages(Session &session, const QString &path) { QFile f(path); if (f.open(QIODevice::ReadOnly)) { @@ -138,7 +167,7 @@ bool ReplayData::parseSessionPages(Session &session, const QString &path) } } -bool ReplayData::parseSessionPages(Session &session, QIODevice *dev) +bool PaperReplay::parseSessionPages(Session &session, QIODevice *dev) { unsigned char magic[2]; if (dev->read(reinterpret_cast<char*>(magic), 2) != 2 || @@ -162,7 +191,7 @@ bool ReplayData::parseSessionPages(Session &session, QIODevice *dev) } } -bool ReplayData::parseSessionPagesV1(Session &session, QIODevice *dev) +bool PaperReplay::parseSessionPagesV1(Session &session, QIODevice *dev) { QDataStream s(dev); if (s.skipRawData(1) != 1) return false; diff --git a/replaydata.h b/paperreplay.h index 39b1e0e..8ad7331 100644 --- a/replaydata.h +++ b/paperreplay.h @@ -1,5 +1,5 @@ -#ifndef REPLAYDATA_H -#define REPLAYDATA_H +#ifndef PAPERREPLAY_H +#define PAPERREPLAY_H #include <QtCore/QDateTime> #include <QtCore/QDir> @@ -7,14 +7,16 @@ #include <QtCore/QMultiMap> #include <QtCore/QVector> -class ReplayData : public QObject +#define PAPER_REPLAY "Paper Replay" + +class PaperReplay : public QObject { Q_OBJECT public: - explicit ReplayData(QObject *parent = 0); + explicit PaperReplay(QObject *parent = 0); - bool open(const QString &path); + bool open(const QString &path, const QString &penSerial, quint64 notebookGuid); void close(); struct Session { @@ -24,18 +26,10 @@ public: QString file; }; - QList<Session> sessions(quint64 penId, quint64 notebookId); - QList<Session> sessions(quint64 penId, quint64 notebookId, quint64 pageAddress); + QList<Session> sessions(); + QList<Session> sessions(quint64 pageAddress); private: - struct NotebookData { - QHash<uint, Session> sessions; - QMultiMap<quint64, uint> byPage; - }; - -private: - bool findSessions(); - static bool parseSessionInfo(Session &session, const QString &path); static bool parseSessionInfo(Session &session, QIODevice *dev); static bool parseSessionInfoV3(Session &session, QIODevice *dev); @@ -46,8 +40,8 @@ private: private: QDir _dir; - QHash<quint64, QHash<quint64, NotebookData> > _notebooks; // TODO Cache on demand - // /userdata/XXX-XXX-XXX-XX/Paper Replay/99/0bf11a726d11f3f3/sessions/PRS-21977890a4 + QHash<quint64, Session> _sessions; + QMultiMap<quint64, quint64> _byPage; }; -#endif // REPLAYDATA_H +#endif // PAPERREPLAY_H diff --git a/scribiu.pro b/scribiu.pro index 31d05ea..f50b75b 100644 --- a/scribiu.pro +++ b/scribiu.pro @@ -20,7 +20,7 @@ SOURCES += main.cc\ afdnotebook.cc \ pageitem.cc \ stfgraphicsitem.cc \ - replaydata.cc + paperreplay.cc HEADERS += mainwindow.h \ smartpenmanager.h \ @@ -32,6 +32,6 @@ HEADERS += mainwindow.h \ afdnotebook.h \ pageitem.h \ stfgraphicsitem.h \ - replaydata.h + paperreplay.h FORMS += mainwindow.ui diff --git a/stfgraphicsitem.cc b/stfgraphicsitem.cc index 865a029..414cf6c 100644 --- a/stfgraphicsitem.cc +++ b/stfgraphicsitem.cc @@ -1,3 +1,4 @@ +#include <QtCore/QDebug> #include <QtGui/QPainterPath> #include "stfreader.h" @@ -16,12 +17,16 @@ public: ~StfToGraphicsPathItems() { } - bool startStroke(const QPoint& p, int, quint64) { + bool startStroke(const QPoint& p, int force, quint64 time) { + Q_UNUSED(force); + Q_UNUSED(time); path = QPainterPath(QPointF(p)); return true; } - bool strokePoint(const QPoint& p, int, quint64) { + bool strokePoint(const QPoint& p, int force, quint64 time) { + Q_UNUSED(force); + Q_UNUSED(time); path.lineTo(QPointF(p)); return true; } |