def __init__(self, datadir, db, icons):
        gtk.TreeStore.__init__(self, AnimatedImage, str, int, gobject.TYPE_PYOBJECT)
        self.icons = icons
        self.datadir = datadir
        self.backend = get_install_backend()
        self.backend.connect("transactions-changed", self.on_transactions_changed)
        self.backend.connect("channels-changed", self.on_channels_changed)
        self.db = db
        self.distro = get_distro()
        # pending transactions
        self._pending = 0
        # setup the normal stuff
        available_icon = self._get_icon("softwarecenter")
        self.available_iter = self.append(None, [available_icon, _("Get Software"), self.ACTION_ITEM_AVAILABLE, None])

        # do initial channel list update
        self._update_channel_list()
        
        icon = AnimatedImage(self.icons.load_icon("computer", self.ICON_SIZE, 0))
        installed_iter = self.append(None, [icon, _("Installed Software"), self.ACTION_ITEM_INSTALLED, None])
        icon = AnimatedImage(None)
        self.append(None, [icon, "<span size='1'> </span>", self.ACTION_ITEM_SEPARATOR_1, None])
        
        # kick off a background check for changes that may have been made
        # in the channels list
        glib.timeout_add(300, lambda: self._check_for_channel_updates(self.channels))
예제 #2
0
    def __init__(self, db, doc=None, application=None):
        """ Create a new AppDetails object. It can be created from
            a xapian.Document or from a db.application.Application object
        """
        GObject.GObject.__init__(self)
        if not doc and not application:
            raise ValueError("Need either document or application")
        self._db = db
        self._db.connect("reopen", self._on_db_reopen)
        self._cache = self._db._aptcache
        self._distro = get_distro()
        self._history = None
        # import here (intead of global) to avoid dbus dependency
        # in update-software-center (that imports application, but
        # never uses AppDetails) LP: #620011
        from softwarecenter.backend import get_install_backend
        self._backend = get_install_backend()
        # FIXME: why two error states ?
        self._error = None
        self._error_not_found = None
        self._screenshot_list = None

        # load application
        self._app = application
        if doc:
            self._app = Application(self._db.get_appname(doc), 
                                    self._db.get_pkgname(doc), 
                                    "")

        # sustitute for apturl
        if self._app.request:
            self._app.request = self._app.request.replace(
                "$distro", self._distro.get_codename())

        # load pkg cache
        self._pkg = None
        if (self._app.pkgname in self._cache and 
            self._cache[self._app.pkgname].candidate):
            self._pkg = self._cache[self._app.pkgname]

        # load xapian document
        self._doc = doc
        if not self._doc:
            try:
                self._doc = self._db.get_xapian_document(
                    self._app.appname, self._app.pkgname)
            except IndexError:
                # if there is no document and no apturl request,
                # set error state
                debfile_matches = re.findall(r'/', self._app.request)
                channel_matches = re.findall(r'channel=[a-z,-]*', 
                                             self._app.request)
                section_matches = re.findall(r'section=[a-z]*', 
                                             self._app.request)
                if (not self._pkg and 
                    not debfile_matches and 
                    not channel_matches and 
                    not section_matches):
                    self._error = _("Not found")
                    self._error_not_found = utf8(_(u"There isn\u2019t a software package called \u201c%s\u201D in your current software sources.")) % utf8(self.pkgname)
 def test_add_license_key_backend(self):
     self._finished = False
     # add repo
     deb_line = "deb https://mvo:[email protected]/canonical-isd-hackers/internal-qa/ubuntu oneiric main"
     signing_key_id = "F5410BE0"
     app = Application("Test app1", self.PKGNAME)
     # install only when runnig as root, as we require polkit promtps
     # otherwise
     # FIXME: provide InstallBackendSimulate()
     if os.getuid() == 0:
         backend = get_install_backend()
         backend.ui = Mock()
         backend.connect("transaction-finished",
                         self._on_transaction_finished)
         # simulate repos becomes available for the public 20 s later
         GObject.timeout_add_seconds(20, self._add_pw_to_commercial_repo)
         # run it
         backend.add_repo_add_key_and_install_app(deb_line, signing_key_id,
                                                  app, "icon",
                                                  self.LICENSE_KEY)
         # wait until the pkg is installed
         while not self._finished:
             while Gtk.events_pending():
                 Gtk.main_iteration()
             time.sleep(0.1)
     if os.getuid() == 0:
         self.assertTrue(os.path.exists(self.LICENSE_KEY_PATH))
         self.assertEqual(
             open(self.LICENSE_KEY_PATH).read(), self.LICENSE_KEY)
예제 #4
0
    def __init__(self, view_manager, datadir, db, cache, icons):
        # boring stuff
        self.view_manager = view_manager

        def on_view_changed(widget, view_id):
            self.view_buttons[view_id].set_active(True)
        self.view_manager.connect('view-changed', on_view_changed)
        self.channel_manager = get_channels_manager(db)

        # backend sig handlers ...
        self.backend = get_install_backend()
        self.backend.connect("transactions-changed",
                             self.on_transaction_changed)
        self.backend.connect("transaction-finished",
                             self.on_transaction_finished)
        self.backend.connect("channels-changed",
                             self.on_channels_changed)

        # widgetry
        Gtk.Box.__init__(self)
        self.set_orientation(Gtk.Orientation.HORIZONTAL)

        # Gui stuff
        self.view_buttons = {}
        self.selectors = {}
        self._prev_view = None  # track the previous active section
        self._prev_item = None  # track the previous active menu-item
        self._handlers = []

        # order is important here!
        # first, the availablepane items
        icon = SymbolicIcon("available")
        self.append_section_with_channel_sel(
                                ViewPages.AVAILABLE,
                                _("All Software"),
                                icon,
                                self.on_get_available_channels)

        # the installedpane items
        icon = SymbolicIcon("installed")
        self.append_section_with_channel_sel(
                                ViewPages.INSTALLED,
                                _("Installed"),
                                icon,
                                self.on_get_installed_channels)

        # the historypane item
        icon = SymbolicIcon("history")
        self.append_section(ViewPages.HISTORY, _("History"), icon)

        #icon = SymbolicIcon("history")
        #self.append_section(ViewPages.UPGRADE, _("Upgrade"), icon)

        # the pendingpane
        icon = PendingSymbolicIcon("pending")
        self.append_section(ViewPages.PENDING, _("Progress"), icon)

        # set sensible atk name
        atk_desc = self.get_accessible()
        atk_desc.set_name(_("Software sources"))
