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

Stellarium / stellarium / 13260145531

11 Feb 2025 09:41AM UTC coverage: 12.127% (+0.03%) from 12.101%
13260145531

Pull #3751

github

10110111
Restore deleted additional SC files
Pull Request #3751: Switch skycultures to the new format

14613 of 120497 relevant lines covered (12.13%)

18620.19 hits per line

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

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

22
// class used to manage groups of Nebulas
23

24
#include "StelApp.hpp"
25
#include "NebulaList.hpp"
26
#include "NebulaMgr.hpp"
27
#include "Nebula.hpp"
28
#include "StelTexture.hpp"
29
#include "StelUtils.hpp"
30
#include "StelMainView.hpp"
31
#include "StelSkyDrawer.hpp"
32
#include "StelTranslator.hpp"
33
#include "StelTextureMgr.hpp"
34
#include "StelObjectMgr.hpp"
35
#include "StelLocaleMgr.hpp"
36
#include "StelSkyCultureMgr.hpp"
37
#include "StelFileMgr.hpp"
38
#include "StelModuleMgr.hpp"
39
#include "StelCore.hpp"
40
#include "StelPainter.hpp"
41

42
#include <unordered_map>
43
#include <algorithm>
44
#include <vector>
45
#include <QDebug>
46
#include <QFile>
47
#include <QSettings>
48
#include <QString>
49
#include <QStringList>
50
#include <QRegularExpression>
51
#include <QDir>
52
#include <QMessageBox>
53

54
// Define version of valid Stellarium DSO Catalog
55
// This number must be incremented each time the content or file format of the stars catalogs change
56
static const QString StellariumDSOCatalogVersion = "3.20";
57

58
namespace
59
{
60

61
void setName(const NebulaP& nebula, const QString& specificName)
×
62
{
63
        const auto currentName = nebula->getEnglishName();
×
64
        if (currentName.isEmpty()) // Set native name of DSO
×
65
                nebula->setProperName(specificName);
×
66
        else if (currentName != specificName) // Add traditional (well-known?) name of DSO as alias
×
67
                nebula->addNameAlias(specificName);
×
68
}
×
69

70
}
71

72
void NebulaMgr::setLabelsColor(const Vec3f& c) {Nebula::labelColor = c; emit labelsColorChanged(c);}
×
73
const Vec3f NebulaMgr::getLabelsColor(void) const {return Nebula::labelColor;}
×
74
void NebulaMgr::setCirclesColor(const Vec3f& c) {Nebula::hintColorMap.insert(Nebula::NebUnknown, c); emit circlesColorChanged(c); }
×
75
const Vec3f NebulaMgr::getCirclesColor(void) const {return Nebula::hintColorMap.value(Nebula::NebUnknown);}
×
76
void NebulaMgr::setRegionsColor(const Vec3f& c) {Nebula::hintColorMap.insert(Nebula::NebRegion, c); emit regionsColorChanged(c); }
×
77
const Vec3f NebulaMgr::getRegionsColor(void) const {return Nebula::hintColorMap.value(Nebula::NebRegion);}
×
78
void NebulaMgr::setGalaxyColor(const Vec3f& c) {Nebula::hintColorMap.insert(Nebula::NebGx, c); Nebula::hintColorMap.insert(Nebula::NebPartOfGx, c); emit galaxiesColorChanged(c); }
×
79
const Vec3f NebulaMgr::getGalaxyColor(void) const {return Nebula::hintColorMap.value(Nebula::NebGx);}
×
80
void NebulaMgr::setRadioGalaxyColor(const Vec3f& c) {Nebula::hintColorMap.insert(Nebula::NebRGx, c); emit radioGalaxiesColorChanged(c); }
×
81
const Vec3f NebulaMgr::getRadioGalaxyColor(void) const {return Nebula::hintColorMap.value(Nebula::NebRGx);}
×
82
void NebulaMgr::setActiveGalaxyColor(const Vec3f& c) {Nebula::hintColorMap.insert(Nebula::NebAGx, c); emit activeGalaxiesColorChanged(c); }
×
83
const Vec3f NebulaMgr::getActiveGalaxyColor(void) const {return Nebula::hintColorMap.value(Nebula::NebAGx);}
×
84
void NebulaMgr::setInteractingGalaxyColor(const Vec3f& c) {Nebula::hintColorMap.insert(Nebula::NebIGx, c); emit interactingGalaxiesColorChanged(c); }
×
85
const Vec3f NebulaMgr::getInteractingGalaxyColor(void) const {return Nebula::hintColorMap.value(Nebula::NebIGx);}
×
86
void NebulaMgr::setQuasarColor(const Vec3f& c) {Nebula::hintColorMap.insert(Nebula::NebQSO, c); emit quasarsColorChanged(c); }
×
87
const Vec3f NebulaMgr::getQuasarColor(void) const {return Nebula::hintColorMap.value(Nebula::NebQSO);}
×
88
void NebulaMgr::setNebulaColor(const Vec3f& c) {Nebula::hintColorMap.insert(Nebula::NebN, c); Nebula::hintColorMap.insert(Nebula::NebCn, c); emit nebulaeColorChanged(c); }
×
89
const Vec3f NebulaMgr::getNebulaColor(void) const {return Nebula::hintColorMap.value(Nebula::NebN);}
×
90
void NebulaMgr::setPlanetaryNebulaColor(const Vec3f& c) {Nebula::hintColorMap.insert(Nebula::NebPn, c); emit planetaryNebulaeColorChanged(c);}
×
91
const Vec3f NebulaMgr::getPlanetaryNebulaColor(void) const {return Nebula::hintColorMap.value(Nebula::NebPn);}
×
92
void NebulaMgr::setReflectionNebulaColor(const Vec3f& c) {Nebula::hintColorMap.insert(Nebula::NebRn, c); emit reflectionNebulaeColorChanged(c);}
×
93
const Vec3f NebulaMgr::getReflectionNebulaColor(void) const {return Nebula::hintColorMap.value(Nebula::NebRn);}
×
94
void NebulaMgr::setBipolarNebulaColor(const Vec3f& c) {Nebula::hintColorMap.insert(Nebula::NebBn, c); emit bipolarNebulaeColorChanged(c);}
×
95
const Vec3f NebulaMgr::getBipolarNebulaColor(void) const {return Nebula::hintColorMap.value(Nebula::NebBn);}
×
96
void NebulaMgr::setEmissionNebulaColor(const Vec3f& c) {Nebula::hintColorMap.insert(Nebula::NebEn, c); emit emissionNebulaeColorChanged(c);}
×
97
const Vec3f NebulaMgr::getEmissionNebulaColor(void) const {return Nebula::hintColorMap.value(Nebula::NebEn);}
×
98
void NebulaMgr::setDarkNebulaColor(const Vec3f& c) {Nebula::hintColorMap.insert(Nebula::NebDn, c); emit darkNebulaeColorChanged(c);}
×
99
const Vec3f NebulaMgr::getDarkNebulaColor(void) const {return Nebula::hintColorMap.value(Nebula::NebDn);}
×
100
void NebulaMgr::setHydrogenRegionColor(const Vec3f& c) {Nebula::hintColorMap.insert(Nebula::NebHII, c); emit hydrogenRegionsColorChanged(c);}
×
101
const Vec3f NebulaMgr::getHydrogenRegionColor(void) const {return Nebula::hintColorMap.value(Nebula::NebHII);}
×
102
void NebulaMgr::setSupernovaRemnantColor(const Vec3f& c) {Nebula::hintColorMap.insert(Nebula::NebSNR, c); emit supernovaRemnantsColorChanged(c);}
×
103
const Vec3f NebulaMgr::getSupernovaRemnantColor(void) const {return Nebula::hintColorMap.value(Nebula::NebSNR);}
×
104
void NebulaMgr::setSupernovaCandidateColor(const Vec3f& c) {Nebula::hintColorMap.insert(Nebula::NebSNC, c); emit supernovaCandidatesColorChanged(c);}
×
105
const Vec3f NebulaMgr::getSupernovaCandidateColor(void) const {return Nebula::hintColorMap.value(Nebula::NebSNC);}
×
106
void NebulaMgr::setSupernovaRemnantCandidateColor(const Vec3f& c) {Nebula::hintColorMap.insert(Nebula::NebSNRC, c); emit supernovaRemnantCandidatesColorChanged(c);}
×
107
const Vec3f NebulaMgr::getSupernovaRemnantCandidateColor(void) const {return Nebula::hintColorMap.value(Nebula::NebSNRC);}
×
108
void NebulaMgr::setInterstellarMatterColor(const Vec3f& c) {Nebula::hintColorMap.insert(Nebula::NebISM, c); emit interstellarMatterColorChanged(c);}
×
109
const Vec3f NebulaMgr::getInterstellarMatterColor(void) const {return Nebula::hintColorMap.value(Nebula::NebISM);}
×
110
void NebulaMgr::setClusterColor(const Vec3f& c) {Nebula::hintColorMap.insert(Nebula::NebCl, c); emit clustersColorChanged(c);}
×
111
const Vec3f NebulaMgr::getClusterColor(void) const {return Nebula::hintColorMap.value(Nebula::NebCl);}
×
112
void NebulaMgr::setOpenClusterColor(const Vec3f& c) {Nebula::hintColorMap.insert(Nebula::NebOc, c); emit openClustersColorChanged(c);}
×
113
const Vec3f NebulaMgr::getOpenClusterColor(void) const {return Nebula::hintColorMap.value(Nebula::NebOc);}
×
114
void NebulaMgr::setGlobularClusterColor(const Vec3f& c) {Nebula::hintColorMap.insert(Nebula::NebGc, c); emit globularClustersColorChanged(c);}
×
115
const Vec3f NebulaMgr::getGlobularClusterColor(void) const {return Nebula::hintColorMap.value(Nebula::NebGc);}
×
116
void NebulaMgr::setStellarAssociationColor(const Vec3f& c) {Nebula::hintColorMap.insert(Nebula::NebSA, c); emit stellarAssociationsColorChanged(c);}
×
117
const Vec3f NebulaMgr::getStellarAssociationColor(void) const {return Nebula::hintColorMap.value(Nebula::NebSA);}
×
118
void NebulaMgr::setStarCloudColor(const Vec3f& c) {Nebula::hintColorMap.insert(Nebula::NebSC, c); emit starCloudsColorChanged(c);}
×
119
const Vec3f NebulaMgr::getStarCloudColor(void) const {return Nebula::hintColorMap.value(Nebula::NebSC);}
×
120
void NebulaMgr::setEmissionObjectColor(const Vec3f& c) {Nebula::hintColorMap.insert(Nebula::NebEMO, c); emit emissionObjectsColorChanged(c);}
×
121
const Vec3f NebulaMgr::getEmissionObjectColor(void) const {return Nebula::hintColorMap.value(Nebula::NebEMO);}
×
122
void NebulaMgr::setBlLacObjectColor(const Vec3f& c) {Nebula::hintColorMap.insert(Nebula::NebBLL, c); emit blLacObjectsColorChanged(c);}
×
123
const Vec3f NebulaMgr::getBlLacObjectColor(void) const {return Nebula::hintColorMap.value(Nebula::NebBLL);}
×
124
void NebulaMgr::setBlazarColor(const Vec3f& c) {Nebula::hintColorMap.insert(Nebula::NebBLA, c); emit blazarsColorChanged(c);}
×
125
const Vec3f NebulaMgr::getBlazarColor(void) const {return Nebula::hintColorMap.value(Nebula::NebBLA);}
×
126
void NebulaMgr::setMolecularCloudColor(const Vec3f& c) {Nebula::hintColorMap.insert(Nebula::NebMolCld, c); emit molecularCloudsColorChanged(c);}
×
127
const Vec3f NebulaMgr::getMolecularCloudColor(void) const {return Nebula::hintColorMap.value(Nebula::NebMolCld);}
×
128
void NebulaMgr::setYoungStellarObjectColor(const Vec3f& c) {Nebula::hintColorMap.insert(Nebula::NebYSO, c); emit youngStellarObjectsColorChanged(c);}
×
129
const Vec3f NebulaMgr::getYoungStellarObjectColor(void) const {return Nebula::hintColorMap.value(Nebula::NebYSO);}
×
130
void NebulaMgr::setPossibleQuasarColor(const Vec3f& c) {Nebula::hintColorMap.insert(Nebula::NebPossQSO, c); emit possibleQuasarsColorChanged(c);}
×
131
const Vec3f NebulaMgr::getPossibleQuasarColor(void) const {return Nebula::hintColorMap.value(Nebula::NebPossQSO);}
×
132
void NebulaMgr::setPossiblePlanetaryNebulaColor(const Vec3f& c) {Nebula::hintColorMap.insert(Nebula::NebPossPN, c); emit possiblePlanetaryNebulaeColorChanged(c);}
×
133
const Vec3f NebulaMgr::getPossiblePlanetaryNebulaColor(void) const {return Nebula::hintColorMap.value(Nebula::NebPossPN);}
×
134
void NebulaMgr::setProtoplanetaryNebulaColor(const Vec3f& c) {Nebula::hintColorMap.insert(Nebula::NebPPN, c); emit protoplanetaryNebulaeColorChanged(c);}
×
135
const Vec3f NebulaMgr::getProtoplanetaryNebulaColor(void) const {return Nebula::hintColorMap.value(Nebula::NebPPN);}
×
136
void NebulaMgr::setStarColor(const Vec3f& c) {Nebula::hintColorMap.insert(Nebula::NebStar, c); emit starsColorChanged(c);}
×
137
const Vec3f NebulaMgr::getStarColor(void) const {return Nebula::hintColorMap.value(Nebula::NebStar);}
×
138
void NebulaMgr::setSymbioticStarColor(const Vec3f& c) {Nebula::hintColorMap.insert(Nebula::NebSymbioticStar, c); emit symbioticStarsColorChanged(c);}
×
139
const Vec3f NebulaMgr::getSymbioticStarColor(void) const {return Nebula::hintColorMap.value(Nebula::NebSymbioticStar);}
×
140
void NebulaMgr::setEmissionLineStarColor(const Vec3f& c) {Nebula::hintColorMap.insert(Nebula::NebEmissionLineStar, c); emit emissionLineStarsColorChanged(c);}
×
141
const Vec3f NebulaMgr::getEmissionLineStarColor(void) const {return Nebula::hintColorMap.value(Nebula::NebEmissionLineStar);}
×
142
void NebulaMgr::setGalaxyClusterColor(const Vec3f& c) {Nebula::hintColorMap.insert(Nebula::NebGxCl, c); emit galaxyClustersColorChanged(c);}
×
143
const Vec3f NebulaMgr::getGalaxyClusterColor(void) const {return Nebula::hintColorMap.value(Nebula::NebGxCl);}
×
144

145
bool NebulaMgr::getHintsProportional(void) const {return Nebula::drawHintProportional;}
×
146
void NebulaMgr::setHintsProportional(const bool proportional)
×
147
{
148
        if(Nebula::drawHintProportional!=proportional)
×
149
        {
150
                Nebula::drawHintProportional=proportional;
×
151
                StelApp::immediateSave("astro/flag_nebula_hints_proportional", proportional);
×
152
                emit hintsProportionalChanged(proportional);
×
153
        }
154
}
×
155

156
bool NebulaMgr::getDesignationUsage(void) const {return Nebula::designationUsage; }
×
157
void NebulaMgr::setDesignationUsage(const bool flag)
×
158
{
159
        if(Nebula::designationUsage!=flag)
×
160
        {
161
                Nebula::designationUsage=flag;
×
162
                StelApp::immediateSave("astro/flag_dso_designation_usage", flag);
×
163
                emit designationUsageChanged(flag);
×
164
        }
165
}
×
166
bool NebulaMgr::getFlagAdditionalNames(void) const {return Nebula::flagShowAdditionalNames;}
×
167
void NebulaMgr::setFlagAdditionalNames(const bool flag)
×
168
{
169
        if(Nebula::flagShowAdditionalNames!=flag)
×
170
        {
171
                Nebula::flagShowAdditionalNames=flag;
×
172
                StelApp::immediateSave("astro/flag_dso_additional_names", flag);
×
173
                emit flagAdditionalNamesDisplayedChanged(flag);
×
174
        }
175
}
×
176

177
bool NebulaMgr::getFlagOutlines(void) const {return Nebula::flagUseOutlines;}
×
178
void NebulaMgr::setFlagOutlines(const bool flag)
×
179
{
180
        if(Nebula::flagUseOutlines!=flag)
×
181
        {
182
                Nebula::flagUseOutlines=flag;
×
183
                StelApp::immediateSave("astro/flag_dso_outlines_usage", flag);
×
184
                emit flagOutlinesDisplayedChanged(flag);
×
185
        }
186
}
×
187

188
NebulaMgr::NebulaMgr(void) : StelObjectModule()
×
189
        , nebGrid(200)
×
190
        , hintsAmount(0)
×
191
        , labelsAmount(0)
×
192
        , hintsBrightness(1.0)
×
193
        , labelsBrightness(1.0)
×
194
        , flagConverter(false)
×
195
        , flagDecimalCoordinates(true)
×
196
{
197
        setObjectName("NebulaMgr");
×
198
}
×
199

200
NebulaMgr::~NebulaMgr()
×
201
{
202
        Nebula::texRegion = StelTextureSP();
×
203
        Nebula::texPointElement = StelTextureSP();
×
204
        Nebula::texPlanetaryNebula = StelTextureSP();
×
205
}
×
206

207
/*************************************************************************
208
 Reimplementation of the getCallOrder method
209
*************************************************************************/
210
double NebulaMgr::getCallOrder(StelModuleActionName actionName) const
×
211
{
212
        if (actionName==StelModule::ActionDraw)
×
213
                return StelApp::getInstance().getModuleMgr().getModule("MilkyWay")->getCallOrder(actionName)+10;
×
214
        return 0;
×
215
}
216

