9#include "framingassistantui.h"
10#include "ui_framingassistant.h"
11#include "mosaiccomponent.h"
12#include "mosaictiles.h"
17#include "ekos/manager.h"
18#include "ekos/mount/mount.h"
19#include "schedulerprocess.h"
20#include "skymapcomposite.h"
23#include <KLocalizedString>
25#include <QtDBus/QDBusReply>
30FramingAssistantUI::FramingAssistantUI():
QDialog(
KStars::Instance()), ui(new Ui::FramingAssistant())
34 auto tiles = KStarsData::Instance()->
skyComposite()->mosaicComponent()->tiles();
36 ui->raBox->setUnits(dmsBox::HOURS);
39 ui->focalLenSpin->setValue(Options::telescopeFocalLength());
40 ui->focalReducerSpin->setValue(Options::telescopeFocalReducer());
41 ui->pixelWSizeSpin->setValue(Options::cameraPixelWidth());
42 ui->pixelHSizeSpin->setValue(Options::cameraPixelHeight());
43 ui->cameraWSpin->setValue(Options::cameraWidth());
44 ui->cameraHSpin->setValue(Options::cameraHeight());
46 ui->positionAngleSpin->setValue(tiles->positionAngle());
47 ui->sequenceEdit->setText(tiles->sequenceFile());
48 ui->directoryEdit->setText(tiles->outputDirectory());
49 ui->targetEdit->setText(tiles->targetName());
50 ui->focusEvery->setValue(tiles->focusEveryN());
51 ui->alignEvery->setValue(tiles->alignEveryN());
52 ui->trackStepCheck->setChecked(tiles->isTrackChecked());
53 ui->focusStepCheck->setChecked(tiles->isFocusChecked());
54 ui->alignStepCheck->setChecked(tiles->isAlignChecked());
55 ui->guideStepCheck->setChecked(tiles->isGuideChecked());
56 ui->mosaicWSpin->setValue(tiles->gridSize().width());
57 ui->mosaicHSpin->setValue(tiles->gridSize().height());
58 ui->overlapSpin->setValue(tiles->overlap());
60 ui->groupEdit->setText(tiles->group());
61 QString completionVal, completionArg;
62 completionVal = tiles->completionCondition(&completionArg);
63 if (completionVal ==
"FinishSequence")
64 ui->sequenceCompletionR->setChecked(
true);
65 else if (completionVal ==
"FinishRepeat")
67 ui->repeatCompletionR->setChecked(
true);
68 ui->repeatsSpin->setValue(completionArg.
toInt());
70 else if (completionVal ==
"FinishLoop")
71 ui->loopCompletionR->setChecked(
true);
73 if (tiles->operationMode() == MosaicTiles::MODE_OPERATION)
75 m_CenterPoint = *tiles.data();
81 m_CenterPoint = *SkyMap::Instance()->
focus();
83 m_CenterPoint.
setRA0(J2000Coords.ra0());
84 m_CenterPoint.setDec0(J2000Coords.dec0());
87 m_CenterPoint.updateCoordsNow(KStarsData::Instance()->updateNum());
88 ui->raBox->show(m_CenterPoint.ra0());
89 ui->decBox->show(m_CenterPoint.dec0());
94 ui->stackedWidget->setCurrentIndex(PAGE_EQUIPMENT);
98 if (Ekos::Manager::Instance()->ekosStatus() == Ekos::Success)
100 ui->goSolveB->setEnabled(
true);
103 connect(Ekos::Manager::Instance()->alignModule(), &Ekos::Align::newStatus,
this, &Ekos::FramingAssistantUI::setAlignState,
106 connect(Ekos::Manager::Instance(), &Ekos::Manager::ekosStatusChanged,
this, [
this](Ekos::CommunicationStatus status)
108 ui->goSolveB->setEnabled(status == Ekos::Success);
111 if (status == Ekos::Success)
115 connect(Ekos::Manager::Instance()->alignModule(), &Ekos::Align::newStatus,
this, &Ekos::FramingAssistantUI::setAlignState,
127 ui->stackedWidget->setCurrentIndex(PAGE_ADJUST_GRID);
131 ui->stackedWidget->setCurrentIndex(PAGE_ADJUST_GRID);
135 ui->stackedWidget->setCurrentIndex(PAGE_SELECT_GRID);
139 ui->stackedWidget->setCurrentIndex(PAGE_SELECT_GRID);
143 ui->stackedWidget->setCurrentIndex(PAGE_CREATE_JOBS);
144 ui->createJobsB->setEnabled(!ui->targetEdit->text().isEmpty() && !ui->sequenceEdit->text().isEmpty() &&
145 !ui->directoryEdit->text().isEmpty());
151 m_CenterPoint.setRA0(range24(m_CenterPoint.ra0().Hours() + dRA.
Hours()));
152 m_CenterPoint.setDec0(rangeDec(m_CenterPoint.dec0().Degrees() + dDE.
Degrees()));
153 m_CenterPoint.updateCoordsNow(KStarsData::Instance()->updateNum());
154 ui->raBox->show(m_CenterPoint.ra0());
155 ui->decBox->show(m_CenterPoint.dec0());
157 m_DebounceTimer->start();
168 m_CenterPoint = *SkyMap::Instance()->focus();
169 auto J2000Coords = m_CenterPoint.catalogueCoord(KStars::Instance()->data()->ut().djd());
170 m_CenterPoint.setRA0(J2000Coords.ra0());
171 m_CenterPoint.setDec0(J2000Coords.dec0());
173 m_CenterPoint.updateCoordsNow(KStarsData::Instance()->updateNum());
174 ui->raBox->show(m_CenterPoint.ra0());
175 ui->decBox->show(m_CenterPoint.dec0());
176 m_DebounceTimer->start();
180 if (tiles->operationMode() == MosaicTiles::MODE_PLANNING && SkyMap::IsFocused())
182 auto sanitized = KSUtils::sanitize(SkyMap::Instance()->focusObject()->
name());
183 if (sanitized !=
i18n(
"unnamed"))
185 ui->targetEdit->setText(sanitized);
187 if (m_JobsDirectory.isEmpty())
190 ui->directoryEdit->setText(m_JobsDirectory +
QDir::separator() + sanitized);
198 if (sanitized !=
i18n(
"unnamed"))
201 sanitized = KSUtils::sanitize(sanitized);
202 ui->targetEdit->setText(sanitized);
204 if (m_JobsDirectory.isEmpty())
207 ui->directoryEdit->setText(m_JobsDirectory +
QDir::separator() + sanitized);
214 m_CenterPoint.setRA0(ui->raBox->createDms());
215 m_CenterPoint.updateCoordsNow(KStarsData::Instance()->updateNum());
216 m_DebounceTimer->start();
222 m_CenterPoint.setDec0(ui->decBox->createDms());
223 m_CenterPoint.updateCoordsNow(KStarsData::Instance()->updateNum());
224 m_DebounceTimer->start();
230 ui->transparencySlider->setValue(Options::mosaicTransparencyLevel());
231 ui->transparencySlider->setEnabled(!Options::mosaicTransparencyAuto());
232 tiles->setPainterAlpha(Options::mosaicTransparencyLevel());
235 ui->transparencySlider->setToolTip(i18nc(
"%1 is the value, % is the percent sign",
"%1%", v));
236 Options::setMosaicTransparencyLevel(v);
237 auto tiles = KStarsData::Instance()->skyComposite()->mosaicComponent()->tiles();
238 tiles->setPainterAlpha(v);
239 m_DebounceTimer->start();
241 ui->transparencyAuto->setChecked(Options::mosaicTransparencyAuto());
242 tiles->setPainterAlphaAuto(Options::mosaicTransparencyAuto());
245 ui->transparencySlider->setEnabled(!v);
246 Options::setMosaicTransparencyAuto(v);
247 auto tiles = KStarsData::Instance()->skyComposite()->mosaicComponent()->tiles();
248 tiles->setPainterAlphaAuto(v);
250 m_DebounceTimer->start();
254 m_DebounceTimer =
new QTimer(
this);
255 m_DebounceTimer->setSingleShot(
true);
256 m_DebounceTimer->setInterval(500);
266 &Ekos::FramingAssistantUI::calculateFOV);
268 &Ekos::FramingAssistantUI::calculateFOV);
270 &Ekos::FramingAssistantUI::calculateFOV);
277 &Ekos::FramingAssistantUI::updateGridFromTargetFOV);
279 &Ekos::FramingAssistantUI::updateGridFromTargetFOV);
281 &Ekos::FramingAssistantUI::updateGridFromTargetFOV);
283 &Ekos::FramingAssistantUI::updateTargetFOVFromGrid);
285 &Ekos::FramingAssistantUI::updateTargetFOVFromGrid);
291 m_DebounceTimer->start();
304 if (tiles->operationMode() == MosaicTiles::MODE_PLANNING)
305 fetchINDIInformation();
307 if (isEquipmentValid())
308 ui->stackedWidget->setCurrentIndex(PAGE_SELECT_GRID);
310 tiles->setOperationMode(MosaicTiles::MODE_PLANNING);
313FramingAssistantUI::~FramingAssistantUI()
315 delete m_DebounceTimer;
318bool FramingAssistantUI::isEquipmentValid()
const
320 return (ui->focalLenSpin->value() > 0 && ui->cameraWSpin->value() > 0 && ui->cameraHSpin->value() > 0 &&
321 ui->pixelWSizeSpin->value() > 0 && ui->pixelHSizeSpin->value() > 0);
324double FramingAssistantUI::getTargetWFOV()
const
326 double const xFOV = ui->cameraWFOVSpin->value() * (1 - ui->overlapSpin->value() / 100.0);
327 return ui->cameraWFOVSpin->value() + xFOV * (ui->mosaicWSpin->value() - 1);
330double FramingAssistantUI::getTargetHFOV()
const
332 double const yFOV = ui->cameraHFOVSpin->value() * (1 - ui->overlapSpin->value() / 100.0);
333 return ui->cameraHFOVSpin->value() + yFOV * (ui->mosaicHSpin->value() - 1);
336double FramingAssistantUI::getTargetMosaicW()
const
339 if (!isEquipmentValid() || !ui->targetWFOVSpin->value() || ui->targetWFOVSpin->value() <= ui->cameraWFOVSpin->value())
343 double const xFOV = ui->cameraWFOVSpin->value() * (1 - ui->overlapSpin->value() / 100.0);
344 int const tiles = 1 + ceil((ui->targetWFOVSpin->value() - ui->cameraWFOVSpin->value()) / xFOV);
349double FramingAssistantUI::getTargetMosaicH()
const
352 if (!isEquipmentValid() || !ui->targetHFOVSpin->value() || ui->targetHFOVSpin->value() <= ui->cameraHFOVSpin->value())
356 double const yFOV = ui->cameraHFOVSpin->value() * (1 - ui->overlapSpin->value() / 100.0);
357 int const tiles = 1 + ceil((ui->targetHFOVSpin->value() - ui->cameraHFOVSpin->value()) / yFOV);
362void FramingAssistantUI::calculateFOV()
364 if (!isEquipmentValid())
367 ui->nextToSelectGridB->setEnabled(
true);
369 ui->targetWFOVSpin->setMinimum(ui->cameraWFOVSpin->value());
370 ui->targetHFOVSpin->setMinimum(ui->cameraHFOVSpin->value());
372 Options::setTelescopeFocalLength(ui->focalLenSpin->value());
373 Options::setTelescopeFocalReducer(ui->focalReducerSpin->value());
374 Options::setCameraPixelWidth(ui->pixelWSizeSpin->value());
375 Options::setCameraPixelHeight(ui->pixelHSizeSpin->value());
376 Options::setCameraWidth(ui->cameraWSpin->value());
377 Options::setCameraHeight(ui->cameraHSpin->value());
378 Options::setCameraRotation(ui->positionAngleSpin->value());
380 auto reducedFocalLength = ui->focalLenSpin->value() * ui->focalReducerSpin->value();
382 const auto fov_x = 206264.8062470963552 * ui->cameraWSpin->value() * ui->pixelWSizeSpin->value() / 60000.0 /
384 const auto fov_y = 206264.8062470963552 * ui->cameraHSpin->value() * ui->pixelHSizeSpin->value() / 60000.0 /
387 ui->cameraWFOVSpin->setValue(fov_x);
388 ui->cameraHFOVSpin->setValue(fov_y);
390 double const target_fov_w = getTargetWFOV();
391 double const target_fov_h = getTargetHFOV();
393 if (ui->targetWFOVSpin->value() < target_fov_w)
395 bool const sig = ui->targetWFOVSpin->blockSignals(
true);
396 ui->targetWFOVSpin->setValue(target_fov_w);
397 ui->targetWFOVSpin->blockSignals(sig);
400 if (ui->targetHFOVSpin->value() < target_fov_h)
402 bool const sig = ui->targetHFOVSpin->blockSignals(
true);
403 ui->targetHFOVSpin->setValue(target_fov_h);
404 ui->targetHFOVSpin->blockSignals(sig);
407 m_DebounceTimer->start();
410void FramingAssistantUI::resetFOV()
412 if (!isEquipmentValid())
415 ui->targetWFOVSpin->setValue(getTargetWFOV());
416 ui->targetHFOVSpin->setValue(getTargetHFOV());
419void FramingAssistantUI::updateTargetFOVFromGrid()
421 if (!isEquipmentValid())
424 double const targetWFOV = getTargetWFOV();
425 double const targetHFOV = getTargetHFOV();
427 if (ui->targetWFOVSpin->value() != targetWFOV)
429 bool const sig = ui->targetWFOVSpin->blockSignals(
true);
430 ui->targetWFOVSpin->setValue(targetWFOV);
431 ui->targetWFOVSpin->blockSignals(sig);
432 m_DebounceTimer->start();
435 if (ui->targetHFOVSpin->value() != targetHFOV)
437 bool const sig = ui->targetHFOVSpin->blockSignals(
true);
438 ui->targetHFOVSpin->setValue(targetHFOV);
439 ui->targetHFOVSpin->blockSignals(sig);
440 m_DebounceTimer->start();
444void FramingAssistantUI::updateGridFromTargetFOV()
446 if (!isEquipmentValid())
449 double const expectedW = getTargetMosaicW();
450 double const expectedH = getTargetMosaicH();
452 if (expectedW != ui->mosaicWSpin->value())
454 bool const sig = ui->mosaicWSpin->blockSignals(
true);
455 ui->mosaicWSpin->setValue(expectedW);
456 ui->mosaicWSpin->blockSignals(sig);
459 if (expectedH != ui->mosaicHSpin->value())
461 bool const sig = ui->mosaicHSpin->blockSignals(
true);
462 ui->mosaicHSpin->setValue(expectedH);
463 ui->mosaicHSpin->blockSignals(sig);
467 m_DebounceTimer->start();
470void FramingAssistantUI::constructMosaic()
472 m_DebounceTimer->stop();
474 if (!isEquipmentValid())
477 auto tiles = KStarsData::Instance()->
skyComposite()->mosaicComponent()->tiles();
481 tiles->setRA0(m_CenterPoint.ra0());
482 tiles->setDec0(m_CenterPoint.dec0());
483 tiles->updateCoordsNow(KStarsData::Instance()->updateNum());
486 tiles->setGridSize(
QSize(ui->mosaicWSpin->value(), ui->mosaicHSpin->value()));
488 tiles->setPositionAngle(ui->positionAngleSpin->value());
490 tiles->setCameraFOV(
QSizeF(ui->cameraWFOVSpin->value(), ui->cameraHFOVSpin->value()));
492 tiles->setMosaicFOV(
QSizeF(ui->targetWFOVSpin->value(), ui->targetHFOVSpin->value()));
494 tiles->setOverlap(ui->overlapSpin->value());
496 tiles->createTiles(ui->reverseOddRows->checkState() == Qt::CheckState::Checked);
499void FramingAssistantUI::fetchINDIInformation()
502 for (
auto oneWidget : ui->equipment->children())
503 oneWidget->blockSignals(
true);
504 for (
auto oneWidget : ui->createGrid->children())
505 oneWidget->blockSignals(
true);
508 "/KStars/Ekos/Align",
509 "org.kde.kstars.Ekos.Align",
517 m_CameraSize =
QSize(values[0], values[1]);
518 ui->cameraWSpin->setValue(m_CameraSize.width());
519 ui->cameraHSpin->setValue(m_CameraSize.height());
520 m_PixelSize =
QSizeF(values[2], values[3]);
521 ui->pixelWSizeSpin->setValue(m_PixelSize.width());
522 ui->pixelHSizeSpin->setValue(m_PixelSize.height());
529 m_FocalLength = values[0];
530 m_FocalReducer = values[2];
531 ui->focalLenSpin->setValue(m_FocalLength);
532 ui->focalReducerSpin->setValue(m_FocalReducer);
539 if (values[0] > INVALID_VALUE)
541 m_PA = KSUtils::rotationToPositionAngle(values[0]);
542 ui->positionAngleSpin->setValue(m_PA);
549 for (
auto oneWidget : ui->equipment->children())
550 oneWidget->blockSignals(
false);
551 for (
auto oneWidget : ui->createGrid->children())
552 oneWidget->blockSignals(
false);
555void FramingAssistantUI::rewordStepEvery(
int v)
564void FramingAssistantUI::goAndSolve()
568 if (m_GOTOSolvePending && m_MountState == ISD::Mount::MOUNT_TRACKING)
570 m_GOTOSolvePending =
false;
571 ui->goSolveB->setStyleSheet(
"border: 1px outset yellow");
577 Ekos::Manager::Instance()->alignModule()->
setSolverAction(Ekos::Align::GOTO_SLEW);
578 Ekos::Manager::Instance()->mountModule()->
gotoTarget(m_CenterPoint);
579 ui->goSolveB->setStyleSheet(
"border: 1px outset magenta");
580 m_GOTOSolvePending =
true;
584void FramingAssistantUI::createJobs()
586 auto scheduler = Ekos::Manager::Instance()->schedulerModule();
587 auto tiles = KStarsData::Instance()->
skyComposite()->mosaicComponent()->tiles();
588 auto sequence = ui->sequenceEdit->text();
589 auto outputDirectory = ui->directoryEdit->text();
590 auto target = ui->targetEdit->text();
591 auto group = ui->groupEdit->text();
593 tiles->setTargetName(target);
594 tiles->setGroup(group);
595 tiles->setOutputDirectory(outputDirectory);
596 tiles->setSequenceFile(sequence);
597 tiles->setFocusEveryN(ui->focusEvery->value());
598 tiles->setAlignEveryN(ui->alignEvery->value());
599 tiles->setStepChecks(ui->trackStepCheck->isChecked(), ui->focusStepCheck->isChecked(),
600 ui->alignStepCheck->isChecked(), ui->guideStepCheck->isChecked());
602 if (ui->sequenceCompletionR->isChecked())
603 tiles->setCompletionCondition(
"FinishSequence",
"");
604 else if (ui->loopCompletionR->isChecked())
605 tiles->setCompletionCondition(
"FinishLoop",
"");
606 else if (ui->repeatCompletionR->isChecked())
607 tiles->setCompletionCondition(
"FinishRepeat",
QString(
"%1").arg(ui->repeatsSpin->value()));
609 tiles->setPositionAngle(ui->positionAngleSpin->value());
611 scheduler->process()->removeAllJobs();
613 QString completionVal, completionArg;
616 completionVal = tiles->completionCondition(&completionArg);
618 if (completionVal ==
"FinishSequence")
619 completionSettings = {{
"sequenceCheck",
true}};
620 else if (completionVal ==
"FinishRepeat")
621 completionSettings = {{
"repeatCheck",
true}, {
"repeatRuns", completionArg.
toInt()}};
622 else if (completionVal ==
"FinishLoop")
623 completionSettings = {{
"loopCheck",
true}};
626 for (
auto oneTile : tiles->tiles())
629 XMLEle *root = scheduler->process()->getSequenceJobRoot(sequence);
633 const auto oneTarget =
QString(
"%1-Part_%2").
arg(target).
arg(batchCount);
634 if (scheduler->process()->createJobSequence(root, oneTarget, outputDirectory) ==
false)
641 auto oneSequence =
QString(
"%1/%2.esq").
arg(outputDirectory, oneTarget);
644 bool shouldFocus = ui->focusStepCheck->isChecked() && (batchCount == 1 || (batchCount % ui->focusEvery->value()) == 0);
645 bool shouldAlign = ui->alignStepCheck->isChecked() && (batchCount == 1 || (batchCount % ui->alignEvery->value()) == 0);
646 QVariantMap settings =
648 {
"nameEdit", oneTarget},
649 {
"groupEdit", tiles->group()},
650 {
"raBox", oneTile->skyCenter.ra0().toHMSString()},
651 {
"decBox", oneTile->skyCenter.dec0().toDMSString()},
653 {
"positionAngleSpin", KSUtils::rangePA(tiles->positionAngle())},
654 {
"sequenceEdit", oneSequence},
655 {
"schedulerTrackStep", ui->trackStepCheck->isChecked()},
656 {
"schedulerFocusStep", shouldFocus},
657 {
"schedulerFocusStep", shouldAlign},
658 {
"schedulerGuideStep", ui->guideStepCheck->isChecked()}
661 scheduler->setAllSettings(settings);
662 scheduler->saveJob();
665 auto schedulerListFile =
QString(
"%1/%2.esl").
arg(outputDirectory, target);
668 Ekos::Manager::Instance()->activateModule(
i18n(
"Scheduler"),
true);
669 scheduler->updateJobTable();
672void FramingAssistantUI::setMountState(ISD::Mount::Status value)
674 m_MountState = value;
675 if (m_GOTOSolvePending && m_MountState == ISD::Mount::MOUNT_TRACKING)
677 m_GOTOSolvePending =
false;
678 ui->goSolveB->setStyleSheet(
"border: 1px outset yellow");
683void FramingAssistantUI::setAlignState(AlignState value)
685 m_AlignState = value;
688 ui->goSolveB->setStyleSheet(
"border: 1px outset green");
690 ui->goSolveB->setStyleSheet(
"border: 1px outset red");
693void FramingAssistantUI::selectSequence()
697 i18n(
"Ekos Sequence Queue (*.esq)"));
701 ui->sequenceEdit->setText(file);
702 ui->createJobsB->setEnabled(!ui->targetEdit->text().isEmpty() && !ui->sequenceEdit->text().isEmpty() &&
703 !ui->directoryEdit->text().isEmpty());
707void FramingAssistantUI::selectImport()
711 i18n(
"Telescopius CSV (*.csv)"));
714 parseMosaicCSV(file);
717bool FramingAssistantUI::parseMosaicCSV(
const QString &filename)
720 csv_sequence.
append(qMakePair(
QString(
"Pane"), KSParser::D_QSTRING));
721 csv_sequence.
append(qMakePair(
QString(
"RA"), KSParser::D_QSTRING));
722 csv_sequence.
append(qMakePair(
QString(
"DEC"), KSParser::D_QSTRING));
723 csv_sequence.
append(qMakePair(
QString(
"Position Angle (East)"), KSParser::D_DOUBLE));
724 csv_sequence.
append(qMakePair(
QString(
"Pane width (arcmins)"), KSParser::D_DOUBLE));
725 csv_sequence.
append(qMakePair(
QString(
"Pane height (arcmins)"), KSParser::D_DOUBLE));
726 csv_sequence.
append(qMakePair(
QString(
"Overlap"), KSParser::D_QSTRING));
727 csv_sequence.
append(qMakePair(
QString(
"Row"), KSParser::D_INT));
728 csv_sequence.
append(qMakePair(
QString(
"Column"), KSParser::D_INT));
729 KSParser csvParser(filename,
',', csv_sequence);
732 int maxRow = 1, maxCol = 1;
733 auto haveCenter =
false;
734 while (csvParser.HasNextRow())
736 row_content = csvParser.ReadNextRow();
737 auto pane = row_content[
"Pane"].toString();
743 if (pane !=
"Center")
745 auto row = row_content[
"Row"].toInt();
746 maxRow = qMax(row, maxRow);
747 auto col = row_content[
"Column"].toInt();
748 maxCol = qMax(col, maxCol);
754 auto ra = row_content[
"RA"].toString().trimmed();
755 auto dec = row_content[
"DEC"].toString().trimmed();
757 ui->raBox->setText(ra.replace(
"hr",
"h"));
758 ui->decBox->setText(
dec.remove(
"ยบ"));
760 auto pa = row_content[
"Position Angle (East)"].toDouble();
761 ui->positionAngleSpin->setValue(pa);
764 auto overlap = row_content[
"Overlap"].toString().trimmed().mid(0, 2).toDouble();
765 ui->overlapSpin->setValue(overlap);
768 if (haveCenter ==
false)
770 KSNotification::sorry(
i18n(
"Import must contain center coordinates."),
i18n(
"Sorry"), 15);
775 ui->mosaicWSpin->setValue(maxRow);
776 ui->mosaicHSpin->setValue(maxCol);
778 m_CenterPoint.setRA0(ui->raBox->createDms());
779 m_CenterPoint.setDec0(ui->decBox->createDms());
780 m_CenterPoint.updateCoordsNow(KStarsData::Instance()->updateNum());
785 ui->nextToAdjustGrid->click();
790bool FramingAssistantUI::importMosaic(
const QJsonObject &payload)
793 auto csv = payload[
"csv"].toString();
795 auto sequence = payload[
"sequence"].toString();
797 auto target = payload[
"target"].toString();
799 auto directory = payload[
"directory"].toString();
802 auto track = payload[
"track"].toBool();
803 auto focus = payload[
"focus"].toBool();
804 auto align = payload[
"align"].toBool();
805 auto guide = payload[
"guide"].toBool();
811 csvFile.
write(csv.toUtf8());
815 m_DebounceTimer->disconnect();
817 if (parseMosaicCSV(csvFile.
fileName()) ==
false)
822 m_JobsDirectory = directory;
825 ui->trackStepCheck->setChecked(track);
826 ui->focusStepCheck->setChecked(focus);
827 ui->alignStepCheck->setChecked(align);
828 ui->guideStepCheck->setChecked(guide);
830 ui->sequenceEdit->setText(sequence);
831 ui->targetEdit->setText(target);
836 if (ui->createJobsB->isEnabled() ==
false)
841 ui->createJobsB->click();
846void FramingAssistantUI::selectDirectory()
849 "Select Jobs Directory"),
852 if (!m_JobsDirectory.isEmpty())
855 QString sanitized = ui->targetEdit->text();
856 if (sanitized.
isEmpty() ==
false && sanitized !=
i18n(
"unnamed"))
859 sanitized = KSUtils::sanitize(sanitized);
860 ui->directoryEdit->setText(m_JobsDirectory +
QDir::separator() + sanitized);
864 ui->directoryEdit->setText(m_JobsDirectory);
867 ui->createJobsB->setEnabled(!ui->targetEdit->text().isEmpty() && !ui->sequenceEdit->text().isEmpty() &&
868 !ui->directoryEdit->text().isEmpty());
872void FramingAssistantUI::sanitizeTarget()
874 QString sanitized = ui->targetEdit->text();
875 if (sanitized !=
i18n(
"unnamed"))
878 sanitized = KSUtils::sanitize(sanitized);
879 ui->targetEdit->blockSignals(
true);
880 ui->targetEdit->setText(sanitized);
881 ui->targetEdit->blockSignals(
false);
883 if (m_JobsDirectory.isEmpty())
886 ui->directoryEdit->setText(m_JobsDirectory +
QDir::separator() + sanitized);
888 ui->createJobsB->setEnabled(!ui->targetEdit->text().isEmpty() && !ui->sequenceEdit->text().isEmpty() &&
889 !ui->directoryEdit->text().isEmpty());
Q_SCRIPTABLE Q_NOREPLY void setSolverAction(int mode)
DBUS interface function.
Q_INVOKABLE Q_SCRIPTABLE bool gotoTarget(const QString &target)
DBUS interface function.
void newStatus(ISD::Mount::Status status)
Change in the mount status.
SkyMapComposite * skyComposite()
This is the main window for KStars.
static KStars * Instance()
SkyPoint * focus()
Retrieve the Focus point; the position on the sky at the center of the skymap.
void objectChanged(SkyObject *)
Emitted when current object changed.
void setDestination(const SkyPoint &f)
sets the destination point of the sky map.
void slewFocus()
Step the Focus point toward the Destination point.
void mosaicCenterChanged(dms dRA, dms dDE)
Emitter when mosaic center is dragged in the sky map.
Provides all necessary information about an object in the sky: its coordinates, name(s),...
virtual QString name(void) const
void setRA0(dms r)
Sets RA0, the catalog Right Ascension.
SkyPoint catalogueCoord(long double jdf)
Computes the J2000.0 catalogue coordinates for this SkyPoint using the epoch removing aberration,...
An angle, stored as degrees, but expressible in many ways.
const double & Degrees() const
Q_SCRIPTABLE bool captureAndSolve(bool initialCall=true)
DBUS interface function.
QString i18np(const char *singular, const char *plural, const TYPE &arg...)
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.
@ ALIGN_FAILED
Alignment failed.
@ ALIGN_ABORTED
Alignment aborted by user or agent.
@ ALIGN_COMPLETE
Alignment successfully completed.
QString name(StandardAction id)
void valueChanged(int value)
QDBusConnection sessionBus()
bool isValid() const const
QString cleanPath(const QString &path)
void valueChanged(double d)
virtual void close() override
QString getExistingDirectory(QWidget *parent, const QString &caption, const QString &dir, Options options)
QString getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, Options options)
qint64 write(const QByteArray &data)
void append(QList< T > &&value)
void setSuffix(const QString &suffix)
QString arg(Args &&... args) const const
bool isEmpty() const const
int toInt(bool *ok, int base) const const
QTextStream & dec(QTextStream &stream)
virtual QString fileName() const const override
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QUrl fromLocalFile(const QString &localFile)