Esempio n. 1
0
 def double_click(self, widget, item, column):
     print "DEBUG double_click"
     if not column == item.ENTRY_COLUMN:
         return
     if item.entry:
         item.entry.grab_focus()
         return
     item.entry_buffer.set_property('cursor-visible', True)
     hbox = gtk.HBox(False)
     align = gtk.Alignment(0, 0, 1, 1)
     entry = Entry()
     entry.set_data("item", item)
     entry.set_data("button_press", False)
     entry.set_buffer(item.entry_buffer)
     entry.set_size_request(item.get_column_widths()[column]-4, 0)
     entry.connect("press-return", lambda w: hbox.destroy())
     entry.connect("destroy", self.edit_done, hbox, item)
     entry.connect_after("focus-in-event", self.entry_focus_changed, item)
     entry.connect_after("focus-out-event", self.entry_focus_changed, item)
     self.pack_start(hbox, False, False)
     self.set_data("entry_widget", entry)
     hbox.pack_start(entry, False, False)
     hbox.pack_start(align)
     hbox.show_all()
     entry.set_can_focus(True)
     entry.grab_focus()
     entry.select_all()
     item.entry = entry
Esempio n. 2
0
class WindowHelper:
	def __init__(self, plugin, window):
		self._window = window
		self._plugin = plugin
		self._entry = None
		
		self._accel = gtk.AccelGroup()
		self._accel.connect_group(gtk.keysyms.C, gtk.gdk.SUPER_MASK, 0, self._do_command)
		self._window.add_accel_group(self._accel)
	
	def deactivate(self):
		self._window.remove_accel_group(self._accel)
		self._window = None
		self._plugin = None

	def update_ui(self):
		pass
	
	def _do_command(self, group, obj, keyval, mod):
		view = self._window.get_active_view()
		
		if not view:
			return False

		if not self._entry:
			self._entry = Entry(self._window.get_active_view())
			self._entry.connect('destroy', self.on_entry_destroy)

		self._entry.grab_focus()
		return True
	
	def on_entry_destroy(self, widget):
		self._entry = None
Esempio n. 3
0
 def double_click(self, widget, item, column):
     print "DEBUG double_click"
     if not column == item.ENTRY_COLUMN:
         return
     if item.entry:
         item.entry.grab_focus()
         return
     item.entry_buffer.set_property('cursor-visible', True)
     hbox = gtk.HBox(False)
     align = gtk.Alignment(0, 0, 1, 1)
     entry = Entry()
     entry.set_data("item", item)
     entry.set_data("button_press", False)
     entry.set_buffer(item.entry_buffer)
     entry.set_size_request(item.get_column_widths()[column] - 4, 0)
     entry.connect("press-return", lambda w: hbox.destroy())
     entry.connect("destroy", self.edit_done, hbox, item)
     entry.connect_after("focus-in-event", self.entry_focus_changed, item)
     entry.connect_after("focus-out-event", self.entry_focus_changed, item)
     self.pack_start(hbox, False, False)
     self.set_data("entry_widget", entry)
     hbox.pack_start(entry, False, False)
     hbox.pack_start(align)
     hbox.show_all()
     entry.set_can_focus(True)
     entry.grab_focus()
     entry.select_all()
     item.entry = entry
