moved kdeaccessibility kdeaddons kdeadmin kdeartwork kdebindings kdeedu kdegames...
[kdeedu.git] / kstars / kstars / indistd.cpp
blob39a54ebf8419cda1493a5cfcdf106203d331729e
1 /* INDI STD
2 Copyright (C) 2003 Jasem Mutlaq (mutlaqja@ikarustech.com)
4 This apppication is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
9 2004-01-18: This class handles INDI Standard properties.
12 #include "indistd.h"
13 #include "Options.h"
14 #include "indielement.h"
15 #include "indiproperty.h"
16 #include "indigroup.h"
17 #include "indidevice.h"
18 #include "indidriver.h"
19 #include "kstars.h"
20 #include "kstarsdata.h"
21 #include "skymap.h"
22 #include "skyobject.h"
23 #include "simclock.h"
24 #include "devicemanager.h"
25 #include "timedialog.h"
26 #include "streamwg.h"
27 #include "fitsviewer.h"
29 #include <sys/socket.h>
30 #include <netinet/in.h>
31 #include <arpa/inet.h>
32 #include <netdb.h>
33 #include <ctype.h>
34 #include <zlib.h>
36 #include <qtimer.h>
37 #include <qlabel.h>
38 #include <qfont.h>
39 #include <qeventloop.h>
40 #include <qsocketnotifier.h>
42 #include <klocale.h>
43 #include <kdebug.h>
44 #include <kpushbutton.h>
45 #include <klineedit.h>
46 #include <kstatusbar.h>
47 #include <kmessagebox.h>
48 #include <kapplication.h>
49 #include <kprogress.h>
50 #include <kurl.h>
51 #include <kdirlister.h>
52 #include <kaction.h>
55 #define STD_BUFFER_SIZ 1024000
56 #define FRAME_ILEN 1024
58 INDIStdDevice::INDIStdDevice(INDI_D *associatedDevice, KStars * kswPtr)
61 dp = associatedDevice;
62 ksw = kswPtr;
63 initDevCounter = 0;
64 seqCount = 0;
65 batchMode = false;
66 ISOMode = false;
68 currentObject = NULL;
69 streamWindow = new StreamWG(this, ksw);
70 devTimer = new QTimer(this);
71 seqLister = new KDirLister();
73 connect( devTimer, SIGNAL(timeout()), this, SLOT(timerDone()) );
74 connect( seqLister, SIGNAL(newItems (const KFileItemList & )), this, SLOT(checkSeqBoundary(const KFileItemList &)));
76 downloadDialog = new KProgressDialog(NULL, 0, i18n("INDI"), i18n("Downloading Data..."));
77 downloadDialog->cancel();
79 parser = newLilXML();
82 INDIStdDevice::~INDIStdDevice()
84 streamWindow->enableStream(false);
85 streamWindow->close();
86 streamDisabled();
89 void INDIStdDevice::handleBLOB(unsigned char *buffer, int bufferSize, int dataType)
92 if (dataType == DATA_STREAM)
94 if (!streamWindow->processStream)
95 return;
97 streamWindow->show();
99 streamWindow->streamFrame->newFrame( buffer, bufferSize, streamWindow->streamWidth, streamWindow->streamHeight);
101 else if (dataType == DATA_FITS || dataType == DATA_OTHER)
103 char filename[256];
104 FILE *fitsTempFile;
105 int fd, nr, n=0;
106 QString currentDir = Options::fitsSaveDirectory();
108 streamWindow->close();
110 if (dataType == DATA_FITS && !batchMode && Options::indiFITSDisplay())
112 strcpy(filename, "/tmp/fitsXXXXXX");
113 if ((fd = mkstemp(filename)) < 0)
115 KMessageBox::error(NULL, "Error making temporary filename.");
116 return;
118 close(fd);
120 else
122 char ts[32];
123 struct tm *tp;
124 time_t t;
125 time (&t);
126 tp = gmtime (&t);
128 if (currentDir[currentDir.length() -1] == '/')
129 currentDir.truncate(currentDir.length() - 1);
131 strncpy(filename, currentDir.ascii(), currentDir.length());
132 filename[currentDir.length()] = '\0';
134 if (dataType == DATA_FITS)
136 char tempFileStr[256];
137 strncpy(tempFileStr, filename, 256);
139 if ( batchMode && !ISOMode)
140 snprintf(filename, sizeof(filename), "%s/%s_%02d.fits", tempFileStr, seqPrefix.ascii(), seqCount);
141 else if (!batchMode && !Options::indiFITSDisplay())
143 strftime (ts, sizeof(ts), "%Y-%m-%dT%H:%M:%S", tp);
144 snprintf(filename, sizeof(filename), "%s/file_%s.fits", tempFileStr, ts);
146 else
148 strftime (ts, sizeof(ts), "%Y-%m-%dT%H:%M:%S", tp);
149 snprintf(filename, sizeof(filename), "%s/%s_%02d_%s.fits", tempFileStr, seqPrefix.ascii(), seqCount, ts);
152 seqCount++;
154 else
156 strftime (ts, sizeof(ts), "/file-%Y-%m-%dT%H:%M:%S.", tp);
157 strncat(filename, ts, sizeof(ts));
158 strncat(filename, dataExt.ascii(), 3);
162 fitsTempFile = fopen(filename, "w");
164 if (fitsTempFile == NULL) return;
166 for (nr=0; nr < (int) bufferSize; nr += n)
167 n = fwrite( ((unsigned char *) buffer) + nr, 1, bufferSize - nr, fitsTempFile);
169 fclose(fitsTempFile);
171 // We're done if we have DATA_OTHER
172 if (dataType == DATA_OTHER)
174 ksw->statusBar()->changeItem( i18n("Data file saved to %1").arg(filename), 0);
175 return;
177 else if (dataType == DATA_FITS && (batchMode || !Options::indiFITSDisplay()))
179 ksw->statusBar()->changeItem( i18n("FITS file saved to %1").arg(filename), 0);
180 emit FITSReceived(dp->label);
181 return;
184 KURL fileURL(filename);
186 FITSViewer * fv = new FITSViewer(&fileURL, ksw);
187 fv->fitsChange();
188 fv->show();
193 void INDIStdDevice::setTextValue(INDI_P *pp)
195 INDI_E *el;
196 int wd, ht;
197 int d, m, y, min, sec, hour;
198 ExtDate indiDate;
199 QTime indiTime;
200 KStarsDateTime indiDateTime;
202 switch (pp->stdID)
204 case EQUATORIAL_COORD:
205 case EQUATORIAL_EOD_COORD:
206 //ksw->map()->forceUpdateNow();
207 ksw->map()->update();
208 break;
211 case TIME:
212 if ( Options::indiAutoTime() )
213 handleDevCounter();
215 // Update KStars time once we receive update from INDI
216 el = pp->findElement("UTC");
217 if (!el) return;
219 sscanf(el->text.ascii(), "%d%*[^0-9]%d%*[^0-9]%dT%d%*[^0-9]%d%*[^0-9]%d", &y, &m, &d, &hour, &min, &sec);
220 indiDate.setYMD(y, m, d);
221 indiTime.setHMS(hour, min, sec);
222 indiDateTime.setDate(indiDate);
223 indiDateTime.setTime(indiTime);
225 ksw->data()->changeDateTime(indiDateTime);
226 ksw->data()->syncLST();
228 break;
230 case SDTIME:
231 if ( Options::indiAutoTime())
232 handleDevCounter();
233 break;
235 case GEOGRAPHIC_COORD:
236 if ( Options::indiAutoGeo() )
237 handleDevCounter();
238 break;
240 case EXPOSE_DURATION:
241 if (pp->state == PS_IDLE || pp->state == PS_OK)
242 pp->set_w->setText(i18n("Start"));
243 break;
245 case IMAGE_SIZE:
246 el = pp->findElement("WIDTH");
247 if (!el) return;
248 wd = (int) el->value;
249 el = pp->findElement("HEIGHT");
250 if (!el) return;
251 ht = (int) el->value;
253 streamWindow->setSize(wd, ht);
254 //streamWindow->allocateStreamBuffer();
255 break;
257 default:
258 break;
264 void INDIStdDevice::setLabelState(INDI_P *pp)
266 INDI_E *lp;
267 INDI_P *imgProp;
268 KAction *tmpAction;
269 INDIDriver *drivers = ksw->getINDIDriver();
270 QFont buttonFont;
272 switch (pp->stdID)
274 case CONNECTION:
275 lp = pp->findElement("CONNECT");
276 if (!lp) return;
278 if (lp->state == PS_ON)
280 initDeviceOptions();
281 emit linkAccepted();
283 imgProp = dp->findProp("EXPOSE_DURATION");
284 if (imgProp)
286 tmpAction = ksw->actionCollection()->action("capture_sequence");
287 if (!tmpAction)
288 kdDebug() << "Warning: capture_sequence action not found" << endl;
289 else
290 tmpAction->setEnabled(true);
293 else
295 if (streamWindow)
297 //sNotifier->disconnect();
298 //dp->parentMgr->sNotifier->disconnect();
299 streamWindow->enableStream(false);
300 streamWindow->close();
302 //close(streamFD);
305 drivers->updateMenuActions();
306 ksw->map()->forceUpdateNow();
307 emit linkRejected();
309 break;
311 case VIDEO_STREAM:
312 lp = pp->findElement("ON");
313 if (!lp) return;
314 if (lp->state == PS_ON)
315 streamWindow->enableStream(true);
316 else
317 streamWindow->enableStream(false);
318 break;
320 default:
321 break;
326 void INDIStdDevice::streamDisabled()
328 INDI_P *pp;
329 INDI_E *el;
331 //pp = dp->findProp("CONNECTION");
332 //if (!pp) return;
333 //if (pp->state == PS_OFF) return;
335 pp = dp->findProp("VIDEO_STREAM");
336 if (!pp) return;
338 el = pp->findElement("OFF");
339 if (!el) return;
341 if (el->state == PS_ON)
342 return;
344 // Turn stream off
345 pp->newSwitch(1);
349 void INDIStdDevice::updateSequencePrefix(QString newPrefix)
351 seqPrefix = newPrefix;
353 seqLister->setNameFilter(QString("%1_*.fits").arg(seqPrefix));
355 seqCount = 0;
357 if (ISOMode) return;
359 seqLister->openURL(Options::fitsSaveDirectory());
361 checkSeqBoundary(seqLister->items());
365 void INDIStdDevice::checkSeqBoundary(const KFileItemList & items)
367 int newFileIndex;
368 QString tempName;
369 char *tempPrefix = new char[64];
371 // No need to check when in ISO mode
372 if (ISOMode)
373 return;
375 for ( KFileItemListIterator it( items ) ; it.current() ; ++it )
377 tempName = it.current()->name();
379 // find the prefix first
380 if (tempName.find(seqPrefix) == -1)
381 continue;
383 strncpy(tempPrefix, tempName.ascii(), 64);
384 tempPrefix[63] = '\0';
386 char * t = tempPrefix;
388 // skip chars
389 while (*t) { if (isdigit(*t)) break; t++; }
390 //tempPrefix = t;
392 newFileIndex = strtol(t, NULL, 10);
394 if (newFileIndex >= seqCount)
395 seqCount = newFileIndex + 1;
398 delete (tempPrefix);
402 void INDIStdDevice::updateTime()
404 INDI_P *pp;
405 INDI_E *lp;
407 pp = dp->findProp("TIME");
408 if (!pp) return;
410 lp = pp->findElement("UTC");
412 if (!lp) return;
414 QTime newTime( ksw->data()->ut().time());
415 ExtDate newDate( ksw->data()->ut().date());
417 lp->write_w->setText(QString("%1-%2-%3T%4:%5:%6").arg(newDate.year()).arg(newDate.month())
418 .arg(newDate.day()).arg(newTime.hour())
419 .arg(newTime.minute()).arg(newTime.second()));
420 pp->newText();
422 pp = dp->findProp("SDTIME");
423 if (!pp) return;
424 lp = pp->findElement("LST");
425 if (!lp) return;
427 lp->write_w->setText(ksw->LST()->toHMSString());
428 pp->newText();
431 void INDIStdDevice::updateLocation()
433 INDI_P *pp;
434 INDI_E * latEle, * longEle;
435 GeoLocation *geo = ksw->geo();
437 pp = dp->findProp("GEOGRAPHIC_COORD");
438 if (!pp) return;
440 dms tempLong (geo->lng()->degree(), geo->lng()->arcmin(), geo->lng()->arcsec());
441 dms fullCir(360,0,0);
443 if (tempLong.degree() < 0)
444 tempLong.setD ( fullCir.Degrees() + tempLong.Degrees());
446 latEle = pp->findElement("LAT");
447 if (!latEle) return;
448 longEle = pp->findElement("LONG");
449 if (!longEle) return;
451 longEle->write_w->setText(QString("%1:%2:%3").arg(tempLong.degree()).arg(tempLong.arcmin()).arg(tempLong.arcsec()));
452 latEle->write_w->setText(QString("%1:%2:%3").arg(geo->lat()->degree()).arg(geo->lat()->arcmin()).arg(geo->lat()->arcsec()));
454 pp->newText();
458 void INDIStdDevice::registerProperty(INDI_P *pp)
460 INDI_E * portEle;
461 INDIDriver *drivers = ksw->getINDIDriver();
462 QString str;
464 switch (pp->stdID)
466 case DEVICE_PORT:
467 portEle = pp->findElement("PORT");
468 if (!portEle) return;
470 if (drivers)
472 for (unsigned int i=0; i < drivers->devices.size(); i++)
474 if (drivers->devices[i]->mgrID == dp->parentMgr->mgrID)
476 if (drivers->devices[i]->deviceType == KSTARS_TELESCOPE)
478 portEle->read_w->setText( Options::indiTelescopePort() );
479 portEle->write_w->setText( Options::indiTelescopePort() );
480 portEle->text = Options::indiTelescopePort();
481 break;
483 else if (drivers->devices[i]->deviceType == KSTARS_VIDEO)
485 portEle->read_w->setText( Options::indiVideoPort() );
486 portEle->write_w->setText( Options::indiVideoPort() );
487 portEle->text = Options::indiVideoPort();
488 break;
493 break;
499 void INDIStdDevice::initDeviceOptions()
502 INDI_P *prop;
504 initDevCounter = 0;
506 if ( Options::indiAutoTime() )
508 prop = dp->findProp("TIME");
509 if (prop)
511 updateTime();
512 initDevCounter += 5;
516 if ( Options::indiAutoGeo() )
518 prop = dp->findProp("GEOGRAPHIC_COORD");
519 if (prop)
521 updateLocation();
522 initDevCounter += 2;
526 if ( Options::indiMessages() )
527 ksw->statusBar()->changeItem( i18n("%1 is online.").arg(dp->name), 0);
529 ksw->map()->forceUpdateNow();
532 void INDIStdDevice::handleDevCounter()
535 if (initDevCounter <= 0)
536 return;
538 initDevCounter--;
540 if ( initDevCounter == 0 && Options::indiMessages() )
541 ksw->statusBar()->changeItem( i18n("%1 is online and ready.").arg(dp->name), 0);
545 bool INDIStdDevice::handleNonSidereal(SkyObject *o)
547 if (!o)
548 return false;
550 int trackIndex=0;
552 kdDebug() << "Object of type " << o->typeName() << endl;
553 //TODO Meade claims that the library access is available to
554 // all telescopes, which is unture. Only classic meade support
555 // that. They claim that library funcion will be available to all
556 // in "later" firmware revisions for the autostar and GPS.
557 // As a temprory solution, I'm going to explicity check for the
558 // device name which ideally I'm not supposed to do since all properties
559 // should be defined from the INDI driver, but since the INDI autostar
560 // and gps define the library functions (based on Meade's future claims)
561 // I will check the device name until Meade's respondes to my query.
563 // Update: Solution
564 // Only Meade Classic will offer an explicit SOLAR_SYSTEM property. If such a property exists
565 // then we take advantage of it. Otherwise, we send RA/DEC to the telescope and start a timer
566 // based on the object type. Objects with high proper motions will require faster updates.
567 // handle Non Sideral is ONLY called when tracking an object, not slewing.
570 INDI_P *prop = dp->findProp(QString("SOLAR_SYSTEM"));
571 INDI_P *setMode = dp->findProp(QString("ON_COORD_SET"));
573 // If the device support it
574 if (prop && setMode)
576 for (unsigned int i=0; i < setMode->el.count(); i++)
577 if (setMode->el.at(i)->name == "TRACK")
578 { trackIndex = i; break; }
580 kdDebug() << "Device supports SOLAR_SYSTEM property" << endl;
582 for (unsigned int i=0; i < prop->el.count(); i++)
583 if (o->name().lower() == prop->el.at(i)->label.lower())
585 prop->newSwitch(i);
586 setMode->newSwitch(trackIndex);
587 return true;
591 kdDebug() << "Device doesn't support SOLAR_SYSTEM property, issuing a timer" << endl;
592 kdDebug() << "Starting timer for object of type " << o->typeName() << endl;
593 currentObject = o;
595 switch (currentObject->type())
597 // Planet/Moon
598 case 2:
599 kdDebug() << "Initiating pulse tracking for " << currentObject->name() << endl;
600 devTimer->start(INDI_PULSE_TRACKING);
601 break;
602 // Comet/Asteroid
603 case 9:
604 case 10:
605 kdDebug() << "Initiating pulse tracking for " << currentObject->name() << endl;
606 devTimer->start(INDI_PULSE_TRACKING);
607 break;
608 default:
609 break;
612 return false;
616 void INDIStdDevice::timerDone()
618 INDI_P *prop;
619 INDI_E *RAEle, *DecEle;
620 INDI_E *el;
621 bool useJ2000 = false;
623 if (!dp->isOn())
625 devTimer->stop();
626 return;
629 prop = dp->findProp("ON_COORD_SET");
630 if (prop == NULL || !currentObject)
631 return;
633 el = prop->findElement("TRACK");
634 if (!el) return;
636 if (el->state != PS_ON)
638 devTimer->stop();
639 return;
642 prop = dp->findProp("EQUATORIAL_EOD_COORD");
644 if (prop == NULL)
646 prop = dp->findProp("EQUATORIAL_COORD");
647 if (prop) useJ2000 = true;
650 if (prop == NULL || !currentObject)
651 return;
653 // wait until slew is done
654 if (prop->state == PS_BUSY)
655 return;
657 kdDebug() << "Timer called, starting processing" << endl;
659 SkyPoint sp(currentObject->ra(), currentObject->dec());
661 kdDebug() << "RA: " << currentObject->ra()->toHMSString() << " - DEC: " << currentObject->dec()->toDMSString() << endl;
662 kdDebug() << "Az: " << currentObject->az()->toHMSString() << " - Alt " << currentObject->alt()->toDMSString() << endl;
664 if (useJ2000)
665 sp.apparentCoord( ksw->data()->ut().djd() , (long double) J2000);
667 // We need to get from JNow (Skypoint) to J2000
668 // The ra0() of a skyPoint is the same as its JNow ra() without this process
670 // Use J2000 coordinate as required by INDI
671 RAEle = prop->findElement("RA");
672 if (!RAEle) return;
673 DecEle = prop->findElement("DEC");
674 if (!DecEle) return;
676 RAEle->write_w->setText(QString("%1:%2:%3").arg(sp.ra()->hour())
677 .arg(sp.ra()->minute())
678 .arg(sp.ra()->second()));
679 DecEle->write_w->setText(QString("%1:%2:%3").arg(sp.dec()->degree())
680 .arg(sp.dec()->arcmin())
681 .arg(sp.dec()->arcsec()));
682 prop->newText();
686 INDIStdProperty::INDIStdProperty(INDI_P *associatedProperty, KStars * kswPtr, INDIStdDevice *stdDevPtr)
688 pp = associatedProperty;
689 ksw = kswPtr;
690 stdDev = stdDevPtr;
693 INDIStdProperty::~INDIStdProperty()
698 void INDIStdProperty::newText()
700 INDI_E *lp;
701 INDIDriver *drivers = ksw->getINDIDriver();
703 switch (pp->stdID)
705 /* Set expose duration button to 'cancel' when busy */
706 case EXPOSE_DURATION:
707 pp->set_w->setText(i18n("Cancel"));
708 break;
710 /* Save Port name in KStars options */
711 case DEVICE_PORT:
712 lp = pp->findElement("PORT");
714 if (lp && drivers)
716 for (unsigned int i=0; i < drivers->devices.size(); i++)
718 if (drivers->devices[i]->mgrID == stdDev->dp->parentMgr->mgrID)
720 if (drivers->devices[i]->deviceType == KSTARS_TELESCOPE)
722 Options::setIndiTelescopePort( lp->text );
723 kdDebug() << "Setting telescope port " << lp->text << endl;
725 else if (drivers->devices[i]->deviceType == KSTARS_VIDEO)
727 Options::setIndiVideoPort( lp->text );
728 kdDebug() << "Setting video port " << lp->text << endl;
730 break;
735 break;
740 bool INDIStdProperty::convertSwitch(int switchIndex, INDI_E *lp)
743 INDI_E *RAEle, *DecEle;
744 INDI_P * prop;
745 SkyPoint sp;
746 bool useJ2000 = false;
748 switch (pp->stdID)
750 /* Handle Slew/Track/Sync */
751 case ON_COORD_SET:
752 // #1 set current object to NULL
753 stdDev->currentObject = NULL;
754 // #2 Deactivate timer if present
755 if (stdDev->devTimer->isActive())
756 stdDev->devTimer->stop();
758 prop = pp->pg->dp->findProp("EQUATORIAL_EOD_COORD");
759 if (prop == NULL)
761 prop = pp->pg->dp->findProp("EQUATORIAL_COORD");
762 if (prop == NULL)
763 return false;
764 else
765 useJ2000 = true;
768 RAEle = prop->findElement("RA");
769 if (!RAEle) return false;
770 DecEle = prop->findElement("DEC");
771 if (!DecEle) return false;
773 // Track is similar to slew, except that for non-sidereal objects
774 // it tracks the objects automatically via a timer.
775 if ((lp->name == "TRACK"))
776 if (stdDev->handleNonSidereal(ksw->map()->clickedObject()))
777 return true;
779 kdDebug() << "\n******** The point BEFORE it was precessed ********" << endl;
780 kdDebug() << "RA : " << ksw->map()->clickedPoint()->ra()->toHMSString() << " - DEC : " << ksw->map()->clickedPoint()->dec()->toDMSString() << endl;
783 // We need to get from JNow (Skypoint) to J2000
784 // The ra0() of a skyPoint is the same as its JNow ra() without this process
785 if (stdDev->currentObject)
786 sp.set (stdDev->currentObject->ra(), stdDev->currentObject->dec());
787 else
788 sp.set (ksw->map()->clickedPoint()->ra(), ksw->map()->clickedPoint()->dec());
790 if (useJ2000)
791 sp.apparentCoord(ksw->data()->ut().djd(), (long double) J2000);
793 // Use J2000 coordinate as required by INDI
794 RAEle->write_w->setText(QString("%1:%2:%3").arg(sp.ra()->hour()).arg(sp.ra()->minute()).arg(sp.ra()->second()));
795 DecEle->write_w->setText(QString("%1:%2:%3").arg(sp.dec()->degree()).arg(sp.dec()->arcmin()).arg(sp.dec()->arcsec()));
797 if (useJ2000)
799 kdDebug() << "\n******** The point AFTER it was precessed ********" << endl;
800 kdDebug() << "RA : " << sp.ra()->toHMSString() << " - DEC : " << sp.dec()->toDMSString() << endl;
804 //sp.apparentCoord((long double) J2000, ksw->data()->ut().djd());
805 //kdDebug() << "\n******** The point AFTER it was precessed AGAIN to JNOW ********" << endl;
806 //kdDebug() << "RA : " << sp.ra()->toHMSString() << " - DEC : " << sp.dec()->toDMSString() << endl;
808 pp->newSwitch(switchIndex);
809 prop->newText();
811 return true;
812 break;
814 /* Handle Abort */
815 case ABORT_MOTION:
816 kdDebug() << "Stopping timer." << endl;
817 stdDev->devTimer->stop();
818 pp->newSwitch(switchIndex);
819 return true;
820 break;
822 case MOVEMENT:
823 pp->newSwitch(switchIndex);
824 break;
826 default:
827 return false;
828 break;
831 return false;
835 // Return true if the complete operation is done here, or false if the operation is to be completed in the properties newSwitch()
836 bool INDIStdProperty::newSwitch(int id, INDI_E* el)
838 INDI_P *prop;
839 el=el;
841 switch (pp->stdID)
843 case CONNECTION:
844 if (id == 1)
845 stdDev->streamDisabled();
846 else
848 prop = pp->pg->dp->findProp("DEVICE_PORT");
849 if (prop)
850 prop->newText();
852 break;
853 case ABORT_MOTION:
854 case PARK:
855 case MOVEMENT:
856 //TODO add text in the status bar "Slew aborted."
857 stdDev->devTimer->stop();
858 break;
859 default:
860 break;
863 return false;
867 void INDIStdProperty::newTime()
869 INDI_E * timeEle;
870 INDI_P *SDProp;
872 timeEle = pp->findElement("UTC");
873 if (!timeEle) return;
875 TimeDialog timedialog ( ksw->data()->ut(), ksw );
877 if ( timedialog.exec() == QDialog::Accepted )
879 QTime newTime( timedialog.selectedTime() );
880 ExtDate newDate( timedialog.selectedDate() );
882 timeEle->write_w->setText(QString("%1-%2-%3T%4:%5:%6")
883 .arg(newDate.year()).arg(newDate.month())
884 .arg(newDate.day()).arg(newTime.hour())
885 .arg(newTime.minute()).arg(newTime.second()));
886 pp->newText();
888 else return;
890 SDProp = pp->pg->dp->findProp("SDTIME");
891 if (!SDProp) return;
892 timeEle = SDProp->findElement("LST");
893 if (!timeEle) return;
895 timeEle->write_w->setText(ksw->LST()->toHMSString());
896 SDProp->newText();
899 #include "indistd.moc"