Kstars

profilewizard.cpp
1 /*
2  SPDX-FileCopyrightText: 2017 Jasem Mutlaq <[email protected]>
3 
4  SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #include "profilewizard.h"
8 
9 #include <QDesktopServices>
10 #include <QUrl>
11 #include <QTcpSocket>
12 #include <QTimer>
13 
14 #include "kstars.h"
15 #include "auxiliary/kspaths.h"
16 #include "ksnotification.h"
17 #include "qMDNS.h"
18 
19 ProfileWizard::ProfileWizard() : QDialog(KStars::Instance())
20 {
21  setupUi(this);
22 
23 #ifdef Q_OS_OSX
25 #endif
26 
27  QPixmap im;
28  if (im.load(KSPaths::locate(QStandardPaths::AppLocalDataLocation, "wzekos.png")))
29  wizardPix->setPixmap(im);
30 
31  remoteEquipmentSVG->load(QString(":/icons/pi.svg"));
32 
33  connect(buttonBox, SIGNAL(rejected()), this, SLOT(close()));
34  connect(buttonBox, &QDialogButtonBox::helpRequested, this, []()
35  {
37  });
38  connect(buttonBox, &QDialogButtonBox::clicked, this, [this](QAbstractButton * button)
39  {
40  if (button == buttonBox->button(QDialogButtonBox::Reset))
41  reset();
42  });
43 
44  connect(discoverEkosB, &QPushButton::clicked, this,
45  []()
46  {
47  QDesktopServices::openUrl(QUrl("https://www.indilib.org/about/ekos.html"));
48  });
49  connect(videoTutorialsB, &QPushButton::clicked, this,
50  []()
51  {
52  QDesktopServices::openUrl(QUrl("https://www.youtube.com/user/QAstronomy"));
53  });
54  connect(INDIInfoB, &QPushButton::clicked, this,
55  []()
56  {
57  QDesktopServices::openUrl(QUrl("https://indilib.org/about/discover-indi.html"));
58  });
59 
60  // Intro actions
61  connect(introNextB, &QPushButton::clicked, this,
62  [this]()
63  {
64  wizardContainer->setCurrentIndex(EQUIPMENT_LOCATION);
65  });
66 
67  // Equipment Location actions
68  connect(localEquipmentB, SIGNAL(clicked()), this, SLOT(processLocalEquipment()));
69  connect(remoteEquipmentB, &QPushButton::clicked, this,
70  [this]()
71  {
72  wizardContainer->setCurrentIndex(REMOTE_EQUIPMENT_SELECTION);
73  });
74  equipmentStellarmateB->setIcon(QIcon(":/icons/stellarmate.svg"));
75  connect(equipmentStellarmateB, &QPushButton::clicked, this, &ProfileWizard::processRemoteEquipmentSelection);
76 
77  equipmentAtikbaseB->setIcon(QIcon(":/icons/atikbase.svg"));
78  connect(equipmentAtikbaseB, &QPushButton::clicked, this, &ProfileWizard::processRemoteEquipmentSelection);
79 
80  connect(equipmentOtherB, &QPushButton::clicked, this, &ProfileWizard::processRemoteEquipmentSelection);
81 
82  // Remote Equipment Action
83  connect(remoteEquipmentNextB, SIGNAL(clicked()), this, SLOT(processRemoteEquipment()));
84 
85  // StellarMate Equipment Action
86  connect(stellarMateEquipmentNextB, SIGNAL(clicked()), this, SLOT(processPiEquipment()));
87 #ifdef Q_OS_WIN
88  // Auto Detect does not work on Windows yet for some reason.
89  // Packet is sent correctly, but no replies are received from anything on the LAN outside of PC.
90  PiAutoDetectB->setEnabled(false);
91 #else
92  connect(PiAutoDetectB, SIGNAL(clicked()), this, SLOT(detectStellarMate()));
93 #endif
94 
95  // Local Mac
96  connect(useExternalINDIB, SIGNAL(clicked()), this, SLOT(processLocalMac()));
97  connect(useInternalINDIB, SIGNAL(clicked()), this, SLOT(processLocalMac()));
98 
99  // Create Profile
100  connect(createProfileB, SIGNAL(clicked()), this, SLOT(createProfile()));
101 }
102 
103 void ProfileWizard::reset()
104 {
105  useInternalServer = true;
106  useWebManager = false;
107  useJoystick = false;
108  useRemoteAstrometry = false;
109  useSkySafari = false;
110  useWatchDog = false;
111  useGuiderType = INTERNAL_GUIDER;
112 
113  host.clear();
114  port = "7624";
115 
116  wizardContainer->setCurrentIndex(INTRO);
117 }
118 
119 void ProfileWizard::processLocalEquipment()
120 {
121 #if defined(Q_OS_OSX)
122  wizardContainer->setCurrentIndex(MAC_LOCAL);
123 #elif defined(Q_OS_WIN)
124  wizardContainer->setCurrentIndex(WINDOWS_LOCAL);
125 #else
126  useInternalServer = true;
127  useJoystickCheck->setEnabled(true);
128  useRemoteAstrometryCheck->setEnabled(false);
129  useWatchDogCheck->setEnabled(false);
130  useSkySafariCheck->setEnabled(true);
131  wizardContainer->setCurrentIndex(CREATE_PROFILE);
132 #endif
133 }
134 
135 void ProfileWizard::processRemoteEquipment()
136 {
137  bool portOK = false;
138  remotePortEdit->text().toInt(&portOK);
139 
140  if (portOK == false)
141  {
142  KSNotification::error(i18n("Invalid port."));
143  return;
144  }
145 
146  if (remoteHostEdit->text().isEmpty())
147  {
148  KSNotification::error(i18n("Host name cannot be empty."));
149  return;
150  }
151 
152  useInternalServer = false;
153 
154  host = remoteHostEdit->text();
155  port = remotePortEdit->text();
156 
157  if (webManagerNotSureB->isChecked())
158  {
159  QTcpSocket socket;
160  // Should probably make 8624 configurable too?
161  socket.connectToHost(host, 8624);
162  useWebManager = socket.waitForConnected();
163  }
164  else
165  useWebManager = webManagerYesR->isChecked();
166 
167  useJoystickCheck->setEnabled(true);
168  useRemoteAstrometryCheck->setEnabled(true);
169  useWatchDogCheck->setEnabled(true);
170  useSkySafariCheck->setEnabled(true);
171 
172  wizardContainer->setCurrentIndex(CREATE_PROFILE);
173 }
174 
175 void ProfileWizard::processPiEquipment()
176 {
177  if (PiHost->text().isEmpty())
178  {
179  KSNotification::error(i18n("Host name cannot be empty."));
180  return;
181  }
182 
183  host = PiHost->text();
184  port = PiPort->text();
185 
186  useInternalServer = false;
187  useWebManager = true;
188 
189  useJoystickCheck->setEnabled(true);
190  useRemoteAstrometryCheck->setEnabled(true);
191  useWatchDogCheck->setEnabled(true);
192  useSkySafariCheck->setEnabled(true);
193 
194  wizardContainer->setCurrentIndex(CREATE_PROFILE);
195 }
196 
197 void ProfileWizard::processLocalMac()
198 {
199  QPushButton *button = qobject_cast<QPushButton *>(sender());
200 
201  if (button == nullptr)
202  return;
203 
204  host = "localhost";
205  port = "7624";
206 
207  useInternalServer = (button == useInternalINDIB);
208 
209  useJoystickCheck->setEnabled(false);
210  useRemoteAstrometryCheck->setEnabled(false);
211  useWatchDogCheck->setEnabled(false);
212  useSkySafariCheck->setEnabled(true);
213 
214  wizardContainer->setCurrentIndex(CREATE_PROFILE);
215 }
216 
217 void ProfileWizard::createProfile()
218 {
219  if (profileNameEdit->text().isEmpty())
220  {
221  KSNotification::error(i18n("Profile name cannot be empty."));
222  return;
223  }
224 
225  useJoystick = useJoystickCheck->isEnabled() && useJoystickCheck->isChecked();
226  useWatchDog = useWatchDogCheck->isEnabled() && useWatchDogCheck->isChecked();
227  useSkySafari = useSkySafariCheck->isEnabled() && useSkySafariCheck->isChecked();
228  useRemoteAstrometry = useRemoteAstrometryCheck->isEnabled() && useRemoteAstrometryCheck->isChecked();
229  if (useInternalGuiderR->isChecked())
230  useGuiderType = INTERNAL_GUIDER;
231  else if (usePHD2R->isChecked())
232  useGuiderType = PHD2_GUIDER;
233  else
234  useGuiderType = LIN_GUIDER;
235 
236  profileName = profileNameEdit->text();
237 
238  if (useInternalServer)
239  {
240  host.clear();
241  port.clear();
242  }
243 
244  accept();
245 }
246 
247 QStringList ProfileWizard::selectedAuxDrivers()
248 {
249  QStringList auxList;
250 
251  if (useJoystick)
252  auxList << "Joystick";
253  if (useWatchDog)
254  auxList << "WatchDog";
255  if (useSkySafari)
256  auxList << "SkySafari";
257  if (useRemoteAstrometry)
258  auxList << "Astrometry";
259 
260  return auxList;
261 }
262 
263 int ProfileWizard::selectedExternalGuider()
264 {
265  return useGuiderType;
266 }
267 
268 void ProfileWizard::detectStellarMate()
269 {
270  stellarMateDetectDialog = new QProgressDialog(this);
271  stellarMateDetectDialog->setMinimum(0);
272  stellarMateDetectDialog->setMaximum(0);
273  stellarMateDetectDialog->setWindowTitle(i18nc("@title:window", "Detecting StellarMate..."));
274  stellarMateDetectDialog->setLabelText(i18n("Please wait while searching for StellarMate..."));
275 
276  stellarMateDetectDialog->show();
277 
278  connect(stellarMateDetectDialog.data(), &QProgressDialog::canceled, [&]()
279  {
280  qMDNS::getInstance()->disconnect();
281  });
282  connect(qMDNS::getInstance(), SIGNAL(hostFound(QHostInfo)), this, SLOT(processHostInfo(QHostInfo)));
283  QTimer::singleShot(120 * 1000, this, SLOT(detectStellarMateTimeout()));
284 
285  qMDNS::getInstance()->lookup("stellarmate");
286 }
287 
288 void ProfileWizard::processHostInfo(QHostInfo info)
289 {
290  PiHost->setText(info.hostName());
292  stellarMateDetectDialog->close();
293 }
294 
295 void ProfileWizard::detectStellarMateTimeout()
296 {
297  if (stellarMateDetectDialog->isHidden() == false)
298  {
299  KSNotification::error(i18n("Failed to detect any StellarMate gadget. Make sure it is powered and on the same network."));
300  stellarMateDetectDialog->close();
301  }
302 }
303 
304 void ProfileWizard::processRemoteEquipmentSelection()
305 {
306  QToolButton *button = qobject_cast<QToolButton*>(sender());
307  if (!button)
308  wizardContainer->setCurrentIndex(GENERIC_EQUIPMENT);
309  else if (button == equipmentStellarmateB)
310  {
311  PiHost->setText("stellarmate.local");
312  wizardContainer->setCurrentIndex(PI_EQUIPMENT);
313  }
314  else if (button == equipmentAtikbaseB)
315  {
316  PiHost->setText("atikbase.local");
317  wizardContainer->setCurrentIndex(PI_EQUIPMENT);
318  }
319 }
virtual void connectToHost(const QString &hostName, quint16 port, QIODevice::OpenMode openMode, QAbstractSocket::NetworkLayerProtocol protocol)
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
void appHelpActivated()
static qMDNS * getInstance()
Returns the only running instance of this class.
Definition: qMDNS.cpp:145
void clicked(bool checked)
bool openUrl(const QUrl &url)
bool close()
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
static KStars * Instance()
Definition: kstars.h:125
void lookup(const QString &name)
Performs a mDNS lookup to find the given host name.
Definition: qMDNS.cpp:185
void rejected()
void clicked(QAbstractButton *button)
QString i18n(const char *text, const TYPE &arg...)
void setWindowFlags(Qt::WindowFlags type)
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)
bool load(const QString &fileName, const char *format, Qt::ImageConversionFlags flags)
ScriptableExtension * host() const
virtual bool waitForConnected(int msecs)
QString i18nc(const char *context, const char *text, const TYPE &arg...)
KGuiItem reset()
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Fri Aug 19 2022 03:57:53 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.