Esempio n. 4
0
class WindowActivatable(GObject.Object, Gedit.WindowActivatable):
    __gtype_name__ = "CommanderWindowActivatable"

    window = GObject.property(type=Gedit.Window)

    def __init__(self):
        GObject.Object.__init__(self)

    def do_activate(self):
        self._entry = None
        self._view = None

        self.install_ui()

    def do_deactivate(self):
        self.uninstall_ui()

    def do_update_state(self):
        pass

    def install_ui(self):
        manager = self.window.get_ui_manager()

        self._action_group = Gtk.ActionGroup("GeditCommanderPluginActions")
        self._action_group.add_toggle_actions([('CommanderModeAction', None,
                                               _('Commander Mode'), '<Ctrl>period',
                                               _('Start commander mode'), self.on_commander_mode)])

        manager.insert_action_group(self._action_group, -1)
        self._merge_id = manager.add_ui_from_string(ui_str)

    def uninstall_ui(self):
        manager = self.window.get_ui_manager()
        manager.remove_ui(self._merge_id)
        manager.remove_action_group(self._action_group)

        manager.ensure_update()

    def on_commander_mode(self, action, user_data=None):
        view = self.window.get_active_view()

        if not view:
            return False

        if action.get_active():
            if not self._entry or view != self._view:
                self._entry = Entry(view)
                self._entry.connect('destroy', self.on_entry_destroy)

            self._entry.grab_focus()
            self._view = view
        elif self._entry:
            self._entry.destroy()
            self._view = None

        return True

    def on_entry_destroy(self, widget, user_data=None):
        self._entry = None
        self._action_group.get_action('CommanderModeAction').set_active(False)
class WindowHelper:
    def __init__(self, plugin, window):
        self._window = window
        self._plugin = plugin
        self._entry = None
        self._view = None

        self.install_ui()

    def install_ui(self):
        manager = self._window.get_ui_manager()

        self._action_group = gtk.ActionGroup("PlumaCommanderPluginActions")
        self._action_group.add_toggle_actions([
            ('CommanderModeAction', None, _('Commander Mode'), '<Ctrl>period',
             _('Start commander mode'), self.on_commander_mode)
        ])

        manager.insert_action_group(self._action_group, -1)
        self._merge_id = manager.add_ui_from_string(ui_str)

    def uninstall_ui(self):
        manager = self._window.get_ui_manager()
        manager.remove_ui(self._merge_id)
        manager.remove_action_group(self._action_group)

        manager.ensure_update()

    def deactivate(self):
        self.uninstall_ui()

        self._window = None
        self._plugin = None

    def update_ui(self):
        pass

    def on_commander_mode(self, action):
        view = self._window.get_active_view()

        if not view:
            return False

        if action.get_active():
            if not self._entry or view != self._view:
                self._entry = Entry(view)
                self._entry.connect('destroy', self.on_entry_destroy)

            self._entry.grab_focus()
            self._view = view
        elif self._entry:
            self._entry.destroy()
            self._view = None

        return True

    def on_entry_destroy(self, widget):
        self._entry = None
        self._action_group.get_action('CommanderModeAction').set_active(False)
class WindowHelper:
	def __init__(self, plugin, window):
		self._window = window
		self._plugin = plugin
		self._entry = None
		self._view = None

		self.install_ui()

	def install_ui(self):
		manager = self._window.get_ui_manager()

		self._action_group = gtk.ActionGroup("PlumaCommanderPluginActions")
		self._action_group.add_toggle_actions([('CommanderModeAction', None, _('Commander Mode'), '<Ctrl>period', _('Start commander mode'), self.on_commander_mode)])

		manager.insert_action_group(self._action_group, -1)
		self._merge_id = manager.add_ui_from_string(ui_str)

	def uninstall_ui(self):
		manager = self._window.get_ui_manager()
		manager.remove_ui(self._merge_id)
		manager.remove_action_group(self._action_group)

		manager.ensure_update()

	def deactivate(self):
		self.uninstall_ui()

		self._window = None
		self._plugin = None

	def update_ui(self):
		pass

	def on_commander_mode(self, action):
		view = self._window.get_active_view()

		if not view:
			return False

		if action.get_active():
			if not self._entry or view != self._view:
				self._entry = Entry(view)
				self._entry.connect('destroy', self.on_entry_destroy)

			self._entry.grab_focus()
			self._view = view
		elif self._entry:
			self._entry.destroy()
			self._view = None

		return True

	def on_entry_destroy(self, widget):
		self._entry = None
		self._action_group.get_action('CommanderModeAction').set_active(False)
