=== modified file 'data/ui/gtk3/SoftwareCenter.ui'
--- data/ui/gtk3/SoftwareCenter.ui	2011-11-07 09:41:23 +0000
+++ data/ui/gtk3/SoftwareCenter.ui	2011-11-30 14:34:40 +0000
@@ -381,7 +381,7 @@
                 <property name="use_underline">True</property>
                 <signal name="activate" handler="on_menu_view_activate" swapped="no"/>
                 <child type="submenu">
-                  <object class="GtkMenu" id="menu4">
+                  <object class="GtkMenu" id="menu_view">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <child>
@@ -420,9 +420,9 @@
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
                         <property name="related_action">navhistory_back_action</property>
+                        <property name="use_action_appearance">False</property>
                         <property name="use_underline">True</property>
                         <property name="use_stock">False</property>
-                        <property name="use_action_appearance">False</property>
                         <accelerator key="bracketleft" signal="activate" modifiers="GDK_CONTROL_MASK"/>
                       </object>
                     </child>
@@ -432,12 +432,28 @@
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
                         <property name="related_action">navhistory_forward_action</property>
+                        <property name="use_action_appearance">False</property>
                         <property name="use_underline">True</property>
                         <property name="use_stock">False</property>
-                        <property name="use_action_appearance">False</property>
                         <accelerator key="bracketright" signal="activate" modifiers="GDK_CONTROL_MASK"/>
                       </object>
                     </child>
+                    <child>
+                      <object class="GtkSeparatorMenuItem" id="add_to_launcher_separator">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkCheckMenuItem" id="menuitem_add_to_launcher">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="use_action_appearance">False</property>
+                        <property name="label" translatable="yes">_New Applications in Launcher</property>
+                        <property name="use_underline">True</property>
+                        <signal name="toggled" handler="on_menuitem_add_to_launcher_toggled" swapped="no"/>
+                      </object>
+                    </child>
                   </object>
                 </child>
               </object>
@@ -476,7 +492,7 @@
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
                         <property name="use_action_appearance">False</property>
-                        <property name="use_underline">False</property>
+                        <property name="use_stock">False</property>
                         <signal name="activate" handler="on_menuitem_developer_activate" swapped="no"/>
                       </object>
                     </child>

=== added file 'softwarecenter/backend/unitylauncher.py'
--- softwarecenter/backend/unitylauncher.py	1970-01-01 00:00:00 +0000
+++ softwarecenter/backend/unitylauncher.py	2011-11-30 14:34:40 +0000
@@ -0,0 +1,98 @@
+# Copyright (C) 2011 Canonical
+#
+# Authors:
+#  Gary Lasker
+#
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free Software
+# Foundation; version 3.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import dbus
+import logging
+
+LOG = logging.getLogger(__name__)
+
+class UnityLauncherInfo(object):
+    """ Simple class to keep track of application details needed for
+        Unity launcher integration
+    """
+    def __init__(self,
+                 name,
+                 icon_name,
+                 icon_file_path,
+                 icon_x,
+                 icon_y,
+                 icon_size,
+                 app_install_desktop_file_path,
+                 installed_desktop_file_path,
+                 trans_id):
+        self.name = name
+        self.icon_name = icon_name
+        self.icon_file_path = icon_file_path
+        self.icon_x = icon_x
+        self.icon_y = icon_y
+        self.icon_size = icon_size
+        self.app_install_desktop_file_path = app_install_desktop_file_path
+        self.installed_desktop_file_path = installed_desktop_file_path
+        self.trans_id = trans_id
+        
+class UnityLauncher(object):
+    """ Implements the integration between Software Center and the Unity
+        launcher
+    """
+    def __init__(self):
+        # keep track of applications that are candidates for adding
+        # to the Unity launcher
+        self.launcher_queue = {}
+        
+    def add_to_launcher_queue(self, pkgname, launcher_info):
+        """ add an application and its associated info to the set of candidates
+            for adding to the Unity launcher
+        """
+        self.launcher_queue[pkgname] = launcher_info
+        
+    def remove_from_launcher_queue(self, pkgname):
+        """ remove an application and its associated info from the set of
+            candidates for adding to the Unity launcher
+        """
+        if pkgname in self.launcher_queue:
+            return self.launcher_queue.pop(pkgname)
+        
+    def send_application_to_launcher(self, pkgname, launcher_info):
+        LOG.debug("sending dbus signal to Unity launcher for application: ", 
+                  launcher_info.name)
+        LOG.debug("  launcher_info.icon_file_path: ", 
+                     launcher_info.icon_file_path)
+        LOG.debug("  launcher_info.installed_desktop_file_path: ",
+                     launcher_info.installed_desktop_file_path)
+        LOG.debug("  launcher_info.trans_id: ", launcher_info.trans_id)
+        # the application is being added to the launcher, so clear it from the
+        # list of candidates in the launcher queue
+        self.remove_from_launcher_queue(pkgname)
+        # add the application by sending a dbus signal to the Unity launcher
+        try:
+            bus = dbus.SessionBus()
+            launcher_obj = bus.get_object('com.canonical.Unity.Launcher',
+                                          '/com/canonical/Unity/Launcher')
+            launcher_iface = dbus.Interface(launcher_obj,
+                                            'com.canonical.Unity.Launcher')
+            launcher_iface.AddLauncherItemFromPosition(
+                    launcher_info.name,
+                    launcher_info.icon_file_path,
+                    launcher_info.icon_x,
+                    launcher_info.icon_y,
+                    launcher_info.icon_size,
+                    launcher_info.installed_desktop_file_path,
+                    launcher_info.trans_id)
+        except Exception as e:
+            LOG.warn("could not send dbus signal to the Unity launcher: (%s)",
+                     e)