217
// read from stream
218
void NebulaMgr::init()
×
219
{
220
        QSettings* conf = StelApp::getInstance().getSettings();
×
221
        Q_ASSERT(conf);
×
222

223
        nebulaFont.setPixelSize(StelApp::getInstance().getScreenFontSize());
×
224
        connect(&StelApp::getInstance(), SIGNAL(screenFontSizeChanged(int)), SLOT(setFontSizeFromApp(int)));
×
225
    auto& texMan = StelApp::getInstance().getTextureManager();
×
226
        // Load dashed shape texture
227
        Nebula::texRegion                = texMan.createTexture(StelFileMgr::getInstallationDir()+"/textures/neb_reg.png");
×
228
        // Load open cluster marker texture
229
        Nebula::texPointElement                = texMan.createTexture(StelFileMgr::getInstallationDir()+"/textures/neb_point_elem.png");
×
230
        // Load planetary nebula marker texture
231
        Nebula::texPlanetaryNebula        = texMan.createTexture(StelFileMgr::getInstallationDir()+"/textures/neb_pnb.png");
×
232
        // Load pointer texture
233
        texPointer = texMan.createTexture(StelFileMgr::getInstallationDir()+"/textures/pointeur5.png");
×
234

235
        setFlagShow(conf->value("astro/flag_nebula",true).toBool());
×
236
        setFlagHints(conf->value("astro/flag_nebula_name",false).toBool());
×
237
        setHintsAmount(conf->value("astro/nebula_hints_amount", 3.0).toDouble());
×
238
        setLabelsAmount(conf->value("astro/nebula_labels_amount", 3.0).toDouble());
×
239
        setHintsProportional(conf->value("astro/flag_nebula_hints_proportional", false).toBool());
×
240
        setFlagOutlines(conf->value("astro/flag_dso_outlines_usage", false).toBool());
×
241
        setFlagAdditionalNames(conf->value("astro/flag_dso_additional_names",true).toBool());
×
242
        setDesignationUsage(conf->value("astro/flag_dso_designation_usage", false).toBool());
×
243
        setFlagSurfaceBrightnessUsage(conf->value("astro/flag_surface_brightness_usage", false).toBool());
×
244
        setFlagSurfaceBrightnessArcsecUsage(conf->value("gui/flag_surface_brightness_arcsec", false).toBool());
×
245
        setFlagSurfaceBrightnessShortNotationUsage(conf->value("gui/flag_surface_brightness_short", false).toBool());
×
246

247
        setFlagSizeLimitsUsage(conf->value("astro/flag_size_limits_usage", false).toBool());
×
248
        setMinSizeLimit(conf->value("astro/size_limit_min", 1.0).toDouble());
×
249
        setMaxSizeLimit(conf->value("astro/size_limit_max", 600.0).toDouble());
×
250

251
        // Load colors from config file
252
        // Upgrade config keys
253
        if (conf->contains("color/nebula_label_color"))
×
254
        {
255
                conf->setValue("color/dso_label_color", conf->value("color/nebula_label_color", "0.4,0.3,0.5").toString());
×
256
                conf->remove("color/nebula_label_color");
×
257
        }
258
        if (conf->contains("color/nebula_circle_color"))
×
259
        {
260
                conf->setValue("color/dso_circle_color", conf->value("color/nebula_circle_color", "0.8,0.8,0.1").toString());
×
261
                conf->remove("color/nebula_circle_color");
×
262
        }
263
        if (conf->contains("color/nebula_galaxy_color"))
×
264
        {
265
                conf->setValue("color/dso_galaxy_color", conf->value("color/nebula_galaxy_color", "1.0,0.2,0.2").toString());
×
266
                conf->remove("color/nebula_galaxy_color");
×
267
        }
268
        if (conf->contains("color/nebula_radioglx_color"))
×
269
        {
270
                conf->setValue("color/dso_radio_galaxy_color", conf->value("color/nebula_radioglx_color", "0.3,0.3,0.3").toString());
×
271
                conf->remove("color/nebula_radioglx_color");
×
272
        }
273
        if (conf->contains("color/nebula_activeglx_color"))
×
274
        {
275
                conf->setValue("color/dso_active_galaxy_color", conf->value("color/nebula_activeglx_color", "1.0,0.5,0.2").toString());
×
276
                conf->remove("color/nebula_activeglx_color");
×
277
        }
278
        if (conf->contains("color/nebula_intglx_color"))
×
279
        {
280
                conf->setValue("color/dso_interacting_galaxy_color", conf->value("color/nebula_intglx_color", "0.2,0.5,1.0").toString());
×
281
                conf->remove("color/nebula_intglx_color");
×
282
        }
283
        if (conf->contains("color/nebula_brightneb_color"))
×
284
        {
285
                conf->setValue("color/dso_nebula_color", conf->value("color/nebula_brightneb_color", "0.1,1.0,0.1").toString());
×
286
                conf->remove("color/nebula_brightneb_color");
×
287
        }
288
        if (conf->contains("color/nebula_darkneb_color"))
×
289
        {
290
                conf->setValue("color/dso_dark_nebula_color", conf->value("color/nebula_darkneb_color", "0.3,0.3,0.3").toString());
×
291
                conf->remove("color/nebula_darkneb_color");
×
292
        }
293
        if (conf->contains("color/nebula_hregion_color"))
×
294
        {
295
                conf->setValue("color/dso_hydrogen_region_color", conf->value("color/nebula_hregion_color", "0.1,1.0,0.1").toString());
×
296
                conf->remove("color/nebula_hregion_color");
×
297
        }
298
        if (conf->contains("color/nebula_snr_color"))
×
299
        {
300
                conf->setValue("color/dso_supernova_remnant_color", conf->value("color/nebula_snr_color", "0.1,1.0,0.1").toString());
×
301
                conf->remove("color/nebula_snr_color");
×
302
        }
303
        if (conf->contains("color/nebula_cluster_color"))
×
304
        {
305
                conf->setValue("color/dso_cluster_color", conf->value("color/nebula_cluster_color", "0.8,0.8,0.1").toString());
×
306
                conf->remove("color/nebula_cluster_color");
×
307
        }
308

309
        // Set colors for markers
310
        setLabelsBrightness(conf->value("astro/nebula_labels_brightness", "1.0").toDouble());
×
311
        setHintsBrightness(conf->value("astro/nebula_hints_brightness", "1.0").toDouble());
×
312
        setLabelsColor(Vec3f(conf->value("color/dso_label_color", "0.2,0.6,0.7").toString()));
×
313
        setCirclesColor(Vec3f(conf->value("color/dso_circle_color", "1.0,0.7,0.2").toString()));
×
314
        setRegionsColor(Vec3f(conf->value("color/dso_region_color", "0.7,0.7,0.2").toString()));
×
315

316
        QString defaultGalaxyColor = conf->value("color/dso_galaxy_color", "1.0,0.2,0.2").toString();
×
317
        setGalaxyColor(           Vec3f(defaultGalaxyColor));
×
318
        setRadioGalaxyColor(      Vec3f(conf->value("color/dso_radio_galaxy_color", "0.3,0.3,0.3").toString()));
×
319
        setActiveGalaxyColor(     Vec3f(conf->value("color/dso_active_galaxy_color", "1.0,0.5,0.2").toString()));
×
320
        setInteractingGalaxyColor(Vec3f(conf->value("color/dso_interacting_galaxy_color", "0.2,0.5,1.0").toString()));
×
321
        setGalaxyClusterColor(    Vec3f(conf->value("color/dso_galaxy_cluster_color", "0.2,0.8,1.0").toString()));
×
322
        setQuasarColor(           Vec3f(conf->value("color/dso_quasar_color", defaultGalaxyColor).toString()));
×
323
        setPossibleQuasarColor(   Vec3f(conf->value("color/dso_possible_quasar_color", defaultGalaxyColor).toString()));
×
324
        setBlLacObjectColor(      Vec3f(conf->value("color/dso_bl_lac_color", defaultGalaxyColor).toString()));
×
325
        setBlazarColor(           Vec3f(conf->value("color/dso_blazar_color", defaultGalaxyColor).toString()));
×
326

327
        QString defaultNebulaColor = conf->value("color/dso_nebula_color", "0.1,1.0,0.1").toString();
×
328
        setNebulaColor(                   Vec3f(defaultNebulaColor));
×
329
        setPlanetaryNebulaColor(          Vec3f(conf->value("color/dso_planetary_nebula_color", defaultNebulaColor).toString()));
×
330
        setReflectionNebulaColor(         Vec3f(conf->value("color/dso_reflection_nebula_color", defaultNebulaColor).toString()));
×
331
        setBipolarNebulaColor(            Vec3f(conf->value("color/dso_bipolar_nebula_color", defaultNebulaColor).toString()));
×
332
        setEmissionNebulaColor(           Vec3f(conf->value("color/dso_emission_nebula_color", defaultNebulaColor).toString()));
×
333
        setDarkNebulaColor(               Vec3f(conf->value("color/dso_dark_nebula_color", "0.3,0.3,0.3").toString()));
×
334
        setHydrogenRegionColor(           Vec3f(conf->value("color/dso_hydrogen_region_color", defaultNebulaColor).toString()));
×
335
        setSupernovaRemnantColor(         Vec3f(conf->value("color/dso_supernova_remnant_color", defaultNebulaColor).toString()));
×
336
        setSupernovaCandidateColor(       Vec3f(conf->value("color/dso_supernova_candidate_color", defaultNebulaColor).toString()));
×
337
        setSupernovaRemnantCandidateColor(Vec3f(conf->value("color/dso_supernova_remnant_cand_color", defaultNebulaColor).toString()));
×
338
        setInterstellarMatterColor(       Vec3f(conf->value("color/dso_interstellar_matter_color", defaultNebulaColor).toString()));
×
339
        setMolecularCloudColor(           Vec3f(conf->value("color/dso_molecular_cloud_color", defaultNebulaColor).toString()));
×
340
        setPossiblePlanetaryNebulaColor(  Vec3f(conf->value("color/dso_possible_planetary_nebula_color", defaultNebulaColor).toString()));
×
341
        setProtoplanetaryNebulaColor(     Vec3f(conf->value("color/dso_protoplanetary_nebula_color", defaultNebulaColor).toString()));
×
342

343
        QString defaultClusterColor = conf->value("color/dso_cluster_color", "1.0,1.0,0.1").toString();
×
344
        setClusterColor(           Vec3f(defaultClusterColor));
×
345
        setOpenClusterColor(       Vec3f(conf->value("color/dso_open_cluster_color", defaultClusterColor).toString()));
×
346
        setGlobularClusterColor(   Vec3f(conf->value("color/dso_globular_cluster_color", defaultClusterColor).toString()));
×
347
        setStellarAssociationColor(Vec3f(conf->value("color/dso_stellar_association_color", defaultClusterColor).toString()));
×
348
        setStarCloudColor(         Vec3f(conf->value("color/dso_star_cloud_color", defaultClusterColor).toString()));
×
349

350
        QString defaultStellarColor = conf->value("color/dso_star_color", "1.0,0.7,0.2").toString();
×
351
        setStarColor(              Vec3f(defaultStellarColor));
×
352
        setSymbioticStarColor(     Vec3f(conf->value("color/dso_symbiotic_star_color", defaultStellarColor).toString()));
×
353
        setEmissionLineStarColor(  Vec3f(conf->value("color/dso_emission_star_color", defaultStellarColor).toString()));
×
354
        setEmissionObjectColor(    Vec3f(conf->value("color/dso_emission_object_color", defaultStellarColor).toString()));
×
355
        setYoungStellarObjectColor(Vec3f(conf->value("color/dso_young_stellar_object_color", defaultStellarColor).toString()));
×
356

357
        // Test that all nebula types have colors!
358
        QMetaEnum nType=QMetaEnum::fromType<Nebula::NebulaType>();
×
359
        for(int t=0; t<nType.keyCount(); t++)
×
360
        {
361
                if (!Nebula::hintColorMap.contains(static_cast<Nebula::NebulaType>(nType.value(t))))
×
362
                                qDebug() << "No color assigned to Nebula Type " << nType.key(t) << ". Please report as bug!";
×
363
        }
364

365
        // for DSO converter (for developers!)
366
        flagConverter = conf->value("devel/convert_dso_catalog", false).toBool();
×
367
        flagDecimalCoordinates = conf->value("devel/convert_dso_decimal_coord", true).toBool();
×
368

369
        setFlagUseTypeFilters(conf->value("astro/flag_use_type_filter", false).toBool());
×
370

371
        loadCatalogFilters();
×
372

373
        Nebula::TypeGroup typeFilters = Nebula::TypeGroup(Nebula::TypeNone);
×
374

375
        conf->beginGroup("dso_type_filters");
×
376
        if (conf->value("flag_show_galaxies", true).toBool())
×
377
                typeFilters        |= Nebula::TypeGalaxies;
×
378
        if (conf->value("flag_show_active_galaxies", true).toBool())
×
379
                typeFilters        |= Nebula::TypeActiveGalaxies;
×
380
        if (conf->value("flag_show_interacting_galaxies", true).toBool())
×
381
                typeFilters        |= Nebula::TypeInteractingGalaxies;
×
382
        if (conf->value("flag_show_open_clusters", true).toBool())
×
383
                typeFilters        |= Nebula::TypeOpenStarClusters;
×
384
        if (conf->value("flag_show_globular_clusters", true).toBool())
×
385
                typeFilters        |= Nebula::TypeGlobularStarClusters;
×
386
        if (conf->value("flag_show_bright_nebulae", true).toBool())
×
387
                typeFilters        |= Nebula::TypeBrightNebulae;
×
388
        if (conf->value("flag_show_dark_nebulae", true).toBool())
×
389
                typeFilters        |= Nebula::TypeDarkNebulae;
×
390
        if (conf->value("flag_show_planetary_nebulae", true).toBool())
×
391
                typeFilters        |= Nebula::TypePlanetaryNebulae;
×
392
        if (conf->value("flag_show_hydrogen_regions", true).toBool())
×
393
                typeFilters        |= Nebula::TypeHydrogenRegions;
×
394
        if (conf->value("flag_show_supernova_remnants", true).toBool())
×
395
                typeFilters        |= Nebula::TypeSupernovaRemnants;
×
396
        if (conf->value("flag_show_galaxy_clusters", true).toBool())
×
397
                typeFilters        |= Nebula::TypeGalaxyClusters;
×
398
        if (conf->value("flag_show_other", true).toBool())
×
399
                typeFilters        |= Nebula::TypeOther;
×
400
        conf->endGroup();
×
401

402
        setTypeFilters(typeFilters);
×
403

404
        // TODO: mechanism to specify which sets get loaded at start time.
405
        // candidate methods:
406
        // 1. config file option (list of sets to load at startup)
407
        // 2. load all
408
        // 3. flag in nebula_textures.fab (yuk)
409
        // 4. info.ini file in each set containing a "load at startup" item
410
        // For now (0.9.0), just load the default set
411
        loadNebulaSet("default");
×
412

413
        updateI18n();
×
414

415
        StelApp *app = &StelApp::getInstance();
×
416
        connect(app, SIGNAL(languageChanged()), this, SLOT(updateI18n()));
×
417
        connect(&app->getSkyCultureMgr(), &StelSkyCultureMgr::currentSkyCultureChanged, this, &NebulaMgr::updateSkyCulture);
×
418
        GETSTELMODULE(StelObjectMgr)->registerStelObjectMgr(this);
×
419

420
        addAction("actionShow_Nebulas", N_("Display Options"), N_("Deep-sky objects"), "flagHintDisplayed", "D", "N");
×
421
        addAction("actionSet_Nebula_TypeFilterUsage", N_("Display Options"), N_("Toggle DSO type filter"), "flagTypeFiltersUsage");
×
422
}
×
423

424
void NebulaMgr::selectAllCatalogs()
×
425
{
426
        setCatalogFilters(Nebula::CatAll);
×
427
}
×
428

429
void NebulaMgr::selectStandardCatalogs()
×
430
{
431
        Nebula::CatalogGroup catalogs = Nebula::CatNone;
×
432
        catalogs |= Nebula::CatNGC;
×
433
        catalogs |= Nebula::CatIC;
×
434
        catalogs |= Nebula::CatM;
×
435
        setCatalogFilters(catalogs);
×
436
}
×
437

438
void NebulaMgr::selectNoneCatalogs()
×
439
{
440
        setCatalogFilters(Nebula::CatNone);
×
441
}
×
442

443
void NebulaMgr::loadCatalogFilters()
×
444
{
445
        QSettings* conf = StelApp::getInstance().getSettings();
×
446
        Q_ASSERT(conf);
×
447

448
        Nebula::CatalogGroup catalogFilters = Nebula::CatalogGroup(Nebula::CatNone);
×
449

450
        conf->beginGroup("dso_catalog_filters");
×
451
        if (conf->value("flag_show_ngc", true).toBool())
×
452
                catalogFilters        |= Nebula::CatNGC;
×
453
        if (conf->value("flag_show_ic", true).toBool())
×
454
                catalogFilters        |= Nebula::CatIC;
×
455
        if (conf->value("flag_show_m", true).toBool())
×
456
                catalogFilters        |= Nebula::CatM;
×
457
        if (conf->value("flag_show_c", false).toBool())
×
458
                catalogFilters        |= Nebula::CatC;
×
459
        if (conf->value("flag_show_b", false).toBool())
×
460
                catalogFilters        |= Nebula::CatB;
×
461
        if (conf->value("flag_show_sh2", false).toBool())
×
462
                catalogFilters        |= Nebula::CatSh2;
×
463
        if (conf->value("flag_show_vdb", false).toBool())
×
464
                catalogFilters        |= Nebula::CatVdB;
×
465
        if (conf->value("flag_show_lbn", false).toBool())
×
466
                catalogFilters        |= Nebula::CatLBN;
×
467
        if (conf->value("flag_show_ldn", false).toBool())
×
468
                catalogFilters        |= Nebula::CatLDN;
×
469
        if (conf->value("flag_show_rcw", false).toBool())
×
470
                catalogFilters        |= Nebula::CatRCW;
×
471
        if (conf->value("flag_show_cr", false).toBool())
×
472
                catalogFilters        |= Nebula::CatCr;
×
473
        if (conf->value("flag_show_mel", false).toBool())
×
474
                catalogFilters        |= Nebula::CatMel;
×
475
        if (conf->value("flag_show_pgc", false).toBool())
×
476
                catalogFilters        |= Nebula::CatPGC;
×
477
        if (conf->value("flag_show_ced", false).toBool())
×
478
                catalogFilters        |= Nebula::CatCed;
×
479
        if (conf->value("flag_show_ugc", false).toBool())
×
480
                catalogFilters        |= Nebula::CatUGC;
×
481
        if (conf->value("flag_show_arp", false).toBool())
×
482
                catalogFilters        |= Nebula::CatArp;
×
483
        if (conf->value("flag_show_vv", false).toBool())
×
484
                catalogFilters        |= Nebula::CatVV;
×
485
        if (conf->value("flag_show_pk", false).toBool())
×
486
                catalogFilters        |= Nebula::CatPK;
×
487
        if (conf->value("flag_show_png", false).toBool())
×
488
                catalogFilters        |= Nebula::CatPNG;
×
489
        if (conf->value("flag_show_snrg", false).toBool())
×
490
                catalogFilters        |= Nebula::CatSNRG;
×
491
        if (conf->value("flag_show_aco", false).toBool())
×
492
                catalogFilters        |= Nebula::CatACO;
×
493
        if (conf->value("flag_show_hcg", false).toBool())
×
494
                catalogFilters        |= Nebula::CatHCG;
×
495
        if (conf->value("flag_show_eso", false).toBool())
×
496
                catalogFilters        |= Nebula::CatESO;
×
497
        if (conf->value("flag_show_vdbh", false).toBool())
×
498
                catalogFilters        |= Nebula::CatVdBH;
×
499
        if (conf->value("flag_show_dwb", false).toBool())
×
500
                catalogFilters        |= Nebula::CatDWB;
×
501
        if (conf->value("flag_show_tr", false).toBool())
×
502
                catalogFilters        |= Nebula::CatTr;
×
503
        if (conf->value("flag_show_st", false).toBool())
×
504
                catalogFilters        |= Nebula::CatSt;
×
505
        if (conf->value("flag_show_ru", false).toBool())
×
506
                catalogFilters        |= Nebula::CatRu;
×
507
        if (conf->value("flag_show_vdbha", false).toBool())
×
508
                catalogFilters        |= Nebula::CatVdBHa;
×
509
        if (conf->value("flag_show_other", true).toBool())
×
510
                catalogFilters        |= Nebula::CatOther;
×
511
        conf->endGroup();
×
512

513
        // NB: nebula set loaded inside setter of catalog filter
514
        setCatalogFilters(int(catalogFilters));
×
515
}
×
516

517
void NebulaMgr::storeCatalogFilters()
×
518
{
519
        QSettings* conf = StelApp::getInstance().getSettings();
×
520
        Q_ASSERT(conf);
×
521

522
        // view dialog / DSO tag settings
523
        const Nebula::CatalogGroup cflags = static_cast<Nebula::CatalogGroup>(getCatalogFilters());
×
524

525
        conf->beginGroup("dso_catalog_filters");
×
526
        conf->setValue("flag_show_ngc",                static_cast<bool>(cflags & Nebula::CatNGC));
×
527
        conf->setValue("flag_show_ic",                static_cast<bool>(cflags & Nebula::CatIC));
×
528
        conf->setValue("flag_show_m",                static_cast<bool>(cflags & Nebula::CatM));
×
529
        conf->setValue("flag_show_c",                static_cast<bool>(cflags & Nebula::CatC));
×
530
        conf->setValue("flag_show_b",                static_cast<bool>(cflags & Nebula::CatB));
×
531
        conf->setValue("flag_show_vdb",                static_cast<bool>(cflags & Nebula::CatVdB));
×
532
        conf->setValue("flag_show_sh2",                static_cast<bool>(cflags & Nebula::CatSh2));
×
533
        conf->setValue("flag_show_rcw",                static_cast<bool>(cflags & Nebula::CatRCW));
×
534
        conf->setValue("flag_show_lbn",                static_cast<bool>(cflags & Nebula::CatLBN));
×
535
        conf->setValue("flag_show_ldn",                static_cast<bool>(cflags & Nebula::CatLDN));
×
536
        conf->setValue("flag_show_cr",                static_cast<bool>(cflags & Nebula::CatCr));
×
537
        conf->setValue("flag_show_mel",                static_cast<bool>(cflags & Nebula::CatMel));
×
538
        conf->setValue("flag_show_ced",                static_cast<bool>(cflags & Nebula::CatCed));
×
539
        conf->setValue("flag_show_pgc",                static_cast<bool>(cflags & Nebula::CatPGC));
×
540
        conf->setValue("flag_show_ugc",                static_cast<bool>(cflags & Nebula::CatUGC));
×
541
        conf->setValue("flag_show_arp",                static_cast<bool>(cflags & Nebula::CatArp));
×
542
        conf->setValue("flag_show_vv",                static_cast<bool>(cflags & Nebula::CatVV));
×
543
        conf->setValue("flag_show_pk",                static_cast<bool>(cflags & Nebula::CatPK));
×
544
        conf->setValue("flag_show_png",                static_cast<bool>(cflags & Nebula::CatPNG));
×
545
        conf->setValue("flag_show_snrg",                static_cast<bool>(cflags & Nebula::CatSNRG));
×
546
        conf->setValue("flag_show_aco",                static_cast<bool>(cflags & Nebula::CatACO));
×
547
        conf->setValue("flag_show_hcg",                static_cast<bool>(cflags & Nebula::CatHCG));
×
548
        conf->setValue("flag_show_eso",                static_cast<bool>(cflags & Nebula::CatESO));
×
549
        conf->setValue("flag_show_vdbh",                static_cast<bool>(cflags & Nebula::CatVdBH));
×
550
        conf->setValue("flag_show_dwb",                static_cast<bool>(cflags & Nebula::CatDWB));
×
551
        conf->setValue("flag_show_tr",                static_cast<bool>(cflags & Nebula::CatTr));
×
552
        conf->setValue("flag_show_st",                static_cast<bool>(cflags & Nebula::CatSt));
×
553
        conf->setValue("flag_show_ru",                static_cast<bool>(cflags & Nebula::CatRu));
×
554
        conf->setValue("flag_show_vdbha",        static_cast<bool>(cflags & Nebula::CatVdBHa));
×
555
        conf->setValue("flag_show_other",                static_cast<bool>(cflags & Nebula::CatOther));
×
556
        conf->endGroup();
×
557
}
×
558