class CommanderWindowActivatable(GObject.Object, Gedit.WindowActivatable):

    window = GObject.property(type=Gedit.Window)

    def __init__(self):
        GObject.Object.__init__(self)

    def do_activate(self):
        self._entry = None
        self._view = None

        action = Gio.SimpleAction.new_stateful("commander", None, GLib.Variant.new_boolean(False))
        action.connect('activate', self.activate_toggle)
        action.connect('change-state', self.commander_mode)
        self.window.add_action(action)

    def do_deactivate(self):
        self.window.remove_action("commander")

    def do_update_state(self):
        pass

    def activate_toggle(self, action, parameter):
        state = action.get_state()
        action.change_state(GLib.Variant.new_boolean(not state.get_boolean()))

    def commander_mode(self, action, state):
        view = self.window.get_active_view()

        if not view:
            return False

        active = state.get_boolean()
        if active:
            if not self._entry or view != self._view:
                self._entry = Entry(view)
                self._entry.connect('destroy', self.on_entry_destroy)

            self._entry.grab_focus()
            self._view = view
        elif self._entry:
            self._entry.destroy()
            self._view = None

        action.set_state(GLib.Variant.new_boolean(active))

        return True

    def on_entry_destroy(self, widget, user_data=None):
        self._entry = None
        self.window.lookup_action("commander").change_state(GLib.Variant.new_boolean(False))
class WindowHelper:
    def __init__(self, plugin, window):
        self._window = window
        self._plugin = plugin
        self._entry = None
        accel_path = '<gedit>/plugins/commander/activate'

        accel = gtk.accel_map_lookup_entry(accel_path)

        if accel == None:
            gtk.accel_map_add_entry(accel_path, gtk.keysyms.period,
                                    gtk.gdk.CONTROL_MASK)

        self._accel = gtk.AccelGroup()
        self._accel.connect_by_path(accel_path, self._do_command)
        self._window.add_accel_group(self._accel)

    def deactivate(self):
        self._window.remove_accel_group(self._accel)
        self._window = None
        self._plugin = None

    def update_ui(self):
        pass

    def _do_command(self, group, obj, keyval, mod):
        view = self._window.get_active_view()

        if not view:
            return False

        if not self._entry:
            self._entry = Entry(self._window.get_active_view())
            self._entry.connect('destroy', self.on_entry_destroy)

        self._entry.grab_focus()
        return True

    def on_entry_destroy(self, widget):
        self._entry = None
class WindowHelper:
	def __init__(self, plugin, window):
		self._window = window
		self._plugin = plugin
		self._entry = None
		accel_path = '<gedit>/plugins/commander/activate'

		accel = gtk.accel_map_lookup_entry(accel_path)

		if accel == None:
			gtk.accel_map_add_entry(accel_path, gtk.keysyms.period, gtk.gdk.CONTROL_MASK)

		self._accel = gtk.AccelGroup()
		self._accel.connect_by_path(accel_path, self._do_command)
		self._window.add_accel_group(self._accel)
	
	def deactivate(self):
		self._window.remove_accel_group(self._accel)
		self._window = None
		self._plugin = None

	def update_ui(self):
		pass
	
	def _do_command(self, group, obj, keyval, mod):
		view = self._window.get_active_view()
		
		if not view:
			return False

		if not self._entry:
			self._entry = Entry(self._window.get_active_view())
			self._entry.connect('destroy', self.on_entry_destroy)

		self._entry.grab_focus()
		return True
	
	def on_entry_destroy(self, widget):
		self._entry = None
