File indexing completed on 2024-05-12 15:50:11
0001 /* -*- C++ -*- 0002 This file is part of ThreadWeaver. 0003 0004 SPDX-FileCopyrightText: 2005-2014 Mirko Boehm <mirko@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #include <QApplication> 0010 #include <QCheckBox> 0011 #include <QCloseEvent> 0012 #include <QFileDialog> 0013 #include <QSettings> 0014 #include <QSortFilterProxyModel> 0015 #include <QString> 0016 #include <QVariant> 0017 0018 #include <ThreadWeaver/ThreadWeaver> 0019 0020 #include "AverageLoadManager.h" 0021 #include "ImageListFilter.h" 0022 #include "ItemDelegate.h" 0023 #include "MainWindow.h" 0024 0025 #include "ui_MainWindow.h" 0026 0027 const QString MainWindow::Setting_OpenLocation = QLatin1String("OpenFilesLocation"); 0028 const QString MainWindow::Setting_OutputLocation = QLatin1String("OutputLocation"); 0029 const QString MainWindow::Setting_WindowState = QLatin1String("WindowState"); 0030 const QString MainWindow::Setting_WindowGeometry = QLatin1String("WindowGeometry"); 0031 0032 using namespace ThreadWeaver; 0033 0034 MainWindow::MainWindow(QWidget *parent) 0035 : QMainWindow(parent) 0036 , ui(new Ui::MainWindow) 0037 , m_fileLoaderFilter(new ImageListFilter(Image::Step_LoadFile, this)) 0038 , m_imageLoaderFilter(new ImageListFilter(Image::Step_LoadImage, this)) 0039 , m_imageScalerFilter(new ImageListFilter(Image::Step_ComputeThumbNail, this)) 0040 , m_imageWriterFilter(new ImageListFilter(Image::Step_SaveThumbNail, this)) 0041 , m_averageLoadManager(new AverageLoadManager(this)) 0042 { 0043 ui->setupUi(this); 0044 // The file loader list: 0045 m_fileLoaderFilter->setSourceModel(&m_model); 0046 ui->fileLoaderList->setModel(m_fileLoaderFilter); 0047 ui->fileLoaderList->setItemDelegate(new ItemDelegate(this)); 0048 ui->fileLoaderCap->setValue(m_model.fileLoaderCap()); 0049 // The image loader list: 0050 m_imageLoaderFilter->setSourceModel(&m_model); 0051 ui->imageLoaderList->setModel(m_imageLoaderFilter); 0052 ui->imageLoaderList->setItemDelegate(new ItemDelegate(this)); 0053 ui->imageLoaderCap->setValue(m_model.imageLoaderCap()); 0054 0055 // The image scaler list: 0056 m_imageScalerFilter->setSourceModel(&m_model); 0057 ui->imageScalerList->setModel(m_imageScalerFilter); 0058 ui->imageScalerList->setItemDelegate(new ItemDelegate(this)); 0059 ui->imageScalerCap->setValue(m_model.computeThumbNailCap()); 0060 0061 // The image writer list: 0062 m_imageWriterFilter->setSourceModel(&m_model); 0063 ui->imageWriterList->setModel(m_imageWriterFilter); 0064 ui->imageWriterList->setItemDelegate(new ItemDelegate(this)); 0065 ui->fileWriterCap->setValue(m_model.saveThumbNailCap()); 0066 0067 ui->workers->setValue(Queue::instance()->maximumNumberOfThreads()); 0068 0069 // Configure average load manager: 0070 ui->loadManager->setEnabled(m_averageLoadManager->available()); 0071 connect(ui->loadManager, SIGNAL(toggled(bool)), SLOT(slotEnableAverageLoadManager(bool))); 0072 0073 connect(ui->actionOpen_Files, SIGNAL(triggered()), SLOT(slotOpenFiles())); 0074 connect(ui->outputDirectory, SIGNAL(clicked()), SLOT(slotSelectOutputDirectory())); 0075 connect(ui->actionQuit, SIGNAL(triggered()), SLOT(slotQuit())); 0076 connect(&m_model, SIGNAL(progress(int, int)), SLOT(slotProgress(int, int))); 0077 connect(ui->fileLoaderCap, SIGNAL(valueChanged(int)), SLOT(slotFileLoaderCapChanged())); 0078 connect(ui->imageLoaderCap, SIGNAL(valueChanged(int)), SLOT(slotImageLoaderCapChanged())); 0079 connect(ui->imageScalerCap, SIGNAL(valueChanged(int)), SLOT(slotComputeThumbNailCapChanged())); 0080 connect(ui->fileWriterCap, SIGNAL(valueChanged(int)), SLOT(slotSaveThumbNailCapChanged())); 0081 0082 connect(ui->workers, SIGNAL(valueChanged(int)), SLOT(slotWorkerCapChanged())); 0083 0084 QSettings settings; 0085 m_outputDirectory = settings.value(Setting_OutputLocation).toString(); 0086 if (!m_outputDirectory.isEmpty()) { 0087 ui->outputDirectory->setText(m_outputDirectory); 0088 } 0089 restoreGeometry(settings.value(Setting_WindowGeometry).toByteArray()); 0090 restoreState(settings.value(Setting_WindowState).toByteArray()); 0091 0092 connect(m_averageLoadManager, SIGNAL(recommendedWorkerCount(int)), SLOT(slotRecommendedWorkerCountChanged(int))); 0093 } 0094 0095 MainWindow::~MainWindow() 0096 { 0097 delete ui; 0098 } 0099 0100 void MainWindow::closeEvent(QCloseEvent *event) 0101 { 0102 event->ignore(); 0103 QMainWindow::closeEvent(event); 0104 slotQuit(); 0105 } 0106 0107 void MainWindow::slotProgress(int step, int total) 0108 { 0109 ui->progressBar->setMinimum(0); 0110 ui->progressBar->setMaximum(total); 0111 ui->progressBar->setValue(step); 0112 ui->actionOpen_Files->setEnabled(step >= total); 0113 } 0114 0115 void MainWindow::slotOpenFiles() 0116 { 0117 QSettings settings; 0118 const QString previousLocation = settings.value(Setting_OpenLocation, QDir::homePath()).toString(); 0119 auto const files = QFileDialog::getOpenFileNames(this, tr("Select images to convert"), previousLocation); 0120 if (files.isEmpty()) { 0121 return; 0122 } 0123 if (m_outputDirectory.isNull()) { 0124 slotSelectOutputDirectory(); 0125 } 0126 m_model.clear(); 0127 const QFileInfo fi(files.at(0)); 0128 settings.setValue(Setting_OpenLocation, fi.absolutePath()); 0129 slotProgress(0, files.count()); 0130 m_model.queueUpConversion(files, m_outputDirectory); 0131 } 0132 0133 void MainWindow::slotSelectOutputDirectory() 0134 { 0135 QSettings settings; 0136 const QString previousLocation = settings.value(Setting_OutputLocation, QDir::homePath()).toString(); 0137 auto directory = QFileDialog::getExistingDirectory(this, tr("Select output directory...")); 0138 if (directory.isNull()) { 0139 return; 0140 } 0141 m_outputDirectory = directory; 0142 settings.setValue(Setting_OutputLocation, directory); 0143 ui->outputDirectory->setText(directory); 0144 } 0145 0146 void MainWindow::slotFileLoaderCapChanged() 0147 { 0148 const int value = ui->fileLoaderCap->value(); 0149 Q_ASSERT(value > 0); // limits set in UI file 0150 m_model.setFileLoaderCap(value); 0151 } 0152 0153 void MainWindow::slotImageLoaderCapChanged() 0154 { 0155 const int value = ui->imageLoaderCap->value(); 0156 Q_ASSERT(value > 0); // limits set in UI file 0157 m_model.setImageLoaderCap(value); 0158 } 0159 0160 void MainWindow::slotComputeThumbNailCapChanged() 0161 { 0162 const int value = ui->imageScalerCap->value(); 0163 Q_ASSERT(value > 0); // limits set in UI file 0164 m_model.setComputeThumbNailCap(value); 0165 } 0166 0167 void MainWindow::slotSaveThumbNailCapChanged() 0168 { 0169 const int value = ui->fileWriterCap->value(); 0170 Q_ASSERT(value > 0); // limits set in UI file 0171 m_model.setSaveThumbNailCap(value); 0172 } 0173 0174 void MainWindow::slotWorkerCapChanged() 0175 { 0176 const int value = ui->workers->value(); 0177 Q_ASSERT(value >= 0); // limits set in UI file 0178 Queue::instance()->setMaximumNumberOfThreads(value); 0179 } 0180 0181 void MainWindow::slotEnableAverageLoadManager(bool enabled) 0182 { 0183 m_averageLoadManager->activate(enabled); 0184 } 0185 0186 void MainWindow::slotRecommendedWorkerCountChanged(int value) 0187 { 0188 auto const minMax = m_averageLoadManager->workersRange(); 0189 ui->workersSlider->setRange(minMax.first, minMax.second); 0190 ui->workersSlider->setValue(value); 0191 ui->loadManager->setText(tr("%1 workers").arg(value)); 0192 ui->workersMin->setText(QString::number(minMax.first)); 0193 ui->workersMax->setText(QString::number(minMax.second)); 0194 Queue::instance()->setMaximumNumberOfThreads(value); 0195 } 0196 0197 void MainWindow::slotQuit() 0198 { 0199 QSettings settings; 0200 settings.setValue(Setting_WindowGeometry, saveGeometry()); 0201 settings.setValue(Setting_WindowState, saveState()); 0202 ThreadWeaver::Queue::instance()->dequeue(); 0203 ThreadWeaver::Queue::instance()->finish(); 0204 QApplication::instance()->quit(); 0205 } 0206 0207 #include "moc_MainWindow.cpp"