~sir-rainbow/+junk/scribes-on-win

« back to all changes in this revision

Viewing changes to SCRIBES/TextBuffer.py

  • Committer: goldenmyst
  • Date: 2007-09-25 17:15:52 UTC
  • Revision ID: goldenmyst@goldenmyst-desktop-20070925171552-mvrhxdd39iibs0sr
New branch. New Trigger Management System. New Trigger API. New Plugin Management System. Fix for bug triggered by PyGTK+ version 2.11 or better.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
# Copyright (C) 2005 Lateef Alabi-Oki
 
3
#
 
4
# This file is part of Scribes.
 
5
#
 
6
# Scribes is free software; you can redistribute it and/or modify
 
7
# it under the terms of the GNU General Public License as published by
 
8
# the Free Software Foundation; either version 2 of the License, or
 
9
# (at your option) any later version.
 
10
#
 
11
# Scribes is distributed in the hope that it will be useful,
 
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
# GNU General Public License for more details.
 
15
#
 
16
# You should have received a copy of the GNU General Public License
 
17
# along with Scribes; if not, write to the Free Software
 
18
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
19
 
 
20
"""
 
21
This module implements a class that creates the buffer for the text
 
22
editor.
 
23
 
 
24
@author: Lateef Alabi-Oki
 
25
@organiation: The Scribes Project
 
26
@copyright: Copyright © 2005 Lateef Alabi-Oki
 
27
@license: GNU GPLv2 or Later
 
28
@contact: mystilleef@gmail.com
 
29
"""
 
30
 
 
31
from gtksourceview import SourceBuffer
 
32
 
 
33
class ScribesTextBuffer(SourceBuffer):
 
34
        """
 
35
        This class creates the buffer for the text editor.
 
36
        """
 
37
 
 
38
        def __init__(self, editor):
 
39
                """
 
40
                Initialize object.
 
41
 
 
42
                @param self: Reference to a ScribesTextBuffer instance.
 
43
                @type self: A ScribesTextBuffer object.
 
44
 
 
45
                @param editor: Reference to the text editor.
 
46
                @type editor: An Editor object.
 
47
                """
 
48
                SourceBuffer.__init__(self)
 
49
                self.__init_attributes(editor)
 
50
                self.__set_properties()
 
51
                self.__signal_id_1 = editor.connect("close-document-no-save", self.__close_document_no_save_cb)
 
52
                self.__signal_id_2 = editor.connect("checking-document", self.__checking_document_cb)
 
53
                self.__signal_id_3 = editor.connect("loaded-document", self.__loaded_document_cb)
 
54
                self.__signal_id_4 = editor.connect("load-error", self.__load_error_cb)
 
55
                self.__signal_id_5 = editor.connect("saved-document", self.__saved_document_cb)
 
56
                self.__signal_id_6 = editor.connect("enable-readonly", self.__enable_readonly_cb)
 
57
                self.__signal_id_7 = editor.connect("disable-readonly", self.__disable_readonly_cb)
 
58
                self.__signal_id_8 = editor.connect("close-document", self.__close_document_cb)
 
59
                self.__signal_id_9 = editor.connect("renamed-document", self.__renamed_document_cb)
 
60
                self.__signal_id_10 = self.connect("notify::cursor-position", self.__cursor_position_cb)
 
61
                self.__signal_id_11 = editor.connect("reload-document", self.__reload_document_cb)
 
62
                self.__signal_id_12 = self.connect_after("notify::cursor-position", self.__cursor_position_after_cb)
 
63
 
 
64
        def __init_attributes(self, editor):
 
65
                """
 
66
                Initialize the attributes of the text editor's buffer.
 
67
 
 
68
                This function contains some attributes not available in the
 
69
                gtksourceview.SourceBuffer class. The attributes provided solely for
 
70
                purpose of the text editor.
 
71
 
 
72
                @param self: Reference to the ScribesTextBuffer instance.
 
73
                @type self: A ScribesTextBuffer object.
 
74
 
 
75
                @param editor: Reference to the text editor.
 
76
                @type editor: An Editor object.
 
77
                """
 
78
                self.__editor = editor
 