=== modified file 'softwarecenter/ui/gtk3/app.py'
--- softwarecenter/ui/gtk3/app.py	2011-11-24 14:48:07 +0000
+++ softwarecenter/ui/gtk3/app.py	2011-11-30 14:34:40 +0000
@@ -61,7 +61,8 @@
                                   MOUSE_EVENT_BACK_BUTTON)
 from softwarecenter.utils import (clear_token_from_ubuntu_sso,
                                   get_http_proxy_string_from_gsettings,
-                                  wait_for_apt_cache_ready)
+                                  wait_for_apt_cache_ready,
+                                  is_unity_running)
 from softwarecenter.ui.gtk3.utils import (get_sc_icon_theme,
                                           init_sc_css_provider)
 from softwarecenter.version import VERSION
@@ -350,7 +351,7 @@
         supported_menuitem = self.builder.get_object("menuitem_view_supported_only")
         supported_menuitem.set_label(self.distro.get_supported_filter_name())
         file_menu = self.builder.get_object("menu1")
-
+        
         if not self.distro.DEVELOPER_URL:
             help_menu = self.builder.get_object("menu_help")
             developer_separator = self.builder.get_object("separator_developer")
@@ -362,6 +363,20 @@
         och = is_oneconf_available()
         if not och:
             file_menu.remove(self.builder.get_object("menuitem_sync_between_computers"))
+            
+        # restore the state of the add to launcher menu item, or remove the menu
+        # item if Unity is not currently running
+        add_to_launcher_menuitem = self.builder.get_object(
+                                                    "menuitem_add_to_launcher")
+        if is_unity_running():
+            add_to_launcher_menuitem.set_active(
+                                self.available_pane.add_to_launcher_enabled)
+        else:
+            view_menu = self.builder.get_object("menu_view")
+            add_to_launcher_separator = self.builder.get_object(
+                                                    "add_to_launcher_separator")
+            view_menu.remove(add_to_launcher_separator)
+            view_menu.remove(add_to_launcher_menuitem)
 
         # run s-c-agent update
         if options.disable_buy or not self.distro.PURCHASE_APP_URL:
@@ -963,6 +978,9 @@
     def on_navhistory_forward_action_activate(self, navhistory_forward_action=None):
         vm = get_viewmanager()
         vm.nav_forward()
+        
+    def on_menuitem_add_to_launcher_toggled(self, menu_item):
+        self.available_pane.add_to_launcher_enabled = menu_item.get_active()
 
 # Help Menu
     def on_menuitem_about_activate(self, widget):
@@ -1154,11 +1172,20 @@
             # in case of a crazy-huge monitor)
             screen_height = Gdk.Screen.height()
             screen_width = Gdk.Screen.width()
-            self.window_main.set_default_size(min(int(.85 * screen_width), 1200),
-                                              min(int(.85 * screen_height), 800))
+            self.window_main.set_default_size(
+                                        min(int(.85 * screen_width), 1200),
+                                        min(int(.85 * screen_height), 800))
         if (self.config.has_option("general", "maximized") and
             self.config.getboolean("general", "maximized")):
             self.window_main.maximize()