559
struct DrawNebulaFuncObject
560
{
561
        DrawNebulaFuncObject(float amaxMagHints, float amaxMagLabels, StelPainter* p, StelCore* aCore, bool acheckMaxMagHints)
×
562
                : maxMagHints(amaxMagHints)
×
563
                , maxMagLabels(amaxMagLabels)
×
564
                , sPainter(p)
×
565
                , core(aCore)
×
566
                , checkMaxMagHints(acheckMaxMagHints)
×
567
        {
568
                angularSizeLimit = 5.f/sPainter->getProjector()->getPixelPerRadAtCenter()*M_180_PIf;
×
569
        }
×
570
        void operator()(StelRegionObject* obj)
×
571
        {
572
                if (checkMaxMagHints)
×
573
                        return;
×
574

575
                Nebula* n = static_cast<Nebula*>(obj);
×
576
                float mag=n->getVisibilityLevelByMagnitude();
×
577

578
                StelSkyDrawer *drawer = core->getSkyDrawer();
×
579
                // filter out DSOs which are too dim to be seen (e.g. for bino observers)
580
                if ((drawer->getFlagNebulaMagnitudeLimit()) && (mag > static_cast<float>(drawer->getCustomNebulaMagnitudeLimit())))
×
581
                        return;
×
582

583
                if (!n->objectInDisplayedCatalog())
×
584
                        return;
×
585

586
                if (!n->objectInAllowedSizeRangeLimits())
×
587
                        return;
×
588

589
                if (n->majorAxisSize>angularSizeLimit || n->majorAxisSize==0.f || mag <= maxMagHints)
×
590
                {
591
                        sPainter->getProjector()->project(n->getJ2000EquatorialPos(core),n->XY);
×
592
                        n->drawLabel(*sPainter, maxMagLabels);
×
593
                        n->drawHints(*sPainter, maxMagHints, core);
×
594
                        n->drawOutlines(*sPainter, maxMagHints);
×
595
                }
596
        }
597
        float maxMagHints;
598
        float maxMagLabels;
599
        StelPainter* sPainter;
600
        StelCore* core;
601
        float angularSizeLimit;
602
        bool checkMaxMagHints;
603
};
604

605
void NebulaMgr::setCatalogFilters(int cflags)
×
606
{
607
        if(cflags != static_cast<int>(Nebula::catalogFilters))
×
608
        {
609
                Nebula::catalogFilters = static_cast<Nebula::CatalogGroup>(cflags);
×
610
                emit catalogFiltersChanged(cflags);
×
611
        }
612
}
×
613

614
void NebulaMgr::setTypeFilters(int tflags)
×
615
{
616
        if(tflags != static_cast<int>(Nebula::typeFilters))
×
617
        {
618
                Nebula::typeFilters = static_cast<Nebula::TypeGroup>(tflags);
×
619
                emit typeFiltersChanged(tflags);
×
620
        }
621
}
×
622

623
void NebulaMgr::setFlagSurfaceBrightnessUsage(const bool usage)
×
624
{
625
        if (usage!=Nebula::surfaceBrightnessUsage)
×
626
        {
627
                Nebula::surfaceBrightnessUsage=usage;
×
628
                StelApp::immediateSave("astro/flag_surface_brightness_usage", Nebula::surfaceBrightnessUsage);
×
629
                emit flagSurfaceBrightnessUsageChanged(usage);
×
630
        }
631
}
×
632

633
bool NebulaMgr::getFlagSurfaceBrightnessUsage(void) const
×
634
{
635
        return Nebula::surfaceBrightnessUsage;
×
636
}
637

638
void NebulaMgr::setFlagSurfaceBrightnessArcsecUsage(const bool usage)
×
639
{
640
        if (usage!=Nebula::flagUseArcsecSurfaceBrightness)
×
641
        {
642
                Nebula::flagUseArcsecSurfaceBrightness=usage;
×
643
                StelApp::immediateSave("gui/flag_surface_brightness_arcsec", Nebula::flagUseArcsecSurfaceBrightness);
×
644
                emit flagSurfaceBrightnessArcsecUsageChanged(usage);
×
645
        }
646
}
×
647

648
bool NebulaMgr::getFlagSurfaceBrightnessArcsecUsage(void) const
×
649
{
650
        return Nebula::flagUseArcsecSurfaceBrightness;
×
651
}
652

653
void NebulaMgr::setFlagSurfaceBrightnessShortNotationUsage(const bool usage)
×
654
{
655
        if (usage!=Nebula::flagUseShortNotationSurfaceBrightness)
×
656
        {
657
                Nebula::flagUseShortNotationSurfaceBrightness=usage;
×
658
                StelApp::immediateSave("gui/flag_surface_brightness_short", Nebula::flagUseShortNotationSurfaceBrightness);
×
659
                emit flagSurfaceBrightnessShortNotationUsageChanged(usage);
×
660
        }
661
}
×
662

663
bool NebulaMgr::getFlagSurfaceBrightnessShortNotationUsage(void) const
×
664
{
665
        return Nebula::flagUseShortNotationSurfaceBrightness;
×
666
}
667

668
void NebulaMgr::setFlagSizeLimitsUsage(const bool usage)
×
669
{
670
        if (usage!=Nebula::flagUseSizeLimits)
×
671
        {
672
                Nebula::flagUseSizeLimits=usage;
×
673
                StelApp::immediateSave("astro/flag_size_limits_usage", Nebula::flagUseSizeLimits);
×
674
                emit flagSizeLimitsUsageChanged(usage);
×
675
        }
676
}
×
677

678
bool NebulaMgr::getFlagSizeLimitsUsage(void) const
×
679
{
680
        return Nebula::flagUseSizeLimits;
×
681
}
682

683
void NebulaMgr::setFlagUseTypeFilters(const bool b)
×
684
{
685
        if (Nebula::flagUseTypeFilters!=b)
×
686
        {
687
                Nebula::flagUseTypeFilters=b;
×
688
                StelApp::immediateSave("astro/flag_use_type_filter", Nebula::flagUseTypeFilters);
×
689
                emit flagUseTypeFiltersChanged(b);
×
690
        }
691
}
×
692

693
bool NebulaMgr::getFlagUseTypeFilters(void) const
×
694
{
695
        return Nebula::flagUseTypeFilters;
×
696
}
697

698
void NebulaMgr::setLabelsAmount(double a)
×
699
{
700
        if((a-labelsAmount) != 0.)
×
701
        {
702
                labelsAmount=a;
×
703
                StelApp::immediateSave("astro/nebula_labels_amount", labelsAmount);
×
704
                emit labelsAmountChanged(a);
×
705
        }
706
}
×
707

708
double NebulaMgr::getLabelsAmount(void) const
×
709
{
710
        return labelsAmount;
×
711
}
712

713
void NebulaMgr::setHintsAmount(double f)
×
714
{
715
        if((hintsAmount-f) != 0.)
×
716
        {
717
                hintsAmount = f;
×
718
                StelApp::immediateSave("astro/nebula_hints_amount", hintsAmount);
×
719
                emit hintsAmountChanged(f);
×
720
        }
721
}
×
722

723
double NebulaMgr::getHintsAmount(void) const
×
724
{
725
        return hintsAmount;
×
726
}
727

728
void NebulaMgr::setLabelsBrightness(double b)
×
729
{
730
        if (b!=labelsBrightness)
×
731
        {
732
                labelsBrightness = b;
×
733
                StelApp::immediateSave("astro/nebula_labels_brightness", labelsBrightness);
×
734
                emit labelsBrightnessChanged(b);
×
735
        }
736
}
×
737

738
double NebulaMgr::getLabelsBrightness(void) const
×
739
{
740
        return labelsBrightness;
×
741
}
742

743
void NebulaMgr::setHintsBrightness(double b)
×
744
{
745
        if (b!=hintsBrightness)
×
746
        {
747
                hintsBrightness = b;
×
748
                StelApp::immediateSave("astro/nebula_hints_brightness", hintsBrightness);
×
749
                emit hintsBrightnessChanged(b);
×
750
        }
751
}
×
752

753
double NebulaMgr::getHintsBrightness(void) const
×
754
{
755
        return hintsBrightness;
×
756
}
757

758

759
void NebulaMgr::setMinSizeLimit(double s)
×
760
{
761
        if((Nebula::minSizeLimit-s) != 0.)
×
762
        {
763
                Nebula::minSizeLimit = s;
×
764
                StelApp::immediateSave("astro/size_limit_min", Nebula::minSizeLimit);
×
765
                emit minSizeLimitChanged(s);
×
766
        }
767
}
×
768

769
double NebulaMgr::getMinSizeLimit() const
×
770
{
771
        return Nebula::minSizeLimit;
×
772
}
773

774
void NebulaMgr::setMaxSizeLimit(double s)
×
775
{
776
        if((Nebula::maxSizeLimit-s) != 0.)
×
777
        {
778
                Nebula::maxSizeLimit = s;
×
779
                StelApp::immediateSave("astro/size_limit_max", Nebula::maxSizeLimit);
×
780
                emit maxSizeLimitChanged(s);
×
781
        }
782
}
×
783

784
double NebulaMgr::getMaxSizeLimit() const
×
785
{
786
        return Nebula::maxSizeLimit;
×
787
}
788

789
float NebulaMgr::computeMaxMagHint(const StelSkyDrawer* skyDrawer) const
×
790
{
791
        return skyDrawer->getLimitMagnitude()*1.2f-2.f+static_cast<float>(hintsAmount *1.)-2.f;
×
792
}
793

794
// Draw all the Nebulae and call drawing the pointer if needed
795
void NebulaMgr::draw(StelCore* core)
×
796
{
797
        const StelProjectorP prj = core->getProjection(StelCore::FrameJ2000);
×
798
        StelPainter sPainter(prj);
×
799
        sPainter.setFont(nebulaFont);
×
800

801
        if(hintsFader.getInterstate()>0.f)
×
802
        {
803
                static StelSkyDrawer* skyDrawer = core->getSkyDrawer();
×
804

805
                Nebula::hintsBrightness  = hintsFader.getInterstate()*flagShow.getInterstate()*static_cast<float>(hintsBrightness);
×
806
                Nebula::labelsBrightness = hintsFader.getInterstate()*flagShow.getInterstate()*static_cast<float>(labelsBrightness);
×
807

808
                // Use a 4 degree margin (esp. for wide outlines)
809
                const float margin = 4.f*M_PI_180f*prj->getPixelPerRadAtCenter();
×
810
                const SphericalRegionP& p = prj->getViewportConvexPolygon(margin, margin);
×
811

812
                // Print all the nebulae of all the selected zones
813
                float maxMagHints  = computeMaxMagHint(skyDrawer);
×
814
                float maxMagLabels = skyDrawer->getLimitMagnitude()-2.f+static_cast<float>(labelsAmount*1.2)-2.f;
×
815
                DrawNebulaFuncObject func(maxMagHints, maxMagLabels, &sPainter, core, hintsFader.getInterstate()<=0.f);
×
816
                nebGrid.processIntersectingPointInRegions(p.data(), func);
×
817
        }
×
818

819
        static StelObjectMgr *som=GETSTELMODULE(StelObjectMgr);
×
820
        if (som->getFlagSelectedObjectPointer())
×
821
                drawPointer(core, sPainter);
×
822
}
×
823

824
void NebulaMgr::drawPointer(const StelCore* core, StelPainter& sPainter)
×
825
{
826
        const StelProjectorP prj = core->getProjection(StelCore::FrameJ2000);
×
827

828
        const QList<StelObjectP> newSelected = GETSTELMODULE(StelObjectMgr)->getSelectedObject("Nebula");
×
829
        if (!newSelected.empty())
×
830
        {
831
                const StelObjectP obj = newSelected[0];
×
832
                Vec3d pos=obj->getJ2000EquatorialPos(core);
×
833

834
                // Compute 2D pos and return if outside screen
835
                if (!prj->projectInPlace(pos)) return;
×
836
                sPainter.setColor(0.4f,0.5f,0.8f);
×
837

838
                texPointer->bind();
×
839

840
                sPainter.setBlending(true);
×
841

842
                // Size on screen
843
                float screenRd = static_cast<float>(obj->getAngularRadius(core))*M_PI_180f*prj->getPixelPerRadAtCenter();
×
844
                if (screenRd>120.f) // avoid oversized marker
×
845
                        screenRd = 120.f;
×
846

847
                if (Nebula::drawHintProportional)
×
848
                        screenRd*=1.2f;
×
849
                screenRd+=20.f + 10.f*std::sin(3.f * static_cast<float>(StelApp::getInstance().getAnimationTime()));
×
850
                sPainter.drawSprite2dMode(static_cast<float>(pos[0])-screenRd*0.5f, static_cast<float>(pos[1])-screenRd*0.5f, 10, 90);
×
851
                sPainter.drawSprite2dMode(static_cast<float>(pos[0])-screenRd*0.5f, static_cast<float>(pos[1])+screenRd*0.5f, 10, 0);
×
852
                sPainter.drawSprite2dMode(static_cast<float>(pos[0])+screenRd*0.5f, static_cast<float>(pos[1])+screenRd*0.5f, 10, -90);
×
853
                sPainter.drawSprite2dMode(static_cast<float>(pos[0])+screenRd*0.5f, static_cast<float>(pos[1])-screenRd*0.5f, 10, -180);
×
854
        }
×
855
}
×
856

857
// Search by name
858
NebulaP NebulaMgr::search(const QString& name)
×
859
{
860
        QString uname = name.toUpper();
×
861

862
        for (const auto& n : std::as_const(dsoArray))
×
863
        {
864
                QString testName = n->getEnglishName().toUpper();
×
865
                if (testName==uname) return n;
×
866
        }
×
867

868
        return searchByDesignation(uname);
×
869
}
×
870

871
void NebulaMgr::loadNebulaSet(const QString& setName)
×
872
{
873
        QString srcCatalogPath        = StelFileMgr::findFile("nebulae/" + setName + "/catalog.txt");
×
874
        QString dsoCatalogPath        = StelFileMgr::findFile("nebulae/" + setName + "/catalog-" + StellariumDSOCatalogVersion + ".dat");
×
875
        if (dsoCatalogPath.isEmpty()) // Extended edition is not exist, let's try find standard edition
×
876
                dsoCatalogPath        = StelFileMgr::findFile("nebulae/" + setName + "/catalog.dat");
×
877
        QString dsoOutlinesPath        = StelFileMgr::findFile("nebulae/" + setName + "/outlines.dat");
×
878
        QString dsoDiscoveryPath = StelFileMgr::findFile("nebulae/" + setName + "/discovery.dat");
×
879

880
        dsoArray.clear();
×
881
        dsoIndex.clear();
×
882
        nebGrid.clear();
×
883

884
        if (flagConverter)
×
885
        {
886
                if (!srcCatalogPath.isEmpty())
×
887
                        convertDSOCatalog(srcCatalogPath, StelFileMgr::findFile("nebulae/" + setName + "/catalog.pack", StelFileMgr::New), flagDecimalCoordinates);
×
888
                else
889
                        qWarning() << "ERROR convert catalogue, because source data set does not exist for " << setName;
×
890
        }
891

892
        if (dsoCatalogPath.isEmpty())
×
893
        {
894
                qWarning() << "ERROR while loading deep-sky catalog data set " << setName;
×
895
                return;
×
896
        }
897

898
        loadDSOCatalog(dsoCatalogPath);
×
899

900
        if (!dsoOutlinesPath.isEmpty())
×
901
                loadDSOOutlines(dsoOutlinesPath);
×
902

903
        if (!dsoDiscoveryPath.isEmpty())
×
904
                loadDSODiscoveryData(dsoDiscoveryPath);
×
905
}
×
906

907
// Look for a nebula by XYZ coords
908
NebulaP NebulaMgr::search(const Vec3d& apos)
×
909
{
910
        Vec3d pos(apos);
×
911
        pos.normalize();
×
912
        NebulaP plusProche;
×
913
        double anglePlusProche=0.0;
×
914
        for (const auto& n : std::as_const(dsoArray))
×
915
        {
916
                if (n->XYZ*pos>anglePlusProche)
×
917
                {
918
                        anglePlusProche=n->XYZ*pos;
×
919
                        plusProche=n;
×
920
                }
921
        }
922
        if (anglePlusProche>0.999) // object within ~2.5 degrees
×
923
        {
924
                return plusProche;
×
925
        }
926
        else return NebulaP();
×
927
}
×
928

929

930
QList<StelObjectP> NebulaMgr::searchAround(const Vec3d& av, double limitFov, const StelCore*) const
×
931
{
932
        QList<StelObjectP> result;
×
933
        if (!getFlagShow())
×
934
                return result;
×
935

936
        Vec3d v(av);
×
937
        v.normalize();
×
938
        const double cosLimFov = cos(limitFov * M_PI/180.);
×
939
        Vec3d equPos;
×
940
        for (const auto& n : std::as_const(dsoArray))
×
941
        {
942
                equPos = n->XYZ;
×
943
                equPos.normalize();
×
944
                if (equPos*v >= cosLimFov)
×
945
                {
946
                        result.push_back(qSharedPointerCast<StelObject>(n));
×
947
                }
948
        }
949
        return result;
×
950
}
×
951

952
NebulaP NebulaMgr::searchDSO(unsigned int DSO) const
×
953
{
954
        if (dsoIndex.contains(DSO))
×
955
                return dsoIndex[DSO];
×
956
        return NebulaP();
×
957
}
958

959

960
NebulaP NebulaMgr::searchM(unsigned int M) const
×
961
{
962
        for (const auto& n : dsoArray)
×
963
                if (n->M_nb == M)
×
964
                        return n;
×
965
        return NebulaP();
×
966
}
967

968
NebulaP NebulaMgr::searchNGC(unsigned int NGC) const
×
969
{
970
        for (const auto& n : dsoArray)
×
971
                if (n->NGC_nb == NGC)
×
972
                        return n;
×
973
        return NebulaP();
×
974
}
975

976
NebulaP NebulaMgr::searchIC(unsigned int IC) const
×
977
{
978
        for (const auto& n : dsoArray)
×
979
                if (n->IC_nb == IC)
×
980
                        return n;
×
981
        return NebulaP();
×
982
}
983

984
NebulaP NebulaMgr::searchC(unsigned int C) const
×
985
{
986
        for (const auto& n : dsoArray)
×
987
                if (n->C_nb == C)
×
988
                        return n;
×
989
        return NebulaP();
×
990
}
991

992
NebulaP NebulaMgr::searchB(unsigned int B) const
×
993
{
994
        for (const auto& n : dsoArray)
×
995
                if (n->B_nb == B)
×
996
                        return n;
×
997
        return NebulaP();
×
998
}
999

1000
NebulaP NebulaMgr::searchSh2(unsigned int Sh2) const
×
1001
{
1002
        for (const auto& n : dsoArray)
×
1003
                if (n->Sh2_nb == Sh2)
×
1004
                        return n;
×
1005
        return NebulaP();
×
1006
}
1007

1008
NebulaP NebulaMgr::searchVdB(unsigned int VdB) const
×
1009
{
1010
        for (const auto& n : dsoArray)
×
1011
                if (n->VdB_nb == VdB)
×
1012
                        return n;
×
1013
        return NebulaP();
×
1014
}
1015

1016
NebulaP NebulaMgr::searchVdBHa(unsigned int VdBHa) const
×
1017
{
1018
        for (const auto& n : dsoArray)
×
1019
                if (n->VdBHa_nb == VdBHa)
×
1020
                        return n;
×
1021
        return NebulaP();
×
1022
}
1023

1024
NebulaP NebulaMgr::searchRCW(unsigned int RCW) const
×
1025
{
1026
        for (const auto& n : dsoArray)
×
1027
                if (n->RCW_nb == RCW)
×
1028
                        return n;
×
1029
        return NebulaP();
×
1030
}
1031

