From 69aa0490c80f47ca613c7e6129c8596a62a234e7 Mon Sep 17 00:00:00 2001 From: JackDemps Date: Tue, 7 Mar 2023 20:40:04 -0500 Subject: [PATCH 1/4] Image import errors --- app/src/importimageseqdialog.cpp | 2 +- app/src/mainwindow2.cpp | 11 ++---- core_lib/src/interface/editor.cpp | 64 +++++++++++++++++++++++-------- core_lib/src/interface/editor.h | 6 +-- 4 files changed, 56 insertions(+), 27 deletions(-) diff --git a/app/src/importimageseqdialog.cpp b/app/src/importimageseqdialog.cpp index 383bf0f46f..86bfab26ea 100644 --- a/app/src/importimageseqdialog.cpp +++ b/app/src/importimageseqdialog.cpp @@ -324,7 +324,7 @@ void ImportImageSeqDialog::importPredefinedSet() const QString& filePath = keySet.filePathAt(i); mEditor->scrubTo(frameIndex); - bool ok = mEditor->importImage(filePath); + bool ok = mEditor->importImage(filePath).ok(); imagesImportedSoFar++; progress.setValue(imagesImportedSoFar); diff --git a/app/src/mainwindow2.cpp b/app/src/mainwindow2.cpp index aef3fd73ae..70aad69dc4 100644 --- a/app/src/mainwindow2.cpp +++ b/app/src/mainwindow2.cpp @@ -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.
TIP: Use Bitmap layer to import bitmaps."), - QMessageBox::Ok, - QMessageBox::Ok); + ErrorDialog errorDialog(st.title(), st.description(), st.details().html()); + errorDialog.exec(); return; } diff --git a/core_lib/src/interface/editor.cpp b/core_lib/src/interface/editor.cpp index 2a9cc9d682..a5aafbf75e 100644 --- a/core_lib/src/interface/editor.cpp +++ b/core_lib/src/interface/editor.cpp @@ -914,17 +914,39 @@ 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(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; + dd << QString("QImageReader format: %1").arg(img.format()); + dd << QString("QImageReader ImageReaderError type: %1").arg(reader.errorString()); + + QString errorDesc; + switch(reader.error()) + { + case QImageReader::ImageReaderError::UnknownError: + errorDesc = QString("We ran into an error while reading this image. Please check if it is valid and try again."); + break; + + case QImageReader::ImageReaderError::FileNotFoundError: + errorDesc = QString("File not found at path \"%1\". Please check if image is present and try again.").arg(filePath); + break; + + default: + errorDesc = QString("An ImageReaderError occurred."); + } + + status = Status(Status::FAIL, dd, "Couldn't import image", errorDesc); } const QPoint pos(view()->getImportView().dx() - (img.width() / 2), @@ -958,15 +980,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(layers()->currentLayer()); + Status status = Status::OK; + DebugDetails dd; + dd << QString("Raw file path: %1").arg(filePath); + VectorImage* vectorImage = layer->getVectorImageAtFrame(currentFrame()); if (vectorImage == nullptr) { @@ -984,14 +1010,20 @@ bool Editor::importVectorImage(const QString& filePath) backup(tr("Import Image")); } + else { + status = Status(Status::FAIL, dd, "Couldn't import image", "Cannot import image into vector layer. Please select a different layer and try again."); + } - 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(layers()->getLastCameraLayer()); @@ -1001,17 +1033,17 @@ bool Editor::importImage(const QString& filePath) } switch (layer->type()) { - case Layer::BITMAP: - return importBitmapImage(filePath); + case Layer::BITMAP: + return importBitmapImage(filePath); - case Layer::VECTOR: - return importVectorImage(filePath); + case Layer::VECTOR: + return importVectorImage(filePath); - default: - { - //mLastError = Status::ERROR_INVALID_LAYER_TYPE; - return false; - } + default: + { + dd << QString("Current layer: %1").arg(layer->type()); + return Status(Status::ERROR_INVALID_LAYER_TYPE, dd, "Couldn't import image.", "Invalid layer type."); + } } } @@ -1020,7 +1052,7 @@ bool Editor::importGIF(const QString& filePath, int numOfImages) Layer* layer = layers()->currentLayer(); if (layer->type() == Layer::BITMAP) { - return importBitmapImage(filePath, numOfImages); + return importBitmapImage(filePath, numOfImages).ok(); } return false; } diff --git a/core_lib/src/interface/editor.h b/core_lib/src/interface/editor.h index 2b517bdfb4..44476eedbb 100644 --- a/core_lib/src/interface/editor.h +++ b/core_lib/src/interface/editor.h @@ -167,7 +167,7 @@ class Editor : public QObject void clearCurrentFrame(); - bool importImage(const QString& filePath); + Status importImage(const QString& filePath); bool importGIF(const QString& filePath, int numOfImages = 0); void restoreKey(); @@ -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); From f3011d5765ca1adf2e500b6ffe10b2676729b0f0 Mon Sep 17 00:00:00 2001 From: scribblemaniac Date: Mon, 27 Mar 2023 02:31:04 -0600 Subject: [PATCH 2/4] Further improve image import error handling --- app/src/importimageseqdialog.cpp | 54 +++++++++++------------------ app/src/mainwindow2.cpp | 32 +++++++++--------- core_lib/src/interface/editor.cpp | 56 +++++++++++++++++-------------- core_lib/src/interface/editor.h | 2 +- 4 files changed, 65 insertions(+), 79 deletions(-) diff --git a/app/src/importimageseqdialog.cpp b/app/src/importimageseqdialog.cpp index 86bfab26ea..a4ac70378b 100644 --- a/app/src/importimageseqdialog.cpp +++ b/app/src/importimageseqdialog.cpp @@ -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" @@ -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++) @@ -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(); @@ -324,7 +304,13 @@ void ImportImageSeqDialog::importPredefinedSet() const QString& filePath = keySet.filePathAt(i); mEditor->scrubTo(frameIndex); - bool ok = mEditor->importImage(filePath).ok(); + Status st = mEditor->importImage(filePath); + if (!st.ok()) + { + ErrorDialog errorDialog(st.title(), st.description(), st.details().html()); + errorDialog.exec(); + break; + } imagesImportedSoFar++; progress.setValue(imagesImportedSoFar); @@ -334,8 +320,6 @@ void ImportImageSeqDialog::importPredefinedSet() { break; } - - if (!ok) { return;} } emit notifyAnimationLengthChanged(); diff --git a/app/src/mainwindow2.cpp b/app/src/mainwindow2.cpp index 70aad69dc4..3a812da68c 100644 --- a/app/src/mainwindow2.cpp +++ b/app/src/mainwindow2.cpp @@ -976,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("Couldn't import image."), tr("Invalid image type. You can only use import files ending with .gif as Animated GIFs.")); + 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; } diff --git a/core_lib/src/interface/editor.cpp b/core_lib/src/interface/editor.cpp index a5aafbf75e..4eb4053611 100644 --- a/core_lib/src/interface/editor.cpp +++ b/core_lib/src/interface/editor.cpp @@ -928,25 +928,28 @@ Status Editor::importBitmapImage(const QString& filePath, int space) QImage img(reader.size(), QImage::Format_ARGB32_Premultiplied); if (img.isNull()) { - dd << QString("QImageReader format: %1").arg(img.format()); + 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::UnknownError: - errorDesc = QString("We ran into an error while reading this image. Please check if it is valid and try again."); - break; - - case QImageReader::ImageReaderError::FileNotFoundError: - errorDesc = QString("File not found at path \"%1\". Please check if image is present and try again.").arg(filePath); - break; - - default: - errorDesc = QString("An ImageReaderError occurred."); + case QImageReader::ImageReaderError::FileNotFoundError: + errorDesc = tr("File not found at path \"%1\". Please check if image is present and try again.").arg(filePath); + break; + case QImageReader::UnsupportedFormatError: + errorDesc = tr("This image format is not supported. Please try converting it to one of the following formats and try again:\n%1") + .arg((QString)reader.supportedImageFormats().join(", ")); + break; + default: + errorDesc = tr("We ran into an error while reading this image. Please check if it is valid and try again."); } - status = Status(Status::FAIL, dd, "Couldn't import image", errorDesc); + status = Status(Status::FAIL, dd, tr("Couldn't import image"), errorDesc); } const QPoint pos(view()->getImportView().dx() - (img.width() / 2), @@ -1011,7 +1014,7 @@ Status Editor::importVectorImage(const QString& filePath) backup(tr("Import Image")); } else { - status = Status(Status::FAIL, dd, "Couldn't import image", "Cannot import image into vector layer. Please select a different layer and try again."); + status = Status(Status::FAIL, dd, tr("Couldn't import image"), tr("Cannot import image into vector layer. Please select a different layer and try again.")); } return status; @@ -1033,28 +1036,29 @@ Status Editor::importImage(const QString& filePath) } switch (layer->type()) { - case Layer::BITMAP: - return importBitmapImage(filePath); + case Layer::BITMAP: + return importBitmapImage(filePath); - case Layer::VECTOR: - return importVectorImage(filePath); + case Layer::VECTOR: + return importVectorImage(filePath); - default: - { - dd << QString("Current layer: %1").arg(layer->type()); - return Status(Status::ERROR_INVALID_LAYER_TYPE, dd, "Couldn't import image.", "Invalid layer type."); - } + default: + dd << QString("Current layer: %1").arg(layer->type()); + return Status(Status::ERROR_INVALID_LAYER_TYPE, dd, tr("Couldn't import image."), tr("Invalid layer type. 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).ok(); + 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("Couldn't import image."), tr("Invalid layer type. You can only import images to a bitmap layer.")); } - return false; + return importBitmapImage(filePath, numOfImages); } void Editor::selectAll() const diff --git a/core_lib/src/interface/editor.h b/core_lib/src/interface/editor.h index 44476eedbb..e2700bf4a1 100644 --- a/core_lib/src/interface/editor.h +++ b/core_lib/src/interface/editor.h @@ -168,7 +168,7 @@ class Editor : public QObject void clearCurrentFrame(); Status importImage(const QString& filePath); - bool importGIF(const QString& filePath, int numOfImages = 0); + Status importGIF(const QString& filePath, int numOfImages = 0); void restoreKey(); void scrubNextKeyFrame(); From 6797d1371b8254210f0c01817c21f471f3a4e341 Mon Sep 17 00:00:00 2001 From: anpanring Date: Sat, 1 Apr 2023 13:43:19 -0400 Subject: [PATCH 3/4] Revising error messages --- app/src/mainwindow2.cpp | 2 +- core_lib/src/interface/editor.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/mainwindow2.cpp b/app/src/mainwindow2.cpp index 3a812da68c..bbe92fea03 100644 --- a/app/src/mainwindow2.cpp +++ b/app/src/mainwindow2.cpp @@ -978,7 +978,7 @@ void MainWindow2::importGIF() QString strImgFileLower = gifDialog->getFilePath(); if (!strImgFileLower.toLower().endsWith(".gif")) { - ErrorDialog errorDialog(tr("Couldn't import image."), tr("Invalid image type. You can only use import files ending with .gif as Animated GIFs.")); + ErrorDialog errorDialog(tr("Import failed"), tr("You can only import files ending with .gif.")); errorDialog.exec(); } else diff --git a/core_lib/src/interface/editor.cpp b/core_lib/src/interface/editor.cpp index 4eb4053611..45c7964593 100644 --- a/core_lib/src/interface/editor.cpp +++ b/core_lib/src/interface/editor.cpp @@ -949,7 +949,7 @@ Status Editor::importBitmapImage(const QString& filePath, int space) errorDesc = tr("We ran into an error while reading this image. Please check if it is valid and try again."); } - status = Status(Status::FAIL, dd, tr("Couldn't import image"), errorDesc); + status = Status(Status::FAIL, dd, tr("Import failed"), errorDesc); } const QPoint pos(view()->getImportView().dx() - (img.width() / 2), @@ -1014,7 +1014,7 @@ Status Editor::importVectorImage(const QString& filePath) backup(tr("Import Image")); } else { - status = Status(Status::FAIL, dd, tr("Couldn't import image"), tr("Cannot import image into vector layer. Please select a different layer and try again.")); + status = Status(Status::FAIL, dd, tr("Import failed"), tr("You cannot import images into a vector layer.")); } return status; @@ -1044,7 +1044,7 @@ Status Editor::importImage(const QString& filePath) default: dd << QString("Current layer: %1").arg(layer->type()); - return Status(Status::ERROR_INVALID_LAYER_TYPE, dd, tr("Couldn't import image."), tr("Invalid layer type. You can only import images to a bitmap layer.")); + return Status(Status::ERROR_INVALID_LAYER_TYPE, dd, tr("Import failed"), tr("You can only import images to a bitmap layer.")); } } @@ -1056,7 +1056,7 @@ Status Editor::importGIF(const QString& filePath, int 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("Couldn't import image."), tr("Invalid layer type. You can only import images to a bitmap layer.")); + return Status(Status::ERROR_INVALID_LAYER_TYPE, dd, tr("Import failed"), tr("You can only import images to a bitmap layer.")); } return importBitmapImage(filePath, numOfImages); } From 6d9d84b398b54f6b0f95fb95a46402b10da7668b Mon Sep 17 00:00:00 2001 From: anpanring Date: Thu, 6 Apr 2023 11:33:50 -0400 Subject: [PATCH 4/4] Image import error message fixes --- core_lib/src/interface/editor.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core_lib/src/interface/editor.cpp b/core_lib/src/interface/editor.cpp index 45c7964593..b6d3d44bfc 100644 --- a/core_lib/src/interface/editor.cpp +++ b/core_lib/src/interface/editor.cpp @@ -939,14 +939,14 @@ Status Editor::importBitmapImage(const QString& filePath, int space) switch(reader.error()) { case QImageReader::ImageReaderError::FileNotFoundError: - errorDesc = tr("File not found at path \"%1\". Please check if image is present and try again.").arg(filePath); + 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("This image format is not supported. Please try converting it to one of the following formats and try again:\n%1") + 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("We ran into an error while reading this image. Please check if it is valid and try again."); + 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);