Kstars

framingassistant.cpp
1/*
2 SPDX-FileCopyrightText: 2022 Jasem Mutlaq <mutlaqja@ikarustech.com>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#include "framingassistant.h"
8#include "ui_framingassistant.h"
9#include "mosaictilesmanager.h"
10#include "kstars.h"
11#include "Options.h"
12#include "scheduler.h"
13#include "skymap.h"
14#include "ekos/manager.h"
15#include "projections/projector.h"
16
17#include "ekos_scheduler_debug.h"
18
19namespace Ekos
20{
21
22FramingAssistant* FramingAssistant::Instance()
23{
24 if (_FramingAssistant == nullptr)
25 {
26 _FramingAssistant = new FramingAssistant;
27 }
28
29 return _FramingAssistant;
30}
31
32FramingAssistant::FramingAssistant(): QDialog(KStars::Instance()), ui(new Ui::FramingAssistant())
33{
34 ui->setupUi(this);
35
36 // Initial optics information is taken from Ekos options
37 ui->focalLenSpin->setValue(Options::telescopeFocalLength());
38 ui->pixelWSizeSpin->setValue(Options::cameraPixelWidth());
39 ui->pixelHSizeSpin->setValue(Options::cameraPixelHeight());
40 ui->cameraWSpin->setValue(Options::cameraWidth());
41 ui->cameraHSpin->setValue(Options::cameraHeight());
42 ui->rotationSpin->setValue(Options::cameraRotation());
43
44 // Initial job location is the home path appended with the target name
45 //ui->jobsDir->setText(QDir::cleanPath(QDir::homePath() + QDir::separator() + targetName.replace(' ', '_')));
46 //ui->selectJobsDirB->setIcon(QIcon::fromTheme("document-open-folder"));
47
48 // The update timer avoids stacking updates which crash the sky map renderer
49 updateTimer = new QTimer(this);
50 updateTimer->setSingleShot(true);
51 updateTimer->setInterval(1000);
52 connect(updateTimer, &QTimer::timeout, this, &Ekos::FramingAssistant::constructMosaic);
53
54 // Scope optics information
55 // - Changing the optics configuration changes the FOV, which changes the target field dimensions
56 connect(ui->focalLenSpin, &QDoubleSpinBox::editingFinished, this, &Ekos::FramingAssistant::calculateFOV);
57 connect(ui->cameraWSpin, &QSpinBox::editingFinished, this, &Ekos::FramingAssistant::calculateFOV);
58 connect(ui->cameraHSpin, &QSpinBox::editingFinished, this, &Ekos::FramingAssistant::calculateFOV);
59 connect(ui->pixelWSizeSpin, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this,
60 &Ekos::FramingAssistant::calculateFOV);
61 connect(ui->pixelHSizeSpin, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this,
62 &Ekos::FramingAssistant::calculateFOV);
63 connect(ui->rotationSpin, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this,
64 &Ekos::FramingAssistant::calculateFOV);
65
66 // Mosaic configuration
67 // - Changing the target field dimensions changes the grid dimensions
68 // - Changing the overlap field changes the grid dimensions (more intuitive than changing the field)
69 // - Changing the grid dimensions changes the target field dimensions
70 connect(ui->targetHFOVSpin, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this,
71 &Ekos::FramingAssistant::updateGridFromTargetFOV);
72 connect(ui->targetWFOVSpin, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this,
73 &Ekos::FramingAssistant::updateGridFromTargetFOV);
74 connect(ui->overlapSpin, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this,
75 &Ekos::FramingAssistant::updateGridFromTargetFOV);
76 connect(ui->mosaicWSpin, QOverload<int>::of(&QSpinBox::valueChanged), this,
77 &Ekos::FramingAssistant::updateTargetFOVFromGrid);
78 connect(ui->mosaicHSpin, QOverload<int>::of(&QSpinBox::valueChanged), this,
79 &Ekos::FramingAssistant::updateTargetFOVFromGrid);
80
81 // Lazy update for s-shape
82 connect(ui->reverseOddRows, &QCheckBox::toggled, this, [&]()
83 {
84 renderedHFOV = 0;
85 updateTimer->start();
86 });
87
88 // Buttons
89 connect(ui->resetB, &QPushButton::clicked, this, &Ekos::FramingAssistant::updateTargetFOVFromGrid);
90 connect(ui->selectJobsDirB, &QPushButton::clicked, this, &Ekos::FramingAssistant::saveJobsDirectory);
91 connect(ui->fetchB, &QPushButton::clicked, this, &FramingAssistant::fetchINDIInformation);
92
93 // The sky map is a pixmap background, and the mosaic tiles are rendered over it
94 //m_TilesScene = new MosaicTilesScene(this);
95 m_SkyPixmapItem = m_TilesScene.addPixmap(targetPix);
96 m_SkyPixmapItem->setTransformationMode(Qt::TransformationMode::SmoothTransformation);
97 m_MosaicTilesManager = new MosaicTilesManager(this);
98 connect(m_MosaicTilesManager, &MosaicTilesManager::newOffset, this, [this](const QPointF & offset)
99 {
100 // Find out new center
101 QPointF cartesianCenter = SkyMap::Instance()->projector()->toScreen(&m_CenterPoint);
102 QPointF destinationCenter = cartesianCenter + offset;
103 SkyPoint newCenter = SkyMap::Instance()->projector()->fromScreen(destinationCenter,
104 KStarsData::Instance()->lst(),
105 KStarsData::Instance()->geo()->lat());
106 SkyPoint J2000Center = newCenter.catalogueCoord(KStars::Instance()->data()->ut().djd());
107 setCenter(J2000Center);
108 updateTimer->start();
109 });
110 m_TilesScene.addItem(m_MosaicTilesManager);
111 //ui->mosaicView->setScene(&m_TilesScene);
112
113 // Always use Equatorial Mode in Mosaic mode
114 m_RememberAltAzOption = Options::useAltAz();
115 Options::setUseAltAz(false);
116 m_RememberShowGround = Options::showGround();
117 Options::setShowGround(false);
118
119 // Rendering options
120 // connect(ui->transparencySlider, QOverload<int>::of(&QSlider::valueChanged), this, [&](int v)
121 // {
122 // ui->transparencySlider->setToolTip(QString("%1%").arg(v));
123 // m_MosaicTilesManager->setPainterAlpha(v);
124 // updateTimer->start();
125 // });
126 // connect(ui->transparencyAuto, &QCheckBox::toggled, this, [&](bool v)
127 // {
128 // ui->transparencySlider->setEnabled(!v);
129 // if (v)
130 // updateTimer->start();
131 // });
132
133 // Job options
134 connect(ui->alignEvery, QOverload<int>::of(&QSpinBox::valueChanged), this, &Ekos::FramingAssistant::rewordStepEvery);
135 connect(ui->focusEvery, QOverload<int>::of(&QSpinBox::valueChanged), this, &Ekos::FramingAssistant::rewordStepEvery);
136 emit ui->alignEvery->valueChanged(0);
137 emit ui->focusEvery->valueChanged(0);
138
139 // Center, fetch optics and adjust size
140 //setCenter(center);
141 fetchINDIInformation();
142 adjustSize();
143}
144
145FramingAssistant::~FramingAssistant()
146{
147 delete updateTimer;
148 Options::setUseAltAz(m_RememberAltAzOption);
149 Options::setShowGround(m_RememberShowGround);
150}
151
152QString FramingAssistant::getJobsDir() const
153{
154 return ui->jobsDir->text();
155}
156
157bool FramingAssistant::isScopeInfoValid() const
158{
159 if (0 < ui->focalLenSpin->value())
160 if (0 < ui->cameraWSpin->value() && 0 < ui->cameraWSpin->value())
161 if (0 < ui->pixelWSizeSpin->value() && 0 < ui->pixelHSizeSpin->value())
162 return true;
163 return false;
164}
165
166double FramingAssistant::getTargetWFOV() const
167{
168 double const xFOV = ui->cameraWFOVSpin->value() * (1 - ui->overlapSpin->value() / 100.0);
169 return ui->cameraWFOVSpin->value() + xFOV * (ui->mosaicWSpin->value() - 1);
170}
171
172double FramingAssistant::getTargetHFOV() const
173{
174 double const yFOV = ui->cameraHFOVSpin->value() * (1 - ui->overlapSpin->value() / 100.0);
175 return ui->cameraHFOVSpin->value() + yFOV * (ui->mosaicHSpin->value() - 1);
176}
177
178double FramingAssistant::getTargetMosaicW() const
179{
180 // If FOV is invalid, or target FOV is null, or target FOV is smaller than camera FOV, we get one tile
181 if (!isScopeInfoValid() || !ui->targetWFOVSpin->value() || ui->targetWFOVSpin->value() <= ui->cameraWFOVSpin->value())
182 return 1;
183
184 // Else we get one tile, plus as many overlapping camera FOVs in the remnant of the target FOV
185 double const xFOV = ui->cameraWFOVSpin->value() * (1 - ui->overlapSpin->value() / 100.0);
186 int const tiles = 1 + ceil((ui->targetWFOVSpin->value() - ui->cameraWFOVSpin->value()) / xFOV);
187 //Ekos::Manager::Instance()->schedulerModule()->appendLogText(QString("[W] Target FOV %1, camera FOV %2 after overlap %3, %4 tiles.").arg(ui->targetWFOVSpin->value()).arg(ui->cameraWFOVSpin->value()).arg(xFOV).arg(tiles));
188 return tiles;
189}
190
191double FramingAssistant::getTargetMosaicH() const
192{
193 // If FOV is invalid, or target FOV is null, or target FOV is smaller than camera FOV, we get one tile
194 if (!isScopeInfoValid() || !ui->targetHFOVSpin->value() || ui->targetHFOVSpin->value() <= ui->cameraHFOVSpin->value())
195 return 1;
196
197 // Else we get one tile, plus as many overlapping camera FOVs in the remnant of the target FOV
198 double const yFOV = ui->cameraHFOVSpin->value() * (1 - ui->overlapSpin->value() / 100.0);
199 int const tiles = 1 + ceil((ui->targetHFOVSpin->value() - ui->cameraHFOVSpin->value()) / yFOV);
200 //Ekos::Manager::Instance()->schedulerModule()->appendLogText(QString("[H] Target FOV %1, camera FOV %2 after overlap %3, %4 tiles.").arg(ui->targetHFOVSpin->value()).arg(ui->cameraHFOVSpin->value()).arg(yFOV).arg(tiles));
201 return tiles;
202}
203
204//int FramingAssistant::exec()
205//{
206// premosaicZoomFactor = Options::zoomFactor();
207
208// int const result = QDialog::exec();
209
210// // Revert various options
211// updateTimer->stop();
212// SkyMap *map = SkyMap::Instance();
213// if (map && 0 < premosaicZoomFactor)
214// map->setZoomFactor(premosaicZoomFactor);
215
216// return result;
217//}
218
219void FramingAssistant::saveJobsDirectory()
220{
221 QString dir = QFileDialog::getExistingDirectory(KStars::Instance(), i18nc("@title:window", "FITS Save Directory"),
222 ui->jobsDir->text());
223
224 if (!dir.isEmpty())
225 ui->jobsDir->setText(dir);
226}
227
228void FramingAssistant::setCenter(const SkyPoint &value)
229{
230 m_CenterPoint = value;
231 m_CenterPoint.apparentCoord(static_cast<long double>(J2000), KStars::Instance()->data()->ut().djd());
232}
233
234void FramingAssistant::calculateFOV()
235{
236 if (!isScopeInfoValid())
237 return;
238
239 ui->fovGroup->setEnabled(true);
240
241 ui->targetWFOVSpin->setMinimum(ui->cameraWFOVSpin->value());
242 ui->targetHFOVSpin->setMinimum(ui->cameraHFOVSpin->value());
243
244 Options::setTelescopeFocalLength(ui->focalLenSpin->value());
245 Options::setCameraPixelWidth(ui->pixelWSizeSpin->value());
246 Options::setCameraPixelHeight(ui->pixelHSizeSpin->value());
247 Options::setCameraWidth(ui->cameraWSpin->value());
248 Options::setCameraHeight(ui->cameraHSpin->value());
249
250 // Calculate FOV in arcmins
251 double const fov_x =
252 206264.8062470963552 * ui->cameraWSpin->value() * ui->pixelWSizeSpin->value() / 60000.0 / ui->focalLenSpin->value();
253 double const fov_y =
254 206264.8062470963552 * ui->cameraHSpin->value() * ui->pixelHSizeSpin->value() / 60000.0 / ui->focalLenSpin->value();
255
256 ui->cameraWFOVSpin->setValue(fov_x);
257 ui->cameraHFOVSpin->setValue(fov_y);
258
259 double const target_fov_w = getTargetWFOV();
260 double const target_fov_h = getTargetHFOV();
261
262 if (ui->targetWFOVSpin->value() < target_fov_w)
263 {
264 bool const sig = ui->targetWFOVSpin->blockSignals(true);
265 ui->targetWFOVSpin->setValue(target_fov_w);
266 ui->targetWFOVSpin->blockSignals(sig);
267 }
268
269 if (ui->targetHFOVSpin->value() < target_fov_h)
270 {
271 bool const sig = ui->targetHFOVSpin->blockSignals(true);
272 ui->targetHFOVSpin->setValue(target_fov_h);
273 ui->targetHFOVSpin->blockSignals(sig);
274 }
275
276 updateTimer->start();
277}
278
279void FramingAssistant::updateTargetFOV()
280{
281 KStars *ks = KStars::Instance();
282 SkyMap *map = SkyMap::Instance();
283
284 // Render the required FOV
285 renderedWFOV = ui->targetWFOVSpin->value();// * cos(ui->rotationSpin->value() * dms::DegToRad);
286 renderedHFOV = ui->targetHFOVSpin->value();// * sin(ui->rotationSpin->value() * dms::DegToRad);
287
288 // Pick thrice the largest FOV to obtain a proper zoom
289 double const spacing = ui->mosaicWSpin->value() < ui->mosaicHSpin->value() ? ui->mosaicHSpin->value() :
290 ui->mosaicWSpin->value();
291 double const scale = 1.0 + 2.0 / (1.0 + spacing);
292 double const renderedFOV = scale * (renderedWFOV < renderedHFOV ? renderedHFOV : renderedWFOV);
293
294 // Check the aspect ratio of the sky map, assuming the map zoom considers the width (see KStars::setApproxFOV)
295 double const aspect_ratio = map->width() / map->height();
296
297 // Set the zoom (in degrees) that gives the expected FOV for the map aspect ratio, and center the target
298 ks->setApproxFOV(renderedFOV * aspect_ratio / 60.0);
299 //center.EquatorialToHorizontal(KStarsData::Instance()->lst(), KStarsData::Instance()->geo()->lat());
300 map->setClickedObject(nullptr);
301 map->setClickedPoint(&m_CenterPoint);
302 map->slotCenter();
303
304 // Wait for the map to stop slewing, so that HiPS renders properly
305 while(map->isSlewing())
306 qApp->processEvents();
307 qApp->processEvents();
308
309 // Compute the horizontal and vertical resolutions, deduce the actual FOV of the map in arcminutes
310 pixelsPerArcminRA = pixelsPerArcminDE = Options::zoomFactor() * dms::DegToRad / 60.0;
311
312 // Get the sky map image - don't bother subframing, it causes imprecision sometimes
313 QImage fullSkyChart(QSize(map->width(), map->height()), QImage::Format_RGB32);
314 map->exportSkyImage(&fullSkyChart, false);
315 qApp->processEvents();
316 m_SkyPixmapItem->setPixmap(QPixmap::fromImage(fullSkyChart));
317
318 // Relocate
319 QRectF sceneRect = m_SkyPixmapItem->boundingRect().translated(-m_SkyPixmapItem->boundingRect().center());
320 m_TilesScene.setSceneRect(sceneRect);
321 m_SkyPixmapItem->setOffset(sceneRect.topLeft());
322 m_SkyPixmapItem->setPos(QPointF());
323
324}
325
326void FramingAssistant::resizeEvent(QResizeEvent *)
327{
328 // Adjust scene rect to avoid rounding holes on border
329 QRectF adjustedSceneRect(m_TilesScene.sceneRect());
330 adjustedSceneRect.setTop(adjustedSceneRect.top() + 2);
331 adjustedSceneRect.setLeft(adjustedSceneRect.left() + 2);
332 adjustedSceneRect.setRight(adjustedSceneRect.right() - 2);
333 adjustedSceneRect.setBottom(adjustedSceneRect.bottom() - 2);
334
335 // ui->mosaicView->fitInView(adjustedSceneRect, Qt::KeepAspectRatioByExpanding);
336 // ui->mosaicView->centerOn(QPointF());
337}
338
339void FramingAssistant::showEvent(QShowEvent *)
340{
341 resizeEvent(nullptr);
342}
343
344void FramingAssistant::resetFOV()
345{
346 if (!isScopeInfoValid())
347 return;
348
349 ui->targetWFOVSpin->setValue(getTargetWFOV());
350 ui->targetHFOVSpin->setValue(getTargetHFOV());
351}
352
353void FramingAssistant::updateTargetFOVFromGrid()
354{
355 if (!isScopeInfoValid())
356 return;
357
358 double const targetWFOV = getTargetWFOV();
359 double const targetHFOV = getTargetHFOV();
360
361 if (ui->targetWFOVSpin->value() != targetWFOV)
362 {
363 bool const sig = ui->targetWFOVSpin->blockSignals(true);
364 ui->targetWFOVSpin->setValue(targetWFOV);
365 ui->targetWFOVSpin->blockSignals(sig);
366 updateTimer->start();
367 }
368
369 if (ui->targetHFOVSpin->value() != targetHFOV)
370 {
371 bool const sig = ui->targetHFOVSpin->blockSignals(true);
372 ui->targetHFOVSpin->setValue(targetHFOV);
373 ui->targetHFOVSpin->blockSignals(sig);
374 updateTimer->start();
375 }
376}
377
378void FramingAssistant::updateGridFromTargetFOV()
379{
380 if (!isScopeInfoValid())
381 return;
382
383 double const expectedW = getTargetMosaicW();
384 double const expectedH = getTargetMosaicH();
385
386 if (expectedW != ui->mosaicWSpin->value())
387 {
388 bool const sig = ui->mosaicWSpin->blockSignals(true);
389 ui->mosaicWSpin->setValue(expectedW);
390 ui->mosaicWSpin->blockSignals(sig);
391 }
392
393 if (expectedH != ui->mosaicHSpin->value())
394 {
395 bool const sig = ui->mosaicHSpin->blockSignals(true);
396 ui->mosaicHSpin->setValue(expectedH);
397 ui->mosaicHSpin->blockSignals(sig);
398 }
399
400 // Update unconditionally, as we may be updating the overlap or the target FOV covered by the mosaic
401 updateTimer->start();
402}
403
404void FramingAssistant::constructMosaic()
405{
406 updateTimer->stop();
407
408 if (!isScopeInfoValid())
409 return;
410
411 updateTargetFOV();
412
413 if (m_MosaicTilesManager->getPA() != ui->rotationSpin->value())
414 Options::setCameraRotation(ui->rotationSpin->value());
415
416 qCDebug(KSTARS_EKOS_SCHEDULER) << "Tile FOV in pixels W:" << ui->cameraWFOVSpin->value() * pixelsPerArcminRA << "H:"
417 << ui->cameraHFOVSpin->value() * pixelsPerArcminDE;
418
419 m_MosaicTilesManager->setPos(0, 0);
420 m_MosaicTilesManager->setSkyCenter(m_CenterPoint);
421 m_MosaicTilesManager->setGridDimensions(ui->mosaicWSpin->value(), ui->mosaicHSpin->value());
422 m_MosaicTilesManager->setPositionAngle(ui->rotationSpin->value());
423 m_MosaicTilesManager->setSingleTileFOV(ui->cameraWFOVSpin->value() * pixelsPerArcminRA,
424 ui->cameraHFOVSpin->value() * pixelsPerArcminDE);
425 m_MosaicTilesManager->setMosaicFOV(ui->targetWFOVSpin->value() * pixelsPerArcminRA,
426 ui->targetHFOVSpin->value() * pixelsPerArcminDE);
427 m_MosaicTilesManager->setOverlap(ui->overlapSpin->value() / 100);
428 m_MosaicTilesManager->setPixelScale(QSizeF(pixelsPerArcminRA * 60.0, pixelsPerArcminDE * 60.0));
429 m_MosaicTilesManager->updateTiles(m_MosaicTilesManager->mapToItem(m_SkyPixmapItem,
430 m_SkyPixmapItem->boundingRect().center()),
431 ui->reverseOddRows->checkState() == Qt::CheckState::Checked);
432
433 // ui->jobCountSpin->setValue(m_MosaicTilesManager->getWidth() * m_MosaicTilesManager->getHeight());
434
435 // if (ui->transparencyAuto->isChecked())
436 // {
437 // // Tiles should be more transparent when many are overlapped
438 // // Overlap < 50%: low transparency, as only two tiles will overlap on a line
439 // // 50% < Overlap < 75%: mid transparency, as three tiles will overlap one a line
440 // // 75% < Overlap: high transparency, as four tiles will overlap on a line
441 // // Slider controlling transparency provides [5%,50%], which is scaled to 0-200 alpha.
442
443 // if (1 < ui->jobCountSpin->value())
444 // ui->transparencySlider->setValue(40 - ui->overlapSpin->value() / 2);
445 // else
446 // ui->transparencySlider->setValue(40);
447
448 // ui->transparencySlider->update();
449 // }
450
451 resizeEvent(nullptr);
452 m_MosaicTilesManager->show();
453
454 //ui->mosaicView->update();
455}
456
457QList <FramingAssistant::Job> FramingAssistant::getJobs() const
458{
459 qCDebug(KSTARS_EKOS_SCHEDULER) << "Mosaic Tile W:" << m_MosaicTilesManager->boundingRect().width() << "H:" <<
460 m_MosaicTilesManager->boundingRect().height();
461
462 QList <FramingAssistant::Job> result;
463
464 // We have two items:
465 // 1. SkyMapItem is the pixmap we fetch from KStars that shows the sky field.
466 // 2. MosaicItem is the constructed mosaic boxes.
467 // We already know the center (RA0,DE0) of the SkyMapItem.
468 // We Map the coordinate of each tile to the SkyMapItem to find out where the tile center is located
469 // on the SkyMapItem pixmap.
470 // We calculate the difference between the tile center and the SkyMapItem center and then find the tile coordinates
471 // in J2000 coords.
472 for (int i = 0; i < m_MosaicTilesManager->getHeight(); i++)
473 {
474 for (int j = 0; j < m_MosaicTilesManager->getWidth(); j++)
475 {
476 MosaicTilesManager::OneTile * const tile = m_MosaicTilesManager->getTile(i, j);
477 qCDebug(KSTARS_EKOS_SCHEDULER) << "Tile #" << i * m_MosaicTilesManager->getWidth() + j << "Center:" << tile->center;
478
479 Job ts;
480 ts.center.setRA0(tile->skyCenter.ra0().Hours());
481 ts.center.setDec0(tile->skyCenter.dec0().Degrees());
482 ts.rotation = -m_MosaicTilesManager->getPA();
483
484 ts.doAlign =
485 (0 < ui->alignEvery->value()) &&
486 (0 == ((j + i * m_MosaicTilesManager->getHeight()) % ui->alignEvery->value()));
487
488 ts.doFocus =
489 (0 < ui->focusEvery->value()) &&
490 (0 == ((j + i * m_MosaicTilesManager->getHeight()) % ui->focusEvery->value()));
491
492 qCDebug(KSTARS_EKOS_SCHEDULER) << "Tile RA0:" << tile->skyCenter.ra0().toHMSString() << "DE0:" <<
493 tile->skyCenter.dec0().toDMSString();
494 result.append(ts);
495 }
496 }
497
498 return result;
499}
500
501void FramingAssistant::fetchINDIInformation()
502{
503 QDBusInterface alignInterface("org.kde.kstars",
504 "/KStars/Ekos/Align",
505 "org.kde.kstars.Ekos.Align",
507
508 QDBusReply<QList<double>> cameraReply = alignInterface.call("cameraInfo");
509 if (cameraReply.isValid())
510 {
511 QList<double> const values = cameraReply.value();
512
513 m_CameraSize = QSize(values[0], values[1]);
514 m_PixelSize = QSizeF(values[2], values[3]);
515 }
516
517 QDBusReply<QList<double>> telescopeReply = alignInterface.call("telescopeInfo");
518 if (telescopeReply.isValid())
519 {
520 QList<double> const values = telescopeReply.value();
521 m_FocalLength = values[0];
522 }
523
524 QDBusReply<QList<double>> solutionReply = alignInterface.call("getSolutionResult");
525 if (solutionReply.isValid())
526 {
527 QList<double> const values = solutionReply.value();
528 if (values[0] > INVALID_VALUE)
529 m_Rotation = values[0];
530 }
531
532 calculateFOV();
533}
534
535void FramingAssistant::rewordStepEvery(int v)
536{
537 QSpinBox * sp = dynamic_cast<QSpinBox *>(sender());
538 if (0 < v)
539 sp->setSuffix(i18np(" Scheduler job", " Scheduler jobs", v));
540 else
541 sp->setSuffix(i18n(" (first only)"));
542}
543
544}
This is the main window for KStars.
Definition kstars.h:89
static KStars * Instance()
Definition kstars.h:121
Q_SCRIPTABLE Q_NOREPLY void setApproxFOV(double FOV_Degrees)
DBUS interface function.
virtual SkyPoint fromScreen(const QPointF &p, dms *LST, const dms *lat, bool onlyAltAz=false) const
Determine RA, Dec coordinates of the pixel at (dx, dy), which are the screen pixel coordinate offsets...
QPointF toScreen(const SkyPoint *o, bool oRefract=true, bool *onVisibleHemisphere=nullptr) const
This is exactly the same as toScreenVec but it returns a QPointF.
Definition projector.cpp:93
This is the canvas on which the sky is painted.
Definition skymap.h:54
const Projector * projector() const
Get the current projector.
Definition skymap.h:300
The sky coordinates of a point in the sky.
Definition skypoint.h:45
void apparentCoord(long double jd0, long double jdf)
Computes the apparent coordinates for this SkyPoint for any epoch, accounting for the effects of prec...
Definition skypoint.cpp:700
SkyPoint catalogueCoord(long double jdf)
Computes the J2000.0 catalogue coordinates for this SkyPoint using the epoch removing aberration,...
Definition skypoint.cpp:710
static constexpr double DegToRad
DegToRad is a const static member equal to the number of radians in one degree (dms::PI/180....
Definition dms.h:390
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.
Definition align.cpp:83
GeoCoordinates geo(const QVariant &location)
KIOCORE_EXPORT QString dir(const QString &fileClass)
void clicked(bool checked)
void toggled(bool checked)
void editingFinished()
QDBusConnection sessionBus()
bool isValid() const const
void valueChanged(double d)
QString getExistingDirectory(QWidget *parent, const QString &caption, const QString &dir, Options options)
void append(QList< T > &&value)
QPixmap fromImage(QImage &&image, Qt::ImageConversionFlags flags)
QPointF topLeft() const const
QRectF translated(const QPointF &offset) const const
void setSuffix(const QString &suffix)
void valueChanged(int i)
bool isEmpty() const const
QFuture< void > map(Iterator begin, Iterator end, MapFunctor &&function)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
void timeout()
void setupUi(QWidget *widget)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:16:41 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.