Merge lp:~fboucault/unity-2d/keyboard_navigation_experimental into lp:~fboucault/unity-2d/icon_provide_better_error_handling

Proposed by Florian Boucault
Status: Superseded
Proposed branch: lp:~fboucault/unity-2d/keyboard_navigation_experimental
Merge into: lp:~fboucault/unity-2d/icon_provide_better_error_handling
Diff against target: 2920 lines (+1417/-409)
54 files modified
.bzrignore (+1/-0)
CMakeLists.txt (+31/-0)
data/com.canonical.Unity2d.gschema.xml (+19/-0)
data/unity-2d.convert (+7/-0)
debian/20_unity-2d-gconf-default (+0/-4)
debian/changelog (+19/-2)
debian/control (+3/-1)
debian/gconf/schemas/unity-2d.schemas (+0/-56)
debian/unity-2d.install (+3/-1)
debian/unity-2d.triggers (+1/-1)
launcher/app/CMakeLists.txt (+3/-2)
launcher/app/launcher.cpp (+13/-28)
launcher/app/launcherview.cpp (+12/-3)
launcher/app/launcherview.h (+4/-3)
launcher/app/visibilitycontroller.cpp (+7/-8)
launcher/app/visibilitycontroller.h (+3/-3)
libunity-2d-private/Unity2d/CMakeLists.txt (+3/-6)
libunity-2d-private/Unity2d/launcherapplicationslist.cpp (+11/-9)
libunity-2d-private/Unity2d/launcherapplicationslist.h (+2/-1)
libunity-2d-private/Unity2d/plugin.cpp (+3/-0)
libunity-2d-private/Unity2d/qsortfilterproxymodelqml.cpp (+114/-6)
libunity-2d-private/Unity2d/qsortfilterproxymodelqml.h (+18/-3)
libunity-2d-private/Unity2d/workspacesinfo.cpp (+0/-2)
libunity-2d-private/src/CMakeLists.txt (+1/-4)
libunity-2d-private/src/giodefaultapplication.cpp (+107/-0)
libunity-2d-private/src/giodefaultapplication.h (+63/-0)
libunity-2d-private/src/unity2dapplication.cpp (+38/-0)
libunity-2d-private/src/unity2dapplication.h (+7/-0)
libunity-2d-private/tests/CMakeLists.txt (+1/-0)
libunity-2d-private/tests/keyboardmodifiersmonitortest.cpp (+1/-0)
libunity-2d-private/tests/mouseareademo.cpp (+1/-0)
libunity-2d-private/tests/qsortfilterproxymodeltest.cpp (+384/-0)
panel/app/main.cpp (+1/-15)
panel/applets/CMakeLists.txt (+0/-4)
panel/applets/indicator/indicator.c (+15/-0)
places/Home.qml (+37/-43)
places/HomeButtonDefaultApplication.qml (+48/-0)
places/HomeShortcuts.qml (+30/-5)
places/ListViewWithHeaders.qml (+277/-0)
places/ListViewWithScrollbar.qml (+7/-30)
places/PlaceEntryView.qml (+41/-23)
places/Renderer.qml (+3/-3)
places/RendererGrid.qml (+24/-77)
places/Scrollbar.qml (+11/-5)
places/SearchEntry.qml (+3/-1)
places/SearchRefine.qml (+5/-0)
places/SearchRefineOptionType.qml (+6/-2)
places/TickBox.qml (+4/-4)
places/UnityEmptySearchRenderer.qml (+1/-1)
places/app/CMakeLists.txt (+0/-2)
places/app/places.cpp (+3/-19)
places/dash.qml (+18/-7)
spread/app/CMakeLists.txt (+0/-4)
spread/app/spread.cpp (+3/-21)
To merge this branch: bzr merge lp:~fboucault/unity-2d/keyboard_navigation_experimental
Reviewer Review Type Date Requested Status
Gerry Boland Pending
Review via email: mp+69479@code.launchpad.net

Description of the change

[dash] Implemented keyboard navigation.

To post a comment you must log in.
639. By Florian Boucault

Remade RendererGrid.interactive false thus preventing mouse interaction with the individual groups.

640. By Florian Boucault

Prevent the focus to be on the refine search pane when it is folded.

641. By Florian Boucault

Added FIXME/

642. By Florian Boucault

Merged colo:proper_grid

Unmerged revisions

642. By Florian Boucault

Merged colo:proper_grid

641. By Florian Boucault

Added FIXME/

640. By Florian Boucault

Prevent the focus to be on the refine search pane when it is folded.

639. By Florian Boucault

Remade RendererGrid.interactive false thus preventing mouse interaction with the individual groups.

638. By Florian Boucault

Merged colo:proper_grid

637. By Florian Boucault

Merged colo:proper_grid

636. By Florian Boucault

No change.

635. By Florian Boucault

Merged colo:proper_grid

634. By Florian Boucault

Merged colo:proper_grid

633. By Florian Boucault

