diff options
Diffstat (limited to 'mainwindow.cc')
-rw-r--r-- | mainwindow.cc | 196 |
1 files changed, 140 insertions, 56 deletions
diff --git a/mainwindow.cc b/mainwindow.cc index 5c27145..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,16 +43,15 @@ MainWindow::MainWindow(QWidget *parent) : ui->notebookTree->header()->setSectionResizeMode(1, QHeaderView::Fixed); ui->notebookTree->header()->setSectionResizeMode(2, QHeaderView::Fixed); ui->notebookTree->expandAll(); - ui->notebookView->setVisible(false); + 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); - ui->paperReplayView->setVisible(false); - 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()), @@ -60,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"); @@ -85,9 +87,8 @@ void MainWindow::closeNotebook() _curPenName.clear(); _curNotebookName.clear(); _replay->close(); + ui->pane2Stack->setCurrentWidget(ui->notebookView); ui->notebookView->setNotebook(QString()); - ui->notebookView->setVisible(false); - ui->paperReplayView->setVisible(false); } void MainWindow::openNotebook(const QString &pen, const QString ¬ebook) @@ -99,28 +100,31 @@ void MainWindow::openNotebook(const QString &pen, const QString ¬ebook) _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->paperReplayView->setVisible(true); + ui->pane2Stack->setCurrentWidget(ui->paperReplayView); } else { QString nbDir = _notebooks->notebookDirectory(_curPenName, _curNotebookName); qDebug() << "Opening notebook" << _curPenName << _curNotebookName << nbDir; + ui->notebookView->setPenUserTime(userTime); ui->notebookView->setPaperReplay(_notebooks->paperReplayDirectory(_curPenName)); ui->notebookView->setNotebook(nbDir); - ui->notebookView->setVisible(true); + ui->pane2Stack->setCurrentWidget(ui->notebookView); } } 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)); @@ -142,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; @@ -173,8 +201,8 @@ void MainWindow::handleNotebookSelected(const QModelIndex &index) // Get column 0, which corresponds to notebook name QModelIndex nb = _notebooks->index(index.row(), 0, parent); - openNotebook(_notebooks->data(parent, Qt::DisplayRole).toString(), - _notebooks->data(nb, Qt::DisplayRole).toString()); + openNotebook(_notebooks->data(parent, NotebookModel::FileNameRole).toString(), + _notebooks->data(nb, NotebookModel::FileNameRole).toString()); } void MainWindow::handleNotebookRowsInserted(const QModelIndex &index, int start, int end) @@ -205,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() @@ -294,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: @@ -309,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)) { @@ -334,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")); @@ -362,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; @@ -377,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(); +} |