+        if self.config.has_option("general", "add_to_launcher"):
+            self.available_pane.add_to_launcher_enabled = (
+                    self.config.getboolean(
+                    "general",
+                    "add_to_launcher"))
+        else:
+            # initial default state is to add to launcher, per spec
+            self.available_pane.add_to_launcher_enabled = True
 
     def save_state(self):
         LOG.debug("save_state")
@@ -1176,6 +1203,10 @@
             # size only matters when non-maximized
             size = self.window_main.get_size() 
             self.config.set("general","size", "%s, %s" % (size[0], size[1]))
+        if self.available_pane.add_to_launcher_enabled:
+            self.config.set("general", "add_to_launcher", "True")
+        else:
+            self.config.set("general", "add_to_launcher", "False")
         self.config.write()
 
     def run(self, args):

=== modified file 'softwarecenter/ui/gtk3/panes/availablepane.py'
--- softwarecenter/ui/gtk3/panes/availablepane.py	2011-11-17 00:28:02 +0000
+++ softwarecenter/ui/gtk3/panes/availablepane.py	2011-11-30 14:34:40 +0000
@@ -21,7 +21,9 @@
 from gi.repository import Gtk
 import logging
 import xapian
+import os
 
+import softwarecenter.utils
 import softwarecenter.ui.gtk3.dialogs as dialogs
 from softwarecenter.ui.gtk3.models.appstore2 import AppListStore
 
@@ -30,9 +32,13 @@
 from softwarecenter.enums import (ActionButtons,
                                   NavButtons,
                                   NonAppVisibility,
-                                  DEFAULT_SEARCH_LIMIT)
+                                  DEFAULT_SEARCH_LIMIT,
+                                  TransactionTypes)
 from softwarecenter.paths import APP_INSTALL_PATH
-from softwarecenter.utils import wait_for_apt_cache_ready
+from softwarecenter.utils import (wait_for_apt_cache_ready,
+                                  is_no_display_desktop_file,
+                                  convert_desktop_file_to_installed_location,
+                                  get_file_path_from_iconname)
 from softwarecenter.db.appfilter import AppFilter
 from softwarecenter.db.database import Application
 from softwarecenter.ui.gtk3.views.purchaseview import PurchaseView
@@ -42,6 +48,8 @@
 from softwarepane import SoftwarePane
 from softwarecenter.ui.gtk3.session.viewmanager import get_viewmanager
 from softwarecenter.ui.gtk3.session.appmanager import get_appmanager
+from softwarecenter.backend.unitylauncher import (UnityLauncher,
+                                                  UnityLauncherInfo)
 
 LOG = logging.getLogger(__name__)
 
@@ -91,6 +99,14 @@
         # views to be created in init_view
         self.cat_view = None
         self.subcategories_view = None
+        
+        # integrate with the Unity launcher
+        self.unity_launcher = UnityLauncher()
+        
+        # flag to indicate whether applications should be added to the
+        # unity launcher when installed (this value is initialized by
+        # the config load in app.py)
+        self.add_to_launcher_enabled = True
 
     def init_view(self):
         if self.view_initialized: 
@@ -179,6 +195,10 @@
 
         # install backend
         self.backend.connect("transactions-changed", self._on_transactions_changed)
+        self.backend.connect("transaction-started", self.on_transaction_started)
+        self.backend.connect("transaction-finished", self.on_transaction_finished)
+        self.backend.connect("transaction-stopped", self.on_transaction_stopped)
+        
         # now we are initialized
         self.searchentry.set_sensitive(True)
         self.emit("available-pane-created")