Esempio n. 10
0
class SpinBox(gtk.VBox):
    '''
    SpinBox.

    @undocumented: set_sensitive
    @undocumented: size_change_cb
    @undocumented: press_increase_button
    @undocumented: press_decrease_button
    @undocumented: handle_key_release
    @undocumented: stop_update_value
    @undocumented: increase_value
    @undocumented: decrease_value
    @undocumented: adjust_value
    @undocumented: update
    @undocumented: update_and_emit
    @undocumented: expose_spin_bg
    @undocumented: create_simple_button
    '''

    __gsignals__ = {
        "value-changed":
        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_INT, )),
        "key-release":
        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_INT, )),
    }

    def __init__(
        self,
        value=0,
        lower=0,
        upper=100,
        step=10,
        default_width=55,
        check_text=is_float,
    ):
        '''
        Initialize SpinBox class.

        @param value: Initialize value, default is 0.
        @param lower: Lower value, default is 0.
        @param upper: Upper value, default is 100.
        @param step: Step value, default is 10.
        @param default_width: Default with, default is 55 pixel.
        @param check_text: The check function, default is is_float to check value is float.
        '''
        gtk.VBox.__init__(self)
        self.current_value = value
        self.lower_value = lower
        self.upper_value = upper
        self.step_value = step
        self.update_delay = 100  # milliseconds
        self.increase_value_id = None
        self.decrease_value_id = None

        # Init.
        self.default_width = default_width
        self.default_height = 22
        self.arrow_button_width = 19
        self.background_color = ui_theme.get_alpha_color(
            "text_entry_background")
        self.acme_color = ui_theme.get_alpha_color("text_entry_acme")
        self.point_color = ui_theme.get_alpha_color("text_entry_point")
        self.frame_point_color = ui_theme.get_alpha_color(
            "text_entry_frame_point")
        self.frame_color = ui_theme.get_alpha_color("text_entry_frame")

        # Widget.
        arrow_up_button = self.create_simple_button("up",
                                                    self.press_increase_button)
        arrow_down_button = self.create_simple_button(
            "down", self.press_decrease_button)
        button_box = gtk.VBox()
        button_box.pack_start(arrow_up_button, False, False)
        button_box.pack_start(arrow_down_button, False, False)
        self.value_entry = Entry(str(value))
        self.value_entry.check_text = check_text
        self.value_entry.connect(
            "press-return",
            lambda entry: self.update_and_emit(int(entry.get_text())))

        self.main_align = gtk.Alignment()
        self.main_align.set(0.5, 0.5, 0, 0)
        hbox = gtk.HBox()
        hbox.pack_start(self.value_entry, False, False)
        hbox.pack_start(button_box, False, False)
        hbox_align = gtk.Alignment()
        hbox_align.set(0.5, 0.5, 1.0, 1.0)
        hbox_align.set_padding(0, 1, 0, 0)
        hbox_align.add(hbox)
        self.main_align.add(hbox_align)
        self.pack_start(self.main_align, False, False)

        # Signals.
        self.connect("size-allocate", self.size_change_cb)
        self.main_align.connect("expose-event", self.expose_spin_bg)

    def set_sensitive(self, sensitive):
        '''
        Internal function to wrap `set_sensitive`.
        '''
        super(SpinBox, self).set_sensitive(sensitive)
        self.value_entry.set_sensitive(sensitive)

    def get_value(self):
        '''
        Get current value.

        @return: Return current value.
        '''
        return self.current_value

    def set_value(self, value):
        '''
        Set value with given value.

        @param value: New value.
        '''
        new_value = self.adjust_value(value)
        if new_value != self.current_value:
            self.update_and_emit(new_value)

    def value_changed(self):
        '''
        Emit `value-changed` signal.
        '''
        self.emit("value-changed", self.current_value)

    def get_lower(self):
        '''
        Get minimum value.
        '''
        return self.lower_value

    def set_lower(self, value):
        '''
        Set lower with given value.

        @param value: New lower value.
        '''
        self.lower_value = value

    def get_upper(self):
        '''
        Get upper value.
        '''
        return self.upper_value

    def set_upper(self, value):
        '''
        Set upper with given value.

        @param value: New upper value.
        '''
        self.upper_value = value

    def get_step(self):
        '''
        Get step.
        '''
        return self.step_value

    def set_step(self, value):
        '''
        Set step with given value.

        @param value: New step value.
        '''
        self.set_step = value

    def size_change_cb(self, widget, rect):
        '''
        Internal callback for `size-allocate` signal.
        '''
        if rect.width > self.default_width:
            self.default_width = rect.width

        self.set_size_request(self.default_width, self.default_height)
        self.value_entry.set_size_request(
            self.default_width - self.arrow_button_width,
            self.default_height - 2)

    def press_increase_button(self, widget, event):
        '''
        Internal callback when user press increase arrow.
        '''
        # self.stop_update_value()

        self.increase_value()

        # self.increase_value_id = gtk.timeout_add(self.update_delay, self.increase_value)

    def press_decrease_button(self, widget, event):
        '''
        Internal callback when user press decrease arrow.
        '''
        # self.stop_update_value()

        self.decrease_value()

        # self.decrease_value_id = gtk.timeout_add(self.update_delay, self.decrease_value)

    def handle_key_release(self, widget, event):
        '''
        Internal callback for `key-release-event` signal.
        '''
        self.stop_update_value()

        self.emit("key-release", self.current_value)

    def stop_update_value(self):
        '''
        Internal function to stop update value.
        '''
        for timeout_id in [self.increase_value_id, self.decrease_value_id]:
            remove_timeout_id(timeout_id)

    def increase_value(self):
        '''
        Internal function to increase value.
        '''
        new_value = self.current_value + self.step_value
        if new_value > self.upper_value:
            new_value = self.upper_value
        if new_value != self.current_value:
            self.update_and_emit(new_value)

        return True

    def decrease_value(self):
        '''
        Internal function to decrease value.
        '''
        new_value = self.current_value - self.step_value
        if new_value < self.lower_value:
            new_value = self.lower_value
        if new_value != self.current_value:
            self.update_and_emit(new_value)

        return True

    def adjust_value(self, value):
        '''
        Internal function to adjust value.
        '''
        if not isinstance(value, int):
            return self.current_value
        else:
            if value < self.lower_value:
                return self.lower_value
            elif value > self.upper_value:
                return self.upper_value
            else:
                return value

    def update(self, new_value):
        '''
        Internal function to update value, just use when need avoid emit signal recursively.
        '''
        self.current_value = new_value
        self.value_entry.set_text(str(self.current_value))

    def update_and_emit(self, new_value):
        '''
        Internal function to update new value and emit `value-changed` signal.
        '''
        self.current_value = new_value
        self.value_entry.set_text(str(self.current_value))
        self.emit("value-changed", self.current_value)

    def expose_spin_bg(self, widget, event):
        '''
        Internal callback for `expose-event` signal.
        '''
        # Init.
        cr = widget.window.cairo_create()
        rect = widget.allocation
        x, y, w, h = rect.x, rect.y, rect.width, rect.height

        # Draw frame.
        with cairo_disable_antialias(cr):
            cr.set_line_width(1)
            if widget.state == gtk.STATE_INSENSITIVE:
                cr.set_source_rgb(*color_hex_to_cairo(
                    ui_theme.get_color("disable_frame").get_color()))
            else:
                cr.set_source_rgb(*color_hex_to_cairo(
                    ui_theme.get_color("combo_entry_frame").get_color()))
            cr.rectangle(rect.x, rect.y, rect.width, rect.height)
            cr.stroke()

            if widget.state == gtk.STATE_INSENSITIVE:
                cr.set_source_rgba(*alpha_color_hex_to_cairo((
                    ui_theme.get_color("disable_background").get_color(),
                    0.9)))
            else:
                cr.set_source_rgba(*alpha_color_hex_to_cairo((
                    ui_theme.get_color("combo_entry_background").get_color(),
                    0.9)))
            cr.rectangle(rect.x, rect.y, rect.width - 1, rect.height - 1)
            cr.fill()

        propagate_expose(widget, event)

        return False

    def create_simple_button(self, name, callback=None):
        '''
        Internal function to create simple button.
        '''
        button = DisableButton(
            (ui_theme.get_pixbuf("spin/spin_arrow_%s_normal.png" % name),
             ui_theme.get_pixbuf("spin/spin_arrow_%s_hover.png" % name),
             ui_theme.get_pixbuf("spin/spin_arrow_%s_press.png" % name),
             ui_theme.get_pixbuf("spin/spin_arrow_%s_disable.png" % name)), )
        if callback:
            button.connect("button-press-event", callback)
            button.connect("button-release-event", self.handle_key_release)
        return button
