00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "indistd.h"
00013 #include "Options.h"
00014 #include "indielement.h"
00015 #include "indiproperty.h"
00016 #include "indigroup.h"
00017 #include "indidevice.h"
00018 #include "indidriver.h"
00019 #include "kstars.h"
00020 #include "kstarsdata.h"
00021 #include "skymap.h"
00022 #include "skyobject.h"
00023 #include "simclock.h"
00024 #include "devicemanager.h"
00025 #include "timedialog.h"
00026 #include "streamwg.h"
00027 #include "ccdpreviewwg.h"
00028 #include "fitsviewer.h"
00029
00030 #include <sys/socket.h>
00031 #include <netinet/in.h>
00032 #include <arpa/inet.h>
00033 #include <netdb.h>
00034 #include <ctype.h>
00035 #include <zlib.h>
00036 #include <stdlib.h>
00037
00038 #include <qtimer.h>
00039 #include <qlabel.h>
00040 #include <qfont.h>
00041 #include <qeventloop.h>
00042 #include <qsocketnotifier.h>
00043
00044 #include <klocale.h>
00045 #include <kdebug.h>
00046 #include <kpushbutton.h>
00047 #include <klineedit.h>
00048 #include <kstatusbar.h>
00049 #include <kmessagebox.h>
00050 #include <kapplication.h>
00051 #include <kprogress.h>
00052 #include <kurl.h>
00053 #include <kdirlister.h>
00054 #include <kaction.h>
00055
00056
00057 #define STD_BUFFER_SIZ 1024000
00058 #define FRAME_ILEN 1024
00059
00060 INDIStdDevice::INDIStdDevice(INDI_D *associatedDevice, KStars * kswPtr)
00061 {
00062
00063 dp = associatedDevice;
00064 ksw = kswPtr;
00065 initDevCounter = 0;
00066 seqCount = 0;
00067 batchMode = false;
00068 ISOMode = false;
00069
00070 currentObject = NULL;
00071 streamWindow = new StreamWG(this, ksw);
00072 CCDPreviewWindow = new CCDPreviewWG(this, ksw);
00073
00074 devTimer = new QTimer(this);
00075 seqLister = new KDirLister();
00076
00077 telescopeSkyObject = new SkyObject(0, 0, 0, 0, i18n("Telescope"));
00078 ksw->data()->appendTelescopeObject(telescopeSkyObject);
00079
00080 connect( devTimer, SIGNAL(timeout()), this, SLOT(timerDone()) );
00081 connect( seqLister, SIGNAL(newItems (const KFileItemList & )), this, SLOT(checkSeqBoundary(const KFileItemList &)));
00082
00083 downloadDialog = new KProgressDialog(NULL, 0, i18n("INDI"), i18n("Downloading Data..."));
00084 downloadDialog->cancel();
00085
00086 parser = newLilXML();
00087 }
00088
00089 INDIStdDevice::~INDIStdDevice()
00090 {
00091 streamWindow->enableStream(false);
00092 streamWindow->close();
00093 CCDPreviewWindow->enableStream(false);
00094 CCDPreviewWindow->close();
00095 streamDisabled();
00096 delete (seqLister);
00097 }
00098
00099 void INDIStdDevice::handleBLOB(unsigned char *buffer, int bufferSize, QString dataFormat)
00100 {
00101
00102 if (dataFormat == ".fits") dataType = DATA_FITS;
00103 else if (dataFormat == ".stream") dataType = DATA_STREAM;
00104 else if (dataFormat == ".ccdpreview") dataType = DATA_CCDPREVIEW;
00105 else dataType = DATA_OTHER;
00106
00107 if (dataType == DATA_STREAM)
00108 {
00109 if (!streamWindow->processStream)
00110 return;
00111
00112 streamWindow->show();
00113 streamWindow->streamFrame->newFrame( buffer, bufferSize, streamWindow->streamWidth, streamWindow->streamHeight);
00114 }
00115 else if (dataType == DATA_CCDPREVIEW)
00116 {
00117 if (!CCDPreviewWindow->processStream)
00118 return;
00119 CCDPreviewWindow->show();
00120 CCDPreviewWindow->streamFrame->newFrame( buffer, bufferSize, CCDPreviewWindow->streamWidth, CCDPreviewWindow->streamHeight);
00121 }
00122 else if (dataType == DATA_FITS || dataType == DATA_OTHER)
00123 {
00124 char filename[256];
00125 FILE *fitsTempFile;
00126 int fd, nr, n=0;
00127 QString currentDir = Options::fitsSaveDirectory();
00128
00129 streamWindow->close();
00130
00131 if (dataType == DATA_FITS && !batchMode && Options::indiFITSDisplay())
00132 {
00133 strcpy(filename, "/tmp/fitsXXXXXX");
00134 if ((fd = mkstemp(filename)) < 0)
00135 {
00136 KMessageBox::error(NULL, "Error making temporary filename.");
00137 return;
00138 }
00139 close(fd);
00140 }
00141 else
00142 {
00143 char ts[32];
00144 struct tm *tp;
00145 time_t t;
00146 time (&t);
00147 tp = gmtime (&t);
00148
00149 if (currentDir[currentDir.length() -1] == '/')
00150 currentDir.truncate(currentDir.length() - 1);
00151
00152 strncpy(filename, currentDir.ascii(), currentDir.length());
00153 filename[currentDir.length()] = '\0';
00154
00155 if (dataType == DATA_FITS)
00156 {
00157 char tempFileStr[256];
00158 strncpy(tempFileStr, filename, 256);
00159
00160 if ( batchMode && !ISOMode)
00161 snprintf(filename, sizeof(filename), "%s/%s_%02d.fits", tempFileStr, seqPrefix.ascii(), seqCount);
00162 else if (!batchMode && !Options::indiFITSDisplay())
00163 {
00164 strftime (ts, sizeof(ts), "%Y-%m-%dT%H:%M:%S", tp);
00165 snprintf(filename, sizeof(filename), "%s/file_%s.fits", tempFileStr, ts);
00166 }
00167 else
00168 {
00169 strftime (ts, sizeof(ts), "%Y-%m-%dT%H:%M:%S", tp);
00170 snprintf(filename, sizeof(filename), "%s/%s_%02d_%s.fits", tempFileStr, seqPrefix.ascii(), seqCount, ts);
00171 }
00172
00173 seqCount++;
00174 }
00175 else
00176 {
00177 strftime (ts, sizeof(ts), "/file-%Y-%m-%dT%H:%M:%S.", tp);
00178 strncat(filename, ts, sizeof(ts));
00179 strncat(filename, dataFormat.ascii(), 10);
00180 }
00181 }
00182
00183 fitsTempFile = fopen(filename, "w");
00184
00185 if (fitsTempFile == NULL) return;
00186
00187 for (nr=0; nr < (int) bufferSize; nr += n)
00188 n = fwrite( ((unsigned char *) buffer) + nr, 1, bufferSize - nr, fitsTempFile);
00189
00190 fclose(fitsTempFile);
00191
00192
00193 if (dataType == DATA_OTHER)
00194 {
00195 ksw->statusBar()->changeItem( i18n("Data file saved to %1").arg(filename), 0);
00196 return;
00197 }
00198 else if (dataType == DATA_FITS && (batchMode || !Options::indiFITSDisplay()))
00199 {
00200 ksw->statusBar()->changeItem( i18n("FITS file saved to %1").arg(filename), 0);
00201 emit FITSReceived(dp->label);
00202 return;
00203 }
00204
00205 KURL fileURL(filename);
00206
00207 FITSViewer * fv = new FITSViewer(&fileURL, ksw);
00208 fv->fitsChange();
00209 fv->show();
00210 }
00211
00212 }
00213
00214
00215 void INDIStdDevice::setTextValue(INDI_P *pp)
00216 {
00217 INDI_E *el;
00218 int wd, ht, bpp, bo, mu;
00219 long mgd;
00220 double fwhm;
00221 int d, m, y, min, sec, hour;
00222 ExtDate indiDate;
00223 QTime indiTime;
00224 KStarsDateTime indiDateTime;
00225
00226 switch (pp->stdID)
00227 {
00228
00229 case TIME:
00230 if ( Options::indiAutoTime() )
00231 handleDevCounter();
00232
00233
00234 el = pp->findElement("UTC");
00235 if (!el) return;
00236
00237 sscanf(el->text.ascii(), "%d%*[^0-9]%d%*[^0-9]%dT%d%*[^0-9]%d%*[^0-9]%d", &y, &m, &d, &hour, &min, &sec);
00238 indiDate.setYMD(y, m, d);
00239 indiTime.setHMS(hour, min, sec);
00240 indiDateTime.setDate(indiDate);
00241 indiDateTime.setTime(indiTime);
00242
00243 ksw->data()->changeDateTime(indiDateTime);
00244 ksw->data()->syncLST();
00245
00246 break;
00247
00248 case SDTIME:
00249 if ( Options::indiAutoTime())
00250 handleDevCounter();
00251 break;
00252
00253 case GEOGRAPHIC_COORD:
00254 if ( Options::indiAutoGeo() )
00255 handleDevCounter();
00256 break;
00257
00258 case CCD_EXPOSE_DURATION:
00259 if (pp->state == PS_IDLE || pp->state == PS_OK)
00260 pp->set_w->setText(i18n("Start"));
00261 break;
00262
00263 case CCD_FRAME:
00264 el = pp->findElement("WIDTH");
00265 if (!el) return;
00266 wd = (int) el->value;
00267 el = pp->findElement("HEIGHT");
00268 if (!el) return;
00269 ht = (int) el->value;
00270
00271 streamWindow->setSize(wd, ht);
00272
00273 break;
00274 case CCDPREVIEW_CTRL:
00275 el = pp->findElement("WIDTH");
00276 if (!el) return;
00277 wd = (int) el->value;
00278 el = pp->findElement("HEIGHT");
00279 if (!el) return;
00280 ht = (int) el->value;
00281 el = pp->findElement("BYTEORDER");
00282 if (!el) return;
00283 bo = (int) el->value;
00284 el = pp->findElement("BYTESPERPIXEL");
00285 if (!el) return;
00286 bpp = (int) el->value;
00287 el = pp->findElement("MAXGOODDATA");
00288 if (!el) return;
00289 mgd = (long) el->value;
00290 CCDPreviewWindow->setCtrl(wd, ht, bo ,bpp,mgd);
00291
00292 break;
00293
00294 case CCD_INFO:
00295 el = pp->findElement("CCD_FWHM_PIXEL");
00296 if (!el) return;
00297 fwhm = el->value;
00298 el = pp->findElement("CCD_PIXEL_SIZE");
00299 if (!el) return;
00300 mu = (int) el->value;
00301 CCDPreviewWindow->setCCDInfo(fwhm, mu);
00302 break;
00303
00304 case EQUATORIAL_COORD:
00305 case EQUATORIAL_EOD_COORD:
00306 if (!dp->isOn()) break;
00307 el = pp->findElement("RA");
00308 if (!el) return;
00309 telescopeSkyObject->setRA(el->value);
00310 el = pp->findElement("DEC");
00311 if (!el) return;
00312 telescopeSkyObject->setDec(el->value);
00313 telescopeSkyObject->EquatorialToHorizontal(ksw->LST(), ksw->geo()->lat());
00314
00315 if (ksw->map()->focusObject() == telescopeSkyObject)
00316 ksw->map()->updateFocus();
00317 else
00318 ksw->map()->update();
00319 break;
00320
00321 case HORIZONTAL_COORD:
00322 if (!dp->isOn()) break;
00323 el = pp->findElement("ALT");
00324 if (!el) return;
00325 telescopeSkyObject->setAlt(el->value);
00326 el = pp->findElement("AZ");
00327 if (!el) return;
00328 telescopeSkyObject->setAz(el->value);
00329 telescopeSkyObject->HorizontalToEquatorial(ksw->LST(), ksw->geo()->lat());
00330
00331 if (ksw->map()->focusObject() == telescopeSkyObject)
00332 ksw->map()->updateFocus();
00333 else
00334 ksw->map()->update();
00335 break;
00336
00337 default:
00338 break;
00339
00340 }
00341
00342 }
00343
00344 void INDIStdDevice::setLabelState(INDI_P *pp)
00345 {
00346 INDI_E *lp;
00347 INDI_P *imgProp;
00348 KAction *tmpAction;
00349 INDIDriver *drivers = ksw->getINDIDriver();
00350 QFont buttonFont;
00351
00352 switch (pp->stdID)
00353 {
00354 case CONNECTION:
00355 lp = pp->findElement("CONNECT");
00356 if (!lp) return;
00357
00358 if (lp->state == PS_ON)
00359 {
00360 initDeviceOptions();
00361 emit linkAccepted();
00362
00363 imgProp = dp->findProp("CCD_EXPOSE_DURATION");
00364 if (imgProp)
00365 {
00366 tmpAction = ksw->actionCollection()->action("capture_sequence");
00367 if (!tmpAction)
00368 kdDebug() << "Warning: capture_sequence action not found" << endl;
00369 else
00370 tmpAction->setEnabled(true);
00371 }
00372 }
00373 else
00374 {
00375 if (streamWindow)
00376 {
00377
00378
00379 streamWindow->enableStream(false);
00380 streamWindow->close();
00381
00382
00383 }
00384
00385 if (ksw->map()->focusObject() == telescopeSkyObject)
00386 {
00387 ksw->map()->stopTracking();
00388 ksw->map()->setFocusObject(NULL);
00389 }
00390
00391 drivers->updateMenuActions();
00392 ksw->map()->forceUpdateNow();
00393 emit linkRejected();
00394 }
00395 break;
00396
00397 case VIDEO_STREAM:
00398 lp = pp->findElement("ON");
00399 if (!lp) return;
00400 if (lp->state == PS_ON)
00401 streamWindow->enableStream(true);
00402 else
00403 streamWindow->enableStream(false);
00404 break;
00405
00406 case CCDPREVIEW_STREAM:
00407 lp = pp->findElement("ON");
00408 if (!lp) return;
00409 if (lp->state == PS_ON)
00410 CCDPreviewWindow->enableStream(true);
00411 else
00412 CCDPreviewWindow->enableStream(false);
00413 break;
00414
00415 default:
00416 break;
00417 }
00418
00419 }
00420
00421 void INDIStdDevice::streamDisabled()
00422 {
00423 INDI_P *pp;
00424 INDI_E *el;
00425
00426
00427
00428
00429
00430 pp = dp->findProp("VIDEO_STREAM");
00431 if (!pp) return;
00432
00433 el = pp->findElement("OFF");
00434 if (!el) return;
00435
00436 if (el->state == PS_ON)
00437 return;
00438
00439
00440 pp->newSwitch(1);
00441
00442 }
00443
00444 void INDIStdDevice::updateSequencePrefix(QString newPrefix)
00445 {
00446 seqPrefix = newPrefix;
00447
00448 seqLister->setNameFilter(QString("%1_*.fits").arg(seqPrefix));
00449
00450 seqCount = 0;
00451
00452 if (ISOMode) return;
00453
00454 seqLister->openURL(Options::fitsSaveDirectory());
00455
00456 checkSeqBoundary(seqLister->items());
00457
00458 }
00459
00460 void INDIStdDevice::checkSeqBoundary(const KFileItemList & items)
00461 {
00462 int newFileIndex;
00463 QString tempName;
00464 char *tempPrefix = new char[64];
00465
00466
00467 if (ISOMode)
00468 return;
00469
00470 for ( KFileItemListIterator it( items ) ; it.current() ; ++it )
00471 {
00472 tempName = it.current()->name();
00473
00474
00475 if (tempName.find(seqPrefix) == -1)
00476 continue;
00477
00478 strncpy(tempPrefix, tempName.ascii(), 64);
00479 tempPrefix[63] = '\0';
00480
00481 char * t = tempPrefix;
00482
00483
00484 while (*t) { if (isdigit(*t)) break; t++; }
00485
00486
00487 newFileIndex = strtol(t, NULL, 10);
00488
00489 if (newFileIndex >= seqCount)
00490 seqCount = newFileIndex + 1;
00491 }
00492
00493 delete [] (tempPrefix);
00494
00495 }
00496
00497 void INDIStdDevice::updateTime()
00498 {
00499 INDI_P *pp;
00500 INDI_E *lp;
00501
00502 pp = dp->findProp("TIME");
00503 if (!pp) return;
00504
00505 lp = pp->findElement("UTC");
00506
00507 if (!lp) return;
00508
00509 QTime newTime( ksw->data()->ut().time());
00510 ExtDate newDate( ksw->data()->ut().date());
00511
00512 lp->write_w->setText(QString("%1-%2-%3T%4:%5:%6").arg(newDate.year()).arg(newDate.month())
00513 .arg(newDate.day()).arg(newTime.hour())
00514 .arg(newTime.minute()).arg(newTime.second()));
00515 pp->newText();
00516
00517 pp = dp->findProp("SDTIME");
00518 if (!pp) return;
00519 lp = pp->findElement("LST");
00520 if (!lp) return;
00521
00522 lp->write_w->setText(ksw->LST()->toHMSString());
00523 pp->newText();
00524 }
00525
00526 void INDIStdDevice::updateLocation()
00527 {
00528 INDI_P *pp;
00529 INDI_E * latEle, * longEle;
00530 GeoLocation *geo = ksw->geo();
00531
00532 pp = dp->findProp("GEOGRAPHIC_COORD");
00533 if (!pp) return;
00534
00535 dms tempLong (geo->lng()->degree(), geo->lng()->arcmin(), geo->lng()->arcsec());
00536 dms fullCir(360,0,0);
00537
00538 if (tempLong.degree() < 0)
00539 tempLong.setD ( fullCir.Degrees() + tempLong.Degrees());
00540
00541 latEle = pp->findElement("LAT");
00542 if (!latEle) return;
00543 longEle = pp->findElement("LONG");
00544 if (!longEle) return;
00545
00546 longEle->write_w->setText(QString("%1:%2:%3").arg(tempLong.degree()).arg(tempLong.arcmin()).arg(tempLong.arcsec()));
00547 latEle->write_w->setText(QString("%1:%2:%3").arg(geo->lat()->degree()).arg(geo->lat()->arcmin()).arg(geo->lat()->arcsec()));
00548
00549 pp->newText();
00550 }
00551
00552
00553 void INDIStdDevice::registerProperty(INDI_P *pp)
00554 {
00555 INDI_E * portEle;
00556 INDIDriver *drivers = ksw->getINDIDriver();
00557 QString str;
00558
00559 switch (pp->stdID)
00560 {
00561 case DEVICE_PORT:
00562 portEle = pp->findElement("PORT");
00563 if (!portEle) return;
00564
00565 if (drivers)
00566 {
00567 for (unsigned int i=0; i < drivers->devices.size(); i++)
00568 {
00569 if (drivers->devices[i]->mgrID == dp->parentMgr->mgrID)
00570 {
00571 if (drivers->devices[i]->deviceType == KSTARS_TELESCOPE)
00572 {
00573 portEle->read_w->setText( Options::indiTelescopePort() );
00574 portEle->write_w->setText( Options::indiTelescopePort() );
00575 portEle->text = Options::indiTelescopePort();
00576 break;
00577 }
00578 else if (drivers->devices[i]->deviceType == KSTARS_VIDEO)
00579 {
00580 portEle->read_w->setText( Options::indiVideoPort() );
00581 portEle->write_w->setText( Options::indiVideoPort() );
00582 portEle->text = Options::indiVideoPort();
00583 break;
00584 }
00585 }
00586 }
00587 }
00588 break;
00589
00590 }
00591
00592 }
00593
00594 void INDIStdDevice::initDeviceOptions()
00595 {
00596
00597 INDI_P *prop;
00598
00599 initDevCounter = 0;
00600
00601 if ( Options::indiAutoTime() )
00602 {
00603 prop = dp->findProp("TIME");
00604 if (prop)
00605 {
00606 updateTime();
00607 initDevCounter += 5;
00608 }
00609 }
00610
00611 if ( Options::indiAutoGeo() )
00612 {
00613 prop = dp->findProp("GEOGRAPHIC_COORD");
00614 if (prop)
00615 {
00616 updateLocation();
00617 initDevCounter += 2;
00618 }
00619 }
00620
00621 if ( Options::indiMessages() )
00622 ksw->statusBar()->changeItem( i18n("%1 is online.").arg(dp->name), 0);
00623
00624 ksw->map()->forceUpdateNow();
00625 }
00626
00627 void INDIStdDevice::handleDevCounter()
00628 {
00629
00630 if (initDevCounter <= 0)
00631 return;
00632
00633 initDevCounter--;
00634
00635 if ( initDevCounter == 0 && Options::indiMessages() )
00636 ksw->statusBar()->changeItem( i18n("%1 is online and ready.").arg(dp->name), 0);
00637
00638 }
00639
00640 bool INDIStdDevice::handleNonSidereal()
00641 {
00642 if (!currentObject)
00643 return false;
00644
00645 int trackIndex=0;
00646 INDI_E *nameEle;
00647
00648 kdDebug() << "Object of type " << currentObject->typeName() << endl;
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664 INDI_P *prop = dp->findProp(QString("SOLAR_SYSTEM"));
00665 INDI_P *setMode = dp->findProp(QString("ON_COORD_SET"));
00666
00667
00668 if (prop && setMode)
00669 {
00670 for (unsigned int i=0; i < setMode->el.count(); i++)
00671 if (setMode->el.at(i)->name == "TRACK")
00672 { trackIndex = i; break; }
00673
00674 kdDebug() << "Device supports SOLAR_SYSTEM property" << endl;
00675
00676 for (unsigned int i=0; i < prop->el.count(); i++)
00677 if (currentObject->name().lower() == prop->el.at(i)->label.lower())
00678 {
00679 prop->newSwitch(i);
00680 setMode->newSwitch(trackIndex);
00681
00682
00683 nameEle = dp->findElem("OBJECT_NAME");
00684 if (nameEle && nameEle->pp->perm != PP_RO)
00685 {
00686 nameEle->write_w->setText(currentObject->name());
00687 nameEle->pp->newText();
00688 }
00689
00690 return true;
00691 }
00692 }
00693
00694 kdDebug() << "Device doesn't support SOLAR_SYSTEM property, issuing a timer" << endl;
00695 kdDebug() << "Starting timer for object of type " << currentObject->typeName() << endl;
00696
00697
00698 switch (currentObject->type())
00699 {
00700
00701 case 2:
00702 kdDebug() << "Initiating pulse tracking for " << currentObject->name() << endl;
00703 devTimer->start(INDI_PULSE_TRACKING);
00704 break;
00705
00706 case 9:
00707 case 10:
00708 kdDebug() << "Initiating pulse tracking for " << currentObject->name() << endl;
00709 devTimer->start(INDI_PULSE_TRACKING);
00710 break;
00711 default:
00712 break;
00713 }
00714
00715 return false;
00716 }
00717
00718
00719 void INDIStdDevice::timerDone()
00720 {
00721 INDI_P *prop;
00722 INDI_E *RAEle, *DecEle;
00723 INDI_E *el;
00724 bool useJ2000 = false;
00725
00726 if (!dp->isOn())
00727 {
00728 devTimer->stop();
00729 return;
00730 }
00731
00732 prop = dp->findProp("ON_COORD_SET");
00733 if (prop == NULL || !currentObject)
00734 return;
00735
00736 el = prop->findElement("TRACK");
00737 if (!el) return;
00738
00739 if (el->state != PS_ON)
00740 {
00741 devTimer->stop();
00742 return;
00743 }
00744
00745 prop = dp->findProp("EQUATORIAL_EOD_COORD");
00746
00747 if (prop == NULL)
00748 {
00749 prop = dp->findProp("EQUATORIAL_COORD");
00750 if (prop) useJ2000 = true;
00751 }
00752
00753 if (prop == NULL || !currentObject)
00754 return;
00755
00756
00757 if (prop->state == PS_BUSY)
00758 return;
00759
00760 kdDebug() << "Timer called, starting processing" << endl;
00761
00762 SkyPoint sp(currentObject->ra(), currentObject->dec());
00763
00764 kdDebug() << "RA: " << currentObject->ra()->toHMSString() << " - DEC: " << currentObject->dec()->toDMSString() << endl;
00765 kdDebug() << "Az: " << currentObject->az()->toHMSString() << " - Alt " << currentObject->alt()->toDMSString() << endl;
00766
00767 if (useJ2000)
00768 {
00769 sp.set(currentObject->ra(), currentObject->dec());
00770 sp.apparentCoord( ksw->data()->ut().djd() , (long double) J2000);
00771 }
00772
00773
00774
00775
00776
00777 RAEle = prop->findElement("RA");
00778 if (!RAEle) return;
00779 DecEle = prop->findElement("DEC");
00780 if (!DecEle) return;
00781
00782 RAEle->write_w->setText(QString("%1:%2:%3").arg(sp.ra()->hour())
00783 .arg(sp.ra()->minute())
00784 .arg(sp.ra()->second()));
00785 DecEle->write_w->setText(QString("%1:%2:%3").arg(sp.dec()->degree())
00786 .arg(sp.dec()->arcmin())
00787 .arg(sp.dec()->arcsec()));
00788 prop->newText();
00789
00790 }
00791
00792 INDIStdProperty::INDIStdProperty(INDI_P *associatedProperty, KStars * kswPtr, INDIStdDevice *stdDevPtr)
00793 {
00794 pp = associatedProperty;
00795 ksw = kswPtr;
00796 stdDev = stdDevPtr;
00797 }
00798
00799 INDIStdProperty::~INDIStdProperty()
00800 {
00801
00802 }
00803
00804 void INDIStdProperty::newText()
00805 {
00806 INDI_E *lp;
00807 INDIDriver *drivers = ksw->getINDIDriver();
00808
00809 switch (pp->stdID)
00810 {
00811
00812 case CCD_EXPOSE_DURATION:
00813 pp->set_w->setText(i18n("Cancel"));
00814 break;
00815
00816
00817 case DEVICE_PORT:
00818 lp = pp->findElement("PORT");
00819
00820 if (lp && drivers)
00821 {
00822 for (unsigned int i=0; i < drivers->devices.size(); i++)
00823 {
00824 if (drivers->devices[i]->mgrID == stdDev->dp->parentMgr->mgrID)
00825 {
00826 if (drivers->devices[i]->deviceType == KSTARS_TELESCOPE)
00827 {
00828 Options::setIndiTelescopePort( lp->text );
00829 kdDebug() << "Setting telescope port " << lp->text << endl;
00830 }
00831 else if (drivers->devices[i]->deviceType == KSTARS_VIDEO)
00832 {
00833 Options::setIndiVideoPort( lp->text );
00834 kdDebug() << "Setting video port " << lp->text << endl;
00835 }
00836 break;
00837 }
00838 }
00839 }
00840
00841 break;
00842 }
00843
00844 }
00845
00846 bool INDIStdProperty::convertSwitch(int switchIndex, INDI_E *lp)
00847 {
00848
00849 INDI_E *RAEle(NULL), *DecEle(NULL), *AzEle(NULL), *AltEle(NULL), *nameEle(NULL);
00850 INDI_P * prop;
00851 SkyPoint sp;
00852 int selectedCoord=0;
00853 bool useJ2000 (false);
00854
00855 switch (pp->stdID)
00856 {
00857
00858 case ON_COORD_SET:
00859
00860 stdDev->currentObject = NULL;
00861
00862 if (stdDev->devTimer->isActive())
00863 stdDev->devTimer->stop();
00864
00865 prop = pp->pg->dp->findProp("EQUATORIAL_EOD_COORD");
00866 if (prop == NULL)
00867 {
00868 prop = pp->pg->dp->findProp("EQUATORIAL_COORD");
00869 if (prop == NULL)
00870 {
00871 prop = pp->pg->dp->findProp("HORIZONTAL_COORD");
00872 if (prop == NULL)
00873 return false;
00874 else
00875 selectedCoord = 1;
00876 }
00877 else
00878 useJ2000 = true;
00879 }
00880
00881 switch (selectedCoord)
00882 {
00883
00884 case 0:
00885 if (prop->perm == PP_RO) return false;
00886 RAEle = prop->findElement("RA");
00887 if (!RAEle) return false;
00888 DecEle = prop->findElement("DEC");
00889 if (!DecEle) return false;
00890 break;
00891
00892
00893 case 1:
00894 if (prop->perm == PP_RO) return false;
00895 AzEle = prop->findElement("AZ");
00896 if (!AzEle) return false;
00897 AltEle = prop->findElement("ALT");
00898 if (!AltEle) return false;
00899 break;
00900 }
00901
00902 stdDev->currentObject = ksw->map()->clickedObject();
00903
00904
00905 if ((lp->name == "TRACK"))
00906 if (stdDev->handleNonSidereal())
00907 return true;
00908
00909
00910 if (stdDev->currentObject)
00911 {
00912 nameEle = pp->pg->dp->findElem("OBJECT_NAME");
00913 if (nameEle && nameEle->pp->perm != PP_RO)
00914 {
00915 nameEle->write_w->setText(stdDev->currentObject->name());
00916 nameEle->pp->newText();
00917 }
00918 }
00919
00920 switch (selectedCoord)
00921 {
00922 case 0:
00923 if (stdDev->currentObject)
00924 sp.set (stdDev->currentObject->ra(), stdDev->currentObject->dec());
00925 else
00926 sp.set (ksw->map()->clickedPoint()->ra(), ksw->map()->clickedPoint()->dec());
00927
00928 if (useJ2000)
00929 sp.apparentCoord(ksw->data()->ut().djd(), (long double) J2000);
00930
00931 RAEle->write_w->setText(QString("%1:%2:%3").arg(sp.ra()->hour()).arg(sp.ra()->minute()).arg(sp.ra()->second()));
00932 DecEle->write_w->setText(QString("%1:%2:%3").arg(sp.dec()->degree()).arg(sp.dec()->arcmin()).arg(sp.dec()->arcsec()));
00933
00934 break;
00935
00936 case 1:
00937 if (stdDev->currentObject)
00938 {
00939 sp.setAz(*stdDev->currentObject->az());
00940 sp.setAlt(*stdDev->currentObject->alt());
00941 }
00942 else
00943 {
00944 sp.setAz(*ksw->map()->clickedPoint()->az());
00945 sp.setAlt(*ksw->map()->clickedPoint()->alt());
00946 }
00947
00948 AzEle->write_w->setText(QString("%1:%2:%3").arg(sp.az()->degree()).arg(sp.az()->arcmin()).arg(sp.az()->arcsec()));
00949 AltEle->write_w->setText(QString("%1:%2:%3").arg(sp.alt()->degree()).arg(sp.alt()->arcmin()).arg(sp.alt()->arcsec()));
00950
00951 break;
00952 }
00953
00954 pp->newSwitch(switchIndex);
00955 prop->newText();
00956
00957 return true;
00958 break;
00959
00960
00961 case ABORT_MOTION:
00962 kdDebug() << "Stopping timer." << endl;
00963 stdDev->devTimer->stop();
00964 pp->newSwitch(switchIndex);
00965 return true;
00966 break;
00967
00968 case MOVEMENT:
00969 pp->newSwitch(switchIndex);
00970 break;
00971
00972 default:
00973 return false;
00974 break;
00975 }
00976
00977 return false;
00978
00979 }
00980
00981
00982 bool INDIStdProperty::newSwitch(int id, INDI_E* el)
00983 {
00984 INDI_P *prop;
00985 el=el;
00986
00987 switch (pp->stdID)
00988 {
00989 case CONNECTION:
00990 if (id == 1)
00991 stdDev->streamDisabled();
00992 else
00993 {
00994 prop = pp->pg->dp->findProp("DEVICE_PORT");
00995 if (prop)
00996 prop->newText();
00997 }
00998 break;
00999 case ABORT_MOTION:
01000 case PARK:
01001 case MOVEMENT:
01002
01003 stdDev->devTimer->stop();
01004 break;
01005 default:
01006 break;
01007 }
01008
01009 return false;
01010
01011 }
01012
01013 void INDIStdProperty::newTime()
01014 {
01015 INDI_E * timeEle;
01016 INDI_P *SDProp;
01017
01018 timeEle = pp->findElement("UTC");
01019 if (!timeEle) return;
01020
01021 TimeDialog timedialog ( ksw->data()->ut(), ksw );
01022
01023 if ( timedialog.exec() == QDialog::Accepted )
01024 {
01025 QTime newTime( timedialog.selectedTime() );
01026 ExtDate newDate( timedialog.selectedDate() );
01027
01028 timeEle->write_w->setText(QString("%1-%2-%3T%4:%5:%6")
01029 .arg(newDate.year()).arg(newDate.month())
01030 .arg(newDate.day()).arg(newTime.hour())
01031 .arg(newTime.minute()).arg(newTime.second()));
01032 pp->newText();
01033 }
01034 else return;
01035
01036 SDProp = pp->pg->dp->findProp("SDTIME");
01037 if (!SDProp) return;
01038 timeEle = SDProp->findElement("LST");
01039 if (!timeEle) return;
01040
01041 timeEle->write_w->setText(ksw->LST()->toHMSString());
01042 SDProp->newText();
01043 }
01044
01045 #include "indistd.moc"