9#include "auxiliary/kspaths.h"
11#include "fitshistogrameditor.h"
12#include "fitshistogramcommand.h"
14#include "fitsviewer.h"
15#include "ksnotification.h"
18#include "ui_fitsheaderdialog.h"
19#include "ui_statform.h"
20#include "fitsstretchui.h"
23#include <QtConcurrent>
25#include "ekos/auxiliary/stellarsolverprofile.h"
26#include "ekos/auxiliary/stellarsolverprofileeditor.h"
28#include <fits_debug.h>
38 undoStack->setUndoLimit(10);
40 connect(undoStack, SIGNAL(cleanChanged(
bool)),
this, SLOT(modifyFITSState(
bool)));
42 m_PlateSolveWidget =
new QDialog(
this);
44 fitsHeaderDialog =
new QDialog(
this);
45 m_HistogramEditor =
new FITSHistogramEditor(
this);
46 connect(m_HistogramEditor, &FITSHistogramEditor::newHistogramCommand,
this, [
this](FITSHistogramCommand * command)
48 undoStack->push(command);
56void FITSTab::saveUnsaved()
58 if (undoStack->
isClean() || m_View->getMode() != FITS_NORMAL)
62 QString message =
i18n(
"The current FITS file has unsaved changes. Would you like to save before closing it?");
65 if (ans == KMessageBox::Yes)
67 if (ans == KMessageBox::No)
83QString FITSTab::getPreviewText()
const
88void FITSTab::setPreviewText(
const QString &value)
93void FITSTab::selectRecentFITS(
int i)
98void FITSTab::clearRecentFITS()
101 recentImages->clear();
105bool FITSTab::setupView(FITSMode mode, FITSScale filter)
109 m_View.
reset(
new FITSView(
this, mode, filter));
113 connect(m_View.
get(), &FITSView::rectangleUpdated,
this, [
this](
QRect roi)
115 displayStats(roi.isValid());
120 stat.setupUi(statWidget);
121 m_PlateSolveUI.setupUi(m_PlateSolveWidget);
126 const QString EditorID =
"FITSSolverProfileEditor";
130 m_EditorDialog =
new KConfigDialog(
nullptr, EditorID, Options::self());
131 m_ProfileEditor =
new Ekos::StellarSolverProfileEditor(
nullptr, Ekos::AlignProfiles, m_EditorDialog.
data());
132 m_ProfileEditorPage = m_EditorDialog->addPage(m_ProfileEditor.
data(),
133 i18n(
"FITS Viewer Solver Profiles Editor"));
138 m_ProfileEditor->loadProfile(m_PlateSolveUI.kcfg_FitsSolverProfile->currentText());
139 KConfigDialog * d = KConfigDialog::exists(EditorID);
142 d->setCurrentPage(m_ProfileEditorPage);
149 for (
int i = 0; i <= STAT_STDDEV; i++)
151 for (
int j = 0; j < 3; j++)
159 stat.statsTable->setSpan(i, 0, 1, 3);
162 fitsTools->addItem(statWidget,
i18n(
"Statistics"));
164 fitsTools->addItem(m_PlateSolveWidget,
i18n(
"Plate Solving"));
167 fitsTools->addItem(m_HistogramEditor,
i18n(
"Histogram"));
169 header.setupUi(fitsHeaderDialog);
170 fitsTools->addItem(fitsHeaderDialog,
i18n(
"FITS Header"));
174 recentPanel->
setLayout(recentPanelLayout);
175 fitsTools->addItem(recentPanel,
i18n(
"Recent Images"));
177 recentPanelLayout->
addWidget(recentImages);
179 recentPanelLayout->
addWidget(clearRecent);
187 fitsSplitter->addWidget(scrollFitsPanel);
188 fitsSplitter->addWidget(m_View.
get());
192 fitsSplitter->setSizes(
QList<int>() << 0 << m_View->width() );
196 stretchUI.reset(
new FITSStretchUI(m_View,
nullptr));
202 connect(m_View.
get(), &FITSView::newStatus,
this, &FITSTab::newStatus);
203 connect(m_View.
get(), &FITSView::debayerToggled,
this, &FITSTab::debayerToggled);
204 connect(m_View.
get(), &FITSView::updated,
this, &FITSTab::updated);
207 connect(m_View.
get(), &FITSView::failed,
this, &FITSTab::failed);
216void FITSTab::loadFile(
const QUrl &imageURL, FITSMode mode, FITSScale filter)
222 if (setupView(mode, filter))
226 connect(m_View.
get(), &FITSView::loaded,
this, [&]()
232 connect(m_View.
get(), &FITSView::updated,
this, &FITSTab::updated);
236 modifyFITSState(
true, imageURL);
238 currentURL = imageURL;
240 m_View->setFilter(filter);
245bool FITSTab::shouldComputeHFR()
const
247 if (viewer->isStarsMarked())
249 if (!Options::autoHFR())
251 return ((!m_View.
isNull()) && (m_View->getMode() == FITS_NORMAL));
254void FITSTab::processData()
258 m_HistogramEditor->setImageData(imageData);
268 if (shouldComputeHFR())
270 m_View->searchStars();
271 qCDebug(KSTARS_FITS) <<
"FITS HFR:" << imageData->getHFR();
285 &FITSTab::selectRecentFITS);
286 recentImages->addItem(imageData->filename());
287 recentImages->setCurrentRow(recentImages->count() - 1);
289 &FITSTab::selectRecentFITS);
297 if (viewer->isStarsMarked())
299 m_View->toggleStars(
true);
300 m_View->updateFrame();
306 stretchUI->generateHistogram();
311 setupView(mode, filter);
316 if (viewer->isStarsMarked())
318 m_View->toggleStars(
true);
322 m_View->setFilter(filter);
324 if (!m_View->loadData(data))
335void FITSTab::modifyFITSState(
bool clean,
const QUrl &imageURL)
339 if (undoStack->
isClean() ==
false)
347 emit changeStatus(clean, imageURL);
350bool FITSTab::saveImage(
const QString &filename)
352 return m_View->saveImage(filename);
355void FITSTab::copyFITS()
360void FITSTab::histoFITS()
362 fitsTools->setCurrentIndex(1);
363 if(m_View->width() > 200)
364 fitsSplitter->setSizes(
QList<int>() << 200 << m_View->width() - 200);
366 fitsSplitter->setSizes(
QList<int>() << 50 << 50);
369void FITSTab::displayStats(
bool roi)
373 stat.statsTable->item(STAT_WIDTH, 0)->setText(
QString::number(imageData->width(roi)));
374 stat.statsTable->item(STAT_HEIGHT, 0)->setText(
QString::number(imageData->height(roi)));
375 stat.statsTable->item(STAT_BITPIX, 0)->setText(
QString::number(imageData->bpp()));
378 stat.statsTable->item(STAT_HFR, 0)->setText(
QString::number(imageData->getHFR(),
'f', 3));
380 stat.statsTable->item(STAT_HFR, 0)->setText(
"---");
382 if (imageData->channels() == 1)
384 for (
int i = STAT_MIN; i <= STAT_STDDEV; i++)
386 if (stat.statsTable->columnSpan(i, 0) != 3)
387 stat.statsTable->setSpan(i, 0, 1, 3);
390 stat.statsTable->horizontalHeaderItem(0)->setText(
i18n(
"Value"));
391 stat.statsTable->hideColumn(1);
392 stat.statsTable->hideColumn(2);
396 for (
int i = STAT_MIN; i <= STAT_STDDEV; i++)
398 if (stat.statsTable->columnSpan(i, 0) != 1)
399 stat.statsTable->setSpan(i, 0, 1, 1);
402 stat.statsTable->horizontalHeaderItem(0)->setText(
i18nc(
"Red",
"R"));
403 stat.statsTable->showColumn(1);
404 stat.statsTable->showColumn(2);
407 if (!Options::nonLinearHistogram() && !imageData->isHistogramConstructed())
408 imageData->constructHistogram();
410 for (
int i = 0; i < imageData->channels(); i++)
412 stat.statsTable->item(STAT_MIN, i)->setText(
QString::number(imageData->getMin(i, roi),
'f', 3));
413 stat.statsTable->item(STAT_MAX, i)->setText(
QString::number(imageData->getMax(i, roi),
'f', 3));
414 stat.statsTable->item(STAT_MEAN, i)->setText(
QString::number(imageData->getMean(i, roi),
'f', 3));
415 stat.statsTable->item(STAT_MEDIAN, i)->setText(
QString::number(imageData->getMedian(i, roi),
'f', 3));
416 stat.statsTable->item(STAT_STDDEV, i)->setText(
QString::number(imageData->getStdDev(i, roi),
'f', 3));
420void FITSTab::statFITS()
422 fitsTools->setCurrentIndex(0);
423 if(m_View->width() > 200)
424 fitsSplitter->setSizes(
QList<int>() << 200 << m_View->width() - 200);
426 fitsSplitter->setSizes(
QList<int>() << 50 << 50);
430void FITSTab::loadFITSHeader()
434 int nkeys = imageData->getRecords().size();
436 header.tableWidget->setRowCount(nkeys);
437 for (
const auto &oneRecord : imageData->getRecords())
441 header.tableWidget->setItem(counter, 0, tempItem);
444 header.tableWidget->setItem(counter, 1, tempItem);
447 header.tableWidget->setItem(counter, 2, tempItem);
451 header.tableWidget->setColumnWidth(0, 100);
452 header.tableWidget->setColumnWidth(1, 100);
453 header.tableWidget->setColumnWidth(2, 250);
456void FITSTab::headerFITS()
458 fitsTools->setCurrentIndex(2);
459 if(m_View->width() > 200)
460 fitsSplitter->setSizes(
QList<int>() << 200 << m_View->width() - 200);
462 fitsSplitter->setSizes(
QList<int>() << 50 << 50);
465bool FITSTab::saveFile()
467 QUrl backupCurrent = currentURL;
468 QUrl currentDir(Options::fitsDir());
469 currentDir.setScheme(
"file");
475 if (mDirty ==
false && !currentURL.
isEmpty())
484 "Images (*.fits *.fits.gz *.fit *.xisf *.jpg *.jpeg *.png)");
488 "FITS (*.fits *.fits.gz *.fit);;XISF (*.xisf);;JPEG (*.jpg *.jpeg);;PNG (*.png)", &selectedFilter);
493 currentURL = backupCurrent;
500 if (selectedFilter.
contains(
"XISF"))
502 else if (selectedFilter.
contains(
"JPEG"))
504 else if (selectedFilter.
contains(
"PNG"))
517 if (!saveImage(localFile))
519 KSNotification::error(
i18n(
"Image save error: %1", m_View->imageData()->getLastError()),
i18n(
"Image Save"));
523 emit newStatus(
i18n(
"File saved to %1", currentURL.
url()), FITS_MESSAGE);
530 KSNotification::sorry(message,
i18n(
"Invalid URL"));
535bool FITSTab::saveFileAs()
541void FITSTab::ZoomIn()
543 QPoint oldCenter = m_View->getImagePoint(m_View->viewport()->rect().center());
545 m_View->cleanUpZoom(oldCenter);
548void FITSTab::ZoomOut()
550 QPoint oldCenter = m_View->getImagePoint(m_View->viewport()->rect().center());
552 m_View->cleanUpZoom(oldCenter);
555void FITSTab::ZoomDefault()
557 QPoint oldCenter = m_View->getImagePoint(m_View->viewport()->rect().center());
558 m_View->ZoomDefault();
559 m_View->cleanUpZoom(oldCenter);
562void FITSTab::tabPositionUpdated()
566 emit newStatus(
QString(
"%1x%2").arg(m_View->imageData()->width()).
arg(m_View->imageData()->height()),
570void FITSTab::setStretchValues(
double shadows,
double midtones,
double highlights)
573 stretchUI->setStretchValues(shadows, midtones, highlights);
576void FITSTab::setAutoStretch()
578 if (!m_View->getAutoStretch())
579 m_View->setAutoStretchParams();
589 case Ekos::AlignProfiles:
591 savedProfiles =
QDir(KSPaths::writableLocation(
594 StellarSolver::loadSavedOptionsProfiles(savedProfiles) :
595 Ekos::getDefaultAlignOptionsProfiles();
597 case Ekos::FocusProfiles:
598 savedProfiles =
QDir(KSPaths::writableLocation(
601 StellarSolver::loadSavedOptionsProfiles(savedProfiles) :
602 Ekos::getDefaultFocusOptionsProfiles();
604 case Ekos::GuideProfiles:
605 savedProfiles =
QDir(KSPaths::writableLocation(
608 StellarSolver::loadSavedOptionsProfiles(savedProfiles) :
609 Ekos::getDefaultGuideOptionsProfiles();
611 case Ekos::HFRProfiles:
612 savedProfiles =
QDir(KSPaths::writableLocation(
615 StellarSolver::loadSavedOptionsProfiles(savedProfiles) :
616 Ekos::getDefaultHFROptionsProfiles();
622void FITSTab::setupSolver(
bool extractOnly)
624 auto parameters = getSSolverParametersList(
static_cast<Ekos::ProfileGroup
>(Options::fitsSolverModule())).at(
625 m_PlateSolveUI.kcfg_FitsSolverProfile->currentIndex());
626 parameters.search_radius = m_PlateSolveUI.kcfg_FitsSolverRadius->value();
638 const int imageWidth = m_View->imageData()->width();
639 const int imageHeight = m_View->imageData()->height();
640 if (m_PlateSolveUI.kcfg_FitsSolverUseScale->isChecked() && imageWidth != 0 && imageHeight != 0)
642 const double scale = m_PlateSolveUI.kcfg_FitsSolverScale->value();
643 double lowScale = scale * 0.8;
644 double highScale = scale * 1.2;
647 const int units = m_PlateSolveUI.kcfg_FitsSolverImageScaleUnits->currentIndex();
648 if (units == SSolver::DEG_WIDTH)
650 lowScale = (lowScale * 3600) / std::max(imageWidth, imageHeight);
651 highScale = (highScale * 3600) / std::min(imageWidth, imageHeight);
653 else if (units == SSolver::ARCMIN_WIDTH)
655 lowScale = (lowScale * 60) / std::max(imageWidth, imageHeight);
656 highScale = (highScale * 60) / std::min(imageWidth, imageHeight);
659 m_Solver->useScale(m_PlateSolveUI.kcfg_FitsSolverUseScale->isChecked(), lowScale, highScale);
661 else m_Solver->useScale(
false, 0, 0);
663 if (m_PlateSolveUI.kcfg_FitsSolverUsePosition->isChecked())
666 const dms ra = m_PlateSolveUI.FitsSolverEstRA->createDms(&ok);
668 const dms dec = m_PlateSolveUI.FitsSolverEstDec->createDms(&ok2);
670 m_Solver->usePosition(
true, ra.
Degrees(),
dec.Degrees());
672 m_Solver->usePosition(
false, 0, 0);
674 else m_Solver->usePosition(
false, 0, 0);
679void FITSTab::extractImage()
681 if (m_Solver.
get() && m_Solver->isRunning())
683 m_PlateSolveUI.SolveButton->setText(
i18n(
"Aborting..."));
687 m_PlateSolveUI.SolveButton->setText(
i18n(
"Cancel"));
691 m_PlateSolveUI.FitsSolverAngle->setText(
"");
692 m_PlateSolveUI.FitsSolverIndexfile->setText(
"");
693 m_PlateSolveUI.Solution1->setText(
i18n(
"Extracting..."));
694 m_PlateSolveUI.Solution2->setText(
"");
696 m_Solver->runSolver(m_View->imageData());
699void FITSTab::solveImage()
701 if (m_Solver.
get() && m_Solver->isRunning())
703 m_PlateSolveUI.SolveButton->setText(
i18n(
"Aborting..."));
707 m_PlateSolveUI.SolveButton->setText(
i18n(
"Cancel"));
711 m_PlateSolveUI.Solution2->setText(
i18n(
"Solving..."));
713 m_Solver->runSolver(m_View->imageData());
716void FITSTab::extractorDone(
bool timedOut,
bool success,
const FITSImage::Solution &solution,
double elapsedSeconds)
719 disconnect(m_Solver.
get(), &SolverUtils::done,
this, &FITSTab::extractorDone);
720 m_PlateSolveUI.Solution2->setText(
"");
724 const QString result =
i18n(
"Extractor timed out: %1s",
QString(
"%L1").arg(elapsedSeconds, 0,
'f', 1));
725 m_PlateSolveUI.Solution1->setText(result);
728 m_PlateSolveUI.SolveButton->setText(
"Solve");
733 const QString result =
i18n(
"Extractor failed: %1s",
QString(
"%L1").arg(elapsedSeconds, 0,
'f', 1));
734 m_PlateSolveUI.Solution1->setText(result);
737 m_PlateSolveUI.SolveButton->setText(
i18n(
"Solve"));
742 const QString starStr =
i18n(
"Extracted %1 stars (%2 unfiltered) in %3s",
743 m_Solver->getNumStarsFound(),
744 m_Solver->getBackground().num_stars_detected,
745 QString(
"%1").arg(elapsedSeconds, 0,
'f', 1));
746 m_PlateSolveUI.Solution1->setText(starStr);
752 for (
int i = 0; i < starList.
size(); i++)
754 const auto &star = starList[i];
755 Edge *oneEdge =
new Edge();
758 oneEdge->val = star.peak;
759 oneEdge->sum = star.flux;
760 oneEdge->HFR = star.HFR;
761 oneEdge->width = star.a;
762 oneEdge->numPixels = star.numPixels;
766 oneEdge->ellipticity = 1 - star.b / star.a;
768 oneEdge->ellipticity = 0;
770 starCenters.
append(oneEdge);
772 m_View->imageData()->setStarCenters(starCenters);
773 m_View->updateFrame();
780void FITSTab::solverDone(
bool timedOut,
bool success,
const FITSImage::Solution &solution,
double elapsedSeconds)
782 disconnect(m_Solver.
get(), &SolverUtils::done,
this, &FITSTab::solverDone);
783 m_PlateSolveUI.SolveButton->setText(
"Solve");
785 if (m_Solver->isRunning())
786 qCDebug(KSTARS_FITS) <<
"solverDone called, but it is still running.";
790 const QString result =
i18n(
"Solver timed out: %1s",
QString(
"%L1").arg(elapsedSeconds, 0,
'f', 1));
791 m_PlateSolveUI.Solution2->setText(result);
795 const QString result =
i18n(
"Solver failed: %1s",
QString(
"%L1").arg(elapsedSeconds, 0,
'f', 1));
796 m_PlateSolveUI.Solution2->setText(result);
800 const bool eastToTheRight = solution.parity == FITSImage::POSITIVE ? false :
true;
801 m_View->imageData()->injectWCS(solution.orientation, solution.ra, solution.dec, solution.pixscale, eastToTheRight);
802 m_View->imageData()->loadWCS();
805 const double solverPA = KSUtils::rotationToPositionAngle(solution.orientation);
806 m_PlateSolveUI.FitsSolverAngle->setText(
QString(
"%1ยบ").arg(solverPA, 0,
'f', 2));
808 int indexUsed = -1, healpixUsed = -1;
809 m_Solver->getSolutionHealpix(&indexUsed, &healpixUsed);
811 m_PlateSolveUI.FitsSolverIndexfile->setText(
"");
813 m_PlateSolveUI.FitsSolverIndexfile->setText(
816 .arg(healpixUsed >= 0 ?
QString(
"-%1").arg(healpixUsed) :
QString(
"")));;
819 const int imageWidth = m_View->imageData()->width();
820 const int units = m_PlateSolveUI.kcfg_FitsSolverImageScaleUnits->currentIndex();
821 if (units == SSolver::DEG_WIDTH)
822 m_PlateSolveUI.kcfg_FitsSolverScale->setValue(solution.pixscale * imageWidth / 3600.0);
823 else if (units == SSolver::ARCMIN_WIDTH)
824 m_PlateSolveUI.kcfg_FitsSolverScale->setValue(solution.pixscale * imageWidth / 60.0);
826 m_PlateSolveUI.kcfg_FitsSolverScale->setValue(solution.pixscale);
829 m_PlateSolveUI.FitsSolverEstRA->show(
dms(solution.ra));
830 m_PlateSolveUI.FitsSolverEstDec->show(
dms(solution.dec));
832 m_PlateSolveUI.Solution2->setText(result);
838int FITSTab::getProfileIndex(
int moduleIndex)
840 if (moduleIndex < 0 || moduleIndex >= Ekos::ProfileGroupNames.
size())
842 const QString moduleName = Ekos::ProfileGroupNames[moduleIndex];
843 const QString str = Options::fitsSolverProfileIndeces();
848 return indeces[moduleName].toString().toInt();
851void FITSTab::setProfileIndex(
int moduleIndex,
int profileIndex)
853 if (moduleIndex < 0 || moduleIndex >= Ekos::ProfileGroupNames.
size())
855 QString str = Options::fitsSolverProfileIndeces();
860 for (
int i = 0; i < Ekos::ProfileGroupNames.size(); i++)
865 else if (name ==
"Guide")
867 else if (name ==
"HFR")
870 initialIndeces[
name] =
"0";
876 indeces[Ekos::ProfileGroupNames[moduleIndex]] =
QString::number(profileIndex);
881void FITSTab::setupProfiles(
int moduleIndex)
883 if (moduleIndex < 0 || moduleIndex >= Ekos::ProfileGroupNames.
size())
885 Ekos::ProfileGroup profileGroup =
static_cast<Ekos::ProfileGroup
>(moduleIndex);
886 Options::setFitsSolverModule(moduleIndex);
890 m_PlateSolveUI.kcfg_FitsSolverProfile->clear();
891 for(
auto ¶m : optionsList)
892 m_PlateSolveUI.kcfg_FitsSolverProfile->addItem(param.listName);
894 m_ProfileEditor->setProfileGroup(profileGroup,
false);
897 m_PlateSolveUI.kcfg_FitsSolverProfile->setCurrentIndex(getProfileIndex(Options::fitsSolverModule()));
899 m_ProfileEditorPage->setHeader(
QString(
"FITS Viewer Solver %1 Profiles Editor")
900 .arg(Ekos::ProfileGroupNames[moduleIndex]));
903void FITSTab::initSolverUI()
906 m_PlateSolveUI.kcfg_FitsSolverModule->clear();
907 for (
int i = 0; i < Ekos::ProfileGroupNames.size(); i++)
908 m_PlateSolveUI.kcfg_FitsSolverModule->addItem(Ekos::ProfileGroupNames[i]);
909 m_PlateSolveUI.kcfg_FitsSolverModule->setCurrentIndex(Options::fitsSolverModule());
911 setupProfiles(Options::fitsSolverModule());
916 m_PlateSolveUI.kcfg_FitsSolverUseScale->setChecked(Options::fitsSolverUseScale());
917 m_PlateSolveUI.kcfg_FitsSolverScale->setValue(Options::fitsSolverScale());
918 m_PlateSolveUI.kcfg_FitsSolverImageScaleUnits->setCurrentIndex(Options::fitsSolverImageScaleUnits());
920 m_PlateSolveUI.kcfg_FitsSolverUsePosition->setChecked(Options::fitsSolverUsePosition());
921 m_PlateSolveUI.kcfg_FitsSolverRadius->setValue(Options::fitsSolverRadius());
923 m_PlateSolveUI.FitsSolverEstRA->setUnits(dmsBox::HOURS);
924 m_PlateSolveUI.FitsSolverEstDec->setUnits(dmsBox::DEGREES);
929 setProfileIndex(m_PlateSolveUI.kcfg_FitsSolverModule->currentIndex(), index);
934 Options::setFitsSolverUseScale(state);
938 Options::setFitsSolverScale(value);
942 Options::setFitsSolverImageScaleUnits(index);
947 Options::setFitsSolverUsePosition(state);
952 Options::setFitsSolverRadius(value);
956 const auto center = SkyMap::Instance()->getCenterPoint();
957 m_PlateSolveUI.FitsSolverEstRA->show(center.ra());
958 m_PlateSolveUI.FitsSolverEstDec->show(center.dec());
962 const SSolver::SolverType
type =
static_cast<SSolver::SolverType
>(Options::solverType());
963 if(type != SSolver::SOLVER_STELLARSOLVER)
965 m_PlateSolveUI.Solution2->setText(
i18n(
"Warning! This tool only supports the internal StellarSolver solver."));
966 m_PlateSolveUI.Solution1->setText(
i18n(
"Change to that in the Ekos Align options menu."));
Primary window to view monochrome and color FITS images.
static KStars * Instance()
An angle, stored as degrees, but expressible in many ways.
const double & Degrees() const
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
Ekos is an advanced Astrophotography tool for Linux.
QString name(GameStandardAction id)
VehicleSection::Type type(QStringView coachNumber, QStringView coachClassification)
void stateChanged(int state)
void setImage(const QImage &image, Mode mode)
void activated(int index)
QString filePath(const QString &fileName) const const
void valueChanged(double d)
bool exists(const QString &fileName)
QUrl getSaveFileUrl(QWidget *parent, const QString &caption, const QUrl &dir, const QString &filter, QString *selectedFilter, Options options, const QStringList &supportedSchemes)
bool exists() const const
QIcon fromTheme(const QString &name)
QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error)
bool isNull() const const
bool isObject() const const
QJsonObject object() const const
QByteArray toJson(JsonFormat format) const const
void append(QList< T > &&value)
void reserve(qsizetype size)
qsizetype size() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
bool disconnect(const QMetaObject::Connection &connection)
bool isNull() const const
void splitterMoved(int pos, int index)
QString arg(Args &&... args) const const
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
QString number(double n, char format, int precision)
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
QByteArray toUtf8() const const
QTextStream & dec(QTextStream &stream)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
void setActive(bool active)
bool isClean() const const
QUrl fromLocalFile(const QString &localFile)
bool isEmpty() const const
bool isValid() const const
void setPath(const QString &path, ParsingMode mode)
QString toLocalFile() const const
QString url(FormattingOptions options) const const