diff --git a/src/KSaneImageSaver.h b/src/KSaneImageSaver.h --- a/src/KSaneImageSaver.h +++ b/src/KSaneImageSaver.h @@ -34,19 +34,13 @@ { Q_OBJECT public: - explicit KSaneImageSaver(QObject *parent = 0); + explicit KSaneImageSaver(QObject *parent = nullptr); ~KSaneImageSaver(); - bool savePng(const QString &name, const QByteArray &data, int width, int height, int format, int dpi); - - bool savePngSync(const QString &name, const QByteArray &data, int width, int height, int format, int dpi); - - bool saveTiff(const QString &name, const QByteArray &data, int width, int height, int format); - - bool saveTiffSync(const QString &name, const QByteArray &data, int width, int height, int format); + bool saveQImage(const QUrl &url, const QString &name, const QByteArray &data, int width, int height, int bpl, int dpi, int format, const QString& fileFormat, int quality); Q_SIGNALS: - void imageSaved(bool success); + void imageSaved(const QUrl &url, const QString &name, bool success); protected: void run() Q_DECL_OVERRIDE; diff --git a/src/KSaneImageSaver.cpp b/src/KSaneImageSaver.cpp --- a/src/KSaneImageSaver.cpp +++ b/src/KSaneImageSaver.cpp @@ -30,27 +30,26 @@ #include #include +#include struct KSaneImageSaver::Private { - enum ImageType { - ImageTypePNG, - ImageTypeTIFF - }; - bool m_savedOk; QMutex m_runMutex; - KSaneImageSaver *q; + QUrl m_url; QString m_name; QByteArray m_data; int m_width; int m_height; - int m_format; + int m_bpl; int m_dpi; - ImageType m_type; + int m_format; + QString m_fileFormat; + int m_quality; - bool savePng(); - bool saveTiff(); + KSaneImageSaver *q; + + bool saveQImage(); }; // ------------------------------------------------------------------------ @@ -65,81 +64,43 @@ delete d; } -bool KSaneImageSaver::savePng(const QString &name, const QByteArray &data, int width, int height, int format, int dpi) +bool KSaneImageSaver::saveQImage(const QUrl &url, const QString &name, const QByteArray &data, int width, int height, int bpl, int dpi, int format, const QString& fileFormat, int quality) { if (!d->m_runMutex.tryLock()) { return false; } + d->m_url = url; d->m_name = name; d->m_data = data; d->m_width = width; d->m_height = height; - d->m_format = format; + d->m_bpl = bpl; d->m_dpi = dpi; - d->m_type = Private::ImageTypePNG; + d->m_format = format; + d->m_fileFormat = fileFormat; + d->m_quality = quality; start(); return true; } -bool KSaneImageSaver::savePngSync(const QString &name, const QByteArray &data, int width, int height, int format, int dpi) -{ - if (!savePng(name, data, width, height, format, dpi)) { - qDebug() << "fail"; - return false; - } - wait(); - return d->m_savedOk; -} - -bool KSaneImageSaver::saveTiff(const QString &name, const QByteArray &data, int width, int height, int format) +void KSaneImageSaver::run() { - if (!d->m_runMutex.tryLock()) { - return false; - } - - d->m_name = name; - d->m_data = data; - d->m_width = width; - d->m_height = height; - d->m_format = format; - d->m_type = Private::ImageTypeTIFF; + d->m_savedOk = d->saveQImage(); + emit imageSaved(d->m_url, d->m_name, d->m_savedOk); - qDebug() << "saving Tiff images is not yet supported"; d->m_runMutex.unlock(); - return false; -} - -bool KSaneImageSaver::saveTiffSync(const QString &name, const QByteArray &data, int width, int height, int format) -{ - if (!saveTiff(name, data, width, height, format)) { - return false; - } - wait(); - return d->m_savedOk; } -void KSaneImageSaver::run() +bool KSaneImageSaver::Private::saveQImage() { - if (d->m_type == Private::ImageTypeTIFF) { - d->m_savedOk = d->saveTiff(); - emit imageSaved(d->m_savedOk); - } - else { - d->m_savedOk = d->savePng(); - emit imageSaved(d->m_savedOk); + if ((m_format != KSaneIface::KSaneWidget::FormatRGB_16_C) && + (m_format != KSaneIface::KSaneWidget::FormatGrayScale16)) { + QImage img = KSaneIface::KSaneWidget::toQImageSilent(m_data, m_width, m_height, m_bpl, m_dpi, (KSaneIface::KSaneWidget::ImageFormat) m_format); + return img.save(m_name, m_fileFormat.toStdString().c_str(), m_quality); } - d->m_runMutex.unlock(); -} -bool KSaneImageSaver::Private::saveTiff() -{ - return false; -} - -bool KSaneImageSaver::Private::savePng() -{ FILE *file; png_structp png_ptr; png_infop info_ptr; diff --git a/src/skanlite.h b/src/skanlite.h --- a/src/skanlite.h +++ b/src/skanlite.h @@ -31,6 +31,7 @@ #include "ui_settings.h" #include "DBusInterface.h" +#include "KSaneImageSaver.h" class ShowImageDialog; class SaveLocation; @@ -64,6 +65,7 @@ void getDir(); void imageReady(QByteArray &, int, int, int, int); void saveImage(); + void imageSaved(const QUrl &url, const QString &name, bool success); void showAboutDialog(); void saveWindowSize(); @@ -93,6 +95,7 @@ private: KAboutData *m_aboutData; KSaneWidget *m_ksanew = nullptr; + KSaneImageSaver *m_image_saver = nullptr; Ui::SkanliteSettings m_settingsUi; QDialog *m_settingsDialog = nullptr; ShowImageDialog *m_showImgDialog = nullptr; diff --git a/src/skanlite.cpp b/src/skanlite.cpp --- a/src/skanlite.cpp +++ b/src/skanlite.cpp @@ -24,7 +24,6 @@ #include "skanlite.h" -#include "KSaneImageSaver.h" #include "SaveLocation.h" #include "showimagedialog.h" @@ -79,6 +78,9 @@ connect(m_ksanew, &KSaneWidget::userMessage, this, &Skanlite::alertUser); connect(m_ksanew, &KSaneWidget::buttonPressed, this, &Skanlite::buttonPressed); + m_image_saver = new KSaneImageSaver(this); + connect(m_image_saver, &KSaneImageSaver::imageSaved, this, &Skanlite::imageSaved); + mainLayout->addWidget(m_ksanew); mainLayout->addWidget(dlgButtonBoxBottom); @@ -372,18 +374,39 @@ } } +bool pathExists(const QString& dir, QWidget* parent) +{ + // propose directory creation if doesn't exists + QUrl dirUrl(dir); + if (dirUrl.isLocalFile()) { + QDir path(dirUrl.toLocalFile()); + if (!path.exists()) { + if (KMessageBox::questionYesNo(parent, i18n("Directory doesn't exist, do you wish to create it?")) == KMessageBox::ButtonCode::Yes ) { + if (!path.mkpath(QLatin1String("."))) { + KMessageBox::error(parent, i18n("Could not create directory %1", path.path())); + return false; + } + } + } + } + return true; +} + void Skanlite::saveImage() { // ask the first time if we are in "ask on first" mode - if ((m_settingsUi.saveModeCB->currentIndex() == SaveModeAskFirst) && m_firstImage) { + QString dir = QDir::cleanPath(m_saveLocation->u_urlRequester->url().url()).append(QLatin1Char('/')); //make sure whole value is processed as path to directory + + while ((m_firstImage && (m_settingsUi.saveModeCB->currentIndex() == SaveModeAskFirst)) || + !pathExists(dir, this)) { if (m_saveLocation->exec() != QFileDialog::Accepted) { m_ksanew->scanCancel(); // In case we are cancelling a document feeder scan return; } + dir = QDir::cleanPath(m_saveLocation->u_urlRequester->url().url()).append(QLatin1Char('/')); m_firstImage = false; } - QString dir = QDir::cleanPath(m_saveLocation->u_urlRequester->url().url()).append(QLatin1Char('/')); //make sure whole value is processed as path to directory QString prefix = m_saveLocation->u_imgPrefix->text(); QString imgFormat = m_saveLocation->u_imgFormat->currentText().toLower(); int fileNumber = m_saveLocation->u_numStartFrom->value(); @@ -487,9 +510,9 @@ QString localName; QString suffix = QFileInfo(fileUrl.fileName()).suffix(); - const char *fileFormat = nullptr; + QString fileFormat; if (suffix.isEmpty()) { - fileFormat = "png"; + fileFormat = QLatin1String("png"); } if (!fileUrl.isLocalFile()) { @@ -507,32 +530,26 @@ localName = fileUrl.toLocalFile(); } + // Save - if ((m_format == KSaneIface::KSaneWidget::FormatRGB_16_C) || - (m_format == KSaneIface::KSaneWidget::FormatGrayScale16)) { - KSaneImageSaver saver; - if (saver.savePngSync(localName, m_data, m_width, m_height, m_format, m_ksanew->currentDPI())) { - m_showImgDialog->close(); // closing the window if it is closed should not be a problem. - } - else { - perrorMessageBox(i18n("Failed to save image")); - return; - } + if (m_img.width() > 1) { + bool success = m_img.save(localName, fileFormat.toStdString().c_str(), quality); + imageSaved(fileUrl, localName, success); + } else { + m_image_saver->saveQImage(fileUrl, localName, m_data, m_width, m_height, m_bytesPerLine, (int) m_ksanew->currentDPI(), m_format, fileFormat, quality); } - else { - // create the image if needed. - if (m_img.width() < 1) { - m_img = m_ksanew->toQImage(m_data, m_width, m_height, m_bytesPerLine, (KSaneIface::KSaneWidget::ImageFormat)m_format); - } - if (m_img.save(localName, fileFormat, quality)) { - m_showImgDialog->close(); // calling close() on a closed window does nothing. - } - else { - perrorMessageBox(i18n("Failed to save image")); - return; - } +} + +void Skanlite::imageSaved(const QUrl &fileUrl, const QString &localName, bool success) +{ + if (!success) { + perrorMessageBox(i18n("Failed to save image")); + return; } + m_showImgDialog->close(); // calling close() on a closed window does nothing. + + if (!fileUrl.isLocalFile()) { QFile tmpFile(localName); tmpFile.open(QIODevice::ReadOnly); @@ -542,7 +559,7 @@ tmpFile.close(); tmpFile.remove(); if (!ok) { - KMessageBox::sorry(0, i18n("Failed to upload image")); + KMessageBox::sorry(nullptr, i18n("Failed to upload image")); } else { emit m_dbusInterface.imageSaved(fileUrl.toString()); @@ -562,7 +579,7 @@ // Save the number QString fileNumStr = QFileInfo(fileUrl.fileName()).completeBaseName(); fileNumStr.remove(baseName); - fileNumber = fileNumStr.toInt(); + int fileNumber = fileNumStr.toInt(); if (fileNumber) { m_saveLocation->u_numStartFrom->setValue(fileNumber + 1); }