79
                self.__uri = None
 
80
                # Register a unique number with the editor's termination queue
 
81
                self.__termination_id = editor.register_termination_id()
 
82
                self.__undoable_action = False
 
83
                self.__signal_id_1 = self.__signal_id_2 = self.__signal_id_3 = None
 
84
                self.__signal_id_4 = self.__signal_id_5 = self.__signal_id_6 = None
 
85
                self.__signal_id_7 = self.__signal_id_8 = self.__signal_id_9 = None
 
86
                self.__signal_id_10 = None
 
87
                return
 
88
 
 
89
        def __set_properties(self):
 
90
                """
 
91
                Set the editor's buffer properties.
 
92
 
 
93
                @param self: Reference to the ScribesTextBuffer instance.
 
94
                @type self: A ScribesTextBuffer object.
 
95
                """
 
96
                self.notify("cursor-position")
 
97
                self.set_check_brackets(False)
 
98
                self.set_max_undo_levels(0)
 
99
                self.set_text("")
 
100
                self.set_modified(False)
 
101
                return
 
102
 
 
103
################################################################################
 
104
#
 
105
#                                                       Signal Handlers
 
106
#
 
107
################################################################################
 
108
 
 
109
        def __checking_document_cb(self, editor, uri):
 
110
                """
 
111
                Handles callback when the text editor is in the process of loading a
 
112
                document into the text editor's buffer.
 
113
 
 
114
                @param self: Reference to the ScribesTextBuffer instance.
 
115
                @type self: A ScribesTextBuffer object.
 
116
 
 
117
                @param editor: An instance of the text editor's.
 
118
                @type editor: An Editor object.
 
119
                """
 
120
                self.__uri = uri
 
121
                self.begin_not_undoable_action()
 
122
                self.__undoable_action = True
 
123
                from gobject import idle_add
 
124
                idle_add(self.__activate_sytnax_colors)
 
125
                return
 
126
 
 
127
        def __loaded_document_cb(self, editor, uri):
 
128
                """
 
129
                Handles callback when the text editor has finished loading documents
 
130
                into the text editor's buffer.
 
131
 
 
132
                @param self: Reference to the ScribesTextBuffer instance.
 
133
                @type self: A ScribesTextBuffer object.
 
134
 
 
135
                @param editor: An instance of the text editor.
 
136
                @type editor: An Editor object.
 
137
                """
 
138
                self.set_modified(False)
 
139
                self.end_not_undoable_action()
 
140
                self.__undoable_action = False
 
141
                self.__set_cursor_positon()
 
142
                return
 
143
 
 
144
        def __saved_document_cb(self, editor, uri):
 
145
                """
 
146
                Handles callback when the text editor's buffer has finished saving the
 
147
                contents of the text editor's buffer.
 
148
 
 
149
                @param self: Reference to the ScribesTextBuffer instance.
 
150
                @type self: A ScribesTextBuffer object.
 
151
 
 
152
                @param editor: An instance of the text editor's.
 
153
                @type editor: An Editor object.
 
154
                """
 
155
                self.set_modified(False)
 
156
                return
 
157
 
 
158
        def __enable_readonly_cb(self, editor):
 
159
                """
 
160
                Handles callback when the text editor is switched to readonly mode.
 
161
 
 
162
                @param self: Reference to the ScribesTextBuffer instance.
 
163
                @type self: A ScribesTextBuffer object.
 
164
 
 
165
                @param editor: An instance of the text editor.
 
166
                @type editor: An Editor object.
 
167
                """
 
168
                self.set_check_brackets(False)
 
169
                return
 
170
 
 
171
        def __disable_readonly_cb(self, editor):
 
172
                """
 
173
                Handles callback when the text editor is switched from readonly to
 
174
                readwrite mode.
 
175
 
 
176
                @param self: Reference to the ScribesTextBuffer instance.
 
177
                @type self: A ScribesTextBuffer object.
 
178
 
 
179
                @param editor: An instance of the text editor.
 
180
                @type editor: An Editor object.
 
181
                """
 
182
                self.set_check_brackets(True)
 
183
                return
 
