aboutsummaryrefslogtreecommitdiff
path: root/mainwindow.cc
diff options
context:
space:
mode:
Diffstat (limited to 'mainwindow.cc')
-rw-r--r--mainwindow.cc183
1 files changed, 135 insertions, 48 deletions
diff --git a/mainwindow.cc b/mainwindow.cc
index bba19cc..cf1ef1a 100644
--- a/mainwindow.cc
+++ b/mainwindow.cc
@@ -25,13 +25,14 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
+#define PAPER_REPLAY_SLIDER_SCALE 100LL /* in msec */
+
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
_notebooks(new NotebookModel(this)),
_manager(new SmartpenManager(this)),
- _media(new Phonon::MediaObject(this)),
- _mediaOutput(new Phonon::AudioOutput(this)),
+ _player(new QMediaPlayer(this)),
_replay(new PaperReplay(this)),
_replayModel(new PaperReplayModel(_replay, this)),
_statusLabel(new QLabel)
@@ -42,14 +43,15 @@ MainWindow::MainWindow(QWidget *parent) :
ui->notebookTree->header()->setSectionResizeMode(1, QHeaderView::Fixed);
ui->notebookTree->header()->setSectionResizeMode(2, QHeaderView::Fixed);
ui->notebookTree->expandAll();
+ ui->replaySlider->setSingleStep(5000 / PAPER_REPLAY_SLIDER_SCALE);
+ ui->replaySlider->setPageStep(30000 / PAPER_REPLAY_SLIDER_SCALE);
ui->paperReplayView->setModel(_replayModel);
ui->paperReplayView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
ui->paperReplayView->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Fixed);
- Phonon::createPath(_media, _mediaOutput);
- _media->setTickInterval(500);
- ui->replaySlider->setMediaObject(_media);
ui->pauseButton->setVisible(false);
ui->statusBar->addWidget(_statusLabel, 1);
+ _player->setAudioRole(QAudio::VideoRole);
+
connect(_notebooks, SIGNAL(rowsInserted(QModelIndex,int,int)),
this, SLOT(handleNotebookRowsInserted(QModelIndex,int,int)));
connect(_manager, SIGNAL(pensBeingSynchronizedChanged()),
@@ -58,12 +60,14 @@ MainWindow::MainWindow(QWidget *parent) :
this, SLOT(handlePenSyncComplete(QString)));
connect(_manager, SIGNAL(syncFailed(QString)),
this, SLOT(handlePenSyncFailed(QString)));
- connect(_media, SIGNAL(stateChanged(Phonon::State,Phonon::State)),
- this, SLOT(handleMediaStateChange(Phonon::State)));
- connect(_media, SIGNAL(totalTimeChanged(qint64)),
- this, SLOT(handleMediaTotalTimeChanged(qint64)));
- connect(_media, SIGNAL(tick(qint64)),
- this, SLOT(handleMediaTick(qint64)));
+ connect(_player, SIGNAL(stateChanged(QMediaPlayer::State)),
+ this, SLOT(handlePlayerStateChanged(QMediaPlayer::State)));
+ connect(_player, SIGNAL(durationChanged(qint64)),
+ this, SLOT(handlePlayerDurationChanged(qint64)));
+ connect(_player, SIGNAL(positionChanged(qint64)),
+ this, SLOT(handlePlayerPositionChanged(qint64)));
+ connect(_player, SIGNAL(seekableChanged(bool)),
+ this, SLOT(handlePlayerSeekableChanged(bool)));
QSettings settings;
settings.beginGroup("mainwindow");
@@ -96,10 +100,12 @@ void MainWindow::openNotebook(const QString &pen, const QString &notebook)
_curPenName = pen;
_curNotebookName = notebook;
+ Smartpen::PenTime userTime = _notebooks->penUserTime(pen);
+
if (_curNotebookName == PAPER_REPLAY) {
QString replayDir = _notebooks->paperReplayDirectory(_curPenName);
- _replay->open(replayDir, 0);
+ _replay->open(replayDir, PAPER_REPLAY_GUID, userTime);
_replayModel->refresh();
ui->pane2Stack->setCurrentWidget(ui->paperReplayView);
@@ -108,6 +114,7 @@ void MainWindow::openNotebook(const QString &pen, const QString &notebook)
qDebug() << "Opening notebook" << _curPenName << _curNotebookName << nbDir;
+ ui->notebookView->setPenUserTime(userTime);
ui->notebookView->setPaperReplay(_notebooks->paperReplayDirectory(_curPenName));
ui->notebookView->setNotebook(nbDir);
ui->pane2Stack->setCurrentWidget(ui->notebookView);
@@ -117,7 +124,7 @@ void MainWindow::openNotebook(const QString &pen, const QString &notebook)
void MainWindow::exportCurrentPageAsPng(const QString &file)
{
qDebug() << "Exporting current page" << ui->notebookView->curPage() << "to" << file;
- QImage image = ui->notebookView->exportPage(ui->notebookView->curPage());
+ QImage image = ui->notebookView->exportPageAsImage(ui->notebookView->curPage());
if (!image.save(file, "PNG")) {
QMessageBox::warning(this, tr("Export page"),
tr("Could not export current page to '%s'").arg(file));
@@ -139,10 +146,34 @@ void MainWindow::exportCurrentPageAsSvg(const QString &file)
painter.end();
}
+void MainWindow::exportCurrentPageAsTXYP(const QString &file, bool relativeTime)
+{
+ QFile f(file);
+ if (!f.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) {
+ QMessageBox::warning(this, tr("Export page"),
+ tr("Could not export current page to '%s'").arg(file));
+ return;
+ }
+ ui->notebookView->exportPageAsTXYP(&f, ui->notebookView->curPage(), relativeTime);
+ f.close();
+}
+
+void MainWindow::exportCurrentPageAsInkML(const QString &file)
+{
+ QFile f(file);
+ if (!f.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) {
+ QMessageBox::warning(this, tr("Export page"),
+ tr("Could not export current page to '%s'").arg(file));
+ return;
+ }
+ ui->notebookView->exportPageAsInkML(&f, ui->notebookView->curPage());
+ f.close();
+}
+
void MainWindow::exportCurrentPaperReplayAsAac(const QString &file)
{
- QString src = _media->currentSource().fileName();
- if (src.isEmpty()) {
+ QString src = currentPlayerMediaPath();
+ if (src.isNull()) {
QMessageBox::warning(this, tr("Export audio"),
tr("No audio file is selected"));
return;
@@ -202,71 +233,80 @@ void MainWindow::handlePaperReplayRequested(const QString &file, qint64 time)
QString filePath = finfo.canonicalFilePath();
- if (_media->currentSource().fileName() != filePath) {
- _media->setCurrentSource(QUrl::fromLocalFile(filePath));
+ if (currentPlayerMediaPath() != filePath) {
+ qDebug() << "requesting media " << filePath;
+ _player->setMedia(QUrl::fromLocalFile(filePath));
}
- switch (_media->state()) {
- case Phonon::PlayingState:
- case Phonon::BufferingState:
- case Phonon::PausedState:
+ qDebug() << "requesting media seek to" << time << "/" << _player->duration();
+
+ if (_player->isSeekable()) {
+ // Media is loaded and ready to go
_pendingSeek = 0;
- _media->seek(time);
- break;
- default:
+ _player->setPosition(time);
+ } else {
+ // Otherwise delay the seek until after media starts playing
_pendingSeek = time;
- break;
}
- _media->play();
+ _player->play();
}
void MainWindow::handlePaperReplayPlay()
{
- _media->play();
+ _player->play();
}
void MainWindow::handlePaperReplayPause()
{
- _media->pause();
+ _player->pause();
+}
+
+void MainWindow::handlePaperReplaySliderChanged(int value)
+{
+ _player->setPosition(value * PAPER_REPLAY_SLIDER_SCALE);
}
-void MainWindow::handleMediaStateChange(Phonon::State state)
+void MainWindow::handlePlayerStateChanged(QMediaPlayer::State state)
{
switch (state) {
- case Phonon::PlayingState:
+ case QMediaPlayer::PlayingState:
ui->playButton->setVisible(false);
ui->pauseButton->setVisible(true);
- if (_pendingSeek) {
- _media->seek(_pendingSeek);
- _pendingSeek = 0;
- }
- ui->mediaPosLabel->setText(formatDuration(_media->currentTime()));
- ui->mediaLenLabel->setText("/ " + formatDuration(_media->totalTime()));
break;
- case Phonon::PausedState:
+ case QMediaPlayer::PausedState:
ui->playButton->setVisible(true);
ui->pauseButton->setVisible(false);
- ui->mediaPosLabel->setText(formatDuration(_media->currentTime()));
- ui->mediaLenLabel->setText("/ " + formatDuration(_media->totalTime()));
break;
default:
ui->playButton->setVisible(true);
ui->pauseButton->setVisible(false);
- ui->mediaPosLabel->setText(QString());
- ui->mediaLenLabel->setText(QString());
break;
}
}
-void MainWindow::handleMediaTotalTimeChanged(qint64 time)
+void MainWindow::handlePlayerDurationChanged(qint64 time)
{
ui->mediaLenLabel->setText("/ " + formatDuration(time));
+ ui->replaySlider->setMaximum(time / PAPER_REPLAY_SLIDER_SCALE);
}
-void MainWindow::handleMediaTick(qint64 time)
+void MainWindow::handlePlayerPositionChanged(qint64 time)
{
ui->mediaPosLabel->setText(formatDuration(time));
+ if (!ui->replaySlider->isSliderDown()) {
+ QSignalBlocker blocker(ui->replaySlider);
+ ui->replaySlider->setValue(time / PAPER_REPLAY_SLIDER_SCALE);
+ }
+}
+
+void MainWindow::handlePlayerSeekableChanged(bool seekable)
+{
+ if (seekable && _pendingSeek) {
+ qDebug() << "requesting (pending) media seek to" << _pendingSeek << "/" << _player->duration();
+ _player->setPosition(_pendingSeek);
+ _pendingSeek = 0;
+ }
}
void MainWindow::handlePensBeingSynchronizedChanged()
@@ -291,13 +331,21 @@ void MainWindow::handlePenSyncFailed(const QString &penName)
void MainWindow::handleExport()
{
+ QSettings settings;
+
if (_curNotebookName == PAPER_REPLAY) {
+ settings.beginGroup("export");
+ settings.beginGroup("audio");
+
+ QString dir = settings.value("dir").toString();
+
QStringList filters;
filters << tr("Current audio as AAC (*.aac)");
QString filter;
- QString fileName = QFileDialog::getSaveFileName(this, tr("Export page"), QString(),
+ QString fileName = QFileDialog::getSaveFileName(this, tr("Export page"), dir,
filters.join(";;"), &filter);
if (fileName.isEmpty()) return;
+
int filterIndex = filters.indexOf(filter);
switch (filterIndex) {
case 0:
@@ -306,17 +354,32 @@ void MainWindow::handleExport()
}
exportCurrentPaperReplayAsAac(fileName);
break;
+ default:
+ Q_UNREACHABLE();
}
+
+ QFileInfo file(fileName);
+ settings.setValue("dir", file.absolutePath());
} else if (!_curNotebookName.isEmpty()) {
+ settings.beginGroup("export");
+ settings.beginGroup("page");
+
+ QString dir = settings.value("dir").toString();
+
QStringList filters;
filters << tr("Current page as PNG image (*.png)")
<< tr("Current page as SVG image (*.svg)")
+ << tr("Current page as TXYP (*.txyp)")
+ << tr("Current page as InkML (*.inkml)")
<< tr("Current audio as AAC (*.aac)");
- QString filter;
- QString fileName = QFileDialog::getSaveFileName(this, tr("Export page"), QString(),
+ int filterIndex = settings.value("filetype").toInt();
+ QString filter = filters.value(filterIndex);
+
+ QString fileName = QFileDialog::getSaveFileName(this, tr("Export page"), dir,
filters.join(";;"), &filter);
if (fileName.isEmpty()) return;
- int filterIndex = filters.indexOf(filter);
+
+ filterIndex = filters.indexOf(filter);
switch (filterIndex) {
case 0:
if (!fileName.endsWith(".png", Qt::CaseInsensitive)) {
@@ -331,12 +394,30 @@ void MainWindow::handleExport()
exportCurrentPageAsSvg(fileName);
break;
case 2:
+ if (!fileName.endsWith(".txyp", Qt::CaseInsensitive)) {
+ fileName.append(".txyp");
+ }
+ exportCurrentPageAsTXYP(fileName, settings.value("txyp_relative_t", true).toBool());
+ break;
+ case 3:
+ if (!fileName.endsWith(".inkml", Qt::CaseInsensitive)) {
+ fileName.append(".inkml");
+ }
+ exportCurrentPageAsInkML(fileName);
+ break;
+ case 4:
if (!fileName.endsWith(".aac", Qt::CaseInsensitive)) {
fileName.append(".aac");
}
exportCurrentPaperReplayAsAac(fileName);
break;
+ default:
+ Q_UNREACHABLE();
}
+
+ QFileInfo file(fileName);
+ settings.setValue("dir", file.absolutePath());
+ settings.setValue("filetype", filterIndex);
} else {
QMessageBox::warning(this, tr("Export page"),
tr("Open a notebook or audio in order to export"));
@@ -359,7 +440,7 @@ void MainWindow::closeEvent(QCloseEvent *event)
settings.endGroup();
}
-QString MainWindow::formatDuration(qint64 time)
+QString MainWindow::formatDuration(qint64 time) const
{
int secs = time / 1000;
int mins = secs / 60;
@@ -374,3 +455,9 @@ QString MainWindow::formatDuration(qint64 time)
return QString("%2:%3").arg(mins).arg(secs, 2, 10, fill);
}
}
+
+QT_WARNING_DISABLE_DEPRECATED
+QString MainWindow::currentPlayerMediaPath() const
+{
+ return _player->media().canonicalUrl().toLocalFile();
+}