From kde-commits Sat Sep 30 22:01:29 2017 From: Csaba Kertesz Date: Sat, 30 Sep 2017 22:01:29 +0000 To: kde-commits Subject: [kstars] /: Implemented Web Manager interface in KStars Lite Message-Id: X-MARC-Message: https://marc.info/?l=kde-commits&m=150680890327567 Git commit 9af3580571d2edefd17cb6a831b753d0b48a4cf5 by Csaba Kertesz. Committed on 30/09/2017 at 22:01. Pushed by ckertesz into branch 'master'. Implemented Web Manager interface in KStars Lite M +1 -1 Tests/kstars_lite_ui/CMakeLists.txt M +213 -9 kstars/indi/clientmanagerlite.cpp M +73 -8 kstars/indi/clientmanagerlite.h M +4 -0 kstars/kstars.kcfg M +2 -1 kstars/kstarslite.cpp M +139 -27 kstars/kstarslite/qml/indi/INDIControlPanel.qml https://commits.kde.org/kstars/9af3580571d2edefd17cb6a831b753d0b48a4cf5 diff --git a/Tests/kstars_lite_ui/CMakeLists.txt b/Tests/kstars_lite_ui/CMa= keLists.txt index d1615d339..50c7a1bb6 100644 --- a/Tests/kstars_lite_ui/CMakeLists.txt +++ b/Tests/kstars_lite_ui/CMakeLists.txt @@ -10,7 +10,7 @@ ECM_ADD_APP_ICON(KSTARS_UI_TESTS_SRC ICONS ) = ADD_EXECUTABLE(kstars_lite_ui_tests ${KSTARS_LITE_UI_TESTS_SRC}) -TARGET_LINK_LIBRARIES(kstars_lite_ui_tests ${TEST_LIBRARIES}) +TARGET_LINK_LIBRARIES(kstars_lite_ui_tests ${TEST_LIBRARIES} -lpthread) = IF (INDI_FOUND) INCLUDE_DIRECTORIES(${INDI_INCLUDE_DIR}) diff --git a/kstars/indi/clientmanagerlite.cpp b/kstars/indi/clientmanagerl= ite.cpp index 823765ff9..86b398c38 100644 --- a/kstars/indi/clientmanagerlite.cpp +++ b/kstars/indi/clientmanagerlite.cpp @@ -33,8 +33,11 @@ #include #include #include +#include +#include #include #include +#include #include = const char *libindi_strings_context =3D "string from libindi, used in the = config dialog"; @@ -51,7 +54,7 @@ DeviceInfoLite::~DeviceInfoLite() { } = -ClientManagerLite::ClientManagerLite() +ClientManagerLite::ClientManagerLite(QQmlContext& main_context) : context(= main_context) { #ifdef ANDROID defaultImageType =3D ".jpeg"; @@ -60,13 +63,14 @@ ClientManagerLite::ClientManagerLite() qmlRegisterType("TelescopeLiteEnums", 1, 0, "TelescopeN= S"); qmlRegisterType("TelescopeLiteEnums", 1, 0, "TelescopeW= E"); qmlRegisterType("TelescopeLiteEnums", 1, 0, "TelescopeC= ommand"); + context.setContextProperty("webMProfileModel", QVariant::fromValue(web= MProfiles)); } = ClientManagerLite::~ClientManagerLite() { } = -bool ClientManagerLite::setHost(QString ip, unsigned int port) +bool ClientManagerLite::setHost(const QString &ip, unsigned int port) { if (!isConnected()) { @@ -92,9 +96,195 @@ void ClientManagerLite::disconnectHost() setConnectedHost(""); } = +void ClientManagerLite::getWebManagerProfiles(const QString &ip, unsigned = int port) +{ + if (webMProfilesReply.get() !=3D nullptr) + return; + + QString urlStr(QString("http://%1:%2/api/profiles").arg(ip).arg(port)); + QNetworkRequest request { QUrl(urlStr) }; + + webMProfilesReply.reset(manager.get(request)); + connect(webMProfilesReply.get(), SIGNAL(error(QNetworkReply::NetworkEr= ror)), + this, SLOT(webManagerReplyError(QNetworkReply::NetworkError))); + connect(webMProfilesReply.get(), &QNetworkReply::finished, this, &Clie= ntManagerLite::webManagerReplyFinished); + setLastUsedServer(ip); + setLastUsedWebManagerPort(port); +} + +void ClientManagerLite::startWebManagerProfile(const QString &profile) +{ + if (webMStartProfileReply.get() !=3D nullptr) + return; + + QString urlStr("http://%1:%2/api/server/start/%3"); + + urlStr =3D urlStr.arg(getLastUsedServer()).arg(getLastUsedWebManagerPo= rt()).arg(profile); + QNetworkRequest request { QUrl(urlStr) }; + + webMStartProfileReply.reset(manager.post(request, QByteArray())); + connect(webMStartProfileReply.get(), SIGNAL(error(QNetworkReply::Netwo= rkError)), + this, SLOT(webManagerReplyError(QNetworkReply::NetworkError))); + connect(webMStartProfileReply.get(), &QNetworkReply::finished, + this, &ClientManagerLite::webManagerReplyFinished); +} + +void ClientManagerLite::stopWebManagerProfile() +{ + if (webMStopProfileReply.get() !=3D nullptr) + return; + + QString urlStr(QString("http://%1:%2/api/server/stop").arg(getLastUsed= Server()).arg(getLastUsedWebManagerPort())); + QNetworkRequest request { QUrl(urlStr) }; + + webMStopProfileReply.reset(manager.post(request, QByteArray())); + connect(webMStopProfileReply.get(), SIGNAL(error(QNetworkReply::Networ= kError)), + this, SLOT(webManagerReplyError(QNetworkReply::NetworkError))); + connect(webMStopProfileReply.get(), &QNetworkReply::finished, + this, &ClientManagerLite::webManagerReplyFinished); +} + +void ClientManagerLite::webManagerReplyError(QNetworkReply::NetworkError c= ode) +{ + if (webMProfilesReply.get() !=3D nullptr) + { + qWarning("Web Manager profile query error: %d", (int)code); + KStarsLite::Instance()->notificationMessage(i18n("Couldn't connect= to the Web Manager")); + webMProfilesReply.release()->deleteLater(); + return; + } + if (webMStatusReply.get() !=3D nullptr) + { + qWarning("Web Manager status query error: %d", (int)code); + KStarsLite::Instance()->notificationMessage(i18n("Couldn't connect= to the Web Manager")); + webMStatusReply.release()->deleteLater(); + return; + } + if (webMStopProfileReply.get() !=3D nullptr) + { + qWarning("Web Manager stop active profile error: %d", (int)code); + KStarsLite::Instance()->notificationMessage(i18n("Couldn't connect= to the Web Manager")); + webMStopProfileReply.release()->deleteLater(); + return; + } + if (webMStartProfileReply.get() !=3D nullptr) + { + qWarning("Web Manager start active profile error: %d", (int)code); + KStarsLite::Instance()->notificationMessage(i18n("Couldn't connect= to the Web Manager")); + webMStartProfileReply.release()->deleteLater(); + return; + } +} + +void ClientManagerLite::webManagerReplyFinished() +{ + // Web Manager profile query + if (webMProfilesReply.get() !=3D nullptr) + { + QByteArray responseData =3D webMProfilesReply->readAll(); + QJsonDocument json =3D QJsonDocument::fromJson(responseData); + + webMProfilesReply.release()->deleteLater(); + if (!json.isArray()) + { + KStarsLite::Instance()->notificationMessage(i18n("Invalid resp= onse from Web Manager")); + return; + } + QJsonArray array =3D json.array(); + + webMProfiles.clear(); + for (int i =3D 0; i < array.size(); ++i) + { + if (array.at(i).isObject() && array.at(i).toObject().contains(= "name")) + { + webMProfiles +=3D array.at(i).toObject()["name"].toString(= ); + } + } + // Send a query for the network status + QString urlStr(QString("http://%1:%2/api/server/status").arg(getLa= stUsedServer()).arg(getLastUsedWebManagerPort())); + QNetworkRequest request { QUrl(urlStr) }; + + webMStatusReply.reset(manager.get(request)); + connect(webMStatusReply.get(), SIGNAL(error(QNetworkReply::Network= Error)), + this, SLOT(webManagerReplyError(QNetworkReply::NetworkErro= r))); + connect(webMStatusReply.get(), &QNetworkReply::finished, this, &Cl= ientManagerLite::webManagerReplyFinished); + return; + } + // Web Manager status query + if (webMStatusReply.get() !=3D nullptr) + { + QByteArray responseData =3D webMStatusReply->readAll(); + QJsonDocument json =3D QJsonDocument::fromJson(responseData); + + webMStatusReply.release()->deleteLater(); + if (!json.isArray() || json.array().size() !=3D 1 || !json.array()= .at(0).isObject()) + { + KStarsLite::Instance()->notificationMessage(i18n("Invalid resp= onse from Web Manager")); + return; + } + QJsonObject object =3D json.array().at(0).toObject(); + + // Check the response + if (!object.contains("status") || !object.contains("active_profile= ")) + { + KStarsLite::Instance()->notificationMessage(i18n("Invalid resp= onse from Web Manager")); + return; + } + QString statusStr =3D object["status"].toString(); + QString activeProfileStr =3D object["active_profile"].toString(); + + indiControlPage->setProperty("webMBrowserButtonVisible", true); + indiControlPage->setProperty("webMStatusTextVisible", true); + if (statusStr =3D=3D "True") + { + // INDI Server is running (online) + indiControlPage->setProperty("webMStatusText", QString(i18n("W= eb Manager Status:")+' '+i18n("Online"))); + indiControlPage->setProperty("webMActiveProfileText", + QString(i18n("Active Profile:")+"= "+activeProfileStr)); + indiControlPage->setProperty("webMActiveProfileLayoutVisible",= true); + indiControlPage->setProperty("webMProfileListVisible", false); + } else { + // INDI Server is not running (offline) + indiControlPage->setProperty("webMStatusText", QString(i18n("W= eb Manager Status:")+' '+i18n("Offline"))); + indiControlPage->setProperty("webMActiveProfileLayoutVisible",= false); + context.setContextProperty("webMProfileModel", QVariant::fromV= alue(webMProfiles)); + indiControlPage->setProperty("webMProfileListVisible", true); + } + return; + } + // Web Manager stop active profile + if (webMStopProfileReply.get() !=3D nullptr) + { + webMStopProfileReply.release()->deleteLater(); + indiControlPage->setProperty("webMStatusText", QString(i18n("Web M= anager Status:")+' '+i18n("Offline"))); + indiControlPage->setProperty("webMStatusTextVisible", true); + indiControlPage->setProperty("webMActiveProfileLayoutVisible", fal= se); + context.setContextProperty("webMProfileModel", QVariant::fromValue= (webMProfiles)); + indiControlPage->setProperty("webMProfileListVisible", true); + return; + } + // Web Manager start active profile + if (webMStartProfileReply.get() !=3D nullptr) + { + webMStartProfileReply.release()->deleteLater(); + // Send a query for the network status + QString urlStr("http://%1:%2/api/server/status"); + + urlStr =3D urlStr.arg(getLastUsedServer()).arg(getLastUsedWebManag= erPort()); + QNetworkRequest request { QUrl(urlStr) }; + + webMStatusReply.reset(manager.get(request)); + connect(webMStatusReply.get(), SIGNAL(error(QNetworkReply::Network= Error)), + this, SLOT(webManagerReplyError(QNetworkReply::NetworkErro= r))); + connect(webMStatusReply.get(), &QNetworkReply::finished, + this, &ClientManagerLite::webManagerReplyFinished); + return; + } +} + TelescopeLite *ClientManagerLite::getTelescope(const QString &deviceName) { - foreach (DeviceInfoLite *devInfo, m_devices) + for (auto& devInfo : m_devices) { if (devInfo->device->getDeviceName() =3D=3D deviceName) { @@ -104,7 +294,7 @@ TelescopeLite *ClientManagerLite::getTelescope(const QS= tring &deviceName) return nullptr; } = -void ClientManagerLite::setConnectedHost(QString connectedHost) +void ClientManagerLite::setConnectedHost(const QString &connectedHost) { m_connectedHost =3D connectedHost; setConnected(m_connectedHost.size() > 0); @@ -118,7 +308,7 @@ void ClientManagerLite::setConnected(bool connected) emit connectedChanged(connected); } = -QString ClientManagerLite::syncLED(QString device, QString property, QStri= ng name) +QString ClientManagerLite::syncLED(const QString &device, const QString &p= roperty, const QString &name) { foreach (DeviceInfoLite *devInfo, m_devices) { @@ -477,7 +667,7 @@ void ClientManagerLite::buildLightGUI(INDI::Property *p= roperty) guiProp->addLayout(EHBox); }*/ = -void ClientManagerLite::sendNewINDISwitch(QString deviceName, QString prop= Name, QString name) +void ClientManagerLite::sendNewINDISwitch(const QString &deviceName, const= QString &propName, const QString &name) { foreach (DeviceInfoLite *devInfo, m_devices) { @@ -577,7 +767,7 @@ void ClientManagerLite::sendNewINDIText(const QString &= deviceName, const QString } } = -void ClientManagerLite::sendNewINDISwitch(QString deviceName, QString prop= Name, int index) +void ClientManagerLite::sendNewINDISwitch(const QString &deviceName, const= QString &propName, int index) { if (index >=3D 0) { @@ -640,7 +830,7 @@ bool ClientManagerLite::saveDisplayImage() return false; } = -bool ClientManagerLite::isDeviceConnected(QString deviceName) +bool ClientManagerLite::isDeviceConnected(const QString &deviceName) { INDI::BaseDevice *device =3D getDevice(deviceName.toStdString().c_str(= )); = @@ -1025,7 +1215,7 @@ QString ClientManagerLite::getLastUsedServer() return Options::lastServer(); } = -void ClientManagerLite::setLastUsedServer(QString server) +void ClientManagerLite::setLastUsedServer(const QString &server) { if (getLastUsedServer() !=3D server) { @@ -1047,3 +1237,17 @@ void ClientManagerLite::setLastUsedPort(int port) lastUsedPortChanged(); } } + +int ClientManagerLite::getLastUsedWebManagerPort() +{ + return Options::lastWebManagerPort(); +} + +void ClientManagerLite::setLastUsedWebManagerPort(int port) +{ + if (getLastUsedWebManagerPort() !=3D port) + { + Options::setLastWebManagerPort(port); + lastUsedWebManagerPortChanged(); + } +} diff --git a/kstars/indi/clientmanagerlite.h b/kstars/indi/clientmanagerlit= e.h index 5fe806028..cd7af67d0 100644 --- a/kstars/indi/clientmanagerlite.h +++ b/kstars/indi/clientmanagerlite.h @@ -21,10 +21,13 @@ #include "indistd.h" = #include +#include +#include = #include = class QFileDialog; +class QQmlContext; = using namespace INDI; class TelescopeLite; @@ -62,27 +65,68 @@ class ClientManagerLite : public INDI::BaseClientQt * connected to some server at least once. **/ Q_PROPERTY(int lastUsedPort READ getLastUsedPort WRITE setLastUsedPort= NOTIFY lastUsedPortChanged) + + /** + * A wrapper for Options::lastServer(). Used to store last Web Manager= used port if user successfully + * connected at least once. + **/ + Q_PROPERTY(int lastUsedWebManagerPort READ getLastUsedWebManagerPort W= RITE setLastUsedWebManagerPort + NOTIFY lastUsedWebManagerPortChanged) public: typedef enum { UPLOAD_CLIENT, UPLOAD_LOCAL, UPLOAD_BOTH } UploadMode; = - ClientManagerLite(); + explicit ClientManagerLite(QQmlContext& main_context); virtual ~ClientManagerLite(); = - Q_INVOKABLE bool setHost(QString ip, unsigned int port); + Q_INVOKABLE bool setHost(const QString &ip, unsigned int port); Q_INVOKABLE void disconnectHost(); = + /** + * Get the profiles from Web Manager + * + * @param ip IP address + * @param port Port number + * + * The process is async and the results are stored in @a webMProfiles.= Once this + * request finishes, the server status is queried from the server. + */ + Q_INVOKABLE void getWebManagerProfiles(const QString &ip, unsigned int= port); + + /** + * Start an INDI server with a Web Manager profile + * + * @param profile Profile name + */ + Q_INVOKABLE void startWebManagerProfile(const QString &profile); + + /** Stop the INDI server with an active Web Manager profile */ + Q_INVOKABLE void stopWebManagerProfile(); + + /** Handle the errors of the async Web Manager requests */ + Q_INVOKABLE void webManagerReplyError(QNetworkReply::NetworkError code= ); + + /** Do actions when async Web Manager requests are finished */ + Q_INVOKABLE void webManagerReplyFinished(); + Q_INVOKABLE TelescopeLite *getTelescope(const QString &deviceName); = QString connectedHost() { return m_connectedHost; } - void setConnectedHost(QString connectedHost); + void setConnectedHost(const QString &connectedHost); void setConnected(bool connected); = + /** + * Set the INDI Control Page + * + * @param page Reference to the QML page + */ + void setIndiControlPage(QObject &page) { indiControlPage =3D &page; }; + /** * @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 =3D ""); + Q_INVOKABLE QString syncLED(const QString &device, const QString &prop= erty, const QString &name =3D ""); = void buildTextGUI(INDI::Property *property); void buildNumberGUI(INDI::Property *property); @@ -93,8 +137,8 @@ class ClientManagerLite : public INDI::BaseClientQt void buildLightGUI(INDI::Property *property); //void buildBLOBGUI(INDI::Property *property); = - Q_INVOKABLE void sendNewINDISwitch(QString deviceName, QString propNam= e, QString name); - Q_INVOKABLE void sendNewINDISwitch(QString deviceName, QString propNam= e, int index); + Q_INVOKABLE void sendNewINDISwitch(const QString &deviceName, const QS= tring &propName, const QString &name); + Q_INVOKABLE void sendNewINDISwitch(const QString &deviceName, const QS= tring &propName, int index); = Q_INVOKABLE void sendNewINDINumber(const QString &deviceName, const QS= tring &propName, const QString &numberName, double value); @@ -102,15 +146,19 @@ class ClientManagerLite : public INDI::BaseClientQt const QString &text); = bool isConnected() { return m_connected; } - Q_INVOKABLE bool isDeviceConnected(QString deviceName); + Q_INVOKABLE bool isDeviceConnected(const QString &deviceName); = QList getDevices() { return m_devices; } = Q_INVOKABLE QString getLastUsedServer(); - Q_INVOKABLE void setLastUsedServer(QString server); + Q_INVOKABLE void setLastUsedServer(const QString &server); = Q_INVOKABLE int getLastUsedPort(); Q_INVOKABLE void setLastUsedPort(int port); + + Q_INVOKABLE int getLastUsedWebManagerPort(); + Q_INVOKABLE void setLastUsedWebManagerPort(int port); + /** * @brief saveDisplayImage * @return true if image was saved false otherwise @@ -173,15 +221,32 @@ class ClientManagerLite : public INDI::BaseClientQt = void lastUsedServerChanged(); void lastUsedPortChanged(); + void lastUsedWebManagerPortChanged(); = private: bool processBLOBasCCD(IBLOB *bp); = + /// Qml context + QQmlContext& context; QList m_devices; QString m_connectedHost; bool m_connected { false }; char BLOBFilename[MAXINDIFILENAME]; QImage displayImage; + /// INDI Control Page + QObject* indiControlPage; + /// Manager for the JSON requests to the Web Manager + QNetworkAccessManager manager; + /// Network reply for querying profiles from the Web Manager + std::unique_ptr webMProfilesReply; + /// Network reply for Web Manager status + std::unique_ptr webMStatusReply; + /// Network reply to stop the active profile in the Web Manager + std::unique_ptr webMStopProfileReply; + /// Network reply to start a profile in the Web Manager + std::unique_ptr webMStartProfileReply; + /// Web Manager profiles + QStringList webMProfiles; #ifdef ANDROID QString defaultImageType; QString defaultImagesLocation; diff --git a/kstars/kstars.kcfg b/kstars/kstars.kcfg index 8692bc321..fc099b440 100644 --- a/kstars/kstars.kcfg +++ b/kstars/kstars.kcfg @@ -2055,6 +2055,10 @@ 7624 + + + 8624 + diff --git a/kstars/kstarslite.cpp b/kstars/kstarslite.cpp index 142ffe1be..7df48939b 100644 --- a/kstars/kstarslite.cpp +++ b/kstars/kstarslite.cpp @@ -61,7 +61,7 @@ KStarsLite::KStarsLite(bool doSplash, bool startClock, co= nst QString &startDateS Q_ASSERT(m_KStarsData); = //INDI Android Client - m_clientManager =3D new ClientManagerLite; + m_clientManager =3D new ClientManagerLite(*m_Engine.rootContext()); m_Engine.rootContext()->setContextProperty("ClientManagerLite", m_clie= ntManager); = //Make instance of KStarsLite and KStarsData available to QML @@ -104,6 +104,7 @@ KStarsLite::KStarsLite(bool doSplash, bool startClock, = const QString &startDateS "QML file was not loaded. Probably syntax error or failed m= odule import."); = m_RootObject =3D m_Engine.rootObjects()[0]; + m_clientManager->setIndiControlPage(*m_RootObject->findChild= ("indiControlPanel")); = QQuickItem *skyMapLiteWrapper =3D m_RootObject->findChild("skyMapLiteWrapper"); = diff --git a/kstars/kstarslite/qml/indi/INDIControlPanel.qml b/kstars/kstar= slite/qml/indi/INDIControlPanel.qml index db018a408..21746150a 100644 --- a/kstars/kstarslite/qml/indi/INDIControlPanel.qml +++ b/kstars/kstarslite/qml/indi/INDIControlPanel.qml @@ -21,15 +21,21 @@ KSPage { title: "INDI Control Panel" = property bool connected: ClientManagerLite.connected + property alias webMStatusText: webMStatusLabel.text + property alias webMStatusTextVisible: webMStatusLabel.visible + property alias webMActiveProfileText: webMActiveProfileLabel.text + property alias webMActiveProfileLayoutVisible: webMActiveProfileLayout= .visible + property alias webMBrowserButtonVisible: webMBrowserButton.visible + property alias webMProfileListVisible: webMProfileList.visible = Component.onCompleted: { - //Debug purposes + // Debug purposes ClientManagerLite.setHost("localhost", 7624) } = onConnectedChanged: { - if(!indiPage.connected) { - for(var i =3D 0; i < devicesModel.count; ++i) { + if (!indiPage.connected) { + for (var i =3D 0; i < devicesModel.count; ++i) { devicesModel.get(i).panel.destroy() stackView.pop(indiPage) } @@ -51,7 +57,7 @@ KSPage { } = KSLabel { - text: xi18n("INDI Host") + text: xi18n("IP Address") } = RowLayout { @@ -61,22 +67,145 @@ KSPage { } = KSTextField { - id:ipHost - placeholderText: xi18n("IP") + id: ipHost + placeholderText: xi18n("xxx.xxx.xxx.xxx") Layout.alignment: Qt.AlignHCenter Layout.maximumWidth: parent.width*0.8 Layout.fillWidth: true text: ClientManagerLite.lastUsedServer } + } + + KSLabel { + text: xi18n("Web Manager Port") + } + + RowLayout { + anchors { + left: parent.left + right: parent.right + } + + KSTextField { + id: portWebManager + placeholderText: xi18n("xxxx") + Layout.alignment: Qt.AlignHCenter + Layout.maximumWidth: parent.width*0.2 + Layout.fillWidth: true + text: ClientManagerLite.lastUsedWebManagerPort + } + + Button { + id: webMConnectButton + text: xi18n("Get Status") + + onClicked: { + ClientManagerLite.getWebManagerProfiles(ipHost.tex= t, parseInt(portWebManager.text)); + Qt.inputMethod.hide() + } + } + } + + KSLabel { + id: webMStatusLabel + text: xi18n("Web Manager Status:") + visible: false + } + + RowLayout { + id: webMActiveProfileLayout + visible: false + + KSLabel { + id: webMActiveProfileLabel + text: xi18n("Active Profile:") + } + + Button { + id: webMStopButton + text: xi18n("Stop") + + onClicked: { + ClientManagerLite.stopWebManagerProfile(); + } + } + } + + ListView { + id: webMProfileList + model: webMProfileModel + highlightFollowsCurrentItem: false + width: parent.width + height: childrenRect.height + visible: false + + delegate: RowLayout { + spacing: 60 + height: webMConnectButton.height + + KSLabel { + height: webMConnectButton.height + text: xi18n("Profile:")+" "+modelData + } + + Button { + height: webMConnectButton.height + text: xi18n("Start") + + onClicked: { + ClientManagerLite.startWebManagerProfile(model= Data); + } + } + } + } // ListView + + Button { + id: webMBrowserButton + text: xi18n("Manage Profiles") + visible: false + + onClicked: { + Qt.openUrlExternally("http://"+ipHost.text+":"+portWeb= Manager.text) + } + } + + KSLabel { + text: xi18n("Server Port") + } + + RowLayout { + anchors { + left: parent.left + right: parent.right + } = KSTextField { - id:portHost - placeholderText: xi18n("Port") + id: portHost + placeholderText: xi18n("INDI Server Port") Layout.alignment: Qt.AlignHCenter Layout.maximumWidth: parent.width*0.2 Layout.fillWidth: true text: ClientManagerLite.lastUsedPort } + + Button { + text: indiPage.connected ? xi18n("Disconnect") : xi18n= ("Connect") + + onClicked: { + if (!indiPage.connected) { + if(ClientManagerLite.setHost(ipHost.text, pars= eInt(portHost.text))) { + notification.showNotification(xi18n("Succe= ssfully connected to the server")) + } else { + notification.showNotification(xi18n("Could= n't connect to the server")) + } + } else { + + ClientManagerLite.disconnectHost() + } + Qt.inputMethod.hide() + } + } + } } = @@ -86,28 +215,11 @@ KSPage { text: xi18n("Connected to ") + ClientManagerLite.connectedHost } = - Button { - text: indiPage.connected ? xi18n("Disconnect") : xi18n("Connec= t ") - - onClicked: { - if(!indiPage.connected) { - if(ClientManagerLite.setHost(ipHost.text, parseInt(por= tHost.text))) { - notification.showNotification(xi18n("Successfully = connected to the server")) - } else { - notification.showNotification(xi18n("Couldn't conn= ect to the server")) - } - } else { - - ClientManagerLite.disconnectHost() - } - Qt.inputMethod.hide() - } - } = ColumnLayout { Layout.fillHeight: true Layout.fillWidth: true - visible : indiPage.connected + visible: indiPage.connected = Rectangle { Layout.fillWidth: true @@ -133,7 +245,7 @@ KSPage { devicesModel.append({ name: deviceName, panel: deviceP= anel }) } onRemoveINDIDevice: { - for(i =3D 0; i < devicesModel.count; ++i) { + for (i =3D 0; i < devicesModel.count; ++i) { if(devicesModel.get(i).name =3D=3D deviceName) { devicesModel.panel.destroy() devicesModel.remove(i)