1032
NebulaP NebulaMgr::searchLDN(unsigned int LDN) const
×
1033
{
1034
        for (const auto& n : dsoArray)
×
1035
                if (n->LDN_nb == LDN)
×
1036
                        return n;
×
1037
        return NebulaP();
×
1038
}
1039

1040
NebulaP NebulaMgr::searchLBN(unsigned int LBN) const
×
1041
{
1042
        for (const auto& n : dsoArray)
×
1043
                if (n->LBN_nb == LBN)
×
1044
                        return n;
×
1045
        return NebulaP();
×
1046
}
1047

1048
NebulaP NebulaMgr::searchCr(unsigned int Cr) const
×
1049
{
1050
        for (const auto& n : dsoArray)
×
1051
                if (n->Cr_nb == Cr)
×
1052
                        return n;
×
1053
        return NebulaP();
×
1054
}
1055

1056
NebulaP NebulaMgr::searchMel(unsigned int Mel) const
×
1057
{
1058
        for (const auto& n : dsoArray)
×
1059
                if (n->Mel_nb == Mel)
×
1060
                        return n;
×
1061
        return NebulaP();
×
1062
}
1063

1064
NebulaP NebulaMgr::searchPGC(unsigned int PGC) const
×
1065
{
1066
        for (const auto& n : dsoArray)
×
1067
                if (n->PGC_nb == PGC)
×
1068
                        return n;
×
1069
        return NebulaP();
×
1070
}
1071

1072
NebulaP NebulaMgr::searchUGC(unsigned int UGC) const
×
1073
{
1074
        for (const auto& n : dsoArray)
×
1075
                if (n->UGC_nb == UGC)
×
1076
                        return n;
×
1077
        return NebulaP();
×
1078
}
1079

1080
NebulaP NebulaMgr::searchCed(QString Ced) const
×
1081
{
1082
        for (const auto& n : dsoArray)
×
1083
                if (n->Ced_nb.trimmed().toUpper() == Ced.trimmed().toUpper())
×
1084
                        return n;
×
1085
        return NebulaP();
×
1086
}
1087

1088
NebulaP NebulaMgr::searchArp(unsigned int Arp) const
×
1089
{
1090
        for (const auto& n : dsoArray)
×
1091
                if (n->Arp_nb == Arp)
×
1092
                        return n;
×
1093
        return NebulaP();
×
1094
}
1095

1096
NebulaP NebulaMgr::searchVV(unsigned int VV) const
×
1097
{
1098
        for (const auto& n : dsoArray)
×
1099
                if (n->VV_nb == VV)
×
1100
                        return n;
×
1101
        return NebulaP();
×
1102
}
1103

1104
NebulaP NebulaMgr::searchPK(QString PK) const
×
1105
{
1106
        for (const auto& n : dsoArray)
×
1107
                if (n->PK_nb.trimmed().toUpper() == PK.trimmed().toUpper())
×
1108
                        return n;
×
1109
        return NebulaP();
×
1110
}
1111

1112
NebulaP NebulaMgr::searchPNG(QString PNG) const
×
1113
{
1114
        for (const auto& n : dsoArray)
×
1115
                if (n->PNG_nb.trimmed().toUpper() == PNG.trimmed().toUpper())
×
1116
                        return n;
×
1117
        return NebulaP();
×
1118
}
1119

1120
NebulaP NebulaMgr::searchSNRG(QString SNRG) const
×
1121
{
1122
        for (const auto& n : dsoArray)
×
1123
                if (n->SNRG_nb.trimmed().toUpper() == SNRG.trimmed().toUpper())
×
1124
                        return n;
×
1125
        return NebulaP();
×
1126
}
1127

1128
NebulaP NebulaMgr::searchACO(QString ACO) const
×
1129
{
1130
        for (const auto& n : dsoArray)
×
1131
                if (n->ACO_nb.trimmed().toUpper() == ACO.trimmed().toUpper())
×
1132
                        return n;
×
1133
        return NebulaP();
×
1134
}
1135

1136
NebulaP NebulaMgr::searchHCG(QString HCG) const
×
1137
{
1138
        for (const auto& n : dsoArray)
×
1139
                if (n->HCG_nb.trimmed().toUpper() == HCG.trimmed().toUpper())
×
1140
                        return n;
×
1141
        return NebulaP();
×
1142
}
1143

1144
NebulaP NebulaMgr::searchESO(QString ESO) const
×
1145
{
1146
        for (const auto& n : dsoArray)
×
1147
                if (n->ESO_nb.trimmed().toUpper() == ESO.trimmed().toUpper())
×
1148
                        return n;
×
1149
        return NebulaP();
×
1150
}
1151

1152
NebulaP NebulaMgr::searchVdBH(QString VdBH) const
×
1153
{
1154
        for (const auto& n : dsoArray)
×
1155
                if (n->VdBH_nb.trimmed().toUpper() == VdBH.trimmed().toUpper())
×
1156
                        return n;
×
1157
        return NebulaP();
×
1158
}
1159

1160
NebulaP NebulaMgr::searchDWB(unsigned int DWB) const
×
1161
{
1162
        for (const auto& n : dsoArray)
×
1163
                if (n->DWB_nb == DWB)
×
1164
                        return n;
×
1165
        return NebulaP();
×
1166
}
1167

1168
NebulaP NebulaMgr::searchTr(unsigned int Tr) const
×
1169
{
1170
        for (const auto& n : dsoArray)
×
1171
                if (n->Tr_nb == Tr)
×
1172
                        return n;
×
1173
        return NebulaP();
×
1174
}
1175

1176
NebulaP NebulaMgr::searchSt(unsigned int St) const
×
1177
{
1178
        for (const auto& n : dsoArray)
×
1179
                if (n->St_nb == St)
×
1180
                        return n;
×
1181
        return NebulaP();
×
1182
}
1183

1184
NebulaP NebulaMgr::searchRu(unsigned int Ru) const
×
1185
{
1186
        for (const auto& n : dsoArray)
×
1187
                if (n->Ru_nb == Ru)
×
1188
                        return n;
×
1189
        return NebulaP();
×
1190
}
1191

1192
QString NebulaMgr::getLatestSelectedDSODesignation() const
×
1193
{
1194
        QString result = "";
×
1195

1196
        const QList<StelObjectP> selected = GETSTELMODULE(StelObjectMgr)->getSelectedObject("Nebula");
×
1197
        if (!selected.empty())
×
1198
        {
1199
                for (const auto& n : dsoArray)
×
1200
                        if (n==selected[0])
×
1201
                                result = n->getDSODesignation(); // Get designation for latest selected DSO
×
1202
        }
1203

1204
        return result;
×
1205
}
×
1206

1207
QString NebulaMgr::getLatestSelectedDSODesignationWIC() const
×
1208
{
1209
        QString result = "";
×
1210

1211
        const QList<StelObjectP> selected = GETSTELMODULE(StelObjectMgr)->getSelectedObject("Nebula");
×
1212
        if (!selected.empty())
×
1213
        {
1214
                for (const auto& n : dsoArray)
×
1215
                        if (n==selected[0])
×
1216
                                result = n->getDSODesignationWIC(); // Get designation for latest selected DSO
×
1217
        }
1218

1219
        return result;
×
1220
}
×
1221

1222
void NebulaMgr::convertDSOCatalog(const QString &in, const QString &out, bool decimal=false)
×
1223
{
1224
        QFile dsoIn(in);
×
1225
        if (!dsoIn.open(QIODevice::ReadOnly | QIODevice::Text))
×
1226
                return;
×
1227

1228
        QFile dsoOut(out);
×
1229
        if (!dsoOut.open(QIODevice::WriteOnly))
×
1230
        {
1231
                qDebug() << "Error converting DSO data! Cannot open file" << QDir::toNativeSeparators(out);
×
1232
                return;
×
1233
        }
1234

1235
        int totalRecords=0;
×
1236
        QString record;
×
1237
        while (!dsoIn.atEnd())
×
1238
        {
1239
                dsoIn.readLine();
×
1240
                ++totalRecords;
×
1241
        }
1242

1243
        // rewind the file to the start
1244
        dsoIn.seek(0);
×
1245

1246
        QDataStream dsoOutStream(&dsoOut);
×
1247
        dsoOutStream.setVersion(QDataStream::Qt_5_2);
×
1248

1249
        int readOk = 0;                                // how many records were read without problems
×
1250
        while (!dsoIn.atEnd())
×
1251
        {
1252
                record = QString::fromUtf8(dsoIn.readLine());
×
1253

1254
                static const QRegularExpression version("ersion\\s+([\\d\\.]+)\\s+(\\w+)");
×
1255
                QRegularExpressionMatch versionMatch;
×
1256
                int vp = record.indexOf(version, 0, &versionMatch);
×
1257
                if (vp!=-1) // Version of catalog, a first line!
×
1258
                        dsoOutStream << versionMatch.captured(1).trimmed() << versionMatch.captured(2).trimmed();
×
1259

1260
                // skip comments
1261
                if (record.startsWith("//") || record.startsWith("#"))
×
1262
                {
1263
                        --totalRecords;
×
1264
                        continue;
×
1265
                }
1266

1267
                if (!record.isEmpty())
×
1268
                {
1269
                        #if (QT_VERSION>=QT_VERSION_CHECK(5, 14, 0))
1270
                        QStringList list=record.split("\t", Qt::KeepEmptyParts);
×
1271
                        #else
1272
                        QStringList list=record.split("\t", QString::KeepEmptyParts);
1273
                        #endif
1274

1275
                        int id                 = list.at(0).toInt();    // ID (inner identification number)
×
1276
                        QString ra             = list.at(1).trimmed();
×
1277
                        QString dec            = list.at(2).trimmed();
×
1278
                        float bMag             = list.at(3).toFloat();  // B magnitude
×
1279
                        float vMag             = list.at(4).toFloat();  // V magnitude
×
1280
                        QString oType          = list.at(5).trimmed();  // Object type
×
1281
                        QString mType          = list.at(6).trimmed();  // Morphological type of object
×
1282
                        float majorAxisSize    = list.at(7).toFloat();  // major axis size (arcmin)
×
1283
                        float minorAxisSize    = list.at(8).toFloat();  // minor axis size (arcmin)
×
1284
                        int orientationAngle   = list.at(9).toInt();    // orientation angle (degrees)
×
1285
                        float z                = list.at(10).toFloat(); // redshift
×
1286
                        float zErr             = list.at(11).toFloat(); // error of redshift
×
1287
                        float plx              = list.at(12).toFloat(); // parallax (mas)
×
1288
                        float plxErr           = list.at(13).toFloat(); // error of parallax (mas)
×
1289
                        float dist             = list.at(14).toFloat(); // distance (Mpc for galaxies, kpc for other objects)
×
1290
                        float distErr          = list.at(15).toFloat(); // distance error (Mpc for galaxies, kpc for other objects)
×
1291
                        // -----------------------------------------------
1292
                        // cross-identification data
1293
                        // -----------------------------------------------
1294
                        int NGC                = list.at(16).toInt();   // NGC number
×
1295
                        int IC                 = list.at(17).toInt();   // IC number
×
1296
                        int M                  = list.at(18).toInt();   // M number
×
1297
                        int C                  = list.at(19).toInt();   // C number
×
1298
                        int B                  = list.at(20).toInt();   // B number
×
1299
                        int Sh2                = list.at(21).toInt();   // Sh2 number
×
1300
                        int VdB                = list.at(22).toInt();   // VdB number
×
1301
                        int RCW                = list.at(23).toInt();   // RCW number
×
1302
                        int LDN                = list.at(24).toInt();   // LDN number
×
1303
                        int LBN                = list.at(25).toInt();   // LBN number
×
1304
                        int Cr                 = list.at(26).toInt();   // Cr number (alias: Col)
×
1305
                        int Mel                = list.at(27).toInt();   // Mel number
×
1306
                        int PGC                = list.at(28).toInt();   // PGC number (subset)
×
1307
                        int UGC                = list.at(29).toInt();   // UGC number (subset)
×
1308
                        QString Ced            = list.at(30).trimmed();        // Ced number
×
1309
                        int Arp                = list.at(31).toInt();   // Arp number
×
1310
                        int VV                 = list.at(32).toInt();   // VV number
×
1311
                        QString PK             = list.at(33).trimmed(); // PK number
×
1312
                        QString PNG            = list.at(34).trimmed(); // PN G number
×
1313
                        QString SNRG           = list.at(35).trimmed(); // SNR G number
×
1314
                        QString ACO            = list.at(36).trimmed(); // ACO number
×
1315
                        QString HCG            = list.at(37).trimmed(); // HCG number
×
1316
                        QString ESO            = list.at(38).trimmed(); // ESO number
×
1317
                        QString VdBH           = list.at(39).trimmed(); // VdBH number
×
1318
                        int DWB                = list.at(40).toInt();   // DWB number
×
1319
                        int Tr                 = list.at(41).toInt();   // Tr number
×
1320
                        int St                 = list.at(42).toInt();   // St number
×
1321
                        int Ru                 = list.at(43).toInt();   // Ru number
×
1322
                        int VdBHa              = list.at(44).toInt();   // VdB-Ha number
×
1323

1324
                        float raRad, decRad;
1325
                        if (decimal)
×
1326
                        {
1327
                                // Convert from deg to rad
1328
                                raRad        = ra.toFloat() *M_PI_180f;
×
1329
                                decRad        = dec.toFloat()*M_PI_180f;
×
1330
                        }
1331
                        else
1332
                        {
1333
                                QStringList raLst;
×
1334
                                if (ra.contains(":"))
×
1335
                                        raLst        = ra.split(":");
×
1336
                                else
1337
                                        raLst        = ra.split(" ");
×
1338

1339
                                QStringList decLst;
×
1340
                                if (dec.contains(":"))
×
1341
                                        decLst = dec.split(":");
×
1342
                                else
1343
                                        decLst = dec.split(" ");
×
1344

1345
                                raRad        = raLst.at(0).toFloat() + raLst.at(1).toFloat()/60.f + raLst.at(2).toFloat()/3600.f;
×
1346
                                decRad        = qAbs(decLst.at(0).toFloat()) + decLst.at(1).toFloat()/60.f + decLst.at(2).toFloat()/3600.f;
×
1347
                                if (dec.startsWith("-")) decRad *= -1.f;
×
1348

1349
                                raRad  *= M_PIf/12.f;        // Convert from hours to rad
×
1350
                                decRad *= M_PIf/180.f;    // Convert from deg to rad
×
1351
                        }
×
1352

1353
                        majorAxisSize /= 60.f;        // Convert from arcmin to degrees
×
1354
                        minorAxisSize /= 60.f;        // Convert from arcmin to degrees
×
1355

1356
                        // Warning: Hyades and LMC has visual magnitude less than 1.0 (0.5^m and 0.9^m)
1357
                        if (bMag <= 0.f) bMag = 99.f;
×
1358
                        if (vMag <= 0.f) vMag = 99.f;
×
1359
                        static const QHash<QString, Nebula::NebulaType> oTypesHash({
1360
                                { "G"   , Nebula::NebGx  },
×
1361
                                { "GX"  , Nebula::NebGx  },
×
1362
                                { "GC"  , Nebula::NebGc  },
×
1363
                                { "OC"  , Nebula::NebOc  },
×
1364
                                { "NB"  , Nebula::NebN   },
×
1365
                                { "PN"  , Nebula::NebPn  },
×
1366
                                { "DN"  , Nebula::NebDn  },
×
1367
                                { "RN"  , Nebula::NebRn  },
×
1368
                                { "C+N" , Nebula::NebCn  },
×
1369
                                { "RNE" , Nebula::NebRn  },
×
1370
                                { "HII" , Nebula::NebHII },
×
1371
                                { "SNR" , Nebula::NebSNR },
×
1372
                                { "BN"  , Nebula::NebBn  },
×
1373
                                { "EN"  , Nebula::NebEn  },
×
1374
                                { "SA"  , Nebula::NebSA  },
×
1375
                                { "SC"  , Nebula::NebSC  },
×
1376
                                { "CL"  , Nebula::NebCl  },
×
1377
                                { "IG"  , Nebula::NebIGx },
×
1378
                                { "RG"  , Nebula::NebRGx },
×
1379
                                { "AGX" , Nebula::NebAGx },
×
1380
                                { "QSO" , Nebula::NebQSO },
×
1381
                                { "ISM" , Nebula::NebISM },
×
1382
                                { "EMO" , Nebula::NebEMO },
×
1383
                                { "GNE" , Nebula::NebHII },
×
1384
                                { "RAD" , Nebula::NebISM },
×
1385
                                { "LIN" , Nebula::NebAGx },// LINER-type active galaxies
×
1386
                                { "BLL" , Nebula::NebBLL },
×
1387
                                { "BLA" , Nebula::NebBLA },
×
1388
                                { "MOC" , Nebula::NebMolCld },
×
1389
                                { "YSO" , Nebula::NebYSO },
×
1390
                                { "Q?"  , Nebula::NebPossQSO },
×
1391
                                { "PN?" , Nebula::NebPossPN },
×
1392
                                { "*"   , Nebula::NebStar},
×
1393
                                { "SFR" , Nebula::NebMolCld },
×
1394
                                { "IR"  , Nebula::NebDn  },
×
1395
                                { "**"  , Nebula::NebStar},
×
1396
                                { "MUL" , Nebula::NebStar},
×
1397
                                { "PPN" , Nebula::NebPPN },
×
1398
                                { "GIG" , Nebula::NebIGx },
×
1399
                                { "OPC" , Nebula::NebOc  },
×
1400
                                { "MGR" , Nebula::NebSA  },
×
1401
                                { "IG2" , Nebula::NebIGx },
×
1402
                                { "IG3" , Nebula::NebIGx },
×
1403
                                { "SY*" , Nebula::NebSymbioticStar},
×
1404
                                { "PA*" , Nebula::NebPPN },
×
1405
                                { "CV*" , Nebula::NebStar},
×
1406
                                { "Y*?" , Nebula::NebYSO },
×
1407
                                { "CGB" , Nebula::NebISM },
×
1408
                                { "SNRG", Nebula::NebSNR },
×
1409
                                { "Y*O" , Nebula::NebYSO },
×
1410
                                { "SR*" , Nebula::NebStar},
×
1411
                                { "EM*" , Nebula::NebEmissionLineStar },
×
1412
                                { "AB*" , Nebula::NebStar },
×
1413
                                { "MI*" , Nebula::NebStar },
×
1414
                                { "MI?" , Nebula::NebStar },
×
1415
                                { "TT*" , Nebula::NebStar },
×
1416
                                { "WR*" , Nebula::NebStar },
×
1417
                                { "C*"  , Nebula::NebEmissionLineStar },
×
1418
                                { "WD*" , Nebula::NebStar },
×
1419
                                { "EL*" , Nebula::NebStar },
×
1420
                                { "NL*" , Nebula::NebStar },
×
1421
                                { "NO*" , Nebula::NebStar },
×
1422
                                { "HS*" , Nebula::NebStar },
×
1423
                                { "LP*" , Nebula::NebStar },
×
1424
                                { "OH*" , Nebula::NebStar },
×
1425
                                { "S?R" , Nebula::NebStar },
×
1426
                                { "IR*" , Nebula::NebStar },
×
1427
                                { "POC" , Nebula::NebMolCld },
×
1428
                                { "PNB" , Nebula::NebPn   },
×
1429
                                { "GXCL", Nebula::NebGxCl },
×
1430
                                { "AL*" , Nebula::NebStar },
×
1431
                                { "PR*" , Nebula::NebStar },
×
1432
                                { "RS*" , Nebula::NebStar },
×
1433
                                { "S*B" , Nebula::NebStar },
×
1434
                                { "SN?" , Nebula::NebSNC  },
×
1435
                                { "SR?" , Nebula::NebSNRC },
×
1436
                                { "DNE" , Nebula::NebDn   },
×
1437
                                { "RG*" , Nebula::NebStar },
×
1438
                                { "PSR" , Nebula::NebSNR  },
×
1439
                                { "HH"  , Nebula::NebISM  },
×
1440
                                { "V*"  , Nebula::NebStar },
×
1441
                                { "*IN" , Nebula::NebCn   },
×
1442
                                { "SN*" , Nebula::NebStar },
×
1443
                                { "PA?" , Nebula::NebPPN  },
×
1444
                                { "BUB" , Nebula::NebISM  },
×
1445
                                { "CLG" , Nebula::NebGxCl },
×
1446
                                { "POG" , Nebula::NebPartOfGx },
×
1447
                                { "CGG" , Nebula::NebGxCl },
×
1448
                                { "SCG" , Nebula::NebGxCl },
×
1449
                                { "REG" , Nebula::NebRegion },
×
1450
                                { "?" , Nebula::NebUnknown }
×
1451
                        });
×
1452

1453
                        Nebula::NebulaType nType=oTypesHash.value(oType.toUpper(), Nebula::NebUnknown);
×
1454
                        if (nType == Nebula::NebUnknown)
×
1455
                                qDebug() << "Record with ID" << id <<"has unknown type of object:" << oType;
×
1456

1457
                        ++readOk;
×
1458

1459
                        dsoOutStream << id << raRad << decRad << bMag << vMag << static_cast<unsigned int>(nType) << mType << majorAxisSize << minorAxisSize
×
1460
                                     << orientationAngle << z << zErr << plx << plxErr << dist  << distErr << NGC << IC << M << C
×
1461
                                     << B << Sh2 << VdB << RCW  << LDN << LBN << Cr << Mel << PGC << UGC << Ced << Arp << VV << PK
×
1462
                                     << PNG << SNRG << ACO << HCG << ESO << VdBH << DWB << Tr << St << Ru << VdBHa;
×
1463
                }
×
1464
        }
×
1465
        dsoIn.close();
×
1466
        dsoOut.flush();
×
1467
        dsoOut.close();
×
1468
        qDebug().noquote() << "Converted" << readOk << "/" << totalRecords << "DSO records";
×
1469
        qDebug().noquote() << "[...] Please use 'gzip -nc catalog.pack > catalog.dat' to pack the catalog.";
×
1470
}
×
1471

