/***************************************************************************
INDI Driver
- - - - - - - - - - - - - - - - - - -
begin : Wed May 7 th 2003
copyright : ( C ) 2001 by Jasem Mutlaq
email : mutlaqja @ ikarustech . com
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/***************************************************************************
* *
* This program 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 . *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "indidriver.h"
# include "indimenu.h"
# include "indihostconf.h"
# include "devicemanager.h"
# include "indidevice.h"
# include "indi/indicom.h"
# include "kstars.h"
# include "kstarsdata.h"
# include "ksutils.h"
# include <tqfile.h>
# include <tqvaluelist.h>
# include <tqcstring.h>
# include <tqradiobutton.h>
# include <tqtextedit.h>
# include <kiconloader.h>
# include <klistview.h>
# include <kpopupmenu.h>
# include <kprocess.h>
# include <kmessagebox.h>
# include <kpushbutton.h>
# include <klineedit.h>
# include <kstandarddirs.h>
# include <kaction.h>
# include <kextsock.h>
# include <unistd.h>
/*
* The dialog will by default be modeless , unless you set ' modal ' to
* TRUE to construct a modal dialog .
*/
INDIDriver : : INDIDriver ( TQWidget * parent ) : devManager ( parent )
{
lastPort = 7263 ;
lastGroup = NULL ;
lastDevice = NULL ;
ksw = ( KStars * ) parent ;
//FormLayout = makeVBoxMainWidget();
localListView - > setSorting ( - 1 ) ;
clientListView - > setSorting ( - 1 ) ;
KIconLoader * icons = KGlobal : : iconLoader ( ) ;
runningPix = icons - > loadIcon ( " exec " , KIcon : : Small ) ;
stopPix = icons - > loadIcon ( " button_cancel " , KIcon : : Small ) ;
localMode = icons - > loadIcon ( " network_local " , KIcon : : Small ) ;
serverMode = icons - > loadIcon ( " network " , KIcon : : Small ) ;
LocalpopMenu = new KPopupMenu ( localListView ) ;
LocalpopMenu - > insertItem ( runningPix , i18n ( " Run Service " ) , 0 ) ;
LocalpopMenu - > insertItem ( stopPix , i18n ( " Stop Service " ) , 1 ) ;
localListView - > setRootIsDecorated ( true ) ;
connected = icons - > loadIcon ( " connect_established " , KIcon : : Small ) ;
disconnected = icons - > loadIcon ( " connect_no " , KIcon : : Small ) ;
establishConnection = icons - > loadIcon ( " connect_creating " , KIcon : : Small ) ;
ClientpopMenu = new KPopupMenu ( clientListView ) ;
ClientpopMenu - > insertItem ( establishConnection , i18n ( " Connect " ) , 0 ) ;
ClientpopMenu - > insertItem ( disconnected , i18n ( " Disconnect " ) , 1 ) ;
for ( uint i = 0 ; i < ksw - > data ( ) - > INDIHostsList . count ( ) ; i + + )
{
TQListViewItem * item = new TQListViewItem ( clientListView , lastGroup ) ;
lastGroup = item ;
item - > setPixmap ( 0 , disconnected ) ;
item - > setText ( 1 , ksw - > data ( ) - > INDIHostsList . at ( i ) - > name ) ;
item - > setText ( 2 , ksw - > data ( ) - > INDIHostsList . at ( i ) - > portnumber ) ;
}
lastGroup = NULL ;
TQObject : : connect ( addB , TQT_SIGNAL ( clicked ( ) ) , this , TQT_SLOT ( addINDIHost ( ) ) ) ;
TQObject : : connect ( modifyB , TQT_SIGNAL ( clicked ( ) ) , this , TQT_SLOT ( modifyINDIHost ( ) ) ) ;
TQObject : : connect ( removeB , TQT_SIGNAL ( clicked ( ) ) , this , TQT_SLOT ( removeINDIHost ( ) ) ) ;
TQObject : : connect ( clientListView , TQT_SIGNAL ( rightButtonPressed ( TQListViewItem * , const TQPoint & , int ) ) , this , TQT_SLOT ( ClientprocessRightButton ( TQListViewItem * , const TQPoint & , int ) ) ) ;
TQObject : : connect ( ClientpopMenu , TQT_SIGNAL ( activated ( int ) ) , this , TQT_SLOT ( processHostStatus ( int ) ) ) ;
TQObject : : connect ( localListView , TQT_SIGNAL ( rightButtonPressed ( TQListViewItem * , const TQPoint & , int ) ) , this , TQT_SLOT ( LocalprocessRightButton ( TQListViewItem * , const TQPoint & , int ) ) ) ;
TQObject : : connect ( LocalpopMenu , TQT_SIGNAL ( activated ( int ) ) , this , TQT_SLOT ( processDeviceStatus ( int ) ) ) ;
TQObject : : connect ( ksw - > getINDIMenu ( ) , TQT_SIGNAL ( driverDisconnected ( int ) ) , this , TQT_SLOT ( shutdownHost ( int ) ) ) ;
TQObject : : connect ( connectHostB , TQT_SIGNAL ( clicked ( ) ) , this , TQT_SLOT ( activateHostConnection ( ) ) ) ;
TQObject : : connect ( disconnectHostB , TQT_SIGNAL ( clicked ( ) ) , this , TQT_SLOT ( activateHostDisconnection ( ) ) ) ;
TQObject : : connect ( runServiceB , TQT_SIGNAL ( clicked ( ) ) , this , TQT_SLOT ( activateRunService ( ) ) ) ;
TQObject : : connect ( stopServiceB , TQT_SIGNAL ( clicked ( ) ) , this , TQT_SLOT ( activateStopService ( ) ) ) ;
TQObject : : connect ( localListView , TQT_SIGNAL ( selectionChanged ( ) ) , this , TQT_SLOT ( updateLocalButtons ( ) ) ) ;
TQObject : : connect ( clientListView , TQT_SIGNAL ( selectionChanged ( ) ) , this , TQT_SLOT ( updateClientButtons ( ) ) ) ;
readXMLDriver ( ) ;
resize ( 500 , 300 ) ;
}
void INDIDriver : : shutdownHost ( int mgrID )
{
TQListViewItem * affectedItem ;
for ( uint i = 0 ; i < ksw - > data ( ) - > INDIHostsList . count ( ) ; i + + )
{
if ( ksw - > data ( ) - > INDIHostsList . at ( i ) - > mgrID = = mgrID )
{
affectedItem = clientListView - > itemAtIndex ( i ) ;
ksw - > data ( ) - > INDIHostsList . at ( i ) - > mgrID = - 1 ;
ksw - > data ( ) - > INDIHostsList . at ( i ) - > isConnected = false ;
affectedItem - > setPixmap ( 0 , disconnected ) ;
connectHostB - > setEnabled ( true ) ;
disconnectHostB - > setEnabled ( false ) ;
return ;
}
}
for ( uint i = 0 ; i < devices . size ( ) ; i + + )
{
if ( devices [ i ] - > mgrID = = mgrID )
{
affectedItem = localListView - > findItem ( devices [ i ] - > label , 0 ) ;
if ( ! affectedItem ) return ;
affectedItem - > setPixmap ( 1 , stopPix ) ;
affectedItem - > setPixmap ( 2 , NULL ) ;
affectedItem - > setText ( 4 , TQString ( " " ) ) ;
runServiceB - > setEnabled ( true ) ;
stopServiceB - > setEnabled ( false ) ;
devices [ i ] - > managed = false ;
devices [ i ] - > restart ( ) ;
return ;
}
}
}
void INDIDriver : : ClientprocessRightButton ( TQListViewItem * item , const TQPoint & p , int column )
{
column = 0 ;
if ( item & & item - > childCount ( ) = = 0 )
ClientpopMenu - > popup ( p ) ;
}
void INDIDriver : : LocalprocessRightButton ( TQListViewItem * item , const TQPoint & p , int column )
{
column = 0 ;
if ( item & & item - > childCount ( ) = = 0 )
LocalpopMenu - > popup ( p ) ;
}
void INDIDriver : : activateRunService ( )
{
processDeviceStatus ( 0 ) ;
}
void INDIDriver : : activateStopService ( )
{
processDeviceStatus ( 1 ) ;
}
void INDIDriver : : activateHostConnection ( )
{
processHostStatus ( 0 ) ;
}
void INDIDriver : : activateHostDisconnection ( )
{
processHostStatus ( 1 ) ;
}
void INDIDriver : : updateLocalButtons ( )
{
if ( localListView - > selectedItem ( ) = = NULL )
return ;
for ( uint i = 0 ; i < devices . size ( ) ; i + + )
if ( localListView - > selectedItem ( ) - > text ( 0 ) = = devices [ i ] - > label )
{
runServiceB - > setEnabled ( devices [ i ] - > state = = 0 ) ;
stopServiceB - > setEnabled ( devices [ i ] - > state = = 1 ) ;
serverLogText - > clear ( ) ;
for ( TQStringList : : Iterator it = devices [ i ] - > serverBuffer . begin ( ) ; it ! = devices [ i ] - > serverBuffer . end ( ) ; + + it )
serverLogText - > insert ( * it ) ;
break ;
}
}
void INDIDriver : : updateClientButtons ( )
{
INDIHostsInfo * hostInfo ;
if ( clientListView - > currentItem ( ) = = NULL )
return ;
for ( uint i = 0 ; i < ksw - > data ( ) - > INDIHostsList . count ( ) ; i + + )
{
hostInfo = ksw - > data ( ) - > INDIHostsList . at ( i ) ;
if ( clientListView - > currentItem ( ) - > text ( 1 ) = = hostInfo - > name & & clientListView - > currentItem ( ) - > text ( 2 ) = = hostInfo - > portnumber )
{
connectHostB - > setEnabled ( ! hostInfo - > isConnected ) ;
disconnectHostB - > setEnabled ( hostInfo - > isConnected ) ;
break ;
}
}
}
void INDIDriver : : processDeviceStatus ( int id )
{
if ( localListView - > selectedItem ( ) = = NULL )
return ;
for ( uint i = 0 ; i < devices . size ( ) ; i + + )
if ( localListView - > selectedItem ( ) - > text ( 0 ) = = devices [ i ] - > label )
{
devices [ i ] - > state = ( id = = 0 ) ? 1 : 0 ;
if ( devices [ i ] - > state )
{
ksw - > getINDIMenu ( ) - > setCustomLabel ( devices [ i ] - > label ) ;
devices [ i ] - > label = ksw - > getINDIMenu ( ) - > currentLabel ;
devices [ i ] - > serverBuffer . clear ( ) ;
if ( ! runDevice ( devices [ i ] ) )
{
devices [ i ] - > restart ( ) ;
return ;
}
if ( devices [ i ] - > mode = = IDevice : : M_LOCAL )
{
//Allow time for the INDI server to listen
usleep ( 50000 ) ;
if ( ! ksw - > getINDIMenu ( ) - > processServer ( ) )
{
devices [ i ] - > restart ( ) ;
return ;
}
}
localListView - > selectedItem ( ) - > setPixmap ( 1 , runningPix ) ;
localListView - > selectedItem ( ) - > setText ( 4 , TQString ( " %1 " ) . arg ( devices [ i ] - > indiPort ) ) ;
runServiceB - > setEnabled ( false ) ;
stopServiceB - > setEnabled ( true ) ;
return ;
}
if ( devices [ i ] - > mode = = IDevice : : M_LOCAL )
ksw - > getINDIMenu ( ) - > processServer ( ) ;
localListView - > selectedItem ( ) - > setPixmap ( 1 , stopPix ) ;
localListView - > selectedItem ( ) - > setPixmap ( 2 , NULL ) ;
localListView - > selectedItem ( ) - > setText ( 4 , TQString ( " " ) ) ;
runServiceB - > setEnabled ( true ) ;
stopServiceB - > setEnabled ( false ) ;
devices [ i ] - > restart ( ) ;
updateMenuActions ( ) ;
return ;
}
}
void INDIDriver : : processHostStatus ( int id )
{
int mgrID ;
bool toConnect = ( id = = 0 ) ;
TQListViewItem * currentItem = clientListView - > selectedItem ( ) ;
if ( ! currentItem ) return ;
INDIHostsInfo * hostInfo ;
for ( uint i = 0 ; i < ksw - > data ( ) - > INDIHostsList . count ( ) ; i + + )
{
hostInfo = ksw - > data ( ) - > INDIHostsList . at ( i ) ;
if ( currentItem - > text ( 1 ) = = hostInfo - > name & & currentItem - > text ( 2 ) = = hostInfo - > portnumber )
{
// Nothing changed, return
if ( hostInfo - > isConnected = = toConnect )
return ;
// connect to host
if ( toConnect )
{
// if connection successful
if ( ( mgrID = ksw - > getINDIMenu ( ) - > processClient ( hostInfo - > hostname , hostInfo - > portnumber ) ) > = 0 )
{
currentItem - > setPixmap ( 0 , connected ) ;
hostInfo - > isConnected = true ;
hostInfo - > mgrID = mgrID ;
connectHostB - > setEnabled ( false ) ;
disconnectHostB - > setEnabled ( true ) ;
}
}
else
{
ksw - > getINDIMenu ( ) - > removeDeviceMgr ( hostInfo - > mgrID ) ;
hostInfo - > mgrID = mgrID = - 1 ;
hostInfo - > isConnected = false ;
currentItem - > setPixmap ( 0 , disconnected ) ;
connectHostB - > setEnabled ( true ) ;
disconnectHostB - > setEnabled ( false ) ;
updateMenuActions ( ) ;
}
}
}
}
void INDIDriver : : updateMenuActions ( )
{
// We iterate over devices, we enable INDI Control Panel if we have any active device
// We enable capture image sequence if we have any imaging device
KAction * tmpAction ;
INDIMenu * devMenu = ksw - > getINDIMenu ( ) ;
bool activeDevice = false ;
bool activeImaging = false ;
INDI_P * imgProp = NULL ;
if ( devMenu = = NULL )
return ;
if ( devMenu - > mgr . count ( ) > 0 )
activeDevice = true ;
for ( uint i = 0 ; i < devMenu - > mgr . count ( ) ; i + + )
{
for ( uint j = 0 ; j < devMenu - > mgr . at ( i ) - > indi_dev . count ( ) ; j + + )
{
imgProp = devMenu - > mgr . at ( i ) - > indi_dev . at ( j ) - > findProp ( " CCD_EXPOSE_DURATION " ) ;
if ( imgProp & & devMenu - > mgr . at ( i ) - > indi_dev . at ( j ) - > isOn ( ) )
{
activeImaging = true ;
break ;
}
}
}
tmpAction = ksw - > actionCollection ( ) - > action ( " indi_control_panel " ) ;
if ( ! tmpAction )
kdDebug ( ) < < " Warning: indi_control_panel action not found " < < endl ;
else
tmpAction - > setEnabled ( activeDevice ) ;
tmpAction = ksw - > actionCollection ( ) - > action ( " capture_sequence " ) ;
if ( ! tmpAction )
kdDebug ( ) < < " Warning: capture_sequence action not found " < < endl ;
else
tmpAction - > setEnabled ( activeImaging ) ;
}
bool INDIDriver : : runDevice ( IDevice * dev )
{
dev - > indiPort = getINDIPort ( ) ;
if ( dev - > indiPort < 0 )
{
KMessageBox : : error ( 0 , i18n ( " Cannot start INDI server: port error. " ) ) ;
return false ;
}
dev - > proc = new KProcess ;
* dev - > proc < < " indiserver " ;
* dev - > proc < < " -v " < < " -r " < < " 0 " < < " -p " < < TQString ( " %1 " ) . arg ( dev - > indiPort ) < < dev - > driver ;
// Check Mode
dev - > mode = localR - > isChecked ( ) ? IDevice : : M_LOCAL : IDevice : : M_SERVER ;
if ( dev - > mode = = IDevice : : M_LOCAL )
localListView - > selectedItem ( ) - > setPixmap ( 2 , localMode ) ;
else
localListView - > selectedItem ( ) - > setPixmap ( 2 , serverMode ) ;
connect ( dev - > proc , TQT_SIGNAL ( receivedStderr ( KProcess * , char * , int ) ) , dev , TQT_SLOT ( processstd ( KProcess * , char * , int ) ) ) ;
dev - > proc - > start ( KProcess : : NotifyOnExit , KProcess : : Stderr ) ;
//dev->proc->start();
return ( dev - > proc - > isRunning ( ) ) ;
}
void INDIDriver : : removeDevice ( IDevice * dev )
{
for ( unsigned int i = 0 ; i < devices . size ( ) ; i + + )
if ( dev - > label = = devices [ i ] - > label )
devices [ i ] - > restart ( ) ;
}
void INDIDriver : : removeDevice ( TQString deviceLabel )
{
for ( unsigned int i = 0 ; i < devices . size ( ) ; i + + )
if ( deviceLabel = = devices [ i ] - > label )
devices [ i ] - > restart ( ) ;
}
void INDIDriver : : saveDevicesToDisk ( )
{
TQFile file ;
TQString elementData ;
file . setName ( locateLocal ( " appdata " , " drivers.xml " ) ) ; //determine filename in local user KDE directory tree.
if ( ! file . open ( IO_WriteOnly ) )
{
TQString message = i18n ( " unable to write to file 'drivers.xml' \n Any changes to INDI device drivers will not be saved. " ) ;
KMessageBox : : sorry ( 0 , message , i18n ( " Could Not Open File " ) ) ;
return ;
}
TQTextStream outstream ( & file ) ;
// Let's write drivers first
outstream < < " <ScopeDrivers> " < < endl ;
for ( unsigned int i = 0 ; i < driversList . count ( ) ; i + + )
outstream < < " <driver> " < < driversList [ i ] < < " </driver> " < < endl ;
outstream < < " </ScopeDrivers> " < < endl ;
// Next we write devices, in the following order:
// Telescopes, CCDs, Filter Wheels, Video, Dome, GPS
// #1 Telescopes
outstream < < " <devGroup group='Telescopes'> " < < endl ;
for ( unsigned i = 0 ; i < devices . size ( ) ; i + + )
{
if ( devices [ i ] - > deviceType = = KSTARS_TELESCOPE )
{
outstream < < TQString ( " <device label='%1' focal_length='%2' aperture='%3'> " ) . arg ( devices [ i ] - > label ) . arg ( devices [ i ] - > focal_length > 0 ? devices [ i ] - > focal_length : - 1 ) . arg ( devices [ i ] - > aperture > 0 ? devices [ i ] - > aperture : - 1 ) < < endl ;
outstream < < " <driver> " < < devices [ i ] - > driver < < " </driver> " < < endl ;
outstream < < " <version> " < < devices [ i ] - > version < < " </version> " < < endl ;
outstream < < " </device> " < < endl ;
}
}
outstream < < " </devGroup> " < < endl ;
// #2 CCDs
outstream < < " <devGroup group='CCDs'> " < < endl ;
for ( unsigned i = 0 ; i < devices . size ( ) ; i + + )
{
if ( devices [ i ] - > deviceType = = KSTARS_CCD )
{
outstream < < TQString ( " <device label='%1'> " ) . arg ( devices [ i ] - > label ) < < endl ;
outstream < < " <driver> " < < devices [ i ] - > driver < < " </driver> " < < endl ;
outstream < < " <version> " < < devices [ i ] - > version < < " </version> " < < endl ;
outstream < < " </device> " < < endl ;
}
}
outstream < < " </devGroup> " < < endl ;
// #3 Filter wheels
outstream < < " <devGroup group='Filter Wheels'> " < < endl ;
for ( unsigned i = 0 ; i < devices . size ( ) ; i + + )
{
if ( devices [ i ] - > deviceType = = KSTARS_FILTER )
{
outstream < < TQString ( " <device label='%1'> " ) . arg ( devices [ i ] - > label ) < < endl ;
outstream < < " <driver> " < < devices [ i ] - > driver < < " </driver> " < < endl ;
outstream < < " <version> " < < devices [ i ] - > version < < " </version> " < < endl ;
outstream < < " </device> " < < endl ;
}
}
outstream < < " </devGroup> " < < endl ;
// #4 Video
outstream < < " <devGroup group='Video'> " < < endl ;
for ( unsigned i = 0 ; i < devices . size ( ) ; i + + )
{
if ( devices [ i ] - > deviceType = = KSTARS_VIDEO )
{
outstream < < TQString ( " <device label='%1'> " ) . arg ( devices [ i ] - > label ) < < endl ;
outstream < < " <driver> " < < devices [ i ] - > driver < < " </driver> " < < endl ;
outstream < < " <version> " < < devices [ i ] - > version < < " </version> " < < endl ;
outstream < < " </device> " < < endl ;
}
}
outstream < < " </devGroup> " < < endl ;
file . close ( ) ;
}
bool INDIDriver : : isDeviceRunning ( TQString deviceLabel )
{
for ( unsigned int i = 0 ; i < devices . size ( ) ; i + + )
if ( deviceLabel = = devices [ i ] - > label )
{
if ( ! devices [ i ] - > proc )
return false ;
else return ( devices [ i ] - > proc - > isRunning ( ) ) ;
}
return false ;
}
int INDIDriver : : getINDIPort ( )
{
lastPort + = 5 ;
KExtendedSocket ks ( TQString ( ) , lastPort , KExtendedSocket : : passiveSocket | KExtendedSocket : : noResolve ) ;
for ( uint i = 0 ; i < 10 ; i + + )
{
if ( ks . listen ( ) < 0 )
{
lastPort + = 5 ;
ks . setPort ( lastPort ) ;
}
else
return lastPort ;
}
return - 1 ;
}
bool INDIDriver : : readXMLDriver ( )
{
TQString indiFile ( " drivers.xml " ) ;
TQFile file ;
char errmsg [ 1024 ] ;
if ( ! KSUtils : : openDataFile ( file , indiFile ) )
{
KMessageBox : : error ( 0 , i18n ( " Unable to find device driver file 'drivers.xml'. Please locate the file and place it in one of the following locations: \n \n \t $(KDEDIR)/share/apps/kstars/%1 \n \t ~/.kde/share/apps/kstars/%1 " ) ) ;
return false ;
}
signed char c ;
LilXML * xmlParser = newLilXML ( ) ;
XMLEle * root = NULL ;
while ( ( c = ( signed char ) file . getch ( ) ) ! = - 1 )
{
root = readXMLEle ( xmlParser , c , errmsg ) ;
if ( root )
{
if ( ! buildDeviceGroup ( root , errmsg ) )
prXMLEle ( stderr , root , 0 ) ;
delXMLEle ( root ) ;
}
else if ( errmsg [ 0 ] )
{
kdDebug ( ) < < TQString ( errmsg ) ;
return false ;
}
}
delLilXML ( xmlParser ) ;
return true ;
}
bool INDIDriver : : buildDriversList ( XMLEle * root , char * /*errmsg[]*/ )
{
XMLEle * ep ;
for ( ep = nextXMLEle ( root , 1 ) ; ep ! = NULL ; ep = nextXMLEle ( root , 0 ) )
driversList < < pcdataXMLEle ( ep ) ;
return true ;
}
bool INDIDriver : : buildDeviceGroup ( XMLEle * root , char errmsg [ ] )
{
XMLAtt * ap ;
XMLEle * ep ;
TQString groupName ;
int groupType = KSTARS_TELESCOPE ;
if ( ! strcmp ( tagXMLEle ( root ) , " ScopeDrivers " ) )
return buildDriversList ( root , errmsg ) ;
// avoid overflow
if ( strlen ( tagXMLEle ( root ) ) > 1024 )
return false ;
// Get device grouping name
ap = findXMLAtt ( root , " group " ) ;
if ( ! ap )
{
snprintf ( errmsg , ERRMSG_SIZE , " Tag %.64s does not have a group attribute " , tagXMLEle ( root ) ) ;
return false ;
}
groupName = valuXMLAtt ( ap ) ;
if ( groupName . find ( " Telescopes " ) ! = - 1 )
groupType = KSTARS_TELESCOPE ;
else if ( groupName . find ( " CCDs " ) ! = - 1 )
groupType = KSTARS_CCD ;
else if ( groupName . find ( " Filter " ) ! = - 1 )
groupType = KSTARS_FILTER ;
else if ( groupName . find ( " Video " ) ! = - 1 )
groupType = KSTARS_VIDEO ;
else if ( groupName . find ( " Focusers " ) ! = - 1 )
groupType = KSTARS_FOCUSER ;
else if ( groupName . find ( " Domes " ) ! = - 1 )
groupType = KSTARS_DOME ;
else if ( groupName . find ( " GPS " ) ! = - 1 )
groupType = KSTARS_GPS ;
//KListViewItem *group = new KListViewItem(topItem, lastGroup);
TQListViewItem * group = new TQListViewItem ( localListView , lastGroup ) ;
group - > setText ( 0 , groupName ) ;
lastGroup = group ;
//group->setOpen(true);
for ( ep = nextXMLEle ( root , 1 ) ; ep ! = NULL ; ep = nextXMLEle ( root , 0 ) )
/*for (int i = 0; i < root->nel; i++)*/
if ( ! buildDriverElement ( ep , group , groupType , errmsg ) )
return false ;
return true ;
}
bool INDIDriver : : buildDriverElement ( XMLEle * root , TQListViewItem * DGroup , int groupType , char errmsg [ ] )
{
XMLAtt * ap ;
XMLEle * el ;
IDevice * dv ;
TQString label ;
TQString driver ;
TQString version ;
double focal_length ( - 1 ) , aperture ( - 1 ) ;
ap = findXMLAtt ( root , " label " ) ;
if ( ! ap )
{
snprintf ( errmsg , ERRMSG_SIZE , " Tag %.64s does not have a label attribute " , tagXMLEle ( root ) ) ;
return false ;
}
label = valuXMLAtt ( ap ) ;
// Let's look for telescope-specfic attributes: focal length and aperture
ap = findXMLAtt ( root , " focal_length " ) ;
if ( ap )
focal_length = TQString ( valuXMLAtt ( ap ) ) . toDouble ( ) ;
ap = findXMLAtt ( root , " aperture " ) ;
if ( ap )
aperture = TQString ( valuXMLAtt ( ap ) ) . toDouble ( ) ;
el = findXMLEle ( root , " driver " ) ;
if ( ! el )
return false ;
driver = pcdataXMLEle ( el ) ;
el = findXMLEle ( root , " version " ) ;
if ( ! el )
return false ;
version = pcdataXMLEle ( el ) ;
TQListViewItem * device = new TQListViewItem ( DGroup , lastDevice ) ;
device - > setText ( 0 , TQString ( label ) ) ;
device - > setPixmap ( 1 , stopPix ) ;
device - > setText ( 3 , TQString ( version ) ) ;
lastDevice = device ;
dv = new IDevice ( label , driver , version ) ;
dv - > deviceType = groupType ;
connect ( dv , TQT_SIGNAL ( newServerInput ( ) ) , this , TQT_SLOT ( updateLocalButtons ( ) ) ) ;
if ( focal_length > 0 )
dv - > focal_length = focal_length ;
if ( aperture > 0 )
dv - > aperture = aperture ;
devices . push_back ( dv ) ;
// SLOTS/SIGNAL, pop menu, indi server logic
return true ;
}
int INDIDriver : : activeDriverCount ( )
{
int count = 0 ;
for ( uint i = 0 ; i < devices . size ( ) ; i + + )
if ( devices [ i ] - > state & & devices [ i ] - > mode = = IDevice : : M_LOCAL )
count + + ;
for ( uint i = 0 ; i < ksw - > data ( ) - > INDIHostsList . count ( ) ; i + + )
if ( ksw - > data ( ) - > INDIHostsList . at ( i ) - > isConnected )
count + + ;
return count ;
}
void INDIDriver : : addINDIHost ( )
{
INDIHostConf hostConf ( this ) ;
hostConf . setCaption ( i18n ( " Add Host " ) ) ;
bool portOk = false ;
if ( hostConf . exec ( ) = = TQDialog : : Accepted )
{
INDIHostsInfo * hostItem = new INDIHostsInfo ;
hostItem - > name = hostConf . nameIN - > text ( ) ;
hostItem - > hostname = hostConf . hostname - > text ( ) ;
hostItem - > portnumber = hostConf . portnumber - > text ( ) ;
hostItem - > isConnected = false ;
hostItem - > mgrID = - 1 ;
hostItem - > portnumber . toInt ( & portOk ) ;
if ( portOk = = false )
{
KMessageBox : : error ( 0 , i18n ( " Error: the port number is invalid. " ) ) ;
return ;
}
//search for duplicates
for ( uint i = 0 ; i < ksw - > data ( ) - > INDIHostsList . count ( ) ; i + + )
if ( hostItem - > name = = ksw - > data ( ) - > INDIHostsList . at ( i ) - > name & &
hostItem - > portnumber = = ksw - > data ( ) - > INDIHostsList . at ( i ) - > portnumber )
{
KMessageBox : : error ( 0 , i18n ( " Host: %1 Port: %2 already exists. " ) . arg ( hostItem - > name ) . arg ( hostItem - > portnumber ) ) ;
return ;
}
ksw - > data ( ) - > INDIHostsList . append ( hostItem ) ;
TQListViewItem * item = new TQListViewItem ( clientListView ) ;
item - > setPixmap ( 0 , disconnected ) ;
item - > setText ( 1 , hostConf . nameIN - > text ( ) ) ;
item - > setText ( 2 , hostConf . portnumber - > text ( ) ) ;
}
saveHosts ( ) ;
}
void INDIDriver : : modifyINDIHost ( )
{
INDIHostConf hostConf ( this ) ;
hostConf . setCaption ( i18n ( " Modify Host " ) ) ;
TQListViewItem * currentItem = clientListView - > currentItem ( ) ;
if ( currentItem = = NULL )
return ;
for ( uint i = 0 ; i < ksw - > data ( ) - > INDIHostsList . count ( ) ; i + + )
if ( currentItem - > text ( 1 ) = = ksw - > data ( ) - > INDIHostsList . at ( i ) - > name & &
currentItem - > text ( 2 ) = = ksw - > data ( ) - > INDIHostsList . at ( i ) - > portnumber )
{
hostConf . nameIN - > setText ( ksw - > data ( ) - > INDIHostsList . at ( i ) - > name ) ;
hostConf . hostname - > setText ( ksw - > data ( ) - > INDIHostsList . at ( i ) - > hostname ) ;
hostConf . portnumber - > setText ( ksw - > data ( ) - > INDIHostsList . at ( i ) - > portnumber ) ;
if ( hostConf . exec ( ) = = TQDialog : : Accepted )
{
INDIHostsInfo * hostItem = new INDIHostsInfo ;
hostItem - > name = hostConf . nameIN - > text ( ) ;
hostItem - > hostname = hostConf . hostname - > text ( ) ;
hostItem - > portnumber = hostConf . portnumber - > text ( ) ;
currentItem - > setText ( 1 , hostConf . nameIN - > text ( ) ) ;
currentItem - > setText ( 2 , hostConf . portnumber - > text ( ) ) ;
ksw - > data ( ) - > INDIHostsList . replace ( clientListView - > itemIndex ( currentItem ) , hostItem ) ;
saveHosts ( ) ;
}
}
}
void INDIDriver : : removeINDIHost ( )
{
if ( clientListView - > currentItem ( ) = = NULL )
return ;
for ( uint i = 0 ; i < ksw - > data ( ) - > INDIHostsList . count ( ) ; i + + )
if ( clientListView - > currentItem ( ) - > text ( 1 ) = = ksw - > data ( ) - > INDIHostsList . at ( i ) - > name & &
clientListView - > currentItem ( ) - > text ( 2 ) = = ksw - > data ( ) - > INDIHostsList . at ( i ) - > portnumber )
{
if ( ksw - > data ( ) - > INDIHostsList . at ( i ) - > isConnected )
{
KMessageBox : : error ( 0 , i18n ( " You need to disconnect the client before removing it. " ) ) ;
return ;
}
if ( KMessageBox : : warningContinueCancel ( 0 , i18n ( " Are you sure you want to remove the %1 client? " ) . arg ( clientListView - > currentItem ( ) - > text ( 1 ) ) , i18n ( " Delete Confirmation " ) , KStdGuiItem : : del ( ) ) ! = KMessageBox : : Continue )
return ;
ksw - > data ( ) - > INDIHostsList . remove ( i ) ;
clientListView - > takeItem ( clientListView - > currentItem ( ) ) ;
break ;
}
saveHosts ( ) ;
}
void INDIDriver : : saveHosts ( )
{
TQFile file ;
TQString hostData ;
file . setName ( locateLocal ( " appdata " , " indihosts.xml " ) ) ; //determine filename in local user KDE directory tree.
if ( ! file . open ( IO_WriteOnly ) )
{
TQString message = i18n ( " unable to write to file 'indihosts.xml' \n Any changes to INDI hosts configurations will not be saved. " ) ;
KMessageBox : : sorry ( 0 , message , i18n ( " Could Not Open File " ) ) ;
return ;
}
TQTextStream outstream ( & file ) ;
for ( uint i = 0 ; i < ksw - > data ( ) - > INDIHostsList . count ( ) ; i + + )
{
hostData = " <INDIHost name=' " ;
hostData + = ksw - > data ( ) - > INDIHostsList . at ( i ) - > name ;
hostData + = " ' hostname=' " ;
hostData + = ksw - > data ( ) - > INDIHostsList . at ( i ) - > hostname ;
hostData + = " ' port=' " ;
hostData + = ksw - > data ( ) - > INDIHostsList . at ( i ) - > portnumber ;
hostData + = " ' /> \n " ;
outstream < < hostData ;
}
file . close ( ) ;
}
INDIDriver : : ~ INDIDriver ( )
{
for ( uint i = 0 ; i < devices . size ( ) ; i + + )
delete ( devices [ i ] ) ;
}
IDevice : : IDevice ( TQString inLabel , TQString inDriver , TQString inVersion )
{
label = inLabel ; ;
driver = inDriver ; ;
version = inVersion ;
// Initially off
state = 0 ;
// No port initially
indiPort = - 1 ;
// not yet managed by DeviceManager
managed = false ;
mgrID = - 1 ;
focal_length = - 1 ;
aperture = - 1 ;
proc = NULL ;
}
void IDevice : : processstd ( KProcess * /*proc*/ , char * buffer , int /*buflen*/ )
{
serverBuffer . append ( buffer ) ;
emit newServerInput ( ) ;
}
IDevice : : ~ IDevice ( )
{
if ( proc )
proc - > kill ( ) ;
}
void IDevice : : restart ( )
{
mgrID = - 1 ;
state = 0 ;
indiPort = - 1 ;
if ( proc )
proc - > kill ( ) ;
proc = NULL ;
}
# include "indidriver.moc"