source: trunk/papywizard/controller/shootController.py @ 1132

Revision 1132, 26.7 KB checked in by fma, 4 years ago (diff)

Use signals for synchronisation

  • Property svn:keywords set to Id
Line 
1# -*- coding: utf-8 -*-
2
3""" Panohead remote control.
4
5License
6=======
7
8 - B{papywizard} (U{http://trac.gbiloba.org/papywizard}) is Copyright:
9  - (C) 2007-2008 Frédéric Mantegazza
10
11This software is governed by the B{CeCILL} license under French law and
12abiding by the rules of distribution of free software.  You can  use,
13modify and/or redistribute the software under the terms of the CeCILL
14license as circulated by CEA, CNRS and INRIA at the following URL
15U{http://www.cecill.info}.
16
17As a counterpart to the access to the source code and  rights to copy,
18modify and redistribute granted by the license, users are provided only
19with a limited warranty  and the software's author,  the holder of the
20economic rights,  and the successive licensors  have only  limited
21liability.
22
23In this respect, the user's attention is drawn to the risks associated
24with loading,  using,  modifying and/or developing or reproducing the
25software by the user in light of its specific status of free software,
26that may mean  that it is complicated to manipulate,  and  that  also
27therefore means  that it is reserved for developers  and  experienced
28professionals having in-depth computer knowledge. Users are therefore
29encouraged to load and test the software's suitability as regards their
30requirements in conditions enabling the security of their systems and/or
31data to be ensured and,  more generally, to use and operate it in the
32same conditions as regards security.
33
34The fact that you are presently reading this means that you have had
35knowledge of the CeCILL license and that you accept its terms.
36
37Module purpose
38==============
39
40Graphical toolkit controller
41
42Implements
43==========
44
45- ShootController
46
47@author: Frédéric Mantegazza
48@copyright: (C) 2007-2008 Frédéric Mantegazza
49@license: CeCILL
50"""
51
52__revision__ = "$Id$"
53
54import os.path
55import time
56import threading
57
58import pygtk
59pygtk.require("2.0")
60import gtk
61import gtk.gdk
62import gobject
63import pango
64
65from papywizard.common.loggingServices import Logger
66from papywizard.common.helpers import sToHmsAsStr
67from papywizard.common.configManager import ConfigManager
68from papywizard.controller.messageController import ErrorMessageController
69from papywizard.controller.abstractController import AbstractController
70from papywizard.controller.configController import ConfigController
71from papywizard.controller.spy import Spy
72from papywizard.view.shootingArea import MosaicArea, PresetArea
73
74
75class ShootController(AbstractController):
76    """ Shoot controller object.
77    """
78    def _init(self):
79        self._gladeFile = "shootDialog.glade"
80        self._signalDict = {"on_textViewTogglebutton_toggled": self.__onTextViewTogglebuttonToggled,
81                            "on_rewindButton_clicked": self.__onRewindButtonclicked,
82                            "on_forwardButton_clicked": self.__onForwardButtonclicked,
83                            "on_stepByStepCheckbutton_toggled": self.__onStepByStepCheckbuttonToggled,
84                            "on_dataFileButton_clicked": self.__onDataFileButtonclicked,
85                            "on_timerButton_clicked": self.__onTimerButtonClicked,
86                            "on_startButton_clicked": self.__onStartButtonClicked,
87                            "on_pauseResumeButton_clicked": self.__onPauseResumeButtonClicked,
88                            "on_stopButton_clicked": self.__onStopButtonClicked,
89                            "on_doneButton_clicked": self.__onDoneButtonClicked,
90                        }
91
92        self.__keyPressedDict = {'Right': False,
93                                 'Left': False,
94                                 'Up': False,
95                                 'Down': False,
96                                 'Return': False,
97                                 'Escape': False
98                             }
99        self.__key = {'Right': gtk.keysyms.Right,
100                      'Left': gtk.keysyms.Left,
101                      'Up': gtk.keysyms.Up,
102                      'Down': gtk.keysyms.Down,
103                      'Return': gtk.keysyms.Return,
104                      'Escape': gtk.keysyms.Escape
105                      }
106
107        self.__thread = None
108
109    def _retreiveWidgets(self):
110        super(ShootController, self)._retreiveWidgets()
111
112        # Load graphical shooting area
113        self.viewport = self.wTree.get_widget("viewport")
114        if self._model.mode == 'mosaic':
115            self.shootingArea = MosaicArea()
116        else:
117            self.shootingArea = PresetArea()
118        self.viewport.add(self.shootingArea)
119        self.shootingArea.show()
120       
121        # Create text shooting area
122        self.textShootingArea = gtk.VBox()
123        self.position1Label = gtk.Label()
124        self.position1Label.modify_font(pango.FontDescription("Arial 18"))
125        self.textShootingArea.pack_start(self.position1Label)
126        self.position1Label.set_text("--")
127        self.position2Label = gtk.Label()
128        self.position2Label.modify_font(pango.FontDescription("Arial 18"))
129        self.textShootingArea.pack_start(self.position2Label)
130        self.position2Label.set_text("")
131        self.repeatLabel = gtk.Label()
132        self.repeatLabel.modify_font(pango.FontDescription("Arial 18"))
133        self.repeatLabel.set_text("--")
134        self.textShootingArea.pack_start(self.repeatLabel)
135        self.textShootingArea.show_all()
136
137        self.rewindButton = self.wTree.get_widget("rewindButton")
138        self.forwardButton = self.wTree.get_widget("forwardButton")
139        self.progressbar = self.wTree.get_widget("progressbar")
140        self.stepByStepCheckbutton = self.wTree.get_widget("stepByStepCheckbutton")
141        self.dataFileButton = self.wTree.get_widget("dataFileButton")
142        self.dataFileButtonImage = self.wTree.get_widget("dataFileButtonImage")
143        self.timerButton = self.wTree.get_widget("timerButton")
144        self.timerButtonImage = self.wTree.get_widget("timerButtonImage")
145        self.startButton = self.wTree.get_widget("startButton")
146        self.pauseResumeButton = self.wTree.get_widget("pauseResumeButton")
147        self.pauseResumeLabel = self.wTree.get_widget("pauseResumeLabel")
148        self.pauseResumeImage = self.wTree.get_widget("pauseResumeImage")
149        self.stopButton = self.wTree.get_widget("stopButton")
150        self.doneButton = self.wTree.get_widget("doneButton")
151
152        # Populate shooting area with preview positions
153        if self._model.mode == 'mosaic':
154
155            # todo: give args in shootingArea.__init__()
156            self.shootingArea.init(self._model.mosaic.yawStart, self._model.mosaic.yawEnd,
157                                   self._model.mosaic.pitchStart, self._model.mosaic.pitchEnd,
158                                   self._model.mosaic.yawFov, self._model.mosaic.pitchFov,
159                                   self._model.camera.getYawFov(self._model.cameraOrientation),
160                                   self._model.camera.getPitchFov(self._model.cameraOrientation),
161                                   self._model.mosaic.yawRealOverlap, self._model.mosaic.pitchRealOverlap)
162            self._model.mosaic.generatePositions()
163            for (index, yawIndex, pitchIndex), (yaw, pitch) in self._model.mosaic.iterPositions():
164                self.shootingArea.add_pict(yaw, pitch, status='preview')
165        else:
166            self.shootingArea.init(440., 220., # visible fov
167                                    16.,  16.) # camera fov
168            self._model.preset.generatePositions()
169            for index, (yaw, pitch) in self._model.preset.iterPositions():
170                self.shootingArea.add_pict(yaw, pitch, status='preview')
171        yaw, pitch = self._model.hardware.readPosition()
172        self.shootingArea.set_current_head_position(yaw, pitch)
173
174    def _connectSignals(self):
175        super(ShootController, self)._connectSignals()
176
177        self.dialog.connect("key-press-event", self.__onKeyPressed)
178        self.dialog.connect("key-release-event", self.__onKeyReleased)
179        self.dialog.connect("delete-event", self.__onDelete)
180
181        self.shootingArea.connect("button-press-event", self.__onMouseButtonPressed)
182        #self.shootingArea.connect("motion-notify-event", self.__onMotionNotify)
183
184        Spy().newPosSignal.connect(self.__refreshPos)
185        self._model.startedSignal.connect(self.__shootingStarted)
186        self._model.pausedSignal.connect(self.__shootingPaused)
187        self._model.resumedSignal.connect(self.__shootingResumed)
188        self._model.stoppedSignal.connect(self.__shootingStopped)
189        self._model.waitingSignal.connect(self.__shootingWaiting)
190        self._model.beginShootSignal.connect(self.__shootingBeginShoot)
191        self._model.progressSignal.connect(self.__shootingProgress)
192        self._model.repeatSignal.connect(self.__shootingRepeat)
193        self._model.newPositionSignal.connect(self.__shootingNewPosition)
194        self._model.sequenceSignal.connect(self.__shootingSequence)
195        self._model.bracketSignal.connect(self.__shootingBracket)
196
197    # Callbacks GTK
198    def __onKeyPressed(self, widget, event, *args):
199
200        # 'Right' key
201        if event.keyval == self.__key['Right']:
202            if not self.__keyPressedDict['Right'] and not self.__keyPressedDict['Left']:
203                Logger().debug("MainController.__onKeyPressed(): 'Right' key pressed; forward shooting position")
204                self.__keyPressedDict['Right'] = True
205                self.__forwardShootingPosition()
206            return True
207
208        # 'Left' key
209        elif event.keyval == self.__key['Left']:
210            if not self.__keyPressedDict['Left'] and not self.__keyPressedDict['Right']:
211                Logger().debug("MainController.__onKeyPressed(): 'Left' key pressed; rewind shooting position")
212                self.__keyPressedDict['Left'] = True
213                self.__rewindShootingPosition()
214            return True
215
216        # 'Up' key
217        elif event.keyval == self.__key['Up']:
218            if not self.__keyPressedDict['Up'] and not self.__keyPressedDict['Down']:
219                Logger().debug("MainController.__onKeyPressed(): 'Up' key pressed; rewind shooting position")
220                self.__keyPressedDict['Up'] = True
221                self.__rewindShootingPosition()
222            return True
223
224        # 'Down' key
225        elif event.keyval == self.__key['Down']:
226            if not self.__keyPressedDict['Down'] and not self.__keyPressedDict['Up']:
227                Logger().debug("MainController.__onKeyPressed(): 'Down' key pressed; forward shooting position")
228                self.__keyPressedDict['Down'] = True
229                self.__forwardShootingPosition()
230            return True
231
232        # 'Return' key
233        if event.keyval == self.__key['Return']:
234            if not self.__keyPressedDict['Return']:
235                Logger().debug("shootController.__onKeyPressed(): 'Return' key pressed")
236                self.__keyPressedDict['Return'] = True
237
238                # Pressing 'Return' while not shooting starts shooting
239                if not self._model.isShooting():
240                    Logger().debug("shootController.__onKeyPressed(): start shooting")
241                    self.__startShooting()
242
243                # Pressing 'Return' while shooting...
244                else:
245
246                    # ...and not paused pauses shooting
247                    if not self._model.isPaused():
248                        Logger().debug("shootController.__onKeyPressed(): pause shooting")
249                        self.__pauseShooting()
250
251                    #... and paused resumes shooting
252                    else:
253                        Logger().debug("shootController.__onKeyPressed(): resume shooting")
254                        self.__resumeShooting()
255                return True
256
257        # 'Escape' key
258        elif event.keyval == self.__key['Escape']:
259           if not self.__keyPressedDict['Escape']:
260               Logger().debug("shootController.__onKeyPressed(): 'Escape' key pressed")
261               self.__keyPressedDict['Escape'] = True
262
263               # Pressing 'Escape' while not shooting exit shoot dialog
264               if not self._model.isShooting():
265                   Logger().debug("shootController.__onKeyPressed(): close shooting dialog")
266                   self.dialog.response(0)
267
268               # Pressing 'Escape' while shooting stops shooting
269               else:
270                   Logger().debug("shootController.__onKeyPressed(): stop shooting")
271                   self.__stopShooting()
272               return True
273
274        else:
275            Logger().warning("MainController.__onKeyPressed(): unbind '%s' key" % event.keyval)
276
277    def __onKeyReleased(self, widget, event, *args):
278
279        # 'Right' key
280        if event.keyval == self.__key['Right']:
281            if self.__keyPressedDict['Right']:
282                Logger().debug("MainController.__onKeyReleased(): 'Right' key released")
283                self.__keyPressedDict['Right'] = False
284            return True
285
286        # 'Left' key
287        if event.keyval == self.__key['Left']:
288            if self.__keyPressedDict['Left']:
289                Logger().debug("MainController.__onKeyReleased(): 'Left' key released")
290                self.__keyPressedDict['Left'] = False
291            return True
292
293        # 'Up' key
294        if event.keyval == self.__key['Up']:
295            if self.__keyPressedDict['Up']:
296                Logger().debug("MainController.__onKeyReleased(): 'Up' key released;")
297                self.__keyPressedDict['Up'] = False
298            return True
299
300        # 'Down' key
301        if event.keyval == self.__key['Down']:
302            if self.__keyPressedDict['Down']:
303                Logger().debug("MainController.__onKeyReleased(): 'Down' key released;")
304                self.__keyPressedDict['Down'] = False
305            return True
306
307        # 'Return' key
308        if event.keyval == self.__key['Return']:
309            if self.__keyPressedDict['Return']:
310                Logger().debug("MainController.__onKeyReleased(): 'Return' key released")
311                self.__keyPressedDict['Return'] = False
312            return True
313
314        # 'Escape' key
315        if event.keyval == self.__key['Escape']:
316            if self.__keyPressedDict['Escape']:
317                Logger().debug("MainController.__onKeyReleased(): 'Escape' key released")
318                self.__keyPressedDict['Escape'] = False
319            return True
320
321        else:
322            Logger().warning("MainController.__onKeyReleased(): unbind '%s' key" % event.keyval)
323
324    def __onDelete(self, widget, event):
325        Logger().trace("ShootController.__onDelete()")
326        self.__stopShooting() # Freeze if shooting!
327
328    def __onMouseButtonPressed(self, widget, event):
329        Logger().trace("ShootController.__onMouseButtonPressed()")
330        if self._model.isPaused():
331            if event.button == 1:
332                index = self.shootingArea.get_selected_image_index(event.x, event.y)
333                if index is not None:
334                    Logger().debug("ShootController.__onMouseButtonPressed(): x=%d, y=%d, index=%d" % (event.x, event.y, index))
335                    self._model.setShootingIndex(index)
336
337    def __onMotionNotify(self, widget, event):
338        #Logger().trace("ShootController.__onMotionNotify()")
339        if self._model.isPaused():
340            if event.is_hint:
341                Logger().trace("ShootController.__onMotionNotify(): is_hint")
342                x, y, state = event.window.get_pointer()
343            else:
344                x = event.x
345                y = event.y
346                state = event.state
347
348            if state & gtk.gdk.BUTTON1_MASK:
349                Logger().debug("ShootController.__onMotionNotify(): drag x=%d, y=%d" % (x, y))
350
351    def __onTextViewTogglebuttonToggled(self, widget):
352        Logger().trace("ShootController.__onTextViewTogglebuttonToggled()")
353        if widget.get_active():
354            self.viewport.remove(self.shootingArea)
355            self.viewport.add(self.textShootingArea)
356        else:
357            self.viewport.remove(self.textShootingArea)
358            self.viewport.add(self.shootingArea)
359
360    def __onRewindButtonclicked(self, widget):
361        Logger().trace("ShootController.__onRewindButtonclicked()")
362        self.__rewindShootingPosition()
363
364    def __onForwardButtonclicked(self, widget):
365        Logger().trace("ShootController.__onForwardButtonclicked()")
366        self.__forwardShootingPosition()
367
368    def __onStepByStepCheckbuttonToggled(self, widget):
369        Logger().trace("ShootController.____onStepByStepCheckbuttonToggled()")
370        switch = self.stepByStepCheckbutton.get_active()
371        self._model.setManualShoot(switch)
372
373    def __onDataFileButtonclicked(self, widget):
374        Logger().trace("ShootController.__onDataFileButtonclicked()")
375        controller = ConfigController(self, self._model, self._serializer)
376        controller.selectPage(5, disable=True)
377        response = controller.run()
378        controller.shutdown()
379        self.refreshView()
380
381    def __onTimerButtonClicked(self, widget):
382        Logger().trace("ShootController.__onTimerButtonClicked()")
383        controller = ConfigController(self, self._model, self._serializer)
384        controller.selectPage(6, disable=True)
385        response = controller.run()
386        controller.shutdown()
387        self.refreshView()
388
389    def __onStartButtonClicked(self, widget):
390        Logger().trace("ShootController.__startButtonClicked()")
391        self.__startShooting()
392
393    def __onPauseResumeButtonClicked(self, widget):
394        Logger().trace("ShootController.__onPauseResumeButtonClicked()")
395        if self._model.isShooting(): # Should always be true here, but...
396            if not self._model.isPaused():
397                self.__pauseShooting() # Not used
398            else:
399                self.__resumeShooting()
400
401    def __onStopButtonClicked(self, widget):
402        Logger().trace("ShootController.__stopButtonClicked()")
403        self.__stopShooting()
404
405    def __onDoneButtonClicked(self, widget):
406        Logger().trace("ShootController.__onDoneButtonClicked()")
407
408    # Callback model (all GUI calls must be done via the serializer)
409    def __shootingStarted(self):
410        Logger().trace("ShootController.__shootingStarted()")
411        self._serializer.addWork(self.shootingArea.clear)
412        self._serializer.addWork(self.progressbar.set_fraction, 0.)
413        self._serializer.addWork(self.position1Label.set_text, "--")
414        self._serializer.addWork(self.position2Label.set_text, "")
415        self._serializer.addWork(self.repeatLabel.set_text, "--")
416        self._serializer.addWork(self.dataFileButton.set_sensitive, False)
417        self._serializer.addWork(self.timerButton.set_sensitive, False)
418        self._serializer.addWork(self.startButton.set_sensitive, False)
419        self._serializer.addWork(self.pauseResumeButton.set_sensitive, True)
420        self._serializer.addWork(self.stopButton.set_sensitive, True)
421        self._serializer.addWork(self.doneButton.set_sensitive, False)
422        self._serializer.addWork(self.rewindButton.set_sensitive, False)
423        self._serializer.addWork(self.forwardButton.set_sensitive, False)
424
425    def __shootingPaused(self):
426        Logger().trace("ShootController.__shootingPaused()")
427        self.pauseResumeButton.set_sensitive(True)
428        self._serializer.addWork(self.pauseResumeLabel.set_text, _("Resume"))
429        self._serializer.addWork(self.rewindButton.set_sensitive, True)
430        self._serializer.addWork(self.forwardButton.set_sensitive, True)
431        self._serializer.addWork(self.progressbar.set_text, _("Idle"))
432
433    def __shootingResumed(self):
434        Logger().trace("ShootController.__shootingResumed()")
435        self._serializer.addWork(self.pauseResumeLabel.set_text, _("Pause"))
436        self._serializer.addWork(self.rewindButton.set_sensitive, False)
437        self._serializer.addWork(self.forwardButton.set_sensitive, False)
438
439    def __shootingStopped(self, status):
440        Logger().debug("ShootController.__shootingStopped(): status=%s" % status)
441        if status == 'ok':
442            self._serializer.addWork(self.progressbar.set_text, _("Finished"))
443        elif status == 'cancel':
444            self._serializer.addWork(self.progressbar.set_text, _("Canceled"))
445        elif status == 'fail':
446            self._serializer.addWork(self.progressbar.set_text, _("Failed"))
447        self._serializer.addWork(self.dataFileButton.set_sensitive, True)
448        self._serializer.addWork(self.timerButton.set_sensitive, True)
449        self._serializer.addWork(self.startButton.set_sensitive, True)
450        self._serializer.addWork(self.pauseResumeButton.set_sensitive, False)
451        self._serializer.addWork(self.stopButton.set_sensitive, False)
452        self._serializer.addWork(self.doneButton.set_sensitive, True)
453
454    def __shootingWaiting(self, wait):
455        Logger().trace("ShootController.__shootingRepeat()")
456        sequenceMessage = _("Waiting %s") % sToHmsAsStr(wait)
457        self._serializer.addWork(self.progressbar.set_text, sequenceMessage)
458
459    def __shootingBeginShoot(self):
460        Logger().trace("ShootController.__shootingBeginShoot()")
461        self._serializer.addWork(self.shootingArea.clear)
462
463    def __shootingProgress(self, progress):
464        Logger().trace("ShootController.__shootingProgress()")
465        self._serializer.addWork(self.progressbar.set_fraction, progress)
466
467    def __shootingRepeat(self, repeat):
468        Logger().trace("ShootController.__shootingRepeat()")
469        sequenceMessage = _("Repeat #%d of %d") % (repeat, self._model.timerEveryRepeat)
470        #self._serializer.addWork(self.progressbar.set_text, sequenceMessage)
471        self.repeatLabel.set_text(sequenceMessage)
472
473    def __shootingNewPosition(self, index, yaw, pitch, status=None, next=False):
474        Logger().trace("ShootController.__shootingNewPosition()")
475        if isinstance(index, tuple):
476            index, yawIndex, pitchIndex = index
477            position2 = _("(yaw #%(yawIndex)d of %(yawNbPicts)d, pitch #%(pitchIndex)d of %(pitchNbPicts)d)")
478            positionData = {'totalNbPicts': self._model.mosaic.totalNbPicts,
479                            'yawNbPicts': self._model.mosaic.yawNbPicts,
480                            'pitchNbPicts' : self._model.mosaic.pitchNbPicts}
481            positionData.update({'index': index, 'yawIndex': yawIndex, 'pitchIndex': pitchIndex})
482            self._serializer.addWork(self.position2Label.set_text, "%s" % position2 % positionData)
483        else:
484            positionData = {'totalNbPicts': self._model.preset.totalNbPicts}
485            positionData.update({'index': index})
486        #Logger().debug("ShootController.__shootingNewPosition(): %s" % sequence % sequenceData)
487        position1 = _("Position #%(index)d of %(totalNbPicts)d")
488        self._serializer.addWork(self.position1Label.set_text, "%s" % position1 % positionData)
489        self.shootingArea.add_pict(yaw, pitch, status, next)
490        self._serializer.addWork(self.shootingArea.refresh)
491
492    def __shootingSequence(self, sequence, **kwargs):
493        Logger().trace("ShootController.__shootingSequence()")
494        if sequence == 'moving':
495            self._serializer.addWork(self.progressbar.set_text, _("Moving"))
496        elif sequence == 'stabilization':
497            self._serializer.addWork(self.progressbar.set_text, _("Stabilization"))
498        elif sequence == 'mirror':
499            self._serializer.addWork(self.progressbar.set_text, _("Mirror lockup"))
500        elif sequence == 'shutter':
501            bracket = kwargs['bracket']
502            totalNbPicts = self._model.camera.bracketingNbPicts
503            self._serializer.addWork(self.progressbar.set_text, _("Shutter cycle - Pict #%d of %d") % (bracket, totalNbPicts))
504
505    def __shootingBracket(self, bracket):
506        Logger().trace("ShootController.__shootingBracket()")
507        sequenceData = {'bracket': bracket,
508                        'bracketingNbPicts': self._model.camera.bracketingNbPicts}
509        Logger().debug("ShootController.__shootingBracket(): bracket=%(bracket)d of %(bracketingNbPicts)d" % sequenceData)
510        #self._serializer.addWork(self.textShootingArea.set_text, "%s" % sequence % sequenceData)
511
512    def __refreshPos(self, yaw, pitch):
513        Logger().trace("ShootController.__refreshPos()")
514        self.shootingArea.set_current_head_position(yaw, pitch)
515        self._serializer.addWork(self.shootingArea.refresh)
516
517    # Helpers
518    def __rewindShootingPosition(self):
519        """
520        """
521        index = self._model.getShootingIndex()
522        Logger().debug("ShootController.__rewindShootingPosition(): old index=%d" % index)
523        try:
524            self._model.setShootingIndex(index - 1)
525            self.shootingArea.set_selected_image_index(index - 1)
526            Logger().debug("ShootController.__rewindShootingPosition():new index=%d" % (index - 1))
527        except IndexError:
528            Logger().exception("ShootController.__rewindShootingPosition()", debug=True)
529
530    def __forwardShootingPosition(self):
531        """
532        """
533        index = self._model.getShootingIndex()
534        Logger().debug("ShootController.__forwardShootingPosition(): old index=%d" % index)
535        try:
536            self._model.setShootingIndex(index + 1)
537            self.shootingArea.set_selected_image_index(index + 1)
538            Logger().debug("ShootController.__forwardShootingPosition(): new index=%d" % (index + 1))
539        except IndexError:
540            Logger().exception("ShootController.__forwardShootingPosition()", debug=True)
541
542    def __startShooting(self):
543
544        # Join previous thread, if any
545        if self.__thread is not None:
546            self.__thread.join()
547
548        # Start new shooting thread
549        self.__thread = threading.Thread(target=self._model.start, name="Shooting")
550        self.__thread.start()
551
552    def __pauseShooting(self):
553        self._model.pause()
554        self.pauseResumeButton.set_sensitive(False)
555
556    def __resumeShooting(self):
557        self._model.resume()
558
559    def __stopShooting(self):
560        self._model.stop()
561
562    # Interface
563    def shutdown(self):
564        super(ShootController, self).shutdown()
565        if self.__thread is not None:
566            self.__thread.join()
567        Spy().newPosSignal.disconnect(self.__refreshPos)
568        self._model.startedSignal.disconnect(self.__shootingStarted)
569        self._model.pausedSignal.disconnect(self.__shootingPaused)
570        self._model.resumedSignal.disconnect(self.__shootingResumed)
571        self._model.stoppedSignal.disconnect(self.__shootingStopped)
572        self._model.waitingSignal.disconnect(self.__shootingWaiting)
573        self._model.beginShootSignal.disconnect(self.__shootingBeginShoot)
574        self._model.progressSignal.disconnect(self.__shootingProgress)
575        self._model.repeatSignal.connect(self.__shootingRepeat)
576        self._model.newPositionSignal.disconnect(self.__shootingNewPosition)
577        self._model.sequenceSignal.disconnect(self.__shootingSequence)
578        self._model.bracketSignal.disconnect(self.__shootingBracket)
579
580    def refreshView(self):
581        dataFileFlag = ConfigManager().getBoolean('Preferences', 'DATA_FILE_ENABLE')
582        self.dataFileButtonImage.set_sensitive(dataFileFlag)
583        timerFlag = ConfigManager().getBoolean('Preferences', 'TIMER_AFTER_ENABLE') or ConfigManager().getBoolean('Preferences', 'TIMER_EVERY_ENABLE')
584        self.timerButtonImage.set_sensitive(timerFlag)
Note: See TracBrowser for help on using the repository browser.