@@ -322,6 +342,75 @@
         """
         if self._is_custom_list_search(self.state.search_term):
             self._update_action_bar()
+            
+    def on_transaction_started(self, backend, pkgname, appname, trans_id, 
+                               trans_type):
+        self._register_unity_launcher_transaction_started(
+            backend, pkgname, appname, trans_id, trans_type)
+
+    def _register_unity_launcher_transaction_started(self, backend, pkgname, 
+                                                     appname, trans_id, 
+                                                     trans_type):
+        if not self.add_to_launcher_enabled:
+            return
+        # mvo: use use softwarecenter.utils explictly so that we can monkey
+        #      patch it in the test
+        if not softwarecenter.utils.is_unity_running():
+            return
+        # we only care about getting the launcher information on an install
+        if not trans_type == TransactionTypes.INSTALL:
+            return
+        # gather details for this transaction and create the launcher_info object
+        app = Application(pkgname=pkgname, appname=appname)
+        appdetails = app.get_details(self.db)
+        # we only add items to the launcher that have a desktop file
+        if not appdetails.desktop_file:
+            return
+        # do not add apps without a exec line (like wine, see #848437)
+        if (os.path.exists(appdetails.desktop_file) and
+            is_no_display_desktop_file(appdetails.desktop_file)):
+            return
+
+        (icon_size, icon_x, icon_y) = self._get_onscreen_icon_details_for_launcher_service(app)
+        launcher_info = UnityLauncherInfo(app.name,
+                                          appdetails.icon,
+                                          "",        # we set the icon_file_path value *after* install
+                                          icon_x,
+                                          icon_y,
+                                          icon_size,
+                                          appdetails.desktop_file,
+                                          "",        # we set the installed_desktop_file_path *after* install
+                                          trans_id)
+        self.unity_launcher.add_to_launcher_queue(app.pkgname, launcher_info)
+
+    def _get_onscreen_icon_details_for_launcher_service(self, app):
+        if self.is_app_details_view_showing():
+            return self.app_details_view.get_app_icon_details()
+        else:
+            # TODO: implement the app list view case once it has been specified
+            return (0, 0, 0)
+
+    def on_transaction_finished(self, backend, result):
+        self._check_unity_launcher_transaction_finished(result)
+        
+    def _check_unity_launcher_transaction_finished(self, result):
+        # add the completed transaction details to the corresponding
+        # launcher_item
+        if result.pkgname in self.unity_launcher.launcher_queue:
+            launcher_info = self.unity_launcher.launcher_queue[result.pkgname]
+            launcher_info.icon_file_path = get_file_path_from_iconname(
+                self.icons, launcher_info.icon_name)
+            installed_path = convert_desktop_file_to_installed_location(
+                launcher_info.app_install_desktop_file_path, result.pkgname)
+            launcher_info.installed_desktop_file_path = installed_path
+            if result.success:
+                self.unity_launcher.send_application_to_launcher(
+                                            result.pkgname, launcher_info)
+            else:
+                self.unity_launcher.remove_from_launcher_queue(result.pkgname)
+
+    def on_transaction_stopped(self, backend, result):
+        self.unity_launcher.remove_from_launcher_queue(result.pkgname)
 
     def on_app_list_changed(self, pane, length):
         """internal helper that keeps the status text and the action

=== modified file 'softwarecenter/ui/gtk3/panes/softwarepane.py'
--- softwarecenter/ui/gtk3/panes/softwarepane.py	2011-10-25 18:38:08 +0000
+++ softwarecenter/ui/gtk3/panes/softwarepane.py	2011-11-30 14:34:40 +0000
@@ -17,7 +17,6 @@
 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
 from gi.repository import Atk
-import dbus
 import gettext
 from gi.repository import GObject
 from gi.repository import Gtk, Gdk
@@ -26,21 +25,14 @@
 import os
 import xapian
 
-from gettext import gettext as _
-
-import softwarecenter.utils
 from softwarecenter.backend import get_install_backend
 from softwarecenter.db.database import Application
 from softwarecenter.db.enquire import AppEnquire
-from softwarecenter.enums import (ActionButtons,
-                                  SortMethods,
-                                  TransactionTypes,
+from softwarecenter.enums import (SortMethods,
                                   DEFAULT_SEARCH_LIMIT,
                                   NonAppVisibility)
 
 from softwarecenter.utils import (ExecutionTime,
-                                  convert_desktop_file_to_installed_location,
-                                  get_file_path_from_iconname,
                                   wait_for_apt_cache_ready,
                                   utf8
                                   )
@@ -55,39 +47,10 @@
                                                 AppDetailsViewGtk as
                                                 AppDetailsView)
 
-from softwarecenter.utils import is_no_display_desktop_file
-
 from basepane import BasePane
 
 LOG = logging.getLogger(__name__)
 
