Merge lp:~gary-lasker/software-center/launcher-integration-lp761851 into lp:software-center

Proposed by Gary Lasker
Status: Merged
Merged at revision: 2710
Proposed branch: lp:~gary-lasker/software-center/launcher-integration-lp761851
Merge into: lp:software-center
Diff against target: 309 lines (+75/-95)
4 files modified
debian/changelog (+6/-1)
softwarecenter/backend/unitylauncher.py (+8/-27)
softwarecenter/ui/gtk3/panes/availablepane.py (+20/-36)
test/gtk3/test_unity_launcher_integration.py (+41/-31)
To merge this branch: bzr merge lp:~gary-lasker/software-center/launcher-integration-lp761851
Reviewer Review Type Date Requested Status
software-store-developers Pending
Review via email: mp+90354@code.launchpad.net

Description of the change

This branch completes the software-center side implementation of the new Unity launcher functionality as specified at https://wiki.ubuntu.com/SoftwareCenter#Learning_how_to_launch_an_application. Note that there remains some additional functionality to be completed on the Unity side (see details in the Unity MP https://code.launchpad.net/~bilalakhtar/unity/software-center-integration-for-o/+merge/89364), but as of this branch the software-center side of the feature should be complete.

I've updated the corresponding unit test for the changes.

NOTE: This branch should land and be released as soon as possible after the corresponding Unity release (scheduled for tonight? but no sign of it yet).

Many thanks!

To post a comment you must log in.
2601. By Gary Lasker

