I have made the following changes intended for : CE:UX:MTF / meegotouchcp-connman
Please review and accept or decline. BOSS has already run some checks on this request. See the "Messages from BOSS" section below. https://build.pub.meego.com//request/show/5174 Thank You, Marko Saukko [This message was auto-generated] --- Request # 5174: Messages from BOSS: State: review at 2012-07-06T13:03:01 by bossbot Reviews: accepted by bossbot : Prechecks succeeded. new for CE-maintainers : Please replace this text with a review and approve/reject the review (not the SR). BOSS will take care of the rest Changes: submit: Project:MTF:UX / meegotouchcp-connman -> CE:UX:MTF / meegotouchcp-connman changes files: -------------- --- meegotouchcp-connman.changes +++ meegotouchcp-connman.changes @@ -0,0 +1,7 @@ +* Thu Jul 05 2012 Dmitry Rozhkov <[email protected]> - 0.2.2 +- Handle nicely user's wrong input. + +* Mon Jul 02 2012 Dmitry Rozhkov <[email protected]> - 0.2.1 +- Rewritten to use PageStackWindow and standard toolbar + components. + old: ---- 0001-Fix-connman-qt-import.patch meegotouchcp-connman-0.2.0.tar.bz2 new: ---- meegotouchcp-connman-0.2.2.tar.bz2 spec files: ----------- --- meegotouchcp-connman.spec +++ meegotouchcp-connman.spec @@ -9,15 +9,14 @@ # << macros Summary: MeegoTouchControlPanel wifi Plugin -Version: 0.2.0 +Version: 0.2.2 Release: 1 Group: System/GUI/Other License: Apache License URL: http://www.meego.com Source0: %{name}-%{version}.tar.bz2 Source100: meegotouchcp-connman.yaml -Patch0: 0001-Fix-connman-qt-import.patch -Requires: connman-qt-declarative +Requires: connman-qt-declarative >= 0.2.0 BuildRequires: qt-qmake %description @@ -28,8 +27,6 @@ %prep %setup -q -n %{name}-%{version} -# 0001-Fix-connman-qt-import.patch -%patch0 -p1 # >> setup # << setup @@ -61,6 +58,8 @@ %defattr(-,root,root,-) %{_libdir}/duicontrolpanel/meegotouchcp-wifi.desktop %{_datadir}/duicontrolpanel/wifi/mainpage.qml +%{_datadir}/duicontrolpanel/wifi/NotificationBanner.qml +%{_datadir}/duicontrolpanel/wifi/StatusPage.qml %{_libdir}/qt4/imports/Connman/js/mustache.js # >> files # << files other changes: -------------- ++++++ meegotouchcp-connman-0.2.0.tar.bz2 -> meegotouchcp-connman-0.2.2.tar.bz2 --- ChangeLog +++ ChangeLog @@ -1,3 +1,6 @@ +meegotouchcp-connman 0.2.2 + handle wrong user's input + meegotouchcp-connman 0.2.0 Rewritten to use QML --- meegotouchcp-connman.spec +++ meegotouchcp-connman.spec @@ -15,6 +15,7 @@ Source0: %{name}-%{version}.tar.bz2 Source100: meegotouchcp-connman.yaml Requires: connman-qt-declarative +BuildRequires: qt-qmake %description @@ -35,6 +36,7 @@ qmake install_prefix=/usr # << build pre +%qmake make %{?jobs:-j%jobs} @@ -45,7 +47,7 @@ # >> install pre export INSTALL_ROOT=%{buildroot} # << install pre -%make_install +%qmake_install # >> install post # << install post @@ -57,7 +59,7 @@ %files %defattr(-,root,root,-) -%{_libdir}/duicontrolpanel/meegotouchcp-connman.desktop +%{_libdir}/duicontrolpanel/meegotouchcp-wifi.desktop %{_datadir}/duicontrolpanel/wifi/mainpage.qml %{_libdir}/qt4/imports/Connman/js/mustache.js # >> files --- meegotouchcp-connman.yaml +++ meegotouchcp-connman.yaml @@ -10,11 +10,13 @@ Description: | This is a plugin for meegotouch-controlpanel that does wifi +PkgBR: + - qt-qmake Requires: - connman-qt-declarative Configure: none -Builder: make +Builder: qmake Files: -- "%{_libdir}/duicontrolpanel/meegotouchcp-connman.desktop" +- "%{_libdir}/duicontrolpanel/meegotouchcp-wifi.desktop" - "%{_datadir}/duicontrolpanel/wifi/mainpage.qml" - "%{_libdir}/qt4/imports/Connman/js/mustache.js" --- qml/NotificationBanner.qml +++ qml/NotificationBanner.qml @@ -0,0 +1,276 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation ([email protected]) +** +** This file is part of the Qt Components project. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 1.1 +import com.nokia.meego 1.0 + +/* + Class: InfoBanner + The InfoBanner component is used to display information to the user. The number of lines of text + shouldn't exceed 3. +*/ + +Item { + id: root + + /* + * Property: iconSource + * [url] The path to the icon image + */ + property url iconSource: "" + + /* + * Property: text + * [string] Text to be displayed in InfoBanner + */ + property alias text: text.text + + /* + * Property: timerEnabled + * [bool=true] Enable/disable timer that dismisses InfoBanner + */ + property bool timerEnabled: true + + /* + * Property: timerShowTime + * [int=3000ms] For setting how long InfoBanner stays visible to user before being dismissed + */ + property alias timerShowTime: sysBannerTimer.interval + + /* + * Property: topMargin + * [int=8 pix] Allows user to customize top margin if needed + */ + property alias topMargin: root.y + + /* + * Property: leftMargin + * [int=8 pix] Allows user to customize left margin if needed + */ + property alias leftMargin: root.x + + /* + * Function: show + * Show InfoBanner + */ + function show() { + parent = __findParent(); + + var window = __findWindow(); + if(window != null) root.pos.y = 8 + window.__statusBarHeight; + + animationShow.running = true; + if (root.timerEnabled) + sysBannerTimer.restart(); + } + + function __findParent() { + var next = parent; + while (next && next.parent && next.objectName != "windowContent") { + next = next.parent; + } + return next; + } + + function __findWindow() { + var result = null; + for(var item = parent; item != null; item = item.parent) { + if(item.objectName == 'pageStackWindow') { + result = item; + break; + } + } + return result; + } + + /* + * Function: hide + * Hide InfoBanner + */ + function hide() { + animationHide.running = true; + } + + implicitHeight: internal.getBannerHeight() + implicitWidth: internal.getBannerWidth() + x:8; y:8 + scale: 0 + + Behavior on y {NumberAnimation {easing.type:Easing.InOutExpo;duration:500}} + + BorderImage { + source: "image://theme/meegotouch-notification-system-background" + anchors.fill: root + horizontalTileMode: BorderImage.Stretch + verticalTileMode: BorderImage.Stretch + border { left: 10; top: 10; right: 10; bottom: 10 } + opacity: 1 + } + + Image { + id: image + anchors { left: parent.left; leftMargin: 16; top: parent.top; topMargin: 16 } + source: root.iconSource + visible: root.iconSource != "" + } + + Text { + id: text + width: internal.getTextWidth() + anchors { left: (image.visible ? image.right : parent.left); leftMargin: (image.visible ? 14:16); + top: parent.top; topMargin: internal.getTopMargin(); bottom: parent.bottom } + color: "white" + wrapMode: Text.Wrap + verticalAlignment: Text.AlignHCenter + font.pixelSize: 24 + font.family: "Nokia Pure" + font.letterSpacing: -1.2 + maximumLineCount: 3 + elide: Text.ElideRight + } + + QtObject { + id: internal + + function getBannerHeight() { + if (image.visible) { + if (text.lineCount <= 2) + return 80; + else + return 80; //106 + } else { + if (text.lineCount <= 1) + return 80; //64 + else if (text.lineCount <= 2) + return 80; + else + return 80; //106 + } + } + + function getBannerWidth() { + if ( screen.currentOrientation==Screen.Portrait || screen.currentOrientation==Screen.PortraitInverted ) { + // In portrait mode, the width of the banner is equal to the width of parent minus left + // and right margins in-between banner and parent. + return parent.width-root.x*2; + } else { + if (image.visible) { + // If an icon image is specified... + if ((image.width+text.paintedWidth+46) <= parent.width*0.54 && text.lineCount <= 1) { + // 46 is the sum of all horizontal margins within the banner. The above condition basically + // says that if there's only one line of text, and the sum of width of icon, text, and required + // margins is less then 54% of the screen width, banner width should be 54% of the screen. + return parent.width*0.54; + } else { + return parent.width-root.x*2; + } + } else { + // If no icon image specified... + if ((text.paintedWidth+32) <= parent.width*0.54 && text.lineCount <= 1) { + // 32 is the sum of all horizontal margins within the banner. The above condition basically + // says that if there's only one line of text, and the sum of width of text and required + // margins is less then 54% of the screen width, banner width should be 54% of the screen. + return parent.width-root.x*2; + } else { + return parent.width-root.x*2; + } + } + } + } + + function getTopMargin() { + if (text.lineCount <= 1 && !image.visible) { + // If there's only one line of text and no icon image, top and bottom margins are equal. + return (root.height-text.paintedHeight)/2; + } else { + // In all other cases, top margin is 4 px more than bottom margin. + return (root.height-text.paintedHeight)/2 + 2; + } + } + + function getTextWidth() { + // 46(32 when there's no icon) is sum of all margins within banner. root.x*2 is sum of margins outside banner. + // Text element width is dertermined by substracting parent width(screen width) by all the margins and + // icon width(if applicable). + return image.visible ? (parent.width-root.x*2-46-image.width) : (parent.width-root.x*2-32); + } + + function getScaleValue() { + // When banner is displayed, as part of transition effect, it'll first be enlarged to the point where its width + // is equal to screen width. root.x*2/root.width calculates the amount of expanding required, where root.x*2 is + // equal to screen.displayWidth minus banner.width + return root.x*2/root.width + 1; + } + } + + Timer { + id: sysBannerTimer + repeat: false + running: false + interval: 3000 + onTriggered: hide() + } + + MouseArea { + anchors.fill: parent + onClicked: hide() + } + + SequentialAnimation { + id: animationShow + NumberAnimation { target: root; property: "scale"; from: 0; to: internal.getScaleValue(); duration: 200; easing.type: Easing.OutQuad} + NumberAnimation { target: root; property: "scale"; from: internal.getScaleValue(); to: 1; duration: 200 } + } + + NumberAnimation { + id: animationHide + target: root; property: "scale"; to: 0; duration: 200; easing.type: Easing.InExpo + } + + Component.onCompleted: { + //__owner = parent; + var window = __findWindow(); + if(window != null) { + window.showStatusBarChanged.connect(function() { + root.topMargin = 8 + window.__statusBarHeight; + }); + } + } +} --- qml/StatusPage.qml +++ qml/StatusPage.qml @@ -0,0 +1,429 @@ +import QtQuick 1.1 +import com.nokia.meego 1.0 +import com.nokia.controlpanel 0.1 +import MeeGo.Connman 0.2 + +Page { + id: statusPage + tools: DcpToolBar {} + + property NetworkService network + property alias networkLabel: networkNameLabel.text + + Flickable { + anchors { fill: parent } + contentHeight: 1100 + + Column { + spacing: 10 + anchors { fill: parent } + Item { + anchors { left: parent.left; right: parent.right } + height: 80 + + Image { + anchors { left: parent.left; verticalCenter: parent.verticalCenter } + source: "image://theme/icon-m-common-wlan-strength5" + width: 60 + height: 60 + } + + Text { + id: networkNameLabel + anchors { left: parent.left; verticalCenter: parent.verticalCenter; leftMargin: 80 } + text: "Network name" + color: "white" + font.pointSize: 18 + } + } + + Item { + anchors { left: parent.left; right: parent.right } + height: 100 + Button { + id: disconnectButton + anchors { + horizontalCenter: parent.horizontalCenter + verticalCenter: parent.verticalCenter + } + text: "Disconnect" + onClicked: { + console.log("Disconnect clicked"); + network.requestDisconnect(); + pageStack.pop(); + } + } + } + + Item { + anchors { left: parent.left; right: parent.right } + height: 100 + Text { + anchors { left: parent.left; leftMargin: 20 } + text: "Method" + color: "grey" + font.pointSize: 14 + } + ButtonRow { + id: method + anchors { left: parent.left; right: parent.right; top: parent.top; topMargin: 30; leftMargin: 10; rightMargin: 10 } + state: statusPage.network.ipv4["Method"] + + states: [ + State { + name: "dhcp" + PropertyChanges {target: networkInfo; visible: true} + PropertyChanges {target: networkFields; visible: false} + }, + State { + name: "manual" + PropertyChanges {target: networkInfo; visible: false} + PropertyChanges {target: networkFields; visible: true} + } + ] + + Button { + text: "DHCP" + checked: statusPage.network.ipv4["Method"] == "dhcp" + onClicked: { + method.state = "dhcp" + } + } + Button { + text: "Static" + checked: statusPage.network.ipv4["Method"] == "manual" + onClicked: { + method.state = "manual" + } + } + } + } + + Item { + id: networkInfo + anchors { left: parent.left; right: parent.right } + height: 440 + + Column { + spacing: 50 + Item { + height: 40 + anchors { left: parent.left; right: parent.right } + + Text { + anchors { left: parent.left; leftMargin: 20; top: parent.top } + text: "IP address" + color: "grey" + font.pointSize: 14 + } + Text { + anchors { left: parent.left; leftMargin: 20; top:parent.top; topMargin: 30 } + text: statusPage.network.ipv4["Address"] + color: "white" + font.pointSize: 20 + } + } + Item { + height: 40 + anchors { left: parent.left; right: parent.right } + + Text { + anchors { left: parent.left; leftMargin: 20; top: parent.top } + text: "Subnet mask" + color: "grey" + font.pointSize: 14 + } + Text { + anchors { left: parent.left; leftMargin: 20; top: parent.top; topMargin: 30 } + text: statusPage.network.ipv4["Netmask"] + color: "white" + font.pointSize: 20 + } + } + Item { + height: 40 + anchors { left: parent.left; right: parent.right } + + Text { + anchors { left: parent.left; leftMargin: 20; top: parent.top } + text: "Router" + color: "grey" + font.pointSize: 14 + } + Text { + anchors { left: parent.left; leftMargin: 20; top: parent.top; topMargin: 30 } + text: statusPage.network.ipv4["Gateway"] + color: "white" + font.pointSize: 20 + } + } + Item { + height: 40 + anchors { left: parent.left; right: parent.right } + + Text { + anchors { left: parent.left; leftMargin: 20; top: parent.top } + text: "DNS" + color: "grey" + font.pointSize: 14 + } + Text { + anchors { left: parent.left; leftMargin: 20; top: parent.top; topMargin: 30 } + text: statusPage.network.nameservers.join() + color: "white" + font.pointSize: 20 + } + } + Item { + height: 60 + anchors { left: parent.left; right: parent.right } + + Text { + anchors { left: parent.left; leftMargin: 20; top: parent.top } + text: "Search domains" + color: "grey" + font.pointSize: 14 + } + Text { + anchors { left: parent.left; leftMargin: 20; top: parent.top; topMargin: 30 } + text: statusPage.network.domains.join() + color: "white" + font.pointSize: 20 + } + } + } + } + + Item { + id: networkFields + anchors { left: parent.left; right: parent.right } + height: 440 + + Column { + spacing: 50 + Item { + height: 40 + anchors { left: parent.left; right: parent.right } + + Text { + anchors { left: parent.left; leftMargin: 20; top: parent.top } + text: "IP address" + color: "grey" + font.pointSize: 14 + } + TextField { + anchors { left: parent.left; leftMargin: 20; top:parent.top; topMargin: 30 } + width: 440 + text: statusPage.network.ipv4["Address"] + font.pointSize: 20 + } + } + Item { + height: 40 + anchors { left: parent.left; right: parent.right } + + Text { + anchors { left: parent.left; leftMargin: 20; top: parent.top } + text: "Subnet mask" + color: "grey" + font.pointSize: 14 + } + TextField { + anchors { left: parent.left; leftMargin: 20; top: parent.top; topMargin: 30 } + width: 440 + text: statusPage.network.ipv4["Netmask"] + font.pointSize: 20 + } + } + Item { + height: 40 + anchors { left: parent.left; right: parent.right } + + Text { + anchors { left: parent.left; leftMargin: 20; top: parent.top } + text: "Router" + color: "grey" + font.pointSize: 14 + } + TextField { + anchors { left: parent.left; leftMargin: 20; top: parent.top; topMargin: 30 } + width: 440 + text: statusPage.network.ipv4["Gateway"] + font.pointSize: 20 + } + } + Item { + height: 40 + anchors { left: parent.left; right: parent.right } + + Text { + anchors { left: parent.left; leftMargin: 20; top: parent.top } + text: "DNS" + color: "grey" + font.pointSize: 14 + } + TextField { + anchors { left: parent.left; leftMargin: 20; top: parent.top; topMargin: 30 } + width: 440 + text: statusPage.network.nameservers.join() + font.pointSize: 20 + } + } + Item { + height: 60 + anchors { left: parent.left; right: parent.right } + + Text { + anchors { left: parent.left; leftMargin: 20; top: parent.top } + text: "Search domains" + color: "grey" + font.pointSize: 14 + } + TextField { + anchors { left: parent.left; leftMargin: 20; top: parent.top; topMargin: 30 } + width: 440 + text: statusPage.network.domains.join() + font.pointSize: 20 + } + } + } + } + + Item { + anchors { left: parent.left; right: parent.right } + height: 100 + Text { + anchors { left: parent.left; leftMargin: 20 } + text: "HTTP Proxy" + color: "grey" + font.pointSize: 14 + } + ButtonRow { + id: proxy + anchors { left: parent.left; right: parent.right; top: parent.top; topMargin: 30; leftMargin: 10; rightMargin: 10 } + state: statusPage.network ? statusPage.network.proxy["Method"] : "auto" + + states: [ + State { + name: "direct" + PropertyChanges {target: proxyManualFields; visible: false} + PropertyChanges {target: proxyAutoFields; visible: false} + PropertyChanges {target: directProxyButton; checked: true} + PropertyChanges {target: manualProxyButton; checked: false} + PropertyChanges {target: autoProxyButton; checked: false} + }, + State { + name: "auto" + PropertyChanges {target: proxyManualFields; visible: false} + PropertyChanges {target: proxyAutoFields; visible: true} + PropertyChanges {target: directProxyButton; checked: false} + PropertyChanges {target: manualProxyButton; checked: false} + PropertyChanges {target: autoProxyButton; checked: true} + }, + State { + name: "manual" + PropertyChanges {target: proxyManualFields; visible: true} + PropertyChanges {target: proxyAutoFields; visible: false} + PropertyChanges {target: directProxyButton; checked: false} + PropertyChanges {target: manualProxyButton; checked: true} + PropertyChanges {target: autoProxyButton; checked: false} + } + ] + + Button { + id: directProxyButton + text: "Off" + onClicked: { + proxy.state = "direct" + } + } + Button { + id: manualProxyButton + text: "Manual" + onClicked: { + proxy.state = "manual" + } + } + Button { + id: autoProxyButton + text: "Auto" + onClicked: { + proxy.state = "auto" + } + } + } + } + + Item { + id: proxyManualFields + anchors { left: parent.left; right: parent.right } + height: 440 + + Column { + spacing: 50 + Item { + height: 40 + anchors { left: parent.left; right: parent.right } + + Text { + anchors { left: parent.left; leftMargin: 20; top: parent.top } + text: "Server" + color: "grey" + font.pointSize: 14 + } + TextField { + anchors { left: parent.left; leftMargin: 20; top:parent.top; topMargin: 30 } + width: 440 + text: "this is Server" + font.pointSize: 20 + } + } + Item { + height: 40 + anchors { left: parent.left; right: parent.right } + + Text { + anchors { left: parent.left; leftMargin: 20; top: parent.top } + text: "Port" + color: "grey" + font.pointSize: 14 + } + TextField { + anchors { left: parent.left; leftMargin: 20; top: parent.top; topMargin: 30 } + width: 440 + text: "this is Port" + font.pointSize: 20 + } + } + } + } + + Item { + id: proxyAutoFields + anchors { left: parent.left; right: parent.right } + height: 440 + + Column { + spacing: 50 + Item { + height: 40 + anchors { left: parent.left; right: parent.right } + + Text { + anchors { left: parent.left; leftMargin: 20; top: parent.top } + text: "URL" + color: "grey" + font.pointSize: 14 + } + TextField { + anchors { left: parent.left; leftMargin: 20; top:parent.top; topMargin: 30 } + width: 440 + text: statusPage.network ? statusPage.network.proxy["URL"] : "Error!" + font.pointSize: 20 + } + } + } + } + } + } +} --- qml/mainpage.qml +++ qml/mainpage.qml @@ -1,29 +1,31 @@ import QtQuick 1.1 import com.nokia.meego 1.0 -import Connman.Qt 0.2 +import MeeGo.Connman 0.2 +import com.nokia.controlpanel 0.1 import "/usr/lib/qt4/imports/Connman/js/mustache.js" as M -PageStack { - id: wifiPageStack - anchors { fill: parent } - Component.onCompleted: { - wifiPageStack.push(initialPage) - } - - function handleInput(input) { - console.log("About to handle input "+ input); - for (var key in input) { - console.log(key + "-> " + input[key]); - } - networkingModel.sendUserReply(input); - wifiPageStack.pop() - scanTimer.running = true; +PageStackWindow { + id: mainWindow + initialPage: mainPage + property variant netfields: {} + + function handleInput(key, value) { + var dict = mainWindow.netfields; + var isDoneEnabled = false; + console.log("Received from TextField " + key + " " + value); + dict[key] = value; + mainWindow.netfields = dict; + for (var id in mainWindow.netfields) { + console.log(id + "-> " + mainWindow.netfields[id]); + isDoneEnabled = isDoneEnabled || mainWindow.netfields[id].length; + } + doneButton.enabled = isDoneEnabled; } Timer { id: scanTimer interval: 25000 - running: false + running: networkingModel.wifiPowered repeat: true triggeredOnStart: true onTriggered: networkingModel.requestScan(); @@ -36,40 +38,39 @@ import com.nokia.meego 1.0 Item { id: form - signal send (variant input) - anchors { fill: parent } + anchors { fill: parent; margins: 10 } Column { + spacing: 5 anchors { fill: parent } {{#fields}} Text { - text: '{{name}} ({{type}} {{requirement}})' + text: '{{name}}' + color: 'white' + font.pointSize: 14 } TextField { id: {{id}} + signal send (string key, string value) + anchors { left: parent.left; right: parent.right } placeholderText: 'enter {{name}}' - } - {{/fields}} - Button { - text: 'Connect' - onClicked: { - console.log('clicked Connect'); - var inputs = {}; - {{#fields}} - if ({{id}}.text) { - inputs['{{name}}'] = {{id}}.text; - } - {{/fields}} - form.send.connect(handleInput); form.send(inputs); + Component.onCompleted: { + {{id}}.send.connect(handleInput); + } + onTextChanged: { + console.log('Sending from TextField {{id}}' + {{id}}.text); + {{id}}.send('{{name}}', {{id}}.text); } } + {{/fields}} } } " + onTechnologiesChanged: { wifiSwitch.checked = networkingModel.wifiPowered; - wifiPageStack.replace(mainPage); scanTimer.running = networkingModel.wifiPowered; } + onWifiPoweredChanged: { wifiSwitch.checked = networkingModel.wifiPowered; scanTimer.running = networkingModel.wifiPowered; @@ -97,17 +98,20 @@ var output = M.Mustache.render(form_tpl, view); console.log("output:" + output); var form = Qt.createQmlObject(output, dynFields, "dynamicForm1"); - wifiPageStack.push(networkPage); + if (pageStack.currentPage == networkPage) { + console.log("Warning: already on networkPage"); + } + if (pageStack.busy) { + console.log("TODO: handle wrong input!!!"); + } else { + pageStack.push(networkPage); + } } - } - Page { - id: initialPage - - Text { - text: "Hello world" - color: "red" - font.pointSize: 24 + onErrorReported: { + console.log("Got error from model: " + error); + mainpageNotificationBanner.text = "Incorrect value entered. Try again." + mainpageNotificationBanner.show() } } @@ -115,28 +119,88 @@ id: networkRow Rectangle { - height: 40 - color: "yellow" + height: 80 + color: "black" anchors { left: parent.left; right: parent.right } - Text { - anchors { left: parent.left; verticalCenter: parent.verticalCenter; leftMargin: 20 } - text: modelData.name - } - Text { - anchors { horizontalCenter: parent.horizontalCenter; verticalCenter: parent.verticalCenter } - text: modelData.favorite ? modelData.state + " (favorite)" : modelData.state - } - Text { - anchors { right: parent.right; verticalCenter: parent.verticalCenter; rightMargin: 40 } - text: modelData.security.join() + " " + modelData.strength + Row { + + Image { + source: { + var strength = modelData.strength; + var str_id = 0; + + if (strength >= 59) { + str_id = 5; + } else if (strength >= 55) { + str_id = 4; + } else if (strength >= 50) { + str_id = 3; + } else if (strength >= 45) { + str_id = 2; + } else if (strength >= 30) { + str_id = 1; + } + return "image://theme/icon-m-common-wlan-strength" + str_id; + } + width: 60 + height: 60 + } + + Column { + Text { + anchors { left: parent.left; leftMargin: 20 } + text: modelData.name ? modelData.name : "hidden network" + color: "white" + font.pointSize: 18 + } + Text { + anchors { left: parent.left; leftMargin: 20 } + text: { + var state = modelData.state; + var security = modelData.security[0]; + + if ((state == "online") || (state == "ready")) { + return "connected"; + } else if (state == "association" || state == "configuration") { + return "connecting..."; + } else { + if (security == "none") { + return "open"; + } else { + return "secure"; + } + } + } + color: { + var state = modelData.state; + if (state == "online" || state == "ready") { + return "gold"; + } else { + return "white"; + } + } + font.pointSize: 14 + } + } } + MouseArea { anchors.fill: parent onClicked: { console.log("clicked " + modelData.name); - modelData.requestConnect(); - networkName.text = modelData.name; + if (modelData.state == "idle" || modelData.state == "failure") { + modelData.requestConnect(); + networkName.text = modelData.name; + } else { + console.log("Show network status page"); + for (var key in modelData.ipv4) { + console.log(key + " -> " + modelData.ipv4[key]); + } + networkStatusPage.networkLabel = modelData.name; + networkStatusPage.network = modelData; + pageStack.push(networkStatusPage); + } } } } @@ -144,19 +208,20 @@ Page { id: mainPage + tools: DcpToolBar {} Column { spacing: 10 anchors { fill: parent } Rectangle { - color: "green" anchors { left: parent.left; right: parent.right } - height: 60 + height: 80 + color: "black" Text { anchors { left: parent.left; verticalCenter: parent.verticalCenter; leftMargin: 20 } - text: "WiFi status" + text: "Wi-Fi networks" color: "white" - font.pointSize: 16 + font.pointSize: 18 } Switch { id: wifiSwitch @@ -167,6 +232,7 @@ } } } + ListView { anchors { left: parent.left; right: parent.right } clip: true @@ -185,30 +251,95 @@ spacing: 10 anchors { fill: parent } Rectangle { - color: "green" + color: "black" + anchors { left: parent.left; right: parent.right } + height: 5 + } + Rectangle { + color: "#222222" + anchors { left: parent.left; right: parent.right } + height: 1 + } + Rectangle { + color: "black" anchors { left: parent.left; right: parent.right } height: 60 - - Text { - anchors { left: parent.left; verticalCenter: parent.verticalCenter; leftMargin: 20 } - text: "Wireless Network Details" - color: "white" - font.pointSize: 16 + Button { + anchors { + left: parent.left; + leftMargin: 20 + verticalCenter: parent.verticalCenter + } + text: "Cancel" + width: 150 + onClicked: { + networkingModel.sendUserReply({}); + pageStack.pop() + scanTimer.running = true; + } } + Button { + id: doneButton + anchors { + right: parent.right; + rightMargin: 20 + verticalCenter: parent.verticalCenter + } + text: 'Done' + width: 150 + enabled: false + platformStyle: ButtonStyle { + background: 'image://theme/meegotouch-button'+__invertedString+'-background-selected'+(position?'-'+position:'') + } + onClicked: { + console.log('clicked Done ' + 'x:' + x + ' y:' + y); + var fields = mainWindow.netfields; + for (var key in fields) { + console.log(key + " --> " + fields[key]); + } + pageStack.pop() + scanTimer.running = true; + networkingModel.sendUserReply(fields); + } + } + } + Rectangle { + color: "#333333" + anchors { left: parent.left; right: parent.right } + height: 1 } Text { - text: "Network:" - color: "green" + anchors { left: parent.left; leftMargin: 10 } + text: "Sign in to secure Wi-Fi network" + color: "white" + font.pointSize: 18 } Text { id: networkName - color: "green" + anchors { left: parent.left; leftMargin: 10 } + color: "white" + font.pointSize: 18 + } + Rectangle { + color: "black" + anchors { left: parent.left; right: parent.right } + height: 30 } Rectangle { anchors { left: parent.left; right: parent.right } height: 200 + color: "black" id: dynFields } } } + + StatusPage { + id: networkStatusPage + } + + NotificationBanner { + id: mainpageNotificationBanner + } + } --- qml/qml.pro +++ qml/qml.pro @@ -5,7 +5,7 @@ desktop_entry.files = meegotouchcp-wifi.desktop qmlpages.path = /usr/share/duicontrolpanel/wifi -qmlpages.files = mainpage.qml +qmlpages.files = mainpage.qml StatusPage.qml NotificationBanner.qml mustache.path = /usr/lib/qt4/imports/Connman/js/ mustache.files = mustache.js ++++++ meegotouchcp-connman.yaml --- meegotouchcp-connman.yaml +++ meegotouchcp-connman.yaml @@ -1,24 +1,24 @@ Name: meegotouchcp-connman Summary: MeegoTouchControlPanel wifi Plugin -Version: 0.2.0 +Version: 0.2.2 Release: 1 Group: System/GUI/Other License: Apache License URL: http://www.meego.com Sources: - "%{name}-%{version}.tar.bz2" -Patches: - - 0001-Fix-connman-qt-import.patch Description: | This is a plugin for meegotouch-controlpanel that does wifi PkgBR: - qt-qmake Requires: - - connman-qt-declarative + - connman-qt-declarative >= 0.2.0 Configure: none Builder: qmake Files: - "%{_libdir}/duicontrolpanel/meegotouchcp-wifi.desktop" - "%{_datadir}/duicontrolpanel/wifi/mainpage.qml" +- "%{_datadir}/duicontrolpanel/wifi/NotificationBanner.qml" +- "%{_datadir}/duicontrolpanel/wifi/StatusPage.qml" - "%{_libdir}/qt4/imports/Connman/js/mustache.js" ++++++ deleted files: --- 0001-Fix-connman-qt-import.patch
