Changeset 2320

Show
Ignore:
Timestamp:
03/09/10 09:34:10 (5 months ago)
Author:
fma
Message:

Applied patch for Download tab and Exposure bias param

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/papywizard/plugins/gphotoBracketPlugins.py

    r2319 r2320  
    5151@copyright: (C) 2007-2010 Frédéric Mantegazza 
    5252@license: CeCILL 
    53  
    54 @todo: use a exposure bias instead of advanced params 
    5553""" 
    5654 
     
    5957import time 
    6058import subprocess 
     59import os.path 
    6160 
    6261from PyQt4 import QtCore, QtGui 
     
    6665from papywizard.plugins.abstractShutterPlugin import AbstractShutterPlugin 
    6766from papywizard.plugins.shutterPluginController import ShutterPluginController 
    68 from papywizard.view.pluginFields import LineEditField, SpinBoxField, DoubleSpinBoxField, \ 
    69                                          CheckBoxField, FileSelectorField 
     67from papywizard.view.pluginFields import LineEditField, SpinBoxField, DirSelectorField, \ 
     68                                         CheckBoxField, FileSelectorField, ComboBoxField 
    7069 
    7170NAME = "Gphoto Bracket" 
     
    7372DEFAULT_MIRROR_LOCKUP = False 
    7473DEFAULT_MIRROR_LOCKUP_COMMAND = "gphoto2 --capture-image" 
    75 DEFAULT_SHOOT_COMMAND = "gphoto2" 
     74DEFAULT_GPHOTO_COMMAND = "gphoto2" 
    7675DEFAULT_BRACKETING_NBPICTS = 1 
    7776DEFAULT_BRACKETING_STEP = 1. 
    7877 
    79 LABEL_SHOOT_COMMAND = QtGui.QApplication.translate("gphotoBracketPlugins", "Shoot command") 
    80 LABEL_CHOOSE_SHOOT_COMMAND = QtGui.QApplication.translate("gphotoBracketPlugins", "Choose shoot command...")  # or "Select gphoto2 path"? 
    81 LABEL_CHOOSE_SHOOT_COMMAND_FILTER = QtGui.QApplication.translate("gphotoBracketPlugins", "All files (*)") 
     78LABEL_GPHOTO_COMMAND = QtGui.QApplication.translate("gphotoBracketPlugins", "gPhoto command") 
     79TEXT_CHOOSE_GPHOTO_COMMAND = QtGui.QApplication.translate("gphotoBracketPlugins", "Choose gphoto2 command...")  # or "Select gphoto2 path"? 
     80TEXT_CHOOSE_GPHOTO_COMMAND_FILTER = QtGui.QApplication.translate("gphotoBracketPlugins", "gphoto2 (gphoto2);;All files (*)") 
    8281LABEL_NB_PICTS = QtGui.QApplication.translate("gphotoBracketPlugins", "Bracketing nb picts") 
    8382LABEL_EV_STEP = QtGui.QApplication.translate("gphotoBracketPlugins", "Ev step") 
     83LABEL_EV_BIAS = QtGui.QApplication.translate("gphotoBracketPlugins", "Exposure bias") 
    8484LABEL_EV_LIST = QtGui.QApplication.translate("gphotoBracketPlugins", "Resulting Ev list") 
    8585LABEL_ADVANCED = QtGui.QApplication.translate("gphotoBracketPlugins", "Advanced") 
     86 
    8687LABEL_ADVANCED_TAB = QtGui.QApplication.translate("gphotoBracketPlugins", 'Advanced') 
    8788LABEL_PLUS_NB_PICTS = QtGui.QApplication.translate("gphotoBracketPlugins", "+ bracketing nb picts") 
     
    9091LABEL_MINUS_STEP = QtGui.QApplication.translate("gphotoBracketPlugins", "- step") 
    9192 
     93LABEL_DOWNLOAD_TAB = QtGui.QApplication.translate("gphotoBracketPlugins", 'Download') 
     94LABEL_DOWNLOAD_ENABLED = QtGui.QApplication.translate("gphotoBracketPlugins", 'Download') 
     95LABEL_DOWNLOAD_DIR = QtGui.QApplication.translate("gphotoBracketPlugins", "Download directory") 
     96#LABEL_DOWNLOAD_FILENAME = QtGui.QApplication.translate("gphotoBracketPlugins", "File name") 
     97#DEFAULT_DOWNLOAD_FILENAME = QtGui.QApplication.translate("gphotoBracketPlugins", "Use camera default") 
     98LABEL_DOWNLOAD_WHEN = QtGui.QApplication.translate("gphotoBracketPlugins", "Download when") 
     99TEXT_AFTER_EACH_SHOT = QtGui.QApplication.translate("gphotoBracketPlugins", "After each shot") 
     100TEXT_AFTER_BRACKETING = QtGui.QApplication.translate("gphotoBracketPlugins", "Bracketing is finished") 
     101LABEL_DOWNLOAD_THEN_DELETE = QtGui.QApplication.translate("gphotoBracketPlugins", "Delete downloaded picts from camera") 
    92102 
    93103class GphotoBracketShutter(AbstractShutterPlugin): 
     
    100110        self.__baseSpeedIndex = None 
    101111        self.__evSteps = None 
     112        self.__lastPictIndex = None 
    102113 
    103114    def _getTimeValue(self): 
     
    115126        self._addConfigKey('_mirrorLockup', 'MIRROR_LOCKUP', default=DEFAULT_MIRROR_LOCKUP) 
    116127        self._addConfigKey('_mirrorLockupCommand', 'MIRROR_LOCKUP_COMMAND', default=DEFAULT_MIRROR_LOCKUP_COMMAND) 
    117         self._addConfigKey('_shootCommand', 'SHOOT_COMMAND', default=DEFAULT_SHOOT_COMMAND) 
     128        self._addConfigKey('_gphotoCommand', 'GPHOTO_COMMAND', default=DEFAULT_GPHOTO_COMMAND) 
    118129        self._addConfigKey('_bracketingNbPicts', 'BRACKETING_NB_PICTS', default=DEFAULT_BRACKETING_NBPICTS) 
    119130        self._addConfigKey('_bracketingEvStep', 'BRACKETING_EV_STEP', default=DEFAULT_BRACKETING_STEP) 
     131        self._addConfigKey('_bracketingEvBias', 'BRACKETING_EV_BIAS', default=0.0) 
    120132        self._addConfigKey('_bracketingPlusNbPicts', 'BRACKETING_PLUS_NB_PICTS', default=int(DEFAULT_BRACKETING_NBPICTS / 2)) 
    121133        self._addConfigKey('_bracketingMinusNbPicts', 'BRACKETING_MINUS_NB_PICTS', default=int(DEFAULT_BRACKETING_NBPICTS / 2)) 
     
    124136        self._addConfigKey('_bracketingEvList', 'BRACKETING_EV_LIST', default="0") 
    125137        self._addConfigKey('_bracketingAdvanced', 'BRACKETING_ADVANCED', default=False) 
    126  
    127     def __getEvOffset(self, bracketNumber): 
    128  
    129         # bracketNumber out of self._config['BRACKETING_NB_PICTS'] 
    130         plusNbPicts = int(self._config['BRACKETING_PLUS_NB_PICTS']) 
    131         minusNbPicts = int(self._config['BRACKETING_MINUS_NB_PICTS']) 
    132         plusStep = self._config['BRACKETING_PLUS_STEP'] 
    133         minusStep = self._config['BRACKETING_MINUS_STEP'] 
    134  
    135         if bracketNumber <= minusNbPicts: # 1,2...minusNbPicts 
    136             return (bracketNumber - minusNbPicts - 1) * minusStep 
    137         elif bracketNumber >= (minusNbPicts + 2): # minusNbPicts + 2, +3... (minusNbPicts+plusNbPicts+1) 
    138             return (bracketNumber - minusNbPicts - 1) * plusStep 
    139         else: 
    140             return 0 
     138        self._addConfigKey('_downloadEnabled', 'DOWNLOAD_ENABLED', default=False) 
     139        self._addConfigKey('_downloadDir', 'DOWNLOAD_DIR', default="") 
     140        #self._addConfigKey('_downloadFilename', 'DOWNLOAD_FILENAME', default=DEFAULT_DOWNLOAD_FILENAME) 
     141        self._addConfigKey('_downloadWhen', 'DOWNLOAD_WHEN', default='') 
     142        self._addConfigKey('_downloadThenDelete', 'DOWNLOAD_THEN_DELETE', default=False) 
    141143 
    142144    def lockupMirror(self): 
     
    151153        """ @todo: Move all this in futur start() callback? 
    152154        """ 
    153  
    154155        # List config 
    155         args = [self._config['SHOOT_COMMAND']] 
     156        args = [self._config['GPHOTO_COMMAND']] 
    156157        args.append("--list-config") 
    157158        Logger().debug("GphotoBracketShutter.init(): execute command '%s'..." % ' '.join(args)) 
    158         p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
     159        p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env={ "LANG": "C" }) 
    159160 
    160161        # Wait end of execution 
    161162        stdout, stderr = p.communicate() 
    162         if p.returncode != 0 and stderr: 
     163        if p.returncode != 0: 
    163164            Logger().error("GphotoBracketShutter.init(): stderr:\n%s" % stderr.strip()) 
     165        else: 
     166            Logger().info("GphotoBracketShutter.init(): stderr:\n%s" % stderr.strip()) 
    164167        Logger().debug("GphotoBracketShutter.init(): stdout:\n%s" % stdout.strip()) 
    165168 
     
    171174 
    172175        # Get config 
    173         args = [self._config['SHOOT_COMMAND']] 
     176        args = [self._config['GPHOTO_COMMAND']] 
    174177        args.append("--get-config") 
    175178        args.append(self.__speedConfig) 
    176179        Logger().debug("GphotoBracketShutter.init(): execute command '%s'..." % ' '.join(args)) 
    177         p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
     180        p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env={ "LANG": "C" }) 
    178181 
    179182        # Wait end of execution 
    180183        stdout, stderr = p.communicate() 
    181         if p.returncode != 0 and stderr: 
     184        if p.returncode != 0: 
    182185            Logger().error("GphotoBracketShutter.init(): stderr:\n%s" % stderr.strip()) 
     186        else: 
     187            Logger().info("GphotoBracketShutter.init(): stderr:\n%s" % stderr.strip()) 
    183188        Logger().debug("GphotoBracketShutter.init(): stdout:\n%s" % stdout.strip()) 
    184189 
     
    195200 
    196201        if float(self.__availableSpeeds[1]) > float(self.__availableSpeeds[2]): 
    197             self.__speedOrder = 1.0 # slower speed first 
    198         else: 
    199             self.__speedOrder = -1.0 # faster speed first 
     202            self.__speedOrder = 1 # slower speed first 
     203        else: 
     204            self.__speedOrder = -1 # faster speed first 
    200205 
    201206        # Guess EV step (1/2, or 1/3) 
     
    205210            self.__evSteps = 2 
    206211 
    207         Logger().info("GphotoBracketShutter.init(): basespeed=%s config=%s order=%+g steps=1/%d" % \ 
     212        Logger().info("GphotoBracketShutter.init(): basespeed=%s config=%s order=%+d steps=1/%d" % \ 
    208213                      (self.__baseSpeed, self.__speedConfig, self.__speedOrder, self.__evSteps)) 
    209214 
     
    211216        Logger().debug("GphotoBracketShutter.shoot(): bracketNumber=%d" % bracketNumber) 
    212217 
    213         evOffset = self.__getEvOffset(bracketNumber) 
    214  
    215         speedIndex = self.__baseSpeedIndex - int(evOffset * self.__evSteps * self.__speedOrder) 
     218        evOffset = self._config['BRACKETING_EV_LIST'].split(",")[bracketNumber - 1].strip() 
     219 
     220        speedIndex = self.__baseSpeedIndex - int(float(evOffset) * self.__evSteps * self.__speedOrder) 
    216221 
    217222        # see if shutter speed is out of range 
     
    226231            elif speedIndex >= (len(self.__availableSpeeds) - 1): 
    227232                speedIndex = len(self.__availableSpeeds) - 2 
    228         Logger().info("GphotoBracketShutter.shoot(): EV=%+d shutter speed=%s (1/%d steps)" % \ 
    229                       (int(evOffset), self.__availableSpeeds[speedIndex], self.__evSteps)) 
     233        Logger().info("GphotoBracketShutter.shoot(): EV=%s shutter speed=%s" % \ 
     234                      (evOffset, self.__availableSpeeds[speedIndex])) 
     235 
     236        downloadEnabled = self._config['DOWNLOAD_ENABLED'] 
     237        downloadThenDelete = self._config['DOWNLOAD_THEN_DELETE'] 
     238        downloadAfterEachShot = (self._config['DOWNLOAD_WHEN'] == TEXT_AFTER_EACH_SHOT) 
     239        downloadAfterBracketing = (self._config['DOWNLOAD_WHEN'] == TEXT_AFTER_BRACKETING) 
     240        bracketingNbPicts = self._config['BRACKETING_NB_PICTS'] 
     241 
     242        # Whether to use --capture-image-and-download, or not 
     243        useCaptureImageAndDownload = downloadEnabled and downloadThenDelete and (downloadAfterEachShot or (bracketingNbPicts == 1)) 
     244 
     245        # List files in the camera 
     246        if (bracketNumber == 1) and downloadEnabled and not useCaptureImageAndDownload: 
     247            args = [self._config['GPHOTO_COMMAND']] 
     248            args.append("--list-files") 
     249            Logger().debug("GphotoBracketShutter.shoot(): execute command '%s'..." % ' '.join(args)) 
     250            p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env={ "LANG": "C" }) 
     251 
     252            # Wait end of execution 
     253            stdout, stderr = p.communicate() 
     254            if p.returncode != 0: 
     255                Logger().error("GphotoBracketShutter.shoot(): stderr:\n%s" % stderr.strip()) 
     256                return p.returncode 
     257            else: 
     258                Logger().info("GphotoBracketShutter.shoot(): stderr:\n%s" % stderr.strip()) 
     259            Logger().debug("GphotoBracketShutter.shoot(): stdout:\n%s" % stdout.strip()) 
     260 
     261            poundIndex = stdout.rfind('#') 
     262            if poundIndex == -1: 
     263                self.__lastPictIndex = 0 
     264            else: 
     265                self.__lastPictIndex = int(stdout[poundIndex + 1 : stdout.find(' ', poundIndex)]) 
     266 
     267            Logger().info("GphotoBracketShutter.shoot(): last file # in the camera is #%d" % self.__lastPictIndex) 
    230268 
    231269        # Capture image 
    232         args = [self._config['SHOOT_COMMAND']] 
     270        args = [self._config['GPHOTO_COMMAND']] 
    233271        args.append("--set-config") 
    234272        args.append("%s=%s" % (self.__speedConfig, self.__availableSpeeds[speedIndex])) 
    235         args.append("--capture-image") 
     273 
     274        if useCaptureImageAndDownload: 
     275            args.append("--capture-image-and-download") 
     276            args.append("--filename") 
     277            args.append(os.path.join(self._config['DOWNLOAD_DIR'], "%f.%C")) 
     278            args.append("--force-overwrite") 
     279        else: 
     280            args.append("--capture-image") 
     281 
    236282        args.append("--set-config") 
    237283        args.append("%s=%s" % (self.__speedConfig, self.__baseSpeed)) 
     
    240286 
    241287        if True:  # Set to False for tests 
    242             p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
     288            p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env={ "LANG": "C" }) 
    243289 
    244290            # Wait end of execution 
    245291            stdout, stderr = p.communicate() 
    246             if p.returncode != 0 and stderr: 
     292            if p.returncode != 0: 
    247293                Logger().error("GphotoBracketShutter.shoot(): stderr:\n%s" % stderr.strip()) 
     294                return p.returncode 
     295            else: 
     296                Logger().info("GphotoBracketShutter.shoot(): stderr:\n%s" % stderr.strip()) 
    248297            Logger().debug("GphotoBracketShutter.shoot(): stdout:\n%s" % stdout.strip()) 
    249298 
    250             return p.returncode 
    251         else: 
    252             return 0 
    253  
     299            # Download files 
     300            if downloadEnabled and not useCaptureImageAndDownload and not (downloadAfterBracketing and (bracketNumber < bracketingNbPicts)): 
     301                args = [self._config['GPHOTO_COMMAND']] 
     302                args.append("--get-file") 
     303                if downloadAfterEachShot: 
     304                    if downloadThenDelete: 
     305                        args.append("%d" % (self.__lastPictIndex + 1)) 
     306                    else: 
     307                        args.append("%d" % (self.__lastPictIndex + bracketNumber)) 
     308                else: 
     309                    args.append("%d-%d" % (self.__lastPictIndex + 1, self.__lastPictIndex + bracketNumber)) 
     310                args.append("--filename") 
     311                args.append(os.path.join(self._config['DOWNLOAD_DIR'], "%f.%C")) 
     312                args.append("--force-overwrite") 
     313                if downloadThenDelete: 
     314                    args.append("--delete-file") 
     315                    if downloadAfterEachShot: 
     316                        args.append("%d" % (self.__lastPictIndex + 1)) 
     317                    else: 
     318                        args.append("%d-%d" % (self.__lastPictIndex + 1, self.__lastPictIndex + bracketNumber)) 
     319                args.append("--recurse") 
     320                Logger().debug("GphotoBracketShutter.shoot(): execute command '%s'..." % ' '.join(args)) 
     321                p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env={ "LANG": "C" }) 
     322 
     323                # Wait end of execution 
     324                stdout, stderr = p.communicate() 
     325                if p.returncode != 0: 
     326                    Logger().error("GphotoBracketShutter.shoot(): stderr:\n%s" % stderr.strip()) 
     327                    return p.returncode 
     328                else: 
     329                    Logger().info("GphotoBracketShutter.shoot(): stderr:\n%s" % stderr.strip()) 
     330                Logger().debug("GphotoBracketShutter.shoot(): stdout:\n%s" % stdout.strip()) 
     331 
     332        return 0 
    254333 
    255334class GphotoBracketShutterController(ShutterPluginController): 
     
    270349        plusStep = int(self._getWidget('Advanced', LABEL_PLUS_STEP).value()) 
    271350        minusStep = int(self._getWidget('Advanced', LABEL_MINUS_STEP).value()) 
     351        evBias = int(self._getWidget('Main', LABEL_EV_BIAS).value()) 
    272352        self._getWidget('Main', LABEL_NB_PICTS).setValue(1 + plusNbPicts + minusNbPicts) 
    273353 
     
    275355        if minusNbPicts > 0: 
    276356            for i in range(-minusNbPicts, 0): 
    277                 evList.append("%+g" % (i * minusStep)) 
    278         evList.append("0") 
     357                evList.append("%s" % formatEv(i * minusStep + evBias)) 
     358        evList.append("%s" % formatEv(evBias)) 
    279359        if plusNbPicts > 0: 
    280             for i in range(1, plusNbPicts + 1): 
    281                 evList.append("%+g" % (i * plusStep)) 
     360            for i in range(1, plusNbPicts+1): 
     361                evList.append("%s" % formatEv(i * plusStep + evBias)) 
    282362 
    283363        self._getWidget('Main', LABEL_EV_LIST).setValue(", ".join(evList)) 
     
    289369        Logger().trace("GphotoBracketShutterController._defineGui()") 
    290370        ShutterPluginController._defineGui(self) 
     371 
     372        self._view.tabWidget.setUsesScrollButtons(False) 
    291373 
    292374        # Main tab 
     
    298380                         #QtGui.QApplication.translate("gphotoBracketPlugins", "All files (*)")), 
    299381                        #'MIRROR_LOCKUP_COMMAND') 
    300         self._addWidget('Main', LABEL_SHOOT_COMMAND, 
    301                         FileSelectorField, (LABEL_CHOOSE_SHOOT_COMMAND, LABEL_CHOOSE_SHOOT_COMMAND_FILTER), 
    302                         'SHOOT_COMMAND') 
     382        self._addWidget('Main', LABEL_GPHOTO_COMMAND, 
     383                        FileSelectorField, (TEXT_CHOOSE_GPHOTO_COMMAND, TEXT_CHOOSE_GPHOTO_COMMAND_FILTER), 
     384                        'GPHOTO_COMMAND') 
    303385        self._addWidget('Main', LABEL_NB_PICTS, SpinBoxField, (1, 11), 'BRACKETING_NB_PICTS') 
    304386        self._getWidget('Main', LABEL_NB_PICTS).setSingleStep(2) 
    305         self._addWidget('Main', LABEL_EV_STEP, DoubleSpinBoxField, (1.0, 5.0, 1, 1., "", " ev"), 'BRACKETING_EV_STEP') 
     387        self._addWidget('Main', LABEL_EV_STEP, SpinBoxField, (1, 5, "", " ev"), 'BRACKETING_EV_STEP') 
    306388        self._addWidget('Main', LABEL_EV_LIST, LineEditField, (), 'BRACKETING_EV_LIST') 
    307389        self._getWidget('Main', LABEL_EV_LIST).setReadOnly(True) 
     390        self._addWidget('Main', LABEL_EV_BIAS, SpinBoxField, (-5, 5, " ", " ev"), 'BRACKETING_EV_BIAS') 
    308391        self._addWidget('Main', LABEL_ADVANCED, CheckBoxField, (), 'BRACKETING_ADVANCED') 
     392        self._addWidget('Main', LABEL_DOWNLOAD_ENABLED, CheckBoxField, (), 'DOWNLOAD_ENABLED') 
    309393 
    310394        # Advanced tab 
    311395        self._addTab('Advanced', LABEL_ADVANCED_TAB) 
    312396        self._addWidget('Advanced', LABEL_PLUS_NB_PICTS, SpinBoxField, (0, 11), 'BRACKETING_PLUS_NB_PICTS') 
    313         self._addWidget('Advanced', LABEL_PLUS_STEP, DoubleSpinBoxField, (1.0, 5.0, 1, 1., "", " ev"), 'BRACKETING_PLUS_STEP') 
     397        self._addWidget('Advanced', LABEL_PLUS_STEP, SpinBoxField, (0, 5, "", " ev"), 'BRACKETING_PLUS_STEP') 
    314398        self._addWidget('Advanced', LABEL_MINUS_NB_PICTS, SpinBoxField, (0, 11), 'BRACKETING_MINUS_NB_PICTS') 
    315         self._addWidget('Advanced', LABEL_MINUS_STEP, DoubleSpinBoxField, (1.0, 5.0, 1, 1., "", " ev"), 'BRACKETING_MINUS_STEP') 
     399        self._addWidget('Advanced', LABEL_MINUS_STEP, SpinBoxField, (0, 5, "", " ev"), 'BRACKETING_MINUS_STEP') 
    316400        self._addWidget('Advanced', LABEL_EV_LIST, LineEditField, (), 'BRACKETING_EV_LIST') 
    317401        self._getWidget('Advanced', LABEL_EV_LIST).setReadOnly(True) 
     402        self._addWidget('Advanced', LABEL_EV_BIAS, SpinBoxField, (-5, 5, " ", " ev"), 'BRACKETING_EV_BIAS') 
     403 
     404        # Download tab 
     405        self._addTab('Download', LABEL_DOWNLOAD_TAB) 
     406        self._addWidget('Download', LABEL_DOWNLOAD_DIR, 
     407                        DirSelectorField, 
     408                        (QtGui.QApplication.translate("gphotoBracketPlugins", "Choose download directory..."),), 
     409                        'DOWNLOAD_DIR') 
     410        #filenamePatterns = [ DEFAULT_DOWNLOAD_FILENAME, "%Y-%m-%d_%Hh%Mm%Ss" ] 
     411        #self._addWidget('Download', LABEL_DOWNLOAD_FILENAME, ComboBoxField, (filenamePatterns, ), 'DOWNLOAD_FILENAME') 
     412        downloadWhen = [ TEXT_AFTER_EACH_SHOT, TEXT_AFTER_BRACKETING ] 
     413        self._addWidget('Download', LABEL_DOWNLOAD_WHEN, ComboBoxField, (downloadWhen, ), 'DOWNLOAD_WHEN') 
     414        self._addWidget('Download', LABEL_DOWNLOAD_THEN_DELETE, CheckBoxField, (), 'DOWNLOAD_THEN_DELETE') 
    318415 
    319416    def refreshView(self): 
     
    323420        self._setTabEnabled('Advanced', advanced) 
    324421 
     422        self._getWidget('Main', LABEL_EV_STEP).setDisabled(advanced or (self._getWidget('Main', LABEL_NB_PICTS).value() <= 1)) 
     423 
     424        # refresh Ev Bias 
     425        self._getWidget('Main', LABEL_EV_BIAS).setDisabled(advanced) 
     426        self._getWidget('Advanced', LABEL_EV_BIAS).setDisabled(not advanced) 
     427        if advanced: 
     428            evBias = self._getWidget('Advanced', LABEL_EV_BIAS).value() 
     429            self._getWidget('Main', LABEL_EV_BIAS).setValue(evBias) 
     430        else: 
     431            evBias = self._getWidget('Main', LABEL_EV_BIAS).value() 
     432            self._getWidget('Advanced', LABEL_EV_BIAS).setValue(evBias) 
     433        if evBias > 0: 
     434            self._getWidget('Main', LABEL_EV_BIAS).setPrefix("+") 
     435            self._getWidget('Advanced', LABEL_EV_BIAS).setPrefix("+") 
     436        else: 
     437            self._getWidget('Main', LABEL_EV_BIAS).setPrefix(" ") 
     438            self._getWidget('Advanced', LABEL_EV_BIAS).setPrefix(" ") 
     439 
     440        download = self._getWidget('Main', LABEL_DOWNLOAD_ENABLED).value() 
     441        self._setTabEnabled('Download', download) 
     442 
     443def formatEv(ev): 
     444    ev = round(ev,1) 
     445    if ev == 0: 
     446        return "0" 
     447    else: 
     448        return "%+g" % ev 
    325449 
    326450def register():