• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Stellarium / stellarium / 6685397774

29 Oct 2023 07:37PM UTC coverage: 11.735% (-0.002%) from 11.737%
6685397774

push

github

10110111
Deduplicate title bar implementation

131 of 131 new or added lines in 56 files covered. (100.0%)

14842 of 126472 relevant lines covered (11.74%)

21617.74 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/plugins/TelescopeControl/src/gui/TelescopeDialog.cpp
1
/*
2
 * Stellarium Telescope Control Plug-in
3
 * 
4
 * Copyright (C) 2009-2011 Bogdan Marinov (this file)
5
 * 
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 * 
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 * 
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA  02110-1335, USA.
19
*/
20

21
#include "Dialog.hpp"
22
#include "StelApp.hpp"
23
#include "StelModuleMgr.hpp"
24
#include "StelStyle.hpp"
25
#include "StelMainView.hpp"
26
#include "StelTranslator.hpp"
27
#include "TelescopeControl.hpp"
28
#include "TelescopeConfigurationDialog.hpp"
29
#include "TelescopeDialog.hpp"
30
#include "ui_telescopeDialog.h"
31
#include "StelGui.hpp"
32
#include <QDebug>
33
#include <QFrame>
34
#include <QTimer>
35
#include <QFile>
36
#include <QFileDialog>
37
#include <QHash>
38
#include <QHeaderView>
39
#include <QSettings>
40
#include <QStandardItem>
41
#include <QRegularExpression>
42

43

44
TelescopeDialog::TelescopeDialog(const QString &dialogName, QObject *parent)
×
45
        : StelDialog(dialogName, parent)
46
        , telescopeCount(0)
×
47
        , configuredSlot(0)
×
48
        , configuredTelescopeIsNew(false)
×
49
{
50
        telescopeStatus[0] = TelescopeControl::StatusNA;
×
51
        connectionTypes[0] = TelescopeControl::ConnectionNA;
×
52

53
        ui = new Ui_telescopeDialogForm;
×
54

55
        //TODO: Fix this - it's in the same plugin
56
        telescopeManager = GETSTELMODULE(TelescopeControl);
×
57

58
        telescopeListModel = new QStandardItemModel(0, ColumnCount);
×
59

60
        //TODO: (FC 2010) This shouldn't be a hash...--> GZ (2022): OK, it's map now.
61
        statusString = {
62
                {TelescopeControl::StatusNA,           N_("N/A")},
×
63
                {TelescopeControl::StatusStarting,     N_("Starting")},
×
64
                {TelescopeControl::StatusConnecting,   N_("Connecting")},
×
65
                {TelescopeControl::StatusConnected,    N_("Connected")},
×
66
                {TelescopeControl::StatusDisconnected, N_("Disconnected")},
×
67
                {TelescopeControl::StatusStopped,      N_("Stopped")}};
×
68
}
×
69

70
TelescopeDialog::~TelescopeDialog()
×
71
{        
72
        delete ui;
×
73
        
74
        delete telescopeListModel;
×
75
}
×
76

77
void TelescopeDialog::retranslate()
×
78
{
79
        if (dialog)
×
80
        {
81
                ui->retranslateUi(dialog);
×
82
                setAboutText();
×
83
                setHeaderNames();
×
84
                updateWarningTexts();
×
85
                
86
                //Retranslate type strings
87
                for (int i = 0; i < telescopeListModel->rowCount(); i++)
×
88
                {
89
                        QStandardItem* item = telescopeListModel->item(i, ColumnType);
×
90
                        QString original = item->data(Qt::UserRole).toString();
×
91
                        QModelIndex index = telescopeListModel->index(i, ColumnType);
×
92
                        telescopeListModel->setData(index, q_(original), Qt::DisplayRole);
×
93
                }
×
94
        }
95
}
×
96

97
// Initialize the dialog widgets and connect the signals/slots
98
void TelescopeDialog::createDialogContent()
×
99
{
100
        ui->setupUi(dialog);
×
101
        
102
        // Kinetic scrolling
103
        kineticScrollingList << ui->telescopeTreeView << ui->textBrowserHelp << ui->textBrowserAbout;
×
104
        StelGui* gui= dynamic_cast<StelGui*>(StelApp::getInstance().getGui());
×
105
        if (gui)
×
106
        {
107
                enableKineticScrolling(gui->getFlagUseKineticScrolling());
×
108
                connect(gui, SIGNAL(flagUseKineticScrollingChanged(bool)), this, SLOT(enableKineticScrolling(bool)));
×
109
        }
110

111
        //Inherited connect
112
        connect(&StelApp::getInstance(), SIGNAL(languageChanged()), this, SLOT(retranslate()));
×
113
        connect(ui->titleBar, &TitleBar::closeClicked, this, &StelDialog::close);
×
114
        connect(ui->titleBar, SIGNAL(movedTo(QPoint)), this, SLOT(handleMovedTo(QPoint)));
×
115

116
        //Connect: sender, signal, receiver, method
117
        //Page: Telescopes
118
        connect(ui->pushButtonChangeStatus, SIGNAL(clicked()), this, SLOT(buttonChangeStatusPressed()));
×
119
        connect(ui->pushButtonConfigure, SIGNAL(clicked()), this, SLOT(buttonConfigurePressed()));
×
120
        connect(ui->pushButtonAdd, SIGNAL(clicked()), this, SLOT(buttonAddPressed()));
×
121
        connect(ui->pushButtonRemove, SIGNAL(clicked()), this, SLOT(buttonRemovePressed()));
×
122
        
123
        connect(ui->telescopeTreeView, SIGNAL(clicked (const QModelIndex &)), this, SLOT(selectTelecope(const QModelIndex &)));
×
124
        //connect(ui->telescopeTreeView, SIGNAL(activated (const QModelIndex &)), this, SLOT(configureTelescope(const QModelIndex &)));
125
        
126
        //Page: Options:
127
        connectBoolProperty(ui->checkBoxReticles,   "TelescopeControl.flagTelescopeReticles");
×
128
        connectBoolProperty(ui->checkBoxLabels,     "TelescopeControl.flagTelescopeLabels");
×
129
        connectBoolProperty(ui->checkBoxCircles,    "TelescopeControl.flagTelescopeCircles");
×
130
        connectColorButton(ui->reticleColorButton,  "TelescopeControl.reticleColor", "TelescopeControl/color_telescope_reticles");
×
131
        connectColorButton(ui->labelColorButton,    "TelescopeControl.labelColor",   "TelescopeControl/color_telescope_labels");
×
132
        connectColorButton(ui->circleColorButton,   "TelescopeControl.circleColor",  "TelescopeControl/color_telescope_circles");
×
133
        connectBoolProperty(ui->checkBoxEnableLogs, "TelescopeControl.useTelescopeServerLogs");
×
134

135
        connect(ui->checkBoxUseExecutables, SIGNAL(toggled(bool)), ui->labelExecutablesDirectory, SLOT(setEnabled(bool)));
×
136
        connect(ui->checkBoxUseExecutables, SIGNAL(toggled(bool)), ui->lineEditExecutablesDirectory, SLOT(setEnabled(bool)));
×
137
        connect(ui->checkBoxUseExecutables, SIGNAL(toggled(bool)), ui->pushButtonPickExecutablesDirectory, SLOT(setEnabled(bool)));
×
138

139
        connect(ui->pushButtonPickExecutablesDirectory, SIGNAL(clicked()), this, SLOT(buttonBrowseServerDirectoryPressed()));
×
140
        //Telescope server directory
141
        connectBoolProperty(ui->checkBoxUseExecutables, "TelescopeControl.useTelescopeServerExecutables");
×
142
        ui->lineEditExecutablesDirectory->setText(telescopeManager->getServerExecutablesDirectoryPath());
×
143

144
        connectStringProperty(ui->lineEditExecutablesDirectory, "TelescopeControl.serverExecutablesDirectoryPath");
×
145

146
        //In other dialogs:
147
        connect(&configurationDialog, SIGNAL(changesDiscarded()), this, SLOT(discardChanges()));
×
148
        connect(&configurationDialog, SIGNAL(changesSaved(QString, TelescopeControl::ConnectionType)), this, SLOT(saveChanges(QString, TelescopeControl::ConnectionType)));
×
149
        
150
        //Initialize the style
151
        updateStyle();
×
152
        
153
        //Initializing the list of telescopes
154
        telescopeListModel->setColumnCount(ColumnCount);
×
155
        setHeaderNames();
×
156
        
157
        ui->telescopeTreeView->setModel(telescopeListModel);
×
158
        ui->telescopeTreeView->header()->setSectionsMovable(false);
×
159
        ui->telescopeTreeView->header()->setSectionResizeMode(ColumnSlot, QHeaderView::ResizeToContents);
×
160
        ui->telescopeTreeView->header()->setStretchLastSection(true);
×
161
        
162
        //Populating the list
163
        //Cycle the slots
164
        for (int slotNumber = TelescopeControl::MIN_SLOT_NUMBER; slotNumber < TelescopeControl::SLOT_NUMBER_LIMIT; slotNumber++)
×
165
        {
166
                //Slot #
167
                //int slotNumber = (i+1)%SLOT_COUNT;//Making sure slot 0 is last
168
                
169
                //Make sure that this is initialized for all slots
170
                telescopeStatus[slotNumber] = TelescopeControl::StatusNA;
×
171
                
172
                //Read the telescope properties
173
                QString name;
×
174
                TelescopeControl::ConnectionType connectionType;
175
                QString equinox;
×
176
                QString host;
×
177
                int portTCP;
178
                int delay;
179
                bool connectAtStartup;
180
                QList<double> circles;
×
181
                QString serverName;
×
182
                QString portSerial;
×
183
                QString rts2Url;
×
184
                QString rts2Username;
×
185
                QString rts2Password;
×
186
                int rts2Refresh;
187
                QString ascomDeviceId;
×
188
                bool ascomUseDeviceEqCoordType;
189

190
                if(!telescopeManager->getTelescopeAtSlot(slotNumber, connectionType, name, equinox, host, portTCP, delay, connectAtStartup, circles, serverName, portSerial, rts2Url, rts2Username, rts2Password, rts2Refresh, ascomDeviceId, ascomUseDeviceEqCoordType))
×
191
                        continue;
×
192
                
193
                //Determine the server type
194
                connectionTypes[slotNumber] = connectionType;
×
195
                
196
                //Determine the telescope's status
197
                if (telescopeManager->isConnectedClientAtSlot(slotNumber))
×
198
                {
199
                        telescopeStatus[slotNumber] = TelescopeControl::StatusConnected;
×
200
                }
201
                else
202
                {
203
                        //TODO: Fix this!
204
                        //At startup everything exists and attempts to connect
205
                        telescopeStatus[slotNumber] = TelescopeControl::StatusConnecting;
×
206
                }
207
                
208
                addModelRow(slotNumber, connectionType, telescopeStatus[slotNumber], name);
×
209
                
210
                //After everything is done, count this as loaded
211
                telescopeCount++;
×
212
        }
×
213
        
214
        //Finished populating the table, let's sort it by slot number
215
        //ui->telescopeTreeView->setSortingEnabled(true);//Set in the .ui file
216
        ui->telescopeTreeView->sortByColumn(ColumnSlot, Qt::AscendingOrder);
×
217
        //(Works even when the table is empty)
218
        //(Makes redundant the delay of 0 above)
219
        
220
        //TODO: Reuse code.
221
        if(telescopeCount > 0)
×
222
        {
223
                ui->telescopeTreeView->setFocus();
×
224
                ui->telescopeTreeView->header()->setSectionResizeMode(ColumnType, QHeaderView::ResizeToContents);
×
225
        }
226
        else
227
        {
228
                ui->pushButtonChangeStatus->setEnabled(false);
×
229
                ui->pushButtonConfigure->setEnabled(false);
×
230
                ui->pushButtonRemove->setEnabled(false);
×
231
                ui->pushButtonAdd->setFocus();
×
232
        }
233
        updateWarningTexts();
×
234
        
235
        if(telescopeCount >= TelescopeControl::SLOT_COUNT)
×
236
                ui->pushButtonAdd->setEnabled(false);
×
237
        
238

239
        //About page
240
        setAboutText();
×
241
        
242
        //Everything must be initialized by now, start the updateTimer
243
        //TODO: Find if it's possible to run it only when the dialog is visible
244
        QTimer* updateTimer = new QTimer(this);
×
245
        connect(updateTimer, SIGNAL(timeout()), this, SLOT(updateTelescopeStates()));
×
246
        updateTimer->start(200);
×
247
}
×
248