-
-class UnityLauncherInfo(object):
-    """ Simple class to keep track of application details needed for
-        Unity launcher integration
-    """
-    def __init__(self,
-                 name,
-                 icon_name,
-                 icon_file_path,
-                 icon_x,
-                 icon_y,
-                 icon_size,
-                 app_install_desktop_file_path,
-                 installed_desktop_file_path,
-                 trans_id):
-        self.name = name
-        self.icon_name = icon_name
-        self.icon_file_path = icon_file_path
-        self.icon_x = icon_x
-        self.icon_y = icon_y
-        self.icon_size = icon_size
-        self.app_install_desktop_file_path = app_install_desktop_file_path
-        self.installed_desktop_file_path = installed_desktop_file_path
-        self.trans_id = trans_id
-        self.add_to_launcher_requested = False
-
-
 # for DisplayState attribute type-checking
 from softwarecenter.db.categories import Category
 from softwarecenter.backend.channel import SoftwareChannel
@@ -202,9 +165,6 @@
         # request (e.g. people click on ubuntu channel, get impatient, click
         # on partner channel)
         self.refresh_seq_nr = 0
-        # keep track of applications that are candidates to be added
-        # to the Unity launcher
-        self.unity_launcher_items = {}
         # this should be initialized
         self.apps_search_term = ""
         # Create the basic frame for the common view
@@ -282,14 +242,9 @@
         # when the cache changes, refresh the app list
         self.cache.connect("cache-ready", self.on_cache_ready)
 
-        # aptdaemon
-        self.backend.connect("transaction-started", self.on_transaction_started)
-        self.backend.connect("transaction-finished", self.on_transaction_finished)
-        self.backend.connect("transaction-stopped", self.on_transaction_stopped)
-        
         # connect signals
         self.connect("app-list-changed", self.on_app_list_changed)
-        
+
         # db reopen
         if self.db:
             self.db.connect("reopen", self.on_db_reopen)
@@ -335,81 +290,6 @@
         vm = get_viewmanager()
         vm.nav_forward()
 
