| 1 | """
|
|---|
| 2 | @package core.globalvar
|
|---|
| 3 |
|
|---|
| 4 | @brief Global variables used by wxGUI
|
|---|
| 5 |
|
|---|
| 6 | (C) 2007-2016 by the GRASS Development Team
|
|---|
| 7 |
|
|---|
| 8 | This program is free software under the GNU General Public License
|
|---|
| 9 | (>=v2). Read the file COPYING that comes with GRASS for details.
|
|---|
| 10 |
|
|---|
| 11 | @author Martin Landa <landa.martin gmail.com>
|
|---|
| 12 | """
|
|---|
| 13 |
|
|---|
| 14 | from __future__ import print_function
|
|---|
| 15 |
|
|---|
| 16 | import os
|
|---|
| 17 | import sys
|
|---|
| 18 | import locale
|
|---|
| 19 |
|
|---|
| 20 | if not os.getenv("GISBASE"):
|
|---|
| 21 | sys.exit("GRASS is not running. Exiting...")
|
|---|
| 22 |
|
|---|
| 23 | # path to python scripts
|
|---|
| 24 | ETCDIR = os.path.join(os.getenv("GISBASE"), "etc")
|
|---|
| 25 | GUIDIR = os.path.join(os.getenv("GISBASE"), "gui")
|
|---|
| 26 | WXGUIDIR = os.path.join(GUIDIR, "wxpython")
|
|---|
| 27 | ICONDIR = os.path.join(GUIDIR, "icons")
|
|---|
| 28 | IMGDIR = os.path.join(GUIDIR, "images")
|
|---|
| 29 | SYMBDIR = os.path.join(IMGDIR, "symbols")
|
|---|
| 30 |
|
|---|
| 31 | from core.debug import Debug
|
|---|
| 32 |
|
|---|
| 33 | try:
|
|---|
| 34 | # intended to be used also outside this module
|
|---|
| 35 | import gettext
|
|---|
| 36 | trans = gettext.translation('grasswxpy',
|
|---|
| 37 | os.path.join(os.getenv("GISBASE"),
|
|---|
| 38 | 'locale')
|
|---|
| 39 | )
|
|---|
| 40 | _ = trans.gettext if sys.version_info.major >=3 else trans.ugettext
|
|---|
| 41 | except IOError:
|
|---|
| 42 | # using no translation silently
|
|---|
| 43 | def null_gettext(string):
|
|---|
| 44 | return string
|
|---|
| 45 | _ = null_gettext
|
|---|
| 46 |
|
|---|
| 47 | from grass.script.core import get_commands
|
|---|
| 48 |
|
|---|
| 49 |
|
|---|
| 50 | def CheckWxPhoenix():
|
|---|
| 51 | if 'phoenix' in wx.version():
|
|---|
| 52 | return True
|
|---|
| 53 | return False
|
|---|
| 54 |
|
|---|
| 55 |
|
|---|
| 56 | def CheckWxVersion(version):
|
|---|
| 57 | """Check wx version"""
|
|---|
| 58 | ver = wx.__version__
|
|---|
| 59 | try:
|
|---|
| 60 | split_ver = ver.split('.')
|
|---|
| 61 | parsed_version = list(map(int, split_ver))
|
|---|
| 62 | except ValueError:
|
|---|
| 63 | # wxPython 4.0.0aX
|
|---|
| 64 | for i, c in enumerate(split_ver[-1]):
|
|---|
| 65 | if not c.isdigit():
|
|---|
| 66 | break
|
|---|
| 67 | parsed_version = list(map(int, split_ver[:-1])) + [int(split_ver[-1][:i])]
|
|---|
| 68 |
|
|---|
| 69 | if parsed_version < version:
|
|---|
| 70 | return False
|
|---|
| 71 |
|
|---|
| 72 | return True
|
|---|
| 73 |
|
|---|
| 74 |
|
|---|
| 75 | def CheckForWx(forceVersion=os.getenv('GRASS_WXVERSION', None)):
|
|---|
| 76 | """Try to import wx module and check its version
|
|---|
| 77 |
|
|---|
| 78 | :param forceVersion: force wxPython version, eg. '2.8'
|
|---|
| 79 | """
|
|---|
| 80 | if 'wx' in sys.modules.keys():
|
|---|
| 81 | return
|
|---|
| 82 |
|
|---|
| 83 | minVersion = [2, 8, 10, 1]
|
|---|
| 84 | try:
|
|---|
| 85 | try:
|
|---|
| 86 | # Note that Phoenix doesn't have wxversion anymore
|
|---|
| 87 | import wxversion
|
|---|
| 88 | except ImportError as e:
|
|---|
| 89 | # if there is no wx raises ImportError
|
|---|
| 90 | import wx
|
|---|
| 91 | return
|
|---|
| 92 | if forceVersion:
|
|---|
| 93 | wxversion.select(forceVersion)
|
|---|
| 94 | wxversion.ensureMinimal(str(minVersion[0]) + '.' + str(minVersion[1]))
|
|---|
| 95 | import wx
|
|---|
| 96 | version = wx.__version__
|
|---|
| 97 |
|
|---|
| 98 | if map(int, version.split('.')) < minVersion:
|
|---|
| 99 | raise ValueError(
|
|---|
| 100 | 'Your wxPython version is %s.%s.%s.%s' %
|
|---|
| 101 | tuple(version.split('.')))
|
|---|
| 102 |
|
|---|
| 103 | except ImportError as e:
|
|---|
| 104 | print('ERROR: wxGUI requires wxPython. %s' % str(e),
|
|---|
| 105 | file=sys.stderr)
|
|---|
| 106 | print('You can still use GRASS GIS modules in'
|
|---|
| 107 | ' the command line or in Python.', file=sys.stderr)
|
|---|
| 108 | sys.exit(1)
|
|---|
| 109 | except (ValueError, wxversion.VersionError) as e:
|
|---|
| 110 | print('ERROR: wxGUI requires wxPython >= %d.%d.%d.%d. ' % tuple(
|
|---|
| 111 | minVersion) + '%s.' % (str(e)), file=sys.stderr)
|
|---|
| 112 | sys.exit(1)
|
|---|
| 113 | except locale.Error as e:
|
|---|
| 114 | print("Unable to set locale:", e, file=sys.stderr)
|
|---|
| 115 | os.environ['LC_ALL'] = ''
|
|---|
| 116 |
|
|---|
| 117 | if not os.getenv("GRASS_WXBUNDLED"):
|
|---|
| 118 | CheckForWx()
|
|---|
| 119 | import wx
|
|---|
| 120 |
|
|---|
| 121 | if CheckWxPhoenix():
|
|---|
| 122 | try:
|
|---|
| 123 | import agw.flatnotebook as FN
|
|---|
| 124 | except ImportError: # if it's not there locally, try the wxPython lib.
|
|---|
| 125 | import wx.lib.agw.flatnotebook as FN
|
|---|
| 126 | else:
|
|---|
| 127 | import wx.lib.flatnotebook as FN
|
|---|
| 128 |
|
|---|
| 129 |
|
|---|
| 130 |
|
|---|
| 131 | """
|
|---|
| 132 | Query layer (generated for example by selecting item in the Attribute Table Manager)
|
|---|
| 133 | Deleted automatically on re-render action
|
|---|
| 134 | """
|
|---|
| 135 | # temporal query layer (removed on re-render action)
|
|---|
| 136 | QUERYLAYER = 'qlayer'
|
|---|
| 137 |
|
|---|
| 138 | """Style definition for FlatNotebook pages"""
|
|---|
| 139 | FNPageStyle = FN.FNB_VC8 | \
|
|---|
| 140 | FN.FNB_BACKGROUND_GRADIENT | \
|
|---|
| 141 | FN.FNB_NODRAG | \
|
|---|
| 142 | FN.FNB_TABS_BORDER_SIMPLE
|
|---|
| 143 |
|
|---|
| 144 | FNPageDStyle = FN.FNB_FANCY_TABS | \
|
|---|
| 145 | FN.FNB_BOTTOM | \
|
|---|
| 146 | FN.FNB_NO_NAV_BUTTONS | \
|
|---|
| 147 | FN.FNB_NO_X_BUTTON
|
|---|
| 148 |
|
|---|
| 149 | FNPageColor = wx.Colour(125, 200, 175)
|
|---|
| 150 |
|
|---|
| 151 | """Dialog widget dimension"""
|
|---|
| 152 | DIALOG_SPIN_SIZE = (150, -1)
|
|---|
| 153 | DIALOG_COMBOBOX_SIZE = (300, -1)
|
|---|
| 154 | DIALOG_GSELECT_SIZE = (400, -1)
|
|---|
| 155 | DIALOG_TEXTCTRL_SIZE = (400, -1)
|
|---|
| 156 | DIALOG_LAYER_SIZE = (100, -1)
|
|---|
| 157 | DIALOG_COLOR_SIZE = (30, 30)
|
|---|
| 158 |
|
|---|
| 159 | MAP_WINDOW_SIZE = (825, 600)
|
|---|
| 160 |
|
|---|
| 161 | GM_WINDOW_MIN_SIZE = (525, 400)
|
|---|
| 162 | # small for ms window which wraps the menu
|
|---|
| 163 | # small for max os x which has the global menu
|
|---|
| 164 | # small for ubuntu when menuproxy is defined
|
|---|
| 165 | # not defined UBUNTU_MENUPROXY on linux means standard menu,
|
|---|
| 166 | # so the probably problem
|
|---|
| 167 | # UBUNTU_MENUPROXY= means ubuntu with disabled global menu [1]
|
|---|
| 168 | # use UBUNTU_MENUPROXY=0 to disbale global menu on ubuntu but in the same time
|
|---|
| 169 | # to get smaller lmgr
|
|---|
| 170 | # [1] https://wiki.ubuntu.com/DesktopExperienceTeam/ApplicationMenu#Troubleshooting
|
|---|
| 171 | if sys.platform in ('win32', 'darwin') or os.environ.get('UBUNTU_MENUPROXY'):
|
|---|
| 172 | GM_WINDOW_SIZE = (GM_WINDOW_MIN_SIZE[0], 600)
|
|---|
| 173 | else:
|
|---|
| 174 | GM_WINDOW_SIZE = (625, 600)
|
|---|
| 175 |
|
|---|
| 176 | if sys.platform == 'win32':
|
|---|
| 177 | BIN_EXT = '.exe'
|
|---|
| 178 | SCT_EXT = '.bat'
|
|---|
| 179 | else:
|
|---|
| 180 | BIN_EXT = SCT_EXT = ''
|
|---|
| 181 |
|
|---|
| 182 |
|
|---|
| 183 | def UpdateGRASSAddOnCommands(eList=None):
|
|---|
| 184 | """Update list of available GRASS AddOns commands to use when
|
|---|
| 185 | parsing string from the command line
|
|---|
| 186 |
|
|---|
| 187 | :param eList: list of AddOns commands to remove
|
|---|
| 188 | """
|
|---|
| 189 | global grassCmd, grassScripts
|
|---|
| 190 |
|
|---|
| 191 | # scan addons (path)
|
|---|
| 192 | addonPath = os.getenv('GRASS_ADDON_PATH', '')
|
|---|
| 193 | addonBase = os.getenv('GRASS_ADDON_BASE')
|
|---|
| 194 | if addonBase:
|
|---|
| 195 | addonPath += os.pathsep + os.path.join(addonBase, 'bin')
|
|---|
| 196 | if sys.platform != 'win32':
|
|---|
| 197 | addonPath += os.pathsep + os.path.join(addonBase, 'scripts')
|
|---|
| 198 |
|
|---|
| 199 | # remove commands first
|
|---|
| 200 | if eList:
|
|---|
| 201 | for ext in eList:
|
|---|
| 202 | if ext in grassCmd:
|
|---|
| 203 | grassCmd.remove(ext)
|
|---|
| 204 | Debug.msg(1, "Number of removed AddOn commands: %d", len(eList))
|
|---|
| 205 |
|
|---|
| 206 | nCmd = 0
|
|---|
| 207 | pathList = os.getenv('PATH', '').split(os.pathsep)
|
|---|
| 208 | for path in addonPath.split(os.pathsep):
|
|---|
| 209 | if not os.path.exists(path) or not os.path.isdir(path):
|
|---|
| 210 | continue
|
|---|
| 211 |
|
|---|
| 212 | # check if addon is in the path
|
|---|
| 213 | if pathList and path not in pathList:
|
|---|
| 214 | os.environ['PATH'] = path + os.pathsep + os.environ['PATH']
|
|---|
| 215 |
|
|---|
| 216 | for fname in os.listdir(path):
|
|---|
| 217 | if fname in ['docs', 'modules.xml']:
|
|---|
| 218 | continue
|
|---|
| 219 | if grassScripts: # win32
|
|---|
| 220 | name, ext = os.path.splitext(fname)
|
|---|
| 221 | if name not in grassCmd:
|
|---|
| 222 | if ext not in [BIN_EXT, SCT_EXT]:
|
|---|
| 223 | continue
|
|---|
| 224 | if name not in grassCmd:
|
|---|
| 225 | grassCmd.add(name)
|
|---|
| 226 | Debug.msg(3, "AddOn commands: %s", name)
|
|---|
| 227 | nCmd += 1
|
|---|
| 228 | if ext == SCT_EXT and \
|
|---|
| 229 | ext in grassScripts.keys() and \
|
|---|
| 230 | name not in grassScripts[ext]:
|
|---|
| 231 | grassScripts[ext].append(name)
|
|---|
| 232 | else:
|
|---|
| 233 | if fname not in grassCmd:
|
|---|
| 234 | grassCmd.add(fname)
|
|---|
| 235 | Debug.msg(3, "AddOn commands: %s", fname)
|
|---|
| 236 | nCmd += 1
|
|---|
| 237 |
|
|---|
| 238 | Debug.msg(1, "Number of GRASS AddOn commands: %d", nCmd)
|
|---|
| 239 |
|
|---|
| 240 | """@brief Collected GRASS-relared binaries/scripts"""
|
|---|
| 241 | grassCmd, grassScripts = get_commands()
|
|---|
| 242 | Debug.msg(1, "Number of core GRASS commands: %d", len(grassCmd))
|
|---|
| 243 | UpdateGRASSAddOnCommands()
|
|---|
| 244 |
|
|---|
| 245 | """@Toolbar icon size"""
|
|---|
| 246 | toolbarSize = (24, 24)
|
|---|
| 247 |
|
|---|
| 248 | """@Check version of wxPython, use agwStyle for 2.8.11+"""
|
|---|
| 249 | hasAgw = CheckWxVersion([2, 8, 11, 0])
|
|---|
| 250 | wxPython3 = CheckWxVersion([3, 0, 0, 0])
|
|---|
| 251 | wxPythonPhoenix = CheckWxPhoenix()
|
|---|
| 252 |
|
|---|
| 253 | gtk3 = True if 'gtk3' in wx.PlatformInfo else False
|
|---|
| 254 |
|
|---|
| 255 | """@Add GUIDIR/scripts into path"""
|
|---|
| 256 | os.environ['PATH'] = os.path.join(
|
|---|
| 257 | GUIDIR, 'scripts') + os.pathsep + os.environ['PATH']
|
|---|