249
void TelescopeDialog::setAboutText()
×
250
{
251
        // Regexp to replace {text} with an HTML link.
252
        static const QRegularExpression a_rx("[{]([^{]*)[}]");
×
253

254
        //TODO: Expand
255
        QString aboutPage = "<html><head></head><body>";
×
256
        aboutPage += "<h2>" + q_("Telescope Control plug-in") + "</h2><table width=\"90%\">";
×
257
        aboutPage += "<tr width=\"30%\"><td><strong>" + q_("Version") + ":</strong></td><td>" + TELESCOPE_CONTROL_PLUGIN_VERSION + "</td></tr>";
×
258
        aboutPage += "<tr><td><strong>" + q_("License") + ":</strong></td><td>" + TELESCOPE_CONTROL_PLUGIN_LICENSE + "</td></tr>";
×
259
        aboutPage += "<tr><td rowspan=5><strong>" + q_("Authors") + "</strong></td><td>Johannes Gajdosik</td></td>";
×
260
        aboutPage += "<tr><td>Bogdan Marinov &lt;bogdan.marinov84@gmail.com&gt; (" + q_("Plug-in and GUI programming") + ")</td></tr>";
×
261
        aboutPage += "<tr><td>Gion Kunz &lt;gion.kunz@gmail.com&gt; (" + q_("ASCOM Telescope Client") + ")</td></tr>";
×
262
        aboutPage += "<tr><td>Petr Kubánek (" + q_("RTS2 support") + ")</td></tr>";
×
263
        aboutPage += "<tr><td>Alessandro Siniscalchi &lt;asiniscalchi@gmail.com&gt; (" + q_("INDI Telescope Client") + ")</td></tr>";
×
264
        aboutPage += "<tr><td rowspan=3><strong>" + q_("Contributors") + ":</strong></td><td>Alexander Wolf</td></tr>";
×
265
        aboutPage += "<tr><td>Michael Heinz</td></tr>";
×
266
        aboutPage += "<tr><td>Alexandros Kosiaris</td></tr>";
×
267
        aboutPage += "</table>";
×
268

269
        aboutPage += "<p>" + q_("This plug-in is based on and reuses a lot of code under the GNU General Public License:") + "</p><ul>";
×
270
        aboutPage += "<li>" + q_("the Telescope, TelescopeDummy, TelescopeTcp and TelescopeMgr classes in Stellarium's code (the client side of Stellarium's original telescope control feature);") + "</li>";
×
271
        aboutPage += "<li>" + q_("the telescope server core code (licensed under the LGPL)") + "</li>";
×
272
        aboutPage += "<li>" + q_("the TelescopeServerLx200 telescope server core code (originally licensed under the LGPL)");
×
273
        aboutPage += "<br/>" + q_("Author of all of the above - the client, the server core, and the LX200 server, along with the Stellarium telescope control network protocol (over TCP/IP), is <b>Johannes Gajdosik</b>.") + "</li>";
×
274
        aboutPage += "<li>" + q_("the TelescopeServerNexStar telescope server core code (originally licensed under the LGPL, based on TelescopeServerLx200) by <b>Michael Heinz</b>.") + "</li>";
×
275
        aboutPage += "<li>" + q_("INDI by <b>Alessandro Siniscalchi</b>.") + "</li></ul>";
×
276

277
        aboutPage += StelApp::getInstance().getModuleMgr().getStandardSupportLinksInfo("Telescope Control plugin");
×
278
        aboutPage += "</body></html>";
×
279
        
280
        QString helpPage = "<html><head></head><body>";
×
281
        // TRANSLATORS: The text between braces is the text of an HTML link.
282
        helpPage += "<p>" + q_("A more complete and up-to-date documentation for this plug-in can be found on the {Telescope Control} page in the Stellarium Wiki.").replace(a_rx, "<a href=\"http://stellarium.sourceforge.net/wiki/index.php/Telescope_Control_plug-in\">\\1</a>") + "</p>";
×
283
        helpPage += "<h3><a name=\"top\" />" + q_("Contents") + "</h3><ul>";
×
284
        helpPage += "<li><a href=\"#Abilities_and_limitations\">" + q_("Abilities and limitations") + "</a></li>";
×
285
        helpPage += "<li><a href=\"#originalfeature\">" + q_("The original telescope control feature") + "</a></li>";
×
286
        helpPage += "<li><a href=\"#usingthisplugin\">" + q_("Using this plug-in") + "</a></li>";
×
287
        helpPage += "<li><a href=\"#mainwindow\">" + q_("Main window ('Telescopes')") + "</a></li>";
×
288
        helpPage += "<li><a href=\"#configwindow\">" + q_("Telescope configuration window") + "</a><ul>";
×
289
        helpPage += "<li><a href=\"#connection_type\">" + q_("Connection type") + "</a></li>";
×
290
        helpPage += "<li><a href=\"#telescope_properties\">" + q_("Telescope properties") + "</a></li>";
×
291
        helpPage += "<li><a href=\"#device_settings\">" + q_("Device settings") + "</a></li>";
×
292
        helpPage += "<li><a href=\"#connection_settings\">" + q_("Connection settings") + "</a></li>";
×
293
        helpPage += "<li><a href=\"#fovcircles\">" + q_("Field of view indicators") + "</a></li></ul></li>";
×
294
        helpPage += "<li><a href=\"#slew_to\">" + q_("'Slew telescope to' window") + "</a></li>";
×
295
        helpPage += "<li><a href=\"#commands\">" + q_("Telescope commands") + "</a></li>";
×
296
        helpPage += "<li><a href=\"#devices\">" + q_("Supported devices") + "</a></li>";
×
297
        helpPage += "<li><a href=\"#virtual_telescope\">" + q_("Virtual telescope") + "</a></li></ul>";
×
298

299
        helpPage += "<h3><a name=\"Abilities_and_limitations\" />" + q_("Abilities and limitations") + "</h3>";
×
300
        helpPage += "<p>" + q_("This plug-in allows Stellarium to send only '<b>slew</b>' ('go to') commands to the device and to receive its current position. It cannot issue any other commands, so users should be aware of the possibility for mount collisions and similar situations. (To abort a slew, you can start another one to a safe position.)") + "</p>";
×
301
        helpPage += "<p>" + q_("As of the current version, this plug-in doesn't allow satellite tracking, and is not very suitable for lunar or planetary observations.") + "</p>";
×
302
        helpPage += "<p><span style=\"color: red; font-weight: bolder;\">" + q_("WARNING: Stellarium CANNOT prevent your telescope from being pointed at the Sun.") + "</span></p><ul>";
×
303
        helpPage += "<li>" + q_("Never point your telescope at the Sun without a proper solar filter installed. The powerful light amplified by the telescope WILL cause irreversible damage to your eyes and/or your equipment.") + "</li>";
×
304
        helpPage += "<li>" + q_("Even if you don't do it deliberately, a slew during daylight hours may cause your telescope to point at the sun on its way to the given destination, so it is strongly recommended to avoid using the telescope control feature before sunset without appropriate protection.") + "</li></ul>";
×
305
        helpPage += "<p><a href=\"#top\"><small>[" + q_("Back to top") + "]</small></a></p>";
×
306

307
        helpPage += "<h3><a name=\"originalfeature\" />" + q_("The original telescope control feature") + "</h3>";
×
308
        helpPage += "<p>" + q_("As of Stellarium 0.10.5, the original telescope control feature has been removed. There is no longer a way to control a telescope with Stellarium without this plug-in.") + "</p>";
×
309
        helpPage += "<p><a href=\"#top\"><small>[" + q_("Back to top") + "]</small></a></p>";
×
310

311
        helpPage += "<h3><a name=\"usingthisplugin\" />" + q_("Using this plug-in") + "</h3>";
×
312
        helpPage += "<p>" + q_("Here are two general ways to control a device with this plug-in, depending on the situation:") + "</p><ul>";
×
313
        helpPage += "<li><b>" + q_("DIRECT CONNECTION") + "</b>: ";
×
314

315
        // TRANSLATORS: The text between braces is the text of an HTML link.
316
        helpPage += q_("A {device supported by the plug-in} is connected with a cable to the computer running Stellarium;").replace(a_rx, "<a href=\"#devices\">\\1</a>");
×
317
        helpPage += "</li>";
×
318
        helpPage += "<li><b>" + q_("INDIRECT CONNECTION") + "</b>: <ul>";
×
319
        helpPage += "<li>";
×
320
        // TRANSLATORS: The text between braces is the text of an HTML link.
321
        helpPage += q_("A device is connected to the same computer but it is driven by a {stand-alone telescope server program}").replace(a_rx, "<a href=\"http://stellarium.sourceforge.net/wiki/index.php/Telescope_Control_%28client-server%29\">\\1</a>") + " ";
×
322
        // TRANSLATORS: The text between braces is the text of an HTML link.
323
        helpPage += q_("or a {third-party application} <b>that can 'talk' to Stellarium</b>;").replace(a_rx, "<a href=\"http://stellarium.sourceforge.net/wiki/index.php/Telescope_Control#Third_party_applications\">\\1</a>");
×
324
        helpPage += "</li>";
×
325
        helpPage += "<li>" + q_("A device is connected to a remote computer and the software that drives it can 'talk' to Stellarium <i>over the network</i>; this software can be either one of Stellarium's stand-alone telescope servers, or a third party application.") + "</li></ul></li></ul>";
×
326
        helpPage += "<p>";
×
327
        // TRANSLATORS: The text between braces is the text of an HTML link.
328
        helpPage += "<p>" + q_("Most older telescopes use cables that connect to a {serial port} (RS-232), the newer ones use USB (Universal Serial Bus).").replace(a_rx, "<a href=\"http://meta.wikimedia.org/wiki/wikipedia:en:serial_port\">\\1</a>")
×
329
                 + " " + q_("On Linux and Mac OS X both cases are handled identically by the plug-in. On Windows, a USB connection may require a 'virtual serial port' software, if it is not supplied with the cable or the telescope.")
×
330
                 + " " + q_("Such a software creates a virtual ('fake') COM port that corresponds to the real USB port so it can be used by the plug-in.")
×
331
                 + " " + q_("On all three platforms, if the computer has no 'classic' serial ports and the telescope can connect only to a serial port, a serial-to-USB (RS-232-to-USB) adapter may be necessary.") + "</p>";
×
332
        helpPage += "<p>" + q_("Telescope set-up (setting geographical coordinates, performing alignment, etc.) should be done before connecting the telescope to Stellarium.") + "</p>";
×
333
        helpPage += "<p><a href=\"#top\"><small>[" + q_("Back to top") + "]</small></a></p>";
×
334

335
        helpPage += "<h3><a name=\"mainwindow\" />" + q_("Main window ('Telescopes')") + "</h3>";
×
336
        helpPage += "<p>" + q_("The plug-in's main window can be opened:") + "</p><ul>";
×
337
        helpPage += "<li>" + q_("By pressing the 'configure' button for the plug-in in the 'Plugins' tab of Stellarium's Configuration window (opened by pressing <b>F2</b> or the respective button in the left toolbar).") + "</li>";
×
338
        helpPage += "<li>";
×
339
        // TRANSLATORS: The text between braces is the text of an HTML link.
340
        helpPage += q_("By pressing the 'Configure telescopes...' button in the {'Slew to' window} (opened by pressing <b>Ctrl+0</b> or the respective button on the bottom toolbar).").replace(a_rx, "<a href=\"#slew_to\">\\1</a>");
×
341
        helpPage += "</li></ul>";
×
342
        helpPage += "<p>" + q_("The <b>Telescopes</b> tab displays a list of the telescope connections that have been set up:") + "</p><ul>";
×
343
        helpPage += "<li>" + q_("The number (<b>#</b>) column shows the number used to control this telescope. For example, for telescope #2, the shortcut is Ctrl+2.") + "</li>";
×
344
        helpPage += "<li>" + q_("The <b>Status</b> column indicates if this connection is currently active or not. Unfortunately, there are some cases in which 'Connected' is displayed when no working connection exists.") + "</li>";
×
345
        helpPage += "<li>" + q_("The <b>Type</b> field indicates what kind of connection is this:") + "</li><ul>";
×
346
        helpPage += "<li>";
×
347
        // TRANSLATORS: The text between braces is the text of an HTML link.
348
        helpPage += q_("<b>virtual</b> means a {virtual telescope};").replace(a_rx, "<a href=\"#virtual_telescope\">\\1</a>");
×
349
        helpPage += "</li>";
×
350
        helpPage += "<li>";
×
351
        // TRANSLATORS: The text between braces is the text of an HTML link.
352
        helpPage += q_("<b>local, Stellarium</b> means a DIRECT connection to the telescope (see {above});").replace(a_rx, "<a href=\"#usingthisplugin\">\\1</a>");
×
353
        helpPage += "</li>";
×
354
        helpPage += "<li>" + q_("<b>local, external</b> means an INDIRECT connection to a program running on the same computer;") + "</li>";
×
355
        helpPage += "<li>" + q_("<b>remote, unknown</b> means an INDIRECT connection over a network to a remote machine.") + "</li></ul></li></ul>";
×
356
        helpPage += "<p>" + q_("To set up a new telescope connection, press the <b>Add</b> button. To modify the configuration of an existing connection, select it in the list and press the <b>Configure</b> button. In both cases, a telescope connection configuration window will open.") + "</p>";
×
357
        helpPage += "<p><a href=\"#top\"><small>[" + q_("Back to top") + "]</small></a></p>";
×
358

359
        helpPage += "<h3><a name=\"configwindow\" />" + q_("Telescope configuration window") + "</h3>";
×
360

361
        helpPage += "<h4><a name=\"connection_type\" />" + q_("Connection type") + "</h4>";
×
362
        helpPage += "<p>";
×
363
        // TRANSLATORS: The text between braces is the text of an HTML link.
364
        helpPage += q_("The topmost field represents the choice between the two types of connections (see {above}):").replace(a_rx, "<a href=\"#usingthisplugin\">\\1</a>");
×
365
        helpPage += "</p>";
×
366
        helpPage += "<p><b>" + q_("Telescope controlled by:") + "</b></p><ul>";
×
367
        helpPage += "<li>" + q_("<b>Stellarium, directly through a serial port</b> is the DIRECT case") + "</li>";
×
368
        helpPage += "<li>" + q_("<b>External software or a remote computer</b> is the INDIRECT case") + "</li>";
×
369
        helpPage += "<li>";
×
370
        // TRANSLATORS: The text between braces is the text of an HTML link.
371
        helpPage += q_("<b>Nothing, just simulate one (a moving reticle)</b> is a {virtual telescope} (no connection)").replace(a_rx, "<a href=\"#virtual_telescope\">\\1</a>");
×
372
        helpPage += "</li></ul>";
×
373
        helpPage += "<p><a href=\"#top\"><small>[" + q_("Back to top") + "]</small></a></p>";
×
374

375
        helpPage += "<h4><a name=\"telescope_properties\" />" + q_("Telescope properties") + "</h4>";
×
376
        helpPage += "<p>" + q_("<b>Name</b> is the label that will be displayed on the screen next to the telescope reticle.") + "</p>";
×
377
        helpPage += "<p>" + q_("<b>Connection delay</b>: If the movement of the telescope reticle on the screen is uneven, you can try increasing or decreasing this value.") + "</p>";
×
378
        helpPage += "<p>" + q_("<b>Coordinate system</b>: Some Celestron telescopes have had their firmware updated and now interpret the coordinates they receive as coordinates that use the equinox of the date (EOD, also known as JNow), making necessary this override.") + "</p>";
×
379
        helpPage += "<p>" + q_("<b>Start/connect at startup</b>: Check this option if you want Stellarium to attempt to connect to the telescope immediately after it starts.")
×
380
                 + " " + q_("Otherwise, to start the telescope, you need to open the main window, select that telescope and press the 'Start/Connect' button.") + "</p>";
×
381
        helpPage += "<p><a href=\"#top\"><small>[" + q_("Back to top") + "]</small></a></p>";
×
382

383
        helpPage += "<h4><a name=\"device_settings\" />" + q_("Device settings") + "</h4>";
×
384
        helpPage += "<p>";
×
385
        // TRANSLATORS: The text between braces is the text of an HTML link.
386
        helpPage += q_("This section is active only for DIRECT connections (see {above}).").replace(a_rx, "<a href=\"#usingthisplugin\">\\1</a>");
×
387
        helpPage += "</p>";
×
388
        helpPage += "<p>" + q_("<b>Serial port</b> sets the serial port used by the telescope.") + "</p>";
×
389
        helpPage += "<p>" + q_("There is a pop-up box that suggests some default values:") + "</p><ul>";
×
390
        helpPage += "<li>" + q_("On Windows, serial ports COM1 to COM10;") + "</li>";
×
391
        helpPage += "<li>" + q_("On Linux, serial ports /dev/ttyS0 to /dev/ttyS3 and USB ports /dev/ttyUSB0 to /dev/ttyUSB3;") + "</li>";
×
392
        helpPage += "<li>" + q_("On Mac OS X, the list is empty as it names its ports in a peculiar way.") + "</li></ul>";
×
393
        helpPage += "<p>" + q_("If you are using an USB cable, the default serial port of your telescope most probably is not in the list of suggestions.") + "</p>";
×
394
        helpPage += "<p>" + q_("To list all valid serial port names in Mac OS X, open a terminal and type:") + "<br /><samp>ls /dev/*</samp></p>";
×
395
        helpPage += "<p>" + q_("This will list all devices, the full name of your serial port should be somewhere in the list (for example, '/dev/cu.usbserial-FTDFZVMK').") + "</p>";
×
396
        helpPage += "<p>";
×
397
        // TRANSLATORS: The text between braces is the text of an HTML link.
398
        helpPage += q_("<b>Device model</b>: see {Supported devices} below.").replace(a_rx, "<a href=\"#devices\">\\1</a>");
×
399
        helpPage += "</p>";
×
400
        helpPage += "<p><a href=\"#top\"><small>[" + q_("Back to top") + "]</small></a></p>";
×
401

402
        helpPage += "<h4><a name=\"connection_settings\" />" + q_("Connection settings") + "</h4>";
×
403
        helpPage += "<p>";
×
404
        // TRANSLATORS: The text between braces is the text of an HTML link.
405
        helpPage += q_("Both fields here refer to communication over a network ({TCP/IP}).").replace(a_rx, "<a href=\"http://meta.wikimedia.org/wiki/wikipedia:en:TCP/IP\">\\1</a>") + " ";
×
406
        // TRANSLATORS: The text between braces is the text of an HTML link.
407
        helpPage += q_("Doing something with them is necessary only for INDIRECT connections (see {above}).").replace(a_rx, "<a href=\"#usingthisplugin\">\\1</a>") + " ";
×
408
        helpPage += "</p>";
×
409
        helpPage += "<p>";
×
410
        // TRANSLATORS: The text between braces is the text of an HTML link.
411
        helpPage += q_("<b>Host</b> can be either a host name or an {IPv4} address such as '127.0.0.1'. The default value of 'localhost' means 'this computer'.").replace(a_rx, "<a href=\"http://meta.wikimedia.org/wiki/wikipedia:en:IPv4\">\\1</a>");
×
412
        helpPage += "</p>";
×
413
        helpPage += "<p>" + q_("<b>Port</b> refers to the TCP port used for communication. The default value depends on the telescope number and ranges between 10001 and 10009.") + "</p>";
×
414
        helpPage += "<p>" + q_("Both values are ignored for DIRECT connections.") + "</p>";
×
415
        helpPage += "<p>" + q_("For INDIRECT connections, modifying the default host name value makes sense only if you are attempting a remote connection over a network.")
×
416
                 + " " + q_("In this case, it should be the name or IP address of the computer that runs a program that runs the telescope.") + "</p>";
×
417
        helpPage += "<p><a href=\"#top\"><small>[" + q_("Back to top") + "]</small></a></p>";
×
418

419
        helpPage += "<h4><a name=\"fovcircles\" />" + q_("Field of view indicators") + "</h4>";
×
420
        helpPage += "<p>" + q_("A series of circles representing different fields of view can be added around the telescope marker. This is a relic from the times before the <strong>Oculars</strong> plug-in existed.") + "</p>";
×
421
        helpPage += "<p>" + q_("In the telescope configuration window, click on 'User Interface Settings'.")
×
422
                 + " " + q_("Mark the 'Use field of view indicators' option, then enter a list of values separated with commas in the field below.")
×
423
                 + " " + q_("The values are interpreted as degrees of arc.") + "</p>";
×
424
        helpPage += "<p>";
×
425
        // TRANSLATORS: The text between braces is the text of an HTML link.
426
        helpPage += q_("This can be used in combination with a {virtual telescope} to display a moving reticle with the Telrad circles.").replace(a_rx, "<a href=\"#virtual_telescope\">\\1</a>");
×
427
        helpPage += "</p>";
×
428
        helpPage += "<p><a href=\"#top\"><small>[" + q_("Back to top") + "]</small></a></p>";
×
429

430
        helpPage += "<h3><a name=\"slew_to\" />" + q_("'Slew telescope to' window") + "</h3>";
×
431
        helpPage += "<p>" + q_("The 'Slew telescope to' window can be opened by pressing <b>Ctrl+0</b> or the respective button in the bottom toolbar.") + "</p>";
×
432
        helpPage += "<p>" + q_("It contains two fields for entering celestial coordinates, selectors for the preferred format (Hours-Minutes-Seconds, Degrees-Minutes-Seconds, or Decimal degrees), a drop-down list and two buttons.") + "</p>";
×
433
        helpPage += "<p>" + q_("The drop-down list contains the names of the currently connected devices.") + " ";
×
434
        helpPage += q_("If no devices are connected, it will remain empty, and the 'Slew' button will be disabled.") + "</p>";
×
435
        helpPage += "<p>" + q_("Pressing the <b>Slew</b> button slews the selected device to the selected set of coordinates.") + " ";
×
436
        // TRANSLATORS: The text between braces is the text of an HTML link.
437
        helpPage += q_("See the section about {keyboard commands} below for other ways of controlling the device.").replace(a_rx, "<a href=\"#commands\">\\1</a>");
×
438
        helpPage += "</p>";
×
439
        helpPage += "<p>";
×
440
        // TRANSLATORS: The text between braces is the text of an HTML link.
441
        helpPage += q_("Pressing the <b>Configure telescopes...</b> button opens the {main window} of the plug-in.").replace(a_rx, "<a href=\"#mainwindow\">\\1</a>");
×
442
        helpPage += "</p>";
×
443
        helpPage += "<p>" + q_("<b>TIP:</b> Inside the 'Slew' window, underlined letters indicate that pressing 'Alt + underlined letter' can be used instead of clicking.") + " ";
×
444
        helpPage +=  q_("For example, pressing <b>Alt+S</b> is equivalent to clicking the 'Slew' button, pressing <b>Alt+E</b> switches to decimal degree format, etc.") + "</p>";
×
445
        helpPage += "<p><a href=\"#top\"><small>[" + q_("Back to top") + "]</small></a></p>";
×
446

447
        helpPage += "<h3><a name=\"commands\" />" + q_("Sending commands") + "</h3>";
×
448
        helpPage += "<p>" + q_("Once a telescope is successfully started/connected, Stellarium displays a telescope reticle labelled with the telescope's name on its current position in the sky.")
×
449
                 + " " + q_("The reticle is an object like every other in Stellarium - it can be selected with the mouse, it can be tracked and it appears as an object in the 'Search' window.") + "</p>";
×
450
        helpPage += "<p>" + q_("<b>To point a device to an object:</b> Select an object (e.g. a star) and press the number of the device while holding down the <b>Ctrl</b> key.")
×
451
                 + " (" + q_("For example, Ctrl+1 for telescope #1.") + ") "
×
452
                 + q_("This will move the telescope to the selected object.") + "</p>";
×
453
        helpPage += "<p>" + q_("<b>To point a device to the center of the view:</b> Press the number of the device while holding down the <b>Alt</b> key.")
×
454
                 + " (" + q_("For example, Alt+1 for telescope #1.") + ") "
×
455
                 + q_("This will slew the device to the point in the center of the current view.")
×
456
                 + " (" + q_("If you move the view after issuing the command, the target won't change unless you issue another command.") + ")</p>";
×
457
        helpPage += "<p>";
×
458
        // TRANSLATORS: The text between braces is the text of an HTML link.
459
        helpPage += q_("<b>To point a device to a given set of coordinates:</b> Use the {'Slew to' window} (press <b>Ctrl+0</b>).").replace(a_rx, "<a href=\"#slew_to\">\\1</a>");
×
460
        helpPage += "</p>";
×
461
        helpPage += "<p><a href=\"#top\"><small>[" + q_("Back to top") + "]</small></a></p>";
×
462

463
        helpPage += "<h3><a name=\"devices\" />" + q_("Supported devices") + "</h3>";
×
464
        helpPage += "<p>";
×
465
        // TRANSLATORS: The text between braces is the text of an HTML link.
466
        helpPage += q_("All devices listed in the {'Device model' list} are convenience definitions using one of the two built-in interfaces: the Meade LX200 (the Meade Autostar controller) interface and the Celestron NexStar interface.").replace(a_rx, "<a href=\"#device_settings\">\\1</a>");
×
467
        helpPage += "</p>";
×
468
        helpPage += "<p>" + q_("The device list contains the following:") + "</p><dl>";
×
469
        helpPage += "<dt><b>Celestron NexStar (compatible)</b></dt><dd>" + q_("Any device using the NexStar interface.") + "</dd>";
×
470
        helpPage += "<dt><b>Losmandy G-11</b></dt><dd>" + q_("A computerized telescope mount made by Losmandy (Meade LX-200/Autostar interface).") + "</dd>";
×
471
        helpPage += "<dt><b>Meade Autostar compatible</b></dt><dd>" + q_("Any device using the LX-200/Autostar interface.") + "</dd>";
×
472
        helpPage += "<dt><b>Meade ETX-70 (#494 Autostar, #506 CCS)</b></dt><dd>" + q_("The Meade ETX-70 telescope with the #494 Autostar controller and the #506 Connector Cable Set.") + " ";
×
473
        // TRANSLATORS: The text between braces is the text of an HTML link.
474
        helpPage += q_("According to the tester, it is a bit slow, so its default setting of %1'Connection delay'%2 is 1.5 seconds instead of 0.5 seconds.").replace(a_rx, "<a href=\"#telescope_properties\">\\1</a>");
×
475
        helpPage += "</dd>";
×
476
        helpPage += "<dt><b>Meade LX200 (compatible)</b></dt><dd>" + q_("Any device using the LX-200/Autostar interface.") + "</dd>";
×
477
        helpPage += "<dt><b>Sky-Watcher SynScan AZ mount</b></dt><dd>" + q_("The Sky-Watcher SynScan AZ GoTo mount is used in a number of telescopes.") + "</dd>";
×
478
        helpPage += "<dt><b>Sky-Watcher SynScan (version 3 or later)</b></dt><dd>" + q_("<b>SynScan</b> is also the name of the hand controller used in other Sky-Watcher GoTo mounts, and it seems that any mount that uses a SynScan controller version 3.0 or greater is supported by the plug-in, as it uses the NexStar protocol.") + "</dd>";
×
479
        helpPage += "<dt><b>Wildcard Innovations Argo Navis (Meade mode)</b></dt><dd>" + q_("Argo Navis is a 'Digital Telescope Computer' by Wildcard Innovations.")
×
480
                 + " " + q_("It is an advanced digital setting circle that turns an ordinary telescope (for example, a dobsonian) into a 'Push To' telescope (a telescope that uses a computer to find targets and human power to move the telescope itself).")
×
481
                 + " " + q_("Just don't forget to set it to Meade compatibility mode and set the baud rate to 9600B")
×
482
                 + "<sup><a href=\"http://www.iceinspace.com.au/forum/showpost.php?p=554948&amp;postcount=18\">1</a></sup>.</dd></dl>";
×
483
        helpPage += "<p><a href=\"#top\"><small>[" + q_("Back to top") + "]</small></a></p>";
×
484

485
        helpPage += "<h3><a name=\"virtual_telescope\" />" + q_("Virtual telescope") + "</h3>";
×
486
        helpPage += "<p>" + q_("If you want to test this plug-in without an actual device connected to the computer, choose <b>Nothing, just simulate one (a moving reticle)</b> in the <b>Telescope controlled by:</b> field. It will show a telescope reticle that will react in the same way as the reticle of a real telescope controlled by the plug-in.") + "</p>";
×
487
        helpPage += "<p>";
×
488
        // TRANSLATORS: The text between braces is the text of an HTML link.
489
        helpPage += q_("See the section above about {field of view indicators} for a possible practical application (emulating 'Telrad' circles).").replace(a_rx, "<a href=\"#fovcircles\">\\1</a>");
×
490
        helpPage += "</p>";
×
491
        helpPage += "<p>";
×
492
        // TRANSLATORS: The text between braces is the text of an HTML link.
493
        helpPage += q_("This feature is equivalent to the 'Dummy' type of telescope supported by {Stellarium's original telescope control feature}.").replace(a_rx, "<a href=\"http://stellarium.sourceforge.net/wiki/index.php/Telescope_Control_%28client-server%29\">\\1</a>");
×
494
        helpPage += "</p>";
×
495
        helpPage += "<p><a href=\"#top\"><small>[" + q_("Back to top") + "]</small></a></p>";
×
496

497
        helpPage += "</body></html>";
×
498
        
499
        StelGui* gui = dynamic_cast<StelGui*>(StelApp::getInstance().getGui());
×
500
        if (gui)
×
501
        {
502
                ui->textBrowserAbout->document()->setDefaultStyleSheet(QString(gui->getStelStyle().htmlStyleSheet));
×
503
                ui->textBrowserHelp->document()->setDefaultStyleSheet(QString(gui->getStelStyle().htmlStyleSheet));
×
504
        }
505
        ui->textBrowserAbout->setHtml(aboutPage);
×
506
        ui->textBrowserHelp->setHtml(helpPage);
×
507
}
×
508