184
 
 
185
        def __load_error_cb(self, editor, uri):
 
186
                """
 
187
                Handles callback when the text editor fails to load a document.
 
188
 
 
189
                This function resets the buffer to a usable state.
 
190
 
 
191
                @param self: Reference to the ScribesTextBuffer instance.
 
192
                @type self: A ScribesTextBuffer object.
 
193
 
 
194
                @param editor: An instance of the text editor
 
195
                @type editor: An Editor object.
 
196
                """
 
197
                self.__uri = None
 
198
                if self.__undoable_action:
 
199
                        self.end_not_undoable_action()
 
200
                self.__set_properties()
 
201
                return
 
202
 
 
203
        def __close_document_cb(self, editor):
 
204
                """
 
205
                Handles callback when the "quit" signal is emitted.
 
206
 
 
207
                @param self: Reference to the ScribesTextBuffer instance.
 
208
                @type self: A ScribesTextBuffer object.
 
209
 
 
210
                @param editor: Reference to the text editor.
 
211
                @type editor: An Editor object.
 
212
                """
 
213
                from gobject import idle_add
 
214
                idle_add(self.__update_cursor_metadata, self.__uri)
 
215
                return
 
216
 
 
217
        def __close_document_no_save_cb(self, editor):
 
218
                self.__destroy()
 
219
                return
 
220
 
 
221
        def __renamed_document_cb(self, editor, uri):
 
222
                """
 
223
                Handles callback when the name of the document is renamed.
 
224
 
 
225
                @param self: Reference to the ScribesTextBuffer instance.
 
226
                @type self: A ScribesTextBuffer object.
 
227
 
 
228
                @param editor: Reference to the text editor.
 
229
                @type editor: An Editor object.
 
230
                """
 
231
                self.__uri = uri
 
232
                self.__activate_sytnax_colors()
 
233
                self.set_modified(False)
 
234
                self.set_check_brackets(True)
 
235
                return
 
236
 
 
237
        def __reload_document_cb(self, *args):
 
238
                self.set_modified(False)
 
239
                self.set_text("")
 
240
                self.set_modified(False)
 
241
                return
 
242
 
 
243
        def __cursor_position_cb(self, *args):
 
244
                try:
 
245
                        self.__editor.emit("cursor-moved")
 
246
                        from gobject import idle_add, source_remove
 
247
                        source_remove(self.__cursor_id)
 
248
                except:
 
249
                        pass
 
250
                self.__cursor_id = idle_add(self.__test_response)
 
251
                return False
 
252
 
 
253
        def __cursor_position_after_cb(self, *args):
 
254
                try:
 
255
                        from gobject import idle_add, source_remove
 
256
                        source_remove(self.__cursor_after_id)
 
257
                except:
 
258
                        pass
 
259
                self.__cursor_after_id = idle_add(self.__test_response)
 
260
                return False
 
261
 
 
262
        def __test_response(self):
 
263
                self.__editor.response()
 
264
                return False
 
265
 
 
266
########################################################################
 
267
#
 
268
#                                               Helper Methods
 
269
#
 
270
########################################################################
 
271
 
 
272
        def __activate_sytnax_colors(self):
 
273
                """
 
274
                Activate syntax highlight colors for the text editor's buffer.
 
275
 
 
276
                @param self: Reference to the ScribesTextBuffer instance.
 
277
                @type self: A ScribesTextBuffer object.
 
278
 
 
279
                @return: True to call this function again, False otherwise.
 
280
                @rtype: A Boolean object.
 
281
                """
 
282
                # Activate syntax highlight for the language.
 
283
                from syntax import activate_syntax_highlight
 
284
                activate_syntax_highlight(self, self.__editor.language)
 
285
                return False
 
286
 
 
287
        def __update_cursor_metadata(self, uri):
 
288
                """
 
289
                Update the cursor database with information about the cursor position in
 
290
                the text editor's buffer.
 
291
 
 
292
                @param self: Reference to the ScribesWindow instance.
 
293
                @type self: A ScribesWindow object.
 
294
 
 
295
                @param uri: A universal resource identifier representing, or pointing
 
296
                        to, a text document.
 
297
                @type uri: A String object.
 
298
                """
 
