diff --git a/DeepSkyStacker/DeepSkyStacker.cpp b/DeepSkyStacker/DeepSkyStacker.cpp
index 0866981e8..3c475155e 100644
--- a/DeepSkyStacker/DeepSkyStacker.cpp
+++ b/DeepSkyStacker/DeepSkyStacker.cpp
@@ -63,7 +63,6 @@ namespace bip = boost::interprocess;
#include "QEventLogger.h"
-CString OUTPUTFILE_FILTERS;
CString STARMASKFILE_FILTERS;
bool g_bShowRefStars = false;
@@ -732,8 +731,6 @@ BOOL DeepSkyStackerApp::InitInstance()
AfxInitRichEdit2();
-
- OUTPUTFILE_FILTERS.LoadString(IDS_FILTER_OUTPUT);
STARMASKFILE_FILTERS.LoadString(IDS_FILTER_MASK);
return TRUE;
diff --git a/DeepSkyStacker/DeepSkyStacker.vcxproj b/DeepSkyStacker/DeepSkyStacker.vcxproj
index 73e96a7fa..f0a9829dd 100644
--- a/DeepSkyStacker/DeepSkyStacker.vcxproj
+++ b/DeepSkyStacker/DeepSkyStacker.vcxproj
@@ -429,7 +429,7 @@ $(QtToolsPath)\windeployqt --pdb $(TargetPath)
-
+
diff --git a/DeepSkyStacker/DeepSkyStacker.vcxproj.filters b/DeepSkyStacker/DeepSkyStacker.vcxproj.filters
index b456023ea..6c3d29ed4 100644
--- a/DeepSkyStacker/DeepSkyStacker.vcxproj.filters
+++ b/DeepSkyStacker/DeepSkyStacker.vcxproj.filters
@@ -271,9 +271,6 @@
Header Files
-
- Dialogs\Processing
-
Dialogs\Processing
@@ -885,6 +882,9 @@
Dialogs\Processing
+
+ Dialogs\Processing
+
diff --git a/DeepSkyStacker/ProcessingDlg.cpp b/DeepSkyStacker/ProcessingDlg.cpp
index c0ead43f5..b599a231e 100644
--- a/DeepSkyStacker/ProcessingDlg.cpp
+++ b/DeepSkyStacker/ProcessingDlg.cpp
@@ -5,6 +5,7 @@
#include "selectrect.h"
#include "FrameInfoSupport.h"
#include "ProcessingSettingsDlg.h"
+#include "SavePicture.h"
#include
#define dssApp DeepSkyStacker::instance()
@@ -238,28 +239,7 @@ namespace DSS
bool ProcessingDlg::saveOnClose()
{
- ZFUNCTRACE_RUNTIME();
- //
- // The existing image is being closed and has been changed, ask the user if they want to save it
- //
- if (dirty_)
- {
- QString message{ tr("Do you want to save the modifications?", "IDS_MSG_SAVEMODIFICATIONS")};
- auto result = QMessageBox::question(this, "DeepSkyStacker",
- message, (QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel), QMessageBox::No);
- switch (result)
- {
- case QMessageBox::Cancel:
- return false;
- break;
- case QMessageBox::No:
- return true;
- break;
- default:
- return saveImage();
- }
- }
- else return true;
+ return askToSave();
}
/* ------------------------------------------------------------------- */
@@ -282,10 +262,10 @@ namespace DSS
/* ------------------------------------------------------------------- */
- void ProcessingDlg::loadFile(const fs::path& file)
+ void ProcessingDlg::loadStackedImage(const fs::path& file)
{
ZFUNCTRACE_RUNTIME();
- qDebug() << "Load File";
+ qDebug() << "Load stacked image";
//
// Load the output file created at the end of the stacking process.
@@ -336,88 +316,90 @@ namespace DSS
ZFUNCTRACE_RUNTIME();
qDebug() << "Load image";
- QFileDialog fileDialog(this);
- QSettings settings;
- QString directory;
- QString extension;
- QString strTitle;
- fs::path file;
+ if (askToSave())
+ {
- DSS::ProgressDlg dlg{ DeepSkyStacker::instance() };
+ QFileDialog fileDialog(this);
+ QSettings settings;
+ QString directory;
+ QString extension;
+ QString strTitle;
+ fs::path file;
- timer.stop();
+ DSS::ProgressDlg dlg{ DeepSkyStacker::instance() };
- directory = settings.value("Folders/SaveDSIFolder").toString();
- extension = settings.value("Folders/SavePictureExtension").toString();
- if (extension.isEmpty()) extension = "tif";
- fileDialog.setDefaultSuffix(extension);
- fileDialog.setFileMode(QFileDialog::ExistingFile); // There can be only one
+ timer.stop();
- fileDialog.setNameFilter(tr("TIFF and FITS Files (*.tif *.tiff *.fits *.fit *.fts)", "IDS_FILTER_DSIIMAGETIFF"));
- fileDialog.selectFile(QString()); // No file(s) selected
- if (!directory.isEmpty())
- fileDialog.setDirectory(directory);
+ directory = settings.value("Folders/SaveDSIFolder").toString();
+ extension = settings.value("Folders/SavePictureExtension").toString();
+ if (extension.isEmpty()) extension = "tif";
+ fileDialog.setDefaultSuffix(extension);
+ fileDialog.setFileMode(QFileDialog::ExistingFile); // There can be only one
- if (QDialog::Accepted == fileDialog.exec())
- {
- QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
- QStringList files = fileDialog.selectedFiles();
+ fileDialog.setNameFilter(tr("TIFF and FITS Files (*.tif *.tiff *.fits *.fit *.fts)", "IDS_FILTER_DSIIMAGETIFF"));
+ fileDialog.selectFile(QString()); // No file(s) selected
+ if (!directory.isEmpty())
+ fileDialog.setDirectory(directory);
- //
- // Now get the file as a standard fs::path object
- //
- if (!files.empty()) // Never, ever attempt to add zero rows!!!
+ if (QDialog::Accepted == fileDialog.exec())
{
- file = files.at(0).toStdU16String();
-
- if (file.has_parent_path())
- directory = QString::fromStdU16String(file.parent_path().generic_u16string());
- else
- directory = QString::fromStdU16String(file.root_path().generic_u16string());
+ QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
+ QStringList files = fileDialog.selectedFiles();
- extension = QString::fromStdU16String(file.extension().generic_u16string());
- }
-
- settings.setValue("Folders/SaveDSIFolder", directory);
- settings.setValue("Folders/SavePictureExtension", extension);
+ //
+ // Now get the file as a standard fs::path object
+ //
+ if (!files.empty()) // Never, ever attempt to add zero rows!!!
+ {
+ file = files.at(0).toStdU16String();
- //
- // Finally load the file of interest
- //
- currentFile = file; // Remember the current file
- dssApp->deepStack().reset();
- dssApp->deepStack().SetProgress(&dlg);
- bool OK = dssApp->deepStack().LoadStackedInfo(file);
- ZASSERT(OK);
+ if (file.has_parent_path())
+ directory = QString::fromStdU16String(file.parent_path().generic_u16string());
+ else
+ directory = QString::fromStdU16String(file.root_path().generic_u16string());
- dssApp->deepStack().SetProgress(nullptr);
+ extension = QString::fromStdU16String(file.extension().generic_u16string());
+ }
- modifyRGBKGradientControls();
- updateInformation();
+ settings.setValue("Folders/SaveDSIFolder", directory);
+ settings.setValue("Folders/SavePictureExtension", extension);
- dssApp->deepStack().GetStackedBitmap().GetBezierAdjust(processingSettings.bezierAdjust_);
- dssApp->deepStack().GetStackedBitmap().GetHistogramAdjust(processingSettings.histoAdjust_);
+ //
+ // Finally load the file of interest
+ //
+ currentFile = file; // Remember the current file
+ dssApp->deepStack().reset();
+ dssApp->deepStack().SetProgress(&dlg);
+ bool OK = dssApp->deepStack().LoadStackedInfo(file);
+ ZASSERT(OK);
- updateControlsFromSettings();
+ dssApp->deepStack().SetProgress(nullptr);
- showHistogram(false);
- resetSliders();
- int height = dssApp->deepStack().GetHeight();
- rectToProcess.Init(dssApp->deepStack().GetWidth(), height, height / 3);
+ modifyRGBKGradientControls();
+ updateInformation();
- processingSettingsList.clear();
- picture->clear();
- processAndShow(true);
+ dssApp->deepStack().GetStackedBitmap().GetBezierAdjust(processingSettings.bezierAdjust_);
+ dssApp->deepStack().GetStackedBitmap().GetHistogramAdjust(processingSettings.histoAdjust_);
- setDirty(false);
+ updateControlsFromSettings();
- timer.start();
+ showHistogram(false);
+ resetSliders();
+ int height = dssApp->deepStack().GetHeight();
+ rectToProcess.Init(dssApp->deepStack().GetWidth(), height, height / 3);
- QGuiApplication::restoreOverrideCursor();
+ processingSettingsList.clear();
+ picture->clear();
+ processAndShow(true);
- };
+ setDirty(false);
+ timer.start();
+ QGuiApplication::restoreOverrideCursor();
+
+ }
+ }
}
/* ------------------------------------------------------------------- */
@@ -427,6 +409,46 @@ namespace DSS
ZFUNCTRACE_RUNTIME();
qDebug() << "Save image to file";
bool bResult = false;
+
+
+ if (dssApp->deepStack().IsLoaded())
+ {
+ QSettings settings;
+
+ auto baseDirectory{ settings.value("Folders/SavePictureFolder").toString() };
+ auto extension{ settings.value("Folders/SavePictureExtension").toString().toLower() };
+ auto applied{ settings.value("Folders/SaveApplySetting", false).toBool() };
+ auto compression{ settings.value("Folders/SaveCompression", (uint)TC_NONE).toUInt() };
+ auto filterIndex{ settings.value("Folders/SavePictureIndex", 0).toUInt() };
+
+
+ QStringList fileFilters{
+ tr("TIFF Image 16 bit/ch (*.tif)", "IDS_FILTER_OUTPUT"),
+ tr("TIFF Image 32 bit/ch - integer (*.tif)", "IDS_FILTER_OUTPUT"),
+ tr("TIFF Image 32 bit/ch - rational (*.tif)", "IDS_FILTER_OUTPUT"),
+ tr("FITS Image 16 bit/ch (*.fts)", "IDS_FILTER_OUTPUT"),
+ tr("FITS Image 32 bit/ch - integer (*.fts)", "IDS_FILTER_OUTPUT"),
+ tr("FITS Image 32 bit/ch - rational (*.fts)", "IDS_FILTER_OUTPUT")
+ };
+
+ if (extension.isEmpty()) extension = ".tif";
+
+ //
+ // SavePicture is a sub-class of QFileDialog, we'll set the QFileDialog vars first
+ //
+ SavePicture dlg{ this, tr("Save Image"), baseDirectory };
+ dlg.setDefaultSuffix(extension);
+ dlg.setNameFilters(fileFilters);
+ dlg.selectNameFilter(fileFilters.at(filterIndex));
+ dlg.setFilter(QDir::Files | QDir::Writable);
+
+ //
+ // Now set our sub-class variables
+ //
+ dlg.setCompression(TIFFCOMPRESSION(compression));
+ dlg.setApply(applied);
+ dlg.exec();
+ }
/*
QSettings settings;
CString strBaseDirectory;
@@ -1126,6 +1148,33 @@ namespace DSS
rectToProcess.Reset();
};
+ /* ------------------------------------------------------------------- */
+
+ bool ProcessingDlg::askToSave()
+ {
+ ZFUNCTRACE_RUNTIME();
+ //
+ // The existing image is being closed and has been changed, ask the user if they want to save it
+ //
+ if (dirty_)
+ {
+ QString message{ tr("Do you want to save the modifications?", "IDS_MSG_SAVEMODIFICATIONS") };
+ auto result = QMessageBox::question(this, "DeepSkyStacker",
+ message, (QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel), QMessageBox::No);
+ switch (result)
+ {
+ case QMessageBox::Cancel:
+ return false;
+ break;
+ case QMessageBox::No:
+ return true;
+ break;
+ default:
+ return saveImage();
+ }
+ }
+ else return true;
+ };
//
@@ -1189,40 +1238,51 @@ namespace DSS
timer.start();
};
-
+ void ProcessingDlg::updateBezierCurve()
+ {
+ setDirty();
+ showHistogram();
+ };
void ProcessingDlg::darkAngleChanged()
{
updateDarkText();
+ emit updateBezierCurve();
}
void ProcessingDlg::darkPowerChanged()
{
updateDarkText();
+ emit updateBezierCurve();
}
void ProcessingDlg::midAngleChanged()
{
updateMidText();
+ emit updateBezierCurve();
}
void ProcessingDlg::midToneChanged()
{
updateMidText();
+ emit updateBezierCurve();
}
void ProcessingDlg::highAngleChanged()
{
updateHighText();
+ emit updateBezierCurve();
}
void ProcessingDlg::highPowerChanged()
{
updateHighText();
+ emit updateBezierCurve();
}
void ProcessingDlg::saturationChanged()
{
+ setDirty();
updateSaturationText();
}
@@ -1556,122 +1616,6 @@ void CProcessingDlg::OnShowWindow(BOOL bShow, UINT nStatus)
/* ------------------------------------------------------------------- */
-void CProcessingDlg::LoadFile(LPCTSTR szFileName)
-{
-
-};
-
-/* ------------------------------------------------------------------- */
-
-void CProcessingDlg::OnLoaddsi()
-{
- if (AskToSave())
- {
- bool bOk = false;
- CString strFilter;
- QSettings settings;
-
- CString strBaseDirectory = (LPCTSTR)settings.value("Folders/SaveDSIFolder", QString("")).toString().utf16();
-
- strFilter.LoadString(IDS_FILTER_DSIIMAGETIFF);
- CFileDialog dlgOpen(true,
- _T(".DSImage"),
- nullptr,
- OFN_FILEMUSTEXIST | OFN_EXPLORER | OFN_PATHMUSTEXIST,
- strFilter,
- this);
- TCHAR szBigBuffer[20000] = _T("");
- DSS::ProgressDlg dlg{ DeepSkyStacker::instance() };
-
- if (strBaseDirectory.GetLength())
- dlgOpen.m_ofn.lpstrInitialDir = strBaseDirectory.GetBuffer(_MAX_PATH);
-
- timer.stop();
-
- dlgOpen.m_ofn.lpstrFile = szBigBuffer;
- dlgOpen.m_ofn.nMaxFile = sizeof(szBigBuffer) / sizeof(szBigBuffer[0]);
-
- if (dlgOpen.DoModal() == IDOK)
- {
- CString strFile;
- POSITION pos;
-
- pos = dlgOpen.GetStartPosition();
- while (pos && !bOk)
- {
- BeginWaitCursor();
- strFile = dlgOpen.GetNextPathName(pos);
- dssApp->deepStack().Clear();
- dssApp->deepStack().SetProgress(&dlg);
- bOk = dssApp->deepStack().LoadStackedInfo(strFile);
- dssApp->deepStack().SetProgress(nullptr);
- EndWaitCursor();
- };
-
- if (bOk)
- {
- m_strCurrentFile = strFile;
-
- TCHAR szDir[1 + _MAX_DIR];
- TCHAR szDrive[1 + _MAX_DRIVE];
-
- _tsplitpath(strFile, szDrive, szDir, nullptr, nullptr);
- strBaseDirectory = szDrive;
- strBaseDirectory += szDir;
-
- settings.setValue("Folders/SaveDSIFolder", QString::fromWCharArray(strBaseDirectory.GetString()));
-
- UpdateMonochromeControls();
- UpdateInfos();
- BeginWaitCursor();
- dssApp->deepStack().GetStackedBitmap().GetBezierAdjust(processingSettings.bezierAdjust_);
- dssApp->deepStack().GetStackedBitmap().GetHistogramAdjust(processingSettings.histoAdjust_);
-
- updateControlsFromSettings();
-
- showHistogram(false);
- // resetSliders();
- int height = dssApp->deepStack().GetHeight();
- rectToProcess.Init(dssApp->deepStack().GetWidth(), height, height / 3);
-
- processingSettingsList.clear();
- m_Picture.SetImg((HBITMAP)nullptr);
- processAndShow(true);
- EndWaitCursor();
- m_bDirty = false;
- };
- };
-
- timer.start();
- };
-}
-
-/* ------------------------------------------------------------------- */
-
-bool CProcessingDlg::AskToSave()
-{
- bool bResult = false;
-
- if (m_bDirty)
- {
- int nResult;
-
- nResult = AfxMessageBox(IDS_MSG_SAVEMODIFICATIONS, MB_YESNOCANCEL | MB_ICONQUESTION);
- if (nResult == IDCANCEL)
- bResult = false;
- else if (nResult == IDNO)
- bResult = true;
- else
- bResult = SavePictureToFile();
- }
- else
- bResult = true;
-
- return bResult;
-};
-
-/* ------------------------------------------------------------------- */
-
void CProcessingDlg::CopyPictureToClipboard()
{
HBITMAP hBitmap;
@@ -1727,194 +1671,4 @@ void CProcessingDlg::CreateStarMask()
}
-bool CProcessingDlg::SavePictureToFile()
-{
- bool bResult = false;
- QSettings settings;
- CString strBaseDirectory;
- CString strBaseExtension;
- bool applied = false;
- uint dwCompression;
- CRect rcSelect;
-
- if (dssApp->deepStack().IsLoaded())
- {
- strBaseDirectory = (LPCTSTR)settings.value("Folders/SavePictureFolder").toString().utf16();
- strBaseExtension = (LPCTSTR)settings.value("Folders/SavePictureExtension").toString().utf16();
- auto dwFilterIndex = settings.value("Folders/SavePictureIndex", 0).toUInt();
- applied = settings.value("Folders/SaveApplySetting", false).toBool();
- dwCompression = settings.value("Folders/SaveCompression", (uint)TC_NONE).toUInt();
-
- if (!strBaseExtension.GetLength())
- strBaseExtension = _T(".tif");
-
- CSavePicture dlgOpen(false,
- _T(".TIF"),
- nullptr,
- OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_ENABLESIZING,
- OUTPUTFILE_FILTERS,
- this);
-
- if (m_SelectRectSink.GetSelectRect(rcSelect))
- dlgOpen.SetUseRect(true, true);
- if (applied)
- dlgOpen.SetApplied(true);
-
- dlgOpen.SetCompression((TIFFCOMPRESSION)dwCompression);
-
- if (strBaseDirectory.GetLength())
- dlgOpen.m_ofn.lpstrInitialDir = strBaseDirectory.GetBuffer(_MAX_PATH);
- dlgOpen.m_ofn.nFilterIndex = dwFilterIndex;
-
- TCHAR szBigBuffer[20000] = _T("");
- DSS::ProgressDlg dlg{ DeepSkyStacker::instance() };
-
- dlgOpen.m_ofn.lpstrFile = szBigBuffer;
- dlgOpen.m_ofn.nMaxFile = sizeof(szBigBuffer) / sizeof(szBigBuffer[0]);
-
- if (dlgOpen.DoModal() == IDOK)
- {
- POSITION pos;
-
- pos = dlgOpen.GetStartPosition();
- if (pos)
- {
- CString strFile;
- LPRECT lpRect = nullptr;
- bool bApply;
- bool bUseRect;
- TIFFCOMPRESSION Compression;
-
- bApply = dlgOpen.GetApplied();
- bUseRect = dlgOpen.GetUseRect();
- Compression = dlgOpen.GetCompression();
-
- if (bUseRect && m_SelectRectSink.GetSelectRect(rcSelect))
- lpRect = &rcSelect;
-
- BeginWaitCursor();
- strFile = dlgOpen.GetNextPathName(pos);
- if (dlgOpen.m_ofn.nFilterIndex == 1)
- dssApp->deepStack().GetStackedBitmap().SaveTIFF16Bitmap(strFile, lpRect, &dlg, bApply, Compression);
- else if (dlgOpen.m_ofn.nFilterIndex == 2)
- dssApp->deepStack().GetStackedBitmap().SaveTIFF32Bitmap(strFile, lpRect, &dlg, bApply, false, Compression);
- else if (dlgOpen.m_ofn.nFilterIndex == 3)
- dssApp->deepStack().GetStackedBitmap().SaveTIFF32Bitmap(strFile, lpRect, &dlg, bApply, true, Compression);
- else if (dlgOpen.m_ofn.nFilterIndex == 4)
- dssApp->deepStack().GetStackedBitmap().SaveFITS16Bitmap(strFile, lpRect, &dlg, bApply);
- else if (dlgOpen.m_ofn.nFilterIndex == 5)
- dssApp->deepStack().GetStackedBitmap().SaveFITS32Bitmap(strFile, lpRect, &dlg, bApply, false);
- else if (dlgOpen.m_ofn.nFilterIndex == 6)
- dssApp->deepStack().GetStackedBitmap().SaveFITS32Bitmap(strFile, lpRect, &dlg, bApply, true);
-
- TCHAR szDir[1 + _MAX_DIR];
- TCHAR szDrive[1 + _MAX_DRIVE];
- TCHAR szExt[1 + _MAX_EXT];
-
- _tsplitpath(strFile, szDrive, szDir, nullptr, szExt);
- strBaseDirectory = szDrive;
- strBaseDirectory += szDir;
- strBaseExtension = szExt;
-
- dwFilterIndex = dlgOpen.m_ofn.nFilterIndex;
- settings.setValue("Folders/SavePictureFolder", QString::fromWCharArray(strBaseDirectory.GetString()));
- settings.setValue("Folders/SavePictureExtension", QString::fromWCharArray(strBaseExtension.GetString()));
- settings.setValue("Folders/SavePictureIndex", (uint)dwFilterIndex);
- settings.setValue("Folders/SaveApplySetting", bApply);
- settings.setValue("Folders/SaveCompression", (uint)Compression);
-
- EndWaitCursor();
-
- m_strCurrentFile = strFile;
- UpdateInfos();
- m_bDirty = false;
- bResult = true;
- };
- };
- }
- else
- {
- AfxMessageBox(IDS_MSG_NOPICTURETOSAVE, MB_OK | MB_ICONSTOP);
- };
-
- return bResult;
-};
-
-/* ------------------------------------------------------------------- */
-
-void CProcessingDlg::OnProcess()
-{
- processAndShow(true);
-}
-
-
-/* ------------------------------------------------------------------- */
-
-
-/* ------------------------------------------------------------------- */
-
-void CProcessingDlg::OnNotifyRedChangeSelPeg(NMHDR*, LRESULT*)
-{
- m_bDirty = true;
- showHistogram();
-};
-
-void CProcessingDlg::OnNotifyRedPegMove(NMHDR*, LRESULT*)
-{
- m_bDirty = true;
- showHistogram();
-};
-
-void CProcessingDlg::OnNotifyRedPegMoved(NMHDR*, LRESULT*)
-{
- m_bDirty = true;
- showHistogram();
-};
-
-void CProcessingDlg::OnNotifyGreenChangeSelPeg(NMHDR*, LRESULT*)
-{
- m_bDirty = true;
- showHistogram();
-};
-
-void CProcessingDlg::OnNotifyGreenPegMove(NMHDR*, LRESULT*)
-{
- m_bDirty = true;
- showHistogram();
-};
-
-void CProcessingDlg::OnNotifyGreenPegMoved(NMHDR*, LRESULT*)
-{
- m_bDirty = true;
- showHistogram();
-};
-
-void CProcessingDlg::OnNotifyBlueChangeSelPeg(NMHDR*, LRESULT*)
-{
- m_bDirty = true;
- showHistogram();
-};
-
-void CProcessingDlg::OnNotifyBluePegMove(NMHDR*, LRESULT*)
-{
- m_bDirty = true;
- showHistogram();
-};
-
-void CProcessingDlg::OnNotifyBluePegMoved(NMHDR*, LRESULT*)
-{
- m_bDirty = true;
- showHistogram();
-};
-
-/* ------------------------------------------------------------------- */
-
-void CProcessingDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
-{
- m_bDirty = true;
- showHistogram();
- CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
-}
-
-/* ------------------------------------------------------------------- */
#endif
\ No newline at end of file
diff --git a/DeepSkyStacker/ProcessingDlg.h b/DeepSkyStacker/ProcessingDlg.h
index 17e9ec39f..dd28ffc8f 100644
--- a/DeepSkyStacker/ProcessingDlg.h
+++ b/DeepSkyStacker/ProcessingDlg.h
@@ -307,7 +307,7 @@ namespace DSS
void copyToClipboard();
void createStarMask();
- void loadFile(const fs::path& file);
+ void loadStackedImage(const fs::path& file);
void loadImage();
bool saveImage();
@@ -361,7 +361,6 @@ namespace DSS
void processAndShow(bool bSaveUndo = true); // Driven by Apply button
-
inline void updateDarkText()
{
//
@@ -428,6 +427,8 @@ namespace DSS
void UpdateHistogramAdjust();
+ bool askToSave();
+
public slots:
void setSelectionRect(const QRectF& rect);
@@ -468,6 +469,8 @@ namespace DSS
void highAngleChanged();
void highPowerChanged();
+ void updateBezierCurve();
+
void saturationChanged();
@@ -483,9 +486,6 @@ namespace DSS
bool SavePictureToFile();
void CreateStarMask();
- void LoadFile(LPCTSTR szFileName);
-
-
#endif
};
diff --git a/DeepSkyStacker/ProcessingSettingsDlg.cpp b/DeepSkyStacker/ProcessingSettingsDlg.cpp
index f0c3b1b62..842e96761 100644
--- a/DeepSkyStacker/ProcessingSettingsDlg.cpp
+++ b/DeepSkyStacker/ProcessingSettingsDlg.cpp
@@ -140,7 +140,7 @@ namespace DSS {
void ProcessingSettingsDlg::nameEdited(const QString& text)
{
- if (text.contains(QRegularExpression("[/\\]")))
+ if (text.contains(QRegularExpression("[/\\\\]")))
{
QApplication::beep();
QMessageBox::critical(const_cast(this), "DeepSkyStacker",
diff --git a/DeepSkyStacker/ProcessingSettingsDlg.h b/DeepSkyStacker/ProcessingSettingsDlg.h
index e8970223f..f22f7ab93 100644
--- a/DeepSkyStacker/ProcessingSettingsDlg.h
+++ b/DeepSkyStacker/ProcessingSettingsDlg.h
@@ -33,7 +33,8 @@
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
**
-****************************************************************************/#include
+****************************************************************************/
+#include
#include "BaseDialog.h"
#include "ProcessingSettings.h"
#include "ui_ProcessingSettingsDlg.h"
diff --git a/DeepSkyStacker/SavePicture.cpp b/DeepSkyStacker/SavePicture.cpp
index 85684328f..7ce2fd59b 100644
--- a/DeepSkyStacker/SavePicture.cpp
+++ b/DeepSkyStacker/SavePicture.cpp
@@ -1,9 +1,180 @@
+/****************************************************************************
+**
+** Copyright (C) 2024 David C. Partridge
+**
+** BSD License Usage
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of DeepSkyStacker nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+**
+****************************************************************************/
// SavePicture.cpp : implementation file
//
-
#include "stdafx.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+
#include "SavePicture.h"
-#include "resourceCZ.h"
+
+namespace DSS
+{
+ SavePicture::SavePicture(QWidget* parent, const QString& caption, const QString& directory, const QString& filter) :
+ QFileDialog(parent, caption, directory, filter),
+ compressionGroup(new QGroupBox(this)),
+ compressionLayout(new QHBoxLayout(compressionGroup)),
+ compressionNone(new QRadioButton(compressionGroup)),
+ compressionZIP(new QRadioButton(compressionGroup)),
+ compressionLZW(new QRadioButton(compressionGroup)),
+ optionsGroup(new QGroupBox(this)),
+ optionsLayout(new QVBoxLayout(optionsGroup)),
+ applyAdjustments(new QRadioButton(optionsGroup)),
+ embedAdjustments(new QRadioButton(optionsGroup)),
+ useRectangle(new QCheckBox(optionsGroup))
+ {
+ compressionGroup->setObjectName("compressionGroup");
+ compressionLayout->setObjectName("compressionLayout");
+ compressionNone->setObjectName("compressionNone");
+ compressionZIP->setObjectName("compressionZIP");
+ compressionLZW->setObjectName("compressionLZW");
+
+ optionsGroup->setObjectName("optionsGroup");
+ optionsLayout->setObjectName("optionsLayout");
+ applyAdjustments->setObjectName("applyAdjustments");
+ embedAdjustments->setObjectName("embedAdjustments");
+ useRectangle->setObjectName("useRectangle");
+
+ compressionGroup->setLayout(compressionLayout);
+ compressionLayout->addWidget(compressionNone);
+ compressionLayout->addWidget(compressionZIP);
+ compressionLayout->addWidget(compressionLZW);
+
+ optionsGroup->setLayout(optionsLayout);
+ optionsLayout->addWidget(applyAdjustments);
+ optionsLayout->addWidget(embedAdjustments);
+ optionsLayout->addWidget(useRectangle);
+
+ retranslateUi(this);
+
+ //
+ // Setting DontUseNativeDialog forces Qt to use a Widget based dialogue.
+ //
+ // This uses a QGridLayout to position the controls, and we can add
+ // additional controls using QGridLayout::addWidget()
+ //
+ setOption(QFileDialog::DontUseNativeDialog);
+
+ QGridLayout* layout{ dynamic_cast(this->layout()) };
+ layout->addWidget(compressionGroup, layout->rowCount(), 0, 1, 2);
+ layout->addWidget(optionsGroup, layout->rowCount(), 0, 1, 2);
+
+ connectSignalsToSlots();
+ }
+
+ void SavePicture::retranslateUi([[maybe_unused]]QWidget* wdgt)
+ {
+ compressionGroup->setTitle(tr("Compression", "IDD_SAVEPICTURE"));
+ compressionNone->setText(tr("None", "IDC_COMPRESSION_NONE"));
+ compressionZIP->setText(tr("ZIP (Deflate)", "IDC_COMPRESSION_ZIP"));
+ compressionLZW->setText(tr("LZW (Deprecated)", "IDC_COMPRESSION_LZW"));
+ optionsGroup->setTitle(tr("Options", "IDD_SAVEPICTURE"));
+ applyAdjustments->setText(tr("Apply adjustments to the saved image", "IDC_APPLIED"));
+ embedAdjustments->setText(tr("Embed adjustments in the saved image but do not apply them", "IDC_EMBEDDED"));
+ embedText = embedAdjustments->text();
+ noAdjustments = tr("Do not apply adjustments to the saved image", "IDS_SAVENOADJUSTMENT");
+ useRectangle->setText(tr("Create an image from the selected rectangle", "IDC_USERECT"));
+ }
+
+ void SavePicture::connectSignalsToSlots()
+ {
+ connect(compressionNone, &QRadioButton::clicked, this, &SavePicture::onCompressionNone);
+ connect(compressionZIP, &QRadioButton::clicked, this, &SavePicture::onCompressionZIP);
+ connect(compressionLZW, &QRadioButton::clicked, this, &SavePicture::onCompressionLZW);
+ connect(applyAdjustments, &QRadioButton::clicked, this, &SavePicture::onApply);
+ connect(embedAdjustments, &QRadioButton::clicked, this, &SavePicture::onEmbed);
+ connect(this, &QFileDialog::filterSelected, this, &SavePicture::onFilter);
+ }
+
+ //
+ // Slots
+ //
+ void SavePicture::onCompressionNone(bool checked)
+ {
+ if (checked) compression_ = TC_NONE;
+ }
+
+ void SavePicture::onCompressionZIP(bool checked)
+ {
+ if (checked) compression_ = TC_DEFLATE;
+ }
+
+ void SavePicture::onCompressionLZW(bool checked)
+ {
+ if (checked) compression_ = TC_LZW;
+ }
+
+ void SavePicture::onApply(bool checked)
+ {
+ if (checked) apply_ = true;
+ }
+
+ void SavePicture::onEmbed(bool checked)
+ {
+ if (checked) apply_ = false;
+ }
+
+
+ void SavePicture::onFilter(const QString& filter)
+ {
+ auto index{ nameFilters().indexOf(filter) };
+ if (index > 2) // FITS files
+ {
+ compression_ = TC_NONE;
+ compressionNone->setChecked(true);
+ compressionZIP->setEnabled(false);
+ compressionLZW->setEnabled(false);
+ embedAdjustments->setText(noAdjustments);
+ }
+ else // TIF files
+ {
+ compressionZIP->setEnabled(true);
+ compressionLZW->setEnabled(true);
+ embedAdjustments->setText(embedText);
+ }
+ }
+
+}
+
+#if (0)
/* ------------------------------------------------------------------- */
// CSavePicture
@@ -204,3 +375,4 @@ void CSavePicture::OnTypeChange()
/* ------------------------------------------------------------------- */
+#endif
\ No newline at end of file
diff --git a/DeepSkyStacker/SavePicture.h b/DeepSkyStacker/SavePicture.h
index 9d9fa6133..3e2aed661 100644
--- a/DeepSkyStacker/SavePicture.h
+++ b/DeepSkyStacker/SavePicture.h
@@ -1,6 +1,131 @@
#pragma once
+/****************************************************************************
+**
+** Copyright (C) 2024 David C. Partridge
+**
+** BSD License Usage
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of DeepSkyStacker nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+**
+****************************************************************************/
+#include
#include "DSSCommon.h"
-#include "ToolTipButton.h"
+
+class QCheckBox;
+class QGroupBox;
+class QHBoxLayout;
+class QRadioButton;
+class QVBoxLayout;
+
+namespace DSS
+{
+ class SavePicture final : public QFileDialog
+ {
+ Q_OBJECT
+
+ public:
+ SavePicture(QWidget* parent = nullptr, const QString& caption = QString(), const QString& directory = QString(), const QString& filter = QString());
+
+ ~SavePicture() = default;
+
+ SavePicture(const SavePicture&) = delete;
+ SavePicture(SavePicture&&) = delete;
+ SavePicture& operator=(const SavePicture& rhs) = delete;
+
+ void retranslateUi(QWidget*);
+
+ void connectSignalsToSlots();
+
+ inline void setCompression(const TIFFCOMPRESSION comp)
+ {
+ compression_ = comp;
+ switch (comp)
+ {
+ case TC_NONE:
+ compressionNone->setChecked(true);
+ break;
+ case TC_DEFLATE:
+ compressionZIP->setChecked(true);
+ break;
+ case TC_LZW:
+ compressionLZW->setChecked(true);
+ break;
+ }
+ }
+
+ inline void setApply(const bool apply)
+ {
+ apply_ = apply;
+ switch (apply)
+ {
+ case false:
+ embedAdjustments->setChecked(true);
+ break;
+ case true:
+ applyAdjustments->setChecked(true);
+ break;
+ }
+ }
+
+ private:
+ QGroupBox* compressionGroup;
+ QHBoxLayout* compressionLayout;
+ QRadioButton* compressionNone;
+ QRadioButton* compressionZIP;
+ QRadioButton* compressionLZW;
+
+ QGroupBox* optionsGroup;
+ QVBoxLayout* optionsLayout;
+ QRadioButton* applyAdjustments;
+ QRadioButton* embedAdjustments;
+ QCheckBox* useRectangle;
+
+ QString embedText;
+ QString noAdjustments;
+
+ TIFFCOMPRESSION compression_;
+ bool apply_;
+ bool useRect_;
+
+
+ private slots:
+ void onCompressionNone(bool checked);
+ void onCompressionZIP(bool checked);
+ void onCompressionLZW(bool checked);
+ void onApply(bool checked);
+ void onEmbed(bool checked);
+ void onFilter(const QString& filter);
+
+ };
+}
+
+#if (0)
// CSavePicture
class CSavePicture : public CFileDialog
@@ -80,5 +205,4 @@ private :
public:
virtual BOOL OnInitDialog();
};
-
-
+#endif
\ No newline at end of file
diff --git a/DeepSkyStacker/StackingDlg.cpp b/DeepSkyStacker/StackingDlg.cpp
index 04447a41d..eddf2e371 100644
--- a/DeepSkyStacker/StackingDlg.cpp
+++ b/DeepSkyStacker/StackingDlg.cpp
@@ -474,8 +474,7 @@ namespace DSS
copy{ nullptr },
erase{ nullptr },
networkManager{ nullptr },
- m_tipShowCount{ 0 },
- dockTitle{ new QLabel(this) }
+ m_tipShowCount{ 0 }
{
ui->setupUi(this);
isos << "100" << "125" << "160" << "200" << "250" << "320" << "400" <<
@@ -680,8 +679,6 @@ namespace DSS
updateListInfo(); // Update information bar and tooltip
- dockTitle->setToolTip(tr("Double click here to dock/undock the image list"));
-
//
// Now iterate over the groups and retranslate the group names and all strings in the table model
// for the image list.
@@ -1126,19 +1123,6 @@ namespace DSS
ui->gamma->setPegsOnLeftOrBottom(true).
setOrientation(QLinearGradientCtrl::Orientation::ForceHorizontal);
- //
- // Set an informative title bar on the dockable image list with a nice gradient
- // as the background (like the old "listInfo" static control).
- //
- QSize size{ 625, 25 };
- dockTitle->setObjectName("dockTitle");
- dockTitle->setMinimumSize(size);
- dockTitle->resize(size);
- dockTitle->setStyleSheet(QString::fromUtf8("QLabel {"
- "background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, "
- "stop:0 rgba(138, 185, 242, 0), stop:1 rgba(138, 185, 242, 255))}"));
- pictureList->setTitleBarWidget(dockTitle);
-
//
// Set up the tab bar (used to be a tab widget)
//
@@ -1771,7 +1755,7 @@ namespace DSS
.arg(frameList.checkedImageCount(PICTURETYPE_OFFSETFRAME))
};
- dockTitle->setText(text);
+ pictureList->dockTitle->setText(text);
for (int i = 0; i < pictureList->tabBar->count(); i++)
{
@@ -2505,7 +2489,7 @@ namespace DSS
dlg.SetJointProgress(false);
dlg.Close();
- dssApp->getProcessingDlg().loadFile(strFileName);
+ dssApp->getProcessingDlg().loadStackedImage(strFileName);
// Change tab to processing
dssApp->setPanel(ActivePanel::ProcessingPanel);
diff --git a/DeepSkyStacker/StackingDlg.h b/DeepSkyStacker/StackingDlg.h
index 1d8fa40a4..0ffbe58fa 100644
--- a/DeepSkyStacker/StackingDlg.h
+++ b/DeepSkyStacker/StackingDlg.h
@@ -297,8 +297,6 @@ namespace DSS
QAction* copy;
QAction* erase;
- QLabel* dockTitle;
-
void checkAskRegister();
void onInitDialog();
diff --git a/DeepSkyStacker/picturelist.cpp b/DeepSkyStacker/picturelist.cpp
index 78fe8db23..3c4ac4d6a 100644
--- a/DeepSkyStacker/picturelist.cpp
+++ b/DeepSkyStacker/picturelist.cpp
@@ -2,12 +2,28 @@
#include "picturelist.h"
namespace DSS
{
- PictureList::PictureList(QWidget* parent)
- : QDockWidget(parent)
+ PictureList::PictureList(QWidget* parent) :
+ QDockWidget(parent),
+ dockTitle{ new QLabel(this) }
{
setupUi(this);
tableView->horizontalHeader()->setSortIndicator(1, Qt::AscendingOrder);
tableView->horizontalHeader()->setSortIndicatorShown(true);
+
+ dockTitle->setToolTip(tr("Double click here to dock/undock the image list"));
+
+ //
+ // Set an informative title bar on the dockable image list with a nice gradient
+ // as the background (like the old "listInfo" static control).
+ //
+ QSize size{ 625, 25 };
+ dockTitle->setObjectName("dockTitle");
+ dockTitle->setMinimumSize(size);
+ dockTitle->resize(size);
+ dockTitle->setStyleSheet(QString::fromUtf8("QLabel {"
+ "background: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, "
+ "stop:0 rgba(138, 185, 242, 0), stop:1 rgba(138, 185, 242, 255))}"));
+ setTitleBarWidget(dockTitle);
}
PictureList::~PictureList()
diff --git a/DeepSkyStacker/picturelist.h b/DeepSkyStacker/picturelist.h
index 04ddd26ac..e92e4ceb3 100644
--- a/DeepSkyStacker/picturelist.h
+++ b/DeepSkyStacker/picturelist.h
@@ -16,6 +16,10 @@ namespace DSS
public:
PictureList(QWidget* parent = nullptr);
~PictureList();
+
+ private:
+ QLabel* dockTitle;
+
#if QT_VERSION < 0x060601 // Shouldn't need this in QT 6.6.1
inline void setDSSClosing() { dssClosing = true; }