File indexing completed on 2025-01-19 09:45:50
0001 /* 0002 SPDX-FileCopyrightText: 2009 Prakash Mohan <prakash.mohan@kdemail.net> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "oal/execute.h" 0008 0009 #include "kstars.h" 0010 #include "kstarsdata.h" 0011 #include "ksnotification.h" 0012 #include "observinglist.h" 0013 #include "dialogs/finddialog.h" 0014 #include "dialogs/locationdialog.h" 0015 #include "oal/observeradd.h" 0016 #include "skycomponents/skymapcomposite.h" 0017 #include "skyobjects/starobject.h" 0018 0019 #include <QFileDialog> 0020 0021 Execute::Execute() 0022 { 0023 QWidget *w = new QWidget; 0024 ui.setupUi(w); 0025 #ifdef Q_OS_OSX 0026 setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint); 0027 #endif 0028 0029 QVBoxLayout *mainLayout = new QVBoxLayout; 0030 mainLayout->addWidget(w); 0031 setLayout(mainLayout); 0032 0033 QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); 0034 mainLayout->addWidget(buttonBox); 0035 connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); 0036 0037 QPushButton *execB = new QPushButton(i18n("End Session")); 0038 QPushButton *addObs = new QPushButton(i18n("Manage Observers")); 0039 execB->setToolTip(i18n("Save and End the current session")); 0040 buttonBox->addButton(execB, QDialogButtonBox::ActionRole); 0041 buttonBox->addButton(addObs, QDialogButtonBox::ActionRole); 0042 connect(execB, SIGNAL(clicked()), this, SLOT(slotEndSession())); 0043 connect(addObs, SIGNAL(clicked()), this, SLOT(slotObserverAdd())); 0044 0045 setWindowTitle(i18nc("@title:window", "Execute Session")); 0046 0047 //initialize the global logObject 0048 logObject = KStarsData::Instance()->logObject(); 0049 0050 //initialize the lists and parameters 0051 init(); 0052 ui.Target->hide(); 0053 ui.AddObject->hide(); 0054 ui.RemoveObject->hide(); 0055 ui.NextButton->hide(); 0056 ui.NextButton->setEnabled(false); 0057 ui.Slew->setEnabled(false); 0058 0059 //make connections 0060 connect(ui.NextButton, SIGNAL(clicked()), this, SLOT(slotNext())); 0061 connect(ui.Slew, SIGNAL(clicked()), this, SLOT(slotSlew())); 0062 connect(ui.Location, SIGNAL(clicked()), this, SLOT(slotLocation())); 0063 connect(ui.Target, SIGNAL(currentTextChanged(QString)), this, SLOT(slotSetTarget(QString))); 0064 connect(ui.SessionURL, SIGNAL(leftClickedUrl()), this, SLOT(slotShowSession())); 0065 connect(ui.ObservationsURL, SIGNAL(leftClickedUrl()), this, SLOT(slotShowTargets())); 0066 connect(ui.AddObject, SIGNAL(leftClickedUrl()), this, SLOT(slotAddObject())); 0067 connect(ui.RemoveObject, SIGNAL(leftClickedUrl()), this, SLOT(slotRemoveObject())); 0068 } 0069 0070 void Execute::init() 0071 { 0072 //initialize geo to current location of the ObservingList 0073 geo = KStarsData::Instance()->geo(); 0074 ui.Location->setText(geo->fullName()); 0075 0076 // JM: Aren't we suppose to take KStars time? The one returned by the OL is the time of the LAST object 0077 // in the list which doesn't make sense. 0078 0079 /* 0080 //set the date time to the dateTime from the OL 0081 ui.Begin->setDateTime( ks->observingList()->dateTime() ); 0082 */ 0083 ui.Begin->setDateTime(KStarsData::Instance()->geo()->UTtoLT(KStarsData::Instance()->clock()->utc())); 0084 0085 KStarsData::Instance()->logObject()->readAll(); 0086 0087 //load Targets 0088 loadTargets(); 0089 0090 //load Equipment 0091 loadEquipment(); 0092 0093 //load Observers 0094 loadObservers(); 0095 0096 if (logObject->scopeList()->isEmpty() || logObject->observerList()->isEmpty()) 0097 { 0098 ui.hintLabel->show(); 0099 } 0100 else 0101 { 0102 ui.hintLabel->hide(); 0103 } 0104 0105 //set Current Items 0106 loadCurrentItems(); 0107 } 0108 void Execute::loadCurrentItems() 0109 { 0110 //Set the current target, equipments and observer 0111 if (currentTarget) 0112 ui.Target->setCurrentRow(findIndexOfTarget(currentTarget->name()), QItemSelectionModel::SelectCurrent); 0113 else 0114 ui.Target->setCurrentRow(0, QItemSelectionModel::SelectCurrent); 0115 0116 if (currentObserver) 0117 ui.Observer->setCurrentIndex(ui.Observer->findText(currentObserver->name() + ' ' + currentObserver->surname())); 0118 if (currentScope) 0119 ui.Scope->setCurrentIndex(ui.Scope->findText(currentScope->name())); 0120 if (currentEyepiece) 0121 ui.Eyepiece->setCurrentIndex(ui.Eyepiece->findText(currentEyepiece->name())); 0122 if (currentLens) 0123 ui.Lens->setCurrentIndex(ui.Lens->findText(currentLens->name())); 0124 if (currentFilter) 0125 ui.Filter->setCurrentIndex(ui.Filter->findText(currentFilter->name())); 0126 } 0127 0128 int Execute::findIndexOfTarget(QString name) 0129 { 0130 for (int i = 0; i < ui.Target->count(); i++) 0131 if (ui.Target->item(i)->text() == name) 0132 return i; 0133 return -1; 0134 } 0135 0136 void Execute::slotNext() 0137 { 0138 switch (ui.stackedWidget->currentIndex()) 0139 { 0140 case 0: 0141 { 0142 saveSession(); 0143 break; 0144 } 0145 case 1: 0146 { 0147 addTargetNotes(); 0148 break; 0149 } 0150 case 2: 0151 { 0152 addObservation(); 0153 ui.stackedWidget->setCurrentIndex(1); 0154 ui.NextButton->setText(i18n("Next Page >")); 0155 QString prevTarget = currentTarget->name(); 0156 loadTargets(); 0157 ui.Target->setCurrentRow(findIndexOfTarget(prevTarget), QItemSelectionModel::SelectCurrent); 0158 selectNextTarget(); 0159 break; 0160 } 0161 } 0162 } 0163 0164 bool Execute::saveSession() 0165 { 0166 OAL::Site *site = logObject->findSiteByName(geo->fullName()); 0167 if (!site) 0168 { 0169 while (logObject->findSiteById(i18n("site_") + QString::number(nextSite))) 0170 nextSite++; 0171 site = new OAL::Site(geo, i18n("site_") + QString::number(nextSite++)); 0172 logObject->siteList()->append(site); 0173 } 0174 if (currentSession) 0175 { 0176 currentSession->setSession(currentSession->id(), site->id(), KStarsDateTime(ui.Begin->dateTime()), 0177 KStarsDateTime(ui.Begin->dateTime()), ui.Weather->toPlainText(), 0178 ui.Equipment->toPlainText(), ui.Comment->toPlainText(), 0179 ui.Language->text()); 0180 } 0181 else 0182 { 0183 while (logObject->findSessionByName(i18n("session_") + QString::number(nextSession))) 0184 nextSession++; 0185 currentSession = new OAL::Session(i18n("session_") + QString::number(nextSession++), site->id(), 0186 KStarsDateTime(ui.Begin->dateTime()), KStarsDateTime(ui.Begin->dateTime()), 0187 ui.Weather->toPlainText(), ui.Equipment->toPlainText(), 0188 ui.Comment->toPlainText(), ui.Language->text()); 0189 logObject->sessionList()->append(currentSession); 0190 } 0191 ui.stackedWidget->setCurrentIndex(1); //Move to the next page 0192 return true; 0193 } 0194 0195 void Execute::slotLocation() 0196 { 0197 QPointer<LocationDialog> ld = new LocationDialog(this); 0198 if (ld->exec() == QDialog::Accepted) 0199 { 0200 geo = ld->selectedCity(); 0201 ui.Location->setText(geo->fullName()); 0202 } 0203 delete ld; 0204 } 0205 0206 void Execute::loadTargets() 0207 { 0208 ui.Target->clear(); 0209 sortTargetList(); 0210 0211 for (auto &o : KStarsData::Instance()->observingList()->sessionList()) 0212 { 0213 ui.Target->addItem(getObjectName(o.data(), false)); 0214 } 0215 } 0216 0217 void Execute::loadEquipment() 0218 { 0219 ui.Scope->clear(); 0220 ui.Eyepiece->clear(); 0221 ui.Lens->clear(); 0222 ui.Filter->clear(); 0223 foreach (OAL::Scope *s, *(logObject->scopeList())) 0224 ui.Scope->addItem(s->name()); 0225 foreach (OAL::Eyepiece *e, *(logObject->eyepieceList())) 0226 ui.Eyepiece->addItem(e->name()); 0227 foreach (OAL::Lens *l, *(logObject->lensList())) 0228 ui.Lens->addItem(l->name()); 0229 foreach (OAL::Filter *f, *(logObject->filterList())) 0230 ui.Filter->addItem(f->name()); 0231 } 0232 0233 void Execute::loadObservers() 0234 { 0235 ui.Observer->clear(); 0236 foreach (OAL::Observer *o, *(logObject->observerList())) 0237 ui.Observer->addItem(o->name() + ' ' + o->surname()); 0238 } 0239 0240 void Execute::sortTargetList() 0241 { 0242 auto timeLessThan = [](QSharedPointer<SkyObject> o1, QSharedPointer<SkyObject> o2) 0243 { 0244 QTime t1 = KStarsData::Instance()->observingList()->scheduledTime(o1.data()); 0245 QTime t2 = KStarsData::Instance()->observingList()->scheduledTime(o2.data()); 0246 0247 if (t1 < QTime(12, 0, 0)) 0248 t1.setHMS(t1.hour() + 12, t1.minute(), t1.second()); 0249 else 0250 t1.setHMS(t1.hour() - 12, t1.minute(), t1.second()); 0251 if (t2 < QTime(12, 0, 0)) 0252 t2.setHMS(t2.hour() + 12, t2.minute(), t2.second()); 0253 else 0254 t2.setHMS(t2.hour() - 12, t2.minute(), t2.second()); 0255 return (t1 < t2); 0256 }; 0257 0258 std::sort(KStarsData::Instance()->observingList()->sessionList().begin(), 0259 KStarsData::Instance()->observingList()->sessionList().end(), timeLessThan); 0260 } 0261 0262 void Execute::addTargetNotes() 0263 { 0264 if (!ui.Target->count()) 0265 return; 0266 SkyObject *o = KStarsData::Instance()->observingList()->findObjectByName(ui.Target->currentItem()->text()); 0267 if (o) 0268 { 0269 currentTarget = o; 0270 KStarsData::Instance()->updateUserLog(o->name(), ui.Notes->toPlainText()); 0271 ui.Notes->clear(); 0272 loadObservationTab(); 0273 } 0274 } 0275 0276 void Execute::loadObservationTab() 0277 { 0278 ui.Time->setTime(KStarsDateTime::currentDateTime().time()); 0279 ui.stackedWidget->setCurrentIndex(2); 0280 ui.NextButton->setText(i18n("Next Target >")); 0281 } 0282 0283 bool Execute::addObservation() 0284 { 0285 slotSetCurrentObjects(); 0286 while (logObject->findObservationByName(i18n("observation_") + QString::number(nextObservation))) 0287 nextObservation++; 0288 KStarsDateTime dt = currentSession->begin(); 0289 dt.setTime(ui.Time->time()); 0290 OAL::Observation *o = new OAL::Observation( 0291 i18n("observation_") + QString::number(nextObservation++), currentObserver, currentSession, currentTarget, dt, 0292 ui.FaintestStar->value(), ui.Seeing->value(), currentScope, currentEyepiece, currentLens, currentFilter, 0293 ui.Description->toPlainText(), ui.Language->text()); 0294 logObject->observationList()->append(o); 0295 ui.Description->clear(); 0296 return true; 0297 } 0298 void Execute::slotEndSession() 0299 { 0300 if (currentSession) 0301 { 0302 currentSession->setSession(currentSession->id(), currentSession->site(), KStarsDateTime(ui.Begin->dateTime()), 0303 KStarsDateTime::currentDateTime(), ui.Weather->toPlainText(), 0304 ui.Equipment->toPlainText(), ui.Comment->toPlainText(), ui.Language->text()); 0305 0306 QUrl fileURL = QFileDialog::getSaveFileUrl(nullptr, i18nc("@title:window", "Save Session"), QUrl(QDir::homePath()), "*.xml"); 0307 0308 if (fileURL.isEmpty()) 0309 { 0310 // Cancel 0311 return; 0312 } 0313 0314 if (fileURL.isValid()) 0315 { 0316 QFile f(fileURL.toLocalFile()); 0317 if (!f.open(QIODevice::WriteOnly)) 0318 { 0319 QString message = i18n("Could not open file %1", f.fileName()); 0320 KSNotification::sorry(message, i18n("Could Not Open File")); 0321 return; 0322 } 0323 QTextStream ostream(&f); 0324 ostream << logObject->writeLog(false); 0325 f.close(); 0326 } 0327 } 0328 hide(); 0329 ui.stackedWidget->setCurrentIndex(0); 0330 logObject->observationList()->clear(); 0331 logObject->sessionList()->clear(); 0332 delete currentSession; 0333 currentTarget = nullptr; 0334 currentSession = nullptr; 0335 } 0336 void Execute::slotObserverAdd() 0337 { 0338 QPointer<ObserverAdd> m_observerAdd = new ObserverAdd(); 0339 m_observerAdd->exec(); 0340 delete m_observerAdd; 0341 } 0342 0343 void Execute::slotSetTarget(const QString &name) 0344 { 0345 currentTarget = KStarsData::Instance()->observingList()->findObjectByName(name); 0346 if (!currentTarget) 0347 { 0348 ui.NextButton->setEnabled(false); 0349 ui.Slew->setEnabled(false); 0350 return; 0351 } 0352 else 0353 { 0354 ui.NextButton->setEnabled(true); 0355 ui.Slew->setEnabled(true); 0356 KStarsData::Instance()->observingList()->selectObject(currentTarget); 0357 KStarsData::Instance()->observingList()->slotCenterObject(); 0358 QString smag = "--"; 0359 if (-30.0 < currentTarget->mag() && currentTarget->mag() < 90.0) 0360 smag = QString::number(currentTarget->mag(), 'g', 0361 2); // The lower limit to avoid display of unrealistic comet magnitudes 0362 ui.Mag->setText(smag); 0363 ui.Type->setText(currentTarget->typeName()); 0364 ui.SchTime->setText( 0365 KStarsData::Instance()->observingList()->scheduledTime(currentTarget).toString("h:mm:ss AP")); 0366 SkyPoint p = currentTarget->recomputeCoords(KStarsDateTime::currentDateTime(), geo); 0367 dms lst(geo->GSTtoLST(KStarsDateTime::currentDateTime().gst())); 0368 p.EquatorialToHorizontal(&lst, geo->lat()); 0369 ui.RA->setText(p.ra().toHMSString()); 0370 ui.Dec->setText(p.dec().toDMSString()); 0371 ui.Alt->setText(p.alt().toDMSString()); 0372 ui.Az->setText(p.az().toDMSString()); 0373 ui.Notes->setText(KStarsData::Instance()->getUserData(currentTarget->name()).userLog); 0374 } 0375 } 0376 0377 void Execute::slotSlew() 0378 { 0379 KStarsData::Instance()->observingList()->slotSlewToObject(); 0380 } 0381 0382 void Execute::selectNextTarget() 0383 { 0384 int i = findIndexOfTarget(currentTarget->name()) + 1; 0385 if (i < ui.Target->count()) 0386 { 0387 ui.Target->selectionModel()->clear(); 0388 ui.Target->setCurrentRow(i, QItemSelectionModel::SelectCurrent); 0389 } 0390 } 0391 0392 void Execute::slotSetCurrentObjects() 0393 { 0394 currentScope = logObject->findScopeByName(ui.Scope->currentText()); 0395 currentEyepiece = logObject->findEyepieceByName(ui.Eyepiece->currentText()); 0396 currentLens = logObject->findLensByName(ui.Lens->currentText()); 0397 currentFilter = logObject->findFilterByName(ui.Filter->currentText()); 0398 currentObserver = logObject->findObserverByName(ui.Observer->currentText()); 0399 } 0400 0401 void Execute::slotShowSession() 0402 { 0403 ui.Target->hide(); 0404 ui.stackedWidget->setCurrentIndex(0); 0405 ui.NextButton->hide(); 0406 ui.AddObject->hide(); 0407 ui.RemoveObject->hide(); 0408 } 0409 0410 void Execute::slotShowTargets() 0411 { 0412 if (saveSession()) 0413 { 0414 ui.Target->show(); 0415 ui.AddObject->show(); 0416 ui.RemoveObject->show(); 0417 ui.stackedWidget->setCurrentIndex(1); 0418 ui.NextButton->show(); 0419 ui.NextButton->setText(i18n("Next Page >")); 0420 } 0421 } 0422 0423 void Execute::slotAddObject() 0424 { 0425 if (FindDialog::Instance()->exec() == QDialog::Accepted) 0426 { 0427 SkyObject *o = FindDialog::Instance()->targetObject(); 0428 if (o != nullptr) 0429 { 0430 KStarsData::Instance()->observingList()->slotAddObject(o, true); 0431 init(); 0432 } 0433 } 0434 } 0435 0436 void Execute::slotRemoveObject() 0437 { 0438 QModelIndex i = ui.Target->currentIndex(); 0439 SkyObject *obj = nullptr; 0440 0441 if (i.isValid()) 0442 { 0443 QString ObjName = i.data().toString(); 0444 0445 obj = KStarsData::Instance()->skyComposite()->findByName(ObjName); 0446 } 0447 0448 if (obj != nullptr) 0449 { 0450 KStarsData::Instance()->observingList()->slotRemoveObject(obj, true); 0451 loadTargets(); 0452 } 0453 } 0454 0455 QString Execute::getObjectName(const SkyObject *o, bool translated) 0456 { 0457 QString finalObjectName; 0458 0459 if (o->name() == "star") 0460 { 0461 StarObject *s = (StarObject *)o; 0462 0463 // JM: Enable HD Index stars to be added to the observing list. 0464 if (s->getHDIndex() != 0) 0465 finalObjectName = QString("HD %1").arg(QString::number(s->getHDIndex())); 0466 } 0467 else 0468 finalObjectName = translated ? o->translatedName() : o->name(); 0469 0470 return finalObjectName; 0471 }