File indexing completed on 2024-04-28 15:11:24

0001 /*
0002     SPDX-FileCopyrightText: 2012 Samikshan Bairagya <samikshan@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "modelmanager.h"
0008 
0009 #include "ksfilereader.h"
0010 #include "kstars.h"
0011 #include "kstarsdata.h"
0012 #include "obsconditions.h"
0013 #include "skymapcomposite.h"
0014 #include "skyobjitem.h"
0015 #include "skyobjlistmodel.h"
0016 #include "starobject.h"
0017 #include "catalogsdb.h"
0018 
0019 #include <QtConcurrent>
0020 
0021 ModelManager::ModelManager(ObsConditions *obs)
0022 {
0023     m_ObsConditions = obs;
0024 
0025     tempModel = new SkyObjListModel();
0026 
0027     m_ModelList  = QList<SkyObjListModel *>();
0028     m_ObjectList = QList<QList<SkyObjItem *>>();
0029 
0030     favoriteClusters = QList<SkyObjItem *>();
0031     favoriteNebulas  = QList<SkyObjItem *>();
0032     favoriteGalaxies = QList<SkyObjItem *>();
0033 
0034     for (int i = 0; i < NumberOfLists; i++)
0035     {
0036         m_ModelList.append(new SkyObjListModel());
0037         m_ObjectList.append(QList<SkyObjItem *>());
0038     }
0039 
0040     QtConcurrent::run(this, &ModelManager::loadLists);
0041 }
0042 
0043 ModelManager::~ModelManager()
0044 {
0045     qDeleteAll(m_ModelList);
0046     foreach (QList<SkyObjItem *> list, m_ObjectList)
0047         qDeleteAll(list);
0048     delete tempModel;
0049 }
0050 
0051 void ModelManager::loadLists()
0052 {
0053     if (KStars::Closing)
0054         return;
0055 
0056     emit loadProgressUpdated(0);
0057     KStarsData *data = KStarsData::Instance();
0058     QVector<QPair<QString, const SkyObject *>> listStars;
0059     listStars.append(data->skyComposite()->objectLists(SkyObject::STAR));
0060     for (int i = 0; i < listStars.size(); i++)
0061     {
0062         QPair<QString, const SkyObject *> pair = listStars.value(i);
0063         const StarObject *star                 = dynamic_cast<const StarObject *>(pair.second);
0064         if (star != nullptr && star->hasLatinName())
0065             m_ObjectList[Stars].append(new SkyObjItem((SkyObject *)(star)));
0066     }
0067     QString prevName;
0068     for (int i = 0; i < m_ObjectList[Stars].size(); i++)
0069     {
0070         SkyObjItem *star = m_ObjectList[Stars].at(i);
0071         if (prevName == star->getName())
0072         {
0073             m_ObjectList[Stars].removeAt(i);
0074             i--;
0075         }
0076         prevName = star->getName();
0077     }
0078 
0079     KSFileReader fileReader;
0080     if (!fileReader.open("Interesting.dat"))
0081         return;
0082 
0083     while (fileReader.hasMoreLines())
0084     {
0085         if (KStars::Closing)
0086             return;
0087 
0088         QString line = fileReader.readLine();
0089 
0090         if (line.length() == 0 || line[0] == '#')
0091             continue;
0092 
0093         SkyObject *o;
0094         if ((o = data->skyComposite()->findByName(line)))
0095         {
0096             //qDebug()<<o->longname()<<o->typeName();
0097             switch (o->type())
0098             {
0099                 case SkyObject::OPEN_CLUSTER:
0100                 case SkyObject::GLOBULAR_CLUSTER:
0101                 case SkyObject::GALAXY_CLUSTER:
0102                     favoriteClusters.append(new SkyObjItem(o));
0103                     break;
0104                 case SkyObject::PLANETARY_NEBULA:
0105                 case SkyObject::DARK_NEBULA:
0106                 case SkyObject::GASEOUS_NEBULA:
0107                     favoriteNebulas.append(new SkyObjItem(o));
0108                     break;
0109                 case SkyObject::GALAXY:
0110                     favoriteGalaxies.append(new SkyObjItem(o));
0111                     break;
0112             }
0113         }
0114     }
0115 
0116     emit loadProgressUpdated(0.20);
0117 
0118     loadObjectList(m_ObjectList[Asteroids], SkyObject::ASTEROID);
0119     emit loadProgressUpdated(0.30);
0120     loadObjectList(m_ObjectList[Comets], SkyObject::COMET);
0121     emit loadProgressUpdated(0.40);
0122     loadObjectList(m_ObjectList[Satellites], SkyObject::SATELLITE);
0123     loadObjectList(m_ObjectList[Supernovas], SkyObject::SUPERNOVA);
0124     emit loadProgressUpdated(0.50);
0125     loadObjectList(m_ObjectList[Constellations], SkyObject::CONSTELLATION);
0126     emit loadProgressUpdated(0.55);
0127     loadObjectList(m_ObjectList[Planets], SkyObject::PLANET);
0128     emit loadProgressUpdated(0.60);
0129 
0130     loadObjectList(m_ObjectList[Galaxies], SkyObject::GALAXY);
0131     emit loadProgressUpdated(0.70);
0132 
0133     loadObjectList(m_ObjectList[Clusters], SkyObject::OPEN_CLUSTER);
0134     loadObjectList(m_ObjectList[Clusters], SkyObject::GLOBULAR_CLUSTER);
0135     loadObjectList(m_ObjectList[Clusters], SkyObject::GALAXY_CLUSTER);
0136     emit loadProgressUpdated(0.80);
0137 
0138     loadObjectList(m_ObjectList[Nebulas], SkyObject::PLANETARY_NEBULA);
0139     loadObjectList(m_ObjectList[Nebulas], SkyObject::SUPERNOVA_REMNANT);
0140     loadObjectList(m_ObjectList[Nebulas], SkyObject::GASEOUS_NEBULA);
0141     loadObjectList(m_ObjectList[Nebulas], SkyObject::DARK_NEBULA);
0142 
0143     emit loadProgressUpdated(0.90);
0144     emit loadProgressUpdated(1);
0145 }
0146 
0147 void ModelManager::updateAllModels(ObsConditions *obs)
0148 {
0149     m_ObsConditions = obs;
0150     resetAllModels();
0151 
0152     for (int i = 0; i < NumberOfLists; i++)
0153         loadObjectsIntoModel(*m_ModelList[i], m_ObjectList[i]);
0154 }
0155 
0156 void ModelManager::updateModel(ObsConditions *obs, QString modelName)
0157 {
0158     m_ObsConditions        = obs;
0159     SkyObjListModel *model = returnModel(modelName);
0160     const auto modelNumber = getModelNumber(modelName);
0161 
0162     if (modelNumber > -1 && model)
0163     {
0164         model->resetModel();
0165         if (showOnlyFavorites && modelName == "galaxies")
0166             loadObjectsIntoModel(*m_ModelList[modelNumber], favoriteGalaxies);
0167         else if (showOnlyFavorites && modelName == "nebulas")
0168             loadObjectsIntoModel(*m_ModelList[modelNumber], favoriteNebulas);
0169         else if (showOnlyFavorites && modelName == "clusters")
0170             loadObjectsIntoModel(*m_ModelList[modelNumber], favoriteClusters);
0171         else
0172             loadObjectsIntoModel(*m_ModelList[modelNumber], m_ObjectList[modelNumber]);
0173         emit modelUpdated();
0174     }
0175 }
0176 
0177 void ModelManager::loadObjectList(QList<SkyObjItem *> &skyObjectList, int type)
0178 {
0179     if (KStars::Closing)
0180         return;
0181 
0182     KStarsData *data                                   = KStarsData::Instance();
0183     QVector<QPair<QString, const SkyObject *>> objects = data->skyComposite()->objectLists(type);
0184 
0185     for (int i = 0; i < objects.size(); i++)
0186     {
0187         if (KStars::Closing)
0188             return;
0189 
0190         QPair<QString, const SkyObject *> pair = objects.value(i);
0191         const SkyObject *listObject            = pair.second;
0192         if(listObject)
0193             if (listObject->name() != i18n("Sun"))
0194                 skyObjectList.append(new SkyObjItem(const_cast<SkyObject *>(listObject)));
0195     }
0196     QString prevName;
0197     for (int i = 0; i < skyObjectList.size(); i++)
0198     {
0199         if (KStars::Closing)
0200             return;
0201 
0202         SkyObjItem *obj = skyObjectList.at(i);
0203         if (prevName == obj->getName())
0204         {
0205             skyObjectList.removeAt(i);
0206             i--;
0207         }
0208         prevName = obj->getName();
0209     }
0210 }
0211 
0212 void ModelManager::loadObjectsIntoModel(SkyObjListModel &model, QList<SkyObjItem *> &skyObjectList)
0213 {
0214     KStarsData *data = KStarsData::Instance();
0215 
0216     foreach (SkyObjItem *soitem, skyObjectList)
0217     {
0218         bool isVisible =
0219             (showOnlyVisible) ? (m_ObsConditions->isVisible(data->geo(), data->lst(), soitem->getSkyObject())) : true;
0220         if (isVisible)
0221             model.addSkyObject(soitem);
0222     }
0223 }
0224 
0225 void ModelManager::resetAllModels()
0226 {
0227     foreach (SkyObjListModel *model, m_ModelList)
0228         model->resetModel();
0229 }
0230 
0231 int ModelManager::getModelNumber(QString modelName)
0232 {
0233     if (modelName == "planets")
0234         return Planets;
0235     if (modelName == "stars")
0236         return Stars;
0237     if (modelName == "constellations")
0238         return Constellations;
0239     if (modelName == "galaxies")
0240         return Galaxies;
0241     if (modelName == "clusters")
0242         return Clusters;
0243     if (modelName == "nebulas")
0244         return Nebulas;
0245     if (modelName == "asteroids")
0246         return Asteroids;
0247     if (modelName == "comets")
0248         return Comets;
0249     if (modelName == "supernovas")
0250         return Supernovas;
0251     if (modelName == "satellites")
0252         return Satellites;
0253     if (modelName == "messier")
0254         return Messier;
0255     if (modelName == "ngc")
0256         return NGC;
0257     if (modelName == "ic")
0258         return IC;
0259     if (modelName == "sharpless")
0260         return Sharpless;
0261     else
0262         return -1;
0263 }
0264 
0265 SkyObjListModel *ModelManager::returnModel(QString modelName)
0266 {
0267     int modelNumber = getModelNumber(modelName);
0268     if (modelNumber > -1 && modelNumber < NumberOfLists)
0269         return m_ModelList[modelNumber];
0270     else
0271         return tempModel;
0272 }
0273 
0274 void ModelManager::loadCatalog(const QString &name)
0275 {
0276     const auto id = getModelNumber(name);
0277     if (m_CatalogMap.count(id) > 0)
0278         return;
0279 
0280     const std::unordered_map<QString, QString> search_prefixes{
0281         { "ngc", "NGC " }, { "ic", "IC " }, { "messier", "M " }, { "sharpless", "Sh2 " }
0282     };
0283 
0284     CatalogsDB::DBManager manager{ CatalogsDB::dso_db_path() };
0285 
0286     const auto &prefix = search_prefixes.at(name);
0287     const int offset   = prefix.size();
0288 
0289     m_CatalogMap[id] = std::get<2>(manager.general_master_query(
0290         QString("name LIKE '%1'").arg(prefix + "%"),
0291         QString("CAST(SUBSTR(name,%1) AS INT)").arg(offset)));
0292 
0293     auto &lst = m_CatalogSkyObjItems[id];
0294 
0295     for (auto &obj : m_CatalogMap[id])
0296     {
0297         obj.updateCoordsNow(KStarsData::Instance()->updateNum());
0298         lst.emplace_back(&obj);
0299     }
0300 
0301     auto &p_lst = m_ObjectList[id];
0302     for (auto &obj : lst)
0303         p_lst.append(&obj);
0304 
0305     updateModel(m_ObsConditions, name);
0306     emit loadProgressUpdated(1);
0307 };