Kstars

framingassistant.cpp
1 /*
2  SPDX-FileCopyrightText: 2022 Jasem Mutlaq <[email protected]>
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 
19 namespace Ekos
20 {
21 
22 FramingAssistant* FramingAssistant::Instance()
23 {
24  if (_FramingAssistant == nullptr)
25  {
26  _FramingAssistant = new FramingAssistant;
27  }
28 
29  return _FramingAssistant;
30 }
31 
32 FramingAssistant::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 
145 FramingAssistant::~FramingAssistant()
146 {
147  delete updateTimer;
148  Options::setUseAltAz(m_RememberAltAzOption);
149  Options::setShowGround(m_RememberShowGround);
150 }
151 
152 QString FramingAssistant::getJobsDir() const
153 {
154  return ui->jobsDir->text();
155 }
156 
157 bool 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 
166 double 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 
172 double 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 
178 double 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 
191 double 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 
219 void 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 
228 void 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 
234 void 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 
279 void 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 
326 void 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 
339 void FramingAssistant::showEvent(QShowEvent *)
340 {
341  resizeEvent(nullptr);
342 }
343 
344 void FramingAssistant::resetFOV()
345 {
346  if (!isScopeInfoValid())
347  return;
348 
349  ui->targetWFOVSpin->setValue(getTargetWFOV());
350  ui->targetHFOVSpin->setValue(getTargetHFOV());
351 }
352 
353 void 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 
378 void 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 
404 void 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 
457 QList <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 
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 
501 void 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 
535 void 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 }
void append(const T &value)
QPixmap fromImage(const QImage &image, Qt::ImageConversionFlags flags)
void setSuffix(const QString &suffix)
Ekos is an advanced Astrophotography tool for Linux. It is based on a modular extensible framework to...
Definition: align.cpp:70
Stores dms coordinates for a point in the sky. for converting between coordinate systems.
Definition: skypoint.h:44
bool isValid() const const
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:385
void clicked(bool checked)
void valueChanged(double d)
void toggled(bool checked)
static KStars * Instance()
Definition: kstars.h:125
QRectF translated(qreal dx, qreal dy) const const
QString i18n(const char *text, const TYPE &arg...)
QDBusConnection sessionBus()
QPointF topLeft() const const
void timeout()
bool isEmpty() const const
GeoCoordinates geo(const QVariant &location)
This is the main window for KStars. In addition to the GUI elements, the class contains the program c...
Definition: kstars.h:92
void setupUi(QWidget *widget)
QString i18np(const char *singular, const char *plural, const TYPE &arg...)
KIOFILEWIDGETS_EXPORT QString dir(const QString &fileClass)
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...
Definition: projector.cpp:406
void editingFinished()
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
Canvas widget for displaying the sky bitmap; also handles user interaction events.
Definition: skymap.h:52
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
QString i18nc(const char *context, const char *text, const TYPE &arg...)
Q_SCRIPTABLE Q_NOREPLY void setApproxFOV(double FOV_Degrees)
DBUS interface function.
Definition: kstarsdbus.cpp:969
const Projector * projector() const
Get the current projector.
Definition: skymap.h:299
void valueChanged(int i)
QFuture< void > map(Sequence &sequence, MapFunctor function)
QString getExistingDirectory(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options)
QVector< V > values(const QMultiHash< K, V > &c)
QDBusReply::Type value() const const
SkyPoint catalogueCoord(long double jdf)
Computes the J2000.0 catalogue coordinates for this SkyPoint using the epoch removing aberration,...
Definition: skypoint.cpp:710
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Fri Aug 12 2022 04:00:54 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.