Beispiel #1
0
 def runLayerConfigAction(self):
     '''Arg-less action to open a new layer config dialog'''        
     dest,lgval,uconf,_,_,_,_,_ = self.controls.readParameters()
     
     if not LU.assessNone(dest):
         self.controls.setStatus(self.controls.STATUS.IDLE,'Cannot open Layer-Config without defined Destination')
         return
         
     if self.confconn is None:
         #build a new confconn
         self.confconn = ConfigConnector(uconf,lgval,dest)
     else:
         #if any parameters have changed, re-initialise
         self.confconn.initConnections(uconf,lgval,dest)
         
     self.runLayerConfigDialog()
Beispiel #2
0
 def initConfigConnector(self,gvs=None,initlc=None):
     '''Try to initialise the configconnector object'''
     self.gvs = gvs if gvs else self.updateFromGPR()
     try:
         uc = self.gvs[2]
         dst = self.gvs[0]
         self.confconn = ConfigConnector(self,uc,self.gvs[1],dst,initlc)
     except RuntimeError as rer:
         msg = 'Runtime error creating {} using "{}.conf" config file. {}'.format(self.gvs[0],uc,rer)
         self.errorEvent(msg)
     except UnicodeEncodeError as uee:
         msg = 'Unicode Encode Error, encode/sanitise input and try again. {}'.format(uee)
         self.errorEvent(msg)
         raise
     except UnicodeDecodeError as ude:
         msg = 'Unicode Decode Error, stored unicode value not being presented correctly. {}'.format(ude)
         #self.errorEvent(msg)
         raise
     except DatasourceCreateException as dce:
         msg = 'Cannot DS CREATE {} connection using "{}.conf" config file. Switching selected config and retrying. Please edit config or set new datasource; {}'.format(dst,uc,dce)
         self.switchDSSelection(dst)
         self.errorEvent(msg)
     except DatasourceOpenException as doe:
         msg = 'Cannot DS OPEN {} connection using "{}.conf" config file. Switching selected config and retrying. Please edit config or set new datasource; {}'.format(dst,uc,doe)
         self.switchDSSelection(dst)
         self.errorEvent(msg)
     except EndpointConnectionException as ece:
         msg = 'Cannot open {} connection using "{}.conf" config file. Internal error; {}'.format(dst,uc,ece)
         self.alertEvent(msg)    
         self.runWizardDialog(uc if uc else self.DUMMY_CONF,dst)
         os.remove(os.path.abspath(os.path.join(os.path.dirname(__file__),'../conf/',self.DUMMY_CONF+'.conf')))
     except ConnectionConfigurationException as cce:
         msg = 'Cannot open {} connection; {}'.format(dst,cce)
         self.alertEvent(msg)   
         self.runWizardDialog(uc if uc else self.DUMMY_CONF,dst)
         os.remove(os.path.abspath(os.path.join(os.path.dirname(__file__),'../conf/',self.DUMMY_CONF+'.conf')))
Beispiel #3
0
 def runLayerConfigAction(self):
     '''Arg-less action to open a new layer config dialog'''        
     dest,lgval,uconf,_,_,_,_,_ = self.controls.readParameters()
     
     if not LU.assessNone(dest):
         self.controls.setStatus(self.controls.STATUS.IDLE,'Cannot open Layer-Config without defined Destination')
         return
         
     if self.confconn is None:
         #build a new confconn
         self.confconn = ConfigConnector(uconf,lgval,dest)
     else:
         #if any parameters have changed, re-initialise
         self.confconn.initConnections(uconf,lgval,dest)
         
     self.runLayerConfigDialog()