예제 #5
0
    def test_add_license_key_backend(self):
        self._finished = False
        # add repo
        deb_line = "deb https://mvo:[email protected]/canonical-isd-hackers/internal-qa/ubuntu oneiric main"
        signing_key_id = "F5410BE0"
        app = Application("Test app1", self.PKGNAME)
        # install only when runnig as root, as we require polkit promtps
        # otherwise
        # FIXME: provide InstallBackendSimulate()
        if os.getuid() == 0:
            backend = get_install_backend()
            backend.ui = Mock()
            backend.connect("transaction-finished", 
                            self._on_transaction_finished)
            # simulate repos becomes available for the public 20 s later
            GObject.timeout_add_seconds(20, self._add_pw_to_commercial_repo)
            # run it
            backend.add_repo_add_key_and_install_app(deb_line,
                                                     signing_key_id,
                                                     app,
                                                     "icon",
                                                     self.LICENSE_KEY)
            # wait until the pkg is installed
            while not self._finished:
		while Gtk.events_pending():
			Gtk.main_iteration()
		time.sleep(0.1)
        if os.getuid() == 0:
            self.assertTrue(os.path.exists(self.LICENSE_KEY_PATH))
            self.assertEqual(open(self.LICENSE_KEY_PATH).read(), self.LICENSE_KEY)
    def __init__(self, db, distro, icons, cache, datadir):
        super(AppDetailsView, self).__init__(datadir)
        self.db = db
        self.distro = distro
        self.icons = icons
        self.cache = cache
        self.cache.connect("cache-ready", self._on_cache_ready)

        self.datadir = datadir
        self.arch = get_current_arch()
        # atk
        atk_desc = self.get_accessible()
        atk_desc.set_name(_("Description"))
        # aptdaemon
        self.backend = get_install_backend()
        self.backend.connect("transaction-started", self._on_transaction_started)
        self.backend.connect("transaction-stopped", self._on_transaction_stopped)
        self.backend.connect("transaction-progress-changed", self._on_transaction_progress_changed)
        # data
        self.pkg = None
        self.app = None
        self.iconname = ""
        # setup user-agent
        settings = self.get_settings()
        settings.set_property("user-agent", USER_AGENT)
        self.connect("navigation-requested", self._on_navigation_requested)
예제 #7
0
    def __init__(self, db, doc=None, application=None):
        """ Create a new AppDetails object. It can be created from
            a xapian.Document or from a db.application.Application object
        """
        GObject.GObject.__init__(self)
        if not doc and not application:
            raise ValueError("Need either document or application")
        self._db = db
        self._db.connect("reopen", self._on_db_reopen)
        self._cache = self._db._aptcache
        self._distro = get_distro()
        self._history = None
        # import here (intead of global) to avoid dbus dependency
        # in update-software-center (that imports application, but
        # never uses AppDetails) LP: #620011
        from softwarecenter.backend import get_install_backend
        self._backend = get_install_backend()
        # FIXME: why two error states ?
        self._error = None
        self._error_not_found = None
        self._screenshot_list = None

        # load application
        self._app = application
        if doc:
            self._app = Application(self._db.get_appname(doc),
                                    self._db.get_pkgname(doc), "")

        # sustitute for apturl
        if self._app.request:
            self._app.request = self._app.request.replace(
                "$distro", self._distro.get_codename())

        # load pkg cache
        self._pkg = None
        if (self._app.pkgname in self._cache
                and self._cache[self._app.pkgname].candidate):
            self._pkg = self._cache[self._app.pkgname]

        # load xapian document
        self._doc = doc
        if not self._doc:
            try:
                self._doc = self._db.get_xapian_document(
                    self._app.appname, self._app.pkgname)
            except IndexError:
                # if there is no document and no apturl request,
                # set error state
                debfile_matches = re.findall(r'/', self._app.request)
                channel_matches = re.findall(r'channel=[a-z,-]*',
                                             self._app.request)
                section_matches = re.findall(r'section=[a-z]*',
                                             self._app.request)
                if (not self._pkg and not debfile_matches
                        and not channel_matches and not section_matches):
                    self._error = _("Not found")
                    self._error_not_found = utf8(
                        _(u"There isn\u2019t a software package called \u201c%s\u201D in your current software sources."
                          )) % utf8(self.pkgname)
예제 #8
0
    def __init__(self, view_manager, datadir, db, cache, icons):
        Gtk.TreeStore.__init__(self)
        self.set_column_types((
            GObject.TYPE_PYOBJECT,  # COL_ICON
            str,  # COL_NAME
            GObject.TYPE_PYOBJECT,  # COL_ACTION
            GObject.TYPE_PYOBJECT,  # COL_CHANNEL
            str,  # COL_BUBBLE_TEXT
        ))  # must match columns above
        self.view_manager = view_manager
        self.icons = icons
        self.datadir = datadir
        self.backend = get_install_backend()
        self.backend.connect("transactions-changed",
                             self.on_transactions_changed)
        self.backend.connect("transaction-finished",
                             self.on_transaction_finished)
        self.db = db
        self.cache = cache
        self.distro = get_distro()
        # pending transactions
        self._pending = 0
        # setup the normal stuff

        # first, the availablepane items
        available_icon = self._get_icon("softwarecenter")
        self.available_iter = self.append(None, [
            available_icon,
            _("Get Software"), ViewPages.AVAILABLE, None, None
        ])

        # the installedpane items
        icon = self._get_icon("computer")
        self.installed_iter = self.append(
            None,
            [icon,
             _("Installed Software"), ViewPages.INSTALLED, None, None])

        # the channelpane
        self.channel_manager = ChannelsManager(db, icons)
        # do initial channel list update
        self._update_channel_list()

        # the historypane item
        icon = self._get_icon("document-open-recent")
        self.append(None, [icon, _("History"), ViewPages.HISTORY, None, None])
        icon = None
        self.append(None, [
            icon, "<span size='1'> </span>", ViewPages.SEPARATOR_1, None, None
        ])

        # the progress pane is build on demand

        # emit a transactions-changed signal to ensure that we display any
        # pending transactions
        self.backend.emit("transactions-changed",
                          self.backend.pending_transactions)
예제 #9
0
    def __init__(self, view_manager, datadir, db, cache, icons):
        # boring stuff
        self.view_manager = view_manager

        def on_view_changed(widget, view_id):
            self.view_buttons[view_id].set_active(True)

        self.view_manager.connect('view-changed', on_view_changed)
        self.channel_manager = get_channels_manager(db)

        # backend sig handlers ...
        self.backend = get_install_backend()
        self.backend.connect("transactions-changed",
                             self.on_transaction_changed)
        self.backend.connect("transaction-finished",
                             self.on_transaction_finished)
        self.backend.connect("channels-changed", self.on_channels_changed)

        # widgetry
        Gtk.Box.__init__(self)
        self.set_orientation(Gtk.Orientation.HORIZONTAL)

        # Gui stuff
        self.view_buttons = {}
        self.selectors = {}
        self._prev_view = None  # track the previous active section
        self._prev_item = None  # track the previous active menu-item
        self._handlers = []

        # order is important here!
        # first, the availablepane items
        icon = SymbolicIcon("available")
        self.append_section_with_channel_sel(ViewPages.AVAILABLE,
                                             _("All Software"), icon,
                                             self.on_get_available_channels)

        # the installedpane items
        icon = SymbolicIcon("installed")
        self.append_section_with_channel_sel(ViewPages.INSTALLED,
                                             _("Installed"), icon,
                                             self.on_get_installed_channels)

        # the historypane item
        icon = SymbolicIcon("history")
        self.append_section(ViewPages.HISTORY, _("History"), icon)

        # the pendingpane
        icon = PendingSymbolicIcon("pending")
        self.append_section(ViewPages.PENDING, _("Progress"), icon)

        # set sensible atk name
        atk_desc = self.get_accessible()
        atk_desc.set_name(_("Software sources"))