-    def on_transaction_started(self, backend, pkgname, appname, trans_id, 
-                               trans_type):
-        self._register_unity_launcher_transaction_started(
-            backend, pkgname, appname, trans_id, trans_type)
-
-        
-    def _get_onscreen_icon_details_for_launcher_service(self, app):
-        if self.is_app_details_view_showing():
-            return self.app_details_view.get_app_icon_details()
-        else:
-            # TODO: implement the app list view case once it has been specified
-            return (0, 0, 0)
-       
-    def _register_unity_launcher_transaction_started(self, backend, pkgname, 
-                                                     appname, trans_id, 
-                                                     trans_type):
-        # mvo: use use softwarecenter.utils explictely so that we can monkey
-        #      patch it in the test
-        if not softwarecenter.utils.is_unity_running():
-            return
-        # add to launcher only applies in the details view currently
-        if not self.is_app_details_view_showing():
-            return
-        # we only care about getting the launcher information on an install
-        if not trans_type == TransactionTypes.INSTALL:
-            if pkgname in self.unity_launcher_items:
-                self.unity_launcher_items.pop(pkgname)
-                self.action_bar.clear()
-            return
-        # gather details for this transaction and create the launcher_info object
-        app = Application(pkgname=pkgname, appname=appname)
-        appdetails = app.get_details(self.db)
-        (icon_size, icon_x, icon_y) = self._get_onscreen_icon_details_for_launcher_service(app)
-        launcher_info = UnityLauncherInfo(app.name,
-                                          appdetails.icon,
-                                          "",        # we set the icon_file_path value *after* install
-                                          icon_x,
-                                          icon_y,
-                                          icon_size,
-                                          appdetails.desktop_file,
-                                          "",        # we set the installed_desktop_file_path *after* install
-                                          trans_id)
-        self.unity_launcher_items[app.pkgname] = launcher_info
-        self.show_add_to_launcher_panel(backend, pkgname, appname, app, appdetails, trans_id, trans_type)
-                
-    def show_add_to_launcher_panel(self, backend, pkgname, appname, app, appdetails, trans_id, trans_type):
-        """
-        if Unity is currently running, display a panel to allow the user
-        the choose whether to add a newly-installed application to the
-        launcher
-        """
-        # TODO: handle local deb install case
-        # TODO: implement the list view case (once it is specified)
-        # only show the panel if unity is running and this is a package install
-        #
-        # we only show the prompt for apps with a desktop file
-        if not appdetails.desktop_file:
-            return
-        # do not add apps without a exec line (like wine, see #848437)
-        if (os.path.exists(appdetails.desktop_file) and
-            is_no_display_desktop_file(appdetails.desktop_file)):
-                return
-        self.action_bar.add_button(ActionButtons.CANCEL_ADD_TO_LAUNCHER,
-                                    _("Not Now"), 
-                                    self.on_cancel_add_to_launcher, 
-                                    pkgname)
-        self.action_bar.add_button(ActionButtons.ADD_TO_LAUNCHER,
-                                   _("Add to Launcher"),
-                                   self.on_add_to_launcher,
-                                   pkgname,
-                                   app,
-                                   appdetails,
-                                   trans_id)
-        self.action_bar.set_label(utf8(_("Add %s to the launcher?")) % utf8(app.name))
-
     def on_query_complete(self, enquirer):
         self.emit("app-list-changed", len(enquirer.matches))
         self.app_view.display_matches(enquirer.matches,
@@ -427,81 +307,10 @@
         self._refresh_apps_with_apt_cache(query)
         return
 
-    def on_add_to_launcher(self, pkgname, app, appdetails, trans_id):
-        """
-        callback indicating the user has chosen to add the indicated application
-        to the launcher
-        """
-        if pkgname in self.unity_launcher_items:
-            launcher_info = self.unity_launcher_items[pkgname]
-            if launcher_info.installed_desktop_file_path:
-                # package install is complete, we can add to the launcher immediately
-                self.unity_launcher_items.pop(pkgname)
-                self.action_bar.clear()
-                self._send_dbus_signal_to_unity_launcher(launcher_info)
-            else:
-                # package is not yet installed, it will be added to the launcher
-                # once the installation is complete
-                LOG.debug("the application '%s' will be added to the Unity launcher when installation is complete" % app.name)
-                launcher_info.add_to_launcher_requested = True
-                self.action_bar.set_label(_("%s will be added to the launcher when installation completes.") % app.name)
-                self.action_bar.remove_button(ActionButtons.CANCEL_ADD_TO_LAUNCHER)
-                self.action_bar.remove_button(ActionButtons.ADD_TO_LAUNCHER)
-
-    def on_cancel_add_to_launcher(self, pkgname):
-        if pkgname in self.unity_launcher_items:
-            self.unity_launcher_items.pop(pkgname)
-        self.action_bar.clear()
-        
-    def on_transaction_finished(self, backend, result):
-        self._check_unity_launcher_transaction_finished(result)
-
     def _is_in_search_mode(self):
         return (self.state.search_term and
                 len(self.state.search_term) >= 2)
 
-    def _check_unity_launcher_transaction_finished(self, result):
-        # add the completed transaction details to the corresponding
-        # launcher_item
-        if result.pkgname in self.unity_launcher_items:
-            launcher_info = self.unity_launcher_items[result.pkgname]
-            launcher_info.icon_file_path = get_file_path_from_iconname(
-                self.icons, launcher_info.icon_name)
-            installed_path = convert_desktop_file_to_installed_location(
-                launcher_info.app_install_desktop_file_path, result.pkgname)
-            launcher_info.installed_desktop_file_path = installed_path
-            # if the request to add to launcher has already been made, do it now
-            if launcher_info.add_to_launcher_requested:
-                if result.success:
-                    self._send_dbus_signal_to_unity_launcher(launcher_info)
-                self.unity_launcher_items.pop(result.pkgname)
-                self.action_bar.clear()
-            
-    def _send_dbus_signal_to_unity_launcher(self, launcher_info):
-        LOG.debug("sending dbus signal to Unity launcher for application: ", launcher_info.name)
-        LOG.debug("  launcher_info.icon_file_path: ", launcher_info.icon_file_path)
-        LOG.debug("  launcher_info.installed_desktop_file_path: ", launcher_info.installed_desktop_file_path)
-        LOG.debug("  launcher_info.trans_id: ", launcher_info.trans_id)
-        try:
-            bus = dbus.SessionBus()
-            launcher_obj = bus.get_object('com.canonical.Unity.Launcher',
-                                          '/com/canonical/Unity/Launcher')
-            launcher_iface = dbus.Interface(launcher_obj, 'com.canonical.Unity.Launcher')
-            launcher_iface.AddLauncherItemFromPosition(launcher_info.name,
-                                                       launcher_info.icon_file_path,
-                                                       launcher_info.icon_x,
-                                                       launcher_info.icon_y,
-                                                       launcher_info.icon_size,
-                                                       launcher_info.installed_desktop_file_path,
-                                                       launcher_info.trans_id)
-        except Exception as e:
-            LOG.warn("could not send dbus signal to the Unity launcher: (%s)", e)
-            
-    def on_transaction_stopped(self, backend, result):
-        if result.pkgname in self.unity_launcher_items:
-            self.unity_launcher_items.pop(result.pkgname)
-        self.action_bar.clear()
-
     def show_appview_spinner(self):
         """ display the spinner in the appview panel """
         if not self.state.search_term:

=== modified file 'test/gtk3/test_unity_launcher_integration.py'
--- test/gtk3/test_unity_launcher_integration.py	2011-11-17 03:17:37 +0000
+++ test/gtk3/test_unity_launcher_integration.py	2011-11-30 14:34:40 +0000
@@ -54,36 +54,10 @@
                                     TransactionTypes.INSTALL)
         # wait a wee bit
         self._zzz()
