1
# -*- coding: utf-8 -*-
2
# Copyright © 2007 Lateef Alabi-Oki
4
# This file is part of Scribes.
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.
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.
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
22
This module documents a class that defines the behavior of the template
23
editor's language treeview.
25
@author: Lateef Alabi-Oki
26
@organization: The Scribes Project
27
@copyright: Copyright © 2007 Lateef Alabi-Oki
28
@license: GNU GPLv2 or Later
29
@contact: mystilleef@gmail.com
32
class TemplateLanguageTreeView(object):
34
This class creates an object that defines the behavior of the
35
template editor's language treeview.
38
def __init__(self, manager, editor):
42
@param self: Reference to the TemplateLanguageTreeView instance.
43
@type self: A TemplateLanguageTreeView object.
45
@param manager: Reference to the TemplateManager instance.
46
@type manager: A TemplateManager object.
48
@param editor: Reference to the text editor.
49
@type editor: An Editor object.
51
self.__init_attributes(manager, editor)
52
self.__set_properties()
53
self.__populate_model()
54
self.__select_language()
55
self.__signal_id_1 = manager.connect("destroy", self.__destroy_cb)
56
self.__signal_id_2 = self.__editor.connect("loaded-document", self.__generic_cb)
57
self.__signal_id_3 = self.__editor.connect("renamed-document", self.__generic_cb)
58
self.__signal_id_4 = manager.connect("show", self.__show_cb)
59
self.__signal_id_5 = self.__treeview.connect("cursor-changed", self.__cursor_changed_cb)
60
self.__signal_id_6 = manager.connect("imported-language", self.__imported_language_cb)
61
self.__signal_id_7 = self.__treeview.connect("drag-data-get", self.__drag_data_get_cb)
62
self.__signal_id_8 = self.__treeview.connect("drag-data-received", self.__drag_data_received_cb)
64
def __init_attributes(self, manager, editor):
66
Initialize data attributes.
68
@param self: Reference to the TemplateLanguageTreeView instance.
69
@type self: A TemplateLanguageTreeView object.
71
@param manager: Reference to the TemplateManager instance.
72
@type manager: A TemplateManager object.
74
@param editor: Reference to the text editor.
75
@type editor: An Editor object.
77
self.__manager = manager
78
self.__editor = editor
79
self.__treeview = manager.glade.get_widget("LanguageTreeView")
80
self.__is_first_time = True
81
self.__model = self.__create_model()
82
self.__renderer = self.__create_renderer()
83
self.__column = self.__create_column()
84
from gtksourceview import SourceLanguagesManager
85
language_list = SourceLanguagesManager().get_available_languages()
86
self.__languages = [name.get_id() for name in language_list]
87
self.__signal_id_1 = self.__signal_id_2 = self.__signal_id_3 = None
88
self.__signal_id_4 = self.__signal_id_5 = self.__signal_id_6 = None
89
self.__signal_id_7 = self.__signal_id_8 = None
92
def __set_properties(self):
94
Set the language view's default properties.
96
@param self: Reference to the TemplateEditorLanguageView instance.
97
@type self: A TemplateEditorLanguageView object.
99
from gtk.gdk import ACTION_DEFAULT, BUTTON1_MASK
100
from gtk import TARGET_SAME_APP
101
self.__treeview.enable_model_drag_source(BUTTON1_MASK, [("STRING", 0, 123)], ACTION_DEFAULT)
102
self.__treeview.enable_model_drag_dest([("STRING", TARGET_SAME_APP, 124)], ACTION_DEFAULT)
103
# self.__treeview.set_property("rules-hint", True)
104
# self.__treeview.set_property("search-column", 0)
105
# self.__treeview.set_property("headers-clickable", True)
106
self.__treeview.append_column(self.__column)
107
self.__treeview.set_model(self.__model)
108
self.__column.clicked()
111
def __create_model(self):
113
Create the model for the template editor's language view.
115
@param self: Reference to the TemplateEditorLanguageView instance.
116
@type self: A TemplateEditorLanguageView object.
118
@return: A model for the language view.
119
@rtype: A gtk.ListStore object.
121
from gtk import ListStore
122
model = ListStore(str, str)
125
def __create_column(self):
127
Create the column for the template editor's language view.
129
@param self: Reference to the TemplateEditorLanguageView instance.
130
@type self: A TemplateEditorLanguageView object.
132
@return: A column for the language view.
133
@rtype: A gtk.TreeViewColumn object.
135
from gtk import TreeViewColumn, TREE_VIEW_COLUMN_GROW_ONLY
136
from gtk import SORT_ASCENDING
137
from i18n import msg0001
138
column = TreeViewColumn(msg0001, self.__renderer, text=0)
139
column.set_property("expand", False)
140
column.set_property("sizing", TREE_VIEW_COLUMN_GROW_ONLY)
141
column.set_property("clickable", True)
142
column.set_sort_column_id(0)
143
column.set_property("sort-indicator", True)
144
column.set_property("sort-order", SORT_ASCENDING)
147
def __create_renderer(self):
149
Create the renderer for the language view's column
151
@param self: Reference to the TemplateEditorLanguageView instance.
152
@type self: A TemplateEditorLanguageView object.
154
@return: A renderer for the language view.
155
@rtype: A gtk.CellRendererText object.
157
from gtk import CellRendererText
158
renderer = CellRendererText()
161
def __populate_model(self):
163
Populate the language view's model.
165
@param self: Reference to the TemplateLanguageTreeView instance.
166
@type self: A TemplateLanguageTreeView object.
168
from gtksourceview import SourceLanguagesManager
169
language_list = SourceLanguagesManager().get_available_languages()
170
language_names = [(name.get_name(), name.get_id()) for name in language_list]
171
self.__model.append(["General", "General"])
172
for name, id in language_names:
173
self.__model.append([name, id])
176
def __select_language(self, language=None):
178
Select a row corresponding to the language in the tree view.
180
@param self: Reference to the TemplateLanguageTreeView instance.
181
@type self: A TemplateLanguageTreeView object.
183
from operator import eq, not_
185
language_id = self.__get_language()
187
language_id = language
189
iterator = model.get_iter_first()
190
language = model.get_value(iterator, 1)
191
if eq(language, language_id):
192
selection = self.__treeview.get_selection()
193
selection.select_iter(iterator)
194
path = model.get_path(iterator)
195
self.__treeview.scroll_to_cell(path, self.__treeview.get_column(0), True, 0.5, 0.0)
198
iterator = model.iter_next(iterator)
200
language = model.get_value(iterator, 1)
201
if eq(language, language_id):
202
selection = self.__treeview.get_selection()
203
selection.select_iter(iterator)
204
path = model.get_path(iterator)
205
self.__treeview.scroll_to_cell(path, self.__treeview.get_column(0), True, 0.5, 0.0)
211
def __get_language(self):
213
Get the current language of the file in the text editor.
215
@param self: Reference to the TemplateLanguageTreeView instance.
216
@type self: A TemplateLanguageTreeView object.
218
@return: Return a language or "General"
219
@rtype: A String object.
221
language = self.__editor.language
222
from operator import not_
223
if not_(language): return "General"
224
return language.get_id()
226
def __get_templates(self, language):
228
from Metadata import open_template_database
229
from Metadata import close_template_database
230
from operator import eq, not_, ne
231
same_prefix = lambda x: x.startswith(language)
232
remove_language = lambda x: ne(x, language)
233
similar_prefix = filter(remove_language, filter(same_prefix, self.__languages))
234
database = open_template_database()
235
for key in database.keys():
237
for value in similar_prefix:
238
if key.startswith(value):
242
if key.startswith(language):
244
trigger = key.replace(language, "")
245
description = database[key][0]
246
template = database[key][1]
247
templates.append((language, trigger, description, template))
248
close_template_database(database)
251
def __get_drop_row(self, path):
253
Get the language of the row drag and drop occurred.
255
@param self: Reference to the TemplateEditorLanguageView instance.
256
@type self: A TemplateEditorLanguageView object.
258
@param path: The row a drag and drop occurred.
259
@type path: A Tuple object.
261
@return: The language identifier of the row a drag and drop occurred.
262
@rtype: A String object.
264
model = self.__treeview.get_model()
265
iterator = model.get_iter(path)
266
language_id = model.get_value(iterator, 1)
269
def __create_new_templates(self, templates, language):
271
Convert old template information to new one.
273
@param self: Reference to the LanguageTreeView instance.
274
@type self: A LanguageTreeView object.
276
@param templates: Reference to the templates information.
277
@type templates: A List object.
279
@param language: Language category to convert templates to.
280
@type language: A String object.
282
def new_template(data):
283
key, description, template, old_language = data
284
return language, key[len(language):], description, template
285
templates = map(new_template, templates)
288
def __destroy_cb(self, manager):
290
Handles callback when the "destroy" signal is emitted.
292
@param self: Reference to the TemplateLanguageTreeView instance.
293
@type self: A TemplateLanguageTreeView object.
295
@param manager: Reference to the TemplateManager instance.
296
@type manager: A TemplateManager object.
298
from SCRIBES.utils import delete_attributes, disconnect_signal
299
disconnect_signal(self.__signal_id_1, manager)
300
disconnect_signal(self.__signal_id_2, self.__editor)
301
disconnect_signal(self.__signal_id_3, self.__editor)
302
disconnect_signal(self.__signal_id_4, manager)
303
disconnect_signal(self.__signal_id_5, self.__treeview)
304
disconnect_signal(self.__signal_id_6, manager)
305
disconnect_signal(self.__signal_id_7, self.__treeview)
306
disconnect_signal(self.__signal_id_8, self.__treeview)
308
self.__treeview.destroy()
309
delete_attributes(self)
314
def __cursor_changed_cb(self, *args):
316
Handles callback when the "cursor-changed" signal is emitted.
318
@param self: Reference to the TemplateLanguageTreeView instance.
319
@type self: A TemplateLanguageTreeView object.
322
selection = self.__treeview.get_selection()
323
model, iterator = selection.get_selected()
324
language_id = model.get_value(iterator, 1)
325
self.__manager.emit("language-selected", language_id)
330
def __generic_cb(self, *args):
332
A generic callback handler to select a language.
334
@param self: Reference to the TemplateLanguageTreeView instance.
335
@type self: A TemplateLanguageTreeView object.
337
self.__select_language()
340
def __show_cb(self, *args):
342
Handles callback when the "show" signal is emitted.
344
@param self: Reference to the TemplateLanguageTreeView instance.
345
@type self: A TemplateLanguageTreeView object.
347
self.__treeview.grab_focus()
348
from SCRIBES.utils import select_row
349
select_row(self.__treeview)
352
def __imported_language_cb(self, manager, language):
354
Handles callback when the "imported-language" signal is emitted.
356
@param self: Reference to the TemplateLanguageTreeView instance.
357
@type self: A TemplateLanguageTreeView object.
359
@param manager: Reference to the TemplateManager instance.
360
@type manager: A TemplateManager object.
362
@param language: A language category
363
@type language: A String object.
365
self.__select_language(language)
366
# No error occurred. I'm just using the signal to make the
367
# template editor window sensitive.
368
manager.emit("import-error")
369
from SCRIBES.utils import select_row
370
select_row(self.__treeview)
371
self.__treeview.grab_focus()
374
def __drag_data_get_cb(self, treeview, context, data, info, time):
376
from Exceptions import NoDataError
377
selection = treeview.get_selection()
378
model, iterator = selection.get_selected()
379
language_id = model.get_value(iterator, 1)
380
templates = self.__get_templates(language_id)
381
from operator import not_
382
if not_(templates): raise NoDataError
383
from WriteXMLTemplate import create_template_string
384
string = create_template_string(templates)
385
data.set(data.target, 8, string)
390
def __drag_data_received_cb(self, treeview, context, x, y, data, info, time):
392
Handles callback when the "drag-data-received" signal is emitted.
394
@param self: Reference to the TemplateLanguageTreeView instance.
395
@type self: A TemplateLanguageTreeView object.
397
@param treeview: Reference to the TemplateEditorLanguageView.
398
@type treeview: A TemplateEditorLanguageView object.
400
@param context: An object containing data about a drag selection.
401
@type context: A gtk.DragContextData object.
403
@param x: The x-cordinate of the drop.
404
@type x: An Integer object.
406
@param y: The y-cordinate of the drop.
407
@type y: An Integer object.
409
@param selection_data: Data representing the drag selection.
410
@type selection_data: A gtk.SelectionData object.
412
@param info: A unique identification for the text editor.
413
@type info: An Integer object.
415
@param time: The time the drop operation occurred.
416
@type time: An Integer object.
418
@return: True to propagate signals to parent widgets.
419
@type: A Boolean Object.
422
from Exceptions import InvalidFileError, ValidationError
423
from Exceptions import NoDataError
424
path, position = treeview.get_dest_row_at_pos(x, y)
425
from gtk import TREE_VIEW_DROP_BEFORE, TREE_VIEW_DROP_AFTER
426
if position in [TREE_VIEW_DROP_BEFORE, TREE_VIEW_DROP_AFTER]: return True
427
language_id = self.__get_drop_row(path)
429
from ReadXMLTemplate import get_template_from_string
430
templates = get_template_from_string(string)
431
from operator import not_
432
if not_(templates): raise NoDataError
433
new_templates = self.__create_new_templates(templates, language_id)
434
from WriteXMLTemplate import create_template_string
435
template_string = create_template_string(new_templates)
436
from ImportTemplate import import_template_from_string
437
templates = import_template_from_string(template_string)
438
if not_(templates): raise NoDataError
439
self.__manager.emit("imported-language", language_id)
440
except InvalidFileError:
441
from i18n import msg0014
442
self.__editor.error_dialog.show_message(msg0014, parent_window=self.__dialog)
443
self.__manager.emit("import-error")
444
except ValidationError:
445
from i18n import msg0014
446
self.__editor.error_dialog.show_message(msg0014, parent_window=self.__dialog)
447
self.__manager.emit("import-error")
449
from i18n import msg0015
450
self.__editor.error_dialog.show_message(msg0015, parent_window=self.__dialog)
451
self.__manager.emit("import-error")