Kstars

indidevice.cpp
1 /*
2  SPDX-FileCopyrightText: 2012 Jasem Mutlaq (mutlaqja AT ikarustech DOT com)
3 
4  SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #include <indicom.h>
8 #include <base64.h>
9 #include <basedevice.h>
10 
11 #include <QFrame>
12 #include <QCheckBox>
13 #include <QLabel>
14 #include <QPushButton>
15 #include <QLayout>
16 #include <QButtonGroup>
17 #include <QSocketNotifier>
18 #include <QDateTime>
19 #include <QSplitter>
20 #include <QLineEdit>
21 #include <QDebug>
22 #include <QComboBox>
23 #include <QStatusBar>
24 #include <QMenu>
25 #include <QTabWidget>
26 #include <QTextEdit>
27 
28 #include <KLed>
29 #include <KLocalizedString>
30 #include <KMessageBox>
31 
32 #include "kstars.h"
33 #include "skymap.h"
34 #include "Options.h"
35 #include "skyobjects/skyobject.h"
36 #include "dialogs/timedialog.h"
37 #include "geolocation.h"
38 
39 #include "indiproperty.h"
40 #include "indidevice.h"
41 #include "indigroup.h"
42 #include "indielement.h"
43 
44 #include <indi_debug.h>
45 
46 const char *libindi_strings_context = "string from libindi, used in the config dialog";
47 
48 INDI_D::INDI_D(QWidget *parent, INDI::BaseDevice *in_dv, ClientManager *in_cm) : QWidget(parent)
49 {
50 #ifdef Q_OS_OSX
51  setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint);
52 #endif
53  m_BaseDevice = in_dv;
54  m_ClientManager = in_cm;
55 
56  m_Name = m_BaseDevice->getDeviceName();
57 
58  QHBoxLayout *layout = new QHBoxLayout(this);
59 
60  deviceVBox = new QSplitter(Qt::Vertical, this);
61 
62  groupContainer = new QTabWidget(this);
63 
64  msgST_w = new QTextEdit(this);
65  msgST_w->setReadOnly(true);
66  msgST_w->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContentsOnFirstShow);
67 
68  deviceVBox->addWidget(groupContainer);
69  deviceVBox->addWidget(msgST_w);
70  deviceVBox->setStretchFactor(0, 2);
71 
72  layout->addWidget(deviceVBox);
73 }
74 
75 bool INDI_D::buildProperty(INDI::Property prop)
76 {
77  if (!prop.isValid())
78  return false;
79 
80  QString groupName(prop.getGroupName());
81 
82  if (prop.getDeviceName() != m_Name)
83  return false;
84 
85  INDI_G *pg = getGroup(groupName);
86 
87  if (pg == nullptr)
88  {
89  pg = new INDI_G(this, groupName);
90  groupsList.append(pg);
91  groupContainer->addTab(pg, i18nc(libindi_strings_context, groupName.toUtf8()));
92  }
93 
94  return pg->addProperty(prop);
95 }
96 
97 #if 0
98 bool INDI_D::removeProperty(INDI::Property prop)
99 {
100  if (prop == nullptr)
101  return false;
102 
103  QString groupName(prop->getGroupName());
104 
105  if (strcmp(prop->getDeviceName(), m_BaseDevice->getDeviceName()))
106  {
107  // qDebug() << Q_FUNC_INFO << "Ignoring property " << prop->getName() << " for device " << prop->getgetDeviceName() << " because our device is "
108  // << dv->getDeviceName() << Qt::endl;
109  return false;
110  }
111 
112  // qDebug() << Q_FUNC_INFO << "Received new property " << prop->getName() << " for our device " << dv->getDeviceName() << Qt::endl;
113 
114  INDI_G *pg = getGroup(groupName);
115 
116  if (pg == nullptr)
117  return false;
118 
119  bool removeResult = pg->removeProperty(prop->getName());
120 
121  if (pg->size() == 0 && removeResult)
122  {
123  //qDebug() << Q_FUNC_INFO << "Removing tab for group " << pg->getName() << " with an index of " << groupsList.indexOf(pg) << Qt::endl;
124  groupContainer->removeTab(groupsList.indexOf(pg));
125  groupsList.removeOne(pg);
126  delete (pg);
127  }
128 
129  return removeResult;
130 }
131 #endif
132 
133 bool INDI_D::removeProperty(const QString &device, const QString &name)
134 {
135  if (device != m_Name)
136  return false;
137 
138  for (auto &oneGroup : groupsList)
139  {
140  for (auto &oneProperty : oneGroup->getProperties())
141  {
142  if (name == oneProperty->getName())
143  {
144  bool rc = oneGroup->removeProperty(name);
145  if (oneGroup->size() == 0)
146  {
147  int index = groupsList.indexOf(oneGroup);
148  groupContainer->removeTab(index);
149  delete groupsList.takeAt(index);
150  }
151  return rc;
152  }
153  }
154  }
155 
156  return false;
157 }
158 
159 bool INDI_D::updateSwitchGUI(ISwitchVectorProperty *svp)
160 {
161  INDI_P *guiProp = nullptr;
162  QString propName(svp->name);
163 
164  if (m_Name != svp->device)
165  return false;
166 
167  for (const auto &pg : groupsList)
168  {
169  if ((guiProp = pg->getProperty(propName)) != nullptr)
170  break;
171  }
172 
173  if (guiProp == nullptr || guiProp->isRegistered() == false)
174  return false;
175 
176  guiProp->updateStateLED();
177 
178  if (guiProp->getGUIType() == PG_MENU)
179  guiProp->updateMenuGUI();
180  else
181  {
182  for (const auto &lp : guiProp->getElements())
183  lp->syncSwitch();
184  }
185 
186  return true;
187 }
188 
189 bool INDI_D::updateTextGUI(ITextVectorProperty *tvp)
190 {
191  INDI_P *guiProp = nullptr;
192  QString propName(tvp->name);
193 
194  if (m_Name != tvp->device)
195  return false;
196 
197  for (const auto &pg : groupsList)
198  {
199  INDI_P * const p = pg->getProperty(propName);
200  if (p != nullptr)
201  {
202  guiProp = p;
203  break;
204  }
205  }
206 
207  if (guiProp == nullptr)
208  return false;
209 
210  guiProp->updateStateLED();
211 
212  for (const auto &lp : guiProp->getElements())
213  lp->syncText();
214 
215  return true;
216 }
217 
218 bool INDI_D::updateNumberGUI(INumberVectorProperty *nvp)
219 {
220  INDI_P *guiProp = nullptr;
221  QString propName(nvp->name);
222 
223  if (m_Name != nvp->device)
224  return false;
225 
226  for (const auto &pg : groupsList)
227  {
228  INDI_P * const p = pg->getProperty(propName);
229  if (p != nullptr)
230  {
231  guiProp = p;
232  break;
233  }
234  }
235 
236  if (guiProp == nullptr)
237  return false;
238 
239  guiProp->updateStateLED();
240 
241  for (const auto &lp : guiProp->getElements())
242  lp->syncNumber();
243 
244  return true;
245 }
246 
247 bool INDI_D::updateLightGUI(ILightVectorProperty *lvp)
248 {
249  INDI_P *guiProp = nullptr;
250  QString propName(lvp->name);
251 
252  if (m_Name != lvp->device)
253  return false;
254 
255  for (const auto &pg : groupsList)
256  {
257  INDI_P * const p = pg->getProperty(propName);
258  if (p != nullptr)
259  {
260  guiProp = p;
261  break;
262  }
263  }
264 
265  if (guiProp == nullptr)
266  return false;
267 
268  guiProp->updateStateLED();
269 
270  for (const auto &lp : guiProp->getElements())
271  lp->syncLight();
272 
273  return true;
274 }
275 
276 bool INDI_D::updateBLOBGUI(IBLOB *bp)
277 {
278  INDI_P *guiProp = nullptr;
279  QString propName(bp->bvp->name);
280 
281  if (m_Name != bp->bvp->device)
282  return false;
283 
284  for (const auto &pg : groupsList)
285  {
286  INDI_P * const p = pg->getProperty(propName);
287  if (p != nullptr)
288  {
289  guiProp = p;
290  break;
291  }
292  }
293 
294  if (guiProp == nullptr)
295  return false;
296 
297  guiProp->updateStateLED();
298 
299  return true;
300 }
301 
302 void INDI_D::updateMessageLog(INDI::BaseDevice *idv, int messageID)
303 {
304  if (idv != m_BaseDevice)
305  return;
306 
307  QString message = QString::fromStdString(m_BaseDevice->messageQueue(messageID));
308  QString formatted = message;
309 
310  // TODO the colors should be from the color scheme
311  if (message.mid(21, 2) == "[E")
312  formatted = QString("<span style='color:red'>%1</span>").arg(message);
313  else if (message.mid(21, 2) == "[W")
314  formatted = QString("<span style='color:orange'>%1</span>").arg(message);
315  else if (message.mid(21, 2) != "[I")
316  {
317  // Debug message
318  qCDebug(KSTARS_INDI) << idv->getDeviceName() << ":" << message.mid(21);
319  return;
320  }
321 
322  if (Options::showINDIMessages())
323  KStars::Instance()->statusBar()->showMessage(i18nc("INDI message shown in status bar", "%1", message), 0);
324 
325  msgST_w->ensureCursorVisible();
326  msgST_w->insertHtml(i18nc("Message shown in INDI control panel", "%1", formatted));
327  msgST_w->insertPlainText("\n");
328  QTextCursor c = msgST_w->textCursor();
330  msgST_w->setTextCursor(c);
331 
332  qCInfo(KSTARS_INDI) << idv->getDeviceName() << ": " << message.mid(21);
333 }
334 
335 //INDI_D::~INDI_D()
336 //{
337 // while (!groupsList.isEmpty())
338 // delete groupsList.takeFirst();
339 //}
340 
341 INDI_G *INDI_D::getGroup(const QString &groupName) const
342 {
343  for (const auto &pg : groupsList)
344  {
345  if (pg->getName() == groupName)
346  return pg;
347  }
348 
349  return nullptr;
350 }
351 
352 void INDI_D::clearMessageLog()
353 {
354  msgST_w->clear();
355 }
void addWidget(QWidget *widget, int stretch, Qt::Alignment alignment)
static KStars * Instance()
Definition: kstars.h:125
void showMessage(const QString &message, int timeout)
QString fromStdString(const std::string &str)
Vertical
QStatusBar * statusBar() const const
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
QString i18nc(const char *context, const char *text, const TYPE &arg...)
bool movePosition(QTextCursor::MoveOperation operation, QTextCursor::MoveMode mode, int n)
QString mid(int position, int n) const const
QString message
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Sat Aug 13 2022 04:01:54 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.