예제 #10
0
 def __init__(self, db):
     self.db = db
     self.distro = get_distro()
     self.backend = get_install_backend()
     self.backend.connect("channels-changed", 
                          self._remove_no_longer_needed_extra_channels)
     # kick off a background check for changes that may have been made
     # in the channels list
     GObject.timeout_add(300, self._check_for_channel_updates_timer)
     # extra channels from e.g. external sources
     self.extra_channels = []
     self._logger = LOG
예제 #11
0
 def __init__(self, db):
     self.db = db
     self.distro = get_distro()
     self.backend = get_install_backend()
     self.backend.connect("channels-changed",
                          self._remove_no_longer_needed_extra_channels)
     # kick off a background check for changes that may have been made
     # in the channels list
     GObject.timeout_add_seconds(10, self._check_for_channel_updates_timer)
     # extra channels from e.g. external sources
     self.extra_channels = []
     self._logger = LOG
예제 #12
0
파일: viewstore.py 프로젝트: cs2c/AppStream
    def __init__(self, view_manager, datadir, db, cache, icons):
        Gtk.TreeStore.__init__(self)
        self.set_column_types((GObject.TYPE_PYOBJECT,  # COL_ICON
                               str,                    # COL_NAME
                               GObject.TYPE_PYOBJECT,  # COL_ACTION
                               GObject.TYPE_PYOBJECT,  # COL_CHANNEL
                               str,                    # COL_BUBBLE_TEXT
                               ))  # must match columns above
        self.view_manager = view_manager
        self.icons = icons
        self.datadir = datadir
        self.backend = get_install_backend()
        self.backend.connect("transactions-changed",
            self.on_transactions_changed)
        self.backend.connect("transaction-finished",
            self.on_transaction_finished)
        self.db = db
        self.cache = cache
        self.distro = get_distro()
        # pending transactions
        self._pending = 0
        # setup the normal stuff

        # first, the availablepane items
        available_icon = self._get_icon("softwarecenter")
        self.available_iter = self.append(None, [available_icon,
            _("Get Software"), ViewPages.AVAILABLE, None, None])

        # the installedpane items
        icon = self._get_icon("computer")
        self.installed_iter = self.append(None, [icon, _("Installed Software"),
            ViewPages.INSTALLED, None, None])

        # the channelpane
        self.channel_manager = ChannelsManager(db, icons)
        # do initial channel list update
        self._update_channel_list()

        # the historypane item
        icon = self._get_icon("document-open-recent")
        self.append(None, [icon, _("History"), ViewPages.HISTORY, None, None])
        icon = None
        self.append(None, [icon, "<span size='1'> </span>",
            ViewPages.SEPARATOR_1, None, None])

        # the progress pane is build on demand

        # emit a transactions-changed signal to ensure that we display any
        # pending transactions
        self.backend.emit("transactions-changed",
            self.backend.pending_transactions)
예제 #13
0
 def __init__(self, db, distro, icons, cache, datadir):
     self.db = db
     self.distro = distro
     self.icons = icons
     self.cache = cache
     self.backend = get_install_backend()
     self.cache.connect("cache-ready", self._on_cache_ready)
     self.datadir = datadir
     self.app = None
     self.appdetails = None
     self.addons_to_install = []
     self.addons_to_remove = []
     # reviews
     self.review_loader = get_review_loader(self.cache, self.db)
예제 #14
0
    def __init__(self, cache, db, distro, icons, datadir, show_ratings=True):

        Gtk.VBox.__init__(self)
        BasePane.__init__(self)

        # other classes we need
        self.enquirer = AppEnquire(cache, db)
        self._query_complete_handler = self.enquirer.connect(
                            "query-complete", self.on_query_complete)

        self.cache = cache
        self.db = db
        self.distro = distro
        self.icons = icons
        self.datadir = datadir
        self.show_ratings = show_ratings
        self.backend = get_install_backend()
        self.nonapps_visible = NonAppVisibility.MAYBE_VISIBLE
        # refreshes can happen out-of-bound so we need to be sure
        # that we only set the new model (when its available) if
        # the refresh_seq_nr of the ready model matches that of the
        # request (e.g. people click on ubuntu channel, get impatient, click
        # on partner channel)
        self.refresh_seq_nr = 0
        # this should be initialized
        self.apps_search_term = ""
        # Create the basic frame for the common view
        self.state = DisplayState()
        vm = get_viewmanager()
        self.searchentry = vm.get_global_searchentry()
        self.back_forward = vm.get_global_backforward()
        # a notebook below
        self.notebook = Gtk.Notebook()
        if not "SOFTWARE_CENTER_DEBUG_TABS" in os.environ:
            self.notebook.set_show_tabs(False)
        self.notebook.set_show_border(False)
        # make a spinner view to display while the applist is loading
        self.spinner_notebook = SpinnerNotebook(self.notebook)
        self.pack_start(self.spinner_notebook, True, True, 0)

        # add a bar at the bottom (hidden by default) for contextual actions
        self.action_bar = ActionBar()
        self.pack_start(self.action_bar, False, True, 0)

        # cursor
        self.busy_cursor = Gdk.Cursor.new(Gdk.CursorType.WATCH)

        # views to be created in init_view
        self.app_view = None
        self.app_details_view = None
예제 #15
0
    def __init__(self, cache, db, distro, icons, datadir, show_ratings=True):

        Gtk.VBox.__init__(self)
        BasePane.__init__(self)

        # other classes we need
        self.enquirer = AppEnquire(cache, db)
        self._query_complete_handler = self.enquirer.connect(
            "query-complete", self.on_query_complete)

        self.cache = cache
        self.db = db
        self.distro = distro
        self.icons = icons
        self.datadir = datadir
        self.show_ratings = show_ratings
        self.backend = get_install_backend()
        self.nonapps_visible = NonAppVisibility.MAYBE_VISIBLE
        # refreshes can happen out-of-bound so we need to be sure
        # that we only set the new model (when its available) if
        # the refresh_seq_nr of the ready model matches that of the
        # request (e.g. people click on ubuntu channel, get impatient, click
        # on partner channel)
        self.refresh_seq_nr = 0
        # this should be initialized
        self.apps_search_term = ""
        # Create the basic frame for the common view
        self.state = DisplayState()
        vm = get_viewmanager()
        self.searchentry = vm.get_global_searchentry()
        self.back_forward = vm.get_global_backforward()
        # a notebook below
        self.notebook = Gtk.Notebook()
        if not SOFTWARE_CENTER_DEBUG_TABS:
            self.notebook.set_show_tabs(False)
        self.notebook.set_show_border(False)
        # make a spinner view to display while the applist is loading
        self.spinner_notebook = SpinnerNotebook(self.notebook)
        self.pack_start(self.spinner_notebook, True, True, 0)

        # add a bar at the bottom (hidden by default) for contextual actions
        self.action_bar = ActionBar()
        self.pack_start(self.action_bar, False, True, 0)

        # cursor
        self.busy_cursor = Gdk.Cursor.new(Gdk.CursorType.WATCH)

        # views to be created in init_view
        self.app_view = None
        self.app_details_view = None
