| Trees | Indices | Help |
|
|---|
|
|
1 """
2 Cotains treeview and treemodel classes for displaying the
3 dataproviders
4
5 Copyright: John Stowers, 2006
6 License: GPLv2
7 """
8
9 import gtk
10 import logging
11 log = logging.getLogger("gtkui.Tree")
12
13 import conduit
14 from conduit.ModuleWrapper import ModuleWrapper
15
16 from gettext import gettext as _
17
19 """
20 Represents a category stored in the treemodel. Not generally intended
21 to be used outside of C{conduit.Tree.DataProviderTreeModel}
22 """
24 ModuleWrapper.__init__(
25 self,
26 klass=None,
27 initargs=(),
28 category=category
29 )
30 self.name=category.name
31 self.classname=category.name
32 self.icon_name=category.icon
33 self.module_type="category"
34
37
38 IDX_ICON = 0
39 IDX_NAME = 1
40 IDX_DESCRIPTION = 2
41 IDX_DND_KEY = 3
42 COLUMN_TYPES = (gtk.gdk.Pixbuf, str, str, str)
43
45 """
46 A treemodel for managing dynamically loaded modules. Manages an internal
47 list of L{conduit.ModuleManager.ModuleWrapper}
48
49 @ivar modules: The array of modules under this treeviews control.
50 @type modules: L{conduit.ModuleManager.ModuleWrapper}[]
51 """
53 """
54 TreeModel constructor
55
56 Ignores modules which are not enabled
57 """
58 gtk.GenericTreeModel.__init__(self)
59 #A dictionary mapping wrappers to paths
60 self.pathMappings = {}
61 #2D array of wrappers at their path indexes
62 self.dataproviders = []
63 #Array of wrappers at their path indexes
64 self.cats = []
65
66 #Add dataproviders
67 self.add_dataproviders(
68 conduit.GLOBALS.moduleManager.get_modules_by_type("source","sink","twoway")
69 )
70 conduit.GLOBALS.moduleManager.connect("dataprovider-available",self._on_dataprovider_available)
71 conduit.GLOBALS.moduleManager.connect("dataprovider-unavailable", self._on_dataprovider_unavailable)
72
75
77 i = 0
78 for j in self.cats:
79 if j.category == category_name:
80 return i
81 i += 1
82 return None
83
87
89 self.pathMappings = {}
90 for i, cat in enumerate(self.cats):
91 self.pathMappings[cat] = (i, )
92 for j, dp in enumerate(self.dataproviders[i]):
93 self.pathMappings[dp] = (i, j)
94
98
101
103 """
104 Adds all enabled dataproviders to the model
105 """
106 #Only display enabled modules
107 module_wrapper_list = [m for m in dpw if m.enabled]
108
109 #Add them to the module
110 for mod in module_wrapper_list:
111 #dont signal the GUI to update, providing this model
112 #is added to a view after it has finished being constructed
113 self.add_dataprovider(mod, False)
114
116 """
117 Adds a dataprovider to the model. Creating a category for it if
118 it does not exist
119
120 @param dpw: The dataproviderwrapper to add
121 @param signal: Whether the associated treeview should be signaled to
122 update the GUI. Set to False for the first time the model is
123 built (in the constructor)
124 @type signal: C{bool}
125 """
126 #Do we need to create a category first?
127 i = self._get_category_index_by_name(dpw.category)
128 if i == None:
129 new_cat = CategoryWrapper(dpw.category)
130 self.cats.append(new_cat)
131 i = self.cats.index(new_cat)
132 self.pathMappings[new_cat] = (i,)
133 #Signal the treeview to redraw
134 if signal:
135 path=self.on_get_path(new_cat)
136 self.row_inserted(path, self.get_iter(path))
137
138 #Now add the dataprovider to the categories children
139 try:
140 self.dataproviders[i].append(dpw)
141 except IndexError:
142 #Doesnt have any kids... yet!
143 self.dataproviders.insert(i, [dpw])
144
145 #Store the index
146 j = self.dataproviders[i].index(dpw)
147 self.pathMappings[dpw] = (i,j)
148
149 #Signal the treeview to redraw
150 if signal:
151 path=self.on_get_path(dpw)
152 self.row_inserted(path, self.get_iter(path))
153
155 """
156 Removes the dataprovider from the treemodel. Also removes the
157 category that it was in if there is no remaining dataproviders in
158 that category
159 """
160 path = self.on_get_path(dpw)
161 self.row_deleted(path)
162 del self.dataproviders[path[0]][path[1]]
163
164 #del (self.childrencache[parent])
165
166 i = self._get_category_index_by_name(dpw.category)
167 if len(self.dataproviders[i]) == 0:
168 log.info("Category %s empty - removing." % dpw.category)
169 self.row_deleted((i, ))
170 del self.dataproviders[i]
171 del self.cats[i]
172
173 self._rebuild_path_mappings()
174
180
186
192
194 """
195 on_get_iter(
196 """
197 if len(self.cats) == 0:
198 return None
199 #Check if this is a toplevel row
200 if len(path) == 1:
201 if path[0] > len(self.cats):
202 return None
203 if debug:
204 print "on_get_iter: path = %s cat = %s" % (path, self.cats[path[0]])
205 return self.cats[path[0]]
206 else:
207 try:
208 if debug:
209 print "on_get_iter: path = %s dataprovider = %s" % (path, self.dataproviders[path[0]][path[1]])
210 return self.dataproviders[path[0]][path[1]]
211 except IndexError:
212 #no modules loaded
213 if debug:
214 print "on_get_iter: No modules loaded path = ", path
215 return None
216
218 """
219 on_get_path(
220 """
221 #print "on_get_path: rowref = ", rowref
222 path = self.pathMappings[rowref]
223 #print "PATH = ", path
224 return path
225
227 """
228 on_get_value(
229 """
230 #print "on_get_value: rowref = %s column = %s" % (rowref, column)
231 if column is IDX_ICON:
232 return rowref.get_descriptive_icon()
233 elif column is IDX_NAME:
234 if self._is_category_heading(rowref):
235 return "<b>"+rowref.name+"</b>"
236 else:
237 return rowref.name
238 elif column is IDX_DESCRIPTION:
239 return rowref.description
240 #Used internally from the TreeView to get the key used by the canvas to
241 #reinstantiate new dataproviders
242 elif column is IDX_DND_KEY:
243 if self._is_category_heading(rowref):
244 return ""
245 else:
246 return rowref.get_dnd_key()
247 #Used internally from the TreeView to see if this is a category heading
248 #and subsequently cancel the drag and drop
249 elif column is IDX_IS_CATEGORY:
250 return self._is_category_heading(rowref)
251