From: hama Date: Wed, 20 Jan 2016 00:29:45 +0000 (+0100) Subject: reimgconvert: gui redesign, search separated X-Git-Url: https://gitweb.hamatoma.de/?a=commitdiff_plain;h=3a50be5c00f49184bbf1988dc5f9b8401c205ad4;p=reqt reimgconvert: gui redesign, search separated * removed unneeded elements (layouts...) * search is a separate thread * recursive processing * new: showing other files --- diff --git a/appl/rebackgui/about.ui b/appl/rebackgui/about.ui new file mode 100644 index 0000000..a6d80c5 --- /dev/null +++ b/appl/rebackgui/about.ui @@ -0,0 +1,74 @@ + + + AboutDialog + + + + 0 + 0 + 400 + 225 + + + + About + + + + + 20 + 20 + 351 + 141 + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">ReFind</span> for searching files in a directory tree</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">This is a program of the project &quot;<span style=" font-weight:600;">Re</span>al <span style=" font-weight:600;">Pub</span>lic <span style=" font-weight:600;">Lib</span>rary&quot;.</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Sources are public domain and available under https://github.com/republib</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Implemented in QT (C++) 5.x</p></body></html> + + + + + + 280 + 180 + 93 + 27 + + + + &OK + + + + + &OK + + + + + + + action_OK + triggered() + AboutDialog + close() + + + -1 + -1 + + + 199 + 112 + + + + + diff --git a/appl/rebackgui/aboutdialog.cpp b/appl/rebackgui/aboutdialog.cpp new file mode 100644 index 0000000..eedd0a8 --- /dev/null +++ b/appl/rebackgui/aboutdialog.cpp @@ -0,0 +1,23 @@ +/* + * aboutdialog.cpp + * + * (Un)License: Public Domain + * You can use and modify this file without any restriction. + * Do what you want. + * No warranties and disclaimer of any damages. + * More info: http://unlicense.org + * The latest sources: https://github.com/republib + */ + +#include "aboutdialog.hpp" +#include "ui_aboutdialog.h" + +AboutDialog::AboutDialog(const QString& version, QWidget *parent) : + QDialog(parent), ui(new Ui::AboutDialog){ + ui->setupUi(this); + ui->labelVersion->setText(version); +} + +AboutDialog::~AboutDialog(){ + delete ui; +} diff --git a/appl/rebackgui/aboutdialog.hpp b/appl/rebackgui/aboutdialog.hpp new file mode 100644 index 0000000..bf51cc7 --- /dev/null +++ b/appl/rebackgui/aboutdialog.hpp @@ -0,0 +1,32 @@ +/* + * aboutdialog.hpp + * + * (Un)License: Public Domain + * You can use and modify this file without any restriction. + * Do what you want. + * No warranties and disclaimer of any damages. + * More info: http://unlicense.org + * The latest sources: https://github.com/republib + */ + +#ifndef ABOUTDIALOG_HPP +#define ABOUTDIALOG_HPP + +#include + +namespace Ui { +class AboutDialog; +} + +class AboutDialog: public QDialog { + Q_OBJECT + +public: + explicit AboutDialog(const QString& version, QWidget *parent = 0); + ~AboutDialog(); + +private: + Ui::AboutDialog *ui; +}; + +#endif // ABOUTDIALOG_HPP diff --git a/appl/rebackgui/aboutdialog.ui b/appl/rebackgui/aboutdialog.ui new file mode 100644 index 0000000..a4e82da --- /dev/null +++ b/appl/rebackgui/aboutdialog.ui @@ -0,0 +1,117 @@ + + + AboutDialog + + + + 0 + 0 + 423 + 289 + + + + Dialog + + + true + + + + + 20 + 20 + 381 + 221 + + + + true + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">ReImgConvert</span> for converting images to smaller dimensions/size.</p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">This is a program of the project</p> +<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Re</span>al <span style=" font-weight:600;">Pub</span>lic <span style=" font-weight:600;">Lib</span>rary (RePubLib)</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Sources are public domain and available under</p> +<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="https://github.com/republib"><span style=" text-decoration: underline; color:#0000ff;">https://github.com/republib</span></a> </p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Implemented in QT (C++) 5.x</p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Icons: Mark James, <a href="http://famfamfam.com"><span style=" text-decoration: underline; color:#0000ff;">http://famfamfam.com</span></a> </p></body></html> + + + false + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + 20 + 250 + 381 + 29 + + + + + + + Version: + + + + + + + 2015.05.00 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + &OK + + + + + + + + + + pushButtonOK + clicked() + AboutDialog + close() + + + 196 + 183 + + + 199 + 108 + + + + + diff --git a/appl/rebackgui/main.cpp b/appl/rebackgui/main.cpp new file mode 100644 index 0000000..b5e8a18 --- /dev/null +++ b/appl/rebackgui/main.cpp @@ -0,0 +1,19 @@ +/* + * Licence: + * You can use and modify this file without any restriction. + * There is no warranty. + * You also can use the licence from http://www.wtfpl.net/. + * The original sources can be found on https://github.com/republib. +*/ + +#include "mainwindow.hpp" +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + MainWindow w; + w.show(); + + return a.exec(); +} diff --git a/appl/rebackgui/mainwindow.cpp b/appl/rebackgui/mainwindow.cpp new file mode 100644 index 0000000..5ef22d6 --- /dev/null +++ b/appl/rebackgui/mainwindow.cpp @@ -0,0 +1,22 @@ +/* + * Licence: + * You can use and modify this file without any restriction. + * There is no warranty. + * You also can use the licence from http://www.wtfpl.net/. + * The original sources can be found on https://github.com/republib. +*/ + +#include "mainwindow.hpp" +#include "ui_mainwindow.h" + +MainWindow::MainWindow(QWidget *parent) : + QMainWindow(parent), + ui(new Ui::MainWindow) +{ + ui->setupUi(this); +} + +MainWindow::~MainWindow() +{ + delete ui; +} diff --git a/appl/rebackgui/mainwindow.hpp b/appl/rebackgui/mainwindow.hpp new file mode 100644 index 0000000..754b001 --- /dev/null +++ b/appl/rebackgui/mainwindow.hpp @@ -0,0 +1,30 @@ +/* + * Licence: + * You can use and modify this file without any restriction. + * There is no warranty. + * You also can use the licence from http://www.wtfpl.net/. + * The original sources can be found on https://github.com/republib. +*/ + +#ifndef MAINWINDOW_HPP +#define MAINWINDOW_HPP + +#include "base/rebase.hpp" + +namespace Ui { +class MainWindow; +} + +class MainWindow : public ReHomeApplication +{ + Q_OBJECT + +public: + explicit MainWindow(QWidget *parent = 0); + ~MainWindow(); + +private: + Ui::MainWindow *ui; +}; + +#endif // MAINWINDOW_HPP diff --git a/appl/rebackgui/mainwindow.ui b/appl/rebackgui/mainwindow.ui new file mode 100644 index 0000000..6050363 --- /dev/null +++ b/appl/rebackgui/mainwindow.ui @@ -0,0 +1,24 @@ + + MainWindow + + + + 0 + 0 + 400 + 300 + + + + MainWindow + + + + + + + + + + + diff --git a/appl/rebackgui/rebackgui.pro b/appl/rebackgui/rebackgui.pro new file mode 100644 index 0000000..ae124c7 --- /dev/null +++ b/appl/rebackgui/rebackgui.pro @@ -0,0 +1,39 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2016-01-18T00:51:17 +# +#------------------------------------------------- + +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = rebackgui +TEMPLATE = app +INCLUDEPATH = ../.. /usr/include/c++/4.9 + +SOURCES += main.cpp\ + ../../base/ReException.cpp \ + ../../base/ReQStringUtils.cpp \ + ../../base/ReFileUtils.cpp \ + ../../base/ReLogger.cpp \ + ../../gui/ReStateStorage.cpp \ + ../../gui/ReGuiValidator.cpp \ + ../../gui/ReGuiQueue.cpp \ + mainwindow.cpp \ + aboutdialog.cpp + +HEADERS += mainwindow.hpp \ + ../../base/rebase.hpp \ + ../../base/ReQStringUtils.hpp \ + ../../gui/ReStateStorage.hpp \ + ../../gui/ReGuiValidator.hpp \ + ../../gui/regui.hpp \ + aboutdialog.hpp + +FORMS += mainwindow.ui \ + aboutdialog.ui + +DISTFILES += \ + ReBackGui.html + diff --git a/appl/reimgconvert/converter.cpp b/appl/reimgconvert/converter.cpp index 50bbde8..26d446e 100644 --- a/appl/reimgconvert/converter.cpp +++ b/appl/reimgconvert/converter.cpp @@ -90,7 +90,50 @@ * */ -QString sizeToString(qint64 size); +bool Converter::m_shouldStop = false; +QStringList Converter::m_files; +uint64_t Converter::m_totalBytes = 0; +int Converter::m_totalFiles = 0; +bool Converter::m_searchReady = false; +QMutex Converter::m_mutex; + +/** + * Constructor. + * + * @param directory the base directory of the images to inspect + * @param mainWindow + */ +Converter::Converter(const QString &directory, MainWindow *mainWindow): + m_sourceDir(directory), + m_mainWindow(mainWindow) +{ +} + +/** + * @brief Logs an error message. + * + * @param message the message to log + * @return false + * @throws ConverterException + */ +bool Converter::error(const QString& message){ + m_mainWindow->log(message); + throw ConverterException(message); + return false; +} + +/** + * @brief Logs a message. + * + * @param message the message to log + * @return true + */ +bool Converter::log(const QString& message){ + printf("%s\n", I18N::s2b(message).constData()); + m_mainWindow->log(message); + return true; +} + /** * @brief Constructor. @@ -111,37 +154,36 @@ QString sizeToString(qint64 size); * but larger * @param mainWindow the window. Will be used for output */ -Converter::Converter(const QString& directory, const QString& targetDirectory, +TaskConverter::TaskConverter(const QString& directory, const QString& targetDirectory, const QString& sourcePattern, const QString& targetType, bool simpleConversion, int maxWidth, int maxHeight, int landscapeX, int landscapeY, int portraitX, int portraitY, int squareX, int quality, MainWindow* mainWindow) : - m_dir(directory), - m_targetDir(targetDirectory), - m_sourcePattern(sourcePattern), - m_targetType(targetType), - m_landscapeWidth(landscapeX), - m_landscapeHeight(landscapeY), - m_portraitWidth(portraitX), - m_portraitHeight(portraitY), - m_squareWidth(squareX), - m_quality(targetType == "jpg" ? quality : 0), - m_mainWindows(mainWindow), - m_shouldStop(false), - m_imageInfo( - new QRegularExpression(" (PNG|GIF|JPEG) (\\d+)x(\\d+) ")), - m_groupWidth(2), - m_groupHeight(3), - m_simpleMode(simpleConversion), - m_maxWidth(maxWidth), - m_maxHeight(maxHeight) + Converter(directory, mainWindow), + m_targetDir(targetDirectory), + m_targetType(targetType), + m_landscapeWidth(landscapeX), + m_landscapeHeight(landscapeY), + m_portraitWidth(portraitX), + m_portraitHeight(portraitY), + m_squareWidth(squareX), + m_quality(targetType == "jpg" ? quality : 0), + m_imageInfo( + new QRegularExpression(" (PNG|GIF|JPEG) (\\d+)x(\\d+) ")), + m_groupWidth(2), + m_groupHeight(3), + m_simpleMode(simpleConversion), + m_maxWidth(maxWidth), + m_maxHeight(maxHeight) { + ReQStringUtils::ensureLastChar(m_sourceDir, OS_SEPARATOR); + ReQStringUtils::ensureLastChar(m_targetDir, OS_SEPARATOR); } /** * @brief Destructor. */ -Converter::~Converter(){ +TaskConverter::~TaskConverter(){ delete m_imageInfo; } @@ -158,16 +200,6 @@ void addArg(QStringList& args, const char* prefix, int value){ args << arg; } -/** - * @brief Changes the state of the thread. - * - * @param state the new state - * @param info an info about the change - */ -void Converter::changeState(Converter::State state, const QString& info){ - m_mainWindows->onThreadStateChanged(state, info); -} - /** * Converts an image into another format. * @@ -179,7 +211,7 @@ void Converter::changeState(Converter::State state, const QString& info){ * @param heightNew the new height of the image * @param quality 0 or quality in % (only for JPEG targets) */ -void Converter::convert(const QString& source, const QString& target, int width, +void TaskConverter::callExternProgram(const QString& source, const QString& target, int width, int height, int widthNew, int heightNew, int quality){ QStringList args; // convert -size 100x200 source.png -resize 50x100 target.jpg"; @@ -202,6 +234,42 @@ void Converter::convert(const QString& source, const QString& target, int width, process.close(); } +/** + * @brief Converts one file. + * + * @param source the file's name with path + * @param target the new filename with path + * @param size the size of the file (in byte) + * @param sizeTarget OUT: the file size of the target + */ +void TaskConverter::convertOneFile(const QString& source, const QString& target, + qint64 size, qint64& sizeTarget){ + int width = 0; + int height = 0; + QString info; + clock_t start = clock(); + if (readProperties(source, width, height, info)){ + int widthNew = width; + int heightNew = height; + if (m_simpleMode) + handleSimple(width, height, widthNew, heightNew); + else + handleUserDefined(width, height, widthNew, heightNew); + QString node = ReFileUtils::nodeOf(source); + log( + node + " " + info + " " + ReQStringUtils::readableSize(size) + + QString(" -> %1x%2 ").arg(widthNew).arg(heightNew)); + callExternProgram(source, target, width, height, widthNew, heightNew, m_quality); + struct stat info; + if (stat(I18N::s2b(target).constData(), &info) == 0){ + sizeTarget = info.st_size; + m_mainWindow->logAppendLast(ReQStringUtils::readableSize(sizeTarget) + + " " + ReQStringUtils::readableDuration( + clock() - start)); + } + } +} + /** * Converts an image with a given maximal width and size. * @@ -211,7 +279,7 @@ void Converter::convert(const QString& source, const QString& target, int width, * @param heightNew OUT: the height of the converted image * @return true: the image needs to be converted */ -bool Converter::handleSimple(int width, int height, int& widthNew, int& heightNew) +bool TaskConverter::handleSimple(int width, int height, int& widthNew, int& heightNew) { bool doConvert = false; if (width > m_maxWidth){ @@ -237,7 +305,7 @@ bool Converter::handleSimple(int width, int height, int& widthNew, int& heightNe * @param heightNew OUT: the height of the converted image * @return true: the image needs to be converted */ -bool Converter::handleUserDefined(int width, int height, int& widthNew, int& heightNew){ +bool TaskConverter::handleUserDefined(int width, int height, int& widthNew, int& heightNew){ bool doConvert = false; if (abs(width - height) < 5){ // Square format: @@ -272,67 +340,6 @@ bool Converter::handleUserDefined(int width, int height, int& widthNew, int& hei return doConvert; } -/** - * @brief Converts one file. - * - * @param source the file's name with path - * @param target the new filename with path - * @param size the size of the file (in byte) - * @param sizeTarget OUT: the file size of the target - */ -void Converter::convertOneFile(const QString& source, const QString& target, - qint64 size, qint64& sizeTarget){ - int width = 0; - int height = 0; - QString info; - clock_t start = clock(); - if (readProperties(source, width, height, info)){ - int widthNew = width; - int heightNew = height; - if (m_simpleMode) - handleSimple(width, height, widthNew, heightNew); - else - handleUserDefined(width, height, widthNew, heightNew); - QString node = ReFileUtils::nodeOf(source); - log( - node + " " + info + " " + ReQStringUtils::readableSize(size) - + QString(" -> %1x%2 ").arg(widthNew).arg(heightNew)); - convert(source, target, width, height, widthNew, heightNew, m_quality); - struct stat info; - if (stat(I18N::s2b(target).constData(), &info) == 0){ - sizeTarget = info.st_size; - m_mainWindows->logAppendLast(ReQStringUtils::readableSize(sizeTarget) - + " " + ReQStringUtils::readableDuration( - clock() - start)); - } - } -} - -/** - * @brief Logs an error message. - * - * @param message the message to log - * @return false - * @throws ConverterException - */ -bool Converter::error(const QString& message){ - m_mainWindows->log(message); - throw ConverterException(message); - return false; -} - -/** - * @brief Logs a message. - * - * @param message the message to log - * @return true - */ -bool Converter::log(const QString& message){ - printf("%s\n", I18N::s2b(message).constData()); - m_mainWindows->log(message); - return true; -} - /** * Reads the image properties. * @@ -343,7 +350,7 @@ bool Converter::log(const QString& message){ * @return true: success * false: properties not readable */ -bool Converter::readProperties(const QString& name, int& width, int& height, +bool TaskConverter::readProperties(const QString& name, int& width, int& height, QString& info){ QPixmap image(name); @@ -366,7 +373,7 @@ bool Converter::readProperties(const QString& name, int& width, int& height, * @return true: success * false: properties not readable */ -bool Converter::readPropertiesByIdentify(const QString& name, int& width, int& height, +bool TaskConverter::readPropertiesByIdentify(const QString& name, int& width, int& height, QString& info){ QStringList args; args << name; @@ -400,67 +407,68 @@ bool Converter::readPropertiesByIdentify(const QString& name, int& width, int& h /** * @brief Runs the thread's task. * - *
    - *
  • Makes the target directory (if necessary)
  • - *
  • Search the images *.png / *.jpg and converts them
  • - *
