1 /*
2  * Navigational Stars plug-in
3  * Copyright (C) 2014-2016 Alexander Wolf
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA  02110-1335, USA.
18  */
19 
20 #include "StelProjector.hpp"
21 #include "StelPainter.hpp"
22 #include "StelApp.hpp"
23 #include "StelCore.hpp"
24 #include "StelGui.hpp"
25 #include "StelGuiItems.hpp"
26 #include "StelModuleMgr.hpp"
27 #include "StelTextureMgr.hpp"
28 #include "StelTranslator.hpp"
29 #include "StelFileMgr.hpp"
30 #include "StelObjectMgr.hpp"
31 #include "StarMgr.hpp"
32 #include "StelPropertyMgr.hpp"
33 #include "StelUtils.hpp"
34 #include "NavStars.hpp"
35 #include "NavStarsWindow.hpp"
36 #include "NavStarsCalculator.hpp"
37 #include "Planet.hpp"
38 
39 #include <QList>
40 #include <QSharedPointer>
41 #include <QMetaEnum>
42 
43 #include "planetsephems/sidereal_time.h"
44 
getStelModule() const45 StelModule* NavStarsStelPluginInterface::getStelModule() const
46 {
47 	return new NavStars();
48 }
49 
getPluginInfo() const50 StelPluginInfo NavStarsStelPluginInterface::getPluginInfo() const
51 {
52 	Q_INIT_RESOURCE(NavStars);
53 
54 	StelPluginInfo info;
55 	info.id = "NavStars";
56 	info.displayedName = N_("Navigational Stars");
57 	info.authors = "Alexander Wolf, Andy Kirkham";
58 	info.contact = STELLARIUM_URL;
59 	info.description = N_("This plugin marks navigational stars from a selected set.");
60 	info.version = NAVSTARS_PLUGIN_VERSION;
61 	info.license = NAVSTARS_PLUGIN_LICENSE;
62 	return info;
63 }
64 
NavStars()65 NavStars::NavStars()
66 	: currentNSSet(AngloAmerican)
67 	, enableAtStartup(false)
68 	, starLabelsState(true)
69 	, upperLimb(false)
70 	, highlightWhenVisible(false)
71 	, limitInfoToNavStars(false)
72 	, tabulatedDisplay(false)
73 	, useUTCTime(false)
74 	, toolbarButton(Q_NULLPTR)
75 {
76 	setObjectName("NavStars");
77 	conf = StelApp::getInstance().getSettings();
78 	propMgr = StelApp::getInstance().getStelPropertyManager();
79 	mainWindow = new NavStarsWindow();
80 	permittedObjects.push_back(QStringLiteral("Sun"));
81 	permittedObjects.push_back(QStringLiteral("Moon"));
82 	permittedObjects.push_back(QStringLiteral("Venus"));
83 	permittedObjects.push_back(QStringLiteral("Mars"));
84 	permittedObjects.push_back(QStringLiteral("Jupiter"));
85 	permittedObjects.push_back(QStringLiteral("Saturn"));
86 }
87 
~NavStars()88 NavStars::~NavStars()
89 {
90 	delete mainWindow;
91 }
92 
getCallOrder(StelModuleActionName actionName) const93 double NavStars::getCallOrder(StelModuleActionName actionName) const
94 {
95 	if (actionName == StelModule::ActionDraw)
96 		return StelApp::getInstance()
97 		        .getModuleMgr()
98 		        .getModule("ConstellationMgr")->getCallOrder(actionName)+10.;
99 	return 0;
100 }
101 
init()102 void NavStars::init()
103 {
104 	if (!conf->childGroups().contains("NavigationalStars"))
105 	{
106 		qDebug() << "[NavStars] no coordinates section exists in main config file - creating with defaults";
107 		restoreDefaultConfiguration();
108 	}
109 	// save default state for star labels and time zone
110 	starLabelsState = propMgr->getStelPropertyValue("StarMgr.flagLabelsDisplayed").toBool();
111 	timeZone = propMgr->getStelPropertyValue("StelCore.currentTimeZone").toString();
112 
113 	// populate settings from main config file.
114 	loadConfiguration();
115 
116 	// populate list of navigational stars
117 	populateNavigationalStarsSet();
118 
119 	setNavStarsMarks(getEnableAtStartup());
120 
121 	// Marker texture - using the same texture as the planet hints.
122 	QString path = StelFileMgr::findFile("textures/planet-indicator.png");
123 	markerTexture = StelApp::getInstance().getTextureManager().createTexture(path);
124 
125 	// key bindings and other actions
126 	addAction("actionShow_NavStars",        N_("Navigational Stars"), N_("Mark the navigational stars"), "navStarsVisible");
127 	addAction("actionShow_NavStars_dialog", N_("Navigational Stars"), N_("Show settings dialog"),        mainWindow, "visible");
128 
129 	connect(StelApp::getInstance().getCore(), SIGNAL(configurationDataSaved()), this, SLOT(saveSettings()));
130 	connect(&StelApp::getInstance(), SIGNAL(flagShowDecimalDegreesChanged(bool)), this, SLOT(setUseDecimalDegrees(bool)));
131 	setUseDecimalDegrees(StelApp::getInstance().getFlagShowDecimalDegrees());
132 
133 	// Toolbar button
134 	StelGui* gui = dynamic_cast<StelGui*>(StelApp::getInstance().getGui());
135 	if (gui!=Q_NULLPTR)
136 	{
137 		if (toolbarButton == Q_NULLPTR)
138 		{
139 			// Create the nav. stars button
140 			toolbarButton = new StelButton(Q_NULLPTR,
141 						       QPixmap(":/NavStars/btNavStars-on.png"),
142 						       QPixmap(":/NavStars/btNavStars-off.png"),
143 						       QPixmap(":/graphicGui/miscGlow32x32.png"),
144 						       "actionShow_NavStars",
145 						       false,
146 						       "actionShow_NavStars_dialog");
147 		}
148 		gui->getButtonBar()->addButton(toolbarButton, "065-pluginsGroup");
149 	}
150 }
151 
deinit()152 void NavStars::deinit()
153 {
154 	if (getFlagUseUTCTime())
155 		propMgr->setStelPropertyValue("StelCore.currentTimeZone", timeZone);
156 	markerTexture.clear();
157 	stars.clear();
158 	starNumbers.clear();
159 }
160 
configureGui(bool show)161 bool NavStars::configureGui(bool show)
162 {
163 	if (show)
164 	{
165 		mainWindow->setVisible(true);
166 	}
167 
168 	return true;
169 }
170 
draw(StelCore * core)171 void NavStars::draw(StelCore* core)
172 {
173 	// Drawing is enabled?
174 	if (markerFader.getInterstate() <= 0.0f)
175 	{
176 		return;
177 	}
178 
179 	QList<int> sn = getStarsNumbers();
180 
181 	if (stars.isEmpty())
182 	{
183 		StelObjectMgr* omgr = GETSTELMODULE(StelObjectMgr);
184 		stars.fill(StelObjectP(), sn.size());
185 		for (int i = 0; i < sn.size(); ++i)
186 		{
187 			QString name = QString("HIP %1").arg(sn.at(i));
188 			stars[i] = omgr->searchByName(name);
189 		}
190 	}
191 
192 	StelProjectorP prj = core->getProjection(StelCore::FrameJ2000);
193 	StelPainter painter(prj);
194 	float mlimit = core->getSkyDrawer()->getLimitMagnitude();
195 
196 	Vec3d pos;
197 	for (int i = 0; i < sn.size(); ++i)
198 	{
199 		if (stars[i].isNull())
200 			continue;
201 
202 		// Don't show if magnitude too low for visibility.
203 		if (highlightWhenVisible && stars[i]->getVMagnitude(core) > mlimit)
204 			continue;
205 
206 		// Get the current position of the navigational star...
207 		if (prj->projectCheck(stars[i]->getJ2000EquatorialPos(core), pos))
208 		{
209 			// ... and draw a marker around it
210 			if (!markerTexture.isNull())
211 			{
212 				painter.setBlending(true);
213 				painter.setColor(markerColor[0], markerColor[1], markerColor[2], markerFader.getInterstate());
214 				markerTexture->bind();
215 				painter.drawSprite2dMode(static_cast<float>(pos[0]), static_cast<float>(pos[1]), 11.f);
216 			}
217 
218 			// Draw the localized name of the star and its ordinal number
219 			QString label = stars[i]->getNameI18n();
220 			if (label.isEmpty())
221 				label = QString("%1").arg(i+1);
222 			else
223 				label = QString("%1 (%2)").arg(label).arg(i+1);
224 			painter.drawText(static_cast<float>(pos[0]), static_cast<float>(pos[1]), label, 0, 10.f, 10.f, false);
225 		}
226 	}
227 
228 	addExtraInfo(core);
229 }
230 
update(double deltaTime)231 void NavStars::update(double deltaTime)
232 {
233 	markerFader.update(static_cast<int>(deltaTime*1000));
234 }
235 
setNavStarsMarks(const bool b)236 void NavStars::setNavStarsMarks(const bool b)
237 {
238 	if (b==getNavStarsMarks())
239 		return;
240 
241 	propMgr->setStelPropertyValue("StarMgr.flagLabelsDisplayed", b ? !b : starLabelsState);
242 
243 	if (getFlagUseUTCTime())
244 		propMgr->setStelPropertyValue("StelCore.currentTimeZone", b ? "UTC" : timeZone);
245 
246 	markerFader = b;
247 	emit navStarsMarksChanged(b);
248 }
249 
getNavStarsMarks() const250 bool NavStars::getNavStarsMarks() const
251 {
252 	return markerFader;
253 }
254 
setEnableAtStartup(bool b)255 void NavStars::setEnableAtStartup(bool b)
256 {
257 	if (b!=getEnableAtStartup())
258 	{
259 		enableAtStartup=b;
260 		emit enableAtStartupChanged(b);
261 	}
262 }
263 
setHighlightWhenVisible(bool b)264 void NavStars::setHighlightWhenVisible(bool b)
265 {
266 	if (b!=getHighlightWhenVisible())
267 	{
268 		highlightWhenVisible=b;
269 		emit highlightWhenVisibleChanged(b);
270 	}
271 }
272 
setLimitInfoToNavStars(bool b)273 void NavStars::setLimitInfoToNavStars(bool b)
274 {
275 	if (b!=getLimitInfoToNavStars())
276 	{
277 		limitInfoToNavStars=b;
278 		emit limitInfoToNavStarsChanged(b);
279 	}
280 }
281 
setUpperLimb(bool b)282 void NavStars::setUpperLimb(bool b)
283 {
284 	if (b!=getUpperLimb())
285 	{
286 		upperLimb=b;
287 		emit upperLimbChanged(b);
288 	}
289 }
290 
setTabulatedDisplay(bool b)291 void NavStars::setTabulatedDisplay(bool b)
292 {
293 	if (b!=getTabulatedDisplay())
294 	{
295 		tabulatedDisplay=b;
296 		emit tabulatedDisplayChanged(b);
297 	}
298 }
299 
setFlagUseUTCTime(bool b)300 void NavStars::setFlagUseUTCTime(bool b)
301 {
302 	if (b!=getFlagUseUTCTime())
303 	{
304 		useUTCTime=b;
305 		emit flagUseUTCTimeChanged(b);
306 
307 		if (getNavStarsMarks())
308 			propMgr->setStelPropertyValue("StelCore.currentTimeZone", b ? "UTC" : timeZone);
309 	}
310 }
311 
setShowExtraDecimals(bool b)312 void NavStars::setShowExtraDecimals(bool b)
313 {
314 	if (b!=getShowExtraDecimals())
315 	{
316 		NavStarsCalculator::useExtraDecimals=b;
317 		emit showExtraDecimalsChanged(b);
318 	}
319 }
320 
setUseDecimalDegrees(bool flag)321 void NavStars::setUseDecimalDegrees(bool flag)
322 {
323 	NavStarsCalculator::useDecimalDegrees = flag;
324 }
325 
restoreDefaultConfiguration(void)326 void NavStars::restoreDefaultConfiguration(void)
327 {
328 	// Remove the whole section from the configuration file
329 	conf->remove("NavigationalStars");
330 	// Load the default values...
331 	loadConfiguration();
332 	// ... then save them.
333 	saveConfiguration();
334 }
335 
loadConfiguration(void)336 void NavStars::loadConfiguration(void)
337 {
338 	conf->beginGroup("NavigationalStars");
339 
340 	setCurrentNavigationalStarsSetKey(conf->value("current_ns_set", "AngloAmerican").toString());
341 	markerColor = Vec3f(conf->value("marker_color", "0.8,0.0,0.0").toString());
342 	enableAtStartup = conf->value("enable_at_startup", false).toBool();
343 	highlightWhenVisible = conf->value("highlight_when_visible", false).toBool();
344 	limitInfoToNavStars  = conf->value("limit_info_to_nav_stars", false).toBool();
345 	tabulatedDisplay = conf->value("tabulated_display", false).toBool();
346 	upperLimb = conf->value("upper_limb", false).toBool();
347 	setShowExtraDecimals(conf->value("extra_decimals", false).toBool());
348 	useUTCTime = conf->value("use_utc_time", false).toBool();
349 
350 	conf->endGroup();
351 }
352 
saveConfiguration(void)353 void NavStars::saveConfiguration(void)
354 {
355 	conf->beginGroup("NavigationalStars");
356 
357 	conf->setValue("current_ns_set", getCurrentNavigationalStarsSetKey());
358 	conf->setValue("marker_color", markerColor.toStr());
359 	conf->setValue("enable_at_startup", getEnableAtStartup());
360 	conf->setValue("highlight_when_visible", getHighlightWhenVisible());
361 	conf->setValue("limit_info_to_nav_stars", getLimitInfoToNavStars());
362 	conf->setValue("tabulated_display", getTabulatedDisplay());
363 	conf->setValue("upper_limb", getUpperLimb());
364 	conf->setValue("extra_decimals", getShowExtraDecimals());
365 	conf->setValue("use_utc_time", getFlagUseUTCTime());
366 
367 	conf->endGroup();
368 }
369 
setCurrentNavigationalStarsSetKey(QString key)370 void NavStars::setCurrentNavigationalStarsSetKey(QString key)
371 {
372 	const QMetaEnum& en = metaObject()->enumerator(metaObject()->indexOfEnumerator("NavigationalStarsSet"));
373 	NavigationalStarsSet nsSet = static_cast<NavigationalStarsSet>(en.keyToValue(key.toLatin1().data()));
374 	if (nsSet<0)
375 	{
376 		qWarning() << "Unknown navigational stars set:" << key << "setting \"AngloAmerican\" instead";
377 		nsSet = AngloAmerican;
378 	}
379 	setCurrentNavigationalStarsSet(nsSet);
380 	populateNavigationalStarsSet();
381 }
382 
getCurrentNavigationalStarsSetKey() const383 QString NavStars::getCurrentNavigationalStarsSetKey() const
384 {
385 	return metaObject()->enumerator(metaObject()->indexOfEnumerator("NavigationalStarsSet")).key(currentNSSet);
386 }
387 
getCurrentNavigationalStarsSetDescription() const388 QString NavStars::getCurrentNavigationalStarsSetDescription() const
389 {
390 	QString txt = "";
391 
392 	switch(getCurrentNavigationalStarsSet())
393 	{
394 		case AngloAmerican:
395 		{
396 			// TRANSLATORS: The emphasis tags mark a title.
397 			txt = q_("The 57 \"selected stars\" that are listed in <em>The Nautical Almanac</em> jointly published by Her Majesty's Nautical Almanac Office and the US Naval Observatory since 1958; consequently, these stars are also used in navigational aids such as the <em>2102D Star Finder</em> and <em>Identifier</em>.");
398 			break;
399 		}
400 		case French:
401 		{
402 			// TRANSLATORS: The emphasis tags mark a book title.
403 			txt = q_("The 81 stars that are listed in the French Nautical Almanac (The original French title is <em>%1</em>) published by the French Bureau des Longitudes.").arg("Ephémérides Nautiques");
404 			break;
405 		}
406 		case Russian:
407 		{
408 			// TRANSLATORS: The emphasis tags mark a book title.
409 			txt = q_("The 160 stars that are listed in the Russian Nautical Almanac (The original Russian title is <em>%1</em>).").arg("Морской астрономический ежегодник");
410 			break;
411 		}
412 		case German:
413 		{
414 			// TRANSLATORS: The emphasis tags mark a book title.
415 			txt = q_("The 80 stars that are listed in the German Nautical Almanac (The original German title is <em>%1</em>) published by the Federal Maritime and Hydrographic Agency of Germany.").arg("Nautisches Jahrbuch");
416 			break;
417 		}
418 	}
419 
420 	return txt;
421 }
422 
populateNavigationalStarsSet(void)423 void NavStars::populateNavigationalStarsSet(void)
424 {
425 	bool currentState = getNavStarsMarks();
426 
427 	setNavStarsMarks(false);
428 	stars.clear();
429 	starNumbers.clear();
430 
431 	// List of HIP numbers of the navigational stars:
432 	switch(getCurrentNavigationalStarsSet())
433 	{
434 		case AngloAmerican:
435 		{
436 			// 57 "selected stars" from The Nautical Almanac.
437 			starNumbers <<    677 <<   2081 <<   3179 <<   3419 <<   7588 <<   9884 <<  13847
438 				    <<  14135 <<  15863 <<  21421 <<  24436 <<  24608 <<  25336 <<  25428
439 				    <<  26311 <<  27989 <<  30438 <<  32349 <<  33579 <<  37279 <<  37826
440 				    <<  41037 <<  44816 <<  45238 <<  46390 <<  49669 <<  54061 <<  57632
441 				    <<  59803 <<  60718 <<  61084 <<  62956 <<  65474 <<  67301 <<  68702
442 				    <<  68933 <<  69673 <<  71683 <<  72603 <<  72607 <<  76267 <<  80763
443 				    <<  82273 <<  84012 <<  85927 <<  86032 <<  87833 <<  90185 <<  91262
444 				    <<  92855 <<  97649 << 100751 << 102098 << 107315 << 109268 << 113368
445 				    << 113963;
446 			break;
447 		}
448 		case French:
449 		{
450 			// 81 stars from French Nautical Almanac
451 			// Original French name: Ephémérides Nautiques
452 			starNumbers <<    677 <<    746 <<   1067 <<   2081 <<   3179 <<   3419 <<   4427
453 				    <<   5447 <<   7588 <<   9884 <<  11767 <<  14135 <<  14576 <<  15863
454 				    <<  21421 <<  24436 <<  24608 <<  25336 <<  25428 <<  26311 <<  26727
455 				    <<  27989 <<  28360 <<  30324 <<  30438 <<  31681 <<  32349 <<  33579
456 				    <<  34444 <<  36850 <<  37279 <<  37826 <<  39429 <<  39953 <<  41037
457 				    <<  42913 <<  44816 <<  45238 <<  45556 <<  46390 <<  49669 <<  53910
458 				    <<  54061 <<  54872 <<  57632 <<  58001 <<  59803 <<  60718 <<  61084
459 				    <<  61932 <<  62434 <<  62956 <<  65378 <<  65474 <<  67301 <<  68702
460 				    <<  68933 <<  69673 <<  71683 <<  72607 <<  76267 <<  80763 <<  82273
461 				    <<  82396 <<  85927 <<  86032 <<  87833 <<  90185 <<  91262 <<  92855
462 				    <<  97649 << 100453 << 100751 << 102098 << 105199 << 107315 << 109268
463 				    << 112122 << 113368 << 113881 << 113963;
464 			break;
465 		}
466 		case Russian:
467 		{
468 			// 160 stars from Russian Nautical Almanac
469 			// Original Russian name: Морской астрономический ежегодник.
470 			starNumbers <<    677 <<    746 <<   1067 <<   2021 <<   2081 <<   3179 <<   3419
471 				    <<   4427 <<   5447 <<   6686 <<   7588 <<   8886 <<   8903 <<   9236
472 				    <<   9640 <<   9884 <<  13847 <<  14135 <<  14576 <<  15863 <<  17702
473 				    <<  18246 <<  18532 <<  21421 <<  23015 <<  23875 <<  24436 <<  24608
474 				    <<  25336 <<  25428 <<  25606 <<  25930 <<  25985 <<  26241 <<  26311
475 				    <<  26451 <<  26634 <<  26727 <<  27913 <<  27989 <<  28360 <<  28380
476 				    <<  30324 <<  30438 <<  31681 <<  32349 <<  32768 <<  33579 <<  33152
477 				    <<  34444 <<  35264 <<  35904 <<  36188 <<  36850 <<  37279 <<  37826
478 				    <<  39429 <<  39757 <<  39953 <<  41037 <<  42913 <<  44816 <<  45238
479 				    <<  45556 <<  46390 <<  46701 <<  49669 <<  50583 <<  52419 <<  52727
480 				    <<  53910 <<  54061 <<  54872 <<  57632 <<  58001 <<  59196 <<  59747
481 				    <<  59774 <<  59803 <<  60718 <<  61084 <<  61359 <<  61585 <<  61932
482 				    <<  61941 <<  62434 <<  62956 <<  63121 <<  63608 <<  65109 <<  65378
483 				    <<  65474 <<  66657 <<  67301 <<  67927 <<  68002 <<  68702 <<  68933
484 				    <<  69673 <<  71075 <<  71352 <<  71681 <<  71860 <<  72105 <<  72603
485 				    <<  72607 <<  73273 <<  74946 <<  74785 <<  76297 <<  76267 <<  77070
486 				    <<  78401 <<  78820 <<  79593 <<  80331 <<  80763 <<  80816 <<  81266
487 				    <<  81377 <<  81693 <<  82273 <<  82396 <<  83081 <<  84012 <<  85258
488 				    <<  85792 <<  85670 <<  85927 <<  86032 <<  86228 <<  79540 <<  86742
489 				    <<  87833 <<  88635 <<  89931 <<  90185 <<  90496 <<  91262 <<  95347
490 				    <<  93506 <<  93747 <<  94141 <<  97165 <<  97278 <<  97649 << 100453
491 				    << 100751 << 102098 << 102488 << 105199 << 107315 << 107556 << 109268
492 				    << 110130 << 112122 << 113368 << 113881 << 113963 <<  11767;
493 			break;
494 		}
495 		case German:
496 		{
497 			// 80 stars from German Nautical Almanac
498 			// Original German name: Nautisches Jahrbuch
499 			// The numbers are identical to the "Nautisches Jahrbuch"
500 			starNumbers <<    677 <<    1067 <<      2081 <<    3179 <<     3419 <<     4427
501 					 <<     5447 <<     7588 <<   11767 <<     9640 <<     9884 <<   14135
502 					 <<   14576 <<   15863 <<   17702 <<   21421 <<   24436 <<   24608
503 					 <<   25336 <<   25428 <<   26311 <<   26727 <<   27366 <<   27989
504 					 <<   28360 <<   30324 <<   30438 <<   31681 <<   32349 <<   33579
505 					 <<   34444 <<   36850 <<   37279 <<   37826 <<   41037 <<   44816
506 					 <<   45238 <<   46390 <<   49669 <<   52419 <<   54061 <<   57632
507 					 <<   60718 <<   61084 <<   62434 <<   62956 <<   63608 <<   65378
508 					 <<   65474 <<   67301 <<   68702 <<   68933 <<   69673 <<   71683
509 					 <<   72105 <<   72622 <<   72607 <<   74785 <<   76267 <<   77070
510 					 <<   80763 <<   82273 <<   82396 <<   85927 <<   86032 <<   86228
511 					 <<   87833 <<   90185 <<   91262 <<   92855 <<   97649 << 100751
512 					 << 102098 << 105199 << 107315 << 109268 << 112122 << 113368
513 					 << 113881 << 113963;
514 			break;
515 		}
516 	}
517 
518 	setNavStarsMarks(currentState);
519 }
520 
addExtraInfo(StelCore * core)521 void NavStars::addExtraInfo(StelCore *core)
522 {
523 	if (0 == stars.size() || "Earth" != core->getCurrentPlanet()->getEnglishName())
524 		return;
525 
526 	StelApp& stelApp = StelApp::getInstance();
527 	bool isSource = stelApp.getStelObjectMgr().getWasSelected();
528 
529 	if (isSource)
530 	{
531 		bool doExtraInfo = true;
532 		StelObjectP selectedObject = stelApp.getStelObjectMgr().getSelectedObject()[0];
533 		if (limitInfoToNavStars)
534 		{
535 			doExtraInfo = false;
536 			QString type = selectedObject->getType();
537 			if(selectedObject->getType() == QStringLiteral("Star")) {
538 				for (QVector<StelObjectP>::const_iterator itor = stars.begin();
539 					itor != stars.end();
540 					itor++)
541 				{
542 					StelObjectP p = *itor;
543 					if (p->getEnglishName() == selectedObject->getEnglishName())
544 					{
545 						doExtraInfo = true;
546 						break;
547 					}
548 				}
549 			}
550 			else
551 			{
552 				QString englishName = selectedObject->getEnglishName();
553 				if (isPermittedObject(englishName))
554 				{
555 					doExtraInfo = true;
556 				}
557 			}
558 		}
559 		if (doExtraInfo)
560 			extraInfo(core, selectedObject);
561 	}
562 }
563 
extraInfo(StelCore * core,const StelObjectP & selectedObject)564 void NavStars::extraInfo(StelCore* core, const StelObjectP& selectedObject)
565 {
566 	double jd, jde, x = 0., y = 0.;
567 	QString extraText = "", englishName = selectedObject->getEnglishName();
568 
569 	jd  = core->getJD();
570 	jde = core->getJDE();
571 
572 	NavStarsCalculator calc;
573 	calc.setUTC(StelUtils::julianDayToISO8601String(jd))
574 		.setLatDeg(core->getCurrentLocation().latitude)
575 		.setLonDeg(core->getCurrentLocation().longitude)
576 		.setJd(jd)
577 		.setJde(jde)
578 		.setGmst(get_mean_sidereal_time(jd, jde));
579 
580 	StelUtils::rectToSphe(&x, &y, selectedObject->getEquinoxEquatorialPos(core));
581 	calc.setRaRad(x).setDecRad(y);
582 
583 	StelUtils::rectToSphe(&x,&y,selectedObject->getAltAzPosGeometric(core));
584 	calc.setAzRad(x).setAltRad(y);
585 
586 	StelUtils::rectToSphe(&x,&y,selectedObject->getAltAzPosApparent(core));
587 	calc.setAzAppRad(x).setAltAppRad(y);
588 
589 	calc.execute();
590 
591 	if ("Sun" == englishName || "Moon" == englishName)
592 	{
593 		// Adjust Ho if target is Sun or Moon by adding/subtracting the angular radius.
594 		double obj_radius_in_degrees = selectedObject->getAngularSize(core);
595 		if (!upperLimb)
596 			obj_radius_in_degrees *= -1;
597 		calc.addAltAppRad((obj_radius_in_degrees * M_PI) / 180.);
598 		extraText = upperLimb ?
599 			" (" + QString(qc_("upper limb", "the highest part of the Sun or Moon")) + ")" :
600 			" (" + QString(qc_("lower limb", "the lowest part of the Sun or Moon")) + ")";
601 	}
602 
603 	if (tabulatedDisplay)
604 		displayTabulatedInfo(selectedObject, calc, extraText);
605 	else
606 		displayStandardInfo(selectedObject, calc, extraText);
607 }
608 
displayStandardInfo(const StelObjectP & selectedObject,NavStarsCalculator & calc,const QString & extraText)609 void NavStars::displayStandardInfo(const StelObjectP& selectedObject, NavStarsCalculator& calc, const QString& extraText)
610 {
611 	Q_UNUSED(extraText)
612 	QString temp;
613 	StelObject::InfoStringGroup infoGroup = StelObject::OtherCoord;
614 	selectedObject->addToExtraInfoString(infoGroup,
615 		oneRowTwoCells(qc_("GHA", "Greenwich Hour Angle") + "&#9800;", calc.gmstPrintable(), "", false));
616 	selectedObject->addToExtraInfoString(infoGroup,
617 		oneRowTwoCells(qc_("SHA", "object Sidereal Hour Angle (ERA, Earth rotation angle)"), calc.shaPrintable(), "", false));
618 	selectedObject->addToExtraInfoString(infoGroup,
619 		oneRowTwoCells(qc_("LHA", "Local Hour Angle"), calc.lhaPrintable(), "", false));
620 	temp = calc.ghaPrintable() + "/" + calc.decPrintable();
621 	selectedObject->addToExtraInfoString(infoGroup,
622 		oneRowTwoCells(qc_("GP: GHA/DEC", "Ground Position of object"), temp, "", false));
623 	temp = calc.gplatPrintable() + "/" + calc.gplonPrintable();
624 	selectedObject->addToExtraInfoString(infoGroup,
625 		oneRowTwoCells(qc_("GP: LAT/LON", "geodetic coordinate system, latitude and longitude of ground point"), temp, "", false));
626 	temp = calc.latPrintable() + "/" + calc.lonPrintable();
627 	selectedObject->addToExtraInfoString(infoGroup,
628 		oneRowTwoCells(qc_("AP: LAT/LON", "geodetic coordinate system, assumed latitude and longitude of user"), temp, "", false));
629 	temp = calc.hcPrintable() + "/" + calc.znPrintable();
630 	selectedObject->addToExtraInfoString(infoGroup,
631 		oneRowTwoCells(qc_("Hc/Zn", "Navigation/horizontal coordinate system, calculated altitude and azimuth"), temp, "", false));
632 }
633 
displayTabulatedInfo(const StelObjectP & selectedObject,NavStarsCalculator & calc,const QString & extraText)634 void NavStars::displayTabulatedInfo(const StelObjectP& selectedObject, NavStarsCalculator& calc, const QString& extraText)
635 {
636 	StelObject::InfoStringGroup infoGroup = StelObject::OtherCoord;
637 	selectedObject->addToExtraInfoString(infoGroup,
638 		oneRowTwoCells(qc_("UTC", "Universal Time Coordinated"), calc.getUTC(), "", false));
639 	selectedObject->addToExtraInfoString(infoGroup, "<table style='margin:0em 0em 0em -0.125em;border-spacing:0px;border:0px;'>");
640 	selectedObject->addToExtraInfoString(infoGroup,
641 		oneRowTwoCells(qc_("Ho", "Navigation/horizontal coordinate system, sextant measured altitude"), calc.altAppPrintable(), extraText, true));
642 	selectedObject->addToExtraInfoString(infoGroup,
643 		oneRowTwoCells(qc_("GHA", "Greenwich Hour Angle") + "&#9800;", calc.gmstPrintable(), "", true));
644 	selectedObject->addToExtraInfoString(infoGroup,
645 		oneRowTwoCells(qc_("LMST", "Local Hour Angle"), calc.lmstPrintable(), "", true));
646 	selectedObject->addToExtraInfoString(infoGroup,
647 		oneRowTwoCells(qc_("SHA", "object Sidereal Hour Angle (ERA, Earth rotation angle)"), calc.shaPrintable(), "", true));
648 	selectedObject->addToExtraInfoString(infoGroup,
649 		oneRowTwoCells(qc_("GHA", "Greenwich Hour Angle"), calc.ghaPrintable(), "", true));
650 	selectedObject->addToExtraInfoString(infoGroup,
651 		oneRowTwoCells(qc_("DEC", "Declination"), calc.decPrintable(), "", true));
652 	selectedObject->addToExtraInfoString(infoGroup,
653 		oneRowTwoCells(qc_("LHA", "Local Hour Angle"), calc.lhaPrintable(), "", true));
654 	selectedObject->addToExtraInfoString(infoGroup,
655 		oneRowTwoCells(qc_("LAT", "geodetic coordinate system, latitude"), calc.gplatPrintable(), "", true));
656 	selectedObject->addToExtraInfoString(infoGroup,
657 		oneRowTwoCells(qc_("LON", "geodetic coordinate system, longitude"), calc.gplonPrintable(), "", true));
658 	selectedObject->addToExtraInfoString(infoGroup,
659 		oneRowTwoCells(qc_("Hc", "Navigation/horizontal coordinate system, calculated altitude"), calc.hcPrintable(), "", true));
660 	selectedObject->addToExtraInfoString(infoGroup,
661 		oneRowTwoCells(qc_("Zn", "Navigation/horizontal coordinate system, calculated azimuth"), calc.znPrintable(), "", true));
662 	selectedObject->addToExtraInfoString(infoGroup, "</table>");
663 }
664 
oneRowTwoCells(const QString & a,const QString & b,const QString & extra,bool tabulatedView)665 QString NavStars::oneRowTwoCells(const QString& a, const QString& b, const QString &extra, bool tabulatedView)
666 {
667 	QString rval;
668 	if (tabulatedView)
669 		rval += QString("<tr><td>%1:</td><td style='text-align:right;'>%2</td><td>%3</td></tr>").arg(a, b, extra);
670 	else
671 		rval += QString("%1: %2 %3<br />").arg(a, b, extra);
672 	return rval;
673 }
674 
isPermittedObject(const QString & s)675 bool NavStars::isPermittedObject(const QString& s)
676 {
677 	QVector<QString>::const_iterator itor = permittedObjects.begin();
678 	while (itor != permittedObjects.end())
679 	{
680 		if (*itor == s)
681 			return true;
682 		++itor;
683 	}
684 	return false;
685 }
686