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();
82 auto J2000Coords = m_CenterPoint.catalogueCoord(
KStars::Instance()->data()->ut().djd());
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");
572 Ekos::Manager::Instance()->alignModule()->captureAndSolve();
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 {
"schedulerAlignStep", 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");
679 Ekos::Manager::Instance()->alignModule()->captureAndSolve();
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());
782 SkyMap::Instance()->setDestination(m_CenterPoint);
783 SkyMap::Instance()->slewFocus();
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());
void newStatus(ISD::Mount::Status status)
Change in the mount status.
static KStars * Instance()
void objectChanged(SkyObject *)
Emitted when current object changed.
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
An angle, stored as degrees, but expressible in many ways.
const double & Degrees() const
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(const QVariant &location)
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)