1472
bool NebulaMgr::loadDSOCatalog(const QString &filename)
×
1473
{
1474
        QFile in(filename);
×
1475
        if (!in.open(QIODevice::ReadOnly))
×
1476
                return false;
×
1477

1478
        qDebug().noquote() << "Loading DSO data ...";
×
1479

1480
        // Let's begin use gzipped data
1481
        QDataStream ins(StelUtils::uncompress(in.readAll()));
×
1482
        ins.setVersion(QDataStream::Qt_5_2);
×
1483

1484
        QString version = "", edition= "";
×
1485
        int totalRecords=0;
×
1486
        while (!ins.atEnd())
×
1487
        {
1488
                if (totalRecords==0) // Read the version of catalog
×
1489
                {
1490
                        ins >> version >> edition;
×
1491
                        if (version.isEmpty())
×
1492
                                version = "3.1"; // The first version of extended edition of the catalog
×
1493
                        if (edition.isEmpty())
×
1494
                                edition = "unknown";
×
1495
                        qDebug().noquote() << "[...]" << QString("Stellarium DSO Catalog, version %1 (%2 edition)").arg(version, edition);
×
1496
                        if (StelUtils::compareVersions(version, StellariumDSOCatalogVersion)!=0)
×
1497
                        {
1498
                                ++totalRecords;
×
1499
                                qDebug().noquote() << "WARNING: Mismatch of DSO catalog version (" << version << ")! The expected version is" << StellariumDSOCatalogVersion;
×
1500
                                qDebug().noquote() << "         See section 5.5 of the User Guide and install the right version of the catalog!";
×
1501
                                QMessageBox::warning(&StelMainView::getInstance(), q_("Attention!"),
×
1502
                                                     QString("%1. %2: %3 - %4: %5. %6").arg(q_("DSO catalog version mismatch"),
×
1503
                                                                                            q_("Found"),
×
1504
                                                                                            version,
1505
                                                                                            q_("Expected"),
×
1506
                                                                                            StellariumDSOCatalogVersion,
1507
                                                                                            q_("See Logfile for instructions.")), QMessageBox::Ok);
×
1508
                                break;
×
1509
                        }
1510
                }
1511
                else
1512
                {
1513
                        // Create a new Nebula record
1514
                        NebulaP e = NebulaP(new Nebula);
×
1515
                        e->readDSO(ins);
×
1516

1517
                        dsoArray.append(e);
×
1518
                        nebGrid.insert(qSharedPointerCast<StelRegionObject>(e));
×
1519
                        if (e->DSO_nb!=0)
×
1520
                                dsoIndex.insert(e->DSO_nb, e);
×
1521
                }
×
1522
                ++totalRecords;
×
1523
        }
1524
        in.close();
×
1525
        qDebug().noquote() << "Loaded" << --totalRecords << "DSO records";
×
1526
        return true;
×
1527
}
×
1528

1529
bool NebulaMgr::loadDSONames(const QString &filename)
×
1530
{
1531
        qDebug() << "Loading DSO name data ...";
×
1532
        QFile dsoNameFile(filename);
×
1533
        if (!dsoNameFile.open(QIODevice::ReadOnly | QIODevice::Text))
×
1534
        {
1535
                qWarning().noquote() << "DSO name data file" << QDir::toNativeSeparators(filename) << "not found.";
×
1536
                return false;
×
1537
        }
1538

1539
        // Read the names of the deep-sky objects
1540
        QString name, record, ref, cdes;
×
1541
        QStringList nodata;
×
1542
        nodata.clear();
×
1543
        int totalRecords=0;
×
1544
        int readOk=0;
×
1545
        unsigned int nb;
1546
        NebulaP e;
×
1547
        static const QRegularExpression commentRx("^(\\s*#.*|\\s*)$");
×
1548
        while (!dsoNameFile.atEnd())
×
1549
        {
1550
                record = QString::fromUtf8(dsoNameFile.readLine());
×
1551
                if (commentRx.match(record).hasMatch())
×
1552
                        continue;
×
1553

1554
                totalRecords++;
×
1555

1556
                // bytes 1 - 5, designator for catalogue (prefix)
1557
                ref  = record.left(5).trimmed();
×
1558
                // bytes 6 -20, identificator for object in the catalog
1559
                cdes = record.mid(5, 15).trimmed().toUpper();
×
1560
                // bytes 21-80, proper name of the object (translatable)
1561
                name = record.mid(21).trimmed(); // Let gets the name with trimmed whitespaces
×
1562

1563
                nb = cdes.toUInt();
×
1564

1565
                static const QStringList catalogs = {
1566
                        "IC",    "M",   "C",  "CR",  "MEL",   "B", "SH2", "VDB", "RCW",  "LDN",
1567
                        "LBN", "NGC", "PGC", "UGC",  "CED", "ARP",  "VV",  "PK", "PNG", "SNRG",
1568
                        "ACO", "HCG", "ESO", "VDBH", "DWB", "TR", "ST", "RU", "DBHA"};
×
1569

1570
                switch (catalogs.indexOf(ref.toUpper()))
×
1571
                {
1572
                        case 0:
×
1573
                                e = searchIC(nb);
×
1574
                                break;
×
1575
                        case 1:
×
1576
                                e = searchM(nb);
×
1577
                                break;
×
1578
                        case 2:
×
1579
                                e = searchC(nb);
×
1580
                                break;
×
1581
                        case 3:
×
1582
                                e = searchCr(nb);
×
1583
                                break;
×
1584
                        case 4:
×
1585
                                e = searchMel(nb);
×
1586
                                break;
×
1587
                        case 5:
×
1588
                                e = searchB(nb);
×
1589
                                break;
×
1590
                        case 6:
×
1591
                                e = searchSh2(nb);
×
1592
                                break;
×
1593
                        case 7:
×
1594
                                e = searchVdB(nb);
×
1595
                                break;
×
1596
                        case 8:
×
1597
                                e = searchRCW(nb);
×
1598
                                break;
×
1599
                        case 9:
×
1600
                                e = searchLDN(nb);
×
1601
                                break;
×
1602
                        case 10:
×
1603
                                e = searchLBN(nb);
×
1604
                                break;
×
1605
                        case 11:
×
1606
                                e = searchNGC(nb);
×
1607
                                break;
×
1608
                        case 12:
×
1609
                                e = searchPGC(nb);
×
1610
                                break;
×
1611
                        case 13:
×
1612
                                e = searchUGC(nb);
×
1613
                                break;
×
1614
                        case 14:
×
1615
                                e = searchCed(cdes);
×
1616
                                break;
×
1617
                        case 15:
×
1618
                                e = searchArp(nb);
×
1619
                                break;
×
1620
                        case 16:
×
1621
                                e = searchVV(nb);
×
1622
                                break;
×
1623
                        case 17:
×
1624
                                e = searchPK(cdes);
×
1625
                                break;
×
1626
                        case 18:
×
1627
                                e = searchPNG(cdes);
×
1628
                                break;
×
1629
                        case 19:
×
1630
                                e = searchSNRG(cdes);
×
1631
                                break;
×
1632
                        case 20:
×
1633
                                e = searchACO(cdes);
×
1634
                                break;
×
1635
                        case 21:
×
1636
                                e = searchHCG(cdes);
×
1637
                                break;
×
1638
                        case 22:
×
1639
                                e = searchESO(cdes);
×
1640
                                break;
×
1641
                        case 23:
×
1642
                                e = searchVdBH(cdes);
×
1643
                                break;
×
1644
                        case 24:
×
1645
                                e = searchDWB(nb);
×
1646
                                break;
×
1647
                        case 25:
×
1648
                                e = searchTr(nb);
×
1649
                                break;
×
1650
                        case 26:
×
1651
                                e = searchSt(nb);
×
1652
                                break;
×
1653
                        case 27:
×
1654
                                e = searchRu(nb);
×
1655
                                break;
×
1656
                        case 28:
×
1657
                                e = searchVdBHa(nb);
×
1658
                                break;
×
1659
                        default:
×
1660
                                e = searchDSO(nb);
×
1661
                                break;
×
1662
                }
1663

1664
                if (!e.isNull())
×
1665
                {
1666
                        static const QRegularExpression transRx("_[(]\"(.*)\"[)](\\s*#.*)?"); // optional comments after name.
×
1667
                        QRegularExpressionMatch transMatch=transRx.match(name);
×
1668
                        if (transMatch.hasMatch())
×
1669
                        {
1670
                                QString propName = transMatch.captured(1).trimmed();
×
1671
                                QString currName = e->getEnglishName();
×
1672
                                if (currName.isEmpty())
×
1673
                                        e->setProperName(propName);
×
1674
                                else if (currName!=propName)
×
1675
                                        e->addNameAlias(propName);
×
1676
                        }
×
1677
                        readOk++;
×
1678
                }
×
1679
                else
1680
                        nodata.append(QString("%1 %2").arg(ref.trimmed(), cdes.trimmed()));
×
1681
        }
1682
        dsoNameFile.close();
×
1683
        qDebug().noquote() << "Loaded" << readOk << "/" << totalRecords << "DSO name records successfully";
×
1684

1685
        int err = nodata.size();
×
1686
        if (err>0)
×
1687
                qDebug().noquote() << "WARNING - No position data for" << err << "objects:" << nodata.join(", ");
×
1688

1689
        return true;
×
1690
}
×
1691

1692
bool NebulaMgr::loadDSODiscoveryData(const QString &filename)
×
1693
{
1694
        qDebug() << "Loading DSO discovery data ...";
×
1695
        QFile dsoDiscoveryFile(filename);
×
1696
        if (!dsoDiscoveryFile.open(QIODevice::ReadOnly | QIODevice::Text))
×
1697
        {
1698
                qWarning().noquote() << "DSO discovery data file" << QDir::toNativeSeparators(filename) << "not found.";
×
1699
                return false;
×
1700
        }
1701

1702
        int readOk = 0;
×
1703
        int totalRecords = 0;
×
1704
        QString record, dso, dYear, dName;
×
1705
        NebulaP e;
×
1706
        while (!dsoDiscoveryFile.atEnd())
×
1707
        {
1708
                record = QString::fromUtf8(dsoDiscoveryFile.readLine());
×
1709
                if (record.startsWith("//") || record.startsWith("#") || record.isEmpty())
×
1710
                        continue;
×
1711

1712
                totalRecords++;
×
1713
                #if (QT_VERSION>=QT_VERSION_CHECK(5, 14, 0))
1714
                QStringList list=record.split("\t", Qt::KeepEmptyParts);
×
1715
                #else
1716
                QStringList list=record.split("\t", QString::KeepEmptyParts);
1717
                #endif
1718

1719
                dso        = list.at(0).trimmed();
×
1720
                dYear        = list.at(1).trimmed();
×
1721
                dName        = list.at(2).trimmed();
×
1722

1723
                e = search(dso);
×
1724
                if (e.isNull()) // maybe this is inner number of DSO
×
1725
                        e = searchDSO(dso.toUInt());
×
1726

1727
                if (!e.isNull())
×
1728
                {
1729
                        e->setDiscoveryData(dName, dYear);
×
1730
                        readOk++;
×
1731
                }
1732
        }
×
1733
        dsoDiscoveryFile.close();
×
1734
        qDebug().noquote() << "Loaded" << readOk << "/" << totalRecords << "DSO discovery records successfully";
×
1735
        return true;
×
1736
}
×
1737

1738
bool NebulaMgr::loadDSOOutlines(const QString &filename)
×
1739
{
1740
        qDebug() << "Loading DSO outline data ...";
×
1741
        QFile dsoOutlineFile(filename);
×
1742
        if (!dsoOutlineFile.open(QIODevice::ReadOnly | QIODevice::Text))
×
1743
        {
1744
                qWarning().noquote() << "DSO outline data file" << QDir::toNativeSeparators(filename) << "not found.";
×
1745
                return false;
×
1746
        }
1747

1748
        double RA, DE;
1749
        int i, readOk = 0;
×
1750
        Vec3d XYZ;
×
1751
        std::vector<Vec3d> *points = Q_NULLPTR;
×
1752
        typedef QPair<double, double> coords;
1753
        coords point, fpoint;
×
1754
        QVector<coords> outline;
×
1755
        QString record, command, dso;
×
1756
        NebulaP e;
×
1757
        // Read the outlines data of the DSO
1758
        static const QRegularExpression commentRx("^(\\s*#.*|\\s*)$");
×
1759
        while (!dsoOutlineFile.atEnd())
×
1760
        {
1761
                record = QString::fromUtf8(dsoOutlineFile.readLine());
×
1762
                if (commentRx.match(record).hasMatch())
×
1763
                        continue;
×
1764

1765
#if (QT_VERSION>=QT_VERSION_CHECK(6,0,0))
1766
                // bytes 1 - 8, RA
1767
                RA = record.first(8).toDouble();
×
1768
                // bytes 9 -18, DE
1769
                DE = record.sliced(9, 10).toDouble();
×
1770
#else
1771
                // bytes 1 - 8, RA
1772
                RA = record.leftRef(8).toDouble();
1773
                // bytes 9 -18, DE
1774
                DE = record.midRef(9, 10).toDouble();
1775
#endif
1776
                // bytes 19-25, command
1777
                command = record.mid(19, 7).trimmed();
×
1778
                // bytes 26, designation of DSO
1779
                dso = record.mid(26).trimmed();
×
1780

1781
                RA*=M_PI/12.;     // Convert from hours to rad
×
1782
                DE*=M_PI/180.;    // Convert from deg to rad
×
1783

1784
                if (command.contains("start", Qt::CaseInsensitive))
×
1785
                {
1786
                        outline.clear();
×
1787
                        e = search(dso);
×
1788
                        if (e.isNull()) // maybe this is inner number of DSO
×
1789
                                e = searchDSO(dso.toUInt());
×
1790

1791
                        point.first  = RA;
×
1792
                        point.second = DE;
×
1793
                        outline.append(point);
×
1794
                        fpoint = point;
×
1795
                }
1796

1797
                if (command.contains("vertex", Qt::CaseInsensitive))
×
1798
                {
1799
                        point.first  = RA;
×
1800
                        point.second = DE;
×
1801
                        outline.append(point);
×
1802
                }
1803

1804
                if (command.contains("end", Qt::CaseInsensitive))
×
1805
                {
1806
                        point.first  = RA;
×
1807
                        point.second = DE;
×
1808
                        outline.append(point);
×
1809
                        outline.append(fpoint);
×
1810

1811
                        if (!e.isNull())
×
1812
                        {
1813
                                points = new std::vector<Vec3d>;
×
1814
                                for (i = 0; i < outline.size(); i++)
×
1815
                                {
1816
                                        // Calc the Cartesian coord with RA and DE
1817
                                        point = outline.at(i);
×
1818
                                        StelUtils::spheToRect(point.first, point.second, XYZ);
×
1819
                                        points->push_back(XYZ);
×
1820
                                }
1821

1822
                                e->outlineSegments.push_back(points);
×
1823
                        }
1824
                        readOk++;
×
1825
                }
1826
        }
1827
        dsoOutlineFile.close();
×
1828
        qDebug().noquote() << "Loaded" << readOk << "DSO outline records successfully";
×
1829
        return true;
×
1830
}
×
1831

1832
void NebulaMgr::updateSkyCulture(const StelSkyCulture& skyCulture)
×
1833
{
1834
        for (const auto& n : std::as_const(dsoArray))
×
1835
                n->removeAllNames();
×
1836

1837
        const auto nameToIdMap = loadCommonNames(skyCulture.fallbackToInternationalNames);
×
1838

1839
        int numLoaded = 0;
×
1840
        if (!skyCulture.names.isEmpty())
×
1841
                numLoaded = loadCultureSpecificNames(skyCulture.names, nameToIdMap);
×
1842

1843
        if (numLoaded)
×
1844
        {
1845
                qDebug() << "Loaded" << numLoaded << "culture-specific DSO names";
×
1846
        }
1847
        else
1848
        {
1849
                QString setName = "default";
×
1850
                QString dsoNamesPath = StelFileMgr::findFile("nebulae/" + setName + "/names.dat");
×
1851
                if (dsoNamesPath.isEmpty())
×
1852
                {
1853
                        qWarning().noquote() << "ERROR while loading deep-sky names data set" << setName;
×
1854
                        return;
×
1855
                }
1856
                loadDSONames(dsoNamesPath);
×
1857
        }
×
1858

1859
        updateI18n();
×
1860
}
×
1861

1862
int NebulaMgr::loadCultureSpecificNames(const QJsonObject& data, const QMap<QString/*name*/,QString/*dsoId*/>& commonNameToIdMap)
×
1863
{
1864
        int loadedTotal = 0;
×
1865
        for (auto it = data.begin(); it != data.end(); ++it)
×
1866
        {
1867
                const auto key = it.key();
×
1868
                const auto specificNames = it->toArray();
×
1869

1870
                if (key.startsWith("HIP "))
×
1871
                {
1872
                        // skip since it's a star
1873
                }
1874
                else if (key.startsWith("NAME "))
×
1875
                {
1876
                        // FIXME: this is a kludge for the discrepancy between stellarium-skycultures database
1877
                        // and Stellarium's internal database. Maybe we should make use of the former and drop
1878
                        // the latter instead of doing this name translation.
1879
                        auto name = key.mid(5);
×
1880
                        static const QHash<QString, QString> renamer{
1881
                                {"Beehive Cluster" , "Beehive"           },
1882
                                {"Carina Nebula"   , "Eta Carinae Nebula"},
1883
                                {u8"ω Cen Cluster" , "Omega Centauri"    },
1884
                        };
×
1885
                        if (const auto it = renamer.find(name); it != renamer.end())
×
1886
                                name = it.value();
×
1887
                        loadCultureSpecificNameForNamedObject(it.value().toArray(), name, commonNameToIdMap);
×
1888
                }
×
1889
                else if (key.startsWith("C "))
×
1890
                {
1891
                        // Caldwell object
1892
                        const unsigned c_nb = key.mid(2).toInt();
×
1893
                        if (c_nb <= 0)
×
1894
                        {
1895
                                qWarning() << "Bad common_names Caldwell object name:" << key;
×
1896
                                continue;
×
1897
                        }
1898
                        for (const auto& n : dsoArray)
×
1899
                        {
1900
                                if (n->C_nb != c_nb) continue;
×
1901

1902
                                for (const auto& entry : specificNames)
×
1903
                                {
1904
                                        const auto specificName = entry.toObject()["english"].toString();
×
1905
                                        if (specificName.isEmpty())
×
1906
                                        {
1907
                                                qWarning().nospace() << "Bad culture-specific name for object " << key << ": " << specificName;
×
1908
                                                continue;
×
1909
                                        }
1910
                                        setName(n, specificName);
×
1911
                                        ++loadedTotal;
×
1912
                                }
×
1913
                        }
1914
                }
1915
                else if (key.startsWith("M "))
×
1916
                {
1917
                        // Messier object
1918
                        const unsigned m_nb = key.mid(2).toInt();
×
1919
                        if (m_nb <= 0)
×
1920
                        {
1921
                                qWarning() << "Bad common_names Messier object name:" << key;
×
1922
                                continue;
×
1923
                        }
1924
                        for (const auto& n : dsoArray)
×
1925
                        {
1926
                                if (n->M_nb != m_nb) continue;
×
1927

1928
                                for (const auto& entry : specificNames)
×
1929
                                {
1930
                                        const auto specificName = entry.toObject()["english"].toString();
×
1931
                                        if (specificName.isEmpty())
×
1932
                                        {
1933
                                                qWarning().nospace() << "Bad culture-specific name for object " << key << ": " << specificName;
×
1934
                                                continue;
×
1935
                                        }
1936
                                        setName(n, specificName);
×
1937
                                        ++loadedTotal;
×
1938
                                }
×
1939
                        }
1940
                }
1941
                else
1942
                {
1943
                        qWarning() << "NebulaMgr: unexpected common_names key:" << key;
×
1944
                }
1945
        }
×
1946
        return loadedTotal;
×
1947
}
×
1948

