1 /*
2 * This file is part of Converseen, an open-source batch image converter
3 * and resizer.
4 *
5 * (C) Francesco Mondello 2009 - 2021
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 *
20 * Contact e-mail: Francesco Mondello <faster3ck@gmail.com>
21 *
22 */
23 
24 #include <QColorDialog>
25 #include <QTimer>
26 #include <string>
27 #include <iostream>
28 #include "mainwindowimpl.h"
29 #include "dialogoptions.h"
30 #include "dialoginfo.h"
31 #include "formats.h"
32 #include "inisettings.h"
33 #include "sizeutil.h"
34 #include "updatechecker.h"
35 #include "dialogmultipageeditor.h"
36 #include "globals.h"
37 
38 using namespace Magick;
39 using namespace std;
40 
41 // TODO: Inserire funzione per sostituire tutte le immagini
42 
MainWindowImpl(QWidget * parent,Qt::WindowFlags f)43 MainWindowImpl::MainWindowImpl(QWidget * parent, Qt::WindowFlags f)
44     : QMainWindow(parent, f)
45 {
46     setupUi(this);
47 
48     iAList = new QList<ImageAttributes>;
49     convertThread = new Converter(this);
50     dlgCStatus = new DialogConversionStatus();
51 
52     CachingSystem::init();
53 
54     connect(treeWidget, SIGNAL(dropped(QStringList)), this, SLOT(loadFiles(QStringList)));
55 
56     connect(bntSelDir, SIGNAL(clicked()), this, SLOT(openOutDirectory()));
57     connect(checkSameDir, SIGNAL(stateChanged(int)), this, SLOT(setCurrentDirectory()));
58     connect(btnFormatOptions, SIGNAL(clicked()), this, SLOT(setQuality()));
59     connect(treeWidget, SIGNAL(itemSelectionChanged()), this, SLOT(onItemSelection()));
60 
61     connect(spin_geoWidth, SIGNAL(editingFinished()), this, SLOT(relativeSizeW()));
62     connect(spin_geoHeight, SIGNAL(editingFinished()), this, SLOT(relativeSizeH()));
63 
64     connect(comboResizeValues, SIGNAL(currentIndexChanged(QString)), this, SLOT(selectGeometryUnit(QString)));
65 
66     connect(checkRename, SIGNAL(stateChanged(int)), this, SLOT(enableRenameLine()));
67     connect(radioPrefixSuffix, SIGNAL(clicked()), this, SLOT(enableProgressiveSpin()));
68     connect(radioProgressive, SIGNAL(clicked()), this, SLOT(enableProgressiveSpin()));
69     connect(checkShowPreview, SIGNAL(stateChanged(int)), this, SLOT(enableShowPreview()));
70 
71     connect(pushReset, SIGNAL(clicked()), this, SLOT(onPushResetClick()));
72 
73     connect(convertThread, SIGNAL(nextConversion(int)), this, SLOT(nextConversion(int)));
74     connect(convertThread, SIGNAL(requestOverwrite(QString)), this, SLOT(overwriteDialog(QString)));
75     connect(convertThread, SIGNAL(errorMessage(QString)), this, SLOT(errorMessage(QString)));
76 
77     connect(dlgCStatus, SIGNAL(stopProcess()), this, SLOT(stopProcess()));
78 
79     connect(pushColor, SIGNAL(clicked()), this, SLOT(choseBackgroundColor()));
80 
81     connect(labelPreview, SIGNAL(previewReady(int, int, double, double)), this, SLOT(showImageInformations(int, int, double, double)));
82 
83     connect(checkRelative, SIGNAL(stateChanged(int)), this, SLOT(setRelativeSizeCheckboxes(int)));
84 
85     createActions();
86     setupMenu();
87     createContextMenu();
88 
89     loadFormats();
90 
91     comboResizeValues->addItems((QStringList() << "%" << "px"));
92 
93     adjustSize();
94     dockWidget->adjustSize();
95 
96     treeWidget->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
97 
98     loadOptions();
99 
100     resetDisplays();
101 
102     if (IniSettings::isAutoChechUpdates()) {
103         checkForUpdates();
104     }
105 
106     checkVersion();
107 }
108 
~MainWindowImpl()109 MainWindowImpl::~MainWindowImpl()
110 {
111     saveSettings();
112 }
113 
importListFromArgv(QString fileName)114 void MainWindowImpl::importListFromArgv(QString fileName)
115 {
116     QFile file(fileName);
117     if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
118         return;
119 
120     QString text = file.readAll();
121     QStringList rawlist = text.split("\n");
122 
123     QStringList list;
124 
125     for (int i = 0; i < rawlist.count(); i++) {
126         QFileInfo fi(rawlist.at(i));
127         if (Formats::readableFilters().contains(fi.suffix(), Qt::CaseInsensitive))
128             list << rawlist.at(i);
129     }
130 
131     loadFiles(list);
132 }
133 
createActions()134 void MainWindowImpl::createActions()
135 {
136     // "File" actions
137     connect(actionOpenFiles, SIGNAL(triggered()), this, SLOT(openFiles()));
138     connect(actionAddFiles, SIGNAL(triggered()), this, SLOT(addFiles()));
139     connect(actionImportWindowsIconIco, SIGNAL(triggered()), this, SLOT(importIcoFile()));
140     connect(actionImportPDFFile, SIGNAL(triggered()), this, SLOT(importPdfFile()));
141 
142     connect(actionShowOptions, SIGNAL(triggered()), this, SLOT(editSettings()));
143     connect(actionClose, SIGNAL(triggered()), this, SLOT(close()));
144 
145     // "Edit" actions
146     connect(actionCheckItems, SIGNAL(triggered()), treeWidget, SLOT(checkItems()));
147     connect(actionCheckAllItems, SIGNAL(triggered()), treeWidget, SLOT(checkAllItems()));
148 
149     connect(actionUncheckItems, SIGNAL(triggered()), treeWidget, SLOT(uncheckItems()));
150     connect(actionUncheckAllItems, SIGNAL(triggered()), treeWidget, SLOT(uncheckAllItems()));
151 
152     connect(actionRemoveItems, SIGNAL(triggered()), this, SLOT(removeItems()));
153     connect(actionRemoveAllItems, SIGNAL(triggered()), this, SLOT(removeAllItems()));
154 
155     // "Actions" actions
156     connect(actionConvert, SIGNAL(triggered()), this, SLOT(elabora()));
157 
158     connect(actionInfo, SIGNAL(triggered()), this, SLOT(about()));
159     connect(actionDonatePaypal, SIGNAL(triggered()), this, SLOT(openPaypalLink()));
160     connect(actionReportBug, SIGNAL(triggered()), this, SLOT(bugReport()));
161     connect(actionCheckForUpdates, SIGNAL(triggered()), this, SLOT(checkForUpdates()));
162 }
163 
setupMenu()164 void MainWindowImpl::setupMenu()
165 {
166     menu_File->addAction(actionOpenFiles);
167     menu_File->addAction(actionAddFiles);
168     menu_File->addSeparator();
169     menu_File->addAction(actionImportWindowsIconIco);
170     menu_File->addAction(actionImportPDFFile);
171     menu_File->addSeparator();
172     menu_File->addAction(actionShowOptions);
173     menu_File->addSeparator();
174     menu_File->addAction(actionClose);
175 
176     menu_Edit->addAction(actionRemoveItems);
177     menu_Edit->addAction(actionRemoveAllItems);
178     menu_Edit->addSeparator();
179     menu_Edit->addAction(actionCheckItems);
180     menu_Edit->addAction(actionCheckAllItems);
181     menu_Edit->addAction(actionUncheckItems);
182     menu_Edit->addAction(actionUncheckAllItems);
183 
184     menu_Actions->addAction(actionConvert);
185 
186     menu_About->addAction(actionInfo);
187 }
188 
createContextMenu()189 void MainWindowImpl::createContextMenu()
190 {
191     QAction *actionSeparator = new QAction(this);
192     actionSeparator->setSeparator(true);
193 
194     treeWidget->setContextMenuPolicy(Qt::ActionsContextMenu);
195     treeWidget->addAction(actionCheckItems);
196     treeWidget->addAction(actionCheckAllItems);
197     treeWidget->addAction(actionUncheckItems);
198     treeWidget->addAction(actionUncheckAllItems);
199     treeWidget->addAction(actionSeparator);
200     treeWidget->addAction(actionRemoveItems);
201     treeWidget->addAction(actionRemoveAllItems);
202 }
203 
openFiles()204 void MainWindowImpl::openFiles()
205 {
206     iAList->clear();
207     addFiles();
208 }
209 
addFiles()210 void MainWindowImpl::addFiles()
211 {
212     CachingSystem::clear();
213 
214     QString path = IniSettings::latestOpenedDir();
215 
216     QString readableFiltersString = Formats::readableFiltersString();
217     QStringList fileNames = QFileDialog::getOpenFileNames(this,
218                                                           tr("Open Image"), path,
219                                                           readableFiltersString);
220 
221     if (!fileNames.isEmpty())
222         loadFiles(fileNames);
223 }
224 
importIcoFile()225 void MainWindowImpl::importIcoFile()
226 {
227     QString path = IniSettings::latestOpenedDir();
228 
229     QString fileName = QFileDialog::getOpenFileName(this,
230         tr("Open Icon file"), path, tr("Microsoft icon (*.ico *.icon)"));
231 
232     if (!fileName.isEmpty())
233         openMultipageFile(fileName);
234 }
235 
importPdfFile()236 void MainWindowImpl::importPdfFile()
237 {
238     QString path = IniSettings::latestOpenedDir();
239 
240     QString fileName = QFileDialog::getOpenFileName(this,
241         tr("Open Pdf file"), path, tr("Portable Document Format (*.pdf)"));
242 
243     if (!fileName.isEmpty())
244         openMultipageFile(fileName);
245 }
246 
openMultipageFile(QString fileName)247 void MainWindowImpl::openMultipageFile(QString fileName)
248 {
249     DialogMultipageEditor *dlg = new DialogMultipageEditor();
250 
251     statusBar()->showMessage(tr("Analyzing the file. It may take a while, please wait..."));
252     QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
253     dlg->readFile(fileName);
254     QApplication::restoreOverrideCursor();
255     statusBar()->clearMessage();
256 
257     dlg->exec();
258 
259     if (dlg->result() == 1) {
260         QStringList fileNames = dlg->fileNames();
261         loadFiles(fileNames);
262     }
263 }
264 
loadFiles(QStringList fileNames)265 void MainWindowImpl::loadFiles(QStringList fileNames)
266 {
267     treeWidget->clear();
268 
269     QFileInfo fi(fileNames.at(0));
270     IniSettings::setLatestOpenedDir(fi.path());
271 
272     for (int i = 0; i < fileNames.count(); i++) {
273         QFileInfo fi(fileNames.at(i));
274         ImageAttributes iA;
275 
276         /* Controlla i doppioni! */
277         if (!checkDuplicates(fileNames, i)) {
278             iA.completeFileName = fileNames.at(i).toLocal8Bit();
279             iA.fileName = fi.fileName();
280             iA.suffix = fi.suffix();
281             iA.size = fi.size();
282             iA.path = fi.path();
283             iAList->append(iA);   // aggiunge
284         }
285     }
286     fillTreeView();
287 }
288 
checkDuplicates(QStringList fileNames,int e)289 bool MainWindowImpl::checkDuplicates(QStringList fileNames, int e)
290 {
291     int cnt = iAList->count();
292 
293     for (int i = 0; i < cnt; i++)
294         if (iAList->at(i).completeFileName == fileNames.at(e).toLocal8Bit())
295             return true;
296 
297     return false;
298 }
299 
fillTreeView()300 void MainWindowImpl::fillTreeView()
301 {
302     treeWidget->addItems(iAList);
303 }
304 
elabora()305 void MainWindowImpl::elabora()
306 {
307     if (!iAList->isEmpty()) {
308         if (treeWidget->thereAreItemsChecked()) {
309             if (!lineDirectory->text().isEmpty()) {
310                 QDir dir(lineDirectory->text());
311                 if((dir.exists()) || (checkSameDir->isChecked())) {
312                     startConversion();
313                 }
314                 else {
315                     int ret = QMessageBox::warning(0, tr("Warning"),
316                                                    tr("The output directory doesn't exists! Would you create it?"),
317                                                    QMessageBox::Ok | QMessageBox::Cancel);
318 
319                     if (ret == QMessageBox::Ok) {
320                         if (!dir.mkpath(lineDirectory->text()))
321                             QMessageBox::warning(0, tr("Warning"),
322                                                  tr("The directory cannot be created!"));
323                         else {
324                             startConversion();
325                         }
326                     }
327                 }
328             }
329             else
330                 QMessageBox::warning(0, tr("Warning"),
331                                      tr("Set an output directory!"));
332         }
333         else
334             QMessageBox::warning(0, tr("Warning"),
335                                  tr("No image checked!"));
336     }
337     else
338         QMessageBox::warning(0, tr("Warning"),
339                              tr("No images to convert!"));
340 }
341 
startConversion()342 void MainWindowImpl::startConversion()
343 {
344     IniSettings::setOutputDir(lineDirectory->text());
345 
346     abort_all = false;
347 
348     statusBar()->showMessage(tr("Processing..."));
349     curr_index = 0;
350 
351     m_progressiveNren = spinProgressiveRen->value();    // Used when the progressive number renaming is checked
352 
353     convertThread->reset();
354 
355     // Colore
356     bool noTransparency = this->checkNoTransp->isChecked();
357     convertThread->setBackgroundColor(m_bgColor, noTransparency);
358 
359     /* Change image size */
360     if (groupDimensions->isChecked()) {
361         QString aspectRatio = "!";
362 
363         if (checkRelative->isChecked())
364             aspectRatio = "";
365 
366         // "%1 x %2 % !"
367 
368         QString resizingString;
369         if (comboResizeValues->currentText() == "px")
370             resizingString = QString("%1x%2%3")
371                     .arg(new_img_width)
372                     .arg(new_img_height)
373                     .arg(aspectRatio);
374         if (comboResizeValues->currentText() == "%")
375             resizingString = QString("%1x%2%")
376                     .arg(spin_geoWidth->value())
377                     .arg(spin_geoHeight->value());
378 
379         convertThread->setResize(resizingString);
380     }
381 
382     /* Change image density */
383     if ((groupResolution->isChecked()) && ((m_xResolution != spin_resX->value()) || (m_yResolution != spin_resY->value()))) {
384         QString densStr = QString("%1x%2")
385                 .arg(spin_resX->value())
386                 .arg(spin_resY->value());
387 
388         convertThread->setDensity(densStr);
389     }
390 
391     if (!radioRotNo->isChecked()) {
392         double rotation = 0;
393 
394         if (radioRotPos90->isChecked())
395             rotation = 90.0;
396         if (radioRotNeg90->isChecked())
397             rotation = -90.0;
398         if (radioRot180->isChecked())
399             rotation = 180.0;
400 
401         convertThread->setRotation(rotation);
402     }
403 
404     if (!radioFlipNo->isChecked()) {
405         FlipOrientation fo;
406 
407         if (radioFlipV->isChecked())
408             fo = VERTICAL;
409         if (radioFlipH->isChecked())
410             fo = HORIZONTAL;
411 
412         convertThread->setFlip(fo);
413     }
414 
415     convertThread->setResamplingFilter(m_resamplingFilter);
416 
417     convert();
418 
419     dlgCStatus->setup(treeWidget->countChecked());
420     dlgCStatus->exec();
421 }
422 
convert()423 void MainWindowImpl::convert()
424 {
425     if ((treeWidget->topLevelItem(curr_index))->checkState(0)) {
426         IniSettings::setLatestWrittenFormatIndex(comboWFormats->currentIndex());
427         statusBar()->showMessage(iAList->at(curr_index).fileName, 5000);
428 
429         QString out_format;
430 
431         QString inputFilename = iAList->at(curr_index).completeFileName;
432 
433         QFileInfo fi(inputFilename);
434 
435         if (comboWFormats->currentIndex() != 0) {
436             out_format = comboWFormats->currentText().split(" - ").at(0);
437         }
438         else {
439             QString suffix = fi.suffix();
440 
441             out_format = suffix;
442         }
443 
444         out_format = out_format.toLower();
445 
446         QString outFileName = QString("%1/%2.%3").arg(destinationPath()).arg(fi.completeBaseName()).arg(out_format);
447 
448         int quality = -1;
449 
450         if ((out_format == "jpg") || (out_format == "jpeg") || (out_format == "mpeg") || (out_format == "mpg")) {
451             quality = jpgQuality;
452         }
453 
454         if ((out_format == "png") || (out_format == "mng")) {
455             quality = pngQuality;
456         }
457 
458         convertThread->setInputPicture(inputFilename);
459         convertThread->setFormat(out_format);
460         convertThread->setQuality(quality);
461         convertThread->setOutputDir(destinationPath());
462 
463         if (checkRename->isChecked()) {
464             // Special renaming settings for the output file enabled
465             QString renamedOutFileName;
466 
467             if (radioPrefixSuffix->isChecked())
468                 renamedOutFileName = renameFileNameOnPrefixSuffix(outFileName);
469             else
470                 renamedOutFileName = renameFileNameOnProgressiveN(outFileName);
471 
472             convertThread->setOutputPictureName(renamedOutFileName);
473         }
474         else {
475             // No special renaming settings for the output file. Set it with tho original name + new extension
476 
477             convertThread->setOutputPictureName(outFileName);
478             convertThread->setOverwrite(checkOverwrite->isChecked());
479         }
480 
481         convertThread->start();
482     }
483     else {
484         nextConversion(2);
485     }
486 }
487 
nextConversion(int conv_status)488 void MainWindowImpl::nextConversion(int conv_status)
489 {
490     if (!abort_all) {
491         if ((treeWidget->topLevelItem(curr_index))->checkState(0)) {
492             dlgCStatus->step(conv_status, iAList->at(curr_index).fileName);
493         }
494 
495         QString msg = "";
496         if (conv_status == 1) {
497             msg = "Converted";
498             // Add the destination dirs to DialogConversionStatus so them can be opened at the end of the image processing
499             dlgCStatus->addOutputDirectory(QDir::toNativeSeparators(destinationPath()));
500         }
501         else if (conv_status == -1)
502             msg = "Error";
503 
504         (treeWidget->topLevelItem(curr_index))->setText(1, msg);
505 
506         curr_index++;
507         if (curr_index < iAList->count()) {
508             convert();
509         }
510         else {
511             statusBar()->showMessage(tr("Processing finished!"), 5000);
512         }
513     }
514 }
515 
renameFileNameOnPrefixSuffix(QString oldFileName)516 QString MainWindowImpl::renameFileNameOnPrefixSuffix(QString oldFileName)
517 {
518     QString t_renamingString = lineRename->text();
519 
520     QFileInfo fi(oldFileName);
521     QString newFileName = QString("%1.%2")
522             .arg(t_renamingString.replace("#", fi.completeBaseName()))
523             .arg(fi.suffix());
524 
525     return QString("%1/%2").arg(fi.path()).arg(newFileName);
526 }
527 
renameFileNameOnProgressiveN(QString oldFileName)528 QString MainWindowImpl::renameFileNameOnProgressiveN(QString oldFileName)
529 {
530     QString t_renamingString = lineRename->text();
531 
532     QFileInfo fi(oldFileName);  // For the output directory
533     QString newFileName = QString("%1.%2")
534             .arg(t_renamingString.replace("#", QString::number(m_progressiveNren)))
535             .arg(fi.suffix());
536 
537     m_progressiveNren++;    // the key of progressive number renaming (set to start when the conversion in starded)
538 
539     return QString("%1/%2").arg(fi.path()).arg(newFileName);
540 }
541 
loadFormats()542 void MainWindowImpl::loadFormats()
543 {
544     Formats::loadFormats();
545 
546     comboWFormats->addItems(Formats::writableFilters());
547     comboWFormats->setCurrentIndex(0);
548 }
549 
setCurrentDirectory()550 void MainWindowImpl::setCurrentDirectory()
551 {
552     bool enabled;
553 
554     if (checkSameDir->isChecked())
555         enabled = false;
556     else
557         enabled = true;
558 
559     lineDirectory->setEnabled(enabled);
560     bntSelDir->setEnabled(enabled);
561 }
562 
openOutDirectory()563 void MainWindowImpl::openOutDirectory()
564 {
565     QString dir = QFileDialog::getExistingDirectory(this, tr("Open Directory"),
566                                                     QDir::homePath(),
567                                                     QFileDialog::ShowDirsOnly
568                                                     | QFileDialog::DontResolveSymlinks);
569 
570     if (!dir.isNull())
571         lineDirectory->setText(QDir::toNativeSeparators(dir));
572     // La cartella viene salvata quando viene avviata la procedura di conversione
573 
574 }
575 
loadOptions()576 void MainWindowImpl::loadOptions()
577 {
578     IniSettings::init();
579 
580     this->restoreGeometry(IniSettings::windowGeometry());
581 
582     lineDirectory->setText(QDir::toNativeSeparators(IniSettings::outputDir()));
583     comboWFormats->setCurrentIndex(IniSettings::latestWrittenFormatIndex());
584     checkOverwrite->setChecked(IniSettings::isOverwriteMode());
585 
586     loadQuality();
587 
588     m_bgColor = IniSettings::backgroundColor();
589 
590     QColor c;
591     c.setNamedColor(m_bgColor);
592     pushColor->setColor(c);
593 
594     checkShowPreview->setChecked(IniSettings::previewChecked());
595     groupDimensions->setChecked(IniSettings::scaleChecked());
596     comboResizeValues->setCurrentIndex(IniSettings::measure());
597     checkRelative->setChecked(IniSettings::aspectRatioChecked());
598     groupResolution->setChecked(IniSettings::resolutionChecked());
599     checkSameDir->setChecked(IniSettings::imageDirChecked());
600     checkRename->setChecked(IniSettings::renameChecked());
601     checkNoTransp->setChecked(IniSettings::bgColorChecked());
602 
603     enableRenameLine();
604     enableProgressiveSpin();
605 }
606 
setQuality()607 void MainWindowImpl::setQuality()
608 {
609     loadQuality();
610 
611     DialogQuality *dlg = new DialogQuality();
612     dlg->setInitValues(jpgQuality, pngQuality, m_resamplingFilter);
613     if (dlg->exec()) {
614         jpgQuality = dlg->getJpegQuality();
615         pngQuality = dlg->getPngQuality();
616 
617         m_resamplingFilter = dlg->getResamplingFilter();
618 
619         IniSettings::setJpgQuality(jpgQuality);
620         IniSettings::setPngQuality(pngQuality);
621         IniSettings::setLatestInterpFiltIdx((int)m_resamplingFilter);
622     }
623 }
624 
loadQuality()625 void MainWindowImpl::loadQuality()
626 {
627     jpgQuality = IniSettings::jpgQuality();
628     pngQuality = IniSettings::pngQuality();
629     m_resamplingFilter = (IMFilterType)IniSettings::latestInterpFiltIdx();
630 }
631 
removeItems()632 void MainWindowImpl::removeItems()
633 {
634     if (!iAList->isEmpty()) {
635         treeWidget->removeItems(iAList);
636         resetDisplays();
637     }
638 }
639 
removeAllItems()640 void MainWindowImpl::removeAllItems()
641 {
642     if (!iAList->isEmpty()) {
643         iAList->clear();
644         CachingSystem::clear();
645         treeWidget->clear();
646 
647         resetDisplays();
648     }
649 }
650 
relativeSizeW()651 void MainWindowImpl::relativeSizeW()
652 {
653     double value = spin_geoWidth->value();
654 
655     if (checkLinkAspect->isChecked()) {
656         if (checkRelative->isChecked()) {
657             if (comboResizeValues->currentText() == "px") {
658                 double relative_H = ( ((double)img_height * value) / (double)img_width);
659                 spin_geoHeight->setValue((double)qRound(relative_H));
660             }
661         }
662     }
663 
664     if (comboResizeValues->currentText() == "%") {
665         if (checkRelative->isChecked())
666             spin_geoHeight->setValue(spin_geoWidth->value());
667     }
668 
669     showNewSizePreview();
670 }
671 
relativeSizeH()672 void MainWindowImpl::relativeSizeH()
673 {
674     double value = spin_geoHeight->value();
675 
676     if (checkLinkAspect->isChecked()) {
677         if (checkRelative->isChecked()) {
678             if (comboResizeValues->currentText() == "px") {
679                 double relative_V = ( ((double)img_width * value) / (double)img_height);
680                 spin_geoWidth->setValue((double)qRound(relative_V));
681             }
682         }
683     }
684 
685     if (comboResizeValues->currentText() == "%") {
686         if (checkRelative->isChecked())
687             spin_geoWidth->setValue(spin_geoHeight->value());
688     }
689 
690     showNewSizePreview();
691 }
692 
loadPreview(QString fileName)693 void MainWindowImpl::loadPreview(QString fileName)
694 {
695     labelPreview->loadPreview(fileName, checkShowPreview->isChecked());
696 }
697 
showImageInformations(int orig_w,int orig_h,double orig_dens_x,double orig_dens_y)698 void MainWindowImpl::showImageInformations(int orig_w, int orig_h, double orig_dens_x, double orig_dens_y)
699 {
700     /*
701         Method executed by the signal myLabelPreviewer::previewReady(orig_w, orig_h, orig_dens_x, orig_dens_y);
702     */
703 
704     img_width = orig_w;
705     img_height = orig_h;
706 
707     m_xResolution = orig_dens_x;
708     m_yResolution = orig_dens_y;
709 
710     int index = treeWidget->currentIndex().row();
711 
712     labelType->setText(QString("<span style=\" font-size:8pt;\">%1</span>")
713                            .arg(iAList->at(index).suffix));
714 
715         QString sSize = SizeUtil::simplifyFileSize(iAList->at(index).size);
716         labelFileSize->setText(QString("<span style=\" font-size:8pt;\">%1</span>")
717                                .arg(sSize));
718 
719         label_ImageSize->setText(QString("<span style=\" font-size:8pt;\">%1 x %2 px</span>")
720                                  .arg(img_width)
721                                  .arg(img_height));
722 
723         label_ImageResolution->setText(QString("<span style=\" font-size:8pt;\">X = %1 Y = %2</span>")
724                                        .arg(m_xResolution)
725                                        .arg(m_yResolution));
726 }
727 
onItemSelection()728 void MainWindowImpl::onItemSelection()
729 {
730     if (!iAList->isEmpty()) {
731         showPreviewAndInfos();
732         showNewSizePreview();
733     }
734 }
735 
onPushResetClick()736 void MainWindowImpl::onPushResetClick()
737 {
738     selectGeometryUnit(comboResizeValues->currentText());
739     spin_resX->setValue(m_xResolution);
740     spin_resY->setValue(m_yResolution);
741 }
742 
showPreviewAndInfos()743 void MainWindowImpl::showPreviewAndInfos()
744 {
745     int index = treeWidget->currentIndex().row();
746     loadPreview(iAList->at(index).completeFileName);
747 }
748 
editSettings()749 void MainWindowImpl::editSettings()
750 {
751     DialogOptions dlg;
752     dlg.exec();
753 
754     if (dlg.result() == 1) {
755         saveSettings();
756         loadOptions();
757     }
758 }
759 
about()760 void MainWindowImpl::about()
761 {
762     DialogInfo dlg;
763     dlg.exec();
764 }
765 
enableRenameLine()766 void MainWindowImpl::enableRenameLine()
767 {
768     if (checkRename->isChecked()) {
769         lineRename->setEnabled(true);
770         radioPrefixSuffix->setEnabled(true);
771         radioProgressive->setEnabled(true);
772         spinProgressiveRen->setEnabled(true);
773         labeStartWith->setEnabled(true);
774     }
775     else
776     {
777         lineRename->setEnabled(false);
778         radioPrefixSuffix->setEnabled(false);
779         radioProgressive->setEnabled(false);
780         spinProgressiveRen->setEnabled(false);
781         labeStartWith->setEnabled(false);
782     }
783 
784     enableProgressiveSpin();
785 }
786 
enableProgressiveSpin()787 void MainWindowImpl::enableProgressiveSpin()
788 {
789     if (radioProgressive->isChecked()) {
790         spinProgressiveRen->setEnabled(true);
791         labeStartWith->setEnabled(true);
792     }
793     else {
794         spinProgressiveRen->setEnabled(false);
795         labeStartWith->setEnabled(false);
796     }
797 }
798 
enableShowPreview()799 void MainWindowImpl::enableShowPreview()
800 {
801     if(treeWidget->selectedItems().count() > 0)
802         onItemSelection();
803     else
804         labelPreview->setText(tr("Preview"));
805 }
806 
selectGeometryUnit(QString unit)807 void MainWindowImpl::selectGeometryUnit(QString unit)
808 {
809     if (unit == "px") {
810         spin_geoWidth->setDecimals(0);
811         spin_geoWidth->setSuffix(" px");
812         spin_geoWidth->setValue((double)img_width);
813 
814         spin_geoHeight->setDecimals(0);
815         spin_geoHeight->setSuffix(" px");
816         spin_geoHeight->setValue((double)img_height);
817     }
818     if (unit == "%") {
819         //spin_geoWidth->setDecimals(2);
820         spin_geoWidth->setSuffix(" %");
821         spin_geoWidth->setValue(100.00);
822 
823         //spin_geoHeight->setDecimals(2);
824         spin_geoHeight->setSuffix(" %");
825         spin_geoHeight->setValue(100.00);
826     }
827 }
828 
829 /* FIXME: Forse è meglio cambiare nome */
showNewSizePreview()830 void MainWindowImpl::showNewSizePreview()
831 {
832     if (comboResizeValues->currentText() == "%") {
833         double new_width, new_height, round_new_width, round_new_height;
834 
835         new_width = (((double)img_width / 100) * (spin_geoWidth->value()));
836         new_height = (((double)img_height / 100) * (spin_geoHeight->value()));
837 
838         round_new_width = qRound(new_width);
839         round_new_height = qRound(new_height);
840 
841         if (treeWidget->selectedItems().count() > 0)
842             labelPixelGeometry->setText(QString("<span style=\" font-size:8pt;\"><center>%1 x %2 pixels</center></span>")
843                                         .arg(round_new_width)
844                                         .arg(round_new_height));
845 
846         new_img_width = round_new_width;
847         new_img_height = round_new_height;
848     }
849     if (comboResizeValues->currentText() == "px") {
850         if (treeWidget->selectedItems().count() > 0)
851             labelPixelGeometry->setText(QString("<span style=\" font-size:8pt;\"><center>%1 x %2 pixels</center></span>")
852                                         .arg(spin_geoWidth->value())
853                                         .arg(spin_geoHeight->value()));
854 
855         new_img_width = spin_geoWidth->value();
856         new_img_height = spin_geoHeight->value();
857     }
858 }
859 
resetDisplays()860 void MainWindowImpl::resetDisplays()
861 {
862     labelPreview->setText(tr("Preview"));
863 
864     img_width = 0;
865     img_height = 0;
866 
867     new_img_width = 0;
868     new_img_height = 0;
869 
870     m_xResolution = 0;
871     m_yResolution = 0;
872 
873     spin_resX->setValue(m_xResolution);
874     spin_resY->setValue(m_yResolution);
875 
876     if (comboResizeValues->currentText() == "%") {
877         spin_geoWidth->setValue(100);
878         spin_geoHeight->setValue(100);
879     }
880     if (comboResizeValues->currentText() == "px") {
881         spin_geoWidth->setValue(1);
882         spin_geoHeight->setValue(1);
883     }
884 
885     labelType->setText(" - ");
886     label_ImageSize->setText(" - ");
887     labelFileSize->setText(" - ");
888     label_ImageResolution->setText(" - ");
889 
890     labelPixelGeometry->setText("");
891 }
892 
checkVersion()893 void MainWindowImpl::checkVersion()
894 {
895     int savedVersion = IniSettings::currentVersion();
896     int currentVersion = globals::CURRENT_INTERNAL_VERSION;
897 
898     if (savedVersion < currentVersion) {
899 #if defined(Q_OS_WIN)
900 	// Open thank you page on Windows
901 		QString welcomePage = QString("http://converseen.fasterland.net/thank/");
902 
903 		QDesktopServices::openUrl(QUrl(welcomePage, QUrl::TolerantMode));
904 #endif
905 
906 		IniSettings::setCurrentVersion(currentVersion);
907     }
908 }
909 
saveSettings()910 void MainWindowImpl::saveSettings()
911 {
912     IniSettings::setWindowGeometry(saveGeometry());
913     IniSettings::setPreviewChecked(checkShowPreview->isChecked());
914     IniSettings::setScaleChecked(groupDimensions->isChecked());
915     IniSettings::setMeasure(comboResizeValues->currentIndex());
916     IniSettings::setAspectRatioChecked(checkRelative->isChecked());
917     IniSettings::setResolutionChecked(groupResolution->isChecked());
918     IniSettings::setImageDirChecked(checkSameDir->isChecked());
919     IniSettings::setRenameChecked(checkRename->isChecked());
920     IniSettings::setBgColorChecked(checkNoTransp->isChecked());
921     IniSettings::setOverwriteMode(checkOverwrite->isChecked());
922 
923     IniSettings::settings->sync();
924 }
925 
overwriteDialog(QString baseName)926 void MainWindowImpl::overwriteDialog(QString baseName)
927 {
928     /*
929         TODO: Sostituisci tutte (vedi sotto)
930     */
931     bool ok;
932     QString newBaseName;
933 
934     while (newBaseName.isEmpty()) {
935         newBaseName = QInputDialog::getText(0, tr("Suggest a new name!"),
936                                             tr("New name:"), QLineEdit::Normal,
937                                             baseName, &ok);
938 
939         if (!ok) {
940             QMessageBox::StandardButton msg;
941             msg = QMessageBox::question(this, tr("Please, specify a name!"),
942                                         /* FIXME: tradurre meglio! */ tr("You should specify a name.\nClick Retry to specify a new name.\nClick Ignore to cancel this operation.\nClick Abort to cancel all operations."),
943                                         QMessageBox::Retry | QMessageBox::Ignore | QMessageBox::Abort);
944 
945             if (msg == QMessageBox::Ignore) {
946                 convertThread->stopProcess();
947                 break;
948             }
949 
950             if (msg == QMessageBox::Abort) {
951                 stopProcess();
952                 break;
953             }
954         }
955         else {
956             if (newBaseName.isEmpty())
957                 QMessageBox::warning(0, tr("Warning!"),
958                                      tr("The filename should not be empty!"));
959 
960             if (newBaseName == baseName) {
961                 QMessageBox::StandardButton msg;
962                 msg = QMessageBox::question(this, tr("Warning!"),
963                                             tr("The name chosen is identical to the initial one. Do you want to overwrite the original file?"),
964                                             QMessageBox::Yes | QMessageBox::No); // TODO: mettere si per tutte!
965 
966                 if (msg == QMessageBox::No)
967                     newBaseName.clear();
968             }
969         }
970     }
971     //convertThread->mutex.unlock();
972     convertThread->setNewBasename(newBaseName, ok);
973 }
974 
stopProcess()975 void MainWindowImpl::stopProcess()
976 {
977     convertThread->stopProcess();
978     abort_all = true;
979     statusBar()->showMessage(tr("Aborted!"), 5000);
980 }
981 
errorMessage(QString err_status)982 void MainWindowImpl::errorMessage(QString err_status)   // Manda stringa di errore al dialog di conversione
983 {
984     dlgCStatus->setErrorMsg(err_status);
985 }
986 
choseBackgroundColor()987 void MainWindowImpl::choseBackgroundColor()
988 {
989     QColor color;
990     color = QColorDialog::getColor(Qt::green, this);
991 
992     m_bgColor = color.name();
993 
994     pushColor->setColor(color);
995 
996     IniSettings::setBackgroundColor(m_bgColor);
997 }
998 
destinationPath()999 QString MainWindowImpl::destinationPath()
1000 {
1001     QString dest = lineDirectory->text();
1002 
1003     if (checkSameDir->isChecked())
1004         dest = iAList->at(curr_index).path;
1005 
1006     return dest;
1007 }
1008 
openPaypalLink()1009 void MainWindowImpl::openPaypalLink()
1010 {
1011     QDesktopServices::openUrl(QUrl("https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=HQA6TBT5354FC", QUrl::TolerantMode));
1012 }
1013 
checkForUpdates()1014 void MainWindowImpl::checkForUpdates()
1015 {
1016     UpdateChecker *up = new UpdateChecker();
1017     up->checkForUpdates();
1018 }
1019 
bugReport()1020 void MainWindowImpl::bugReport()
1021 {
1022     QDesktopServices::openUrl(QUrl("https://github.com/Faster3ck/Converseen/issues", QUrl::TolerantMode));
1023 }
1024 
setRelativeSizeCheckboxes(int state)1025 void MainWindowImpl::setRelativeSizeCheckboxes(int state)
1026 {
1027     if (state == 0)
1028         checkLinkAspect->setEnabled(false);
1029     else
1030         checkLinkAspect->setEnabled(true);
1031 }
1032