Beispiel #4
0
 def initConfigConnector(self,gvs=None,initlc=None):
     '''Try to initialise the configconnector object'''
     self.gvs = gvs if gvs else self.updateFromGPR()
     try:
         uc = self.gvs[2]
         dst = self.gvs[0]
         self.confconn = ConfigConnector(self,uc,self.gvs[1],dst,initlc)
     except RuntimeError as rer:
         msg = 'Runtime error creating {} using "{}.conf" config file. {}'.format(self.gvs[0],uc,rer)
         self.errorEvent(msg)
     except UnicodeEncodeError as uee:
         msg = 'Unicode Encode Error, encode/sanitise input and try again. {}'.format(uee)
         self.errorEvent(msg)
         raise
     except UnicodeDecodeError as ude:
         msg = 'Unicode Decode Error, stored unicode value not being presented correctly. {}'.format(ude)
         #self.errorEvent(msg)
         raise
     except DatasourceCreateException as dce:
         msg = 'Cannot DS CREATE {} connection using "{}.conf" config file. Switching selected config and retrying. Please edit config or set new datasource; {}'.format(dst,uc,dce)
         self.switchDSSelection(dst)
         self.errorEvent(msg)
     except DatasourceOpenException as doe:
         msg = 'Cannot DS OPEN {} connection using "{}.conf" config file. Switching selected config and retrying. Please edit config or set new datasource; {}'.format(dst,uc,doe)
         self.switchDSSelection(dst)
         self.errorEvent(msg)
     except EndpointConnectionException as ece:
         msg = 'Cannot open {} connection using "{}.conf" config file. Internal error; {}'.format(dst,uc,ece)
         self.alertEvent(msg)    
         self.runWizardDialog(uc if uc else self.DUMMY_CONF,dst)
         os.remove(os.path.abspath(os.path.join(os.path.dirname(__file__),'../conf/',self.DUMMY_CONF+'.conf')))
     except ConnectionConfigurationException as cce:
         msg = 'Cannot open {} connection; {}'.format(dst,cce)
         self.alertEvent(msg)   
         self.runWizardDialog(uc if uc else self.DUMMY_CONF,dst)
         os.remove(os.path.abspath(os.path.join(os.path.dirname(__file__),'../conf/',self.DUMMY_CONF+'.conf')))
Beispiel #5
0
class Test_2_ConfigConnector(unittest.TestCase):
    
    UCONF = 'TEST'
    LGVAL = 'v:x100'
    DESTNAME = 'PostgreSQL'
    
    def setUp(self):
        testlog.debug('ConfigConnector_Test.setUp')
        self.configconnector = ConfigConnector(None,self.UCONF,self.LGVAL,self.DESTNAME)    
        self.sep,self.dep = self._fetchEPs()
        self.configconnector.reg.setupLayerConfig(self.configconnector.tp,self.sep,self.dep)
        
    def tearDown(self):
        testlog.debug('ConfigConnector_Test.tearDown')
        self._dropEPs()

    def _fetchEPs(self):
        sep = self.configconnector.reg.openEndPoint('WFS', self.UCONF)
        dep = self.configconnector.reg.openEndPoint(self.DESTNAME, self.UCONF)
        return sep,dep
        
    def _dropEPs(self):
        self.configconnector.reg.closeEndPoint('WFS')
        self.configconnector.reg.closeEndPoint(self.DESTNAME)
        self.sep, self.dep = None, None
        
        
    def test_2_setupComplete(self):     
        self.assertIsNotNone(self.configconnector.complete,'complete init')
        self.configconnector.setupCompleteLayerList(self.dep)
        self.assertIsNotNone(self.configconnector.complete,'complete indep')
    
    def test_1_setupReserved(self): 
        self.assertIsNotNone(self.configconnector.reserved,'reserved init')
        self.configconnector.setupReservedLayerList()
        self.assertIsNotNone(self.configconnector.reserved,'reserved indep')
            
    def test_3_setupAssigned(self):
        self.assertIsNotNone(self.configconnector.assigned,'assigned init')
        self.configconnector.setupAssignedLayerList()
        self.assertIsNotNone(self.configconnector.assigned,'assigned indep')
