Skip to content

Commit

Permalink
More detailed error reporting for image import failure (pencil2d#1750)
Browse files Browse the repository at this point in the history
* Image import errors

* Further improve image import error handling

* Revising error messages

* Image import error message fixes

---------

Co-authored-by: scribblemaniac <scribblemaniac@users.noreply.github.com>
  • Loading branch information
anpanring and scribblemaniac authored Apr 6, 2023
1 parent 37918ac commit 91c50ff
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 77 deletions.
54 changes: 19 additions & 35 deletions app/src/importimageseqdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ GNU General Public License for more details.
#include "app_util.h"

#include "editor.h"
#include "errordialog.h"
#include "predefinedsetmodel.h"
#include "layermanager.h"
#include "viewmanager.h"
Expand Down Expand Up @@ -178,37 +179,25 @@ void ImportImageSeqDialog::importArbitrarySequence()
int imagesImportedSoFar = 0;
progress.setMaximum(totalImagesToImport);

QString failedFiles;
bool failedImport = false;
for (const QString& strImgFile : files)
{
QString strImgFileLower = strImgFile.toLower();

if (strImgFileLower.endsWith(".png") ||
strImgFileLower.endsWith(".jpg") ||
strImgFileLower.endsWith(".jpeg") ||
strImgFileLower.endsWith(".bmp") ||
strImgFileLower.endsWith(".tif") ||
strImgFileLower.endsWith(".tiff"))
Status st = mEditor->importImage(strImgFile);
if (!st.ok())
{
mEditor->importImage(strImgFile);
ErrorDialog errorDialog(st.title(), st.description(), st.details().html());
errorDialog.exec();
break;
}

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

if (progress.wasCanceled())
{
break;
}
}
else
if (progress.wasCanceled())
{
failedFiles += strImgFile + "\n";
if (!failedImport)
{
failedImport = true;
}
break;
}

for (int i = 1; i < number; i++)
Expand All @@ -217,15 +206,6 @@ void ImportImageSeqDialog::importArbitrarySequence()
}
}

if (failedImport)
{
QMessageBox::warning(mParent,
tr("Warning"),
tr("Unable to import") + failedFiles,
QMessageBox::Ok,
QMessageBox::Ok);
}


emit notifyAnimationLengthChanged();
progress.close();
Expand Down Expand Up @@ -324,7 +304,13 @@ void ImportImageSeqDialog::importPredefinedSet()
const QString& filePath = keySet.filePathAt(i);

mEditor->scrubTo(frameIndex);
bool ok = mEditor->importImage(filePath);
Status st = mEditor->importImage(filePath);
if (!st.ok())
{
ErrorDialog errorDialog(st.title(), st.description(), st.details().html());
errorDialog.exec();
break;
}
imagesImportedSoFar++;

progress.setValue(imagesImportedSoFar);
Expand All @@ -334,8 +320,6 @@ void ImportImageSeqDialog::importPredefinedSet()
{
break;
}

if (!ok) { return;}
}

emit notifyAnimationLengthChanged();
Expand Down
43 changes: 19 additions & 24 deletions app/src/mainwindow2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -868,14 +868,11 @@ void MainWindow2::importImage()
return;
}

bool ok = mEditor->importImage(strFilePath);
if (!ok)
Status st = mEditor->importImage(strFilePath);
if (!st.ok())
{
QMessageBox::warning(this,
tr("Warning"),
tr("Unable to import image.<br><b>TIP:</b> Use Bitmap layer to import bitmaps."),
QMessageBox::Ok,
QMessageBox::Ok);
ErrorDialog errorDialog(st.title(), st.description(), st.details().html());
errorDialog.exec();
return;
}

Expand Down Expand Up @@ -979,29 +976,27 @@ void MainWindow2::importGIF()
progress.show();

QString strImgFileLower = gifDialog->getFilePath();
bool importOK = strImgFileLower.toLower().endsWith(".gif");

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

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

if (!importOK)
{
QMessageBox::warning(this,
tr("Warning"),
tr("was unable to import %1").arg(strImgFileLower),
QMessageBox::Ok,
QMessageBox::Ok);
}
progress.setValue(100);
progress.close();

progress.setValue(100);
progress.close();
if (!st.ok())
{
ErrorDialog errorDialog(st.title(), st.description(), st.details().html());
errorDialog.exec();
}
}

mSuppressAutoSaveDialog = false;
}
Expand Down
64 changes: 50 additions & 14 deletions core_lib/src/interface/editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -914,17 +914,42 @@ void Editor::updateObject()
emit updateLayerCount();
}

