7#include "drivermanager.h"
9#include "config-kstars.h"
11#include "clientmanager.h"
12#include "driverinfo.h"
13#include "guimanager.h"
14#include "indilistener.h"
18#include "kstarsdata.h"
20#include "servermanager.h"
21#include "ui_indihostconf.h"
22#include "auxiliary/ksnotification.h"
24#include <basedevice.h>
28#include <KActionCollection>
29#include <knotification.h>
33#include <QtConcurrent>
34#include <indi_debug.h>
36#define INDI_MAX_TRIES 2
37#define ERRMSG_SIZE 1024
39DriverManagerUI::DriverManagerUI(
QWidget *parent) :
QFrame(parent)
43 localTreeWidget->setSortingEnabled(
false);
44 localTreeWidget->setRootIsDecorated(
true);
46 clientTreeWidget->setSortingEnabled(
false);
57 &DriverManagerUI::makePortEditable);
60void DriverManagerUI::makePortEditable(
QTreeWidgetItem *selectedItem,
int column)
63 if (column == ::DriverManager::LOCAL_PORT_COLUMN)
67 localTreeWidget->editItem(selectedItem, ::DriverManager::LOCAL_PORT_COLUMN);
71INDIDBus *DriverManager::_INDIDBus =
nullptr;
75 if (_DriverManager ==
nullptr)
80 qRegisterMetaType<QSharedPointer<DriverInfo>>(
"QSharedPointer<DriverInfo>");
83 return _DriverManager;
86void DriverManager::release()
88 delete (_DriverManager);
90 _DriverManager =
nullptr;
100 currentPort = Options::serverPortStart() - 1;
103 ui =
new DriverManagerUI(
this);
105 setLayout(mainLayout);
106 setWindowTitle(
i18nc(
"@title:window",
"Device Manager"));
126 if (Options::indiDriversDir().isEmpty())
127 Options::setIndiDriversDir(
137 updateCustomDrivers();
140 ui->localTreeWidget->setEnabled(
false);
144DriverManager::~DriverManager()
151 if (driver.
isNull() || driver->getDriverSource() == GENERATED_SOURCE)
154 QString currentDriver;
155 ServerMode mode = connectionMode;
156 ServerManager *manager = driver->getServerManager();
160 if (driver->getDriverSource() != HOST_SOURCE)
162 if (ui->localTreeWidget->currentItem())
163 currentDriver = ui->localTreeWidget->currentItem()->text(LOCAL_NAME_COLUMN);
165 for (
auto &item : ui->localTreeWidget->findItems(
168 item->setText(LOCAL_VERSION_COLUMN, driver->getVersion());
171 mode = manager->getMode();
173 dState = driver->getServerState();
174 cState = driver->getClientState() && dState;
176 bool locallyAvailable =
false;
177 if (driver->getAuxInfo().contains(
"LOCALLY_AVAILABLE"))
179 driver->getAuxInfo().value(
"LOCALLY_AVAILABLE",
false).toBool();
184 if (locallyAvailable)
186 ui->runServiceB->setEnabled(!dState);
187 ui->stopServiceB->setEnabled(dState);
188 item->setIcon(LOCAL_STATUS_COLUMN,
189 dState ? ui->runningPix : ui->stopPix);
193 ui->runServiceB->setEnabled(
false);
194 ui->stopServiceB->setEnabled(
false);
199 item->setIcon(LOCAL_MODE_COLUMN, ui->serverMode);
207 item->setIcon(LOCAL_MODE_COLUMN, QIcon());
208 item->setText(LOCAL_PORT_COLUMN,
QString::number(driver->getUserPort()));
214 if (locallyAvailable)
216 ui->runServiceB->setEnabled(!cState);
217 ui->stopServiceB->setEnabled(cState);
218 item->setIcon(LOCAL_STATUS_COLUMN,
219 cState ? ui->runningPix : ui->stopPix);
223 ui->runServiceB->setEnabled(
false);
224 ui->stopServiceB->setEnabled(
false);
229 item->setIcon(LOCAL_MODE_COLUMN, ui->localMode);
238 item->setIcon(LOCAL_MODE_COLUMN, QIcon());
239 const auto port = driver->getUserPort() == -1 ? QString() : QString::
number(driver->getUserPort());
240 item->setText(LOCAL_PORT_COLUMN, port);
247 if (currentDriver == driver->getLabel())
249 ui->serverLogText->clear();
250 ui->serverLogText->append(driver->getServerBuffer());
256 for (
auto &item : ui->clientTreeWidget->findItems(driver->getName(),
Qt::MatchExactly,
259 if (driver->getClientState())
261 item->setIcon(HOST_STATUS_COLUMN, ui->connected);
262 ui->connectHostB->setEnabled(
false);
263 ui->disconnectHostB->setEnabled(
true);
267 item->setIcon(HOST_STATUS_COLUMN, ui->disconnected);
268 ui->connectHostB->setEnabled(
true);
269 ui->disconnectHostB->setEnabled(
false);
281 for (
auto &dv : dList)
286 for (
auto &idv : dList)
289 if ((dv->getHost() == idv->getHost() && dv->getPort() == idv->getPort()))
292 if (dv->getClientState() || dv->getServerState())
296 i18n(
"Driver %1 is already running, do you want to restart it?",
304 stopDevices(stopList);
311 for (
auto &qdi : uHosts)
328 if (uList.
empty() ==
false)
341 qCDebug(KSTARS_INDI) <<
"INDI: Starting local drivers...";
343 for (
auto &qdv : uHosts)
348 port = qdv.at(0)->getPort();
349 auto host = qdv.at(0)->getHost();
353 port = getINDIPort(port);
357 emit serverFailed(host, port,
i18n(
"Cannot start INDI server: port error."));
361 serverManager =
new ServerManager(host, port);
363 if (serverManager ==
nullptr)
365 emit serverFailed(host, port,
i18n(
"Failed to create local INDI server"));
369 servers.append(serverManager);
370 serverManager->setPendingDrivers(qdv);
371 serverManager->setMode(connectionMode);
378 serverManager->start();
382void DriverManager::startLocalDrivers(
ServerManager *serverManager)
386#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
395 emit driverStarted(driver);
397 auto manager = driver->getServerManager();
399 if (manager->pendingDrivers().
count() > 0)
401#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
410 if (connectionMode == SERVER_ONLY)
416 startClientManager(manager->managedDrivers(), manager->getHost(), manager->getPort());
421 emit driverFailed(driver, message);
423 qCWarning(KSTARS_INDI) <<
"Driver" << driver->getName() <<
"failed to start. Retrying in 5 seconds...";
427 auto manager = driver->getServerManager();
429 if (manager->pendingDrivers().
count() > 0)
431#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
443 auto clientManager =
new ClientManager();
446 clientManager->appendManagedDriver(dv);
454 GUIManager::Instance()->addClient(clientManager);
455 INDIListener::Instance()->addClient(clientManager);
457 clientManager->establishConnection();
462 qCDebug(KSTARS_INDI) <<
"INDI: Stopping local drivers...";
465 for (QSharedPointer<DriverInfo>dv : dList)
467 ClientManager *cm = dv->getClientManager();
474 if (cm->count() == 0)
476 GUIManager::Instance()->removeClient(cm);
477 INDIListener::Instance()->removeClient(cm);
478 cm->disconnectServer();
479 clients.removeOne(cm);
488 for (QSharedPointer<DriverInfo>dv : dList)
490 ServerManager *sm = dv->getServerManager();
499 servers.removeOne(sm);
506 currentPort = Options::serverPortStart() - 1;
511void DriverManager::disconnectClients()
513 for (
auto &clientManager : clients)
515 clientManager->disconnectAll();
516 clientManager->disconnect();
520void DriverManager::clearServers()
522 for (
auto &serverManager : servers)
523 serverManager->stop();
528void DriverManager::activateRunService()
530 processLocalTree(
true);
533void DriverManager::activateStopService()
535 processLocalTree(
false);
538void DriverManager::activateHostConnection()
540 processRemoteTree(
true);
543void DriverManager::activateHostDisconnection()
545 processRemoteTree(
false);
550 auto cm = driver->getClientManager();
554 else if (!clients.isEmpty())
556 auto host = driver->getHost();
557 auto port = driver->getPort();
558 auto it = std::find_if(clients.begin(), clients.end(), [host, port](
const auto & oneClient)
560 return oneClient->getHost() == host && oneClient->getPort() == port;
563 if (it != clients.end())
570void DriverManager::updateLocalTab()
572 if (ui->localTreeWidget->currentItem() ==
nullptr)
575 QString currentDriver = ui->localTreeWidget->currentItem()->text(LOCAL_NAME_COLUMN);
577 auto device = std::find_if(driversList.begin(), driversList.end(), [currentDriver](
const auto & oneDriver)
579 return currentDriver == oneDriver->getLabel();
581 if (device != driversList.end())
582 processDeviceStatus(*device);
585void DriverManager::updateClientTab()
587 QTreeWidgetItem *item = ui->clientTreeWidget->currentItem();
593 int port = item->
text(HOST_PORT_COLUMN).
toInt();
595 auto device = std::find_if(driversList.begin(), driversList.end(), [hostname, port](
const auto & oneDriver)
597 return hostname == oneDriver->getName() && port == oneDriver->getPort();
599 if (device != driversList.end())
600 processDeviceStatus(*device);
603void DriverManager::processLocalTree(
bool dState)
605 QList<QSharedPointer<DriverInfo>> processed_devices;
610 connectionMode = ui->localR->isChecked() ? SERVER_CLIENT : SERVER_ONLY;
612 for (
auto &item : ui->localTreeWidget->selectedItems())
614 for (
auto &device : driversList)
619 if (item->
text(LOCAL_NAME_COLUMN) == device->getLabel() &&
620 device->getServerState() != dState)
622 processed_devices.
append(device);
627 if (port == -1 && item->
text(LOCAL_PORT_COLUMN).
isEmpty() ==
false)
629 port = item->
text(LOCAL_PORT_COLUMN).
toInt(&portOK);
633 KSNotification::error(
i18n(
"Invalid port entry: %1", item->
text(LOCAL_PORT_COLUMN)));
638 device->setHostParameters(
"localhost", port);
643 if (processed_devices.
empty())
647 startDevices(processed_devices);
649 stopDevices(processed_devices);
652void DriverManager::setClientFailed(
const QString &message)
656 if (client ==
nullptr)
659 auto host = client->getHost();
660 auto port = client->getPort();
664 emit clientFailed(host, port, message);
666 GUIManager::Instance()->removeClient(client);
667 INDIListener::Instance()->removeClient(client);
669 KSNotification::event(QLatin1String(
"IndiServerMessage"), message, KSNotification::INDI);
671 clients.removeOne(client);
672 client->deleteLater();
674 if (connectionMode == SERVER_CLIENT)
675 activateStopService();
681void DriverManager::setClientTerminated(
const QString &message)
685 if (client ==
nullptr)
688 auto host = client->getHost();
689 auto port = client->getPort();
693 emit clientTerminated(host, port, message);
695 GUIManager::Instance()->removeClient(client);
696 INDIListener::Instance()->removeClient(client);
698 KSNotification::event(QLatin1String(
"IndiServerMessage"), message, KSNotification::INDI, KSNotification::Alert);
700 clients.removeOne(client);
701 client->deleteLater();
708void DriverManager::setServerStarted()
711 qCDebug(KSTARS_INDI) <<
"INDI: INDI Server started locally on port " << manager->getPort();
712 startLocalDrivers(manager);
713 emit serverStarted(manager->getHost(), manager->getPort());
716void DriverManager::setServerFailed(
const QString &message)
720 if (server ==
nullptr)
723 for (
auto &dv : driversList)
725 if (dv->getServerManager() == server)
731 if (server->getMode() == SERVER_ONLY)
732 KSNotification::error(message);
734 emit serverFailed(server->getHost(), server->getPort(), message);
735 servers.removeOne(server);
736 server->deleteLater();
741void DriverManager::setServerTerminated(
const QString &message)
745 if (server ==
nullptr)
748 for (
auto &dv : driversList)
750 if (dv->getServerManager() == server)
756 if (server->getMode() == SERVER_ONLY)
757 KSNotification::error(message);
759 emit serverTerminated(server->getHost(), server->getPort(), message);
760 servers.removeOne(server);
761 server->deleteLater();
766void DriverManager::processRemoteTree(
bool dState)
768 QTreeWidgetItem *currentItem = ui->clientTreeWidget->currentItem();
772 for (
auto &dv : driversList)
774 if (dv->getDriverSource() != HOST_SOURCE)
780 if (currentItem->
text(HOST_NAME_COLUMN) == dv->getName() &&
781 currentItem->
text(HOST_PORT_COLUMN).
toInt() == dv->getPort())
784 if (dv->getClientState() == dState)
789 connectRemoteHost(dv);
792 disconnectRemoteHost(dv);
799 auto host = driver->getHost();
800 auto port = driver->getPort();
802 auto clientManager =
new ClientManager();
804 clientManager->appendManagedDriver(driver);
812 GUIManager::Instance()->addClient(clientManager);
813 INDIListener::Instance()->addClient(clientManager);
815 clientManager->establishConnection();
818void DriverManager::setClientStarted()
821 if (clientManager ==
nullptr)
824 clients.append(clientManager);
828 KSNotification::event(QLatin1String(
"ConnectionSuccessful"),
829 i18n(
"Connected to INDI server"));
831 emit clientStarted(clientManager->getHost(), clientManager->getPort());
836 ClientManager *clientManager = driver->getClientManager();
842 GUIManager::Instance()->removeClient(clientManager);
843 INDIListener::Instance()->removeClient(clientManager);
844 clients.removeOne(clientManager);
853void DriverManager::resizeDeviceColumn()
855 ui->localTreeWidget->resizeColumnToContents(0);
858void DriverManager::updateMenuActions()
863 QAction *tmpAction =
nullptr;
864 bool activeDevice =
false;
866 if (clients.size() > 0)
870 if (tmpAction !=
nullptr)
877int DriverManager::getINDIPort(
int customPort)
880 qWarning() <<
"INDI server is currently not supported on Windows.";
883 int lastPort = Options::serverPortEnd();
884 bool success =
false;
888 if (currentPort > lastPort)
889 currentPort = Options::serverPortStart();
891 QTcpServer temp_server;
893 if (customPort != -1)
905 for (; currentPort <= lastPort; currentPort++)
918bool DriverManager::readINDIHosts()
920 QString indiFile(
"indihosts.xml");
925 LilXML *xmlParser = newLilXML();
926 XMLEle *root =
nullptr;
927 XMLAtt *ap =
nullptr;
928 QString hName, hHost, hPort;
934 delLilXML(xmlParser);
940 root = readXMLEle(xmlParser, c, errmsg);
945 ap = findXMLAtt(root,
"name");
948 delLilXML(xmlParser);
952 hName = QString(valuXMLAtt(ap));
955 ap = findXMLAtt(root,
"hostname");
959 delLilXML(xmlParser);
963 hHost = QString(valuXMLAtt(ap));
965 ap = findXMLAtt(root,
"port");
969 delLilXML(xmlParser);
973 hPort = QString(valuXMLAtt(ap));
975 QSharedPointer<DriverInfo> dv(
new DriverInfo(hName));
976 dv->setHostParameters(hHost, hPort.
toInt());
977 dv->setDriverSource(HOST_SOURCE);
979 connect(dv.get(), &DriverInfo::deviceStateChanged,
this, [dv,
this]()
981 processDeviceStatus(dv);
984 driversList.append(dv);
986 QTreeWidgetItem *item =
new QTreeWidgetItem(ui->clientTreeWidget, lastGroup);
988 item->
setIcon(HOST_STATUS_COLUMN, ui->disconnected);
989 item->
setText(HOST_NAME_COLUMN, hName);
990 item->
setText(HOST_PORT_COLUMN, hPort);
996 qDebug() << Q_FUNC_INFO << errmsg;
997 delLilXML(xmlParser);
1002 delLilXML(xmlParser);
1007bool DriverManager::readXMLDrivers()
1012 QString driversDir = Options::indiDriversDir();
1014 if (Options::indiDriversAreInternal())
1019 if (indiDir.
cd(driversDir) ==
false)
1021 KSNotification::error(
i18n(
"Unable to find INDI drivers directory: %1\nPlease "
1022 "make sure to set the correct "
1023 "path in KStars configuration",
1033 for (
auto &fileInfo : list)
1035 if (fileInfo.fileName().endsWith(QLatin1String(
"_sk.xml")))
1038 processXMLDriver(fileInfo.absoluteFilePath());
1042 processXMLDriver(QLatin1String(
":/indidrivers.xml"));
1047void DriverManager::processXMLDriver(
const QString &driverName)
1049 QFile file(driverName);
1052 KSNotification::error(
i18n(
"Failed to open INDI Driver file: %1", driverName));
1056 char errmsg[ERRMSG_SIZE];
1058 LilXML *xmlParser = newLilXML();
1059 XMLEle *root =
nullptr;
1060 XMLEle *ep =
nullptr;
1062 if (driverName.
endsWith(QLatin1String(
"drivers.xml")))
1063 driverSource = PRIMARY_XML;
1065 driverSource = THIRD_PARTY_XML;
1069 root = readXMLEle(xmlParser, c, errmsg);
1074 if (!strcmp(tagXMLEle(root),
"driversList"))
1076 for (ep = nextXMLEle(root, 1); ep !=
nullptr; ep = nextXMLEle(root, 0))
1078 if (!buildDeviceGroup(ep, errmsg))
1079 prXMLEle(stderr, ep, 0);
1085 if (!buildDeviceGroup(root, errmsg))
1086 prXMLEle(stderr, root, 0);
1093 qCDebug(KSTARS_INDI) << QString(errmsg);
1094 delLilXML(xmlParser);
1099 delLilXML(xmlParser);
1102bool DriverManager::buildDeviceGroup(XMLEle *root,
char errmsg[])
1107 QTreeWidgetItem *group;
1108 DeviceFamily groupType = KSTARS_TELESCOPE;
1111 if (strlen(tagXMLEle(root)) > 1024)
1115 ap = findXMLAtt(root,
"group");
1119 snprintf(errmsg, ERRMSG_SIZE,
"Tag %.64s does not have a group attribute",
1124 groupName = valuXMLAtt(ap);
1125 groupType = DeviceFamilyLabels.key(groupName);
1129 if (groupType == KSTARS_CCD || groupType == KSTARS_VIDEO)
1134 QList<QTreeWidgetItem *> treeList =
1137 group = treeList[0];
1139 group =
new QTreeWidgetItem(ui->localTreeWidget, lastGroup);
1144 for (ep = nextXMLEle(root, 1); ep !=
nullptr; ep = nextXMLEle(root, 0))
1146 if (!buildDriverElement(ep, group, groupType, errmsg))
1153bool DriverManager::buildDriverElement(XMLEle *root,
QTreeWidgetItem *DGroup,
1154 DeviceFamily groupType,
char errmsg[])
1162 QString manufacturer(
"Others");
1169 ap = findXMLAtt(root,
"label");
1172 snprintf(errmsg, ERRMSG_SIZE,
"Tag %.64s does not have a label attribute",
1177 label = valuXMLAtt(ap);
1180 if (findDriverByLabel(label) !=
nullptr)
1183 ap = findXMLAtt(root,
"manufacturer");
1185 manufacturer = valuXMLAtt(ap);
1188 ap = findXMLAtt(root,
"port");
1190 port = valuXMLAtt(ap);
1194 ap = findXMLAtt(root,
"skel");
1196 skel = valuXMLAtt(ap);
1199 ap = findXMLAtt(root,
"mdpd");
1203 mdpd = (QString(valuXMLAtt(ap)) == QString(
"true")) ?
true : false;
1204 vMap.insert(
"mdpd", mdpd);
1207 el = findXMLEle(root,
"driver");
1212 driver = pcdataXMLEle(el);
1214 ap = findXMLAtt(el,
"name");
1217 snprintf(errmsg, ERRMSG_SIZE,
"Tag %.64s does not have a name attribute",
1222 name = valuXMLAtt(ap);
1224 el = findXMLEle(root,
"version");
1230 bool versionOK =
false;
1232 if (versionOK ==
false)
1235 bool driverIsAvailable = checkDriverAvailability(driver);
1237 vMap.insert(
"LOCALLY_AVAILABLE", driverIsAvailable);
1240 QTreeWidgetItem *device =
new QTreeWidgetItem(DGroup);
1242 device->
setText(LOCAL_NAME_COLUMN, label);
1243 if (driverIsAvailable)
1244 device->
setIcon(LOCAL_STATUS_COLUMN, ui->stopPix);
1246 device->
setIcon(LOCAL_STATUS_COLUMN, remoteIcon);
1247 device->
setText(LOCAL_VERSION_COLUMN, version);
1248 device->
setText(LOCAL_PORT_COLUMN, port);
1251 if (groupType == KSTARS_TELESCOPE && driversStringList.contains(driver) ==
false)
1252 driversStringList.append(driver);
1254 QSharedPointer<DriverInfo> dv(
new DriverInfo(name));
1256 dv->setLabel(label);
1257 dv->setVersion(version);
1258 dv->setExecutable(driver);
1259 dv->setManufacturer(manufacturer);
1260 dv->setSkeletonFile(skel);
1261 dv->setType(groupType);
1262 dv->setDriverSource(driverSource);
1264 dv->setAuxInfo(vMap);
1266 connect(dv.get(), &DriverInfo::deviceStateChanged,
this, [dv,
this]()
1268 processDeviceStatus(dv);
1271 driversList.append(dv);
1276bool DriverManager::checkDriverAvailability(
const QString &driver)
1278 QString indiServerDir = Options::indiServer();
1279 if (Options::indiServerIsInternal())
1282 indiServerDir = QFileInfo(Options::indiServer()).dir().path();
1284 QFile driverFile(indiServerDir +
'/' + driver);
1286 if (driverFile.exists() ==
false)
1292void DriverManager::updateCustomDrivers()
1294 for (
const QVariantMap &oneDriver : m_CustomDrivers->customDrivers())
1296 QSharedPointer<DriverInfo> dv(
new DriverInfo(oneDriver[
"Name"].
toString()));
1297 dv->setLabel(oneDriver[
"Label"].
toString());
1298 dv->setUniqueLabel(dv->getLabel());
1299 dv->setExecutable(oneDriver[
"Exec"].
toString());
1300 dv->setVersion(oneDriver[
"Version"].
toString());
1301 dv->setManufacturer(oneDriver[
"Manufacturer"].
toString());
1302 dv->setType(DeviceFamilyLabels.key(oneDriver[
"Family"].toString()));
1303 dv->setDriverSource(CUSTOM_SOURCE);
1305 bool driverIsAvailable = checkDriverAvailability(oneDriver[
"Exec"].
toString());
1307 vMap.insert(
"LOCALLY_AVAILABLE", driverIsAvailable);
1308 dv->setAuxInfo(vMap);
1310 driversList.append(dv);
1316void DriverManager::updateCustomDrivers()
1322 QTreeWidgetItem *group =
nullptr;
1323 QTreeWidgetItem *widgetDev =
nullptr;
1325 QSharedPointer<DriverInfo>drv =
nullptr;
1328 QList<QTreeWidgetItem *> treeList = ui->localTreeWidget->findItems(
"Telescopes",
Qt::MatchExactly);
1330 group = treeList[0];
1334 KStarsData::Instance()->
logObject()->readAll();
1337 foreach (OAL::Scope *s, *(KStarsData::Instance()->logObject()->scopeList()))
1341 if (s->driver() ==
i18n(
"None"))
1345 if ((drv = findDriverByLabel(label)))
1347 if (s->aperture() > 0 && s->focalLength() > 0)
1349 vMap.insert(
"TELESCOPE_APERTURE", s->aperture());
1350 vMap.insert(
"TELESCOPE_FOCAL_LENGTH", s->focalLength());
1351 drv->setAuxInfo(vMap);
1354 drv->setExecutable(s->driver());
1359 driver = s->driver();
1362 QTreeWidgetItem *device =
new QTreeWidgetItem(group);
1363 device->
setText(LOCAL_NAME_COLUMN, QString(label));
1364 device->
setIcon(LOCAL_STATUS_COLUMN, ui->stopPix);
1365 device->
setText(LOCAL_VERSION_COLUMN, QString(version));
1367 QSharedPointer<DriverInfo>dv =
new DriverInfo(name);
1369 dv->setLabel(label);
1370 dv->setExecutable(driver);
1371 dv->setVersion(version);
1372 dv->setType(KSTARS_TELESCOPE);
1373 dv->setDriverSource(EM_XML);
1375 if (s->aperture() > 0 && s->focalLength() > 0)
1377 vMap.insert(
"TELESCOPE_APERTURE", s->aperture());
1378 vMap.insert(
"TELESCOPE_FOCAL_LENGTH", s->focalLength());
1379 dv->setAuxInfo(vMap);
1382 connect(dv, SIGNAL(deviceStateChanged(DriverInfo*)),
this, SLOT(processDeviceStatus(DriverInfo*)));
1383 driversList.append(dv);
1387 foreach (QSharedPointer<DriverInfo>dev, driversList)
1390 if (dev->getDriverSource() != EM_XML || dev->getClientState())
1393 if (KStarsData::Instance()->logObject()->findScopeByName(dev->getName()))
1397 QList<QTreeWidgetItem *> devList =
1401 widgetDev = devList[0];
1407 driversList.removeOne(dev);
1413void DriverManager::addINDIHost()
1416 Ui::INDIHostConf hostConf;
1417 hostConf.setupUi(&hostConfDialog);
1419 bool portOk =
false;
1423 QSharedPointer<DriverInfo> hostItem(
new DriverInfo(hostConf.nameIN->text()));
1425 hostConf.portnumber->text().toInt(&portOk);
1427 if (portOk ==
false)
1429 KSNotification::error(
i18n(
"Error: the port number is invalid."));
1433 hostItem->setHostParameters(hostConf.hostname->text(),
1434 hostConf.portnumber->text().toInt());
1438 foreach (QSharedPointer<DriverInfo>host, driversList)
1439 if (hostItem->getName() == host->getName() &&
1440 hostItem->getPort() == host->getPort())
1442 KSNotification::error(
i18n(
"Host: %1 Port: %2 already exists.",
1443 hostItem->getName(), hostItem->getPort()));
1447 hostItem->setDriverSource(HOST_SOURCE);
1449 connect(hostItem.get(), &DriverInfo::deviceStateChanged,
this, [hostItem,
this]()
1451 processDeviceStatus(hostItem);
1454 driversList.append(hostItem);
1456 QTreeWidgetItem *item =
new QTreeWidgetItem(ui->clientTreeWidget);
1457 item->
setIcon(HOST_STATUS_COLUMN, ui->disconnected);
1458 item->
setText(HOST_NAME_COLUMN, hostConf.nameIN->text());
1459 item->
setText(HOST_PORT_COLUMN, hostConf.portnumber->text());
1465void DriverManager::modifyINDIHost()
1468 Ui::INDIHostConf hostConf;
1469 hostConf.
setupUi(&hostConfDialog);
1472 QTreeWidgetItem *currentItem = ui->clientTreeWidget->currentItem();
1474 if (currentItem ==
nullptr)
1477 for (
auto &host : driversList)
1479 if (currentItem->
text(HOST_NAME_COLUMN) == host->getName() &&
1480 currentItem->
text(HOST_PORT_COLUMN).
toInt() == host->getPort())
1482 hostConf.nameIN->setText(host->getName());
1483 hostConf.hostname->setText(host->getHost());
1488 host->setName(hostConf.nameIN->text());
1489 host->setHostParameters(hostConf.hostname->text(),
1490 hostConf.portnumber->text().toInt());
1492 currentItem->
setText(HOST_NAME_COLUMN, hostConf.nameIN->text());
1493 currentItem->
setText(HOST_PORT_COLUMN, hostConf.portnumber->text());
1502void DriverManager::removeINDIHost()
1504 if (ui->clientTreeWidget->currentItem() ==
nullptr)
1507 foreach (QSharedPointer<DriverInfo>host, driversList)
1508 if (ui->clientTreeWidget->currentItem()->text(HOST_NAME_COLUMN) ==
1510 ui->clientTreeWidget->currentItem()->text(HOST_PORT_COLUMN).toInt() ==
1513 if (host->getClientState())
1515 KSNotification::error(
1516 i18n(
"You need to disconnect the client before removing it."));
1522 i18n(
"Are you sure you want to remove the %1 client?",
1523 ui->clientTreeWidget->currentItem()->text(HOST_NAME_COLUMN)),
1524 i18n(
"Delete Confirmation"),
1528 driversList.removeOne(host);
1529 delete (ui->clientTreeWidget->currentItem());
1536void DriverManager::saveHosts()
1543 .filePath(
"indihosts.xml"));
1547 KSNotification::sorry(
i18n(
"Unable to write to file 'indihosts.xml'\nAny changes "
1548 "to INDI hosts configurations will not be saved."),
1549 i18n(
"Could Not Open File"));
1553 QTextStream outstream(&file);
1556 foreach (QSharedPointer<DriverInfo>host, driversList)
1558 if (host->getDriverSource() != HOST_SOURCE)
1561 hostData =
"<INDIHost name='";
1562 hostData += host->getName();
1563 hostData +=
"' hostname='";
1564 hostData += host->getHost();
1565 hostData +=
"' port='";
1567 hostData +=
"' />\n";
1569 outstream << hostData;
1577 auto driver = std::find_if(driversList.begin(), driversList.end(), [name](
auto & oneDriver)
1579 return oneDriver->getName() == name;
1582 if (driver != driversList.end())
1585 return QSharedPointer<DriverInfo>();
1590 auto driver = std::find_if(driversList.begin(), driversList.end(), [label](
auto & oneDriver)
1592 return oneDriver->getLabel() == label;
1595 if (driver != driversList.end())
1598 return QSharedPointer<DriverInfo>();
1603 auto driver = std::find_if(driversList.begin(), driversList.end(), [
exec](
auto & oneDriver)
1605 return oneDriver->getLabel() == exec;
1608 if (driver != driversList.end())
1611 return QSharedPointer<DriverInfo>();
1617 QString uniqueLabel =
label;
1619 for (
auto &cm : clients)
1621 auto devices = cm->getDevices();
1623 for (
auto &dv : devices)
1625 if (label == QString(dv.getDeviceName()))
1630 uniqueLabel = QString(
"%1 %2").
arg(label).
arg(nset + 1);
1635QJsonArray DriverManager::getDriverList()
const
1637 QJsonArray driverArray;
1639 for (
const auto &drv : driversList)
1640 driverArray.
append(drv->toJson());
1647 for (
auto &oneServer : servers)
1649 if (oneServer->contains(driver))
1651 return oneServer->restartDriver(driver);
ClientManager manages connection to INDI server, creation of devices, and receiving/sending propertie...
void disconnectAll()
disconnectAll Disconnect from server and disconnect all BLOB Managers.
void removeManagedDriver(const QSharedPointer< DriverInfo > &driver)
removeManagedDriver Remove managed driver from pool of drivers managed by this client manager.
Handles adding new drivers to database.
DriverManager is the primary class to handle all operations related to starting and stopping INDI dri...
void getUniqueHosts(const QList< QSharedPointer< DriverInfo > > &dList, QList< QList< QSharedPointer< DriverInfo > > > &uHosts)
getUniqueHosts Given a list of DriverInfos, extract all the host:port information from all the driver...
Collection of INDI DBus functions.
Q_INVOKABLE QAction * action(const QString &name) const
static void beep(const QString &reason=QString())
OAL::Log * logObject()
Return log object.
static KStars * Instance()
void slotSetDomeEnabled(bool enable)
slotSetDomeEnabled call when dome comes online or goes offline.
void slotSetTelescopeEnabled(bool enable)
slotSetTelescopeEnabled call when telescope comes online or goes offline.
virtual KActionCollection * actionCollection() const
ServerManager is responsible for starting and shutting local INDI servers.
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
char * toString(const EngineQuery &query)
KIOCORE_EXPORT QString number(KIO::filesize_t size)
ButtonCode warningContinueCancel(QWidget *parent, const QString &text, const QString &title=QString(), const KGuiItem &buttonContinue=KStandardGuiItem::cont(), const KGuiItem &buttonCancel=KStandardGuiItem::cancel(), const QString &dontAskAgainName=QString(), Options options=Notify)
KIOCORE_EXPORT QStringList list(const QString &fileClass)
QString name(StandardAction id)
QString label(StandardShortcut id)
NETWORKMANAGERQT_EXPORT QString hostname()
NETWORKMANAGERQT_EXPORT QString version()
const char * constData() const const
QString applicationDirPath()
QDialog(QWidget *parent, Qt::WindowFlags f)
bool cd(const QString &dirName)
QFileInfoList entryInfoList(Filters filters, SortFlags sort) const const
void setFilter(Filters filters)
void setNameFilters(const QStringList &nameFilters)
virtual QString fileName() const const override
bool open(FILE *fh, OpenMode mode, FileHandleFlags handleFlags)
void setFileName(const QString &name)
virtual void close() override
QIcon fromTheme(const QString &name)
void append(const QJsonValue &value)
void append(QList< T > &&value)
qsizetype count() const const
bool isEmpty() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
T qobject_cast(QObject *object)
QObject * sender() const const
bool isNull() const const
QString findExecutable(const QString &executableName, const QStringList &paths)
QString locate(StandardLocation type, const QString &fileName, LocateOptions options)
QString arg(Args &&... args) const const
bool endsWith(QChar c, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
QString number(double n, char format, int precision)
double toDouble(bool *ok) const const
int toInt(bool *ok, int base) const const
QByteArray toLatin1() const const
QFuture< T > run(Function function,...)
bool listen(const QHostAddress &address, quint16 port)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
void expanded(const QModelIndex &index)
void setText(int column, const QString &text)
QString text(int column) const const