on xenial help sign in
Merge
2be1452Albert Astals
CMakeLists.txt+2
@@ -96,6 +96,7 @@ include(autopilot)
96declare_autopilot_test(shell unity8.shell ${CMAKE_SOURCE_DIR}/tests/autopilot/)
96declare_autopilot_test(shell unity8.shell ${CMAKE_SOURCE_DIR}/tests/autopilot/)
97
97
98set(SHELL_APP unity8)
98set(SHELL_APP unity8)
99+set(SCOPE_TOOL unity-scope-tool)
99
100
100include_directories(
101include_directories(
101 ${CMAKE_SOURCE_DIR}/include
102 ${CMAKE_SOURCE_DIR}/include
@@ -105,6 +106,7 @@ include_directories(
105# add subdirectories to build
106# add subdirectories to build
106add_subdirectory(include)
107add_subdirectory(include)
107add_subdirectory(src)
108add_subdirectory(src)
109+add_subdirectory(tools)
108add_subdirectory(qml)
110add_subdirectory(qml)
109add_subdirectory(tests)
111add_subdirectory(tests)
110add_subdirectory(plugins)
112add_subdirectory(plugins)
data/CMakeLists.txt+3−2
@@ -1,7 +1,8 @@
1# generate desktop file
1# generate desktop file
2configure_file(${SHELL_APP}.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/${SHELL_APP}.desktop @ONLY)
2configure_file(${SHELL_APP}.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/${SHELL_APP}.desktop @ONLY)
3+configure_file(${SCOPE_TOOL}.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/${SCOPE_TOOL}.desktop @ONLY)
3
4
4−# install desktop file
5+# install desktop files
5−install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SHELL_APP}.desktop
6+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SHELL_APP}.desktop ${CMAKE_CURRENT_BINARY_DIR}/${SCOPE_TOOL}.desktop
6 DESTINATION ${CMAKE_INSTALL_DATADIR}/applications
7 DESTINATION ${CMAKE_INSTALL_DATADIR}/applications
7 )
8 )
data/unity-scope-tool.desktop.innew file+8
@@ -0,0 +1,8 @@
1+[Desktop Entry]
2+Type=Application
3+Name=Unity Scope Tool
4+Comment=Developer tool for Unity scopes.
5+Exec=@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@/unity-scope-tool
6+Terminal=false
7+Icon=unity-scope-tool
8+X-Ubuntu-Touch=true
debian/control+9
@@ -59,6 +59,15 @@ Depends: qmenumodel-qml (>= 0.2.7),
59Description: Indicators client test application
59Description: Indicators client test application
60 This package contains the client application for indicators used by autopilot
60 This package contains the client application for indicators used by autopilot
61
61
62+Package: unity-scope-tool
63+Architecture: any
64+Depends: unity8 (= ${binary:Version}),
65+ ${misc:Depends},
66+ ${shlibs:Depends},
67+Description: Development tool for Unity scopes
68+ This package contains the development tool for new generation Unity scopes, based
69+ on Unity8.
70+
62Package: unity8
71Package: unity8
63Architecture: any
72Architecture: any
64Provides: indicator-renderer,
73Provides: indicator-renderer,
debian/unity-scope-tool.installnew file+3
@@ -0,0 +1,3 @@
1+usr/bin/unity-scope-tool
2+usr/share/applications/unity-scope-tool.desktop
3+usr/share/unity8/ScopeTool.qml
po/hu.po+30−26
@@ -8,61 +8,65 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-11-29 09:21+0100\n"
10"POT-Creation-Date: 2013-11-29 09:21+0100\n"
11−"PO-Revision-Date: 2013-06-27 04:28+0000\n"
11+"PO-Revision-Date: 2014-01-04 15:30+0000\n"
12−"Last-Translator: Michał Sawicz <michal.sawicz@canonical.com>\n"
12+"Last-Translator: Péter MÁTÓ <mato.peter@gmail.com>\n"
13"Language-Team: Hungarian <hu@li.org>\n"
13"Language-Team: Hungarian <hu@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2013-12-29 06:04+0000\n"
18+"X-Launchpad-Export-Date: 2014-01-05 05:50+0000\n"
19"X-Generator: Launchpad (build 16877)\n"
19"X-Generator: Launchpad (build 16877)\n"
20
20
21#: Components/EdgeDemoOverlay.qml:151
21#: Components/EdgeDemoOverlay.qml:151
22msgid "Skip intro"
22msgid "Skip intro"
23−msgstr ""
23+msgstr "A bemutató kihagyása"
24
24
25#: Components/EdgeDemo.qml:112
25#: Components/EdgeDemo.qml:112
26msgid "Right edge"
26msgid "Right edge"
27−msgstr ""
27+msgstr "Jobb szél"
28
28
29#: Components/EdgeDemo.qml:113
29#: Components/EdgeDemo.qml:113
30msgid "Try swiping from the right edge to unlock the phone"
30msgid "Try swiping from the right edge to unlock the phone"
31−msgstr ""
31+msgstr "A telefon feloldásához csúsztassa ujját a jobb szélről"
32
32
33#: Components/EdgeDemo.qml:144
33#: Components/EdgeDemo.qml:144
34msgid "Top edge"
34msgid "Top edge"
35−msgstr ""
35+msgstr "Felső szél"
36
36
37#: Components/EdgeDemo.qml:145
37#: Components/EdgeDemo.qml:145
38msgid "Try swiping from the top edge to access the indicators"
38msgid "Try swiping from the top edge to access the indicators"
39−msgstr ""
39+msgstr "A jelzők eléréséhez csúsztassa ujját a felső szélről"
40
40
41#: Components/EdgeDemo.qml:170
41#: Components/EdgeDemo.qml:170
42msgid "Close"
42msgid "Close"
43−msgstr ""
43+msgstr "Bezárás"
44
44
45#: Components/EdgeDemo.qml:171
45#: Components/EdgeDemo.qml:171
46msgid "Swipe up again to close the settings screen"
46msgid "Swipe up again to close the settings screen"
47−msgstr ""
47+msgstr "A beállítások bezárásához csúsztassa ujját újra felfelé"
48
48
49#: Components/EdgeDemo.qml:198
49#: Components/EdgeDemo.qml:198
50msgid "Left edge"
50msgid "Left edge"
51−msgstr ""
51+msgstr "Bal szél"
52
52
53#: Components/EdgeDemo.qml:199
53#: Components/EdgeDemo.qml:199
54msgid "Swipe from the left to reveal the launcher for quick access to apps"
54msgid "Swipe from the left to reveal the launcher for quick access to apps"
55msgstr ""
55msgstr ""
56+"Csúsztassa ujját a bal szélről az indítón található alkalmazások gyors "
57+"eléréséhez"
56
58
57#: Components/EdgeDemo.qml:226
59#: Components/EdgeDemo.qml:226
58msgid "Well done"
60msgid "Well done"
59−msgstr ""
61+msgstr "Rendben"
60
62
61#: Components/EdgeDemo.qml:227
63#: Components/EdgeDemo.qml:227
62msgid ""
64msgid ""
63"You have now mastered the edge gestures and can start using the "
65"You have now mastered the edge gestures and can start using the "
64"phone<br><br>Tap anywhere to start"
66"phone<br><br>Tap anywhere to start"
65msgstr ""
67msgstr ""
68+"Miután megismerte a szélek használatát, nincs más hátra...<br><br>Koppintson "
69+"a folytatáshoz!"
66
70
67#: Components/PageHeader.qml:364
71#: Components/PageHeader.qml:364
68msgid "Recent searches"
72msgid "Recent searches"
@@ -70,50 +74,50 @@ msgstr "Legutóbbi keresések"
70
74
71#: Dash/Apps/AppPreview.qml:135
75#: Dash/Apps/AppPreview.qml:135
72msgid "Rate this"
76msgid "Rate this"
73−msgstr ""
77+msgstr "Osztályzás"
74
78
75#. TRANSLATORS: Number of persons who rated this app/video/whatever
79#. TRANSLATORS: Number of persons who rated this app/video/whatever
76#: Dash/Previews/Header.qml:93
80#: Dash/Previews/Header.qml:93
77#, qt-format
81#, qt-format
78msgid "(%1)"
82msgid "(%1)"
79−msgstr ""
83+msgstr "(%1)"
80
84
81#. TRANSLATORS: Number of persons who wrote reviews for this app/video/whatever
85#. TRANSLATORS: Number of persons who wrote reviews for this app/video/whatever
82#: Dash/Previews/Header.qml:105
86#: Dash/Previews/Header.qml:105
83#, qt-format
87#, qt-format
84msgid "%1 review"
88msgid "%1 review"
85msgid_plural "%1 reviews"
89msgid_plural "%1 reviews"
86−msgstr[0] ""
90+msgstr[0] "%1 értékelés"
87−msgstr[1] ""
91+msgstr[1] "%1 értékelés"
88
92
89#: Dash/Previews/Reviews.qml:74
93#: Dash/Previews/Reviews.qml:74
90msgid "Add a review"
94msgid "Add a review"
91−msgstr ""
95+msgstr "Értékelés hozzáadása"
92
96
93#: Dash/Previews/Reviews.qml:86
97#: Dash/Previews/Reviews.qml:86
94msgid "Review"
98msgid "Review"
95−msgstr ""
99+msgstr "Értékelés"
96
100
97#: Dash/Previews/Reviews.qml:121
101#: Dash/Previews/Reviews.qml:121
98msgid "Send"
102msgid "Send"
99−msgstr ""
103+msgstr "Küldés"
100
104
101#: Dash/Previews/Reviews.qml:139
105#: Dash/Previews/Reviews.qml:139
102msgid "Comments:"
106msgid "Comments:"
103−msgstr ""
107+msgstr "Hozzászólások:"
104
108
105#: Greeter/Lockscreen.qml:149
109#: Greeter/Lockscreen.qml:149
106msgid "Emergency Call"
110msgid "Emergency Call"
107−msgstr ""
111+msgstr "Vészhívás"
108
112
109#: Greeter/PassphraseLockscreen.qml:59
113#: Greeter/PassphraseLockscreen.qml:59
110#, qt-format
114#, qt-format
111msgid "Hello %1"
115msgid "Hello %1"
112−msgstr ""
116+msgstr "Szia %1"
113
117
114#: Greeter/PassphraseLockscreen.qml:59
118#: Greeter/PassphraseLockscreen.qml:59
115msgid "Hello"
119msgid "Hello"
116−msgstr ""
120+msgstr "Szia"
117
121
118#: Hud/HudParametrizedActionsPage.qml:132
122#: Hud/HudParametrizedActionsPage.qml:132
119msgid "Confirm"
123msgid "Confirm"
@@ -137,7 +141,7 @@ msgstr "Beszéd…"
137
141
138#: Notifications/NotificationMenuItemFactory.qml:89
142#: Notifications/NotificationMenuItemFactory.qml:89
139msgid "Show password"
143msgid "Show password"
140−msgstr ""
144+msgstr "Jelszó megjelenítése"
141
145
142#: Panel/SearchIndicator.qml:27
146#: Panel/SearchIndicator.qml:27
143msgid "Search"
147msgid "Search"
@@ -146,11 +150,11 @@ msgstr "Keresés"
146#: plugins/Unity/Launcher/launcheritem.cpp:43
150#: plugins/Unity/Launcher/launcheritem.cpp:43
147#: plugins/Unity/Launcher/launcheritem.cpp:73
151#: plugins/Unity/Launcher/launcheritem.cpp:73
148msgid "Lock to Launcher"
152msgid "Lock to Launcher"
149−msgstr ""
153+msgstr "Indítóban tartás"
150
154
151#: plugins/Unity/Launcher/launcheritem.cpp:73
155#: plugins/Unity/Launcher/launcheritem.cpp:73
152msgid "Unlock from Launcher"
156msgid "Unlock from Launcher"
153−msgstr ""
157+msgstr "Eltávolítás az Indítóból"
154
158
155#: Shell.qml:439
159#: Shell.qml:439
156#, qt-format
160#, qt-format
po/ru.po+8−7
@@ -8,15 +8,15 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2013-11-29 09:21+0100\n"
10"POT-Creation-Date: 2013-11-29 09:21+0100\n"
11−"PO-Revision-Date: 2013-10-01 05:55+0000\n"
11+"PO-Revision-Date: 2014-01-07 05:21+0000\n"
12−"Last-Translator: Zonov Roman <Unknown>\n"
12+"Last-Translator: Ivlev Denis <Unknown>\n"
13"Language-Team: Russian <ru@li.org>\n"
13"Language-Team: Russian <ru@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
17"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
18"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
18"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
19−"X-Launchpad-Export-Date: 2013-12-29 06:04+0000\n"
19+"X-Launchpad-Export-Date: 2014-01-07 05:33+0000\n"
20"X-Generator: Launchpad (build 16877)\n"
20"X-Generator: Launchpad (build 16877)\n"
21
21
22#: Components/EdgeDemoOverlay.qml:151
22#: Components/EdgeDemoOverlay.qml:151
@@ -89,7 +89,8 @@ msgstr "(%1)"
89#, qt-format
89#, qt-format
90msgid "%1 review"
90msgid "%1 review"
91msgid_plural "%1 reviews"
91msgid_plural "%1 reviews"
92−msgstr[0] "%1 отзыв"
92+msgstr[0] "%1 отзыва"
93+msgstr[1] "%1 отзывов"
93
94
94#: Dash/Previews/Reviews.qml:74
95#: Dash/Previews/Reviews.qml:74
95msgid "Add a review"
96msgid "Add a review"
@@ -142,7 +143,7 @@ msgstr "Говорите..."
142
143
143#: Notifications/NotificationMenuItemFactory.qml:89
144#: Notifications/NotificationMenuItemFactory.qml:89
144msgid "Show password"
145msgid "Show password"
145−msgstr ""
146+msgstr "Показать пароль"
146
147
147#: Panel/SearchIndicator.qml:27
148#: Panel/SearchIndicator.qml:27
148msgid "Search"
149msgid "Search"
@@ -151,11 +152,11 @@ msgstr "Поиск"
151#: plugins/Unity/Launcher/launcheritem.cpp:43
152#: plugins/Unity/Launcher/launcheritem.cpp:43
152#: plugins/Unity/Launcher/launcheritem.cpp:73
153#: plugins/Unity/Launcher/launcheritem.cpp:73
153msgid "Lock to Launcher"
154msgid "Lock to Launcher"
154−msgstr ""
155+msgstr "Закрепить на панели"
155
156
156#: plugins/Unity/Launcher/launcheritem.cpp:73
157#: plugins/Unity/Launcher/launcheritem.cpp:73
157msgid "Unlock from Launcher"
158msgid "Unlock from Launcher"
158−msgstr ""
159+msgstr "Убрать с панели"
159
160
160#: Shell.qml:439
161#: Shell.qml:439
161#, qt-format
162#, qt-format
qml/Components/PageHeader.qml+1−2
@@ -117,9 +117,8 @@ Item {
117
117
118 function openPopover() {
118 function openPopover() {
119 if (searchHistory.count > 0) {
119 if (searchHistory.count > 0) {
120− searchContainer.popover = PopupUtils.open(popoverComponent, searchField,
120+ searchContainer.popover = PopupUtils.open(popoverComponent, pointerPositioner,
121 {
121 {
122− "pointerTarget": pointerPositioner,
123 "contentWidth": searchField.width,
122 "contentWidth": searchField.width,
124 "edgeMargins": units.gu(1)
123 "edgeMargins": units.gu(1)
125 }
124 }
qml/Notifications/Notification.qml+5−2
@@ -106,8 +106,11 @@ Item {
106
106
107 anchors.fill: contentColumn
107 anchors.fill: contentColumn
108 objectName: "interactiveArea"
108 objectName: "interactiveArea"
109+ onClicked: {
109− enabled: notification.type == Notification.Interactive
110+ if (notification.type == Notification.Interactive) {
110− onClicked: notification.notification.invokeAction(actionRepeater.itemAt(0).actionId)
111+ notification.notification.invokeAction(actionRepeater.itemAt(0).actionId)
112+ }
113+ }
111 }
114 }
112
115
113 Column {
116 Column {
qml/Panel/IndicatorItem.qml−13
@@ -23,7 +23,6 @@ Item {
23 id: indicatorItem
23 id: indicatorItem
24
24
25 property alias widgetSource: loader.source
25 property alias widgetSource: loader.source
26− property bool highlighted: false
27 property bool dimmed: false
26 property bool dimmed: false
28 property var indicatorProperties: undefined
27 property var indicatorProperties: undefined
29 property bool indicatorVisible: loader.item ? loader.item.enabled : false
28 property bool indicatorVisible: loader.item ? loader.item.enabled : false
@@ -46,16 +45,4 @@ Item {
46 }
45 }
47 }
46 }
48 }
47 }
49−
50− Rectangle {
51− color: Theme.palette.selected.foreground
52− objectName: "highlight"
53− height: units.dp(2)
54− width: parent.width
55− anchors.top: parent.bottom
56− visible: highlighted
57−
58− opacity: highlighted ? 1 : 0
59− Behavior on opacity { StandardAnimation {} }
60− }
61}
48}
qml/Panel/IndicatorRow.qml+39−8
@@ -29,6 +29,8 @@ Item {
29 property var visibleIndicators: defined
29 property var visibleIndicators: defined
30 property int overFlowWidth: width
30 property int overFlowWidth: width
31 property bool showAll: false
31 property bool showAll: false
32+ property real currentItemOffset: 0.0
33+ property real unitProgress: 0.0
32
34
33 width: units.gu(40)
35 width: units.gu(40)
34 height: units.gu(3)
36 height: units.gu(3)
@@ -79,23 +81,23 @@ Item {
79 height: indicatorRow.height
81 height: indicatorRow.height
80 width: indicatorItem.width
82 width: indicatorItem.width
81 visible: indicatorItem.indicatorVisible
83 visible: indicatorItem.indicatorVisible
82− opacity: 1.0
84+ opacity: 1.0 * opacityMultiplier
83 y: 0
85 y: 0
84 state: "standard"
86 state: "standard"
85
87
86 property int ownIndex: index
88 property int ownIndex: index
87− property alias highlighted: indicatorItem.highlighted
89+ property bool highlighted: indicatorRow.state != "initial" ? ownIndex == indicatorRow.currentItemIndex : false
88− property alias dimmed: indicatorItem.dimmed
90+ property bool dimmed: indicatorRow.state != "initial" ? ownIndex != indicatorRow.currentItemIndex : false
89
91
90− property bool hidden: !showAll && !indicatorItem.highlighted && (indicatorRow.state == "locked" || indicatorRow.state == "commit")
92+ property bool hidden: !showAll && !highlighted && (indicatorRow.state == "locked" || indicatorRow.state == "commit")
91 property bool overflow: row.width - itemWrapper.x > overFlowWidth
93 property bool overflow: row.width - itemWrapper.x > overFlowWidth
94+ property real opacityMultiplier: highlighted ? 1 : (1 - indicatorRow.unitProgress)
92
95
93 IndicatorItem {
96 IndicatorItem {
94 id: indicatorItem
97 id: indicatorItem
95 height: parent.height
98 height: parent.height
96
99
97− highlighted: indicatorRow.state != "initial" ? itemWrapper.ownIndex == indicatorRow.currentItemIndex : false
100+ dimmed: itemWrapper.dimmed
98− dimmed: indicatorRow.state != "initial" ? itemWrapper.ownIndex != indicatorRow.currentItemIndex : false
99
101
100 widgetSource: model.widgetSource
102 widgetSource: model.widgetSource
101 indicatorProperties : model.indicatorProperties
103 indicatorProperties : model.indicatorProperties
@@ -135,14 +137,43 @@ Item {
135
137
136 transitions: [
138 transitions: [
137 Transition {
139 Transition {
138− StandardAnimation {
140+ UbuntuNumberAnimation {
139 target: itemWrapper
141 target: itemWrapper
140 property: "opacity"
142 property: "opacity"
141− duration: 300
143+ duration: UbuntuAnimation.BriskDuration
142 }
144 }
143 }
145 }
144 ]
146 ]
145 }
147 }
146 }
148 }
147 }
149 }
150+
151+ Rectangle {
152+ id: highlight
153+ color: Theme.palette.selected.foreground
154+ objectName: "highlight"
155+ height: units.dp(2)
156+ anchors.top: row.bottom
157+ visible: indicatorRow.currentItem != null
158+ x: row.x + (indicatorRow.currentItem != null ? indicatorRow.currentItem.x + centerOffset : 0)
159+ width: indicatorRow.currentItem != null ? indicatorRow.currentItem.width : 0
160+
161+ property real centerOffset: {
162+ if (indicatorRow.currentItemOffset > 0.1) {
163+ return (indicatorRow.currentItemOffset - 0.1) * units.gu(0.4);
164+ } else if (indicatorRow.currentItemOffset < -0.1) {
165+ return (indicatorRow.currentItemOffset + 0.1) * units.gu(0.4);
166+ }
167+ return 0.0;
168+ }
169+
170+ Behavior on width {
171+ enabled: unitProgress > 0;
172+ UbuntuNumberAnimation { duration: UbuntuAnimation.FastDuration }
173+ }
174+ Behavior on x {
175+ enabled: unitProgress > 0;
176+ UbuntuNumberAnimation { duration: UbuntuAnimation.FastDuration }
177+ }
178+ }
148}
179}
qml/Panel/Indicators.qml+22−11
@@ -39,6 +39,7 @@ Showable {
39 property bool contentEnabled: true
39 property bool contentEnabled: true
40 property bool initalizeItem: true
40 property bool initalizeItem: true
41 readonly property alias content: menuContent
41 readonly property alias content: menuContent
42+ property real unitProgress: 0.0
42
43
43 // TODO: Perhaps we need a animation standard for showing/hiding? Each showable seems to
44 // TODO: Perhaps we need a animation standard for showing/hiding? Each showable seems to
44 // use its own values. Need to ask design about this.
45 // use its own values. Need to ask design about this.
@@ -128,23 +129,31 @@ Showable {
128 rowCoordinates = indicatorRow.mapToItem(indicatorRow.row, xValue, 0);
129 rowCoordinates = indicatorRow.mapToItem(indicatorRow.row, xValue, 0);
129 // get the current delegate
130 // get the current delegate
130 currentItem = indicatorRow.row.childAt(rowCoordinates.x, 0);
131 currentItem = indicatorRow.row.childAt(rowCoordinates.x, 0);
131− if (currentItem && currentItem != indicatorRow.currentItem ) {
132+ if (currentItem) {
132 itemCoordinates = indicatorRow.row.mapToItem(currentItem, rowCoordinates.x, 0);
133 itemCoordinates = indicatorRow.row.mapToItem(currentItem, rowCoordinates.x, 0);
133 distanceFromRightEdge = (currentItem.width - itemCoordinates.x) / (currentItem.width);
134 distanceFromRightEdge = (currentItem.width - itemCoordinates.x) / (currentItem.width);
135+ if (currentItem != indicatorRow.currentItem) {
134− if (Math.abs(currentItem.ownIndex - indicatorRow.currentItemIndex) > 1) {
136+ if (Math.abs(currentItem.ownIndex - indicatorRow.currentItemIndex) > 1) {
135− bufferExceeded = true;
136− } else {
137− if (indicatorRow.currentItemIndex < currentItem.ownIndex && distanceFromRightEdge < (1 - effectiveBufferThreshold)) {
138− bufferExceeded = true;
139− } else if (indicatorRow.currentItemIndex > currentItem.ownIndex && distanceFromRightEdge > effectiveBufferThreshold) {
140 bufferExceeded = true;
137 bufferExceeded = true;
138+ } else {
139+ if (indicatorRow.currentItemIndex < currentItem.ownIndex && distanceFromRightEdge < (1 - effectiveBufferThreshold)) {
140+ bufferExceeded = true;
141+ } else if (indicatorRow.currentItemIndex > currentItem.ownIndex && distanceFromRightEdge > effectiveBufferThreshold) {
142+ bufferExceeded = true;
143+ }
141 }
144 }
145+ if ((!useBuffer || (useBuffer && bufferExceeded)) || indicatorRow.currentItemIndex < 0 || indicatorRow.currentItem == null) {
146+ indicatorRow.currentItem = currentItem;
147+ }
148+
149+ // need to re-init the distanceFromRightEdge for offset calculation
150+ itemCoordinates = indicatorRow.row.mapToItem(indicatorRow.currentItem, rowCoordinates.x, 0);
151+ distanceFromRightEdge = (indicatorRow.currentItem.width - itemCoordinates.x) / (indicatorRow.currentItem.width);
142 }
152 }
143− if ((!useBuffer || (useBuffer && bufferExceeded)) || indicatorRow.currentItem < 0 || indicatorRow.currentItem == null) {
153+ indicatorRow.currentItemOffset = 1 - (distanceFromRightEdge * 2);
144− indicatorRow.currentItem = currentItem;
154+ } else {
145− }
146− } else if (!currentItem) {
147 indicatorRow.setDefaultItem();
155 indicatorRow.setDefaultItem();
156+ indicatorRow.currentItemOffset = 0;
148 }
157 }
149 initalizeItem = indicatorRow.currentItem == null;
158 initalizeItem = indicatorRow.currentItem == null;
150 }
159 }
@@ -268,6 +277,7 @@ Showable {
268 height: indicators.panelHeight
277 height: indicators.panelHeight
269 indicatorsModel: indicatorsModel
278 indicatorsModel: indicatorsModel
270 state: indicators.state
279 state: indicators.state
280+ unitProgress: indicators.unitProgress
271
281
272 Connections {
282 Connections {
273 property bool enableIndexChangeSignal: true
283 property bool enableIndexChangeSignal: true
@@ -326,6 +336,7 @@ Showable {
326 if (hideAnimation.running) {
336 if (hideAnimation.running) {
327 indicators.state = "initial";
337 indicators.state = "initial";
328 initalizeItem = true;
338 initalizeItem = true;
339+ menuContent.animateNextMenuChange = false;
329 }
340 }
330 }
341 }
331 }
342 }
qml/Panel/MenuContent.qml+3−1
@@ -33,6 +33,7 @@ MainView {
33 property int contentReleaseInterval: 20000
33 property int contentReleaseInterval: 20000
34 property bool activeHeader: false
34 property bool activeHeader: false
35 property alias visibleIndicators: visibleIndicatorsModel.visible
35 property alias visibleIndicators: visibleIndicatorsModel.visible
36+ property bool animateNextMenuChange: false
36
37
37 width: units.gu(40)
38 width: units.gu(40)
38 height: units.gu(42)
39 height: units.gu(42)
@@ -41,11 +42,12 @@ MainView {
41 var filteredIndex = filteredIndicators.mapFromSource(index)
42 var filteredIndex = filteredIndicators.mapFromSource(index)
42
43
43 if (tabs.selectedTabIndex !== filteredIndex) {
44 if (tabs.selectedTabIndex !== filteredIndex) {
44− if (tabs.selectedTabIndex == -1) {
45+ if (tabs.selectedTabIndex == -1 || !animateNextMenuChange) {
45 tabs.tabBar.animate = false;
46 tabs.tabBar.animate = false;
46 }
47 }
47 tabs.selectedTabIndex = filteredIndex;
48 tabs.selectedTabIndex = filteredIndex;
48 tabs.tabBar.animate = true;
49 tabs.tabBar.animate = true;
50+ animateNextMenuChange = true;
49 }
51 }
50 }
52 }
51
53
qml/Panel/Panel.qml+1−1
@@ -107,7 +107,7 @@ Item {
107 pinnedMode: !fullscreenMode
107 pinnedMode: !fullscreenMode
108 overFlowWidth: search.state=="hidden" ? parent.width : parent.width - search.width
108 overFlowWidth: search.state=="hidden" ? parent.width : parent.width - search.width
109
109
110− property real unitProgress: (height - panelHeight) / (openedHeight - panelHeight)
110+ unitProgress: (height - panelHeight) / (openedHeight - panelHeight)
111 }
111 }
112
112
113 PanelSeparatorLine {
113 PanelSeparatorLine {
qml/ScopeTool.qmlnew file+177
@@ -0,0 +1,177 @@
1+/*
2+* Copyright (C) 2013 Canonical, Ltd.
3+*
4+* This program is free software; you can redistribute it and/or modify
5+* it under the terms of the GNU General Public License as published by
6+* the Free Software Foundation; version 3.
7+*
8+* This program is distributed in the hope that it will be useful,
9+* but WITHOUT ANY WARRANTY; without even the implied warranty of
10+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+* GNU General Public License for more details.
12+*
13+* You should have received a copy of the GNU General Public License
14+* along with this program. If not, see <http://www.gnu.org/licenses/>.
15+*/
16+
17+import QtQuick 2.0
18+import Ubuntu.Components 0.1
19+import Ubuntu.Components.Popups 0.1
20+import Unity 0.1
21+import "Dash"
22+
23+Rectangle {
24+ id: root
25+ width: units.gu(80)
26+ height: units.gu(72)
27+ color: "#88FFFFFF"
28+
29+ // Fake shell object
30+ QtObject {
31+ id: shell
32+ }
33+
34+ // Fake greeter object
35+ QtObject {
36+ id: greeter
37+ property bool shown
38+ }
39+
40+ // Fake panel object
41+ QtObject {
42+ id: panel
43+ signal searchClicked
44+ }
45+
46+
47+ Scopes {
48+ id: scopes
49+ }
50+
51+ Rectangle {
52+ anchors.fill: scopeView
53+ color: "#FCFCFC"
54+ }
55+
56+ GenericScopeView {
57+ id: scopeView
58+
59+ anchors {
60+ top: parent.top
61+ bottom: parent.bottom
62+ left: parent.left
63+ right: controls.left
64+ }
65+
66+ scope: scopes.loaded ? scopes.get(scopeSelector.selectedIndex) : undefined
67+ }
68+
69+ Rectangle {
70+ id: controls
71+ color: "lightgrey"
72+ width: units.gu(40)
73+ anchors {
74+ top: parent.top
75+ bottom: parent.bottom
76+ right: parent.right
77+ }
78+
79+ Column {
80+ anchors { fill: parent; margins: units.gu(1) }
81+ spacing: units.gu(1)
82+
83+ Label {
84+ text: "Search query"
85+ }
86+
87+ TextField {
88+ id: searchField
89+ anchors { left: parent.left; right: parent.right }
90+
91+ onTextChanged: scopeView.scope.searchQuery = text
92+
93+ Connections {
94+ target: scopeView.scope
95+ onSearchQueryChanged: searchField.text = scopeView.scope.searchQuery
96+ }
97+ }
98+
99+ Label {
100+ text: "Scope selection"
101+ height: units.gu(4)
102+ verticalAlignment: Text.AlignBottom
103+ }
104+
105+ OptionSelector {
106+ id: scopeSelector
107+ anchors { left: parent.left; right: parent.right }
108+
109+ model: scopes
110+ delegate: OptionSelectorDelegate {
111+ text: model.title
112+ }
113+ }
114+
115+ Label {
116+ text: "Category"
117+ height: units.gu(4)
118+ verticalAlignment: Text.AlignBottom
119+ }
120+
121+ OptionSelector {
122+ id: categorySelector
123+ anchors { left: parent.left; right: parent.right }
124+ model: scopeView.scope ? scopeView.scope.categories : null
125+
126+ property Item selectedItem
127+
128+ delegate: OptionSelectorDelegate {
129+ id: categoryDelegate
130+ text: model.name
131+ property string categoryId: model.categoryId
132+ property string template: JSON.stringify(JSON.parse(model.rawRendererTemplate), null, " ");
133+
134+ onSelectedChanged: if (selected) categorySelector.selectedItem = categoryDelegate
135+ }
136+ }
137+
138+ TextArea {
139+ id: categoryJson
140+ width: parent.width
141+ autoSize: true
142+ readOnly: true
143+ text: categorySelector.selectedItem && categorySelector.selectedItem.template
144+ }
145+
146+ Button {
147+ width: parent.width
148+ text: "Override category"
149+ onClicked: {
150+ PopupUtils.open(categoryEditor)
151+ }
152+ }
153+ }
154+ }
155+
156+ Component {
157+ id: categoryEditor
158+
159+ ComposerSheet {
160+ id: sheet
161+ title: "Editing category definition"
162+
163+ TextArea {
164+ id: categoryEditorArea
165+ anchors.fill: parent
166+ wrapMode: Text.WordWrap
167+ text: categoryJson.text
168+ }
169+
170+ onCancelClicked: PopupUtils.close(sheet)
171+ onConfirmClicked: {
172+ PopupUtils.close(sheet);
173+ scopeView.scope.categories.overrideCategoryJson(categorySelector.selectedItem.categoryId, categoryEditorArea.text);
174+ }
175+ }
176+ }
177+}
tests/qmltests/Dash/tst_GenericScopeView.qml+9
@@ -321,6 +321,15 @@ Item {
321
321
322 categoryListView.positionAtBeginning();
322 categoryListView.positionAtBeginning();
323
323
324+ // wait for the header0 to be on its position
325+ tryCompareFunction(
326+ function() {
327+ var header0 = findChild(genericScopeView, "dashSectionHeader0")
328+ var pageHeader = findChild(genericScopeView, "pageHeader");
329+ return header0.y == pageHeader.height;
330+ },
331+ true);
332+
324 var header0 = findChild(genericScopeView, "dashSectionHeader0")
333 var header0 = findChild(genericScopeView, "dashSectionHeader0")
325 var category0 = findChild(genericScopeView, "dashCategory0")
334 var category0 = findChild(genericScopeView, "dashCategory0")
326 mouseClick(header0, header0.width / 2, header0.height / 2);
335 mouseClick(header0, header0.width / 2, header0.height / 2);
tests/qmltests/Notifications/tst_Notifications.qml+4−10
@@ -225,7 +225,6 @@ Row {
225 { id: "nada_id", label: "Nada"}],
225 { id: "nada_id", label: "Nada"}],
226 summaryVisible: true,
226 summaryVisible: true,
227 bodyVisible: true,
227 bodyVisible: true,
228− interactiveAreaEnabled: false,
229 iconVisible: true,
228 iconVisible: true,
230 shapedIcon: true,
229 shapedIcon: true,
231 nonShapedIcon: false,
230 nonShapedIcon: false,
@@ -244,7 +243,6 @@ Row {
244 actions: [],
243 actions: [],
245 summaryVisible: true,
244 summaryVisible: true,
246 bodyVisible: false,
245 bodyVisible: false,
247− interactiveAreaEnabled: false,
248 iconVisible: false,
246 iconVisible: false,
249 shapedIcon: false,
247 shapedIcon: false,
250 nonShapedIcon: false,
248 nonShapedIcon: false,
@@ -282,7 +280,6 @@ Row {
282 actions: [{ id: "reply_id", label: "Dummy"}],
280 actions: [{ id: "reply_id", label: "Dummy"}],
283 summaryVisible: true,
281 summaryVisible: true,
284 bodyVisible: true,
282 bodyVisible: true,
285− interactiveAreaEnabled: true,
286 iconVisible: true,
283 iconVisible: true,
287 shapedIcon: true,
284 shapedIcon: true,
288 nonShapedIcon: false,
285 nonShapedIcon: false,
@@ -302,7 +299,6 @@ Row {
302 { id: "reject_id", label: "Reject"}],
299 { id: "reject_id", label: "Reject"}],
303 summaryVisible: true,
300 summaryVisible: true,
304 bodyVisible: true,
301 bodyVisible: true,
305− interactiveAreaEnabled: false,
306 iconVisible: true,
302 iconVisible: true,
307 shapedIcon: true,
303 shapedIcon: true,
308 nonShapedIcon: false,
304 nonShapedIcon: false,
@@ -321,7 +317,6 @@ Row {
321 actions: [],
317 actions: [],
322 summaryVisible: true,
318 summaryVisible: true,
323 bodyVisible: true,
319 bodyVisible: true,
324− interactiveAreaEnabled: false,
325 iconVisible: true,
320 iconVisible: true,
326 shapedIcon: true,
321 shapedIcon: true,
327 nonShapedIcon: false,
322 nonShapedIcon: false,
@@ -341,7 +336,6 @@ Row {
341 actions: [],
336 actions: [],
342 summaryVisible: true,
337 summaryVisible: true,
343 bodyVisible: true,
338 bodyVisible: true,
344− interactiveAreaEnabled: false,
345 iconVisible: true,
339 iconVisible: true,
346 shapedIcon: false,
340 shapedIcon: false,
347 nonShapedIcon: true,
341 nonShapedIcon: true,
@@ -395,14 +389,14 @@ Row {
395 compare(icon.visible, data.iconVisible, "avatar-icon visibility is incorrect")
389 compare(icon.visible, data.iconVisible, "avatar-icon visibility is incorrect")
396 compare(shapedIcon.visible, data.shapedIcon, "shaped-icon visibility is incorrect")
390 compare(shapedIcon.visible, data.shapedIcon, "shaped-icon visibility is incorrect")
397 compare(nonShapedIcon.visible, data.nonShapedIcon, "non-shaped-icon visibility is incorrect")
391 compare(nonShapedIcon.visible, data.nonShapedIcon, "non-shaped-icon visibility is incorrect")
398− compare(interactiveArea.enabled, data.interactiveAreaEnabled, "check for interactive area")
399
392
400− if(data.interactiveAreaEnabled) {
393+ // test input does not fall through
401− mouseClick(notification, notification.width / 2, notification.height / 2)
394+ mouseClick(notification, notification.width / 2, notification.height / 2)
395+ if(data.type == Notification.Interactive) {
402 actionSpy.wait()
396 actionSpy.wait()
403 compare(actionSpy.signalArguments[0][0], data.actions[0]["id"], "got wrong id for interactive action")
397 compare(actionSpy.signalArguments[0][0], data.actions[0]["id"], "got wrong id for interactive action")
404− compare(clickThroughSpy.count, 0, "click on interactive notification fell through")
405 }
398 }
399+ compare(clickThroughSpy.count, 0, "click on notification fell through")
406
400
407 compare(secondaryIcon.visible, data.secondaryIconVisible, "secondary-icon visibility is incorrect")
401 compare(secondaryIcon.visible, data.secondaryIconVisible, "secondary-icon visibility is incorrect")
408 compare(summaryLabel.visible, data.summaryVisible, "summary-text visibility is incorrect")
402 compare(summaryLabel.visible, data.summaryVisible, "summary-text visibility is incorrect")
tests/qmltests/Panel/tst_IndicatorItem.qml−11
@@ -41,17 +41,6 @@ Rectangle {
41 tryCompareFunction(function(){return indicatorItem.opacity < 1.0}, true);
41 tryCompareFunction(function(){return indicatorItem.opacity < 1.0}, true);
42 }
42 }
43
43
44− function test_highlight() {
45− var itemHighlight = findChild(indicatorItem, "highlight");
46− verify(itemHighlight != undefined);
47−
48− indicatorItem.highlighted = true;
49− compare(itemHighlight.visible, true, "Indicator should be highlighted");
50−
51− indicatorItem.highlighted = false;
52− compare(itemHighlight.visible, false, "Indicator should not be highlighted");
53− }
54−
55 function test_empty() {
44 function test_empty() {
56 compare(indicatorItem.indicatorVisible, false, "IndicatorItem should not be visible.");
45 compare(indicatorItem.indicatorVisible, false, "IndicatorItem should not be visible.");
57 indicatorItem.widgetSource = "qrc:/tests/indciators/qml/fake_menu_widget1.qml";
46 indicatorItem.widgetSource = "qrc:/tests/indciators/qml/fake_menu_widget1.qml";
tests/qmltests/Panel/tst_IndicatorRow.qml+18−4
@@ -34,6 +34,7 @@ Item {
34 {
34 {
35 indicatorRow.state = "initial";
35 indicatorRow.state = "initial";
36 indicatorRow.currentItem = null;
36 indicatorRow.currentItem = null;
37+ indicatorRow.unitProgress = 0.0;
37 }
38 }
38
39
39 PanelBackground {
40 PanelBackground {
@@ -83,14 +84,13 @@ Item {
83 function test_current_item_commit() {
84 function test_current_item_commit() {
84 init_test();
85 init_test();
85
86
86− indicatorRow.setCurrentItem(1);
87+ indicatorRow.setCurrentItem(2);
87 indicatorRow.state = "commit";
88 indicatorRow.state = "commit";
88 tryCompare(get_indicator_item_at(0), "opacity", 0.0);
89 tryCompare(get_indicator_item_at(0), "opacity", 0.0);
89− tryCompare(get_indicator_item_at(1), "opacity", 1.0);
90+ tryCompare(get_indicator_item_at(1), "opacity", 0.0);
90− tryCompare(get_indicator_item_at(2), "opacity", 0.0);
91+ tryCompare(get_indicator_item_at(2), "opacity", 1.0);
91 tryCompare(get_indicator_item_at(3), "opacity", 0.0);
92 tryCompare(get_indicator_item_at(3), "opacity", 0.0);
92 tryCompare(get_indicator_item_at(4), "opacity", 0.0);
93 tryCompare(get_indicator_item_at(4), "opacity", 0.0);
93−
94 }
94 }
95 }
95 }
96
96
@@ -166,6 +166,20 @@ Item {
166 compare(get_indicator_item_at(3).highlighted, false, "Other indicators should not highlight when in locked state");
166 compare(get_indicator_item_at(3).highlighted, false, "Other indicators should not highlight when in locked state");
167 compare(get_indicator_item_at(4).highlighted, false, "Other indicators should not highlight when in locked state");
167 compare(get_indicator_item_at(4).highlighted, false, "Other indicators should not highlight when in locked state");
168 }
168 }
169+
170+ function test_opacity() {
171+ init_test();
172+
173+ indicatorRow.state = "reveal";
174+ indicatorRow.unitProgress = 0.5;
175+ indicatorRow.setCurrentItem(2);
176+
177+ compare(get_indicator_item_at(0).opacity, 0.5, "Other indicator opacity should change in response to panel progress");
178+ compare(get_indicator_item_at(1).opacity, 0.5, "Other indicator opacity should change in response to panel progress");
179+ compare(get_indicator_item_at(2).opacity, 1.0, "Current indicator should not change in response to panel progress");
180+ compare(get_indicator_item_at(3).opacity, 0.5, "Other indicator opacity should change in response to panel progress");
181+ compare(get_indicator_item_at(4).opacity, 0.5, "Other indicator opacity should change in response to panel progress");
182+ }
169 }
183 }
170
184
171 UT.UnityTestCase {
185 UT.UnityTestCase {
tools/CMakeLists.txtnew file+11
@@ -0,0 +1,11 @@
1+add_executable(${SCOPE_TOOL}
2+ scopetool.cpp
3+ registry-tracker.cpp
4+ )
5+
6+qt5_use_modules(${SCOPE_TOOL} Qml Quick)
7+
8+# install binaries
9+install(TARGETS ${SCOPE_TOOL}
10+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
11+ )
tools/registry-tracker.cppnew file+116
@@ -0,0 +1,116 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Michal Hruby <michal.hruby@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+// Qt
21+#include <QtGlobal>
22+#include <QDir>
23+
24+// local
25+#include "registry-tracker.h"
26+
27+
28+RegistryTracker::RegistryTracker(QString const& scope_dir):
29+ m_scopeDir(scope_dir),
30+ m_registry(nullptr),
31+ m_endpoints_dir(QDir::temp().filePath("scope-dev-endpoints.XXXXXX"))
32+{
33+ runRegistry();
34+}
35+
36+RegistryTracker::~RegistryTracker()
37+{
38+ if (m_registry.state() != QProcess::NotRunning) {
39+ m_registry.terminate();
40+ m_registry.waitForFinished(5000);
41+ m_registry.kill();
42+ }
43+}
44+
45+#define RUNTIME_CONFIG \
46+"[Runtime]\n" \
47+"Registry.Identity = Registry\n" \
48+"Registry.ConfigFile = %1\n" \
49+"Default.Middleware = Zmq\n" \
50+"Zmq.ConfigFile = %2\n"
51+
52+#define REGISTRY_CONFIG \
53+"[Registry]\n" \
54+"Middleware = Zmq\n" \
55+"Zmq.Endpoint = ipc://%1/Registry\n" \
56+"Zmq.EndpointDir = %2\n" \
57+"Zmq.ConfigFile = %3\n" \
58+"Scope.InstallDir = %4\n" \
59+"Scoperunner.Path = %5\n"
60+
61+#define MW_CONFIG \
62+"[Zmq]\n" \
63+"EndpointDir.Public = %1\n" \
64+"EndpointDir.Private = %2\n"
65+
66+void RegistryTracker::runRegistry()
67+{
68+ QDir tmp(QDir::temp());
69+ m_runtime_config.setFileTemplate(tmp.filePath("Runtime.ini.XXXXXX"));
70+ m_registry_config.setFileTemplate(tmp.filePath("Registry.ini.XXXXXX"));
71+ m_mw_config.setFileTemplate(tmp.filePath("Zmq.ini.XXXXXX"));
72+
73+ if (!m_runtime_config.open() || !m_registry_config.open() || !m_mw_config.open() || !m_endpoints_dir.isValid()) {
74+ qWarning("Unable to open temporary files!");
75+ return;
76+ }
77+
78+ QString scopesLibdir;
79+ {
80+ QProcess pkg_config;
81+ QStringList arguments;
82+ arguments << "--variable=libdir";
83+ arguments << "libunity-scopes";
84+ pkg_config.start("pkg-config", arguments);
85+ pkg_config.waitForFinished();
86+ QByteArray libdir = pkg_config.readAllStandardOutput();
87+ scopesLibdir = QDir(QString::fromLocal8Bit(libdir)).path().trimmed();
88+ }
89+
90+ if (scopesLibdir.size() == 0) {
91+ qWarning("Unable to find libunity-scopes package config file");
92+ return;
93+ }
94+
95+ QString scopeRunnerPath = QDir(scopesLibdir).filePath("scoperunner/scoperunner");
96+
97+ QString runtime_ini = QString(RUNTIME_CONFIG).arg(m_registry_config.fileName()).arg(m_mw_config.fileName());
98+ QString registry_ini = QString(REGISTRY_CONFIG).arg(m_endpoints_dir.path()).arg(m_endpoints_dir.path()).arg(m_mw_config.fileName()).arg(m_scopeDir).arg(scopeRunnerPath);
99+ QString mw_ini = QString(MW_CONFIG).arg(m_endpoints_dir.path()).arg(m_endpoints_dir.path());
100+
101+ m_runtime_config.write(runtime_ini.toUtf8());
102+ m_registry_config.write(registry_ini.toUtf8());
103+ m_mw_config.write(mw_ini.toUtf8());
104+
105+ m_runtime_config.flush();
106+ m_registry_config.flush();
107+ m_mw_config.flush();
108+
109+ qputenv("UNITY_SCOPES_RUNTIME_PATH", m_runtime_config.fileName().toLocal8Bit());
110+
111+ QString registryBin(QDir(scopesLibdir).filePath("scoperegistry/scoperegistry"));
112+ QStringList arguments;
113+ arguments << m_runtime_config.fileName();
114+
115+ m_registry.start(registryBin, arguments);
116+}
tools/registry-tracker.hnew file+44
@@ -0,0 +1,44 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Michal Hruby <michal.hruby@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+// Qt
21+#include <QProcess>
22+#include <QTemporaryFile>
23+#include <QTemporaryDir>
24+#include <QDebug>
25+
26+
27+class RegistryTracker
28+{
29+public:
30+ RegistryTracker(QString const&);
31+ ~RegistryTracker();
32+
33+ QProcess* registry() const;
34+
35+private:
36+ void runRegistry();
37+
38+ QString m_scopeDir;
39+ QProcess m_registry;
40+ QTemporaryDir m_endpoints_dir;
41+ QTemporaryFile m_runtime_config;
42+ QTemporaryFile m_registry_config;
43+ QTemporaryFile m_mw_config;
44+};
tools/scopetool.cppnew file+84
@@ -0,0 +1,84 @@
1+/*
2+ * Copyright (C) 2012 Canonical, Ltd.
3+ *
4+ * Authors:
5+ * Gerry Boland <gerry.boland@canonical.com>
6+ *
7+ * This program is free software; you can redistribute it and/or modify
8+ * it under the terms of the GNU General Public License as published by
9+ * the Free Software Foundation; version 3.
10+ *
11+ * This program is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+ * GNU General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU General Public License
17+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+// Qt
21+#include <QtQuick/QQuickView>
22+#include <QtGui/QGuiApplication>
23+#include <QtQml/QQmlEngine>
24+#include <QtQml/QQmlContext>
25+#include <QScopedPointer>
26+#include <QDebug>
27+#include <libintl.h>
28+
29+
30+// local
31+#include <paths.h>
32+#include "registry-tracker.h"
33+
34+
35+int main(int argc, char *argv[])
36+{
37+ /* Workaround Qt platform integration plugin not advertising itself
38+ as having the following capabilities:
39+ - QPlatformIntegration::ThreadedOpenGL
40+ - QPlatformIntegration::BufferQueueingOpenGL
41+ */
42+ setenv("QML_FORCE_THREADED_RENDERER", "1", 1);
43+ setenv("QML_FIXED_ANIMATION_STEP", "1", 1);
44+
45+ QGuiApplication::setApplicationName("Unity Scope Tool");
46+ QGuiApplication *application;
47+ application = new QGuiApplication(argc, argv);
48+
49+ QStringList arguments = application->arguments();
50+ QString scopesDir;
51+ if (arguments.contains("--scope-dir")) {
52+ int idx = arguments.indexOf("--scope-dir");
53+ scopesDir = arguments[idx+1];
54+ }
55+
56+ QScopedPointer<RegistryTracker> tracker;
57+ if (!scopesDir.isEmpty()) {
58+ tracker.reset(new RegistryTracker(scopesDir));
59+ }
60+
61+ resolveIconTheme();
62+
63+ bindtextdomain("unity8", translationDirectory().toUtf8().data());
64+
65+ QQuickView* view = new QQuickView();
66+ view->setResizeMode(QQuickView::SizeRootObjectToView);
67+ view->setTitle(QGuiApplication::applicationName());
68+ view->engine()->setBaseUrl(QUrl::fromLocalFile(::qmlDirectory()));
69+
70+ QUrl source(::qmlDirectory() + "ScopeTool.qml");
71+ prependImportPaths(view->engine(), ::overrideImportPaths());
72+ appendImportPaths(view->engine(), ::fallbackImportPaths());
73+
74+ view->setSource(source);
75+
76+ view->show();
77+
78+ int result = application->exec();
79+
80+ delete view;
81+ delete application;
82+
83+ return result;
84+}