예제 #16
0
 def __init__(self, db, distro, icons, cache, datadir):
     self.db = db
     self.distro = distro
     self.icons = icons
     self.cache = cache
     self.backend = get_install_backend()
     self.cache.connect("cache-ready", self._on_cache_ready)
     self.datadir = datadir
     self.app = None
     self.appdetails = None
     self.addons_to_install = []
     self.addons_to_remove = []
     # reviews
     self.review_loader = get_review_loader(self.cache, self.db)
예제 #17
0
    def __init__(self, icons):
        # icon, status, progress
        Gtk.ListStore.__init__(self)
        self.set_column_types(self.column_types)

        self._transactions_watcher = get_transactions_watcher()
        self._transactions_watcher.connect("lowlevel-transactions-changed",
                                           self._on_lowlevel_transactions_changed)
        # data
        self.icons = icons
        # the apt-daemon stuff
        self.backend = get_install_backend()
        self._signals = []
        # let the pulse helper run
        GObject.timeout_add(500, self._pulse_purchase_helper)
예제 #18
0
 def reinstall_purchased(self):
     """ reinstall a purchased app """
     LOG.debug("reinstall_purchased %s" % self.app)
     appdetails = self.app.get_details(self.db)
     iconname = appdetails.icon
     deb_line = appdetails.deb_line
     license_key = appdetails.license_key
     license_key_path = appdetails.license_key_path
     signing_key_id = appdetails.signing_key_id
     backend = get_install_backend()
     backend.add_repo_add_key_and_install_app(deb_line,
                                              signing_key_id,
                                              self.app,
                                              iconname,
                                              license_key,
                                              license_key_path)
예제 #19
0
 def __init__(self, parent=None):
     super(PkgListModel, self).__init__()
     self._docs = []
     roles = dict(enumerate(PkgListModel.COLUMNS))
     self.setRoleNames(roles)
     self._query = ""
     self._category = ""
     pathname = os.path.join(XAPIAN_BASE_PATH, "xapian")
     self.cache = get_pkg_info()
     self.db = StoreDatabase(pathname, self.cache)
     self.db.open(use_axi=False)
     self.backend = get_install_backend()
     self.backend.connect("transaction-progress-changed", self._on_backend_transaction_progress_changed)
     self.reviews = get_review_loader(self.cache)
     # FIXME: get this from a parent
     self._catparser = CategoriesParser(self.db)
     self._categories = self._catparser.parse_applications_menu("/usr/share/app-install")
 def __init__(self, parent=None):
     super(PkgListModel, self).__init__()
     self._docs = []
     roles = dict(enumerate(PkgListModel.COLUMNS))
     self.setRoleNames(roles)
     self._query = ""
     self._category = ""
     pathname = os.path.join(XAPIAN_BASE_PATH, "xapian")
     self.cache = get_pkg_info()
     self.db = StoreDatabase(pathname, self.cache)
     self.db.open(use_axi=False)
     self.backend = get_install_backend()
     self.backend.connect("transaction-progress-changed",
                          self._on_backend_transaction_progress_changed)
     self.reviews = get_review_loader(self.cache)
     # FIXME: get this from a parent
     self._catparser = CategoriesParser(self.db)
     self._categories = self._catparser.parse_applications_menu(
         '/usr/share/app-install')
예제 #21
0
    def set_channel(self, channel):
        """
        set the current software channel object for display in the channel pane
        and set up the AppViewFilter if required
        """
        self.channel = channel
        # check to see if there is any section info that needs to be applied
        # FIXME
        #~ if channel._channel_color:
            #~ self.section.set_color(channel._channel_color)
        #~ if channel._channel_view_id:
            #~ self.section.set_view_id(channel._channel_view_id)
        #~ self.section_sync()

        # check if the channel needs to added
        if channel.needs_adding and channel._source_entry:
            dialog = Gtk.MessageDialog(flags=Gtk.DialogFlags.MODAL,
                                       type=Gtk.MessageType.QUESTION)
            dialog.set_title("")
            dialog.set_markup("<big><b>%s</b></big>" % _("Add channel"))
            dialog.format_secondary_text(_("The selected channel is not yet "
                "added. Do you want to add it now?"))
            dialog.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
                               Gtk.STOCK_ADD, Gtk.ResponseType.YES)
            res = dialog.run()
            dialog.destroy()
            if res == Gtk.ResponseType.YES:
                channel.needs_adding = False
                backend = get_install_backend()
                backend.add_sources_list_entry(channel._source_entry)
                backend.emit("channels-changed", True)
                backend.reload()
            return
        # normal operation
        self.nonapps_visible = NonAppVisibility.MAYBE_VISIBLE
        self.apps_filter = None
        if self.channel.installed_only:
            if self.apps_filter is None:
                self.apps_filter = AppViewFilter(self.db, self.cache)
            self.apps_filter.set_installed_only(True)
        # switch to applist, this will clear searches too
        self.display_list()
예제 #22
0
 def _process_json(self, json_string):
     try:
         LOG.debug("server returned: '%s'" % json_string)
         res = json.loads(json_string)
         #print res
     except:
         LOG.debug("error processing json: '%s'" % json_string)
         return
     if res["successful"] == False:
         if (res.get("user_canceled", False) or
                 # note the different spelling
                 res.get("user_cancelled", False) or
                 # COMPAT with older clients that do not send the user
                 #        canceled property (LP: #696861), this msg appears
                 #        to be not translated
                 "CANCELLED" in res.get("failures", "")):
             self.emit("purchase-cancelled-by-user")
             self._block_wk_handlers()
             return
         # this is what the agent implements
         elif "failures" in res:
             LOG.error("the server returned a error: '%s'" %
                       res["failures"])
         # show a generic error, the "failures" string we get from the
         # server is way too technical to show, but we do log it
         self.emit("purchase-failed")
         self._block_wk_handlers()
         return
     else:
         self.emit("purchase-succeeded")
         self._block_wk_handlers()
         # gather data from response
         deb_line = res["deb_line"]
         signing_key_id = res["signing_key_id"]
         license_key = res.get("license_key")
         license_key_path = res.get("license_key_path")
         # add repo and key
         backend = get_install_backend()
         backend.add_repo_add_key_and_install_app(deb_line, signing_key_id,
                                                  self.app, self.iconname,
                                                  license_key,
                                                  license_key_path)
