/
giface.py
291 lines (221 loc) · 9.38 KB
/
giface.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
"""
@package lmgr.giface
@brief Layer Manager GRASS interface
Classes:
- giface::LayerManagerGrassInterface
(C) 2012 by the GRASS Development Team
This program is free software under the GNU General Public License
(>=v2). Read the file COPYING that comes with GRASS for details.
@author Anna Kratochvilova <kratochanna gmail.com>
@author Vaclav Petras <wenzeslaus gmail.com>
"""
from __future__ import print_function
import os
from grass.pydispatch.signal import Signal
from core.giface import Notification
from core.utils import GetLayerNameFromCmd
class Layer(object):
"""@implements core::giface::Layer
.. note::
Currently implemented without specifying the interface.
It only provides all attributes of existing layer as used in lmgr.
"""
def __init__(self, layer, pydata):
self._layer = layer
self._pydata = pydata
def __getattr__(self, name):
return self._pydata[0][name]
def __dir__(self):
return self._pydata[0].keys()
def __str__(self):
return '' if self.maplayer.name is None else self.maplayer.name
class LayerList(object):
"""@implements core.giface.Layer"""
def __init__(self, tree):
self._tree = tree
def __len__(self):
return len([layer for layer in self])
def __iter__(self):
"""Iterates over the contents of the list."""
item = self._tree.GetFirstChild(self._tree.root)[0]
while item and item.IsOk():
yield Layer(item, self._tree.GetPyData(item))
item = self._tree.GetNextItem(item)
def __getitem__(self, index):
"""Select a layer from the LayerList using the index."""
return [l for l in self][index]
def __repr__(self):
"""Return a representation of the object."""
return "LayerList(%r)" % [layer for layer in self]
def GetSelectedLayers(self, checkedOnly=True):
items = self._tree.GetSelectedLayer(multi=True,
checkedOnly=checkedOnly)
layers = []
for item in items:
layer = Layer(item, self._tree.GetPyData(item))
layers.append(layer)
return layers
# TODO: it is not clear if default of checkedOnly should be False or True
def GetSelectedLayer(self, checkedOnly=False):
"""Returns selected layer or None when there is no selected layer."""
item = self._tree.GetSelectedLayer(multi=False,
checkedOnly=checkedOnly)
if item is None:
return None
else:
data = self._tree.GetPyData(item)
return Layer(item, data)
def GetLayerInfo(self, layer):
"""For compatibility only, will be removed."""
return Layer(layer, self._tree.GetPyData(layer))
def AddLayer(self, ltype, name=None, checked=None,
opacity=1.0, cmd=None):
"""Adds a new layer to the layer list.
Launches property dialog if needed (raster, vector, etc.)
:param ltype: layer type (raster, vector, raster_3d, ...)
:param name: layer name
:param checked: if True layer is checked
:param opacity: layer opacity level
:param cmd: command (given as a list)
"""
l = self._tree.AddLayer(ltype=ltype, lname=name, lchecked=checked,
lopacity=opacity, lcmd=cmd)
return Layer(l, self._tree.GetPyData(l))
def DeleteLayer(self, layer):
"""Remove layer from layer list"""
self._tree.Delete(layer._layer)
def CheckLayer(self, layer, checked=True):
"""Check or uncheck layer"""
self._tree.forceCheck = True
self._tree.CheckItem(layer._layer, checked=checked)
def SelectLayer(self, layer, select=True):
"Select or unselect layer"
self._tree.SelectItem(layer._layer, select)
def ChangeLayer(self, layer, **kwargs):
"Change layer (cmd, ltype, opacity)"
if 'cmd' in kwargs:
layer._pydata[0]['cmd'] = kwargs['cmd']
layerName, found = GetLayerNameFromCmd(kwargs['cmd'], fullyQualified=True)
if found:
layer._pydata[0]['label'] = layerName
if 'ltype' in kwargs:
layer._pydata[0]['type'] = kwargs['ltype']
if 'opacity' in kwargs:
layer._pydata[0]['maplayer'].SetOpacity(kwargs['opacity'])
self._tree.ChangeLayer(layer._layer)
self._tree.SetItemIcon(layer._layer)
self._tree.SetItemText(layer._layer, self._tree._getLayerName(layer._layer))
def IsLayerChecked(self, layer):
"""Returns True if layer is checked, False otherwise"""
return self._tree.IsItemChecked(layer._layer)
def GetLayersByName(self, name):
items = self._tree.FindItemByData(key='name', value=name)
if items is None:
return []
else:
layers = []
for item in items:
layer = Layer(item, self._tree.GetPyData(item))
layers.append(layer)
return layers
def GetLayerByData(self, key, value):
"""Returns layer with specified.
Returns only one layer.
Avoid using this method, it might be removed in the future.
"""
if key == 'name':
print("giface.GetLayerByData(): Do not with use key='name',"
" use GetLayersByName instead.")
item = self._tree.FindItemByData(key=key, value=value)
if item is None:
return None
else:
return Layer(item, self._tree.GetPyData(item))
class LayerManagerGrassInterface(object):
"""@implements core::giface::GrassInterface"""
def __init__(self, lmgr):
"""Costructor is specific to the current implementation.
Uses Layer Manager object including its private attributes.
(It encapsulates existing Layer Manager so access to private members
is intention.)
"""
self.lmgr = lmgr
# Signal when some map is created or updated by a module.
# attributes: name: map name, ltype: map type,
# add: if map should be added to layer tree (questionable attribute)
self.mapCreated = Signal('LayerManagerGrassInterface.mapCreated')
# Signal emitted to request updating of map
self.updateMap = Signal('LayerManagerGrassInterface.updateMap')
def RunCmd(self, *args, **kwargs):
self.lmgr._gconsole.RunCmd(*args, **kwargs)
def Help(self, entry, online=False):
cmdlist = ['g.manual', 'entry=%s' % entry]
if online:
cmdlist.append('-o')
self.RunCmd(cmdlist, compReg=False,
notification=Notification.NO_NOTIFICATION)
def WriteLog(self, text, wrap=None,
notification=Notification.HIGHLIGHT):
self.lmgr._gconsole.WriteLog(text=text, wrap=wrap,
notification=notification)
def WriteCmdLog(self, text, pid=None,
notification=Notification.MAKE_VISIBLE):
self.lmgr._gconsole.WriteCmdLog(text=text, pid=pid,
notification=notification)
def WriteWarning(self, text):
self.lmgr._gconsole.WriteWarning(text=text)
def WriteError(self, text):
self.lmgr._gconsole.WriteError(text=text)
def GetLayerTree(self):
return self.lmgr.GetLayerTree()
def GetLayerList(self):
return LayerList(self.lmgr.GetLayerTree())
def GetMapDisplay(self):
return self.lmgr.GetMapDisplay(onlyCurrent=True)
def GetAllMapDisplays(self):
return self.lmgr.GetMapDisplay(onlyCurrent=False)
def GetMapWindow(self):
if self.lmgr.GetMapDisplay(onlyCurrent=True):
return self.lmgr.GetMapDisplay(onlyCurrent=True).GetMapWindow()
else:
return None
def GetProgress(self):
return self.lmgr.goutput.GetProgressBar()
def UpdateCmdHistory(self, cmd):
self.lmgr.goutput.GetPrompt().UpdateCmdHistory(cmd)
def ShowStatusbar(self, show=True):
self.lmgr.GetMapDisplay().statusbarManager.Show(show)
def IsStatusbarShown(self):
return self.lmgr.GetMapDisplay().statusbarManager.IsShown()
def ShowAllToolbars(self, show=True):
if not show: # hide
action = self.lmgr.GetMapDisplay().RemoveToolbar
else:
action = self.lmgr.GetMapDisplay().AddToolbar
for toolbar in self.lmgr.GetMapDisplay().GetToolbarNames():
action(toolbar)
def AreAllToolbarsShown(self):
return self.lmgr.GetMapDisplay().GetMapToolbar().IsShown()
class LayerManagerGrassInterfaceForMapDisplay(object):
"""Provides reference only to the given layer list (according to tree),
not to the current.
@implements core::giface::GrassInterface
"""
def __init__(self, giface, tree):
"""
:param giface: original grass interface
:param tree: tree which will be used instead of the tree from giface
"""
self._giface = giface
self.tree = tree
# Signal emitted to request updating of map
self.updateMap = Signal(
'LayerManagerGrassInterfaceForMapDisplay.updateMap')
def GetLayerTree(self):
return self.tree
def GetLayerList(self):
return LayerList(self.tree)
def GetMapWindow(self):
return self.tree.GetMapDisplay().GetMapWindow()
def __getattr__(self, name):
return getattr(self._giface, name)