~ubuntu-branches/ubuntu/jaunty/pida/jaunty

« back to all changes in this revision

Viewing changes to src/plugins/culebra/edit.py

  • Committer: Bazaar Package Importer
  • Author(s): Barry deFreese
  • Date: 2006-08-01 13:08:56 UTC
  • mfrom: (0.1.2 etch) (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20060801130856-v92ktopgdxc8rv7q
Tags: 0.3.1-2ubuntu1
* Re-sync with Debian
* Remove bashisms from debian/rules

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# -*- coding: utf-8 -*-
2
 
# Copyright Fernando San Martín Woerner <fsmw@gnome.org>
3
 
# $Id: edit.py 475 2005-07-29 17:29:32Z snmartin $
4
 
#Permission is hereby granted, free of charge, to any person obtaining a copy
5
 
#of this software and associated documentation files (the "Software"), to deal
6
 
#in the Software without restriction, including without limitation the rights
7
 
#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
 
#copies of the Software, and to permit persons to whom the Software is
9
 
#furnished to do so, subject to the following conditions:
10
 
#
11
 
#The above copyright notice and this permission notice shall be included in
12
 
#all copies or substantial portions of the Software.
13
 
#
14
 
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
 
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
 
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
 
#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
 
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
 
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
 
#SOFTWARE.
21
 
 
22
 
# This file is part of Culebra project.
23
 
 
24
 
import gtk
25
 
import sys, os
26
 
import pango
27
 
import dialogs
28
 
import gtksourceview
29
 
import gnomevfs
30
 
import importsTipper
31
 
import keyword
32
 
 
33
 
BLOCK_SIZE = 2048
34
 
 
35
 
special_chars = (".",)
36
 
RESPONSE_FORWARD = 0
37
 
RESPONSE_BACKWARD = 1
38
 
RESPONSE_REPLACE = 2
39
 
RESPONSE_REPLACE_ALL = 3
40
 
 
41
 
global newnumber
42
 
newnumber = 1
43
 
 
44
 
class CulebraBuffer(gtksourceview.SourceBuffer):
45
 
 
46
 
    def __init__(self, filename=None):
47
 
        gtksourceview.SourceBuffer.__init__(self)
48
 
        self.filename=filename
49
 
 
50
 
 
51
 
class CulebraView(gtksourceview.SourceView):
52
 
 
53
 
    def __init__(self, buff=CulebraBuffer()):
54
 
        if buffer is None:
55
 
            gtksourceview.SourceView.__init__(self)
56
 
        else:
57
 
            gtksourceview.SourceView.__init__(self, buff)
58
 
                
59
 
class EditWindow(gtk.EventBox):
60
 
 
61
 
    def __init__(self, plugin=None, quit_cb=None):
62
 
        gtk.EventBox.__init__(self)
63
 
        self.search_string = None
64
 
        self.last_search_iter = None
65
 
        self.completion_win = None
66
 
        self.insert_string = None
67
 
        self.cursor_iter = None
68
 
        self.plugin = plugin
69
 
        self.wins = []
70
 
        self.current_word = ""
71
 
        self.wl = []
72
 
        self.ac_w = None
73
 
        self.set_size_request(470, 300)
74
 
        self.connect("delete_event", self.file_exit)
75
 
        self.quit_cb = quit_cb
76
 
        self.vbox = gtk.VBox()
77
 
        self.add(self.vbox)
78
 
        self.vbox.show()
79
 
        self.menubar, self.toolbar = self.create_menu()
80
 
        hdlbox = gtk.HandleBox()
81
 
        self.vbox.pack_start(hdlbox, expand=False)
82
 
        hdlbox.show()
83
 
        hdlbox.add(self.menubar)
84
 
        self.menubar.show()
85
 
        hdlbox = gtk.HandleBox()
86
 
        self.vbox.pack_start(hdlbox, expand=False)
87
 
        hdlbox.show()
88
 
        hdlbox.add(self.toolbar)
89
 
        self.toolbar.show()
90
 
        self.vpaned = gtk.VPaned()
91
 
        self.vbox.pack_start(self.vpaned, expand=True, fill = True)
92
 
        self.vpaned.show()
93
 
        self.vbox1 = gtk.VBox()
94
 
        self.vpaned.add1(self.vbox1)
95
 
        self.vbox.show()
96
 
        self.vbox1.show()
97
 
        self.hpaned = gtk.HPaned()
98
 
        self.vbox1.pack_start(self.hpaned, True, True)
99
 
        self.hpaned.set_border_width(5)
100
 
        self.hpaned.show()
101
 
        # the gtksourceview
102
 
        lm = gtksourceview.SourceLanguagesManager()
103
 
        buff = CulebraBuffer()
104
 
        self.new = True
105
 
        buff.set_data('languages-manager', lm)
106
 
#        self.editor = gtksourceview.SourceView(buff)
107
 
        self.editor = CulebraView(buff)
108
 
        self.plugin.pida.mainwindow.connect('delete-event', self.file_exit)
109
 
        font_desc = pango.FontDescription('monospace 10')
110
 
        if font_desc:
111
 
            self.editor.modify_font(font_desc)
112
 
        
113
 
        buff.connect('insert-text', self.insert_at_cursor_cb)
114
 
        buff.set_data("save", False)
115
 
        manager = buff.get_data('languages-manager')
116
 
        language = manager.get_language_from_mime_type("text/x-python")
117
 
        buff.set_highlight(True)
118
 
        buff.set_language(language)
119
 
        scrolledwin2 = gtk.ScrolledWindow()
120
 
        scrolledwin2.add(self.editor)
121
 
        self.editor.set_auto_indent(True)
122
 
        self.editor.set_show_line_numbers(True)
123
 
        self.editor.set_show_line_markers(True)
124
 
        self.editor.set_tabs_width(4)
125
 
        self.editor.connect('key-press-event', self.text_key_press_event_cb)
126
 
        self.editor.connect('move-cursor', self.move_cursor)
127
 
        self.editor.set_margin(80)
128
 
        self.editor.set_show_margin(True)
129
 
        self.editor.set_smart_home_end(True)
130
 
        self.editor.set_highlight_current_line(True)
131
 
        scrolledwin2.show()
132
 
        self.editor.show()
133
 
        self.editor.grab_focus()
134
 
        buff.set_data('filename', "untitled.py")
135
 
        self.wins.append([buff, "untitled.py"])
136
 
        self.current_buffer = 0
137
 
        self.hpaned.add2(scrolledwin2)
138
 
        self.hpaned.set_position(200)
139
 
        self.dirty = 0
140
 
        self.clipboard = gtk.Clipboard(selection='CLIPBOARD')
141
 
        self.dirname = "."
142
 
        # sorry, ugly
143
 
        self.filetypes = {}
144
 
        return
145
 
        
146
 
    def create_menu(self):
147
 
        ui_string = """<ui>
148
 
        <menubar>
149
 
                <menu name='FileMenu' action='FileMenu'>
150
 
                        <menuitem action='FileNew'/>
151
 
                        <menuitem action='FileOpen'/>
152
 
                        <menuitem action='FileSave'/>
153
 
                        <menuitem action='FileSaveAs'/>
154
 
                        <menuitem action='Close'/>
155
 
                        <separator/>
156
 
                        <menuitem action='FileExit'/>
157
 
                </menu>
158
 
                <menu name='EditMenu' action='EditMenu'>
159
 
                        <menuitem action='EditUndo'/>
160
 
                        <menuitem action='EditRedo'/>
161
 
                        <separator/>
162
 
                        <menuitem action='EditCut'/>
163
 
                        <menuitem action='EditCopy'/>
164
 
                        <menuitem action='EditPaste'/>
165
 
                        <menuitem action='EditClear'/>
166
 
                        <separator/>
167
 
                        <menuitem action='DuplicateLine'/>
168
 
                        <menuitem action='DeleteLine'/>
169
 
                        <menuitem action='CommentBlock'/>
170
 
                        <menuitem action='UncommentBlock'/>
171
 
                        <menuitem action='UpperSelection'/>
172
 
                        <menuitem action='LowerSelection'/>
173
 
                        <separator/>
174
 
                        <menuitem action='Configuration' />
175
 
                </menu>
176
 
                <menu name='FindMenu' action='FindMenu'>
177
 
                        <menuitem action='EditFind'/>
178
 
                        <menuitem action='EditFindNext'/>
179
 
                        <menuitem action='EditReplace'/>
180
 
                        <separator/>                        
181
 
                        <menuitem action='GotoLine'/>
182
 
                </menu>
183
 
                <menu name='RunMenu' action='RunMenu'>
184
 
                        <menuitem action='RunScript'/>
185
 
                        <menuitem action='StopScript'/>
186
 
                        <menuitem action='DebugScript'/>
187
 
                        <menuitem action='DebugStep'/>
188
 
                        <menuitem action='DebugNext'/>
189
 
                        <menuitem action='DebugContinue'/>
190
 
                </menu>
191
 
                <menu name='BufferMenu' action='BufferMenu'>
192
 
                        <menuitem action='PrevBuffer'/>
193
 
                        <menuitem action='NextBuffer'/>
194
 
                </menu>
195
 
        </menubar>
196
 
        <toolbar>
197
 
                <toolitem action='FileNew'/>
198
 
                <toolitem action='FileOpen'/>
199
 
                <toolitem action='FileSave'/>
200
 
                <toolitem action='FileSaveAs'/>
201
 
                <toolitem action='Close'/>
202
 
                <separator/>
203
 
                <toolitem action='EditUndo'/>
204
 
                <toolitem action='EditRedo'/>
205
 
                <separator/>
206
 
                <toolitem action='EditCut'/>
207
 
                <toolitem action='EditCopy'/>
208
 
                <toolitem action='EditPaste'/>
209
 
                <separator/>
210
 
                <toolitem action='EditFind'/>
211
 
                <toolitem action='EditReplace'/>
212
 
                <separator/>
213
 
                <toolitem action='RunScript'/>
214
 
                <toolitem action='StopScript'/>
215
 
                <separator/>
216
 
                <toolitem action='PrevBuffer'/>
217
 
                <toolitem action='NextBuffer'/>
218
 
        </toolbar>
219
 
        </ui>
220
 
        """
221
 
        actions = [
222
 
            ('FileMenu', None, '_File'),
223
 
            ('FileNew', gtk.STOCK_NEW, None, None, None, self.file_new),
224
 
            ('FileOpen', gtk.STOCK_OPEN, None, None, None, self.file_open),
225
 
            ('FileSave', gtk.STOCK_SAVE, None, None, None, self.file_save),
226
 
            ('FileSaveAs', gtk.STOCK_SAVE_AS, None, None, None,
227
 
             self.file_saveas),
228
 
            ('Close', gtk.STOCK_CLOSE, None, None, None, self.file_close),
229
 
            ('FileExit', gtk.STOCK_QUIT, None, None, None, self.file_exit),
230
 
            ('EditMenu', None, '_Edit'),
231
 
            ('EditUndo', gtk.STOCK_UNDO, None, "<control>z", None, self.edit_undo),
232
 
            ('EditRedo', gtk.STOCK_REDO, None, "<control><shift>z", None, self.edit_redo),
233
 
            ('EditCut', gtk.STOCK_CUT, None, None, None, self.edit_cut),
234
 
            ('EditCopy', gtk.STOCK_COPY, None, None, None, self.edit_copy),
235
 
            ('EditPaste', gtk.STOCK_PASTE, None, None, None, self.edit_paste),
236
 
            ('EditClear', gtk.STOCK_REMOVE, 'C_lear', None, None,
237
 
             self.edit_clear),
238
 
            ('Configuration', None, 'Configur_e', None, None,
239
 
                lambda action: self.plugin.do_action('showconfig', 'culebra')),
240
 
            
241
 
             ('DuplicateLine', None, 'Duplicate Line', '<control>d', 
242
 
                 None, self.duplicate_line),
243
 
             ('DeleteLine', None, 'Delete Line', '<control>y', 
244
 
                 None, self.delete_line),
245
 
             ('CommentBlock', None, 'Comment Selection', '<control>k', 
246
 
                 None, self.comment_block),
247
 
             ('UncommentBlock', None, 'Uncomment Selection', '<control><shift>k', 
248
 
                 None, self.uncomment_block),
249
 
             ('UpperSelection', None, 'Upper Selection', '<control>u', 
250
 
                 None, self.upper_selection),
251
 
             ('LowerSelection', None, 'Lower Selection', '<control><shift>u', 
252
 
                 None, self.lower_selection),
253
 
            ('FindMenu', None, '_Find'),
254
 
            ('EditFind', gtk.STOCK_FIND, None, None, None, self.edit_find),
255
 
            ('EditFindNext', None, 'Find _Next', None, None, self.edit_find_next),
256
 
            ('EditReplace', gtk.STOCK_FIND_AND_REPLACE, None, '<control>h', 
257
 
                None, self.edit_replace),
258
 
            ('GotoLine', None, 'Goto Line', '<control>g', 
259
 
                 None, self.goto_line),
260
 
            ('RunMenu', None, '_Run'),
261
 
            ('RunScript', gtk.STOCK_EXECUTE, None, "F5",None, self.run_script),
262
 
            ('StopScript', gtk.STOCK_STOP, None, "<ctrl>F5",None, self.stop_script),
263
 
            ('DebugScript', None, "Debug Script", "F7",None, self.debug_script),
264
 
            ('DebugStep', None, "Step", "F8",None, self.step_script),
265
 
            ('DebugNext', None, "Next", "<shift>F7",None, self.next_script),
266
 
            ('DebugContinue', None, "Continue", "<control>F7", None, self.continue_script),
267
 
            ('BufferMenu', None, '_Buffers'),
268
 
            ('PrevBuffer', gtk.STOCK_GO_UP, None, "<shift>F6",None, self.prev_buffer),
269
 
            ('NextBuffer', gtk.STOCK_GO_DOWN, None, "F6",None, self.next_buffer),
270
 
            ]
271
 
        self.ag = gtk.ActionGroup('edit')
272
 
        self.ag.add_actions(actions)
273
 
        self.ui = gtk.UIManager()
274
 
        self.ui.insert_action_group(self.ag, 0)
275
 
        self.ui.add_ui_from_string(ui_string)
276
 
        self.get_parent_window().add_accel_group(self.ui.get_accel_group())
277
 
        return (self.ui.get_widget('/menubar'), self.ui.get_widget('/toolbar'))
278
 
    
279
 
    def set_title(self, title):
280
 
        self.plugin.pida.mainwindow.set_title(title)
281
 
 
282
 
    def move_cursor(self, tv, step, count, extend_selection):
283
 
        return
284
 
 
285
 
    def get_parent_window(self):
286
 
        return self.plugin.pida.mainwindow
287
 
 
288
 
    def get_current(self, page = None):
289
 
        if len(self.wins) > 0:
290
 
            if page is None:
291
 
                return self.wins[self.current_buffer]
292
 
        return None, None
293
 
 
294
 
    def _new_tab(self, f, buff = None):
295
 
        l = [n for n in self.wins if n[1]==f]
296
 
        if len(l) == 0:
297
 
            lm = gtksourceview.SourceLanguagesManager()
298
 
            if buff is None:
299
 
                buff = CulebraBuffer()
300
 
                self.new = True
301
 
            buff.set_data('languages-manager', lm)
302
 
            font_desc = pango.FontDescription('monospace 10')
303
 
            if font_desc:
304
 
                self.editor.modify_font(font_desc)
305
 
            buff.connect('insert-text', self.insert_at_cursor_cb)
306
 
            buff.set_data("save", False)
307
 
            self.editor.set_buffer(buff)
308
 
            self.editor.grab_focus()
309
 
            buff.set_data('filename', f)
310
 
            self.wins.append([buff, f])
311
 
            self.current_buffer = len(self.wins) - 1
312
 
 
313
 
    def insert_at_cursor_cb(self, buff, iter, text, length):
314
 
        complete = ""
315
 
        buff, fn = self.get_current()
316
 
        iter2 = buff.get_iter_at_mark(buff.get_insert())
317
 
        s, e = buff.get_bounds()
318
 
        text_code = buff.get_text(s, e)
319
 
        lst_ = []
320
 
        if self.ac_w is not None:
321
 
            self.ac_w.hide()
322
 
        mod = False
323
 
        if text != '.':
324
 
            complete = self.get_context(buff, iter2, True)
325
 
            if "\n" in complete or complete.isdigit():
326
 
                return
327
 
            else:
328
 
                complete = complete + text
329
 
            try:
330
 
                c = compile(text_code, '<string>', 'exec')
331
 
                lst_ = [a for a in c.co_names if a.startswith(complete)]
332
 
                con = map(str, c.co_consts)
333
 
                con = [a for a in con if a.startswith(complete) and a not in lst_]
334
 
                lst_ += con
335
 
                lst_ += keyword.kwlist
336
 
                lst_ = [a for a in lst_ if a.startswith(complete)]
337
 
                lst_.sort()
338
 
            except:
339
 
                lst_ += keyword.kwlist
340
 
                lst_ = [a for a in lst_ if a.startswith(complete)]
341
 
                lst_.sort()
342
 
        else:
343
 
            mod = True
344
 
            complete = self.get_context(buff, iter2)
345
 
            if complete.isdigit():
346
 
                return
347
 
            if len(complete.strip()) > 0:
348
 
                try:
349
 
                    lst_ = [str(a[0]) for a in importsTipper.GenerateTip(complete, os.path.dirname(fn)) if a is not None]
350
 
                except:
351
 
                    try:
352
 
                        c = compile(text_code, '<string>', 'exec')
353
 
                        lst_ = [a for a in c.co_names if a.startswith(complete)]
354
 
                        con = map(str, c.co_consts)
355
 
                        con = [a for a in con if a.startswith(complete) and a not in lst_]
356
 
                        lst_ += con
357
 
                        lst_ += keyword.kwlist
358
 
                        lst_ = [a for a in lst_ if a.startswith(complete)]
359
 
                        lst_.sort()
360
 
                        complete = ""
361
 
                    except:
362
 
                        lst_ += keyword.kwlist
363
 
                        lst_ = [a for a in lst_ if a.startswith(complete)]
364
 
                        lst_.sort()
365
 
                        complete = ""
366
 
                        
367
 
        if len(lst_)==0:
368
 
            return
369
 
        if self.ac_w is None:
370
 
            self.ac_w = AutoCompletionWindow(self.editor, iter2, complete, 
371
 
                                        lst_, 
372
 
                                        self.plugin.pida.mainwindow, 
373
 
                                        mod, 
374
 
                                        self.context_bounds)
375
 
        else:
376
 
            self.ac_w.set_list(self.editor, iter2, complete, 
377
 
                           lst_, 
378
 
                           self.plugin.pida.mainwindow, 
379
 
                           mod, 
380
 
                           self.context_bounds)
381
 
        return
382
 
        
383
 
    def get_context(self, buff, it, sp=False):
384
 
        iter2 = it.copy()
385
 
        if sp:
386
 
            it.backward_word_start()
387
 
        else:
388
 
            it.backward_word_starts(1)
389
 
        iter3 = it.copy()
390
 
        iter3.backward_chars(1)
391
 
        prev = iter3.get_text(it)
392
 
        complete = it.get_text(iter2)
393
 
        self.context_bounds = (buff.create_mark('cstart',it), buff.create_mark('cend',iter2))
394
 
        if prev in (".", "_"):
395
 
            t = self.get_context(buff, it)
396
 
            return t + complete
397
 
        else:
398
 
            count = 0
399
 
            return complete
400
 
 
401
 
    def text_key_press_event_cb(self, widget, event):
402
 
        #print event.state, event.keyval
403
 
        keyname = gtk.gdk.keyval_name(event.keyval)
404
 
        buf = widget.get_buffer()
405
 
        bound = buf.get_selection_bounds()
406
 
        tabs = widget.get_tabs_width()
407
 
        space = " ".center(tabs)
408
 
        # shift-tab unindent
409
 
        if event.state & gtk.gdk.SHIFT_MASK and keyname == "ISO_Left_Tab":
410
 
            if len(bound) == 0:
411
 
                it = buf.get_iter_at_mark(buf.get_insert())
412
 
                start = buf.get_iter_at_line(it.get_line())
413
 
                end = buf.get_iter_at_line(it.get_line())
414
 
                count = 0
415
 
                while end.get_char() == " " and count < tabs:
416
 
                    end.forward_char()
417
 
                    count += 1
418
 
                buf.delete(start, end)
419
 
            else:
420
 
                start, end = bound
421
 
                start_line = start.get_line()
422
 
                end_line = end.get_line()
423
 
                while start_line <= end_line:
424
 
                    insert_iter = buf.get_iter_at_line(start_line)
425
 
                    if not insert_iter.ends_line():
426
 
                        s_it = buf.get_iter_at_line(start_line)
427
 
                        e_it = buf.get_iter_at_line(start_line)
428
 
                        count = 0
429
 
                        while e_it.get_char() == " " and count < tabs:
430
 
                            e_it.forward_char()
431
 
                            count += 1
432
 
                        buf.delete(s_it, e_it)        
433
 
                    start_line += 1
434
 
            return True
435
 
        #tab indent
436
 
        elif event.keyval == gtk.keysyms.Tab:
437
 
            if len(bound) == 0:
438
 
                buf.insert_at_cursor(space)
439
 
            else:
440
 
                start, end = bound
441
 
                start_line = start.get_line()
442
 
                end_line = end.get_line()
443
 
                while start_line <= end_line:
444
 
                    insert_iter = buf.get_iter_at_line(start_line)
445
 
                    if not insert_iter.ends_line():
446
 
                        buf.insert(insert_iter, space)
447
 
                    start_line += 1
448
 
            return True
449
 
 
450
 
    def load_file(self, fname):
451
 
        try:
452
 
            fd = open(fname)
453
 
            self._new_tab(fname)
454
 
            buff, fn = self.wins[self.current_buffer]
455
 
            buff.set_text('')
456
 
            buff.set_data('filename', fname)
457
 
            buff.set_text(fd.read())
458
 
            fd.close()
459
 
            self.editor.set_buffer(buff)
460
 
            self.editor.queue_draw()
461
 
            self.set_title(os.path.basename(fname))
462
 
            self.dirname = os.path.dirname(fname)
463
 
            buff.set_modified(False)
464
 
            self.new = False
465
 
            self.check_mime(self.current_buffer)
466
 
            buff.place_cursor(buff.get_start_iter())
467
 
        except:
468
 
            dlg = gtk.MessageDialog(self.get_parent_window(),
469
 
                    gtk.DIALOG_DESTROY_WITH_PARENT,
470
 
                    gtk.MESSAGE_ERROR, gtk.BUTTONS_OK,
471
 
                    "Can't open " + fname)
472
 
            print sys.exc_info()[1]
473
 
            resp = dlg.run()
474
 
            dlg.hide()
475
 
            return
476
 
        self.check_mime(self.current_buffer)
477
 
        self.plugin.do_edit('getbufferlist')
478
 
        self.plugin.do_edit('getcurrentbuffer')
479
 
        for i, (buff, fn) in enumerate(self.wins):
480
 
            if fn == fname:
481
 
                self.plugin.do_edit('changebuffer', i)
482
 
                break
483
 
        self.editor.grab_focus()
484
 
 
485
 
    def check_mime(self, buffer_number):
486
 
        buff, fname = self.wins[buffer_number]
487
 
        manager = buff.get_data('languages-manager')
488
 
        if os.path.isabs(fname):
489
 
            path = fname
490
 
        else:
491
 
            path = os.path.abspath(fname)
492
 
        uri = gnomevfs.URI(path)
493
 
        mime_type = gnomevfs.get_mime_type(path) # needs ASCII filename, not URI
494
 
        if mime_type:
495
 
            language = manager.get_language_from_mime_type(mime_type)
496
 
            if language:
497
 
                buff.set_highlight(True)
498
 
                buff.set_language(language)
499
 
            else:
500
 
                dlg = gtk.MessageDialog(self.get_parent_window(),
501
 
                    gtk.DIALOG_DESTROY_WITH_PARENT,
502
 
                    gtk.MESSAGE_ERROR, gtk.BUTTONS_OK,
503
 
                    'No language found for mime type "%s"' % mime_type)
504
 
                buff.set_highlight(False)
505
 
        else:
506
 
            dlg = gtk.MessageDialog(self.get_parent_window(),
507
 
                    gtk.DIALOG_DESTROY_WITH_PARENT,
508
 
                    gtk.MESSAGE_ERROR, gtk.BUTTONS_OK,
509
 
                    'Couldn\'t get mime type for file "%s"' % fname)
510
 
            buff.set_highlight(False)
511
 
        buff.set_data("save", False)
512
 
 
513
 
    def chk_save(self):
514
 
        buff, fname = self.get_current()
515
 
        if buff is None:
516
 
            return False
517
 
        if buff.get_modified():
518
 
            dlg = gtk.Dialog('Unsaved File', self.get_parent_window(),
519
 
                    gtk.DIALOG_DESTROY_WITH_PARENT,
520
 
                         (gtk.STOCK_YES, gtk.RESPONSE_YES,
521
 
                          gtk.STOCK_NO, gtk.RESPONSE_NO,
522
 
                          gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
523
 
            lbl = gtk.Label((fname or "Untitled")+
524
 
                        " has not been saved\n" +
525
 
                        "Do you want to save it?")
526
 
            lbl.show()
527
 
            dlg.vbox.pack_start(lbl)
528
 
            ret = dlg.run()
529
 
            dlg.hide()
530
 
            if ret == gtk.RESPONSE_NO:
531
 
                return False
532
 
            if ret == gtk.RESPONSE_YES:
533
 
                if self.file_save():
534
 
                    return False
535
 
            return True
536
 
        return False
537
 
 
538
 
    def file_new(self, mi=None):
539
 
        if self.chk_save(): return
540
 
        self._new_tab("untitled%s.py" % len(self.wins))
541
 
        buff, fname = self.get_current()
542
 
        buff.set_text("")
543
 
        buff.set_data('filename', fname)
544
 
        buff.set_modified(False)
545
 
        self.new = True
546
 
        manager = buff.get_data('languages-manager')
547
 
        language = manager.get_language_from_mime_type("text/x-python")
548
 
        buff.set_highlight(True)
549
 
        buff.set_language(language)
550
 
        self.plugin.do_edit('getbufferlist')
551
 
        self.plugin.do_edit('getcurrentbuffer')
552
 
        self.plugin.do_edit('changebuffer', len(self.wins) - 1)
553
 
 
554
 
        return
555
 
 
556
 
    def file_open(self, mi=None):
557
 
        fn = self.get_current()[1]
558
 
        dirn =os.path.dirname(fn)
559
 
        fname = dialogs.OpenFile('Open File', self.get_parent_window(),
560
 
                                  dirn, None, "*.py")
561
 
        
562
 
        if not fname: return
563
 
        if self.new:
564
 
            buff = self.get_current()[0]
565
 
            if not buff.get_modified():
566
 
                del self.wins[self.current_buffer]
567
 
        self.load_file(fname)
568
 
        self.plugin.pida.mainwindow.set_title(os.path.split(fname)[1])
569
 
        return
570
 
 
571
 
    def file_save(self, mi=None, fname=None):
572
 
        if self.new:
573
 
            return self.file_saveas()
574
 
        buff = self.editor.get_buffer()
575
 
        curr_mark = buff.get_iter_at_mark(buff.get_insert())
576
 
        f = buff.get_data('filename')
577
 
        ret = False
578
 
        if fname is None:
579
 
            fname = f
580
 
        try:
581
 
            start, end = buff.get_bounds()
582
 
            blockend = start.copy()
583
 
            fd = open(fname, "w")
584
 
            while blockend.forward_chars(BLOCK_SIZE):
585
 
                buf = buff.get_text(start, blockend)
586
 
                fd.write(buf)
587
 
                start = blockend.copy()
588
 
            buf = buff.get_text(start, blockend)
589
 
            fd.write(buf)
590
 
            fd.close()
591
 
            buff.set_modified(False)
592
 
            buff.set_data("save", True)
593
 
            buff.set_data('filename', fname)
594
 
            self.plugin.pida.mainwindow.set_title(os.path.split(fname)[1])
595
 
            ret = True
596
 
            self.wins[self.current_buffer] = [buff, fname]
597
 
        except:
598
 
            dlg = gtk.MessageDialog(self.get_parent_window(),
599
 
                                gtk.DIALOG_DESTROY_WITH_PARENT,
600
 
                                gtk.MESSAGE_ERROR, gtk.BUTTONS_OK,
601
 
                                "Error saving file " + fname)
602
 
            print sys.exc_info()[1]
603
 
            resp = dlg.run()
604
 
            dlg.hide()
605
 
 
606
 
        self.check_mime(self.current_buffer)
607
 
        self.plugin.do_edit('getbufferlist')
608
 
        self.plugin.do_edit('getcurrentbuffer')
609
 
#        self.plugin.do_edit('changebuffer', len(self.wins) - 1)
610
 
        buff.place_cursor(curr_mark)
611
 
        self.editor.grab_focus()
612
 
        return ret
613
 
 
614
 
    def file_saveas(self, mi=None):
615
 
        buff, f = self.get_current()
616
 
        f = dialogs.SaveFile('Save File As', 
617
 
                                self.get_parent_window(), 
618
 
                                self.dirname,
619
 
                                f)
620
 
        if not f: return False
621
 
 
622
 
        self.dirname = os.path.dirname(f)
623
 
        self.plugin.pida.mainwindow.set_title(os.path.basename(f))
624
 
        self.new = 0
625
 
        return self.file_save(fname=f)
626
 
 
627
 
    def file_close(self, mi=None, event=None):
628
 
        del self.wins[self.current_buffer]
629
 
        if len(self.wins) == 0:
630
 
            self._new_tab('untitled.py')
631
 
        else:
632
 
            self.current_buffer = len(self.wins) - 1
633
 
            self.editor.set_buffer(self.wins[self.current_buffer][0])
634
 
        self.plugin.do_edit('getbufferlist')
635
 
        self.plugin.do_edit('getcurrentbuffer')
636
 
        return
637
 
 
638
 
    def file_exit(self, mi=None, event=None):
639
 
        if self.chk_save(): return True
640
 
        self.hide()
641
 
        self.destroy()
642
 
        if self.quit_cb: self.quit_cb(self)
643
 
        self.plugin.do_action('quit')
644
 
        return False
645
 
 
646
 
    def edit_cut(self, mi):
647
 
        buff = self.get_current()[0]
648
 
        buff.cut_clipboard(self.clipboard, True)
649
 
        return
650
 
 
651
 
    def edit_copy(self, mi):
652
 
        buff = self.get_current()[0]
653
 
        buff.copy_clipboard(self.clipboard)
654
 
        return
655
 
 
656
 
    def edit_paste(self, mi):
657
 
        buff = self.get_current()[0]
658
 
        buff.paste_clipboard(self.clipboard, None, True)
659
 
        return
660
 
 
661
 
    def edit_clear(self, mi):
662
 
        buff = self.get_current()[0]
663
 
        buff.delete_selection(True, True)
664
 
        return
665
 
        
666
 
    def edit_undo(self, mi):
667
 
        buff = self.get_current()[0]
668
 
        buff.undo()
669
 
        
670
 
    def edit_redo(self, mi):
671
 
        buff = self.get_current()[0]
672
 
        buff.redo()
673
 
 
674
 
    def edit_find(self, mi): 
675
 
        def dialog_response_callback(dialog, response_id):
676
 
            if response_id == gtk.RESPONSE_CLOSE:
677
 
                dialog.destroy()
678
 
                return
679
 
            self._search(search_text.get_text(), self.last_search_iter)
680
 
        buff = self.get_current()[0]
681
 
        search_text = gtk.Entry()
682
 
        s = buff.get_selection_bounds()
683
 
        if len(s) > 0:
684
 
            search_text.set_text(buff.get_slice(s[0], s[1]))
685
 
        dialog = gtk.Dialog("Search", self.get_parent_window(),
686
 
                            gtk.DIALOG_DESTROY_WITH_PARENT,
687
 
                            (gtk.STOCK_FIND, RESPONSE_FORWARD,
688
 
                             gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE))
689
 
        dialog.vbox.pack_end(search_text, True, True, 0)
690
 
        dialog.connect("response", dialog_response_callback)
691
 
        dialog.set_default_response(RESPONSE_FORWARD)
692
 
        search_text.set_activates_default(True)
693
 
        search_text.show()
694
 
        search_text.grab_focus()
695
 
        dialog.show_all()
696
 
        response_id = dialog.run()
697
 
        
698
 
    def edit_replace(self, mi): 
699
 
        def dialog_response_callback(dialog, response_id):
700
 
            if response_id == gtk.RESPONSE_CLOSE:
701
 
                dialog.destroy()
702
 
                return
703
 
            if response_id == RESPONSE_FORWARD:
704
 
                self._search(search_text.get_text(), self.last_search_iter)
705
 
                return
706
 
            if response_id == RESPONSE_REPLACE:
707
 
                if not self._search(search_text.get_text(), self.last_search_iter):
708
 
                    return
709
 
                start, end = buff.get_selection_bounds()
710
 
                buff.delete(start, end)
711
 
                buff.insert(start, replace_text.get_text())
712
 
                self.last_search_iter = buff.get_iter_at_mark(buff.get_insert())
713
 
                start = buff.get_iter_at_mark(buff.get_insert())
714
 
                start.backward_chars(len(replace_text.get_text()))
715
 
                buff.select_range(start, self.last_search_iter)
716
 
            if response_id == RESPONSE_REPLACE_ALL:
717
 
                current_iter = buff.get_iter_at_mark(buff.get_insert())
718
 
                while self._search(search_text.get_text(), self.last_search_iter, False):
719
 
                    start, end = buff.get_selection_bounds()
720
 
                    buff.delete(start, end)
721
 
                    buff.insert(start, replace_text.get_text())
722
 
                    self.last_search_iter = buff.get_iter_at_mark(buff.get_insert())
723
 
                    start = buff.get_iter_at_mark(buff.get_insert())
724
 
                    start.backward_chars(len(replace_text.get_text()))
725
 
                    buff.select_range(start, self.last_search_iter)
726
 
                buff.place_cursor(current_iter)
727
 
        buff = self.get_current()[0]
728
 
        search_text = gtk.Entry()
729
 
        replace_text = gtk.Entry() 
730
 
        s = buff.get_selection_bounds()
731
 
        if len(s) > 0:
732
 
            search_text.set_text(buff.get_slice(s[0], s[1]))
733
 
        dialog = gtk.Dialog("Search", self.get_parent_window(),
734
 
                            gtk.DIALOG_DESTROY_WITH_PARENT,
735
 
                            (gtk.STOCK_FIND, RESPONSE_FORWARD,
736
 
                             "Replace", RESPONSE_REPLACE,
737
 
                             "Replace All", RESPONSE_REPLACE_ALL,
738
 
                             gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE))
739
 
        lbl = gtk.Label("Find what:")
740
 
        dialog.vbox.pack_start(lbl, True, True, 0)
741
 
        dialog.vbox.pack_start(search_text, True, True, 0)
742
 
        lbl = gtk.Label("Replace with:")
743
 
        dialog.vbox.pack_start(lbl, True, True, 0)
744
 
        dialog.vbox.pack_start(replace_text, True, True, 0)
745
 
        dialog.connect("response", dialog_response_callback)
746
 
        dialog.set_default_response(RESPONSE_FORWARD)
747
 
        search_text.set_activates_default(True)
748
 
        replace_text.set_activates_default(True)
749
 
        search_text.show()
750
 
        replace_text.show()
751
 
        search_text.grab_focus()
752
 
        dialog.show_all()
753
 
        response_id = dialog.run()
754
 
    
755
 
    def _search(self, search_string, iter = None, scroll=True):
756
 
        buff, fname = self.get_current()
757
 
        if iter is None:
758
 
            start = buff.get_start_iter()
759
 
        else:
760
 
            start = iter
761
 
        i = 0
762
 
        if search_string:
763
 
            self.search_string = search_string
764
 
            res = start.forward_search(search_string, gtk.TEXT_SEARCH_TEXT_ONLY)
765
 
            if res:
766
 
                match_start, match_end = res
767
 
                buff.place_cursor(match_start)
768
 
                buff.select_range(match_start, match_end)
769
 
                if scroll:
770
 
                    self.editor.scroll_to_iter(match_start, 0.25)
771
 
                self.last_search_iter = match_end
772
 
                return True
773
 
            else:
774
 
                self.search_string = None
775
 
                self.last_search_iter = buff.get_iter_at_mark(buff.get_insert())
776
 
                return False
777
 
            
778
 
    def edit_find_next(self, mi):
779
 
        self._search(self.search_string, self.last_search_iter)
780
 
    
781
 
    def goto_line(self, mi=None):
782
 
        def dialog_response_callback(dialog, response_id):
783
 
            if response_id == gtk.RESPONSE_CLOSE:
784
 
                dialog.destroy()
785
 
                return
786
 
            line = line_text.get_text()
787
 
            if line.isdigit():
788
 
                buff, f = self.get_current()
789
 
                titer = buff.get_iter_at_line(int(line)-1)
790
 
                self.editor.scroll_to_iter(titer, 0.25)
791
 
                buff.place_cursor(titer)
792
 
                self.editor.grab_focus()
793
 
                dialog.destroy()
794
 
       
795
 
        line_text = gtk.Entry()
796
 
        dialog = gtk.Dialog("Goto Line", self.get_parent_window(),
797
 
                            gtk.DIALOG_DESTROY_WITH_PARENT,
798
 
                            (gtk.STOCK_GO_FORWARD, RESPONSE_FORWARD,
799
 
                             gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE))
800
 
        dialog.vbox.pack_end(line_text, True, True, 0)
801
 
        dialog.connect("response", dialog_response_callback)
802
 
        dialog.set_default_response(RESPONSE_FORWARD)
803
 
        line_text.set_activates_default(True)
804
 
        line_text.show()
805
 
        line_text.grab_focus()
806
 
        dialog.show_all()
807
 
        response_id = dialog.run()
808
 
 
809
 
    def comment_block(self, mi=None):
810
 
        comment = "#"
811
 
        buf = self.get_current()[0]
812
 
        bound = buf.get_selection_bounds()
813
 
        if len(bound) == 0:
814
 
            it = buf.get_iter_at_mark(buf.get_insert())
815
 
            line = it.get_line()
816
 
            insert_iter = buf.get_iter_at_line(line)
817
 
            buf.insert(insert_iter, comment)
818
 
        else:
819
 
            start, end = bound
820
 
            start_line = start.get_line()
821
 
            end_line = end.get_line()
822
 
            while start_line <= end_line:
823
 
                insert_iter = buf.get_iter_at_line(start_line)
824
 
                if not insert_iter.ends_line():
825
 
                    buf.insert(insert_iter, comment)
826
 
                start_line += 1
827
 
   
828
 
    def uncomment_block(self, mi=None):
829
 
        buf = self.get_current()[0]
830
 
        bound = buf.get_selection_bounds()
831
 
        if len(bound) == 0:
832
 
            it = buf.get_iter_at_mark(buf.get_insert())
833
 
            start = buf.get_iter_at_line(it.get_line())
834
 
            end = buf.get_iter_at_line(it.get_line())
835
 
            count = 0
836
 
            while end.get_char() == "#":
837
 
                end.forward_char()
838
 
                count += 1
839
 
            buf.delete(start, end)
840
 
        else:
841
 
            start, end = bound
842
 
            start_line = start.get_line()
843
 
            end_line = end.get_line()
844
 
            while start_line <= end_line:
845
 
                insert_iter = buf.get_iter_at_line(start_line)
846
 
                if not insert_iter.ends_line():
847
 
                    s_it = buf.get_iter_at_line(start_line)
848
 
                    e_it = buf.get_iter_at_line(start_line)
849
 
                    count = 0
850
 
                    while e_it.get_char() == "#":
851
 
                        e_it.forward_char()
852
 
                        count += 1
853
 
                    buf.delete(s_it, e_it)        
854
 
                start_line += 1
855
 
                
856
 
    def delete_line(self, mi):
857
 
        buf = self.get_current()[0]
858
 
        it = buf.get_iter_at_mark(buf.get_insert())
859
 
        line = it.get_line()
860
 
        start = buf.get_iter_at_line(line)
861
 
        end = buf.get_iter_at_line(line+1)
862
 
        if start.get_line() == end.get_line():
863
 
            end.forward_to_end()
864
 
        buf.delete(start, end)
865
 
            
866
 
    def duplicate_line(self, mi):
867
 
        buf = self.get_current()[0]
868
 
        it = buf.get_iter_at_mark(buf.get_insert())
869
 
        line = it.get_line()
870
 
        start = buf.get_iter_at_line(line)
871
 
        end = buf.get_iter_at_line(line+1)
872
 
        ret = ""
873
 
        if start.get_line() == end.get_line():
874
 
            end.forward_to_end()
875
 
            ret = "\n"
876
 
        text = buf.get_text(start, end)
877
 
        buf.insert(end, ret+text)
878
 
    
879
 
    def upper_selection(self, mi):
880
 
        buf = self.get_current()[0]
881
 
        bound = buf.get_selection_bounds()
882
 
        if not len(bound) == 0:
883
 
            start, end = bound
884
 
            text = buf.get_text(start, end)
885
 
            buf.delete(start, end)
886
 
            buf.insert(start, text.upper())
887
 
            
888
 
    def lower_selection(self, mi):
889
 
        buf = self.get_current()[0]
890
 
        bound = buf.get_selection_bounds()
891
 
        if not len(bound) == 0:
892
 
            start, end = bound
893
 
            text = buf.get_text(start, end)
894
 
            buf.delete(start, end)
895
 
            buf.insert(start, text.lower())
896
 
    
897
 
    def run_script(self, mi):
898
 
        self.file_save()
899
 
        self.plugin.do_evt("bufferexecute") 
900
 
        
901
 
    def stop_script(self, mi):
902
 
        self.plugin.do_evt('killterminal')
903
 
        
904
 
    def debug_script(self, mi):
905
 
        self.plugin.do_evt('debuggerload')
906
 
        buff = self.get_current()[0]
907
 
        titer = buff.get_iter_at_line(0)
908
 
        self.editor.scroll_to_iter(titer, 0.25)
909
 
        buff.place_cursor(titer)
910
 
        
911
 
    def step_script(self, mi):
912
 
        self.plugin.do_evt('step')
913
 
 
914
 
    def next_script(self, mi):
915
 
        self.plugin.do_evt('next')
916
 
 
917
 
    def continue_script(self, mi):
918
 
        self.plugin.do_evt('continue')
919
 
        
920
 
    def next_buffer(self, mi):
921
 
        i = self.current_buffer + 1
922
 
        if i >= len(self.wins):
923
 
            i = 0
924
 
        self.plugin.do_edit('changebuffer', i)
925
 
 
926
 
    def prev_buffer(self, mi):
927
 
        i = self.current_buffer - 1
928
 
        if i < 0:
929
 
            i = len(self.wins) - 1
930
 
        self.plugin.do_edit('changebuffer', i)
931
 
 
932
 
        
933
 
class AutoCompletionWindow(gtk.Window):
934
 
    
935
 
    def __init__(self,  source_view, trig_iter, text, lst, parent, mod, cbound):
936
 
        
937
 
        gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
938
 
        
939
 
        self.set_decorated(False)
940
 
        self.store = gtk.ListStore(str, str, str)
941
 
        self.source = source_view
942
 
        self.it = trig_iter
943
 
        self.mod = mod
944
 
        self.cbounds = cbound
945
 
        self.found = False
946
 
        self.text = text
947
 
        frame = gtk.Frame()
948
 
        
949
 
        for i in lst:
950
 
            self.store.append((gtk.STOCK_CONVERT, i, ""))
951
 
        self.tree = gtk.TreeView(self.store)
952
 
        
953
 
        render = gtk.CellRendererPixbuf()
954
 
        column = gtk.TreeViewColumn('', render, stock_id=0)
955
 
        self.tree.append_column(column)
956
 
        col = gtk.TreeViewColumn()
957
 
        render = gtk.CellRendererText()
958
 
        column = gtk.TreeViewColumn('', render, text=1)
959
 
        self.tree.append_column(column)
960
 
        col = gtk.TreeViewColumn()
961
 
        render = gtk.CellRendererText()
962
 
        column = gtk.TreeViewColumn('', render, text=2)
963
 
        self.tree.append_column(column)
964
 
        rect = source_view.get_iter_location(trig_iter)
965
 
        wx, wy = source_view.buffer_to_window_coords(gtk.TEXT_WINDOW_WIDGET, 
966
 
                                rect.x, rect.y + rect.height)
967
 
 
968
 
        tx, ty = source_view.get_window(gtk.TEXT_WINDOW_WIDGET).get_origin()
969
 
        wth, hht = parent.get_size()
970
 
        width = wth - (tx+wx)
971
 
        height = hht - (ty+wy)
972
 
        if width > 200: width = 200
973
 
        if height > 200: height = 200
974
 
        self.move(wx+tx, wy+ty)
975
 
        self.add(frame)
976
 
        frame.add(self.tree)
977
 
        self.tree.set_size_request(width, height)
978
 
        self.tree.connect('row-activated', self.row_activated_cb)
979
 
        self.tree.connect('focus-out-event', self.focus_out_event_cb)
980
 
        self.tree.connect('key-press-event', self.key_press_event_cb)
981
 
        self.tree.set_search_column(1)
982
 
        self.tree.set_search_equal_func(self.search_func)
983
 
        self.tree.set_headers_visible(False)
984
 
        self.set_transient_for(parent)
985
 
        self.show_all()
986
 
        self.tree.set_cursor((0,))
987
 
        self.tree.grab_focus()
988
 
        
989
 
    def set_list(self, source_view, trig_iter, text, lst, parent, mod, cbound):
990
 
        self.mod = mod
991
 
        self.cbounds = cbound
992
 
        self.store = gtk.ListStore(str, str, str)
993
 
        self.source = source_view
994
 
        self.it = trig_iter
995
 
        self.found = False
996
 
        self.text = text
997
 
        for i in lst:
998
 
            self.store.append((gtk.STOCK_CONVERT, i, ""))
999
 
        self.tree.set_model(self.store)
1000
 
        self.tree.set_search_column(1)
1001
 
        self.tree.set_search_equal_func(self.search_func)
1002
 
        rect = source_view.get_iter_location(trig_iter)
1003
 
        wx, wy = source_view.buffer_to_window_coords(gtk.TEXT_WINDOW_WIDGET, 
1004
 
                                rect.x, rect.y + rect.height)
1005
 
        tx, ty = source_view.get_window(gtk.TEXT_WINDOW_WIDGET).get_origin()
1006
 
        wth, hht = parent.get_size()
1007
 
        wth += tx
1008
 
        hht += ty
1009
 
        width = wth - (wx+tx) 
1010
 
        height = hht - (wy+ty)
1011
 
        if width > 200: width = 200
1012
 
        if height > 200: height = 200
1013
 
        self.move(wx+tx, wy+ty)
1014
 
        self.tree.set_size_request(width, height)
1015
 
        self.show_all()
1016
 
        self.tree.set_cursor((0,))
1017
 
        self.tree.grab_focus()
1018
 
        
1019
 
    def row_activated_cb(self, tree, path, view_column, data = None):
1020
 
        self.complete = self.store[path][1] + self.store[path][2]
1021
 
        self.insert_complete()
1022
 
        
1023
 
    def insert_complete(self):
1024
 
        buff = self.source.get_buffer()
1025
 
        try:
1026
 
            if not self.mod:
1027
 
                s, e = self.cbounds
1028
 
                buff.select_range(buff.get_iter_at_mark(s), buff.get_iter_at_mark(e))
1029
 
                start, end = buff.get_selection_bounds()
1030
 
                buff.delete(start, end)
1031
 
                buff.insert(start, self.complete)
1032
 
            else:
1033
 
                buff.insert_at_cursor(self.complete)
1034
 
        except:
1035
 
            buff.insert_at_cursor(self.complete[len(self.text):])
1036
 
        self.hide()
1037
 
 
1038
 
    def focus_out_event_cb(self, widget, event):
1039
 
        self.hide()
1040
 
 
1041
 
    def key_press_event_cb(self, widget, event):
1042
 
        if event.keyval == gtk.keysyms.Escape:
1043
 
            self.hide()
1044
 
        elif event.keyval == gtk.keysyms.BackSpace:
1045
 
            self.hide()
1046
 
            
1047
 
    def search_func(self, model, column, key, it):
1048
 
        if self.mod:
1049
 
            cp_text = key
1050
 
        else:
1051
 
            cp_text = self.text + key
1052
 
            self.complete = cp_text
1053
 
        if model.get_path(model.get_iter_first()) == model.get_path(it):
1054
 
            self.found = False
1055
 
        if model.get_value(it, column).startswith(cp_text):
1056
 
            self.found = True
1057
 
        if model.iter_next(it) is None and not self.found:
1058
 
            if self.text != "":
1059
 
                self.complete = model.get_value(it, 1)
1060
 
            else:
1061
 
                self.complete = key
1062
 
            self.insert_complete()
1063
 
            self.hide()
1064
 
        return not model.get_value(it, column).startswith(cp_text)
1065
 
 
1066
 
class Cb:
1067
 
    def __init__(self):
1068
 
        self.mainwindow = None
1069
 
        
1070
 
def edit(fname, mainwin=False):
1071
 
    quit_cb = lambda w: gtk.main_quit()
1072
 
    cb = Cb()
1073
 
    w = gtk.Window()
1074
 
    w.connect('delete-event', gtk.main_quit)
1075
 
    cb.mainwindow = w
1076
 
    e = EditWindow(cb, quit_cb=quit_cb)
1077
 
    if fname != "":
1078
 
        w.file_new()
1079
 
    w.set_title("Culebra")
1080
 
    w.add(e)
1081
 
    w.maximize()
1082
 
    w.show_all()
1083
 
    w.set_size_request(0,0)
1084
 
 
1085
 
    w.dirname = os.getcwd()
1086
 
 
1087
 
    if mainwin: gtk.main()
1088
 
    return
1089
 
 
1090
 
if __name__ == '__main__':
1091
 
    import sys
1092
 
 
1093
 
    if len(sys.argv) > 1:
1094
 
        fname = sys.argv[-1]
1095
 
    else:
1096
 
        fname = ""
1097
 
    edit(fname, mainwin=True)
1098