aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mainwindow.cc69
-rw-r--r--mainwindow.h9
-rw-r--r--mainwindow.ui80
-rw-r--r--notebookview.cc9
-rw-r--r--notebookview.h3
-rw-r--r--pageitem.cc14
-rw-r--r--pageitem.h4
-rw-r--r--paperreplay.cc105
-rw-r--r--paperreplay.h36
-rw-r--r--scribiu.pro8
-rw-r--r--stfgraphicsitem.cc29
-rw-r--r--stfgraphicsitem.h3
-rw-r--r--stfreader.cc4
-rw-r--r--stfreader.h4
-rw-r--r--stfstrokeitem.cc36
-rw-r--r--stfstrokeitem.h25
16 files changed, 379 insertions, 59 deletions
diff --git a/mainwindow.cc b/mainwindow.cc
index c509d4e..e269c61 100644
--- a/mainwindow.cc
+++ b/mainwindow.cc
@@ -6,7 +6,9 @@ MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
_notebooks(new NotebookModel(this)),
- _manager(new SmartpenManager(this))
+ _manager(new SmartpenManager(this)),
+ _media(new Phonon::MediaObject(this)),
+ _mediaOutput(new Phonon::AudioOutput(this))
{
ui->setupUi(this);
ui->notebookTree->setModel(_notebooks);
@@ -14,6 +16,11 @@ MainWindow::MainWindow(QWidget *parent) :
ui->notebookTree->header()->setResizeMode(1, QHeaderView::Fixed);
ui->notebookTree->header()->setResizeMode(2, QHeaderView::Fixed);
ui->notebookTree->expandAll();
+ Phonon::createPath(_media, _mediaOutput);
+ ui->replaySlider->setMediaObject(_media);
+ ui->pauseButton->setVisible(false);
+ connect(_media, SIGNAL(stateChanged(Phonon::State,Phonon::State)),
+ this, SLOT(handleMediaStateChange(Phonon::State)));
}
MainWindow::~MainWindow()
@@ -65,3 +72,63 @@ void MainWindow::handleCurPageChanged()
{
ui->pageEdit->setText(QString::number(ui->notebookView->curPage() + 1));
}
+
+void MainWindow::handlePaperReplayRequested(const QString &file, qint64 time)
+{
+ QFileInfo finfo(file);
+ if (!finfo.exists()) {
+ qWarning() << "Cannot open paper replay media file:" << finfo.canonicalFilePath();
+ }
+
+ QString filePath = finfo.canonicalFilePath();
+
+ if (_media->currentSource().fileName() != filePath) {
+ _media->setCurrentSource(filePath);
+ }
+
+ switch (_media->state()) {
+ case Phonon::PlayingState:
+ case Phonon::BufferingState:
+ case Phonon::PausedState:
+ _pendingSeek = 0;
+ _media->seek(time);
+ break;
+ default:
+ _pendingSeek = time;
+ break;
+ }
+
+ _media->play();
+}
+
+void MainWindow::handlePaperReplayPlay()
+{
+ _media->play();
+}
+
+void MainWindow::handlePaperReplayPause()
+{
+ _media->pause();
+}
+
+void MainWindow::handleMediaStateChange(Phonon::State state)
+{
+ qDebug() << "Media state change:" << state;
+ switch (state) {
+ case Phonon::PlayingState:
+ ui->playButton->setVisible(false);
+ ui->pauseButton->setVisible(true);
+ if (_pendingSeek) {
+ _media->seek(_pendingSeek);
+ _pendingSeek = 0;
+ }
+ break;
+ case Phonon::PausedState:
+ ui->playButton->setVisible(true);
+ ui->pauseButton->setVisible(false);
+ break;
+ default:
+ ui->playButton->setVisible(true);
+ ui->pauseButton->setVisible(false);
+ }
+}
diff --git a/mainwindow.h b/mainwindow.h
index 4072ffa..7a8fab4 100644
--- a/mainwindow.h
+++ b/mainwindow.h
@@ -2,6 +2,8 @@
#define MAINWINDOW_H
#include <QtGui/QMainWindow>
+#include <phonon/MediaObject>
+#include <phonon/AudioOutput>
#include "notebookmodel.h"
#include "smartpenmanager.h"
@@ -24,11 +26,18 @@ public slots:
private slots:
void handleNotebookSelected(const QModelIndex &index);
void handleCurPageChanged();
+ void handlePaperReplayRequested(const QString &file, qint64 time);
+ void handlePaperReplayPlay();
+ void handlePaperReplayPause();
+ void handleMediaStateChange(Phonon::State state);
private:
Ui::MainWindow *ui;
NotebookModel *_notebooks;
SmartpenManager *_manager;
+ Phonon::MediaObject *_media;
+ Phonon::AudioOutput *_mediaOutput;
+ qint64 _pendingSeek;
QString _curPenName;
QString _curNotebookName;
diff --git a/mainwindow.ui b/mainwindow.ui
index ac3dce3..4a0e1ea 100644
--- a/mainwindow.ui
+++ b/mainwindow.ui
@@ -206,18 +206,32 @@
<string>...</string>
</property>
<property name="icon">
- <iconset theme="media-playback-start"/>
+ <iconset theme="media-playback-start">
+ <normaloff/>
+ </iconset>
</property>
</widget>
</item>
<item>
- <widget class="QSlider" name="replaySlider">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
+ <widget class="QToolButton" name="pauseButton">
+ <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-pause"/>
</property>
</widget>
</item>
<item>
+ <widget class="Phonon::SeekSlider" name="replaySlider" native="true"/>
+ </item>
+ <item>
<widget class="QLabel" name="replayLabel"/>
</item>
</layout>
@@ -271,11 +285,18 @@
<header>notebookview.h</header>
<slots>
<signal>curPageChanged()</signal>
+ <signal>paperReplayRequested(QString,qint64)</signal>
<slot>setZoom(int)</slot>
<slot>prevPage()</slot>
<slot>nextPage()</slot>
</slots>
</customwidget>
+ <customwidget>
+ <class>Phonon::SeekSlider</class>
+ <extends>QWidget</extends>
+ <header location="global">Phonon/SeekSlider</header>
+ <container>1</container>
+ </customwidget>
</customwidgets>
<resources/>
<connections>
@@ -375,10 +396,61 @@
</hint>
</hints>
</connection>
+ <connection>
+ <sender>notebookView</sender>
+ <signal>paperReplayRequested(QString,qint64)</signal>
+ <receiver>MainWindow</receiver>
+ <slot>handlePaperReplayRequested(QString,qint64)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>521</x>
+ <y>193</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>358</x>
+ <y>192</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>playButton</sender>
+ <signal>clicked()</signal>
+ <receiver>MainWindow</receiver>
+ <slot>handlePaperReplayPlay()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>341</x>
+ <y>343</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>358</x>
+ <y>192</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>pauseButton</sender>
+ <signal>clicked()</signal>
+ <receiver>MainWindow</receiver>
+ <slot>handlePaperReplayPause()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>377</x>
+ <y>343</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>358</x>
+ <y>192</y>
+ </hint>
+ </hints>
+ </connection>
</connections>
<slots>
<slot>handleNotebookSelected(QModelIndex)</slot>
<slot>handleZoomChanged(int)</slot>
<slot>handleCurPageChanged()</slot>
+ <slot>handlePaperReplayRequested(QString,qint64)</slot>
+ <slot>handlePaperReplayPlay()</slot>
+ <slot>handlePaperReplayPause()</slot>
</slots>
</ui>
diff --git a/notebookview.cc b/notebookview.cc
index aa37ac9..9553451 100644
--- a/notebookview.cc
+++ b/notebookview.cc
@@ -88,6 +88,11 @@ void NotebookView::setZoom(int zoom)
}
}
+void NotebookView::requestPaperReplay(const QString &file, qint64 time)
+{
+ emit paperReplayRequested(file, time);
+}
+
void NotebookView::clear()
{
removePages();
@@ -158,7 +163,7 @@ bool NotebookView::createPages()
if (pens.isEmpty()) return false;
// Failure to open paperreplay data is not fatal
- _replay->open(_replayPath, pens[0], _nb->guid());
+ bool haveReplay = _replay->open(_replayPath, pens[0], _nb->guid());
QList<int> pagesWithStrokes = _nb->pagesWithStrokes(pens.first());
Q_ASSERT(_pages.isEmpty());
@@ -166,7 +171,7 @@ bool NotebookView::createPages()
_maxPageSize.setWidth(0);
_maxPageSize.setHeight(0);
foreach (int pageNum, pagesWithStrokes) {
- PageItem *page = new PageItem(_nb, pageNum);
+ PageItem *page = new PageItem(_nb, haveReplay ? _replay : 0, pageNum);
QRectF box = page->boundingRect();
if (box.width() > _maxPageSize.width()) {
_maxPageSize.setWidth(box.width());
diff --git a/notebookview.h b/notebookview.h
index 567d5cf..1b3eb46 100644
--- a/notebookview.h
+++ b/notebookview.h
@@ -32,10 +32,13 @@ public:
int zoom() const;
+ void requestPaperReplay(const QString &file, qint64 time);
+
signals:
void pageNumbersChanged();
void curPageChanged();
void zoomChanged();
+ void paperReplayRequested(const QString &file, qint64 time);
public slots:
void clear();
diff --git a/pageitem.cc b/pageitem.cc
index f938eeb..3bd5b7f 100644
--- a/pageitem.cc
+++ b/pageitem.cc
@@ -3,8 +3,8 @@
#include "pageitem.h"
#include "stfgraphicsitem.h"
-PageItem::PageItem(AfdNotebook *nb, int pageNum, QGraphicsItem *parent) :
- QGraphicsItem(parent), _nb(nb), _pageNum(pageNum), _strokesLoaded(false)
+PageItem::PageItem(AfdNotebook *nb, PaperReplay *replay, int pageNum, QGraphicsItem *parent) :
+ QGraphicsItem(parent), _nb(nb), _replay(replay), _pageNum(pageNum), _strokesLoaded(false)
{
_pageSize = _nb->getPageSize(pageNum);
_pageTrim = _nb->getPageTrim(pageNum);
@@ -51,6 +51,13 @@ void PageItem::createStrokes()
{
QStringList pens = _nb->penSerials();
if (pens.isEmpty()) return;
+
+ // Load paper replay data if available
+ AfdPageAddress pageAddr = _nb->getPageAddress(_pageNum);
+ PaperReplay::SessionList replays = _replay ? _replay->sessions(pageAddr.toUInt64()) : PaperReplay::SessionList();
+
+ // Now create a new StfGraphicsItem for every stroke file
+ // Which will in turn create a stroke item for every stroke
QStringList strokeFiles = _nb->strokeFiles(pens.first(), _pageNum);
foreach (const QString &strokeFile, strokeFiles) {
QFile f(strokeFile);
@@ -58,7 +65,8 @@ void PageItem::createStrokes()
qWarning() << "Could not open stroke file:" << strokeFile;
continue;
}
- new StfGraphicsItem(&f, this);
+ new StfGraphicsItem(&f, replays, this);
}
+
qDebug() << "strokes loaded for page" << _pageNum;
}
diff --git a/pageitem.h b/pageitem.h
index 2e6059a..10959d9 100644
--- a/pageitem.h
+++ b/pageitem.h
@@ -4,11 +4,12 @@
#include <QtGui/QGraphicsItem>
#include "afdnotebook.h"
+#include "paperreplay.h"
class PageItem : public QGraphicsItem
{
public:
- explicit PageItem(AfdNotebook *nb, int pageNum, QGraphicsItem *parent = 0);
+ explicit PageItem(AfdNotebook *nb, PaperReplay *replay, int pageNum, QGraphicsItem *parent = 0);
enum { Type = UserType + 'p' };
@@ -23,6 +24,7 @@ private:
private:
AfdNotebook *_nb;
+ PaperReplay *_replay;
int _pageNum;
QSize _pageSize;
QRect _pageTrim;
diff --git a/paperreplay.cc b/paperreplay.cc
index 579ea3c..e0e654e 100644
--- a/paperreplay.cc
+++ b/paperreplay.cc
@@ -24,14 +24,72 @@ PaperReplay::PaperReplay(QObject *parent) :
{
}
-PaperReplay::Session::Session() : d(new SessionData)
+PaperReplay::Session::Session() : d()
{
}
+PaperReplay::Session::Session(quint64 id) : d(new SessionData)
+{
+ d->id = id;
+}
+
PaperReplay::Session::~Session()
{
}
+bool PaperReplay::Session::isValid() const
+{
+ return d;
+}
+
+quint64 PaperReplay::Session::id() const
+{
+ return d ? d->id : 0;
+}
+
+QString PaperReplay::Session::fileName() const
+{
+ return d->file;
+}
+
+qint64 PaperReplay::Session::startTime() const
+{
+ return d->start;
+}
+
+qint64 PaperReplay::Session::endTime() const
+{
+ return d->end;
+}
+
+PaperReplay::SessionList::SessionList()
+{
+}
+
+PaperReplay::SessionList::SessionList(const QMap<qint64, Session> &byTime)
+ : _m(byTime)
+{
+}
+
+QList<PaperReplay::Session> PaperReplay::SessionList::sessionsDuringTime(qint64 time) const
+{
+ QList<Session> sessions;
+ if (_m.isEmpty()) return sessions;
+ QMap<qint64, Session>::const_iterator it = _m.lowerBound(time);
+
+ if (it == _m.end()) --it;
+
+ while (it->d->start <= time && time <= it->d->end) {
+ sessions.append(*it);
+ if (it == _m.begin()) {
+ break;
+ } else {
+ --it;
+ }
+ }
+ return sessions;
+}
+
bool PaperReplay::open(const QString &path, const QString &penSerial, quint64 notebookGuid)
{
_dir.setPath(path + QString("/userdata/%1/Paper Replay/99/%2/sessions")
@@ -44,44 +102,43 @@ bool PaperReplay::open(const QString &path, const QString &penSerial, quint64 no
QDirIterator iter(_dir.path(), QStringList("PRS-*"), QDir::Dirs | QDir::NoDotAndDotDot);
while (iter.hasNext()) {
- QDir sessionDir(iter.next());
bool ok;
+ QDir sessionDir(iter.next());
quint64 sessionId = sessionDir.dirName().mid(4).toULongLong(&ok, 16);
+
if (!ok) {
qWarning() << "Invalid session identifier:" << sessionDir.dirName();
+ continue;
}
- Session &session = _sessions[sessionId];
+
+ Session session(sessionId);
if (!parseSessionInfo(session.d, sessionDir.filePath("session.info"))) {
qWarning() << "Could not parse:" << sessionDir.absoluteFilePath("session.info");
}
if (!parseSessionPages(session.d, sessionDir.filePath("session.pages"))) {
qWarning() << "Could not parse:" << sessionDir.absoluteFilePath("session.pages");
}
- }
+ if (!session.d->file.isEmpty()) {
+ session.d->file = sessionDir.filePath(session.d->file);
+ }
+
+ foreach (quint64 page, session.d->pages) {
+ _byPageTime[page].insert(session.d->start, session);
+ }
+ }
return true;
}
void PaperReplay::close()
{
- _sessions.clear();
- _byPage.clear();
+ _byPageTime.clear();
_dir.setPath(QString());
}
-QList<PaperReplay::Session> PaperReplay::sessions() const
+PaperReplay::SessionList PaperReplay::sessions(quint64 pageAddress) const
{
- return _sessions.values();
-}
-
-QList<PaperReplay::Session> PaperReplay::sessions(quint64 pageAddress) const
-{
- QList<Session> sessions;
- QMultiMap<quint64, quint64>::const_iterator it = _byPage.constFind(pageAddress);
- while (it != _byPage.end() && it.key() == pageAddress) {
- sessions.append(_sessions[it.value()]);
- }
- return sessions;
+ return SessionList(_byPageTime[pageAddress]);
}
bool PaperReplay::parseSessionInfo(SessionData *session, const QString &path)
@@ -123,7 +180,7 @@ bool PaperReplay::parseSessionInfoV3(SessionData *session, QIODevice *dev)
QDataStream s(dev);
if (s.skipRawData(5) != 5) return false;
- quint64 startTime, endTime, creationTime;
+ qint64 startTime, endTime, creationTime;
QString name;
s >> startTime >> endTime >> creationTime;
@@ -132,10 +189,10 @@ bool PaperReplay::parseSessionInfoV3(SessionData *session, QIODevice *dev)
}
session->name = name;
- session->start = Smartpen::fromPenTime(startTime);
- session->end = Smartpen::fromPenTime(endTime);
+ session->start = startTime;
+ session->end = endTime;
- qDebug() << "Session:" << name << session->start << session->end;
+ qDebug() << "Session:" << name << Smartpen::fromPenTime(session->start) << Smartpen::fromPenTime(session->end);
quint16 num_clips;
s >> num_clips;
@@ -156,6 +213,7 @@ bool PaperReplay::parseSessionInfoV3(SessionData *session, QIODevice *dev)
quint16 num_strokes;
s >> num_strokes;
+ // TODO:
for (uint i = 0; i < num_strokes; ++i) {
quint64 a, b, c;
quint32 d;
@@ -216,7 +274,8 @@ bool PaperReplay::parseSessionPagesV1(SessionData *session, QIODevice *dev)
session->pages.reserve(session->pages.size() + num_pages);
for (uint i = 0; i < num_pages; ++i) {
- quint64 address, time;
+ quint64 address;
+ qint64 time;
s >> address >> time;
session->pages.append(address);
diff --git a/paperreplay.h b/paperreplay.h
index e771584..c9eb6f2 100644
--- a/paperreplay.h
+++ b/paperreplay.h
@@ -1,10 +1,9 @@
#ifndef PAPERREPLAY_H
#define PAPERREPLAY_H
-#include <QtCore/QDateTime>
#include <QtCore/QDir>
#include <QtCore/QHash>
-#include <QtCore/QMultiMap>
+#include <QtCore/QMap>
#include <QtCore/QVector>
#define PAPER_REPLAY "Paper Replay"
@@ -14,8 +13,9 @@ class PaperReplay : public QObject
Q_OBJECT
struct SessionData : public QSharedData {
+ quint64 id;
QString name;
- QDateTime start, end;
+ qint64 start, end;
QVector<quint64> pages;
QString file;
};
@@ -28,26 +28,45 @@ public:
Session();
~Session();
+ bool isValid() const;
+
+ quint64 id() const;
+
QString name() const;
- QDateTime startTime() const;
- QDateTime endTime() const;
+ qint64 startTime() const;
+ qint64 endTime() const;
QVector<quint64> pages() const;
QString fileName() const;
private:
+ Session(quint64 id);
QSharedDataPointer<SessionData> d;
friend class PaperReplay;
+ friend class SessionList;
+ };
+
+ class SessionList {
+ public:
+ SessionList();
+
+ QList<Session> sessionsDuringTime(qint64 time) const;
+
+ private:
+ explicit SessionList(const QMap<qint64, Session>& byTime);
+
+ QMap<qint64, Session> _m;
+
+ friend class PaperReplay;
};
bool open(const QString &path, const QString &penSerial, quint64 notebookGuid);
void close();
- QList<Session> sessions() const;
- QList<Session> sessions(quint64 pageAddress) const;
+ SessionList sessions(quint64 pageAddress) const;
private:
static bool parseSessionInfo(SessionData *session, const QString &path);
@@ -60,8 +79,7 @@ private:
private:
QDir _dir;
- QHash<quint64, Session> _sessions;
- QMultiMap<quint64, quint64> _byPage;
+ QMap<quint64, QMap<qint64, Session> > _byPageTime;
};
#endif // PAPERREPLAY_H
diff --git a/scribiu.pro b/scribiu.pro
index 861ceff..a49ef42 100644
--- a/scribiu.pro
+++ b/scribiu.pro
@@ -1,4 +1,4 @@
-QT += core gui
+QT += core gui phonon
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
@@ -21,7 +21,8 @@ SOURCES += main.cc\
pageitem.cc \
stfgraphicsitem.cc \
paperreplay.cc \
- afdpageaddress.cc
+ afdpageaddress.cc \
+ stfstrokeitem.cc
HEADERS += mainwindow.h \
smartpenmanager.h \
@@ -34,6 +35,7 @@ HEADERS += mainwindow.h \
pageitem.h \
stfgraphicsitem.h \
paperreplay.h \
- afdpageaddress.h
+ afdpageaddress.h \
+ stfstrokeitem.h
FORMS += mainwindow.ui
diff --git a/stfgraphicsitem.cc b/stfgraphicsitem.cc
index 414cf6c..3c3a48b 100644
--- a/stfgraphicsitem.cc
+++ b/stfgraphicsitem.cc
@@ -2,38 +2,51 @@
#include <QtGui/QPainterPath>
#include "stfreader.h"
+#include "smartpen.h"
+#include "stfstrokeitem.h"
#include "stfgraphicsitem.h"
class StfToGraphicsPathItems : public StfReader::StrokeHandler {
QGraphicsItem *parent;
+ PaperReplay::SessionList replays;
+ PaperReplay::Session replay;
+ qint64 startTime, lastTime;
QPainterPath path;
QRectF bound;
public:
- StfToGraphicsPathItems(QGraphicsItem* parent)
- : parent(parent), path(), bound(0.0, 0.0, 1.0, 1.0) {
+ StfToGraphicsPathItems(const PaperReplay::SessionList &replays, QGraphicsItem* parent)
+ : parent(parent), replays(replays), path(), bound(0.0, 0.0, 1.0, 1.0) {
}
~StfToGraphicsPathItems() {
}
- bool startStroke(const QPoint& p, int force, quint64 time) {
+ bool startStroke(const QPoint& p, int force, qint64 time) {
Q_UNUSED(force);
- Q_UNUSED(time);
+ QList<PaperReplay::Session> sessions = replays.sessionsDuringTime(time);
+ if (!sessions.isEmpty()) {
+ replay = sessions.first();
+ } else {
+ replay = PaperReplay::Session();
+ }
+ startTime = time;
+ lastTime = time;
path = QPainterPath(QPointF(p));
return true;
}
- bool strokePoint(const QPoint& p, int force, quint64 time) {
+ bool strokePoint(const QPoint& p, int force, qint64 time) {
Q_UNUSED(force);
Q_UNUSED(time);
+ lastTime = time;
path.lineTo(QPointF(p));
return true;
}
bool endStroke() {
bound |= path.boundingRect();
- new QGraphicsPathItem(path, parent);
+ new StfStrokeItem(path, replay, startTime, lastTime, parent);
/* Parent will take the child down with him when deleted. */
return true;
}
@@ -43,12 +56,12 @@ public:
}
};
-StfGraphicsItem::StfGraphicsItem(QIODevice *dev, QGraphicsItem *parent) :
+StfGraphicsItem::StfGraphicsItem(QIODevice *dev, const PaperReplay::SessionList &replays, QGraphicsItem *parent) :
QGraphicsItem(parent)
{
setFlags(ItemHasNoContents);
- StfToGraphicsPathItems h(this);
+ StfToGraphicsPathItems h(replays, this);
StfReader r;
r.setStrokeHandler(&h);
if (r.parse(dev)) {
diff --git a/stfgraphicsitem.h b/stfgraphicsitem.h
index ed62ede..3d3178e 100644
--- a/stfgraphicsitem.h
+++ b/stfgraphicsitem.h
@@ -2,13 +2,14 @@
#define STFGRAPHICSITEM_H
#include <QtGui/QGraphicsItem>
+#include "paperreplay.h"
class StfGraphicsItem : public QGraphicsItem
{
QRectF bbox;
public:
- explicit StfGraphicsItem(QIODevice *stf, QGraphicsItem *parent = 0);
+ explicit StfGraphicsItem(QIODevice *stf, const PaperReplay::SessionList &replays, QGraphicsItem *parent = 0);
enum { Type = UserType + 's' };
diff --git a/stfreader.cc b/stfreader.cc
index c5edff0..fc62603 100644
--- a/stfreader.cc
+++ b/stfreader.cc
@@ -23,12 +23,12 @@ StfReader::StrokeHandler::~StrokeHandler()
bool StfReader::parseV1(BitReader& br)
{
- quint64 cur_time = 0;
+ qint64 cur_time = 0;
while (!br.atEnd()) {
syncV1(br);
quint8 header = br.readBits(8);
- quint64 time;
+ qint64 time;
QPoint p0, pa;
int f0;
diff --git a/stfreader.h b/stfreader.h
index 06013e1..447e737 100644
--- a/stfreader.h
+++ b/stfreader.h
@@ -11,8 +11,8 @@ public:
{
public:
virtual ~StrokeHandler();
- virtual bool startStroke(const QPoint& p, int force, quint64 time) = 0;
- virtual bool strokePoint(const QPoint& p, int force, quint64 time) = 0;
+ virtual bool startStroke(const QPoint& p, int force, qint64 time) = 0;
+ virtual bool strokePoint(const QPoint& p, int force, qint64 time) = 0;
virtual bool endStroke() = 0;
};
diff --git a/stfstrokeitem.cc b/stfstrokeitem.cc
new file mode 100644
index 0000000..caf1ae5
--- /dev/null
+++ b/stfstrokeitem.cc
@@ -0,0 +1,36 @@
+#include <QtCore/QDebug>
+#include <QtGui/QPen>
+#include <QtGui/QCursor>
+#include <QtGui/QGraphicsScene>
+#include <QtGui/QGraphicsSceneMouseEvent>
+#include "notebookview.h"
+#include "stfstrokeitem.h"
+
+StfStrokeItem::StfStrokeItem(const QPainterPath &stroke, const PaperReplay::Session &session, qint64 startTime, qint64 endTime, QGraphicsItem *parent)
+ : QGraphicsPathItem(stroke, parent), _session(session),
+ _startTime(startTime), _endTime(endTime)
+{
+ if (_session.isValid()) {
+ setPen(QPen(Qt::green));
+ setCursor(Qt::PointingHandCursor);
+ }
+}
+
+int StfStrokeItem::type() const
+{
+ return Type;
+}
+
+void StfStrokeItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (_session.isValid() && !_session.fileName().isEmpty()) {
+ QGraphicsView *view = scene()->views().first();
+ if (NotebookView *nbview = qobject_cast<NotebookView*>(view)) {
+ event->accept();
+ qint64 time = _startTime - _session.startTime();
+ if (time < 10) time = 0;
+
+ nbview->requestPaperReplay(_session.fileName(), time);
+ }
+ }
+}
diff --git a/stfstrokeitem.h b/stfstrokeitem.h
new file mode 100644
index 0000000..1e780af
--- /dev/null
+++ b/stfstrokeitem.h
@@ -0,0 +1,25 @@
+#ifndef STFSTROKEITEM_H
+#define STFSTROKEITEM_H
+
+#include <QtGui/QGraphicsPathItem>
+#include "paperreplay.h"
+
+class StfStrokeItem : public QGraphicsPathItem
+{
+public:
+ StfStrokeItem(const QPainterPath &stroke, const PaperReplay::Session &session, qint64 startTime, qint64 endTime, QGraphicsItem *parent = 0);
+
+ enum { Type = UserType + 't' };
+
+ int type() const;
+
+protected:
+ void mousePressEvent(QGraphicsSceneMouseEvent *event);
+
+private:
+ PaperReplay::Session _session;
+ qint64 _startTime;
+ qint64 _endTime;
+};
+
+#endif // STFSTROKEITEM_H