509
void TelescopeDialog::setHeaderNames()
×
510
{
511
        const QStringList headerStrings = {
512
                // TRANSLATORS: Symbol for "number"
513
                qc_("#", "numero sign"),
514
                //"Start";
515
                q_("Status"),
516
                q_("Type"),
517
                q_("Name")};
×
518
        telescopeListModel->setHorizontalHeaderLabels(headerStrings);
×
519
}
×
520

521
void TelescopeDialog::updateWarningTexts()
×
522
{
523
        QString text;
×
524
        if (telescopeCount > 0)
×
525
        {
526
#ifdef Q_OS_MACOS
527
                QString modifierName = "Command";
528
#else
529
                QString modifierName = "Ctrl";
×
530
#endif
531
                
532
                text = QString(q_("To slew a connected telescope to an object (for example, a star), select that object, then hold down the %1 key and press the key with that telescope's number. To slew it to the center of the current view, hold down the Alt key and press the key with that telescope's number.")).arg(modifierName);
×
533
        }
×
534
        else
535
        {
536
                if (telescopeManager->getDeviceModels().isEmpty())
×
537
                {
538
                        // TRANSLATORS: Currently, it is very unlikely if not impossible to actually see this text. :)
539
                        text = q_("No device model descriptions are available. Stellarium will not be able to control a telescope on its own, but it is still possible to do it through an external application or to connect to a remote host.");
×
540
                }
541
                else
542
                {
543
                        // TRANSLATORS: The translated name of the Add button is automatically inserted.
544
                        text = QString(q_("Press the \"%1\" button to set up a new telescope connection.")).arg(ui->pushButtonAdd->text());
×
545
                }
546
        }
547
        
548
        ui->labelWarning->setText(text);
×
549
}
×
550

