diff --git a/plugins/extensions/animationrenderer/AnimationRenderer.cpp b/plugins/extensions/animationrenderer/AnimationRenderer.cpp index 7f4001711e..d65734ec56 100644 --- a/plugins/extensions/animationrenderer/AnimationRenderer.cpp +++ b/plugins/extensions/animationrenderer/AnimationRenderer.cpp @@ -1,200 +1,199 @@ /* * Copyright (c) 2016 Boudewijn Rempt * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "AnimationRenderer.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "DlgAnimationRenderer.h" K_PLUGIN_FACTORY_WITH_JSON(AnimaterionRendererFactory, "kritaanimationrenderer.json", registerPlugin();) AnimaterionRenderer::AnimaterionRenderer(QObject *parent, const QVariantList &) : KisViewPlugin(parent) { // Shows the big dialog KisAction *action = createAction("render_animation"); action->setActivationFlags(KisAction::IMAGE_HAS_ANIMATION); connect(action, SIGNAL(triggered()), this, SLOT(slotRenderAnimation())); // Re-renders the image sequence as defined in the last render action = createAction("render_image_sequence_again"); action->setActivationFlags(KisAction::IMAGE_HAS_ANIMATION); connect(action, SIGNAL(triggered()), this, SLOT(slotRenderSequenceAgain())); } AnimaterionRenderer::~AnimaterionRenderer() { } void AnimaterionRenderer::slotRenderAnimation() { KisImageWSP image = m_view->image(); if (!image) return; if (!image->animationInterface()->hasAnimation()) return; KisDocument *doc = m_view->document(); doc->setFileProgressProxy(); doc->setFileProgressUpdater(i18n("Export frames")); DlgAnimationRenderer dlgAnimationRenderer(doc, m_view->mainWindow()); dlgAnimationRenderer.setCaption(i18n("Render Animation")); KisConfig kisConfig; KisPropertiesConfigurationSP cfg = new KisPropertiesConfiguration(); cfg->fromXML(kisConfig.exportConfiguration("IMAGESEQUENCE")); dlgAnimationRenderer.setSequenceConfiguration(cfg); cfg->clearProperties(); cfg->fromXML(kisConfig.exportConfiguration("ANIMATION_RENDERER")); dlgAnimationRenderer.setVideoConfiguration(cfg); cfg->clearProperties(); cfg->fromXML(kisConfig.exportConfiguration("FFMPEG_CONFIG")); dlgAnimationRenderer.setEncoderConfiguration(cfg); // update the UI to show the selected export options dlgAnimationRenderer.updateExportUIOptions(); if (dlgAnimationRenderer.exec() == QDialog::Accepted) { KisPropertiesConfigurationSP sequenceConfig = dlgAnimationRenderer.getSequenceConfiguration(); kisConfig.setExportConfiguration("IMAGESEQUENCE", sequenceConfig); QString mimetype = sequenceConfig->getString("mimetype"); QString extension = KisMimeDatabase::suffixesForMimeType(mimetype).first(); QString baseFileName = QString("%1/%2.%3").arg(sequenceConfig->getString("directory")) .arg(sequenceConfig->getString("basename")) .arg(extension); KisAnimationExportSaver exporter(doc, baseFileName, sequenceConfig->getInt("first_frame"), sequenceConfig->getInt("last_frame"), sequenceConfig->getInt("sequence_start")); KisImportExportFilter::ConversionStatus status = exporter.exportAnimation(dlgAnimationRenderer.getFrameExportConfiguration()); if (status != KisImportExportFilter::OK) { const QString msg = KisImportExportFilter::conversionStatusString(status); QMessageBox::critical(0, i18nc("@title:window", "Krita"), i18n("Could not export animation frames:\n%1", msg)); } else { QString savedFilesMask = exporter.savedFilesMask(); KisPropertiesConfigurationSP videoConfig = dlgAnimationRenderer.getVideoConfiguration(); if (videoConfig) { kisConfig.setExportConfiguration("ANIMATION_RENDERER", videoConfig); KisPropertiesConfigurationSP encoderConfig = dlgAnimationRenderer.getEncoderConfiguration(); if (encoderConfig) { kisConfig.setExportConfiguration("FFMPEG_CONFIG", encoderConfig); encoderConfig->setProperty("savedFilesMask", savedFilesMask); } - const QDir framesDir(sequenceConfig->getString("directory")); const QString fileName = videoConfig->getString("filename"); - QString resultFile = QFileInfo(fileName).isAbsolute() ? fileName : - framesDir.absoluteFilePath(fileName); + QString resultFile = fileName; + KIS_SAFE_ASSERT_RECOVER_NOOP(QFileInfo(resultFile).isAbsolute()) { const QFileInfo info(resultFile); QDir dir(info.absolutePath()); if (!dir.exists()) { dir.mkpath(info.absolutePath()); } KIS_SAFE_ASSERT_RECOVER_NOOP(dir.exists()); } QSharedPointer encoder = dlgAnimationRenderer.encoderFilter(); encoder->setMimeType(mimetype.toLatin1()); QFile fi(resultFile); KisImportExportFilter::ConversionStatus res; if (!fi.open(QIODevice::WriteOnly)) { qWarning() << "Could not open" << fi.fileName() << "for writing!"; res = KisImportExportFilter::CreationError; } else { encoder->setFilename(fi.fileName()); res = encoder->convert(doc, &fi, encoderConfig); fi.close(); } if (res != KisImportExportFilter::OK) { QMessageBox::critical(0, i18nc("@title:window", "Krita"), i18n("Could not render animation:\n%1", doc->errorMessage())); } if (videoConfig->getBool("delete_sequence", false)) { QDir d(sequenceConfig->getString("directory")); QStringList sequenceFiles = d.entryList(QStringList() << sequenceConfig->getString("basename") + "*." + extension, QDir::Files); Q_FOREACH(const QString &f, sequenceFiles) { d.remove(f); } } } } } doc->clearFileProgressUpdater(); doc->clearFileProgressProxy(); } void AnimaterionRenderer::slotRenderSequenceAgain() { KisImageWSP image = m_view->image(); if (!image) return; if (!image->animationInterface()->hasAnimation()) return; KisDocument *doc = m_view->document(); doc->setFileProgressProxy(); doc->setFileProgressUpdater(i18n("Export frames")); KisConfig kisConfig; KisPropertiesConfigurationSP cfg = new KisPropertiesConfiguration(); cfg->fromXML(kisConfig.exportConfiguration("IMAGESEQUENCE")); QString mimetype = cfg->getString("mimetype"); QString extension = KisMimeDatabase::suffixesForMimeType(mimetype).first(); QString baseFileName = QString("%1/%2.%3").arg(cfg->getString("directory")) .arg(cfg->getString("basename")) .arg(extension); KisAnimationExportSaver exporter(doc, baseFileName, cfg->getInt("first_frame"), cfg->getInt("last_frame"), cfg->getInt("sequence_start")); bool success = exporter.exportAnimation(); Q_ASSERT(success); doc->clearFileProgressUpdater(); doc->clearFileProgressProxy(); } #include "AnimationRenderer.moc" diff --git a/plugins/extensions/animationrenderer/DlgAnimationRenderer.cpp b/plugins/extensions/animationrenderer/DlgAnimationRenderer.cpp index 64cdd212a0..c1ac46fa3d 100644 --- a/plugins/extensions/animationrenderer/DlgAnimationRenderer.cpp +++ b/plugins/extensions/animationrenderer/DlgAnimationRenderer.cpp @@ -1,526 +1,541 @@ /* * Copyright (c) 2016 Boudewijn Rempt * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "DlgAnimationRenderer.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include DlgAnimationRenderer::DlgAnimationRenderer(KisDocument *doc, QWidget *parent) : KoDialog(parent) , m_image(doc->image()) , m_doc(doc) , m_defaultFileName(QFileInfo(doc->url().toLocalFile()).completeBaseName()) { KisConfig cfg; setCaption(i18n("Render Animation")); setButtons(Ok | Cancel); setDefaultButton(Ok); if (m_defaultFileName.isEmpty()) { m_defaultFileName = i18n("Untitled"); } m_page = new WdgAnimaterionRenderer(this); m_page->layout()->setMargin(0); m_page->dirRequester->setMode(KoFileDialog::OpenDirectory); QString lastLocation = cfg.readEntry("AnimationRenderer/last_sequence_export_location", QStandardPaths::writableLocation(QStandardPaths::PicturesLocation)); m_page->dirRequester->setFileName(lastLocation); m_page->intStart->setMinimum(doc->image()->animationInterface()->fullClipRange().start()); m_page->intStart->setMaximum(doc->image()->animationInterface()->fullClipRange().end()); m_page->intStart->setValue(doc->image()->animationInterface()->playbackRange().start()); m_page->intEnd->setMinimum(doc->image()->animationInterface()->fullClipRange().start()); m_page->intEnd->setMaximum(doc->image()->animationInterface()->fullClipRange().end()); m_page->intEnd->setValue(doc->image()->animationInterface()->playbackRange().end()); QFileInfo audioFileInfo(doc->image()->animationInterface()->audioChannelFileName()); const bool hasAudio = audioFileInfo.exists(); m_page->chkIncludeAudio->setEnabled(hasAudio); m_page->chkIncludeAudio->setChecked(hasAudio && !doc->image()->animationInterface()->isAudioMuted()); QStringList mimes = KisImportExportManager::mimeFilter(KisImportExportManager::Export); mimes.sort(); Q_FOREACH(const QString &mime, mimes) { QString description = KisMimeDatabase::descriptionForMimeType(mime); if (description.isEmpty()) { description = mime; } m_page->cmbMimetype->addItem(description, mime); if (mime == "image/png") { m_page->cmbMimetype->setCurrentIndex(m_page->cmbMimetype->count() - 1); } } setMainWidget(m_page); KoJsonTrader trader; QListlist = trader.query("Krita/AnimationExporter", ""); Q_FOREACH(QPluginLoader *loader, list) { QJsonObject json = loader->metaData().value("MetaData").toObject(); QStringList mimetypes = json.value("X-KDE-Export").toString().split(","); Q_FOREACH(const QString &mime, mimetypes) { KLibFactory *factory = qobject_cast(loader->instance()); if (!factory) { warnUI << loader->errorString(); continue; } QObject* obj = factory->create(0); if (!obj || !obj->inherits("KisImportExportFilter")) { delete obj; continue; } QSharedPointerfilter(static_cast(obj)); if (!filter) { delete obj; continue; } m_renderFilters.append(filter); QString description = KisMimeDatabase::descriptionForMimeType(mime); if (description.isEmpty()) { description = mime; } m_page->cmbRenderType->addItem(description, mime); } } m_page->videoFilename->setMode(KoFileDialog::SaveFile); m_page->videoFilename->setStartDir(QStandardPaths::writableLocation(QStandardPaths::PicturesLocation)); qDeleteAll(list); connect(m_page->bnExportOptions, SIGNAL(clicked()), this, SLOT(sequenceMimeTypeSelected())); connect(m_page->bnRenderOptions, SIGNAL(clicked()), this, SLOT(selectRenderOptions())); m_page->ffmpegLocation->setFileName(findFFMpeg()); m_page->ffmpegLocation->setMode(KoFileDialog::OpenFile); connect(m_page->ffmpegLocation, SIGNAL(fileSelected(QString)), this, SLOT(ffmpegLocationChanged(QString))); m_page->cmbRenderType->setCurrentIndex(cfg.readEntry("AnimationRenderer/render_type", 0)); connect(m_page->shouldExportOnlyImageSequence, SIGNAL(toggled(bool)), this, SLOT(slotExportTypeChanged())); connect(m_page->shouldExportOnlyVideo, SIGNAL(toggled(bool)), this, SLOT(slotExportTypeChanged())); connect(m_page->shouldExportAll, SIGNAL(toggled(bool)), this, SLOT(slotExportTypeChanged())); updateExportUIOptions(); // connect and cold init connect(m_page->cmbRenderType, SIGNAL(currentIndexChanged(int)), this, SLOT(selectRenderType(int))); selectRenderType(m_page->cmbRenderType->currentIndex()); resize(m_page->sizeHint()); } DlgAnimationRenderer::~DlgAnimationRenderer() { KisConfig cfg; cfg.writeEntry("AnimationRenderer/last_sequence_export_location", m_page->dirRequester->fileName()); cfg.writeEntry("AnimationRenderer/render_type", m_page->cmbRenderType->currentIndex()); cfg.setCustomFFMpegPath(m_page->ffmpegLocation->fileName()); if (m_encoderConfigWidget) { m_encoderConfigWidget->setParent(0); m_encoderConfigWidget->deleteLater(); } if (m_frameExportConfigWidget) { m_frameExportConfigWidget->setParent(0); m_frameExportConfigWidget->deleteLater(); } delete m_page; } QString DlgAnimationRenderer::fetchRenderingDirectory() const { QString result = m_page->dirRequester->fileName(); if (m_page->shouldExportOnlyVideo->isChecked()) { const QFileInfo info(fetchRenderingFileName()); if (info.isAbsolute()) { result = info.absolutePath(); } } return result; } QString DlgAnimationRenderer::fetchRenderingFileName() const { QString filename = m_page->videoFilename->fileName(); + if (QFileInfo(filename).completeSuffix().isEmpty()) { QString mimetype = m_page->cmbRenderType->itemData(m_page->cmbRenderType->currentIndex()).toString(); filename += "." + KisMimeDatabase::suffixesForMimeType(mimetype).first(); } + + if (QFileInfo(filename).isRelative()) { + QDir baseDir(m_page->dirRequester->fileName()); + + if (m_page->shouldExportOnlyVideo->isChecked()) { + QString documentDir = QFileInfo(m_doc->url().toLocalFile()).absolutePath(); + if (!documentDir.isEmpty()) { + baseDir = documentDir; + } + } + + filename = baseDir.absoluteFilePath(filename); + } + return filename; } KisPropertiesConfigurationSP DlgAnimationRenderer::getSequenceConfiguration() const { KisPropertiesConfigurationSP cfg = new KisPropertiesConfiguration(); cfg->setProperty("basename", m_page->txtBasename->text()); cfg->setProperty("last_document_path", m_doc->localFilePath()); cfg->setProperty("directory", fetchRenderingDirectory()); cfg->setProperty("first_frame", m_page->intStart->value()); cfg->setProperty("last_frame", m_page->intEnd->value()); cfg->setProperty("sequence_start", m_page->sequenceStart->value()); cfg->setProperty("mimetype", m_page->cmbMimetype->currentData().toString()); return cfg; } void DlgAnimationRenderer::setSequenceConfiguration(KisPropertiesConfigurationSP cfg) { m_page->txtBasename->setText(cfg->getString("basename", "frame")); if (cfg->getString("last_document_path") != m_doc->localFilePath()) { cfg->removeProperty("first_frame"); cfg->removeProperty("last_frame"); cfg->removeProperty("sequence_start"); } m_page->dirRequester->setFileName(cfg->getString("directory", QStandardPaths::writableLocation(QStandardPaths::PicturesLocation))); m_page->intStart->setValue(cfg->getInt("first_frame", m_image->animationInterface()->playbackRange().start())); m_page->intEnd->setValue(cfg->getInt("last_frame", m_image->animationInterface()->playbackRange().end())); m_page->sequenceStart->setValue(cfg->getInt("sequence_start", m_image->animationInterface()->playbackRange().start())); QString mimetype = cfg->getString("mimetype"); for (int i = 0; i < m_page->cmbMimetype->count(); ++i) { if (m_page->cmbMimetype->itemData(i).toString() == mimetype) { m_page->cmbMimetype->setCurrentIndex(i); break; } } } KisPropertiesConfigurationSP DlgAnimationRenderer::getFrameExportConfiguration() const { if (m_frameExportConfigWidget) { KisPropertiesConfigurationSP cfg = m_frameExportConfigWidget->configuration(); cfg->setProperty("basename", m_page->txtBasename->text()); cfg->setProperty("directory", fetchRenderingDirectory()); cfg->setProperty("first_frame", m_page->intStart->value()); cfg->setProperty("last_frame", m_page->intEnd->value()); cfg->setProperty("sequence_start", m_page->sequenceStart->value()); cfg->setProperty("ffmpeg_path", m_page->ffmpegLocation->fileName()); return m_frameExportConfigWidget->configuration(); } return 0; } KisPropertiesConfigurationSP DlgAnimationRenderer::getVideoConfiguration() const { // don't continue if we are only exporting image sequence if (m_page->shouldExportOnlyImageSequence->isChecked()) { return 0; } KisPropertiesConfigurationSP cfg = new KisPropertiesConfiguration(); cfg->setProperty("filename", fetchRenderingFileName()); cfg->setProperty("first_frame", m_page->intStart->value()); cfg->setProperty("last_frame", m_page->intEnd->value()); cfg->setProperty("sequence_start", m_page->sequenceStart->value()); // delete image sequence if we are only exporting out video cfg->setProperty("delete_sequence", m_page->shouldExportOnlyVideo->isChecked()); return cfg; } void DlgAnimationRenderer::setVideoConfiguration(KisPropertiesConfigurationSP /*cfg*/) { } KisPropertiesConfigurationSP DlgAnimationRenderer::getEncoderConfiguration() const { // don't continue if we are only exporting image sequence if (m_page->shouldExportOnlyImageSequence->isChecked()) { return 0; } KisPropertiesConfigurationSP cfg = new KisPropertiesConfiguration(); if (m_encoderConfigWidget) { cfg = m_encoderConfigWidget->configuration(); } cfg->setProperty("mimetype", m_page->cmbRenderType->currentData().toString()); cfg->setProperty("directory", fetchRenderingDirectory()); cfg->setProperty("first_frame", m_page->intStart->value()); cfg->setProperty("last_frame", m_page->intEnd->value()); cfg->setProperty("sequence_start", m_page->sequenceStart->value()); cfg->setProperty("include_audio", m_page->chkIncludeAudio->isChecked()); return cfg; } void DlgAnimationRenderer::setEncoderConfiguration(KisPropertiesConfigurationSP /*cfg*/) { } QSharedPointer DlgAnimationRenderer::encoderFilter() const { if (m_page->cmbRenderType->currentIndex() < m_renderFilters.size()) { return m_renderFilters[m_page->cmbRenderType->currentIndex()]; } return QSharedPointer(0); } void DlgAnimationRenderer::selectRenderType(int index) { if (index >= m_renderFilters.size()) return; QString mimetype = m_page->cmbRenderType->itemData(index).toString(); if (!m_page->videoFilename->fileName().isEmpty() && QFileInfo(m_page->videoFilename->fileName()).completeBaseName() != m_defaultFileName) { m_defaultFileName = QFileInfo(m_page->videoFilename->fileName()).completeBaseName(); } m_page->videoFilename->setMimeTypeFilters(QStringList() << mimetype, mimetype); m_page->videoFilename->setFileName(m_defaultFileName + "." + KisMimeDatabase::suffixesForMimeType(mimetype).first()); } void DlgAnimationRenderer::selectRenderOptions() { int index = m_page->cmbRenderType->currentIndex(); if (m_encoderConfigWidget) { m_encoderConfigWidget->deleteLater(); m_encoderConfigWidget = 0; } if (index >= m_renderFilters.size()) return; QSharedPointer filter = m_renderFilters[index]; QString mimetype = m_page->cmbRenderType->itemData(index).toString(); if (filter) { m_encoderConfigWidget = filter->createConfigurationWidget(0, KisDocument::nativeFormatMimeType(), mimetype.toLatin1()); if (m_encoderConfigWidget) { m_encoderConfigWidget->setConfiguration(filter->lastSavedConfiguration("", mimetype.toLatin1())); KoDialog dlg(this); dlg.setMainWidget(m_encoderConfigWidget); dlg.setButtons(KoDialog::Ok | KoDialog::Cancel); if (!dlg.exec()) { m_encoderConfigWidget->setConfiguration(filter->lastSavedConfiguration()); } dlg.setMainWidget(0); m_encoderConfigWidget->hide(); m_encoderConfigWidget->setParent(0); } } else { m_encoderConfigWidget = 0; } } void DlgAnimationRenderer::sequenceMimeTypeSelected() { int index = m_page->cmbMimetype->currentIndex(); if (m_frameExportConfigWidget) { m_frameExportConfigWidget->deleteLater(); m_frameExportConfigWidget = 0; } QString mimetype = m_page->cmbMimetype->itemData(index).toString(); QSharedPointer filter(KisImportExportManager::filterForMimeType(mimetype, KisImportExportManager::Export)); if (filter) { m_frameExportConfigWidget = filter->createConfigurationWidget(0, KisDocument::nativeFormatMimeType(), mimetype.toLatin1()); if (m_frameExportConfigWidget) { m_frameExportConfigWidget->setConfiguration(filter->lastSavedConfiguration("", mimetype.toLatin1())); KoDialog dlg(this); dlg.setMainWidget(m_frameExportConfigWidget); dlg.setButtons(KoDialog::Ok | KoDialog::Cancel); if (!dlg.exec()) { m_frameExportConfigWidget->setConfiguration(filter->lastSavedConfiguration()); } m_frameExportConfigWidget->hide(); m_frameExportConfigWidget->setParent(0); dlg.setMainWidget(0); } } } void DlgAnimationRenderer::ffmpegLocationChanged(const QString &s) { KisConfig cfg; cfg.setCustomFFMpegPath(s); } void DlgAnimationRenderer::updateExportUIOptions() { KisConfig cfg; // read in what type to export to. Defaults to image sequence only QString exportType = cfg.readEntry("AnimationRenderer/export_type", "ImageSequence"); if (exportType == "ImageSequence") { m_page->shouldExportOnlyImageSequence->setChecked(true); } else if (exportType == "Video") { m_page->shouldExportOnlyVideo->setChecked(true); } else { m_page->shouldExportAll->setChecked(true); // export to both } } void DlgAnimationRenderer::slotButtonClicked(int button) { if (button == KoDialog::Ok && !m_page->shouldExportOnlyImageSequence->isChecked()) { QString ffmpeg = m_page->ffmpegLocation->fileName(); if (m_page->videoFilename->fileName().isEmpty()) { QMessageBox::warning(this, i18nc("@title:window", "Krita"), i18n("Please enter a file name to render to.")); return; } else if (ffmpeg.isEmpty()) { QMessageBox::warning(this, i18nc("@title:window", "Krita"), i18n("The location of FFmpeg is unknown. Please install FFmpeg first: Krita cannot render animations without FFmpeg. (www.ffmpeg.org)")); return; } else { QFileInfo fi(ffmpeg); if (!fi.exists()) { QMessageBox::warning(this, i18nc("@title:window", "Krita"), i18n("The location of FFmpeg is invalid. Please select the correct location of the FFmpeg executable on your system.")); return; } } } KoDialog::slotButtonClicked(button); } QString DlgAnimationRenderer::findFFMpeg() { QString result; QStringList proposedPaths; QString customPath = KisConfig().customFFMpegPath(); proposedPaths << customPath; proposedPaths << customPath + QDir::separator() + "ffmpeg"; proposedPaths << QDir::homePath() + "/bin/ffmpeg"; proposedPaths << "/usr/bin/ffmpeg"; proposedPaths << "/usr/local/bin/ffmpeg"; proposedPaths << KoResourcePaths::getApplicationRoot() + QDir::separator() + "bin" + QDir::separator() + "ffmpeg"; Q_FOREACH (const QString &path, proposedPaths) { if (path.isEmpty()) continue; QProcess testProcess; testProcess.start(path, QStringList() << "-version"); testProcess.waitForFinished(1000); const bool successfulStart = testProcess.state() == QProcess::NotRunning && testProcess.error() == QProcess::UnknownError; if (successfulStart) { result = path; break; } } return result; } void DlgAnimationRenderer::slotExportTypeChanged() { KisConfig cfg; // if a video format needs to be outputted if (m_page->shouldExportAll->isChecked() || m_page->shouldExportOnlyVideo->isChecked()) { // videos always uses PNG for creating video, so disable the ability to change the format m_page->cmbMimetype->setEnabled(false); for (int i = 0; i < m_page->cmbMimetype->count(); ++i) { if (m_page->cmbMimetype->itemData(i).toString() == "image/png") { m_page->cmbMimetype->setCurrentIndex(i); break; } } } // if only exporting video if (m_page->shouldExportOnlyVideo->isChecked()) { m_page->cmbMimetype->setEnabled(false); // allow to change image format m_page->imageSequenceOptionsGroup->setVisible(false); m_page->videoOptionsGroup->setVisible(false); //shrinks the horizontal space temporarily to help resize() work m_page->videoOptionsGroup->setVisible(true); cfg.writeEntry("AnimationRenderer/export_type", "Video"); } // if only an image sequence needs to be output if (m_page->shouldExportOnlyImageSequence->isChecked()) { m_page->cmbMimetype->setEnabled(true); // allow to change image format m_page->videoOptionsGroup->setVisible(false); m_page->imageSequenceOptionsGroup->setVisible(true); cfg.writeEntry("AnimationRenderer/export_type", "ImageSequence"); } // show all options if (m_page->shouldExportAll->isChecked() ) { m_page->imageSequenceOptionsGroup->setVisible(true); m_page->videoOptionsGroup->setVisible(true); cfg.writeEntry("AnimationRenderer/export_type", "VideoAndImageSequence"); } // for the resize to work as expected, try to hide elements first before displaying other ones. // if the widget gets bigger at any point, the resize will use that, even if elements are hidden later to make it smaller resize(m_page->sizeHint()); }