diff options
-rw-r--r-- | afdnotebook.cc | 100 | ||||
-rw-r--r-- | afdnotebook.h | 50 | ||||
-rw-r--r-- | afdpageaddress.cc | 61 | ||||
-rw-r--r-- | afdpageaddress.h | 66 | ||||
-rw-r--r-- | paperreplay.cc | 55 | ||||
-rw-r--r-- | paperreplay.h | 50 | ||||
-rw-r--r-- | scribiu.pro | 6 | ||||
-rw-r--r-- | smartpen.h | 4 |
8 files changed, 239 insertions, 153 deletions
diff --git a/afdnotebook.cc b/afdnotebook.cc index e3b024a..a1f8423 100644 --- a/afdnotebook.cc +++ b/afdnotebook.cc @@ -36,7 +36,7 @@ bool AfdNotebook::open(const QString &path) void AfdNotebook::close() { _title.clear(); - _lastPage = _firstPage = PageAddress(0, 0, 0, 0, 0); + _lastPage = _firstPage = AfdPageAddress(); _pagesPerBook = 0; _gfx.clear(); _pages.clear(); @@ -59,6 +59,33 @@ int AfdNotebook::numPages() const return _pages.size(); } +AfdPageAddress AfdNotebook::getPageAddress(int pageNum) const +{ + if (pageNum < 0 || pageNum >= _pages.size()) { + qWarning() << "Invalid page number:" << pageNum << "for notebook" << _title; + } + uint new_page = _firstPage.page() + pageNum; + return AfdPageAddress(_firstPage.section(), _firstPage.segment(), _firstPage.shelf(), + _firstPage.book() + new_page / _pagesPerBook, + new_page % _pagesPerBook); +} + +int AfdNotebook::getPageNumber(const AfdPageAddress &addr) const +{ + if (addr.section() == _firstPage.section() + && addr.segment() == _firstPage.segment() + && addr.shelf() == _firstPage.shelf()) { + long firstPage = (_firstPage.book() * _pagesPerBook) + _firstPage.page(); + long page = (addr.book() * _pagesPerBook) + addr.page() - firstPage; + if (page >= 0 && page < _pages.size()) { + return page; + } + } + + qWarning() << "Invalid address for notebook" << _title; + return -1; +} + QString AfdNotebook::getPageBackgroundName(int page) const { const Page& p = _pages.at(page); @@ -167,43 +194,6 @@ bool AfdNotebook::readStrokes(const QString &penSerial, int page, StfReader::Str return true; } -AfdNotebook::PageAddress::PageAddress(const QString &str) -{ - QStringList parts = str.split('.'); - if (parts.count() == 5) { - series = parts[0].toUInt(); - shelf = parts[1].toUInt(); - segment = parts[2].toUInt(); - book = parts[3].toUInt(); - page = parts[4].toUInt(); - } else if (parts.count() == 4) { - series = 0; - shelf = parts[0].toUInt(); - segment = parts[1].toUInt(); - book = parts[2].toUInt(); - page = parts[3].toUInt(); - } else { - qWarning() << "Unknown page address syntax:" << str; - } -} - -QString AfdNotebook::PageAddress::toString() const -{ - QStringList l; - l.reserve(5); - - if (series) { - l.append(QString::number(series)); - } - - l.append(QString::number(shelf)); - l.append(QString::number(segment)); - l.append(QString::number(book)); - l.append(QString::number(page)); - - return l.join("."); -} - QMap<QString, QString> AfdNotebook::parsePropertyList(QIODevice *dev) { QMap<QString, QString> result; @@ -238,8 +228,8 @@ bool AfdNotebook::parseMainInfo() _title = info["title"]; _guid = info["guid"].mid(3).toULongLong(0, 16); - _firstPage = PageAddress(info["pagestart"]); - _lastPage = PageAddress(info["pagestop"]); + _firstPage = AfdPageAddress(info["pagestart"]); + _lastPage = AfdPageAddress(info["pagestop"]); _pagesPerBook = info.value("segment-pages-per-book", "108").toUInt(); return true; @@ -333,7 +323,7 @@ bool AfdNotebook::findPenData() foreach (QString pageName, pageDirs) { pageName.remove('/'); qDebug() << " page data" << pageName; - int pageNum = getPageNumber(PageAddress(pageName)); + int pageNum = getPageNumber(AfdPageAddress(pageName)); if (pageNum < 0) continue; QDir pageDir(dir.filePath(pageName)); @@ -358,9 +348,6 @@ bool AfdNotebook::findPenData() stroke.file = penDir.filePath(strokeFile); bool ok = true; - qDebug() << " " << strokeFile.mid(2, 8) << strokeFile.mid(13, 8); - qDebug() << " " << strokeFile.mid(2, 8).toUInt(0, 16) << strokeFile.mid(13, 8).toUInt(0, 16); - if (ok) stroke.begin = Smartpen::fromPenTime(strokeFile.mid(2, 8).toLongLong(&ok, 16) * 1000ULL); if (ok) stroke.end = Smartpen::fromPenTime(strokeFile.mid(13, 8).toLongLong(&ok, 16) * 1000ULL); @@ -378,28 +365,3 @@ bool AfdNotebook::findPenData() return true; } - -AfdNotebook::PageAddress AfdNotebook::getPageAddress(int page) const -{ - PageAddress addr = _firstPage; - Q_ASSERT(page >= 0); - uint new_page = addr.page + page; - addr.book += new_page / _pagesPerBook; - addr.page = new_page % _pagesPerBook; - return addr; -} - -int AfdNotebook::getPageNumber(const PageAddress &addr) -{ - // series(0), shelf(0), segment(0), book(0), page(0) - if (addr.series == _firstPage.series && addr.shelf == _firstPage.shelf && addr.segment == _firstPage.segment) { - int firstPage = (_firstPage.book * _pagesPerBook) + _firstPage.page; - int page = (addr.book * _pagesPerBook) + addr.page - firstPage; - if (page >= 0 && page < _pages.size()) { - return page; - } - } - - qWarning() << "Invalid address for notebook" << _title; - return -1; -} diff --git a/afdnotebook.h b/afdnotebook.h index 737196e..74861ca 100644 --- a/afdnotebook.h +++ b/afdnotebook.h @@ -5,6 +5,7 @@ #include <QtCore/QDir> #include <QtCore/QMap> #include <QtGui/QImage> +#include "afdpageaddress.h" #include "stfreader.h" class AfdNotebook : public QObject @@ -15,26 +16,6 @@ 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(); @@ -43,6 +24,9 @@ public: int numPages() const; + AfdPageAddress getPageAddress(int pageNum) const; + int getPageNumber(const AfdPageAddress &addr) const; + QString getPageBackgroundName(int page) const; QPixmap getPageBackground(int page); @@ -85,39 +69,15 @@ private: bool parseGfx(const QString &file); bool findPenData(); - PageAddress getPageAddress(int page) const; - int getPageNumber(const PageAddress &addr); - private: QDir _dir; QString _title; quint64 _guid; - PageAddress _firstPage, _lastPage; + AfdPageAddress _firstPage, _lastPage; uint _pagesPerBook; QMap<QString, Gfx> _gfx; QList<Page> _pages; QMap<QString, PenData> _penData; }; -inline AfdNotebook::PageAddress::PageAddress() - : series(0), shelf(0), segment(0), book(0), page(0) -{ -} - -inline AfdNotebook::PageAddress::PageAddress(uint shelf, uint segment, uint book, uint page) - : series(0), shelf(shelf), segment(segment), book(book), page(page) -{ -} - -inline AfdNotebook::PageAddress::PageAddress(uint series, uint shelf, uint segment, uint book, uint page) - : series(series), shelf(shelf), segment(segment), book(book), page(page) -{ -} - -inline bool AfdNotebook::PageAddress::operator ==(const PageAddress &o) const -{ - return series == o.series && shelf == o.shelf && segment == o.segment && - book == o.book && page == o.page; -} - #endif diff --git a/afdpageaddress.cc b/afdpageaddress.cc new file mode 100644 index 0000000..708dcef --- /dev/null +++ b/afdpageaddress.cc @@ -0,0 +1,61 @@ +#include <QtCore/QDebug> +#include <QtCore/QStringList> +#include "afdpageaddress.h" + +namespace { +quint64 addressToUint64(uint section, uint segment, uint shelf, uint book, uint page) +{ + return quint64(section & 0xFFFU) << 52 | + quint64(segment & 0xFFFU) << 40 | quint64(shelf & 0xFFFFU) << 24 | + quint64(book & 0xFFFU) << 12 | quint64(page & 0xFFFU); +} +} + +AfdPageAddress::AfdPageAddress(uint section, uint segment, uint shelf, uint book, uint page) + : v(addressToUint64(section, segment, shelf, book, page)) +{ +} + +AfdPageAddress::AfdPageAddress(uint segment, uint shelf, uint book, uint page) + : v(addressToUint64(0, segment, shelf, book, page)) +{ +} + +AfdPageAddress::AfdPageAddress(const QString &addr) +{ + uint section, segment, shelf, book, page; + QStringList parts = addr.split('.'); + if (parts.count() == 5) { + section = parts[0].toUInt(); + segment = parts[1].toUInt(); + shelf = parts[2].toUInt(); + book = parts[3].toUInt(); + page = parts[4].toUInt(); + } else if (parts.count() == 4) { + section = 0; + segment = parts[0].toUInt(); + shelf = parts[1].toUInt(); + book = parts[2].toUInt(); + page = parts[3].toUInt(); + } else { + qWarning() << "Unknown page address syntax:" << addr; + } + v = addressToUint64(section, segment, shelf, book, page); +} + +QString AfdPageAddress::toString() const +{ + QStringList l; + l.reserve(5); + + if (section()) { + l.append(QString::number(section())); + } + + l.append(QString::number(segment())); + l.append(QString::number(shelf())); + l.append(QString::number(book())); + l.append(QString::number(page())); + + return l.join("."); +} diff --git a/afdpageaddress.h b/afdpageaddress.h new file mode 100644 index 0000000..911dd53 --- /dev/null +++ b/afdpageaddress.h @@ -0,0 +1,66 @@ +#ifndef AFDPAGEADDRESS_H +#define AFDPAGEADDRESS_H + +#include <QtCore/QString> + +class AfdPageAddress +{ +public: + AfdPageAddress(); + AfdPageAddress(uint section, uint segment, uint shelf, uint book, uint page); + AfdPageAddress(uint segment, uint shelf, uint book, uint page); + explicit AfdPageAddress(const QString &addr); + explicit AfdPageAddress(quint64 addr); + + uint section() const; + uint segment() const; + uint shelf() const; + uint book() const; + uint page() const; + + QString toString() const; + quint64 toUInt64() const; + +private: + quint64 v; +}; + +inline AfdPageAddress::AfdPageAddress() : v(0) +{ +} + +inline AfdPageAddress::AfdPageAddress(quint64 addr) : v(addr) +{ +} + +inline uint AfdPageAddress::section() const +{ + return (v >> 52) & 0xFFFU; +} + +inline uint AfdPageAddress::segment() const +{ + return (v >> 40) & 0xFFFU; +} + +inline uint AfdPageAddress::shelf() const +{ + return (v >> 24) & 0xFFFFU; +} + +inline uint AfdPageAddress::book() const +{ + return (v >> 12) & 0xFFFU; +} + +inline uint AfdPageAddress::page() const +{ + return (v >> 0) & 0xFFFU; +} + +inline quint64 AfdPageAddress::toUInt64() const +{ + return v; +} + +#endif // AFDPAGEADDRESS_H diff --git a/paperreplay.cc b/paperreplay.cc index 8bfb20e..579ea3c 100644 --- a/paperreplay.cc +++ b/paperreplay.cc @@ -24,6 +24,14 @@ PaperReplay::PaperReplay(QObject *parent) : { } +PaperReplay::Session::Session() : d(new SessionData) +{ +} + +PaperReplay::Session::~Session() +{ +} + bool PaperReplay::open(const QString &path, const QString &penSerial, quint64 notebookGuid) { _dir.setPath(path + QString("/userdata/%1/Paper Replay/99/%2/sessions") @@ -43,10 +51,10 @@ bool PaperReplay::open(const QString &path, const QString &penSerial, quint64 no qWarning() << "Invalid session identifier:" << sessionDir.dirName(); } Session &session = _sessions[sessionId]; - if (!parseSessionInfo(session, sessionDir.filePath("session.info"))) { + if (!parseSessionInfo(session.d, sessionDir.filePath("session.info"))) { qWarning() << "Could not parse:" << sessionDir.absoluteFilePath("session.info"); } - if (!parseSessionPages(session, sessionDir.filePath("session.pages"))) { + if (!parseSessionPages(session.d, sessionDir.filePath("session.pages"))) { qWarning() << "Could not parse:" << sessionDir.absoluteFilePath("session.pages"); } } @@ -61,22 +69,22 @@ void PaperReplay::close() _dir.setPath(QString()); } -QList<PaperReplay::Session> PaperReplay::sessions() +QList<PaperReplay::Session> PaperReplay::sessions() const { return _sessions.values(); } -QList<PaperReplay::Session> PaperReplay::sessions(quint64 pageAddress) +QList<PaperReplay::Session> PaperReplay::sessions(quint64 pageAddress) const { QList<Session> sessions; - QMultiMap<quint64, quint64>::iterator it = _byPage.find(pageAddress); + QMultiMap<quint64, quint64>::const_iterator it = _byPage.constFind(pageAddress); while (it != _byPage.end() && it.key() == pageAddress) { sessions.append(_sessions[it.value()]); } return sessions; } -bool PaperReplay::parseSessionInfo(Session &session, const QString &path) +bool PaperReplay::parseSessionInfo(SessionData *session, const QString &path) { QFile f(path); if (f.open(QIODevice::ReadOnly)) { @@ -86,7 +94,7 @@ bool PaperReplay::parseSessionInfo(Session &session, const QString &path) } } -bool PaperReplay::parseSessionInfo(Session &session, QIODevice *dev) +bool PaperReplay::parseSessionInfo(SessionData *session, QIODevice *dev) { unsigned char magic[2]; if (dev->read(reinterpret_cast<char*>(magic), 2) != 2 || @@ -110,12 +118,12 @@ bool PaperReplay::parseSessionInfo(Session &session, QIODevice *dev) } } -bool PaperReplay::parseSessionInfoV3(Session &session, QIODevice *dev) +bool PaperReplay::parseSessionInfoV3(SessionData *session, QIODevice *dev) { QDataStream s(dev); if (s.skipRawData(5) != 5) return false; - qint64 startTime, endTime, creationTime; + quint64 startTime, endTime, creationTime; QString name; s >> startTime >> endTime >> creationTime; @@ -123,19 +131,26 @@ bool PaperReplay::parseSessionInfoV3(Session &session, QIODevice *dev) return false; } - qDebug() << "Name:" << name << Smartpen::fromPenTime(startTime) << Smartpen::fromPenTime(endTime) << creationTime; + session->name = name; + session->start = Smartpen::fromPenTime(startTime); + session->end = Smartpen::fromPenTime(endTime); + + qDebug() << "Session:" << name << session->start << session->end; quint16 num_clips; s >> num_clips; + Q_ASSERT(num_clips == 1); // TODO: We do not yet know how to handle this scenario + for (uint i = 0; i < num_clips; ++i) { QString file; if (!readUtfString(s, file)) { return false; } s >> startTime >> endTime; - qDebug() << " Clip:" << file << startTime << endTime; - qDebug() << " " << QDateTime::fromTime_t(startTime) << QDateTime::fromTime_t(endTime); + + qDebug() << " Clip:" << file << Smartpen::fromPenTime(startTime) << Smartpen::fromPenTime(endTime); + session->file = file; } quint16 num_strokes; @@ -157,7 +172,7 @@ bool PaperReplay::parseSessionInfoV3(Session &session, QIODevice *dev) return true; } -bool PaperReplay::parseSessionPages(Session &session, const QString &path) +bool PaperReplay::parseSessionPages(SessionData *session, const QString &path) { QFile f(path); if (f.open(QIODevice::ReadOnly)) { @@ -167,7 +182,7 @@ bool PaperReplay::parseSessionPages(Session &session, const QString &path) } } -bool PaperReplay::parseSessionPages(Session &session, QIODevice *dev) +bool PaperReplay::parseSessionPages(SessionData *session, QIODevice *dev) { unsigned char magic[2]; if (dev->read(reinterpret_cast<char*>(magic), 2) != 2 || @@ -191,21 +206,21 @@ bool PaperReplay::parseSessionPages(Session &session, QIODevice *dev) } } -bool PaperReplay::parseSessionPagesV1(Session &session, QIODevice *dev) +bool PaperReplay::parseSessionPagesV1(SessionData *session, QIODevice *dev) { QDataStream s(dev); if (s.skipRawData(1) != 1) return false; quint16 num_pages = 0; s >> num_pages; - session.pages.reserve(session.pages.size() + num_pages); + session->pages.reserve(session->pages.size() + num_pages); for (uint i = 0; i < num_pages; ++i) { - quint64 address, unk; - s >> address >> unk; + quint64 address, time; + s >> address >> time; - session.pages.append(address); - qDebug() << " Page:" << address << unk; + session->pages.append(address); + qDebug() << " Page:" << address << time << Smartpen::fromPenTime(time); } return true; diff --git a/paperreplay.h b/paperreplay.h index 8ad7331..e771584 100644 --- a/paperreplay.h +++ b/paperreplay.h @@ -13,30 +13,50 @@ class PaperReplay : public QObject { Q_OBJECT + struct SessionData : public QSharedData { + QString name; + QDateTime start, end; + QVector<quint64> pages; + QString file; + }; + public: explicit PaperReplay(QObject *parent = 0); - bool open(const QString &path, const QString &penSerial, quint64 notebookGuid); - void close(); + class Session { + public: + Session(); + ~Session(); - struct Session { - QDateTime start, end; - QString name; - QVector<quint64> pages; - QString file; + QString name() const; + + QDateTime startTime() const; + QDateTime endTime() const; + + QVector<quint64> pages() const; + + QString fileName() const; + + private: + QSharedDataPointer<SessionData> d; + + friend class PaperReplay; }; - QList<Session> sessions(); - QList<Session> sessions(quint64 pageAddress); + bool open(const QString &path, const QString &penSerial, quint64 notebookGuid); + void close(); + + QList<Session> sessions() const; + QList<Session> sessions(quint64 pageAddress) const; private: - static bool parseSessionInfo(Session &session, const QString &path); - static bool parseSessionInfo(Session &session, QIODevice *dev); - static bool parseSessionInfoV3(Session &session, QIODevice *dev); + static bool parseSessionInfo(SessionData *session, const QString &path); + static bool parseSessionInfo(SessionData *session, QIODevice *dev); + static bool parseSessionInfoV3(SessionData *session, QIODevice *dev); - static bool parseSessionPages(Session &session, const QString &path); - static bool parseSessionPages(Session &session, QIODevice *dev); - static bool parseSessionPagesV1(Session &session, QIODevice *dev); + static bool parseSessionPages(SessionData *session, const QString &path); + static bool parseSessionPages(SessionData *session, QIODevice *dev); + static bool parseSessionPagesV1(SessionData *session, QIODevice *dev); private: QDir _dir; diff --git a/scribiu.pro b/scribiu.pro index f50b75b..861ceff 100644 --- a/scribiu.pro +++ b/scribiu.pro @@ -20,7 +20,8 @@ SOURCES += main.cc\ afdnotebook.cc \ pageitem.cc \ stfgraphicsitem.cc \ - paperreplay.cc + paperreplay.cc \ + afdpageaddress.cc HEADERS += mainwindow.h \ smartpenmanager.h \ @@ -32,6 +33,7 @@ HEADERS += mainwindow.h \ afdnotebook.h \ pageitem.h \ stfgraphicsitem.h \ - paperreplay.h + paperreplay.h \ + afdpageaddress.h FORMS += mainwindow.ui @@ -7,8 +7,8 @@ #include <openobex/obex.h> // TODO: These values are mostly random. -#define SMARTPEN_DPI_X (800.0) -#define SMARTPEN_DPI_Y (800.0) +#define SMARTPEN_DPI_X (677.3333) +#define SMARTPEN_DPI_Y (677.3333) #define SMARTPEN_BLEED_X 333.3 #define SMARTPEN_BLEED_Y 333.3 |