-        
-    def test_unity_launcher_stays_after_install_finished(self):
-        test_pkgname = "gl-117"
-        mock_result = Mock()
-        mock_result.pkgname = test_pkgname
-        mock_result.success = True
-        # now pretend
-        # now pretend
-        self._navigate_to_appdetails_and_install(test_pkgname)
-        # pretend we are done
-        available_pane.backend.emit("transaction-finished", mock_result)
-        # this is normally set in the transaction-finished call but our
-        # app is not really installed so we need to mock it here
-        available_pane.unity_launcher_items[test_pkgname].installed_desktop_file_path = "/some/path"
-        # wait a wee bit
-        self._zzz()
-        # ensure we still have the button
-        button = available_pane.action_bar.get_button(
-                ActionButtons.ADD_TO_LAUNCHER)
-        self.assertNotEqual(button, None)
-        self.assertTrue(button.get_property("visible"))
-        # now click it even though the transaction is over
-        button.clicked()
-        self._zzz()
-        # ensure the add to launcher button is now hidden
-        button = available_pane.action_bar.get_button(
-                ActionButtons.ADD_TO_LAUNCHER)
-        self.assertEqual(button, None)
 
     def test_unity_launcher_integration(self):
+        # test the automatic add to launcher enabled functionality
+        available_pane.add_to_launcher_enabled = True
         test_pkgname = "lincity-ng"
         mock_result = Mock()
         mock_result.pkgname = test_pkgname
@@ -91,18 +65,10 @@
         # now pretend
         self._navigate_to_appdetails_and_install(test_pkgname)
         
-        # verify that the panel is shown offering to add the app to the launcher
-        self.assertTrue(available_pane.action_bar.get_property("visible"))
-        button = available_pane.action_bar.get_button(
-            ActionButtons.ADD_TO_LAUNCHER)
-        self.assertTrue(button is not None)
-        # click the button 
-        button.clicked()
-
         # check that a correct UnityLauncherInfo object has been created and
         # added to the queue
-        self.assertTrue(test_pkgname in available_pane.unity_launcher_items)
-        launcher_info = available_pane.unity_launcher_items.pop(test_pkgname)
+        self.assertTrue(test_pkgname in available_pane.unity_launcher.launcher_queue)
+        launcher_info = available_pane.unity_launcher.remove_from_launcher_queue(test_pkgname)
         # check the UnityLauncherInfo values themselves
         self.assertEqual(launcher_info.name, "lincity-ng")
         self.assertEqual(launcher_info.icon_name, "lincity-ng")
@@ -114,8 +80,22 @@
         self.assertEqual(launcher_info.trans_id, "testid101")
         # finally, make sure the the app has been removed from the launcher
         # queue        
-        self.assertFalse(test_pkgname in available_pane.unity_launcher_items)
-        
+        self.assertFalse(test_pkgname in available_pane.unity_launcher.launcher_queue)
+        
+    def test_unity_launcher_integration_disabled(self):
+        # test the case where automatic add to launcher is disabled
+        available_pane.add_to_launcher_enabled = False
+        test_pkgname = "lincity-ng"
+        mock_result = Mock()
+        mock_result.pkgname = test_pkgname
+        mock_result.success = True
+        # now pretend
+        self._navigate_to_appdetails_and_install(test_pkgname)
+        
+        # check that no corresponding unity_launcher info object has been added
+        # to the queue
+        self.assertFalse(test_pkgname in available_pane.unity_launcher.launcher_queue)
+
     def test_desktop_file_path_conversion(self):
         # test 'normal' case
         app_install_desktop_path = ("./data/app-install/desktop/" +

