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);
101 ui->goRotateB->setEnabled(
true);
104 connect(Ekos::Manager::Instance()->alignModule(), &Ekos::Align::newStatus,
this, &Ekos::FramingAssistantUI::setAlignState,
107 connect(Ekos::Manager::Instance(), &Ekos::Manager::ekosStatusChanged,
this, [
this](Ekos::CommunicationStatus status)
109 ui->goSolveB->setEnabled(status == Ekos::Success);
110 ui->goRotateB->setEnabled(status == Ekos::Success);
113 if (status == Ekos::Success)
117 connect(Ekos::Manager::Instance()->alignModule(), &Ekos::Align::newStatus,
this, &Ekos::FramingAssistantUI::setAlignState,
130 ui->stackedWidget->setCurrentIndex(PAGE_ADJUST_GRID);
134 ui->stackedWidget->setCurrentIndex(PAGE_ADJUST_GRID);
138 ui->stackedWidget->setCurrentIndex(PAGE_SELECT_GRID);
142 ui->stackedWidget->setCurrentIndex(PAGE_SELECT_GRID);
146 ui->stackedWidget->setCurrentIndex(PAGE_CREATE_JOBS);
147 ui->createJobsB->setEnabled(!ui->targetEdit->text().isEmpty() && !ui->sequenceEdit->text().isEmpty() &&
148 !ui->directoryEdit->text().isEmpty());
154 m_CenterPoint.setRA0(range24(m_CenterPoint.ra0().Hours() + dRA.
Hours()));
155 m_CenterPoint.setDec0(rangeDec(m_CenterPoint.dec0().Degrees() + dDE.
Degrees()));
156 m_CenterPoint.updateCoordsNow(KStarsData::Instance()->updateNum());
157 ui->raBox->show(m_CenterPoint.ra0());
158 ui->decBox->show(m_CenterPoint.dec0());
160 m_DebounceTimer->start();
171 m_CenterPoint = *SkyMap::Instance()->focus();
172 auto J2000Coords = m_CenterPoint.catalogueCoord(KStars::Instance()->data()->ut().djd());
173 m_CenterPoint.setRA0(J2000Coords.ra0());
174 m_CenterPoint.setDec0(J2000Coords.dec0());
176 m_CenterPoint.updateCoordsNow(KStarsData::Instance()->updateNum());
177 ui->raBox->show(m_CenterPoint.ra0());
178 ui->decBox->show(m_CenterPoint.dec0());
179 m_DebounceTimer->start();
183 if (tiles->operationMode() == MosaicTiles::MODE_PLANNING && SkyMap::IsFocused())
185 auto sanitized = KSUtils::sanitize(SkyMap::Instance()->focusObject()->
name());
186 if (sanitized !=
i18n(
"unnamed"))
188 ui->targetEdit->setText(sanitized);
190 if (m_JobsDirectory.isEmpty())
193 ui->directoryEdit->setText(m_JobsDirectory +
QDir::separator() + sanitized);
201 if (sanitized !=
i18n(
"unnamed"))
204 sanitized = KSUtils::sanitize(sanitized);
205 ui->targetEdit->setText(sanitized);
207 if (m_JobsDirectory.isEmpty())
210 ui->directoryEdit->setText(m_JobsDirectory +
QDir::separator() + sanitized);
217 m_CenterPoint.setRA0(ui->raBox->createDms());
218 m_CenterPoint.updateCoordsNow(KStarsData::Instance()->updateNum());
219 m_DebounceTimer->start();
225 m_CenterPoint.setDec0(ui->decBox->createDms());
226 m_CenterPoint.updateCoordsNow(KStarsData::Instance()->updateNum());
227 m_DebounceTimer->start();
233 ui->transparencySlider->setValue(Options::mosaicTransparencyLevel());
234 ui->transparencySlider->setEnabled(!Options::mosaicTransparencyAuto());
235 tiles->setPainterAlpha(Options::mosaicTransparencyLevel());
238 ui->transparencySlider->setToolTip(i18nc(
"%1 is the value, % is the percent sign",
"%1%", v));
239 Options::setMosaicTransparencyLevel(v);
240 auto tiles = KStarsData::Instance()->skyComposite()->mosaicComponent()->tiles();
241 tiles->setPainterAlpha(v);
242 m_DebounceTimer->start();
244 ui->transparencyAuto->setChecked(Options::mosaicTransparencyAuto());
245 tiles->setPainterAlphaAuto(Options::mosaicTransparencyAuto());
248 ui->transparencySlider->setEnabled(!v);
249 Options::setMosaicTransparencyAuto(v);
250 auto tiles = KStarsData::Instance()->skyComposite()->mosaicComponent()->tiles();
251 tiles->setPainterAlphaAuto(v);
253 m_DebounceTimer->start();
257 m_DebounceTimer =
new QTimer(
this);
258 m_DebounceTimer->setSingleShot(
true);
259 m_DebounceTimer->setInterval(500);
269 &Ekos::FramingAssistantUI::calculateFOV);
271 &Ekos::FramingAssistantUI::calculateFOV);
273 &Ekos::FramingAssistantUI::calculateFOV);
280 &Ekos::FramingAssistantUI::updateGridFromTargetFOV);
282 &Ekos::FramingAssistantUI::updateGridFromTargetFOV);
284 &Ekos::FramingAssistantUI::updateGridFromTargetFOV);
286 &Ekos::FramingAssistantUI::updateTargetFOVFromGrid);
288 &Ekos::FramingAssistantUI::updateTargetFOVFromGrid);
294 m_DebounceTimer->start();
307 if (tiles->operationMode() == MosaicTiles::MODE_PLANNING)
308 fetchINDIInformation();
310 if (isEquipmentValid())
311 ui->stackedWidget->setCurrentIndex(PAGE_SELECT_GRID);
313 tiles->setOperationMode(MosaicTiles::MODE_PLANNING);
316FramingAssistantUI::~FramingAssistantUI()
318 delete m_DebounceTimer;
321bool FramingAssistantUI::isEquipmentValid()
const
323 return (ui->focalLenSpin->value() > 0 && ui->cameraWSpin->value() > 0 && ui->cameraHSpin->value() > 0 &&
324 ui->pixelWSizeSpin->value() > 0 && ui->pixelHSizeSpin->value() > 0);
327double FramingAssistantUI::getTargetWFOV()
const
329 double const xFOV = ui->cameraWFOVSpin->value() * (1 - ui->overlapSpin->value() / 100.0);
330 return ui->cameraWFOVSpin->value() + xFOV * (ui->mosaicWSpin->value() - 1);
333double FramingAssistantUI::getTargetHFOV()
const
335 double const yFOV = ui->cameraHFOVSpin->value() * (1 - ui->overlapSpin->value() / 100.0);
336 return ui->cameraHFOVSpin->value() + yFOV * (ui->mosaicHSpin->value() - 1);
339double FramingAssistantUI::getTargetMosaicW()
const
342 if (!isEquipmentValid() || !ui->targetWFOVSpin->value() || ui->targetWFOVSpin->value() <= ui->cameraWFOVSpin->value())
346 double const xFOV = ui->cameraWFOVSpin->value() * (1 - ui->overlapSpin->value() / 100.0);
347 int const tiles = 1 + ceil((ui->targetWFOVSpin->value() - ui->cameraWFOVSpin->value()) / xFOV);
352double FramingAssistantUI::getTargetMosaicH()
const
355 if (!isEquipmentValid() || !ui->targetHFOVSpin->value() || ui->targetHFOVSpin->value() <= ui->cameraHFOVSpin->value())
359 double const yFOV = ui->cameraHFOVSpin->value() * (1 - ui->overlapSpin->value() / 100.0);
360 int const tiles = 1 + ceil((ui->targetHFOVSpin->value() - ui->cameraHFOVSpin->value()) / yFOV);
365void FramingAssistantUI::calculateFOV()
367 if (!isEquipmentValid())
370 ui->nextToSelectGridB->setEnabled(
true);
372 ui->targetWFOVSpin->setMinimum(ui->cameraWFOVSpin->value());
373 ui->targetHFOVSpin->setMinimum(ui->cameraHFOVSpin->value());
375 Options::setTelescopeFocalLength(ui->focalLenSpin->value());
376 Options::setTelescopeFocalReducer(ui->focalReducerSpin->value());
377 Options::setCameraPixelWidth(ui->pixelWSizeSpin->value());
378 Options::setCameraPixelHeight(ui->pixelHSizeSpin->value());
379 Options::setCameraWidth(ui->cameraWSpin->value());
380 Options::setCameraHeight(ui->cameraHSpin->value());
381 Options::setCameraRotation(ui->positionAngleSpin->value());
383 auto reducedFocalLength = ui->focalLenSpin->value() * ui->focalReducerSpin->value();
385 const auto fov_x = 206264.8062470963552 * ui->cameraWSpin->value() * ui->pixelWSizeSpin->value() / 60000.0 /
387 const auto fov_y = 206264.8062470963552 * ui->cameraHSpin->value() * ui->pixelHSizeSpin->value() / 60000.0 /
390 ui->cameraWFOVSpin->setValue(fov_x);
391 ui->cameraHFOVSpin->setValue(fov_y);
393 double const target_fov_w = getTargetWFOV();
394 double const target_fov_h = getTargetHFOV();
396 if (ui->targetWFOVSpin->value() < target_fov_w)
398 bool const sig = ui->targetWFOVSpin->blockSignals(
true);
399 ui->targetWFOVSpin->setValue(target_fov_w);
400 ui->targetWFOVSpin->blockSignals(sig);
403 if (ui->targetHFOVSpin->value() < target_fov_h)
405 bool const sig = ui->targetHFOVSpin->blockSignals(
true);
406 ui->targetHFOVSpin->setValue(target_fov_h);
407 ui->targetHFOVSpin->blockSignals(sig);
410 m_DebounceTimer->start();
413void FramingAssistantUI::resetFOV()
415 if (!isEquipmentValid())
418 ui->targetWFOVSpin->setValue(getTargetWFOV());
419 ui->targetHFOVSpin->setValue(getTargetHFOV());
422void FramingAssistantUI::updateTargetFOVFromGrid()
424 if (!isEquipmentValid())
427 double const targetWFOV = getTargetWFOV();
428 double const targetHFOV = getTargetHFOV();
430 if (ui->targetWFOVSpin->value() != targetWFOV)
432 bool const sig = ui->targetWFOVSpin->blockSignals(
true);
433 ui->targetWFOVSpin->setValue(targetWFOV);
434 ui->targetWFOVSpin->blockSignals(sig);
435 m_DebounceTimer->start();
438 if (ui->targetHFOVSpin->value() != targetHFOV)
440 bool const sig = ui->targetHFOVSpin->blockSignals(
true);
441 ui->targetHFOVSpin->setValue(targetHFOV);
442 ui->targetHFOVSpin->blockSignals(sig);
443 m_DebounceTimer->start();
447void FramingAssistantUI::updateGridFromTargetFOV()
449 if (!isEquipmentValid())
452 double const expectedW = getTargetMosaicW();
453 double const expectedH = getTargetMosaicH();
455 if (expectedW != ui->mosaicWSpin->value())
457 bool const sig = ui->mosaicWSpin->blockSignals(
true);
458 ui->mosaicWSpin->setValue(expectedW);
459 ui->mosaicWSpin->blockSignals(sig);
462 if (expectedH != ui->mosaicHSpin->value())
464 bool const sig = ui->mosaicHSpin->blockSignals(
true);
465 ui->mosaicHSpin->setValue(expectedH);
466 ui->mosaicHSpin->blockSignals(sig);
470 m_DebounceTimer->start();
473void FramingAssistantUI::constructMosaic()
475 m_DebounceTimer->stop();
477 if (!isEquipmentValid())
480 auto tiles = KStarsData::Instance()->skyComposite()->mosaicComponent()->tiles();
484 tiles->setRA0(m_CenterPoint.ra0());
485 tiles->setDec0(m_CenterPoint.dec0());
486 tiles->updateCoordsNow(KStarsData::Instance()->updateNum());
489 tiles->setGridSize(
QSize(ui->mosaicWSpin->value(), ui->mosaicHSpin->value()));
491 tiles->setPositionAngle(ui->positionAngleSpin->value());
493 tiles->setCameraFOV(
QSizeF(ui->cameraWFOVSpin->value(), ui->cameraHFOVSpin->value()));
495 tiles->setMosaicFOV(
QSizeF(ui->targetWFOVSpin->value(), ui->targetHFOVSpin->value()));
497 tiles->setOverlap(ui->overlapSpin->value());
499 tiles->createTiles(ui->reverseOddRows->checkState() == Qt::CheckState::Checked);
502void FramingAssistantUI::fetchINDIInformation()
505 for (
auto oneWidget : ui->equipment->children())
506 oneWidget->blockSignals(
true);
507 for (
auto oneWidget : ui->createGrid->children())
508 oneWidget->blockSignals(
true);
511 "/KStars/Ekos/Align",
512 "org.kde.kstars.Ekos.Align",
520 m_CameraSize =
QSize(values[0], values[1]);
521 ui->cameraWSpin->setValue(m_CameraSize.width());
522 ui->cameraHSpin->setValue(m_CameraSize.height());
523 m_PixelSize =
QSizeF(values[2], values[3]);
524 ui->pixelWSizeSpin->setValue(m_PixelSize.width());
525 ui->pixelHSizeSpin->setValue(m_PixelSize.height());
532 m_FocalLength = values[0];
533 m_FocalReducer = values[2];
534 ui->focalLenSpin->setValue(m_FocalLength);
535 ui->focalReducerSpin->setValue(m_FocalReducer);
542 if (values[0] > INVALID_VALUE)
544 m_PA = KSUtils::rotationToPositionAngle(values[0]);
545 ui->positionAngleSpin->setValue(m_PA);
552 for (
auto oneWidget : ui->equipment->children())
553 oneWidget->blockSignals(
false);
554 for (
auto oneWidget : ui->createGrid->children())
555 oneWidget->blockSignals(
false);
558void FramingAssistantUI::rewordStepEvery(
int v)
567void FramingAssistantUI::goAndSolve()
571 if (m_GOTOSolvePending && m_MountState == ISD::Mount::MOUNT_TRACKING)
573 m_GOTOSolvePending =
false;
574 ui->goSolveB->setStyleSheet(
"border: 1px outset yellow");
575 ui->goRotateB->setStyleSheet(
"border: 1px outset yellow");
576 Ekos::Manager::Instance()->alignModule()->captureAndSolve();
581 Ekos::Manager::Instance()->alignModule()->setSolverAction(Ekos::Align::GOTO_SLEW);
582 Ekos::Manager::Instance()->mountModule()->gotoTarget(m_CenterPoint);
583 ui->goSolveB->setStyleSheet(
"border: 1px outset magenta");
584 ui->goRotateB->setStyleSheet(
"border: 1px outset magenta");
585 m_GOTOSolvePending =
true;
589void FramingAssistantUI::goAndRotate()
591 Ekos::Manager::Instance()->alignModule()->setProperty(
"targetPositionAngle", ui->positionAngleSpin->value());
595void FramingAssistantUI::createJobs()
597 auto scheduler = Ekos::Manager::Instance()->schedulerModule();
598 auto tiles = KStarsData::Instance()->skyComposite()->mosaicComponent()->tiles();
599 auto sequence = ui->sequenceEdit->text();
600 auto outputDirectory = ui->directoryEdit->text();
601 auto target = ui->targetEdit->text();
602 auto group = ui->groupEdit->text();
604 tiles->setTargetName(target);
605 tiles->setGroup(group);
606 tiles->setOutputDirectory(outputDirectory);
607 tiles->setSequenceFile(sequence);
608 tiles->setFocusEveryN(ui->focusEvery->value());
609 tiles->setAlignEveryN(ui->alignEvery->value());
610 tiles->setStepChecks(ui->trackStepCheck->isChecked(), ui->focusStepCheck->isChecked(),
611 ui->alignStepCheck->isChecked(), ui->guideStepCheck->isChecked());
613 if (ui->sequenceCompletionR->isChecked())
614 tiles->setCompletionCondition(
"FinishSequence",
"");
615 else if (ui->loopCompletionR->isChecked())
616 tiles->setCompletionCondition(
"FinishLoop",
"");
617 else if (ui->repeatCompletionR->isChecked())
618 tiles->setCompletionCondition(
"FinishRepeat",
QString(
"%1").arg(ui->repeatsSpin->value()));
620 tiles->setPositionAngle(ui->positionAngleSpin->value());
622 scheduler->process()->removeAllJobs();
624 QString completionVal, completionArg;
627 completionVal = tiles->completionCondition(&completionArg);
629 if (completionVal ==
"FinishSequence")
630 completionSettings = {{
"sequenceCheck",
true}};
631 else if (completionVal ==
"FinishRepeat")
632 completionSettings = {{
"repeatCheck",
true}, {
"repeatRuns", completionArg.
toInt()}};
633 else if (completionVal ==
"FinishLoop")
634 completionSettings = {{
"loopCheck",
true}};
637 for (
auto oneTile : tiles->tiles())
640 XMLEle *root = scheduler->process()->getSequenceJobRoot(sequence);
644 const auto oneTarget =
QString(
"%1-Part_%2").
arg(target).
arg(batchCount);
645 if (scheduler->process()->createJobSequence(root, oneTarget, outputDirectory) ==
false)
652 auto oneSequence =
QString(
"%1/%2.esq").
arg(outputDirectory, oneTarget);
655 bool shouldFocus = ui->focusStepCheck->isChecked() && (batchCount == 1 || (batchCount % ui->focusEvery->value()) == 0);
656 bool shouldAlign = ui->alignStepCheck->isChecked() && (batchCount == 1 || (batchCount % ui->alignEvery->value()) == 0);
657 QVariantMap settings =
659 {
"nameEdit", oneTarget},
660 {
"groupEdit", tiles->group()},
661 {
"raBox", oneTile->skyCenter.ra0().toHMSString()},
662 {
"decBox", oneTile->skyCenter.dec0().toDMSString()},
664 {
"positionAngleSpin", KSUtils::rangePA(tiles->positionAngle())},
665 {
"sequenceEdit", oneSequence},
666 {
"schedulerTrackStep", ui->trackStepCheck->isChecked()},
667 {
"schedulerFocusStep", shouldFocus},
668 {
"schedulerAlignStep", shouldAlign},
669 {
"schedulerGuideStep", ui->guideStepCheck->isChecked()}
672 scheduler->setAllSettings(settings);
673 scheduler->saveJob();
676 auto schedulerListFile =
QString(
"%1/%2.esl").
arg(outputDirectory, target);
679 Ekos::Manager::Instance()->activateModule(
i18n(
"Scheduler"),
true);
680 scheduler->updateJobTable();
683void FramingAssistantUI::setMountState(ISD::Mount::Status value)
685 m_MountState = value;
686 if (m_GOTOSolvePending && m_MountState == ISD::Mount::MOUNT_TRACKING)
688 m_GOTOSolvePending =
false;
689 ui->goSolveB->setStyleSheet(
"border: 1px outset yellow");
690 ui->goRotateB->setStyleSheet(
"border: 1px outset yellow");
691 Ekos::Manager::Instance()->alignModule()->captureAndSolve();
695void FramingAssistantUI::setAlignState(AlignState value)
697 m_AlignState = value;
701 ui->goSolveB->setStyleSheet(
"border: 1px outset green");
702 ui->goRotateB->setStyleSheet(
"border: 1px outset green");
706 ui->goSolveB->setStyleSheet(
"border: 1px outset red");
707 ui->goRotateB->setStyleSheet(
"border: 1px outset red");
711void FramingAssistantUI::selectSequence()
715 i18n(
"Ekos Sequence Queue (*.esq)"));
719 ui->sequenceEdit->setText(file);
720 ui->createJobsB->setEnabled(!ui->targetEdit->text().isEmpty() && !ui->sequenceEdit->text().isEmpty() &&
721 !ui->directoryEdit->text().isEmpty());
725void FramingAssistantUI::selectImport()
729 i18n(
"Telescopius CSV (*.csv)"));
732 parseMosaicCSV(file);
735bool FramingAssistantUI::parseMosaicCSV(
const QString &filename)
738 csv_sequence.
append(qMakePair(
QString(
"Pane"), KSParser::D_QSTRING));
739 csv_sequence.
append(qMakePair(
QString(
"RA"), KSParser::D_QSTRING));
740 csv_sequence.
append(qMakePair(
QString(
"DEC"), KSParser::D_QSTRING));
741 csv_sequence.
append(qMakePair(
QString(
"Position Angle (East)"), KSParser::D_DOUBLE));
742 csv_sequence.
append(qMakePair(
QString(
"Pane width (arcmins)"), KSParser::D_DOUBLE));
743 csv_sequence.
append(qMakePair(
QString(
"Pane height (arcmins)"), KSParser::D_DOUBLE));
744 csv_sequence.
append(qMakePair(
QString(
"Overlap"), KSParser::D_QSTRING));
745 csv_sequence.
append(qMakePair(
QString(
"Row"), KSParser::D_INT));
746 csv_sequence.
append(qMakePair(
QString(
"Column"), KSParser::D_INT));
747 KSParser csvParser(filename,
',', csv_sequence);
750 int maxRow = 1, maxCol = 1;
751 auto haveCenter =
false;
752 while (csvParser.HasNextRow())
754 row_content = csvParser.ReadNextRow();
755 auto pane = row_content[
"Pane"].toString();
761 if (pane !=
"Center")
763 auto row = row_content[
"Row"].toInt();
764 maxRow = qMax(row, maxRow);
765 auto col = row_content[
"Column"].toInt();
766 maxCol = qMax(col, maxCol);
772 auto ra = row_content[
"RA"].toString().trimmed();
773 auto dec = row_content[
"DEC"].toString().trimmed();
775 ui->raBox->setText(ra.replace(
"hr",
"h"));
776 ui->decBox->setText(
dec.remove(
"ยบ"));
778 auto pa = row_content[
"Position Angle (East)"].toDouble();
779 ui->positionAngleSpin->setValue(pa);
782 auto overlap = row_content[
"Overlap"].toString().trimmed().mid(0, 2).toDouble();
783 ui->overlapSpin->setValue(overlap);
786 if (haveCenter ==
false)
788 KSNotification::sorry(
i18n(
"Import must contain center coordinates."),
i18n(
"Sorry"), 15);
793 ui->mosaicWSpin->setValue(maxRow);
794 ui->mosaicHSpin->setValue(maxCol);
796 m_CenterPoint.setRA0(ui->raBox->createDms());
797 m_CenterPoint.setDec0(ui->decBox->createDms());
798 m_CenterPoint.updateCoordsNow(KStarsData::Instance()->updateNum());
800 SkyMap::Instance()->setDestination(m_CenterPoint);
801 SkyMap::Instance()->slewFocus();
803 ui->nextToAdjustGrid->click();
808bool FramingAssistantUI::importMosaic(
const QJsonObject &payload)
811 auto csv = payload[
"csv"].toString();
813 auto sequence = payload[
"sequence"].toString();
815 auto target = payload[
"target"].toString();
817 auto directory = payload[
"directory"].toString();
820 auto track = payload[
"track"].toBool();
821 auto focus = payload[
"focus"].toBool();
822 auto align = payload[
"align"].toBool();
823 auto guide = payload[
"guide"].toBool();
829 csvFile.
write(csv.toUtf8());
833 m_DebounceTimer->disconnect();
835 if (parseMosaicCSV(csvFile.
fileName()) ==
false)
840 m_JobsDirectory = directory;
843 ui->trackStepCheck->setChecked(track);
844 ui->focusStepCheck->setChecked(focus);
845 ui->alignStepCheck->setChecked(align);
846 ui->guideStepCheck->setChecked(guide);
848 ui->sequenceEdit->setText(sequence);
849 ui->targetEdit->setText(target);
854 if (ui->createJobsB->isEnabled() ==
false)
859 ui->createJobsB->click();
864void FramingAssistantUI::selectDirectory()
867 "Select Jobs Directory"),
870 if (!m_JobsDirectory.isEmpty())
873 QString sanitized = ui->targetEdit->text();
874 if (sanitized.
isEmpty() ==
false && sanitized !=
i18n(
"unnamed"))
877 sanitized = KSUtils::sanitize(sanitized);
878 ui->directoryEdit->setText(m_JobsDirectory +
QDir::separator() + sanitized);
882 ui->directoryEdit->setText(m_JobsDirectory);
885 ui->createJobsB->setEnabled(!ui->targetEdit->text().isEmpty() && !ui->sequenceEdit->text().isEmpty() &&
886 !ui->directoryEdit->text().isEmpty());
890void FramingAssistantUI::sanitizeTarget()
892 QString sanitized = ui->targetEdit->text();
893 if (sanitized !=
i18n(
"unnamed"))
896 sanitized = KSUtils::sanitize(sanitized);
897 ui->targetEdit->blockSignals(
true);
898 ui->targetEdit->setText(sanitized);
899 ui->targetEdit->blockSignals(
false);
901 if (m_JobsDirectory.isEmpty())
904 ui->directoryEdit->setText(m_JobsDirectory +
QDir::separator() + sanitized);
906 ui->createJobsB->setEnabled(!ui->targetEdit->text().isEmpty() && !ui->sequenceEdit->text().isEmpty() &&
907 !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)