~ubuntu-branches/ubuntu/precise/grass/precise

« back to all changes in this revision

Viewing changes to gui/wxpython/gui_modules/preferences.py

  • Committer: Bazaar Package Importer
  • Author(s): Francesco Paolo Lovergine
  • Date: 2011-04-13 17:08:41 UTC
  • mfrom: (8.1.7 sid)
  • Revision ID: james.westby@ubuntu.com-20110413170841-ss1t9bic0d0uq0gz
Tags: 6.4.1-1
* New upstream version.
* Now build-dep on libjpeg-dev and current libreadline6-dev.
* Removed patch swig: obsolete.
* Policy bumped to 3.9.2, without changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
"""
 
1
"""!
2
2
@package preferences
3
3
 
4
4
@brief User preferences dialog
6
6
Sets default display font, etc.
7
7
 
8
8
Classes:
 
9
 - Settings
 
10
 - PreferencesBaseDialog
9
11
 - PreferencesDialog
10
12
 - DefaultFontDialog
11
13
 - MapsetAccess
 
14
 - NvizPreferencesDialog
12
15
 
13
 
(C) 2007-2009 by the GRASS Development Team
 
16
(C) 2007-2010 by the GRASS Development Team
14
17
This program is free software under the GNU General Public
15
18
License (>=v2). Read the file COPYING that comes with GRASS
16
19
for details.
17
20
 
18
21
@author Michael Barton (Arizona State University)
19
 
Martin Landa <landa.martin gmail.com>
 
22
@author Martin Landa <landa.martin gmail.com>
20
23
"""
21
24
 
22
25
import os
23
26
import sys
24
27
import copy
25
28
import stat
 
29
import types
26
30
try:
27
31
    import pwd
28
32
    havePwd = True
37
41
import wx.lib.filebrowsebutton as filebrowse
38
42
import wx.lib.colourselect as csel
39
43
import wx.lib.mixins.listctrl as listmix
40
 
from wx.lib.wordwrap import wordwrap
 
44
 
 
45
from grass.script import core as grass
41
46
 
42
47
import gcmd
43
 
import grassenv
44
48
import utils
45
49
import globalvar
46
50
from debug import Debug as Debug
47
51
 
48
52
class Settings:
49
 
    """Generic class where to store settings"""
 
53
    """!Generic class where to store settings"""
50
54
    def __init__(self):
51
55
        #
52
56
        # settings filename
58
62
        # key/value separator
59
63
        #
60
64
        self.sep = ';'
61
 
 
 
65
        
 
66
        try:
 
67
            projFile = utils.PathJoin(os.environ["GRASS_PROJSHARE"], 'epsg')
 
68
        except KeyError:
 
69
            projFile = ''
 
70
        
62
71
        #
63
72
        # default settings
64
73
        #
69
78
            'general': {
70
79
                # use default window layout (layer manager, displays, ...)
71
80
                'defWindowPos' : {
72
 
                    'enabled' : False,
73
 
                    'dim' : ''
 
81
                    'enabled' : True,
 
82
                    'dim' : '%d,0,%d,%d,0,0,%d,%d' % \
 
83
                        (globalvar.MAP_WINDOW_SIZE[0] + 5,
 
84
                         globalvar.GM_WINDOW_SIZE[0],
 
85
                         globalvar.GM_WINDOW_SIZE[1],
 
86
                         globalvar.MAP_WINDOW_SIZE[0],
 
87
                         globalvar.MAP_WINDOW_SIZE[1])
74
88
                    },
75
89
                # expand/collapse element list
76
90
                'elementListExpand' : {
99
113
                    'type' : '',
100
114
                    'encoding': 'ISO-8859-1',
101
115
                    },
 
116
                'outputfont' : {
 
117
                    'type' : 'Courier New',
 
118
                    'size': '10',
 
119
                    },
102
120
                'driver': {
103
121
                    'type': 'default'
104
122
                    },
108
126
                'autoRendering': {
109
127
                    'enabled' : True
110
128
                    },
 
129
                'autoZooming' : {
 
130
                    'enabled' : False
 
131
                    },
111
132
                'statusbarMode': {
112
133
                    'selection' : 0
113
134
                    },
114
135
                'bgcolor': {
115
136
                    'color' : (255, 255, 255, 255),
116
 
                    }
 
137
                    },
 
138
                },
 
139
            #
 
140
            # projection
 
141
            #
 
142
            'projection' : {
 
143
                'statusbar' : {
 
144
                    'proj4'    : '',
 
145
                    'epsg'     : '',
 
146
                    'projFile' : projFile,
 
147
                    },
 
148
                'format' : {
 
149
                    'll'  : 'DMS',
 
150
                    'precision' : 2,
 
151
                    },
117
152
                },
118
153
            #
119
154
            # advanced
164
199
                'rasterOverlay' : {
165
200
                    'enabled' : True
166
201
                    },
 
202
                'rasterColorTable' : {
 
203
                    'enabled'   : False,
 
204
                    'selection' : 'rainbow',
 
205
                    },
167
206
                # d.vect
168
207
                'showType': {
169
208
                    'point' : {
186
225
                        },
187
226
                    },
188
227
                'addNewLayer' : {
189
 
                    'enabled' : False
 
228
                    'enabled' : True,
 
229
                    },
 
230
                'interactiveInput' : {
 
231
                    'enabled' : True,
190
232
                    },
191
233
                },
192
234
            #
297
339
                'delRecord' : {
298
340
                    'enabled' : True
299
341
                    },
 
342
                # add centroid to left/right area
 
343
                'addCentroid' : {
 
344
                    'enabled' : False
 
345
                    },
 
346
                # do not attach category to boundary
 
347
                'catBoundary' : {
 
348
                    'enabled' : False
 
349
                    },
300
350
                # query tool
301
351
                'query' : {
302
352
                    'selection' : 0,
392
442
                    'enabled' : True
393
443
                    },
394
444
                },
 
445
            'gcpman' : {
 
446
                'rms' : {
 
447
                    'highestonly' : True,
 
448
                    'sdfactor' : 1,
 
449
                    },
 
450
                'symbol' : {
 
451
                    'color' : (0, 0, 255, 255),
 
452
                    'hcolor' : (255, 0, 0, 255),
 
453
                    'scolor' : (0, 255, 0, 255),
 
454
                    'ucolor' : (255, 165, 0, 255),
 
455
                    'unused' : True,
 
456
                    'size' : 8,
 
457
                    'width' : 2,
 
458
                    },
 
459
                },
395
460
            'georect' : {
396
461
                'symbol' : {
397
462
                    'color' : (0, 0, 255, 255),
401
466
            'nviz' : {
402
467
                'view' : {
403
468
                    'persp' : {
404
 
                        'value' : 40,
 
469
                        'value' : 20,
405
470
                        'step' : 5,
406
471
                        },
407
 
                    'pos' : {
408
 
                        'x' : 0.85,
409
 
                        'y' : 0.85,
 
472
                    'position' : {
 
473
                        'x' : 0.84,
 
474
                        'y' : 0.16,
410
475
                        },
411
476
                    'height' : {
412
477
                        'step' : 100,
416
481
                        'step' : 5,
417
482
                        },
418
483
                    'z-exag' : {
419
 
                        'value': 1,
420
484
                        'step' : 1,
421
485
                        },
 
486
                    'background' : {
 
487
                        'color' : (255, 255, 255, 255), # white
 
488
                        },
422
489
                    },
423
490
                'surface' : {
424
491
                    'shine': {
466
533
                        'value' : (0, 0, 0, 255), # constant: black
467
534
                        },
468
535
                    'draw' : {
469
 
                        'mode' : 0, # isosurfaces
470
 
                        'shading' : 1, # gouraud
 
536
                        'mode'       : 0, # isosurfaces
 
537
                        'shading'    : 1, # gouraud
471
538
                        'resolution' : 3, # polygon resolution
472
539
                        },
473
540
                    'shine': {
474
541
                        'map' : False,
475
 
                        'value' : 60.0,
476
 
                        },
477
 
                    },
478
 
                'settings': {
479
 
                    'general' : {
480
 
                        'bgcolor' : (255, 255, 255, 255), # white
 
542
                        'value' : 60,
 
543
                        },
 
544
                    },
 
545
                'light' : {
 
546
                    'position' : {
 
547
                        'x' : 0.68,
 
548
                        'y' : 0.68,
 
549
                        'z' : 80,
 
550
                        },
 
551
                    'bright'  : 80,
 
552
                    'color'   : (255, 255, 255, 255), # white
 
553
                    'ambient' : 20,
 
554
                    },
 
555
                'fringe' : {
 
556
                    'elev'   : 55,
 
557
                    'color'  : (128, 128, 128, 255), # grey
 
558
                    },
 
559
                },
 
560
            'modeler' : {
 
561
                'action' : {
 
562
                    'color' : {
 
563
                        'valid'   :  (180, 234, 154, 255), # light green
 
564
                        'invalid' :  (255, 255, 255, 255), # white
 
565
                        'running' :  (255, 0, 0, 255),     # red
 
566
                        'disabled' : (211, 211, 211, 255), # light grey
 
567
                        },
 
568
                    'size' : {
 
569
                        'width'  : 100,
 
570
                        'height' : 50,
 
571
                        },
 
572
                    'width': {
 
573
                        'parameterized' : 2,
 
574
                        'default'       : 1,
 
575
                        },
 
576
                    },
 
577
                'data' : { 
 
578
                    'color': {
 
579
                        'raster'   : (215, 215, 248, 255), # light blue
 
580
                        'raster3d' : (215, 248, 215, 255), # light green
 
581
                        'vector'   : (248, 215, 215, 255), # light red
 
582
                        },
 
583
                    'size' : {
 
584
                        'width' : 175,
 
585
                        'height' : 50,
 
586
                        },
 
587
                    },
 
588
                'loop' : {
 
589
                    'size' : {
 
590
                        'width' : 175,
 
591
                        'height' : 40,
 
592
                        },
 
593
                    },
 
594
                'if-else' : {
 
595
                    'size' : {
 
596
                        'width' : 150,
 
597
                        'height' : 40,
481
598
                        },
482
599
                    },
483
600
                },
484
601
            }
 
602
 
 
603
        # quick fix, http://trac.osgeo.org/grass/ticket/1233
 
604
        # TODO
 
605
        if sys.platform == 'darwin':
 
606
            self.defaultSettings['general']['defWindowPos']['enabled'] = False
485
607
        
486
608
        #
487
609
        # user settings
489
611
        self.userSettings = copy.deepcopy(self.defaultSettings)
490
612
        try:
491
613
            self.ReadSettingsFile()
492
 
        except gcmd.SettingsError, e:
493
 
            print >> sys.stderr, e.message
 
614
        except gcmd.GException, e:
 
615
            print >> sys.stderr, e.value
494
616
 
495
617
        #
496
618
        # internal settings (based on user settings)
548
670
        self.internalSettings['vdigit']['bgmap']['value'] = ''
549
671
        
550
672
    def ReadSettingsFile(self, settings=None):
551
 
        """Reads settings file (mapset, location, gisdbase)"""
 
673
        """!Reads settings file (mapset, location, gisdbase)"""
552
674
        if settings is None:
553
675
            settings = self.userSettings
554
676
 
555
677
        # look for settings file
556
 
        # -> mapser
557
 
        #  -> location
558
 
        #   -> gisdbase
559
 
        gisdbase = grassenv.GetGRASSVariable("GISDBASE")
560
 
        location_name = grassenv.GetGRASSVariable("LOCATION_NAME")
561
 
        mapset_name = grassenv.GetGRASSVariable("MAPSET")
562
 
 
 
678
        gisenv = grass.gisenv()
 
679
        gisdbase = gisenv['GISDBASE']
 
680
        location_name = gisenv['LOCATION_NAME']
 
681
        mapset_name = gisenv['MAPSET']
 
682
        
563
683
        mapset_file = os.path.join(gisdbase, location_name, mapset_name, self.fileName)
564
684
        location_file = os.path.join(gisdbase, location_name, self.fileName)
565
685
        gisdbase_file = os.path.join(gisdbase, self.fileName)
584
704
                                                key='font', subkey='encoding')
585
705
        
586
706
    def __ReadFile(self, filename, settings=None):
587
 
        """Read settings from file to dict"""
 
707
        """!Read settings from file to dict"""
588
708
        if settings is None:
589
709
            settings = self.userSettings
590
710
 
620
740
        file.close()
621
741
 
622
742
    def SaveToFile(self, settings=None):
623
 
        """Save settings to the file"""
 
743
        """!Save settings to the file"""
624
744
        if settings is None:
625
745
            settings = self.userSettings
626
746
        
627
747
        loc = self.Get(group='advanced', key='settingsFile', subkey='type')
628
748
        home = os.path.expanduser("~") # MS Windows fix ?
629
 
        gisdbase = grassenv.GetGRASSVariable("GISDBASE")
630
 
        location_name = grassenv.GetGRASSVariable("LOCATION_NAME")
631
 
        mapset_name = grassenv.GetGRASSVariable("MAPSET")
 
749
        
 
750
        gisenv = grass.gisenv()
 
751
        gisdbase = gisenv['GISDBASE']
 
752
        location_name = gisenv['LOCATION_NAME']
 
753
        mapset_name = gisenv['MAPSET']
632
754
        filePath = None
633
755
        if loc == 'home':
634
756
            filePath = os.path.join(home, self.fileName)
650
772
                    subkeys = settings[group][key].keys()
651
773
                    for idx in range(len(subkeys)):
652
774
                        value = settings[group][key][subkeys[idx]]
653
 
                        if type(value) == type({}):
 
775
                        if type(value) == types.DictType:
654
776
                            if idx > 0:
655
777
                                file.write('%s%s%s%s%s' % (os.linesep, group, self.sep, key, self.sep))
656
778
                            file.write('%s%s' % (subkeys[idx], self.sep))
662
784
                                                       svalue))
663
785
                                if sidx < len(kvalues) - 1:
664
786
                                    file.write('%s' % self.sep)
 
787
                            if idx < len(subkeys) - 1:
 
788
                                file.write('%s%s%s%s%s' % (os.linesep, group, self.sep, key, self.sep))
665
789
                        else:
666
790
                            value = self.__parseValue(settings[group][key][subkeys[idx]])
667
791
                            file.write('%s%s%s' % (subkeys[idx], self.sep, value))
668
 
                            if idx < len(subkeys) - 1:
 
792
                            if idx < len(subkeys) - 1 and \
 
793
                                    type(settings[group][key][subkeys[idx + 1]]) != types.DictType:
669
794
                                file.write('%s' % self.sep)
670
 
                    file.write('%s' % os.linesep)
 
795
                    file.write(os.linesep)
671
796
        except IOError, e:
672
 
            raise gcmd.SettingsError(message=e)
 
797
            raise gcmd.GException(e)
673
798
        except StandardError, e:
674
 
            raise gcmd.SettingsError(message=_('Writing settings to file <%(file)s> failed.'
675
 
                                               '\n\nDetails: %(detail)s') % { 'file' : filePath,
676
 
                                                                              'detail' : e })
 
799
            raise gcmd.GException(_('Writing settings to file <%(file)s> failed.'
 
800
                                    '\n\nDetails: %(detail)s') % { 'file' : filePath,
 
801
                                                                   'detail' : e })
677
802
        
678
803
        file.close()
679
804
        
680
805
        return filePath
681
806
 
682
807
    def __parseValue(self, value, read=False):
683
 
        """Parse value to be store in settings file"""
 
808
        """!Parse value to be store in settings file"""
684
809
        if read: # -> read settings (cast values)
685
810
            if value == 'True':
686
811
                value = True
710
835
        return value
711
836
 
712
837
    def Get(self, group, key=None, subkey=None, internal=False):
713
 
        """Get value by key/subkey
 