예제 #23
0
    def __init__(self, db, cache, icons, icon_size, global_icon_cache):
        AppPropertiesHelper.__init__(self, db, cache, icons, icon_size, global_icon_cache)

        # backend stuff
        self.backend = get_install_backend()
        self.backend.connect("transaction-progress-changed", self._on_transaction_progress_changed)
        self.backend.connect("transaction-started", self._on_transaction_started)
        self.backend.connect("transaction-finished", self._on_transaction_finished)

        # keep track of paths for transactions in progress
        self.transaction_path_map = {}

        # active row path
        self.active_row = None

        self._in_progress = False
        self._break = False

        # other stuff
        self.active = False
예제 #24
0
 def _process_json(self, json_string):
     try:
         LOG.debug("server returned: '%s'" % json_string)
         res = json.loads(json_string)
         #print res
     except:
         LOG.debug("error processing json: '%s'" % json_string)
         return
     if res["successful"] == False:
         if (res.get("user_canceled", False) or
             # note the different spelling
             res.get("user_cancelled", False) or
             # COMPAT with older clients that do not send the user
             #        canceled property (LP: #696861), this msg appears
             #        to be not translated
             "CANCELLED" in res.get("failures", "")):
             self.emit("purchase-cancelled-by-user")
             self._block_wk_handlers()
             return
         # this is what the agent implements
         elif "failures" in res:
             LOG.error("the server returned a error: '%s'" %
                 res["failures"])
         # show a generic error, the "failures" string we get from the
         # server is way too technical to show, but we do log it
         self.emit("purchase-failed")
         self._block_wk_handlers()
         return
     else:
         self.emit("purchase-succeeded")
         self._block_wk_handlers()
         # gather data from response
         deb_line = res["deb_line"]
         signing_key_id = res["signing_key_id"]
         license_key = res.get("license_key")
         license_key_path = res.get("license_key_path")
         # add repo and key
         backend = get_install_backend()
         backend.add_repo_add_key_and_install_app(
             deb_line, signing_key_id, self.app, self.iconname,
             license_key, license_key_path, json.dumps(self._oauth_token))
예제 #25
0
    def __init__(self, db, cache, icons, icon_size, global_icon_cache):
        # the usual suspects
        self.db = db
        self.cache = cache

        # reviews stats loader
        self.review_loader = get_review_loader(cache, db)

        # backend stuff
        self.backend = get_install_backend()
        self.backend.connect("transaction-progress-changed", self._on_transaction_progress_changed)
        self.backend.connect("transaction-started", self._on_transaction_started)
        self.backend.connect("transaction-finished", self._on_transaction_finished)

        # keep track of paths for transactions in progress
        self.transaction_path_map = {}

        # icon jazz
        self.icons = icons
        self.icon_size = icon_size

        if global_icon_cache:
            self.icon_cache = _app_icon_cache
        else:
            self.icon_cache = {}

        # active row path
        self.active_row = None

        # cache the 'missing icon' used in the treeview for apps without an icon
        self._missing_icon = icons.load_icon(Icons.MISSING_APP, icon_size, 0)

        self._in_progress = False
        self._break = False

        # other stuff
        self.active = False
        return
예제 #26
0
    def __init__(self, db, cache, icons, icon_size, global_icon_cache):
        AppPropertiesHelper.__init__(self, db, cache, icons, icon_size,
                                     global_icon_cache)

        # backend stuff
        self.backend = get_install_backend()
        self.backend.connect("transaction-progress-changed",
            self._on_transaction_progress_changed)
        self.backend.connect("transaction-started",
            self._on_transaction_started)
        self.backend.connect("transaction-finished",
            self._on_transaction_finished)

        # keep track of paths for transactions in progress
        self.transaction_path_map = {}

        # active row path
        self.active_row = None

        self._in_progress = False
        self._break = False

        # other stuff
        self.active = False
예제 #27
0
    def __init__(self, app_view, db, icons, show_ratings, store=None):
        Gtk.TreeView.__init__(self)
        self._logger = logging.getLogger("softwarecenter.view.appview")

        self.app_view = app_view
        self.db = db

        self.pressed = False
        self.focal_btn = None
        self._action_block_list = []
        self._needs_collapse = []
        self.expanded_path = None

        #~ # if this hacked mode is available everything will be fast
        #~ # and we can set fixed_height mode and still have growing rows
        #~ # (see upstream gnome #607447)
        try:
            self.set_property("ubuntu-almost-fixed-height-mode", True)
            self.set_fixed_height_mode(True)
        except:
            self._logger.warn("ubuntu-almost-fixed-height-mode extension not available")

        self.set_headers_visible(False)

        # a11y: this is a cell renderer that only displays a icon, but still
        #       has a markup property for orca and friends
        # we use it so that orca and other a11y tools get proper text to read
        # it needs to be the first one, because that is what the tools look
        # at by default
        tr = CellRendererAppView(icons,
                                 self.create_pango_layout(''),
                                 show_ratings,
                                 Icons.INSTALLED_OVERLAY)
        tr.set_pixbuf_width(32)
        tr.set_button_spacing(em(0.3))

        # create buttons and set initial strings
        info = CellButtonRenderer(self,
                                  name=CellButtonIDs.INFO)
        info.set_markup_variants(
                    {self.VARIANT_INFO: _('More Info')})

        action = CellButtonRenderer(self,
                                    name=CellButtonIDs.ACTION)

        action.set_markup_variants(
                {self.VARIANT_INSTALL: _('Install'),
                 self.VARIANT_REMOVE: _('Remove'),
                 self.VARIANT_PURCHASE: _(u'Buy\u2026')})

        tr.button_pack_start(info)
        tr.button_pack_end(action)

        column = Gtk.TreeViewColumn("Applications", tr,
                                    application=AppGenericStore.COL_ROW_DATA)
        column.set_cell_data_func(tr, self._cell_data_func_cb)
        column.set_fixed_width(200)
        column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
        self.append_column(column)

        # network status watcher
        watcher = get_network_watcher()
        watcher.connect("changed", self._on_net_state_changed, tr)

        # custom cursor
        self._cursor_hand = Gdk.Cursor.new(Gdk.CursorType.HAND2)

        self.connect("style-updated", self._on_style_updated, tr)
        # button and motion are "special"
        self.connect("button-press-event", self._on_button_press_event, tr)
        self.connect("button-release-event", self._on_button_release_event, tr)
        self.connect("key-press-event", self._on_key_press_event, tr)
        self.connect("key-release-event", self._on_key_release_event, tr)
        self.connect("motion-notify-event", self._on_motion, tr)
        self.connect("cursor-changed", self._on_cursor_changed, tr)
        # our own "activate" handler
        self.connect("row-activated", self._on_row_activated, tr)

        self.backend = get_install_backend()
        self._transactions_connected = False
        self.connect('realize', self._on_realize, tr)
예제 #28
0
 def test_fake_aptd(self):
     from softwarecenter.backend import get_install_backend
     backend = get_install_backend()
     backend.install("2vcard", "", "")
     self._p()
