71
65
wx.Frame.__init__(self, parent = parent, id = id, style = style)
73
67
self.locale = wx.Locale(language = wx.LANGUAGE_DEFAULT)
75
self.panel = scrolled.ScrolledPanel(parent = self, id = wx.ID_ANY)
69
# scroll panel was used here but not properly and is probably not need
70
# as long as it is not high too much
71
self.panel = wx.Panel(parent=self, id=wx.ID_ANY)
79
gettext.install('grasswxpy', os.path.join(os.getenv("GISBASE"), 'locale'), unicode = True)
82
76
# graphical elements
86
name = os.path.join(globalvar.ETCIMGDIR, "startup_banner.gif")
80
if os.getenv('ISISROOT'):
81
name = os.path.join(globalvar.GUIDIR, "images", "startup_banner_isis.png")
83
name = os.path.join(globalvar.GUIDIR, "images", "startup_banner.png")
87
84
self.hbitmap = wx.StaticBitmap(self.panel, wx.ID_ANY,
88
85
wx.Bitmap(name = name,
89
type = wx.BITMAP_TYPE_GIF))
86
type = wx.BITMAP_TYPE_PNG))
91
self.hbitmap = wx.StaticBitmap(self.panel, wx.ID_ANY, wx.EmptyBitmap(530,150))
88
self.hbitmap = wx.StaticBitmap(self.panel, wx.ID_ANY, wx.BitmapFromImage(wx.EmptyImage(530,150)))
94
91
### crashes when LOCATION doesn't exist
92
# get version & revision
95
93
versionFile = open(os.path.join(globalvar.ETCDIR, "VERSIONNUMBER"))
96
grassVersion = versionFile.readline().split(' ')[0].rstrip('\n')
94
versionLine = versionFile.readline().rstrip('\n')
97
95
versionFile.close()
99
self.select_box = wx.StaticBox (parent = self.panel, id = wx.ID_ANY,
100
label = " %s " % _("Choose project location and mapset"))
102
self.manage_box = wx.StaticBox (parent = self.panel, id = wx.ID_ANY,
103
label = " %s " % _("Manage"))
104
self.lwelcome = wx.StaticText(parent = self.panel, id = wx.ID_ANY,
105
label = _("Welcome to GRASS GIS %s\n"
106
"The world's leading open source GIS") % grassVersion,
107
style = wx.ALIGN_CENTRE)
108
self.ltitle = wx.StaticText(parent = self.panel, id = wx.ID_ANY,
109
label = _("Select an existing project location and mapset\n"
110
"or define a new location"),
111
style = wx.ALIGN_CENTRE)
112
self.ldbase = wx.StaticText(parent = self.panel, id = wx.ID_ANY,
113
label = _("GIS Data Directory:"))
114
self.llocation = wx.StaticText(parent = self.panel, id = wx.ID_ANY,
115
label = _("Project location\n(projection/coordinate system)"),
116
style = wx.ALIGN_CENTRE)
117
self.lmapset = wx.StaticText(parent = self.panel, id = wx.ID_ANY,
118
label = _("Accessible mapsets\n(directories of GIS files)"),
119
style = wx.ALIGN_CENTRE)
120
self.lcreate = wx.StaticText(parent = self.panel, id = wx.ID_ANY,
121
label = _("Create new mapset\nin selected location"),
122
style = wx.ALIGN_CENTRE)
123
self.ldefine = wx.StaticText(parent = self.panel, id = wx.ID_ANY,
124
label = _("Define new location"),
125
style = wx.ALIGN_CENTRE)
126
self.lmanageloc = wx.StaticText(parent = self.panel, id = wx.ID_ANY,
127
label = _("Rename/delete selected\nmapset or location"),
128
style = wx.ALIGN_CENTRE)
97
grassVersion, grassRevision = versionLine.split(' ', 1)
98
if grassVersion.endswith('svn'):
99
grassRevisionStr = ' (%s)' % grassRevision
101
grassRevisionStr = ''
103
grassVersion = versionLine
104
grassRevisionStr = ''
106
self.gisdbase_box = wx.StaticBox(parent=self.panel, id=wx.ID_ANY,
107
label=" %s " % _("1. Select GRASS GIS database directory"))
108
self.location_box = wx.StaticBox(parent=self.panel, id=wx.ID_ANY,
109
label=" %s " % _("2. Select GRASS Location"))
110
self.mapset_box = wx.StaticBox(parent=self.panel, id=wx.ID_ANY,
111
label=" %s " % _("3. Select GRASS Mapset"))
113
self.lmessage = wx.StaticText(parent=self.panel)
114
# It is not clear if all wx versions supports color, so try-except.
115
# The color itself may not be correct for all platforms/system settings
116
# but in http://xoomer.virgilio.it/infinity77/wxPython/Widgets/wx.SystemSettings.html
117
# there is no 'warning' color.
119
self.lmessage.SetForegroundColour(wx.Colour(255, 0, 0))
120
except AttributeError:
123
self.gisdbase_panel = wx.Panel(parent=self.panel)
124
self.location_panel = wx.Panel(parent=self.panel)
125
self.mapset_panel = wx.Panel(parent=self.panel)
127
self.ldbase = wx.StaticText(
128
parent=self.gisdbase_panel, id=wx.ID_ANY,
129
label=_("GRASS GIS database directory contains Locations."))
131
self.llocation = StaticWrapText(
132
parent=self.location_panel, id=wx.ID_ANY,
133
label=_("All data in one Location is in the same "
134
" coordinate reference system (projection)."
135
" One Location can be one project."
136
" Location contains Mapsets."),
139
self.lmapset = StaticWrapText(
140
parent=self.mapset_panel, id=wx.ID_ANY,
141
label=_("Mapset contains GIS data related"
142
" to one project, task within one project,"
143
" subregion or user."),
147
for label in [self.ldbase, self.llocation, self.lmapset]:
148
label.SetForegroundColour(
149
wx.SystemSettings_GetColour(wx.SYS_COLOUR_GRAYTEXT))
150
except AttributeError:
151
# for explanation of try-except see above
131
155
self.bstart = wx.Button(parent = self.panel, id = wx.ID_ANY,
132
label = _("Start &GRASS"))
156
label = _("Start &GRASS session"))
133
157
self.bstart.SetDefault()
134
158
self.bexit = wx.Button(parent = self.panel, id = wx.ID_EXIT)
135
159
self.bstart.SetMinSize((180, self.bexit.GetSize()[1]))
136
160
self.bhelp = wx.Button(parent = self.panel, id = wx.ID_HELP)
137
self.bbrowse = wx.Button(parent = self.panel, id = wx.ID_ANY,
161
self.bbrowse = wx.Button(parent = self.gisdbase_panel, id = wx.ID_ANY,
138
162
label = _("&Browse"))
139
self.bmapset = wx.Button(parent = self.panel, id = wx.ID_ANY,
140
label = _("&Create mapset"))
141
self.bwizard = wx.Button(parent = self.panel, id = wx.ID_ANY,
142
label = _("&Location wizard"))
143
self.bwizard.SetToolTipString(_("Start location wizard."
163
self.bmapset = wx.Button(parent = self.mapset_panel, id = wx.ID_ANY,
165
self.bmapset.SetToolTipString(
166
_("Create a new Mapset in selected Location"))
167
self.bwizard = wx.Button(parent = self.location_panel, id = wx.ID_ANY,
169
self.bwizard.SetToolTipString(_("Create a new location using location wizard."
144
170
" After location is created successfully,"
145
171
" GRASS session is started."))
146
self.manageloc = wx.Choice(parent = self.panel, id = wx.ID_ANY,
147
choices = [_('Rename mapset'), _('Rename location'),
148
_('Delete mapset'), _('Delete location')])
149
self.manageloc.SetSelection(0)
172
self.rename_location_button = wx.Button(parent=self.location_panel, id=wx.ID_ANY,
174
self.rename_location_button.SetToolTipString(_("Rename selected location"))
175
self.delete_location_button = wx.Button(parent=self.location_panel, id=wx.ID_ANY,
177
self.delete_location_button.SetToolTipString(_("Delete selected location"))
178
self.rename_mapset_button = wx.Button(parent=self.mapset_panel, id=wx.ID_ANY,
180
self.rename_mapset_button.SetToolTipString(_("Rename selected mapset"))
181
self.delete_mapset_button = wx.Button(parent=self.mapset_panel, id=wx.ID_ANY,
183
self.delete_mapset_button.SetToolTipString(_("Delete selected mapset"))
152
self.tgisdbase = wx.TextCtrl(parent = self.panel, id = wx.ID_ANY, value = "", size = (300, -1),
186
self.tgisdbase = wx.TextCtrl(parent = self.gisdbase_panel, id = wx.ID_ANY, value = "", size = (300, -1),
153
187
style = wx.TE_PROCESS_ENTER)
156
self.lblocations = GListBox(parent = self.panel,
157
id = wx.ID_ANY, size = (180, 200),
190
self.lblocations = GListBox(parent = self.location_panel,
191
id=wx.ID_ANY, size=(180, 200),
158
192
choices = self.listOfLocations)
160
193
self.lblocations.SetColumnWidth(0, 180)
162
195
# TODO: sort; but keep PERMANENT on top of list
164
self.lbmapsets = GListBox(parent = self.panel,
165
id = wx.ID_ANY, size = (180, 200),
197
self.lbmapsets = GListBox(parent = self.mapset_panel,
198
id=wx.ID_ANY, size=(180, 200),
166
199
choices = self.listOfMapsets)
168
200
self.lbmapsets.SetColumnWidth(0, 180)
170
# layout & properties
171
self._set_properties()
202
# layout & properties, first do layout so everything is created
172
203
self._do_layout()
204
self._set_properties(grassVersion, grassRevisionStr)
175
207
self.bbrowse.Bind(wx.EVT_BUTTON, self.OnBrowse)
178
210
self.bhelp.Bind(wx.EVT_BUTTON, self.OnHelp)
179
211
self.bmapset.Bind(wx.EVT_BUTTON, self.OnCreateMapset)
180
212
self.bwizard.Bind(wx.EVT_BUTTON, self.OnWizard)
181
self.manageloc.Bind(wx.EVT_CHOICE, self.OnManageLoc)
214
self.rename_location_button.Bind(wx.EVT_BUTTON, self.RenameLocation)
215
self.delete_location_button.Bind(wx.EVT_BUTTON, self.DeleteLocation)
216
self.rename_mapset_button.Bind(wx.EVT_BUTTON, self.RenameMapset)
217
self.delete_mapset_button.Bind(wx.EVT_BUTTON, self.DeleteMapset)
182
219
self.lblocations.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnSelectLocation)
183
220
self.lbmapsets.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnSelectMapset)
184
221
self.lbmapsets.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnStart)
185
222
self.tgisdbase.Bind(wx.EVT_TEXT_ENTER, self.OnSetDatabase)
186
223
self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
188
def _set_properties(self):
189
"""!Set frame properties"""
190
self.SetTitle(_("Welcome to GRASS GIS"))
191
self.SetIcon(wx.Icon(os.path.join(globalvar.ETCICONDIR, "grass.ico"),
225
def _set_properties(self, version, revision):
226
"""Set frame properties"""
227
self.SetTitle(_("GRASS GIS %s startup%s") % (version, revision))
228
self.SetIcon(wx.Icon(os.path.join(globalvar.ICONDIR, "grass.ico"),
192
229
wx.BITMAP_TYPE_ICO))
194
self.lwelcome.SetForegroundColour(wx.Colour(35, 142, 35))
195
self.lwelcome.SetFont(wx.Font(13, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))
197
231
self.bstart.SetForegroundColour(wx.Colour(35, 142, 35))
198
232
self.bstart.SetToolTipString(_("Enter GRASS session"))
199
233
self.bstart.Enable(False)
200
234
self.bmapset.Enable(False)
201
self.manageloc.Enable(False)
235
# this all was originally a choice, perhaps just mapset needed
236
self.rename_location_button.Enable(False)
237
self.delete_location_button.Enable(False)
238
self.rename_mapset_button.Enable(False)
239
self.delete_mapset_button.Enable(False)
204
242
if not self.gisdbase:
218
256
self.OnSetDatabase(None)
219
257
location = self.GetRCValue("LOCATION_NAME")
220
if location == "<UNKNOWN>" or \
221
not os.path.isdir(os.path.join(self.gisdbase, location)):
258
if location == "<UNKNOWN>":
260
if not os.path.isdir(os.path.join(self.gisdbase, location)):
226
self.UpdateLocations(self.gisdbase)
264
self.UpdateLocations(self.gisdbase)
266
self.lblocations.SetSelection(self.listOfLocations.index(location),
268
self.lblocations.EnsureVisible(self.listOfLocations.index(location))
270
sys.stderr.write(_("ERROR: Location <%s> not found\n") % self.GetRCValue("LOCATION_NAME"))
271
if len(self.listOfLocations) > 0:
272
self.lblocations.SetSelection(0, force = True)
273
self.lblocations.EnsureVisible(0)
274
location = self.listOfLocations[0]
279
self.UpdateMapsets(os.path.join(self.gisdbase, location))
280
mapset = self.GetRCValue("MAPSET")
228
self.lblocations.SetSelection(self.listOfLocations.index(location),
230
self.lblocations.EnsureVisible(self.listOfLocations.index(location))
283
self.lbmapsets.SetSelection(self.listOfMapsets.index(mapset),
285
self.lbmapsets.EnsureVisible(self.listOfMapsets.index(mapset))
231
286
except ValueError:
232
print >> sys.stderr, _("ERROR: Location <%s> not found") % location
235
self.UpdateMapsets(os.path.join(self.gisdbase, location))
236
mapset = self.GetRCValue("MAPSET")
239
self.lbmapsets.SetSelection(self.listOfMapsets.index(mapset),
241
self.lbmapsets.EnsureVisible(self.listOfMapsets.index(mapset))
243
self.lbmapsets.Clear()
244
print >> sys.stderr, _("ERROR: Mapset <%s> not found") % mapset
287
sys.stderr.write(_("ERROR: Mapset <%s> not found\n") % mapset)
288
self.lbmapsets.SetSelection(0, force = True)
289
self.lbmapsets.EnsureVisible(0)
246
291
def _do_layout(self):
247
sizer = wx.BoxSizer(wx.VERTICAL)
292
sizer = wx.BoxSizer(wx.VERTICAL)
293
self.sizer = sizer # for the layout call after changing message
248
294
dbase_sizer = wx.BoxSizer(wx.HORIZONTAL)
249
location_sizer = wx.BoxSizer(wx.HORIZONTAL)
250
select_boxsizer = wx.StaticBoxSizer(self.select_box, wx.VERTICAL)
251
select_sizer = wx.FlexGridSizer(rows = 2, cols = 2, vgap = 4, hgap = 4)
252
select_sizer.AddGrowableRow(1)
253
select_sizer.AddGrowableCol(0)
254
select_sizer.AddGrowableCol(1)
255
manage_sizer = wx.StaticBoxSizer(self.manage_box, wx.VERTICAL)
296
location_mapset_sizer = wx.BoxSizer(wx.HORIZONTAL)
298
gisdbase_panel_sizer = wx.BoxSizer(wx.VERTICAL)
299
gisdbase_boxsizer = wx.StaticBoxSizer(self.gisdbase_box, wx.VERTICAL)
256
301
btns_sizer = wx.BoxSizer(wx.HORIZONTAL)
303
self.gisdbase_panel.SetSizer(gisdbase_panel_sizer)
258
305
# gis data directory
259
dbase_sizer.Add(item = self.ldbase, proportion = 0,
260
flag = wx.ALIGN_CENTER_VERTICAL |
261
wx.ALIGN_CENTER_HORIZONTAL | wx.ALL,
307
gisdbase_boxsizer.Add(item=self.gisdbase_panel, proportion=1,
308
flag=wx.EXPAND | wx.ALL,
311
gisdbase_panel_sizer.Add(item=dbase_sizer, proportion=1,
312
flag=wx.EXPAND | wx.ALL,
314
gisdbase_panel_sizer.Add(item=self.ldbase, proportion=0,
315
flag=wx.EXPAND | wx.ALL,
263
318
dbase_sizer.Add(item = self.tgisdbase, proportion = 1,
264
319
flag = wx.ALIGN_CENTER_VERTICAL | wx.ALL,
266
321
dbase_sizer.Add(item = self.bbrowse, proportion = 0,
267
322
flag = wx.ALIGN_CENTER_VERTICAL | wx.ALL,
271
select_sizer.Add(item = self.llocation, proportion = 0,
272
flag = wx.ALIGN_CENTER_HORIZONTAL | wx.ALL,
274
select_sizer.Add(item = self.lmapset, proportion = 0,
275
flag = wx.ALIGN_CENTER_HORIZONTAL | wx.ALL,
277
select_sizer.Add(item = self.lblocations, proportion = 1,
279
select_sizer.Add(item = self.lbmapsets, proportion = 1,
282
select_boxsizer.Add(item = select_sizer, proportion = 1,
285
# define new location and mapset
286
manage_sizer.Add(item = self.ldefine, proportion = 0,
287
flag = wx.ALIGN_CENTER_HORIZONTAL | wx.ALL,
289
manage_sizer.Add(item = self.bwizard, proportion = 0,
290
flag = wx.ALIGN_CENTER_HORIZONTAL | wx.BOTTOM,
292
manage_sizer.Add(item = self.lcreate, proportion = 0,
293
flag = wx.ALIGN_CENTER_HORIZONTAL | wx.ALL,
295
manage_sizer.Add(item = self.bmapset, proportion = 0,
296
flag = wx.ALIGN_CENTER_HORIZONTAL | wx.BOTTOM,
298
manage_sizer.Add(item = self.lmanageloc, proportion = 0,
299
flag = wx.ALIGN_CENTER_HORIZONTAL | wx.ALL,
301
manage_sizer.Add(item = self.manageloc, proportion = 0,
302
flag = wx.ALIGN_CENTER_HORIZONTAL | wx.BOTTOM,
306
location_sizer.Add(item = select_boxsizer, proportion = 1,
325
gisdbase_panel_sizer.Fit(self.gisdbase_panel)
327
# location and mapset lists
329
def layout_list_box(box, panel, list_box, buttons, description):
330
panel_sizer = wx.BoxSizer(wx.VERTICAL)
331
main_sizer = wx.BoxSizer(wx.HORIZONTAL)
332
box_sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
333
buttons_sizer = wx.BoxSizer(wx.VERTICAL)
335
panel.SetSizer(panel_sizer)
336
panel_sizer.Fit(panel)
338
main_sizer.Add(item=list_box, proportion=1,
339
flag=wx.EXPAND | wx.ALL,
341
main_sizer.Add(item=buttons_sizer, proportion=0,
342
flag=wx.ALIGN_CENTER_HORIZONTAL | wx.ALL,
344
for button in buttons:
345
buttons_sizer.Add(item=button, proportion=0,
346
flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
348
box_sizer.Add(item=panel, proportion=1,
349
flag=wx.EXPAND | wx.ALL,
351
panel_sizer.Add(item=main_sizer, proportion=1,
352
flag=wx.EXPAND | wx.ALL,
354
panel_sizer.Add(item=description, proportion=0,
355
flag=wx.EXPAND | wx.ALL,
359
location_boxsizer = layout_list_box(
360
box=self.location_box,
361
panel=self.location_panel,
362
list_box=self.lblocations,
363
buttons=[self.bwizard, self.rename_location_button,
364
self.delete_location_button],
365
description=self.llocation)
366
mapset_boxsizer = layout_list_box(
368
panel=self.mapset_panel,
369
list_box=self.lbmapsets,
370
buttons=[self.bmapset, self.rename_mapset_button,
371
self.delete_mapset_button],
372
description=self.lmapset)
374
# location and mapset sizer
375
location_mapset_sizer.Add(item=location_boxsizer, proportion=1,
307
376
flag = wx.LEFT | wx.RIGHT | wx.EXPAND,
309
location_sizer.Add(item = manage_sizer, proportion = 0,
378
location_mapset_sizer.Add(item=mapset_boxsizer, proportion=1,
310
379
flag = wx.RIGHT | wx.EXPAND,
314
383
btns_sizer.Add(item = self.bstart, proportion = 0,
315
384
flag = wx.ALIGN_CENTER_HORIZONTAL |
456
556
def ImportFile(self, filePath):
457
"""!Tries to import file as vector or raster.
557
"""Tries to import file as vector or raster.
459
559
If successfull sets default region from imported map.
461
returncode, stdout, messagesIfVector = RunCommand('v.in.ogr', dsn = filePath, flags = 'l',
462
read = True, getErrorMsg = True)
466
returncode, messages = RunCommand('v.in.ogr', dsn = filePath,
467
output = os.path.splitext(os.path.basename(filePath))[0],
471
message = _("Import of vector data source <%(name)s> failed.") % {'name': filePath}
472
message += "\n" + messages
473
GError(message = message)
475
GMessage(message = _("Vector data source <%(name)s> imported successfully.") % {'name': filePath})
476
stdout = RunCommand('g.list', type = 'vect', read = True)
477
maps = stdout.splitlines()
479
# TODO: what about resolution?
480
RunCommand('g.region', flags = 's', vect = maps[0])
485
returncode, messages = RunCommand('r.in.gdal', input = filePath,
486
output = os.path.splitext(os.path.basename(filePath))[0],
490
message = _("Attempt to import data source <%(name)s> as raster or vector failed. ") % {'name': filePath}
491
message += "\n\n" + messagesIfVector + "\n" + messages
492
GError(message = message)
494
GMessage(message = _("Raster data source <%(name)s> imported successfully.") % {'name': filePath})
495
stdout = RunCommand('g.list', type = 'rast', read = True)
496
maps = stdout.splitlines()
498
RunCommand('g.region', flags = 's', rast = maps[0])
500
def OnManageLoc(self, event):
501
"""!Location management choice control handler
503
sel = event.GetSelection()
507
self.RenameLocation()
511
self.DeleteLocation()
515
def RenameMapset(self):
516
"""!Rename selected mapset
561
RunCommand('db.connect', flags='c')
562
mapName = os.path.splitext(os.path.basename(filePath))[0]
563
vectors = RunCommand('v.in.ogr', input = filePath, flags = 'l',
568
if mapName in vectors:
570
returncode, error = RunCommand('v.in.ogr', input=filePath, output=mapName, flags='e',
573
returncode, error = RunCommand('r.in.gdal', input=filePath, output=mapName, flags='e',
578
GError(parent = self,
579
message = _("Import of <%(name)s> failed.\n"
580
"Reason: %(msg)s") % ({'name': filePath, 'msg': error}))
582
GMessage(message=_("Data file <%(name)s> imported successfully. "
583
"The location's default region was set from this imported map.") %
587
# the event can be refactored out by using lambda in bind
588
def RenameMapset(self, event):
589
"""Rename selected mapset
518
591
location = self.listOfLocations[self.lblocations.GetSelection()]
519
592
mapset = self.listOfMapsets[self.lbmapsets.GetSelection()]