551
QString TelescopeDialog::getTypeLabel(TelescopeControl::ConnectionType type)
×
552
{
553
        static const QMap<TelescopeControl::ConnectionType, QString>map={
554
                // TRANSLATORS: Telescope connection type
555
                { TelescopeControl::ConnectionInternal, N_("local, Stellarium")},
×
556
                // TRANSLATORS: Telescope connection type
557
                { TelescopeControl::ConnectionLocal, N_("local, external")},
×
558
                // TRANSLATORS: Telescope connection type
559
                { TelescopeControl::ConnectionRemote, N_("remote, unknown")},
×
560
                // TRANSLATORS: Telescope connection type
561
                {TelescopeControl::ConnectionVirtual, N_("virtual")},
×
562
                // TRANSLATORS: Telescope connection type
563
                {TelescopeControl::ConnectionRTS2, N_("remote, RTS2")},
×
564
                // TRANSLATORS: Telescope connection type
565
                {TelescopeControl::ConnectionINDI, N_("remote, INDI/INDIGO")},
×
566
                // TRANSLATORS: Telescope connection type
567
                {TelescopeControl::ConnectionASCOM, N_("local, ASCOM")}};
×
568
        return map.value(type, "");
×
569
}
570

571
void TelescopeDialog::addModelRow(int number,
×
572
                                  TelescopeControl::ConnectionType type,
573
                                  TelescopeControl::TelescopeStatus status,
574
                                  const QString& name)