sync up with latest trunk

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'debian/changelog'
--- debian/changelog 2012-01-30 03:59:38 +0000
+++ debian/changelog 2012-01-30 04:08:26 +0000
@@ -15,7 +15,12 @@
15 - add a test function in test_utils.py which covers all of15 - add a test function in test_utils.py which covers all of
16 get_nice_date_string16 get_nice_date_string
1717
18 -- Gary Lasker <gary.lasker@canonical.com> Sun, 29 Jan 2012 22:57:47 -050018 [ Gary Lasker ]
19 * lp:~gary-lasker/software-center/launcher-integration-lp761851:
20 - update to the Unity launcher integration implementation to
21 support the revamped functionality on the Unity side (LP: #761851)
22
23 -- Gary Lasker <gary.lasker@canonical.com> Sun, 29 Jan 2012 23:04:52 -0500
1924
20software-center (5.1.7) precise; urgency=low25software-center (5.1.7) precise; urgency=low
2126
2227
=== modified file 'softwarecenter/backend/unitylauncher.py'
--- softwarecenter/backend/unitylauncher.py 2011-11-29 21:50:55 +0000
+++ softwarecenter/backend/unitylauncher.py 2012-01-30 04:08:26 +0000
@@ -33,7 +33,6 @@
33 icon_y,33 icon_y,
34 icon_size,34 icon_size,
35 app_install_desktop_file_path,35 app_install_desktop_file_path,
36 installed_desktop_file_path,
37 trans_id):36 trans_id):
38 self.name = name37 self.name = name
39 self.icon_name = icon_name38 self.icon_name = icon_name
@@ -42,43 +41,25 @@
42 self.icon_y = icon_y41 self.icon_y = icon_y
43 self.icon_size = icon_size42 self.icon_size = icon_size
44 self.app_install_desktop_file_path = app_install_desktop_file_path43 self.app_install_desktop_file_path = app_install_desktop_file_path
45 self.installed_desktop_file_path = installed_desktop_file_path
46 self.trans_id = trans_id44 self.trans_id = trans_id
47 45
48class UnityLauncher(object):46class UnityLauncher(object):
49 """ Implements the integration between Software Center and the Unity47 """ Implements the integration between Software Center and the Unity
50 launcher48 launcher
51 """49 """
52 def __init__(self):50
53 # keep track of applications that are candidates for adding
54 # to the Unity launcher
55 self.launcher_queue = {}
56
57 def add_to_launcher_queue(self, pkgname, launcher_info):
58 """ add an application and its associated info to the set of candidates
59 for adding to the Unity launcher
60 """
61 self.launcher_queue[pkgname] = launcher_info
62
63 def remove_from_launcher_queue(self, pkgname):
64 """ remove an application and its associated info from the set of
65 candidates for adding to the Unity launcher
66 """
67 if pkgname in self.launcher_queue:
68 return self.launcher_queue.pop(pkgname)
69
70 def send_application_to_launcher(self, pkgname, launcher_info):51 def send_application_to_launcher(self, pkgname, launcher_info):
52 """ send a dbus message to the Unity launcher service to initiate
53 the add to launcher functionality for the specified application
54 """
71 LOG.debug("sending dbus signal to Unity launcher for application: ", 55 LOG.debug("sending dbus signal to Unity launcher for application: ",
72 launcher_info.name)56 launcher_info.name)
73 LOG.debug(" launcher_info.icon_file_path: ", 57 LOG.debug(" launcher_info.icon_file_path: ",
74 launcher_info.icon_file_path)58 launcher_info.icon_file_path)
75 LOG.debug(" launcher_info.installed_desktop_file_path: ",59 LOG.debug(" launcher_info.app_install_desktop_file_path: ",
76 launcher_info.installed_desktop_file_path)60 launcher_info.app_install_desktop_file_path)
77 LOG.debug(" launcher_info.trans_id: ", launcher_info.trans_id)61 LOG.debug(" launcher_info.trans_id: ", launcher_info.trans_id)
78 # the application is being added to the launcher, so clear it from the62
79 # list of candidates in the launcher queue
80 self.remove_from_launcher_queue(pkgname)
81 # add the application by sending a dbus signal to the Unity launcher
82 try:63 try:
83 bus = dbus.SessionBus()64 bus = dbus.SessionBus()
84 launcher_obj = bus.get_object('com.canonical.Unity.Launcher',65 launcher_obj = bus.get_object('com.canonical.Unity.Launcher',
@@ -91,7 +72,7 @@
91 launcher_info.icon_x,72 launcher_info.icon_x,
92 launcher_info.icon_y,73 launcher_info.icon_y,
93 launcher_info.icon_size,74 launcher_info.icon_size,
94 launcher_info.installed_desktop_file_path,75 launcher_info.app_install_desktop_file_path,
95 launcher_info.trans_id)76 launcher_info.trans_id)
96 except Exception as e:77 except Exception as e:
97 LOG.warn("could not send dbus signal to the Unity launcher: (%s)",78 LOG.warn("could not send dbus signal to the Unity launcher: (%s)",
9879
=== modified file 'softwarecenter/ui/gtk3/panes/availablepane.py'
--- softwarecenter/ui/gtk3/panes/availablepane.py 2012-01-12 20:18:16 +0000
+++ softwarecenter/ui/gtk3/panes/availablepane.py 2012-01-30 04:08:26 +0000
@@ -37,7 +37,6 @@
37from softwarecenter.paths import APP_INSTALL_PATH37from softwarecenter.paths import APP_INSTALL_PATH
38from softwarecenter.utils import (wait_for_apt_cache_ready,38from softwarecenter.utils import (wait_for_apt_cache_ready,
39 get_exec_line_from_desktop,39 get_exec_line_from_desktop,
40 convert_desktop_file_to_installed_location,
41 get_file_path_from_iconname)40 get_file_path_from_iconname)
42from softwarecenter.db.appfilter import AppFilter41from softwarecenter.db.appfilter import AppFilter
43from softwarecenter.db.database import Application42from softwarecenter.db.database import Application
@@ -199,8 +198,6 @@
199 # install backend198 # install backend
200 self.backend.connect("transactions-changed", self._on_transactions_changed)199 self.backend.connect("transactions-changed", self._on_transactions_changed)
201 self.backend.connect("transaction-started", self.on_transaction_started)200 self.backend.connect("transaction-started", self.on_transaction_started)
202 self.backend.connect("transaction-finished", self.on_transaction_finished)
203 self.backend.connect("transaction-stopped", self.on_transaction_stopped)
204 201
205 # now we are initialized202 # now we are initialized
206 self.searchentry.set_sensitive(True)203 self.searchentry.set_sensitive(True)
@@ -352,22 +349,22 @@
352 349
353 def on_transaction_started(self, backend, pkgname, appname, trans_id, 350 def on_transaction_started(self, backend, pkgname, appname, trans_id,
354 trans_type):351 trans_type):
355 self._register_unity_launcher_transaction_started(352 self._add_application_to_unity_launcher(
356 backend, pkgname, appname, trans_id, trans_type)353 backend, pkgname, appname, trans_id, trans_type)
357354
358 def _register_unity_launcher_transaction_started(self, backend, pkgname, 355 def _add_application_to_unity_launcher(self, backend, pkgname,
359 appname, trans_id, 356 appname, trans_id,
360 trans_type):357 trans_type):
361 if not self.add_to_launcher_enabled:358 if not self.add_to_launcher_enabled:
362 return359 return
363 # mvo: use use softwarecenter.utils explictly so that we can monkey360 # mvo: use use softwarecenter.utils explictly so that we can monkey
364 # patch it in the test361 # patch it in the test
365 if not softwarecenter.utils.is_unity_running():362 if not softwarecenter.utils.is_unity_running():
366 return363 return
367 # we only care about getting the launcher information on an install364 # we only care about installs
368 if not trans_type == TransactionTypes.INSTALL:365 if not trans_type == TransactionTypes.INSTALL:
369 return366 return
370 # gather details for this transaction and create the launcher_info object367
371 app = Application(pkgname=pkgname, appname=appname)368 app = Application(pkgname=pkgname, appname=appname)
372 appdetails = app.get_details(self.db)369 appdetails = app.get_details(self.db)
373 # we only add items to the launcher that have a desktop file370 # we only add items to the launcher that have a desktop file
@@ -380,17 +377,26 @@
380 not get_exec_line_from_desktop(appdetails.desktop_file)):377 not get_exec_line_from_desktop(appdetails.desktop_file)):
381 return378 return
382379
383 (icon_size, icon_x, icon_y) = self._get_onscreen_icon_details_for_launcher_service(app)380 # now gather up the unity launcher info items and send the app to the
381 # launcher service
382 launcher_info = self._get_unity_launcher_info(app, appdetails, trans_id)
383 self.unity_launcher.send_application_to_launcher(pkgname, launcher_info)
384
385 def _get_unity_launcher_info(self, app, appdetails, trans_id):
386 (icon_size, icon_x, icon_y) = (
387 self._get_onscreen_icon_details_for_launcher_service(app))
388 icon_path = get_file_path_from_iconname(
389 self.icons,
390 iconname=appdetails.icon_file_name)
384 launcher_info = UnityLauncherInfo(app.name,391 launcher_info = UnityLauncherInfo(app.name,
385 appdetails.icon,392 appdetails.icon,
386 "", # we set the icon_file_path value *after* install393 icon_path,
387 icon_x,394 icon_x,
388 icon_y,395 icon_y,
389 icon_size,396 icon_size,
390 appdetails.desktop_file,397 appdetails.desktop_file,
391 "", # we set the installed_desktop_file_path *after* install
392 trans_id)398 trans_id)
393 self.unity_launcher.add_to_launcher_queue(app.pkgname, launcher_info)399 return launcher_info
394400
395 def _get_onscreen_icon_details_for_launcher_service(self, app):401 def _get_onscreen_icon_details_for_launcher_service(self, app):
396 if self.is_app_details_view_showing():402 if self.is_app_details_view_showing():
@@ -399,28 +405,6 @@
399 # TODO: implement the app list view case once it has been specified405 # TODO: implement the app list view case once it has been specified
400 return (0, 0, 0)406 return (0, 0, 0)
401407
402 def on_transaction_finished(self, backend, result):
403 self._check_unity_launcher_transaction_finished(result)
404
405 def _check_unity_launcher_transaction_finished(self, result):
406 # add the completed transaction details to the corresponding
407 # launcher_item
408 if result.pkgname in self.unity_launcher.launcher_queue:
409 launcher_info = self.unity_launcher.launcher_queue[result.pkgname]
410 launcher_info.icon_file_path = get_file_path_from_iconname(
411 self.icons, launcher_info.icon_name)
412 installed_path = convert_desktop_file_to_installed_location(
413 launcher_info.app_install_desktop_file_path, result.pkgname)
414 launcher_info.installed_desktop_file_path = installed_path
415 if result.success:
416 self.unity_launcher.send_application_to_launcher(
417 result.pkgname, launcher_info)
418 else:
419 self.unity_launcher.remove_from_launcher_queue(result.pkgname)
420
421 def on_transaction_stopped(self, backend, result):
422 self.unity_launcher.remove_from_launcher_queue(result.pkgname)
423
424 def on_app_list_changed(self, pane, length):408 def on_app_list_changed(self, pane, length):
425 """internal helper that keeps the status text and the action409 """internal helper that keeps the status text and the action
426 bar up-to-date by keeping track of the app-list-changed410 bar up-to-date by keeping track of the app-list-changed
427411
=== modified file 'test/gtk3/test_unity_launcher_integration.py'
--- test/gtk3/test_unity_launcher_integration.py 2012-01-16 14:42:49 +0000
+++ test/gtk3/test_unity_launcher_integration.py 2012-01-30 04:08:26 +0000
@@ -4,8 +4,6 @@
4import time4import time
5import unittest5import unittest
66
7from mock import Mock
8
9from testutils import setup_test_env7from testutils import setup_test_env
10setup_test_env()8setup_test_env()
119
@@ -16,6 +14,7 @@
16from softwarecenter.utils import convert_desktop_file_to_installed_location14from softwarecenter.utils import convert_desktop_file_to_installed_location
17from softwarecenter.db.application import Application15from softwarecenter.db.application import Application
18from softwarecenter.ui.gtk3.panes.availablepane import get_test_window16from softwarecenter.ui.gtk3.panes.availablepane import get_test_window
17from softwarecenter.backend.unitylauncher import UnityLauncherInfo
1918
20# we can only have one instance of availablepane, so create it here19# we can only have one instance of availablepane, so create it here
21win = get_test_window()20win = get_test_window()
@@ -51,47 +50,58 @@
51 TransactionTypes.INSTALL)50 TransactionTypes.INSTALL)
52 # wait a wee bit51 # wait a wee bit
53 self._zzz()52 self._zzz()
54
55 def test_unity_launcher_integration(self):
56 # test the automatic add to launcher enabled functionality
57 available_pane.add_to_launcher_enabled = True
58 test_pkgname = "lincity-ng"
59 mock_result = Mock()
60 mock_result.pkgname = test_pkgname
61 mock_result.success = True
62 # now pretend
63 self._navigate_to_appdetails_and_install(test_pkgname)
64 53
65 # check that a correct UnityLauncherInfo object has been created and54 def _fake_send_application_to_launcher_and_check(self,
66 # added to the queue55 pkgname, launcher_info):
67 self.assertTrue(test_pkgname in available_pane.unity_launcher.launcher_queue)56 self.assertEqual(pkgname, self.expected_pkgname)
68 launcher_info = available_pane.unity_launcher.remove_from_launcher_queue(test_pkgname)57 self.assertEqual(launcher_info.name, self.expected_launcher_info.name)
69 # check the UnityLauncherInfo values themselves58 self.assertEqual(launcher_info.icon_name,
70 self.assertEqual(launcher_info.name, "lincity-ng")59 self.expected_launcher_info.icon_name)
71 self.assertEqual(launcher_info.icon_name, "lincity-ng")
72 self.assertTrue(launcher_info.icon_x > 5)60 self.assertTrue(launcher_info.icon_x > 5)
73 self.assertTrue(launcher_info.icon_y > 5)61 self.assertTrue(launcher_info.icon_y > 5)
74 self.assertEqual(launcher_info.icon_size, 96)62 self.assertEqual(launcher_info.icon_size, 96)
75 self.assertEqual(launcher_info.app_install_desktop_file_path,63 self.assertEqual(launcher_info.app_install_desktop_file_path,
76 "/usr/share/app-install/desktop/lincity-ng:lincity-ng.desktop")64 self.expected_launcher_info.app_install_desktop_file_path)
77 self.assertEqual(launcher_info.trans_id, "testid101")65 self.assertEqual(launcher_info.trans_id,
78 # finally, make sure the the app has been removed from the launcher66 self.expected_launcher_info.trans_id)
79 # queue 67
80 self.assertFalse(test_pkgname in available_pane.unity_launcher.launcher_queue)68 def test_unity_launcher_integration(self):
69 # test the automatic add to launcher enabled functionality
70 available_pane.add_to_launcher_enabled = True
71 test_pkgname = "lincity-ng"
72 # now pretend
73 # for testing, we substitute a fake version of UnityLauncher's
74 # send_application_to_launcher method that lets us check for the
75 # correct values and also avoids firing the actual dbus signal
76 # to the unity launcher service
77 self.expected_pkgname = test_pkgname
78 self.expected_launcher_info = UnityLauncherInfo("lincity-ng",
79 "lincity-ng",
80 0, 0, 0, 0, # these values are set in availablepane
81 "/usr/share/app-install/desktop/lincity-ng:lincity-ng.desktop",
82 "testid101")
83 available_pane.unity_launcher.send_application_to_launcher = (
84 self._fake_send_application_to_launcher_and_check)
85 self._navigate_to_appdetails_and_install(test_pkgname)
81 86
82 def test_unity_launcher_integration_disabled(self):87 def test_unity_launcher_integration_disabled(self):
83 # test the case where automatic add to launcher is disabled88 # test the case where automatic add to launcher is disabled
84 available_pane.add_to_launcher_enabled = False89 available_pane.add_to_launcher_enabled = False
85 test_pkgname = "lincity-ng"90 test_pkgname = "lincity-ng"
86 mock_result = Mock()
87 mock_result.pkgname = test_pkgname
88 mock_result.success = True
89 # now pretend91 # now pretend
92 # for testing, we substitute a fake version of UnityLauncher's
93 # send_application_to_launcher method that lets us check for the
94 # correct values and also avoids firing the actual dbus signal
95 # to the unity launcher service
96 # in the disabled add to launcher case, we just want to insure
97 # that we never call send_application_to_launcher, so we can just
98 # plug in bogus values and we will catch a call if it occurs
99 self.expected_pkgname = ""
100 self.expected_launcher_info = UnityLauncherInfo("", "",
101 0, 0, 0, 0, "", "")
102 available_pane.unity_launcher.send_application_to_launcher = (
103 self._fake_send_application_to_launcher_and_check)
90 self._navigate_to_appdetails_and_install(test_pkgname)104 self._navigate_to_appdetails_and_install(test_pkgname)
91
92 # check that no corresponding unity_launcher info object has been added
93 # to the queue
94 self.assertFalse(test_pkgname in available_pane.unity_launcher.launcher_queue)
95105
96 def test_desktop_file_path_conversion(self):106 def test_desktop_file_path_conversion(self):
97 # test 'normal' case107 # test 'normal' case

Subscribers

People subscribed via source and target branches