Merged colo:proper_grid

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file '.bzrignore'
--- .bzrignore 2011-06-15 14:39:35 +0000
+++ .bzrignore 2011-07-27 15:02:42 +0000
@@ -78,3 +78,4 @@
78debian/unity-qt-spread78debian/unity-qt-spread
79debian/libuqpanel-dev79debian/libuqpanel-dev
80debian/libuqpanel080debian/libuqpanel0
81data/gschemas.compiled
8182
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt 2011-06-27 13:40:51 +0000
+++ CMakeLists.txt 2011-07-27 15:02:42 +0000
@@ -4,6 +4,7 @@
4# Dirs4# Dirs
5set(UNITY_2D_DIR share/unity-2d)5set(UNITY_2D_DIR share/unity-2d)
6set(UNITY_DIR /usr/share/unity/)6set(UNITY_DIR /usr/share/unity/)
7set(UNITY_2D_DATA_DIR "${CMAKE_SOURCE_DIR}/data")
78
8configure_file(config.h.in config.h)9configure_file(config.h.in config.h)
910
@@ -23,6 +24,36 @@
23find_package(Qt4 REQUIRED)24find_package(Qt4 REQUIRED)
24find_package(X11 REQUIRED)25find_package(X11 REQUIRED)
25find_package(Gettext REQUIRED)26find_package(Gettext REQUIRED)
27pkg_check_modules(GLIB REQUIRED glib-2.0)
28pkg_check_modules(GDK REQUIRED gdk-2.0)
29pkg_check_modules(GTK REQUIRED gtk+-2.0)
30pkg_check_modules(GIO REQUIRED gio-2.0)
31pkg_check_modules(WNCK REQUIRED libwnck-1.0)
32
33
34# GSettings schemas
35pkg_check_modules(GLIB REQUIRED glib-2.0)
36set (UNITY_2D_SCHEMAS "com.canonical.Unity2d.gschema.xml")
37set (UNITY_2D_GCONF_CONVERT "unity-2d.convert")
38set (GSETTINGS_DIR "${CMAKE_INSTALL_PREFIX}/share/glib-2.0/schemas/")
39set (GCONF_CONVERT_DIR "${CMAKE_INSTALL_PREFIX}/share/GConf/gsettings")
40execute_process (COMMAND ${PKG_CONFIG_EXECUTABLE} gio-2.0 --variable glib_compile_schemas OUTPUT_VARIABLE GLIB_COMPILE_SCHEMAS OUTPUT_STRIP_TRAILING_WHITESPACE)
41
42# Run the schemas validator and error if it fails
43execute_process (COMMAND ${GLIB_COMPILE_SCHEMAS} ${UNITY_2D_DATA_DIR} ERROR_VARIABLE _schemas_invalid OUTPUT_STRIP_TRAILING_WHITESPACE)
44
45if (_schemas_invalid)
46 message (SEND_ERROR "Schemas validation error: ${_schemas_invalid}")
47endif (_schemas_invalid)
48
49# Actually install and recompile the schemas
50message (STATUS "GSettings schemas will be installed into ${GSETTINGS_DIR}")
51install (FILES ${UNITY_2D_DATA_DIR}/${UNITY_2D_SCHEMAS} DESTINATION ${GSETTINGS_DIR})
52install (CODE "message (STATUS \"Compiling GSettings schemas\")")
53install (CODE "execute_process (COMMAND ${GLIB_COMPILE_SCHEMAS} ${GSETTINGS_DIR})")
54
55# Install GConf to GSettings conversion file
56install (FILES ${UNITY_2D_DATA_DIR}/${UNITY_2D_GCONF_CONVERT} DESTINATION ${GCONF_CONVERT_DIR})
2657
27include_directories(58include_directories(
28 ${CMAKE_BINARY_DIR}59 ${CMAKE_BINARY_DIR}
2960
=== added directory 'data'
=== added file 'data/com.canonical.Unity2d.gschema.xml'
--- data/com.canonical.Unity2d.gschema.xml 1970-01-01 00:00:00 +0000
+++ data/com.canonical.Unity2d.gschema.xml 2011-07-27 15:02:42 +0000
@@ -0,0 +1,19 @@
1<schemalist>
2 <schema path="/com/canonical/unity-2d/launcher/" id="com.canonical.Unity2d.Launcher" gettext-domain="unity-2d">
3 <key type="b" name="super-key-enable">
4 <default>true</default>
5 <summary>Super key activation.</summary>
6 <description>Whether or not the super (also called windows key) key is used.</description>
7 </key>
8 <key name="hide-mode" type="i">
9 <default>2</default>
10 <summary>Hiding mode of the launcher</summary>
11 <description>Possible values: 0: never hide; the launcher is always visible. Always set /com/canonical/unity-2d/launcher/use-strut to true when using that mode 1: auto hide; the launcher will disappear after a short time if the user is not interacting with it 2: intellihide; the launcher will disappear if a window is placed on top of it and if the user is not interacting with it</description>
12 </key>
13 <key name="use-strut" type="b">
14 <default>false</default>
15 <summary>Reserve launcher area</summary>
16 <description>Use EWMH standard to reserve an area of the desktop (struts) so that no window can use the launcher's area</description>
17 </key>
18 </schema>
19</schemalist>
020
=== added file 'data/unity-2d.convert'
--- data/unity-2d.convert 1970-01-01 00:00:00 +0000
+++ data/unity-2d.convert 2011-07-27 15:02:42 +0000
@@ -0,0 +1,7 @@
1[com.canonical.Unity2d.Launcher]
2super-key-enable = /desktop/unity-2d/launcher/super_key_enable
3hide-mode = /desktop/unity-2d/launcher/hide_mode
4use-strut = /desktop/unity-2d/launcher/use_strut
5
6[com.canonical.Unity.Launcher]
7favorites = /desktop/unity-2d/launcher/favorites
08
=== modified file 'debian/20_unity-2d-gconf-default'
--- debian/20_unity-2d-gconf-default 2011-06-15 13:05:38 +0000
+++ debian/20_unity-2d-gconf-default 2011-07-27 15:02:42 +0000
@@ -1,9 +1,5 @@
1/apps/gnome-power-manager/lock/use_screensaver_settings true1/apps/gnome-power-manager/lock/use_screensaver_settings true
2/apps/gnome-power-manager/general/use_time_for_policy false2/apps/gnome-power-manager/general/use_time_for_policy false
3/desktop/unity-2d/launcher/favorites [ubiquity-gtkui.desktop,nautilus-home.desktop,firefox.desktop,libreoffice-writer.desktop,libreoffice-calc.desktop,libreoffice-impress.desktop,ubuntu-software-center.desktop,ubuntuone-control-panel-gtk.desktop]
4/desktop/unity-2d/launcher/hide_mode 2
5/desktop/unity-2d/launcher/use_strut false
6/desktop/unity-2d/launcher/super_key_enable true
7/desktop/gnome/applications/window_manager/default /usr/bin/metacity3/desktop/gnome/applications/window_manager/default /usr/bin/metacity
8/desktop/gnome/applications/window_manager/current /usr/bin/metacity4/desktop/gnome/applications/window_manager/current /usr/bin/metacity
9/apps/metacity/general/show_maximized_titlebars false5/apps/metacity/general/show_maximized_titlebars false
106
=== modified file 'debian/changelog'
--- debian/changelog 2011-07-13 10:11:55 +0000
+++ debian/changelog 2011-07-27 15:02:42 +0000
@@ -1,10 +1,27 @@
1unity-2d (3.8.12-0ubuntu1) UNRELEASED; urgency=low1unity-2d (3.8.12-0ubuntu1) UNRELEASED; urgency=low
22
3 [ Florian Boucault ]
3 * do not run pkgbinarymangler to convert images to 8bit since this breaks4 * do not run pkgbinarymangler to convert images to 8bit since this breaks
4 the launcher icon background handling. (LP: #809205)5 the launcher icon background handling. (LP: #809205)
5 (QT upstream bug: http://bugreports.qt.nokia.com/browse/QTBUG-4459)6 (QT upstream bug: http://bugreports.qt.nokia.com/browse/QTBUG-4459)
67 * debian/unity-2d.install:
7 -- Florian Boucault <florian.boucault@canonical.com> Wed, 13 Jul 2011 12:11:05 +02008 - install GSettings schemas into usr/share/glib-2.0/schemas
9 - install GConf to GSettings conversion into usr/share/GConf/gsettings
10 * debian/gconf/schemas/unity-2d.schemas:
11 - remove GConf schema for /desktop/unity-2d/launcher/super_key_enable
12 - remove GConf schema for /desktop/unity-2d/launcher/favorites
13 * debian/20_unity-2d-gconf-default:
14 - remove default value for /desktop/unity-2d/launcher/super_key_enable
15 - remove default value for /desktop/unity-2d/launcher/favorites
16 * debian/control:
17 - add dependency on libdconf-qt-dev
18
19 [ Didier Roche ]
20 * Fix typo in trigger (debian/unity-2d.triggers): (LP: #807358)
21 * Install the apport hook in the right directory so that it's not launched
22 unconditionally (LP: #712343)
23
24 -- Florian Boucault <florian.boucault@canonical.com> Fri, 22 Jul 2011 18:56:33 +0200
825
9unity-2d (3.8.10-0ubuntu1) natty; urgency=low26unity-2d (3.8.10-0ubuntu1) natty; urgency=low
1027
1128
=== modified file 'debian/control'
--- debian/control 2011-06-22 21:17:49 +0000
+++ debian/control 2011-07-27 15:02:42 +0000
@@ -12,6 +12,7 @@
12 libglib2.0-dev,12 libglib2.0-dev,
13 libwnck-dev,13 libwnck-dev,
14 libqtgconf-dev,14 libqtgconf-dev,
15 libdconf-qt-dev,
15 libqtbamf-dev,16 libqtbamf-dev,
16 libqtdee-dev,17 libqtdee-dev,
17 libdbusmenu-qt-dev,18 libdbusmenu-qt-dev,
@@ -42,7 +43,8 @@
42Section: libs43Section: libs
43Architecture: any44Architecture: any
44Depends: ${shlibs:Depends},45Depends: ${shlibs:Depends},
45 ${misc:Depends}46 ${misc:Depends},
47 unity-common,
46Description: Unity 2D shared library48Description: Unity 2D shared library
47 This library is used to host common code used by several Unity 2D components49 This library is used to host common code used by several Unity 2D components
48 It is only used internally, there is no use case for it outside of the unity-2d50 It is only used internally, there is no use case for it outside of the unity-2d
4951
=== removed directory 'debian/gconf/schemas'
=== removed file 'debian/gconf/schemas/unity-2d.schemas'
--- debian/gconf/schemas/unity-2d.schemas 2011-06-15 13:10:14 +0000
+++ debian/gconf/schemas/unity-2d.schemas 1970-01-01 00:00:00 +0000
@@ -1,56 +0,0 @@
1<gconfschemafile>
2<schemalist>
3 <schema>
4 <key>/schemas/desktop/unity-2d/launcher/favorites</key>
5 <applyto>/desktop/unity-2d/launcher/favorites</applyto>
6 <owner>unity-2d</owner>
7 <type>list</type>
8 <list_type>string</list_type>
9 <default>[ubiquity-gtkui.desktop,nautilus-home.desktop,firefox.desktop,libreoffice-writer.desktop,libreoffice-calc.desktop,libreoffice-impress.desktop,ubuntu-software-center.desktop,ubuntuone-control-panel-gtk.desktop]</default>
10 <locale name="C">
11 <short>Favorite applications</short>
12 <long>List of desktop files of applications that have been marked as favorites by the user in the launcher</long>
13 </locale>
14 </schema>
15
16 <schema>
17 <key>/schemas/desktop/unity-2d/launcher/hide_mode</key>
18 <applyto>/desktop/unity-2d/launcher/hide_mode</applyto>
19 <owner>unity-2d</owner>
20 <type>int</type>
21 <default>2</default>
22 <locale name="C">
23 <short>Hiding mode of the launcher</short>
24 <long>Possible values:
250: never hide; the launcher is always visible. Always set /desktop/unity-2d/launcher/use_strut to true when using that mode
261: auto hide; the launcher will disappear after a short time if the user is not interacting with it
272: intellihide; the launcher will disappear if a window is placed on top of it and if the user is not interacting with it</long>
28 </locale>
29 </schema>
30
31 <schema>
32 <key>/schemas/desktop/unity-2d/launcher/use_strut</key>
33 <applyto>/desktop/unity-2d/launcher/use_strut</applyto>
34 <owner>unity-2d</owner>
35 <type>bool</type>
36 <default>false</default>
37 <locale name="C">
38 <short>Reserve launcher area</short>
39 <long>Use EWMH standard to reserve an area of the desktop (struts) so that no window can use the launcher's area</long>
40 </locale>
41 </schema>
42
43 <schema>
44 <key>/schemas/desktop/unity-2d/launcher/super_key_enable</key>
45 <applyto>/desktop/unity-2d/launcher/super_key_enable</applyto>
46 <owner>unity-2d</owner>
47 <type>bool</type>
48 <default>true</default>
49 <locale name="C">
50 <short>Super key activation</short>
51 <long>Whether or not the super (also called windows key) key is used</long>
52 </locale>
53 </schema>
54</schemalist>
55</gconfschemafile>
56
570
=== modified file 'debian/unity-2d.install'
--- debian/unity-2d.install 2011-06-15 13:05:38 +0000
+++ debian/unity-2d.install 2011-07-27 15:02:42 +0000
@@ -1,7 +1,9 @@
1debian/unity-2d.py /usr/share/apport/general-hooks1debian/unity-2d.py /usr/share/apport/package-hooks
2debian/gconf/* /usr/share/gconf2debian/gconf/* /usr/share/gconf
3session/unity-2d.desktop /usr/share/xsessions3session/unity-2d.desktop /usr/share/xsessions
4session/2d-ubuntu.session /usr/share/gnome-session/sessions4session/2d-ubuntu.session /usr/share/gnome-session/sessions
5debian/20_unity-2d-gconf-mandatory /usr/share/gconf/unity-2d/mandatory5debian/20_unity-2d-gconf-mandatory /usr/share/gconf/unity-2d/mandatory
6debian/20_unity-2d-gconf-default /usr/share/gconf/unity-2d/default6debian/20_unity-2d-gconf-default /usr/share/gconf/unity-2d/default
7usr/share/locale/*/LC_MESSAGES/unity-2d.mo7usr/share/locale/*/LC_MESSAGES/unity-2d.mo
8usr/share/glib-2.0/schemas/com.canonical.Unity2d.gschema.xml
9usr/share/GConf/gsettings
810
=== modified file 'debian/unity-2d.triggers'
--- debian/unity-2d.triggers 2011-01-26 11:34:38 +0000
+++ debian/unity-2d.triggers 2011-07-27 15:02:42 +0000
@@ -1,2 +1,2 @@
1interest /usr/share/gconf/unity-2d/defaults1interest /usr/share/gconf/unity-2d/default
2interest /usr/share/gconf/unity-2d/mandatory2interest /usr/share/gconf/unity-2d/mandatory
33
=== modified file 'launcher/app/CMakeLists.txt'
--- launcher/app/CMakeLists.txt 2011-06-11 11:33:52 +0000
+++ launcher/app/CMakeLists.txt 2011-07-27 15:02:42 +0000
@@ -1,8 +1,7 @@
1# Dependencies1# Dependencies
2pkg_check_modules(GTK REQUIRED gtk+-2.0)
3pkg_check_modules(X11 REQUIRED x11)
4pkg_check_modules(GEIS REQUIRED libutouch-geis)2pkg_check_modules(GEIS REQUIRED libutouch-geis)
5pkg_check_modules(QTGCONF REQUIRED libqtgconf)3pkg_check_modules(QTGCONF REQUIRED libqtgconf)
4pkg_check_modules(DCONFQT REQUIRED dconf-qt)
65
7# Sources6# Sources
8set(launcher_SRCS7set(launcher_SRCS
@@ -38,6 +37,7 @@
38 ${X11_INCLUDE_DIRS}37 ${X11_INCLUDE_DIRS}
39 ${GEIS_INCLUDE_DIRS}38 ${GEIS_INCLUDE_DIRS}
40 ${QTGCONF_INCLUDE_DIRS}39 ${QTGCONF_INCLUDE_DIRS}
40 ${DCONFQT_INCLUDE_DIRS}
41 ${libunity-2d-private_SOURCE_DIR}/src41 ${libunity-2d-private_SOURCE_DIR}/src
42 )42 )
4343
@@ -50,6 +50,7 @@
50 ${X11_LDFLAGS}50 ${X11_LDFLAGS}
51 ${GEIS_LDFLAGS}51 ${GEIS_LDFLAGS}
52 ${QTGCONF_LDFLAGS}52 ${QTGCONF_LDFLAGS}
53 ${DCONFQT_LDFLAGS}
53 unity-2d-private54 unity-2d-private
54 )55 )
5556
5657
=== modified file 'launcher/app/launcher.cpp'
--- launcher/app/launcher.cpp 2011-06-22 08:33:52 +0000
+++ launcher/app/launcher.cpp 2011-07-27 15:02:42 +0000
@@ -17,16 +17,14 @@
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */18 */
1919
20#include <gtk/gtk.h>
21
22// unity-2d20// unity-2d
23#include <gnomesessionclient.h>21#include <gnomesessionclient.h>
24#include <launcherclient.h>22#include <launcherclient.h>
25#include <unity2dapplication.h>23#include <unity2dapplication.h>
26#include <propertybinder.h>24#include <propertybinder.h>
2725
28// libqtgconf26// libdconf-qt
29#include <gconfitem-qml-wrapper.h>27#include "qconf.h"
3028
31// Qt29// Qt
32#include <QApplication>30#include <QApplication>
@@ -44,6 +42,11 @@
44#include "unity2dpanel.h"42#include "unity2dpanel.h"
45#include "gesturehandler.h"43#include "gesturehandler.h"
4644
45// libc
46#include <stdlib.h>
47
48static const char* LAUNCHER_DCONF_SCHEMA = "com.canonical.Unity2d.Launcher";
49
47#if defined(QMLJSDEBUGGER)50#if defined(QMLJSDEBUGGER)
48#include <qt_private/qdeclarativedebughelper_p.h>51#include <qt_private/qdeclarativedebughelper_p.h>
49#endif52#endif
@@ -73,24 +76,7 @@
7376
74int main(int argc, char *argv[])77int main(int argc, char *argv[])
75{78{
76 /* Unity2d plugin uses GTK APIs to retrieve theme icons79 Unity2dApplication::earlySetup(argc, argv);
77 (gtk_icon_theme_get_default) and requires a call to gtk_init */
78 gtk_init(&argc, &argv);
79
80 Unity2dDebug::installHandlers();
81
82 /* When the environment variable QT_GRAPHICSSYSTEM is not set,
83 force graphics system to 'raster' instead of the default 'native'
84 which on X11 is 'XRender'.
85 'XRender' defaults to using a TrueColor visual. We do _not_ mimick that
86 behaviour with 'raster' by calling QApplication::setColorSpec because
87 of a bug where black rectangular artifacts were appearing randomly:
88
89 https://bugs.launchpad.net/unity-2d/+bug/734143
90 */
91 if(getenv("QT_GRAPHICSSYSTEM") == 0) {
92 QApplication::setGraphicsSystem("raster");
93 }
94 Unity2dApplication application(argc, argv);80 Unity2dApplication application(argc, argv);
95 QSet<QString> arguments = QSet<QString>::fromList(QCoreApplication::arguments());81 QSet<QString> arguments = QSet<QString>::fromList(QCoreApplication::arguments());
9682
@@ -132,12 +118,11 @@
132118
133 launcherView->setSource(QUrl("./Launcher.qml"));119 launcherView->setSource(QUrl("./Launcher.qml"));
134120
135 /* Synchronise panel's "useStrut" property with its corresponding GConf key */121 /* Synchronise panel's "useStrut" property with its corresponding DConf key */
136 GConfItemQmlWrapper useStrutGconf;122 QConf dconfLauncher(LAUNCHER_DCONF_SCHEMA);
137 useStrutGconf.setKey("/desktop/unity-2d/launcher/use_strut");123 panel.setUseStrut(dconfLauncher.property("useStrut").toBool());
138 panel.setUseStrut(useStrutGconf.getValue().toBool());
139 PropertyBinder useStrutBinder;124 PropertyBinder useStrutBinder;
140 useStrutBinder.bind(&useStrutGconf, "value", &panel, "useStrut");125 useStrutBinder.bind(&dconfLauncher, "useStrut", &panel, "useStrut");
141126
142 /* Composing the QML declarative view inside the panel */127 /* Composing the QML declarative view inside the panel */
143 panel.addWidget(launcherView);128 panel.addWidget(launcherView);
@@ -149,7 +134,7 @@
149 the launcher itself was autostarted (which is the common case when134 the launcher itself was autostarted (which is the common case when
150 running installed).135 running installed).
151 For a discussion, see https://bugs.launchpad.net/upicek/+bug/684160. */136 For a discussion, see https://bugs.launchpad.net/upicek/+bug/684160. */
152 g_unsetenv("DESKTOP_AUTOSTART_ID");137 unsetenv("DESKTOP_AUTOSTART_ID");
153138
154 /* Gesture handler instance in charge of listening to gesture events and139 /* Gesture handler instance in charge of listening to gesture events and
155 trigger appropriate actions in response. */140 trigger appropriate actions in response. */
156141
=== modified file 'launcher/app/launcherview.cpp'
--- launcher/app/launcherview.cpp 2011-06-22 08:54:52 +0000
+++ launcher/app/launcherview.cpp 2011-07-27 15:02:42 +0000
@@ -36,6 +36,9 @@
36#include <X11/Xlib.h>36#include <X11/Xlib.h>
37#include <X11/Xatom.h>37#include <X11/Xatom.h>
3838
39// libdconf-qt
40#include "qconf.h"
41
39#include <keyboardmodifiersmonitor.h>42#include <keyboardmodifiersmonitor.h>
40#include <hotkey.h>43#include <hotkey.h>
41#include <hotkeymonitor.h>44#include <hotkeymonitor.h>
@@ -55,6 +58,7 @@
55static const char* SPREAD_DBUS_METHOD_IS_SHOWN = "IsShown";58static const char* SPREAD_DBUS_METHOD_IS_SHOWN = "IsShown";
56static const char* APPLICATIONS_PLACE = "/usr/share/unity/places/applications.place";59static const char* APPLICATIONS_PLACE = "/usr/share/unity/places/applications.place";
57static const char* COMMANDS_PLACE_ENTRY = "Runner";60static const char* COMMANDS_PLACE_ENTRY = "Runner";
61static const char* LAUNCHER_DCONF_SCHEMA = "com.canonical.Unity2d.Launcher";
5862
59LauncherView::LauncherView(QWidget* parent) :63LauncherView::LauncherView(QWidget* parent) :
60 Unity2DDeclarativeView(parent),64 Unity2DDeclarativeView(parent),
@@ -67,8 +71,8 @@
67 connect(&m_superKeyHoldTimer, SIGNAL(timeout()), SLOT(updateSuperKeyHoldState()));71 connect(&m_superKeyHoldTimer, SIGNAL(timeout()), SLOT(updateSuperKeyHoldState()));
68 connect(this, SIGNAL(superKeyTapped()), SLOT(toggleDash()));72 connect(this, SIGNAL(superKeyTapped()), SLOT(toggleDash()));
6973
70 m_enableSuperKey.setKey("/desktop/unity-2d/launcher/super_key_enable");74 m_dconf_launcher = new QConf(LAUNCHER_DCONF_SCHEMA);
71 connect(&m_enableSuperKey, SIGNAL(valueChanged()), SLOT(updateSuperKeyMonitoring()));75 connect(m_dconf_launcher, SIGNAL(superKeyEnableChanged(bool)), SLOT(updateSuperKeyMonitoring()));
72 updateSuperKeyMonitoring();76 updateSuperKeyMonitoring();
7377
74 /* Alt+F1 gives the keyboard focus to the launcher. */78 /* Alt+F1 gives the keyboard focus to the launcher. */
@@ -86,6 +90,11 @@
86 }90 }
87}91}
8892
93LauncherView::~LauncherView()
94{
95 delete m_dconf_launcher;
96}
97
89void98void
90LauncherView::activateWindow()99LauncherView::activateWindow()
91{100{
@@ -111,7 +120,7 @@
111{120{
112 KeyboardModifiersMonitor *modifiersMonitor = KeyboardModifiersMonitor::instance();121 KeyboardModifiersMonitor *modifiersMonitor = KeyboardModifiersMonitor::instance();
113122
114 QVariant value = m_enableSuperKey.getValue();123 QVariant value = m_dconf_launcher->property("superKeyEnable");
115 if (!value.isValid() || value.toBool() == true) {124 if (!value.isValid() || value.toBool() == true) {
116 QObject::connect(modifiersMonitor,125 QObject::connect(modifiersMonitor,
117 SIGNAL(keyboardModifiersChanged(Qt::KeyboardModifiers)),126 SIGNAL(keyboardModifiersChanged(Qt::KeyboardModifiers)),
118127
=== modified file 'launcher/app/launcherview.h'
--- launcher/app/launcherview.h 2011-06-22 08:54:52 +0000
+++ launcher/app/launcherview.h 2011-07-27 15:02:42 +0000
@@ -24,13 +24,13 @@
24#include <QList>24#include <QList>
25#include <QUrl>25#include <QUrl>
26#include <QTimer>26#include <QTimer>
2727#include <QVariant>
28#include "gconfitem-qml-wrapper.h"
2928
30#include <unity2ddeclarativeview.h>29#include <unity2ddeclarativeview.h>
3130
32class DeclarativeDragDropEvent;31class DeclarativeDragDropEvent;
33class LauncherDBus;32class LauncherDBus;
33class QConf;
3434
35class LauncherView : public Unity2DDeclarativeView35class LauncherView : public Unity2DDeclarativeView
36{36{
@@ -40,6 +40,7 @@
4040
41public:41public:
42 explicit LauncherView(QWidget* parent = NULL);42 explicit LauncherView(QWidget* parent = NULL);
43 ~LauncherView();
4344
44 bool superKeyHeld() const { return m_superKeyHeld; }45 bool superKeyHeld() const { return m_superKeyHeld; }
4546
@@ -66,7 +67,7 @@
66 void focusOutEvent(QFocusEvent* event);67 void focusOutEvent(QFocusEvent* event);
6768
68private:69private:
69 GConfItemQmlWrapper m_enableSuperKey;70 QConf* m_dconf_launcher;
70 bool m_superKeyPressed;71 bool m_superKeyPressed;
71 bool m_superKeyHeld;72 bool m_superKeyHeld;
72 QTimer m_superKeyHoldTimer;73 QTimer m_superKeyHoldTimer;
7374
=== modified file 'launcher/app/visibilitycontroller.cpp'
--- launcher/app/visibilitycontroller.cpp 2011-06-11 11:33:52 +0000
+++ launcher/app/visibilitycontroller.cpp 2011-07-27 15:02:42 +0000
@@ -30,27 +30,25 @@
30#include <debug_p.h>30#include <debug_p.h>
31#include <unity2dpanel.h>31#include <unity2dpanel.h>
3232
33// libqtgconf33// libdconf-qt
34#include <gconfitem-qml-wrapper.h>34#include "qconf.h"
3535
36// Qt36// Qt
37#include <QDBusConnection>37#include <QDBusConnection>
38#include <QDBusServiceWatcher>38#include <QDBusServiceWatcher>
3939
40static const char* GCONF_LAUNCHER_HIDEMODE_KEY = "/desktop/unity-2d/launcher/hide_mode";40static const char* LAUNCHER_DCONF_SCHEMA = "com.canonical.Unity2d.Launcher";
4141
42VisibilityController::VisibilityController(Unity2dPanel* panel)42VisibilityController::VisibilityController(Unity2dPanel* panel)
43: QObject(panel)43: QObject(panel)
44, m_panel(panel)44, m_panel(panel)
45, m_hideModeKey(new GConfItemQmlWrapper(this))45, m_dconf_launcher(new QConf(LAUNCHER_DCONF_SCHEMA))
46, m_dbusWatcher(new QDBusServiceWatcher(this))46, m_dbusWatcher(new QDBusServiceWatcher(this))
47{47{
48 m_hideModeKey->setKey(GCONF_LAUNCHER_HIDEMODE_KEY);
49
50 m_dbusWatcher->setConnection(QDBusConnection::sessionBus());48 m_dbusWatcher->setConnection(QDBusConnection::sessionBus());
51 m_dbusWatcher->setWatchMode(QDBusServiceWatcher::WatchForUnregistration);49 m_dbusWatcher->setWatchMode(QDBusServiceWatcher::WatchForUnregistration);
5250
53 connect(m_hideModeKey, SIGNAL(valueChanged()), SLOT(update()));51 connect(m_dconf_launcher, SIGNAL(hideModeChanged(int)), SLOT(update()));
54 connect(m_panel, SIGNAL(useStrutChanged(bool)), SLOT(update()));52 connect(m_panel, SIGNAL(useStrutChanged(bool)), SLOT(update()));
55 connect(m_panel, SIGNAL(manualSlidingChanged(bool)), SLOT(update()));53 connect(m_panel, SIGNAL(manualSlidingChanged(bool)), SLOT(update()));
56 connect(m_dbusWatcher, SIGNAL(serviceUnregistered(const QString&)), SLOT(slotServiceUnregistered(const QString&)));54 connect(m_dbusWatcher, SIGNAL(serviceUnregistered(const QString&)), SLOT(slotServiceUnregistered(const QString&)));
@@ -59,6 +57,7 @@
5957
60VisibilityController::~VisibilityController()58VisibilityController::~VisibilityController()
61{59{
60 delete m_dconf_launcher;
62}61}
6362
64void VisibilityController::update()63void VisibilityController::update()
@@ -66,7 +65,7 @@
66 if (!m_forceVisibleCountHash.isEmpty()) {65 if (!m_forceVisibleCountHash.isEmpty()) {
67 return;66 return;
68 }67 }
69 AutoHideMode mode = AutoHideMode(m_hideModeKey->getValue().toInt());68 AutoHideMode mode = AutoHideMode(m_dconf_launcher->property("hideMode").toInt());
7069
71 setBehavior(0);70 setBehavior(0);
7271
7372
=== modified file 'launcher/app/visibilitycontroller.h'
--- launcher/app/visibilitycontroller.h 2011-06-11 11:33:52 +0000
+++ launcher/app/visibilitycontroller.h 2011-07-27 15:02:42 +0000
@@ -28,14 +28,14 @@
28#include <QObject>28#include <QObject>
29#include <QScopedPointer>29#include <QScopedPointer>
3030
31class GConfItemQmlWrapper;31class QConf;
3232
33class AbstractVisibilityBehavior;33class AbstractVisibilityBehavior;
34class Unity2dPanel;34class Unity2dPanel;
35class QDBusServiceWatcher;35class QDBusServiceWatcher;
3636
37/**37/**
38 * This class monitors the hide_mode gconf key and set up an instance of38 * This class monitors the hide_mode dconf key and set up an instance of
39 * AbstractVisibilityBehavior depending on its value39 * AbstractVisibilityBehavior depending on its value
40 *40 *
41 * It also tracks requests for forced visibility: the launcher or another41 * It also tracks requests for forced visibility: the launcher or another
@@ -77,7 +77,7 @@
77 };77 };
78 Q_DISABLE_COPY(VisibilityController);78 Q_DISABLE_COPY(VisibilityController);
79 Unity2dPanel* m_panel;79 Unity2dPanel* m_panel;
80 GConfItemQmlWrapper* m_hideModeKey;80 QConf* m_dconf_launcher;
81 QDBusServiceWatcher* m_dbusWatcher;81 QDBusServiceWatcher* m_dbusWatcher;
82 QScopedPointer<AbstractVisibilityBehavior> m_behavior;82 QScopedPointer<AbstractVisibilityBehavior> m_behavior;
8383
8484
=== modified file 'libunity-2d-private/Unity2d/CMakeLists.txt'
--- libunity-2d-private/Unity2d/CMakeLists.txt 2011-06-22 08:54:52 +0000
+++ libunity-2d-private/Unity2d/CMakeLists.txt 2011-07-27 15:02:42 +0000
@@ -1,16 +1,11 @@
1# Dependencies1# Dependencies
2pkg_check_modules(WNCK REQUIRED libwnck-1.0)
3pkg_check_modules(QTBAMF REQUIRED libqtbamf)2pkg_check_modules(QTBAMF REQUIRED libqtbamf)
4pkg_check_modules(QTGCONF REQUIRED libqtgconf)3pkg_check_modules(QTGCONF REQUIRED libqtgconf)
5pkg_check_modules(QTDEE REQUIRED libqtdee)4pkg_check_modules(QTDEE REQUIRED libqtdee)
6pkg_check_modules(DBUSMENUQT REQUIRED dbusmenu-qt)5pkg_check_modules(DBUSMENUQT REQUIRED dbusmenu-qt)
7pkg_check_modules(GLIB REQUIRED glib-2.0)
8pkg_check_modules(GDK REQUIRED gdk-2.0)
9pkg_check_modules(GIO REQUIRED gio-2.0)
10pkg_check_modules(STARTUPNOTIFICATION REQUIRED libstartup-notification-1.0)6pkg_check_modules(STARTUPNOTIFICATION REQUIRED libstartup-notification-1.0)
11pkg_check_modules(INDICATOR REQUIRED indicator)7pkg_check_modules(INDICATOR REQUIRED indicator)
128pkg_check_modules(DCONFQT REQUIRED dconf-qt)
13find_package(X11 REQUIRED)
149
15# Sources10# Sources
16set(unity-2d-private-qml_SRCS11set(unity-2d-private-qml_SRCS
@@ -100,6 +95,7 @@
100 ${STARTUPNOTIFICATION_INCLUDE_DIRS}95 ${STARTUPNOTIFICATION_INCLUDE_DIRS}
101 ${INDICATOR_INCLUDE_DIRS}96 ${INDICATOR_INCLUDE_DIRS}
102 ${X11_INCLUDE_DIR}97 ${X11_INCLUDE_DIR}
98 ${DCONFQT_INCLUDE_DIRS}
103 ${libunity-2d-private_SOURCE_DIR}/src99 ${libunity-2d-private_SOURCE_DIR}/src
104 )100 )
105101
@@ -119,6 +115,7 @@
119 ${GIO_LDFLAGS}115 ${GIO_LDFLAGS}
120 ${STARTUPNOTIFICATION_LDFLAGS}116 ${STARTUPNOTIFICATION_LDFLAGS}
121 ${INDICATOR_LDFLAGS}117 ${INDICATOR_LDFLAGS}
118 ${DCONFQT_LDFLAGS}
122 ${X11_Xcomposite_LIB}119 ${X11_Xcomposite_LIB}
123 unity-2d-private120 unity-2d-private
124 )121 )
125122
=== modified file 'libunity-2d-private/Unity2d/launcherapplicationslist.cpp'
--- libunity-2d-private/Unity2d/launcherapplicationslist.cpp 2011-07-13 16:04:50 +0000
+++ libunity-2d-private/Unity2d/launcherapplicationslist.cpp 2011-07-27 15:02:42 +0000
@@ -23,6 +23,9 @@
23#include "bamf-application.h"23#include "bamf-application.h"
24#include "gconfitem-qml-wrapper.h"24#include "gconfitem-qml-wrapper.h"
2525
26// libdconf-qt
27#include "qconf.h"
28
26// unity-2d29// unity-2d
27#include <debug_p.h>30#include <debug_p.h>
2831
@@ -40,7 +43,8 @@
40}43}
4144
4245
43#define FAVORITES_KEY QString("/desktop/unity-2d/launcher/favorites")46#define LAUNCHER_DCONF_SCHEMA QString("com.canonical.Unity.Launcher")
47#define LAUNCHER_DCONF_PATH QString("/desktop/unity/launcher")
44#define DBUS_SERVICE_UNITY "com.canonical.Unity"48#define DBUS_SERVICE_UNITY "com.canonical.Unity"
45#define DBUS_SERVICE_LAUNCHER_ENTRY "com.canonical.Unity.LauncherEntry"49#define DBUS_SERVICE_LAUNCHER_ENTRY "com.canonical.Unity.LauncherEntry"
46#define DBUS_SERVICE_LAUNCHER "com.canonical.Unity.Launcher"50#define DBUS_SERVICE_LAUNCHER "com.canonical.Unity.Launcher"
@@ -52,8 +56,7 @@
52LauncherApplicationsList::LauncherApplicationsList(QObject *parent) :56LauncherApplicationsList::LauncherApplicationsList(QObject *parent) :
53 QAbstractListModel(parent)57 QAbstractListModel(parent)
54{58{
55 m_favorites_list = new GConfItemQmlWrapper();59 m_dconf_launcher = new QConf(LAUNCHER_DCONF_SCHEMA);
56 m_favorites_list->setKey(FAVORITES_KEY);
5760
58 QDBusConnection session = QDBusConnection::sessionBus();61 QDBusConnection session = QDBusConnection::sessionBus();
59 /* FIXME: libunity will send out the Update signal for LauncherEntries62 /* FIXME: libunity will send out the Update signal for LauncherEntries
@@ -171,7 +174,7 @@
171 sn_display_unref(m_snDisplay);174 sn_display_unref(m_snDisplay);
172175
173 qDeleteAll(m_applications);176 qDeleteAll(m_applications);
174 delete m_favorites_list;177 delete m_dconf_launcher;
175}178}
176179
177QString180QString
@@ -366,9 +369,8 @@
366LauncherApplicationsList::load()369LauncherApplicationsList::load()
367{370{
368 /* Insert favorites */371 /* Insert favorites */
369 /* FIXME: migrate to GSettings, like unity. */
370 QString desktop_file;372 QString desktop_file;
371 QStringList favorites = m_favorites_list->getValue().toStringList();373 QStringList favorites = m_dconf_launcher->property("favorites").toStringList();
372374
373 Q_FOREACH(QString favorite, favorites) {375 Q_FOREACH(QString favorite, favorites) {
374 insertFavoriteApplication(favorite);376 insertFavoriteApplication(favorite);
@@ -453,9 +455,9 @@
453 }455 }
454 }456 }
455457
456 m_favorites_list->blockSignals(true);458 m_dconf_launcher->blockSignals(true);
457 m_favorites_list->setValue(QVariant(favorites));459 m_dconf_launcher->setProperty("favorites", QVariant(favorites));
458 m_favorites_list->blockSignals(false);460 m_dconf_launcher->blockSignals(false);
459}461}
460462
461int463int
462464
=== modified file 'libunity-2d-private/Unity2d/launcherapplicationslist.h'
--- libunity-2d-private/Unity2d/launcherapplicationslist.h 2011-07-13 16:04:50 +0000
+++ libunity-2d-private/Unity2d/launcherapplicationslist.h 2011-07-27 15:02:42 +0000
@@ -37,6 +37,7 @@
37class BamfApplication;37class BamfApplication;
38class BamfView;38class BamfView;
39class GConfItemQmlWrapper;39class GConfItemQmlWrapper;
40class QConf;
4041
41class LauncherApplicationsList : public QAbstractListModel, protected AbstractX11EventFilter, protected QDBusContext42class LauncherApplicationsList : public QAbstractListModel, protected AbstractX11EventFilter, protected QDBusContext
42{43{
@@ -88,7 +89,7 @@
88 displayed (m_applications).89 displayed (m_applications).
89 */90 */
90 QHash<QString, LauncherApplication*> m_applicationForExecutable;91 QHash<QString, LauncherApplication*> m_applicationForExecutable;
91 GConfItemQmlWrapper* m_favorites_list;92 QConf* m_dconf_launcher;
9293
93 /* Startup notification support */94 /* Startup notification support */
94 SnDisplay *m_snDisplay;95 SnDisplay *m_snDisplay;
9596
=== modified file 'libunity-2d-private/Unity2d/plugin.cpp'
--- libunity-2d-private/Unity2d/plugin.cpp 2011-07-14 11:17:30 +0000
+++ libunity-2d-private/Unity2d/plugin.cpp 2011-07-27 15:02:42 +0000
@@ -47,6 +47,7 @@
47#include "cacheeffect.h"47#include "cacheeffect.h"
48#include "iconutilities.h"48#include "iconutilities.h"
49#include "unity2dtr.h"49#include "unity2dtr.h"
50#include "giodefaultapplication.h"
5051
51#include "mimedata.h"52#include "mimedata.h"
52#include "dragdropevent.h"53#include "dragdropevent.h"
@@ -127,6 +128,8 @@
127 qmlRegisterType<ForceVisibleBehavior>(uri, 0, 1, "ForceVisibleBehavior");128 qmlRegisterType<ForceVisibleBehavior>(uri, 0, 1, "ForceVisibleBehavior");
128129
129 qmlRegisterType<IconUtilities>(); // Register the type as non creatable130 qmlRegisterType<IconUtilities>(); // Register the type as non creatable
131
132 qmlRegisterType<GioDefaultApplication>(uri, 0, 1, "GioDefaultApplication");
130}133}
131134
132void Unity2dPlugin::initializeEngine(QDeclarativeEngine *engine, const char *uri)135void Unity2dPlugin::initializeEngine(QDeclarativeEngine *engine, const char *uri)
133136
=== modified file 'libunity-2d-private/Unity2d/qsortfilterproxymodelqml.cpp'
--- libunity-2d-private/Unity2d/qsortfilterproxymodelqml.cpp 2011-04-28 13:09:25 +0000
+++ libunity-2d-private/Unity2d/qsortfilterproxymodelqml.cpp 2011-07-27 15:02:42 +0000
@@ -18,14 +18,17 @@
18#include <debug_p.h>18#include <debug_p.h>
1919
20QSortFilterProxyModelQML::QSortFilterProxyModelQML(QObject *parent) :20QSortFilterProxyModelQML::QSortFilterProxyModelQML(QObject *parent) :
21 QSortFilterProxyModel(parent)21 QSortFilterProxyModel(parent), m_limit(-1)
22{22{
23 connect(this, SIGNAL(modelReset()), SIGNAL(countChanged()));
24 connect(this, SIGNAL(rowsInserted(QModelIndex,int,int)), SIGNAL(countChanged()));
25 connect(this, SIGNAL(rowsRemoved(QModelIndex,int,int)), SIGNAL(countChanged()));
23}26}
2427
25void28void QSortFilterProxyModelQML::setRoleNames(const QHash<int,QByteArray> &roleNames)
26QSortFilterProxyModelQML::updateRoleNames()
27{29{
28 setRoleNames(((QAbstractItemModel*)sourceModel())->roleNames());30 QSortFilterProxyModel::setRoleNames(roleNames);
31 Q_EMIT roleNamesChanged(roleNames);
29}32}
3033
31QObject*34QObject*
@@ -51,10 +54,25 @@
51 sourceModel()->disconnect(this);54 sourceModel()->disconnect(this);
52 }55 }
5356
57 /* Workaround for limitation of QAbstractProxyModel: if sourceModel's
58 roleNames changes, the QAbstractProxyModel's roleNames are not updated
59 to reflect that change.
60 As a consequence it works around Qt bug http://bugreports.qt.nokia.com/browse/QTBUG-20405
61 */
62 bool hasRoleNamesChangedSignal;
63 hasRoleNamesChangedSignal = connect(itemModel, SIGNAL(roleNamesChanged(QHash<int,QByteArray>)), SLOT(setRoleNames(QHash<int,QByteArray>)));
64 if (!hasRoleNamesChangedSignal) {
65 UQ_WARNING << "received a sourceModel that does not notify of changes of its roleNames";
66 }
67 setRoleNames(itemModel->roleNames());
68
54 setSourceModel(itemModel);69 setSourceModel(itemModel);
5570
56 connect(itemModel, SIGNAL(modelAboutToBeReset()), SLOT(updateRoleNames()));71 connect(itemModel, SIGNAL(modelReset()), SIGNAL(totalCountChanged()));
57 connect(itemModel, SIGNAL(modelReset()), SLOT(updateRoleNames()));72 connect(itemModel, SIGNAL(rowsInserted(QModelIndex,int,int)), SIGNAL(totalCountChanged()));
73 connect(itemModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), SIGNAL(totalCountChanged()));
74 Q_EMIT totalCountChanged();
75 Q_EMIT countChanged();
58}76}
5977
60QVariantMap78QVariantMap
@@ -76,7 +94,97 @@
76}94}
7795
78int96int
97QSortFilterProxyModelQML::totalCount() const
98{
99 if (sourceModel() != NULL) {
100 return sourceModel()->rowCount();
101 } else {
102 return 0;
103 }
104}
105
106int
79QSortFilterProxyModelQML::count()107QSortFilterProxyModelQML::count()
80{108{
81 return rowCount();109 return rowCount();
82}110}
111
112int
113QSortFilterProxyModelQML::rowCount(const QModelIndex &parent) const
114{
115 int count = QSortFilterProxyModel::rowCount(parent);
116 if (m_limit >= 0) {
117 return qMin(count, m_limit);
118 } else {
119 return count;
120 }
121}
122
123int
124QSortFilterProxyModelQML::limit() const
125{
126 return m_limit;
127}
128
129void
130QSortFilterProxyModelQML::setLimit(int limit)
131{
132 if (limit != m_limit) {
133 int count = QSortFilterProxyModel::rowCount();
134 int start;
135 int end;
136 bool inserted = false;
137 bool removed = false;
138
139 if (m_limit == -1) {
140 if (limit < count) {
141 start = qMin(count, limit);
142 end = count-1;
143 removed = true;
144 }
145 } else if (limit == -1) {
146 if (m_limit < count) {
147 start = qMin(count, m_limit);
148 end = count-1;
149 inserted = true;
150 }
151 } else if (m_limit >= count && limit >= count) {
152 // Nothing
153 } else if (m_limit >= count && limit < count) {
154 start = qMin(count, limit);
155 end = count-1;
156 removed = true;
157 } else if (m_limit < count && limit >= count) {
158 start = qMin(count, m_limit);
159 end = count-1;
160 inserted = true;
161 } else if (m_limit < count && limit < count) {
162 if (m_limit < limit) {
163 start = qMin(count, m_limit);
164 end = qMin(count, limit)-1;
165 inserted = true;
166 } else {
167 start = qMin(count, limit);
168 end = qMin(count, m_limit)-1;
169 removed = true;
170 }
171 }
172
173 if (inserted) {
174 beginInsertRows(QModelIndex(), start, end);
175 }
176 if (removed) {
177 beginRemoveRows(QModelIndex(), start, end);
178 }
179 m_limit = limit;
180
181 if (inserted) {
182 endInsertRows();
183 }
184 if (removed) {
185 endRemoveRows();
186 }
187
188 Q_EMIT limitChanged();
189 }
190}
83191
=== modified file 'libunity-2d-private/Unity2d/qsortfilterproxymodelqml.h'
--- libunity-2d-private/Unity2d/qsortfilterproxymodelqml.h 2011-03-23 14:04:23 +0000
+++ libunity-2d-private/Unity2d/qsortfilterproxymodelqml.h 2011-07-27 15:02:42 +0000
@@ -24,21 +24,36 @@
24 Q_OBJECT24 Q_OBJECT
2525
26 Q_PROPERTY(QObject* model READ sourceModelQObject WRITE setSourceModelQObject)26 Q_PROPERTY(QObject* model READ sourceModelQObject WRITE setSourceModelQObject)
27 Q_PROPERTY(int limit READ limit WRITE setLimit NOTIFY limitChanged)
28 Q_PROPERTY(int totalCount READ totalCount NOTIFY totalCountChanged)
29 Q_PROPERTY(int count READ count NOTIFY countChanged)
2730
28public:31public:
29 explicit QSortFilterProxyModelQML(QObject *parent = 0);32 explicit QSortFilterProxyModelQML(QObject *parent = 0);
3033
31 Q_INVOKABLE QVariantMap get(int row);34 Q_INVOKABLE QVariantMap get(int row);
32 Q_INVOKABLE int count();35 Q_INVOKABLE int count();
36 int rowCount(const QModelIndex &parent = QModelIndex()) const;
3337
34 /* getters */38 /* getters */
35 QObject* sourceModelQObject() const;39 QObject* sourceModelQObject() const;
40 int limit() const;
41 int totalCount() const;
3642
37 /* setters */43 /* setters */
38 void setSourceModelQObject(QObject *model);44 void setSourceModelQObject(QObject *model);
3945 void setLimit(int limit);
40private Q_SLOTS:46
41 void updateRoleNames();47 Q_SLOT void setRoleNames(const QHash<int,QByteArray> &roleNames);
48
49Q_SIGNALS:
50 void limitChanged();
51 void totalCountChanged();
52 void countChanged();
53 void roleNamesChanged(const QHash<int,QByteArray> &);
54
55private:
56 int m_limit;
42};57};
4358
44#endif // QSORTFILTERPROXYMODELQML_H59#endif // QSORTFILTERPROXYMODELQML_H
4560
=== modified file 'libunity-2d-private/Unity2d/workspacesinfo.cpp'
--- libunity-2d-private/Unity2d/workspacesinfo.cpp 2011-06-27 13:43:05 +0000
+++ libunity-2d-private/Unity2d/workspacesinfo.cpp 2011-07-27 15:02:42 +0000
@@ -9,8 +9,6 @@
9#include <libwnck/workspace.h>9#include <libwnck/workspace.h>
10}10}
1111
12#include "gconfitem-qml-wrapper.h"
13
14#include <QAbstractEventDispatcher>12#include <QAbstractEventDispatcher>
15#include <QX11Info>13#include <QX11Info>
1614
1715
=== modified file 'libunity-2d-private/src/CMakeLists.txt'
--- libunity-2d-private/src/CMakeLists.txt 2011-07-12 10:30:50 +0000
+++ libunity-2d-private/src/CMakeLists.txt 2011-07-27 15:02:42 +0000
@@ -1,7 +1,3 @@
1# Dependencies
2pkg_check_modules(GLIB REQUIRED glib-2.0)
3pkg_check_modules(WNCK REQUIRED libwnck-1.0)
4
5# Sources1# Sources
6set(libunity-2d-private_SRCS2set(libunity-2d-private_SRCS
7 gconnector.cpp3 gconnector.cpp
@@ -24,6 +20,7 @@
24 edgehitdetector.cpp20 edgehitdetector.cpp
25 forcevisiblebehavior.cpp21 forcevisiblebehavior.cpp
26 intellihidebehavior.cpp22 intellihidebehavior.cpp
23 giodefaultapplication.cpp
27 )24 )
2825
29# Build26# Build
3027
=== added file 'libunity-2d-private/src/giodefaultapplication.cpp'
--- libunity-2d-private/src/giodefaultapplication.cpp 1970-01-01 00:00:00 +0000
+++ libunity-2d-private/src/giodefaultapplication.cpp 2011-07-27 15:02:42 +0000
@@ -0,0 +1,107 @@
1/*
2 * Copyright (C) 2011 Canonical, Ltd.
3 *
4 * Authors:
5 * Florian Boucault <florian.boucault@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#include "giodefaultapplication.h"
21
22// libunity-2d
23#include <gscopedpointer.h>
24
25// Qt
26#include <QFileSystemWatcher>
27#include <QDir>
28#include <QTimer>
29
30// gio
31#include <gio/gio.h>
32#include <gio/gdesktopappinfo.h>
33
34static const QString MIMEAPPS_FILE = QDir::homePath() + QString("/.local/share/applications/mimeapps.list");
35
36GioDefaultApplication::GioDefaultApplication(QObject* parent)
37 : QObject(parent),
38 m_contentType(""),
39 m_desktopFile(""),
40 m_mimeappsWatcher(new QFileSystemWatcher(this))
41{
42 /* GIO does not have any signal to inform us of changes in default
43 applications to handle a certain content type. Work around that
44 by monitoring file MIMEAPPS_FILE that is overwritten when default
45 applications change. */
46 m_mimeappsWatcher->addPath(MIMEAPPS_FILE);
47 connect(m_mimeappsWatcher, SIGNAL(fileChanged(const QString&)),
48 SLOT(onMimeappsFileChanged()));
49
50}
51
52void GioDefaultApplication::onMimeappsFileChanged()
53{
54 /* FIXME: wait for 10 seconds before updating the desktop file because
55 of a bug in gio where g_app_info_get_default_for_type will not immediately
56 return the updated result.
57 Ref.: https://bugzilla.gnome.org/show_bug.cgi?id=653999
58 */
59 QTimer::singleShot(10000, this, SLOT(updateDesktopFile()));
60 /* If the file is already being monitored, we shouldn’t need to do anything.
61 However it seems that in some cases, a change to the file will stop
62 emiting further fileChanged signals, despite the file still being in the
63 list of monitored files. This is the case when the desktop file is being
64 edited in gedit for example. This may be a bug in QT itself.
65 To work around this issue, remove the path and add it again. */
66 m_mimeappsWatcher->removePath(MIMEAPPS_FILE);
67 m_mimeappsWatcher->addPath(MIMEAPPS_FILE);
68}
69
70QString GioDefaultApplication::desktopFile() const
71{
72 return m_desktopFile;
73}
74
75QString GioDefaultApplication::contentType() const
76{
77 return m_contentType;
78}
79
80void GioDefaultApplication::setContentType(const QString& contentType)
81{
82 if (contentType == m_contentType) {
83 return;
84 }
85
86 m_contentType = contentType;
87 Q_EMIT contentTypeChanged();
88 updateDesktopFile();
89}
90
91void GioDefaultApplication::updateDesktopFile()
92{
93 GObjectScopedPointer<GAppInfo> app_info;
94 QByteArray byte_array = m_contentType.toUtf8();
95 gchar *content_type = byte_array.data();
96
97 app_info.reset(g_app_info_get_default_for_type(content_type, false));
98 if (!app_info.isNull()) {
99 m_desktopFile = QString::fromUtf8(g_desktop_app_info_get_filename((GDesktopAppInfo*)app_info.data()));
100 } else {
101 m_desktopFile = "";
102 }
103
104 Q_EMIT desktopFileChanged();
105}
106
107#include "giodefaultapplication.moc"
0108
=== added file 'libunity-2d-private/src/giodefaultapplication.h'
--- libunity-2d-private/src/giodefaultapplication.h 1970-01-01 00:00:00 +0000
+++ libunity-2d-private/src/giodefaultapplication.h 2011-07-27 15:02:42 +0000
@@ -0,0 +1,63 @@
1/*
2 * Copyright (C) 2011 Canonical, Ltd.
3 *
4 * Authors:
5 * Florian Boucault <florian.boucault@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#ifndef GIODEFAULTAPPLICATION_H
21#define GIODEFAULTAPPLICATION_H
22
23#include <QObject>
24#include <QString>
25
26class QFileSystemWatcher;
27
28/* Wrapper around GIO's g_app_info_get_default_for_type.
29 To use it, set the contentType property and the desktopFile will contain the
30 path to the desktop file of the application handling that kind of content.
31*/
32class GioDefaultApplication : public QObject
33{
34 Q_OBJECT
35
36 Q_PROPERTY(QString desktopFile READ desktopFile NOTIFY desktopFileChanged)
37 Q_PROPERTY(QString contentType READ contentType WRITE setContentType NOTIFY contentTypeChanged)
38
39public:
40 GioDefaultApplication(QObject* parent=0);
41
42 /* getters */
43 QString desktopFile() const;
44 QString contentType() const;
45
46 /* setters */
47 void setContentType(const QString& contentType);
48
49Q_SIGNALS:
50 void desktopFileChanged();
51 void contentTypeChanged();
52
53private:
54 Q_SLOT void updateDesktopFile();
55 Q_SLOT void onMimeappsFileChanged();
56
57 QString m_contentType;
58 QString m_desktopFile;
59 QFileSystemWatcher* m_mimeappsWatcher;
60};
61
62#endif // GIODEFAULTAPPLICATION
63
064
=== modified file 'libunity-2d-private/src/unity2dapplication.cpp'
--- libunity-2d-private/src/unity2dapplication.cpp 2011-06-11 10:50:03 +0000
+++ libunity-2d-private/src/unity2dapplication.cpp 2011-07-27 15:02:42 +0000
@@ -21,8 +21,17 @@
2121
22// Self22// Self
23#include "unity2dapplication.h"23#include "unity2dapplication.h"
24#include "config.h"
25
26// libunity-2d
27#include <debug_p.h>
28#include <unity2ddebug.h>
2429
25// Qt30// Qt
31#include <QWindowsStyle>
32
33// GTK
34#include <gtk/gtk.h>
2635
27AbstractX11EventFilter::~AbstractX11EventFilter()36AbstractX11EventFilter::~AbstractX11EventFilter()
28{37{
@@ -32,9 +41,38 @@
32 }41 }
33}42}
3443
44void Unity2dApplication::earlySetup(int& argc, char** argv)
45{
46 // Parts of unity-2d uses GTK so it needs to be initialized
47 gtk_init(&argc, &argv);
48
49 Unity2dDebug::installHandlers();
50
51 /* When the environment variable QT_GRAPHICSSYSTEM is not set, force
52 * graphics system to 'raster' instead of the default 'native' which on X11
53 * is 'XRender'. 'XRender' defaults to using a TrueColor visual. We do
54 * _not_ mimick that behaviour with 'raster' by calling
55 * QApplication::setColorSpec because of bugs where some pixmaps become
56 * blueish or black rectangular artifacts were appearing randomly:
57 *
58 * https://bugs.launchpad.net/unity-2d/+bug/689877
59 * https://bugs.launchpad.net/unity-2d/+bug/734143
60 */
61 if(getenv("QT_GRAPHICSSYSTEM") == 0) {
62 QApplication::setGraphicsSystem("raster");
63 }
64}
65
35Unity2dApplication::Unity2dApplication(int& argc, char** argv)66Unity2dApplication::Unity2dApplication(int& argc, char** argv)
36: QApplication(argc, argv)67: QApplication(argc, argv)
37{68{
69 /* Allow developers to run Unity 2D uninstalled by telling dconf-qt
70 where to look for Unity 2D's schemas.
71 It relies on the fact that the schema is compiled when running cmake.
72 */
73 if (!isRunningInstalled()) {
74 qputenv("GSETTINGS_SCHEMA_DIR", unity2dDirectory().toLocal8Bit() + "/data");
75 }
38}76}
3977
40Unity2dApplication::~Unity2dApplication()78Unity2dApplication::~Unity2dApplication()
4179
=== modified file 'libunity-2d-private/src/unity2dapplication.h'
--- libunity-2d-private/src/unity2dapplication.h 2011-02-28 17:14:19 +0000
+++ libunity-2d-private/src/unity2dapplication.h 2011-07-27 15:02:42 +0000
@@ -49,6 +49,13 @@
49 void removeX11EventFilter(AbstractX11EventFilter*);49 void removeX11EventFilter(AbstractX11EventFilter*);
5050
51 /**51 /**
52 * This method must be called *before* instantiating a Unity2dApplication.
53 * It inits gtk and adjusts settings like the graphics system and the Qt
54 * style.
55 */
56 static void earlySetup(int& argc, char** argv);
57
58 /**
52 * Note: This function will return a null pointer if you did not use a Unity2dApplication in your application!59 * Note: This function will return a null pointer if you did not use a Unity2dApplication in your application!
53 */60 */
54 static Unity2dApplication* instance();61 static Unity2dApplication* instance();
5562
=== modified file 'libunity-2d-private/tests/CMakeLists.txt'
--- libunity-2d-private/tests/CMakeLists.txt 2011-07-12 10:30:50 +0000
+++ libunity-2d-private/tests/CMakeLists.txt 2011-07-27 15:02:42 +0000
@@ -40,6 +40,7 @@
40 unity2dtrtest40 unity2dtrtest
41 launchermenutest41 launchermenutest
42 listaggregatormodeltest42 listaggregatormodeltest
43 qsortfilterproxymodeltest
43 )44 )
4445
45add_custom_target(unity2dtr_po COMMAND46add_custom_target(unity2dtr_po COMMAND
4647
=== modified file 'libunity-2d-private/tests/keyboardmodifiersmonitortest.cpp'
--- libunity-2d-private/tests/keyboardmodifiersmonitortest.cpp 2011-01-26 15:50:26 +0000
+++ libunity-2d-private/tests/keyboardmodifiersmonitortest.cpp 2011-07-27 15:02:42 +0000
@@ -39,6 +39,7 @@
39#define UQ_TEST_MAIN(TestObject) \39#define UQ_TEST_MAIN(TestObject) \
40int main(int argc, char *argv[]) \40int main(int argc, char *argv[]) \
41{ \41{ \
42 Unity2dApplication::earlySetup(argc, argv); \
42 Unity2dApplication app(argc, argv); \43 Unity2dApplication app(argc, argv); \
43 QTEST_DISABLE_KEYPAD_NAVIGATION \44 QTEST_DISABLE_KEYPAD_NAVIGATION \
44 TestObject tc; \45 TestObject tc; \
4546
=== modified file 'libunity-2d-private/tests/mouseareademo.cpp'
--- libunity-2d-private/tests/mouseareademo.cpp 2011-02-15 18:18:13 +0000
+++ libunity-2d-private/tests/mouseareademo.cpp 2011-07-27 15:02:42 +0000
@@ -29,6 +29,7 @@
2929
30int main(int argc, char** argv)30int main(int argc, char** argv)
31{31{
32 Unity2dApplication::earlySetup(argc, argv);
32 Unity2dApplication app(argc, argv);33 Unity2dApplication app(argc, argv);
33 QWidget window;34 QWidget window;
34 QLabel* enteredLabel = new QLabel("Entered");35 QLabel* enteredLabel = new QLabel("Entered");
3536
=== added file 'libunity-2d-private/tests/qsortfilterproxymodeltest.cpp'
--- libunity-2d-private/tests/qsortfilterproxymodeltest.cpp 1970-01-01 00:00:00 +0000
+++ libunity-2d-private/tests/qsortfilterproxymodeltest.cpp 2011-07-27 15:02:42 +0000
@@ -0,0 +1,384 @@
1/*
2 * Copyright (C) 2011 Canonical, Ltd.
3 *
4 * Authors:
5 * Florian Boucault <florian.boucault@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// local
21#include "qsortfilterproxymodelqml.h"
22
23// Qt
24#include <QTest>
25#include <QSignalSpy>
26#include <QModelIndex>
27#include <QAbstractListModel>
28#include <QDebug>
29
30
31class MockListModel : public QAbstractListModel
32{
33 Q_OBJECT
34
35public:
36 MockListModel(QObject* parent = 0)
37 : QAbstractListModel(parent)
38 {
39 }
40
41 int rowCount(const QModelIndex& parent = QModelIndex()) const
42 {
43 return m_list.size();
44 }
45
46 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const
47 {
48 Q_UNUSED(role)
49
50 if (!index.isValid() || index.row() < 0 || index.row() >= m_list.size()) {
51 return QVariant();
52 }
53 return QVariant(m_list[index.row()]);
54 }
55
56 void setRoleNames(const QHash<int,QByteArray> &roleNames) {
57 QAbstractListModel::setRoleNames(roleNames);
58 Q_EMIT roleNamesChanged(roleNames);
59 }
60
61 bool insertRows(int row, int count, const QModelIndex &parent=QModelIndex()) {
62 beginInsertRows(parent, row, row+count-1);
63 for (int i=0; i<count; i++) {
64 m_list.insert(i+row, "test"+i);
65 }
66 endInsertRows();
67 return true;
68 }
69
70 bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex()) {
71 beginRemoveRows(parent, row, row+count-1);
72 for (int i=0; i<count; i++) {
73 m_list.removeAt(row);
74 }
75 endInsertRows();
76 return true;
77 }
78
79Q_SIGNALS:
80 void roleNamesChanged(const QHash<int,QByteArray> &);
81
82private:
83 QStringList m_list;
84};
85
86class QSortFilterProxyModelTest : public QObject
87{
88 Q_OBJECT
89
90private Q_SLOTS:
91
92 void initTestCase() {
93 qRegisterMetaType<QModelIndex>("QModelIndex");
94 }
95
96 void testRoleNamesSetAfter()
97 {
98 QSortFilterProxyModelQML proxy;
99 MockListModel model;
100 QHash<int, QByteArray> roles;
101
102 proxy.setSourceModelQObject(&model);
103
104 roles.clear();
105 roles[0] = "role0";
106 roles[1] = "role1";
107 model.setRoleNames(roles);
108 QCOMPARE(model.roleNames(), proxy.roleNames());
109 }
110
111 void testRoleNamesSetBefore()
112 {
113 QSortFilterProxyModelQML proxy;
114 MockListModel model;
115 QHash<int, QByteArray> roles;
116
117 roles.clear();
118 roles[0] = "role0";
119 roles[1] = "role1";
120 model.setRoleNames(roles);
121
122 proxy.setSourceModelQObject(&model);
123 QCOMPARE(model.roleNames(), proxy.roleNames());
124 }
125
126 void testCountSetAfter()
127 {
128 QSortFilterProxyModelQML proxy;
129 MockListModel model;
130 model.insertRows(0, 5);
131
132 QSignalSpy spyOnCountChanged(&proxy, SIGNAL(countChanged()));
133
134 proxy.setSourceModelQObject(&model);
135 QCOMPARE(proxy.count(), 5);
136 QVERIFY(spyOnCountChanged.count() >= 1);
137 }
138
139 void testCountInsert()
140 {
141 QSortFilterProxyModelQML proxy;
142 MockListModel model;
143
144 proxy.setSourceModelQObject(&model);
145
146 QSignalSpy spyOnCountChanged(&proxy, SIGNAL(countChanged()));
147
148 model.insertRows(0, 5);
149 QCOMPARE(proxy.count(), 5);
150 QCOMPARE(spyOnCountChanged.count(), 1);
151 }
152
153 void testCountRemove()
154 {
155 QSortFilterProxyModelQML proxy;
156 MockListModel model;
157 model.insertRows(0, 5);
158
159 proxy.setSourceModelQObject(&model);
160
161 QSignalSpy spyOnCountChanged(&proxy, SIGNAL(countChanged()));
162
163 model.removeRows(0, 3);
164 QCOMPARE(proxy.count(), 2);
165 QCOMPARE(spyOnCountChanged.count(), 1);
166 }
167
168 void testLimitCount()
169 {
170 QSortFilterProxyModelQML proxy;
171 MockListModel model;
172
173 proxy.setSourceModelQObject(&model);
174 proxy.setLimit(3);
175
176 QSignalSpy spyOnCountChanged(&proxy, SIGNAL(countChanged()));
177
178 model.insertRows(0, 5);
179 QCOMPARE(proxy.count(), 3);
180 QCOMPARE(spyOnCountChanged.count(), 1);
181 }
182
183 void testLimitLesserThanCount()
184 {
185 QSortFilterProxyModelQML proxy;
186 MockListModel model;
187 QList<QVariant> arguments;
188 model.insertRows(0, 10);
189
190 proxy.setSourceModelQObject(&model);
191
192 QSignalSpy spyOnRowsRemoved(&proxy, SIGNAL(rowsRemoved(const QModelIndex &, int, int)));
193 QSignalSpy spyOnRowsInserted(&proxy, SIGNAL(rowsInserted(const QModelIndex &, int, int)));
194 QSignalSpy spyOnCountChanged(&proxy, SIGNAL(countChanged()));
195
196 proxy.setLimit(5);
197 QCOMPARE(spyOnRowsRemoved.count(), 1);
198 QCOMPARE(spyOnRowsInserted.count(), 0);
199 QCOMPARE(spyOnCountChanged.count(), 1);
200 arguments = spyOnRowsRemoved.takeFirst();
201 QCOMPARE(arguments.at(1).toInt(), 5);
202 QCOMPARE(arguments.at(2).toInt(), 9);
203 QCOMPARE(proxy.count(), 5);
204 spyOnRowsRemoved.clear();
205 spyOnCountChanged.clear();
206
207 proxy.setLimit(7);
208 QCOMPARE(spyOnRowsInserted.count(), 1);
209 QCOMPARE(spyOnRowsRemoved.count(), 0);
210 QCOMPARE(spyOnCountChanged.count(), 1);
211 arguments = spyOnRowsInserted.takeFirst();
212 QCOMPARE(arguments.at(1).toInt(), 5);
213 QCOMPARE(arguments.at(2).toInt(), 6);
214 QCOMPARE(proxy.count(), 7);
215 spyOnRowsInserted.clear();
216 spyOnCountChanged.clear();
217
218 proxy.setLimit(3);
219 QCOMPARE(spyOnRowsRemoved.count(), 1);
220 QCOMPARE(spyOnRowsInserted.count(), 0);
221 QCOMPARE(spyOnCountChanged.count(), 1);
222 arguments = spyOnRowsRemoved.takeFirst();
223 QCOMPARE(arguments.at(1).toInt(), 3);
224 QCOMPARE(arguments.at(2).toInt(), 6);
225 QCOMPARE(proxy.count(), 3);
226 spyOnRowsRemoved.clear();
227 spyOnCountChanged.clear();
228 }
229
230 void testLimitGreaterThanCount()
231 {
232 QSortFilterProxyModelQML proxy;
233 MockListModel model;
234 QList<QVariant> arguments;
235 model.insertRows(0, 5);
236
237 proxy.setSourceModelQObject(&model);
238
239 QSignalSpy spyOnRowsRemoved(&proxy, SIGNAL(rowsRemoved(const QModelIndex &, int, int)));
240 QSignalSpy spyOnRowsInserted(&proxy, SIGNAL(rowsInserted(const QModelIndex &, int, int)));
241 QSignalSpy spyOnCountChanged(&proxy, SIGNAL(countChanged()));
242
243 proxy.setLimit(7);
244 QCOMPARE(spyOnRowsRemoved.count(), 0);
245 QCOMPARE(spyOnRowsInserted.count(), 0);
246 QCOMPARE(spyOnCountChanged.count(), 0);
247 QCOMPARE(proxy.count(), 5);
248
249 proxy.setLimit(5);
250 QCOMPARE(spyOnRowsRemoved.count(), 0);
251 QCOMPARE(spyOnRowsInserted.count(), 0);
252 QCOMPARE(spyOnCountChanged.count(), 0);
253 QCOMPARE(proxy.count(), 5);
254
255 proxy.setLimit(3);
256 QCOMPARE(spyOnRowsInserted.count(), 0);
257 QCOMPARE(spyOnRowsRemoved.count(), 1);
258 QCOMPARE(spyOnCountChanged.count(), 1);
259 arguments = spyOnRowsRemoved.takeFirst();
260 QCOMPARE(arguments.at(1).toInt(), 3);
261 QCOMPARE(arguments.at(2).toInt(), 4);
262 QCOMPARE(proxy.count(), 3);
263 spyOnRowsRemoved.clear();
264 spyOnCountChanged.clear();
265
266 proxy.setLimit(4);
267 QCOMPARE(spyOnRowsRemoved.count(), 0);
268 QCOMPARE(spyOnRowsInserted.count(), 1);
269 QCOMPARE(spyOnCountChanged.count(), 1);
270 arguments = spyOnRowsInserted.takeFirst();
271 QCOMPARE(arguments.at(1).toInt(), 3);
272 QCOMPARE(arguments.at(2).toInt(), 3);
273 QCOMPARE(proxy.count(), 4);
274 spyOnRowsInserted.clear();
275 spyOnCountChanged.clear();
276
277 proxy.setLimit(7);
278 QCOMPARE(spyOnRowsRemoved.count(), 0);
279 QCOMPARE(spyOnRowsInserted.count(), 1);
280 QCOMPARE(spyOnCountChanged.count(), 1);
281 arguments = spyOnRowsInserted.takeFirst();
282 QCOMPARE(arguments.at(1).toInt(), 4);
283 QCOMPARE(arguments.at(2).toInt(), 4);
284 QCOMPARE(proxy.count(), 5);
285 spyOnRowsInserted.clear();
286 spyOnCountChanged.clear();
287 }
288
289 void testLimitMinusOne()
290 {
291 QSortFilterProxyModelQML proxy;
292 MockListModel model;
293 QList<QVariant> arguments;
294 model.insertRows(0, 5);
295
296 proxy.setSourceModelQObject(&model);
297
298 QSignalSpy spyOnRowsRemoved(&proxy, SIGNAL(rowsRemoved(const QModelIndex &, int, int)));
299 QSignalSpy spyOnRowsInserted(&proxy, SIGNAL(rowsInserted(const QModelIndex &, int, int)));
300 QSignalSpy spyOnCountChanged(&proxy, SIGNAL(countChanged()));
301
302 proxy.setLimit(7);
303 QCOMPARE(spyOnRowsRemoved.count(), 0);
304 QCOMPARE(spyOnRowsInserted.count(), 0);
305 QCOMPARE(spyOnCountChanged.count(), 0);
306 QCOMPARE(proxy.count(), 5);
307
308 proxy.setLimit(-1);
309 QCOMPARE(spyOnRowsRemoved.count(), 0);
310 QCOMPARE(spyOnRowsInserted.count(), 0);
311 QCOMPARE(spyOnCountChanged.count(), 0);
312 QCOMPARE(proxy.count(), 5);
313
314 proxy.setLimit(3);
315 QCOMPARE(spyOnRowsInserted.count(), 0);
316 QCOMPARE(spyOnRowsRemoved.count(), 1);
317 QCOMPARE(spyOnCountChanged.count(), 1);
318 arguments = spyOnRowsRemoved.takeFirst();
319 QCOMPARE(arguments.at(1).toInt(), 3);
320 QCOMPARE(arguments.at(2).toInt(), 4);
321 QCOMPARE(proxy.count(), 3);
322 spyOnRowsRemoved.clear();
323 spyOnCountChanged.clear();
324
325 proxy.setLimit(-1);
326 QCOMPARE(spyOnRowsRemoved.count(), 0);
327 QCOMPARE(spyOnRowsInserted.count(), 1);
328 QCOMPARE(spyOnCountChanged.count(), 1);
329 arguments = spyOnRowsInserted.takeFirst();
330 QCOMPARE(arguments.at(1).toInt(), 3);
331 QCOMPARE(arguments.at(2).toInt(), 4);
332 QCOMPARE(proxy.count(), 5);
333 spyOnRowsInserted.clear();
334 spyOnCountChanged.clear();
335 }
336
337 void testLimitInsert() {
338 QSortFilterProxyModelQML proxy;
339 MockListModel model;
340 QList<QVariant> arguments;
341
342 proxy.setSourceModelQObject(&model);
343 proxy.setLimit(7);
344
345 QSignalSpy spyOnRowsRemoved(&proxy, SIGNAL(rowsRemoved(const QModelIndex &, int, int)));
346 QSignalSpy spyOnRowsInserted(&proxy, SIGNAL(rowsInserted(const QModelIndex &, int, int)));
347 QSignalSpy spyOnCountChanged(&proxy, SIGNAL(countChanged()));
348
349 model.insertRows(0, 5);
350 QCOMPARE(spyOnRowsRemoved.count(), 0);
351 QCOMPARE(spyOnRowsInserted.count(), 1);
352 QCOMPARE(spyOnCountChanged.count(), 1);
353 arguments = spyOnRowsInserted.takeFirst();
354 QCOMPARE(arguments.at(1).toInt(), 0);
355 QCOMPARE(arguments.at(2).toInt(), 4);
356 QCOMPARE(proxy.count(), 5);
357 spyOnRowsInserted.clear();
358 spyOnCountChanged.clear();
359
360 model.insertRows(2, 2);
361 QCOMPARE(spyOnRowsRemoved.count(), 0);
362 QCOMPARE(spyOnRowsInserted.count(), 1);
363 QCOMPARE(spyOnCountChanged.count(), 1);
364 arguments = spyOnRowsInserted.takeFirst();
365 QCOMPARE(arguments.at(1).toInt(), 2);
366 QCOMPARE(arguments.at(2).toInt(), 3);
367 QCOMPARE(proxy.count(), 7);
368 spyOnRowsInserted.clear();
369 spyOnCountChanged.clear();
370
371 /* FIXME: failing case due to QSortFilterProxyModel emitting
372 rowsInserted/rowsRemoved regardless of the limit */
373 //model.insertRows(5, 3);
374 //QCOMPARE(proxy.count(), 7);
375 //QCOMPARE(spyOnRowsRemoved.count(), 0);
376 //QCOMPARE(spyOnRowsInserted.count(), 0);
377 //QCOMPARE(spyOnCountChanged.count(), 0);
378 }
379};
380
381QTEST_MAIN(QSortFilterProxyModelTest)
382
383#include "qsortfilterproxymodeltest.moc"
384
0385
=== modified file 'panel/app/main.cpp'
--- panel/app/main.cpp 2011-06-06 09:23:48 +0000
+++ panel/app/main.cpp 2011-07-27 15:02:42 +0000
@@ -52,21 +52,7 @@
52int main(int argc, char** argv)52int main(int argc, char** argv)
53{53{
54 ThemeEngineHandler handler;54 ThemeEngineHandler handler;
5555 Unity2dApplication::earlySetup(argc, argv);
56 Unity2dDebug::installHandlers();
57
58 /* When the environment variable QT_GRAPHICSSYSTEM is not set,
59 force graphics system to 'raster' instead of the default 'native'
60 which on X11 is 'XRender'.
61 'XRender' defaults to using a TrueColor visual. We do _not_ mimick that
62 behaviour with 'raster' by calling QApplication::setColorSpec because
63 of a bug where black rectangular artifacts were appearing randomly:
64
65 https://bugs.launchpad.net/unity-2d/+bug/734143
66 */
67 if(getenv("QT_GRAPHICSSYSTEM") == 0) {
68 QApplication::setGraphicsSystem("raster");
69 }
70 Unity2dApplication app(argc, argv);56 Unity2dApplication app(argc, argv);
71 QApplication::setStyle(new Unity2dStyle);57 QApplication::setStyle(new Unity2dStyle);
7258
7359
=== modified file 'panel/applets/CMakeLists.txt'
--- panel/applets/CMakeLists.txt 2011-06-22 08:22:14 +0000
+++ panel/applets/CMakeLists.txt 2011-07-27 15:02:42 +0000
@@ -14,11 +14,7 @@
1414
15pkg_check_modules(QTBAMF REQUIRED libqtbamf)15pkg_check_modules(QTBAMF REQUIRED libqtbamf)
16pkg_check_modules(DBUSMENUQT REQUIRED dbusmenu-qt)16pkg_check_modules(DBUSMENUQT REQUIRED dbusmenu-qt)
17pkg_check_modules(GTK REQUIRED gtk+-2.0)
18pkg_check_modules(INDICATOR REQUIRED indicator)17pkg_check_modules(INDICATOR REQUIRED indicator)
19pkg_check_modules(WNCK REQUIRED libwnck-1.0)
20
21find_package(X11 REQUIRED)
2218
23# Get indicator dirs from pkgconfig19# Get indicator dirs from pkgconfig
24read_pkg_variable(INDICATOR_DIR indicator indicatordir)20read_pkg_variable(INDICATOR_DIR indicator indicatordir)
2521
=== modified file 'panel/applets/indicator/indicator.c'
--- panel/applets/indicator/indicator.c 2011-03-30 14:50:35 +0000
+++ panel/applets/indicator/indicator.c 2011-07-27 15:02:42 +0000
@@ -152,6 +152,20 @@
152 return;152 return;
153}153}
154154
155static gboolean
156entry_scrolled (GtkWidget *menuitem, GdkEventScroll *event, gpointer data)
157{
158 IndicatorObject *io = g_object_get_data (G_OBJECT (menuitem), MENU_DATA_INDICATOR_OBJECT);
159 IndicatorObjectEntry *entry = g_object_get_data (G_OBJECT (menuitem), MENU_DATA_INDICATOR_ENTRY);
160
161 g_return_val_if_fail(INDICATOR_IS_OBJECT(io), FALSE);
162
163 g_signal_emit_by_name (io, "scroll", 1, event->direction);
164 g_signal_emit_by_name (io, "scroll-entry", entry, 1, event->direction);
165
166 return FALSE;
167}
168
155static void169static void
156entry_added (IndicatorObject * io, IndicatorObjectEntry * entry, GtkWidget * menubar)170entry_added (IndicatorObject * io, IndicatorObjectEntry * entry, GtkWidget * menubar)
157{171{
@@ -233,6 +247,7 @@
233247
234 g_object_set_data(G_OBJECT(menuitem), MENU_DATA_INDICATOR_ENTRY, entry);248 g_object_set_data(G_OBJECT(menuitem), MENU_DATA_INDICATOR_ENTRY, entry);
235 g_object_set_data(G_OBJECT(menuitem), MENU_DATA_INDICATOR_OBJECT, io);249 g_object_set_data(G_OBJECT(menuitem), MENU_DATA_INDICATOR_OBJECT, io);
250 g_signal_connect(G_OBJECT (menuitem), "scroll-event", G_CALLBACK(entry_scrolled), NULL);
236251
237 return;252 return;
238}253}
239254
=== modified file 'places/Home.qml'
--- places/Home.qml 2011-06-23 17:08:53 +0000
+++ places/Home.qml 2011-07-27 15:02:42 +0000
@@ -19,7 +19,7 @@
19import QtQuick 1.019import QtQuick 1.0
20import Unity2d 1.0 /* Necessary for SortFilterProxyModel and for the ImageProvider serving image://icons/theme_name/icon_name */20import Unity2d 1.0 /* Necessary for SortFilterProxyModel and for the ImageProvider serving image://icons/theme_name/icon_name */
2121
22Item {22FocusScope {
23 property variant model: PageModel {23 property variant model: PageModel {
24 /* model.entrySearchQuery is copied over to all place entries's globalSearchQuery property */24 /* model.entrySearchQuery is copied over to all place entries's globalSearchQuery property */
25 onEntrySearchQueryChanged: {25 onEntrySearchQueryChanged: {
@@ -36,7 +36,7 @@
36 var placeEntry, i36 var placeEntry, i
37 for (i=0; i<dash.places.rowCount(); i=i+1) {37 for (i=0; i<dash.places.rowCount(); i=i+1) {
38 placeEntry = dash.places.get(i)38 placeEntry = dash.places.get(i)
39 if (placeEntry.globalResultsModel != null && placeEntry.globalResultsModel.count() != 0) {39 if (placeEntry.globalResultsModel != null && placeEntry.globalResultsModel.count != 0) {
40 var firstResult = placeEntry.globalResultsModel.get(0)40 var firstResult = placeEntry.globalResultsModel.get(0)
41 /* Places give back the uri of the item in 'column_0' per specification */41 /* Places give back the uri of the item in 'column_0' per specification */
42 var uri = firstResult.column_042 var uri = firstResult.column_0
@@ -96,50 +96,39 @@
96 ListViewWithScrollbar {96 ListViewWithScrollbar {
97 id: globalSearch97 id: globalSearch
9898
99 focus: globalSearchActive
99 opacity: globalSearchActive ? 1 : 0100 opacity: globalSearchActive ? 1 : 0
100 anchors.fill: parent101 anchors.fill: parent
101102
102 list.model: dash.places103 model: dash.places
103104
104 list.delegate: UnityDefaultRenderer {105 bodyDelegate: UnityDefaultRenderer {
105 width: ListView.view.width106 placeEntryModel: model.item
106107 displayName: model.item.name
107 parentListView: list108 iconHint: model.item.icon
108 placeEntryModel: item109
109 displayName: item.name110 group_model: model.item.globalResultsModel
110 iconHint: item.icon111 property bool focusable: group_model != undefined && group_model.count > 0
111112 }
112 /* Filter out results for which the corresponding group's renderer113
113 is 'UnityEmptySearchRenderer'.114 headerDelegate: GroupHeader {
114 Each result has a column (the second one) containing the id of115 visible: body.needHeader && body.focusable
115 the group it belongs to (groupId).116 height: visible ? 32 : 0
116 */117
117 model: SortFilterProxyModel {118 property bool foldable: body.folded != undefined
118 model: item.globalResultsModel119 availableCount: foldable && body.group_model != null ? body.group_model.count - body.cellsPerRow : 0
119120 folded: foldable ? body.folded : false
120 /* FIXME: we ignore the groupId with renderer 'UnityEmptySearchRenderer'121 onClicked: if(foldable) body.folded = !body.folded
121 by hardcoding it instead of looking it up in the Place's122
122 groupsModel as Unity does.123 icon: body.iconHint
123124 label: body.displayName
124 Two solutions could be envisioned:
125 1) Actually looking for the row in the Place's groupsModel
126 that has in its first column 'UnityEmptySearchRenderer'.
127 That would require adding an API in libqtdee's DeeListModel.
128 2) Changing the behaviour of the place daemons so that the
129 Place's globalResultsModel is empty when there are no
130 results. The applications place does that but not the
131 files place.
132 */
133 property int ignoredGroupId: 5
134 filterRole: 2 /* groupId column */
135 filterRegExp: RegExp("^[^%1]$".arg(ignoredGroupId)) /* anything but the ignoredGroupId */
136 }
137 }125 }
138 }126 }
139127
140 Rectangle {128 FocusScope {
141 id: shortcuts129 id: shortcuts
142130
131 focus: !globalSearchActive
143 opacity: (!globalSearchActive && (shortcutsActive || dashView.dashMode == DashDeclarativeView.FullScreenMode)) ? 1 : 0132 opacity: (!globalSearchActive && (shortcutsActive || dashView.dashMode == DashDeclarativeView.FullScreenMode)) ? 1 : 0
144 anchors.horizontalCenter: parent.horizontalCenter133 anchors.horizontalCenter: parent.horizontalCenter
145 anchors.verticalCenter: parent.verticalCenter134 anchors.verticalCenter: parent.verticalCenter
@@ -147,11 +136,14 @@
147 width: 888136 width: 888
148 height: 466137 height: 466
149138
150 radius: 5139 Rectangle {
151 border.width: 1140 anchors.fill: parent
152 /* FIXME: wrong colors */141 radius: 5
153 border.color: Qt.rgba(1, 1, 1, 0.2)142 border.width: 1
154 color: Qt.rgba(0, 0, 0, 0.3)143 /* FIXME: wrong colors */
144 border.color: Qt.rgba(1, 1, 1, 0.2)
145 color: Qt.rgba(0, 0, 0, 0.3)
146 }
155147
156 Button {148 Button {
157 id: closeShortcutsButton149 id: closeShortcutsButton
@@ -182,11 +174,13 @@
182 on the default version if a custom one doesn’t exist. */174 on the default version if a custom one doesn’t exist. */
183 Loader {175 Loader {
184 id: customShortcutsLoader176 id: customShortcutsLoader
177 focus: status == Loader.Ready
185 anchors.fill: parent178 anchors.fill: parent
186 source: "HomeShortcutsCustomized.qml"179 source: "HomeShortcutsCustomized.qml"
187 }180 }
188 Loader {181 Loader {
189 id: defaultShortcutsLoader182 id: defaultShortcutsLoader
183 focus: !customShortcutsLoader.focus
190 anchors.fill: parent184 anchors.fill: parent
191 source: (customShortcutsLoader.status == Loader.Error) ? "HomeShortcuts.qml" : ""185 source: (customShortcutsLoader.status == Loader.Error) ? "HomeShortcuts.qml" : ""
192 }186 }
193187
=== added file 'places/HomeButtonDefaultApplication.qml'
--- places/HomeButtonDefaultApplication.qml 1970-01-01 00:00:00 +0000
+++ places/HomeButtonDefaultApplication.qml 2011-07-27 15:02:42 +0000
@@ -0,0 +1,48 @@
1/*
2 * This file is part of unity-2d
3 *
4 * Copyright 2011 Canonical Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19import QtQuick 1.0
20/* Necessary for:
21 - ImageProvider serving image://icons/theme_name/icon_name
22 - LauncherApplication
23*/
24import Unity2d 1.0
25
26HomeButton {
27 property alias contentType: defaultApplication.contentType
28
29 GioDefaultApplication {
30 id: defaultApplication
31 }
32
33 LauncherApplication {
34 id: application
35 desktop_file: defaultApplication.desktopFile
36 }
37
38 visible: application.desktop_file != ""
39
40 onClicked: {
41 dashView.active = false
42 application.activate()
43 }
44
45 icon: "image://icons/" + application.icon
46 iconSourceSize.width: 128
47 iconSourceSize.height: 128
48}
049
=== modified file 'places/HomeShortcuts.qml'
--- places/HomeShortcuts.qml 2011-06-23 17:08:53 +0000
+++ places/HomeShortcuts.qml 2011-07-27 15:02:42 +0000
@@ -19,16 +19,41 @@
19import QtQuick 1.019import QtQuick 1.0
20import Unity2d 1.0 /* Necessary for the ImageProvider serving image://icons/theme_name/icon_name */20import Unity2d 1.0 /* Necessary for the ImageProvider serving image://icons/theme_name/icon_name */
2121
22Flow {22Grid {
23 anchors.fill: parent23 anchors.fill: parent
24 anchors.topMargin: 2624 anchors.topMargin: 26
25 anchors.bottomMargin: 3525 anchors.bottomMargin: 35
26 anchors.leftMargin: 3226 anchors.leftMargin: 32
27 anchors.rightMargin: 3227 anchors.rightMargin: 32
28 spacing: 6128 spacing: 61
29 columns: 4
30 rows: 2
31
32 function selectChild(index) {
33 if (index < 0 || index >= children.length) return false
34 currentIndex = index
35 children[index].focus = true
36 return true
37 }
38
39 property int currentIndex: 0
40 Keys.onPressed: if (handleKeyPress(event.key)) event.accepted = true
41 function handleKeyPress(key) {
42 switch (key) {
43 case Qt.Key_Right:
44 return selectChild(currentIndex+1)
45 case Qt.Key_Left:
46 return selectChild(currentIndex-1)
47 case Qt.Key_Up:
48 return selectChild(currentIndex-columns)
49 case Qt.Key_Down:
50 return selectChild(currentIndex+columns)
51 }
52 }
2953
30 /* FIXME: dummy icons need to be replaced by design's */54 /* FIXME: dummy icons need to be replaced by design's */
31 HomeButton {55 HomeButton {
56 focus: true
32 label: u2d.tr("Media Apps")57 label: u2d.tr("Media Apps")
33 icon: "artwork/find_media_apps.png"58 icon: "artwork/find_media_apps.png"
34 onClicked: activatePlaceEntry("/usr/share/unity/places/applications.place", "Files", 9)59 onClicked: activatePlaceEntry("/usr/share/unity/places/applications.place", "Files", 9)
@@ -53,9 +78,9 @@
53 }78 }
5479
55 /* FIXME: use user's preferred applications instead of hardcoding them */80 /* FIXME: use user's preferred applications instead of hardcoding them */
56 HomeButtonApplication {81 HomeButtonDefaultApplication {
57 label: u2d.tr("Browse the Web")82 label: u2d.tr("Browse the Web")
58 key: "/desktop/gnome/applications/browser/exec"83 contentType: "x-scheme-handler/http"
59 }84 }
6085
61 HomeButtonApplication {86 HomeButtonApplication {
@@ -63,9 +88,9 @@
63 desktopFile: "shotwell.desktop"88 desktopFile: "shotwell.desktop"
64 }89 }
6590
66 HomeButtonApplication {91 HomeButtonDefaultApplication {
67 label: u2d.tr("Check Email")92 label: u2d.tr("Check Email")
68 key: "/desktop/gnome/url-handlers/mailto/command"93 contentType: "x-scheme-handler/mailto"
69 }94 }
7095
71 HomeButtonApplication {96 HomeButtonApplication {
7297
=== added file 'places/ListViewWithHeaders.qml'
--- places/ListViewWithHeaders.qml 1970-01-01 00:00:00 +0000
+++ places/ListViewWithHeaders.qml 2011-07-27 15:02:42 +0000
@@ -0,0 +1,277 @@
1/*
2 * This file is part of unity-2d
3 *
4 * Copyright 2010-2011 Canonical Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19import QtQuick 1.0
20
21/*
22 List item that behaves similarly to a ListView but supports adding headers
23 before every delegate.
24 It works around the lack of flexibility in section headers positioning of
25 ListView (cf. http://bugreports.qt.nokia.com/browse/QTBUG-12880). It also
26 supports delegates that are flickable by flicking their content properly
27 depending on where you are in the list.
28
29 To use it the following properties need to be set:
30 - bodyDelegate: Component used as a template for each item of the model; it
31 must have the following properties:
32 - 'contentY': same definition as a Flickable's
33 - 'totalHeight': the total height of the content of the body
34 - 'currentItem': a reference to the item of the body (e.g. a delegate of
35 a ListView) currently focused by the body
36 - headerDelegate: Component used as a template for the header preceding each body
37
38 Two behaviours are available for the headers positioning:
39 - normal: the headers are always positioned just before the body
40 - accordion: the headers are stacked at the top and bottom of the list
41
42 Currently, it only works in a vertical layout.
43*/
44FocusScope {
45 id: list
46
47 property alias flickable: mouse
48 property alias model: repeater.model
49 property bool accordion: false
50 /* bodyDelegate must be an item that has the following properties:
51 - 'contentY'
52 - 'totalHeight'
53 - 'currentItem'
54 */
55 property Component bodyDelegate
56 property Component headerDelegate
57 property int currentIndex: -1
58 /* FIXME: Should be read-only but it is not possible to define a read-only property from QML.
59 Ref.: https://bugreports.qt.nokia.com//browse/QTBUG-15257
60 */
61 property variant currentItem: items.childFromIndex(currentIndex)
62
63
64 clip: true
65
66 /* updateMouseContentY() needs to be called when any of the variable
67 involved in the computation of the 'y' property of the currentSubItem changes.
68
69 if accordion is false:
70 - heightFirstChildren(index)
71 - headerLoader.height
72 - list.height
73
74 if accordion is true:
75 - heightFirstChildren(index)
76 - items.availableHeight
77 - heightFirstHeaders(index)
78
79 items.contentHeight seems to depend on all of those so it's enough to
80 depend only on it.
81 */
82 function updateMouseContentY() {
83 if (currentSubItem != undefined) {
84 mouse.contentY = Math.max(currentSubItem.mapToItem(mouse.contentItem, 0, 0).y -list.height/2, 0)
85 }
86 }
87 property variant currentSubItem: currentItem != undefined ? currentItem.bodyLoader.item.currentItem : undefined
88 onCurrentSubItemChanged: updateMouseContentY()
89
90 Connections {
91 target: items
92 onContentHeightChanged: updateMouseContentY()
93 }
94
95 FocusScope {
96 id: items
97
98 property int availableHeight: list.height - heightFirstHeaders(repeater.count)
99 property int contentHeight: items.heightFirstChildren(repeater.count)
100 property real value: mouse.contentY
101
102 anchors.fill: parent
103
104 function heightFirstChildren(n) {
105 var i
106 var totalHeight = 0
107 /* items.children contains both the repeated items and the repeater
108 itself. Skip and ignore the repeater. */
109 for (i=0; i<n && i<children.length; i++) {
110 if(children[i] == repeater) {n += 1; continue}
111 totalHeight += children[i].height
112 }
113 return totalHeight
114 }
115
116 function heightFirstHeaders(n) {
117 var i
118 var totalHeight = 0
119 /* items.children contains both the repeated items and the repeater
120 itself. Skip and ignore the repeater. */
121 for (i=0; i<n && i<children.length; i++) {
122 if(children[i] == repeater) {n += 1; continue}
123 totalHeight += children[i].headerLoader.height
124 }
125 return totalHeight
126 }
127
128 function clamp(x, min, max) {
129 return Math.max(Math.min(x, max), min)
130 }
131
132
133 /* Keyboard navigation */
134 function isIndexValid(index) {
135 /* Assuming that children contains exactly one item that is not a child (repeater) */
136 return index >= 0 && index < children.length-1
137 }
138
139 focus: true
140 Keys.onPressed: if (handleKeyPress(event.key)) event.accepted = true
141 function handleKeyPress(key) {
142 switch (key) {
143 case Qt.Key_Down:
144 return selectNextEnabled()
145 case Qt.Key_Up:
146 return selectPreviousEnabled()
147 }
148 }
149
150 function childFromIndex(index) {
151 var indexInChildren = 0
152 for(var i=0; i<children.length; i++) {
153 if (children[i] != repeater) {
154 if (indexInChildren == index) return children[i]
155 indexInChildren++
156 }
157 }
158
159 return undefined
160 }
161
162 function selectNextEnabled() {
163 var index = currentIndex
164 do {
165 index += 1
166 if (!isIndexValid(index)) return false
167 } while(!childFromIndex(index).focusable)
168 currentIndex = index
169 return true
170 }
171
172 function selectPreviousEnabled() {
173 var index = currentIndex
174 do {
175 index -= 1
176 if (!isIndexValid(index)) return false
177 } while(!childFromIndex(index).focusable)
178 currentIndex = index
179 return true
180 }
181
182 property bool needsFocus: false
183 onChildrenChanged: {
184 /* FIXME: this workarounds the fact that list.focus is set to false
185 when the child with focus is destroyed
186 */
187 if (needsFocus) {
188 list.focus = true
189 needsFocus = false
190 }
191 /* Assuming that children contains exactly one item that is not a child (repeater) */
192 if(children.length <= 1) {
193 list.currentIndex = -1
194 } else {
195 list.currentIndex = -1
196 selectNextEnabled()
197 }
198 }
199
200 Repeater {
201 id: repeater
202
203 FocusScope {
204 property alias bodyLoader: bodyLoader
205 property alias headerLoader: headerLoader
206
207 focus: index == list.currentIndex
208 Component.onDestruction: items.needsFocus = true
209
210 width: list.width
211 height: headerLoader.height + bodyLoader.item.totalHeight
212 property bool focusable: bodyLoader.item.focusable
213
214 property int pmin: pmax - (ymax - ymin)
215 property int pmax: items.heightFirstChildren(index) - ymin
216 property int ymin: list.accordion ? items.heightFirstHeaders(index) : -headerLoader.height
217 property int ymax: list.accordion ? ymin + items.availableHeight : list.height
218 y: items.clamp(-items.value + ymax + pmin, ymin, ymax)
219
220 Loader {
221 id: headerLoader
222
223 focus: visible
224 KeyNavigation.down: bodyLoader
225 sourceComponent: headerDelegate
226 onLoaded: item.focus = true
227 width: parent.width
228
229 /* Workaround Qt bug http://bugreports.qt.nokia.com/browse/QTBUG-18857
230 More documentation at http://bugreports.qt.nokia.com/browse/QTBUG-18011
231 */
232 property int index
233 Binding { target: headerLoader; property: "index"; value: index }
234 property variant model
235 Binding { target: headerLoader; property: "model"; value: model }
236 property variant body
237 Binding { target: headerLoader; property: "body"; value: bodyLoader.item }
238 }
239
240 Loader {
241 id: bodyLoader
242
243 focus: !headerLoader.focus
244 KeyNavigation.up: headerLoader
245 sourceComponent: list.bodyDelegate
246 onLoaded: item.focus = true
247 width: parent.width
248 anchors.top: headerLoader.bottom
249 height: items.clamp(parent.ymax - parent.y, 0, item.totalHeight)
250
251 Binding {
252 target: bodyLoader.item
253 property: "contentY"
254 value: Math.max(items.value - pmax, 0)
255 }
256
257 /* Workaround Qt bug http://bugreports.qt.nokia.com/browse/QTBUG-18857
258 More documentation at http://bugreports.qt.nokia.com/browse/QTBUG-18011
259 */
260 property int index
261 Binding { target: bodyLoader; property: "index"; value: index }
262 property variant model
263 Binding { target: bodyLoader; property: "model"; value: model }
264 }
265 }
266 }
267 }
268
269 Flickable {
270 id: mouse
271
272 z: -1
273 anchors.fill: parent
274 contentWidth: parent.width
275 contentHeight: items.contentHeight
276 }
277}
0278
=== modified file 'places/ListViewWithScrollbar.qml'
--- places/ListViewWithScrollbar.qml 2011-06-23 17:08:53 +0000
+++ places/ListViewWithScrollbar.qml 2011-07-27 15:02:42 +0000
@@ -18,44 +18,21 @@
1818
19import QtQuick 1.019import QtQuick 1.0
2020
21Item {21FocusScope {
22 property alias list: list
23 property alias scrollbar: scrollbar22 property alias scrollbar: scrollbar
23 property alias model: list.model
24 property alias bodyDelegate: list.bodyDelegate
25 property alias headerDelegate: list.headerDelegate
2426
25 ListView {27 ListViewWithHeaders {
26 id: list28 id: list
2729
30 focus: true
28 anchors.top: parent.top31 anchors.top: parent.top
29 anchors.bottom: parent.bottom32 anchors.bottom: parent.bottom
30 anchors.left: parent.left33 anchors.left: parent.left
31 anchors.right: scrollbar.left34 anchors.right: scrollbar.left
32 anchors.rightMargin: 1535 anchors.rightMargin: 15
33
34 clip: true
35 /* FIXME: proper spacing cannot be set because of the hack in Group.qml
36 whereby empty groups are still in the list but invisible and of
37 height 0.
38 */
39 //spacing: 31
40
41 orientation: ListView.Vertical
42
43 /* WARNING - HACK - FIXME
44 Issue:
45 User wise annoying jumps in the list are observable if cacheBuffer is
46 set to 0 (which is the default value). States such as 'folded' are
47 lost when scrolling a lot.
48
49 Explanation:
50 The height of the Group delegate depends on its content. However its
51 content is not known until the delegate is instantiated because it
52 depends on the number of results displayed by its GridView.
53
54 Resolution:
55 We set the cacheBuffer to the biggest possible int in order to make
56 sure all delegates are always instantiated.
57 */
58 cacheBuffer: 2147483647
59 }36 }
6037
61 Scrollbar {38 Scrollbar {
@@ -67,7 +44,7 @@
67 anchors.bottomMargin: 1044 anchors.bottomMargin: 10
68 anchors.right: parent.right45 anchors.right: parent.right
6946
70 targetFlickable: list47 targetFlickable: list.flickable
7148
72 /* Hide the scrollbar if there is less than a page of results */49 /* Hide the scrollbar if there is less than a page of results */
73 opacity: targetFlickable.visibleArea.heightRatio < 1.0 ? 1.0 : 0.050 opacity: targetFlickable.visibleArea.heightRatio < 1.0 ? 1.0 : 0.0
7451
=== modified file 'places/PlaceEntryView.qml'
--- places/PlaceEntryView.qml 2011-06-23 17:08:53 +0000
+++ places/PlaceEntryView.qml 2011-07-27 15:02:42 +0000
@@ -19,7 +19,7 @@
19import QtQuick 1.019import QtQuick 1.0
20import Unity2d 1.0 /* Necessary for SortFilterProxyModel */20import Unity2d 1.0 /* Necessary for SortFilterProxyModel */
2121
22Item {22FocusScope {
23 id: placeEntryView23 id: placeEntryView
2424
25 /* An instance of PlaceEntryModel */25 /* An instance of PlaceEntryModel */
@@ -31,9 +31,9 @@
31 ('firstGroupModel') is used to filter the search results per group.31 ('firstGroupModel') is used to filter the search results per group.
32 */32 */
33 var placeEntry, i33 var placeEntry, i
34 for (i=0; i<placeEntryView.model.entryGroupsModel.count(); i=i+1) {34 for (i=0; i<placeEntryView.model.entryGroupsModel.count; i=i+1) {
35 firstGroupModel.groupId = i35 firstGroupModel.groupId = i
36 if (firstGroupModel.count() != 0) {36 if (firstGroupModel.count != 0) {
37 var firstResult = firstGroupModel.get(0)37 var firstResult = firstGroupModel.get(0)
38 /* Places give back the uri of the item in 'column_0' per specification */38 /* Places give back the uri of the item in 'column_0' per specification */
39 var uri = firstResult.column_039 var uri = firstResult.column_0
@@ -62,6 +62,7 @@
62 ListViewWithScrollbar {62 ListViewWithScrollbar {
63 id: results63 id: results
6464
65 focus: true
65 anchors.fill: parent66 anchors.fill: parent
6667
67 /* The group's delegate is chosen dynamically depending on what68 /* The group's delegate is chosen dynamically depending on what
@@ -74,10 +75,10 @@
74 If groupRenderer == 'UnityShowcaseRenderer' then it will look for75 If groupRenderer == 'UnityShowcaseRenderer' then it will look for
75 the file 'UnityShowcaseRenderer.qml' and use it to render the group.76 the file 'UnityShowcaseRenderer.qml' and use it to render the group.
76 */77 */
77 list.delegate: Loader {78 bodyDelegate: Loader {
78 property string groupRenderer: column_079 property string groupRenderer: model.column_0
79 property string displayName: column_180 property string displayName: model.column_1
80 property string iconHint: column_281 property string iconHint: model.column_2
81 property int groupId: index82 property int groupId: index
8283
83 source: groupRenderer ? groupRenderer+".qml" : ""84 source: groupRenderer ? groupRenderer+".qml" : ""
@@ -86,12 +87,8 @@
86 console.log("Failed to load renderer", groupRenderer)87 console.log("Failed to load renderer", groupRenderer)
87 }88 }
8889
89 width: ListView.view.width
90
91 /* Model that will be used by the group's delegate */90 /* Model that will be used by the group's delegate */
92 SortFilterProxyModel {91 property variant group_model: SortFilterProxyModel {
93 id: group_model
94
95 model: placeEntryView.model.entryResultsModel92 model: placeEntryView.model.entryResultsModel
9693
97 /* resultsModel contains data for all the groups of a given Place.94 /* resultsModel contains data for all the groups of a given Place.
@@ -102,16 +99,37 @@
102 filterRegExp: RegExp("^%1$".arg(groupId)) /* exact match */99 filterRegExp: RegExp("^%1$".arg(groupId)) /* exact match */
103 }100 }
104101
105 onLoaded: {102 /* Required by ListViewWithHeaders when the loaded Renderer is a Flickable.
106 item.parentListView = results.list103 In that case the list view scrolls the Flickable appropriately.
107 item.displayName = displayName104 */
108 item.iconHint = iconHint105 property int totalHeight: item.totalHeight != undefined ? item.totalHeight : 0
109 item.groupId = groupId106 property int contentY
110 item.model = group_model107 Binding { target: item; property: "contentY"; value: contentY }
111 item.placeEntryModel = placeEntryView.model108 property bool focusable: group_model.count > 0
112 }109 property variant currentItem: item.currentItem
113 }110
114111 Binding { target: item; property: "displayName"; value: displayName }
115 list.model: placeEntryView.model != undefined ? placeEntryView.model.entryGroupsModel : undefined112 Binding { target: item; property: "iconHint"; value: iconHint }
113 Binding { target: item; property: "groupId"; value: groupId }
114 Binding { target: item; property: "group_model"; value: group_model }
115 Binding { target: item; property: "placeEntryModel"; value: placeEntryView.model }
116
117 onLoaded: item.focus = true
118 }
119
120 headerDelegate: GroupHeader {
121 visible: body.item.needHeader && body.focusable
122 height: visible ? 32 : 0
123
124 property bool foldable: body.item.folded != undefined
125 availableCount: foldable ? body.group_model.count - body.item.cellsPerRow : 0
126 folded: foldable ? body.item.folded : false
127 onClicked: if(foldable) body.item.folded = !body.item.folded
128
129 icon: body.iconHint
130 label: body.displayName
131 }
132
133 model: placeEntryView.model != undefined ? placeEntryView.model.entryGroupsModel : undefined
116 }134 }
117}135}
118136
=== modified file 'places/Renderer.qml'
--- places/Renderer.qml 2011-06-23 17:08:53 +0000
+++ places/Renderer.qml 2011-07-27 15:02:42 +0000
@@ -26,11 +26,11 @@
26 itself. A typical renderer is the UnityDefaultRender that lays out the items26 itself. A typical renderer is the UnityDefaultRender that lays out the items
27 in a grid of icons with the item's title underneath it.27 in a grid of icons with the item's title underneath it.
28*/28*/
29Item {29FocusScope {
30 property string displayName /* Name of the group typically displayed in the header */30 property string displayName /* Name of the group typically displayed in the header */
31 property string iconHint /* Icon id of the group */31 property string iconHint /* Icon id of the group */
32 property int groupId /* Index of the group */32 property int groupId /* Index of the group */
33 property variant model /* List model containing the items to be displayed by the renderer */33 property variant group_model /* List model containing the items to be displayed by the renderer */
34 property variant placeEntryModel /* Reference to the place entry the group belongs to */34 property variant placeEntryModel /* Reference to the place entry the group belongs to */
35 property variant parentListView /* Reference to the ListView the renderer is nested into */35 property bool needHeader: false /* Whether or not the renderer requires a header to be displayed */
36}36}
3737
=== modified file 'places/RendererGrid.qml'
--- places/RendererGrid.qml 2011-06-23 17:08:53 +0000
+++ places/RendererGrid.qml 2011-07-27 15:02:42 +0000
@@ -28,6 +28,11 @@
28Renderer {28Renderer {
29 id: renderer29 id: renderer
3030
31 needHeader: true
32 property alias cellsPerRow: results.cellsPerRow
33 property alias contentY: results.contentY
34 property alias currentItem: results.currentItem
35
31 property variant cellRenderer36 property variant cellRenderer
32 property bool folded37 property bool folded
33 folded: {38 folded: {
@@ -44,99 +49,35 @@
44 property int horizontalSpacing: 2649 property int horizontalSpacing: 26
45 property int verticalSpacing: 2650 property int verticalSpacing: 26
4651
47 /* Using results.contentHeight produces binding loop warnings and potential52 /* FIXME: using results_layout.anchors.topMargin in the following expression
48 rendering issues. We compute the height manually.53 causes QML to think they might be an anchor loop. */
49 */54 property int totalHeight: results.count > 0 ? results_layout.anchors.topMargin + results.totalHeight : 0
50 /* FIXME: tricking the system by making the delegate of height 0 and with
51 an invisible header is no good: the item in the model still
52 exists and some things such as keyboard selection break.
53 */
54 height: results.count > 0 ? header.height + results_layout.anchors.topMargin + results.totalHeight : 0
55 //Behavior on height {NumberAnimation {duration: 200}}
56
57 GroupHeader {
58 id: header
59
60 visible: results.count > 0
61 availableCount: results.count - results.cellsPerRow
62 folded: parent.folded
63 anchors.top: parent.top
64 anchors.left: parent.left
65 anchors.right: parent.right
66 height: 32
67 icon: parent.iconHint
68 label: parent.displayName
69
70 onClicked: parent.folded = !parent.folded
71 }
7255
73 Item {56 Item {
74 id: results_layout57 id: results_layout
7558
76 anchors.top: header.bottom59 anchors.fill: parent
77 anchors.topMargin: 2260 anchors.topMargin: 12
78 anchors.left: parent.left
79 anchors.leftMargin: 261 anchors.leftMargin: 2
80 anchors.right: parent.right
81 anchors.bottom: parent.bottom
8262
83 CenteredGridView {63 CenteredGridView {
84 id: results64 id: results
8565
86 /* FIXME: this is a gross hack compensating for the lack of sections66 focus: true
87 in GridView (see ListView.section).67
8868 anchors.fill: parent
89 We nest GridViews inside a ListView and add headers manually69
90 (GroupHeader). The total height of each Group is computed70 property int totalHeight: results.cellHeight*Math.ceil(count/cellsPerRow)
91 manually and given back to the ListView. However that size cannot
92 be used by the individual GridViews because it would make them
93 load all of their delegates at once using far too much memory and
94 processing power. Instead we constrain the height of the GridViews
95 and compute their position manually to compensate for the position
96 changes when flicking the ListView.
97
98 We assume that renderer.parentListView is the ListView we nest our
99 GridView into.
100 */
101 property variant flickable: renderer.parentListView.contentItem
102
103 /* flickable.contentY*0 is equal to 0 but is necessary in order to
104 have the entire expression being evaluated at the right moment.
105 */
106 property int inFlickableY: flickable.contentY*0+parent.mapToItem(flickable, 0, 0).y
107 /* note: testing for flickable.height < 0 is probably useless since it is
108 unlikely flickable.height will ever be negative.
109 */
110 property int compensateY: inFlickableY > 0 || flickable.height < 0 || totalHeight < flickable.height ? 0 : -inFlickableY
111
112 /* Synchronise the position and content's position of the GridView
113 with the current position of flickable's visibleArea */
114 function synchronisePosition() {
115 y = compensateY
116 contentY = compensateY
117 }
118
119 onCompensateYChanged: synchronisePosition()
120 /* Any change in content needs to trigger a synchronisation */
121 onCountChanged: synchronisePosition()
122 onModelChanged: synchronisePosition()
123
124 width: flickable.width
125 height: Math.min(totalHeight, flickable.height)
126
127 /* Only display one line of items when folded */
128 property int displayedCount: folded ? cellsPerRow : count
129 property int totalHeight: results.cellHeight*Math.ceil(displayedCount/cellsPerRow)
13071
131 minHorizontalSpacing: renderer.horizontalSpacing72 minHorizontalSpacing: renderer.horizontalSpacing
132 minVerticalSpacing: renderer.verticalSpacing73 minVerticalSpacing: renderer.verticalSpacing
133 delegateWidth: renderer.cellWidth74 delegateWidth: renderer.cellWidth
134 delegateHeight: renderer.cellHeight75 delegateHeight: renderer.cellHeight
13576
136 interactive: false77// interactive: false
137 clip: true78 clip: true
13879
139 delegate: Item {80 delegate: FocusScope {
14081
141 width: results.cellWidth82 width: results.cellWidth
142 height: results.cellHeight83 height: results.cellHeight
@@ -157,6 +98,7 @@
157 height: results.delegateHeight98 height: results.delegateHeight
158 anchors.horizontalCenter: parent.horizontalCenter99 anchors.horizontalCenter: parent.horizontalCenter
159100
101 focus: true
160 sourceComponent: cellRenderer102 sourceComponent: cellRenderer
161 onLoaded: {103 onLoaded: {
162 item.uri = uri104 item.uri = uri
@@ -164,11 +106,16 @@
164 item.mimetype = mimetype106 item.mimetype = mimetype
165 item.displayName = displayName107 item.displayName = displayName
166 item.comment = comment108 item.comment = comment
109 item.focus = true
167 }110 }
168 }111 }
169 }112 }
170113
171 model: renderer.model114 /* Only display one line of items when folded */
115 model: SortFilterProxyModel {
116 model: renderer.group_model != undefined ? renderer.group_model : null
117 limit: folded ? results.cellsPerRow : -1
118 }
172 }119 }
173 }120 }
174}121}
175122
=== modified file 'places/Scrollbar.qml'
--- places/Scrollbar.qml 2011-06-23 17:08:53 +0000
+++ places/Scrollbar.qml 2011-07-27 15:02:42 +0000
@@ -72,12 +72,18 @@
72 anchors.left: parent.left72 anchors.left: parent.left
73 anchors.right: parent.right73 anchors.right: parent.right
7474
75 y: {75 Binding {
76 var clampedYPosition = Math.max(0, Math.min(1-targetFlickable.visibleArea.heightRatio,76 target: slider
77 targetFlickable.visibleArea.yPosition))77 property: "y"
78 return clampedYPosition * scrollbar.height78 value: {
79 var clampedYPosition = Math.max(0, Math.min(1-targetFlickable.visibleArea.heightRatio,
80 targetFlickable.visibleArea.yPosition))
81 return clampedYPosition * scrollbar.height
82 }
83 when: !dragMouseArea.drag.active
79 }84 }
80 height: Math.max(minimalHeight, targetFlickable.visibleArea.heightRatio * scrollbar.height)85
86 height: Math.min(scrollbar.height, Math.max(minimalHeight, targetFlickable.visibleArea.heightRatio * scrollbar.height))
8187
82 Behavior on height {NumberAnimation {duration: 200; easing.type: Easing.InOutQuad}}88 Behavior on height {NumberAnimation {duration: 200; easing.type: Easing.InOutQuad}}
8389
8490
=== modified file 'places/SearchEntry.qml'
--- places/SearchEntry.qml 2011-06-23 17:08:53 +0000
+++ places/SearchEntry.qml 2011-07-27 15:02:42 +0000
@@ -19,7 +19,7 @@
19import QtQuick 1.019import QtQuick 1.0
20import Effects 1.020import Effects 1.0
2121
22FocusScope {22AbstractButton {
23 property string searchQuery23 property string searchQuery
2424
25 /* Cancels current search when the dash becomes invisible */25 /* Cancels current search when the dash becomes invisible */
@@ -37,6 +37,8 @@
37 /* Keys forwarded to the search entry are forwarded to the text input. */37 /* Keys forwarded to the search entry are forwarded to the text input. */
38 Keys.forwardTo: [search_input]38 Keys.forwardTo: [search_input]
3939
40 opacity: state == "selected" ? 1.0 : 0.7
41
40 BorderImage {42 BorderImage {
41 anchors.fill: parent43 anchors.fill: parent
42 source: "artwork/search_background.sci"44 source: "artwork/search_background.sci"
4345
=== modified file 'places/SearchRefine.qml'
--- places/SearchRefine.qml 2011-06-23 17:08:53 +0000
+++ places/SearchRefine.qml 2011-07-27 15:02:42 +0000
@@ -49,6 +49,8 @@
4949
50 focus: true50 focus: true
5151
52 KeyNavigation.down: options
53
52 anchors.left: parent.left54 anchors.left: parent.left
53 anchors.right: parent.right55 anchors.right: parent.right
54 anchors.top: parent.top56 anchors.top: parent.top
@@ -61,6 +63,7 @@
61 text: u2d.tr("Refine search")63 text: u2d.tr("Refine search")
62 font.bold: true64 font.bold: true
63 font.pixelSize: 1665 font.pixelSize: 16
66 font.underline: parent.state == "selected"
6467
65 anchors.top: parent.top68 anchors.top: parent.top
66 anchors.left: parent.left69 anchors.left: parent.left
@@ -92,6 +95,8 @@
92 opacity: folded ? 0.0 : 1.095 opacity: folded ? 0.0 : 1.0
93 Behavior on opacity {NumberAnimation {duration: 100; easing.type: Easing.InOutQuad}}96 Behavior on opacity {NumberAnimation {duration: 100; easing.type: Easing.InOutQuad}}
9497
98 KeyNavigation.up: header
99
95 anchors.left: parent.left100 anchors.left: parent.left
96 anchors.right: parent.right101 anchors.right: parent.right
97 anchors.top: header.bottom102 anchors.top: header.bottom
98103
=== modified file 'places/SearchRefineOptionType.qml'
--- places/SearchRefineOptionType.qml 2011-06-23 17:08:53 +0000
+++ places/SearchRefineOptionType.qml 2011-07-27 15:02:42 +0000
@@ -21,9 +21,11 @@
21SearchRefineOption {21SearchRefineOption {
22 id: searchRefineOption22 id: searchRefineOption
2323
24 AbstractButton {24 Item {
25 id: header25 id: header
2626
27 KeyNavigation.down: filters
28
27 focus: true29 focus: true
28 anchors.top: parent.top30 anchors.top: parent.top
29 anchors.left: parent.left31 anchors.left: parent.left
@@ -39,6 +41,7 @@
39 text: searchRefineOption.title41 text: searchRefineOption.title
40 font.pixelSize: 1642 font.pixelSize: 16
41 font.bold: true43 font.bold: true
44 font.underline: parent.state == "selected"
42 }45 }
43 }46 }
4447
@@ -63,6 +66,7 @@
6366
64 /* Make sure the first item is selected when getting the focus for the first time */67 /* Make sure the first item is selected when getting the focus for the first time */
65 currentIndex: 068 currentIndex: 0
69 KeyNavigation.up: header
6670
67 delegate: TickBox {71 delegate: TickBox {
68 height: filters.cellHeight72 height: filters.cellHeight
@@ -70,7 +74,7 @@
70 /* Not checking for placeEntryModel != undefined leads to a segfault74 /* Not checking for placeEntryModel != undefined leads to a segfault
71 when switching places */75 when switching places */
72 text: placeEntryModel != undefined ? column_0 : ""76 text: placeEntryModel != undefined ? column_0 : ""
73 ticked: dash.currentPage.model.activeSection == model.index77 checked: dash.currentPage.model.activeSection == model.index
7478
75 onClicked: placeEntryModel.activeSection = model.index79 onClicked: placeEntryModel.activeSection = model.index
76 }80 }
7781
=== modified file 'places/TickBox.qml'
--- places/TickBox.qml 2011-06-23 17:08:53 +0000
+++ places/TickBox.qml 2011-07-27 15:02:42 +0000
@@ -22,8 +22,8 @@
22 id: tickBox22 id: tickBox
2323
24 property string text24 property string text
25 property bool ticked: false25 property bool checked: false
26 property bool canUntick: true26 property bool canUncheck: true
2727
28 width: childrenRect.width28 width: childrenRect.width
29 height: childrenRect.height29 height: childrenRect.height
@@ -43,7 +43,7 @@
43 Image {43 Image {
44 id: box44 id: box
4545
46 opacity: !canUntick && ticked ? 0 : 146 opacity: !canUncheck && checked ? 0 : 1
47 anchors.top: parent.top47 anchors.top: parent.top
48 anchors.left: parent.left48 anchors.left: parent.left
49 source: "artwork/tick_box.png"49 source: "artwork/tick_box.png"
@@ -58,7 +58,7 @@
58 anchors.topMargin: 258 anchors.topMargin: 2
59 anchors.left: box.left59 anchors.left: box.left
60 anchors.leftMargin: 360 anchors.leftMargin: 3
61 opacity: ticked ? 1.0 : parent.state == "selected" ? 0.4 : 0.061 opacity: checked ? 1.0 : parent.state == "selected" ? 0.4 : 0.0
62 source: "artwork/tick.png"62 source: "artwork/tick.png"
63 width: sourceSize.width63 width: sourceSize.width
64 height: sourceSize.height64 height: sourceSize.height
6565
=== modified file 'places/UnityEmptySearchRenderer.qml'
--- places/UnityEmptySearchRenderer.qml 2011-06-23 17:08:53 +0000
+++ places/UnityEmptySearchRenderer.qml 2011-07-27 15:02:42 +0000
@@ -40,7 +40,7 @@
40 boundsBehavior: ListView.StopAtBounds40 boundsBehavior: ListView.StopAtBounds
41 orientation: ListView.Vertical41 orientation: ListView.Vertical
4242
43 model: renderer.model43 model: renderer.group_model
44 delegate: Button {44 delegate: Button {
45 property string uri: column_045 property string uri: column_0
46 property string iconHint: column_146 property string iconHint: column_1
4747
=== modified file 'places/app/CMakeLists.txt'
--- places/app/CMakeLists.txt 2011-03-08 09:20:02 +0000
+++ places/app/CMakeLists.txt 2011-07-27 15:02:42 +0000
@@ -1,7 +1,5 @@
1# Dependencies1# Dependencies
2find_package(X11 REQUIRED)
3pkg_check_modules(QTGCONF REQUIRED libqtgconf)2pkg_check_modules(QTGCONF REQUIRED libqtgconf)
4pkg_check_modules(GTK REQUIRED gtk+-2.0)
53
6# Sources4# Sources
7set(places_SRCS5set(places_SRCS
86
=== modified file 'places/app/places.cpp'
--- places/app/places.cpp 2011-06-27 13:43:05 +0000
+++ places/app/places.cpp 2011-07-27 15:02:42 +0000
@@ -31,9 +31,8 @@
3131
32#include <X11/Xlib.h>32#include <X11/Xlib.h>
3333
34#include <gtk/gtk.h>
35
36// unity-2d34// unity-2d
35#include <unity2dapplication.h>
37#include <unity2ddebug.h>36#include <unity2ddebug.h>
3837
39#include "dashdeclarativeview.h"38#include "dashdeclarativeview.h"
@@ -41,23 +40,8 @@
4140
42int main(int argc, char *argv[])41int main(int argc, char *argv[])
43{42{
44 /* gtk needs to be inited, otherwise we get an assert failure in gdk */43 Unity2dApplication::earlySetup(argc, argv);
45 gtk_init(&argc, &argv);44 Unity2dApplication application(argc, argv);
46 Unity2dDebug::installHandlers();
47
48 /* When the environment variable QT_GRAPHICSSYSTEM is not set,
49 force graphics system to 'raster' instead of the default 'native'
50 which on X11 is 'XRender'.
51 'XRender' defaults to using a TrueColor visual. We do _not_ mimick that
52 behaviour with 'raster' by calling QApplication::setColorSpec because
53 of a bug where some pixmaps become blueish:
54
55 https://bugs.launchpad.net/unity-2d/+bug/689877
56 */
57 if(getenv("QT_GRAPHICSSYSTEM") == 0) {
58 QApplication::setGraphicsSystem("raster");
59 }
60 QApplication application(argc, argv);
61 QSet<QString> arguments = QSet<QString>::fromList(QCoreApplication::arguments());45 QSet<QString> arguments = QSet<QString>::fromList(QCoreApplication::arguments());
6246
63 qmlRegisterType<DashDeclarativeView>("Unity2d", 1, 0, "DashDeclarativeView");47 qmlRegisterType<DashDeclarativeView>("Unity2d", 1, 0, "DashDeclarativeView");
6448
=== modified file 'places/dash.qml'
--- places/dash.qml 2011-07-05 19:01:18 +0000
+++ places/dash.qml 2011-07-27 15:02:42 +0000
@@ -31,6 +31,9 @@
31 }31 }
3232
33 function activatePage(page) {33 function activatePage(page) {
34 /* Always give the focus to the search entry when switching pages */
35 search_entry.focus = true
36
34 if (page == currentPage) {37 if (page == currentPage) {
35 return38 return
36 }39 }
@@ -40,12 +43,6 @@
40 }43 }
41 currentPage = page44 currentPage = page
42 currentPage.visible = true45 currentPage.visible = true
43 /* FIXME: For some reason currentPage gets the focus when it becomes
44 visible. Reset the focus to the search_bar instead.
45 It could be due to Qt bug QTBUG-13380:
46 "Listview gets focus when it becomes visible"
47 */
48 search_entry.focus = true
49 }46 }
5047
51 function activatePlaceEntry(fileName, groupName, section) {48 function activatePlaceEntry(fileName, groupName, section) {
@@ -121,13 +118,18 @@
121 /* Unhandled keys will always be forwarded to the search bar. That way118 /* Unhandled keys will always be forwarded to the search bar. That way
122 the user can type and search from anywhere in the interface without119 the user can type and search from anywhere in the interface without
123 necessarily focusing the search bar first. */120 necessarily focusing the search bar first. */
124 Keys.forwardTo: [search_entry]121 //Keys.forwardTo: [search_entry]
125122
126123
127 SearchEntry {124 SearchEntry {
128 id: search_entry125 id: search_entry
129126
130 focus: true127 focus: true
128 /* FIXME: check on visible necessary; fixed in Qt Quick 1.1
129 ref: http://bugreports.qt.nokia.com/browse/QTBUG-15862
130 */
131 KeyNavigation.right: refine_search.visible ? refine_search : search_entry
132 KeyNavigation.down: pageLoader
131133
132 anchors.top: parent.top134 anchors.top: parent.top
133 anchors.topMargin: 10135 anchors.topMargin: 10
@@ -142,6 +144,8 @@
142 SearchRefine {144 SearchRefine {
143 id: refine_search145 id: refine_search
144146
147 KeyNavigation.left: search_entry
148
145 /* SearchRefine is only to be displayed for places, not in the home page */149 /* SearchRefine is only to be displayed for places, not in the home page */
146 visible: dashView.activePlaceEntry != ""150 visible: dashView.activePlaceEntry != ""
147 placeEntryModel: visible && currentPage != undefined ? currentPage.model : undefined151 placeEntryModel: visible && currentPage != undefined ? currentPage.model : undefined
@@ -158,6 +162,12 @@
158 Loader {162 Loader {
159 id: pageLoader163 id: pageLoader
160164
165 /* FIXME: check on visible necessary; fixed in Qt Quick 1.1
166 ref: http://bugreports.qt.nokia.com/browse/QTBUG-15862
167 */
168 KeyNavigation.right: refine_search.visible && !refine_search.folded ? refine_search : pageLoader
169 KeyNavigation.up: search_entry
170
161 anchors.top: search_entry.bottom171 anchors.top: search_entry.bottom
162 anchors.topMargin: 2172 anchors.topMargin: 2
163 anchors.bottom: parent.bottom173 anchors.bottom: parent.bottom
@@ -165,6 +175,7 @@
165 anchors.leftMargin: 20175 anchors.leftMargin: 20
166 anchors.right: !refine_search.visible || refine_search.folded ? parent.right : refine_search.left176 anchors.right: !refine_search.visible || refine_search.folded ? parent.right : refine_search.left
167 anchors.rightMargin: !refine_search.visible || refine_search.folded ? 0 : 15177 anchors.rightMargin: !refine_search.visible || refine_search.folded ? 0 : 15
178 onLoaded: item.focus = true
168 }179 }
169 }180 }
170181
171182
=== modified file 'spread/app/CMakeLists.txt'
--- spread/app/CMakeLists.txt 2011-03-07 14:52:11 +0000
+++ spread/app/CMakeLists.txt 2011-07-27 15:02:42 +0000
@@ -1,7 +1,3 @@
1# Dependencies
2pkg_check_modules(GTK REQUIRED gtk+-2.0)
3find_package(X11 REQUIRED)
4
5# Sources1# Sources
6set(spread_SRCS2set(spread_SRCS
7 spread.cpp3 spread.cpp
84
=== modified file 'spread/app/spread.cpp'
--- spread/app/spread.cpp 2011-06-22 08:33:52 +0000
+++ spread/app/spread.cpp 2011-07-27 15:02:42 +0000
@@ -18,7 +18,6 @@
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */19 */
2020
21#include <gtk/gtk.h>
22#include <QApplication>21#include <QApplication>
23#include <QDesktopWidget>22#include <QDesktopWidget>
24#include <QDeclarativeEngine>23#include <QDeclarativeEngine>
@@ -28,31 +27,14 @@
28#include "spreadcontrol.h"27#include "spreadcontrol.h"
29#include "launcherclient.h"28#include "launcherclient.h"
3029
31#include <unity2ddebug.h>30#include <unity2dapplication.h>
3231
33#include "config.h"32#include "config.h"
3433
35int main(int argc, char *argv[])34int main(int argc, char *argv[])
36{35{
37 /* Unity2d plugin uses GTK APIs to retrieve theme icons36 Unity2dApplication::earlySetup(argc, argv);
38 (gtk_icon_theme_get_default) and requires a call to gtk_init */37 Unity2dApplication application(argc, argv);
39 gtk_init(&argc, &argv);
40
41 Unity2dDebug::installHandlers();
42
43 /* When the environment variable QT_GRAPHICSSYSTEM is not set,
44 force graphics system to 'raster' instead of the default 'native'
45 which on X11 is 'XRender'.
46 'XRender' defaults to using a TrueColor visual. We do _not_ mimick that
47 behaviour with 'raster' by calling QApplication::setColorSpec because
48 of a bug where some pixmaps become blueish:
49
50 https://bugs.launchpad.net/unity-2d/+bug/689877
51 */
52 if(getenv("QT_GRAPHICSSYSTEM") == 0) {
53 QApplication::setGraphicsSystem("raster");
54 }
55 QApplication application(argc, argv);
56 QSet<QString> arguments = QSet<QString>::fromList(QCoreApplication::arguments());38 QSet<QString> arguments = QSet<QString>::fromList(QCoreApplication::arguments());
5739
58 SpreadView view;40 SpreadView view;

Subscribers

People subscribed via source and target branches

to all changes: