1 /*
2  * Stellarium Novae Plug-in GUI
3  *
4  * Copyright (C) 2013 Alexander Wolf
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 <QDebug>
22 #include <QTimer>
23 #include <QDateTime>
24 #include <QUrl>
25 #include <QFileDialog>
26 
27 #include "StelApp.hpp"
28 #include "StelCore.hpp"
29 #include "ui_novaeDialog.h"
30 #include "NovaeDialog.hpp"
31 #include "Novae.hpp"
32 #include "StelModuleMgr.hpp"
33 #include "StelObjectMgr.hpp"
34 #include "StelMovementMgr.hpp"
35 #include "StelStyle.hpp"
36 #include "StelGui.hpp"
37 #include "StelFileMgr.hpp"
38 #include "StelTranslator.hpp"
39 
NovaeDialog()40 NovaeDialog::NovaeDialog()
41 	: StelDialog("Novae")
42 	, nova(Q_NULLPTR)
43 	, updateTimer(Q_NULLPTR)
44 {
45 	ui = new Ui_novaeDialog;
46 }
47 
~NovaeDialog()48 NovaeDialog::~NovaeDialog()
49 {
50 	if (updateTimer)
51 	{
52 		updateTimer->stop();
53 		delete updateTimer;
54 		updateTimer = Q_NULLPTR;
55 	}
56 	delete ui;
57 }
58 
retranslate()59 void NovaeDialog::retranslate()
60 {
61 	if (dialog)
62 	{
63 		ui->retranslateUi(dialog);
64 		refreshUpdateValues();
65 		setAboutHtml();
66 	}
67 }
68 
69 // Initialize the dialog widgets and connect the signals/slots
createDialogContent()70 void NovaeDialog::createDialogContent()
71 {
72 	nova = GETSTELMODULE(Novae);
73 	ui->setupUi(dialog);
74 	ui->tabs->setCurrentIndex(0);
75 	connect(&StelApp::getInstance(), SIGNAL(languageChanged()),
76 		this, SLOT(retranslate()));
77 
78 	// Kinetic scrolling
79 	kineticScrollingList << ui->aboutTextBrowser;
80 	StelGui* gui= dynamic_cast<StelGui*>(StelApp::getInstance().getGui());
81 	if (gui)
82 	{
83 		enableKineticScrolling(gui->getFlagUseKineticScrolling());
84 		connect(gui, SIGNAL(flagUseKineticScrollingChanged(bool)), this, SLOT(enableKineticScrolling(bool)));
85 	}
86 
87 
88 	// Settings tab / updates group
89 	connect(ui->internetUpdatesCheckbox, SIGNAL(stateChanged(int)), this, SLOT(setUpdatesEnabled(int)));
90 	connect(ui->updateButton, SIGNAL(clicked()), this, SLOT(updateJSON()));
91 	connect(nova, SIGNAL(updateStateChanged(Novae::UpdateState)), this, SLOT(updateStateReceiver(Novae::UpdateState)));
92 	connect(nova, SIGNAL(jsonUpdateComplete(void)), this, SLOT(updateCompleteReceiver(void)));
93 	connect(ui->updateFrequencySpinBox, SIGNAL(valueChanged(int)), this, SLOT(setUpdateValues(int)));
94 	refreshUpdateValues(); // fetch values for last updated and so on
95 	// if the state didn't change, setUpdatesEnabled will not be called, so we force it
96 	setUpdatesEnabled(ui->internetUpdatesCheckbox->checkState());
97 
98 	updateTimer = new QTimer(this);
99 	connect(updateTimer, SIGNAL(timeout()), this, SLOT(refreshUpdateValues()));
100 	updateTimer->start(7000);
101 
102 	connect(ui->closeStelWindow, SIGNAL(clicked()), this, SLOT(close()));
103 	connect(ui->TitleBar, SIGNAL(movedTo(QPoint)), this, SLOT(handleMovedTo(QPoint)));
104 
105 	connect(ui->restoreDefaultsButton, SIGNAL(clicked()), this, SLOT(restoreDefaults()));
106 	connect(ui->saveSettingsButton, SIGNAL(clicked()), this, SLOT(saveSettings()));
107 
108 	// About tab
109 	setAboutHtml();
110 
111 	updateGuiFromSettings();
112 }
113 
setAboutHtml(void)114 void NovaeDialog::setAboutHtml(void)
115 {
116 	QString html = "<html><head></head><body>";
117 	html += "<h2>" + q_("Bright Novae Plug-in") + "</h2><table width=\"90%\">";
118 	html += "<tr width=\"30%\"><td><strong>" + q_("Version") + ":</strong></td><td>" + NOVAE_PLUGIN_VERSION + "</td></tr>";
119 	html += "<tr><td><strong>" + q_("License") + ":</strong></td><td>" + NOVAE_PLUGIN_LICENSE + "</td></tr>";
120 	html += "<tr><td><strong>" + q_("Author") + ":</strong></td><td>Alexander Wolf</td></tr>";
121 	html += "</table>";
122 
123 	html += "<p>" + q_("A plugin that shows some bright novae in the Milky Way galaxy.");
124 	html += " " + q_("You can find novae via search tool by entering designation of nova or its common name (e.g. 'Nova Cygni 1975' or 'V1500 Cyg').") + "</p>";
125 
126 	html += "<p>" + q_("This plugin allows you to see recent bright novae: ");
127 	html += nova->getNovaeList();
128 	html += ". " + q_("This list altogether contains %1 stars.").arg(nova->getCountNovae());
129 	html += " " + q_("All those novae are brighter than %1 at peak of brightness.").arg(QString::number(nova->getLowerLimitBrightness(), 'f', 2) + "<sup>m</sup>") + "</p>";
130 	html += "<h3>" + q_("Light curves") + "</h3>";
131 	html += q_("This plugin uses a very simple model for calculation of light curves for novae stars.") + " ";
132 	html += q_("This model is based on time for decay by %1 magnitudes from the maximum value, where %1 is 2, 3, 6 and 9.").arg("<em>N</em>") + " ";
133 	html += q_("If a nova has no values for decay of magnitude then this plugin will use generalized values for it.");
134 	html += "<p>";
135 
136 	html += StelApp::getInstance().getModuleMgr().getStandardSupportLinksInfo("Bright Novae plugin");
137 	html += "</body></html>";
138 
139 	StelGui* gui = dynamic_cast<StelGui*>(StelApp::getInstance().getGui());
140 	if(gui!=Q_NULLPTR)
141 	{
142 		QString htmlStyleSheet(gui->getStelStyle().htmlStyleSheet);
143 		ui->aboutTextBrowser->document()->setDefaultStyleSheet(htmlStyleSheet);
144 	}
145 
146 	ui->aboutTextBrowser->setHtml(html);
147 }
148 
refreshUpdateValues(void)149 void NovaeDialog::refreshUpdateValues(void)
150 {
151 	QString nextUpdate = q_("Next update");
152 	ui->lastUpdateDateTimeEdit->setDateTime(nova->getLastUpdate());
153 	ui->updateFrequencySpinBox->setValue(nova->getUpdateFrequencyDays());
154 	int secondsToUpdate = nova->getSecondsToUpdate();
155 	ui->internetUpdatesCheckbox->setChecked(nova->getUpdatesEnabled());
156 	if (!nova->getUpdatesEnabled())
157 		ui->nextUpdateLabel->setText(q_("Internet updates disabled"));
158 	else if (nova->getUpdateState() == Novae::Updating)
159 		ui->nextUpdateLabel->setText(q_("Updating now..."));
160 	else if (secondsToUpdate <= 60)
161 		ui->nextUpdateLabel->setText(QString("%1: %2").arg(nextUpdate, q_("< 1 minute")));
162 	else if (secondsToUpdate < 3600)
163 	{
164 		int n = (secondsToUpdate/60)+1;
165 		// TRANSLATORS: minutes.
166 		ui->nextUpdateLabel->setText(QString("%1: %2 %3").arg(nextUpdate, QString::number(n), qc_("m", "time")));
167 	}
168 	else if (secondsToUpdate < 86400)
169 	{
170 		int n = (secondsToUpdate/3600)+1;
171 		// TRANSLATORS: hours.
172 		ui->nextUpdateLabel->setText(QString("%1: %2 %3").arg(nextUpdate, QString::number(n), qc_("h", "time")));
173 	}
174 	else
175 	{
176 		int n = (secondsToUpdate/86400)+1;
177 		// TRANSLATORS: days.
178 		ui->nextUpdateLabel->setText(QString("%1: %2 %3").arg(nextUpdate, QString::number(n), qc_("d", "time")));
179 	}
180 }
181 
setUpdateValues(int days)182 void NovaeDialog::setUpdateValues(int days)
183 {
184 	nova->setUpdateFrequencyDays(days);
185 	refreshUpdateValues();
186 }
187 
setUpdatesEnabled(int checkState)188 void NovaeDialog::setUpdatesEnabled(int checkState)
189 {
190 	bool b = checkState != Qt::Unchecked;
191 	nova->setUpdatesEnabled(b);
192 	ui->updateFrequencySpinBox->setEnabled(b);
193 	if(b)
194 		ui->updateButton->setText(q_("Update now"));
195 	else
196 		ui->updateButton->setText(q_("Update from files"));
197 
198 	refreshUpdateValues();
199 }
200 
updateStateReceiver(Novae::UpdateState state)201 void NovaeDialog::updateStateReceiver(Novae::UpdateState state)
202 {
203 	//qDebug() << "NovaeDialog::updateStateReceiver got a signal";
204 	if (state==Novae::Updating)
205 		ui->nextUpdateLabel->setText(q_("Updating now..."));
206 	else if (state==Novae::DownloadError || state==Novae::OtherError)
207 	{
208 		ui->nextUpdateLabel->setText(q_("Update error"));
209 		updateTimer->start();  // make sure message is displayed for a while...
210 	}
211 }
212 
updateCompleteReceiver(void)213 void NovaeDialog::updateCompleteReceiver(void)
214 {
215 	ui->nextUpdateLabel->setText(QString(q_("Novae is updated")));
216 	// display the status for another full interval before refreshing status
217 	updateTimer->start();
218 	ui->lastUpdateDateTimeEdit->setDateTime(nova->getLastUpdate());
219 	QTimer *timer = new QTimer(this);
220 	connect(timer, SIGNAL(timeout()), this, SLOT(refreshUpdateValues()));
221 	setAboutHtml();
222 }
223 
restoreDefaults(void)224 void NovaeDialog::restoreDefaults(void)
225 {
226 	if (askConfirmation())
227 	{
228 		qDebug() << "[Novae] restore defaults...";
229 		nova->restoreDefaults();
230 		nova->readSettingsFromConfig();
231 		updateGuiFromSettings();
232 	}
233 	else
234 		qDebug() << "[Novae] restore defaults is canceled...";
235 }
236 
updateGuiFromSettings(void)237 void NovaeDialog::updateGuiFromSettings(void)
238 {
239 	ui->internetUpdatesCheckbox->setChecked(nova->getUpdatesEnabled());
240 	refreshUpdateValues();
241 }
242 
saveSettings(void)243 void NovaeDialog::saveSettings(void)
244 {
245 	nova->saveSettingsToConfig();
246 }
247 
updateJSON(void)248 void NovaeDialog::updateJSON(void)
249 {
250 	if(nova->getUpdatesEnabled())
251 	{
252 		nova->updateJSON();
253 	}
254 }
255