838
        """!Get value by key/subkey
714
839
 
715
840
        Raise KeyError if key is not found
716
841
        
733
858
                else:
734
859
                    return settings[group][key]
735
860
            else:
736
 
                if type(subkey) == type([]) or \
737
 
                        type(subkey) == type(()):
 
861
                if type(subkey) == type(tuple()) or \
 
862
                        type(subkey) == type(list()):
738
863
                    return settings[group][key][subkey[0]][subkey[1]]
739
864
                else:
740
865
                    return settings[group][key][subkey]  
741
866
 
742
867
        except KeyError:
743
 
            #raise gcmd.SettingsError("%s %s:%s:%s." % (_("Unable to get value"),
744
 
            #                                           group, key, subkey))
745
868
            print >> sys.stderr, "Settings: unable to get value '%s:%s:%s'\n" % \
746
869
                (group, key, subkey)
747
870
        
748
 
    def Set(self, group, value, key=None, subkey=None, internal=False):
749
 
        """Set value of key/subkey
750
 
 
 
871
    def Set(self, group, value, key = None, subkey = None, internal = False):
 
872
        """!Set value of key/subkey
 
873
        
751
874
        Raise KeyError if group/key is not found
752
875
        
753
876
        @param group settings group
760
883
            settings = self.internalSettings
761
884
        else:
762
885
            settings = self.userSettings
763
 
 
 
886
        
764
887
        try:
765
888
            if subkey is None:
766
889
                if key is None:
768
891
                else:
769
892
                    settings[group][key] = value
770
893
            else:
771
 
                if type(subkey) == type([]):
 
894
                if type(subkey) == type(tuple()) or \
 
895
                        type(subkey) == type(list()):
772
896
                    settings[group][key][subkey[0]][subkey[1]] = value
773
897
                else:
774
898
                    settings[group][key][subkey] = value
775
899
        except KeyError:
776
 
            raise gcmd.SettingsError("%s '%s:%s:%s'" % (_("Unable to set "), group, key, subkey))
777
 
 
 
900
            raise gcmd.GException("%s '%s:%s:%s'" % (_("Unable to set "), group, key, subkey))
 
901
        
778
902
    def Append(self, dict, group, key, subkey, value):
779
 
        """Set value of key/subkey
 
