From fb74fb0e0dc720bde9df2813b559b94b66815a34 Mon Sep 17 00:00:00 2001 From: Jiri Moskovcak Date: Tue, 25 Jan 2011 22:05:45 +0100 Subject: fixed some gui warnings rhbz#671488 - it turned out to be caused by some unused code we had in git, so I just removed it and find out, that I was redefining the "show" signal from GObject, so I renamed it to "show_gui" --- src/gui/CCDBusBackend.py | 3 +- src/gui/CCMainWindow.py | 6 +- src/gui/CCReporterDialog.py | 578 -------------------------------------------- src/gui/CellRenderers.py | 66 ----- 4 files changed, 5 insertions(+), 648 deletions(-) delete mode 100644 src/gui/CCReporterDialog.py delete mode 100644 src/gui/CellRenderers.py (limited to 'src/gui') diff --git a/src/gui/CCDBusBackend.py b/src/gui/CCDBusBackend.py index 6d48d014..d2b867c7 100644 --- a/src/gui/CCDBusBackend.py +++ b/src/gui/CCDBusBackend.py @@ -21,6 +21,7 @@ class DBusManager(gobject.GObject): # and later with policyKit bus = None def __init__(self): + session = None # binds the dbus to glib mainloop DBusGMainLoop(set_as_default=True) @@ -60,7 +61,7 @@ class DBusManager(gobject.GObject): # signal emited to update gui with current status gobject.signal_new("update", self, gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,)) # signal emited to show gui if user try to run it again - gobject.signal_new("show", self, gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ()) + gobject.signal_new("show_gui", self, gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ()) gobject.signal_new("daemon-state-changed", self, gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,)) gobject.signal_new("report-done", self, gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,)) diff --git a/src/gui/CCMainWindow.py b/src/gui/CCMainWindow.py index 651c8e54..9fbd95b0 100644 --- a/src/gui/CCMainWindow.py +++ b/src/gui/CCMainWindow.py @@ -21,7 +21,6 @@ import CCDBusBackend from CC_gui_functions import * from CCDumpList import getDumpList from CCDump import * # FILENAME_xxx, CD_xxx -from CCReporterDialog import ReporterDialog, ReporterSelector from CReporterAssistant import ReporterAssistant from PluginsSettingsDialog import PluginsSettingsDialog from SettingsDialog import SettingsDialog @@ -39,6 +38,7 @@ class MainWindow(): self.gladefile = "%s/ccgui.glade" % sys.path[0] self.wTree = gtk.glade.XML(self.gladefile) + #Get the Main Window, and connect the "destroy" event self.window = self.wTree.get_widget("main_window") if self.window: @@ -102,7 +102,7 @@ class MainWindow(): #self.ccdaemon.connect("update", self.update_cb) # for now, just treat them the same (w/o this, we don't even see daemon warnings in logs!): #self.ccdaemon.connect("warning", self.update_cb) - self.ccdaemon.connect("show", self.show_cb) + self.ccdaemon.connect("show_gui", self.show_cb) self.ccdaemon.connect("daemon-state-changed", self.on_daemon_state_changed_cb) self.ccdaemon.connect("report-done", self.on_report_done_cb) @@ -394,7 +394,7 @@ class MainWindow(): sys.exit() def show(self): - self.window.show() + self.window.show_all() def show_cb(self, daemon): if self.window: diff --git a/src/gui/CCReporterDialog.py b/src/gui/CCReporterDialog.py deleted file mode 100644 index b34baf87..00000000 --- a/src/gui/CCReporterDialog.py +++ /dev/null @@ -1,578 +0,0 @@ -# -*- coding: utf-8 -*- -import pygtk -pygtk.require("2.0") -import gtk -import gobject -import sys -from CC_gui_functions import * -import CellRenderers -from ABRTPlugin import PluginInfo -from PluginSettingsUI import PluginSettingsUI -from PluginList import getPluginInfoList -from CCDump import * # FILENAME_xxx, CD_xxx -from abrt_utils import _, log, log1, log2, get_verbose_level, g_verbose - -# FIXME - create method or smth that returns type|editable|content - -# response -REFRESH = -50 -SHOW_LOG = -60 - -# default texts -COMMENT_HINT_TEXT = _("Brief description of how to reproduce this or what you did...") -HOW_TO_HINT_TEXT = "1.\n2.\n3.\n" - -class ReporterDialog(): - """Reporter window""" - def __init__(self, report, daemon, log=None, parent=None): - self.editable = [] - self.row_dict = {} - self.report = report - #Set the Glade file - # FIXME add to path - builderfile = "%s/report.glade" % sys.path[0] - self.builder = gtk.Builder() - self.builder.add_from_file(builderfile) - #Get the Main Window, and connect the "destroy" event - self.window = self.builder.get_object("reporter_dialog") - self.window.set_default_size(-1, 800) - self.window.connect("response", self.on_response, daemon) - if parent: - self.window.set_position(gtk.WIN_POS_CENTER_ON_PARENT) - self.window.set_transient_for(parent) - self.window.set_modal(True) - else: - self.window.set_position(gtk.WIN_POS_CENTER) - - # comment textview - self.tvComment = self.builder.get_object("tvComment") - self.tvComment.connect("focus-in-event", self.on_comment_focus_cb) - self.show_hint_comment = 1 - - # "how to reproduce" textview - self.tevHowToReproduce = self.builder.get_object("tevHowToReproduce") - - self.builder.get_object("fErrors").hide() - bLog = self.builder.get_object("bLog") - #if g_verbose > 0: - doesn't work! why?! - if get_verbose_level() > 0: - bLog.connect("clicked", self.show_log_cb, log) - else: - bLog.unset_flags(gtk.VISIBLE) - tb_send_bt = self.builder.get_object("cbSendBacktrace") - tb_send_bt.connect("toggled", self.on_send_backtrace_toggled) - try: - tb_send_bt.get_child().modify_fg(gtk.STATE_NORMAL,gtk.gdk.color_parse("red")) - except Exception, ex: - # we don't want gui to die if it fails to set the button color - log(ex) - self.allow_send() - self.hydrate() - - def check_backtrace(self): - print "checking backtrace" - - def warn_user(self, warnings): - # FIXME: show in lError - fErrors = self.builder.get_object("fErrors") - lErrors = self.builder.get_object("lErrors") - warning_lbl = None - for warning in warnings: - if warning_lbl: - warning_lbl += "\n* %s" % warning - else: - warning_lbl = "* %s" % warning - lErrors.set_label(warning_lbl) - fErrors.show_all() - - def hide_warning(self): - fErrors = self.builder.get_object("fErrors") - lErrors = self.builder.get_object("lErrors") - fErrors.hide() - - def allow_send(self): - self.hide_warning() - bSend = self.builder.get_object("bSend") - SendBacktrace = self.builder.get_object("cbSendBacktrace").get_active() - send = True - error_msgs = [] - try: - rating = int(self.report[FILENAME_RATING][CD_CONTENT]) - except: - rating = None - # active buttons acording to required fields - # if an backtrace has rating use it - if not SendBacktrace: - send = False - error_msgs.append(_("You must check the backtrace for sensitive data.")) - # we have both SendBacktrace and rating - if rating != None: - try: - package = self.report[FILENAME_PACKAGE][CD_CONTENT] - # if we don't have package for some reason - except: - package = None - # not usable report - if int(self.report[FILENAME_RATING][CD_CONTENT]) < 3: - if package: - error_msgs.append(_("Reporting disabled because the backtrace is unusable.\nPlease try to install debuginfo manually using the command: debuginfo-install %s \nthen use the Refresh button to regenerate the backtrace." % package[0:package.rfind('-',0,package.rfind('-'))])) - else: - error_msgs.append(_("The backtrace is unusable, you cannot report this!")) - send = False - # probably usable 3 - elif int(self.report[FILENAME_RATING][CD_CONTENT]) < 4: - error_msgs.append(_("The backtrace is incomplete, please make sure you provide the steps to reproduce.")) - - if error_msgs: - self.warn_user(error_msgs) - bSend.set_sensitive(send) - if not send: - bSend.set_tooltip_text(_("Reporting disabled, please fix the problems shown above.")) - else: - bSend.set_tooltip_text(_("Sends the report using the selected plugin.")) - - def on_send_backtrace_toggled(self, toggle_button): - self.allow_send() - - def show_log_cb(self, widget, log): - show_log(log, parent=self.window) - - # this callback is called when user press Cancel or Report button in Report dialog - def on_response(self, dialog, response_id, daemon): - # the button has been pressed (probably) - if response_id == gtk.RESPONSE_APPLY: - if not (self.check_report()): - dialog.stop_emission("response") - self.builder.get_object("bSend").stop_emission("clicked") - if response_id == SHOW_LOG: - # prevent the report dialog from quitting the run() and closing itself - dialog.stop_emission("response") - - def on_send_toggled(self, cell, path, model): - model[path][3] = not model[path][3] - - def on_comment_focus_cb(self, widget, event): - if self.show_hint_comment: - # clear "hint" text by supplying a fresh, empty TextBuffer - widget.set_buffer(gtk.TextBuffer()) - self.show_hint_comment = 0 - - def set_label(self, label_widget, text): - if len(text) > label_widget.get_max_width_chars(): - label_widget.set_tooltip_text(text) - label_widget.set_text(text) - - def hydrate(self): - self.editable = [] - self.old_comment = COMMENT_HINT_TEXT - self.old_how_to_reproduce = HOW_TO_HINT_TEXT - for item in self.report: - try: - log2("report[%s]:%s/%s/%s", item, self.report[item][0], self.report[item][1], self.report[item][2][0:20]) - except: - pass - - if item == FILENAME_BACKTRACE: - buff = gtk.TextBuffer() - tvBacktrace = self.builder.get_object("tvBacktrace") - buff.set_text(self.report[item][CD_CONTENT]) - tvBacktrace.set_buffer(buff) - continue - - if item == FILENAME_COMMENT: - try: - if self.report[item][CD_CONTENT]: - self.old_comment = self.report[item][CD_CONTENT] - except Exception, e: - pass - continue - - if item == FILENAME_REPRODUCE: - try: - if self.report[item][CD_CONTENT]: - self.old_how_to_reproduce = self.report[item][CD_CONTENT] - except Exception, e: - pass - continue - - if self.report[item][CD_TYPE] == CD_SYS: - continue - - # item name 0| value 1| editable? 2| toggled? 3| visible?(attachment)4 - # FIXME: handle editable fields - if self.report[item][CD_TYPE] == CD_BIN: - self.builder.get_object("fAttachment").show() - vbAttachments = self.builder.get_object("vbAttachments") - toggle = gtk.CheckButton(self.report[item][CD_CONTENT]) - vbAttachments.pack_start(toggle) - # bind item to checkbox - toggle.item = item - #FIXME: temporary workaround, in 1.0.4 reporters don't care - # about this, they just send what they want to - # TicketUploader even sends coredump!! - #toggle.show() - continue - - # It must be CD_TXT field - item_label = self.builder.get_object("l%s" % item) - if item_label: - self.set_label(item_label, self.report[item][CD_CONTENT]) - else: - # no widget to show this item - # probably some new item need to adjust the GUI! - # FIXME: add some window+button to show all the info - # in raw form (smth like the old report dialog) - pass - #end for - - buff = gtk.TextBuffer() - self.show_hint_comment = (self.old_comment == COMMENT_HINT_TEXT) - if self.show_hint_comment: - buff.set_text(COMMENT_HINT_TEXT) - else: - buff.set_text(self.old_comment) - self.tvComment.set_buffer(buff) - - buff = gtk.TextBuffer() - if self.old_how_to_reproduce == "": - buff.set_text(HOW_TO_HINT_TEXT) - else: - buff.set_text(self.old_how_to_reproduce) - self.tevHowToReproduce.set_buffer(buff) - - def dehydrate(self): - ## # handle attachments - ## vbAttachments = self.builder.get_object("vbAttachments") - ## for attachment in vbAttachments.get_children(): - ## #print "%s file %s" % (["not sending","sending"][attachment.get_active()], attachment.get_label()) - ## del self.report[attachment.item] - - # handle comment - buff = self.tvComment.get_buffer() - text = buff.get_text(buff.get_start_iter(), buff.get_end_iter()) - if self.old_comment != text: - self.report[FILENAME_COMMENT] = [CD_TXT, 'y', text] - # handle how to reproduce - buff = self.tevHowToReproduce.get_buffer() - text = buff.get_text(buff.get_start_iter(), buff.get_end_iter()) - if self.old_how_to_reproduce != text: - self.report[FILENAME_REPRODUCE] = [CD_TXT, 'y', text] - # handle backtrace - tev_backtrace = self.builder.get_object("tvBacktrace") - buff = tev_backtrace.get_buffer() - text = buff.get_text(buff.get_start_iter(), buff.get_end_iter()) - self.report[FILENAME_BACKTRACE] = [CD_TXT, 'y', text] - - def check_report(self): - # FIXME: check the report for passwords and some other potentially - # sensitive info - self.dehydrate() - return True - - def run(self): - result = self.window.run() - self.window.destroy() - return (result, self.report) - -class ReporterSelector(): - def __init__(self, crashdump, daemon, log=None, parent=None): - self.connected_signals = [] - self.updates = "" - self.daemon = daemon - self.dump = crashdump - self.selected_reporters = [] - #FIXME: cache settings! Create some class to represent it like PluginList - self.settings = daemon.getSettings() - pluginlist = getPluginInfoList(daemon) - self.reporters = [] - AnalyzerActionsAndReporters = self.settings["AnalyzerActionsAndReporters"] - try: - reporters = None - try: - reporters = AnalyzerActionsAndReporters[self.dump.getAnalyzerName()+":"+self.dump.getPackageName()] - except KeyError: - pass - if not reporters: - reporters = AnalyzerActionsAndReporters[crashdump.getAnalyzerName()] - for reporter_name in reporters.split(','): - reporter = pluginlist.getReporterByName(reporter_name) - if reporter: - self.reporters.append(reporter) - except KeyError: - # Analyzer has no associated reporters. - pass - - builderfile = "%s/report.glade" % sys.path[0] - self.builder = gtk.Builder() - self.builder.add_from_file(builderfile) - self.window = self.builder.get_object("w_reporters") - b_cancel = self.builder.get_object("b_close") - - if parent: - self.window.set_position(gtk.WIN_POS_CENTER_ON_PARENT) - self.window.set_transient_for(parent) - self.window.set_modal(True) - self.connect_signal(self.window, "delete-event", self.on_window_delete) - self.connect_signal(self.window, "destroy-event", self.on_window_delete) - self.connect_signal(b_cancel, "clicked", self.on_close_clicked) - else: - # if we don't have parent we want to quit the mainloop on close - self.window.set_position(gtk.WIN_POS_CENTER) - self.connect_signal(self.window, "delete-event", gtk.main_quit) - self.connect_signal(self.window, "destroy-event", gtk.main_quit) - self.connect_signal(b_cancel, "clicked", gtk.main_quit) - - - self.pBarWindow = self.builder.get_object("pBarWindow") - self.pBarWindow.set_transient_for(self.window) - - reporters_vbox = self.builder.get_object("vb_reporters") - for reporter in self.reporters: - button = gtk.Button(str(reporter)) - self.connect_signal(button, "clicked", self.on_reporter_clicked, data=reporter) - reporters_vbox.pack_start(button) - - # progress bar window to show while bt is being extracted - self.pBarWindow = self.builder.get_object("pBarWindow") - if self.pBarWindow: - self.connect_signal(self.pBarWindow, "delete_event", self.sw_delete_event_cb) - if parent: - self.pBarWindow.set_transient_for(parent) - else: - self.pBarWindow.set_transient_for(self.window) - self.pBar = self.builder.get_object("pBar") - - # connect handlers for daemon signals - #self.ccdaemon.connect("abrt-error", self.error_cb) - self.connect_signal(daemon, "update", self.update_cb) - # for now, just treat them the same (w/o this, we don't even see daemon warnings in logs!): - #self.ccdaemon.connect("warning", self.update_cb) - #self.ccdaemon.connect("show", self.show_cb) - #self.ccdaemon.connect("daemon-state-changed", self.on_daemon_state_changed_cb) - self.connect_signal(daemon, "report-done", self.on_report_done_cb) - self.connect_signal(daemon, "analyze-complete", self.on_analyze_complete_cb, self.pBarWindow) - - def connect_signal(self, obj, signal, callback, data=None): - if data: - signal_id = obj.connect(signal, callback, data) - else: - signal_id = obj.connect(signal, callback) - self.connected_signals.append((obj, signal_id)) - - def disconnect_signals(self): - # we need to disconnect all signals in order to break all references - # to this object, otherwise python won't destroy this object and the - # signals emmited by daemon will get caught by multiple instances of - # this class - for obj, signal_id in self.connected_signals: - obj.disconnect(signal_id) - - def cleanup_and_exit(self): - if not self.window.get_property("visible"): - self.disconnect_signals() - # if the reporter selector doesn't have a parent - if not self.window.get_transient_for(): - gtk.main_quit() - - def update_cb(self, daemon, message): - self.updates += message - if self.updates[-1] != '\n': - self.updates += '\n' - message = message.replace('\n',' ') - self.builder.get_object("lStatus").set_text(message) - buff = gtk.TextBuffer() - buff.set_text(self.updates) - end = buff.get_insert() - tvUpdates = self.builder.get_object("tvUpdates") - tvUpdates.set_buffer(buff) - tvUpdates.scroll_mark_onscreen(end) - - def sw_delete_event_cb(self, widget, event, data=None): - if self.timer: - gobject.source_remove(self.timer) - widget.hide() - return True - - def show(self): - if not self.reporters: - gui_error_message(_("No reporter plugin available for this type of crash.\n" - "Please check abrt.conf.")) - elif len(self.reporters) > 1: - self.builder.get_object("vb_reporters").show_all() - self.window.show() - else: - # we have only one reporter in the list - self.selected_reporters = [str(self.reporters[0])] - self.show_report() - - def on_config_plugin_clicked(self, button, plugin, image): - ui = PluginSettingsUI(plugin, parent=self.window) - ui.hydrate() - response = ui.run() - if response == gtk.RESPONSE_APPLY: - ui.dehydrate() - if plugin.Settings.check(): - try: - plugin.save_settings_on_client_side() - except Exception, e: - gui_error_message(_("Cannot save plugin settings:\n %s" % e)) - box = image.get_parent() - im = gtk.Image() - im.set_from_stock(gtk.STOCK_APPLY, gtk.ICON_SIZE_MENU) - box.remove(image) - box.pack_start(im, expand = False, fill = False) - im.show() - image.destroy() - button.set_sensitive(False) - elif response == gtk.RESPONSE_CANCEL: - log1("cancel") - ui.destroy() - - def check_settings(self, reporters): - wrong_conf_plugs = [] - for reporter in reporters: - if reporter.Settings.check() == False: - wrong_conf_plugs.append(reporter) - - if wrong_conf_plugs: - gladefile = "%s%ssettings_wizard.glade" % (sys.path[0],"/") - builder = gtk.Builder() - builder.add_from_file(gladefile) - dialog = builder.get_object("WrongSettings") - vbWrongSettings = builder.get_object("vbWrongSettings") - for plugin in wrong_conf_plugs: - hbox = gtk.HBox() - hbox.set_spacing(6) - image = gtk.Image() - image.set_from_stock(gtk.STOCK_CANCEL, gtk.ICON_SIZE_MENU) - button = gtk.Button(_("Configure %s options" % plugin.getName())) - button.connect("clicked", self.on_config_plugin_clicked, plugin, image) - hbox.pack_start(button) - hbox.pack_start(image, expand = False, fill = False) - vbWrongSettings.pack_start(hbox) - vbWrongSettings.show_all() - dialog.set_transient_for(self.window) - dialog.set_modal(True) - response = dialog.run() - dialog.destroy() - if response != gtk.RESPONSE_YES: - # user cancelled reporting - return False - return True - - def on_reporter_clicked(self, widget, reporter): - self.selected_reporters = [reporter] - if self.check_settings(self.selected_reporters): - self.show_report() - - def on_close_clicked(self, widget): - self.disconnect_signals() - self.window.destroy() - - def on_window_delete(self, window, event): - self.disconnect_signals() - return False - - def on_report_done_cb(self, daemon, result): - try: - gobject.source_remove(self.timer) - except: - pass - self.pBarWindow.hide() - gui_report_dialog(result, self.window) - - self.cleanup_and_exit() - - def on_analyze_complete_cb(self, daemon, report, pBarWindow): - try: - gobject.source_remove(self.timer) - except: - pass - self.pBarWindow.hide() -#FIXME - why we need this?? -> timeout warnings -# try: -# dumplist = getDumpList(self.daemon) -# except Exception, e: -# print e - if not report: - gui_error_message(_("Unable to get report!\nIs debuginfo missing?")) - return - - # if we have only one reporter enabled, the window with - # the selection is not shown, so we can't use it as a parent - # and we use the mainwindow instead - if self.window.get_property("visible"): - parent_window = self.window - else: - parent_window = self.window.get_transient_for() - - report_dialog = ReporterDialog(report, self.daemon, log=self.updates, parent=parent_window) - # (response, report) - response, result = report_dialog.run() - - if response == gtk.RESPONSE_APPLY: - try: - self.pBarWindow.show_all() - self.timer = gobject.timeout_add(100, self.progress_update_cb) - pluginlist = getPluginInfoList(self.daemon) - reporters_settings = pluginlist.getReporterPluginsSettings() - log2("Report(result,reporters,settings):") - log2(" result:%s", str(result)) - # Careful, this will print reporters_settings["Password"] too - log2(" settings:%s", str(reporters_settings)) - self.daemon.Report(result, self.selected_reporters, reporters_settings) - log2("Report() returned") - #self.hydrate() - except Exception, ex: - gui_error_message(_("Reporting failed!\n%s" % ex)) - # -50 == REFRESH - elif response == -50: - self.refresh_report(report) - else: - self.cleanup_and_exit() - - # call to update the progressbar - def progress_update_cb(self, *args): - self.pBar.pulse() - return True - - def refresh_report(self, report): - self.updates = "" - self.pBarWindow.show_all() - self.timer = gobject.timeout_add(100, self.progress_update_cb) - - # show the report window with selected report - try: - self.daemon.start_job(report[CD_DUMPDIR][CD_CONTENT], force=1) - except Exception, ex: - # FIXME #3 dbus.exceptions.DBusException: org.freedesktop.DBus.Error.NoReply: Did not receive a reply - # do this async and wait for yum to end with debuginfoinstal - if self.timer: - gobject.source_remove(self.timer) - self.pBarWindow.hide() - gui_error_message(_("Error acquiring the report: %s" % ex)) - return - - def show_report(self): - self.updates = "" - # FIXME don't duplicate the code, move to function - #self.pBar.show() - self.pBarWindow.show_all() - self.timer = gobject.timeout_add(100, self.progress_update_cb) - - # show the report window with selected dump - # when getReport is done it emits "analyze-complete" and on_analyze_complete_cb is called - # FIXME: does it make sense to change it to use callback rather then signal emitting? - try: - self.daemon.start_job(self.dump.getDumpDir()) - except Exception, ex: - # FIXME #3 dbus.exceptions.DBusException: org.freedesktop.DBus.Error.NoReply: Did not receive a reply - # do this async and wait for yum to end with debuginfoinstal - if self.timer: - gobject.source_remove(self.timer) - self.pBarWindow.hide() - gui_error_message(_("Error acquiring the report: %s" % ex)) - return - - def __del__(self): - log1("ReporterSelector: instance is about to be garbage-collected") diff --git a/src/gui/CellRenderers.py b/src/gui/CellRenderers.py deleted file mode 100644 index 155d8ce3..00000000 --- a/src/gui/CellRenderers.py +++ /dev/null @@ -1,66 +0,0 @@ -# -*- coding: utf-8 -*- -import gtk - -class CellTextView(gtk.TextView, gtk.CellEditable): - - __gtype_name__ = "CellTextView" - - def do_editing_done(self, *args): - self.remove_widget() - - def do_remove_widget(self, *args): - pass - - def do_start_editing(self, *args): - pass - - def get_text(self): - text_buffer = self.get_buffer() - bounds = text_buffer.get_bounds() - return text_buffer.get_text(*bounds) - - def set_text(self, text): - self.get_buffer().set_text(text) - - -class MultilineCellRenderer(gtk.CellRendererText): - - __gtype_name__ = "MultilineCellRenderer" - - def __init__(self): - gtk.CellRendererText.__init__(self) - self._in_editor_menu = False - self.old_text = "" - - def _on_editor_focus_out_event(self, editor, event): - if self._in_editor_menu: return - editor.remove_widget() - self.emit("edited", editor.get_data("path"), editor.get_text()) - - def _on_editor_key_press_event(self, editor, event): - if event.state & (gtk.gdk.SHIFT_MASK | gtk.gdk.CONTROL_MASK): return - if event.keyval == gtk.keysyms.Escape: - editor.set_text(self.old_text) - editor.remove_widget() - self.emit("editing-canceled") - - def _on_editor_populate_popup(self, editor, menu): - self._in_editor_menu = True - def on_menu_unmap(menu, self): - self._in_editor_menu = False - menu.connect("unmap", on_menu_unmap, self) - - def do_start_editing(self, event, widget, path, bg_area, cell_area, flags): - editor = CellTextView() - editor.modify_font(self.props.font_desc) - self.old_text = self.props.text - editor.set_text(self.props.text) - editor.set_size_request(cell_area.width, cell_area.height) - editor.set_border_width(min(self.props.xpad, self.props.ypad)) - editor.set_data("path", path) - editor.connect("focus-out-event", self._on_editor_focus_out_event) - editor.connect("key-press-event", self._on_editor_key_press_event) - editor.connect("populate-popup", self._on_editor_populate_popup) - editor.show() - return editor - -- cgit