예제 #29
0
    def __init__(self, cache, db, icons, search_query=None, limit=200,
                 sort=False, filter=None):
        """
        Initalize a AppStore.

        :Parameters:
        - `cache`: apt cache (for stuff like the overlay icon)
        - `db`: a xapian.Database that contians the applications
        - `icons`: a gtk.IconTheme that contains the icons
        - `search_query`: a single search as a xapian.Query or a list
        - `limit`: how many items the search should return (0 == unlimited)
        - `sort`: sort alphabetically after a search
                   (default is to use relevance sort)
        - `filter`: filter functions that can be used to filter the
                    data further. A python function that gets a pkgname
        """
        gtk.GenericTreeModel.__init__(self)
        self.search_query = search_query
        self.cache = cache
        self.db = db
        self.icons = icons
        # invalidate the cache on icon theme changes
        self.icons.connect("changed", lambda theme: _app_icon_cache.clear())
        self._appicon_missing_icon = self.icons.load_icon(MISSING_APP_ICON, self.ICON_SIZE, 0)
        self.apps = []
        # this is used to re-set the cursor
        self.app_index_map = {}
        # this is used to find the in-progress rows
        self.pkgname_index_map = {}
        self.sorted = sort
        self.filter = filter
        self.active = True
        self.backend = get_install_backend()
        self.backend.connect("transaction-progress-changed", self._on_transaction_progress_changed)
        # rowref of the active app and last active app
        self.active_app = None
        self._prev_active_app = 0
        self._searches_sort_mode = self._get_searches_sort_mode()
        # FIXME: do the sorting/adding in a seperate thread?
        if not search_query:
            # limit to applications
            for m in db.xapiandb.postlist("ATapplication"):
                doc = db.xapiandb.get_document(m.docid)
                if filter and self.is_filtered_out(filter, doc):
                    continue
                appname = doc.get_value(XAPIAN_VALUE_APPNAME)
                pkgname = db.get_pkgname(doc)
                popcon = db.get_popcon(doc)
                self.apps.append(Application(appname, pkgname, popcon))
                # keep the UI going
                while gtk.events_pending():
                    gtk.main_iteration()
            self.apps.sort()
            for (i, app) in enumerate(self.apps):
                self.app_index_map[app] = i
        else:
            # we support single and list search_queries,
            # if list we append them one by one
            if isinstance(search_query, xapian.Query):
                search_query = [search_query]
            already_added = set()
            for q in search_query:
                logging.debug("using query: '%s'" % q)
                enquire = xapian.Enquire(db.xapiandb)
                enquire.set_query(q)
                # set search order mode
                if self._searches_sort_mode == self.SEARCHES_SORTED_BY_POPCON:
                    enquire.set_sort_by_value_then_relevance(XAPIAN_VALUE_POPCON)
                elif self._searches_sort_mode == self.SEARCHES_SORTED_BY_ALPHABETIC:
                    self.sorted=sort=True
                if limit == 0:
                    matches = enquire.get_mset(0, len(db))
                else:
                    matches = enquire.get_mset(0, limit)
                logging.debug("found ~%i matches" % matches.get_matches_estimated())
                app_index = 0
                for m in matches:
                    doc = m.document
                    if "APPVIEW_DEBUG_TERMS" in os.environ:
                        print doc.get_value(XAPIAN_VALUE_APPNAME)
                        for t in doc.termlist():
                            print "'%s': %s (%s); " % (t.term, t.wdf, t.termfreq),
                        print "\n"
                    appname = doc.get_value(XAPIAN_VALUE_APPNAME)
                    pkgname = db.get_pkgname(doc)
                    if filter and self.is_filtered_out(filter, doc):
                        continue
                    # when doing multiple queries we need to ensure
                    # we don't add duplicates
                    popcon = db.get_popcon(doc)
                    app = Application(appname, pkgname, popcon)
                    if not app in already_added:
                        self.apps.append(app)
                        already_added.add(app)
                        if not sort:
                            self.app_index_map[app] = app_index
                            app_index = app_index + 1
                    # keep the UI going
                    while gtk.events_pending():
                        gtk.main_iteration()
            if sort:
                self.apps.sort()
                for (i, app) in enumerate(self.apps):
                    self.app_index_map[app] = i
            # build the pkgname map
            for (i, app) in enumerate(self.apps):
                if not app.pkgname in self.pkgname_index_map:
                    self.pkgname_index_map[app.pkgname] = []
                self.pkgname_index_map[app.pkgname].append(i)
예제 #30
0
    def __init__(self, show_ratings, store=None):
        gtk.TreeView.__init__(self)
        self.buttons = {}
        self.focal_btn = None

        # if this hacked mode is available everything will be fast
        # and we can set fixed_height mode and still have growing rows
        # (see upstream gnome #607447)
        try:
            self.set_property("ubuntu-almost-fixed-height-mode", True)
            self.set_fixed_height_mode(True)
        except:
            logging.warn("ubuntu-almost-fixed-height-mode extension not available")

        self.set_headers_visible(False)

        # a11y: this is a fake cell renderer with a zero size
        # we use it so that orca and other a11y tools get proper text to read
        # it needs to be the first one, because that is what the tools look
        # at by default
        tt = gtk.CellRendererText()
        column = gtk.TreeViewColumn("Name", tt, text=AppStore.COL_TEXT)
        column.set_fixed_width(1)
        column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
        self.append_column(column)

        # the columns that are actually visible
        tp = CellRendererPixbufWithOverlay("software-center-installed")
        tp.set_property('ypad', 2)

        column = gtk.TreeViewColumn("Icon", tp,
                                    pixbuf=AppStore.COL_ICON,
                                    overlay=AppStore.COL_INSTALLED)
        column.set_fixed_width(32)
        column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
        self.append_column(column)

        tr = CellRendererAppView(show_ratings)
        tr.set_property('xpad', 3)
        tr.set_property('ypad', 2)

        column = gtk.TreeViewColumn("Apps", tr, 
                                    markup=AppStore.COL_MARKUP,
                                    rating=AppStore.COL_POPCON,
                                    isactive=AppStore.COL_IS_ACTIVE,
                                    installed=AppStore.COL_INSTALLED, 
                                    available=AppStore.COL_AVAILABLE,
                                    action_in_progress=AppStore.COL_ACTION_IN_PROGRESS)
        column.set_fixed_width(200)
        column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
        self.append_column(column)

        if store is None:
            store = gtk.ListStore(str, gtk.gdk.Pixbuf)
        self.set_model(store)

        # custom cursor
        self._cursor_hand = gtk.gdk.Cursor(gtk.gdk.HAND2)
        # our own "activate" handler
        self.connect("row-activated", self._on_row_activated)

        # button and motion are "special"
        self.connect("style-set", self._on_style_set, tr)
        self.connect("button-press-event", self._on_button_press_event, column)
        self.connect("cursor-changed", self._on_cursor_changed)
        self.connect("motion-notify-event", self._on_motion, tr, column)

        self.backend = get_install_backend()
        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)
예제 #31
0
    def test_fake_aptd(self):
        from softwarecenter.backend import get_install_backend

        backend = get_install_backend()
        backend.install(Application("2vcard", ""), iconname="")
        self._p()
