You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdeedu/kstars/kstars/indistd.cpp

1046 lines
26 KiB

/* INDI STD
Copyright (C) 2003 Jasem Mutlaq (mutlaqja@ikarustech.com)
This apppication is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
2004-01-18: This class handles INDI Standard properties.
*/
#include "indistd.h"
#include "Options.h"
#include "indielement.h"
#include "indiproperty.h"
#include "indigroup.h"
#include "indidevice.h"
#include "indidriver.h"
#include "kstars.h"
#include "kstarsdata.h"
#include "skymap.h"
#include "skyobject.h"
#include "simclock.h"
#include "devicemanager.h"
#include "timedialog.h"
#include "streamwg.h"
#include "ccdpreviewwg.h"
#include "fitsviewer.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <ctype.h>
#include <zlib.h>
#include <stdlib.h>
#include <tqtimer.h>
#include <tqlabel.h>
#include <tqfont.h>
#include <tqeventloop.h>
#include <tqsocketnotifier.h>
#include <tdelocale.h>
#include <kdebug.h>
#include <kpushbutton.h>
#include <klineedit.h>
#include <kstatusbar.h>
#include <tdemessagebox.h>
#include <tdeapplication.h>
#include <kprogress.h>
#include <kurl.h>
#include <kdirlister.h>
#include <tdeaction.h>
#define STD_BUFFER_SIZ 1024000
#define FRAME_ILEN 1024
INDIStdDevice::INDIStdDevice(INDI_D *associatedDevice, KStars * kswPtr)
{
dp = associatedDevice;
ksw = kswPtr;
initDevCounter = 0;
setCount = 0;
batchMode = false;
ISOMode = false;
currentObject = NULL;
streamWindow = new StreamWG(this, ksw);
CCDPreviewWindow = new CCDPreviewWG(this, ksw);
devTimer = new TQTimer(this);
seqLister = new KDirLister();
telescopeSkyObject = new SkyObject(0, 0, 0, 0, i18n("Telescope"));
ksw->data()->appendTelescopeObject(telescopeSkyObject);
connect( devTimer, TQ_SIGNAL(timeout()), this, TQ_SLOT(timerDone()) );
connect( seqLister, TQ_SIGNAL(newItems (const KFileItemList & )), this, TQ_SLOT(checkSeqBoundary(const KFileItemList &)));
downloadDialog = new KProgressDialog(NULL, 0, i18n("INDI"), i18n("Downloading Data..."));
downloadDialog->cancel();
parser = newLilXML();
}
INDIStdDevice::~INDIStdDevice()
{
streamWindow->enableStream(false);
streamWindow->close();
CCDPreviewWindow->enableStream(false);
CCDPreviewWindow->close();
streamDisabled();
delete (seqLister);
}
void INDIStdDevice::handleBLOB(unsigned char *buffer, int bufferSize, TQString dataFormat)
{
if (dataFormat == ".fits") dataType = DATA_FITS;
else if (dataFormat == ".stream") dataType = DATA_STREAM;
else if (dataFormat == ".ccdpreview") dataType = DATA_CCDPREVIEW;
else dataType = DATA_OTHER;
if (dataType == DATA_STREAM)
{
if (!streamWindow->processStream)
return;
streamWindow->show();
streamWindow->streamFrame->newFrame( buffer, bufferSize, streamWindow->streamWidth, streamWindow->streamHeight);
}
else if (dataType == DATA_CCDPREVIEW)
{
if (!CCDPreviewWindow->processStream)
return;
CCDPreviewWindow->show();
CCDPreviewWindow->streamFrame->newFrame( buffer, bufferSize, CCDPreviewWindow->streamWidth, CCDPreviewWindow->streamHeight);
}
else if (dataType == DATA_FITS || dataType == DATA_OTHER)
{
char filename[256];
FILE *fitsTempFile;
int fd, nr, n=0;
TQString currentDir = Options::fitsSaveDirectory();
streamWindow->close();
if (dataType == DATA_FITS && !batchMode && Options::indiFITSDisplay())
{
strcpy(filename, "/tmp/fitsXXXXXX");
if ((fd = mkstemp(filename)) < 0)
{
KMessageBox::error(NULL, "Error making temporary filename.");
return;
}
close(fd);
}
else
{
char ts[32];
struct tm *tp;
time_t t;
time (&t);
tp = gmtime (&t);
if (currentDir[currentDir.length() -1] == '/')
currentDir.truncate(currentDir.length() - 1);
strncpy(filename, currentDir.ascii(), currentDir.length());
filename[currentDir.length()] = '\0';
if (dataType == DATA_FITS)
{
char tempFileStr[256];
strncpy(tempFileStr, filename, 256);
if ( batchMode && !ISOMode)
snprintf(filename, sizeof(filename), "%s/%s_%02d.fits", tempFileStr, seqPrefix.ascii(), setCount);
else if (!batchMode && !Options::indiFITSDisplay())
{
strftime (ts, sizeof(ts), "%Y-%m-%dT%H:%M:%S", tp);
snprintf(filename, sizeof(filename), "%s/file_%s.fits", tempFileStr, ts);
}
else
{
strftime (ts, sizeof(ts), "%Y-%m-%dT%H:%M:%S", tp);
snprintf(filename, sizeof(filename), "%s/%s_%02d_%s.fits", tempFileStr, seqPrefix.ascii(), setCount, ts);
}
setCount++;
}
else
{
strftime (ts, sizeof(ts), "/file-%Y-%m-%dT%H:%M:%S.", tp);
strncat(filename, ts, sizeof(ts));
strncat(filename, dataFormat.ascii(), 10);
}
}
fitsTempFile = fopen(filename, "w");
if (fitsTempFile == NULL) return;
for (nr=0; nr < (int) bufferSize; nr += n)
n = fwrite( ((unsigned char *) buffer) + nr, 1, bufferSize - nr, fitsTempFile);
fclose(fitsTempFile);
// We're done if we have DATA_OTHER
if (dataType == DATA_OTHER)
{
ksw->statusBar()->changeItem( i18n("Data file saved to %1").arg(filename), 0);
return;
}
else if (dataType == DATA_FITS && (batchMode || !Options::indiFITSDisplay()))
{
ksw->statusBar()->changeItem( i18n("FITS file saved to %1").arg(filename), 0);
emit FITSReceived(dp->label);
return;
}
KURL fileURL(filename);
FITSViewer * fv = new FITSViewer(&fileURL, ksw);
fv->fitsChange();
fv->show();
}
}
/* Process standard Text and Number properties arrives from the driver */
void INDIStdDevice::setTextValue(INDI_P *pp)
{
INDI_E *el;
int wd, ht, bpp, bo, mu;
long mgd;
double fwhm;
int d, m, y, min, sec, hour;
ExtDate indiDate;
TQTime indiTime;
KStarsDateTime indiDateTime;
switch (pp->stdID)
{
case TIME:
if ( Options::indiAutoTime() )
handleDevCounter();
// Update KStars time once we receive update from INDI
el = pp->findElement("UTC");
if (!el) return;
sscanf(el->text.ascii(), "%d%*[^0-9]%d%*[^0-9]%dT%d%*[^0-9]%d%*[^0-9]%d", &y, &m, &d, &hour, &min, &sec);
indiDate.setYMD(y, m, d);
indiTime.setHMS(hour, min, sec);
indiDateTime.setDate(indiDate);
indiDateTime.setTime(indiTime);
ksw->data()->changeDateTime(indiDateTime);
ksw->data()->syncLST();
break;
case SDTIME:
if ( Options::indiAutoTime())
handleDevCounter();
break;
case GEOGRAPHIC_COORD:
if ( Options::indiAutoGeo() )
handleDevCounter();
break;
case CCD_EXPOSE_DURATION:
if (pp->state == PS_IDLE || pp->state == PS_OK)
pp->set_w->setText(i18n("Start"));
break;
case CCD_FRAME:
el = pp->findElement("WIDTH");
if (!el) return;
wd = (int) el->value;
el = pp->findElement("HEIGHT");
if (!el) return;
ht = (int) el->value;
streamWindow->setSize(wd, ht);
//streamWindow->allocateStreamBuffer();
break;
case CCDPREVIEW_CTRL:
el = pp->findElement("WIDTH");
if (!el) return;
wd = (int) el->value;
el = pp->findElement("HEIGHT");
if (!el) return;
ht = (int) el->value;
el = pp->findElement("BYTEORDER");
if (!el) return;
bo = (int) el->value;
el = pp->findElement("BYTESPERPIXEL");
if (!el) return;
bpp = (int) el->value;
el = pp->findElement("MAXGOODDATA");
if (!el) return;
mgd = (long) el->value;
CCDPreviewWindow->setCtrl(wd, ht, bo ,bpp,mgd);
break;
case CCD_INFO:
el = pp->findElement("CCD_FWHM_PIXEL");
if (!el) return;
fwhm = el->value;
el = pp->findElement("CCD_PIXEL_SIZE");
if (!el) return;
mu = (int) el->value;
CCDPreviewWindow->setCCDInfo(fwhm, mu);
break;
case EQUATORIAL_COORD:
case EQUATORIAL_EOD_COORD:
if (!dp->isOn()) break;
el = pp->findElement("RA");
if (!el) return;
telescopeSkyObject->setRA(el->value);
el = pp->findElement("DEC");
if (!el) return;
telescopeSkyObject->setDec(el->value);
telescopeSkyObject->EquatorialToHorizontal(ksw->LST(), ksw->geo()->lat());
// Force immediate update of skymap if the focus object is our telescope.
if (ksw->map()->focusObject() == telescopeSkyObject)
ksw->map()->updateFocus();
else
ksw->map()->update();
break;
case HORIZONTAL_COORD:
if (!dp->isOn()) break;
el = pp->findElement("ALT");
if (!el) return;
telescopeSkyObject->setAlt(el->value);
el = pp->findElement("AZ");
if (!el) return;
telescopeSkyObject->setAz(el->value);
telescopeSkyObject->HorizontalToEquatorial(ksw->LST(), ksw->geo()->lat());
// Force immediate update of skymap if the focus object is our telescope.
if (ksw->map()->focusObject() == telescopeSkyObject)
ksw->map()->updateFocus();
else
ksw->map()->update();
break;
default:
break;
}
}
void INDIStdDevice::setLabelState(INDI_P *pp)
{
INDI_E *lp;
INDI_P *imgProp;
TDEAction *tmpAction;
INDIDriver *drivers = ksw->getINDIDriver();
TQFont buttonFont;
switch (pp->stdID)
{
case CONNECTION:
lp = pp->findElement("CONNECT");
if (!lp) return;
if (lp->state == PS_ON)
{
initDeviceOptions();
emit linkAccepted();
imgProp = dp->findProp("CCD_EXPOSE_DURATION");
if (imgProp)
{
tmpAction = ksw->actionCollection()->action("capture_sequence");
if (!tmpAction)
kdDebug() << "Warning: capture_sequence action not found" << endl;
else
tmpAction->setEnabled(true);
}
}
else
{
if (streamWindow)
{
//sNotifier->disconnect();
//dp->parentMgr->sNotifier->disconnect();
streamWindow->enableStream(false);
streamWindow->close();
//close(streamFD);
}
if (ksw->map()->focusObject() == telescopeSkyObject)
{
ksw->map()->stopTracking();
ksw->map()->setFocusObject(NULL);
}
drivers->updateMenuActions();
ksw->map()->forceUpdateNow();
emit linkRejected();
}
break;
case VIDEO_STREAM:
lp = pp->findElement("ON");
if (!lp) return;
if (lp->state == PS_ON)
streamWindow->enableStream(true);
else
streamWindow->enableStream(false);
break;
case CCDPREVIEW_STREAM:
lp = pp->findElement("ON");
if (!lp) return;
if (lp->state == PS_ON)
CCDPreviewWindow->enableStream(true);
else
CCDPreviewWindow->enableStream(false);
break;
default:
break;
}
}
void INDIStdDevice::streamDisabled()
{
INDI_P *pp;
INDI_E *el;
//pp = dp->findProp("CONNECTION");
//if (!pp) return;
//if (pp->state == PS_OFF) return;
pp = dp->findProp("VIDEO_STREAM");
if (!pp) return;
el = pp->findElement("OFF");
if (!el) return;
if (el->state == PS_ON)
return;
// Turn stream off
pp->newSwitch(1);
}
void INDIStdDevice::updateSequencePrefix(TQString newPrefix)
{
seqPrefix = newPrefix;
seqLister->setNameFilter(TQString("%1_*.fits").arg(seqPrefix));
setCount = 0;
if (ISOMode) return;
seqLister->openURL(Options::fitsSaveDirectory());
checkSeqBoundary(seqLister->items());
}
void INDIStdDevice::checkSeqBoundary(const KFileItemList & items)
{
int newFileIndex;
TQString tempName;
char *tempPrefix = new char[64];
// No need to check when in ISO mode
if (ISOMode)
return;
for ( KFileItemListIterator it( items ) ; it.current() ; ++it )
{
tempName = it.current()->name();
// find the prefix first
if (tempName.find(seqPrefix) == -1)
continue;
strncpy(tempPrefix, tempName.ascii(), 64);
tempPrefix[63] = '\0';
char * t = tempPrefix;
// skip chars
while (*t) { if (isdigit(*t)) break; t++; }
//tempPrefix = t;
newFileIndex = strtol(t, NULL, 10);
if (newFileIndex >= setCount)
setCount = newFileIndex + 1;
}
delete [] (tempPrefix);
}
void INDIStdDevice::updateTime()
{
INDI_P *pp;
INDI_E *lp;
pp = dp->findProp("TIME");
if (!pp) return;
lp = pp->findElement("UTC");
if (!lp) return;
TQTime newTime( ksw->data()->ut().time());
ExtDate newDate( ksw->data()->ut().date());
lp->write_w->setText(TQString("%1-%2-%3T%4:%5:%6").arg(newDate.year()).arg(newDate.month())
.arg(newDate.day()).arg(newTime.hour())
.arg(newTime.minute()).arg(newTime.second()));
pp->newText();
pp = dp->findProp("SDTIME");
if (!pp) return;
lp = pp->findElement("LST");
if (!lp) return;
lp->write_w->setText(ksw->LST()->toHMSString());
pp->newText();
}
void INDIStdDevice::updateLocation()
{
INDI_P *pp;
INDI_E * latEle, * longEle;
GeoLocation *geo = ksw->geo();
pp = dp->findProp("GEOGRAPHIC_COORD");
if (!pp) return;
dms tempLong (geo->lng()->degree(), geo->lng()->arcmin(), geo->lng()->arcsec());
dms fullCir(360,0,0);
if (tempLong.degree() < 0)
tempLong.setD ( fullCir.Degrees() + tempLong.Degrees());
latEle = pp->findElement("LAT");
if (!latEle) return;
longEle = pp->findElement("LONG");
if (!longEle) return;
longEle->write_w->setText(TQString("%1:%2:%3").arg(tempLong.degree()).arg(tempLong.arcmin()).arg(tempLong.arcsec()));
latEle->write_w->setText(TQString("%1:%2:%3").arg(geo->lat()->degree()).arg(geo->lat()->arcmin()).arg(geo->lat()->arcsec()));
pp->newText();
}
void INDIStdDevice::registerProperty(INDI_P *pp)
{
INDI_E * portEle;
INDIDriver *drivers = ksw->getINDIDriver();
TQString str;
switch (pp->stdID)
{
case DEVICE_PORT:
portEle = pp->findElement("PORT");
if (!portEle) return;
if (drivers)
{
for (unsigned int i=0; i < drivers->devices.size(); i++)
{
if (drivers->devices[i]->mgrID == dp->parentMgr->mgrID)
{
if (drivers->devices[i]->deviceType == KSTARS_TELESCOPE)
{
portEle->read_w->setText( Options::indiTelescopePort() );
portEle->write_w->setText( Options::indiTelescopePort() );
portEle->text = Options::indiTelescopePort();
break;
}
else if (drivers->devices[i]->deviceType == KSTARS_VIDEO)
{
portEle->read_w->setText( Options::indiVideoPort() );
portEle->write_w->setText( Options::indiVideoPort() );
portEle->text = Options::indiVideoPort();
break;
}
}
}
}
break;
}
}
void INDIStdDevice::initDeviceOptions()
{
INDI_P *prop;
initDevCounter = 0;
if ( Options::indiAutoTime() )
{
prop = dp->findProp("TIME");
if (prop)
{
updateTime();
initDevCounter += 5;
}
}
if ( Options::indiAutoGeo() )
{
prop = dp->findProp("GEOGRAPHIC_COORD");
if (prop)
{
updateLocation();
initDevCounter += 2;
}
}
if ( Options::indiMessages() )
ksw->statusBar()->changeItem( i18n("%1 is online.").arg(dp->name), 0);
ksw->map()->forceUpdateNow();
}
void INDIStdDevice::handleDevCounter()
{
if (initDevCounter <= 0)
return;
initDevCounter--;
if ( initDevCounter == 0 && Options::indiMessages() )
ksw->statusBar()->changeItem( i18n("%1 is online and ready.").arg(dp->name), 0);
}
bool INDIStdDevice::handleNonSidereal()
{
if (!currentObject)
return false;
int trackIndex=0;
INDI_E *nameEle;
kdDebug() << "Object of type " << currentObject->typeName() << endl;
//TODO Meade claims that the library access is available to
// all telescopes, which is unture. Only classic meade support
// that. They claim that library funcion will be available to all
// in "later" firmware revisions for the autostar and GPS.
// As a temprory solution, I'm going to explicity check for the
// device name which ideally I'm not supposed to do since all properties
// should be defined from the INDI driver, but since the INDI autostar
// and gps define the library functions (based on Meade's future claims)
// I will check the device name until Meade's respondes to my query.
// Update: Solution
// Only Meade Classic will offer an explicit SOLAR_SYSTEM property. If such a property exists
// then we take advantage of it. Otherwise, we send RA/DEC to the telescope and start a timer
// based on the object type. Objects with high proper motions will require faster updates.
// handle Non Sideral is ONLY called when tracking an object, not slewing.
INDI_P *prop = dp->findProp(TQString("SOLAR_SYSTEM"));
INDI_P *setMode = dp->findProp(TQString("ON_COORD_SET"));
// If the device support it
if (prop && setMode)
{
for (unsigned int i=0; i < setMode->el.count(); i++)
if (setMode->el.at(i)->name == "TRACK")
{ trackIndex = i; break; }
kdDebug() << "Device supports SOLAR_SYSTEM property" << endl;
for (unsigned int i=0; i < prop->el.count(); i++)
if (currentObject->name().lower() == prop->el.at(i)->label.lower())
{
prop->newSwitch(i);
setMode->newSwitch(trackIndex);
/* Send object name if available */
nameEle = dp->findElem("OBJECT_NAME");
if (nameEle && nameEle->pp->perm != PP_RO)
{
nameEle->write_w->setText(currentObject->name());
nameEle->pp->newText();
}
return true;
}
}
kdDebug() << "Device doesn't support SOLAR_SYSTEM property, issuing a timer" << endl;
kdDebug() << "Starting timer for object of type " << currentObject->typeName() << endl;
switch (currentObject->type())
{
// Planet/Moon
case 2:
kdDebug() << "Initiating pulse tracking for " << currentObject->name() << endl;
devTimer->start(INDI_PULSE_TRACKING);
break;
// Comet/Asteroid
case 9:
case 10:
kdDebug() << "Initiating pulse tracking for " << currentObject->name() << endl;
devTimer->start(INDI_PULSE_TRACKING);
break;
default:
break;
}
return false;
}
void INDIStdDevice::timerDone()
{
INDI_P *prop;
INDI_E *RAEle, *DecEle;
INDI_E *el;
bool useJ2000 = false;
if (!dp->isOn())
{
devTimer->stop();
return;
}
prop = dp->findProp("ON_COORD_SET");
if (prop == NULL || !currentObject)
return;
el = prop->findElement("TRACK");
if (!el) return;
if (el->state != PS_ON)
{
devTimer->stop();
return;
}
prop = dp->findProp("EQUATORIAL_EOD_COORD");
if (prop == NULL)
{
prop = dp->findProp("EQUATORIAL_COORD");
if (prop) useJ2000 = true;
}
if (prop == NULL || !currentObject)
return;
// wait until slew is done
if (prop->state == PS_BUSY)
return;
kdDebug() << "Timer called, starting processing" << endl;
SkyPoint sp(currentObject->ra(), currentObject->dec());
kdDebug() << "RA: " << currentObject->ra()->toHMSString() << " - DEC: " << currentObject->dec()->toDMSString() << endl;
kdDebug() << "Az: " << currentObject->az()->toHMSString() << " - Alt " << currentObject->alt()->toDMSString() << endl;
if (useJ2000)
{
sp.set(currentObject->ra(), currentObject->dec());
sp.apparentCoord( ksw->data()->ut().djd() , (long double) J2000);
}
// We need to get from JNow (Skypoint) to J2000
// The ra0() of a skyPoint is the same as its JNow ra() without this process
// Use J2000 coordinate as required by INDI
RAEle = prop->findElement("RA");
if (!RAEle) return;
DecEle = prop->findElement("DEC");
if (!DecEle) return;
RAEle->write_w->setText(TQString("%1:%2:%3").arg(sp.ra()->hour())
.arg(sp.ra()->minute())
.arg(sp.ra()->second()));
DecEle->write_w->setText(TQString("%1:%2:%3").arg(sp.dec()->degree())
.arg(sp.dec()->arcmin())
.arg(sp.dec()->arcsec()));
prop->newText();
}
INDIStdProperty::INDIStdProperty(INDI_P *associatedProperty, KStars * kswPtr, INDIStdDevice *stdDevPtr)
{
pp = associatedProperty;
ksw = kswPtr;
stdDev = stdDevPtr;
}
INDIStdProperty::~INDIStdProperty()
{
}
void INDIStdProperty::newText()
{
INDI_E *lp;
INDIDriver *drivers = ksw->getINDIDriver();
switch (pp->stdID)
{
/* Set expose duration button to 'cancel' when busy */
case CCD_EXPOSE_DURATION:
pp->set_w->setText(i18n("Cancel"));
break;
/* Save Port name in KStars options */
case DEVICE_PORT:
lp = pp->findElement("PORT");
if (lp && drivers)
{
for (unsigned int i=0; i < drivers->devices.size(); i++)
{
if (drivers->devices[i]->mgrID == stdDev->dp->parentMgr->mgrID)
{
if (drivers->devices[i]->deviceType == KSTARS_TELESCOPE)
{
Options::setIndiTelescopePort( lp->text );
kdDebug() << "Setting telescope port " << lp->text << endl;
}
else if (drivers->devices[i]->deviceType == KSTARS_VIDEO)
{
Options::setIndiVideoPort( lp->text );
kdDebug() << "Setting video port " << lp->text << endl;
}
break;
}
}
}
break;
}
}
bool INDIStdProperty::convertSwitch(int switchIndex, INDI_E *lp)
{
INDI_E *RAEle(NULL), *DecEle(NULL), *AzEle(NULL), *AltEle(NULL), *nameEle(NULL);
INDI_P * prop;
SkyPoint sp;
int selectedCoord=0; /* 0 for Equatorial, 1 for Horizontal */
bool useJ2000 (false);
switch (pp->stdID)
{
/* Handle Slew/Track/Sync */
case ON_COORD_SET:
// #1 set current object to NULL
stdDev->currentObject = NULL;
// #2 Deactivate timer if present
if (stdDev->devTimer->isActive())
stdDev->devTimer->stop();
prop = pp->pg->dp->findProp("EQUATORIAL_EOD_COORD");
if (prop == NULL)
{
prop = pp->pg->dp->findProp("EQUATORIAL_COORD");
if (prop == NULL)
{
prop = pp->pg->dp->findProp("HORIZONTAL_COORD");
if (prop == NULL)
return false;
else
selectedCoord = 1; /* Select horizontal */
}
else
useJ2000 = true;
}
switch (selectedCoord)
{
// Equatorial
case 0:
if (prop->perm == PP_RO) return false;
RAEle = prop->findElement("RA");
if (!RAEle) return false;
DecEle = prop->findElement("DEC");
if (!DecEle) return false;
break;
// Horizontal
case 1:
if (prop->perm == PP_RO) return false;
AzEle = prop->findElement("AZ");
if (!AzEle) return false;
AltEle = prop->findElement("ALT");
if (!AltEle) return false;
break;
}
stdDev->currentObject = ksw->map()->clickedObject();
// Track is similar to slew, except that for non-sidereal objects
// it tracks the objects automatically via a timer.
if ((lp->name == "TRACK"))
if (stdDev->handleNonSidereal())
return true;
/* Send object name if available */
if (stdDev->currentObject)
{
nameEle = pp->pg->dp->findElem("OBJECT_NAME");
if (nameEle && nameEle->pp->perm != PP_RO)
{
nameEle->write_w->setText(stdDev->currentObject->name());
nameEle->pp->newText();
}
}
switch (selectedCoord)
{
case 0:
if (stdDev->currentObject)
sp.set (stdDev->currentObject->ra(), stdDev->currentObject->dec());
else
sp.set (ksw->map()->clickedPoint()->ra(), ksw->map()->clickedPoint()->dec());
if (useJ2000)
sp.apparentCoord(ksw->data()->ut().djd(), (long double) J2000);
RAEle->write_w->setText(TQString("%1:%2:%3").arg(sp.ra()->hour()).arg(sp.ra()->minute()).arg(sp.ra()->second()));
DecEle->write_w->setText(TQString("%1:%2:%3").arg(sp.dec()->degree()).arg(sp.dec()->arcmin()).arg(sp.dec()->arcsec()));
break;
case 1:
if (stdDev->currentObject)
{
sp.setAz(*stdDev->currentObject->az());
sp.setAlt(*stdDev->currentObject->alt());
}
else
{
sp.setAz(*ksw->map()->clickedPoint()->az());
sp.setAlt(*ksw->map()->clickedPoint()->alt());
}
AzEle->write_w->setText(TQString("%1:%2:%3").arg(sp.az()->degree()).arg(sp.az()->arcmin()).arg(sp.az()->arcsec()));
AltEle->write_w->setText(TQString("%1:%2:%3").arg(sp.alt()->degree()).arg(sp.alt()->arcmin()).arg(sp.alt()->arcsec()));
break;
}
pp->newSwitch(switchIndex);
prop->newText();
return true;
break;
/* Handle Abort */
case ABORT_MOTION:
kdDebug() << "Stopping timer." << endl;
stdDev->devTimer->stop();
pp->newSwitch(switchIndex);
return true;
break;
case MOVEMENT:
pp->newSwitch(switchIndex);
break;
default:
return false;
break;
}
return false;
}
// Return true if the complete operation is done here, or false if the operation is to be completed in the properties newSwitch()
bool INDIStdProperty::newSwitch(int id, INDI_E* el)
{
INDI_P *prop;
el=el;
switch (pp->stdID)
{
case CONNECTION:
if (id == 1)
stdDev->streamDisabled();
else
{
prop = pp->pg->dp->findProp("DEVICE_PORT");
if (prop)
prop->newText();
}
break;
case ABORT_MOTION:
case PARK:
case MOVEMENT:
//TODO add text in the status bar "Slew aborted."
stdDev->devTimer->stop();
break;
default:
break;
}
return false;
}
void INDIStdProperty::newTime()
{
INDI_E * timeEle;
INDI_P *SDProp;
timeEle = pp->findElement("UTC");
if (!timeEle) return;
TimeDialog timedialog ( ksw->data()->ut(), ksw );
if ( timedialog.exec() == TQDialog::Accepted )
{
TQTime newTime( timedialog.selectedTime() );
ExtDate newDate( timedialog.selectedDate() );
timeEle->write_w->setText(TQString("%1-%2-%3T%4:%5:%6")
.arg(newDate.year()).arg(newDate.month())
.arg(newDate.day()).arg(newTime.hour())
.arg(newTime.minute()).arg(newTime.second()));
pp->newText();
}
else return;
SDProp = pp->pg->dp->findProp("SDTIME");
if (!SDProp) return;
timeEle = SDProp->findElement("LST");
if (!timeEle) return;
timeEle->write_w->setText(ksw->LST()->toHMSString());
SDProp->newText();
}
#include "indistd.moc"