903
        """!Set value of key/subkey
780
904
 
781
905
        Create group/key/subkey if not exists
782
906
        
788
912
        """
789
913
        if not dict.has_key(group):
790
914
            dict[group] = {}
791
 
 
 
915
        
792
916
        if not dict[group].has_key(key):
793
917
            dict[group][key] = {}
794
 
 
795
 
        if type(subkey) == type([]):
 
918
        
 
919
        if type(subkey) == types.ListType:
796
920
            # TODO: len(subkey) > 2
797
921
            if not dict[group][key].has_key(subkey[0]):
798
922
                dict[group][key][subkey[0]] = {}
799
 
            dict[group][key][subkey[0]][subkey[1]] = value
 
923
            try:
 
924
                dict[group][key][subkey[0]][subkey[1]] = value
 
925
            except TypeError:
 
926
                print >> sys.stderr, _("Unable to parse settings '%s'") % value + \
 
927
                    ' (' + group + ':' + key + ':' + subkey[0] + ':' + subkey[1] + ')'
800
928
        else:
801
 
            dict[group][key][subkey] = value
802
 
 
 
929
            try:
 
930
                dict[group][key][subkey] = value
 
931
            except TypeError:
 
932
                print >> sys.stderr, _("Unable to parse settings '%s'") % value + \
 
933
                    ' (' + group + ':' + key + ':' + subkey + ')'
 
934
        
803
935
    def GetDefaultSettings(self):
804
 
        """Get default user settings"""
 
936
        """!Get default user settings"""
805
937
        return self.defaultSettings
806
938
 
807
939
globalSettings = Settings()
808
940
 
809
 
class PreferencesDialog(wx.Dialog):
810
 
    """User preferences dialog"""
811
 
    def __init__(self, parent, title=_("User GUI settings"),
812
 
                 settings=globalSettings,
813
 
                 style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER):
814
 
        self.parent = parent # GMFrame
815
 
        self.title = title
816
 
        wx.Dialog.__init__(self, parent=parent, id=wx.ID_ANY, title=title,
817
 
                           style=style, size=(-1, -1))
818
 
 
 
941
class PreferencesBaseDialog(wx.Dialog):
 
942
    """!Base preferences dialog"""
 
943
    def __init__(self, parent, settings, title = _("User settings"),
 
944
                 size = (500, 375),
 
945
                 style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER):
 
946
        self.parent = parent # ModelerFrame
 
947
        self.title  = title
 
948
        self.size   = size
819
949
        self.settings = settings
 
950
        
 
951
        wx.Dialog.__init__(self, parent = parent, id = wx.ID_ANY, title = title,
 
952
                           style = style)
 
953
        
820
954
        # notebook
821
 
        notebook = wx.Notebook(parent=self, id=wx.ID_ANY, style=wx.BK_DEFAULT)
822
 
 
 
955
        self.notebook = wx.Notebook(parent=self, id=wx.ID_ANY, style=wx.BK_DEFAULT)
 
956
        
823
957
        # dict for window ids
824
958
        self.winId = {}
825
 
 
 
959
        
826
960
        # create notebook pages
827
 
        self.__CreateGeneralPage(notebook)
828
 
        self.__CreateDisplayPage(notebook)
829
 
        self.__CreateCmdPage(notebook)
830
 
        self.__CreateAttributeManagerPage(notebook)
831
 
        self.__CreateWorkspacePage(notebook)
832
 
        self.__CreateAdvancedPage(notebook)
833
 
 
 
961
        
834
962
        # buttons
835
 
        btnDefault = wx.Button(self, wx.ID_ANY, _("Set to default"))
836
 
        btnSave = wx.Button(self, wx.ID_SAVE)
837
 
        btnApply = wx.Button(self, wx.ID_APPLY)
838
 
        btnCancel = wx.Button(self, wx.ID_CANCEL)
839
 
        btnSave.SetDefault()
840
 
 
 
963
        self.btnDefault = wx.Button(self, wx.ID_ANY, _("Set to default"))
 
964
        self.btnSave = wx.Button(self, wx.ID_SAVE)
 
965
        self.btnApply = wx.Button(self, wx.ID_APPLY)
 
966
        self.btnCancel = wx.Button(self, wx.ID_CANCEL)
 
967
        self.btnSave.SetDefault()
 
968
        
841
969
        # bindigs
842
 
        btnDefault.Bind(wx.EVT_BUTTON, self.OnDefault)
843
 
        btnDefault.SetToolTipString(_("Revert settings to default and apply changes"))
844
 
        btnApply.Bind(wx.EVT_BUTTON, self.OnApply)
845
 
        btnApply.SetToolTipString(_("Apply changes for the current session"))
846
 
        btnSave.Bind(wx.EVT_BUTTON, self.OnSave)
847
 
        btnSave.SetToolTipString(_("Apply and save changes to user settings file (default for next sessions)"))
848
 
        btnSave.SetDefault()
849
 
        btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel)
850
 
        btnCancel.SetToolTipString(_("Close dialog and ignore changes"))
851
 
 
 
970
        self.btnDefault.Bind(wx.EVT_BUTTON, self.OnDefault)
 
971
        self.btnDefault.SetToolTipString(_("Revert settings to default and apply changes"))
 
972
        self.btnApply.Bind(wx.EVT_BUTTON, self.OnApply)
 
973
        self.btnApply.SetToolTipString(_("Apply changes for the current session"))
 
974
        self.btnSave.Bind(wx.EVT_BUTTON, self.OnSave)
 
975
        self.btnSave.SetToolTipString(_("Apply and save changes to user settings file (default for next sessions)"))
 
976
        self.btnSave.SetDefault()
 
977
        self.btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel)
 
978
        self.btnCancel.SetToolTipString(_("Close dialog and ignore changes"))
 
979
 
 
980
        self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
 
981
 
 
982
        self._layout()
 
983
        
 
984
    def _layout(self):
 
985
        """!Layout window"""
852
986
        # sizers
853
987
        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
