summaryrefslogtreecommitdiff
path: root/plugins/externaltools/tools/manager.py
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/externaltools/tools/manager.py')
-rwxr-xr-xplugins/externaltools/tools/manager.py207
1 files changed, 118 insertions, 89 deletions
diff --git a/plugins/externaltools/tools/manager.py b/plugins/externaltools/tools/manager.py
index 4d4d50aa..c0656cb8 100755
--- a/plugins/externaltools/tools/manager.py
+++ b/plugins/externaltools/tools/manager.py
@@ -18,23 +18,22 @@
__all__ = ('Manager', )
-import pluma
-import gtk
-import gtksourceview2 as gsv
import os.path
from library import *
from functions import *
import hashlib
from xml.sax import saxutils
-import gobject
+from gi.repository import GObject, Gio, Gdk, Gtk, GtkSource, Pluma
+
+class LanguagesPopup(Gtk.Window):
+ __gtype_name__ = "LanguagePopup"
-class LanguagesPopup(gtk.Window):
COLUMN_NAME = 0
COLUMN_ID = 1
COLUMN_ENABLED = 2
def __init__(self, languages):
- gtk.Window.__init__(self, gtk.WINDOW_POPUP)
+ Gtk.Window.__init__(self, type=Gtk.WindowType.POPUP)
self.set_default_size(200, 200)
self.props.can_focus = True
@@ -43,44 +42,61 @@ class LanguagesPopup(gtk.Window):
self.init_languages(languages)
self.show()
- self.map()
self.grab_add()
- gtk.gdk.keyboard_grab(self.window, False, 0L)
- gtk.gdk.pointer_grab(self.window, False, gtk.gdk.BUTTON_PRESS_MASK |
- gtk.gdk.BUTTON_RELEASE_MASK |
- gtk.gdk.POINTER_MOTION_MASK |
- gtk.gdk.ENTER_NOTIFY_MASK |
- gtk.gdk.LEAVE_NOTIFY_MASK |
- gtk.gdk.PROXIMITY_IN_MASK |
- gtk.gdk.PROXIMITY_OUT_MASK, None, None, 0L)
+ self.keyboard = None
+ device_manager = Gdk.Display.get_device_manager(self.get_window().get_display())
+ for device in device_manager.list_devices(Gdk.DeviceType.MASTER):
+ if device.get_source() == Gdk.InputSource.KEYBOARD:
+ self.keyboard = device
+ break
+
+ self.pointer = device_manager.get_client_pointer()
+
+ if self.keyboard is not None:
+ self.keyboard.grab(self.get_window(),
+ Gdk.GrabOwnership.WINDOW, False,
+ Gdk.EventMask.KEY_PRESS_MASK |
+ Gdk.EventMask.KEY_RELEASE_MASK,
+ None, Gdk.CURRENT_TIME)
+ self.pointer.grab(self.get_window(),
+ Gdk.GrabOwnership.WINDOW, False,
+ Gdk.EventMask.BUTTON_PRESS_MASK |
+ Gdk.EventMask.BUTTON_RELEASE_MASK |
+ Gdk.EventMask.POINTER_MOTION_MASK |
+ Gdk.EventMask.ENTER_NOTIFY_MASK |
+ Gdk.EventMask.LEAVE_NOTIFY_MASK |
+ Gdk.EventMask.PROXIMITY_IN_MASK |
+ Gdk.EventMask.PROXIMITY_OUT_MASK |
+ Gdk.EventMask.SCROLL_MASK,
+ None, Gdk.CURRENT_TIME)
self.view.get_selection().select_path((0,))
def build(self):
- self.model = gtk.ListStore(str, str, bool)
+ self.model = Gtk.ListStore(str, str, bool)
- self.sw = gtk.ScrolledWindow()
+ self.sw = Gtk.ScrolledWindow()
self.sw.show()
- self.sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- self.sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
+ self.sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
+ self.sw.set_shadow_type(Gtk.ShadowType.ETCHED_IN)
- self.view = gtk.TreeView(self.model)
+ self.view = Gtk.TreeView(self.model)
self.view.show()
self.view.set_headers_visible(False)
- column = gtk.TreeViewColumn()
+ column = Gtk.TreeViewColumn()
- renderer = gtk.CellRendererToggle()
+ renderer = Gtk.CellRendererToggle()
column.pack_start(renderer, False)
column.set_attributes(renderer, active=self.COLUMN_ENABLED)
renderer.connect('toggled', self.on_language_toggled)
- renderer = gtk.CellRendererText()
+ renderer = Gtk.CellRendererText()
column.pack_start(renderer, True)
column.set_attributes(renderer, text=self.COLUMN_NAME)
@@ -94,7 +110,7 @@ class LanguagesPopup(gtk.Window):
def enabled_languages(self, model, path, piter, ret):
enabled = model.get_value(piter, self.COLUMN_ENABLED)
- if path == (0,) and enabled:
+ if path.get_indices()[0] == 0 and enabled:
return True
if enabled:
@@ -113,8 +129,9 @@ class LanguagesPopup(gtk.Window):
return val == '-'
def init_languages(self, languages):
- manager = gsv.LanguageManager()
- langs = pluma.language_manager_list_languages_sorted(manager, True)
+ manager = GtkSource.LanguageManager()
+ langs = [manager.get_language(x) for x in manager.get_language_ids()]
+ langs.sort(key=lambda x: x.get_name())
self.model.append([_('All languages'), None, not languages])
self.model.append(['-', None, False])
@@ -142,7 +159,7 @@ class LanguagesPopup(gtk.Window):
self.model.set_value(self.model.get_iter_first(), self.COLUMN_ENABLED, False)
def do_key_press_event(self, event):
- if event.keyval == gtk.keysyms.Escape:
+ if event.keyval == Gdk.KEY_Escape:
self.destroy()
return True
else:
@@ -155,34 +172,35 @@ class LanguagesPopup(gtk.Window):
def in_window(self, event, window=None):
if not window:
- window = self.window
+ window = self.get_window()
geometry = window.get_geometry()
origin = window.get_origin()
- return event.x_root >= origin[0] and \
- event.x_root <= origin[0] + geometry[2] and \
- event.y_root >= origin[1] and \
- event.y_root <= origin[1] + geometry[3]
+ return event.x_root >= origin[1] and \
+ event.x_root <= origin[1] + geometry[2] and \
+ event.y_root >= origin[2] and \
+ event.y_root <= origin[2] + geometry[3]
def do_destroy(self):
- gtk.gdk.keyboard_ungrab(0L)
- gtk.gdk.pointer_ungrab(0L)
+ if self.keyboard:
+ self.keyboard.ungrab(Gdk.CURRENT_TIME)
+ self.pointer.ungrab(Gdk.CURRENT_TIME)
- return gtk.Window.do_destroy(self)
+ return Gtk.Window.do_destroy(self)
def setup_event(self, event, window):
fr = event.window.get_origin()
to = window.get_origin()
event.window = window
- event.x += fr[0] - to[0]
- event.y += fr[1] - to[1]
+ event.x += fr[1] - to[1]
+ event.y += fr[2] - to[2]
def resolve_widgets(self, root):
res = [root]
- if isinstance(root, gtk.Container):
+ if isinstance(root, Gtk.Container):
root.forall(lambda x, y: res.extend(self.resolve_widgets(x)), None)
return res
@@ -196,14 +214,14 @@ class LanguagesPopup(gtk.Window):
return res
- def propagate_mouse_event(self, event):
+ def propagate_mouse_event(self, event, reverse=True):
allwidgets = self.resolve_widgets(self.get_child())
- allwidgets.reverse()
-
- orig = [event.x, event.y]
+
+ if reverse:
+ allwidgets.reverse()
for widget in allwidgets:
- windows = self.resolve_windows(widget.window)
+ windows = self.resolve_windows(widget.get_window())
windows.reverse()
for window in windows:
@@ -231,7 +249,7 @@ class LanguagesPopup(gtk.Window):
return self.propagate_mouse_event(event)
def do_scroll_event(self, event):
- return self.propagate_mouse_event(event)
+ return self.propagate_mouse_event(event, False)
def do_motion_notify_event(self, event):
return self.propagate_mouse_event(event)
@@ -248,25 +266,33 @@ class LanguagesPopup(gtk.Window):
def do_proximity_out_event(self, event):
return self.propagate_mouse_event(event)
-gobject.type_register(LanguagesPopup)
-
-class Manager:
+class Manager(GObject.Object):
TOOL_COLUMN = 0 # For Tree
NAME_COLUMN = 1 # For Combo
+ __gsignals__ = {
+ 'tools-updated': (GObject.SignalFlags.RUN_LAST, None, ())
+ }
+
def __init__(self, datadir):
+ GObject.Object.__init__(self)
self.datadir = datadir
self.dialog = None
+ self._size = (0, 0)
self._languages = {}
self._tool_rows = {}
self.build()
+
+ def get_final_size(self):
+ return self._size
def build(self):
callbacks = {
'on_new_tool_button_clicked' : self.on_new_tool_button_clicked,
'on_remove_tool_button_clicked' : self.on_remove_tool_button_clicked,
'on_tool_manager_dialog_response' : self.on_tool_manager_dialog_response,
+ 'on_tool_manager_dialog_configure_event': self.on_tool_manager_dialog_configure_event,
'on_tool_manager_dialog_focus_out': self.on_tool_manager_dialog_focus_out,
'on_accelerator_key_press' : self.on_accelerator_key_press,
'on_accelerator_focus_in' : self.on_accelerator_focus_in,
@@ -275,7 +301,7 @@ class Manager:
}
# Load the "main-window" widget from the ui file.
- self.ui = gtk.Builder()
+ self.ui = Gtk.Builder()
self.ui.add_from_file(os.path.join(self.datadir, 'ui', 'tools.ui'))
self.ui.connect_signals(callbacks)
self.dialog = self.ui.get_object('tool-manager-dialog')
@@ -345,7 +371,7 @@ class Manager:
del self.accelerators[shortcut]
def add_tool_to_language(self, tool, language):
- if isinstance(language, gsv.Language):
+ if isinstance(language, GtkSource.Language):
lid = language.get_id()
else:
lid = language
@@ -353,7 +379,7 @@ class Manager:
if not lid in self._languages:
piter = self.model.append(None, [language])
- parent = gtk.TreeRowReference(self.model, self.model.get_path(piter))
+ parent = Gtk.TreeRowReference.new(self.model, self.model.get_path(piter))
self._languages[lid] = parent
else:
parent = self._languages[lid]
@@ -364,11 +390,11 @@ class Manager:
if not tool in self._tool_rows:
self._tool_rows[tool] = []
- self._tool_rows[tool].append(gtk.TreeRowReference(self.model, self.model.get_path(child)))
+ self._tool_rows[tool].append(Gtk.TreeRowReference.new(self.model, self.model.get_path(child)))
return child
def add_tool(self, tool):
- manager = gsv.LanguageManager()
+ manager = GtkSource.LanguageManager()
ret = None
for lang in tool.languages:
@@ -391,16 +417,16 @@ class Manager:
self.script_hash = None
self.accelerators = dict()
- self.model = gtk.TreeStore(object)
+ self.model = Gtk.TreeStore(object)
self.view.set_model(self.model)
for tool in self.tools.tree.tools:
self.add_tool(tool)
self.model.set_default_sort_func(self.sort_tools)
- self.model.set_sort_column_id(-1, gtk.SORT_ASCENDING)
+ self.model.set_sort_column_id(-1, Gtk.SortType.ASCENDING)
- def sort_tools(self, model, iter1, iter2):
+ def sort_tools(self, model, iter1, iter2, user_data=None):
# For languages, sort All before everything else, otherwise alphabetical
t1 = model.get_value(iter1, self.TOOL_COLUMN)
t2 = model.get_value(iter2, self.TOOL_COLUMN)
@@ -413,7 +439,7 @@ class Manager:
return 1
def lang_name(lang):
- if isinstance(lang, gsv.Language):
+ if isinstance(lang, GtkSource.Language):
return lang.get_name()
else:
return _('Plain Text')
@@ -428,13 +454,13 @@ class Manager:
def __init_tools_view(self):
# Tools column
- column = gtk.TreeViewColumn('Tools')
- renderer = gtk.CellRendererText()
+ column = Gtk.TreeViewColumn('Tools')
+ renderer = Gtk.CellRendererText()
column.pack_start(renderer, False)
renderer.set_property('editable', True)
self.view.append_column(column)
- column.set_cell_data_func(renderer, self.get_cell_data_cb)
+ column.set_cell_data_func(renderer, self.get_cell_data_cb, None)
renderer.connect('edited', self.on_view_label_cell_edited)
renderer.connect('editing-started', self.on_view_label_cell_editing_started)
@@ -493,7 +519,8 @@ class Manager:
self.current_node.save_files = combo_value(self, 'save-files')
buf = self['commands'].get_buffer()
- script = buf.get_text(*buf.get_bounds())
+ (start, end) = buf.get_bounds()
+ script = buf.get_text(start, end, False)
h = self.compute_hash(script)
if h != self.script_hash:
# script has changed -> save it
@@ -521,7 +548,7 @@ class Manager:
if not self.current_node or not self.current_node.languages:
self['languages_label'].set_text(_('All Languages'))
else:
- manager = gsv.LanguageManager()
+ manager = GtkSource.LanguageManager()
langs = []
for lang in self.current_node.languages:
@@ -547,8 +574,8 @@ class Manager:
buf.end_not_undoable_action()
self.script_hash = self.compute_hash(script)
- contenttype = gio.content_type_guess(data=script)
- lmanager = pluma.get_language_manager()
+ contenttype, uncertain = Gio.content_type_guess(None, script)
+ lmanager = GtkSource.LanguageManager.get_default()
language = lmanager.guess_language(content_type=contenttype)
if language is not None:
@@ -605,7 +632,7 @@ class Manager:
piter = self.model.iter_parent(piter)
tool = self.model.get_value(piter, self.TOOL_COLUMN)
- if isinstance(tool, gsv.Language):
+ if isinstance(tool, GtkSource.Language):
return tool.get_id()
elif tool:
return 'plain'
@@ -712,7 +739,7 @@ class Manager:
piter = self.model.get_iter(path)
tool = self.model.get_value(piter, self.TOOL_COLUMN)
- if isinstance(editable, gtk.Entry):
+ if isinstance(editable, Gtk.Entry):
editable.set_text(tool.name)
editable.grab_focus()
@@ -742,7 +769,7 @@ class Manager:
# Check whether accelerator already exists
self.remove_accelerator(self.current_node)
- name = gtk.accelerator_name(keyval, mod)
+ name = Gtk.accelerator_name(keyval, mod)
if name == '':
self.current_node.shorcut = None
@@ -752,10 +779,10 @@ class Manager:
col = self.accelerator_collision(name, self.current_node)
if col:
- dialog = gtk.MessageDialog(self.dialog,
- gtk.DIALOG_MODAL,
- gtk.MESSAGE_ERROR,
- gtk.BUTTONS_OK,
+ dialog = Gtk.MessageDialog(self.dialog,
+ Gtk.DialogFlags.MODAL,
+ Gtk.MessageType.ERROR,
+ Gtk.ButtonsType.CLOSE,
_('This accelerator is already bound to %s') % (', '.join(map(lambda x: x.name, col)),))
dialog.run()
@@ -771,20 +798,20 @@ class Manager:
return True
def on_accelerator_key_press(self, entry, event):
- mask = event.state & gtk.accelerator_get_default_mod_mask()
+ mask = event.state & Gtk.accelerator_get_default_mod_mask()
- if event.keyval == gtk.keysyms.Escape:
+ if event.keyval == Gdk.KEY_Escape:
entry.set_text(default(self.current_node.shortcut, ''))
self['commands'].grab_focus()
return True
- elif event.keyval == gtk.keysyms.Delete \
- or event.keyval == gtk.keysyms.BackSpace:
+ elif event.keyval == Gdk.KEY_Delete \
+ or event.keyval == Gdk.KEY_BackSpace:
entry.set_text('')
self.remove_accelerator(self.current_node)
self.current_node.shortcut = None
self['commands'].grab_focus()
return True
- elif event.keyval in range(gtk.keysyms.F1, gtk.keysyms.F12 + 1):
+ elif event.keyval in range(Gdk.KEY_F1, Gdk.KEY_F12 + 1):
# New accelerator
if self.set_accelerator(event.keyval, mask):
entry.set_text(default(self.current_node.shortcut, ''))
@@ -792,7 +819,7 @@ class Manager:
# Capture all `normal characters`
return True
- elif gtk.gdk.keyval_to_unicode(event.keyval):
+ elif Gdk.keyval_to_unicode(event.keyval):
if mask:
# New accelerator
if self.set_accelerator(event.keyval, mask):
@@ -817,8 +844,8 @@ class Manager:
self.tool_changed(self.current_node)
def on_tool_manager_dialog_response(self, dialog, response):
- if response == gtk.RESPONSE_HELP:
- pluma.help_display(self.dialog, 'pluma', 'pluma-external-tools-plugin')
+ if response == Gtk.ResponseType.HELP:
+ Pluma.help_display(self.dialog, 'pluma', 'pluma-external-tools-plugin')
return
self.on_tool_manager_dialog_focus_out(dialog, None)
@@ -827,20 +854,22 @@ class Manager:
self.dialog = None
self.tools = None
+ def on_tool_manager_dialog_configure_event(self, dialog, event):
+ if dialog.get_realized():
+ alloc = dialog.get_allocation()
+ self._size = (alloc.width, alloc.height)
+
def on_tool_manager_dialog_focus_out(self, dialog, event):
self.save_current_tool()
+ self.emit('tools-updated')
- for window in pluma.app_get_default().get_windows():
- helper = window.get_data("ExternalToolsPluginWindowData")
- helper.menu.update()
-
- def get_cell_data_cb(self, column, cell, model, piter):
+ def get_cell_data_cb(self, column, cell, model, piter, user_data=None):
tool = model.get_value(piter, self.TOOL_COLUMN)
if tool == None or not isinstance(tool, Tool):
if tool == None:
label = _('All Languages')
- elif not isinstance(tool, gsv.Language):
+ elif not isinstance(tool, GtkSource.Language):
label = _('Plain Text')
else:
label = tool.get_name()
@@ -869,7 +898,7 @@ class Manager:
for row in self._tool_rows[tool]:
path = row.get_path()
- if path[0] == parent[0]:
+ if path.get_indices()[0] == parent.get_indices()[0]:
return True
return False
@@ -882,7 +911,7 @@ class Manager:
ret = None
if node:
- ref = gtk.TreeRowReference(self.model, self.model.get_path(piter))
+ ref = Gtk.TreeRowReference(self.model, self.model.get_path(piter))
# Update languages, make sure to inhibit selection change stuff
self.view.get_selection().handler_block(self.selection_changed_id)
@@ -908,7 +937,7 @@ class Manager:
del self._languages[language]
# Now, add for any that are new
- manager = gsv.LanguageManager()
+ manager = GtkSource.LanguageManager()
for lang in self.current_node.languages:
if not self.tool_in_language(self.current_node, lang):
@@ -940,8 +969,8 @@ class Manager:
popup = LanguagesPopup(self.current_node.languages)
popup.set_transient_for(self.dialog)
- origin = button.window.get_origin()
- popup.move(origin[0], origin[1] - popup.allocation.height)
+ origin = button.get_window().get_origin()
+ popup.move(origin[1], origin[2] - popup.get_allocation().height)
popup.connect('destroy', self.update_languages)