4 class TrafficLight(gtk
.DrawingArea
):
5 def __init__(self
, start
=False):
6 gtk
.DrawingArea
.__init
__(self
)
7 self
.connect("expose_event", self
.expose
)
10 def expose(self
, widget
, event
):
11 self
.context
= widget
.window
.cairo_create()
12 self
.draw(self
.context
)
16 def draw(self
, context
):
17 rect
= self
.get_allocation()
20 context
.rectangle(0, 0, rect
.width
, rect
.height
)
25 if self
.status
== False:
26 context
.set_source_rgb(1.0, 0.0, 0.0)
27 context
.arc(rect
.width
/ 2, 1 * (rect
.height
/ 4), min([(rect
.width
/2)-sub
, (rect
.height
/4)-sub
]), 0, 2.0 * math
.pi
)
30 context
.set_source_rgb(0.0, 0.0, 0.0)
31 context
.arc(rect
.width
/ 2, 1 * (rect
.height
/ 4), min([(rect
.width
/2)-sub
, (rect
.height
/4)-sub
]), math
.pi
, 2*math
.pi
)
36 if self
.status
== True:
37 context
.arc(rect
.width
/ 2, 3 * (rect
.height
/ 4), min([(rect
.width
/2)-sub
, (rect
.height
/4)-sub
]), 0, 2.0 * math
.pi
)
38 context
.set_source_rgb(0.0, 1.0, 0.0)
41 context
.set_source_rgb(0.0, 0.0, 0.0)
42 context
.arc(rect
.width
/ 2, 3 * (rect
.height
/ 4), min([(rect
.width
/2)-sub
, (rect
.height
/4)-sub
]), math
.pi
, 2*math
.pi
)
47 def set(self
, status
):
53 self
.set(not self
.get())
59 #=======================================================================================================0
60 #=======================================================================================================0
61 #=======================================================================================================0
62 #=======================================================================================================0
63 #=======================================================================================================0
64 """Autocomplete feature for gtk.TextView
65 This code is inspired and adapted from the Advene Project who has been inspired by the Scribes project
66 (http://scribes.sf.net/) - GPLv2
71 import pgw
, pgw
.Undo
, pgw
.Syntax
72 import gettext
; _
= gettext
.gettext
73 class SQLTextView(gtk
.VBox
):
74 def __init__(self
, db
):
75 gtk
.VBox
.__init
__(self
)
77 self
.enable_completion
= True
79 undo
= pgw
.Undo
.Undo()
80 scroll
= gtk
.ScrolledWindow()
81 scroll
.set_policy(gtk
.POLICY_AUTOMATIC
, gtk
.POLICY_AUTOMATIC
)
82 scroll
.set_property("height-request", 150)
83 scroll
.set_shadow_type(gtk
.SHADOW_NONE
)
84 self
.buffer = gtk
.TextBuffer()
85 self
.buffer.connect('delete-range', undo
.text_deleted
)
86 self
.buffer.connect('insert-text', undo
.text_inserted
)
88 syntax
= pgw
.Syntax
.Syntax(self
.buffer)
90 buffer_handlers
.append(self
.buffer.connect('delete-range',
92 buffer_handlers
.append(self
.buffer.connect('insert-text',
93 syntax
.text_inserted
))
94 buffer_handlers
.append(self
.buffer.connect('changed',
96 self
.textview
= gtk
.TextView(self
.buffer)
97 scroll
.add(self
.textview
)
101 self
.is_visible
=False
105 self
.widget
=self
.build_widget()
112 """Register the various callbacks for completion.
114 self
.textview
.connect("key-press-event", self
.key_press_event_cb
)
115 self
.textview
.connect("focus-out-event", self
.hide_completion_window
)
116 self
.textview
.get_buffer().connect("delete-range", self
.hide_completion_window
)
117 self
.textview
.get_buffer().connect_after("insert-text", self
.insert_text_cb
)
118 self
.textview
.connect("paste-clipboard", self
.hide_completion_window
)
119 self
.textview
.connect_after("paste-clipboard", self
.hide_completion_window
)
120 #self.textview.connect("button-press-event", self.__button_press_event_cb)
123 def insert_text_cb(self
, textbuffer
, iterator
, text
, length
):
124 """Handles callback when the "insert-text" signal is emitted.
127 self
.hide_completion_window()
129 self
.check_completion()
132 def hide_completion_window(self
, *p
):
133 self
.widget
.hide_all()
134 self
.is_visible
=False
136 def show_completion_window(self
, *p
):
137 width
, height
= self
.widget
.size_request()
146 self
.widget
.resize(width
, height
)
147 self
.widget
.set_property("width-request", width
)
148 self
.widget
.set_property("height-request", height
)
149 self
.position_window(width
, height
)
150 self
.widget
.show_all()
151 self
.position_window(width
, height
)
154 def get_cursor_rectangle(self
):
155 b
=self
.textview
.get_buffer()
156 cursor_iterator
=b
.get_iter_at_mark(b
.get_insert())
157 rectangle
= self
.textview
.get_iter_location(cursor_iterator
)
160 def get_cursor_textview_coordinates(self
):
161 rectangle
=self
.get_cursor_rectangle()
162 # Get the cursor's window coordinates.
163 position
= self
.textview
.buffer_to_window_coords(gtk
.TEXT_WINDOW_TEXT
, rectangle
.x
, rectangle
.y
)
164 cursor_x
= position
[0]
165 cursor_y
= position
[1]
166 return cursor_x
, cursor_y
168 def get_cursor_size(self
):
169 """Get the cursor's size.
171 rectangle
=self
.get_cursor_rectangle()
172 return rectangle
.width
, rectangle
.height
174 def position_window(self
, width
, height
):
175 """Position the completion window in the text editor's buffer.
177 @param width: The completion window's width.
178 @type width: An Integer object.
180 @param height: The completion window's height.
181 @type height: An Integer object.
183 # Get the cursor's coordinate and size.
184 cursor_x
, cursor_y
= self
.get_cursor_textview_coordinates()
185 cursor_height
= self
.get_cursor_size()[1]
186 # Get the text editor's textview coordinate and size.
187 window
= self
.textview
.get_window(gtk
.TEXT_WINDOW_TEXT
)
188 rectangle
= self
.textview
.get_visible_rect()
189 window_x
, window_y
= window
.get_origin()
190 window_width
, window_height
= rectangle
.width
, rectangle
.height
192 # Determine where to position the completion window.
193 position_x
= window_x
+ cursor_x
194 position_y
= window_y
+ cursor_y
+ cursor_height
196 # If the completion window extends past the text editor's buffer,
197 # reposition the completion window inside the text editor's buffer area.
198 if position_x
+ width
> window_x
+ window_width
:
199 position_x
= (window_x
+ window_width
) - width
200 if position_y
+ height
> window_y
+ window_height
:
201 position_y
= (window_y
+ cursor_y
) - height
202 #if not_(self.__signals_are_blocked):
203 x
, y
= self
.widget
.get_position()
208 if position_x
!= x
or position_y
!= y
:
209 # Set the window's new position.
210 self
.widget
.move(position_x
, position_y
)
212 def populate_model(self
, completion_list
):
213 """Populate the view's data model.
215 @param self: Reference to the CompletionTreeView instance.
216 @type self: A CompletionTreeView object.
218 if completion_list
!= self
.word_list
:
219 self
.word_list
= completion_list
221 for word
in self
.word_list
:
222 self
.model
.append([word
])
223 self
.treeview
.columns_autosize()
224 self
.treeview
.get_selection().select_path(0)
226 def get_word_before_cursor(self
):
227 b
=self
.textview
.get_buffer()
228 cursor_position
=b
.get_iter_at_mark(b
.get_insert())
229 word_start
=cursor_position
.copy()
230 word_start
.backward_word_start()
231 return word_start
.get_text(cursor_position
)
233 def insert_word_completion(self
, path
):
234 """Insert item selected in the completion window into the text editor's
237 @param path: The selected row in the completion window.
238 @type path: A gtk.TreeRow object.
240 # Get the selected completion string.
241 completion_string
= self
.model
[path
[0]][0].decode("utf8")
243 word
=self
.get_word_before_cursor().encode('utf8')
244 complete
=completion_string
.replace(word
, '')
245 b
=self
.textview
.get_buffer()
246 b
.begin_user_action()
247 b
.insert_at_cursor(complete
)
251 """ Returns a sorted list of Completions"""
252 def get_completions(self
, word
, context
):
253 print "SQLTextView: get_completions(word=%s, context=%s)"%(word
, context
)
255 b
=self
.textview
.get_buffer()
256 cursor_pos
= b
.get_iter_at_mark(b
.get_insert())
257 w_start
= cursor_pos
.copy()
258 w_start
.backward_word_start()
259 word
= w_start
.get_text( cursor_pos
)
260 if word
!= "" and word
.strip() in pgw
.Syntax
.KEYWORDS
:
261 self
.last
= word
.strip()
262 return pgw
.Syntax
.KEYWORDS
[word
.strip()]
263 elif word
!= "" and self
.last
in pgw
.Syntax
.KEYWORDS
:
265 for it
in pgw
.Syntax
.KEYWORDS
[self
.last
]:
266 if type(it
) == str and it
.startswith(word
):
270 for it
in pgw
.Syntax
.KEYWORDS
.keys():
271 if type(it
) == str and it
.startswith(word
):
276 def check_completion(self
):
277 word
= self
.get_word_before_cursor()
278 if self
.enable_completion
and word
:
281 matches
=self
.get_completions(word
, context
=self
.buffer)
283 self
.populate_model(matches
)
284 self
.show_completion_window()
287 self
.hide_completion_window()
289 self
.hide_completion_window()
292 def key_press_event_cb(self
, widget
, event
):
293 """Handles "key-press-event" for the treeview and textview.
295 This function allows the "Up" and "Down" arrow keys to work in
296 the word completion window.
298 if not self
.is_visible
:
301 if event
.keyval
in (gtk
.keysyms
.Tab
, gtk
.keysyms
.Right
, gtk
.keysyms
.Left
,
302 gtk
.keysyms
.Home
, gtk
.keysyms
.End
, gtk
.keysyms
.Insert
,
304 gtk
.keysyms
.Page_Up
, gtk
.keysyms
.Page_Down
,
306 self
.hide_completion_window()
309 # Get the selected item on the completion window.
310 selection
= self
.treeview
.get_selection()
311 # Get the model and iterator of the selected item.
312 model
, iterator
= selection
.get_selected()
313 # If for whatever reason the selection is lost, select the first row
314 # automatically when the up or down arrow key is pressed.
316 selection
.select_path((0,))
317 model
, iterator
= selection
.get_selected()
318 path
= model
.get_path(iterator
)
319 if event
.keyval
== gtk
.keysyms
.Return
:
320 # Insert the selected item into the editor's buffer when the enter key
322 self
.treeview
.row_activated(path
, self
.treeview
.get_column(0))
323 elif event
.keyval
== gtk
.keysyms
.Up
:
324 # If the up key is pressed check to see if the first row is selected.
325 # If it is, select the last row. Otherwise, get the path to the row
326 # above and select it.
328 number_of_rows
= len(model
)
329 selection
.select_path(number_of_rows
- 1)
330 self
.treeview
.scroll_to_cell(number_of_rows
- 1)
332 selection
.select_path((path
[0] - 1, ))
333 self
.treeview
.scroll_to_cell((path
[0] - 1, ))
334 elif event
.keyval
== gtk
.keysyms
.Down
:
335 # Get the iterator of the next row.
336 next_iterator
= model
.iter_next(iterator
)
337 # If the next row exists, select it, if not select the first row.
339 selection
.select_iter(next_iterator
)
340 path
= model
.get_path(next_iterator
)
341 self
.treeview
.scroll_to_cell(path
)
343 selection
.select_path(0)
344 self
.treeview
.scroll_to_cell(0)
349 def build_widget(self
):
350 w
=gtk
.Window(gtk
.WINDOW_POPUP
)
352 w
.set_type_hint(gtk
.gdk
.WINDOW_TYPE_HINT_MENU
)
353 w
.set_size_request(200, 200)
355 self
.treeview
=gtk
.TreeView()
357 self
.model
= gtk
.ListStore(str)
358 renderer
= gtk
.CellRendererText()
359 col
=gtk
.TreeViewColumn("", renderer
, text
=0)
360 col
.set_expand(False)
362 self
.treeview
.append_column(col
)
363 self
.treeview
.set_headers_visible(False)
364 self
.treeview
.set_rules_hint(True)
365 self
.treeview
.set_hover_selection(True)
366 self
.treeview
.set_model(self
.model
)
368 def treeview_row_activated_cb(treeview
, path
, column
):
369 """Handles "row-activated" in the treeview.
371 self
.insert_word_completion(path
)
372 self
.hide_completion_window()
374 self
.treeview
.connect("row-activated", treeview_row_activated_cb
)
376 style
= self
.textview
.get_style()
377 color
= style
.base
[gtk
.STATE_SELECTED
]
378 self
.treeview
.modify_base(gtk
.STATE_ACTIVE
, color
)
380 scroll
=gtk
.ScrolledWindow()
381 scroll
.add(self
.treeview
)
382 scroll
.set_policy(gtk
.POLICY_AUTOMATIC
, gtk
.POLICY_AUTOMATIC
)
383 scroll
.set_border_width(2)