854
 
        btnSizer.Add(item=btnDefault, proportion=1,
 
988
        btnSizer.Add(item=self.btnDefault, proportion=1,
855
989
                     flag=wx.ALL, border=5)
856
990
        btnStdSizer = wx.StdDialogButtonSizer()
857
 
        btnStdSizer.AddButton(btnCancel)
858
 
        btnStdSizer.AddButton(btnSave)
859
 
        btnStdSizer.AddButton(btnApply)
 
991
        btnStdSizer.AddButton(self.btnCancel)
 
992
        btnStdSizer.AddButton(self.btnSave)
 
993
        btnStdSizer.AddButton(self.btnApply)
860
994
        btnStdSizer.Realize()
861
995
        
862
996
        mainSizer = wx.BoxSizer(wx.VERTICAL)
863
 
        mainSizer.Add(item=notebook, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
 
997
        mainSizer.Add(item=self.notebook, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
864
998
        mainSizer.Add(item=btnSizer, proportion=0,
865
999
                      flag=wx.EXPAND, border=0)
866
1000
        mainSizer.Add(item=btnStdSizer, proportion=0,
867
1001
                      flag=wx.EXPAND | wx.ALL | wx.ALIGN_RIGHT, border=5)
868
 
 
 
1002
        
869
1003
        self.SetSizer(mainSizer)
870
1004
        mainSizer.Fit(self)
871
 
 
 
1005
        
 
1006
    def OnDefault(self, event):
 
1007
        """!Button 'Set to default' pressed"""
 
1008
        self.settings.userSettings = copy.deepcopy(self.settings.defaultSettings)
 
1009
        
 
1010
        # update widgets
 
1011
        for gks in self.winId.keys():
 
1012
            try:
 
1013
                group, key, subkey = gks.split(':')
 
1014
                value = self.settings.Get(group, key, subkey)
 
1015
            except ValueError:
 
1016
                group, key, subkey, subkey1 = gks.split(':')
 
1017
                value = self.settings.Get(group, key, [subkey, subkey1])
 
1018
            win = self.FindWindowById(self.winId[gks])
 
1019
            if win.GetName() in ('GetValue', 'IsChecked'):
 
1020
                value = win.SetValue(value)
 
1021
            elif win.GetName() == 'GetSelection':
 
1022
                value = win.SetSelection(value)
 
1023
            elif win.GetName() == 'GetStringSelection':
 
1024
                value = win.SetStringSelection(value)
 
1025
            else:
 
1026
                value = win.SetValue(value)
 
1027
        
 
1028
    def OnApply(self, event):
 
1029
        """!Button 'Apply' pressed"""
 
1030
        if self._updateSettings():
 
1031
            self.parent.goutput.WriteLog(_('Settings applied to current session but not saved'))
 
1032
            self.Close()
 
1033
 
 
1034
    def OnCloseWindow(self, event):
 
1035
        self.Hide()
 
1036
        
 
1037
    def OnCancel(self, event):
 
1038
        """!Button 'Cancel' pressed"""
 
1039
        self.Close()
 
1040
        
 
1041
    def OnSave(self, event):
 
1042
        """!Button 'Save' pressed"""
 
1043
        if self._updateSettings():
 
1044
            file = self.settings.SaveToFile()
 
1045
            self.parent.goutput.WriteLog(_('Settings saved to file \'%s\'.') % file)
 
1046
            self.Close()
 
1047
 
 
1048
    def _updateSettings(self):
 
1049
        """!Update user settings"""
 
1050
        for item in self.winId.keys():
 
1051
            try:
 
1052
                group, key, subkey = item.split(':')
 
1053
                subkey1 = None
 
1054
            except ValueError:
 
1055
                group, key, subkey, subkey1 = item.split(':')
 
1056
            
 
1057
            id = self.winId[item]
 
1058
            win = self.FindWindowById(id)
 
1059
            if win.GetName() == 'GetValue':
 
1060
                value = win.GetValue()
 
1061
            elif win.GetName() == 'GetSelection':
 
1062
                value = win.GetSelection()
 
1063
            elif win.GetName() == 'IsChecked':
 
1064
                value = win.IsChecked()
 
1065
            elif win.GetName() == 'GetStringSelection':
 
1066
                value = win.GetStringSelection()
 
1067
            elif win.GetName() == 'GetColour':
 
1068
                value = tuple(win.GetValue())
 
1069
            else:
 
1070
                value = win.GetValue()
 
1071
 
 
1072
            if key == 'keycolumn' and value == '':
 
1073
                wx.MessageBox(parent=self,
 
1074
                              message=_("Key column cannot be empty string."),
 
1075
                              caption=_("Error"), style=wx.OK | wx.ICON_ERROR)
 
1076
                win.SetValue(self.settings.Get(group='atm', key='keycolumn', subkey='value'))
 
1077
                return False
 
1078
 
 
1079
            if subkey1:
 
1080
                self.settings.Set(group, value, key, [subkey, subkey1])
 
1081
            else:
 
1082
                self.settings.Set(group, value, key, subkey)
 
1083
        
 
1084
        return True
 
1085
 
 
1086
class PreferencesDialog(PreferencesBaseDialog):
 
1087
    """!User preferences dialog"""
 
1088
    def __init__(self, parent, title = _("GUI settings"),
 
1089
                 settings = globalSettings):
 
1090
        
 
1091
        PreferencesBaseDialog.__init__(self, parent = parent, title = title,
 
1092
                                       settings = settings)
 
1093
        
 
1094
        # create notebook pages
 
1095
        self._CreateGeneralPage(self.notebook)
 
1096
        self._CreateDisplayPage(self.notebook)
 
1097
        self._CreateCmdPage(self.notebook)
 
1098
        self._CreateAttributeManagerPage(self.notebook)
 
1099
        self._CreateProjectionPage(self.notebook)
 
1100
        self._CreateWorkspacePage(self.notebook)
 
1101
        self._CreateAdvancedPage(self.notebook)
 
1102
        
872
1103
        self.SetMinSize(self.GetBestSize())
873
 
        self.SetSize((500, 375))
874
 
 
875
 
    def __CreateGeneralPage(self, notebook):
876
 
        """Create notebook page for general settings"""
 
1104
        self.SetSize(self.size)
 
1105
        
 
1106
    def _CreateGeneralPage(self, notebook):
 
1107
        """!Create notebook page for general settings"""
877
1108
        panel = wx.Panel(parent=notebook, id=wx.ID_ANY)
878
1109
        notebook.AddPage(page=panel, text=_("General"))
879
1110
 
964
1195
        
965
1196
        return panel
966
1197
 
967
 
    def __CreateDisplayPage(self, notebook):
968
 
        """Create notebook page for display settings"""
 
1198
    def _CreateDisplayPage(self, notebook):
 
1199
        """!Create notebook page for display settings"""
 
1200
   
969
1201
        panel = wx.Panel(parent=notebook, id=wx.ID_ANY)
970
1202
        notebook.AddPage(page=panel, text=_("Display"))
971
1203
 
996
1228
        sizer.Add(item=gridSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=5)
997
1229
        border.Add(item=sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=3)
998
1230
 
 
1231
        row = 1
 
1232
        gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
 
1233
                                         label=_("Font for command output:")),
 
1234
                      flag=wx.ALIGN_LEFT |
 
1235
                      wx.ALIGN_CENTER_VERTICAL,
 
1236
                      pos=(row, 0))
 
1237
        outfontButton = wx.Button(parent=panel, id=wx.ID_ANY,
 
1238
                               label=_("Set font"), size=(100, -1))
 
1239
        gridSizer.Add(item=outfontButton,
 
1240
                      flag=wx.ALIGN_RIGHT |
 
1241
                      wx.ALIGN_CENTER_VERTICAL,
 
1242
                      pos=(row, 1))
 
1243
 
 
1244
        #
 
1245
        # display settings
 
1246
        #
999
1247
        box   = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("Default display settings"))
1000
1248
        sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
1001
1249
 
1014
1262
        listOfDrivers = self.settings.Get(group='display', key='driver', subkey='choices', internal=True)
1015
1263
        # check if cairo is available
1016
1264
        if 'cairo' not in listOfDrivers:
1017
 
            for line in gcmd.Command(['d.mon', '-l']).ReadStdOutput():
 
1265
            for line in gcmd.RunCommand('d.mon',
 
1266
                                        flags = 'l',
 
1267
                                        read = True).splitlines():
1018
1268
                if 'cairo' in line:
1019
1269
                    listOfDrivers.append('cairo')
1020
1270
                    break
 
1271
        
1021
1272
        driver = wx.Choice(parent=panel, id=wx.ID_ANY, size=(150, -1),
1022
1273
                           choices=listOfDrivers,
1023
1274
                           name="GetStringSelection")
1060
1311
                      pos=(row, 0))
1061
1312
        bgColor = csel.ColourSelect(parent=panel, id=wx.ID_ANY,
1062
1313
                                    colour=self.settings.Get(group='display', key='bgcolor', subkey='color'),
1063
 
                                    size=(35, 35))
 
1314
                                    size=globalvar.DIALOG_COLOR_SIZE)
1064
1315
        bgColor.SetName('GetColour')
1065
1316
        self.winId['display:bgcolor:color'] = bgColor.GetId()
1066
1317
        
1093
1344
 
1094
1345
        gridSizer.Add(item=autoRendering,
1095
1346
                      pos=(row, 0), span=(1, 2))
 
1347
        
 
1348
        #
 
1349
        # auto-zoom
 
1350
        #
 
1351
        row += 1
 
1352
        autoZooming = wx.CheckBox(parent=panel, id=wx.ID_ANY,
 
1353
                                  label=_("Enable auto-zooming to selected map layer"),
 
1354
                                  name="IsChecked")
 
1355
        autoZooming.SetValue(self.settings.Get(group='display', key='autoZooming', subkey='enabled'))
 
1356
        self.winId['display:autoZooming:enabled'] = autoZooming.GetId()
 
1357
 
 
1358
        gridSizer.Add(item=autoZooming,
 
1359
                      pos=(row, 0), span=(1, 2))
1096
1360
 
1097
1361
        sizer.Add(item=gridSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=5)
1098
1362
        border.Add(item=sizer, proportion=0, flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border=3)
1099
 
 
 
1363
        
1100
1364
        panel.SetSizer(border)
1101
 
        
 
1365
                
1102
1366
        # bindings
1103
1367
        fontButton.Bind(wx.EVT_BUTTON, self.OnSetFont)
 
1368
        outfontButton.Bind(wx.EVT_BUTTON, self.OnSetOutputFont)
1104
1369
        
1105
1370
        return panel
1106
1371
 
1107
 
    def __CreateCmdPage(self, notebook):
1108
 
        """Create notebook page for commad dialog settings"""
 
1372
    def _CreateCmdPage(self, notebook):
 
1373
        """!Create notebook page for commad dialog settings"""
1109
1374
        panel = wx.Panel(parent=notebook, id=wx.ID_ANY)
1110
1375
        notebook.AddPage(page=panel, text=_("Command"))
1111
1376
        
1132
1397
        row += 1
1133
1398
        # close