575
{
576
        Q_ASSERT(telescopeListModel);
×
577
        
578
        QStandardItem* tempItem = nullptr;
×
579
        int lastRow = telescopeListModel->rowCount();
×
580
        // Number
581
        tempItem = new QStandardItem(QString::number(number));
×
582
        tempItem->setEditable(false);
×
583
        telescopeListModel->setItem(lastRow, ColumnSlot, tempItem);
×
584
        
585
        // Checkbox
586
        //TODO: This is not updated, because it was commented out
587
        //tempItem = new QStandardItem;
588
        //tempItem->setEditable(false);
589
        //tempItem->setCheckable(true);
590
        //tempItem->setCheckState(Qt::Checked);
591
        //tempItem->setData("If checked, this telescope will start when Stellarium is started", Qt::ToolTipRole);
592
        //telescopeListModel->setItem(lastRow, ColumnStartup, tempItem);//Start-up checkbox
593
        
594
        //Status
595
        tempItem = new QStandardItem(q_(statusString.value((status))));
×
596
        tempItem->setEditable(false);
×
597
        telescopeListModel->setItem(lastRow, ColumnStatus, tempItem);
×
598
        
599
        //Type
600
        QString typeLabel = getTypeLabel(type);
×
601
        tempItem = new QStandardItem(q_(typeLabel));
×
602
        tempItem->setEditable(false);
×
603
        tempItem->setData(typeLabel, Qt::UserRole);
×
604
        telescopeListModel->setItem(lastRow, ColumnType, tempItem);
×
605
        
606
        //Name
607
        tempItem = new QStandardItem(name);
×
608
        tempItem->setEditable(false);
×
609
        telescopeListModel->setItem(lastRow, ColumnName, tempItem);
×
610
}
×
611