Beispiel #6
0
class LDSMain(QMainWindow):
    '''This file (GUI functionality) has not been tested in any meaningful way and is likely to break on unexpected input'''
    
    HELPFILE = os.path.abspath(os.path.join(os.path.dirname(__file__),'../../doc/README'))
    #            destname,lgval,uc, epsg, fd,td
    DEF_RVALS = ('',      '',   '','2193','','')
    
    MAX_WIZARD_ATTEMPTS = 2
    
    DUMMY_CONF = '_deleteme'
    
    WGEO = (300, 300, 350, 250)
    
    def __init__(self,initlc=False):        ####INITLC FOR TRACING ONLY DELETE IN PRODUCTION
        super(LDSMain, self).__init__()
        
        self.layers = None
        self.groups = None
        self.gpr = None
        self.gvs = None
        
        initcc = True
        #if init=False no point reading gpr vals
        wcount = 0
        while initcc and wcount<self.MAX_WIZARD_ATTEMPTS:
            try:
                self.initConfigConnector(initlc=initlc)
                initcc = False
                break
            except MalformedConnectionString as mcse:
                ldslog.warn('Connection String malformed or missing. '+str(mcse))
                self.runWizardDialog(None,None)
                wcount += 1
            except DriverInitialisationException as die:
                ldslog.warn('Cannot Initialise selected driver. '+str(die))
                self.runWizardDialog(None,None)
                wcount += 1
                #self.initConfigConnector(self.DEF_RVALS)
                #initcc = False
            except Exception as e:
                ldslog.error('Unhandled Exception in Config Setup. '+str(e))
                wcount += 1
        else:
            raise e

        self.setGeometry(*self.WGEO)
        self.setWindowTitle('LDS Data Replicator')
        self.setWindowIcon(QIcon(LINZ))
        
        self.statusbar = self.statusBar()
        self.statusbar.showMessage('Ready')
        
        self.controls = LDSControls(self)
        
        self.setCentralWidget(self.controls)
        
        openUCAction = QAction(QIcon(OPEN), 'Open &User Config', self)        
        openUCAction.setShortcut('Ctrl+U')
        openUCAction.setStatusTip('Open User Preferences Editor')
        openUCAction.triggered.connect(self.launchUCEditor)
        
        openLCAction = QAction(QIcon(OPEN), 'Open &Layer Config', self)        
        openLCAction.setShortcut('Ctrl+L')
        openLCAction.setStatusTip('Open Layer Config File (only applies to external LC storage)')
        openLCAction.triggered.connect(self.launchLCEditor)
        #self.enableLCEdit(openLCAction)
        
        initUCAction = QAction(QIcon(UC), 'Database &Setup Wizard', self)   
        initUCAction.setShortcut('Ctrl+S')
        initUCAction.setStatusTip('Open Database Setup Wizard')
        initUCAction.triggered.connect(self.runWizardAction)
        
        initLCAction = QAction(QIcon(LC), 'Layer &Config Editor', self)   
        initLCAction.setShortcut('Ctrl+C')
        initLCAction.setStatusTip('Open Layer Config Editor')
        initLCAction.triggered.connect(self.runLayerConfigAction)
        
        exitAction = QAction(QIcon(EXIT), '&Exit', self)        
        exitAction.setShortcut('Ctrl+E')
        exitAction.setStatusTip('Exit Application')
        exitAction.triggered.connect(self.close)#qApp.quit)
        
        helpAction = QAction(QIcon(HELP), '&Help', self)        
        helpAction.setShortcut('Ctrl+H')
        helpAction.setStatusTip('Open Help Document')
        helpAction.triggered.connect(self.launchHelpFile)
        
        self.menubar = self.menuBar()

        fileMenu = self.menubar.addMenu('&File')
        fileMenu.addAction(openUCAction)
        fileMenu.addAction(openLCAction)
        fileMenu.addSeparator()
        fileMenu.addAction(initUCAction)
        fileMenu.addAction(initLCAction)
        fileMenu.addSeparator()
        fileMenu.addAction(exitAction)

        helpMenu = self.menubar.addMenu('&Help')
        helpMenu.addAction(helpAction)

    def updateFromGPR(self):
        '''Read GPR file for changes or init'''
        if not self.gpr: 
            self.gpr = GUIPrefsReader()
        return [x if LU.assessNone(x) else y for x,y in zip(self.gpr.read(),self.DEF_RVALS)]
        
    def initConfigConnector(self,gvs=None,initlc=None):
        '''Try to initialise the configconnector object'''
        self.gvs = gvs if gvs else self.updateFromGPR()
        try:
            uc = self.gvs[2]
            dst = self.gvs[0]
            self.confconn = ConfigConnector(self,uc,self.gvs[1],dst,initlc)
        except RuntimeError as rer:
            msg = 'Runtime error creating {} using "{}.conf" config file. {}'.format(self.gvs[0],uc,rer)
            self.errorEvent(msg)
        except UnicodeEncodeError as uee:
            msg = 'Unicode Encode Error, encode/sanitise input and try again. {}'.format(uee)
            self.errorEvent(msg)
            raise
        except UnicodeDecodeError as ude:
            msg = 'Unicode Decode Error, stored unicode value not being presented correctly. {}'.format(ude)
            #self.errorEvent(msg)
            raise
        except DatasourceCreateException as dce:
            msg = 'Cannot DS CREATE {} connection using "{}.conf" config file. Switching selected config and retrying. Please edit config or set new datasource; {}'.format(dst,uc,dce)
            self.switchDSSelection(dst)
            self.errorEvent(msg)
        except DatasourceOpenException as doe:
            msg = 'Cannot DS OPEN {} connection using "{}.conf" config file. Switching selected config and retrying. Please edit config or set new datasource; {}'.format(dst,uc,doe)
            self.switchDSSelection(dst)
            self.errorEvent(msg)
        except EndpointConnectionException as ece:
            msg = 'Cannot open {} connection using "{}.conf" config file. Internal error; {}'.format(dst,uc,ece)
            self.alertEvent(msg)    
            self.runWizardDialog(uc if uc else self.DUMMY_CONF,dst)
            os.remove(os.path.abspath(os.path.join(os.path.dirname(__file__),'../conf/',self.DUMMY_CONF+'.conf')))
        except ConnectionConfigurationException as cce:
            msg = 'Cannot open {} connection; {}'.format(dst,cce)
            self.alertEvent(msg)   
            self.runWizardDialog(uc if uc else self.DUMMY_CONF,dst)
            os.remove(os.path.abspath(os.path.join(os.path.dirname(__file__),'../conf/',self.DUMMY_CONF+'.conf')))
                

    def switchDSSelection(self,disconnected):
        #check next best configured DS configs
        trythis = [DataStore.DRIVER_NAMES[i] for i in ('fg','sl','pg','ms') 
                   if DataStore.DRIVER_NAMES[i] in self.gpr.getDestinations() 
                   and DataStore.DRIVER_NAMES[i] != disconnected][0]
        self.gpr.writesecline('prefs', 'dest', trythis)
        
    def enableLCEdit(self,control):
        '''Enable User Config read control for external configs'''
        dep = self.confconn.reg.openEndPoint(self.confconn.destname,self.confconn.uconf)
        control.setEnabled(dep.confwrap.readDSProperty(self.confconn.destname,'config')=='external')
        self.confconn.reg.closeEndPoint(self.confconn.destname)
        dep = None
        
    def launchUCEditor(self, checked=None):
        '''User Config Editor launch'''
        fn = LU.standardiseUserConfigName(str(self.controls.cflist[self.controls.confcombo.currentIndex()]))
        prefs = LDSPrefsEditor(fn,self)
        prefs.setWindowTitle('LDS Preferences Editor (User Config)')
        prefs.show()    
        
    def launchLCEditor(self, checked=None):
        '''Layer Config Editor launch'''
        fn = LU.standardiseLayerConfigName(str(self.controls.destlist[self.controls.destcombo.currentIndex()]))
        prefs = LDSPrefsEditor(fn,self)
        prefs.setWindowTitle('LDS Preferences Editor (Layer Config)')
        prefs.show()
        
    def launchHelpFile(self):
        if os.name == 'nt':
            #windows
            from lds.WinUtilities import WinUtilities
            WinUtilities.callStartFile(self.HELPFILE)
        elif os.name == 'posix':
            #posix
            subprocess.Popen(['xdg-open', self.HELPFILE])

        
    def runWizardAction(self):
        '''Init and run the User Config setup wizz'''
        self.controls.setStatus(self.controls.STATUS.BUSY,'Opening User-Config Wizard')  
        #rather than readparams
        uconf = self.controls.confcombo.itemText(self.controls.confcombo.currentIndex())
        secname = self.controls.destcombo.itemText(self.controls.destcombo.currentIndex())
        self.statusbar.showMessage('Editing User-Config')
        self.runWizardDialog(uconf, secname)
        #update the gui with new dest data
        self.initConfigConnector()
        self.controls.updateGUIValues(self.gvs)

        
    def runWizardDialog(self,uconf,secname):
        '''User Config/Wizz dialog opener'''
        from lds.gui.MainConfigWizard import LDSConfigWizard
        ldscw = LDSConfigWizard(uconf,secname,self)
        ldscw.exec_()
        ldscw = None
        
    
    def runLayerConfigAction(self):
        '''Arg-less action to open a new layer config dialog'''        
        dest,lgval,uconf,_,_,_,_,_ = self.controls.readParameters()
        
        if not LU.assessNone(dest):
            self.controls.setStatus(self.controls.STATUS.IDLE,'Cannot open Layer-Config without defined Destination')
            return
            
        if self.confconn is None:
            #build a new confconn
            self.confconn = ConfigConnector(uconf,lgval,dest)
        else:
            #if any parameters have changed, re-initialise
            self.confconn.initConnections(uconf,lgval,dest)
            
        self.runLayerConfigDialog()
        
    def runLayerConfigDialog(self):
        '''Layer Config dialog opener'''
        ldscs = LayerConfigSelector(self)
        ldscs.show()
        
    def closeEvent(self, event, bypass=False):
        '''Close confirmation dialog'''
        reply = QMessageBox.question(self, 'Message', "Are you sure you want to quit?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No)

        if reply == QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()
            
    def errorEvent(self,msg):
        '''Display error message and close'''
        ldslog.error(msg)
        popup = QMessageBox.critical(self, 'Error',msg, QMessageBox.Close)
        self.close()
        
    def alertEvent(self,msg):
        '''Display message and continue'''
        ldslog.error(msg)
        popup = QMessageBox.warning(self, 'Attention',msg, QMessageBox.Ok)
Beispiel #7
0
 def setUp(self):
     testlog.debug('ConfigConnector_Test.setUp')
     self.configconnector = ConfigConnector(None,self.UCONF,self.LGVAL,self.DESTNAME)    
     self.sep,self.dep = self._fetchEPs()
     self.configconnector.reg.setupLayerConfig(self.configconnector.tp,self.sep,self.dep)
Beispiel #8
0
class LDSMain(QMainWindow):
    '''This file (GUI functionality) has not been tested in any meaningful way and is likely to break on unexpected input'''

    HELPFILE = os.path.abspath(os.path.join(os.path.dirname(__file__),'../../doc/README'))
    #            destname,lgval,uc, epsg, fd,td
    DEF_RVALS = ('',      '',   '','2193','','')
    
    MAX_WIZARD_ATTEMPTS = 2
    
    DUMMY_CONF = '_deleteme'
    
    WGEO = (300, 300, 350, 250)
    
    def __init__(self,initlc=False):        ####INITLC FOR TRACING ONLY DELETE IN PRODUCTION
        super(LDSMain, self).__init__()
        
        self.layers = None
        self.groups = None
        self.gpr = None
        self.gvs = None
        
        initcc = True
        #if init=False no point reading gpr vals
        wcount = 0
        while initcc and wcount<self.MAX_WIZARD_ATTEMPTS:
            try:
                self.initConfigConnector(initlc=initlc)
                initcc = False
                break
            except MalformedConnectionString as mcse:
                ldslog.warn('Connection String malformed or missing. '+str(mcse))
                self.runWizardDialog(None,None)
                wcount += 1
            except DriverInitialisationException as die:
                ldslog.warn('Cannot Initialise selected driver. '+str(die))
                self.runWizardDialog(None,None)
                wcount += 1
                #self.initConfigConnector(self.DEF_RVALS)
                #initcc = False
            except Exception as e:
                ldslog.error('Unhandled Exception in Config Setup. '+str(e))
                wcount += 1
        else:
            raise e

        self.setGeometry(*self.WGEO)
        self.setWindowTitle('LDS Data Replicator')
        self.setWindowIcon(QIcon(LINZ))
        
        self.statusbar = self.statusBar()
        self.statusbar.showMessage('Ready')
        
        self.controls = LDSControls(self)
        
        self.setCentralWidget(self.controls)
        
        openUCAction = QAction(QIcon(OPEN), 'Open &User Config', self)        
        openUCAction.setShortcut('Ctrl+U')
        openUCAction.setStatusTip('Open User Preferences Editor')
        openUCAction.triggered.connect(self.launchUCEditor)
        
        openLCAction = QAction(QIcon(OPEN), 'Open &Layer Config', self)        
        openLCAction.setShortcut('Ctrl+L')
        openLCAction.setStatusTip('Open Layer Config File (only applies to external LC storage)')
        openLCAction.triggered.connect(self.launchLCEditor)
        #self.enableLCEdit(openLCAction)
        
        initUCAction = QAction(QIcon(UC), 'Database &Setup Wizard', self)   
        initUCAction.setShortcut('Ctrl+S')
        initUCAction.setStatusTip('Open Database Setup Wizard')
        initUCAction.triggered.connect(self.runWizardAction)
        
        initLCAction = QAction(QIcon(LC), 'Layer &Config Editor', self)   
        initLCAction.setShortcut('Ctrl+C')
        initLCAction.setStatusTip('Open Layer Config Editor')
        initLCAction.triggered.connect(self.runLayerConfigAction)
        
        exitAction = QAction(QIcon(EXIT), '&Exit', self)        
        exitAction.setShortcut('Ctrl+E')
        exitAction.setStatusTip('Exit Application')
        exitAction.triggered.connect(self.close)#qApp.quit)
        
        helpAction = QAction(QIcon(HELP), '&Help', self)        
        helpAction.setShortcut('Ctrl+H')
        helpAction.setStatusTip('Open Help Document')
        helpAction.triggered.connect(self.launchHelpFile)
        
        self.menubar = self.menuBar()

        fileMenu = self.menubar.addMenu('&File')
        fileMenu.addAction(openUCAction)
        fileMenu.addAction(openLCAction)
        fileMenu.addSeparator()
        fileMenu.addAction(initUCAction)
        fileMenu.addAction(initLCAction)
        fileMenu.addSeparator()
        fileMenu.addAction(exitAction)

        helpMenu = self.menubar.addMenu('&Help')
        helpMenu.addAction(helpAction)

    def updateFromGPR(self):
        '''Read GPR file for changes or init'''
        if not self.gpr: 
            self.gpr = GUIPrefsReader()
        return [x if LU.assessNone(x) else y for x,y in zip(self.gpr.read(),self.DEF_RVALS)]
        
    def initConfigConnector(self,gvs=None,initlc=None):
        '''Try to initialise the configconnector object'''
        self.gvs = gvs if gvs else self.updateFromGPR()
        try:
            uc = self.gvs[2]
            dst = self.gvs[0]
            self.confconn = ConfigConnector(self,uc,self.gvs[1],dst,initlc)
        except RuntimeError as rer:
            msg = 'Runtime error creating {} using "{}.conf" config file. {}'.format(self.gvs[0],uc,rer)
            self.errorEvent(msg)
        except UnicodeEncodeError as uee:
            msg = 'Unicode Encode Error, encode/sanitise input and try again. {}'.format(uee)
            self.errorEvent(msg)
            raise
        except UnicodeDecodeError as ude:
            msg = 'Unicode Decode Error, stored unicode value not being presented correctly. {}'.format(ude)
            #self.errorEvent(msg)
            raise
        except DatasourceCreateException as dce:
            msg = 'Cannot DS CREATE {} connection using "{}.conf" config file. Switching selected config and retrying. Please edit config or set new datasource; {}'.format(dst,uc,dce)
            self.switchDSSelection(dst)
            self.errorEvent(msg)
        except DatasourceOpenException as doe:
            msg = 'Cannot DS OPEN {} connection using "{}.conf" config file. Switching selected config and retrying. Please edit config or set new datasource; {}'.format(dst,uc,doe)
            self.switchDSSelection(dst)
            self.errorEvent(msg)
        except EndpointConnectionException as ece:
            msg = 'Cannot open {} connection using "{}.conf" config file. Internal error; {}'.format(dst,uc,ece)
            self.alertEvent(msg)    
            self.runWizardDialog(uc if uc else self.DUMMY_CONF,dst)
            os.remove(os.path.abspath(os.path.join(os.path.dirname(__file__),'../conf/',self.DUMMY_CONF+'.conf')))
        except ConnectionConfigurationException as cce:
            msg = 'Cannot open {} connection; {}'.format(dst,cce)
            self.alertEvent(msg)   
            self.runWizardDialog(uc if uc else self.DUMMY_CONF,dst)
            os.remove(os.path.abspath(os.path.join(os.path.dirname(__file__),'../conf/',self.DUMMY_CONF+'.conf')))
                

    def switchDSSelection(self,disconnected):
        #check next best configured DS configs
        trythis = [DataStore.DRIVER_NAMES[i] for i in ('fg','sl','pg','ms') 
                   if DataStore.DRIVER_NAMES[i] in self.gpr.getDestinations() 
                   and DataStore.DRIVER_NAMES[i] != disconnected][0]
        self.gpr.writesecline('prefs', 'dest', trythis)
        
    def enableLCEdit(self,control):
        '''Enable User Config read control for external configs'''
        dep = self.confconn.reg.openEndPoint(self.confconn.destname,self.confconn.uconf)
        control.setEnabled(dep.confwrap.readDSProperty(self.confconn.destname,'config')=='external')
        self.confconn.reg.closeEndPoint(self.confconn.destname)
        dep = None
        
    def launchUCEditor(self, checked=None):
        '''User Config Editor launch'''
        fn = LU.standardiseUserConfigName(str(self.controls.cflist[self.controls.confcombo.currentIndex()]))
        prefs = LDSPrefsEditor(fn,self)
        prefs.setWindowTitle('LDS Preferences Editor (User Config)')
        prefs.show()    
        
    def launchLCEditor(self, checked=None):
        '''Layer Config Editor launch'''
        fn = LU.standardiseLayerConfigName(str(self.controls.destlist[self.controls.destcombo.currentIndex()]))
        prefs = LDSPrefsEditor(fn,self)
        prefs.setWindowTitle('LDS Preferences Editor (Layer Config)')
        prefs.show()
        
    def launchHelpFile(self):
        if os.name == 'nt':
            #windows
            from lds.WinUtilities import WinUtilities
            WinUtilities.callStartFile(self.HELPFILE)
        elif os.name == 'posix':
            #posix
            subprocess.Popen(['xdg-open', self.HELPFILE])

        
    def runWizardAction(self):
        '''Init and run the User Config setup wizz'''
        self.controls.setStatus(self.controls.STATUS.BUSY,'Opening User-Config Wizard')  
        #rather than readparams
        uconf = self.controls.confcombo.itemText(self.controls.confcombo.currentIndex())
        secname = self.controls.destcombo.itemText(self.controls.destcombo.currentIndex())
        self.statusbar.showMessage('Editing User-Config')
        self.runWizardDialog(uconf, secname)
        #update the gui with new dest data
        self.initConfigConnector()
        self.controls.updateGUIValues(self.gvs)

        
    def runWizardDialog(self,uconf,secname):
        '''User Config/Wizz dialog opener'''
        from lds.gui.MainConfigWizard import LDSConfigWizard
        ldscw = LDSConfigWizard(uconf,secname,self)
        ldscw.exec_()
        ldscw = None
        
    
    def runLayerConfigAction(self):
        '''Arg-less action to open a new layer config dialog'''        
        dest,lgval,uconf,_,_,_,_,_ = self.controls.readParameters()
        
        if not LU.assessNone(dest):
            self.controls.setStatus(self.controls.STATUS.IDLE,'Cannot open Layer-Config without defined Destination')
            return
            
        if self.confconn is None:
            #build a new confconn
            self.confconn = ConfigConnector(uconf,lgval,dest)
        else:
            #if any parameters have changed, re-initialise
            self.confconn.initConnections(uconf,lgval,dest)
            
        self.runLayerConfigDialog()
        
    def runLayerConfigDialog(self):
        '''Layer Config dialog opener'''
        ldscs = LayerConfigSelector(self)
        ldscs.show()
        
    def closeEvent(self, event, bypass=False):
        '''Close confirmation dialog'''
        reply = QMessageBox.question(self, 'Message', "Are you sure you want to quit?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No)

        if reply == QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()
            
    def errorEvent(self,msg):
        '''Display error message and close'''
        ldslog.error(msg)
        popup = QMessageBox.critical(self, 'Error',msg, QMessageBox.Close)
        self.close()
        
    def alertEvent(self,msg):
        '''Display message and continue'''
        ldslog.error(msg)
        popup = QMessageBox.warning(self, 'Attention',msg, QMessageBox.Ok)