1134
1399
        close = wx.CheckBox(parent=panel, id=wx.ID_ANY,
1135
 
                            label=_("Close dialog on finish"),
 
1400
                            label=_("Close dialog when command is successfully finished"),
1136
1401
                            name="IsChecked")
1137
1402
        close.SetValue(self.settings.Get(group='cmd', key='closeDlg', subkey='enabled'))
1138
1403
        self.winId['cmd:closeDlg:enabled'] = close.GetId()
1146
1411
                          name="IsChecked")
1147
1412
        add.SetValue(self.settings.Get(group='cmd', key='addNewLayer', subkey='enabled'))
1148
1413
        self.winId['cmd:addNewLayer:enabled'] = add.GetId()
1149
 
        
 
1414
    
1150
1415
        gridSizer.Add(item=add,
1151
1416
                      pos=(row, 0), span=(1, 2))
 
1417
        
 
1418
        row += 1
 
1419
        # interactive input
 
1420
        interactive = wx.CheckBox(parent = panel, id = wx.ID_ANY,
 
1421
                                  label = _("Allow interactive input"),
 
1422
                                  name = "IsChecked")
 
1423
        interactive.SetValue(self.settings.Get(group='cmd', key='interactiveInput', subkey='enabled'))
 
1424
        self.winId['cmd:interactiveInput:enabled'] = interactive.GetId()
 
1425
        gridSizer.Add(item = interactive,
 
1426
                      pos = (row, 0), span = (1, 2))
 
1427
        
1152
1428
        row += 1
1153
1429
        # verbosity
1154
1430
        gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
1189
1465
        
1190
1466
        gridSizer.Add(item=rasterOverlay,
1191
1467
                      pos=(row, 0), span=(1, 2))
 
1468
 
 
1469
        # default color table
 
1470
        row += 1
 
1471
        rasterCTCheck = wx.CheckBox(parent=panel, id=wx.ID_ANY,
 
1472
                                    label=_("Default color table"),
 
1473
                                    name='IsChecked')
 
1474
        rasterCTCheck.SetValue(self.settings.Get(group='cmd', key='rasterColorTable', subkey='enabled'))
 
1475
        self.winId['cmd:rasterColorTable:enabled'] = rasterCTCheck.GetId()
 
1476
        rasterCTCheck.Bind(wx.EVT_CHECKBOX, self.OnCheckColorTable)
 
1477
        
 
1478
        gridSizer.Add(item=rasterCTCheck,
 
1479
                      pos=(row, 0))
 
1480
        
 
1481
        rasterCTName = wx.Choice(parent=panel, id=wx.ID_ANY, size=(200, -1),
 
1482
                               choices=utils.GetColorTables(),
 
1483
                               name="GetStringSelection")
 
1484
        rasterCTName.SetStringSelection(self.settings.Get(group='cmd', key='rasterColorTable', subkey='selection'))
 
1485
        self.winId['cmd:rasterColorTable:selection'] = rasterCTName.GetId()
 
1486
        if not rasterCTCheck.IsChecked():
 
1487
            rasterCTName.Enable(False)
 
1488
        
 
1489
        gridSizer.Add(item=rasterCTName,
 
1490
                      pos=(row, 1))
1192
1491
        
1193
1492
        sizer.Add(item=gridSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=5)
1194
1493
        border.Add(item=sizer, proportion=0, flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border=3)
1221
1520
        
1222
1521
        return panel
1223
1522
 
1224
 
    def __CreateAttributeManagerPage(self, notebook):
1225
 
        """Create notebook page for 'Attribute Table Manager' settings"""
 
1523
    def _CreateAttributeManagerPage(self, notebook):
 
1524
        """!Create notebook page for 'Attribute Table Manager' settings"""
1226
1525
        panel = wx.Panel(parent=notebook, id=wx.ID_ANY)
1227
1526
        notebook.AddPage(page=panel, text=_("Attributes"))
1228
1527
 
1241
1540
        label = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Color:"))
1242
1541
        hlColor = csel.ColourSelect(parent=panel, id=wx.ID_ANY,
1243
1542
                                    colour=self.settings.Get(group='atm', key='highlight', subkey='color'),
1244
 
                                    size=(35, 35))
 
1543
                                    size=globalvar.DIALOG_COLOR_SIZE)
1245
1544
        hlColor.SetName('GetColour')
1246
1545
        self.winId['atm:highlight:color'] = hlColor.GetId()
1247
1546
 
1350
1649
 
1351
1650
        return panel
1352
1651
 
1353
 
    def __CreateWorkspacePage(self, notebook):
1354
 
        """Create notebook page for workspace settings"""
 
1652
    def _CreateProjectionPage(self, notebook):
 
1653
        """!Create notebook page for workspace settings"""
 
1654
        panel = wx.Panel(parent=notebook, id=wx.ID_ANY)
 
1655
        notebook.AddPage(page=panel, text=_("Projection"))
 
1656
        
 
1657
        border = wx.BoxSizer(wx.VERTICAL)
 
1658
        
 
1659
        #
 
1660
        # projections statusbar settings
 
1661
        #
 
1662
        box   = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("Projection statusbar settings"))
 
1663
        sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
 
1664
 
 
1665
        gridSizer = wx.GridBagSizer (hgap=3, vgap=3)
 
1666
        gridSizer.AddGrowableCol(1)
 
1667
 
 
1668
        # epsg
 
1669
        row = 0
 
1670
        label = wx.StaticText(parent=panel, id=wx.ID_ANY,
 
1671
                              label=_("EPSG code:"))
 
1672
        epsgCode = wx.ComboBox(parent=panel, id=wx.ID_ANY,
 
1673
                               name="GetValue",
 
1674
                               size = (150, -1))
 
1675
        self.epsgCodeDict = dict()
 
1676
        epsgCode.SetValue(str(self.settings.Get(group='projection', key='statusbar', subkey='epsg')))
 
1677
        self.winId['projection:statusbar:epsg'] = epsgCode.GetId()
 
1678
        
 
1679
        gridSizer.Add(item=label,
 
1680
                      pos=(row, 0),
 
1681
                      flag = wx.ALIGN_CENTER_VERTICAL)
 
1682
        gridSizer.Add(item=epsgCode,
 
1683
                      pos=(row, 1), span=(1, 2))
 
1684
        
 
1685
        # proj
 
1686
        row += 1
 
1687
        label = wx.StaticText(parent=panel, id=wx.ID_ANY,
 
1688
                              label=_("Proj.4 string (required):"))
 
1689
        projString = wx.TextCtrl(parent=panel, id=wx.ID_ANY,
 
1690
                                 value=self.settings.Get(group='projection', key='statusbar', subkey='proj4'),
 
1691
                                 name="GetValue", size=(400, -1))
 
1692
        self.winId['projection:statusbar:proj4'] = projString.GetId()
 
1693
 
 
1694
        gridSizer.Add(item=label,
 
1695
                      pos=(row, 0),
 
1696
                      flag = wx.ALIGN_CENTER_VERTICAL)
 
1697
        gridSizer.Add(item=projString,
 
1698
                      pos=(row, 1), span=(1, 2),
 
1699
                      flag = wx.ALIGN_CENTER_VERTICAL)
 
1700
        
 
1701
        # epsg file
 
1702
        row += 1
 
1703
        label = wx.StaticText(parent=panel, id=wx.ID_ANY,
 
1704
                              label=_("EPSG file:"))
 
1705
        projFile = wx.TextCtrl(parent=panel, id=wx.ID_ANY,
 
1706
                               value = self.settings.Get(group='projection', key='statusbar', subkey='projFile'),
 
1707
                               name="GetValue", size=(400, -1))
 
1708
        self.winId['projection:statusbar:projFile'] = projFile.GetId()
 
1709
        gridSizer.Add(item=label,
 
1710
                      pos=(row, 0),
 
1711
                      flag = wx.ALIGN_CENTER_VERTICAL)
 
1712
        gridSizer.Add(item=projFile,
 
1713
                      pos=(row, 1),
 
1714
                      flag = wx.ALIGN_CENTER_VERTICAL)
 
1715
        
 
1716
        # note + button
 
1717
        row += 1
 
1718
        note = wx.StaticText(parent = panel, id = wx.ID_ANY,
 
1719
                             label = _("Load EPSG codes (be patient), enter EPSG code or "
 
1720
                                       "insert Proj.4 string directly."))
 
1721
        gridSizer.Add(item=note,
 
1722
                      span = (1, 2),
 
1723
                      pos=(row, 0))
 
1724
 
 
1725
        row += 1
 
1726
        epsgLoad = wx.Button(parent=panel, id=wx.ID_ANY,
 
1727
                             label=_("&Load EPSG codes"))
 
1728
        gridSizer.Add(item=epsgLoad,
 
1729
                      flag = wx.ALIGN_RIGHT,
 
1730
                      pos=(row, 1))
 
1731
        
 
1732
        sizer.Add(item=gridSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=5)
 
