File indexing completed on 2024-04-28 15:09:03

0001 
0002 #include "opsastrometryindexfiles.h"
0003 
0004 #include "align.h"
0005 #include "kstars.h"
0006 #include "ksutils.h"
0007 #include "Options.h"
0008 #include "ksnotification.h"
0009 
0010 #include <KConfigDialog>
0011 #include <KMessageBox>
0012 
0013 namespace Ekos
0014 {
0015 OpsAstrometryIndexFiles::OpsAstrometryIndexFiles(Align *parent) : QDialog(KStars::Instance())
0016 {
0017     setupUi(this);
0018 
0019     downloadSpeed       = 100;
0020     actualdownloadSpeed = downloadSpeed;
0021     alignModule         = parent;
0022     manager             = new QNetworkAccessManager();
0023 
0024     indexURL->setText("http://broiler.astrometry.net/~dstn/");
0025 
0026     //Get a pointer to the KConfigDialog
0027     // m_ConfigDialog = KConfigDialog::exists( "alignsettings" );
0028     connect(openIndexFileDirectory, SIGNAL(clicked()), this, SLOT(slotOpenIndexFileDirectory()));
0029     connect(indexURL, &QLineEdit::textChanged, [&]()
0030     {
0031         indexURL->text();
0032     });
0033 
0034 
0035     astrometryIndex[2.8]  = "00";
0036     astrometryIndex[4.0]  = "01";
0037     astrometryIndex[5.6]  = "02";
0038     astrometryIndex[8]    = "03";
0039     astrometryIndex[11]   = "04";
0040     astrometryIndex[16]   = "05";
0041     astrometryIndex[22]   = "06";
0042     astrometryIndex[30]   = "07";
0043     astrometryIndex[42]   = "08";
0044     astrometryIndex[60]   = "09";
0045     astrometryIndex[85]   = "10";
0046     astrometryIndex[120]  = "11";
0047     astrometryIndex[170]  = "12";
0048     astrometryIndex[240]  = "13";
0049     astrometryIndex[340]  = "14";
0050     astrometryIndex[480]  = "15";
0051     astrometryIndex[680]  = "16";
0052     astrometryIndex[1000] = "17";
0053     astrometryIndex[1400] = "18";
0054     astrometryIndex[2000] = "19";
0055 
0056     QList<QCheckBox *> checkboxes = findChildren<QCheckBox *>();
0057 
0058     connect(indexLocations, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
0059             &OpsAstrometryIndexFiles::slotUpdate);
0060 
0061     for (auto &checkBox : checkboxes)
0062     {
0063         connect(checkBox, &QCheckBox::clicked, this, &OpsAstrometryIndexFiles::downloadOrDeleteIndexFiles);
0064     }
0065 
0066     QList<QProgressBar *> progressBars = findChildren<QProgressBar *>();
0067     QList<QLabel *> qLabels = findChildren<QLabel *>();
0068     QList<QPushButton *> qButtons = findChildren<QPushButton *>();
0069 
0070     for (auto &bar : progressBars)
0071     {
0072         if(bar->objectName().contains("progress"))
0073         {
0074             bar->setVisible(false);
0075             bar->setTextVisible(false);
0076         }
0077     }
0078 
0079     for (auto &button : qButtons)
0080     {
0081         if(button->objectName().contains("cancel"))
0082         {
0083             button->setVisible(false);
0084         }
0085     }
0086 
0087     for (QLabel * label : qLabels)
0088     {
0089         if(label->text().contains("info") || label->text().contains("perc"))
0090         {
0091             label->setVisible(false);
0092         }
0093     }
0094 
0095     connect(addIndexFileDirectory, &QAbstractButton::clicked, this, [this]()
0096     {
0097         QString dir = QFileDialog::getExistingDirectory(this, "Load Index File Directory",
0098                       QDir::homePath(),
0099                       QFileDialog::ShowDirsOnly
0100                       | QFileDialog::DontResolveSymlinks);
0101         if (dir.isEmpty())
0102             return;
0103         addDirectoryToList(dir);
0104     });
0105     connect(removeIndexFileDirectory, &QAbstractButton::clicked, this, [this]()
0106     {
0107         if(indexLocations->currentIndex() != 0)
0108             removeDirectoryFromList(indexLocations->currentText());
0109     });
0110 
0111 
0112 }
0113 
0114 void OpsAstrometryIndexFiles::showEvent(QShowEvent *)
0115 {
0116     updateIndexDirectoryList();
0117 
0118 }
0119 
0120 void OpsAstrometryIndexFiles::updateIndexDirectoryList()
0121 {
0122     // This is needed because they might have directories stored in the config file.
0123     // So we can't just use the options folder list.
0124     QStringList astrometryDataDirs = KSUtils::getAstrometryDataDirs();
0125 
0126     indexLocations->clear();
0127     if(astrometryDataDirs.count() > 1)
0128         indexLocations->addItem("All Sources");
0129     indexLocations->addItems(astrometryDataDirs);
0130     slotUpdate();
0131 }
0132 
0133 void OpsAstrometryIndexFiles::addDirectoryToList(QString directory)
0134 {
0135     QDir dir(directory);
0136     if(!dir.exists())
0137         return;
0138     QString directoryPath = dir.absolutePath();
0139 
0140     QStringList indexFileDirs = Options::astrometryIndexFolderList();
0141     if(indexFileDirs.contains(directoryPath))
0142         return;
0143     indexFileDirs.append(directoryPath);
0144     Options::setAstrometryIndexFolderList(indexFileDirs);
0145     updateIndexDirectoryList();
0146 }
0147 
0148 void OpsAstrometryIndexFiles::removeDirectoryFromList(QString directory)
0149 {
0150     QStringList indexFileDirs = Options::astrometryIndexFolderList();
0151     if(indexFileDirs.contains(directory))
0152     {
0153         indexFileDirs.removeOne(directory);
0154         Options::setAstrometryIndexFolderList(indexFileDirs);
0155         updateIndexDirectoryList();
0156     }
0157 }
0158 
0159 void OpsAstrometryIndexFiles::slotUpdate()
0160 {
0161     QList<QCheckBox *> checkboxes = findChildren<QCheckBox *>();
0162 
0163     for (auto &checkBox : checkboxes)
0164     {
0165         checkBox->setChecked(false);
0166     }
0167 
0168     if(indexLocations->count() == 0)
0169         return;
0170 
0171     double fov_w, fov_h, fov_pixscale;
0172 
0173     // Values in arcmins. Scale in arcsec per pixel
0174     alignModule->getFOVScale(fov_w, fov_h, fov_pixscale);
0175 
0176     double fov_check = qMax(fov_w, fov_h);
0177 
0178     FOVOut->setText(QString("%1' x %2'").arg(QString::number(fov_w, 'f', 2), QString::number(fov_h, 'f', 2)));
0179 
0180     QStringList nameFilter("*.fits");
0181 
0182     QStringList astrometryDataDirs = Options::astrometryIndexFolderList();
0183 
0184     bool allDirsSelected = (indexLocations->currentIndex() == 0 && astrometryDataDirs.count() > 1);
0185     bool folderIsWriteable;
0186 
0187     QStringList astrometryDataDirsToIndex;
0188 
0189     if(allDirsSelected)
0190     {
0191         folderDetails->setText(i18n("Downloads Disabled, this is not a directory, it is a list of all index files."));
0192         folderIsWriteable = false;
0193         astrometryDataDirsToIndex = astrometryDataDirs;
0194         openIndexFileDirectory->setEnabled(false);
0195     }
0196     else
0197     {
0198         QString folderPath = indexLocations->currentText();
0199         folderIsWriteable = QFileInfo(folderPath).isWritable();
0200         if(folderIsWriteable)
0201             folderDetails->setText(i18n("Downloads Enabled, the directory exists and is writeable."));
0202         else
0203             folderDetails->setText(i18n("Downloads Disabled, directory permissions issue."));
0204         if(!QFileInfo::exists(folderPath))
0205             folderDetails->setText(i18n("Downloads Disabled, directory does not exist."));
0206         astrometryDataDirsToIndex << folderPath;
0207         openIndexFileDirectory->setEnabled(true);
0208     }
0209     folderDetails->setCursorPosition(0);
0210 
0211     //This loop checks all the folders that are supposed to be checked for the files
0212     //It checks the box if it finds them
0213     for(auto &astrometryDataDir : astrometryDataDirsToIndex)
0214     {
0215         QDir directory(astrometryDataDir);
0216         QStringList indexList = directory.entryList(nameFilter);
0217 
0218         for (auto &indexName : indexList)
0219         {
0220             if (fileCountMatches(directory, indexName))
0221             {
0222                 indexName                = indexName.replace('-', '_').left(10);
0223                 QCheckBox *indexCheckBox = findChild<QCheckBox *>(indexName);
0224                 if (indexCheckBox)
0225                     indexCheckBox->setChecked(true);
0226             }
0227         }
0228     }
0229 
0230     for (auto &checkBox : checkboxes)
0231     {
0232         checkBox->setEnabled(folderIsWriteable);
0233         checkBox->setIcon(QIcon(":/icons/astrometry-optional.svg"));
0234         checkBox->setToolTip(i18n("Optional"));
0235         checkBox->setStyleSheet("");
0236     }
0237 
0238     float last_skymarksize = 2;
0239 
0240     for (auto &skymarksize : astrometryIndex.keys())
0241     {
0242         QString indexName1        = "index_41" + astrometryIndex.value(skymarksize);
0243         QString indexName2        = "index_42" + astrometryIndex.value(skymarksize);
0244         QString indexName3        = "index_52" + astrometryIndex.value(skymarksize);
0245         QCheckBox *indexCheckBox1 = findChild<QCheckBox *>(indexName1);
0246         QCheckBox *indexCheckBox2 = findChild<QCheckBox *>(indexName2);
0247         QCheckBox *indexCheckBox3 = findChild<QCheckBox *>(indexName3);
0248         if ((skymarksize >= 0.40 * fov_check && skymarksize <= 0.9 * fov_check) ||
0249                 (fov_check > last_skymarksize && fov_check < skymarksize))
0250         {
0251             if (indexCheckBox1)
0252             {
0253                 indexCheckBox1->setIcon(QIcon(":/icons/astrometry-required.svg"));
0254                 indexCheckBox1->setToolTip(i18n("Required"));
0255             }
0256             if (indexCheckBox2)
0257             {
0258                 indexCheckBox2->setIcon(QIcon(":/icons/astrometry-required.svg"));
0259                 indexCheckBox2->setToolTip(i18n("Required"));
0260             }
0261             if (indexCheckBox3)
0262             {
0263                 indexCheckBox3->setIcon(QIcon(":/icons/astrometry-required.svg"));
0264                 indexCheckBox3->setToolTip(i18n("Required"));
0265             }
0266         }
0267         else if (skymarksize >= 0.10 * fov_check && skymarksize <= fov_check)
0268         {
0269             if (indexCheckBox1)
0270             {
0271                 indexCheckBox1->setIcon(QIcon(":/icons/astrometry-recommended.svg"));
0272                 indexCheckBox1->setToolTip(i18n("Recommended"));
0273             }
0274             if (indexCheckBox2)
0275             {
0276                 indexCheckBox2->setIcon(QIcon(":/icons/astrometry-recommended.svg"));
0277                 indexCheckBox2->setToolTip(i18n("Recommended"));
0278             }
0279             if (indexCheckBox3)
0280             {
0281                 indexCheckBox3->setIcon(QIcon(":/icons/astrometry-recommended.svg"));
0282                 indexCheckBox3->setToolTip(i18n("Recommended"));
0283             }
0284         }
0285 
0286         last_skymarksize = skymarksize;
0287     }
0288 
0289     //This loop goes over all the directories and adds a stylesheet to change the look of the checkbox text
0290     //if the File is installed in any directory.  Note that this indicator is then used below in the
0291     //Index File download function to check if they really want to do install a file that is installed.
0292     for(QString astrometryDataDir : astrometryDataDirs)
0293     {
0294         QDir directory(astrometryDataDir);
0295         QStringList indexList = directory.entryList(nameFilter);
0296 
0297         for (auto &indexName : indexList)
0298         {
0299             if (fileCountMatches(directory, indexName))
0300             {
0301                 indexName                = indexName.replace('-', '_').left(10);
0302                 QCheckBox *indexCheckBox = findChild<QCheckBox *>(indexName);
0303                 if (indexCheckBox)
0304                     indexCheckBox->setStyleSheet("QCheckBox{font-weight: bold; color:green}");
0305             }
0306         }
0307     }
0308 }
0309 
0310 int OpsAstrometryIndexFiles::indexFileCount(QString indexName)
0311 {
0312     int count = 0;
0313     if(indexName.contains("4207") || indexName.contains("4206") || indexName.contains("4205"))
0314         count = 12;
0315     else if(indexName.contains("4204") || indexName.contains("4203") || indexName.contains("4202")
0316             || indexName.contains("4201") || indexName.contains("4200") || indexName.contains("5206")
0317             || indexName.contains("5205") || indexName.contains("5204") || indexName.contains("5203")
0318             || indexName.contains("5202") || indexName.contains("5201") || indexName.contains("5200"))
0319         count = 48;
0320     else
0321         count = 1;
0322     return count;
0323 }
0324 
0325 bool OpsAstrometryIndexFiles::fileCountMatches(QDir directory, QString indexName)
0326 {
0327     QString indexNameMatch = indexName.left(10) + "*.fits";
0328     QStringList list = directory.entryList(QStringList(indexNameMatch));
0329     return list.count() == indexFileCount(indexName);
0330 }
0331 
0332 void OpsAstrometryIndexFiles::slotOpenIndexFileDirectory()
0333 {
0334     if(indexLocations->count() == 0)
0335         return;
0336     QUrl path = QUrl::fromLocalFile(indexLocations->currentText());
0337     QDesktopServices::openUrl(path);
0338 }
0339 
0340 bool OpsAstrometryIndexFiles::astrometryIndicesAreAvailable()
0341 {
0342     QUrl indexUrl = QUrl(this->indexURL->text());
0343     QNetworkReply *response = manager->get(QNetworkRequest(QUrl(indexUrl.url(QUrl::RemovePath))));
0344     QTimer timeout(this);
0345     timeout.setInterval(5000);
0346     timeout.setSingleShot(true);
0347     timeout.start();
0348     while (!response->isFinished())
0349     {
0350         if (!timeout.isActive())
0351         {
0352             response->deleteLater();
0353             return false;
0354         }
0355         qApp->processEvents();
0356     }
0357 
0358     timeout.stop();
0359     bool wasSuccessful = (response->error() == QNetworkReply::NoError);
0360     response->deleteLater();
0361 
0362     return wasSuccessful;
0363 }
0364 
0365 void OpsAstrometryIndexFiles::downloadIndexFile(const QString &URL, const QString &fileN, QCheckBox *checkBox,
0366         int currentIndex, int maxIndex, double fileSize)
0367 {
0368     QElapsedTimer downloadTime;
0369     downloadTime.start();
0370 
0371     QString indexString = QString::number(currentIndex);
0372     if (currentIndex < 10)
0373         indexString = '0' + indexString;
0374 
0375     QString indexSeriesName             = checkBox->text().remove('&');
0376     QProgressBar *indexDownloadProgress = findChild<QProgressBar *>(indexSeriesName.replace('-', '_').left(10) + "_progress");
0377     QLabel *indexDownloadInfo           = findChild<QLabel *>(indexSeriesName.replace('-', '_').left(10) + "_info");
0378     QPushButton *indexDownloadCancel    = findChild<QPushButton *>(indexSeriesName.replace('-', '_').left(10) + "_cancel");
0379     QLabel *indexDownloadPerc    = findChild<QLabel *>(indexSeriesName.replace('-', '_').left(10) + "_perc");
0380 
0381     setDownloadInfoVisible(indexSeriesName, checkBox, true);
0382 
0383     if(indexDownloadInfo)
0384     {
0385         if (indexDownloadProgress && maxIndex > 0)
0386             indexDownloadProgress->setValue(currentIndex * 100 / maxIndex);
0387         indexDownloadInfo->setText("(" + QString::number(currentIndex) + '/' + QString::number(maxIndex + 1) + ") ");
0388     }
0389 
0390     QString indexURL = URL;
0391 
0392     indexURL.replace('*', indexString);
0393 
0394     QNetworkReply *response = manager->get(QNetworkRequest(QUrl(indexURL)));
0395 
0396     //Shut it down after too much time elapses.
0397     //If the filesize is less  than 4 MB, it sets the timeout for 1 minute or 60000 ms.
0398     //If it's larger, it assumes a bad download rate of 1 Mbps (100 bytes/ms)
0399     //and the calculation estimates the time in milliseconds it would take to download.
0400     int timeout = 60000;
0401     if(fileSize > 4000000)
0402         timeout = fileSize / downloadSpeed;
0403     //qDebug()<<"Filesize: "<< fileSize << ", timeout: " << timeout;
0404 
0405     QMetaObject::Connection *cancelConnection = new QMetaObject::Connection();
0406     QMetaObject::Connection *replyConnection = new QMetaObject::Connection();
0407     QMetaObject::Connection *percentConnection = new QMetaObject::Connection();
0408 
0409     if(indexDownloadPerc)
0410     {
0411         *percentConnection = connect(response, &QNetworkReply::downloadProgress,
0412                                      [ = ](qint64 bytesReceived, qint64 bytesTotal)
0413         {
0414             if (indexDownloadProgress)
0415             {
0416                 indexDownloadProgress->setValue(bytesReceived);
0417                 indexDownloadProgress->setMaximum(bytesTotal);
0418             }
0419             indexDownloadPerc->setText(QString::number(bytesReceived * 100 / bytesTotal) + '%');
0420         });
0421 
0422     }
0423 
0424     timeoutTimer.disconnect();
0425     connect(&timeoutTimer, &QTimer::timeout, this, [&]()
0426     {
0427         KSNotification::error(
0428             i18n("Download Timed out.  Either the network is not fast enough, the file is not accessible, or you are not connected."));
0429         disconnectDownload(cancelConnection, replyConnection, percentConnection);
0430         if(response)
0431         {
0432             response->abort();
0433             response->deleteLater();
0434         }
0435         setDownloadInfoVisible(indexSeriesName, checkBox, false);
0436     });
0437     timeoutTimer.start(timeout);
0438 
0439     *cancelConnection = connect(indexDownloadCancel, &QPushButton::clicked,
0440                                 [ = ]()
0441     {
0442         qDebug() << Q_FUNC_INFO << "Download Cancelled.";
0443         timeoutTimer.stop();
0444         disconnectDownload(cancelConnection, replyConnection, percentConnection);
0445         if(response)
0446         {
0447             response->abort();
0448             response->deleteLater();
0449         }
0450         setDownloadInfoVisible(indexSeriesName, checkBox, false);
0451     });
0452 
0453     *replyConnection = connect(response, &QNetworkReply::finished, this,
0454                                [ = ]()
0455     {
0456         timeoutTimer.stop();
0457         if(response)
0458         {
0459             disconnectDownload(cancelConnection, replyConnection, percentConnection);
0460             setDownloadInfoVisible(indexSeriesName, checkBox, false);
0461             response->deleteLater();
0462             if (response->error() != QNetworkReply::NoError)
0463                 return;
0464 
0465             QByteArray responseData = response->readAll();
0466             QString indexFileN      = fileN;
0467 
0468             indexFileN.replace('*', indexString);
0469 
0470             QFile file(indexFileN);
0471             if (QFileInfo(QFileInfo(file).path()).isWritable())
0472             {
0473                 if (!file.open(QIODevice::WriteOnly))
0474                 {
0475                     KSNotification::error(i18n("File Write Error"));
0476                     slotUpdate();
0477                     return;
0478                 }
0479                 else
0480                 {
0481                     file.write(responseData.data(), responseData.size());
0482                     file.close();
0483                     int downloadedFileSize = QFileInfo(file).size();
0484                     int dtime = downloadTime.elapsed();
0485                     actualdownloadSpeed = (actualdownloadSpeed + (downloadedFileSize / dtime)) / 2;
0486                     qDebug() << Q_FUNC_INFO << "Filesize: " << downloadedFileSize << ", time: " << dtime << ", inst speed: " <<
0487                              downloadedFileSize / dtime <<
0488                              ", averaged speed: " << actualdownloadSpeed;
0489 
0490                 }
0491             }
0492             else
0493             {
0494                 KSNotification::error(i18n("Astrometry Folder Permissions Error"));
0495             }
0496 
0497             if (currentIndex == maxIndex)
0498             {
0499                 slotUpdate();
0500             }
0501             else
0502                 downloadIndexFile(URL, fileN, checkBox, currentIndex + 1, maxIndex, fileSize);
0503         }
0504     });
0505 }
0506 
0507 void OpsAstrometryIndexFiles::setDownloadInfoVisible(QString indexSeriesName, QCheckBox *checkBox, bool set)
0508 {
0509     Q_UNUSED(checkBox);
0510 
0511     QProgressBar *indexDownloadProgress = findChild<QProgressBar *>(indexSeriesName.replace('-', '_').left(10) + "_progress");
0512     QLabel *indexDownloadInfo           = findChild<QLabel *>(indexSeriesName.replace('-', '_').left(10) + "_info");
0513     QPushButton *indexDownloadCancel    = findChild<QPushButton *>(indexSeriesName.replace('-', '_').left(10) + "_cancel");
0514     QLabel *indexDownloadPerc          = findChild<QLabel *>(indexSeriesName.replace('-', '_').left(10) + "_perc");
0515     if (indexDownloadProgress)
0516         indexDownloadProgress->setVisible(set);
0517     if (indexDownloadInfo)
0518         indexDownloadInfo->setVisible(set);
0519     if (indexDownloadCancel)
0520         indexDownloadCancel->setVisible(set);
0521     if (indexDownloadPerc)
0522         indexDownloadPerc->setVisible(set);
0523 }
0524 void OpsAstrometryIndexFiles::disconnectDownload(QMetaObject::Connection *cancelConnection,
0525         QMetaObject::Connection *replyConnection, QMetaObject::Connection *percentConnection)
0526 {
0527     if(cancelConnection)
0528         disconnect(*cancelConnection);
0529     if(replyConnection)
0530         disconnect(*replyConnection);
0531     if(percentConnection)
0532         disconnect(*percentConnection);
0533 }
0534 
0535 void OpsAstrometryIndexFiles::downloadOrDeleteIndexFiles(bool checked)
0536 {
0537     QCheckBox *checkBox = qobject_cast<QCheckBox *>(QObject::sender());
0538 
0539     if (indexLocations->count() == 0)
0540         return;
0541 
0542     QString astrometryDataDir = indexLocations->currentText();
0543     if(!QFileInfo::exists(astrometryDataDir))
0544     {
0545         KSNotification::sorry(
0546             i18n("The selected Index File directory does not exist.  Please either create it or choose another."));
0547     }
0548 
0549     if (checkBox)
0550     {
0551         QString indexSeriesName = checkBox->text().remove('&');
0552         QString filePath        = astrometryDataDir + '/' + indexSeriesName;
0553         QString fileNumString   = indexSeriesName.mid(8, 2);
0554 
0555         if (checked)
0556         {
0557             if(!checkBox->styleSheet().isEmpty()) //This means that the checkbox has a stylesheet so the index file was installed someplace.
0558             {
0559                 if (KMessageBox::Cancel == KMessageBox::warningContinueCancel(
0560                             nullptr, i18n("The file %1 already exists in another directory.  Are you sure you want to download it to this directory as well?",
0561                                           indexSeriesName),
0562                             i18n("Install File(s)"), KStandardGuiItem::cont(),
0563                             KStandardGuiItem::cancel(), "install_index_files_warning"))
0564                 {
0565                     slotUpdate();
0566                     return;
0567                 }
0568             }
0569             checkBox->setChecked(!checked);
0570             if (astrometryIndicesAreAvailable())
0571             {
0572                 QString BASE_URL;
0573                 QString URL;
0574 
0575                 if (this->indexURL->text().endsWith("/"))
0576                 {
0577                     BASE_URL = this->indexURL->text();
0578                 }
0579                 else
0580                 {
0581                     BASE_URL = this->indexURL->text() + "/";
0582                 }
0583 
0584                 if (indexSeriesName.startsWith(QLatin1String("index-41")))
0585                     URL = BASE_URL + "4100/" + indexSeriesName;
0586                 else if (indexSeriesName.startsWith(QLatin1String("index-42")))
0587                     URL = BASE_URL + "4200/" + indexSeriesName;
0588                 else if (indexSeriesName.startsWith(QLatin1String("index-52")))
0589                     URL = "https://portal.nersc.gov/project/cosmo/temp/dstn/index-5200/LITE/" + indexSeriesName;
0590 
0591                 int maxIndex = indexFileCount(indexSeriesName) - 1;
0592 
0593                 double fileSize = 1E11 * qPow(astrometryIndex.key(fileNumString),
0594                                               -1.909); //This estimates the file size based on skymark size obtained from the index number.
0595                 if(maxIndex != 0)
0596                     fileSize /= maxIndex; //FileSize is divided between multiple files for some index series.
0597                 downloadIndexFile(URL, filePath, checkBox, 0, maxIndex, fileSize);
0598             }
0599             else
0600             {
0601                 KSNotification::sorry(i18n("Could not contact Astrometry Index Server."));
0602             }
0603         }
0604         else
0605         {
0606             if (KMessageBox::Continue == KMessageBox::warningContinueCancel(
0607                         nullptr, i18n("Are you sure you want to delete these index files? %1", indexSeriesName),
0608                         i18n("Delete File(s)"), KStandardGuiItem::cont(),
0609                         KStandardGuiItem::cancel(), "delete_index_files_warning"))
0610             {
0611                 if (QFileInfo(astrometryDataDir).isWritable())
0612                 {
0613                     QStringList nameFilter("*.fits");
0614                     QDir directory(astrometryDataDir);
0615                     QStringList indexList = directory.entryList(nameFilter);
0616                     for (auto &fileName : indexList)
0617                     {
0618                         if (fileName.contains(indexSeriesName.left(10)))
0619                         {
0620                             if (!directory.remove(fileName))
0621                             {
0622                                 KSNotification::error(i18n("File Delete Error"));
0623                                 slotUpdate();
0624                                 return;
0625                             }
0626                             slotUpdate();
0627                         }
0628                     }
0629                 }
0630                 else
0631                 {
0632                     KSNotification::error(i18n("Astrometry Folder Permissions Error"));
0633                     slotUpdate();
0634                 }
0635             }
0636         }
0637     }
0638 }
0639 }