612
void TelescopeDialog::updateModelRow(int rowNumber,
×
613
                                     TelescopeControl::ConnectionType type,
614
                                     TelescopeControl::TelescopeStatus status,
615
                                     const QString& name)
616
{
617
        Q_ASSERT(telescopeListModel);
×
618
        if (rowNumber > telescopeListModel->rowCount())
×
619
                return;
×
620
        
621
        //The slot number doesn't need to be updated. :)
622
        //Status
623
        QString statusLabel = q_(statusString[status]);
×
624
        QModelIndex index = telescopeListModel->index(rowNumber, ColumnStatus);
×
625
        telescopeListModel->setData(index, statusLabel, Qt::DisplayRole);
×
626
        
627
        //Type
628
        QString typeLabel = getTypeLabel(type);
×
629
        index = telescopeListModel->index(rowNumber, ColumnType);
×
630
        telescopeListModel->setData(index, typeLabel, Qt::UserRole);
×
631
        telescopeListModel->setData(index, q_(typeLabel), Qt::DisplayRole);
×
632
        
633
        //Name
634
        index = telescopeListModel->index(rowNumber, ColumnName);
×
635
        telescopeListModel->setData(index, name, Qt::DisplayRole);
×
636
}
×
637

638

639
void TelescopeDialog::selectTelecope(const QModelIndex & index)
×
640
{
641
        //Extract selected item index
642
        int selectedSlot = telescopeListModel->data( telescopeListModel->index(index.row(),0) ).toInt();
×
643
        updateStatusButtonForSlot(selectedSlot);
×
644

645
        //In all cases
646
        ui->pushButtonRemove->setEnabled(true);
×
647
}
×
648

649
void TelescopeDialog::configureTelescope(const QModelIndex & currentIndex)
×
650
{
651
        configuredTelescopeIsNew = false;
×
652
        configuredSlot = telescopeListModel->data( telescopeListModel->index(currentIndex.row(), ColumnSlot) ).toInt();
×
653
        
654
        //Stop the telescope first if necessary
655
        if(connectionTypes[configuredSlot] != TelescopeControl::ConnectionInternal && telescopeStatus[configuredSlot] != TelescopeControl::StatusDisconnected)
×
656
        {
657
                if(telescopeManager->stopTelescopeAtSlot(configuredSlot)) //Act as "Disconnect"
×
658
                        telescopeStatus[configuredSlot] = TelescopeControl::StatusDisconnected;
×
659
                else
660
                        return;
×
661
        }
662
        else if(telescopeStatus[configuredSlot] != TelescopeControl::StatusStopped)
×
663
        {
664
                if(telescopeManager->stopTelescopeAtSlot(configuredSlot)) //Act as "Stop"
×
665
                        telescopeStatus[configuredSlot] = TelescopeControl::StatusStopped;
×
666
        }
667
        //Update the status in the list
668
        int curRow = ui->telescopeTreeView->currentIndex().row();
×
669
        QModelIndex curIndex = telescopeListModel->index(curRow, ColumnStatus);
×
670
        QString string = q_(statusString.value(telescopeStatus[configuredSlot]));
×
671
        telescopeListModel->setData(curIndex, string, Qt::DisplayRole);
×
672
        
673
        setVisible(false);
×
674
        configurationDialog.setVisible(true); //This should be called first to actually create the dialog content
×
675
        
676
        configurationDialog.initExistingTelescopeConfiguration(configuredSlot);
×
677
}
×
678