299
                if self.__uri:
 
300
                        from cursor_metadata import update_cursor_position_in_database
 
301
                        from cursor import get_cursor_line, get_cursor_index
 
302
                        cursor_line = get_cursor_line(self)
 
303
                        cursor_index = get_cursor_index(self)
 
304
                        cursor_position = cursor_line, cursor_index
 
305
                        update_cursor_position_in_database(uri, cursor_position)
 
306
                self.__destroy()
 
307
                return False
 
308
 
 
309
        def __set_cursor_positon(self):
 
310
                """
 
311
                Determine where to place the cursor when a file is loaded.
 
312
 
 
313
                The editor stores the last cursor position in a database so that
 
314
                when a file is loaded the cursor is placed at the last position in the
 
315
                file.
 
316
 
 
317
                However, it is possible that another software program alters the state
 
318
                of the file. Thus making the information in the editor's database
 
319
                obsolete. In such a case, the editor tries to determine where to place
 
320
                the cursor.
 
321
 
 
322
                If the changes are too drastic, the editor places the cursor at the
 
323
                begining of the file. If the changes are minor, the editor places the
 
324
                cursor at an approximate position close the the last position the cursor
 
325
                was last seen.
 
326
 
 
327
                @param self: Reference to the Loader object.
 
328
                @type self: A Loader object.
 
329
                """
 
330
                self.__editor.response()
 
331
                try:
 
332
                        from cursor_metadata import get_cursor_position_from_database
 
333
                        position = get_cursor_position_from_database(self.__uri)
 
334
                        cursor_line, cursor_index = position[0] + 1, position[1]
 
335
                except TypeError:
 
336
                        cursor_line, cursor_index = 1, 0
 
337
                start_iterator = self.get_start_iter()
 
338
                number_of_lines = self.get_line_count()
 
339
                from operator import gt
 
340
                if gt(cursor_line, number_of_lines):
 
341
                        self.place_cursor(start_iterator)
 
342
                        self.__editor.response()
 
343
                        return
 
344
                iterator = self.get_iter_at_line(cursor_line - 1)
 
345
                line_index = iterator.get_bytes_in_line()
 
346
                if gt(cursor_index, line_index):
 
347
                        iterator.set_line_index(line_index)
 
348
                else:
 
349
                        iterator.set_line_index(cursor_index)
 
350
                self.place_cursor(iterator)
 
351
                from cursor import move_view_to_cursor
 
352
                move_view_to_cursor(self.__editor.textview)
 
353
                self.__editor.response()
 
354
                return False
 
355
 
 
356
        def __precompile_methods(self):
 
357
                try:
 
358
                        from psyco import bind
 
359
#                       bind(self.__set_cursor_positon)
 
360
#                       bind(self.__update_cursor_metadata)
 
361
#                       bind(self.__activate_sytnax_colors)
 
362
                except ImportError:
 
363
                        pass
 
364
                return False
 
365
 
 
366
        def __destroy(self):
 
367
                from utils import disconnect_signal, delete_attributes
 
368
                disconnect_signal(self.__signal_id_1, self.__editor)
 
369
                disconnect_signal(self.__signal_id_2, self.__editor)
 
370
                disconnect_signal(self.__signal_id_3, self.__editor)
 
371
                disconnect_signal(self.__signal_id_4, self.__editor)
 
372
                disconnect_signal(self.__signal_id_5, self.__editor)
 
373
                disconnect_signal(self.__signal_id_6, self.__editor)
 
374
                disconnect_signal(self.__signal_id_7, self.__editor)
 
375
                disconnect_signal(self.__signal_id_8, self.__editor)
 
376
                disconnect_signal(self.__signal_id_9, self.__editor)
 
377
                disconnect_signal(self.__signal_id_10, self)
 
378
                disconnect_signal(self.__signal_id_11, self.__editor)
 
379
                disconnect_signal(self.__signal_id_12, self)
 
380
                self.__editor.unregister_termination_id(self.__termination_id)
 
381
                delete_attributes(self)
 
382
                del self
 
383
                self = None
 
384
                return False