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