Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve support for animated image importing #1801

Merged
merged 7 commits into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 48 additions & 1 deletion app/src/actioncommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ GNU General Public License for more details.
#include "soundclip.h"
#include "camera.h"

#include "importimageseqdialog.h"
#include "importpositiondialog.h"
#include "movieimporter.h"
#include "movieexporter.h"
#include "filedialog.h"
Expand All @@ -65,6 +67,50 @@ ActionCommands::ActionCommands(QWidget* parent) : QObject(parent)

ActionCommands::~ActionCommands() {}

Status ActionCommands::importAnimatedImage()
{
ImportImageSeqDialog fileDialog(mParent, ImportExportDialog::Import, FileType::ANIMATED_IMAGE);
fileDialog.exec();
if (fileDialog.result() != QDialog::Accepted)
{
return Status::CANCELED;
}
int frameSpacing = fileDialog.getSpace();
QString strImgFileLower = fileDialog.getFilePath();

ImportPositionDialog positionDialog(mEditor, mParent);
positionDialog.exec();
if (positionDialog.result() != QDialog::Accepted)
{
return Status::CANCELED;
}

// Show a progress dialog, as this could take a while if the gif is huge
QProgressDialog progressDialog(tr("Importing Animated Image..."), tr("Abort"), 0, 100, mParent);
hideQuestionMark(progressDialog);
progressDialog.setWindowModality(Qt::WindowModal);
progressDialog.show();

Status st = mEditor->importAnimatedImage(strImgFileLower, frameSpacing, [&progressDialog](int prog) {
progressDialog.setValue(prog);
QApplication::processEvents();
}, [&progressDialog]() {
return progressDialog.wasCanceled();
});

progressDialog.setValue(100);
progressDialog.close();

if (!st.ok())
{
ErrorDialog errorDialog(st.title(), st.description(), st.details().html());
errorDialog.exec();
return Status::SAFE;
}

return Status::OK;
}