1949
void NebulaMgr::loadCultureSpecificNameForNamedObject(const QJsonArray& data, const QString& commonName,
×
1950
                                                      const QMap<QString/*name*/,QString/*dsoId*/>& commonNameToIdMap)
1951
{
1952
        const auto commonNameIndexIt = commonNameToIdMap.find(commonName.toUpper());
×
1953
        if (commonNameIndexIt == commonNameToIdMap.end())
×
1954
        {
1955
                // This may actually not even be a nebula, so we shouldn't emit any warning, just return
1956
                return;
×
1957
        }
1958
        const auto dsoId = commonNameIndexIt.value();
×
1959

1960
        for (const auto& entry : data)
×
1961
        {
1962
                const auto specificName = entry.toObject()["english"].toString();
×
1963
                if (specificName.isEmpty()) continue;
×
1964

1965
                NebulaP e = search(dsoId);
×
1966
                if (!e.isNull()) // avoid crash
×
1967
                        setName(e, specificName);
×
1968
                else
1969
                        qWarning() << "Failed to find DSO" << dsoId;
×
1970
        }
×
1971
}
×
1972
QMap<QString/*name*/,QString/*dsoId*/> NebulaMgr::loadCommonNames(const bool saveIntoObjects)
×
1973
{
1974
        QString namesFile = StelFileMgr::findFile("skycultures/common_dso_names.fab");
×
1975
        if (namesFile.isEmpty())
×
1976
        {
1977
                qWarning().noquote() << "Failed to open common DSO names file";
×
1978
                return {};
×
1979
        }
1980

1981
        // Open file
1982
        QFile dsoNamesFile(namesFile);
×
1983
        if (!dsoNamesFile.open(QIODevice::ReadOnly | QIODevice::Text))
×
1984
        {
1985
                qWarning().noquote() << "Failed to open file" << QDir::toNativeSeparators(namesFile);
×
1986
                return {};
×
1987
        }
1988

1989
        // Now parse the file
1990
        // lines to ignore which start with a # or are empty
1991
        static const QRegularExpression commentRx("^(\\s*#.*|\\s*)$");
×
1992

1993
        // lines which look like records - we use the RE to extract the fields
1994
        // which will be available in recMatch.capturedTexts()
1995
        static const QRegularExpression recRx("^\\s*([\\w\\s\\-\\+\\.]+)\\s*\\|[_]*[(]\"(.*)\"[)]\\s*([\\,\\d\\s]*)");
×
1996

1997
        QMap<QString/*name*/,QString/*dsoId*/> output;
×
1998
        QString record, dsoId, nativeName;
×
1999
        int totalRecords=0;
×
2000
        int readOk=0;
×
2001
        int lineNumber=0;
×
2002
        while (!dsoNamesFile.atEnd())
×
2003
        {
2004
                record = QString::fromUtf8(dsoNamesFile.readLine()).trimmed();
×
2005
                lineNumber++;
×
2006

2007
                // Skip comments
2008
                if (commentRx.match(record).hasMatch())
×
2009
                        continue;
×
2010

2011
                totalRecords++;
×
2012

2013
                QRegularExpressionMatch recMatch=recRx.match(record);
×
2014
                if (!recMatch.hasMatch())
×
2015
                {
2016
                        qWarning().noquote() << "ERROR - cannot parse record at line" << lineNumber << "in native deep-sky object names file" << QDir::toNativeSeparators(namesFile);
×
2017
                }
2018
                else
2019
                {
2020
                        dsoId = recMatch.captured(1).trimmed();
×
2021
                        nativeName = recMatch.captured(2).trimmed(); // Use translatable text
×
2022
                        NebulaP e = search(dsoId);
×
2023
                        if (!e.isNull()) // avoid crash
×
2024
                        {
2025
                                if (saveIntoObjects)
×
2026
                                        setName(e, nativeName);
×
2027
                                output[nativeName.toUpper()] = dsoId;
×
2028
                        }
2029
                        else
2030
                                qWarning().noquote() << "ERROR - could NOT found DSO " << dsoId;
×
2031

2032
                        readOk++;
×
2033
                }
×
2034
        }
×
2035
        dsoNamesFile.close();
×
2036
        qDebug().noquote() << "Loaded" << readOk << "/" << totalRecords << "common names of deep-sky objects";
×
2037

2038
        return output;
×
2039
}
×
2040

2041
void NebulaMgr::updateI18n()
×
2042
{
2043
        const StelTranslator& trans = StelApp::getInstance().getLocaleMgr().getSkyTranslator();
×
2044
        for (const auto& n : std::as_const(dsoArray))
×
2045
                n->translateName(trans);
×
2046
}
×
2047

2048

2049
//! Return the matching Nebula object's pointer if exists or an "empty" StelObjectP
2050
StelObjectP NebulaMgr::searchByNameI18n(const QString& nameI18n) const
×
2051
{
2052
        QString objw = nameI18n.toUpper();
×
2053

2054
        // Search by common names
2055
        for (const auto& n : std::as_const(dsoArray))
×
2056
        {
2057
                QString objwcap = n->nameI18.toUpper();
×
2058
                if (objwcap==objw)
×
2059
                        return qSharedPointerCast<StelObject>(n);
×
2060
        }
×
2061

2062
        // Search by aliases of common names
2063
        for (const auto& n : std::as_const(dsoArray))
×
2064
        {
2065
                for (auto &objwcapa : n->nameI18Aliases)
×
2066
                {
2067
                        if (objwcapa.toUpper()==objw)
×
2068
                                return qSharedPointerCast<StelObject>(n);
×
2069
                }
2070
        }
2071

2072
        // Search by designation
2073
        NebulaP n = searchByDesignation(objw);
×
2074
        return qSharedPointerCast<StelObject>(n);
×
2075
}
×
2076

2077

2078
//! Return the matching Nebula object's pointer if exists or an "empty" StelObjectP
2079
StelObjectP NebulaMgr::searchByName(const QString& name) const
×
2080
{
2081
        QString objw = name.toUpper();
×
2082

2083
        // Search by common names
2084
        for (const auto& n : dsoArray)
×
2085
        {
2086
                QString objwcap = n->englishName.toUpper();
×
2087
                if (objwcap==objw)
×
2088
                        return qSharedPointerCast<StelObject>(n);
×
2089
        }
×
2090

2091
        if (getFlagAdditionalNames())
×
2092
        {
2093
                // Search by aliases of common names
2094
                for (const auto& n : dsoArray)
×
2095
                {
2096
                        for (auto &objwcapa : n->englishAliases)
×
2097
                        {
2098
                                if (objwcapa.toUpper()==objw)
×
2099
                                        return qSharedPointerCast<StelObject>(n);
×
2100
                        }
2101
                }
2102
        }
2103

2104
        // Search by designation
2105
        NebulaP n = searchByDesignation(objw);
×
2106
        return qSharedPointerCast<StelObject>(n);
×
2107
}
×
2108

2109
//! Return the matching Nebula object's pointer if exists or Q_NULLPTR
2110
//! TODO Decide whether empty StelObjectP or Q_NULLPTR is the better return type and select the same for both.
2111
NebulaP NebulaMgr::searchByDesignation(const QString &designation) const
×
2112
{
2113
        NebulaP n;
×
2114
        QString uname = designation.toUpper();
×
2115
        // If no match found, try search by catalog reference
2116
        static const QRegularExpression catNumRx("^(M|NGC|IC|C|B|VDB|RCW|LDN|LBN|CR|MEL|PGC|UGC|ARP|VV|DWB|TR|TRUMPLER|ST|STOCK|RU|RUPRECHT|VDB-HA)\\s*(\\d+)$");
×
2117
        QRegularExpressionMatch catNumMatch=catNumRx.match(uname);
×
2118
        if (catNumMatch.hasMatch())
×
2119
        {
2120
                QString cat = catNumMatch.captured(1);
×
2121
                unsigned int num = catNumMatch.captured(2).toUInt();
×
2122
                if (cat == "M") n = searchM(num);
×
2123
                if (cat == "NGC") n = searchNGC(num);
×
2124
                if (cat == "IC") n = searchIC(num);
×
2125
                if (cat == "C") n = searchC(num);
×
2126
                if (cat == "B") n = searchB(num);
×
2127
                if (cat == "VDB-HA") n = searchVdBHa(num);
×
2128
                if (cat == "VDB") n = searchVdB(num);
×
2129
                if (cat == "RCW") n = searchRCW(num);
×
2130
                if (cat == "LDN") n = searchLDN(num);
×
2131
                if (cat == "LBN") n = searchLBN(num);
×
2132
                if (cat == "CR") n = searchCr(num);
×
2133
                if (cat == "MEL") n = searchMel(num);
×
2134
                if (cat == "PGC") n = searchPGC(num);
×
2135
                if (cat == "UGC") n = searchUGC(num);
×
2136
                if (cat == "ARP") n = searchArp(num);
×
2137
                if (cat == "VV") n = searchVV(num);
×
2138
                if (cat == "DWB") n = searchDWB(num);
×
2139
                if (cat == "TR" || cat == "TRUMPLER") n = searchTr(num);
×
2140
                if (cat == "ST" || cat == "STOCK") n = searchSt(num);
×
2141
                if (cat == "RU" || cat == "RUPRECHT") n = searchRu(num);
×
2142
        }
×
2143
        static const QRegularExpression dCatNumRx("^(SH)\\s*\\d-\\s*(\\d+)$");
×
2144
        QRegularExpressionMatch dCatNumMatch=dCatNumRx.match(uname);
×
2145
        if (dCatNumMatch.hasMatch())
×
2146
        {
2147
                QString dcat = dCatNumMatch.captured(1);
×
2148
                unsigned int dnum = dCatNumMatch.captured(2).toUInt();
×
2149

2150
                if (dcat == "SH") n = searchSh2(dnum);
×
2151
        }
×
2152
        static const QRegularExpression sCatNumRx("^(CED|PK|ACO|ABELL|HCG|ESO|VDBH)\\s*(.+)$");
×
2153
        QRegularExpressionMatch sCatNumMatch=sCatNumRx.match(uname);
×
2154
        if (sCatNumMatch.hasMatch())
×
2155
        {
2156
                QString cat = sCatNumMatch.captured(1);
×
2157
                QString num = sCatNumMatch.captured(2).trimmed();
×
2158

2159
                if (cat == "CED") n = searchCed(num);
×
2160
                if (cat == "PK") n = searchPK(num);
×
2161
                if (cat == "ACO" || cat == "ABELL") n = searchACO(num);
×
2162
                if (cat == "HCG") n = searchHCG(num);
×
2163
                if (cat == "ESO") n = searchESO(num);
×
2164
                if (cat == "VDBH") n = searchVdBH(num);
×
2165
        }
×
2166
        static const QRegularExpression gCatNumRx("^(PN|SNR)\\s*G(.+)$");
×
2167
        QRegularExpressionMatch gCatNumMatch=gCatNumRx.match(uname);
×
2168
        if (gCatNumMatch.hasMatch())
×
2169
        {
2170
                QString cat = gCatNumMatch.captured(1);
×
2171
                QString num = gCatNumMatch.captured(2).trimmed();
×
2172

2173
                if (cat == "PN") n = searchPNG(num);
×
2174
                if (cat == "SNR") n = searchSNRG(num);
×
2175
        }
×
2176

2177
        return n;
×
2178
}
×
2179

