• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

kstars

indidriver.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           INDI Driver
00003                              -------------------
00004     begin                : Wed May 7th 2003
00005     copyright            : (C) 2001 by Jasem Mutlaq
00006     email                : mutlaqja@ikarustech.com
00007  ***************************************************************************/
00008 /***************************************************************************
00009  *                                                                         *
00010  *   This program is free software; you can redistribute it and/or modify  *
00011  *   it under the terms of the GNU General Public License as published by  *
00012  *   the Free Software Foundation; either version 2 of the License, or     *
00013  *   (at your option) any later version.                                   *
00014  *                                                                         *
00015  ***************************************************************************/
00016 
00017 #include "indidriver.h"
00018 #include "indimenu.h"
00019 #include "indihostconf.h"
00020 #include "devicemanager.h"
00021 #include "indidevice.h"
00022 #include "indi/indicom.h"
00023 
00024 #include "kstars.h"
00025 #include "kstarsdata.h"
00026 #include "ksutils.h"
00027 
00028 #include <qfile.h>
00029 #include <qvaluelist.h>
00030 #include <qcstring.h>
00031 #include <qradiobutton.h>
00032 #include <qtextedit.h>
00033 
00034 #include <kiconloader.h>
00035 #include <klistview.h>
00036 #include <kpopupmenu.h>
00037 #include <kprocess.h>
00038 #include <kmessagebox.h>
00039 #include <kpushbutton.h>
00040 #include <klineedit.h>
00041 #include <kstandarddirs.h>
00042 #include <kaction.h>
00043 
00044 #include <kextsock.h>
00045 #include <unistd.h>
00046 
00047 /*
00048  *  The dialog will by default be modeless, unless you set 'modal' to
00049  *  TRUE to construct a modal dialog.
00050  */
00051 INDIDriver::INDIDriver(QWidget *parent) : devManager( parent )
00052 
00053 {
00054 
00055     lastPort = 7263;
00056     lastGroup = NULL;
00057     lastDevice = NULL;
00058 
00059     ksw = (KStars *) parent;
00060 
00061     //FormLayout =  makeVBoxMainWidget();
00062 
00063     localListView->setSorting(-1);
00064     clientListView->setSorting(-1);
00065 
00066     KIconLoader *icons = KGlobal::iconLoader();
00067     runningPix = icons->loadIcon( "exec", KIcon::Small);
00068     stopPix    = icons->loadIcon( "button_cancel", KIcon::Small);
00069     localMode  = icons->loadIcon( "network_local", KIcon::Small);
00070     serverMode = icons->loadIcon( "network", KIcon::Small);
00071 
00072     LocalpopMenu = new KPopupMenu(localListView);
00073     LocalpopMenu->insertItem( runningPix, i18n("Run Service") , 0);
00074     LocalpopMenu->insertItem( stopPix, i18n("Stop Service"), 1);
00075 
00076     localListView->setRootIsDecorated(true);
00077 
00078   connected           = icons->loadIcon( "connect_established", KIcon::Small);
00079   disconnected        = icons->loadIcon( "connect_no", KIcon::Small);
00080   establishConnection = icons->loadIcon( "connect_creating", KIcon::Small);
00081 
00082   ClientpopMenu = new KPopupMenu(clientListView);
00083   ClientpopMenu->insertItem( establishConnection, i18n("Connect") , 0);
00084   ClientpopMenu->insertItem( disconnected, i18n("Disconnect"), 1);
00085 
00086 
00087   for (uint i = 0; i < ksw->data()->INDIHostsList.count(); i++)
00088   {
00089     QListViewItem *item = new QListViewItem(clientListView, lastGroup);
00090     lastGroup = item;
00091     item->setPixmap(0, disconnected);
00092         item->setText(1, ksw->data()->INDIHostsList.at(i)->name);
00093     item->setText(2, ksw->data()->INDIHostsList.at(i)->portnumber);
00094 
00095   }
00096 
00097   lastGroup = NULL;
00098 
00099   QObject::connect(addB, SIGNAL(clicked()), this, SLOT(addINDIHost()));
00100   QObject::connect(modifyB, SIGNAL(clicked()), this, SLOT(modifyINDIHost()));
00101   QObject::connect(removeB, SIGNAL(clicked()), this, SLOT(removeINDIHost()));
00102 
00103   QObject::connect(clientListView, SIGNAL(rightButtonPressed ( QListViewItem *, const QPoint &, int )), this, SLOT(ClientprocessRightButton( QListViewItem *, const QPoint &, int )));
00104 
00105 QObject::connect(ClientpopMenu, SIGNAL(activated(int)), this, SLOT(processHostStatus(int)));
00106 
00107 QObject::connect(localListView, SIGNAL(rightButtonPressed ( QListViewItem *, const QPoint &, int )), this, SLOT(LocalprocessRightButton( QListViewItem *, const QPoint &, int )));
00108 
00109 QObject::connect(LocalpopMenu, SIGNAL(activated(int)), this, SLOT(processDeviceStatus(int)));
00110 
00111 QObject::connect(ksw->getINDIMenu(), SIGNAL(driverDisconnected(int)), this, SLOT(shutdownHost(int)));
00112 
00113 QObject::connect(connectHostB, SIGNAL(clicked()), this, SLOT(activateHostConnection()));
00114 QObject::connect(disconnectHostB, SIGNAL(clicked()), this, SLOT(activateHostDisconnection()));
00115 
00116 QObject::connect(runServiceB, SIGNAL(clicked()), this, SLOT(activateRunService()));
00117 QObject::connect(stopServiceB, SIGNAL(clicked()), this, SLOT(activateStopService()));
00118 
00119 QObject::connect(localListView, SIGNAL(selectionChanged()), this, SLOT(updateLocalButtons()));
00120 QObject::connect(clientListView, SIGNAL(selectionChanged()), this, SLOT(updateClientButtons()));
00121 
00122 readXMLDriver();
00123 resize( 500, 300);
00124 
00125 }
00126 
00127 void INDIDriver::shutdownHost(int mgrID)
00128 {
00129   QListViewItem *affectedItem;
00130 
00131 for (uint i=0; i < ksw->data()->INDIHostsList.count(); i++)
00132 {
00133      if (ksw->data()->INDIHostsList.at(i)->mgrID == mgrID)
00134      {
00135         affectedItem = clientListView->itemAtIndex(i);
00136     ksw->data()->INDIHostsList.at(i)->mgrID = -1;
00137     ksw->data()->INDIHostsList.at(i)->isConnected = false;
00138         affectedItem->setPixmap(0, disconnected);
00139     connectHostB->setEnabled(true);
00140         disconnectHostB->setEnabled(false);
00141     return;
00142      }
00143  }
00144  
00145   for (uint i=0; i < devices.size(); i++)
00146   {
00147     if (devices[i]->mgrID == mgrID)
00148     {
00149       affectedItem = localListView->findItem(devices[i]->label, 0);
00150       if (!affectedItem) return;
00151       affectedItem->setPixmap(1, stopPix);
00152       affectedItem->setPixmap(2, NULL);
00153       affectedItem->setText(4, QString(""));
00154       runServiceB->setEnabled(true);
00155       stopServiceB->setEnabled(false);
00156       devices[i]->managed = false;
00157       devices[i]->restart();
00158       return;
00159     
00160     }
00161   }
00162       
00163           
00164 }
00165 
00166 void INDIDriver::ClientprocessRightButton( QListViewItem *item, const QPoint &p, int column)
00167 {
00168 
00169   column = 0;
00170 
00171   if (item && item->childCount() == 0)
00172     ClientpopMenu->popup(p);
00173 }
00174 
00175 void INDIDriver::LocalprocessRightButton( QListViewItem *item, const QPoint &p, int column)
00176 {
00177 
00178   column = 0;
00179 
00180   if (item && item->childCount() == 0)
00181     LocalpopMenu->popup(p);
00182 }
00183 
00184 void INDIDriver::activateRunService()
00185 {
00186   processDeviceStatus(0);
00187 }
00188 
00189 void INDIDriver::activateStopService()
00190 {
00191   processDeviceStatus(1);
00192 }
00193 
00194 void INDIDriver::activateHostConnection()
00195 {
00196   processHostStatus(0);
00197 }
00198 
00199 void INDIDriver::activateHostDisconnection()
00200 {
00201   processHostStatus(1);
00202 }
00203     
00204 void INDIDriver::updateLocalButtons()
00205 {
00206   
00207   if (localListView->selectedItem() == NULL)
00208    return;
00209  
00210   for (uint i=0; i < devices.size(); i++)
00211      if (localListView->selectedItem()->text(0) == devices[i]->label)
00212      {
00213     runServiceB->setEnabled(devices[i]->state == 0);
00214     stopServiceB->setEnabled(devices[i]->state == 1);
00215     
00216     serverLogText->clear();
00217     
00218     for ( QStringList::Iterator it = devices[i]->serverBuffer.begin(); it != devices[i]->serverBuffer.end(); ++it )
00219        serverLogText->insert(*it);
00220     
00221     break;
00222      }
00223 
00224 }
00225 
00226 void INDIDriver::updateClientButtons()
00227 {
00228  INDIHostsInfo *hostInfo;
00229  if (clientListView->currentItem() == NULL)
00230   return;
00231 
00232 
00233 for (uint i=0; i < ksw->data()->INDIHostsList.count(); i++)
00234    {
00235      hostInfo = ksw->data()->INDIHostsList.at(i);
00236      if (clientListView->currentItem()->text(1) == hostInfo->name && clientListView->currentItem()->text(2) == hostInfo->portnumber)
00237      {
00238        connectHostB->setEnabled(!hostInfo->isConnected);
00239        disconnectHostB->setEnabled(hostInfo->isConnected);
00240        break;
00241      }
00242     }
00243    
00244 }
00245 
00246     
00247 void INDIDriver::processDeviceStatus(int id)
00248 {
00249   if (localListView->selectedItem() == NULL)
00250     return;
00251 
00252    for (uint i=0; i < devices.size(); i++)
00253      if (localListView->selectedItem()->text(0) == devices[i]->label)
00254      {
00255     devices[i]->state = (id == 0) ? 1 : 0;
00256     if (devices[i]->state)
00257     {
00258 
00259       ksw->getINDIMenu()->setCustomLabel(devices[i]->label);
00260       devices[i]->label = ksw->getINDIMenu()->currentLabel;
00261 
00262       devices[i]->serverBuffer.clear();
00263       
00264       if (!runDevice(devices[i]))
00265       {
00266        devices[i]->restart();
00267        return;
00268       }
00269 
00270       if (devices[i]->mode == IDevice::M_LOCAL)
00271       {
00272            //Allow time for the INDI server to listen
00273         usleep(50000);
00274 
00275         if (!ksw->getINDIMenu()->processServer())
00276         {
00277             devices[i]->restart();
00278             return;
00279         }
00280       }
00281 
00282       localListView->selectedItem()->setPixmap(1, runningPix);
00283       localListView->selectedItem()->setText(4, QString("%1").arg(devices[i]->indiPort));
00284       runServiceB->setEnabled(false);
00285       stopServiceB->setEnabled(true);
00286       
00287       return;
00288     }
00289     
00290       if (devices[i]->mode == IDevice::M_LOCAL)
00291         ksw->getINDIMenu()->processServer();
00292         
00293       localListView->selectedItem()->setPixmap(1, stopPix);
00294       localListView->selectedItem()->setPixmap(2, NULL);
00295       localListView->selectedItem()->setText(4, QString(""));
00296       runServiceB->setEnabled(true);
00297       stopServiceB->setEnabled(false);
00298       devices[i]->restart();
00299       updateMenuActions();
00300       return;
00301      }
00302 }
00303 
00304 void INDIDriver::processHostStatus(int id)
00305 {
00306    int mgrID;
00307    bool toConnect = (id == 0);
00308    QListViewItem *currentItem = clientListView->selectedItem();
00309    if (!currentItem) return;
00310    INDIHostsInfo *hostInfo;
00311 
00312    for (uint i=0; i < ksw->data()->INDIHostsList.count(); i++)
00313    {
00314      hostInfo = ksw->data()->INDIHostsList.at(i);
00315      if (currentItem->text(1) == hostInfo->name && currentItem->text(2) == hostInfo->portnumber)
00316      {
00317         // Nothing changed, return
00318         if (hostInfo->isConnected == toConnect)
00319      return;
00320 
00321     // connect to host
00322     if (toConnect)
00323     {
00324        // if connection successful
00325           if ( (mgrID = ksw->getINDIMenu()->processClient(hostInfo->hostname, hostInfo->portnumber)) >= 0)
00326       {
00327         currentItem->setPixmap(0, connected);
00328         hostInfo->isConnected = true;
00329         hostInfo->mgrID = mgrID;
00330         connectHostB->setEnabled(false);
00331         disconnectHostB->setEnabled(true);
00332       }
00333     }
00334     else
00335     {
00336       ksw->getINDIMenu()->removeDeviceMgr(hostInfo->mgrID);
00337       hostInfo->mgrID = mgrID = -1;
00338       hostInfo->isConnected = false;
00339       currentItem->setPixmap(0, disconnected);
00340       connectHostB->setEnabled(true);
00341       disconnectHostB->setEnabled(false);
00342       updateMenuActions();
00343     }
00344     
00345     
00346 
00347        }
00348     }
00349 }
00350 
00351 void INDIDriver::updateMenuActions()
00352 {
00353   // We iterate over devices, we enable INDI Control Panel if we have any active device
00354   // We enable capture image sequence if we have any imaging device
00355   
00356   KAction *tmpAction;
00357   INDIMenu *devMenu = ksw->getINDIMenu();
00358   bool activeDevice = false;
00359   bool activeImaging = false;
00360   INDI_P *imgProp = NULL;
00361   
00362   if (devMenu == NULL)
00363      return;
00364   
00365   if (devMenu->mgr.count() > 0)
00366    activeDevice = true;
00367    
00368   for (uint i=0; i < devMenu->mgr.count(); i++)
00369   {
00370     for (uint j=0; j < devMenu->mgr.at(i)->indi_dev.count(); j++)
00371     {
00372                 imgProp = devMenu->mgr.at(i)->indi_dev.at(j)->findProp("CCD_EXPOSE_DURATION");
00373             if (imgProp && devMenu->mgr.at(i)->indi_dev.at(j)->isOn())
00374             {
00375               activeImaging = true;
00376               break;
00377             }
00378     }
00379   }
00380    
00381   tmpAction = ksw->actionCollection()->action("indi_control_panel");
00382   if (!tmpAction)
00383     kdDebug() << "Warning: indi_control_panel action not found" << endl;
00384   else
00385     tmpAction->setEnabled(activeDevice);
00386   
00387   tmpAction = ksw->actionCollection()->action("capture_sequence");
00388   if (!tmpAction)
00389     kdDebug() << "Warning: capture_sequence action not found" << endl;
00390   else
00391     tmpAction->setEnabled(activeImaging);
00392   
00393 }
00394 
00395 bool INDIDriver::runDevice(IDevice *dev)
00396 {
00397   dev->indiPort = getINDIPort();
00398 
00399   if (dev->indiPort < 0)
00400   {
00401    KMessageBox::error(0, i18n("Cannot start INDI server: port error."));
00402    return false;
00403   }
00404 
00405   dev->proc = new KProcess;
00406   
00407   *dev->proc << "indiserver";
00408   *dev->proc << "-v" << "-r" << "0" << "-p" << QString("%1").arg(dev->indiPort) << dev->driver;
00409   
00410   // Check Mode
00411   dev->mode = localR->isChecked() ? IDevice::M_LOCAL : IDevice::M_SERVER;
00412   
00413   if (dev->mode == IDevice::M_LOCAL)
00414     localListView->selectedItem()->setPixmap(2, localMode);
00415   else
00416     localListView->selectedItem()->setPixmap(2, serverMode);
00417 
00418   connect(dev->proc, SIGNAL(receivedStderr (KProcess *, char *, int)),  dev, SLOT(processstd(KProcess *, char*, int)));
00419 
00420   dev->proc->start(KProcess::NotifyOnExit, KProcess::Stderr);
00421   //dev->proc->start();
00422   
00423   return (dev->proc->isRunning());
00424 }
00425 
00426 void INDIDriver::removeDevice(IDevice *dev)
00427 {
00428 
00429   for (unsigned int i=0 ; i < devices.size(); i++)
00430      if (dev->label == devices[i]->label)
00431         devices[i]->restart();
00432 }
00433 
00434 void INDIDriver::removeDevice(QString deviceLabel)
00435 {
00436   for (unsigned int i=0 ; i < devices.size(); i++)
00437      if (deviceLabel == devices[i]->label)
00438         devices[i]->restart();
00439 
00440 }
00441 
00442 void INDIDriver::saveDevicesToDisk()
00443 {
00444 
00445  QFile file;
00446  QString elementData;
00447 
00448  file.setName( locateLocal( "appdata", "drivers.xml" ) ); //determine filename in local user KDE directory tree.
00449 
00450  if ( !file.open( IO_WriteOnly))
00451  {
00452   QString message = i18n( "unable to write to file 'drivers.xml'\nAny changes to INDI device drivers will not be saved." );
00453  KMessageBox::sorry( 0, message, i18n( "Could Not Open File" ) );
00454   return;
00455  }
00456 
00457  QTextStream outstream(&file);
00458 
00459  // Let's write drivers first
00460  outstream << "<ScopeDrivers>" << endl;
00461  for (unsigned int i=0; i < driversList.count(); i++)
00462   outstream << "       <driver>" << driversList[i] << "</driver>" << endl;
00463  outstream << "</ScopeDrivers>" << endl;
00464 
00465  // Next we write devices, in the following order:
00466  // Telescopes, CCDs, Filter Wheels, Video, Dome, GPS
00467 
00468   // #1 Telescopes
00469   outstream << "<devGroup group='Telescopes'>" << endl;
00470   for (unsigned i=0; i < devices.size(); i++)
00471   {
00472      if (devices[i]->deviceType == KSTARS_TELESCOPE)
00473      {
00474     outstream << QString("<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;
00475 
00476     outstream << "       <driver>" << devices[i]->driver << "</driver>" << endl;
00477     outstream << "       <version>" << devices[i]->version << "</version>" << endl;
00478         outstream << "</device>" << endl;
00479       }
00480    }
00481    outstream << "</devGroup>" << endl;
00482 
00483    // #2 CCDs
00484    outstream << "<devGroup group='CCDs'>" << endl;
00485    for (unsigned i=0; i < devices.size(); i++)
00486    {
00487      if (devices[i]->deviceType == KSTARS_CCD)
00488      {
00489     outstream << QString("<device label='%1'>").arg(devices[i]->label) << endl;
00490     outstream << "       <driver>" << devices[i]->driver << "</driver>" << endl;
00491     outstream << "       <version>" << devices[i]->version << "</version>" << endl;
00492         outstream << "</device>" << endl;
00493      }
00494   }
00495   outstream << "</devGroup>" << endl;
00496 
00497   // #3 Filter wheels
00498   outstream << "<devGroup group='Filter Wheels'>" << endl;
00499    for (unsigned i=0; i < devices.size(); i++)
00500    {
00501      if (devices[i]->deviceType == KSTARS_FILTER)
00502      {
00503     outstream << QString("<device label='%1'>").arg(devices[i]->label) << endl;
00504     outstream << "       <driver>" << devices[i]->driver << "</driver>" << endl;
00505     outstream << "       <version>" << devices[i]->version << "</version>" << endl;
00506         outstream << "</device>" << endl;
00507      }
00508   }
00509   outstream << "</devGroup>" << endl;
00510 
00511    // #4 Video
00512    outstream << "<devGroup group='Video'>" << endl;
00513    for (unsigned i=0; i < devices.size(); i++)
00514    {
00515      if (devices[i]->deviceType == KSTARS_VIDEO)
00516      {
00517     outstream << QString("<device label='%1'>").arg(devices[i]->label) << endl;
00518     outstream << "       <driver>" << devices[i]->driver << "</driver>" << endl;
00519     outstream << "       <version>" << devices[i]->version << "</version>" << endl;
00520         outstream << "</device>" << endl;
00521      }
00522    }
00523    outstream << "</devGroup>" << endl;
00524 
00525    file.close();
00526 
00527 }
00528 
00529 bool INDIDriver::isDeviceRunning(QString deviceLabel)
00530 {
00531 
00532     for (unsigned int i=0 ; i < devices.size(); i++)
00533      if (deviceLabel == devices[i]->label)
00534      {
00535        if (!devices[i]->proc)
00536         return false;
00537        else return (devices[i]->proc->isRunning());
00538      }
00539 
00540     return false;
00541 
00542 }
00543 
00544 int INDIDriver::getINDIPort()
00545 {
00546 
00547   lastPort+=5;
00548 
00549   KExtendedSocket ks(QString::null, lastPort, KExtendedSocket::passiveSocket | KExtendedSocket::noResolve);
00550 
00551   for (uint i=0 ; i < 10; i++)
00552   {
00553     if (ks.listen() < 0)
00554     {
00555       lastPort+=5;
00556       ks.setPort(lastPort);
00557     }
00558     else
00559      return lastPort;
00560   }
00561 
00562    return -1;
00563 }
00564 
00565 bool INDIDriver::readXMLDriver()
00566 {
00567   QString indiFile("drivers.xml");
00568   QFile file;
00569   char errmsg[1024];
00570 
00571   if ( !KSUtils::openDataFile( file, indiFile ) )
00572   {
00573      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"));
00574 
00575     return false;
00576  }
00577 
00578  signed char c;
00579  LilXML *xmlParser = newLilXML();
00580  XMLEle *root = NULL;
00581 
00582  while ( (c = (signed char) file.getch()) != -1)
00583  {
00584     root = readXMLEle(xmlParser, c, errmsg);
00585 
00586     if (root)
00587     {
00588       if (!buildDeviceGroup(root, errmsg))
00589          prXMLEle(stderr, root, 0);
00590 
00591       delXMLEle(root);
00592     }
00593     else if (errmsg[0])
00594     {
00595       kdDebug() << QString(errmsg);
00596       return false;
00597     }
00598   }
00599 
00600  delLilXML(xmlParser);
00601  return true;
00602 
00603 }
00604 
00605 bool INDIDriver::buildDriversList( XMLEle *root, char* /*errmsg[]*/)
00606 {
00607 
00608   XMLEle *ep;
00609 
00610   for (ep = nextXMLEle (root, 1); ep != NULL; ep = nextXMLEle (root, 0))
00611       driversList << pcdataXMLEle(ep);
00612 
00613   return true;
00614 
00615 }
00616 
00617 bool INDIDriver::buildDeviceGroup(XMLEle *root, char errmsg[])
00618 {
00619 
00620   XMLAtt *ap;
00621   XMLEle *ep;
00622   QString groupName;
00623   int groupType = KSTARS_TELESCOPE;
00624 
00625   if (!strcmp(tagXMLEle(root), "ScopeDrivers"))
00626     return buildDriversList(root, errmsg);
00627  
00628   // avoid overflow
00629   if (strlen(tagXMLEle(root)) > 1024)
00630    return false;
00631 
00632   // Get device grouping name
00633   ap = findXMLAtt(root, "group");
00634 
00635   if (!ap)
00636   {
00637     snprintf(errmsg, ERRMSG_SIZE, "Tag %.64s does not have a group attribute", tagXMLEle(root));
00638     return false;
00639   }
00640 
00641   groupName = valuXMLAtt(ap);
00642   
00643   if (groupName.find("Telescopes") != -1)
00644     groupType = KSTARS_TELESCOPE;
00645   else if (groupName.find("CCDs") != -1)
00646     groupType = KSTARS_CCD;
00647   else if (groupName.find("Filter") != -1)
00648     groupType = KSTARS_FILTER;
00649   else if (groupName.find("Video") != -1)
00650     groupType = KSTARS_VIDEO;
00651   else if (groupName.find("Focusers") != -1)
00652     groupType = KSTARS_FOCUSER;
00653   else if (groupName.find("Domes") != -1)
00654     groupType = KSTARS_DOME;
00655   else if (groupName.find("GPS") != -1)
00656     groupType = KSTARS_GPS;
00657 
00658 
00659   //KListViewItem *group = new KListViewItem(topItem, lastGroup);
00660   QListViewItem *group = new QListViewItem(localListView, lastGroup);
00661   group->setText(0, groupName);
00662   lastGroup = group;
00663   //group->setOpen(true);
00664 
00665 
00666   for (ep = nextXMLEle(root, 1) ; ep != NULL ; ep = nextXMLEle(root, 0))
00667   /*for (int i = 0; i < root->nel; i++)*/
00668     if (!buildDriverElement(ep, group, groupType, errmsg))
00669       return false;
00670 
00671   return true;
00672 }
00673 
00674 bool INDIDriver::buildDriverElement(XMLEle *root, QListViewItem *DGroup, int groupType, char errmsg[])
00675 {
00676   XMLAtt *ap;
00677   XMLEle *el;
00678   IDevice *dv;
00679   QString label;
00680   QString driver;
00681   QString version;
00682   double focal_length (-1), aperture (-1);
00683 
00684   ap = findXMLAtt(root, "label");
00685   if (!ap)
00686   {
00687     snprintf(errmsg, ERRMSG_SIZE, "Tag %.64s does not have a label attribute", tagXMLEle(root));
00688     return false;
00689   }
00690 
00691   label = valuXMLAtt(ap);
00692 
00693   // Let's look for telescope-specfic attributes: focal length and aperture
00694   ap = findXMLAtt(root, "focal_length");
00695   if (ap)
00696    focal_length = QString(valuXMLAtt(ap)).toDouble();
00697 
00698   ap = findXMLAtt(root, "aperture");
00699   if (ap)
00700    aperture = QString(valuXMLAtt(ap)).toDouble();
00701 
00702 
00703   el = findXMLEle(root, "driver");
00704 
00705   if (!el)
00706    return false;
00707 
00708   driver = pcdataXMLEle(el);
00709   
00710   el = findXMLEle(root, "version");
00711 
00712   if (!el)
00713    return false;
00714 
00715   version = pcdataXMLEle(el);
00716 
00717   QListViewItem *device = new QListViewItem(DGroup, lastDevice);
00718 
00719   device->setText(0, QString(label));
00720   device->setPixmap(1, stopPix);
00721   device->setText(3, QString(version));
00722 
00723   lastDevice = device;
00724 
00725   dv = new IDevice(label, driver, version);
00726   dv->deviceType = groupType;
00727   connect(dv, SIGNAL(newServerInput()), this, SLOT(updateLocalButtons()));
00728   if (focal_length > 0)
00729    dv->focal_length = focal_length;
00730   if (aperture > 0)
00731    dv->aperture = aperture;
00732   
00733   devices.push_back(dv);
00734 
00735   // SLOTS/SIGNAL, pop menu, indi server logic
00736   return true;
00737 }
00738 
00739 int INDIDriver::activeDriverCount()
00740 {
00741   int count = 0;
00742 
00743   for (uint i=0; i < devices.size(); i++)
00744     if (devices[i]->state && devices[i]->mode == IDevice::M_LOCAL)
00745       count++;
00746 
00747   for (uint i=0; i < ksw->data()->INDIHostsList.count(); i++)
00748     if (ksw->data()->INDIHostsList.at(i)->isConnected)
00749       count++;
00750 
00751 
00752   return count;
00753 
00754 }
00755 
00756 void INDIDriver::addINDIHost()
00757 {
00758   INDIHostConf hostConf(this);
00759   hostConf.setCaption(i18n("Add Host"));
00760   bool portOk = false;
00761 
00762   if (hostConf.exec() == QDialog::Accepted)
00763   {
00764     INDIHostsInfo *hostItem = new INDIHostsInfo;
00765     hostItem->name        = hostConf.nameIN->text();
00766     hostItem->hostname    = hostConf.hostname->text();
00767     hostItem->portnumber  = hostConf.portnumber->text();
00768     hostItem->isConnected = false;
00769     hostItem->mgrID       = -1;
00770 
00771     hostItem->portnumber.toInt(&portOk);
00772 
00773     if (portOk == false)
00774     {
00775      KMessageBox::error(0, i18n("Error: the port number is invalid."));
00776      return;
00777     }
00778 
00779     //search for duplicates
00780     for (uint i=0; i < ksw->data()->INDIHostsList.count(); i++)
00781      if (hostItem->name   == ksw->data()->INDIHostsList.at(i)->name &&
00782          hostItem->portnumber == ksw->data()->INDIHostsList.at(i)->portnumber)
00783      {
00784        KMessageBox::error(0, i18n("Host: %1 Port: %2 already exists.").arg(hostItem->name).arg(hostItem->portnumber));
00785        return;
00786      }
00787 
00788     ksw->data()->INDIHostsList.append(hostItem);
00789 
00790     QListViewItem *item = new QListViewItem(clientListView);
00791     item->setPixmap(0, disconnected);
00792     item->setText(1, hostConf.nameIN->text());
00793     item->setText(2, hostConf.portnumber->text());
00794 
00795   }
00796 
00797     saveHosts();
00798 }
00799 
00800 
00801 
00802 void INDIDriver::modifyINDIHost()
00803 {
00804 
00805   INDIHostConf hostConf(this);
00806   hostConf.setCaption(i18n("Modify Host"));
00807 
00808   QListViewItem *currentItem = clientListView->currentItem();
00809 
00810   if (currentItem == NULL)
00811    return;
00812 
00813   for (uint i=0; i < ksw->data()->INDIHostsList.count(); i++)
00814      if (currentItem->text(1) == ksw->data()->INDIHostsList.at(i)->name &&
00815          currentItem->text(2) == ksw->data()->INDIHostsList.at(i)->portnumber)
00816      {
00817 
00818         hostConf.nameIN->setText(ksw->data()->INDIHostsList.at(i)->name);
00819     hostConf.hostname->setText(ksw->data()->INDIHostsList.at(i)->hostname);
00820     hostConf.portnumber->setText(ksw->data()->INDIHostsList.at(i)->portnumber);
00821 
00822     if (hostConf.exec() == QDialog::Accepted)
00823     {
00824         INDIHostsInfo *hostItem = new INDIHostsInfo;
00825     hostItem->name       = hostConf.nameIN->text();
00826         hostItem->hostname   = hostConf.hostname->text();
00827         hostItem->portnumber = hostConf.portnumber->text();
00828 
00829         currentItem->setText(1, hostConf.nameIN->text());
00830         currentItem->setText(2, hostConf.portnumber->text());
00831 
00832         ksw->data()->INDIHostsList.replace(clientListView->itemIndex(currentItem), hostItem);
00833 
00834         saveHosts();
00835     }
00836 
00837      }
00838 }
00839 
00840 void INDIDriver::removeINDIHost()
00841 {
00842 
00843  if (clientListView->currentItem() == NULL)
00844   return;
00845 
00846  for (uint i=0; i < ksw->data()->INDIHostsList.count(); i++)
00847      if (clientListView->currentItem()->text(1) == ksw->data()->INDIHostsList.at(i)->name &&
00848          clientListView->currentItem()->text(2) == ksw->data()->INDIHostsList.at(i)->portnumber)
00849    {
00850         if (ksw->data()->INDIHostsList.at(i)->isConnected)
00851         {
00852            KMessageBox::error( 0, i18n("You need to disconnect the client before removing it."));
00853            return;
00854         }
00855 
00856         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)
00857            return;
00858        
00859     ksw->data()->INDIHostsList.remove(i);
00860     clientListView->takeItem(clientListView->currentItem());
00861     break;
00862    }
00863 
00864  
00865 
00866  saveHosts();
00867 
00868 }
00869 
00870 void INDIDriver::saveHosts()
00871 {
00872 
00873  QFile file;
00874  QString hostData;
00875 
00876  file.setName( locateLocal( "appdata", "indihosts.xml" ) ); //determine filename in local user KDE directory tree.
00877 
00878  if ( !file.open( IO_WriteOnly))
00879  {
00880   QString message = i18n( "unable to write to file 'indihosts.xml'\nAny changes to INDI hosts configurations will not be saved." );
00881  KMessageBox::sorry( 0, message, i18n( "Could Not Open File" ) );
00882   return;
00883  }
00884 
00885  QTextStream outstream(&file);
00886 
00887  for (uint i= 0; i < ksw->data()->INDIHostsList.count(); i++)
00888  {
00889 
00890  hostData  = "<INDIHost name='";
00891  hostData += ksw->data()->INDIHostsList.at(i)->name;
00892  hostData += "' hostname='";
00893  hostData += ksw->data()->INDIHostsList.at(i)->hostname;
00894  hostData += "' port='";
00895  hostData += ksw->data()->INDIHostsList.at(i)->portnumber;
00896  hostData += "' />\n";
00897 
00898  outstream << hostData;
00899 
00900  }
00901 
00902   file.close();
00903 
00904 }
00905 
00906 INDIDriver::~INDIDriver()
00907 {
00908 
00909   for (uint i=0; i < devices.size(); i++)
00910    delete (devices[i]);
00911 
00912 }
00913 
00914 IDevice::IDevice(QString inLabel, QString inDriver, QString inVersion)
00915 {
00916   label = inLabel;;
00917   driver = inDriver;;
00918   version = inVersion;
00919 
00920   // Initially off
00921   state = 0;
00922 
00923   // No port initially
00924   indiPort = -1;
00925 
00926   // not yet managed by DeviceManager
00927   managed = false;
00928 
00929   mgrID = -1;
00930 
00931   focal_length = -1;
00932   aperture = -1;
00933 
00934   proc = NULL;
00935 
00936 }
00937 
00938 void IDevice::processstd(KProcess* /*proc*/, char* buffer, int /*buflen*/)
00939 {
00940   serverBuffer.append(buffer);
00941   emit newServerInput();
00942 }
00943 
00944 
00945 IDevice::~IDevice()
00946 {
00947   if (proc)
00948       proc->kill();
00949 
00950 }
00951 
00952 void IDevice::restart()
00953 {
00954 
00955   mgrID = -1;
00956 
00957   state = 0;
00958 
00959   indiPort = -1;
00960 
00961   if (proc)
00962     proc->kill();
00963 
00964   proc = NULL;
00965 
00966 }
00967 
00968 #include "indidriver.moc"

kstars

Skip menu "kstars"
  • Main Page
  • Modules
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • keduca
  • kstars
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal