diff --git a/settingsmodules/NetworkSettingsSheet.qml b/settingsmodules/NetworkSettingsSheet.qml new file mode 100644 index 00000000..231faec6 --- /dev/null +++ b/settingsmodules/NetworkSettingsSheet.qml @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2013 Robin Burchell + * Copyright (C) 2012 Jolla Ltd. + * + * 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 Nemo Mobile 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." + */ + +import QtQuick 2.0 +import QtQuick.Controls 1.2 +import MeeGo.Connman 0.2 +import "mustache.js" as M + +Item { + id: networkPage + property variant mustacheView + property UserAgent userAgent + property Timer scanTimer + + + property var netfields: {} + + function handleInput(key, value) { + var dict = {}; + var isDoneEnabled = false; + console.log("Received from TextField " + key + " " + value); + dict[key] = value; + networkPage.netfields = dict; + for (var id in networkPage.netfields) { + console.log(id + "-> " + networkPage.netfields[id]); + isDoneEnabled = isDoneEnabled || networkPage.netfields[id].length; + } + networkPage.acceptButtonEnabled = isDoneEnabled; + } + + Connections { + target: userAgent + onUserInputCanceled: { + console.log("qmlsettings: UserAgent cancelled user input request"); + networkPage.reject() + } + } + + Button { + text: "Reject" + onClicked: { + userAgent.sendUserReply({}); + scanTimer.running = true; + } + } + + Button { + text: "Accept" + onClicked: { + console.log('clicked Done ' + 'x:' + x + ' y:' + y); + var fields = networkPage.netfields; + for (var key in fields) { + console.log(key + " --> " + fields[key]); + } + scanTimer.running = true; + userAgent.sendUserReply(fields); + } + } + + Column { + spacing: 10 + anchors.fill: parent + Label { + anchors { left: parent.left; leftMargin: 10 } + text: "Sign in to secure Wi-Fi network" + } + Label { + id: networkName + anchors { left: parent.left; leftMargin: 10 } + } + Item { + height: 30 + } + Item { + id: dynFields + width: parent.width + height: 200 + property string form_tpl: " + import QtQuick 2.0 + import com.nokia.meego 2.0 + Item { + id: form + anchors { fill: parent; margins: 10 } + Column { + spacing: 5 + anchors { fill: parent } + {{#fields}} + Text { + 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}}' + Component.onCompleted: { + {{id}}.send.connect(handleInput); + } + onTextChanged: { + console.log('Sending from TextField {{id}}' + {{id}}.text); + {{id}}.send('{{name}}', {{id}}.text); + } + } + {{/fields}} + } + } + " + Component.onCompleted: { + console.log(mustacheView) + console.log(form_tpl) + // TODO: can we replace mustache with just regular old bindings? + var output = M.Mustache.render(form_tpl, mustacheView); + console.log("Creating " + output) + var form = Qt.createQmlObject(output, dynFields, "dynamicForm1"); + console.log("Created " + form) + } + } + } +} + + diff --git a/settingsmodules/SettingsSheet.qml b/settingsmodules/SettingsSheet.qml index decc470a..d96abe8e 100644 --- a/settingsmodules/SettingsSheet.qml +++ b/settingsmodules/SettingsSheet.qml @@ -33,6 +33,7 @@ import QtQuick 2.0 import QtQuick.Layouts 1.1 import org.kde.plasma.components 2.0 +import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.extras 2.0 as PlasmaExtras import MeeGo.Connman 0.2 @@ -135,7 +136,7 @@ Item { } } - + stackView.pop(); } } Button { @@ -171,28 +172,40 @@ Item { anchors.right: parent.right spacing: 10 - Rectangle { + Row { anchors { left: parent.left; right: parent.right } - height: 80 - color: "transparent" - Image { - anchors { left: parent.left; verticalCenter: parent.verticalCenter } - source: "image://theme/icon-m-common-wlan-strength5" - width: 60 - height: 60 + PlasmaCore.IconItem { + height: units.iconSizes.large + width: height + source: { + var strength = form.strength; + var str_id = 0; + + if (strength >= 100) { + str_id = 100; + } else if (strength >= 80) { + str_id = 80; + } else if (strength >= 60) { + str_id = 60; + } else if (strength >= 40) { + str_id = 40; + } else if (strength >= 20) { + str_id = 20; + } + return "network-wireless-" + str_id; + } } - Text { - anchors { left: parent.left; verticalCenter: parent.verticalCenter; leftMargin: 80 } + PlasmaExtras.Heading { text: form.networkName } } - Rectangle { + Item { anchors { left: parent.left; right: parent.right } height: 100 - color: "transparent" + Button { id: disconnectButton anchors { @@ -203,21 +216,20 @@ Item { onClicked: { console.log("Disconnect clicked"); network.requestDisconnect(); - sheet.close(); + stackView.pop(); } } } - Item { + Column { anchors { left: parent.left; right: parent.right } - height: 100 Text { anchors { left: parent.left; leftMargin: 20 } text: "Method" } ButtonRow { id: method - anchors { left: parent.left; right: parent.right; top: parent.top; topMargin: 30; leftMargin: 10; rightMargin: 10 } + anchors { left: parent.left; right: parent.right; leftMargin: 10; rightMargin: 10 } state: form.ipv4.Method states: [ @@ -250,81 +262,72 @@ Item { } } - Item { + Column { id: networkInfo anchors { left: parent.left; right: parent.right } - height: 340 - + spacing: 50 Column { - spacing: 50 - Item { - height: 40 - anchors { left: parent.left; right: parent.right } + anchors { left: parent.left; right: parent.right } - Text { - anchors { left: parent.left; leftMargin: 20; top: parent.top } - text: "IP address" - } - Text { - anchors { left: parent.left; leftMargin: 20; top:parent.top; topMargin: 30 } - text: form.ipv4.Address - } + Text { + anchors { left: parent.left; leftMargin: 20; } + text: "IP address" } - Item { - height: 40 - anchors { left: parent.left; right: parent.right } - - Text { - anchors { left: parent.left; leftMargin: 20; top: parent.top } - text: "Subnet mask" - } - Text { - anchors { left: parent.left; leftMargin: 20; top: parent.top; topMargin: 30 } - text: form.ipv4.Netmask - } - } - Item { - height: 40 - anchors { left: parent.left; right: parent.right } - - Text { - anchors { left: parent.left; leftMargin: 20; top: parent.top } - text: "Router" - } - Text { - anchors { left: parent.left; leftMargin: 20; top: parent.top; topMargin: 30 } - text: form.ipv4.Gateway - } - } - Item { - height: 40 - anchors { left: parent.left; right: parent.right } - - Text { - anchors { left: parent.left; leftMargin: 20; top: parent.top } - text: "DNS" - } - Text { - anchors { left: parent.left; leftMargin: 20; top: parent.top; topMargin: 30 } - text: form.nameservers.join() - } + Text { + anchors { left: parent.left; leftMargin: 20; topMargin: 30 } + text: form.ipv4.Address } } + Column { + anchors { left: parent.left; right: parent.right } + + Text { + anchors { left: parent.left; leftMargin: 20 } + text: "Subnet mask" + } + Text { + anchors { left: parent.left; leftMargin: 20; topMargin: 30 } + text: form.ipv4.Netmask + } + } + Column { + anchors { left: parent.left; right: parent.right } + + Text { + anchors { left: parent.left; leftMargin: 20 } + text: "Router" + } + Text { + anchors { left: parent.left; leftMargin: 20; topMargin: 30 } + text: form.ipv4.Gateway + } + } + Column { + anchors { left: parent.left; right: parent.right } + + Text { + anchors { left: parent.left; leftMargin: 20 } + text: "DNS" + } + Text { + anchors { left: parent.left; leftMargin: 20; topMargin: 30 } + text: form.nameservers.join() + } + } + } Item { id: networkFields anchors { left: parent.left; right: parent.right } - height: 360 Column { spacing: 50 - Item { - height: 40 + Column { anchors { left: parent.left; right: parent.right } Text { - anchors { left: parent.left; leftMargin: 20; top: parent.top } + anchors { left: parent.left; leftMargin: 20 } text: "IP address" } TextField { @@ -334,47 +337,44 @@ Item { text: form.ipv4.Address } } - Item { - height: 40 + Column { anchors { left: parent.left; right: parent.right } Text { - anchors { left: parent.left; leftMargin: 20; top: parent.top } + anchors { left: parent.left; leftMargin: 20 } text: "Subnet mask" } TextField { id: netmask - anchors { left: parent.left; leftMargin: 20; top: parent.top; topMargin: 30 } + anchors { left: parent.left; leftMargin: 20; topMargin: 30 } width: 440 text: form.ipv4.Netmask } } - Item { - height: 40 + Column { anchors { left: parent.left; right: parent.right } Text { - anchors { left: parent.left; leftMargin: 20; top: parent.top } + anchors { left: parent.left; leftMargin: 20 } text: "Router" } TextField { id: gateway - anchors { left: parent.left; leftMargin: 20; top: parent.top; topMargin: 30 } + anchors { left: parent.left; leftMargin: 20; topMargin: 30 } width: 440 text: form.ipv4.Gateway } } - Item { - height: 40 + Column { anchors { left: parent.left; right: parent.right } Text { - anchors { left: parent.left; leftMargin: 20; top: parent.top } + anchors { left: parent.left; leftMargin: 20 } text: "DNS" } TextField { id: nameserversField - anchors { left: parent.left; leftMargin: 20; top: parent.top; topMargin: 30 } + anchors { left: parent.left; leftMargin: 20; topMargin: 30 } width: 440 text: { var nservs = ""; @@ -390,32 +390,30 @@ Item { } } - Item { - height: 100 + Column { anchors { left: parent.left; right: parent.right } Text { - anchors { left: parent.left; leftMargin: 20; top: parent.top } + anchors { left: parent.left; leftMargin: 20 } text: "Search domains" } TextField { id: domainsField - anchors { left: parent.left; leftMargin: 20; top: parent.top; topMargin: 30 } + anchors { left: parent.left; leftMargin: 20; topMargin: 30 } width: 440 text: form.domains.join() } } - Item { + Column { anchors { left: parent.left; right: parent.right } - height: 100 Text { anchors { left: parent.left; leftMargin: 20 } text: "HTTP Proxy" } ButtonRow { id: proxy - anchors { left: parent.left; right: parent.right; top: parent.top; topMargin: 30; leftMargin: 10; rightMargin: 10 } + anchors { left: parent.left; right: parent.right; topMargin: 30; leftMargin: 10; rightMargin: 10 } state: form.proxy.Method states: [ @@ -469,75 +467,66 @@ Item { } } - Item { + Column { id: proxyManualFields anchors { left: parent.left; right: parent.right } - height: 440 + spacing: 50 Column { - spacing: 50 - Item { - height: 40 - anchors { left: parent.left; right: parent.right } + anchors { left: parent.left; right: parent.right } - Text { - anchors { left: parent.left; leftMargin: 20; top: parent.top } - text: "Server" - } - TextField { - id: proxyserver - anchors { left: parent.left; leftMargin: 20; top:parent.top; topMargin: 30 } - width: 440 - text: form.proxyConfig.Servers ? form.proxyConfig.Servers[0].split(":")[0] : "" - } + Text { + anchors { left: parent.left; leftMargin: 20 } + text: "Server" } - Item { - height: 40 - anchors { left: parent.left; right: parent.right } + TextField { + id: proxyserver + anchors { left: parent.left; leftMargin: 20; top:parent.top; topMargin: 30 } + width: 440 + text: form.proxyConfig.Servers ? form.proxyConfig.Servers[0].split(":")[0] : "" + } + } + Column { + anchors { left: parent.left; right: parent.right } - Text { - anchors { left: parent.left; leftMargin: 20; top: parent.top } - text: "Port" - } - TextField { - id: proxyport - anchors { left: parent.left; leftMargin: 20; top: parent.top; topMargin: 30 } - width: 440 - text: form.proxyConfig.Servers ? form.proxyConfig.Servers[0].split(":")[1] : "" - // TODO: validator - } + Text { + anchors { left: parent.left; leftMargin: 20 } + text: "Port" + } + TextField { + id: proxyport + anchors { left: parent.left; leftMargin: 20; topMargin: 30 } + width: 440 + text: form.proxyConfig.Servers ? form.proxyConfig.Servers[0].split(":")[1] : "" + // TODO: validator } } } - Item { + Column { id: proxyAutoFields anchors { left: parent.left; right: parent.right } - height: 440 + spacing: 50 + CheckBox { + id: proxyAutoUrl + text: "Use URL provided by DHCP server" + } Column { - spacing: 50 - CheckBox { - id: proxyAutoUrl - text: "Use URL provided by DHCP server" - } - Item { - height: 40 - visible: !proxyAutoUrl.checked - anchors { left: parent.left; right: parent.right } + visible: !proxyAutoUrl.checked + anchors { left: parent.left; right: parent.right } - Text { - anchors { left: parent.left; leftMargin: 20; top: parent.top } - text: "URL" - } - TextField { - id: proxyurl - anchors { left: parent.left; leftMargin: 20; top:parent.top; topMargin: 30 } - width: 440 - readOnly: proxyAutoUrl.checked - text: form.proxy.URL - // TODO: validator - } + Text { + anchors { left: parent.left; leftMargin: 20 } + text: "URL" + } + TextField { + id: proxyurl + anchors { left: parent.left; leftMargin: 20; top:parent.top; topMargin: 30 } + width: 440 + readOnly: proxyAutoUrl.checked + text: form.proxy.URL + // TODO: validator } } } diff --git a/settingsmodules/WirelessSettings.qml b/settingsmodules/WirelessSettings.qml index 9fe7bede..7407ee01 100644 --- a/settingsmodules/WirelessSettings.qml +++ b/settingsmodules/WirelessSettings.qml @@ -42,12 +42,14 @@ import QtQuick.Controls 1.2 StackView { id: stackView initialItem: mainView + width: 1080 + height: 1815 Component { id: mainView Item { id: mainWindow - property Item tools: commonTools + property Item tools//: commonTools Timer { id: scanTimer @@ -96,15 +98,16 @@ StackView { } if (!networkingModel.sheetOpened) { networkingModel.sheetOpened = true - var sheet = pageStack.openSheet(Qt.resolvedUrl("NetworkSettingsSheet.qml"), { + var sheet = stackView.push({item: Qt.resolvedUrl("NetworkSettingsSheet.qml"), properties:{ mustacheView: view, networkName: networkingModel.networkName, userAgent: userAgent, scanTimer: scanTimer - }) - sheet.accepted.connect(function() { networkingModel.sheetOpened = false }) - sheet.rejected.connect(function() { networkingModel.sheetOpened = false }) - // TODO: there was code that checked for pageStack.busy and + }}) + + // sheet.accepted.connect(function() { networkingModel.sheetOpened = false }) + //sheet.rejected.connect(function() { networkingModel.sheetOpened = false }) + // TODO: there was code that checked for stackView.busy and // didn't open if it was true. What was that about? } } @@ -130,17 +133,19 @@ StackView { ListView { id: networkList //header: WirelessApplet { } - anchors.margins: UiConstants.DefaultMargin + anchors.margins: 4//UiConstants.DefaultMargin anchors.fill: parent model: networkingModel delegate: PlasmaComponents.ListItem { - + enabled: true PlasmaCore.IconItem { + id: icon anchors { left: parent.left top: parent.top bottom: parent.bototm } + height: units.iconSizes.large width: height source: { var strength = modelData.strength; @@ -166,6 +171,7 @@ StackView { top: parent.top right: parent.right bottom: parent.bottom + leftMargin: units.smallSpacing } PlasmaExtras.Heading { level: 2 diff --git a/settingsmodules/mustache.js b/settingsmodules/mustache.js new file mode 100644 index 00000000..641cebd5 --- /dev/null +++ b/settingsmodules/mustache.js @@ -0,0 +1,536 @@ +/*! + * mustache.js - Logic-less {{mustache}} templates with JavaScript + * http://github.com/janl/mustache.js + */ +var Mustache = (typeof module !== "undefined" && module.exports) || {}; + +(function (exports) { + + exports.name = "mustache.js"; + exports.version = "0.5.0-dev"; + exports.tags = ["{{", "}}"]; + exports.parse = parse; + exports.compile = compile; + exports.render = render; + exports.clearCache = clearCache; + + // This is here for backwards compatibility with 0.4.x. + exports.to_html = function (template, view, partials, send) { + var result = render(template, view, partials); + + if (typeof send === "function") { + send(result); + } else { + return result; + } + }; + + var _toString = Object.prototype.toString; + var _isArray = Array.isArray; + var _forEach = Array.prototype.forEach; + var _trim = String.prototype.trim; + + var isArray; + if (_isArray) { + isArray = _isArray; + } else { + isArray = function (obj) { + return _toString.call(obj) === "[object Array]"; + }; + } + + var forEach; + if (_forEach) { + forEach = function (obj, callback, scope) { + return _forEach.call(obj, callback, scope); + }; + } else { + forEach = function (obj, callback, scope) { + for (var i = 0, len = obj.length; i < len; ++i) { + callback.call(scope, obj[i], i, obj); + } + }; + } + + var spaceRe = /^\s*$/; + + function isWhitespace(string) { + return spaceRe.test(string); + } + + var trim; + if (_trim) { + trim = function (string) { + return string == null ? "" : _trim.call(string); + }; + } else { + var trimLeft, trimRight; + + if (isWhitespace("\xA0")) { + trimLeft = /^\s+/; + trimRight = /\s+$/; + } else { + // IE doesn't match non-breaking spaces with \s, thanks jQuery. + trimLeft = /^[\s\xA0]+/; + trimRight = /[\s\xA0]+$/; + } + + trim = function (string) { + return string == null ? "" : + String(string).replace(trimLeft, "").replace(trimRight, ""); + }; + } + + var escapeMap = { + "&": "&", + "<": "<", + ">": ">", + '"': '"', + "'": ''' + }; + + function escapeHTML(string) { + return String(string).replace(/&(?!\w+;)|[<>"']/g, function (s) { + return escapeMap[s] || s; + }); + } + + /** + * Adds the `template`, `line`, and `file` properties to the given error + * object and alters the message to provide more useful debugging information. + */ + function debug(e, template, line, file) { + file = file || "