summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore7
-rw-r--r--doc/classic.css295
-rw-r--r--doc/doc.pri51
-rwxr-xr-xdoc/fixnavi.pl70
-rw-r--r--doc/images/accelerometer-sensor.pngbin0 -> 19747 bytes
-rw-r--r--doc/images/attitude-sensor.pngbin0 -> 23553 bytes
-rw-r--r--doc/images/location-info.pngbin0 -> 59842 bytes
-rw-r--r--doc/images/qt-creator-project-button.pngbin0 -> 22076 bytes
-rw-r--r--doc/images/qt-logo.pngbin0 -> 1471 bytes
-rw-r--r--doc/images/qt-simulator-application.pngbin0 -> 6493 bytes
-rw-r--r--doc/images/qt-simulator-battery.pngbin0 -> 7032 bytes
-rw-r--r--doc/images/qt-simulator-contacts.pngbin0 -> 11362 bytes
-rw-r--r--doc/images/qt-simulator-devices.pngbin0 -> 512292 bytes
-rw-r--r--doc/images/qt-simulator-drives.pngbin0 -> 10542 bytes
-rw-r--r--doc/images/qt-simulator-generic-settings.pngbin0 -> 24153 bytes
-rw-r--r--doc/images/qt-simulator-location.pngbin0 -> 8354 bytes
-rw-r--r--doc/images/qt-simulator-messaging.pngbin0 -> 7148 bytes
-rw-r--r--doc/images/qt-simulator-network.pngbin0 -> 19428 bytes
-rw-r--r--doc/images/qt-simulator-quick-tour.pngbin0 -> 237907 bytes
-rw-r--r--doc/images/qt-simulator-scripting.pngbin0 -> 11038 bytes
-rw-r--r--doc/images/qt-simulator-search-advanced.pngbin0 -> 33258 bytes
-rw-r--r--doc/images/qt-simulator-sensors.pngbin0 -> 20981 bytes
-rw-r--r--doc/images/qt-simulator-view-settings.pngbin0 -> 7258 bytes
-rw-r--r--doc/images/qt-simulator.pngbin0 -> 231402 bytes
-rw-r--r--doc/scripting.qdoc4
-rw-r--r--doc/simulator.qdoc992
-rw-r--r--doc/simulator.qdocconf222
-rw-r--r--fonts/heiseigoths60.ttfbin0 -> 2903684 bytes
-rw-r--r--fonts/nosnb.ttfbin0 -> 113944 bytes
-rw-r--r--fonts/nosnr.ttfbin0 -> 118348 bytes
-rw-r--r--fonts/s60snr.ttfbin0 -> 442068 bytes
-rw-r--r--fonts/s60ssb.ttfbin0 -> 436228 bytes
-rw-r--r--fonts/s60tsb.ttfbin0 -> 449140 bytes
-rw-r--r--fonts/s60zdigi.ttfbin0 -> 34340 bytes
-rw-r--r--models/maemoFremantle/N900.pngbin0 -> 238563 bytes
-rw-r--r--models/maemoFremantle/maemoFremantle.config11
-rw-r--r--models/symbianNonTouch/N95_8GB.pngbin0 -> 154406 bytes
-rw-r--r--models/symbianNonTouch/symbianNonTouch.config35
-rw-r--r--models/symbianTouch/N97.pngbin0 -> 232296 bytes
-rw-r--r--models/symbianTouch/symbianTouch.config14
-rw-r--r--scripts/autostart/.directory0
-rw-r--r--scripts/devices/.Maemo Fremantle.qs.swpbin0 -> 12288 bytes
-rw-r--r--scripts/devices/Default.qs18
-rw-r--r--scripts/devices/Maemo Fremantle.qs18
-rw-r--r--scripts/examples/devicechange.qs22
-rw-r--r--scripts/examples/location.qs20
-rw-r--r--scripts/examples/messagebox.qs3
-rw-r--r--scripts/examples/rotate.qs2
-rw-r--r--scripts/examples/runOutOfBattery.qs18
-rw-r--r--scripts/examples/sysinfodevice.qs11
-rw-r--r--scripts/examples/sysinfogeneric.qs6
-rw-r--r--scripts/examples/sysinfonetwork.qs16
-rw-r--r--scripts/favorites/favoriteScript.qs1
-rw-r--r--simulator.pro45
-rw-r--r--src/main.cpp127
-rw-r--r--src/mobility/contacts.cpp108
-rw-r--r--src/mobility/contacts.h75
-rw-r--r--src/mobility/messaging.cpp149
-rw-r--r--src/mobility/messaging.h56
-rw-r--r--src/mobility/mobility.pri12
-rw-r--r--src/mobility/mobilitydata.cpp262
-rw-r--r--src/mobility/mobilitydata.h82
-rw-r--r--src/mobility/mobilitymanager.cpp503
-rw-r--r--src/mobility/mobilitymanager.h130
-rw-r--r--src/other/application.cpp349
-rw-r--r--src/other/application.h123
-rw-r--r--src/other/applicationmanager.cpp382
-rw-r--r--src/other/applicationmanager.h100
-rw-r--r--src/other/configurationreader.cpp172
-rw-r--r--src/other/configurationreader.h64
-rw-r--r--src/other/deviceitem.cpp315
-rw-r--r--src/other/deviceitem.h173
-rw-r--r--src/other/displaywidget.cpp88
-rw-r--r--src/other/displaywidget.h58
-rw-r--r--src/other/menu.cpp121
-rw-r--r--src/other/menu.h66
-rw-r--r--src/other/menuwidget.cpp130
-rw-r--r--src/other/menuwidget.h80
-rw-r--r--src/other/other.pri36
-rw-r--r--src/other/phononmanager.cpp737
-rw-r--r--src/other/phononmanager.h120
-rw-r--r--src/other/phononsignalbridges.cpp167
-rw-r--r--src/other/phononsignalbridges.h113
-rw-r--r--src/other/phononvideowidget.cpp51
-rw-r--r--src/other/phononvideowidget.h61
-rw-r--r--src/other/widget.cpp261
-rw-r--r--src/other/widget.h93
-rw-r--r--src/other/widgetmanager.cpp536
-rw-r--r--src/other/widgetmanager.h109
-rw-r--r--src/shared/qtlockedfile/README.txt10
-rw-r--r--src/shared/qtlockedfile/namespace.patch70
-rw-r--r--src/shared/qtlockedfile/qtlockedfile.cpp158
-rw-r--r--src/shared/qtlockedfile/qtlockedfile.h77
-rw-r--r--src/shared/qtlockedfile/qtlockedfile.pri13
-rw-r--r--src/shared/qtlockedfile/qtlockedfile_unix.cpp107
-rw-r--r--src/shared/qtlockedfile/qtlockedfile_win.cpp203
-rw-r--r--src/shared/qtsingleapplication/README.txt10
-rw-r--r--src/shared/qtsingleapplication/namespace.patch133
-rw-r--r--src/shared/qtsingleapplication/qtlocalpeer.cpp172
-rw-r--r--src/shared/qtsingleapplication/qtlocalpeer.h65
-rw-r--r--src/shared/qtsingleapplication/qtsingleapplication.cpp141
-rw-r--r--src/shared/qtsingleapplication/qtsingleapplication.h81
-rw-r--r--src/shared/qtsingleapplication/qtsingleapplication.pri14
-rw-r--r--src/shared/qtsingleapplication/qtsinglecoreapplication.cpp68
-rw-r--r--src/shared/qtsingleapplication/qtsinglecoreapplication.h59
-rw-r--r--src/shared/qtsingleapplication/qtsinglecoreapplication.pri14
-rw-r--r--src/src.pri77
-rw-r--r--src/ui/applicationtablewidget.cpp57
-rw-r--r--src/ui/applicationtablewidget.h52
-rw-r--r--src/ui/configurationwidget.cpp405
-rw-r--r--src/ui/configurationwidget.h141
-rw-r--r--src/ui/contactsui.cpp103
-rw-r--r--src/ui/contactsui.h56
-rw-r--r--src/ui/icons/hicolor/128x128/apps/Nokia-Simulator.pngbin0 -> 13714 bytes
-rw-r--r--src/ui/icons/hicolor/16x16/apps/Nokia-Simulator.pngbin0 -> 809 bytes
-rw-r--r--src/ui/icons/hicolor/24x24/apps/Nokia-Simulator.pngbin0 -> 1501 bytes
-rw-r--r--src/ui/icons/hicolor/256x256/apps/Nokia-Simulator.pngbin0 -> 34553 bytes
-rw-r--r--src/ui/icons/hicolor/32x32/apps/Nokia-Simulator.pngbin0 -> 1924 bytes
-rw-r--r--src/ui/icons/hicolor/48x48/apps/Nokia-Simulator.pngbin0 -> 3802 bytes
-rw-r--r--src/ui/icons/hicolor/64x64/apps/Nokia-Simulator.pngbin0 -> 5002 bytes
-rw-r--r--src/ui/inspector.ui133
-rw-r--r--src/ui/locationui.cpp117
-rw-r--r--src/ui/locationui.h59
-rw-r--r--src/ui/mainwindow.cpp399
-rw-r--r--src/ui/mainwindow.h85
-rw-r--r--src/ui/menus/fremantle_landscape.pngbin0 -> 43409 bytes
-rw-r--r--src/ui/menus/fremantle_portrait.pngbin0 -> 14714 bytes
-rw-r--r--src/ui/menus/menus.qrc10
-rw-r--r--src/ui/menus/symbiantouch_buttons_small_landscape.pngbin0 -> 15257 bytes
-rw-r--r--src/ui/menus/symbiantouch_buttons_small_portrait.pngbin0 -> 7900 bytes
-rw-r--r--src/ui/menus/symbiantouch_status_landscape.pngbin0 -> 15458 bytes
-rw-r--r--src/ui/menus/symbiantouch_status_portrait.pngbin0 -> 12254 bytes
-rw-r--r--src/ui/messagingui.cpp76
-rw-r--r--src/ui/messagingui.h53
-rw-r--r--src/ui/sensorsui.cpp522
-rw-r--r--src/ui/sensorsui.h231
-rw-r--r--src/ui/style/images/advanced.pngbin0 -> 1201 bytes
-rw-r--r--src/ui/style/images/advanced_light.pngbin0 -> 1186 bytes
-rw-r--r--src/ui/style/images/battery_0.pngbin0 -> 442 bytes
-rw-r--r--src/ui/style/images/battery_100.pngbin0 -> 424 bytes
-rw-r--r--src/ui/style/images/battery_20.pngbin0 -> 436 bytes
-rw-r--r--src/ui/style/images/battery_40.pngbin0 -> 440 bytes
-rw-r--r--src/ui/style/images/battery_60.pngbin0 -> 442 bytes
-rw-r--r--src/ui/style/images/battery_80.pngbin0 -> 441 bytes
-rw-r--r--src/ui/style/images/batterypower.pngbin0 -> 661 bytes
-rw-r--r--src/ui/style/images/closebutton.pngbin0 -> 2106 bytes
-rw-r--r--src/ui/style/images/connection.pngbin0 -> 747 bytes
-rw-r--r--src/ui/style/images/favoriteScripts.pngbin0 -> 516 bytes
-rw-r--r--src/ui/style/images/network.pngbin0 -> 930 bytes
-rw-r--r--src/ui/style/images/networkstatus.pngbin0 -> 450 bytes
-rw-r--r--src/ui/style/images/phone.pngbin0 -> 929 bytes
-rw-r--r--src/ui/style/images/reset.pngbin0 -> 184 bytes
-rw-r--r--src/ui/style/images/unknownpower.pngbin0 -> 718 bytes
-rw-r--r--src/ui/style/images/wall.pngbin0 -> 706 bytes
-rw-r--r--src/ui/style/images/wall_charge.pngbin0 -> 939 bytes
-rw-r--r--src/ui/systeminfogenericui.cpp928
-rw-r--r--src/ui/systeminfogenericui.h310
-rw-r--r--src/ui/systeminfonetworkui.cpp482
-rw-r--r--src/ui/systeminfonetworkui.h208
-rw-r--r--src/ui/systeminfostorageui.cpp387
-rw-r--r--src/ui/systeminfostorageui.h140
-rw-r--r--src/ui/ui.pri28
-rw-r--r--src/ui/ui.qrc5
-rw-r--r--src/ui/viewconfiguration.cpp175
-rw-r--r--src/ui/viewconfiguration.h89
-rw-r--r--src/ui/viewconfiguration.ui261
-rw-r--r--stubdata/standardcontacts.vcf373
-rw-r--r--stubdata/standardmessages/testmessage7
-rw-r--r--stubdata/standardselfcontact.vcf10
169 files changed, 15264 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..c219394
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,7 @@
+*.user
+Makefile*
+*.obj
+*.pdb
+moc_*
+ui_*
+
diff --git a/doc/classic.css b/doc/classic.css
new file mode 100644
index 0000000..f97bdbe
--- /dev/null
+++ b/doc/classic.css
@@ -0,0 +1,295 @@
+BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV {
+ font-family: Arial, Geneva, Helvetica, sans-serif;
+}
+H1 {
+ text-align: center;
+ font-size: 160%;
+}
+H2 {
+ font-size: 120%;
+}
+H3 {
+ font-size: 100%;
+}
+
+h3.fn,span.fn
+{
+ background-color: #eee;
+ border-width: 1px;
+ border-style: solid;
+ border-color: #ddd;
+ font-weight: bold;
+ padding: 6px 0px 6px 10px;
+ margin: 42px 0px 0px 0px;
+}
+
+hr {
+ border: 0;
+ color: #a0a0a0;
+ background-color: #ccc;
+ height: 1px;
+ width: 100%;
+ text-align: left;
+ margin: 34px 0px 34px 0px;
+}
+
+table.valuelist {
+ border-width: 1px 1px 1px 1px;
+ border-style: solid;
+ border-color: #dddddd;
+ border-collapse: collapse;
+ background-color: #f0f0f0;
+}
+
+table.indextable {
+ border-width: 1px 1px 1px 1px;
+ border-collapse: collapse;
+ background-color: #f0f0f0;
+ border-color:#555;
+ font-size: 110%;
+}
+
+table td.largeindex {
+ border-width: 1px 1px 1px 1px;
+ border-collapse: collapse;
+ background-color: #f0f0f0;
+ border-color:#555;
+ font-size: 120%;
+}
+
+table.valuelist th {
+ border-width: 1px 1px 1px 2px;
+ padding: 4px;
+ border-style: solid;
+ border-color: #666;
+ color:white;
+ background-color:#666;
+}
+
+th.titleheader {
+ border-width: 1px 0px 1px 0px;
+ padding: 4px;
+ border-style: solid;
+ border-color: #444;
+ color:white;
+ background-color:#555555;
+ font-size: 110%;
+}
+
+th.largeheader {
+ border-width: 1px 0px 1px 0px;
+ padding: 4px;
+ border-style: solid;
+ border-color: #444;
+ color:white;
+ background-color:#555555;
+ font-size: 120%;
+}
+
+p {
+
+ margin-left: 4px;
+ margin-top: 8px;
+ margin-bottom: 8px;
+}
+
+a:link
+{
+ color: #0046ad;
+ text-decoration: none
+}
+
+a:visited
+{
+ color: #672967;
+ text-decoration: none
+}
+
+a.obsolete
+{
+ color: #661100;
+ text-decoration: none
+}
+
+a.compat
+{
+ color: #661100;
+ text-decoration: none
+}
+
+a.obsolete:visited
+{
+ color: #995500;
+ text-decoration: none
+}
+
+a.compat:visited
+{
+ color: #995500;
+ text-decoration: none
+}
+
+body
+{
+ background: #ffffff;
+ color: black
+}
+
+table.generic, table.annotated
+{
+ border-width: 1px;
+ border-color:#bbb;
+ border-style:solid;
+ border-collapse:collapse;
+}
+
+table td.memItemLeft {
+ width: 180px;
+ padding: 2px 0px 0px 8px;
+ margin: 4px;
+ border-width: 1px;
+ border-color: #E0E0E0;
+ border-style: none;
+ font-size: 100%;
+ white-space: nowrap
+}
+
+table td.memItemRight {
+ padding: 2px 8px 0px 8px;
+ margin: 4px;
+ border-width: 1px;
+ border-color: #E0E0E0;
+ border-style: none;
+ font-size: 100%;
+}
+
+table tr.odd {
+ background: #f0f0f0;
+ color: black;
+}
+
+table tr.even {
+ background: #e4e4e4;
+ color: black;
+}
+
+table.annotated th {
+ padding: 3px;
+ text-align: left
+}
+
+table.annotated td {
+ padding: 3px;
+}
+
+table tr pre
+{
+ padding-top: 0px;
+ padding-bottom: 0px;
+ padding-left: 0px;
+ padding-right: 0px;
+ border: none;
+ background: none
+}
+
+tr.qt-style
+{
+ background: #96E066;
+ color: black
+}
+
+body pre
+{
+ padding: 0.2em;
+ border: #e7e7e7 1px solid;
+ background: #f1f1f1;
+ color: black
+}
+
+table tr.qt-code pre
+{
+ padding: 0.2em;
+ border: #e7e7e7 1px solid;
+ background: #f1f1f1;
+ color: black
+}
+
+span.preprocessor, span.preprocessor a
+{
+ color: darkblue;
+}
+
+span.comment
+{
+ color: darkred;
+ font-style: italic
+}
+
+span.string,span.char
+{
+ color: darkgreen;
+}
+
+.title
+{
+ text-align: center
+}
+
+.subtitle
+{
+ font-size: 0.8em
+}
+
+.small-subtitle
+{
+ font-size: 0.65em
+}
+
+.qmlitem {
+ padding: 0;
+}
+
+.qmlname {
+ white-space: nowrap;
+ font-weight: bold;
+ font-size: 125%;
+}
+
+.qmltype {
+ font-weight: bold;
+ font-size: 125%;
+}
+
+.qmlproto, .qmldoc {
+ // border-top: 1px solid #84b0c7;
+}
+
+.qmlproto {
+ padding: 0;
+ //background-color: #e4e4e4;//#d5e1e8;
+ //font-weight: bold;
+ //-webkit-border-top-left-radius: 8px;
+ //-webkit-border-top-right-radius: 8px;
+ //-moz-border-radius-topleft: 8px;
+ //-moz-border-radius-topright: 8px;
+}
+
+.qmldoc {
+ border-top: 1px solid #e4e4e4;
+ //padding: 2px 5px;
+ //background-color: #eef3f5;
+ //border-top-width: 0;
+ //-webkit-border-bottom-left-radius: 8px;
+ //-webkit-border-bottom-right-radius: 8px;
+ //-moz-border-radius-bottomleft: 8px;
+ //-moz-border-radius-bottomright: 8px;
+}
+
+.qmldoc p, .qmldoc dl, .qmldoc ul {
+ //margin: 6px 0;
+}
+
+*.qmlitem p {
+ //margin-top: 0px;
+ //margin-bottom: 0px;
+}
diff --git a/doc/doc.pri b/doc/doc.pri
new file mode 100644
index 0000000..dcaa495
--- /dev/null
+++ b/doc/doc.pri
@@ -0,0 +1,51 @@
+# Adapted from doc/doc.pri in Qt Creator.
+
+QDOC_BIN = $$[QT_INSTALL_BINS]/qdoc3
+win32:QDOC_BIN = $$replace(QDOC_BIN, "/", "\\")
+
+unix {
+ QDOC = SRCDIR=$$PWD OUTDIR=$$OUT_PWD/doc/html QT_MOBILITY_SOURCE_PATH=$$QT_MOBILITY_SOURCE_PATH $$QDOC_BIN
+ HELPGENERATOR = $$[QT_INSTALL_BINS]/qhelpgenerator
+} else {
+ QDOC = set SRCDIR=$$PWD&& set OUTDIR=$$OUT_PWD/doc/html&& set QT_MOBILITY_SOURCE_PATH=$$QT_MOBILITY_SOURCE_PATH&& $$QDOC_BIN
+ # Always run qhelpgenerator inside its own cmd; this is a workaround for
+ # an unusual bug which causes qhelpgenerator.exe to do nothing
+ HELPGENERATOR = cmd /C $$replace($$list($$[QT_INSTALL_BINS]/qhelpgenerator.exe), "/", "\\")
+}
+
+QHP_FILE = $$OUT_PWD/doc/html/simulator.qhp
+QCH_FILE = $$OUT_PWD/doc/simulator.qch
+
+unix {
+html_docs.commands = $$QDOC $$PWD/simulator.qdocconf
+} else {
+html_docs.commands = \"$$QDOC $$PWD/simulator.qdocconf\"
+}
+html_docs.depends += $$PWD/simulator.qdoc $$PWD/scripting.qdoc $$PWD/simulator.qdocconf
+html_docs.files = $$QHP_FILE
+
+qch_docs.commands = $$HELPGENERATOR -o $$QCH_FILE $$QHP_FILE
+qch_docs.depends += html_docs
+qch_docs.files = $$QCH_FILE
+
+unix:!macx {
+ qch_docs.path = $$PREFIX/doc
+ qch_docs.CONFIG += no_check_exist
+ INSTALLS += qch_docs
+}
+
+macx {
+ DOC_DIR = "$${OUT_PWD}/bin/Simulator.app/Contents/Resources/doc"
+ cp_docs.commands = mkdir -p \"$${DOC_DIR}\" ; $${QMAKE_COPY} \"$${QCH_FILE}\" \"$${DOC_DIR}\"
+ cp_docs.depends += qch_docs
+ docs.depends = cp_docs
+ QMAKE_EXTRA_TARGETS += html_docs qch_docs cp_docs docs
+}
+!macx {
+ docs.depends = qch_docs
+ QMAKE_EXTRA_TARGETS += html_docs qch_docs docs
+}
+
+OTHER_FILES = $$PWD/simulator.qdoc \
+ $$PWD/scripting.qdoc \
+ $$PWD/simulator.qdocconf
diff --git a/doc/fixnavi.pl b/doc/fixnavi.pl
new file mode 100755
index 0000000..bf6acaa
--- /dev/null
+++ b/doc/fixnavi.pl
@@ -0,0 +1,70 @@
+#! /usr/bin/perl -w
+
+use strict;
+
+@ARGV == 1 or die "usage: $0 <qdoc-file>\n";
+my $file = $ARGV[0];
+open FILE, $file or die "File $file cannot be opened.\n";
+my @toc = ();
+my %title2page = ();
+my $doctitle = "";
+my $curpage = "";
+my $intoc = 0;
+while (<FILE>) {
+ if (keys(%title2page) == 1 && /^\h*\\list/) {
+ $intoc++;
+ } elsif (!$intoc) {
+ if (/^\h*\\page\h+(\H+)/) {
+ $curpage = $1;
+ } elsif (/^\h*\\title\h+(.+)$/) {
+ if ($curpage eq "") {
+ die "Title '$1' appears in no \\page.\n";
+ }
+ $title2page{$1} = $curpage;
+ $doctitle = $1 if (!$doctitle);
+ $curpage = "";
+ }
+ } else {
+ if (/^\h*\\endlist/) {
+ $intoc--;
+ } elsif (/^\h*\\o\h+\\l\h*{(.*)}$/) {
+ push @toc, $1;
+ }
+ }
+}
+close FILE;
+
+my %prev = ();
+my %next = ();
+my $last = $doctitle;
+for my $title (@toc) {
+ $next{$last} = $title2page{$title};
+ $prev{$title} = $title2page{$last};
+ $last = $title;
+}
+
+open IN, $file or die "File $file cannot be opened a second time?!\n";
+open OUT, '>'.$file.".out" or die "File $file.out cannot be created.\n";
+my $cutting = 0;
+while (<IN>) {
+ if (!$cutting) {
+ if (/^\h*\\contentspage/) {
+ $cutting = 1;
+ }
+ } else {
+ if (/^\h*\\title\h+(.+)$/) {
+ print OUT " \\previouspage ".$prev{$1} if ($prev{$1});
+ print OUT " \\page ".$title2page{$1};
+ print OUT " \\nextpage ".$next{$1} if ($next{$1});
+ print OUT "\n";
+ $cutting = 0;
+ } else {
+ next;
+ }
+ }
+ print OUT $_;
+}
+close OUT;
+close IN;
+
+rename($file.".out", $file) or die "Cannot replace $file with new version.\n";
diff --git a/doc/images/accelerometer-sensor.png b/doc/images/accelerometer-sensor.png
new file mode 100644
index 0000000..ef30d87
--- /dev/null
+++ b/doc/images/accelerometer-sensor.png
Binary files differ
diff --git a/doc/images/attitude-sensor.png b/doc/images/attitude-sensor.png
new file mode 100644
index 0000000..2b642d9
--- /dev/null
+++ b/doc/images/attitude-sensor.png
Binary files differ
diff --git a/doc/images/location-info.png b/doc/images/location-info.png
new file mode 100644
index 0000000..41ea01d
--- /dev/null
+++ b/doc/images/location-info.png
Binary files differ
diff --git a/doc/images/qt-creator-project-button.png b/doc/images/qt-creator-project-button.png
new file mode 100644
index 0000000..94eba95
--- /dev/null
+++ b/doc/images/qt-creator-project-button.png
Binary files differ
diff --git a/doc/images/qt-logo.png b/doc/images/qt-logo.png
new file mode 100644
index 0000000..3e2e480
--- /dev/null
+++ b/doc/images/qt-logo.png
Binary files differ
diff --git a/doc/images/qt-simulator-application.png b/doc/images/qt-simulator-application.png
new file mode 100644
index 0000000..5dd165d
--- /dev/null
+++ b/doc/images/qt-simulator-application.png
Binary files differ
diff --git a/doc/images/qt-simulator-battery.png b/doc/images/qt-simulator-battery.png
new file mode 100644
index 0000000..0fe17cd
--- /dev/null
+++ b/doc/images/qt-simulator-battery.png
Binary files differ
diff --git a/doc/images/qt-simulator-contacts.png b/doc/images/qt-simulator-contacts.png
new file mode 100644
index 0000000..3689374
--- /dev/null
+++ b/doc/images/qt-simulator-contacts.png
Binary files differ
diff --git a/doc/images/qt-simulator-devices.png b/doc/images/qt-simulator-devices.png
new file mode 100644
index 0000000..e6f0864
--- /dev/null
+++ b/doc/images/qt-simulator-devices.png
Binary files differ
diff --git a/doc/images/qt-simulator-drives.png b/doc/images/qt-simulator-drives.png
new file mode 100644
index 0000000..913f688
--- /dev/null
+++ b/doc/images/qt-simulator-drives.png
Binary files differ
diff --git a/doc/images/qt-simulator-generic-settings.png b/doc/images/qt-simulator-generic-settings.png
new file mode 100644
index 0000000..aa6f1e6
--- /dev/null
+++ b/doc/images/qt-simulator-generic-settings.png
Binary files differ
diff --git a/doc/images/qt-simulator-location.png b/doc/images/qt-simulator-location.png
new file mode 100644
index 0000000..88bc55d
--- /dev/null
+++ b/doc/images/qt-simulator-location.png
Binary files differ
diff --git a/doc/images/qt-simulator-messaging.png b/doc/images/qt-simulator-messaging.png
new file mode 100644
index 0000000..ac02f5d
--- /dev/null
+++ b/doc/images/qt-simulator-messaging.png
Binary files differ
diff --git a/doc/images/qt-simulator-network.png b/doc/images/qt-simulator-network.png
new file mode 100644
index 0000000..ae74c1e
--- /dev/null
+++ b/doc/images/qt-simulator-network.png
Binary files differ
diff --git a/doc/images/qt-simulator-quick-tour.png b/doc/images/qt-simulator-quick-tour.png
new file mode 100644
index 0000000..651c240
--- /dev/null
+++ b/doc/images/qt-simulator-quick-tour.png
Binary files differ
diff --git a/doc/images/qt-simulator-scripting.png b/doc/images/qt-simulator-scripting.png
new file mode 100644
index 0000000..cf816d0
--- /dev/null
+++ b/doc/images/qt-simulator-scripting.png
Binary files differ
diff --git a/doc/images/qt-simulator-search-advanced.png b/doc/images/qt-simulator-search-advanced.png
new file mode 100644
index 0000000..55fb83a
--- /dev/null
+++ b/doc/images/qt-simulator-search-advanced.png
Binary files differ
diff --git a/doc/images/qt-simulator-sensors.png b/doc/images/qt-simulator-sensors.png
new file mode 100644
index 0000000..bd151de
--- /dev/null
+++ b/doc/images/qt-simulator-sensors.png
Binary files differ
diff --git a/doc/images/qt-simulator-view-settings.png b/doc/images/qt-simulator-view-settings.png
new file mode 100644
index 0000000..89b4bc9
--- /dev/null
+++ b/doc/images/qt-simulator-view-settings.png
Binary files differ
diff --git a/doc/images/qt-simulator.png b/doc/images/qt-simulator.png
new file mode 100644
index 0000000..87cf626
--- /dev/null
+++ b/doc/images/qt-simulator.png
Binary files differ
diff --git a/doc/scripting.qdoc b/doc/scripting.qdoc
new file mode 100644
index 0000000..7cc3813
--- /dev/null
+++ b/doc/scripting.qdoc
@@ -0,0 +1,4 @@
+/*!
+ \class LocationScriptInterface
+ \brief Exposed as location.
+*/
diff --git a/doc/simulator.qdoc b/doc/simulator.qdoc
new file mode 100644
index 0000000..27b2ada
--- /dev/null
+++ b/doc/simulator.qdoc
@@ -0,0 +1,992 @@
+// **********************************************************************
+// NOTE: the sections are not ordered by their logical order to avoid
+// reshuffling the file each time the index order changes (i.e., often).
+// Run the fixnavi.pl script to adjust the links to the index order.
+// **********************************************************************
+
+/*!
+ \contentspage{index.html}{Simulator}
+ \page index.html
+ \nextpage simulator-description.html
+
+ \title Qt Simulator Manual
+
+ \section1 Version 0.9.0 (1.0.0 Beta)
+
+ With Qt Simulator, you can test Qt applications that are intended for
+ mobile devices in an environment similar to that of the device. You can
+ change the information that the device has about its configuration and
+ environment.
+
+ \image qt-simulator.png "Qt Simulator"
+
+ \note Please report bugs and suggestions to the
+ \l{http://bugreports.qt.nokia.com}{JIRA task tracker}.
+
+ \list
+ \o \l{Introducing Qt Simulator}
+ \o \l{Starting Qt Simulator}
+ \o \l{Quick Tour}
+ \o \l{Simulating Device Use}
+ \o \l{Simulating Networking}
+ \o \l{Simulating Location}
+ \o \l{Simulating Storage Devices}
+ \o \l{Importing Contacts}
+ \o \l{Simulating Messaging}
+ \o \l{Simulating Sensors}
+ \o \l{Testing Applications Using the Qt Mobility Service Framework}
+ \o \l{Interacting with Applications}
+ \o \l{Checking Application Layout}
+ \o \l{Scripting}
+ \o \l{Adding New Device Models}
+ \o \l{Known Issues}
+ \endlist
+*/
+
+/*!
+
+ \contentspage index.html
+ \previouspage simulator-starting.html
+ \page simulator-quick-tour.html
+ \nextpage simulator-generic.html
+
+ \title Quick Tour
+
+ This section describes the Qt Simulator interface and the most important tasks
+ that you can perform with Qt Simulator.
+
+ \image qt-simulator-quick-tour.png "Device Control dialog"
+
+ Qt Simulator displays a device with the application open on the screen. To interact with
+ the application, use the mouse and keyboard. To move the device window, drag the device
+ frame.
+
+ The \gui{Device Control} dialog provides the following controls:
+
+ \list
+
+ \o \gui{Quick access buttons} - Check how the application handles changes in device
+ state, such as battery level, network mode, signal strength, and power state. Run your
+ favorite scripts.
+
+ \o \gui{Device settings} - Adjust the properties of the simulated
+ device. To filter the list, enter a setting name into the search
+ field. Click the buttons next to the tabs to show advanced and rarely used settings.
+
+ \image qt-simulator-search-advanced.png "Search field and Advanced settings button"
+
+ \o \gui{Application settings} - Manage applications running on Qt Simulator.
+
+ \image qt-simulator-application.png "Application view"
+
+ \o \gui{View settings} - See how the application looks on different devices.
+ Change the device to be simulated, rotate the device, or change the display
+ resolution and size. Move the zoom slider to the left to scale the device
+ to its real size and to the right to make each device pixel correspond to
+ a pixel of your screen.
+
+ \image qt-simulator-view-settings.png "View settings"
+
+ \endlist*/
+
+/*!
+
+ \contentspage index.html
+ \previouspage simulator-description.html
+ \page simulator-starting.html
+ \nextpage simulator-quick-tour.html
+
+ \title Starting Qt Simulator
+
+ You can start Qt Simulator directly from Qt Creator to quickly test and debug
+ applications:
+
+ \list 1
+
+ \o Create a Qt Creator project.
+
+ \o In the \gui{Projects} mode, \gui{Build Settings}, click \gui{Add} to
+ add a new build configuration.
+
+ \o In the \gui{Configuration Name} field, enter a name for the configuration.
+
+ \o In the \gui{Qt Version} field, select the Simulator Qt version.
+
+ \o Click \gui{Make Active} to activate the new build configuration.
+
+ \o Click the \gui{+} button to add \gui{Simulator} as a target.
+
+ \o Click the \gui{Play} button to build and run the application.
+
+ \endlist
+
+ \section1 Switching Between Build Configurations
+
+ To switch between build configurations in Qt Creator, click the \gui{Project}
+ button and select a project:
+
+ \image qt-creator-project-button.png "Project button"
+
+ The button shows the name of your project and the
+ currently active build configuration.
+
+*/
+
+
+
+/*!
+ \contentspage index.html
+ \previouspage simulator-quick-tour.html
+ \page simulator-generic.html
+ \nextpage simulator-networking.html
+
+ \title Simulating Device Use
+
+ \image qt-simulator-generic-settings.png "Generic settings"
+
+ You can use Qt Simulator to test applications that use the Qt System Info API to
+ access general information from the mobile device.
+ Mobile devices have been designed for use when mobile. Keep the characteristics of
+ mobile devices in mind when you create applications for them. Use Qt Simulator to
+ simulate the behavior of applications on different device models in different
+ conditions:
+
+ \list
+
+ \o \l{Running Out of Battery Power}
+ \o \l{Using Silent and Offline Profiles}
+ \o \l{Changing Device Language}
+ \o \l{Supporting Device Features}
+ \o \l{Accessing Services}
+ \o \l{Handling User Input}
+ \o \l{Identifying Devices}
+ \o \l{Using Colors}
+ \omit \o \l{Turning off Screen Saver} \endomit
+
+ \endlist
+
+ \section1 Running Out of Battery Power
+
+ Mobile devices are not constantly connected to a power outlet, but run on battery power.
+ Optimize power consumption to keep the total consumption at an acceptable level and to
+ prevent users from running out of battery power. In addition, make sure that applications
+ run successfully in low-memory condition or display a clear and informative error message.
+
+ You can write a script that decreases the battery level setting, to check how applications
+ behave when the device runs out of power. You can load an example script that decreases the
+ value for battery level, \tt{scripts/examples/runOutOfBattery.qs}.
+ For more information on loading scripts, see \l{Scripting}.
+
+ You can also check how applications behave, when the mobile device is connected to a
+ power outlet or it is charging.
+
+ Change the \gui{Battery level} and \gui{Power state} settings in the \gui{Generic}
+ section.
+
+ \section1 Using Silent and Offline Profiles
+
+ Profiles allow users to adjust and customize ringing tones, alert tones, and other
+ mobile device tones for different events, environments, or caller groups. Users can
+ change the active profile on their devices.
+
+ The \gui{Offiline} profile (flight mode) prevents mobile devices from accidentally
+ switching on, sending, or receiving messages, or using WLAN, Bluetooth, GPS, or
+ FM radio. In addition, it closes any Internet connection that may be in operation
+ when users select the profile.
+
+ Test applications with different profiles to make sure that:
+
+ \list
+
+ \o Application sounds do not override the currently selected profile. Sounds
+ should not play in the \gui{Silent} profile, unless the application is intended for
+ audio playback.
+
+ \o Applications work correctly in the \gui{Offline} profile, with the
+ phone capabilities and network connections disabled.
+
+ \endlist
+
+ In the \gui {Generic} section, \gui{Profile} field, select profiles to test the application with a
+ particular profile.
+
+ \section1 Changing Device Language
+
+ Implement predefined texts in the application UI using logical names instead of
+ hard-coding them to the application. This enables localization by changing the
+ language packet (LOC file) that is used.
+
+ After translation, UI texts in different languages may take up more space than the original
+ text. To prepare for text expansion, avoid using long and difficult UI text.
+
+ Do not truncate the predefined UI texts even if the components may do it automatically.
+ This makes it difficult to understand the texts and creates a feeling of unfinished
+ software.
+
+ You can fine-tune UI text strings to different display sizes by producing
+ separate text strings for the small and large displays (orientation, aspect ratio,
+ physical size). This avoids the problem of having abbreviated text strings when there
+ is plenty of display space available.
+
+ When users change the language settings on the mobile device, the localized version should
+ be started automatically.
+
+ Click the \gui{Advanced Settings} button to display the language settings in the
+ \gui{Generic} section:
+
+ \list
+
+ \o \gui{Language} displays the current system language as a two-letter ISO 639-1
+ language code. For example, EN.
+
+ \o \gui{Country code} displays the current system country code as a two-letter
+ ISO 3166-1 country code.
+
+ \o \gui{Available languages} displays available Qt language translations as two-letter
+ ISO 639-1 language codes. If translations cannot be found, it displays the current system
+ language.
+
+ \endlist
+
+ Change the \gui{Language} and \gui{Country code} settings
+ to test that the localized versions of your application start correctly and look
+ and function as they should.
+
+ Click \gui{Show} next to \gui{Available languages}, and then click \gui Add to add new
+ language codes. Use the ISO 639-1 language codes.
+
+ \omit ### Is a link to the country code list needed here? \endomit
+
+ \section1 Supporting Device Features
+
+ Mobile devices support different sets of device features, depending on their configuration
+ and the underlying hardware. When you develop applications for multiple devices, you can
+ programmatically determine which platform, software version, languages, features, and
+ accessories a particular device supports. This allows you to programmatically enable and
+ disable application functions for a particular device.
+
+ Change the \gui{Features} in the \gui{Generic} section to check how your
+ application behaves when a particular device feature is supported or not supported.
+ For example, devices can support several physical connection methods, such as \gui{Bluetooth},
+ \gui{Infrared}, and \gui{USB} (universal serial bus) for downloading data. Devices can also
+ have a \gui{Memory Card} available for storing the data.
+
+ Change the \gui{Operating System}, \gui{Qt}, and \gui{Firmware} \gui{Versions} to check
+ how your application behaves on a specific version. Click \gui{Change} to specify the
+ version. Specify firmware versions as follows:
+ \bold major.minor.build. If a particular version does not include the build part, set it to 0.
+ If a particular element is not available at all, the API returns the error
+ \bold {Not Installed}.
+
+ \section1 Accessing Services
+
+ The basis for access security is the effective identification of the users and the
+ equipment they are using. The device can be protected with a lock code, while the
+ SIM card, memory card, and applications can have their own PIN codes and passwords.
+ For enterprise applications, this can mean that only a specific user with a specific
+ application, device, memory card, and SIM card can access the corporate data.
+
+ Devices are identified by international mobile equipment identity (IMEI) and
+ international mobile subscriber identity (IMSI) numbers. Change the \gui{IMEI} and
+ \gui{IMSI} numbers in the \gui{Generic} section to test access security for
+ applications.
+
+ \section1 Handling User Input
+
+ In order to support as many target devices as possible, applications must support
+ different input control configurations:
+
+ \list
+
+ \o Hardware keypad and touch
+
+ \o Touch-only
+
+ \o Hardware keypad only
+
+ \endlist
+
+ For devices that support both hardware keypad and touch interactions, consider which
+ is the best mode of interaction for the application. For touch-only devices, all
+ interactions should naturally be touch-optimised.
+
+ For devices that support only the hardware keypad, touch-only components can be
+ flagged out of the application. This way it is possible to create applications that
+ will function with different device configurations.
+
+ Change the \gui{Input methods} in the \gui{Generic} section to test how
+ the application handles different input methods.
+
+ \section1 Identifying Devices
+
+ You can specify the \gui{Manufacturer}, \gui{Model}, and \gui{Product name} to
+ allow applications to identify the device. You can write any values in the fields.
+ For example, you could set \gui{Manufacturer} to \bold {Nokia} and \gui{Model} to \bold {N97}.
+
+ \section1 Using Colors
+
+ Like computer monitors, mobile devices use an additive color process. Unlike print
+ media, which begin with a white surface, the computer screen begins as a black surface
+ to which colored light red, green, and blue (RGB) is added.
+
+ Although early mobile devices supported very few colors, color support is now quite
+ robust, with a large proportion of devices providing 12-bit (4,096 colors),
+ 16-bit (65,536 colors), or 24-bit (16 million colors) color support. However,
+ similar to the variety in screen size, many devices in use support varying color depths,
+ with newer, low-cost models typically supporting 12- or 16-bit color depths.
+
+ Applications can query the color scheme of the mobile device and adapt to it. For
+ example, applications can switch to a night color scheme when brightness falls
+ below a certain value.
+
+ Change the \gui{Color depth} and \gui{Brightness} values in the \gui{Generic}
+ section to change the way the application perceives them.
+
+ \omit
+
+ \section1 Turning off Screen Saver
+
+ Applications can turn off the screen saver on the mobile device. However, if the screen
+ saver is secure by policy, the policy is be honored and screen saver cannot be
+ turned off.
+
+ As a rule, do not override screen saver settings because they work automatically
+ according to user-set preferences. The application can monitor the screen saver status
+ to detect whether the device is in active use.
+
+ You can override the settings in special cases, such as in a navigation
+ application. However, the application should monitor the device status to check
+ whether the prerequisites are still valid. For example:
+
+ \list
+
+ \o Is the device connected to a power supply (charger or car kit)?
+ \o Does the application require lights on the foreground?
+ \o Is the battery level sufficient?
+
+ \endlist
+
+ Select the \gui {Screen saver inhibited} check box in the \gui {Generic} section
+ to turn off the screen saver.
+
+ \endomit
+
+*/
+
+/*!
+ \contentspage index.html
+ \previouspage simulator-generic.html
+ \page simulator-networking.html
+ \nextpage simulator-location.html
+
+ \title Simulating Networking
+
+ Mobile applications can be divided into stand-alone and client-server applications.
+ However, the difference is not always clear. Stand-alone applications may offer the
+ possibility to refresh or update information from a server, and client-server
+ applications may store recent information on the device, thus enabling use of the
+ application without server connection.
+
+ Additionally, connection to a server can be established through a variety of services,
+ such as Bluetooth, WLAN, or the mobile network. If possible, the application should use
+ the most sensible connection method, such as a WLAN for internet connection, when
+ available.
+
+ Hide the complexity of network connectivity in your applications. Short network coverage
+ problems should not cause loss of users' work or stop them from working. Connection
+ status should be displayed clearly. Synchronization should be automatic but under user
+ control.
+
+ When users move around with their mobile device, the device connects to
+ available cells with sufficient signal strength. You can change the network settings to
+ test how the application handles roaming from one cell or network to another.
+
+ You can use Qt Simulator to test applications that use the Qt Bearer Management API
+ to manage the connectivity state to the network.
+ Change the \gui{Network mode properties}, such as \gui{Status} and
+ \gui{Signal strength} in the \gui{Network} section.
+
+ \image qt-simulator-network.png "Network settings"
+
+ You can also load the \c sysinfonetwork.qs example script to test how your
+ application behaves when the device moves between cells with varying signal strength
+ in a GSM network. For more information on loading scripts, see \l{Scripting}.
+
+*/
+
+/*!
+ \contentspage index.html
+ \previouspage simulator-networking.html
+ \page simulator-location.html
+ \nextpage simulator-drives.html
+
+ \title Simulating Location
+
+ Applications can use the Qt Location API to access basic geographical information
+ obtained from satellite or other sources about the user, including latitude and
+ longitude, bearing, speed and altitude. This allows you to develop a range of
+ geographical applications, for example, maps.
+
+ Location-based services (LBS) use coordinates from the world geodetic system (WGS 84),
+ which is also used as a reference system by the global positioning system (GPS).
+ The coordinates are based on values for latitude, longitude, and altitude (elevation
+ above sea level).
+
+ The North Pole is 90 degrees North (+90 degrees) and the South Pole is 90 degrees South
+ (-90 degrees). The Equator is defined as 0 degrees; locations above it have positive
+ latitudes (0 to +90 degrees); those below (0 to -90 degrees) negative ones.
+
+ There are two definitions of North Pole; Magnetic North Pole and True (Geographical)
+ North Pole. Any application with a compass must check how the API defines North Pole.
+
+ The Magnetic North Pole is the point to which compasses point. The True North Pole
+ defines latitude as +90 degrees.
+
+ Meridians are constant longitudinal (north-south) values. The Prime (Greenwich)
+ Meridian's value is 0 degrees. WGS84, which LBS use, defines its zero meridian some
+ 100 meters east of the Prime one. Locations east of the Prime Meridian have positive
+ longitudinal values (0 to +180 degrees), those west (0 to -180 degrees) have negative
+ ones.
+
+ Latitude lines are smaller near the poles. At the equator, one degree of longitude
+ is roughly 111.3 km, whereas at 60 degrees of latitude one degree of longitude is
+ only 55.8 km.
+
+ \image location-info.png
+
+ GPS connections can consume the battery power rapidly, so you should take this into
+ account when designing applications that access this functionality.
+
+ To test an application that uses LBS, specify values for \gui{Latitude},
+ \gui{Longitude}, and \gui{Altitude} in the \gui{Location} section.
+
+ \image qt-simulator-location.png "Location settings"
+
+*/
+
+/*!
+ \contentspage index.html
+ \previouspage simulator-location.html
+ \page simulator-drives.html
+ \nextpage simulator-contacts.html
+
+ \title Simulating Storage Devices
+
+ One or several storage devices, such as memory cards, can be added to mobile devices to increase the available
+ storage space. Devices may also have internal non-removable memory cards or internal mass
+ storage. That is, multiple drives are supported.
+
+ Applications can use the Qt System Info API to check how much space is available in a
+ particular storage. To test the applications, specify
+ the space available on the device in the \gui{Available space} field in
+ \gui{Storage Properties} in the \gui{Storage} section.
+
+ \image qt-simulator-drives.png "Storage settings"
+
+*/
+
+/*!
+ \contentspage index.html
+ \previouspage simulator-drives.html
+ \page simulator-contacts.html
+ \nextpage simulator-messaging.html
+
+ \title Importing Contacts
+
+ You can use Qt Simulator to test applications that use the Qt Contacts API to access
+ address book information. The applications can create, edit, list, delete, and look up
+ contact information whether it is stored locally or remotely.
+
+ You can use the predefined contacts in the \gui{Contacts} section to test applications. Click
+ \gui{Import} to import new contact information from vCard files (\c {.vcf}).
+
+ \image qt-simulator-contacts.png "Contacts"
+
+ The initial contact list is created from the data in \tt{stubdata/standardcontacts.vcf}
+ during Qt Simulator startup. The 'self' contact is read from
+ \tt{stubdata/standardselfcontact.vcf}.
+*/
+
+/*!
+ \contentspage index.html
+ \previouspage simulator-application.html
+ \page simulator-views.html
+ \nextpage simulator-scripting.html
+
+ \title Checking Application Layout
+
+ Unlike PC displays, which have standardised to two or three common sizes,
+ mobile phone displays still come in many shapes and sizes. The screens have
+ grown larger, while smaller screens still exist at the lower end of the market.
+ Displays typically support both portrait and landscape modes.
+
+ The screen size of mobile devices is significantly smaller than that available
+ on desktop devices. Carefully consider what is the most relevant content to
+ present on the application UI, as it might not be reasonable to try and fit as
+ much content into the screen as you might have in a desktop application.
+
+ Relate the position and size of widgets to the dimensions of the display.
+ This enables the same set of information to be presented on the screen in all
+ resolutions; higher resolution devices just display finer graphics.
+
+ Change the settings in the \gui{View} section to check application
+ layout.
+
+ \image qt-simulator-view-settings.png "View settings"
+
+ \section1 Changing Device Models
+
+ Each unique mobile device targets a different market niche, a combination of form,
+ functionality, and price, which expands the total addressable market for mobile
+ applications. The characteristics of your target devices, such as screen size and
+ orientation, touch support, and the availability of a keyboard or home screen, affect
+ application design.
+
+ In the \gui{Device} field, select different device models to test the application
+ on them.
+
+ \section1 Rotating Devices
+
+ Rotation changes the orientation of the primary display between portrait and
+ landscape. Rotation is effected by a sensor or is specifically disabled in the
+ device configuration. Additionally, you can disable rotation in applications
+ by using the forced orientation application property.
+
+ By default, all applications can present in portrait or landscape orientation.
+ Based on the product ID, one orientation is considered dominant. Because most
+ application software must deploy to multiple devices, ensure that your
+ application layout is properly usable in both orientations.
+
+ Click \gui{Rotate Device} to change the orientation of the display between
+ portrait and landscape.
+
+ \section1 Changing Screen Resolution
+
+ In addition to the display size in pixels, physical screen dimensions have an
+ impact on designs. Devices with the same size display can vary in physical
+ dimensions and, consequently, in screen resolution. The implications are most
+ obvious on images, particularly on those that contain graphic text or fine details.
+ For example, on devices that share a 240-pixel screen width, a logo that is legible
+ at 154 pixels per inch may be somewhat less so at 199 pixels per inch.
+
+ You can use Qt Simulator to ensure that screens designed on a large computer monitor
+ are suitable once transferred to a mobile device and that critical visual elements
+ remain legible at all supported screen sizes.
+
+ Move the \gui{Zoom} slider to the left to scale the device to its real size and to the
+ right to make each device pixel correspond to a pixel on the screen. However, Windows
+ always reports the DPI of the screen as 96 pixels per inch, and therefore, Qt Simulator
+ cannot reliably detect the DPI of the screen. The same problem might arise on some Linux systems
+ that use a fixed value for the DPI.
+
+ Click the \gui {Advanced Settings} button to make the \gui {Native size}
+ setting match the real size of the device. In the \gui Configuration dialog,
+ you can use the following approaches
+ to scale the screen to the correct size:
+
+ \list
+
+ \o In the \gui {Diagonal in inches} field, enter the diagonal of the display
+ in inches.
+
+ \o In the \gui {Manual Correction} group, place a ruler next to the line,
+ and then move the slider to the 10 inch or 4 centimeter mark on the ruler.
+
+ \o In the \gui {Correction Factor} field, enter a value to scale the
+ screen. This value is adjusted automatically when you edit the other
+ fields.
+
+ \endlist
+
+ Qt Simulator scales fonts according to the screen DPI. Always specify font size in points,
+ not pixels, to have them scaled correctly on different screen sizes.
+
+ \omit ### Add an image of a screen in both ends of the scale\endomit
+
+
+
+*/
+
+/*!
+ \contentspage index.html
+ \previouspage index.html
+ \page simulator-description.html
+ \nextpage simulator-starting.html
+
+ \title Introducing Qt Simulator
+
+ Qt Simulator allows you to quickly test and debug applications that
+ target mobile devices, without the overhead of emulating the device
+ at hardware level. It provides special versions of the Qt and
+ Qt Mobility libraries that forward the display and settings to it.
+
+ You can link applications that use the Qt and Qt Mobility APIs to these
+ libraries to run them inside Qt Simulator. This allows you to see how applications
+ look and function on different devices in different situations. For example, you can
+ view the application layout on Symbian and Maemo devices, in both landscape and
+ portrait orientation. Or you can check how your application behaves when
+ device battery power decreases to low or critical level.
+
+ \image qt-simulator-devices.png "Symbian non-touch and Maemo devices"
+
+ Qt Simulator does not support any device specific APIs by design. Therefore,
+ applications that run well on Qt Simulator also run on any device that hosts the
+ Qt and Qt Mobility libraries.
+
+ The following Qt Mobility components are supported:
+ \list
+ \o \l{http://qt.nokia.com/doc/qtmobility-1.0-beta/bearer-management.html}{Bearer Management}
+ \o \l{http://qt.nokia.com/doc/qtmobility-1.0-beta/contacts.html}{Contacts}
+ \o \l{http://qt.nokia.com/doc/qtmobility-1.0-beta/location-overview.html}{Location}
+ \o \l{http://qt.nokia.com/doc/qtmobility-1.0-beta/messaging.html}{Messaging}
+ \o \l{http://qt.nokia.com/doc/qtmobility-1.0-beta/publ-subs.html}{Publish and Subscribe}
+ \o \l{http://qt.nokia.com/doc/qtmobility-1.0-beta/service-frameworks.html}{Qt Service Framework}
+ \o \l{http://qt.nokia.com/doc/qtmobility-1.0-beta/sensors-api.html}{Sensors}
+ \o \l{http://qt.nokia.com/doc/qtmobility-1.0-beta/systeminfo.html}{System Information}
+ \o \l{http://qt.nokia.com/doc/qtmobility-1.0-beta/versit.html}{Versit}
+ \endlist
+*/
+
+/*!
+ \contentspage index.html
+ \previouspage simulator-views.html
+ \page simulator-scripting.html
+ \nextpage simulator-adding-models.html
+
+ \title Scripting
+
+ The Qt Simulator JavaScript interface enables you to automate recurring
+ sets of changes or to simulate a continuously changing environment.
+
+ \image qt-simulator-scripting.png "Scripting"
+
+ \section1 Locating Scripts
+
+ Create a script (.js or .qs) that sets the device to its desired state when you
+ open an application in Qt Simulator. Place the script in the \tt{scripts/autostart/}
+ folder to run it automatically when Qt Simulator starts.
+
+ You can then use the \gui{Device Control} dialog to change the default
+ settings according to your test cases. To run the same tests repeatedly
+ or to test complicated sequences of events, create scripts and place them in
+ the \tt{scripts} folder.
+
+ Place you favorite scripts in the \tt{scripts/favorites/} folder.
+
+ Example scripts are located in \tt{scripts/examples/}.
+
+ \section1 Running Scripts
+
+ To run a script:
+
+ \list 1
+
+ \o Click the \gui{JS} quick access button to
+ bring up a list of scripts in the \tt{scripts/favorites/} folder.
+
+ \o Double-click a script in the \gui{Scripting} tab that shows
+ the scripts in the \tt{scripts/} folder.
+
+ \o Place a script in the \tt{scripts/autostart} folder to run it when Qt Simulator
+ starts.
+
+ \o Add the \c {-runscript <script file>} parameter to a call of the Qt Simulator application
+ on the command line to trigger the execution of a script in the currently running Qt Simulator
+ instance externally.
+
+ \endlist
+
+ The \gui{Active scripts} field shows a list of currently active scripts.
+ To pause or resume a script, select it and click \gui{Pause}. To abort a script,
+ select it and click \gui{Abort}.
+
+
+ \section1 Function Reference
+
+ The following objects and functions are added to the common JavaScript global scope:
+ \list
+ \o yield(ms): delay execution of this script for the given number of milliseconds
+ \o simulator: \l{SimulatorScriptInterface}
+ \o location: \l{LocationScriptInterface}
+ \o sensors: \l{SensorsScriptInterface}
+ \o sysinfo.generic: \l{GenericSystemInfoScriptInterface}
+ \o sysinfo.network: \l{NetworkSystemInfoScriptInterface}
+ \o sysinfo.storage: \l{StorageSystemInfoScriptInterface}
+ \endlist
+*/
+
+/*!
+ \contentspage index.html
+ \previouspage simulator-scripting.html
+ \page simulator-adding-models.html
+ \nextpage simulator-known-issues.html
+
+ \title Adding New Device Models
+
+ Qt Simulator contains predefined configuration files for several Nokia devices.
+ You can add devices by creating configuration files that specify the screen
+ size. That is, the size of the area on which Qt Simulator draws the
+ application. You can also add an image of the device in PNG format.
+ In the configuration file, specify the position of the screen within the image.
+
+ The graphics and settings for the device models are stored in the \c {models/}
+ folder next to your Qt Simulator executable. To add a new device, create a subfolder
+ and put a \c {\<your device name\>.config} file into it. It is easiest to
+ copy and modify one of the existing files.
+
+ Device configuration files have a key:value syntax, with the following valid keys:
+ \list
+ \o \c {name:\<string\>} - required. Name to show in the device selection
+ drop down menu.
+
+ \o \c {resolutionWidth:\<integer\>} - required. Width of the device screen.
+
+ \o \c {resolutionHeight:\<integer\>} - required. Height of the device screen.
+
+ \o \c {diagonalInInch:\<float\>} - required. Length of the screen diagonal
+ in inches.
+
+ \o \c {mockup:\<path\>} - required. Path to the image for the device.
+ Relative to the \c{.config} file.
+
+ \o \c {offsetX:\<integer\>} - required. Offset of the screen top left
+ corner from the top left corner of the mockup image.
+
+ \o \c {offsetY:\<integer\>} - required. Offset of the screen top left
+ corner from the top left corner of the mockup image.
+
+ \o \c{defaultFontSize:\<integer\>} - optional (default: 12). Font size the
+ device uses if it is not set explicitly.
+
+ \o \c {forceDpi:\<integer\>} - optional. Renders the screen by using
+ this DPI value instead of the physical DPI computed from the
+ \c {diagonalInInch} value.
+
+ \o \c {style:\<string\>} - optional. Use this Qt style for applications running
+ in Qt Simulator.
+
+ \o \c {button:\<key name\>,\<key text\>,\<x\>,\<y\>,\<width\>,\<height\>} -
+ optional, may be used more than once. When the user clicks inside the
+ rectangle defined by \c {x,y,width,height} send the key specified by \c {key name} and
+ \c {key text} to the application. \c {key name} must be the name of a value in the
+ Qt::Keys enum. \c {key text} is the value the \c {text()} member of the generated
+ QKeyEvent returns.
+ \endlist
+
+ In addition to that, it is possible to run a script whenever your device is chosen in the
+ device selection. Therefore just add a file named
+ <name of your device (given in the .config file)>.qs to \c {scripts/devices}.
+*/
+
+/*!
+ \contentspage index.html
+ \previouspage simulator-adding-models.html
+ \page simulator-known-issues.html
+
+ \title Known Issues
+
+ In Linux, if hardware acceleration for graphics is not available, black
+ corners appear around the device and the background turns black when rotating
+ the device.
+*/
+
+/*!
+ \contentspage index.html
+ \previouspage simulator-contacts.html
+ \page simulator-messaging.html
+ \nextpage simulator-sensors.html
+
+ \title Simulating Messaging
+
+ The term messaging comprises text messaging, picture messaging, multimedia messaging,
+ instant messaging, and e-mail. Text messaging is enabled by the Short Message Service (SMS).
+ When providing email services to mobile device users, mobile devices rely upon the services
+ provided by remote e-mail servers. They support the POP3, IMAP4 and SMTP protocols for
+ connecting to these servers.
+
+ You can use Qt Simulator to test applications that use the Qt Mobility Messaging API to
+ access messaging services to search and sort messages, notify of changes to messages stored,
+ send messages with or without attachments, retrieve message data, and launch the preferred
+ messaging client to either display an existing message, or compose a message.
+
+ In the \gui{Messaging} section, click \gui {Trigger} to trigger incoming email or SMS from
+ a random person in the contact list.
+
+ \image qt-simulator-messaging.png "Messaging section"
+
+ Click \gui{Import} to import a whole
+ directory of email messages that are stored in maildir format.
+
+ During startup, Qt Simulator imports the directory \tt{stubdata/standardmessages/}.
+
+*/
+
+/*!
+ \contentspage index.html
+ \previouspage simulator-messaging.html
+ \page simulator-sensors.html
+ \nextpage simulator-serviceframework.html
+
+ \title Simulating Sensors
+
+ Mobile devices contain built-in sensors, such as an accelerometer, a compass, and ambient
+ light or proximity sensors. The availability of sensors depends on the device model.
+
+ The following types of interaction can be enabled by using the sensors on the device:
+
+ \list
+
+ \o Changing application settings based on the ambient light conditions, such as
+ bright sunshine or night time.
+
+ \o Changing the screen orientation on the device from portrait to landscape as
+ the device is rotated.
+
+ \o Silencing an incoming call when the device orientation is changed (for example, on a
+ table) from screen down to screen up and back again.
+
+ \o Allowing movement gestures, such as device rotation, to trigger an action.
+
+ \o In a map application, changing the orientation of a map based on the device
+ compass orientation.
+
+ \o Triggering an action when the device comes in close proximity to the user's hand
+ or head.
+
+ \endlist
+
+ You can test applications that use the Qt Mobility Sensors API in the Qt Simulator.
+ The \gui{Sensors} section contains controls to set the values the sensors currently
+ return.
+
+ \image qt-simulator-sensors.png "Sensors section"
+
+ \section1 Changing Light Conditions
+
+ Specify the ambient light state in the \gui {Ambient light} field.
+
+ \section1 Device Movement
+
+ The accelerometer sensor channel detects movement gestures, such as moving a mobile
+ device up or down. The three-dimensional Cartesian coordinate system is used to
+ illustrate direction of the acceleration, as shown in the figure below. The x and y axes
+ define a plane where z-axis direction is perpendicular to the xy plane. When a device moves
+ along an axis in the positive direction, the acceleration is positive. When the device
+ moves in the negative direction, the acceleration is negative. For example, when a device
+ moves along the x-axis to the direction of -x, the acceleration is negative.
+
+ \image accelerometer-sensor.png
+
+ A mobile device placed screen up on a desk experiences a force of approximately 9.8 on
+ the z axis (that is, upwards). This is the proper acceleration the device experiences
+ relative to freefall.
+
+ To simulate movement of the device, use the sliders to specify values for the x, y,
+ and z axis in the \gui {Accelerometer x}, \gui {Accelerometer y}, and \gui {Accelerometer z}
+ fields.
+
+ \section1 Device Rotation
+
+ The attitude sensor detects the rotation of the device around the x, y, or z axis:
+
+ \list
+
+ \o Pitch of the device is the rotation around the x axis
+ \o Roll is the rotation around the y axis
+ \o Yaw is the rotation around the z axis
+
+ \image attitude-sensor.png
+
+ \endlist
+
+ Pitch and roll are zero (0) when the phone lies flat, screen up. Yaw is 0 when the top of the
+ device points towards the reference point. Yaw requires a fixed, external reference point
+ that the device can detect. For example, devices with a compass may use magnetic north as a
+ reference point. Devices that cannot detect a fixed, external reference point always
+ return 0 for yaw.
+
+ Use the sliders to set the \gui {Attitude pitch}, \gui {Attitude roll}, and
+ \gui {Attitude yaw} values to test how the application handles the interaction
+ related to rotating the device.
+
+ \section1 Compass Orientation
+
+ The compass returns the azimuth of the device as degrees from magnetic north in a clockwise
+ direction based on the top of the device.
+
+ \note The top of the device is a fixed point and may not represent the orientation that the
+ user is holding the device in.
+
+ The calibration status of the device must be accurate for the azimuth to be accurate.
+ It takes some time to calibrate the magnetic north sensor and, even after being calibrated,
+ it can become uncalibrated. So, for an application to be sure the data coming from the magnetic
+ north sensor channel is accurate, it must monitor changes in the calibration property and
+ inform the user if something needs to be done to recalibrate the sensor.
+
+ Use sliders to set the \gui {Compass calibration level} and \gui {Compass azimuth} values.
+
+ \section1 Proximity
+
+ Proximity indicates how far away from the device the user is. Use the button to toggle between
+ \gui {Near} and \gui {Far} distance.
+
+ \section1 Using a Fixed Timestamp
+
+ Many sensors update frequently, and therefore sensor readings done by the client
+ application contain a fresh timestamp by default. To disable that and provide a fixed timestamp
+ manually, select the \gui Override radio button in the \gui Timestamp group and specify
+ a date and time.
+
+*/
+
+/*!
+ \contentspage index.html
+ \previouspage simulator-sensors.html
+ \page simulator-serviceframework.html
+ \nextpage simulator-application.html
+
+ \title Testing Applications Using the Qt Mobility Service Framework
+
+ The \l{http://qt.nokia.com/doc/qtmobility-1.0-beta/service-frameworks.html}{Qt Service Framework}
+ defines a unified way of finding, implementing and accessing services across multiple
+ platforms.
+
+ A service is an independent component that allows a client to perform a well-defined
+ operation. Clients can find services based on their name and version as well as the
+ interface that is implemented by the service object. Once the service has been identified,
+ the framework starts the service and returns a pointer to it. Services are implemented as plugins.
+
+ You can use the service framework to unify and access multiple platform specific service
+ implementations via the same Qt-based client application. However,
+ the service database is not shared between desktop applications and applications compiled
+ for the Qt Simulator. Therefore, to test client applications using the service framework
+ on Qt Simulator, you must use the \c{servicefw} command-line application
+ \omit Ship it! Path? \endomit to register a service.
+
+ To tell Qt where to look for plugins, either add them to the search path by calling
+ QCoreApplication::addLibraryPath() or set the QT_PLUGIN_PATH.
+*/
+
+
+/*!
+ \contentspage index.html
+ \previouspage simulator-serviceframework.html
+ \page simulator-application.html
+ \nextpage simulator-views.html
+
+ \title Interacting with Applications
+
+ You can run several applications simultaneously in Qt Simulator. They can be managed
+ in the \gui Applications view.
+
+ \image qt-simulator-application.png "Application view"
+
+ The title of the active application is displayed in the \gui {Topmost widget's title}
+ field.
+
+ To test menu commands, click them in the \gui {Application's menu bar} field.
+ The actions are simulated on the device screen.
+
+ To quit the active application, click \gui Quit.
+
+*/
diff --git a/doc/simulator.qdocconf b/doc/simulator.qdocconf
new file mode 100644
index 0000000..f67be6f
--- /dev/null
+++ b/doc/simulator.qdocconf
@@ -0,0 +1,222 @@
+# Run qdoc from the directory that contains this file.
+
+project = simulator
+description = "Qt Simulator Manual"
+
+headers = \
+ $$SRCDIR/../src/ui/sensorsui.h \
+ $$SRCDIR/../src/ui/systeminfogenericui.h \
+ $$SRCDIR/../src/ui/systeminfostorageui.h \
+ $$SRCDIR/../src/ui/systeminfonetworkui.h \
+ $$SRCDIR/../src/ui/configurationwidget.h \
+ $$SIMULATOR_DEPENDENCY_PATH/include/remotecontrolwidget/locationui.h
+sources = \
+ $$SRCDIR/../src/ui/sensorsui.cpp \
+ $$SRCDIR/../src/ui/systeminfogenericui.cpp \
+ $$SRCDIR/../src/ui/systeminfostorageui.cpp \
+ $$SRCDIR/../src/ui/systeminfonetworkui.cpp \
+ $$SRCDIR/../src/ui/configurationwidget.cpp
+headerdirs =
+sourcedirs = $SRCDIR
+imagedirs = $SRCDIR/images
+outputdir = $OUTDIR
+exampledirs = $SRCDIR
+indexes = qt.index
+
+extraimages.HTML = qt-logo
+
+sources.fileextensions = "simulator.qdoc scripting.qdoc"
+
+
+qhp.projects = Simulator
+qhp.Simulator.file = simulator.qhp
+qhp.Simulator.namespace = com.nokia.qt.simulator.090
+qhp.Simulator.virtualFolder = doc
+qhp.Simulator.indexTitle = Qt Simulator
+qhp.Simulator.indexRoot =
+qhp.Simulator.extraFiles = classic.css \
+ images/qt-logo.png
+qhp.Simulator.filterAttributes = simulator
+
+qhp.Simulator.subprojects = scripting
+qhp.Simulator.subprojects.scripting.title = Scripting
+qhp.Simulator.subprojects.scripting.indexTitle = Simulator Scripting
+qhp.Simulator.subprojects.scripting.selectors = class
+qhp.Simulator.subprojects.scripting.sortPages = true
+
+# macros.qdocconf
+
+macro.aring.HTML = "&aring;"
+macro.Auml.HTML = "&Auml;"
+macro.author = "\\bold{Author:}"
+macro.br.HTML = "<br />"
+macro.BR.HTML = "<br />"
+macro.aacute.HTML = "&aacute;"
+macro.eacute.HTML = "&eacute;"
+macro.iacute.HTML = "&iacute;"
+macro.gui = "\\bold"
+macro.hr.HTML = "<hr />"
+macro.key = "\\bold"
+macro.menu = "\\bold"
+macro.note = "\\bold{Note:}"
+macro.oslash.HTML = "&oslash;"
+macro.ouml.HTML = "&ouml;"
+macro.QA = "\\e{Qt Assistant}"
+macro.QD = "\\e{Qt Designer}"
+macro.QL = "\\e{Qt Linguist}"
+macro.param = "\\e"
+macro.raisedaster.HTML = "<sup>*</sup>"
+macro.reg.HTML = "<sup>&reg;</sup>"
+macro.return = "Returns"
+macro.starslash = "\\c{*/}"
+macro.uuml.HTML = "&uuml;"
+macro.mdash.HTML = "&mdash;"
+
+# compat.qdocconf
+
+alias.i = e
+alias.include = input
+
+macro.0 = "\\\\0"
+macro.b = "\\\\b"
+macro.n = "\\\\n"
+macro.r = "\\\\r"
+macro.i = "\\o"
+macro.i11 = "\\o{1,1}"
+macro.i12 = "\\o{1,2}"
+macro.i13 = "\\o{1,3}"
+macro.i14 = "\\o{1,4}"
+macro.i15 = "\\o{1,5}"
+macro.i16 = "\\o{1,6}"
+macro.i17 = "\\o{1,7}"
+macro.i18 = "\\o{1,8}"
+macro.i19 = "\\o{1,9}"
+macro.i21 = "\\o{2,1}"
+macro.i31 = "\\o{3,1}"
+macro.i41 = "\\o{4,1}"
+macro.i51 = "\\o{5,1}"
+macro.i61 = "\\o{6,1}"
+macro.i71 = "\\o{7,1}"
+macro.i81 = "\\o{8,1}"
+macro.i91 = "\\o{9,1}"
+macro.img = "\\image"
+macro.endquote = "\\endquotation"
+spurious = "Missing comma in .*" \
+ "Missing pattern .*"
+
+# Doxygen compatibility commands
+
+macro.see = "\\sa"
+macro.function = "\\fn"
+
+# qt-cpp-ignore.qdocconf
+
+Cpp.ignoretokens = QAXFACTORY_EXPORT \
+ QDESIGNER_COMPONENTS_LIBRARY \
+ QDESIGNER_EXTENSION_LIBRARY \
+ QDESIGNER_SDK_LIBRARY \
+ QDESIGNER_SHARED_LIBRARY \
+ QDESIGNER_UILIB_LIBRARY \
+ QM_EXPORT_CANVAS \
+ QM_EXPORT_DNS \
+ QM_EXPORT_DOM \
+ QM_EXPORT_FTP \
+ QM_EXPORT_HTTP \
+ QM_EXPORT_ICONVIEW \
+ QM_EXPORT_NETWORK \
+ QM_EXPORT_OPENGL \
+ QM_EXPORT_SQL \
+ QM_EXPORT_TABLE \
+ QM_EXPORT_WORKSPACE \
+ QM_EXPORT_XML \
+ QT_ASCII_CAST_WARN \
+ QT_ASCII_CAST_WARN_CONSTRUCTOR \
+ QT_BEGIN_HEADER \
+ QT_DESIGNER_STATIC \
+ QT_END_HEADER \
+ QT_FASTCALL \
+ QT_WIDGET_PLUGIN_EXPORT \
+ Q_COMPAT_EXPORT \
+ Q_CORE_EXPORT \
+ Q_EXPLICIT \
+ Q_EXPORT \
+ Q_EXPORT_CODECS_CN \
+ Q_EXPORT_CODECS_JP \
+ Q_EXPORT_CODECS_KR \
+ Q_EXPORT_PLUGIN \
+ Q_GFX_INLINE \
+ Q_GUI_EXPORT \
+ Q_GUI_EXPORT_INLINE \
+ Q_GUI_EXPORT_STYLE_CDE \
+ Q_GUI_EXPORT_STYLE_COMPACT \
+ Q_GUI_EXPORT_STYLE_MAC \
+ Q_GUI_EXPORT_STYLE_MOTIF \
+ Q_GUI_EXPORT_STYLE_MOTIFPLUS \
+ Q_GUI_EXPORT_STYLE_PLATINUM \
+ Q_GUI_EXPORT_STYLE_POCKETPC \
+ Q_GUI_EXPORT_STYLE_SGI \
+ Q_GUI_EXPORT_STYLE_WINDOWS \
+ Q_GUI_EXPORT_STYLE_WINDOWSXP \
+ QHELP_EXPORT \
+ Q_INLINE_TEMPLATE \
+ Q_INTERNAL_WIN_NO_THROW \
+ Q_NETWORK_EXPORT \
+ Q_OPENGL_EXPORT \
+ Q_OUTOFLINE_TEMPLATE \
+ Q_SQL_EXPORT \
+ Q_SVG_EXPORT \
+ Q_SCRIPT_EXPORT \
+ Q_TESTLIB_EXPORT \
+ Q_TYPENAME \
+ Q_XML_EXPORT \
+ Q_XMLSTREAM_EXPORT \
+ Q_XMLPATTERNS_EXPORT \
+ QDBUS_EXPORT \
+ QT_BEGIN_NAMESPACE \
+ QT_BEGIN_INCLUDE_NAMESPACE \
+ QT_END_NAMESPACE \
+ QT_END_INCLUDE_NAMESPACE \
+ PHONON_EXPORT \
+ EXTENSIONSYSTEM_EXPORT \
+ Q_INVOKABLE
+Cpp.ignoredirectives = Q_DECLARE_HANDLE \
+ Q_DECLARE_INTERFACE \
+ Q_DECLARE_METATYPE \
+ Q_DECLARE_OPERATORS_FOR_FLAGS \
+ Q_DECLARE_PRIVATE \
+ Q_DECLARE_PUBLIC \
+ Q_DECLARE_SHARED \
+ Q_DECLARE_TR_FUNCTIONS \
+ Q_DECLARE_TYPEINFO \
+ Q_DISABLE_COPY \
+ QT_FORWARD_DECLARE_CLASS \
+ Q_DUMMY_COMPARISON_OPERATOR \
+ Q_ENUMS \
+ Q_FLAGS \
+ Q_INTERFACES \
+ __attribute__ \
+ K_DECLARE_PRIVATE \
+ PHONON_OBJECT \
+ PHONON_HEIR
+
+
+
+HTML.stylesheets = classic.css
+HTML.postheader = "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">\n" \
+ "<tr>\n" \
+ "<td align=\"left\" valign=\"top\" width=\"32\">" \
+ "<a href=\"http://qt.nokia.com/\"><img src=\"images/qt-logo.png\" align=\"left\" border=\"0\" /></a>" \
+ "</td>\n" \
+ "<td width=\"1\">&nbsp;&nbsp;</td>" \
+ "<td class=\"postheader\" valign=\"center\">" \
+ "<a href=\"index.html\">" \
+ "<font color=\"#004faf\">Home</font></a>&nbsp;&middot; " \
+ "</td>" \
+ "</tr></table>"
+
+HTML.footer = "<p /><address><hr /><div align=\"center\">\n" \
+ "<table width=\"100%\" cellspacing=\"0\" border=\"0\"><tr class=\"address\">\n" \
+ "<td width=\"40%\" align=\"left\">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies)</td>\n" \
+ "<td width=\"20%\" align=\"center\"><a href=\"trademarks.html\">Trademarks</a></td>\n" \
+ "<td width=\"40%\" align=\"right\"><div align=\"right\">Qt Simulator</div></td>\n" \
+ "</tr></table></div></address>"
diff --git a/fonts/heiseigoths60.ttf b/fonts/heiseigoths60.ttf
new file mode 100644
index 0000000..f63be2a
--- /dev/null
+++ b/fonts/heiseigoths60.ttf
Binary files differ
diff --git a/fonts/nosnb.ttf b/fonts/nosnb.ttf
new file mode 100644
index 0000000..81f135d
--- /dev/null
+++ b/fonts/nosnb.ttf
Binary files differ
diff --git a/fonts/nosnr.ttf b/fonts/nosnr.ttf
new file mode 100644
index 0000000..55d7f8d
--- /dev/null
+++ b/fonts/nosnr.ttf
Binary files differ
diff --git a/fonts/s60snr.ttf b/fonts/s60snr.ttf
new file mode 100644
index 0000000..3a8404f
--- /dev/null
+++ b/fonts/s60snr.ttf
Binary files differ
diff --git a/fonts/s60ssb.ttf b/fonts/s60ssb.ttf
new file mode 100644
index 0000000..8c4ce5f
--- /dev/null
+++ b/fonts/s60ssb.ttf
Binary files differ
diff --git a/fonts/s60tsb.ttf b/fonts/s60tsb.ttf
new file mode 100644
index 0000000..bb4900a
--- /dev/null
+++ b/fonts/s60tsb.ttf
Binary files differ
diff --git a/fonts/s60zdigi.ttf b/fonts/s60zdigi.ttf
new file mode 100644
index 0000000..c7ccf31
--- /dev/null
+++ b/fonts/s60zdigi.ttf
Binary files differ
diff --git a/models/maemoFremantle/N900.png b/models/maemoFremantle/N900.png
new file mode 100644
index 0000000..308053a
--- /dev/null
+++ b/models/maemoFremantle/N900.png
Binary files differ
diff --git a/models/maemoFremantle/maemoFremantle.config b/models/maemoFremantle/maemoFremantle.config
new file mode 100644
index 0000000..adcea37
--- /dev/null
+++ b/models/maemoFremantle/maemoFremantle.config
@@ -0,0 +1,11 @@
+name:Maemo Fremantle
+resolutionWidth:480
+resolutionHeight:800
+diagonalInInch:3.5
+mockup:N900.png
+offsetX:72
+offsetY:165
+defaultFontSize:18
+forceDpi:96
+menu:maemoFremantle
+nativeOrientation:landscape
diff --git a/models/symbianNonTouch/N95_8GB.png b/models/symbianNonTouch/N95_8GB.png
new file mode 100644
index 0000000..797b3c5
--- /dev/null
+++ b/models/symbianNonTouch/N95_8GB.png
Binary files differ
diff --git a/models/symbianNonTouch/symbianNonTouch.config b/models/symbianNonTouch/symbianNonTouch.config
new file mode 100644
index 0000000..db9b22f
--- /dev/null
+++ b/models/symbianNonTouch/symbianNonTouch.config
@@ -0,0 +1,35 @@
+name:Symbian NonTouch
+resolutionWidth:240
+resolutionHeight:320
+diagonalInInch:2.8
+mockup:N95_8GB.png
+offsetX:27
+offsetY:66
+defaultFontSize:7
+style:s60
+button:Key_1,1,41,563,67,32
+button:Key_2,2,109,563,73,32
+button:Key_3,3,182,563,67,32
+button:Key_4,4,41,592,67,32
+button:Key_5,5,109,592,73,32
+button:Key_6,6,182,592,67,32
+button:Key_7,7,41,623,67,32
+button:Key_8,8,109,623,73,32
+button:Key_9,9,182,623,67,32
+button:Key_Asterisk,*,41,659,67,32
+button:Key_0,0,109,659,73,32
+button:Key_NumberSign,#,182,659,67,32
+button:Key_Up,,129,441,34,19
+button:Key_Down,,129,496,34,19
+button:Key_Right,,163,460,20,33
+button:Key_Left,,109,460,20,33
+button:Key_Call,,19,470,40,40
+button:Key_Hangup,,232,471,40,40
+button:Key_Context1,,21,441,83,29
+button:Key_Context2,,186,441,85,29
+button:Key_TopMenu,,49,458,57,34
+button:Key_Music,,184,459,59,34
+button:Key_Select,,128,461,35,34
+button:Key_Spell,,60,493,49,20
+button:Key_Backspace,,183,494,48,20
+nativeOrientation:portrait
diff --git a/models/symbianTouch/N97.png b/models/symbianTouch/N97.png
new file mode 100644
index 0000000..2f9237e
--- /dev/null
+++ b/models/symbianTouch/N97.png
Binary files differ
diff --git a/models/symbianTouch/symbianTouch.config b/models/symbianTouch/symbianTouch.config
new file mode 100644
index 0000000..c68b854
--- /dev/null
+++ b/models/symbianTouch/symbianTouch.config
@@ -0,0 +1,14 @@
+name:Symbian Touch
+resolutionWidth:360
+resolutionHeight:640
+diagonalInInch:3.5
+mockup:N97.png
+offsetX:52
+offsetY:171
+defaultFontSize:7
+style:s60
+button:Key_TopMenu,,50,872,62,50
+button:Key_Call,,165,864,42,66
+button:Key_Hangup,,255,858,43,78
+menu:symbianTouch
+nativeOrientation:portrait
diff --git a/scripts/autostart/.directory b/scripts/autostart/.directory
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/scripts/autostart/.directory
diff --git a/scripts/devices/.Maemo Fremantle.qs.swp b/scripts/devices/.Maemo Fremantle.qs.swp
new file mode 100644
index 0000000..4c09ea2
--- /dev/null
+++ b/scripts/devices/.Maemo Fremantle.qs.swp
Binary files differ
diff --git a/scripts/devices/Default.qs b/scripts/devices/Default.qs
new file mode 100644
index 0000000..fdae535
--- /dev/null
+++ b/scripts/devices/Default.qs
@@ -0,0 +1,18 @@
+sysinfo.generic.inputMethod = sysinfo.generic.SingleTouch | sysinfo.generic.Keyboard | sysinfo.generic.Keys
+sysinfo.generic.setFeature(sysinfo.generic.BluetoothFeature, true)
+sysinfo.generic.setFeature(sysinfo.generic.CameraFeature, true)
+sysinfo.generic.setFeature(sysinfo.generic.FmradioFeature, false)
+sysinfo.generic.setFeature(sysinfo.generic.IrFeature, false)
+sysinfo.generic.setFeature(sysinfo.generic.LedFeature, false)
+sysinfo.generic.setFeature(sysinfo.generic.MemcardFeature, true)
+sysinfo.generic.setFeature(sysinfo.generic.UsbFeature, false)
+sysinfo.generic.setFeature(sysinfo.generic.VibFeature, true)
+sysinfo.generic.setFeature(sysinfo.generic.WlanFeature, true)
+sysinfo.generic.setFeature(sysinfo.generic.SimFeature, true)
+sysinfo.generic.setFeature(sysinfo.generic.LocationnFeature, true)
+sysinfo.generic.setFeature(sysinfo.generic.VideoOutFeature, true)
+sysinfo.generic.setFeature(sysinfo.generic.HapticsFeature, true)
+sysinfo.generic.manufacturer = "Simulator Manufacturer"
+sysinfo.generic.model = "Simulator Model"
+sysinfo.generic.productName = "Simulator Product Name"
+
diff --git a/scripts/devices/Maemo Fremantle.qs b/scripts/devices/Maemo Fremantle.qs
new file mode 100644
index 0000000..570c01f
--- /dev/null
+++ b/scripts/devices/Maemo Fremantle.qs
@@ -0,0 +1,18 @@
+sysinfo.generic.inputMethod = sysinfo.generic.SingleTouch | sysinfo.generic.Keyboard | sysinfo.generic.Keys
+sysinfo.generic.setFeature(sysinfo.generic.BluetoothFeature, true)
+sysinfo.generic.setFeature(sysinfo.generic.CameraFeature, true)
+sysinfo.generic.setFeature(sysinfo.generic.FmradioFeature, true)
+sysinfo.generic.setFeature(sysinfo.generic.IrFeature, false)
+sysinfo.generic.setFeature(sysinfo.generic.LedFeature, true)
+sysinfo.generic.setFeature(sysinfo.generic.MemcardFeature, true)
+sysinfo.generic.setFeature(sysinfo.generic.UsbFeature, true)
+sysinfo.generic.setFeature(sysinfo.generic.VibFeature, true)
+sysinfo.generic.setFeature(sysinfo.generic.WlanFeature, true)
+sysinfo.generic.setFeature(sysinfo.generic.SimFeature, true)
+sysinfo.generic.setFeature(sysinfo.generic.LocationnFeature, true)
+sysinfo.generic.setFeature(sysinfo.generic.VideoOutFeature, true)
+sysinfo.generic.setFeature(sysinfo.generic.HapticsFeature, true)
+sysinfo.generic.manufacturer = "Nokia"
+sysinfo.generic.model = "iarmv7I"
+sysinfo.generic.productName = "EX-51"
+
diff --git a/scripts/examples/devicechange.qs b/scripts/examples/devicechange.qs
new file mode 100644
index 0000000..16064a3
--- /dev/null
+++ b/scripts/examples/devicechange.qs
@@ -0,0 +1,22 @@
+// This script shows how you can change the currently
+// displayed skin
+// Interesting hooks:
+// simulator.deviceCount()
+// simulator.setDevice(int)
+// simulator.setDevice(string)
+// simulator.currentDeviceName()
+// simulator.currentDeviceIndex()
+
+var devCount = simulator.deviceCount();
+var originalName = simulator.currentDeviceName();
+messageBox("The device has " + devCount + " different skins");
+
+var current = 0;
+for (current = 0; current < devCount; ++current) {
+ simulator.setDevice(current);
+ messageBox("Switched to device: " +
+ simulator.currentDeviceName() +
+ " Index: " + simulator.currentDeviceIndex());
+}
+
+simulator.setDevice(originalName);
diff --git a/scripts/examples/location.qs b/scripts/examples/location.qs
new file mode 100644
index 0000000..1ace32f
--- /dev/null
+++ b/scripts/examples/location.qs
@@ -0,0 +1,20 @@
+// This script just moves continuasly from the current location to another one
+// Interesting parts:
+// location.latitude
+// location.longitude
+// location.altitude
+// (current not working) location.datetime
+
+var i = 0;
+while (i < 10)
+{
+ location.latitude += 0.0001;
+ location.longitude -= 0.0001;
+ location.altitude += 0.000001;
+ location.useCurrentTimestamp = true;
+
+ print ("Updated position:" + i);
+ i = i + 1;
+
+ yield(2000);
+}
diff --git a/scripts/examples/messagebox.qs b/scripts/examples/messagebox.qs
new file mode 100644
index 0000000..1de34ae
--- /dev/null
+++ b/scripts/examples/messagebox.qs
@@ -0,0 +1,3 @@
+// Simply show a message box
+
+messageBox("Message Boxes are always useful for debugging purposes");
diff --git a/scripts/examples/rotate.qs b/scripts/examples/rotate.qs
new file mode 100644
index 0000000..605e129
--- /dev/null
+++ b/scripts/examples/rotate.qs
@@ -0,0 +1,2 @@
+// This example lets the simulator rotate
+simulator.rotate();
diff --git a/scripts/examples/runOutOfBattery.qs b/scripts/examples/runOutOfBattery.qs
new file mode 100644
index 0000000..124492c
--- /dev/null
+++ b/scripts/examples/runOutOfBattery.qs
@@ -0,0 +1,18 @@
+// Decreases the battery level over 15 seconds until it's empty
+
+var startBatteryLevel = sysinfo.generic.batteryLevel; // save start battery level
+var drainTime = 15; // seconds
+var steps = 15; // number of steps for reducing battery level
+
+// set power state to battery power
+sysinfo.generic.currentPowerState = sysinfo.generic.BatteryPower;
+
+// running this script doesn't make sense if battery is already drained
+if (startBatteryLevel === 0)
+ startBatteryLevel = 100;
+
+// slowly drain battery
+for (var i = 0; i < steps; ++i) {
+ sysinfo.generic.batteryLevel = startBatteryLevel * (1 - i/(steps-1));
+ yield(drainTime/steps * 1000);
+}
diff --git a/scripts/examples/sysinfodevice.qs b/scripts/examples/sysinfodevice.qs
new file mode 100644
index 0000000..7d8e331
--- /dev/null
+++ b/scripts/examples/sysinfodevice.qs
@@ -0,0 +1,11 @@
+// set some device data
+
+sysinfo.generic.batteryLevel = 11;
+sysinfo.generic.currentPowerState = sysinfo.generic.WallPower;
+sysinfo.generic.simStatus = sysinfo.generic.SimLocked;
+sysinfo.generic.currentProfile = sysinfo.generic.LoudProfile;
+sysinfo.generic.imsi = "543210987654321"
+sysinfo.generic.imei = "54-321098-765432-1"
+sysinfo.generic.deviceLocked = true;
+
+
diff --git a/scripts/examples/sysinfogeneric.qs b/scripts/examples/sysinfogeneric.qs
new file mode 100644
index 0000000..5cfccad
--- /dev/null
+++ b/scripts/examples/sysinfogeneric.qs
@@ -0,0 +1,6 @@
+sysinfo.generic.currentLanguage = "bork"
+sysinfo.generic.currentCountryCode = "Borkland"
+sysinfo.generic.addAvailableLanguage("talk")
+sysinfo.generic.setFeature(sysinfo.generic.BluetoothFeature, true)
+sysinfo.generic.setVersion(sysinfo.generic.QtCore, "4.7")
+print(sysinfo.generic.version(sysinfo.generic.QtCore))
diff --git a/scripts/examples/sysinfonetwork.qs b/scripts/examples/sysinfonetwork.qs
new file mode 100644
index 0000000..97693ef
--- /dev/null
+++ b/scripts/examples/sysinfonetwork.qs
@@ -0,0 +1,16 @@
+// set some network data
+
+sysinfo.network.currentMobileCountryCode = "fi";
+
+sysinfo.network.cellId = 1;
+sysinfo.network.setNetworkSignalStrength(sysinfo.network.GsmMode, 10);
+yield(2000);
+sysinfo.network.cellId = 2;
+sysinfo.network.setNetworkSignalStrength(sysinfo.network.GsmMode, 50);
+yield(2000);
+sysinfo.network.cellId = 3;
+sysinfo.network.setNetworkSignalStrength(sysinfo.network.GsmMode, 20);
+yield(2000);
+sysinfo.network.cellId = 4;
+sysinfo.network.setNetworkSignalStrength(sysinfo.network.GsmMode, 100);
+yield(2000)
diff --git a/scripts/favorites/favoriteScript.qs b/scripts/favorites/favoriteScript.qs
new file mode 100644
index 0000000..13cfc31
--- /dev/null
+++ b/scripts/favorites/favoriteScript.qs
@@ -0,0 +1 @@
+print("Put your favorite scripts into this folder.");
diff --git a/simulator.pro b/simulator.pro
new file mode 100644
index 0000000..c5afa42
--- /dev/null
+++ b/simulator.pro
@@ -0,0 +1,45 @@
+TEMPLATE = app
+
+# Grab paths from environment variables if unset
+isEmpty(QT_NOKIA_SDK_PATH): QT_NOKIA_SDK_PATH = $$(QT_NOKIA_SDK_PATH)
+isEmpty(QT_MOBILITY_SOURCE_PATH): QT_MOBILITY_SOURCE_PATH = $$(QT_MOBILITY_SOURCE_PATH)
+isEmpty(QMF_INCLUDEDIR): QMF_INCLUDEDIR = $$(QMF_INCLUDEDIR)
+isEmpty(SIMULATOR_DEPENDENCY_PATH): SIMULATOR_DEPENDENCY_PATH = $$(SIMULATOR_DEPENDENCY_PATH)
+
+isEmpty(QT_NOKIA_SDK_PATH): error(Please call qmake with QT_NOKIA_SDK_PATH=<path to nokia-sdk source directory>)
+isEmpty(QT_MOBILITY_SOURCE_PATH): error(Please call qmake with QT_MOBILITY_SOURCE_PATH=<path to mobility source directory>)
+isEmpty(QMF_INCLUDEDIR): error(Please call qmake with QMF_INCLUDEDIR=<qmf-source/src/libraries/qtopiamail>)
+isEmpty(SIMULATOR_DEPENDENCY_PATH): error(Please call qmake with SIMULATOR_DEPENDENCY_PATH=<simulator-dependency-path>)
+
+TARGET = simulator
+DESTDIR= ./
+QT += network
+CONFIG += mobility
+MOBILITY += contacts versit
+contains(QT_CONFIG, phonon) {
+ QT += phonon
+}
+
+include(src/src.pri)
+include(doc/doc.pri)
+
+# install rules
+!isEmpty(PREFIX) {
+ target.path = $$PREFIX
+
+ macx: INSTALLSUBDIR=$${TARGET}.app/Contents/MacOS/
+
+ scripts.files = scripts
+ scripts.path = $$PREFIX/$$INSTALLSUBDIR
+
+ stubdata.files = stubdata
+ stubdata.path = $$PREFIX/$$INSTALLSUBDIR
+
+ fonts.files = fonts/*.ttf
+ fonts.path = $$PREFIX/$$INSTALLSUBDIR/fonts
+
+ devices.files = models
+ devices.path = $$PREFIX/$$INSTALLSUBDIR
+
+ INSTALLS += target scripts stubdata fonts devices
+}
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644
index 0000000..1bf669b
--- /dev/null
+++ b/src/main.cpp
@@ -0,0 +1,127 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "qtsingleapplication.h"
+
+#include "ui/mainwindow.h"
+#include "qsimulatordata_p.h"
+#include "messaging.h"
+
+#include <QtCore/QDebug>
+#include <QtCore/QDir>
+#include <QtCore/QSettings>
+#include <QtCore/QTimer>
+#include <QtGui/QApplication>
+#include <QtGui/QDesktopServices>
+
+static void registerSimulator(const QString &location)
+{
+ QSettings userSettings;
+ QSettings *settings = &userSettings;
+#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
+ // If the system settings are writable, don't touch the user settings.
+ // The reason is that a simulator started with sudo could otherwise create
+ // a root-owned configuration file a user directory.
+ QSettings systemSettings(QSettings::SystemScope, SIMULATOR_APP_VENDOR, SIMULATOR_APP_NAME);
+
+ // QSettings::isWritable isn't reliable enough in 4.7, determine writability experimentally
+ systemSettings.setValue(SIMULATOR_APP_LOCATION_KEY, QLatin1String("SETTABLE"));
+ systemSettings.sync();
+ if (systemSettings.status() == QSettings::NoError) {
+ settings = &systemSettings;
+ if (userSettings.contains(SIMULATOR_APP_LOCATION_KEY))
+ userSettings.remove(SIMULATOR_APP_LOCATION_KEY);
+ }
+#endif
+
+ const QString locationKey = QLatin1String(SIMULATOR_APP_LOCATION_KEY);
+ QVariant value = settings->value(locationKey);
+ if (!value.isValid() || settings->value(locationKey).toString() != location)
+ settings->setValue(locationKey, location);
+
+ const QString dataKey = QLatin1String(SIMULATOR_APP_DATA_KEY);
+ QString appDataLocation = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
+ if (appDataLocation.isEmpty())
+ appDataLocation = location;
+
+ value = settings->value(dataKey);
+ if (!value.isValid() || settings->value(dataKey).toString() != appDataLocation)
+ settings->setValue(dataKey, appDataLocation);
+}
+
+int main(int argc, char **argv)
+{
+ QCoreApplication::setOrganizationName(SIMULATOR_APP_VENDOR);
+ QCoreApplication::setApplicationName(SIMULATOR_APP_NAME);
+
+ SharedTools::QtSingleApplication app(SIMULATOR_APP_NAME, argc, argv);
+
+ QDir::setCurrent(app.applicationDirPath());
+
+ QDir pluginsDir = QDir::current();
+ if (pluginsDir.cd("plugins"))
+ QApplication::addLibraryPath(pluginsDir.absolutePath());
+
+ registerSimulator(app.applicationFilePath());
+
+ if (argc >= 2 && QByteArray(argv[1]) == "-registeronly") {
+ //As creation of the messaging folder takes ages, we do that when
+ //registering the simulator
+ Messaging m;
+ m.setInitialData();
+ // Don't return directly. Otherwise we crash.
+ QTimer::singleShot(1000, &app, SLOT(quit()));
+ return app.exec();
+ }
+
+ bool isFirstInstance = !app.isRunning();
+ if (argc >= 3 && QByteArray(argv[1]) == "-runscript") {
+ if (isFirstInstance) {
+ qWarning() << "Ignored -runscript: No running simulator found";
+ return -1;
+ }
+
+ if (!app.sendMessage(QString("runscript %1").arg(argv[2]))) {
+ qWarning() << "Could not send message to running simulator.";
+ return -1;
+ }
+ }
+
+ if (!isFirstInstance) {
+ // activate running instance?
+ return 0;
+ }
+
+ app.initialize();
+ MainWindow main;
+ QObject::connect(&app, SIGNAL(messageReceived(QString)), &main, SLOT(handleMessage(QString)));
+ main.show();
+ return app.exec();
+}
+
diff --git a/src/mobility/contacts.cpp b/src/mobility/contacts.cpp
new file mode 100644
index 0000000..fd5933c
--- /dev/null
+++ b/src/mobility/contacts.cpp
@@ -0,0 +1,108 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "contacts.h"
+
+#include <contacts/qcontact.h>
+#include <contacts/qcontactmanager.h>
+#include <contacts/details/qcontactname.h>
+#include <contacts/details/qcontactdisplaylabel.h>
+#include <contacts/details/qcontactphonenumber.h>
+#include <contacts/engines/qcontactmemorybackend_p.h>
+#include <versit/qversitreader.h>
+#include <versit/qversitcontactimporter.h>
+
+#include <QtCore/QMap>
+#include <QtCore/QString>
+#include <QtCore/QFile>
+#include <QtCore/QTextStream>
+
+using namespace QtMobility;
+
+Contacts::Contacts(QObject *parent)
+ : QObject(parent)
+{
+ QMap<QString, QString> engineParams;
+ engineParams.insert("id", "simulator");
+ mManager = new QContactManager("memory", engineParams, this);
+
+ connect(mManager, SIGNAL(contactsAdded(const QList<QContactLocalId> &)), SIGNAL(contactsAdded(const QList<QContactLocalId> &)));
+ connect(mManager, SIGNAL(contactsChanged(const QList<QContactLocalId> &)), SIGNAL(contactsChanged(const QList<QContactLocalId> &)));
+ connect(mManager, SIGNAL(contactsRemoved(const QList<QContactLocalId> &)), SIGNAL(contactsRemoved(const QList<QContactLocalId> &)));
+ connect(mManager, SIGNAL(relationshipsAdded(QList<QContactLocalId>)), SIGNAL(relationshipsAdded(QList<QContactLocalId>)));
+ connect(mManager, SIGNAL(relationshipsRemoved(QList<QContactLocalId>)), SIGNAL(relationshipsRemoved(QList<QContactLocalId>)));
+}
+
+QContactManager *Contacts::manager()
+{
+ return mManager;
+}
+
+void Contacts::setInitialData()
+{
+ importFromVCardFile("stubdata/standardselfcontact.vcf");
+ if (mManager->contactIds().count() == 1) {
+ mManager->setSelfContactId(mManager->contactIds().at(0));
+ } else {
+ qWarning("The file stubdata/standardselfcontact.vcf contains more than one contact. Not setting a self contact.");
+ }
+
+ importFromVCardFile("stubdata/standardcontacts.vcf");
+}
+
+void Contacts::publish() const
+{
+ emit contactsDataChanged(*mManager);
+}
+
+bool Contacts::importFromVCardFile(const QString &fileName)
+{
+ QFile contactsFile(fileName);
+ contactsFile.open(QIODevice::ReadOnly);
+ if (!contactsFile.isReadable())
+ return false;
+
+ QVersitReader reader;
+ reader.setDevice(&contactsFile);
+ if (!reader.startReading())
+ return false;
+ reader.waitForFinished();
+
+ QVersitContactImporter importer;
+ if (!importer.importDocuments(reader.results())) {
+ qWarning() << "Could not import contacts from " << fileName;
+ return false;
+ }
+
+ QList<QContact> contacts = importer.contacts();
+ QMap<int, QContactManager::Error> errors;
+ mManager->saveContacts(&contacts, &errors);
+
+ return true;
+}
diff --git a/src/mobility/contacts.h b/src/mobility/contacts.h
new file mode 100644
index 0000000..7f18b51
--- /dev/null
+++ b/src/mobility/contacts.h
@@ -0,0 +1,75 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef CONTACTS_H
+#define CONTACTS_H
+
+#include <QtCore/QObject>
+#include <QtCore/QList>
+#include <contacts/qtcontactsglobal.h>
+
+namespace QtMobility {
+ class QContactManager;
+}
+
+// These are required - otherwise the signals defined below have to contain
+// QtMobility:: in their signature and and that makes connect() refuse to
+// connect them.
+using QtMobility::QContactLocalId;
+using QtMobility::QContactManager;
+
+class Contacts : public QObject
+{
+ Q_OBJECT
+public:
+ explicit Contacts(QObject *parent = 0);
+
+ QtMobility::QContactManager *manager();
+
+public slots:
+ void setInitialData();
+ void publish() const;
+ bool importFromVCardFile(const QString &fileName);
+
+signals:
+ // for incremental changes triggered remotely
+ void contactsAdded(const QList<QContactLocalId> &contactIds) const;
+ void contactsChanged(const QList<QContactLocalId> &contactIds) const;
+ void contactsRemoved(const QList<QContactLocalId> &contactIds) const;
+ void relationshipsAdded(const QList<QContactLocalId> &affectedContactIds) const;
+ void relationshipsRemoved(const QList<QContactLocalId> &affectedContactIds) const;
+
+ // for a complete update triggered by publish
+ void contactsDataChanged(const QContactManager &) const;
+
+private:
+ QtMobility::QContactManager *mManager;
+};
+
+#endif // CONTACTS_H
diff --git a/src/mobility/messaging.cpp b/src/mobility/messaging.cpp
new file mode 100644
index 0000000..00eadc9
--- /dev/null
+++ b/src/mobility/messaging.cpp
@@ -0,0 +1,149 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "messaging.h"
+
+#include <qmailstore.h>
+#include <qsimulatordata_p.h>
+
+#include <QtCore/QDir>
+#include <QtCore/QThread>
+
+class MaildirImporter : public QThread
+{
+public:
+ MaildirImporter(const QString &path, QObject *parent = 0)
+ : QThread(parent), mPath(path)
+ {
+ }
+
+protected:
+ virtual void run()
+ {
+ QDir dir(mPath);
+ if (!dir.exists())
+ return;
+
+ QMailStore *store = QMailStore::instance();
+ QMailAccountIdList accountIdList = store->queryAccounts();
+ if (accountIdList.isEmpty())
+ return;
+ QMailFolderIdList folderIdList = store->queryFolders();
+ if (folderIdList.isEmpty())
+ return;
+
+ foreach (const QFileInfo &fileInfo, dir.entryInfoList(QDir::Files)) {
+ QFile file(fileInfo.absoluteFilePath());
+ file.open(QIODevice::ReadOnly);
+ QByteArray data = file.readAll();
+ file.close();
+
+ // RFC 2822 requires CRLF line endings
+ for (int i = 0; i < data.size(); ++i) {
+ if (data.at(i) == '\n' && i > 0 && data.at(i-1) != '\r') {
+ data.insert(i, '\r');
+ ++i;
+ }
+ }
+
+ QMailMessage message(QMailMessage::fromRfc2822(data));
+ if (message.headerFields().isEmpty())
+ continue;
+
+ QMailMessage *storeMessage = new QMailMessage(message);
+ storeMessage->setMessageType(QMailMessage::Email);
+ storeMessage->setParentAccountId(accountIdList.first());
+ storeMessage->setParentFolderId(folderIdList.first());
+ QMailStore::instance()->addMessage(storeMessage);
+ }
+ }
+
+private:
+ QString mPath;
+};
+
+Messaging::Messaging(QObject *parent) :
+ QObject(parent)
+{
+}
+
+void Messaging::setInitialData()
+{
+ // have to use the same on the client
+ QtSimulatorPrivate::qt_setQmfPaths();
+
+ QMailStore *mailstore = QMailStore::instance();
+
+ // remove existing data
+ mailstore->removeAccounts(QMailAccountKey());
+
+ // add stub account
+ QMailAccount *account = new QMailAccount();
+ account->setName("TestAccount");
+ mailstore->addAccount(account, 0);
+
+ // add stub folder
+ QMailFolder *folder = new QMailFolder("TestFolder");
+ mailstore->addFolder(folder);
+
+ importMaildir("stubdata/standardmessages");
+}
+
+void Messaging::addMessage(QMailMessage *message)
+{
+ QMailStore *store = QMailStore::instance();
+ QMailAccountIdList accountIdList = store->queryAccounts();
+ if (accountIdList.isEmpty())
+ return;
+ QMailFolderIdList folderIdList = store->queryFolders();
+ if (folderIdList.isEmpty())
+ return;
+
+ message->setParentAccountId(accountIdList.first());
+ message->setParentFolderId(folderIdList.first());
+ store->addMessage(message);
+}
+
+void Messaging::importMaildir(const QString &path)
+{
+ // remove done threads
+ QMutableListIterator<MaildirImporter *> it(mImporterThreads);
+ while (it.hasNext()) {
+ MaildirImporter *importer = it.next();
+ if (importer->isFinished()) {
+ delete importer;
+ it.remove();
+ }
+ }
+
+ // start new importer thread
+ MaildirImporter *maildirImporter = new MaildirImporter(path, this);
+ maildirImporter->start();
+ mImporterThreads += maildirImporter;
+}
diff --git a/src/mobility/messaging.h b/src/mobility/messaging.h
new file mode 100644
index 0000000..1cbf54d
--- /dev/null
+++ b/src/mobility/messaging.h
@@ -0,0 +1,56 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef MESSAGING_H
+#define MESSAGING_H
+
+#include <QtCore/QObject>
+
+class MaildirImporter;
+class QMailAccount;
+class QMailFolder;
+class QMailMessage;
+
+class Messaging : public QObject
+{
+Q_OBJECT
+public:
+ explicit Messaging(QObject *parent = 0);
+
+ void importMaildir(const QString &path);
+ void addMessage(QMailMessage *message);
+
+public slots:
+ void setInitialData();
+
+private:
+ QList<MaildirImporter *> mImporterThreads;
+};
+
+#endif // MESSAGING_H
diff --git a/src/mobility/mobility.pri b/src/mobility/mobility.pri
new file mode 100644
index 0000000..86c81a7
--- /dev/null
+++ b/src/mobility/mobility.pri
@@ -0,0 +1,12 @@
+INCLUDEPATH += src/mobility
+DEPENDPATH += src/mobility
+SOURCES += \
+ mobilitymanager.cpp \
+ contacts.cpp \
+ mobilitydata.cpp \
+ messaging.cpp
+HEADERS += \
+ mobilitymanager.h \
+ contacts.h \
+ mobilitydata.h \
+ messaging.h
diff --git a/src/mobility/mobilitydata.cpp b/src/mobility/mobilitydata.cpp
new file mode 100644
index 0000000..469a409
--- /dev/null
+++ b/src/mobility/mobilitydata.cpp
@@ -0,0 +1,262 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "mobilitydata.h"
+
+#include <contacts/qcontactmanager.h>
+#include <contacts/qcontact.h>
+#include <contacts/details/qcontactemailaddress.h>
+#include <contacts/details/qcontactphonenumber.h>
+#include <qmailmessage.h>
+
+#include <qmath.h>
+
+using namespace QtMobility;
+
+MobilityData::MobilityData(QObject *parent)
+ : QObject(parent)
+ , mContacts(new Contacts(this))
+ , mLocationUi(0)
+ , mSystemInfoGenericUi(0)
+ , mSystemInfoNetworkUi(0)
+ , mSystemInfoStorageUi(0)
+ , mMessaging(new Messaging(this))
+ , mSensorsUi(0)
+ , mInitialized(false)
+ , mInitializeWithLandscape(false)
+{
+}
+
+void MobilityData::setInitialData()
+{
+ setInitialLocationData();
+ mContacts->setInitialData();
+ setInitialSystemInfoGenericData();
+ setInitialSystemInfoNetworkData();
+ setInitialSystemInfoStorageData();
+ mMessaging->setInitialData();
+ setInitialSensorsData();
+}
+
+void MobilityData::setInitialSensorsData()
+{
+ SensorsUi::SensorsData sensors;
+ sensors.ambientLightLevel = SensorsScriptInterface::Light;
+
+ if (mInitializeWithLandscape) {
+ sensors.accelerometerX = -9.8;
+ sensors.accelerometerY = 0;
+ } else {
+ sensors.accelerometerX = 0;
+ sensors.accelerometerY = 9.8;
+ }
+ sensors.accelerometerZ = 0;
+
+ sensors.magnetometerX = 0.5;
+ sensors.magnetometerY = 0.5;
+ sensors.magnetometerY = 0.5;
+ sensors.magnetometerCalibrationLevel = 0.85;
+
+ sensors.compassCalibrationLevel = 0.85;
+ sensors.compassAzimuth = 132.65;
+
+ sensors.proximitySensorClose = true;
+
+ mSensorsUi->setSensorsData(sensors);
+ mInitialized = true;
+}
+
+void MobilityData::setInitialLocationData()
+{
+ LocationUi::LocationData data;
+ data.latitude = 52.5056819;
+ data.longitude = 13.3232027;
+ data.altitude = 4.897392;
+ data.useCurrentTime = true;
+ mLocationUi->setLocation(data);
+}
+
+void MobilityData::setInitialSystemInfoGenericData()
+{
+ GenericSystemInfoUi::GenericData data;
+ data.currentLanguage = "en";
+ data.currentCountryCode = "EN";
+ data.availableLanguages.append("en");
+ data.availableLanguages.append("de");
+ data.features[GenericSystemInfoScriptInterface::LocationFeature] = true;
+ data.features[GenericSystemInfoScriptInterface::UsbFeature] = true;
+ data.versions[GenericSystemInfoScriptInterface::QtCore] = "4.6 probably";
+ data.versions[GenericSystemInfoScriptInterface::Firmware] = "1.9-alpha-rc7";
+ data.displayBrightness = 100;
+ data.colorDepth = 32;
+ data.profile = GenericSystemInfoScriptInterface::NormalProfile;
+ data.currentPowerState = GenericSystemInfoScriptInterface::WallPower;
+ data.simStatus = GenericSystemInfoScriptInterface::SimNotAvailable;
+ data.inputFlags = static_cast<GenericSystemInfoScriptInterface::InputMethod>
+ (GenericSystemInfoScriptInterface::Keyboard | GenericSystemInfoScriptInterface::Mouse);
+ data.imei = "12-345678-901234-5";
+ data.imsi = "12345679012345";
+ data.manufacturer = "simulator manufacturer";
+ data.model = "simulator model";
+ data.productName = "simulator product name";
+ data.batteryLevel = 84;
+ data.deviceLocked = false;
+ mSystemInfoGenericUi->setGenericData(data);
+}
+
+void MobilityData::setInitialSystemInfoNetworkData()
+{
+ NetworkSystemInfoUi::NetworkData data;
+ data.cellId = 12345;
+ data.locationAreaCode = 54321;
+ data.currentMobileCountryCode = QLatin1String("242");
+ data.currentMobileNetworkCode = QLatin1String("123456789");
+ data.homeMobileCountryCode = QLatin1String("+47");
+ data.homeMobileNetworkCode = QLatin1String("987654321");
+ data.currentMode = NetworkSystemInfoScriptInterface::EthernetMode;
+
+ for (int i = 0; i < data.networkInfo.size(); ++i) {
+ NetworkSystemInfoUi::NetworkData::ModeInfo &mode = data.networkInfo[i];
+
+ mode.name = QLatin1String("name");
+ mode.macAddress = QLatin1String("ff:ff:ff:ff:ff:ff");
+ mode.signalStrength = 75;
+ mode.status = NetworkSystemInfoScriptInterface::UndefinedStatus;
+ }
+ mSystemInfoNetworkUi->setNetworkData(data);
+}
+
+void MobilityData::setInitialSystemInfoStorageData()
+{
+ StorageSystemInfoScriptInterface *si = mSystemInfoStorageUi->scriptInterface();
+ si->addDrive("Internal Drive", StorageSystemInfoScriptInterface::InternalDrive,
+ 256*1024*qint64(1024), 32*1024*qint64(1024));
+ si->addDrive("Removable Drive", StorageSystemInfoScriptInterface::RemovableDrive,
+ 4*1024*1024*qint64(1024), 3*1024*1024*qint64(1024));
+}
+
+static int randomInt(int begin, int end)
+{
+ return begin + floor((qreal)qrand() / RAND_MAX * (end - begin));
+}
+
+void MobilityData::addNewEmail()
+{
+ // ### A script should do this...
+ QContactManager *manager = mContacts->manager();
+
+ // find sender
+ QList<QContact> contacts = manager->contacts();
+ QContact sender = contacts.at(randomInt(0, contacts.size()));
+
+ // find target
+ QContact receiver = manager->contact(manager->selfContactId());
+
+ // make message
+ QMailMessage *message = new QMailMessage();
+ message->setMessageType(QMailMessage::Email);
+ message->setSubject(tr("Generated message"));
+ message->setBody(
+ QMailMessageBody::fromData(tr("This is a simulator-generated email message."),
+ QMailMessageContentType("text/plain"),
+ QMailMessageBodyFwd::NoEncoding));
+ message->setFrom(QMailAddress(sender.displayLabel(),
+ sender.detail<QContactEmailAddress>().emailAddress()));
+ message->setTo(QMailAddress(receiver.displayLabel(),
+ receiver.detail<QContactEmailAddress>().emailAddress()));
+ mMessaging->addMessage(message);
+}
+
+void MobilityData::addNewSms()
+{
+ // ### A script should do this...
+ QContactManager *manager = mContacts->manager();
+
+ // find sender
+ QList<QContact> contacts = manager->contacts();
+ QContact sender = contacts.at(randomInt(0, contacts.size()));
+
+ // find target
+ QContact receiver = manager->contact(manager->selfContactId());
+
+ // make message
+ QMailMessage *message = new QMailMessage();
+ message->setMessageType(QMailMessage::Sms);
+ message->setSubject(tr("Generated message"));
+ message->setBody(
+ QMailMessageBody::fromData(tr("This is a simulator-generated SMS message."),
+ QMailMessageContentType("text/plain"),
+ QMailMessageBodyFwd::NoEncoding));
+ message->setFrom(QMailAddress(sender.displayLabel(),
+ sender.detail<QContactPhoneNumber>().number()));
+ message->setTo(QMailAddress(receiver.displayLabel(),
+ receiver.detail<QContactPhoneNumber>().number()));
+ mMessaging->addMessage(message);
+}
+
+void MobilityData::rotateDevice(Orientation current, Orientation native)
+{
+ SensorsUi::SensorsData sensors = mSensorsUi->sensorsData();
+
+ if (native == landscapeOrientation) {
+ if (current == portraitOrientation) {
+ sensors.accelerometerX -= 9.8;
+ sensors.accelerometerY -= 9.8;
+ } else {
+ sensors.accelerometerX += 9.8;
+ sensors.accelerometerY += 9.8;
+ }
+ } else {
+ if (current == portraitOrientation) {
+ sensors.accelerometerX -= 9.8;
+ sensors.accelerometerY += 9.8;
+ } else {
+ sensors.accelerometerX += 9.8;
+ sensors.accelerometerY -= 9.8;
+ }
+ }
+
+ mSensorsUi->setSensorsData(sensors);
+}
+
+void MobilityData::changeDevice(Orientation current, Orientation currentNative, Orientation targetNative)
+{
+ if (currentNative == targetNative)
+ return;
+
+ if (!mInitialized) {
+ if (targetNative == landscapeOrientation)
+ mInitializeWithLandscape = true;
+ else
+ mInitializeWithLandscape = false;
+ return;
+ }
+
+ rotateDevice(currentNative, current == landscapeOrientation ? portraitOrientation : landscapeOrientation);
+}
diff --git a/src/mobility/mobilitydata.h b/src/mobility/mobilitydata.h
new file mode 100644
index 0000000..4be7c98
--- /dev/null
+++ b/src/mobility/mobilitydata.h
@@ -0,0 +1,82 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef MOBILITYDATA_H
+#define MOBILITYDATA_H
+
+#include <QObject>
+
+// while a forward declaration would suffice, we include these here
+// as everything using MobilityData will usually want to include them too
+#include "contacts.h"
+#include "systeminfogenericui.h"
+#include "systeminfonetworkui.h"
+#include "systeminfostorageui.h"
+#include "messaging.h"
+#include "sensorsui.h"
+#include "deviceitem.h"
+
+#include <remotecontrolwidget/locationui.h>
+
+class MobilityData : public QObject
+{
+Q_OBJECT
+public:
+ explicit MobilityData(QObject *parent = 0);
+
+ Contacts *mContacts;
+ LocationUi *mLocationUi;
+ GenericSystemInfoUi *mSystemInfoGenericUi;
+ NetworkSystemInfoUi *mSystemInfoNetworkUi;
+ StorageSystemInfoUi *mSystemInfoStorageUi;
+ Messaging *mMessaging;
+ SensorsUi *mSensorsUi;
+
+ void setInitialData();
+
+public slots:
+ void addNewEmail();
+ void addNewSms();
+
+ // for adjusting data based on orientation of device
+ void rotateDevice(Orientation current, Orientation native);
+ void changeDevice(Orientation current, Orientation currentNative, Orientation targetNative);
+
+private:
+ void setInitialSensorsData();
+ void setInitialLocationData();
+ void setInitialSystemInfoNetworkData();
+ void setInitialSystemInfoStorageData();
+ void setInitialSystemInfoGenericData();
+
+ bool mInitialized;
+ bool mInitializeWithLandscape;
+};
+
+#endif // MOBILITYDATA_H
diff --git a/src/mobility/mobilitymanager.cpp b/src/mobility/mobilitymanager.cpp
new file mode 100644
index 0000000..2bb340d
--- /dev/null
+++ b/src/mobility/mobilitymanager.cpp
@@ -0,0 +1,503 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "mobilitymanager.h"
+#include "mobilitydata.h"
+
+#include <qsimulatordata_p.h>
+#include <contacts/engines/qcontactmemorybackend_p.h>
+#include <contacts/engines/qcontactmemorybackenddata_simulator_p.h>
+#include <contacts/qcontactmanager.h>
+#include <contacts/qcontactmanager_p.h>
+#include <contacts/qcontactrelationship.h>
+
+#include <QtCore/QList>
+#include <QtCore/QDebug>
+
+#include <QtNetwork/QLocalSocket>
+#include <QtNetwork/QLocalServer>
+
+#include <limits>
+
+using namespace QtMobility;
+
+int MobilityClient::contactsClientsCount = 0;
+
+MobilityServer::MobilityServer(MobilityData *mobility, QObject *parent)
+ : QObject(parent)
+ , mMobility(mobility)
+{
+ mServer = new QLocalServer();
+ QLocalServer::removeServer(SIMULATOR_MOBILITY_SERVERNAME);
+ if (!mServer->listen(SIMULATOR_MOBILITY_SERVERNAME)) {
+ qFatal("Could not open mobility server");
+ }
+ connect(mServer, SIGNAL(newConnection()), this, SLOT(newConnection()));
+
+ qt_registerSystemInfoTypes();
+ qt_registerContactsTypes();
+ qt_registerLocationTypes();
+ qt_registerSensorTypes();
+}
+
+MobilityServer::~MobilityServer()
+{
+ if (mServer) {
+ mServer->close();
+ QLocalServer::removeServer(SIMULATOR_DISPLAY_SERVERNAME);
+ delete mServer;
+ mServer = 0;
+ }
+}
+
+void MobilityServer::newConnection()
+{
+ // get the incoming connection
+ QLocalSocket* socket = mServer->nextPendingConnection();
+ if (!socket->isValid()) {
+ qWarning() << "Invalid socket!";
+ return;
+ }
+
+ // expect an initial application connect packet to to verify that this is
+ // indeed a simulator client application and to get its pid
+ using namespace ::QtSimulatorPrivate;
+
+ // read the command id
+ qint32 requestCommand = 0;
+ qint64 bytesToRead = sizeof(requestCommand);
+ qint64 bytesRead = qt_blockingRead(
+ socket, reinterpret_cast<char *>(&requestCommand), bytesToRead, 500);
+ if (bytesRead < bytesToRead)
+ {
+ qWarning("Dropped incoming connection, couldn't read command id.");
+ return;
+ }
+ if (requestCommand != QtSimulatorPrivate::Command::ApplicationConnect)
+ {
+ qWarning("Dropped incoming connection, it sent an invalid command.");
+ return;
+ }
+
+ // read the command
+ QtSimulatorPrivate::ApplicationConnectCommand cmd;
+ bytesToRead = sizeof(cmd.request);
+ bytesRead = qt_blockingRead(
+ socket, reinterpret_cast<char *>(&cmd.request), bytesToRead, 500);
+ if (bytesRead < bytesToRead)
+ {
+ qWarning("Dropped incoming connection, couldn't read command data.");
+ return;
+ }
+
+ // send a reply
+ qint64 bytesToWrite = sizeof(cmd.reply);
+ qint64 bytesWritten = qt_blockingWrite(
+ socket, reinterpret_cast<const char *>(&cmd.reply), bytesToWrite, 500);
+ if (bytesWritten < bytesToWrite)
+ {
+ qWarning("Dropped incoming connection, couldn't send connect reply.");
+ return;
+ }
+
+ // success: register client
+ mClients.append(new MobilityClient(cmd.request.applicationPid, socket, this));
+}
+
+void MobilityServer::removeClient(MobilityClient *c)
+{
+ mClients.removeAll(c);
+}
+
+MobilityClient::MobilityClient(qint64 pid, QLocalSocket *receiveSocket, MobilityServer *server)
+ : QObject(server)
+ , mPid(pid)
+ , mReceiveSocket(receiveSocket)
+ , mSendSocket(0)
+ , mMobilityServer(server)
+ , mNotifyClientOnContactsChange(true)
+{
+ // initiate sendSocket as a backchannel to the client
+ mSendSocket = new QLocalSocket(this);
+ mSendSocket->connectToServer(qt_mobilityServerName(pid));
+ if (!mSendSocket->waitForConnected(1000))
+ qFatal("Couldn't set up back channel to mobility interface of client");
+
+ // there might be data available already
+ readyRead();
+ connect(mReceiveSocket, SIGNAL(readyRead()), this, SLOT(readyRead()));
+ connect(mReceiveSocket, SIGNAL(disconnected()), this, SLOT(disconnect()));
+}
+
+MobilityClient::~MobilityClient()
+{
+ mSendSocket->disconnectFromServer();
+ mSendSocket->deleteLater();
+}
+
+void MobilityClient::disconnect()
+{
+ mMobilityServer->removeClient(this);
+ delete this;
+}
+
+void MobilityClient::readyRead()
+{
+ mReadBuffer += mReceiveSocket->readAll();
+ forever {
+ QtSimulatorPrivate::IncomingRemoteMetacall rpc;
+ if (rpc.read(&mReadBuffer)) {
+ if (rpc.call(mReceiveSocket, this)) {
+ continue;
+ }
+ qWarning("Ignoring a call to %s, No such slot in MobilityClient.", rpc.signature().data());
+ }
+ break;
+ }
+}
+
+void MobilityClient::sendSystemGenericInfo(const GenericSystemInfoUi::GenericData &data)
+{
+ QSystemInfoData sysInfoData;
+ sysInfoData.availableLanguages = data.availableLanguages;
+ sysInfoData.currentCountryCode = data.currentCountryCode;
+ sysInfoData.currentLanguage = data.currentLanguage;
+ sysInfoData.features = data.features;
+ sysInfoData.versions = data.versions;
+ QtSimulatorPrivate::RemoteMetacall<void>::call(mSendSocket, QtSimulatorPrivate::NoSync,
+ "setSystemInfoData", sysInfoData);
+ QSystemDeviceInfoData deviceInfoData;
+ deviceInfoData.batteryLevel = data.batteryLevel;
+ deviceInfoData.currentPowerState = static_cast<QtMobility::QSystemDeviceInfo::PowerState>(data.currentPowerState);
+ deviceInfoData.currentProfile = static_cast<QtMobility::QSystemDeviceInfo::Profile>(data.profile);
+ deviceInfoData.deviceLocked = data.deviceLocked;
+ deviceInfoData.imei = data.imei;
+ deviceInfoData.imsi = data.imsi;
+ QtMobility::QSystemDeviceInfo::InputMethodFlags flags;
+ if (data.inputFlags & GenericSystemInfoScriptInterface::Keys)
+ flags |= QSystemDeviceInfo::Keys;
+ if (data.inputFlags & GenericSystemInfoScriptInterface::Keypad)
+ flags |= QSystemDeviceInfo::Keypad;
+ if (data.inputFlags & GenericSystemInfoScriptInterface::Keyboard)
+ flags |= QSystemDeviceInfo::Keyboard;
+ if (data.inputFlags & GenericSystemInfoScriptInterface::MultiTouch)
+ flags |= QSystemDeviceInfo::MultiTouch;
+ if (data.inputFlags & GenericSystemInfoScriptInterface::SingleTouch)
+ flags |= QSystemDeviceInfo::SingleTouch;
+ if (data.inputFlags & GenericSystemInfoScriptInterface::Mouse)
+ flags |= QSystemDeviceInfo::Mouse;
+ deviceInfoData.inputMethodType = flags;
+ deviceInfoData.manufacturer = data.manufacturer;
+ deviceInfoData.model = data.model;
+ deviceInfoData.productName = data.productName;
+ deviceInfoData.simStatus = static_cast<QtMobility::QSystemDeviceInfo::SimStatus>(data.simStatus);
+ QtSimulatorPrivate::RemoteMetacall<void>::call(mSendSocket, QtSimulatorPrivate::NoSync,
+ "setSystemDeviceInfoData", deviceInfoData);
+
+ QSystemDisplayInfoData displayInfoData;
+ displayInfoData.colorDepth = data.colorDepth;
+ displayInfoData.displayBrightness = data.displayBrightness;
+ QtSimulatorPrivate::RemoteMetacall<void>::call(mSendSocket, QtSimulatorPrivate::NoSync,
+ "setSystemDisplayInfoData", displayInfoData);
+
+}
+
+void MobilityClient::sendSystemStorageInfo(const StorageSystemInfoUi::StorageData &data)
+{
+ QSystemStorageInfoData storage;
+ QHashIterator<QString, StorageSystemInfoUi::StorageData::DriveInfo> iter(data.drives);
+ while (iter.hasNext()) {
+ iter.next();
+ QSystemStorageInfoData::DriveInfo info;
+ info.type = static_cast<QSystemStorageInfo::DriveType>(iter.value().type);
+ info.availableSpace = iter.value().availableSpace;
+ info.totalSpace = iter.value().totalSpace;
+ storage.drives.insert(iter.key(), info);
+ }
+
+ QtSimulatorPrivate::RemoteMetacall<void>::call(mSendSocket, QtSimulatorPrivate::NoSync,
+ "setSystemStorageInfoData", storage);
+}
+
+void MobilityClient::sendSystemNetworkInfo(const NetworkSystemInfoUi::NetworkData &data)
+{
+ QSystemNetworkInfoData network;
+ network.cellId = data.cellId;
+ network.locationAreaCode = data.locationAreaCode;
+ network.currentMobileCountryCode = data.currentMobileCountryCode;
+ network.currentMobileNetworkCode = data.currentMobileNetworkCode;
+ network.homeMobileCountryCode = data.homeMobileCountryCode;
+ network.homeMobileNetworkCode = data.homeMobileNetworkCode;
+ network.currentMode = static_cast<QSystemNetworkInfo::NetworkMode>(data.currentMode);
+ foreach (const NetworkSystemInfoUi::NetworkData::ModeInfo &modeInfo, data.networkInfo) {
+ QSystemNetworkInfoData::NetworkInfo info;
+ info.name = modeInfo.name;
+ info.macAddress = modeInfo.macAddress;
+ info.signalStrength = modeInfo.signalStrength;
+ info.status = static_cast<QSystemNetworkInfo::NetworkStatus>(modeInfo.status);
+ network.networkInfo.append(info);
+ }
+
+ QtSimulatorPrivate::RemoteMetacall<void>::call(mSendSocket, QtSimulatorPrivate::NoSync,
+ "setSystemNetworkInfoData", network);
+}
+
+void MobilityClient::sendLocationData(const LocationUi::LocationData &data)
+{
+ QGeoPositionInfoData location;
+ location.latitude = data.latitude;
+ location.longitude = data.longitude;
+ location.altitude = data.altitude;
+ if (data.useCurrentTime)
+ location.dateTime = QDateTime();
+ else
+ location.dateTime = data.timestamp;
+ location.minimumInterval = 1000;
+ location.enabled = true;
+ QtSimulatorPrivate::RemoteMetacall<void>::call(mSendSocket, QtSimulatorPrivate::NoSync,
+ "setLocationData", location);
+}
+
+void MobilityClient::sendSensorsData(const SensorsUi::SensorsData &data)
+{
+ QDateTime timestampToSend;
+ if (!data.useCurrentTime)
+ timestampToSend = data.timestamp;
+ QAmbientLightReadingData ambientData;
+ ambientData.lightLevel = static_cast<QtMobility::QAmbientLightReading::LightLevel>(data.ambientLightLevel);
+ ambientData.timestamp = timestampToSend;
+ QtSimulatorPrivate::RemoteMetacall<void>::call(mSendSocket, QtSimulatorPrivate::NoSync,
+ "setAmbientLightData", ambientData);
+
+ QAccelerometerReadingData accelermometerData;
+ accelermometerData.x = data.accelerometerX;
+ accelermometerData.y = data.accelerometerY;
+ accelermometerData.z = data.accelerometerZ;
+ accelermometerData.timestamp = timestampToSend;
+ QtSimulatorPrivate::RemoteMetacall<void>::call(mSendSocket, QtSimulatorPrivate::NoSync,
+ "setAccelerometerData", accelermometerData);
+
+ QMagnetometerReadingData magnetometerData;
+ magnetometerData.x = data.magnetometerX;
+ magnetometerData.y = data.magnetometerY;
+ magnetometerData.z = data.magnetometerZ;
+ magnetometerData.calibrationLevel = data.magnetometerCalibrationLevel;
+ magnetometerData.timestamp = timestampToSend;
+ QtSimulatorPrivate::RemoteMetacall<void>::call(mSendSocket, QtSimulatorPrivate::NoSync,
+ "setMagnetometerData", magnetometerData);
+
+ QCompassReadingData compassData;
+ compassData.azimuth = data.compassAzimuth;
+ compassData.calibrationLevel = data.compassCalibrationLevel;
+ compassData.timestamp = timestampToSend;
+ QtSimulatorPrivate::RemoteMetacall<void>::call(mSendSocket, QtSimulatorPrivate::NoSync,
+ "setCompassData", compassData);
+
+ QProximityReadingData proximityData;
+ proximityData.close = data.proximitySensorClose;
+ proximityData.timestamp = timestampToSend;
+ QtSimulatorPrivate::RemoteMetacall<void>::call(mSendSocket, QtSimulatorPrivate::NoSync,
+ "setProximityData", proximityData);
+}
+
+// Sends simulator contact data to client, overwriting its local data.
+// Can invalidate ids the client stored locally.
+// Ideally it's used only for the initial data transmission.
+void MobilityClient::sendContactData(const QContactManager &manager)
+{
+ QContactSimulatorData data;
+ QContactMemoryEngineData *engineData = static_cast<QContactMemoryEngine *>(manager.d->m_engine)->d;
+ data.m_selfContactId = engineData->m_selfContactId;
+ data.m_contacts = engineData->m_contacts;
+ data.m_contactIds = engineData->m_contactIds;
+ data.m_relationships = engineData->m_relationships;
+ data.m_orderedRelationships = engineData->m_orderedRelationships;
+ data.m_definitionIds = engineData->m_definitionIds;
+ data.m_definitions = engineData->m_definitions;
+ data.m_nextContactId = engineData->m_nextContactId;
+
+ // to avoid collisions, give each client a large area for unique detail ids
+ // ### TODO: Ugly hack.
+ contactsClientsCount++;
+ data.m_lastDetailId = std::numeric_limits<int>::max() / 1000 * contactsClientsCount;
+
+ QtSimulatorPrivate::RemoteMetacall<void>::call(mSendSocket, QtSimulatorPrivate::NoSync,
+ "setContactData", data);
+}
+
+void MobilityClient::setRequestsSystemInfo()
+{
+ connect(mMobilityServer->mMobility->mSystemInfoStorageUi, SIGNAL(storageDataChanged(StorageSystemInfoUi::StorageData)),
+ SLOT(sendSystemStorageInfo(StorageSystemInfoUi::StorageData)));
+ connect(mMobilityServer->mMobility->mSystemInfoGenericUi, SIGNAL(genericDataChanged(GenericSystemInfoUi::GenericData)),
+ SLOT(sendSystemGenericInfo(GenericSystemInfoUi::GenericData)));
+ connect(mMobilityServer->mMobility->mSystemInfoNetworkUi, SIGNAL(networkDataChanged(NetworkSystemInfoUi::NetworkData)),
+ SLOT(sendSystemNetworkInfo(NetworkSystemInfoUi::NetworkData)));
+ sendSystemGenericInfo(mMobilityServer->mMobility->mSystemInfoGenericUi->genericData());
+ sendSystemNetworkInfo(mMobilityServer->mMobility->mSystemInfoNetworkUi->networkData());
+ sendSystemStorageInfo(mMobilityServer->mMobility->mSystemInfoStorageUi->storageData());
+ QtSimulatorPrivate::RemoteMetacall<void>::call(mSendSocket, QtSimulatorPrivate::NoSync,
+ "initialSystemInfoDataSent");
+}
+
+void MobilityClient::setRequestsLocationInfo()
+{
+ connect(mMobilityServer->mMobility->mLocationUi, SIGNAL(locationChanged(LocationUi::LocationData)),
+ SLOT(sendLocationData(LocationUi::LocationData)));
+ sendLocationData(mMobilityServer->mMobility->mLocationUi->locationData());
+ QtSimulatorPrivate::RemoteMetacall<void>::call(mSendSocket, QtSimulatorPrivate::NoSync,
+ "initialLocationDataSent");
+}
+
+void MobilityClient::setRequestsContactInfo()
+{
+ connect(mMobilityServer->mMobility->mContacts, SIGNAL(contactsDataChanged(QContactManager)), this, SLOT(sendContactData(QContactManager)));
+ connect(mMobilityServer->mMobility->mContacts, SIGNAL(contactsAdded(QList<QContactLocalId>)), this, SLOT(sendAddedContacts(QList<QContactLocalId>)));
+ connect(mMobilityServer->mMobility->mContacts, SIGNAL(contactsChanged(QList<QContactLocalId>)), this, SLOT(sendChangedContacts(QList<QContactLocalId>)));
+ connect(mMobilityServer->mMobility->mContacts, SIGNAL(contactsRemoved(QList<QContactLocalId>)), this, SLOT(sendRemovedContacts(QList<QContactLocalId>)));
+ connect(mMobilityServer->mMobility->mContacts, SIGNAL(relationshipsAdded(QList<QContactLocalId>)), this, SLOT(sendRelationshipsFor(QList<QContactLocalId>)));
+ connect(mMobilityServer->mMobility->mContacts, SIGNAL(relationshipsRemoved(QList<QContactLocalId>)), this, SLOT(sendRelationshipsFor(QList<QContactLocalId>)));
+}
+
+void MobilityClient::setRequestsSensors()
+{
+ connect(mMobilityServer->mMobility->mSensorsUi, SIGNAL(sensorsDataChanged(SensorsUi::SensorsData)),
+ SLOT(sendSensorsData(SensorsUi::SensorsData)));
+ sendSensorsData(mMobilityServer->mMobility->mSensorsUi->sensorsData());
+ QtSimulatorPrivate::RemoteMetacall<void>::call(mSendSocket, QtSimulatorPrivate::NoSync,
+ "initialSensorsDataSent");
+}
+
+void MobilityClient::triggerContactDataResend()
+{
+ mMobilityServer->mMobility->mContacts->publish();
+ QtSimulatorPrivate::RemoteMetacall<void>::call(mSendSocket, QtSimulatorPrivate::NoSync,
+ "initialContactDataSent");
+}
+
+Simulator::SaveContactReply MobilityClient::requestSaveContact(const QContact &contact)
+{
+ Simulator::SaveContactReply reply;
+ reply.savedContact = contact;
+
+ // execute change and notify other clients in the process
+ mNotifyClientOnContactsChange = false;
+ mMobilityServer->mMobility->mContacts->manager()->saveContact(&reply.savedContact);
+ mNotifyClientOnContactsChange = true;
+
+ reply.error = mMobilityServer->mMobility->mContacts->manager()->error();
+ return reply;
+}
+
+int MobilityClient::requestRemoveContact(uint id)
+{
+ // execute change and notify other clients in the process
+ mNotifyClientOnContactsChange = false;
+ mMobilityServer->mMobility->mContacts->manager()->removeContact(id);
+ mNotifyClientOnContactsChange = true;
+
+ return static_cast<int>(mMobilityServer->mMobility->mContacts->manager()->error());
+}
+
+Simulator::SaveRelationshipReply MobilityClient::requestSaveRelationship(const QContactRelationship &relationship)
+{
+ Simulator::SaveRelationshipReply reply;
+ reply.savedRelationship = relationship;
+
+ // execute change and notify other clients in the process
+ mNotifyClientOnContactsChange = false;
+ mMobilityServer->mMobility->mContacts->manager()->saveRelationship(&reply.savedRelationship);
+ mNotifyClientOnContactsChange = true;
+
+ reply.error = mMobilityServer->mMobility->mContacts->manager()->error();
+ return reply;
+}
+
+int MobilityClient::requestRemoveRelationship(const QContactRelationship &relationship)
+{
+ // execute change and notify other clients in the process
+ mNotifyClientOnContactsChange = false;
+ mMobilityServer->mMobility->mContacts->manager()->removeRelationship(relationship);
+ mNotifyClientOnContactsChange = true;
+
+ return static_cast<int>(mMobilityServer->mMobility->mContacts->manager()->error());
+}
+
+void MobilityClient::sendAddedContacts(const QList<QContactLocalId> &contactIds)
+{
+ if (!mNotifyClientOnContactsChange)
+ return;
+
+ foreach (QContactLocalId id, contactIds) {
+ const QContact &contact = mMobilityServer->mMobility->mContacts->manager()->contact(id);
+ QtSimulatorPrivate::RemoteMetacall<void>::call(mSendSocket, QtSimulatorPrivate::NoSync,
+ "addContact", contact);
+ }
+}
+
+void MobilityClient::sendChangedContacts(const QList<QContactLocalId> &contactIds)
+{
+ if (!mNotifyClientOnContactsChange)
+ return;
+
+ foreach (QContactLocalId id, contactIds) {
+ const QContact &contact = mMobilityServer->mMobility->mContacts->manager()->contact(id);
+ QtSimulatorPrivate::RemoteMetacall<void>::call(mSendSocket, QtSimulatorPrivate::NoSync,
+ "changeContact", contact);
+ }
+}
+
+void MobilityClient::sendRemovedContacts(const QList<QContactLocalId> &contactIds)
+{
+ if (!mNotifyClientOnContactsChange)
+ return;
+
+ foreach (QContactLocalId id, contactIds) {
+ QtSimulatorPrivate::RemoteMetacall<void>::call(mSendSocket, QtSimulatorPrivate::NoSync,
+ "removeContact", id);
+ }
+}
+
+void MobilityClient::sendRelationshipsFor(const QList<QContactLocalId> &contactIds)
+{
+ if (!mNotifyClientOnContactsChange)
+ return;
+
+ QContactManager *manager = mMobilityServer->mMobility->mContacts->manager();
+
+ foreach (QContactLocalId localId, contactIds) {
+ QContactId id(manager->contact(localId).id());
+ QList<QContactRelationship> relationships(manager->relationships(id));
+ QVariantList list;
+ foreach (const QContactRelationship &r, relationships)
+ list.append(QVariant::fromValue(r));
+ QtSimulatorPrivate::RemoteMetacall<void>::call(mSendSocket, QtSimulatorPrivate::NoSync,
+ "setRelationships", localId, list);
+ }
+}
diff --git a/src/mobility/mobilitymanager.h b/src/mobility/mobilitymanager.h
new file mode 100644
index 0000000..0888f3d
--- /dev/null
+++ b/src/mobility/mobilitymanager.h
@@ -0,0 +1,130 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef MOBILITY_H
+#define MOBILITY_H
+
+#include "sensorsui.h"
+#include "systeminfonetworkui.h"
+#include "systeminfostorageui.h"
+#include "systeminfogenericui.h"
+
+#include <remotecontrolwidget/locationui.h>
+
+#include <systeminfo/qsysteminfodata_simulator_p.h>
+#include <location/qgeopositioninfodata_simulator_p.h>
+#include <mobilitysimulator/mobilityconnection_p.h>
+#include <contacts/engines/qcontactmemorybackenddata_simulator_p.h>
+#include <contacts/engines/qcontactmemorybackenddata_simulator_p.h>
+#include <../plugins/sensors/simulator/qsensordata_simulator_p.h>
+
+class QLocalSocket;
+class QLocalServer;
+class MobilityData;
+class MobilityClient;
+namespace QtMobility {
+ class QContactManager;
+ class QContact;
+}
+// Required to give some slots below a connectable signature.
+using namespace QtMobility;
+
+class MobilityServer : public QObject
+{
+ Q_OBJECT
+public:
+ explicit MobilityServer(MobilityData *mobility, QObject *parent = 0);
+ ~MobilityServer();
+
+private slots:
+ void newConnection();
+
+private:
+ void removeClient(MobilityClient *c);
+
+ QLocalServer *mServer;
+ QList<MobilityClient *> mClients;
+
+ MobilityData *mMobility;
+
+ friend class MobilityClient;
+};
+
+class MobilityClient : public QObject
+{
+ Q_OBJECT
+public:
+ MobilityClient(qint64 pid, QLocalSocket *receiveSocket, MobilityServer *server);
+ ~MobilityClient();
+
+public slots:
+ void sendSystemStorageInfo(const StorageSystemInfoUi::StorageData &data);
+ void sendSystemGenericInfo(const GenericSystemInfoUi::GenericData &data);
+ void sendSystemNetworkInfo(const NetworkSystemInfoUi::NetworkData &data);
+
+ void sendLocationData(const LocationUi::LocationData &data);
+
+ void sendContactData(const QContactManager &manager);
+
+ void sendSensorsData(const SensorsUi::SensorsData &data);
+
+private slots:
+ void disconnect();
+ void readyRead();
+
+ void sendAddedContacts(const QList<QContactLocalId> &);
+ void sendChangedContacts(const QList<QContactLocalId> &);
+ void sendRemovedContacts(const QList<QContactLocalId> &);
+ void sendRelationshipsFor(const QList<QContactLocalId> &);
+
+ // called remotely
+ void setRequestsSystemInfo();
+ void setRequestsLocationInfo();
+ void setRequestsContactInfo();
+ void setRequestsSensors();
+ void triggerContactDataResend();
+
+ QtMobility::Simulator::SaveContactReply requestSaveContact(const QtMobility::QContact &contact);
+ int requestRemoveContact(uint id);
+ QtMobility::Simulator::SaveRelationshipReply requestSaveRelationship(const QtMobility::QContactRelationship &relationship);
+ int requestRemoveRelationship(const QtMobility::QContactRelationship &relationship);
+
+private:
+ qint64 mPid;
+ QLocalSocket *mReceiveSocket;
+ QLocalSocket *mSendSocket;
+ QByteArray mReadBuffer;
+ MobilityServer *mMobilityServer;
+
+ bool mNotifyClientOnContactsChange;
+
+ static int contactsClientsCount;
+};
+
+#endif // MOBILITY_H
diff --git a/src/other/application.cpp b/src/other/application.cpp
new file mode 100644
index 0000000..840709a
--- /dev/null
+++ b/src/other/application.cpp
@@ -0,0 +1,349 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "application.h"
+#include "applicationmanager.h"
+#include "displaywidget.h"
+#include "phononmanager.h"
+#include "widgetmanager.h"
+#include "widget.h"
+
+#include <QtCore/QTimer>
+#include <QtGui/QDesktopWidget>
+#include <QtGui/QApplication>
+#include <QtGui/QMenu>
+#include <QtNetwork/QLocalSocket>
+
+Application::Application(const QString &name, int id, qint64 pid, QLocalSocket *s, ApplicationManager *m)
+ : m_name(name)
+ , m_id(id)
+ , m_processId(pid)
+ , receiveSocket(s)
+ , sendSocket(0)
+ , applicationManager(m)
+ , mPhononManager(0)
+ , killTimer(0)
+{
+ readData(); // maybe there's already data to read
+ connect(receiveSocket, SIGNAL(readyRead()), this, SLOT(readData()));
+ connect(receiveSocket, SIGNAL(disconnected()), this, SLOT(disconnect()));
+
+ sendSocket = new QLocalSocket(this);
+ sendSocket->connectToServer(QtSimulatorPrivate::qt_applicationServerName(pid));
+
+ QtSimulatorPrivate::qt_registerUserTypes();
+}
+
+Application::~Application()
+{
+ receiveSocket->disconnectFromServer();
+ receiveSocket->deleteLater();
+}
+
+void Application::readData()
+{
+ readBuffer += receiveSocket->readAll();
+ forever {
+ QtSimulatorPrivate::IncomingRemoteMetacall rpc;
+ if (rpc.read(&readBuffer)) {
+ bool callWasHandled = false;
+ callWasHandled = rpc.call(receiveSocket, this) || rpc.call(receiveSocket, mWidgetManager);
+ if (!callWasHandled) {
+ mPhononManager->setCurrentApplication(this);
+ callWasHandled = rpc.call(receiveSocket, mPhononManager);
+ }
+ if (callWasHandled) {
+ continue;
+ }
+ qWarning("Ignoring a call to %s, No such slot in the receiving objects.", rpc.signature().data());
+ }
+ break;
+ }
+}
+
+/**
+ * Tries hard to kill the application by regularly sending quit messages.
+ */
+void Application::kill()
+{
+ if (!killTimer) {
+ killTimer = new QTimer(this);
+ connect(killTimer, SIGNAL(timeout()), this, SLOT(kill()));
+ killTimer->start(100);
+ }
+
+ QtSimulatorPrivate::RemoteMetacall<void>::call(sendSocket, QtSimulatorPrivate::NoSync,
+ "killApplication");
+}
+
+void Application::setPhononManager(PhononManager *manager)
+{
+ mPhononManager = manager;
+}
+
+void Application::setWidgetManager(WidgetManager *wm)
+{
+ mWidgetManager = wm;
+}
+
+DisplayWidget* Application::display() const
+{
+ return mWidgetManager->display();
+}
+
+int Application::createWidget(int parentId, QRect geometry, QString title)
+{
+ return mWidgetManager->create(
+ parentId,
+ geometry,
+ title,
+ this);
+}
+
+QtSimulatorPrivate::DisplayInfo Application::displayInfo()
+{
+ return applicationManager->displayInfo();
+}
+
+QString Application::systemFontDirectory()
+{
+ return applicationManager->fontDirectory();
+}
+
+void Application::disconnect()
+{
+ this->deleteLater();
+ applicationManager->unregisterApplication(m_id);
+}
+
+void Application::updateActionFromVariantList(QAction* action, const QVariantList& list)
+{
+ action->setAutoRepeat(list.at(0).toBool());
+
+ QIcon icon = list.at(1).value<QIcon>();
+ // ### don't set icons for now. Something's wrong with it.
+ //action->setIcon(icon);
+ //action->setIconText(list.at(2).toString());
+ action->setCheckable(list.at(3).toBool());
+ action->setChecked(list.at(4).toBool());
+ action->setEnabled(list.at(5).toBool());
+ action->setIconVisibleInMenu(list.at(6).toBool());
+ action->setSeparator(list.at(7).toBool());
+ action->setVisible(list.at(8).toBool());
+ QString text = list.at(9).toString();
+ action->setText(text);
+ action->setIconVisibleInMenu(list.at(10).toBool());
+
+ QtSimulatorPrivate::RemotePointer remoteMenu = list.at(11).value<QtSimulatorPrivate::RemotePointer>();
+ if (remoteMenu) {
+ QMenu* menu = provideMenu(remoteMenu);
+ action->setMenu(menu);
+ }
+}
+
+Application::SimulatorActionData Application::variantListToSimulatorActionData(QVariantList& list, bool createAction)
+{
+ SimulatorActionData item;
+ QVariant remotePointerVariant = list.at(12);
+ item.remotePointer = remotePointerVariant.value<QtSimulatorPrivate::RemotePointer>();
+
+ if (createAction) {
+ item.action = new QAction(0);
+ item.action->setProperty("remotePointer", remotePointerVariant);
+ connect(item.action, SIGNAL(triggered()), SLOT(onMenuActionTriggered()));
+ updateActionFromVariantList(item.action, list);
+ } else {
+ item.action = 0;
+ }
+
+ return item;
+}
+
+void Application::registerMenuBar(QtSimulatorPrivate::RemotePointer remoteMenuBar, int widgetId)
+{
+ //qDebug("Application::registerMenuBar");
+ QMenuBar* menuBar = new QMenuBar();
+ mMenuBarHash.insert(remoteMenuBar, menuBar);
+ menuBar->setNativeMenuBar(false);
+
+ Widget* widget = mWidgetManager->widgetForId(widgetId);
+ if (widget)
+ widget->setMenuBar(menuBar);
+}
+
+void Application::unregisterMenuBar(QtSimulatorPrivate::RemotePointer remoteMenuBar, int widgetId)
+{
+ Widget* widget = mWidgetManager->widgetForId(widgetId);
+ if (widget)
+ widget->setMenuBar(0);
+
+ QMenuBar* menuBar = mMenuBarHash.value(remoteMenuBar, 0);
+ delete menuBar;
+ mMenuBarHash.remove(remoteMenuBar);
+}
+
+void Application::reparentMenuBar(QtSimulatorPrivate::RemotePointer remoteMenuBar, int oldWidgetId, int newWidgetId)
+{
+ //qDebug("Application::reparentMenuBar from %d to %d", oldWidgetId, newWidgetId);
+ QMenuBar* menuBar = mMenuBarHash.value(remoteMenuBar, 0);
+ Widget* oldWidget = mWidgetManager->widgetForId(oldWidgetId);
+ Widget* newWidget = mWidgetManager->widgetForId(newWidgetId);
+ if (oldWidget)
+ oldWidget->setMenuBar(0);
+ if (newWidget)
+ newWidget->setMenuBar(menuBar);
+}
+
+void Application::menuBarAddAction(QtSimulatorPrivate::RemotePointer remoteMenuBar, QVariantList actionData, QtSimulatorPrivate::RemotePointer remoteBeforeAction)
+{
+ //qDebug("Application::menuBarAddAction %p", remoteMenuBar.ptr);
+ QMenuBar* menuBar = mMenuBarHash.value(remoteMenuBar, 0);
+ if (!menuBar) {
+ qWarning("Application::menuBarAddAction can't find menuBar.");
+ return;
+ }
+
+ QAction *beforeAction;
+ beforeAction = mActionHash.value(remoteBeforeAction, 0);
+
+ SimulatorActionData item = variantListToSimulatorActionData(actionData);
+ mActionHash.insert(item.remotePointer, item.action);
+
+ menuBar->insertAction(beforeAction, item.action);
+}
+
+void Application::menuBarSyncAction(QVariantList actionData)
+{
+ //qDebug("Application::menuBarSyncAction");
+ SimulatorActionData item = variantListToSimulatorActionData(actionData, false);
+ QAction* action = mActionHash.value(item.remotePointer, 0);
+ if (!action) {
+ qWarning("Application::menuBarSyncAction can't find action.");
+ return;
+ }
+
+ updateActionFromVariantList(action, actionData);
+}
+
+void Application::menuBarRemoveAction(QtSimulatorPrivate::RemotePointer remoteMenuBar, QtSimulatorPrivate::RemotePointer remoteAction)
+{
+ QMenuBar* menuBar = mMenuBarHash.value(remoteMenuBar, 0);
+ if (!menuBar) {
+ qWarning("Application::menuBarRemoveAction can't find menuBar.");
+ return;
+ }
+ QAction* action = mActionHash.value(remoteAction, 0);
+ if (!action) {
+ qWarning("Application::menuBarRemoveAction can't find action.");
+ return;
+ }
+ mActionHash.remove(remoteAction);
+ menuBar->removeAction(action);
+ delete action;
+}
+
+QMenu* Application::provideMenu(QtSimulatorPrivate::RemotePointer remoteMenu)
+{
+ QMenu* menu = mMenuHash.value(remoteMenu, 0);
+ if (!menu) {
+ menu = new QMenu;
+ mMenuHash.insert(remoteMenu, menu);
+ }
+ return menu;
+}
+
+void Application::destroyMenu(QtSimulatorPrivate::RemotePointer remoteMenu)
+{
+ QMenu* menu = mMenuHash.value(remoteMenu, 0);
+ if (!menu) {
+ qWarning("Application::destroyMenu can't find menu.");
+ return;
+ }
+ mMenuHash.remove(remoteMenu);
+ delete menu;
+}
+
+void Application::menuAddAction(QtSimulatorPrivate::RemotePointer remoteMenu, QVariantList actionData, QtSimulatorPrivate::RemotePointer remoteBeforeAction)
+{
+ QMenu* menu = provideMenu(remoteMenu);
+ if (!menu) {
+ qWarning("Application::menuAddAction can't find menu.");
+ return;
+ }
+
+ QAction* beforeAction = mActionHash.value(remoteBeforeAction, 0);
+ SimulatorActionData smi = variantListToSimulatorActionData(actionData);
+ menu->insertAction(beforeAction, smi.action);
+ mActionHash.insert(smi.remotePointer, smi.action);
+}
+
+void Application::menuSyncAction(QVariantList actionData)
+{
+ SimulatorActionData smi = variantListToSimulatorActionData(actionData, false);
+ QAction* action = mActionHash.value(smi.remotePointer, 0);
+ if (!action) {
+ qWarning("Application::menuSyncAction can't find action.");
+ return;
+ }
+ updateActionFromVariantList(action, actionData);
+}
+
+void Application::menuRemoveAction(QtSimulatorPrivate::RemotePointer remoteMenu, QtSimulatorPrivate::RemotePointer remoteAction)
+{
+ QMenu* menu = provideMenu(remoteMenu);
+ if (!menu) {
+ qWarning("Application::menuRemoveAction can't find menu.");
+ return;
+ }
+
+ QAction* action = mActionHash.value(remoteAction, 0);
+ if (!action) {
+ qWarning("Application::menuRemoveAction can't find action.");
+ return;
+ }
+
+ menu->removeAction(action);
+ mActionHash.remove(remoteAction);
+ delete action;
+}
+
+void Application::onMenuActionTriggered()
+{
+ QAction* action = qobject_cast<QAction*>(sender());
+ Q_ASSERT(action);
+ if (!action)
+ return;
+
+ QVariant v = action->property("remotePointer");
+ if (v.isNull())
+ return;
+
+ QtSimulatorPrivate::RemoteMetacall<void>::call(sendSocket, QtSimulatorPrivate::NoSync,
+ "triggerAction", v);
+}
diff --git a/src/other/application.h b/src/other/application.h
new file mode 100644
index 0000000..fc75ff2
--- /dev/null
+++ b/src/other/application.h
@@ -0,0 +1,123 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef APPLICATION_H
+#define APPLICATION_H
+
+#include "qsimulatordata_p.h"
+#include <QtGui/QMenuBar>
+#include <QtCore/QObject>
+#include <QtCore/QRect>
+#include <QtCore/QHash>
+
+class ApplicationManager;
+class PhononManager;
+class WidgetManager;
+class DisplayWidget;
+class QString;
+class QLocalSocket;
+
+class Application : public QObject
+{
+ Q_OBJECT
+public:
+ ~Application();
+ inline QString name() const { return m_name; }
+ inline int id() const { return m_id; }
+ qint64 processId() const { return m_processId; }
+
+ void setPhononManager(PhononManager *manager);
+ void setWidgetManager(WidgetManager *wm);
+ DisplayWidget* display() const;
+ QLocalSocket *socket() { return sendSocket; }
+
+signals:
+ void widgetUpdate();
+ void widgetDestroyed();
+
+public slots:
+ void readData();
+ void kill();
+
+private slots:
+ // called remotely
+ void disconnect();
+ QtSimulatorPrivate::DisplayInfo displayInfo();
+ QString systemFontDirectory();
+ int createWidget(int parentId, QRect geometry, QString title);
+
+ void registerMenuBar(QtSimulatorPrivate::RemotePointer remoteMenuBar, int widgetId);
+ void unregisterMenuBar(QtSimulatorPrivate::RemotePointer remoteMenuBar, int widgetId);
+ void reparentMenuBar(QtSimulatorPrivate::RemotePointer remoteMenuBar, int oldWidgetId, int newWidgetId);
+ void menuBarAddAction(QtSimulatorPrivate::RemotePointer remoteMenuBar, QVariantList actionData, QtSimulatorPrivate::RemotePointer beforeAction);
+ void menuBarSyncAction(QVariantList actionData);
+ void menuBarRemoveAction(QtSimulatorPrivate::RemotePointer remoteMenuBar, QtSimulatorPrivate::RemotePointer action);
+
+private:
+ QMenu* provideMenu(QtSimulatorPrivate::RemotePointer remoteMenu);
+private slots:
+ void destroyMenu(QtSimulatorPrivate::RemotePointer remoteMenu);
+ void menuAddAction(QtSimulatorPrivate::RemotePointer menu, QVariantList actionData, QtSimulatorPrivate::RemotePointer beforeAction);
+ void menuSyncAction(QVariantList actionData);
+ void menuRemoveAction(QtSimulatorPrivate::RemotePointer menu, QtSimulatorPrivate::RemotePointer action);
+ void onMenuActionTriggered();
+
+private:
+ friend class ApplicationManager;
+ explicit Application(const QString &name,
+ int id,
+ qint64 pid,
+ QLocalSocket *s,
+ ApplicationManager* m);
+
+ struct SimulatorActionData
+ {
+ QAction* action;
+ QtSimulatorPrivate::RemotePointer remotePointer;
+ };
+
+ SimulatorActionData variantListToSimulatorActionData(QVariantList& list, bool createAction = true);
+ void updateActionFromVariantList(QAction* action, const QVariantList& list);
+
+ QString m_name;
+ int m_id; // TODO: can we just use the process id?
+ qint64 m_processId;
+ QLocalSocket *receiveSocket, *sendSocket;
+ QByteArray readBuffer;
+ ApplicationManager *applicationManager;
+ PhononManager* mPhononManager;
+ WidgetManager *mWidgetManager;
+ QHash<QtSimulatorPrivate::RemotePointer, QAction*> mActionHash;
+ QHash<QtSimulatorPrivate::RemotePointer, QMenuBar*> mMenuBarHash;
+ QHash<QtSimulatorPrivate::RemotePointer, QMenu*> mMenuHash;
+
+ QTimer *killTimer;
+};
+
+#endif // APPLICATION_H
diff --git a/src/other/applicationmanager.cpp b/src/other/applicationmanager.cpp
new file mode 100644
index 0000000..9ccfcea
--- /dev/null
+++ b/src/other/applicationmanager.cpp
@@ -0,0 +1,382 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "application.h"
+#include "applicationmanager.h"
+#include "applicationtablewidget.h"
+#include "deviceitem.h"
+#include "widgetmanager.h"
+#include "widget.h"
+
+#include <QtCore/QTimer>
+#include <QtGui/QLayout>
+#include <QtGui/QFileDialog>
+#include <QtGui/QMessageBox>
+#include <QtGui/QDesktopWidget>
+#include <QtGui/QApplication>
+#include <QtNetwork/QLocalServer>
+#include <QtNetwork/QLocalSocket>
+
+#include <cmath>
+
+#ifdef Q_OS_WIN
+# include <windows.h>
+# include <Tlhelp32.h>
+#elif defined(Q_OS_UNIX)
+# include <sys/types.h>
+# include <unistd.h>
+# include <errno.h>
+#endif
+
+namespace {
+ int gAppIdCounter = 0;
+}
+
+ApplicationManager::ApplicationManager(QObject *parent)
+ : QObject(parent)
+ , mServer(0)
+ , mPhononManager(0)
+ , mWidgetManager(0)
+ , mTableWidget(0)
+ , mSimulatorStarted(false)
+{
+ // simulator socket connection
+ QLocalSocket checkSocket;
+ checkSocket.connectToServer(SIMULATOR_DISPLAY_SERVERNAME);
+ if (checkSocket.waitForConnected(100)) {
+ mSimulatorStarted = true;
+ return;
+ }
+
+ mServer = new QLocalServer();
+ QLocalServer::removeServer(SIMULATOR_DISPLAY_SERVERNAME);
+ if (!mServer->listen(SIMULATOR_DISPLAY_SERVERNAME)) {
+ qFatal("Could not open mServer");
+ }
+ connect(mServer, SIGNAL(newConnection()), this, SLOT(handleConnection()));
+ connect(this, SIGNAL(applicationRegistered(Application*)), this, SLOT(registerApplication(Application*)));
+
+ // debug window
+ mTableWidget = new ApplicationTableWidget();
+ mConfigWidget = new QWidget();
+ QHBoxLayout* layout = new QHBoxLayout;
+ layout->addWidget(mTableWidget);
+ mConfigWidget->setLayout(layout);
+ connect(mTableWidget, SIGNAL(killApplication(int)), this, SLOT(killApplication(int)));
+
+ // watch for simulator clients that have been terminated
+ QTimer* watchDogTimer = new QTimer(this);
+ watchDogTimer->setObjectName(QLatin1String("watchDogTimer"));
+ connect(watchDogTimer, SIGNAL(timeout()), SLOT(watchDogTimer()));
+ watchDogTimer->start(5000);
+}
+
+ApplicationManager::~ApplicationManager()
+{
+ if (mServer) {
+ mServer->close();
+ QLocalServer::removeServer(SIMULATOR_DISPLAY_SERVERNAME);
+ delete mServer;
+ mServer = 0;
+ }
+ if (mTableWidget)
+ delete mTableWidget;
+}
+
+void ApplicationManager::registerApplication(Application *newApp)
+{
+ mApps.push_back(newApp);
+
+ // add to debug application table
+ mTableWidget->insertRow(0);
+ QTableWidgetItem *item = new QTableWidgetItem(QString::number(newApp->id()));
+ item->setData(0, newApp->id());
+ mTableWidget->setItem(0, 0, item);
+ mTableWidget->setItem(0, 1, new QTableWidgetItem(newApp->name()));
+ mTableWidget->sortItems(0);
+
+ if (mApps.size() == 1)
+ emit firstAppRegistered();
+ //qDebug() << "ApplicationManager registered:" << newApp->name();
+}
+
+void ApplicationManager::unregisterApplication(int id)
+{
+ emit applicationUnRegistered(id);
+ for (int i = 0; i < mApps.size(); ++i) {
+ if (mApps.at(i)->id() == id) {
+ Application* item = mApps.takeAt(i);
+ //qDebug() << "ApplicationManager removes:" << item->name();
+ item->deleteLater();
+
+ // remove from debug application table
+ for (int r = 0; r < mTableWidget->rowCount(); ++r) {
+ if (mTableWidget->item(r, 0)->data(0).toInt() == id) {
+ mTableWidget->removeRow(r);
+ break;
+ }
+ }
+ break;
+ }
+ }
+ if (mApps.isEmpty()) {
+ emit lastAppUnregistered();
+ }
+}
+
+bool ApplicationManager::hasApplications() const
+{
+ return !mApps.empty();
+}
+
+bool ApplicationManager::simulatorAlreadyStarted() const
+{
+ return mSimulatorStarted;
+}
+
+bool ApplicationManager::initializeFontDirectory()
+{
+ // make sure that we have a valid font directory
+ QDir fontDir("fonts");
+ if (!fontDir.exists()) {
+ QMessageBox errorMsg;
+ errorMsg.setWindowTitle(tr("\"%1\" folder does not exist").arg("Fonts"));
+ errorMsg.setText(tr("The \"%1\" folder could not be located in the installation directory.").arg("fonts"));
+ errorMsg.setIcon(QMessageBox::Critical);
+ errorMsg.exec();
+ return false;
+ }
+ mFontDirectory = fontDir.absolutePath();
+ return true;
+}
+
+void ApplicationManager::killApplication(int id)
+{
+ for (int i = 0; i < mApps.size(); ++i) {
+ if (mApps.at(i)->id() == id) {
+ Application* item = mApps.at(i);
+ item->kill();
+ break;
+ }
+ }
+}
+
+void ApplicationManager::killCurrentApplication()
+{
+ Widget *activeWidget = mWidgetManager->activeWidget();
+ if (!activeWidget)
+ return;
+
+ mWidgetManager->activeWidget()->owner->kill();
+}
+
+void ApplicationManager::killAllApplications()
+{
+ foreach (Application* item, mApps) {
+ item->kill();
+ }
+}
+
+Application* ApplicationManager::applicationForId(int id)
+{
+ foreach(Application* item, mApps) {
+ if (item->id() == id)
+ return item;
+ }
+ return 0;
+}
+
+
+
+void ApplicationManager::handleConnection()
+{
+ // get the incoming connection
+ QLocalSocket* socket = mServer->nextPendingConnection();
+ if (!socket->isValid())
+ qWarning() << "Invalid socket!";
+
+ using namespace QtSimulatorPrivate;
+
+ // read the command id
+ qint32 requestCommand = 0;
+ qint64 bytesToRead = sizeof(requestCommand);
+ qint64 bytesRead = qt_blockingRead(
+ socket, reinterpret_cast<char *>(&requestCommand), bytesToRead, 500);
+ if (bytesRead < bytesToRead)
+ {
+ qWarning("Dropped incoming connection, couldn't read command id.");
+ return;
+ }
+ if (requestCommand != Command::ApplicationConnect)
+ {
+ qWarning("Dropped incoming connection, it sent an invalid command.");
+ return;
+ }
+
+ // read the command
+ ApplicationConnectCommand cmd;
+ bytesToRead = sizeof(cmd.request);
+ bytesRead = qt_blockingRead(
+ socket, reinterpret_cast<char *>(&cmd.request), bytesToRead, 500);
+ if (bytesRead < bytesToRead)
+ {
+ qWarning("Dropped incoming connection, couldn't read command data.");
+ return;
+ }
+
+ // send a reply
+ cmd.reply.appId = gAppIdCounter + 1;
+ qint64 bytesToWrite = sizeof(cmd.reply);
+ qint64 bytesWritten = qt_blockingWrite(
+ socket, reinterpret_cast<const char *>(&cmd.reply), bytesToWrite, 500);
+ if (bytesWritten < bytesToWrite)
+ {
+ qWarning("Dropped incoming connection, couldn't send connect reply.");
+ return;
+ }
+
+ // success: register new application
+ gAppIdCounter++;
+ Application *app = new Application(QString::fromLatin1(cmd.request.applicationName),
+ cmd.reply.appId, cmd.request.applicationPid, socket, this);
+ app->setPhononManager(mPhononManager);
+ app->setWidgetManager(mWidgetManager);
+ emit applicationRegistered(app);
+}
+
+void ApplicationManager::setPhononManager(PhononManager *manager)
+{
+ Q_ASSERT(!mPhononManager);
+ mPhononManager = manager;
+}
+
+void ApplicationManager::setWidgetManager(WidgetManager *widMan)
+{
+ // changing the widget manager not yet supported
+ Q_ASSERT(!mWidgetManager);
+
+ mWidgetManager = widMan;
+
+ // basic display info data that's fixed for a widget manager
+ QImage tmp(16, 16, widMan->imageFormat());
+ mDisplayInfo.format = tmp.format();
+ mDisplayInfo.numColors = tmp.numColors();
+ mDisplayInfo.depth = tmp.depth();
+ QDesktopWidget *desktop = QApplication::desktop();
+ mDisplayInfo.hostDpi = QSize(desktop->logicalDpiX(), desktop->logicalDpiY());
+}
+
+QString ApplicationManager::fontDirectory()
+{
+ return mFontDirectory;
+}
+
+const QtSimulatorPrivate::DisplayInfo &ApplicationManager::displayInfo()
+{
+ return mDisplayInfo;
+}
+
+void ApplicationManager::watchDogTimer()
+{
+#ifdef Q_OS_WIN
+ QHash<qint64, Application*> pidMapping;
+ foreach (Application* app, mApps)
+ pidMapping.insert(app->processId(), app);
+
+ HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+ if (hSnapShot == INVALID_HANDLE_VALUE) {
+ QTimer* watchDogTimer = findChild<QTimer*>(QLatin1String("watchDogTimer"));
+ watchDogTimer->stop();
+ qWarning("Cannot create process snapshot. Watchdog timer stopped.");
+ return;
+ }
+ BOOL bSuccess;
+ PROCESSENTRY32 processEntry;
+ processEntry.dwSize = sizeof(processEntry);
+ bSuccess = Process32First(hSnapShot, &processEntry);
+ while (bSuccess) {
+ Application* app = pidMapping.value(processEntry.th32ProcessID, 0);
+ if (app)
+ pidMapping.remove(processEntry.th32ProcessID);
+ bSuccess = Process32Next(hSnapShot, &processEntry);
+ }
+ CloseHandle(hSnapShot);
+
+ QHash<qint64, Application*>::iterator it;
+ for (it = pidMapping.begin(); it != pidMapping.end(); ++it)
+ watchDogBark(it.value());
+
+#elif defined(Q_OS_UNIX)
+ foreach (Application *app, mApps) {
+ pid_t pgid = getpgid(app->processId());
+ if (pgid == -1 && errno == ESRCH)
+ watchDogBark(app);
+ }
+
+#else
+ QTimer* watchDogTimer = findChild<QTimer*>(QLatin1String("watchDogTimer"));
+ watchDogTimer->stop();
+ qWarning("ApplicationManager::watchDogTimer not implemented");
+#endif
+}
+
+void ApplicationManager::watchDogBark(Application* deadApp)
+{
+ qWarning() << "Application died without unregistering. Unregistering now:" << deadApp->name();
+ unregisterApplication(deadApp->id());
+}
+
+
+void ApplicationManager::updateDisplayInformation(const QSize &resolution, const DeviceData &device)
+{
+ using namespace std;
+ qreal pixelDiagonal = sqrt(pow((qreal)resolution.width(), 2) + pow((qreal)resolution.height(), 2));
+ QSizeF displaySizeInch(QSizeF(resolution) * device.diagonalInInch / pixelDiagonal);
+
+ mDisplayInfo.size = resolution;
+ mDisplayInfo.availableRect = device.availableGeometry;
+
+ // calculate dpi
+ if (device.forceDpi != -1) {
+ mDisplayInfo.dpi = QSize(device.forceDpi, device.forceDpi);
+ } else {
+ mDisplayInfo.dpi.setWidth(resolution.width() / displaySizeInch.width());
+ mDisplayInfo.dpi.setHeight(resolution.height() / displaySizeInch.height());
+ }
+
+ mDisplayInfo.defaultFontSize = device.defaultFontSize;
+ mDisplayInfo.style = device.style;
+
+ const qreal MMperInch = 25.4;
+ mDisplayInfo.sizeMM = QSize(displaySizeInch.width() * MMperInch, displaySizeInch.height() * MMperInch);
+
+ foreach (Application *application, mApps)
+ QtSimulatorPrivate::RemoteMetacall<void>::call(application->socket(), QtSimulatorPrivate::NoSync,
+ "updateDisplayInformation");
+}
diff --git a/src/other/applicationmanager.h b/src/other/applicationmanager.h
new file mode 100644
index 0000000..7100397
--- /dev/null
+++ b/src/other/applicationmanager.h
@@ -0,0 +1,100 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef APPLICATIONMANAGER_H
+#define APPLICATIONMANAGER_H
+
+#include "qsimulatordata_p.h"
+#include <QtCore/QObject>
+#include <QtCore/QSize>
+
+class Application;
+class ApplicationTableWidget;
+class PhononManager;
+class WidgetManager;
+class QLocalServer;
+class QMenuBar;
+struct DeviceData;
+
+class ApplicationManager : public QObject
+{
+ Q_OBJECT
+public:
+ ApplicationManager(QObject* parent = 0);
+ ~ApplicationManager();
+
+ Application* applicationForId(int);
+ void setPhononManager(PhononManager *manager);
+ void setWidgetManager(WidgetManager *widMan);
+ inline QWidget* logWidget() { return mConfigWidget; }
+
+ QString fontDirectory();
+ const QtSimulatorPrivate::DisplayInfo &displayInfo();
+
+ bool hasApplications() const;
+ bool simulatorAlreadyStarted() const;
+ bool initializeFontDirectory();
+
+signals:
+ void applicationRegistered(Application*);
+ void applicationUnRegistered(int id);
+ void applicationTimedOut(int id);
+ void firstAppRegistered();
+ void lastAppUnregistered();
+
+public slots:
+ void handleConnection();
+ void registerApplication(Application*);
+ void unregisterApplication(int id);
+ void killApplication(int id);
+ void killCurrentApplication();
+ void killAllApplications();
+ void updateDisplayInformation(const QSize &resolution, const DeviceData &device);
+
+protected slots:
+ void watchDogTimer();
+
+private:
+ void watchDogBark(Application* deadApp);
+
+private:
+ QLocalServer *mServer;
+ PhononManager *mPhononManager;
+ WidgetManager *mWidgetManager;
+ QList<Application*> mApps;
+ ApplicationTableWidget *mTableWidget;
+ QWidget *mConfigWidget;
+ QString mFontDirectory;
+
+ bool mSimulatorStarted;
+
+ QtSimulatorPrivate::DisplayInfo mDisplayInfo;
+};
+
+#endif // APPLICATIONMANAGER_H
diff --git a/src/other/configurationreader.cpp b/src/other/configurationreader.cpp
new file mode 100644
index 0000000..392b2fa
--- /dev/null
+++ b/src/other/configurationreader.cpp
@@ -0,0 +1,172 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "configurationreader.h"
+#include "deviceitem.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtCore/QDebug>
+#include <QtCore/QMetaEnum>
+
+bool ConfigurationReader::processDir(QDir *dir, QList<DeviceData>& deviceDataList)
+{
+ mErrorMessages.clear();
+ mCurrentDir = dir;
+
+ bool noErrors = true;
+ foreach (const QString& modelDirName, dir->entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
+ if (!dir->cd(modelDirName))
+ continue;
+
+ foreach(const QString& fileName, dir->entryList(QStringList() << "*.config", QDir::Files))
+ {
+ mCurrentConfigFile = dir->filePath(fileName);
+ QFile file(mCurrentConfigFile);
+ DeviceData data;
+ if (processFile(&file, &data))
+ deviceDataList.append(data);
+ else
+ noErrors = false;
+ }
+
+ dir->cdUp();
+ }
+
+ return noErrors;
+}
+
+bool ConfigurationReader::processFile(QFile *file, DeviceData *data)
+{
+ if (!file->open(QIODevice::ReadOnly | QIODevice::Text))
+ return false;
+
+ QString errorMsg;
+ QString fileName = file->fileName();
+ int start = fileName.lastIndexOf('/');
+ int end = fileName.lastIndexOf('.');
+ data->name = fileName.mid(start + 1, end - start - 1);
+ int lineNr=0;
+ while (!file->atEnd()) {
+ lineNr++;
+ QByteArray line = file->readLine();
+ if (!processLine(line, data, errorMsg)) {
+ error(tr("Error in line %1: %2").arg(lineNr).arg(errorMsg));
+ errorMsg.clear();
+ return false;
+ }
+ }
+ return true;
+}
+
+bool ConfigurationReader::processLine(const QByteArray &line, DeviceData *deviceData, QString& errorMsg)
+{
+ QList<QByteArray> list = line.split(':');
+ if (list.count() != 2) {
+ errorMsg = "ConfigurationReader: Invalid property. Syntax is name:value";
+ return false;
+ }
+ QByteArray parameter = list.at(0).trimmed();
+ QByteArray value = list.at(1).trimmed();
+ if (parameter == "name")
+ deviceData->name = value;
+ else if (parameter == "resolutionWidth")
+ deviceData->resolution.setWidth(value.toInt());
+ else if (parameter == "resolutionHeight")
+ deviceData->resolution.setHeight(value.toInt());
+ else if (parameter == "diagonalInInch")
+ deviceData->diagonalInInch = value.toFloat();
+ else if (parameter == "mockup") {
+ deviceData->mockupPath = mCurrentDir->filePath(value);
+ if (!mCurrentDir->exists(value)) {
+ errorMsg = tr("Mockup file %1 does not exist.").arg(deviceData->mockupPath);
+ return false;
+ }
+ } else if (parameter == "offsetX")
+ deviceData->offset.setX(value.toInt());
+ else if (parameter == "offsetY")
+ deviceData->offset.setY(value.toInt());
+ else if (parameter == "defaultFontSize")
+ deviceData->defaultFontSize = value.toInt();
+ else if (parameter == "forceDpi")
+ deviceData->forceDpi = value.toInt();
+ else if (parameter == "style")
+ deviceData->style = value;
+ else if (parameter == "button") {
+ QList<QByteArray> values = value.split(',');
+ if (values.count() != 6) {
+ errorMsg = tr("ConfigurationReader: button property requires six comma separated values\n"
+ " button:keycode,keytext,x,y,width,height");
+ return false;
+ }
+ Button b;
+ const QMetaObject &qtMetaObject(QObject::staticQtMetaObject);
+ QMetaEnum keyEnum = qtMetaObject.enumerator(qtMetaObject.indexOfEnumerator("Key"));
+ int keyCode = keyEnum.keyToValue(values[0].constData());
+ if (keyCode == -1) {
+ errorMsg = tr("ConfigurationReader: Not a valid Qt::Key name: %1").arg(values[0].data());
+ return false;
+ }
+ b.key = static_cast<Qt::Key>(keyCode);
+ b.text = values[1];
+ b.area = QRectF(values[2].toFloat(), values[3].toFloat(),
+ values[4].toFloat(), values[5].toFloat());
+ deviceData->buttons.append(b);
+ } else if (parameter == "menu") {
+ if (value == "maemoFremantle") {
+ deviceData->menuType = MaemoFremantle;
+ } else if (value == "symbianTouch") {
+ deviceData->menuType = SymbianTouch;
+ } else {
+ errorMsg = tr("ConfigurationReader: menu property requires a valid type for portrait mode\n"
+ " (top, right, bottom, left)");
+ return false;
+ }
+ } else if (parameter == "nativeOrientation") {
+ if (value == "landscape")
+ deviceData->nativeOrientation = landscapeOrientation;
+ else if (value == "portrait")
+ deviceData->nativeOrientation = portraitOrientation;
+ } else
+ return false;
+ return true;
+}
+
+void ConfigurationReader::error(const QString& msg)
+{
+ mErrorMessages.append(mCurrentConfigFile + ": " + msg);
+}
+
+QString ConfigurationReader::errorMessageLines() const
+{
+ QString msg;
+ foreach (const QString& str, mErrorMessages)
+ msg.append(str + '\n');
+ return msg;
+}
diff --git a/src/other/configurationreader.h b/src/other/configurationreader.h
new file mode 100644
index 0000000..622b2bd
--- /dev/null
+++ b/src/other/configurationreader.h
@@ -0,0 +1,64 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef CONFIGURATIONREADER_H
+#define CONFIGURATIONREADER_H
+
+#include <QtCore/QObject>
+#include <QtCore/QStringList>
+
+struct DeviceData;
+class QFile;
+class QDir;
+
+class ConfigurationReader: public QObject
+{
+ Q_OBJECT
+public:
+ bool processDir(QDir *dir, QList<DeviceData>& deviceDataList);
+ bool processFile(QFile *file, DeviceData *data);
+
+ QStringList errorMessages() const
+ {
+ return mErrorMessages;
+ }
+
+ QString errorMessageLines() const;
+
+private:
+ bool processLine(const QByteArray &line, DeviceData* deviceData, QString& errorMsg);
+ void error(const QString& msg);
+
+private:
+ QDir* mCurrentDir;
+ QString mCurrentConfigFile;
+ QStringList mErrorMessages;
+};
+
+#endif //CONFIGURATIONREADER_H
diff --git a/src/other/deviceitem.cpp b/src/other/deviceitem.cpp
new file mode 100644
index 0000000..eb20339
--- /dev/null
+++ b/src/other/deviceitem.cpp
@@ -0,0 +1,315 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "deviceitem.h"
+#include "displaywidget.h"
+#include "menu.h"
+
+#include <qmath.h>
+#include <QtCore/QState>
+#include <QtCore/QSignalTransition>
+#include <QtCore/QPropertyAnimation>
+#include <QtGui/QGraphicsSceneMouseEvent>
+
+DeviceItem::DeviceItem(QGraphicsItem *parent)
+ : QGraphicsObject(parent)
+ , isLandscape(false)
+ , mDisplay(0)
+ , mMockup(0)
+ , mMenu(0)
+{
+ mMockup = new QGraphicsPixmapItem(QPixmap(), this);
+ mDisplay = new DisplayWidget(this);
+ mDisplay->setParentItem(mMockup);
+
+ mLandscapeState = new QState;
+ mPortraitState = new QState;
+
+ const int rotationDuration = 250;
+ mLandscapeState->assignProperty(this, "rotation", -90);
+ connect(mLandscapeState, SIGNAL(exited()), this, SLOT(startRotate()));
+ QSignalTransition *l2p = mLandscapeState->addTransition(this, "rotationSignal()", mPortraitState);
+ QPropertyAnimation *l2pRotAnim = new QPropertyAnimation(this, "rotation", this);
+ l2pRotAnim->setDuration(rotationDuration);
+ l2p->addAnimation(l2pRotAnim);
+ connect(l2pRotAnim, SIGNAL(finished()), this, SLOT(setPortrait()));
+
+ mPortraitState->assignProperty(this, "rotation", 0);
+ connect(mPortraitState, SIGNAL(exited()), this, SLOT(startRotate()));
+ QSignalTransition *p2l = mPortraitState->addTransition(this, "rotationSignal()", mLandscapeState);
+ QPropertyAnimation *p2lRotAnim = new QPropertyAnimation(this, "rotation", this);
+ p2lRotAnim->setDuration(rotationDuration);
+ p2l->addAnimation(p2lRotAnim);
+ connect(p2lRotAnim, SIGNAL(finished()), this, SLOT(setLandscape()));
+
+ mStateMachine.addState(mPortraitState);
+ mStateMachine.setInitialState(mPortraitState);
+ mStateMachine.addState(mLandscapeState);
+ mStateMachine.start();
+}
+
+DeviceItem::~DeviceItem()
+{
+ if (mMenu) {
+ delete mMenu;
+ mMenu = 0;
+ }
+}
+
+DisplayWidget *DeviceItem::display()
+{
+ return mDisplay;
+}
+
+QRectF DeviceItem::boundingRect() const
+{
+ return QRectF(QPointF(-mSize.width()/2, -mSize.height()/2), mSize);
+}
+
+void DeviceItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ Q_UNUSED(painter);
+ Q_UNUSED(option);
+ Q_UNUSED(widget);
+}
+
+void DeviceItem::changeDevice(const DeviceData &data)
+{
+ // the the device mockup was not yet read, do so now
+ if (data.mockup.isNull()) {
+ data.mockup = QPixmap(data.mockupPath);
+ if (data.mockup.isNull())
+ qFatal("Could not read mockup image %s", qPrintable(data.mockupPath));
+ }
+
+ Orientation current;
+ if (isLandscape)
+ current = landscapeOrientation;
+ else
+ current = portraitOrientation;
+ if (data.nativeOrientation != mDeviceData.nativeOrientation) {
+ emit deviceChanged(current, mDeviceData.nativeOrientation, data.nativeOrientation);
+ }
+ mDeviceData = data;
+
+ // self size
+ prepareGeometryChange();
+ mSize = mDeviceData.mockup.size();
+
+ newWindowSize();
+ newViewSize();
+
+ // mockup setup
+ mMockup->setPixmap(mDeviceData.mockup);
+ mMockup->setPos(-mSize.width()/2, -mSize.height()/2);
+ mMockup->setTransformOriginPoint(mSize.width()/2, mSize.height()/2);
+
+ // button setup
+ qDeleteAll(mButtons);
+ mButtons.clear();
+ foreach (const Button &buttonmDeviceData, mDeviceData.buttons) {
+ DeviceButton *button = new DeviceButton(buttonmDeviceData, mMockup);
+ connect(button, SIGNAL(pressed(Qt::Key, QString)), this, SIGNAL(buttonPressed(Qt::Key, QString)));
+ connect(button, SIGNAL(released(Qt::Key)), this, SIGNAL(buttonReleased(Qt::Key)));
+ mButtons.append(button);
+ }
+
+ // menu setup
+ if (mMenu) {
+ delete mMenu;
+ mMenu = 0;
+ }
+ switch (mDeviceData.menuType) {
+ case MaemoFremantle:
+ mMenu = new FremantleMenu(mDisplay);
+ break;
+ case SymbianTouch:
+ mMenu = new SymbianTouchMenu(mDisplay);
+ break;
+ default:
+ break;
+ }
+ updateMenuPositionAndSize();
+ mDeviceData.availableGeometry = mAvailableGeometry;
+ // display setup
+ QPoint newPos(mDeviceData.offset);
+ QSize newResolution(mDeviceData.resolution);
+
+ if (isLandscape) {
+ newPos += QPoint(mDeviceData.resolution.width(),0);
+ newResolution.transpose();
+ }
+ mDisplay->setPos(newPos);
+ mDisplay->setSize(newResolution);
+
+ emit deviceChanged(newResolution, mDeviceData);
+}
+
+void DeviceItem::toggleOrientation()
+{
+ emit rotationSignal();
+}
+
+void DeviceItem::setLandscape()
+{
+ isLandscape = true;
+
+ newViewSize();
+
+ mDisplay->setRotation(90);
+ mDisplay->setX(mDeviceData.offset.x() + mDeviceData.resolution.width());
+ QSize newResolution = mDeviceData.resolution;
+ newResolution.transpose();
+ mDisplay->setSize(QSize(mDeviceData.resolution.height(), mDeviceData.resolution.width()));
+
+ updateMenuPositionAndSize();
+ mDeviceData.availableGeometry = mAvailableGeometry;
+
+ emit deviceChanged(newResolution, mDeviceData);
+ emit orientationChanged(landscapeOrientation, mDeviceData.nativeOrientation);
+}
+
+void DeviceItem::setPortrait()
+{
+ isLandscape = false;
+
+ newViewSize();
+
+ mDisplay->setRotation(0);
+ mDisplay->setSize(mDeviceData.resolution);
+ mDisplay->setX(mDeviceData.offset.x());
+
+ updateMenuPositionAndSize();
+ mDeviceData.availableGeometry = mAvailableGeometry;
+
+ emit deviceChanged(mDeviceData.resolution, mDeviceData);
+ emit orientationChanged(portraitOrientation, mDeviceData.nativeOrientation);
+}
+
+void DeviceItem::startRotate()
+{
+ // set the view to the maximum size
+ int rotationSide = rotationSideLength() * scale();
+ setPos(rotationSide/2, rotationSide/2);
+ emit viewSizeRequired(QSize(rotationSide, rotationSide));
+}
+
+void DeviceItem::changeScaleFactor(qreal newScaleFactor)
+{
+ setScale(newScaleFactor);
+
+ newWindowSize();
+ newViewSize();
+}
+
+void DeviceItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ mDragOffset = event->scenePos().toPoint();
+}
+
+void DeviceItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+{
+#ifndef Q_WS_X11
+ emit drag(event->screenPos() - mDragOffset);
+#else
+ ungrabMouse();
+ emit drag(event->screenPos());
+#endif
+}
+
+void DeviceItem::newViewSize()
+{
+ QSizeF windowSize = mSize * scale();
+ if (isLandscape)
+ windowSize.transpose();
+ setPos(windowSize.width()/2, windowSize.height()/2);
+ emit viewSizeRequired(windowSize.toSize());
+}
+
+void DeviceItem::newWindowSize()
+{
+ int rotationSide = rotationSideLength() * scale();
+ setPos(rotationSide/2, rotationSide/2);
+ emit sizeChanged(QSize(rotationSide, rotationSide));
+}
+
+int DeviceItem::rotationSideLength()
+{
+#ifdef Q_OS_WIN
+ return sqrt(pow(mSize.width(), 2) + pow(mSize.height(), 2));
+#else
+ return std::max(mSize.width(), mSize.height());
+#endif
+}
+
+void DeviceItem::updateMenuPositionAndSize()
+{
+ QRect displayRect;
+ if (isLandscape)
+ displayRect.setRect(0, 0, mDeviceData.resolution.height(), mDeviceData.resolution.width());
+ else
+ displayRect.setRect(0, 0, mDeviceData.resolution.width(), mDeviceData.resolution.height());
+ if (mMenu) {
+ mAvailableGeometry = mMenu->updateMenus(isLandscape, displayRect);
+ } else {
+ mAvailableGeometry = displayRect;
+ }
+ emit offsetChanged(mAvailableGeometry.topLeft());
+}
+
+DeviceButton::DeviceButton(const Button &button, QGraphicsItem *parent)
+ : QGraphicsObject(parent)
+ , mButton(button)
+{
+ setPos(button.area.topLeft());
+}
+
+QRectF DeviceButton::boundingRect() const
+{
+ return QRectF(QPointF(), mButton.area.size());
+}
+
+void DeviceButton::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ Q_UNUSED(painter);
+ Q_UNUSED(option);
+ Q_UNUSED(widget);
+}
+
+void DeviceButton::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_UNUSED(event);
+ emit pressed(mButton.key, mButton.text);
+}
+
+void DeviceButton::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_UNUSED(event);
+ emit released(mButton.key);
+}
diff --git a/src/other/deviceitem.h b/src/other/deviceitem.h
new file mode 100644
index 0000000..b824d14
--- /dev/null
+++ b/src/other/deviceitem.h
@@ -0,0 +1,173 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef DEVICEITEM_H
+#define DEVICEITEM_H
+
+#include <QtGui/QGraphicsObject>
+#include <QtCore/QStateMachine>
+
+#define SIMULATOR_MENU_Z 10000
+
+struct Button
+{
+ QRectF area;
+ QString text;
+ Qt::Key key;
+};
+
+enum MenuType {
+ MaemoFremantle,
+ SymbianTouch,
+ None
+};
+
+enum Orientation {
+ notSet,
+ portraitOrientation,
+ landscapeOrientation,
+};
+
+struct DeviceData
+{
+ DeviceData()
+ : diagonalInInch(0.)
+ , defaultFontSize(12)
+ , forceDpi(-1)
+ , menuType(None)
+ , nativeOrientation(notSet)
+ {}
+
+ QString name;
+ QSize resolution;
+ QRect availableGeometry;
+ qreal diagonalInInch;
+ QString mockupPath;
+ mutable QPixmap mockup;
+ QPoint offset;
+ int defaultFontSize;
+ int forceDpi;
+ QList<Button> buttons;
+ MenuType menuType;
+ QString style;
+ Orientation nativeOrientation;
+};
+
+class DisplayWidget;
+class Menu;
+class QState;
+
+class DeviceButton: public QGraphicsObject
+{
+ Q_OBJECT
+public:
+ explicit DeviceButton(const Button &button, QGraphicsItem *parent = 0);
+
+ virtual QRectF boundingRect() const;
+ virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+protected:
+ virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
+ virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+
+private:
+ Button mButton;
+
+signals:
+ void pressed(Qt::Key, QString) const;
+ void released(Qt::Key) const;
+};
+
+class DeviceItem: public QGraphicsObject
+{
+ Q_OBJECT
+public:
+ DeviceItem(QGraphicsItem *parent = 0);
+ ~DeviceItem();
+
+ DisplayWidget *display();
+
+ virtual QRectF boundingRect() const;
+ virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+public slots:
+ void changeDevice(const DeviceData &data);
+ void toggleOrientation();
+ void changeScaleFactor(qreal newScaleFactor);
+
+protected:
+ virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
+ virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
+
+private:
+ void newWindowSize();
+ void newViewSize();
+ int rotationSideLength();
+ void updateMenuPositionAndSize();
+
+ bool isLandscape;
+
+ DeviceData mDeviceData;
+
+ QSizeF mSize;
+ QRect mAvailableGeometry;
+ DisplayWidget *mDisplay;
+ QGraphicsPixmapItem *mMockup;
+
+ QStateMachine mStateMachine;
+ QState *mLandscapeState;
+ QState *mPortraitState;
+
+ QPoint mDragOffset;
+
+ QList<DeviceButton*> mButtons;
+ Menu *mMenu;
+
+private slots:
+ void startRotate();
+ void setLandscape();
+ void setPortrait();
+
+signals:
+ void rotationSignal();
+ void sizeChanged(const QSize &size);
+ void drag(const QPoint &to); // to is the new top-left point of the view in screen coordinates
+ void viewSizeRequired(const QSize &size);
+
+ void deviceChanged(const QSize &resolution, const DeviceData &device);
+ void offsetChanged(const QPoint &newOffset);
+
+ void buttonPressed(Qt::Key key, QString text);
+ void buttonReleased(Qt::Key key);
+
+ void orientationChanged(Orientation current, Orientation native);
+ void deviceChanged(Orientation current, Orientation currentNative, Orientation targetNative);
+};
+
+#endif //DEVICEITEM_H
diff --git a/src/other/displaywidget.cpp b/src/other/displaywidget.cpp
new file mode 100644
index 0000000..7f1c638
--- /dev/null
+++ b/src/other/displaywidget.cpp
@@ -0,0 +1,88 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "displaywidget.h"
+#include "widgetmanager.h"
+#include "widget.h"
+
+#include <QtGui/QKeyEvent>
+#include <QtGui/QPainter>
+
+DisplayWidget::DisplayWidget(QGraphicsItem *parent)
+: QGraphicsItem(parent)
+{
+ setFlag(QGraphicsItem::ItemClipsChildrenToShape);
+}
+
+int DisplayWidget::width() const
+{
+ return mSize.width();
+}
+
+int DisplayWidget::height() const
+{
+ return mSize.height();
+}
+
+QSize DisplayWidget::size() const
+{
+ return mSize;
+}
+
+void DisplayWidget::setWidth(quint32 w)
+{
+ mSize.setWidth(w);
+}
+
+void DisplayWidget::setHeight(quint32 h)
+{
+ mSize.setHeight(h);
+}
+
+void DisplayWidget::setSize(const QSize &s)
+{
+ if (mSize != s)
+ {
+ mSize = s;
+ }
+}
+
+QRectF DisplayWidget::boundingRect() const
+{
+ return QRectF(0, 0, width(), height());
+}
+
+void DisplayWidget::paint(QPainter * painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ Q_UNUSED(option);
+ Q_UNUSED(widget);
+
+ painter->setBrush(QColor(0, 0, 33));
+ painter->drawRect(boundingRect().toRect());
+}
diff --git a/src/other/displaywidget.h b/src/other/displaywidget.h
new file mode 100644
index 0000000..a8ef05b
--- /dev/null
+++ b/src/other/displaywidget.h
@@ -0,0 +1,58 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef DISPLAYWIDGET_H
+#define DISPLAYWIDGET_H
+
+#include <QtCore/QTimer>
+#include <QtGui/QGraphicsItem>
+
+class WidgetManager;
+
+class DisplayWidget : public QGraphicsItem
+{
+public:
+ DisplayWidget(QGraphicsItem *parent = 0);
+
+ int width() const;
+ int height() const;
+ QSize size() const;
+
+ void setWidth(quint32 w);
+ void setHeight(quint32 h);
+ void setSize(const QSize &s);
+
+ virtual QRectF boundingRect() const;
+ virtual void paint( QPainter * painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+private:
+ QSize mSize;
+};
+
+#endif // DISPLAYWIDGET_H
diff --git a/src/other/menu.cpp b/src/other/menu.cpp
new file mode 100644
index 0000000..8de2a53
--- /dev/null
+++ b/src/other/menu.cpp
@@ -0,0 +1,121 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "menu.h"
+#include "menuwidget.h"
+
+Menu::Menu(QGraphicsItem *displayWidget, QObject *parent)
+: QObject(parent)
+{
+ Q_UNUSED(displayWidget);
+}
+
+Menu::~Menu(void)
+{
+ qDeleteAll(mMenuWidgets);
+ mMenuWidgets.clear();
+}
+
+QRect Menu::updateMenus(Orientation orientation, const QRect &displayRect)
+{
+ QRect mAvailableGeometry = displayRect;
+ bool isLandscape = true;
+ if (orientation == portraitOrientation)
+ isLandscape = false;
+
+ foreach (MenuWidget *menu, mMenuWidgets) {
+ MenuWidgetType currentType = menu->currentType(isLandscape);
+ switch (currentType) {
+ case (topMenu): {
+ menu->setX(mAvailableGeometry.x());
+ menu->setY(mAvailableGeometry.y());
+ menu->setHeight(menu->currentExtend(isLandscape));
+ menu->setWidth(mAvailableGeometry.width());
+ mAvailableGeometry.setTop(mAvailableGeometry.top() + menu->currentExtend(isLandscape));
+ break;
+ } case (rightMenu): {
+ menu->setX(mAvailableGeometry.x() + mAvailableGeometry.width() - menu->currentExtend(isLandscape));
+ menu->setY(mAvailableGeometry.y());
+ menu->setHeight(mAvailableGeometry.height());
+ menu->setWidth(menu->currentExtend(isLandscape));
+ mAvailableGeometry.setWidth(mAvailableGeometry.width() - menu->currentExtend(isLandscape));
+ break;
+ } case (bottomMenu): {
+ menu->setX(mAvailableGeometry.x());
+ menu->setY(mAvailableGeometry.y() + mAvailableGeometry.height() - menu->currentExtend(isLandscape));
+ menu->setHeight(menu->currentExtend(isLandscape));
+ menu->setWidth(mAvailableGeometry.width());
+ mAvailableGeometry.setHeight(mAvailableGeometry.height() - menu->currentExtend(isLandscape));
+ break;
+ } case (leftMenu): {
+ menu->setX(mAvailableGeometry.x());
+ menu->setY(mAvailableGeometry.y());
+ menu->setWidth(menu->currentExtend(isLandscape));
+ menu->setHeight(mAvailableGeometry.height());
+ mAvailableGeometry.setX(mAvailableGeometry.x() + menu->currentExtend(isLandscape));
+ break;
+ } default: {
+ menu->setSize(QSize(0,0));
+ break;
+ }
+ }
+ menu->showPixmap(isLandscape);
+ }
+ return mAvailableGeometry;
+}
+
+QRect Menu::updateMenus(bool isLandscape, const QRect &displayRect)
+{
+ if (isLandscape)
+ return updateMenus(landscapeOrientation, displayRect);
+ else
+ return updateMenus(portraitOrientation, displayRect);
+}
+
+FremantleMenu::FremantleMenu(QGraphicsItem *displayWidget, QObject *parent)
+: Menu(displayWidget, parent)
+{
+ MenuWidget *menuWidget = new MenuWidget(topMenu, 57, topMenu, 56, displayWidget);
+ menuWidget->setPortraitPixmap(QPixmap(":/menus/fremantle_portrait.png"));
+ menuWidget->setLandscapePixmap(QPixmap(":/menus/fremantle_landscape.png"));
+ mMenuWidgets.append(menuWidget);
+}
+
+SymbianTouchMenu::SymbianTouchMenu(QGraphicsItem *displayWidget, QObject *parent)
+: Menu(displayWidget, parent)
+{
+ MenuWidget *menuWidget = new MenuWidget(bottomMenu, 60, rightMenu, 138, displayWidget);
+ menuWidget->setPortraitPixmap(QPixmap(":/menus/symbiantouch_buttons_small_portrait.png"));
+ menuWidget->setLandscapePixmap(QPixmap(":/menus/symbiantouch_buttons_small_landscape.png"));
+ mMenuWidgets.append(menuWidget);
+ menuWidget = new MenuWidget(topMenu, 73, topMenu, 73, displayWidget);
+ menuWidget->setPortraitPixmap(QPixmap(":/menus/symbiantouch_status_portrait.png"));
+ menuWidget->setLandscapePixmap(QPixmap(":/menus/symbiantouch_status_landscape.png"));
+ mMenuWidgets.append(menuWidget);
+}
diff --git a/src/other/menu.h b/src/other/menu.h
new file mode 100644
index 0000000..7e4a459
--- /dev/null
+++ b/src/other/menu.h
@@ -0,0 +1,66 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef MENU_H
+#define MENU_H
+
+#include "deviceitem.h"
+
+#include <QtCore/QObject>
+
+class MenuWidget;
+class QRect;
+class QGraphicsItem;
+class Menu : public QObject
+{
+ Q_OBJECT
+public:
+ explicit Menu(QGraphicsItem *displayWidget, QObject *parent = 0);
+ virtual ~Menu();
+
+ virtual QRect updateMenus(Orientation orientation, const QRect &displayRect);
+ QRect updateMenus(bool isLandscape, const QRect &displayRect);
+
+protected:
+ QList<MenuWidget *> mMenuWidgets;
+};
+
+class FremantleMenu: public Menu
+{
+public:
+ explicit FremantleMenu(QGraphicsItem *displayWidget, QObject *parent = 0);
+};
+
+class SymbianTouchMenu: public Menu
+{
+public:
+ explicit SymbianTouchMenu(QGraphicsItem *displayWidget, QObject *parent = 0);
+};
+
+#endif //MENU_H
diff --git a/src/other/menuwidget.cpp b/src/other/menuwidget.cpp
new file mode 100644
index 0000000..150287e
--- /dev/null
+++ b/src/other/menuwidget.cpp
@@ -0,0 +1,130 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "menuwidget.h"
+
+#include <QtGui/QPainter>
+
+MenuWidget::MenuWidget(MenuWidgetType portraitType, int portraitExtend, MenuWidgetType landscapeType, int landscapeExtend, QGraphicsItem *parent)
+: QGraphicsPixmapItem(parent)
+, mPortraitType(portraitType)
+, mPortraitExtend(portraitExtend)
+, mLandscapeType(landscapeType)
+, mLandscapeExtend(landscapeExtend)
+{
+ setZValue(SIMULATOR_MENU_Z);
+}
+
+MenuWidgetType MenuWidget::currentType(bool landscape) const
+{
+ if (landscape)
+ return mLandscapeType;
+ else
+ return mPortraitType;
+}
+
+int MenuWidget::currentExtend(bool landscape) const
+{
+ if (landscape)
+ return mLandscapeExtend;
+ else
+ return mPortraitExtend;
+}
+
+MenuWidgetType MenuWidget::landscapeType() const
+{
+ return mLandscapeType;
+}
+
+MenuWidgetType MenuWidget::portraitType() const
+{
+ return mPortraitType;
+}
+
+int MenuWidget::portraitExtend() const
+{
+ return mPortraitExtend;
+}
+
+int MenuWidget::landscapeExtend() const
+{
+ return mLandscapeExtend;
+}
+
+int MenuWidget::width() const
+{
+ return mSize.width();
+}
+
+int MenuWidget::height() const
+{
+ return mSize.height();
+}
+
+QSize MenuWidget::size() const
+{
+ return mSize;
+}
+
+void MenuWidget::setWidth(quint32 w)
+{
+ mSize.setWidth(w);
+}
+
+void MenuWidget::setHeight(quint32 h)
+{
+ mSize.setHeight(h);
+}
+
+void MenuWidget::setSize(const QSize &s)
+{
+ if (mSize != s)
+ {
+ mSize = s;
+ }
+}
+
+void MenuWidget::showPixmap(bool isLandscape)
+{
+ if (isLandscape)
+ setPixmap(mLandscapePixmap);
+ else
+ setPixmap(mPortraitPixmap);
+ show();
+}
+
+void MenuWidget::setPortraitPixmap(const QPixmap &portraitPixmap)
+{
+ mPortraitPixmap = portraitPixmap;
+}
+
+void MenuWidget::setLandscapePixmap(const QPixmap &landscapePixmap)
+{
+ mLandscapePixmap = landscapePixmap;
+}
diff --git a/src/other/menuwidget.h b/src/other/menuwidget.h
new file mode 100644
index 0000000..d66a7e1
--- /dev/null
+++ b/src/other/menuwidget.h
@@ -0,0 +1,80 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef MENUWIDGET_H
+#define MENUWIDGET_H
+
+#include "deviceitem.h"
+
+#include <QtGui/QGraphicsObject>
+
+enum MenuWidgetType {
+ topMenu,
+ leftMenu,
+ bottomMenu,
+ rightMenu,
+ noMenu
+};
+
+class MenuWidget : public QGraphicsPixmapItem
+{
+public:
+ enum {MenuType = UserType + 2};
+ MenuWidget(MenuWidgetType type, int portraitExtend, MenuWidgetType landscapeType, int landscapeExtend, QGraphicsItem *parent = 0);
+
+ MenuWidgetType currentType(bool landscape) const;
+ int currentExtend(bool landscape) const;
+ MenuWidgetType portraitType() const;
+ int portraitExtend() const;
+ MenuWidgetType landscapeType() const;
+ int landscapeExtend() const;
+
+ int type() const {return MenuType;};
+ int width() const;
+ int height() const;
+ QSize size() const;
+
+ void showPixmap(bool isLandscape);
+ void setPortraitPixmap(const QPixmap &portraitPixmap);
+ void setLandscapePixmap(const QPixmap &landscapePixmap);
+ void setWidth(quint32 w);
+ void setHeight(quint32 h);
+ void setSize(const QSize &s);
+
+private:
+ QSize mSize;
+ MenuWidgetType mPortraitType;
+ int mPortraitExtend;
+ QPixmap mPortraitPixmap;
+ MenuWidgetType mLandscapeType;
+ int mLandscapeExtend;
+ QPixmap mLandscapePixmap;
+};
+
+#endif // MENUWIDGET_H
diff --git a/src/other/other.pri b/src/other/other.pri
new file mode 100644
index 0000000..56f4ee1
--- /dev/null
+++ b/src/other/other.pri
@@ -0,0 +1,36 @@
+INCLUDEPATH += src/other \
+ $$QT_NOKIA_SDK_PATH/src/gui/kernel \
+ $$QT_NOKIA_SDK_PATH/src/plugins/phonon/simulator/shared
+DEPENDPATH += src/other
+SOURCES += application.cpp \
+ applicationmanager.cpp \
+ configurationreader.cpp \
+ deviceitem.cpp \
+ displaywidget.cpp \
+ menu.cpp \
+ menuwidget.cpp \
+ phononmanager.cpp \
+ widgetmanager.cpp \
+ widget.cpp
+HEADERS += application.h \
+ applicationmanager.h \
+ configurationreader.h \
+ deviceitem.h \
+ displaywidget.h \
+ menu.h \
+ menuwidget.h \
+ phononmanager.h \
+ widgetmanager.h \
+ widget.h
+
+contains(QT_CONFIG, phonon) {
+ SOURCES += \
+ phononsignalbridges.cpp \
+ phononvideowidget.cpp
+ HEADERS += \
+ phononsignalbridges.h \
+ phononvideowidget.h
+}
+
+HEADERS += $$QT_NOKIA_SDK_PATH/src/plugins/phonon/simulator/shared/phononsimulatorhelpers.h
+SOURCES += $$QT_NOKIA_SDK_PATH/src/plugins/phonon/simulator/shared/phononsimulatorhelpers.cpp
diff --git a/src/other/phononmanager.cpp b/src/other/phononmanager.cpp
new file mode 100644
index 0000000..110b18e
--- /dev/null
+++ b/src/other/phononmanager.cpp
@@ -0,0 +1,737 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "phononmanager.h"
+#include "application.h"
+#include "displaywidget.h"
+#include "widgetmanager.h"
+#include "widget.h"
+
+#include <QtCore/QTimer>
+#include <QtCore/QDebug>
+#include <qsimulatordata_p.h>
+
+PhononManager::PhononManager(QObject *parent)
+: QObject(parent),
+ mBackend(0),
+ mCurrentApplication(0)
+{
+ Phonon::Simulator::qt_registerPhononSimulatorTypes();
+}
+
+PhononManager::~PhononManager()
+{
+}
+
+QSet<QObject*> PhononManager::createObjectSet(const QVariantList& vlist)
+{
+ QSet<QObject*> objectSet;
+ bool ok;
+ foreach (const QVariant &v, vlist) {
+ int i = v.toInt(&ok);
+ if (!ok)
+ continue;
+ objectSet.insert(reinterpret_cast<QObject*>(i));
+ }
+ return objectSet;
+}
+
+#ifndef QT_NO_PHONON
+#include "phononsignalbridges.h"
+#include "phononvideowidget.h"
+#include <phonon/audiooutput.h>
+#include <phonon/audiooutputinterface.h>
+#include <phonon/effect.h>
+#include <phonon/backendinterface.h>
+#include <phonon/medianode.h>
+#include <phonon/mediaobject.h>
+#include <phonon/videowidget.h>
+#include <phonon/private/factory_p.h>
+
+void PhononManager::backend_init()
+{
+ QObject* phononBackend = Phonon::Factory::backend();
+ mBackend = qobject_cast<Phonon::BackendInterface*>(phononBackend);
+ BackendSignalBridge* bridge = new BackendSignalBridge(mCurrentApplication, phononBackend);
+ bridge->setObjectName("backend signal bridge");
+}
+
+inline Phonon::MediaNode* castIdToMediaNode(const Phonon::Simulator::Pointer& p)
+{
+ QObject* qobj = reinterpret_cast<QObject*>(p.ptr);
+ MediaNode* node = qobject_cast<MediaObject*>(qobj);
+ if (!node)
+ node = qobject_cast<AudioOutput*>(qobj);
+ if (!node)
+ node = qobject_cast<Effect*>(qobj);
+ if (!node)
+ node = qobject_cast<VideoWidget*>(qobj);
+ return node;
+}
+
+void PhononManager::backend_destroyObjects(QVariantList vl)
+{
+ //qDebug("PhononManager::backend_destroyObjects");
+ foreach (const QVariant &v, vl) {
+ Simulator::Pointer p = v.value<Simulator::Pointer>();
+ MediaNode* mediaNode = castIdToMediaNode(p);
+ delete mediaNode;
+ }
+}
+
+QStringList PhononManager::backend_availableMimeTypes()
+{
+ return mBackend->availableMimeTypes();
+}
+
+QStringList PhononManager::backend_objectDescriptionIndexes(int type)
+{
+ QStringList ret;
+ foreach (int idx, mBackend->objectDescriptionIndexes(static_cast<Phonon::ObjectDescriptionType>(type)))
+ ret.append(QString::number(idx));
+ return ret;
+}
+
+QHash<QString, QVariant> PhononManager::backend_objectDescriptionProperties(int type, int index)
+{
+ QHash<QByteArray, QVariant> props;
+ props = mBackend->objectDescriptionProperties(static_cast<Phonon::ObjectDescriptionType>(type), index);
+
+ QHash<QByteArray, QVariant>::const_iterator it = props.constBegin();
+ QHash<QByteArray, QVariant>::const_iterator itEnd = props.constEnd();
+
+ QHash<QString, QVariant> ret;
+ for (; it != itEnd; ++it)
+ ret.insert(QString::fromLocal8Bit(it.key()), it.value());
+
+ return ret;
+}
+
+Phonon::Simulator::Pointer PhononManager::backend_createObject(int c, const QVariantList args)
+{
+ Phonon::BackendInterface::Class classId = static_cast<Phonon::BackendInterface::Class>(c);
+
+ QObject* phononObj = 0;
+ PhononSignalBridge* bridge = 0;
+ Phonon::Simulator::Pointer ret;
+ switch (classId)
+ {
+ case Phonon::BackendInterface::MediaObjectClass:
+ phononObj = new MediaObject(mCurrentApplication);
+ bridge = new PhononMediaObjectSignalBridge(mCurrentApplication, phononObj);
+ break;
+ case Phonon::BackendInterface::AudioOutputClass:
+ phononObj = new AudioOutput(mCurrentApplication);
+ bridge = new PhononAudioOutputSignalBridge(mCurrentApplication, phononObj);
+ break;
+ case Phonon::BackendInterface::EffectClass:
+ if (args.isEmpty()) {
+ qWarning("PhononManager::backend_createObject can't create Phonon::Effect. Parameter missing.");
+ return ret;
+ }
+ qWarning("PhononManager::backend_createObject ### Effect creation not implemented.");
+ //phononObj = new Effect(m_audioEffects[ args[0].toInt() ], mCurrentApplication);
+ break;
+ case Phonon::BackendInterface::VideoWidgetClass:
+ {
+ PhononVideoWidget* simulatorVideoWidget = new PhononVideoWidget(mCurrentApplication);
+ phononObj = simulatorVideoWidget->videoWidget();
+ break;
+ }
+ default:
+ return ret;
+ }
+
+ //qDebug() << "PhononManager::backend_createObject" << c << args << phononObj;
+ ret.ptr = phononObj;
+ return ret;
+}
+
+bool PhononManager::backend_startConnectionChange(QVariantList objects)
+{
+ return mBackend->startConnectionChange(createObjectSet(objects));
+}
+
+bool PhononManager::backend_endConnectionChange(QVariantList objects)
+{
+ return mBackend->endConnectionChange(createObjectSet(objects));
+}
+
+bool PhononManager::backend_connectNodes(Phonon::Simulator::Pointer _source, Phonon::Simulator::Pointer _sink)
+{
+ //qDebug("PhononManager::backend_connectNodes(%d, %d)", _source, _sink);
+ MediaNode* sourceNode = castIdToMediaNode(_source);
+ MediaNode* sinkNode = castIdToMediaNode(_sink);
+ Q_ASSERT(sourceNode);
+ Q_ASSERT(sinkNode);
+ Path path = createPath(sourceNode, sinkNode);
+ return path.isValid();
+}
+
+bool PhononManager::backend_disconnectNodes(Phonon::Simulator::Pointer _source, Phonon::Simulator::Pointer _sink)
+{
+ //qDebug("PhononManager::backend_disconnectNodes(%d, %d)", _source, _sink);
+ MediaNode* sourceNode = castIdToMediaNode(_source);
+ MediaNode* sinkNode = castIdToMediaNode(_sink);
+ Q_ASSERT(sourceNode);
+ Q_ASSERT(sinkNode);
+
+ bool ret = false;
+ foreach (Path p, sourceNode->outputPaths()) {
+ if (p.sink() == sinkNode) {
+ ret = p.disconnect();
+ break;
+ }
+ }
+
+ return ret;
+}
+
+inline Phonon::MediaObject* castIdToMediaObject(const Phonon::Simulator::Pointer& p)
+{
+ return qobject_cast<Phonon::MediaObject*>(reinterpret_cast<QObject*>(p.ptr));
+}
+
+int PhononManager::mediaObject_state(Phonon::Simulator::Pointer id)
+{
+ Phonon::MediaObject* mo = castIdToMediaObject(id);
+ return mo ? mo->state() : Phonon::ErrorState;
+}
+
+bool PhononManager::mediaObject_hasVideo(Phonon::Simulator::Pointer id)
+{
+ Phonon::MediaObject* mo = castIdToMediaObject(id);
+ return mo ? mo->hasVideo() : false;
+}
+
+bool PhononManager::mediaObject_isSeekable(Phonon::Simulator::Pointer id)
+{
+ Phonon::MediaObject* mo = castIdToMediaObject(id);
+ return mo ? mo->isSeekable() : false;
+}
+
+qint64 PhononManager::mediaObject_totalTime(Phonon::Simulator::Pointer id)
+{
+ Phonon::MediaObject* mo = castIdToMediaObject(id);
+ return mo ? mo->totalTime() : 0;
+}
+
+qint64 PhononManager::mediaObject_currentTime(Phonon::Simulator::Pointer id)
+{
+ Phonon::MediaObject* mo = castIdToMediaObject(id);
+ return mo ? mo->currentTime() : 0;
+}
+
+int PhononManager::mediaObject_tickInterval(Phonon::Simulator::Pointer id)
+{
+ Phonon::MediaObject* mo = castIdToMediaObject(id);
+ return mo ? mo->tickInterval() : 0;
+}
+
+void PhononManager::mediaObject_setTickInterval(Phonon::Simulator::Pointer id, int newTickInterval)
+{
+ Phonon::MediaObject* mo = castIdToMediaObject(id);
+ if (mo) mo->setTickInterval(newTickInterval);
+}
+
+void PhononManager::mediaObject_pause(Phonon::Simulator::Pointer id)
+{
+ Phonon::MediaObject* mo = castIdToMediaObject(id);
+ if (mo) mo->pause();
+}
+
+void PhononManager::mediaObject_stop(Phonon::Simulator::Pointer id)
+{
+ Phonon::MediaObject* mo = castIdToMediaObject(id);
+ if (mo) mo->stop();
+}
+
+void PhononManager::mediaObject_play(Phonon::Simulator::Pointer id)
+{
+ Phonon::MediaObject* mo = castIdToMediaObject(id);
+ if (mo) mo->play();
+}
+
+QString PhononManager::mediaObject_errorString(Phonon::Simulator::Pointer id)
+{
+ Phonon::MediaObject* mo = castIdToMediaObject(id);
+ return mo ? mo->errorString() : QString();
+}
+
+int PhononManager::mediaObject_errorType(Phonon::Simulator::Pointer id)
+{
+ Phonon::MediaObject* mo = castIdToMediaObject(id);
+ return mo ? mo->errorType() : Phonon::FatalError;
+}
+
+int PhononManager::mediaObject_prefinishMark(Phonon::Simulator::Pointer id)
+{
+ Phonon::MediaObject* mo = castIdToMediaObject(id);
+ return mo ? mo->prefinishMark() : 0;
+}
+
+void PhononManager::mediaObject_setPrefinishMark(Phonon::Simulator::Pointer id, int newPrefinishMark)
+{
+ Phonon::MediaObject* mo = castIdToMediaObject(id);
+ if (mo) mo->setPrefinishMark(newPrefinishMark);
+}
+
+int PhononManager::mediaObject_transitionTime(Phonon::Simulator::Pointer id)
+{
+ Phonon::MediaObject* mo = castIdToMediaObject(id);
+ return mo ? mo->transitionTime() : 0;
+}
+
+void PhononManager::mediaObject_setTransitionTime(Phonon::Simulator::Pointer id, int t)
+{
+ Phonon::MediaObject* mo = castIdToMediaObject(id);
+ if (mo) mo->setTransitionTime(t);
+}
+
+qint64 PhononManager::mediaObject_remainingTime(Phonon::Simulator::Pointer id)
+{
+ Phonon::MediaObject* mo = castIdToMediaObject(id);
+ return mo ? mo->remainingTime() : 0;
+}
+
+QVariantList PhononManager::mediaObject_source(Phonon::Simulator::Pointer id)
+{
+ Phonon::MediaObject* mo = castIdToMediaObject(id);
+ if (!mo)
+ return QVariantList();
+
+ return Phonon::Simulator::mediaSourceToVariantList(mo->currentSource());
+}
+
+void PhononManager::mediaObject_setSource(Phonon::Simulator::Pointer id, const QVariantList& vl)
+{
+ Phonon::MediaObject* mo = castIdToMediaObject(id);
+ if (mo)
+ mo->setCurrentSource(Phonon::Simulator::mediaSourceFromVariantList(vl));
+}
+
+void PhononManager::mediaObject_setNextSource(Phonon::Simulator::Pointer id, const QVariantList& vl)
+{
+ Q_UNUSED(id);
+ Q_UNUSED(vl);
+ // ### not sure if we must handle this...
+ Q_UNUSED(id);
+ Q_UNUSED(vl);
+
+ //Phonon::MediaObject* mo = castIdToMediaObject(id);
+ //if (mo)
+ // mo->setNextSource(Phonon::Simulator::mediaSourceFromVariantList(vl));
+}
+
+void PhononManager::mediaObject_seek(Phonon::Simulator::Pointer id, qlonglong t)
+{
+ Phonon::MediaObject* mo = castIdToMediaObject(id);
+ if (mo) mo->seek(t);
+}
+
+inline Phonon::AudioOutput* castIdToAudioOutput(const Phonon::Simulator::Pointer& p)
+{
+ return qobject_cast<Phonon::AudioOutput*>(reinterpret_cast<QObject*>(p.ptr));
+}
+
+int PhononManager::audioOutput_outputDevice(Phonon::Simulator::Pointer id)
+{
+ Phonon::AudioOutput* iface = castIdToAudioOutput(id);
+ return iface ? iface->outputDevice().index() : -1;
+}
+
+void PhononManager::audioOutput_setVolume(Phonon::Simulator::Pointer id, double v)
+{
+ Phonon::AudioOutput* iface = castIdToAudioOutput(id);
+ if (iface) iface->setVolume(v);
+}
+
+bool PhononManager::audioOutput_setOutputDevice(Phonon::Simulator::Pointer id, int newDevice)
+{
+ Phonon::AudioOutput* iface = castIdToAudioOutput(id);
+ return iface ? iface->setOutputDevice(AudioOutputDevice::fromIndex(newDevice)) : -1;
+}
+
+double PhononManager::audioOutput_volume(Phonon::Simulator::Pointer id)
+{
+ Phonon::AudioOutput* iface = castIdToAudioOutput(id);
+ return iface ? iface->volume() : 0;
+}
+
+inline Phonon::VideoWidget* castIdToVideoWidget(const Phonon::Simulator::Pointer& p)
+{
+ return qobject_cast<Phonon::VideoWidget*>(reinterpret_cast<QObject*>(p.ptr));
+}
+
+void PhononManager::videoWidget_setAspectRatio(Phonon::Simulator::Pointer id, int r)
+{
+ Phonon::VideoWidget* vw = castIdToVideoWidget(id);
+ if (vw)
+ vw->setAspectRatio(static_cast<Phonon::VideoWidget::AspectRatio>(r));
+}
+
+void PhononManager::videoWidget_setScaleMode(Phonon::Simulator::Pointer id, int m)
+{
+ Phonon::VideoWidget* vw = castIdToVideoWidget(id);
+ if (vw)
+ vw->setScaleMode(static_cast<Phonon::VideoWidget::ScaleMode>(m));
+}
+
+void PhononManager::videoWidget_setBrightness(Phonon::Simulator::Pointer id, qreal b)
+{
+ Phonon::VideoWidget* vw = castIdToVideoWidget(id);
+ if (vw)
+ vw->setBrightness(b);
+}
+
+void PhononManager::videoWidget_setContrast(Phonon::Simulator::Pointer id, qreal c)
+{
+ Phonon::VideoWidget* vw = castIdToVideoWidget(id);
+ if (vw)
+ vw->setContrast(c);
+}
+
+void PhononManager::videoWidget_setHue(Phonon::Simulator::Pointer id, qreal h)
+{
+ Phonon::VideoWidget* vw = castIdToVideoWidget(id);
+ if (vw)
+ vw->setHue(h);
+}
+
+void PhononManager::videoWidget_setSaturation(Phonon::Simulator::Pointer id, qreal s)
+{
+ Phonon::VideoWidget* vw = castIdToVideoWidget(id);
+ if (vw)
+ vw->setSaturation(s);
+}
+
+int PhononManager::videoWidget_aspectRatio(Phonon::Simulator::Pointer id)
+{
+ Phonon::VideoWidget* vw = castIdToVideoWidget(id);
+ return vw ? static_cast<int>(vw->aspectRatio()) : 0;
+}
+
+int PhononManager::videoWidget_scaleMode(Phonon::Simulator::Pointer id)
+{
+ Phonon::VideoWidget* vw = castIdToVideoWidget(id);
+ return vw ? static_cast<int>(vw->scaleMode()) : 0;
+}
+
+qreal PhononManager::videoWidget_brightness(Phonon::Simulator::Pointer id)
+{
+ Phonon::VideoWidget* vw = castIdToVideoWidget(id);
+ return vw ? vw->brightness() : 0;
+}
+
+qreal PhononManager::videoWidget_contrast(Phonon::Simulator::Pointer id)
+{
+ Phonon::VideoWidget* vw = castIdToVideoWidget(id);
+ return vw ? vw->contrast() : 0;
+}
+
+qreal PhononManager::videoWidget_hue(Phonon::Simulator::Pointer id)
+{
+ Phonon::VideoWidget* vw = castIdToVideoWidget(id);
+ return vw ? vw->hue() : 0;
+}
+
+qreal PhononManager::videoWidget_saturation(Phonon::Simulator::Pointer id)
+{
+ Phonon::VideoWidget* vw = castIdToVideoWidget(id);
+ return vw ? vw->saturation() : 0;
+}
+
+void PhononManager::videoWidget_moveEvent(Phonon::Simulator::Pointer id, QPoint pos)
+{
+ Phonon::VideoWidget* vw = castIdToVideoWidget(id);
+ if (vw)
+ vw->move(pos);
+}
+
+void PhononManager::videoWidget_resizeEvent(Phonon::Simulator::Pointer id, QSize s)
+{
+ Phonon::VideoWidget* vw = castIdToVideoWidget(id);
+ if (vw)
+ vw->resize(s);
+}
+
+#else // QT_NO_PHONON
+
+void PhononManager::backend_init()
+{
+ qWarning() << "Client tries to use phonon, but the simulator isn't built with phonon support.";
+}
+
+void PhononManager::backend_destroyObjects(QVariantList vl)
+{
+ Q_UNUSED(vl);
+}
+
+QStringList PhononManager::backend_availableMimeTypes()
+{
+ return QStringList();
+}
+
+QStringList PhononManager::backend_objectDescriptionIndexes(int)
+{
+ return QStringList();
+}
+
+QHash<QString, QVariant> PhononManager::backend_objectDescriptionProperties(int, int)
+{
+ return QHash<QString, QVariant>();
+}
+
+Phonon::Simulator::Pointer PhononManager::backend_createObject(int, const QVariantList)
+{
+ Phonon::Simulator::Pointer pointer;
+ pointer.ptr = 0;
+ return pointer;
+}
+
+bool PhononManager::backend_startConnectionChange(QVariantList)
+{
+ return false;
+}
+
+bool PhononManager::backend_endConnectionChange(QVariantList)
+{
+ return false;
+}
+
+bool PhononManager::backend_connectNodes(Phonon::Simulator::Pointer, Phonon::Simulator::Pointer)
+{
+ return false;
+}
+
+bool PhononManager::backend_disconnectNodes(Phonon::Simulator::Pointer, Phonon::Simulator::Pointer)
+{
+ return false;
+}
+
+int PhononManager::mediaObject_state(Phonon::Simulator::Pointer)
+{
+ return 0;
+}
+
+bool PhononManager::mediaObject_hasVideo(Phonon::Simulator::Pointer)
+{
+ return false;
+}
+
+bool PhononManager::mediaObject_isSeekable(Phonon::Simulator::Pointer)
+{
+ return false;
+}
+
+qint64 PhononManager::mediaObject_totalTime(Phonon::Simulator::Pointer)
+{
+ return 0;
+}
+
+qint64 PhononManager::mediaObject_currentTime(Phonon::Simulator::Pointer)
+{
+ return 0;
+}
+
+int PhononManager::mediaObject_tickInterval(Phonon::Simulator::Pointer)
+{
+ return 0;
+}
+
+void PhononManager::mediaObject_setTickInterval(Phonon::Simulator::Pointer, int)
+{
+}
+
+void PhononManager::mediaObject_pause(Phonon::Simulator::Pointer)
+{
+}
+
+void PhononManager::mediaObject_stop(Phonon::Simulator::Pointer)
+{
+}
+
+void PhononManager::mediaObject_play(Phonon::Simulator::Pointer)
+{
+}
+
+QString PhononManager::mediaObject_errorString(Phonon::Simulator::Pointer)
+{
+ return QString("Simulator does not support phonon");
+}
+
+int PhononManager::mediaObject_errorType(Phonon::Simulator::Pointer)
+{
+ return 0;
+}
+
+int PhononManager::mediaObject_prefinishMark(Phonon::Simulator::Pointer)
+{
+ return 0;
+}
+
+void PhononManager::mediaObject_setPrefinishMark(Phonon::Simulator::Pointer, int)
+{
+}
+
+int PhononManager::mediaObject_transitionTime(Phonon::Simulator::Pointer)
+{
+ return 0;
+}
+
+void PhononManager::mediaObject_setTransitionTime(Phonon::Simulator::Pointer, int)
+{
+}
+
+qint64 PhononManager::mediaObject_remainingTime(Phonon::Simulator::Pointer)
+{
+ return 0;
+}
+
+QVariantList PhononManager::mediaObject_source(Phonon::Simulator::Pointer)
+{
+ return QVariantList();
+}
+
+void PhononManager::mediaObject_setSource(Phonon::Simulator::Pointer, const QVariantList&)
+{
+}
+
+void PhononManager::mediaObject_setNextSource(Phonon::Simulator::Pointer, const QVariantList&)
+{
+}
+
+void PhononManager::mediaObject_seek(Phonon::Simulator::Pointer, qlonglong)
+{
+}
+
+int PhononManager::audioOutput_outputDevice(Phonon::Simulator::Pointer)
+{
+ return 0;
+}
+
+void PhononManager::audioOutput_setVolume(Phonon::Simulator::Pointer, double)
+{
+}
+
+bool PhononManager::audioOutput_setOutputDevice(Phonon::Simulator::Pointer, int)
+{
+ return false;
+}
+
+double PhononManager::audioOutput_volume(Phonon::Simulator::Pointer)
+{
+ return 0;
+}
+
+void PhononManager::videoWidget_setAspectRatio(Phonon::Simulator::Pointer id, int r)
+{
+ Q_UNUSED(id);
+ Q_UNUSED(r);
+}
+
+void PhononManager::videoWidget_setScaleMode(Phonon::Simulator::Pointer id, int m)
+{
+ Q_UNUSED(id);
+ Q_UNUSED(m);
+}
+
+void PhononManager::videoWidget_setBrightness(Phonon::Simulator::Pointer id, qreal b)
+{
+ Q_UNUSED(id);
+ Q_UNUSED(b);
+}
+
+void PhononManager::videoWidget_setContrast(Phonon::Simulator::Pointer id, qreal c)
+{
+ Q_UNUSED(id);
+ Q_UNUSED(c);
+}
+
+void PhononManager::videoWidget_setHue(Phonon::Simulator::Pointer id, qreal h)
+{
+ Q_UNUSED(id);
+ Q_UNUSED(h);
+}
+
+void PhononManager::videoWidget_setSaturation(Phonon::Simulator::Pointer id, qreal s)
+{
+ Q_UNUSED(id);
+ Q_UNUSED(s);
+}
+
+int PhononManager::videoWidget_aspectRatio(Phonon::Simulator::Pointer id)
+{
+ Q_UNUSED(id);
+ return 0;
+}
+
+int PhononManager::videoWidget_scaleMode(Phonon::Simulator::Pointer id)
+{
+ Q_UNUSED(id);
+ return 0;
+}
+
+qreal PhononManager::videoWidget_brightness(Phonon::Simulator::Pointer id)
+{
+ Q_UNUSED(id);
+ return 0.0f;
+}
+
+qreal PhononManager::videoWidget_contrast(Phonon::Simulator::Pointer id)
+{
+ Q_UNUSED(id);
+ return 0.0f;
+}
+
+qreal PhononManager::videoWidget_hue(Phonon::Simulator::Pointer id)
+{
+ Q_UNUSED(id);
+ return 0.0f;
+}
+
+qreal PhononManager::videoWidget_saturation(Phonon::Simulator::Pointer id)
+{
+ Q_UNUSED(id);
+ return 0.0f;
+}
+
+void PhononManager::videoWidget_moveEvent(Phonon::Simulator::Pointer id, QPoint pos)
+{
+ Q_UNUSED(id);
+ Q_UNUSED(pos);
+}
+
+void PhononManager::videoWidget_resizeEvent(Phonon::Simulator::Pointer id, QSize s)
+{
+ Q_UNUSED(id);
+ Q_UNUSED(s);
+}
+
+#endif // else QT_NO_PHONON
diff --git a/src/other/phononmanager.h b/src/other/phononmanager.h
new file mode 100644
index 0000000..ee5197d
--- /dev/null
+++ b/src/other/phononmanager.h
@@ -0,0 +1,120 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef __PHONONMANAGER_H__
+#define __PHONONMANAGER_H__
+
+#include <phononsimulatorhelpers.h>
+
+#include <QtCore/QObject>
+#include <QtCore/QVariant>
+#include <QtCore/QHash>
+#include <QtCore/QStringList>
+#include <QtCore/QSize>
+#include <QtCore/QPoint>
+
+class Application;
+
+namespace Phonon {
+ class BackendInterface;
+}
+
+class PhononManager : public QObject
+{
+ Q_OBJECT
+public:
+ PhononManager(QObject *parent = 0);
+ ~PhononManager();
+
+ void setCurrentApplication(Application* app) { mCurrentApplication = app; }
+
+private slots:
+ void backend_init();
+ void backend_destroyObjects(QVariantList);
+ QStringList backend_availableMimeTypes();
+ QStringList backend_objectDescriptionIndexes(int type);
+ QHash<QString, QVariant> backend_objectDescriptionProperties(int type, int index);
+ Phonon::Simulator::Pointer backend_createObject(int c, const QVariantList args);
+ bool backend_startConnectionChange(QVariantList objects);
+ bool backend_endConnectionChange(QVariantList objects);
+ bool backend_connectNodes(Phonon::Simulator::Pointer _source, Phonon::Simulator::Pointer _sink);
+ bool backend_disconnectNodes(Phonon::Simulator::Pointer _source, Phonon::Simulator::Pointer _sink);
+
+ int mediaObject_state(Phonon::Simulator::Pointer id);
+ bool mediaObject_hasVideo(Phonon::Simulator::Pointer id);
+ bool mediaObject_isSeekable(Phonon::Simulator::Pointer id);
+ qint64 mediaObject_totalTime(Phonon::Simulator::Pointer id);
+ qint64 mediaObject_currentTime(Phonon::Simulator::Pointer id);
+ int mediaObject_tickInterval(Phonon::Simulator::Pointer id);
+ void mediaObject_setTickInterval(Phonon::Simulator::Pointer id, int newTickInterval);
+ void mediaObject_pause(Phonon::Simulator::Pointer id);
+ void mediaObject_stop(Phonon::Simulator::Pointer id);
+ void mediaObject_play(Phonon::Simulator::Pointer id);
+ QString mediaObject_errorString(Phonon::Simulator::Pointer id);
+ int mediaObject_errorType(Phonon::Simulator::Pointer id);
+ int mediaObject_prefinishMark(Phonon::Simulator::Pointer id);
+ void mediaObject_setPrefinishMark(Phonon::Simulator::Pointer id, int newPrefinishMark);
+ int mediaObject_transitionTime(Phonon::Simulator::Pointer id);
+ void mediaObject_setTransitionTime(Phonon::Simulator::Pointer id, int t);
+ qint64 mediaObject_remainingTime(Phonon::Simulator::Pointer id);
+ QVariantList mediaObject_source(Phonon::Simulator::Pointer id);
+ void mediaObject_setSource(Phonon::Simulator::Pointer id, const QVariantList&);
+ void mediaObject_setNextSource(Phonon::Simulator::Pointer id, const QVariantList&);
+ void mediaObject_seek(Phonon::Simulator::Pointer id, qlonglong t);
+
+ int audioOutput_outputDevice(Phonon::Simulator::Pointer id);
+ void audioOutput_setVolume(Phonon::Simulator::Pointer id, double v);
+ bool audioOutput_setOutputDevice(Phonon::Simulator::Pointer id, int newDevice);
+ double audioOutput_volume(Phonon::Simulator::Pointer id);
+
+ void videoWidget_setAspectRatio(Phonon::Simulator::Pointer id, int r);
+ void videoWidget_setScaleMode(Phonon::Simulator::Pointer id, int m);
+ void videoWidget_setBrightness(Phonon::Simulator::Pointer id, qreal b);
+ void videoWidget_setContrast(Phonon::Simulator::Pointer id, qreal c);
+ void videoWidget_setHue(Phonon::Simulator::Pointer id, qreal h);
+ void videoWidget_setSaturation(Phonon::Simulator::Pointer id, qreal s);
+ int videoWidget_aspectRatio(Phonon::Simulator::Pointer id);
+ int videoWidget_scaleMode(Phonon::Simulator::Pointer id);
+ qreal videoWidget_brightness(Phonon::Simulator::Pointer id);
+ qreal videoWidget_contrast(Phonon::Simulator::Pointer id);
+ qreal videoWidget_hue(Phonon::Simulator::Pointer id);
+ qreal videoWidget_saturation(Phonon::Simulator::Pointer id);
+
+ void videoWidget_moveEvent(Phonon::Simulator::Pointer id, QPoint pos);
+ void videoWidget_resizeEvent(Phonon::Simulator::Pointer id, QSize s);
+
+private:
+ QSet<QObject*> createObjectSet(const QVariantList& vlist);
+
+private:
+ Phonon::BackendInterface* mBackend;
+ Application* mCurrentApplication;
+};
+
+#endif // __PHONONMANAGER_H__
diff --git a/src/other/phononsignalbridges.cpp b/src/other/phononsignalbridges.cpp
new file mode 100644
index 0000000..10bb731
--- /dev/null
+++ b/src/other/phononsignalbridges.cpp
@@ -0,0 +1,167 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "phononsignalbridges.h"
+#include "application.h"
+
+#include <qsimulatordata_p.h>
+#include <phononsimulatorhelpers.h>
+#include <QtCore/QStringList>
+
+BackendSignalBridge::BackendSignalBridge(Application* app, QObject* sender)
+: PhononSignalBridge(app, sender)
+{
+ connect(sender, SIGNAL(objectDescriptionChanged(ObjectDescriptionType)), SLOT(on_backend_ObjectDescriptionChanged(ObjectDescriptionType)));
+}
+
+void BackendSignalBridge::on_backend_ObjectDescriptionChanged(ObjectDescriptionType odt)
+{
+ QtSimulatorPrivate::RemoteMetacall<void>::call(mApplication->socket(), QtSimulatorPrivate::NoSync,
+ "backend_objectDescriptionChanged", remoteId(), static_cast<int>(odt));
+}
+
+PhononMediaObjectSignalBridge::PhononMediaObjectSignalBridge(Application* app, QObject* sender)
+: PhononSignalBridge(app, sender)
+{
+ connect(sender, SIGNAL(aboutToFinish()), SLOT(aboutToFinish()));
+ connect(sender, SIGNAL(bufferStatus(int)), SLOT(bufferStatus(int)));
+ connect(sender, SIGNAL(currentSourceChanged(const Phonon::MediaSource&)), SLOT(currentSourceChanged(const Phonon::MediaSource&)));
+ connect(sender, SIGNAL(finished()), SLOT(finished()));
+ connect(sender, SIGNAL(hasVideoChanged(bool)), SLOT(hasVideoChanged(bool)));
+ connect(sender, SIGNAL(metaDataChanged()), SLOT(metaDataChanged()));
+ connect(sender, SIGNAL(prefinishMarkReached(qint32)), SLOT(prefinishMarkReached(qint32)));
+ connect(sender, SIGNAL(seekableChanged(bool)), SLOT(seekableChanged(bool)));
+ connect(sender, SIGNAL(stateChanged(Phonon::State, Phonon::State)), SLOT(stateChanged(Phonon::State, Phonon::State)));
+ connect(sender, SIGNAL(tick(qint64)), SLOT(tick(qint64)));
+ connect(sender, SIGNAL(totalTimeChanged(qint64)), SLOT(totalTimeChanged(qint64)));
+}
+
+void PhononMediaObjectSignalBridge::aboutToFinish()
+{
+ QtSimulatorPrivate::RemoteMetacall<void>::call(mApplication->socket(), QtSimulatorPrivate::NoSync,
+ "mediaObject_aboutToFinish", remoteId());
+}
+
+void PhononMediaObjectSignalBridge::bufferStatus(int percentFilled)
+{
+ QtSimulatorPrivate::RemoteMetacall<void>::call(mApplication->socket(), QtSimulatorPrivate::NoSync,
+ "mediaObject_bufferStatus", remoteId(), percentFilled);
+}
+
+void PhononMediaObjectSignalBridge::currentSourceChanged(const MediaSource& newSource)
+{
+ QtSimulatorPrivate::RemoteMetacall<void>::call(mApplication->socket(), QtSimulatorPrivate::NoSync,
+ "mediaObject_currentSourceChanged", remoteId(), Phonon::Simulator::mediaSourceToVariantList(newSource));
+}
+
+void PhononMediaObjectSignalBridge::finished()
+{
+ QtSimulatorPrivate::RemoteMetacall<void>::call(mApplication->socket(), QtSimulatorPrivate::NoSync,
+ "mediaObject_finished", remoteId());
+}
+
+void PhononMediaObjectSignalBridge::hasVideoChanged(bool hasVideo)
+{
+ QtSimulatorPrivate::RemoteMetacall<void>::call(mApplication->socket(), QtSimulatorPrivate::NoSync,
+ "mediaObject_hasVideoChanged", remoteId(), hasVideo);
+}
+
+void PhononMediaObjectSignalBridge::metaDataChanged()
+{
+ QStringList payload;
+ QMultiMap<QString, QString> metaData = mediaObject()->metaData();
+ QMultiMap<QString, QString>::const_iterator it = metaData.begin();
+ for (; it != metaData.end(); ++it)
+ payload << it.key() << it.value();
+
+ QtSimulatorPrivate::RemoteMetacall<void>::call(mApplication->socket(), QtSimulatorPrivate::NoSync,
+ "mediaObject_metaDataChanged", remoteId(), payload);
+}
+
+void PhononMediaObjectSignalBridge::prefinishMarkReached(qint32 msecToEnd)
+{
+ QtSimulatorPrivate::RemoteMetacall<void>::call(mApplication->socket(), QtSimulatorPrivate::NoSync,
+ "mediaObject_prefinishMarkReached", remoteId(), msecToEnd);
+}
+
+void PhononMediaObjectSignalBridge::seekableChanged(bool isSeekable)
+{
+ QtSimulatorPrivate::RemoteMetacall<void>::call(mApplication->socket(), QtSimulatorPrivate::NoSync,
+ "mediaObject_seekableChanged", remoteId(), isSeekable);
+}
+
+void PhononMediaObjectSignalBridge::stateChanged(Phonon::State newstate, Phonon::State oldstate)
+{
+ QtSimulatorPrivate::RemoteMetacall<void>::call(mApplication->socket(), QtSimulatorPrivate::NoSync,
+ "mediaObject_stateChanged", remoteId(), (int)newstate, (int)oldstate);
+}
+
+void PhononMediaObjectSignalBridge::tick(qint64 time)
+{
+ QtSimulatorPrivate::RemoteMetacall<void>::call(mApplication->socket(), QtSimulatorPrivate::NoSync,
+ "mediaObject_tick", remoteId(), time);
+}
+
+void PhononMediaObjectSignalBridge::totalTimeChanged(qint64 newTotalTime)
+{
+ QtSimulatorPrivate::RemoteMetacall<void>::call(mApplication->socket(), QtSimulatorPrivate::NoSync,
+ "mediaObject_totalTimeChanged", remoteId(), newTotalTime);
+}
+
+PhononAudioOutputSignalBridge::PhononAudioOutputSignalBridge(Application* app, QObject* sender)
+: PhononSignalBridge(app, sender)
+{
+ connect(sender, SIGNAL(mutedChanged(bool)), SLOT(mutedChanged(bool)));
+ connect(sender, SIGNAL(outputDeviceChanged(const Phonon::AudioOutputDevice&)), SLOT(outputDeviceChanged(const Phonon::AudioOutputDevice&)));
+ connect(sender, SIGNAL(volumeChanged(qreal)), SLOT(volumeChanged(qreal)));
+}
+
+void PhononAudioOutputSignalBridge::mutedChanged(bool muted)
+{
+ Q_UNUSED(muted)
+ // We probably don't have to handle this. We already get volumeChanged signals.
+
+ //QtSimulatorPrivate::RemoteMetacall<void>::call(mApplication->socket(), QtSimulatorPrivate::NoSync,
+ // "audioOutput_mutedChanged", remoteId(), muted);
+}
+
+void PhononAudioOutputSignalBridge::outputDeviceChanged(const Phonon::AudioOutputDevice &newAudioOutputDevice)
+{
+ Q_UNUSED(newAudioOutputDevice)
+ /// There's no matching signal in the private AudioOutput class. :-/
+
+ //QtSimulatorPrivate::RemoteMetacall<void>::call(mApplication->socket(), QtSimulatorPrivate::NoSync,
+ // "audioOutput_outputDeviceChanged", remoteId(), newAudioOutputDevice.index());
+}
+
+void PhononAudioOutputSignalBridge::volumeChanged(qreal newVolume)
+{
+ QtSimulatorPrivate::RemoteMetacall<void>::call(mApplication->socket(), QtSimulatorPrivate::NoSync,
+ "audioOutput_volumeChanged", remoteId(), newVolume);
+}
diff --git a/src/other/phononsignalbridges.h b/src/other/phononsignalbridges.h
new file mode 100644
index 0000000..ab6a166
--- /dev/null
+++ b/src/other/phononsignalbridges.h
@@ -0,0 +1,113 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef __PHONONSIGNALBRIDGES_H__
+#define __PHONONSIGNALBRIDGES_H__
+
+#include <phononsimulatorhelpers.h>
+#include <phonon/mediaobject.h>
+#include <phonon/audiooutput.h>
+
+using namespace Phonon;
+
+class Application;
+
+class PhononSignalBridge : public QObject
+{
+ Q_OBJECT
+public:
+ PhononSignalBridge(Application* app, QObject* sender)
+ : QObject(sender), mApplication(app)
+ {
+ }
+
+ inline Phonon::Simulator::Pointer remoteId()
+ {
+ Phonon::Simulator::Pointer p;
+ p.ptr = parent();
+ return p;
+ }
+
+protected:
+ Application* mApplication;
+};
+
+class BackendSignalBridge : public PhononSignalBridge
+{
+ Q_OBJECT
+public:
+ BackendSignalBridge(Application* app, QObject* sender);
+
+protected slots:
+ void on_backend_ObjectDescriptionChanged(ObjectDescriptionType);
+};
+
+class PhononMediaObjectSignalBridge : public PhononSignalBridge
+{
+ Q_OBJECT
+public:
+ PhononMediaObjectSignalBridge(Application* app, QObject* sender);
+
+ Phonon::MediaObject* mediaObject()
+ {
+ return qobject_cast<Phonon::MediaObject*>(parent());
+ }
+
+private slots:
+ void aboutToFinish();
+ void bufferStatus(int percentFilled);
+ void currentSourceChanged(const Phonon::MediaSource& newSource);
+ void finished();
+ void hasVideoChanged(bool hasVideo);
+ void metaDataChanged();
+ void prefinishMarkReached(qint32 msecToEnd);
+ void seekableChanged(bool isSeekable);
+ void stateChanged(Phonon::State newstate, Phonon::State oldstate);
+ void tick(qint64 time);
+ void totalTimeChanged(qint64 newTotalTime);
+};
+
+class PhononAudioOutputSignalBridge : public PhononSignalBridge
+{
+ Q_OBJECT
+public:
+ PhononAudioOutputSignalBridge(Application* app, QObject* sender);
+
+ Phonon::AudioOutput* audioOutput()
+ {
+ return qobject_cast<Phonon::AudioOutput*>(parent());
+ }
+
+private slots:
+ void mutedChanged(bool muted);
+ void outputDeviceChanged(const Phonon::AudioOutputDevice &newAudioOutputDevice);
+ void volumeChanged(qreal newVolume);
+};
+
+#endif // __PHONONSIGNALBRIDGES_H__
diff --git a/src/other/phononvideowidget.cpp b/src/other/phononvideowidget.cpp
new file mode 100644
index 0000000..f3367c8
--- /dev/null
+++ b/src/other/phononvideowidget.cpp
@@ -0,0 +1,51 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "phononvideowidget.h"
+#include "application.h"
+#include "displaywidget.h"
+#include "widget.h"
+#include "widgetmanager.h"
+#include <phonon/videowidget.h>
+
+PhononVideoWidget::PhononVideoWidget(Application* app)
+: QGraphicsProxyWidget(app->display()),
+ mApplication(app)
+{
+ connect(app, SIGNAL(destroyed()), this, SLOT(deleteLater()));
+
+ mVideoWidget = new Phonon::VideoWidget;
+ setWidget(mVideoWidget);
+
+ setData(0, QLatin1String("PhononVideoWidget"));
+}
+
+PhononVideoWidget::~PhononVideoWidget()
+{
+}
diff --git a/src/other/phononvideowidget.h b/src/other/phononvideowidget.h
new file mode 100644
index 0000000..8e0af97
--- /dev/null
+++ b/src/other/phononvideowidget.h
@@ -0,0 +1,61 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef __PHONONVIDEOWIDGET_H__
+#define __PHONONVIDEOWIDGET_H__
+
+#include <QtGui/QGraphicsProxyWidget>
+
+class Application;
+class Widget;
+
+namespace Phonon {
+ class VideoWidget;
+}
+
+class PhononVideoWidget : public QGraphicsProxyWidget
+{
+ Q_OBJECT
+public:
+ PhononVideoWidget(Application* app);
+ ~PhononVideoWidget();
+
+ Phonon::VideoWidget* videoWidget() const
+ {
+ return mVideoWidget;
+ }
+
+private slots:
+
+private:
+ Phonon::VideoWidget* mVideoWidget;
+ Application* mApplication;
+};
+
+#endif // __PHONONVIDEOWIDGET_H__
diff --git a/src/other/widget.cpp b/src/other/widget.cpp
new file mode 100644
index 0000000..5beb814
--- /dev/null
+++ b/src/other/widget.cpp
@@ -0,0 +1,261 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "deviceitem.h"
+#include "widget.h"
+#include "application.h"
+#include "displaywidget.h"
+#include "qsimulatordata_p.h"
+
+#ifndef QT_NO_PHONON
+#include "phononvideowidget.h"
+#endif
+
+#include <QtCore/QDebug>
+#include <QtCore/QSharedMemory>
+#include <QtCore/QThread>
+#include <QtCore/QTime>
+#include <QtGui/QPainter>
+#include <QtGui/QGraphicsSceneMouseEvent>
+#include <QtGui/QGraphicsScene>
+
+class Sleeper : QThread
+{
+public:
+ using QThread::msleep;
+};
+
+static int bytesForFormat(QImage::Format format)
+{
+ //qDebug() << "Size: " << (QImage(16,16, format).bytesPerLine() / 16);
+ return QImage(16,16, format).bytesPerLine() / 16;
+}
+
+Widget::Widget(QRect geometry, QImage::Format f, const QString &t, Application* who, int id, QGraphicsItem *parent)
+ : QGraphicsItem(parent)
+ , format(f)
+ , widgetId(id)
+ , title(t)
+ , owner(who)
+ , memory(0)
+ , width(geometry.width())
+ , height(geometry.height())
+ , fullscreen(false)
+ , mMenuBar(0)
+ , wantsUpdate(false)
+{
+ //Commented out, in order to be
+ //able to easily re-enable mouse tracking
+ //setAcceptHoverEvents(true);
+ setFlag(QGraphicsItem::ItemIsFocusable);
+ setFlag(QGraphicsItem::ItemIgnoresParentOpacity);
+ setPos(geometry.topLeft());
+ createMemory();
+}
+
+Widget::~Widget()
+{
+ scene()->removeItem(this);
+ delete memory;
+}
+
+QRectF Widget::boundingRect() const
+{
+ return QRectF(0, 0, width, height);
+}
+
+void Widget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ Q_UNUSED(option);
+ Q_UNUSED(widget);
+
+ memory->lock();
+ QImage image((uchar*)memory->data(), width, height, format);
+ painter->drawImage(QPoint(0,0), image);
+ memory->unlock();
+}
+
+bool Widget::createMemory()
+{
+ int size = width * height * bytesForFormat(format);
+ if (memory && size == memory->size())
+ return true;
+
+ if (memory) {
+ delete memory;
+ memory = 0;
+ }
+
+ if (size < 0)
+ return false;
+ else if (size == 0)
+ size = 1;
+
+ const QString key = QtSimulatorPrivate::qt_widgetShareName(owner->id(), widgetId);
+ //qDebug() << "Creating widget memory:" << size << key;
+
+ memory = new QSharedMemory(key);
+ QTime time;
+ const int timeout = 1500;
+ while (!memory->create(size, QSharedMemory::ReadWrite)) {
+ if (memory->error() == QSharedMemory::AlreadyExists)
+ {
+ if (!memory->attach(QSharedMemory::ReadWrite))
+ qFatal("Could not attach to existing shared memory, error %s", qPrintable(memory->errorString()));
+ if (memory->size() < size)
+ qFatal("Shared memory already exists, and is too small: %d where %d required", memory->size(), size);
+ break;
+ }
+
+ if (time.isNull())
+ time.start();
+ else if (time.elapsed() >= timeout) {
+ qWarning() << "Could not create display memory.";
+ delete memory;
+ memory = 0;
+ return false;
+ }
+ else {
+ qWarning() << "Could not create display memory. Retrying...";
+ Sleeper::msleep(10);
+ }
+ }
+ memory->lock();
+ uchar* data = (uchar*) memory->data();
+ QImage displayImage(data, width, height, format);
+ QPainter imagePainter(&displayImage);
+ QBrush brush(Qt::transparent);
+ imagePainter.fillRect(0,0, width, height, brush);
+ imagePainter.end();
+ memory->unlock();
+ return true;
+}
+
+QRect Widget::geometry() const
+{
+ return QRect(x(), y(), width, height);
+}
+
+void Widget::setGeometry(QRect g)
+{
+ prepareGeometryChange();
+ setPos(g.topLeft());
+ width = g.width();
+ height = g.height();
+ createMemory();
+}
+
+void Widget::mousePressEvent(QGraphicsSceneMouseEvent* ev)
+{
+ handleMouseEvent(QEvent::MouseButtonPress, ev);
+}
+
+void Widget::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* ev)
+{
+ handleMouseEvent(QEvent::MouseButtonDblClick, ev);
+}
+
+void Widget::mouseReleaseEvent(QGraphicsSceneMouseEvent* ev)
+{
+ handleMouseEvent(QEvent::MouseButtonRelease, ev);
+}
+
+void Widget::mouseMoveEvent(QGraphicsSceneMouseEvent* ev)
+{
+ handleMouseEvent(QEvent::MouseMove, ev);
+}
+
+void Widget::hoverMoveEvent(QGraphicsSceneHoverEvent *ev)
+{
+ QtSimulatorPrivate::RemoteMetacall<void>::call(owner->socket(), QtSimulatorPrivate::NoSync,
+ "dispatchMouseEvent",
+ widgetId,
+ static_cast<int>(QEvent::MouseMove),
+ mapToItem(owner->display(), ev->pos() - offset).toPoint(),
+ static_cast<int>(Qt::NoButton),
+ static_cast<int>(Qt::NoButton),
+ static_cast<int>(ev->modifiers()));
+ ev->accept();
+}
+
+void Widget::handleMouseEvent(QEvent::Type type, QGraphicsSceneMouseEvent *ev)
+{
+ QtSimulatorPrivate::RemoteMetacall<void>::call(owner->socket(), QtSimulatorPrivate::NoSync,
+ "dispatchMouseEvent",
+ widgetId,
+ static_cast<int>(type),
+ mapToItem(owner->display(), ev->pos() - offset).toPoint(),
+ static_cast<int>(ev->button()),
+ static_cast<int>(ev->buttons()),
+ static_cast<int>(ev->modifiers()));
+ ev->accept();
+}
+
+void Widget::keyPressEvent(QKeyEvent* ev)
+{
+ handleKeyEvent(ev);
+}
+
+void Widget::keyReleaseEvent(QKeyEvent* ev)
+{
+ handleKeyEvent(ev);
+}
+
+void Widget::handleKeyEvent(QKeyEvent* ev)
+{
+ QtSimulatorPrivate::RemoteMetacall<void>::call(owner->socket(), QtSimulatorPrivate::NoSync,
+ "dispatchKeyEvent",
+ widgetId,
+ static_cast<int>(ev->type()),
+ static_cast<int>(ev->key()),
+ static_cast<int>(ev->modifiers()),
+ ev->text(),
+ ev->isAutoRepeat(),
+ static_cast<int>(ev->count()));
+ ev->accept();
+}
+
+void Widget::updateOffset(const QPoint &newOffset)
+{
+ if (offset != newOffset) {
+ setPos(pos() - offset + newOffset);
+
+ offset = newOffset;
+ }
+}
+
+void Widget::setFullscreen(bool full)
+{
+ fullscreen = full;
+}
+
+bool Widget::isFullScreen() const
+{
+ return fullscreen;
+}
diff --git a/src/other/widget.h b/src/other/widget.h
new file mode 100644
index 0000000..cbe82d5
--- /dev/null
+++ b/src/other/widget.h
@@ -0,0 +1,93 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef WIDGET_H
+#define WIDGET_H
+
+#include <QtGui/QGraphicsItem>
+#include <QtGui/QtEvents>
+
+class Application;
+class QSharedMemory;
+class QString;
+class QMenuBar;
+
+class Widget : public QGraphicsItem
+{
+public:
+ Widget(QRect geometry, QImage::Format f, const QString &t, Application* who, int id, QGraphicsItem *parent=0);
+ ~Widget();
+
+ virtual QRectF boundingRect() const;
+ virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget=0);
+
+ static const int WidgetType = UserType+1;
+ virtual int type() const { return WidgetType; }
+
+ bool createMemory();
+ QImage::Format format;
+ int widgetId;
+ QString title;
+ Application* owner;
+
+ QRect geometry() const;
+ void setGeometry(QRect g);
+
+ void updateOffset(const QPoint &newOffset);
+ void setFullscreen(bool full);
+ bool isFullScreen() const;
+
+ QMenuBar* menuBar() const { return mMenuBar; }
+ void setMenuBar(QMenuBar* menuBar) { mMenuBar = menuBar; }
+
+protected:
+ virtual void mousePressEvent(QGraphicsSceneMouseEvent* ev);
+ virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent* ev);
+ virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent* ev);
+ virtual void mouseMoveEvent(QGraphicsSceneMouseEvent* ev);
+ virtual void hoverMoveEvent(QGraphicsSceneHoverEvent* ev);
+ virtual void keyPressEvent(QKeyEvent* ev);
+ virtual void keyReleaseEvent(QKeyEvent* ev);
+ void handleMouseEvent(QEvent::Type type, QGraphicsSceneMouseEvent* ev);
+ void handleKeyEvent(QKeyEvent* ev);
+
+private:
+ friend class WidgetManager;
+ friend class DisplayWidget;
+ QSharedMemory *memory;
+
+ int width;
+ int height;
+ QPoint offset;
+ bool fullscreen;
+ QMenuBar* mMenuBar;
+ bool wantsUpdate;
+};
+
+#endif // WIDGET_H
diff --git a/src/other/widgetmanager.cpp b/src/other/widgetmanager.cpp
new file mode 100644
index 0000000..0d4fb37
--- /dev/null
+++ b/src/other/widgetmanager.cpp
@@ -0,0 +1,536 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "widgetmanager.h"
+#include "widget.h"
+#include "menuwidget.h"
+#include "application.h"
+#include "displaywidget.h"
+#include "qsimulatordata_p.h"
+
+#include <QtCore/QDebug>
+#include <QtGui/QWidget>
+#include <QtGui/QTableWidget>
+#include <QtGui/QLayout>
+
+namespace {
+ int gWidgetIdCounter = 100; // 0 is the desktop.
+}
+
+inline QString stringForCoord(QRect geometry)
+{
+ QString result;
+ result += QString::number(geometry.left()) + QLatin1String(",") + QString::number(geometry.top()) + QLatin1String(";");
+ result += QString::number(geometry.width()) + QLatin1String(",") + QString::number(geometry.height());
+ return result;
+}
+
+WidgetManager::WidgetManager(DisplayWidget *dw, QObject *parent)
+ : QObject(parent)
+ , displayWidget(dw)
+ , mFocusWidget(0)
+{
+ // Some client applications repaint themselves continuously and send an inordinate amount
+ // of paint events. If we call update for every one of these, the event loop stalls on unix
+ // and no timers get executed any more. So we just store the update request
+ // (Widget::wantsUpdate) and handle them regularly.
+ QTimer *updateTimer = new QTimer(this);
+ connect(updateTimer, SIGNAL(timeout()), this, SLOT(handleUpdateRequests()));
+ updateTimer->start(1000/60);
+ mImageFormat = QImage::Format_RGB32;
+
+ tableWidget = new QTableWidget(0, 3);
+ QStringList headerItems;
+ headerItems << "ID" << "Widget Name" << "Rect";
+ tableWidget->setHorizontalHeaderLabels(headerItems);
+ configWidget = new QWidget();
+ QHBoxLayout* layout = new QHBoxLayout;
+ layout->addWidget(tableWidget);
+ configWidget->setLayout(layout);
+}
+
+WidgetManager::~WidgetManager()
+{
+}
+
+DisplayWidget* WidgetManager::display() const
+{
+ return displayWidget;
+}
+
+QImage::Format WidgetManager::imageFormat() const
+{
+ return mImageFormat;
+}
+
+// Returns the widget with the given id, asserts if not found.
+Widget* WidgetManager::widgetForId(int id) const
+{
+ // ignore requests for the root widget
+ if (id == 0 || id == SIMULATOR_DISPLAY_ID)
+ return 0;
+
+ foreach(Widget* w, widgets) {
+ if (w->widgetId == id)
+ return w;
+ }
+ Q_ASSERT(false && "widgetId does not exist");
+ return 0;
+}
+
+int WidgetManager::widgetAt(const QPoint &p) const
+{
+ QPoint actualPosition = p + mOffset;
+ //qDebug("WidgetManager::idForPosition %d, %d", p.x(), p.y());
+ foreach(Widget* w, widgets) {
+ if (!w->isVisible())
+ continue;
+ const QPoint t(w->parentItem()->mapFromItem(displayWidget, actualPosition).toPoint());
+ const QRect wGeometry = w->geometry();
+ if (wGeometry.contains(t))
+ return w->widgetId;
+ }
+ return 0;
+}
+
+Widget *WidgetManager::focusWidget() const
+{
+ return mFocusWidget;
+}
+
+Widget *WidgetManager::activeWidget() const
+{
+ if (mFocusWidget)
+ return mFocusWidget;
+
+ else return topWidget();
+}
+
+Widget *WidgetManager::topWidget() const
+{
+ Widget *top = 0;
+ foreach(Widget* w, widgets) {
+ if (!top || w->zValue() > top->zValue()) {
+ top = w;
+ continue;
+ }
+ }
+ return top;
+}
+
+int WidgetManager::create(int parentWidgetId, QRect geometry, const QString &title, Application* app)
+{
+ //qDebug() << "Creating Widget... parent: " << parentWidgetId << " geometry: " << geometry << " id: " << gWidgetIdCounter;
+
+ QGraphicsItem *parent = displayWidget;
+ if (parentWidgetId)
+ parent = widgetForId(parentWidgetId);
+ if (!parent)
+ qFatal("Could not create child widget of unknown parent with id %d", parentWidgetId);
+
+ geometry = QRect(parent->mapFromItem(displayWidget, geometry.topLeft() + mOffset).toPoint(), geometry.size());
+ Widget *w = new Widget(geometry, mImageFormat, title, app, gWidgetIdCounter++, parent);
+ w->hide();
+ w->offset = mOffset;
+
+ widgets.push_front(w);
+ setHighestZ(w);
+
+ // insert into debug window widgets list
+ tableWidget->insertRow(0);
+ tableWidget->setItem(0, 0, new QTableWidgetItem(QString::number(w->widgetId)));
+ tableWidget->setItem(0, 1, new QTableWidgetItem(w->title));
+ tableWidget->setItem(0, 2, new QTableWidgetItem(stringForCoord(w->geometry())));
+
+ return w->widgetId;
+}
+
+void WidgetManager::showWidget(int id)
+{
+ //qDebug("WidgetManager::show %d", id);
+ Widget* w = widgetForId(id);
+ if (!w)
+ return;
+ w->show();
+ w->update();
+ w->setFocus();
+ updateLogItem(id);
+}
+
+void WidgetManager::paintWidget(qint32 id)
+{
+ Widget* w = widgetForId(id);
+ if (!w)
+ return;
+
+ w->wantsUpdate = true;
+}
+
+void WidgetManager::setWidgetGeometry(int id, const QRect &geometry)
+{
+ //qDebug() << "WidgetManager::setGeometry " << id << " geometry: " << geometry;
+ Widget *w = widgetForId(id);
+ if (!w)
+ return;
+
+ QRect transformed(geometry);
+ transformed.moveTopLeft(w->parentItem()->mapFromItem(displayWidget, transformed.topLeft() + mOffset).toPoint());
+ w->setGeometry(transformed);
+
+ if (!w->createMemory())
+ qFatal("Could not create memory for widget.");
+ updateLogItem(id);
+}
+
+void WidgetManager::moveWidget(int id, const QPoint &to)
+{
+ Widget *w = widgetForId(id);
+ if (!w)
+ return;
+
+ QPoint p;
+ p = QPoint(w->parentItem()->mapFromItem(displayWidget, to + mOffset).toPoint());
+ w->setPos(p);
+
+ updateLogItem(id);
+}
+
+void WidgetManager::updateLogItem(int id)
+{
+ // Find the list item
+ int row = -1;
+ for (int i = 0; i < tableWidget->rowCount(); ++i) {
+ if (tableWidget->item(i,0)->text().toInt() == id) {
+ row = i;
+ break;
+ }
+ }
+ // Find the widget
+ Widget *w = 0;
+ for (int i = 0; i < widgets.size(); ++i) {
+ if (widgets.at(i)->widgetId == id) {
+ w = widgets.at(i);
+ break;
+ }
+ }
+
+ if (row == -1 || w == 0)
+ return;
+
+ // update the content
+ tableWidget->setItem(row, 0, new QTableWidgetItem(QString::number(w->widgetId)));
+ tableWidget->setItem(row, 1, new QTableWidgetItem(w->title));
+ QRect actualGeometry = w->geometry();
+ actualGeometry.adjust(-mOffset.x(), -mOffset.y(), 0, 0);
+ tableWidget->setItem(row, 2, new QTableWidgetItem(stringForCoord(actualGeometry) + QString(";z:") + QString::number(w->zValue())));
+}
+
+void WidgetManager::hideWidget(int id)
+{
+ Widget *w = widgetForId(id);
+ if (!w)
+ return;
+ w->hide();
+}
+
+void WidgetManager::destroyWidget(int id)
+{
+ Widget *w = widgetForId(id);
+ if (!w)
+ return;
+ removeWidgetFromTable(id);
+ widgets.removeAll(w);
+ if (mFocusWidget == w) {
+ mFocusWidget = topWidget();
+ if (mFocusWidget)
+ emit topWidgetChanged(mFocusWidget);
+ else
+ emit topWidgetChanged(0);
+ }
+ delete w;
+}
+
+void WidgetManager::raiseAboveMenus(int id)
+{
+ Widget *w = widgetForId(id);
+ if (!w)
+ return;
+ w->setFullscreen(true);
+ setHighestZ(w);
+}
+
+void WidgetManager::dropBelowMenus(int id)
+{
+ Widget *w = widgetForId(id);
+ if (!w)
+ return;
+ w->setFullscreen(false);
+ setHighestZ(w);
+}
+
+void WidgetManager::removeWidgetFromTable(int id)
+{
+ // Find the list item
+ int row = -1;
+ for (int i = 0; i < tableWidget->rowCount(); ++i) {
+ if (tableWidget->item(i,0)->text().toInt() == id) {
+ row = i;
+ break;
+ }
+ }
+ if (row != -1)
+ tableWidget->removeRow(row);
+}
+
+void WidgetManager::onApplicationUnregistered(int appId)
+{
+ for (int i =0; i < widgets.length(); i++) {
+ Widget *current = widgets.at(i);
+ if (current->owner->id() == appId) {
+ destroyWidget(current->widgetId);
+ --i;
+ }
+ }
+}
+
+void WidgetManager::stackWidget(int id, int pos)
+{
+ //qDebug("WidgetManager::stack %d %d", id, pos);
+ Widget *item = widgetForId(id);
+ if (!item)
+ return;
+
+ if (pos == -1) { // -1 front
+ setHighestZ(item);
+ } else if (pos == -2) { // -2 back
+ setLowestZ(item);
+ } else if (pos > 0) {
+ Widget *under = widgetForId(pos);
+ if (!under)
+ return;
+
+ setZBefore(item, under);
+ }
+}
+
+void WidgetManager::setWidgetWindowTitle(int id, const QString &title)
+{
+ Widget *w = widgetForId(id);
+ if (!w)
+ return;
+ w->title = title;
+ // ### TODO: Update the window decorations when they exist.
+}
+
+void WidgetManager::setFocusWidget(int id)
+{
+ Widget *w = widgetForId(id);
+ if (!w)
+ return;
+ mFocusWidget = w;
+ mFocusWidget->setFocus();
+}
+
+void WidgetManager::setWidgetOpacity(int id, double opacity)
+{
+ Widget *w = widgetForId(id);
+ if (!w)
+ return;
+ w->setOpacity(opacity);
+}
+
+void WidgetManager::setWidgetParent(int id, int newParentId)
+{
+ Widget *w = widgetForId(id);
+ if (!w)
+ return;
+ Widget *newParent = widgetForId(newParentId);
+ if (!newParent)
+ return;
+
+ //qDebug() << "Setting parent for " << id << " to " << newParentId;
+ w->setParentItem(newParent);
+}
+
+void WidgetManager::handleUpdateRequests()
+{
+ foreach (Widget *w, widgets) {
+ if (w->isVisible() && w->wantsUpdate) {
+ w->update();
+ w->wantsUpdate = false;
+ }
+ }
+}
+
+void WidgetManager::sendKeyPress(Qt::Key key, const QString &text)
+{
+ Widget *fw = focusWidget();
+ if (!fw)
+ return;
+
+ QScopedPointer<QKeyEvent> ev(new QKeyEvent(QEvent::KeyPress, key, Qt::NoModifier, text));
+ fw->handleKeyEvent(ev.data());
+}
+
+void WidgetManager::sendKeyRelease(Qt::Key key)
+{
+ // BUG: Can we be certain the focus widget didn't change since the key press?
+ Widget *fw = focusWidget();
+ if (!fw)
+ return;
+
+ QScopedPointer<QKeyEvent> ev(new QKeyEvent(QEvent::KeyRelease, key, Qt::NoModifier));
+ fw->handleKeyEvent(ev.data());
+}
+
+void WidgetManager::changeOffset(const QPoint &offset)
+{
+ mOffset = offset;
+ updateWidgetOffset(mOffset);
+}
+
+void WidgetManager::updateWidgetOffset(const QPoint &newOffset)
+{
+ foreach(Widget* w, widgets) {
+ w->updateOffset(newOffset);
+ }
+}
+
+
+/*!
+ Adjust the Z order of this and all siblings to make this have the highest value
+ and thus be painted over all siblings.
+*/
+void WidgetManager::setHighestZ(Widget *w)
+{
+ if (!w->parentItem())
+ return;
+
+ QMap<qreal, Widget *> order;
+
+ // get the existing z order of everything but this and menus
+ foreach (Widget *child, widgets) {
+ if (child != w && child->type() != MenuWidget::MenuType
+ && w->isFullScreen() == child->isFullScreen())
+ order.insert(child->zValue(), child);
+ }
+
+ int z;
+ // set new z order with this on top
+ if (!w->isFullScreen())
+ z = 0;
+ else
+ z = SIMULATOR_MENU_Z + 1;
+ foreach (Widget *v, order)
+ v->setZValue(z++);
+ w->setZValue(z);
+
+ // show the active menu bar
+ emit topWidgetChanged(w);
+
+#ifndef QT_NO_PHONON
+ // make sure that video widgets stay on top
+ ++z;
+ foreach (Widget *child, widgets) {
+ QVariant objectName = child->data(0);
+ if (objectName.isNull() || objectName.toString() != QLatin1String("PhononVideoWidget"))
+ continue;
+
+ child->setZValue(z);
+ }
+#endif
+}
+
+/*!
+ Adjust the Z order of this and all siblings to make this have the lowest value
+ and thus be painted under all siblings.
+*/
+void WidgetManager::setLowestZ(Widget *w)
+{
+ if (!w->parentItem())
+ return;
+
+ QMap<qreal, Widget *> order;
+
+ // get the existing z order of everything but this and menus
+ foreach (Widget *child, widgets) {
+ if (child != w && child->type() != MenuWidget::MenuType
+ && w->isFullScreen() == child->isFullScreen())
+ order.insert(child->zValue(), child);
+ }
+
+ int z;
+ if (!w->isFullScreen())
+ z = 0;
+ else
+ z = SIMULATOR_MENU_Z + 1;
+
+ w->setZValue(z++);
+ foreach (Widget *v, order)
+ v->setZValue(z++);
+}
+
+/*!
+ Adjust the Z order of this and all siblings to make this be painted just before other.
+*/
+void WidgetManager::setZBefore(Widget *w, Widget *other)
+{
+ if (!w->parentItem())
+ return;
+
+ QMap<qreal, Widget *> order;
+ bool otherFound = false;
+
+ // get the existing z order of everything but this and menus
+ foreach (Widget *child, widgets) {
+ if (child != w && child->type() != MenuWidget::MenuType)
+ order.insert(child->zValue(), child);
+ if (child == other)
+ otherFound = true;
+ }
+ if (!otherFound) {
+ qWarning("Could not reorder widgets. %s is no sibling of %s",
+ qPrintable(other->title), qPrintable(w->title));
+ return;
+ }
+
+ // set new z order with this before other
+ int z;
+ if (other->isFullScreen())
+ z = SIMULATOR_MENU_Z + 1;
+ else
+ z = 0;
+ foreach (Widget *v, order) {
+ if (v->isFullScreen() == other->isFullScreen()) {
+ if (v == other)
+ w->setZValue(z++);
+ v->setZValue(z++);
+ }
+ }
+}
diff --git a/src/other/widgetmanager.h b/src/other/widgetmanager.h
new file mode 100644
index 0000000..185bb21
--- /dev/null
+++ b/src/other/widgetmanager.h
@@ -0,0 +1,109 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef WIDGETMANAGER_H
+#define WIDGETMANAGER_H
+
+#include <QtGui/QImage>
+#include <QtCore/QObject>
+
+class Application;
+class DisplayWidget;
+class Widget;
+class QPoint;
+class QRect;
+class QTableWidget;
+class QWidget;
+class QMenuBar;
+
+class WidgetManager : public QObject
+{
+ Q_OBJECT
+public:
+ explicit WidgetManager(DisplayWidget *dw, QObject *parent = 0);
+ ~WidgetManager();
+
+ Widget* widgetForId(int) const;
+ Widget* focusWidget() const;
+ Widget* activeWidget() const;
+ Widget* topWidget() const;
+
+ DisplayWidget* display() const;
+ QImage::Format imageFormat() const;
+ inline QWidget* logWidget() { return configWidget; }
+
+ int create(int parentWidgetId, QRect geometry, const QString &title, Application *app);
+
+public slots:
+ int widgetAt(const QPoint &position) const;
+ void showWidget(int);
+ void paintWidget(int id);
+ void setWidgetGeometry(int id, const QRect &geometry);
+ void moveWidget(int id, const QPoint &to);
+ void hideWidget(int id);
+ void destroyWidget(int id);
+ void raiseAboveMenus(int id);
+ void dropBelowMenus(int id);
+ void stackWidget(int id, int pos); // -1 front, -2 back
+ void setHighestZ(Widget *w);
+ void setLowestZ(Widget *w);
+ void setZBefore(Widget *w, Widget *other);
+ void setWidgetWindowTitle(int id, const QString &title);
+ void setFocusWidget(int id);
+ void setWidgetOpacity(int id, double opacity);
+ void setWidgetParent(int id, int newParentId);
+
+ void onApplicationUnregistered(int appId);
+
+ void sendKeyPress(Qt::Key key, const QString &text = "");
+ void sendKeyRelease(Qt::Key key);
+
+ void changeOffset(const QPoint &offset);
+
+ private slots:
+ void handleUpdateRequests();
+
+signals:
+ void topWidgetChanged(Widget *);
+
+private:
+ void updateLogItem(int id);
+ void removeWidgetFromTable(int id);
+ void updateWidgetOffset(const QPoint &newOffset);
+ QList<Widget*> widgets;
+ QTableWidget *tableWidget;
+ QWidget *configWidget;
+ DisplayWidget *displayWidget;
+ Widget *mFocusWidget;
+ QPoint mOffset;
+
+ QImage::Format mImageFormat;
+};
+
+#endif
diff --git a/src/shared/qtlockedfile/README.txt b/src/shared/qtlockedfile/README.txt
new file mode 100644
index 0000000..6fcf2fd
--- /dev/null
+++ b/src/shared/qtlockedfile/README.txt
@@ -0,0 +1,10 @@
+This is the src directory of the QtLockedFile
+solution integrated over from addons/main/utils/qtlockedfile/src .
+
+namespace.patch was applied to introduce the SharedTools namespace.
+
+It is required by the QtSingleApplication solution.
+
+History:
+
+16.05.2008 Integrated
diff --git a/src/shared/qtlockedfile/namespace.patch b/src/shared/qtlockedfile/namespace.patch
new file mode 100644
index 0000000..eb894a3
--- /dev/null
+++ b/src/shared/qtlockedfile/namespace.patch
@@ -0,0 +1,70 @@
+
+--- qtlockedfile.cpp 1970-01-01 01:00:00.000000000
++++ qtlockedfile.cpp 2008/05/16 10:51:19.000000000
+@@ -1,5 +1,7 @@
+ #include "qtlockedfile.h"
+
++namespace SharedTools {
++
+ /*!
+ \class QtLockedFile
+
+@@ -123,3 +125,5 @@
+
+ Destroys the \e QtLockedFile object. If any locks were held, they are released.
+ */
++
++}
+
+--- qtlockedfile.h 1970-01-01 01:00:00.000000000
++++ qtlockedfile.h 2008/05/16 10:51:19.000000000
+@@ -19,6 +19,8 @@
+ # define QT_QTLOCKEDFILE_EXPORT
+ #endif
+
++namespace SharedTools {
++
+ class QT_QTLOCKEDFILE_EXPORT QtLockedFile : public QFile
+ {
+ public:
+@@ -41,4 +43,6 @@
+ LockMode m_lock_mode;
+ };
+
++}
++
+ #endif
+
+--- qtlockedfile_unix.cpp 1970-01-01 01:00:00.000000000
++++ qtlockedfile_unix.cpp 2008/05/16 10:51:19.000000000
+@@ -5,6 +5,8 @@
+
+ #include "qtlockedfile.h"
+
++namespace SharedTools {
++
+ bool QtLockedFile::lock(LockMode mode, bool block)
+ {
+ if (!isOpen()) {
+@@ -73,3 +75,4 @@
+ unlock();
+ }
+
++}
+
+--- qtlockedfile_win.cpp 1970-01-01 01:00:00.000000000
++++ qtlockedfile_win.cpp 2008/05/16 10:51:19.000000000
+@@ -2,6 +2,8 @@
+ #include <qt_windows.h>
+ #include <QtCore/QFileInfo>
+
++namespace SharedTools {
++
+ #define SEMAPHORE_PREFIX "QtLockedFile semaphore "
+ #define MUTEX_PREFIX "QtLockedFile mutex "
+ #define SEMAPHORE_MAX 100
+@@ -168,3 +170,4 @@
+ }
+ }
+
++}
diff --git a/src/shared/qtlockedfile/qtlockedfile.cpp b/src/shared/qtlockedfile/qtlockedfile.cpp
new file mode 100644
index 0000000..9277510
--- /dev/null
+++ b/src/shared/qtlockedfile/qtlockedfile.cpp
@@ -0,0 +1,158 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "qtlockedfile.h"
+
+namespace SharedTools {
+
+/*!
+ \class QtLockedFile
+
+ \brief The QtLockedFile class extends QFile with advisory locking functions.
+
+ A file may be locked in read or write mode. Multiple instances of
+ \e QtLockedFile, created in multiple processes running on the same
+ machine, may have a file locked in read mode. Exactly one instance
+ may have it locked in write mode. A read and a write lock cannot
+ exist simultaneously on the same file.
+
+ The file locks are advisory. This means that nothing prevents
+ another process from manipulating a locked file using QFile or
+ file system functions offered by the OS. Serialization is only
+ guaranteed if all processes that access the file use
+ QtLockedFile. Also, while holding a lock on a file, a process
+ must not open the same file again (through any API), or locks
+ can be unexpectedly lost.
+
+ The lock provided by an instance of \e QtLockedFile is released
+ whenever the program terminates. This is true even when the
+ program crashes and no destructors are called.
+*/
+
+/*! \enum QtLockedFile::LockMode
+
+ This enum describes the available lock modes.
+
+ \value ReadLock A read lock.
+ \value WriteLock A write lock.
+ \value NoLock Neither a read lock nor a write lock.
+*/
+
+/*!
+ Constructs an unlocked \e QtLockedFile object. This constructor behaves in the same way
+ as \e QFile::QFile().
+
+ \sa QFile::QFile()
+*/
+QtLockedFile::QtLockedFile()
+ : QFile()
+{
+#ifdef Q_OS_WIN
+ m_semaphore_hnd = 0;
+ m_mutex_hnd = 0;
+#endif
+ m_lock_mode = NoLock;
+}
+
+/*!
+ Constructs an unlocked QtLockedFile object with file \a name. This constructor behaves in
+ the same way as \e QFile::QFile(const QString&).
+
+ \sa QFile::QFile()
+*/
+QtLockedFile::QtLockedFile(const QString &name)
+ : QFile(name)
+{
+#ifdef Q_OS_WIN
+ m_semaphore_hnd = 0;
+ m_mutex_hnd = 0;
+#endif
+ m_lock_mode = NoLock;
+}
+
+/*!
+ Returns \e true if this object has a in read or write lock;
+ otherwise returns \e false.
+
+ \sa lockMode()
+*/
+bool QtLockedFile::isLocked() const
+{
+ return m_lock_mode != NoLock;
+}
+
+/*!
+ Returns the type of lock currently held by this object, or \e QtLockedFile::NoLock.
+
+ \sa isLocked()
+*/
+QtLockedFile::LockMode QtLockedFile::lockMode() const
+{
+ return m_lock_mode;
+}
+
+/*!
+ \fn bool QtLockedFile::lock(LockMode mode, bool block = true)
+
+ Obtains a lock of type \a mode.
+
+ If \a block is true, this
+ function will block until the lock is acquired. If \a block is
+ false, this function returns \e false immediately if the lock cannot
+ be acquired.
+
+ If this object already has a lock of type \a mode, this function returns \e true immediately. If this object has a lock of a different type than \a mode, the lock
+ is first released and then a new lock is obtained.
+
+ This function returns \e true if, after it executes, the file is locked by this object,
+ and \e false otherwise.
+
+ \sa unlock(), isLocked(), lockMode()
+*/
+
+/*!
+ \fn bool QtLockedFile::unlock()
+
+ Releases a lock.
+
+ If the object has no lock, this function returns immediately.
+
+ This function returns \e true if, after it executes, the file is not locked by
+ this object, and \e false otherwise.
+
+ \sa lock(), isLocked(), lockMode()
+*/
+
+/*!
+ \fn QtLockedFile::~QtLockedFile()
+
+ Destroys the \e QtLockedFile object. If any locks were held, they are released.
+*/
+
+} // namespace SharedTools
diff --git a/src/shared/qtlockedfile/qtlockedfile.h b/src/shared/qtlockedfile/qtlockedfile.h
new file mode 100644
index 0000000..1a438e7
--- /dev/null
+++ b/src/shared/qtlockedfile/qtlockedfile.h
@@ -0,0 +1,77 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef QTLOCKEDFILE_H
+#define QTLOCKEDFILE_H
+
+#include <QtCore/QFile>
+
+#if defined(Q_OS_WIN)
+# if !defined(QT_QTLOCKEDFILE_EXPORT) && !defined(QT_QTLOCKEDFILE_IMPORT)
+# define QT_QTLOCKEDFILE_EXPORT
+# elif defined(QT_QTLOCKEDFILE_IMPORT)
+# if defined(QT_QTLOCKEDFILE_EXPORT)
+# undef QT_QTLOCKEDFILE_EXPORT
+# endif
+# define QT_QTLOCKEDFILE_EXPORT __declspec(dllimport)
+# elif defined(QT_QTLOCKEDFILE_EXPORT)
+# undef QT_QTLOCKEDFILE_EXPORT
+# define QT_QTLOCKEDFILE_EXPORT __declspec(dllexport)
+# endif
+#else
+# define QT_QTLOCKEDFILE_EXPORT
+#endif
+
+namespace SharedTools {
+
+class QT_QTLOCKEDFILE_EXPORT QtLockedFile : public QFile
+{
+public:
+ enum LockMode { NoLock = 0, ReadLock, WriteLock };
+
+ QtLockedFile();
+ QtLockedFile(const QString &name);
+ ~QtLockedFile();
+
+ bool lock(LockMode mode, bool block = true);
+ bool unlock();
+ bool isLocked() const;
+ LockMode lockMode() const;
+
+private:
+#ifdef Q_OS_WIN
+ Qt::HANDLE m_semaphore_hnd;
+ Qt::HANDLE m_mutex_hnd;
+#endif
+ LockMode m_lock_mode;
+};
+
+} // namespace SharedTools
+
+#endif // QTLOCKEDFILE_H
diff --git a/src/shared/qtlockedfile/qtlockedfile.pri b/src/shared/qtlockedfile/qtlockedfile.pri
new file mode 100644
index 0000000..46d1f1a
--- /dev/null
+++ b/src/shared/qtlockedfile/qtlockedfile.pri
@@ -0,0 +1,13 @@
+INCLUDEPATH += $$PWD
+DEPENDPATH += $$PWD
+HEADERS += $$PWD/qtlockedfile.h
+SOURCES += $$PWD/qtlockedfile.cpp
+
+unix:SOURCES += $$PWD/qtlockedfile_unix.cpp
+win32:SOURCES += $$PWD/qtlockedfile_win.cpp
+
+win32:contains(TEMPLATE, lib):contains(CONFIG, shared) {
+ DEFINES += QT_QTLOCKEDFILE_EXPORT=__declspec(dllexport)
+}
+
+
diff --git a/src/shared/qtlockedfile/qtlockedfile_unix.cpp b/src/shared/qtlockedfile/qtlockedfile_unix.cpp
new file mode 100644
index 0000000..76eb151
--- /dev/null
+++ b/src/shared/qtlockedfile/qtlockedfile_unix.cpp
@@ -0,0 +1,107 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "qtlockedfile.h"
+
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+namespace SharedTools {
+
+bool QtLockedFile::lock(LockMode mode, bool block)
+{
+ if (!isOpen()) {
+ qWarning("QtLockedFile::lock(): file is not opened");
+ return false;
+ }
+
+ if (mode == NoLock)
+ return unlock();
+
+ if (mode == m_lock_mode)
+ return true;
+
+ if (m_lock_mode != NoLock)
+ unlock();
+
+ struct flock fl;
+ fl.l_whence = SEEK_SET;
+ fl.l_start = 0;
+ fl.l_len = 0;
+ fl.l_type = (mode == ReadLock) ? F_RDLCK : F_WRLCK;
+ int cmd = block ? F_SETLKW : F_SETLK;
+ int ret = fcntl(handle(), cmd, &fl);
+
+ if (ret == -1) {
+ if (errno != EINTR && errno != EAGAIN)
+ qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno));
+ return false;
+ }
+
+
+ m_lock_mode = mode;
+ return true;
+}
+
+
+bool QtLockedFile::unlock()
+{
+ if (!isOpen()) {
+ qWarning("QtLockedFile::unlock(): file is not opened");
+ return false;
+ }
+
+ if (!isLocked())
+ return true;
+
+ struct flock fl;
+ fl.l_whence = SEEK_SET;
+ fl.l_start = 0;
+ fl.l_len = 0;
+ fl.l_type = F_UNLCK;
+ int ret = fcntl(handle(), F_SETLKW, &fl);
+
+ if (ret == -1) {
+ qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno));
+ return false;
+ }
+
+ m_lock_mode = NoLock;
+ return true;
+}
+
+QtLockedFile::~QtLockedFile()
+{
+ if (isOpen())
+ unlock();
+}
+
+} // namespace SharedTools
diff --git a/src/shared/qtlockedfile/qtlockedfile_win.cpp b/src/shared/qtlockedfile/qtlockedfile_win.cpp
new file mode 100644
index 0000000..758055f
--- /dev/null
+++ b/src/shared/qtlockedfile/qtlockedfile_win.cpp
@@ -0,0 +1,203 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "qtlockedfile.h"
+
+#include <qt_windows.h>
+#include <QtCore/QFileInfo>
+
+namespace SharedTools {
+
+#define SEMAPHORE_PREFIX "QtLockedFile semaphore "
+#define MUTEX_PREFIX "QtLockedFile mutex "
+#define SEMAPHORE_MAX 100
+
+static QString errorCodeToString(DWORD errorCode)
+{
+ QString result;
+ char *data = 0;
+ FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+ 0, errorCode, 0,
+ (char*)&data, 0, 0);
+ result = QString::fromLocal8Bit(data);
+ if (data != 0)
+ LocalFree(data);
+
+ if (result.endsWith("\n"))
+ result.truncate(result.length() - 1);
+
+ return result;
+}
+
+bool QtLockedFile::lock(LockMode mode, bool block)
+{
+ if (!isOpen()) {
+ qWarning("QtLockedFile::lock(): file is not opened");
+ return false;
+ }
+
+ if (mode == m_lock_mode)
+ return true;
+
+ if (m_lock_mode != 0)
+ unlock();
+
+ if (m_semaphore_hnd == 0) {
+ QFileInfo fi(*this);
+ QString sem_name = QString::fromLatin1(SEMAPHORE_PREFIX)
+ + fi.absoluteFilePath().toLower();
+
+ QT_WA( {
+ m_semaphore_hnd = CreateSemaphoreW(0, SEMAPHORE_MAX, SEMAPHORE_MAX,
+ (TCHAR*)sem_name.utf16());
+ } , {
+ m_semaphore_hnd = CreateSemaphoreA(0, SEMAPHORE_MAX, SEMAPHORE_MAX,
+ sem_name.toLocal8Bit().constData());
+ } );
+
+ if (m_semaphore_hnd == 0) {
+ qWarning("QtLockedFile::lock(): CreateSemaphore: %s",
+ errorCodeToString(GetLastError()).toLatin1().constData());
+ return false;
+ }
+ }
+
+ bool gotMutex = false;
+ int decrement;
+ if (mode == ReadLock) {
+ decrement = 1;
+ } else {
+ decrement = SEMAPHORE_MAX;
+ if (m_mutex_hnd == 0) {
+ QFileInfo fi(*this);
+ QString mut_name = QString::fromLatin1(MUTEX_PREFIX)
+ + fi.absoluteFilePath().toLower();
+ QT_WA( {
+ m_mutex_hnd = CreateMutexW(NULL, FALSE, (TCHAR*)mut_name.utf16());
+ } , {
+ m_mutex_hnd = CreateMutexA(NULL, FALSE, mut_name.toLocal8Bit().constData());
+ } );
+
+ if (m_mutex_hnd == 0) {
+ qWarning("QtLockedFile::lock(): CreateMutex: %s",
+ errorCodeToString(GetLastError()).toLatin1().constData());
+ return false;
+ }
+ }
+ DWORD res = WaitForSingleObject(m_mutex_hnd, block ? INFINITE : 0);
+ if (res == WAIT_TIMEOUT)
+ return false;
+ if (res == WAIT_FAILED) {
+ qWarning("QtLockedFile::lock(): WaitForSingleObject (mutex): %s",
+ errorCodeToString(GetLastError()).toLatin1().constData());
+ return false;
+ }
+ gotMutex = true;
+ }
+
+ for (int i = 0; i < decrement; ++i) {
+ DWORD res = WaitForSingleObject(m_semaphore_hnd, block ? INFINITE : 0);
+ if (res == WAIT_TIMEOUT) {
+ if (i) {
+ // A failed nonblocking rw locking. Undo changes to semaphore.
+ if (ReleaseSemaphore(m_semaphore_hnd, i, NULL) == 0) {
+ qWarning("QtLockedFile::unlock(): ReleaseSemaphore: %s",
+ errorCodeToString(GetLastError()).toLatin1().constData());
+ // Fall through
+ }
+ }
+ if (gotMutex)
+ ReleaseMutex(m_mutex_hnd);
+ return false;
+ }
+ if (res != WAIT_OBJECT_0) {
+ if (gotMutex)
+ ReleaseMutex(m_mutex_hnd);
+ qWarning("QtLockedFile::lock(): WaitForSingleObject (semaphore): %s",
+ errorCodeToString(GetLastError()).toLatin1().constData());
+ return false;
+ }
+ }
+
+ m_lock_mode = mode;
+ if (gotMutex)
+ ReleaseMutex(m_mutex_hnd);
+ return true;
+}
+
+bool QtLockedFile::unlock()
+{
+ if (!isOpen()) {
+ qWarning("QtLockedFile::unlock(): file is not opened");
+ return false;
+ }
+
+ if (!isLocked())
+ return true;
+
+ int increment;
+ if (m_lock_mode == ReadLock)
+ increment = 1;
+ else
+ increment = SEMAPHORE_MAX;
+
+ DWORD ret = ReleaseSemaphore(m_semaphore_hnd, increment, 0);
+ if (ret == 0) {
+ qWarning("QtLockedFile::unlock(): ReleaseSemaphore: %s",
+ errorCodeToString(GetLastError()).toLatin1().constData());
+ return false;
+ }
+
+ m_lock_mode = QtLockedFile::NoLock;
+ return true;
+}
+
+QtLockedFile::~QtLockedFile()
+{
+ if (isOpen())
+ unlock();
+ if (m_mutex_hnd != 0) {
+ DWORD ret = CloseHandle(m_mutex_hnd);
+ if (ret == 0) {
+ qWarning("QtLockedFile::~QtLockedFile(): CloseHandle (mutex): %s",
+ errorCodeToString(GetLastError()).toLatin1().constData());
+ }
+ m_mutex_hnd = 0;
+ }
+ if (m_semaphore_hnd != 0) {
+ DWORD ret = CloseHandle(m_semaphore_hnd);
+ if (ret == 0) {
+ qWarning("QtLockedFile::~QtLockedFile(): CloseHandle (semaphore): %s",
+ errorCodeToString(GetLastError()).toLatin1().constData());
+ }
+ m_semaphore_hnd = 0;
+ }
+}
+
+} // namespace SharedTools
diff --git a/src/shared/qtsingleapplication/README.txt b/src/shared/qtsingleapplication/README.txt
new file mode 100644
index 0000000..1909a33
--- /dev/null
+++ b/src/shared/qtsingleapplication/README.txt
@@ -0,0 +1,10 @@
+This is the src directory of the QtSingleApplication solution
+integrated over from addons/main/utils/qtsingleapplication/src .
+
+namespace.patch was applied to introduce the SharedTools namespace.
+
+It additionally requires the QtLockedFile solution.
+
+History:
+
+16.05.2008 Integrated
diff --git a/src/shared/qtsingleapplication/namespace.patch b/src/shared/qtsingleapplication/namespace.patch
new file mode 100644
index 0000000..2876e3a
--- /dev/null
+++ b/src/shared/qtsingleapplication/namespace.patch
@@ -0,0 +1,133 @@
+
+--- qtlocalpeer.cpp 1970-01-01 01:00:00.000000000
++++ qtlocalpeer.cpp 2008/05/16 10:36:53.000000000
+@@ -13,6 +13,8 @@
+ #include <time.h>
+ #endif
+
++namespace SharedTools {
++
+ const char* QtLocalPeer::ack = "ack";
+
+ QtLocalPeer::QtLocalPeer(QObject* parent, const QString &appId)
+@@ -139,3 +141,5 @@
+ delete socket;
+ emit messageReceived(message); // ##(might take a long time to return)
+ }
++
++}
+
+--- qtlocalpeer.h 1970-01-01 01:00:00.000000000
++++ qtlocalpeer.h 2008/05/16 10:36:53.000000000
+@@ -1,9 +1,11 @@
+
++
+ #include <QtNetwork/QLocalServer>
+ #include <QtNetwork/QLocalSocket>
+ #include <QtCore/QDir>
+ #include <qtlockedfile.h>
+
++namespace SharedTools {
+
+ class QtLocalPeer : public QObject
+ {
+@@ -31,3 +33,5 @@
+ private:
+ static const char* ack;
+ };
++
++} // SharedTools
+
+--- qtsingleapplication.cpp 1970-01-01 01:00:00.000000000
++++ qtsingleapplication.cpp 2008/05/16 10:36:53.000000000
+@@ -3,6 +3,8 @@
+ #include "qtlocalpeer.h"
+ #include <QtGui/QWidget>
+
++namespace SharedTools {
++
+ void QtSingleApplication::sysInit(const QString &appId)
+ {
+ actWin = 0;
+@@ -95,3 +97,5 @@
+ actWin->activateWindow();
+ }
+ }
++
++}
+
+--- qtsingleapplication.h 1970-01-01 01:00:00.000000000
++++ qtsingleapplication.h 2008/05/16 10:36:53.000000000
+@@ -1,6 +1,8 @@
+
+ #include <QtGui/QApplication>
+
++namespace SharedTools {
++
+ class QtLocalPeer;
+
+ class QtSingleApplication : public QApplication
+@@ -47,3 +49,5 @@
+ QtLocalPeer *peer;
+ QWidget *actWin;
+ };
++
++}
+
+--- qtsingleapplication.pri 1970-01-01 01:00:00.000000000
++++ qtsingleapplication.pri 2008/05/16 10:36:53.000000000
+@@ -6,7 +6,7 @@
+ QT *= network
+
+ gotqtlockedfile = $$find(HEADERS, .*qtlockedfile.h)
+-isEmpty(gotqtlockedfile):include(../../qtlockedfile/src/qtlockedfile.pri)
++isEmpty(gotqtlockedfile):include(../qtlockedfile/qtlockedfile.pri)
+
+
+ win32:contains(TEMPLATE, lib):contains(CONFIG, shared) {
+
+--- qtsinglecoreapplication.cpp 1970-01-01 01:00:00.000000000
++++ qtsinglecoreapplication.cpp 2008/05/16 10:36:53.000000000
+@@ -2,6 +2,7 @@
+ #include "qtsinglecoreapplication.h"
+ #include "qtlocalpeer.h"
+
++namespace SharedTools {
+
+ QtSingleCoreApplication::QtSingleCoreApplication(int &argc, char **argv)
+ : QCoreApplication(argc, argv)
+@@ -36,3 +37,4 @@
+ return peer->applicationId();
+ }
+
++}
+
+--- qtsinglecoreapplication.h 1970-01-01 01:00:00.000000000
++++ qtsinglecoreapplication.h 2008/05/16 10:36:53.000000000
+@@ -1,6 +1,8 @@
+
+ #include <QtCore/QCoreApplication>
+
++namespace SharedTools {
++
+ class QtLocalPeer;
+
+ class QtSingleCoreApplication : public QCoreApplication
+@@ -25,3 +27,5 @@
+ private:
+ QtLocalPeer* peer;
+ };
++
++}
+
+--- qtsinglecoreapplication.pri 1970-01-01 01:00:00.000000000
++++ qtsinglecoreapplication.pri 2008/05/16 10:36:53.000000000
+@@ -6,7 +6,7 @@
+ QT *= network
+
+ gotqtlockedfile = $$find(HEADERS, .*qtlockedfile.h)
+-isEmpty(gotqtlockedfile):include(../../qtlockedfile/src/qtlockedfile.pri)
++isEmpty(gotqtlockedfile):include(../qtlockedfile/qtlockedfile.pri)
+
+
+ win32:contains(TEMPLATE, lib):contains(CONFIG, shared) {
diff --git a/src/shared/qtsingleapplication/qtlocalpeer.cpp b/src/shared/qtsingleapplication/qtlocalpeer.cpp
new file mode 100644
index 0000000..45b130c
--- /dev/null
+++ b/src/shared/qtsingleapplication/qtlocalpeer.cpp
@@ -0,0 +1,172 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "qtlocalpeer.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QTime>
+
+#if defined(Q_OS_WIN)
+#include <QtCore/QLibrary>
+#include <QtCore/qt_windows.h>
+typedef BOOL(WINAPI*PProcessIdToSessionId)(DWORD,DWORD*);
+static PProcessIdToSessionId pProcessIdToSessionId = 0;
+#endif
+
+#if defined(Q_OS_UNIX)
+#include <time.h>
+#include <unistd.h>
+#endif
+
+namespace SharedTools {
+
+const char *QtLocalPeer::ack = "ack";
+
+QtLocalPeer::QtLocalPeer(QObject *parent, const QString &appId)
+ : QObject(parent), id(appId)
+{
+ if (id.isEmpty())
+ id = QCoreApplication::applicationFilePath(); //### On win, check if this returns .../argv[0] without casefolding; .\MYAPP == .\myapp on Win
+
+ QByteArray idc = id.toUtf8();
+ quint16 idNum = qChecksum(idc.constData(), idc.size());
+ //### could do: two 16bit checksums over separate halves of id, for a 32bit result - improved uniqeness probability. Every-other-char split would be best.
+
+ socketName = QLatin1String("qtsingleapplication-")
+ + QString::number(idNum, 16);
+#if defined(Q_OS_WIN)
+ if (!pProcessIdToSessionId) {
+ QLibrary lib("kernel32");
+ pProcessIdToSessionId = (PProcessIdToSessionId)lib.resolve("ProcessIdToSessionId");
+ }
+ if (pProcessIdToSessionId) {
+ DWORD sessionId = 0;
+ pProcessIdToSessionId(GetCurrentProcessId(), &sessionId);
+ socketName += QLatin1Char('-') + QString::number(sessionId, 16);
+ }
+#else
+ socketName += QLatin1Char('-') + QString::number(::getuid(), 16);
+#endif
+
+ server = new QLocalServer(this);
+ QString lockName = QDir(QDir::tempPath()).absolutePath()
+ + QLatin1Char('/') + socketName
+ + QLatin1String("-lockfile");
+ lockFile.setFileName(lockName);
+ lockFile.open(QIODevice::ReadWrite);
+}
+
+bool QtLocalPeer::isClient()
+{
+ if (lockFile.isLocked())
+ return false;
+
+ if (!lockFile.lock(QtLockedFile::WriteLock, false))
+ return true;
+
+ if (!QLocalServer::removeServer(socketName))
+ qWarning("QtSingleCoreApplication: could not cleanup socket");
+ bool res = server->listen(socketName);
+ if (!res)
+ qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString()));
+ QObject::connect(server, SIGNAL(newConnection()), SLOT(receiveConnection()));
+ return false;
+}
+
+bool QtLocalPeer::sendMessage(const QString &message, int timeout)
+{
+ if (!isClient())
+ return false;
+
+ QLocalSocket socket;
+ bool connOk = false;
+ for (int i = 0; i < 2; i++) {
+ // Try twice, in case the other instance is just starting up
+ socket.connectToServer(socketName);
+ connOk = socket.waitForConnected(timeout/2);
+ if (connOk || i)
+ break;
+ int ms = 250;
+#if defined(Q_OS_WIN)
+ Sleep(DWORD(ms));
+#else
+ struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 };
+ nanosleep(&ts, NULL);
+#endif
+ }
+ if (!connOk)
+ return false;
+
+ QByteArray uMsg(message.toUtf8());
+ QDataStream ds(&socket);
+ ds.writeBytes(uMsg.constData(), uMsg.size());
+ bool res = socket.waitForBytesWritten(timeout);
+ res &= socket.waitForReadyRead(timeout); // wait for ack
+ res &= (socket.read(qstrlen(ack)) == ack);
+ return res;
+}
+
+void QtLocalPeer::receiveConnection()
+{
+ QLocalSocket* socket = server->nextPendingConnection();
+ if (!socket)
+ return;
+
+ // Why doesn't Qt have a blocking stream that takes care of this shait???
+ while (socket->bytesAvailable() < static_cast<int>(sizeof(quint32)))
+ socket->waitForReadyRead();
+ QDataStream ds(socket);
+ QByteArray uMsg;
+ quint32 remaining;
+ ds >> remaining;
+ uMsg.resize(remaining);
+ int got = 0;
+ char* uMsgBuf = uMsg.data();
+ //qDebug() << "RCV: remaining" << remaining;
+ do {
+ got = ds.readRawData(uMsgBuf, remaining);
+ remaining -= got;
+ uMsgBuf += got;
+ //qDebug() << "RCV: got" << got << "remaining" << remaining;
+ } while (remaining && got >= 0 && socket->waitForReadyRead(2000));
+ //### error check: got<0
+ if (got < 0) {
+ qWarning() << "QtLocalPeer: Message reception failed" << socket->errorString();
+ delete socket;
+ return;
+ }
+ // ### async this
+ QString message = QString::fromUtf8(uMsg.constData(), uMsg.size());
+ socket->write(ack, qstrlen(ack));
+ socket->waitForBytesWritten(1000);
+ delete socket;
+ emit messageReceived(message); // ##(might take a long time to return)
+}
+
+} // namespace SharedTools
diff --git a/src/shared/qtsingleapplication/qtlocalpeer.h b/src/shared/qtsingleapplication/qtlocalpeer.h
new file mode 100644
index 0000000..c708b9b
--- /dev/null
+++ b/src/shared/qtsingleapplication/qtlocalpeer.h
@@ -0,0 +1,65 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "qtlockedfile.h"
+
+#include <QtNetwork/QLocalServer>
+#include <QtNetwork/QLocalSocket>
+#include <QtCore/QDir>
+
+namespace SharedTools {
+
+class QtLocalPeer : public QObject
+{
+ Q_OBJECT
+
+public:
+ QtLocalPeer(QObject *parent = 0, const QString &appId = QString());
+ bool isClient();
+ bool sendMessage(const QString &message, int timeout);
+ QString applicationId() const
+ { return id; }
+
+Q_SIGNALS:
+ void messageReceived(const QString &message);
+
+protected Q_SLOTS:
+ void receiveConnection();
+
+protected:
+ QString id;
+ QString socketName;
+ QLocalServer* server;
+ QtLockedFile lockFile;
+
+private:
+ static const char* ack;
+};
+
+} // namespace SharedTools
diff --git a/src/shared/qtsingleapplication/qtsingleapplication.cpp b/src/shared/qtsingleapplication/qtsingleapplication.cpp
new file mode 100644
index 0000000..2032471
--- /dev/null
+++ b/src/shared/qtsingleapplication/qtsingleapplication.cpp
@@ -0,0 +1,141 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "qtsingleapplication.h"
+#include "qtlocalpeer.h"
+
+#include <QtGui/QWidget>
+#include <QtGui/QFileOpenEvent>
+
+namespace SharedTools {
+
+void QtSingleApplication::sysInit(const QString &appId)
+{
+ actWin = 0;
+ peer = new QtLocalPeer(this, appId);
+ connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&)));
+}
+
+
+QtSingleApplication::QtSingleApplication(int &argc, char **argv, bool GUIenabled)
+ : QApplication(argc, argv, GUIenabled)
+{
+ sysInit();
+}
+
+
+QtSingleApplication::QtSingleApplication(const QString &appId, int &argc, char **argv)
+ : QApplication(argc, argv)
+{
+ sysInit(appId);
+}
+
+
+QtSingleApplication::QtSingleApplication(int &argc, char **argv, Type type)
+ : QApplication(argc, argv, type)
+{
+ sysInit();
+}
+
+
+#if defined(Q_WS_X11)
+QtSingleApplication::QtSingleApplication(Display* dpy, Qt::HANDLE visual, Qt::HANDLE colormap)
+ : QApplication(dpy, visual, colormap)
+{
+ sysInit();
+}
+
+QtSingleApplication::QtSingleApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual, Qt::HANDLE cmap)
+ : QApplication(dpy, argc, argv, visual, cmap)
+{
+ sysInit();
+}
+
+QtSingleApplication::QtSingleApplication(Display* dpy, const QString &appId,
+ int argc, char **argv, Qt::HANDLE visual, Qt::HANDLE colormap)
+ : QApplication(dpy, argc, argv, visual, colormap)
+{
+ sysInit(appId);
+}
+#endif
+
+bool QtSingleApplication::event(QEvent *event)
+{
+ if (event->type() == QEvent::FileOpen) {
+ QFileOpenEvent *foe = static_cast<QFileOpenEvent*>(event);
+ emit fileOpenRequest(foe->file());
+ return true;
+ }
+ return QApplication::event(event);
+}
+
+bool QtSingleApplication::isRunning()
+{
+ return peer->isClient();
+}
+
+
+bool QtSingleApplication::sendMessage(const QString &message, int timeout)
+{
+ return peer->sendMessage(message, timeout);
+}
+
+
+QString QtSingleApplication::id() const
+{
+ return peer->applicationId();
+}
+
+
+void QtSingleApplication::setActivationWindow(QWidget *aw, bool activateOnMessage)
+{
+ actWin = aw;
+ if (activateOnMessage)
+ connect(peer, SIGNAL(messageReceived(QString)), this, SLOT(activateWindow()));
+ else
+ disconnect(peer, SIGNAL(messageReceived(QString)), this, SLOT(activateWindow()));
+}
+
+
+QWidget* QtSingleApplication::activationWindow() const
+{
+ return actWin;
+}
+
+
+void QtSingleApplication::activateWindow()
+{
+ if (actWin) {
+ actWin->setWindowState(actWin->windowState() & ~Qt::WindowMinimized);
+ actWin->raise();
+ actWin->activateWindow();
+ }
+}
+
+} // namespace SharedTools
diff --git a/src/shared/qtsingleapplication/qtsingleapplication.h b/src/shared/qtsingleapplication/qtsingleapplication.h
new file mode 100644
index 0000000..0fbd77b
--- /dev/null
+++ b/src/shared/qtsingleapplication/qtsingleapplication.h
@@ -0,0 +1,81 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include <QtGui/QApplication>
+
+namespace SharedTools {
+
+class QtLocalPeer;
+
+class QtSingleApplication : public QApplication
+{
+ Q_OBJECT
+
+public:
+ QtSingleApplication(int &argc, char **argv, bool GUIenabled = true);
+ QtSingleApplication(const QString &id, int &argc, char **argv);
+ QtSingleApplication(int &argc, char **argv, Type type);
+#if defined(Q_WS_X11)
+ QtSingleApplication(Display *dpy, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0);
+ QtSingleApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE cmap = 0);
+#endif
+
+ bool isRunning();
+ QString id() const;
+
+ void setActivationWindow(QWidget* aw, bool activateOnMessage = true);
+ QWidget* activationWindow() const;
+ bool event(QEvent *event);
+
+
+public Q_SLOTS:
+ bool sendMessage(const QString &message, int timeout = 5000);
+ void activateWindow();
+
+//Obsolete methods:
+public:
+ void initialize(bool = true)
+ { isRunning(); }
+
+#if defined(Q_WS_X11)
+ QtSingleApplication(Display* dpy, const QString &id, int argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0);
+#endif
+// end obsolete methods
+
+Q_SIGNALS:
+ void messageReceived(const QString &message);
+ void fileOpenRequest(const QString &file);
+
+private:
+ void sysInit(const QString &appId = QString());
+ QtLocalPeer *peer;
+ QWidget *actWin;
+};
+
+} // namespace SharedTools
diff --git a/src/shared/qtsingleapplication/qtsingleapplication.pri b/src/shared/qtsingleapplication/qtsingleapplication.pri
new file mode 100644
index 0000000..f6d8462
--- /dev/null
+++ b/src/shared/qtsingleapplication/qtsingleapplication.pri
@@ -0,0 +1,14 @@
+INCLUDEPATH += $$PWD
+DEPENDPATH += $$PWD
+HEADERS += $$PWD/qtsingleapplication.h $$PWD/qtlocalpeer.h
+SOURCES += $$PWD/qtsingleapplication.cpp $$PWD/qtlocalpeer.cpp
+
+QT *= network
+
+gotqtlockedfile = $$find(HEADERS, .*qtlockedfile.h)
+isEmpty(gotqtlockedfile):include(../qtlockedfile/qtlockedfile.pri)
+
+
+win32:contains(TEMPLATE, lib):contains(CONFIG, shared) {
+ DEFINES += QT_QTSINGLEAPPLICATION_EXPORT=__declspec(dllexport)
+}
diff --git a/src/shared/qtsingleapplication/qtsinglecoreapplication.cpp b/src/shared/qtsingleapplication/qtsinglecoreapplication.cpp
new file mode 100644
index 0000000..5cbb606
--- /dev/null
+++ b/src/shared/qtsingleapplication/qtsinglecoreapplication.cpp
@@ -0,0 +1,68 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "qtsinglecoreapplication.h"
+#include "qtlocalpeer.h"
+
+namespace SharedTools {
+
+QtSingleCoreApplication::QtSingleCoreApplication(int &argc, char **argv)
+ : QCoreApplication(argc, argv)
+{
+ peer = new QtLocalPeer(this);
+ connect(peer, SIGNAL(messageReceived(QString)), SIGNAL(messageReceived(QString)));
+}
+
+
+QtSingleCoreApplication::QtSingleCoreApplication(const QString &appId, int &argc, char **argv)
+ : QCoreApplication(argc, argv)
+{
+ peer = new QtLocalPeer(this, appId);
+ connect(peer, SIGNAL(messageReceived(QString)), SIGNAL(messageReceived(QString)));
+}
+
+
+bool QtSingleCoreApplication::isRunning()
+{
+ return peer->isClient();
+}
+
+
+bool QtSingleCoreApplication::sendMessage(const QString &message, int timeout)
+{
+ return peer->sendMessage(message, timeout);
+}
+
+
+QString QtSingleCoreApplication::id() const
+{
+ return peer->applicationId();
+}
+
+} // namespace SharedTools
diff --git a/src/shared/qtsingleapplication/qtsinglecoreapplication.h b/src/shared/qtsingleapplication/qtsinglecoreapplication.h
new file mode 100644
index 0000000..275c520
--- /dev/null
+++ b/src/shared/qtsingleapplication/qtsinglecoreapplication.h
@@ -0,0 +1,59 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include <QtCore/QCoreApplication>
+
+namespace SharedTools {
+
+class QtLocalPeer;
+
+class QtSingleCoreApplication : public QCoreApplication
+{
+ Q_OBJECT
+
+public:
+ QtSingleCoreApplication(int &argc, char **argv);
+ QtSingleCoreApplication(const QString &id, int &argc, char **argv);
+
+ bool isRunning();
+ QString id() const;
+
+public Q_SLOTS:
+ bool sendMessage(const QString &message, int timeout = 5000);
+
+
+Q_SIGNALS:
+ void messageReceived(const QString &message);
+
+
+private:
+ QtLocalPeer* peer;
+};
+
+} // namespace SharedTools
diff --git a/src/shared/qtsingleapplication/qtsinglecoreapplication.pri b/src/shared/qtsingleapplication/qtsinglecoreapplication.pri
new file mode 100644
index 0000000..3d6301b
--- /dev/null
+++ b/src/shared/qtsingleapplication/qtsinglecoreapplication.pri
@@ -0,0 +1,14 @@
+INCLUDEPATH += $$PWD
+DEPENDPATH += $$PWD
+HEADERS += $$PWD/qtsinglecoreapplication.h $$PWD/qtlocalpeer.h
+SOURCES += $$PWD/qtsinglecoreapplication.cpp $$PWD/qtlocalpeer.cpp
+
+QT *= network
+
+gotqtlockedfile = $$find(HEADERS, .*qtlockedfile.h)
+isEmpty(gotqtlockedfile):include(../qtlockedfile/qtlockedfile.pri)
+
+
+win32:contains(TEMPLATE, lib):contains(CONFIG, shared) {
+ DEFINES += QT_QTSINGLECOREAPPLICATION_EXPORT=__declspec(dllexport)
+}
diff --git a/src/src.pri b/src/src.pri
new file mode 100644
index 0000000..9513e96
--- /dev/null
+++ b/src/src.pri
@@ -0,0 +1,77 @@
+include(other/other.pri)
+include(mobility/mobility.pri)
+include(ui/ui.pri)
+include(shared/qtlockedfile/qtlockedfile.pri)
+include(shared/qtsingleapplication/qtsingleapplication.pri)
+
+DEFINES += SIMULATOR_APPLICATION
+
+# Input
+SOURCES += src/main.cpp
+HEADERS +=
+
+# Shared communication implementation
+SOURCES += $$QT_NOKIA_SDK_PATH/src/gui/kernel/qsimulatordata.cpp
+HEADERS += $$QT_NOKIA_SDK_PATH/src/gui/kernel/qsimulatordata_p.h
+OTHER_FILES += \
+ $$QT_NOKIA_SDK_PATH/src/gui/kernel/qsimulatorconnection.cpp \
+ $$QT_NOKIA_SDK_PATH/src/gui/kernel/qsimulatorconnection_p.h
+
+# Mobility
+INCLUDEPATH += \
+ $$QT_MOBILITY_SOURCE_PATH/src \
+ $$QT_MOBILITY_SOURCE_PATH/src/global \
+ $$QT_MOBILITY_SOURCE_PATH/src/contacts \
+ $$QT_MOBILITY_SOURCE_PATH/src/contacts/engines \
+ $$QT_MOBILITY_SOURCE_PATH/src/contacts/filters \
+ $$QT_MOBILITY_SOURCE_PATH/src/contacts/details \
+ $$QT_MOBILITY_SOURCE_PATH/src/contacts/requests \
+ $$QT_MOBILITY_SOURCE_PATH/plugins/sensors/simulator
+
+SOURCES += $$QT_MOBILITY_SOURCE_PATH/src/systeminfo/qsysteminfodata_simulator.cpp \
+ $$QT_MOBILITY_SOURCE_PATH/src/location/qgeopositioninfodata_simulator.cpp \
+ $$QT_MOBILITY_SOURCE_PATH/src/systeminfo/qsysteminfo_simulator.cpp \
+ $$QT_MOBILITY_SOURCE_PATH/src/systeminfo/qsysteminfo.cpp \
+ $$QT_MOBILITY_SOURCE_PATH/src/contacts/engines/qcontactmemorybackenddata_simulator.cpp \
+ $$QT_MOBILITY_SOURCE_PATH/plugins/sensors/simulator/qsensordata_simulator.cpp
+HEADERS += $$QT_MOBILITY_SOURCE_PATH/src/systeminfo/qsysteminfodata_simulator_p.h \
+ $$QT_MOBILITY_SOURCE_PATH/src/location/qgeopositioninfodata_simulator_p.h \
+ $$QT_MOBILITY_SOURCE_PATH/src/systeminfo/qsysteminfo_simulator_p.h \
+ $$QT_MOBILITY_SOURCE_PATH/src/systeminfo/qsysteminfo.h \
+ $$QT_MOBILITY_SOURCE_PATH/src/contacts/engines/qcontactmemorybackenddata_simulator_p.h \
+ $$QT_MOBILITY_SOURCE_PATH/plugins/sensors/simulator/qsensordata_simulator_p.h
+
+OTHER_FILES += \
+ $$QT_MOBILITY_SOURCE_PATH/src/mobilitysimulator/mobilityconnection.cpp \
+ $$QT_MOBILITY_SOURCE_PATH/src/mobilitysimulator/mobilityconnection_p.h \
+ $$QT_MOBILITY_SOURCE_PATH/src/contacts/engines/qcontactsimulatorbackend_p.h \
+ $$QT_MOBILITY_SOURCE_PATH/src/contacts/engines/qcontactsimulatorbackend.cpp
+
+
+INCLUDEPATH *= $$SIMULATOR_DEPENDENCY_PATH/include
+!mac {
+ LIBS *= -L$$SIMULATOR_DEPENDENCY_PATH/lib
+} else {
+ QMAKE_LFLAGS *= -F$$SIMULATOR_DEPENDENCY_PATH/lib
+}
+unix: isEmpty(INSTALLER) {
+ LIBS *= -Wl,-rpath,$$SIMULATOR_DEPENDENCY_PATH/lib
+}
+
+# link dependencies
+INCLUDEPATH *= $$QMF_INCLUDEDIR $$QMF_INCLUDEDIR/support
+!mac {
+ qtAddLibrary(qtopiamail)
+ qtAddLibrary(remotecontrolwidget)
+} else {
+ LIBS += -framework qtopiamail
+ LIBS += -framework remotecontrolwidget
+}
+
+
+# Set rpath for shipping binaries
+!mac:unix:!isEmpty(INSTALLER) {
+ QMAKE_RPATHDIR = \$\$ORIGIN/lib
+ LIBS += -Wl,-z,origin \'-Wl,-rpath,$${QMAKE_RPATHDIR}\'
+ QMAKE_RPATHDIR =
+}
diff --git a/src/ui/applicationtablewidget.cpp b/src/ui/applicationtablewidget.cpp
new file mode 100644
index 0000000..b3ebb42
--- /dev/null
+++ b/src/ui/applicationtablewidget.cpp
@@ -0,0 +1,57 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "applicationtablewidget.h"
+
+#include <QtGui/QKeyEvent>
+
+ApplicationTableWidget::ApplicationTableWidget(QWidget *parent)
+ : QTableWidget(0, 2, parent)
+{
+ setSelectionBehavior(QAbstractItemView::SelectRows);
+ setSelectionMode(QAbstractItemView::SingleSelection);
+
+ QStringList headerItems;
+ headerItems << "ID" << "Application Name";
+ setHorizontalHeaderLabels(headerItems);
+}
+
+ApplicationTableWidget::~ApplicationTableWidget()
+{
+
+}
+
+void ApplicationTableWidget::keyPressEvent(QKeyEvent *e)
+{
+ if (e->key() == Qt::Key_Delete && currentRow() >= 0) {
+ QTableWidgetItem *currentItem = item(currentRow(), 0);
+ int applicationId = currentItem->data(0).toInt();
+ emit killApplication(applicationId);
+ }
+}
diff --git a/src/ui/applicationtablewidget.h b/src/ui/applicationtablewidget.h
new file mode 100644
index 0000000..1953b42
--- /dev/null
+++ b/src/ui/applicationtablewidget.h
@@ -0,0 +1,52 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef APPLICATIONTABLEWIDGET_H
+#define APPLICATIONTABLEWIDGET_H
+
+#include <QtGui/QTableWidget>
+
+class ApplicationTableWidget : public QTableWidget
+{
+ Q_OBJECT
+
+public:
+ ApplicationTableWidget(QWidget *parent = 0);
+ ~ApplicationTableWidget();
+
+private:
+
+protected:
+ virtual void keyPressEvent(QKeyEvent *e);
+
+signals:
+ void killApplication(int id);
+};
+
+#endif // APPLICATIONTABLEWIDGET_H
diff --git a/src/ui/configurationwidget.cpp b/src/ui/configurationwidget.cpp
new file mode 100644
index 0000000..8bc63e1
--- /dev/null
+++ b/src/ui/configurationwidget.cpp
@@ -0,0 +1,405 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "configurationwidget.h"
+#include "ui_inspector.h"
+#include "configurationreader.h"
+#include "qsimulatordata_p.h"
+#include "viewconfiguration.h"
+#include "widget.h"
+#include "application.h"
+
+#include <qmath.h>
+#include <QtCore/QSettings>
+#include <QtCore/QThread>
+#include <QtCore/QDir>
+#include <QtGui/QDesktopWidget>
+#include <QtGui/QScrollBar>
+#include <QtGui/QMessageBox>
+#include <QtGui/QToolButton>
+#include <QtGui/QCloseEvent>
+#include <QtGui/QMenuBar>
+#include <QtGui/QPushButton>
+
+ConfigurationWidget::ConfigurationWidget(QWidget *parent)
+ : RemoteControlWidget(parent)
+ , ui_inspector(new Ui_Inspector)
+ , mCorrectionFactor(1)
+ , mViewConfiguration(0)
+{
+ QDesktopWidget *desktop = QApplication::desktop();
+ mLogicalDpi.setWidth(desktop->logicalDpiX());
+ mLogicalDpi.setHeight(desktop->logicalDpiY());
+
+ setWindowTitle(tr("Qt Simulator"));
+
+ mScriptInterface = new SimulatorScriptInterface(this);
+
+ initializeApplicationArea();
+ initializeViewArea();
+}
+
+ConfigurationWidget::~ConfigurationWidget()
+{
+}
+
+void ConfigurationWidget::initializeViewArea()
+{
+ QWidget *target = new QWidget();
+ ui_inspector->setupUi(target);
+ connect(ui_inspector->rotateButton, SIGNAL(clicked()), this, SLOT(rotate()));
+ connect(ui_inspector->scaleSlider, SIGNAL(valueChanged(int)), this, SLOT(changeScaleFactor(int)));
+ connect(ui_inspector->deviceListView, SIGNAL(currentIndexChanged(int)), this, SLOT(changeDeviceSelection(int)));
+
+ mViewPage = new PageWidget(tr("View"), target);
+ mViewPage->setHideable(true);
+ mViewPage->setHasAdvancedButton(true);
+ connect(mViewPage, SIGNAL(advancedButtonClicked()), SLOT(showViewConfiguration()));
+ addPage(mViewPage);
+}
+
+void ConfigurationWidget::initializeApplicationArea()
+{
+ QWidget *target = new QWidget();
+ QFormLayout *innerLayout = new QFormLayout();
+ mWidgetTitle = new QLineEdit();
+ mWidgetTitle->setReadOnly(true);
+ innerLayout->addRow(tr("Topmost widget's title"), mWidgetTitle);
+ mMenuLayout = new QHBoxLayout();
+ innerLayout->addRow(tr("Application's menubar"), mMenuLayout);
+ QPushButton *exitButton = new QPushButton(tr("Quit"));
+ connect(exitButton, SIGNAL(clicked()), SIGNAL(exitButtonClicked()));
+ innerLayout->addRow(tr("Quit current application"), exitButton);
+ target->setLayout(innerLayout);
+
+ mAppPage = new PageWidget(tr("Application"), target);
+ mAppPage->setHideable(true);
+ mAppPage->hideContent();
+ addPage(mAppPage);
+}
+
+int ConfigurationWidget::currentDeviceIndex() const
+{
+ return ui_inspector->deviceListView->currentIndex();
+}
+
+QString ConfigurationWidget::currentDeviceName() const
+{
+ return ui_inspector->deviceListView->currentText();
+}
+
+void ConfigurationWidget::changeDeviceSelection(int newIndex)
+{
+ ui_inspector->deviceListView->setCurrentIndex(newIndex);
+ const DeviceData &newData = deviceList.at(newIndex);
+ emit deviceSelectionChanged(newData);
+ changeScaleFactor(ui_inspector->scaleSlider->value());
+}
+
+void ConfigurationWidget::updateTopWidget(Widget *topWidget)
+{
+ QMenuBar *menuBar = 0;
+ if (topWidget) {
+ menuBar = topWidget->menuBar();
+ mWidgetTitle->setText(topWidget->title);
+ } else {
+ mWidgetTitle->setText(QString());
+ }
+
+ if (mMenuBar == menuBar)
+ return;
+
+ if (mMenuBar) {
+ mMenuBar->hide();
+ mMenuLayout->removeWidget(mMenuBar);
+ }
+
+ mMenuBar = menuBar;
+ if (!menuBar)
+ return;
+
+ mMenuLayout->insertWidget(0, mMenuBar);
+ mMenuBar->show();
+}
+
+void ConfigurationWidget::initializeSelection()
+{
+ if (deviceList.count() == 0)
+ return;
+
+ ui_inspector->deviceListView->setCurrentIndex(0);
+ changeDeviceSelection(0);
+}
+
+void ConfigurationWidget::changeScaleFactor(int sliderPosition)
+{
+ int index = currentDeviceIndex();
+ if (index < 0 || index >= deviceList.size())
+ return;
+
+ const DeviceData &data = deviceList.at(index);
+ qreal pixelDiagonal = sqrt(pow((qreal)data.resolution.width(), 2) + pow((qreal)data.resolution.height(), 2));
+ qreal displayWidthInInch = data.diagonalInInch / pixelDiagonal * data.resolution.width();
+
+ qreal minimalScale = mLogicalDpi.width() * displayWidthInInch / data.resolution.width() * mCorrectionFactor;
+
+ emit scaleFactorChanged((minimalScale + qreal(sliderPosition) / 100. * (1. - minimalScale)));
+}
+
+void ConfigurationWidget::changeCorrectionFactor(qreal newFactor)
+{
+ mCorrectionFactor = newFactor;
+ changeScaleFactor(ui_inspector->scaleSlider->value());
+}
+
+void ConfigurationWidget::closeEvent(QCloseEvent *event)
+{
+ event->ignore();
+ emit closeMainWindow();
+}
+
+void ConfigurationWidget::rotate()
+{
+ emit rotateRequested();
+}
+
+void ConfigurationWidget::writeSettings(const QString &vendor, const QString &name) const
+{
+ RemoteControlWidget::writeSettings(vendor, name);
+
+ QSettings settings(vendor, name);
+
+ settings.beginGroup("ConfigurationWidget");
+ settings.setValue("scale", ui_inspector->scaleSlider->value());
+ settings.setValue("corrfactor", mCorrectionFactor);
+ settings.setValue("viewPageVisible", mViewPage->isContentVisible());
+ settings.setValue("appPageVisible", mAppPage->isContentVisible());
+
+ int index = currentDeviceIndex();
+ if (index >= 0 && index < deviceList.size())
+ settings.setValue("device", deviceList.at(index).name);
+
+ settings.endGroup();
+}
+
+void ConfigurationWidget::readSettings(const QString &vendor, const QString &name)
+{
+ RemoteControlWidget::readSettings(vendor, name);
+
+ QSettings settings(vendor, name);
+
+ settings.beginGroup("ConfigurationWidget");
+ if (settings.contains("scale"))
+ ui_inspector->scaleSlider->setValue(settings.value("scale").toInt());
+ if (settings.contains("corrfactor")) {
+ changeCorrectionFactor(settings.value("corrfactor").toDouble());
+ }
+ if (settings.contains("viewPageVisible")) {
+ bool viewPageVisible = settings.value("viewPageVisible").toBool();
+ if (viewPageVisible)
+ mViewPage->showContent();
+ else
+ mViewPage->hideContent();
+ }
+ if (settings.contains("appPageVisible")) {
+ bool appPageVisible = settings.value("appPageVisible").toBool();
+ if (appPageVisible)
+ mAppPage->showContent();
+ else
+ mAppPage->hideContent();
+ }
+
+ if (settings.contains("device")) {
+ QString deviceName = settings.value("device").toString();
+ for (int i = 0; i < deviceList.size(); ++i) {
+ if (deviceList.at(i).name == deviceName)
+ ui_inspector->deviceListView->setCurrentIndex(i);
+ }
+ }
+
+ settings.endGroup();
+}
+
+void ConfigurationWidget::showViewConfiguration()
+{
+ if (!mViewConfiguration) {
+ mViewConfiguration = new ViewConfiguration(mCorrectionFactor, this);
+ connect(mViewConfiguration, SIGNAL(correctionFactorChanged(qreal)), SLOT(changeCorrectionFactor(qreal)));
+ }
+
+ mViewConfiguration->exec();
+
+}
+
+bool ConfigurationWidget::initializeDeviceList()
+{
+ QDir modelsDir("models");
+ if (!modelsDir.exists()) {
+ QMessageBox errorMsg;
+ errorMsg.setWindowTitle(tr("Folder does not exist"));
+ errorMsg.setText(tr("The \"%1\" folder could not be located in the installation directory.").arg(modelsDir.dirName()));
+ errorMsg.setIcon(QMessageBox::Critical);
+ errorMsg.exec();
+ return false;
+ }
+
+ ConfigurationReader confReader;
+ deviceList.clear();
+ bool noErrors = confReader.processDir(&modelsDir, deviceList);
+ if (!noErrors && !deviceList.isEmpty()) {
+ QMessageBox msgbox;
+ msgbox.setWindowTitle(tr("Errors occurred while reading device configurations"));
+ msgbox.setText(confReader.errorMessageLines());
+ msgbox.setIcon(QMessageBox::Critical);
+ msgbox.exec();
+ }
+
+ if (deviceList.isEmpty()) {
+ QMessageBox errorMsg;
+ errorMsg.setWindowTitle(tr("Devices could not be found"));
+ QString msg;
+ if (!noErrors) {
+ msg = confReader.errorMessageLines();
+ }
+ msg += tr("No valid device configuration files (.config) could be found in the \"%1\" folder.").arg(modelsDir.dirName());
+ errorMsg.setText(msg);
+ errorMsg.setIcon(QMessageBox::Critical);
+ errorMsg.exec();
+ return false;
+ }
+
+ foreach (const DeviceData &data, deviceList)
+ ui_inspector->deviceListView->addItem(data.name);
+ return true;
+}
+
+SimulatorScriptInterface *ConfigurationWidget::scriptInterface()
+{
+ return mScriptInterface;
+}
+
+SimulatorScriptInterface::SimulatorScriptInterface(ConfigurationWidget *ui)
+ : QObject(ui), ui(ui)
+{
+}
+
+SimulatorScriptInterface::~SimulatorScriptInterface()
+{
+}
+
+/*!
+ \class SimulatorScriptInterface
+ \brief Exposed as simulator.
+*/
+
+/*!
+ \property SimulatorScriptInterface::zoom
+
+ \brief the device scaling
+
+ The value can be between between 0 for real-world size and 100 for pixel equivalence.
+
+*/
+int SimulatorScriptInterface::zoom() const
+{
+ return ui->ui_inspector->scaleSlider->value();
+}
+
+void SimulatorScriptInterface::setZoom(int z)
+{
+ if (z < 0)
+ z = 0;
+ else if (z > 100)
+ z = 100;
+ ui->ui_inspector->scaleSlider->setValue(z);
+}
+
+/*!
+ Returns the index of the current device.
+
+ \sa setDevice(), deviceCount()
+*/
+int SimulatorScriptInterface::currentDeviceIndex() const
+{
+ return ui->currentDeviceIndex();
+}
+
+/*!
+ Returns the name of the current device.
+
+ \sa setDevice()
+*/
+QString SimulatorScriptInterface::currentDeviceName() const
+{
+ return ui->currentDeviceName();
+}
+
+/*!
+ Returns the number of available device models.
+
+ \sa setDevice(), currentDeviceIndex()
+*/
+int SimulatorScriptInterface::deviceCount() const
+{
+ return ui->deviceList.size();
+}
+
+/*!
+ Rotates the current device.
+*/
+void SimulatorScriptInterface::rotate()
+{
+ ui->rotate();
+}
+
+/*!
+ Sets the current device to the one with \a index.
+
+ \sa deviceCount(), currentDeviceIndex()
+*/
+void SimulatorScriptInterface::setDevice(int index)
+{
+ ui->changeDeviceSelection(index);
+}
+
+/*!
+ Sets the current device to be the one identified by \a dev.
+
+ \sa currentDeviceName()
+*/
+void SimulatorScriptInterface::setDevice(const QString &dev)
+{
+ const QList<DeviceData> &devices = ui->deviceList;
+ for (int i = 0; i < devices.size(); ++i) {
+ if (devices.at(i).name == dev) {
+ ui->changeDeviceSelection(i);
+ break;
+ }
+ }
+}
diff --git a/src/ui/configurationwidget.h b/src/ui/configurationwidget.h
new file mode 100644
index 0000000..8f9f63e
--- /dev/null
+++ b/src/ui/configurationwidget.h
@@ -0,0 +1,141 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef CONFIGURATIONWIDGET_H
+#define CONFIGURATIONWIDGET_H
+
+#include "deviceitem.h"
+
+#include <remotecontrolwidget/remotecontrolwidget.h>
+
+#include <QtGui/QWidget>
+#include <QtCore/QPointer>
+
+class Ui_Inspector;
+class OptionsItem;
+class FilterLineEdit;
+class MobilityData;
+class ToolBox;
+class ToolBoxPage;
+class StyledBar;
+class QToolButton;
+class QMenuBar;
+class ViewConfiguration;
+class QLineEdit;
+class Widget;
+class SimulatorScriptInterface;
+
+class ConfigurationWidget: public RemoteControlWidget
+{
+ Q_OBJECT
+public:
+ explicit ConfigurationWidget(QWidget *parent = 0);
+ ~ConfigurationWidget();
+
+ SimulatorScriptInterface *scriptInterface();
+
+ void initializeSelection();
+
+ int currentDeviceIndex() const;
+ QString currentDeviceName() const;
+
+ bool initializeDeviceList();
+
+ virtual void writeSettings(const QString &vendor, const QString &name) const;
+ virtual void readSettings(const QString &vendor, const QString &name);
+
+public slots:
+ void changeDeviceSelection(int newIndex);
+ void updateTopWidget(Widget *topWidget);
+
+signals:
+ void deviceSelectionChanged(const DeviceData &data);
+ void scaleFactorChanged(qreal newScaleFactor);
+ void rotateRequested();
+ void closeMainWindow();
+ void exitButtonClicked();
+
+protected:
+ virtual void closeEvent(QCloseEvent *event);
+
+private slots:
+ void changeScaleFactor(int sliderPosition);
+ void changeCorrectionFactor(qreal);
+ void rotate();
+ void showViewConfiguration();
+
+private:
+ void initializeViewArea();
+ void initializeApplicationArea();
+
+ QList<DeviceData> deviceList;
+ Ui_Inspector *ui_inspector;
+ qreal mCorrectionFactor;
+
+ QSize mLogicalDpi;
+
+ QToolButton *viewButton;
+
+ ViewConfiguration *mViewConfiguration;
+ QHBoxLayout *mMenuLayout;
+ QLineEdit *mWidgetTitle;
+
+ PageWidget *mAppPage;
+ PageWidget *mViewPage;
+
+ QPointer<QMenuBar> mMenuBar;
+
+ SimulatorScriptInterface *mScriptInterface;
+ friend class SimulatorScriptInterface;
+};
+
+class SimulatorScriptInterface : public QObject
+{
+ Q_OBJECT
+public:
+ SimulatorScriptInterface(ConfigurationWidget *ui);
+ virtual ~SimulatorScriptInterface();
+
+ Q_PROPERTY(int zoom READ zoom WRITE setZoom)
+
+ int zoom() const;
+ void setZoom(int z);
+
+ Q_INVOKABLE int currentDeviceIndex() const;
+ Q_INVOKABLE QString currentDeviceName() const;
+ Q_INVOKABLE int deviceCount() const;
+ Q_INVOKABLE void rotate();
+ Q_INVOKABLE void setDevice(const QString & dev);
+ Q_INVOKABLE void setDevice(int index);
+
+private:
+ ConfigurationWidget *ui;
+};
+
+#endif //CONFIGURATIONWIDGET_H
diff --git a/src/ui/contactsui.cpp b/src/ui/contactsui.cpp
new file mode 100644
index 0000000..e111dbc
--- /dev/null
+++ b/src/ui/contactsui.cpp
@@ -0,0 +1,103 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "contactsui.h"
+
+#include "contacts.h"
+#include "configurationwidget.h"
+
+#include <remotecontrolwidget/optionsitem.h>
+
+#include <contacts/qcontactmanager.h>
+#include <contacts/qcontact.h>
+#include <contacts/details/qcontactname.h>
+
+#include <QtCore/QList>
+#include <QtGui/QPushButton>
+#include <QtGui/QTableWidget>
+#include <QtGui/QFileDialog>
+#include <QtGui/QMessageBox>
+
+ContactsUi::ContactsUi(Contacts *contacts, QWidget *parent)
+ : ToolBoxPage(parent)
+ , mContacts(contacts)
+ , mContactList(0)
+{
+ QStringList tags;
+ QList<OptionsItem *> optionsList;
+
+ mContactList = new QTableWidget();
+ mContactList->setColumnCount(1);
+ mContactList->setColumnWidth(0, mContactList->width() - mContactList->frameWidth());
+ mContactList->setHorizontalHeaderLabels(QStringList(tr("Name")));
+ mContactList->horizontalHeaderItem(0)->setTextAlignment(Qt::AlignLeft);
+ OptionsItem *item = new OptionsItem("", mContactList, true);
+ item->setTags(tags);
+ optionsList << item;
+
+ QPushButton *contactsImportButton = new QPushButton(tr("Import"));
+ connect(contactsImportButton, SIGNAL(clicked()), this, SLOT(importContacts()));
+ item = new OptionsItem("", contactsImportButton, true);
+ item->setTags(tags);
+ optionsList << item;
+
+ connect(mContacts, SIGNAL(contactsAdded(QList<QContactLocalId>)), this, SLOT(updateContactList()));
+ connect(mContacts, SIGNAL(contactsRemoved(QList<QContactLocalId>)), this, SLOT(updateContactList()));
+ connect(mContacts, SIGNAL(contactsChanged(QList<QContactLocalId>)), this, SLOT(updateContactList()));
+ connect(mContacts, SIGNAL(contactsDataChanged(const QContactManager &)), this, SLOT(updateContactList()));
+
+ setTitle(tr("Contacts"));
+ setOptions(optionsList);
+}
+
+void ContactsUi::importContacts()
+{
+ QString importFile = QFileDialog::getOpenFileName(0, tr("Select vCard File to Import"), ".", "*.vcf");
+ if (importFile.isNull())
+ return;
+
+ if (!mContacts->importFromVCardFile(importFile)) {
+ QMessageBox::information(0, tr("Import Failed"),
+ tr("Sorry, unable to import \"%1\".").arg(importFile));
+ }
+
+ updateContactList();
+}
+
+void ContactsUi::updateContactList() {
+ QList<QContactLocalId> contactIds = mContacts->manager()->contactIds();
+ mContactList->setRowCount(contactIds.size());
+
+ int row = 0;
+ foreach (const QContactLocalId &id, contactIds) {
+ QString name = mContacts->manager()->contact(id).displayLabel();
+ mContactList->setItem(row++, 0, new QTableWidgetItem(name));
+ }
+}
+
diff --git a/src/ui/contactsui.h b/src/ui/contactsui.h
new file mode 100644
index 0000000..6d756dc
--- /dev/null
+++ b/src/ui/contactsui.h
@@ -0,0 +1,56 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef CONTACTSUI_H
+#define CONTACTSUI_H
+
+#include <remotecontrolwidget/toolbox.h>
+
+#include <QtCore/QObject>
+
+class ConfigurationWidget;
+class Contacts;
+class QTableWidget;
+
+class ContactsUi : public ToolBoxPage
+{
+ Q_OBJECT
+public:
+ explicit ContactsUi(Contacts *contacts, QWidget *parent = 0);
+
+private slots:
+ void importContacts();
+ void updateContactList();
+
+private:
+ Contacts *mContacts;
+ QTableWidget *mContactList;
+};
+
+#endif // CONTACTSUI_H
diff --git a/src/ui/icons/hicolor/128x128/apps/Nokia-Simulator.png b/src/ui/icons/hicolor/128x128/apps/Nokia-Simulator.png
new file mode 100644
index 0000000..3530343
--- /dev/null
+++ b/src/ui/icons/hicolor/128x128/apps/Nokia-Simulator.png
Binary files differ
diff --git a/src/ui/icons/hicolor/16x16/apps/Nokia-Simulator.png b/src/ui/icons/hicolor/16x16/apps/Nokia-Simulator.png
new file mode 100644
index 0000000..6734273
--- /dev/null
+++ b/src/ui/icons/hicolor/16x16/apps/Nokia-Simulator.png
Binary files differ
diff --git a/src/ui/icons/hicolor/24x24/apps/Nokia-Simulator.png b/src/ui/icons/hicolor/24x24/apps/Nokia-Simulator.png
new file mode 100644
index 0000000..c22d6fc
--- /dev/null
+++ b/src/ui/icons/hicolor/24x24/apps/Nokia-Simulator.png
Binary files differ
diff --git a/src/ui/icons/hicolor/256x256/apps/Nokia-Simulator.png b/src/ui/icons/hicolor/256x256/apps/Nokia-Simulator.png
new file mode 100644
index 0000000..e3c6843
--- /dev/null
+++ b/src/ui/icons/hicolor/256x256/apps/Nokia-Simulator.png
Binary files differ
diff --git a/src/ui/icons/hicolor/32x32/apps/Nokia-Simulator.png b/src/ui/icons/hicolor/32x32/apps/Nokia-Simulator.png
new file mode 100644
index 0000000..3f41ef8
--- /dev/null
+++ b/src/ui/icons/hicolor/32x32/apps/Nokia-Simulator.png
Binary files differ
diff --git a/src/ui/icons/hicolor/48x48/apps/Nokia-Simulator.png b/src/ui/icons/hicolor/48x48/apps/Nokia-Simulator.png
new file mode 100644
index 0000000..7aa7dfe
--- /dev/null
+++ b/src/ui/icons/hicolor/48x48/apps/Nokia-Simulator.png
Binary files differ
diff --git a/src/ui/icons/hicolor/64x64/apps/Nokia-Simulator.png b/src/ui/icons/hicolor/64x64/apps/Nokia-Simulator.png
new file mode 100644
index 0000000..c4efee1
--- /dev/null
+++ b/src/ui/icons/hicolor/64x64/apps/Nokia-Simulator.png
Binary files differ
diff --git a/src/ui/inspector.ui b/src/ui/inspector.ui
new file mode 100644
index 0000000..2aacfe8
--- /dev/null
+++ b/src/ui/inspector.ui
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Inspector</class>
+ <widget class="QWidget" name="Inspector">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>388</width>
+ <height>126</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Device Control</string>
+ </property>
+ <property name="styleSheet">
+ <string/>
+ </property>
+ <layout class="QVBoxLayout" name="mainLayout">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QFrame" name="viewFrame">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>250</height>
+ </size>
+ </property>
+ <layout class="QFormLayout" name="viewLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Device</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="deviceListView">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QPushButton" name="rotateButton">
+ <property name="text">
+ <string>Rotate Device</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Zoom</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <item>
+ <widget class="QSlider" name="scaleSlider">
+ <property name="minimum">
+ <number>0</number>
+ </property>
+ <property name="maximum">
+ <number>100</number>
+ </property>
+ <property name="value">
+ <number>0</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_6">
+ <item>
+ <widget class="QLabel" name="label_6">
+ <property name="text">
+ <string>Native size</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>Native resolution</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item row="3" column="0">
+ <layout class="QHBoxLayout" name="horizontalLayout_3"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/ui/locationui.cpp b/src/ui/locationui.cpp
new file mode 100644
index 0000000..53e8e03
--- /dev/null
+++ b/src/ui/locationui.cpp
@@ -0,0 +1,117 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "locationui.h"
+
+#include "optionsitem.h"
+#include "configurationwidget.h"
+#include "location.h"
+
+#include <location/qgeopositioninfodata_simulator_p.h>
+
+#include <QtGui/QLineEdit>
+#include <QtGui/QDoubleValidator>
+#include <QtGui/QPushButton>
+#include <QtGui/QBoxLayout>
+#include <QtGui/QDateTimeEdit>
+
+LocationUi::LocationUi(ConfigurationWidget *w, Location *location)
+ : QObject(w)
+ , mLocation(location)
+ , mLatitudeEdit(0)
+ , mLongitudeEdit(0)
+ , mAltitudeEdit(0)
+ , mTimeEdit(0)
+{
+ QStringList tags;
+ QList<OptionsItem *> optionsList;
+
+ mLatitudeEdit = new QLineEdit("52.5056819");
+ mLatitudeEdit->setValidator(new QDoubleValidator(-90, 90, 10, this));
+ OptionsItem *item = new OptionsItem(tr("Latitude"), mLatitudeEdit);
+ connect(mLatitudeEdit, SIGNAL(editingFinished()), SLOT(triggerLocationInfoChange()));
+ item->setTags(tags);
+ optionsList << item;
+
+ mLongitudeEdit = new QLineEdit("13.3232027");
+ mLatitudeEdit->setValidator(new QDoubleValidator(-180, 180, 10, this));
+ item = new OptionsItem(tr("Longitude"), mLongitudeEdit);
+ connect(mLongitudeEdit, SIGNAL(editingFinished()), SLOT(triggerLocationInfoChange()));
+ item->setTags(tags);
+ optionsList << item;
+
+ mAltitudeEdit = new QLineEdit("13.3232027");
+ mAltitudeEdit->setValidator(new QDoubleValidator(-15000, 15000, 10, this));
+ item = new OptionsItem(tr("Altitude"), mAltitudeEdit);
+ connect(mAltitudeEdit, SIGNAL(editingFinished()), SLOT(triggerLocationInfoChange()));
+ item->setTags(tags);
+ optionsList << item;
+
+ mTimeEdit = new QDateTimeEdit();
+ QPushButton *locationTimeButton = new QPushButton(tr("Now"));
+ QHBoxLayout *hLayout = new QHBoxLayout();
+ hLayout->setContentsMargins(0, 0, 0, 0);
+ QVBoxLayout *vLayout = new QVBoxLayout();
+ vLayout->addWidget(mTimeEdit);
+ vLayout->addWidget(locationTimeButton);
+ hLayout->addLayout(vLayout);
+ QWidget *tmp = new QWidget();
+ tmp->setLayout(hLayout);
+ connect(mTimeEdit, SIGNAL(dateTimeChanged(const QDateTime &)), SLOT(triggerLocationInfoChange()));
+ connect(locationTimeButton, SIGNAL(clicked()), this, SLOT(updateLocationTime()));
+ item = new OptionsItem(tr("Timestamp"), tmp);
+ item->setTags(tags);
+ optionsList << item;
+ connect(mLocation, SIGNAL(locationChanged(QGeoPositionInfoData)), this, SLOT(locationSetData()));
+
+ w->addToolBoxPage(tr("Location"), optionsList);
+}
+
+void LocationUi::triggerLocationInfoChange()
+{
+ mLocation->setLatitude(mLatitudeEdit->text().toDouble());
+ mLocation->setLongitude(mLongitudeEdit->text().toDouble());
+ mLocation->setAltitude(mAltitudeEdit->text().toDouble());
+ mLocation->setDateTime(mTimeEdit->dateTime());
+ mLocation->publish();
+}
+
+void LocationUi::updateLocationTime()
+{
+ mTimeEdit->setDateTime(QDateTime::currentDateTime());
+}
+
+void LocationUi::locationSetData()
+{
+ mLatitudeEdit->setText(QString::number(mLocation->latitude(), 'f', 8));
+ mLongitudeEdit->setText(QString::number(mLocation->longitude(), 'f', 8));
+ mAltitudeEdit->setText(QString::number(mLocation->altitude(), 'f', 8));
+ mTimeEdit->setDateTime(mLocation->dateTime());
+}
+
diff --git a/src/ui/locationui.h b/src/ui/locationui.h
new file mode 100644
index 0000000..d241237
--- /dev/null
+++ b/src/ui/locationui.h
@@ -0,0 +1,59 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef LOCATIONUI_H
+#define LOCATIONUI_H
+
+#include <QtCore/QObject>
+
+class ConfigurationWidget;
+class Location;
+class QLineEdit;
+class QDateTimeEdit;
+
+class LocationUi : public QObject
+{
+ Q_OBJECT
+public:
+ LocationUi(ConfigurationWidget* w, Location *location);
+
+private slots:
+ void updateLocationTime();
+ void locationSetData();
+ void triggerLocationInfoChange();
+
+private:
+ Location *mLocation;
+ QLineEdit *mLatitudeEdit;
+ QLineEdit *mLongitudeEdit;
+ QLineEdit *mAltitudeEdit;
+ QDateTimeEdit *mTimeEdit;
+};
+
+#endif // LOCATIONUI_H
diff --git a/src/ui/mainwindow.cpp b/src/ui/mainwindow.cpp
new file mode 100644
index 0000000..a62140b
--- /dev/null
+++ b/src/ui/mainwindow.cpp
@@ -0,0 +1,399 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "mainwindow.h"
+#include "configurationwidget.h"
+#include "displaywidget.h"
+#include "applicationmanager.h"
+#include "phononmanager.h"
+#include "widgetmanager.h"
+#include "mobilitymanager.h"
+#include "mobilitydata.h"
+
+#include "contactsui.h"
+#include "systeminfogenericui.h"
+#include "systeminfonetworkui.h"
+#include "systeminfostorageui.h"
+#include "messagingui.h"
+#include "sensorsui.h"
+
+#include <remotecontrolwidget/locationui.h>
+#include <remotecontrolwidget/scriptui.h>
+#include <remotecontrolwidget/scriptadapter.h>
+#include <remotecontrolwidget/batterybutton.h>
+#include <remotecontrolwidget/powerbutton.h>
+#include <remotecontrolwidget/signalstrengthbutton.h>
+#include <remotecontrolwidget/networkmodebutton.h>
+#include <remotecontrolwidget/favoritescriptbutton.h>
+
+#include <QtCore/QDebug>
+#include <QtCore/QTimer>
+#include <QtCore/QSettings>
+#include <QtCore/QDir>
+#include <QtGui/QKeyEvent>
+#include <QtGui/QLayout>
+#include <QtGui/QGraphicsView>
+#include <QtGui/QPixmap>
+#include <QtGui/QPushButton>
+#include <QtGui/QApplication>
+#include <QtGui/QDesktopWidget>
+
+#if defined(Q_WS_X11)
+#include <private/qt_x11_p.h>
+#include <QtGui/QX11Info>
+#endif
+
+MainWindow::MainWindow(QWidget *parent)
+ : QWidget(parent)
+ , view(0)
+ , config(0)
+ , applicationManager(0)
+ , deviceItem(0)
+ , debugWindow(0)
+ , startupError(false)
+{
+ setWindowIcon(QIcon(":/ui/icons/hicolor/256x256/apps/Nokia-Simulator.png"));
+
+ applicationManager = new ApplicationManager(this);
+ if (applicationManager->simulatorAlreadyStarted()
+ || !applicationManager->initializeFontDirectory()) {
+ QTimer::singleShot(0, this, SLOT(close()));
+ startupError = true;
+ return;
+ }
+
+ MobilityData *mobility = new MobilityData(this);
+ mobilityServer = new MobilityServer(mobility, this);
+
+ setWindowTitle(tr("Qt Simulator"));
+#ifdef Q_OS_MAC
+ // Sorry, widgets with translucent background are broken on MacOS X.
+ // Wait until QTBUG-6831 is fixed.
+#else
+ setAttribute(Qt::WA_TranslucentBackground);
+ setWindowFlags(Qt::FramelessWindowHint);
+ // set a mask, because kwin's compositor won't draw shadows under the window then
+ setMask(QRect(0,0,4096,4096));
+#endif
+
+ scene = new QGraphicsScene(this);
+
+ deviceItem = new DeviceItem;
+
+ scene->addItem(deviceItem);
+
+ view = new QGraphicsView(scene);
+ view->setOptimizationFlag(QGraphicsView::DontSavePainterState);
+ view->setRenderHint(QPainter::SmoothPixmapTransform);
+ view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ // otherwise the graphics view won't be transparent
+ view->viewport()->setAutoFillBackground(false);
+
+ PhononManager* phononManager = new PhononManager(this);
+ phononManager->setObjectName("PhononManager");
+ applicationManager->setPhononManager(phononManager);
+
+ WidgetManager *widgetManager = new WidgetManager(deviceItem->display(), this);
+ applicationManager->setWidgetManager(widgetManager);
+
+ connect(applicationManager, SIGNAL(applicationUnRegistered(int)), widgetManager, SLOT(onApplicationUnregistered(int)));
+ connect(deviceItem, SIGNAL(deviceChanged(QSize,DeviceData)), applicationManager, SLOT(updateDisplayInformation(QSize,DeviceData)));
+ connect(deviceItem, SIGNAL(drag(QPoint)), this, SLOT(dragFromView(QPoint)));
+ connect(deviceItem, SIGNAL(viewSizeRequired(QSize)), this, SLOT(setViewSize(QSize)));
+ connect(deviceItem, SIGNAL(buttonPressed(Qt::Key, QString)), widgetManager, SLOT(sendKeyPress(Qt::Key, QString)));
+ connect(deviceItem, SIGNAL(buttonReleased(Qt::Key)), widgetManager, SLOT(sendKeyRelease(Qt::Key)));
+ connect(deviceItem, SIGNAL(offsetChanged(const QPoint &)), widgetManager, SLOT(changeOffset(const QPoint &)));
+ connect(deviceItem, SIGNAL(orientationChanged(Orientation, Orientation)), mobility, SLOT(rotateDevice(Orientation, Orientation)));
+ connect(deviceItem, SIGNAL(deviceChanged(Orientation, Orientation, Orientation)),
+ mobility, SLOT(changeDevice(Orientation, Orientation, Orientation)));
+
+ view->setFrameStyle(QFrame::NoFrame);
+ view->setParent(this);
+
+ // Setup debug window.
+ debugWindow = new QWidget(this);
+ debugWindow->setWindowFlags(Qt::Window);
+ QHBoxLayout *layout = new QHBoxLayout;
+ layout->addWidget(applicationManager->logWidget());
+ layout->addWidget(widgetManager->logWidget());
+ debugWindow->setLayout(layout);
+
+ // Setup configuration window.
+ config = new ConfigurationWidget(this);
+ if (!config->initializeDeviceList()) {
+ QTimer::singleShot(0, this, SLOT(close()));
+ startupError = true;
+ return;
+ }
+ connect(widgetManager, SIGNAL(topWidgetChanged(Widget *)), config, SLOT(updateTopWidget(Widget *)));
+ connect(config, SIGNAL(deviceSelectionChanged(const DeviceData &)), deviceItem, SLOT(changeDevice(const DeviceData &)));
+ connect(deviceItem, SIGNAL(sizeChanged(const QSize &)), this, SLOT(setSizeToDevice(const QSize &)));
+ connect(config, SIGNAL(closeMainWindow()), this, SLOT(close()));
+ connect(config, SIGNAL(rotateRequested()), deviceItem, SLOT(toggleOrientation()));
+ connect(config, SIGNAL(scaleFactorChanged(qreal)), deviceItem, SLOT(changeScaleFactor(qreal)));
+ connect(config, SIGNAL(exitButtonClicked()), applicationManager, SLOT(killCurrentApplication()));
+
+ scriptAdapter = new ScriptAdapter(this);
+
+ // build ui pages
+ GenericSystemInfoUi *genericSystemInfoUi = new GenericSystemInfoUi(this);
+ mobility->mSystemInfoGenericUi = genericSystemInfoUi;
+ config->addSimulateSubPage(genericSystemInfoUi);
+
+ StorageSystemInfoUi *storageSystemInfoUi = new StorageSystemInfoUi(this);
+ mobility->mSystemInfoStorageUi = storageSystemInfoUi;
+ config->addSimulateSubPage(storageSystemInfoUi);
+
+ NetworkSystemInfoUi *networkSystemInfoUi = new NetworkSystemInfoUi(this);
+ mobility->mSystemInfoNetworkUi = networkSystemInfoUi;
+ config->addSimulateSubPage(networkSystemInfoUi);
+
+ LocationUi *locationUi = new LocationUi(this);
+ mobility->mLocationUi = locationUi;
+ config->addSimulateSubPage(locationUi);
+
+ config->addSimulateSubPage(new ContactsUi(mobility->mContacts, this));
+ config->addSimulateSubPage(new MessagingUi(mobility, this));
+
+ SensorsUi *sensorsUi = new SensorsUi(this);
+ mobility->mSensorsUi = sensorsUi;
+ config->addSimulateSubPage(sensorsUi);
+
+ config->addSimulateSubPage(new ScriptUi(scriptAdapter, this));
+
+ NetworkModeButton *networkModeButton = new NetworkModeButton(this);
+ connect(networkModeButton, SIGNAL(networkModeChanged(NetworkModeButton::NetworkMode)),
+ networkSystemInfoUi, SLOT(setCurrentNetworkMode(NetworkModeButton::NetworkMode)));
+ connect(networkSystemInfoUi, SIGNAL(currentNetworkModeChanged(NetworkModeButton::NetworkMode)),
+ networkModeButton, SLOT(setDisplayedNetworkMode(NetworkModeButton::NetworkMode)));
+ config->addMenuButton(networkModeButton);
+
+ SignalStrengthButton *signalStrengthButton = new SignalStrengthButton(this);
+ connect(signalStrengthButton, SIGNAL(signalStrengthChanged(SignalStrengthButton::SignalStrength)),
+ networkSystemInfoUi, SLOT(setCurrentNetworkSignalStrength(SignalStrengthButton::SignalStrength)));
+ connect(networkSystemInfoUi, SIGNAL(currentNetworkSignalStrengthChanged(SignalStrengthButton::SignalStrength)),
+ signalStrengthButton, SLOT(setDisplayedSignalStrength(SignalStrengthButton::SignalStrength)));
+ config->addMenuButton(signalStrengthButton);
+
+ BatteryButton *batteryButton = new BatteryButton(this);
+ connect(batteryButton, SIGNAL(batteryLevelChanged(BatteryButton::BatteryLevel)),
+ mobility->mSystemInfoGenericUi, SLOT(setCurrentBatteryLevel(BatteryButton::BatteryLevel)));
+ connect(mobility->mSystemInfoGenericUi, SIGNAL(currentBatteryLevelChanged(BatteryButton::BatteryLevel)),
+ batteryButton, SLOT(setDisplayedBatteryLevel(BatteryButton::BatteryLevel)));
+ config->addMenuButton(batteryButton);
+
+ PowerButton *powerButton = new PowerButton(this);
+ connect(powerButton, SIGNAL(powerStateChanged(PowerButton::PowerState)),
+ mobility->mSystemInfoGenericUi, SLOT(setCurrentPowerState(PowerButton::PowerState)));
+ connect(mobility->mSystemInfoGenericUi, SIGNAL(currentPowerStateChanged(PowerButton::PowerState)),
+ powerButton, SLOT(setDisplayedState(PowerButton::PowerState)));
+ config->addMenuButton(powerButton);
+
+ FavoriteScriptButton *scriptButton = new FavoriteScriptButton(this);
+ connect(scriptButton, SIGNAL(scriptSelected(QString)),
+ scriptAdapter, SLOT(run(QString)));
+ // ### Should be a path in the user directory, not next to the executable!
+ QDir scriptDir(QCoreApplication::applicationDirPath());
+ scriptDir.cd("scripts");
+ scriptDir.cd("favorites");
+ scriptButton->setPath(scriptDir.path());
+ config->addMenuButton(scriptButton);
+
+ // register script interfaces
+ scriptAdapter->addScriptInterface("simulator", config->scriptInterface());
+ scriptAdapter->addScriptInterface("sensors", sensorsUi->scriptInterface());
+ scriptAdapter->addScriptInterface("location", locationUi->scriptInterface());
+ scriptAdapter->addScriptInterface("sysinfo.generic", genericSystemInfoUi->scriptInterface());
+ scriptAdapter->addScriptInterface("sysinfo.network", networkSystemInfoUi->scriptInterface());
+ scriptAdapter->addScriptInterface("sysinfo.storage", storageSystemInfoUi->scriptInterface());
+
+ connect(config, SIGNAL(deviceSelectionChanged(const DeviceData &)), SLOT(callDeviceScript(const DeviceData &)));
+
+ config->initializeSelection();
+ config->setWindowFlags(Qt::Tool);
+ config->readSettings(QCoreApplication::organizationName(), QCoreApplication::applicationName());
+
+ mobility->setInitialData();
+
+ config->show();
+
+ // Filter to show debug window on special key press.
+ view->installEventFilter(this);
+ view->setFocus();
+
+ readSettings();
+ scriptAdapter->runAutostartScripts();
+}
+
+MainWindow::~MainWindow()
+{
+}
+
+bool MainWindow::eventFilter(QObject *watched, QEvent *event)
+{
+ if (watched == view)
+ {
+ if (event->type() == QEvent::KeyPress) {
+ QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
+ if (keyEvent->key() == Qt::Key_F9
+ && keyEvent->modifiers() & Qt::ControlModifier)
+ {
+ debugWindow->show();
+ }
+ }
+ }
+ return false;
+}
+
+void MainWindow::closeEvent(QCloseEvent *event)
+{
+ if (applicationManager->hasApplications()) {
+ event->ignore();
+ applicationManager->killAllApplications();
+ connect(applicationManager, SIGNAL(lastAppUnregistered()), this, SLOT(close()));
+ return;
+ }
+
+ if (!startupError) {
+ writeSettings();
+ config->writeSettings(QCoreApplication::organizationName(), QCoreApplication::applicationName());
+ }
+}
+
+void MainWindow::setSizeToDevice(const QSize &size)
+{
+ QSize targetSize(size);
+
+ // don't try to make windows bigger than allowed on X11
+#ifdef Q_WS_X11
+ QSize maxSize = QApplication::desktop()->availableGeometry(this).size();
+ targetSize = targetSize.boundedTo(maxSize);
+#endif
+ setMaximumSize(targetSize);
+ resize(targetSize);
+}
+
+void MainWindow::dragFromView(const QPoint &to)
+{
+#ifdef Q_WS_X11
+ XEvent xev;
+ xev.xclient.type = ClientMessage;
+ xev.xclient.message_type = ATOM(_NET_WM_MOVERESIZE);
+ xev.xclient.display = X11->display;
+ xev.xclient.window = winId();
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = to.x();
+ xev.xclient.data.l[1] = to.y();
+ // only moving (the "move via keyboard" value seems to impose less
+ // movement restrictions)
+ xev.xclient.data.l[2] = 10;
+ xev.xclient.data.l[3] = Button1;
+ xev.xclient.data.l[4] = 2; // user event
+ XUngrabPointer(X11->display, X11->time);
+ XSendEvent(X11->display, QX11Info::appRootWindow(x11Info().screen()), False,
+ SubstructureRedirectMask | SubstructureNotifyMask, &xev);
+#else
+ move(to - view->pos());
+#endif
+}
+
+void MainWindow::setViewSize(const QSize &size)
+{
+ QSize targetSize(size);
+
+ // X11 seems to be unable to draw windows bigger than the available desktop geometry.
+ // Therefore, we enable scroll bars there if the view is required to be bigger than that.
+#ifdef Q_WS_X11
+ QSize maxSize = QApplication::desktop()->availableGeometry(this).size();
+ targetSize = targetSize.boundedTo(maxSize);
+ // the first check is for whether we're rotating at the moment
+ if (targetSize == this->size() || targetSize == size) {
+ view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ } else {
+ view->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ view->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ }
+
+ // adjust the window mask, otherwise the window is transparent, but clickable
+ setMask(QRect(QPoint(width() - targetSize.width(), height() - targetSize.height()) / 2, targetSize));
+#endif
+
+ // resize and center the view
+ view->move(QPoint(width() - targetSize.width(), height() - targetSize.height()) / 2);
+ view->resize(targetSize);
+
+ view->setSceneRect(0, 0, size.width(), size.height());
+ view->centerOn(size.width() / 2, size.height() / 2);
+}
+
+void MainWindow::writeSettings() const
+{
+ QSettings settings;
+
+ settings.beginGroup("MainWindow");
+ settings.setValue("pos", pos());
+ settings.endGroup();
+}
+
+void MainWindow::readSettings()
+{
+ QSettings settings;
+
+ settings.beginGroup("MainWindow");
+ if (settings.contains("pos")) {
+ const QPoint savedPosition = settings.value("pos").toPoint();
+ const QRect geometry = QApplication::desktop()->availableGeometry(savedPosition);
+ if (geometry.contains(savedPosition))
+ move(savedPosition);
+ }
+ settings.endGroup();
+}
+
+void MainWindow::handleMessage(const QString &message)
+{
+ if (message.startsWith(QLatin1String("runscript "))) {
+ const QString filePath = message.mid(10);
+ scriptAdapter->run(filePath);
+ }
+}
+
+void MainWindow::callDeviceScript(const DeviceData &newDevice)
+{
+ QString deviceScript = QCoreApplication::applicationDirPath()
+ + QString::fromUtf8("/scripts/devices/") + newDevice.name
+ + QString::fromUtf8(".qs");
+
+ if (!QFile::exists(deviceScript)) {
+ deviceScript = deviceScript.replace(newDevice.name + QString::fromUtf8(".qs"),
+ QString::fromUtf8("Default.qs"));
+ }
+ scriptAdapter->run(deviceScript);
+}
diff --git a/src/ui/mainwindow.h b/src/ui/mainwindow.h
new file mode 100644
index 0000000..32497ae
--- /dev/null
+++ b/src/ui/mainwindow.h
@@ -0,0 +1,85 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+#include "deviceitem.h"
+#include <QtGui/QWidget>
+
+class DeviceItem;
+class ApplicationManager;
+class MobilityServer;
+class ConfigurationWidget;
+class ScriptAdapter;
+class QGraphicsView;
+class QGraphicsScene;
+
+class MainWindow : public QWidget
+{
+ Q_OBJECT
+
+public:
+ MainWindow(QWidget *parent = 0);
+ ~MainWindow();
+
+ virtual bool eventFilter(QObject *watched, QEvent *event);
+ virtual void closeEvent(QCloseEvent *event);
+
+public slots:
+ void setSizeToDevice(const QSize &size);
+ void dragFromView(const QPoint &to);
+ void setViewSize(const QSize &size);
+
+ // for messages from other simulator instances
+ void handleMessage(const QString &message);
+
+private slots:
+ void callDeviceScript(const DeviceData &newDevice);
+
+private:
+ void writeSettings() const;
+ void readSettings();
+
+private:
+ QGraphicsView *view;
+ QGraphicsScene *scene;
+
+ ConfigurationWidget *config;
+ ApplicationManager *applicationManager;
+ DeviceItem *deviceItem;
+
+ MobilityServer *mobilityServer;
+
+ ScriptAdapter *scriptAdapter;
+
+ QWidget *debugWindow;
+ bool startupError;
+};
+
+#endif // MAINWINDOW_H
diff --git a/src/ui/menus/fremantle_landscape.png b/src/ui/menus/fremantle_landscape.png
new file mode 100644
index 0000000..9b1de05
--- /dev/null
+++ b/src/ui/menus/fremantle_landscape.png
Binary files differ
diff --git a/src/ui/menus/fremantle_portrait.png b/src/ui/menus/fremantle_portrait.png
new file mode 100644
index 0000000..d9e12bd
--- /dev/null
+++ b/src/ui/menus/fremantle_portrait.png
Binary files differ
diff --git a/src/ui/menus/menus.qrc b/src/ui/menus/menus.qrc
new file mode 100644
index 0000000..773d106
--- /dev/null
+++ b/src/ui/menus/menus.qrc
@@ -0,0 +1,10 @@
+<RCC>
+ <qresource prefix="/menus">
+ <file>fremantle_landscape.png</file>
+ <file>fremantle_portrait.png</file>
+ <file>symbiantouch_status_landscape.png</file>
+ <file>symbiantouch_status_portrait.png</file>
+ <file>symbiantouch_buttons_small_landscape.png</file>
+ <file>symbiantouch_buttons_small_portrait.png</file>
+ </qresource>
+</RCC>
diff --git a/src/ui/menus/symbiantouch_buttons_small_landscape.png b/src/ui/menus/symbiantouch_buttons_small_landscape.png
new file mode 100644
index 0000000..a3653dd
--- /dev/null
+++ b/src/ui/menus/symbiantouch_buttons_small_landscape.png
Binary files differ
diff --git a/src/ui/menus/symbiantouch_buttons_small_portrait.png b/src/ui/menus/symbiantouch_buttons_small_portrait.png
new file mode 100644
index 0000000..f0f3af7
--- /dev/null
+++ b/src/ui/menus/symbiantouch_buttons_small_portrait.png
Binary files differ
diff --git a/src/ui/menus/symbiantouch_status_landscape.png b/src/ui/menus/symbiantouch_status_landscape.png
new file mode 100644
index 0000000..99a1e97
--- /dev/null
+++ b/src/ui/menus/symbiantouch_status_landscape.png
Binary files differ
diff --git a/src/ui/menus/symbiantouch_status_portrait.png b/src/ui/menus/symbiantouch_status_portrait.png
new file mode 100644
index 0000000..c9dff3e
--- /dev/null
+++ b/src/ui/menus/symbiantouch_status_portrait.png
Binary files differ
diff --git a/src/ui/messagingui.cpp b/src/ui/messagingui.cpp
new file mode 100644
index 0000000..6ebc22e
--- /dev/null
+++ b/src/ui/messagingui.cpp
@@ -0,0 +1,76 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "messagingui.h"
+
+#include "configurationwidget.h"
+#include "mobilitydata.h"
+
+#include <remotecontrolwidget/optionsitem.h>
+
+#include <QtGui/QPushButton>
+#include <QtGui/QFileDialog>
+
+MessagingUi::MessagingUi(MobilityData *mobilityData, QWidget *parent)
+ : ToolBoxPage(parent)
+ , mMobilityData(mobilityData)
+{
+ QList<OptionsItem *> options;
+ OptionsItem *item;
+
+ QPushButton *incomingEmailButton = new QPushButton(tr("Trigger"));
+ item = new OptionsItem(tr("Incoming email"), incomingEmailButton);
+ item->addTag(tr("message"));
+ connect(incomingEmailButton, SIGNAL(clicked()), mobilityData, SLOT(addNewEmail()));
+ options += item;
+
+ QPushButton *incomingSmsButton = new QPushButton(tr("Trigger"));
+ item = new OptionsItem(tr("Incoming SMS"), incomingSmsButton);
+ item->addTag(tr("message"));
+ connect(incomingSmsButton, SIGNAL(clicked()), mobilityData, SLOT(addNewSms()));
+ options += item;
+
+ QPushButton *importMaildirButton = new QPushButton(tr("Import"));
+ item = new OptionsItem(tr("Import mail directory"), importMaildirButton);
+ item->addTag(tr("message"));
+ connect(importMaildirButton, SIGNAL(clicked()), this, SLOT(importMaildir()));
+ options += item;
+
+ setTitle(tr("Messaging"));
+ setOptions(options);
+}
+
+void MessagingUi::importMaildir()
+{
+ QString dir = QFileDialog::getExistingDirectory(0, tr("Select maildir Directory to Import"));
+ if (dir.isEmpty())
+ return;
+
+ mMobilityData->mMessaging->importMaildir(dir);
+}
diff --git a/src/ui/messagingui.h b/src/ui/messagingui.h
new file mode 100644
index 0000000..372f7bf
--- /dev/null
+++ b/src/ui/messagingui.h
@@ -0,0 +1,53 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef MESSAGINGUI_H
+#define MESSAGINGUI_H
+
+#include <remotecontrolwidget/toolbox.h>
+
+#include <QtCore/QObject>
+
+class MobilityData;
+class ConfigurationWidget;
+
+class MessagingUi : public ToolBoxPage
+{
+ Q_OBJECT
+public:
+ explicit MessagingUi(MobilityData *mobilityData, QWidget *parent = 0);
+
+private slots:
+ void importMaildir();
+
+private:
+ MobilityData *mMobilityData;
+};
+
+#endif // MESSAGINGUI_H
diff --git a/src/ui/sensorsui.cpp b/src/ui/sensorsui.cpp
new file mode 100644
index 0000000..1710d1b
--- /dev/null
+++ b/src/ui/sensorsui.cpp
@@ -0,0 +1,522 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "sensorsui.h"
+
+#include "configurationwidget.h"
+
+#include <QtCore/QMetaEnum>
+#include <QtGui/QComboBox>
+#include <QtGui/QLineEdit>
+#include <QtGui/QSlider>
+#include <QtGui/QDoubleValidator>
+#include <QtGui/QPushButton>
+#include <QtGui/QRadioButton>
+#include <QtGui/QBoxLayout>
+#include <QtGui/QDateTimeEdit>
+#include <qmath.h>
+
+SensorDoubleEdit::SensorDoubleEdit(QWidget *parent)
+ : QWidget(parent)
+ , mValue(0)
+ , mDecimalPlaces(0)
+ , mCorrectionFactor(1)
+{
+ QVBoxLayout *vLayout = new QVBoxLayout();
+ vLayout->setMargin(0);
+ vLayout->setSpacing(1);
+ mSlider = new QSlider();
+ mSlider->setOrientation(Qt::Horizontal);
+ mSlider->setTickInterval(1);
+ connect(mSlider, SIGNAL(valueChanged(int)), SLOT(changeValue(int)));
+ mLineEdit = new QLineEdit("0.00");
+ mLineEdit->setValidator(new QDoubleValidator(this));
+ connect(mLineEdit, SIGNAL(editingFinished()), SLOT(updateValueFromLineEdit()));
+ vLayout->addWidget(mSlider);
+ vLayout->addWidget(mLineEdit);
+ setLayout(vLayout);
+}
+
+double SensorDoubleEdit::value() const
+{
+ return mValue;
+}
+
+void SensorDoubleEdit::setValue(double newValue, bool skipSignal)
+{
+ if (mValue != newValue)
+ {
+ mValue = newValue;
+ mLineEdit->setText(QString::number(newValue, 'f', mDecimalPlaces));
+ int sliderPos = (int)(newValue * mCorrectionFactor);
+ if (mSlider->value() != sliderPos)
+ mSlider->setValue(sliderPos);
+ if (!skipSignal)
+ emit valueChanged(newValue);
+ }
+}
+
+void SensorDoubleEdit::changeValue(int newValue)
+{
+ double actualValue = newValue / (double)mCorrectionFactor;
+ setValue(actualValue);
+}
+
+void SensorDoubleEdit::updateValueFromLineEdit()
+{
+ double newValue = mLineEdit->text().toDouble(0);
+ if (newValue >= mRange.first && newValue <= mRange.second)
+ setValue(newValue);
+ else
+ mLineEdit->setText(QString::number(mValue));
+}
+
+void SensorDoubleEdit::setRange(double min, double max)
+{
+ if (mRange.first != min || mRange.second != max) {
+ mRange = QPair<double, double>(min, max);
+ updateSlider();
+ }
+}
+
+void SensorDoubleEdit::setDecimalPlaces(int places)
+{
+ if (mDecimalPlaces != places) {
+ mDecimalPlaces = places;
+ mCorrectionFactor = pow(10., places);
+ updateSlider();
+ }
+}
+
+void SensorDoubleEdit::updateSlider()
+{
+ mSlider->setRange(mRange.first * mCorrectionFactor, mRange.second * mCorrectionFactor);
+ mSlider->setValue(mValue * mCorrectionFactor);
+}
+
+SensorsUi::SensorsUi(QWidget *parent)
+ : ToolBoxPage(parent)
+ , mAmbientLightBox(0)
+ , mAccelerometerXEdit(0)
+ , mAccelerometerYEdit(0)
+ , mAccelerometerZEdit(0)
+ , mMagnetometerXEdit(0)
+ , mMagnetometerYEdit(0)
+ , mMagnetometerZEdit(0)
+ , mMagnetometerCalibrationLevelEdit(0)
+ , mCompassCalibrationLevelEdit(0)
+ , mCompassAzimuthEdit(0)
+ , mProximitySensorCloseButton(0)
+ , mTimeEdit(0)
+{
+ mScriptInterface = new SensorsScriptInterface(this);
+
+ QStringList tags;
+ QList<OptionsItem *> optionsList;
+
+ mAmbientLightBox = new QComboBox();
+ connect(mAmbientLightBox, SIGNAL(activated(int)), SLOT(emitSensorsDataChange()));
+ OptionsItem *item = new OptionsItem(tr("Ambient light"), mAmbientLightBox);
+ optionsList << item;
+
+ mAccelerometerXEdit = new SensorDoubleEdit();
+ mAccelerometerXEdit->setRange(-50, 50);
+ mAccelerometerXEdit->setDecimalPlaces(2);
+ item = new OptionsItem(tr("Accelerometer x"), mAccelerometerXEdit);
+ connect(mAccelerometerXEdit, SIGNAL(valueChanged(double)), SLOT(emitSensorsDataChange()));
+ item->setTags(tags);
+ optionsList << item;
+
+ mAccelerometerYEdit = new SensorDoubleEdit();
+ mAccelerometerYEdit->setRange(-50, 50);
+ mAccelerometerYEdit->setDecimalPlaces(2);
+ item = new OptionsItem(tr("Accelerometer y"), mAccelerometerYEdit);
+ connect(mAccelerometerYEdit, SIGNAL(valueChanged(double)), SLOT(emitSensorsDataChange()));
+ item->setTags(tags);
+ optionsList << item;
+
+ mAccelerometerZEdit = new SensorDoubleEdit();
+ mAccelerometerZEdit->setRange(-50, 50);
+ mAccelerometerZEdit->setDecimalPlaces(2);
+ item = new OptionsItem(tr("Accelerometer z"), mAccelerometerZEdit);
+ connect(mAccelerometerZEdit, SIGNAL(valueChanged(double)), SLOT(emitSensorsDataChange()));
+ item->setTags(tags);
+ optionsList << item;
+
+ mMagnetometerXEdit = new SensorDoubleEdit();
+ mMagnetometerXEdit->setRange(0, 1);
+ mMagnetometerXEdit->setDecimalPlaces(2);
+ item = new OptionsItem(tr("Magnetometer x"), mMagnetometerXEdit);
+ connect(mMagnetometerXEdit, SIGNAL(valueChanged(double)), SLOT(emitSensorsDataChange()));
+ item->setTags(tags);
+ optionsList << item;
+
+ mMagnetometerYEdit = new SensorDoubleEdit();
+ mMagnetometerYEdit->setRange(0, 1);
+ mMagnetometerYEdit->setDecimalPlaces(2);
+ item = new OptionsItem(tr("Magnetometer y"), mMagnetometerYEdit);
+ connect(mMagnetometerYEdit, SIGNAL(valueChanged(double)), SLOT(emitSensorsDataChange()));
+ item->setTags(tags);
+ optionsList << item;
+
+ mMagnetometerZEdit = new SensorDoubleEdit();
+ mMagnetometerZEdit->setRange(0, 1);
+ mMagnetometerZEdit->setDecimalPlaces(2);
+ item = new OptionsItem(tr("Magnetometer z"), mMagnetometerZEdit);
+ connect(mMagnetometerZEdit, SIGNAL(valueChanged(double)), SLOT(emitSensorsDataChange()));
+ item->setTags(tags);
+ optionsList << item;
+
+ mMagnetometerCalibrationLevelEdit = new SensorDoubleEdit();
+ mMagnetometerCalibrationLevelEdit->setRange(0, 1);
+ mMagnetometerCalibrationLevelEdit->setDecimalPlaces(2);
+ item = new OptionsItem(tr("Magnetometer calibration level"), mMagnetometerCalibrationLevelEdit);
+ connect(mMagnetometerCalibrationLevelEdit, SIGNAL(valueChanged(double)), SLOT(emitSensorsDataChange()));
+ item->setTags(tags);
+ optionsList << item;
+
+ mCompassAzimuthEdit = new SensorDoubleEdit();
+ mCompassAzimuthEdit->setRange(0, 360);
+ mCompassAzimuthEdit->setDecimalPlaces(2);
+ item = new OptionsItem(tr("Compass azimuth"), mCompassAzimuthEdit);
+ connect(mCompassAzimuthEdit, SIGNAL(valueChanged(double)), SLOT(emitSensorsDataChange()));
+ item->setTags(tags);
+ optionsList << item;
+
+ mCompassCalibrationLevelEdit = new SensorDoubleEdit();
+ mCompassCalibrationLevelEdit->setRange(0, 1);
+ mCompassCalibrationLevelEdit->setDecimalPlaces(2);
+ item = new OptionsItem(tr("Compass calibration level"), mCompassCalibrationLevelEdit);
+ connect(mCompassCalibrationLevelEdit, SIGNAL(valueChanged(double)), SLOT(emitSensorsDataChange()));
+ item->setTags(tags);
+ optionsList << item;
+
+ mProximitySensorCloseButton = new QPushButton(tr("Far"));
+ mProximitySensorCloseButton->setCheckable(true);
+ item = new OptionsItem(tr("Proximity distance"), mProximitySensorCloseButton);
+ connect(mProximitySensorCloseButton, SIGNAL(toggled(bool)), SLOT(emitSensorsDataChange()));
+ connect(mProximitySensorCloseButton, SIGNAL(toggled(bool)), SLOT(updateProximityButtonText()));
+ item->setTags(tags);
+ optionsList << item;
+
+ QHBoxLayout *radioLayout = new QHBoxLayout();
+ mCurrentRadio = new QRadioButton(tr("Current"));
+ mCurrentRadio->setChecked(true);
+ mOverrideRadio = new QRadioButton(tr("Override"));
+ radioLayout->addWidget(mCurrentRadio);
+ radioLayout->addWidget(mOverrideRadio);
+ mTimeEdit = new QDateTimeEdit();
+ mTimeEdit->setDisabled(true);
+ QVBoxLayout *vLayout = new QVBoxLayout();
+ vLayout->setContentsMargins(0, 0, 0, 0);
+ vLayout->addLayout(radioLayout);
+ vLayout->addWidget(mTimeEdit);
+ QWidget *tmp = new QWidget();
+ tmp->setLayout(vLayout);
+ item = new OptionsItem(tr("Timestamp"), tmp);
+ item->setTags(tags << tr("Current") << tr("Override"));
+ optionsList << item;
+ connect(mCurrentRadio, SIGNAL(toggled(bool)), SLOT(updateTimeEditDisabled()));
+ connect(mTimeEdit, SIGNAL(dateTimeChanged(const QDateTime &)), SLOT(emitSensorsDataChange()));
+
+ initializeAmbientLightOptions();
+
+ setTitle(tr("Sensors"));
+ setOptions(optionsList);
+}
+
+SensorsUi::~SensorsUi()
+{
+}
+
+SensorsScriptInterface *SensorsUi::scriptInterface() const
+{
+ return mScriptInterface;
+}
+
+SensorsUi::SensorsData SensorsUi::sensorsData() const
+{
+ SensorsUi::SensorsData data;
+ data.ambientLightLevel = static_cast<SensorsScriptInterface::LightLevel>(mAmbientLightBox->currentIndex());
+ data.accelerometerX = mAccelerometerXEdit->value();
+ data.accelerometerY = mAccelerometerYEdit->value();
+ data.accelerometerZ = mAccelerometerZEdit->value();
+ data.magnetometerX = mMagnetometerXEdit->value();
+ data.magnetometerY = mMagnetometerYEdit->value();
+ data.magnetometerZ = mMagnetometerZEdit->value();
+ data.magnetometerCalibrationLevel = mMagnetometerCalibrationLevelEdit->value();
+ data.compassCalibrationLevel = mCompassCalibrationLevelEdit->value();
+ data.compassAzimuth = mCompassAzimuthEdit->value();
+ data.proximitySensorClose = mProximitySensorCloseButton->isChecked();
+ data.useCurrentTime = mCurrentRadio->isChecked();
+ data.timestamp = mTimeEdit->dateTime();
+ return data;
+}
+
+void SensorsUi::setSensorsData(const SensorsUi::SensorsData &data)
+{
+ setDisplayedSensorsData(data);
+ emit sensorsDataChanged(data);
+}
+
+void SensorsUi::setDisplayedSensorsData(const SensorsUi::SensorsData &data)
+{
+ mAmbientLightBox->setCurrentIndex(data.ambientLightLevel);
+ mAccelerometerXEdit->setValue(data.accelerometerX);
+ mAccelerometerYEdit->setValue(data.accelerometerY);
+ mAccelerometerZEdit->setValue(data.accelerometerZ);
+ mMagnetometerXEdit->setValue(data.magnetometerX);
+ mMagnetometerYEdit->setValue(data.magnetometerY);
+ mMagnetometerZEdit->setValue(data.magnetometerZ);
+ mMagnetometerCalibrationLevelEdit->setValue(data.magnetometerCalibrationLevel);
+ mCompassCalibrationLevelEdit->setValue(data.compassCalibrationLevel);
+ mCompassAzimuthEdit->setValue(data.compassAzimuth);
+ mProximitySensorCloseButton->setChecked(data.proximitySensorClose);
+ mCurrentRadio->setChecked(data.useCurrentTime);
+ mTimeEdit->setDateTime(data.timestamp);
+}
+
+void SensorsUi::emitSensorsDataChange() const
+{
+ emit sensorsDataChanged(sensorsData());
+}
+
+void SensorsUi::initializeAmbientLightOptions()
+{
+ mAmbientLightBox->clear();
+ QStringList lightOptions;
+
+ const QMetaObject &metaObject = SensorsScriptInterface::staticMetaObject;
+ int enumIndex = metaObject.indexOfEnumerator("LightLevel");
+ QMetaEnum metaEnum = metaObject.enumerator(enumIndex);
+ for (int i = 0; i < metaEnum.keyCount(); ++i)
+ lightOptions.append(metaEnum.key(i));
+ mAmbientLightBox->addItems(lightOptions);
+}
+
+void SensorsUi::updateProximityButtonText()
+{
+ mProximitySensorCloseButton->setText(mProximitySensorCloseButton->isChecked() ? tr("Near") : tr("Far"));
+}
+
+void SensorsUi::updateTimeEditDisabled()
+{
+ mTimeEdit->setDisabled(mCurrentRadio->isChecked());
+}
+
+/*!
+ \class SensorsScriptInterface
+ \brief Exposed as sensors.
+*/
+
+SensorsScriptInterface::SensorsScriptInterface(SensorsUi *ui)
+ : QObject(ui)
+ , ui(ui)
+{
+ int enumIndex = metaObject()->indexOfEnumerator("LightLevel");
+ QMetaEnum metaEnum = metaObject()->enumerator(enumIndex);
+ for (int i = 0; i < metaEnum.keyCount(); ++i)
+ setProperty(metaEnum.key(i), metaEnum.value(i));
+}
+
+SensorsScriptInterface::~SensorsScriptInterface()
+{
+}
+
+void SensorsScriptInterface::setAmbientLightLevel(const LightLevel &data)
+{
+ int index = static_cast<int>(data);
+ if (ui->mAmbientLightBox->currentIndex() != index) {
+ ui->mAmbientLightBox->setCurrentIndex(index);
+ ui->emitSensorsDataChange();
+ }
+
+}
+
+SensorsScriptInterface::LightLevel SensorsScriptInterface::ambientLightLevel() const
+{
+ SensorsScriptInterface::LightLevel lightLevel = static_cast<SensorsScriptInterface::LightLevel>(ui->mAmbientLightBox->currentIndex());
+ return lightLevel;
+}
+
+void SensorsScriptInterface::setAccelerometerX(double x)
+{
+ if (ui->mAccelerometerXEdit->value() != x) {
+ ui->mAccelerometerXEdit->setValue(x);
+ ui->emitSensorsDataChange();
+ }
+}
+
+double SensorsScriptInterface::accelerometerX() const
+{
+ return ui->mAccelerometerXEdit->value();
+}
+
+void SensorsScriptInterface::setAccelerometerY(double Y)
+{
+ if (ui->mAccelerometerYEdit->value() != Y) {
+ ui->mAccelerometerYEdit->setValue(Y);
+ ui->emitSensorsDataChange();
+ }
+}
+
+double SensorsScriptInterface::accelerometerY() const
+{
+ return ui->mAccelerometerYEdit->value();
+}
+
+void SensorsScriptInterface::setAccelerometerZ(double Z)
+{
+ if (ui->mAccelerometerZEdit->value() != Z) {
+ ui->mAccelerometerZEdit->setValue(Z);
+ ui->emitSensorsDataChange();
+ }
+}
+
+double SensorsScriptInterface::accelerometerZ() const
+{
+ return ui->mAccelerometerZEdit->value();
+}
+
+void SensorsScriptInterface::setMagnetometerX(double x)
+{
+ if (ui->mMagnetometerXEdit->value() != x) {
+ ui->mMagnetometerXEdit->setValue(x);
+ ui->emitSensorsDataChange();
+ }
+}
+
+double SensorsScriptInterface::magnetometerX() const
+{
+ return ui->mMagnetometerXEdit->value();
+}
+
+void SensorsScriptInterface::setMagnetometerY(double Y)
+{
+ if (ui->mMagnetometerYEdit->value() != Y) {
+ ui->mMagnetometerYEdit->setValue(Y);
+ ui->emitSensorsDataChange();
+ }
+}
+
+double SensorsScriptInterface::magnetometerY() const
+{
+ return ui->mMagnetometerYEdit->value();
+}
+
+void SensorsScriptInterface::setMagnetometerZ(double Z)
+{
+ if (ui->mMagnetometerZEdit->value() != Z) {
+ ui->mMagnetometerZEdit->setValue(Z);
+ ui->emitSensorsDataChange();
+ }
+}
+
+double SensorsScriptInterface::magnetometerZ() const
+{
+ return ui->mMagnetometerZEdit->value();
+}
+
+void SensorsScriptInterface::setMagnetometerCalibrationLevel(double l)
+{
+ if (ui->mMagnetometerCalibrationLevelEdit->value() != l) {
+ ui->mMagnetometerCalibrationLevelEdit->setValue(l);
+ ui->emitSensorsDataChange();
+ }
+}
+
+double SensorsScriptInterface::magnetometerCalibrationLevel() const
+{
+ return ui->mMagnetometerCalibrationLevelEdit->value();
+}
+
+void SensorsScriptInterface::setCompassCalibrationLevel(double l)
+{
+ if (ui->mCompassCalibrationLevelEdit->value() != l) {
+ ui->mCompassCalibrationLevelEdit->setValue(l);
+ ui->emitSensorsDataChange();
+ }
+}
+
+double SensorsScriptInterface::compassCalibrationLevel() const
+{
+ return ui->mCompassCalibrationLevelEdit->value();
+}
+
+void SensorsScriptInterface::setCompassAzimuth(double a)
+{
+ if (ui->mCompassAzimuthEdit->value() != a) {
+ ui->mCompassAzimuthEdit->setValue(a);
+ ui->emitSensorsDataChange();
+ }
+}
+
+double SensorsScriptInterface::compassAzimuth() const
+{
+ return ui->mCompassAzimuthEdit->value();
+}
+
+void SensorsScriptInterface::setProximitySensorClose(bool c)
+{
+ if (ui->mProximitySensorCloseButton->isChecked() != c) {
+ ui->mProximitySensorCloseButton->setChecked(c);
+ ui->emitSensorsDataChange();
+ }
+}
+
+bool SensorsScriptInterface::proximitySensorClose() const
+{
+ return ui->mProximitySensorCloseButton->isChecked();
+}
+
+void SensorsScriptInterface::setUseCurrentTimestamp(bool t)
+{
+ if (ui->mCurrentRadio->isChecked() != t) {
+ ui->mCurrentRadio->setChecked(t);
+ ui->emitSensorsDataChange();
+ }
+}
+
+bool SensorsScriptInterface::useCurrentTimestamp() const
+{
+ return ui->mCurrentRadio->isChecked();
+}
+
+void SensorsScriptInterface::setTimestamp(const QDateTime &t)
+{
+ if (ui->mTimeEdit->dateTime() != t) {
+ ui->mTimeEdit->setDateTime(t);
+ ui->emitSensorsDataChange();
+ }
+}
+
+QDateTime SensorsScriptInterface::timestamp() const
+{
+ return ui->mTimeEdit->dateTime();
+}
diff --git a/src/ui/sensorsui.h b/src/ui/sensorsui.h
new file mode 100644
index 0000000..c3c48c3
--- /dev/null
+++ b/src/ui/sensorsui.h
@@ -0,0 +1,231 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef SENSORSUI_H
+#define SENSORSUI_H
+
+#include <QtCore/QObject>
+#include <QtCore/QDateTime>
+#include <QtGui/QSlider>
+
+#include <remotecontrolwidget/toolbox.h>
+
+class ConfigurationWidget;
+class Sensors;
+class QComboBox;
+class QLineEdit;
+class QDateTimeEdit;
+class QPushButton;
+class QRadioButton;
+class SensorsScriptInterface;
+
+class SensorDoubleEdit: public QWidget
+{
+ Q_OBJECT
+public:
+ SensorDoubleEdit(QWidget *parent = 0);
+
+ double value() const;
+ void setValue(double newValue, bool skipSignal = false);
+
+ void setRange(double min, double max);
+ QPair<double, double> range() const;
+
+ void setDecimalPlaces(int places);
+ int decimalPlaces() const;
+
+private slots:
+ void changeValue(int newValue);
+ void updateValueFromLineEdit();
+
+signals:
+ void valueChanged(double);
+
+private:
+ double mValue;
+ QPair<double, double> mRange;
+ int mDecimalPlaces;
+ int mCorrectionFactor;
+ QSlider *mSlider;
+ QLineEdit *mLineEdit;
+
+ void updateSlider();
+};
+
+class SensorsUi;
+
+class SensorsScriptInterface : public QObject
+{
+ Q_OBJECT
+public:
+ // depends on order of items
+ // has to match QAmbientLightReading::LightLevel
+ enum LightLevel {
+ Undefined,
+ Dark,
+ Twilight,
+ Light,
+ Bright,
+ Sunny
+ };
+ Q_ENUMS(LightLevel);
+
+ SensorsScriptInterface(SensorsUi *ui);
+ virtual ~SensorsScriptInterface();
+
+ Q_PROPERTY(LightLevel ambientLightLevel READ ambientLightLevel WRITE setAmbientLightLevel)
+ Q_PROPERTY(double accelerometerX READ accelerometerX WRITE setAccelerometerX)
+ Q_PROPERTY(double accelerometerY READ accelerometerY WRITE setAccelerometerY)
+ Q_PROPERTY(double accelerometerZ READ accelerometerZ WRITE setAccelerometerZ)
+
+ Q_PROPERTY(double magnetometerX READ magnetometerX WRITE setMagnetometerX)
+ Q_PROPERTY(double magnetometerY READ magnetometerY WRITE setMagnetometerY)
+ Q_PROPERTY(double magnetometerZ READ magnetometerZ WRITE setMagnetometerZ)
+ Q_PROPERTY(double magnetometerCalibrationLevel READ magnetometerCalibrationLevel WRITE setMagnetometerCalibrationLevel)
+
+ Q_PROPERTY(double compassCalibrationLevel READ compassCalibrationLevel WRITE setCompassCalibrationLevel)
+ Q_PROPERTY(double compassAzimuth READ compassAzimuth WRITE setCompassAzimuth)
+
+ Q_PROPERTY(bool proximitySensorClose READ proximitySensorClose WRITE setProximitySensorClose)
+
+ Q_PROPERTY(bool useCurrentTimestamp READ useCurrentTimestamp WRITE setUseCurrentTimestamp)
+ Q_PROPERTY(QDateTime timestamp READ timestamp WRITE setTimestamp)
+
+ void setAmbientLightLevel(const LightLevel &data);
+ LightLevel ambientLightLevel() const;
+
+ void setAccelerometerX(double x);
+ double accelerometerX() const;
+
+ void setAccelerometerY(double y);
+ double accelerometerY() const;
+
+ void setAccelerometerZ(double z);
+ double accelerometerZ() const;
+
+ void setMagnetometerX(double x);
+ double magnetometerX() const;
+
+ void setMagnetometerY(double y);
+ double magnetometerY() const;
+
+ void setMagnetometerZ(double z);
+ double magnetometerZ() const;
+
+ void setMagnetometerCalibrationLevel(double l);
+ double magnetometerCalibrationLevel() const;
+
+ void setCompassCalibrationLevel(double l);
+ double compassCalibrationLevel() const;
+
+ void setCompassAzimuth(double a);
+ double compassAzimuth() const;
+
+ void setProximitySensorClose(bool c);
+ bool proximitySensorClose() const;
+
+ void setUseCurrentTimestamp(bool t);
+ bool useCurrentTimestamp() const;
+
+ void setTimestamp(const QDateTime &t);
+ QDateTime timestamp() const;
+
+private:
+ SensorsUi *ui;
+};
+
+class SensorsUi : public ToolBoxPage
+{
+ Q_OBJECT
+public:
+ struct SensorsData {
+ int ambientLightLevel;
+ double accelerometerX;
+ double accelerometerY;
+ double accelerometerZ;
+ double magnetometerX;
+ double magnetometerY;
+ double magnetometerZ;
+ double magnetometerCalibrationLevel;
+ double compassCalibrationLevel;
+ double compassAzimuth;
+ bool proximitySensorClose;
+ bool useCurrentTime;
+ QDateTime timestamp;
+ };
+
+ explicit SensorsUi(QWidget *parent = 0);
+ virtual ~SensorsUi();
+
+ SensorsScriptInterface *scriptInterface() const;
+
+ SensorsUi::SensorsData sensorsData() const;
+
+public slots:
+ void setSensorsData(const SensorsUi::SensorsData &data);
+ void setDisplayedSensorsData(const SensorsUi::SensorsData &data);
+
+signals:
+ void sensorsDataChanged(const SensorsUi::SensorsData &data) const;
+
+private slots:
+ void emitSensorsDataChange() const;
+ void updateTimeEditDisabled();
+ void updateProximityButtonText();
+
+private:
+ void initializeAmbientLightOptions();
+
+ friend class SensorsScriptInterface;
+ SensorsScriptInterface *mScriptInterface;
+
+ void setTimestamp(const QDateTime &t);
+ QDateTime getTimestamp() const;
+
+ QComboBox *mAmbientLightBox;
+ SensorDoubleEdit *mAccelerometerXEdit;
+ SensorDoubleEdit *mAccelerometerYEdit;
+ SensorDoubleEdit *mAccelerometerZEdit;
+
+ SensorDoubleEdit *mMagnetometerXEdit;
+ SensorDoubleEdit *mMagnetometerYEdit;
+ SensorDoubleEdit *mMagnetometerZEdit;
+ SensorDoubleEdit *mMagnetometerCalibrationLevelEdit;
+
+ SensorDoubleEdit *mCompassCalibrationLevelEdit;
+ SensorDoubleEdit *mCompassAzimuthEdit;
+
+ QPushButton *mProximitySensorCloseButton;
+
+ QRadioButton *mCurrentRadio;
+ QRadioButton *mOverrideRadio;
+ QDateTimeEdit *mTimeEdit;
+};
+
+#endif // SENSORSUI_H
diff --git a/src/ui/style/images/advanced.png b/src/ui/style/images/advanced.png
new file mode 100644
index 0000000..2a894ec
--- /dev/null
+++ b/src/ui/style/images/advanced.png
Binary files differ
diff --git a/src/ui/style/images/advanced_light.png b/src/ui/style/images/advanced_light.png
new file mode 100644
index 0000000..b32829f
--- /dev/null
+++ b/src/ui/style/images/advanced_light.png
Binary files differ
diff --git a/src/ui/style/images/battery_0.png b/src/ui/style/images/battery_0.png
new file mode 100644
index 0000000..eb4d1e8
--- /dev/null
+++ b/src/ui/style/images/battery_0.png
Binary files differ
diff --git a/src/ui/style/images/battery_100.png b/src/ui/style/images/battery_100.png
new file mode 100644
index 0000000..de8c2e9
--- /dev/null
+++ b/src/ui/style/images/battery_100.png
Binary files differ
diff --git a/src/ui/style/images/battery_20.png b/src/ui/style/images/battery_20.png
new file mode 100644
index 0000000..4048b36
--- /dev/null
+++ b/src/ui/style/images/battery_20.png
Binary files differ
diff --git a/src/ui/style/images/battery_40.png b/src/ui/style/images/battery_40.png
new file mode 100644
index 0000000..71e4e09
--- /dev/null
+++ b/src/ui/style/images/battery_40.png
Binary files differ
diff --git a/src/ui/style/images/battery_60.png b/src/ui/style/images/battery_60.png
new file mode 100644
index 0000000..2562a3e
--- /dev/null
+++ b/src/ui/style/images/battery_60.png
Binary files differ
diff --git a/src/ui/style/images/battery_80.png b/src/ui/style/images/battery_80.png
new file mode 100644
index 0000000..6947b1f
--- /dev/null
+++ b/src/ui/style/images/battery_80.png
Binary files differ
diff --git a/src/ui/style/images/batterypower.png b/src/ui/style/images/batterypower.png
new file mode 100644
index 0000000..67d15e4
--- /dev/null
+++ b/src/ui/style/images/batterypower.png
Binary files differ
diff --git a/src/ui/style/images/closebutton.png b/src/ui/style/images/closebutton.png
new file mode 100644
index 0000000..6eea001
--- /dev/null
+++ b/src/ui/style/images/closebutton.png
Binary files differ
diff --git a/src/ui/style/images/connection.png b/src/ui/style/images/connection.png
new file mode 100644
index 0000000..2a0577d
--- /dev/null
+++ b/src/ui/style/images/connection.png
Binary files differ
diff --git a/src/ui/style/images/favoriteScripts.png b/src/ui/style/images/favoriteScripts.png
new file mode 100644
index 0000000..1348354
--- /dev/null
+++ b/src/ui/style/images/favoriteScripts.png
Binary files differ
diff --git a/src/ui/style/images/network.png b/src/ui/style/images/network.png
new file mode 100644
index 0000000..13e7c09
--- /dev/null
+++ b/src/ui/style/images/network.png
Binary files differ
diff --git a/src/ui/style/images/networkstatus.png b/src/ui/style/images/networkstatus.png
new file mode 100644
index 0000000..9173c65
--- /dev/null
+++ b/src/ui/style/images/networkstatus.png
Binary files differ
diff --git a/src/ui/style/images/phone.png b/src/ui/style/images/phone.png
new file mode 100644
index 0000000..0ea8fbb
--- /dev/null
+++ b/src/ui/style/images/phone.png
Binary files differ
diff --git a/src/ui/style/images/reset.png b/src/ui/style/images/reset.png
new file mode 100644
index 0000000..cc0d6a2
--- /dev/null
+++ b/src/ui/style/images/reset.png
Binary files differ
diff --git a/src/ui/style/images/unknownpower.png b/src/ui/style/images/unknownpower.png
new file mode 100644
index 0000000..e09005c
--- /dev/null
+++ b/src/ui/style/images/unknownpower.png
Binary files differ
diff --git a/src/ui/style/images/wall.png b/src/ui/style/images/wall.png
new file mode 100644
index 0000000..3845fc3
--- /dev/null
+++ b/src/ui/style/images/wall.png
Binary files differ
diff --git a/src/ui/style/images/wall_charge.png b/src/ui/style/images/wall_charge.png
new file mode 100644
index 0000000..85caf66
--- /dev/null
+++ b/src/ui/style/images/wall_charge.png
Binary files differ
diff --git a/src/ui/systeminfogenericui.cpp b/src/ui/systeminfogenericui.cpp
new file mode 100644
index 0000000..68cd020
--- /dev/null
+++ b/src/ui/systeminfogenericui.cpp
@@ -0,0 +1,928 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "systeminfogenericui.h"
+
+#include <QtCore/QMetaEnum>
+#include <QtGui/QPushButton>
+#include <QtGui/QBoxLayout>
+#include <QtGui/QLineEdit>
+#include <QtGui/QComboBox>
+#include <QtGui/QCheckBox>
+#include <QtGui/QLabel>
+#include <QtGui/QSpinBox>
+#include <QtGui/QFormLayout>
+#include <QtGui/QGroupBox>
+#include <QtGui/QInputDialog>
+
+GenericSystemInfoUi::GenericSystemInfoUi(QWidget *parent)
+ : ToolBoxPage(parent)
+{
+ mScriptInterface = new GenericSystemInfoScriptInterface(this);
+
+ initializeGeneric();
+
+ // button translators
+ connect(this, SIGNAL(genericDataChanged(GenericSystemInfoUi::GenericData)), SLOT(emitButtonSignalsOnChange()));
+}
+
+void GenericSystemInfoUi::initializeGeneric()
+{
+ QStringList tags;
+ QList<OptionsItem *> optionsList;
+ tags << tr("generic");
+
+ systemInfoBatteryLevel = new QSpinBox();
+ systemInfoBatteryLevel->setRange(0, 100);
+ systemInfoBatteryStatus = new QLabel();
+ systemInfoBatteryStatus->setAlignment(Qt::AlignHCenter);
+ QVBoxLayout *vLayout = new QVBoxLayout();
+ vLayout->setContentsMargins(0, 0, 0, 0);
+ vLayout->addWidget(systemInfoBatteryLevel);
+ vLayout->addWidget(systemInfoBatteryStatus);
+ QWidget *tmp = new QWidget();
+ tmp->setContentsMargins(0, 0, 0, 0);
+ tmp->setLayout(vLayout);
+ connect(systemInfoBatteryLevel, SIGNAL(valueChanged(int)), SLOT(sysinfoUpdateBatteryStatus(int)));
+ connect(systemInfoBatteryLevel, SIGNAL(editingFinished()), SLOT(emitGenericDataChanged()));
+ OptionsItem *item = new OptionsItem(tr("Battery level"), tmp);
+ optionsList << item;
+
+ systemInfoPowerState = new QComboBox();
+ connect(systemInfoPowerState, SIGNAL(activated(int)), SLOT(emitGenericDataChanged()));
+ item = new OptionsItem(tr("Power state"), systemInfoPowerState);
+ optionsList << item;
+
+ systemInfoProfile = new QComboBox();
+ connect(systemInfoProfile, SIGNAL(activated(int)), SLOT(emitGenericDataChanged()));
+ item = new OptionsItem(tr("Profile"), systemInfoProfile);
+ optionsList << item;
+
+ systemInfoDeviceLocked = new QCheckBox();
+ connect(systemInfoDeviceLocked, SIGNAL(clicked()), SLOT(emitGenericDataChanged()));
+ item = new OptionsItem(tr("Device locked"), systemInfoDeviceLocked);
+ optionsList << item;
+
+ systemInfoLanguage = new QLineEdit();
+ systemInfoLanguage->setInputMask("<AA");
+ systemInfoLanguage->setValidator(new QRegExpValidator(QRegExp("\\S\\S"), systemInfoLanguage));
+ connect(systemInfoLanguage, SIGNAL(editingFinished()), SLOT(emitGenericDataChanged()));
+ item = new OptionsItem(tr("Language"), systemInfoLanguage);
+ item->setAdvanced();
+ item->setTags(tags);
+ optionsList << item;
+
+ systemInfoCountryCode = new QLineEdit();
+ systemInfoCountryCode->setInputMask(">AA");
+ systemInfoCountryCode->setValidator(new QRegExpValidator(QRegExp("\\S\\S"), systemInfoCountryCode));
+ connect(systemInfoCountryCode, SIGNAL(editingFinished()), SLOT(emitGenericDataChanged()));
+ item = new OptionsItem(tr("Country code"), systemInfoCountryCode);
+ item->setAdvanced();
+ optionsList << item;
+
+ systemInfoAvailableLanguages = new QComboBox();
+ QPushButton *systemInfoAddAvailableLanguage = new QPushButton(tr("Add"));
+ QPushButton *systemInfoRemoveAvailableLanguage = new QPushButton(tr("Remove"));
+ QHBoxLayout *hLayout = new QHBoxLayout();
+ hLayout->setContentsMargins(0, 0, 0, 0);
+ hLayout->addWidget(systemInfoAvailableLanguages);
+ hLayout->addWidget(systemInfoAddAvailableLanguage);
+ hLayout->addWidget(systemInfoRemoveAvailableLanguage);
+ QGroupBox *systemInfoLanguageGroupBox = new QGroupBox();
+ systemInfoLanguageGroupBox->setLayout(hLayout);
+ QPushButton *toggleLanguagesVisible = new QPushButton(tr("Show"));
+ connect(systemInfoRemoveAvailableLanguage, SIGNAL(clicked()), SLOT(sysinfoRemoveAvailableLanguage()));
+ connect(systemInfoAddAvailableLanguage, SIGNAL(clicked()), SLOT(sysinfoAddAvailableLanguage()));
+ item = new OptionsItem(tr("Available languages"), toggleLanguagesVisible);
+ item->setTags(tags);
+ item->setAdvanced();
+ OptionsItem *advancedItem = new OptionsItem("", systemInfoLanguageGroupBox, true);
+ item->setAdvancedPage(advancedItem);
+ optionsList << item;
+
+ systemInfoFeatures = new QComboBox();
+ systemInfoFeatureEnabled = new QLabel(tr("available"));
+ QPushButton *systemInfoToggleFeature = new QPushButton(tr("Toggle"));
+ hLayout = new QHBoxLayout();
+ hLayout->setContentsMargins(0, 0, 0, 0);
+ hLayout->addWidget(systemInfoFeatures);
+ hLayout->addWidget(systemInfoFeatureEnabled);
+ hLayout->addWidget(systemInfoToggleFeature);
+ QGroupBox *systemInfoFeaturesGroupBox = new QGroupBox();
+ systemInfoFeaturesGroupBox->setLayout(hLayout);
+ QPushButton *toggleFeaturesVisible = new QPushButton(tr("Show"));
+ connect(systemInfoToggleFeature, SIGNAL(clicked()), this, SLOT(sysinfoToggleFeature()));
+ connect(systemInfoFeatures, SIGNAL(activated(int)), this, SLOT(sysinfoDisplayFeature()));
+ item = new OptionsItem(tr("Features"), toggleFeaturesVisible);
+ QStringList featureTags = tags;
+ featureTags << tr("Bluetooth") << tr("Camera") << tr("FM Radio") << tr("Infrared");
+ featureTags << tr("LED") << tr("Memory Card") << tr("USB") << tr("Vibration");
+ featureTags << tr("WLAN") << tr("SIM") << tr("Location") << tr("Video out") << tr("Haptics");
+ item->setTags(featureTags);
+ item->setAdvanced();
+ advancedItem = new OptionsItem("", systemInfoFeaturesGroupBox, true);
+ item->setAdvancedPage(advancedItem);
+ optionsList << item;
+
+ systemInfoVersions = new QComboBox();
+ systemInfoVersionString = new QLabel(tr("version text"));
+ QPushButton *systemInfoChangeVersion = new QPushButton(tr("Change"));
+ hLayout = new QHBoxLayout();
+ hLayout->setContentsMargins(0, 0, 0, 0);
+ hLayout->addWidget(systemInfoVersions);
+ hLayout->addWidget(systemInfoVersionString);
+ hLayout->addWidget(systemInfoChangeVersion);
+ QGroupBox *systemInfoVersionsGroupBox = new QGroupBox();
+ systemInfoVersionsGroupBox->setLayout(hLayout);
+ QPushButton *toggleVersionsVisible = new QPushButton(tr("Show"));
+ connect(systemInfoChangeVersion, SIGNAL(clicked()), SLOT(sysinfoChangeVersion()));
+ connect(systemInfoVersions, SIGNAL(activated(int)), SLOT(sysinfoDisplayVersion()));
+ item = new OptionsItem(tr("Versions"), toggleVersionsVisible);
+ QStringList versionTags = tags;
+ versionTags << "os" << "qt" << "firmware";
+ item->setTags(versionTags);
+ item->setAdvanced();
+ advancedItem = new OptionsItem("", systemInfoVersionsGroupBox, true);
+ item->setAdvancedPage(advancedItem);
+ optionsList << item;
+
+ tags.removeAll(tr("generic"));
+ tags << tr("device");
+
+ systemInfoSimStatus = new QComboBox();
+ connect(systemInfoSimStatus, SIGNAL(activated(int)), SLOT(emitGenericDataChanged()));
+ item = new OptionsItem(tr("SIM Status"), systemInfoSimStatus);
+ item->setTags(tags);
+ item->setAdvanced();
+ optionsList << item;
+
+ systemInfoImei = new QLineEdit();
+ systemInfoImei->setInputMask("99-999999-999999-9");
+ systemInfoImei->setValidator(new QRegExpValidator(QRegExp("\\d{2}-\\d{6}-\\d{6}-\\d"), systemInfoImei));
+ connect(systemInfoImei, SIGNAL(editingFinished()), SLOT(emitGenericDataChanged()));
+ item = new OptionsItem(tr("IMEI"), systemInfoImei);
+ item->setTags(tags);
+ item->setAdvanced();
+ optionsList << item;
+
+ systemInfoImsi = new QLineEdit();
+ systemInfoImsi->setInputMask("999999999999990");
+ systemInfoImsi->setValidator(new QRegExpValidator(QRegExp("\\d{14}[\\d\\s]?"), systemInfoImsi));
+ connect(systemInfoImsi, SIGNAL(editingFinished()), SLOT(emitGenericDataChanged()));
+ item = new OptionsItem(tr("IMSI"), systemInfoImsi);
+ item->setTags(tags);
+ item->setAdvanced();
+ optionsList << item;
+
+ systemInfoInputKeys = new QCheckBox(tr("Keys"));
+ systemInfoInputKeypad = new QCheckBox(tr("Keypad"));
+ systemInfoInputKeyboard = new QCheckBox(tr("Keyboard"));
+ systemInfoInputSingleTouch = new QCheckBox(tr("Single touch"));
+ systemInfoInputMultiTouch = new QCheckBox(tr("Multitouch"));
+ systemInfoInputMouse = new QCheckBox(tr("Mouse"));
+ QGridLayout *gridLayout = new QGridLayout();
+ gridLayout->addWidget(systemInfoInputKeys, 0, 0);
+ gridLayout->addWidget(systemInfoInputKeypad, 0, 1);
+ gridLayout->addWidget(systemInfoInputKeyboard, 0, 2);
+ gridLayout->addWidget(systemInfoInputSingleTouch, 1, 0);
+ gridLayout->addWidget(systemInfoInputMultiTouch, 1, 1);
+ gridLayout->addWidget(systemInfoInputMouse, 1, 2);
+ QGroupBox *systemInfoInputGroupBox = new QGroupBox;
+ systemInfoInputGroupBox->setLayout(gridLayout);
+ QPushButton *toggleInputMethodsVisible = new QPushButton(tr("Show"));
+ connect(systemInfoInputKeys, SIGNAL(clicked()), SLOT(emitGenericDataChanged()));
+ connect(systemInfoInputKeypad, SIGNAL(clicked()), SLOT(emitGenericDataChanged()));
+ connect(systemInfoInputKeyboard, SIGNAL(clicked()), SLOT(emitGenericDataChanged()));
+ connect(systemInfoInputSingleTouch, SIGNAL(clicked()), SLOT(emitGenericDataChanged()));
+ connect(systemInfoInputMultiTouch, SIGNAL(clicked()), SLOT(emitGenericDataChanged()));
+ connect(systemInfoInputMouse, SIGNAL(clicked()), SLOT(emitGenericDataChanged()));
+ item = new OptionsItem(tr("Input methods"), toggleInputMethodsVisible);
+ QStringList inputTags = tags;
+ inputTags << tr("keys") << tr("keypad") << tr("keyboard") << tr("single");
+ inputTags << tr("multi") << tr("touch") << tr("mouse");
+ item->setTags(inputTags);
+ item->setAdvanced();
+ advancedItem = new OptionsItem("", systemInfoInputGroupBox, true);
+ item->setAdvancedPage(advancedItem);
+ optionsList << item;
+
+ systemInfoManufacturer = new QLineEdit();
+ connect(systemInfoManufacturer, SIGNAL(editingFinished()), SLOT(emitGenericDataChanged()));
+ item = new OptionsItem(tr("Manufacturer"), systemInfoManufacturer);
+ item->setTags(tags);
+ item->setAdvanced();
+ optionsList << item;
+
+ systemInfoModel = new QLineEdit();
+ connect(systemInfoModel, SIGNAL(editingFinished()), SLOT(emitGenericDataChanged()));
+ item = new OptionsItem(tr("Model"), systemInfoModel);
+ item->setTags(tags);
+ item->setAdvanced();
+ optionsList << item;
+
+ systemInfoProductName = new QLineEdit();
+ connect(systemInfoProductName, SIGNAL(editingFinished()), SLOT(emitGenericDataChanged()));
+ item = new OptionsItem(tr("Product name"), systemInfoProductName);
+ item->setTags(tags);
+ item->setAdvanced();
+ optionsList << item;
+
+ tags.removeAll(tr("device"));
+ tags << tr("display");
+
+ systemInfoColorDepth = new QSpinBox();
+ systemInfoColorDepth->setRange(8, 32);
+ systemInfoColorDepth->setValue(32);
+ systemInfoColorDepth->setSingleStep(8);
+ connect(systemInfoColorDepth, SIGNAL(editingFinished()), SLOT(emitGenericDataChanged()));
+ item = new OptionsItem(tr("Color depth"), systemInfoColorDepth);
+ item->setTags(tags);
+ item->setAdvanced();
+ optionsList << item;
+
+ systemInfoBrightness = new QSpinBox();
+ systemInfoBrightness->setRange(1, 100);
+ connect(systemInfoBrightness, SIGNAL(editingFinished()), SLOT(emitGenericDataChanged()));
+ item = new OptionsItem(tr("Brightness"), systemInfoBrightness);
+ item->setTags(tags);
+ item->setAdvanced();
+ optionsList << item;
+
+ /* ### TODO: Implement.
+ tags.removeAll(tr("display"));
+ tags << tr("screen") << tr("saver") << tr("screensaver");
+
+ QCheckBox *screenSaverInhibited = new QCheckBox();
+ item = new OptionsItem(tr("Screen saver inhibited"), screenSaverInhibited);
+ item->setTags(tags);
+ item->setAdvanced();
+ optionsList << item;
+ */
+
+ initializeGenericOptions();
+ initializeDeviceOptions();
+
+ setTitle(tr("Generic"));
+ setOptions(optionsList);
+}
+
+GenericSystemInfoUi::~GenericSystemInfoUi()
+{
+}
+
+void GenericSystemInfoUi::initializeGenericOptions()
+{
+ systemInfoVersions->clear();
+ systemInfoVersions->addItem(tr("Operating System"), GenericSystemInfoScriptInterface::Os);
+ systemInfoVersions->addItem(tr("Qt"), GenericSystemInfoScriptInterface::QtCore);
+ systemInfoVersions->addItem(tr("Firmware"), GenericSystemInfoScriptInterface::Firmware);
+ sysinfoDisplayVersion();
+
+ systemInfoFeatures->clear();
+ systemInfoFeatures->addItem(tr("Bluetooth"), GenericSystemInfoScriptInterface::BluetoothFeature);
+ systemInfoFeatures->addItem(tr("Camera"), GenericSystemInfoScriptInterface::CameraFeature);
+ systemInfoFeatures->addItem(tr("FM Radio"), GenericSystemInfoScriptInterface::FmradioFeature);
+ systemInfoFeatures->addItem(tr("Infrared"), GenericSystemInfoScriptInterface::IrFeature);
+ systemInfoFeatures->addItem(tr("LED"), GenericSystemInfoScriptInterface::LedFeature);
+ systemInfoFeatures->addItem(tr("Memory Card"), GenericSystemInfoScriptInterface::MemcardFeature);
+ systemInfoFeatures->addItem(tr("USB"), GenericSystemInfoScriptInterface::UsbFeature);
+ systemInfoFeatures->addItem(tr("Vibration"), GenericSystemInfoScriptInterface::VibFeature);
+ systemInfoFeatures->addItem(tr("WLAN"), GenericSystemInfoScriptInterface::WlanFeature);
+ systemInfoFeatures->addItem(tr("SIM"), GenericSystemInfoScriptInterface::SimFeature);
+ systemInfoFeatures->addItem(tr("Location"), GenericSystemInfoScriptInterface::LocationFeature);
+ systemInfoFeatures->addItem(tr("Video out"), GenericSystemInfoScriptInterface::VideoOutFeature);
+ systemInfoFeatures->addItem(tr("Haptics"), GenericSystemInfoScriptInterface::HapticsFeature);
+ sysinfoDisplayFeature();
+}
+
+void GenericSystemInfoUi::initializeDeviceOptions()
+{
+ systemInfoPowerState->clear();
+ QStringList powerStates;
+ // depends on order of items
+ powerStates.append(tr("Unknown or Error"));
+ powerStates.append(tr("Battery"));
+ powerStates.append(tr("Wall"));
+ powerStates.append(tr("Wall and Charging"));
+ systemInfoPowerState->addItems(powerStates);
+
+ systemInfoProfile->clear();
+ QStringList profiles;
+ // depends on order of items
+ profiles.append(tr("Unknown or Error"));
+ profiles.append(tr("Silent"));
+ profiles.append(tr("Normal"));
+ profiles.append(tr("Loud"));
+ profiles.append(tr("Vibrate"));
+ profiles.append(tr("Offline"));
+ profiles.append(tr("Powersave"));
+ profiles.append(tr("Custom"));
+ systemInfoProfile->addItems(profiles);
+
+ systemInfoSimStatus->clear();
+ QStringList simStates;
+ // depends on order of items
+ simStates.append(tr("Not Available"));
+ simStates.append(tr("Single"));
+ simStates.append(tr("Dual"));
+ simStates.append(tr("Locked"));
+ systemInfoSimStatus->addItems(simStates);
+}
+
+GenericSystemInfoUi::GenericData::GenericData()
+ : features(13)
+ , versions(4)
+{
+}
+
+
+void GenericSystemInfoUi::sysinfoAddAvailableLanguage()
+{
+ QString newLang = QInputDialog::getText(0,
+ "Add New Language", "Enter the new available language:");
+ if (!newLang.isEmpty()) {
+ systemInfoAvailableLanguages->addItem(newLang);
+ emitGenericDataChanged();
+ }
+}
+
+void GenericSystemInfoUi::sysinfoRemoveAvailableLanguage()
+{
+ systemInfoAvailableLanguages->removeItem(systemInfoAvailableLanguages->currentIndex());
+ emitGenericDataChanged();
+}
+
+void GenericSystemInfoUi::sysinfoToggleFeature()
+{
+ GenericSystemInfoScriptInterface::Feature currentFeature
+ = static_cast<GenericSystemInfoScriptInterface::Feature>(systemInfoFeatures->currentIndex());
+ mFeatures[currentFeature] ^= 1;
+ sysinfoDisplayFeature();
+ emitGenericDataChanged();
+}
+
+void GenericSystemInfoUi::sysinfoChangeVersion()
+{
+ GenericSystemInfoScriptInterface::Version v = static_cast<GenericSystemInfoScriptInterface::Version>(systemInfoVersions->itemData(systemInfoVersions->currentIndex()).toInt());
+ QString newVersion = QInputDialog::getText(0,
+ "Change Version", "Enter the new version string:",
+ QLineEdit::Normal, mVersions.value(v));
+ if (!newVersion.isEmpty()) {
+ mVersions[v] = newVersion;
+ sysinfoDisplayVersion();
+ emitGenericDataChanged();
+ }
+}
+
+void GenericSystemInfoUi::sysinfoDisplayVersion()
+{
+ GenericSystemInfoScriptInterface::Version v = static_cast<GenericSystemInfoScriptInterface::Version>(systemInfoVersions->itemData(systemInfoVersions->currentIndex()).toInt());
+ systemInfoVersionString->setText(mVersions.value(v));
+}
+
+void GenericSystemInfoUi::sysinfoDisplayFeature()
+{
+ GenericSystemInfoScriptInterface::Feature f = static_cast<GenericSystemInfoScriptInterface::Feature>(systemInfoFeatures->itemData(systemInfoFeatures->currentIndex()).toInt());
+ if (mFeatures.value(f))
+ systemInfoFeatureEnabled->setText("Available");
+ else
+ systemInfoFeatureEnabled->setText("Not Available");
+}
+
+void GenericSystemInfoUi::sysinfoSetAvailableLanguages(const QStringList &list)
+{
+ systemInfoAvailableLanguages->clear();
+ systemInfoAvailableLanguages->addItems(list);
+ emitGenericDataChanged();
+}
+
+void GenericSystemInfoUi::emitGenericDataChanged()
+{
+ emit genericDataChanged(genericData());
+}
+
+GenericSystemInfoUi::GenericData GenericSystemInfoUi::genericData() const
+{
+ GenericData data;
+ data.currentLanguage = systemInfoLanguage->text();
+ data.availableLanguages.clear();
+ for (int i = 0; i < systemInfoAvailableLanguages->count(); i++)
+ data.availableLanguages.append(systemInfoAvailableLanguages->itemText(i));
+ data.currentCountryCode = systemInfoCountryCode->text();
+ data.displayBrightness = systemInfoBrightness->value();
+ data.colorDepth = systemInfoColorDepth->value();
+ data.profile = static_cast<GenericSystemInfoScriptInterface::Profile>(systemInfoProfile->currentIndex());
+ data.currentPowerState = static_cast<GenericSystemInfoScriptInterface::PowerState>(systemInfoPowerState->currentIndex());
+ data.simStatus = static_cast<GenericSystemInfoScriptInterface::SimStatus>(systemInfoSimStatus->currentIndex());
+ GenericSystemInfoScriptInterface::InputMethodFlags iflags;
+ if (systemInfoInputKeys->isChecked())
+ iflags |= GenericSystemInfoScriptInterface::Keys;
+ if (systemInfoInputKeypad->isChecked())
+ iflags |= GenericSystemInfoScriptInterface::Keypad;
+ if (systemInfoInputKeyboard->isChecked())
+ iflags |= GenericSystemInfoScriptInterface::Keyboard;
+ if (systemInfoInputSingleTouch->isChecked())
+ iflags |= GenericSystemInfoScriptInterface::SingleTouch;
+ if (systemInfoInputMultiTouch->isChecked())
+ iflags |= GenericSystemInfoScriptInterface::MultiTouch;
+ if (systemInfoInputMouse->isChecked())
+ iflags |= GenericSystemInfoScriptInterface::Mouse;
+ data.inputFlags = iflags;
+ data.imei = systemInfoImei->text();
+ data.imsi = systemInfoImsi->text();
+ data.manufacturer = systemInfoManufacturer->text();
+ data.model = systemInfoModel->text();
+ data.productName = systemInfoProductName->text();
+ data.deviceLocked = systemInfoDeviceLocked->isChecked();
+ data.batteryLevel = systemInfoBatteryLevel->value();
+ data.features = mFeatures;
+ data.versions = mVersions;
+ return data;
+}
+
+GenericSystemInfoScriptInterface *GenericSystemInfoUi::scriptInterface()
+{
+ return mScriptInterface;
+}
+
+void GenericSystemInfoUi::sysinfoUpdateBatteryStatus(int level)
+{
+ // batteryButton->updateIcon(level);
+ if (level > 100)
+ systemInfoBatteryStatus->setText("No battery level");
+ else if (level > 40)
+ systemInfoBatteryStatus->setText("Battery normal");
+ else if (level > 10)
+ systemInfoBatteryStatus->setText("Battery low");
+ else if (level > 3)
+ systemInfoBatteryStatus->setText("Battery very low");
+ else if (level >= 0)
+ systemInfoBatteryStatus->setText("Battery critical");
+ else // negative
+ systemInfoBatteryStatus->setText("No battery level");
+}
+
+void GenericSystemInfoUi::setGenericData(const GenericSystemInfoUi::GenericData &data)
+{
+ setDisplayedGenericData(data);
+ emit genericDataChanged(data);
+}
+
+void GenericSystemInfoUi::setDisplayedGenericData(const GenericSystemInfoUi::GenericData &data)
+{
+ systemInfoAvailableLanguages->clear();
+ foreach (const QString &language, data.availableLanguages)
+ systemInfoAvailableLanguages->addItem(language);
+ systemInfoBatteryLevel->setValue(data.batteryLevel);
+ systemInfoBrightness->setValue(data.displayBrightness);
+ systemInfoColorDepth->setValue(data.colorDepth);
+ systemInfoCountryCode->setText(data.currentCountryCode);
+ systemInfoDeviceLocked->setChecked(data.deviceLocked);
+ mFeatures = data.features;
+ mScriptInterface->setInputMethod(data.inputFlags);
+ systemInfoImei->setText(data.imei);
+ systemInfoImsi->setText(data.imsi);
+ systemInfoManufacturer->setText(data.manufacturer);
+ systemInfoModel->setText(data.model);
+ systemInfoPowerState->setCurrentIndex(static_cast<int>(data.currentPowerState));
+ systemInfoLanguage->setText(data.currentLanguage);
+ systemInfoProductName->setText(data.productName);
+ systemInfoProfile->setCurrentIndex(static_cast<int>(data.profile));
+ systemInfoSimStatus->setCurrentIndex(static_cast<int>(data.simStatus));
+ mVersions = data.versions;
+}
+
+void GenericSystemInfoUi::setCurrentPowerState(PowerButton::PowerState powerState)
+{
+ mScriptInterface->setCurrentPowerState(static_cast<GenericSystemInfoScriptInterface::PowerState>(powerState));
+}
+
+void GenericSystemInfoUi::setCurrentBatteryLevel(BatteryButton::BatteryLevel batteryLevel)
+{
+ switch (batteryLevel) {
+ case BatteryButton::BatteryCritical:
+ mScriptInterface->setBatteryLevel(3);
+ break;
+ case BatteryButton::BatteryVeryLow:
+ mScriptInterface->setBatteryLevel(10);
+ break;
+ case BatteryButton::BatteryLow:
+ mScriptInterface->setBatteryLevel(40);
+ break;
+ case BatteryButton::BatteryNormal:
+ mScriptInterface->setBatteryLevel(100);
+ break;
+ default:
+ mScriptInterface->setBatteryLevel(0);
+ break;
+ }
+}
+
+void GenericSystemInfoUi::emitButtonSignalsOnChange()
+{
+ GenericSystemInfoScriptInterface::PowerState currentState = mScriptInterface->currentPowerState();
+ emit currentPowerStateChanged(static_cast<PowerButton::PowerState>(currentState));
+
+ int currentLevel = mScriptInterface->batteryLevel();
+ if (currentLevel <= 3)
+ emit currentBatteryLevelChanged(BatteryButton::BatteryCritical);
+ else if (currentLevel <= 10)
+ emit currentBatteryLevelChanged(BatteryButton::BatteryVeryLow);
+ else if (currentLevel <= 40)
+ emit currentBatteryLevelChanged(BatteryButton::BatteryLow);
+ else
+ emit currentBatteryLevelChanged(BatteryButton::BatteryNormal);
+}
+
+
+/*!
+ \class GenericSystemInfoScriptInterface
+ \brief Exposed as sysinfo.generic.
+*/
+
+GenericSystemInfoScriptInterface::GenericSystemInfoScriptInterface(GenericSystemInfoUi *ui)
+ : QObject(ui)
+ , ui(ui)
+{
+ int enumIndex = metaObject()->indexOfEnumerator("Version");
+ QMetaEnum metaEnum = metaObject()->enumerator(enumIndex);
+ for (int i = 0; i < metaEnum.keyCount(); ++i)
+ setProperty(metaEnum.key(i), metaEnum.value(i));
+
+ enumIndex = metaObject()->indexOfEnumerator("Feature");
+ metaEnum = metaObject()->enumerator(enumIndex);
+ for (int i = 0; i < metaEnum.keyCount(); ++i)
+ setProperty(metaEnum.key(i), metaEnum.value(i));
+
+ enumIndex = metaObject()->indexOfEnumerator("BatteryStatus");
+ metaEnum = metaObject()->enumerator(enumIndex);
+ for (int i = 0; i < metaEnum.keyCount(); ++i)
+ setProperty(metaEnum.key(i), metaEnum.value(i));
+
+ enumIndex = metaObject()->indexOfEnumerator("PowerState");
+ metaEnum = metaObject()->enumerator(enumIndex);
+ for (int i = 0; i < metaEnum.keyCount(); ++i)
+ setProperty(metaEnum.key(i), metaEnum.value(i));
+
+ enumIndex = metaObject()->indexOfEnumerator("InputMethod");
+ metaEnum = metaObject()->enumerator(enumIndex);
+ for (int i = 0; i < metaEnum.keyCount(); ++i)
+ setProperty(metaEnum.key(i), metaEnum.value(i));
+
+ enumIndex = metaObject()->indexOfEnumerator("Profile");
+ metaEnum = metaObject()->enumerator(enumIndex);
+ for (int i = 0; i < metaEnum.keyCount(); ++i)
+ setProperty(metaEnum.key(i), metaEnum.value(i));
+
+ enumIndex = metaObject()->indexOfEnumerator("SimStatus");
+ metaEnum = metaObject()->enumerator(enumIndex);
+ for (int i = 0; i < metaEnum.keyCount(); ++i)
+ setProperty(metaEnum.key(i), metaEnum.value(i));
+}
+
+GenericSystemInfoScriptInterface::~GenericSystemInfoScriptInterface()
+{
+}
+
+QString GenericSystemInfoScriptInterface::currentLanguage() const
+{
+ return ui->systemInfoLanguage->text();
+}
+
+QStringList GenericSystemInfoScriptInterface::availableLanguages() const
+{
+ QStringList returnList;
+ for (int i = 0; i < ui->systemInfoAvailableLanguages->count(); i++)
+ returnList.append(ui->systemInfoAvailableLanguages->itemText(i));
+ return returnList;
+}
+
+QString GenericSystemInfoScriptInterface::currentCountryCode() const
+{
+ return ui->systemInfoCountryCode->text();
+}
+
+bool GenericSystemInfoScriptInterface::hasFeature(GenericSystemInfoScriptInterface::Feature f) const
+{
+ return (ui->mFeatures.contains(f) && ui->mFeatures.value(f));
+}
+
+QString GenericSystemInfoScriptInterface::version(GenericSystemInfoScriptInterface::Version v, const QString &param) const
+{
+ Q_UNUSED(param);
+ return ui->mVersions[v];
+}
+
+int GenericSystemInfoScriptInterface::displayBrightness(int screen) const
+{
+ Q_UNUSED(screen);
+ return ui->systemInfoBrightness->text().toInt();
+}
+
+int GenericSystemInfoScriptInterface::colorDepth(int screen) const
+{
+ Q_UNUSED(screen);
+ return ui->systemInfoColorDepth->text().toInt();
+}
+
+GenericSystemInfoScriptInterface::Profile GenericSystemInfoScriptInterface::currentProfile() const
+{
+ return static_cast<GenericSystemInfoScriptInterface::Profile>(ui->systemInfoProfile->currentIndex());
+}
+
+GenericSystemInfoScriptInterface::PowerState GenericSystemInfoScriptInterface::currentPowerState() const
+{
+ return static_cast<GenericSystemInfoScriptInterface::PowerState>(ui->systemInfoPowerState->currentIndex());
+}
+
+GenericSystemInfoScriptInterface::SimStatus GenericSystemInfoScriptInterface::simStatus() const
+{
+ return static_cast<GenericSystemInfoScriptInterface::SimStatus>(ui->systemInfoSimStatus->currentIndex());
+}
+
+GenericSystemInfoScriptInterface::InputMethodFlags GenericSystemInfoScriptInterface::inputMethod() const
+{
+ GenericSystemInfoScriptInterface::InputMethodFlags flags;
+ if (ui->systemInfoInputKeys->isChecked())
+ flags |= GenericSystemInfoScriptInterface::Keys;
+ if (ui->systemInfoInputKeypad->isChecked())
+ flags |= GenericSystemInfoScriptInterface::Keypad;
+ if (ui->systemInfoInputKeyboard->isChecked())
+ flags |= GenericSystemInfoScriptInterface::Keyboard;
+ if (ui->systemInfoInputSingleTouch->isChecked())
+ flags |= GenericSystemInfoScriptInterface::SingleTouch;
+ if (ui->systemInfoInputMultiTouch->isChecked())
+ flags |= GenericSystemInfoScriptInterface::MultiTouch;
+ if (ui->systemInfoInputMouse->isChecked())
+ flags |= GenericSystemInfoScriptInterface::Mouse;
+ return flags;
+}
+
+QString GenericSystemInfoScriptInterface::imei() const
+{
+ return ui->systemInfoImei->text();
+}
+
+QString GenericSystemInfoScriptInterface::imsi() const
+{
+ return ui->systemInfoImsi->text();
+}
+
+QString GenericSystemInfoScriptInterface::manufacturer() const
+{
+ return ui->systemInfoManufacturer->text();
+}
+
+QString GenericSystemInfoScriptInterface::model() const
+{
+ return ui->systemInfoModel->text();
+}
+
+QString GenericSystemInfoScriptInterface::productName() const
+{
+ return ui->systemInfoProductName->text();
+}
+
+int GenericSystemInfoScriptInterface::batteryLevel() const
+{
+ return ui->systemInfoBatteryLevel->value();
+}
+
+bool GenericSystemInfoScriptInterface::isDeviceLocked() const
+{
+ return (ui->systemInfoDeviceLocked->isChecked());
+}
+
+GenericSystemInfoScriptInterface::BatteryStatus GenericSystemInfoScriptInterface::batteryStatus() const
+{
+ if (ui->systemInfoBatteryLevel->value() < 0)
+ return GenericSystemInfoScriptInterface::NoBatteryLevel;
+ else if (ui->systemInfoBatteryLevel->value() <= 3)
+ return GenericSystemInfoScriptInterface::BatteryCritical;
+ else if (ui->systemInfoBatteryLevel->value() <= 10)
+ return GenericSystemInfoScriptInterface::BatteryVeryLow;
+ else if (ui->systemInfoBatteryLevel->value() <= 40)
+ return GenericSystemInfoScriptInterface::BatteryLow;
+ else if (ui->systemInfoBatteryLevel->value() <= 100)
+ return GenericSystemInfoScriptInterface::BatteryNormal;
+ else
+ return GenericSystemInfoScriptInterface::NoBatteryLevel;
+}
+
+void GenericSystemInfoScriptInterface::setCurrentLanguage(const QString &v)
+{
+ if (ui->systemInfoLanguage->text() != v) {
+ ui->systemInfoLanguage->setText(v);
+ ui->emitGenericDataChanged();
+ }
+}
+
+void GenericSystemInfoScriptInterface::setCurrentCountryCode(const QString &v)
+{
+ if (ui->systemInfoCountryCode->text() != v) {
+ ui->systemInfoCountryCode->setText(v);
+ ui->emitGenericDataChanged();
+ }
+}
+
+void GenericSystemInfoScriptInterface::setAvailableLanguages(const QStringList &v)
+{
+ ui->systemInfoAvailableLanguages->clear();
+ foreach(const QString &language, v)
+ ui->systemInfoAvailableLanguages->addItem(language);
+ ui->emitGenericDataChanged();
+}
+
+void GenericSystemInfoScriptInterface::addAvailableLanguage(const QString &v)
+{
+ ui->systemInfoAvailableLanguages->addItem(v);
+ ui->emitGenericDataChanged();
+}
+
+bool GenericSystemInfoScriptInterface::removeAvailableLanguage(const QString &v)
+{
+ bool retValue = false;
+ for (int i = 0; i < ui->systemInfoAvailableLanguages->count(); i++) {
+ if (ui->systemInfoAvailableLanguages->itemText(i) == v) {
+ ui->systemInfoAvailableLanguages->removeItem(i);
+ i--;
+ retValue = true;
+ }
+ }
+ if (retValue)
+ ui->emitGenericDataChanged();
+ return retValue;
+}
+
+void GenericSystemInfoScriptInterface::removeAllAvailableLanguages()
+{
+ ui->systemInfoAvailableLanguages->clear();
+ ui->emitGenericDataChanged();
+}
+
+void GenericSystemInfoScriptInterface::setFeature(GenericSystemInfoScriptInterface::Feature f, bool enabled)
+{
+ ui->mFeatures[f] = enabled;
+ ui->sysinfoDisplayFeature();
+ ui->emitGenericDataChanged();
+}
+
+void GenericSystemInfoScriptInterface::setVersion(GenericSystemInfoScriptInterface::Version v, const QString &to)
+{
+ ui->mVersions[v] = to;
+ ui->sysinfoDisplayVersion();
+ ui->emitGenericDataChanged();
+}
+
+void GenericSystemInfoScriptInterface::setDisplayBrightness(int brightness)
+{
+ if (ui->systemInfoBrightness->value() != brightness) {
+ ui->systemInfoBrightness->setValue(brightness);
+ ui->emitGenericDataChanged();
+ }
+}
+
+void GenericSystemInfoScriptInterface::setColorDepth(int depth)
+{
+ if (ui->systemInfoColorDepth->value() != depth) {
+ ui->systemInfoColorDepth->setValue(depth);
+ ui->emitGenericDataChanged();
+ }
+}
+
+void GenericSystemInfoScriptInterface::setCurrentProfile(GenericSystemInfoScriptInterface::Profile v)
+{
+ int index = static_cast<int>(v);
+ if (ui->systemInfoProfile->currentIndex() != index) {
+ ui->systemInfoProfile->setCurrentIndex(index);
+ ui->emitGenericDataChanged();
+ }
+}
+
+void GenericSystemInfoScriptInterface::setCurrentPowerState(GenericSystemInfoScriptInterface::PowerState v)
+{
+ int index = static_cast<int>(v);
+ if (ui->systemInfoPowerState->currentIndex() != index) {
+ ui->systemInfoPowerState->setCurrentIndex(index);
+ ui->emitGenericDataChanged();
+ }
+}
+
+void GenericSystemInfoScriptInterface::setSimStatus(GenericSystemInfoScriptInterface::SimStatus v)
+{
+ int index = static_cast<int>(v);
+ if (ui->systemInfoSimStatus->currentIndex() != index) {
+ ui->systemInfoSimStatus->setCurrentIndex(index);
+ ui->emitGenericDataChanged();
+ }
+}
+
+void GenericSystemInfoScriptInterface::setInputMethod(GenericSystemInfoScriptInterface::InputMethodFlags v)
+{
+ if (v & GenericSystemInfoScriptInterface::Keys)
+ ui->systemInfoInputKeys->setChecked(true);
+ else
+ ui->systemInfoInputKeys->setChecked(false);
+ if (v & GenericSystemInfoScriptInterface::Keypad)
+ ui->systemInfoInputKeypad->setChecked(true);
+ else
+ ui->systemInfoInputKeypad->setChecked(false);
+ if (v & GenericSystemInfoScriptInterface::Keyboard)
+ ui->systemInfoInputKeyboard->setChecked(true);
+ else
+ ui->systemInfoInputKeyboard->setChecked(false);
+ if (v & GenericSystemInfoScriptInterface::SingleTouch)
+ ui->systemInfoInputSingleTouch->setChecked(true);
+ else
+ ui->systemInfoInputSingleTouch->setChecked(false);
+ if (v & GenericSystemInfoScriptInterface::MultiTouch)
+ ui->systemInfoInputMultiTouch->setChecked(true);
+ else
+ ui->systemInfoInputMultiTouch->setChecked(false);
+ if (v & GenericSystemInfoScriptInterface::Mouse)
+ ui->systemInfoInputMouse->setChecked(true);
+ else
+ ui->systemInfoInputMouse->setChecked(false);
+}
+
+void GenericSystemInfoScriptInterface::setImei(const QString &v)
+{
+ if (ui->systemInfoImei->text() != v) {
+ ui->systemInfoImei->setText(v);
+ ui->emitGenericDataChanged();
+ }
+}
+
+void GenericSystemInfoScriptInterface::setImsi(const QString &v)
+{
+ if (ui->systemInfoImsi->text() != v) {
+ ui->systemInfoImsi->setText(v);
+ ui->emitGenericDataChanged();
+ }
+}
+
+void GenericSystemInfoScriptInterface::setManufacturer(const QString &v)
+{
+ if (ui->systemInfoManufacturer->text() != v) {
+ ui->systemInfoManufacturer->setText(v);
+ ui->emitGenericDataChanged();
+ }
+}
+
+void GenericSystemInfoScriptInterface::setModel(const QString &v)
+{
+ if (ui->systemInfoModel->text() != v) {
+ ui->systemInfoModel->setText(v);
+ ui->emitGenericDataChanged();
+ }
+}
+
+void GenericSystemInfoScriptInterface::setProductName(const QString &v)
+{
+ if (ui->systemInfoProductName->text() != v) {
+ ui->systemInfoProductName->setText(v);
+ ui->emitGenericDataChanged();
+ }
+}
+
+void GenericSystemInfoScriptInterface::setBatteryLevel(int v)
+{
+ if (ui->systemInfoBatteryLevel->value() != v) {
+ ui->systemInfoBatteryLevel->setValue(v);
+ ui->emitGenericDataChanged();
+ }
+}
+
+void GenericSystemInfoScriptInterface::setDeviceLocked(bool v)
+{
+ if (ui->systemInfoDeviceLocked->isChecked() != v) {
+ ui->systemInfoDeviceLocked->setChecked(v);
+ ui->emitGenericDataChanged();
+ }
+}
diff --git a/src/ui/systeminfogenericui.h b/src/ui/systeminfogenericui.h
new file mode 100644
index 0000000..30013dc
--- /dev/null
+++ b/src/ui/systeminfogenericui.h
@@ -0,0 +1,310 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef SYSINFOGENERICUI_H
+#define SYSINFOGENERICUI_H
+
+#include <remotecontrolwidget/toolbox.h>
+#include <remotecontrolwidget/batterybutton.h>
+#include <remotecontrolwidget/powerbutton.h>
+
+#include <QtCore/QObject>
+#include <QtCore/QHash>
+
+class BatteryButton;
+class PowerButton;
+class QLineEdit;
+class QComboBox;
+class QLabel;
+class QSpinBox;
+class QCheckBox;
+
+class GenericSystemInfoUi;
+
+class GenericSystemInfoScriptInterface : public QObject
+{
+ Q_OBJECT
+public:
+ //must mimic QSystem::Version
+ enum Version {
+ Os = 1,
+ QtCore,
+ Firmware
+ };
+ Q_ENUMS(Version)
+
+ //must mimic QSystem::Feature
+ enum Feature {
+ BluetoothFeature=0,
+ CameraFeature,
+ FmradioFeature,
+ IrFeature,
+ LedFeature,
+ MemcardFeature,
+ UsbFeature,
+ VibFeature,
+ WlanFeature,
+ SimFeature,
+ LocationFeature,
+ VideoOutFeature,
+ HapticsFeature
+ };
+ Q_ENUMS(Feature)
+
+ //must mimic QSystemDeviceInfo::BatteryStatus
+ enum BatteryStatus {
+ NoBatteryLevel = 0,
+ BatteryCritical,
+ BatteryVeryLow,
+ BatteryLow,
+ BatteryNormal
+ };
+ Q_ENUMS(BatteryStatus)
+
+ //must mimic QSystemDeviceInfo::PowerState
+ enum PowerState {
+ UnknownPower = 0,
+ BatteryPower,
+ WallPower,
+ WallPowerChargingBattery
+ };
+ Q_ENUMS(PowerState)
+
+ //must mimic QSystemDeviceInfo::InputMethod
+ enum InputMethod {
+ Keys = 0x0000001,
+ Keypad = 0x0000002,
+ Keyboard = 0x0000004,
+ SingleTouch = 0x0000008,
+ MultiTouch = 0x0000010,
+ Mouse = 0x0000020
+ };
+ Q_DECLARE_FLAGS(InputMethodFlags, InputMethod)
+ Q_ENUMS(InputMethod)
+ Q_FLAGS(InputMethodFlags)
+
+ //must mimic QSystemDeviceInfo::Profile
+ enum Profile {
+ UnknownProfile = 0,
+ SilentProfile,
+ NormalProfile,
+ LoudProfile,
+ VibProfile,
+ OfflineProfile,
+ PowersaveProfile,
+ CustomProfile
+ };
+ Q_ENUMS(Profile)
+
+ //must mimic QSystemDeviceInfo::SimStatus
+ enum SimStatus {
+ SimNotAvailable = 0,
+ SingleSimAvailable,
+ DualSimAvailable,
+ SimLocked
+ };
+ Q_ENUMS(SimStatus)
+
+ explicit GenericSystemInfoScriptInterface(GenericSystemInfoUi *ui);
+ ~GenericSystemInfoScriptInterface();
+
+ QString currentLanguage() const;
+ QStringList availableLanguages() const;
+ QString currentCountryCode() const;
+ Q_INVOKABLE bool hasFeature(GenericSystemInfoScriptInterface::Feature f) const;
+ Q_INVOKABLE QString version(GenericSystemInfoScriptInterface::Version v, const QString &param = "") const;
+ int displayBrightness(int screen = 0) const;
+ int colorDepth(int screen = 0) const;
+ GenericSystemInfoScriptInterface::Profile currentProfile() const;
+ GenericSystemInfoScriptInterface::PowerState currentPowerState() const;
+ GenericSystemInfoScriptInterface::SimStatus simStatus() const;
+ GenericSystemInfoScriptInterface::InputMethodFlags inputMethod() const;
+ QString imei() const;
+ QString imsi() const;
+ QString manufacturer() const;
+ QString model() const;
+ QString productName() const;
+ int batteryLevel() const;
+ bool isDeviceLocked() const;
+ Q_INVOKABLE GenericSystemInfoScriptInterface::BatteryStatus batteryStatus() const;
+
+ Q_PROPERTY(QString currentLanguage READ currentLanguage WRITE setCurrentLanguage)
+ Q_PROPERTY(QStringList availableLanguages READ availableLanguages WRITE setAvailableLanguages)
+ Q_PROPERTY(QString currentCountryCode READ currentCountryCode WRITE setCurrentCountryCode)
+ Q_PROPERTY(int displayBrightness READ displayBrightness WRITE setDisplayBrightness)
+ Q_PROPERTY(int colorDepth READ colorDepth WRITE setColorDepth)
+ Q_PROPERTY(Profile currentProfile READ currentProfile WRITE setCurrentProfile)
+ Q_PROPERTY(PowerState currentPowerState READ currentPowerState WRITE setCurrentPowerState)
+ Q_PROPERTY(SimStatus simStatus READ simStatus WRITE setSimStatus)
+ Q_PROPERTY(InputMethodFlags inputMethod READ inputMethod WRITE setInputMethod)
+ Q_PROPERTY(QString imei READ imei WRITE setImei)
+ Q_PROPERTY(QString imsi READ imsi WRITE setImsi)
+ Q_PROPERTY(QString manufacturer READ manufacturer WRITE setManufacturer)
+ Q_PROPERTY(QString model READ model WRITE setModel)
+ Q_PROPERTY(QString productName READ productName WRITE setProductName)
+ Q_PROPERTY(int batteryLevel READ batteryLevel WRITE setBatteryLevel)
+ Q_PROPERTY(bool deviceLocked READ isDeviceLocked WRITE setDeviceLocked)
+
+public slots:
+ void setCurrentLanguage(const QString &v);
+ void setCurrentCountryCode(const QString &v);
+ void setAvailableLanguages(const QStringList &v);
+ void addAvailableLanguage(const QString &v);
+ bool removeAvailableLanguage(const QString &v);
+ void removeAllAvailableLanguages();
+ void setFeature(GenericSystemInfoScriptInterface::Feature f, bool enabled);
+ void setVersion(GenericSystemInfoScriptInterface::Version v, const QString &to);
+ void setDisplayBrightness(int brightness);
+ void setColorDepth(int depth);
+ void setCurrentProfile(GenericSystemInfoScriptInterface::Profile v);
+ void setCurrentPowerState(GenericSystemInfoScriptInterface::PowerState v);
+ void setSimStatus(GenericSystemInfoScriptInterface::SimStatus v);
+ void setInputMethod(GenericSystemInfoScriptInterface::InputMethodFlags v);
+ void setImei(const QString &v);
+ void setImsi(const QString &v);
+ void setManufacturer(const QString &v);
+ void setModel(const QString &v);
+ void setProductName(const QString &v);
+ void setBatteryLevel(int v);
+ void setDeviceLocked(bool v);
+
+private:
+ GenericSystemInfoUi *ui;
+};
+
+class GenericSystemInfoUi : public ToolBoxPage
+{
+ Q_OBJECT
+public:
+ struct GenericData {
+ GenericData();
+
+ QString currentLanguage;
+ QStringList availableLanguages;
+ QString currentCountryCode;
+ int displayBrightness;
+ int colorDepth;
+ GenericSystemInfoScriptInterface::Profile profile;
+ GenericSystemInfoScriptInterface::PowerState currentPowerState;
+ GenericSystemInfoScriptInterface::SimStatus simStatus;
+ GenericSystemInfoScriptInterface::InputMethodFlags inputFlags;
+ QString imei;
+ QString imsi;
+ QString manufacturer;
+ QString model;
+ QString productName;
+ int batteryLevel;
+ bool deviceLocked;
+
+ QVector<bool> features;
+ QVector<QString> versions;
+ };
+ explicit GenericSystemInfoUi(QWidget *parent = 0);
+ virtual ~GenericSystemInfoUi();
+
+ GenericSystemInfoScriptInterface *scriptInterface();
+
+ GenericData genericData() const;
+
+public slots:
+ void setGenericData(const GenericSystemInfoUi::GenericData &data);
+ void setDisplayedGenericData(const GenericSystemInfoUi::GenericData &data);
+
+signals:
+ void genericDataChanged(const GenericSystemInfoUi::GenericData &data) const;
+
+ // since the quick access button enums differ from the enums here,
+ // we need these translator slots/signals
+public slots:
+ void setCurrentBatteryLevel(BatteryButton::BatteryLevel);
+ void setCurrentPowerState(PowerButton::PowerState);
+signals:
+ void currentBatteryLevelChanged(BatteryButton::BatteryLevel) const;
+ void currentPowerStateChanged(PowerButton::PowerState) const;
+private slots:
+ void emitButtonSignalsOnChange();
+
+private slots:
+ void emitGenericDataChanged();
+
+private slots:
+ void sysinfoAddAvailableLanguage();
+ void sysinfoRemoveAvailableLanguage();
+ void sysinfoToggleFeature();
+ void sysinfoChangeVersion();
+ void sysinfoDisplayVersion();
+ void sysinfoDisplayFeature();
+ void sysinfoSetAvailableLanguages(const QStringList &list);
+
+ void sysinfoUpdateBatteryStatus(int level);
+
+private:
+ void initializeGeneric();
+
+ void initializeGenericOptions();
+ void initializeDeviceOptions();
+
+
+private:
+ GenericData data;
+ QLineEdit *systemInfoLanguage;
+ QLineEdit *systemInfoCountryCode;
+ QComboBox *systemInfoAvailableLanguages;
+ QComboBox *systemInfoFeatures;
+ QLabel *systemInfoFeatureEnabled;
+ QComboBox *systemInfoVersions;
+ QLabel *systemInfoVersionString;
+ QSpinBox *systemInfoBatteryLevel;
+ QLabel *systemInfoBatteryStatus;
+ QComboBox *systemInfoPowerState;
+ QComboBox *systemInfoProfile;
+ QComboBox *systemInfoSimStatus;
+ QLineEdit *systemInfoImei;
+ QLineEdit *systemInfoImsi;
+ QCheckBox *systemInfoInputKeys;
+ QCheckBox *systemInfoInputKeypad;
+ QCheckBox *systemInfoInputKeyboard;
+ QCheckBox *systemInfoInputSingleTouch;
+ QCheckBox *systemInfoInputMultiTouch;
+ QCheckBox *systemInfoInputMouse;
+ QCheckBox *systemInfoDeviceLocked;
+ QLineEdit *systemInfoManufacturer;
+ QLineEdit *systemInfoModel;
+ QLineEdit *systemInfoProductName;
+ QSpinBox *systemInfoColorDepth;
+ QSpinBox *systemInfoBrightness;
+
+ QVector<bool> mFeatures;
+ QVector<QString> mVersions;
+
+ GenericSystemInfoScriptInterface *mScriptInterface;
+ friend class GenericSystemInfoScriptInterface;
+};
+
+#endif // SYSINFOGENERICUI_H
diff --git a/src/ui/systeminfonetworkui.cpp b/src/ui/systeminfonetworkui.cpp
new file mode 100644
index 0000000..d83d4a9
--- /dev/null
+++ b/src/ui/systeminfonetworkui.cpp
@@ -0,0 +1,482 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "systeminfonetworkui.h"
+
+#include <QtCore/QMetaEnum>
+#include <QtGui/QPushButton>
+#include <QtGui/QBoxLayout>
+#include <QtGui/QLineEdit>
+#include <QtGui/QComboBox>
+#include <QtGui/QCheckBox>
+#include <QtGui/QLabel>
+#include <QtGui/QSpinBox>
+#include <QtGui/QFormLayout>
+#include <QtGui/QGroupBox>
+#include <QtGui/QInputDialog>
+
+void NetworkSystemInfoUi::initializeNetwork()
+{
+ QStringList tags;
+ QList<OptionsItem *> optionsList;
+
+ networkCellId = new QSpinBox();
+ networkCellId->setRange(0, 999999999);
+ connect(networkCellId, SIGNAL(editingFinished()), this, SLOT(emitNetworkDataChange()));
+ OptionsItem *item = new OptionsItem(tr("Cell ID"), networkCellId);
+ item->setTags(tags);
+ optionsList << item;
+
+ networkLocationAreaCode = new QSpinBox();
+ networkLocationAreaCode->setRange(0, 999999999);
+ connect(networkLocationAreaCode, SIGNAL(editingFinished()), this, SLOT(emitNetworkDataChange()));
+ item = new OptionsItem(tr("Location area code"), networkLocationAreaCode);
+ item->setTags(tags);
+ optionsList << item;
+
+ networkMobileCountryCode = new QLineEdit();
+ networkMobileCountryCode->setInputMask("999");
+ networkMobileCountryCode->setValidator(new QRegExpValidator(QRegExp("\\d{3}"), networkMobileCountryCode));
+ item = new OptionsItem(tr("Mobile country code"), networkMobileCountryCode);
+ connect(networkMobileCountryCode, SIGNAL(editingFinished()), this, SLOT(emitNetworkDataChange()));
+ item->setTags(tags);
+ optionsList << item;
+
+ networkMobileNetworkCode = new QLineEdit();
+ QRegExp rx("\\d*");
+ networkMobileNetworkCode->setValidator(new QRegExpValidator(rx, 0));
+
+ connect(networkMobileNetworkCode, SIGNAL(editingFinished()), this, SLOT(emitNetworkDataChange()));
+ item = new OptionsItem(tr("Mobile network code"), networkMobileNetworkCode);
+ item->setTags(tags);
+ optionsList << item;
+
+ networkHomeCountryCode = new QLineEdit();
+ networkHomeCountryCode->setInputMask("+990");
+ networkHomeCountryCode->setValidator(new QRegExpValidator(QRegExp("\\+\\d\\d[\\d\\s]?"), networkHomeCountryCode));
+ connect(networkHomeCountryCode, SIGNAL(editingFinished()), this, SLOT(emitNetworkDataChange()));
+ item = new OptionsItem(tr("Home country code"), networkHomeCountryCode);
+ item->setTags(tags);
+ optionsList << item;
+
+ networkHomeNetworkCode = new QLineEdit();
+ networkHomeNetworkCode->setValidator(new QRegExpValidator(rx, 0));
+ connect(networkHomeNetworkCode, SIGNAL(editingFinished()), this, SLOT(emitNetworkDataChange()));
+ item = new OptionsItem(tr("Home network code"), networkHomeNetworkCode);
+ item->setTags(tags);
+ optionsList << item;
+
+ networkCurrentMode = new QComboBox();
+ connect(networkCurrentMode, SIGNAL(activated(int)), this, SLOT(emitNetworkDataChange()));
+ item = new OptionsItem(tr("Currently active mode"), networkCurrentMode);
+ optionsList << item;
+
+ networkModes = new QComboBox();
+ networkName = new QLineEdit();
+ networkStatus = new QComboBox();
+ networkMacAddress = new QLineEdit();
+ networkMacAddress->setInputMask("HH:HH:HH:HH:HH:HH");
+ networkMacAddress->setValidator(new QRegExpValidator(QRegExp("(\\S\\S:){5}\\S\\S"), networkMacAddress));
+ networkSignalStrength = new QSpinBox();
+ networkSignalStrength->setRange(-1, 100);
+ networkSignalStrength->setValue(-1);
+ QFormLayout *fLayout = new QFormLayout();
+ fLayout->addRow(tr("Name"), networkName);
+ fLayout->addRow(tr("Status"), networkStatus);
+ fLayout->addRow(tr("MAC address"), networkMacAddress);
+ fLayout->addRow(tr("Signal Strength"), networkSignalStrength);
+ QGroupBox *networkModeProperties = new QGroupBox(tr("Properties"));
+ networkModeProperties->setLayout(fLayout);
+ QHBoxLayout *hLayout = new QHBoxLayout();
+ hLayout->addWidget(new QLabel(tr("Edit properties of")));
+ hLayout->addWidget(networkModes);
+ QVBoxLayout *vLayout = new QVBoxLayout();
+ vLayout->addLayout(hLayout);
+ vLayout->addWidget(networkModeProperties);
+ networkModeProperties = new QGroupBox();
+ networkModeProperties->setLayout(vLayout);
+ QPushButton *toggleNetworkSettingsVisible = new QPushButton(tr("Show"));
+ connect(networkModes, SIGNAL(activated(int)), this, SLOT(showNetworkMode()));
+ connect(networkName, SIGNAL(editingFinished()), this, SLOT(editNetworkMode()));
+ connect(networkStatus, SIGNAL(activated(int)), this, SLOT(editNetworkMode()));
+ connect(networkMacAddress, SIGNAL(editingFinished()), this, SLOT(editNetworkMode()));
+ connect(networkSignalStrength, SIGNAL(editingFinished()), this, SLOT(editNetworkMode()));
+ item = new OptionsItem("Network mode properties", toggleNetworkSettingsVisible);
+ QStringList networkModeTags = tags;
+ networkModeTags << tr("name") << tr("status") << tr("mac") << tr("address") << tr("mode") << tr("signal") << tr("strength");
+ item->setTags(networkModeTags);
+ OptionsItem *advancedItem = new OptionsItem("", networkModeProperties, true);
+ item->setAdvancedPage(advancedItem);
+ optionsList << item;
+
+ initializeNetworkOptions();
+
+ setTitle(tr("Network"));
+ setOptions(optionsList);
+}
+
+void NetworkSystemInfoUi::initializeNetworkOptions()
+{
+ networkStatus->clear();
+ // depends on order
+ networkStatus->addItem(tr("Undefined"));
+ networkStatus->addItem(tr("No Network Available"));
+ networkStatus->addItem(tr("Emergency Only"));
+ networkStatus->addItem(tr("Searching"));
+ networkStatus->addItem(tr("Busy"));
+ networkStatus->addItem(tr("Connected"));
+ networkStatus->addItem(tr("Home Network"));
+ networkStatus->addItem(tr("Denied"));
+ networkStatus->addItem(tr("Roaming"));
+
+ networkCurrentMode->clear();
+ // depends on order
+ networkCurrentMode->addItem(tr("Unknown Mode"), NetworkSystemInfoScriptInterface::UnknownMode);
+ networkCurrentMode->addItem(tr("GSM Mode"), NetworkSystemInfoScriptInterface::GsmMode);
+ networkCurrentMode->addItem(tr("CDMA Mode"), NetworkSystemInfoScriptInterface::CdmaMode);
+ networkCurrentMode->addItem(tr("W-CDMA Mode"), NetworkSystemInfoScriptInterface::WcdmaMode);
+ networkCurrentMode->addItem(tr("WLAN Mode"), NetworkSystemInfoScriptInterface::WlanMode);
+ networkCurrentMode->addItem(tr("Ethernet Mode"), NetworkSystemInfoScriptInterface::EthernetMode);
+ networkCurrentMode->addItem(tr("Bluetooth Mode"), NetworkSystemInfoScriptInterface::BluetoothMode);
+ networkCurrentMode->addItem(tr("WiMAX Mode"), NetworkSystemInfoScriptInterface::WimaxMode);
+
+ networkModes->clear();
+ // depends on order
+ networkModes->addItem(tr("Unknown Mode"), NetworkSystemInfoScriptInterface::UnknownMode);
+ networkModes->addItem(tr("GSM Mode"), NetworkSystemInfoScriptInterface::GsmMode);
+ networkModes->addItem(tr("CDMA Mode"), NetworkSystemInfoScriptInterface::CdmaMode);
+ networkModes->addItem(tr("W-CDMA Mode"), NetworkSystemInfoScriptInterface::WcdmaMode);
+ networkModes->addItem(tr("WLAN Mode"), NetworkSystemInfoScriptInterface::WlanMode);
+ networkModes->addItem(tr("Ethernet Mode"), NetworkSystemInfoScriptInterface::EthernetMode);
+ networkModes->addItem(tr("Bluetooth Mode"), NetworkSystemInfoScriptInterface::BluetoothMode);
+ networkModes->addItem(tr("WiMAX Mode"), NetworkSystemInfoScriptInterface::WimaxMode);
+
+ networkModeInfo.resize(8);
+ showNetworkMode();
+}
+
+NetworkSystemInfoUi::NetworkData::NetworkData()
+ : networkInfo(8)
+{
+}
+
+
+NetworkSystemInfoUi::NetworkSystemInfoUi(QWidget *parent)
+ : ToolBoxPage(parent)
+{
+ mScriptInterface = new NetworkSystemInfoScriptInterface(this);
+ initializeNetwork();
+
+ // update displayed values when underlying data changes
+ connect(this, SIGNAL(networkDataChanged(NetworkSystemInfoUi::NetworkData)), SLOT(showNetworkMode()));
+
+ // button translators
+ connect(this, SIGNAL(networkDataChanged(NetworkSystemInfoUi::NetworkData)), SLOT(emitButtonSignalsOnChange()));
+}
+
+NetworkSystemInfoUi::~NetworkSystemInfoUi()
+{
+}
+
+NetworkSystemInfoScriptInterface *NetworkSystemInfoUi::scriptInterface()
+{
+ return mScriptInterface;
+}
+
+void NetworkSystemInfoUi::showNetworkMode()
+{
+ int index = networkModes->itemData(networkModes->currentIndex()).toInt();
+ const NetworkData::ModeInfo &info = networkModeInfo.at(index);
+ networkName->setText(info.name);
+ networkMacAddress->setText(info.macAddress);
+ networkSignalStrength->setValue(info.signalStrength);
+ networkStatus->setCurrentIndex(static_cast<int>(info.status));
+}
+
+void NetworkSystemInfoUi::editNetworkMode()
+{
+ int index = networkModes->currentIndex();
+ networkModeInfo[index].name = networkName->text();
+ networkModeInfo[index].macAddress = networkMacAddress->text();
+ networkModeInfo[index].signalStrength = networkSignalStrength->value();
+ networkModeInfo[index].status = static_cast<NetworkSystemInfoScriptInterface::NetworkStatus>(networkStatus->currentIndex());
+
+ emitNetworkDataChange();
+}
+
+void NetworkSystemInfoUi::emitNetworkDataChange()
+{
+ emit networkDataChanged(networkData());
+}
+
+NetworkSystemInfoUi::NetworkData NetworkSystemInfoUi::networkData() const
+{
+ NetworkData d;
+ d.cellId = mScriptInterface->cellId();
+ d.locationAreaCode = mScriptInterface->locationAreaCode();
+ d.currentMobileCountryCode = mScriptInterface->currentMobileCountryCode();
+ d.currentMobileNetworkCode = mScriptInterface->currentMobileNetworkCode();
+ d.homeMobileCountryCode = mScriptInterface->homeMobileCountryCode();
+ d.homeMobileNetworkCode = mScriptInterface->homeMobileNetworkCode();
+ d.currentMode = mScriptInterface->currentMode();
+ d.networkInfo = networkModeInfo;
+ return d;
+}
+
+void NetworkSystemInfoUi::setNetworkData(const NetworkSystemInfoUi::NetworkData &data)
+{
+ setDisplayedNetworkData(data);
+ emit networkDataChanged(data);
+}
+
+void NetworkSystemInfoUi::setDisplayedNetworkData(const NetworkSystemInfoUi::NetworkData &data)
+{
+ networkCellId->setValue(data.cellId);
+ networkLocationAreaCode->setValue(data.locationAreaCode);
+ networkMobileCountryCode->setText(data.currentMobileCountryCode);
+ networkMobileNetworkCode->setText(data.currentMobileNetworkCode);
+ networkHomeCountryCode->setText(data.homeMobileCountryCode);
+ networkHomeNetworkCode->setText(data.homeMobileNetworkCode);
+ networkCurrentMode->setCurrentIndex(static_cast<int>(data.currentMode));
+ networkModeInfo = data.networkInfo;
+ showNetworkMode();
+}
+
+void NetworkSystemInfoUi::emitButtonSignalsOnChange()
+{
+ NetworkSystemInfoScriptInterface::NetworkMode currentMode = mScriptInterface->currentMode();
+ emit currentNetworkModeChanged(static_cast<NetworkModeButton::NetworkMode>(currentMode));
+
+ int strength = mScriptInterface->networkSignalStrength(currentMode);
+
+ SignalStrengthButton::SignalStrength s;
+ if (strength == 0) {
+ s = SignalStrengthButton::NoSignal;
+ } else if (strength <= 20) {
+ s = SignalStrengthButton::SignalVeryLow;
+ } else if (strength <= 40) {
+ s = SignalStrengthButton::SignalLow;
+ } else {
+ s = SignalStrengthButton::SignalNormal;
+ }
+ emit currentNetworkSignalStrengthChanged(s);
+}
+
+void NetworkSystemInfoUi::setCurrentNetworkMode(NetworkModeButton::NetworkMode m)
+{
+ mScriptInterface->setCurrentMode(static_cast<NetworkSystemInfoScriptInterface::NetworkMode>(m));
+}
+
+void NetworkSystemInfoUi::setCurrentNetworkSignalStrength(SignalStrengthButton::SignalStrength s)
+{
+ NetworkSystemInfoScriptInterface::NetworkMode mode = mScriptInterface->currentMode();
+
+ switch (s) {
+ case SignalStrengthButton::NoSignal:
+ mScriptInterface->setNetworkSignalStrength(mode, 0);
+ break;
+ case SignalStrengthButton::SignalVeryLow:
+ mScriptInterface->setNetworkSignalStrength(mode, 20);
+ break;
+ case SignalStrengthButton::SignalLow:
+ mScriptInterface->setNetworkSignalStrength(mode, 40);
+ break;
+ case SignalStrengthButton::SignalNormal:
+ mScriptInterface->setNetworkSignalStrength(mode, 100);
+ break;
+ }
+}
+
+
+/*!
+ \class NetworkSystemInfoScriptInterface
+ \brief Exposed as sysinfo.network.
+*/
+
+NetworkSystemInfoScriptInterface::NetworkSystemInfoScriptInterface(NetworkSystemInfoUi *ui)
+ : QObject(ui)
+ , ui(ui)
+{
+ int enumIndex = metaObject()->indexOfEnumerator("NetworkStatus");
+ QMetaEnum metaEnum = metaObject()->enumerator(enumIndex);
+ for (int i = 0; i < metaEnum.keyCount(); ++i)
+ setProperty(metaEnum.key(i), metaEnum.value(i));
+
+ enumIndex = metaObject()->indexOfEnumerator("NetworkMode");
+ metaEnum = metaObject()->enumerator(enumIndex);
+ for (int i = 0; i < metaEnum.keyCount(); ++i)
+ setProperty(metaEnum.key(i), metaEnum.value(i));
+}
+
+NetworkSystemInfoScriptInterface::~NetworkSystemInfoScriptInterface()
+{
+}
+
+int NetworkSystemInfoScriptInterface::cellId() const
+{
+ return ui->networkCellId->value();
+}
+
+void NetworkSystemInfoScriptInterface::setCellId(int id)
+{
+ if (id != cellId()) {
+ ui->networkCellId->setValue(id);
+ ui->emitNetworkDataChange();
+ }
+}
+
+int NetworkSystemInfoScriptInterface::locationAreaCode() const
+{
+ return ui->networkLocationAreaCode->value();
+}
+
+void NetworkSystemInfoScriptInterface::setLocationAreaCode(int code)
+{
+ if (code != locationAreaCode()) {
+ ui->networkLocationAreaCode->setValue(code);
+ ui->emitNetworkDataChange();
+ }
+}
+
+QString NetworkSystemInfoScriptInterface::currentMobileCountryCode() const
+{
+ return ui->networkMobileCountryCode->text();
+}
+
+QString NetworkSystemInfoScriptInterface::currentMobileNetworkCode() const
+{
+ return ui->networkMobileNetworkCode->text();
+}
+
+QString NetworkSystemInfoScriptInterface::homeMobileCountryCode() const
+{
+ return ui->networkHomeCountryCode->text();
+}
+
+QString NetworkSystemInfoScriptInterface::homeMobileNetworkCode() const
+{
+ return ui->networkHomeNetworkCode->text();
+}
+
+void NetworkSystemInfoScriptInterface::setCurrentMobileCountryCode(const QString &code)
+{
+ if (code != currentMobileCountryCode()) {
+ ui->networkMobileCountryCode->setText(code);
+ ui->emitNetworkDataChange();
+ }
+}
+
+void NetworkSystemInfoScriptInterface::setCurrentMobileNetworkCode(const QString &code)
+{
+ if (code != currentMobileNetworkCode()) {
+ ui->networkMobileNetworkCode->setText(code);
+ ui->emitNetworkDataChange();
+ }
+}
+
+void NetworkSystemInfoScriptInterface::setHomeMobileCountryCode(const QString &code)
+{
+ if (code != homeMobileCountryCode()) {
+ ui->networkHomeCountryCode->setText(code);
+ ui->emitNetworkDataChange();
+ }
+}
+
+void NetworkSystemInfoScriptInterface::setHomeMobileNetworkCode(const QString &code)
+{
+ if (code != homeMobileNetworkCode()) {
+ ui->networkHomeNetworkCode->setText(code);
+ ui->emitNetworkDataChange();
+ }
+}
+
+NetworkSystemInfoScriptInterface::NetworkMode NetworkSystemInfoScriptInterface::currentMode() const
+{
+ return static_cast<NetworkMode>(ui->networkCurrentMode->currentIndex());
+}
+
+void NetworkSystemInfoScriptInterface::setCurrentMode(NetworkSystemInfoScriptInterface::NetworkMode m)
+{
+ if (m != currentMode()) {
+ ui->networkCurrentMode->setCurrentIndex(static_cast<int>(m));
+ ui->emitNetworkDataChange();
+ }
+}
+
+QString NetworkSystemInfoScriptInterface::networkName(NetworkMode m) const
+{
+ return ui->networkModeInfo.at(static_cast<int>(m)).name;
+}
+
+void NetworkSystemInfoScriptInterface::setNetworkName(NetworkMode m, const QString &name)
+{
+ if (name != networkName(m)) {
+ ui->networkModeInfo[static_cast<int>(m)].name = name;
+ ui->emitNetworkDataChange();
+ }
+}
+
+QString NetworkSystemInfoScriptInterface::macAddress(NetworkMode m) const
+{
+ return ui->networkModeInfo.at(static_cast<int>(m)).macAddress;
+}
+
+void NetworkSystemInfoScriptInterface::setNetworkMacAddress(NetworkMode m, const QString &mac)
+{
+ if (mac != macAddress(m)) {
+ ui->networkModeInfo[static_cast<int>(m)].macAddress = mac;
+ ui->emitNetworkDataChange();
+ }
+}
+
+qint32 NetworkSystemInfoScriptInterface::networkSignalStrength(NetworkMode m) const
+{
+ return ui->networkModeInfo.at(static_cast<int>(m)).signalStrength;
+}
+
+void NetworkSystemInfoScriptInterface::setNetworkSignalStrength(NetworkMode m, qint32 strength)
+{
+ if (strength != networkSignalStrength(m)) {
+ ui->networkModeInfo[static_cast<int>(m)].signalStrength = strength;
+ ui->emitNetworkDataChange();
+ }
+}
+
+NetworkSystemInfoScriptInterface::NetworkStatus NetworkSystemInfoScriptInterface::networkStatus(NetworkMode m) const
+{
+ return ui->networkModeInfo.at(static_cast<int>(m)).status;
+}
+
+void NetworkSystemInfoScriptInterface::setNetworkStatus(NetworkMode m, NetworkSystemInfoScriptInterface::NetworkStatus status)
+{
+ if (status != networkStatus(m)) {
+ ui->networkModeInfo[static_cast<int>(m)].status = status;
+ ui->emitNetworkDataChange();
+ }
+}
diff --git a/src/ui/systeminfonetworkui.h b/src/ui/systeminfonetworkui.h
new file mode 100644
index 0000000..8fdbab5
--- /dev/null
+++ b/src/ui/systeminfonetworkui.h
@@ -0,0 +1,208 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef SYSINFONETWORKUI_H
+#define SYSINFONETWORKUI_H
+
+#include <remotecontrolwidget/toolbox.h>
+#include <remotecontrolwidget/networkmodebutton.h>
+#include <remotecontrolwidget/signalstrengthbutton.h>
+
+#include <QtCore/QObject>
+
+class ConfigurationWidget;
+class NetworkModeButton;
+class SignalStrengthButton;
+class QLineEdit;
+class QComboBox;
+class QLabel;
+class QSpinBox;
+class QCheckBox;
+
+class NetworkSystemInfoUi;
+
+class NetworkSystemInfoScriptInterface : public QObject
+{
+ Q_OBJECT
+public:
+ // must mimic QSystemNetworkInfo::NetworkStatus
+ enum NetworkStatus {
+ UndefinedStatus = 0,
+ NoNetworkAvailable,
+ EmergencyOnly,
+ Searching,
+ Busy,
+ Connected,
+ HomeNetwork,
+ Denied,
+ Roaming
+ };
+ Q_ENUMS(NetworkStatus)
+
+ // must mimic QSystemNetworkInfo::NetworkMode
+ enum NetworkMode {
+ UnknownMode=0,
+ GsmMode,
+ CdmaMode,
+ WcdmaMode,
+ WlanMode,
+ EthernetMode,
+ BluetoothMode,
+ WimaxMode
+ };
+ Q_ENUMS(NetworkMode)
+
+ explicit NetworkSystemInfoScriptInterface(NetworkSystemInfoUi *ui);
+ virtual ~NetworkSystemInfoScriptInterface();
+
+ int cellId() const;
+ int locationAreaCode() const;
+ QString currentMobileCountryCode() const;
+ QString currentMobileNetworkCode() const;
+ QString homeMobileCountryCode() const;
+ QString homeMobileNetworkCode() const;
+ NetworkMode currentMode() const;
+
+ Q_PROPERTY(int cellId READ cellId WRITE setCellId)
+ Q_PROPERTY(int locationAreaCode READ locationAreaCode WRITE setLocationAreaCode)
+ Q_PROPERTY(QString currentMobileCountryCode READ currentMobileCountryCode WRITE setCurrentMobileCountryCode)
+ Q_PROPERTY(QString currentMobileNetworkCode READ currentMobileNetworkCode WRITE setCurrentMobileNetworkCode)
+ Q_PROPERTY(QString homeMobileCountryCode READ homeMobileCountryCode WRITE setHomeMobileCountryCode)
+ Q_PROPERTY(QString homeMobileNetworkCode READ homeMobileNetworkCode WRITE setHomeMobileNetworkCode)
+ Q_PROPERTY(NetworkMode currentMode READ currentMode WRITE setCurrentMode)
+
+ Q_INVOKABLE QString networkName(NetworkMode m) const;
+ Q_INVOKABLE QString macAddress(NetworkMode m) const;
+ Q_INVOKABLE qint32 networkSignalStrength(NetworkMode m) const;
+ Q_INVOKABLE NetworkStatus networkStatus(NetworkMode m) const;
+
+public slots:
+ void setCellId(int id);
+ void setLocationAreaCode(int code);
+ void setCurrentMobileCountryCode(const QString &code);
+ void setCurrentMobileNetworkCode(const QString &code);
+ void setHomeMobileCountryCode(const QString &code);
+ void setHomeMobileNetworkCode(const QString &code);
+ void setCurrentMode(NetworkSystemInfoScriptInterface::NetworkMode m);
+
+ void setNetworkName(NetworkSystemInfoScriptInterface::NetworkMode m, const QString &name);
+ void setNetworkMacAddress(NetworkSystemInfoScriptInterface::NetworkMode m, const QString &mac);
+ void setNetworkSignalStrength(NetworkSystemInfoScriptInterface::NetworkMode m, qint32 strength);
+ void setNetworkStatus(NetworkSystemInfoScriptInterface::NetworkMode m, NetworkSystemInfoScriptInterface::NetworkStatus status);
+
+private:
+ NetworkSystemInfoUi *ui;
+};
+
+class NetworkSystemInfoUi : public ToolBoxPage
+{
+ Q_OBJECT
+public:
+ struct NetworkData
+ {
+ NetworkData();
+
+ struct ModeInfo
+ {
+ NetworkSystemInfoScriptInterface::NetworkStatus status;
+ QString name;
+ QString macAddress;
+ qint32 signalStrength;
+ //QNetworkInterface interface;
+ };
+
+ QVector<ModeInfo> networkInfo;
+
+ int cellId;
+ int locationAreaCode;
+
+ QString currentMobileCountryCode;
+ QString currentMobileNetworkCode;
+ QString homeMobileCountryCode;
+ QString homeMobileNetworkCode;
+ NetworkSystemInfoScriptInterface::NetworkMode currentMode;
+ };
+
+ explicit NetworkSystemInfoUi(QWidget *parent = 0);
+ virtual ~NetworkSystemInfoUi();
+
+ NetworkSystemInfoScriptInterface *scriptInterface();
+
+ NetworkData networkData() const;
+
+public slots:
+ void setNetworkData(const NetworkSystemInfoUi::NetworkData &data);
+ void setDisplayedNetworkData(const NetworkSystemInfoUi::NetworkData &data);
+
+signals:
+ void networkDataChanged(const NetworkSystemInfoUi::NetworkData &data) const;
+
+
+// since the quick access button enums differ from the enums here,
+// we need these translator slots/signals
+public slots:
+ void setCurrentNetworkMode(NetworkModeButton::NetworkMode);
+ void setCurrentNetworkSignalStrength(SignalStrengthButton::SignalStrength);
+signals:
+ void currentNetworkModeChanged(NetworkModeButton::NetworkMode) const;
+ void currentNetworkSignalStrengthChanged(SignalStrengthButton::SignalStrength) const;
+private slots:
+ void emitButtonSignalsOnChange();
+
+
+private slots:
+ void emitNetworkDataChange();
+ void showNetworkMode();
+ void editNetworkMode();
+
+private:
+ void initializeNetwork();
+ void initializeNetworkOptions();
+
+private:
+ QSpinBox *networkCellId;
+ QSpinBox *networkLocationAreaCode;
+ QLineEdit* networkMobileCountryCode;
+ QLineEdit* networkMobileNetworkCode;
+ QLineEdit* networkHomeCountryCode;
+ QLineEdit* networkHomeNetworkCode;
+ QComboBox *networkCurrentMode;
+ QComboBox *networkModes;
+ QLineEdit *networkName;
+ QComboBox *networkStatus;
+ QLineEdit *networkMacAddress;
+ QSpinBox * networkSignalStrength;
+
+ QVector<NetworkData::ModeInfo> networkModeInfo;
+
+ NetworkSystemInfoScriptInterface *mScriptInterface;
+ friend class NetworkSystemInfoScriptInterface;
+};
+
+#endif // SYSINFONETWORKUI_H
diff --git a/src/ui/systeminfostorageui.cpp b/src/ui/systeminfostorageui.cpp
new file mode 100644
index 0000000..e0fcc3a
--- /dev/null
+++ b/src/ui/systeminfostorageui.cpp
@@ -0,0 +1,387 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "systeminfostorageui.h"
+
+#include <QtCore/QMetaEnum>
+#include <QtGui/QPushButton>
+#include <QtGui/QBoxLayout>
+#include <QtGui/QLineEdit>
+#include <QtGui/QComboBox>
+#include <QtGui/QCheckBox>
+#include <QtGui/QLabel>
+#include <QtGui/QSpinBox>
+#include <QtGui/QFormLayout>
+#include <QtGui/QGroupBox>
+#include <QtGui/QInputDialog>
+
+void StorageSystemInfoUi::initializeStorage()
+{
+ QStringList tags;
+ QList<OptionsItem *> optionsList;
+ tags << tr("drives") << tr("memory") << tr("storage");
+
+ systemInfoDrives = new QComboBox();
+ QPushButton *systemInfoChangeDriveName = new QPushButton(tr("Change Name"));
+ QPushButton *systemInfoRemoveDrive = new QPushButton(tr("Remove"));
+ QPushButton *systemInfoAddDrive = new QPushButton(tr("Add"));
+ QHBoxLayout *hLayout = new QHBoxLayout();
+ hLayout->addWidget(systemInfoChangeDriveName);
+ hLayout->addWidget(systemInfoRemoveDrive);
+ hLayout->addWidget(systemInfoAddDrive);
+ QVBoxLayout *vLayout = new QVBoxLayout();
+ vLayout->addWidget(systemInfoDrives);
+ vLayout->addLayout(hLayout);
+ systemInfoDriveType = new QComboBox();
+ systemInfoDriveTotalSpace = new QLineEdit();
+ QRegExp rx("\\d*");
+ systemInfoDriveTotalSpace->setValidator(new QRegExpValidator(rx, this));
+ systemInfoDriveAvailableSpace = new QLineEdit();
+ systemInfoDriveAvailableSpace->setValidator(new QRegExpValidator(rx, this));
+ QFormLayout *driveLayout = new QFormLayout();
+ driveLayout->addRow(tr("Type"), systemInfoDriveType);
+ driveLayout->addRow(tr("Total space"), systemInfoDriveTotalSpace);
+ driveLayout->addRow(tr("Available space"), systemInfoDriveAvailableSpace);
+ QGroupBox *drivePropertyGroupBox = new QGroupBox(tr("Storage Properties"));
+ drivePropertyGroupBox->setLayout(driveLayout);
+ vLayout->addWidget(drivePropertyGroupBox);
+ QWidget *drives = new QWidget();
+ drives->setLayout(vLayout);
+ connect(systemInfoDrives, SIGNAL(activated(int)), SLOT(showDriveInfo()));
+ connect(systemInfoAddDrive, SIGNAL(clicked()), SLOT(addDriveClicked()));
+ connect(systemInfoRemoveDrive, SIGNAL(clicked()), SLOT(removeDriveClicked()));
+ connect(systemInfoChangeDriveName, SIGNAL(clicked()), SLOT(renameDriveClicked()));
+ connect(systemInfoDriveType, SIGNAL(activated(int)), SLOT(editDriveInfo()));
+ connect(systemInfoDriveTotalSpace, SIGNAL(editingFinished()), SLOT(editDriveInfo()));
+ connect(systemInfoDriveAvailableSpace, SIGNAL(editingFinished()), SLOT(editDriveInfo()));
+ OptionsItem *item = new OptionsItem("", drives, true);
+ QStringList drivesTags = tags;
+ drivesTags << tr("total") << tr("available") << tr("space");
+ item->setTags(drivesTags);
+ optionsList << item;
+
+ initializeStorageOptions();
+
+ setTitle(tr("Storage"));
+ setOptions(optionsList);
+}
+
+void StorageSystemInfoUi::initializeStorageOptions()
+{
+ systemInfoDriveType->clear();
+ QStringList driveTypes;
+ // depends on order of items
+ driveTypes.append(tr("No Drive"));
+ driveTypes.append(tr("Internal Drive"));
+ driveTypes.append(tr("Removable Drive"));
+ driveTypes.append(tr("Remote Drive"));
+ driveTypes.append(tr("CD-ROM Drive"));
+ systemInfoDriveType->addItems(driveTypes);
+}
+
+StorageSystemInfoUi::StorageSystemInfoUi(QWidget *parent)
+ : ToolBoxPage(parent)
+{
+ mScriptInterface = new StorageSystemInfoScriptInterface(this);
+
+ initializeStorage();
+
+ // when the data changes, update the display
+ connect(this, SIGNAL(storageDataChanged(StorageSystemInfoUi::StorageData)),
+ SLOT(showDriveInfo()));
+}
+
+StorageSystemInfoScriptInterface *StorageSystemInfoUi::scriptInterface()
+{
+ return mScriptInterface;
+}
+
+StorageSystemInfoUi::StorageData StorageSystemInfoUi::storageData() const
+{
+ return mData;
+}
+
+void StorageSystemInfoUi::setStorageData(const StorageSystemInfoUi::StorageData &data)
+{
+ setDisplayedStorageData(data);
+ emit storageDataChanged(data);
+}
+
+void StorageSystemInfoUi::setDisplayedStorageData(const StorageSystemInfoUi::StorageData &data)
+{
+ mData = data;
+ updateDrivesList();
+}
+
+void StorageSystemInfoUi::emitStorageDataChange()
+{
+ emit storageDataChanged(storageData());
+}
+
+void StorageSystemInfoUi::showDriveInfo()
+{
+ bool editingEnabled = systemInfoDrives->count() != 0;
+ systemInfoDriveType->setEnabled(editingEnabled);
+ systemInfoDriveAvailableSpace->setEnabled(editingEnabled);
+ systemInfoDriveTotalSpace->setEnabled(editingEnabled);
+
+ if (!editingEnabled)
+ return;
+
+ const QString curDrive = systemInfoDrives->currentText();
+ systemInfoDriveType->setCurrentIndex(static_cast<int>(mScriptInterface->typeForDrive(curDrive)));
+ systemInfoDriveAvailableSpace->setText(QString::number(mScriptInterface->availableDiskSpace(curDrive)));
+ systemInfoDriveTotalSpace->setText(QString::number(mScriptInterface->totalDiskSpace(curDrive)));
+}
+
+void StorageSystemInfoUi::editDriveInfo()
+{
+ if (systemInfoDrives->count() == 0)
+ return;
+
+ const QString curDrive = systemInfoDrives->currentText();
+ StorageData::DriveInfo &driveInfo = mData.drives[curDrive];
+ driveInfo.type = static_cast<StorageSystemInfoScriptInterface::DriveType>(systemInfoDriveType->currentIndex());
+ driveInfo.totalSpace = systemInfoDriveTotalSpace->text().toLongLong();
+ driveInfo.availableSpace = systemInfoDriveAvailableSpace->text().toLongLong();
+
+ emitStorageDataChange();
+}
+
+void StorageSystemInfoUi::updateDrivesList(const QString &driveToShow)
+{
+ QString showDrive = driveToShow;
+ if (showDrive.isNull())
+ showDrive = systemInfoDrives->currentText();
+
+ systemInfoDrives->clear();
+ systemInfoDrives->addItems(mData.drives.keys());
+
+ if (mData.drives.contains(showDrive))
+ systemInfoDrives->setCurrentIndex(mData.drives.keys().indexOf(showDrive));
+
+ showDriveInfo();
+}
+
+void StorageSystemInfoUi::renameDisplayedDrive(const QString &from, const QString &to)
+{
+ StorageData::DriveInfo prevDriveInfo = mData.drives.value(from);
+ mData.drives.remove(from);
+ mData.drives.insert(to, prevDriveInfo);
+ updateDrivesList(to);
+}
+
+void StorageSystemInfoUi::renameDriveClicked()
+{
+ if (systemInfoDrives->count() == 0)
+ return;
+
+ const QString oldName = systemInfoDrives->currentText();
+ const QString newName = QInputDialog::getText(0,
+ "Change Drive Name", "Enter the new drive name:",
+ QLineEdit::Normal, oldName);
+
+ if (newName.isEmpty())
+ return;
+
+ renameDisplayedDrive(oldName, newName);
+ emitStorageDataChange();
+}
+
+void StorageSystemInfoUi::addDisplayedDrive(const QString &name)
+{
+ StorageData::DriveInfo driveInfo;
+ mData.drives.insert(name, driveInfo);
+ updateDrivesList(name);
+}
+
+void StorageSystemInfoUi::addDriveClicked()
+{
+ const QString newName = QInputDialog::getText(0,
+ "Add New Drive", "Enter the new drive name:");
+ if (newName.isEmpty())
+ return;
+
+ addDisplayedDrive(newName);
+ emitStorageDataChange();
+}
+
+void StorageSystemInfoUi::removeDisplayedDrive(const QString &name)
+{
+ mData.drives.remove(name);
+ updateDrivesList();
+}
+
+void StorageSystemInfoUi::removeDriveClicked()
+{
+ if (systemInfoDrives->count() == 0)
+ return;
+
+ removeDisplayedDrive(systemInfoDrives->currentText());
+ emitStorageDataChange();
+}
+
+
+StorageSystemInfoUi::StorageData::DriveInfo::DriveInfo()
+ : type(StorageSystemInfoScriptInterface::NoDrive)
+ , totalSpace(-1)
+ , availableSpace(-1)
+{
+}
+
+
+/*!
+ \class StorageSystemInfoScriptInterface
+ \brief Exposed as sysinfo.storage.
+*/
+
+StorageSystemInfoScriptInterface::StorageSystemInfoScriptInterface(StorageSystemInfoUi *ui)
+ : QObject(ui)
+ , ui(ui)
+{
+ int enumIndex = metaObject()->indexOfEnumerator("DriveType");
+ QMetaEnum metaEnum = metaObject()->enumerator(enumIndex);
+ for (int i = 0; i < metaEnum.keyCount(); ++i)
+ setProperty(metaEnum.key(i), metaEnum.value(i));
+}
+
+StorageSystemInfoScriptInterface::~StorageSystemInfoScriptInterface()
+{
+}
+
+QStringList StorageSystemInfoScriptInterface::logicalDrives() const
+{
+ return ui->mData.drives.keys();
+}
+
+StorageSystemInfoScriptInterface::DriveType StorageSystemInfoScriptInterface::typeForDrive(const QString &name) const
+{
+ if (!ui->mData.drives.contains(name))
+ return NoDrive;
+ return ui->mData.drives.value(name).type;
+}
+
+qint64 StorageSystemInfoScriptInterface::totalDiskSpace(const QString &name) const
+{
+ if (!ui->mData.drives.contains(name))
+ return -1;
+ return ui->mData.drives.value(name).totalSpace;
+}
+
+qint64 StorageSystemInfoScriptInterface::availableDiskSpace(const QString &name) const
+{
+ if (!ui->mData.drives.contains(name))
+ return -1;
+ return ui->mData.drives.value(name).availableSpace;
+}
+
+bool StorageSystemInfoScriptInterface::addDrive(const QString &name)
+{
+ if (ui->mData.drives.contains(name))
+ return false;
+
+ ui->addDisplayedDrive(name);
+ ui->emitStorageDataChange();
+ return true;
+}
+
+bool StorageSystemInfoScriptInterface::addDrive(const QString &name,
+ StorageSystemInfoScriptInterface::DriveType type,
+ qint64 totalSpace, qint64 availableSpace)
+{
+ if (ui->mData.drives.contains(name))
+ return false;
+
+ ui->addDisplayedDrive(name);
+ StorageSystemInfoUi::StorageData::DriveInfo &di = ui->mData.drives[name];
+ di.type = type;
+ di.availableSpace = availableSpace;
+ di.totalSpace = totalSpace;
+ ui->emitStorageDataChange();
+ return true;
+}
+
+bool StorageSystemInfoScriptInterface::removeDrive(const QString &name)
+{
+ if (!ui->mData.drives.contains(name))
+ return false;
+
+ ui->removeDisplayedDrive(name);
+ ui->emitStorageDataChange();
+ return true;
+}
+
+bool StorageSystemInfoScriptInterface::setName(const QString &oldname, const QString &newname)
+{
+ if (!ui->mData.drives.contains(oldname))
+ return false;
+
+ ui->renameDisplayedDrive(oldname, newname);
+ ui->emitStorageDataChange();
+ return true;
+}
+
+bool StorageSystemInfoScriptInterface::setType(const QString &name, StorageSystemInfoScriptInterface::DriveType type)
+{
+ if (!ui->mData.drives.contains(name))
+ return false;
+
+ if (ui->mData.drives[name].type != type)
+ {
+ ui->mData.drives[name].type = type;
+ ui->emitStorageDataChange();
+ }
+ return true;
+}
+
+bool StorageSystemInfoScriptInterface::setTotalSpace(const QString &name, qint64 space)
+{
+ if (!ui->mData.drives.contains(name))
+ return false;
+
+ if (ui->mData.drives[name].totalSpace != space)
+ {
+ ui->mData.drives[name].totalSpace = space;
+ ui->emitStorageDataChange();
+ }
+ return true;
+}
+
+bool StorageSystemInfoScriptInterface::setAvailableSpace(const QString &name, qint64 space)
+{
+ if (!ui->mData.drives.contains(name))
+ return false;
+
+ if (ui->mData.drives[name].availableSpace != space)
+ {
+ ui->mData.drives[name].availableSpace = space;
+ ui->emitStorageDataChange();
+ }
+ return true;
+}
diff --git a/src/ui/systeminfostorageui.h b/src/ui/systeminfostorageui.h
new file mode 100644
index 0000000..aab3741
--- /dev/null
+++ b/src/ui/systeminfostorageui.h
@@ -0,0 +1,140 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef SYSINFOSTORAGEUI_H
+#define SYSINFOSTORAGEUI_H
+
+#include <remotecontrolwidget/toolbox.h>
+
+#include <QtCore/QObject>
+#include <QtCore/QHash>
+
+class QLineEdit;
+class QComboBox;
+
+class StorageSystemInfoUi;
+
+class StorageSystemInfoScriptInterface : public QObject
+{
+ Q_OBJECT
+public:
+ // must mimic QSystemStorageInfo::DriveType
+ enum DriveType {
+ NoDrive = 0,
+ InternalDrive,
+ RemovableDrive,
+ RemoteDrive,
+ CdromDrive
+ };
+ Q_ENUMS(DriveType)
+
+ explicit StorageSystemInfoScriptInterface(StorageSystemInfoUi *ui);
+ virtual ~StorageSystemInfoScriptInterface();
+
+ Q_INVOKABLE QStringList logicalDrives() const;
+ Q_INVOKABLE DriveType typeForDrive(const QString &name) const;
+ Q_INVOKABLE qint64 totalDiskSpace(const QString &name) const;
+ Q_INVOKABLE qint64 availableDiskSpace(const QString &name) const;
+
+public slots:
+ bool addDrive(const QString &name);
+ bool addDrive(const QString &name, StorageSystemInfoScriptInterface::DriveType type,
+ qint64 totalSpace, qint64 availableSpace);
+ bool removeDrive(const QString &name);
+ bool setName(const QString &oldname, const QString &newname);
+ bool setType(const QString &name, StorageSystemInfoScriptInterface::DriveType type);
+ bool setTotalSpace(const QString &name, qint64 space);
+ bool setAvailableSpace(const QString &name, qint64 space);
+
+private:
+ StorageSystemInfoUi *ui;
+};
+
+class StorageSystemInfoUi : public ToolBoxPage
+{
+ Q_OBJECT
+public:
+ struct StorageData {
+ struct DriveInfo
+ {
+ DriveInfo();
+
+ StorageSystemInfoScriptInterface::DriveType type;
+ qint64 totalSpace;
+ qint64 availableSpace;
+ };
+
+ QHash<QString, DriveInfo> drives;
+ };
+
+ explicit StorageSystemInfoUi(QWidget *parent = 0);
+
+ StorageSystemInfoScriptInterface *scriptInterface();
+
+ StorageData storageData() const;
+
+public slots:
+ void setStorageData(const StorageSystemInfoUi::StorageData &data);
+ void setDisplayedStorageData(const StorageSystemInfoUi::StorageData &data);
+
+signals:
+ void storageDataChanged(const StorageSystemInfoUi::StorageData &data) const;
+
+private slots:
+ void emitStorageDataChange();
+ void showDriveInfo();
+ void editDriveInfo();
+ void updateDrivesList(const QString &driveToShow = QString());
+
+ void addDisplayedDrive(const QString &name);
+ void removeDisplayedDrive(const QString &name);
+ void renameDisplayedDrive(const QString &from, const QString &to);
+
+ void renameDriveClicked();
+ void addDriveClicked();
+ void removeDriveClicked();
+
+private:
+ void initializeStorage();
+ void initializeStorageOptions();
+
+
+private:
+ QComboBox *systemInfoDrives;
+ QComboBox *systemInfoDriveType;
+ QLineEdit *systemInfoDriveTotalSpace;
+ QLineEdit *systemInfoDriveAvailableSpace;
+
+ StorageData mData;
+
+ StorageSystemInfoScriptInterface *mScriptInterface;
+ friend class StorageSystemInfoScriptInterface;
+};
+
+#endif // SYSINFOSTORAGEUI_H
diff --git a/src/ui/ui.pri b/src/ui/ui.pri
new file mode 100644
index 0000000..9cb3f46
--- /dev/null
+++ b/src/ui/ui.pri
@@ -0,0 +1,28 @@
+INCLUDEPATH += src/ui
+DEPENDPATH += src/ui
+HEADERS += applicationtablewidget.h \
+ mainwindow.h \
+ configurationwidget.h \
+ contactsui.h \
+ systeminfogenericui.h \
+ systeminfonetworkui.h \
+ systeminfostorageui.h \
+ messagingui.h \
+ sensorsui.h \
+ viewconfiguration.h
+SOURCES += applicationtablewidget.cpp \
+ mainwindow.cpp \
+ configurationwidget.cpp \
+ contactsui.cpp \
+ systeminfogenericui.cpp \
+ systeminfonetworkui.cpp \
+ systeminfostorageui.cpp \
+ messagingui.cpp \
+ sensorsui.cpp \
+ viewconfiguration.cpp
+RESOURCES += menus/menus.qrc
+FORMS += inspector.ui \
+ viewconfiguration.ui
+
+RESOURCES += \
+ src/ui/ui.qrc
diff --git a/src/ui/ui.qrc b/src/ui/ui.qrc
new file mode 100644
index 0000000..f157ed7
--- /dev/null
+++ b/src/ui/ui.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/ui">
+ <file>icons/hicolor/256x256/apps/Nokia-Simulator.png</file>
+ </qresource>
+</RCC>
diff --git a/src/ui/viewconfiguration.cpp b/src/ui/viewconfiguration.cpp
new file mode 100644
index 0000000..c472a2c
--- /dev/null
+++ b/src/ui/viewconfiguration.cpp
@@ -0,0 +1,175 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "viewconfiguration.h"
+
+#include <QtGui/QGraphicsLineItem>
+#include <QtGui/QDesktopWidget>
+#include <QtGui/QPainter>
+#include <qmath.h>
+
+ViewConfiguration::ViewConfiguration(qreal correctionFactor, QWidget *parent)
+ : QDialog(parent)
+ , mCurrentCorrectionFactor(correctionFactor)
+ , mCurrentUnit(Centrimetre)
+{
+ ui.setupUi(this);
+
+ mRulerWidget = new RulerWidget(correctionFactor, this);
+ ui.scrollArea->setWidget(mRulerWidget);
+
+ qreal widthInInch = qApp->desktop()->width() / qApp->desktop()->logicalDpiX();
+ qreal heightInInch = qApp->desktop()->height() / qApp->desktop()->logicalDpiY();
+ mDiagonalInInch = sqrt(pow(widthInInch, 2) + pow(heightInInch, 2));
+ ui.diagonalInInch->setText(QString::number(mDiagonalInInch));
+
+ connect(ui.horizontalSlider, SIGNAL(valueChanged(int)), SLOT(updateCorrectionFromSlider()));
+ connect(ui.cmRadioButton, SIGNAL(toggled(bool)), SLOT(updateUnit()));
+ connect(ui.inchRadioButton, SIGNAL(toggled(bool)), SLOT(updateUnit()));
+ connect(ui.exitButton, SIGNAL(clicked()), SLOT(close()));
+ connect(ui.diagonalInInch, SIGNAL(editingFinished()), SLOT(updateCorrectionFromMonitorValues()));
+ connect(ui.correctionFactorEdit, SIGNAL(editingFinished()), SLOT(updateCorrectionFromLineEdit()));
+ connect(this, SIGNAL(correctionFactorChanged(qreal)), SLOT(updateValues(qreal)));
+ updateValues(mCurrentCorrectionFactor);
+}
+
+ViewConfiguration::~ViewConfiguration()
+{
+
+}
+
+void ViewConfiguration::updateValues(qreal factor)
+{
+ ui.horizontalSlider->setValue(factor * 100);
+ updateLine();
+ ui.correctionFactorEdit->setText(QString::number(factor));
+ ui.diagonalInInch->setText(QString::number(mDiagonalInInch / factor));
+}
+void ViewConfiguration::updateLine()
+{
+ qreal lineWidth;
+ if (mCurrentUnit == Centrimetre)
+ lineWidth = qApp->desktop()->logicalDpiX() / 2.54 * 10 * mCurrentCorrectionFactor;
+ else
+ lineWidth = qApp->desktop()->logicalDpiX() * 4 * mCurrentCorrectionFactor;
+ mRulerWidget->setFixedWidth(lineWidth);
+ ui.scrollArea->setMinimumWidth(lineWidth);
+ mRulerWidget->updateCorrectionFactor(ui.horizontalSlider->value() / 100.);
+}
+
+void ViewConfiguration::updateUnit()
+{
+ if (ui.cmRadioButton->isChecked())
+ mCurrentUnit = Centrimetre;
+ else
+ mCurrentUnit = Inch;
+ mRulerWidget->updateCurrentUnit(mCurrentUnit);
+ updateLine();
+}
+
+void ViewConfiguration::updateCorrectionFromSlider()
+{
+ if (mCurrentCorrectionFactor != ui.horizontalSlider->value() / 100.) {
+ mCurrentCorrectionFactor = ui.horizontalSlider->value() / 100.;
+ emit correctionFactorChanged(mCurrentCorrectionFactor);
+ }
+}
+
+void ViewConfiguration::updateCorrectionFromMonitorValues()
+{
+ mCurrentCorrectionFactor = mDiagonalInInch / ui.diagonalInInch->text().toDouble();
+ if (mCurrentCorrectionFactor > 2)
+ mCurrentCorrectionFactor = 2;
+ else if (mCurrentCorrectionFactor < 0.5)
+ mCurrentCorrectionFactor = 0.5;
+ emit correctionFactorChanged(mCurrentCorrectionFactor);
+}
+
+void ViewConfiguration::updateCorrectionFromLineEdit()
+{
+ qreal newValue = ui.correctionFactorEdit->text().toDouble();
+ if (newValue < 0.5)
+ newValue = 0.5;
+ else if (newValue > 2)
+ newValue = 2;
+ if (mCurrentCorrectionFactor != newValue) {
+ mCurrentCorrectionFactor = newValue;
+ emit correctionFactorChanged(mCurrentCorrectionFactor);
+ }
+}
+
+RulerWidget::RulerWidget(qreal correctionFactor, QWidget *parent)
+ : QWidget(parent)
+ , mCorrectionFactor(correctionFactor)
+ , mCurrentUnit(Centrimetre)
+{
+ setFixedHeight(5);
+}
+
+void RulerWidget::updateCorrectionFactor(qreal newFactor)
+{
+ mCorrectionFactor = newFactor;
+ repaint();
+}
+
+void RulerWidget::updateCurrentUnit(Unit newUnit)
+{
+ mCurrentUnit = newUnit;
+ repaint();
+}
+
+void RulerWidget::paintEvent(QPaintEvent *e)
+{
+ Q_UNUSED(e);
+ QPalette p = QApplication::palette();
+ QPainter painter(this);
+ painter.setPen(Qt::NoPen);
+ qreal oneStep = qApp->desktop()->logicalDpiX() * mCorrectionFactor;;
+ if (mCurrentUnit == Centrimetre)
+ oneStep /= 2.54;
+ qreal drawnWidth = 0;
+ bool highlight = false;
+ painter.setBrush(p.color(QPalette::Shadow));
+ QRectF currentRect = rect();
+ currentRect.setWidth(oneStep);
+ while ((drawnWidth + oneStep)<= rect().width()) {
+ painter.drawRect(currentRect);
+ currentRect.translate(oneStep, 0);
+ drawnWidth += oneStep;
+ if (!highlight)
+ painter.setBrush(p.color(QPalette::Mid));
+ else
+ painter.setBrush(p.color(QPalette::Shadow));
+ highlight ^= 1;
+ }
+ if (drawnWidth < rect().width()) {
+ currentRect.setWidth(rect().width() - drawnWidth);
+ painter.drawRect(currentRect);
+ }
+}
diff --git a/src/ui/viewconfiguration.h b/src/ui/viewconfiguration.h
new file mode 100644
index 0000000..cfec72e
--- /dev/null
+++ b/src/ui/viewconfiguration.h
@@ -0,0 +1,89 @@
+/**************************************************************************
+**
+** This file is part of Qt Simulator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef VIEWCONFIGURATION_H
+#define VIEWCONFIGURATION_H
+
+#include <QDialog>
+#include "ui_viewconfiguration.h"
+
+class QGraphicsLineItem;
+
+enum Unit {
+ Centrimetre,
+ Inch
+};
+
+class RulerWidget: public QWidget
+{
+ Q_OBJECT
+public:
+
+ explicit RulerWidget(qreal correctionFactor = 1, QWidget *parent = 0);
+ void updateCorrectionFactor(qreal newFactor);
+ void updateCurrentUnit(Unit newUnit);
+
+protected:
+ virtual void paintEvent(QPaintEvent *e);
+
+private:
+ qreal mCorrectionFactor;
+ Unit mCurrentUnit;
+};
+
+class ViewConfiguration : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit ViewConfiguration(qreal correctionFactor = 1, QWidget *parent = 0);
+ ~ViewConfiguration();
+
+signals:
+ void correctionFactorChanged(qreal factor);
+
+private slots:
+ void updateValues(qreal factor);
+ void updateLine();
+ void updateUnit();
+
+ void updateCorrectionFromSlider();
+ void updateCorrectionFromMonitorValues();
+ void updateCorrectionFromLineEdit();
+
+private:
+ Ui::ViewConfigurationClass ui;
+
+ qreal mCurrentCorrectionFactor;
+ Unit mCurrentUnit;
+ qreal mDiagonalInInch;
+ RulerWidget *mRulerWidget;
+};
+
+#endif // VIEWCONFIGURATION_H
diff --git a/src/ui/viewconfiguration.ui b/src/ui/viewconfiguration.ui
new file mode 100644
index 0000000..c53f570
--- /dev/null
+++ b/src/ui/viewconfiguration.ui
@@ -0,0 +1,261 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ViewConfigurationClass</class>
+ <widget class="QWidget" name="ViewConfigurationClass">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>275</width>
+ <height>389</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Configuration</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetMinimumSize</enum>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="groupBox_3">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Correction</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QLabel" name="label_4">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Depending on the used operating system and configuration, it is possible that the view's &quot;native size&quot; setting does not reflect the real size of the device. The following two approaches can be used to correct this issue.</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Monitor Values</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="label_7">
+ <property name="text">
+ <string>The correction factor can be calculated with the help of you monitor's diagonal in inch. Just enter the correct value.</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_5">
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Diagonal in inches</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="diagonalInInch"/>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Manual correction</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>The line should have exactly the width given below. If it has not, use the slider to correct its length.</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QWidget" name="unitBox" native="true">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QRadioButton" name="cmRadioButton">
+ <property name="text">
+ <string>10 cm</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="inchRadioButton">
+ <property name="text">
+ <string>4 inch</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QScrollArea" name="scrollArea">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>15</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Plain</enum>
+ </property>
+ <property name="lineWidth">
+ <number>0</number>
+ </property>
+ <property name="verticalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ <property name="horizontalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ <property name="widgetResizable">
+ <bool>true</bool>
+ </property>
+ <widget class="QWidget" name="scrollAreaWidgetContents">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>217</width>
+ <height>16</height>
+ </rect>
+ </property>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSlider" name="horizontalSlider">
+ <property name="minimum">
+ <number>50</number>
+ </property>
+ <property name="maximum">
+ <number>200</number>
+ </property>
+ <property name="value">
+ <number>100</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <item>
+ <spacer name="horizontalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_6">
+ <property name="text">
+ <string>Correction Factor</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="correctionFactorEdit">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="exitButton">
+ <property name="text">
+ <string>Exit</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/stubdata/standardcontacts.vcf b/stubdata/standardcontacts.vcf
new file mode 100644
index 0000000..18f08a9
--- /dev/null
+++ b/stubdata/standardcontacts.vcf
@@ -0,0 +1,373 @@
+BEGIN:VCARD
+PHOTO:images/avatars/yilmaz_emre.png
+FN:Emre Yilmaz
+N:Yilmaz;Emre;;;
+NAME:Emre Yilmaz
+EMAIL:yilmaz@gmail.com
+TEL:+447676982463
+TEL:02065792431
+ADR:;;56 Edmonton Square;Leister;;;UK
+UID:1
+VERSION:3.0
+END:VCARD
+
+BEGIN:VCARD
+PHOTO:images/avatars/wright_caroline.png
+FN:Caroline Wright
+N:Wright;Caroline;;;
+NAME:Caroline Wright
+EMAIL:wrightstuff@tiscali.co.uk
+TEL:07956328190
+ADR:;;28 Dalston Road;London;;E4 8FG;
+UID:2
+VERSION:3.0
+END:VCARD
+
+BEGIN:VCARD
+PHOTO:images/avatars/taylor_steve.png
+FN:Steve Taylor
+N:Taylor;Steve;;;
+NAME:Steve Taylor
+EMAIL:stevetaylor100@hotmail.com
+EMAIL:steve.taylor@orange.com
+TEL:+447765238901
+ADR:;;1987 Great Western Road;Glasgow;;;UK
+UID:3
+VERSION:3.0
+END:VCARD
+
+BEGIN:VCARD
+PHOTO:images/avatars/sorenson_anita.png
+FN:Anita Sorenson
+N:Sorenson;Anita;;;
+NAME:Anita Sorenson
+EMAIL:anitasorenson@aol.com
+TEL:07923409252
+ADR:;;10B Laird Street;Glasgow;;G3 6RD;
+UID:4
+VERSION:3.0
+END:VCARD
+
+BEGIN:VCARD
+PHOTO:images/avatars/shiel_becky.png
+FN:Becky Shiel
+N:Shiel;Becky;;;
+NAME:Becky Shiel
+EMAIL:beckyshiel@tate.org.uk
+TEL:+44782317900
+ADR:;;89C Hackney Road;London;;E8 6NM;
+UID:5
+VERSION:3.0
+END:VCARD
+
+BEGIN:VCARD
+PHOTO:images/avatars/shakiba_nadia.png
+FN:Nadia Shakiba
+N:Shakiba;Nadia;;;
+NAME:Nadia Shakiba
+EMAIL:nadia.shakiba@ovi.com
+TEL:+447906237192
+ADR:;;76 Pierce Grove;Coventry;;;UK
+UID:6
+VERSION:3.0
+END:VCARD
+
+BEGIN:VCARD
+PHOTO:images/avatars/saranouk_suzie.png
+FN:Suzie Saranouk
+N:Saranouk;Suzie;;;
+NAME:Suzie Saranouk
+EMAIL:suzie.saranouk@hotmail.com
+EMAIL:suzie@tastypastries.com
+TEL:02056982179
+ADR:;;69 Riverbank;Liverpool;;;UK
+UID:7
+VERSION:3.0
+END:VCARD
+
+BEGIN:VCARD
+PHOTO:images/avatars/rosencrans_claus.png
+FN:Claus Rosencrans
+N:Rosencrans;Claus;;;
+NAME:Claus Rosencrans
+EMAIL:c.rosencrans@falconindustries.com
+TEL:+442076892013
+ADR:;;45 High Street;Chester;;;UK
+UID:8
+VERSION:3.0
+END:VCARD
+
+BEGIN:VCARD
+PHOTO:images/avatars/paul_lisa.png
+FN:Lisa Paul
+N:Paul;Lisa;;;
+NAME:Lisa Paul
+EMAIL:lisa.paul@ovi.com
+TEL:07612984270
+ADR:;;29 Acacia Gardens;Slough;;;UK
+UID:9
+VERSION:3.0
+END:VCARD
+
+BEGIN:VCARD
+PHOTO:images/avatars/noble_emily.png
+FN:Emily Noble
+N:Noble;Emily;;;
+NAME:Emily Noble
+EMAIL:emily.noble@yahoo.co.uk
+EMAIL:emily@dcs.co.uk
+TEL:+44752361790
+ADR:;;12 Edinburgh Road;London;;E17 6DM;
+UID:10
+VERSION:3.0
+END:VCARD
+
+BEGIN:VCARD
+PHOTO:images/avatars/nanette_melissa.png
+FN:Melissa Nanette
+N:Nanette;Melissa;;;
+NAME:Melissa Nanette
+EMAIL:melnan@gmail.com
+EMAIL:melissa@orange.com
+TEL:07843729817
+ADR:;;1 Freemantle Street;Coventry;;;UK
+UID:11
+VERSION:3.0
+END:VCARD
+
+BEGIN:VCARD
+PHOTO:images/avatars/mccallum_sarah.png
+FN:Sarah McCallum
+N:McCallum;Sarah;;;
+NAME:Sarah McCallum
+EMAIL:sarahmc@tiscali.co.uk
+TEL:+447923461089
+ADR:;;10B Laird Street;Glasgow;;G3 6RD;
+UID:12
+VERSION:3.0
+END:VCARD
+
+BEGIN:VCARD
+PHOTO:images/avatars/mason_mary.png
+FN:Mary Mason
+N:Mason;Mary;;;
+NAME:Mary Mason
+EMAIL:marymason@hotmail.com
+TEL:020568725219
+ADR:;;12 Davis Close;Wimbledon;;;London
+UID:13
+VERSION:3.0
+END:VCARD
+
+BEGIN:VCARD
+PHOTO:images/avatars/marks_harry.png
+FN:Harry Marks
+N:Marks;Harry;;;
+NAME:Harry Marks
+EMAIL:hmarks@marksandson.co.uk
+EMAIL:harrymarks@gmail.com
+TEL:07902346182
+ADR:;;98 Conifer Drive;Bury St Edmunds;;;Sussex
+UID:14
+VERSION:3.0
+END:VCARD
+
+BEGIN:VCARD
+PHOTO:images/avatars/jameson_tyrone.png
+FN:Tyrone Jameson
+N:Jameson;Tyrone;;;
+NAME:Tyrone Jameson
+EMAIL:tyronej@ovi.com
+TEL:+447512349825
+ADR:;;Flat 4;143 Peckam High Street;;;London
+UID:15
+VERSION:3.0
+END:VCARD
+
+BEGIN:VCARD
+PHOTO:images/avatars/jain_paresh.png
+FN:Paresh Jain
+N:Jain;Paresh;;;
+NAME:Paresh Jain
+EMAIL:pareshjain@hotmail.com
+TEL:+447908252685
+ADR:;;Flat 4;143 Peckam High Street;;;London
+UID:16
+VERSION:3.0
+END:VCARD
+
+BEGIN:VCARD
+PHOTO:images/avatars/hope_darlia.png
+FN:Dalia Hope
+N:Hope;Dalia;;;
+NAME:Dalia Hope
+EMAIL:dalia@hopeandgloria.com
+EMAIL:daliahope@tiscali.co.uk
+TEL:+44205639021
+ADR:;;121;;;;
+UID:17
+VERSION:3.0
+END:VCARD
+
+BEGIN:VCARD
+PHOTO:images/avatars/hernandez_adriana.png
+FN:Adriana Hernandez
+N:Hernandez;Adriana;;;
+NAME:Adriana Hernandez
+EMAIL:adriana.hernandez@gmail.com
+TEL:+932218200
+ADR:;;Avenida Icaria 195;08005 Barcelona;;;Spain
+UID:18
+VERSION:3.0
+END:VCARD
+
+BEGIN:VCARD
+PHOTO:images/avatars/henderson_ben.png
+FN:Ben Henderson
+N:Henderson;Ben;;;
+NAME:Ben Henderson
+EMAIL:ben@hopebikes.com
+TEL:+447592020111
+ADR:;;11 Headingley Road;Leeds;;;UK
+UID:19
+VERSION:3.0
+END:VCARD
+
+BEGIN:VCARD
+PHOTO:images/avatars/hansel_justus.png
+FN:Justus Hansel
+N:Hansel;Justus;;;
+NAME:Justus Hansel
+EMAIL:justus.hansel@hotmail.com
+TEL:+447628262802
+ADR:;;90 Dalbert Road;London;;W14 8GH;
+UID:20
+VERSION:3.0
+END:VCARD
+
+BEGIN:VCARD
+PHOTO:images/avatars/george_kim.png
+FN:Kim George
+N:George;Kim;;;
+NAME:Kim George
+EMAIL:kimgeorge@gmail.com
+EMAIL:kim@thelittleshop.co.uk
+TEL:+44780925292
+TEL:02056857291
+ADR:;;89C Hackney Road;London;;E8 6NM;
+UID:21
+VERSION:3.0
+END:VCARD
+
+BEGIN:VCARD
+PHOTO:images/avatars/ganesvoort_daatje.png
+FN:Daatje Ganesvoort
+N:Ganesvoort;Daatje;;;
+NAME:Daatje Ganesvoort
+EMAIL:d.ganesvoort@blythandhiggins.co.uk
+TEL:+44786262892
+ADR:;;65 Hampstead Mansions;London;;N1 4RG;
+UID:22
+VERSION:3.0
+END:VCARD
+
+BEGIN:VCARD
+PHOTO:images/avatars/davis_tina.png
+FN:Tina Davis
+N:Davis;Tina;;;
+NAME:Tina Davis
+EMAIL:tinadavis@hotmail.com
+TEL:0765271991
+ADR:;;10B Laird Street;Glasgow;;G3 6RD;
+UID:23
+VERSION:3.0
+END:VCARD
+
+BEGIN:VCARD
+PHOTO:images/avatars/dalby_elaine.png
+FN:Elaine Dalby
+N:Dalby;Elaine;;;
+NAME:Elaine Dalby
+EMAIL:elaine@dalbydj.co.uk
+TEL:+447908635241
+ADR:;;89 Terrence Street;Bristol;;;UK
+UID:24
+VERSION:3.0
+END:VCARD
+
+BEGIN:VCARD
+PHOTO:images/avatars/charles_betty.png
+FN:Betty Charles
+N:Charles;Betty;;;
+NAME:Betty Charles
+EMAIL:betty.charles@blythandhiggins.co.uk
+EMAIL:bcharley@yahoo.com
+TEL:07954637251
+TEL:+442056572312
+ADR:;;65 Hampstead Mansions;London;;N1 4RG;
+UID:25
+VERSION:3.0
+END:VCARD
+
+BEGIN:VCARD
+PHOTO:images/avatars/chee_dan.png
+FN:Dan Chee
+N:Chee;Dan;;;
+NAME:Dan Chee
+EMAIL:danchee4@yahoo.com
+TEL:079852629191
+ADR:;;143 Defoe Road;Chester;;;UK
+UID:26
+VERSION:3.0
+END:VCARD
+
+BEGIN:VCARD
+PHOTO:images/avatars/cansai_lakshya.png
+FN:Lakshya Cansai
+N:Cansai;Lakshya;;;
+NAME:Lakshya Cansai
+EMAIL:lakshya@googlemail.com
+TEL:+17563828903
+ADR:;;1600 Pennsylvania Avenue;Boston;;;USA
+UID:27
+VERSION:3.0
+END:VCARD
+
+BEGIN:VCARD
+PHOTO:images/avatars/banks_jules.png
+FN:Jules Banks
+N:Banks;Jules;;;
+NAME:Jules Banks
+EMAIL:julez86@yahoo.co.uk
+TEL:+447892562421
+ADR:;;187 Churchill Street;Brighton;;B13 6TF;
+UID:28
+VERSION:3.0
+END:VCARD
+
+BEGIN:VCARD
+PHOTO:images/avatars/adeyemo_fred.png
+FN:Fred Adeyemo
+N:Adeyemo;Fred;;;
+NAME:Fred Adeyemo
+EMAIL:fred.adeyemo@troll.no
+TEL:+3587654321
+ADR:;;Sandakerveien 116;Oslo;;;Norway
+UID:29
+VERSION:3.0
+END:VCARD
+
+BEGIN:VCARD
+PHOTO:images/avatars/ackert_boris.png
+FN:Boris Ackert
+N:Ackert;Boris;;;
+NAME:Boris Ackert
+EMAIL:borisackert@hotmail.com
+EMAIL:boris@backert.com
+TEL:+4456428724
+TEL:+442087624272
+ADR:;;15 Blackhill Cresent;London;;SW11 5DF;
+UID:30
+VERSION:3.0
+END:VCARD
+
diff --git a/stubdata/standardmessages/testmessage b/stubdata/standardmessages/testmessage
new file mode 100644
index 0000000..3f05225
--- /dev/null
+++ b/stubdata/standardmessages/testmessage
@@ -0,0 +1,7 @@
+From: simulator@example.com
+To: user@example.com
+Subject: Test message
+Content-Type: text/plain
+Date: Thu, 4 Mar 2010 13:44:48 +0100
+
+This is a test message.
diff --git a/stubdata/standardselfcontact.vcf b/stubdata/standardselfcontact.vcf
new file mode 100644
index 0000000..91e49d8
--- /dev/null
+++ b/stubdata/standardselfcontact.vcf
@@ -0,0 +1,10 @@
+BEGIN:VCARD
+FN:Self Simulator
+N:Simulator;Self;;;
+NAME:Self Simulator
+EMAIL:selfcontact@example.com
+TEL:+44123456789
+ADR:;;56 Edmonton Square;Leister;;;UK
+UID:0
+VERSION:3.0
+END:VCARD