andre@2: /* Copyright (C) 2014 by Intevation GmbH andre@2: * andre@2: * This file is Free Software under the GNU GPL (v>=2) andre@2: * and comes with ABSOLUTELY NO WARRANTY! andre@2: * See LICENSE.txt for details. andre@2: */ andre@2: #include "pngplayer.h" andre@3: #include "constants.h" andre@3: #include "imagelabel.h" andre@2: #include andre@2: #include andre@2: #include andre@3: #include andre@3: #include andre@3: #include andre@5: #include andre@10: #include andre@10: #include andre@3: andre@3: #include andre@2: andre@2: PNGPlayer::PNGPlayer(QWidget *parent, Qt::WindowFlags f) : QWidget(parent, f) { andre@2: setupGUI(); andre@5: QSettings settings; andre@5: mSpeedSlider->setValue(settings.value(REPLAY_SPEED_KEY, REPLAY_SPEED_DEFAULT).toInt()); andre@5: speedChanged(); andre@2: } andre@2: andre@2: void PNGPlayer::setupGUI() { andre@2: QVBoxLayout *baseLayout = new QVBoxLayout; andre@3: mPNGLabel = new ImageLabel; andre@3: mPNGLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); andre@3: andre@3: QHBoxLayout *controlArea = new QHBoxLayout; andre@3: QHBoxLayout *controlBtns = new QHBoxLayout; andre@3: controlArea->addLayout(controlBtns); andre@10: controlArea->addStretch(-1); andre@3: andre@10: QPushButton *firstBtn = new QPushButton; andre@10: firstBtn->setIcon(QApplication::style()->standardIcon(QStyle::SP_MediaSkipBackward)); andre@3: controlBtns->addWidget(firstBtn); andre@3: connect(firstBtn, &QPushButton::clicked, this, &PNGPlayer::firstClicked); andre@3: andre@10: QPushButton *prevBtn = new QPushButton; andre@10: prevBtn->setIcon(QApplication::style()->standardIcon(QStyle::SP_MediaSeekBackward)); andre@3: controlBtns->addWidget(prevBtn); andre@3: connect(prevBtn, &QPushButton::clicked, this, &PNGPlayer::back); andre@3: andre@10: mPlayBtn = new QPushButton; andre@3: mPlayBtn->setCheckable(true); andre@10: mPlayBtn->setIcon(QApplication::style()->standardIcon(QStyle::SP_MediaPlay)); andre@3: controlBtns->addWidget(mPlayBtn); andre@3: connect(mPlayBtn, &QPushButton::clicked, this, &PNGPlayer::togglePlay); andre@3: andre@10: QPushButton *nextBtn = new QPushButton; andre@10: nextBtn->setIcon(QApplication::style()->standardIcon(QStyle::SP_MediaSeekForward)); andre@3: connect(nextBtn, &QPushButton::clicked, this, &PNGPlayer::advance); andre@3: controlBtns->addWidget(nextBtn); andre@3: andre@10: QPushButton *lastBtn = new QPushButton; andre@10: lastBtn->setIcon(QApplication::style()->standardIcon(QStyle::SP_MediaSkipForward)); andre@3: controlBtns->addWidget(lastBtn); andre@3: connect(lastBtn, &QPushButton::clicked, this, &PNGPlayer::lastClicked); andre@3: andre@3: mSlider = new QSlider(Qt::Horizontal); andre@3: mSlider->setTickPosition(QSlider::TicksBelow); andre@3: connect(mSlider, &QSlider::valueChanged, this, &PNGPlayer::sliderChanged); andre@3: connect(mSlider, &QSlider::sliderPressed, this, &PNGPlayer::sliderPressed); andre@3: connect(mSlider, &QSlider::sliderReleased, this, &PNGPlayer::sliderReleased); andre@3: andre@3: QVBoxLayout *speedInfoArea = new QVBoxLayout; andre@3: QHBoxLayout *speedArea = new QHBoxLayout; andre@3: speedInfoArea->addLayout(speedArea); andre@3: andre@3: QLabel *speedLabel = new QLabel(tr("Speed:")); andre@3: speedArea->addWidget(speedLabel); andre@3: andre@3: mSpeedSlider = new QSlider(Qt::Horizontal); andre@5: mSpeedSlider->setMaximum(10); andre@5: mSpeedSlider->setTickInterval(1); andre@3: mSpeedSlider->setTickPosition(QSlider::TicksBelow); andre@5: mSpeedSlider->setTracking(false); andre@5: mSpeedSlider->setInvertedAppearance(true); andre@5: andre@3: speedArea->addWidget(mSpeedSlider); andre@5: connect(mSpeedSlider, &QSlider::valueChanged, this, &PNGPlayer::speedChanged); andre@3: andre@3: mCurSpeedLabel = new QLabel; andre@3: speedArea->addWidget(mCurSpeedLabel); andre@3: speedArea->addStretch(-1); andre@3: andre@3: mPositionLabel = new QLabel; andre@3: speedInfoArea->addWidget(mPositionLabel); andre@3: andre@3: controlArea->addLayout(speedInfoArea); andre@3: andre@2: baseLayout->addWidget(mPNGLabel); andre@3: baseLayout->addLayout(controlArea); andre@3: baseLayout->addWidget(mSlider); andre@3: andre@2: connect(&mAdvanceTimer, SIGNAL(timeout()), this, SIGNAL(advance())); andre@2: setLayout(baseLayout); andre@2: } andre@2: andre@3: void PNGPlayer::showPicture(const QString& fileName, int current, int max, andre@3: const QDateTime& timestamp) { andre@2: QPixmap pic(mBaseDir.filePath(fileName)); andre@2: /* If this is too slow we could use a pixmap cache here and do andre@2: * some intelligent preloading */ andre@2: if (pic.isNull()) { andre@20: qWarning() << "Failed to load picture: " << fileName; andre@7: // emit error(tr("Failed to load picture: '%1'").arg(fileName)); andre@2: return; andre@2: } andre@2: mPNGLabel->setPixmap(pic); andre@3: updatePositions(current, max, timestamp); andre@2: } andre@3: andre@3: void PNGPlayer::updatePositions(int current, int max, const QDateTime& timestamp) { andre@3: mMax = max; andre@3: mSlider->blockSignals(true); /* We only want user generated changes */ andre@3: mSlider->setValue(current); andre@3: mSlider->blockSignals(false); andre@3: mSlider->setMaximum(max); andre@3: mPositionLabel->setText("" + tr("Screenshot Nr.:") + " " + andre@3: QString("%1 (%2)").arg(current).arg(max) + " / " + andre@8: tr("Timestamp:") + " " + (timestamp.isValid() ? andre@8: timestamp.toString(LONG_DATE_FORMAT) : tr("Unknown"))); andre@3: andre@3: if (mMax == current && mAdvanceTimer.isActive()) { andre@3: togglePlay(); andre@3: } andre@3: } andre@3: andre@3: void PNGPlayer::setSpeed(int mSecsPerPicture) { andre@3: if (mSecsPerPicture == 1000) { andre@3: mCurSpeedLabel->setText(tr("%1 second per Picture"). andre@5: arg(mSecsPerPicture / 1000.)); andre@3: } else { andre@3: mCurSpeedLabel->setText(tr("%1 seconds per Picture"). andre@5: arg(mSecsPerPicture / 1000.)); andre@3: } andre@3: mAdvanceTimer.setInterval(mSecsPerPicture); andre@3: } andre@3: andre@3: void PNGPlayer::togglePlay() { andre@3: if (mAdvanceTimer.isActive()) { andre@3: mAdvanceTimer.stop(); andre@3: mPlayBtn->setChecked(false); andre@10: mPlayBtn->setIcon(QApplication::style()->standardIcon(QStyle::SP_MediaPlay)); andre@3: } else { andre@3: mAdvanceTimer.start(); andre@3: mPlayBtn->setChecked(true); andre@10: mPlayBtn->setIcon(QApplication::style()->standardIcon(QStyle::SP_MediaPause)); andre@3: emit advance(); andre@3: } andre@3: } andre@3: andre@3: void PNGPlayer::sliderChanged() { andre@3: qDebug() << "Slider moved. "; andre@3: emit jumpToFrame(mSlider->value()); andre@3: } andre@3: andre@3: void PNGPlayer::sliderPressed() { andre@3: qDebug() << "Slider pressed. Deactivating timer. "; andre@3: mAdvanceTimer.stop(); andre@3: } andre@3: andre@3: void PNGPlayer::sliderReleased() { andre@3: if (mPlayBtn->isChecked()) { andre@3: mAdvanceTimer.start(); andre@3: } andre@3: } andre@3: andre@3: void PNGPlayer::firstClicked() { andre@3: emit jumpToFrame(0); andre@3: } andre@3: andre@3: void PNGPlayer::lastClicked() { andre@3: emit jumpToFrame(mMax); andre@3: } andre@5: andre@5: void PNGPlayer::speedChanged() { andre@5: if (mSpeedSlider->value()) { andre@5: setSpeed(mSpeedSlider->value() * REPLAY_SPEED_STEP_MS); andre@5: } else { andre@5: setSpeed(REPLAY_SPEED_STEP_MS / 2); andre@5: } andre@5: QSettings settings; andre@5: settings.setValue(REPLAY_SPEED_KEY, mSpeedSlider->value()); andre@5: }