9#include "auxiliary/kspaths.h"
11#include "fitshistogramcommand.h"
13#include "fitsviewer.h"
14#include "ksnotification.h"
17#include "ui_fitsheaderdialog.h"
18#include "ui_statform.h"
19#include "fitsstretchui.h"
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?");
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)
225 if (setupView(mode, filter))
229 connect(m_View.
get(), &FITSView::loaded,
this, [&]()
235 connect(m_View.
get(), &FITSView::updated,
this, &FITSTab::updated);
239 modifyFITSState(
true, imageURL);
241 currentURL = imageURL;
243 m_View->setFilter(filter);
248bool FITSTab::shouldComputeHFR()
const
250 if (viewer->isStarsMarked())
252 if (!Options::autoHFR())
254 return ((!m_View.
isNull()) && (m_View->getMode() == FITS_NORMAL));
257void FITSTab::processData()
261 m_HistogramEditor->setImageData(imageData);
271 if (shouldComputeHFR())
273 m_View->searchStars();
274 qCDebug(KSTARS_FITS) <<
"FITS HFR:" << imageData->getHFR();
288 &FITSTab::selectRecentFITS);
289 recentImages->addItem(imageData->filename());
290 recentImages->setCurrentRow(recentImages->count() - 1);
292 &FITSTab::selectRecentFITS);
300 if (viewer->isStarsMarked())
302 m_View->toggleStars(
true);
303 m_View->updateFrame();
309 stretchUI->generateHistogram();
314 setupView(mode, filter);
319 if (viewer->isStarsMarked())
321 m_View->toggleStars(
true);
325 m_View->setFilter(filter);
327 if (!m_View->loadData(data))
338void FITSTab::modifyFITSState(
bool clean,
const QUrl &imageURL)
342 if (undoStack->
isClean() ==
false)
350 emit changeStatus(clean, imageURL);
353bool FITSTab::saveImage(
const QString &filename)
355 return m_View->saveImage(filename);
358void FITSTab::copyFITS()
363void FITSTab::histoFITS()
365 fitsTools->setCurrentIndex(1);
366 if(m_View->width() > 200)
367 fitsSplitter->setSizes(
QList<int>() << 200 << m_View->width() - 200);
369 fitsSplitter->setSizes(
QList<int>() << 50 << 50);
372void FITSTab::displayStats(
bool roi)
376 stat.statsTable->item(STAT_WIDTH, 0)->setText(
QString::number(imageData->width(roi)));
377 stat.statsTable->item(STAT_HEIGHT, 0)->setText(
QString::number(imageData->height(roi)));
378 stat.statsTable->item(STAT_BITPIX, 0)->setText(
QString::number(imageData->bpp()));
381 stat.statsTable->item(STAT_HFR, 0)->setText(
QString::number(imageData->getHFR(),
'f', 3));
383 stat.statsTable->item(STAT_HFR, 0)->setText(
"---");
385 if (imageData->channels() == 1)
387 for (
int i = STAT_MIN; i <= STAT_STDDEV; i++)
389 if (stat.statsTable->columnSpan(i, 0) != 3)
390 stat.statsTable->setSpan(i, 0, 1, 3);
393 stat.statsTable->horizontalHeaderItem(0)->setText(
i18n(
"Value"));
394 stat.statsTable->hideColumn(1);
395 stat.statsTable->hideColumn(2);
399 for (
int i = STAT_MIN; i <= STAT_STDDEV; i++)
401 if (stat.statsTable->columnSpan(i, 0) != 1)
402 stat.statsTable->setSpan(i, 0, 1, 1);
405 stat.statsTable->horizontalHeaderItem(0)->setText(
i18nc(
"Red",
"R"));
406 stat.statsTable->showColumn(1);
407 stat.statsTable->showColumn(2);
410 if (!Options::nonLinearHistogram() && !imageData->isHistogramConstructed())
411 imageData->constructHistogram();
413 for (
int i = 0; i < imageData->channels(); i++)
415 stat.statsTable->item(STAT_MIN, i)->setText(
QString::number(imageData->getMin(i, roi),
'f', 3));
416 stat.statsTable->item(STAT_MAX, i)->setText(
QString::number(imageData->getMax(i, roi),
'f', 3));
417 stat.statsTable->item(STAT_MEAN, i)->setText(
QString::number(imageData->getMean(i, roi),
'f', 3));
418 stat.statsTable->item(STAT_MEDIAN, i)->setText(
QString::number(imageData->getMedian(i, roi),
'f', 3));
419 stat.statsTable->item(STAT_STDDEV, i)->setText(
QString::number(imageData->getStdDev(i, roi),
'f', 3));
423void FITSTab::statFITS()
425 fitsTools->setCurrentIndex(0);
426 if(m_View->width() > 200)
427 fitsSplitter->setSizes(
QList<int>() << 200 << m_View->width() - 200);
429 fitsSplitter->setSizes(
QList<int>() << 50 << 50);
433void FITSTab::loadFITSHeader()
437 int nkeys = imageData->getRecords().size();
439 header.tableWidget->setRowCount(nkeys);
440 for (
const auto &oneRecord : imageData->getRecords())
444 header.tableWidget->setItem(counter, 0, tempItem);
447 header.tableWidget->setItem(counter, 1, tempItem);
450 header.tableWidget->setItem(counter, 2, tempItem);
454 header.tableWidget->setColumnWidth(0, 100);
455 header.tableWidget->setColumnWidth(1, 100);
456 header.tableWidget->setColumnWidth(2, 250);
459void FITSTab::headerFITS()
461 fitsTools->setCurrentIndex(2);
462 if(m_View->width() > 200)
463 fitsSplitter->setSizes(
QList<int>() << 200 << m_View->width() - 200);
465 fitsSplitter->setSizes(
QList<int>() << 50 << 50);
468bool FITSTab::saveFile()
470 QUrl backupCurrent = currentURL;
471 QUrl currentDir(Options::fitsDir());
472 currentDir.setScheme(
"file");
478 if (mDirty ==
false && !currentURL.
isEmpty())
487 "Images (*.fits *.fits.gz *.fit *.xisf *.jpg *.jpeg *.png)");
491 "FITS (*.fits *.fits.gz *.fit);;XISF (*.xisf);;JPEG (*.jpg *.jpeg);;PNG (*.png)", &selectedFilter);
496 currentURL = backupCurrent;
503 if (selectedFilter.
contains(
"XISF"))
505 else if (selectedFilter.
contains(
"JPEG"))
507 else if (selectedFilter.
contains(
"PNG"))
520 if (!saveImage(localFile))
522 KSNotification::error(
i18n(
"Image save error: %1", m_View->imageData()->getLastError()),
i18n(
"Image Save"));
526 emit newStatus(
i18n(
"File saved to %1", currentURL.
url()), FITS_MESSAGE);
533 KSNotification::sorry(message,
i18n(
"Invalid URL"));
538bool FITSTab::saveFileAs()
544void FITSTab::ZoomIn()
546 QPoint oldCenter = m_View->getImagePoint(m_View->viewport()->rect().center());
548 m_View->cleanUpZoom(oldCenter);
551void FITSTab::ZoomOut()
553 QPoint oldCenter = m_View->getImagePoint(m_View->viewport()->rect().center());
555 m_View->cleanUpZoom(oldCenter);
558void FITSTab::ZoomDefault()
560 QPoint oldCenter = m_View->getImagePoint(m_View->viewport()->rect().center());
561 m_View->ZoomDefault();
562 m_View->cleanUpZoom(oldCenter);
565void FITSTab::tabPositionUpdated()
569 emit newStatus(
QString(
"%1x%2").arg(m_View->imageData()->width()).
arg(m_View->imageData()->height()),
573void FITSTab::setStretchValues(
double shadows,
double midtones,
double highlights)
576 stretchUI->setStretchValues(shadows, midtones, highlights);
579void FITSTab::setAutoStretch()
581 if (!m_View->getAutoStretch())
582 m_View->setAutoStretchParams();
592 case Ekos::AlignProfiles:
594 savedProfiles =
QDir(KSPaths::writableLocation(
597 StellarSolver::loadSavedOptionsProfiles(savedProfiles) :
598 Ekos::getDefaultAlignOptionsProfiles();
600 case Ekos::FocusProfiles:
601 savedProfiles =
QDir(KSPaths::writableLocation(
604 StellarSolver::loadSavedOptionsProfiles(savedProfiles) :
605 Ekos::getDefaultFocusOptionsProfiles();
607 case Ekos::GuideProfiles:
608 savedProfiles =
QDir(KSPaths::writableLocation(
611 StellarSolver::loadSavedOptionsProfiles(savedProfiles) :
612 Ekos::getDefaultGuideOptionsProfiles();
614 case Ekos::HFRProfiles:
615 savedProfiles =
QDir(KSPaths::writableLocation(
618 StellarSolver::loadSavedOptionsProfiles(savedProfiles) :
619 Ekos::getDefaultHFROptionsProfiles();
625void FITSTab::setupSolver(
bool extractOnly)
627 auto parameters = getSSolverParametersList(
static_cast<Ekos::ProfileGroup
>(Options::fitsSolverModule())).at(
628 m_PlateSolveUI.kcfg_FitsSolverProfile->currentIndex());
629 parameters.search_radius = m_PlateSolveUI.kcfg_FitsSolverRadius->value();
641 const int imageWidth = m_View->imageData()->width();
642 const int imageHeight = m_View->imageData()->height();
643 if (m_PlateSolveUI.kcfg_FitsSolverUseScale->isChecked() && imageWidth != 0 && imageHeight != 0)
645 const double scale = m_PlateSolveUI.kcfg_FitsSolverScale->value();
646 double lowScale = scale * 0.8;
647 double highScale = scale * 1.2;
650 const int units = m_PlateSolveUI.kcfg_FitsSolverImageScaleUnits->currentIndex();
651 if (units == SSolver::DEG_WIDTH)
653 lowScale = (lowScale * 3600) / std::max(imageWidth, imageHeight);
654 highScale = (highScale * 3600) / std::min(imageWidth, imageHeight);
656 else if (units == SSolver::ARCMIN_WIDTH)
658 lowScale = (lowScale * 60) / std::max(imageWidth, imageHeight);
659 highScale = (highScale * 60) / std::min(imageWidth, imageHeight);
662 m_Solver->useScale(m_PlateSolveUI.kcfg_FitsSolverUseScale->isChecked(), lowScale, highScale);
664 else m_Solver->useScale(
false, 0, 0);
666 if (m_PlateSolveUI.kcfg_FitsSolverUsePosition->isChecked())
669 const dms ra = m_PlateSolveUI.FitsSolverEstRA->createDms(&ok);
671 const dms dec = m_PlateSolveUI.FitsSolverEstDec->createDms(&ok2);
673 m_Solver->usePosition(
true, ra.
Degrees(),
dec.Degrees());
675 m_Solver->usePosition(
false, 0, 0);
677 else m_Solver->usePosition(
false, 0, 0);
682void FITSTab::extractImage()
684 if (m_Solver.
get() && m_Solver->isRunning())
686 m_PlateSolveUI.SolveButton->setText(
i18n(
"Aborting..."));
690 m_PlateSolveUI.SolveButton->setText(
i18n(
"Cancel"));
694 m_PlateSolveUI.FitsSolverAngle->setText(
"");
695 m_PlateSolveUI.FitsSolverIndexfile->setText(
"");
696 m_PlateSolveUI.Solution1->setText(
i18n(
"Extracting..."));
697 m_PlateSolveUI.Solution2->setText(
"");
699 m_Solver->runSolver(m_View->imageData());
702void FITSTab::solveImage()
704 if (m_Solver.
get() && m_Solver->isRunning())
706 m_PlateSolveUI.SolveButton->setText(
i18n(
"Aborting..."));
710 m_PlateSolveUI.SolveButton->setText(
i18n(
"Cancel"));
714 m_PlateSolveUI.Solution2->setText(
i18n(
"Solving..."));
716 m_Solver->runSolver(m_View->imageData());
719void FITSTab::extractorDone(
bool timedOut,
bool success,
const FITSImage::Solution &solution,
double elapsedSeconds)
722 disconnect(m_Solver.
get(), &SolverUtils::done,
this, &FITSTab::extractorDone);
723 m_PlateSolveUI.Solution2->setText(
"");
727 const QString result =
i18n(
"Extractor timed out: %1s",
QString(
"%L1").arg(elapsedSeconds, 0,
'f', 1));
728 m_PlateSolveUI.Solution1->setText(result);
731 m_PlateSolveUI.SolveButton->setText(
"Solve");
736 const QString result =
i18n(
"Extractor failed: %1s",
QString(
"%L1").arg(elapsedSeconds, 0,
'f', 1));
737 m_PlateSolveUI.Solution1->setText(result);
740 m_PlateSolveUI.SolveButton->setText(
i18n(
"Solve"));
745 const QString starStr =
i18n(
"Extracted %1 stars (%2 unfiltered) in %3s",
746 m_Solver->getNumStarsFound(),
747 m_Solver->getBackground().num_stars_detected,
748 QString(
"%1").arg(elapsedSeconds, 0,
'f', 1));
749 m_PlateSolveUI.Solution1->setText(starStr);
755 for (
int i = 0; i < starList.
size(); i++)
757 const auto &star = starList[i];
758 Edge *oneEdge =
new Edge();
761 oneEdge->val = star.peak;
762 oneEdge->sum = star.flux;
763 oneEdge->HFR = star.HFR;
764 oneEdge->width = star.a;
765 oneEdge->numPixels = star.numPixels;
769 oneEdge->ellipticity = 1 - star.b / star.a;
771 oneEdge->ellipticity = 0;
773 starCenters.
append(oneEdge);
775 m_View->imageData()->setStarCenters(starCenters);
776 m_View->updateFrame();
783void FITSTab::solverDone(
bool timedOut,
bool success,
const FITSImage::Solution &solution,
double elapsedSeconds)
785 disconnect(m_Solver.
get(), &SolverUtils::done,
this, &FITSTab::solverDone);
786 m_PlateSolveUI.SolveButton->setText(
"Solve");
788 if (m_Solver->isRunning())
789 qCDebug(KSTARS_FITS) <<
"solverDone called, but it is still running.";
793 const QString result =
i18n(
"Solver timed out: %1s",
QString(
"%L1").arg(elapsedSeconds, 0,
'f', 1));
794 m_PlateSolveUI.Solution2->setText(result);
798 const QString result =
i18n(
"Solver failed: %1s",
QString(
"%L1").arg(elapsedSeconds, 0,
'f', 1));
799 m_PlateSolveUI.Solution2->setText(result);
803 const bool eastToTheRight = solution.parity == FITSImage::POSITIVE ? false :
true;
804 m_View->imageData()->injectWCS(solution.orientation, solution.ra, solution.dec, solution.pixscale, eastToTheRight);
805 m_View->imageData()->loadWCS();
808 const double solverPA = KSUtils::rotationToPositionAngle(solution.orientation);
809 m_PlateSolveUI.FitsSolverAngle->setText(
QString(
"%1ยบ").arg(solverPA, 0,
'f', 2));
811 int indexUsed = -1, healpixUsed = -1;
812 m_Solver->getSolutionHealpix(&indexUsed, &healpixUsed);
814 m_PlateSolveUI.FitsSolverIndexfile->setText(
"");
816 m_PlateSolveUI.FitsSolverIndexfile->setText(
819 .arg(healpixUsed >= 0 ?
QString(
"-%1").arg(healpixUsed) :
QString(
"")));;
822 const int imageWidth = m_View->imageData()->width();
823 const int units = m_PlateSolveUI.kcfg_FitsSolverImageScaleUnits->currentIndex();
824 if (units == SSolver::DEG_WIDTH)
825 m_PlateSolveUI.kcfg_FitsSolverScale->setValue(solution.pixscale * imageWidth / 3600.0);
826 else if (units == SSolver::ARCMIN_WIDTH)
827 m_PlateSolveUI.kcfg_FitsSolverScale->setValue(solution.pixscale * imageWidth / 60.0);
829 m_PlateSolveUI.kcfg_FitsSolverScale->setValue(solution.pixscale);
832 m_PlateSolveUI.FitsSolverEstRA->show(
dms(solution.ra));
833 m_PlateSolveUI.FitsSolverEstDec->show(
dms(solution.dec));
835 m_PlateSolveUI.Solution2->setText(result);
841int FITSTab::getProfileIndex(
int moduleIndex)
843 if (moduleIndex < 0 || moduleIndex >= Ekos::ProfileGroupNames.
size())
845 const QString moduleName = Ekos::ProfileGroupNames[moduleIndex];
846 const QString str = Options::fitsSolverProfileIndeces();
851 return indeces[moduleName].toString().toInt();
854void FITSTab::setProfileIndex(
int moduleIndex,
int profileIndex)
856 if (moduleIndex < 0 || moduleIndex >= Ekos::ProfileGroupNames.
size())
858 QString str = Options::fitsSolverProfileIndeces();
863 for (
int i = 0; i < Ekos::ProfileGroupNames.size(); i++)
868 else if (name ==
"Guide")
870 else if (name ==
"HFR")
873 initialIndeces[
name] =
"0";
879 indeces[Ekos::ProfileGroupNames[moduleIndex]] =
QString::number(profileIndex);
884void FITSTab::setupProfiles(
int moduleIndex)
886 if (moduleIndex < 0 || moduleIndex >= Ekos::ProfileGroupNames.
size())
888 Ekos::ProfileGroup profileGroup =
static_cast<Ekos::ProfileGroup
>(moduleIndex);
889 Options::setFitsSolverModule(moduleIndex);
893 m_PlateSolveUI.kcfg_FitsSolverProfile->clear();
894 for(
auto ¶m : optionsList)
895 m_PlateSolveUI.kcfg_FitsSolverProfile->addItem(param.listName);
897 m_ProfileEditor->setProfileGroup(profileGroup,
false);
900 m_PlateSolveUI.kcfg_FitsSolverProfile->setCurrentIndex(getProfileIndex(Options::fitsSolverModule()));
902 m_ProfileEditorPage->setHeader(
QString(
"FITS Viewer Solver %1 Profiles Editor")
903 .arg(Ekos::ProfileGroupNames[moduleIndex]));
906void FITSTab::initSolverUI()
909 m_PlateSolveUI.kcfg_FitsSolverModule->clear();
910 for (
int i = 0; i < Ekos::ProfileGroupNames.size(); i++)
911 m_PlateSolveUI.kcfg_FitsSolverModule->addItem(Ekos::ProfileGroupNames[i]);
912 m_PlateSolveUI.kcfg_FitsSolverModule->setCurrentIndex(Options::fitsSolverModule());
914 setupProfiles(Options::fitsSolverModule());
919 m_PlateSolveUI.kcfg_FitsSolverUseScale->setChecked(Options::fitsSolverUseScale());
920 m_PlateSolveUI.kcfg_FitsSolverScale->setValue(Options::fitsSolverScale());
921 m_PlateSolveUI.kcfg_FitsSolverImageScaleUnits->setCurrentIndex(Options::fitsSolverImageScaleUnits());
923 m_PlateSolveUI.kcfg_FitsSolverUsePosition->setChecked(Options::fitsSolverUsePosition());
924 m_PlateSolveUI.kcfg_FitsSolverRadius->setValue(Options::fitsSolverRadius());
926 m_PlateSolveUI.FitsSolverEstRA->setUnits(dmsBox::HOURS);
927 m_PlateSolveUI.FitsSolverEstDec->setUnits(dmsBox::DEGREES);
932 setProfileIndex(m_PlateSolveUI.kcfg_FitsSolverModule->currentIndex(), index);
937 Options::setFitsSolverUseScale(state);
941 Options::setFitsSolverScale(value);
945 Options::setFitsSolverImageScaleUnits(index);
950 Options::setFitsSolverUsePosition(state);
955 Options::setFitsSolverRadius(value);
959 const auto center = SkyMap::Instance()->getCenterPoint();
960 m_PlateSolveUI.FitsSolverEstRA->show(center.ra());
961 m_PlateSolveUI.FitsSolverEstDec->show(center.dec());
965 const SSolver::SolverType
type =
static_cast<SSolver::SolverType
>(Options::solverType());
966 if(type != SSolver::SOLVER_STELLARSOLVER)
968 m_PlateSolveUI.Solution2->setText(
i18n(
"Warning! This tool only supports the internal StellarSolver solver."));
969 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.
ButtonCode warningContinueCancel(QWidget *parent, const QString &text, const QString &title=QString(), const KGuiItem &buttonContinue=KStandardGuiItem::cont(), const KGuiItem &buttonCancel=KStandardGuiItem::cancel(), const QString &dontAskAgainName=QString(), Options options=Notify)
VehicleSection::Type type(QStringView coachNumber, QStringView coachClassification)
QString name(StandardAction id)
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 toLatin1() 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 toString(FormattingOptions options) const const
QString url(FormattingOptions options) const const