#include "settingsdialog.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "rawimage.h" extern int DEFAULT_WIDTH; extern double SATURATION; extern int FILTERING; extern bool BESTFIT; extern QMap headerHighlight; class EvenNumber : public QSpinBox { public: explicit EvenNumber(QWidget *parent) : QSpinBox(parent){} protected: QValidator::State validate(QString &text, int &) const { bool ok; int val = text.toInt(&ok); if(ok && (val & 1) == 0)return QValidator::Acceptable; if(ok)return QValidator::Intermediate; return QValidator::Invalid; } void fixup(QString &input) const { bool ok; int val = input.toInt(&ok); val -= val & 1; input = QString::number(val); } }; SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent) { QFormLayout *layout = new QFormLayout(this); setWindowTitle(tr("Settings")); QSettings settings; m_preloadImages = new QSpinBox(this); m_preloadImages->setRange(0, 32); m_preloadImages->setValue(settings.value("settings/preloadimagecount", DEFAULT_WIDTH).toInt()); m_preloadImages->setToolTip(tr("How many images are preloaded before and after current image.")); m_thumSize = new EvenNumber(this); m_thumSize->setRange(64, 512); m_thumSize->setSingleStep(2); m_thumSize->setValue(settings.value("settings/thumnailsize", THUMB_SIZE).toInt()); m_thumSize->setToolTip(tr("Thumbnail size in pixels")); m_saturation = new QDoubleSpinBox(this); m_saturation->setMinimum(0); m_saturation->setMaximum(100); m_saturation->setSuffix(" %"); m_saturation->setValue(settings.value("settings/saturation", SATURATION * 100.0).toDouble()); m_saturation->setToolTip(tr("Set threshold value that is considered saturated when showing statistics.\nFor RAW files you may set 22%")); m_slideShowTime = new QDoubleSpinBox(this); m_slideShowTime->setMinimum(0.01); m_slideShowTime->setMaximum(10); m_slideShowTime->setSuffix(" s"); m_slideShowTime->setValue(settings.value("settings/slideshowtime", 1.0).toDouble()); m_slideShowTime->setSingleStep(0.1); m_useNativeDialog = new QCheckBox(tr("Don't use native file dialog"), this); m_useNativeDialog->setChecked(QApplication::testAttribute(Qt::AA_DontUseNativeDialogs)); m_filtering = new QComboBox(this); m_filtering->addItems({tr("Nearest"), tr("Linear"), tr("Cubic")}); m_filtering->setCurrentIndex(FILTERING); m_qualityThumbnail = new QCheckBox(tr("Smooth thumbnails"), this); m_qualityThumbnail->setChecked(QUALITY_RESIZE); m_qualityThumbnail->setToolTip(tr("Use box filter when downsampling thumbnails instead of nearest. Slightly slower.")); m_bestFit = new QCheckBox(tr("Best Fit on image load")); m_bestFit->setToolTip(tr("Set Best Fit zoom level when opening new image.")); m_bestFit->setChecked(BESTFIT); m_headerHighlight = new QListWidget(this); m_headerHighlight->setToolTip(tr("List of FITS keywords that will be highlighted in Image info")); for(auto i = headerHighlight.begin(); i != headerHighlight.end(); i++) { QListWidgetItem *item = new QListWidgetItem(m_headerHighlight); item->setText(i.key()); item->setBackground(i.value()); } m_keyword = new QLineEdit(this); m_keyword->setPlaceholderText(tr("FITS keyword")); QPushButton *color = new QPushButton(this); QPixmap pix(16, 16); pix.fill(m_color); color->setIcon(pix); connect(color, &QPushButton::clicked, [this, color](){ QColor rgb = QColorDialog::getColor(m_color, this); if(rgb.isValid()) { QPixmap pix(16, 16); pix.fill(rgb); color->setIcon(pix); m_color = rgb; } }); QPushButton *add = new QPushButton(tr("Add keyword highlight"), this); connect(add, &QPushButton::clicked, [this](){ auto list = m_headerHighlight->findItems(m_keyword->text(), Qt::MatchFixedString | Qt::MatchCaseSensitive); if(list.size())return; QListWidgetItem *item = new QListWidgetItem(m_headerHighlight); item->setText(m_keyword->text()); item->setBackground(m_color); }); QPushButton *remove = new QPushButton(tr("Remove keyword highlight"), this); connect(remove, &QPushButton::clicked, [this](){ auto list = m_headerHighlight->selectedItems(); for(auto item : list) delete item; }); m_lang = new QComboBox(this); m_lang->addItems({"English", "Français", "Slovenčina", "Português"}); QString lang; switch(QLocale().language()) { default: case QLocale::English: lang = "en"; break; case QLocale::French: lang = "fr"; break; case QLocale::Slovak: lang = "sk"; break; case QLocale::Portuguese: lang = "pt_BR"; break; } lang = settings.value("settings/lang", lang).toString(); if(lang == "en")m_lang->setCurrentIndex(0); else if(lang == "fr")m_lang->setCurrentIndex(1); else if(lang == "sk")m_lang->setCurrentIndex(2); else if(lang == "pt_BR")m_lang->setCurrentIndex(3); layout->addRow(tr("Image preload count"), m_preloadImages); layout->addRow(tr("Thumbnails size"), m_thumSize); layout->addRow(tr("Saturation"), m_saturation); layout->addRow(tr("Slideshow interval"), m_slideShowTime); layout->addRow(tr("Image interpolation"), m_filtering); layout->addRow(tr("Language"), m_lang); layout->addRow(m_qualityThumbnail); layout->addRow(m_useNativeDialog); layout->addRow(m_bestFit); layout->addRow(new QLabel(tr("FITS header highlight"), this)); layout->addRow(m_headerHighlight); layout->addRow(m_keyword, color); layout->addRow(add, remove); #ifdef Q_OS_WIN64 QPushButton *installThumbnailer = new QPushButton(tr("Install"), this); installThumbnailer->setToolTip(tr("This will install thumnail generation for FITS and XISF files in File Explorer")); connect(installThumbnailer, &QPushButton::clicked, this, &SettingsDialog::installThumbnailer); layout->addRow(tr("Install thumbnailer"), installThumbnailer); #endif //layout->addRow(new QLabel(tr("Changes in settings will take effect after program restart."))); QDialogButtonBox *buttonBox = new QDialogButtonBox(this); buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); connect(this, &QDialog::accepted, this, &SettingsDialog::saveSettings); layout->addRow(buttonBox); } void SettingsDialog::loadSettings() { QSettings settings; THUMB_SIZE = settings.value("settings/thumbnailsize", THUMB_SIZE).toInt(); THUMB_SIZE_BORDER = THUMB_SIZE + 10; THUMB_SIZE_BORDER_Y = THUMB_SIZE + 30; DEFAULT_WIDTH = settings.value("settings/preloadimagecount", DEFAULT_WIDTH).toInt(); SATURATION = settings.value("settings/saturation", 95.0).toDouble() / 100.0; FILTERING = settings.value("settings/filtering", FILTERING).toInt(); QUALITY_RESIZE = settings.value("settings/qualitythumbnail", QUALITY_RESIZE).toBool(); BESTFIT = settings.value("settings/bestfit", BESTFIT).toBool(); QStringList keywords = settings.value("settings/headerhighlightkeywords").toStringList(); QStringList colors = settings.value("settings/headerhighlightcolors").toStringList(); for(int i = 0; i < std::min(keywords.size(), colors.size()); i++) headerHighlight.insert(keywords[i], QColor::fromString(colors[i])); QApplication::setAttribute(Qt::AA_DontUseNativeDialogs, settings.value("settings/dontusenativedialogs", false).toBool()); } bool SettingsDialog::loadThumbsizes() { QSettings settings; int OLD_THUMB_SIZE = THUMB_SIZE; THUMB_SIZE = settings.value("settings/thumbnailsize", THUMB_SIZE).toInt(); THUMB_SIZE_BORDER = THUMB_SIZE + 10; THUMB_SIZE_BORDER_Y = THUMB_SIZE + 30; return OLD_THUMB_SIZE != THUMB_SIZE; } void SettingsDialog::installThumbnailer() { #ifdef Q_OS_WIN64 QString path = QCoreApplication::instance()->applicationDirPath() + "/tenmonthumbnailer.dll"; if(!QFileInfo::exists(path)) { QMessageBox::critical(this, tr("Missing dll"), tr("Can't find ") + path); return; } QProcess regsvr; int ret = regsvr.execute("regsvr32.exe", {"/s", path}); if(ret == 0) QMessageBox::information(this, tr("Thumbnail support"), tr("Thumbnail generation support sucessufully installed.")); else QMessageBox::critical(this, tr("Error"), tr("Failed to register thumbnailer. %1").arg(ret)); #endif } void SettingsDialog::saveSettings() { QSettings settings; settings.setValue("settings/thumbnailsize", m_thumSize->value()); settings.setValue("settings/preloadimagecount", m_preloadImages->value()); settings.setValue("settings/dontusenativedialogs", m_useNativeDialog->isChecked()); settings.setValue("settings/saturation", m_saturation->value()); settings.setValue("settings/slideshowtime", m_slideShowTime->value()); settings.setValue("settings/qualitythumbnail", m_qualityThumbnail->isChecked()); QUALITY_RESIZE = m_qualityThumbnail->isChecked(); FILTERING = m_filtering->currentIndex(); BESTFIT = m_bestFit->isChecked(); settings.setValue("settings/filtering", FILTERING); settings.setValue("settings/bestfit", BESTFIT); SATURATION = m_saturation->value() / 100.0; QApplication::setAttribute(Qt::AA_DontUseNativeDialogs, m_useNativeDialog->isChecked()); if(DEFAULT_WIDTH != m_preloadImages->value()) emit preloadChanged(m_preloadImages->value()); headerHighlight.clear(); QStringList colors; for(int i = 0; i < m_headerHighlight->count(); i++) { auto item = m_headerHighlight->item(i); colors.push_back(item->background().color().name()); headerHighlight[item->text()] = item->background().color(); } settings.setValue("settings/headerhighlightkeywords", headerHighlight.keys()); settings.setValue("settings/headerhighlightcolors", colors); QString lang; int langIdx = m_lang->currentIndex(); switch(langIdx) { case 0: lang = "en"; break; case 1: lang = "fr"; break; case 2: lang = "sk"; break; case 3: lang = "pt_BR"; break; } settings.setValue("settings/lang", lang); }