예제 #32
0
        res = "ok"
        res = error(parent=parent,
                    primary=primary,
                    secondary=secondary,
                    details=details,
                    alternative_action=alternative_action)
        if res == Gtk.ResponseType.YES:
            res = "yes"
        return res

if __name__ == "__main__":
    from softwarecenter.backend import get_install_backend
    from softwarecenter.ui.gtk3.aptd_gtk3 import InstallBackendUI
    from mock import Mock

    aptd = get_install_backend()
    aptd.ui = InstallBackendUI()
    # test config file prompt
    trans = Mock()
    res = aptd._config_file_conflict(trans, "/etc/group", "/etc/group-")
    print (res)

    # test medium required
    trans = Mock()
    res = aptd._medium_required(trans, "medium", "drive")
    print (res)

    # test error dialog
    trans = Mock()
    trans.error_code = 102
    trans.error_details = "details"
예제 #33
0
    def __init__(self, app_view, db, icons, show_ratings, store=None):
        Gtk.TreeView.__init__(self)
        self._logger = logging.getLogger("softwarecenter.view.appview")

        self.app_view = app_view
        self.db = db

        self.pressed = False
        self.focal_btn = None
        self._action_block_list = []
        self._needs_collapse = []
        self.expanded_path = None
        self.selected_row_renderer = None

        # pixbuf for the icon that is displayed in the selected row
        self.selected_row_icon = None

        #~ # if this hacked mode is available everything will be fast
        #~ # and we can set fixed_height mode and still have growing rows
        #~ # (see upstream gnome #607447)
        try:
            self.set_property("ubuntu-almost-fixed-height-mode", True)
            self.set_fixed_height_mode(True)
        except:
            self._logger.warn(
                "ubuntu-almost-fixed-height-mode extension not available")

        self.set_headers_visible(False)

        # our custom renderer
        self._renderer = CellRendererAppView(icons,
                                             self.create_pango_layout(''),
                                             show_ratings,
                                             Icons.INSTALLED_OVERLAY)
        self._renderer.set_pixbuf_width(32)
        self._renderer.set_button_spacing(em(0.3))

        # create buttons and set initial strings
        info = CellButtonRenderer(self, name=CellButtonIDs.INFO)
        info.set_markup_variants({self.VARIANT_INFO: _('More Info')})

        action = CellButtonRenderer(self, name=CellButtonIDs.ACTION)

        action.set_markup_variants({
            self.VARIANT_INSTALL: _('Install'),
            self.VARIANT_REMOVE: _('Remove'),
            self.VARIANT_PURCHASE: _(u'Buy\u2026')
        })

        self._renderer.button_pack_start(info)
        self._renderer.button_pack_end(action)

        self._column = Gtk.TreeViewColumn(
            "Applications",
            self._renderer,
            application=AppGenericStore.COL_ROW_DATA)
        self._column.set_cell_data_func(self._renderer,
                                        self._cell_data_func_cb)
        self._column.set_fixed_width(200)
        self._column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
        self.append_column(self._column)

        # network status watcher
        watcher = get_network_watcher()
        watcher.connect("changed", self._on_net_state_changed, self._renderer)

        # custom cursor
        self._cursor_hand = Gdk.Cursor.new(Gdk.CursorType.HAND2)

        self.connect("style-updated", self._on_style_updated, self._renderer)
        # button and motion are "special"
        self.connect("button-press-event", self._on_button_press_event,
                     self._renderer)
        self.connect("button-release-event", self._on_button_release_event,
                     self._renderer)
        self.connect("key-press-event", self._on_key_press_event,
                     self._renderer)
        self.connect("key-release-event", self._on_key_release_event,
                     self._renderer)
        self.connect("motion-notify-event", self._on_motion, self._renderer)
        self.connect("cursor-changed", self._on_cursor_changed, self._renderer)
        # our own "activate" handler
        self.connect("row-activated", self._on_row_activated, self._renderer)

        self.backend = get_install_backend()
        self._transactions_connected = False
        self.connect('realize', self._on_realize, self._renderer)
예제 #34
0
 def test_fake_aptd(self):
     from softwarecenter.backend import get_install_backend
     backend = get_install_backend()
     backend.install("2vcard", "", "")
     self._p()
예제 #35
0
    def __init__(self, helper, doc, icon_size=48):
        TileButton.__init__(self)
        self._pressed = False

        label = helper.get_appname(doc)
        icon = helper.get_icon_at_size(doc, icon_size, icon_size)
        stats = helper.get_review_stats(doc)
        doc.installed = doc.available = None
        self.is_installed = helper.is_installed(doc)
        self._overlay = helper.icons.load_icon(Icons.INSTALLED_OVERLAY,
                                               self.INSTALLED_OVERLAY_SIZE,
                                               0) # flags

        self.box.set_orientation(Gtk.Orientation.HORIZONTAL)
        self.box.set_spacing(StockEms.SMALL)

        self.content_left = Gtk.Box.new(Gtk.Orientation.VERTICAL, StockEms.MEDIUM)
        self.content_right = Gtk.Box.new(Gtk.Orientation.VERTICAL, 1)
        self.box.pack_start(self.content_left, False, False, 0)
        self.box.pack_start(self.content_right, False, False, 0)
        self.image = _parse_icon(icon, icon_size)
        self.content_left.pack_start(self.image, False, False, 0)

        self.title = Gtk.Label.new(self._MARKUP % GObject.markup_escape_text(label))
        self.title.set_alignment(0.0, 0.5)
        self.title.set_use_markup(True)
        self.title.set_ellipsize(Pango.EllipsizeMode.END)
        self.content_right.pack_start(self.title, False, False, 0)

        categories = helper.get_categories(doc)
        if categories is not None:
            self.category = Gtk.Label.new('<span font_desc="%i">%s</span>' % (em(0.6), GObject.markup_escape_text(categories)))
            self.category.set_use_markup(True)
            self.category.set_alignment(0.0, 0.5)
            self.category.set_ellipsize(Pango.EllipsizeMode.END)
            self.content_right.pack_start(self.category, False, False, 4)

        stats_a11y = None
        if stats is not None:
            self.stars = Star(size=StarSize.SMALL)
            self.stars.render_outline = True
            self.stars.set_rating(stats.ratings_average)
            self.rating_box = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, StockEms.SMALL)
            self.rating_box.pack_start(self.stars, False, False, 0)
            self.n_ratings = Gtk.Label.new(
                '<span font_desc="%i"> (%i)</span>' %  (
                    em(0.45), stats.ratings_total))
            self.n_ratings.set_use_markup(True)
            self.n_ratings.set_name("subtle-label")
            self.n_ratings.set_alignment(0.0, 0.5)
            self.rating_box.pack_start(self.n_ratings, False, False, 0)
            self.content_right.pack_start(self.rating_box, False, False, 0)
            # TRANSLATORS: this is an accessibility description for eg orca and
            # is not visible in the ui
            stats_a11y = _('%(stars)d stars - %(reviews)d reviews') % {
                'stars': stats.ratings_average, 'reviews': stats.ratings_total}
        
            #work out width tile needs to be to ensure ratings text is all visible
            req_width = (self.stars.size_request().width +
                         self.image.size_request().width +
                         self.n_ratings.size_request().width +
                         StockEms.MEDIUM * 3
                         )
            global _global_featured_tile_width
            _global_featured_tile_width = max(_global_featured_tile_width,
                                              req_width)

        details = AppDetails(db=helper.db, doc=doc)
        price = details.price or _("Free")
        if price == '0.00':
            price = _("Free")
        if price != _("Free"):
            price = 'US$ ' + price
        self.price = Gtk.Label.new(
            '<span font_desc="%i">%s</span>' % (em(0.6), price))
        self.price.set_use_markup(True)
        self.price.set_name("subtle-label")
        self.price.set_alignment(0.0, 0.5)
        self.content_right.pack_start(self.price, False, False, 0)

        self.set_name("featured-tile")

        a11y_name = '. '.join([t for t in [label, categories, stats_a11y, price] if t])    
        self.get_accessible().set_name(a11y_name)

        backend = get_install_backend()
        backend.connect("transaction-finished",
                        self.on_transaction_finished,
                        helper, doc)

        self.connect("enter-notify-event", self.on_enter)
        self.connect("leave-notify-event", self.on_leave)
        self.connect("button-press-event", self.on_press)
        self.connect("button-release-event", self.on_release)
        return
