def testRadioWithoutTrue(self): olist = ObjectList( [Column('foo', radio=True, data_type=bool, editable=True)]) column = olist.get_treeview().get_column(0) renderer = column.get_cells()[0] items = [Settable(foo=False) for i in range(5)] olist.add_list(items) self.assertEqual(items[0].foo, False) renderer.emit('toggled', 0) self.assertEqual(items[0].foo, True)
def testRadioWithoutTrue(self): olist = ObjectList( [Column('foo', radio=True, data_type=bool, editable=True)]) column = olist.get_treeview().get_column(0) renderer = column.get_cell_renderers()[0] items = [Settable(foo=False) for i in range(5)] olist.add_list(items) self.assertEqual(items[0].foo, False) renderer.emit('toggled', 0) self.assertEqual(items[0].foo, True)
class ListSlave(SlaveDelegate): def __init__(self, parent): self.parent = parent self.news_list = ObjectList([ Column('title', 'Title of article', str), Column('author', 'Author of article', str), Column('url', 'Address of article', str)]) SlaveDelegate.__init__(self, toplevel=self.news_list) self.news_list.add_list(news) self.news_list.select(self.news_list[0]) def on_news_list__selection_changed(self, list, item): print("%s %s %s\n" % (item.title, item.author, item.url)) def on_news_list__double_click(self, the_list, selected_object): self.parent.ok.clicked()
class ListSlave(SlaveDelegate): def __init__(self, parent): self.parent = parent self.news_list = ObjectList([ Column('title', 'Title of article', str), Column('author', 'Author of article', str), Column('url', 'Address of article', str)]) SlaveDelegate.__init__(self, toplevel=self.news_list) self.news_list.add_list(news) self.news_list.select(self.news_list[0]) def on_news_list__selection_changed(self, list, item): print "%s %s %s\n" % (item.title, item.author, item.url) def on_news_list__double_click(self, the_list, selected_object): self.parent.ok.clicked()
NewsItem("Smallpox Vaccinations for EVERYONE", "JRoyale", "http://www.pigdog.org/auto/Power_Corrupts/link/2700.html"), NewsItem("Is that uranium in your pocket or are you just happy to see me?", "Baron Earl", "http://www.pigdog.org/auto/bad_people/link/2699.html"), NewsItem("Cut 'n Paste", "Baron Earl", "http://www.pigdog.org/auto/ArtFux/link/2690.html"), NewsItem("A Slippery Exit", "Reverend CyberSatan", "http://www.pigdog.org/auto/TheCorporateFuck/link/2683.html"), NewsItem("Those Crazy Dutch Have Resurrected Elvis", "Miss Conduct", "http://www.pigdog.org/auto/viva_la_musica/link/2678.html") ] # Specify the columns: one for each attribute of NewsItem, the URL # column invisible by default my_columns = [Column("title", sorted=True), Column("author", justify=Gtk.Justification.RIGHT), Column("url", title="URL", visible=False)] objectlist = ObjectList(my_columns) objectlist.add_list(news) w = Gtk.Window() w.connect('delete-event', Gtk.main_quit) w.set_size_request(600, 250) w.add(objectlist) w.show_all() Gtk.main()
class DokuwikiView(GladeDelegate): """ A dokuwiki editor window """ def __init__(self): GladeDelegate.__init__(self, gladefile="pydoku", delete_handler=self.quit_if_last) self.setup_wikitree() self.setup_attachments() self.setup_side() self.setup_sourceview() self.setup_htmlview() self.page_edit = self.view.notebook1.get_nth_page(0) self.page_view = self.view.notebook1.get_nth_page(1) self.page_attach = self.view.notebook1.get_nth_page(2) self.show_all() def quit_if_last(self, *args): self.htmlview.destroy() # for some reason has to be deleted explicitly GladeDelegate.quit_if_last(self) # general interface functions def post(self, text): id = self.view.statusbar.get_context_id("zap") self.view.statusbar.push(id, text) # setup functions def setup_side(self): columns = ['user', 'sum', 'type', 'version', 'ip'] columns = [Column(s) for s in columns] self.versionlist = ObjectList(columns) self.view.side_vbox.pack_start(gtk.Label('Version Log:'), False, False) self.view.side_vbox.add(self.versionlist) self.view.side_vbox.pack_start(gtk.Label('BackLinks:'), False, False) self.backlinks = ObjectList([Column('name')]) self.view.side_vbox.add(self.backlinks) def setup_attachments(self): columns = ['id', 'size', 'lastModified', 'writable', 'isimg', 'perms'] columns = [Column(s) for s in columns] self.attachmentlist = ObjectList(columns) self.view.attachments_vbox.add(self.attachmentlist) def setup_wikitree(self): columns = ['name', 'id', 'lastModified', 'perms', 'size'] columns = [Column(s) for s in columns] self.objectlist = ObjectTree(columns) self.objectlist.connect("selection-changed", self.selected) self.view.vbox2.add(self.objectlist) def setup_htmlview(self): self.htmlview = gtkmozembed.MozEmbed() self.view.html_scrolledwindow.add(self.htmlview) self.htmlview.realize() self.htmlview.show() def setup_sourceview(self): self.buffer = DokuwikiBuffer(table) self.editor = gtksourceview.SourceView(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 = gtk.TextView(self.buffer) self.editor.set_left_margin(5) self.editor.set_right_margin(5) self.editor.set_wrap_mode(gtk.WRAP_WORD_CHAR) self.view.scrolledwindow1.add(self.editor) # dokuwiki operations def get_version(self): version = self._rpc.dokuwiki.getVersion() self.view.version.set_text(version) def get_pagelist(self): pages = self._rpc.wiki.getAllPages() self._sections = {} self.objectlist.clear() for page in pages: self.add_page(page) self.view.new_page.set_sensitive(True) self.view.delete_page.set_sensitive(True) def get_attachments(self, ns): attachments = self._rpc.wiki.getAttachments(ns, {}) attachments = [DictWrapper(s) for s in attachments] self.attachmentlist.add_list(attachments) def get_backlinks(self, pagename): backlinks = self._rpc.wiki.getBackLinks(pagename) backlinks = [Section(s) for s in backlinks] self.backlinks.add_list(backlinks) def get_versions(self, pagename): versionlist = self._rpc.wiki.getPageVersions(pagename, 0) versionlist = [DictWrapper(s) for s in versionlist] self.versionlist.add_list(versionlist) def get_htmlview(self, pagename): text = self._rpc.wiki.getPageHTML(pagename) self.htmlview.render_data(text, len(text), self.url.get_text(), 'text/html') # XXX following is for gtkhtml (not used) #self.document.clear() #self.document.open_stream('text/html') #self.document.write_stream(text) #self.document.close_stream() def put_page(self, text, summary, minor): pars = {} if summary: pars['sum'] = summary if minor: pars['minor'] = minor self._rpc.wiki.putPage(self.current, text, pars) if not self.current in self._sections: self.add_page({"id":self.current}) # put a page into the page tree def add_page(self, page): name = page["id"] path = name.split(":") prev = None for i,pathm in enumerate(path): if i == len(path)-1: # a page new = DictWrapper(page, pathm) self._sections[name] = new self.objectlist.append(prev, new, False) else: # a namespace part_path = ":".join(path[:i+1]) if not part_path in self._sections: new = Section(pathm, part_path) self._sections[part_path] = new self.objectlist.append(prev, new, False) else: new = self._sections[part_path] prev = new # page selected callback def selected(self, widget, object): if not object: return if isinstance(object, Section): self.get_attachments(object.id) if not isinstance(object, DictWrapper): return text = self._rpc.wiki.getPage(object.id) self.current = object.id self.buffer.add_text(text) self.get_htmlview(self.current) self.get_backlinks(object.id) self.get_versions(object.id) # kiwi interface callbacks def on_view_edit__toggled(self, widget): if widget.get_active(): self.notebook1.insert_page(self.page_edit, gtk.Label('edit'), 0) else: self.notebook1.remove_page(self.notebook1.page_num(self.page_edit)) def on_view_view__toggled(self, widget): if widget.get_active(): self.notebook1.insert_page(self.page_view, gtk.Label('view'), 1) else: self.notebook1.remove_page(self.notebook1.page_num(self.page_view)) def on_view_attachments__toggled(self, widget): if widget.get_active(): self.notebook1.insert_page(self.page_attach, gtk.Label('attach')) else: self.notebook1.remove_page(self.notebook1.page_num(self.page_attach)) def on_view_extra__toggled(self, widget): if widget.get_active(): self.backlinks.show() self.versionlist.show() self.view.hpaned2.set_position(self._prevpos) else: self.backlinks.hide() self.versionlist.hide() self._prevpos = self.view.hpaned2.get_position() self.view.hpaned2.set_position(self.view.hpaned2.allocation.width) def on_button_list__clicked(self, *args): self.post("Connecting...") dialog = ModalDialog("User Details") # prepare widgets = {} items = ["user", "password"] for i,item in enumerate(items): widgets[item] = gtk.Entry() if i == 1: widgets[item].set_visibility(False) hbox = gtk.HBox() hbox.pack_start(gtk.Label(item+': ')) hbox.add(widgets[item]) dialog.vbox.add(hbox) dialog.show_all() # run response = dialog.run() user = widgets['user'].get_text() password = widgets['password'].get_text() dialog.destroy() if not response == gtk.RESPONSE_ACCEPT: return # following commented line is for gtkhtml (not used) #simplebrowser.currentUrl = self.view.url.get_text() # handle response params = urlencode({'u':user,'p':password}) fullurl = self.view.url.get_text() + "/lib/exe/xmlrpc.php?"+ params self._rpc = ServerProxy(fullurl) try: self.get_version() except: self.post("Failure to connect") self.get_pagelist() self.post("Connected") def on_delete_page__clicked(self, *args): dialog = ModalDialog("Are you sure?") response = dialog.run() if response == gtk.RESPONSE_ACCEPT: value = self._sections[self.current] sel = self.objectlist.remove(value) self._rpc.wiki.putPage(self.current, "", {}) self.current = None dialog.destroy() def on_new_page__clicked(self, *args): dialog = ModalDialog("Name for the new page") text_w = gtk.Entry() text_w.show() response = [] dialog.vbox.add(text_w) response = dialog.run() if response == gtk.RESPONSE_ACCEPT: text = text_w.get_text() if text: self.current = text dialog.destroy() def on_button_h1__clicked(self, *args): self.buffer.set_style('h1') def on_button_h2__clicked(self, *args): self.buffer.set_style('h2') def on_button_h3__clicked(self, *args): self.buffer.set_style('h3') def on_button_h4__clicked(self, *args): self.buffer.set_style('h4') def on_button_h5__clicked(self, *args): self.buffer.set_style('h5') def on_button_h6__clicked(self, *args): self.buffer.set_style('h6') def on_button_bold__clicked(self, *args): self.buffer.set_style('bold') def on_button_italic__clicked(self, *args): self.buffer.set_style('italic') def on_button_clear_style__clicked(self, *args): self.buffer.clear_style() def on_button_save__clicked(self, *args): self.post("Saving...") dialog = ModalDialog("Commit message") entry = gtk.Entry() minor = gtk.CheckButton("Minor") dialog.vbox.add(gtk.Label("Your attention to detail\nIs greatly appreciated")) dialog.vbox.add(entry) dialog.vbox.add(minor) dialog.show_all() response = dialog.run() if response == gtk.RESPONSE_ACCEPT: text = self.buffer.process_text() self.put_page(text, entry.get_text(), minor.get_active()) self.get_htmlview(self.current) self.get_versions(self.current) self.post("Saved") dialog.destroy() # unused stuff def request_url(self, document, url, stream): f = simplebrowser.open_url(url) stream.write(f.read()) def setup_htmlview_gtkhtml(self): # XXX not used now self.document = gtkhtml2.Document() self.document.connect('request_url', self.request_url) self.htmlview = gtkhtml2.View() self.htmlview.set_document(self.document) def setup_sourceview_gtksourceview(self): # XXX not used now self.buffer = gtksourceview.Buffer(table) self.editor = gtksourceview.View(self.buffer) if True: self.editor.set_show_line_numbers(True) lm = gtksourceview.LanguageManager() self.editor.set_indent_on_tab(True) self.editor.set_indent_width(4) self.editor.set_property("auto-indent", True) self.editor.set_property("highlight-current-line", True) self.editor.set_insert_spaces_instead_of_tabs(True) lang = lm.get_language("python") self.buffer.set_language(lang) self.buffer.set_highlight_syntax(True)
def get_selected(*args,**kwords): print objectlist.get_selected() results=[[5, 'Foo2', 'yummy food'], [6, 'Foobar', 'best foobar evar!']] #the first argument is the name of the attr in the object for the row that goes #in the column my_columns = [ Column("r_id", title="ID", visible=False), Column("name", title="Name", sorted=True), Column("desc", title="Description") ] recipes=[recipe_info(x) for x in results] objectlist = ObjectList(my_columns) objectlist.add_list(recipes) w = gtk.Window() w.connect('delete-event', gtk.main_quit) vb=gtk.VBox() vb.add(objectlist) b=gtk.Button("Click Me!") b.connect("clicked", get_selected) vb.add(b) w.add(vb) w.show_all() gtk.main()
class ShowLastPackets(InformationWindow): ## @var win # window ## @var visualizer # visualizer ## @var viz_node # visualizer node ## @var node # the node ## @var tx_list # packet transmit list ## @var rx_list # packet receive list ## @var drop_list # packet drop list ## @var packet_capture_options # packet capture options ## @var packet_filter_widget # packet filter widget ## @var packet_filter_list # list of TypeIdConfig instances ## @var op_AND_button # AND button ## @var op_OR_button # OR button class PacketList(gtk.ScrolledWindow): """ PacketList class """ ## @var table_model # table model ( COLUMN_TIME, COLUMN_INTERFACE, COLUMN_SIZE, COLUMN_CONTENTS, ) = range(4) def __init__(self): """ Initializer @param self this object """ super(ShowLastPackets.PacketList, self).__init__() self.set_properties(hscrollbar_policy=gtk.POLICY_AUTOMATIC, vscrollbar_policy=gtk.POLICY_AUTOMATIC) self.table_model = gtk.ListStore(*([str] * 4)) treeview = gtk.TreeView(self.table_model) treeview.show() self.add(treeview) def add_column(descr, colid): column = gtk.TreeViewColumn(descr, gtk.CellRendererText(), text=colid) treeview.append_column(column) add_column("Time", self.COLUMN_TIME) add_column("Interface", self.COLUMN_INTERFACE) add_column("Size", self.COLUMN_SIZE) add_column("Contents", self.COLUMN_CONTENTS) def update(self, node, packet_list): """! Update function @param self this object @param node the node @param packet_list packet list @return none """ self.table_model.clear() for sample in packet_list: tree_iter = self.table_model.append() if sample.device is None: interface_name = "(unknown)" else: interface_name = ns.core.Names.FindName(sample.device) if not interface_name: interface_name = "(interface %i)" % sample.device.GetIfIndex( ) self.table_model.set(tree_iter, self.COLUMN_TIME, str(sample.time.GetSeconds()), self.COLUMN_INTERFACE, interface_name, self.COLUMN_SIZE, str(sample.packet.GetSize()), self.COLUMN_CONTENTS, str(sample.packet)) def __init__(self, visualizer, node_index): """ Initializer @param self this object @param visualizer the visualizer object @param node_index the node index """ InformationWindow.__init__(self) self.win = gtk.Dialog(parent=visualizer.window, flags=gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_NO_SEPARATOR, buttons=(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)) self.win.connect("response", self._response_cb) self.win.set_title("Last packets for node %i" % node_index) self.visualizer = visualizer self.viz_node = visualizer.get_node(node_index) self.node = ns.network.NodeList.GetNode(node_index) def smart_expand(expander, vbox): if expander.get_expanded(): vbox.set_child_packing(expander, expand=True, fill=True, padding=0, pack_type=gtk.PACK_START) else: vbox.set_child_packing(expander, expand=False, fill=False, padding=0, pack_type=gtk.PACK_START) main_hbox = gtk.HBox(False, 4) main_hbox.show() main_vbox = gtk.VBox(False, 4) main_vbox.show() self.win.vbox.add(main_hbox) main_hbox.add(main_vbox) self.tx_list = self.PacketList() self.tx_list.show() group = gtk.Expander("Last transmitted packets") group.show() group.add(self.tx_list) main_vbox.pack_start(group, expand=False, fill=False) group.connect_after("activate", smart_expand, main_vbox) self.rx_list = self.PacketList() self.rx_list.show() group = gtk.Expander("Last received packets") group.show() group.add(self.rx_list) main_vbox.pack_start(group, expand=False, fill=False) group.connect_after("activate", smart_expand, main_vbox) self.drop_list = self.PacketList() self.drop_list.show() group = gtk.Expander("Last dropped packets") group.show() group.add(self.drop_list) main_vbox.pack_start(group, expand=False, fill=False) group.connect_after("activate", smart_expand, main_vbox) # Packet Filter # - options self.packet_capture_options = ns.visualizer.PyViz.PacketCaptureOptions( ) self.packet_capture_options.numLastPackets = 100 packet_filter_vbox = gtk.VBox(False, 4) packet_filter_vbox.show() main_hbox.add(packet_filter_vbox) sel_buttons_box = gtk.HButtonBox() sel_buttons_box.show() packet_filter_vbox.pack_start(sel_buttons_box, False, False, 4) select_all_button = gobject.new(gtk.Button, label="Sel. All", visible=True) select_none_button = gobject.new(gtk.Button, label="Sel. None", visible=True) sel_buttons_box.add(select_all_button) sel_buttons_box.add(select_none_button) self.packet_filter_widget = ObjectList([ Column('selected', title="Sel.", data_type=bool, editable=True), Column('name', title="Header"), ], sortable=True) self.packet_filter_widget.show() packet_filter_vbox.pack_start(self.packet_filter_widget, True, True, 4) class TypeIdConfig(object): __slots__ = ['name', 'selected', 'typeid'] self.packet_filter_list = [] # list of TypeIdConfig instances Header = ns.core.TypeId.LookupByName("ns3::Header") Trailer = ns.core.TypeId.LookupByName("ns3::Trailer") for typeid_i in range(ns.core.TypeId.GetRegisteredN()): typeid = ns.core.TypeId.GetRegistered(typeid_i) # check if this is a header or trailer subtype typeid_tmp = typeid type_is_good = False while 1: if typeid_tmp == Header or typeid_tmp == Trailer: type_is_good = True break if typeid_tmp.HasParent(): typeid_tmp = typeid_tmp.GetParent() else: break if not type_is_good: continue if typeid in [Header, Trailer]: continue c = TypeIdConfig() c.selected = True c.name = typeid.GetName() c.typeid = typeid self.packet_filter_list.append(c) self.packet_filter_widget.add_list(self.packet_filter_list) def update_capture_options(): if self.op_AND_button.props.active: self.packet_capture_options.mode = ns.visualizer.PyViz.PACKET_CAPTURE_FILTER_HEADERS_AND else: self.packet_capture_options.mode = ns.visualizer.PyViz.PACKET_CAPTURE_FILTER_HEADERS_OR self.packet_capture_options.numLastPackets = 100 self.packet_capture_options.headers = [ c.typeid for c in self.packet_filter_list if c.selected ] self.visualizer.simulation.lock.acquire() try: self.visualizer.simulation.sim_helper.SetPacketCaptureOptions( self.node.GetId(), self.packet_capture_options) finally: self.visualizer.simulation.lock.release() def sel_all_cb(bt): for c in self.packet_filter_list: c.selected = True self.packet_filter_widget.refresh() update_capture_options() def sel_none_cb(bt): for c in self.packet_filter_list: c.selected = False self.packet_filter_widget.refresh() update_capture_options() select_all_button.connect("clicked", sel_all_cb) select_none_button.connect("clicked", sel_none_cb) op_buttons_box = gtk.HButtonBox() op_buttons_box.show() packet_filter_vbox.pack_start(op_buttons_box, False, False, 4) self.op_AND_button = gobject.new(gtk.RadioButton, label="AND", visible=True) self.op_OR_button = gobject.new(gtk.RadioButton, label="OR", visible=True, group=self.op_AND_button) op_buttons_box.add(self.op_AND_button) op_buttons_box.add(self.op_OR_button) self.op_OR_button.props.active = True self.op_AND_button.connect("toggled", lambda b: update_capture_options()) def cell_edited(l, obj, attribute): update_capture_options() self.packet_filter_widget.connect("cell-edited", cell_edited) update_capture_options() self.visualizer.add_information_window(self) self.win.set_default_size(600, 300) self.win.show() def _response_cb(self, win, response): """! Response callback function @param self this object @param win the window @param response the response @return none """ self.win.destroy() self.visualizer.remove_information_window(self) def update(self): """! Update function @param self this object @return none """ last_packets = self.visualizer.simulation.sim_helper.GetLastPackets( self.node.GetId()) self.tx_list.update(self.node, last_packets.lastTransmittedPackets) self.rx_list.update(self.node, last_packets.lastReceivedPackets) self.drop_list.update(self.node, last_packets.lastDroppedPackets)
class ChartDialog(gtk.Window): def __init__(self): self._js_data = None self._js_options = None self._current = None gtk.Window.__init__(self) self.set_size_request(800, 480) self.vbox = gtk.VBox() self.add(self.vbox) self.vbox.show() hbox = gtk.HBox() self.vbox.pack_start(hbox, False, False, 6) hbox.show() label = gtk.Label('Period:') hbox.pack_start(label, False, False, 6) label.show() self.chart_type = ProxyComboBox() self.chart_type.connect( 'content-changed', self._on_chart_type__content_changed) hbox.pack_start(self.chart_type, False, False, 6) self.chart_type.show() self.period_values = ProxyComboBox() self.period_values.connect( 'content-changed', self._on_period_values__content_changed) hbox.pack_start(self.period_values, False, False, 6) self.period_values.show() self._view = WebView() self._view.get_view().connect( 'load-finished', self._on_view__document_load_finished) self.vbox.pack_start(self._view, True, True) self.results = ObjectList() self.results.connect( 'row-activated', self._on_results__row_activated) self.vbox.pack_start(self.results, True, True) self._setup_daemon() @api.async def _setup_daemon(self): daemon = yield start_daemon() self._daemon_uri = daemon.base_uri proxy = daemon.get_client() yield proxy.callRemote('start_webservice') self.chart_type.prefill([ ('Year', 'YearlyPayments'), ('Month', 'MonthlyPayments'), ('Day', 'DailyPayments'), ]) @api.async def _invoke_chart(self, chart_type_name, **report_kwargs): def _get_chart_url(**kwargs): params = [] for key, value in kwargs.items(): params.append(key + '=' + str(value)) return '%s/web/chart.json?%s' % ( self._daemon_uri, '&'.join(params)) url = _get_chart_url(type=chart_type_name, **report_kwargs) page = yield getPage(url) data = json.loads(page) api.asyncReturn(data) def _render_chart(self, chart_class, response): self._render_javascript(chart_class, response) self._render_objectlist(chart_class, response) def _render_javascript(self, chart_class, response): ticks = [item['short_title'] for item in response['items']] self._js_data = response['data'] options = {} options['description'] = response['description'] options['series'] = [dict(label=c['title']) for c in chart_class.columns][1:] options['xaxis_ticks'] = ticks self._js_options = options self._view.load_uri('%s/web/static/chart.html' % ( self._daemon_uri,)) def _render_objectlist(self, chart_class, response): columns = [] for kwargs in chart_class.columns: kwargs = kwargs.copy() name = kwargs.pop('name') columns.append(Column(name, **kwargs)) self.results.set_columns(columns) items = [] for item in response['items']: settable = Settable(**item) settable.chart_class = chart_class items.append(settable) self.results.add_list(items, clear=True) self.results.show() def _load_finished(self): self._view.js_function_call( "plot", self._js_data, self._js_options) @api.async def _show_one(self, chart_type_name, start, end): chart_class = get_chart_class(chart_type_name) report_kwargs = dict(start=start.strftime('%Y-%m-%d'), end=end.strftime('%Y-%m-%d')) # Get chart datab response = yield self._invoke_chart(chart_type_name, **report_kwargs) self._render_chart(chart_class, response) def _update_period_values(self): chart_type_name = self.chart_type.get_selected() chart_class = get_chart_class(chart_type_name) values = chart_class.get_combo_labels() self.period_values.prefill(values) # # Callbacks # def _on_view__document_load_finished(self, view, frame): self._load_finished() def _on_chart_type__content_changed(self, combo): self._update_period_values() def _on_period_values__content_changed(self, combo): kind = self.chart_type.get_selected() value = self.period_values.get_selected() if not value: return start, end = value if self._current == (kind, start, end): return self._show_one(kind, start, end) self._current = kind, start, end def _on_results__row_activated(self, results, item): chart_type_name = item.chart_class.__name__ if chart_type_name == 'YearlyPayments': start = localdate(item.year, 1, 1).date() end = localdate(item.year, 12, 31).date() chart_type_name = 'MonthlyPayments' elif chart_type_name == 'MonthlyPayments': start = localdate(item.year, item.month, 1).date() end = start + relativedelta(days=31) chart_type_name = 'DailyPayments' else: return self._show_one(chart_type_name, start, end)
class DetailsTab(gtk.VBox): details_dialog_class = None def __init__(self, model, parent): super(DetailsTab, self).__init__() self.model = model self._parent = parent self.set_spacing(6) self.set_border_width(6) self.klist = ObjectList(self.get_columns()) self.klist.add_list(self.populate()) self.pack_start(self.klist) self.klist.show() if len(self.klist) and self.get_details_dialog_class(): self.button_box = gtk.HButtonBox() self.button_box.set_layout(gtk.BUTTONBOX_START) details_button = gtk.Button(self.details_lbl) self.button_box.pack_start(details_button) details_button.set_sensitive(bool(self.klist.get_selected())) details_button.show() self.pack_end(self.button_box, False, False) self.button_box.show() self.button_box.details_button = details_button details_button.connect('clicked', self._on_details_button__clicked) self.klist.connect('row-activated', self._on_klist__row_activated) self.klist.connect('selection-changed', self._on_klist__selection_changed) self.setup_widgets() def refresh(self): """Refreshes the list of respective tab.""" self.klist.clear() self.klist.add_list(self.populate()) def get_columns(self): """Returns a list of columns this tab should show.""" raise NotImplementedError def show_details(self): """Called when the details button is clicked. Displays the details of the selected object in the list.""" model = self.get_details_model(self.klist.get_selected()) run_dialog(self.get_details_dialog_class(), parent=self._parent, store=self._parent.store, model=model, visual_mode=True) def get_label(self): """Returns the name of the tab.""" label = gtk.Label(self.labels[1]) return label def get_details_model(self, model): """Subclassses can overwrite this method if the details dialog class needs a model different than the one on the list.""" return model def get_details_dialog_class(self): """Subclasses must return the dialog that should be displayed for more information about the item on the list""" return self.details_dialog_class def setup_widgets(self): """Override this if tab needs to do some custom widget setup.""" # # Callbacks # def _on_details_button__clicked(self, button): self.show_details() def _on_klist__row_activated(self, klist, item): self.show_details() def _on_klist__selection_changed(self, klist, data): self.button_box.details_button.set_sensitive(bool(data))
class DetailsTab(gtk.VBox): details_dialog_class = None def __init__(self, model, parent): super(DetailsTab, self).__init__() self.model = model self._parent = parent self.set_spacing(6) self.set_border_width(6) self.klist = ObjectList(self.get_columns()) self.klist.add_list(self.populate()) self.pack_start(self.klist) self.klist.show() if len(self.klist) and self.get_details_dialog_class(): self.button_box = gtk.HButtonBox() self.button_box.set_layout(gtk.BUTTONBOX_START) details_button = gtk.Button(self.details_lbl) self.button_box.pack_start(details_button) details_button.set_sensitive(bool(self.klist.get_selected())) details_button.show() self.pack_end(self.button_box, False, False) self.button_box.show() self.button_box.details_button = details_button details_button.connect('clicked', self._on_details_button__clicked) self.klist.connect('row-activated', self._on_klist__row_activated) self.klist.connect('selection-changed', self._on_klist__selection_changed) self.setup_widgets() def refresh(self): """Refreshes the list of respective tab.""" self.klist.clear() self.klist.add_list(self.populate()) def get_columns(self): """Returns a list of columns this tab should show.""" raise NotImplementedError def show_details(self): """Called when the details button is clicked. Displays the details of the selected object in the list.""" model = self.get_details_model(self.klist.get_selected()) run_dialog(self.get_details_dialog_class(), parent=self._parent, store=self._parent.store, model=model, visual_mode=True) def get_label(self): """Returns the name of the tab.""" label = gtk.Label(self.labels[1]) return label def get_details_model(self, model): """Subclassses can overwrite this method if the details dialog class needs a model different than the one on the list.""" return model def get_details_dialog_class(self): """Subclasses must return the dialog that should be displayed for more information about the item on the list""" return self.details_dialog_class def setup_widgets(self): """Override this if tab needs to do some custom widget setup.""" # # Callbacks # def _on_details_button__clicked(self, button): self.show_details() def _on_klist__row_activated(self, klist, item): self.show_details() def _on_klist__selection_changed(self, klist, data): self.button_box.details_button.set_sensitive(bool(data))
class ListDialog: """ Diálogo de edição de uma tabela com botões padrão e uma lista de campos. """ def __init__(self, controle, tabela, titulo): """ controle é um objeto da classe Controle. tabela é o nome de uma instancia de Classe no Controle que referencia um tabela no Modelo. titulo é nome de leitura da tabela sendo editada (ex. 'Categorias') """ self.controle = controle self.tabela = tabela self.data = [] self.buttons = [] self.new_method = self.create_new_record self.save_method = self.salvar self.populate_method = self.populate self.titulo = titulo or self.tabela.nome_tabela self.edit_mode = False self.editing_new = False self.editing = False self.selection = None self.do_nothing = False def make_widget(self, fields, custom_buttons = []): """ Cria e retorna o widget que contém o toolbar, a lista e os campos para edição. fields é uma lista de FieldType. custom_buttons é uma lista de ListToolButton que substitui os botões padrão. """ #-------Campos self.fields = [] for field in fields: if field.show_field: field.label = gtk.Label(field.titulo + ":") if field.tabelacombo: field.entry = ComboEntry() tabelacombo = getattr(self.controle, field.tabelacombo) itens = tabelacombo.combo() field.entry.prefill(itens) else: field.entry = ProxyEntry(field.tipo) field.entry.set_mask(field.mask) self.fields.append(field) vbox_main = gtk.VBox() hbox_topo = gtk.HBox() self.widget = gtk.EventBox() #-------Toolbar toolbar = gtk.Toolbar() toolbar.set_orientation(gtk.ORIENTATION_VERTICAL) toolbar.set_style(gtk.TOOLBAR_BOTH) if not custom_buttons: self.tb_novo = ListToolButton(self.default_new, gtk.STOCK_NEW) self.tb_edit = ListToolButton(self.default_edit, gtk.STOCK_EDIT) self.custom_buttons = [self.tb_novo, self.tb_edit] else: self.custom_buttons = custom_buttons for tool_button in self.custom_buttons: toolbar.insert(tool_button.button, -1) #-------Lista vbox_lista = gtk.VBox() hbox_entry = gtk.HBox() self.entry_localizar = gtk.Entry() self.entry_localizar.connect('activate', self.localizar) label = gtk.Label('Localizar') frame_lista = gtk.Frame(self.titulo) self.listview = self.create_list() self.listview.connect("row_activated", self.on_row_activated) self.listview.connect('selection-changed',self.on_selection_changed) #-------Frame frame_dados = gtk.Frame("Informações") hbox_dados = gtk.HBox(False, 6) vbox_label = gtk.VBox(True, 4) vbox_entry = gtk.VBox(True, 4) for field in self.fields: if field.show_field: vbox_label.pack_start(field.label, False, True, 8) vbox_entry.pack_start(field.entry, False, True, 8) #Botões self.button_save = gtk.Button(stock=gtk.STOCK_SAVE) self.button_save.connect("clicked", self.save_method) self.button_cancel = gtk.Button(stock=gtk.STOCK_CANCEL) self.button_cancel.connect("clicked", self.cancel) vbox_dados_buttons = gtk.VButtonBox() vbox_dados_buttons.set_layout(gtk.BUTTONBOX_SPREAD) vbox_dados_buttons.add(self.button_save) vbox_dados_buttons.add(self.button_cancel) #-------Notify self.notify = self.controle.notify() self.notify_box = self.notify.get_widget() self.notify.show_notify('info','Clique em NOVO para adicionar um novo item') self.tabela.set_notify(self.notify) #-------Posicionar todos frame_lista.add(self.listview) vbox_lista.pack_start(hbox_entry, False, False, 2) vbox_lista.pack_start(frame_lista, True, True, 2) hbox_entry.pack_end(self.entry_localizar, False, False, 2) hbox_entry.pack_end(label, False, False, 2) hbox_topo.pack_start(toolbar, False, False, 5) hbox_topo.pack_start(vbox_lista, True, True, 2) hbox_dados.pack_start(vbox_label, False, False, 2) hbox_dados.pack_start(vbox_entry, True, True, 2) hbox_dados.pack_start(vbox_dados_buttons, False, False, 2) frame_dados.add(hbox_dados) vbox_main.pack_start(hbox_topo, True, True, 2) vbox_main.pack_start(frame_dados, False, False, 2) vbox_main.pack_start(self.notify_box, False, True, 2) self.widget.add(vbox_main) self.set_edit_mode(False) return self.widget def create_list(self): columns = [] for field in self.fields: if field.show_in_list: columns.append(Column(field.field_name, data_type = field.tipo, title = field.titulo)) self.lista = ObjectList(columns) self.data = self.populate_method() self.lista.extend(self.data) return self.lista def localizar(self, entry): text = self.entry_localizar.get_text().lower() searches = text.split(" ") if not searches: #lista vazia lista = self.data else: lista = [] for item in self.data: itemtext = "" #reúne o texto inteiro do item (separado por espaço): for field in self.fields: if field.searchable: itemtext += str(getattr(item, field.field_name)).lower() + " " contain_all = True for searchtext in searches: if searchtext not in itemtext: contain_all = False if contain_all: lista.append(item) self.lista.add_list(lista) def set_edit_mode(self, edit_mode): """ Coloca ou tira os campos em modo de edição. """ for field in self.fields: if field.entry: field.entry.set_sensitive(edit_mode) for tool_button in self.custom_buttons: tool_button.button.set_sensitive(not edit_mode) self.entry_localizar.set_sensitive(not edit_mode) self.button_save.set_sensitive(edit_mode) self.button_cancel.set_sensitive(edit_mode) self.editing = edit_mode def cancel(self, widget): """Cancela a edição de um item""" self.set_edit_mode(False) self.clear_entry() self.lista.refresh() if self.editing_new: self.lista.remove(self.newobj) self.editing_new = False self.notify.show_notify('info','Clique em NOVO para adicionar um novo item') def create_new_record(self): """Adiciona um item padrão a lista para depois ser editado""" self.notify.hide() obj = ListItem() for field in self.fields: if field.tipo == str or field.tabelacombo: setattr(obj, field.field_name, '') else: setattr(obj, field.field_name, converter.from_string(field.tipo, '0')) return obj def populate(self): """Popula a lista com os itens""" itens = self.tabela.listar() objetos = [] for item in itens: obj = ListItem() for field in self.fields: if not field.tabelacombo: setattr(obj, field.field_name, item[field.field_name]) else: tabelacombo = getattr(self.controle, field.tabelacombo) descricao = tabelacombo.item_descricao(item[field.field_name]) try: setattr(obj, field.field_name, descricao[0][0]) except: setattr(obj, field.field_name, descricao) objetos.append(obj) return objetos def default_new(self, sender): self.newobj = self.new_method() #Chama new_method para criar um novo item self.data.append(self.newobj) self.listview.append(self.newobj) self.listview.refresh() self.listview.select(self.newobj) self.set_edit_mode(True) self.editing_new = True self.item = self.selection def default_edit(self, sender): if self.selection: self.populate_entry(self.selection) self.set_edit_mode(True) self.item = self.selection def on_row_activated(self, list, item): """Preenche os campos com os valores da coluna clicada e coloca em modo de edição""" self.item = item self.populate_entry(item) def populate_entry(self, item): """Preenche os campos com os itens""" self.notify.hide() for field in self.fields: if field.entry: if field.tabelacombo: field.entry.select_item_by_label(str(getattr(item, field.field_name))) else: field.entry.set_text(str(getattr(item, field.field_name))) self.set_edit_mode(True) def clear_entry(self): """Limpa os campos apos edicao ou cancelar""" for field in self.fields: if field.entry: field.entry.set_text('') self.set_edit_mode(False) def on_selection_changed(self, list, selection): """Verifica se o usuario editou os campos e não salvou""" if self.do_nothing: self.do_nothing = False return self.selection = selection response = False if self.editing == True: for field in self.fields: if field.entry: if not field.identificador: user_edited = field.entry.get_text() #Se for um novo item if self.editing_new == True: if user_edited: response = self.ask_to_save(field) if response == True: self.salvar(None) else: self.cancel(None) else: if response: self.do_nothing = True self.listview.select(self.item) else: self.cancel(None) #Se editando item da lista elif self.editing == True: field_in_list = (str(getattr(self.item, field.field_name))) if user_edited != field_in_list: response = self.ask_to_save(field) if response == True: self.salvar(None) else: self.cancel(None) else: if response: self.do_nothing = True self.listview.select(self.item) def ask_to_save(self, field): """Pergunta ao usuario sobre a edicao de campos""" #Criando um novo if self.editing_new : question =str('Deseja salvar %s ?') for field in self.fields: if field.searchable: registro = quote(str(field.entry.get_text())) #Editando else: question =str('Deseja salvar alterações em %s ?') registro = quote(str(getattr(self.item, field.field_name))) response = yesno((question) % (registro,), parent=None, default=gtk.RESPONSE_OK, buttons=((gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL), (gtk.STOCK_SAVE, gtk.RESPONSE_OK))) return response == gtk.RESPONSE_OK def salvar(self, widget): """Insere ou edita um registro na tabela""" record = {} #Insere novo if self.editing_new : record = self.tabela.insert(self.fields) if record : for field in self.fields: if field.identificador: setattr(self.newobj, field.field_name, record['last_id']) elif field.tabelacombo: tabelacombo = getattr(self.controle, field.tabelacombo) descricao = tabelacombo.item_descricao(record[field.field_name]) setattr(self.newobj, field.field_name, descricao[0][0]) else: setattr(self.newobj, field.field_name, record[field.field_name]) self.editing_new = False self.lista.refresh() self.clear_entry() self.hide_notify() #Edita else: record = self.tabela.update(self.fields, self.item) if record: for field in self.fields: if field.identificador: pass elif field.tabelacombo: tabelacombo = getattr(self.controle, field.tabelacombo) descricao = tabelacombo.item_descricao(record[field.field_name]) try: setattr(self.item, field.field_name, descricao[0][0]) except: setattr(self.item, field.field_name, descricao) else: setattr(self.item, field.field_name, record[field.field_name]) self.lista.refresh() self.clear_entry() self.hide_notify() def hide_notify(self): self.notify.hide()
class SelectDialog: """ Classe que implementa uma janela de pesquisa de registros dentro de uma tabela. """ def __init__(self, recordset, campos_retorno = []): """ Inicializa o objeto SelectDialog. recordset é o objeto Recordset que contém a lista a ser exibida e campos_retorno é a lista de campos do registro selecionado que serão retornados (por padrão, todos os campos do recordset). """ self.recordset = recordset self.view_items = self.recordset.items self.campos_retorno = campos_retorno or [col.attribute for col in self.recordset.columns] self.clear() def clear(self): """ Limpa (ou inicializa) as variáveis de interface. """ self.dialog = None self.lista = None self.entry_pesq = None def activate(self, titulo = "", parent = None): """ Exibe o diálogo para a seleção do registro. Retorna None se o diálogo foi cancelado ou a tupla com campos_retorno caso tenha escolhido um item. """ self.dialog = self.create_dialog(titulo or "Pesquisa", parent) self.lista.add_list(self.view_items) ret = None response = self.dialog.run() if response == gtk.RESPONSE_OK: selected = self.lista.get_selected() ret = [kgetattr(selected, campo) for campo in self.campos_retorno] self.dialog.hide() return ret def create_dialog(self, titulo, parent): dialog = gtk.Dialog(titulo, parent, gtk.DIALOG_MODAL, (gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)) dialog.set_position(gtk.WIN_POS_CENTER) dialog.set_size_request(520, 470) dialog.set_border_width(8) frame_pesq = gtk.Frame("Pesquisar") hbox = gtk.HBox(False, 2) label_pesq = gtk.Label("Pesquisar por:") self.entry_pesq = gtk.Entry(0) hbox.set_border_width(8) hbox.pack_start(label_pesq, False, True, 2) hbox.add(self.entry_pesq) frame_pesq.add(hbox) self.lista = ObjectList(self.recordset.columns) #scrolled_window = gtk.ScrolledWindow() #scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) #scrolled_window.add(self.lista) self.entry_pesq.connect("backspace", self.do_search) dialog.vbox.pack_start(frame_pesq, False, True, 2) dialog.vbox.add(self.lista) dialog.show_all() return dialog def do_search(self, entry): text = self.entry_pesq.get_text().lower() if text: self.view_items = [item for item in self.recordset.items if text in kgetattr(item, 'nome')] else: self.view_items = self.recordset.items self.lista.add_list(self.view_items)
class ShortcutsEditor(BasicDialog): size = (700, 400) title = _("Keyboard shortcuts") def __init__(self): BasicDialog.__init__(self, size=ShortcutsEditor.size, title=ShortcutsEditor.title) self._create_ui() def _create_ui(self): self.cancel_button.hide() hbox = gtk.HBox(spacing=6) self.main.remove(self.main.get_child()) self.main.add(hbox) hbox.show() self.categories = ObjectList( [Column('label', sorted=True, expand=True)], get_binding_categories(), gtk.SELECTION_BROWSE) self.categories.connect('selection-changed', self._on_categories__selection_changed) self.categories.set_headers_visible(False) self.categories.set_size_request(200, -1) hbox.pack_start(self.categories, False, False) self.categories.show() box = gtk.VBox(spacing=6) hbox.pack_start(box) box.show() self.shortcuts = ObjectList(self._get_columns(), [], gtk.SELECTION_BROWSE) box.pack_start(self.shortcuts) self.shortcuts.show() self._label = gtk.Label( _("You need to restart Stoq for the changes to take effect")) box.pack_start(self._label, False, False, 6) box.show() defaults_button = gtk.Button(_("Reset defaults")) defaults_button.connect('clicked', self._on_defaults_button__clicked) self.action_area.pack_start(defaults_button, False, False, 6) self.action_area.reorder_child(defaults_button, 0) defaults_button.show() def _on_categories__selection_changed(self, categories, category): if not category: return self.shortcuts.add_list(get_bindings(category.name), clear=True) def _on_defaults_button__clicked(self, button): old = self.categories.get_selected() api.user_settings.remove('shortcuts') remove_user_bindings() self._label.show() self.categories.refresh() self.categories.select(old) def _get_columns(self): return [ Column('description', _("Description"), data_type=str, expand=True, sorted=True), ShortcutColumn('shortcut', _("Shortcut"), self) ] def set_binding(self, binding): set_user_binding(binding.name, binding.shortcut) d = api.user_settings.get('shortcuts', {}) d[binding.name] = binding.shortcut self._label.show() def remove_binding(self, binding): remove_user_binding(binding.name) d = api.user_settings.get('shortcuts', {}) try: del d[binding.name] except KeyError: pass self._label.show()
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 ShowLastPackets(InformationWindow): ## @var win # window ## @var visualizer # visualizer ## @var viz_node # visualizer node ## @var node # the node ## @var tx_list # packet transmit list ## @var rx_list # packet receive list ## @var drop_list # packet drop list ## @var packet_capture_options # packet capture options ## @var packet_filter_widget # packet filter widget ## @var packet_filter_list # list of TypeIdConfig instances ## @var op_AND_button # AND button ## @var op_OR_button # OR button class PacketList(Gtk.ScrolledWindow): """ PacketList class """ ## @var table_model # table model ( COLUMN_TIME, COLUMN_INTERFACE, COLUMN_SIZE, COLUMN_CONTENTS, ) = range(4) def __init__(self): """ Initializer @param self this object """ super(ShowLastPackets.PacketList, self).__init__() self.set_properties(hscrollbar_policy=Gtk.PolicyType.AUTOMATIC, vscrollbar_policy=Gtk.PolicyType.AUTOMATIC) self.table_model = Gtk.ListStore(*([str]*4)) treeview = Gtk.TreeView(self.table_model) treeview.show() self.add(treeview) def add_column(descr, colid): column = Gtk.TreeViewColumn(descr, Gtk.CellRendererText(), text=colid) treeview.append_column(column) add_column("Time", self.COLUMN_TIME) add_column("Interface", self.COLUMN_INTERFACE) add_column("Size", self.COLUMN_SIZE) add_column("Contents", self.COLUMN_CONTENTS) def update(self, node, packet_list): """! Update function @param self this object @param node the node @param packet_list packet list @return none """ self.table_model.clear() for sample in packet_list: tree_iter = self.table_model.append() if sample.device is None: interface_name = "(unknown)" else: interface_name = ns.core.Names.FindName(sample.device) if not interface_name: interface_name = "(interface %i)" % sample.device.GetIfIndex() self.table_model.set(tree_iter, self.COLUMN_TIME, str(sample.time.GetSeconds()), self.COLUMN_INTERFACE, interface_name, self.COLUMN_SIZE, str(sample.packet.GetSize ()), self.COLUMN_CONTENTS, str(sample.packet) ) def __init__(self, visualizer, node_index): """ Initializer @param self this object @param visualizer the visualizer object @param node_index the node index """ InformationWindow.__init__(self) self.win = Gtk.Dialog(parent=visualizer.window, flags=Gtk.DialogFlags.DESTROY_WITH_PARENT|Gtk.DialogFlags.NO_SEPARATOR, buttons=(Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE)) self.win.connect("response", self._response_cb) self.win.set_title("Last packets for node %i" % node_index) self.visualizer = visualizer self.viz_node = visualizer.get_node(node_index) self.node = ns.network.NodeList.GetNode(node_index) def smart_expand(expander, vbox): if expander.get_expanded(): vbox.set_child_packing(expander, expand=True, fill=True, padding=0, pack_type=Gtk.PACK_START) else: vbox.set_child_packing(expander, expand=False, fill=False, padding=0, pack_type=Gtk.PACK_START) main_hbox = Gtk.HBox(False, 4) main_hbox.show() main_vbox = Gtk.VBox(False, 4) main_vbox.show() self.win.vbox.add(main_hbox) main_hbox.add(main_vbox) self.tx_list = self.PacketList() self.tx_list.show() group = Gtk.Expander("Last transmitted packets") group.show() group.add(self.tx_list) main_vbox.pack_start(group, expand=False, fill=False) group.connect_after("activate", smart_expand, main_vbox) self.rx_list = self.PacketList() self.rx_list.show() group = Gtk.Expander("Last received packets") group.show() group.add(self.rx_list) main_vbox.pack_start(group, expand=False, fill=False) group.connect_after("activate", smart_expand, main_vbox) self.drop_list = self.PacketList() self.drop_list.show() group = Gtk.Expander("Last dropped packets") group.show() group.add(self.drop_list) main_vbox.pack_start(group, expand=False, fill=False) group.connect_after("activate", smart_expand, main_vbox) # Packet Filter # - options self.packet_capture_options = ns.visualizer.PyViz.PacketCaptureOptions() self.packet_capture_options.numLastPackets = 100 packet_filter_vbox = Gtk.VBox(False, 4) packet_filter_vbox.show() main_hbox.add(packet_filter_vbox) sel_buttons_box = Gtk.HButtonBox() sel_buttons_box.show() packet_filter_vbox.pack_start(sel_buttons_box, False, False, 4) select_all_button = GObject.new(Gtk.Button, label="Sel. All", visible=True) select_none_button = GObject.new(Gtk.Button, label="Sel. None", visible=True) sel_buttons_box.add(select_all_button) sel_buttons_box.add(select_none_button) self.packet_filter_widget = ObjectList([ Column('selected', title="Sel.", data_type=bool, editable=True), Column('name', title="Header"), ], sortable=True) self.packet_filter_widget.show() packet_filter_vbox.pack_start(self.packet_filter_widget, True, True, 4) class TypeIdConfig(object): __slots__ = ['name', 'selected', 'typeid'] self.packet_filter_list = [] # list of TypeIdConfig instances Header = ns.core.TypeId.LookupByName("ns3::Header") Trailer = ns.core.TypeId.LookupByName("ns3::Trailer") for typeid_i in range(ns.core.TypeId.GetRegisteredN()): typeid = ns.core.TypeId.GetRegistered(typeid_i) # check if this is a header or trailer subtype typeid_tmp = typeid type_is_good = False while 1: if typeid_tmp == Header or typeid_tmp == Trailer: type_is_good = True break if typeid_tmp.HasParent(): typeid_tmp = typeid_tmp.GetParent() else: break if not type_is_good: continue if typeid in [Header, Trailer]: continue c = TypeIdConfig() c.selected = True c.name = typeid.GetName() c.typeid = typeid self.packet_filter_list.append(c) self.packet_filter_widget.add_list(self.packet_filter_list) def update_capture_options(): if self.op_AND_button.props.active: self.packet_capture_options.mode = ns.visualizer.PyViz.PACKET_CAPTURE_FILTER_HEADERS_AND else: self.packet_capture_options.mode = ns.visualizer.PyViz.PACKET_CAPTURE_FILTER_HEADERS_OR self.packet_capture_options.numLastPackets = 100 self.packet_capture_options.headers = [c.typeid for c in self.packet_filter_list if c.selected] self.visualizer.simulation.lock.acquire() try: self.visualizer.simulation.sim_helper.SetPacketCaptureOptions( self.node.GetId(), self.packet_capture_options) finally: self.visualizer.simulation.lock.release() def sel_all_cb(bt): for c in self.packet_filter_list: c.selected = True self.packet_filter_widget.refresh() update_capture_options() def sel_none_cb(bt): for c in self.packet_filter_list: c.selected = False self.packet_filter_widget.refresh() update_capture_options() select_all_button.connect("clicked", sel_all_cb) select_none_button.connect("clicked", sel_none_cb) op_buttons_box = Gtk.HButtonBox() op_buttons_box.show() packet_filter_vbox.pack_start(op_buttons_box, False, False, 4) self.op_AND_button = GObject.new(Gtk.RadioButton, label="AND", visible=True) self.op_OR_button = GObject.new(Gtk.RadioButton, label="OR", visible=True, group=self.op_AND_button) op_buttons_box.add(self.op_AND_button) op_buttons_box.add(self.op_OR_button) self.op_OR_button.props.active = True self.op_AND_button.connect("toggled", lambda b: update_capture_options()) def cell_edited(l, obj, attribute): update_capture_options() self.packet_filter_widget.connect("cell-edited", cell_edited) update_capture_options() self.visualizer.add_information_window(self) self.win.set_default_size(600, 300) self.win.show() def _response_cb(self, win, response): """! Response callback function @param self this object @param win the window @param response the response @return none """ self.win.destroy() self.visualizer.remove_information_window(self) def update(self): """! Update function @param self this object @return none """ last_packets = self.visualizer.simulation.sim_helper.GetLastPackets(self.node.GetId()) self.tx_list.update(self.node, last_packets.lastTransmittedPackets) self.rx_list.update(self.node, last_packets.lastReceivedPackets) self.drop_list.update(self.node, last_packets.lastDroppedPackets)
NewsItem("Is that uranium in your pocket or are you just happy to see me?", "Baron Earl", "http://www.pigdog.org/auto/bad_people/link/2699.html"), NewsItem("Cut 'n Paste", "Baron Earl", "http://www.pigdog.org/auto/ArtFux/link/2690.html"), NewsItem("A Slippery Exit", "Reverend CyberSatan", "http://www.pigdog.org/auto/TheCorporateFuck/link/2683.html"), NewsItem("Those Crazy Dutch Have Resurrected Elvis", "Miss Conduct", "http://www.pigdog.org/auto/viva_la_musica/link/2678.html") ] # Specify the columns: one for each attribute of NewsItem, the URL # column invisible by default my_columns = [ Column("title", sorted=True), Column("author", justify=Gtk.Justification.RIGHT), Column("url", title="URL", visible=False) ] objectlist = ObjectList(my_columns) objectlist.add_list(news) w = Gtk.Window() w.connect('delete-event', Gtk.main_quit) w.set_size_request(600, 250) w.add(objectlist) w.show_all() Gtk.main()
class FormFieldEditor(BasicDialog): size = (700, 400) title = _("Form fields") def __init__(self, store): self.store = store BasicDialog.__init__(self, size=FormFieldEditor.size, title=FormFieldEditor.title) self._create_ui() def _create_ui(self): hbox = Gtk.HBox() self.main.remove(self.main.get_child()) self.main.add(hbox) hbox.show() self.forms = ObjectList( [Column('description', title=_('Description'), sorted=True, expand=True, format_func=stoqlib_gettext)], self.store.find(UIForm), Gtk.SelectionMode.BROWSE) self.forms.connect('selection-changed', self._on_forms__selection_changed) self.forms.set_headers_visible(False) self.forms.set_size_request(200, -1) hbox.pack_start(self.forms, False, False, 0) self.forms.show() box = Gtk.VBox() hbox.pack_start(box, True, True, 0) box.show() self.fields = ObjectList(self._get_columns(), [], Gtk.SelectionMode.BROWSE) box.pack_start(self.fields, True, True, 0) self.fields.show() box.show() def _on_forms__selection_changed(self, forms, form): if not form: return self.fields.add_list(self.store.find(UIField, ui_form=form), clear=True) self.fields.set_cell_data_func(self._uifield__cell_data_func) def _uifield__cell_data_func(self, column, renderer, obj, text): if isinstance(renderer, Gtk.CellRendererText): return text manager = get_plugin_manager() if manager.is_any_active(['nfe', 'nfce']): is_editable = obj.field_name not in [u'street', u'district', u'city', u'state', u'country', u'street_number'] renderer.set_property('sensitive', is_editable) renderer.set_property('activatable', is_editable) return text def _get_columns(self): return [Column('description', title=_('Description'), data_type=str, expand=True, sorted=True, format_func=stoqlib_gettext), Column('visible', title=_('Visible'), data_type=bool, width=120, editable=True), Column('mandatory', title=_('Mandatory'), data_type=bool, width=120, editable=True)] def confirm(self, *args): self.store.confirm(True) BasicDialog.confirm(self, *args) info(_("Changes will be applied after all instances of Stoq are restarted.")) def cancel(self, *args): self.store.rollback(close=False) BasicDialog.confirm(self, *args)
class ChartDialog(gtk.Window): def __init__(self): self._js_data = None self._js_options = None self._current = None gtk.Window.__init__(self) self.set_size_request(800, 480) self.vbox = gtk.VBox() self.add(self.vbox) self.vbox.show() hbox = gtk.HBox() self.vbox.pack_start(hbox, False, False, 6) hbox.show() label = gtk.Label('Period:') hbox.pack_start(label, False, False, 6) label.show() self.chart_type = ProxyComboBox() self.chart_type.connect('content-changed', self._on_chart_type__content_changed) hbox.pack_start(self.chart_type, False, False, 6) self.chart_type.show() self.period_values = ProxyComboBox() self.period_values.connect('content-changed', self._on_period_values__content_changed) hbox.pack_start(self.period_values, False, False, 6) self.period_values.show() self._view = WebView() self._view.get_view().connect('load-finished', self._on_view__document_load_finished) self.vbox.pack_start(self._view, True, True) self.results = ObjectList() self.results.connect('row-activated', self._on_results__row_activated) self.vbox.pack_start(self.results, True, True) self._setup_daemon() @api. async def _setup_daemon(self): daemon = yield start_daemon() self._daemon_uri = daemon.base_uri proxy = daemon.get_client() yield proxy.callRemote('start_webservice') self.chart_type.prefill([ ('Year', 'YearlyPayments'), ('Month', 'MonthlyPayments'), ('Day', 'DailyPayments'), ]) @api. async def _invoke_chart(self, chart_type_name, **report_kwargs): def _get_chart_url(**kwargs): params = [] for key, value in kwargs.items(): params.append(key + '=' + str(value)) return '%s/web/chart.json?%s' % (self._daemon_uri, '&'.join(params)) url = _get_chart_url(type=chart_type_name, **report_kwargs) page = yield getPage(url) data = json.loads(page) api.asyncReturn(data) def _render_chart(self, chart_class, response): self._render_javascript(chart_class, response) self._render_objectlist(chart_class, response) def _render_javascript(self, chart_class, response): ticks = [item['short_title'] for item in response['items']] self._js_data = response['data'] options = {} options['description'] = response['description'] options['series'] = [ dict(label=c['title']) for c in chart_class.columns ][1:] options['xaxis_ticks'] = ticks self._js_options = options self._view.load_uri('%s/web/static/chart.html' % (self._daemon_uri, )) def _render_objectlist(self, chart_class, response): columns = [] for kwargs in chart_class.columns: kwargs = kwargs.copy() name = kwargs.pop('name') columns.append(Column(name, **kwargs)) self.results.set_columns(columns) items = [] for item in response['items']: settable = Settable(**item) settable.chart_class = chart_class items.append(settable) self.results.add_list(items, clear=True) self.results.show() def _load_finished(self): self._view.js_function_call("plot", self._js_data, self._js_options) @api. async def _show_one(self, chart_type_name, start, end): chart_class = get_chart_class(chart_type_name) report_kwargs = dict(start=start.strftime('%Y-%m-%d'), end=end.strftime('%Y-%m-%d')) # Get chart datab response = yield self._invoke_chart(chart_type_name, **report_kwargs) self._render_chart(chart_class, response) def _update_period_values(self): chart_type_name = self.chart_type.get_selected() chart_class = get_chart_class(chart_type_name) values = chart_class.get_combo_labels() self.period_values.prefill(values) # # Callbacks # def _on_view__document_load_finished(self, view, frame): self._load_finished() def _on_chart_type__content_changed(self, combo): self._update_period_values() def _on_period_values__content_changed(self, combo): kind = self.chart_type.get_selected() value = self.period_values.get_selected() if not value: return start, end = value if self._current == (kind, start, end): return self._show_one(kind, start, end) self._current = kind, start, end def _on_results__row_activated(self, results, item): chart_type_name = item.chart_class.__name__ if chart_type_name == 'YearlyPayments': start = localdate(item.year, 1, 1).date() end = localdate(item.year, 12, 31).date() chart_type_name = 'MonthlyPayments' elif chart_type_name == 'MonthlyPayments': start = localdate(item.year, item.month, 1).date() end = start + relativedelta(days=31) chart_type_name = 'DailyPayments' else: return self._show_one(chart_type_name, start, end)
class ShortcutsEditor(BasicDialog): size = (700, 400) title = _("Keyboard shortcuts") def __init__(self): BasicDialog.__init__(self, size=ShortcutsEditor.size, title=ShortcutsEditor.title) self._create_ui() def _create_ui(self): self.cancel_button.hide() hbox = gtk.HBox(spacing=6) self.main.remove(self.main.get_child()) self.main.add(hbox) hbox.show() self.categories = ObjectList( [Column('label', sorted=True, expand=True)], get_binding_categories(), gtk.SELECTION_BROWSE) self.categories.connect('selection-changed', self._on_categories__selection_changed) self.categories.set_headers_visible(False) self.categories.set_size_request(200, -1) hbox.pack_start(self.categories, False, False) self.categories.show() box = gtk.VBox(spacing=6) hbox.pack_start(box) box.show() self.shortcuts = ObjectList(self._get_columns(), [], gtk.SELECTION_BROWSE) box.pack_start(self.shortcuts) self.shortcuts.show() self._label = gtk.Label( _("You need to restart Stoq for the changes to take effect")) box.pack_start(self._label, False, False, 6) box.show() defaults_button = gtk.Button(_("Reset defaults")) defaults_button.connect('clicked', self._on_defaults_button__clicked) self.action_area.pack_start(defaults_button, False, False, 6) self.action_area.reorder_child(defaults_button, 0) defaults_button.show() def _on_categories__selection_changed(self, categories, category): if not category: return self.shortcuts.add_list(get_bindings(category.name), clear=True) def _on_defaults_button__clicked(self, button): old = self.categories.get_selected() api.user_settings.remove('shortcuts') remove_user_bindings() self._label.show() self.categories.refresh() self.categories.select(old) def _get_columns(self): return [Column('description', _("Description"), data_type=str, expand=True, sorted=True), ShortcutColumn('shortcut', _("Shortcut"), self)] def set_binding(self, binding): set_user_binding(binding.name, binding.shortcut) d = api.user_settings.get('shortcuts', {}) d[binding.name] = binding.shortcut self._label.show() def remove_binding(self, binding): remove_user_binding(binding.name) d = api.user_settings.get('shortcuts', {}) try: del d[binding.name] except KeyError: pass self._label.show()
class search_results_window: """A results window for a searching for a recipe""" def __init__ (self, searchline="", mode=gtk.SELECTION_SINGLE): """Search for the name like searchstring""" self.window=gtk.Window(gtk.WINDOW_TOPLEVEL) self.window.connect("destroy", self.exit) self.window.set_size_request(600, 250) self.vbox=gtk.VBox(homogeneous=False,spacing=0) self.window.add(self.vbox) self.cur=con.cursor() if searchline.count(':') !=0: search_options=dict(self.parse_search_string(searchline)) print search_options results=[[5, 'Foo2', 'yummy food'], [6, 'Foobar', 'best foobar evar!']] else: searchline="%" + searchline + "%" self.cur.execute("""SELECT recipe_id,name,description FROM recipes WHERE name LIKE %s""", (searchline,)) results=self.cur.fetchall() my_columns = [ Column("name", title="Name", sorted=True), Column("desc", title="Description") ] self.objectlist = ObjectList(my_columns, mode=mode) self.objectlist.set_size_request(600,225) recipes=[RecipeInfo(x) for x in results] self.objectlist.add_list(recipes) self.b=gtk.Button("Show Selected") self.b.connect("clicked", self.show_recipe2) self.vbox.add(self.objectlist) self.vbox.add(self.b) self.window.show_all() def parse_search_string(self,s): foo,indexes=findall(':',s) p=0 l=[] s_len=len(s) for i in indexes: for j in range(i+1,s_len+1): #print (j,s_len) if j >= s_len: l.append(s[p:j].strip()) break else: if s[j] == " ": t=j if s[j] == ':': l.append(s[p:t].strip()) p=t break return [[y.lower() for y in x.split(':')] for x in l] def show_recipe2(self,widget,*data): recipe=self.objectlist.get_selected() self.window.hide() current_recipe(recipe_id=recipe.r_id) def show_recipe(self,widget,data): self.window.hide() recipe=current_recipe(recipe_id=data) def exit(self, widget): main_window.window.show()
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 DokuwikiView(GladeDelegate): """ A dokuwiki editor window """ def __init__(self): GladeDelegate.__init__(self, gladefile="pydoku", delete_handler=self.quit_if_last) self._icons = {} self.throbber_icon = Throbber(self.view.throbber) self.setup_wikitree() self.setup_wikislist() self.setup_attachments() self.setup_lastchanges() self.setup_side() self.setup_sourceview() self.setup_htmlview() self.page_edit = self.view.notebook1.get_nth_page(0) self.page_view = self.view.notebook1.get_nth_page(1) self.page_attach = self.view.notebook1.get_nth_page(2) self.show_all() if len(cfg.getChildren()): wiki = cfg.getChildren()[0] self.connect(wiki.url, wiki.user, wiki.password) self.wiki = wiki if wiki.current: self.load_page(wiki.current) # quit override to work with twisted def quit_if_last(self, *args): self.htmlview.destroy() # for some reason has to be deleted explicitly windows = [toplevel for toplevel in gtk.window_list_toplevels() if toplevel.get_property('type') == gtk.WINDOW_TOPLEVEL] if len(windows) == 1: reactor.stop() # general interface functions def post(self, text): id = self.view.statusbar.get_context_id("zap") self.view.statusbar.push(id, text) # setup functions def setup_wikislist(self): columns = [Column('url',format_func=self.get_favicon,data_type=gtk.gdk.Pixbuf,icon_size=gtk.ICON_SIZE_SMALL_TOOLBAR)] self.wikislist = ObjectList(columns) columns.append(Column('url', title='Wiki', column='url')) self.wikislist.set_columns(columns) self.view.vbox2.pack_start(self.wikislist) self.view.vbox2.reorder_child(self.wikislist, 0) self.wikislist.add_list(cfg.getChildren()) self.wikislist.connect("selection-changed", self.wiki_selected) threads.deferToThread(self.download_favicons, cfg) def download_favicons(self, cfg): for wiki in cfg.getChildren(): self.download_favicon(wiki) def download_favicon(self, wiki): import urllib icon_url = wiki.url+"/lib/tpl/sidebar/images/favicon.ico" filename, headers = urllib.urlretrieve(icon_url, "/tmp/ico.ico") if headers["Content-Type"] == 'image/x-icon': self.add_favicon(wiki, filename) def get_favicon(self, wiki_url): return self._icons.get(wiki_url, page_icon) def add_favicon(self, wiki, filename): pixbuf = gtk.gdk.pixbuf_new_from_file(filename) pixbuf = pixbuf.scale_simple(16,16,gtk.gdk.INTERP_BILINEAR) self._icons[wiki.url] = pixbuf self.objectlist.refresh() def setup_side(self): columns = ['sum', 'user', 'type', 'version', 'ip'] columns = [Column(s) for s in columns] self.versionlist = ObjectList(columns) self.view.side_vbox.pack_start(gtk.Label('Version Log:'), False, False) self.view.side_vbox.add(self.versionlist) self.versionlist.connect("selection-changed", self.version_selected) self.view.side_vbox.pack_start(gtk.Label('BackLinks:'), False, False) self.backlinks = ObjectList([Column('name')]) self.backlinks.connect("selection-changed", self.change_selected) self.view.side_vbox.add(self.backlinks) def setup_attachments(self): columns = ['id', 'size', 'lastModified', 'writable', 'isimg', 'perms'] columns = [Column(s) for s in columns] self.attachmentlist = ObjectList(columns) self.view.attachments_vbox.add(self.attachmentlist) def setup_lastchanges(self): columns = ['name', 'author', 'lastModified', 'perms', 'version', 'size'] columns = [Column(s) for s in columns] columns.append(Column('lastModified', sorted=True, order=gtk.SORT_DESCENDING)) self.lastchangeslist = ObjectList(columns) self.lastchangeslist.connect("selection-changed", self.change_selected) self.view.side_vbox.add(self.lastchangeslist) def setup_wikitree(self): columns = ['id', 'lastModified', 'perms', 'size'] columns = [Column(s) for s in columns] columns.insert(0, Column('icon', title='name', data_type=gtk.gdk.Pixbuf)) self.objectlist = ObjectTree(columns) columns.insert(1, Column('name', column='icon')) self.objectlist.set_columns(columns) self.objectlist.connect("selection-changed", self.selected) self.view.vbox2.add(self.objectlist) def html_realized(self, widget): if self.wiki and self.wiki.current: self.get_htmlview(self.wiki.current) def setup_htmlview(self): self.htmlview = gtkmozembed.MozEmbed() self.view.html_scrolledwindow.add_with_viewport(self.htmlview) self.htmlview.connect('realize', self.html_realized) #self.htmlview.set_size_request(800,600) #self.htmlview.realize() #self.view.html_scrolledwindow.show_all() #self.htmlview.show() def setup_sourceview(self): self.buffer = DokuwikiBuffer(table) self.editor = gtksourceview.SourceView(self.buffer) #self.editor.set_show_line_numbers(True) 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 = gtk.TextView(self.buffer) self.editor.set_left_margin(5) self.editor.set_right_margin(5) self.editor.set_wrap_mode(gtk.WRAP_WORD_CHAR) self.view.scrolledwindow1.add(self.editor) lm = gtksourceview.SourceLanguagesManager() langs = lm.get_available_languages() lang_diffs = filter(lambda s: s.get_name() == 'Diff', langs) if lang_diffs: self.buffer.set_language(lang_diffs[0]) # dokuwiki operations def _getVersion(self): return self._rpc.dokuwiki.getVersion() def get_version(self): return threads.deferToThread(self._getVersion) def get_pagelist(self): print "getpagelist1" pages = self._rpc.wiki.getAllPages() self._sections = {} self.objectlist.clear() print "getpagelist1.5" print "PAGES",pages for page in pages: self.add_page(page) print "getpagelist2" self.view.new_page.set_sensitive(True) self.view.delete_page.set_sensitive(True) if self.wiki.current: self.set_selection(self.wiki.current) print "getpagelist3" # XXX self.get_recent_changes() print "getpagelist2" def _getRecentChanges(self): return self._rpc.wiki.getRecentChanges(int(time.time()-(60*60*24*7*12))) def _gotRecentChanges(self, changes): changes = [DictWrapper(s) for s in changes] self.lastchangeslist.add_list(changes) def get_recent_changes(self): self.callDeferred(self._getRecentChanges, self._gotRecentChanges) def get_attachments(self, ns): attachments = self._rpc.wiki.getAttachments(ns, {}) attachments = [DictWrapper(s) for s in attachments] self.attachmentlist.add_list(attachments) def _getBackLinks(self, pagename): return self._rpc.wiki.getBackLinks(pagename) def _gotBackLinks(self, backlinks): backlinks = [Section(s) for s in backlinks] self.backlinks.add_list(backlinks) def get_backlinks(self, pagename): self.callDeferred(self._getBackLinks, self._gotBackLinks, pagename) def _getVersions(self, pagename): return self._rpc.wiki.getPageVersions(pagename, 0) def _gotVersions(self, versionlist): versionlist = [DictWrapper(s) for s in versionlist] self.versionlist.add_list(versionlist) def get_versions(self, pagename): self.callDeferred(self._getVersions, self._gotVersions, pagename) def _getHtmlData(self, pagename): text = self._rpc.wiki.getPageHTML(pagename) return text def _gotHtmlData(self, text): self.throbber_icon.stop() if not self.htmlview.window: return text = """<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head><body>"""+text+"</body>" self.htmlview.render_data(text, len(text), self.wiki.url, 'text/html') self.htmlview.realize() self.htmlview.show() def get_htmlview(self, pagename): self.throbber_icon.start() self.callDeferred(self._getHtmlData, self._gotHtmlData, pagename) #d.addErrback(self.someError) # XXX following is for gtkhtml (not used) #self.document.clear() #self.document.open_stream('text/html') #self.document.write_stream(text) #self.document.close_stream() def callDeferred(self, get_func, got_func, *args): d = threads.deferToThread(get_func, *args) d.addCallback(got_func) def _getEditText(self, pagename): return self._rpc.wiki.getPage(pagename) def _gotEditText(self, text): self.throbber_icon.stop() self.buffer.set_highlight(False) self.editor.set_editable(True) self.buffer.add_text(text) def _getDiffText(self, pagename, version, idx): return self._rpc.wiki.getPageVersion(pagename, version), idx def _gotDiffText(self, data): import difflib import StringIO text, idx = data self.textstack[idx] = text if not None in self.textstack: fromlines = self.textstack[0].split("\n") tolines = self.textstack[1].split("\n") diff_text = difflib.unified_diff(fromlines, tolines, "a", "b", self.versions[0], self.versions[1]) self.throbber_icon.stop() self.buffer.clear() str_buffer = StringIO.StringIO() for line in diff_text: str_buffer.write(line+'\n') str_buffer.seek(0) self.buffer.add_text(str_buffer.read()) self.buffer.set_highlight(True) self.editor.set_editable(False) def get_difftext(self, pagename, version, prev_version): self.throbber_icon.start() self.textstack = [None, None] self.versions = [version, prev_version] self.callDeferred(self._getDiffText, self._gotDiffText, pagename, prev_version, 0) self.callDeferred(self._getDiffText, self._gotDiffText, pagename, version, 1) def get_edittext(self, pagename): self.throbber_icon.start() self.callDeferred(self._getEditText, self._gotEditText, pagename) def put_page(self, text, summary, minor): pars = {} if summary: pars['sum'] = summary if minor: pars['minor'] = minor d = threads.deferToThread(self._rpc.wiki.putPage, self.wiki.current, text, pars) return d # put a page into the page tree def add_page(self, page): print page try: name = page["id"] path = name.split(":") prev = None for i, pathm in enumerate(path): if i == len(path)-1: # a page new = DictWrapper(page, pathm) self._sections[name] = new self.objectlist.append(prev, new, False) else: # a namespace part_path = ":".join(path[:i+1]) if not part_path in self._sections: new = Section(pathm, part_path) self._sections[part_path] = new self.objectlist.append(prev, new, False) else: new = self._sections[part_path] prev = new except: traceback.print_exc() def expand_to(self, pagename): path = pagename.split(":") for i, pathm in enumerate(path): if not i == len(path)-1: section = self._sections[":".join(path[:i+1])] self.view.objectlist.expand(section) def set_selection(self, pagename): obj = self._sections[pagename] self.expand_to(pagename) self.view.objectlist.select(obj, True) #self.selected(widget, obj) # page selected callback def wiki_selected(self, widget, wiki): self.connect(wiki.url, wiki.user, wiki.password) self.objectlist.clear() self.versionlist.clear() self.lastchangeslist.clear() self.backlinks.clear() self._sections = {} self.wiki = wiki self.buffer.clear() if wiki.current: self.load_page(wiki.current) def version_selected(self, widget, object): # yes, the previous item is the next in the widget if object == None: return previous = widget.get_next(object) if not previous: return prev_version = previous.version self.get_difftext(self.wiki.current, int(object.version), int(prev_version)) def change_selected(self, widget, object): if not object: return self.set_selection(object.name) def selected(self, widget, object): if not object: return if isinstance(object, Section): self.get_attachments(object.id) if not isinstance(object, DictWrapper): return self.wiki.current = object.id cfg.save() self.load_page(object.id) def load_page(self, pagename): self.get_edittext(pagename) self.get_htmlview(pagename) self.get_backlinks(pagename) self.get_versions(pagename) # kiwi interface callbacks def on_view_edit__toggled(self, widget): if widget.get_active(): self.notebook1.insert_page(self.page_edit, gtk.Label('edit'), 0) else: self.notebook1.remove_page(self.notebook1.page_num(self.page_edit)) def on_view_view__toggled(self, widget): if widget.get_active(): self.notebook1.insert_page(self.page_view, gtk.Label('view'), 1) else: self.notebook1.remove_page(self.notebook1.page_num(self.page_view)) def on_view_attachments__toggled(self, widget): if widget.get_active(): self.notebook1.insert_page(self.page_attach, gtk.Label('attach')) else: self.notebook1.remove_page(self.notebook1.page_num(self.page_attach)) def on_view_extra__toggled(self, widget): if widget.get_active(): self.backlinks.show() self.versionlist.show() self.view.hpaned2.set_position(self._prevpos) else: self.backlinks.hide() self.versionlist.hide() self._prevpos = self.view.hpaned2.get_position() self.view.hpaned2.set_position(self.view.hpaned2.allocation.width) def on_button_add__clicked(self, *args): dialog = ModalDialog("User Details") # prepare widgets = {} items = ["url","user", "password"] for i, item in enumerate(items): widgets[item] = gtk.Entry() if i == 2: widgets[item].set_visibility(False) hbox = gtk.HBox() hbox.pack_start(gtk.Label(item+': ')) hbox.add(widgets[item]) dialog.vbox.add(hbox) dialog.show_all() # run response = dialog.run() user = widgets['user'].get_text() password = widgets['password'].get_text() url = widgets['url'].get_text() dialog.destroy() if not response == gtk.RESPONSE_ACCEPT: return self.wiki = cfg.new(Dokuwiki, url=url, user=user, password=password) cfg.addChild(self.wiki) cfg.save() self.connect(url, user, password) def get_full_url(self, url, user, password): try: if user and password: split_url = url.split('://') proto = split_url[0] base_url = split_url[1] return proto + '://' + user + ':' + password + '@' + base_url return url except: traceback.print_exc() def connect(self, url, user, password): # following commented line is for gtkhtml (not used) #simplebrowser.currentUrl = self.view.url.get_text() # handle response self.post("Connecting to " + url) params = urlencode({'u':user, 'p':password}) print self.get_full_url(url, user, password) fullurl = self.get_full_url(url, user, password) + "/lib/exe/xmlrpc.php?"+ params print "serverproxy1" self._rpc = ServerProxy(fullurl) print "serverproxy1" d = self.get_version() d.addCallback(self.connected) d.addErrback(self.error_connecting) def error_connecting(self, failure): self.post("Error connecting to " + self.wiki.url) print failure.getErrorMessage() def connected(self, version): print "connected1" self.view.version.set_text(version) print "connected1.5" self.get_pagelist() print "connected2" self.post("Connected") def on_delete_page__clicked(self, *args): dialog = ModalDialog("Are you sure?") response = dialog.run() if response == gtk.RESPONSE_ACCEPT: value = self._sections[self.wiki.current] sel = self.objectlist.remove(value) self._rpc.wiki.putPage(self.wiki.current, "", {}) self.wiki.current = '' cfg.save() dialog.destroy() def on_new_page__clicked(self, *args): dialog = ModalDialog("Name for the new page") text_w = gtk.Entry() text_w.show() response = [] dialog.vbox.add(text_w) response = dialog.run() if response == gtk.RESPONSE_ACCEPT: text = text_w.get_text() if text: self.wiki.current = text cfg.save() self.buffer.clear() dialog.destroy() def on_button_h1__clicked(self, *args): self.buffer.set_style('h1') def on_button_h2__clicked(self, *args): self.buffer.set_style('h2') def on_button_h3__clicked(self, *args): self.buffer.set_style('h3') def on_button_h4__clicked(self, *args): self.buffer.set_style('h4') def on_button_h5__clicked(self, *args): self.buffer.set_style('h5') def on_button_h6__clicked(self, *args): self.buffer.set_style('h6') def on_button_bold__clicked(self, *args): self.buffer.set_style('bold') def on_button_italic__clicked(self, *args): self.buffer.set_style('italic') def on_button_clear_style__clicked(self, *args): self.buffer.clear_style() def _pagePut(self, *args): if not self.wiki.current in self._sections: self.add_page({"id":self.wiki.current}) self.get_htmlview(self.wiki.current) self.get_versions(self.wiki.current) self.post("Saved") def on_button_save__clicked(self, *args): """ Save button callback """ dialog = ModalDialog("Commit message") entry = gtk.Entry() minor = gtk.CheckButton("Minor") dialog.vbox.add(gtk.Label("Your attention to detail\nis greatly appreciated")) dialog.vbox.add(entry) dialog.vbox.add(minor) dialog.show_all() response = dialog.run() if response == gtk.RESPONSE_ACCEPT: self.post("Saving...") text = self.buffer.process_text() self.throbber_icon.start() d = self.put_page(text, entry.get_text(), minor.get_active()) d.addCallback(self._pagePut) dialog.destroy() # unused stuff def request_url(self, document, url, stream): f = simplebrowser.open_url(url) stream.write(f.read()) def setup_htmlview_gtkhtml(self): # XXX not used now self.document = gtkhtml2.Document() self.document.connect('request_url', self.request_url) self.htmlview = gtkhtml2.View() self.htmlview.set_document(self.document)
class FormFieldEditor(BasicDialog): size = (700, 400) title = _("Form fields") def __init__(self, store): self.store = store BasicDialog.__init__(self, size=FormFieldEditor.size, title=FormFieldEditor.title) self._create_ui() def _create_ui(self): hbox = gtk.HBox() self.main.remove(self.main.get_child()) self.main.add(hbox) hbox.show() self.forms = ObjectList( [Column('description', title=_('Description'), sorted=True, expand=True, format_func=stoqlib_gettext)], self.store.find(UIForm), gtk.SELECTION_BROWSE) self.forms.connect('selection-changed', self._on_forms__selection_changed) self.forms.set_headers_visible(False) self.forms.set_size_request(200, -1) hbox.pack_start(self.forms, False, False) self.forms.show() box = gtk.VBox() hbox.pack_start(box) box.show() self.fields = ObjectList(self._get_columns(), [], gtk.SELECTION_BROWSE) box.pack_start(self.fields) self.fields.show() box.show() def _on_forms__selection_changed(self, forms, form): if not form: return self.fields.add_list(self.store.find(UIField, ui_form=form), clear=True) def _get_columns(self): return [Column('description', title=_('Description'), data_type=str, expand=True, sorted=True, format_func=stoqlib_gettext), Column('visible', title=_('Visible'), data_type=bool, width=120, editable=True), Column('mandatory', title=_('Mandatory'), data_type=bool, width=120, editable=True)] def confirm(self, *args): self.store.confirm(True) BasicDialog.confirm(self, *args) info(_("Changes will be applied after all instances of Stoq are restarted.")) def cancel(self, *args): self.store.rollback(close=False) BasicDialog.confirm(self, *args)
class FormFieldEditor(BasicDialog): size = (700, 400) title = _("Form fields") def __init__(self, store): self.store = store BasicDialog.__init__(self, size=FormFieldEditor.size, title=FormFieldEditor.title) self._create_ui() def _create_ui(self): hbox = gtk.HBox() self.main.remove(self.main.get_child()) self.main.add(hbox) hbox.show() self.forms = ObjectList( [Column('description', title=_('Description'), sorted=True, expand=True, format_func=stoqlib_gettext)], self.store.find(UIForm), gtk.SELECTION_BROWSE) self.forms.connect('selection-changed', self._on_forms__selection_changed) self.forms.set_headers_visible(False) self.forms.set_size_request(200, -1) hbox.pack_start(self.forms, False, False) self.forms.show() box = gtk.VBox() hbox.pack_start(box) box.show() self.fields = ObjectList(self._get_columns(), [], gtk.SELECTION_BROWSE) box.pack_start(self.fields) self.fields.show() box.show() def _on_forms__selection_changed(self, forms, form): if not form: return self.fields.add_list(self.store.find(UIField, ui_form=form), clear=True) def _get_columns(self): return [Column('description', title=_('Description'), data_type=str, expand=True, sorted=True, format_func=stoqlib_gettext), Column('visible', title=_('Visible'), data_type=bool, width=120, editable=True), Column('mandatory', title=_('Mandatory'), data_type=bool, width=120, editable=True)] def confirm(self, *args): self.store.confirm(True) BasicDialog.confirm(self, *args) def cancel(self, *args): self.store.rollback(close=False) BasicDialog.confirm(self, *args)