#include "egif.h" #include "cfg.h" #include "tools.h" #include #include #include #include #include #include #include #include #include EGif *EGif::create(const QString &file, PageListItem *pageItem, EBase *multiWin) { auto movie = new QMovie(file); if(! movie->isValid()) { QMessageBox::critical(pageItem->listWidget(), "Gif Error", Tools::readErrStr(movie->lastError())+": "+movie->lastErrorString()+"\n"+file); delete movie; return 0; } movie->setCacheMode(QMovie::CacheAll); movie->jumpToFrame(0); QFileInfo info(file); return new EGif(movie, info.absolutePath(), info.fileName(), pageItem, multiWin); } EGif *EGif::create(const QJsonObject &json, PageListItem *pageItem, EBase *multiWin) { auto widget = json["widget"]; auto dir = widget["path"].toString(); auto name = widget["file"].toString(); if(! QFileInfo::exists(dir)) dir = pageItem->mPageDir; QString file = dir + "/" + name; if(QFileInfo::exists(file)) ; else if(QFileInfo::exists(file = pageItem->mPageDir + "/" + name)) dir = pageItem->mPageDir; else return nullptr; auto movie = new QMovie(file); if(! movie->isValid()) { delete movie; return 0; } movie->setCacheMode(QMovie::CacheAll); movie->jumpToFrame(0); auto ins = new EGif(movie, dir, name, pageItem, multiWin); ins->setBaseAttr(json); auto play = json["play"]; ins->mDuration = play["playDuration"].toInt(); ins->mPlayTimes = play["playTimes"].toInt(); return ins; } EGif::EGif(QMovie *movie, const QString &dir, const QString &name, PageListItem *pageItem, EBase *multiWin) : EBase(multiWin), mMovie(movie), mDir(dir), mName(name), mPageItem(pageItem) { mType = EBase::Gif; } EGif::~EGif() { if(mMovie) delete mMovie; } void EGif::paint(QPainter *painter, const QStyleOptionGraphicsItem *a, QWidget *b) { if(mMovie) { painter->setRenderHints(QPainter::Antialiasing|QPainter::SmoothPixmapTransform); painter->drawPixmap(innerRect(), mMovie->currentPixmap(), QRectF()); if(timer==0) { auto delay = mMovie->nextFrameDelay(); if(delay) { timer = new SyncTimer(delay); connect(timer, &SyncTimer::timeout, this, &EGif::sltNext, Qt::BlockingQueuedConnection); timer->start(); } } } EBase::paint(painter, a, b); } void EGif::sltNext() { if(isVisible() && mMovie) { mMovie->jumpToNextFrame(); timer->inter = mMovie->nextFrameDelay(); update(); } else if(timer) { timer->stop(); timer = 0; } } void EGif::loadFiles() { if(mMovie) return; if(! QFileInfo::exists(mDir + "/" + mName)) return; mMovie = new QMovie(mDir + "/" + mName, QByteArray()); mMovie->setCacheMode(QMovie::CacheAll); mMovie->jumpToFrame(0); } void EGif::freeFiles() { if(mMovie==0) return; delete mMovie; mMovie = 0; } QWidget* EGif::attrWgt() { auto wgtAttr = new QWidget; auto vBox = new QVBoxLayout(wgtAttr); vBox->setContentsMargins(6, 0, 6, 0); if(mMultiWin) vBox->setSpacing(3); addBaseAttrWgt(vBox); auto hBox = new QHBoxLayout(); hBox->addWidget(new QLabel(tr("Basic Properties"))); auto line = new QFrame(); line->setFrameShape(QFrame::HLine); line->setFrameShadow(QFrame::Sunken); hBox->addWidget(line, 1); vBox->addLayout(hBox); hBox = new QHBoxLayout(); hBox->addSpacing(6); hBox->addWidget(new QLabel(tr("File"))); auto wFile = new QLineEdit(mName); wFile->setReadOnly(true); hBox->addWidget(wFile); auto bnSelectFile = new QPushButton("..."); bnSelectFile->setFixedWidth(30); bnSelectFile->setObjectName("bnSelectFile"); connect(bnSelectFile, &QPushButton::clicked, wgtAttr, [=] { auto file = QFileDialog::getOpenFileName(wgtAttr, tr("Select File"), gFileHome, EGif::filters()); if(file.isEmpty()) return; auto movie = new QMovie(file); if(! movie->isValid()) { QMessageBox::critical(wgtAttr, "Gif Error", Tools::readErrStr(movie->lastError())+": "+movie->lastErrorString()+"\n"+file); delete movie; return; } movie->setCacheMode(QMovie::CacheAll); movie->jumpToFrame(0); QFileInfo fileInfo(file); mName = fileInfo.fileName(); wFile->setText(mName); mDir = fileInfo.absolutePath(); gFileHome = mDir; if(mMovie) delete mMovie; mMovie = movie; }); hBox->addWidget(bnSelectFile); vBox->addLayout(hBox); hBox = new QHBoxLayout(); hBox->addWidget(new QLabel(tr("Play Properties"))); line = new QFrame(); line->setFrameShape(QFrame::HLine); line->setFrameShadow(QFrame::Sunken); hBox->addWidget(line, 1); vBox->addLayout(hBox); hBox = new QHBoxLayout(); hBox->addSpacing(6); hBox->addWidget(new QLabel(tr("Play Duration"))); auto wPlayDuration = new QSpinBox(); wPlayDuration->setRange(1, 99999); wPlayDuration->setValue(mDuration); connect(wPlayDuration, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) { mDuration = value; }); hBox->addWidget(wPlayDuration); hBox->addWidget(new QLabel(tr("s"))); hBox->addStretch(); vBox->addLayout(hBox); hBox = new QHBoxLayout(); hBox->addSpacing(6); hBox->addWidget(new QLabel(tr("Play Times"))); auto wPlayTimes = new QSpinBox(); wPlayTimes->setRange(1, 99999); wPlayTimes->setValue(mPlayTimes); connect(wPlayTimes, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) { mPlayTimes = value; }); hBox->addWidget(wPlayTimes); hBox->addStretch(); vBox->addLayout(hBox); vBox->addStretch(); return wgtAttr; } bool EGif::save(const QString &pageDir) { QString oldFile = mDir + PAGEDEL_SUFFIX + "/" + mName; if(QFileInfo::exists(oldFile)) ; else if(QFileInfo::exists(oldFile = mDir + "/" + mName)) ; else return false; QFile::copy(oldFile, pageDir + "/" + mName); mDir = pageDir; return true; } QJsonObject EGif::attrJson() const { QJsonObject oRoot; addBaseAttr(oRoot); oRoot["elementType"] = "Gif"; oRoot["widget"] = QJsonObject{ {"file", mName}, {"path", mDir} }; oRoot["play"] = QJsonObject{ {"playDuration", mDuration}, {"playTimes", mPlayTimes} }; return oRoot; }