예제 #36
0
    def __init__(self, helper, doc, icon_size=48):
        TileButton.__init__(self)
        self._pressed = False

        label = helper.get_appname(doc)
        icon = helper.get_icon_at_size(doc, icon_size, icon_size)
        stats = helper.get_review_stats(doc)
        helper.update_availability(doc)
        helper.connect("needs-refresh", self._on_needs_refresh, doc, icon_size)
        self.is_installed = helper.is_installed(doc)
        self._overlay = helper.icons.load_icon(Icons.INSTALLED_OVERLAY,
                                               self.INSTALLED_OVERLAY_SIZE,
                                               0)  # flags

        self.box.set_orientation(Gtk.Orientation.HORIZONTAL)
        self.box.set_spacing(StockEms.SMALL)

        self.content_left = Gtk.Box.new(Gtk.Orientation.VERTICAL,
                                        StockEms.MEDIUM)
        self.content_right = Gtk.Box.new(Gtk.Orientation.VERTICAL, 1)
        self.box.pack_start(self.content_left, False, False, 0)
        self.box.pack_start(self.content_right, False, False, 0)
        self.image = Gtk.Image()
        _update_icon(self.image, icon, icon_size)
        self.content_left.pack_start(self.image, False, False, 0)

        self.title = Gtk.Label.new(self._MARKUP %
                                   GObject.markup_escape_text(label))
        self.title.set_alignment(0.0, 0.5)
        self.title.set_use_markup(True)
        self.title.set_tooltip_text(label)
        self.title.set_ellipsize(Pango.EllipsizeMode.END)
        self.content_right.pack_start(self.title, False, False, 0)

        categories = helper.get_categories(doc)
        if categories is not None:
            self.category = Gtk.Label.new(
                '<span font_desc="%i">%s</span>' %
                (em(0.6), GObject.markup_escape_text(categories)))
            self.category.set_use_markup(True)
            self.category.set_alignment(0.0, 0.5)
            self.category.set_ellipsize(Pango.EllipsizeMode.END)
            self.content_right.pack_start(self.category, False, False, 4)

        stats_a11y = None
        if stats is not None:
            self.stars = Star(size=StarSize.SMALL)
            self.stars.render_outline = True
            self.stars.set_rating(stats.ratings_average)
            self.rating_box = Gtk.Box.new(Gtk.Orientation.HORIZONTAL,
                                          StockEms.SMALL)
            self.rating_box.pack_start(self.stars, False, False, 0)
            self.n_ratings = Gtk.Label.new(
                '<span font_desc="%i"> (%i)</span>' %
                (em(0.45), stats.ratings_total))
            self.n_ratings.set_use_markup(True)
            self.n_ratings.set_name("subtle-label")
            self.n_ratings.set_alignment(0.0, 0.5)
            self.rating_box.pack_start(self.n_ratings, False, False, 0)
            self.content_right.pack_start(self.rating_box, False, False, 0)
            # TRANSLATORS: this is an accessibility description for eg orca and
            # is not visible in the ui
            stats_a11y = _('%(stars)d stars - %(reviews)d reviews') % {
                'stars': stats.ratings_average,
                'reviews': stats.ratings_total
            }

            # work out width tile needs to be to ensure ratings text is all
            # visible
            req_width = (self.stars.size_request().width +
                         self.image.size_request().width +
                         self.n_ratings.size_request().width +
                         StockEms.MEDIUM * 3)
            global _global_featured_tile_width
            _global_featured_tile_width = max(_global_featured_tile_width,
                                              req_width)

        details = AppDetails(db=helper.db, doc=doc)
        # TRANSLATORS: Free here means Gratis
        price = details.price or _("Free")
        if price == '0.00':
            # TRANSLATORS: Free here means Gratis
            price = _("Free")
        # TRANSLATORS: Free here means Gratis
        if price != _("Free"):
            price = 'US$ ' + price
        self.price = Gtk.Label.new('<span font_desc="%i">%s</span>' %
                                   (em(0.6), price))
        self.price.set_use_markup(True)
        self.price.set_name("subtle-label")
        self.price.set_alignment(0.0, 0.5)
        self.content_right.pack_start(self.price, False, False, 0)

        self.set_name("featured-tile")

        a11y_name = '. '.join(
            [t for t in [label, categories, stats_a11y, price] if t])
        self.get_accessible().set_name(a11y_name)

        backend = get_install_backend()
        backend.connect("transaction-finished", self.on_transaction_finished,
                        helper, doc)

        self.connect("enter-notify-event", self.on_enter)
        self.connect("leave-notify-event", self.on_leave)
        self.connect("button-press-event", self.on_press)
        self.connect("button-release-event", self.on_release)
 def test_fake_aptd(self):
     from softwarecenter.backend import get_install_backend
     backend = get_install_backend()
     backend.install(Application("2vcard", ""), iconname="")
     self._p()
        res = error(parent=parent,
                    primary=primary,
                    secondary=secondary,
                    details=details,
                    alternative_action=alternative_action)
        if res == Gtk.ResponseType.YES:
            res = "yes"
        return res


if __name__ == "__main__":
    from softwarecenter.backend import get_install_backend
    from softwarecenter.ui.gtk3.aptd_gtk3 import InstallBackendUI
    from mock import Mock

    aptd = get_install_backend()
    aptd.ui = InstallBackendUI()
    # test config file prompt
    trans = Mock()
    res = aptd._config_file_conflict(trans, "/etc/group", "/etc/group-")
    print(res)

    # test medium required
    trans = Mock()
    res = aptd._medium_required(trans, "medium", "drive")
    print(res)

    # test error dialog
    trans = Mock()
    trans.error_code = 102
    trans.error_details = "details"