File indexing completed on 2024-07-21 06:28:25

0001 /*
0002     SPDX-FileCopyrightText: 2003 Jasem Mutlaq <mutlaqja@ikarustech.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "telescopewizardprocess.h"
0008 
0009 #include "driverinfo.h"
0010 #include "drivermanager.h"
0011 #include "guimanager.h"
0012 #include "indidevice.h"
0013 #include "indielement.h"
0014 #include "indilistener.h"
0015 #include "indiproperty.h"
0016 #include "kstars.h"
0017 #include "kstarsdata.h"
0018 #include "ksutils.h"
0019 #include "Options.h"
0020 #include "dialogs/timedialog.h"
0021 
0022 #include <QProgressDialog>
0023 #include <QStatusBar>
0024 
0025 telescopeWizardProcess::telescopeWizardProcess(QWidget *parent) : QDialog(parent)
0026 {
0027     QFile sideIMG;
0028 
0029     ui.reset(new Ui::telescopeWizard());
0030     ui->setupUi(this);
0031 
0032     if (KSUtils::openDataFile(sideIMG, "wzscope.png"))
0033         ui->wizardPix->setPixmap(QPixmap(sideIMG.fileName()));
0034 
0035     ui->backB->hide();
0036     currentPage = INTRO_P;
0037 
0038     INDIMessageBar = Options::showINDIMessages();
0039     Options::setShowINDIMessages(false);
0040 
0041     QTime newTime(KStars::Instance()->data()->lt().time());
0042     QDate newDate(KStars::Instance()->data()->lt().date());
0043 
0044     ui->timeOut->setText(QString().sprintf("%02d:%02d:%02d", newTime.hour(), newTime.minute(), newTime.second()));
0045     ui->dateOut->setText(QString().sprintf("%d-%02d-%02d", newDate.year(), newDate.month(), newDate.day()));
0046 
0047     // FIXME is there a better way to check if a translated message is empty?
0048     //if (KStars::Instance()->data()->geo()->translatedProvince().isEmpty())
0049     if (KStars::Instance()->data()->geo()->translatedProvince() == QString("(I18N_EMPTY_MESSAGE)"))
0050         ui->locationOut->setText(QString("%1, %2")
0051                                      .arg(KStars::Instance()->data()->geo()->translatedName(),
0052                                           KStars::Instance()->data()->geo()->translatedCountry()));
0053     else
0054         ui->locationOut->setText(QString("%1, %2, %3")
0055                                      .arg(KStars::Instance()->data()->geo()->translatedName(),
0056                                           KStars::Instance()->data()->geo()->translatedProvince(),
0057                                           KStars::Instance()->data()->geo()->translatedCountry()));
0058 
0059     for (DriverInfo *dv : DriverManager::Instance()->getDrivers())
0060     {
0061         if (dv->getType() == KSTARS_TELESCOPE)
0062         {
0063             ui->telescopeCombo->addItem(dv->getTreeLabel());
0064             driversList[dv->getTreeLabel()] = dv;
0065         }
0066     }
0067 
0068     portList << "/dev/ttyS0"
0069              << "/dev/ttyS1"
0070              << "/dev/ttyS2"
0071              << "/dev/ttyS3"
0072              << "/dev/ttyS4"
0073              << "/dev/ttyUSB0"
0074              << "/dev/ttyUSB1"
0075              << "/dev/ttyUSB2"
0076              << "/dev/ttyUSB3";
0077 
0078     connect(ui->helpB, SIGNAL(clicked()), parent, SLOT(appHelpActivated()));
0079     connect(ui->cancelB, SIGNAL(clicked()), this, SLOT(cancelCheck()));
0080     connect(ui->nextB, SIGNAL(clicked()), this, SLOT(processNext()));
0081     connect(ui->backB, SIGNAL(clicked()), this, SLOT(processBack()));
0082     connect(ui->setTimeB, SIGNAL(clicked()), this, SLOT(newTime()));
0083     connect(ui->setLocationB, SIGNAL(clicked()), this, SLOT(newLocation()));
0084 
0085     //newDeviceTimer = new QTimer(this);
0086     //QObject::connect( newDeviceTimer, SIGNAL(timeout()), this, SLOT(processPort()) );
0087 }
0088 
0089 telescopeWizardProcess::~telescopeWizardProcess()
0090 {
0091     Options::setShowINDIMessages(INDIMessageBar);
0092     //Reset();
0093 }
0094 
0095 //Called when cancel is clicked, gives a warning if past the first couple of steps
0096 void telescopeWizardProcess::cancelCheck(void)
0097 {
0098     switch (currentPage)
0099     {
0100         case TELESCOPE_P:
0101         case LOCAL_P:
0102         case PORT_P:
0103             if (KMessageBox::warningYesNo(0, i18n("Are you sure you want to cancel?")) == KMessageBox::Yes)
0104                 emit rejected();
0105             break;
0106         default:
0107             emit rejected();
0108             break;
0109     }
0110 }
0111 
0112 void telescopeWizardProcess::processNext(void)
0113 {
0114     switch (currentPage)
0115     {
0116         case INTRO_P:
0117             currentPage++;
0118             ui->backB->show();
0119             ui->wizardContainer->setCurrentIndex(currentPage);
0120             break;
0121         case MODEL_P:
0122             currentPage++;
0123             ui->wizardContainer->setCurrentIndex(currentPage);
0124             break;
0125         case TELESCOPE_P:
0126             currentPage++;
0127             ui->wizardContainer->setCurrentIndex(currentPage);
0128             break;
0129         case LOCAL_P:
0130             currentPage++;
0131             ui->wizardContainer->setCurrentIndex(currentPage);
0132             break;
0133         case PORT_P:
0134             establishLink();
0135             break;
0136         default:
0137             break;
0138     }
0139 }
0140 
0141 void telescopeWizardProcess::processBack(void)
0142 {
0143     // for now, just display the next page, and restart once we reached the end
0144 
0145     switch (currentPage)
0146     {
0147         case INTRO_P:
0148             // we shouldn't be here!
0149             break;
0150             break;
0151         case MODEL_P:
0152             currentPage--;
0153             ui->backB->hide();
0154             ui->wizardContainer->setCurrentIndex(currentPage);
0155             break;
0156         case TELESCOPE_P:
0157             currentPage--;
0158             ui->wizardContainer->setCurrentIndex(currentPage);
0159             break;
0160         case LOCAL_P:
0161             currentPage--;
0162             ui->wizardContainer->setCurrentIndex(currentPage);
0163             break;
0164         case PORT_P:
0165             currentPage--;
0166             ui->wizardContainer->setCurrentIndex(currentPage);
0167             break;
0168         default:
0169             break;
0170     }
0171 }
0172 
0173 void telescopeWizardProcess::newTime()
0174 {
0175     TimeDialog timedialog(KStars::Instance()->data()->lt(), KStars::Instance()->data()->geo(), KStars::Instance());
0176 
0177     if (timedialog.exec() == QDialog::Accepted)
0178     {
0179         KStarsDateTime dt(timedialog.selectedDate(), timedialog.selectedTime());
0180         KStars::Instance()->data()->changeDateTime(dt);
0181 
0182         ui->timeOut->setText(
0183             QString().sprintf("%02d:%02d:%02d", dt.time().hour(), dt.time().minute(), dt.time().second()));
0184         ui->dateOut->setText(QString().sprintf("%d-%02d-%02d", dt.date().year(), dt.date().month(), dt.date().day()));
0185     }
0186 }
0187 
0188 void telescopeWizardProcess::newLocation()
0189 {
0190     KStars::Instance()->slotGeoLocator();
0191     GeoLocation *geo = KStars::Instance()->data()->geo();
0192     ui->locationOut->setText(
0193         QString("%1, %2, %3").arg(geo->translatedName(),geo->translatedProvince(), geo->translatedCountry()));
0194     ui->timeOut->setText(QString().sprintf("%02d:%02d:%02d", KStars::Instance()->data()->lt().time().hour(),
0195                                            KStars::Instance()->data()->lt().time().minute(),
0196                                            KStars::Instance()->data()->lt().time().second()));
0197     ui->dateOut->setText(QString().sprintf("%d-%02d-%02d", KStars::Instance()->data()->lt().date().year(),
0198                                            KStars::Instance()->data()->lt().date().month(),
0199                                            KStars::Instance()->data()->lt().date().day()));
0200 }
0201 
0202 void telescopeWizardProcess::establishLink()
0203 {
0204     managedDevice.clear();
0205 
0206     DriverInfo *dv = driversList.value(ui->telescopeCombo->currentText());
0207 
0208     if (dv == nullptr)
0209         return;
0210 
0211     managedDevice.append(dv);
0212     connect(INDIListener::Instance(), SIGNAL(newDevice(ISD::GDInterface*)), this,
0213             SLOT(processTelescope(ISD::GDInterface*)));
0214 
0215     if (ui->portIn->text().isEmpty())
0216     {
0217         progressScan = new QProgressDialog(i18n("Please wait while KStars scan communication ports for attached "
0218                                                 "telescopes.\nThis process might take few minutes to complete."),
0219                                            i18n("Cancel"), 0, portList.count());
0220         progressScan->setValue(0);
0221         //qDebug() << "KProgressDialog for automatic search has been initiated";
0222     }
0223     else
0224     {
0225         progressScan = new QProgressDialog(i18n("Please wait while KStars tries to connect to your telescope..."),
0226                                            i18n("Cancel"), portList.count(), portList.count());
0227         progressScan->setValue(portList.count());
0228         //qDebug() << "KProgressDialog for manual search has been initiated";
0229     }
0230 
0231     progressScan->setAutoClose(true);
0232     progressScan->setAutoReset(true);
0233     progressScan->show();
0234 
0235     if (dv->getClientState() == false)
0236     {
0237         if (DriverManager::Instance()->startDevices(managedDevice) == false)
0238         {
0239             Reset();
0240             close();
0241             return;
0242         }
0243     }
0244     else
0245         processTelescope(INDIListener::Instance()->getDevice(dv->getName()));
0246 }
0247 
0248 void telescopeWizardProcess::processTelescope(ISD::GDInterface *telescope)
0249 {
0250     if (telescope == nullptr)
0251         return;
0252 
0253     scopeDevice = telescope;
0254 
0255     // port empty, start autoscan
0256     if (ui->portIn->text().isEmpty())
0257     {
0258         //newDeviceTimer->stop();
0259         linkRejected = false;
0260         connect(scopeDevice, SIGNAL(Connected()), this, SLOT(linkSuccess()), Qt::QueuedConnection);
0261         connect(scopeDevice, SIGNAL(Disconnected()), this, SLOT(scanPorts()), Qt::QueuedConnection);
0262         scanPorts();
0263     }
0264     else
0265     {
0266         QString scopePort = ui->portIn->text();
0267 
0268         scopeDevice->runCommand(INDI_SET_PORT, &scopePort);
0269 
0270         scopeDevice->runCommand(INDI_CONNECT);
0271 
0272         Options::setShowINDIMessages(INDIMessageBar);
0273 
0274         close();
0275     }
0276 
0277     /*
0278     pp = indiDev->findProp("DEVICE_PORT");
0279     if (!pp) return;
0280     lp = pp->findElement("PORT");
0281     if (!lp) return;
0282 
0283     lp->write_w->setText(ui->portIn->text());
0284 
0285     pp = indiDev->findProp("CONNECTION");
0286     if (!pp) return;
0287 
0288     //newDeviceTimer->stop();
0289     */
0290 
0291     /*lp = pp->findElement("CONNECT");
0292     pp->newSwitch(lp);
0293 
0294     Reset();
0295 
0296     indimenu->show();*/
0297 }
0298 
0299 void telescopeWizardProcess::scanPorts()
0300 {
0301     if (progressScan == nullptr)
0302     {
0303         close();
0304         return;
0305     }
0306 
0307     currentPort++;
0308 
0309     if (progressScan->wasCanceled())
0310     {
0311         if (linkRejected)
0312             return;
0313 
0314         disconnect(this, SLOT(linkSuccess()));
0315         disconnect(this, SLOT(scanPorts()));
0316 
0317         DriverManager::Instance()->stopDevices(managedDevice);
0318         linkRejected = true;
0319         Reset();
0320         return;
0321     }
0322 
0323     progressScan->setValue(currentPort);
0324 
0325     //qDebug() << "Current port is " << currentPort << " and port count is " << portList.count() << endl;
0326 
0327     if (currentPort >= portList.count())
0328     {
0329         if (linkRejected)
0330             return;
0331 
0332         disconnect(this, SLOT(scanPorts()));
0333         disconnect(this, SLOT(linkSuccess()));
0334         linkRejected = true;
0335         DriverManager::Instance()->stopDevices(managedDevice);
0336         Reset();
0337 
0338         KMessageBox::sorry(
0339             0,
0340             i18n("Sorry. KStars failed to detect any attached telescopes, please check your settings and try again."));
0341         return;
0342     }
0343 
0344     QString scopePort = portList[currentPort];
0345     scopeDevice->runCommand(INDI_SET_PORT, &scopePort);
0346 
0347     scopeDevice->runCommand(INDI_CONNECT);
0348 }
0349 
0350 void telescopeWizardProcess::linkSuccess()
0351 {
0352     Reset();
0353 
0354     KStars::Instance()->statusBar()->showMessage(i18n("Telescope Wizard completed successfully."), 0);
0355 
0356     close();
0357 
0358     GUIManager::Instance()->show();
0359 }
0360 
0361 void telescopeWizardProcess::Reset()
0362 {
0363     currentPort  = -1;
0364     linkRejected = false;
0365 
0366     delete (progressScan);
0367     progressScan = nullptr;
0368 }