1733
        border.Add(item=sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=3)
 
1734
 
 
1735
        #
 
1736
        # format
 
1737
        #
 
1738
        box   = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("Coordinates format"))
 
1739
        sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
 
1740
        
 
1741
        gridSizer = wx.GridBagSizer (hgap=3, vgap=3)
 
1742
        gridSizer.AddGrowableCol(2)
 
1743
 
 
1744
        row = 0
 
1745
        # ll format
 
1746
        ll = wx.RadioBox(parent = panel, id = wx.ID_ANY,
 
1747
                         label = " %s " % _("LL projections"),
 
1748
                         choices = ["DMS", "DEG"],
 
1749
                         name = "GetStringSelection")
 
1750
        self.winId['projection:format:ll'] = ll.GetId()
 
1751
        if self.settings.Get(group = 'projection', key = 'format', subkey = 'll') == 'DMS':
 
1752
            ll.SetSelection(0)
 
1753
        else:
 
1754
            ll.SetSelection(1)
 
1755
        
 
1756
        # precision
 
1757
        precision =  wx.SpinCtrl(parent = panel, id = wx.ID_ANY,
 
1758
                                 min = 0, max = 12,
 
1759
                                 name = "GetValue")
 
1760
        precision.SetValue(int(self.settings.Get(group = 'projection', key = 'format', subkey = 'precision')))
 
1761
        self.winId['projection:format:precision'] = precision.GetId()
 
1762
                
 
1763
        gridSizer.Add(item=ll,
 
1764
                      pos=(row, 0))
 
1765
        gridSizer.Add(item=wx.StaticText(parent = panel, id = wx.ID_ANY,
 
1766
                                         label = _("Precision:")),
 
1767
                      flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT | wx.LEFT,
 
1768
                      border = 20,
 
1769
                      pos=(row, 1))
 
1770
        gridSizer.Add(item=precision,
 
1771
                      flag = wx.ALIGN_CENTER_VERTICAL,
 
1772
                      pos=(row, 2))
 
1773
        
 
1774
        
 
1775
        sizer.Add(item=gridSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=5)
 
1776
        border.Add(item=sizer, proportion=0, flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border=3)
 
1777
        
 
1778
        panel.SetSizer(border)
 
1779
 
 
1780
        # bindings
 
1781
        epsgLoad.Bind(wx.EVT_BUTTON, self.OnLoadEpsgCodes)
 
1782
        epsgCode.Bind(wx.EVT_COMBOBOX, self.OnSetEpsgCode)
 
1783
        epsgCode.Bind(wx.EVT_TEXT_ENTER, self.OnSetEpsgCode)
 
1784
        
 
1785
        return panel
 
1786
 
 
1787
    def _CreateWorkspacePage(self, notebook):
 
1788
        """!Create notebook page for workspace settings"""
1355
1789
        panel = wx.Panel(parent=notebook, id=wx.ID_ANY)
1356
1790
        notebook.AddPage(page=panel, text=_("Workspace"))
1357
1791
 
1394
1828
        
1395
1829
        return panel
1396
1830
 
1397
 
    def __CreateAdvancedPage(self, notebook):
1398
 
        """Create notebook page for advanced settings"""
 
1831
    def _CreateAdvancedPage(self, notebook):
 
1832
        """!Create notebook page for advanced settings"""
1399
1833
        panel = wx.Panel(parent=notebook, id=wx.ID_ANY)
1400
1834
        notebook.AddPage(page=panel, text=_("Advanced"))
1401
1835
 
1463
1897
        
1464
1898
        return panel
1465
1899
 
 
1900
    def OnCheckColorTable(self, event):
 
1901
        """!Set/unset default color table"""
 
1902
        win = self.FindWindowById(self.winId['cmd:rasterColorTable:selection'])
 
1903
        if event.IsChecked():
 
1904
            win.Enable()
 
1905
        else:
 
1906
            win.Enable(False)
 
1907
        
 
1908
    def OnLoadEpsgCodes(self, event):
 
1909
        """!Load EPSG codes from the file"""
 
1910
        win = self.FindWindowById(self.winId['projection:statusbar:projFile'])
 
1911
        path = win.GetValue()
 
1912
 
 
1913
        self.epsgCodeDict = utils.ReadEpsgCodes(path)
 
1914
        list = self.FindWindowById(self.winId['projection:statusbar:epsg'])
 
1915
        if type(self.epsgCodeDict) == type(''):
 
