aboutsummaryrefslogtreecommitdiffstats
path: root/mobility
diff options
context:
space:
mode:
authorLauro Neto <lauro.neto@openbossa.org>2011-10-11 17:40:07 -0300
committerLauro Neto <lauro.neto@openbossa.org>2011-10-11 17:40:07 -0300
commitf52941712fc32dfd2881bed0771c86ed76716883 (patch)
tree753b9aa8807eef4bba7497e57d26fac1f0ad023e /mobility
parent9616988e1332f9e67cdaab338c3970232cd9d68f (diff)
parent53bd4b768ea773723f6eba338ecb2cee0facf591 (diff)
Merge branch 'qml'
Diffstat (limited to 'mobility')
-rw-r--r--mobility/audiooutput/generator/MainPage.qml58
-rw-r--r--mobility/audiooutput/generator/audiooutput.py (renamed from mobility/audiooutput/audiooutput.py)111
-rw-r--r--mobility/audiooutput/generator/generator.py117
-rw-r--r--mobility/audiooutput/generator/main.qml11
-rw-r--r--mobility/audiooutput/generator/toneplayer.py203
-rw-r--r--mobility/audiooutput/player/MainPage.qml16
-rw-r--r--mobility/audiooutput/player/main.qml11
-rw-r--r--mobility/audiooutput/player/qmlplayer.py70
-rw-r--r--mobility/audiooutput/player/simpleplayer.py (renamed from mobility/audiooutput/simpleplayer.py)3
-rw-r--r--mobility/feedback/MainPage.qml43
-rw-r--r--mobility/feedback/hapticsquare-qtgui.py127
-rw-r--r--mobility/feedback/hapticsquare.py136
-rw-r--r--mobility/feedback/main.qml11
-rw-r--r--mobility/organizer/qml/OverviewPage.qml56
-rw-r--r--mobility/organizer/qml/TodoEdit.qml239
-rw-r--r--mobility/organizer/qml/main.qml10
-rw-r--r--mobility/organizer/qml/qmltodo.py274
-rw-r--r--mobility/samplephonebook/qml/ContactEdit.qml116
-rw-r--r--mobility/samplephonebook/qml/MainPage.qml47
-rw-r--r--mobility/samplephonebook/qml/SelectBackend.qml41
-rw-r--r--mobility/samplephonebook/qml/main.qml10
-rw-r--r--mobility/samplephonebook/qml/qmlsamplephonebook.py274
-rw-r--r--mobility/servicebrowser/qml/HoldButton.qml45
-rw-r--r--mobility/servicebrowser/qml/ImplementationDetails.qml60
-rw-r--r--mobility/servicebrowser/qml/ServiceImplementations.qml93
-rw-r--r--mobility/servicebrowser/qml/ServicesPage.qml61
-rw-r--r--mobility/servicebrowser/qml/main.qml10
-rw-r--r--mobility/servicebrowser/qml/qmlbrowser.py134
-rw-r--r--mobility/servicebrowser/servicebrowser.py2
-rw-r--r--mobility/sysinfo/dialog.py2
-rw-r--r--mobility/sysinfo/qml/AvailableLanguages.qml21
-rw-r--r--mobility/sysinfo/qml/DevicePage.qml73
-rw-r--r--mobility/sysinfo/qml/DisplayPage.qml58
-rw-r--r--mobility/sysinfo/qml/GeneralPage.qml60
-rw-r--r--mobility/sysinfo/qml/NetworkDetails.qml67
-rw-r--r--mobility/sysinfo/qml/NetworkPage.qml76
-rw-r--r--mobility/sysinfo/qml/ScreenSaverPage.qml10
-rw-r--r--mobility/sysinfo/qml/StoragePage.qml55
-rw-r--r--mobility/sysinfo/qml/TabBarPage.qml31
-rw-r--r--mobility/sysinfo/qml/main.py334
-rw-r--r--mobility/sysinfo/qml/main.qml10
41 files changed, 2993 insertions, 193 deletions
diff --git a/mobility/audiooutput/generator/MainPage.qml b/mobility/audiooutput/generator/MainPage.qml
new file mode 100644
index 0000000..aedc384
--- /dev/null
+++ b/mobility/audiooutput/generator/MainPage.qml
@@ -0,0 +1,58 @@
+
+
+import QtQuick 1.1
+import com.nokia.meego 1.0
+import com.nokia.extras 1.1
+
+Page {
+ id: mainPage
+ anchors.margins: rootWindow.pageMargin
+ anchors.fill: parent
+
+ Flow {
+ anchors.fill: parent
+
+ Flickable {
+ width: deviceButtons.width
+ height: screen.displayHeight
+ contentHeight: deviceButtons.height
+ ButtonColumn {
+ id: deviceButtons
+ Repeater {
+ model: deviceModel
+ Button {
+ text: modelData
+ onClicked: {
+ player.deviceChanged(index)
+ }
+ }
+ }
+ }
+ }
+
+ Column {
+ CheckBox {
+ anchors.left: parent.left
+ id: play
+ checked: true
+ text: "Play when checked"
+ onClicked: { player.toggleSuspendResume() }
+
+ Connections {
+ target: player
+ onPlaybackResumed: {
+ play.checked = true
+ }
+ }
+ }
+
+ CheckBox {
+ anchors.left: parent.left
+ id: pushpull
+ checked: true
+ text: "Pull mode when checked"
+ onClicked: { player.toggleMode() }
+ }
+ }
+ }
+}
diff --git a/mobility/audiooutput/audiooutput.py b/mobility/audiooutput/generator/audiooutput.py
index 523a93d..fa05611 100644
--- a/mobility/audiooutput/audiooutput.py
+++ b/mobility/audiooutput/generator/audiooutput.py
@@ -10,6 +10,8 @@ import struct
from math import sin, pi
+from generator import Generator
+
DURATION_SECONDS = 1
TONE_FREQUENCY_HZ = 600
DATA_FREQUENCY_HZ = 44100
@@ -20,115 +22,6 @@ PULL_MODE_LABEL = 'Enable pull mode'
SUSPEND_LABEL = 'Suspend playback'
RESUME_LABEL = 'Resume playback'
-signed8 = struct.Struct('>b')
-unsigned8 = struct.Struct('>B')
-
-bigSigned16 = struct.Struct('>h')
-bigUnsigned16 = struct.Struct('>H')
-
-littleSigned16 = struct.Struct('<h')
-littleUnsigned16 = struct.Struct('<H')
-
-
-class Generator(QIODevice):
-
- def __init__(self, fmt, durationUs, frequency, parent, filename=None):
- QIODevice.__init__(self, parent)
- self.pos = 0
- self.buf = []
-
- self.generateData(fmt, durationUs, frequency)
- if filename:
- self.dump(filename, fmt)
-
- def dump(self, filename, fmt):
-
- import wave
-
- handle = wave.open(filename, 'wb')
-
- handle.setnchannels(fmt.channels())
- handle.setsampwidth(fmt.sampleSize()/8)
- handle.setframerate(fmt.sampleRate())
- handle.writeframes(''.join(self.buf))
-
- handle.close()
-
- def start(self):
- self.open(QIODevice.ReadOnly)
-
- def stop(self):
- self.pos = 0
- self.close()
-
- def readData(self, size):
- total = 0
- data = []
-
- while size - total > 0:
- chunk = min(len(self.buf) - self.pos, size - total)
- data.extend(self.buf[self.pos:self.pos + chunk])
- self.pos = (self.pos + chunk) % len(self.buf)
- total += chunk
-
- return ''.join(data)
-
- def writeData(self, data, maxLen):
- return 0
-
- def bytesAvailable(self):
- return len(self.buf) + QIODevice.bytesAvailable(self)
-
- def generateData(self, fmt, durationUs, frequency):
- channelBytes = fmt.sampleSize() / 8
- sampleBytes = fmt.channels() * channelBytes
-
- seconds = durationUs / 1000000
- length = fmt.frequency() * sampleBytes * seconds
-
- assert length % sampleBytes == 0
-
- self.buf = [''] * length
-
- sampleIndex = 0
-
- for i in range(0, length, channelBytes):
- position = float(sampleIndex % fmt.frequency()) / fmt.frequency()
- x = sin(2 * pi * frequency * position)
-
- for channel in range(fmt.channels()):
- if fmt.sampleSize() == 8:
- value = ((1.0 + x) / 2 * 255) % 255
-
- if fmt.sampleType() == QAudioFormat.UnSignedInt:
- data = unsigned8.pack(value)
- else: #Signed
- data = signed8.pack(value - 127)
-
- self.buf[i + channel * channelBytes] = data
-
- elif fmt.sampleSize() == 16:
- value = ((1.0 + x) / 2 * 65535) % 65535
-
- if fmt.sampleType() == QAudioFormat.UnSignedInt:
- if fmt.byteOrder() == QAudioFormat.LittleEndian:
- data = littleUnsigned16.pack(value)
- else:
- data = bigUnsigned16.pack(value)
- else:
- value -= 32767
-
- if fmt.byteOrder() == QAudioFormat.LittleEndian:
- data = littleSigned16.pack(value)
- else:
- data = bigSigned16.pack(value)
-
- self.buf[i + channel * channelBytes] = data[0]
- self.buf[i + channel * channelBytes + 1] = data[1]
-
- sampleIndex += 1
-
-
class AudioTest(QMainWindow):
def __init__(self, filename=None):
diff --git a/mobility/audiooutput/generator/generator.py b/mobility/audiooutput/generator/generator.py
new file mode 100644
index 0000000..9e2dd5e
--- /dev/null
+++ b/mobility/audiooutput/generator/generator.py
@@ -0,0 +1,117 @@
+
+import struct
+from math import sin, pi
+
+from PySide.QtCore import QIODevice, QByteArray, QTimer
+from QtMobility.MultimediaKit import QAudioFormat, QAudio, QAudioDeviceInfo
+
+signed8 = struct.Struct('>b')
+unsigned8 = struct.Struct('>B')
+
+bigSigned16 = struct.Struct('>h')
+bigUnsigned16 = struct.Struct('>H')
+
+littleSigned16 = struct.Struct('<h')
+littleUnsigned16 = struct.Struct('<H')
+
+
+class Generator(QIODevice):
+
+ def __init__(self, fmt, durationUs, frequency, parent, filename=None):
+ QIODevice.__init__(self, parent)
+ self.pos = 0
+ self.buf = []
+
+ self.generateData(fmt, durationUs, frequency)
+ if filename:
+ self.dump(filename, fmt)
+
+ def dump(self, filename, fmt):
+
+ import wave
+
+ handle = wave.open(filename, 'wb')
+
+ handle.setnchannels(fmt.channels())
+ handle.setsampwidth(fmt.sampleSize()/8)
+ handle.setframerate(fmt.sampleRate())
+ handle.writeframes(''.join(self.buf))
+
+ handle.close()
+
+ def start(self):
+ self.open(QIODevice.ReadOnly)
+
+ def stop(self):
+ self.pos = 0
+ self.close()
+
+ def readData(self, size):
+ total = 0
+ data = []
+
+ while size - total > 0:
+ chunk = min(len(self.buf) - self.pos, size - total)
+ data.extend(self.buf[self.pos:self.pos + chunk])
+ self.pos = (self.pos + chunk) % len(self.buf)
+ total += chunk
+
+ return ''.join(data)
+
+ def writeData(self, data, maxLen):
+ return 0
+
+ def bytesAvailable(self):
+ return len(self.buf) + QIODevice.bytesAvailable(self)
+
+ def generateData(self, fmt, durationUs, frequency):
+ channelBytes = fmt.sampleSize() / 8
+ sampleBytes = fmt.channels() * channelBytes
+
+ seconds = durationUs / 1000000
+ length = fmt.frequency() * sampleBytes * seconds
+
+ assert length % sampleBytes == 0
+
+ self.buf = [''] * length
+
+ sampleIndex = 0
+
+ for i in range(0, length, channelBytes):
+ position = float(sampleIndex % fmt.frequency()) / fmt.frequency()
+ x = sin(2 * pi * frequency * position)
+
+ for channel in range(fmt.channels()):
+ if fmt.sampleSize() == 8:
+ value = ((1.0 + x) / 2 * 255) % 255
+
+ if fmt.sampleType() == QAudioFormat.UnSignedInt:
+ data = unsigned8.pack(value)
+ else: #Signed
+ data = signed8.pack(value - 127)
+
+ self.buf[i + channel * channelBytes] = data
+
+ elif fmt.sampleSize() == 16:
+ value = ((1.0 + x) / 2 * 65535) % 65535
+
+ if fmt.sampleType() == QAudioFormat.UnSignedInt:
+ if fmt.byteOrder() == QAudioFormat.LittleEndian:
+ data = littleUnsigned16.pack(value)
+ else:
+ data = bigUnsigned16.pack(value)
+ else:
+ value -= 32767
+
+ if fmt.byteOrder() == QAudioFormat.LittleEndian:
+ data = littleSigned16.pack(value)
+ else:
+ data = bigSigned16.pack(value)
+
+ self.buf[i + channel * channelBytes] = data[0]
+ self.buf[i + channel * channelBytes + 1] = data[1]
+
+ sampleIndex += 1
+
+
+
diff --git a/mobility/audiooutput/generator/main.qml b/mobility/audiooutput/generator/main.qml
new file mode 100644
index 0000000..dd3484d
--- /dev/null
+++ b/mobility/audiooutput/generator/main.qml
@@ -0,0 +1,11 @@
+
+import QtQuick 1.1
+import com.nokia.meego 1.0
+
+PageStackWindow {
+
+ id: rootWindow
+ showStatusBar: false
+ initialPage: MainPage { }
+
+}
diff --git a/mobility/audiooutput/generator/toneplayer.py b/mobility/audiooutput/generator/toneplayer.py
new file mode 100644
index 0000000..a142203
--- /dev/null
+++ b/mobility/audiooutput/generator/toneplayer.py
@@ -0,0 +1,203 @@
+'''
+ Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ All rights reserved.
+ Contact: Nokia Corporation (qt-info@nokia.com)
+
+ This file is part of the Qt Mobility Components.
+
+ $QT_BEGIN_LICENSE:LGPL$
+ No Commercial Usage
+ This file contains pre-release code and may not be distributed.
+ You may use this file in accordance with the terms and conditions
+ contained in the Technology Preview License Agreement accompanying
+ this package.
+
+ GNU Lesser General Public License Usage
+ Alternatively, this file may be used under the terms of the GNU Lesser
+ General Public License version 2.1 as published by the Free Software
+ Foundation and appearing in the file LICENSE.LGPL included in the
+ packaging of this file. Please review the following information to
+ ensure the GNU Lesser General Public License version 2.1 requirements
+ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+
+ In addition, as a special exception, Nokia gives you certain additional
+ rights. These rights are described in the Nokia Qt LGPL Exception
+ version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+
+ If you have questions regarding the use of this file, please contact
+ Nokia at qt-info@nokia.com.
+'''
+
+import os
+import sys
+
+from PySide.QtCore import QObject, QUrl, QTimer, QByteArray, Slot, Property, Signal
+from PySide.QtGui import QApplication
+from PySide.QtDeclarative import QDeclarativeView
+from QtMobility.MultimediaKit import QAudioFormat, QAudioDeviceInfo, QAudioOutput, QAudio
+
+from generator import Generator
+
+PUSH_MODE_LABEL = 'Enable push mode'
+PULL_MODE_LABEL = 'Enable pull mode'
+SUSPEND_LABEL = 'Suspend playback'
+RESUME_LABEL = 'Resume playback'
+
+BUFFER_SIZE = 32768
+DURATION_SECONDS = 1
+TONE_FREQUENCY_HZ = 600
+DATA_FREQUENCY_HZ = 44100
+
+
+class TonePlayer(QObject):
+
+ changed = Signal()
+
+ def getStateLabel(self):
+ print "Getting"
+ return self._label
+
+ def setStateLabel(self, value):
+ print "Setting", value
+ self._label = value
+ self.changed.emit()
+
+ stateLabel = Property(str, getStateLabel, setStateLabel, notify=changed)
+
+ def __init__(self, devices=None, filename=None, parent=None):
+ QObject.__init__(self, parent)
+
+ self.pullTimer = QTimer(self)
+ self.buf = QByteArray()
+ self.devices = devices
+ self.device = QAudioDeviceInfo.defaultOutputDevice()
+ self.generator = None
+ self.audioOutput = None
+ self.output = None
+ self.fmt = QAudioFormat()
+ self.pullMode = False
+ self.dump = filename
+ self._label = SUSPEND_LABEL
+
+ self.initializeAudio()
+
+ def initializeAudio(self):
+ self.pullTimer.timeout.connect(self.pullTimerExpired)
+
+ self.pullMode = True
+
+ self.fmt.setFrequency(DATA_FREQUENCY_HZ)
+ self.fmt.setChannels(1)
+ self.fmt.setSampleSize(16)
+ self.fmt.setCodec('audio/pcm')
+ self.fmt.setByteOrder(QAudioFormat.LittleEndian)
+ self.fmt.setSampleType(QAudioFormat.SignedInt)
+
+ info = QAudioDeviceInfo(QAudioDeviceInfo.defaultOutputDevice())
+ if not info.isFormatSupported(self.fmt):
+ print 'Default format not supported - trying to use nearest'
+ self.fmt = info.nearestFormat(self.fmt)
+
+ self.generator = Generator(self.fmt, DURATION_SECONDS * 1000000,
+ TONE_FREQUENCY_HZ, self, self.dump)
+
+ self.createAudioOutput()
+
+ def createAudioOutput(self):
+ self.audioOutput = QAudioOutput(self.device, self.fmt, self)
+ self.audioOutput.notify.connect(self.notified)
+ self.audioOutput.stateChanged.connect(self.stateChanged)
+ self.generator.start()
+ self.audioOutput.start(self.generator)
+
+ @Slot()
+ def toggleSuspendResume(self):
+ if self.audioOutput.state() == QAudio.SuspendedState:
+ print 'Status: Suspended, resuming'
+ self.audioOutput.resume()
+ self.stateLabel = SUSPEND_LABEL
+ elif self.audioOutput.state() == QAudio.ActiveState:
+ print 'Status: Active, suspending'
+ self.audioOutput.suspend()
+ self.stateLabel = RESUME_LABEL
+ elif self.audioOutput.state() == QAudio.StoppedState:
+ print 'Status: Stopped, resuming'
+ self.audioOutput.resume()
+ self.stateLabel = SUSPEND_LABEL
+ elif self.audioOutput.state() == QAudio.IdleState:
+ print 'Status: Idle'
+
+ playbackResumed = Signal()
+
+ @Slot()
+ def toggleMode(self):
+ self.pullTimer.stop()
+ self.audioOutput.stop()
+
+ if self.pullMode:
+ print "Enabling push mode"
+ self.output = self.audioOutput.start()
+ self.pullMode = False
+ self.pullTimer.start(5)
+ else:
+ print "Enabling pull mode"
+ self.pullMode = True
+ self.audioOutput.start(self.generator)
+ self.playbackResumed.emit()
+
+ @Slot(int)
+ def deviceChanged(self, index):
+ print "Device changed: index:", index
+ print "Selected device name: ", self.devices[index].deviceName()
+ self.pullTimer.stop()
+ self.generator.stop()
+ self.audioOutput.stop()
+ self.audioOutput.disconnect(self)
+ self.device = self.devices[index]
+ self.createAudioOutput()
+
+ def stateChanged(self, state):
+ print 'State changed: ', state
+
+ def notified(self):
+ print 'Bytes free %d, elapsed usecs %d, processed usecs %d' % (
+ self.audioOutput.bytesFree(),
+ self.audioOutput.elapsedUSecs(),
+ self.audioOutput.processedUSecs())
+
+ def pullTimerExpired(self):
+ if self.audioOutput.state() != QAudio.StoppedState:
+ chunks = self.audioOutput.bytesFree() / self.audioOutput.periodSize()
+ while chunks:
+ data = self.generator.read(self.audioOutput.periodSize())
+ self.output.write(data)
+ if len(data) != self.audioOutput.periodSize():
+ break
+ chunks -= 1
+
+
+def main():
+ app = QApplication([])
+ app.setApplicationName('Audio Output Test')
+ view = QDeclarativeView()
+
+ devices = []
+ for info in QAudioDeviceInfo.availableDevices(QAudio.AudioOutput):
+ devices.append(info)
+
+ player = TonePlayer(devices, sys.argv[1] if len(sys.argv) > 1 else None)
+
+ context = view.rootContext()
+ context.setContextProperty("player", player)
+ context.setContextProperty("deviceModel", [x.deviceName() for x in devices])
+
+ url = QUrl('main.qml')
+ view.setSource(url)
+
+
+ view.show()
+
+ app.exec_()
+
+if __name__ == '__main__':
+ main()
diff --git a/mobility/audiooutput/player/MainPage.qml b/mobility/audiooutput/player/MainPage.qml
new file mode 100644
index 0000000..57358bc
--- /dev/null
+++ b/mobility/audiooutput/player/MainPage.qml
@@ -0,0 +1,16 @@
+
+
+import QtQuick 1.1
+import com.nokia.meego 1.0
+
+Page {
+ id: mainPage
+ anchors.margins: rootWindow.pageMargin
+
+ Button {
+ id: play
+ text: "Play!"
+ anchors.fill: parent
+ onClicked: player.play()
+ }
+}
diff --git a/mobility/audiooutput/player/main.qml b/mobility/audiooutput/player/main.qml
new file mode 100644
index 0000000..dd3484d
--- /dev/null
+++ b/mobility/audiooutput/player/main.qml
@@ -0,0 +1,11 @@
+
+import QtQuick 1.1
+import com.nokia.meego 1.0
+
+PageStackWindow {
+
+ id: rootWindow
+ showStatusBar: false
+ initialPage: MainPage { }
+
+}
diff --git a/mobility/audiooutput/player/qmlplayer.py b/mobility/audiooutput/player/qmlplayer.py
new file mode 100644
index 0000000..51a3c49
--- /dev/null
+++ b/mobility/audiooutput/player/qmlplayer.py
@@ -0,0 +1,70 @@
+'''
+ Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ All rights reserved.
+ Contact: Nokia Corporation (qt-info@nokia.com)
+
+ This file is part of the Qt Mobility Components.
+
+ $QT_BEGIN_LICENSE:LGPL$
+ No Commercial Usage
+ This file contains pre-release code and may not be distributed.
+ You may use this file in accordance with the terms and conditions
+ contained in the Technology Preview License Agreement accompanying
+ this package.
+
+ GNU Lesser General Public License Usage
+ Alternatively, this file may be used under the terms of the GNU Lesser
+ General Public License version 2.1 as published by the Free Software
+ Foundation and appearing in the file LICENSE.LGPL included in the
+ packaging of this file. Please review the following information to
+ ensure the GNU Lesser General Public License version 2.1 requirements
+ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+
+ In addition, as a special exception, Nokia gives you certain additional
+ rights. These rights are described in the Nokia Qt LGPL Exception
+ version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+
+ If you have questions regarding the use of this file, please contact
+ Nokia at qt-info@nokia.com.
+'''
+
+import os
+import sys
+
+from PySide.QtCore import *
+from PySide.QtGui import *
+from PySide.QtDeclarative import *
+from QtMobility.MultimediaKit import *
+
+class Player(QObject):
+
+ def __init__(self, filename, parent=None):
+ QObject.__init__(self, parent)
+
+ self.source = QUrl.fromLocalFile(os.path.abspath(filename))
+ self.player = QMediaPlayer()
+ self.player.setMedia(self.source)
+
+ @Slot()
+ def play(self):
+ self.player.play()
+
+def main():
+ app = QApplication([])
+ view = QDeclarativeView()
+ player = Player(sys.argv[1])
+ context = view.rootContext()
+ context.setContextProperty("player", player)
+
+ url = QUrl('main.qml')
+ view.setSource(url)
+ view.showFullScreen()
+
+ app.exec_()
+
+
+if __name__ == '__main__':
+ main()
+
+
+
diff --git a/mobility/audiooutput/simpleplayer.py b/mobility/audiooutput/player/simpleplayer.py
index f65b0b3..1e4213c 100644
--- a/mobility/audiooutput/simpleplayer.py
+++ b/mobility/audiooutput/player/simpleplayer.py
@@ -1,4 +1,5 @@
+import os
import sys
from PySide.QtCore import QUrl
@@ -30,7 +31,7 @@ def main():
app = QApplication([])
app.setApplicationName('Simple Audio player')
- window = AudioTest(sys.argv[1])
+ window = AudioTest(os.path.abspath(sys.argv[1]))
window.show()
return app.exec_()
diff --git a/mobility/feedback/MainPage.qml b/mobility/feedback/MainPage.qml
new file mode 100644
index 0000000..4678be9
--- /dev/null
+++ b/mobility/feedback/MainPage.qml
@@ -0,0 +1,43 @@
+
+
+import QtQuick 1.1
+import com.nokia.meego 1.0
+
+Page {
+ id: mainPage
+ anchors.margins: rootWindow.pageMargin
+
+ Flow {
+ anchors.top: parent.top
+ anchors.right: parent.right
+ anchors.left: parent.left
+ anchors.margins: 10
+
+ spacing: 10
+
+ Button {
+ id: rumble
+ text: "Rumble"
+ onClicked: effectPlayer.playRumble()
+ }
+
+ Button {
+ id: ocean
+ text: "Ocean"
+ onClicked: effectPlayer.playOcean()
+ }
+
+ Button {
+ id: buttonClick
+ text: "Button Click"
+ onClicked: effectPlayer.playButtonClick()
+ }
+
+ Button {
+ id: negativeEffect
+ text: "Negative Effect"
+ onClicked: effectPlayer.playNegativeEffect()
+ }
+ }
+
+}
diff --git a/mobility/feedback/hapticsquare-qtgui.py b/mobility/feedback/hapticsquare-qtgui.py
new file mode 100644
index 0000000..0554f4d
--- /dev/null
+++ b/mobility/feedback/hapticsquare-qtgui.py
@@ -0,0 +1,127 @@
+'''
+ Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ All rights reserved.
+ Contact: Nokia Corporation (qt-info@nokia.com)
+
+ This file is part of the Qt Mobility Components.
+
+ $QT_BEGIN_LICENSE:LGPL$
+ No Commercial Usage
+ This file contains pre-release code and may not be distributed.
+ You may use this file in accordance with the terms and conditions
+ contained in the Technology Preview License Agreement accompanying
+ this package.
+
+ GNU Lesser General Public License Usage
+ Alternatively, this file may be used under the terms of the GNU Lesser
+ General Public License version 2.1 as published by the Free Software
+ Foundation and appearing in the file LICENSE.LGPL included in the
+ packaging of this file. Please review the following information to
+ ensure the GNU Lesser General Public License version 2.1 requirements
+ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+
+ In addition, as a special exception, Nokia gives you certain additional
+ rights. These rights are described in the Nokia Qt LGPL Exception
+ version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+
+ If you have questions regarding the use of this file, please contact
+ Nokia at qt-info@nokia.com.
+'''
+
+from PySide.QtCore import *
+from PySide.QtGui import *
+from QtMobility.Feedback import *
+
+class HapticButton(QWidget):
+ clicked = Signal()
+ toggled = Signal(bool)
+
+ def __init__(self, label):
+ QWidget.__init__(self, None)
+ self.m_label = label
+ self.m_checked = False
+ self.m_checkable = False
+
+ self.setMinimumSize(100, 100)
+
+ def mousePressEvent(self, qMouseEvent):
+ self.clicked.emit()
+
+ def paintEvent(self, qPaintEvent):
+ paint = QPainter(self)
+
+ r = QRect(1, 1, self.width()-2, self.height()-2)
+ paint.drawRoundedRect(r, 10, 10)
+ paint.drawText(r, Qt.AlignCenter, self.m_label)
+
+class Dialog(QDialog):
+
+ def __init__(self):
+ QDialog.__init__(self)
+ self.m_rumble = QFeedbackHapticsEffect()
+ self.m_rumble.setAttackIntensity(0.1)
+ self.m_rumble.setAttackTime(250)
+ self.m_rumble.setIntensity(1)
+ self.m_rumble.setDuration(1000)
+ self.m_rumble.setFadeTime(250)
+ self.m_rumble.setFadeIntensity(0.1)
+
+ self.m_ocean = QFeedbackHapticsEffect()
+ self.m_ocean.setAttackIntensity(0.1)
+ self.m_ocean.setAttackTime(450)
+ self.m_ocean.setIntensity(0.8)
+ self.m_ocean.setDuration(6000)
+ self.m_ocean.setFadeTime(900)
+ self.m_ocean.setFadeIntensity(0.05)
+ self.m_ocean.setPeriod(1500)
+
+ self.m_btnRumble = HapticButton("Rumble!")
+ self.m_btnOcean = HapticButton("Ocean")
+ self.m_btnButtonClick = HapticButton("Click")
+ self.m_btnNegativeEffect = HapticButton("Oops!")
+ self.topLayout = QGridLayout(self)
+ self.topLayout.addWidget(self.m_btnRumble, 0, 0)
+ self.topLayout.addWidget(self.m_btnOcean, 0, 1)
+ self.topLayout.addWidget(self.m_btnButtonClick, 1, 0)
+ self.topLayout.addWidget(self.m_btnNegativeEffect, 1, 1)
+
+ self.m_btnRumble.clicked.connect(self.playRumble)
+ self.m_btnOcean.clicked.connect(self.playOcean)
+ self.m_btnButtonClick.clicked.connect(self.playButtonClick)
+ self.m_btnNegativeEffect.clicked.connect(self.playNegativeEffect)
+
+ def __del__(self):
+ del self.m_btnRumble
+ del self.m_btnOcean
+ del self.m_btnButtonClick
+ del self.m_btnNegativeEffect
+
+ def playRumble(self):
+ self.m_rumble.start()
+ print "Play rumble"
+
+ def playOcean(self):
+ if self.m_ocean.state() == QFeedbackEffect.Stopped:
+ self.m_ocean.start()
+ print "Ocean start"
+ else:
+ self.m_ocean.stop()
+ print "Ocean stop"
+
+ def playButtonClick(self):
+ QFeedbackEffect.playThemeEffect(QFeedbackEffect.ThemeBasicButton)
+ print "Play button click"
+
+ def playNegativeEffect(self):
+ QFeedbackEffect.playThemeEffect(QFeedbackEffect.ThemeNegativeTacticon)
+ print "Play negative button click"
+
+
+def main():
+ app = QApplication([])
+ w = Dialog()
+ w.showMaximized()
+ return app.exec_()
+
+if __name__ == "__main__":
+ main()
diff --git a/mobility/feedback/hapticsquare.py b/mobility/feedback/hapticsquare.py
index 0554f4d..ba5a964 100644
--- a/mobility/feedback/hapticsquare.py
+++ b/mobility/feedback/hapticsquare.py
@@ -1,5 +1,5 @@
'''
- Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
All rights reserved.
Contact: Nokia Corporation (qt-info@nokia.com)
@@ -30,77 +30,38 @@
from PySide.QtCore import *
from PySide.QtGui import *
+from PySide.QtDeclarative import *
from QtMobility.Feedback import *
-class HapticButton(QWidget):
- clicked = Signal()
- toggled = Signal(bool)
-
- def __init__(self, label):
- QWidget.__init__(self, None)
- self.m_label = label
- self.m_checked = False
- self.m_checkable = False
-
- self.setMinimumSize(100, 100)
-
- def mousePressEvent(self, qMouseEvent):
- self.clicked.emit()
-
- def paintEvent(self, qPaintEvent):
- paint = QPainter(self)
-
- r = QRect(1, 1, self.width()-2, self.height()-2)
- paint.drawRoundedRect(r, 10, 10)
- paint.drawText(r, Qt.AlignCenter, self.m_label)
-
-class Dialog(QDialog):
-
- def __init__(self):
- QDialog.__init__(self)
- self.m_rumble = QFeedbackHapticsEffect()
- self.m_rumble.setAttackIntensity(0.1)
- self.m_rumble.setAttackTime(250)
- self.m_rumble.setIntensity(1)
- self.m_rumble.setDuration(1000)
- self.m_rumble.setFadeTime(250)
- self.m_rumble.setFadeIntensity(0.1)
-
- self.m_ocean = QFeedbackHapticsEffect()
- self.m_ocean.setAttackIntensity(0.1)
- self.m_ocean.setAttackTime(450)
- self.m_ocean.setIntensity(0.8)
- self.m_ocean.setDuration(6000)
- self.m_ocean.setFadeTime(900)
- self.m_ocean.setFadeIntensity(0.05)
- self.m_ocean.setPeriod(1500)
-
- self.m_btnRumble = HapticButton("Rumble!")
- self.m_btnOcean = HapticButton("Ocean")
- self.m_btnButtonClick = HapticButton("Click")
- self.m_btnNegativeEffect = HapticButton("Oops!")
- self.topLayout = QGridLayout(self)
- self.topLayout.addWidget(self.m_btnRumble, 0, 0)
- self.topLayout.addWidget(self.m_btnOcean, 0, 1)
- self.topLayout.addWidget(self.m_btnButtonClick, 1, 0)
- self.topLayout.addWidget(self.m_btnNegativeEffect, 1, 1)
-
- self.m_btnRumble.clicked.connect(self.playRumble)
- self.m_btnOcean.clicked.connect(self.playOcean)
- self.m_btnButtonClick.clicked.connect(self.playButtonClick)
- self.m_btnNegativeEffect.clicked.connect(self.playNegativeEffect)
-
- def __del__(self):
- del self.m_btnRumble
- del self.m_btnOcean
- del self.m_btnButtonClick
- del self.m_btnNegativeEffect
-
- def playRumble(self):
- self.m_rumble.start()
- print "Play rumble"
-
- def playOcean(self):
+class EffectPlayer(QObject):
+
+ def __init__(self, parent=None):
+ QObject.__init__(self, parent)
+
+ self.m_rumble = QFeedbackHapticsEffect()
+ self.m_rumble.setAttackIntensity(0.1)
+ self.m_rumble.setAttackTime(250)
+ self.m_rumble.setIntensity(1)
+ self.m_rumble.setDuration(1000)
+ self.m_rumble.setFadeTime(250)
+ self.m_rumble.setFadeIntensity(0.1)
+
+ self.m_ocean = QFeedbackHapticsEffect()
+ self.m_ocean.setAttackIntensity(0.1)
+ self.m_ocean.setAttackTime(450)
+ self.m_ocean.setIntensity(0.8)
+ self.m_ocean.setDuration(6000)
+ self.m_ocean.setFadeTime(900)
+ self.m_ocean.setFadeIntensity(0.05)
+ self.m_ocean.setPeriod(1500)
+
+ @Slot()
+ def playRumble(self):
+ print "Starting rumble effect"
+ self.m_rumble.start()
+
+ @Slot()
+ def playOcean(self):
if self.m_ocean.state() == QFeedbackEffect.Stopped:
self.m_ocean.start()
print "Ocean start"
@@ -108,20 +69,33 @@ class Dialog(QDialog):
self.m_ocean.stop()
print "Ocean stop"
- def playButtonClick(self):
- QFeedbackEffect.playThemeEffect(QFeedbackEffect.ThemeBasicButton)
- print "Play button click"
+ @Slot()
+ def playButtonClick(self):
+ QFeedbackEffect.playThemeEffect(QFeedbackEffect.ThemeBasicButton)
+ print "Play button click"
- def playNegativeEffect(self):
- QFeedbackEffect.playThemeEffect(QFeedbackEffect.ThemeNegativeTacticon)
- print "Play negative button click"
+ @Slot()
+ def playNegativeEffect(self):
+ QFeedbackEffect.playThemeEffect(QFeedbackEffect.ThemeNegativeTacticon)
+ print "Play negative button click"
def main():
- app = QApplication([])
- w = Dialog()
- w.showMaximized()
- return app.exec_()
+ app = QApplication([])
+ view = QDeclarativeView()
+ player = EffectPlayer()
+ context = view.rootContext()
+ context.setContextProperty("effectPlayer", player)
-if __name__ == "__main__":
+ url = QUrl('main.qml')
+ view.setSource(url)
+ view.showFullScreen()
+
+ app.exec_()
+
+
+if __name__ == '__main__':
main()
+
+
+
diff --git a/mobility/feedback/main.qml b/mobility/feedback/main.qml
new file mode 100644
index 0000000..dd3484d
--- /dev/null
+++ b/mobility/feedback/main.qml
@@ -0,0 +1,11 @@
+
+import QtQuick 1.1
+import com.nokia.meego 1.0
+
+PageStackWindow {
+
+ id: rootWindow
+ showStatusBar: false
+ initialPage: MainPage { }
+
+}
diff --git a/mobility/organizer/qml/OverviewPage.qml b/mobility/organizer/qml/OverviewPage.qml
new file mode 100644
index 0000000..4f4f4ed
--- /dev/null
+++ b/mobility/organizer/qml/OverviewPage.qml
@@ -0,0 +1,56 @@
+
+import QtQuick 1.1
+import com.nokia.meego 1.0
+import com.nokia.extras 1.1
+
+Page {
+ id: overviewPage
+ anchors.margins: UiConstants.DefaultMargin
+ orientationLock: PageOrientation.LockPortrait
+
+ Label {
+ anchors.centerIn: parent
+ text: "No tasks"
+ visible: manager.todos.length == 0
+ }
+
+ Flickable {
+ anchors.fill: parent
+ clip: true
+
+ flickableDirection: Flickable.VerticalFlick
+ contentHeight: todoButtons.height
+ contentWidth: todoButtons.width
+
+ ButtonColumn {
+ id: todoButtons
+
+ // On N9 it seems that displayWidth keeps pointing to the larger
+ // side of the screen, even in portrait mode...
+ width: screen.displayHeight - 2 * UiConstants.DefaultMargin
+
+ Repeater {
+ model: manager.todos
+ Button {
+ text: modelData
+ onClicked: {
+ manager.editExistingTodo(index)
+ pageStack.push(Qt.createComponent("TodoEdit.qml"))
+ }
+ }
+ }
+ }
+ }
+
+ tools: ToolBarLayout {
+ id: mainTools
+ ToolButton {
+ text: "Add Task"
+ onClicked: {
+ manager.editNewTodo() // Prepare new todo info
+ pageStack.push(Qt.createComponent("TodoEdit.qml"))
+ }
+ }
+ }
+
+}
diff --git a/mobility/organizer/qml/TodoEdit.qml b/mobility/organizer/qml/TodoEdit.qml
new file mode 100644
index 0000000..65c60d6
--- /dev/null
+++ b/mobility/organizer/qml/TodoEdit.qml
@@ -0,0 +1,239 @@
+
+import QtQuick 1.1
+import com.nokia.meego 1.0
+import com.nokia.extras 1.1
+
+Page {
+ id: editPage
+ anchors.margins: UiConstants.DefaultMargin
+ orientationLock: PageOrientation.LockPortrait
+
+ property int todoId: -1
+
+ Flickable {
+ anchors.fill: parent
+ contentHeight: editCol.height
+ flickableDirection: Flickable.VerticalFlick
+
+ Column {
+ id: editCol
+
+ width: parent.width
+ anchors.horizontalCenter: parent.horizontalCenter
+ spacing: 10
+
+ Label {
+ text: "Subject"
+ }
+
+ TextField {
+ id: subjectField
+ text: manager.todoSubject
+
+ Keys.onReturnPressed: {
+ parent.focus = true;
+ }
+ }
+
+ Label {
+ text: "Start Date"
+ }
+
+ Column {
+ spacing: 20
+ Button {
+ id: selectStartDateButton
+ text: manager.todoStartDateTime[1] + "/" + manager.todoStartDateTime[2] + "/" + manager.todoStartDateTime[0]
+
+ onClicked: {
+ startDateSelector.day = manager.todoStartDateTime[2];
+ startDateSelector.month = manager.todoStartDateTime[1];
+ startDateSelector.year = manager.todoStartDateTime[0];
+ startDateSelector.open()
+ }
+
+ DatePickerDialog {
+ id: startDateSelector
+
+ onAccepted: {
+ manager.setTodoStartDate(year, month, day)
+ }
+ }
+ }
+
+ Button {
+ id: selectStartTimeButton
+ text: manager.todoStartDateTime[3]+ ":" + manager.todoStartDateTime[4]
+
+ onClicked: {
+ startTimeSelector.hour = manager.todoStartDateTime[3];
+ startTimeSelector.minute = manager.todoStartDateTime[4];
+ startTimeSelector.open()
+ }
+
+ TimePickerDialog {
+ id: startTimeSelector
+ fields: DateTime.Hours | DateTime.Minutes
+ acceptButtonText: "Confirm"
+ rejectButtonText: "Cancel"
+
+ onAccepted: {
+ manager.setTodoStartTime(hour, minute)
+ }
+
+ }
+ }
+
+ }
+
+ Label {
+ text: "Due Date"
+ }
+
+ Column {
+ spacing: 20
+ Button {
+ id: selectDueDateButton
+ text: manager.todoDueDateTime[1] + "/" + manager.todoDueDateTime[2] + "/" + manager.todoDueDateTime[0]
+
+ onClicked: {
+ dueDateSelector.day = manager.todoDueDateTime[2];
+ dueDateSelector.month = manager.todoDueDateTime[1];
+ dueDateSelector.year = manager.todoDueDateTime[0];
+ dueDateSelector.open()
+ }
+
+ DatePickerDialog {
+ id: dueDateSelector
+
+ onAccepted: {
+ manager.setTodoDueDate(year, month, day)
+ }
+ }
+ }
+
+ Button {
+ id: selectDueTimeButton
+ text: manager.todoDueDateTime[3]+ ":" + manager.todoDueDateTime[4]
+
+ onClicked: {
+ dueTimeSelector.hour = manager.todoDueDateTime[3];
+ dueTimeSelector.minute = manager.todoDueDateTime[4];
+ dueTimeSelector.open()
+ }
+
+ TimePickerDialog {
+ id: dueTimeSelector
+ fields: DateTime.Hours | DateTime.Minutes
+ acceptButtonText: "Confirm"
+ rejectButtonText: "Cancel"
+
+ onAccepted: {
+ manager.setTodoDueTime(hour, minute)
+ }
+ }
+ }
+
+ }
+
+ Label {
+ text: "Status"
+ }
+
+ Button {
+ id: statusButton
+ text: statusSelection.model.get(statusSelection.selectedIndex).name
+
+ onClicked: {
+ statusSelection.open();
+ }
+
+
+ SelectionDialog {
+ id: statusSelection
+ titleText: "Select status"
+ selectedIndex: manager.todoStatus
+
+ model: ListModel {
+ ListElement { name: "Not started" }
+ ListElement { name: "In progress" }
+ ListElement { name: "Complete" }
+ }
+
+ onAccepted: {
+ manager.todoStatus = statusSelection.selectedIndex;
+ }
+ }
+ }
+
+ Label {
+ text: "Priority"
+ }
+
+ Button {
+ id: priorityButton
+ text: prioritySelection.model.get(prioritySelection.selectedIndex).name
+
+ onClicked: {
+ prioritySelection.open();
+ }
+
+
+ SelectionDialog {
+ id: prioritySelection
+ titleText: "Select priority"
+ selectedIndex: manager.todoPriority
+
+ model: ListModel {
+ ListElement { name: "Unknown" }
+ ListElement { name: "Highest" }
+ ListElement { name: "Extremely high" }
+ ListElement { name: "Very high" }
+ ListElement { name: "High" }
+ ListElement { name: "Medium" }
+ ListElement { name: "Low" }
+ ListElement { name: "Very low" }
+ ListElement { name: "Extremely low" }
+ ListElement { name: "Lowest" }
+ }
+
+ onAccepted: {
+ manager.todoPriority = prioritySelection.selectedIndex;
+ }
+ }
+ }
+ }
+ }
+
+ tools: ToolBarLayout {
+ id: editTools
+ ToolButton {
+ text: "Save"
+ onClicked: {
+ console.log("Saving new task")
+ manager.todoSubject = subjectField.text; // Other fields are handled by dialog.accept signal
+ manager.saveTodo();
+ pageStack.pop();
+ }
+ }
+ ToolButton {
+ text: "Delete"
+ enabled: !manager.isNewTodo
+ onClicked: {
+ console.log("Deleting todo.");
+ manager.deleteCurrent();
+ pageStack.pop();
+ }
+ }
+ ToolButton {
+ text: "Cancel"
+ onClicked: {
+ console.log("Cancel task edit");
+ console.log("Is new todo?" + manager.isNewTodo);
+ manager.reload();
+ pageStack.pop();
+ }
+ }
+ }
+
+}
diff --git a/mobility/organizer/qml/main.qml b/mobility/organizer/qml/main.qml
new file mode 100644
index 0000000..88c1b95
--- /dev/null
+++ b/mobility/organizer/qml/main.qml
@@ -0,0 +1,10 @@
+
+import QtQuick 1.1
+import com.nokia.meego 1.0
+
+PageStackWindow {
+
+ id: rootWindow
+ showStatusBar: false
+ initialPage: OverviewPage { }
+}
diff --git a/mobility/organizer/qml/qmltodo.py b/mobility/organizer/qml/qmltodo.py
new file mode 100644
index 0000000..a3523f2
--- /dev/null
+++ b/mobility/organizer/qml/qmltodo.py
@@ -0,0 +1,274 @@
+'''
+ Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ All rights reserved.
+ Contact: Nokia Corporation (qt-info@nokia.com)
+
+ This file is part of the Qt Mobility Components.
+
+ $QT_BEGIN_LICENSE:LGPL$
+ No Commercial Usage
+ This file contains pre-release code and may not be distributed.
+ You may use this file in accordance with the terms and conditions
+ contained in the Technology Preview License Agreement accompanying
+ this package.
+
+ GNU Lesser General Public License Usage
+ Alternatively, this file may be used under the terms of the GNU Lesser
+ General Public License version 2.1 as published by the Free Software
+ Foundation and appearing in the file LICENSE.LGPL included in the
+ packaging of this file. Please review the following information to
+ ensure the GNU Lesser General Public License version 2.1 requirements
+ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+
+ In addition, as a special exception, Nokia gives you certain additional
+ rights. These rights are described in the Nokia Qt LGPL Exception
+ version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+
+ If you have questions regarding the use of this file, please contact
+ Nokia at qt-info@nokia.com.
+'''
+
+import os
+import sys
+
+from PySide.QtCore import QObject, Signal, Slot, Property, QUrl, qWarning
+from PySide.QtCore import QAbstractItemModel, QDate, QDateTime, QTime
+from PySide.QtGui import QApplication
+from PySide.QtDeclarative import QDeclarativeView
+from QtMobility.Organizer import QOrganizerManager, QOrganizerItemSortOrder
+from QtMobility.Organizer import QOrganizerTodo, QOrganizerTodoTime
+from QtMobility.Organizer import QOrganizerItemFilter, QOrganizerItemDetailFilter
+from QtMobility.Organizer import QOrganizerItemPriority, QOrganizerTodoProgress
+from QtMobility.Organizer import QOrganizerItemType
+
+
+class TodoManager(QObject):
+
+ def __init__(self):
+ QObject.__init__(self)
+
+ self.manager = QOrganizerManager("memory")
+ self._todos = [] # FIXME Use a model instead of a string list as model
+ self._todo = None # Current todo being edited or created
+
+ self.reload()
+
+ @Slot()
+ def reload(self):
+ self._todos = []
+
+ sortOrder = QOrganizerItemSortOrder()
+ sortOrder.setDetailDefinitionName(QOrganizerTodoTime.DefinitionName,
+ QOrganizerTodoTime.FieldDueDateTime)
+
+ todoFilter = QOrganizerItemFilter()
+
+ items = self.manager.items(todoFilter, [sortOrder])
+
+ todos = []
+ for item in items:
+ if item.type() == QOrganizerItemType.TypeTodo:
+ todo = QOrganizerTodo(item)
+
+ display = todo.startDateTime().toString("yy/MM/dd hh:mm") +\
+ "-" + todo.dueDateTime().toString("yy/MM/dd hh:mm") +\
+ "\n" + todo.displayLabel()
+
+ todos.append((display, todo))
+
+ self._todos = todos
+ self.todosChanged.emit()
+
+ @Slot()
+ def deleteCurrent(self):
+ self.manager.removeItem(self._todo.id())
+ self.reload()
+
+ currentTodoChanged = Signal()
+
+ @Slot()
+ def editNewTodo(self):
+ """Sets the current todo to a newly created todo"""
+ newTodo = QOrganizerTodo()
+ newTodo.setPriority(QOrganizerItemPriority.HighPriority)
+ newTodo.setStatus(QOrganizerTodoProgress.StatusNotStarted)
+ currentDateTime = QDateTime(QDate.currentDate(), QTime.currentTime())
+ newTodo.setStartDateTime(currentDateTime)
+ newTodo.setDueDateTime(currentDateTime.addSecs(60*60))
+
+ self._todo = newTodo
+ self._todo.isNewTodo = True
+ self.currentTodoChanged.emit()
+
+ @Property(bool, notify=currentTodoChanged)
+ def isNewTodo(self):
+ return self._todo.isNewTodo if self._todo else True
+
+ @Slot(int)
+ def editExistingTodo(self, index):
+ self._todo = self._todos[index][1]
+ self._todo.isNewTodo = False
+ self.currentTodoChanged.emit()
+
+ @Slot()
+ def saveTodo(self):
+ self.manager.saveItem(self._todo)
+ self._todo = None
+ self.reload()
+
+ todosChanged = Signal()
+ @Property("QStringList", notify=todosChanged)
+ def todos(self):
+ return [x[0] for x in self._todos]
+
+ @todos.setter
+ def setTodo(self, value):
+ self._todos = value
+ self.todosChanged.emit()
+
+ # Subject
+ currentTodoSubjectChanged = Signal()
+
+ @Property(str, notify=currentTodoSubjectChanged)
+ def todoSubject(self):
+ return self._todo.displayLabel()
+
+ @todoSubject.setter
+ def setTodoSubject(self, value):
+ self._todo.setDisplayLabel(value)
+ self.currentTodoSubjectChanged.emit()
+
+ # Dates and times
+ def datetimeToStrList(self, datetime):
+ date = datetime.date()
+ time = datetime.time()
+ return (("%02d "*5) % (date.year(), date.month(), date.day(),
+ time.hour(), time.minute())).split()
+
+# @Slot(result="QStringList")
+ @Property("QStringList", notify=currentTodoChanged)
+ def todoStartDateTime(self):
+ return self.datetimeToStrList(self._todo.startDateTime())
+
+ @Slot(int, int, int)
+ def setTodoStartDate(self, year, month, day):
+ orig_time = self._todo.startDateTime().time()
+ date = QDate(year, month, day)
+ datetime = QDateTime(date, orig_time)
+
+ self._todo.setStartDateTime(datetime)
+ self.currentTodoChanged.emit()
+
+ @Slot(int, int)
+ def setTodoStartTime(self, hour, minute):
+ orig_date = self._todo.startDateTime().date()
+ time = QTime(hour, minute)
+ datetime = QDateTime(orig_date, time)
+
+ self._todo.setStartDateTime(datetime)
+ self.currentTodoChanged.emit()
+
+ @Property("QStringList", notify=currentTodoChanged)
+ def todoDueDateTime(self):
+ return self.datetimeToStrList(self._todo.dueDateTime())
+
+ @Slot(int, int, int)
+ def setTodoDueDate(self, year, month, day):
+ orig_time = self._todo.dueDateTime().time()
+ date = QDate(year, month, day)
+ datetime = QDateTime(date, orig_time)
+
+ self._todo.setDueDateTime(datetime)
+
+ self.currentTodoChanged.emit()
+
+ @Slot(int, int)
+ def setTodoDueTime(self, hour, minute):
+ orig_date = self._todo.dueDateTime().date()
+ time = QTime(hour, minute)
+ datetime = QDateTime(orig_date, time)
+
+ self._todo.setDueDateTime(datetime)
+
+ self.currentTodoChanged.emit()
+
+ # Status
+
+ Status = [
+ QOrganizerTodoProgress.StatusNotStarted,
+ QOrganizerTodoProgress.StatusInProgress,
+ QOrganizerTodoProgress.StatusComplete,
+ ]
+
+ @Property(int, notify=currentTodoChanged)
+ def todoStatus(self):
+ status = self._todo.status()
+ try:
+ index = self.Status.index(status)
+ return index
+ except ValueError:
+ return 0
+
+ @todoStatus.setter
+ def setTodoStatus(self, value):
+ try:
+ self._todo.setStatus(self.Status[value])
+ self.currentTodoChanged.emit()
+ except IndexError:
+ pass # Fail silently...
+
+ # Priority
+
+ Priority = [
+ QOrganizerItemPriority.UnknownPriority,
+ QOrganizerItemPriority.HighestPriority,
+ QOrganizerItemPriority.ExtremelyHighPriority,
+ QOrganizerItemPriority.VeryHighPriority,
+ QOrganizerItemPriority.HighPriority,
+ QOrganizerItemPriority.MediumPriority,
+ QOrganizerItemPriority.LowPriority,
+ QOrganizerItemPriority.VeryLowPriority,
+ QOrganizerItemPriority.ExtremelyLowPriority,
+ QOrganizerItemPriority.LowestPriority,
+ ]
+
+ @Property(int, notify=currentTodoChanged)
+ def todoPriority(self):
+ priority = self._todo.priority()
+ try:
+ index = self.Priority.index(priority)
+ return index
+ except ValueError:
+ return 0
+
+ @todoPriority.setter
+ def setTodoPriority(self, value):
+ try:
+ self._todo.setPriority(self.Priority[value])
+ self.currentTodoChanged.emit()
+ except IndexError:
+ pass # Fail silently...
+
+
+def main():
+ app = QApplication([])
+ view = QDeclarativeView()
+ manager = TodoManager()
+ context = view.rootContext()
+ context.setContextProperty("manager", manager)
+
+ url = QUrl('main.qml')
+ view.setSource(url)
+
+ if "-no-fs" not in sys.argv:
+ view.showFullScreen()
+ else:
+ view.show()
+
+ app.exec_()
+
+
+if __name__ == '__main__':
+ main()
+
+
diff --git a/mobility/samplephonebook/qml/ContactEdit.qml b/mobility/samplephonebook/qml/ContactEdit.qml
new file mode 100644
index 0000000..295f32b
--- /dev/null
+++ b/mobility/samplephonebook/qml/ContactEdit.qml
@@ -0,0 +1,116 @@
+
+import QtQuick 1.1
+import com.nokia.meego 1.0
+
+Page {
+ id: contactEdit
+ anchors.margins: UiConstants.DefaultMargin
+ orientationLock: PageOrientation.LockPortrait
+
+
+ Flickable {
+ anchors.fill: parent
+ contentHeight: textFields.height
+ Column {
+ id: textFields
+ anchors.fill: parent
+ Label {
+ text: "Name"
+ }
+ TextField {
+ id: fieldName
+ anchors.left: parent.left
+ anchors.right: parent.right
+ text: manager.contactData[0]
+ }
+ Label {
+ text: "Phone"
+ }
+ TextField {
+ id: fieldPhone
+ text: manager.contactData[1]
+ anchors.left: parent.left
+ anchors.right: parent.right
+ }
+ Label {
+ text: "Email"
+ }
+ TextField {
+ id: fieldEmail
+ text: (manager.emailEnabled ? manager.contactData[2] : "<not supported>")
+ readOnly: !manager.emailEnabled
+ anchors.left: parent.left
+ anchors.right: parent.right
+ }
+ Label {
+ text: "Address"
+ }
+ TextField {
+ id: fieldAddress
+ text: (manager.addressEnabled ? manager.contactData[3] : "<not supported>")
+ readOnly: !manager.addressEnabled
+ anchors.left: parent.left
+ anchors.right: parent.right
+ }
+
+ }
+ }
+ Dialog {
+ id: errorDialog
+ visualParent: contactEdit
+ title: Item {
+ id: titleField
+ height: errorDialog.platformStyle.titleBarHeight
+ width: parent.width
+ Label {
+ id: titleLabel
+ anchors.verticalCenter: titleField.verticalCenter
+ font.capitalization: Font.MixedCase
+ color: "white"
+ text: "Error"
+ }
+ }
+ content:Item {
+ id: name
+ height: childrenRect.height
+ Text {
+ id: text
+ font.pixelSize: 22
+ color: "white"
+ text: manager.errorMessage
+ }
+ }
+ buttons: ButtonRow {
+ platformStyle: ButtonStyle { }
+ anchors.horizontalCenter: parent.horizontalCenter
+ Button {id: b1; text: "Edit fields"; onClicked: errorDialog.accept()}
+ Button {id: b2; text: "Cancel entry"; onClicked: errorDialog.reject()}
+ }
+ }
+
+ tools: ToolBarLayout {
+ id: mainTools
+ ToolButton {
+ text: "Save"
+ onClicked: {
+ console.log("Save contact");
+ if (!manager.saveContact(fieldName.text, fieldPhone.text, fieldEmail.text, fieldAddress.text)) {
+ errorDialog.open();
+ } else {
+ manager.selectContact(-1);
+ pageStack.pop();
+ }
+ }
+ }
+ ToolButton {
+ text: "Cancel"
+ onClicked: {
+ console.log("Cancel edit/add")
+ manager.selectContact(-1)
+ pageStack.pop()
+ }
+ }
+ }
+
+
+}
diff --git a/mobility/samplephonebook/qml/MainPage.qml b/mobility/samplephonebook/qml/MainPage.qml
new file mode 100644
index 0000000..bbbef5b
--- /dev/null
+++ b/mobility/samplephonebook/qml/MainPage.qml
@@ -0,0 +1,47 @@
+
+
+import QtQuick 1.1
+import com.nokia.meego 1.0
+import com.nokia.extras 1.1
+
+Page {
+ id: mainPage
+ anchors.margins: UiConstants.DefaultMargin
+ orientationLock: PageOrientation.LockPortrait
+
+ Flickable {
+ anchors.fill: parent
+
+ ButtonColumn {
+ Repeater {
+ model: manager.contactsNames
+ Button {
+ text: modelData
+ onClicked: {
+ console.log("Editing existing contact")
+ manager.selectContact(index)
+ pageStack.push(Qt.createComponent("ContactEdit.qml"))
+ }
+ }
+ }
+ }
+ }
+
+ tools: ToolBarLayout {
+ id: mainTools
+ ToolButton {
+ text: "Add..."
+ onClicked: {
+ console.log("Add new contact")
+ pageStack.push(Qt.createComponent("ContactEdit.qml"))
+ }
+ }
+ ToolButton {
+ text: "Select backend..."
+ onClicked: {
+ pageStack.push(Qt.createComponent("SelectBackend.qml"))
+ }
+ }
+ }
+
+}
diff --git a/mobility/samplephonebook/qml/SelectBackend.qml b/mobility/samplephonebook/qml/SelectBackend.qml
new file mode 100644
index 0000000..ec927e8
--- /dev/null
+++ b/mobility/samplephonebook/qml/SelectBackend.qml
@@ -0,0 +1,41 @@
+
+import QtQuick 1.1
+import com.nokia.meego 1.0
+
+Page {
+ id: selectBackend
+ anchors.margins: UiConstants.DefaultMargin
+ orientationLock: PageOrientation.LockPortrait
+
+
+ ListView {
+ anchors.fill: parent
+ anchors.centerIn: parent
+ model: manager.availableManagers
+ delegate: Button {
+ text: modelData
+ onClicked: {
+ manager.selectManager(modelData)
+ pageStack.pop()
+ }
+ }
+ }
+
+ tools: ToolBarLayout {
+ id: mainTools
+ ToolButton {
+ text: "Select"
+ onClicked: {
+ console.log("Selected new backend")
+ pageStack.pop()
+ }
+ }
+ ToolButton {
+ text: "Cancel"
+ onClicked: {
+ console.log("Cancel edit/add")
+ pageStack.pop()
+ }
+ }
+ }
+}
diff --git a/mobility/samplephonebook/qml/main.qml b/mobility/samplephonebook/qml/main.qml
new file mode 100644
index 0000000..49eb008
--- /dev/null
+++ b/mobility/samplephonebook/qml/main.qml
@@ -0,0 +1,10 @@
+
+import QtQuick 1.1
+import com.nokia.meego 1.0
+
+PageStackWindow {
+
+ id: rootWindow
+ showStatusBar: false
+ initialPage: MainPage { }
+}
diff --git a/mobility/samplephonebook/qml/qmlsamplephonebook.py b/mobility/samplephonebook/qml/qmlsamplephonebook.py
new file mode 100644
index 0000000..796c15b
--- /dev/null
+++ b/mobility/samplephonebook/qml/qmlsamplephonebook.py
@@ -0,0 +1,274 @@
+'''
+ Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ All rights reserved.
+ Contact: Nokia Corporation (qt-info@nokia.com)
+
+ This file is part of the Qt Mobility Components.
+
+ $QT_BEGIN_LICENSE:LGPL$
+ No Commercial Usage
+ This file contains pre-release code and may not be distributed.
+ You may use this file in accordance with the terms and conditions
+ contained in the Technology Preview License Agreement accompanying
+ this package.
+
+ GNU Lesser General Public License Usage
+ Alternatively, this file may be used under the terms of the GNU Lesser
+ General Public License version 2.1 as published by the Free Software
+ Foundation and appearing in the file LICENSE.LGPL included in the
+ packaging of this file. Please review the following information to
+ ensure the GNU Lesser General Public License version 2.1 requirements
+ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+
+ In addition, as a special exception, Nokia gives you certain additional
+ rights. These rights are described in the Nokia Qt LGPL Exception
+ version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+
+ If you have questions regarding the use of this file, please contact
+ Nokia at qt-info@nokia.com.
+'''
+
+import os
+import sys
+
+from PySide.QtCore import QObject, Signal, Slot, Property, QUrl, qWarning
+from PySide.QtGui import QApplication
+from PySide.QtDeclarative import QDeclarativeView
+from QtMobility.Contacts import QContactManager, QContactPhoneNumber, QContact
+from QtMobility.Contacts import QContactAddress, QContactEmailAddress, QContactType
+from QtMobility.Contacts import QContactName
+
+
+class MyContactManager(QObject):
+
+ def __init__(self):
+ QObject.__init__(self)
+
+ self._availableManagers = {}
+ self._contacts = []
+
+ self.initialisedManagers = {}
+ self.manager = None
+ self.contactId = 0
+
+ self._errorMessage = ""
+ self._emailEnabled = False
+ self._addressEnabled = True
+
+ availableMgrs = QContactManager.availableManagers()
+ availableMgrs.remove("invalid")
+ for managerName in availableMgrs:
+ params = {}
+ managerUri = QContactManager.buildUri(managerName, params)
+ self._availableManagers[managerName] = managerUri
+
+ self.selectManager(self.availableManagers[0])
+
+ # Email Enabled property
+ onErrorMessageChanged = Signal()
+
+ @Property(str, notify=onErrorMessageChanged)
+ def errorMessage(self):
+ return self._errorMessage
+
+ @errorMessage.setter
+ def setErrorMessage(self, value):
+ self._errorMessage = value
+ self.onErrorMessageChanged.emit()
+
+ # Email Enabled property
+ onEmailEnabledChanged = Signal()
+
+ @Property("bool", notify=onEmailEnabledChanged)
+ def emailEnabled(self):
+ return self._emailEnabled
+
+ @emailEnabled.setter
+ def setEmailEnabled(self, value):
+ self._emailEnabled = value
+ self.onEmailEnabledChanged.emit()
+
+ # Address Enabled property
+ onAddressEnabledChanged = Signal()
+
+ @Property("bool", notify=onAddressEnabledChanged)
+ def addressEnabled(self):
+ return self._addressEnabled
+
+ @addressEnabled.setter
+ def setAddressEnabled(self, value):
+ self._addressEnabled = value
+ self.onAddressEnabledChanged.emit()
+
+ @Property("QStringList", constant=True)
+ def availableManagers(self):
+ return self._availableManagers.keys()
+
+ # List of contacts changed property
+ onContactsChanged = Signal()
+
+ @Property("QStringList", notify=onContactsChanged)
+ def contactsNames(self):
+ return [x[0] for x in self._contacts]
+
+ onSelectedContactChanged = Signal()
+
+ def emitContactsChanged(self):
+ self.onContactsChanged.emit()
+
+ @Property("QStringList", notify=onSelectedContactChanged)
+ def contactData(self):
+ if not self.contactId:
+ print "Trying to get data while no contact selected..."
+ return ["", "", "", ""]
+
+ print "Getting existing contact data"
+
+ contact = self.manager.contact(self.contactId)
+
+ name = self.manager.synthesizedContactDisplayLabel(contact)
+ phone = contact.detail(QContactPhoneNumber.DefinitionName).value(QContactPhoneNumber.FieldNumber)
+
+ if self.emailEnabled:
+ emailObj = contact.detail(QContactEmailAddress.DefinitionName)
+ email = emailObj.value(QContactEmailAddress.FieldEmailAddress)
+ else:
+ email = ""
+
+ if self.addressEnabled:
+ addressObj = contact.detail(QContactAddress.DefinitionName)
+ address = addressObj.value(QContactAddress.FieldStreet)
+ else:
+ address = ""
+
+ return name, phone, email, address
+
+ @Slot(int)
+ def selectContact(self, idx):
+ if idx == -1:
+ self.contactId = 0
+ else:
+ self.contactId = self._contacts[idx][1]
+
+ @Slot(str)
+ def selectManager(self, name):
+ managerUri = self._availableManagers[name]
+
+ # first, check to see if they reselected the same backend.
+ if self.manager and self.manager.managerUri() == managerUri:
+ return
+
+ # the change is real. update.
+ if self.initialisedManagers.has_key(managerUri):
+ self.manager = self.initialisedManagers[managerUri]
+ else:
+ self.manager = QContactManager.fromUri(managerUri)
+ if self.manager.error():
+ print "Failed to open store...."
+ del self.manager
+ self.manager = None
+ return
+ self.initialisedManagers[managerUri] = self.manager
+
+ defs = self.manager.detailDefinitions(QContactType.TypeContact)
+
+ self.emailEnabled = bool(defs["EmailAddress"])
+ self.addressEnabled = bool(defs["Address"])
+
+ self.updateContactList()
+
+ def updateContactList(self):
+ self._contacts = []
+
+ for contact in self.manager.contacts():
+ name = self.manager.synthesizedContactDisplayLabel(contact)
+ self._contacts.append((name, contact.localId()))
+ self.emitContactsChanged()
+
+ saveEmptyName = Signal()
+
+ @Slot(str, str, str, str, result=bool)
+ def saveContact(self, name, phone, email, address):
+ if not self.manager:
+ qWarning("No manager selected, cannot save")
+ return
+
+ if self.contactId:
+ print "Updating existing contact"
+ contact = self.manager.contact(self.contactId)
+ else:
+ print "Creating new contact"
+ contact = QContact()
+
+ if not name:
+ self.errorMessage = "Name must not be empty!"
+ return False
+
+ # Name
+ if name != self.manager.synthesizedContactDisplayLabel(contact):
+ saveNameField = self.nameField()
+ if saveNameField:
+ nm = QContactName(contact.detail(QContactName().DefinitionName))
+ nm.setValue(saveNameField, name)
+ contact.saveDetail(nm)
+
+ # Phone
+ phoneObj = QContactPhoneNumber(contact.detail(QContactPhoneNumber.DefinitionName))
+ phoneObj.setNumber(phone)
+ contact.saveDetail(phoneObj)
+
+ # Email
+ if self.emailEnabled:
+ emailObj = QContactEmailAddress(contact.detail(QContactEmailAddress.DefinitionName))
+ emailObj.setEmailAddress(email)
+ contact.saveDetail(emailObj)
+
+ # Address
+ if self.addressEnabled:
+ addressObj = QContactAddress(contact.detail(QContactAddress.DefinitionName))
+ addressObj.setStreet(address)
+ contact.saveDetail(addressObj)
+
+ contact = self.manager.compatibleContact(contact)
+ success = self.manager.saveContact(contact)
+ if not success:
+ qWarning("Failed to save contact")
+
+ self.updateContactList()
+
+ return True
+
+
+ def nameField(self):
+ # return the field which the name data should be saved in.
+ if not self.manager:
+ return ""
+
+ defs = self.manager.detailDefinitions(QContactType.TypeContact)
+ nameDef = defs[QContactName.DefinitionName]
+ if QContactName.FieldCustomLabel in nameDef.fields():
+ return QContactName.FieldCustomLabel
+ elif QContactName.FieldFirstName in nameDef.fields():
+ return QContactName.FieldFirstName
+ else:
+ return ""
+
+def main():
+ app = QApplication([])
+ view = QDeclarativeView()
+ manager = MyContactManager()
+ context = view.rootContext()
+ context.setContextProperty("manager", manager)
+
+ url = QUrl('main.qml')
+ view.setSource(url)
+ view.showFullScreen()
+
+ app.exec_()
+
+
+if __name__ == '__main__':
+ main()
+
+
+
diff --git a/mobility/servicebrowser/qml/HoldButton.qml b/mobility/servicebrowser/qml/HoldButton.qml
new file mode 100644
index 0000000..32ce02e
--- /dev/null
+++ b/mobility/servicebrowser/qml/HoldButton.qml
@@ -0,0 +1,45 @@
+
+import QtQuick 1.1
+import com.nokia.meego 1.0
+
+Button {
+ text: ""
+
+ property int holdTime: 800 // Hold time in msecs
+
+ signal held
+ signal clickedWithoutHold // Replace the original clicked signal, which keeps being emitted.
+
+ onPressedChanged: {
+ if (pressed) {
+ // Start counting
+ holdTimer.wasTriggered = false;
+ holdTimer.start();
+ } else {
+ // Just stop the timer
+ holdTimer.restart();
+ holdTimer.stop();
+ }
+
+ if (!pressed && !holdTimer.wasTriggered) {
+ // Replaces the clicked signal
+ clickedWithoutHold();
+ holdTimer.restart();
+ holdTimer.stop();
+ }
+ }
+
+ Timer {
+ property bool wasTriggered: false
+ id: holdTimer
+ interval: holdTime
+ running: false
+ repeat: false
+ onTriggered: {
+ wasTriggered = true
+ held();
+ restart();
+ stop();
+ }
+ }
+}
diff --git a/mobility/servicebrowser/qml/ImplementationDetails.qml b/mobility/servicebrowser/qml/ImplementationDetails.qml
new file mode 100644
index 0000000..bfbf139
--- /dev/null
+++ b/mobility/servicebrowser/qml/ImplementationDetails.qml
@@ -0,0 +1,60 @@
+
+import QtQuick 1.1
+import com.nokia.meego 1.0
+import com.nokia.extras 1.1
+
+Page {
+
+ property string implementationSpec: ""
+ property int implementationIndex: -1
+ property string serviceName: ""
+ property int serviceIndex: -1
+
+ id: implementationDetails
+ anchors.margins: UiConstants.DefaultMargin
+ //orientationLock: PageOrientation.LockPortrait
+
+ Label {
+ id: titleLabel
+ anchors.top: parent.top
+ width: parent.width
+ anchors.horizontalCenter: parent.horizontalCenter
+ text: "Implementation: " + implementationSpec
+ }
+
+ Flickable {
+ anchors.top: titleLabel.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ width: parent.width
+ contentHeight: servicesButtons.height
+
+ ButtonColumn {
+ id: servicesButtons
+ width: parent.width
+ anchors.horizontalCenter: parent.horizontalCenter
+ Repeater {
+ model: manager.implementationDetails(implementationSpec, implementationIndex,
+ serviceName, serviceIndex);
+ Button {
+ width: parent.width
+ text: modelData
+ onClicked: {
+ console.log("Selecting service")
+ //manager.selectService(index)
+ }
+ }
+ }
+ }
+ }
+
+ tools: ToolBarLayout {
+ id: implementationPageTools
+ ToolButton {
+ text: "Back"
+ onClicked: {
+ pageStack.pop();
+ }
+ }
+ }
+
+}
diff --git a/mobility/servicebrowser/qml/ServiceImplementations.qml b/mobility/servicebrowser/qml/ServiceImplementations.qml
new file mode 100644
index 0000000..28791cc
--- /dev/null
+++ b/mobility/servicebrowser/qml/ServiceImplementations.qml
@@ -0,0 +1,93 @@
+
+import QtQuick 1.1
+import com.nokia.meego 1.0
+import com.nokia.extras 1.1
+
+Page {
+
+ property string serviceName: ""
+ property int serviceIndex: -1
+
+ id: serviceImplementations
+ anchors.margins: UiConstants.DefaultMargin
+ //orientationLock: PageOrientation.LockPortrait
+
+ Label {
+ id: titleLabel
+ anchors.top: parent.top
+ anchors.horizontalCenter: parent.horizontalCenter
+ text: "Service: " + serviceName
+ }
+
+ Flickable {
+ anchors.top: titleLabel.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ width: parent.width
+ contentHeight: servicesButtons.height
+
+ ButtonColumn {
+ id: servicesButtons
+ width: parent.width
+ anchors.horizontalCenter: parent.horizontalCenter
+ Repeater {
+ id: buttonRepeater
+ model: manager.serviceImplementations(serviceName, serviceIndex)
+
+ HoldButton {
+ text: modelData
+ // TODO Getting some "Unable to assing undefined value" at this line when
+ // setting model to a different list (line 73), but the example is working
+ // so far.
+ width: parent.width
+
+ onHeld: {
+ setDefaultDialog.titleText = "Change default implementation";
+ setDefaultDialog.message = "Set " + modelData + " as default?";
+ setDefaultDialog.index = index;
+ setDefaultDialog.open();
+ }
+
+ onClickedWithoutHold: {
+ pageStack.push(Qt.createComponent("ImplementationDetails.qml"),
+ { implementationSpec: modelData,
+ implementationIndex: index,
+ serviceName: serviceName,
+ serviceIndex: serviceIndex
+ });
+
+ }
+ }
+ }
+ }
+ }
+
+ QueryDialog {
+ property int index: -1
+
+ id: setDefaultDialog
+ acceptButtonText: "Yes"
+ rejectButtonText: "No"
+
+ onAccepted: {
+ console.log("Accepted");
+ manager.setDefault(index);
+ buttonRepeater.model = manager.serviceImplementations(serviceName, serviceIndex)
+ }
+
+ onRejected: {
+ console.log("Rejected");
+ }
+
+ }
+
+ tools: ToolBarLayout {
+ id: implementationPageTools
+ ToolButton {
+ text: "Back"
+ onClicked: {
+ pageStack.pop();
+ }
+ }
+ }
+
+}
diff --git a/mobility/servicebrowser/qml/ServicesPage.qml b/mobility/servicebrowser/qml/ServicesPage.qml
new file mode 100644
index 0000000..4bcf85c
--- /dev/null
+++ b/mobility/servicebrowser/qml/ServicesPage.qml
@@ -0,0 +1,61 @@
+
+
+import QtQuick 1.1
+import com.nokia.meego 1.0
+import com.nokia.extras 1.1
+
+Page {
+ id: servicePage
+ anchors.margins: UiConstants.DefaultMargin
+ //orientationLock: PageOrientation.LockPortrait
+
+ Label {
+ id: titleLabel
+ anchors.top: parent.top
+ anchors.horizontalCenter: parent.horizontalCenter
+ text: "Services available"
+ }
+
+ Flickable {
+ anchors.top: titleLabel.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ width: parent.width
+ contentHeight: servicesButtons.height
+
+ ButtonColumn {
+ id: servicesButtons
+ width: parent.width
+ anchors.horizontalCenter: parent.horizontalCenter
+ Repeater {
+ model: manager.servicesNames
+ Button {
+ text: modelData
+ onClicked: {
+ console.log("Selecting service")
+ pageStack.push(Qt.createComponent("ServiceImplementations.qml"),
+ { serviceName: modelData,
+ serviceIndex: index })
+ }
+ }
+ }
+ }
+ }
+
+ /*tools: ToolBarLayout {
+ id: mainTools
+ ToolButton {
+ text: "Add..."
+ onClicked: {
+ console.log("Add new contact")
+ pageStack.push(Qt.createComponent("ContactEdit.qml"))
+ }
+ }
+ ToolButton {
+ text: "Select backend..."
+ onClicked: {
+ pageStack.push(Qt.createComponent("SelectBackend.qml"))
+ }
+ }
+ }*/
+
+}
diff --git a/mobility/servicebrowser/qml/main.qml b/mobility/servicebrowser/qml/main.qml
new file mode 100644
index 0000000..ee8dfe8
--- /dev/null
+++ b/mobility/servicebrowser/qml/main.qml
@@ -0,0 +1,10 @@
+
+import QtQuick 1.1
+import com.nokia.meego 1.0
+
+PageStackWindow {
+
+ id: rootWindow
+ showStatusBar: false
+ initialPage: ServicesPage { }
+}
diff --git a/mobility/servicebrowser/qml/qmlbrowser.py b/mobility/servicebrowser/qml/qmlbrowser.py
new file mode 100644
index 0000000..4ac9b51
--- /dev/null
+++ b/mobility/servicebrowser/qml/qmlbrowser.py
@@ -0,0 +1,134 @@
+'''
+ Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ All rights reserved.
+ Contact: Nokia Corporation (qt-info@nokia.com)
+
+ This file is part of the Qt Mobility Components.
+
+ $QT_BEGIN_LICENSE:LGPL$
+ No Commercial Usage
+ This file contains pre-release code and may not be distributed.
+ You may use this file in accordance with the terms and conditions
+ contained in the Technology Preview License Agreement accompanying
+ this package.
+
+ GNU Lesser General Public License Usage
+ Alternatively, this file may be used under the terms of the GNU Lesser
+ General Public License version 2.1 as published by the Free Software
+ Foundation and appearing in the file LICENSE.LGPL included in the
+ packaging of this file. Please review the following information to
+ ensure the GNU Lesser General Public License version 2.1 requirements
+ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+
+ In addition, as a special exception, Nokia gives you certain additional
+ rights. These rights are described in the Nokia Qt LGPL Exception
+ version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+
+ If you have questions regarding the use of this file, please contact
+ Nokia at qt-info@nokia.com.
+'''
+
+import os
+import sys
+
+from PySide.QtCore import QObject, Signal, Slot, Property, QUrl, qWarning
+from PySide.QtGui import QApplication
+from PySide.QtDeclarative import QDeclarativeView
+from QtMobility.ServiceFramework import QServiceManager
+
+
+class ServiceManager(QObject):
+
+ def __init__(self):
+ QObject.__init__(self)
+
+ self._services = []
+ self._errorMessage = ""
+ self._emailEnabled = False
+ self._addressEnabled = True
+
+ self.manager = QServiceManager(self)
+
+ self.reloadServicesList()
+
+ def reloadServicesList(self):
+ self._services = []
+ for service in self.manager.findServices():
+ self._services.append(service)
+ self.onServicesChanged.emit()
+
+ onServicesChanged = Signal()
+
+ @Property("QStringList", notify=onServicesChanged)
+ def servicesNames(self):
+ return self._services
+
+ @Slot(str, int, result="QStringList")
+ def serviceImplementations(self, serviceName, serviceIndex):
+ print "Interfaces implemented by ", serviceName
+
+ self._implementations = []
+ for descriptor in self.manager.findInterfaces(serviceName):
+ impSpec = "%s %d.%d" % (descriptor.interfaceName(),
+ descriptor.majorVersion(),
+ descriptor.minorVersion())
+
+ if not serviceName:
+ impSpec += " (" + descriptor.serviceName() + ")"
+
+ default = self.manager.interfaceDefault(descriptor.interfaceName())
+ if descriptor == default:
+ impSpec += " (default)"
+
+ self._implementations.append((impSpec, descriptor))
+ return [x[0] for x in self._implementations]
+
+ @Slot(str, int, str, int, result="QStringList")
+ def implementationDetails(self, implementationSpec, implementationIndex,
+ serviceName, serviceIndex):
+
+ selectedImplementation = self._implementations[implementationIndex][1]
+ implementationRef = self.manager.loadInterface(selectedImplementation)
+ attributes = []
+
+ if not implementationRef:
+ return ["(Error loading service plugin)"]
+
+ metaObject = implementationRef.metaObject()
+
+ for i in range(metaObject.methodCount()):
+ method = metaObject.method(i)
+ attributes.append("[METHOD] " + method.signature())
+
+ for i in range(metaObject.propertyCount()):
+ p = metaObject.property(i)
+ attributes.append("[PROPERTY] " + p.name())
+
+ return attributes if attributes else ["(no attributes found)"]
+
+ @Slot(int)
+ def setDefault(self, index):
+ descriptor = self._implementations[index][1]
+
+ if descriptor.isValid():
+ if self.manager.setInterfaceDefault(descriptor):
+ pass
+
+def main():
+ app = QApplication([])
+ view = QDeclarativeView()
+ manager = ServiceManager()
+ context = view.rootContext()
+ context.setContextProperty("manager", manager)
+
+ url = QUrl('main.qml')
+ view.setSource(url)
+ view.showFullScreen()
+
+ app.exec_()
+
+
+if __name__ == '__main__':
+ main()
+
+
diff --git a/mobility/servicebrowser/servicebrowser.py b/mobility/servicebrowser/servicebrowser.py
index c6ed671..c034018 100644
--- a/mobility/servicebrowser/servicebrowser.py
+++ b/mobility/servicebrowser/servicebrowser.py
@@ -89,7 +89,7 @@ class ServiceBrowser(QWidget):
for desc in descriptors:
text = "%s %d.%d" % (desc.interfaceName(), desc.majorVersion(), desc.minorVersion())
- if len(serviceName) == 0:
+ if not serviceName:
text += " (" + desc.serviceName() + ")"
defaultInterfaceImpl = self.serviceManager.interfaceDefault(desc.interfaceName())
diff --git a/mobility/sysinfo/dialog.py b/mobility/sysinfo/dialog.py
index bd5fba0..b1dfb33 100644
--- a/mobility/sysinfo/dialog.py
+++ b/mobility/sysinfo/dialog.py
@@ -206,7 +206,7 @@ class Dialog(QWidget, Ui_Dialog):
def netStatusComboActivated(self, index):
status = ""
- reIndex = index
+ reIndex = QSystemNetworkInfo.NetworkMode(index)
self.displayNetworkStatus(self.ni.networkStatus(reIndex))
self.macAddressLabel.setText(self.ni.macAddress(reIndex))
strength = self.ni.networkSignalStrength(reIndex)
diff --git a/mobility/sysinfo/qml/AvailableLanguages.qml b/mobility/sysinfo/qml/AvailableLanguages.qml
new file mode 100644
index 0000000..9d20ca6
--- /dev/null
+++ b/mobility/sysinfo/qml/AvailableLanguages.qml
@@ -0,0 +1,21 @@
+import QtQuick 1.1
+import com.nokia.meego 1.0
+
+Page {
+ id: availableLanguages
+ anchors.margins: UiConstants.DefaultMargin
+ orientationLock: PageOrientation.LockPortrait
+
+ ListView {
+ anchors.fill: parent
+ anchors.centerIn: parent
+ model: sysinfo.availableManagers
+ delegate: Button {
+ text: modelData
+ onClicked: {
+ languageButton.text = text
+ pageStack.pop()
+ }
+ }
+ }
+}
diff --git a/mobility/sysinfo/qml/DevicePage.qml b/mobility/sysinfo/qml/DevicePage.qml
new file mode 100644
index 0000000..ab60424
--- /dev/null
+++ b/mobility/sysinfo/qml/DevicePage.qml
@@ -0,0 +1,73 @@
+import QtQuick 1.1
+import com.nokia.meego 1.0
+
+Page {
+ id: devicePage
+ orientationLock: PageOrientation.LockLandscape
+ Flickable {
+ id: flickableDevice
+ anchors.fill: parent
+ flickableDirection: Flickable.VerticalFlick
+ contentHeight: columnDevice.height + toolBarLayout.height
+ contentWidth: flickableDevice.width
+ Column {
+ id: columnDevice
+ anchors.top: parent.top
+ anchors.topMargin: 20
+ anchors.left: parent.left
+ anchors.leftMargin: 20
+ spacing: 25
+ ProgressBar {
+ id: progressBar
+ minimumValue: 0
+ maximumValue: 100
+ value: 10
+ width: parent.width
+ }
+ Label { text: "Power state" }
+ ButtonColumn {
+ RadioButton { text: "Unknown power" }
+ RadioButton { text: "Battery power" }
+ RadioButton { text: "Wall power" }
+ RadioButton { text: "Wall Power charging Battery" }
+ spacing: 10
+ }
+ Row {
+ Label { text: "IMEI: " }
+ Label { id: labelIMEI; text: sysinfo.imei }
+ }
+ Row {
+ Label { text: "IMSI: " }
+ Label { id: labelIMSI; text: sysinfo.imsi }
+ }
+ Row {
+ Label { text: "Manufacturer: " }
+ Label { id: labelManufacturer; text: sysinfo.manufacturer }
+ }
+ Row {
+ Label { text: "Model: " }
+ Label { id: labelModel; text: sysinfo.model }
+ }
+ Row {
+ Label { text: "Product: " }
+ Label { id: labelProduct; text: sysinfo.product }
+ }
+ Row {
+ Button { id: buttonLock; iconSource: "../general_unlock.png"; checked: sysinfo.deviceLock }
+ Label { text: "Device lock"; anchors.verticalCenter: parent.verticalCenter }
+ }
+ Row {
+ Label { text: "Current profile: " }
+ Label { id: labelProfile; text: sysinfo.profile }
+ }
+ Row {
+ Label { text: "Input method " }
+ Label { id: labelInputMethod; text: sysinfo.inputMethod }
+ }
+ RadioButton { text: "Bluetooth on"; checked: sysinfo.bluetoothState }
+ }
+ }
+ ScrollDecorator {
+ flickableItem: flickableDevice
+ }
+}
diff --git a/mobility/sysinfo/qml/DisplayPage.qml b/mobility/sysinfo/qml/DisplayPage.qml
new file mode 100644
index 0000000..205fafc
--- /dev/null
+++ b/mobility/sysinfo/qml/DisplayPage.qml
@@ -0,0 +1,58 @@
+import QtQuick 1.1
+import com.nokia.meego 1.0
+
+Page {
+ id: displayPage
+ anchors.margins: UiConstants.DefaultMargin
+ orientationLock: PageOrientation.LockLandscape
+ Flickable {
+ id: flickableDisplay
+ anchors.fill: parent
+ flickableDirection: Flickable.VerticalFlick
+ contentHeight: columnDisplay.height + toolBarLayout.height
+ contentWidth: flickableDisplay.width
+ Column {
+ id: columnDisplay
+ anchors.top: parent.top
+ anchors.topMargin: 20
+ anchors.left: parent.left
+ anchors.leftMargin: 20
+ spacing: 25
+ Row {
+ Label { text: "Brightness: " }
+ Label { id: labelBrightness; text: sysinfo.displayBrightness }
+ }
+ Row {
+ Label { text: "Color depth: " }
+ Label { id: labelColorDepth; text: sysinfo.colorDepth }
+ }
+/* Row {
+ Label { text: "Orientation: " }
+ Label { id: labelOrientation; text: "" }
+ }
+ Row {
+ Label { text: "Contrast: " }
+ Label { id: labelContrast; text: "" }
+ }
+ Row {
+ Label { text: "DPI Width: " }
+ Label { id: labelDPIWidth; text: "" }
+ }
+ Row {
+ Label { text: "DPI Height: " }
+ Label { id: labelDPIHeight; text: "" }
+ }
+ Row {
+ Label { text: "Physical Width: " }
+ Label { id: labelPhysicalWidth; text: "" }
+ }
+ Row {
+ Label { text: "Physical Height: " }
+ Label { id: labelPhysicalHeight; text: "" }
+ }*/
+ }
+ }
+ ScrollDecorator {
+ flickableItem: flickableDisplay
+ }
+}
diff --git a/mobility/sysinfo/qml/GeneralPage.qml b/mobility/sysinfo/qml/GeneralPage.qml
new file mode 100644
index 0000000..48dafbb
--- /dev/null
+++ b/mobility/sysinfo/qml/GeneralPage.qml
@@ -0,0 +1,60 @@
+import QtQuick 1.1
+import com.nokia.meego 1.0
+
+Page {
+ id: generalPage
+ orientationLock: PageOrientation.LockLandscape
+ anchors.margins: UiConstants.DefaultMargin
+
+ Column {
+ anchors.fill: parent
+ spacing: 25
+ Row {
+ spacing: 20
+ Label { text: "Current language:" }
+ Label { id: currentLanguage; text: sysinfo.currentLanguage }
+ }
+ Row {
+ spacing: 20
+ Label { text: "Current country:" }
+ Label { id: currentCountry; text: "currentCountry" }
+ }
+ Row {
+ spacing: 20
+ Label { text: "Available languages:"; anchors.verticalCenter: parent.verticalCenter }
+ Button {
+ id: languageButton
+ text: "Select a language"
+ onClicked: {
+ pageStack.push(Qt.createComponent("AvailableLanguages.qml"))
+ }
+ }
+ }
+ Row {
+ spacing: 20
+ Label { text: "Version"; anchors.verticalCenter: parent.verticalCenter }
+ Button {
+ id: versionButton
+ text: "Select version"
+ onClicked: pageStack.push(Qt.createComponent("AvailableVersions.qml"))
+
+ }
+ TextField {
+ text: ""
+ }
+ }
+
+ Row {
+ spacing: 20
+ Label { text: "Feature supported"; anchors.verticalCenter: parent.verticalCenter }
+ Button {
+ id: featureButton
+ text: "Select feature"
+ onClicked: pageStack.push(Qt.createComponent("AvailableFeatures.qml"))
+ }
+ TextField {
+ text: ""
+ }
+ }
+ }
+}
diff --git a/mobility/sysinfo/qml/NetworkDetails.qml b/mobility/sysinfo/qml/NetworkDetails.qml
new file mode 100644
index 0000000..9ad2527
--- /dev/null
+++ b/mobility/sysinfo/qml/NetworkDetails.qml
@@ -0,0 +1,67 @@
+import QtQuick 1.1
+import com.nokia.meego 1.0
+import com.nokia.extras 1.1
+
+Sheet {
+
+ id: sheet
+
+ property string networkMode: ""
+
+ acceptButtonText: "Close"
+ rejectButtonText: ""
+
+ title: Label {
+ text: "Details for network mode " + sheet.networkMode
+ }
+
+ content: Flickable {
+ anchors.fill: parent
+ anchors.margins: UiConstants.DefaultMargin
+ contentWidth: col.width
+ contentHeight: col.height
+ flickableDirection: Flickable.VerticalFlick
+
+ Column {
+ id: col
+
+ anchors.top: parent.top
+// anchors.left: parent.left
+// anchors.right: parent.right
+ spacing: 10
+
+ Label {
+ text: "Network status: " + sysinfo.networkStatus(networkMode)
+ }
+
+ Label {
+ text: "Network name: " + sysinfo.networkName(networkMode)
+ }
+
+ Label {
+ text: "Interface name: " + sysinfo.networkInterfaceName(networkMode)
+ }
+
+ Label {
+ text: "MAC Address: " + sysinfo.networkMacAddress(networkMode)
+ }
+
+ Row {
+ anchors.left: col.left
+ anchors.right: col.right
+
+ spacing: 10
+ Label {
+ text: "Signal strength:"
+ }
+
+ ProgressBar {
+ width: 600
+ minimumValue: -1
+ maximumValue: 100
+ value: sysinfo.networkSignalStrength(networkMode)
+ }
+ }
+ }
+ }
+}
diff --git a/mobility/sysinfo/qml/NetworkPage.qml b/mobility/sysinfo/qml/NetworkPage.qml
new file mode 100644
index 0000000..bb44e6e
--- /dev/null
+++ b/mobility/sysinfo/qml/NetworkPage.qml
@@ -0,0 +1,76 @@
+import QtQuick 1.1
+import com.nokia.meego 1.0
+
+Page {
+
+ id: page
+ orientationLock: PageOrientation.LockLandscape
+ anchors.margins: UiConstants.DefaultMargin
+
+ Flickable {
+ id: flickNetwork
+ anchors.fill: parent
+ flickableDirection: Flickable.VerticalFlick
+ contentHeight: colNetwork.height + toolBarLayout.height
+ contentWidth: flickNetwork.width
+
+ Column {
+ id: colNetwork
+ spacing: 20
+
+ ButtonColumn {
+ id: columnNetworks
+ //anchors.top: parent.top
+ //width: parent.width
+
+ Repeater {
+ model: sysinfo.networksNames
+ Button {
+ text: modelData
+ onClicked: {
+ console.log("Getting info for" + modelData);
+ var component = Qt.createComponent("NetworkDetails.qml");
+ if (component.status == Component.Ready) {
+ var networkSheet = component.createObject(page,
+ {
+ "networkMode": modelData
+ });
+ networkSheet.open();
+ } else {
+ console.log("Component not ready");
+ }
+ }
+ }
+ }
+ }
+
+ // Cell ID stuff
+ Label {
+ text: "Cell ID: " + sysinfo.cellId()
+ }
+
+ Label {
+ text: "Location Area Code: " + sysinfo.locationAreaCode()
+ }
+
+ Label {
+ text: "Current Mobile Country Code: " + sysinfo.currentMCC()
+ }
+
+ Label {
+ text: "Current Mobile Network Code: " + sysinfo.currentMNC()
+ }
+
+ Label {
+ text: "Home Mobile Country Code: " + sysinfo.homeMCC()
+ }
+
+ Label {
+ text: "Home Mobile Network Code: " + sysinfo.homeMNC()
+ }
+
+ }
+
+ }
+
+}
diff --git a/mobility/sysinfo/qml/ScreenSaverPage.qml b/mobility/sysinfo/qml/ScreenSaverPage.qml
new file mode 100644
index 0000000..d25e760
--- /dev/null
+++ b/mobility/sysinfo/qml/ScreenSaverPage.qml
@@ -0,0 +1,10 @@
+import QtQuick 1.1
+import com.nokia.meego 1.0
+
+Page {
+ id: screenSaverTab
+ orientationLock: PageOrientation.LockLandscape
+ anchors.margins: UiConstants.DefaultMargin
+
+ RadioButton { text: "Screen saver inhibited"; checked: sysinfo.screenSaverInhibited }
+}
diff --git a/mobility/sysinfo/qml/StoragePage.qml b/mobility/sysinfo/qml/StoragePage.qml
new file mode 100644
index 0000000..6c5ad2a
--- /dev/null
+++ b/mobility/sysinfo/qml/StoragePage.qml
@@ -0,0 +1,55 @@
+import QtQuick 1.1
+import com.nokia.meego 1.0
+
+Page {
+ id: storageTab
+ orientationLock: PageOrientation.LockLandscape
+ anchors.margins: UiConstants.DefaultMargin
+
+ Flickable {
+ anchors.fill: parent
+ flickableDirection: Flickable.VerticalFlick
+ contentHeight: columnStorage.height + toolBarLayout.height
+ contentWidth: width
+ Column {
+ id: columnStorage
+ anchors.top: parent.top
+ width: parent.width
+
+ spacing: 25
+
+ Repeater {
+
+ model: sysinfo.volumeNames
+
+ Column {
+
+ width: parent.width
+
+ Label {
+ width: parent.width
+ text: "Volume: " + modelData
+ platformStyle: LabelStyle {
+ fontPixelSize: 32
+ }
+ }
+
+ Row {
+ spacing: 30
+ Label {
+ text: "Type: " + sysinfo.storageType(modelData)
+ }
+
+ Label {
+ text: "Total size: " + sysinfo.totalStorageSize(modelData)
+ }
+
+ Label {
+ text: "Available: " + sysinfo.availableStorageSize(modelData)
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/mobility/sysinfo/qml/TabBarPage.qml b/mobility/sysinfo/qml/TabBarPage.qml
new file mode 100644
index 0000000..8cc24de
--- /dev/null
+++ b/mobility/sysinfo/qml/TabBarPage.qml
@@ -0,0 +1,31 @@
+import QtQuick 1.1
+import com.nokia.meego 1.0
+
+Page {
+ id: tabBarPage
+ anchors.margins: UiConstants.DefaultMargin
+ orientationLock: PageOrientation.LockLandscape
+
+ tools: ToolBarLayout {
+ id: toolBarLayout
+ ButtonRow {
+ platformStyle: TabButtonStyle { }
+ TabButton { text: "General"; tab: generalTab }
+ TabButton { text: "Device"; tab: deviceTab }
+ TabButton { text: "Display"; tab: displayTab }
+ TabButton { text: "Storage"; tab: storageTab }
+ TabButton { text: "Network"; tab: networkTab }
+ TabButton { text: "Screen saver"; tab: screenSaverTab }
+ }
+ }
+ TabGroup {
+ anchors.fill: parent
+ currentTab: generalTab
+ GeneralPage { id: generalTab }
+ DevicePage { id: deviceTab }
+ DisplayPage { id: displayTab }
+ StoragePage { id: storageTab }
+ NetworkPage { id: networkTab }
+ ScreenSaverPage { id: screenSaverTab }
+ }
+}
diff --git a/mobility/sysinfo/qml/main.py b/mobility/sysinfo/qml/main.py
new file mode 100644
index 0000000..a4e0d89
--- /dev/null
+++ b/mobility/sysinfo/qml/main.py
@@ -0,0 +1,334 @@
+#!/usr/bin/python
+
+import sys
+import os
+
+from PySide import QtCore
+from PySide import QtGui
+from PySide import QtDeclarative
+from PySide import QtOpenGL
+from QtMobility.SystemInfo import QSystemInfo, QSystemDeviceInfo, QSystemDisplayInfo, QSystemStorageInfo, QSystemNetworkInfo, QSystemScreenSaver
+
+
+class SystemInfoModel(QtCore.QObject):
+ changed = QtCore.Signal()
+
+ def __init__(self):
+ super(SystemInfoModel, self).__init__()
+ self.systemInfo = QSystemInfo(self)
+ self.setupGeneral()
+ self.setupDevice()
+ self.setupDisplay()
+ self.setupStorage()
+ self.setupNetwork()
+ self.setupScreenSaver()
+
+ @QtCore.Property(str, notify=changed)
+ def currentLanguage(self):
+ return self._currentLanguage
+
+ @QtCore.Property("QStringList", notify=changed)
+ def availableLanguages(self):
+ return self._availableLanguages
+
+ @QtCore.Property(int, notify=changed)
+ def displayBrightness(self):
+ return self._displayBrightness
+
+ @QtCore.Property(int, notify=changed)
+ def colorDepth(self):
+ return self._colorDepth
+
+ @QtCore.Property(str, notify=changed)
+ def imei(self):
+ return self._imei
+
+ @QtCore.Property(str, notify=changed)
+ def imsi(self):
+ return self._imsi
+
+ @QtCore.Property(str, notify=changed)
+ def manufacturer(self):
+ return self._manufacturer
+
+ @QtCore.Property(str, notify=changed)
+ def product(self):
+ return self._product
+
+ @QtCore.Property(str, notify=changed)
+ def model(self):
+ return self._model
+
+ @QtCore.Property(str, notify=changed)
+ def profile(self):
+ return self._profile
+
+ @QtCore.Property(str, notify=changed)
+ def inputMethod(self):
+ return self._inputMethod
+
+ @QtCore.Property(bool, notify=changed)
+ def deviceLock(self):
+ return self._deviceLock
+
+ @QtCore.Property(str, notify=changed)
+ def simStatus(self):
+ return self._simStatus
+
+ @QtCore.Property(bool, notify=changed)
+ def bluetoothState(self):
+ return self._bluetoothState
+
+ @QtCore.Property("QStringList", notify=changed)
+ def volumeNames(self):
+ return self._volumeNames
+
+ @QtCore.Property("QStringList", notify=changed)
+ def networksNames(self):
+ return ["Wlan", "Ethernet", "Gsm", "Cdma", "Wcdma"]
+
+ @QtCore.Property(bool, notify=changed)
+ def screenSaverInhibited(self):
+ return self._screenSaverInhibited
+
+ def setupGeneral(self):
+ self._currentLanguage = self.systemInfo.currentLanguage()
+ self._availableLanguages = self.systemInfo.availableLanguages()
+
+ def setupDevice(self):
+ self.deviceInfo = QSystemDeviceInfo(self)
+ self._batteryLevel = self.deviceInfo.batteryLevel()
+ self.deviceInfo.batteryLevelChanged.connect(self.updateBatteryStatus)
+ self.deviceInfo.batteryStatusChanged.connect(self.displayBatteryStatus)
+ self.deviceInfo.powerStateChanged.connect(self.updatePowerState)
+ self._imei = self.deviceInfo.imei()
+ self._imsi = self.deviceInfo.imsi()
+ self._manufacturer = self.deviceInfo.manufacturer()
+ self._model = self.deviceInfo.model()
+ self._product = self.deviceInfo.productName()
+ self._deviceLock = self.deviceInfo.isDeviceLocked()
+
+ methods = self.deviceInfo.inputMethodType()
+ inputs = []
+ if methods & QSystemDeviceInfo.Keys:
+ inputs.append("Keys")
+ if methods & QSystemDeviceInfo.Keypad:
+ inputs.append("Keypad")
+ if methods & QSystemDeviceInfo.Keyboard:
+ inputs.append("Keyboard")
+ if methods & QSystemDeviceInfo.SingleTouch:
+ inputs.append("Touch Screen")
+ if methods & QSystemDeviceInfo.MultiTouch:
+ inputs.append("Multi touch")
+ if methods & QSystemDeviceInfo.Mouse:
+ inputs.append("Mouse")
+
+ self._inputMethod = " ".join(inputs)
+ self.updateSimStatus()
+ self.updateProfile()
+
+ self._bluetoothState = self.deviceInfo.currentBluetoothPowerState()
+ self.deviceInfo.bluetoothStateChanged.connect(self.updateBluetoothState)
+
+ def setupDisplay(self):
+ self.displayInfo = QSystemDisplayInfo()
+ self._displayBrightness = self.displayInfo.displayBrightness(0)
+ self._colorDepth = self.displayInfo.colorDepth(0)
+
+ def setupStorage(self):
+ self.storageInfo = QSystemStorageInfo()
+ self._volumeNames = self.storageInfo.logicalDrives()
+
+ @QtCore.Slot(str, result=str)
+ def storageType(self, volumeName):
+ names = {
+ QSystemStorageInfo.InternalDrive: "Internal",
+ QSystemStorageInfo.RemovableDrive: "Removable",
+ QSystemStorageInfo.CdromDrive: "CD-Rom",
+ QSystemStorageInfo.RemoteDrive: "Network",
+ }
+
+ volType = self.storageInfo.typeForDrive(volumeName)
+
+ return names.get(volType, "Unknown")
+
+ @QtCore.Slot(str, result=str)
+ def totalStorageSize(self, volumeName):
+ return self.convert_bytes(self.storageInfo.totalDiskSpace(volumeName))
+
+ @QtCore.Slot(str, result=str)
+ def availableStorageSize(self, volumeName):
+ return self.convert_bytes(self.storageInfo.availableDiskSpace(volumeName))
+
+ def convert_bytes(self, bytes):
+ # From http://www.5dollarwhitebox.org/drupal/node/84
+ bytes = float(bytes)
+ if bytes >= 1099511627776:
+ terabytes = bytes / 1099511627776
+ size = '%.2fT' % terabytes
+ elif bytes >= 1073741824:
+ gigabytes = bytes / 1073741824
+ size = '%.2fG' % gigabytes
+ elif bytes >= 1048576:
+ megabytes = bytes / 1048576
+ size = '%.2fM' % megabytes
+ elif bytes >= 1024:
+ kilobytes = bytes / 1024
+ size = '%.2fK' % kilobytes
+ else:
+ size = '%.2fb' % bytes
+ return size
+
+ def setupNetwork(self):
+ self.networkInfo = QSystemNetworkInfo()
+
+ def modeEnumForName(self, name):
+ try:
+ mode = getattr(QSystemNetworkInfo, name.capitalize() + "Mode")
+ except AttributeError as e:
+ print e
+ return None
+
+ return mode
+
+ @QtCore.Slot(str, result=str)
+ def networkStatus(self, modeName):
+ mode = self.modeEnumForName(modeName)
+ status = self.networkInfo.networkStatus(mode)
+ statusName = str(status).split('.')[-1]
+ # Split the CamelCase enum name
+ import re
+ return re.sub(r'([a-z])([A-Z])', r'\1 \2', statusName)
+
+ @QtCore.Slot(str, result=str)
+ def networkName(self, modeName):
+ mode = self.modeEnumForName(modeName)
+ name = self.networkInfo.networkName(mode)
+ return name if name else "<Unknown>"
+
+ @QtCore.Slot(str, result=str)
+ def networkInterfaceName(self, modeName):
+ mode = self.modeEnumForName(modeName)
+ name = self.networkInfo.interfaceForMode(mode).humanReadableName()
+ return name if name else "<Unknown>"
+
+ @QtCore.Slot(str, result=str)
+ def networkMacAddress(self, modeName):
+ mode = self.modeEnumForName(modeName)
+ mac = self.networkInfo.macAddress(mode)
+ return mac if mac else "<Unknown>"
+
+ @QtCore.Slot(str, result=int)
+ def networkSignalStrength(self, modeName):
+ mode = self.modeEnumForName(modeName)
+ return self.networkInfo.networkSignalStrength(mode)
+
+ @QtCore.Slot(result=str)
+ def cellId(self):
+ cell = self.networkInfo.cellId()
+ return str(cell) if cell != -1 else "<Unavailable>"
+
+ @QtCore.Slot(result=str)
+ def locationAreaCode(self):
+ code = self.networkInfo.locationAreaCode()
+ return str(code) if code != -1 else "<Unavailable>"
+
+ @QtCore.Slot(result=str)
+ def currentMCC(self):
+ code = self.networkInfo.currentMobileCountryCode()
+ return code if code else "<Unavailable>"
+
+ @QtCore.Slot(result=str)
+ def currentMNC(self):
+ code = self.networkInfo.currentMobileNetworkCode()
+ return code if code else "<Unavailable>"
+
+ @QtCore.Slot(result=str)
+ def homeMCC(self):
+ code = self.networkInfo.homeMobileCountryCode()
+ return code if code else "<Unavailable>"
+
+ @QtCore.Slot(result=str)
+ def homeMNC(self):
+ code = self.networkInfo.homeMobileNetworkCode()
+ return code if code else "<Unavailable>"
+
+ def setupScreenSaver(self):
+ self.saverInfo = QSystemScreenSaver(self)
+ self._screenSaverInhibited = self.saverInfo.screenSaverInhibited()
+
+ def updateBluetoothState(self, on):
+ self._bluetoothState = on
+ self.changed.emit()
+
+ def updateBatteryStatus(self, status):
+ self._batteryLevel = status
+ self.emit(QtCore.SIGNAL('changed()'))
+
+ def displayBatteryStatus(self, status):
+ pass
+
+ def updatePowerState(self, newState):
+ pass
+
+ def updateSimStatus(self):
+ if self.deviceInfo:
+ status = self.deviceInfo.simStatus()
+ if status == QSystemDeviceInfo.SimLocked:
+ simstring = "Sim Locked";
+ elif status == QSystemDeviceInfo.SimNotAvailable:
+ simstring = "Sim not available";
+ elif status == QSystemDeviceInfo.SingleSimAvailable:
+ simstring = "Single Sim Available";
+ elif status == QSystemDeviceInfo.DualSimAvailable:
+ simstring = "Dual Sim available";
+ else:
+ simstring = ""
+
+ self._simStatus = simstring
+
+
+ def updateProfile(self):
+ if self.deviceInfo:
+ current = self.deviceInfo.currentProfile()
+ if current == QSystemDeviceInfo.UnknownProfile:
+ profilestring = "Unknown"
+ elif current == QSystemDeviceInfo.SilentProfile:
+ profilestring = "Silent"
+ elif current == QSystemDeviceInfo.NormalProfile:
+ profilestring = "Normal"
+ elif current == QSystemDeviceInfo.LoudProfile:
+ profilestring = "Loud"
+ elif current == QSystemDeviceInfo.VibProfile:
+ profilestring = "Vibrate"
+ elif current == QSystemDeviceInfo.OfflineProfile:
+ profilestring = "Offline";
+ elif current == QSystemDeviceInfo.PowersaveProfile:
+ profilestring = "Powersave";
+ elif current == QSystemDeviceInfo.CustomProfile:
+ profilestring = "custom";
+
+ self._profile = profilestring
+
+class SystemInfoUI(QtCore.QObject):
+ def __init__(self):
+ super(SystemInfoUI, self).__init__()
+ self.view = QtDeclarative.QDeclarativeView()
+ self.rc = self.view.rootContext()
+
+ self.model = SystemInfoModel()
+ self.rc.setContextProperty('sysinfo', self.model)
+
+ self.view.setSource('main.qml')
+
+ if "-no-fs" in sys.argv:
+ self.view.show()
+ else:
+ self.view.showFullScreen()
+
+ self.systemInfo = QSystemInfo(self)
+
+if __name__ == "__main__":
+ app = QtGui.QApplication([])
+ ui = SystemInfoUI()
+ app.exec_()
diff --git a/mobility/sysinfo/qml/main.qml b/mobility/sysinfo/qml/main.qml
new file mode 100644
index 0000000..57bdc31
--- /dev/null
+++ b/mobility/sysinfo/qml/main.qml
@@ -0,0 +1,10 @@
+import QtQuick 1.1
+import com.nokia.meego 1.0
+
+PageStackWindow {
+ id: appWindow
+
+ initialPage: tabBarPage
+
+ TabBarPage { id: tabBarPage }
+}