+ * Makes the target directory (if necessary). + * Converts all files from the filelist created by TaskSearch. */ -void Converter::run(){ +void TaskConverter::run(){ QString msg; clock_t start = clock(); uint64_t preSize = 0; uint64_t postSize = 0; uint64_t lengthTarget = 0; int no = 0; + QString info; + QString node; + QString targetDir; try{ - if (!m_dir.exists()) - error( - QObject::tr("Directory does not exist: ") + m_dir.absolutePath()); - if (!m_targetDir.exists()){ - QString parentName = m_targetDir.path(); - QString subdir = m_targetDir.dirName(); - QDir parent(m_targetDir.path()); - parent.cdUp(); - parent.mkdir(subdir); - } - if (!m_targetDir.exists()){ - error( - QObject::tr("Cannot create the target directory: ") - + m_targetDir.absolutePath()); - } - changeState(Converter::STATE_STARTING, ""); + while (! m_shouldStop && ! m_searchReady){ + m_mutex.lock(); + if (m_files.size() == 0) + info.clear(); + else{ + info = m_files.first(); + m_files.removeFirst(); + } + m_mutex.unlock(); + if (info.isEmpty()){ + QThread::sleep(50); + } else { + int ix = info.indexOf('\t'); + node = info.mid(ix + 1); + info.resize(ix); + targetDir = m_targetDir; + if (!info.isEmpty()) + targetDir += info + OS_SEPARATOR; + if (! QDir(targetDir).exists()) + _mkdir(I18N::s2b(targetDir).constData()); + QDir dir(targetDir); + if (! dir.exists()){ + error(tr("cannot create directory: %1").arg(targetDir)); + }else { + no++; + QString path = m_sourceDir + info + node; + qint64 length = QFileInfo(path).size(); + QString nodeTarget = ReFileUtils::replaceExtension(node, + "." + m_targetType); + QString target = m_targetDir + info + nodeTarget; + convertOneFile(path, target, length, lengthTarget); + preSize += length; + postSize += lengthTarget; + int percentFiles = int(no * 100 / max(1, m_totalFiles)); + int percentSize = int(preSize * 100 / max(1, m_totalBytes)); + m_mainWindow->setStatusMessage(LOG_INFO, + tr("%1 file(s) of %2 (%3 %), %4 -> %5 (%6 %)") + .arg(no).arg(m_totalFiles) + .arg(percentFiles + percentSize / 2) + .arg(ReQStringUtils::readableSize(preSize)) + .arg(ReQStringUtils::readableSize(postSize)) + .arg(postSize * 100.0 / max(1, preSize), 0, + 'f', 2)); + + } + } + } m_shouldStop = false; - QDirIterator it(m_dir.absolutePath()); - QRegExp regExpr(m_sourcePattern, Qt::CaseInsensitive, QRegExp::Wildcard); - while (it.hasNext()){ - if (m_shouldStop){ - log(QObject::tr("Canceled by the user")); - break; - } - it.next(); - if (it.fileInfo().isDir()) - continue; - QString node = it.fileName(); - if (regExpr.indexIn(node) >= 0){ - no++; - QString path = m_dir.absoluteFilePath(node); - qint64 length = it.fileInfo().size(); - QString nodeTarget = ReFileUtils::replaceExtension(node, - "." + m_targetType); - QString target = m_targetDir.absoluteFilePath(nodeTarget); - convertOneFile(path, target, length, lengthTarget); - preSize += length; - postSize += lengthTarget; - m_mainWindows->setStatusMessage(LOG_INFO, - tr("%1 file(s) %2 -> %3 (%4 %)") - .arg(no) - .arg(ReQStringUtils::readableSize(preSize)) - .arg(ReQStringUtils::readableSize(postSize)) - .arg(postSize * 100.0 / max(1, preSize), 0, - 'f', 2)); - } - } - changeState(Converter::STATE_SUB_TASK_STOPPED, msg); } catch (ConverterException exc){ log( QObject::tr("Execution stopped because of error(s): ") @@ -472,29 +480,137 @@ void Converter::run(){ .arg(ReQStringUtils::readableSize(postSize)) .arg(postSize * 100.0 / preSize, 0, 'f', 2) .arg(ReQStringUtils::readableDuration(clock() - start)); - changeState(Converter::STATE_READY, msg); + m_mainWindow->finishTask(msg); } /** - * @brief Search for the Perl script which make the conversion itself. + * Constructor. * - * @param node the name of script without path. - * @return the full name of the script (with path) + * @param directory the base directory to inspect + * @param sourcePattern the pattern of the image files to convert + * @param mainWindow the parent */ -QString findScript(const QString& node){ - static QString rc; - if (rc.isEmpty()){ +TaskSearch::TaskSearch(const QString& directory, + const QString& sourcePattern, bool recursive, MainWindow* mainWindow) : + Converter(directory, mainWindow), + m_sourcePattern(sourcePattern), + m_recursive(recursive) +{ +} - QDir dir = QDir::current(); - QFile scriptFile(dir.filePath(node)); - if (!scriptFile.exists()){ - extern char** g_argv; - dir.setPath(g_argv[0]); - dir.cdUp(); - scriptFile.setFileName(dir.filePath(node)); - } - if (scriptFile.exists()) - rc = scriptFile.fileName(); - } - return rc; +/** + * Search the image files in one directory and write it to a list. + * + * This method is recursive. + * + * @param dir the directory to inspect + */ +void TaskSearch::searchOneDirectory(const QString& dir){ + QDirIterator it(dir); + QRegExp regExpr(m_sourcePattern, Qt::CaseInsensitive, QRegExp::Wildcard); + QString relPath; + QString info; + if (dir.length() > m_sourceDir.length()) + relPath = m_sourceDir.mid(m_sourceDir.length()); + while (it.hasNext()){ + if (m_shouldStop){ + break; + } + it.next(); + if (! it.fileInfo().isDir() && regExpr.indexIn(it.fileName()) >= 0){ + info = relPath + "\t" + it.fileName(); + m_mutex.lock(); + m_files.append(info); + m_mutex.unlock(); + } + } + if (m_recursive && ! m_shouldStop){ + QDirIterator it2(dir); + while (it2.hasNext()){ + if (m_shouldStop){ + break; + } + it2.next(); + + if (it2.fileInfo().isDir()){ + searchOneDirectory(it2.filePath()); + } + } + } } + +/** + * Search the input files and write it into the result list. + */ +void TaskSearch::run(){ + m_searchReady = false; + searchOneDirectory(m_sourceDir); + m_searchReady = true; +} + +/** + * Constructor. + * + * @param directory the base directory to inspect + * @param sourcePattern the pattern of the image files to convert + * @param mainWindow the parent + */ +TaskShowOther::TaskShowOther(const QString& directory, + const QString& sourcePattern, bool recursive, MainWindow* mainWindow) : + Converter(directory, mainWindow), + m_sourcePattern(sourcePattern), + m_recursive(recursive) +{ +} + +/** + * Search the image files in one directory and write it to a list. + * + * This method is recursive. + * + * @param dir the directory to inspect + */ +void TaskShowOther::processOneDirectory(const QString& dir){ + QDirIterator it(dir); + QRegExp regExpr(m_sourcePattern, Qt::CaseInsensitive, QRegExp::Wildcard); + QString relPath; + QString info; + if (dir.length() > m_sourceDir.length()) + relPath = m_sourceDir.mid(m_sourceDir.length()); + while (it.hasNext()){ + if (m_shouldStop){ + break; + } + it.next(); + if (! it.fileInfo().isDir() && regExpr.indexIn(it.fileName()) < 0){ + info = relPath + it.fileName(); + m_totalFiles++; + m_mainWindow->remoteLog(info); + } + } + if (m_recursive && ! m_shouldStop){ + QDirIterator it2(dir); + while (it2.hasNext()){ + if (m_shouldStop){ + break; + } + it2.next(); + + if (it2.fileInfo().isDir()){ + processOneDirectory(it2.filePath()); + } + } + } +} + +/** + * Search the input files and write it into the result list. + */ +void TaskShowOther::run(){ + m_searchReady = false; + m_totalFiles = 0; + processOneDirectory(m_sourceDir); + m_searchReady = true; + m_mainWindow->finishTask(tr("Found: %1 file(s)").arg(m_totalFiles)); +} + diff --git a/appl/reimgconvert/converter.hpp b/appl/reimgconvert/converter.hpp index 0ba19a1..891374a 100644 --- a/appl/reimgconvert/converter.hpp +++ b/appl/reimgconvert/converter.hpp @@ -18,6 +18,7 @@ #include #include #include +#include class MainWindow; class ConverterException { @@ -41,56 +42,90 @@ public: class Converter: public QThread { Q_OBJECT + public: - enum State { - STATE_UNDEF, STATE_STARTING, STATE_SUB_TASK_STOPPED, STATE_READY, - }; -public: - Converter(const QString& directory, const QString& targetDirectory, - const QString& sourcePattern, const QString& targetType, - bool simpleConversion, int maxWidth, int maxHeight, int landscapeX, - int landscapeY, int portraitX, int portraitY, int squareX, int quality, - MainWindow* mainWindows); - ~Converter(); + Converter(const QString& directory, MainWindow* mainWindow); public: bool error(const QString& message); bool log(const QString& message); - void run(); - void stop(){ - m_shouldStop = true; - } protected: - bool buildArgs(); - void changeState(State state, const QString& info); - void convert(const QString& source, const QString& target, int width, - int height, int widthNew, int heightNew, int quality); - void convertOneFile(const QString& source, const QString& target, - qint64 size, qint64& sizeTarget); - bool handleSimple(int width, int height, int& widthNew, int& heightNew); - bool handleUserDefined(int width, int height, int& widthNew, int& heightNew); - bool readProperties(const QString& name, int &width, int &height, - QString &info); - bool readPropertiesByIdentify(const QString& name, int &width, int &height, - QString &info); + virtual void run() = 0; +protected: + QString m_sourceDir; + MainWindow* m_mainWindow; +public: + static bool m_shouldStop; + static QStringList m_files; + static qint64 m_totalBytes; + static int m_totalFiles; + static bool m_searchReady; + static QMutex m_mutex; +}; + +class TaskConverter : public Converter { +public: + TaskConverter(const QString& directory, const QString& targetDirectory, + const QString& sourcePattern, const QString& targetType, + bool simpleConversion, int maxWidth, int maxHeight, int landscapeX, + int landscapeY, int portraitX, int portraitY, int squareX, int quality, + MainWindow* mainWindows); + ~TaskConverter(); +protected: + virtual void run(); +protected: + bool buildArgs(); + void callExternProgram(const QString& source, const QString& target, int width, + int height, int widthNew, int heightNew, int quality); + void converterTask(); + void convertOneFile(const QString& source, const QString& target, + qint64 size, qint64& sizeTarget); + bool handleSimple(int width, int height, int& widthNew, int& heightNew); + bool handleUserDefined(int width, int height, int& widthNew, int& heightNew); + bool readProperties(const QString& name, int &width, int &height, + QString &info); + bool readPropertiesByIdentify(const QString& name, int &width, int &height, + QString &info); +private: + QString m_targetDir; + QString m_targetType; + int m_landscapeWidth; + int m_landscapeHeight; + int m_portraitWidth; + int m_portraitHeight; + int m_squareWidth; + int m_quality; + QRegularExpression* m_imageInfo; + int m_groupWidth; + int m_groupHeight; + bool m_simpleMode; + int m_maxWidth; + int m_maxHeight; +}; + +class TaskSearch : public Converter { +public: + TaskSearch(const QString& dir, const QString& sourcePattern, + bool recursive, MainWindow* mainWindows); +protected: + virtual void run(); +protected: + void searchOneDirectory(const QString& dir); +private: + QString m_sourcePattern; + bool m_recursive; +}; + +class TaskShowOther : public Converter { +public: + TaskShowOther(const QString& dir, const QString& sourcePattern, + bool recursive, MainWindow* mainWindows); +protected: + virtual void run(); +protected: + void processOneDirectory(const QString& dir); private: - QDir m_dir; - QDir m_targetDir; QString m_sourcePattern; - QString m_targetType; - int m_landscapeWidth; - int m_landscapeHeight; - int m_portraitWidth; - int m_portraitHeight; - int m_squareWidth; - int m_quality; - MainWindow* m_mainWindows; - bool m_shouldStop; - QRegularExpression* m_imageInfo; - int m_groupWidth; - int m_groupHeight; - bool m_simpleMode; - int m_maxWidth; - int m_maxHeight; + bool m_recursive; }; #endif // CONVERTER_HPP diff --git a/appl/reimgconvert/mainwindow.cpp b/appl/reimgconvert/mainwindow.cpp index 5f8006d..5a6fef5 100644 --- a/appl/reimgconvert/mainwindow.cpp +++ b/appl/reimgconvert/mainwindow.cpp @@ -34,7 +34,9 @@ const QString VERSION("2016.01.15"); MainWindow::MainWindow(const QString& homeDir, QWidget *parent) : ReHomeApplication("reimgconvert", homeDir, 2, 100100100, parent), ui(new Ui::MainWindow), - m_converter(NULL), + m_taskConvert(NULL), + m_taskSearch(NULL), + m_taskShowOther(NULL), m_logger(), m_guiQueue(), m_guiTimer(new QTimer(this)){ @@ -57,13 +59,14 @@ MainWindow::MainWindow(const QString& homeDir, QWidget *parent) : connect(ui->pushButtonSelectDest, SIGNAL(clicked()), this, SLOT(selectTarget())); connect(ui->actionSelectSource, SIGNAL(triggered()), this, - SLOT(selectSource())); + SLOT(onSelectSource())); connect(ui->pushButtonSelectSource, SIGNAL(clicked()), this, - SLOT(selectSource())); + SLOT(onSelectSource())); connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(about())); connect(ui->comboBoxTemplate, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(onTemplateChangeIndex(const QString&))); connect(m_guiTimer, SIGNAL(timeout()), this, SLOT(guiTimerUpdate())); + connect(ui->pushButtonShowOtherFiles, SIGNAL(clicked()), this, SLOT(onShowOtherFiles())); restoreState(); m_guiTimer->start(100); } @@ -73,7 +76,9 @@ MainWindow::MainWindow(const QString& homeDir, QWidget *parent) : */ MainWindow::~MainWindow(){ delete ui; - delete m_converter; + delete m_taskConvert; + delete m_taskSearch; + delete m_taskShowOther; } /** @@ -110,6 +115,18 @@ bool MainWindow::error(const QString& message){ return false; } +/** + * Finishs a task with sending a ready message. + * + * Note: the method is called from a non-main thread. + * + * @param message the message to show + */ +void MainWindow::finishTask(const QString& message){ + Converter::m_mutex.lock(); + m_guiQueue.pushBack(ReGuiQueueItem(ReGuiQueueItem::ReadyMessage, NULL, message)); + Converter::m_mutex.unlock(); +} /** * Callback method of the GUI timer. */ @@ -117,7 +134,9 @@ void MainWindow::guiTimerUpdate() { int count = m_guiQueue.count(); while(count-- > 0){ + Converter::m_mutex.lock(); ReGuiQueueItem item = m_guiQueue.popFront(); + Converter::m_mutex.unlock(); if (item.m_type == ReGuiQueueItem::Undef) break; if (! item.apply()){ @@ -147,7 +166,6 @@ void MainWindow::guiTimerUpdate() + " " + item.m_value); break; } - } } } @@ -173,8 +191,10 @@ bool MainWindow::log(const QString& message){ * @return true */ bool MainWindow::logAppendLast(const QString& message){ + Converter::m_mutex.lock(); m_guiQueue.pushBack(ReGuiQueueItem(ReGuiQueueItem::ListAppendToCurrent, ui->listWidget, message)); + Converter::m_mutex.unlock(); return true; } @@ -182,8 +202,8 @@ bool MainWindow::logAppendLast(const QString& message){ * @brief Handles the button click on "convert". */ void MainWindow::onConvert(){ - startStop(true); - delete m_converter; + Converter::m_shouldStop = false; + startStop(true); m_errors = 0; int landscapeX = comboInt(ui->comboBoxLandscapeX, 0, "*", 0); int landscapeY = comboInt(ui->comboBoxLandscapeY, 0, "*", 0); @@ -198,18 +218,48 @@ void MainWindow::onConvert(){ bool simpleConversion = match.hasMatch(); if (m_errors == 0){ saveState(); - m_converter = new Converter(ui->comboBoxSourceDir->currentText(), + delete m_taskSearch; + m_taskSearch = new TaskSearch(ui->comboBoxSourceDir->currentText(), + ui->comboBoxSourcePattern->currentText(), + ui->checkBoxCopyOtherFiles->isChecked(), this); + m_taskSearch->start(); + + delete m_taskConvert; + m_taskConvert = new TaskConverter(ui->comboBoxSourceDir->currentText(), ui->comboBoxTargetDir->currentText(), ui->comboBoxSourcePattern->currentText(), ui->comboBoxDestType->currentText(), simpleConversion, maxWidth, maxHeight, landscapeX, landscapeY, portraitX, portraitY, squareX, quality, this); - // start the thread: - m_converter->start(); + m_taskConvert->start(); } } + +/** + * Selects the destination directory with a dialog. + */ +void MainWindow::onSelectSource(){ + QString dir = QFileDialog::getExistingDirectory(this, + tr("Select Source Directory"), ui->comboBoxSourceDir->currentText(), + QFileDialog::ShowDirsOnly); + if (!dir.isEmpty()) + ui->comboBoxSourceDir->setCurrentText(dir); +} + +/** + * Shows the files not matching the file pattern (describing the images). + */ +void MainWindow::onShowOtherFiles(){ + Converter::m_shouldStop = false; + startStop(true); + delete m_taskShowOther; + m_taskShowOther = new TaskShowOther(ui->comboBoxSourceDir->currentText(), + ui->comboBoxSourcePattern->currentText(), + ui->checkBoxCopyOtherFiles->isChecked(), this); + m_taskShowOther->start(); +} /** * @brief Handles the click on the button "file select". * @@ -230,7 +280,7 @@ void MainWindow::onSourceFileSelect(){ * @brief Handles the click on the button "stop". */ void MainWindow::onStop(){ - m_converter->stop(); + Converter::m_shouldStop = true; } /** @@ -247,26 +297,17 @@ void MainWindow::onTemplateChangeIndex(const QString & text){ } /** - * @brief Handles the event "thread changed". + * Writes a text to the log. * - * Note: this method is called from a non main thread + * Note: this method is called from a non-main thread * - * @param state the new state of the thread - * @param info info about the new state. Not used + * @param message the text to set */ -void MainWindow::onThreadStateChanged(Converter::State state, const QString& info){ - switch (state) { - case Converter::STATE_READY: - m_guiQueue.pushBack(ReGuiQueueItem(ReGuiQueueItem::ReadyMessage, NULL, info)); - //ui->statusBar->showMessage(info); - break; - case Converter::STATE_SUB_TASK_STOPPED: - //ui->statusBar->showMessage(info); - break; - case Converter::STATE_STARTING: - default: - break; - } +void MainWindow::remoteLog(const QString& message){ + Converter::m_mutex.lock(); + m_guiQueue.pushBack(ReGuiQueueItem(ReGuiQueueItem::ListEnd, + ui->listWidget, message)); + Converter::m_mutex.unlock(); } /** * Reads the history of the widget values and other parameters and set it. @@ -330,17 +371,6 @@ bool MainWindow::say(ReLoggerLevel level, const QString& message) return level == LOG_ERROR; } -/** - * Selects the destination directory with a dialog. - */ -void MainWindow::selectSource(){ - QString dir = QFileDialog::getExistingDirectory(this, - tr("Select Source Directory"), ui->comboBoxSourceDir->currentText(), - QFileDialog::ShowDirsOnly); - if (!dir.isEmpty()) - ui->comboBoxSourceDir->setCurrentText(dir); -} - /** * Sets the maximal dimensions (from the "simple" interface). * @@ -384,8 +414,10 @@ void MainWindow::selectTarget(){ * @param message the text to set */ void MainWindow::setRemoteStatus(const QString& message){ + Converter::m_mutex.lock(); m_guiQueue.pushBack(ReGuiQueueItem(ReGuiQueueItem::StatusLine, NULL, message)); + Converter::m_mutex.unlock(); } /** @@ -406,6 +438,7 @@ void MainWindow::setStatusMessage(bool error, const QString& message){ */ void MainWindow::startStop(bool isStart){ ui->actionStart->setEnabled(!isStart); + ui->pushButtonShowOtherFiles->setEnabled(! isStart); ui->actionStop->setEnabled(isStart); ui->pushButtonConvert->setEnabled(! isStart); ui->pushButtonStop->setEnabled(isStart); diff --git a/appl/reimgconvert/mainwindow.hpp b/appl/reimgconvert/mainwindow.hpp index 05ececf..148371a 100644 --- a/appl/reimgconvert/mainwindow.hpp +++ b/appl/reimgconvert/mainwindow.hpp @@ -35,9 +35,10 @@ public: public: virtual void aboutToQuit(); bool error(const QString& message); + void finishTask(const QString& message); bool log(const QString& message); bool logAppendLast(const QString& message); - void onThreadStateChanged(Converter::State state, const QString& info); + void remoteLog(const QString& message); void setRemoteStatus(const QString& message); void setStatusMessage(bool error, const QString& message); public: @@ -52,14 +53,17 @@ private slots: void clear(); void guiTimerUpdate(); void onConvert(); + void onShowOtherFiles(); void onSourceFileSelect(); void onStop(); void onTemplateChangeIndex(const QString& text); - void selectSource(); + void onSelectSource(); void selectTarget(); private: Ui::MainWindow *ui; - Converter* m_converter; + TaskConverter* m_taskConvert; + TaskSearch* m_taskSearch; + TaskShowOther* m_taskShowOther; QLabel* m_statusMessage; ReLogger m_logger; ReGuiQueue m_guiQueue; diff --git a/appl/reimgconvert/mainwindow.ui b/appl/reimgconvert/mainwindow.ui index 21bcb38..dcd95ab 100644 --- a/appl/reimgconvert/mainwindow.ui +++ b/appl/reimgconvert/mainwindow.ui @@ -6,7 +6,7 @@ 0 0 - 823 + 958 783 @@ -20,520 +20,43 @@ ReImgConvert - + - - - - - - - 0 - 150 - - - - - 16777215 - 150 - - - - 0 - - - - Dimensions (quick) - - - - - - - - - 100 - 0 - - - - - 100 - 16777215 - - - - Template: - - - - - - - - 316 - 0 - - - - - Website: 1024x768 - - - - - Website II: 800x600 - - - - - Photo: 2048x1536 - - - - - Photo II: 3072x2304 - - - - - Midi: 600x400 - - - - - Mini: 150x100 - - - - - User defined - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - - 100 - 0 - - - - - 100 - 16777215 - - - - Max. Width: - - - - - - - - 100 - 0 - - - - - 100 - 16777215 - - - - true - - - - - - - - - - - - 100 - 0 - - - - - 100 - 16777215 - - - - Max. Height: - - - - - - - - 100 - 0 - - - - - 100 - 16777215 - - - - true - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - Dimensions (separated) - - - - - - - 230 - 100 - - - - - 230 - 100 - - - - Portrait: - - - - - 2 - 30 - 221 - 65 - - - - - - - - 100 - 0 - - - - - 100 - 16777215 - - - - Max. Width: - - - - - - - - 100 - 0 - - - - - 100 - 16777215 - - - - true - - - - - - - - 100 - 0 - - - - - 100 - 16777215 - - - - Max. Height: - - - - - - - - 100 - 0 - - - - - 100 - 16777215 - - - - true - - - - - - - - - - - - 230 - 100 - - - - - 230 - 100 - - - - Landscape: - - - - - 3 - 31 - 221 - 65 - - - - - - - - 100 - 0 - - - - - 100 - 16777215 - - - - Max. Width: - - - - - - - - 100 - 0 - - - - - 100 - 16777215 - - - - true - - - - - - - - 100 - 0 - - - - - 100 - 16777215 - - - - Max. Height: - - - - - - - - 100 - 0 - - - - - 100 - 16777215 - - - - true - - - - - - - - - - - - 150 - 100 - - - - - 150 - 100 - - - - Square: - - - - - 0 - 60 - 100 - 26 - - - - - 100 - 0 - - - - - 100 - 16777215 - - - - true - - - - - - 0 - 40 - 141 - 18 - - - - Max. Width/Height: - - - - - - - - Qt::Horizontal - - - - 47 - 20 - - - - - - groupBox_2 - groupBox_3 - groupBox - horizontalSpacer_2 - - - - - - - + + + + 0 + 150 + + + + + 16777215 + 150 + + + + 0 + + + + Dimensions (quick) + + + + + 11 + 11 + 561 + 30 + + + + + - 100 + 110 0 @@ -544,53 +67,85 @@ - File Pattern: + Template: - - + + - 100 + 390 0 - - - 100 - 16777215 - - - - true - + + + Website: 1024x768 + + + + + Website II: 800x600 + + + + + Photo: 2048x1536 + + + + + Photo II: 3072x2304 + + + + + Midi: 600x400 + + + + + Mini: 150x100 + + + + + User defined + + - - - - - 100 - 0 - + + + + Qt::Horizontal - + - 100 - 16777215 + 40 + 20 - - Dest. Type: - - + - - + + + + + + 13 + 62 + 560 + 30 + + + + + - 100 + 110 0 @@ -600,23 +155,16 @@ 16777215 - - - jpg - - - - - png - - + + Max. Width: + - - + + - 100 + 125 0 @@ -626,34 +174,16 @@ 16777215 - - A pattern of the source files with wildcards '*' (anything) and '?' (exact one char) - true - - - *.jpg - - - - - *.png - - - - - *.gif - - - - + + - 100 + 125 0 @@ -664,156 +194,31 @@ - Quality (%) + Max. Height: - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - Source Directory (Images): - - - - - - - - - true - - - /tmp/img - - - - - - - - 30 - 16777215 - - - - Auswahldialog - - - ... - - - - - - - - - - - - - - 100 - 0 - - - - - 100 - 16777215 - - - - Destination: - - - - - - - - - true - - - - - - - - - - - 50 - 0 - - - - - 50 - 16777215 - - - - ... - - - - - - - - - - - - - + - 150 + 125 0 - 150 + 100 16777215 - - Converts the images - - - &Convert - - - - :/main/icons/action_go.png:/main/icons/action_go.png + + true - + Qt::Horizontal @@ -825,72 +230,732 @@ - - - - Clears the list - - - C&lear - - - Ctrl+L + + + + + + Dimensions (separated) + + + + + + + 250 + 100 + + + + + 230 + 100 + + + + Portrait: + + + + + 2 + 30 + 234 + 65 + + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + Max. Width: + + + + + + + + 125 + 0 + + + + + 100 + 16777215 + + + + true + + + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + Max. Height: + + + + + + + + 125 + 0 + + + + + 100 + 16777215 + + + + true + + + + - - - - - Qt::Horizontal - - - - 40 - 20 - + + + + + + + 250 + 100 + + + + + 230 + 100 + + + + Landscape: + + + + + 3 + 31 + 234 + 65 + - - - - - - true + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + Max. Width: + + + + + + + + 125 + 0 + + + + + 100 + 16777215 + + + + true + + + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + Max. Height: + + + + + + + + 125 + 0 + + + + + 100 + 16777215 + + + + true + + + + + + + + + + + + 250 + 100 + + + + + 150 + 100 + + + + Square: + + + + + 0 + 60 + 125 + 26 + - 150 + 125 0 - 150 + 100 16777215 - - Stops the conversion + + true - - &Stop + + + + + 0 + 40 + 141 + 18 + - - - :/main/icons/cancel.png:/main/icons/cancel.png + + Max. Width/Height: - - - - - - - - listWidget - tabWidget - + + + + + + Qt::Horizontal + + + + 47 + 20 + + + + + + groupBox_2 + groupBox_3 + groupBox + horizontalSpacer_2 + + + + + + + + 125 + 0 + + + + + 100 + 16777215 + + + + Quality (%): + + + + + + + + 125 + 0 + + + + + 100 + 16777215 + + + + true + + + + + + + + 125 + 0 + + + + + 100 + 16777215 + + + + File Pattern: + + + + + + + + 125 + 0 + + + + + 100 + 16777215 + + + + A pattern of the source files with wildcards '*' (anything) and '?' (exact one char) + + + true + + + + *.jpg + + + + + *.png + + + + + *.gif + + + + + + + + + 125 + 0 + + + + + 100 + 16777215 + + + + Dest. Type: + + + + + + + + 125 + 0 + + + + + 100 + 16777215 + + + + + jpg + + + + + png + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + Source Directory (Images): + + + + + + + + + true + + + /tmp/img + + + + + + + + 30 + 16777215 + + + + Auswahldialog + + + ... + + + + + + + + + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + Destination: + + + + + + + + + true + + + + + + + + + + + 50 + 0 + + + + + 50 + 16777215 + + + + ... + + + + + + + + + + + + + + + + 125 + 0 + + + + Process the subdirectories too + + + Recursive + + + + + + + + 125 + 0 + + + + Files not matching the file pattern will be copied too (and not ignored) + + + Copy other files + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 150 + 0 + + + + Show other files + + + + + + + + + + + + 150 + 0 + + + + + 150 + 16777215 + + + + Converts the images + + + &Convert + + + + :/main/icons/action_go.png:/main/icons/action_go.png + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 150 + 0 + + + + Clears the list + + + C&lear + + + Ctrl+L + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + true + + + + 150 + 0 + + + + + 150 + 16777215 + + + + Stops the conversion + + + &Stop + + + + :/main/icons/cancel.png:/main/icons/cancel.png + + + + + + + + @@ -898,7 +963,7 @@ 0 0 - 823 + 958 26