1916
            wx.MessageBox(parent=self,
 
1917
                          message=_("Unable to read EPSG codes: %s") % self.epsgCodeDict,
 
1918
                          caption=_("Error"),  style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
 
1919
            self.epsgCodeDict = dict()
 
1920
            list.SetItems([])
 
1921
            list.SetValue('')
 
1922
            self.FindWindowById(self.winId['projection:statusbar:proj4']).SetValue('')
 
1923
            return
 
1924
        
 
1925
        choices = map(str, self.epsgCodeDict.keys())
 
1926
 
 
1927
        list.SetItems(choices)
 
1928
        try:
 
1929
            code = int(list.GetValue())
 
1930
        except ValueError:
 
1931
            code = -1
 
1932
        win = self.FindWindowById(self.winId['projection:statusbar:proj4'])
 
1933
        if self.epsgCodeDict.has_key(code):
 
1934
            win.SetValue(self.epsgCodeDict[code][1])
 
1935
        else:
 
1936
            list.SetSelection(0)
 
1937
            code = int(list.GetStringSelection())
 
1938
            win.SetValue(self.epsgCodeDict[code][1])
 
1939
    
 
1940
    def OnSetEpsgCode(self, event):
 
1941
        """!EPSG code selected"""
 
1942
        winCode = self.FindWindowById(event.GetId())
 
1943
        win = self.FindWindowById(self.winId['projection:statusbar:proj4'])
 
1944
        if not self.epsgCodeDict:
 
1945
            wx.MessageBox(parent=self,
 
1946
                          message=_("EPSG code %s not found") % event.GetString(),
 
1947
                          caption=_("Error"),  style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
 
1948
            winCode.SetValue('')
 
1949
            win.SetValue('')
 
1950
        
 
1951
        try:
 
1952
            code = int(event.GetString())
 
1953
        except ValueError:
 
1954
            wx.MessageBox(parent=self,
 
1955
                          message=_("EPSG code %s not found") % str(code),
 
1956
                          caption=_("Error"),  style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
 
1957
            winCode.SetValue('')
 
1958
            win.SetValue('')
 
1959
        
 
1960
        
 
1961
        try:
 
1962
            win.SetValue(self.epsgCodeDict[code][1].replace('<>', '').strip())
 
1963
        except KeyError:
 
1964
            wx.MessageBox(parent=self,
 
1965
                          message=_("EPSG code %s not found") % str(code),
 
1966
                          caption=_("Error"),  style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
 
1967
            winCode.SetValue('')
 
1968
            win.SetValue('')
 
1969
        
1466
1970
    def OnSetFont(self, event):
1467
1971
        """'Set font' button pressed"""
1468
1972
        dlg = DefaultFontDialog(parent=self, id=wx.ID_ANY,
1469
1973
                                title=_('Select default display font'),
1470
 
                                style=wx.DEFAULT_DIALOG_STYLE)
 
1974
                                style=wx.DEFAULT_DIALOG_STYLE,
 
1975
                                type='font')
1471
1976
        
1472
1977
        if dlg.ShowModal() == wx.ID_OK:
1473
1978
            # set default font and encoding environmental variables
1485
1990
        dlg.Destroy()
1486
1991
        
1487
1992
        event.Skip()
1488
 
        
1489
 
    def OnSave(self, event):
1490
 
        """Button 'Save' pressed"""
1491
 
        if self.__UpdateSettings():
1492
 
            file = self.settings.SaveToFile()
1493
 
            self.parent.goutput.WriteLog(_('Settings saved to file \'%s\'.') % file)
1494
 
            self.Close()
1495
 
 
1496
 
    def OnApply(self, event):
1497
 
        """Button 'Apply' pressed"""
1498
 
        if self.__UpdateSettings():
1499
 
            self.Close()
1500
 
 
1501
 
    def OnCancel(self, event):
1502
 
        """Button 'Cancel' pressed"""
1503
 
        self.Close()
1504
 
 
1505
 
    def OnDefault(self, event):
1506
 
        """Button 'Set to default' pressed"""
1507
 
        self.settings.userSettings = copy.deepcopy(self.settings.defaultSettings)
1508
 
        
1509
 
        # update widgets
1510
 
        for gks in self.winId.keys():
1511
 
            try:
1512
 
                group, key, subkey = gks.split(':')
1513
 
                value = self.settings.Get(group, key, subkey)
1514
 
            except ValueError:
1515
 
                group, key, subkey, subkey1 = gks.split(':')
1516
 
                value = self.settings.Get(group, key, [subkey, subkey1])
1517
 
            win = self.FindWindowById(self.winId[gks])
1518
 
            if win.GetName() in ('GetValue', 'IsChecked'):
1519
 
                value = win.SetValue(value)
1520
 
            elif win.GetName() == 'GetSelection':
1521
 
                value = win.SetSelection(value)
1522
 
            elif win.GetName() == 'GetStringSelection':
1523
 
                value = win.SetStringSelection(value)
1524
 
            else:
1525
 
                value = win.SetValue(value)
1526
 
 
1527
 
    def __UpdateSettings(self):
1528
 
        """Update user settings"""
1529
 
        for item in self.winId.keys():
1530
 
            try:
1531
 
                group, key, subkey = item.split(':')
1532
 
                subkey1 = None
1533
 
            except ValueError:
1534
 
                group, key, subkey, subkey1 = item.split(':')
1535
 
            
1536
 
            id = self.winId[item]
1537
 
            win = self.FindWindowById(id)
1538
 
            if win.GetName() == 'GetValue':
1539
 
                value = win.GetValue()
1540
 
            elif win.GetName() == 'GetSelection':
1541
 
                value = win.GetSelection()
1542
 
            elif win.GetName() == 'IsChecked':
1543
 
                value = win.IsChecked()
1544
 
            elif win.GetName() == 'GetStringSelection':
1545
 
                value = win.GetStringSelection()
1546
 
            elif win.GetName() == 'GetColour':
1547
 
                value = tuple(win.GetValue())
1548
 
            else:
1549
 
                value = win.GetValue()
1550
 
 
1551
 
            if key == 'keycolumn' and value == '':
1552
 
                wx.MessageBox(parent=self,
1553
 
                              message=_("Key column cannot be empty string."),
1554
 
                              caption=_("Error"), style=wx.OK | wx.ICON_ERROR)
1555
 
                win.SetValue(self.settings.Get(group='atm', key='keycolumn', subkey='value'))
1556
 
                return False
1557
 
 
1558
 
            if subkey1:
1559
 
                self.settings.Set(group, value, key, [subkey, subkey1])
1560
 
            else:
1561
 
                self.settings.Set(group, value, key, subkey)
1562
 
            
 
1993
 
 
1994
    def OnSetOutputFont(self, event):
 
1995
        """'Set output font' button pressed"""
 
1996
        
 
1997
        dlg = DefaultFontDialog(parent=self, id=wx.ID_ANY,
 
1998
                                title=_('Select output font'),
 
1999
                                style=wx.DEFAULT_DIALOG_STYLE,
 
2000
                                type='outputfont')
 
2001
        
 
2002
        if dlg.ShowModal() == wx.ID_OK:
 
2003
            # set output font and font size variables
 
2004
            if dlg.font:
 
2005
                self.settings.Set(group='display', value=dlg.font,
 
2006
                                  key='outputfont', subkey='type')
 
2007
 
 
2008
                self.settings.Set(group='display', value=dlg.fontsize,
 
2009
                                  key='outputfont', subkey='size')
 
2010
 
 
2011
# Standard font dialog broken for Mac in OS X 10.6
 
2012
#        type = self.settings.Get(group='display', key='outputfont', subkey='type')   
 
2013
                           
 
2014
#        size = self.settings.Get(group='display', key='outputfont', subkey='size')
 
2015
#        if size == None or size == 0: size = 10
 
2016
#        size = float(size)
 
2017
        
 
2018
#        data = wx.FontData()
 
2019
#        data.EnableEffects(True)
 
2020
#        data.SetInitialFont(wx.Font(pointSize=size, family=wx.FONTFAMILY_MODERN, faceName=type, style=wx.NORMAL, weight=0))
 
2021
 
 
2022
#        dlg = wx.FontDialog(self, data)
 
2023
 
 
2024
#        if dlg.ShowModal() == wx.ID_OK:
 
2025
#            data = dlg.GetFontData()
 
2026
#            font = data.GetChosenFont()
 
2027
 
 
2028
#            self.settings.Set(group='display', value=font.GetFaceName(),
 
2029
#                                  key='outputfont', subkey='type')
 
2030
#            self.settings.Set(group='display', value=font.GetPointSize(),
 
2031
#                                  key='outputfont', subkey='size')
 
2032
                
 
2033
        dlg.Destroy()
 
2034
 
 
2035
        event.Skip()
 
2036
        
 
2037
    def _updateSettings(self):
 
2038
        """!Update user settings"""
 
2039
        PreferencesBaseDialog._updateSettings(self)
 
2040
        
1563
2041
        #
1564
2042
        # update default window dimension
1565
2043
        #
1589
2067
    """
1590
2068
    def __init__(self, parent, id, title,
1591
2069
                 pos=wx.DefaultPosition, size=wx.DefaultSize,
1592
 
                 style=wx.DEFAULT_DIALOG_STYLE,
1593
 
                 settings=globalSettings):
 
2070
                 style=wx.DEFAULT_DIALOG_STYLE |
 
2071
                 wx.RESIZE_BORDER,
 
2072
                 settings=globalSettings,
 
2073
                 type='font'):
1594
2074
        
1595
2075
        self.settings = settings
 
2076
        self.type = type
1596
2077
        
1597
2078
        wx.Dialog.__init__(self, parent, id, title, pos, size, style)
1598
2079
 
1599
2080
        panel = wx.Panel(parent=self, id=wx.ID_ANY)
1600
2081
        
1601
 
        if "GRASS_FONT" in os.environ:
1602
 
            self.font = os.environ["GRASS_FONT"]
1603
 
        else:
1604
 
            self.font = self.settings.Get(group='display',
1605
 
                                          key='font', subkey='type')
1606
 
 
1607
2082
        self.fontlist = self.GetFonts()
1608
 
 
1609
 
        self.encoding = self.settings.Get(group='display',
1610
 
                                          key='font', subkey='encoding')
1611
2083
        
1612
2084
        border = wx.BoxSizer(wx.VERTICAL)
1613
2085
        box   = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("Font settings"))
1627
2099
                                 style=wx.LB_SINGLE|wx.LB_SORT)
1628
2100
        self.Bind(wx.EVT_LISTBOX, self.EvtListBox, self.fontlb)
1629
2101
        self.Bind(wx.EVT_LISTBOX_DCLICK, self.EvtListBoxDClick, self.fontlb)
 
2102
 
 
2103
        gridSizer.Add(item=self.fontlb,
 
2104
                flag=wx.EXPAND, pos=(1, 0))
 
2105
 
 
2106
        if self.type == 'font':
 
2107
            if "GRASS_FONT" in os.environ:
 
2108
                self.font = os.environ["GRASS_FONT"]
 
2109
            else:
 
2110
                self.font = self.settings.Get(group='display',
 
2111
                                              key='font', subkey='type')
 
2112
            self.encoding = self.settings.Get(group='display',
 
2113
                                          key='font', subkey='encoding')
 
2114
 
 
2115
            label = wx.StaticText(parent=panel, id=wx.ID_ANY,
 
2116
                                  label=_("Character encoding:"))
 
2117
            gridSizer.Add(item=label,
 
2118
                          flag=wx.ALIGN_CENTER_VERTICAL,
 
2119
                          pos=(2, 0))
 
2120
 
 
2121
            self.textentry = wx.TextCtrl(parent=panel, id=wx.ID_ANY,
 
2122
                                         value=self.encoding)
 
2123
            gridSizer.Add(item=self.textentry,
 
2124
                    flag=wx.EXPAND, pos=(3, 0))
 
2125
 
 
2126
            self.textentry.Bind(wx.EVT_TEXT, self.OnEncoding)
 
2127
 
 
2128
        elif self.type == 'outputfont':
 
2129
            self.font = self.settings.Get(group='display',
 
2130
                                              key='outputfont', subkey='type')
 
2131
            self.fontsize = self.settings.Get(group='display',
 
2132
                                          key='outputfont', subkey='size')
 
2133
            label = wx.StaticText(parent=panel, id=wx.ID_ANY,
 
2134
                              label=_("Font size:"))
 
2135
            gridSizer.Add(item=label,
 
2136
                      flag=wx.ALIGN_CENTER_VERTICAL,
 
2137
                      pos=(2, 0))
 
2138
                      
 
2139
            self.spin = wx.SpinCtrl(parent=panel, id=wx.ID_ANY)
 
2140
            if self.fontsize:
 
2141
                self.spin.SetValue(self.fontsize)
 
2142
            self.spin.Bind(wx.EVT_SPINCTRL, self.OnSizeSpin)
 
2143
            self.spin.Bind(wx.EVT_TEXT, self.OnSizeSpin)
 
2144
            gridSizer.Add(item=self.spin,
 
2145
                      flag=wx.ALIGN_CENTER_VERTICAL,
 
2146
                      pos=(3, 0))
 
2147
 
 
2148
        else: 
 
2149
            return
 
2150
 
1630
2151
        if self.font:
1631
2152
            self.fontlb.SetStringSelection(self.font, True)
1632
2153
 
1633
 
        gridSizer.Add(item=self.fontlb,
1634
 
                flag=wx.EXPAND, pos=(0, 1))
1635
 
 
1636
 
        label = wx.StaticText(parent=panel, id=wx.ID_ANY,
1637
 
                              label=("Character encoding:"))
1638
 
        gridSizer.Add(item=label,
1639
 
                      flag=wx.ALIGN_CENTER_VERTICAL,
1640
 
                      pos=(1, 0))
1641
 
 
1642
 
        self.textentry = wx.TextCtrl(parent=panel, id=wx.ID_ANY,
1643
 
                                     value=self.encoding)
1644
 
        gridSizer.Add(item=self.textentry,
1645
 
                flag=wx.EXPAND, pos=(1, 1))
1646
 
 
1647
 
        self.textentry.Bind(wx.EVT_TEXT, self.OnEncoding)
1648
 
 
1649
2154
        sizer.Add(item=gridSizer, proportion=1,
1650
2155
                  flag=wx.EXPAND | wx.ALL,
1651
2156
                  border=5)
1691
2196
    def EvtListBoxDClick(self, event):
1692
2197
        self.font = event.GetString()
1693
2198
        event.Skip()
1694
 
 
 
2199
        
 
2200
    def OnSizeSpin(self, event):
 
2201
        self.fontsize = self.spin.GetValue()
 
2202
        event.Skip()
 
2203
    
1695
2204
    def GetFonts(self):
1696
2205
        """
1697
2206
        parses fonts directory or fretypecap file to get a list of fonts for the listbox
1700
2209
 
1701
2210
        cmd = ["d.font", "-l"]
1702
2211
 
1703
 
        p = gcmd.Command(cmd, stderr=None)
1704
 
 
1705
 
        dfonts = p.ReadStdOutput()
 
2212
        ret = gcmd.RunCommand('d.font',
 
2213
                              read = True,
 
2214
                              flags = 'l')
 
2215
 
 
2216
        if not ret:
 
2217
            return fontlist
 
2218
 
 
2219
        dfonts = ret.splitlines()
1706
2220
        dfonts.sort(lambda x,y: cmp(x.lower(), y.lower()))
1707
2221
        for item in range(len(dfonts)):
1708
2222
           # ignore duplicate fonts and those starting with #
1713
2227
        return fontlist
1714
2228
 
1715
2229
class MapsetAccess(wx.Dialog):
1716
 
    """
1717
 
    Controls setting options and displaying/hiding map overlay decorations
1718
 
    """
1719
 
    def __init__(self, parent, id, title=_('Set/unset access to mapsets in current location'),
1720
 
                 pos=wx.DefaultPosition, size=(350, 400),
1721
 
                 style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER):
 
2230
    """!Controls setting options and displaying/hiding map overlay
 
2231
    decorations
 
2232
    """
 
2233
    def __init__(self, parent, id = wx.ID_ANY,
 
2234
                 title=_('Manage access to mapsets'),
 
2235
                 size = (350, 400),
 
2236
                 style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, **kwargs):
1722
2237
        
1723
 
        wx.Dialog.__init__(self, parent, id, title, pos, size, style)
 
2238
        wx.Dialog.__init__(self, parent, id, title, size = size, style = style, **kwargs)
1724
2239
 
1725
 
        self.all_mapsets = utils.ListOfMapsets(all=True)
1726
 
        self.accessible_mapsets = utils.ListOfMapsets(all=False)
1727
 
        self.curr_mapset = grassenv.GetGRASSVariable('MAPSET')
 
2240
        self.all_mapsets_ordered = utils.ListOfMapsets(get = 'ordered')
 
2241
        self.accessible_mapsets  = utils.ListOfMapsets(get = 'accessible')
 
2242
        self.curr_mapset = grass.gisenv()['MAPSET']
1728
2243
 
1729
2244
        # make a checklistbox from available mapsets and check those that are active
1730
2245
        sizer = wx.BoxSizer(wx.VERTICAL)
1731
2246
 
1732
2247
        label = wx.StaticText(parent=self, id=wx.ID_ANY,
1733
 
                              label=_("Check mapset to make it accessible, uncheck it to hide it.%s"
1734
 
                                      "Note: PERMANENT and current mapset are always accessible.") % os.linesep)
 
2248
                              label=_("Check a mapset to make it accessible, uncheck it to hide it.\n"
 
2249
                                      "  Notes:\n"
 
2250
                                      "    - The current mapset is always accessible.\n"
 
2251
                                      "    - You may only write to the current mapset.\n"
 
2252
                                      "    - You may only write to mapsets which you own."))
 
2253
        
1735
2254
        sizer.Add(item=label, proportion=0,
1736
2255
                  flag=wx.ALL, border=5)
1737
2256
 
1738
2257
        self.mapsetlb = CheckListMapset(parent=self)
1739
 
        self.mapsetlb.LoadData(self.all_mapsets)
 
2258
        self.mapsetlb.LoadData()
1740
2259
        
1741
2260
        sizer.Add(item=self.mapsetlb, proportion=1,
1742
2261
                  flag=wx.ALL | wx.EXPAND, border=5)
1743
2262
 
1744
2263
        # check all accessible mapsets
1745
2264
        for mset in self.accessible_mapsets:
1746
 
            self.mapsetlb.CheckItem(self.all_mapsets.index(mset), True)
 
2265
            self.mapsetlb.CheckItem(self.all_mapsets_ordered.index(mset), True)
 
2266
 
 
2267
        # FIXME (howto?): grey-out current mapset
 
2268
        #self.mapsetlb.Enable(0, False)
1747
2269
 
1748
2270
        # dialog buttons
1749
2271
        line = wx.StaticLine(parent=self, id=wx.ID_ANY,
1771
2293
        self.SetMinSize(size)
1772
2294
        
1773
2295
    def GetMapsets(self):
1774
 
        """Get list of checked mapsets"""
 
2296
        """!Get list of checked mapsets"""
1775
2297
        ms = []
1776
2298
        i = 0
1777
 
        for mset in self.all_mapsets:
 
2299
        for mset in self.all_mapsets_ordered:
1778
2300
            if self.mapsetlb.IsChecked(i):
1779
2301
                ms.append(mset)
1780
2302
            i += 1
1782
2304
        return ms
1783
2305
 
1784
2306
class CheckListMapset(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin, listmix.CheckListCtrlMixin):
1785
 
    """List of mapset/owner/group"""
 
2307
    """!List of mapset/owner/group"""
1786
2308
    def __init__(self, parent, pos=wx.DefaultPosition,
1787
2309
                 log=None):
1788
2310
        self.parent = parent
1795
2317
        # setup mixins
1796
2318
        listmix.ListCtrlAutoWidthMixin.__init__(self)
1797
2319
 
1798
 
    def LoadData(self, mapsets):
1799
 
        """Load data into list"""
 
2320
    def LoadData(self):
 
2321
        """!Load data into list"""
1800
2322
        self.InsertColumn(0, _('Mapset'))
1801
2323
        self.InsertColumn(1, _('Owner'))
1802
2324
        ### self.InsertColumn(2, _('Group'))
 
2325
        gisenv = grass.gisenv()
 
2326
        locationPath = os.path.join(gisenv['GISDBASE'], gisenv['LOCATION_NAME'])
1803
2327
 
1804
 
        locationPath = os.path.join(grassenv.GetGRASSVariable('GISDBASE'),
1805
 
                                    grassenv.GetGRASSVariable('LOCATION_NAME'))
1806
 
        
1807
 
        ret = gcmd.RunCommand('g.mapsets',
1808
 
                              flags = 'l',
1809
 
                              read = True)
1810
 
        mapsets = []
1811
 
        if ret:
1812
 
            mapsets = ret.replace('\n', '').split()
1813
 
        
1814
 
        for mapset in mapsets:
 
2328
        for mapset in self.parent.all_mapsets_ordered:
1815
2329
            index = self.InsertStringItem(sys.maxint, mapset)
1816
2330
            mapsetPath = os.path.join(locationPath,
1817
2331
                                      mapset)
1829
2343
        ### self.SetColumnWidth(col=1, width=wx.LIST_AUTOSIZE)
1830
2344
        
1831
2345
    def OnCheckItem(self, index, flag):
1832
 
        """Mapset checked/unchecked"""
1833
 
        mapset = self.parent.all_mapsets[index]
1834
 
        if mapset == 'PERMANENT' or mapset == self.parent.curr_mapset:
 
2346
        """!Mapset checked/unchecked"""
 
2347
        mapset = self.parent.all_mapsets_ordered[index]
 
2348
        if mapset == self.parent.curr_mapset:
1835
2349
            self.CheckItem(index, True)