679
void TelescopeDialog::buttonChangeStatusPressed()
×
680
{
681
        if(!ui->telescopeTreeView->currentIndex().isValid())
×
682
                return;
×
683
        
684
        //Extract selected slot
685
        int selectedSlot = telescopeListModel->data( telescopeListModel->index(ui->telescopeTreeView->currentIndex().row(), ColumnSlot) ).toInt();
×
686
        
687
        //TODO: As most of these are asynchronous actions, it looks like that there should be a queue...
688
        
689
        if(connectionTypes[selectedSlot] != TelescopeControl::ConnectionInternal)
×
690
        {
691
                //Can't be launched by Stellarium -> can't be stopped by Stellarium
692
                //Can be only connected/disconnected
693
                if(telescopeStatus[selectedSlot] == TelescopeControl::StatusDisconnected)
×
694
                {
695
                        if(telescopeManager->startTelescopeAtSlot(selectedSlot)) //Act as "Connect"
×
696
                                telescopeStatus[selectedSlot] = TelescopeControl::StatusConnecting;
×
697
                }
698
                else
699
                {
700
                        if(telescopeManager->stopTelescopeAtSlot(selectedSlot)) //Act as "Disconnect"
×
701
                                telescopeStatus[selectedSlot] = TelescopeControl::StatusDisconnected;
×
702
                }
703
        }
704
        else
705
        {
706
                switch(telescopeStatus[selectedSlot]) //Why the switch?
×
707
                {
708
                        case TelescopeControl::StatusNA:
×
709
                        case TelescopeControl::StatusStopped:
710
                        {
711
                                if(telescopeManager->startTelescopeAtSlot(selectedSlot)) //Act as "Start"
×
712
                                        telescopeStatus[selectedSlot] = TelescopeControl::StatusConnecting;
×
713
                        }
714
                        break;
×
715
                        case TelescopeControl::StatusConnecting:
×
716
                        case TelescopeControl::StatusConnected:
717
                        {
718
                                if(telescopeManager->stopTelescopeAtSlot(selectedSlot)) //Act as "Stop"
×
719
                                        telescopeStatus[selectedSlot] = TelescopeControl::StatusStopped;
×
720
                        }
721
                        break;
×
722
                        default:
×
723
                                break;
×
724
                }
725
        }
726
        
727
        //Update the status in the list
728
        int curRow = ui->telescopeTreeView->currentIndex().row();
×
729
        QModelIndex curIndex = telescopeListModel->index(curRow, ColumnStatus);
×
730
        QString string = q_(statusString.value(telescopeStatus[selectedSlot]));
×
731
        telescopeListModel->setData(curIndex, string, Qt::DisplayRole);
×
732
}
733

734
void TelescopeDialog::buttonConfigurePressed()
×
735
{
736
        if(ui->telescopeTreeView->currentIndex().isValid())
×
737
                configureTelescope(ui->telescopeTreeView->currentIndex());
×
738
}
×
739

740
void TelescopeDialog::buttonAddPressed()
×
741
{
742
        if(telescopeCount >= TelescopeControl::SLOT_COUNT)
×
743
                return;
×
744
        
745
        configuredTelescopeIsNew = true;
×
746
        
747
        //Find the first unoccupied slot (there is at least one)
748
        for (configuredSlot = TelescopeControl::MIN_SLOT_NUMBER; configuredSlot < TelescopeControl::SLOT_NUMBER_LIMIT; configuredSlot++)
×
749
        {
750
                //configuredSlot = (i+1)%SLOT_COUNT;
751
                if(telescopeStatus[configuredSlot] == TelescopeControl::StatusNA)
×
752
                        break;
×
753
        }
754
        
755
        setVisible(false);
×
756
        configurationDialog.setVisible(true); //This should be called first to actually create the dialog content
×
757
        configurationDialog.initNewTelescopeConfiguration(configuredSlot);
×
758
}
759

760
void TelescopeDialog::buttonRemovePressed()
×
761
{
762
        if(!ui->telescopeTreeView->currentIndex().isValid())
×
763
                return;
×
764
        
765
        //Extract selected slot
766
        int selectedSlot = telescopeListModel->data( telescopeListModel->index(ui->telescopeTreeView->currentIndex().row(),0) ).toInt();
×
767
        
768
        //Stop the telescope if necessary and remove it
769
        if(telescopeManager->stopTelescopeAtSlot(selectedSlot))
×
770
        {
771
                //TODO: Update status?
772
                if(!telescopeManager->removeTelescopeAtSlot(selectedSlot))
×
773
                {
774
                        //TODO: Add debug
775
                        qDebug() << "Cannot remove telescope at slot" << selectedSlot;
×
776
                        return;
×
777
                }
778
        }
779
        else
780
        {
781
                //TODO: Add debug
782
                qDebug() << "Cannot stop telescope at slot" << selectedSlot << ". Rejecting removal.";
×
783
                return;
×
784
        }
785
        
786
        //Save the changes to file
787
        telescopeManager->saveTelescopes();
×
788
        
789
        telescopeStatus[selectedSlot] = TelescopeControl::StatusNA;
×
790
        telescopeCount -= 1;
×
791
        
792
//Update the interface to reflect the changes:
793
        
794
        //Make sure that the header section keeps it size
795
        if(telescopeCount == 0)
×
796
                ui->telescopeTreeView->header()->setSectionResizeMode(ColumnType, QHeaderView::Interactive);
×
797
        
798
        //Remove the telescope from the table/tree
799
        telescopeListModel->removeRow(ui->telescopeTreeView->currentIndex().row());
×
800
        
801
        //If there are less than the maximal number of telescopes now, new ones can be added
802
        if(telescopeCount < TelescopeControl::SLOT_COUNT)
×
803
                ui->pushButtonAdd->setEnabled(true);
×
804
        
805
        //If there are no telescopes left, disable some buttons
806
        if(telescopeCount == 0)
×
807
        {
808
                //TODO: Fix the phantom text of the Status button (reuse code?)
809
                //IDEA: Vsible/invisible instead of enabled/disabled?
810
                //The other buttons expand to take the place (delete spacers)
811
                ui->pushButtonChangeStatus->setEnabled(false);
×
812
                ui->pushButtonConfigure->setEnabled(false);
×
813
                ui->pushButtonRemove->setEnabled(false);
×
814
        }
815
        else
816
        {
817
                ui->telescopeTreeView->setCurrentIndex(telescopeListModel->index(0,0));
×
818
        }
819
        updateWarningTexts();
×
820
}
821

