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

Revision 1416, 28.5 KB checked in by fma, 4 years ago (diff)

Use Qt signal for position refresh

  • 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-2009 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-2009 Frédéric Mantegazza
49@license: CeCILL
50"""
51
52__revision__ = "$Id$"
53
54import sys
55import os.path
56import time
57import threading
58
59from PyQt4 import QtCore, QtGui
60
61from papywizard.common.loggingServices import Logger
62from papywizard.common.helpers import sToHmsAsStr
63from papywizard.common.configManager import ConfigManager
64from papywizard.controller.abstractController import AbstractModalDialogController
65from papywizard.controller.configController import ConfigController
66from papywizard.controller.spy import Spy
67from papywizard.view.shootingScene import ShootingView, MosaicShootingScene, PresetShootingScene
68
69
70class ShootController(AbstractModalDialogController):
71    """ Shoot controller object.
72    """
73    def _init(self):
74        self._uiFile = "shootDialog.ui"
75
76        self.__keyPressedDict = {'Right': False,
77                                 'Left': False,
78                                 'Up': False,
79                                 'Down': False,
80                             }
81        self.__key = {'Right': QtCore.Qt.Key_Right,
82                      'Left': QtCore.Qt.Key_Left,
83                      'Up': QtCore.Qt.Key_Up,
84                      'Down': QtCore.Qt.Key_Down,
85                      'Return': QtCore.Qt.Key_Return,
86                      'Escape': QtCore.Qt.Key_Escape
87                      }
88
89        self.__thread = None
90        self.__shootingElapseTimer = QtCore.QTimer()
91        QtCore.QCoreApplication.connect(self.__shootingElapseTimer, QtCore.SIGNAL("timeout()"), self.__updateShootingElapsedTime)
92
93    def _initWidgets(self):
94
95        # Let the dialog be managed as a window so it can
96        # be displayed fullscreen on Nokia N8x0 devices
97        self._view.setWindowFlags(QtCore.Qt.Window)
98
99        if self._model.timerRepeatEnable:
100            self._view.repeatLabel.setText("--/%d" % self._model.timerRepeat)
101        else:
102            self._view.repeatLabel.setText("")
103
104        # Init text view
105        self._view.currentIndexLabel.setText("--/%d" % self._model.scan.totalNbPicts)
106        self._view.nextIndexLabel.setText("--/%d" % self._model.scan.totalNbPicts)
107        if self._model.mode == 'mosaic':
108            self._view.yawCurrentIndexLabel.setText("--/%d" % self._model.mosaic.yawNbPicts)
109            self._view.pitchCurrentIndexLabel.setText("--/%d" % self._model.mosaic.pitchNbPicts)
110            self._view.yawNextIndexLabel.setText("--/%d" % self._model.mosaic.yawNbPicts)
111            self._view.pitchNextIndexLabel.setText("--/%d" % self._model.mosaic.pitchNbPicts)
112        else:
113            self._view.yawCurrentIndexLabel.setText("--")
114            self._view.pitchCurrentIndexLabel.setText("--")
115            self._view.yawNextIndexLabel.setText("--")
116            self._view.pitchNextIndexLabel.setText("--")
117
118        # Create graphical shooting view and scene
119        self._view.shootingGraphicsView = ShootingView()
120        self._view.shootingStackedWidget.insertWidget(0, self._view.shootingGraphicsView)
121        self._view.shootingStackedWidget.setCurrentIndex(0)
122        if self._model.mode == 'mosaic':  # Use a factory
123            self.__shootingScene = MosaicShootingScene(self._model.mosaic.yawStart, self._model.mosaic.yawEnd,
124                                                       self._model.mosaic.pitchStart, self._model.mosaic.pitchEnd,
125                                                       self._model.mosaic.yawFov, self._model.mosaic.pitchFov,
126                                                       self._model.camera.getYawFov(self._model.cameraOrientation),
127                                                       self._model.camera.getPitchFov(self._model.cameraOrientation))
128
129        else:
130            self.__shootingScene = PresetShootingScene(0, 360,
131                                                       -90, 90,
132                                                       360, 180,
133                                                       60,
134                                                       60)
135
136        # Assign shooting scene to view
137        self._view.shootingGraphicsView.setScene(self.__shootingScene)
138
139        # Populate shooting scene with preview positions
140        self._model.scan.generatePositions()
141        while True:
142            try:
143                index, (yaw, pitch) = self._model.scan.getCurrentPosition()
144                if isinstance(index, tuple):
145                    index, yawIndex, pitchIndex = index
146                self.__shootingScene.addPicture(index, yaw, pitch, 'preview')
147                self._model.scan.index += 1
148            except IndexError:
149                Logger().exception("ShootController._initWidgets()", debug=True)
150                break
151
152        # Connect picture clicked signal
153        self.__shootingScene.pictureClicked.connect(self.__onPictureClicked)
154
155        # Refresh head position
156        yaw, pitch = self._model.hardware.readPosition()
157        self.__shootingScene.setHeadPosition(yaw, pitch)
158
159        # Select next picture position
160        self.__shootingScene.selectNextPicture(1)
161
162        # Keyboard behaviour
163        self._view.grabKeyboard()
164
165    def _connectQtSignals(self):
166        super(ShootController, self)._connectQtSignals()
167
168        self.connect(self._view.shootingStackPushButton, QtCore.SIGNAL("toggled(bool)"), self.__onShootingStackPushButtonToggled)
169        self.connect(self._view.rewindPushButton, QtCore.SIGNAL("clicked()"), self.__onRewindPushButtonClicked)
170        self.connect(self._view.forwardPushButton, QtCore.SIGNAL("clicked()"), self.__onForwardPushButtonClicked)
171
172        self.connect(self._view.dataPushButton, QtCore.SIGNAL("clicked()"), self.__onDataPushButtonClicked)
173        self.connect(self._view.timerPushButton, QtCore.SIGNAL("clicked()"), self.__onTimerPushButtonClicked)
174        self.connect(self._view.stepByStepPushButton, QtCore.SIGNAL("toggled(bool)"), self.__onStepByStepPushButtonToggled)
175
176        self.connect(self._view.startPushButton, QtCore.SIGNAL("clicked()"), self.__onStartPushButtonClicked)
177        self.connect(self._view.pauseResumePushButton, QtCore.SIGNAL("clicked()"), self.__onPauseResumePushButtonClicked)
178        self.connect(self._view.stopPushButton, QtCore.SIGNAL("clicked()"), self.__onStopPushButtonClicked)
179
180    def _connectSignals(self):
181        self.connect(Spy(), QtCore.SIGNAL("newPosition"), self.__refreshPos, QtCore.Qt.BlockingQueuedConnection)
182        self.connect(self._model, QtCore.SIGNAL("started"), self.__shootingStarted)
183        self.connect(self._model, QtCore.SIGNAL("paused"), self.__shootingPaused)
184        self.connect(self._model, QtCore.SIGNAL("resumed"), self.__shootingResumed)
185        self.connect(self._model, QtCore.SIGNAL("stopped"), self.__shootingStopped)
186        self.connect(self._model, QtCore.SIGNAL("waiting"), self.__shootingWaiting)
187        self.connect(self._model, QtCore.SIGNAL("progress"), self.__shootingProgress)
188        self.connect(self._model, QtCore.SIGNAL("repeat"), self.__shootingRepeat)
189        self.connect(self._model, QtCore.SIGNAL("update"), self.__shootingUpdate)
190        self.connect(self._model, QtCore.SIGNAL("sequence"), self.__shootingSequence)
191
192        self._view.keyPressEvent = self.__onKeyPressed
193        self._view.keyReleaseEvent = self.__onKeyReleased
194
195    def _disconnectSignals(self):
196        self.disconnect(Spy(), QtCore.SIGNAL("newPosition"), self.__refreshPos)
197        self.disconnect(self._model, QtCore.SIGNAL("started"), self.__shootingStarted)
198        self.disconnect(self._model, QtCore.SIGNAL("paused"), self.__shootingPaused)
199        self.disconnect(self._model, QtCore.SIGNAL("resumed"), self.__shootingResumed)
200        self.disconnect(self._model, QtCore.SIGNAL("stopped"), self.__shootingStopped)
201        self.disconnect(self._model, QtCore.SIGNAL("waiting"), self.__shootingWaiting)
202        self.disconnect(self._model, QtCore.SIGNAL("progress"), self.__shootingProgress)
203        self.disconnect(self._model, QtCore.SIGNAL("repeat"), self.__shootingRepeat)
204        self.disconnect(self._model, QtCore.SIGNAL("update"), self.__shootingUpdate)
205        self.disconnect(self._model, QtCore.SIGNAL("sequence"), self.__shootingSequence)
206
207    # Callbacks Qt
208    def _onCloseEvent(self, event):
209        Logger().trace("ShootController._onCloseEvent()")
210        if not self._model.isShooting():
211            self.shutdown()
212            event.accept()
213        else:
214            event.ignore()
215
216    def __onKeyPressed(self, event):
217        #Logger().debug("MainController.__onKeyPressed(): key='%s" % event.key())
218
219        # 'Right' key
220        if event.key() == self.__key['Right']:
221            if not self.__keyPressedDict['Right'] and not self.__keyPressedDict['Left']:
222                if self._model.isPaused():
223                    Logger().debug("MainController.__onKeyPressed(): 'Right' key pressed; forward shooting position")
224                    self.__keyPressedDict['Right'] = True
225                    self.__forwardShootingPosition()
226            event.ignore()
227
228        # 'Left' key
229        elif event.key() == self.__key['Left']:
230            if not self.__keyPressedDict['Left'] and not self.__keyPressedDict['Right']:
231                if self._model.isPaused():
232                    Logger().debug("MainController.__onKeyPressed(): 'Left' key pressed; rewind shooting position")
233                    self.__keyPressedDict['Left'] = True
234                    self.__rewindShootingPosition()
235            event.ignore()
236
237        # 'Up' key
238        elif event.key() == self.__key['Up']:
239            if not self.__keyPressedDict['Up'] and not self.__keyPressedDict['Down']:
240                if self._model.isPaused():
241                    Logger().debug("MainController.__onKeyPressed(): 'Up' key pressed; rewind shooting position")
242                    self.__keyPressedDict['Up'] = True
243                    self.__rewindShootingPosition()
244            event.ignore()
245
246        # 'Down' key
247        elif event.key() == self.__key['Down']:
248            if not self.__keyPressedDict['Down'] and not self.__keyPressedDict['Up']:
249                if self._model.isPaused():
250                    Logger().debug("MainController.__onKeyPressed(): 'Down' key pressed; forward shooting position")
251                    self.__keyPressedDict['Down'] = True
252                    self.__forwardShootingPosition()
253            event.ignore()
254
255        # 'Return' key
256        if event.key() == self.__key['Return']:
257            Logger().debug("shootController.__onKeyPressed(): 'Return' key pressed")
258
259            # Pressing 'Return' while not shooting starts shooting
260            if not self._model.isShooting():
261                Logger().debug("shootController.__onKeyPressed(): start shooting")
262                self.__startShooting()
263
264            # Pressing 'Return' while shooting...
265            else:
266
267                # ...and not paused pauses shooting
268                if not self._model.isPaused():
269                    Logger().debug("shootController.__onKeyPressed(): pause shooting")
270                    self.__pauseShooting()
271
272                #... and paused resumes shooting
273                else:
274                    Logger().debug("shootController.__onKeyPressed(): resume shooting")
275                    self.__resumeShooting()
276            event.ignore()
277
278        # 'Escape' key
279        elif event.key() == self.__key['Escape']:
280            Logger().debug("shootController.__onKeyPressed(): 'Escape' key pressed")
281
282            # Pressing 'Escape' while not shooting exit shoot dialog
283            if not self._model.isShooting():
284                Logger().debug("shootController.__onKeyPressed(): close shooting dialog")
285                self._view.reject()
286
287            # Pressing 'Escape' while shooting stops shooting
288            else:
289                Logger().debug("shootController.__onKeyPressed(): stop shooting")
290                self.__stopShooting()
291            event.ignore()
292
293        else:
294            event.accept()
295
296    def __onKeyReleased(self, event):
297        #Logger().debug("MainController.__onKeyReleased(): key='%s" % event.key())
298
299        # 'Right' key
300        if event.key() == self.__key['Right']:
301            if self.__keyPressedDict['Right']:
302                Logger().debug("MainController.__onKeyReleased(): 'Right' key released")
303                self.__keyPressedDict['Right'] = False
304            event.ignore()
305
306        # 'Left' key
307        if event.key() == self.__key['Left']:
308            if self.__keyPressedDict['Left']:
309                Logger().debug("MainController.__onKeyReleased(): 'Left' key released")
310                self.__keyPressedDict['Left'] = False
311            event.ignore()
312
313        # 'Up' key
314        if event.key() == self.__key['Up']:
315            if self.__keyPressedDict['Up']:
316                Logger().debug("MainController.__onKeyReleased(): 'Up' key released;")
317                self.__keyPressedDict['Up'] = False
318            event.ignore()
319
320        # 'Down' key
321        if event.key() == self.__key['Down']:
322            if self.__keyPressedDict['Down']:
323                Logger().debug("MainController.__onKeyReleased(): 'Down' key released;")
324                self.__keyPressedDict['Down'] = False
325            event.ignore()
326
327        else:
328            event.accept()
329
330    def __onMotionNotify(self, widget, event):
331        #Logger().trace("ShootController.__onMotionNotify()")
332        if self._model.isPaused():
333            if event.is_hint:
334                Logger().trace("ShootController.__onMotionNotify(): is_hint")
335                x, y, state = event.window.get_pointer()
336            else:
337                x = event.x
338                y = event.y
339                state = event.state
340
341            if state & gtk.gdk.BUTTON1_MASK:
342                Logger().debug("ShootController.__onMotionNotify(): drag x=%d, y=%d" % (x, y))
343
344    def __onShootingStackPushButtonToggled(self, checked):
345        Logger().trace("ShootController.__onShootingStackPushButtonToggled()")
346        if checked:
347            self._view.shootingStackedWidget.setCurrentIndex(1)
348        else:
349            self._view.shootingStackedWidget.setCurrentIndex(0)
350
351    def __onRewindPushButtonClicked(self):
352        Logger().trace("ShootController.__onRewindPushButtonClicked()")
353        self.__rewindShootingPosition()
354
355    def __onForwardPushButtonClicked(self):
356        Logger().trace("ShootController.__onForwardPushButtonClicked()")
357        self.__forwardShootingPosition()
358
359    def __onDataPushButtonClicked(self):
360        Logger().trace("ShootController.__onDataPushButtonClicked()")
361        controller = ConfigController(self, self._model)
362        controller.selectTab(5, disable=True)
363        response = controller.exec_()
364        self.refreshView()
365
366    def __onTimerPushButtonClicked(self):
367        Logger().trace("ShootController.__onTimerPushButtonClicked()")
368        controller = ConfigController(self, self._model)
369        controller.selectTab(6, disable=True)
370        response = controller.exec_()
371        if self._model.timerRepeatEnable:
372            self._view.repeatLabel.setText("--/%d" % self._model.timerRepeat)
373        else:
374            self._view.repeatLabel.setText("")
375        self.refreshView()
376
377    def __onStepByStepPushButtonToggled(self, checked):
378        Logger().trace("ShootController.__onStepByStepPushButtonToggled()")
379        self._model.setStepByStep(checked)
380        if checked:
381            self._view.stepByStepPushButton.setIcon(QtGui.QIcon(":/icons/button_ok.png"))
382        else:
383            self._view.stepByStepPushButton.setIcon(QtGui.QIcon(":/icons/button_cancel.png"))
384
385    def __onStartPushButtonClicked(self):
386        Logger().trace("ShootController.__startPushButtonClicked()")
387        self.__startShooting()
388
389    def __onPauseResumePushButtonClicked(self):
390        Logger().trace("ShootController.__onPauseResumePushButtonClicked()")
391        if self._model.isShooting(): # Should always be true here, but...
392            if not self._model.isPaused():
393                self.__pauseShooting() # Not used
394            else:
395                self.__resumeShooting()
396
397    def __onStopPushButtonClicked(self):
398        Logger().trace("ShootController.__stopPushButtonClicked()")
399        self.__stopShooting()
400
401    def __onDonePushButtonClicked(self):
402        Logger().trace("ShootController.__onDonePushButtonClicked()")
403        self.shutdown()
404
405    def __onPictureClicked(self, index):
406        Logger().trace("ShootController.__onPictureClicked(): index=%d" % index)
407        if self._model.isPaused():
408            self._model.scan.index = index
409            self.__refreshNextPosition()
410            self._model.forceNewPosition()
411
412    def __updateShootingElapsedTime(self):
413        #Logger().trace("ShootController.__updateShootingElapsedTime()")
414        if self._model.isShooting():
415            shootingTime, elapsedTime = self._model.getShootingElapsedTime()
416            self._view.shootingTimeLabel.setText("%s" % sToHmsAsStr(shootingTime))
417            self._view.elapsedTimeLabel.setText("%s" % sToHmsAsStr(elapsedTime))
418        else:
419            self.__shootingElapseTimer.stop()
420
421    # Callback model
422    def __shootingStarted(self):
423        Logger().trace("ShootController.__shootingStarted()")
424        self.__shootingScene.clear()
425        self._view.shootingProgressBar.setValue(0)
426        self._view.totalProgressBar.setValue(0)
427        if self._model.timerRepeatEnable:
428            self._view.repeatLabel.setText("--/%d" % self._model.timerRepeat)
429        else:
430            self._view.repeatLabel.setText("")
431        self._view.shootingTimeLabel.setText("00:00:00")
432        self._view.elapsedTimeLabel.setText("00:00:00")
433        self._view.currentIndexLabel.setText("--/%d" % self._model.scan.totalNbPicts)
434        self._view.nextIndexLabel.setText("--/%d" % self._model.scan.totalNbPicts)
435        if self._model.mode == 'mosaic':
436            self._view.yawCurrentIndexLabel.setText("--/%d" % self._model.mosaic.yawNbPicts)
437            self._view.pitchCurrentIndexLabel.setText("--/%d" % self._model.mosaic.pitchNbPicts)
438            self._view.yawNextIndexLabel.setText("--/%d" % self._model.mosaic.yawNbPicts)
439            self._view.pitchNextIndexLabel.setText("--/%d" % self._model.mosaic.pitchNbPicts)
440        else:
441            self._view.yawCurrentIndexLabel.setText("--")
442            self._view.pitchCurrentIndexLabel.setText("--")
443            self._view.yawNextIndexLabel.setText("--")
444            self._view.pitchNextIndexLabel.setText("--")
445        self._view.dataPushButton.setEnabled(False)
446        self._view.timerPushButton.setEnabled(False)
447        self._view.startPushButton.setEnabled(False)
448        self._view.pauseResumePushButton.setEnabled(True)
449        self._view.stopPushButton.setEnabled(True)
450        self._view.buttonBox.setEnabled(False)
451        self._view.rewindPushButton.setEnabled(False)
452        self._view.forwardPushButton.setEnabled(False)
453        self.__shootingElapseTimer.start(1000)
454
455    def __shootingPaused(self):
456        Logger().trace("ShootController.__shootingPaused()")
457        self._view.pauseResumePushButton.setEnabled(True)
458        self._view.pauseResumePushButton.setText(_("Resume"))
459        self._view.rewindPushButton.setEnabled(True)
460        self._view.forwardPushButton.setEnabled(True)
461        self._view.sequenceLabel.setText(_("Paused"))
462        self._view.textNextLabel.setEnabled(True)
463        self._view.nextIndexLabel.setEnabled(True)
464        self._view.yawNextIndexLabel.setEnabled(True)
465        self._view.pitchNextIndexLabel.setEnabled(True)
466
467    def __shootingResumed(self):
468        Logger().trace("ShootController.__shootingResumed()")
469        self._view.pauseResumePushButton.setText(_("Pause"))
470        self._view.rewindPushButton.setEnabled(False)
471        self._view.forwardPushButton.setEnabled(False)
472        self._view.textNextLabel.setEnabled(False)
473        self._view.nextIndexLabel.setEnabled(False)
474        self._view.yawNextIndexLabel.setEnabled(False)
475        self._view.pitchNextIndexLabel.setEnabled(False)
476
477    def __shootingStopped(self, status):
478        Logger().debug("ShootController.__shootingStopped(): status=%s" % status)
479        if status == 'ok':
480            self._view.sequenceLabel.setText( _("Finished"))
481        elif status == 'cancel':
482            self._view.sequenceLabel.setText(_("Canceled"))
483        elif status == 'fail':
484            self._view.sequenceLabel.setText(_("Failed"))
485        self._view.dataPushButton.setEnabled(True)
486        self._view.timerPushButton.setEnabled(True)
487        self._view.startPushButton.setEnabled(True)
488        self._view.pauseResumePushButton.setEnabled(False)
489        self._view.stopPushButton.setEnabled(False)
490        self._view.buttonBox.setEnabled(True)
491
492    def __shootingWaiting(self, wait):
493        Logger().trace("ShootController.__shootingRepeat()")
494        sequenceMessage = _("Waiting") + " %s" % sToHmsAsStr(wait)
495        self._view.sequenceLabel.setText(sequenceMessage)
496
497    def __shootingProgress(self, shootingProgress=None, totalProgress=None):
498        Logger().trace("ShootController.__shootingProgress()")
499        if shootingProgress is not None:
500            self._view.shootingProgressBar.setValue(int(round(shootingProgress * 100)))
501        if totalProgress is not None:
502           self._view.totalProgressBar.setValue(int(round(totalProgress * 100)))
503
504    def __shootingRepeat(self, repeat):
505        Logger().trace("ShootController.__shootingRepeat()")
506        self.__shootingScene.clear()
507        if self._model.timerRepeatEnable:
508            self._view.repeatLabel.setText("%d/%d" % (repeat, self._model.timerRepeat))
509
510    def __shootingUpdate(self, index, yaw, pitch, state=None, next=False):
511        Logger().trace("ShootController.__shootingUpdate()")
512
513        # Update text area
514        if isinstance(index, tuple):
515            index, yawIndex, pitchIndex = index
516            self._view.yawCurrentIndexLabel.setText("%d/%d" % (yawIndex, self._model.mosaic.yawNbPicts))
517            self._view.yawNextIndexLabel.setText("%d/%d" % (yawIndex, self._model.mosaic.yawNbPicts))
518            self._view.pitchCurrentIndexLabel.setText("%d/%d" % (pitchIndex, self._model.mosaic.pitchNbPicts))
519            self._view.pitchNextIndexLabel.setText("%d/%d" % (pitchIndex, self._model.mosaic.pitchNbPicts))
520        else:
521            self._view.yawCurrentIndexLabel.setText("%.1f" % yaw)
522            self._view.yawNextIndexLabel.setText("%.1f" % yaw)
523            self._view.pitchCurrentIndexLabel.setText("%.1f" % pitch)
524            self._view.pitchNextIndexLabel.setText("%.1f" % pitch)
525        self._view.currentIndexLabel.setText("%d/%d" % (index, self._model.scan.totalNbPicts))
526        self._view.nextIndexLabel.setText("%d/%d" % (index, self._model.scan.totalNbPicts))
527
528        # Update graphical area
529        if state is not None:
530            self.__shootingScene.setPictureState(index, state)
531        if next is True:
532            self.__shootingScene.selectNextPicture(index)
533        elif next is False:
534            self.__shootingScene.selectNextPicture(index + 1)
535
536    def __shootingSequence(self, sequence, bracket=None):
537        Logger().trace("ShootController.__shootingSequence()")
538        if sequence == 'moving':
539            self._view.sequenceLabel.setText(_("Moving"))
540        elif sequence == 'stabilization':
541            self._view.sequenceLabel.setText(_("Stabilization"))
542        elif sequence == 'mirror':
543            self._view.sequenceLabel.setText(_("Mirror lockup"))
544        elif sequence == 'shutter':
545            totalNbPicts = self._model.camera.bracketingNbPicts
546            self._view.sequenceLabel.setText(_("Shutter - Picture") + " %d/%d" % (bracket, totalNbPicts))
547
548    def __refreshPos(self, yaw, pitch):
549        """ Refresh position according to new pos.
550
551        @param yaw: yaw axis value
552        @type yaw: float
553
554        @param pitch: pitch axix value
555        @type pitch: float
556        """
557        #Logger().trace("ShootController.__refreshPos()")
558        self.__shootingScene.setHeadPosition(yaw, pitch)
559
560    # Helpers
561    def __refreshNextPosition(self):
562        index, (yaw, pitch) = self._model.scan.getCurrentPosition()
563
564        # Update text area
565        if isinstance(index, tuple):
566            index, yawIndex, pitchIndex = index
567            self._view.yawNextIndexLabel.setText("%d/%d" % (yawIndex, self._model.mosaic.yawNbPicts))
568            self._view.pitchNextIndexLabel.setText("%d/%d" % (pitchIndex, self._model.mosaic.pitchNbPicts))
569        else:
570            self._view.yawNextIndexLabel.setText("%.1f" % yaw)
571            self._view.pitchNextIndexLabel.setText("%.1f" % pitch)
572        self._view.nextIndexLabel.setText("%d/%d" % (index, self._model.scan.totalNbPicts))
573
574        # Update graphical area
575        self.__shootingScene.selectNextPicture(index)
576
577    def __rewindShootingPosition(self):
578        """
579        """
580        Logger().debug("ShootController.__rewindShootingPosition(): old index=%d" % self._model.scan.index)
581        try:
582            self._model.scan.index -= 1
583            self.__refreshNextPosition()
584            self._model.forceNewPosition()
585            Logger().debug("ShootController.__rewindShootingPosition(): new index=%d" % self._model.scan.index)
586        except IndexError:
587            Logger().exception("ShootController.__rewindShootingPosition()", debug=True)
588
589    def __forwardShootingPosition(self):
590        """
591        """
592        Logger().debug("ShootController.__forwardShootingPosition(): old index=%d" % self._model.scan.index)
593        try:
594            self._model.scan.index += 1
595            self.__refreshNextPosition()
596            self._model.forceNewPosition()
597            Logger().debug("ShootController.__forwardShootingPosition(): new index=%d" % self._model.scan.index)
598        except IndexError:
599            Logger().exception("ShootController.__forwardShootingPosition()", debug=True)
600
601    def __startShooting(self):
602
603        # Join previous thread, if any
604        if self.__thread is not None:
605            self.__thread.wait()
606
607        # Start new shooting thread
608        self.__thread = ShootingThread(self._model)
609        self.__thread.start()
610
611    def __pauseShooting(self):
612        self._model.pause()
613        self._view.pauseResumePushButton.setEnabled(False)
614
615    def __resumeShooting(self):
616        self._model.resume()
617
618    def __stopShooting(self):
619        self._model.stop()
620
621    # Interface
622    def shutdown(self):
623        super(ShootController, self).shutdown()
624        if self.__thread is not None:
625            self.__thread.wait()
626
627    def refreshView(self):
628        dataFlag = ConfigManager().getBoolean('Preferences', 'DATA_FILE_ENABLE')
629        if dataFlag:
630            self._view.dataPushButton.setIcon(QtGui.QIcon(":/icons/button_ok.png"))
631        else:
632            self._view.dataPushButton.setIcon(QtGui.QIcon(":/icons/button_cancel.png"))
633
634        timerFlag = self._model.timerAfterEnable or self._model.timerRepeatEnable
635        if timerFlag:
636            self._view.timerPushButton.setIcon(QtGui.QIcon(":/icons/button_ok.png"))
637        else:
638            self._view.timerPushButton.setIcon(QtGui.QIcon(":/icons/button_cancel.png"))
639
640
641class ShootingThread(QtCore.QThread):
642    """ Special thread starting shooting.
643    """
644    def __init__(self, model, parent=None):
645        """ Init the shooting thread.
646        """
647        QtCore.QThread.__init__(self, parent)
648        self.__model = model
649
650    def run(self):
651        threading.currentThread().setName("Shooting")
652        self.__model.start()
Note: See TracBrowser for help on using the repository browser.