Esempio n. 11
0
class SpinBox(gtk.VBox):
    '''
    SpinBox.

    @undocumented: set_sensitive
    @undocumented: size_change_cb
    @undocumented: press_increase_button
    @undocumented: press_decrease_button
    @undocumented: handle_key_release
    @undocumented: stop_update_value
    @undocumented: increase_value
    @undocumented: decrease_value
    @undocumented: adjust_value
    @undocumented: update
    @undocumented: update_and_emit
    @undocumented: expose_spin_bg
    @undocumented: create_simple_button
    '''

    __gsignals__ = {
        "value-changed" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_INT,)),
        "key-release" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_INT,)),
        }

    def __init__(self,
                 value=0,
                 lower=0,
                 upper=100,
                 step=10,
                 default_width=55,
                 check_text=is_float,
                 ):
        '''
        Initialize SpinBox class.

        @param value: Initialize value, default is 0.
        @param lower: Lower value, default is 0.
        @param upper: Upper value, default is 100.
        @param step: Step value, default is 10.
        @param default_width: Default with, default is 55 pixel.
        @param check_text: The check function, default is is_float to check value is float.
        '''
        gtk.VBox.__init__(self)
        self.current_value = value
        self.lower_value = lower
        self.upper_value = upper
        self.step_value  = step
        self.update_delay = 100 # milliseconds
        self.increase_value_id = None
        self.decrease_value_id = None

        # Init.
        self.default_width = default_width
        self.default_height = 22
        self.arrow_button_width = 19
        self.background_color = ui_theme.get_alpha_color("text_entry_background")
        self.acme_color = ui_theme.get_alpha_color("text_entry_acme")
        self.point_color = ui_theme.get_alpha_color("text_entry_point")
        self.frame_point_color = ui_theme.get_alpha_color("text_entry_frame_point")
        self.frame_color = ui_theme.get_alpha_color("text_entry_frame")

        # Widget.
        arrow_up_button = self.create_simple_button("up", self.press_increase_button)
        arrow_down_button = self.create_simple_button("down", self.press_decrease_button)
        button_box = gtk.VBox()
        button_box.pack_start(arrow_up_button, False, False)
        button_box.pack_start(arrow_down_button, False, False)
        self.value_entry = Entry(str(value))
        self.value_entry.check_text = check_text
        self.value_entry.connect("press-return", lambda entry: self.update_and_emit(int(entry.get_text())))

        self.main_align = gtk.Alignment()
        self.main_align.set(0.5, 0.5, 0, 0)
        hbox = gtk.HBox()
        hbox.pack_start(self.value_entry, False, False)
        hbox.pack_start(button_box, False, False)
        hbox_align = gtk.Alignment()
        hbox_align.set(0.5, 0.5, 1.0, 1.0)
        hbox_align.set_padding(0, 1, 0, 0)
        hbox_align.add(hbox)
        self.main_align.add(hbox_align)
        self.pack_start(self.main_align, False, False)

        # Signals.
        self.connect("size-allocate", self.size_change_cb)
        self.main_align.connect("expose-event", self.expose_spin_bg)

    def set_sensitive(self, sensitive):
        '''
        Internal function to wrap `set_sensitive`.
        '''
        super(SpinBox, self).set_sensitive(sensitive)
        self.value_entry.set_sensitive(sensitive)

    def get_value(self):
        '''
        Get current value.

        @return: Return current value.
        '''
        return self.current_value

    def set_value(self, value):
        '''
        Set value with given value.

        @param value: New value.
        '''
        new_value = self.adjust_value(value)
        if new_value != self.current_value:
            self.update_and_emit(new_value)

    def value_changed(self):
        '''
        Emit `value-changed` signal.
        '''
        self.emit("value-changed", self.current_value)

    def get_lower(self):
        '''
        Get minimum value.
        '''
        return self.lower_value

    def set_lower(self, value):
        '''
        Set lower with given value.

        @param value: New lower value.
        '''
        self.lower_value = value

    def get_upper(self):
        '''
        Get upper value.
        '''
        return self.upper_value

    def set_upper(self, value):
        '''
        Set upper with given value.

        @param value: New upper value.
        '''
        self.upper_value = value

    def get_step(self):
        '''
        Get step.
        '''
        return self.step_value

    def set_step(self, value):
        '''
        Set step with given value.

        @param value: New step value.
        '''
        self.set_step = value

    def size_change_cb(self, widget, rect):
        '''
        Internal callback for `size-allocate` signal.
        '''
        if rect.width > self.default_width:
            self.default_width = rect.width

        self.set_size_request(self.default_width, self.default_height)
        self.value_entry.set_size_request(self.default_width - self.arrow_button_width, self.default_height - 2)

    def press_increase_button(self, widget, event):
        '''
        Internal callback when user press increase arrow.
        '''
        # self.stop_update_value()

        self.increase_value()

        # self.increase_value_id = gtk.timeout_add(self.update_delay, self.increase_value)

    def press_decrease_button(self, widget, event):
        '''
        Internal callback when user press decrease arrow.
        '''
        # self.stop_update_value()

        self.decrease_value()

        # self.decrease_value_id = gtk.timeout_add(self.update_delay, self.decrease_value)

    def handle_key_release(self, widget, event):
        '''
        Internal callback for `key-release-event` signal.
        '''
        self.stop_update_value()

        self.emit("key-release", self.current_value)

    def stop_update_value(self):
        '''
        Internal function to stop update value.
        '''
        for timeout_id in [self.increase_value_id, self.decrease_value_id]:
            remove_timeout_id(timeout_id)

    def increase_value(self):
        '''
        Internal function to increase value.
        '''
        new_value = self.current_value + self.step_value
        if new_value > self.upper_value:
            new_value = self.upper_value
        if new_value != self.current_value:
            self.update_and_emit(new_value)

        return True

    def decrease_value(self):
        '''
        Internal function to decrease value.
        '''
        new_value = self.current_value - self.step_value
        if new_value < self.lower_value:
            new_value = self.lower_value
        if new_value != self.current_value:
            self.update_and_emit(new_value)

        return True

    def adjust_value(self, value):
        '''
        Internal function to adjust value.
        '''
        if not isinstance(value, int):
            return self.current_value
        else:
            if value < self.lower_value:
                return self.lower_value
            elif value > self.upper_value:
                return self.upper_value
            else:
                return value

    def update(self, new_value):
        '''
        Internal function to update value, just use when need avoid emit signal recursively.
        '''
        self.current_value = new_value
        self.value_entry.set_text(str(self.current_value))

    def update_and_emit(self, new_value):
        '''
        Internal function to update new value and emit `value-changed` signal.
        '''
        self.current_value = new_value
        self.value_entry.set_text(str(self.current_value))
        self.emit("value-changed", self.current_value)

    def expose_spin_bg(self, widget, event):
        '''
        Internal callback for `expose-event` signal.
        '''
        # Init.
        cr = widget.window.cairo_create()
        rect = widget.allocation
        x, y, w, h = rect.x, rect.y, rect.width, rect.height

        # Draw frame.
        with cairo_disable_antialias(cr):
            cr.set_line_width(1)
            if widget.state == gtk.STATE_INSENSITIVE:
                cr.set_source_rgb(*color_hex_to_cairo(ui_theme.get_color("disable_frame").get_color()))
            else:
                cr.set_source_rgb(*color_hex_to_cairo(ui_theme.get_color("combo_entry_frame").get_color()))
            cr.rectangle(rect.x, rect.y, rect.width, rect.height)
            cr.stroke()

            if widget.state == gtk.STATE_INSENSITIVE:
                cr.set_source_rgba(*alpha_color_hex_to_cairo((ui_theme.get_color("disable_background").get_color(), 0.9)))
            else:
                cr.set_source_rgba(*alpha_color_hex_to_cairo((ui_theme.get_color("combo_entry_background").get_color(), 0.9)))
            cr.rectangle(rect.x, rect.y, rect.width - 1, rect.height - 1)
            cr.fill()

        propagate_expose(widget, event)

        return False

    def create_simple_button(self, name, callback=None):
        '''
        Internal function to create simple button.
        '''
        button = DisableButton(
            (ui_theme.get_pixbuf("spin/spin_arrow_%s_normal.png" % name),
             ui_theme.get_pixbuf("spin/spin_arrow_%s_hover.png" % name),
             ui_theme.get_pixbuf("spin/spin_arrow_%s_press.png" % name),
             ui_theme.get_pixbuf("spin/spin_arrow_%s_disable.png" % name)),
            )
        if callback:
            button.connect("button-press-event", callback)
            button.connect("button-release-event", self.handle_key_release)
        return button
