--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>AboutDialog</class>
+ <widget class="QDialog" name="AboutDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>225</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>About</string>
+ </property>
+ <widget class="QTextEdit" name="textEdit">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>20</y>
+ <width>351</width>
+ <height>141</height>
+ </rect>
+ </property>
+ <property name="html">
+ <string><!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></string>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="pushButton">
+ <property name="geometry">
+ <rect>
+ <x>280</x>
+ <y>180</y>
+ <width>93</width>
+ <height>27</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&OK</string>
+ </property>
+ </widget>
+ <action name="action_OK">
+ <property name="text">
+ <string>&OK</string>
+ </property>
+ </action>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>action_OK</sender>
+ <signal>triggered()</signal>
+ <receiver>AboutDialog</receiver>
+ <slot>close()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>-1</x>
+ <y>-1</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>199</x>
+ <y>112</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
--- /dev/null
+/*
+ * 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 "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;
+}
--- /dev/null
+/*
+ * 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 ABOUTDIALOG_HPP
+#define ABOUTDIALOG_HPP
+
+#include <QDialog>
+
+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
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>AboutDialog</class>
+ <widget class="QDialog" name="AboutDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>423</width>
+ <height>289</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <property name="modal">
+ <bool>true</bool>
+ </property>
+ <widget class="QTextEdit" name="textEdit">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>20</y>
+ <width>381</width>
+ <height>221</height>
+ </rect>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ <property name="html">
+ <string><!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></string>
+ </property>
+ <property name="acceptRichText">
+ <bool>false</bool>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ <widget class="QWidget" name="layoutWidget">
+ <property name="geometry">
+ <rect>
+ <x>20</x>
+ <y>250</y>
+ <width>381</width>
+ <height>29</height>
+ </rect>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Version:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelVersion">
+ <property name="text">
+ <string>2015.05.00</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pushButtonOK">
+ <property name="text">
+ <string>&OK</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>pushButtonOK</sender>
+ <signal>clicked()</signal>
+ <receiver>AboutDialog</receiver>
+ <slot>close()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>196</x>
+ <y>183</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>199</x>
+ <y>108</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
* 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 "../../base/rebase.hpp"
#include "converter.hpp"
#include "mainwindow.hpp"
+#include <QRegularExpression>
+#include <QRegExp>
/** @mainpage A converter for images.
*
*
* @section install_sec Installation
*
- * Copy rplshrink and img_conv.pl into a directory inserted in the executable
+ * Copy reimgconvert into a directory inserted in the executable
* path, e.g. /usr/local/bin and give them the right "executable".
*
* @subsection req_sec Requirements
*
* <ul>
* <li>ImageMagick</li>
- * <li>Perl</li>
* </ul>
*
* @section prog_sec Programming Features
*
* <ul>
* <li>V1.0 Basic version. Predefined (static) values of the combo boxes.
- * User language is German only.
+ * User language is English only.
* </li>
* </ul>
*
* @brief Implements a specific exception for the converter.
*
* Will be used on errors.
-*/
+ */
/** @class ConvertLogger converter.hpp "converter.hpp"
*
* @brief Implements an abstract base class for logging.
-*/
-
+ */
/** @class Converter converter.hpp "converter.hpp"
*
*
*/
+QString sizeToString(qint64 size);
+
/**
* @brief Constructor.
*
* @param mainWindow the window. Will be used for output
*/
Converter::Converter(const QString& directory, const QString& targetDirectory,
- int landscapeX, int landscapeY,
- int portraitX, int portraitY,
- int squareX, int quality,
- MainWindow* mainWindow) :
- m_dir(directory),
- m_targetDir(targetDirectory.indexOf(QDir::separator()) >= 0
- ? targetDirectory
- : directory + QDir::separator() + targetDirectory),
- m_landscapeWidth(landscapeX),
- m_landscapeHeight(landscapeY),
- m_portraitWidth(portraitX),
- m_portraitHeight(portraitY),
- m_squareWidth(squareX),
- m_quality(quality),
- m_mainWindows(mainWindow),
- m_script(new QProcess()),
- m_shouldStop(false)
-{
+ const QString& sourcePattern, const QString& targetType, int landscapeX,
+ int landscapeY, int portraitX, int portraitY, int squareX, int quality,
+ MainWindow* mainWindow) :
+ m_dir(directory),
+ m_targetDir(
+ targetDirectory.indexOf(QDir::separator()) >= 0 ?
+ targetDirectory :
+ directory + QDir::separator() + 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){
}
/**
* @brief Destructor.
*/
-Converter::~Converter()
-{
- delete m_script;
+Converter::~Converter(){
+ delete m_imageInfo;
}
/**
* @param prefix the string starting the argument
* @param value the value of the argument
*/
-void addArg(QStringList& args, const char* prefix, int value)
-{
- QString arg;
- arg.sprintf("%s%d", prefix, value);
- args << arg;
+void addArg(QStringList& args, const char* prefix, int value){
+ QString arg;
+ arg.sprintf("%s%d", prefix, value);
+ args << arg;
}
/**
- * @brief Builds the arguments of the script call.
+ * @brief Changes the state of the thread.
*
- * @return true: OK<br>
- * false: error occurred
+ * @param state the new state
+ * @param info an info about the change
*/
-bool Converter::buildArgs()
-{
- bool rc = true;
- m_args.clear();
- m_args << "-v";
- if (m_landscapeHeight > 0)
- addArg(m_args, "-lw", m_landscapeHeight);
- else if (m_landscapeWidth > 0)
- addArg(m_args, "-lh", m_landscapeWidth);
- else
- rc = error("keine/falsche Maximalangabe beim Breitformat");
-
- if (m_portraitWidth > 0)
- addArg(m_args, "-pw", m_portraitWidth);
- else if (m_portraitHeight > 0)
- addArg(m_args, "-ph", m_portraitHeight);
- else
- rc = error("keine/falsche Maximalangabe beim Hochformat");
-
- if (m_squareWidth > 0)
- addArg(m_args, "-sw", m_squareWidth);
- else
- rc = error("keine/falsche Maximalangabe beim Hochformat");
-
- if (m_quality < 10 || m_quality > 100)
- rc = error("keine/falsche Qualität");
- else
- addArg(m_args, "-q", m_quality);
-
- return rc;
+void Converter::changeState(Converter::State state, const QString& info){
+ m_mainWindows->on_threadStateChanged(state, info);
}
/**
- * @brief Changes the state of the thread.
+ * Reads the image properties from an image file.
*
- * @param state the new state
- * @param info an info about the change
+ * @param name filename with path
+ * @param width OUT: the width of the image
+ * @param height OUT: the height of the image
+ * @param info OUT: information of the image
+ * @return <code>true</code>: success<br>
+ * <code>false</code>: cannot retrieve the image data
*/
-void Converter::changeState(Converter::State state, const QString& info)
-{
- m_mainWindows->on_threadStateChanged(state, info);
+/**
+ * Converts an image into another format.
+ *
+ * @param source the source filename with path
+ * @param target the target filename with path
+ * @param width the old width of the image
+ * @param height the old height of the image
+ * @param widthNew the new width of the image
+ * @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,
+ int height, int widthNew, int heightNew, int quality){
+ QStringList args;
+ // convert -size 100x200 source.png -resize 50x100 target.jpg";
+ args << "-size" << QString::number(width) + "x" + QString::number(height);
+ args << source;
+ if (quality > 0)
+ args << "-quality" << QString::number(quality);
+ args << "-resize"
+ << QString::number(widthNew) + "x" + QString::number(heightNew);
+ args << target;
+ QProcess process;
+ process.start("/usr/bin/convert", args);
+ QByteArray output;
+ while (process.waitForReadyRead()){
+ output = process.readAll();
+ }
+ output = process.readAllStandardError();
+ if (!output.isEmpty())
+ error(output);
+ process.close();
}
/**
- * @brief Runs the thread's task.
+ * @brief Converts one file.
*
- * <ul>
- *<li>Makes the target directory (if necessary)</li>
- *<li>Search the images *.png / *.jpg and converts them</li>
- *<ul>
+ * @param source the file's name with path
+ * @param target the new filename with path
+ * @param size the size of the file (in byte)
*/
-void Converter::run()
-{
- QString msg;
- int no = 0;
- try {
- if (! m_dir.exists())
- error("Verzeichnis existiert nicht: " + 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("Kann Zielverzeichnis nicht anlegen: " + m_targetDir.absolutePath());
- }
- QStringList names;
- names.append("*.jpg");
- names.append("*.JPG");
- names.append("*.png");
- names.append("*.PNG");
- changeState(Converter::STATE_STARTING, "");
- buildArgs();
- m_shouldStop = false;
- QDirIterator it(m_dir.absolutePath(), names);
- while(it.hasNext()){
- if (m_shouldStop){
- log("Abbruch durch Benutzer");
- break;
+void Converter::convertOneFile(const QString& source, const QString& target,
+ qint64 size){
+ int width = 0;
+ int height = 0;
+ QString info;
+ clock_t start = clock();
+ if (readProperties(source, width, height, info)){
+ bool doConvert = false;
+ int widthNew, heightNew;
+ if (abs(width - height) < 5){
+ // Square format:
+ doConvert = width > m_squareWidth;
+ if (doConvert)
+ widthNew = heightNew = m_squareWidth;
+ }else if (width > height){
+ // Landscape:
+ doConvert = width > m_landscapeWidth || height > m_landscapeHeight;
+ if (doConvert){
+ if (width > m_landscapeWidth && m_landscapeWidth > 0){
+ widthNew = m_landscapeWidth;
+ heightNew = height * m_landscapeWidth / width;
+ }else{
+ heightNew = m_landscapeHeight;
+ widthNew = width * m_landscapeHeight / height;
}
- no++;
- it.next();
- QString path = it.path();
- qint64 length = it.fileInfo().size();
- path += QDir::separator();
- path += it.fileName();
- convertOneFile(path, length);
-
- msg.sprintf("%4d Datei(en) konvertiert", no);
- changeState(Converter::STATE_SUB_TASK_STOPPED, msg);
- }
- } catch(ConverterException exc){
- log("Abarbeitung wegen Fehlers gestoppt: " + exc.message());
- }
- msg.sprintf("%d Datei(en) konvertiert", no);
- changeState(Converter::STATE_READY, msg);
+ }
+ }else{
+ // Portrait
+ doConvert = width > m_portraitWidth || height > m_portraitHeight;
+ if (doConvert){
+ if (width > m_portraitWidth && m_portraitWidth > 0){
+ widthNew = m_portraitWidth;
+ heightNew = height * m_portraitWidth / width;
+ }else{
+ heightNew = m_portraitHeight;
+ widthNew = width * m_portraitHeight / height;
+ }
+ }
+ }
+ log(
+ source + " " + info + " " + sizeToString(size)
+ + QString(" -> %1x%2 ").arg(widthNew).arg(heightNew));
+ convert(source, target, width, height, widthNew, heightNew, m_quality);
+ struct stat info;
+ if (stat(target.toUtf8().constData(), &info) == 0)
+ m_mainWindows->logAppendLast(sizeToString(info.st_size) + " ");
+ }
+ m_mainWindows->logAppendLast(
+ QString("").sprintf("%.3f sec",
+ double(clock() - start) / CLOCKS_PER_SEC));
}
/**
- * Reads the image properties from an image file.
+ * @brief Logs an error message.
*
- * @param name filename with path
- * @param width OUT: the width of the image
- * @param height OUT: the height of the image
- * @param info OUT: information of the image
+ * @param message the message to log
+ * @return <code>false</code>
+ * @throws ConverterException
*/
-void Converter::readProperties(const QString& name, int& width, int& height, QString& info)
-{
-
+bool Converter::error(const QString& message){
+ m_mainWindows->log(message);
+ throw ConverterException(message);
+ return false;
}
/**
- * @brief Search for the Perl script which make the conversion itself.
+ * @brief Logs a message.
*
- * @param node the name of script without path.
- * @return the full name of the script (with path)
+ * @param message the message to log
+ * @return <code>true</code>
*/
-QString findScript(const QString& node)
-{
- static QString rc;
- if (rc.isEmpty()){
-
- 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;
+bool Converter::log(const QString& message){
+ printf("%s\n", message.toUtf8().constData());
+ m_mainWindows->log(message);
+ return true;
}
+
/**
- * @brief Converts the size into a human readable string.
+ * Reads the image properties using the external program "identify".
*
- * @param size the size in bytes
- * @return the size as human readable string, e.g. "2MiByte"
+ * @param name the filename with path
+ * @param width OUT: the width of the image
+ * @param height OUT: the height of the image
+ * @param info OUT: an info about the image
+ * @return <code>true</code>: success
+ * <code>false</code>: properties not readable
*/
-QString sizeToString(qint64 size)
-{
- QString rc;
- if (size < 10*1024)
- rc.sprintf("%d Bytes", (int) size);
- else if (size < qint64(10*1024*1024))
- rc.sprintf("%d KiBytes", (int) (size / 1024));
- else if (size < qint64(10*1024*1024)*1024)
- rc.sprintf("%d MiBytes", (int) (size / 1024 / 1024));
- else
- rc.sprintf("%d GiBytes", (int) (size / 1024 / 1024 / 1024));
- return rc;
+bool Converter::readProperties(const QString& name, int& width, int& height,
+ QString& info){
+ QStringList args;
+ args << name;
+ QProcess process;
+ process.start("/usr/bin/identify", args);
+ QByteArray output;
+ bool rc = false;
+ while (process.waitForReadyRead()){
+ output = process.readAll();
+ QRegularExpressionMatch match = m_imageInfo->match(output);
+ if (!match.hasMatch())
+ error(
+ QObject::tr("I am confused (wrong image data):\n%1\nExpected: %2").arg(
+ output.constData()).arg(m_imageInfo->pattern()));
+ else{
+ width = match.captured(m_groupWidth).toInt();
+ height = match.captured(m_groupHeight).toInt();
+ rc = true;
+ info = QString("%1x%2").arg(width).arg(height);
+ break;
+ }
+ }
+ output = process.readAll();
+ output = process.readAllStandardError();
+ if (!output.isEmpty())
+ error(output);
+ process.close();
+ return rc;
}
/**
- * @brief Converts one file.
+ * @brief Runs the thread's task.
*
- * @param file the file's name
- * @param size the size of the file (in byte)
+ * <ul>
+ *<li>Makes the target directory (if necessary)</li>
+ *<li>Search the images *.png / *.jpg and converts them</li>
+ *<ul>
*/
-void Converter::convertOneFile(const QString& file, qint64 size)
-{
- QString node("img_trans.pl");
- log(file + " " + sizeToString(size));
- QString script(findScript(node));
- if (script.isEmpty())
- error("Script nicht gefunden: " + node);
- else {
- QStringList args;
- args << script << m_args << file << m_targetDir.absolutePath();
- m_script->start("/usr/bin/perl", args);
- QByteArray output;
- while (m_script->waitForReadyRead()){
- output = m_script->readAll();
- QList<QByteArray> lines = output.split('\n');
- QList<QByteArray>::iterator it;
- for (it = lines.begin(); it != lines.end(); it++){
- log(*it);
- }
- }
- output = m_script->readAllStandardError();
- if (!output.isEmpty())
- error(output);
- m_script->close();
- }
+void Converter::run(){
+ QString msg;
+ int no = 0;
+ 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, "");
+ 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 = ReQStringUtil::replaceExtension(node,
+ "." + m_targetType);
+ QString target = m_targetDir.absoluteFilePath(nodeTarget);
+ convertOneFile(path, target, length);
+ }
+ }
+ changeState(Converter::STATE_SUB_TASK_STOPPED, msg);
+ } catch (ConverterException exc){
+ log(
+ QObject::tr("Execution stopped because of error(s): ")
+ + exc.message());
+ }
+ msg = QObject::tr("%1 file(s) converted").arg(no);
+ changeState(Converter::STATE_READY, msg);
+ m_mainWindows->switchRun(true);
}
/**
- * @brief Logs a message.
+ * @brief Search for the Perl script which make the conversion itself.
*
- * @param message the message to log
- * @return <code>true</code>
+ * @param node the name of script without path.
+ * @return the full name of the script (with path)
*/
-bool Converter::log(const QString& message)
-{
- printf ("%s\n", message.toUtf8().constData());
- m_mainWindows->log(message);
- return true;
-}
+QString findScript(const QString& node){
+ static QString rc;
+ if (rc.isEmpty()){
+ 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;
+}
/**
- * @brief Logs an error message.
+ * @brief Converts the size into a human readable string.
*
- * @param message the message to log
- * @return <code>false</code>
- * @throws ConverterException
+ * @param size the size in bytes
+ * @return the size as human readable string, e.g. "2MiByte"
*/
-bool Converter::error(const QString& message)
-{
- m_mainWindows->log(message);
- throw ConverterException(message);
- return false;
+QString sizeToString(qint64 size){
+ QString rc;
+ if (size < 10 * 1024)
+ rc.sprintf("%d Bytes", (int) size);
+ else if (size < qint64(10 * 1024 * 1024))
+ rc.sprintf("%d KiBytes", (int) (size / 1024));
+ else if (size < qint64(10 * 1024 * 1024) * 1024)
+ rc.sprintf("%d MiBytes", (int) (size / 1024 / 1024));
+ else
+ rc.sprintf("%d GiBytes", (int) (size / 1024 / 1024 / 1024));
+ return rc;
}
* 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 CONVERTER_HPP
#define CONVERTER_HPP
#include <QThread>
class MainWindow;
-class ConverterException{
+class ConverterException {
public:
- ConverterException(const QString& message) : m_message(message)
- {}
- const QString& message() const
- { return m_message; }
+ ConverterException(const QString& message) :
+ m_message(message){
+ }
+ const QString& message() const{
+ return m_message;
+ }
private:
- QString m_message;
+ QString m_message;
};
-class ConvertLogger{
+class ConvertLogger {
public:
- virtual bool log(const QString& message) = 0;
- virtual bool error(const QString& message) = 0;
+ virtual bool log(const QString& message) = 0;
+ virtual bool error(const QString& message) = 0;
};
-class Converter : public QThread
-{
- Q_OBJECT
+class Converter: public QThread {
+ Q_OBJECT
public:
- enum State {
- STATE_UNDEF,
- STATE_STARTING,
- STATE_SUB_TASK_STOPPED,
- STATE_READY,
- };
+ enum State {
+ STATE_UNDEF, STATE_STARTING, STATE_SUB_TASK_STOPPED, STATE_READY,
+ };
public:
- Converter(const QString& directory, const QString& targetDirectory,
- int landscapeX, int landscapey,
- int portraitX, int portraitY,
- int squareX, int quality, MainWindow* mainWindows);
- ~Converter();
+ Converter(const QString& directory, const QString& targetDirectory,
+ const QString& sourcePattern, const QString& targetType, int landscapeX,
+ int landscapey, int portraitX, int portraitY, int squareX, int quality,
+ MainWindow* mainWindows);
+ ~Converter();
public:
- bool log(const QString& message);
- bool error(const QString& message);
- void run();
- void stop(){
- m_shouldStop = true;
- }
+ bool error(const QString& message);
+ bool log(const QString& message);
+ void run();
+ void stop(){
+ m_shouldStop = true;
+ }
protected:
- void readProperties(const QString& name, int &width, int &height, QString &info);
- void convertOneFile(const QString& name, qint64 size);
- bool buildArgs();
- void changeState(State state, const QString& info);
+ 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);
+ bool readProperties(const QString& name, int &width, int &height,
+ QString &info);
private:
- QDir m_dir;
- QDir m_targetDir;
- int m_landscapeWidth;
- int m_landscapeHeight;
- int m_portraitWidth;
- int m_portraitHeight;
- int m_squareWidth;
- int m_quality;
- MainWindow* m_mainWindows;
- QProcess* m_script;
- QStringList m_args;
- bool m_shouldStop;
+ 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;
};
-
#endif // CONVERTER_HPP
* 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 <QApplication>
char** g_argv;
-int main(int argc, char *argv[])
-{
- g_argv = argv;
- QApplication a(argc, argv);
- MainWindow w;
- w.show();
+int main(int argc, char *argv[]){
+ g_argv = argv;
+ QApplication a(argc, argv);
+ MainWindow w;
+ w.show();
- return a.exec();
+ return a.exec();
}
* 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"
+#include "aboutdialog.hpp"
+
+const QString VERSION("2015.05.31");
/** @class MainWindow mainwindow.hpp "mainwindow.hpp"
*
* @param parent NULL or the parent (who destroys the objects at the end)
*/
MainWindow::MainWindow(QWidget *parent) :
- QMainWindow(parent),
- ui(new Ui::MainWindow),
- m_converter(NULL)
-{
- ui->setupUi(this);
- QStringList defaultX;
- defaultX.append("*");
- defaultX.append("1024");
- defaultX.append("1920");
- defaultX.append("800");
- QStringList defaultY;
- defaultY.append("*");
- defaultY.append("768");
- defaultY.append("1050");
- defaultY.append("600");
- QStringList quality;
- quality.append("70");
- quality.append("85");
- quality.append("100");
- QStringList target;
- target.append("normal");
- target.append("mini");
- target.append("1024");
- target.append("1920");
- ui->comboLandscapeX->addItems(defaultX);
- ui->comboLandscapeY->addItems(defaultY);
- ui->comboPortraitX->addItems(defaultX);
- ui->comboPortraitY->addItems(defaultY);
- ui->comboSquareX->addItems(defaultX);
- ui->comboQuality->addItems(quality);
- ui->comboTarget->addItems(target);
- ui->comboLandscapeX->setCurrentText("1024");
- ui->comboLandscapeY->setCurrentText("*");
- ui->comboPortraitX->setCurrentText("*");
- ui->comboPortraitY->setCurrentText("768");
- ui->comboSquareX->setCurrentText("768");
- ui->comboQuality->setCurrentText("70");
- ui->comboTarget->setCurrentText("normal");
- ui->buttonStop->hide();
+ QMainWindow(parent), ui(new Ui::MainWindow), m_converter(NULL){
+ ui->setupUi(this);
+ switchRun(true);
+ QStringList defaultX;
+ defaultX.append("*");
+ defaultX.append("1024");
+ defaultX.append("1920");
+ defaultX.append("800");
+ QStringList defaultY;
+ defaultY.append("*");
+ defaultY.append("768");
+ defaultY.append("1050");
+ defaultY.append("600");
+ QStringList quality;
+ quality.append("70");
+ quality.append("85");
+ quality.append("100");
+ QStringList target;
+ target.append("normal");
+ target.append("mini");
+ target.append("1024");
+ target.append("1920");
+ ui->comboLandscapeX->addItems(defaultX);
+ ui->comboLandscapeY->addItems(defaultY);
+ ui->comboPortraitX->addItems(defaultX);
+ ui->comboPortraitY->addItems(defaultY);
+ ui->comboSquareX->addItems(defaultX);
+ ui->comboQuality->addItems(quality);
+ ui->comboTarget->addItems(target);
+ ui->comboLandscapeX->setCurrentText("1024");
+ ui->comboLandscapeY->setCurrentText("*");
+ ui->comboPortraitX->setCurrentText("*");
+ ui->comboPortraitY->setCurrentText("768");
+ ui->comboSquareX->setCurrentText("768");
+ ui->comboQuality->setCurrentText("70");
+ ui->comboTarget->setCurrentText("normal");
+ ui->buttonStop->hide();
+
+ connect(ui->actionSelectDestination, SIGNAL(triggered()), this,
+ SLOT(selectDestination()));
+ connect(ui->pushButtonSelectDest, SIGNAL(clicked()), this,
+ SLOT(selectDestination()));
+ connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(about()));
+
+}
+
+/**
+ * Selects the destination directory with a dialog.
+ */
+void MainWindow::selectDestination(){
+ QString dir = QFileDialog::getExistingDirectory(this,
+ tr("Select Destination Directory"), ui->comboTarget->currentText(),
+ QFileDialog::ShowDirsOnly);
+ if (!dir.isEmpty())
+ ui->comboTarget->setCurrentText(dir);
}
/**
* @brief Destructor
*/
-MainWindow::~MainWindow()
-{
- delete ui;
- delete m_converter;
+MainWindow::~MainWindow(){
+ delete ui;
+ delete m_converter;
+}
+
+/**
+ * Starts the about dialog.
+ */
+void MainWindow::about(){
+ AboutDialog dialog(VERSION);
+ dialog.exec();
}
/**
* @param message the message to log
* @return <code>true</code>
*/
-bool MainWindow::log(const QString& message)
-{
- ui->listWidget->addItem(message);
- return true;
+bool MainWindow::log(const QString& message){
+ ui->listWidget->insertItem(0, message);
+ return true;
+}
+
+/**
+ * @brief Logs a message
+ *
+ * @param message the message to log
+ * @return <code>true</code>
+ */
+bool MainWindow::logAppendLast(const QString& message){
+ QListWidgetItem* item = ui->listWidget->item(0);
+ item->setText(item->text() + " " + message);
+ return true;
+}
+
+/**
+ * Enables/disables the buttons/actions relevant for running.
+ *
+ * @param runActive <code>true</code>: the conversion is possible
+ */
+void MainWindow::switchRun(bool runActive){
+ if (runActive){
+ ui->buttonConvert->show();
+ ui->buttonStop->hide();
+ }else{
+ ui->buttonConvert->hide();
+ ui->buttonStop->show();
+ }
+ ui->actionConvert->setEnabled(runActive);
+ ui->actionStop->setEnabled(not runActive);
}
/**
* @brief Handles the button click on "convert".
*/
-void MainWindow::on_buttonConvert_clicked()
-{
- ui->buttonConvert->hide();
- ui->buttonStop->show();
- delete m_converter;
- m_converter = new Converter(ui->comboSourceDir->currentText(),
- ui->comboLandscapeX->currentText(),
- atol(ui->comboLandscapeX->currentText().toLatin1().constData()),
- atol(ui->comboLandscapeY->currentText().toLatin1().constData()),
- atol(ui->comboPortraitX->currentText().toLatin1().constData()),
- atol(ui->comboPortraitY->currentText().toLatin1().constData()),
- atol(ui->comboSquareX->currentText().toLatin1().constData()),
- atol(ui->comboQuality->currentText().toLatin1().constData()),
- this);
- // start the thread:
- m_converter->start();
+void MainWindow::on_buttonConvert_clicked(){
+ switchRun(false);
+ delete m_converter;
+ m_converter = new Converter(ui->comboSourceDir->currentText(),
+ ui->comboLandscapeX->currentText(),
+ ui->comboBoxSourcePattern->currentText(),
+ ui->comboBoxDestType->currentText(),
+ atol(ui->comboLandscapeX->currentText().toLatin1().constData()),
+ atol(ui->comboLandscapeY->currentText().toLatin1().constData()),
+ atol(ui->comboPortraitX->currentText().toLatin1().constData()),
+ atol(ui->comboPortraitY->currentText().toLatin1().constData()),
+ atol(ui->comboSquareX->currentText().toLatin1().constData()),
+ atol(ui->comboQuality->currentText().toLatin1().constData()), this);
+ // start the thread:
+ m_converter->start();
}
/**
* @param state the new state of the thread
* @param info info about the new state. Not used
*/
-void MainWindow::on_threadStateChanged(Converter::State state,
- const QString&)
-{
- switch(state){
- case Converter::STATE_READY:
- ui->buttonConvert->show();
- ui->buttonStop->hide();
- //ui->statusBar->showMessage(info);
- break;
- case Converter::STATE_SUB_TASK_STOPPED:
- //ui->statusBar->showMessage(info);
- break;
- case Converter::STATE_STARTING:
- default:
- break;
- }
+void MainWindow::on_threadStateChanged(Converter::State state, const QString&){
+ switch (state) {
+ case Converter::STATE_READY:
+ ui->buttonConvert->show();
+ ui->buttonStop->hide();
+ //ui->statusBar->showMessage(info);
+ break;
+ case Converter::STATE_SUB_TASK_STOPPED:
+ //ui->statusBar->showMessage(info);
+ break;
+ case Converter::STATE_STARTING:
+ default:
+ break;
+ }
}
/**
* @brief Handles the click on the button "stop".
*/
-void MainWindow::on_buttonStop_clicked()
-{
- m_converter->stop();
- ui->buttonConvert->show();
- ui->buttonStop->hide();
+void MainWindow::on_buttonStop_clicked(){
+ m_converter->stop();
+ ui->buttonConvert->show();
+ ui->buttonStop->hide();
}
/**
* Shows a selection dialog for directories and sets the source directory
* onto the selected directory.
*/
-void MainWindow::on_buttonFileSelect_clicked()
-{
- QFileDialog selection;
- selection.setFileMode(QFileDialog::DirectoryOnly);
- QString dir = ui->comboSourceDir->currentText();
- if (! dir.isEmpty())
- selection.setDirectory(dir);
- if (selection.exec())
- ui->comboSourceDir->setCurrentText(selection.selectedFiles().at(0));
+void MainWindow::on_buttonFileSelect_clicked(){
+ QFileDialog selection;
+ selection.setFileMode(QFileDialog::DirectoryOnly);
+ QString dir = ui->comboSourceDir->currentText();
+ if (!dir.isEmpty())
+ selection.setDirectory(dir);
+ if (selection.exec())
+ ui->comboSourceDir->setCurrentText(selection.selectedFiles().at(0));
}
-
* 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
class MainWindow;
}
-class MainWindow : public QMainWindow, public ConvertLogger
-{
- Q_OBJECT
+class MainWindow: public QMainWindow, public ConvertLogger {
+ Q_OBJECT
public:
- explicit MainWindow(QWidget *parent = 0);
- ~MainWindow();
+ explicit MainWindow(QWidget *parent = 0);
+ ~MainWindow();
public:
- bool log(const QString& message);
- bool error(const QString& message){
- log("+++ " + message); return false;
- }
-private slots:
- void on_buttonFileSelect_clicked();
-
- void on_buttonStop_clicked();
-
- void on_buttonConvert_clicked();
-public slots:
- void on_threadStateChanged(Converter::State state, const QString& info);
+ bool error(const QString& message){
+ log("+++ " + message);
+ return false;
+ }
+ bool log(const QString& message);
+ bool logAppendLast(const QString& message);
+ void switchRun(bool runActive);private slots:
+ void about();
+ void on_buttonFileSelect_clicked();
+ void on_buttonStop_clicked();
+ void on_buttonConvert_clicked();
+ void selectDestination();public slots:
+ void on_threadStateChanged(Converter::State state, const QString& info);
private:
- Ui::MainWindow *ui;
- Converter* m_converter;
+ Ui::MainWindow *ui;
+ Converter* m_converter;
};
#endif // MAINWINDOW_HPP
<rect>
<x>0</x>
<y>0</y>
- <width>735</width>
- <height>532</height>
+ <width>772</width>
+ <height>556</height>
</rect>
</property>
<property name="minimumSize">
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QWidget" name="widget" native="true">
- <layout class="QVBoxLayout" name="verticalLayout_3">
+ <layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
</widget>
</widget>
</item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="minimumSize">
</widget>
</widget>
</item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="minimumSize">
</item>
</layout>
</item>
- <item>
- <spacer name="horizontalSpacer_2">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
</layout>
</item>
<item>
<property name="title">
<string>Others:</string>
</property>
- <widget class="QPushButton" name="pushButtonSelectDest">
- <property name="geometry">
- <rect>
- <x>640</x>
- <y>70</y>
- <width>51</width>
- <height>27</height>
- </rect>
- </property>
- <property name="text">
- <string>...</string>
- </property>
- </widget>
- <widget class="QWidget" name="layoutWidget3">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>30</y>
- <width>221</width>
- <height>28</height>
- </rect>
- </property>
- <layout class="QFormLayout" name="formLayout_3">
- <item row="0" column="0">
- <widget class="QLabel" name="label_6">
- <property name="minimumSize">
- <size>
- <width>100</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>100</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string>Quality (%)</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QComboBox" name="comboQuality">
- <property name="minimumSize">
- <size>
- <width>100</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>100</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="editable">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="layoutWidget4">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>70</y>
- <width>631</width>
- <height>28</height>
- </rect>
- </property>
- <layout class="QFormLayout" name="formLayout_4">
- <item row="0" column="0">
- <widget class="QLabel" name="label_7">
- <property name="minimumSize">
- <size>
- <width>100</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>100</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string>Destination: </string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QComboBox" name="comboTarget">
- <property name="editable">
- <bool>true</bool>
- </property>
- <property name="currentText">
- <string/>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="layoutWidget5">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>110</y>
- <width>631</width>
- <height>28</height>
- </rect>
- </property>
- <layout class="QHBoxLayout" name="horizontalLayout_4">
- <item>
- <widget class="QLabel" name="label_2">
- <property name="minimumSize">
- <size>
- <width>100</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>100</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string>Template:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QComboBox" name="comboBox">
- <item>
- <property name="text">
- <string>Website: 1024x768</string>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_7">
+ <item>
+ <layout class="QFormLayout" name="formLayout_3">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_6">
+ <property name="minimumSize">
+ <size>
+ <width>100</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>100</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Quality (%)</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="comboQuality">
+ <property name="minimumSize">
+ <size>
+ <width>100</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>100</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="editable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
</property>
- </item>
- <item>
- <property name="text">
- <string>Website II: 800x600</string>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
</property>
- </item>
- <item>
- <property name="text">
- <string>Photo: 2048x1536</string>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QFormLayout" name="formLayout_5">
+ <property name="fieldGrowthPolicy">
+ <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
- </item>
- <item>
- <property name="text">
- <string>Photo II: 3072x2304</string>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_10">
+ <property name="minimumSize">
+ <size>
+ <width>100</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>100</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>File Pattern:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="comboBoxSourcePattern">
+ <property name="minimumSize">
+ <size>
+ <width>100</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>100</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>A pattern of the source files with wildcards '*' (anything) and '?' (exact one char)</string>
+ </property>
+ <property name="editable">
+ <bool>true</bool>
+ </property>
+ <item>
+ <property name="text">
+ <string notr="true">*.jpg</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string notr="true">*.png</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>*.gif</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
</property>
- </item>
- <item>
- <property name="text">
- <string>Midi: 600x400</string>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
</property>
- </item>
- <item>
- <property name="text">
- <string>Mini: 150x100</string>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QFormLayout" name="formLayout_6">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_11">
+ <property name="minimumSize">
+ <size>
+ <width>100</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>100</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Dest. Type:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="comboBoxDestType">
+ <property name="minimumSize">
+ <size>
+ <width>100</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>100</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <item>
+ <property name="text">
+ <string notr="true">jpg</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string notr="true">png</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_6">
+ <item>
+ <widget class="QLabel" name="label_7">
+ <property name="minimumSize">
+ <size>
+ <width>100</width>
+ <height>0</height>
+ </size>
</property>
- </item>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="layoutWidget6">
- <property name="geometry">
- <rect>
- <x>240</x>
- <y>30</y>
- <width>209</width>
- <height>28</height>
- </rect>
- </property>
- <layout class="QFormLayout" name="formLayout_5">
- <item row="0" column="0">
- <widget class="QLabel" name="label_10">
- <property name="minimumSize">
- <size>
- <width>100</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>100</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string>Source Type:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QComboBox" name="comboBoxSourceType">
- <property name="minimumSize">
- <size>
- <width>100</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>100</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="editable">
- <bool>true</bool>
- </property>
- <item>
- <property name="text">
- <string notr="true">jpg</string>
+ <property name="maximumSize">
+ <size>
+ <width>100</width>
+ <height>16777215</height>
+ </size>
</property>
- </item>
- <item>
<property name="text">
- <string notr="true">png</string>
+ <string>Destination: </string>
</property>
- </item>
- <item>
- <property name="text">
- <string>gif</string>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="comboTarget">
+ <property name="editable">
+ <bool>true</bool>
</property>
- </item>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="layoutWidget7">
- <property name="geometry">
- <rect>
- <x>480</x>
- <y>30</y>
- <width>211</width>
- <height>28</height>
- </rect>
- </property>
- <layout class="QFormLayout" name="formLayout_6">
- <item row="0" column="0">
- <widget class="QLabel" name="label_11">
- <property name="minimumSize">
- <size>
- <width>100</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>100</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string>Dest. Type:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QComboBox" name="comboBoxDestType">
- <property name="minimumSize">
- <size>
- <width>100</width>
- <height>0</height>
- </size>
- </property>
- <property name="maximumSize">
- <size>
- <width>100</width>
- <height>16777215</height>
- </size>
- </property>
- <item>
- <property name="text">
- <string notr="true">jpg</string>
+ <property name="currentText">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pushButtonSelectDest">
+ <property name="minimumSize">
+ <size>
+ <width>50</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>50</width>
+ <height>16777215</height>
+ </size>
</property>
- </item>
- <item>
<property name="text">
- <string notr="true">png</string>
+ <string>...</string>
</property>
- </item>
- </widget>
- </item>
- </layout>
- </widget>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_8">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="minimumSize">
+ <size>
+ <width>100</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>100</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Template:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="comboBox">
+ <item>
+ <property name="text">
+ <string>Website: 1024x768</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Website II: 800x600</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Photo: 2048x1536</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Photo II: 3072x2304</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Midi: 600x400</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Mini: 150x100</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
</widget>
</item>
<item>
- <layout class="QHBoxLayout" name="horizontalLayout_2" stretch="1,0,0">
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
</layout>
</item>
<item>
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <layout class="QVBoxLayout" name="verticalLayout">
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
<item>
<widget class="QPushButton" name="buttonConvert">
<property name="minimumSize">
<rect>
<x>0</x>
<y>0</y>
- <width>735</width>
+ <width>772</width>
<height>23</height>
</rect>
</property>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
- <x>367</x>
- <y>265</y>
+ <x>-1</x>
+ <y>-1</y>
</hint>
<hint type="destinationlabel">
<x>367</x>
TARGET = reimgconvert
TEMPLATE = app
+INCLUDEPATH = ../.. /usr/include/c++/4.9
SOURCES += main.cpp\
- mainwindow.cpp \
- converter.cpp
+ ../../base/ReException.cpp \
+ ../../base/ReQStringUtil.cpp \
+ ../../base/ReLogger.cpp \
+ mainwindow.cpp \
+ converter.cpp \
+ aboutdialog.cpp
HEADERS += mainwindow.hpp \
- converter.hpp
+ converter.hpp \
+ aboutdialog.hpp
-FORMS += mainwindow.ui
+FORMS += mainwindow.ui \
+ aboutdialog.ui
RESOURCES += \
- reimgconvert.qrc
+ reimgconvert.qrc
OTHER_FILES +=
*/
ReString ReQStringUtil::extensionOf(const ReString& filename){
QString rc;
-
int index = filename.lastIndexOf('.');
+ int index2 = 0;
if (index > 0){
- int index2 = filename.lastIndexOf('/');
- if (index2 < index){
-#if defined WIN32
+ index2 = filename.lastIndexOf('/');
+ if (index2 >= 0){
+ if (index > index2)
+ rc = filename.mid(index);
+ } else {
+#if defined __linux__
+ rc = filename.mid(index);
+#elif defined WIN32
index2 = filename.lastIndexOf('\\');
- if (index2 < index)
- rc = filename.mid(index);
+ if (index2 < 0 || index > index2)
+ rc = filename.mid(index);
#endif
}
}
return rc;
}
+/**
+ * Replaces the file extension of a filename.
+ *
+ * @param path the filename to change
+ * @param ext the new file extension, e.g. ".txt"
+ * @return path with a new file extension
+ */
+
+QString ReQStringUtil::replaceExtension(const QString& path, const QString& ext)
+{
+ QString oldExt = extensionOf(path);
+ QString rc;
+ if (oldExt.isEmpty())
+ rc = path + ext;
+ else
+ rc = path.mid(0, path.size() - oldExt.size()) + ext;
+ return rc;
+}
/**
* Replaces placeholders by their values.
*
}
static ReString nodeOf(const ReString& filename);
static QString pathAppend(const QString& base, const QString& path);
+ static QString replaceExtension(const QString& path, const QString& ext);
static bool replacePlaceholders(QString& text,
const QMap <QString, QString>& placeholders, QString* error);
static void skipExpected(const ReString& text, QChar expected, int& index,