822
void TelescopeDialog::saveChanges(QString name, TelescopeControl::ConnectionType type)
×
823
{
824
        //Save the changes to file
825
        telescopeManager->saveTelescopes();
×
826
        
827
        //Type and server properties
828
        connectionTypes[configuredSlot] = type;
×
829
        switch (type)
×
830
        {
831
                case TelescopeControl::ConnectionVirtual:
×
832
                        telescopeStatus[configuredSlot] = TelescopeControl::StatusStopped;
×
833
                        break;
×
834

835
                case TelescopeControl::ConnectionInternal:
×
836
                        if(configuredTelescopeIsNew)
×
837
                                telescopeStatus[configuredSlot] = TelescopeControl::StatusStopped;//TODO: Is there a point? Isn't it better to force the status update method?
×
838
                        break;
×
839

840
                case TelescopeControl::ConnectionLocal:
×
841
                        telescopeStatus[configuredSlot] = TelescopeControl::StatusDisconnected;
×
842
                        break;
×
843

844
                case TelescopeControl::ConnectionRemote:
×
845
                default:
846
                        telescopeStatus[configuredSlot] = TelescopeControl::StatusDisconnected;
×
847
        }
848
        
849
        //Update the model/list
850
        TelescopeControl::TelescopeStatus status = telescopeStatus[configuredSlot];
×
851
        if(configuredTelescopeIsNew)
×
852
        {
853
                addModelRow(configuredSlot, type, status, name);
×
854
                telescopeCount++;
×
855
        }
856
        else
857
        {
858
                int currentRow = ui->telescopeTreeView->currentIndex().row();
×
859
                updateModelRow(currentRow, type, status, name);
×
860
        }
861
        //Sort the updated table by slot number
862
        ui->telescopeTreeView->sortByColumn(ColumnSlot, Qt::AscendingOrder);
×
863
        
864
        //Can't add more telescopes if they have reached the maximum number
865
        if (telescopeCount >= TelescopeControl::SLOT_COUNT)
×
866
                ui->pushButtonAdd->setEnabled(false);
×
867
        
868
        //
869
        if (telescopeCount == 0)
×
870
        {
871
                ui->pushButtonChangeStatus->setEnabled(false);
×
872
                ui->pushButtonConfigure->setEnabled(false);
×
873
                ui->pushButtonRemove->setEnabled(false);
×
874
                ui->telescopeTreeView->header()->setSectionResizeMode(ColumnType, QHeaderView::Interactive);
×
875
        }
876
        else
877
        {
878
                ui->telescopeTreeView->setFocus();
×
879
                ui->telescopeTreeView->setCurrentIndex(telescopeListModel->index(0,0));
×
880
                ui->pushButtonConfigure->setEnabled(true);
×
881
                ui->pushButtonRemove->setEnabled(true);
×
882
                ui->telescopeTreeView->header()->setSectionResizeMode(ColumnType, QHeaderView::ResizeToContents);
×
883
        }
884
        updateWarningTexts();
×
885
        
886
        configuredTelescopeIsNew = false;
×
887
        configurationDialog.setVisible(false);
×
888
        setVisible(true);//Brings the current window to the foreground
×
889
}
×
890

891
void TelescopeDialog::discardChanges()
×
892
{
893
        configurationDialog.setVisible(false);
×
894
        setVisible(true);//Brings the current window to the foreground
×
895
        
896
        if (telescopeCount >= TelescopeControl::SLOT_COUNT)
×
897
                ui->pushButtonAdd->setEnabled(false);
×
898
        if (telescopeCount == 0)
×
899
                ui->pushButtonRemove->setEnabled(false);
×
900
        
901
        configuredTelescopeIsNew = false;
×
902
}
×
903

904
void TelescopeDialog::updateTelescopeStates()
×
905
{
906
        if(telescopeCount == 0)
×
907
                return;
×
908
        
909
        int slotNumber = -1;
×
910
        for (int i=0; i<(telescopeListModel->rowCount()); i++)
×
911
        {
912
                slotNumber = telescopeListModel->data( telescopeListModel->index(i, ColumnSlot) ).toInt();
×
913
                //TODO: Check if these cover all possibilities
914
                if (telescopeManager->isConnectedClientAtSlot(slotNumber))
×
915
                {
916
                        telescopeStatus[slotNumber] = TelescopeControl::StatusConnected;
×
917
                }
918
                else if(telescopeManager->isExistingClientAtSlot(slotNumber))
×
919
                {
920
                        telescopeStatus[slotNumber] = TelescopeControl::StatusConnecting;
×
921
                }
922
                else
923
                {
924
                        if(connectionTypes[slotNumber] == TelescopeControl::ConnectionInternal)
×
925
                                telescopeStatus[slotNumber] = TelescopeControl::StatusStopped;
×
926
                        else
927
                                telescopeStatus[slotNumber] = TelescopeControl::StatusDisconnected;
×
928
                }
929
                
930
                //Update the status in the list
931
                QModelIndex index = telescopeListModel->index(i, ColumnStatus);
×
932
                QString statusStr = q_(statusString.value(telescopeStatus[slotNumber]));
×
933
                telescopeListModel->setData(index, statusStr, Qt::DisplayRole);
×
934
        }
×
935
        
936
        if(ui->telescopeTreeView->currentIndex().isValid())
×
937
        {
938
                int selectedSlot = telescopeListModel->data( telescopeListModel->index(ui->telescopeTreeView->currentIndex().row(), ColumnSlot) ).toInt();
×
939
                //Update the ChangeStatus button
940
                updateStatusButtonForSlot(selectedSlot);
×
941
        }
942
}
943

944
void TelescopeDialog::updateStatusButtonForSlot(int selectedSlot)
×
945
{
946
        if(connectionTypes[selectedSlot] != TelescopeControl::ConnectionInternal)
×
947
        {
948
                //Can't be launched by Stellarium => can't be stopped by Stellarium
949
                //Can be only connected/disconnected
950
                if(telescopeStatus[selectedSlot] == TelescopeControl::StatusDisconnected)
×
951
                {
952
                        setStatusButtonToConnect();
×
953
                        ui->pushButtonChangeStatus->setEnabled(true);
×
954
                }
955
                else
956
                {
957
                        setStatusButtonToDisconnect();
×
958
                        ui->pushButtonChangeStatus->setEnabled(true);
×
959
                }
960
        }
961
        else
962
        {
963
                switch(telescopeStatus[selectedSlot])
×
964
                {
965
                        case TelescopeControl::StatusNA:
×
966
                        case TelescopeControl::StatusStopped:
967
                                setStatusButtonToStart();
×
968
                                ui->pushButtonChangeStatus->setEnabled(true);
×
969
                                break;
×
970
                        case TelescopeControl::StatusConnected:
×
971
                        case TelescopeControl::StatusConnecting:
972
                                setStatusButtonToStop();
×
973
                                ui->pushButtonChangeStatus->setEnabled(true);
×
974
                                break;
×
975
                        default:
×
976
                                setStatusButtonToStart();
×
977
                                ui->pushButtonChangeStatus->setEnabled(false);
×
978
                                ui->pushButtonConfigure->setEnabled(false);
×
979
                                ui->pushButtonRemove->setEnabled(false);
×
980
                                break;
×
981
                }
982
        }
983
}
×
984

985
void TelescopeDialog::setStatusButtonToStart()
×
986
{
987
        ui->pushButtonChangeStatus->setText(q_("Start"));
×
988
        ui->pushButtonChangeStatus->setIcon(QIcon(":/graphicGui/uibtStart.png"));
×
989
        ui->pushButtonChangeStatus->setToolTip(q_("Start the selected local telescope"));
×
990
}
×
991

992
void TelescopeDialog::setStatusButtonToStop()
×
993
{
994
        ui->pushButtonChangeStatus->setText(q_("Stop"));
×
995
        ui->pushButtonChangeStatus->setIcon(QIcon(":/graphicGui/uibtStop.png"));
×
996
        ui->pushButtonChangeStatus->setToolTip(q_("Stop the selected local telescope"));
×
997
}
×
998

999
void TelescopeDialog::setStatusButtonToConnect()
×
1000
{
1001
        ui->pushButtonChangeStatus->setText(q_("Connect"));
×
1002
        ui->pushButtonChangeStatus->setIcon(QIcon(":/graphicGui/uibtStart.png"));
×
1003
        ui->pushButtonChangeStatus->setToolTip(q_("Connect to the selected telescope"));
×
1004
}
×
1005

1006
void TelescopeDialog::setStatusButtonToDisconnect()
×
1007
{
1008
        ui->pushButtonChangeStatus->setText(q_("Disconnect"));
×
1009
        ui->pushButtonChangeStatus->setIcon(QIcon(":/graphicGui/uibtStop.png"));
×
1010
        ui->pushButtonChangeStatus->setToolTip(q_("Disconnect from the selected telescope"));
×
1011
}
×
1012

1013
void TelescopeDialog::updateStyle()
×
1014
{
1015
        if (dialog)
×
1016
        {
1017
                StelGui* gui = dynamic_cast<StelGui*>(StelApp::getInstance().getGui());
×
1018
                if (gui)
×
1019
                        ui->textBrowserAbout->document()->setDefaultStyleSheet(gui->getStelStyle().htmlStyleSheet);
×
1020
        }
1021
}
×
1022

1023
void TelescopeDialog::buttonBrowseServerDirectoryPressed()
×
1024
{
1025
        QString newPath = QFileDialog::getExistingDirectory (&StelMainView::getInstance(), QString(q_("Select a directory")), telescopeManager->getServerExecutablesDirectoryPath());
×
1026
        //TODO: Validation? Directory exists and contains servers?
1027
        if(!newPath.isEmpty())
×
1028
        {
1029
                ui->lineEditExecutablesDirectory->setText(newPath);
×
1030
                telescopeManager->setServerExecutablesDirectoryPath(newPath);
×
1031
                telescopeManager->setFlagUseServerExecutables(true);
×
1032
        }
1033
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc