File indexing completed on 2024-04-21 03:44:52
0001 /* 0002 SPDX-FileCopyrightText: 2002 Pablo de Vicente <vicente@oan.es> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "modcalcsidtime.h" 0008 0009 #include "kstarsdata.h" 0010 #include "kstarsdatetime.h" 0011 #include "ksnotification.h" 0012 #include "dialogs/locationdialog.h" 0013 0014 #include <KLineEdit> 0015 0016 #include <QTextStream> 0017 0018 // Qt version calming 0019 #include <qtskipemptyparts.h> 0020 0021 modCalcSidTime::modCalcSidTime(QWidget *parent) : QFrame(parent) 0022 { 0023 setupUi(this); 0024 0025 //Preset date and location 0026 showCurrentTimeAndLocation(); 0027 0028 // signals and slots connections 0029 connect(LocationButton, SIGNAL(clicked()), this, SLOT(slotChangeLocation())); 0030 connect(Date, SIGNAL(dateChanged(QDate)), this, SLOT(slotChangeDate())); 0031 connect(LT, SIGNAL(timeChanged(QTime)), this, SLOT(slotConvertST(QTime))); 0032 connect(ST, SIGNAL(timeChanged(QTime)), this, SLOT(slotConvertLT(QTime))); 0033 0034 connect(LocationCheckBatch, SIGNAL(clicked()), this, SLOT(slotLocationChecked())); 0035 connect(DateCheckBatch, SIGNAL(clicked()), this, SLOT(slotDateChecked())); 0036 connect(LocationCheckBatch, SIGNAL(clicked()), this, SLOT(slotHelpLabel())); 0037 connect(DateCheckBatch, SIGNAL(clicked()), this, SLOT(slotHelpLabel())); 0038 connect(ComputeComboBatch, SIGNAL(currentIndexChanged(int)), this, SLOT(slotHelpLabel())); 0039 0040 connect(InputFileBatch, SIGNAL(urlSelected(QUrl)), this, SLOT(slotCheckFiles())); 0041 connect(OutputFileBatch, SIGNAL(urlSelected(QUrl)), this, SLOT(slotCheckFiles())); 0042 connect(LocationButtonBatch, SIGNAL(clicked()), this, SLOT(slotLocationBatch())); 0043 connect(RunButtonBatch, SIGNAL(clicked()), this, SLOT(slotRunBatch())); 0044 connect(ViewButtonBatch, SIGNAL(clicked()), this, SLOT(slotViewBatch())); 0045 0046 RunButtonBatch->setEnabled(false); 0047 ViewButtonBatch->setEnabled(false); 0048 0049 show(); 0050 } 0051 0052 void modCalcSidTime::showCurrentTimeAndLocation() 0053 { 0054 KStarsData *data = KStarsData::Instance(); 0055 LT->setTime(data->lt().time()); 0056 Date->setDate(data->lt().date()); 0057 0058 geo = data->geo(); 0059 LocationButton->setText(geo->fullName()); 0060 geoBatch = data->geo(); 0061 LocationButtonBatch->setText(geoBatch->fullName()); 0062 0063 slotConvertST(LT->time()); 0064 } 0065 0066 void modCalcSidTime::slotChangeLocation() 0067 { 0068 QPointer<LocationDialog> ld = new LocationDialog(this); 0069 0070 if (ld->exec() == QDialog::Accepted) 0071 { 0072 GeoLocation *newGeo = ld->selectedCity(); 0073 if (newGeo) 0074 { 0075 geo = newGeo; 0076 LocationButton->setText(geo->fullName()); 0077 0078 //Update the displayed ST 0079 slotConvertST(LT->time()); 0080 } 0081 } 0082 delete ld; 0083 } 0084 0085 void modCalcSidTime::slotChangeDate() 0086 { 0087 slotConvertST(LT->time()); 0088 } 0089 0090 void modCalcSidTime::slotConvertST(const QTime <) 0091 { 0092 // blockSignals is used to break signal loop 0093 ST->blockSignals(true); 0094 ST->setTime(computeLTtoST(lt)); 0095 ST->blockSignals(false); 0096 } 0097 0098 void modCalcSidTime::slotConvertLT(const QTime &st) 0099 { 0100 // blockSignals is used to break signal loop 0101 LT->blockSignals(true); 0102 LT->setTime(computeSTtoLT(st)); 0103 LT->blockSignals(false); 0104 } 0105 0106 QTime modCalcSidTime::computeLTtoST(QTime lt) 0107 { 0108 KStarsDateTime utdt = geo->LTtoUT(KStarsDateTime(Date->date(), lt)); 0109 dms st = geo->GSTtoLST(utdt.gst()); 0110 return QTime(st.hour(), st.minute(), st.second()); 0111 } 0112 0113 QTime modCalcSidTime::computeSTtoLT(QTime st) 0114 { 0115 KStarsDateTime dt0 = KStarsDateTime(Date->date(), QTime(0, 0, 0)); 0116 dms lst; 0117 lst.setH(st.hour(), st.minute(), st.second()); 0118 dms gst = geo->LSTtoGST(lst); 0119 return geo->UTtoLT(KStarsDateTime(Date->date(), dt0.GSTtoUT(gst))).time(); 0120 } 0121 0122 //** Batch mode **// 0123 void modCalcSidTime::slotDateChecked() 0124 { 0125 DateBatch->setEnabled(!DateCheckBatch->isChecked()); 0126 } 0127 0128 void modCalcSidTime::slotLocationChecked() 0129 { 0130 LocationButtonBatch->setEnabled(!LocationCheckBatch->isChecked()); 0131 0132 if (LocationCheckBatch->isChecked()) 0133 { 0134 QString message = i18n("Location strings consist of the " 0135 "comma-separated names of the city, province and country. " 0136 "If the string contains spaces, enclose it in quotes so it " 0137 "gets parsed properly."); 0138 0139 KMessageBox::information(nullptr, message, i18n("Hint for writing location strings"), 0140 "DontShowLocationStringMessageBox"); 0141 } 0142 } 0143 0144 void modCalcSidTime::slotHelpLabel() 0145 { 0146 QStringList inList; 0147 if (ComputeComboBatch->currentIndex() == 0) 0148 inList.append(i18n("local time")); 0149 else 0150 inList.append(i18n("sidereal time")); 0151 0152 if (DateCheckBatch->checkState() == Qt::Checked) 0153 inList.append(i18n("date")); 0154 0155 if (LocationCheckBatch->checkState() == Qt::Checked) 0156 inList.append(i18n("location")); 0157 0158 QString inListString = inList[0]; 0159 if (inList.size() == 2) 0160 inListString = i18n("%1 and %2", inList[0], inList[1]); 0161 if (inList.size() == 3) 0162 inListString = i18n("%1, %2 and %3", inList[0], inList[1], inList[2]); 0163 0164 HelpLabel->setText(i18n("Specify %1 in the input file.", inListString)); 0165 } 0166 0167 void modCalcSidTime::slotLocationBatch() 0168 { 0169 QPointer<LocationDialog> ld = new LocationDialog(this); 0170 0171 if (ld->exec() == QDialog::Accepted) 0172 { 0173 GeoLocation *newGeo = ld->selectedCity(); 0174 if (newGeo) 0175 { 0176 geoBatch = newGeo; 0177 LocationButtonBatch->setText(geoBatch->fullName()); 0178 } 0179 } 0180 delete ld; 0181 } 0182 0183 void modCalcSidTime::slotCheckFiles() 0184 { 0185 if (!InputFileBatch->lineEdit()->text().isEmpty() && !OutputFileBatch->lineEdit()->text().isEmpty()) 0186 { 0187 RunButtonBatch->setEnabled(true); 0188 } 0189 else 0190 { 0191 RunButtonBatch->setEnabled(false); 0192 } 0193 } 0194 0195 void modCalcSidTime::slotRunBatch() 0196 { 0197 QString inputFileName = InputFileBatch->url().toLocalFile(); 0198 0199 if (QFile::exists(inputFileName)) 0200 { 0201 QFile f(inputFileName); 0202 if (!f.open(QIODevice::ReadOnly)) 0203 { 0204 QString message = i18n("Could not open file %1.", f.fileName()); 0205 KSNotification::sorry(message, i18n("Could Not Open File")); 0206 inputFileName.clear(); 0207 return; 0208 } 0209 0210 QTextStream istream(&f); 0211 processLines(istream); 0212 0213 ViewButtonBatch->setEnabled(true); 0214 0215 f.close(); 0216 } 0217 else 0218 { 0219 QString message = i18n("Invalid file: %1", inputFileName); 0220 KSNotification::sorry(message, i18n("Invalid file")); 0221 inputFileName.clear(); 0222 return; 0223 } 0224 } 0225 0226 void modCalcSidTime::processLines(QTextStream &istream) 0227 { 0228 QFile fOut(OutputFileBatch->url().toLocalFile()); 0229 fOut.open(QIODevice::WriteOnly); 0230 QTextStream ostream(&fOut); 0231 0232 QString line; 0233 dms LST; 0234 QTime inTime, outTime; 0235 QDate dt; 0236 0237 if (!DateCheckBatch->isChecked()) 0238 dt = DateBatch->date(); 0239 0240 while (!istream.atEnd()) 0241 { 0242 line = istream.readLine(); 0243 line = line.trimmed(); 0244 0245 QStringList fields = line.split(' ', Qt::SkipEmptyParts); 0246 0247 //Find and parse the location string 0248 if (LocationCheckBatch->isChecked()) 0249 { 0250 //First, look for a pair of quotation marks, and parse the string between them 0251 QChar q = '\"'; 0252 if (line.indexOf(q) == -1) 0253 q = '\''; 0254 if (line.count(q) == 2) 0255 { 0256 int iStart = line.indexOf(q); 0257 int iEnd = line.indexOf(q, iStart + 1); 0258 QString locationString = line.mid(iStart, iEnd - iStart + 1); 0259 line.remove(locationString); 0260 fields = line.split(' ', Qt::SkipEmptyParts); 0261 locationString.remove(q); 0262 0263 QStringList locationFields = locationString.split(',', Qt::SkipEmptyParts); 0264 for (int i = 0; i < locationFields.size(); i++) 0265 locationFields[i] = locationFields[i].trimmed(); 0266 0267 if (locationFields.size() == 1) 0268 locationFields.insert(1, ""); 0269 if (locationFields.size() == 2) 0270 locationFields.insert(1, ""); 0271 if (locationFields.size() != 3) 0272 { 0273 qDebug() << Q_FUNC_INFO << "Error: could not parse location string: " << locationString; 0274 continue; 0275 } 0276 0277 geoBatch = KStarsData::Instance()->locationNamed(locationFields[0], locationFields[1], 0278 locationFields[2]); 0279 if (geoBatch == nullptr) 0280 { 0281 qDebug() << Q_FUNC_INFO << "Error: location not found in database: " << locationString; 0282 continue; 0283 } 0284 } 0285 } 0286 0287 if (DateCheckBatch->isChecked()) 0288 { 0289 //Parse one of the fields as the date 0290 for (auto &s : fields) 0291 { 0292 dt = QDate::fromString(s); 0293 if (dt.isValid()) 0294 break; 0295 } 0296 if (!dt.isValid()) 0297 { 0298 qDebug() << Q_FUNC_INFO << "Error: did not find a valid date string in: " << line; 0299 continue; 0300 } 0301 } 0302 0303 //Parse one of the fields as the time 0304 for (auto &s : fields) 0305 { 0306 if (s.contains(':')) 0307 { 0308 inTime = QTime::fromString(s.length() == 4 ? '0' + s : s); 0309 if (inTime.isValid()) 0310 break; 0311 } 0312 } 0313 if (!inTime.isValid()) 0314 { 0315 qDebug() << Q_FUNC_INFO << "Error: did not find a valid time string in: " << line; 0316 continue; 0317 } 0318 0319 if (geoBatch != nullptr) 0320 { 0321 if (ComputeComboBatch->currentIndex() == 0) 0322 { 0323 //inTime is the local time, compute LST 0324 KStarsDateTime ksdt(dt, inTime); 0325 ksdt = geoBatch->LTtoUT(ksdt); 0326 dms lst = geoBatch->GSTtoLST(ksdt.gst()); 0327 outTime = QTime(lst.hour(), lst.minute(), lst.second()); 0328 } 0329 else 0330 { 0331 //inTime is the sidereal time, compute the local time 0332 KStarsDateTime ksdt(dt, QTime(0, 0, 0)); 0333 dms lst; 0334 lst.setH(inTime.hour(), inTime.minute(), inTime.second()); 0335 QTime ut = ksdt.GSTtoUT(geoBatch->LSTtoGST(lst)); 0336 ksdt.setTime(ut); 0337 ksdt = geoBatch->UTtoLT(ksdt); 0338 outTime = ksdt.time(); 0339 } 0340 0341 //Write to output file 0342 ostream << QLocale().toString(dt, QLocale::LongFormat) << " \"" << geoBatch->fullName() << "\" " 0343 << QLocale().toString(inTime) << " " << QLocale().toString(outTime) << '\n'; 0344 } 0345 } 0346 0347 fOut.close(); 0348 } 0349 0350 void modCalcSidTime::slotViewBatch() 0351 { 0352 QFile fOut(OutputFileBatch->url().toLocalFile()); 0353 fOut.open(QIODevice::ReadOnly); 0354 QTextStream istream(&fOut); 0355 QStringList text; 0356 0357 while (!istream.atEnd()) 0358 text.append(istream.readLine()); 0359 0360 fOut.close(); 0361 0362 KMessageBox::informationList(nullptr, i18n("Results of Sidereal time calculation"), text, 0363 OutputFileBatch->url().toLocalFile()); 0364 }