home *** CD-ROM | disk | FTP | other *** search
Wrap
# Source Generated with Decompyle++ # File: in.pyo (Python 2.4) import pygtk pygtk.require('2.0') import gtk import gtk.glade as gtk import gtk.gdk as gtk import gobject import gconf import pango import gettext from gettext import gettext as _ app = 'gnome-app-install' gettext.textdomain(app) gettext.bindtextdomain(app) gtk.glade.textdomain(app) gtk.glade.bindtextdomain(app) import stat import glob import re import subprocess import tempfile import warnings import os import sys from datetime import datetime import dbus import dbus.service as dbus import dbus.glib as dbus from warnings import warn warnings.filterwarnings('ignore', 'ICON:.*', UserWarning) warnings.filterwarnings('ignore', 'apt API not stable yet', FutureWarning) import apt import apt_pkg from UpdateManager.Common.aptsources import SourcesList, is_mirror from DialogNewlyInstalled import DialogNewlyInstalled from DialogPendingChanges import DialogPendingChanges from DialogMultipleApps import DialogMultipleApps from DialogUnavailable import DialogUnavailable from DialogProprietary import DialogProprietary from PackageWorker import PackageWorker from Menu import ApplicationMenu from ReleaseNotesViewer import ReleaseNotesViewer from SimpleGladeApp import SimpleGladeApp from Progress import GtkOpProgressWindow from Util import * import common desktop_environment_mapping = { ('kdelibs4c2a', 'python-kde3'): (_('%s integrates well into the Kubuntu desktop'), 'application-kubuntu'), ('libgnome2-0', 'python-gnome2'): (_('%s integrates well into the Ubuntu desktop'), 'application-ubuntu'), 'libgnustep-base1.11': (_('%s integrates well into the Gnustep desktop'), None), ('libxfce4util4',): (_('%s integrates well into the Xubuntu desktop'), None) } from Menu import SHOW_ALL, SHOW_ALL_SUPPORTED, SHOW_ALL_FREE, SHOW_ONLY_MAIN, SHOW_ONLY_PROPRIETARY, SHOW_ONLY_THIRD_PARTY class AppInstallDbusControler(dbus.service.Object): ''' this is a helper to provide the AppInstallIFace ''' def __init__(self, parent, bus_name, object_path = '/org/freedesktop/AppInstallObject'): dbus.service.Object.__init__(self, bus_name, object_path) self.parent = parent def bringToFront(self): self.parent.window_main.present() return True bringToFront = dbus.service.method('org.freedesktop.AppInstallIFace')(bringToFront) class AppInstall(SimpleGladeApp): def __init__(self, datadir, desktopdir, arguments = None, mime_search = None): self.setupDbus() self.search_timeout_id = 0 self.icons = common.ToughIconTheme() gtk.window_set_default_icon(self.icons.load_icon('gnome-app-install', 32, 0)) SimpleGladeApp.__init__(self, domain = 'gnome-app-install', path = datadir + '/gnome-app-install.glade') self.channelsdir = desktopdir + '/channels' self.datadir = datadir self.desktopdir = desktopdir self.button_apply.set_sensitive(False) self.setupTreeview() self.sort_by_ranking = False self.config = gconf.client_get_default() self.config.add_dir('/apps/gnome-app-install', gconf.CLIENT_PRELOAD_NONE) self.tooltips = gtk.Tooltips() self.tipmap = { } filter_to_restore = self.config.get_int('/apps/gnome-app-install/filter_applications') if filter_to_restore not in range(5): filter_to_restore = 0 list_filters = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_BOOLEAN, gobject.TYPE_STRING, gobject.TYPE_INT) self.combobox_filter.set_model(list_filters) filter_renderer = gtk.CellRendererText() self.combobox_filter.pack_start(filter_renderer) for desc, sep, tooltip, filter in [ (_('All Open Source applications'), False, _('Show only applications which can be freely used, modified and distributed. This includes the main as well as the community maintained applications'), SHOW_ALL_FREE), (_('All supported applications'), False, _('Show all applications (including commercial) that are supported by Canonical Ltd or third party vendors. '), SHOW_ALL_SUPPORTED), (_('All available applications'), False, _('Show all available applications including unsupported, restricted and third party applications'), SHOW_ALL), ('separator', True, 'separator', -1), (_('Only main applications'), False, _('Show only the main applications which are officially supported by Canonical Ltd.'), SHOW_ONLY_MAIN), (_('Only restricted applications'), False, _('Show only applications which are restricted in use or distribution by copyright or by legal issues in some countries'), SHOW_ONLY_PROPRIETARY), (_('Only third party applications'), False, _('Show only applications which are provided and supported by third party vendors'), SHOW_ONLY_THIRD_PARTY)]: list_filters.append((desc, sep, tooltip, filter)) self.combobox_filter.set_row_separator_func(self.separator_filter) self.combobox_filter.set_cell_data_func(filter_renderer, self.tooltip_on_filter) if filter == filter_to_restore: self.combobox_filter.set_active(len(list_filters) - 1) self.tooltips.set_tip(self.eventbox_filter, tooltip) continue self.combobox_filter.connect('changed', self.on_combobox_filter_changed) self.textview_description = ReleaseNotesViewer() self.textview_description.set_wrap_mode(gtk.WRAP_WORD) self.textview_description.set_pixels_below_lines(3) self.textview_description.set_right_margin(6) self.textview_description.set_left_margin(6) self.scrolled_description.add(self.textview_description) self.scrolled_description.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) atk_desc = self.textview_description.get_accessible() atk_desc.set_name(_('Description')) if mime_search: self.label_progress.set_markup('<big><b>%s</b></big>\n\n%s' % (_('Searching for appropriate applications'), _('Please wait. This might take a minute or two.'))) else: self.window_main.show() self.updateCache(filter_to_restore) self.search_entry.grab_focus() self.show_intro() self.textview_description.show() self.multiple_pkgs_seen = set() if mime_search: self.window_main.show() self.menu.mimeSearch = mime_search self.scrolledwindow_left.hide() self.search_entry.set_text(mime_search.string) self.on_search_timeout() self.packageWorker = PackageWorker() self.last_toggle = None time_cache = 0 for f in glob.glob('/var/lib/apt/lists/*Packages'): mt = os.stat(f)[stat.ST_MTIME] ct = os.stat(f)[stat.ST_CTIME] if mt > time_cache: time_cache = mt if ct > time_cache: time_cache = ct continue time_source = os.stat('/etc/apt/sources.list')[stat.ST_MTIME] for f in glob.glob('/etc/apt/sources.list.d/*.list'): mt = os.stat(f)[stat.ST_MTIME] ct = os.stat(f)[stat.ST_CTIME] if mt > time_source: time_source = mt if ct > time_source: time_source = ct continue if time_cache < time_source: self.dialog_cache_outdated.set_transient_for(self.window_main) self.dialog_cache_outdated.realize() self.dialog_cache_outdated.window.set_functions(gtk.gdk.FUNC_MOVE) res = self.dialog_cache_outdated.run() self.dialog_cache_outdated.hide() if res == gtk.RESPONSE_YES: self.reloadSources() def separator_filter(self, model, iter, user_data = None): '''Used to draw a spearator in the combobox for the filters''' return model.get_value(iter, 1) def setupDbus(self): ''' this sets up a dbus listener if none is installed alread ''' try: bus = dbus.SessionBus() except: print 'warning: could not initiate dbus' return None proxy_obj = bus.get_object('org.freedesktop.AppInstall', '/org/freedesktop/AppInstallObject') iface = dbus.Interface(proxy_obj, 'org.freedesktop.AppInstallIFace') try: iface.bringToFront() sys.exit(0) except dbus.DBusException: e = None print 'no listening object (%s) ' % e bus_name = dbus.service.BusName('org.freedesktop.AppInstall', bus) self.dbusControler = AppInstallDbusControler(self, bus_name) def setBusy(self, flag): ''' Show a watch cursor if the app is busy for more than 0.3 sec. Furthermore provide a loop to handle user interface events ''' if self.window_main.window is None: return None if flag == True: self.window_main.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH)) else: self.window_main.window.set_cursor(None) while gtk.events_pending(): gtk.main_iteration() def on_combobox_filter_changed(self, combobox): '''The filter for the application list was changed''' self.setBusy(True) active = combobox.get_active() model = combobox.get_model() iter = model.get_iter(active) filter = model.get_value(iter, 3) if filter in range(6): self.config.set_int('/apps/gnome-app-install/filter_applications', filter) self.menu.filter = filter self.menu._refilter() if len(self.menu.treeview_packages.get_model()) == 0: self.show_no_results_msg() else: self.menu.treeview_packages.set_cursor(0) tooltip = model.get_value(iter, 2) self.tooltips.set_tip(self.eventbox_filter, tooltip) self.setBusy(False) def on_window_main_key_press_event(self, widget, event): GDK_q = 113 if event.state & gtk.gdk.CONTROL_MASK and event.keyval == GDK_q: self.on_window_main_delete_event(self.window_main, None) def error_not_available(self, item): '''Show an error message that the application cannot be installed''' header = _('%s cannot be installed on your computer type (%s)') % (item.name, self.cache.getArch()) msg = _('Either the application requires special hardware features or the vendor decided to not support your computer type.') d = gtk.MessageDialog(parent = self.window_main, flags = gtk.DIALOG_MODAL, type = gtk.MESSAGE_ERROR, buttons = gtk.BUTTONS_CLOSE) d.set_title('') d.set_markup('<big><b>%s</b></big>\n\n%s' % (header, msg)) d.realize() d.window.set_functions(gtk.gdk.FUNC_MOVE) d.run() d.destroy() def tooltip_on_filter(self, cell_view, cell_renderer, model, iter): ''' Show a disclaimer in the tooltips of the filters ''' id = model.get_path(iter)[0] item_text = model.get_value(iter, 0) item_disclaimer = model.get_value(iter, 2) cell_renderer.set_property('text', item_text) cell_parent = cell_view.get_parent() if isinstance(cell_parent, gtk.MenuItem): if cell_parent not in self.tipmap or self.tipmap[cell_parent] != item_disclaimer: self.tipmap[cell_parent] = item_disclaimer self.tooltips.set_tip(cell_parent, item_disclaimer) def on_install_toggle(self, renderer, path): model = self.treeview_packages.get_model() (name, item, popcon) = model[path] pkg = item.pkgname if not self.cache.has_key(pkg) and self.cache[pkg].candidateDownloadable: for it in self.cache._cache.FileList: if it.Component != '' and it.Component == item.component: self.error_not_available(item) return False continue self.saveState() if self.addChannel(item): self.last_toggle = name self.restoreState() return None if self.cache[pkg].isInstalled: self.cache[pkg].markDelete(autoFix = False) if self.cache._depcache.BrokenCount > 0: d = gtk.MessageDialog(parent = self.window_main, flags = gtk.DIALOG_MODAL, type = gtk.MESSAGE_ERROR, buttons = gtk.BUTTONS_CLOSE) d.set_title('') d.set_markup('<big><b>%s</b></big>\n\n%s' % (_("Cannot remove '%s'") % pkg, _("One or more applications depend on '%s'. To remove '%s' and the dependent applications, please switch to the advanced software manager.") % (pkg, pkg))) d.realize() d.window.set_functions(gtk.gdk.FUNC_MOVE) d.run() d.destroy() self.cache.clean() return None self.cache[pkg].markKeep() else: apt_error = False try: self.cache[pkg].markInstall(autoFix = True) except SystemError: apt_error = True if self.cache._depcache.BrokenCount > 0 and self.cache._depcache.DelCount > 0 or apt_error: d = gtk.MessageDialog(parent = self.window_main, flags = gtk.DIALOG_MODAL, type = gtk.MESSAGE_ERROR, buttons = gtk.BUTTONS_CLOSE) d.set_title('') d.set_markup('<big><b>%s</b></big>\n\n%s' % (_("Cannot install '%s'") % pkg, _("This application conflicts with other installed software. To install '%s' the conflicting software must be removed before.\n\nSwitch to the advanced mode to resolve this conflict.") % pkg)) d.realize() d.window.set_functions(gtk.gdk.FUNC_MOVE) d.run() d.destroy() self.cache.clean() return None item.toInstall = not (item.toInstall) if len(self.menu.pkg_to_app[item.pkgname]) > 1: apps = self.menu.pkg_to_app[item.pkgname] for app in apps: app.toInstall = item.toInstall self.treeview_packages.queue_draw() if item.pkgname not in self.multiple_pkgs_seen: dia = DialogMultipleApps(self.datadir, self.window_main, apps, item.name) dia.run() dia.hide() self.multiple_pkgs_seen.add(item.pkgname) self.button_apply.set_sensitive(self.menu.isChanged()) def addChannel(self, item): '''Ask for confirmation to add the missing channel or component of the current selected application''' if item.thirdparty and item.channel: dia = DialogProprietary(self.datadir, self.window_main, item) else: dia = DialogUnavailable(self.datadir, self.window_main, item) res = dia.run() dia.hide() if res != gtk.RESPONSE_OK: return False if item.component: self.enableComponent(item.component) if item.component == 'multiverse': for it in self.cache._cache.FileList: if it.Component != '' and it.Component == 'universe': break continue elif item.channel: self.enableChannel(item.channel) else: print 'ERROR: addChannel() called without channel or component' return False self.reloadSources() return True def setupTreeview(self): def popcon_view_func(cell_layout, renderer, model, iter, self): ''' Create a pixmap showing a row of stars representing the popularity of the corresponding application ''' (name, item, popcon) = model[iter] rank = int(5 * item.popcon / self.menu.popcon_max) pix_rating = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, 96, 16) pix_rating.fill(0) for i in range(5): if not i > rank: self.pixbuf_star.copy_area(0, 0, 16, 16, pix_rating, 20 * i, 0) continue renderer.set_property('pixbuf', pix_rating) def package_view_func(cell_layout, renderer, model, iter): app = model.get_value(iter, COL_ITEM) name = app.name desc = app.description current = app.isInstalled future = app.toInstall available = app.available if current != future: markup = '<b>%s</b>\n<small><b>%s</b></small>' % (name, desc) else: markup = '%s\n<small>%s</small>' % (name, desc) renderer.set_property('markup', markup) def toggle_cell_func(column, cell, model, iter): menuitem = model.get_value(iter, COL_ITEM) cell.set_property('active', menuitem.toInstall) cell.set_property('visible', True) if menuitem.architectures and self.cache.getArch() not in menuitem.architectures: cell.set_property('activatable', False) else: cell.set_property('activatable', True) def icon_cell_func(column, cell, model, iter): (menuitem,) = model.get(iter, COL_ITEM) if menuitem == None or menuitem.iconname == None: cell.set_property('pixbuf', None) cell.set_property('visible', False) return None icon = menuitem.icontheme._getIcon(menuitem.iconname, 24) cell.set_property('pixbuf', icon) cell.set_property('visible', True) column = gtk.TreeViewColumn(_('Application')) column.set_expand(True) column.set_sort_column_id(COL_NAME) column.set_resizable(True) column.set_sizing(gtk.TREE_VIEW_COLUMN_GROW_ONLY) check_column = gtk.TreeViewColumn('') renderer = gtk.CellRendererPixbuf() renderer.set_property('xpad', 4) popcon_column = gtk.TreeViewColumn(_('Popularity'), renderer) popcon_column.set_sort_column_id(COL_POPCON) popcon_column.set_cell_data_func(renderer, popcon_view_func, self) self.pixbuf_star = self.icons.load_icon('gnome-app-install-star', 16, 0) self.toggle_render = gtk.CellRendererToggle() self.store_toggle_id = self.toggle_render.connect('toggled', self.on_install_toggle) self.toggle_render.set_property('xalign', 0.29999999999999999) check_column.pack_start(self.toggle_render, False) check_column.set_cell_data_func(self.toggle_render, toggle_cell_func) render = gtk.CellRendererPixbuf() column.pack_start(render, False) column.set_cell_data_func(render, icon_cell_func) render = gtk.CellRendererText() render.set_property('ellipsize', pango.ELLIPSIZE_END) column.pack_start(render, True) column.add_attribute(render, 'markup', COL_NAME) column.set_cell_data_func(render, package_view_func) self.treeview_packages.append_column(check_column) self.treeview_packages.append_column(column) self.treeview_packages.append_column(popcon_column) column = gtk.TreeViewColumn('') render = gtk.CellRendererPixbuf() column.pack_start(render, False) column.set_cell_data_func(render, icon_cell_func) self.treeview_categories.set_search_column(COL_NAME) render = gtk.CellRendererText() render.set_property('scale', 1.0) column.pack_start(render, True) column.add_attribute(render, 'markup', COL_NAME) self.treeview_categories.append_column(column) def saveState(self): ''' save the current state of the app ''' (self.to_add, self.to_rm) = self.menu.getChanges() (self.cursor_categories_path, x) = self.treeview_categories.get_cursor() model = self.treeview_packages.get_model() (packages_path, x) = self.treeview_packages.get_cursor() if packages_path: it = model.get_iter(packages_path) self.cursor_pkgname = model.get_value(it, COL_NAME) else: self.cursor_pkgname = None def restoreState(self): ''' restore the current state of the app ''' self.treeview_categories.set_cursor(self.cursor_categories_path) model = self.treeview_packages.get_model() query = self.search_entry.get_text() if query: self.on_search_timeout() for item in self.to_add: if self.cache.has_key(item.pkgname): try: self.cache[item.pkgname].markInstall(autoFix = True) except SystemError: continue apps = self.menu.pkg_to_app[item.pkgname] for app in apps: app.toInstall = item.toInstall for item in self.to_rm: if self.cache.has_key(item.pkgname): try: self.cache[item.pkgname].markDelete(autoFix = True) except SystemError: continue apps = self.menu.pkg_to_app[item.pkgname] for app in apps: app.toInstall = item.toInstall self.treeview_packages.queue_draw() for it in iterate_list_store(model, model.get_iter_first()): name = model.get_value(it, COL_NAME) if name == self.last_toggle: self.last_toggle = None path = model.get_path(it) self.treeview_packages.set_cursor(path) self.on_install_toggle(None, path) break if name == self.cursor_pkgname and self.last_toggle == None: path = model.get_path(it) self.treeview_packages.set_cursor(path) break continue def updateCache(self, filter = SHOW_ONLY_MAIN): self.window_main.set_sensitive(False) self.setBusy(True) progress = GtkOpProgressWindow(self.glade, self.window_main) try: self.cache = MyCache(progress) except Exception: e = None header = _('Failed to check for installed and available applications') msg = _("This is a major failure of your software management system. Check the file permissions and correctness of the file '/etc/apt/sources.list' and reload the software information: 'sudo apt-get update'.") print e d = gtk.MessageDialog(parent = self.window_main, flags = gtk.DIALOG_MODAL, type = gtk.MESSAGE_ERROR, buttons = gtk.BUTTONS_CLOSE) d.set_title('') d.set_markup('<big><b>%s</b></big>\n\n%s' % (header, msg)) d.realize() d.window.set_functions(gtk.gdk.FUNC_MOVE) d.run() d.destroy() sys.exit(1) self.menu = ApplicationMenu(self.desktopdir, self.datadir, self.cache, self.treeview_categories, self.treeview_packages, progress, filter) self.treeview_categories.set_cursor((0,)) adj = self.scrolled_window.get_vadjustment() adj.set_value(0) self.setBusy(False) self.window_main.set_sensitive(True) def ignoreChanges(self): ''' If any changes have been made, ask the user to apply them and return a value based on the status. Returns True if the changes should be thrown away and False otherwise ''' if not self.menu.isChanged(): return True (to_add, to_rm) = self.menu.getChanges() dia = DialogPendingChanges(self.datadir, self.window_main, to_add, to_rm) header = _('Apply changes to installed applications before closing?') msg = _('If you do not apply your changes they will be lost permanently.') dia.label_pending.set_markup('<big><b>%s</b></big>\n\n%s' % (header, msg)) dia.button_ignore_changes.set_label(_('_Close Without Applying')) dia.button_ignore_changes.show() dia.dialog_pending_changes.realize() dia.dialog_pending_changes.window.set_functions(gtk.gdk.FUNC_MOVE) res = dia.run() dia.hide() return res def on_button_help_clicked(self, widget): subprocess.Popen([ '/usr/bin/yelp', 'ghelp:gnome-app-install']) def applyChanges(self, final = False): (to_add, to_rm) = self.menu.getChanges() self.setBusy(True) ret = self.packageWorker.perform_action(self.window_main, to_add, to_rm) if ret != 0: self.setBusy(False) return False if final != True: self.updateCache(filter = self.menu.filter) self.button_apply.set_sensitive(self.menu.isChanged()) if len(to_add) > 0: dia = DialogNewlyInstalled(self.datadir, self.window_main, to_add, self.cache) dia.run() dia.hide() self.setBusy(False) return True def on_button_ok_clicked(self, button): if not self.menu.isChanged(): self.quit() if self.confirmChanges(): if self.applyChanges(final = True): if self.menu.mimeSearch: self.menu.mimeSearch.retry_open() self.quit() def confirmChanges(self): (to_add, to_rm) = self.menu.getChanges() dia = DialogPendingChanges(self.datadir, self.window_main, to_add, to_rm) header = _('Apply the following changes?') msg = _('Please take a final look through the list of applications that will be installed or removed.') dia.label_pending.set_markup('<big><b>%s</b></big>\n\n%s' % (header, msg)) res = dia.run() dia.hide() if res != gtk.RESPONSE_APPLY: return False else: return True def on_button_apply_clicked(self, button): ret = self.confirmChanges() if ret == True: self.applyChanges() def on_search_timeout(self): query = self.search_entry.get_text() store = self.menu.treeview_packages.get_model() if query.lstrip() != '': self.menu.searchTerms = query.lower().split(' ') self.sort_by_ranking = True else: self.menu.searchTerms = [] self.sort_by_ranking = False self.on_treeview_categories_cursor_changed(self.treeview_categories) if len(store) == 0: self.show_no_results_msg() else: self.menu.treeview_packages.set_cursor(0) def on_search_entry_changed(self, widget): if self.search_timeout_id > 0: gobject.source_remove(self.search_timeout_id) self.search_timeout_id = gobject.timeout_add(500, self.on_search_timeout) def on_button_clear_clicked(self, button): self.search_entry.set_text('') self.menu.search(None) self.button_clear.set_sensitive(False) def on_item_about_activate(self, button): VERSION = VERSION import Version self.dialog_about.set_version(VERSION) self.dialog_about.run() self.dialog_about.hide() def on_reload_activate(self, item): self.reloadSources() def on_button_cancel_clicked(self, item): self.quit() def reloadSources(self): self.window_main.set_sensitive(False) ret = self.packageWorker.perform_action(self.window_main, action = PackageWorker.UPDATE) self.updateCache(filter = self.menu.filter) self.window_main.set_sensitive(True) return ret def enableChannel(self, channel): ''' enables a channel with 3rd party software ''' channelpath = '%s/%s.list' % (self.channelsdir, channel) channelkey = '%s/%s.key' % (self.channelsdir, channel) if not os.path.exists(channelpath): print "WARNING: channel '%s' not found" % channelpath return None cmd = [ 'gksu', '--desktop', '/usr/share/applications/gnome-app-install.desktop', '--', 'cp', channelpath, apt_pkg.Config.FindDir('Dir::Etc::sourceparts')] subprocess.call(cmd) if os.path.exists(channelkey): cmd = [ 'gksu', '--desktop', '/usr/share/applications/gnome-app-install.desktop', '--', 'apt-key', 'add', channelkey] subprocess.call(cmd) def enableComponent(self, component): ''' Enables a component of the current distribution (in a seperate file in /etc/apt/sources.list.d/$dist-$comp) ''' pipe = os.popen('lsb_release -c -s') distro = pipe.read().strip() del pipe if component == '': print 'no repo found in enableRepository' return None mirror = 'http://archive.ubuntu.com/ubuntu' sources = SourcesList() newentry_sec = '' newentry_updates = '' for source in sources: if source.invalid or source.disabled: continue if source.dist == '%s-updates' % distro: if component in source.comps: newentry_updates = '' else: newentry_updates = 'deb %s %s-updates %s\n' % (source.uri, distro, component) if source.dist == '%s-security' % distro: if component in source.comps: newentry_sec = '' else: newentry_sec = 'deb http://security.ubuntu.com/ubuntu %s-security %s\n' % (distro, component) if source.uri != mirror and is_mirror(mirror, source.uri): mirror = source.uri continue newentry = '# automatically added by gnome-app-install on %s\n' % datetime.today() newentry += 'deb %s %s %s\n' % (mirror, distro, component) if newentry_sec != '': newentry += newentry_sec if newentry_updates != '': newentry += newentry_updates channel_dir = apt_pkg.Config.FindDir('Dir::Etc::sourceparts') channel_file = '%s-%s.list' % (distro, component) channel = tempfile.NamedTemporaryFile() channel.write(newentry) channel.flush() cmd = [ 'gksu', '--desktop', '/usr/share/applications/gnome-app-install.desktop', '--', 'install', '-m', '644', '-o', '0', channel.name, channel_dir + channel_file] subprocess.call(cmd) def on_window_main_delete_event(self, window, event): if window.get_property('sensitive') == False: return True if self.menu.isChanged(): ret = self.ignoreChanges() if ret == gtk.RESPONSE_APPLY: if not self.applyChanges(final = True): return True elif ret == gtk.RESPONSE_CANCEL: return True elif ret == gtk.RESPONSE_CLOSE: self.quit() self.quit() def on_window_main_destroy_event(self, data = None): self.quit() def quit(self): gtk.main_quit() sys.exit(0) def show_description(self, item): '''Collect and show some information about the package that contains the selected application''' details = [] clean_desc = '' short_desc = '' version = '' desktop_environment = '' icons = [] if self.cache.has_key(item.pkgname): version = self.cache[item.pkgname].candidateVersion for dependencies in desktop_environment_mapping: for dep in dependencies: if self.cache.pkgDependsOn(item.pkgname, dep): details.append(desktop_environment_mapping[dependencies][0] % item.name) if desktop_environment_mapping[dependencies][1] != None: icons.append([ desktop_environment_mapping[dependencies][1], desktop_environment_mapping[dependencies][0] % item.name]) break continue if item.available: pkg = self.cache[item.pkgname] rough_desc = pkg.description.rstrip(' \n\t') first_break = rough_desc.find('\n') short_desc = rough_desc[:first_break].rstrip('\n\t ') rough_desc = rough_desc[first_break + 1:].lstrip('\n\t ') p = re.compile('^(\\s|\\t)*(\\*|0|-)', re.MULTILINE) rough_desc = p.sub('\n*', rough_desc) p = re.compile('\\n', re.MULTILINE) rough_desc = p.sub(' ', rough_desc) p = re.compile('\\s\\s+', re.MULTILINE) rough_desc = p.sub('\n', rough_desc) lines = rough_desc.split('\n') for i in range(len(lines)): if lines[i].split() == []: continue first_chunk = lines[i].split()[0] if first_chunk == '*': p = re.compile('\\*\\s*', re.MULTILINE) lines[i] = p.sub('', lines[i]) clean_desc += '\xe2\x80\xa2 %s\n' % lines[i] continue clean_desc += '%s\n' % lines[i] else: msg = _('%s cannot be installed' % item.name) for it in self.cache._cache.FileList: if (it.Component != '' or it.Component == item.component or item.architectures) and self.cache.getArch() not in item.architectures: details.append(_('%s cannot be installed on your computer type (%s). Either the application requires special hardware features or the vendor decided to not support your computer type.') % (item.name, self.cache.getArch())) break continue if item.component == 'universe': care_about_freedom = _('This application is brought to you by the Ubuntu community.') icons.append([ 'application-community', care_about_freedom]) elif item.component == 'multiverse' or item.thirdparty: care_about_freedom = _('The use, modification and distribution of %s is restricted by copyright or by legal terms in some countries.') % item.name icons.append([ 'application-proprietary', care_about_freedom]) elif item.thirdparty or item.channel: care_about_freedom = '%s is provided by a third party vendor and is therefore not an official part of Ubuntu. The third party vendor is responsible for support and security updates.' % item.name icons.append([ 'application-proprietary', care_about_freedom]) elif item.component == 'main' or item.supported: icons.append([ 'application-supported', _('Canonical Ltd. supports %s with security updates') % item.name]) care_about_freedom = '' else: care_about_freedom = '' s = '' buffer = self.textview_description.get_buffer() buffer.set_text('') tag_table = buffer.get_tag_table() tag_table.foreach((lambda tag, table: table.remove(tag)), tag_table) iter = buffer.get_start_iter() pango_context = self.textview_description.get_pango_context() font_desc = pango_context.get_font_description() font_size = font_desc.get_size() / pango.SCALE buffer.insert_with_tags_by_name(iter, ' %s' % item.name, 'app-name') if short_desc != '': tag_name = buffer.create_tag('short-desc', weight = pango.WEIGHT_BOLD) buffer.insert_with_tags_by_name(iter, '\n%s' % short_desc, 'short-desc') for emblem in icons: image_emblem = gtk.Image() image_emblem.set_from_icon_name(emblem[0], gtk.ICON_SIZE_MENU) image_emblem.set_pixel_size(16) event = gtk.EventBox() style = self.textview_description.get_style() event.modify_bg(gtk.STATE_NORMAL, style.base[gtk.STATE_NORMAL]) event.add(image_emblem) self.tooltips.set_tip(event, emblem[1]) buffer.insert(iter, ' ') anchor = buffer.create_child_anchor(iter) self.textview_description.add_child_at_anchor(event, anchor) event.show() image_emblem.show() elif care_about_freedom != '': buffer.insert(iter, '\n%s' % care_about_freedom) if clean_desc != '': buffer.insert(iter, '\n%s' % clean_desc) if version != '': buffer.insert(iter, _('Version: %s (%s)') % (version, item.pkgname)) if len(details) > 0: for x in details: buffer.insert(iter, '\n%s' % x) def clear_description(self): buffer = self.textview_description.get_buffer() buffer.set_text('') def on_treeview_packages_row_activated(self, treeview, path, view_column): iter = treeview.get_model().get_iter(path) item = treeview.get_model().get_value(iter, COL_ITEM) if item.architectures and self.cache.getArch() not in item.architectures: return False self.on_install_toggle(None, path) def on_treeview_categories_cursor_changed(self, treeview): self.setBusy(True) path = treeview.get_cursor()[0] iter = treeview.get_model().get_iter(path) (name, item) = treeview.get_model()[iter] self.treeview_packages.set_model(item.applications) self.menu._refilter() if self.sort_by_ranking: if not item.applications.has_default_sort_func(): item.applications.set_default_sort_func(None) item.applications.set_default_sort_func(self.menu._ranking_sort_func) item.applications.set_sort_column_id(-1, gtk.SORT_ASCENDING) else: item.applications.set_default_sort_func(None) item.applications.set_default_sort_func(self.menu._ranking_sort_func) item.applications.set_sort_column_id(-1, gtk.SORT_ASCENDING) elif item.applications.has_default_sort_func(): item.applications.set_sort_column_id(COL_NAME, gtk.SORT_ASCENDING) item.applications.set_default_sort_func(None) if len(self.menu.treeview_packages.get_model()) == 0: self.show_no_results_msg() else: self.menu.treeview_packages.set_cursor(0) self.setBusy(False) def on_treeview_packages_cursor_changed(self, treeview): path = treeview.get_cursor()[0] iter = treeview.get_model().get_iter(path) (name, item, popcon) = treeview.get_model()[iter] self.show_description(item) def show_no_results_msg(self): ''' Give the user some hints if the search returned no results''' buffer = self.textview_description.get_buffer() buffer.set_text('') tag_table = buffer.get_tag_table() tag_table.foreach((lambda tag, table: table.remove(tag)), tag_table) tag_header = buffer.create_tag('first-line', weight = pango.WEIGHT_BOLD, pixels_above_lines = 6) msg = _('There is no matching application available.') iter = buffer.get_start_iter() buffer.insert_with_tags_by_name(iter, msg, 'first-line') if self.menu.filter != SHOW_ALL_FREE and self.menu.filter != SHOW_ALL: msg = '\n%s' % _("To broaden your search, choose 'Show all Open Source applications' or 'Show all available' applications.") buffer.insert_with_tags(iter, msg) if self.treeview_categories.get_cursor()[0] != (0,): msg = '\n%s' % _("To broaden your search, choose 'All' categories.") buffer.insert_with_tags(iter, msg) def show_intro(self): ''' Show a quick introduction to gnome-app-install in the description view''' buffer = self.textview_description.get_buffer() buffer.set_text('') iter = buffer.get_start_iter() tag_header = buffer.create_tag('header', scale = pango.SCALE_LARGE, weight = pango.WEIGHT_BOLD, pixels_above_lines = 6) msg = _('To install an application check the box next to the application. Uncheck the box to remove the application.') + '\n' msg += _('To perform advanced tasks use the Synaptic package manager.') buffer.insert_with_tags(iter, '%s\n' % _('Quick Introduction'), tag_header) buffer.insert(iter, msg) if __name__ == '__main__': app = AppInstall(os.path.abspath('menu-data'), os.path.abspath('data'), sys.argv) gtk.main()