Status ActionCommands::importMovieVideo()
{
QString filePath = FileDialog::getOpenFileName(mParent, FileType::MOVIE);
Expand Down Expand Up @@ -106,6 +152,7 @@ Status ActionCommands::importMovieVideo()
{
ErrorDialog errorDialog(st.title(), st.description(), st.details().html(), mParent);
errorDialog.exec();
return Status::SAFE;
}

mEditor->layers()->notifyAnimationLengthChanged();
Expand Down Expand Up @@ -293,7 +340,7 @@ Status ActionCommands::exportMovie(bool isGif)
desc.loop = dialog->getLoop();
desc.alpha = dialog->getTransparency();

DoubleProgressDialog progressDlg;
DoubleProgressDialog progressDlg(mParent);
progressDlg.setWindowModality(Qt::WindowModal);
progressDlg.setWindowTitle(tr("Exporting movie"));
Qt::WindowFlags eFlags = Qt::Dialog | Qt::WindowTitleHint;
Expand Down
1 change: 1 addition & 0 deletions app/src/actioncommands.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class ActionCommands : public QObject
void setCore(Editor* e) { mEditor = e; }

// file
Status importAnimatedImage();
Status importMovieVideo();
Status importSound(FileType type);
Status exportMovie(bool isGif = false);
Expand Down
4 changes: 2 additions & 2 deletions app/src/doubleprogressdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ GNU General Public License for more details.
#include <QtMath>

DoubleProgressDialog::DoubleProgressDialog(QWidget *parent) :
QDialog(parent),
QProgressDialog(parent),
ui(new Ui::DoubleProgressDialog)
{
ui->setupUi(this);

major = new ProgressBarControl(ui->majorProgressBar);
minor = new ProgressBarControl(ui->minorProgressBar);

connect(ui->cancelButton, &QPushButton::pressed, this, &DoubleProgressDialog::canceled);
setCancelButton(ui->cancelButton);
}

DoubleProgressDialog::~DoubleProgressDialog()
Expand Down
7 changes: 2 additions & 5 deletions app/src/doubleprogressdialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ GNU General Public License for more details.
#ifndef DOUBLEPROGRESSDIALOG_H
#define DOUBLEPROGRESSDIALOG_H

#include <QDialog>
#include <QProgressDialog>
#include <QProgressBar>

namespace Ui {
class DoubleProgressDialog;
}

class DoubleProgressDialog : public QDialog
class DoubleProgressDialog : public QProgressDialog
{
Q_OBJECT

Expand Down Expand Up @@ -63,9 +63,6 @@ class DoubleProgressDialog : public QDialog

ProgressBarControl *major, *minor;

signals:
void canceled();

private:
Ui::DoubleProgressDialog *ui;
};
Expand Down
6 changes: 6 additions & 0 deletions app/src/filedialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ QString FileDialog::getDefaultExtensionByFileType(const FileType fileType)
case FileType::IMAGE: return PFF_DEFAULT_IMAGE_EXT;
case FileType::IMAGE_SEQUENCE: return PFF_DEFAULT_IMAGE_SEQ_EXT;
case FileType::GIF: return PFF_DEFAULT_ANIMATED_EXT;
case FileType::ANIMATED_IMAGE: return PFF_DEFAULT_ANIMATED_EXT;
case FileType::PALETTE: return PFF_DEFAULT_PALETTE_EXT;
case FileType::MOVIE: return PFF_DEFAULT_MOVIE_EXT;
case FileType::SOUND: return PFF_DEFAULT_SOUND_EXT;
Expand Down Expand Up @@ -167,6 +168,7 @@ QString FileDialog::openDialogCaption(FileType fileType)
case FileType::IMAGE: return tr("Import image");
case FileType::IMAGE_SEQUENCE: return tr("Import image sequence");
case FileType::GIF: return tr("Import Animated GIF");
case FileType::ANIMATED_IMAGE: return tr("Import animated image");
case FileType::MOVIE: return tr("Import movie");
case FileType::SOUND: return tr("Import sound");
case FileType::PALETTE: return tr("Open palette");
Expand All @@ -182,6 +184,7 @@ QString FileDialog::saveDialogCaption(FileType fileType)
case FileType::IMAGE: return tr("Export image");
case FileType::IMAGE_SEQUENCE: return tr("Export image sequence");
case FileType::GIF: return tr("Export Animated GIF");
case FileType::ANIMATED_IMAGE: return tr("Export animated image");
case FileType::MOVIE: return tr("Export movie");
case FileType::SOUND: return tr("Export sound");
case FileType::PALETTE: return tr("Export palette");
Expand All @@ -197,6 +200,7 @@ QString FileDialog::openFileFilters(FileType fileType)
case FileType::IMAGE: return PFF_IMAGE_FILTER;
case FileType::IMAGE_SEQUENCE: return PFF_IMAGE_SEQ_FILTER;
case FileType::GIF: return PFF_GIF_EXT_FILTER;
case FileType::ANIMATED_IMAGE: return PFF_ANIMATED_IMAGE_EXT_FILTER;
case FileType::MOVIE: return PFF_MOVIE_EXT;
case FileType::SOUND: return PFF_SOUND_EXT_FILTER;
case FileType::PALETTE: return PFF_PALETTE_EXT_FILTER;
Expand All @@ -212,6 +216,7 @@ QString FileDialog::saveFileFilters(FileType fileType)
case FileType::IMAGE: return "";
case FileType::IMAGE_SEQUENCE: return "";
case FileType::GIF: return QString("%1 (*.gif)").arg(tr("Animated GIF"));
case FileType::ANIMATED_IMAGE: return "";
case FileType::MOVIE: return "MP4 (*.mp4);; AVI (*.avi);; WebM (*.webm);; APNG (*.apng)";
case FileType::SOUND: return "";
case FileType::PALETTE: return PFF_PALETTE_EXT_FILTER;
Expand Down Expand Up @@ -286,6 +291,7 @@ QString FileDialog::toSettingKey(FileType fileType)
case FileType::IMAGE: return "Image";
case FileType::IMAGE_SEQUENCE: return "ImageSequence";
case FileType::GIF: return "Animated GIF";
case FileType::ANIMATED_IMAGE: return "Animated Image";
case FileType::MOVIE: return "Movie";
case FileType::SOUND: return "Sound";
case FileType::PALETTE: return "Palette";
Expand Down
10 changes: 8 additions & 2 deletions app/src/importimageseqdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,16 @@ void ImportImageSeqDialog::setupLayout()

hideInstructionsLabel(true);

if (mFileType == FileType::GIF) {
switch (mFileType)
{
case FileType::GIF:
setWindowTitle(tr("Import Animated GIF"));
} else {
break;
case FileType::IMAGE_SEQUENCE:
setWindowTitle(tr("Import image sequence"));
break;
default:
setWindowTitle(tr("Import animated image"));
}

connect(uiOptionsBox->spaceSpinBox, static_cast<void(QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &ImportImageSeqDialog::setSpace);
Expand Down
51 changes: 3 additions & 48 deletions app/src/mainwindow2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ void MainWindow2::createMenus()
connect(ui->actionImport_ImageSeqNum, &QAction::triggered, this, &MainWindow2::importPredefinedImageSet);
connect(ui->actionImportLayers_from_pclx, &QAction::triggered, this, &MainWindow2::importLayers);
connect(ui->actionImport_MovieVideo, &QAction::triggered, this, &MainWindow2::importMovieVideo);
connect(ui->actionImport_Gif, &QAction::triggered, this, &MainWindow2::importGIF);
connect(ui->actionImport_AnimatedImage, &QAction::triggered, this, &MainWindow2::importAnimatedImage);

connect(ui->actionImport_Sound, &QAction::triggered, [=] { mCommands->importSound(FileType::SOUND); });
connect(ui->actionImport_MovieAudio, &QAction::triggered, [=] { mCommands->importSound(FileType::MOVIE); });
Expand Down Expand Up @@ -949,57 +949,12 @@ void MainWindow2::importLayers()
importLayers->open();
}

void MainWindow2::importGIF()
void MainWindow2::importAnimatedImage()
{
auto gifDialog = new ImportImageSeqDialog(this, ImportExportDialog::Import, FileType::GIF);
gifDialog->exec();
if (gifDialog->result() == QDialog::Rejected)
{
return;
}

// Flag this so we don't prompt the user about auto-save in the middle of the import.
mSuppressAutoSaveDialog = true;

ImportPositionDialog* positionDialog = new ImportPositionDialog(mEditor, this);
OnScopeExit(delete positionDialog)

positionDialog->exec();
if (positionDialog->result() != QDialog::Accepted)
{
return;
}

int space = gifDialog->getSpace();

// Show a progress dialog, as this could take a while if the gif is huge
QProgressDialog progress(tr("Importing Animated GIF..."), tr("Abort"), 0, 100, this);
hideQuestionMark(progress);
progress.setWindowModality(Qt::WindowModal);
progress.show();

QString strImgFileLower = gifDialog->getFilePath();
if (!strImgFileLower.toLower().endsWith(".gif"))
{
ErrorDialog errorDialog(tr("Import failed"), tr("You can only import files ending with .gif."));
errorDialog.exec();
}
else
{
Status st = mEditor->importGIF(strImgFileLower, space);

progress.setValue(50);
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents); // Required to make progress bar update

progress.setValue(100);
progress.close();

if (!st.ok())
{
ErrorDialog errorDialog(st.title(), st.description(), st.details().html());
errorDialog.exec();
}
}
mCommands->importAnimatedImage();

mSuppressAutoSaveDialog = false;
}
Expand Down
2 changes: 1 addition & 1 deletion app/src/mainwindow2.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public slots:
void importPredefinedImageSet();
void importLayers();
void importMovieVideo();
void importGIF();
void importAnimatedImage();

void lockWidgets(bool shouldLock);

Expand Down
5 changes: 5 additions & 0 deletions app/ui/exportimageoptions.ui
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@
<string>TIFF</string>
</property>
</item>
<item>
<property name="text">
<string>WEBP</string>
</property>
</item>
</widget>
</item>
<item>
Expand Down
6 changes: 3 additions & 3 deletions app/ui/mainwindow2.ui
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
<addaction name="actionImport_ImageSeq"/>
<addaction name="actionImport_ImageSeqNum"/>
<addaction name="actionImport_MovieVideo"/>
<addaction name="actionImport_Gif"/>
<addaction name="actionImport_AnimatedImage"/>
<addaction name="actionImportLayers_from_pclx"/>
<addaction name="separator"/>
<addaction name="actionImport_Sound"/>
Expand Down Expand Up @@ -912,9 +912,9 @@
<string>F1</string>
</property>
</action>
<action name="actionImport_Gif">
<action name="actionImport_AnimatedImage">
<property name="text">
<string>Animated GIF...</string>
<string>Animated Image...</string>
</property>
</action>
<action name="actionExport_Animated_GIF">
Expand Down
Loading