Commit 1ec33812 authored by Artem Fedoskin's avatar Artem Fedoskin
Browse files

Added support of "Light" properties to INDI. Eliminated a few bugs with

UI.
parent d03d3fcc
......@@ -692,6 +692,7 @@ if(BUILD_KSTARS_LITE)
kstarslite/qml/indi/ImagePreview.qml
kstarslite/qml/indi/modules/MotionControl.qml
kstarslite/qml/indi/modules/Led.qml
kstarslite/qml/indi/modules/KSLed.qml
kstarslite/qml/indi/modules/Property.qml
kstarslite/qml/indi/modules/KSTab.qml
kstarslite/qml/indi/modules/KSComboBox.qml
......
......@@ -35,6 +35,8 @@
#include "kspaths.h"
#include <QApplication>
const char *libindi_strings_context = "string from libindi, used in the config dialog";
#ifdef Q_OS_ANDROID
#include "../../android_lib/include/libraw/libraw.h"
#endif
......@@ -103,12 +105,24 @@ void ClientManagerLite::setConnected(bool connected) {
emit connectedChanged(connected);
}
QString ClientManagerLite::updateLED(QString device, QString property) {
QString ClientManagerLite::syncLED(QString device, QString property, QString name) {
foreach(DeviceInfoLite *devInfo, m_devices) {
if(devInfo->device->getDeviceName() == device) {
INDI::Property *prop = devInfo->device->getProperty(property.toStdString().c_str());
INDI::Property *prop = devInfo->device->getProperty(property.toLatin1());
if(prop) {
switch (prop->getState())
IPState state = prop->getState();
if(!name.isEmpty()) {
ILight *lights = prop->getLight()->lp;
for (int i=0; i < prop->getLight()->nlp; i++) {
if(lights[i].name == name) {
state = lights[i].s;
break;
}
if(i == prop->getLight()->nlp - 1) return ""; // no Light with name "name" found so return empty string
}
}
switch (state)
{
case IPS_IDLE:
return "grey";
......@@ -368,6 +382,70 @@ void ClientManagerLite::buildSwitch(bool buttonGroup, ISwitch *sw, INDI::Propert
}
}
void ClientManagerLite::buildLightGUI(INDI::Property *property) {
ILightVectorProperty *lvp = property->getLight();
if (lvp == NULL)
return;
for (int i=0; i < lvp->nlp; i++)
{
ILight *ilp = &(lvp->lp[i]);
QString name = ilp->name;
QString label = i18nc(libindi_strings_context, ilp->label);
if (label == "(I18N_EMPTY_MESSAGE)")
label = ilp->label;
if (label.isEmpty())
label = i18nc(libindi_strings_context, ilp->name);
if (label == "(I18N_EMPTY_MESSAGE)")
label = ilp->name;
emit createINDILight(property->getDeviceName(), property->getName(), label, name);
}
}
/*void ClientManagerLite::buildBLOBGUI(INDI::Property *property) {
IBLOBVectorProperty *ibp = property->getBLOB();
QString name = ibp->name;
QString label = i18nc(libindi_strings_context, ibp->label);
if (label == "(I18N_EMPTY_MESSAGE)")
label = ibp->label;
if (label.isEmpty())
label = i18nc(libindi_strings_context, ibp->name);
if (label == "(I18N_EMPTY_MESSAGE)")
label = ibp->name;
text = i18n("INDI DATA STREAM");
switch (property->getPermission())
{
case IP_RW:
setupElementRead(ELEMENT_READ_WIDTH);
setupElementWrite(ELEMENT_WRITE_WIDTH);
setupBrowseButton();
break;
case IP_RO:
setupElementRead(ELEMENT_FULL_WIDTH);
break;
case IP_WO:
setupElementWrite(ELEMENT_FULL_WIDTH);
setupBrowseButton();
break;
}
guiProp->addLayout(EHBox);
}*/
void ClientManagerLite::sendNewINDISwitch(QString deviceName, QString propName, QString name) {
foreach(DeviceInfoLite *devInfo, m_devices) {
INDI::BaseDevice *device = devInfo->device;
......@@ -597,7 +675,7 @@ void ClientManagerLite::newProperty(INDI::Property *property)
break;
case INDI_LIGHT:
//buildLightGUI();
buildLightGUI(property);
break;
case INDI_BLOB:
......@@ -610,7 +688,7 @@ void ClientManagerLite::newProperty(INDI::Property *property)
}
void ClientManagerLite::removeProperty(INDI::Property *property) {
emit removeINDIProperty(property->getGroupName(),property->getName());
emit removeINDIProperty(property->getDeviceName(), property->getGroupName(),property->getName());
DeviceInfoLite *devInfo = nullptr;
foreach(DeviceInfoLite *di, m_devices) {
......@@ -632,6 +710,7 @@ void ClientManagerLite::removeProperty(INDI::Property *property) {
void ClientManagerLite::newBLOB(IBLOB *bp) {
processBLOBasCCD(bp);
emit newLEDState(bp->bvp->device , bp->name);
}
bool ClientManagerLite::processBLOBasCCD(IBLOB *bp) {
......@@ -785,6 +864,7 @@ void ClientManagerLite::newSwitch(ISwitchVectorProperty *svp) {
}
if(sw != NULL) {
emit newINDISwitch(svp->device, svp->name, sw->name, sw->s == ISS_ON);
emit newLEDState(svp->device, svp->name);
}
}
}
......@@ -805,6 +885,7 @@ void ClientManagerLite::newNumber(INumberVectorProperty *nvp)
QString numberName = num.name;
emit newINDINumber(deviceName, propName, numberName, QString(buf).trimmed());
emit newLEDState(deviceName, propName);
}
}
......@@ -816,12 +897,13 @@ void ClientManagerLite::newText(ITextVectorProperty *tvp) {
QString fieldName = text.name;
emit newINDIText(deviceName, propName, fieldName, text.text);
emit newLEDState(deviceName, propName);
}
}
void ClientManagerLite::newLight(ILightVectorProperty *lvp) {
QString deviceName = lvp->device;
QString propName = lvp->name;
emit newINDILight(lvp->device, lvp->name);
emit newLEDState(lvp->device, lvp->name);
}
void ClientManagerLite::newMessage(INDI::BaseDevice *dp, int messageID) {
......
......@@ -61,13 +61,20 @@ public:
QString connectedHost() { return m_connectedHost; }
void setConnectedHost(QString connectedHost);
void setConnected(bool connected);
Q_INVOKABLE QString updateLED(QString device, QString property);
/**
* @brief syncLED
* @param name of Light which LED needs to be synced
* @return color of state
*/
Q_INVOKABLE QString syncLED(QString device, QString property, QString name = "");
void buildTextGUI(INDI::Property * property);
void buildNumberGUI(INDI::Property * property);
void buildMenuGUI(INDI::Property * property);
void buildSwitchGUI(INDI::Property * property, PGui guiType);
void buildSwitch(bool buttonGroup, ISwitch *sw, INDI::Property *property, bool exclusive = false, PGui guiType = PG_BUTTONS);
void buildLightGUI(INDI::Property *property);
//void buildBLOBGUI(INDI::Property *property);
Q_INVOKABLE void sendNewINDISwitch(QString deviceName, QString propName, QString name);
Q_INVOKABLE void sendNewINDISwitch(QString deviceName, QString propName, int index);
......@@ -122,14 +129,18 @@ signals:
void createINDIMenu(QString deviceName, QString propName, QString switchLabel, QString switchName, bool isSelected);
void removeINDIProperty(QString groupName, QString propName);
void createINDILight(QString deviceName, QString propName, QString label, QString lightName);
void removeINDIProperty(QString deviceName, QString groupName, QString propName);
//Update signals
void newINDISwitch(QString deviceName, QString propName, QString switchName, bool isOn);
void newINDINumber(QString deviceName, QString propName, QString numberName, QString value);
void newINDIText(QString deviceName, QString propName, QString fieldName, QString text);
void newINDIMessage(QString message);
void newINDILight(QString deviceName, QString propName);
void newINDIBLOBImage(QString deviceName, bool isLoaded);
void newLEDState(QString deviceName, QString propName); // to sync LED for properties
void connectedHostChanged(QString);
void connectedChanged(bool);
......
......@@ -26,6 +26,8 @@ TelescopeLite::TelescopeLite(INDI::BaseDevice *device)
IsParked=false;
clientManager = KStarsLite::Instance()->clientManagerLite();
setSlewRate(0);
setSlewDecreasable(false);
setSlewIncreasable(true);
}
......
......@@ -47,7 +47,6 @@ class QQuickItem;
class KStarsLite : public QObject
{
Q_OBJECT
private:
/**
* @short Constructor.
......
......@@ -8,6 +8,7 @@ install( FILES modules/MotionControl.qml
modules/Led.qml
modules/Property.qml
modules/KSTab.qml
modules/KSLed.qml
modules/KSButtonSwitch.qml
modules/KSButtonsSwitchRow.qml
modules/KSINDIText.qml
......
......@@ -13,18 +13,26 @@ Item {
devicesPage.showPage(backtoInit)
}
property string title
property string deviceName
property ImagePreview imagePreview: null
KSPage {
id: devicesPage
contentItem: deviceTabView
title: devicesPanel.title
title: devicesPanel.deviceName + " - " + deviceTabView.currentTabTitle
TabView {
id: deviceTabView
currentIndex: 0
property var groups: []
property var properties: []
property var tabs: []
property string currentTabTitle: ""
onCurrentIndexChanged: {
currentTabTitle = getTab(currentIndex).title
}
Component.onCompleted: {
if(Qt.platform.os != "android") {
......@@ -39,7 +47,8 @@ Item {
Connections {
target: ClientManagerLite
onNewINDIProperty: {
if(devicesPage.title === deviceName) {
if(deviceTabView.currentTabTitle == "") deviceTabView.currentTabTitle = groupName
if(devicesPanel.deviceName === deviceName) {
if(deviceTabView.groups.indexOf(groupName) == -1) {
deviceTabView.groups.push(groupName)
var newTabComp = Qt.createComponent("modules/KSTab.qml");
......@@ -59,13 +68,14 @@ Item {
if(tab.title === groupName) {
var propComp = Qt.createComponent("modules/Property.qml");
var property = propComp.createObject(tab.columnItem)
property.name = propName
property.propName = propName
property.label = label
property.device = deviceName
if(propName == "CCD_EXPOSURE") {
property.deviceName = deviceName
property.parentTab = tab
if(propName == "CCD_EXPOSURE" && devicesPanel.imagePreview == null) {
var imgPreviewComp = Qt.createComponent("ImagePreview.qml");
var imagePreview = imgPreviewComp.createObject(devicesPanel)
imagePreview.deviceName = devicesPanel.title
devicesPanel.imagePreview = imgPreviewComp.createObject(devicesPanel)
devicesPanel.imagePreview.deviceName = devicesPanel.deviceName
}
}
}
......@@ -78,7 +88,7 @@ Item {
if(tab.title === groupName && groupName != "Motion Control") {
var columnItem = deviceTabView.tabs[i].columnItem
for(var c = 0; c < columnItem.children.length; ++c) {
if(columnItem.children[c].name === propName) {
if(columnItem.children[c].propName === propName) {
columnItem.children[c].destroy()
}
}
......@@ -87,6 +97,9 @@ Item {
groups.splice(groups.indexOf(groupName), 1)
tab.destroy()
}
/*if(propName == "CCD_EXPOSURE" && devicesPanel.imagePreview != null) {
imgPreview.destroy()
}*/
}
}
}
......
......@@ -33,6 +33,7 @@ KSPage {
devicesModel.get(i).panel.destroy()
}
devicesModel.clear()
showPage(initPage)
showPassiveNotification("Disconnected from the server")
}
}
......@@ -40,12 +41,13 @@ KSPage {
ColumnLayout {
id: cPanelColumn
spacing: 5 * num.dp
anchors {
top: parent.top
left: parent.left
right: parent.right
topMargin: 5 * num.dp
topMargin: 15 * num.dp
leftMargin: 25 * num.dp
rightMargin: 25 * num.dp
}
......@@ -92,7 +94,8 @@ KSPage {
}
Controls.Button {
text: indiPage.connected ? "Disconnect" : "Connect"
text: indiPage.connected ? "Disconnect" : "Connect "
onClicked: {
if(!indiPage.connected) {
if(ClientManagerLite.setHost(ipHost.text, parseInt(portHost.text))) {
......@@ -134,7 +137,7 @@ KSPage {
onNewINDIDevice: {
var component = Qt.createComponent(Qt.resolvedUrl("./DevicePanel.qml"));
var devicePanel = component.createObject(pagesWindow);
devicePanel.title = deviceName
devicePanel.deviceName = deviceName
devicesModel.append({ name: deviceName, panel: devicePanel })
}
onRemoveINDIDevice: {
......@@ -170,6 +173,8 @@ KSPage {
topPadding: 0
bottomPadding: 0
visible: connected
ListView {
id: list
......
......@@ -12,8 +12,8 @@ KSPage {
contentItem: imgPreviewColumn
title: "Image Preview - " + deviceName
property string deviceName: title
property Item buttonRow
property string deviceName
property Item buttonRow: null
Item {
id: imgPreviewColumn
......@@ -29,6 +29,7 @@ KSPage {
Layout.fillWidth: true
spacing: 5 * num.dp
Controls.Button {
text: "Save As"
......@@ -58,11 +59,13 @@ KSPage {
Connections {
target: ClientManagerLite
onNewINDIBLOBImage: {
image.source = "image://images/ccdPreview"
imagePreview.showPage()
if(imagePreview.deviceName == deviceName) {
image.source = "image://images/ccdPreview"
imagePreview.showPage()
}
}
onCreateINDIButton: {
if(deviceName == imagePreview.deviceName) {
if(imagePreview.deviceName == deviceName) {
if(propName == "UPLOAD_MODE") {
if(imagePreview.buttonRow == null) {
var buttonRowComp = Qt.createComponent("modules/KSButtonsSwitchRow.qml");
......@@ -75,5 +78,15 @@ KSPage {
}
}
}
onRemoveINDIProperty: {
if(imagePreview.deviceName == deviceName) {
if(propName == "UPLOAD_MODE") {
if(imagePreview.buttonRow != null) {
imagePreview.buttonRow.destroy()
imagePreview.buttonRow = null
}
}
}
}
}
}
......@@ -3,7 +3,7 @@ import QtQuick.Controls 1.4
Button {
property string switchName: ""
property Row parentRow
property Flow parentRow
checkable: true
checked: true
......
import QtQuick 2.4
import QtQuick.Controls 1.4
import QtQuick.Window 2.2
import "../../constants" 1.0
import QtQuick.Layouts 1.2
Row {
Flow {
id:buttonsRow
property bool checkBox: false
property string propName: ""
property string deviceName: ""
property bool exclusive: false
spacing: 5
//Layout.fillWidth: true
spacing: 5 * num.dp
Connections {
target: ClientManagerLite
......@@ -24,7 +28,6 @@ Row {
}
}
function addButton(propText, switchName, initChecked, enabled) {
var buttonComp = Qt.createComponent("KSButtonSwitch.qml");
var button = buttonComp.createObject(this)
......
......@@ -3,7 +3,7 @@ import QtQuick.Controls 1.4
CheckBox {
property string switchName: ""
property Row parentRow
property Flow parentRow
onClicked: {
parentRow.sendNewSwitch(switchName, null)
......
......@@ -2,14 +2,15 @@ import QtQuick 2.4
import QtQuick.Controls 1.4
ComboBox {
id: comboBox
property string deviceName: ""
property string propName: ""
Connections {
target: ClientManagerLite
onNewINDISwitch: {
if(deviceName == device) {
if(name == propName) {
if(comboBox.deviceName == deviceName) {
if(comboBox.propName == propName) {
for(var i = 0; i < model.count; ++i) {
if(model.get(i).name == switchName && isOn) {
currentIndex = i;
......@@ -23,7 +24,7 @@ ComboBox {
onActivated: {
if(index >= 0) {
ClientManagerLite.sendNewINDISwitch(deviceName,propName,index)
ClientManagerLite.sendNewINDISwitch(comboBox.deviceName, comboBox.propName,index)
}
}
......
......@@ -4,9 +4,10 @@ import "../../constants" 1.0
import org.kde.kirigami 1.0 as Kirigami
Column {
id: columnTextProp
Layout.fillHeight: true
Layout.fillWidth: true
spacing: 5 * num.dp
width: parent.width
property string propLabel: ""
Kirigami.Label {
......@@ -14,9 +15,9 @@ Column {
}
Rectangle {
id:separator
id: separator
height: num.dp
color: "grey"
height: 1 * num.dp
width: parent.width
}
......@@ -24,7 +25,7 @@ Column {
var textItem
if(writable) {
var textComp = Qt.createComponent("KSINDITextField.qml");
textItem = textComp.createObject(columnProp)
textItem = textComp.createObject(this)
textItem.deviceName = deviceName
textItem.propName = propName
textItem.fieldName = fieldName
......
......@@ -7,7 +7,7 @@ import QtQuick 2.4
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.4
Row {
Flow {
id: textRow
spacing: 5 * num.dp
anchors {
......@@ -62,5 +62,4 @@ Row {
}
}
}
}
import QtQuick 2.4
import QtQuick.Layouts 1.2
import QtQuick.Controls 1.4
import org.kde.kirigami 1.0 as Kirigami
import "../../constants" 1.0
import "../../modules"
Row {
spacing: 5
id: ledRow
property string deviceName
property string propName
property string label
property string name //Used in Light
onDeviceNameChanged: {
syncLEDProperty()
}
onPropNameChanged: {
syncLEDProperty()
}
function syncLEDProperty() {
led.color = ClientManagerLite.syncLED(ledRow.deviceName, ledRow.propName)
}
function syncLEDLight() {
led.color = ClientManagerLite.syncLED(ledRow.deviceName, ledRow.propName, ledRow.name)
}
Connections {
target: ClientManagerLite
onNewINDILight: {
if(ledRow.deviceName == deviceName) {
if(ledRow.propName == propName) {
ledRow.syncLEDLight() // We update only Lights here
}
}
}
}
Led {
id: led
color: "red"
anchors.verticalCenter: parent.verticalCenter
}
Kirigami.Label {
text: ledRow.label
anchors.verticalCenter: parent.verticalCenter
}
}
......@@ -3,6 +3,7 @@ import QtQuick.Layouts 1.2
import QtQuick.Controls 1.4
import org.kde.kirigami 1.0 as Kirigami
import "../../constants" 1.0
import "../../modules"
Tab {
id: tab
......@@ -10,7 +11,6 @@ Tab {
fill: parent