From 42b4e4a895db6a389bbe0d21855fdf00c294dd90 Mon Sep 17 00:00:00 2001 From: Sagar Chalise Date: Fri, 19 Jul 2013 00:56:11 +0545 Subject: [PATCH 01/28] Ported to gi.repository.. still some glitch though --- geany/__init__.py | 2 +- geany/console.py | 91 +++---- geany/loader.py | 324 ++++++++++++------------ geany/manager.py | 345 +++++++++++++------------- geany/plugin.py | 200 +++++++-------- geany/signalmanager.py | 96 ++++--- plugins/console.py | 551 ++++++++++++++++++++--------------------- plugins/hello.py | 6 +- 8 files changed, 795 insertions(+), 820 deletions(-) diff --git a/geany/__init__.py b/geany/__init__.py index 493dfa4..1cf6030 100644 --- a/geany/__init__.py +++ b/geany/__init__.py @@ -66,4 +66,4 @@ signals = SignalManager() import plugin -from plugin import Plugin +from plugin import Plugin \ No newline at end of file diff --git a/geany/console.py b/geany/console.py index 6ae8462..2742aa6 100644 --- a/geany/console.py +++ b/geany/console.py @@ -28,21 +28,16 @@ # To modify output appearance, set attributes of console.stdout_tag and # console.stderr_tag. # -# Console may subclass a type other than gtk.TextView, to allow syntax highlighting and stuff, +# Console may subclass a type other than Gtk.TextView, to allow syntax highlighting and stuff, # e.g.: # console_type = pyconsole.ConsoleType(moo.TextView) -# console = console_type(use_rlcompleter=False, start_script="import moo\nimport gtk\n") +# console = console_type(use_rlcompleter=False, start_script="import moo\nimport Gtk\n") # # This widget is not a replacement for real terminal with python running # inside: GtkTextView is not a terminal. # The use case is: you have a python program, you create this widget, # and inspect your program interiors. - -import gtk -import gtk.gdk as gdk -import gobject -import pango -import gtk.keysyms as _keys +from gi.repository import GObject, Gtk, Gdk, Pango import code import sys import keyword @@ -109,8 +104,8 @@ def get(self, dir, text): def __init__(self): object.__init__(self) - self.set_wrap_mode(gtk.WRAP_CHAR) - self.modify_font(pango.FontDescription("Monospace")) + self.set_wrap_mode(Gtk.WrapMode.CHAR) + self.modify_font(Pango.FontDescription("Monospace")) self.buffer = self.get_buffer() self.buffer.connect("insert-text", self.on_buf_insert) @@ -160,7 +155,7 @@ def raw_input(self, ps=None): self.thaw_undo() self.__move_cursor_to(iter) - self.scroll_to_mark(self.cursor, 0.2) + self.scroll_to_mark(self.cursor, 0.2, use_align=False, xalign=0.5, yalign=0.5) self.in_raw_input = True @@ -177,7 +172,7 @@ def on_buf_mark_set(self, buffer, iter, mark): if iter.compare(self.__get_start()) >= 0 and \ iter.compare(self.__get_end()) <= 0: buffer.move_mark_by_name("cursor", iter) - self.scroll_to_mark(self.cursor, 0.2) + self.scroll_to_mark(self.cursor, 0.2, use_align=False, xalign=0.5, yalign=0.5) def __insert(self, iter, text): self.do_insert = True @@ -242,27 +237,27 @@ def do_key_press_event(self, event, parent_type): self.tab_pressed = 0 handled = True - state = event.state & (gdk.SHIFT_MASK | - gdk.CONTROL_MASK | - gdk.MOD1_MASK) + state = event.state & (Gdk.ModifierType.SHIFT_MASK | + Gdk.ModifierType.CONTROL_MASK | + Gdk.ModifierType.MOD1_MASK) keyval = event.keyval if not state: - if keyval == _keys.Return: + if keyval == Gdk.KEY_Return: self._commit() - elif keyval == _keys.Up: + elif keyval == Gdk.KEY_Up: self.__history(-1) - elif keyval == _keys.Down: + elif keyval == Gdk.KEY_Down: self.__history(1) - elif keyval == _keys.Left: + elif keyval == Gdk.KEY_Left: self.__move_cursor(-1) - elif keyval == _keys.Right: + elif keyval == Gdk.KEY_Right: self.__move_cursor(1) - elif keyval == _keys.Home: + elif keyval == Gdk.KEY_Home: self.__move_cursor(-10000) - elif keyval == _keys.End: + elif keyval == Gdk.KEY_End: self.__move_cursor(10000) - elif keyval == _keys.Tab: + elif keyval == Gdk.KEY_Tab: cursor = self.__get_cursor() if cursor.starts_line(): handled = False @@ -275,8 +270,8 @@ def do_key_press_event(self, event, parent_type): self.__complete() else: handled = False - elif state == gdk.CONTROL_MASK: - if keyval == _keys.u: + elif state == Gdk.ModifierType.CONTROL_MASK: + if keyval == Gdk.KEY_u: start = self.__get_start() end = self.__get_cursor() self.__delete(start, end) @@ -286,7 +281,7 @@ def do_key_press_event(self, event, parent_type): handled = False if not handled: - return parent_type.do_key_press_event(self, event) + return parent_type.do_key_press_event(self, event.key) else: return True @@ -296,7 +291,7 @@ def __history(self, dir): if not new_text is None: self.__replace_line(new_text) self.__move_cursor(0) - self.scroll_to_mark(self.cursor, 0.2) + self.scroll_to_mark(self.cursor, 0.2, use_align=False, xalign=0.5, yalign=0.5) def __get_cursor(self): return self.buffer.get_iter_at_mark(self.cursor) @@ -343,9 +338,9 @@ def __delete_at_cursor(self, howmany): self.__delete(iter, end) def __get_width(self): - if not (self.flags() & gtk.REALIZED): + if not (Gtk.get_realized()): return 80 - layout = pango.Layout(self.get_pango_context()) + layout = Pango.Layout(self.get_pango_context()) letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" layout.set_text(letters) pix_width = layout.get_pixel_size()[0] @@ -386,7 +381,7 @@ def __print_completions(self, completions): self.__insert(iter, "%s%s%s" % (self.ps, line_start, line_end)) iter.set_line_offset(len(self.ps) + len(line_start)) self.__move_cursor_to(iter) - self.scroll_to_mark(self.cursor, 0.2) + self.scroll_to_mark(self.cursor, 0.2, use_align=False, xalign=0.5, yalign=0.5) def __complete(self): text = self.__get_text(self.__get_start(), self.__get_cursor()) @@ -523,10 +518,7 @@ def do_command(self, code): self.showtraceback() def runcode(self, code): - if gtk.pygtk_version[1] < 8: - self.do_command(code) - else: - self.emit("command", code) + self.emit("command", code) def exec_command(self, command): if self._get_line(): @@ -596,28 +588,25 @@ def complete(self, text): return completions -def ReadLineType(t=gtk.TextView): +def ReadLineType(t=Gtk.TextView): class readline(t, _ReadLine): def __init__(self, *args, **kwargs): t.__init__(self) _ReadLine.__init__(self, *args, **kwargs) def do_key_press_event(self, event): return _ReadLine.do_key_press_event(self, event, t) - gobject.type_register(readline) + GObject.type_register(readline) return readline -def ConsoleType(t=gtk.TextView): +def ConsoleType(t=Gtk.TextView): class console_type(t, _Console): __gsignals__ = { - 'command' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (object,)), + 'command' : (GObject.SignalFlags.RUN_LAST, None, (object,)), 'key-press-event' : 'override' } def __init__(self, *args, **kwargs): - if gtk.pygtk_version[1] < 8: - gobject.GObject.__init__(self) - else: - t.__init__(self) + GObject.GObject.__init__(self) _Console.__init__(self, *args, **kwargs) def do_command(self, code): @@ -626,9 +615,7 @@ def do_command(self, code): def do_key_press_event(self, event): return _Console.do_key_press_event(self, event, t) - if gtk.pygtk_version[1] < 8: - gobject.type_register(console_type) - + GObject.type_register(console_type) return console_type ReadLine = ReadLineType() @@ -642,19 +629,19 @@ def _create_widget(start_script): return console def _make_window(start_script="import geany\n"): - window = gtk.Window() + window = Gtk.Window() window.set_title("Python Console") - swin = gtk.ScrolledWindow() - swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS) + swin = Gtk.ScrolledWindow() + swin.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.ALWAYS) window.add(swin) console = _create_widget(start_script) swin.add(console) window.set_default_size(500, 400) window.show_all() - if not gtk.main_level(): - window.connect("destroy", gtk.main_quit) - gtk.main() + if not Gtk.main_level(): + window.connect("destroy", Gtk.main_quit) + Gtk.main() return console @@ -662,4 +649,4 @@ def _make_window(start_script="import geany\n"): import sys import os sys.path.insert(0, os.getcwd()) - _make_window(sys.argv[1:] and '\n'.join(sys.argv[1:]) + '\n' or None) + _make_window(sys.argv[1:] and '\n'.join(sys.argv[1:]) + '\n' or None) \ No newline at end of file diff --git a/geany/loader.py b/geany/loader.py index 14b9b73..cfbe36e 100644 --- a/geany/loader.py +++ b/geany/loader.py @@ -8,165 +8,165 @@ class PluginLoader(object): - plugins = {} - - def __init__(self, plugin_dirs): - - self.plugin_dirs = plugin_dirs - - self.available_plugins = [] - for plugin in self.iter_plugin_info(): - self.available_plugins.append(plugin) - - self.restore_loaded_plugins() - - - def update_loaded_plugins_file(self): - for path in self.plugin_dirs: - if os.path.isdir(path): - try: - state_file = os.path.join(path, '.loaded_plugins') - with open(state_file, 'w') as f: - for plugfn in self.plugins: - f.write("%s\n" % plugfn) - except IOError as err: - if err.errno == 13: #perms - pass - else: - raise - - - def restore_loaded_plugins(self): - loaded_plugins = [] - for path in reversed(self.plugin_dirs): - state_file = os.path.join(path, ".loaded_plugins") - if os.path.exists(state_file): - for line in open(state_file): - line = line.strip() - if line not in loaded_plugins: - loaded_plugins.append(line) - for filename in loaded_plugins: - self.load_plugin(filename) - - - def load_all_plugins(self): - - for plugin_info in self.iter_plugin_info(): - if plugin_filename.endswith('test.py'): # hack for testing - continue - plug = self.load_plugin(plugin_info.filename) - if plug: - print("Loaded plugin: %s" % plugin_info.filename) - print(" Name: %s v%s" % (plug.name, plug.version)) - print(" Desc: %s" % plug.description) - print(" Author: %s" % plug.author) - - - def unload_all_plugins(self): - - for plugin in self.plugins: - self.unload_plugin(plugin) - - - def reload_all_plugins(self): - - self.unload_all_plugins() - self.load_all_plugins() - - - def iter_plugin_info(self): - - for d in self.plugin_dirs: - if os.path.isdir(d): - for current_file in os.listdir(d): - #check inside folders inside the plugins dir so we can load .py files here as plugins - current_path=os.path.abspath(os.path.join(d, current_file)) - if os.path.isdir(current_path): - for plugin_folder_file in os.listdir(current_path): - if plugin_folder_file.endswith('.py'): - #loop around results if its fails to load will never reach yield - for p in self.load_plugin_info(current_path,plugin_folder_file): - yield p - - #not a sub directory so if it ends with .py lets just attempt to load it as a plugin - if current_file.endswith('.py'): - #loop around results if its fails to load will never reach yield - for p in self.load_plugin_info(d,current_file): - yield p - - def load_plugin_info(self,d,f): - filename = os.path.abspath(os.path.join(d, f)) - if filename.endswith("test.py"): - pass - text = open(filename).read() - module_name = os.path.basename(filename)[:-3] - try: - module = imp.load_source(module_name, filename) - except ImportError as exc: - print "Error: failed to import settings module ({})".format(exc) - module=None - if module: - for k, v in module.__dict__.iteritems(): - if k == geany.Plugin.__name__: - continue - try: - if issubclass(v, geany.Plugin): - inf = PluginInfo( - filename, - getattr(v, '__plugin_name__'), - getattr(v, '__plugin_version__', ''), - getattr(v, '__plugin_description__', ''), - getattr(v, '__plugin_author__', ''), - v) - yield inf - - except TypeError: - continue - - - def load_plugin(self, filename): - - for avail in self.available_plugins: - if avail.filename == filename: - inst = avail.cls() - self.plugins[filename] = inst - self.update_loaded_plugins_file() - geany.ui_utils.set_statusbar('GeanyPy: plugin activated: %s' % - inst.name, True) - return inst - - - def unload_plugin(self, filename): - - try: - plugin = self.plugins[filename] - name = plugin.name - plugin.cleanup() - del self.plugins[filename] - self.update_loaded_plugins_file() - geany.ui_utils.set_statusbar('GeanyPy: plugin deactivated: %s' % - name, True) - except KeyError: - print("Unable to unload plugin '%s': it's not loaded" % filename) - - - def reload_plugin(self, filename): - - if filename in self.plugins: - self.unload_plugin(filename) - self.load_plugin(filename) - - - def plugin_has_help(self, filename): - - for plugin_info in self.iter_plugin_info(): - if plugin_info.filename == filename: - return hasattr(plugin_info.cls, 'show_help') - - - def plugin_has_configure(self, filename): - - try: - return hasattr(self.plugins[filename], 'show_configure') - except KeyError: - return None + plugins = {} + + def __init__(self, plugin_dirs): + + self.plugin_dirs = plugin_dirs + + self.available_plugins = [] + for plugin in self.iter_plugin_info(): + self.available_plugins.append(plugin) + + self.restore_loaded_plugins() + + + def update_loaded_plugins_file(self): + for path in self.plugin_dirs: + if os.path.isdir(path): + try: + state_file = os.path.join(path, '.loaded_plugins') + with open(state_file, 'w') as f: + for plugfn in self.plugins: + f.write("%s\n" % plugfn) + except IOError as err: + if err.errno == 13: #perms + pass + else: + raise + + + def restore_loaded_plugins(self): + loaded_plugins = [] + for path in reversed(self.plugin_dirs): + state_file = os.path.join(path, ".loaded_plugins") + if os.path.exists(state_file): + for line in open(state_file): + line = line.strip() + if line not in loaded_plugins: + loaded_plugins.append(line) + for filename in loaded_plugins: + self.load_plugin(filename) + + + def load_all_plugins(self): + + for plugin_info in self.iter_plugin_info(): + if plugin_filename.endswith('test.py'): # hack for testing + continue + plug = self.load_plugin(plugin_info.filename) + if plug: + print("Loaded plugin: %s" % plugin_info.filename) + print(" Name: %s v%s" % (plug.name, plug.version)) + print(" Desc: %s" % plug.description) + print(" Author: %s" % plug.author) + + + def unload_all_plugins(self): + + for plugin in self.plugins: + self.unload_plugin(plugin) + + + def reload_all_plugins(self): + + self.unload_all_plugins() + self.load_all_plugins() + + + def iter_plugin_info(self): + + for d in self.plugin_dirs: + if os.path.isdir(d): + for current_file in os.listdir(d): + #check inside folders inside the plugins dir so we can load .py files here as plugins + current_path=os.path.abspath(os.path.join(d, current_file)) + if os.path.isdir(current_path): + for plugin_folder_file in os.listdir(current_path): + if plugin_folder_file.endswith('.py'): + #loop around results if its fails to load will never reach yield + for p in self.load_plugin_info(current_path,plugin_folder_file): + yield p + + #not a sub directory so if it ends with .py lets just attempt to load it as a plugin + if current_file.endswith('.py'): + #loop around results if its fails to load will never reach yield + for p in self.load_plugin_info(d,current_file): + yield p + + def load_plugin_info(self,d,f): + filename = os.path.abspath(os.path.join(d, f)) + if filename.endswith("test.py"): + pass + text = open(filename).read() + module_name = os.path.basename(filename)[:-3] + try: + module = imp.load_source(module_name, filename) + except ImportError as exc: + print "Error: failed to import settings module ({})".format(exc) + module=None + if module: + for k, v in module.__dict__.iteritems(): + if k == geany.Plugin.__name__: + continue + try: + if issubclass(v, geany.Plugin): + inf = PluginInfo( + filename, + getattr(v, '__plugin_name__'), + getattr(v, '__plugin_version__', ''), + getattr(v, '__plugin_description__', ''), + getattr(v, '__plugin_author__', ''), + v) + yield inf + + except TypeError: + continue + + + def load_plugin(self, filename): + + for avail in self.available_plugins: + if avail.filename == filename: + inst = avail.cls() + self.plugins[filename] = inst + self.update_loaded_plugins_file() + geany.ui_utils.set_statusbar('GeanyPy: plugin activated: %s' % + inst.name, True) + return inst + + + def unload_plugin(self, filename): + + try: + plugin = self.plugins[filename] + name = plugin.name + plugin.cleanup() + del self.plugins[filename] + self.update_loaded_plugins_file() + geany.ui_utils.set_statusbar('GeanyPy: plugin deactivated: %s' % + name, True) + except KeyError: + print("Unable to unload plugin '%s': it's not loaded" % filename) + + + def reload_plugin(self, filename): + + if filename in self.plugins: + self.unload_plugin(filename) + self.load_plugin(filename) + + + def plugin_has_help(self, filename): + + for plugin_info in self.iter_plugin_info(): + if plugin_info.filename == filename: + return hasattr(plugin_info.cls, 'show_help') + + + def plugin_has_configure(self, filename): + + try: + return hasattr(self.plugins[filename], 'show_configure') + except KeyError: + return None diff --git a/geany/manager.py b/geany/manager.py index 9c7e9a4..e3b753d 100644 --- a/geany/manager.py +++ b/geany/manager.py @@ -1,179 +1,172 @@ -import gtk -import gobject -import glib +from gi.repository import GObject, GLib, Gtk from htmlentitydefs import name2codepoint from loader import PluginLoader - -class PluginManager(gtk.Dialog): - - def __init__(self, plugin_dirs=[]): - gtk.Dialog.__init__(self, title="Plugin Manager") - self.loader = PluginLoader(plugin_dirs) - - self.set_default_size(400, 450) - self.set_has_separator(True) - icon = self.render_icon(gtk.STOCK_PREFERENCES, gtk.ICON_SIZE_MENU) - self.set_icon(icon) - - self.connect("response", lambda w,d: self.hide()) - - vbox = gtk.VBox(False, 12) - vbox.set_border_width(12) - - lbl = gtk.Label("Choose plugins to load or unload:") - lbl.set_alignment(0.0, 0.5) - vbox.pack_start(lbl, False, False, 0) - - sw = gtk.ScrolledWindow() - sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) - sw.set_shadow_type(gtk.SHADOW_ETCHED_IN) - vbox.pack_start(sw, True, True, 0) - - self.treeview = gtk.TreeView() - sw.add(self.treeview) - - vbox.show_all() - - self.get_content_area().add(vbox) - - action_area = self.get_action_area() - action_area.set_spacing(0) - action_area.set_homogeneous(False) - - btn = gtk.Button(stock=gtk.STOCK_CLOSE) - btn.set_border_width(6) - btn.connect("clicked", lambda x: self.response(gtk.RESPONSE_CLOSE)) - action_area.pack_start(btn, False, True, 0) - btn.show() - - self.btn_help = gtk.Button(stock=gtk.STOCK_HELP) - self.btn_help.set_border_width(6) - self.btn_help.set_no_show_all(True) - action_area.pack_start(self.btn_help, False, True, 0) - action_area.set_child_secondary(self.btn_help, True) - - self.btn_prefs = gtk.Button(stock=gtk.STOCK_PREFERENCES) - self.btn_prefs.set_border_width(6) - self.btn_prefs.set_no_show_all(True) - action_area.pack_start(self.btn_prefs, False, True, 0) - action_area.set_child_secondary(self.btn_prefs, True) - - action_area.show() - - self.load_plugins_list() - - - def on_help_button_clicked(self, button, treeview, model): - path = treeview.get_cursor()[0] - iter = model.get_iter(path) - filename = model.get_value(iter, 2) - for plugin in self.loader.available_plugins: - if plugin.filename == filename: - plugin.cls.show_help() - break - else: - print("Plugin does not support help function") - - - def on_preferences_button_clicked(self, button, treeview, model): - path = treeview.get_cursor()[0] - iter = model.get_iter(path) - filename = model.get_value(iter, 2) - try: - self.loader.plugins[filename].show_configure() - except KeyError: - print("Plugin is not loaded, can't run configure function") - - - def activate_plugin(self, filename): - self.loader.load_plugin(filename) - - - def deactivate_plugin(self, filename): - self.loader.unload_plugin(filename) - - - def load_plugins_list(self): - liststore = gtk.ListStore(gobject.TYPE_BOOLEAN, str, str) - - self.btn_help.connect("clicked", - self.on_help_button_clicked, self.treeview, liststore) - - self.btn_prefs.connect("clicked", - self.on_preferences_button_clicked, self.treeview, liststore) - - self.treeview.set_model(liststore) - self.treeview.set_headers_visible(False) - self.treeview.set_grid_lines(True) - - check_renderer = gtk.CellRendererToggle() - check_renderer.set_radio(False) - check_renderer.connect('toggled', self.on_plugin_load_toggled, liststore) - text_renderer = gtk.CellRendererText() - - check_column = gtk.TreeViewColumn(None, check_renderer, active=0) - text_column = gtk.TreeViewColumn(None, text_renderer, markup=1) - - self.treeview.append_column(check_column) - self.treeview.append_column(text_column) - - self.treeview.connect('row-activated', - self.on_row_activated, check_renderer, liststore) - self.treeview.connect('cursor-changed', - self.on_selected_plugin_changed, liststore) - - self.load_sorted_plugins_info(liststore) - - - def load_sorted_plugins_info(self, list_store): - - plugin_info_list = list(self.loader.iter_plugin_info()) - #plugin_info_list.sort(key=lambda pi: pi[1]) - - for plugin_info in plugin_info_list: - - lbl = str('%s %s\n%s\n' + - 'Author: %s\n' + - 'Filename: %s') % ( - glib.markup_escape_text(plugin_info.name), - glib.markup_escape_text(plugin_info.version), - glib.markup_escape_text(plugin_info.description), - glib.markup_escape_text(plugin_info.author), - glib.markup_escape_text(plugin_info.filename)) - - loaded = plugin_info.filename in self.loader.plugins - - list_store.append([loaded, lbl, plugin_info.filename]) - - - def on_selected_plugin_changed(self, treeview, model): - - path = treeview.get_cursor()[0] - iter = model.get_iter(path) - filename = model.get_value(iter, 2) - active = model.get_value(iter, 0) - - if self.loader.plugin_has_configure(filename): - self.btn_prefs.set_visible(True) - else: - self.btn_prefs.set_visible(False) - - if self.loader.plugin_has_help(filename): - self.btn_help.set_visible(True) - else: - self.btn_help.set_visible(False) - - - def on_plugin_load_toggled(self, cell, path, model): - active = not cell.get_active() - iter = model.get_iter(path) - model.set_value(iter, 0, active) - if active: - self.activate_plugin(model.get_value(iter, 2)) - else: - self.deactivate_plugin(model.get_value(iter, 2)) - - - def on_row_activated(self, tvw, path, view_col, cell, model): - self.on_plugin_load_toggled(cell, path, model) +class PluginManager(Gtk.Dialog): + def __init__(self, plugin_dirs=[]): + super(PluginManager, self).__init__(title="Plugin Manager") + self.loader = PluginLoader(plugin_dirs) + self.set_default_size(400, 450) + icon = self.render_icon(Gtk.STOCK_PREFERENCES, Gtk.IconSize.MENU) + self.set_icon(icon) + + self.connect("response", lambda w,d: self.hide()) + + vbox = Gtk.VBox(False, 12) + vbox.set_border_width(12) + + lbl = Gtk.Label("Choose plugins to load or unload:") + lbl.set_alignment(0.0, 0.5) + vbox.pack_start(lbl, False, False, 0) + + sw = Gtk.ScrolledWindow() + sw.set_hexpand(True) + sw.set_vexpand(True) + sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) + sw.set_shadow_type(Gtk.ShadowType.ETCHED_IN) + vbox.pack_start(sw, True, True, 0) + + self.treeview = Gtk.TreeView() + sw.add(self.treeview) + + vbox.show_all() + + self.get_content_area().add(vbox) + + action_area = self.get_action_area() + action_area.set_spacing(0) + action_area.set_homogeneous(False) + + btn = Gtk.Button(stock=Gtk.STOCK_CLOSE) + btn.set_border_width(6) + btn.connect("clicked", lambda x: self.response(Gtk.ResponseType.CLOSE)) + action_area.pack_start(btn, False, True, 0) + btn.show() + + self.btn_help = Gtk.Button(stock=Gtk.STOCK_HELP) + self.btn_help.set_border_width(6) + self.btn_help.set_no_show_all(True) + action_area.pack_start(self.btn_help, False, True, 0) + action_area.set_child_secondary(self.btn_help, True) + + self.btn_prefs = Gtk.Button(stock=Gtk.STOCK_PREFERENCES) + self.btn_prefs.set_border_width(6) + self.btn_prefs.set_no_show_all(True) + action_area.pack_start(self.btn_prefs, False, True, 0) + action_area.set_child_secondary(self.btn_prefs, True) + + action_area.show() + + self.load_plugins_list() + + def on_help_button_clicked(self, button, treeview, model): + path = treeview.get_cursor()[0] + iter = model.get_iter(path) + filename = model.get_value(iter, 2) + for plugin in self.loader.available_plugins: + if plugin.filename == filename: + plugin.cls.show_help() + break + else: + print("Plugin does not support help function") + + + def on_preferences_button_clicked(self, button, treeview, model): + path = treeview.get_cursor()[0] + iter = model.get_iter(path) + filename = model.get_value(iter, 2) + try: + self.loader.plugins[filename].show_configure() + except KeyError: + print("Plugin is not loaded, can't run configure function") + + + def activate_plugin(self, filename): + self.loader.load_plugin(filename) + + + def deactivate_plugin(self, filename): + self.loader.unload_plugin(filename) + + + def load_plugins_list(self): + liststore = Gtk.ListStore(GObject.TYPE_BOOLEAN, str, str) + + self.btn_help.connect("clicked", + self.on_help_button_clicked, self.treeview, liststore) + + self.btn_prefs.connect("clicked", + self.on_preferences_button_clicked, self.treeview, liststore) + + self.treeview.set_model(liststore) + self.treeview.set_headers_visible(False) + self.treeview.set_grid_lines(True) + + check_renderer = Gtk.CellRendererToggle() + check_renderer.set_radio(False) + check_renderer.connect('toggled', self.on_plugin_load_toggled, liststore) + text_renderer = Gtk.CellRendererText() + check_column = Gtk.TreeViewColumn(None, check_renderer, active=0) + text_column = Gtk.TreeViewColumn(None, text_renderer, markup=1) + + self.treeview.append_column(check_column) + self.treeview.append_column(text_column) + + self.treeview.connect('row-activated', + self.on_row_activated, check_renderer, liststore) + self.treeview.connect('cursor-changed', + self.on_selected_plugin_changed, liststore) + + self.load_sorted_plugins_info(liststore) + + + def load_sorted_plugins_info(self, list_store): + plugin_info_list = list(self.loader.iter_plugin_info()) + #plugin_info_list.sort(key=lambda pi: pi[1]) + + for plugin_info in plugin_info_list: + + lbl = str('%s %s\n%s\n' + + 'Author: %s\n' + + 'Filename: %s') % ( + GLib.markup_escape_text(plugin_info.name), + GLib.markup_escape_text(plugin_info.version), + GLib.markup_escape_text(plugin_info.description), + GLib.markup_escape_text(plugin_info.author), + GLib.markup_escape_text(plugin_info.filename)) + + loaded = plugin_info.filename in self.loader.plugins + + list_store.append([loaded, lbl, plugin_info.filename]) + + + def on_selected_plugin_changed(self, treeview, model): + + path = treeview.get_cursor()[0] + iter = model.get_iter(path) + filename = model.get_value(iter, 2) + active = model.get_value(iter, 0) + + if self.loader.plugin_has_configure(filename): + self.btn_prefs.set_visible(True) + else: + self.btn_prefs.set_visible(False) + + if self.loader.plugin_has_help(filename): + self.btn_help.set_visible(True) + else: + self.btn_help.set_visible(False) + + + def on_plugin_load_toggled(self, cell, path, model): + active = not cell.get_active() + iter = model.get_iter(path) + model.set_value(iter, 0, active) + if active: + self.activate_plugin(model.get_value(iter, 2)) + else: + self.deactivate_plugin(model.get_value(iter, 2)) + + + def on_row_activated(self, tvw, path, view_col, cell, model): + self.on_plugin_load_toggled(cell, path, model) \ No newline at end of file diff --git a/geany/plugin.py b/geany/plugin.py index 18e0ba2..3399092 100644 --- a/geany/plugin.py +++ b/geany/plugin.py @@ -2,30 +2,30 @@ All plugins need to import this module and inherit from the Plugin class. A basic plugin could look something like this: - import geany - from geany.plugin import Plugin + import geany + from geany.plugin import Plugin - class OpenNewDocumentPlugin(Plugin): + class OpenNewDocumentPlugin(Plugin): - __plugin_name__ = "Open new document plugin" + __plugin_name__ = "Open new document plugin" - _doc = None + _doc = None - def __init__(self): - Plugin.__init__(self) - print "About to open a new document" - self.open_document('/path/to/some/file') + def __init__(self): + Plugin.__init__(self) + print "About to open a new document" + self.open_document('/path/to/some/file') - def open_document(self, filename): - self._doc = geany.document.open(filename) + def open_document(self, filename): + self._doc = geany.document.open(filename) - def close_document(self): - self._doc.close() - self._doc = None + def close_document(self): + self._doc.close() + self._doc = None - def cleanup(self): - if self._doc is not None: - self._doc.close() + def cleanup(self): + if self._doc is not None: + self._doc.close() The guts of the API are exposed to plugins through the `geany` package and its modules. @@ -38,86 +38,86 @@ def cleanup(self): class Plugin(object): - """ - Base class for all plugins. All plugins must inherit from this in order - to be properly detected. - """ - - # Child classes should implement these (at least __plugin__name__) - #__plugin_name__ = None - #__plugin_description__ = None - #__plugin_version__ = None - #__plugin_author__ = None - - - _events = { - "document-open": [], - # TODO: add more events here - } - - - def __init__(self): - """ - When the plugin is loaded its __init__() function will be called - so that's a good place to put plugin initialization code. - """ - - - - def cleanup(self): - """ - When the plugin is unloaded the cleanup() function will be called, so - it's a good place to put and clean-up/tear-down code. - """ - pass - - - @property - def __plugin_name__(self): - """ - Plugins must implement a __plugin_name__ attribute that returns the - string name of the plugin. - """ - raise NotImplementedError( - "Plugin's must implement the __plugin_name__ attribute.") - - - @property - def name(self): - """ - Get plugin's name. - """ - return self.__plugin_name__ - - - @property - def description(self): - """ - Get plugin's description. - """ - if hasattr(self, '__plugin_description__'): - return self.__plugin_description__ - else: - return "" - - - @property - def version(self): - """ - Get plugin's version. - """ - if hasattr(self, '__plugin_version__'): - return self.__plugin_version__ - else: - return "" - - - @property - def author(self): - """ - Get plugin's author. - """ - if hasattr(self, '__plugin_author__'): - return self.__plugin_author__ - else: - return "" + """ + Base class for all plugins. All plugins must inherit from this in order + to be properly detected. + """ + + # Child classes should implement these (at least __plugin__name__) + #__plugin_name__ = None + #__plugin_description__ = None + #__plugin_version__ = None + #__plugin_author__ = None + + + _events = { + "document-open": [], + # TODO: add more events here + } + + + def __init__(self): + """ + When the plugin is loaded its __init__() function will be called + so that's a good place to put plugin initialization code. + """ + + + + def cleanup(self): + """ + When the plugin is unloaded the cleanup() function will be called, so + it's a good place to put and clean-up/tear-down code. + """ + pass + + + @property + def __plugin_name__(self): + """ + Plugins must implement a __plugin_name__ attribute that returns the + string name of the plugin. + """ + raise NotImplementedError( + "Plugin's must implement the __plugin_name__ attribute.") + + + @property + def name(self): + """ + Get plugin's name. + """ + return self.__plugin_name__ + + + @property + def description(self): + """ + Get plugin's description. + """ + if hasattr(self, '__plugin_description__'): + return self.__plugin_description__ + else: + return "" + + + @property + def version(self): + """ + Get plugin's version. + """ + if hasattr(self, '__plugin_version__'): + return self.__plugin_version__ + else: + return "" + + + @property + def author(self): + """ + Get plugin's author. + """ + if hasattr(self, '__plugin_author__'): + return self.__plugin_author__ + else: + return "" \ No newline at end of file diff --git a/geany/signalmanager.py b/geany/signalmanager.py index 45a434e..3e0d69e 100644 --- a/geany/signalmanager.py +++ b/geany/signalmanager.py @@ -3,56 +3,54 @@ all signals on. The signals are emitted from the C code in signalmanager.c, where the Geany types get wrapped in PyObject types. """ +from gi.repository import GObject -import gobject +class SignalManager(GObject.GObject): + """ + Manages callback functions for events emitted by Geany's internal GObject. + """ + __gsignals__ = { + 'build-start': (GObject.SignalFlags.RUN_LAST, None, + ()), + 'document-activate': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'document-before-save': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'document-close': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'document-filetype-set': (GObject.SignalFlags.RUN_LAST, None, + (object, object)), + 'document-new': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'document-open': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'document-reload': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'document-save': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'editor-notify': (GObject.SignalFlags.RUN_LAST, GObject.TYPE_BOOLEAN, + (object, object)), + 'geany-startup-complete': (GObject.SignalFlags.RUN_LAST, None, + ()), + 'project-close': (GObject.SignalFlags.RUN_LAST, None, + ()), + 'project-dialog-confirmed': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'project-dialog-open': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'project-dialog-close': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'project-open': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'project-save': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'update-editor-menu': (GObject.SignalFlags.RUN_LAST, None, + (GObject.TYPE_STRING, GObject.TYPE_INT, + object)), + } # __gsignals__ -class SignalManager(gobject.GObject): - """ - Manages callback functions for events emitted by Geany's internal GObject. - """ - __gsignals__ = { - 'build-start': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - ()), - 'document-activate': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'document-before-save': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'document-close': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'document-filetype-set': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT)), - 'document-new': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'document-open': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'document-reload': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'document-save': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'editor-notify': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_BOOLEAN, - (gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT)), - 'geany-startup-complete': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - ()), - 'project-close': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - ()), - 'project-dialog-confirmed': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'project-dialog-open': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'project-dialog-close': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'project-open': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'project-save': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'update-editor-menu': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_STRING, gobject.TYPE_INT, - gobject.TYPE_PYOBJECT)), - } # __gsignals__ - - def __init__(self): - self.__gobject_init__() - -gobject.type_register(SignalManager) + def __init__(self): + super(SignalManager, self).__init__() +GObject.type_register(SignalManager) \ No newline at end of file diff --git a/plugins/console.py b/plugins/console.py index ee26ae3..644234e 100644 --- a/plugins/console.py +++ b/plugins/console.py @@ -2,312 +2,309 @@ from ConfigParser import SafeConfigParser import geany import geany.console -import gobject -import gtk -import gtk.gdk as gdk -import pango +from gi.repository import GObject, Gtk, Gdk, Pango -WIDGET_STATES = [ gtk.STATE_NORMAL, gtk.STATE_ACTIVE, gtk.STATE_PRELIGHT, - gtk.STATE_SELECTED, gtk.STATE_INSENSITIVE ] +WIDGET_STATES = [ Gtk.StateFlags.NORMAL, Gtk.StateFlags.ACTIVE, Gtk.StateFlags.PRELIGHT, + Gtk.StateFlags.SELECTED, Gtk.StateFlags.INSENSITIVE ] class ConsolePlugin(geany.Plugin): - __plugin_name__ = "Python Console" - __plugin_description__ = ("Installs a Python console that allows you " + - "to use the Geany API.") - __plugin_version__ = "0.01" - __plugin_author__ = "Matthew Brush " + __plugin_name__ = "Python Console" + __plugin_description__ = ("Installs a Python console that allows you " + + "to use the Geany API.") + __plugin_version__ = "0.01" + __plugin_author__ = "Matthew Brush " - _font = "Monospace 9" - _bg = "#FFFFFF" - _fg = "#000000" - _banner = ("Geany Python Console\n You can access the Geany Python " + - "API by importing the `geany' module.\n") - _use_rl_completer = True - - _builder = None - - def __init__(self): - geany.Plugin.__init__(self) - self.load_config() - self.install_console() - - - def cleanup(self): - #self.save_config() - self.on_save_config_timeout() # do it now - self.uninstall_console() - - - def load_config(self): - self.cfg_path = os.path.join(geany.app.configdir, "plugins", "pyconsole.conf") - self.cfg = SafeConfigParser() - self.cfg.read(self.cfg_path) - - - def save_config(self): - gobject.idle_add(self.on_save_config_timeout) - - - def on_save_config_timeout(self, data=None): - self.cfg.write(open(self.cfg_path, 'w')) - return False - - - def install_console(self): - - # load general settings - self.banner = self.banner - self.use_rl_completer = self.use_rl_completer - - self.swin = gtk.ScrolledWindow() - self.swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS) - self.console = geany.console.Console(banner = self.banner, - use_rlcompleter = self.use_rl_completer) - self.console.connect("populate-popup", self.on_console_populate_popup) - - # apply appearance settings - self.font = self.font - self.bg = self.bg - self.fg = self.fg - - self.swin.add(self.console) - geany.main_widgets.message_window_notebook.append_page(self.swin, - gtk.Label("Python")) - - self.swin.show_all() - self.save_config() - - def uninstall_console(self): - self.swin.destroy() - - - def _get_font(self): - if self.cfg.has_section('appearances'): - if self.cfg.has_option('appearances', 'font'): - return self.cfg.get('appearances', 'font') - return self._font - def _set_font(self, font): - self._font = font - font_desc = pango.FontDescription(font) - self.console.modify_font(font_desc) - if not self.cfg.has_section('appearances'): - self.cfg.add_section('appearances') - self.cfg.set('appearances', 'font', self._font) - self.save_config() - font = property(_get_font, _set_font) - - - def _get_bg(self): - if self.cfg.has_section('appearances'): - if self.cfg.has_option('appearances', 'bg_color'): - return self.cfg.get('appearances', 'bg_color') - return self._bg - def _set_bg(self, bg): - self._bg = bg - color = gdk.color_parse(self._bg) - for state in WIDGET_STATES: - self.console.modify_bg(state, color) - self.console.modify_base(state, color) - if not self.cfg.has_section('appearances'): - self.cfg.add_section('appearances') - self.cfg.set('appearances', 'bg_color', self._bg) - self.save_config() - bg = property(_get_bg, _set_bg) - - - def _get_fg(self): - if self.cfg.has_section('appearances'): - if self.cfg.has_option('appearances', 'fg_color'): - return self.cfg.get('appearances', 'fg_color') - return self._fg - def _set_fg(self, fg): - self._fg = fg - color = gdk.color_parse(self._fg) - for state in WIDGET_STATES: - self.console.modify_fg(state, color) - self.console.modify_text(state, color) - if not self.cfg.has_section('appearances'): - self.cfg.add_section('appearances') - self.cfg.set('appearances', 'fg_color', self._fg) - self.save_config() - fg = property(_get_fg, _set_fg) - - - def _get_banner(self): - if self.cfg.has_section('general'): - if self.cfg.has_option('general', 'banner'): - return self.cfg.get('general', 'banner') - return self._banner - def _set_banner(self, banner): - self._banner = banner - if not self.cfg.has_section('general'): - self.cfg.add_section('general') - self.cfg.set('general', 'banner', self._banner) - self.save_config() - banner = property(_get_banner, _set_banner) - - - def _get_use_rl_completer(self): - if self.cfg.has_section('general'): - if self.cfg.has_option('general', 'use_rl_completer'): - return self.cfg.getboolean('general', 'use_rl_completer') - return self._use_rl_completer - def _set_use_rl_completer(self, use_rl_completer): - self._use_rl_completer = use_rl_completer - if not self.cfg.has_section('general'): - self.cfg.add_section('general') - self.cfg.set('general', 'use_rl_completer', - str(self._use_rl_completer).lower()) - self.save_config() - use_rl_completer = property(_get_use_rl_completer, _set_use_rl_completer) - - - def on_console_populate_popup(self, textview, menu, data=None): - item = gtk.SeparatorMenuItem() - item.show() - menu.append(item) - item = gtk.ImageMenuItem(stock_id=gtk.STOCK_PREFERENCES) - item.show() - menu.append(item) - item.connect("activate", lambda w,d=None: self.show_configure()) - - - def on_banner_changed(self, text_buf, data=None): - self.banner = text_buf.get_text(text_buf.get_start_iter(), text_buf.get_end_iter()) - - def on_use_rl_completer_toggled(self, chk_btn, data=None): - self.use_rl_completer = chk_btn.get_active() - - def on_font_changed(self, font_btn, data=None): - self.font = font_btn.get_font_name() - - def on_fg_color_changed(self, clr_btn, data=None): - self.fg = clr_btn.get_color().to_string() - - def on_bg_color_changed(self, clr_btn, data=None): - self.bg = clr_btn.get_color().to_string() - - - def show_configure(self): - dialog = gtk.Dialog("Configure Python Console", - geany.main_widgets.window, - gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, - (gtk.STOCK_CLOSE, gtk.RESPONSE_ACCEPT)) - - dialog.set_has_separator(True) - - content_area = dialog.get_content_area() - content_area.set_border_width(6) - - vbox = gtk.VBox(spacing=6) - vbox.set_border_width(6) - - lbl = gtk.Label() - lbl.set_use_markup(True) - lbl.set_markup("General") - - fra_general = gtk.Frame("") - fra_general.set_shadow_type(gtk.SHADOW_NONE) - fra_general.set_label_widget(lbl) - - al_general = gtk.Alignment(0.0, 0.0, 1.0, 1.0) - al_general.set_padding(0, 0, 12, 0) - fra_general.add(al_general) + _font = "Monospace 9" + _bg = "#FFFFFF" + _fg = "#000000" + _banner = ("Geany Python Console\n You can access the Geany Python " + + "API by importing the `geany' module.\n") + _use_rl_completer = True + + _builder = None + + def __init__(self): + geany.Plugin.__init__(self) + self.load_config() + self.install_console() + + + def cleanup(self): + #self.save_config() + self.on_save_config_timeout() # do it now + self.uninstall_console() + + + def load_config(self): + self.cfg_path = os.path.join(geany.app.configdir, "plugins", "pyconsole.conf") + self.cfg = SafeConfigParser() + self.cfg.read(self.cfg_path) + + + def save_config(self): + GObject.idle_add(self.on_save_config_timeout) + + + def on_save_config_timeout(self, data=None): + self.cfg.write(open(self.cfg_path, 'w')) + return False + + + def install_console(self): + + # load general settings + self.banner = self.banner + self.use_rl_completer = self.use_rl_completer + + self.swin = Gtk.ScrolledWindow() + self.swin.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.ALWAYS) + self.console = geany.console.Console(banner = self.banner, + use_rlcompleter = self.use_rl_completer) + self.console.connect("populate-popup", self.on_console_populate_popup) + + # apply appearance settings + self.font = self.font + self.bg = self.bg + self.fg = self.fg + + self.swin.add(self.console) + geany.main_widgets.message_window_notebook.append_page(self.swin, + Gtk.Label("Python")) + + self.swin.show_all() + self.save_config() + + def uninstall_console(self): + self.swin.destroy() + + + def _get_font(self): + if self.cfg.has_section('appearances'): + if self.cfg.has_option('appearances', 'font'): + return self.cfg.get('appearances', 'font') + return self._font + def _set_font(self, font): + self._font = font + font_desc = Pango.FontDescription(font) + self.console.modify_font(font_desc) + if not self.cfg.has_section('appearances'): + self.cfg.add_section('appearances') + self.cfg.set('appearances', 'font', self._font) + self.save_config() + font = property(_get_font, _set_font) + + + def _get_bg(self): + if self.cfg.has_section('appearances'): + if self.cfg.has_option('appearances', 'bg_color'): + return self.cfg.get('appearances', 'bg_color') + return self._bg + def _set_bg(self, bg): + self._bg = bg + color = Gdk.color_parse(self._bg) + for state in WIDGET_STATES: + self.console.modify_bg(state, color) + self.console.modify_base(state, color) + if not self.cfg.has_section('appearances'): + self.cfg.add_section('appearances') + self.cfg.set('appearances', 'bg_color', self._bg) + self.save_config() + bg = property(_get_bg, _set_bg) + + + def _get_fg(self): + if self.cfg.has_section('appearances'): + if self.cfg.has_option('appearances', 'fg_color'): + return self.cfg.get('appearances', 'fg_color') + return self._fg + def _set_fg(self, fg): + self._fg = fg + color = Gdk.color_parse(self._fg) + for state in WIDGET_STATES: + self.console.modify_fg(state, color) + self.console.modify_text(state, color) + if not self.cfg.has_section('appearances'): + self.cfg.add_section('appearances') + self.cfg.set('appearances', 'fg_color', self._fg) + self.save_config() + fg = property(_get_fg, _set_fg) + + + def _get_banner(self): + if self.cfg.has_section('general'): + if self.cfg.has_option('general', 'banner'): + return self.cfg.get('general', 'banner') + return self._banner + def _set_banner(self, banner): + self._banner = banner + if not self.cfg.has_section('general'): + self.cfg.add_section('general') + self.cfg.set('general', 'banner', self._banner) + self.save_config() + banner = property(_get_banner, _set_banner) + + + def _get_use_rl_completer(self): + if self.cfg.has_section('general'): + if self.cfg.has_option('general', 'use_rl_completer'): + return self.cfg.getboolean('general', 'use_rl_completer') + return self._use_rl_completer + def _set_use_rl_completer(self, use_rl_completer): + self._use_rl_completer = use_rl_completer + if not self.cfg.has_section('general'): + self.cfg.add_section('general') + self.cfg.set('general', 'use_rl_completer', + str(self._use_rl_completer).lower()) + self.save_config() + use_rl_completer = property(_get_use_rl_completer, _set_use_rl_completer) + + + def on_console_populate_popup(self, textview, menu, data=None): + item = Gtk.SeparatorMenuItem() + item.show() + menu.append(item) + item = Gtk.ImageMenuItem(stock_id=Gtk.STOCK_PREFERENCES) + item.show() + menu.append(item) + item.connect("activate", lambda w,d=None: self.show_configure()) + + + def on_banner_changed(self, text_buf, data=None): + self.banner = text_buf.get_text(text_buf.get_start_iter(), text_buf.get_end_iter()) + + def on_use_rl_completer_toggled(self, chk_btn, data=None): + self.use_rl_completer = chk_btn.get_active() + + def on_font_changed(self, font_btn, data=None): + self.font = font_btn.get_font_name() + + def on_fg_color_changed(self, clr_btn, data=None): + self.fg = clr_btn.get_color().to_string() + + def on_bg_color_changed(self, clr_btn, data=None): + self.bg = clr_btn.get_color().to_string() + + + def show_configure(self): + dialog = Gtk.Dialog("Configure Python Console", + geany.main_widgets.window, + Gtk.DialogType.MODAL | Gtk.DialogType.DESTROY_WITH_PARENT, + (Gtk.STOCK_CLOSE, Gtk.ResponseType.ACCEPT)) + + dialog.set_has_separator(True) + + content_area = dialog.get_content_area() + content_area.set_border_width(6) + + vbox = Gtk.VBox(spacing=6) + vbox.set_border_width(6) + + lbl = Gtk.Label() + lbl.set_use_markup(True) + lbl.set_markup("General") + + fra_general = Gtk.Frame("") + fra_general.set_shadow_type(Gtk.ShadowType.NONE) + fra_general.set_label_widget(lbl) + + al_general = Gtk.Alignment(0.0, 0.0, 1.0, 1.0) + al_general.set_padding(0, 0, 12, 0) + fra_general.add(al_general) - tbl = gtk.Table(3, 2, False) - tbl.set_row_spacings(6) - tbl.set_col_spacings(6) - tbl.set_border_width(6) - - lbl = gtk.Label("Banner:") - lbl.set_alignment(0.0, 0.0) + tbl = Gtk.Table(3, 2, False) + tbl.set_row_spacings(6) + tbl.set_col_spacings(6) + tbl.set_border_width(6) + + lbl = Gtk.Label("Banner:") + lbl.set_alignment(0.0, 0.0) - tvw = gtk.TextView() - tvw.get_buffer().set_text(self.banner) - tvw.get_buffer().connect("changed", self.on_banner_changed) + tvw = Gtk.TextView() + tvw.get_buffer().set_text(self.banner) + tvw.get_buffer().connect("changed", self.on_banner_changed) - swin = gtk.ScrolledWindow() - swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) - swin.set_shadow_type(gtk.SHADOW_ETCHED_IN) - swin.add(tvw) + swin = Gtk.ScrolledWindow() + swin.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) + swin.set_shadow_type(Gtk.ShadowType.ETCHED_IN) + swin.add(tvw) - tbl.attach(lbl, 0, 1, 0, 1, gtk.FILL, gtk.FILL, 0, 0) - tbl.attach(swin, 1, 2, 0, 1, gtk.EXPAND | gtk.FILL, gtk.EXPAND | gtk.FILL, 0, 0) + tbl.attach(lbl, 0, 1, 0, 1, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) + tbl.attach(swin, 1, 2, 0, 1, Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, 0, 0) - lbl = gtk.Label("") - lbl.set_alignment(0.0, 0.5) + lbl = Gtk.Label("") + lbl.set_alignment(0.0, 0.5) - check = gtk.CheckButton("Use Readline") - if self.use_rl_completer: - check.set_active(True) - check.connect("toggled", self.on_use_rl_completer_toggled) + check = Gtk.CheckButton("Use Readline") + if self.use_rl_completer: + check.set_active(True) + check.connect("toggled", self.on_use_rl_completer_toggled) - tbl.attach(lbl, 0, 1, 1, 2, gtk.FILL, gtk.FILL, 0, 0) - tbl.attach(check, 1, 2, 1, 2, gtk.FILL, gtk.FILL, 0, 0) + tbl.attach(lbl, 0, 1, 1, 2, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) + tbl.attach(check, 1, 2, 1, 2, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) - lbl = gtk.Label("") - lbl.set_alignment(0.0, 0.5) - lbl.set_use_markup(True) - lbl.set_markup('' + - 'Note: General settings will be applied when console is reloaded.' + - '') - tbl.attach(lbl, 0, 2, 2, 3, gtk.FILL, gtk.FILL, 0, 0) + lbl = Gtk.Label("") + lbl.set_alignment(0.0, 0.5) + lbl.set_use_markup(True) + lbl.set_markup('' + + 'Note: General settings will be applied when console is reloaded.' + + '') + tbl.attach(lbl, 0, 2, 2, 3, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) - al_general.add(tbl) + al_general.add(tbl) - lbl = gtk.Label() - lbl.set_use_markup(True) - lbl.set_markup("Appearances") + lbl = Gtk.Label() + lbl.set_use_markup(True) + lbl.set_markup("Appearances") - fra_appearances = gtk.Frame("") - fra_appearances.set_shadow_type(gtk.SHADOW_NONE) - fra_appearances.set_label_widget(lbl) + fra_appearances = Gtk.Frame("") + fra_appearances.set_shadow_type(Gtk.ShadowType.NONE) + fra_appearances.set_label_widget(lbl) - al_appearances = gtk.Alignment(0.0, 0.0, 1.0, 1.0) - al_appearances.set_padding(0, 0, 12, 0) - fra_appearances.add(al_appearances) + al_appearances = Gtk.Alignment(0.0, 0.0, 1.0, 1.0) + al_appearances.set_padding(0, 0, 12, 0) + fra_appearances.add(al_appearances) - tbl = gtk.Table(3, 2, False) - tbl.set_row_spacings(6) - tbl.set_col_spacings(6) - tbl.set_border_width(6) + tbl = Gtk.Table(3, 2, False) + tbl.set_row_spacings(6) + tbl.set_col_spacings(6) + tbl.set_border_width(6) - lbl = gtk.Label("Font:") - lbl.set_alignment(0.0, 0.5) + lbl = Gtk.Label("Font:") + lbl.set_alignment(0.0, 0.5) - btn = gtk.FontButton(self.font) - btn.connect("font-set", self.on_font_changed) + btn = Gtk.FontButton(self.font) + btn.connect("font-set", self.on_font_changed) - tbl.attach(lbl, 0, 1, 0, 1, gtk.FILL, gtk.FILL, 0, 0) - tbl.attach(btn, 1, 2, 0, 1, gtk.FILL | gtk.EXPAND, gtk.FILL, 0, 0) + tbl.attach(lbl, 0, 1, 0, 1, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) + tbl.attach(btn, 1, 2, 0, 1, Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, Gtk.AttachOptions.FILL, 0, 0) - lbl = gtk.Label("FG Color:") - lbl.set_alignment(0.0, 0.5) + lbl = Gtk.Label("FG Color:") + lbl.set_alignment(0.0, 0.5) - btn = gtk.ColorButton(gdk.color_parse(self.fg)) - btn.connect("color-set", self.on_fg_color_changed) + btn = Gtk.ColorButton(Gdk.color_parse(self.fg)) + btn.connect("color-set", self.on_fg_color_changed) - tbl.attach(lbl, 0, 1, 1, 2, gtk.FILL, gtk.FILL, 0, 0) - tbl.attach(btn, 1, 2, 1, 2, gtk.FILL | gtk.EXPAND, gtk.FILL, 0, 0) + tbl.attach(lbl, 0, 1, 1, 2, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) + tbl.attach(btn, 1, 2, 1, 2, Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, Gtk.AttachOptions.FILL, 0, 0) - lbl = gtk.Label("BG Color:") - lbl.set_alignment(0.0, 0.5) + lbl = Gtk.Label("BG Color:") + lbl.set_alignment(0.0, 0.5) - btn = gtk.ColorButton(gdk.color_parse(self.bg)) - btn.connect("color-set", self.on_bg_color_changed) + btn = Gtk.ColorButton(Gdk.color_parse(self.bg)) + btn.connect("color-set", self.on_bg_color_changed) - tbl.attach(lbl, 0, 1, 2, 3, gtk.FILL, gtk.FILL, 0, 0) - tbl.attach(btn, 1, 2, 2, 3, gtk.FILL | gtk.EXPAND, gtk.FILL, 0, 0) + tbl.attach(lbl, 0, 1, 2, 3, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) + tbl.attach(btn, 1, 2, 2, 3, Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, Gtk.AttachOptions.FILL, 0, 0) - al_appearances.add(tbl) + al_appearances.add(tbl) - vbox.pack_start(fra_general, True, True, 0) - vbox.pack_start(fra_appearances, False, True, 0) - content_area.pack_start(vbox, True, True, 0) - content_area.show_all() + vbox.pack_start(fra_general, True, True, 0) + vbox.pack_start(fra_appearances, False, True, 0) + content_area.pack_start(vbox, True, True, 0) + content_area.show_all() - dialog.run() - dialog.destroy() + dialog.run() + dialog.destroy() \ No newline at end of file diff --git a/plugins/hello.py b/plugins/hello.py index dfa7d27..c9e2859 100644 --- a/plugins/hello.py +++ b/plugins/hello.py @@ -1,4 +1,4 @@ -import gtk +from gi.repository import Gtk import geany class HelloWorld(geany.Plugin): @@ -9,7 +9,7 @@ class HelloWorld(geany.Plugin): __plugin_author__ = "John Doe " def __init__(self): - self.menu_item = gtk.MenuItem("Hello World") + self.menu_item = Gtk.MenuItem("Hello World") self.menu_item.show() geany.main_widgets.tools_menu.append(self.menu_item) self.menu_item.connect("activate", self.on_hello_item_clicked) @@ -18,4 +18,4 @@ def cleanup(self): self.menu_item.destroy() def on_hello_item_clicked(widget, data): - geany.dialogs.show_msgbox("Hello World") + geany.dialogs.show_msgbox("Hello World") \ No newline at end of file From b617e877d19799b7cd1ae9bf7ecd1f35169027ee Mon Sep 17 00:00:00 2001 From: Sagar Chalise Date: Fri, 19 Jul 2013 01:00:32 +0545 Subject: [PATCH 02/28] gtk3 port still needs some testing --- src/geanypy-plugin.c | 6 ++++-- src/geanypy-uiutils.c | 26 +++++++++++++------------- src/geanypy.h | 8 ++++---- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/geanypy-plugin.c b/src/geanypy-plugin.c index 7b85071..d505e79 100644 --- a/src/geanypy-plugin.c +++ b/src/geanypy-plugin.c @@ -80,7 +80,9 @@ GeanyPy_start_interpreter(void) #endif Py_Initialize(); - + #if GTK_CHECK_VERSION(3, 2, 0) + PySys_SetArgv(0, "[]"); + #endif /* Import the C modules */ initapp(); initdialogs(); @@ -277,4 +279,4 @@ G_MODULE_EXPORT void plugin_cleanup(void) GeanyPy_stop_interpreter(); gtk_widget_destroy(loader_item); g_free(plugin_dir); -} +} \ No newline at end of file diff --git a/src/geanypy-uiutils.c b/src/geanypy-uiutils.c index 58f63cb..88dee08 100644 --- a/src/geanypy-uiutils.c +++ b/src/geanypy-uiutils.c @@ -419,18 +419,18 @@ static PyMethodDef UiUtilsModule_methods[] = { PyMODINIT_FUNC initui_utils(void) { PyObject *m; - - init_pygobject(); - init_pygtk(); - m = PyImport_ImportModule("gobject"); - - if (m) - { - PyGObject_Type = (PyTypeObject *) PyObject_GetAttrString(m, "GObject"); - Py_XDECREF(m); - } - - InterfacePrefsType.tp_new = PyType_GenericNew; + #if GTK_CHECK_VERSION(2, 18, 0) + init_pygobject(); + init_pygtk(); + m = PyImport_ImportModule("gobject"); + if (m) + { + PyGObject_Type = (PyTypeObject *) PyObject_GetAttrString(m, "GObject"); + Py_XDECREF(m); + } + #endif + + InterfacePrefsType.tp_new = PyType_GenericNew; if (PyType_Ready(&InterfacePrefsType) < 0) return; @@ -446,4 +446,4 @@ PyMODINIT_FUNC initui_utils(void) Py_INCREF(&MainWidgetsType); PyModule_AddObject(m, "MainWidgets", (PyObject *) &MainWidgetsType); -} +} \ No newline at end of file diff --git a/src/geanypy.h b/src/geanypy.h index 0029b70..672a417 100644 --- a/src/geanypy.h +++ b/src/geanypy.h @@ -78,11 +78,11 @@ extern "C" { #include #ifndef GEANYPY_WINDOWS -/* Used with the results of `pkg-config --cflags pygtk-2.0` */ -# include -#else /* On windows the path of pygtk.h is directly an include dir */ # include +#elseif GTK_CHECK_VERSION(2, 18, 0) +/* Used with the results of `pkg-config --cflags pygtk-2.0` */ +# include #endif #ifndef GTK @@ -116,4 +116,4 @@ extern "C" { } /* extern "C" */ #endif -#endif /* GEANYPY_H__ */ +#endif /* GEANYPY_H__ */ \ No newline at end of file From 87e8f8d2eae5da0b22ccc59e3a407dc5f0dc3607 Mon Sep 17 00:00:00 2001 From: Sagar Chalise Date: Fri, 19 Jul 2013 08:33:16 +0545 Subject: [PATCH 03/28] Initialize pygobject on both Gtk3 and Gtk2 --- src/geanypy-uiutils.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/geanypy-uiutils.c b/src/geanypy-uiutils.c index 88dee08..e463fb2 100644 --- a/src/geanypy-uiutils.c +++ b/src/geanypy-uiutils.c @@ -420,16 +420,18 @@ PyMODINIT_FUNC initui_utils(void) { PyObject *m; #if GTK_CHECK_VERSION(2, 18, 0) - init_pygobject(); - init_pygtk(); - m = PyImport_ImportModule("gobject"); - if (m) - { - PyGObject_Type = (PyTypeObject *) PyObject_GetAttrString(m, "GObject"); - Py_XDECREF(m); - } + init_pygobject(); + init_pygtk(); + m = PyImport_ImportModule("gobject"); + #else + pygobject_init(-1, -1, -1); + m = PyImport_ImportModule("gi._gobject"); #endif - + if (m) + { + PyGObject_Type = (PyTypeObject *) PyObject_GetAttrString(m, "GObject"); + Py_XDECREF(m); + } InterfacePrefsType.tp_new = PyType_GenericNew; if (PyType_Ready(&InterfacePrefsType) < 0) return; From d34b59ef6f2be8521d1a9002702582c87ddbb29d Mon Sep 17 00:00:00 2001 From: Sagar Chalise Date: Fri, 19 Jul 2013 10:53:37 +0545 Subject: [PATCH 04/28] Plugin listing now working along with preference of console plugin --- geany/loader.py | 10 +++++----- geany/manager.py | 10 +++++----- plugins/console.py | 19 +++++++++---------- 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/geany/loader.py b/geany/loader.py index cfbe36e..15533b8 100644 --- a/geany/loader.py +++ b/geany/loader.py @@ -14,9 +14,9 @@ def __init__(self, plugin_dirs): self.plugin_dirs = plugin_dirs - self.available_plugins = [] - for plugin in self.iter_plugin_info(): - self.available_plugins.append(plugin) + #self.available_plugins = [] + #for plugin in self.iter_plugin_info(): + #self.available_plugins.append(plugin) self.restore_loaded_plugins() @@ -126,7 +126,7 @@ def load_plugin_info(self,d,f): def load_plugin(self, filename): - for avail in self.available_plugins: + for avail in self.iter_plugin_info(): if avail.filename == filename: inst = avail.cls() self.plugins[filename] = inst @@ -169,4 +169,4 @@ def plugin_has_configure(self, filename): try: return hasattr(self.plugins[filename], 'show_configure') except KeyError: - return None + return None \ No newline at end of file diff --git a/geany/manager.py b/geany/manager.py index e3b753d..59c2e87 100644 --- a/geany/manager.py +++ b/geany/manager.py @@ -63,7 +63,7 @@ def on_help_button_clicked(self, button, treeview, model): path = treeview.get_cursor()[0] iter = model.get_iter(path) filename = model.get_value(iter, 2) - for plugin in self.loader.available_plugins: + for plugin in self.loader.iter_plugin_info(): if plugin.filename == filename: plugin.cls.show_help() break @@ -121,10 +121,10 @@ def load_plugins_list(self): def load_sorted_plugins_info(self, list_store): - plugin_info_list = list(self.loader.iter_plugin_info()) + #plugin_info_list = list(self.loader.iter_plugin_info()) #plugin_info_list.sort(key=lambda pi: pi[1]) - for plugin_info in plugin_info_list: + for plugin_info in self.loader.iter_plugin_info(): lbl = str('%s %s\n%s\n' + 'Author: %s\n' + @@ -135,9 +135,9 @@ def load_sorted_plugins_info(self, list_store): GLib.markup_escape_text(plugin_info.author), GLib.markup_escape_text(plugin_info.filename)) - loaded = plugin_info.filename in self.loader.plugins + loaded = plugin_info.filename in self.loader.plugins - list_store.append([loaded, lbl, plugin_info.filename]) + list_store.append([loaded, lbl, plugin_info.filename]) def on_selected_plugin_changed(self, treeview, model): diff --git a/plugins/console.py b/plugins/console.py index 644234e..0d831ee 100644 --- a/plugins/console.py +++ b/plugins/console.py @@ -5,8 +5,8 @@ from gi.repository import GObject, Gtk, Gdk, Pango -WIDGET_STATES = [ Gtk.StateFlags.NORMAL, Gtk.StateFlags.ACTIVE, Gtk.StateFlags.PRELIGHT, - Gtk.StateFlags.SELECTED, Gtk.StateFlags.INSENSITIVE ] +WIDGET_STATES = [ Gtk.StateType.NORMAL, Gtk.StateType.ACTIVE, Gtk.StateType.PRELIGHT, + Gtk.StateType.SELECTED, Gtk.StateType.INSENSITIVE ] class ConsolePlugin(geany.Plugin): @@ -191,11 +191,8 @@ def on_bg_color_changed(self, clr_btn, data=None): def show_configure(self): dialog = Gtk.Dialog("Configure Python Console", geany.main_widgets.window, - Gtk.DialogType.MODAL | Gtk.DialogType.DESTROY_WITH_PARENT, + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, (Gtk.STOCK_CLOSE, Gtk.ResponseType.ACCEPT)) - - dialog.set_has_separator(True) - content_area = dialog.get_content_area() content_area.set_border_width(6) @@ -206,11 +203,12 @@ def show_configure(self): lbl.set_use_markup(True) lbl.set_markup("General") - fra_general = Gtk.Frame("") + fra_general = Gtk.Frame() fra_general.set_shadow_type(Gtk.ShadowType.NONE) fra_general.set_label_widget(lbl) - al_general = Gtk.Alignment(0.0, 0.0, 1.0, 1.0) + al_general = Gtk.Alignment() + al_general.set(0.0, 0.0, 1.0, 1.0) al_general.set_padding(0, 0, 12, 0) fra_general.add(al_general) @@ -259,11 +257,12 @@ def show_configure(self): lbl.set_use_markup(True) lbl.set_markup("Appearances") - fra_appearances = Gtk.Frame("") + fra_appearances = Gtk.Frame() fra_appearances.set_shadow_type(Gtk.ShadowType.NONE) fra_appearances.set_label_widget(lbl) - al_appearances = Gtk.Alignment(0.0, 0.0, 1.0, 1.0) + al_appearances = Gtk.Alignment() + al_appearances.set(0.0, 0.0, 1.0, 1.0) al_appearances.set_padding(0, 0, 12, 0) fra_appearances.add(al_appearances) From 7f01516be79452087c1299817198b7d965745e0b Mon Sep 17 00:00:00 2001 From: Sagar Chalise Date: Fri, 19 Jul 2013 20:49:38 +0545 Subject: [PATCH 05/28] super way of initializing --- plugins/console.py | 2 +- plugins/demo.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/console.py b/plugins/console.py index 0d831ee..6665495 100644 --- a/plugins/console.py +++ b/plugins/console.py @@ -27,7 +27,7 @@ class ConsolePlugin(geany.Plugin): _builder = None def __init__(self): - geany.Plugin.__init__(self) + super(ConsolePlugin, self).__init__() self.load_config() self.install_console() diff --git a/plugins/demo.py b/plugins/demo.py index 77ef0d0..8b8a091 100644 --- a/plugins/demo.py +++ b/plugins/demo.py @@ -9,10 +9,10 @@ class DemoPlugin(geany.Plugin): __plugin_author__ = "Matthew Brush " def __init__(self): - geany.Plugin.__init__(self) + super(DemoPlugin, self).__init__() print("Demo plugin initializing") doc = geany.document.new_file() doc.editor.scintilla.set_text("Hello from the Demo plugin") def cleanup(self): - print("Demo plugin cleaning up") + print("Demo plugin cleaning up") \ No newline at end of file From e3cefcf926bf3c066708c8b5e60a0567ca7d020e Mon Sep 17 00:00:00 2001 From: Sagar Chalise Date: Fri, 19 Jul 2013 21:01:20 +0545 Subject: [PATCH 06/28] Pygtk compatible codebase..not tested with pygtk --- geany/__init__.py | 2 +- geany/console.py | 87 ++++++++++++++++---------- geany/loader.py | 6 -- geany/manager.py | 139 +++++++++++++++++++++++------------------ geany/signalmanager.py | 82 +++++++++++++----------- plugins/console.py | 119 +++++++++++++++++++---------------- plugins/hello.py | 12 +++- 7 files changed, 254 insertions(+), 193 deletions(-) diff --git a/geany/__init__.py b/geany/__init__.py index 1cf6030..493dfa4 100644 --- a/geany/__init__.py +++ b/geany/__init__.py @@ -66,4 +66,4 @@ signals = SignalManager() import plugin -from plugin import Plugin \ No newline at end of file +from plugin import Plugin diff --git a/geany/console.py b/geany/console.py index 2742aa6..d3776c7 100644 --- a/geany/console.py +++ b/geany/console.py @@ -28,16 +28,29 @@ # To modify output appearance, set attributes of console.stdout_tag and # console.stderr_tag. # -# Console may subclass a type other than Gtk.TextView, to allow syntax highlighting and stuff, +# Console may subclass a type other than gtk.TextView, to allow syntax highlighting and stuff, # e.g.: # console_type = pyconsole.ConsoleType(moo.TextView) -# console = console_type(use_rlcompleter=False, start_script="import moo\nimport Gtk\n") +# console = console_type(use_rlcompleter=False, start_script="import moo\nimport gtk\n") # # This widget is not a replacement for real terminal with python running # inside: GtkTextView is not a terminal. # The use case is: you have a python program, you create this widget, # and inspect your program interiors. -from gi.repository import GObject, Gtk, Gdk, Pango +try: + from gi import pygtkcompat +except ImportError: + pygtkcompat = None + +if pygtkcompat is not None: + pygtkcompat.enable() + pygtkcompat.enable_gtk(version='3.0') + +import gtk +import gtk.gdk as gdk +import gobject +import pango +import gtk.keysyms as _keys import code import sys import keyword @@ -104,8 +117,8 @@ def get(self, dir, text): def __init__(self): object.__init__(self) - self.set_wrap_mode(Gtk.WrapMode.CHAR) - self.modify_font(Pango.FontDescription("Monospace")) + self.set_wrap_mode(gtk.WRAP_CHAR) + self.modify_font(pango.FontDescription("Monospace")) self.buffer = self.get_buffer() self.buffer.connect("insert-text", self.on_buf_insert) @@ -237,27 +250,27 @@ def do_key_press_event(self, event, parent_type): self.tab_pressed = 0 handled = True - state = event.state & (Gdk.ModifierType.SHIFT_MASK | - Gdk.ModifierType.CONTROL_MASK | - Gdk.ModifierType.MOD1_MASK) + state = event.state & (gdk.SHIFT_MASK | + gdk.CONTROL_MASK | + gdk.MOD1_MASK) keyval = event.keyval if not state: - if keyval == Gdk.KEY_Return: + if keyval == _keys.Return: self._commit() - elif keyval == Gdk.KEY_Up: + elif keyval == _keys.Up: self.__history(-1) - elif keyval == Gdk.KEY_Down: + elif keyval == _keys.Down: self.__history(1) - elif keyval == Gdk.KEY_Left: + elif keyval == _keys.Left: self.__move_cursor(-1) - elif keyval == Gdk.KEY_Right: + elif keyval == _keys.Right: self.__move_cursor(1) - elif keyval == Gdk.KEY_Home: + elif keyval == _keys.Home: self.__move_cursor(-10000) - elif keyval == Gdk.KEY_End: + elif keyval == _keys.End: self.__move_cursor(10000) - elif keyval == Gdk.KEY_Tab: + elif keyval == _keys.Tab: cursor = self.__get_cursor() if cursor.starts_line(): handled = False @@ -270,8 +283,8 @@ def do_key_press_event(self, event, parent_type): self.__complete() else: handled = False - elif state == Gdk.ModifierType.CONTROL_MASK: - if keyval == Gdk.KEY_u: + elif state == gdk.CONTROL_MASK: + if keyval == _keys.u: start = self.__get_start() end = self.__get_cursor() self.__delete(start, end) @@ -338,9 +351,9 @@ def __delete_at_cursor(self, howmany): self.__delete(iter, end) def __get_width(self): - if not (Gtk.get_realized()): + if not (gtk.get_realized()): return 80 - layout = Pango.Layout(self.get_pango_context()) + layout = pango.Layout(self.get_pango_context()) letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" layout.set_text(letters) pix_width = layout.get_pixel_size()[0] @@ -518,7 +531,10 @@ def do_command(self, code): self.showtraceback() def runcode(self, code): - self.emit("command", code) + if gtk.pygtk_version[1] < 8: + self.do_command(code) + else: + self.emit("command", code) def exec_command(self, command): if self._get_line(): @@ -588,25 +604,28 @@ def complete(self, text): return completions -def ReadLineType(t=Gtk.TextView): +def ReadLineType(t=gtk.TextView): class readline(t, _ReadLine): def __init__(self, *args, **kwargs): t.__init__(self) _ReadLine.__init__(self, *args, **kwargs) def do_key_press_event(self, event): return _ReadLine.do_key_press_event(self, event, t) - GObject.type_register(readline) + gobject.type_register(readline) return readline -def ConsoleType(t=Gtk.TextView): +def ConsoleType(t=gtk.TextView): class console_type(t, _Console): __gsignals__ = { - 'command' : (GObject.SignalFlags.RUN_LAST, None, (object,)), + 'command' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (object,)), 'key-press-event' : 'override' } def __init__(self, *args, **kwargs): - GObject.GObject.__init__(self) + if gtk.pygtk_version[1] < 8: + gobject.GObject.__init__(self) + else: + t.__init__(self) _Console.__init__(self, *args, **kwargs) def do_command(self, code): @@ -615,7 +634,9 @@ def do_command(self, code): def do_key_press_event(self, event): return _Console.do_key_press_event(self, event, t) - GObject.type_register(console_type) + if gtk.pygtk_version[1] < 8: + gobject.type_register(console_type) + return console_type ReadLine = ReadLineType() @@ -629,19 +650,19 @@ def _create_widget(start_script): return console def _make_window(start_script="import geany\n"): - window = Gtk.Window() + window = gtk.Window() window.set_title("Python Console") - swin = Gtk.ScrolledWindow() - swin.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.ALWAYS) + swin = gtk.ScrolledWindow() + swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS) window.add(swin) console = _create_widget(start_script) swin.add(console) window.set_default_size(500, 400) window.show_all() - if not Gtk.main_level(): - window.connect("destroy", Gtk.main_quit) - Gtk.main() + if not gtk.main_level(): + window.connect("destroy", gtk.main_quit) + gtk.main() return console diff --git a/geany/loader.py b/geany/loader.py index 15533b8..ae4e504 100644 --- a/geany/loader.py +++ b/geany/loader.py @@ -11,13 +11,7 @@ class PluginLoader(object): plugins = {} def __init__(self, plugin_dirs): - self.plugin_dirs = plugin_dirs - - #self.available_plugins = [] - #for plugin in self.iter_plugin_info(): - #self.available_plugins.append(plugin) - self.restore_loaded_plugins() diff --git a/geany/manager.py b/geany/manager.py index 59c2e87..7cd2680 100644 --- a/geany/manager.py +++ b/geany/manager.py @@ -1,74 +1,89 @@ -from gi.repository import GObject, GLib, Gtk +try: + from gi import pygtkcompat +except ImportError: + pygtkcompat = None + +if pygtkcompat is not None: + pygtkcompat.enable() + pygtkcompat.enable_gtk(version='3.0') + +import gtk +import gobject +import glib from htmlentitydefs import name2codepoint from loader import PluginLoader -class PluginManager(Gtk.Dialog): + +class PluginManager(gtk.Dialog): + def __init__(self, plugin_dirs=[]): super(PluginManager, self).__init__(title="Plugin Manager") self.loader = PluginLoader(plugin_dirs) + self.set_default_size(400, 450) - icon = self.render_icon(Gtk.STOCK_PREFERENCES, Gtk.IconSize.MENU) + icon = self.render_icon(gtk.STOCK_PREFERENCES, gtk.ICON_SIZE_MENU) self.set_icon(icon) - + self.connect("response", lambda w,d: self.hide()) - - vbox = Gtk.VBox(False, 12) + + vbox = gtk.VBox(False, 12) vbox.set_border_width(12) - - lbl = Gtk.Label("Choose plugins to load or unload:") + + lbl = gtk.Label("Choose plugins to load or unload:") lbl.set_alignment(0.0, 0.5) vbox.pack_start(lbl, False, False, 0) - - sw = Gtk.ScrolledWindow() + + sw = gtk.ScrolledWindow() sw.set_hexpand(True) sw.set_vexpand(True) - sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) - sw.set_shadow_type(Gtk.ShadowType.ETCHED_IN) + sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + sw.set_shadow_type(gtk.SHADOW_ETCHED_IN) vbox.pack_start(sw, True, True, 0) - - self.treeview = Gtk.TreeView() + + self.treeview = gtk.TreeView() sw.add(self.treeview) - + vbox.show_all() - + self.get_content_area().add(vbox) - + action_area = self.get_action_area() action_area.set_spacing(0) action_area.set_homogeneous(False) - - btn = Gtk.Button(stock=Gtk.STOCK_CLOSE) + + btn = gtk.Button(stock=gtk.STOCK_CLOSE) btn.set_border_width(6) - btn.connect("clicked", lambda x: self.response(Gtk.ResponseType.CLOSE)) + btn.connect("clicked", lambda x: self.response(gtk.RESPONSE_CLOSE)) action_area.pack_start(btn, False, True, 0) btn.show() - - self.btn_help = Gtk.Button(stock=Gtk.STOCK_HELP) + + self.btn_help = gtk.Button(stock=gtk.STOCK_HELP) self.btn_help.set_border_width(6) self.btn_help.set_no_show_all(True) action_area.pack_start(self.btn_help, False, True, 0) action_area.set_child_secondary(self.btn_help, True) - - self.btn_prefs = Gtk.Button(stock=Gtk.STOCK_PREFERENCES) + + self.btn_prefs = gtk.Button(stock=gtk.STOCK_PREFERENCES) self.btn_prefs.set_border_width(6) self.btn_prefs.set_no_show_all(True) action_area.pack_start(self.btn_prefs, False, True, 0) action_area.set_child_secondary(self.btn_prefs, True) - + action_area.show() - + self.load_plugins_list() + def on_help_button_clicked(self, button, treeview, model): path = treeview.get_cursor()[0] iter = model.get_iter(path) filename = model.get_value(iter, 2) - for plugin in self.loader.iter_plugin_info(): + for plugin in self.loader.available_plugins: if plugin.filename == filename: plugin.cls.show_help() break - else: - print("Plugin does not support help function") + else: + print("Plugin does not support help function") def on_preferences_button_clicked(self, button, treeview, model): @@ -90,74 +105,76 @@ def deactivate_plugin(self, filename): def load_plugins_list(self): - liststore = Gtk.ListStore(GObject.TYPE_BOOLEAN, str, str) + liststore = gtk.ListStore(gobject.TYPE_BOOLEAN, str, str) self.btn_help.connect("clicked", - self.on_help_button_clicked, self.treeview, liststore) + self.on_help_button_clicked, self.treeview, liststore) self.btn_prefs.connect("clicked", - self.on_preferences_button_clicked, self.treeview, liststore) + self.on_preferences_button_clicked, self.treeview, liststore) self.treeview.set_model(liststore) self.treeview.set_headers_visible(False) self.treeview.set_grid_lines(True) - check_renderer = Gtk.CellRendererToggle() + check_renderer = gtk.CellRendererToggle() check_renderer.set_radio(False) check_renderer.connect('toggled', self.on_plugin_load_toggled, liststore) - text_renderer = Gtk.CellRendererText() - check_column = Gtk.TreeViewColumn(None, check_renderer, active=0) - text_column = Gtk.TreeViewColumn(None, text_renderer, markup=1) - + text_renderer = gtk.CellRendererText() + + check_column = gtk.TreeViewColumn(None, check_renderer, active=0) + text_column = gtk.TreeViewColumn(None, text_renderer, markup=1) + self.treeview.append_column(check_column) self.treeview.append_column(text_column) - + self.treeview.connect('row-activated', - self.on_row_activated, check_renderer, liststore) + self.on_row_activated, check_renderer, liststore) self.treeview.connect('cursor-changed', - self.on_selected_plugin_changed, liststore) - + self.on_selected_plugin_changed, liststore) + self.load_sorted_plugins_info(liststore) def load_sorted_plugins_info(self, list_store): - #plugin_info_list = list(self.loader.iter_plugin_info()) + + plugin_info_list = list(self.loader.iter_plugin_info()) #plugin_info_list.sort(key=lambda pi: pi[1]) - for plugin_info in self.loader.iter_plugin_info(): - + for plugin_info in plugin_info_list: + lbl = str('%s %s\n%s\n' + - 'Author: %s\n' + - 'Filename: %s') % ( - GLib.markup_escape_text(plugin_info.name), - GLib.markup_escape_text(plugin_info.version), - GLib.markup_escape_text(plugin_info.description), - GLib.markup_escape_text(plugin_info.author), - GLib.markup_escape_text(plugin_info.filename)) - + 'Author: %s\n' + + 'Filename: %s') % ( + glib.markup_escape_text(plugin_info.name), + glib.markup_escape_text(plugin_info.version), + glib.markup_escape_text(plugin_info.description), + glib.markup_escape_text(plugin_info.author), + glib.markup_escape_text(plugin_info.filename)) + loaded = plugin_info.filename in self.loader.plugins - + list_store.append([loaded, lbl, plugin_info.filename]) - + def on_selected_plugin_changed(self, treeview, model): - + path = treeview.get_cursor()[0] iter = model.get_iter(path) filename = model.get_value(iter, 2) active = model.get_value(iter, 0) - + if self.loader.plugin_has_configure(filename): self.btn_prefs.set_visible(True) else: self.btn_prefs.set_visible(False) - + if self.loader.plugin_has_help(filename): self.btn_help.set_visible(True) else: self.btn_help.set_visible(False) - - + + def on_plugin_load_toggled(self, cell, path, model): active = not cell.get_active() iter = model.get_iter(path) @@ -166,7 +183,7 @@ def on_plugin_load_toggled(self, cell, path, model): self.activate_plugin(model.get_value(iter, 2)) else: self.deactivate_plugin(model.get_value(iter, 2)) - - + + def on_row_activated(self, tvw, path, view_col, cell, model): self.on_plugin_load_toggled(cell, path, model) \ No newline at end of file diff --git a/geany/signalmanager.py b/geany/signalmanager.py index 3e0d69e..16d7910 100644 --- a/geany/signalmanager.py +++ b/geany/signalmanager.py @@ -3,54 +3,62 @@ all signals on. The signals are emitted from the C code in signalmanager.c, where the Geany types get wrapped in PyObject types. """ -from gi.repository import GObject +try: + from gi import pygtkcompat +except ImportError: + pygtkcompat = None +if pygtkcompat is not None: + pygtkcompat.enable() + pygtkcompat.enable_gtk(version='3.0') +import gobject -class SignalManager(GObject.GObject): + +class SignalManager(gobject.GObject): """ Manages callback functions for events emitted by Geany's internal GObject. """ __gsignals__ = { - 'build-start': (GObject.SignalFlags.RUN_LAST, None, + 'build-start': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()), - 'document-activate': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'document-before-save': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'document-close': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'document-filetype-set': (GObject.SignalFlags.RUN_LAST, None, - (object, object)), - 'document-new': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'document-open': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'document-reload': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'document-save': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'editor-notify': (GObject.SignalFlags.RUN_LAST, GObject.TYPE_BOOLEAN, - (object, object)), - 'geany-startup-complete': (GObject.SignalFlags.RUN_LAST, None, + 'document-activate': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'document-before-save': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'document-close': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'document-filetype-set': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT)), + 'document-new': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'document-open': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'document-reload': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'document-save': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'editor-notify': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_BOOLEAN, + (gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT)), + 'geany-startup-complete': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()), - 'project-close': (GObject.SignalFlags.RUN_LAST, None, + 'project-close': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()), - 'project-dialog-confirmed': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'project-dialog-open': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'project-dialog-close': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'project-open': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'project-save': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'update-editor-menu': (GObject.SignalFlags.RUN_LAST, None, - (GObject.TYPE_STRING, GObject.TYPE_INT, - object)), + 'project-dialog-confirmed': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'project-dialog-open': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'project-dialog-close': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'project-open': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'project-save': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'update-editor-menu': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_STRING, gobject.TYPE_INT, + gobject.TYPE_PYOBJECT)), } # __gsignals__ def __init__(self): super(SignalManager, self).__init__() -GObject.type_register(SignalManager) \ No newline at end of file +gobject.type_register(SignalManager) \ No newline at end of file diff --git a/plugins/console.py b/plugins/console.py index 6665495..69a46cf 100644 --- a/plugins/console.py +++ b/plugins/console.py @@ -1,12 +1,24 @@ +try: + from gi import pygtkcompat +except ImportError: + pygtkcompat = None + +if pygtkcompat is not None: + pygtkcompat.enable() + pygtkcompat.enable_gtk(version='3.0') + import os from ConfigParser import SafeConfigParser import geany import geany.console -from gi.repository import GObject, Gtk, Gdk, Pango +import gobject +import gtk +import gtk.gdk as gdk +import pango -WIDGET_STATES = [ Gtk.StateType.NORMAL, Gtk.StateType.ACTIVE, Gtk.StateType.PRELIGHT, - Gtk.StateType.SELECTED, Gtk.StateType.INSENSITIVE ] +WIDGET_STATES = [ gtk.STATE_NORMAL, gtk.STATE_ACTIVE, gtk.STATE_PRELIGHT, + gtk.STATE_SELECTED, gtk.STATE_INSENSITIVE ] class ConsolePlugin(geany.Plugin): @@ -45,7 +57,7 @@ def load_config(self): def save_config(self): - GObject.idle_add(self.on_save_config_timeout) + gobject.idle_add(self.on_save_config_timeout) def on_save_config_timeout(self, data=None): @@ -59,8 +71,8 @@ def install_console(self): self.banner = self.banner self.use_rl_completer = self.use_rl_completer - self.swin = Gtk.ScrolledWindow() - self.swin.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.ALWAYS) + self.swin = gtk.ScrolledWindow() + self.swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS) self.console = geany.console.Console(banner = self.banner, use_rlcompleter = self.use_rl_completer) self.console.connect("populate-popup", self.on_console_populate_popup) @@ -72,7 +84,7 @@ def install_console(self): self.swin.add(self.console) geany.main_widgets.message_window_notebook.append_page(self.swin, - Gtk.Label("Python")) + gtk.Label("Python")) self.swin.show_all() self.save_config() @@ -88,7 +100,7 @@ def _get_font(self): return self._font def _set_font(self, font): self._font = font - font_desc = Pango.FontDescription(font) + font_desc = pango.FontDescription(font) self.console.modify_font(font_desc) if not self.cfg.has_section('appearances'): self.cfg.add_section('appearances') @@ -104,7 +116,7 @@ def _get_bg(self): return self._bg def _set_bg(self, bg): self._bg = bg - color = Gdk.color_parse(self._bg) + color = gdk.color_parse(self._bg) for state in WIDGET_STATES: self.console.modify_bg(state, color) self.console.modify_base(state, color) @@ -122,7 +134,7 @@ def _get_fg(self): return self._fg def _set_fg(self, fg): self._fg = fg - color = Gdk.color_parse(self._fg) + color = gdk.color_parse(self._fg) for state in WIDGET_STATES: self.console.modify_fg(state, color) self.console.modify_text(state, color) @@ -163,10 +175,10 @@ def _set_use_rl_completer(self, use_rl_completer): def on_console_populate_popup(self, textview, menu, data=None): - item = Gtk.SeparatorMenuItem() + item = gtk.SeparatorMenuItem() item.show() menu.append(item) - item = Gtk.ImageMenuItem(stock_id=Gtk.STOCK_PREFERENCES) + item = gtk.ImageMenuItem(stock_id=gtk.STOCK_PREFERENCES) item.show() menu.append(item) item.connect("activate", lambda w,d=None: self.show_configure()) @@ -189,114 +201,115 @@ def on_bg_color_changed(self, clr_btn, data=None): def show_configure(self): - dialog = Gtk.Dialog("Configure Python Console", + dialog = gtk.Dialog("Configure Python Console", geany.main_widgets.window, - Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, - (Gtk.STOCK_CLOSE, Gtk.ResponseType.ACCEPT)) + gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, + (gtk.STOCK_CLOSE, gtk.RESPONSE_ACCEPT)) + + #dialog.set_has_separator(True) + content_area = dialog.get_content_area() content_area.set_border_width(6) - vbox = Gtk.VBox(spacing=6) + vbox = gtk.VBox(spacing=6) vbox.set_border_width(6) - lbl = Gtk.Label() + lbl = gtk.Label() lbl.set_use_markup(True) lbl.set_markup("General") - fra_general = Gtk.Frame() - fra_general.set_shadow_type(Gtk.ShadowType.NONE) + fra_general = gtk.Frame() + fra_general.set_shadow_type(gtk.SHADOW_NONE) fra_general.set_label_widget(lbl) - al_general = Gtk.Alignment() - al_general.set(0.0, 0.0, 1.0, 1.0) + al_general = gtk.Alignment(0.0, 0.0, 1.0, 1.0) al_general.set_padding(0, 0, 12, 0) fra_general.add(al_general) - tbl = Gtk.Table(3, 2, False) + tbl = gtk.Table(3, 2, False) tbl.set_row_spacings(6) tbl.set_col_spacings(6) tbl.set_border_width(6) - lbl = Gtk.Label("Banner:") + lbl = gtk.Label("Banner:") lbl.set_alignment(0.0, 0.0) - tvw = Gtk.TextView() + tvw = gtk.TextView() tvw.get_buffer().set_text(self.banner) tvw.get_buffer().connect("changed", self.on_banner_changed) - swin = Gtk.ScrolledWindow() - swin.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) - swin.set_shadow_type(Gtk.ShadowType.ETCHED_IN) + swin = gtk.ScrolledWindow() + swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + swin.set_shadow_type(gtk.SHADOW_ETCHED_IN) swin.add(tvw) - tbl.attach(lbl, 0, 1, 0, 1, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) - tbl.attach(swin, 1, 2, 0, 1, Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, 0, 0) + tbl.attach(lbl, 0, 1, 0, 1, gtk.FILL, gtk.FILL, 0, 0) + tbl.attach(swin, 1, 2, 0, 1, gtk.EXPAND | gtk.FILL, gtk.EXPAND | gtk.FILL, 0, 0) - lbl = Gtk.Label("") + lbl = gtk.Label("") lbl.set_alignment(0.0, 0.5) - check = Gtk.CheckButton("Use Readline") + check = gtk.CheckButton("Use Readline") if self.use_rl_completer: check.set_active(True) check.connect("toggled", self.on_use_rl_completer_toggled) - tbl.attach(lbl, 0, 1, 1, 2, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) - tbl.attach(check, 1, 2, 1, 2, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) + tbl.attach(lbl, 0, 1, 1, 2, gtk.FILL, gtk.FILL, 0, 0) + tbl.attach(check, 1, 2, 1, 2, gtk.FILL, gtk.FILL, 0, 0) - lbl = Gtk.Label("") + lbl = gtk.Label("") lbl.set_alignment(0.0, 0.5) lbl.set_use_markup(True) lbl.set_markup('' + 'Note: General settings will be applied when console is reloaded.' + '') - tbl.attach(lbl, 0, 2, 2, 3, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) + tbl.attach(lbl, 0, 2, 2, 3, gtk.FILL, gtk.FILL, 0, 0) al_general.add(tbl) - lbl = Gtk.Label() + lbl = gtk.Label() lbl.set_use_markup(True) lbl.set_markup("Appearances") - fra_appearances = Gtk.Frame() - fra_appearances.set_shadow_type(Gtk.ShadowType.NONE) + fra_appearances = gtk.Frame() + fra_appearances.set_shadow_type(gtk.SHADOW_NONE) fra_appearances.set_label_widget(lbl) - al_appearances = Gtk.Alignment() - al_appearances.set(0.0, 0.0, 1.0, 1.0) + al_appearances = gtk.Alignment(0.0, 0.0, 1.0, 1.0) al_appearances.set_padding(0, 0, 12, 0) fra_appearances.add(al_appearances) - tbl = Gtk.Table(3, 2, False) + tbl = gtk.Table(3, 2, False) tbl.set_row_spacings(6) tbl.set_col_spacings(6) tbl.set_border_width(6) - lbl = Gtk.Label("Font:") + lbl = gtk.Label("Font:") lbl.set_alignment(0.0, 0.5) - btn = Gtk.FontButton(self.font) + btn = gtk.FontButton(self.font) btn.connect("font-set", self.on_font_changed) - tbl.attach(lbl, 0, 1, 0, 1, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) - tbl.attach(btn, 1, 2, 0, 1, Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, Gtk.AttachOptions.FILL, 0, 0) + tbl.attach(lbl, 0, 1, 0, 1, gtk.FILL, gtk.FILL, 0, 0) + tbl.attach(btn, 1, 2, 0, 1, gtk.FILL | gtk.EXPAND, gtk.FILL, 0, 0) - lbl = Gtk.Label("FG Color:") + lbl = gtk.Label("FG Color:") lbl.set_alignment(0.0, 0.5) - btn = Gtk.ColorButton(Gdk.color_parse(self.fg)) + btn = gtk.ColorButton(gdk.color_parse(self.fg)) btn.connect("color-set", self.on_fg_color_changed) - tbl.attach(lbl, 0, 1, 1, 2, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) - tbl.attach(btn, 1, 2, 1, 2, Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, Gtk.AttachOptions.FILL, 0, 0) + tbl.attach(lbl, 0, 1, 1, 2, gtk.FILL, gtk.FILL, 0, 0) + tbl.attach(btn, 1, 2, 1, 2, gtk.FILL | gtk.EXPAND, gtk.FILL, 0, 0) - lbl = Gtk.Label("BG Color:") + lbl = gtk.Label("BG Color:") lbl.set_alignment(0.0, 0.5) - btn = Gtk.ColorButton(Gdk.color_parse(self.bg)) + btn = gtk.ColorButton(gdk.color_parse(self.bg)) btn.connect("color-set", self.on_bg_color_changed) - tbl.attach(lbl, 0, 1, 2, 3, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) - tbl.attach(btn, 1, 2, 2, 3, Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, Gtk.AttachOptions.FILL, 0, 0) + tbl.attach(lbl, 0, 1, 2, 3, gtk.FILL, gtk.FILL, 0, 0) + tbl.attach(btn, 1, 2, 2, 3, gtk.FILL | gtk.EXPAND, gtk.FILL, 0, 0) al_appearances.add(tbl) diff --git a/plugins/hello.py b/plugins/hello.py index c9e2859..d6153b8 100644 --- a/plugins/hello.py +++ b/plugins/hello.py @@ -1,4 +1,12 @@ -from gi.repository import Gtk +try: + from gi import pygtkcompat +except ImportError: + pygtkcompat = None + +if pygtkcompat is not None: + pygtkcompat.enable() + pygtkcompat.enable_gtk(version='3.0') +import gtk import geany class HelloWorld(geany.Plugin): @@ -9,7 +17,7 @@ class HelloWorld(geany.Plugin): __plugin_author__ = "John Doe " def __init__(self): - self.menu_item = Gtk.MenuItem("Hello World") + self.menu_item = gtk.MenuItem("Hello World") self.menu_item.show() geany.main_widgets.tools_menu.append(self.menu_item) self.menu_item.connect("activate", self.on_hello_item_clicked) From 58e19092a06579e8db5adee10efefb403d032ed2 Mon Sep 17 00:00:00 2001 From: Sagar Chalise Date: Fri, 19 Jul 2013 21:52:36 +0545 Subject: [PATCH 07/28] Gtk3 and Gtk2 both compabilities undertaken --- src/geanypy-plugin.c | 7 +++---- src/geanypy-uiutils.c | 18 +++++++++--------- src/geanypy.h | 11 ++++++----- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/geanypy-plugin.c b/src/geanypy-plugin.c index d505e79..66478e2 100644 --- a/src/geanypy-plugin.c +++ b/src/geanypy-plugin.c @@ -80,8 +80,8 @@ GeanyPy_start_interpreter(void) #endif Py_Initialize(); - #if GTK_CHECK_VERSION(3, 2, 0) - PySys_SetArgv(0, "[]"); + #if GTK_CHECK_VERSION(3, 0, 0) + PySys_SetArgv(0, "[]"); #endif /* Import the C modules */ initapp(); @@ -150,7 +150,6 @@ GeanyPy_init_manager(const gchar *dir) gchar *sys_plugin_dir = NULL; g_return_if_fail(dir != NULL); - module = PyImport_ImportModule("geany.manager"); if (module == NULL) { @@ -265,7 +264,7 @@ plugin_init(GeanyData *data) loader_item = gtk_menu_item_new_with_label(_("Python Plugin Manager")); gtk_widget_set_sensitive(loader_item, plugin_dir != NULL); - gtk_menu_append(GTK_MENU(geany->main_widgets->tools_menu), loader_item); + gtk_menu_shell_append(GTK_MENU_SHELL(geany->main_widgets->tools_menu), loader_item); gtk_widget_show(loader_item); g_signal_connect(loader_item, "activate", G_CALLBACK(on_python_plugin_loader_activate), NULL); diff --git a/src/geanypy-uiutils.c b/src/geanypy-uiutils.c index e463fb2..d3f06aa 100644 --- a/src/geanypy-uiutils.c +++ b/src/geanypy-uiutils.c @@ -123,8 +123,8 @@ UiUtils_combo_box_add_to_history(PyObject *module, PyObject *args, PyObject *kwa { GOB_CHECK(py_cbo, 1); widget = pygobject_get(py_cbo); - GOB_TYPE_CHECK(widget, GTK_TYPE_COMBO_BOX_ENTRY, 1); - ui_combo_box_add_to_history(GTK_COMBO_BOX_ENTRY(widget), text, hist_len); + GOB_TYPE_CHECK(widget, GTK_TYPE_COMBO_BOX_TEXT, 1); + ui_combo_box_add_to_history(GTK_COMBO_BOX_TEXT(widget), text, hist_len); } Py_RETURN_NONE; @@ -418,21 +418,21 @@ static PyMethodDef UiUtilsModule_methods[] = { PyMODINIT_FUNC initui_utils(void) { - PyObject *m; - #if GTK_CHECK_VERSION(2, 18, 0) - init_pygobject(); - init_pygtk(); - m = PyImport_ImportModule("gobject"); - #else + PyObject *m; + #if GTK_CHECK_VERSION(3, 0, 0) pygobject_init(-1, -1, -1); m = PyImport_ImportModule("gi._gobject"); + #else + init_pygobject() + init_pygtk() + m = PyImport_ImportModule("gobject"); #endif if (m) { PyGObject_Type = (PyTypeObject *) PyObject_GetAttrString(m, "GObject"); Py_XDECREF(m); } - InterfacePrefsType.tp_new = PyType_GenericNew; + InterfacePrefsType.tp_new = PyType_GenericNew; if (PyType_Ready(&InterfacePrefsType) < 0) return; diff --git a/src/geanypy.h b/src/geanypy.h index 672a417..168d7d6 100644 --- a/src/geanypy.h +++ b/src/geanypy.h @@ -77,12 +77,13 @@ extern "C" { #include #include -#ifndef GEANYPY_WINDOWS -/* On windows the path of pygtk.h is directly an include dir */ -# include -#elseif GTK_CHECK_VERSION(2, 18, 0) +#ifdef GEANYPY_WINDOWS /* Used with the results of `pkg-config --cflags pygtk-2.0` */ -# include +#include +/* On windows the path of pygtk.h is directly an include dir */ +#endif +#if !GTK_CHECK_VERSION(3, 0, 0) +#include #endif #ifndef GTK From 3da7333ef8d83578bfc4199c7780bb6a8025f8f1 Mon Sep 17 00:00:00 2001 From: Sagar Chalise Date: Fri, 19 Jul 2013 22:19:34 +0545 Subject: [PATCH 08/28] README for gtk2 and gtk3 --- README.markdown | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/README.markdown b/README.markdown index fd42392..f21c550 100644 --- a/README.markdown +++ b/README.markdown @@ -60,12 +60,27 @@ To build GeanyPy you need the following dependencies: * Python 2.6+ and development files (I don't think Python 3 will work). * Geany 0.21+ and development files (from SVN) + +** For Gtk2 ** + * PyGTK 2.0 and development files +** For Gtk3 ** + +* GObject Introspection is needed [pygtk not needed.] + On Debian/Ubuntu, the (non-Geany) dependencies can be installed like this: - $ apt-get install python python-dev python-gtk2 python-gtk2-dev + $ sudo apt-get install python python-dev + +** For Gtk2 ** + + $ sudo apt-get install python-gtk2 python-gtk2-dev + +** For Gtk3 ** + $ sudo apt-get install python-gi python-gi-dev + See Geany's documentation/website for information on compiling it from the Subversion or Git repositories. @@ -90,4 +105,4 @@ far. I imagine 2.7 series will also work fine. Running on Windows ------------------ -See `README.win32` for more information. +See `README.win32` for more information. \ No newline at end of file From 9d122d2e26ede77ab6bd9811311102b14efb846a Mon Sep 17 00:00:00 2001 From: Sagar Chalise Date: Fri, 19 Jul 2013 22:42:38 +0545 Subject: [PATCH 09/28] Pure gtk3 codebase and configurations/makefiles --- configure.ac | 4 +- geany/__init__.py | 2 +- geany/console.py | 87 ++++++++++---------------- geany/loader.py | 6 ++ geany/manager.py | 139 ++++++++++++++++++----------------------- geany/signalmanager.py | 82 +++++++++++------------- plugins/console.py | 119 ++++++++++++++++------------------- plugins/hello.py | 12 +--- src/Makefile.am | 6 +- 9 files changed, 198 insertions(+), 259 deletions(-) diff --git a/configure.ac b/configure.ac index 35230e6..2b18609 100644 --- a/configure.ac +++ b/configure.ac @@ -19,7 +19,7 @@ AC_PROG_SED # Check for headers, libraries and packages AC_CHECK_HEADERS([stdio.h string.h dlfcn.h]) PKG_CHECK_MODULES([GEANY], [geany >= 0.21]) -PKG_CHECK_MODULES([PYGTK], [pygtk-2.0]) +PKG_CHECK_MODULES([PYGOBJECT], [pygobject-3.0]) AX_PYTHON_DEVEL([>= '2.6']) AX_PYTHON_LIBRARY(,[AC_MSG_ERROR([Cannot determine location of the Python DSO])]) AC_SUBST([PYTHON]) @@ -37,4 +37,4 @@ AC_CONFIG_FILES([ geany/Makefile plugins/Makefile ]) -AC_OUTPUT +AC_OUTPUT \ No newline at end of file diff --git a/geany/__init__.py b/geany/__init__.py index 493dfa4..1cf6030 100644 --- a/geany/__init__.py +++ b/geany/__init__.py @@ -66,4 +66,4 @@ signals = SignalManager() import plugin -from plugin import Plugin +from plugin import Plugin \ No newline at end of file diff --git a/geany/console.py b/geany/console.py index d3776c7..2742aa6 100644 --- a/geany/console.py +++ b/geany/console.py @@ -28,29 +28,16 @@ # To modify output appearance, set attributes of console.stdout_tag and # console.stderr_tag. # -# Console may subclass a type other than gtk.TextView, to allow syntax highlighting and stuff, +# Console may subclass a type other than Gtk.TextView, to allow syntax highlighting and stuff, # e.g.: # console_type = pyconsole.ConsoleType(moo.TextView) -# console = console_type(use_rlcompleter=False, start_script="import moo\nimport gtk\n") +# console = console_type(use_rlcompleter=False, start_script="import moo\nimport Gtk\n") # # This widget is not a replacement for real terminal with python running # inside: GtkTextView is not a terminal. # The use case is: you have a python program, you create this widget, # and inspect your program interiors. -try: - from gi import pygtkcompat -except ImportError: - pygtkcompat = None - -if pygtkcompat is not None: - pygtkcompat.enable() - pygtkcompat.enable_gtk(version='3.0') - -import gtk -import gtk.gdk as gdk -import gobject -import pango -import gtk.keysyms as _keys +from gi.repository import GObject, Gtk, Gdk, Pango import code import sys import keyword @@ -117,8 +104,8 @@ def get(self, dir, text): def __init__(self): object.__init__(self) - self.set_wrap_mode(gtk.WRAP_CHAR) - self.modify_font(pango.FontDescription("Monospace")) + self.set_wrap_mode(Gtk.WrapMode.CHAR) + self.modify_font(Pango.FontDescription("Monospace")) self.buffer = self.get_buffer() self.buffer.connect("insert-text", self.on_buf_insert) @@ -250,27 +237,27 @@ def do_key_press_event(self, event, parent_type): self.tab_pressed = 0 handled = True - state = event.state & (gdk.SHIFT_MASK | - gdk.CONTROL_MASK | - gdk.MOD1_MASK) + state = event.state & (Gdk.ModifierType.SHIFT_MASK | + Gdk.ModifierType.CONTROL_MASK | + Gdk.ModifierType.MOD1_MASK) keyval = event.keyval if not state: - if keyval == _keys.Return: + if keyval == Gdk.KEY_Return: self._commit() - elif keyval == _keys.Up: + elif keyval == Gdk.KEY_Up: self.__history(-1) - elif keyval == _keys.Down: + elif keyval == Gdk.KEY_Down: self.__history(1) - elif keyval == _keys.Left: + elif keyval == Gdk.KEY_Left: self.__move_cursor(-1) - elif keyval == _keys.Right: + elif keyval == Gdk.KEY_Right: self.__move_cursor(1) - elif keyval == _keys.Home: + elif keyval == Gdk.KEY_Home: self.__move_cursor(-10000) - elif keyval == _keys.End: + elif keyval == Gdk.KEY_End: self.__move_cursor(10000) - elif keyval == _keys.Tab: + elif keyval == Gdk.KEY_Tab: cursor = self.__get_cursor() if cursor.starts_line(): handled = False @@ -283,8 +270,8 @@ def do_key_press_event(self, event, parent_type): self.__complete() else: handled = False - elif state == gdk.CONTROL_MASK: - if keyval == _keys.u: + elif state == Gdk.ModifierType.CONTROL_MASK: + if keyval == Gdk.KEY_u: start = self.__get_start() end = self.__get_cursor() self.__delete(start, end) @@ -351,9 +338,9 @@ def __delete_at_cursor(self, howmany): self.__delete(iter, end) def __get_width(self): - if not (gtk.get_realized()): + if not (Gtk.get_realized()): return 80 - layout = pango.Layout(self.get_pango_context()) + layout = Pango.Layout(self.get_pango_context()) letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" layout.set_text(letters) pix_width = layout.get_pixel_size()[0] @@ -531,10 +518,7 @@ def do_command(self, code): self.showtraceback() def runcode(self, code): - if gtk.pygtk_version[1] < 8: - self.do_command(code) - else: - self.emit("command", code) + self.emit("command", code) def exec_command(self, command): if self._get_line(): @@ -604,28 +588,25 @@ def complete(self, text): return completions -def ReadLineType(t=gtk.TextView): +def ReadLineType(t=Gtk.TextView): class readline(t, _ReadLine): def __init__(self, *args, **kwargs): t.__init__(self) _ReadLine.__init__(self, *args, **kwargs) def do_key_press_event(self, event): return _ReadLine.do_key_press_event(self, event, t) - gobject.type_register(readline) + GObject.type_register(readline) return readline -def ConsoleType(t=gtk.TextView): +def ConsoleType(t=Gtk.TextView): class console_type(t, _Console): __gsignals__ = { - 'command' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (object,)), + 'command' : (GObject.SignalFlags.RUN_LAST, None, (object,)), 'key-press-event' : 'override' } def __init__(self, *args, **kwargs): - if gtk.pygtk_version[1] < 8: - gobject.GObject.__init__(self) - else: - t.__init__(self) + GObject.GObject.__init__(self) _Console.__init__(self, *args, **kwargs) def do_command(self, code): @@ -634,9 +615,7 @@ def do_command(self, code): def do_key_press_event(self, event): return _Console.do_key_press_event(self, event, t) - if gtk.pygtk_version[1] < 8: - gobject.type_register(console_type) - + GObject.type_register(console_type) return console_type ReadLine = ReadLineType() @@ -650,19 +629,19 @@ def _create_widget(start_script): return console def _make_window(start_script="import geany\n"): - window = gtk.Window() + window = Gtk.Window() window.set_title("Python Console") - swin = gtk.ScrolledWindow() - swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS) + swin = Gtk.ScrolledWindow() + swin.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.ALWAYS) window.add(swin) console = _create_widget(start_script) swin.add(console) window.set_default_size(500, 400) window.show_all() - if not gtk.main_level(): - window.connect("destroy", gtk.main_quit) - gtk.main() + if not Gtk.main_level(): + window.connect("destroy", Gtk.main_quit) + Gtk.main() return console diff --git a/geany/loader.py b/geany/loader.py index ae4e504..15533b8 100644 --- a/geany/loader.py +++ b/geany/loader.py @@ -11,7 +11,13 @@ class PluginLoader(object): plugins = {} def __init__(self, plugin_dirs): + self.plugin_dirs = plugin_dirs + + #self.available_plugins = [] + #for plugin in self.iter_plugin_info(): + #self.available_plugins.append(plugin) + self.restore_loaded_plugins() diff --git a/geany/manager.py b/geany/manager.py index 7cd2680..59c2e87 100644 --- a/geany/manager.py +++ b/geany/manager.py @@ -1,89 +1,74 @@ -try: - from gi import pygtkcompat -except ImportError: - pygtkcompat = None - -if pygtkcompat is not None: - pygtkcompat.enable() - pygtkcompat.enable_gtk(version='3.0') - -import gtk -import gobject -import glib +from gi.repository import GObject, GLib, Gtk from htmlentitydefs import name2codepoint from loader import PluginLoader - -class PluginManager(gtk.Dialog): - +class PluginManager(Gtk.Dialog): def __init__(self, plugin_dirs=[]): super(PluginManager, self).__init__(title="Plugin Manager") self.loader = PluginLoader(plugin_dirs) - self.set_default_size(400, 450) - icon = self.render_icon(gtk.STOCK_PREFERENCES, gtk.ICON_SIZE_MENU) + icon = self.render_icon(Gtk.STOCK_PREFERENCES, Gtk.IconSize.MENU) self.set_icon(icon) - + self.connect("response", lambda w,d: self.hide()) - - vbox = gtk.VBox(False, 12) + + vbox = Gtk.VBox(False, 12) vbox.set_border_width(12) - - lbl = gtk.Label("Choose plugins to load or unload:") + + lbl = Gtk.Label("Choose plugins to load or unload:") lbl.set_alignment(0.0, 0.5) vbox.pack_start(lbl, False, False, 0) - - sw = gtk.ScrolledWindow() + + sw = Gtk.ScrolledWindow() sw.set_hexpand(True) sw.set_vexpand(True) - sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) - sw.set_shadow_type(gtk.SHADOW_ETCHED_IN) + sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) + sw.set_shadow_type(Gtk.ShadowType.ETCHED_IN) vbox.pack_start(sw, True, True, 0) - - self.treeview = gtk.TreeView() + + self.treeview = Gtk.TreeView() sw.add(self.treeview) - + vbox.show_all() - + self.get_content_area().add(vbox) - + action_area = self.get_action_area() action_area.set_spacing(0) action_area.set_homogeneous(False) - - btn = gtk.Button(stock=gtk.STOCK_CLOSE) + + btn = Gtk.Button(stock=Gtk.STOCK_CLOSE) btn.set_border_width(6) - btn.connect("clicked", lambda x: self.response(gtk.RESPONSE_CLOSE)) + btn.connect("clicked", lambda x: self.response(Gtk.ResponseType.CLOSE)) action_area.pack_start(btn, False, True, 0) btn.show() - - self.btn_help = gtk.Button(stock=gtk.STOCK_HELP) + + self.btn_help = Gtk.Button(stock=Gtk.STOCK_HELP) self.btn_help.set_border_width(6) self.btn_help.set_no_show_all(True) action_area.pack_start(self.btn_help, False, True, 0) action_area.set_child_secondary(self.btn_help, True) - - self.btn_prefs = gtk.Button(stock=gtk.STOCK_PREFERENCES) + + self.btn_prefs = Gtk.Button(stock=Gtk.STOCK_PREFERENCES) self.btn_prefs.set_border_width(6) self.btn_prefs.set_no_show_all(True) action_area.pack_start(self.btn_prefs, False, True, 0) action_area.set_child_secondary(self.btn_prefs, True) - + action_area.show() - + self.load_plugins_list() - def on_help_button_clicked(self, button, treeview, model): path = treeview.get_cursor()[0] iter = model.get_iter(path) filename = model.get_value(iter, 2) - for plugin in self.loader.available_plugins: + for plugin in self.loader.iter_plugin_info(): if plugin.filename == filename: plugin.cls.show_help() break - else: - print("Plugin does not support help function") + else: + print("Plugin does not support help function") def on_preferences_button_clicked(self, button, treeview, model): @@ -105,76 +90,74 @@ def deactivate_plugin(self, filename): def load_plugins_list(self): - liststore = gtk.ListStore(gobject.TYPE_BOOLEAN, str, str) + liststore = Gtk.ListStore(GObject.TYPE_BOOLEAN, str, str) self.btn_help.connect("clicked", - self.on_help_button_clicked, self.treeview, liststore) + self.on_help_button_clicked, self.treeview, liststore) self.btn_prefs.connect("clicked", - self.on_preferences_button_clicked, self.treeview, liststore) + self.on_preferences_button_clicked, self.treeview, liststore) self.treeview.set_model(liststore) self.treeview.set_headers_visible(False) self.treeview.set_grid_lines(True) - check_renderer = gtk.CellRendererToggle() + check_renderer = Gtk.CellRendererToggle() check_renderer.set_radio(False) check_renderer.connect('toggled', self.on_plugin_load_toggled, liststore) - text_renderer = gtk.CellRendererText() - - check_column = gtk.TreeViewColumn(None, check_renderer, active=0) - text_column = gtk.TreeViewColumn(None, text_renderer, markup=1) - + text_renderer = Gtk.CellRendererText() + check_column = Gtk.TreeViewColumn(None, check_renderer, active=0) + text_column = Gtk.TreeViewColumn(None, text_renderer, markup=1) + self.treeview.append_column(check_column) self.treeview.append_column(text_column) - + self.treeview.connect('row-activated', - self.on_row_activated, check_renderer, liststore) + self.on_row_activated, check_renderer, liststore) self.treeview.connect('cursor-changed', - self.on_selected_plugin_changed, liststore) - + self.on_selected_plugin_changed, liststore) + self.load_sorted_plugins_info(liststore) def load_sorted_plugins_info(self, list_store): - - plugin_info_list = list(self.loader.iter_plugin_info()) + #plugin_info_list = list(self.loader.iter_plugin_info()) #plugin_info_list.sort(key=lambda pi: pi[1]) - for plugin_info in plugin_info_list: - + for plugin_info in self.loader.iter_plugin_info(): + lbl = str('%s %s\n%s\n' + - 'Author: %s\n' + - 'Filename: %s') % ( - glib.markup_escape_text(plugin_info.name), - glib.markup_escape_text(plugin_info.version), - glib.markup_escape_text(plugin_info.description), - glib.markup_escape_text(plugin_info.author), - glib.markup_escape_text(plugin_info.filename)) - + 'Author: %s\n' + + 'Filename: %s') % ( + GLib.markup_escape_text(plugin_info.name), + GLib.markup_escape_text(plugin_info.version), + GLib.markup_escape_text(plugin_info.description), + GLib.markup_escape_text(plugin_info.author), + GLib.markup_escape_text(plugin_info.filename)) + loaded = plugin_info.filename in self.loader.plugins - + list_store.append([loaded, lbl, plugin_info.filename]) - + def on_selected_plugin_changed(self, treeview, model): - + path = treeview.get_cursor()[0] iter = model.get_iter(path) filename = model.get_value(iter, 2) active = model.get_value(iter, 0) - + if self.loader.plugin_has_configure(filename): self.btn_prefs.set_visible(True) else: self.btn_prefs.set_visible(False) - + if self.loader.plugin_has_help(filename): self.btn_help.set_visible(True) else: self.btn_help.set_visible(False) - - + + def on_plugin_load_toggled(self, cell, path, model): active = not cell.get_active() iter = model.get_iter(path) @@ -183,7 +166,7 @@ def on_plugin_load_toggled(self, cell, path, model): self.activate_plugin(model.get_value(iter, 2)) else: self.deactivate_plugin(model.get_value(iter, 2)) - - + + def on_row_activated(self, tvw, path, view_col, cell, model): self.on_plugin_load_toggled(cell, path, model) \ No newline at end of file diff --git a/geany/signalmanager.py b/geany/signalmanager.py index 16d7910..3e0d69e 100644 --- a/geany/signalmanager.py +++ b/geany/signalmanager.py @@ -3,62 +3,54 @@ all signals on. The signals are emitted from the C code in signalmanager.c, where the Geany types get wrapped in PyObject types. """ -try: - from gi import pygtkcompat -except ImportError: - pygtkcompat = None +from gi.repository import GObject -if pygtkcompat is not None: - pygtkcompat.enable() - pygtkcompat.enable_gtk(version='3.0') -import gobject - -class SignalManager(gobject.GObject): +class SignalManager(GObject.GObject): """ Manages callback functions for events emitted by Geany's internal GObject. """ __gsignals__ = { - 'build-start': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + 'build-start': (GObject.SignalFlags.RUN_LAST, None, ()), - 'document-activate': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'document-before-save': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'document-close': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'document-filetype-set': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT)), - 'document-new': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'document-open': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'document-reload': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'document-save': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'editor-notify': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_BOOLEAN, - (gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT)), - 'geany-startup-complete': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + 'document-activate': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'document-before-save': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'document-close': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'document-filetype-set': (GObject.SignalFlags.RUN_LAST, None, + (object, object)), + 'document-new': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'document-open': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'document-reload': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'document-save': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'editor-notify': (GObject.SignalFlags.RUN_LAST, GObject.TYPE_BOOLEAN, + (object, object)), + 'geany-startup-complete': (GObject.SignalFlags.RUN_LAST, None, ()), - 'project-close': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + 'project-close': (GObject.SignalFlags.RUN_LAST, None, ()), - 'project-dialog-confirmed': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'project-dialog-open': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'project-dialog-close': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'project-open': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'project-save': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'update-editor-menu': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_STRING, gobject.TYPE_INT, - gobject.TYPE_PYOBJECT)), + 'project-dialog-confirmed': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'project-dialog-open': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'project-dialog-close': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'project-open': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'project-save': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'update-editor-menu': (GObject.SignalFlags.RUN_LAST, None, + (GObject.TYPE_STRING, GObject.TYPE_INT, + object)), } # __gsignals__ def __init__(self): super(SignalManager, self).__init__() -gobject.type_register(SignalManager) \ No newline at end of file +GObject.type_register(SignalManager) \ No newline at end of file diff --git a/plugins/console.py b/plugins/console.py index 69a46cf..6665495 100644 --- a/plugins/console.py +++ b/plugins/console.py @@ -1,24 +1,12 @@ -try: - from gi import pygtkcompat -except ImportError: - pygtkcompat = None - -if pygtkcompat is not None: - pygtkcompat.enable() - pygtkcompat.enable_gtk(version='3.0') - import os from ConfigParser import SafeConfigParser import geany import geany.console -import gobject -import gtk -import gtk.gdk as gdk -import pango +from gi.repository import GObject, Gtk, Gdk, Pango -WIDGET_STATES = [ gtk.STATE_NORMAL, gtk.STATE_ACTIVE, gtk.STATE_PRELIGHT, - gtk.STATE_SELECTED, gtk.STATE_INSENSITIVE ] +WIDGET_STATES = [ Gtk.StateType.NORMAL, Gtk.StateType.ACTIVE, Gtk.StateType.PRELIGHT, + Gtk.StateType.SELECTED, Gtk.StateType.INSENSITIVE ] class ConsolePlugin(geany.Plugin): @@ -57,7 +45,7 @@ def load_config(self): def save_config(self): - gobject.idle_add(self.on_save_config_timeout) + GObject.idle_add(self.on_save_config_timeout) def on_save_config_timeout(self, data=None): @@ -71,8 +59,8 @@ def install_console(self): self.banner = self.banner self.use_rl_completer = self.use_rl_completer - self.swin = gtk.ScrolledWindow() - self.swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS) + self.swin = Gtk.ScrolledWindow() + self.swin.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.ALWAYS) self.console = geany.console.Console(banner = self.banner, use_rlcompleter = self.use_rl_completer) self.console.connect("populate-popup", self.on_console_populate_popup) @@ -84,7 +72,7 @@ def install_console(self): self.swin.add(self.console) geany.main_widgets.message_window_notebook.append_page(self.swin, - gtk.Label("Python")) + Gtk.Label("Python")) self.swin.show_all() self.save_config() @@ -100,7 +88,7 @@ def _get_font(self): return self._font def _set_font(self, font): self._font = font - font_desc = pango.FontDescription(font) + font_desc = Pango.FontDescription(font) self.console.modify_font(font_desc) if not self.cfg.has_section('appearances'): self.cfg.add_section('appearances') @@ -116,7 +104,7 @@ def _get_bg(self): return self._bg def _set_bg(self, bg): self._bg = bg - color = gdk.color_parse(self._bg) + color = Gdk.color_parse(self._bg) for state in WIDGET_STATES: self.console.modify_bg(state, color) self.console.modify_base(state, color) @@ -134,7 +122,7 @@ def _get_fg(self): return self._fg def _set_fg(self, fg): self._fg = fg - color = gdk.color_parse(self._fg) + color = Gdk.color_parse(self._fg) for state in WIDGET_STATES: self.console.modify_fg(state, color) self.console.modify_text(state, color) @@ -175,10 +163,10 @@ def _set_use_rl_completer(self, use_rl_completer): def on_console_populate_popup(self, textview, menu, data=None): - item = gtk.SeparatorMenuItem() + item = Gtk.SeparatorMenuItem() item.show() menu.append(item) - item = gtk.ImageMenuItem(stock_id=gtk.STOCK_PREFERENCES) + item = Gtk.ImageMenuItem(stock_id=Gtk.STOCK_PREFERENCES) item.show() menu.append(item) item.connect("activate", lambda w,d=None: self.show_configure()) @@ -201,115 +189,114 @@ def on_bg_color_changed(self, clr_btn, data=None): def show_configure(self): - dialog = gtk.Dialog("Configure Python Console", + dialog = Gtk.Dialog("Configure Python Console", geany.main_widgets.window, - gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, - (gtk.STOCK_CLOSE, gtk.RESPONSE_ACCEPT)) - - #dialog.set_has_separator(True) - + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, + (Gtk.STOCK_CLOSE, Gtk.ResponseType.ACCEPT)) content_area = dialog.get_content_area() content_area.set_border_width(6) - vbox = gtk.VBox(spacing=6) + vbox = Gtk.VBox(spacing=6) vbox.set_border_width(6) - lbl = gtk.Label() + lbl = Gtk.Label() lbl.set_use_markup(True) lbl.set_markup("General") - fra_general = gtk.Frame() - fra_general.set_shadow_type(gtk.SHADOW_NONE) + fra_general = Gtk.Frame() + fra_general.set_shadow_type(Gtk.ShadowType.NONE) fra_general.set_label_widget(lbl) - al_general = gtk.Alignment(0.0, 0.0, 1.0, 1.0) + al_general = Gtk.Alignment() + al_general.set(0.0, 0.0, 1.0, 1.0) al_general.set_padding(0, 0, 12, 0) fra_general.add(al_general) - tbl = gtk.Table(3, 2, False) + tbl = Gtk.Table(3, 2, False) tbl.set_row_spacings(6) tbl.set_col_spacings(6) tbl.set_border_width(6) - lbl = gtk.Label("Banner:") + lbl = Gtk.Label("Banner:") lbl.set_alignment(0.0, 0.0) - tvw = gtk.TextView() + tvw = Gtk.TextView() tvw.get_buffer().set_text(self.banner) tvw.get_buffer().connect("changed", self.on_banner_changed) - swin = gtk.ScrolledWindow() - swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) - swin.set_shadow_type(gtk.SHADOW_ETCHED_IN) + swin = Gtk.ScrolledWindow() + swin.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) + swin.set_shadow_type(Gtk.ShadowType.ETCHED_IN) swin.add(tvw) - tbl.attach(lbl, 0, 1, 0, 1, gtk.FILL, gtk.FILL, 0, 0) - tbl.attach(swin, 1, 2, 0, 1, gtk.EXPAND | gtk.FILL, gtk.EXPAND | gtk.FILL, 0, 0) + tbl.attach(lbl, 0, 1, 0, 1, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) + tbl.attach(swin, 1, 2, 0, 1, Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, 0, 0) - lbl = gtk.Label("") + lbl = Gtk.Label("") lbl.set_alignment(0.0, 0.5) - check = gtk.CheckButton("Use Readline") + check = Gtk.CheckButton("Use Readline") if self.use_rl_completer: check.set_active(True) check.connect("toggled", self.on_use_rl_completer_toggled) - tbl.attach(lbl, 0, 1, 1, 2, gtk.FILL, gtk.FILL, 0, 0) - tbl.attach(check, 1, 2, 1, 2, gtk.FILL, gtk.FILL, 0, 0) + tbl.attach(lbl, 0, 1, 1, 2, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) + tbl.attach(check, 1, 2, 1, 2, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) - lbl = gtk.Label("") + lbl = Gtk.Label("") lbl.set_alignment(0.0, 0.5) lbl.set_use_markup(True) lbl.set_markup('' + 'Note: General settings will be applied when console is reloaded.' + '') - tbl.attach(lbl, 0, 2, 2, 3, gtk.FILL, gtk.FILL, 0, 0) + tbl.attach(lbl, 0, 2, 2, 3, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) al_general.add(tbl) - lbl = gtk.Label() + lbl = Gtk.Label() lbl.set_use_markup(True) lbl.set_markup("Appearances") - fra_appearances = gtk.Frame() - fra_appearances.set_shadow_type(gtk.SHADOW_NONE) + fra_appearances = Gtk.Frame() + fra_appearances.set_shadow_type(Gtk.ShadowType.NONE) fra_appearances.set_label_widget(lbl) - al_appearances = gtk.Alignment(0.0, 0.0, 1.0, 1.0) + al_appearances = Gtk.Alignment() + al_appearances.set(0.0, 0.0, 1.0, 1.0) al_appearances.set_padding(0, 0, 12, 0) fra_appearances.add(al_appearances) - tbl = gtk.Table(3, 2, False) + tbl = Gtk.Table(3, 2, False) tbl.set_row_spacings(6) tbl.set_col_spacings(6) tbl.set_border_width(6) - lbl = gtk.Label("Font:") + lbl = Gtk.Label("Font:") lbl.set_alignment(0.0, 0.5) - btn = gtk.FontButton(self.font) + btn = Gtk.FontButton(self.font) btn.connect("font-set", self.on_font_changed) - tbl.attach(lbl, 0, 1, 0, 1, gtk.FILL, gtk.FILL, 0, 0) - tbl.attach(btn, 1, 2, 0, 1, gtk.FILL | gtk.EXPAND, gtk.FILL, 0, 0) + tbl.attach(lbl, 0, 1, 0, 1, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) + tbl.attach(btn, 1, 2, 0, 1, Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, Gtk.AttachOptions.FILL, 0, 0) - lbl = gtk.Label("FG Color:") + lbl = Gtk.Label("FG Color:") lbl.set_alignment(0.0, 0.5) - btn = gtk.ColorButton(gdk.color_parse(self.fg)) + btn = Gtk.ColorButton(Gdk.color_parse(self.fg)) btn.connect("color-set", self.on_fg_color_changed) - tbl.attach(lbl, 0, 1, 1, 2, gtk.FILL, gtk.FILL, 0, 0) - tbl.attach(btn, 1, 2, 1, 2, gtk.FILL | gtk.EXPAND, gtk.FILL, 0, 0) + tbl.attach(lbl, 0, 1, 1, 2, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) + tbl.attach(btn, 1, 2, 1, 2, Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, Gtk.AttachOptions.FILL, 0, 0) - lbl = gtk.Label("BG Color:") + lbl = Gtk.Label("BG Color:") lbl.set_alignment(0.0, 0.5) - btn = gtk.ColorButton(gdk.color_parse(self.bg)) + btn = Gtk.ColorButton(Gdk.color_parse(self.bg)) btn.connect("color-set", self.on_bg_color_changed) - tbl.attach(lbl, 0, 1, 2, 3, gtk.FILL, gtk.FILL, 0, 0) - tbl.attach(btn, 1, 2, 2, 3, gtk.FILL | gtk.EXPAND, gtk.FILL, 0, 0) + tbl.attach(lbl, 0, 1, 2, 3, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) + tbl.attach(btn, 1, 2, 2, 3, Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, Gtk.AttachOptions.FILL, 0, 0) al_appearances.add(tbl) diff --git a/plugins/hello.py b/plugins/hello.py index d6153b8..c9e2859 100644 --- a/plugins/hello.py +++ b/plugins/hello.py @@ -1,12 +1,4 @@ -try: - from gi import pygtkcompat -except ImportError: - pygtkcompat = None - -if pygtkcompat is not None: - pygtkcompat.enable() - pygtkcompat.enable_gtk(version='3.0') -import gtk +from gi.repository import Gtk import geany class HelloWorld(geany.Plugin): @@ -17,7 +9,7 @@ class HelloWorld(geany.Plugin): __plugin_author__ = "John Doe " def __init__(self): - self.menu_item = gtk.MenuItem("Hello World") + self.menu_item = Gtk.MenuItem("Hello World") self.menu_item.show() geany.main_widgets.tools_menu.append(self.menu_item) self.menu_item.connect("activate", self.on_hello_item_clicked) diff --git a/src/Makefile.am b/src/Makefile.am index 3be1760..3c30b24 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,11 +2,11 @@ geanyplugin_LTLIBRARIES = geanypy.la geanyplugindir = $(libdir)/geany geanypy_la_LDFLAGS = -module -avoid-version -Wl,--export-dynamic -geanypy_la_CPPFLAGS = @GEANY_CFLAGS@ @PYGTK_CFLAGS@ @PYTHON_CPPFLAGS@ \ +geanypy_la_CPPFLAGS = @GEANY_CFLAGS@ @PYGOBJECT_CFLAGS@ @PYTHON_CPPFLAGS@ \ -DGEANYPY_PYTHON_DIR="\"$(libdir)/geany/geanypy\"" \ -DGEANYPY_PLUGIN_DIR="\"$(datadir)/geany/geanypy/plugins\"" \ -UHAVE_CONFIG_H -geanypy_la_LIBADD = @GEANY_LIBS@ @PYGTK_LIBS@ @PYTHON_LDFLAGS@ \ +geanypy_la_LIBADD = @GEANY_LIBS@ @PYGOBJECT_LIBS@ @PYTHON_LDFLAGS@ \ @PYTHON_EXTRA_LIBS@ @PYTHON_EXTRA_LDFLAGS@ geanypy_la_SOURCES = geanypy-app.c \ geanypy-dialogs.c \ @@ -31,4 +31,4 @@ geanypy_la_SOURCES = geanypy-app.c \ geanypy-search.c \ geanypy-signalmanager.c geanypy-signalmanager.h \ geanypy-templates.c \ - geanypy-uiutils.c geanypy-uiutils.h + geanypy-uiutils.c geanypy-uiutils.h \ No newline at end of file From ba77101e2194409a9c07a4a932aac0d1f9758bf2 Mon Sep 17 00:00:00 2001 From: Sagar Chalise Date: Sat, 20 Jul 2013 22:07:31 +0545 Subject: [PATCH 10/28] Donot know why keybinding was not enabled by default --- geany/__init__.py | 4 + src/geanypy-bindings.c | 236 +++++++++++++++++++++++++++++++++++++++++ src/geanypy-plugin.c | 2 + 3 files changed, 242 insertions(+) create mode 100644 src/geanypy-bindings.c diff --git a/geany/__init__.py b/geany/__init__.py index 1cf6030..94a9003 100644 --- a/geany/__init__.py +++ b/geany/__init__.py @@ -8,6 +8,7 @@ """ import app +import bindings import console import dialogs import document @@ -65,5 +66,8 @@ # GObject to connect signal handlers on and which emits signals. signals = SignalManager() +# Initialize the keybindings manager +bindings.init() + import plugin from plugin import Plugin \ No newline at end of file diff --git a/src/geanypy-bindings.c b/src/geanypy-bindings.c new file mode 100644 index 0000000..ffe1c83 --- /dev/null +++ b/src/geanypy-bindings.c @@ -0,0 +1,236 @@ +#include "geanypy.h" + + +#define KB_MAX 256 +#define KB_LABEL_MAX 255 + +typedef struct +{ + gchar *kg_name; + GeanyKeyGroup *group; + GeanyKeyBinding *bindings[KB_MAX] ; + PyObject *callbacks[KB_MAX]; + PyObject *user_data[KB_MAX]; + gchar labels[KB_MAX][KB_LABEL_MAX]; + gboolean slots[KB_MAX]; + gboolean registered[KB_MAX]; + gboolean initialized; +} KbManager; + + +static KbManager manager = { NULL }; + + +static gchar *name_to_key(const gchar *name) +{ + gchar *ptr, *ret = g_strdup(name); + for (ptr = ret; *ptr != '\0'; ptr++) { + if (!isalnum(*ptr)) + *ptr = '_'; + } + if (strlen(ret) && !isalpha(ret[0])) + ret[0] = '_'; + return ret; +} + + +static uint next_key_id(gboolean *found) +{ + uint i; + for (i = 0; i < KB_MAX; i++) + { + if (!manager.slots[i]) + { + if (found) + *found = TRUE; + return i; + } + } + if (found) + *found = FALSE; + return 0; +} + + +static void on_keybinding_activate(guint key_id) +{ + PyObject *args; + + g_return_if_fail(key_id < KB_MAX); + + if (manager.slots[key_id]) + { + g_return_if_fail(manager.callbacks[key_id]); + g_return_if_fail(PyCallable_Check(manager.callbacks[key_id])); + + if (manager.user_data[key_id]) + args = Py_BuildValue("(iO)", key_id, manager.user_data[key_id]); + else + args = Py_BuildValue("(i)", key_id); + + if (!args) + { + g_warning("Unable to build Python arguments."); + if (PyErr_Occurred()) + PyErr_Print(); + return; + } + + (void) PyObject_CallObject(manager.callbacks[key_id], args); + Py_DECREF(args); + } +} + + +PyObject * kb_manager_init(PyObject *module) +{ + + if (manager.initialized) + Py_RETURN_TRUE; + + manager.kg_name = name_to_key("GeanyPy" /* FIXME: use plugin name */); + manager.group = plugin_set_key_group(geany_plugin, manager.kg_name, KB_MAX, + (GeanyKeyGroupCallback) on_keybinding_activate); + + if (manager.group) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; +} + + +#if 0 +PyObject * kb_manager_finalize(PyObject *module) +{ + uint i; + for (i = 0; i < KB_MAX; i++) + { + Py_XDECREF(manager.callbacks[i]); + Py_XDECREF(manager.user_data[i]); + g_free(manager.labels[i]); + } + g_free(manager.kg_name); + Py_RETURN_NONE; +} +#endif + + +PyObject * kb_manager_register_binding(PyObject *module, PyObject *args) +{ + guint id; + gboolean found_id; + gchar *key_name; + const gchar *name, *label; + PyObject *pCallback, *pData = NULL; + + if (!PyArg_ParseTuple(args, "ssO|O", &name, &label, &pCallback, &pData)) + { + PyErr_SetString(PyExc_ValueError, "unable to parse arguments"); + return NULL; + } + + found_id = FALSE; + id = next_key_id(&found_id); + if (!found_id) + { + PyErr_SetString(PyExc_RuntimeError, "no free keybindings left"); + return NULL; + } + + if (!PyCallable_Check(pCallback)) + { + PyErr_SetString(PyExc_ValueError, "callback function is not callable"); + return NULL; + } + + /* TODO: need to check name, label, callback? */ + + snprintf(manager.labels[id], KB_LABEL_MAX, "%s: %s", name, label); + + if (!manager.registered[id]) + { + key_name = g_strdup_printf("%s_%d", manager.kg_name, id); + manager.bindings[id] = keybindings_set_item(manager.group, + (gsize) id, + NULL, + 0, + 0, + key_name, + manager.labels[id], + NULL); + g_free(key_name); + + if (manager.bindings[id]) + manager.registered[id] = TRUE; + else + { + PyErr_SetString(PyExc_RuntimeError, "unable to register keybinding"); + return NULL; + } + } + + Py_INCREF(pCallback); + manager.callbacks[id] = pCallback; + + Py_XINCREF(pData); + manager.user_data[id] = pData; + + manager.slots[id] = TRUE; + + return PyInt_FromLong((long) id); +} + + +PyObject * kb_manager_unregister_binding(PyObject *module, PyObject *args) +{ + guint id; + + if (!PyArg_ParseTuple(args, "I", &id)) + { + PyErr_SetString(PyExc_ValueError, "expecting a single int argument"); + return NULL; + } + + if (id >= KB_MAX) + { + gchar *msg = g_strdup_printf("id is out of range (0-%d)", KB_MAX); + PyErr_SetString(PyExc_IndexError, msg); + g_free(msg); + return NULL; + } + + if (!manager.slots[id]) + { + PyErr_SetString(PyExc_IndexError, "id is not registered"); + return NULL; + } + + Py_XDECREF(manager.callbacks[id]); + Py_XDECREF(manager.user_data[id]); + manager.callbacks[id] = NULL; + manager.user_data[id] = NULL; + manager.slots[id] = FALSE; + manager.labels[id][0] = '\0'; + + Py_RETURN_NONE; +} + + +static PyMethodDef KbManagerModule_methods[] = { + { "init", (PyCFunction) kb_manager_init, METH_NOARGS, + "Initialize the keybindings manager." }, + { "register_binding", (PyCFunction) kb_manager_register_binding, + METH_VARARGS, "Register a callback function for a keybinding event." }, + { "unregister_binding", (PyCFunction) kb_manager_unregister_binding, + METH_VARARGS, "Unregister a callback function by id." }, + { NULL } +}; + + +PyMODINIT_FUNC initbindings(void) +{ + PyObject *m; + + m = Py_InitModule3("bindings", KbManagerModule_methods, + "Keybindings management."); +} \ No newline at end of file diff --git a/src/geanypy-plugin.c b/src/geanypy-plugin.c index 66478e2..8427bca 100644 --- a/src/geanypy-plugin.c +++ b/src/geanypy-plugin.c @@ -43,6 +43,7 @@ static SignalManager *signal_manager = NULL; /* Forward declarations to prevent compiler warnings. */ PyMODINIT_FUNC initapp(void); +PyMODINIT_FUNC initbindings(void); PyMODINIT_FUNC initdialogs(void); PyMODINIT_FUNC initdocument(void); PyMODINIT_FUNC initeditor(void); @@ -85,6 +86,7 @@ GeanyPy_start_interpreter(void) #endif /* Import the C modules */ initapp(); + initbindings(); initdialogs(); initdocument(); initeditor(); From 28299290d09397d1801d4bd96df5aac43055ed7e Mon Sep 17 00:00:00 2001 From: Sagar Chalise Date: Sat, 20 Jul 2013 22:11:24 +0545 Subject: [PATCH 11/28] Added keybinding --- src/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Makefile.am b/src/Makefile.am index 3c30b24..5e3247d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -9,6 +9,7 @@ geanypy_la_CPPFLAGS = @GEANY_CFLAGS@ @PYGOBJECT_CFLAGS@ @PYTHON_CPPFLAGS@ \ geanypy_la_LIBADD = @GEANY_LIBS@ @PYGOBJECT_LIBS@ @PYTHON_LDFLAGS@ \ @PYTHON_EXTRA_LIBS@ @PYTHON_EXTRA_LDFLAGS@ geanypy_la_SOURCES = geanypy-app.c \ + geanypy-bindings.c \ geanypy-dialogs.c \ geanypy-document.c geanypy-document.h \ geanypy-editor.c geanypy-editor.h \ From fcd83b40745ddbe434e4d41062e604dae76df717 Mon Sep 17 00:00:00 2001 From: Sagar Chalise Date: Sat, 20 Jul 2013 22:24:57 +0545 Subject: [PATCH 12/28] Gtk2 and gtk3 --- geany/console.py | 87 ++++++++++++++++---------- geany/loader.py | 6 -- geany/manager.py | 139 +++++++++++++++++++++++------------------ geany/signalmanager.py | 82 +++++++++++++----------- plugins/console.py | 119 +++++++++++++++++++---------------- plugins/hello.py | 12 +++- 6 files changed, 253 insertions(+), 192 deletions(-) diff --git a/geany/console.py b/geany/console.py index 2742aa6..d3776c7 100644 --- a/geany/console.py +++ b/geany/console.py @@ -28,16 +28,29 @@ # To modify output appearance, set attributes of console.stdout_tag and # console.stderr_tag. # -# Console may subclass a type other than Gtk.TextView, to allow syntax highlighting and stuff, +# Console may subclass a type other than gtk.TextView, to allow syntax highlighting and stuff, # e.g.: # console_type = pyconsole.ConsoleType(moo.TextView) -# console = console_type(use_rlcompleter=False, start_script="import moo\nimport Gtk\n") +# console = console_type(use_rlcompleter=False, start_script="import moo\nimport gtk\n") # # This widget is not a replacement for real terminal with python running # inside: GtkTextView is not a terminal. # The use case is: you have a python program, you create this widget, # and inspect your program interiors. -from gi.repository import GObject, Gtk, Gdk, Pango +try: + from gi import pygtkcompat +except ImportError: + pygtkcompat = None + +if pygtkcompat is not None: + pygtkcompat.enable() + pygtkcompat.enable_gtk(version='3.0') + +import gtk +import gtk.gdk as gdk +import gobject +import pango +import gtk.keysyms as _keys import code import sys import keyword @@ -104,8 +117,8 @@ def get(self, dir, text): def __init__(self): object.__init__(self) - self.set_wrap_mode(Gtk.WrapMode.CHAR) - self.modify_font(Pango.FontDescription("Monospace")) + self.set_wrap_mode(gtk.WRAP_CHAR) + self.modify_font(pango.FontDescription("Monospace")) self.buffer = self.get_buffer() self.buffer.connect("insert-text", self.on_buf_insert) @@ -237,27 +250,27 @@ def do_key_press_event(self, event, parent_type): self.tab_pressed = 0 handled = True - state = event.state & (Gdk.ModifierType.SHIFT_MASK | - Gdk.ModifierType.CONTROL_MASK | - Gdk.ModifierType.MOD1_MASK) + state = event.state & (gdk.SHIFT_MASK | + gdk.CONTROL_MASK | + gdk.MOD1_MASK) keyval = event.keyval if not state: - if keyval == Gdk.KEY_Return: + if keyval == _keys.Return: self._commit() - elif keyval == Gdk.KEY_Up: + elif keyval == _keys.Up: self.__history(-1) - elif keyval == Gdk.KEY_Down: + elif keyval == _keys.Down: self.__history(1) - elif keyval == Gdk.KEY_Left: + elif keyval == _keys.Left: self.__move_cursor(-1) - elif keyval == Gdk.KEY_Right: + elif keyval == _keys.Right: self.__move_cursor(1) - elif keyval == Gdk.KEY_Home: + elif keyval == _keys.Home: self.__move_cursor(-10000) - elif keyval == Gdk.KEY_End: + elif keyval == _keys.End: self.__move_cursor(10000) - elif keyval == Gdk.KEY_Tab: + elif keyval == _keys.Tab: cursor = self.__get_cursor() if cursor.starts_line(): handled = False @@ -270,8 +283,8 @@ def do_key_press_event(self, event, parent_type): self.__complete() else: handled = False - elif state == Gdk.ModifierType.CONTROL_MASK: - if keyval == Gdk.KEY_u: + elif state == gdk.CONTROL_MASK: + if keyval == _keys.u: start = self.__get_start() end = self.__get_cursor() self.__delete(start, end) @@ -338,9 +351,9 @@ def __delete_at_cursor(self, howmany): self.__delete(iter, end) def __get_width(self): - if not (Gtk.get_realized()): + if not (gtk.get_realized()): return 80 - layout = Pango.Layout(self.get_pango_context()) + layout = pango.Layout(self.get_pango_context()) letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" layout.set_text(letters) pix_width = layout.get_pixel_size()[0] @@ -518,7 +531,10 @@ def do_command(self, code): self.showtraceback() def runcode(self, code): - self.emit("command", code) + if gtk.pygtk_version[1] < 8: + self.do_command(code) + else: + self.emit("command", code) def exec_command(self, command): if self._get_line(): @@ -588,25 +604,28 @@ def complete(self, text): return completions -def ReadLineType(t=Gtk.TextView): +def ReadLineType(t=gtk.TextView): class readline(t, _ReadLine): def __init__(self, *args, **kwargs): t.__init__(self) _ReadLine.__init__(self, *args, **kwargs) def do_key_press_event(self, event): return _ReadLine.do_key_press_event(self, event, t) - GObject.type_register(readline) + gobject.type_register(readline) return readline -def ConsoleType(t=Gtk.TextView): +def ConsoleType(t=gtk.TextView): class console_type(t, _Console): __gsignals__ = { - 'command' : (GObject.SignalFlags.RUN_LAST, None, (object,)), + 'command' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (object,)), 'key-press-event' : 'override' } def __init__(self, *args, **kwargs): - GObject.GObject.__init__(self) + if gtk.pygtk_version[1] < 8: + gobject.GObject.__init__(self) + else: + t.__init__(self) _Console.__init__(self, *args, **kwargs) def do_command(self, code): @@ -615,7 +634,9 @@ def do_command(self, code): def do_key_press_event(self, event): return _Console.do_key_press_event(self, event, t) - GObject.type_register(console_type) + if gtk.pygtk_version[1] < 8: + gobject.type_register(console_type) + return console_type ReadLine = ReadLineType() @@ -629,19 +650,19 @@ def _create_widget(start_script): return console def _make_window(start_script="import geany\n"): - window = Gtk.Window() + window = gtk.Window() window.set_title("Python Console") - swin = Gtk.ScrolledWindow() - swin.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.ALWAYS) + swin = gtk.ScrolledWindow() + swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS) window.add(swin) console = _create_widget(start_script) swin.add(console) window.set_default_size(500, 400) window.show_all() - if not Gtk.main_level(): - window.connect("destroy", Gtk.main_quit) - Gtk.main() + if not gtk.main_level(): + window.connect("destroy", gtk.main_quit) + gtk.main() return console diff --git a/geany/loader.py b/geany/loader.py index 15533b8..ae4e504 100644 --- a/geany/loader.py +++ b/geany/loader.py @@ -11,13 +11,7 @@ class PluginLoader(object): plugins = {} def __init__(self, plugin_dirs): - self.plugin_dirs = plugin_dirs - - #self.available_plugins = [] - #for plugin in self.iter_plugin_info(): - #self.available_plugins.append(plugin) - self.restore_loaded_plugins() diff --git a/geany/manager.py b/geany/manager.py index 59c2e87..7cd2680 100644 --- a/geany/manager.py +++ b/geany/manager.py @@ -1,74 +1,89 @@ -from gi.repository import GObject, GLib, Gtk +try: + from gi import pygtkcompat +except ImportError: + pygtkcompat = None + +if pygtkcompat is not None: + pygtkcompat.enable() + pygtkcompat.enable_gtk(version='3.0') + +import gtk +import gobject +import glib from htmlentitydefs import name2codepoint from loader import PluginLoader -class PluginManager(Gtk.Dialog): + +class PluginManager(gtk.Dialog): + def __init__(self, plugin_dirs=[]): super(PluginManager, self).__init__(title="Plugin Manager") self.loader = PluginLoader(plugin_dirs) + self.set_default_size(400, 450) - icon = self.render_icon(Gtk.STOCK_PREFERENCES, Gtk.IconSize.MENU) + icon = self.render_icon(gtk.STOCK_PREFERENCES, gtk.ICON_SIZE_MENU) self.set_icon(icon) - + self.connect("response", lambda w,d: self.hide()) - - vbox = Gtk.VBox(False, 12) + + vbox = gtk.VBox(False, 12) vbox.set_border_width(12) - - lbl = Gtk.Label("Choose plugins to load or unload:") + + lbl = gtk.Label("Choose plugins to load or unload:") lbl.set_alignment(0.0, 0.5) vbox.pack_start(lbl, False, False, 0) - - sw = Gtk.ScrolledWindow() + + sw = gtk.ScrolledWindow() sw.set_hexpand(True) sw.set_vexpand(True) - sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) - sw.set_shadow_type(Gtk.ShadowType.ETCHED_IN) + sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + sw.set_shadow_type(gtk.SHADOW_ETCHED_IN) vbox.pack_start(sw, True, True, 0) - - self.treeview = Gtk.TreeView() + + self.treeview = gtk.TreeView() sw.add(self.treeview) - + vbox.show_all() - + self.get_content_area().add(vbox) - + action_area = self.get_action_area() action_area.set_spacing(0) action_area.set_homogeneous(False) - - btn = Gtk.Button(stock=Gtk.STOCK_CLOSE) + + btn = gtk.Button(stock=gtk.STOCK_CLOSE) btn.set_border_width(6) - btn.connect("clicked", lambda x: self.response(Gtk.ResponseType.CLOSE)) + btn.connect("clicked", lambda x: self.response(gtk.RESPONSE_CLOSE)) action_area.pack_start(btn, False, True, 0) btn.show() - - self.btn_help = Gtk.Button(stock=Gtk.STOCK_HELP) + + self.btn_help = gtk.Button(stock=gtk.STOCK_HELP) self.btn_help.set_border_width(6) self.btn_help.set_no_show_all(True) action_area.pack_start(self.btn_help, False, True, 0) action_area.set_child_secondary(self.btn_help, True) - - self.btn_prefs = Gtk.Button(stock=Gtk.STOCK_PREFERENCES) + + self.btn_prefs = gtk.Button(stock=gtk.STOCK_PREFERENCES) self.btn_prefs.set_border_width(6) self.btn_prefs.set_no_show_all(True) action_area.pack_start(self.btn_prefs, False, True, 0) action_area.set_child_secondary(self.btn_prefs, True) - + action_area.show() - + self.load_plugins_list() + def on_help_button_clicked(self, button, treeview, model): path = treeview.get_cursor()[0] iter = model.get_iter(path) filename = model.get_value(iter, 2) - for plugin in self.loader.iter_plugin_info(): + for plugin in self.loader.available_plugins: if plugin.filename == filename: plugin.cls.show_help() break - else: - print("Plugin does not support help function") + else: + print("Plugin does not support help function") def on_preferences_button_clicked(self, button, treeview, model): @@ -90,74 +105,76 @@ def deactivate_plugin(self, filename): def load_plugins_list(self): - liststore = Gtk.ListStore(GObject.TYPE_BOOLEAN, str, str) + liststore = gtk.ListStore(gobject.TYPE_BOOLEAN, str, str) self.btn_help.connect("clicked", - self.on_help_button_clicked, self.treeview, liststore) + self.on_help_button_clicked, self.treeview, liststore) self.btn_prefs.connect("clicked", - self.on_preferences_button_clicked, self.treeview, liststore) + self.on_preferences_button_clicked, self.treeview, liststore) self.treeview.set_model(liststore) self.treeview.set_headers_visible(False) self.treeview.set_grid_lines(True) - check_renderer = Gtk.CellRendererToggle() + check_renderer = gtk.CellRendererToggle() check_renderer.set_radio(False) check_renderer.connect('toggled', self.on_plugin_load_toggled, liststore) - text_renderer = Gtk.CellRendererText() - check_column = Gtk.TreeViewColumn(None, check_renderer, active=0) - text_column = Gtk.TreeViewColumn(None, text_renderer, markup=1) - + text_renderer = gtk.CellRendererText() + + check_column = gtk.TreeViewColumn(None, check_renderer, active=0) + text_column = gtk.TreeViewColumn(None, text_renderer, markup=1) + self.treeview.append_column(check_column) self.treeview.append_column(text_column) - + self.treeview.connect('row-activated', - self.on_row_activated, check_renderer, liststore) + self.on_row_activated, check_renderer, liststore) self.treeview.connect('cursor-changed', - self.on_selected_plugin_changed, liststore) - + self.on_selected_plugin_changed, liststore) + self.load_sorted_plugins_info(liststore) def load_sorted_plugins_info(self, list_store): - #plugin_info_list = list(self.loader.iter_plugin_info()) + + plugin_info_list = list(self.loader.iter_plugin_info()) #plugin_info_list.sort(key=lambda pi: pi[1]) - for plugin_info in self.loader.iter_plugin_info(): - + for plugin_info in plugin_info_list: + lbl = str('%s %s\n%s\n' + - 'Author: %s\n' + - 'Filename: %s') % ( - GLib.markup_escape_text(plugin_info.name), - GLib.markup_escape_text(plugin_info.version), - GLib.markup_escape_text(plugin_info.description), - GLib.markup_escape_text(plugin_info.author), - GLib.markup_escape_text(plugin_info.filename)) - + 'Author: %s\n' + + 'Filename: %s') % ( + glib.markup_escape_text(plugin_info.name), + glib.markup_escape_text(plugin_info.version), + glib.markup_escape_text(plugin_info.description), + glib.markup_escape_text(plugin_info.author), + glib.markup_escape_text(plugin_info.filename)) + loaded = plugin_info.filename in self.loader.plugins - + list_store.append([loaded, lbl, plugin_info.filename]) - + def on_selected_plugin_changed(self, treeview, model): - + path = treeview.get_cursor()[0] iter = model.get_iter(path) filename = model.get_value(iter, 2) active = model.get_value(iter, 0) - + if self.loader.plugin_has_configure(filename): self.btn_prefs.set_visible(True) else: self.btn_prefs.set_visible(False) - + if self.loader.plugin_has_help(filename): self.btn_help.set_visible(True) else: self.btn_help.set_visible(False) - - + + def on_plugin_load_toggled(self, cell, path, model): active = not cell.get_active() iter = model.get_iter(path) @@ -166,7 +183,7 @@ def on_plugin_load_toggled(self, cell, path, model): self.activate_plugin(model.get_value(iter, 2)) else: self.deactivate_plugin(model.get_value(iter, 2)) - - + + def on_row_activated(self, tvw, path, view_col, cell, model): self.on_plugin_load_toggled(cell, path, model) \ No newline at end of file diff --git a/geany/signalmanager.py b/geany/signalmanager.py index 3e0d69e..16d7910 100644 --- a/geany/signalmanager.py +++ b/geany/signalmanager.py @@ -3,54 +3,62 @@ all signals on. The signals are emitted from the C code in signalmanager.c, where the Geany types get wrapped in PyObject types. """ -from gi.repository import GObject +try: + from gi import pygtkcompat +except ImportError: + pygtkcompat = None +if pygtkcompat is not None: + pygtkcompat.enable() + pygtkcompat.enable_gtk(version='3.0') +import gobject -class SignalManager(GObject.GObject): + +class SignalManager(gobject.GObject): """ Manages callback functions for events emitted by Geany's internal GObject. """ __gsignals__ = { - 'build-start': (GObject.SignalFlags.RUN_LAST, None, + 'build-start': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()), - 'document-activate': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'document-before-save': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'document-close': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'document-filetype-set': (GObject.SignalFlags.RUN_LAST, None, - (object, object)), - 'document-new': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'document-open': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'document-reload': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'document-save': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'editor-notify': (GObject.SignalFlags.RUN_LAST, GObject.TYPE_BOOLEAN, - (object, object)), - 'geany-startup-complete': (GObject.SignalFlags.RUN_LAST, None, + 'document-activate': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'document-before-save': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'document-close': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'document-filetype-set': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT)), + 'document-new': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'document-open': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'document-reload': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'document-save': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'editor-notify': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_BOOLEAN, + (gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT)), + 'geany-startup-complete': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()), - 'project-close': (GObject.SignalFlags.RUN_LAST, None, + 'project-close': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()), - 'project-dialog-confirmed': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'project-dialog-open': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'project-dialog-close': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'project-open': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'project-save': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'update-editor-menu': (GObject.SignalFlags.RUN_LAST, None, - (GObject.TYPE_STRING, GObject.TYPE_INT, - object)), + 'project-dialog-confirmed': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'project-dialog-open': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'project-dialog-close': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'project-open': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'project-save': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'update-editor-menu': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_STRING, gobject.TYPE_INT, + gobject.TYPE_PYOBJECT)), } # __gsignals__ def __init__(self): super(SignalManager, self).__init__() -GObject.type_register(SignalManager) \ No newline at end of file +gobject.type_register(SignalManager) \ No newline at end of file diff --git a/plugins/console.py b/plugins/console.py index 6665495..69a46cf 100644 --- a/plugins/console.py +++ b/plugins/console.py @@ -1,12 +1,24 @@ +try: + from gi import pygtkcompat +except ImportError: + pygtkcompat = None + +if pygtkcompat is not None: + pygtkcompat.enable() + pygtkcompat.enable_gtk(version='3.0') + import os from ConfigParser import SafeConfigParser import geany import geany.console -from gi.repository import GObject, Gtk, Gdk, Pango +import gobject +import gtk +import gtk.gdk as gdk +import pango -WIDGET_STATES = [ Gtk.StateType.NORMAL, Gtk.StateType.ACTIVE, Gtk.StateType.PRELIGHT, - Gtk.StateType.SELECTED, Gtk.StateType.INSENSITIVE ] +WIDGET_STATES = [ gtk.STATE_NORMAL, gtk.STATE_ACTIVE, gtk.STATE_PRELIGHT, + gtk.STATE_SELECTED, gtk.STATE_INSENSITIVE ] class ConsolePlugin(geany.Plugin): @@ -45,7 +57,7 @@ def load_config(self): def save_config(self): - GObject.idle_add(self.on_save_config_timeout) + gobject.idle_add(self.on_save_config_timeout) def on_save_config_timeout(self, data=None): @@ -59,8 +71,8 @@ def install_console(self): self.banner = self.banner self.use_rl_completer = self.use_rl_completer - self.swin = Gtk.ScrolledWindow() - self.swin.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.ALWAYS) + self.swin = gtk.ScrolledWindow() + self.swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS) self.console = geany.console.Console(banner = self.banner, use_rlcompleter = self.use_rl_completer) self.console.connect("populate-popup", self.on_console_populate_popup) @@ -72,7 +84,7 @@ def install_console(self): self.swin.add(self.console) geany.main_widgets.message_window_notebook.append_page(self.swin, - Gtk.Label("Python")) + gtk.Label("Python")) self.swin.show_all() self.save_config() @@ -88,7 +100,7 @@ def _get_font(self): return self._font def _set_font(self, font): self._font = font - font_desc = Pango.FontDescription(font) + font_desc = pango.FontDescription(font) self.console.modify_font(font_desc) if not self.cfg.has_section('appearances'): self.cfg.add_section('appearances') @@ -104,7 +116,7 @@ def _get_bg(self): return self._bg def _set_bg(self, bg): self._bg = bg - color = Gdk.color_parse(self._bg) + color = gdk.color_parse(self._bg) for state in WIDGET_STATES: self.console.modify_bg(state, color) self.console.modify_base(state, color) @@ -122,7 +134,7 @@ def _get_fg(self): return self._fg def _set_fg(self, fg): self._fg = fg - color = Gdk.color_parse(self._fg) + color = gdk.color_parse(self._fg) for state in WIDGET_STATES: self.console.modify_fg(state, color) self.console.modify_text(state, color) @@ -163,10 +175,10 @@ def _set_use_rl_completer(self, use_rl_completer): def on_console_populate_popup(self, textview, menu, data=None): - item = Gtk.SeparatorMenuItem() + item = gtk.SeparatorMenuItem() item.show() menu.append(item) - item = Gtk.ImageMenuItem(stock_id=Gtk.STOCK_PREFERENCES) + item = gtk.ImageMenuItem(stock_id=gtk.STOCK_PREFERENCES) item.show() menu.append(item) item.connect("activate", lambda w,d=None: self.show_configure()) @@ -189,114 +201,115 @@ def on_bg_color_changed(self, clr_btn, data=None): def show_configure(self): - dialog = Gtk.Dialog("Configure Python Console", + dialog = gtk.Dialog("Configure Python Console", geany.main_widgets.window, - Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, - (Gtk.STOCK_CLOSE, Gtk.ResponseType.ACCEPT)) + gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, + (gtk.STOCK_CLOSE, gtk.RESPONSE_ACCEPT)) + + #dialog.set_has_separator(True) + content_area = dialog.get_content_area() content_area.set_border_width(6) - vbox = Gtk.VBox(spacing=6) + vbox = gtk.VBox(spacing=6) vbox.set_border_width(6) - lbl = Gtk.Label() + lbl = gtk.Label() lbl.set_use_markup(True) lbl.set_markup("General") - fra_general = Gtk.Frame() - fra_general.set_shadow_type(Gtk.ShadowType.NONE) + fra_general = gtk.Frame() + fra_general.set_shadow_type(gtk.SHADOW_NONE) fra_general.set_label_widget(lbl) - al_general = Gtk.Alignment() - al_general.set(0.0, 0.0, 1.0, 1.0) + al_general = gtk.Alignment(0.0, 0.0, 1.0, 1.0) al_general.set_padding(0, 0, 12, 0) fra_general.add(al_general) - tbl = Gtk.Table(3, 2, False) + tbl = gtk.Table(3, 2, False) tbl.set_row_spacings(6) tbl.set_col_spacings(6) tbl.set_border_width(6) - lbl = Gtk.Label("Banner:") + lbl = gtk.Label("Banner:") lbl.set_alignment(0.0, 0.0) - tvw = Gtk.TextView() + tvw = gtk.TextView() tvw.get_buffer().set_text(self.banner) tvw.get_buffer().connect("changed", self.on_banner_changed) - swin = Gtk.ScrolledWindow() - swin.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) - swin.set_shadow_type(Gtk.ShadowType.ETCHED_IN) + swin = gtk.ScrolledWindow() + swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + swin.set_shadow_type(gtk.SHADOW_ETCHED_IN) swin.add(tvw) - tbl.attach(lbl, 0, 1, 0, 1, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) - tbl.attach(swin, 1, 2, 0, 1, Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, 0, 0) + tbl.attach(lbl, 0, 1, 0, 1, gtk.FILL, gtk.FILL, 0, 0) + tbl.attach(swin, 1, 2, 0, 1, gtk.EXPAND | gtk.FILL, gtk.EXPAND | gtk.FILL, 0, 0) - lbl = Gtk.Label("") + lbl = gtk.Label("") lbl.set_alignment(0.0, 0.5) - check = Gtk.CheckButton("Use Readline") + check = gtk.CheckButton("Use Readline") if self.use_rl_completer: check.set_active(True) check.connect("toggled", self.on_use_rl_completer_toggled) - tbl.attach(lbl, 0, 1, 1, 2, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) - tbl.attach(check, 1, 2, 1, 2, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) + tbl.attach(lbl, 0, 1, 1, 2, gtk.FILL, gtk.FILL, 0, 0) + tbl.attach(check, 1, 2, 1, 2, gtk.FILL, gtk.FILL, 0, 0) - lbl = Gtk.Label("") + lbl = gtk.Label("") lbl.set_alignment(0.0, 0.5) lbl.set_use_markup(True) lbl.set_markup('' + 'Note: General settings will be applied when console is reloaded.' + '') - tbl.attach(lbl, 0, 2, 2, 3, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) + tbl.attach(lbl, 0, 2, 2, 3, gtk.FILL, gtk.FILL, 0, 0) al_general.add(tbl) - lbl = Gtk.Label() + lbl = gtk.Label() lbl.set_use_markup(True) lbl.set_markup("Appearances") - fra_appearances = Gtk.Frame() - fra_appearances.set_shadow_type(Gtk.ShadowType.NONE) + fra_appearances = gtk.Frame() + fra_appearances.set_shadow_type(gtk.SHADOW_NONE) fra_appearances.set_label_widget(lbl) - al_appearances = Gtk.Alignment() - al_appearances.set(0.0, 0.0, 1.0, 1.0) + al_appearances = gtk.Alignment(0.0, 0.0, 1.0, 1.0) al_appearances.set_padding(0, 0, 12, 0) fra_appearances.add(al_appearances) - tbl = Gtk.Table(3, 2, False) + tbl = gtk.Table(3, 2, False) tbl.set_row_spacings(6) tbl.set_col_spacings(6) tbl.set_border_width(6) - lbl = Gtk.Label("Font:") + lbl = gtk.Label("Font:") lbl.set_alignment(0.0, 0.5) - btn = Gtk.FontButton(self.font) + btn = gtk.FontButton(self.font) btn.connect("font-set", self.on_font_changed) - tbl.attach(lbl, 0, 1, 0, 1, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) - tbl.attach(btn, 1, 2, 0, 1, Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, Gtk.AttachOptions.FILL, 0, 0) + tbl.attach(lbl, 0, 1, 0, 1, gtk.FILL, gtk.FILL, 0, 0) + tbl.attach(btn, 1, 2, 0, 1, gtk.FILL | gtk.EXPAND, gtk.FILL, 0, 0) - lbl = Gtk.Label("FG Color:") + lbl = gtk.Label("FG Color:") lbl.set_alignment(0.0, 0.5) - btn = Gtk.ColorButton(Gdk.color_parse(self.fg)) + btn = gtk.ColorButton(gdk.color_parse(self.fg)) btn.connect("color-set", self.on_fg_color_changed) - tbl.attach(lbl, 0, 1, 1, 2, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) - tbl.attach(btn, 1, 2, 1, 2, Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, Gtk.AttachOptions.FILL, 0, 0) + tbl.attach(lbl, 0, 1, 1, 2, gtk.FILL, gtk.FILL, 0, 0) + tbl.attach(btn, 1, 2, 1, 2, gtk.FILL | gtk.EXPAND, gtk.FILL, 0, 0) - lbl = Gtk.Label("BG Color:") + lbl = gtk.Label("BG Color:") lbl.set_alignment(0.0, 0.5) - btn = Gtk.ColorButton(Gdk.color_parse(self.bg)) + btn = gtk.ColorButton(gdk.color_parse(self.bg)) btn.connect("color-set", self.on_bg_color_changed) - tbl.attach(lbl, 0, 1, 2, 3, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) - tbl.attach(btn, 1, 2, 2, 3, Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, Gtk.AttachOptions.FILL, 0, 0) + tbl.attach(lbl, 0, 1, 2, 3, gtk.FILL, gtk.FILL, 0, 0) + tbl.attach(btn, 1, 2, 2, 3, gtk.FILL | gtk.EXPAND, gtk.FILL, 0, 0) al_appearances.add(tbl) diff --git a/plugins/hello.py b/plugins/hello.py index c9e2859..d6153b8 100644 --- a/plugins/hello.py +++ b/plugins/hello.py @@ -1,4 +1,12 @@ -from gi.repository import Gtk +try: + from gi import pygtkcompat +except ImportError: + pygtkcompat = None + +if pygtkcompat is not None: + pygtkcompat.enable() + pygtkcompat.enable_gtk(version='3.0') +import gtk import geany class HelloWorld(geany.Plugin): @@ -9,7 +17,7 @@ class HelloWorld(geany.Plugin): __plugin_author__ = "John Doe " def __init__(self): - self.menu_item = Gtk.MenuItem("Hello World") + self.menu_item = gtk.MenuItem("Hello World") self.menu_item.show() geany.main_widgets.tools_menu.append(self.menu_item) self.menu_item.connect("activate", self.on_hello_item_clicked) From 3e8b0b82fe6c753b491367985823946d155fbc00 Mon Sep 17 00:00:00 2001 From: Sagar Chalise Date: Sat, 20 Jul 2013 22:34:12 +0545 Subject: [PATCH 13/28] GeanyPy Keybinding naming --- src/geanypy-bindings.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/geanypy-bindings.c b/src/geanypy-bindings.c index ffe1c83..5506faf 100644 --- a/src/geanypy-bindings.c +++ b/src/geanypy-bindings.c @@ -88,7 +88,7 @@ PyObject * kb_manager_init(PyObject *module) if (manager.initialized) Py_RETURN_TRUE; - manager.kg_name = name_to_key("GeanyPy" /* FIXME: use plugin name */); + manager.kg_name = name_to_key(geany_plugin->info->name /* FIXME: use plugin name */); manager.group = plugin_set_key_group(geany_plugin, manager.kg_name, KB_MAX, (GeanyKeyGroupCallback) on_keybinding_activate); From 218062e1af3a1b63b5e263919c95c4e8d4b32b2e Mon Sep 17 00:00:00 2001 From: Sagar Chalise Date: Mon, 29 Jul 2013 22:28:17 -0700 Subject: [PATCH 14/28] Update console.py --- geany/console.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/geany/console.py b/geany/console.py index d3776c7..7f13851 100644 --- a/geany/console.py +++ b/geany/console.py @@ -351,7 +351,7 @@ def __delete_at_cursor(self, howmany): self.__delete(iter, end) def __get_width(self): - if not (gtk.get_realized()): + if not (self.get_realized()): return 80 layout = pango.Layout(self.get_pango_context()) letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" @@ -670,4 +670,4 @@ def _make_window(start_script="import geany\n"): import sys import os sys.path.insert(0, os.getcwd()) - _make_window(sys.argv[1:] and '\n'.join(sys.argv[1:]) + '\n' or None) \ No newline at end of file + _make_window(sys.argv[1:] and '\n'.join(sys.argv[1:]) + '\n' or None) From e641dbd9983cf9cc1933e52a50243748f0e342d6 Mon Sep 17 00:00:00 2001 From: Sagar Chalise Date: Wed, 31 Jul 2013 06:53:16 +0545 Subject: [PATCH 15/28] Added parent to plugin manager as well as some cleanup --- geany/manager.py | 4 ++-- src/geanypy-plugin.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/geany/manager.py b/geany/manager.py index 7cd2680..43de031 100644 --- a/geany/manager.py +++ b/geany/manager.py @@ -16,8 +16,8 @@ class PluginManager(gtk.Dialog): - def __init__(self, plugin_dirs=[]): - super(PluginManager, self).__init__(title="Plugin Manager") + def __init__(self, parent=None, plugin_dirs=[]): + super(PluginManager, self).__init__(title="Plugin Manager", parent=parent) self.loader = PluginLoader(plugin_dirs) self.set_default_size(400, 450) diff --git a/src/geanypy-plugin.c b/src/geanypy-plugin.c index 8427bca..7b5188d 100644 --- a/src/geanypy-plugin.c +++ b/src/geanypy-plugin.c @@ -195,11 +195,11 @@ GeanyPy_init_manager(const gchar *dir) if (sys_plugin_dir) { g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "System plugins: %s", sys_plugin_dir); - args = Py_BuildValue("([s, s])", sys_plugin_dir, dir); + args = Py_BuildValue("(O, [s, s])", pygobject_new(G_OBJECT(geany_data->main_widgets->window)), sys_plugin_dir, dir); g_free(sys_plugin_dir); } else - args = Py_BuildValue("([s])", dir); + args = Py_BuildValue("(O, [s])", pygobject_new(G_OBJECT(geany_data->main_widgets->window)), dir); manager = PyObject_CallObject(man, args); if (PyErr_Occurred()) From b79ca903f898efebfbeeca784faa1ef25779fe19 Mon Sep 17 00:00:00 2001 From: Sagar Chalise Date: Wed, 31 Jul 2013 23:26:08 +0545 Subject: [PATCH 16/28] added flags --- geany/manager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/geany/manager.py b/geany/manager.py index 43de031..0f2e4e9 100644 --- a/geany/manager.py +++ b/geany/manager.py @@ -17,7 +17,7 @@ class PluginManager(gtk.Dialog): def __init__(self, parent=None, plugin_dirs=[]): - super(PluginManager, self).__init__(title="Plugin Manager", parent=parent) + super(PluginManager, self).__init__(title="Plugin Manager", parent=parent, flags=gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_MODAL) self.loader = PluginLoader(plugin_dirs) self.set_default_size(400, 450) @@ -186,4 +186,4 @@ def on_plugin_load_toggled(self, cell, path, model): def on_row_activated(self, tvw, path, view_col, cell, model): - self.on_plugin_load_toggled(cell, path, model) \ No newline at end of file + self.on_plugin_load_toggled(cell, path, model) From 50626e238a4eda04f1194339759e4639b46938a0 Mon Sep 17 00:00:00 2001 From: Sagar Chalise Date: Thu, 1 Aug 2013 10:50:21 +0545 Subject: [PATCH 17/28] Build compatible with pygtk as well as pygobject --- configure.ac | 2 +- geany/console.py | 4 ++-- geany/manager.py | 7 ++++--- m4/gtk.m4 | 26 ++++++++++++++++++++++++++ src/Makefile.am | 9 +++++++++ src/geanypy-uiutils.c | 4 ++-- 6 files changed, 44 insertions(+), 8 deletions(-) create mode 100644 m4/gtk.m4 diff --git a/configure.ac b/configure.ac index 2b18609..f9a798e 100644 --- a/configure.ac +++ b/configure.ac @@ -19,7 +19,7 @@ AC_PROG_SED # Check for headers, libraries and packages AC_CHECK_HEADERS([stdio.h string.h dlfcn.h]) PKG_CHECK_MODULES([GEANY], [geany >= 0.21]) -PKG_CHECK_MODULES([PYGOBJECT], [pygobject-3.0]) +GP_CHECK_GTK3([PKG_CHECK_MODULES([PYGOBJECT], [pygobject-3.0])], [PKG_CHECK_MODULES([PYGTK], [pygtk-2.0])]) AX_PYTHON_DEVEL([>= '2.6']) AX_PYTHON_LIBRARY(,[AC_MSG_ERROR([Cannot determine location of the Python DSO])]) AC_SUBST([PYTHON]) diff --git a/geany/console.py b/geany/console.py index 7f13851..87e2c4a 100644 --- a/geany/console.py +++ b/geany/console.py @@ -294,7 +294,7 @@ def do_key_press_event(self, event, parent_type): handled = False if not handled: - return parent_type.do_key_press_event(self, event.key) + return parent_type.do_key_press_event(self, event.key if hasattr(event, "key") else event) else: return True @@ -670,4 +670,4 @@ def _make_window(start_script="import geany\n"): import sys import os sys.path.insert(0, os.getcwd()) - _make_window(sys.argv[1:] and '\n'.join(sys.argv[1:]) + '\n' or None) + _make_window(sys.argv[1:] and '\n'.join(sys.argv[1:]) + '\n' or None) \ No newline at end of file diff --git a/geany/manager.py b/geany/manager.py index 0f2e4e9..3e05e79 100644 --- a/geany/manager.py +++ b/geany/manager.py @@ -34,8 +34,9 @@ def __init__(self, parent=None, plugin_dirs=[]): vbox.pack_start(lbl, False, False, 0) sw = gtk.ScrolledWindow() - sw.set_hexpand(True) - sw.set_vexpand(True) + if hasattr(sw, 'set_hexpand'): + sw.set_hexpand(True) + sw.set_vexpand(True) sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) sw.set_shadow_type(gtk.SHADOW_ETCHED_IN) vbox.pack_start(sw, True, True, 0) @@ -186,4 +187,4 @@ def on_plugin_load_toggled(self, cell, path, model): def on_row_activated(self, tvw, path, view_col, cell, model): - self.on_plugin_load_toggled(cell, path, model) + self.on_plugin_load_toggled(cell, path, model) \ No newline at end of file diff --git a/m4/gtk.m4 b/m4/gtk.m4 new file mode 100644 index 0000000..1958be1 --- /dev/null +++ b/m4/gtk.m4 @@ -0,0 +1,26 @@ +dnl checks for the GTK version to build against (2 or 3) +dnl defines GP_GTK_PACKAGE (e.g. "gtk+-2.0"), GP_GTK_VERSION (e.g. "2.24") and +dnl GP_GTK_VERSION_MAJOR (e.g. "2"); and defines the GP_GTK3 AM conditional +AC_DEFUN([GP_CHECK_GTK_VERSION], +[ + AC_REQUIRE([AC_PROG_AWK]) + AC_REQUIRE([PKG_PROG_PKG_CONFIG]) + + _gtk_req=$(${PKG_CONFIG} --print-requires geany | ${AWK} '/^gtk\+-/{print}') + GP_GTK_PACKAGE=$(echo ${_gtk_req} | ${AWK} '{print $[]1}') + GP_GTK_VERSION=$(echo ${_gtk_req} | ${AWK} '{print $[]3}') + GP_GTK_VERSION_MAJOR=$(echo ${GP_GTK_VERSION} | cut -d. -f1) + AC_SUBST([GP_GTK_PACKAGE]) + AC_SUBST([GP_GTK_VERSION]) + AC_SUBST([GP_GTK_VERSION_MAJOR]) + + AM_CONDITIONAL([GP_GTK3], [test "x$GP_GTK_VERSION_MAJOR" = x3]) + +]) + +dnl executes $1 if GTK3 is used, and $2 otherwise +AC_DEFUN([GP_CHECK_GTK3], +[ + AC_REQUIRE([GP_CHECK_GTK_VERSION]) + AS_IF([test ${GP_GTK_VERSION_MAJOR} = 3],[$1],[$2]) +]) \ No newline at end of file diff --git a/src/Makefile.am b/src/Makefile.am index 5e3247d..812af48 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,12 +2,21 @@ geanyplugin_LTLIBRARIES = geanypy.la geanyplugindir = $(libdir)/geany geanypy_la_LDFLAGS = -module -avoid-version -Wl,--export-dynamic +if GP_GTK3 geanypy_la_CPPFLAGS = @GEANY_CFLAGS@ @PYGOBJECT_CFLAGS@ @PYTHON_CPPFLAGS@ \ -DGEANYPY_PYTHON_DIR="\"$(libdir)/geany/geanypy\"" \ -DGEANYPY_PLUGIN_DIR="\"$(datadir)/geany/geanypy/plugins\"" \ -UHAVE_CONFIG_H geanypy_la_LIBADD = @GEANY_LIBS@ @PYGOBJECT_LIBS@ @PYTHON_LDFLAGS@ \ @PYTHON_EXTRA_LIBS@ @PYTHON_EXTRA_LDFLAGS@ +else +geanypy_la_CPPFLAGS = @GEANY_CFLAGS@ @PYGTK_CFLAGS@ @PYTHON_CPPFLAGS@ \ + -DGEANYPY_PYTHON_DIR="\"$(libdir)/geany/geanypy\"" \ + -DGEANYPY_PLUGIN_DIR="\"$(datadir)/geany/geanypy/plugins\"" \ + -UHAVE_CONFIG_H +geanypy_la_LIBADD = @GEANY_LIBS@ @PYGTK_LIBS@ @PYTHON_LDFLAGS@ \ + @PYTHON_EXTRA_LIBS@ @PYTHON_EXTRA_LDFLAGS@ +endif geanypy_la_SOURCES = geanypy-app.c \ geanypy-bindings.c \ geanypy-dialogs.c \ diff --git a/src/geanypy-uiutils.c b/src/geanypy-uiutils.c index d3f06aa..99f2e2e 100644 --- a/src/geanypy-uiutils.c +++ b/src/geanypy-uiutils.c @@ -423,8 +423,8 @@ PyMODINIT_FUNC initui_utils(void) pygobject_init(-1, -1, -1); m = PyImport_ImportModule("gi._gobject"); #else - init_pygobject() - init_pygtk() + init_pygobject(); + init_pygtk(); m = PyImport_ImportModule("gobject"); #endif if (m) From 34bdb6fa64e1bd182a8ea8704f2257dc7673a235 Mon Sep 17 00:00:00 2001 From: Sagar Chalise Date: Thu, 1 Aug 2013 12:10:49 +0545 Subject: [PATCH 18/28] Color in colorbutton for console preference --- plugins/console.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/plugins/console.py b/plugins/console.py index 69a46cf..d6bbfaf 100644 --- a/plugins/console.py +++ b/plugins/console.py @@ -295,8 +295,7 @@ def show_configure(self): lbl = gtk.Label("FG Color:") lbl.set_alignment(0.0, 0.5) - - btn = gtk.ColorButton(gdk.color_parse(self.fg)) + btn = gtk.ColorButton(color=gdk.color_parse(self.fg)) btn.connect("color-set", self.on_fg_color_changed) tbl.attach(lbl, 0, 1, 1, 2, gtk.FILL, gtk.FILL, 0, 0) @@ -305,7 +304,7 @@ def show_configure(self): lbl = gtk.Label("BG Color:") lbl.set_alignment(0.0, 0.5) - btn = gtk.ColorButton(gdk.color_parse(self.bg)) + btn = gtk.ColorButton(color=gdk.color_parse(self.bg)) btn.connect("color-set", self.on_bg_color_changed) tbl.attach(lbl, 0, 1, 2, 3, gtk.FILL, gtk.FILL, 0, 0) From 4c29b7859fa2740bbfcb6397544cb04256865a9d Mon Sep 17 00:00:00 2001 From: Sagar Chalise Date: Sun, 4 Aug 2013 11:31:44 +0545 Subject: [PATCH 19/28] Pure gtk3 --- configure.ac | 2 +- geany/console.py | 87 ++++++++++-------------- geany/loader.py | 6 ++ geany/manager.py | 146 ++++++++++++++++++----------------------- geany/signalmanager.py | 82 +++++++++++------------ plugins/console.py | 122 ++++++++++++++++------------------ plugins/hello.py | 12 +--- src/Makefile.am | 9 --- 8 files changed, 198 insertions(+), 268 deletions(-) diff --git a/configure.ac b/configure.ac index f9a798e..2b18609 100644 --- a/configure.ac +++ b/configure.ac @@ -19,7 +19,7 @@ AC_PROG_SED # Check for headers, libraries and packages AC_CHECK_HEADERS([stdio.h string.h dlfcn.h]) PKG_CHECK_MODULES([GEANY], [geany >= 0.21]) -GP_CHECK_GTK3([PKG_CHECK_MODULES([PYGOBJECT], [pygobject-3.0])], [PKG_CHECK_MODULES([PYGTK], [pygtk-2.0])]) +PKG_CHECK_MODULES([PYGOBJECT], [pygobject-3.0]) AX_PYTHON_DEVEL([>= '2.6']) AX_PYTHON_LIBRARY(,[AC_MSG_ERROR([Cannot determine location of the Python DSO])]) AC_SUBST([PYTHON]) diff --git a/geany/console.py b/geany/console.py index 87e2c4a..91166ca 100644 --- a/geany/console.py +++ b/geany/console.py @@ -28,29 +28,16 @@ # To modify output appearance, set attributes of console.stdout_tag and # console.stderr_tag. # -# Console may subclass a type other than gtk.TextView, to allow syntax highlighting and stuff, +# Console may subclass a type other than Gtk.TextView, to allow syntax highlighting and stuff, # e.g.: # console_type = pyconsole.ConsoleType(moo.TextView) -# console = console_type(use_rlcompleter=False, start_script="import moo\nimport gtk\n") +# console = console_type(use_rlcompleter=False, start_script="import moo\nimport Gtk\n") # # This widget is not a replacement for real terminal with python running # inside: GtkTextView is not a terminal. # The use case is: you have a python program, you create this widget, # and inspect your program interiors. -try: - from gi import pygtkcompat -except ImportError: - pygtkcompat = None - -if pygtkcompat is not None: - pygtkcompat.enable() - pygtkcompat.enable_gtk(version='3.0') - -import gtk -import gtk.gdk as gdk -import gobject -import pango -import gtk.keysyms as _keys +from gi.repository import GObject, Gtk, Gdk, Pango import code import sys import keyword @@ -117,8 +104,8 @@ def get(self, dir, text): def __init__(self): object.__init__(self) - self.set_wrap_mode(gtk.WRAP_CHAR) - self.modify_font(pango.FontDescription("Monospace")) + self.set_wrap_mode(Gtk.WrapMode.CHAR) + self.modify_font(Pango.FontDescription("Monospace")) self.buffer = self.get_buffer() self.buffer.connect("insert-text", self.on_buf_insert) @@ -250,27 +237,27 @@ def do_key_press_event(self, event, parent_type): self.tab_pressed = 0 handled = True - state = event.state & (gdk.SHIFT_MASK | - gdk.CONTROL_MASK | - gdk.MOD1_MASK) + state = event.state & (Gdk.ModifierType.SHIFT_MASK | + Gdk.ModifierType.CONTROL_MASK | + Gdk.ModifierType.MOD1_MASK) keyval = event.keyval if not state: - if keyval == _keys.Return: + if keyval == Gdk.KEY_Return: self._commit() - elif keyval == _keys.Up: + elif keyval == Gdk.KEY_Up: self.__history(-1) - elif keyval == _keys.Down: + elif keyval == Gdk.KEY_Down: self.__history(1) - elif keyval == _keys.Left: + elif keyval == Gdk.KEY_Left: self.__move_cursor(-1) - elif keyval == _keys.Right: + elif keyval == Gdk.KEY_Right: self.__move_cursor(1) - elif keyval == _keys.Home: + elif keyval == Gdk.KEY_Home: self.__move_cursor(-10000) - elif keyval == _keys.End: + elif keyval == Gdk.KEY_End: self.__move_cursor(10000) - elif keyval == _keys.Tab: + elif keyval == Gdk.KEY_Tab: cursor = self.__get_cursor() if cursor.starts_line(): handled = False @@ -283,8 +270,8 @@ def do_key_press_event(self, event, parent_type): self.__complete() else: handled = False - elif state == gdk.CONTROL_MASK: - if keyval == _keys.u: + elif state == Gdk.ModifierType.CONTROL_MASK: + if keyval == Gdk.KEY_u: start = self.__get_start() end = self.__get_cursor() self.__delete(start, end) @@ -294,7 +281,7 @@ def do_key_press_event(self, event, parent_type): handled = False if not handled: - return parent_type.do_key_press_event(self, event.key if hasattr(event, "key") else event) + return parent_type.do_key_press_event(self, event.key) else: return True @@ -353,7 +340,7 @@ def __delete_at_cursor(self, howmany): def __get_width(self): if not (self.get_realized()): return 80 - layout = pango.Layout(self.get_pango_context()) + layout = Pango.Layout(self.get_pango_context()) letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" layout.set_text(letters) pix_width = layout.get_pixel_size()[0] @@ -531,10 +518,7 @@ def do_command(self, code): self.showtraceback() def runcode(self, code): - if gtk.pygtk_version[1] < 8: - self.do_command(code) - else: - self.emit("command", code) + self.emit("command", code) def exec_command(self, command): if self._get_line(): @@ -604,28 +588,25 @@ def complete(self, text): return completions -def ReadLineType(t=gtk.TextView): +def ReadLineType(t=Gtk.TextView): class readline(t, _ReadLine): def __init__(self, *args, **kwargs): t.__init__(self) _ReadLine.__init__(self, *args, **kwargs) def do_key_press_event(self, event): return _ReadLine.do_key_press_event(self, event, t) - gobject.type_register(readline) + GObject.type_register(readline) return readline -def ConsoleType(t=gtk.TextView): +def ConsoleType(t=Gtk.TextView): class console_type(t, _Console): __gsignals__ = { - 'command' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (object,)), + 'command' : (GObject.SignalFlags.RUN_LAST, None, (object,)), 'key-press-event' : 'override' } def __init__(self, *args, **kwargs): - if gtk.pygtk_version[1] < 8: - gobject.GObject.__init__(self) - else: - t.__init__(self) + GObject.GObject.__init__(self) _Console.__init__(self, *args, **kwargs) def do_command(self, code): @@ -634,9 +615,7 @@ def do_command(self, code): def do_key_press_event(self, event): return _Console.do_key_press_event(self, event, t) - if gtk.pygtk_version[1] < 8: - gobject.type_register(console_type) - + GObject.type_register(console_type) return console_type ReadLine = ReadLineType() @@ -650,19 +629,19 @@ def _create_widget(start_script): return console def _make_window(start_script="import geany\n"): - window = gtk.Window() + window = Gtk.Window() window.set_title("Python Console") - swin = gtk.ScrolledWindow() - swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS) + swin = Gtk.ScrolledWindow() + swin.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.ALWAYS) window.add(swin) console = _create_widget(start_script) swin.add(console) window.set_default_size(500, 400) window.show_all() - if not gtk.main_level(): - window.connect("destroy", gtk.main_quit) - gtk.main() + if not Gtk.main_level(): + window.connect("destroy", Gtk.main_quit) + Gtk.main() return console diff --git a/geany/loader.py b/geany/loader.py index ae4e504..15533b8 100644 --- a/geany/loader.py +++ b/geany/loader.py @@ -11,7 +11,13 @@ class PluginLoader(object): plugins = {} def __init__(self, plugin_dirs): + self.plugin_dirs = plugin_dirs + + #self.available_plugins = [] + #for plugin in self.iter_plugin_info(): + #self.available_plugins.append(plugin) + self.restore_loaded_plugins() diff --git a/geany/manager.py b/geany/manager.py index 3e05e79..7288414 100644 --- a/geany/manager.py +++ b/geany/manager.py @@ -1,90 +1,74 @@ -try: - from gi import pygtkcompat -except ImportError: - pygtkcompat = None - -if pygtkcompat is not None: - pygtkcompat.enable() - pygtkcompat.enable_gtk(version='3.0') - -import gtk -import gobject -import glib +from gi.repository import GObject, GLib, Gtk from htmlentitydefs import name2codepoint from loader import PluginLoader - -class PluginManager(gtk.Dialog): - +class PluginManager(Gtk.Dialog): def __init__(self, parent=None, plugin_dirs=[]): - super(PluginManager, self).__init__(title="Plugin Manager", parent=parent, flags=gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_MODAL) + super(PluginManager, self).__init__(title="Plugin Manager", parent=parent, flags=Gtk.DialogFlags.DESTROY_WITH_PARENT | Gtk.DialogFlags.MODAL) self.loader = PluginLoader(plugin_dirs) - self.set_default_size(400, 450) - icon = self.render_icon(gtk.STOCK_PREFERENCES, gtk.ICON_SIZE_MENU) + icon = self.render_icon(Gtk.STOCK_PREFERENCES, Gtk.IconSize.MENU) self.set_icon(icon) - + self.connect("response", lambda w,d: self.hide()) - - vbox = gtk.VBox(False, 12) + + vbox = Gtk.VBox(False, 12) vbox.set_border_width(12) - - lbl = gtk.Label("Choose plugins to load or unload:") + + lbl = Gtk.Label("Choose plugins to load or unload:") lbl.set_alignment(0.0, 0.5) vbox.pack_start(lbl, False, False, 0) - - sw = gtk.ScrolledWindow() - if hasattr(sw, 'set_hexpand'): - sw.set_hexpand(True) - sw.set_vexpand(True) - sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) - sw.set_shadow_type(gtk.SHADOW_ETCHED_IN) + + sw = Gtk.ScrolledWindow() + sw.set_hexpand(True) + sw.set_vexpand(True) + sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) + sw.set_shadow_type(Gtk.ShadowType.ETCHED_IN) vbox.pack_start(sw, True, True, 0) - - self.treeview = gtk.TreeView() + + self.treeview = Gtk.TreeView() sw.add(self.treeview) - + vbox.show_all() - + self.get_content_area().add(vbox) - + action_area = self.get_action_area() action_area.set_spacing(0) action_area.set_homogeneous(False) - - btn = gtk.Button(stock=gtk.STOCK_CLOSE) + + btn = Gtk.Button(stock=Gtk.STOCK_CLOSE) btn.set_border_width(6) - btn.connect("clicked", lambda x: self.response(gtk.RESPONSE_CLOSE)) + btn.connect("clicked", lambda x: self.response(Gtk.ResponseType.CLOSE)) action_area.pack_start(btn, False, True, 0) btn.show() - - self.btn_help = gtk.Button(stock=gtk.STOCK_HELP) + + self.btn_help = Gtk.Button(stock=Gtk.STOCK_HELP) self.btn_help.set_border_width(6) self.btn_help.set_no_show_all(True) action_area.pack_start(self.btn_help, False, True, 0) action_area.set_child_secondary(self.btn_help, True) - - self.btn_prefs = gtk.Button(stock=gtk.STOCK_PREFERENCES) + + self.btn_prefs = Gtk.Button(stock=Gtk.STOCK_PREFERENCES) self.btn_prefs.set_border_width(6) self.btn_prefs.set_no_show_all(True) action_area.pack_start(self.btn_prefs, False, True, 0) action_area.set_child_secondary(self.btn_prefs, True) - + action_area.show() - + self.load_plugins_list() - def on_help_button_clicked(self, button, treeview, model): path = treeview.get_cursor()[0] iter = model.get_iter(path) filename = model.get_value(iter, 2) - for plugin in self.loader.available_plugins: + for plugin in self.loader.iter_plugin_info(): if plugin.filename == filename: plugin.cls.show_help() break - else: - print("Plugin does not support help function") + else: + print("Plugin does not support help function") def on_preferences_button_clicked(self, button, treeview, model): @@ -106,76 +90,74 @@ def deactivate_plugin(self, filename): def load_plugins_list(self): - liststore = gtk.ListStore(gobject.TYPE_BOOLEAN, str, str) + liststore = Gtk.ListStore(GObject.TYPE_BOOLEAN, str, str) self.btn_help.connect("clicked", - self.on_help_button_clicked, self.treeview, liststore) + self.on_help_button_clicked, self.treeview, liststore) self.btn_prefs.connect("clicked", - self.on_preferences_button_clicked, self.treeview, liststore) + self.on_preferences_button_clicked, self.treeview, liststore) self.treeview.set_model(liststore) self.treeview.set_headers_visible(False) self.treeview.set_grid_lines(True) - check_renderer = gtk.CellRendererToggle() + check_renderer = Gtk.CellRendererToggle() check_renderer.set_radio(False) check_renderer.connect('toggled', self.on_plugin_load_toggled, liststore) - text_renderer = gtk.CellRendererText() - - check_column = gtk.TreeViewColumn(None, check_renderer, active=0) - text_column = gtk.TreeViewColumn(None, text_renderer, markup=1) - + text_renderer = Gtk.CellRendererText() + check_column = Gtk.TreeViewColumn(None, check_renderer, active=0) + text_column = Gtk.TreeViewColumn(None, text_renderer, markup=1) + self.treeview.append_column(check_column) self.treeview.append_column(text_column) - + self.treeview.connect('row-activated', - self.on_row_activated, check_renderer, liststore) + self.on_row_activated, check_renderer, liststore) self.treeview.connect('cursor-changed', - self.on_selected_plugin_changed, liststore) - + self.on_selected_plugin_changed, liststore) + self.load_sorted_plugins_info(liststore) def load_sorted_plugins_info(self, list_store): - - plugin_info_list = list(self.loader.iter_plugin_info()) + #plugin_info_list = list(self.loader.iter_plugin_info()) #plugin_info_list.sort(key=lambda pi: pi[1]) - for plugin_info in plugin_info_list: - + for plugin_info in self.loader.iter_plugin_info(): + lbl = str('%s %s\n%s\n' + - 'Author: %s\n' + - 'Filename: %s') % ( - glib.markup_escape_text(plugin_info.name), - glib.markup_escape_text(plugin_info.version), - glib.markup_escape_text(plugin_info.description), - glib.markup_escape_text(plugin_info.author), - glib.markup_escape_text(plugin_info.filename)) - + 'Author: %s\n' + + 'Filename: %s') % ( + GLib.markup_escape_text(plugin_info.name), + GLib.markup_escape_text(plugin_info.version), + GLib.markup_escape_text(plugin_info.description), + GLib.markup_escape_text(plugin_info.author), + GLib.markup_escape_text(plugin_info.filename)) + loaded = plugin_info.filename in self.loader.plugins - + list_store.append([loaded, lbl, plugin_info.filename]) - + def on_selected_plugin_changed(self, treeview, model): - + path = treeview.get_cursor()[0] iter = model.get_iter(path) filename = model.get_value(iter, 2) active = model.get_value(iter, 0) - + if self.loader.plugin_has_configure(filename): self.btn_prefs.set_visible(True) else: self.btn_prefs.set_visible(False) - + if self.loader.plugin_has_help(filename): self.btn_help.set_visible(True) else: self.btn_help.set_visible(False) - - + + def on_plugin_load_toggled(self, cell, path, model): active = not cell.get_active() iter = model.get_iter(path) @@ -184,7 +166,7 @@ def on_plugin_load_toggled(self, cell, path, model): self.activate_plugin(model.get_value(iter, 2)) else: self.deactivate_plugin(model.get_value(iter, 2)) - - + + def on_row_activated(self, tvw, path, view_col, cell, model): self.on_plugin_load_toggled(cell, path, model) \ No newline at end of file diff --git a/geany/signalmanager.py b/geany/signalmanager.py index 16d7910..3e0d69e 100644 --- a/geany/signalmanager.py +++ b/geany/signalmanager.py @@ -3,62 +3,54 @@ all signals on. The signals are emitted from the C code in signalmanager.c, where the Geany types get wrapped in PyObject types. """ -try: - from gi import pygtkcompat -except ImportError: - pygtkcompat = None +from gi.repository import GObject -if pygtkcompat is not None: - pygtkcompat.enable() - pygtkcompat.enable_gtk(version='3.0') -import gobject - -class SignalManager(gobject.GObject): +class SignalManager(GObject.GObject): """ Manages callback functions for events emitted by Geany's internal GObject. """ __gsignals__ = { - 'build-start': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + 'build-start': (GObject.SignalFlags.RUN_LAST, None, ()), - 'document-activate': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'document-before-save': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'document-close': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'document-filetype-set': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT)), - 'document-new': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'document-open': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'document-reload': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'document-save': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'editor-notify': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_BOOLEAN, - (gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT)), - 'geany-startup-complete': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + 'document-activate': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'document-before-save': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'document-close': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'document-filetype-set': (GObject.SignalFlags.RUN_LAST, None, + (object, object)), + 'document-new': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'document-open': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'document-reload': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'document-save': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'editor-notify': (GObject.SignalFlags.RUN_LAST, GObject.TYPE_BOOLEAN, + (object, object)), + 'geany-startup-complete': (GObject.SignalFlags.RUN_LAST, None, ()), - 'project-close': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + 'project-close': (GObject.SignalFlags.RUN_LAST, None, ()), - 'project-dialog-confirmed': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'project-dialog-open': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'project-dialog-close': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'project-open': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'project-save': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_PYOBJECT,)), - 'update-editor-menu': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, - (gobject.TYPE_STRING, gobject.TYPE_INT, - gobject.TYPE_PYOBJECT)), + 'project-dialog-confirmed': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'project-dialog-open': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'project-dialog-close': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'project-open': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'project-save': (GObject.SignalFlags.RUN_LAST, None, + (object,)), + 'update-editor-menu': (GObject.SignalFlags.RUN_LAST, None, + (GObject.TYPE_STRING, GObject.TYPE_INT, + object)), } # __gsignals__ def __init__(self): super(SignalManager, self).__init__() -gobject.type_register(SignalManager) \ No newline at end of file +GObject.type_register(SignalManager) \ No newline at end of file diff --git a/plugins/console.py b/plugins/console.py index d6bbfaf..1bd02f1 100644 --- a/plugins/console.py +++ b/plugins/console.py @@ -1,24 +1,12 @@ -try: - from gi import pygtkcompat -except ImportError: - pygtkcompat = None - -if pygtkcompat is not None: - pygtkcompat.enable() - pygtkcompat.enable_gtk(version='3.0') - import os from ConfigParser import SafeConfigParser import geany import geany.console -import gobject -import gtk -import gtk.gdk as gdk -import pango +from gi.repository import GObject, Gtk, Gdk, Pango -WIDGET_STATES = [ gtk.STATE_NORMAL, gtk.STATE_ACTIVE, gtk.STATE_PRELIGHT, - gtk.STATE_SELECTED, gtk.STATE_INSENSITIVE ] +WIDGET_STATES = [ Gtk.StateType.NORMAL, Gtk.StateType.ACTIVE, Gtk.StateType.PRELIGHT, + Gtk.StateType.SELECTED, Gtk.StateType.INSENSITIVE ] class ConsolePlugin(geany.Plugin): @@ -57,7 +45,7 @@ def load_config(self): def save_config(self): - gobject.idle_add(self.on_save_config_timeout) + GObject.idle_add(self.on_save_config_timeout) def on_save_config_timeout(self, data=None): @@ -71,8 +59,8 @@ def install_console(self): self.banner = self.banner self.use_rl_completer = self.use_rl_completer - self.swin = gtk.ScrolledWindow() - self.swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS) + self.swin = Gtk.ScrolledWindow() + self.swin.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.ALWAYS) self.console = geany.console.Console(banner = self.banner, use_rlcompleter = self.use_rl_completer) self.console.connect("populate-popup", self.on_console_populate_popup) @@ -84,7 +72,7 @@ def install_console(self): self.swin.add(self.console) geany.main_widgets.message_window_notebook.append_page(self.swin, - gtk.Label("Python")) + Gtk.Label("Python")) self.swin.show_all() self.save_config() @@ -100,7 +88,7 @@ def _get_font(self): return self._font def _set_font(self, font): self._font = font - font_desc = pango.FontDescription(font) + font_desc = Pango.FontDescription(font) self.console.modify_font(font_desc) if not self.cfg.has_section('appearances'): self.cfg.add_section('appearances') @@ -116,7 +104,7 @@ def _get_bg(self): return self._bg def _set_bg(self, bg): self._bg = bg - color = gdk.color_parse(self._bg) + color = Gdk.color_parse(self._bg) for state in WIDGET_STATES: self.console.modify_bg(state, color) self.console.modify_base(state, color) @@ -134,7 +122,7 @@ def _get_fg(self): return self._fg def _set_fg(self, fg): self._fg = fg - color = gdk.color_parse(self._fg) + color = Gdk.color_parse(self._fg) for state in WIDGET_STATES: self.console.modify_fg(state, color) self.console.modify_text(state, color) @@ -175,10 +163,10 @@ def _set_use_rl_completer(self, use_rl_completer): def on_console_populate_popup(self, textview, menu, data=None): - item = gtk.SeparatorMenuItem() + item = Gtk.SeparatorMenuItem() item.show() menu.append(item) - item = gtk.ImageMenuItem(stock_id=gtk.STOCK_PREFERENCES) + item = Gtk.ImageMenuItem(stock_id=Gtk.STOCK_PREFERENCES) item.show() menu.append(item) item.connect("activate", lambda w,d=None: self.show_configure()) @@ -201,114 +189,114 @@ def on_bg_color_changed(self, clr_btn, data=None): def show_configure(self): - dialog = gtk.Dialog("Configure Python Console", - geany.main_widgets.window, - gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, - (gtk.STOCK_CLOSE, gtk.RESPONSE_ACCEPT)) - - #dialog.set_has_separator(True) - + dialog = Gtk.Dialog(title="Configure Python Console", + parent=geany.main_widgets.window, + flags=Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, + buttons=(Gtk.STOCK_CLOSE, Gtk.ResponseType.ACCEPT)) content_area = dialog.get_content_area() content_area.set_border_width(6) - vbox = gtk.VBox(spacing=6) + vbox = Gtk.VBox(spacing=6) vbox.set_border_width(6) - lbl = gtk.Label() + lbl = Gtk.Label() lbl.set_use_markup(True) lbl.set_markup("General") - fra_general = gtk.Frame() - fra_general.set_shadow_type(gtk.SHADOW_NONE) + fra_general = Gtk.Frame() + fra_general.set_shadow_type(Gtk.ShadowType.NONE) fra_general.set_label_widget(lbl) - al_general = gtk.Alignment(0.0, 0.0, 1.0, 1.0) + al_general = Gtk.Alignment() + al_general.set(0.0, 0.0, 1.0, 1.0) al_general.set_padding(0, 0, 12, 0) fra_general.add(al_general) - tbl = gtk.Table(3, 2, False) + tbl = Gtk.Table(3, 2, False) tbl.set_row_spacings(6) tbl.set_col_spacings(6) tbl.set_border_width(6) - lbl = gtk.Label("Banner:") + lbl = Gtk.Label("Banner:") lbl.set_alignment(0.0, 0.0) - tvw = gtk.TextView() + tvw = Gtk.TextView() tvw.get_buffer().set_text(self.banner) tvw.get_buffer().connect("changed", self.on_banner_changed) - swin = gtk.ScrolledWindow() - swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) - swin.set_shadow_type(gtk.SHADOW_ETCHED_IN) + swin = Gtk.ScrolledWindow() + swin.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) + swin.set_shadow_type(Gtk.ShadowType.ETCHED_IN) swin.add(tvw) - tbl.attach(lbl, 0, 1, 0, 1, gtk.FILL, gtk.FILL, 0, 0) - tbl.attach(swin, 1, 2, 0, 1, gtk.EXPAND | gtk.FILL, gtk.EXPAND | gtk.FILL, 0, 0) + tbl.attach(lbl, 0, 1, 0, 1, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) + tbl.attach(swin, 1, 2, 0, 1, Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, 0, 0) - lbl = gtk.Label("") + lbl = Gtk.Label("") lbl.set_alignment(0.0, 0.5) - check = gtk.CheckButton("Use Readline") + check = Gtk.CheckButton("Use Readline") if self.use_rl_completer: check.set_active(True) check.connect("toggled", self.on_use_rl_completer_toggled) - tbl.attach(lbl, 0, 1, 1, 2, gtk.FILL, gtk.FILL, 0, 0) - tbl.attach(check, 1, 2, 1, 2, gtk.FILL, gtk.FILL, 0, 0) + tbl.attach(lbl, 0, 1, 1, 2, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) + tbl.attach(check, 1, 2, 1, 2, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) - lbl = gtk.Label("") + lbl = Gtk.Label("") lbl.set_alignment(0.0, 0.5) lbl.set_use_markup(True) lbl.set_markup('' + 'Note: General settings will be applied when console is reloaded.' + '') - tbl.attach(lbl, 0, 2, 2, 3, gtk.FILL, gtk.FILL, 0, 0) + tbl.attach(lbl, 0, 2, 2, 3, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) al_general.add(tbl) - lbl = gtk.Label() + lbl = Gtk.Label() lbl.set_use_markup(True) lbl.set_markup("Appearances") - fra_appearances = gtk.Frame() - fra_appearances.set_shadow_type(gtk.SHADOW_NONE) + fra_appearances = Gtk.Frame() + fra_appearances.set_shadow_type(Gtk.ShadowType.NONE) fra_appearances.set_label_widget(lbl) - al_appearances = gtk.Alignment(0.0, 0.0, 1.0, 1.0) + al_appearances = Gtk.Alignment() + al_appearances.set(0.0, 0.0, 1.0, 1.0) al_appearances.set_padding(0, 0, 12, 0) fra_appearances.add(al_appearances) - tbl = gtk.Table(3, 2, False) + tbl = Gtk.Table(3, 2, False) tbl.set_row_spacings(6) tbl.set_col_spacings(6) tbl.set_border_width(6) - lbl = gtk.Label("Font:") + lbl = Gtk.Label("Font:") lbl.set_alignment(0.0, 0.5) - btn = gtk.FontButton(self.font) + btn = Gtk.FontButton(self.font) btn.connect("font-set", self.on_font_changed) - tbl.attach(lbl, 0, 1, 0, 1, gtk.FILL, gtk.FILL, 0, 0) - tbl.attach(btn, 1, 2, 0, 1, gtk.FILL | gtk.EXPAND, gtk.FILL, 0, 0) + tbl.attach(lbl, 0, 1, 0, 1, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) + tbl.attach(btn, 1, 2, 0, 1, Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, Gtk.AttachOptions.FILL, 0, 0) - lbl = gtk.Label("FG Color:") + lbl = Gtk.Label("FG Color:") lbl.set_alignment(0.0, 0.5) - btn = gtk.ColorButton(color=gdk.color_parse(self.fg)) + + btn = Gtk.ColorButton(color=Gdk.color_parse(self.fg)) btn.connect("color-set", self.on_fg_color_changed) - tbl.attach(lbl, 0, 1, 1, 2, gtk.FILL, gtk.FILL, 0, 0) - tbl.attach(btn, 1, 2, 1, 2, gtk.FILL | gtk.EXPAND, gtk.FILL, 0, 0) + tbl.attach(lbl, 0, 1, 1, 2, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) + tbl.attach(btn, 1, 2, 1, 2, Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, Gtk.AttachOptions.FILL, 0, 0) - lbl = gtk.Label("BG Color:") + lbl = Gtk.Label("BG Color:") lbl.set_alignment(0.0, 0.5) - btn = gtk.ColorButton(color=gdk.color_parse(self.bg)) + btn = Gtk.ColorButton(color=Gdk.color_parse(self.bg)) btn.connect("color-set", self.on_bg_color_changed) - tbl.attach(lbl, 0, 1, 2, 3, gtk.FILL, gtk.FILL, 0, 0) - tbl.attach(btn, 1, 2, 2, 3, gtk.FILL | gtk.EXPAND, gtk.FILL, 0, 0) + tbl.attach(lbl, 0, 1, 2, 3, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) + tbl.attach(btn, 1, 2, 2, 3, Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, Gtk.AttachOptions.FILL, 0, 0) al_appearances.add(tbl) diff --git a/plugins/hello.py b/plugins/hello.py index d6153b8..c9e2859 100644 --- a/plugins/hello.py +++ b/plugins/hello.py @@ -1,12 +1,4 @@ -try: - from gi import pygtkcompat -except ImportError: - pygtkcompat = None - -if pygtkcompat is not None: - pygtkcompat.enable() - pygtkcompat.enable_gtk(version='3.0') -import gtk +from gi.repository import Gtk import geany class HelloWorld(geany.Plugin): @@ -17,7 +9,7 @@ class HelloWorld(geany.Plugin): __plugin_author__ = "John Doe " def __init__(self): - self.menu_item = gtk.MenuItem("Hello World") + self.menu_item = Gtk.MenuItem("Hello World") self.menu_item.show() geany.main_widgets.tools_menu.append(self.menu_item) self.menu_item.connect("activate", self.on_hello_item_clicked) diff --git a/src/Makefile.am b/src/Makefile.am index 812af48..5e3247d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,21 +2,12 @@ geanyplugin_LTLIBRARIES = geanypy.la geanyplugindir = $(libdir)/geany geanypy_la_LDFLAGS = -module -avoid-version -Wl,--export-dynamic -if GP_GTK3 geanypy_la_CPPFLAGS = @GEANY_CFLAGS@ @PYGOBJECT_CFLAGS@ @PYTHON_CPPFLAGS@ \ -DGEANYPY_PYTHON_DIR="\"$(libdir)/geany/geanypy\"" \ -DGEANYPY_PLUGIN_DIR="\"$(datadir)/geany/geanypy/plugins\"" \ -UHAVE_CONFIG_H geanypy_la_LIBADD = @GEANY_LIBS@ @PYGOBJECT_LIBS@ @PYTHON_LDFLAGS@ \ @PYTHON_EXTRA_LIBS@ @PYTHON_EXTRA_LDFLAGS@ -else -geanypy_la_CPPFLAGS = @GEANY_CFLAGS@ @PYGTK_CFLAGS@ @PYTHON_CPPFLAGS@ \ - -DGEANYPY_PYTHON_DIR="\"$(libdir)/geany/geanypy\"" \ - -DGEANYPY_PLUGIN_DIR="\"$(datadir)/geany/geanypy/plugins\"" \ - -UHAVE_CONFIG_H -geanypy_la_LIBADD = @GEANY_LIBS@ @PYGTK_LIBS@ @PYTHON_LDFLAGS@ \ - @PYTHON_EXTRA_LIBS@ @PYTHON_EXTRA_LDFLAGS@ -endif geanypy_la_SOURCES = geanypy-app.c \ geanypy-bindings.c \ geanypy-dialogs.c \ From 247d34ba27d539df8f4622c2e1bb5bbe022544de Mon Sep 17 00:00:00 2001 From: Sagar Chalise Date: Sun, 4 Aug 2013 11:37:35 +0545 Subject: [PATCH 20/28] Gtk2 & gtk3 compatibilities --- configure.ac | 2 +- geany/console.py | 87 ++++++++++++++---------- geany/loader.py | 6 -- geany/manager.py | 146 +++++++++++++++++++++++------------------ geany/signalmanager.py | 82 ++++++++++++----------- plugins/console.py | 122 ++++++++++++++++++---------------- plugins/hello.py | 12 +++- src/Makefile.am | 9 +++ 8 files changed, 268 insertions(+), 198 deletions(-) diff --git a/configure.ac b/configure.ac index 2b18609..f9a798e 100644 --- a/configure.ac +++ b/configure.ac @@ -19,7 +19,7 @@ AC_PROG_SED # Check for headers, libraries and packages AC_CHECK_HEADERS([stdio.h string.h dlfcn.h]) PKG_CHECK_MODULES([GEANY], [geany >= 0.21]) -PKG_CHECK_MODULES([PYGOBJECT], [pygobject-3.0]) +GP_CHECK_GTK3([PKG_CHECK_MODULES([PYGOBJECT], [pygobject-3.0])], [PKG_CHECK_MODULES([PYGTK], [pygtk-2.0])]) AX_PYTHON_DEVEL([>= '2.6']) AX_PYTHON_LIBRARY(,[AC_MSG_ERROR([Cannot determine location of the Python DSO])]) AC_SUBST([PYTHON]) diff --git a/geany/console.py b/geany/console.py index 91166ca..87e2c4a 100644 --- a/geany/console.py +++ b/geany/console.py @@ -28,16 +28,29 @@ # To modify output appearance, set attributes of console.stdout_tag and # console.stderr_tag. # -# Console may subclass a type other than Gtk.TextView, to allow syntax highlighting and stuff, +# Console may subclass a type other than gtk.TextView, to allow syntax highlighting and stuff, # e.g.: # console_type = pyconsole.ConsoleType(moo.TextView) -# console = console_type(use_rlcompleter=False, start_script="import moo\nimport Gtk\n") +# console = console_type(use_rlcompleter=False, start_script="import moo\nimport gtk\n") # # This widget is not a replacement for real terminal with python running # inside: GtkTextView is not a terminal. # The use case is: you have a python program, you create this widget, # and inspect your program interiors. -from gi.repository import GObject, Gtk, Gdk, Pango +try: + from gi import pygtkcompat +except ImportError: + pygtkcompat = None + +if pygtkcompat is not None: + pygtkcompat.enable() + pygtkcompat.enable_gtk(version='3.0') + +import gtk +import gtk.gdk as gdk +import gobject +import pango +import gtk.keysyms as _keys import code import sys import keyword @@ -104,8 +117,8 @@ def get(self, dir, text): def __init__(self): object.__init__(self) - self.set_wrap_mode(Gtk.WrapMode.CHAR) - self.modify_font(Pango.FontDescription("Monospace")) + self.set_wrap_mode(gtk.WRAP_CHAR) + self.modify_font(pango.FontDescription("Monospace")) self.buffer = self.get_buffer() self.buffer.connect("insert-text", self.on_buf_insert) @@ -237,27 +250,27 @@ def do_key_press_event(self, event, parent_type): self.tab_pressed = 0 handled = True - state = event.state & (Gdk.ModifierType.SHIFT_MASK | - Gdk.ModifierType.CONTROL_MASK | - Gdk.ModifierType.MOD1_MASK) + state = event.state & (gdk.SHIFT_MASK | + gdk.CONTROL_MASK | + gdk.MOD1_MASK) keyval = event.keyval if not state: - if keyval == Gdk.KEY_Return: + if keyval == _keys.Return: self._commit() - elif keyval == Gdk.KEY_Up: + elif keyval == _keys.Up: self.__history(-1) - elif keyval == Gdk.KEY_Down: + elif keyval == _keys.Down: self.__history(1) - elif keyval == Gdk.KEY_Left: + elif keyval == _keys.Left: self.__move_cursor(-1) - elif keyval == Gdk.KEY_Right: + elif keyval == _keys.Right: self.__move_cursor(1) - elif keyval == Gdk.KEY_Home: + elif keyval == _keys.Home: self.__move_cursor(-10000) - elif keyval == Gdk.KEY_End: + elif keyval == _keys.End: self.__move_cursor(10000) - elif keyval == Gdk.KEY_Tab: + elif keyval == _keys.Tab: cursor = self.__get_cursor() if cursor.starts_line(): handled = False @@ -270,8 +283,8 @@ def do_key_press_event(self, event, parent_type): self.__complete() else: handled = False - elif state == Gdk.ModifierType.CONTROL_MASK: - if keyval == Gdk.KEY_u: + elif state == gdk.CONTROL_MASK: + if keyval == _keys.u: start = self.__get_start() end = self.__get_cursor() self.__delete(start, end) @@ -281,7 +294,7 @@ def do_key_press_event(self, event, parent_type): handled = False if not handled: - return parent_type.do_key_press_event(self, event.key) + return parent_type.do_key_press_event(self, event.key if hasattr(event, "key") else event) else: return True @@ -340,7 +353,7 @@ def __delete_at_cursor(self, howmany): def __get_width(self): if not (self.get_realized()): return 80 - layout = Pango.Layout(self.get_pango_context()) + layout = pango.Layout(self.get_pango_context()) letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" layout.set_text(letters) pix_width = layout.get_pixel_size()[0] @@ -518,7 +531,10 @@ def do_command(self, code): self.showtraceback() def runcode(self, code): - self.emit("command", code) + if gtk.pygtk_version[1] < 8: + self.do_command(code) + else: + self.emit("command", code) def exec_command(self, command): if self._get_line(): @@ -588,25 +604,28 @@ def complete(self, text): return completions -def ReadLineType(t=Gtk.TextView): +def ReadLineType(t=gtk.TextView): class readline(t, _ReadLine): def __init__(self, *args, **kwargs): t.__init__(self) _ReadLine.__init__(self, *args, **kwargs) def do_key_press_event(self, event): return _ReadLine.do_key_press_event(self, event, t) - GObject.type_register(readline) + gobject.type_register(readline) return readline -def ConsoleType(t=Gtk.TextView): +def ConsoleType(t=gtk.TextView): class console_type(t, _Console): __gsignals__ = { - 'command' : (GObject.SignalFlags.RUN_LAST, None, (object,)), + 'command' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (object,)), 'key-press-event' : 'override' } def __init__(self, *args, **kwargs): - GObject.GObject.__init__(self) + if gtk.pygtk_version[1] < 8: + gobject.GObject.__init__(self) + else: + t.__init__(self) _Console.__init__(self, *args, **kwargs) def do_command(self, code): @@ -615,7 +634,9 @@ def do_command(self, code): def do_key_press_event(self, event): return _Console.do_key_press_event(self, event, t) - GObject.type_register(console_type) + if gtk.pygtk_version[1] < 8: + gobject.type_register(console_type) + return console_type ReadLine = ReadLineType() @@ -629,19 +650,19 @@ def _create_widget(start_script): return console def _make_window(start_script="import geany\n"): - window = Gtk.Window() + window = gtk.Window() window.set_title("Python Console") - swin = Gtk.ScrolledWindow() - swin.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.ALWAYS) + swin = gtk.ScrolledWindow() + swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS) window.add(swin) console = _create_widget(start_script) swin.add(console) window.set_default_size(500, 400) window.show_all() - if not Gtk.main_level(): - window.connect("destroy", Gtk.main_quit) - Gtk.main() + if not gtk.main_level(): + window.connect("destroy", gtk.main_quit) + gtk.main() return console diff --git a/geany/loader.py b/geany/loader.py index 15533b8..ae4e504 100644 --- a/geany/loader.py +++ b/geany/loader.py @@ -11,13 +11,7 @@ class PluginLoader(object): plugins = {} def __init__(self, plugin_dirs): - self.plugin_dirs = plugin_dirs - - #self.available_plugins = [] - #for plugin in self.iter_plugin_info(): - #self.available_plugins.append(plugin) - self.restore_loaded_plugins() diff --git a/geany/manager.py b/geany/manager.py index 7288414..3e05e79 100644 --- a/geany/manager.py +++ b/geany/manager.py @@ -1,74 +1,90 @@ -from gi.repository import GObject, GLib, Gtk +try: + from gi import pygtkcompat +except ImportError: + pygtkcompat = None + +if pygtkcompat is not None: + pygtkcompat.enable() + pygtkcompat.enable_gtk(version='3.0') + +import gtk +import gobject +import glib from htmlentitydefs import name2codepoint from loader import PluginLoader -class PluginManager(Gtk.Dialog): + +class PluginManager(gtk.Dialog): + def __init__(self, parent=None, plugin_dirs=[]): - super(PluginManager, self).__init__(title="Plugin Manager", parent=parent, flags=Gtk.DialogFlags.DESTROY_WITH_PARENT | Gtk.DialogFlags.MODAL) + super(PluginManager, self).__init__(title="Plugin Manager", parent=parent, flags=gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_MODAL) self.loader = PluginLoader(plugin_dirs) + self.set_default_size(400, 450) - icon = self.render_icon(Gtk.STOCK_PREFERENCES, Gtk.IconSize.MENU) + icon = self.render_icon(gtk.STOCK_PREFERENCES, gtk.ICON_SIZE_MENU) self.set_icon(icon) - + self.connect("response", lambda w,d: self.hide()) - - vbox = Gtk.VBox(False, 12) + + vbox = gtk.VBox(False, 12) vbox.set_border_width(12) - - lbl = Gtk.Label("Choose plugins to load or unload:") + + lbl = gtk.Label("Choose plugins to load or unload:") lbl.set_alignment(0.0, 0.5) vbox.pack_start(lbl, False, False, 0) - - sw = Gtk.ScrolledWindow() - sw.set_hexpand(True) - sw.set_vexpand(True) - sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) - sw.set_shadow_type(Gtk.ShadowType.ETCHED_IN) + + sw = gtk.ScrolledWindow() + if hasattr(sw, 'set_hexpand'): + sw.set_hexpand(True) + sw.set_vexpand(True) + sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + sw.set_shadow_type(gtk.SHADOW_ETCHED_IN) vbox.pack_start(sw, True, True, 0) - - self.treeview = Gtk.TreeView() + + self.treeview = gtk.TreeView() sw.add(self.treeview) - + vbox.show_all() - + self.get_content_area().add(vbox) - + action_area = self.get_action_area() action_area.set_spacing(0) action_area.set_homogeneous(False) - - btn = Gtk.Button(stock=Gtk.STOCK_CLOSE) + + btn = gtk.Button(stock=gtk.STOCK_CLOSE) btn.set_border_width(6) - btn.connect("clicked", lambda x: self.response(Gtk.ResponseType.CLOSE)) + btn.connect("clicked", lambda x: self.response(gtk.RESPONSE_CLOSE)) action_area.pack_start(btn, False, True, 0) btn.show() - - self.btn_help = Gtk.Button(stock=Gtk.STOCK_HELP) + + self.btn_help = gtk.Button(stock=gtk.STOCK_HELP) self.btn_help.set_border_width(6) self.btn_help.set_no_show_all(True) action_area.pack_start(self.btn_help, False, True, 0) action_area.set_child_secondary(self.btn_help, True) - - self.btn_prefs = Gtk.Button(stock=Gtk.STOCK_PREFERENCES) + + self.btn_prefs = gtk.Button(stock=gtk.STOCK_PREFERENCES) self.btn_prefs.set_border_width(6) self.btn_prefs.set_no_show_all(True) action_area.pack_start(self.btn_prefs, False, True, 0) action_area.set_child_secondary(self.btn_prefs, True) - + action_area.show() - + self.load_plugins_list() + def on_help_button_clicked(self, button, treeview, model): path = treeview.get_cursor()[0] iter = model.get_iter(path) filename = model.get_value(iter, 2) - for plugin in self.loader.iter_plugin_info(): + for plugin in self.loader.available_plugins: if plugin.filename == filename: plugin.cls.show_help() break - else: - print("Plugin does not support help function") + else: + print("Plugin does not support help function") def on_preferences_button_clicked(self, button, treeview, model): @@ -90,74 +106,76 @@ def deactivate_plugin(self, filename): def load_plugins_list(self): - liststore = Gtk.ListStore(GObject.TYPE_BOOLEAN, str, str) + liststore = gtk.ListStore(gobject.TYPE_BOOLEAN, str, str) self.btn_help.connect("clicked", - self.on_help_button_clicked, self.treeview, liststore) + self.on_help_button_clicked, self.treeview, liststore) self.btn_prefs.connect("clicked", - self.on_preferences_button_clicked, self.treeview, liststore) + self.on_preferences_button_clicked, self.treeview, liststore) self.treeview.set_model(liststore) self.treeview.set_headers_visible(False) self.treeview.set_grid_lines(True) - check_renderer = Gtk.CellRendererToggle() + check_renderer = gtk.CellRendererToggle() check_renderer.set_radio(False) check_renderer.connect('toggled', self.on_plugin_load_toggled, liststore) - text_renderer = Gtk.CellRendererText() - check_column = Gtk.TreeViewColumn(None, check_renderer, active=0) - text_column = Gtk.TreeViewColumn(None, text_renderer, markup=1) - + text_renderer = gtk.CellRendererText() + + check_column = gtk.TreeViewColumn(None, check_renderer, active=0) + text_column = gtk.TreeViewColumn(None, text_renderer, markup=1) + self.treeview.append_column(check_column) self.treeview.append_column(text_column) - + self.treeview.connect('row-activated', - self.on_row_activated, check_renderer, liststore) + self.on_row_activated, check_renderer, liststore) self.treeview.connect('cursor-changed', - self.on_selected_plugin_changed, liststore) - + self.on_selected_plugin_changed, liststore) + self.load_sorted_plugins_info(liststore) def load_sorted_plugins_info(self, list_store): - #plugin_info_list = list(self.loader.iter_plugin_info()) + + plugin_info_list = list(self.loader.iter_plugin_info()) #plugin_info_list.sort(key=lambda pi: pi[1]) - for plugin_info in self.loader.iter_plugin_info(): - + for plugin_info in plugin_info_list: + lbl = str('%s %s\n%s\n' + - 'Author: %s\n' + - 'Filename: %s') % ( - GLib.markup_escape_text(plugin_info.name), - GLib.markup_escape_text(plugin_info.version), - GLib.markup_escape_text(plugin_info.description), - GLib.markup_escape_text(plugin_info.author), - GLib.markup_escape_text(plugin_info.filename)) - + 'Author: %s\n' + + 'Filename: %s') % ( + glib.markup_escape_text(plugin_info.name), + glib.markup_escape_text(plugin_info.version), + glib.markup_escape_text(plugin_info.description), + glib.markup_escape_text(plugin_info.author), + glib.markup_escape_text(plugin_info.filename)) + loaded = plugin_info.filename in self.loader.plugins - + list_store.append([loaded, lbl, plugin_info.filename]) - + def on_selected_plugin_changed(self, treeview, model): - + path = treeview.get_cursor()[0] iter = model.get_iter(path) filename = model.get_value(iter, 2) active = model.get_value(iter, 0) - + if self.loader.plugin_has_configure(filename): self.btn_prefs.set_visible(True) else: self.btn_prefs.set_visible(False) - + if self.loader.plugin_has_help(filename): self.btn_help.set_visible(True) else: self.btn_help.set_visible(False) - - + + def on_plugin_load_toggled(self, cell, path, model): active = not cell.get_active() iter = model.get_iter(path) @@ -166,7 +184,7 @@ def on_plugin_load_toggled(self, cell, path, model): self.activate_plugin(model.get_value(iter, 2)) else: self.deactivate_plugin(model.get_value(iter, 2)) - - + + def on_row_activated(self, tvw, path, view_col, cell, model): self.on_plugin_load_toggled(cell, path, model) \ No newline at end of file diff --git a/geany/signalmanager.py b/geany/signalmanager.py index 3e0d69e..16d7910 100644 --- a/geany/signalmanager.py +++ b/geany/signalmanager.py @@ -3,54 +3,62 @@ all signals on. The signals are emitted from the C code in signalmanager.c, where the Geany types get wrapped in PyObject types. """ -from gi.repository import GObject +try: + from gi import pygtkcompat +except ImportError: + pygtkcompat = None +if pygtkcompat is not None: + pygtkcompat.enable() + pygtkcompat.enable_gtk(version='3.0') +import gobject -class SignalManager(GObject.GObject): + +class SignalManager(gobject.GObject): """ Manages callback functions for events emitted by Geany's internal GObject. """ __gsignals__ = { - 'build-start': (GObject.SignalFlags.RUN_LAST, None, + 'build-start': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()), - 'document-activate': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'document-before-save': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'document-close': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'document-filetype-set': (GObject.SignalFlags.RUN_LAST, None, - (object, object)), - 'document-new': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'document-open': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'document-reload': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'document-save': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'editor-notify': (GObject.SignalFlags.RUN_LAST, GObject.TYPE_BOOLEAN, - (object, object)), - 'geany-startup-complete': (GObject.SignalFlags.RUN_LAST, None, + 'document-activate': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'document-before-save': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'document-close': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'document-filetype-set': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT)), + 'document-new': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'document-open': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'document-reload': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'document-save': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'editor-notify': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_BOOLEAN, + (gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT)), + 'geany-startup-complete': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()), - 'project-close': (GObject.SignalFlags.RUN_LAST, None, + 'project-close': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()), - 'project-dialog-confirmed': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'project-dialog-open': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'project-dialog-close': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'project-open': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'project-save': (GObject.SignalFlags.RUN_LAST, None, - (object,)), - 'update-editor-menu': (GObject.SignalFlags.RUN_LAST, None, - (GObject.TYPE_STRING, GObject.TYPE_INT, - object)), + 'project-dialog-confirmed': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'project-dialog-open': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'project-dialog-close': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'project-open': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'project-save': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT,)), + 'update-editor-menu': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, + (gobject.TYPE_STRING, gobject.TYPE_INT, + gobject.TYPE_PYOBJECT)), } # __gsignals__ def __init__(self): super(SignalManager, self).__init__() -GObject.type_register(SignalManager) \ No newline at end of file +gobject.type_register(SignalManager) \ No newline at end of file diff --git a/plugins/console.py b/plugins/console.py index 1bd02f1..d6bbfaf 100644 --- a/plugins/console.py +++ b/plugins/console.py @@ -1,12 +1,24 @@ +try: + from gi import pygtkcompat +except ImportError: + pygtkcompat = None + +if pygtkcompat is not None: + pygtkcompat.enable() + pygtkcompat.enable_gtk(version='3.0') + import os from ConfigParser import SafeConfigParser import geany import geany.console -from gi.repository import GObject, Gtk, Gdk, Pango +import gobject +import gtk +import gtk.gdk as gdk +import pango -WIDGET_STATES = [ Gtk.StateType.NORMAL, Gtk.StateType.ACTIVE, Gtk.StateType.PRELIGHT, - Gtk.StateType.SELECTED, Gtk.StateType.INSENSITIVE ] +WIDGET_STATES = [ gtk.STATE_NORMAL, gtk.STATE_ACTIVE, gtk.STATE_PRELIGHT, + gtk.STATE_SELECTED, gtk.STATE_INSENSITIVE ] class ConsolePlugin(geany.Plugin): @@ -45,7 +57,7 @@ def load_config(self): def save_config(self): - GObject.idle_add(self.on_save_config_timeout) + gobject.idle_add(self.on_save_config_timeout) def on_save_config_timeout(self, data=None): @@ -59,8 +71,8 @@ def install_console(self): self.banner = self.banner self.use_rl_completer = self.use_rl_completer - self.swin = Gtk.ScrolledWindow() - self.swin.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.ALWAYS) + self.swin = gtk.ScrolledWindow() + self.swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS) self.console = geany.console.Console(banner = self.banner, use_rlcompleter = self.use_rl_completer) self.console.connect("populate-popup", self.on_console_populate_popup) @@ -72,7 +84,7 @@ def install_console(self): self.swin.add(self.console) geany.main_widgets.message_window_notebook.append_page(self.swin, - Gtk.Label("Python")) + gtk.Label("Python")) self.swin.show_all() self.save_config() @@ -88,7 +100,7 @@ def _get_font(self): return self._font def _set_font(self, font): self._font = font - font_desc = Pango.FontDescription(font) + font_desc = pango.FontDescription(font) self.console.modify_font(font_desc) if not self.cfg.has_section('appearances'): self.cfg.add_section('appearances') @@ -104,7 +116,7 @@ def _get_bg(self): return self._bg def _set_bg(self, bg): self._bg = bg - color = Gdk.color_parse(self._bg) + color = gdk.color_parse(self._bg) for state in WIDGET_STATES: self.console.modify_bg(state, color) self.console.modify_base(state, color) @@ -122,7 +134,7 @@ def _get_fg(self): return self._fg def _set_fg(self, fg): self._fg = fg - color = Gdk.color_parse(self._fg) + color = gdk.color_parse(self._fg) for state in WIDGET_STATES: self.console.modify_fg(state, color) self.console.modify_text(state, color) @@ -163,10 +175,10 @@ def _set_use_rl_completer(self, use_rl_completer): def on_console_populate_popup(self, textview, menu, data=None): - item = Gtk.SeparatorMenuItem() + item = gtk.SeparatorMenuItem() item.show() menu.append(item) - item = Gtk.ImageMenuItem(stock_id=Gtk.STOCK_PREFERENCES) + item = gtk.ImageMenuItem(stock_id=gtk.STOCK_PREFERENCES) item.show() menu.append(item) item.connect("activate", lambda w,d=None: self.show_configure()) @@ -189,114 +201,114 @@ def on_bg_color_changed(self, clr_btn, data=None): def show_configure(self): - dialog = Gtk.Dialog(title="Configure Python Console", - parent=geany.main_widgets.window, - flags=Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, - buttons=(Gtk.STOCK_CLOSE, Gtk.ResponseType.ACCEPT)) + dialog = gtk.Dialog("Configure Python Console", + geany.main_widgets.window, + gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, + (gtk.STOCK_CLOSE, gtk.RESPONSE_ACCEPT)) + + #dialog.set_has_separator(True) + content_area = dialog.get_content_area() content_area.set_border_width(6) - vbox = Gtk.VBox(spacing=6) + vbox = gtk.VBox(spacing=6) vbox.set_border_width(6) - lbl = Gtk.Label() + lbl = gtk.Label() lbl.set_use_markup(True) lbl.set_markup("General") - fra_general = Gtk.Frame() - fra_general.set_shadow_type(Gtk.ShadowType.NONE) + fra_general = gtk.Frame() + fra_general.set_shadow_type(gtk.SHADOW_NONE) fra_general.set_label_widget(lbl) - al_general = Gtk.Alignment() - al_general.set(0.0, 0.0, 1.0, 1.0) + al_general = gtk.Alignment(0.0, 0.0, 1.0, 1.0) al_general.set_padding(0, 0, 12, 0) fra_general.add(al_general) - tbl = Gtk.Table(3, 2, False) + tbl = gtk.Table(3, 2, False) tbl.set_row_spacings(6) tbl.set_col_spacings(6) tbl.set_border_width(6) - lbl = Gtk.Label("Banner:") + lbl = gtk.Label("Banner:") lbl.set_alignment(0.0, 0.0) - tvw = Gtk.TextView() + tvw = gtk.TextView() tvw.get_buffer().set_text(self.banner) tvw.get_buffer().connect("changed", self.on_banner_changed) - swin = Gtk.ScrolledWindow() - swin.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) - swin.set_shadow_type(Gtk.ShadowType.ETCHED_IN) + swin = gtk.ScrolledWindow() + swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + swin.set_shadow_type(gtk.SHADOW_ETCHED_IN) swin.add(tvw) - tbl.attach(lbl, 0, 1, 0, 1, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) - tbl.attach(swin, 1, 2, 0, 1, Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL, 0, 0) + tbl.attach(lbl, 0, 1, 0, 1, gtk.FILL, gtk.FILL, 0, 0) + tbl.attach(swin, 1, 2, 0, 1, gtk.EXPAND | gtk.FILL, gtk.EXPAND | gtk.FILL, 0, 0) - lbl = Gtk.Label("") + lbl = gtk.Label("") lbl.set_alignment(0.0, 0.5) - check = Gtk.CheckButton("Use Readline") + check = gtk.CheckButton("Use Readline") if self.use_rl_completer: check.set_active(True) check.connect("toggled", self.on_use_rl_completer_toggled) - tbl.attach(lbl, 0, 1, 1, 2, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) - tbl.attach(check, 1, 2, 1, 2, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) + tbl.attach(lbl, 0, 1, 1, 2, gtk.FILL, gtk.FILL, 0, 0) + tbl.attach(check, 1, 2, 1, 2, gtk.FILL, gtk.FILL, 0, 0) - lbl = Gtk.Label("") + lbl = gtk.Label("") lbl.set_alignment(0.0, 0.5) lbl.set_use_markup(True) lbl.set_markup('' + 'Note: General settings will be applied when console is reloaded.' + '') - tbl.attach(lbl, 0, 2, 2, 3, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) + tbl.attach(lbl, 0, 2, 2, 3, gtk.FILL, gtk.FILL, 0, 0) al_general.add(tbl) - lbl = Gtk.Label() + lbl = gtk.Label() lbl.set_use_markup(True) lbl.set_markup("Appearances") - fra_appearances = Gtk.Frame() - fra_appearances.set_shadow_type(Gtk.ShadowType.NONE) + fra_appearances = gtk.Frame() + fra_appearances.set_shadow_type(gtk.SHADOW_NONE) fra_appearances.set_label_widget(lbl) - al_appearances = Gtk.Alignment() - al_appearances.set(0.0, 0.0, 1.0, 1.0) + al_appearances = gtk.Alignment(0.0, 0.0, 1.0, 1.0) al_appearances.set_padding(0, 0, 12, 0) fra_appearances.add(al_appearances) - tbl = Gtk.Table(3, 2, False) + tbl = gtk.Table(3, 2, False) tbl.set_row_spacings(6) tbl.set_col_spacings(6) tbl.set_border_width(6) - lbl = Gtk.Label("Font:") + lbl = gtk.Label("Font:") lbl.set_alignment(0.0, 0.5) - btn = Gtk.FontButton(self.font) + btn = gtk.FontButton(self.font) btn.connect("font-set", self.on_font_changed) - tbl.attach(lbl, 0, 1, 0, 1, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) - tbl.attach(btn, 1, 2, 0, 1, Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, Gtk.AttachOptions.FILL, 0, 0) + tbl.attach(lbl, 0, 1, 0, 1, gtk.FILL, gtk.FILL, 0, 0) + tbl.attach(btn, 1, 2, 0, 1, gtk.FILL | gtk.EXPAND, gtk.FILL, 0, 0) - lbl = Gtk.Label("FG Color:") + lbl = gtk.Label("FG Color:") lbl.set_alignment(0.0, 0.5) - - btn = Gtk.ColorButton(color=Gdk.color_parse(self.fg)) + btn = gtk.ColorButton(color=gdk.color_parse(self.fg)) btn.connect("color-set", self.on_fg_color_changed) - tbl.attach(lbl, 0, 1, 1, 2, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) - tbl.attach(btn, 1, 2, 1, 2, Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, Gtk.AttachOptions.FILL, 0, 0) + tbl.attach(lbl, 0, 1, 1, 2, gtk.FILL, gtk.FILL, 0, 0) + tbl.attach(btn, 1, 2, 1, 2, gtk.FILL | gtk.EXPAND, gtk.FILL, 0, 0) - lbl = Gtk.Label("BG Color:") + lbl = gtk.Label("BG Color:") lbl.set_alignment(0.0, 0.5) - btn = Gtk.ColorButton(color=Gdk.color_parse(self.bg)) + btn = gtk.ColorButton(color=gdk.color_parse(self.bg)) btn.connect("color-set", self.on_bg_color_changed) - tbl.attach(lbl, 0, 1, 2, 3, Gtk.AttachOptions.FILL, Gtk.AttachOptions.FILL, 0, 0) - tbl.attach(btn, 1, 2, 2, 3, Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, Gtk.AttachOptions.FILL, 0, 0) + tbl.attach(lbl, 0, 1, 2, 3, gtk.FILL, gtk.FILL, 0, 0) + tbl.attach(btn, 1, 2, 2, 3, gtk.FILL | gtk.EXPAND, gtk.FILL, 0, 0) al_appearances.add(tbl) diff --git a/plugins/hello.py b/plugins/hello.py index c9e2859..d6153b8 100644 --- a/plugins/hello.py +++ b/plugins/hello.py @@ -1,4 +1,12 @@ -from gi.repository import Gtk +try: + from gi import pygtkcompat +except ImportError: + pygtkcompat = None + +if pygtkcompat is not None: + pygtkcompat.enable() + pygtkcompat.enable_gtk(version='3.0') +import gtk import geany class HelloWorld(geany.Plugin): @@ -9,7 +17,7 @@ class HelloWorld(geany.Plugin): __plugin_author__ = "John Doe " def __init__(self): - self.menu_item = Gtk.MenuItem("Hello World") + self.menu_item = gtk.MenuItem("Hello World") self.menu_item.show() geany.main_widgets.tools_menu.append(self.menu_item) self.menu_item.connect("activate", self.on_hello_item_clicked) diff --git a/src/Makefile.am b/src/Makefile.am index 5e3247d..812af48 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,12 +2,21 @@ geanyplugin_LTLIBRARIES = geanypy.la geanyplugindir = $(libdir)/geany geanypy_la_LDFLAGS = -module -avoid-version -Wl,--export-dynamic +if GP_GTK3 geanypy_la_CPPFLAGS = @GEANY_CFLAGS@ @PYGOBJECT_CFLAGS@ @PYTHON_CPPFLAGS@ \ -DGEANYPY_PYTHON_DIR="\"$(libdir)/geany/geanypy\"" \ -DGEANYPY_PLUGIN_DIR="\"$(datadir)/geany/geanypy/plugins\"" \ -UHAVE_CONFIG_H geanypy_la_LIBADD = @GEANY_LIBS@ @PYGOBJECT_LIBS@ @PYTHON_LDFLAGS@ \ @PYTHON_EXTRA_LIBS@ @PYTHON_EXTRA_LDFLAGS@ +else +geanypy_la_CPPFLAGS = @GEANY_CFLAGS@ @PYGTK_CFLAGS@ @PYTHON_CPPFLAGS@ \ + -DGEANYPY_PYTHON_DIR="\"$(libdir)/geany/geanypy\"" \ + -DGEANYPY_PLUGIN_DIR="\"$(datadir)/geany/geanypy/plugins\"" \ + -UHAVE_CONFIG_H +geanypy_la_LIBADD = @GEANY_LIBS@ @PYGTK_LIBS@ @PYTHON_LDFLAGS@ \ + @PYTHON_EXTRA_LIBS@ @PYTHON_EXTRA_LDFLAGS@ +endif geanypy_la_SOURCES = geanypy-app.c \ geanypy-bindings.c \ geanypy-dialogs.c \ From 3428323686493d1956019c2345caf3eb27f17b34 Mon Sep 17 00:00:00 2001 From: Sagar Chalise Date: Mon, 6 Oct 2014 13:11:52 +0545 Subject: [PATCH 21/28] gtk3 configure and make --- configure.ac | 11 ++++------- src/Makefile.am | 16 +++------------- 2 files changed, 7 insertions(+), 20 deletions(-) diff --git a/configure.ac b/configure.ac index 7522d04..2b18609 100644 --- a/configure.ac +++ b/configure.ac @@ -6,23 +6,20 @@ AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_SRCDIR([src/geanypy-plugin.c]) AC_CONFIG_HEADERS([src/plugin-config.h]) -AM_INIT_AUTOMAKE([1.11.1 -Wall foreign]) +AM_INIT_AUTOMAKE([1.11.1 -Wall -Werror foreign]) +LT_INIT([disable-static]) # Configure build system and tools AM_SILENT_RULES([yes]) -# fix for automake >= 1.12 -m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) - # Check for utilities AC_PROG_CC AC_PROG_SED -LT_INIT([disable-static]) # Check for headers, libraries and packages AC_CHECK_HEADERS([stdio.h string.h dlfcn.h]) PKG_CHECK_MODULES([GEANY], [geany >= 0.21]) -GP_CHECK_GTK3([PKG_CHECK_MODULES([PYGOBJECT], [pygobject-3.0])], [PKG_CHECK_MODULES([PYGTK], [pygtk-2.0])]) +PKG_CHECK_MODULES([PYGOBJECT], [pygobject-3.0]) AX_PYTHON_DEVEL([>= '2.6']) AX_PYTHON_LIBRARY(,[AC_MSG_ERROR([Cannot determine location of the Python DSO])]) AC_SUBST([PYTHON]) @@ -40,4 +37,4 @@ AC_CONFIG_FILES([ geany/Makefile plugins/Makefile ]) -AC_OUTPUT +AC_OUTPUT \ No newline at end of file diff --git a/src/Makefile.am b/src/Makefile.am index 86c8105..5e3247d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,30 +2,20 @@ geanyplugin_LTLIBRARIES = geanypy.la geanyplugindir = $(libdir)/geany geanypy_la_LDFLAGS = -module -avoid-version -Wl,--export-dynamic -if GP_GTK3 geanypy_la_CPPFLAGS = @GEANY_CFLAGS@ @PYGOBJECT_CFLAGS@ @PYTHON_CPPFLAGS@ \ -DGEANYPY_PYTHON_DIR="\"$(libdir)/geany/geanypy\"" \ -DGEANYPY_PLUGIN_DIR="\"$(datadir)/geany/geanypy/plugins\"" \ -UHAVE_CONFIG_H geanypy_la_LIBADD = @GEANY_LIBS@ @PYGOBJECT_LIBS@ @PYTHON_LDFLAGS@ \ @PYTHON_EXTRA_LIBS@ @PYTHON_EXTRA_LDFLAGS@ -else -geanypy_la_CPPFLAGS = @GEANY_CFLAGS@ @PYGTK_CFLAGS@ @PYTHON_CPPFLAGS@ \ - -DGEANYPY_PYTHON_DIR="\"$(libdir)/geany/geanypy\"" \ - -DGEANYPY_PLUGIN_DIR="\"$(datadir)/geany/geanypy/plugins\"" \ - -UHAVE_CONFIG_H -geanypy_la_LIBADD = @GEANY_LIBS@ @PYGTK_LIBS@ @PYTHON_LDFLAGS@ \ - @PYTHON_EXTRA_LIBS@ @PYTHON_EXTRA_LDFLAGS@ -endif geanypy_la_SOURCES = geanypy-app.c \ geanypy-bindings.c \ geanypy-dialogs.c \ geanypy-document.c geanypy-document.h \ geanypy-editor.c geanypy-editor.h \ geanypy-encoding.c geanypy-encoding.h \ - geanypy-filetypes.c geanypy-filetypes.h \ - geanypy-glog.c \ - geanypy.h \ + geanypy-filetypes.c \ + geanypy-geanypy.h \ geanypy-highlighting.c \ geanypy-indentprefs.c \ geanypy-interfaceprefs.c \ @@ -42,4 +32,4 @@ geanypy_la_SOURCES = geanypy-app.c \ geanypy-search.c \ geanypy-signalmanager.c geanypy-signalmanager.h \ geanypy-templates.c \ - geanypy-uiutils.c geanypy-uiutils.h + geanypy-uiutils.c geanypy-uiutils.h \ No newline at end of file From 8dadf0c9f9b3d2c66f05b28344cffa672b890219 Mon Sep 17 00:00:00 2001 From: Sagar Chalise Date: Mon, 6 Oct 2014 14:26:51 +0545 Subject: [PATCH 22/28] Gtk2 and gtk3 compatabilities --- configure.ac | 9 ++++++--- src/Makefile.am | 7 ++++--- src/geanypy.h | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/configure.ac b/configure.ac index 2b18609..cc1254b 100644 --- a/configure.ac +++ b/configure.ac @@ -6,15 +6,18 @@ AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_SRCDIR([src/geanypy-plugin.c]) AC_CONFIG_HEADERS([src/plugin-config.h]) -AM_INIT_AUTOMAKE([1.11.1 -Wall -Werror foreign]) -LT_INIT([disable-static]) +AM_INIT_AUTOMAKE([1.11.1 -Wall foreign]) # Configure build system and tools AM_SILENT_RULES([yes]) +# fix for automake >= 1.12 +m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) + # Check for utilities AC_PROG_CC AC_PROG_SED +LT_INIT([disable-static]) # Check for headers, libraries and packages AC_CHECK_HEADERS([stdio.h string.h dlfcn.h]) @@ -37,4 +40,4 @@ AC_CONFIG_FILES([ geany/Makefile plugins/Makefile ]) -AC_OUTPUT \ No newline at end of file +AC_OUTPUT diff --git a/src/Makefile.am b/src/Makefile.am index 5e3247d..b887484 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -14,8 +14,9 @@ geanypy_la_SOURCES = geanypy-app.c \ geanypy-document.c geanypy-document.h \ geanypy-editor.c geanypy-editor.h \ geanypy-encoding.c geanypy-encoding.h \ - geanypy-filetypes.c \ - geanypy-geanypy.h \ + geanypy-filetypes.c geanypy-filetypes.h \ + geanypy-glog.h \ + geanypy.h \ geanypy-highlighting.c \ geanypy-indentprefs.c \ geanypy-interfaceprefs.c \ @@ -32,4 +33,4 @@ geanypy_la_SOURCES = geanypy-app.c \ geanypy-search.c \ geanypy-signalmanager.c geanypy-signalmanager.h \ geanypy-templates.c \ - geanypy-uiutils.c geanypy-uiutils.h \ No newline at end of file + geanypy-uiutils.c geanypy-uiutils.h diff --git a/src/geanypy.h b/src/geanypy.h index 168d7d6..f198213 100644 --- a/src/geanypy.h +++ b/src/geanypy.h @@ -117,4 +117,4 @@ extern "C" { } /* extern "C" */ #endif -#endif /* GEANYPY_H__ */ \ No newline at end of file +#endif /* GEANYPY_H__ */ From ed481b11e70cb5cfb45a8b83ea2e2d1a6afb6ae2 Mon Sep 17 00:00:00 2001 From: Sagar Chalise Date: Wed, 11 Mar 2015 23:43:56 +0545 Subject: [PATCH 23/28] IN newer gobject issue with PyGObject --- configure.ac | 2 ++ src/geanypy-uiutils.c | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index cc1254b..0b188b9 100644 --- a/configure.ac +++ b/configure.ac @@ -41,3 +41,5 @@ AC_CONFIG_FILES([ plugins/Makefile ]) AC_OUTPUT +m4_pattern_allow([AM_PROG_AR]) +AM_PROG_AR \ No newline at end of file diff --git a/src/geanypy-uiutils.c b/src/geanypy-uiutils.c index 99f2e2e..0a5840c 100644 --- a/src/geanypy-uiutils.c +++ b/src/geanypy-uiutils.c @@ -3,7 +3,7 @@ #define GOB_CHECK(pyobj, arg) \ { \ - if (!pyobj || pyobj == Py_None || !pygobject_check(pyobj, PyGObject_Type)) \ + if (!pyobj || pyobj == Py_None || !pygobject_check(pyobj, PyGobject_Type)) \ { \ PyErr_SetString(PyExc_ValueError, \ "argument " #arg " must inherit from a gobject.GObject type"); \ @@ -23,7 +23,7 @@ } -static PyTypeObject *PyGObject_Type = NULL; +static PyTypeObject *PyGobject_Type = NULL; static PyObject * @@ -429,7 +429,7 @@ PyMODINIT_FUNC initui_utils(void) #endif if (m) { - PyGObject_Type = (PyTypeObject *) PyObject_GetAttrString(m, "GObject"); + PyGobject_Type = (PyTypeObject *) PyObject_GetAttrString(m, "GObject"); Py_XDECREF(m); } InterfacePrefsType.tp_new = PyType_GenericNew; From a6b995b05526be598d7627e2fd37301228b77e38 Mon Sep 17 00:00:00 2001 From: Sagar Chalise Date: Wed, 11 Mar 2015 23:44:13 +0545 Subject: [PATCH 24/28] IN newer gobject issue with PyGObject --- src/geanypy-uiutils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/geanypy-uiutils.c b/src/geanypy-uiutils.c index 0a5840c..4d2718e 100644 --- a/src/geanypy-uiutils.c +++ b/src/geanypy-uiutils.c @@ -429,7 +429,7 @@ PyMODINIT_FUNC initui_utils(void) #endif if (m) { - PyGobject_Type = (PyTypeObject *) PyObject_GetAttrString(m, "GObject"); + PyGobject_Type = (PyTypeObject *) PyObject_GetAttrString(m, "_PyGObject_API"); Py_XDECREF(m); } InterfacePrefsType.tp_new = PyType_GenericNew; From 767bba63f4a5f73c5344c139aa0b0510c1dcd462 Mon Sep 17 00:00:00 2001 From: Sagar Chalise Date: Thu, 12 Mar 2015 00:01:51 +0545 Subject: [PATCH 25/28] GLOG c file not header --- src/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index b887484..d926ea2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -15,7 +15,7 @@ geanypy_la_SOURCES = geanypy-app.c \ geanypy-editor.c geanypy-editor.h \ geanypy-encoding.c geanypy-encoding.h \ geanypy-filetypes.c geanypy-filetypes.h \ - geanypy-glog.h \ + geanypy-glog.c \ geanypy.h \ geanypy-highlighting.c \ geanypy-indentprefs.c \ @@ -33,4 +33,4 @@ geanypy_la_SOURCES = geanypy-app.c \ geanypy-search.c \ geanypy-signalmanager.c geanypy-signalmanager.h \ geanypy-templates.c \ - geanypy-uiutils.c geanypy-uiutils.h + geanypy-uiutils.c geanypy-uiutils.h \ No newline at end of file From 5e5e59b179b802b8f0b8cbe04ae573e6ac9127b2 Mon Sep 17 00:00:00 2001 From: Sagar Chalise Date: Thu, 12 Mar 2015 00:14:34 +0545 Subject: [PATCH 26/28] initialize glog --- src/geanypy-plugin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/geanypy-plugin.c b/src/geanypy-plugin.c index 88bb68a..2a5b059 100644 --- a/src/geanypy-plugin.c +++ b/src/geanypy-plugin.c @@ -282,4 +282,4 @@ G_MODULE_EXPORT void plugin_cleanup(void) GeanyPy_stop_interpreter(); gtk_widget_destroy(loader_item); g_free(plugin_dir); -} +} \ No newline at end of file From 740cdd007cdaf381e82379017c854fbfe345419e Mon Sep 17 00:00:00 2001 From: Sagar Chalise Date: Mon, 7 Dec 2015 18:35:10 +0545 Subject: [PATCH 27/28] unload all plugins --- geany/manager.py | 6 +++++- src/geanypy-plugin.c | 13 ++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/geany/manager.py b/geany/manager.py index 3e05e79..2a004c8 100644 --- a/geany/manager.py +++ b/geany/manager.py @@ -103,6 +103,10 @@ def activate_plugin(self, filename): def deactivate_plugin(self, filename): self.loader.unload_plugin(filename) + + def deactivate_all_plugins(self): + self.response(gtk.RESPONSE_CLOSE) + self.loader.unload_all_plugins() def load_plugins_list(self): @@ -187,4 +191,4 @@ def on_plugin_load_toggled(self, cell, path, model): def on_row_activated(self, tvw, path, view_col, cell, model): - self.on_plugin_load_toggled(cell, path, model) \ No newline at end of file + self.on_plugin_load_toggled(cell, path, model) diff --git a/src/geanypy-plugin.c b/src/geanypy-plugin.c index 2a5b059..c96d52f 100644 --- a/src/geanypy-plugin.c +++ b/src/geanypy-plugin.c @@ -277,9 +277,20 @@ plugin_init(GeanyData *data) G_MODULE_EXPORT void plugin_cleanup(void) { + PyObject* deactivate_all_plugins = PyObject_GetAttrString(manager, + "deactivate_all_plugins"); + if (deactivate_all_plugins != NULL) + { + PyObject* r = PyObject_CallObject(deactivate_all_plugins, NULL); + if (r) + Py_DECREF(r); + Py_DECREF(deactivate_all_plugins); + + } + signal_manager_free(signal_manager); Py_XDECREF(manager); GeanyPy_stop_interpreter(); gtk_widget_destroy(loader_item); g_free(plugin_dir); -} \ No newline at end of file +} From f1476cb1df97d5d894eb2dbd4780811d5bf5c26f Mon Sep 17 00:00:00 2001 From: Sagar Chalise Date: Fri, 15 Jan 2016 23:17:21 +0545 Subject: [PATCH 28/28] Upstream changes --- src/geanypy-encoding.c | 109 ----------------------------------------- src/geanypy-encoding.h | 10 ---- 2 files changed, 119 deletions(-) diff --git a/src/geanypy-encoding.c b/src/geanypy-encoding.c index 8ffa5fa..a1fc21b 100644 --- a/src/geanypy-encoding.c +++ b/src/geanypy-encoding.c @@ -1,94 +1,6 @@ #include "geanypy.h" -static void -Encoding_dealloc(Encoding *self) -{ - g_return_if_fail(self != NULL); - self->ob_type->tp_free((PyObject *) self); -} - - -static int -Encoding_init(Encoding *self) -{ - g_return_val_if_fail(self != NULL, -1); - self->encoding = NULL; - return 0; -} - - -static PyObject * -Encoding_get_property(Encoding *self, const gchar *prop_name) -{ - g_return_val_if_fail(self != NULL, NULL); - g_return_val_if_fail(prop_name != NULL, NULL); - - if (!self->encoding) - { - PyErr_SetString(PyExc_RuntimeError, - "Encoding instance not initialized properly"); - return NULL; - } - - if (g_str_equal(prop_name, "charset") && self->encoding->charset) - return PyString_FromString(self->encoding->charset); - else if (g_str_equal(prop_name, "group")) - return PyInt_FromLong((glong) self->encoding->group); - else if (g_str_equal(prop_name, "idx")) - return PyInt_FromLong((glong) self->encoding->idx); - else if (g_str_equal(prop_name, "name") && self->encoding->name) - return PyString_FromString(self->encoding->name); - else if (g_str_equal(prop_name, "order")) - return PyInt_FromLong((glong) self->encoding->order); - - Py_RETURN_NONE; -} -GEANYPY_PROPS_READONLY(Encoding); - - -static PyGetSetDef Encoding_getseters[] = { - GEANYPY_GETSETDEF(Encoding, "charset", - "String representation of the encoding, ex. 'ISO-8859-3'."), - GEANYPY_GETSETDEF(Encoding, "group", - "Internally used member for grouping (see encoding.GROUP_* constants)."), - GEANYPY_GETSETDEF(Encoding, "idx", - "The index of the encoding, (see encoding.* constants, not encoding.GROUP_*)."), - GEANYPY_GETSETDEF(Encoding, "name", - "Translatable and descriptive name of the encoding, ex 'South European'."), - GEANYPY_GETSETDEF(Encoding, "order", - "Internally used member for grouping."), - { NULL } -}; - - -PyTypeObject EncodingType = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "geany.encoding.Encoding", /* tp_name */ - sizeof(Encoding), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor) Encoding_dealloc, /* tp_dealloc */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* tp_print - tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - "Wrapper around a GeanyEncoding structure.", /* tp_doc */ - 0, 0, 0, 0, 0, 0, 0, 0, /* tp_traverse - tp_members */ - Encoding_getseters, /* tp_getset */ - 0, 0, 0, 0, 0, /* tp_base - tp_dictoffset */ - (initproc) Encoding_init, /* tp_init */ - 0, 0, /* tp_alloc - tp_new */ -}; - - -Encoding *Encoding_create_new_from_geany_encoding(GeanyEncoding *enc) -{ - Encoding *self; - self = (Encoding *) PyObject_CallObject((PyObject *) &EncodingType, NULL); - self->encoding = enc; - return self; -} - - static PyObject * Encodings_convert_to_utf8(PyObject *module, PyObject *args, PyObject *kwargs) { @@ -156,17 +68,6 @@ Encodings_get_charset_from_index(PyObject *module, PyObject *args, PyObject *kwa } -static const gchar *encoding_groups[] = { - "GROUP_NONE", - "GROUP_WEST_EUROPEAN", - "GROUP_EAST_EUROPEAN", - "GROUP_EAST_ASIAN", - "GROUP_ASIAN", - "GROUP_MIDDLE_EASTERN", - "GROUP_UNICODE" -}; - - static const gchar *encoding_names[] = { "ISO_8859_1", "ISO_8859_2", @@ -292,19 +193,9 @@ initencoding(void) int i; PyObject *m; - EncodingType.tp_new = PyType_GenericNew; - if (PyType_Ready(&EncodingType) < 0) - return; - m = Py_InitModule3("encoding", EncodingsModule_methods, "Encoding conversion functions."); - Py_INCREF(&EncodingType); - PyModule_AddObject(m, "Encoding", (PyObject *) &EncodingType); - for (i = 0; i < GEANY_ENCODINGS_MAX; i++) PyModule_AddIntConstant(m, encoding_names[i], (glong) i); - - for (i = 0; i < GEANY_ENCODING_GROUPS_MAX; i++) - PyModule_AddIntConstant(m, encoding_groups[i], (glong) i); } diff --git a/src/geanypy-encoding.h b/src/geanypy-encoding.h index 1c586c1..caea0a1 100644 --- a/src/geanypy-encoding.h +++ b/src/geanypy-encoding.h @@ -1,14 +1,4 @@ #ifndef GEANYPY_ENCODING_H__ #define GEANYPY_ENCODING_H__ -PyTypeObject EncodingType; - -typedef struct -{ - PyObject_HEAD - GeanyEncoding *encoding; -} Encoding; - -Encoding *Encoding_create_new_from_geany_encoding(GeanyEncoding *enc); - #endif /* GEANYPY_ENCODING_H__ */