Kstars

modcalcsidtime.cpp
1 /*
2  SPDX-FileCopyrightText: 2002 Pablo de Vicente <[email protected]>
3 
4  SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #include "modcalcsidtime.h"
8 
9 #include "kstarsdata.h"
10 #include "kstarsdatetime.h"
11 #include "ksnotification.h"
12 #include "dialogs/locationdialog.h"
13 
14 #include <KLineEdit>
15 
16 #include <QTextStream>
17 
18 // Qt version calming
19 #include <qtskipemptyparts.h>
20 
21 modCalcSidTime::modCalcSidTime(QWidget *parent) : QFrame(parent)
22 {
23  setupUi(this);
24 
25  //Preset date and location
26  showCurrentTimeAndLocation();
27 
28  // signals and slots connections
29  connect(LocationButton, SIGNAL(clicked()), this, SLOT(slotChangeLocation()));
30  connect(Date, SIGNAL(dateChanged(QDate)), this, SLOT(slotChangeDate()));
31  connect(LT, SIGNAL(timeChanged(QTime)), this, SLOT(slotConvertST(QTime)));
32  connect(ST, SIGNAL(timeChanged(QTime)), this, SLOT(slotConvertLT(QTime)));
33 
34  connect(LocationCheckBatch, SIGNAL(clicked()), this, SLOT(slotLocationChecked()));
35  connect(DateCheckBatch, SIGNAL(clicked()), this, SLOT(slotDateChecked()));
36  connect(LocationCheckBatch, SIGNAL(clicked()), this, SLOT(slotHelpLabel()));
37  connect(DateCheckBatch, SIGNAL(clicked()), this, SLOT(slotHelpLabel()));
38  connect(ComputeComboBatch, SIGNAL(currentIndexChanged(int)), this, SLOT(slotHelpLabel()));
39 
40  connect(InputFileBatch, SIGNAL(urlSelected(QUrl)), this, SLOT(slotCheckFiles()));
41  connect(OutputFileBatch, SIGNAL(urlSelected(QUrl)), this, SLOT(slotCheckFiles()));
42  connect(LocationButtonBatch, SIGNAL(clicked()), this, SLOT(slotLocationBatch()));
43  connect(RunButtonBatch, SIGNAL(clicked()), this, SLOT(slotRunBatch()));
44  connect(ViewButtonBatch, SIGNAL(clicked()), this, SLOT(slotViewBatch()));
45 
46  RunButtonBatch->setEnabled(false);
47  ViewButtonBatch->setEnabled(false);
48 
49  show();
50 }
51 
52 void modCalcSidTime::showCurrentTimeAndLocation()
53 {
54  KStarsData *data = KStarsData::Instance();
55  LT->setTime(data->lt().time());
56  Date->setDate(data->lt().date());
57 
58  geo = data->geo();
59  LocationButton->setText(geo->fullName());
60  geoBatch = data->geo();
61  LocationButtonBatch->setText(geoBatch->fullName());
62 
63  slotConvertST(LT->time());
64 }
65 
66 void modCalcSidTime::slotChangeLocation()
67 {
68  QPointer<LocationDialog> ld = new LocationDialog(this);
69 
70  if (ld->exec() == QDialog::Accepted)
71  {
72  GeoLocation *newGeo = ld->selectedCity();
73  if (newGeo)
74  {
75  geo = newGeo;
76  LocationButton->setText(geo->fullName());
77 
78  //Update the displayed ST
79  slotConvertST(LT->time());
80  }
81  }
82  delete ld;
83 }
84 
85 void modCalcSidTime::slotChangeDate()
86 {
87  slotConvertST(LT->time());
88 }
89 
90 void modCalcSidTime::slotConvertST(const QTime &lt)
91 {
92  // blockSignals is used to break signal loop
93  ST->blockSignals(true);
94  ST->setTime(computeLTtoST(lt));
95  ST->blockSignals(false);
96 }
97 
98 void modCalcSidTime::slotConvertLT(const QTime &st)
99 {
100  // blockSignals is used to break signal loop
101  LT->blockSignals(true);
102  LT->setTime(computeSTtoLT(st));
103  LT->blockSignals(false);
104 }
105 
106 QTime modCalcSidTime::computeLTtoST(QTime lt)
107 {
108  KStarsDateTime utdt = geo->LTtoUT(KStarsDateTime(Date->date(), lt));
109  dms st = geo->GSTtoLST(utdt.gst());
110  return QTime(st.hour(), st.minute(), st.second());
111 }
112 
113 QTime modCalcSidTime::computeSTtoLT(QTime st)
114 {
115  KStarsDateTime dt0 = KStarsDateTime(Date->date(), QTime(0, 0, 0));
116  dms lst;
117  lst.setH(st.hour(), st.minute(), st.second());
118  dms gst = geo->LSTtoGST(lst);
119  return geo->UTtoLT(KStarsDateTime(Date->date(), dt0.GSTtoUT(gst))).time();
120 }
121 
122 //** Batch mode **//
123 void modCalcSidTime::slotDateChecked()
124 {
125  DateBatch->setEnabled(!DateCheckBatch->isChecked());
126 }
127 
128 void modCalcSidTime::slotLocationChecked()
129 {
130  LocationButtonBatch->setEnabled(!LocationCheckBatch->isChecked());
131 
132  if (LocationCheckBatch->isChecked())
133  {
134  QString message = i18n("Location strings consist of the "
135  "comma-separated names of the city, province and country. "
136  "If the string contains spaces, enclose it in quotes so it "
137  "gets parsed properly.");
138 
139  KMessageBox::information(nullptr, message, i18n("Hint for writing location strings"),
140  "DontShowLocationStringMessageBox");
141  }
142 }
143 
144 void modCalcSidTime::slotHelpLabel()
145 {
146  QStringList inList;
147  if (ComputeComboBatch->currentIndex() == 0)
148  inList.append(i18n("local time"));
149  else
150  inList.append(i18n("sidereal time"));
151 
152  if (DateCheckBatch->checkState() == Qt::Checked)
153  inList.append(i18n("date"));
154 
155  if (LocationCheckBatch->checkState() == Qt::Checked)
156  inList.append(i18n("location"));
157 
158  QString inListString = inList[0];
159  if (inList.size() == 2)
160  inListString = i18n("%1 and %2", inList[0], inList[1]);
161  if (inList.size() == 3)
162  inListString = i18n("%1, %2 and %3", inList[0], inList[1], inList[2]);
163 
164  HelpLabel->setText(i18n("Specify %1 in the input file.", inListString));
165 }
166 
167 void modCalcSidTime::slotLocationBatch()
168 {
169  QPointer<LocationDialog> ld = new LocationDialog(this);
170 
171  if (ld->exec() == QDialog::Accepted)
172  {
173  GeoLocation *newGeo = ld->selectedCity();
174  if (newGeo)
175  {
176  geoBatch = newGeo;
177  LocationButtonBatch->setText(geoBatch->fullName());
178  }
179  }
180  delete ld;
181 }
182 
183 void modCalcSidTime::slotCheckFiles()
184 {
185  if (!InputFileBatch->lineEdit()->text().isEmpty() && !OutputFileBatch->lineEdit()->text().isEmpty())
186  {
187  RunButtonBatch->setEnabled(true);
188  }
189  else
190  {
191  RunButtonBatch->setEnabled(false);
192  }
193 }
194 
195 void modCalcSidTime::slotRunBatch()
196 {
197  QString inputFileName = InputFileBatch->url().toLocalFile();
198 
199  if (QFile::exists(inputFileName))
200  {
201  QFile f(inputFileName);
202  if (!f.open(QIODevice::ReadOnly))
203  {
204  QString message = i18n("Could not open file %1.", f.fileName());
205  KSNotification::sorry(message, i18n("Could Not Open File"));
206  inputFileName.clear();
207  return;
208  }
209 
210  QTextStream istream(&f);
211  processLines(istream);
212 
213  ViewButtonBatch->setEnabled(true);
214 
215  f.close();
216  }
217  else
218  {
219  QString message = i18n("Invalid file: %1", inputFileName);
220  KSNotification::sorry(message, i18n("Invalid file"));
221  inputFileName.clear();
222  return;
223  }
224 }
225 
226 void modCalcSidTime::processLines(QTextStream &istream)
227 {
228  QFile fOut(OutputFileBatch->url().toLocalFile());
229  fOut.open(QIODevice::WriteOnly);
230  QTextStream ostream(&fOut);
231 
232  QString line;
233  dms LST;
234  QTime inTime, outTime;
235  QDate dt;
236 
237  if (!DateCheckBatch->isChecked())
238  dt = DateBatch->date();
239 
240  while (!istream.atEnd())
241  {
242  line = istream.readLine();
243  line = line.trimmed();
244 
245  QStringList fields = line.split(' ', Qt::SkipEmptyParts);
246 
247  //Find and parse the location string
248  if (LocationCheckBatch->isChecked())
249  {
250  //First, look for a pair of quotation marks, and parse the string between them
251  QChar q = '\"';
252  if (line.indexOf(q) == -1)
253  q = '\'';
254  if (line.count(q) == 2)
255  {
256  int iStart = line.indexOf(q);
257  int iEnd = line.indexOf(q, iStart + 1);
258  QString locationString = line.mid(iStart, iEnd - iStart + 1);
259  line.remove(locationString);
260  fields = line.split(' ', Qt::SkipEmptyParts);
261  locationString.remove(q);
262 
263  QStringList locationFields = locationString.split(',', Qt::SkipEmptyParts);
264  for (int i = 0; i < locationFields.size(); i++)
265  locationFields[i] = locationFields[i].trimmed();
266 
267  if (locationFields.size() == 1)
268  locationFields.insert(1, "");
269  if (locationFields.size() == 2)
270  locationFields.insert(1, "");
271  if (locationFields.size() != 3)
272  {
273  qDebug() << Q_FUNC_INFO << "Error: could not parse location string: " << locationString;
274  continue;
275  }
276 
277  geoBatch = KStarsData::Instance()->locationNamed(locationFields[0], locationFields[1],
278  locationFields[2]);
279  if (geoBatch == nullptr)
280  {
281  qDebug() << Q_FUNC_INFO << "Error: location not found in database: " << locationString;
282  continue;
283  }
284  }
285  }
286 
287  if (DateCheckBatch->isChecked())
288  {
289  //Parse one of the fields as the date
290  for (auto &s : fields)
291  {
292  dt = QDate::fromString(s);
293  if (dt.isValid())
294  break;
295  }
296  if (!dt.isValid())
297  {
298  qDebug() << Q_FUNC_INFO << "Error: did not find a valid date string in: " << line;
299  continue;
300  }
301  }
302 
303  //Parse one of the fields as the time
304  for (auto &s : fields)
305  {
306  if (s.contains(':'))
307  {
308  inTime = QTime::fromString(s.length() == 4 ? '0' + s : s);
309  if (inTime.isValid())
310  break;
311  }
312  }
313  if (!inTime.isValid())
314  {
315  qDebug() << Q_FUNC_INFO << "Error: did not find a valid time string in: " << line;
316  continue;
317  }
318 
319  if (geoBatch != nullptr)
320  {
321  if (ComputeComboBatch->currentIndex() == 0)
322  {
323  //inTime is the local time, compute LST
324  KStarsDateTime ksdt(dt, inTime);
325  ksdt = geoBatch->LTtoUT(ksdt);
326  dms lst = geoBatch->GSTtoLST(ksdt.gst());
327  outTime = QTime(lst.hour(), lst.minute(), lst.second());
328  }
329  else
330  {
331  //inTime is the sidereal time, compute the local time
332  KStarsDateTime ksdt(dt, QTime(0, 0, 0));
333  dms lst;
334  lst.setH(inTime.hour(), inTime.minute(), inTime.second());
335  QTime ut = ksdt.GSTtoUT(geoBatch->LSTtoGST(lst));
336  ksdt.setTime(ut);
337  ksdt = geoBatch->UTtoLT(ksdt);
338  outTime = ksdt.time();
339  }
340 
341  //Write to output file
342  ostream << QLocale().toString(dt, QLocale::LongFormat) << " \"" << geoBatch->fullName() << "\" "
343  << QLocale().toString(inTime) << " " << QLocale().toString(outTime) << '\n';
344  }
345  }
346 
347  fOut.close();
348 }
349 
350 void modCalcSidTime::slotViewBatch()
351 {
352  QFile fOut(OutputFileBatch->url().toLocalFile());
353  fOut.open(QIODevice::ReadOnly);
354  QTextStream istream(&fOut);
355  QStringList text;
356 
357  while (!istream.atEnd())
358  text.append(istream.readLine());
359 
360  fOut.close();
361 
362  KMessageBox::informationList(nullptr, i18n("Results of Sidereal time calculation"), text,
363  OutputFileBatch->url().toLocalFile());
364 }
void append(const T &value)
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
QString fullName() const
Definition: geolocation.cpp:46
const KStarsDateTime & lt() const
Definition: kstarsdata.h:151
QTime fromString(const QString &string, Qt::DateFormat format)
QStringList split(const QString &sep, QString::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
QTime time() const const
QString trimmed() const const
void clear()
bool isValid() const const
bool exists() const const
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
virtual void setH(const double &x)
Sets floating-point value of angle, in hours.
Definition: dms.h:210
int size() const const
QString i18n(const char *text, const TYPE &arg...)
bool atEnd() const const
SkipEmptyParts
GeoLocation * geo()
Definition: kstarsdata.h:230
QString readLine(qint64 maxlen)
QString toString(qlonglong i) const const
bool isValid() const const
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const const
void setupUi(QWidget *widget)
int second() const
Definition: dms.cpp:231
int hour() const const
void insert(int i, const T &value)
QString & remove(int position, int n)
void show()
An angle, stored as degrees, but expressible in many ways.
Definition: dms.h:37
QDate fromString(const QString &string, Qt::DateFormat format)
int count() const const
int second() const const
QDate date() const const
int hour() const
Definition: dms.h:147
void information(QWidget *parent, const QString &text, const QString &title=QString(), const QString &dontShowAgainName=QString(), Options options=Notify)
void informationList(QWidget *parent, const QString &text, const QStringList &strlist, const QString &title=QString(), const QString &dontShowAgainName=QString(), Options options=Notify)
int minute() const
Definition: dms.cpp:221
QTime GSTtoUT(dms GST) const
Convert a given Greenwich Sidereal Time to Universal Time (=Greenwich Mean Time).
QString mid(int position, int n) const const
int minute() const const
QString message
Relevant data about an observing location on Earth.
Definition: geolocation.h:27
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Sun Oct 1 2023 04:02:41 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.