def __init__(self, interface_uri = None): builderfile = os.path.join(os.path.dirname(__file__), 'desktop.ui') builder = gtk.Builder() builder.set_translation_domain('zero-install') builder.add_from_file(builderfile) self.window = builder.get_object('main') self.set_keep_above(True) def set_uri_ok(uri): text = uri.get_text() self.window.set_response_sensitive(_RESPONSE_NEXT, bool(text)) uri = builder.get_object('interface_uri') about = builder.get_object('about') icon_widget = builder.get_object('icon') category = builder.get_object('category') dialog_next = builder.get_object('dialog_next') dialog_ok = builder.get_object('dialog_ok') if interface_uri: uri.set_text(interface_uri) uri.connect('changed', set_uri_ok) set_uri_ok(uri) for c in categories: category.append_text(_(c)) category.set_active(11) def uri_dropped(iface): if not gtkutils.sanity_check_iface(self.window, iface): return False uri.set_text(iface) self.window.response(_RESPONSE_NEXT) print("ok") return True gtkutils.make_iface_uri_drop_target(self.window, uri_dropped) nb = builder.get_object('notebook1') def update_details_page(): iface_uri = model.canonical_iface_uri(uri.get_text()) iface = iface_cache.get_interface(iface_uri) feed = iface_cache.get_feed(iface_uri) assert feed, iface_uri about.set_text('%s - %s' % (feed.get_name(), feed.summary)) icon_path = iface_cache.get_icon_path(iface) from zeroinstall.gtkui import icon icon_pixbuf = icon.load_icon(icon_path) if icon_pixbuf: icon_widget.set_from_pixbuf(icon_pixbuf) feed_category = None for meta in feed.get_metadata(XMLNS_IFACE, 'category'): feed_category = meta.content break if feed_category: i = 0 for row in categories: if row.lower() == feed_category.lower(): category.set_active(i) break i += 1 self.window.set_response_sensitive(_RESPONSE_PREV, True) def finish(): from . import xdgutils iface_uri = model.canonical_iface_uri(uri.get_text()) iface = iface_cache.get_interface(iface_uri) feed = iface_cache.get_feed(iface_uri) try: icon_path = iface_cache.get_icon_path(iface) xdgutils.add_to_menu(feed, icon_path, categories[category.get_active()]) except SafeException as ex: box = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, str(ex)) box.run() box.destroy() else: self.window.destroy() def response(box, resp): if resp == _RESPONSE_NEXT: iface = uri.get_text() if not gtkutils.sanity_check_iface(self.window, iface): return self.window.set_sensitive(False) self.set_keep_above(False) import subprocess child = subprocess.Popen(['0launch', '--gui', '--download-only', '--', iface], stdout = subprocess.PIPE, stderr = subprocess.STDOUT) errors = [b''] def output_ready(src, cond): got = os.read(src.fileno(), 100) if got: errors[0] += got else: status = child.wait() self.window.set_sensitive(True) self.set_keep_above(True) if status == 0: update_details_page() nb.next_page() dialog_next.set_property('visible', False) dialog_ok.set_property('visible', True) dialog_ok.grab_focus() else: box = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _('Failed to run 0launch.\n') + errors[0].decode('utf-8')) box.run() box.destroy() return False return True glib.io_add_watch(child.stdout, glib.IO_IN | glib.IO_HUP, output_ready) elif resp == gtk.RESPONSE_OK: finish() elif resp == _RESPONSE_PREV: dialog_next.set_property('visible', True) dialog_ok.set_property('visible', False) dialog_next.grab_focus() nb.prev_page() self.window.set_response_sensitive(_RESPONSE_PREV, False) else: box.destroy() self.window.connect('response', response) if interface_uri: self.window.response(_RESPONSE_NEXT)
def __init__(self, interface_uri=None): builderfile = os.path.join(os.path.dirname(__file__), 'desktop.ui') builder = gtk.Builder() builder.set_translation_domain('zero-install') builder.add_from_file(builderfile) self.window = builder.get_object('main') self.set_keep_above(True) def set_uri_ok(uri): text = uri.get_text() self.window.set_response_sensitive(_RESPONSE_NEXT, bool(text)) uri = builder.get_object('interface_uri') about = builder.get_object('about') icon_widget = builder.get_object('icon') category = builder.get_object('category') dialog_next = builder.get_object('dialog_next') dialog_ok = builder.get_object('dialog_ok') if interface_uri: uri.set_text(interface_uri) uri.connect('changed', set_uri_ok) set_uri_ok(uri) for c in categories: category.append_text(_(c)) category.set_active(11) def uri_dropped(iface): if not gtkutils.sanity_check_iface(self.window, iface): return False uri.set_text(iface) self.window.response(_RESPONSE_NEXT) print("ok") return True gtkutils.make_iface_uri_drop_target(self.window, uri_dropped) nb = builder.get_object('notebook1') def update_details_page(): iface_uri = model.canonical_iface_uri(uri.get_text()) iface = iface_cache.get_interface(iface_uri) feed = iface_cache.get_feed(iface_uri) assert feed, iface_uri about.set_text('%s - %s' % (feed.get_name(), feed.summary)) icon_path = iface_cache.get_icon_path(iface) from zeroinstall.gtkui import icon icon_pixbuf = icon.load_icon(icon_path) if icon_pixbuf: icon_widget.set_from_pixbuf(icon_pixbuf) feed_category = None for meta in feed.get_metadata(XMLNS_IFACE, 'category'): feed_category = meta.content break if feed_category: i = 0 for row in categories: if row.lower() == feed_category.lower(): category.set_active(i) break i += 1 self.window.set_response_sensitive(_RESPONSE_PREV, True) def finish(): from . import xdgutils iface_uri = model.canonical_iface_uri(uri.get_text()) iface = iface_cache.get_interface(iface_uri) feed = iface_cache.get_feed(iface_uri) try: icon_path = iface_cache.get_icon_path(iface) xdgutils.add_to_menu(feed, icon_path, categories[category.get_active()]) except SafeException as ex: box = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, str(ex)) box.run() box.destroy() else: self.window.destroy() def response(box, resp): if resp == _RESPONSE_NEXT: iface = uri.get_text() if not gtkutils.sanity_check_iface(self.window, iface): return self.window.set_sensitive(False) self.set_keep_above(False) import subprocess child = subprocess.Popen( ['0launch', '--gui', '--download-only', '--', iface], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) errors = [b''] def output_ready(src, cond): got = os.read(src.fileno(), 100) if got: errors[0] += got else: status = child.wait() self.window.set_sensitive(True) self.set_keep_above(True) if status == 0: update_details_page() nb.next_page() dialog_next.set_property('visible', False) dialog_ok.set_property('visible', True) dialog_ok.grab_focus() else: box = gtk.MessageDialog( self.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _('Failed to run 0launch.\n') + errors[0].decode('utf-8')) box.run() box.destroy() return False return True glib.io_add_watch(child.stdout, glib.IO_IN | glib.IO_HUP, output_ready) elif resp == gtk.RESPONSE_OK: finish() elif resp == _RESPONSE_PREV: dialog_next.set_property('visible', True) dialog_ok.set_property('visible', False) dialog_next.grab_focus() nb.prev_page() self.window.set_response_sensitive(_RESPONSE_PREV, False) else: box.destroy() self.window.connect('response', response) if interface_uri: self.window.response(_RESPONSE_NEXT)
def __init__(self, iface_cache, app_list): """Constructor. @param iface_cache: used to find extra information about programs @type iface_cache: L{zeroinstall.injector.iface_cache.IfaceCache} @param app_list: used to list or remove applications @type app_list: L{AppList} """ builderfile = os.path.join(os.path.dirname(__file__), 'desktop.ui') self.iface_cache = iface_cache self.app_list = app_list builder = gtk.Builder() builder.set_translation_domain('zero-install') builder.add_from_file(builderfile) self.window = builder.get_object('applist') tv = builder.get_object('treeview') self.model = gtk.ListStore(gtk.gdk.Pixbuf, str, str, str) self.populate_model() tv.set_model(self.model) tv.get_selection().set_mode(gtk.SELECTION_NONE) cell_icon = gtk.CellRendererPixbuf() cell_icon.set_property('xpad', 4) cell_icon.set_property('ypad', 4) column = gtk.TreeViewColumn('Icon', cell_icon, pixbuf=AppListBox.ICON) tv.append_column(column) cell_text = gtk.CellRendererText() cell_text.set_property('ellipsize', pango.ELLIPSIZE_END) column = gtk.TreeViewColumn('Name', cell_text, markup=AppListBox.MARKUP) column.set_expand(True) tv.append_column(column) cell_actions = ActionsRenderer(self, tv) actions_column = gtk.TreeViewColumn('Actions', cell_actions, uri=AppListBox.URI) tv.append_column(actions_column) def redraw_actions(path): if path is not None: area = tv.get_cell_area(path, actions_column) if gtk2: tv.queue_draw_area(*area) else: tv.queue_draw_area(area.x, area.y, area.width, area.height) tv.set_property('has-tooltip', True) def query_tooltip(widget, x, y, keyboard_mode, tooltip): x, y = tv.convert_widget_to_bin_window_coords(x, y) pos = tv.get_path_at_pos(x, y) if pos: new_hover = (None, None, None) path, col, x, y = pos if col == actions_column: area = tv.get_cell_area(path, col) iface = self.model[path][AppListBox.URI] action = cell_actions.get_action(area, x, y) if action is not None: new_hover = (path, iface, action) if new_hover != cell_actions.hover: redraw_actions(cell_actions.hover[0]) cell_actions.hover = new_hover redraw_actions(cell_actions.hover[0]) tv.set_tooltip_cell(tooltip, pos[0], pos[1], None) if new_hover[2] is not None: tooltip.set_text(_tooltips[cell_actions.hover[2]]) return True return False tv.connect('query-tooltip', query_tooltip) def leave(widget, lev): redraw_actions(cell_actions.hover[0]) cell_actions.hover = (None, None, None) tv.connect('leave-notify-event', leave) self.model.set_sort_column_id(AppListBox.NAME, gtk.SORT_ASCENDING) show_cache = builder.get_object('show_cache') self.window.action_area.set_child_secondary(show_cache, True) def response(box, resp): if resp == 0: # Show Cache subprocess.Popen(['0store', 'manage']) elif resp == 1: # Add from zeroinstall.gtkui.addbox import AddBox box = AddBox() box.window.connect('destroy', lambda dialog: self.populate_model()) box.window.show() else: box.destroy() self.window.connect('response', response) # Drag-and-drop def uri_dropped(iface): if not gtkutils.sanity_check_iface(self.window, iface): return False from zeroinstall.gtkui.addbox import AddBox box = AddBox(iface) box.window.connect('destroy', lambda dialog: self.populate_model()) box.window.show() return True gtkutils.make_iface_uri_drop_target(self.window, uri_dropped)
def __init__(self, iface_cache, app_list): """Constructor. @param iface_cache: used to find extra information about programs @type iface_cache: L{zeroinstall.injector.iface_cache.IfaceCache} @param app_list: used to list or remove applications @type app_list: L{AppList} """ builderfile = os.path.join(os.path.dirname(__file__), 'desktop.ui') self.iface_cache = iface_cache self.app_list = app_list builder = gtk.Builder() builder.set_translation_domain('zero-install') builder.add_from_file(builderfile) self.window = builder.get_object('applist') tv = builder.get_object('treeview') self.model = gtk.ListStore(gtk.gdk.Pixbuf, str, str, str) self.populate_model() tv.set_model(self.model) tv.get_selection().set_mode(gtk.SELECTION_NONE) cell_icon = gtk.CellRendererPixbuf() cell_icon.set_property('xpad', 4) cell_icon.set_property('ypad', 4) column = gtk.TreeViewColumn('Icon', cell_icon, pixbuf = AppListBox.ICON) tv.append_column(column) cell_text = gtk.CellRendererText() cell_text.set_property('ellipsize', pango.ELLIPSIZE_END) column = gtk.TreeViewColumn('Name', cell_text, markup = AppListBox.MARKUP) column.set_expand(True) tv.append_column(column) cell_actions = ActionsRenderer(self, tv) actions_column = gtk.TreeViewColumn('Actions', cell_actions, uri = AppListBox.URI) tv.append_column(actions_column) def redraw_actions(path): if path is not None: area = tv.get_cell_area(path, actions_column) if gtk2: tv.queue_draw_area(*area) else: tv.queue_draw_area(area.x, area.y, area.width, area.height) tv.set_property('has-tooltip', True) def query_tooltip(widget, x, y, keyboard_mode, tooltip): x, y = tv.convert_widget_to_bin_window_coords(x, y) pos = tv.get_path_at_pos(x, y) if pos: new_hover = (None, None, None) path, col, x, y = pos if col == actions_column: area = tv.get_cell_area(path, col) iface = self.model[path][AppListBox.URI] action = cell_actions.get_action(area, x, y) if action is not None: new_hover = (path, iface, action) if new_hover != cell_actions.hover: redraw_actions(cell_actions.hover[0]) cell_actions.hover = new_hover redraw_actions(cell_actions.hover[0]) tv.set_tooltip_cell(tooltip, pos[0], pos[1], None) if new_hover[2] is not None: tooltip.set_text(_tooltips[cell_actions.hover[2]]) return True return False tv.connect('query-tooltip', query_tooltip) def leave(widget, lev): redraw_actions(cell_actions.hover[0]) cell_actions.hover = (None, None, None) tv.connect('leave-notify-event', leave) self.model.set_sort_column_id(AppListBox.NAME, gtk.SORT_ASCENDING) show_cache = builder.get_object('show_cache') self.window.action_area.set_child_secondary(show_cache, True) def response(box, resp): if resp == 0: # Show Cache subprocess.Popen(['0store', 'manage']) elif resp == 1: # Add from zeroinstall.gtkui.addbox import AddBox box = AddBox() box.window.connect('destroy', lambda dialog: self.populate_model()) box.window.show() else: box.destroy() self.window.connect('response', response) # Drag-and-drop def uri_dropped(iface): if not gtkutils.sanity_check_iface(self.window, iface): return False from zeroinstall.gtkui.addbox import AddBox box = AddBox(iface) box.window.connect('destroy', lambda dialog: self.populate_model()) box.window.show() return True gtkutils.make_iface_uri_drop_target(self.window, uri_dropped)