bool Editor::importBitmapImage(const QString& filePath, int space)
Status Editor::importBitmapImage(const QString& filePath, int space)
{
QImageReader reader(filePath);

Q_ASSERT(layers()->currentLayer()->type() == Layer::BITMAP);
auto layer = static_cast<LayerBitmap*>(layers()->currentLayer());

Status status = Status::OK;
DebugDetails dd;
dd << QString("Raw file path: %1").arg(filePath);

QImage img(reader.size(), QImage::Format_ARGB32_Premultiplied);
if (img.isNull())
{
return false;
QString format = reader.format();
if (!format.isEmpty())
{
dd << QString("QImageReader format: %1").arg(format);
}
dd << QString("QImageReader ImageReaderError type: %1").arg(reader.errorString());

QString errorDesc;
switch(reader.error())
{
case QImageReader::ImageReaderError::FileNotFoundError:
errorDesc = tr("File not found at path \"%1\". Please check the image is present at the specified location and try again.").arg(filePath);
break;
case QImageReader::UnsupportedFormatError:
errorDesc = tr("Image format is not supported. Please convert the image file to one of the following formats and try again:\n%1")
.arg((QString)reader.supportedImageFormats().join(", "));
break;
default:
errorDesc = tr("An error has occurred while reading the image. Please check that the file is a valid image and try again.");
}

status = Status(Status::FAIL, dd, tr("Import failed"), errorDesc);
}

const QPoint pos(view()->getImportView().dx() - (img.width() / 2),
Expand Down Expand Up @@ -958,15 +983,19 @@ bool Editor::importBitmapImage(const QString& filePath, int space)
}
}

return true;
return status;
}

bool Editor::importVectorImage(const QString& filePath)
Status Editor::importVectorImage(const QString& filePath)
{
Q_ASSERT(layers()->currentLayer()->type() == Layer::VECTOR);

auto layer = static_cast<LayerVector*>(layers()->currentLayer());

Status status = Status::OK;
DebugDetails dd;
dd << QString("Raw file path: %1").arg(filePath);

VectorImage* vectorImage = layer->getVectorImageAtFrame(currentFrame());
if (vectorImage == nullptr)
{
Expand All @@ -984,14 +1013,20 @@ bool Editor::importVectorImage(const QString& filePath)

backup(tr("Import Image"));
}
else {
status = Status(Status::FAIL, dd, tr("Import failed"), tr("You cannot import images into a vector layer."));
}

return ok;
return status;
}

bool Editor::importImage(const QString& filePath)
Status Editor::importImage(const QString& filePath)
{
Layer* layer = layers()->currentLayer();

DebugDetails dd;
dd << QString("Raw file path: %1").arg(filePath);

if (view()->getImportFollowsCamera())
{
LayerCamera* camera = static_cast<LayerCamera*>(layers()->getLastCameraLayer());
Expand All @@ -1008,21 +1043,22 @@ bool Editor::importImage(const QString& filePath)
return importVectorImage(filePath);

default:
{
//mLastError = Status::ERROR_INVALID_LAYER_TYPE;
return false;
}
dd << QString("Current layer: %1").arg(layer->type());
return Status(Status::ERROR_INVALID_LAYER_TYPE, dd, tr("Import failed"), tr("You can only import images to a bitmap layer."));
}
}

bool Editor::importGIF(const QString& filePath, int numOfImages)
Status Editor::importGIF(const QString& filePath, int numOfImages)
{
Layer* layer = layers()->currentLayer();
if (layer->type() == Layer::BITMAP)
if (layer->type() != Layer::BITMAP)
{
return importBitmapImage(filePath, numOfImages);
DebugDetails dd;
dd << QString("Raw file path: %1").arg(filePath);
dd << QString("Current layer: %1").arg(layer->type());
return Status(Status::ERROR_INVALID_LAYER_TYPE, dd, tr("Import failed"), tr("You can only import images to a bitmap layer."));
}
return false;
return importBitmapImage(filePath, numOfImages);
}

void Editor::selectAll() const
Expand Down
8 changes: 4 additions & 4 deletions core_lib/src/interface/editor.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,8 @@ class Editor : public QObject

void clearCurrentFrame();

bool importImage(const QString& filePath);
bool importGIF(const QString& filePath, int numOfImages = 0);
Status importImage(const QString& filePath);
Status importGIF(const QString& filePath, int numOfImages = 0);
void restoreKey();

void scrubNextKeyFrame();
Expand Down Expand Up @@ -224,8 +224,8 @@ class Editor : public QObject
void resetAutoSaveCounter();

private:
bool importBitmapImage(const QString&, int space = 0);
bool importVectorImage(const QString&);
Status importBitmapImage(const QString&, int space = 0);
Status importVectorImage(const QString&);

void pasteToCanvas(BitmapImage* bitmapImage, int frameNumber);
void pasteToCanvas(VectorImage* vectorImage, int frameNumber);
Expand Down

0 comments on commit 91c50ff

Please sign in to comment.