class Jumper(gobject.GObject):
	def __init__(self, plugin, window):
		gobject.GObject.__init__(self)

		self._window = window
		self._plugin = plugin

		self._entry = None
		self._accel = gtk.AccelGroup()
		self._accel.connect_group(gtk.keysyms.comma, gtk.gdk.CONTROL_MASK, 0, self.init_entry)
		self._window.add_accel_group(self._accel)

	def deactivate(self):
		self._window.remove_accel_group(self._accel)
		self._entry = None

		self._window = None
		self._plugin = None

	def init_entry(self, group, obj, keyval, mod):
		view = self._window.get_active_view()

		if not view:
			return False

		if not self._entry:
			self._entry = Entry(self._window.get_active_view(), "pattern:")
			self._entry.connect("execute", self.on_entry_execute)
			self._entry.connect("destroy", self.on_entry_destroy)

		self._entry.grab_focus()
		return True

	def on_entry_destroy(self, widget):
		self._entry = None
		if self.get_data("labels"):
			for k, v in self.get_data("labels").items():
				v[0].destroy()

	def on_entry_execute(self, widget):
		if self._entry.read_label() == "pattern:":
			return self.handle_pattern()
		else:
			return self.handle_shortcut()

	def handle_pattern(self):
		value = self._entry.read_input()
		regex = re.compile(value)
		view  = self._window.get_active_view()
		ha    = view.get_hadjustment()
		va    = view.get_vadjustment()
		doc   = view.get_buffer()
		if doc is not None:
			code = doc.get_text(*doc.get_bounds()).decode("utf-8")

			self.set_data("labels", {})
			i  = 0

			vp = va.get_value()
			hp = ha.get_value()

			for match in regex.finditer(code):
				iter = doc.get_iter_at_offset( match.start() )
				location = view.get_iter_location(iter)
				key  = SHORTCUT_LABELS[i]
				i    = i + 1

				label = gtk.Label()
				label.modify_font(view.style.font_desc)
				label.set_markup(key)

				eb = gtk.EventBox()
				eb.add(label)
				eb.show_all()

				self.get_data("labels")[key] = [eb, iter]
				view.add_child_in_window(eb, gtk.TEXT_WINDOW_TEXT, int(location.x - hp), int(location.y - vp))

			self._entry.update_label("jump to:")
			self._entry.clear_input()

	def handle_shortcut(self):
		view = self._window.get_active_view()
		key  = self._entry.read_input().strip()

		view.get_buffer().place_cursor( self.get_data("labels")[key][1] )
		view.grab_focus()