~ubuntu-branches/ubuntu/trusty/gedit-plugins/trusty-proposed

« back to all changes in this revision

Viewing changes to plugins/colorpicker/colorpicker.py

  • Committer: Package Import Robot
  • Author(s): Robert Ancell
  • Date: 2012-09-20 10:44:09 UTC
  • mfrom: (1.4.10)
  • Revision ID: package-import@ubuntu.com-20120920104409-2mnmhan1tst7olxy
Tags: 3.5.2-0ubuntu1
New upstream bugfix release

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
#  This file is part of gedit-plugins
4
4
#
5
5
#  Copyright (C) 2006 Jesse van den Kieboom
 
6
#  Copyright (C) 2012 Ignacio Casal Quinteiro
6
7
#
7
8
#  This program is free software; you can redistribute it and/or modify
8
9
#  it under the terms of the GNU General Public License as published by
16
17
#
17
18
#  You should have received a copy of the GNU General Public License
18
19
#  along with this program; if not, write to the Free Software
19
 
#  Foundation, Inc., 59 Temple Place, Suite 330,
20
 
#  Boston, MA 02111-1307, USA.
 
20
#  Foundation, Inc., 51 Franklin Street, Fifth Floor,
 
21
#  Boston, MA 02110-1301, USA.
21
22
 
