diff --git a/fsl/__init__.py b/fsl/__init__.py index b82e1ba3fd253ef40ddf3df9beca764a69cfb333..3bcf0bb9c8e757dd6535f7392cf9fb240a3d24ea 100644 --- a/fsl/__init__.py +++ b/fsl/__init__.py @@ -320,17 +320,22 @@ def fslDirWarning(frame, toolName, fslEnvActive): if fslEnvActive: return - msg = 'The FSLDIR environment variable is not set - '\ - '{} may not behave correctly.'.format(toolName) + warnmsg = 'The FSLDIR environment variable is not set - '\ + '{} may not behave correctly.'.format(toolName) if frame is not None: import wx - wx.MessageDialog( - frame, - message=msg, - style=wx.OK | wx.ICON_EXCLAMATION).ShowModal() + from fsl.utils.fsldirdlg import FSLDirDialog + + dlg = FSLDirDialog(frame, toolName) + + if dlg.ShowModal() == wx.ID_OK: + fsldir = dlg.GetFSLDir() + log.debug('Setting $FSLDIR to {} (specified ' + 'by user)'.format(fsldir)) + os.environ['FSLDIR'] = fsldir else: - log.warn(msg) + log.warn(warnmsg) def buildGUI(args, fslTool, toolCtx, fslEnvActive): diff --git a/fsl/data/atlases.py b/fsl/data/atlases.py index b9ddf49d5f7bcfb87207f888597af34c00af539f..dd5165a7bbda47f5b2f44cbd6f2490859491cc83 100644 --- a/fsl/data/atlases.py +++ b/fsl/data/atlases.py @@ -61,13 +61,18 @@ import fsl.utils.transform as transform log = logging.getLogger(__name__) +ATLAS_DIR = None -if os.environ.get('FSLDIR', None) is None: - log.warn('$FSLDIR is not set - atlases are not available') +def _setAtlasDir(): + global ATLAS_DIR - ATLAS_DIR = None -else: - ATLAS_DIR = op.join(os.environ['FSLDIR'], 'data', 'atlases') + if ATLAS_DIR is not None: + return + + if os.environ.get('FSLDIR', None) is None: + log.warn('$FSLDIR is not set - atlases are not available') + else: + ATLAS_DIR = op.join(os.environ['FSLDIR'], 'data', 'atlases') ATLAS_DESCRIPTIONS = collections.OrderedDict() @@ -84,6 +89,8 @@ def listAtlases(refresh=False): :attr:`ATLAS_DESCRIPTIONS`). """ + _setAtlasDir() + if ATLAS_DIR is None: return [] @@ -112,6 +119,8 @@ def getAtlasDescription(atlasID): atlas with the given ``atlasID``. """ + _setAtlasDir() + if ATLAS_DIR is None: return None @@ -130,6 +139,8 @@ def loadAtlas(atlasID, loadSummary=False): a 4D :class:`ProbabilisticAtlas` image is loaded. """ + _setAtlasDir() + if ATLAS_DIR is None: return None diff --git a/fsl/data/strings.py b/fsl/data/strings.py index 338b7aa17ad144e1a3fceb0a1de81e756f7acfd1..ffbadc580a64bca2065dabe89e15e187631bf2c7 100644 --- a/fsl/data/strings.py +++ b/fsl/data/strings.py @@ -10,6 +10,12 @@ import fsl.data.constants as constants messages = TypeDict({ + 'FSLDirDialog.FSLDirNotSet' : 'The $FSLDIR environment variable ' + 'is not set - \n{} may not behave ' + 'correctly.', + 'FSLDirDialog.selectFSLDir' : 'Select the directory in which ' + 'FSL is installed', + 'fslview.loading' : 'Loading {}', 'FSLViewSplash.default' : 'Loading ...', @@ -92,6 +98,9 @@ messages = TypeDict({ titles = TypeDict({ + + 'FSLDirDialog' : '$FSLDIR is not set', + 'image.saveImage.dialog' : 'Save image file', 'ProcessingDialog.error' : 'Error', @@ -182,6 +191,10 @@ actions = TypeDict({ }) labels = TypeDict({ + + 'FSLDirDialog.locate' : 'Locate $FSLDIR', + 'FSLDirDialog.skip' : 'Skip', + 'LocationPanel.worldLocation' : 'Coordinates: ', 'LocationPanel.worldLocation.unknown' : 'Unknown', 'LocationPanel.voxelLocation' : 'Voxel location', diff --git a/fsl/utils/fsldirdlg.py b/fsl/utils/fsldirdlg.py new file mode 100644 index 0000000000000000000000000000000000000000..ba983379b6b9513200235c9784a3dfad06943d70 --- /dev/null +++ b/fsl/utils/fsldirdlg.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python +# +# fsldirdlg.py +# +# +# Author: Paul McCarthy <pauldmccarthy@gmail.com> +# +""" +This module defines a dialog which can be used, when the ``$FSLDIR`` +environment variable is not set, to prompt the user to identify the +FSL installation location. +""" + + +import wx + +import fsl.data.strings as strings + + +class FSLDirDialog(wx.Dialog): + + def __init__(self, parent, toolName): + + wx.Dialog.__init__(self, parent, title=strings.titles[self]) + + self.__fsldir = None + self.__icon = wx.StaticBitmap(self) + self.__message = wx.StaticText( self, style=wx.ALIGN_CENTRE) + self.__locate = wx.Button( self, id=wx.ID_OK) + self.__skip = wx.Button( self, id=wx.ID_CANCEL) + + icon = wx.ArtProvider.GetMessageBoxIcon(wx.ICON_EXCLAMATION) + bmp = wx.EmptyBitmap(icon.GetWidth(), icon.GetHeight()) + bmp.CopyFromIcon(icon) + + self.__icon.SetBitmap(bmp) + self.__message.SetLabel( + strings.messages[self, 'FSLDirNotSet'].format(toolName)) + self.__locate .SetLabel(strings.labels[self, 'locate']) + self.__skip .SetLabel(strings.labels[self, 'skip']) + + self.__skip .Bind(wx.EVT_BUTTON, self.__onSkip) + self.__locate.Bind(wx.EVT_BUTTON, self.__onLocate) + + self.__sizer = wx.BoxSizer(wx.VERTICAL) + self.__labelSizer = wx.BoxSizer(wx.HORIZONTAL) + self.__buttonSizer = wx.BoxSizer(wx.HORIZONTAL) + + self.__labelSizer.Add(self.__icon, flag=wx.ALL | wx.CENTRE, + border=20) + self.__labelSizer.Add(self.__message, + flag=wx.ALL | wx.CENTRE, + proportion=1, + border=20) + + self.__buttonSizer.AddStretchSpacer() + self.__buttonSizer.Add(self.__locate, + flag=wx.ALL | wx.CENTRE, + border=10, + proportion=1) + self.__buttonSizer.Add(self.__skip, + flag=wx.ALL | wx.CENTRE, + border=10, + proportion=1) + + self.__buttonSizer.Add((40, -1)) + + self.__sizer.Add(self.__labelSizer, flag=wx.EXPAND, proportion=1) + self.__sizer.Add(self.__buttonSizer, flag=wx.EXPAND) + + self.SetSizer(self.__sizer) + self.Fit() + + + def GetFSLDir(self): + return self.__fsldir + + + def __onSkip(self, ev): + self.EndModal(wx.ID_CANCEL) + + + def __onLocate(self, ev): + + dlg = wx.DirDialog( + self, + message=strings.messages[self, 'selectFSLDir'], + style=wx.DD_DEFAULT_STYLE | wx.DD_DIR_MUST_EXIST) + + if dlg.ShowModal() != wx.ID_OK: + self.EndModal(wx.ID_CANCEL) + + self.__fsldir = dlg.GetPath() + + self.EndModal(wx.ID_OK)