Compare commits

..

5 Commits

Author SHA1 Message Date
nou 9e79133464 Fix compile error 2025-11-01 12:11:53 +01:00
nou e08107aa13 Improve Save as 2025-11-01 12:06:24 +01:00
nou 6eda2c4e48 Remove some code 2025-10-20 23:48:47 +02:00
nou b16ae3a9ee Add language setting 2025-10-20 21:29:59 +02:00
nou 56bba27ae3 Give save filter only formats that are supported 2025-10-20 00:23:11 +02:00
13 changed files with 121 additions and 34 deletions
+1 -1
Submodule libXISF updated: c6581e1122...2e74d94641
+9
View File
@@ -59,6 +59,15 @@
</screenshots>
<content_rating type="oars-1.1"/>
<releases>
<release version="20251101" date="2025-11-01">
<description>
<ul>
<li>Better image Save as</li>
<li>Fix xisf file corruption when platesolving</li>
<li>Add selecting language</li>
</ul>
</description>
</release>
<release version="20250915" date="2025-09-15">
<description>
<ul>
+3 -7
View File
@@ -113,12 +113,8 @@ BatchProcessing::BatchProcessing(Database *database, QWidget *parent) : QDialog(
_engine = new Script::ScriptEngine(_database, this);
connect(_engine, &Script::ScriptEngine::newMessage, this, &BatchProcessing::newMessage);
QStringList apiList;
apiList << "core.log" << "core.mark" << "core.unmark" << "core.isMarked" << "core.getObjects" << "core.setMaxthread";
apiList << "core.sync" << "core.getString" << "core.getInt" << "core.getFloat" << "core.question" << "core.plot";
apiList << "fileName" << "absoluteFileName";
_completerModel = new QStringListModel(this);
_completerModel->setStringList(apiList);
_completer = new QCompleter(_completerModel, this);
_ui->consoleLineEdit->setCompleter(_completer);
connect(_ui->executeButton, &QPushButton::clicked, _ui->consoleLineEdit, &QLineEdit::returnPressed);
@@ -128,13 +124,13 @@ BatchProcessing::BatchProcessing(Database *database, QWidget *parent) : QDialog(
QString program = _ui->consoleLineEdit->text();
QJSValue val = _engine->eval(program);
_ui->consoleLineEdit->addLine();
qDebug() << val.toString();
//qDebug() << val.toString();
}
});
connect(_ui->consoleLineEdit, &QLineEdit::textEdited, [this](const QString &text){
QStringList comp = _engine->complete(text);
qDebug() << comp;
//qDebug() << comp;
_completerModel->setStringList(comp);
});
+5 -1
View File
@@ -193,7 +193,11 @@ void ConvertRunable::run()
QFileInfo info(m_outfile);
info.dir().mkpath(".");
if(m_params.autostretch)
if(m_params.stretch)
{
rawimage->applySTF(m_params.mtf);
}
else if(m_params.autostretch)
{
rawimage->calcStats();
MTFParam mtfParam = rawimage->calcMTFParams();
+3
View File
@@ -6,6 +6,7 @@
#include <QSemaphore>
#include <QSize>
#include "imageinfodata.h"
#include "mtfparam.h"
class Image;
@@ -33,6 +34,8 @@ public:
QSize resize;
Qt::AspectRatioMode aspect = Qt::KeepAspectRatio;
bool autostretch = false;
bool stretch = false;
MTFParam mtf;
ConvertParams(){}
ConvertParams(const QVariantMap &map);
};
+14 -2
View File
@@ -3,6 +3,7 @@
#include <QSurfaceFormat>
#include <QTranslator>
#include <QCommandLineParser>
#include <QSettings>
#include <stdlib.h>
#include "../thumbnailer/genthumbnail.h"
@@ -76,8 +77,19 @@ int main(int argc, char *argv[])
QTranslator translator;
QTranslator translator2;
if(translator.load(QLocale(), "tenmon", "_", ":/translations"))
a.installTranslator(&translator);
QSettings settings;
QString lang = settings.value("settings/lang").toString();
if(lang.isEmpty())
{
if(translator.load(QLocale(), "tenmon", "_", ":/translations"))
a.installTranslator(&translator);
}
else
{
if(translator.load("tenmon_" + lang, ":/translations"))
a.installTranslator(&translator);
}
if(translator2.load(QLocale(), "tenmon", "_", a.applicationDirPath()))
a.installTranslator(&translator2);
+27 -15
View File
@@ -18,6 +18,7 @@
#include <QThreadPool>
#include <QStatusBar>
#include <QImageReader>
#include <QImageWriter>
#include <QMimeDatabase>
#include <QDesktopServices>
#include <QJsonDocument>
@@ -57,12 +58,18 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
for(auto format : supportedFormats)
{
QMimeType mimeType = db.mimeTypeForName(format);
_saveFilter.append(mimeType.filterString() + ";;");
_openFilter.append("*.");
_openFilter.append(mimeType.suffixes().join(" *."));
_openFilter.append(" ");
nameFilter.append(mimeType.suffixes());
}
auto supportedWrite = QImageWriter::supportedMimeTypes();
for(auto format : supportedWrite)
{
QMimeType mimeType = db.mimeTypeForName(format);
_saveFilter.append(mimeType.filterString() + ";;");
}
_openFilter.append("*.fit *.fits *.fts *.fz *.xisf *.cr2 *.cr3 *.nef *.dng)");
_openFilter.append(tr(";;All files (*)"));
nameFilter.append({"fit", "fits", "fts", "fz", "xisf", "cr2", "cr3", "nef", "dng"});
@@ -613,12 +620,16 @@ void MainWindow::reindex()
void MainWindow::saveAs()
{
QString selectedFilter;
ImagePtr ptr = m_ringList->currentImage();
if(!ptr)return;
QFileInfo srcFile(ptr->name());
QString file = QFileDialog::getSaveFileName(this,
tr("Save as"),
_lastDir,
_lastDir + "/" + srcFile.baseName(),
_saveFilter,
&selectedFilter);
auto filterToFormat = [](const QString &file, const QString &filter) -> const char*
auto filterToFormat = [](const QString &file, const QString &filter) -> const QString
{
QString suffix = QFileInfo(file).suffix();
if(!suffix.compare("jpg", Qt::CaseInsensitive) || !suffix.compare("jpeg", Qt::CaseInsensitive))return "jpeg";
@@ -628,30 +639,31 @@ void MainWindow::saveAs()
if(filter.contains("png"))return "png";
if(filter.contains("fits"))return "fits";
if(filter.contains("xisf"))return "xisf";
QRegularExpression suf("\\(\\*\\.([a-zA-Z]+).*\\)");
auto match = suf.match(filter);
if(match.hasMatch())
return match.captured(1);
return "jpeg";
};
if(!file.isEmpty())
{
auto button = QMessageBox::question(this, tr("Apply stretch?"), tr("Apply current stretch function to image?"));
QString format = filterToFormat(file, selectedFilter);
if(format == "fits" || format == "xisf")
{
convert(file, format);
}
else
{
QImage img = m_image->renderToImage();
if(!img.isNull())
img.save(file, filterToFormat(file, selectedFilter));
}
convert(file, format, button == QMessageBox::Yes);
}
}
void MainWindow::convert(const QString &outfile, const QString &format)
void MainWindow::convert(const QString &outfile, const QString &format, bool stretch)
{
QString file = m_ringList->currentImage()->name();
QThreadPool::globalInstance()->start(new ConvertRunable(file, outfile, format));
ConvertRunable::ConvertParams param;
param.stretch = stretch;
param.mtf = m_stretchPanel->params();
QThreadPool::globalInstance()->start(new ConvertRunable(file, outfile, format, param));
}
void MainWindow::markImage()
+1 -1
View File
@@ -52,7 +52,7 @@ public slots:
void indexDir(const QString &dir);
void reindex();
void saveAs();
void convert(const QString &outfile, const QString &format);
void convert(const QString &outfile, const QString &format, bool stretch);
void markImage();
void unmarkImage();
void markAndNext();
+22 -6
View File
@@ -1195,12 +1195,28 @@ void RawImage::applySTF(const MTFParam &mtfParams)
for(size_t i = 0; i < len; i++)
{
float x;
if constexpr(std::numeric_limits<std::remove_reference_t<decltype(*src)>>::is_integer)x = src[i] * iscale;
else x = src[i] * unit.first + unit.second;
x = (x - mtfParams.blackPoint[0]) / (mtfParams.whitePoint[0] - mtfParams.blackPoint[0]);
x = std::clamp(x, 0.0f, 1.0f);
x = ((mtfParams.midPoint[0] - 1.0f) * x) / ((2.0f * mtfParams.midPoint[0] - 1.0f) * x - mtfParams.midPoint[0]);
src[i] = x * s;
if(m_ch == 4)
{
size_t c = i & 0x3;
if(c < 3)
{
if constexpr(std::numeric_limits<std::remove_reference_t<decltype(*src)>>::is_integer)x = src[i] * iscale;
else x = src[i] * unit.first + unit.second;
x = (x - mtfParams.blackPoint[c]) / (mtfParams.whitePoint[c] - mtfParams.blackPoint[c]);
x = std::clamp(x, 0.0f, 1.0f);
x = ((mtfParams.midPoint[c] - 1.0f) * x) / ((2.0f * mtfParams.midPoint[c] - 1.0f) * x - mtfParams.midPoint[c]);
src[i] = x * s;
}
}
else
{
if constexpr(std::numeric_limits<std::remove_reference_t<decltype(*src)>>::is_integer)x = src[i] * iscale;
else x = src[i] * unit.first + unit.second;
x = (x - mtfParams.blackPoint[0]) / (mtfParams.whitePoint[0] - mtfParams.blackPoint[0]);
x = std::clamp(x, 0.0f, 1.0f);
x = ((mtfParams.midPoint[0] - 1.0f) * x) / ((2.0f * mtfParams.midPoint[0] - 1.0f) * x - mtfParams.midPoint[0]);
src[i] = x * s;
}
}
};
+29 -1
View File
@@ -129,11 +129,30 @@ SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent)
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);
@@ -150,7 +169,6 @@ SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent)
#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);
@@ -237,4 +255,14 @@ void SettingsDialog::saveSettings()
}
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);
}
+1
View File
@@ -32,6 +32,7 @@ private:
QListWidget *m_headerHighlight;
QColor m_color = Qt::yellow;
QLineEdit *m_keyword;
QComboBox *m_lang;
};
#endif // SETTINGSDIALOG_H
+5
View File
@@ -104,6 +104,11 @@ StretchToolbar::~StretchToolbar()
settings.setValue("stretchtoolbar/autostretch", m_autoStretchOnLoad->isChecked());
}
const MTFParam &StretchToolbar::params() const
{
return m_mtfParam;
}
void StretchToolbar::stretchImage(Image *img)
{
if(img && img->rawImage())
+1
View File
@@ -22,6 +22,7 @@ class StretchToolbar : public QToolBar
public:
explicit StretchToolbar(QWidget *parent = nullptr);
~StretchToolbar();
const MTFParam& params() const;
public slots:
void stretchImage(Image *img);
void resetMTF();