Kstars

exporteyepieceview.cpp
1/*
2 SPDX-FileCopyrightText: 2016 Akarsh Simha <akarsh@kde.org>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#include "exporteyepieceview.h"
8
9#include "dms.h"
10#include "eyepiecefield.h"
11#include "kstarsdata.h"
12#include "Options.h"
13#include "skypoint.h"
14
15#include <QComboBox>
16#include <QDialogButtonBox>
17#include <QFileDialog>
18#include <QHBoxLayout>
19#include <QLabel>
20#include <QPainter>
21#include <QPixmap>
22#include <QVBoxLayout>
23#include <QWidget>
24
26 const QPixmap *renderChart, QWidget *parent)
27 : QDialog(parent), m_dt(dt)
28{
29#ifdef Q_OS_OSX
31#endif
32 m_sp.reset(new SkyPoint(*_sp)); // Work on a copy.
33
34 Q_ASSERT(renderChart);
35 m_renderChart.reset(new QPixmap(*renderChart));
36
37 if (renderImage != nullptr)
38 m_renderImage.reset(new QPixmap(*renderImage));
39
40 setWindowTitle(i18nc("@title:window", "Export eyepiece view"));
41
42 QWidget *mainWidget = new QWidget(this);
43 QVBoxLayout *mainLayout = new QVBoxLayout;
44 mainLayout->addWidget(mainWidget);
45 setLayout(mainLayout);
46
48 mainLayout->addWidget(buttonBox);
49 connect(buttonBox, SIGNAL(rejected()), this, SLOT(slotCloseDialog()));
50 connect(buttonBox, SIGNAL(accepted()), this, SLOT(slotSaveImage()));
51
52 QVBoxLayout *rows = new QVBoxLayout;
53 mainWidget->setLayout(rows);
54
55 QLabel *tickInfoLabel = new QLabel(i18n("Overlay orientation vs. time ticks: "), this);
56 m_tickConfigCombo = new QComboBox(this);
57 m_tickConfigCombo->addItem(i18n("None"));
58 m_tickConfigCombo->addItem(i18n("Towards Zenith"));
59 m_tickConfigCombo->addItem(i18n("Dobsonian View"));
60
61 QHBoxLayout *optionsLayout = new QHBoxLayout;
62 optionsLayout->addWidget(tickInfoLabel);
63 optionsLayout->addWidget(m_tickConfigCombo);
64 optionsLayout->addStretch();
65 rows->addLayout(optionsLayout);
66
67 m_tickWarningLabel = new QLabel(this);
68 rows->addWidget(m_tickWarningLabel);
69
70 m_outputDisplay = new QLabel;
71 m_outputDisplay->setBackgroundRole(QPalette::Base);
72 m_outputDisplay->setScaledContents(false);
73 m_outputDisplay->setMinimumWidth(400);
75 rows->addWidget(m_outputDisplay);
76
77 connect(m_tickConfigCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(slotOverlayTicks(int)));
78 connect(m_tickConfigCombo, SIGNAL(activated(int)), this, SLOT(slotOverlayTicks(int)));
79
80 render();
81 show();
82}
83
85{
86 m_tickConfig = tickConfig;
87 if (tickConfig == 0)
88 m_tickWarningLabel->setText(QString());
89 else if (tickConfig == 1)
90 m_tickWarningLabel->setText(i18n("Note: This overlay makes sense only if the view was generated in alt/az mode "
91 "with a preset such as Refractor or Vanilla"));
92 else if (tickConfig == 2)
93 m_tickWarningLabel->setText(i18n("Note: This overlay makes sense only if the view was generated in alt/az "
94 "mode with a preset such as Dobsonian"));
95 render();
96}
97
98void ExportEyepieceView::render()
99{
100 float baseWidth = m_renderChart->width();
101 float baseHeight = m_renderChart->height();
102
103 if (m_renderImage.get() != nullptr)
104 m_output = QImage(int(baseWidth * 2.25), int(baseHeight),
105 QImage::Format_ARGB32); // 0.25 * baseWidth gap between the images
106 else
107 m_output = QImage(int(baseWidth), int(baseHeight), QImage::Format_ARGB32);
108
109 m_output.fill(Qt::white);
110 QPainter op(&m_output);
111 op.drawPixmap(QPointF(0, 0), *m_renderChart);
112 if (m_renderImage.get() != nullptr)
113 op.drawPixmap(QPointF(baseWidth * 1.25, 0), *m_renderImage);
114
115 if (m_tickConfig != 0 && Options::useAltAz()) // FIXME: this is very skymap-state-heavy for my happiness --asimha
116 {
117 // we must draw ticks
118 QImage tickOverlay(baseWidth, baseHeight, QImage::Format_ARGB32);
119 tickOverlay.fill(Qt::transparent);
120
121 QPainter p(&tickOverlay);
122 p.setPen(Qt::red); // FIXME: Determine color depending on situation, or make it configurable
123 double rEnd = 0.85 * (baseWidth / 2.);
124 double rStart = 0.8 * (baseWidth / 2.);
125 QFont font;
126 font.setPixelSize((rEnd - rStart));
127 p.setFont(font);
128
129 GeoLocation *geo = KStarsData::Instance()->geo();
130 double alt0 = m_sp->alt().Degrees(); // altitude when hour = 0, i.e. at m_dt (see below).
131 dms northAngle0 = EyepieceField::findNorthAngle(m_sp.get(), geo->lat());
132
133 for (float hour = -3.5; hour <= 3.5; hour += 0.5)
134 {
135 dms rotation; // rotation
136
137 // FIXME: Code duplication : code duplicated from EyepieceField. This should really be a member of SkyPoint or something.
138 SkyPoint sp = SkyPoint::timeTransformed(m_sp.get(), m_dt, geo, hour);
139 double alt = sp.alt().Degrees();
140 dms northAngle = EyepieceField::findNorthAngle(&sp, geo->lat());
141
142 rotation = (northAngle - northAngle0);
143 if (m_tickConfig == 2)
144 {
145 // Dobsonian: add additional CW rotation by altitude, but compensate for the fact that we've already rotated by alt0
146 rotation = rotation - dms((alt - alt0));
147 }
148 rotation = rotation.reduce();
149 p.save();
150 p.translate(baseWidth / 2.0, baseHeight / 2.0);
151 p.rotate(-(rotation.Degrees() + 90.0));
152 p.drawLine(QPointF(rStart, 0), QPointF(rEnd, 0));
153 QTime ct = geo->UTtoLT(m_dt.addSecs(3600.0 * hour)).time();
154 p.drawText(QPointF(rEnd + 0.01 * baseWidth, 0), QString::asprintf("%02d:%02d", ct.hour(), ct.minute()));
155 p.restore();
156 }
157 p.end();
158 op.drawImage(QPointF(0, 0), tickOverlay);
159 if (m_renderImage.get() != nullptr)
160 {
161 op.drawImage(QPointF(baseWidth * 1.25, 0), tickOverlay);
162 }
163 }
164 op.end();
165
166 m_outputDisplay->setPixmap((QPixmap::fromImage(m_output))
167 .scaled(m_outputDisplay->width(), m_outputDisplay->height(), Qt::KeepAspectRatio,
169}
170
172{
173 // does nothing at the moment. TODO: Implement.
174 QString fileName = QFileDialog::getSaveFileName(this, i18nc("@title:window", "Save Image as"), QString(),
175 i18n("Image files (*.png *.jpg *.xpm *.bmp *.gif)"));
176 if (!fileName.isEmpty())
177 {
178 m_output.save(fileName);
180 }
181}
182
ExportEyepieceView(const SkyPoint *_sp, const KStarsDateTime &dt, const QPixmap *renderImage, const QPixmap *renderChart, QWidget *parent=nullptr)
Constructor.
void slotOverlayTicks(int overlayType)
Change the tick overlay scheme.
void slotSaveImage()
Save the image (export), and then close the dialog by calling slotCloseDialog()
void slotCloseDialog()
Closes the dialog, and sets up deleteLater() so that the dialog is destructed.
static dms findNorthAngle(const SkyPoint *sp, const dms *lat)
Finds the angle between "up" (i.e.
Contains all relevant information for specifying a location on Earth: City Name, State/Province name,...
Definition geolocation.h:28
GeoLocation * geo()
Definition kstarsdata.h:230
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
KStarsDateTime addSecs(double s) const
The sky coordinates of a point in the sky.
Definition skypoint.h:45
static SkyPoint timeTransformed(const SkyPoint *p, const KStarsDateTime &dt, const GeoLocation *geo, const double hour=0)
returns a time-transformed SkyPoint.
const dms & alt() const
Definition skypoint.h:281
An angle, stored as degrees, but expressible in many ways.
Definition dms.h:38
const dms reduce() const
return the equivalent angle between 0 and 360 degrees.
Definition dms.cpp:251
const double & Degrees() const
Definition dms.h:141
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
GeoCoordinates geo(const QVariant &location)
void addLayout(QLayout *layout, int stretch)
void addStretch(int stretch)
void addWidget(QWidget *widget, int stretch, Qt::Alignment alignment)
void addItem(const QIcon &icon, const QString &text, const QVariant &userData)
void accepted()
void rejected()
QString getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, Options options)
void setPixelSize(int pixelSize)
void fill(Qt::GlobalColor color)
bool save(QIODevice *device, const char *format, int quality) const const
void setPixmap(const QPixmap &)
void setScaledContents(bool)
void setText(const QString &)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void deleteLater()
QPixmap fromImage(QImage &&image, Qt::ImageConversionFlags flags)
QString asprintf(const char *cformat,...)
bool isEmpty() const const
KeepAspectRatio
SmoothTransformation
int hour() const const
int minute() const const
QWidget(QWidget *parent, Qt::WindowFlags f)
void hide()
void setMinimumWidth(int minw)
void setBackgroundRole(QPalette::ColorRole role)
void setLayout(QLayout *layout)
void show()
void setSizePolicy(QSizePolicy)
void setWindowFlags(Qt::WindowFlags type)
void setWindowTitle(const QString &)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Jul 19 2024 11:51:35 by doxygen 1.11.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.