Kstars

opsastrometryindexfiles.cpp
1 
2 #include "opsastrometryindexfiles.h"
3 
4 #include "align.h"
5 #include "kstars.h"
6 #include "ksutils.h"
7 #include "Options.h"
8 #include "kspaths.h"
9 #include "ksnotification.h"
10 
11 #include <KConfigDialog>
12 #include <KMessageBox>
13 
14 namespace Ekos
15 {
16 OpsAstrometryIndexFiles::OpsAstrometryIndexFiles(Align *parent) : QDialog(KStars::Instance())
17 {
18  setupUi(this);
19 
20  downloadSpeed = 100;
21  actualdownloadSpeed = downloadSpeed;
22  alignModule = parent;
23  manager = new QNetworkAccessManager();
24 
25  indexURL->setText("http://broiler.astrometry.net/~dstn/");
26 
27  //Get a pointer to the KConfigDialog
28  // m_ConfigDialog = KConfigDialog::exists( "alignsettings" );
29  connect(openIndexFileDirectory, SIGNAL(clicked()), this, SLOT(slotOpenIndexFileDirectory()));
30  connect(indexURL, &QLineEdit::textChanged, [&]()
31  {
32  indexURL->text();
33  });
34 
35 
36  astrometryIndex[2.8] = "00";
37  astrometryIndex[4.0] = "01";
38  astrometryIndex[5.6] = "02";
39  astrometryIndex[8] = "03";
40  astrometryIndex[11] = "04";
41  astrometryIndex[16] = "05";
42  astrometryIndex[22] = "06";
43  astrometryIndex[30] = "07";
44  astrometryIndex[42] = "08";
45  astrometryIndex[60] = "09";
46  astrometryIndex[85] = "10";
47  astrometryIndex[120] = "11";
48  astrometryIndex[170] = "12";
49  astrometryIndex[240] = "13";
50  astrometryIndex[340] = "14";
51  astrometryIndex[480] = "15";
52  astrometryIndex[680] = "16";
53  astrometryIndex[1000] = "17";
54  astrometryIndex[1400] = "18";
55  astrometryIndex[2000] = "19";
56 
57  QList<QCheckBox *> checkboxes = findChildren<QCheckBox *>();
58 
59  connect(indexLocations, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
60  &OpsAstrometryIndexFiles::slotUpdate);
61 
62  for (auto &checkBox : checkboxes)
63  {
64  connect(checkBox, &QCheckBox::clicked, this, &OpsAstrometryIndexFiles::downloadOrDeleteIndexFiles);
65  }
66 
67  QList<QProgressBar *> progressBars = findChildren<QProgressBar *>();
68  QList<QLabel *> qLabels = findChildren<QLabel *>();
69  QList<QPushButton *> qButtons = findChildren<QPushButton *>();
70 
71  for (auto &bar : progressBars)
72  {
73  if(bar->objectName().contains("progress"))
74  {
75  bar->setVisible(false);
76  bar->setTextVisible(false);
77  }
78  }
79 
80  for (auto &button : qButtons)
81  {
82  if(button->objectName().contains("cancel"))
83  {
84  button->setVisible(false);
85  }
86  }
87 
88  for (QLabel * label : qLabels)
89  {
90  if(label->text().contains("info") || label->text().contains("perc"))
91  {
92  label->setVisible(false);
93  }
94  }
95 
96  connect(addIndexFileDirectory, &QAbstractButton::clicked, this, [this]()
97  {
98  QString dir = QFileDialog::getExistingDirectory(this, "Load Index File Directory",
102  if (dir.isEmpty())
103  return;
104  addDirectoryToList(dir);
105  });
106  connect(removeIndexFileDirectory, &QAbstractButton::clicked, this, [this]()
107  {
108  if(indexLocations->currentIndex() != 0)
109  removeDirectoryFromList(indexLocations->currentText());
110  });
111 
112 
113 }
114 
115 void OpsAstrometryIndexFiles::showEvent(QShowEvent *)
116 {
117  updateIndexDirectoryList();
118 
119 }
120 
121 void OpsAstrometryIndexFiles::updateIndexDirectoryList()
122 {
123  // This is needed because they might have directories stored in the config file.
124  // So we can't just use the options folder list.
125  QStringList astrometryDataDirs = KSUtils::getAstrometryDataDirs();
126 
127  indexLocations->clear();
128  if(astrometryDataDirs.count() > 1)
129  indexLocations->addItem("All Sources");
130  indexLocations->addItems(astrometryDataDirs);
131  slotUpdate();
132 }
133 
134 void OpsAstrometryIndexFiles::addDirectoryToList(QString directory)
135 {
136  QDir dir(directory);
137  if(!dir.exists())
138  return;
139  QString directoryPath = dir.absolutePath();
140 
141  QStringList indexFileDirs = Options::astrometryIndexFolderList();
142  if(indexFileDirs.contains(directoryPath))
143  return;
144  indexFileDirs.append(directoryPath);
145  Options::setAstrometryIndexFolderList(indexFileDirs);
146  updateIndexDirectoryList();
147 }
148 
149 void OpsAstrometryIndexFiles::removeDirectoryFromList(QString directory)
150 {
151  QStringList indexFileDirs = Options::astrometryIndexFolderList();
152  if(indexFileDirs.contains(directory))
153  {
154  indexFileDirs.removeOne(directory);
155  Options::setAstrometryIndexFolderList(indexFileDirs);
156  updateIndexDirectoryList();
157  }
158 }
159 
160 void OpsAstrometryIndexFiles::slotUpdate()
161 {
162  QList<QCheckBox *> checkboxes = findChildren<QCheckBox *>();
163 
164  for (auto &checkBox : checkboxes)
165  {
166  checkBox->setChecked(false);
167  }
168 
169  if(indexLocations->count() == 0)
170  return;
171 
172  double fov_w, fov_h, fov_pixscale;
173 
174  // Values in arcmins. Scale in arcsec per pixel
175  alignModule->getFOVScale(fov_w, fov_h, fov_pixscale);
176 
177  double fov_check = qMax(fov_w, fov_h);
178 
179  FOVOut->setText(QString("%1' x %2'").arg(QString::number(fov_w, 'f', 2), QString::number(fov_h, 'f', 2)));
180 
181  QStringList nameFilter("*.fits");
182 
183  QStringList astrometryDataDirs = Options::astrometryIndexFolderList();
184 
185  bool allDirsSelected = (indexLocations->currentIndex() == 0 && astrometryDataDirs.count() > 1);
186  bool folderIsWriteable;
187 
188  QStringList astrometryDataDirsToIndex;
189 
190  if(allDirsSelected)
191  {
192  folderDetails->setText(i18n("Downloads Disabled, this is not a directory, it is a list of all index files."));
193  folderIsWriteable = false;
194  astrometryDataDirsToIndex = astrometryDataDirs;
195  openIndexFileDirectory->setEnabled(false);
196  }
197  else
198  {
199  QString folderPath = indexLocations->currentText();
200  folderIsWriteable = QFileInfo(folderPath).isWritable();
201  if(folderIsWriteable)
202  folderDetails->setText(i18n("Downloads Enabled, the directory exists and is writeable."));
203  else
204  folderDetails->setText(i18n("Downloads Disabled, directory permissions issue."));
205  if(!QFileInfo(folderPath).exists())
206  folderDetails->setText(i18n("Downloads Disabled, directory does not exist."));
207  astrometryDataDirsToIndex << folderPath;
208  openIndexFileDirectory->setEnabled(true);
209  }
210  folderDetails->setCursorPosition(0);
211 
212  //This loop checks all the folders that are supposed to be checked for the files
213  //It checks the box if it finds them
214  for(QString astrometryDataDir : astrometryDataDirsToIndex)
215  {
216  QDir directory(astrometryDataDir);
217  QStringList indexList = directory.entryList(nameFilter);
218 
219  for (auto &indexName : indexList)
220  {
221  if (fileCountMatches(directory, indexName))
222  {
223  indexName = indexName.replace('-', '_').left(10);
224  QCheckBox *indexCheckBox = findChild<QCheckBox *>(indexName);
225  if (indexCheckBox)
226  indexCheckBox->setChecked(true);
227  }
228  }
229  }
230 
231 
232 
233  for (auto &checkBox : checkboxes)
234  {
235  checkBox->setEnabled(folderIsWriteable);
236  checkBox->setIcon(QIcon(":/icons/astrometry-optional.svg"));
237  checkBox->setToolTip(i18n("Optional"));
238  checkBox->setStyleSheet("");
239  }
240 
241  float last_skymarksize = 2;
242 
243  for (auto &skymarksize : astrometryIndex.keys())
244  {
245  QString indexName1 = "index_41" + astrometryIndex.value(skymarksize);
246  QString indexName2 = "index_42" + astrometryIndex.value(skymarksize);
247  QString indexName3 = "index_52" + astrometryIndex.value(skymarksize);
248  QCheckBox *indexCheckBox1 = findChild<QCheckBox *>(indexName1);
249  QCheckBox *indexCheckBox2 = findChild<QCheckBox *>(indexName2);
250  QCheckBox *indexCheckBox3 = findChild<QCheckBox *>(indexName3);
251  if ((skymarksize >= 0.40 * fov_check && skymarksize <= 0.9 * fov_check) ||
252  (fov_check > last_skymarksize && fov_check < skymarksize))
253  {
254  if (indexCheckBox1)
255  {
256  indexCheckBox1->setIcon(QIcon(":/icons/astrometry-required.svg"));
257  indexCheckBox1->setToolTip(i18n("Required"));
258  }
259  if (indexCheckBox2)
260  {
261  indexCheckBox2->setIcon(QIcon(":/icons/astrometry-required.svg"));
262  indexCheckBox2->setToolTip(i18n("Required"));
263  }
264  if (indexCheckBox3)
265  {
266  indexCheckBox3->setIcon(QIcon(":/icons/astrometry-required.svg"));
267  indexCheckBox3->setToolTip(i18n("Required"));
268  }
269  }
270  else if (skymarksize >= 0.10 * fov_check && skymarksize <= fov_check)
271  {
272  if (indexCheckBox1)
273  {
274  indexCheckBox1->setIcon(QIcon(":/icons/astrometry-recommended.svg"));
275  indexCheckBox1->setToolTip(i18n("Recommended"));
276  }
277  if (indexCheckBox2)
278  {
279  indexCheckBox2->setIcon(QIcon(":/icons/astrometry-recommended.svg"));
280  indexCheckBox2->setToolTip(i18n("Recommended"));
281  }
282  if (indexCheckBox3)
283  {
284  indexCheckBox3->setIcon(QIcon(":/icons/astrometry-recommended.svg"));
285  indexCheckBox3->setToolTip(i18n("Recommended"));
286  }
287  }
288 
289  last_skymarksize = skymarksize;
290  }
291 
292  //This loop goes over all the directories and adds a stylesheet to change the look of the checkbox text
293  //if the File is installed in any directory. Note that this indicator is then used below in the
294  //Index File download function to check if they really want to do install a file that is installed.
295  for(QString astrometryDataDir : astrometryDataDirs)
296  {
297  QDir directory(astrometryDataDir);
298  QStringList indexList = directory.entryList(nameFilter);
299 
300  for (auto &indexName : indexList)
301  {
302  if (fileCountMatches(directory, indexName))
303  {
304  indexName = indexName.replace('-', '_').left(10);
305  QCheckBox *indexCheckBox = findChild<QCheckBox *>(indexName);
306  if (indexCheckBox)
307  indexCheckBox->setStyleSheet("QCheckBox{font-weight: bold; color:green}");
308  }
309  }
310  }
311 }
312 
313 int OpsAstrometryIndexFiles::indexFileCount(QString indexName)
314 {
315  int count = 0;
316  if(indexName.contains("4207") || indexName.contains("4206") || indexName.contains("4205"))
317  count = 12;
318  else if(indexName.contains("4204") || indexName.contains("4203") || indexName.contains("4202")
319  || indexName.contains("4201") || indexName.contains("4200") || indexName.contains("5206")
320  || indexName.contains("5205") || indexName.contains("5204") || indexName.contains("5203")
321  || indexName.contains("5202") || indexName.contains("5201") || indexName.contains("5200"))
322  count = 48;
323  else
324  count = 1;
325  return count;
326 }
327 
328 bool OpsAstrometryIndexFiles::fileCountMatches(QDir directory, QString indexName)
329 {
330  QString indexNameMatch = indexName.left(10) + "*.fits";
331  QStringList list = directory.entryList(QStringList(indexNameMatch));
332  return list.count() == indexFileCount(indexName);
333 }
334 
335 void OpsAstrometryIndexFiles::slotOpenIndexFileDirectory()
336 {
337  if(indexLocations->count() == 0)
338  return;
339  QUrl path = QUrl::fromLocalFile(indexLocations->currentText());
341 }
342 
343 bool OpsAstrometryIndexFiles::astrometryIndicesAreAvailable()
344 {
345  QUrl indexUrl = QUrl(this->indexURL->text());
346  QNetworkReply *response = manager->get(QNetworkRequest(QUrl(indexUrl.url(QUrl::RemovePath))));
347  QTimer timeout(this);
348  timeout.setInterval(5000);
349  timeout.setSingleShot(true);
350  timeout.start();
351  while (!response->isFinished())
352  {
353  if (!timeout.isActive())
354  {
355  response->deleteLater();
356  return false;
357  }
358  qApp->processEvents();
359  }
360 
361  timeout.stop();
362  bool wasSuccessful = (response->error() == QNetworkReply::NoError);
363  response->deleteLater();
364 
365  return wasSuccessful;
366 }
367 
368 void OpsAstrometryIndexFiles::downloadIndexFile(const QString &URL, const QString &fileN, QCheckBox *checkBox,
369  int currentIndex, int maxIndex, double fileSize)
370 {
371  QElapsedTimer downloadTime;
372  downloadTime.start();
373 
374  QString indexString = QString::number(currentIndex);
375  if (currentIndex < 10)
376  indexString = '0' + indexString;
377 
378  QString indexSeriesName = checkBox->text().remove('&');
379  QProgressBar *indexDownloadProgress = findChild<QProgressBar *>(indexSeriesName.replace('-', '_').left(10) + "_progress");
380  QLabel *indexDownloadInfo = findChild<QLabel *>(indexSeriesName.replace('-', '_').left(10) + "_info");
381  QPushButton *indexDownloadCancel = findChild<QPushButton *>(indexSeriesName.replace('-', '_').left(10) + "_cancel");
382  QLabel *indexDownloadPerc = findChild<QLabel *>(indexSeriesName.replace('-', '_').left(10) + "_perc");
383 
384  setDownloadInfoVisible(indexSeriesName, checkBox, true);
385 
386  if(indexDownloadInfo)
387  {
388  if (indexDownloadProgress && maxIndex > 0)
389  indexDownloadProgress->setValue(currentIndex * 100 / maxIndex);
390  indexDownloadInfo->setText("(" + QString::number(currentIndex) + '/' + QString::number(maxIndex + 1) + ") ");
391  }
392 
393  QString indexURL = URL;
394 
395  indexURL.replace('*', indexString);
396 
397  QNetworkReply *response = manager->get(QNetworkRequest(QUrl(indexURL)));
398 
399  //Shut it down after too much time elapses.
400  //If the filesize is less than 4 MB, it sets the timeout for 1 minute or 60000 ms.
401  //If it's larger, it assumes a bad download rate of 1 Mbps (100 bytes/ms)
402  //and the calculation estimates the time in milliseconds it would take to download.
403  int timeout = 60000;
404  if(fileSize > 4000000)
405  timeout = fileSize / downloadSpeed;
406  //qDebug()<<"Filesize: "<< fileSize << ", timeout: " << timeout;
407 
408  QMetaObject::Connection *cancelConnection = new QMetaObject::Connection();
409  QMetaObject::Connection *replyConnection = new QMetaObject::Connection();
410  QMetaObject::Connection *percentConnection = new QMetaObject::Connection();
411 
412  if(indexDownloadPerc)
413  {
414  *percentConnection = connect(response, &QNetworkReply::downloadProgress,
415  [ = ](qint64 bytesReceived, qint64 bytesTotal)
416  {
417  if (indexDownloadProgress)
418  {
419  indexDownloadProgress->setValue(bytesReceived);
420  indexDownloadProgress->setMaximum(bytesTotal);
421  }
422  indexDownloadPerc->setText(QString::number(bytesReceived * 100 / bytesTotal) + '%');
423  });
424 
425  }
426 
427  timeoutTimer.disconnect();
428  connect(&timeoutTimer, &QTimer::timeout, [&]()
429  {
430  KSNotification::error(
431  i18n("Download Timed out. Either the network is not fast enough, the file is not accessible, or you are not connected."));
432  disconnectDownload(cancelConnection, replyConnection, percentConnection);
433  if(response)
434  {
435  response->abort();
436  response->deleteLater();
437  }
438  setDownloadInfoVisible(indexSeriesName, checkBox, false);
439  });
440  timeoutTimer.start(timeout);
441 
442  *cancelConnection = connect(indexDownloadCancel, &QPushButton::clicked,
443  [ = ]()
444  {
445  qDebug() << Q_FUNC_INFO << "Download Cancelled.";
446  timeoutTimer.stop();
447  disconnectDownload(cancelConnection, replyConnection, percentConnection);
448  if(response)
449  {
450  response->abort();
451  response->deleteLater();
452  }
453  setDownloadInfoVisible(indexSeriesName, checkBox, false);
454  });
455 
456  *replyConnection = connect(response, &QNetworkReply::finished, this,
457  [ = ]()
458  {
459  timeoutTimer.stop();
460  if(response)
461  {
462  disconnectDownload(cancelConnection, replyConnection, percentConnection);
463  setDownloadInfoVisible(indexSeriesName, checkBox, false);
464  response->deleteLater();
465  if (response->error() != QNetworkReply::NoError)
466  return;
467 
468  QByteArray responseData = response->readAll();
469  QString indexFileN = fileN;
470 
471  indexFileN.replace('*', indexString);
472 
473  QFile file(indexFileN);
474  if (QFileInfo(QFileInfo(file).path()).isWritable())
475  {
476  if (!file.open(QIODevice::WriteOnly))
477  {
478  KSNotification::error(i18n("File Write Error"));
479  slotUpdate();
480  return;
481  }
482  else
483  {
484  file.write(responseData.data(), responseData.size());
485  file.close();
486  int downloadedFileSize = QFileInfo(file).size();
487  int dtime = downloadTime.elapsed();
488  actualdownloadSpeed = (actualdownloadSpeed + (downloadedFileSize / dtime)) / 2;
489  qDebug() << Q_FUNC_INFO << "Filesize: " << downloadedFileSize << ", time: " << dtime << ", inst speed: " << downloadedFileSize / dtime <<
490  ", averaged speed: " << actualdownloadSpeed;
491 
492  }
493  }
494  else
495  {
496  KSNotification::error(i18n("Astrometry Folder Permissions Error"));
497  }
498 
499  if (currentIndex == maxIndex)
500  {
501  slotUpdate();
502  }
503  else
504  downloadIndexFile(URL, fileN, checkBox, currentIndex + 1, maxIndex, fileSize);
505  }
506  });
507 }
508 
509 void OpsAstrometryIndexFiles::setDownloadInfoVisible(QString indexSeriesName, QCheckBox *checkBox, bool set)
510 {
511  Q_UNUSED(checkBox);
512 
513  QProgressBar *indexDownloadProgress = findChild<QProgressBar *>(indexSeriesName.replace('-', '_').left(10) + "_progress");
514  QLabel *indexDownloadInfo = findChild<QLabel *>(indexSeriesName.replace('-', '_').left(10) + "_info");
515  QPushButton *indexDownloadCancel = findChild<QPushButton *>(indexSeriesName.replace('-', '_').left(10) + "_cancel");
516  QLabel *indexDownloadPerc = findChild<QLabel *>(indexSeriesName.replace('-', '_').left(10) + "_perc");
517  if (indexDownloadProgress)
518  indexDownloadProgress->setVisible(set);
519  if (indexDownloadInfo)
520  indexDownloadInfo->setVisible(set);
521  if (indexDownloadCancel)
522  indexDownloadCancel->setVisible(set);
523  if (indexDownloadPerc)
524  indexDownloadPerc->setVisible(set);
525 }
526 void OpsAstrometryIndexFiles::disconnectDownload(QMetaObject::Connection *cancelConnection,
527  QMetaObject::Connection *replyConnection, QMetaObject::Connection *percentConnection)
528 {
529  if(cancelConnection)
530  disconnect(*cancelConnection);
531  if(replyConnection)
532  disconnect(*replyConnection);
533  if(percentConnection)
534  disconnect(*percentConnection);
535 }
536 
537 void OpsAstrometryIndexFiles::downloadOrDeleteIndexFiles(bool checked)
538 {
539  QCheckBox *checkBox = qobject_cast<QCheckBox *>(QObject::sender());
540 
541  if (indexLocations->count() == 0)
542  return;
543 
544  QString astrometryDataDir = indexLocations->currentText();
545  if(!QFileInfo(astrometryDataDir).exists())
546  {
547  KSNotification::sorry(
548  i18n("The selected Index File directory does not exist. Please either create it or choose another."));
549  }
550 
551  if (checkBox)
552  {
553  QString indexSeriesName = checkBox->text().remove('&');
554  QString filePath = astrometryDataDir + '/' + indexSeriesName;
555  QString fileNumString = indexSeriesName.mid(8, 2);
556 
557  if (checked)
558  {
559  if(!checkBox->styleSheet().isEmpty()) //This means that the checkbox has a stylesheet so the index file was installed someplace.
560  {
561  if (KMessageBox::Cancel == KMessageBox::warningContinueCancel(
562  nullptr, i18n("The file %1 already exists in another directory. Are you sure you want to download it to this directory as well?",
563  indexSeriesName),
564  i18n("Install File(s)"), KStandardGuiItem::cont(),
565  KStandardGuiItem::cancel(), "install_index_files_warning"))
566  {
567  slotUpdate();
568  return;
569  }
570  }
571  checkBox->setChecked(!checked);
572  if (astrometryIndicesAreAvailable())
573  {
574  QString BASE_URL;
575  QString URL;
576 
577  if (this->indexURL->text().endsWith("/"))
578  {
579  BASE_URL = this->indexURL->text();
580  }
581  else
582  {
583  BASE_URL = this->indexURL->text() + "/";
584  }
585 
586  if (indexSeriesName.startsWith(QLatin1String("index-41")))
587  URL = BASE_URL + "4100/" + indexSeriesName;
588  else if (indexSeriesName.startsWith(QLatin1String("index-42")))
589  URL = BASE_URL + "4200/" + indexSeriesName;
590  else if (indexSeriesName.startsWith(QLatin1String("index-52")))
591  URL = "https://portal.nersc.gov/project/cosmo/temp/dstn/index-5200/LITE/" + indexSeriesName;
592 
593  int maxIndex = indexFileCount(indexSeriesName) - 1;
594 
595  double fileSize = 1E11 * qPow(astrometryIndex.key(fileNumString),
596  -1.909); //This estimates the file size based on skymark size obtained from the index number.
597  if(maxIndex != 0)
598  fileSize /= maxIndex; //FileSize is divided between multiple files for some index series.
599  downloadIndexFile(URL, filePath, checkBox, 0, maxIndex, fileSize);
600  }
601  else
602  {
603  KSNotification::sorry(i18n("Could not contact Astrometry Index Server."));
604  }
605  }
606  else
607  {
608  if (KMessageBox::Continue == KMessageBox::warningContinueCancel(
609  nullptr, i18n("Are you sure you want to delete these index files? %1", indexSeriesName),
610  i18n("Delete File(s)"), KStandardGuiItem::cont(),
611  KStandardGuiItem::cancel(), "delete_index_files_warning"))
612  {
613  if (QFileInfo(astrometryDataDir).isWritable())
614  {
615  QStringList nameFilter("*.fits");
616  QDir directory(astrometryDataDir);
617  QStringList indexList = directory.entryList(nameFilter);
618  for (auto &fileName : indexList)
619  {
620  if (fileName.contains(indexSeriesName.left(10)))
621  {
622  if (!directory.remove(fileName))
623  {
624  KSNotification::error(i18n("File Delete Error"));
625  slotUpdate();
626  return;
627  }
628  slotUpdate();
629  }
630  }
631  }
632  else
633  {
634  KSNotification::error(i18n("Astrometry Folder Permissions Error"));
635  slotUpdate();
636  }
637  }
638  }
639  }
640 }
641 }
void append(const T &value)
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const const
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
void setText(const QString &)
QString number(int n, int base)
ButtonCode warningContinueCancel(QWidget *parent, const QString &text, const QString &title=QString(), const KGuiItem &buttonContinue=KStandardGuiItem::cont(), const KGuiItem &buttonCancel=KStandardGuiItem::cancel(), const QString &dontAskAgainName=QString(), Options options=Notify)
Ekos is an advanced Astrophotography tool for Linux. It is based on a modular extensible framework to...
Definition: align.cpp:70
int count(const T &value) const const
QNetworkReply::NetworkError error() const const
bool contains(const QString &str, Qt::CaseSensitivity cs) const const
QString url(QUrl::FormattingOptions options) const const
void clicked(bool checked)
QObject * sender() const const
void setStyleSheet(const QString &styleSheet)
bool openUrl(const QUrl &url)
QString homePath()
void setChecked(bool)
KIOFILEWIDGETS_EXPORT QStringList list(const QString &fileClass)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
KGuiItem cancel()
virtual void setVisible(bool visible)
void deleteLater()
QString i18n(const char *text, const TYPE &arg...)
void setMaximum(int maximum)
bool removeOne(const T &value)
void textChanged(const QString &text)
void timeout()
bool isEmpty() const const
QUrl fromLocalFile(const QString &localFile)
qint64 size() const const
bool remove(const QString &fileName)
This is the main window for KStars. In addition to the GUI elements, the class contains the program c...
Definition: kstars.h:92
qint64 elapsed() const const
void setupUi(QWidget *widget)
QString & replace(int position, int n, QChar after)
QString label(StandardShortcut id)
bool isFinished() const const
void setIcon(const QIcon &icon)
KIOFILEWIDGETS_EXPORT QString dir(const QString &fileClass)
void setToolTip(const QString &)
QString left(int n) const const
bool isWritable() const const
void currentIndexChanged(int index)
KGuiItem cont()
int size() const const
QByteArray readAll()
QStringList entryList(QDir::Filters filters, QDir::SortFlags sort) const const
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
void setValue(int value)
QString getExistingDirectory(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options)
QString mid(int position, int n) const const
QObject * parent() const const
char * data()
virtual void abort()=0
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Thu Aug 11 2022 04:00:02 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.