22
23
from gi.repository import GObject, Gtk, Gdk, Gedit
23
24
import re
42
43
</ui>
43
44
"""
44
45
 
45
 
class ColorPickerPlugin(GObject.Object, Gedit.WindowActivatable):
46
 
    __gtype_name__ = "ColorPickerPlugin"
47
 
 
48
 
    window = GObject.property(type=Gedit.Window)
49
 
 
50
 
    def __init__(self):
51
 
        GObject.Object.__init__(self)
52
 
        self._dialog = None
53
 
 
54
 
    def do_activate(self):
55
 
        self._insert_menu()
56
 
        self._update()
57
 
 
58
 
    def do_deactivate(self):
59
 
        self._remove_menu()
60
 
 
61
 
    def do_update_state(self):
62
 
        self._update()
63
 
 
64
 
    def _update(self):
65
 
        tab = self.window.get_active_tab()
66
 
        self._action_group.set_sensitive(tab != None)
67
 
 
68
 
        if not tab and self._dialog and \
69
 
                self._dialog.get_transient_for() == self.window:
70
 
            self._dialog.response(Gtk.ResponseType.CLOSE)
71
 
 
72
 
    def _insert_menu(self):
73
 
        manager = self.window.get_ui_manager()
74
 
        self._action_group = Gtk.ActionGroup(name="GeditColorPickerPluginActions")
75
 
        self._action_group.add_actions(
76
 
                [("ColorPicker", None, _("Pick _Color..."), None,
77
 
                 _("Pick a color from a dialog"),
78
 
                 lambda a: self.on_color_picker_activate())])
79
 
 
80
 
        manager.insert_action_group(self._action_group)
81
 
        self._ui_id = manager.add_ui_from_string(ui_str)
82
 
 
83
 
    def _remove_menu(self):
84
 
        manager = self.window.get_ui_manager()
85
 
        manager.remove_ui(self._ui_id)
86
 
        manager.remove_action_group(self._action_group)
87
 
        manager.ensure_update()
 
46
class ColorHelper:
 
47
 
 
48
    def scale_color_component(self, component):
 
49
        return min(max(int(round(component * 255.)), 0), 255)
88
50
 
89
51
    def skip_hex(self, buf, iter, next_char):
90
52
        while True:
101
63
            if not next_char(iter):
102
64
                return
103
65
 
104
 
    def get_rgba_position(self, buf):
 
66
    def get_rgba_position(self, buf, use_bounds):
105
67
        bounds = buf.get_selection_bounds()
106
68
        if bounds == ():
 
69
            if use_bounds:
 
70
                return None
 
71
 
107
72
            # No selection, find color in the current cursor position
108
73
            start = buf.get_iter_at_mark(buf.get_insert())
109
74
 
128
93
 
129
94
        return start, end
130
95
 
131
 
    def insert_color(self, text):
132
 
        view = self.window.get_active_view()
133
 
 
 
96
    def insert_color(self, view, text):
134
97
        if not view or not view.get_editable():
135
98
            return
136
99
 
142
105
        doc.begin_user_action()
143
106
 
144
107
        # Get the color
145
 
        bounds = self.get_rgba_position(doc)
 
108
        bounds = self.get_rgba_position(doc, False)
146
109
 
147
110
        if not bounds:
148
111
            doc.delete_selection(False, True)
153
116
 
154
117
        doc.end_user_action()
155
118
 
156
 
    def scale_color_component(self, component):
157
 
        return min(max(int(round(component * 255.)), 0), 255)
158
 
 
159
 
    def get_current_color(self):
160
 
        doc = self.window.get_active_document()
161
 
 
 
119
    def get_current_color(self, doc, use_bounds):
162
120
        if not doc:
163
121
            return None
164
122
 
165
 
        bounds = self.get_rgba_position(doc)
 
123
        bounds = self.get_rgba_position(doc, use_bounds)
166
124
 
167
125
        if bounds:
168
126
            return doc.get_text(bounds[0], bounds[1], False)
169
127
        else:
170
128
            return None
171
129
 
 
130
class ColorPickerWindowActivatable(GObject.Object, Gedit.WindowActivatable):
 
131
 
 
132
    window = GObject.property(type=Gedit.Window)
 
133
 
 
134
    def __init__(self):
 
135
        GObject.Object.__init__(self)
 
136
        self._dialog = None
 
137
        self._color_helper = ColorHelper()
 
138
 
 
139
    def do_activate(self):
 
140
        self._insert_menu()
 
141
        self._update()
 
142
 
 
143
    def do_deactivate(self):
 
144
        self._remove_menu()
 
145
 
 
146
    def do_update_state(self):
 
147
        self._update()
 
148
 
 
149
    def _update(self):
 
150
        tab = self.window.get_active_tab()
 
151
        self._action_group.set_sensitive(tab != None)
 
152
 
 
153
        if not tab and self._dialog and \
 
154
                self._dialog.get_transient_for() == self.window:
 
155
            self._dialog.response(Gtk.ResponseType.CLOSE)
 
156
 
 
157
    def _insert_menu(self):
 
158
        manager = self.window.get_ui_manager()
 
159
        self._action_group = Gtk.ActionGroup(name="GeditColorPickerPluginActions")
 
160
        self._action_group.add_actions(
 
161
                [("ColorPicker", None, _("Pick _Color..."), None,
 
162
                 _("Pick a color from a dialog"),
 
163
                 lambda a: self.on_color_picker_activate())])
 
164
 
 
165
        manager.insert_action_group(self._action_group)
 
166
        self._ui_id = manager.add_ui_from_string(ui_str)
 
167
 
 
168
    def _remove_menu(self):
 
169
        manager = self.window.get_ui_manager()
 
170
        manager.remove_ui(self._ui_id)
 
171
        manager.remove_action_group(self._action_group)
 
172
        manager.ensure_update()
 
173
 
172
174
    # Signal handlers
173
175
 
174
176
    def on_color_picker_activate(self):
177
179
 
178
180
            self._dialog.connect_after('response', self.on_dialog_response)
179
181
 
180
 
        rgba_str = self.get_current_color()
 
182
        rgba_str = self._color_helper.get_current_color(self.window.get_active_document(), False)
181
183
 
182
184
        if rgba_str:
183
185
            rgba = Gdk.RGBA()
193
195
            rgba = Gdk.RGBA()
194
196
            dialog.get_rgba(rgba)
195
197
 
196
 
            self.insert_color("%02x%02x%02x" % (self.scale_color_component(rgba.red), \
197
 
                                                self.scale_color_component(rgba.green), \
198
 
                                                self.scale_color_component(rgba.blue)))
 
198
            self._color_helper.insert_color(self.window.get_active_view(),
 
199
                                            "%02x%02x%02x" % (self._color_helper.scale_color_component(rgba.red), \
 
200
                                                              self._color_helper.scale_color_component(rgba.green), \
 
201
                                                              self._color_helper.scale_color_component(rgba.blue)))
199
202
        else:
200
203
            self._dialog.destroy()
201
204
            self._dialog = None
202
205
 
 
206
 
 
207
class ColorPickerViewActivatable(GObject.Object, Gedit.ViewActivatable):
 
208
 
 
209
    view = GObject.property(type=Gedit.View)
 
210
 
 
211
    def __init__(self):
 
212
        GObject.Object.__init__(self)
 
213
        self._color_button = None
 
214
        self._color_helper = ColorHelper()
 
215
 
 
216
    def do_activate(self):
 
217
        # we do not have a direct accessor to the overlay
 
218
        self.overlay = self.view.get_parent().get_parent()
 
219
        self.overlay.connect('get-child-position', self.on_get_child_position)
 
220
 
 
221
        buf = self.view.get_buffer()
 
222
        buf.connect_after('mark-set', self.on_buffer_mark_set)
 
223
 
 
224
    def do_deactivate(self):
 
225
        if self._color_button is not None:
 
226
            self._color_button.destroy()
 
227
            self._color_button = None
 
228
 
 
229
    def on_get_child_position(self, overlay, widget, alloc):
 
230
        if widget == self._color_button:
 
231
            buf = self.view.get_buffer()
 
232
            bounds = buf.get_selection_bounds()
 
233
            if bounds != ():
 
234
                start, end = bounds
 
235
                location = self.view.get_iter_location(start)
 
236
                x, y = self.view.buffer_to_window_coords(Gtk.TextWindowType.TEXT, location.x, location.y)
 
237
                min_width, nat_width = widget.get_preferred_width()
 
238
                min_height, nat_height = widget.get_preferred_height()
 
239
                alloc.x = x
 
240
                if y - nat_height > 0:
 
241
                    alloc.y = y - nat_height
 
242
                else:
 
243
                    alloc.y = y + location.height
 
244
                alloc.width = nat_width
 
245
                alloc.height = nat_height
 
246
 
 
247
                return True
 
248
 
 
249
        return False
 
250
 
 
251
    def on_buffer_mark_set(self, buf, location, mark):
 
252
 
 
253
        if not buf.get_has_selection():
 
254
            if self._color_button:
 
255
                self._color_button.destroy()
 
256
                self._color_button = None
 
257
            return
 
258
 
 
259
        if mark != buf.get_insert() and mark != buf.get_selection_bound():
 
260
            return
 
261
 
 
262
        rgba_str = self._color_helper.get_current_color(self.view.get_buffer(), True)
 
263
        if rgba_str is not None and self._color_button is None:
 
264
            rgba = Gdk.RGBA()
 
265
            parsed = rgba.parse(rgba_str)
 
266
            if parsed:
 
267
                self._color_button = Gtk.ColorButton.new_with_rgba(rgba)
 
268
                self._color_button.set_halign(Gtk.Align.START)
 
269
                self._color_button.set_valign(Gtk.Align.START)
 
270
                self._color_button.show()
 
271
                self._color_button.connect('color-set', self.on_color_set)
 
272
 
 
273
                self.overlay.add_overlay(self._color_button)
 
274
        elif not rgba_str and self._color_button is not None:
 
275
            self._color_button.destroy()
 
276
            self._color_button = None
 
277
 
 
278
    def on_color_set(self, color_button):
 
279
        rgba = Gdk.RGBA()
 
280
        color_button.get_rgba(rgba)
 
281
 
 
282
        self._color_helper.insert_color(self.view,
 
283
                                        "%02x%02x%02x" % (self._color_helper.scale_color_component(rgba.red), \
 
284
                                                          self._color_helper.scale_color_component(rgba.green), \
 
285
                                                          self._color_helper.scale_color_component(rgba.blue)))
 
286
 
203
287
# ex:ts=4:et: