Changeset 2320
- Timestamp:
- 03/09/10 09:34:10 (5 months ago)
- Files:
-
- 1 modified
-
trunk/papywizard/plugins/gphotoBracketPlugins.py (modified) (20 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/papywizard/plugins/gphotoBracketPlugins.py
r2319 r2320 51 51 @copyright: (C) 2007-2010 Frédéric Mantegazza 52 52 @license: CeCILL 53 54 @todo: use a exposure bias instead of advanced params55 53 """ 56 54 … … 59 57 import time 60 58 import subprocess 59 import os.path 61 60 62 61 from PyQt4 import QtCore, QtGui … … 66 65 from papywizard.plugins.abstractShutterPlugin import AbstractShutterPlugin 67 66 from papywizard.plugins.shutterPluginController import ShutterPluginController 68 from papywizard.view.pluginFields import LineEditField, SpinBoxField, D oubleSpinBoxField, \69 CheckBoxField, FileSelectorField 67 from papywizard.view.pluginFields import LineEditField, SpinBoxField, DirSelectorField, \ 68 CheckBoxField, FileSelectorField, ComboBoxField 70 69 71 70 NAME = "Gphoto Bracket" … … 73 72 DEFAULT_MIRROR_LOCKUP = False 74 73 DEFAULT_MIRROR_LOCKUP_COMMAND = "gphoto2 --capture-image" 75 DEFAULT_ SHOOT_COMMAND = "gphoto2"74 DEFAULT_GPHOTO_COMMAND = "gphoto2" 76 75 DEFAULT_BRACKETING_NBPICTS = 1 77 76 DEFAULT_BRACKETING_STEP = 1. 78 77 79 LABEL_ SHOOT_COMMAND = QtGui.QApplication.translate("gphotoBracketPlugins", "Shootcommand")80 LABEL_CHOOSE_SHOOT_COMMAND = QtGui.QApplication.translate("gphotoBracketPlugins", "Choose shootcommand...") # or "Select gphoto2 path"?81 LABEL_CHOOSE_SHOOT_COMMAND_FILTER = QtGui.QApplication.translate("gphotoBracketPlugins", "All files (*)")78 LABEL_GPHOTO_COMMAND = QtGui.QApplication.translate("gphotoBracketPlugins", "gPhoto command") 79 TEXT_CHOOSE_GPHOTO_COMMAND = QtGui.QApplication.translate("gphotoBracketPlugins", "Choose gphoto2 command...") # or "Select gphoto2 path"? 80 TEXT_CHOOSE_GPHOTO_COMMAND_FILTER = QtGui.QApplication.translate("gphotoBracketPlugins", "gphoto2 (gphoto2);;All files (*)") 82 81 LABEL_NB_PICTS = QtGui.QApplication.translate("gphotoBracketPlugins", "Bracketing nb picts") 83 82 LABEL_EV_STEP = QtGui.QApplication.translate("gphotoBracketPlugins", "Ev step") 83 LABEL_EV_BIAS = QtGui.QApplication.translate("gphotoBracketPlugins", "Exposure bias") 84 84 LABEL_EV_LIST = QtGui.QApplication.translate("gphotoBracketPlugins", "Resulting Ev list") 85 85 LABEL_ADVANCED = QtGui.QApplication.translate("gphotoBracketPlugins", "Advanced") 86 86 87 LABEL_ADVANCED_TAB = QtGui.QApplication.translate("gphotoBracketPlugins", 'Advanced') 87 88 LABEL_PLUS_NB_PICTS = QtGui.QApplication.translate("gphotoBracketPlugins", "+ bracketing nb picts") … … 90 91 LABEL_MINUS_STEP = QtGui.QApplication.translate("gphotoBracketPlugins", "- step") 91 92 93 LABEL_DOWNLOAD_TAB = QtGui.QApplication.translate("gphotoBracketPlugins", 'Download') 94 LABEL_DOWNLOAD_ENABLED = QtGui.QApplication.translate("gphotoBracketPlugins", 'Download') 95 LABEL_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") 98 LABEL_DOWNLOAD_WHEN = QtGui.QApplication.translate("gphotoBracketPlugins", "Download when") 99 TEXT_AFTER_EACH_SHOT = QtGui.QApplication.translate("gphotoBracketPlugins", "After each shot") 100 TEXT_AFTER_BRACKETING = QtGui.QApplication.translate("gphotoBracketPlugins", "Bracketing is finished") 101 LABEL_DOWNLOAD_THEN_DELETE = QtGui.QApplication.translate("gphotoBracketPlugins", "Delete downloaded picts from camera") 92 102 93 103 class GphotoBracketShutter(AbstractShutterPlugin): … … 100 110 self.__baseSpeedIndex = None 101 111 self.__evSteps = None 112 self.__lastPictIndex = None 102 113 103 114 def _getTimeValue(self): … … 115 126 self._addConfigKey('_mirrorLockup', 'MIRROR_LOCKUP', default=DEFAULT_MIRROR_LOCKUP) 116 127 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) 118 129 self._addConfigKey('_bracketingNbPicts', 'BRACKETING_NB_PICTS', default=DEFAULT_BRACKETING_NBPICTS) 119 130 self._addConfigKey('_bracketingEvStep', 'BRACKETING_EV_STEP', default=DEFAULT_BRACKETING_STEP) 131 self._addConfigKey('_bracketingEvBias', 'BRACKETING_EV_BIAS', default=0.0) 120 132 self._addConfigKey('_bracketingPlusNbPicts', 'BRACKETING_PLUS_NB_PICTS', default=int(DEFAULT_BRACKETING_NBPICTS / 2)) 121 133 self._addConfigKey('_bracketingMinusNbPicts', 'BRACKETING_MINUS_NB_PICTS', default=int(DEFAULT_BRACKETING_NBPICTS / 2)) … … 124 136 self._addConfigKey('_bracketingEvList', 'BRACKETING_EV_LIST', default="0") 125 137 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) 141 143 142 144 def lockupMirror(self): … … 151 153 """ @todo: Move all this in futur start() callback? 152 154 """ 153 154 155 # List config 155 args = [self._config[' SHOOT_COMMAND']]156 args = [self._config['GPHOTO_COMMAND']] 156 157 args.append("--list-config") 157 158 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" }) 159 160 160 161 # Wait end of execution 161 162 stdout, stderr = p.communicate() 162 if p.returncode != 0 and stderr:163 if p.returncode != 0: 163 164 Logger().error("GphotoBracketShutter.init(): stderr:\n%s" % stderr.strip()) 165 else: 166 Logger().info("GphotoBracketShutter.init(): stderr:\n%s" % stderr.strip()) 164 167 Logger().debug("GphotoBracketShutter.init(): stdout:\n%s" % stdout.strip()) 165 168 … … 171 174 172 175 # Get config 173 args = [self._config[' SHOOT_COMMAND']]176 args = [self._config['GPHOTO_COMMAND']] 174 177 args.append("--get-config") 175 178 args.append(self.__speedConfig) 176 179 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" }) 178 181 179 182 # Wait end of execution 180 183 stdout, stderr = p.communicate() 181 if p.returncode != 0 and stderr:184 if p.returncode != 0: 182 185 Logger().error("GphotoBracketShutter.init(): stderr:\n%s" % stderr.strip()) 186 else: 187 Logger().info("GphotoBracketShutter.init(): stderr:\n%s" % stderr.strip()) 183 188 Logger().debug("GphotoBracketShutter.init(): stdout:\n%s" % stdout.strip()) 184 189 … … 195 200 196 201 if float(self.__availableSpeeds[1]) > float(self.__availableSpeeds[2]): 197 self.__speedOrder = 1 .0# slower speed first198 else: 199 self.__speedOrder = -1 .0# faster speed first202 self.__speedOrder = 1 # slower speed first 203 else: 204 self.__speedOrder = -1 # faster speed first 200 205 201 206 # Guess EV step (1/2, or 1/3) … … 205 210 self.__evSteps = 2 206 211 207 Logger().info("GphotoBracketShutter.init(): basespeed=%s config=%s order=%+ gsteps=1/%d" % \212 Logger().info("GphotoBracketShutter.init(): basespeed=%s config=%s order=%+d steps=1/%d" % \ 208 213 (self.__baseSpeed, self.__speedConfig, self.__speedOrder, self.__evSteps)) 209 214 … … 211 216 Logger().debug("GphotoBracketShutter.shoot(): bracketNumber=%d" % bracketNumber) 212 217 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) 216 221 217 222 # see if shutter speed is out of range … … 226 231 elif speedIndex >= (len(self.__availableSpeeds) - 1): 227 232 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) 230 268 231 269 # Capture image 232 args = [self._config[' SHOOT_COMMAND']]270 args = [self._config['GPHOTO_COMMAND']] 233 271 args.append("--set-config") 234 272 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 236 282 args.append("--set-config") 237 283 args.append("%s=%s" % (self.__speedConfig, self.__baseSpeed)) … … 240 286 241 287 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" }) 243 289 244 290 # Wait end of execution 245 291 stdout, stderr = p.communicate() 246 if p.returncode != 0 and stderr:292 if p.returncode != 0: 247 293 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()) 248 297 Logger().debug("GphotoBracketShutter.shoot(): stdout:\n%s" % stdout.strip()) 249 298 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 254 333 255 334 class GphotoBracketShutterController(ShutterPluginController): … … 270 349 plusStep = int(self._getWidget('Advanced', LABEL_PLUS_STEP).value()) 271 350 minusStep = int(self._getWidget('Advanced', LABEL_MINUS_STEP).value()) 351 evBias = int(self._getWidget('Main', LABEL_EV_BIAS).value()) 272 352 self._getWidget('Main', LABEL_NB_PICTS).setValue(1 + plusNbPicts + minusNbPicts) 273 353 … … 275 355 if minusNbPicts > 0: 276 356 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)) 279 359 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)) 282 362 283 363 self._getWidget('Main', LABEL_EV_LIST).setValue(", ".join(evList)) … … 289 369 Logger().trace("GphotoBracketShutterController._defineGui()") 290 370 ShutterPluginController._defineGui(self) 371 372 self._view.tabWidget.setUsesScrollButtons(False) 291 373 292 374 # Main tab … … 298 380 #QtGui.QApplication.translate("gphotoBracketPlugins", "All files (*)")), 299 381 #'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') 303 385 self._addWidget('Main', LABEL_NB_PICTS, SpinBoxField, (1, 11), 'BRACKETING_NB_PICTS') 304 386 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') 306 388 self._addWidget('Main', LABEL_EV_LIST, LineEditField, (), 'BRACKETING_EV_LIST') 307 389 self._getWidget('Main', LABEL_EV_LIST).setReadOnly(True) 390 self._addWidget('Main', LABEL_EV_BIAS, SpinBoxField, (-5, 5, " ", " ev"), 'BRACKETING_EV_BIAS') 308 391 self._addWidget('Main', LABEL_ADVANCED, CheckBoxField, (), 'BRACKETING_ADVANCED') 392 self._addWidget('Main', LABEL_DOWNLOAD_ENABLED, CheckBoxField, (), 'DOWNLOAD_ENABLED') 309 393 310 394 # Advanced tab 311 395 self._addTab('Advanced', LABEL_ADVANCED_TAB) 312 396 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') 314 398 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') 316 400 self._addWidget('Advanced', LABEL_EV_LIST, LineEditField, (), 'BRACKETING_EV_LIST') 317 401 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') 318 415 319 416 def refreshView(self): … … 323 420 self._setTabEnabled('Advanced', advanced) 324 421 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 443 def formatEv(ev): 444 ev = round(ev,1) 445 if ev == 0: 446 return "0" 447 else: 448 return "%+g" % ev 325 449 326 450 def register():
