class Diary(ProxyDelegate): def __init__(self): self.entries = ObjectList([ Column("title", width=120), Column("period", width=80), Column("text", expand=True) ]) ProxyDelegate.__init__(self, DiaryEntry(), ['title', 'period', 'text'], gladefile="diary.ui", delete_handler=self.quit_if_last) self.hbox.pack_start(self.entries, True, True, 0) self.entries.show() self.entries.grab_focus() def on_add__clicked(self, button): entry = DiaryEntry() entry.title = 'New title' self.set_model(entry) self.entries.append(entry) self.title.grab_focus() def on_remove__clicked(self, button): entry = self.entries.get_selected() if entry: self.entries.remove(entry) def on_entries__selection_changed(self, entries, instance): if instance: self.set_model(instance)
class Diary(ProxyDelegate): def __init__(self): self.entries = ObjectList([Column("title", width=120), Column("period", width=80), Column("text", expand=True)]) ProxyDelegate.__init__(self, DiaryEntry(), ['title', 'period', 'text'], gladefile="diary", delete_handler=self.quit_if_last) self.hbox.pack_start(self.entries) self.entries.show() self.entries.grab_focus() def on_add__clicked(self, button): entry = DiaryEntry() entry.title = 'New title' self.set_model(entry) self.entries.append(entry) self.title.grab_focus() def on_remove__clicked(self, button): entry = self.entries.get_selected() if entry: self.entries.remove(entry) def on_entries__selection_changed(self, entries, instance): if instance: self.set_model(instance)
class StockIconDialog(BaseDialog): def __init__(self, parent=None): BaseDialog.__init__(self, parent, title=_('Stock Icons'), buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK)) self.set_size_request(260, 330) self._stockicons = ObjectList([Column('stock_id', use_stock=True), Column('name')]) self._stockicons.set_headers_visible(False) self._stockicons.connect('row-activated', self._on_stockicons__row_activated) self._icons = {} for stock_label, stock_id in get_stock_icons(): icon = Settable(stock_id=stock_id, name=stock_label) self._stockicons.append(icon) self._icons[stock_id] = icon self.vbox.pack_start(self._stockicons) self._stockicons.show() def select(self, value): icon = self._icons.get(value) if icon: self._stockicons.select(icon) def get_selected(self): icon = self._stockicons.get_selected() if icon: return icon.stock_id def _on_stockicons__row_activated(self, objectlist, icon): self.emit('response', gtk.RESPONSE_OK)
class BooleanDataTests(unittest.TestCase): def setUp(self): self.list = ObjectList([Column('value', data_type=bool, radio=True, editable=True)]) self.list.append(Settable(value=True)) self.list.append(Settable(value=False)) def testAddingInstances(self): self.assertEqual(self.list[0].value, True) self.assertEqual(self.list[1].value, False) def testSelect(self): self.assertEqual(self.list[0].value, True) self.assertEqual(self.list[1].value, False) column = self.list.get_column_by_name('value') treeview_column = self.list.get_treeview_column(column) renderer = treeview_column.get_cell_renderers() renderer[0].emit('toggled', 1) self.assertEqual(self.list[0].value, False) self.assertEqual(self.list[1].value, True) renderer[0].emit('toggled', 0) self.assertEqual(self.list[0].value, True) self.assertEqual(self.list[1].value, False)
class PropertiesAdminGtkNode(BaseAdminGtkNode): gladeFile = os.path.join('flumotion', 'component', 'base', 'properties.glade') def __init__(self, state, admin): BaseAdminGtkNode.__init__(self, state, admin, title=_("Properties")) def haveWidgetTree(self): self.widget = gtk.VBox() self.widget.set_border_width(6) self.properties = ObjectList( [Column('name'), Column('value')]) self.properties.set_size_request(-1, 200) self.widget.pack_start(self.properties, False, False) self.properties.show() properties = self.state.get('config')['properties'] propertyNames = properties.keys()[:] propertyNames.sort() for name in propertyNames: self.properties.append( Settable(name=name, value=properties[name])) return self.widget
def test_export_from_object_list(self): from kiwi.ui.objectlist import ObjectList, Column fruits = ObjectList( [Column('name', data_type=str), Column('price', data_type=int)]) for name, price in [('Apple', 4), ('Pineapple', 2), ('Kiwi', 8), ('Banana', 3), ('Melon', 5)]: fruits.append(Fruit(name, price)) ofx = XLSExporter() ofx.add_from_object_list(fruits) try: temp_file = ofx.save() with open(temp_file.name, 'rb') as f: data = f.read() # We should use xlrd to 're-open' the spreadsheet and parse its content. self.assertTrue(len(data) > 0) finally: temp_file.close() os.unlink(temp_file.name)
class BooleanDataTests(unittest.TestCase): def setUp(self): self.list = ObjectList( [Column('value', data_type=bool, radio=True, editable=True)]) self.list.append(Settable(value=True)) self.list.append(Settable(value=False)) def testAddingInstances(self): self.assertEqual(self.list[0].value, True) self.assertEqual(self.list[1].value, False) def testSelect(self): self.assertEqual(self.list[0].value, True) self.assertEqual(self.list[1].value, False) column = self.list.get_column_by_name('value') treeview_column = self.list.get_treeview_column(column) renderer = treeview_column.get_cells() renderer[0].emit('toggled', 1) self.assertEqual(self.list[0].value, False) self.assertEqual(self.list[1].value, True) renderer[0].emit('toggled', 0) self.assertEqual(self.list[0].value, True) self.assertEqual(self.list[1].value, False)
def test_export_from_object_list(self): fruits = ObjectList([Column('name', data_type=str), Column('price', data_type=int)]) for name, price in [('Apple', 4), ('Pineapple', 2), ('Kiwi', 8), ('Banana', 3), ('Melon', 5)]: fruits.append(Fruit(name, price)) ofx = XLSExporter() ofx.add_from_object_list(fruits) try: temp_file = ofx.save() data = open(temp_file.name).read() # We should use xlrd to 're-open' the spreadsheet and parse its content. self.assertTrue(len(data) > 0) finally: temp_file.close() os.unlink(temp_file.name)
class ManView(PidaView): icon_name = 'gtk-library' label_text = 'Man' def create_ui(self): self._count = 0 self.__vbox = gtk.VBox(spacing=3) self.__vbox.set_border_width(6) self.__hbox = gtk.HBox() self.__entry = gtk.Entry() self.__entry.connect('changed', self.cb_entry_changed) self.__check = gtk.CheckButton(label='-k') self.__check.connect('toggled', self.cb_entry_changed) self.__list = ObjectList([ Column('markup', title=_('Man page'), sorted=True, use_markup=True), Column('description', title=_('Description'), use_markup=True), ]) self.__list.connect('double-click', self._on_man_double_click) self.__list.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self.__hbox.pack_start(self.__entry) self.__hbox.pack_start(self.__check, expand=False) self.__vbox.pack_start(self.__hbox, expand=False) self.__vbox.pack_start(self.__list) self.add_main_widget(self.__vbox) self.__vbox.show_all() def clear_items(self): self._count = 0 self.__list.clear() def add_item(self, item): self._count += 1 self.__list.append(item) def _on_man_double_click(self, olist, item): commandargs = ['/usr/bin/env', 'man', item.number, item.pattern] directory = os.path.dirname(commandargs[0]) self.svc.boss.cmd('commander', 'execute', commandargs=commandargs, cwd=directory, icon='gnome-library', title='%(pattern)s(%(number)d)' % dict( pattern=item.pattern, number=int(item.number) )) def cb_entry_changed(self, w): options = '-f' if self.__check.get_active(): options = '-k' self.svc.cmd_find(options=options, pattern=self.__entry.get_text()) def can_be_closed(self): self.svc.get_action('show_man').set_active(False)
def __init__(self): listt = ObjectList(self.columns) listt.connect('selection-changed', self.selected) # selecting categories f = urllib.urlopen("http://pacnet.archlinux.pl/api/categories/").read() categories=json.loads(f) for category in categories: row = CategoryItem(category['fields']['name']) listt.append(row) SlaveView.__init__(self, listt)
class SpykeeWifiListView(SlaveView): def __init__(self, cf): self.networks = ObjectList([Column("essid", "Network Name",), Column("encryption", "Security"), Column("strength", "Signal Strength")]) self.cf = cf self.cf.currentProtocol.getVisibleWifi() SlaveView.__init__(self, toplevel=self.networks) def wifiReceived(self, wifi): for network in wifi: n = SpykeeWifiNetwork(network, wifi[network][0], wifi[network][1]) self.networks.append(n)
class SpykeeListView(SlaveView): def __init__(self): self.robots = ObjectList([Column("name", "Name",), Column("ip", "IP Address")]) d = twistedprotocol.discover(5, self) d.addCallback(self.discovered) SlaveView.__init__(self, toplevel=self.robots) def spykeeFound(self, name, ip): r = SpykeeRobot(name, ip) self.robots.append(r) def discovered(self, spykees): if not spykees: d = gtk.MessageDialog(message_format="No Spykee Robots found") d.show()
class PyflakeView(PidaView): icon_name = 'python-icon' label_text = _('Python Errors') def create_ui(self): self.errors_ol = ObjectList( Column('markup', use_markup=True) ) self.errors_ol.set_headers_visible(False) self.errors_ol.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self.add_main_widget(self.errors_ol) self.errors_ol.connect('double-click', self._on_errors_double_clicked) self.errors_ol.show_all() self.sort_combo = AttrSortCombo( self.errors_ol, [ ('lineno', _('Line Number')), ('message_string', _('Message')), ('name', _('Type')), ], 'lineno', ) self.sort_combo.show() self.add_main_widget(self.sort_combo, expand=False) def clear_items(self): self.errors_ol.clear() def set_items(self, items): self.clear_items() for item in items: self.errors_ol.append(self.decorate_pyflake_message(item)) def decorate_pyflake_message(self, msg): args = [('<b>%s</b>' % arg) for arg in msg.message_args] msg.message_string = msg.message % tuple(args) msg.name = msg.__class__.__name__ msg.markup = ('<tt>%s </tt><i>%s</i>\n%s' % (msg.lineno, msg.name, msg.message_string)) return msg def _on_errors_double_clicked(self, ol, item): self.svc.boss.editor.cmd('goto_line', line=item.lineno) def can_be_closed(self): self.svc.get_action('show_python_errors').set_active(False)
class Diary(ProxyDelegate): def __init__(self): self.entries = ObjectList([ Column("title", width=120, sorted=True), Column("period", width=80), Column("text", expand=True, visible=False) ]) ProxyDelegate.__init__(self, DiaryEntry(), ['title', 'period', 'text', 'chars', 'words'], gladefile="diary2.ui", delete_handler=self.quit_if_last) self.hbox.pack_start(self.entries, True, True, 0) self.entries.show() self.entries.grab_focus() self.set_editable(False) def set_editable(self, editable): self.leftbox.set_sensitive(editable) self.remove.set_sensitive(editable) def proxy_updated(self, *args): self.entries.update(self.model) def on_add__clicked(self, button): entry = DiaryEntry() entry.title = 'Untitled' self.entries.append(entry, select=True) self.set_editable(True) def on_remove__clicked(self, button): entry = self.entries.get_selected() if entry: self.entries.remove(entry, select=True) self.set_editable(len(self.entries) >= 1) if not len(self.entries): self.set_model(None) def on_text__content_changed(self, text): self.proxy.update_many(("chars", "words")) self.entries.update(self.model) def on_entries__selection_changed(self, entries, instance): if instance: self.set_model(instance) self.title.grab_focus()
class TestSignals(unittest.TestCase): def setUp(self): self.klist = ObjectList() self.klist.connect('has-rows', self._on_klist__has_rows) self.klist.connect('selection-changed', self._on_klist__selection_changed) self.rows = None self.selected = None def _on_klist__has_rows(self, klist, rows): self.rows = rows def _on_klist__selection_changed(self, klist, selected): self.selected = selected def testHasRows(self): self.assertEqual(self.rows, None) self.assertEqual(len(self.klist), 0) # Add one self.klist.append(0) self.assertEqual(len(self.klist), 1) self.assertEqual(self.rows, True) self.klist.remove(0) self.assertEqual(self.rows, False) self.assertEqual(len(self.klist), 0) # Add several self.klist.extend((1, 2)) self.assertEqual(len(self.klist), 2) self.assertEqual(self.rows, True) self.klist.remove(1) self.assertEqual(self.rows, True) self.klist.remove(2) self.assertEqual(self.rows, False) self.assertEqual(len(self.klist), 0) def testSelectionChanged(self): self.assertEqual(self.selected, None) self.assertEqual(len(self.klist), 0) self.klist.extend((0, 1)) self.klist.select(0) self.assertEqual(self.selected, 0) self.klist.unselect_all() self.assertEqual(self.selected, None) self.assertRaises(ValueError, self.klist.select, 2)
def _create_field_list(self): items = ObjectList([Column('description', width=200), Column('len', data_type=int, editable=True)]) items.enable_dnd() items.set_size_request(200, -1) descriptions = {} invoice_fields = get_invoice_fields() for invoice_field in sorted(invoice_fields, key=operator.attrgetter('name')): items.append( Settable(description=invoice_field.get_description(), name=invoice_field.name, len=invoice_field.length)) descriptions[invoice_field.name] = invoice_field.description self._field_descriptions = descriptions self.left_vbox.pack_end(items, True, True) items.show()
class DeviceConstantsDialog(BasicDialog): size = (500, 300) def __init__(self, store, printer): self._constant_slave = None self.store = store self.printer = printer BasicDialog.__init__(self, hide_footer=False, title='edit', size=self.size) self.main.set_border_width(6) self._create_ui() def _create_ui(self): hbox = Gtk.HBox() self.klist = ObjectList([Column('name')]) self.klist.set_size_request(150, -1) self.klist.get_treeview().set_headers_visible(False) self.klist.connect('selection-changed', self._on_klist__selection_changed) hbox.pack_start(self.klist, True, True, 0) hbox.show() for name, ctype in [(_(u'Units'), DeviceConstant.TYPE_UNIT), (_(u'Tax'), DeviceConstant.TYPE_TAX), (_(u'Payments'), DeviceConstant.TYPE_PAYMENT)]: self.klist.append(Settable(name=name, type=ctype)) self.klist.show() self._constant_slave = _DeviceConstantsList(self.store, self.printer) self._constant_slave.switch(DeviceConstant.TYPE_UNIT) hbox.pack_start(self._constant_slave.get_toplevel(), True, True, 0) # FIXME: redesign BasicDialog self.main.remove(self.main_label) self.main.add(hbox) hbox.show_all() def _on_klist__selection_changed(self, klist, selected): self._constant_slave.switch(selected.type)
def testExportFromObjectList(self): fruits = ObjectList( [Column('name', data_type=str), Column('price', data_type=int)]) for name, price in [('Apple', 4), ('Pineapple', 2), ('Kiwi', 8), ('Banana', 3), ('Melon', 5)]: fruits.append(Fruit(name, price)) ofx = XLSExporter() ofx.add_from_object_list(fruits) temp_file = ofx.save() data = open(temp_file.name).read() # We should use xlrd to 're-open' the spreadsheet and parse its content. self.assertTrue(len(data) > 0)
class Diary(ProxyDelegate): def __init__(self): self.entries = ObjectList([Column("title", width=120, sorted=True), Column("period", width=80), Column("text", expand=True, visible=False)]) ProxyDelegate.__init__(self, DiaryEntry(), ['title', 'period', 'text', 'chars', 'words'], gladefile="diary2.ui", delete_handler=self.quit_if_last) self.hbox.pack_start(self.entries, True, True, 0) self.entries.show() self.entries.grab_focus() self.set_editable(False) def set_editable(self, editable): self.leftbox.set_sensitive(editable) self.remove.set_sensitive(editable) def proxy_updated(self, *args): self.entries.update(self.model) def on_add__clicked(self, button): entry = DiaryEntry() entry.title = 'Untitled' self.entries.append(entry, select=True) self.set_editable(True) def on_remove__clicked(self, button): entry = self.entries.get_selected() if entry: self.entries.remove(entry, select=True) self.set_editable(len(self.entries) >= 1) if not len(self.entries): self.set_model(None) def on_text__content_changed(self, text): self.proxy.update_many(("chars", "words")) self.entries.update(self.model) def on_entries__selection_changed(self, entries, instance): if instance: self.set_model(instance) self.title.grab_focus()
class DeviceConstantsDialog(BasicDialog): size = (500, 300) def __init__(self, store, printer): self._constant_slave = None self.store = store self.printer = printer BasicDialog.__init__(self, hide_footer=False, title='edit', size=self.size) self.main.set_border_width(6) self._create_ui() def _create_ui(self): hbox = gtk.HBox() self.klist = ObjectList([Column('name')]) self.klist.set_size_request(150, -1) self.klist.get_treeview().set_headers_visible(False) self.klist.connect('selection-changed', self._on_klist__selection_changed) hbox.pack_start(self.klist) hbox.show() for name, ctype in [(_(u'Units'), DeviceConstant.TYPE_UNIT), (_(u'Tax'), DeviceConstant.TYPE_TAX), (_(u'Payments'), DeviceConstant.TYPE_PAYMENT)]: self.klist.append(Settable(name=name, type=ctype)) self.klist.show() self._constant_slave = _DeviceConstantsList(self.store, self.printer) self._constant_slave.switch(DeviceConstant.TYPE_UNIT) hbox.pack_start(self._constant_slave.get_toplevel()) # FIXME: redesign BasicDialog self.main.remove(self.main_label) self.main.add(hbox) hbox.show_all() def _on_klist__selection_changed(self, klist, selected): self._constant_slave.switch(selected.type)
def _create_field_list(self): items = ObjectList([ Column('description', width=200), Column('len', data_type=int, editable=True) ]) items.enable_dnd() items.set_size_request(200, -1) descriptions = {} invoice_fields = get_invoice_fields() for invoice_field in sorted(invoice_fields, key=operator.attrgetter('name')): items.append( Settable(description=invoice_field.get_description(), name=invoice_field.name, len=invoice_field.length)) descriptions[invoice_field.name] = invoice_field.description self._field_descriptions = descriptions self.left_vbox.pack_end(items, True, True) items.show()
class PropertiesAdminGtkNode(BaseAdminGtkNode): gladeFile = os.path.join('flumotion', 'component', 'base', 'properties.glade') uiStateHandlers = None _properties = {} def __init__(self, state, admin): BaseAdminGtkNode.__init__(self, state, admin, title=_("Properties")) def haveWidgetTree(self): self.widget = gtk.VBox() self.widget.set_border_width(6) self.properties = ObjectList( [Column('name'), Column('value')]) self.properties.set_size_request(-1, 200) self.widget.pack_start(self.properties, False, False) self.properties.show() self._reloadProperties(self.state.get('config')['properties']) return self.widget # IStateListener Interface def stateSet(self, object, key, value): if key == 'properties': self._reloadProperties(value) ### Private methods def _reloadProperties(self, properties): if properties is None: return self.properties.clear() propertyNames = properties.keys()[:] propertyNames.sort() for name in propertyNames: self.properties.append( Settable(name=name, value=properties[name]))
class Package(SlaveView): columns = [ Column("name", sorted=True), Column("version"), Column("installed"), Column("description") ] def __init__(self): self.list = ObjectList(self.columns) self.list.connect('selection-changed', self.info) self.to_install = "" # selecting categories f = urllib.urlopen("http://pacnet.karbownicki.com/api/category/app-accessibility/").read() packages=json.loads(f) for category in packages: got = local.check(category['name']) row = PackageItem(category['name'], category['version'], got, category['description']) self.list.append(row) SlaveView.__init__(self, self.list) def info(self, the_list, item): command = ["pacman", "-Si", item.name] pkg_info, errors = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() shell.get_widget("info").get_buffer().set_text(pkg_info) self.to_install = item.name def new_list(self, category): self.list.clear() f = urllib.urlopen("http://pacnet.karbownicki.com/api/category/%s/" % category).read() packages=json.loads(f) for category in packages: got = local.check(category['name']) row = PackageItem(category['name'], category['version'], got, category['description']) self.list.append(row)
class TodoView(PidaView): label_text = _("TODO") icon_name = "accessories-text-editor" def create_ui(self): self.todo_list = ObjectList([Column("line", sorted=True), Column("todo"), Column("marker")]) self.todo_list.connect("double-click", self._on_todo_double_click) self.add_main_widget(self.todo_list) self.todo_list.show_all() def clear_items(self): gcall(self.todo_list.clear) def add_item(self, todo, line, marker): self.todo_list.append(TodoItem(todo, line, marker)) def _on_todo_double_click(self, olist, item): self.svc.boss.editor.cmd("goto_line", line=item.line) def can_be_closed(self): self.svc.get_action("show_todo").set_active(False)
data = (Person('Evandro', 23, 'Belo Horizonte'), Person('Daniel', 22, 'São Carlos'), Person('Henrique', 21, 'São Carlos'), Person('Gustavo', 23, 'São Jose do Santos'), Person('Johan', 23, 'Göteborg'), Person('Lorenzo', 26, 'Granada')) win = Gtk.Window() win.set_size_request(850, 300) win.connect('destroy', Gtk.main_quit) vbox = Gtk.VBox() win.add(vbox) l = ObjectList(columns, mode=Gtk.SelectionMode.MULTIPLE) l.extend(data) l.append(Person('Nando', 29 + len(l), 'Santos')) # add an extra person vbox.pack_start(l, True, True, 0) label = SummaryLabel(klist=l, column='salary', label='<b>Total:</b>', value_format='<b>%s</b>') vbox.pack_start(label, False, True, 6) win.show_all() Gtk.main()
class ListContainer(Gtk.Box): """A ListContainer is an :class:`ObjectList` with buttons to be able to modify the content of the list. Depending on the list_mode, @see :class:`set_list_mode` you will have add, remove and edit buttons. Signals ======= - B{add-item} (returns item): - emitted when the add button is clicked, you're expected to return an object here - B{remove-item} (item, returns bool): - emitted when removing an item, you can block the removal from the list by returning False - B{edit-item} (item): - emitted when editing an item you can block the update afterwards by returning False :ivar add_button: add button :type add_button: :class:`Gtk.Button` :ivar remove_button: remove button :type remove_button: :class:`Gtk.Button` :ivar edit_button: edit button :type edit_button: :class:`Gtk.Button` """ __gtype_name__ = 'ListContainer' gsignal('add-item', retval=object) gsignal('remove-item', object, retval=bool) gsignal('edit-item', object, retval=bool) gsignal('selection-changed', object) def __init__(self, columns, orientation=Gtk.Orientation.VERTICAL): """ Create a new ListContainer object. :param columns: columns for the :class:`kiwi.ui.objectlist.ObjectList` :type columns: a list of :class:`kiwi.ui.objectlist.Columns` :param orientation: the position where the buttons will be placed: at the right (vertically) or at the bottom (horizontally) of the list. Defaults to the right of the list. :type: Gtk.Orientation.HORIZONTAL or Gtk.Orientation.VERTICAL """ self._list_type = None super(ListContainer, self).__init__(orientation=Gtk.Orientation.HORIZONTAL) self._orientation = orientation self._create_ui(columns) self.set_list_type(ListType.NORMAL) # Private API def _create_ui(self, columns): self.list = ObjectList(columns) self.list.connect('selection-changed', self._on_list__selection_changed) self.list.connect('row-activated', self._on_list__row_activated) self.add_button = Gtk.Button(stock=Gtk.STOCK_ADD) self.add_button.connect('clicked', self._on_add_button__clicked) self.remove_button = Gtk.Button(stock=Gtk.STOCK_REMOVE) self.remove_button.set_sensitive(False) self.remove_button.connect('clicked', self._on_remove_button__clicked) self.edit_button = Gtk.Button(stock=Gtk.STOCK_EDIT) self.edit_button.set_sensitive(False) self.edit_button.connect('clicked', self._on_edit_button__clicked) self._vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6) if self._orientation == Gtk.Orientation.VERTICAL: self.pack_start(self.list, True, True, 0) self.list.show() self._add_buttons_to_box(self._vbox) self._pack_vbox() elif self._orientation == Gtk.Orientation.HORIZONTAL: self._vbox.pack_start(self.list, True, True, 0) self.list.show() hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6) self._add_buttons_to_box(hbox) self._vbox.pack_start(hbox, False, True, 0) hbox.show() self._pack_vbox() else: raise TypeError( "buttons_orientation must be Gtk.Orientation.VERTICAL " " or Gtk.Orientation.HORIZONTAL") def _add_buttons_to_box(self, box): box.pack_start(self.add_button, False, True, 0) box.pack_start(self.remove_button, False, True, 0) box.pack_start(self.edit_button, False, True, 0) def _pack_vbox(self): self.pack_start(self._vbox, False, True, 6) self._vbox.show() def _set_child_packing(self, padding): expand = self._orientation == Gtk.Orientation.HORIZONTAL self.set_child_packing(self._vbox, expand, True, padding, Gtk.PackType.START) def _add_item(self): retval = self.emit('add-item') if retval is None: return elif isinstance(retval, NotImplementedError): raise retval self.list.append(retval) self.list.refresh() def _remove_item(self, item): retval = self.emit('remove-item', item) if retval: self.list.remove(item) def _edit_item(self, item): retval = self.emit('edit-item', item) if retval: self.list.update(item) # Public API def add_item(self, item): """Appends an item to the list :param item: item to append """ self.list.append(item) def add_items(self, items): """Appends a list of items to the list :param items: items to add :type items: a sequence of items """ self.list.extend(items) def remove_item(self, item): """Removes an item from the list :param item: item to remove """ self.list.remove(item) def update_item(self, item): """Updates an item in the list. You should call this if you change the object :param item: item to update """ self.list.update(item) def default_remove(self, item): """Asks the user confirmation for removal of an item. :param item: a description of the item that will be removed :returns: True if the user confirm the removal, False otherwise """ response = yesno(_('Do you want to remove %s ?') % (GLib.markup_escape_text(str(item)), ), parent=None, default=Gtk.ResponseType.OK, buttons=((Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL), (Gtk.STOCK_REMOVE, Gtk.ResponseType.OK))) return response == Gtk.ResponseType.OK def set_list_type(self, list_type): """Sets the kind of list type. :param list_type: """ if not isinstance(list_type, ListType): raise TypeError("list_type must be a ListType enum") self.add_button.set_property( 'visible', list_type not in [ ListType.READONLY, ListType.REMOVEONLY, ListType.UNADDABLE ]) self.remove_button.set_property( 'visible', list_type not in [ListType.READONLY, ListType.ADDONLY, ListType.UNREMOVABLE]) self.edit_button.set_property( 'visible', list_type not in [ ListType.READONLY, ListType.ADDONLY, ListType.UNEDITABLE, ListType.REMOVEONLY ]) if list_type in [ListType.READONLY, ListType.REMOVEONLY]: padding = 0 else: padding = 6 self._set_child_packing(padding) self._list_type = list_type def clear(self): """Removes all the items in the list""" self.list.clear() # Callbacks def _on_list__selection_changed(self, list, selection): object_selected = selection is not None self.remove_button.set_sensitive(object_selected) self.edit_button.set_sensitive(object_selected) self.emit('selection-changed', selection) def _on_list__row_activated(self, list, item): if self._list_type not in [ ListType.READONLY, ListType.ADDONLY, ListType.UNEDITABLE ]: self._edit_item(item) def _on_add_button__clicked(self, button): self._add_item() def _on_remove_button__clicked(self, button): self._remove_item(self.list.get_selected()) def _on_edit_button__clicked(self, button): self._edit_item(self.list.get_selected())
(AVAILABLE, SOLD_OUT, ROTTEN) = range(3) class Fruit: def __init__(self, name, status): self.name = name self.status = status fruits = ObjectList([Column('name', data_type=str), Column('status', title="Current status", data_type=FruitStatus, editable=True)]) for name, status in [('Apple', FruitStatus.AVAILABLE), ('Pineapple', FruitStatus.SOLD_OUT), ('Kiwi', FruitStatus.AVAILABLE), ('Banana', FruitStatus.ROTTEN), ('Melon', FruitStatus.AVAILABLE)]: fruits.append(Fruit(name, status)) window = gtk.Window() window.connect('delete-event', gtk.main_quit) window.set_title('Fruits') window.set_size_request(200, 180) window.add(fruits) window.show_all() gtk.main()
from gi.repository import Gtk from kiwi.ui.objectlist import Column, ObjectList class Fruit: def __init__(self, name, price): self.name = name self.price = price fruits = ObjectList([Column('name', data_type=str), Column('price', data_type=int)]) for name, price in [('Apple', 4), ('Pineapple', 2), ('Kiwi', 8), ('Banana', 3), ('Melon', 5)]: fruits.append(Fruit(name, price)) window = Gtk.Window() window.connect('delete-event', Gtk.main_quit) window.set_title('Fruits') window.set_size_request(150, 180) window.add(fruits) window.show_all() Gtk.main()
class MethodTest(unittest.TestCase): def setUp(self): self.klist = ObjectList([Column('name', sorted=True)], [Settable(name='first')]) def testNonZero(self): self.assertEqual(self.klist.__nonzero__(), True) self.klist.remove(self.klist[0]) self.assertEqual(self.klist.__nonzero__(), True) if not self.klist: raise AssertionError def testIter(self): for item1 in self.klist: pass for item2 in iter(self.klist): self.assertEqual(item1, item2) def testGetItem(self): self.klist.append(Settable(name='second')) model = self.klist.get_model() item1 = model[0][0] item2 = model[1][0] self.assertEqual(self.klist[0], item1) self.assertEqual(self.klist[:1], [item1]) self.assertEqual(self.klist[-1:], [item2]) self.assertRaises(TypeError, self.klist.__getitem__, None) def testSetItem(self): self.klist[0] = Settable(name='second') self.assertRaises(NotImplementedError, self.klist.__setitem__, slice(0), None) self.assertRaises(TypeError, self.klist.__setitem__, None, None) def testIndex(self): self.assertRaises(NotImplementedError, self.klist.index, 0, start=0) self.assertRaises(NotImplementedError, self.klist.index, 0, stop=0) self.assertEqual(self.klist.index(self.klist[0]), 0) self.assertRaises(ValueError, self.klist.index, None) def testCount(self): item = self.klist[0] self.assertEqual(self.klist.count(item), 1) self.klist.append(item) self.assertEqual(self.klist.count(item), 2) self.klist.clear() self.assertEqual(self.klist.count(item), 0) def testPop(self): self.assertRaises(NotImplementedError, self.klist.pop, None) def testReverse(self): self.assertRaises(NotImplementedError, self.klist.reverse, 1, 2) def testSort(self): self.assertRaises(NotImplementedError, self.klist.sort, 1, 2) def testSelectPath(self): self.klist.get_treeview().get_selection().set_mode(gtk.SELECTION_NONE) self.assertRaises(TypeError, self.klist.select_paths, (0,)) self.klist.get_treeview().get_selection().set_mode(gtk.SELECTION_SINGLE) self.klist.select_paths((0,)) def testSelect(self): self.klist.get_treeview().get_selection().set_mode(gtk.SELECTION_NONE) self.assertRaises(TypeError, self.klist.select, None) self.klist.get_treeview().get_selection().set_mode(gtk.SELECTION_SINGLE) def testGetSelected(self): item = self.klist[0] self.klist.select(item) self.klist.get_treeview().get_selection().set_mode(gtk.SELECTION_SINGLE) self.assertEqual(self.klist.get_selected(), item) def testGetSelectedRows(self): self.klist.get_treeview().get_selection().set_mode(gtk.SELECTION_MULTIPLE) item = self.klist[0] self.klist.select(item) self.assertEqual(self.klist.get_selected_rows(), [item]) def testGetNextAndPrevious(self): self.klist.append(Settable(name='second')) self.klist.append(Settable(name='third')) item1, item2, item3 = self.klist self.assertEqual(self.klist.get_next(item1), item2) self.assertEqual(self.klist.get_next(item2), item3) self.assertEqual(self.klist.get_next(item3), item1) self.assertRaises(ValueError, self.klist.get_next, None) self.assertEqual(self.klist.get_previous(item1), item3) self.assertEqual(self.klist.get_previous(item2), item1) self.assertEqual(self.klist.get_previous(item3), item2) self.assertRaises(ValueError, self.klist.get_previous, None) def testInsert(self): self.klist = ObjectList([Column('name')]) self.assertEqual(list(self.klist), []) self.klist.insert(0, Settable(name='one')) self.assertEqual(self.klist[0].name, 'one') self.klist.insert(0, Settable(name='two')) self.assertEqual(self.klist[0].name, 'two') self.assertEqual(self.klist[1].name, 'one') self.klist.insert(1, Settable(name='three')) self.assertEqual(self.klist[0].name, 'two') self.assertEqual(self.klist[1].name, 'three') self.assertEqual(self.klist[2].name, 'one')
class MethodTest(unittest.TestCase): def setUp(self): self.klist = ObjectList([Column('name', sorted=True)], [Settable(name='first')]) def testNonZero(self): self.assertEqual(self.klist.__nonzero__(), True) self.klist.remove(self.klist[0]) self.assertEqual(self.klist.__nonzero__(), True) if not self.klist: raise AssertionError def testIter(self): for item1 in self.klist: pass for item2 in iter(self.klist): self.assertEqual(item1, item2) def testGetItem(self): self.klist.append(Settable(name='second')) model = self.klist.get_model() item1 = model[0][0] item2 = model[1][0] self.assertEqual(self.klist[0], item1) self.assertEqual(self.klist[:1], [item1]) self.assertEqual(self.klist[-1:], [item2]) self.assertRaises(TypeError, self.klist.__getitem__, None) def testSetItem(self): self.klist[0] = Settable(name='second') self.assertRaises(NotImplementedError, self.klist.__setitem__, slice(0), None) self.assertRaises(TypeError, self.klist.__setitem__, None, None) def testIndex(self): self.assertRaises(NotImplementedError, self.klist.index, 0, start=0) self.assertRaises(NotImplementedError, self.klist.index, 0, stop=0) self.assertEqual(self.klist.index(self.klist[0]), 0) self.assertRaises(ValueError, self.klist.index, None) def testCount(self): item = self.klist[0] self.assertEqual(self.klist.count(item), 1) self.klist.append(item) self.assertEqual(self.klist.count(item), 2) self.klist.clear() self.assertEqual(self.klist.count(item), 0) def testPop(self): self.assertRaises(NotImplementedError, self.klist.pop, None) def testReverse(self): self.assertRaises(NotImplementedError, self.klist.reverse, 1, 2) def testSort(self): self.assertRaises(NotImplementedError, self.klist.sort, 1, 2) def testSelectPath(self): self.klist.get_treeview().get_selection().set_mode( Gtk.SelectionMode.NONE) self.assertRaises(TypeError, self.klist.select_paths, (0, )) self.klist.get_treeview().get_selection().set_mode( Gtk.SelectionMode.SINGLE) self.klist.select_paths((0, )) def testSelect(self): self.klist.get_treeview().get_selection().set_mode( Gtk.SelectionMode.NONE) self.assertRaises(TypeError, self.klist.select, None) self.klist.get_treeview().get_selection().set_mode( Gtk.SelectionMode.SINGLE) def testGetSelected(self): item = self.klist[0] self.klist.select(item) self.klist.get_treeview().get_selection().set_mode( Gtk.SelectionMode.SINGLE) self.assertEqual(self.klist.get_selected(), item) def testGetSelectedRows(self): self.klist.get_treeview().get_selection().set_mode( Gtk.SelectionMode.MULTIPLE) item = self.klist[0] self.klist.select(item) self.assertEqual(self.klist.get_selected_rows(), [item]) def testGetNextAndPrevious(self): self.klist.append(Settable(name='second')) self.klist.append(Settable(name='third')) item1, item2, item3 = self.klist self.assertEqual(self.klist.get_next(item1), item2) self.assertEqual(self.klist.get_next(item2), item3) self.assertEqual(self.klist.get_next(item3), item1) self.assertRaises(ValueError, self.klist.get_next, None) self.assertEqual(self.klist.get_previous(item1), item3) self.assertEqual(self.klist.get_previous(item2), item1) self.assertEqual(self.klist.get_previous(item3), item2) self.assertRaises(ValueError, self.klist.get_previous, None) def testInsert(self): self.klist = ObjectList([Column('name')]) self.assertEqual(list(self.klist), []) self.klist.insert(0, Settable(name='one')) self.assertEqual(self.klist[0].name, 'one') self.klist.insert(0, Settable(name='two')) self.assertEqual(self.klist[0].name, 'two') self.assertEqual(self.klist[1].name, 'one') self.klist.insert(1, Settable(name='three')) self.assertEqual(self.klist[0].name, 'two') self.assertEqual(self.klist[1].name, 'three') self.assertEqual(self.klist[2].name, 'one')
from kiwi.ui.objectlist import Column, ObjectList class Fruit: def __init__(self, icon, name): self.icon = icon self.name = name fruits = ObjectList([Column('icon', use_stock=True, justify=gtk.JUSTIFY_CENTER, icon_size=gtk.ICON_SIZE_LARGE_TOOLBAR), Column('name', column='icon')]) for icon, name in [(gtk.STOCK_OK, 'Apple'), (gtk.STOCK_CANCEL, 'Pineapple'), (gtk.STOCK_HELP, 'Kiwi'), (gtk.STOCK_DELETE, 'Banana'), (gtk.STOCK_HOME, 'Melon')]: fruits.append(Fruit(icon, name)) window = gtk.Window() window.connect('delete-event', gtk.main_quit) window.set_title('Fruits') window.set_size_request(150, 180) window.add(fruits) window.show_all() gtk.main()
import gtk from kiwi.ui.objectlist import Column, ObjectList class Fruit: def __init__(self, name, cost): self.name = name self.cost = cost fruits = ObjectList([Column('name', data_type=str, editable=True, expand=True), Column('cost', data_type=int, editable=True)]) for name, cost in [('Apple', 4), ('Pineapple', 2), ('Kiwi', 8), ('Banana', 3), ('Melon', 5)]: fruits.append(Fruit(name, cost)) window = gtk.Window() window.connect('delete-event', gtk.main_quit) window.set_title('Editable Fruit List') window.set_size_request(230, 150) window.add(fruits) window.show_all() gtk.main()
class DataTests(unittest.TestCase): """In all this tests we use the same configuration for a list""" def setUp(self): self.win = gtk.Window() self.win.set_default_size(400, 400) self.list = ObjectList([Column('name'), Column('age')]) self.win.add(self.list) refresh_gui() def tearDown(self): self.win.destroy() del self.win def testAddingOneInstance(self): # we should have two columns now self.assertEqual(2, len(self.list.get_columns())) person = Person('henrique', 21) self.list.append(person) refresh_gui() # usually you don't use the model directly, but tests are all about # breaking APIs, right? self.assertEqual(self.list[0], person) self.assertEqual(self.list[0].name, 'henrique') self.assertEqual(self.list[0].age, 21) # we still have to columns, right? self.assertEqual(2, len(self.list.get_columns())) def testAddingAObjectList(self): global persons self.list.add_list(persons) refresh_gui() self.assertEqual(len(self.list), len(persons)) def testAddingABunchOfInstances(self): global persons for person in persons: self.list.append(person) refresh_gui() self.assertEqual(len(self.list), len(persons)) def testRemovingOneInstance(self): global persons self.list.add_list(persons) refresh_gui() # we are going to remove Kiko person = persons[2] self.list.remove(person) self.assertEqual(len(self.list), len(persons) - 1) # now let's remove something that is not on the list #new_person = Person('Evandro', 24) #self.assertRaises(ValueError, self.list.remove, new_person) # note that even a new person with the same values as a person # in the list is not considered to be in the list #existing_person = Person('Gustavo', 25) #self.assertRaises(ValueError, self.list.remove, # existing_person) def testClearObjectList(self): global persons self.list.add_list(persons) refresh_gui() self.list.clear() self.assertEqual(len(self.list), 0) def testUpdatingOneInstance(self): global persons self.list.add_list(persons) refresh_gui() persons[0].age = 29 self.list.update(persons[0]) refresh_gui() # Do we have the same number of instances that we had before ? self.assertEqual(len(self.list), len(persons)) # Trying to find our updated instance in the list self.assertEqual(self.list[0].age, 29) # let's be evil new_person = Person('Nando', 32) self.assertRaises(ValueError, self.list.update, new_person) def testContains(self): global persons self.list.add_list(persons) self.assertEqual(persons[0] in self.list, True) new_person = Person('Nando', 32) self.assertEqual(new_person in self.list, False) def testSelect(self): first = persons[0] self.list.add_list(persons) self.list.select(first) self.assertEqual(self.list.get_selected(), first) self.list.remove(first) self.assertRaises(ValueError, self.list.select, first)
class PylintView(GladeDelegate, BaseReporter): """ A dokuwiki editor window """ mapping = {'E':'error', 'W':'warning', 'C':'low'} def __init__(self): self.icons = {} GladeDelegate.__init__(self, gladefile="lintgtk", delete_handler=self.quit_if_last) self.setup_sourceview() self.setup_side() self.throbber_icon = Throbber(self.view.throbber) self.show_all() def setup_config(self): """ Setup configuration file. """ nomondir = os.path.join(user.home,'.pylintgtk') if not os.path.exists(nomondir): os.mkdir(nomondir) cfg = FileDataSource(file=os.path.join(nomondir,'config.caf')) cfg.save() return cfg # quit override to work with twisted def quit_if_last(self, *_): """ Quit if we're the last window. """ windows = [toplevel for toplevel in gtk.window_list_toplevels() if toplevel.get_property('type') == gtk.WINDOW_TOPLEVEL] if len(windows) == 1: reactor.stop() def setup_sourceview(self): """ Setup the source editor. """ self.buffer = gtksourceview.Buffer() tagtable = self.buffer.get_tag_table() setup_tags(tagtable) lang_manager = gtksourceview.LanguageManager() lang = lang_manager.get_language('python') self.buffer.set_language(lang) self.editor = gtksourceview.View(self.buffer) accel_group = gtk.AccelGroup() self.get_toplevel().add_accel_group(accel_group) self.editor.add_accelerator("paste-clipboard", accel_group, ord('v'), gtk.gdk.CONTROL_MASK, 0) self.editor.add_accelerator("copy-clipboard", accel_group, ord('c'), gtk.gdk.CONTROL_MASK, 0) self.editor.add_accelerator("cut-clipboard", accel_group, ord('x'), gtk.gdk.CONTROL_MASK, 0) self.editor.set_left_margin(5) self.editor.set_right_margin(5) self.editor.set_show_line_marks(True) self.editor.set_show_line_numbers(True) self.editor.set_auto_indent(True) self.editor.set_insert_spaces_instead_of_tabs(True) self.editor.set_highlight_current_line(True) self.editor.set_indent_width(4) self.editor.set_indent_on_tab(True) path = environ.find_resource('images', 'red-warning.png') high = gtk.gdk.pixbuf_new_from_file(path) path = environ.find_resource('images', 'violet-warning.png') medium = gtk.gdk.pixbuf_new_from_file(path) path = environ.find_resource('images', 'yellow-warning.png') low = gtk.gdk.pixbuf_new_from_file(path) self.icons["low"] = low self.icons["warning"] = medium self.icons["error"] = high self.editor.set_mark_category_pixbuf('error', high) self.editor.set_mark_category_pixbuf('warning', medium) self.editor.set_mark_category_pixbuf('low', low) self.view.scrolledwindow1.add(self.editor) # setup functions def format_icon(self, value): """ return appropriate icon for kiwi. """ priority = self.mapping.get(value[0], 'low') return self.icons[priority] def setup_side(self): """ Setup the side statistics. """ columns = [Column('code', data_type=gtk.gdk.Pixbuf, format_func=self.format_icon, title=""), Column('line', sorted=True), Column('message'), Column('object'), Column('code')] self.problemlist = ObjectList(columns) self.view.side_vbox.pack_start(gtk.Label('Violations:'), False, False) self.view.side_vbox.add(self.problemlist) self.problemlist.connect("selection-changed", self.problem_selected) self.view.side_vbox.pack_start(gtk.Label('Stats:'), False, False) self.statslist = ObjectList([Column('name'), Column('value')]) #self.backlinks.connect("selection-changed", self.change_selected) self.view.side_vbox.add(self.statslist) def problem_selected(self, _, violation): """ A violation was selected on the objectlist. """ if not violation: return start = self.buffer.get_iter_at_line(violation.line-1) end = self.buffer.get_iter_at_line(violation.line-1) end.forward_to_line_end() self.buffer.place_cursor(start) self.editor.scroll_to_iter(start, 0.1) self.buffer.select_range(start, end) def load_file(self, filename): """ Load and check a file. """ self.linter = lint.PyLinter() self.linter.set_reporter(self) checkers.initialize(self.linter) source_file = open(filename, 'r') text = source_file.read() source_file.close() self.buffer.set_property('text', text) self.linecount = self.buffer.get_line_count() self.text = text self.lastfilename = filename self.check() def set_score(self, value): """ Set the score widget value. """ scoretext = "<big><big><big>%s</big></big></big>" % (value,) self.view.score.set_markup(scoretext) def _check_done(self, _): """ A pylint check has finished. """ self.set_score("%.1f"%(self.linter.stats['global_note'],)) self.view.comments.set_value(self.linter.stats['comment_lines']) self.view.lines.set_value(self.linter.stats['code_lines']) for key, value in self.linter.stats.iteritems(): if value.__class__ in [int, str, float]: self.statslist.append(Stat(key.replace("_"," "), value)) self.throbber_icon.stop() self.view.progressbar.set_fraction(1.0) def _check_error(self, failure): """ There was an error doing the pylint check. """ print self, failure def check(self): """ Perform a check on current file. """ self.view.progressbar.set_fraction(0.0) self.set_score('?') self.throbber_icon.start() self.idx = 0 self.linter = lint.PyLinter() self.linter.set_reporter(self) checkers.initialize(self.linter) deferred = threads.deferToThread(self.linter.check, self.lastfilename) deferred.addCallback(self._check_done) deferred.addErrback(self._check_error) def on_button_save__clicked(self, _): """ Kiwi callback for the save button. """ text = self.buffer.get_property('text') sourcefile = open(self.lastfilename, 'w') sourcefile.write(text) sourcefile.close() self.linecount = self.buffer.get_line_count() while self.idx > 0: mark = self.buffer.get_mark(str(self.idx-1)) if mark: self.buffer.delete_mark(mark) self.idx -= 1 self.idx = 0 self.problemlist.clear() self.statslist.clear() start, end = self.buffer.get_bounds() self.buffer.remove_source_marks(start, end, 'violation') self.buffer.remove_tag_by_name('violation', start, end) self.check() def _display(self, layout): """ Necessary for pylint.BaseReporter """ pass def add_message(self, msg_id, opts, msg): """ A message arrived from the checker thread. """ reactor.callFromThread(self.add_message_main, msg_id, opts, msg) def add_message_main(self, msg_id, opts, msg): """ Main thread callback for a message arriving from pylint. """ _, _, obj, line = opts self.problemlist.append(ViolationReport(code=msg_id, icon=msg_id, line=line, object=obj, message=msg)) startiter = self.buffer.get_iter_at_line(line-1) enditer = self.buffer.get_iter_at_line(line-1) enditer.forward_to_line_end() self.buffer.apply_tag_by_name('violation', startiter, enditer) fraction = self.linter.stats['statement'] / float(self.linecount) self.view.progressbar.set_fraction(fraction) priority = self.mapping.get(msg_id[0], 'low') self.buffer.create_source_mark(str(self.idx), priority, startiter) self.idx += 1
Person('Daniel', 22, 'São Carlos'), Person('Henrique', 21, 'São Carlos'), Person('Gustavo', 23, 'São Jose do Santos'), Person('Johan', 23, 'Göteborg'), Person('Lorenzo', 26, 'Granada') ) win = gtk.Window() win.set_size_request(850, 300) win.connect('destroy', gtk.main_quit) vbox = gtk.VBox() win.add(vbox) l = ObjectList(columns, mode=gtk.SELECTION_MULTIPLE) l.extend(data) l.append(Person('Nando', 29+len(l), 'Santos')) # add an extra person vbox.pack_start(l) label = SummaryLabel(klist=l, column='salary', label='<b>Total:</b>', value_format='<b>%s</b>') vbox.pack_start(label, expand=False, padding=6) win.show_all() gtk.main()
import gtk from kiwi.ui.objectlist import Column, ObjectList class Fruit: def __init__(self, name, price): self.name = name self.price = price fruits = ObjectList([ Column('name', data_type=str, sorted=True), Column('price', data_type=int) ]) for name, price in [('Kiwi', 8), ('Apple', 4), ('Pineapple', 2), ('Banana', 3), ('Melon', 5)]: fruits.append(Fruit(name, price)) window = gtk.Window() window.connect('delete-event', gtk.main_quit) window.set_title('Fruits') window.set_size_request(150, 180) window.add(fruits) window.show_all() gtk.main()
class Fruit: def __init__(self, name, status): self.name = name self.status = status adjustment = Gtk.Adjustment(step_incr=1, upper=15) fruits = ObjectList([ Column('name', data_type=str), Column('quantity', title="Quantity", spin_adjustment=adjustment, data_type=float, editable=True) ]) fruits.set_spinbutton_digits('quantity', 3) for name, quantity in [('Apple', 1), ('Pineapple', 2), ('Kiwi', 3), ('Banana', 4), ('Melon', 6)]: fruits.append(Fruit(name, quantity)) window = Gtk.Window() window.connect('delete-event', Gtk.main_quit) window.set_title('Fruits') window.set_size_request(200, 180) window.add(fruits) window.show_all() Gtk.main()
class ListContainer(gtk.HBox): """A ListContainer is an L{ObjectList} with buttons to be able to modify the content of the list. Depending on the list_mode, @see L{set_list_mode} you will have add, remove and edit buttons. Signals ======= - B{add-item} (returns item): - emitted when the add button is clicked, you're expected to return an object here - B{remove-item} (item, returns bool): - emitted when removing an item, you can block the removal from the list by returning False - B{edit-item} (item): - emitted when editing an item you can block the update afterwards by returning False @ivar add_button: add button @type add_button: L{gtk.Button} @ivar remove_button: remove button @type remove_button: L{gtk.Button} @ivar edit_button: edit button @type edit_button: L{gtk.Button} """ gsignal('add-item', retval=object) gsignal('remove-item', object, retval=bool) gsignal('edit-item', object, retval=bool) gsignal('selection-changed', object) def __init__(self, columns, orientation=gtk.ORIENTATION_VERTICAL): """ Create a new ListContainer object. @param columns: columns for the L{kiwi.ui.objectlist.ObjectList} @type columns: a list of L{kiwi.ui.objectlist.Columns} @param orientation: the position where the buttons will be placed: at the right (vertically) or at the bottom (horizontally) of the list. Defaults to the right of the list. @type: gtk.ORIENTATION_HORIZONTAL or gtk.ORIENTATION_VERTICAL """ self._list_type = None gtk.HBox.__init__(self) self._orientation = orientation self._create_ui(columns) self.set_list_type(ListType.NORMAL) # Private API def _create_ui(self, columns): self.list = ObjectList(columns) self.list.connect('selection-changed', self._on_list__selection_changed) self.list.connect('row-activated', self._on_list__row_activated) self.add_button = gtk.Button(stock=gtk.STOCK_ADD) self.add_button.connect('clicked', self._on_add_button__clicked) self.remove_button = gtk.Button(stock=gtk.STOCK_REMOVE) self.remove_button.set_sensitive(False) self.remove_button.connect('clicked', self._on_remove_button__clicked) self.edit_button = gtk.Button(stock=gtk.STOCK_EDIT) self.edit_button.set_sensitive(False) self.edit_button.connect('clicked', self._on_edit_button__clicked) self._vbox = gtk.VBox(spacing=6) if self._orientation == gtk.ORIENTATION_VERTICAL: self.pack_start(self.list) self.list.show() self._add_buttons_to_box(self._vbox) self._pack_vbox() elif self._orientation == gtk.ORIENTATION_HORIZONTAL: self._vbox.pack_start(self.list) self.list.show() hbox = gtk.HBox(spacing=6) self._add_buttons_to_box(hbox) self._vbox.pack_start(hbox, expand=False) hbox.show() self._pack_vbox() else: raise TypeError( "buttons_orientation must be gtk.ORIENTATION_VERTICAL " " or gtk.ORIENTATION_HORIZONTAL") def _add_buttons_to_box(self, box): box.pack_start(self.add_button, expand=False) box.pack_start(self.remove_button, expand=False) box.pack_start(self.edit_button, expand=False) def _pack_vbox(self): self.pack_start(self._vbox, expand=False, padding=6) self._vbox.show() def _set_child_packing(self, padding): expand = self._orientation == gtk.ORIENTATION_HORIZONTAL self.set_child_packing(self._vbox, expand, True, padding, gtk.PACK_START) def _add_item(self): retval = self.emit('add-item') if retval is None: return elif isinstance(retval, NotImplementedError): raise retval self.list.append(retval) def _remove_item(self, item): retval = self.emit('remove-item', item) if retval: self.list.remove(item) def _edit_item(self, item): retval = self.emit('edit-item', item) if retval: self.list.update(item) # Public API def add_item(self, item): """Appends an item to the list @param item: item to append """ self.list.append(item) def add_items(self, items): """Appends a list of items to the list @param items: items to add @type items: a sequence of items """ self.list.extend(items) def remove_item(self, item): """Removes an item from the list @param item: item to remove """ self.list.remove(item) def update_item(self, item): """Updates an item in the list. You should call this if you change the object @param item: item to update """ self.list.update(item) def default_remove(self, item): """Asks the user confirmation for removal of an item. @param item: a description of the item that will be removed @returns: True if the user confirm the removal, False otherwise """ response = yesno(_('Do you want to remove %s ?') % (quote(str(item)),), parent=None, default=gtk.RESPONSE_OK, buttons=((gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL), (gtk.STOCK_REMOVE, gtk.RESPONSE_OK))) return response == gtk.RESPONSE_OK def set_list_type(self, list_type): """Sets the kind of list type. @param list_type: """ if not isinstance(list_type, ListType): raise TypeError("list_type must be a ListType enum") self.add_button.set_property( 'visible', (list_type != ListType.READONLY and list_type != ListType.REMOVEONLY and list_type != ListType.UNADDABLE)) self.remove_button.set_property( 'visible', (list_type != ListType.READONLY and list_type != ListType.UNREMOVABLE)) self.edit_button.set_property( 'visible', (list_type != ListType.READONLY and list_type != ListType.UNEDITABLE and list_type != ListType.REMOVEONLY)) if list_type in [ListType.READONLY, ListType.REMOVEONLY]: padding = 0 else: padding = 6 self._set_child_packing(padding) self._list_type = list_type def clear(self): """Removes all the items in the list""" self.list.clear() # Callbacks def _on_list__selection_changed(self, list, selection): object_selected = selection is not None self.remove_button.set_sensitive(object_selected) self.edit_button.set_sensitive(object_selected) self.emit('selection-changed', selection) def _on_list__row_activated(self, list, item): if (self._list_type != ListType.READONLY and self._list_type != ListType.UNEDITABLE): self._edit_item(item) def _on_add_button__clicked(self, button): self._add_item() def _on_remove_button__clicked(self, button): self._remove_item(self.list.get_selected()) def _on_edit_button__clicked(self, button): self._edit_item(self.list.get_selected())
class ListContainer(gtk.HBox): """A ListContainer is an L{ObjectList} with buttons to be able to modify the content of the list. Depending on the list_mode, @see L{set_list_mode} you will have add, remove and edit buttons. Signals ======= - B{add-item} (returns item): - emitted when the add button is clicked, you're expected to return an object here - B{remove-item} (item, returns bool): - emitted when removing an item, you can block the removal from the list by returning False - B{edit-item} (item): - emitted when editing an item you can block the update afterwards by returning False @ivar add_button: add button @type add_button: L{gtk.Button} @ivar remove_button: remove button @type remove_button: L{gtk.Button} @ivar edit_button: edit button @type edit_button: L{gtk.Button} """ gsignal('add-item', retval=object) gsignal('remove-item', object, retval=bool) gsignal('edit-item', object, retval=bool) gsignal('selection-changed', object) def __init__(self, columns, orientation=gtk.ORIENTATION_VERTICAL): """ Create a new ListContainer object. @param columns: columns for the L{kiwi.ui.objectlist.ObjectList} @type columns: a list of L{kiwi.ui.objectlist.Columns} @param orientation: the position where the buttons will be placed: at the right (vertically) or at the bottom (horizontally) of the list. Defaults to the right of the list. @type: gtk.ORIENTATION_HORIZONTAL or gtk.ORIENTATION_VERTICAL """ self._list_type = None gtk.HBox.__init__(self) self._orientation = orientation self._create_ui(columns) self.set_list_type(ListType.NORMAL) # Private API def _create_ui(self, columns): self.list = ObjectList(columns) self.list.connect('selection-changed', self._on_list__selection_changed) self.list.connect('row-activated', self._on_list__row_activated) self.add_button = gtk.Button(stock=gtk.STOCK_ADD) self.add_button.connect('clicked', self._on_add_button__clicked) self.remove_button = gtk.Button(stock=gtk.STOCK_REMOVE) self.remove_button.set_sensitive(False) self.remove_button.connect('clicked', self._on_remove_button__clicked) self.edit_button = gtk.Button(stock=gtk.STOCK_EDIT) self.edit_button.set_sensitive(False) self.edit_button.connect('clicked', self._on_edit_button__clicked) self._vbox = gtk.VBox(spacing=6) if self._orientation == gtk.ORIENTATION_VERTICAL: self.pack_start(self.list) self.list.show() self._add_buttons_to_box(self._vbox) self._pack_vbox() elif self._orientation == gtk.ORIENTATION_HORIZONTAL: self._vbox.pack_start(self.list) self.list.show() hbox = gtk.HBox(spacing=6) self._add_buttons_to_box(hbox) self._vbox.pack_start(hbox, expand=False) hbox.show() self._pack_vbox() else: raise TypeError( "buttons_orientation must be gtk.ORIENTATION_VERTICAL " " or gtk.ORIENTATION_HORIZONTAL") def _add_buttons_to_box(self, box): box.pack_start(self.add_button, expand=False) box.pack_start(self.remove_button, expand=False) box.pack_start(self.edit_button, expand=False) def _pack_vbox(self): self.pack_start(self._vbox, expand=False, padding=6) self._vbox.show() def _set_child_packing(self, padding): expand = self._orientation == gtk.ORIENTATION_HORIZONTAL self.set_child_packing(self._vbox, expand, True, padding, gtk.PACK_START) def _add_item(self): retval = self.emit('add-item') if retval is None: return elif isinstance(retval, NotImplementedError): raise retval self.list.append(retval) def _remove_item(self, item): retval = self.emit('remove-item', item) if retval: self.list.remove(item) def _edit_item(self, item): retval = self.emit('edit-item', item) if retval: self.list.update(item) # Public API def add_item(self, item): """Appends an item to the list @param item: item to append """ self.list.append(item) def add_items(self, items): """Appends a list of items to the list @param items: items to add @type items: a sequence of items """ self.list.extend(items) def remove_item(self, item): """Removes an item from the list @param item: item to remove """ self.list.remove(item) def update_item(self, item): """Updates an item in the list. You should call this if you change the object @param item: item to update """ self.list.update(item) def default_remove(self, item): """Asks the user confirmation for removal of an item. @param item: a description of the item that will be removed @returns: True if the user confirm the removal, False otherwise """ response = yesno(_('Do you want to remove %s ?') % (quote(str(item)), ), parent=None, default=gtk.RESPONSE_OK, buttons=((gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL), (gtk.STOCK_REMOVE, gtk.RESPONSE_OK))) return response == gtk.RESPONSE_OK def set_list_type(self, list_type): """Sets the kind of list type. @param list_type: """ if not isinstance(list_type, ListType): raise TypeError("list_type must be a ListType enum") self.add_button.set_property('visible', (list_type != ListType.READONLY and list_type != ListType.REMOVEONLY and list_type != ListType.UNADDABLE)) self.remove_button.set_property( 'visible', (list_type != ListType.READONLY and list_type != ListType.UNREMOVABLE)) self.edit_button.set_property('visible', (list_type != ListType.READONLY and list_type != ListType.UNEDITABLE and list_type != ListType.REMOVEONLY)) if list_type in [ListType.READONLY, ListType.REMOVEONLY]: padding = 0 else: padding = 6 self._set_child_packing(padding) self._list_type = list_type def clear(self): """Removes all the items in the list""" self.list.clear() # Callbacks def _on_list__selection_changed(self, list, selection): object_selected = selection is not None self.remove_button.set_sensitive(object_selected) self.edit_button.set_sensitive(object_selected) self.emit('selection-changed', selection) def _on_list__row_activated(self, list, item): if (self._list_type != ListType.READONLY and self._list_type != ListType.UNEDITABLE): self._edit_item(item) def _on_add_button__clicked(self, button): self._add_item() def _on_remove_button__clicked(self, button): self._remove_item(self.list.get_selected()) def _on_edit_button__clicked(self, button): self._edit_item(self.list.get_selected())
class PlayMediaWindow(Delegate): widgets = ["imgAddMediaFile"] def __init__(self, parent, recentPlayed=None): windowName = "PlayMediaWindow" Delegate.__init__(self, gladefile=globals.gladeFile, toplevel_name=windowName, delete_handler=self.quit_if_last) # Create the delegate and set it up self.buildObjectList(recentPlayed) self.mediaList.grab_focus() slave = SlaveDelegate(toplevel=self.mediaList) self.attach_slave("labelX", slave) slave.focus_toplevel() # Must be done after attach self.slave = slave self.set_transient_for(parent) # Set the image image = self.get_widget("imgAddMediaFile") image.set_from_file( os.path.join(globals.imageDir, "movie_track_add.png")) def buildObjectList(self, mediaList): """ This method builds and initialize the ObjectList. """ self.mediaList = ObjectList(media_list_columns) self.mediaList.connect('selection_changed', self.media_selected) self.mediaList.connect('double-click', self.double_click) for media in mediaList: mf = MediaFile(media.getFilename(), uri=media.getURI(), length=media.getLengthSec()) mf.lastPlayed = media.getLastPlayed() self.mediaList.append(mf) # FIXME: Remove it. Only for testing #for i in [('test1.wmv', "2.34"), # ('test2.wmv', "2.59"), # ('test3.wmv', "2.59"), # ('test4.wmv', "2.59")]: # self.mediaList.append(MediaFile(i[0], i[1])) def media_selected(self, the_list, item): pass def double_click(self, the_list, selected_object): self.emit('result', selected_object.uri) self.hide_and_quit() def on_bCancel__clicked(self, *args): """ This method is called when the user clicks the Cancel button. It closes the dialog. """ self.hide_and_quit() def on_bQuit__clicked(self, *args): """ This method is called when the user clicks the Quit button. It closes the dialog and quits Morphin. """ self.emit('result', 'quit') self.hide_and_quit() def on_bPlayMedia__clicked(self, *args): """ This method is called when the user clicks the Play Media button. """ dialog = gtk.FileChooserDialog("Open Media...", None, gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK)) dialog.set_default_response(gtk.RESPONSE_OK) filter = gtk.FileFilter() filter.set_name("Media files") for pattern in globals.compatibleFiles: filter.add_mime_type(pattern) dialog.add_filter(filter) filter = gtk.FileFilter() filter.set_name("All files") filter.add_pattern("*") dialog.add_filter(filter) response = dialog.run() if response == gtk.RESPONSE_OK: self.emit('result', dialog.get_filename()) self.hide_and_quit() elif response == gtk.RESPONSE_CANCEL: pass dialog.destroy() def on_bPlayDisk__clicked(self, *args): """ """ pass def onKeyPressEvent(self, widget=None, event=None): """ """ pass
class Fruit: def __init__(self, icon, name): self.icon = icon self.name = name fruits = ObjectList([ Column('icon', use_stock=True, justify=Gtk.Justification.CENTER, icon_size=Gtk.IconSize.LARGE_TOOLBAR), Column('name', column='icon') ]) for icon, name in [(Gtk.STOCK_OK, 'Apple'), (Gtk.STOCK_CANCEL, 'Pineapple'), (Gtk.STOCK_HELP, 'Kiwi'), (Gtk.STOCK_DELETE, 'Banana'), (Gtk.STOCK_HOME, 'Melon')]: fruits.append(Fruit(icon, name)) window = Gtk.Window() window.connect('delete-event', Gtk.main_quit) window.set_title('Fruits') window.set_size_request(150, 180) window.add(fruits) window.show_all() Gtk.main()
class ChecklistView(PidaView): key = 'checklist.view' icon_name = 'gtk-todo' label_text = _('Check list') def create_ui(self): self._vbox = gtk.VBox(spacing=3) self._vbox.set_border_width(3) self.create_toolbar() self.create_newitem() self.create_list() self.add_main_widget(self._vbox) self._vbox.show_all() def create_tab_label(self, icon_name, text): if None in [icon_name, text]: return None label = gtk.Label(text) b_factory = gtk.HBox b = b_factory(spacing=2) icon = gtk.image_new_from_stock(icon_name, gtk.ICON_SIZE_MENU) b.pack_start(icon) b.pack_start(label) b.show_all() return b def create_list(self): self._list = ObjectList([ Column('done', title=_('Done'), data_type=bool, editable=True), Column('title', title=_('Title'), data_type=str, editable=True, expand=True), Column('priority', title=_('Priority'), data_type=ChecklistStatus, editable=True) ]) self._list.connect('cell-edited', self._on_item_edit) self._list.connect('selection-changed', self._on_item_selected) self._list.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self._vbox.add(self._list) self._sort_combo = AttrSortCombo(self._list, [ ('done', _('Done')), ('title', _('Title')), ('priority', _('Priority')), ], 'title') self._vbox.pack_start(self._sort_combo, expand=False) self._list.show_all() self._sort_combo.show_all() def create_newitem(self): self._hbox = gtk.HBox(spacing=3) self._newitem_title = gtk.Entry() self._newitem_title.connect('changed', self._on_newitem_changed) self._newitem_ok = gtk.Button(stock=gtk.STOCK_ADD) self._newitem_ok.connect('clicked', self._on_item_add) self._newitem_ok.set_sensitive(False) self._hbox.pack_start(self._newitem_title, expand=True) self._hbox.pack_start(self._newitem_ok, expand=False) self._vbox.pack_start(self._hbox, expand=False) self._hbox.show_all() def create_toolbar(self): self._uim = gtk.UIManager() self._uim.insert_action_group(self.svc.get_action_group(), 0) uim_data = pkgutil.get_data(__name__, 'uidef/checklist-toolbar.xml') self._uim.add_ui_from_string(uim_data) self._uim.ensure_update() self._toolbar = self._uim.get_toplevels('toolbar')[0] self._toolbar.set_style(gtk.TOOLBAR_ICONS) self._toolbar.set_icon_size(gtk.ICON_SIZE_SMALL_TOOLBAR) self._vbox.pack_start(self._toolbar, expand=False) self.svc.get_action('checklist_del').set_sensitive(False) self._toolbar.show_all() def add_item(self, item): self._list.append(item, select=True) self.svc.save() def update_item(self, item): self._list.update(item) self.svc.save() def remove_item(self, item): self._list.remove(item) self.svc.save() def clear(self): self._list.clear() def _on_item_selected(self, olist, item): self.svc.get_action('checklist_del').set_sensitive(item is not None) self.svc.set_current(item) def _on_item_edit(self, olist, item, value): self.svc.save() def _on_item_add(self, w): title = self._newitem_title.get_text() self.svc.add_item(ChecklistItem(title=title)) self._newitem_title.set_text('') def _on_newitem_changed(self, w): self._newitem_ok.set_sensitive(self._newitem_title.get_text() != '') def can_be_closed(self): self.svc.get_action('show_checklist').set_active(False)
class Display: """This is the main window class.""" def __init__(self, cache_directory, username, password): """cache_directory is the directory to store downloaded data in, username is the JID to login with, password is the password used to log in.""" # Make a connection self.jid = username self.password = password self.client = pubsubclient.PubSubClient(self.jid, self.password) # Make the window self.draw_window() def draw_window(self): """Display related things.""" # Make a window and split it into sections self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) self.hpaned = gtk.HPaned() self.window.add(self.hpaned) self.right_vpaned = gtk.VPaned() self.hpaned.pack2(self.right_vpaned) self.left_vbox = gtk.VBox() self.hpaned.pack1(self.left_vbox) # Make a Kiwi ObjectList with columns "name" and "count" for # subscription names and the name_column = Column('name', 'Name') name_column.expand = True unread_column = Column('unread', 'Unread') count_column = Column('count', 'Total') self.node_list = ObjectList([name_column, unread_column, count_column]) self.left_vbox.pack_start(self.node_list) self.add_button = gtk.Button(stock=gtk.STOCK_ADD) self.add_button.set_label("New Subscription") self.add_button.connect("released", self.add_released) self.left_vbox.pack_end(self.add_button, expand=False) title_column = Column('title') author_column = Column('author') date_column = Column('date') title_column.expand = True self.entry_list = ObjectList([title_column, author_column, date_column]) self.right_vpaned.pack1(self.entry_list) #self.webscroll = gtk.ScrolledWindow() #self.webview = webkit.WebView() #self.webscroll.add(self.webview) #self.right_vpaned.pack2(self.webscroll) self.window.show_all() def disable_subscribe_button(self, args): """Makes the subscribe button in the add-new-subscription dialogue insensitive.""" self.add_window['add_button'].set_sensitive(False) def subscribe_to_node(self, args): """Subscribes the logged in account to the node selected in the add-new-subscription dialogue.""" self.add_window['node_list'].get_selected().subscribe(self.client, self.jid, return_function=self.subscription_finished) def subscription_finished(self, reply): """Handles replies to subscription requests.""" print 'Reply received"' if reply.find(".//error") is not None: print "Error subscribing" elif reply.find(".//result") is not None: print "Subscription successful!" # Close the new-subscription dialogue self.add_window['window'].destroy() # Add the subscribed-to node to the list of subscriptions self.node_list.append(LeftRow("test", 0, 0)) def add_released(self, args): """Run when the "Subscribe" button is pressed.""" # Make a place to store all of the new GTK stuff self.add_window = {} # Make the Add Node window and put it in there self.add_window['window'] = gtk.Window() self.add_window['window'].set_title("Add New Subscription") # Split it vertically self.add_window['vbox'] = gtk.VBox() self.add_window['window'].add(self.add_window['vbox']) # Split the top horizontally self.add_window['top_hbox'] = gtk.HBox() self.add_window['vbox'].pack_start(self.add_window['top_hbox'], expand=False) # Add the "Location:" label to the top self.add_window['location_label'] = gtk.Label("Location: ") self.add_window['top_hbox'].pack_start(self.add_window['location_label'], expand=False) # Add the "Find" button to the top self.add_window['find_button'] = gtk.Button(label="Find", stock=gtk.STOCK_FIND) self.add_window['find_button'].connect("released", self.find_new_nodes) self.add_window['top_hbox'].pack_end(self.add_window['find_button'], expand=False) # Add the location entry box in between self.add_window['location_entry'] = gtk.Entry() self.add_window['top_hbox'].pack_end(self.add_window['location_entry'], expand=True) self.add_window['bottom_hbox'] = gtk.HBox() self.add_window['vbox'].pack_end(self.add_window['bottom_hbox'], expand=False) self.add_window['find_progress'] = gtk.ProgressBar() self.add_window['bottom_hbox'].pack_end(self.add_window['find_progress'], expand=True) self.add_window['add_button'] = gtk.Button(label="Subscribe", stock=gtk.STOCK_ADD) self.add_window['add_button'].set_label("Subscribe") ## FIXME: The Subscribe button should be insensitive to start ## with, then activate when a node is selected. #self.add_window['add_button'].set_sensitive(False) self.add_window['add_button'].connect("released", self.subscribe_to_node) self.add_window['bottom_hbox'].pack_end(self.add_window['add_button'], expand=False) # Add the list of found nodes self.add_window['name_column'] = Column('name', 'Name') self.add_window['location_column'] = Column('name', 'Location') self.add_window['name_column'].expand = True self.add_window['location_column'].expand = True self.add_window['node_list'] = ObjectList([self.add_window['name_column'], self.add_window['location_column']]) self.add_window['vbox'].pack_end(self.add_window['node_list'], expand=True, fill=True) # Display everything self.add_window['window'].show_all() def pulse_find_progress(self): """Updates the progress bar when finding new nodes.""" # Sleep here so that we aren't checking for replies constantly time.sleep(0.05) # Do the pulsing self.add_window['find_progress'].pulse() # Return whether we're still searching return self.finding def find_new_nodes(self, arg): """Search for nodes at the server entered in the add-new-subscription window.""" self.add_window["entered_server"] = pubsubclient.Server(name=self.add_window['location_entry'].get_text()) self.client.get_nodes(self.add_window["entered_server"], None, return_function=self.found_new_nodes) # Remember that we're still on the lookout for nodes self.finding = True gobject.idle_add(self.pulse_find_progress) def found_new_nodes(self, reply): """The program waits until this is run. Could be more elegant using a signal though""" # We don't need to search any more self.finding = False # Run the following if we end up with a failure if reply == "error": # Reset the search progress self.add_window['find_progress'].set_fraction(0.0) # Tell the user we've failed to find anything due to an error self.add_window['find_progress'].set_text('Error finding nodes at ' + self.add_window['location_entry'].get_text()) # Run the following if we end up with a success else: # Traverse the nodes we've received for node in reply: # Add each one to the add-subscription-dialogue's list self.add_window['node_list'].append(node) # Get any children of the discovered nodes node.get_sub_nodes(self.client, self.found_new_nodes) # We're now finding for children, so keep up the search self.finding = True # Display the new window contents self.add_window['window'].show_all() def connect(self): """Connect the account given during initialisation.""" # Try to connect connected = self.client.connect() # Check if we succeeded if connected == 1: print 'Failed to connect, exiting' sys.exit(1) self.connected = True # Process new messages when there's nothing else to do gobject.idle_add(self.idle_process) self.client.retrieve_subscriptions(self.jid.getDomain(), return_function=self.subscriptions_received) def subscriptions_received(self, subscriptions): """Handles replies to retrieve_subscriptions.""" def add_nodes(self, nodes): """Adds the given nodes to the subscribed list.""" for node in nodes: if node not in self.node_list: self.node_list.append(LeftRow(node.name, 0, 0)) def handle_incoming(self, stanza): #os.popen("mkdir -p pages/") #while True: # filename = ''.join(Random().sample(string.letters+string.digits, 16)) # if filename not in os.listdir("pages"): break #page_file = open("pages/" + filename, 'w') #page = Element('html') #head = SubElement(page, 'head') #css_link = SubElement(head, 'link', attrib={"rel":"stylesheet", "type":"text/css", "href":os.getcwd() + "/page_settings/test1/item.css"}) #body = SubElement(page, 'body') #wholediv = SubElement(body, 'div', attrib={'class':'whole'}) #titlediv = SubElement(wholediv, 'div', attrib={"class":"title"}) #maindiv = SubElement(wholediv, 'div', attrib={"class":"main"}) #for event in stanza.xpath("//e:event", namespaces={"e":"http://jabber.org/protocol/pubsub#event"}): # for item_node in event.xpath("//i:items", namespaces={"i":"http://jabber.org/protocol/pubsub#event"}): # title = SubElement(titlediv, 'a') # title.text = "TITLE: " + item_node.get("node") # body_text = SubElement(maindiv, 'a') # body_text.text = "MAIN: " + item_node.get("node") #page_file.write(etree.tostring(page)) #page_file.close() #self.webview.open(os.getcwd() + "/pages/" + filename) pass def process(self): """Handle any pending XMPP events.""" self.client.process() def idle_process(self): """Check for new messages. Good to run in gobject idle time.""" # It's a good idea to wait a bit betweeen updates, to stop # overworking the machine time.sleep(0.1) # Do the processing self.process() # Idle functions stop being called when they return False, in # this case when we disconnect return self.connected def destroy(self, widget, data=None): """Close the program""" gtk.main_quit() def main(self): """Initialises and starts the GTK main loop.""" #gobject.idle_add(self.idle_process) self.window.connect("destroy", self.destroy) self.client.assign_message_handler(self.handle_incoming) gtk.main()
class VirtLabView(BaseView): ''' MVC View ''' def __init__(self, model): self.__model = model #self.__model.set_view(self) BaseView.__init__(self, gladefile="virtlab", delete_handler=self.quit_if_last) # self.__col_pixbuf = gtk.TreeViewColumn("Image") # cellrenderer_pixbuf = gtk.CellRendererPixbuf() # cellrenderer_pixbuf.set_properties("pixbuf", ) # self.__col_pixbuf.pack_start(cellrenderer_pixbuf, False) # self.__col_pixbuf.add_attribute(cellrenderer_pixbuf, "pixbuf", 1) tableColumns = [ Column("image", title=" ", width=30, data_type=gtk.gdk.Pixbuf, sorted=False), Column("name", title='VM Name', width=130, sorted=True), Column("state", title='State', width=70), Column("order", title='Order (Delay/min)', width=145), Column("ordinal", visible=False), Column("delay", visible=False), Column("desc", title='Description', width=200) ] self.vmlist_widget = ObjectList(tableColumns) self.vmlist_widget.set_size_request(300, 400) self.vmlist_widget.set_selection_mode(gtk.SELECTION_SINGLE) self.hbox4.pack_start(self.vmlist_widget) store = gtk.ListStore(gobject.TYPE_STRING) self.vmlist_widget.show() self.__dialog = None self.__status_text = gtk.TextBuffer() try: self.populate_vmlist() self.populate_order_dropdown(store, len(self.__model.get_vms())) except VMLabException as exception: if exception.vme_id is c.EXCEPTION_LIBVIRT_001: error("Initialization error", "No connection to Libvirtd.\n Exiting.") exit(1) self.ordercombo.set_model(store) cell = gtk.CellRendererText() self.ordercombo.pack_start(cell, True) self.ordercombo.add_attribute(cell, 'text', 0) self.virtlab.set_size_request(800, 460) self.change_title("") self.__statusbar_ctx = self.statusbar.get_context_id("virtlab") self.virtlab.set_icon(gtk.gdk.pixbuf_new_from_file("pixmaps/about-logo.png")) def __delaystring(self, delay): if delay > 0: return " (" + str(delay) + ")" else: return "" def change_title(self, value): if value == "" or None: self.virtlab.set_title(c.WINDOW_TITLE) else: self.virtlab.set_title(c.WINDOW_TITLE + "(" + value + ")") def dialog_filechooser_open(self): chooser = gtk.FileChooserDialog(title="Open VMLab Project", action=gtk.FILE_CHOOSER_ACTION_OPEN, buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK)) chooser.set_default_response(gtk.RESPONSE_OK) filter = gtk.FileFilter() filter.add_pattern("*"+c.SAVE_FILE_SUFFIX) chooser.set_filter(filter) file_name = "" response = chooser.run() if response == gtk.RESPONSE_OK: file_name = chooser.get_filename() chooser.destroy() return file_name elif response == gtk.RESPONSE_CANCEL: chooser.destroy() return def dialog_filechooser_save(self): chooser = gtk.FileChooserDialog(title="Save VMLab Project", action=gtk.FILE_CHOOSER_ACTION_SAVE, buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK)) chooser.set_default_response(gtk.RESPONSE_CANCEL) filter = gtk.FileFilter() filter.add_pattern("*"+c.SAVE_FILE_SUFFIX) file_name = "" response = chooser.run() if response == gtk.RESPONSE_OK: file_name = chooser.get_filename() chooser.destroy() return file_name elif response == gtk.RESPONSE_CANCEL: chooser.destroy() return elif response == gtk.RESPONSE_CLOSE: chooser.destroy() return def populate_vmlist(self): ''' Populates view with current status ''' self.vmlist_widget.clear() for vm_instance in self.__model.get_vms(): self.vmlist_widget.append(Settable(image=populate_image(vm_instance.get_state()), name=vm_instance.get_name(), state=vm_instance.get_state().get_state_str(), order=self.get_display_order(vm_instance.get_order()) + self.__delaystring(vm_instance.get_delay()), ordinal=vm_instance.get_order(), delay=vm_instance.get_delay(), desc=vm_instance.get_desc())) def populate_order_dropdown(self, list_store, vm_count): list_store.clear() list_store.append([""]) if vm_count > 0: for num in range(1, vm_count + 1): list_store.append([self.get_display_order(num)]) def add_status_dialogbox(self, text): field_content = self.__status_text.get_text(self.__status_text.get_start_iter(), self.__status_text.get_end_iter(), False) field_content += strftime("%d %b %Y %H:%M:%S", localtime()) + " " + text + "\n" self.__status_text.set_text(field_content) def clear_dialog_log(self): self.__status_text.set_text("") def show_dialog(self): self.__dialog = gtk.Dialog(title="Launch status", parent=self.virtlab, flags=gtk.DIALOG_MODAL, buttons=None) self.__dialog.set_position(gtk.WIN_POS_CENTER_ON_PARENT) self.__dialog.set_transient_for(self.virtlab) close_button = gtk.Button("Close window") terminate_button = gtk.Button("Terminate") clear_button = gtk.Button("Clear log") start_button = gtk.Button("Launch scheduled") start_once_button = gtk.Button("Launch all once") close_button.connect("clicked", lambda d, r: r.destroy(), self.__dialog) clear_button.connect("clicked", lambda d, r: r.clear_dialog_log(), self) terminate_button.connect("clicked", self.controller.hook_dialog_terminate_clicked, None) start_button.connect("clicked", self.controller.hook_dialog_start_clicked, None) start_once_button.connect("clicked", self.controller.hook_dialog_all_start_clicked, None) scrolled_window = gtk.ScrolledWindow(hadjustment=None, vadjustment=None) scrolled_window.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS) text_view = gtk.TextView() scrolled_window.add_with_viewport(text_view) scrolled_window.show() text_view.set_buffer(self.__status_text) # pylint: disable=E1101 self.__dialog.action_area.pack_start(start_button, True, True, 0) self.__dialog.action_area.pack_start(start_once_button, True, True, 0) self.__dialog.action_area.pack_start(clear_button, True, True, 0) self.__dialog.action_area.pack_start(terminate_button, True, True, 0) self.__dialog.action_area.pack_start(close_button, True, True, 0) self.__dialog.vbox.pack_start(scrolled_window, True, True, 0) scrolled_window.set_size_request(500, 200) start_button.show() start_once_button.show() terminate_button.show() close_button.show() clear_button.show() text_view.show() self.__dialog.show() text_view.set_editable(False) text_view.set_cursor_visible(False) def show_about(self): about = gtk.AboutDialog() about.set_program_name("Virtual Lab Manager") about.set_version("1.0 RC") import os path = os.path.dirname(virtlab.__file__) f = open(path + '/LICENCE', 'r') about.set_license(f.read()) about.set_copyright("GPLv3, (c) Authors") about.set_logo(gtk.gdk.pixbuf_new_from_file("pixmaps/about-logo.png")) about.set_authors(["Harri Savolainen", "Esa Elo"]) about.set_comments("Virtual Machine lab tool") about.set_website("https://github.com/hsavolai/vmlab") about.run() about.hide() def dialog_overwrite(self): response = messagedialog(gtk.MESSAGE_QUESTION, "File exists, overwrite?", None, self.toplevel, gtk.BUTTONS_OK_CANCEL ) if response == gtk.RESPONSE_OK: return True return False def dialog_file_error(self, error_msg): messagedialog(gtk.MESSAGE_ERROR, "File operation failed!", error_msg, self.toplevel, gtk.BUTTONS_OK ) def set_statusbar(self, value): #self.statusbar.remove_all(self.__statusbar_ctx) self.statusbar.pop(self.__statusbar_ctx) self.statusbar.push(self.__statusbar_ctx, value) @staticmethod def get_display_order(number): if number is 0: return "" upper_suffixes = { "11": "th", "12": "th", "13": "th" } lower_suffixes = { "1": "st", "2": "nd", "3": "rd", } digits = str(number) if digits[-2:] in upper_suffixes: return digits + upper_suffixes[digits[-2:]] if digits[-1:] in lower_suffixes: return digits + lower_suffixes[digits[-1:]] else: return digits + "th"
from gi.repository import Gtk from kiwi.ui.objectlist import Column, ObjectList class Fruit: def __init__(self, name, cost): self.name = name self.cost = cost fruits = ObjectList([ Column('name', data_type=str, editable=True, expand=True), Column('cost', data_type=int, editable=True) ]) for name, cost in [('Apple', 4), ('Pineapple', 2), ('Kiwi', 8), ('Banana', 3), ('Melon', 5)]: fruits.append(Fruit(name, cost)) window = Gtk.Window() window.connect('delete-event', Gtk.main_quit) window.set_title('Editable Fruit List') window.set_size_request(230, 150) window.add(fruits) window.show_all() Gtk.main()
from gi.repository import Gtk from kiwi.ui.objectlist import Column, ObjectList class Object: def __init__(self, name, value): self.name, self.value = name, value columns = [ Column('name'), Column('value', data_type=bool, radio=True, editable=True) ] win = Gtk.Window() win.set_size_request(300, 120) win.connect('delete-event', Gtk.main_quit) list = ObjectList(columns) win.add(list) for name, value in [('First', False), ('Second', False), ('Third', True), ('Fourth', False), ('Fifth', False)]: list.append(Object(name, value)) win.show_all() Gtk.main()
class DVBServiceInformationAdminGtkNode(BaseAdminGtkNode): channels = {} siwidget = None def render(self): def returnWidget(res): return self.siwidget self.siwidget = ObjectList([Column('programnumber', 'Program Number', data_type=str), Column('name', data_type=str), Column('whatson', 'What\'s On', data_type=str)]) whatsontvcolumn = self.siwidget.get_treeview_column(\ self.siwidget.get_column_by_name('whatson')) import pango for renderer in whatsontvcolumn.get_cell_renderers(): renderer.set_property('wrap-width', 200) renderer.set_property('wrap-mode', pango.WRAP_WORD) self.widget = self.siwidget d = BaseAdminGtkNode.render(self) d.addCallback(returnWidget) return d def setUIState(self, state): BaseAdminGtkNode.setUIState(self, state) self._watcher = _StateWatcher(state, { 'channelnames': self._setChannelName, 'whatson': self._setWhatsOn, }, {}, {}, setitemers={ 'channelnames': self._setChannelNameItem, 'whatson': self._setWhatsOnItem, }, delitemers={ 'channelnames': self._delChannelNameItem, 'whatson': self._delWhatsOnItem, }) self._watcher.show() for chan in self.channels: self.siwidget.append(chan) def _setChannelName(self, state, value): if value is None: return for k, v in value.items(): self._setChannelNameItem(state, k, v) def _setChannelNameItem(self, state, key, value): self.debug("set channel name item %s:%s", key, value) if key in self.channels: chan = self.channels[key] chan.set_name(value) else: self.channels[key] = DVBChannel(key, value) if self.siwidget: self.siwidget.append(self.channels[key]) def _delChannelNameItem(self, state, key, value): pass def _setWhatsOn(self, state, value): if value is None: return for k, v in value.items(): self._setWhatsOnItem(state, k, v) def _setWhatsOnItem(self, state, key, value): if key in self.channels: chan = self.channels[key] chan.set_whatson(value) else: chan = DVBChannel(key, "") chan.set_whatson(value) self.channels[key] = chan if self.siwidget: self.siwidget.append(chan) def _delWhatsOnItem(self, state, key, value): pass
class DataTests(unittest.TestCase): """In all this tests we use the same configuration for a list""" def setUp(self): self.win = Gtk.Window() self.win.set_default_size(400, 400) self.list = ObjectList([Column('name'), Column('age')]) self.win.add(self.list) refresh_gui() def tearDown(self): self.win.destroy() del self.win def testAddingOneInstance(self): # we should have two columns now self.assertEqual(2, len(self.list.get_columns())) person = Person('henrique', 21) self.list.append(person) refresh_gui() # usually you don't use the model directly, but tests are all about # breaking APIs, right? self.assertEqual(self.list[0], person) self.assertEqual(self.list[0].name, 'henrique') self.assertEqual(self.list[0].age, 21) # we still have to columns, right? self.assertEqual(2, len(self.list.get_columns())) def testAddingAObjectList(self): global persons self.list.add_list(persons) refresh_gui() self.assertEqual(len(self.list), len(persons)) def testAddingABunchOfInstances(self): global persons for person in persons: self.list.append(person) refresh_gui() self.assertEqual(len(self.list), len(persons)) def testRemovingOneInstance(self): global persons self.list.add_list(persons) refresh_gui() # we are going to remove Kiko person = persons[2] self.list.remove(person) self.assertEqual(len(self.list), len(persons) - 1) # now let's remove something that is not on the list #new_person = Person('Evandro', 24) #self.assertRaises(ValueError, self.list.remove, new_person) # note that even a new person with the same values as a person # in the list is not considered to be in the list #existing_person = Person('Gustavo', 25) #self.assertRaises(ValueError, self.list.remove, # existing_person) def testClearObjectList(self): global persons self.list.add_list(persons) refresh_gui() self.list.clear() self.assertEqual(len(self.list), 0) def testUpdatingOneInstance(self): global persons self.list.add_list(persons) refresh_gui() persons[0].age = 29 self.list.update(persons[0]) refresh_gui() # Do we have the same number of instances that we had before ? self.assertEqual(len(self.list), len(persons)) # Trying to find our updated instance in the list self.assertEqual(self.list[0].age, 29) # let's be evil new_person = Person('Nando', 32) self.assertRaises(ValueError, self.list.update, new_person) def testContains(self): global persons self.list.add_list(persons) self.assertEqual(persons[0] in self.list, True) new_person = Person('Nando', 32) self.assertEqual(new_person in self.list, False) def testSelect(self): first = persons[0] self.list.add_list(persons) self.list.select(first) self.assertEqual(self.list.get_selected(), first) self.list.remove(first) self.assertRaises(ValueError, self.list.select, first)
class BookmarkView(PidaView): icon_name = 'gtk-library' label_text = _('Bookmarks') def create_ui(self): self._vbox = gtk.VBox() self.create_toolbar() self.create_ui_list() self.add_main_widget(self._vbox) self._vbox.show_all() def create_tab_label(self, icon_name, text): if None in [icon_name, text]: return None label = gtk.Label(text) b_factory = gtk.HBox b = b_factory(spacing=2) icon = gtk.image_new_from_stock(icon_name, gtk.ICON_SIZE_MENU) b.pack_start(icon) b.pack_start(label) b.show_all() return b def create_ui_list(self): self._books = gtk.Notebook() self._books.set_border_width(6) self._list_dirs = ObjectList([Column('markup', data_type=str, use_markup=True)]) self._list_dirs.connect('row-activated', self._on_item_activated) self._list_dirs.connect('selection-changed', self._on_item_selected) self._list_dirs.set_headers_visible(False) self._list_dirs.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self._books.append_page(self._list_dirs, tab_label=self.create_tab_label('stock_folder', _('Dirs'))) self._list_files = ObjectList([Column('markup', data_type=str, use_markup=True)]) self._list_files.connect('row-activated', self._on_item_activated) self._list_files.connect('selection-changed', self._on_item_selected) self._list_files.set_headers_visible(False) self._list_files.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self._books.append_page(self._list_files, tab_label=self.create_tab_label('text-x-generic', _('Files'))) """ self._list_url = ObjectList([Column('markup', data_type=str, use_markup=True)]) self._list_url.set_headers_visible(False) self._books.add(self._list_url) """ self._vbox.add(self._books) self._books.show_all() def create_toolbar(self): self._uim = gtk.UIManager() self._uim.insert_action_group(self.svc.get_action_group(), 0) self._uim.add_ui_from_file(get_uidef_path('bookmark-toolbar.xml')) self._uim.ensure_update() self._toolbar = self._uim.get_toplevels('toolbar')[0] self._toolbar.set_style(gtk.TOOLBAR_ICONS) self._toolbar.set_icon_size(gtk.ICON_SIZE_SMALL_TOOLBAR) self._vbox.pack_start(self._toolbar, expand=False) self._toolbar.show_all() def add_item(self, item): if item.group == 'file': self._list_files.append(item) elif item.group == 'path': self._list_dirs.append(item) elif item.group == 'url': self._list_urls.append(item) def remove_item(self, item): if item.group == 'file': self._list_files.remove(item) elif item.group == 'path': self._list_dirs.remove(item) elif item.group == 'url': self._list_urls.remove(item) def clear_all(self): self._list_files.clear() self._list_dirs.clear() #self._list_urls.clear() def can_be_closed(self): self.svc.get_action('show_bookmark').set_active(False) def _on_item_selected(self, olist, item): self.svc.set_current(item) def _on_item_activated(self, olist, item): item.run(self.svc)
class Fruit: def __init__(self, name, status): self.name = name self.status = status fruits = ObjectList([ Column('name', data_type=str), Column('status', title="Current status", data_type=FruitStatus, editable=True) ]) for name, status in [('Apple', FruitStatus.AVAILABLE), ('Pineapple', FruitStatus.SOLD_OUT), ('Kiwi', FruitStatus.AVAILABLE), ('Banana', FruitStatus.ROTTEN), ('Melon', FruitStatus.AVAILABLE)]: fruits.append(Fruit(name, status)) window = gtk.Window() window.connect('delete-event', gtk.main_quit) window.set_title('Fruits') window.set_size_request(200, 180) window.add(fruits) window.show_all() gtk.main()