2180
//! Find and return the list of at most maxNbItem objects auto-completing the passed object name
2181
QStringList NebulaMgr::listMatchingObjects(const QString& objPrefix, int maxNbItem, bool useStartOfWords) const
×
2182
{
2183
        QStringList result;
×
2184
        if (maxNbItem <= 0)
×
2185
                return result;
×
2186

2187
        QString objw = objPrefix.toUpper();
×
2188

2189
        // Search by Messier objects number (possible formats are "M31" or "M 31")
2190
        if (objw.size()>=1 && objw.at(0)=='M' && objw.left(3)!="MEL")
×
2191
        {
2192
                for (const auto& n : dsoArray)
×
2193
                {
2194
                        if (n->M_nb==0) continue;
×
2195
                        QString constw = QString("M%1").arg(n->M_nb);
×
2196
                        QString constws = constw.mid(0, objw.size());
×
2197
                        if (constws.toUpper()==objw)
×
2198
                        {
2199
                                result << constws;
×
2200
                                continue;        // Prevent adding both forms for name
×
2201
                        }
2202
                        constw = QString("M %1").arg(n->M_nb);
×
2203
                        constws = constw.mid(0, objw.size());
×
2204
                        if (constws.toUpper()==objw)
×
2205
                                result << constw;
×
2206
                }
×
2207
        }
2208

2209
        // Search by Melotte objects number (possible formats are "Mel31" or "Mel 31")
2210
        if (objw.size()>=1 && objw.left(3)=="MEL")
×
2211
        {
2212
                for (const auto& n : dsoArray)
×
2213
                {
2214
                        if (n->Mel_nb==0) continue;
×
2215
                        QString constw = QString("Mel%1").arg(n->Mel_nb);
×
2216
                        QString constws = constw.mid(0, objw.size());
×
2217
                        QString constws2 = QString("Melotte%1").arg(n->Mel_nb).mid(0, objw.size());
×
2218
                        if (constws.toUpper()==objw || constws2.toUpper()==objw)
×
2219
                        {
2220
                                result << constws;
×
2221
                                continue;        // Prevent adding both forms for name
×
2222
                        }
2223
                        constw = QString("Mel %1").arg(n->Mel_nb);
×
2224
                        constws = constw.mid(0, objw.size());
×
2225
                        constws2 = QString("Melotte %1").arg(n->Mel_nb).mid(0, objw.size());
×
2226
                        if (constws.toUpper()==objw || constws2.toUpper()==objw)
×
2227
                                result << constw;
×
2228
                }
×
2229
        }
2230

2231
        // Search by IC objects number (possible formats are "IC466" or "IC 466")
2232
        if (objw.size()>=1 && objw.left(2)=="IC")
×
2233
        {
2234
                for (const auto& n : dsoArray)
×
2235
                {
2236
                        if (n->IC_nb==0) continue;
×
2237
                        QString constw = QString("IC%1").arg(n->IC_nb);
×
2238
                        QString constws = constw.mid(0, objw.size());
×
2239
                        if (constws.toUpper()==objw)
×
2240
                        {
2241
                                result << constws;
×
2242
                                continue;        // Prevent adding both forms for name
×
2243
                        }
2244
                        constw = QString("IC %1").arg(n->IC_nb);
×
2245
                        constws = constw.mid(0, objw.size());
×
2246
                        if (constws.toUpper()==objw)
×
2247
                                result << constw;
×
2248
                }
×
2249
        }
2250

2251
        // Search by NGC numbers (possible formats are "NGC31" or "NGC 31")
2252
        for (const auto& n : dsoArray)
×
2253
        {
2254
                if (n->NGC_nb==0) continue;
×
2255
                QString constw = QString("NGC%1").arg(n->NGC_nb);
×
2256
                QString constws = constw.mid(0, objw.size());
×
2257
                if (constws.toUpper()==objw)
×
2258
                {
2259
                        result << constws;
×
2260
                        continue;
×
2261
                }
2262
                constw = QString("NGC %1").arg(n->NGC_nb);
×
2263
                constws = constw.mid(0, objw.size());
×
2264
                if (constws.toUpper()==objw)
×
2265
                        result << constw;
×
2266
        }
×
2267

2268
        // Search by PGC object numbers (possible formats are "PGC31" or "PGC 31")
2269
        if (objw.size()>=1 && objw.left(3)=="PGC")
×
2270
        {
2271
                for (const auto& n : dsoArray)
×
2272
                {
2273
                        if (n->PGC_nb==0) continue;
×
2274
                        QString constw = QString("PGC%1").arg(n->PGC_nb);
×
2275
                        QString constws = constw.mid(0, objw.size());
×
2276
                        if (constws.toUpper()==objw)
×
2277
                        {
2278
                                result << constws;        // Prevent adding both forms for name
×
2279
                                continue;
×
2280
                        }
2281
                        constw = QString("PGC %1").arg(n->PGC_nb);
×
2282
                        constws = constw.mid(0, objw.size());
×
2283
                        if (constws.toUpper()==objw)
×
2284
                                result << constw;
×
2285
                }
×
2286
        }
2287

2288
        // Search by UGC object numbers (possible formats are "UGC31" or "UGC 31")
2289
        if (objw.size()>=1 && objw.left(3)=="UGC")
×
2290
        {
2291
                for (const auto& n : dsoArray)
×
2292
                {
2293
                        if (n->UGC_nb==0) continue;
×
2294
                        QString constw = QString("UGC%1").arg(n->UGC_nb);
×
2295
                        QString constws = constw.mid(0, objw.size());
×
2296
                        if (constws.toUpper()==objw)
×
2297
                        {
2298
                                result << constws;
×
2299
                                continue;        // Prevent adding both forms for name
×
2300
                        }
2301
                        constw = QString("UGC %1").arg(n->UGC_nb);
×
2302
                        constws = constw.mid(0, objw.size());
×
2303
                        if (constws.toUpper()==objw)
×
2304
                                result << constw;
×
2305
                }
×
2306
        }
2307

2308
        // Search by Caldwell objects number (possible formats are "C31" or "C 31")
2309
        if (objw.size()>=1 && objw.at(0)=='C' && objw.left(2)!="CR" && objw.left(2)!="CE")
×
2310
        {
2311
                for (const auto& n : dsoArray)
×
2312
                {
2313
                        if (n->C_nb==0) continue;
×
2314
                        QString constw = QString("C%1").arg(n->C_nb);
×
2315
                        QString constws = constw.mid(0, objw.size());
×
2316
                        if (constws.toUpper()==objw)
×
2317
                        {
2318
                                result << constws;
×
2319
                                continue;        // Prevent adding both forms for name
×
2320
                        }
2321
                        constw = QString("C %1").arg(n->C_nb);
×
2322
                        constws = constw.mid(0, objw.size());
×
2323
                        if (constws.toUpper()==objw)
×
2324
                                result << constw;
×
2325
                }
×
2326
        }
2327

2328
        // Search by Collinder objects number (possible formats are "Cr31" or "Cr 31")
2329
        if (objw.size()>=1 && (objw.left(2)=="CR" || objw.left(9)=="COLLINDER"))
×
2330
        {
2331
                for (const auto& n : dsoArray)
×
2332
                {
2333
                        if (n->Cr_nb==0) continue;
×
2334
                        QString constw = QString("Cr%1").arg(n->Cr_nb);
×
2335
                        QString constws = constw.mid(0, objw.size());
×
2336
                        QString constws2 = QString("Collinder%1").arg(n->Cr_nb).mid(0, objw.size());
×
2337
                        if (constws.toUpper()==objw || constws2.toUpper()==objw)
×
2338
                        {
2339
                                result << constws;
×
2340
                                continue;        // Prevent adding both forms for name
×
2341
                        }
2342
                        constw = QString("Cr %1").arg(n->Cr_nb);
×
2343
                        constws = constw.mid(0, objw.size());
×
2344
                        constws2 = QString("Collinder %1").arg(n->Cr_nb).mid(0, objw.size());
×
2345
                        if (constws.toUpper()==objw || constws2.toUpper()==objw)
×
2346
                                result << constw;
×
2347
                }
×
2348
        }
2349

2350
        // Search by Ced objects number (possible formats are "Ced31" or "Ced 31")
2351
        if (objw.size()>=1 && objw.left(3)=="CED")
×
2352
        {
2353
                for (const auto& n : dsoArray)
×
2354
                {
2355
                        if (n->Ced_nb.isEmpty()) continue;
×
2356
                        QString constw = QString("Ced%1").arg(n->Ced_nb.trimmed());
×
2357
                        QString constws = constw.mid(0, objw.size());
×
2358
                        if (constws.toUpper()==objw)
×
2359
                        {
2360
                                result << constws;
×
2361
                                continue;        // Prevent adding both forms for name
×
2362
                        }
2363
                        constw = QString("Ced %1").arg(n->Ced_nb.trimmed());
×
2364
                        constws = constw.mid(0, objw.size());
×
2365
                        if (constws.toUpper()==objw)
×
2366
                                result << constw;
×
2367
                }
×
2368
        }
2369

2370
        // Search by Barnard objects number (possible formats are "B31" or "B 31")
2371
        if (objw.size()>=1 && objw.at(0)=='B')
×
2372
        {
2373
                for (const auto& n : dsoArray)
×
2374
                {
2375
                        if (n->B_nb==0) continue;
×
2376
                        QString constw = QString("B%1").arg(n->B_nb);
×
2377
                        QString constws = constw.mid(0, objw.size());
×
2378
                        if (constws.toUpper()==objw)
×
2379
                        {
2380
                                result << constws;
×
2381
                                continue;        // Prevent adding both forms for name
×
2382
                        }
2383
                        constw = QString("B %1").arg(n->B_nb);
×
2384
                        constws = constw.mid(0, objw.size());
×
2385
                        if (constws.toUpper()==objw)
×
2386
                                result << constw;
×
2387
                }
×
2388
        }
2389

2390
        // Search by Sharpless objects number (possible formats are "Sh2-31" or "Sh 2-31")
2391
        if (objw.size()>=1 && objw.left(2)=="SH")
×
2392
        {
2393
                for (const auto& n : dsoArray)
×
2394
                {
2395
                        if (n->Sh2_nb==0) continue;
×
2396
                        QString constw = QString("SH2-%1").arg(n->Sh2_nb);
×
2397
                        QString constws = constw.mid(0, objw.size());
×
2398
                        if (constws.toUpper()==objw)
×
2399
                        {
2400
                                result << constws;
×
2401
                                continue;        // Prevent adding both forms for name
×
2402
                        }
2403
                        constw = QString("SH 2-%1").arg(n->Sh2_nb);
×
2404
                        constws = constw.mid(0, objw.size());
×
2405
                        if (constws.toUpper()==objw)
×
2406
                                result << constw;
×
2407
                }
×
2408
        }
2409

2410
        // Search by van den Bergh objects number (possible formats are "vdB31" or "vdB 31")
2411
        if (objw.size()>=1 && objw.left(3)=="VDB" && objw.left(6)!="VDB-HA" && objw.left(4)!="VDBH")
×
2412
        {
2413
                for (const auto& n : dsoArray)
×
2414
                {
2415
                        if (n->VdB_nb==0) continue;
×
2416
                        QString constw = QString("vdB%1").arg(n->VdB_nb);
×
2417
                        QString constws = constw.mid(0, objw.size());
×
2418
                        if (constws.toUpper()==objw)
×
2419
                        {
2420
                                result << constws;
×
2421
                                continue;        // Prevent adding both forms for name
×
2422
                        }
2423
                        constw = QString("vdB %1").arg(n->VdB_nb);
×
2424
                        constws = constw.mid(0, objw.size());
×
2425
                        if (constws.toUpper()==objw)
×
2426
                                result << constw;
×
2427
                }
×
2428
        }
2429

2430
        // Search by RCW objects number (possible formats are "RCW31" or "RCW 31")
2431
        if (objw.size()>=1 && objw.left(3)=="RCW")
×
2432
        {
2433
                for (const auto& n : dsoArray)
×
2434
                {
2435
                        if (n->RCW_nb==0) continue;
×
2436
                        QString constw = QString("RCW%1").arg(n->RCW_nb);
×
2437
                        QString constws = constw.mid(0, objw.size());
×
2438
                        if (constws.toUpper()==objw)
×
2439
                        {
2440
                                result << constws;
×
2441
                                continue;        // Prevent adding both forms for name
×
2442
                        }
2443
                        constw = QString("RCW %1").arg(n->RCW_nb);
×
2444
                        constws = constw.mid(0, objw.size());
×
2445
                        if (constws.toUpper()==objw)
×
2446
                                result << constw;
×
2447
                }
×
2448
        }
2449

2450
        // Search by LDN objects number (possible formats are "LDN31" or "LDN 31")
2451
        if (objw.size()>=1 && objw.left(3)=="LDN")
×
2452
        {
2453
                for (const auto& n : dsoArray)
×
2454
                {
2455
                        if (n->LDN_nb==0) continue;
×
2456
                        QString constw = QString("LDN%1").arg(n->LDN_nb);
×
2457
                        QString constws = constw.mid(0, objw.size());
×
2458
                        if (constws.toUpper()==objw)
×
2459
                        {
2460
                                result << constws;
×
2461
                                continue;        // Prevent adding both forms for name
×
2462
                        }
2463
                        constw = QString("LDN %1").arg(n->LDN_nb);
×
2464
                        constws = constw.mid(0, objw.size());
×
2465
                        if (constws.toUpper()==objw)
×
2466
                                result << constw;
×
2467
                }
×
2468
        }
2469

2470
        // Search by LBN objects number (possible formats are "LBN31" or "LBN 31")
2471
        if (objw.size()>=1 && objw.left(3)=="LBN")
×
2472
        {
2473
                for (const auto& n : dsoArray)
×
2474
                {
2475
                        if (n->LBN_nb==0) continue;
×
2476
                        QString constw = QString("LBN%1").arg(n->LBN_nb);
×
2477
                        QString constws = constw.mid(0, objw.size());
×
2478
                        if (constws.toUpper()==objw)
×
2479
                        {
2480
                                result << constws;
×
2481
                                continue;        // Prevent adding both forms for name
×
2482
                        }
2483
                        constw = QString("LBN %1").arg(n->LBN_nb);
×
2484
                        constws = constw.mid(0, objw.size());
×
2485
                        if (constws.toUpper()==objw)
×
2486
                                result << constw;
×
2487
                }
×
2488
        }
2489

2490
        // Search by Arp objects number
2491
        if (objw.size()>=1 && objw.left(3)=="ARP")
×
2492
        {
2493
                for (const auto& n : dsoArray)
×
2494
                {
2495
                        if (n->Arp_nb==0) continue;
×
2496
                        QString constw = QString("Arp%1").arg(n->Arp_nb);
×
2497
                        QString constws = constw.mid(0, objw.size());
×
2498
                        if (constws.toUpper()==objw)
×
2499
                        {
2500
                                result << constws;
×
2501
                                continue;        // Prevent adding both forms for name
×
2502
                        }
2503
                        constw = QString("Arp %1").arg(n->Arp_nb);
×
2504
                        constws = constw.mid(0, objw.size());
×
2505
                        if (constws.toUpper()==objw)
×
2506
                                result << constw;
×
2507
                }
×
2508
        }
2509

2510
        // Search by VV objects number
2511
        if (objw.size()>=1 && objw.left(2)=="VV")
×
2512
        {
2513
                for (const auto& n : dsoArray)
×
2514
                {
2515
                        if (n->VV_nb==0) continue;
×
2516
                        QString constw = QString("VV%1").arg(n->VV_nb);
×
2517
                        QString constws = constw.mid(0, objw.size());
×
2518
                        if (constws.toUpper()==objw)
×
2519
                        {
2520
                                result << constws;
×
2521
                                continue;        // Prevent adding both forms for name
×
2522
                        }
2523
                        constw = QString("VV %1").arg(n->VV_nb);
×
2524
                        constws = constw.mid(0, objw.size());
×
2525
                        if (constws.toUpper()==objw)
×
2526
                                result << constw;
×
2527
                }
×
2528
        }
2529

2530
        // Search by PK objects number
2531
        if (objw.size()>=1 && objw.left(2)=="PK")
×
2532
        {
2533
                for (const auto& n : dsoArray)
×
2534
                {
2535
                        if (n->PK_nb.isEmpty()) continue;
×
2536
                        QString constw = QString("PK%1").arg(n->PK_nb.trimmed());
×
2537
                        QString constws = constw.mid(0, objw.size());
×
2538
                        if (constws.toUpper()==objw)
×
2539
                        {
2540
                                result << constws;
×
2541
                                continue;        // Prevent adding both forms for name
×
2542
                        }
2543
                        constw = QString("PK %1").arg(n->PK_nb.trimmed());
×
2544
                        constws = constw.mid(0, objw.size());
×
2545
                        if (constws.toUpper()==objw)
×
2546
                                result << constw;
×
2547
                }
×
2548
        }
2549

2550
        // Search by PN G objects number
2551
        if (objw.size()>=1 && objw.left(2)=="PN")
×
2552
        {
2553
                for (const auto& n : dsoArray)
×
2554
                {
2555
                        if (n->PNG_nb.isEmpty()) continue;
×
2556
                        QString constw = QString("PNG%1").arg(n->PNG_nb.trimmed());
×
2557
                        QString constws = constw.mid(0, objw.size());
×
2558
                        if (constws.toUpper()==objw)
×
2559
                        {
2560
                                result << constws;
×
2561
                                continue;        // Prevent adding both forms for name
×
2562
                        }
2563
                        constw = QString("PN G%1").arg(n->PNG_nb.trimmed());
×
2564
                        constws = constw.mid(0, objw.size());
×
2565
                        if (constws.toUpper()==objw)
×
2566
                                result << constw;
×
2567
                }
×
2568
        }
2569

2570
        // Search by SNR G objects number
2571
        if (objw.size()>=1 && objw.left(3)=="SNR")
×
2572
        {
2573
                for (const auto& n : dsoArray)
×
2574
                {
2575
                        if (n->SNRG_nb.isEmpty()) continue;
×
2576
                        QString constw = QString("SNRG%1").arg(n->SNRG_nb.trimmed());
×
2577
                        QString constws = constw.mid(0, objw.size());
×
2578
                        if (constws.toUpper()==objw)
×
2579
                        {
2580
                                result << constws;
×
2581
                                continue;        // Prevent adding both forms for name
×
2582
                        }
2583
                        constw = QString("SNR G%1").arg(n->SNRG_nb.trimmed());
×
2584
                        constws = constw.mid(0, objw.size());
×
2585
                        if (constws.toUpper()==objw)
×
2586
                                result << constw;
×
2587
                }
×
2588
        }
2589

2590
        // Search by ACO (Abell) objects number
2591
        if (objw.size()>=1 && (objw.left(5)=="ABELL" || objw.left(3)=="ACO"))
×
2592
        {
2593
                for (const auto& n : dsoArray)
×
2594
                {
2595
                        if (n->ACO_nb.isEmpty()) continue;
×
2596
                        QString constw = QString("Abell%1").arg(n->ACO_nb.trimmed());
×
2597
                        QString constws = constw.mid(0, objw.size());
×
2598
                        QString constws2 = QString("ACO%1").arg(n->ACO_nb.trimmed()).mid(0, objw.size());
×
2599
                        if (constws.toUpper()==objw || constws2.toUpper()==objw)
×
2600
                        {
2601
                                result << constws;
×
2602
                                continue;        // Prevent adding both forms for name
×
2603
                        }
2604
                        constw = QString("Abell %1").arg(n->ACO_nb.trimmed());
×
2605
                        constws = constw.mid(0, objw.size());
×
2606
                        constws2 = QString("ACO %1").arg(n->ACO_nb.trimmed()).mid(0, objw.size());
×
2607
                        if (constws.toUpper()==objw || constws2.toUpper()==objw)
×
2608
                                result << constw;
×
2609
                }
×
2610
        }
2611

2612
        // Search by HCG objects number
2613
        if (objw.size()>=1 && objw.left(3)=="HCG")
×
2614
        {
2615
                for (const auto& n : dsoArray)
×
2616
                {
2617
                        if (n->HCG_nb.isEmpty()) continue;
×
2618
                        QString constw = QString("HCG%1").arg(n->HCG_nb.trimmed());
×
2619
                        QString constws = constw.mid(0, objw.size());
×
2620
                        if (constws.toUpper()==objw)
×
2621
                        {
2622
                                result << constws;
×
2623
                                continue;        // Prevent adding both forms for name
×
2624
                        }
2625
                        constw = QString("HCG %1").arg(n->HCG_nb.trimmed());
×
2626
                        constws = constw.mid(0, objw.size());
×
2627
                        if (constws.toUpper()==objw)
×
2628
                                result << constw;
×
2629
                }
×
2630
        }
2631

2632
        // Search by ESO objects number
2633
        if (objw.size()>=1 && objw.left(3)=="ESO")
×
2634
        {
2635
                for (const auto& n : dsoArray)
×
2636
                {
2637
                        if (n->ESO_nb.isEmpty()) continue;
×
2638
                        QString constw = QString("ESO%1").arg(n->ESO_nb.trimmed());
×
2639
                        QString constws = constw.mid(0, objw.size());
×
2640
                        if (constws.toUpper()==objw)
×
2641
                        {
2642
                                result << constws;
×
2643
                                continue;        // Prevent adding both forms for name
×
2644
                        }
2645
                        constw = QString("ESO %1").arg(n->ESO_nb.trimmed());
×
2646
                        constws = constw.mid(0, objw.size());
×
2647
                        if (constws.toUpper()==objw)
×
2648
                                result << constw;
×
2649
                }
×
2650
        }
2651

2652
        // Search by VdBH objects number
2653
        if (objw.size()>=1 && objw.left(4)=="VDBH")
×
2654
        {
2655
                for (const auto& n : dsoArray)
×
2656
                {
2657
                        if (n->VdBH_nb.isEmpty()) continue;
×
2658
                        QString constw = QString("vdBH%1").arg(n->VdBH_nb.trimmed());
×
2659
                        QString constws = constw.mid(0, objw.size());
×
2660
                        if (constws.toUpper()==objw)
×
2661
                        {
2662
                                result << constws;
×
2663
                                continue;        // Prevent adding both forms for name
×
2664
                        }
2665
                        constw = QString("vdBH %1").arg(n->VdBH_nb.trimmed());
×
2666
                        constws = constw.mid(0, objw.size());
×
2667
                        if (constws.toUpper()==objw)
×
2668
                                result << constw;
×
2669
                }
×
2670
        }
2671

2672
        // Search by DWB objects number
2673
        if (objw.size()>=1 && objw.left(3)=="DWB")
×
2674
        {
2675
                for (const auto& n : dsoArray)
×
2676
                {
2677
                        if (n->DWB_nb==0) continue;
×
2678
                        QString constw = QString("DWB%1").arg(n->DWB_nb);
×
2679
                        QString constws = constw.mid(0, objw.size());
×
2680
                        if (constws.toUpper()==objw)
×
2681
                        {
2682
                                result << constws;
×
2683
                                continue;        // Prevent adding both forms for name
×
2684
                        }
2685
                        constw = QString("DWB %1").arg(n->DWB_nb);
×
2686
                        constws = constw.mid(0, objw.size());
×
2687
                        if (constws.toUpper()==objw)
×
2688
                                result << constw;
×
2689
                }
×
2690
        }
2691

2692
        // Search by Tr (Trumpler) objects number
2693
        if (objw.size()>=1 && (objw.left(8)=="TRUMPLER" || objw.left(2)=="TR"))
×
2694
        {
2695
                for (const auto& n : dsoArray)
×
2696
                {
2697
                        if (n->Tr_nb==0) continue;
×
2698
                        QString constw = QString("Tr%1").arg(n->Tr_nb);
×
2699
                        QString constws = constw.mid(0, objw.size());
×
2700
                        QString constws2 = QString("Trumpler%1").arg(n->Tr_nb).mid(0, objw.size());
×
2701
                        if (constws.toUpper()==objw || constws2.toUpper()==objw)
×
2702
                        {
2703
                                result << constws;
×
2704
                                continue;        // Prevent adding both forms for name
×
2705
                        }
2706
                        constw = QString("Tr %1").arg(n->Tr_nb);
×
2707
                        constws = constw.mid(0, objw.size());
×
2708
                        constws2 = QString("Trumpler %1").arg(n->Tr_nb).mid(0, objw.size());
×
2709
                        if (constws.toUpper()==objw || constws2.toUpper()==objw)
×
2710
                                result << constw;
×
2711
                }
×
2712
        }
2713

2714
        // Search by St (Stock) objects number
2715
        if (objw.size()>=1 && (objw.left(5)=="STOCK" || objw.left(2)=="ST"))
×
2716
        {
2717
                for (const auto& n : dsoArray)
×
2718
                {
2719
                        if (n->St_nb==0) continue;
×
2720
                        QString constw = QString("St%1").arg(n->St_nb);
×
2721
                        QString constws = constw.mid(0, objw.size());
×
2722
                        QString constws2 = QString("Stock%1").arg(n->St_nb).mid(0, objw.size());
×
2723
                        if (constws.toUpper()==objw || constws2.toUpper()==objw)
×
2724
                        {
2725
                                result << constws;
×
2726
                                continue;        // Prevent adding both forms for name
×
2727
                        }
2728
                        constw = QString("St %1").arg(n->St_nb);
×
2729
                        constws = constw.mid(0, objw.size());
×
2730
                        constws2 = QString("Stock %1").arg(n->St_nb).mid(0, objw.size());
×
2731
                        if (constws.toUpper()==objw || constws2.toUpper()==objw)
×
2732
                                result << constw;
×
2733
                }
×
2734
        }
2735

2736
        // Search by Ru (Ruprecht) objects number
2737
        if (objw.size()>=1 && (objw.left(8)=="RUPRECHT" || objw.left(2)=="RU"))
×
2738
        {
2739
                for (const auto& n : dsoArray)
×
2740
                {
2741
                        if (n->Ru_nb==0) continue;
×
2742
                        QString constw = QString("Ru%1").arg(n->Ru_nb);
×
2743
                        QString constws = constw.mid(0, objw.size());
×
2744
                        QString constws2 = QString("Ruprecht%1").arg(n->Ru_nb).mid(0, objw.size());
×
2745
                        if (constws.toUpper()==objw || constws2.toUpper()==objw)
×
2746
                        {
2747
                                result << constws;
×
2748
                                continue;        // Prevent adding both forms for name
×
2749
                        }
2750
                        constw = QString("Ru %1").arg(n->Ru_nb);
×
2751
                        constws = constw.mid(0, objw.size());
×
2752
                        constws2 = QString("Ruprecht %1").arg(n->Ru_nb).mid(0, objw.size());
×
2753
                        if (constws.toUpper()==objw || constws2.toUpper()==objw)
×
2754
                                result << constw;
×
2755
                }
×
2756
        }
2757

2758
        // Search by van den Bergh-Hagen Catalogue objects number
2759
        if (objw.size()>=1 && objw.left(6)=="VDB-HA")
×
2760
        {
2761
                for (const auto& n : dsoArray)
×
2762
                {
2763
                        if (n->VdBHa_nb==0) continue;
×
2764
                        QString constw = QString("vdB-Ha%1").arg(n->VdBHa_nb);
×
2765
                        QString constws = constw.mid(0, objw.size());
×
2766
                        if (constws.toUpper()==objw)
×
2767
                        {
2768
                                result << constws;
×
2769
                                continue;        // Prevent adding both forms for name
×
2770
                        }
2771
                        constw = QString("vdB-Ha %1").arg(n->VdBHa_nb);
×
2772
                        constws = constw.mid(0, objw.size());
×
2773
                        if (constws.toUpper()==objw)
×
2774
                                result << constw;
×
2775
                }
×
2776
        }
2777

2778
        // Search by common names and aliases
2779
        QStringList names;
×
2780
        for (const auto& n : dsoArray)
×
2781
        {
2782
                names.append(n->nameI18);
×
2783
                names.append(n->englishName);
×
2784
                if (getFlagAdditionalNames())
×
2785
                {
2786
                        QStringList nameList = n->nameI18Aliases;
×
2787
                        for (const auto &name : nameList)
×
2788
                                names.append(name);
×
2789

2790
                        nameList = n->englishAliases;
×
2791
                        for (const auto &name : std::as_const(nameList))
×
2792
                                names.append(name);
×
2793
                }
×
2794
        }
2795

2796
        QString fullMatch = "";
×
2797
        for (const auto& name : std::as_const(names))
×
2798
        {
2799
                if (!matchObjectName(name, objPrefix, useStartOfWords))
×
2800
                        continue;
×
2801

2802
                if (name==objPrefix)
×
2803
                        fullMatch = name;
×
2804
                else
2805
                        result.append(name);
×
2806
        }
2807

2808
        result.sort();
×
2809
        if (!fullMatch.isEmpty())
×
2810
                result.prepend(fullMatch);
×
2811

2812
        if (result.size() > maxNbItem)
×
2813
                result.erase(result.begin() + maxNbItem, result.end());
×
2814

2815
        return result;
×
2816
}
×
2817

2818
QStringList NebulaMgr::listAllObjects(bool inEnglish) const
×
2819
{
2820
        QStringList result;
×
2821
        for (const auto& n : dsoArray)
×
2822
        {
2823
                if (!n->getEnglishName().isEmpty())
×
2824
                {
2825
                        if (inEnglish)
×
2826
                                result << n->getEnglishName();
×
2827
                        else
2828
                                result << n->getNameI18n();
×
2829
                }
2830
        }
2831
        return result;
×
2832
}
×
2833

