1 /*
2 SPDX-FileCopyrightText: 2012 Samikshan Bairagya <samikshan@gmail.com>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7 #include "modelmanager.h"
8
9 #include "ksfilereader.h"
10 #include "kstars.h"
11 #include "kstarsdata.h"
12 #include "obsconditions.h"
13 #include "skymapcomposite.h"
14 #include "skyobjitem.h"
15 #include "skyobjlistmodel.h"
16 #include "starobject.h"
17 #include "catalogsdb.h"
18
19 #include <QtConcurrent>
20
ModelManager(ObsConditions * obs)21 ModelManager::ModelManager(ObsConditions *obs)
22 {
23 m_ObsConditions = obs;
24
25 tempModel = new SkyObjListModel();
26
27 m_ModelList = QList<SkyObjListModel *>();
28 m_ObjectList = QList<QList<SkyObjItem *>>();
29
30 favoriteClusters = QList<SkyObjItem *>();
31 favoriteNebulas = QList<SkyObjItem *>();
32 favoriteGalaxies = QList<SkyObjItem *>();
33
34 for (int i = 0; i < NumberOfLists; i++)
35 {
36 m_ModelList.append(new SkyObjListModel());
37 m_ObjectList.append(QList<SkyObjItem *>());
38 }
39
40 QtConcurrent::run(this, &ModelManager::loadLists);
41 }
42
~ModelManager()43 ModelManager::~ModelManager()
44 {
45 qDeleteAll(m_ModelList);
46 foreach (QList<SkyObjItem *> list, m_ObjectList)
47 qDeleteAll(list);
48 delete tempModel;
49 }
50
loadLists()51 void ModelManager::loadLists()
52 {
53 if (KStars::Closing)
54 return;
55
56 emit loadProgressUpdated(0);
57 KStarsData *data = KStarsData::Instance();
58 QVector<QPair<QString, const SkyObject *>> listStars;
59 listStars.append(data->skyComposite()->objectLists(SkyObject::STAR));
60 for (int i = 0; i < listStars.size(); i++)
61 {
62 QPair<QString, const SkyObject *> pair = listStars.value(i);
63 const StarObject *star = dynamic_cast<const StarObject *>(pair.second);
64 if (star != nullptr && star->hasLatinName())
65 m_ObjectList[Stars].append(new SkyObjItem((SkyObject *)(star)));
66 }
67 QString prevName;
68 for (int i = 0; i < m_ObjectList[Stars].size(); i++)
69 {
70 SkyObjItem *star = m_ObjectList[Stars].at(i);
71 if (prevName == star->getName())
72 {
73 m_ObjectList[Stars].removeAt(i);
74 i--;
75 }
76 prevName = star->getName();
77 }
78
79 KSFileReader fileReader;
80 if (!fileReader.open("Interesting.dat"))
81 return;
82
83 while (fileReader.hasMoreLines())
84 {
85 if (KStars::Closing)
86 return;
87
88 QString line = fileReader.readLine();
89
90 if (line.length() == 0 || line[0] == '#')
91 continue;
92
93 SkyObject *o;
94 if ((o = data->skyComposite()->findByName(line)))
95 {
96 //qDebug()<<o->longname()<<o->typeName();
97 switch (o->type())
98 {
99 case SkyObject::OPEN_CLUSTER:
100 case SkyObject::GLOBULAR_CLUSTER:
101 case SkyObject::GALAXY_CLUSTER:
102 favoriteClusters.append(new SkyObjItem(o));
103 break;
104 case SkyObject::PLANETARY_NEBULA:
105 case SkyObject::DARK_NEBULA:
106 case SkyObject::GASEOUS_NEBULA:
107 favoriteNebulas.append(new SkyObjItem(o));
108 break;
109 case SkyObject::GALAXY:
110 favoriteGalaxies.append(new SkyObjItem(o));
111 break;
112 }
113 }
114 }
115
116 emit loadProgressUpdated(0.20);
117
118 loadObjectList(m_ObjectList[Asteroids], SkyObject::ASTEROID);
119 emit loadProgressUpdated(0.30);
120 loadObjectList(m_ObjectList[Comets], SkyObject::COMET);
121 emit loadProgressUpdated(0.40);
122 loadObjectList(m_ObjectList[Satellites], SkyObject::SATELLITE);
123 loadObjectList(m_ObjectList[Supernovas], SkyObject::SUPERNOVA);
124 emit loadProgressUpdated(0.50);
125 loadObjectList(m_ObjectList[Constellations], SkyObject::CONSTELLATION);
126 emit loadProgressUpdated(0.55);
127 loadObjectList(m_ObjectList[Planets], SkyObject::PLANET);
128 emit loadProgressUpdated(0.60);
129
130 loadObjectList(m_ObjectList[Galaxies], SkyObject::GALAXY);
131 emit loadProgressUpdated(0.70);
132
133 loadObjectList(m_ObjectList[Clusters], SkyObject::OPEN_CLUSTER);
134 loadObjectList(m_ObjectList[Clusters], SkyObject::GLOBULAR_CLUSTER);
135 loadObjectList(m_ObjectList[Clusters], SkyObject::GALAXY_CLUSTER);
136 emit loadProgressUpdated(0.80);
137
138 loadObjectList(m_ObjectList[Nebulas], SkyObject::PLANETARY_NEBULA);
139 loadObjectList(m_ObjectList[Nebulas], SkyObject::SUPERNOVA_REMNANT);
140 loadObjectList(m_ObjectList[Nebulas], SkyObject::GASEOUS_NEBULA);
141 loadObjectList(m_ObjectList[Nebulas], SkyObject::DARK_NEBULA);
142
143 emit loadProgressUpdated(0.90);
144 emit loadProgressUpdated(1);
145 }
146
updateAllModels(ObsConditions * obs)147 void ModelManager::updateAllModels(ObsConditions *obs)
148 {
149 m_ObsConditions = obs;
150 resetAllModels();
151
152 for (int i = 0; i < NumberOfLists; i++)
153 loadObjectsIntoModel(*m_ModelList[i], m_ObjectList[i]);
154 }
155
updateModel(ObsConditions * obs,QString modelName)156 void ModelManager::updateModel(ObsConditions *obs, QString modelName)
157 {
158 m_ObsConditions = obs;
159 SkyObjListModel *model = returnModel(modelName);
160 const auto modelNumber = getModelNumber(modelName);
161
162 if (modelNumber > -1 && model)
163 {
164 model->resetModel();
165 if (showOnlyFavorites && modelName == "galaxies")
166 loadObjectsIntoModel(*m_ModelList[modelNumber], favoriteGalaxies);
167 else if (showOnlyFavorites && modelName == "nebulas")
168 loadObjectsIntoModel(*m_ModelList[modelNumber], favoriteNebulas);
169 else if (showOnlyFavorites && modelName == "clusters")
170 loadObjectsIntoModel(*m_ModelList[modelNumber], favoriteClusters);
171 else
172 loadObjectsIntoModel(*m_ModelList[modelNumber], m_ObjectList[modelNumber]);
173 emit modelUpdated();
174 }
175 }
176
loadObjectList(QList<SkyObjItem * > & skyObjectList,int type)177 void ModelManager::loadObjectList(QList<SkyObjItem *> &skyObjectList, int type)
178 {
179 if (KStars::Closing)
180 return;
181
182 KStarsData *data = KStarsData::Instance();
183 QVector<QPair<QString, const SkyObject *>> objects = data->skyComposite()->objectLists(type);
184
185 for (int i = 0; i < objects.size(); i++)
186 {
187 if (KStars::Closing)
188 return;
189
190 QPair<QString, const SkyObject *> pair = objects.value(i);
191 const SkyObject *listObject = pair.second;
192 if (listObject->name() != i18n("Sun"))
193 skyObjectList.append(new SkyObjItem(const_cast<SkyObject *>(listObject)));
194 }
195 QString prevName;
196 for (int i = 0; i < skyObjectList.size(); i++)
197 {
198 if (KStars::Closing)
199 return;
200
201 SkyObjItem *obj = skyObjectList.at(i);
202 if (prevName == obj->getName())
203 {
204 skyObjectList.removeAt(i);
205 i--;
206 }
207 prevName = obj->getName();
208 }
209 }
210
loadObjectsIntoModel(SkyObjListModel & model,QList<SkyObjItem * > & skyObjectList)211 void ModelManager::loadObjectsIntoModel(SkyObjListModel &model, QList<SkyObjItem *> &skyObjectList)
212 {
213 KStarsData *data = KStarsData::Instance();
214
215 foreach (SkyObjItem *soitem, skyObjectList)
216 {
217 bool isVisible =
218 (showOnlyVisible) ? (m_ObsConditions->isVisible(data->geo(), data->lst(), soitem->getSkyObject())) : true;
219 if (isVisible)
220 model.addSkyObject(soitem);
221 }
222 }
223
resetAllModels()224 void ModelManager::resetAllModels()
225 {
226 foreach (SkyObjListModel *model, m_ModelList)
227 model->resetModel();
228 }
229
getModelNumber(QString modelName)230 int ModelManager::getModelNumber(QString modelName)
231 {
232 if (modelName == "planets")
233 return Planets;
234 if (modelName == "stars")
235 return Stars;
236 if (modelName == "constellations")
237 return Constellations;
238 if (modelName == "galaxies")
239 return Galaxies;
240 if (modelName == "clusters")
241 return Clusters;
242 if (modelName == "nebulas")
243 return Nebulas;
244 if (modelName == "asteroids")
245 return Asteroids;
246 if (modelName == "comets")
247 return Comets;
248 if (modelName == "supernovas")
249 return Supernovas;
250 if (modelName == "satellites")
251 return Satellites;
252 if (modelName == "messier")
253 return Messier;
254 if (modelName == "ngc")
255 return NGC;
256 if (modelName == "ic")
257 return IC;
258 if (modelName == "sharpless")
259 return Sharpless;
260 else
261 return -1;
262 }
263
returnModel(QString modelName)264 SkyObjListModel *ModelManager::returnModel(QString modelName)
265 {
266 int modelNumber = getModelNumber(modelName);
267 if (modelNumber > -1 && modelNumber < NumberOfLists)
268 return m_ModelList[modelNumber];
269 else
270 return tempModel;
271 }
272
loadCatalog(const QString & name)273 void ModelManager::loadCatalog(const QString &name)
274 {
275 const auto id = getModelNumber(name);
276 if (m_CatalogMap.count(id) > 0)
277 return;
278
279 const std::unordered_map<QString, QString> search_prefixes{
280 { "ngc", "NGC " }, { "ic", "IC " }, { "messier", "M " }, { "sharpless", "Sh2 " }
281 };
282
283 CatalogsDB::DBManager manager{ CatalogsDB::dso_db_path() };
284
285 const auto &prefix = search_prefixes.at(name);
286 const int offset = prefix.size();
287
288 m_CatalogMap[id] = std::get<2>(manager.general_master_query(
289 QString("name LIKE '%1'").arg(prefix + "%"),
290 QString("CAST(SUBSTR(name,%1) AS INT)").arg(offset)));
291
292 auto &lst = m_CatalogSkyObjItems[id];
293
294 for (auto &obj : m_CatalogMap[id])
295 {
296 obj.updateCoordsNow(KStarsData::Instance()->updateNum());
297 lst.emplace_back(&obj);
298 }
299
300 auto &p_lst = m_ObjectList[id];
301 for (auto &obj : lst)
302 p_lst.append(&obj);
303
304 updateModel(m_ObsConditions, name);
305 emit loadProgressUpdated(1);
306 };
307