aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--afdnotebook.cc100
-rw-r--r--afdnotebook.h50
-rw-r--r--afdpageaddress.cc61
-rw-r--r--afdpageaddress.h66
-rw-r--r--paperreplay.cc55
-rw-r--r--paperreplay.h50
-rw-r--r--scribiu.pro6
-rw-r--r--smartpen.h4
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
diff --git a/smartpen.h b/smartpen.h
index c44ef71..76fbae4 100644
--- a/smartpen.h
+++ b/smartpen.h
@@ -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