2834
QStringList NebulaMgr::listAllObjectsByType(const QString &objType, bool inEnglish) const
×
2835
{
2836
        QStringList result;
×
2837
        int type = objType.toInt();
×
2838
        switch (type)
×
2839
        {
2840
                case 0: // Bright galaxies?
×
2841
                        for (const auto& n : dsoArray)
×
2842
                        {
2843
                                if (n->nType==type && qMin(n->vMag, n->bMag)<=10.f)
×
2844
                                {
2845
                                        if (!n->getEnglishName().isEmpty())
×
2846
                                        {
2847
                                                if (inEnglish)
×
2848
                                                        result << n->getEnglishName();
×
2849
                                                else
2850
                                                        result << n->getNameI18n();
×
2851
                                        }
2852
                                        else
2853
                                                result << n->getDSODesignationWIC();
×
2854
                                }
2855
                        }
2856
                        break;
×
2857
                case 100: // Messier Catalogue?
×
2858
                        for (const auto& n : getDeepSkyObjectsByType(objType))
×
2859
                                result << QString("M%1").arg(n->M_nb);
×
2860
                        break;
×
2861
                case 101: // Caldwell Catalogue?
×
2862
                        for (const auto& n : getDeepSkyObjectsByType(objType))
×
2863
                                result << QString("C%1").arg(n->C_nb);
×
2864
                        break;
×
2865
                case 102: // Barnard Catalogue?
×
2866
                        for (const auto& n : getDeepSkyObjectsByType(objType))
×
2867
                                result << QString("B %1").arg(n->B_nb);
×
2868
                        break;
×
2869
                case 103: // Sharpless Catalogue?
×
2870
                        for (const auto& n : getDeepSkyObjectsByType(objType))
×
2871
                                result << QString("SH 2-%1").arg(n->Sh2_nb);
×
2872
                        break;
×
2873
                case 104: // van den Bergh Catalogue
×
2874
                        for (const auto& n : getDeepSkyObjectsByType(objType))
×
2875
                                result << QString("vdB %1").arg(n->VdB_nb);
×
2876
                        break;
×
2877
                case 105: // RCW Catalogue
×
2878
                        for (const auto& n : getDeepSkyObjectsByType(objType))
×
2879
                                result << QString("RCW %1").arg(n->RCW_nb);
×
2880
                        break;
×
2881
                case 106: // Collinder Catalogue
×
2882
                        for (const auto& n : getDeepSkyObjectsByType(objType))
×
2883
                                result << QString("Cr %1").arg(n->Cr_nb);
×
2884
                        break;
×
2885
                case 107: // Melotte Catalogue
×
2886
                        for (const auto& n : getDeepSkyObjectsByType(objType))
×
2887
                                result << QString("Mel %1").arg(n->Mel_nb);
×
2888
                        break;
×
2889
                case 108: // New General Catalogue
×
2890
                        for (const auto& n : getDeepSkyObjectsByType(objType))
×
2891
                                result << QString("NGC %1").arg(n->NGC_nb);
×
2892
                        break;
×
2893
                case 109: // Index Catalogue
×
2894
                        for (const auto& n : getDeepSkyObjectsByType(objType))
×
2895
                                result << QString("IC %1").arg(n->IC_nb);
×
2896
                        break;
×
2897
                case 110: // Lynds' Catalogue of Bright Nebulae
×
2898
                        for (const auto& n : getDeepSkyObjectsByType(objType))
×
2899
                                result << QString("LBN %1").arg(n->LBN_nb);
×
2900
                        break;
×
2901
                case 111: // Lynds' Catalogue of Dark Nebulae
×
2902
                        for (const auto& n : getDeepSkyObjectsByType(objType))
×
2903
                                result << QString("LDN %1").arg(n->LDN_nb);
×
2904
                        break;
×
2905
                case 114: // Cederblad Catalog
×
2906
                        for (const auto& n : getDeepSkyObjectsByType(objType))
×
2907
                                result << QString("Ced %1").arg(n->Ced_nb);
×
2908
                        break;
×
2909
                case 115: // Atlas of Peculiar Galaxies (Arp)
×
2910
                        for (const auto& n : getDeepSkyObjectsByType(objType))
×
2911
                                result << QString("Arp %1").arg(n->Arp_nb);
×
2912
                        break;
×
2913
                case 116: // The Catalogue of Interacting Galaxies by Vorontsov-Velyaminov (VV)
×
2914
                        for (const auto& n : getDeepSkyObjectsByType(objType))
×
2915
                                result << QString("VV %1").arg(n->VV_nb);
×
2916
                        break;
×
2917
                case 117: // Catalogue of Galactic Planetary Nebulae (PK)
×
2918
                        for (const auto& n : getDeepSkyObjectsByType(objType))
×
2919
                                result << QString("PK %1").arg(n->PK_nb);
×
2920
                        break;
×
2921
                case 118: // Strasbourg-ESO Catalogue of Galactic Planetary Nebulae by Acker et. al. (PN G)
×
2922
                        for (const auto& n : getDeepSkyObjectsByType(objType))
×
2923
                                result << QString("PN G%1").arg(n->PNG_nb);
×
2924
                        break;
×
2925
                case 119: // A catalogue of Galactic supernova remnants by Green (SNR G)
×
2926
                        for (const auto& n : getDeepSkyObjectsByType(objType))
×
2927
                                result << QString("SNR G%1").arg(n->SNRG_nb);
×
2928
                        break;
×
2929
                case 120: // A Catalog of Rich Clusters of Galaxies by Abell et. al. (Abell (ACO))
×
2930
                        for (const auto& n : getDeepSkyObjectsByType(objType))
×
2931
                                result << QString("Abell %1").arg(n->ACO_nb);
×
2932
                        break;
×
2933
                case 121: // Hickson Compact Group by Hickson et. al. (HCG)
×
2934
                        for (const auto& n : getDeepSkyObjectsByType(objType))
×
2935
                                result << QString("HCG %1").arg(n->HCG_nb);
×
2936
                        break;
×
2937
                case 122: // ESO/Uppsala Survey of the ESO(B) Atlas (ESO)
×
2938
                        for (const auto& n : getDeepSkyObjectsByType(objType))
×
2939
                                result << QString("ESO %1").arg(n->ESO_nb);
×
2940
                        break;
×
2941
                case 123: // Catalogue of southern stars embedded in nebulosity (vdBH)
×
2942
                        for (const auto& n : getDeepSkyObjectsByType(objType))
×
2943
                                result << QString("vdBH %1").arg(n->VdBH_nb);
×
2944
                        break;
×
2945
                case 124: // Catalogue and distances of optically visible H II regions (DWB)
×
2946
                        for (const auto& n : getDeepSkyObjectsByType(objType))
×
2947
                                result << QString("DWB %1").arg(n->DWB_nb);
×
2948
                        break;
×
2949
                case 125: // Trumpler Catalogue (Tr)
×
2950
                        for (const auto& n : getDeepSkyObjectsByType(objType))
×
2951
                                result << QString("Tr %1").arg(n->Tr_nb);
×
2952
                        break;
×
2953
                case 126: // Stock Catalogue (St)
×
2954
                        for (const auto& n : getDeepSkyObjectsByType(objType))
×
2955
                                result << QString("St %1").arg(n->St_nb);
×
2956
                        break;
×
2957
                case 127: // Ruprecht Catalogue (Ru)
×
2958
                        for (const auto& n : getDeepSkyObjectsByType(objType))
×
2959
                                result << QString("Ru %1").arg(n->Ru_nb);
×
2960
                        break;
×
2961
                case 128: // van den Bergh-Hagen Catalogue (VdB-Ha)
×
2962
                        for (const auto& n : getDeepSkyObjectsByType(objType))
×
2963
                                result << QString("vdB-Ha %1").arg(n->VdBHa_nb);
×
2964
                        break;
×
2965
                case 150: // Dwarf galaxies [see NebulaList.hpp]
×
2966
                {
2967
                        for (unsigned int i = 0; i < sizeof(DWARF_GALAXIES) / sizeof(DWARF_GALAXIES[0]); i++)
×
2968
                                result << QString("PGC %1").arg(DWARF_GALAXIES[i]);
×
2969
                        break;
×
2970
                }
2971
                case 151: // Herschel 400 Catalogue [see NebulaList.hpp]
×
2972
                {
2973
                        for (unsigned int i = 0; i < sizeof(H400_LIST) / sizeof(H400_LIST[0]); i++)
×
2974
                                result << QString("NGC %1").arg(H400_LIST[i]);
×
2975
                        break;
×
2976
                }
2977
                case 152: // Jack Bennett's deep sky catalogue [see NebulaList.hpp]
×
2978
                {
2979
                        for (unsigned int i = 0; i < sizeof(BENNETT_LIST) / sizeof(BENNETT_LIST[0]); i++)
×
2980
                                result << QString("NGC %1").arg(BENNETT_LIST[i]);
×
2981
                        result << "Mel 105" << "IC 1459";
×
2982
                        break;
×
2983
                }
2984
                case 153: // James Dunlop's deep sky catalogue [see NebulaList.hpp]
×
2985
                {
2986
                        for (unsigned int i = 0; i < sizeof(DUNLOP_LIST) / sizeof(DUNLOP_LIST[0]); i++)
×
2987
                                result << QString("NGC %1").arg(DUNLOP_LIST[i]);
×
2988
                        break;
×
2989
                }
2990
                default:
×
2991
                {
2992
                        for (const auto& n : dsoArray)
×
2993
                        {
2994
                                if (n->nType==type)
×
2995
                                {
2996
                                        if (!n->getEnglishName().isEmpty())
×
2997
                                        {
2998
                                                if (inEnglish)
×
2999
                                                        result << n->getEnglishName();
×
3000
                                                else
3001
                                                        result << n->getNameI18n();
×
3002
                                        }
3003
                                        else
3004
                                                result << n->getDSODesignationWIC();
×
3005
                                }
3006
                        }
3007
                        break;
×
3008
                }
3009
        }
3010

3011
        result.removeDuplicates();
×
3012
        return result;
×
3013
}
×
3014

3015
const QList<NebulaP> NebulaMgr::getDeepSkyObjectsByType(const QString &objType) const
×
3016
{
3017
        QList<NebulaP> dso;
×
3018
        int type = objType.toInt();
×
3019
        switch (type)
×
3020
        {
3021
                case 100: // Messier Catalogue?
×
3022
                        for (const auto& n : dsoArray)
×
3023
                        {
3024
                                if (n->M_nb>0)
×
3025
                                        dso.append(n);
×
3026
                        }
3027
                        break;
×
3028
                case 101: // Caldwell Catalogue?
×
3029
                        for (const auto& n : dsoArray)
×
3030
                        {
3031
                                if (n->C_nb>0)
×
3032
                                        dso.append(n);
×
3033
                        }
3034
                        break;
×
3035
                case 102: // Barnard Catalogue?
×
3036
                        for (const auto& n : dsoArray)
×
3037
                        {
3038
                                if (n->B_nb>0)
×
3039
                                        dso.append(n);
×
3040
                        }
3041
                        break;
×
3042
                case 103: // Sharpless Catalogue?
×
3043
                        for (const auto& n : dsoArray)
×
3044
                        {
3045
                                if (n->Sh2_nb>0)
×
3046
                                        dso.append(n);
×
3047
                        }
3048
                        break;
×
3049
                case 104: // van den Bergh Catalogue
×
3050
                        for (const auto& n : dsoArray)
×
3051
                        {
3052
                                if (n->VdB_nb>0)
×
3053
                                        dso.append(n);
×
3054
                        }
3055
                        break;
×
3056
                case 105: // RCW Catalogue
×
3057
                        for (const auto& n : dsoArray)
×
3058
                        {
3059
                                if (n->RCW_nb>0)
×
3060
                                        dso.append(n);
×
3061
                        }
3062
                        break;
×
3063
                case 106: // Collinder Catalogue
×
3064
                        for (const auto& n : dsoArray)
×
3065
                        {
3066
                                if (n->Cr_nb>0)
×
3067
                                        dso.append(n);
×
3068
                        }
3069
                        break;
×
3070
                case 107: // Melotte Catalogue
×
3071
                        for (const auto& n : dsoArray)
×
3072
                        {
3073
                                if (n->Mel_nb>0)
×
3074
                                        dso.append(n);
×
3075
                        }
3076
                        break;
×
3077
                case 108: // New General Catalogue
×
3078
                        for (const auto& n : dsoArray)
×
3079
                        {
3080
                                if (n->NGC_nb>0)
×
3081
                                        dso.append(n);
×
3082
                        }
3083
                        break;
×
3084
                case 109: // Index Catalogue
×
3085
                        for (const auto& n : dsoArray)
×
3086
                        {
3087
                                if (n->IC_nb>0)
×
3088
                                        dso.append(n);
×
3089
                        }
3090
                        break;
×
3091
                case 110: // Lynds' Catalogue of Bright Nebulae
×
3092
                        for (const auto& n : dsoArray)
×
3093
                        {
3094
                                if (n->LBN_nb>0)
×
3095
                                        dso.append(n);
×
3096
                        }
3097
                        break;
×
3098
                case 111: // Lynds' Catalogue of Dark Nebulae
×
3099
                        for (const auto& n : dsoArray)
×
3100
                        {
3101
                                if (n->LDN_nb>0)
×
3102
                                        dso.append(n);
×
3103
                        }
3104
                        break;
×
3105
                case 112: // Principal Galaxy Catalog
×
3106
                        for (const auto& n : dsoArray)
×
3107
                        {
3108
                                if (n->PGC_nb>0)
×
3109
                                        dso.append(n);
×
3110
                        }
3111
                        break;
×
3112
                case 113: // The Uppsala General Catalogue of Galaxies
×
3113
                        for (const auto& n : dsoArray)
×
3114
                        {
3115
                                if (n->UGC_nb>0)
×
3116
                                        dso.append(n);
×
3117
                        }
3118
                        break;
×
3119
                case 114: // Cederblad Catalog
×
3120
                        for (const auto& n : dsoArray)
×
3121
                        {
3122
                                if (!n->Ced_nb.isEmpty())
×
3123
                                        dso.append(n);
×
3124
                        }
3125
                        break;
×
3126
                case 115: // Atlas of Peculiar Galaxies (Arp)
×
3127
                        for (const auto& n : dsoArray)
×
3128
                        {
3129
                                if (n->Arp_nb>0)
×
3130
                                        dso.append(n);
×
3131
                        }
3132
                        break;
×
3133
                case 116: // The Catalogue of Interacting Galaxies by Vorontsov-Velyaminov (VV)
×
3134
                        for (const auto& n : dsoArray)
×
3135
                        {
3136
                                if (n->VV_nb>0)
×
3137
                                        dso.append(n);
×
3138
                        }
3139
                        break;
×
3140
                case 117: // Catalogue of Galactic Planetary Nebulae (PK)
×
3141
                        for (const auto& n : dsoArray)
×
3142
                        {
3143
                                if (!n->PK_nb.isEmpty())
×
3144
                                        dso.append(n);
×
3145
                        }
3146
                        break;
×
3147
                case 118: // Strasbourg-ESO Catalogue of Galactic Planetary Nebulae by Acker et. al. (PN G)
×
3148
                        for (const auto& n : dsoArray)
×
3149
                        {
3150
                                if (!n->PNG_nb.isEmpty())
×
3151
                                        dso.append(n);
×
3152
                        }
3153
                        break;
×
3154
                case 119: // A catalogue of Galactic supernova remnants by Green (SNR G)
×
3155
                        for (const auto& n : dsoArray)
×
3156
                        {
3157
                                if (!n->SNRG_nb.isEmpty())
×
3158
                                        dso.append(n);
×
3159
                        }
3160
                        break;
×
3161
                case 120: // A Catalog of Rich Clusters of Galaxies by Abell et. al. (ACO)
×
3162
                        for (const auto& n : dsoArray)
×
3163
                        {
3164
                                if (!n->ACO_nb.isEmpty())
×
3165
                                        dso.append(n);
×
3166
                        }
3167
                        break;
×
3168
                case 121: // Hickson Compact Group by Hickson et. al. (HCG)
×
3169
                        for (const auto& n : dsoArray)
×
3170
                        {
3171
                                if (!n->HCG_nb.isEmpty())
×
3172
                                        dso.append(n);
×
3173
                        }
3174
                        break;
×
3175
                case 122: // ESO/Uppsala Survey of the ESO(B) Atlas (ESO)
×
3176
                        for (const auto& n : dsoArray)
×
3177
                        {
3178
                                if (!n->ESO_nb.isEmpty())
×
3179
                                        dso.append(n);
×
3180
                        }
3181
                        break;
×
3182
                case 123: // Catalogue of southern stars embedded in nebulosity (VdBH)
×
3183
                        for (const auto& n : dsoArray)
×
3184
                        {
3185
                                if (!n->VdBH_nb.isEmpty())
×
3186
                                        dso.append(n);
×
3187
                        }
3188
                        break;
×
3189
                case 124: // Catalogue and distances of optically visible H II regions (DWB)
×
3190
                        for (const auto& n : dsoArray)
×
3191
                        {
3192
                                if (n->DWB_nb > 0)
×
3193
                                        dso.append(n);
×
3194
                        }
3195
                        break;
×
3196
                case 125: // Trumpler Catalogue (Tr)
×
3197
                        for (const auto& n : dsoArray)
×
3198
                        {
3199
                                if (n->Tr_nb > 0)
×
3200
                                        dso.append(n);
×
3201
                        }
3202
                        break;
×
3203
                case 126: // Stock Catalogue (St)
×
3204
                        for (const auto& n : dsoArray)
×
3205
                        {
3206
                                if (n->St_nb > 0)
×
3207
                                        dso.append(n);
×
3208
                        }
3209
                        break;
×
3210
                case 127: // Ruprecht Catalogue (Ru)
×
3211
                        for (const auto& n : dsoArray)
×
3212
                        {
3213
                                if (n->Ru_nb > 0)
×
3214
                                        dso.append(n);
×
3215
                        }
3216
                        break;
×
3217
                case 128: // van den Bergh-Hagen Catalogue (VdB-Ha)
×
3218
                        for (const auto& n : dsoArray)
×
3219
                        {
3220
                                if (n->VdBHa_nb > 0)
×
3221
                                        dso.append(n);
×
3222
                        }
3223
                        break;
×
3224
                case 150: // Dwarf galaxies [see NebulaList.hpp]
×
3225
                {
3226
                        NebulaP ds;
×
3227
                        for (unsigned int i = 0; i < sizeof(DWARF_GALAXIES) / sizeof(DWARF_GALAXIES[0]); i++)
×
3228
                        {
3229
                                ds = searchPGC(DWARF_GALAXIES[i]);
×
3230
                                if (!ds.isNull())
×
3231
                                        dso.append(ds);
×
3232
                        }
3233
                        break;
×
3234
                }
×
3235
                case 151: // Herschel 400 Catalogue [see NebulaList.hpp]
×
3236
                {
3237
                        NebulaP ds;
×
3238
                        for (unsigned int i = 0; i < sizeof(H400_LIST) / sizeof(H400_LIST[0]); i++)
×
3239
                        {
3240
                                ds = searchNGC(H400_LIST[i]);
×
3241
                                if (!ds.isNull())
×
3242
                                        dso.append(ds);
×
3243
                        }
3244
                        break;
×
3245
                }
×
3246
                case 152: // Jack Bennett's deep sky catalogue [see NebulaList.hpp]
×
3247
                {
3248
                        NebulaP ds;
×
3249
                        for (unsigned int i = 0; i < sizeof(BENNETT_LIST) / sizeof(BENNETT_LIST[0]); i++)
×
3250
                        {
3251
                                ds = searchNGC(BENNETT_LIST[i]);
×
3252
                                if (!ds.isNull())
×
3253
                                        dso.append(ds);
×
3254
                        }
3255
                        ds = searchMel(105);
×
3256
                        if (!ds.isNull())
×
3257
                                dso.append(ds);
×
3258
                        ds = searchIC(1459);
×
3259
                        if (!ds.isNull())
×
3260
                                dso.append(ds);
×
3261
                        break;
×
3262
                }
×
3263
                case 153: // James Dunlop's deep sky catalogue [see NebulaList.hpp]
×
3264
                {
3265
                        NebulaP ds;
×
3266
                        for (unsigned int i = 0; i < sizeof(DUNLOP_LIST) / sizeof(DUNLOP_LIST[0]); i++)
×
3267
                        {
3268
                                ds = searchNGC(DUNLOP_LIST[i]);
×
3269
                                if (!ds.isNull())
×
3270
                                        dso.append(ds);
×
3271
                        }
3272
                        break;
×
3273
                }
×
3274
                default:
×
3275
                {
3276
                        for (const auto& n : dsoArray)
×
3277
                        {
3278
                                if (n->nType==type)
×
3279
                                        dso.append(n);
×
3280
                        }
3281
                        break;
×
3282
                }
3283
        }
3284

3285
        return dso;
×
3286
}
×
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