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

Revision 1172, 30.0 KB checked in by fma, 4 years ago (diff)

Text view improvement

  • 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 sys
55import os.path
56import time
57import threading
58
59import pygtk
60pygtk.require("2.0")
61import gtk
62import gtk.gdk
63import gobject
64import pango
65
66from papywizard.common.loggingServices import Logger
67from papywizard.common.helpers import sToHmsAsStr
68from papywizard.common.configManager import ConfigManager
69from papywizard.controller.messageController import ErrorMessageController
70from papywizard.controller.abstractController import AbstractController
71from papywizard.controller.configController import ConfigController
72from papywizard.controller.spy import Spy
73from papywizard.view.shootingArea import MosaicArea, PresetArea
74
75if hasattr(sys, "frozen"):
76    path = os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])), "papywizard", "common")
77else:
78    path = os.path.dirname(__file__)
79
80
81class ShootController(AbstractController):
82    """ Shoot controller object.
83    """
84    def _init(self):
85        self._gladeFile = "shootDialog.glade"
86        self._signalDict = {"on_textViewTogglebutton_toggled": self.__onTextViewTogglebuttonToggled,
87                            "on_rewindButton_clicked": self.__onRewindButtonclicked,
88                            "on_forwardButton_clicked": self.__onForwardButtonclicked,
89                            "on_stepByStepCheckbutton_toggled": self.__onStepByStepCheckbuttonToggled,
90                            "on_dataFileButton_clicked": self.__onDataFileButtonclicked,
91                            "on_timerButton_clicked": self.__onTimerButtonClicked,
92                            "on_startButton_clicked": self.__onStartButtonClicked,
93                            "on_pauseResumeButton_clicked": self.__onPauseResumeButtonClicked,
94                            "on_stopButton_clicked": self.__onStopButtonClicked,
95                            "on_doneButton_clicked": self.__onDoneButtonClicked,
96                        }
97
98        self.__keyPressedDict = {'Right': False,
99                                 'Left': False,
100                                 'Up': False,
101                                 'Down': False,
102                                 'Return': False,
103                                 'Escape': False
104                             }
105        self.__key = {'Right': gtk.keysyms.Right,
106                      'Left': gtk.keysyms.Left,
107                      'Up': gtk.keysyms.Up,
108                      'Down': gtk.keysyms.Down,
109                      'Return': gtk.keysyms.Return,
110                      'Escape': gtk.keysyms.Escape
111                      }
112
113        self.__thread = None
114
115    def _retreiveWidgets(self):
116        super(ShootController, self)._retreiveWidgets()
117
118        self.viewport = self.wTree.get_widget("viewport")
119        self.textShootingArea = self.wTree.get_widget("table")
120        self.currentIndexLabel = self.wTree.get_widget("currentIndexLabel")
121        self.nextIndexLabel = self.wTree.get_widget("nextIndexLabel")
122        self.yawCurrentIndexLabel = self.wTree.get_widget("yawCurrentIndexLabel")
123        self.pitchCurrentIndexLabel = self.wTree.get_widget("pitchCurrentIndexLabel")
124        self.yawNextIndexLabel = self.wTree.get_widget("yawNextIndexLabel")
125        self.pitchNextIndexLabel = self.wTree.get_widget("pitchNextIndexLabel")
126        self.repeatLabel = self.wTree.get_widget("repeatLabel")
127        self.rewindButton = self.wTree.get_widget("rewindButton")
128        self.forwardButton = self.wTree.get_widget("forwardButton")
129        self.progressbar = self.wTree.get_widget("progressbar")
130        self.stepByStepCheckbutton = self.wTree.get_widget("stepByStepCheckbutton")
131        self.dataFileButton = self.wTree.get_widget("dataFileButton")
132        self.dataFileButtonImage = self.wTree.get_widget("dataFileButtonImage")
133        self.timerButton = self.wTree.get_widget("timerButton")
134        self.timerButtonImage = self.wTree.get_widget("timerButtonImage")
135        self.startButton = self.wTree.get_widget("startButton")
136        self.pauseResumeButton = self.wTree.get_widget("pauseResumeButton")
137        self.pauseResumeLabel = self.wTree.get_widget("pauseResumeLabel")
138        #self.pauseResumeImage = self.wTree.get_widget("pauseResumeImage")
139        self.stopButton = self.wTree.get_widget("stopButton")
140        self.doneButton = self.wTree.get_widget("doneButton")
141
142    def _initWidgets(self):
143
144        # Font
145        #for i in xrange(1, 7):
146            #label = self.wTree.get_widget("textLabel%d" % i)
147            #self._setFontParams(label, scale=0.8)
148        scale = 1.4
149        self._setFontParams(self.currentIndexLabel, scale=scale, weight=pango.WEIGHT_BOLD)
150        self._setFontParams(self.nextIndexLabel, scale=scale, weight=pango.WEIGHT_BOLD)
151        self._setFontParams(self.repeatLabel, scale=scale, weight=pango.WEIGHT_BOLD)
152        self._setFontParams(self.yawCurrentIndexLabel, scale=scale, weight=pango.WEIGHT_BOLD)
153        self._setFontParams(self.pitchCurrentIndexLabel, scale=scale, weight=pango.WEIGHT_BOLD)
154        self._setFontParams(self.yawNextIndexLabel, scale=scale, weight=pango.WEIGHT_BOLD)
155        self._setFontParams(self.pitchNextIndexLabel, scale=scale, weight=pango.WEIGHT_BOLD)
156
157        # Init text view
158        self.currentIndexLabel.set_text(_("--/%d") % self._model.scan.totalNbPicts)
159        self.nextIndexLabel.set_text(_("--/%d") % self._model.scan.totalNbPicts)
160        if self._model.timerRepeatEnable:
161            self.repeatLabel.set_text(_("--/%d") % self._model.timerRepeat)
162        else:
163            self.repeatLabel.set_text("")
164        if self._model.mode == 'mosaic':
165            self.yawCurrentIndexLabel.set_text(_("--/%d") % self._model.mosaic.yawNbPicts)
166            self.pitchCurrentIndexLabel.set_text(_("--/%d") % self._model.mosaic.pitchNbPicts)
167            self.yawNextIndexLabel.set_text(_("--/%d") % self._model.mosaic.yawNbPicts)
168            self.pitchNextIndexLabel.set_text(_("--/%d") % self._model.mosaic.pitchNbPicts)
169        else:
170            self.yawCurrentIndexLabel.set_text("")
171            self.pitchCurrentIndexLabel.set_text("")
172            self.yawNextIndexLabel.set_text("")
173            self.pitchNextIndexLabel.set_text("")
174
175        # Load graphical shooting area and replace the text view
176        if self._model.mode == 'mosaic':
177            self.shootingArea = MosaicArea() # Use a factory
178        else:
179            self.shootingArea = PresetArea() # Use a factory
180        self.viewport.remove(self.textShootingArea)
181        self.viewport.add(self.shootingArea)
182        self.shootingArea.show()
183
184        # Populate shooting area with preview positions
185        if self._model.mode == 'mosaic':
186
187            # todo: give args in shootingArea.__init__()
188            self.shootingArea.init(self._model.mosaic.yawStart, self._model.mosaic.yawEnd,
189                                   self._model.mosaic.pitchStart, self._model.mosaic.pitchEnd,
190                                   self._model.mosaic.yawFov, self._model.mosaic.pitchFov,
191                                   self._model.camera.getYawFov(self._model.cameraOrientation),
192                                   self._model.camera.getPitchFov(self._model.cameraOrientation),
193                                   self._model.mosaic.yawRealOverlap, self._model.mosaic.pitchRealOverlap)
194            self._model.mosaic.generatePositions()
195            for (index, yawIndex, pitchIndex), (yaw, pitch) in self._model.mosaic.iterPositions():
196                self.shootingArea.add_pict(yaw, pitch, status='preview')
197        else:
198            self.shootingArea.init(440., 220., # visible fov
199                                    16.,  16.) # camera fov
200            self._model.preset.generatePositions()
201            for index, (yaw, pitch) in self._model.preset.iterPositions():
202                self.shootingArea.add_pict(yaw, pitch, status='preview')
203        yaw, pitch = self._model.hardware.readPosition()
204        self.shootingArea.set_current_head_position(yaw, pitch)
205
206    def _connectSignals(self):
207        super(ShootController, self)._connectSignals()
208
209        self.dialog.connect("key-press-event", self.__onKeyPressed)
210        self.dialog.connect("key-release-event", self.__onKeyReleased)
211        self.dialog.connect("delete-event", self.__onDelete)
212
213        self.shootingArea.connect("button-press-event", self.__onMouseButtonPressed)
214        #self.shootingArea.connect("motion-notify-event", self.__onMotionNotify)
215
216        Spy().newPosSignal.connect(self.__refreshPos)
217        self._model.startedSignal.connect(self.__shootingStarted)
218        self._model.pausedSignal.connect(self.__shootingPaused)
219        self._model.resumedSignal.connect(self.__shootingResumed)
220        self._model.stoppedSignal.connect(self.__shootingStopped)
221        self._model.waitingSignal.connect(self.__shootingWaiting)
222        self._model.beginShootSignal.connect(self.__shootingBeginShoot)
223        self._model.progressSignal.connect(self.__shootingProgress)
224        self._model.repeatSignal.connect(self.__shootingRepeat)
225        self._model.newPositionSignal.connect(self.__shootingNewPosition)
226        self._model.sequenceSignal.connect(self.__shootingSequence)
227
228    # Callbacks GTK
229    def __onKeyPressed(self, widget, event, *args):
230
231        # 'Right' key
232        if event.keyval == self.__key['Right']:
233            if not self.__keyPressedDict['Right'] and not self.__keyPressedDict['Left']:
234                if self._model.isPaused():
235                    Logger().debug("MainController.__onKeyPressed(): 'Right' key pressed; forward shooting position")
236                    self.__keyPressedDict['Right'] = True
237                    self.__forwardShootingPosition()
238            return True
239
240        # 'Left' key
241        elif event.keyval == self.__key['Left']:
242            if not self.__keyPressedDict['Left'] and not self.__keyPressedDict['Right']:
243                if self._model.isPaused():
244                    Logger().debug("MainController.__onKeyPressed(): 'Left' key pressed; rewind shooting position")
245                    self.__keyPressedDict['Left'] = True
246                    self.__rewindShootingPosition()
247            return True
248
249        # 'Up' key
250        elif event.keyval == self.__key['Up']:
251            if not self.__keyPressedDict['Up'] and not self.__keyPressedDict['Down']:
252                if self._model.isPaused():
253                    Logger().debug("MainController.__onKeyPressed(): 'Up' key pressed; rewind shooting position")
254                    self.__keyPressedDict['Up'] = True
255                    self.__rewindShootingPosition()
256            return True
257
258        # 'Down' key
259        elif event.keyval == self.__key['Down']:
260            if not self.__keyPressedDict['Down'] and not self.__keyPressedDict['Up']:
261                if self._model.isPaused():
262                    Logger().debug("MainController.__onKeyPressed(): 'Down' key pressed; forward shooting position")
263                    self.__keyPressedDict['Down'] = True
264                    self.__forwardShootingPosition()
265            return True
266
267        # 'Return' key
268        if event.keyval == self.__key['Return']:
269            if not self.__keyPressedDict['Return']:
270                Logger().debug("shootController.__onKeyPressed(): 'Return' key pressed")
271                self.__keyPressedDict['Return'] = True
272
273                # Pressing 'Return' while not shooting starts shooting
274                if not self._model.isShooting():
275                    Logger().debug("shootController.__onKeyPressed(): start shooting")
276                    self.__startShooting()
277
278                # Pressing 'Return' while shooting...
279                else:
280
281                    # ...and not paused pauses shooting
282                    if not self._model.isPaused():
283                        Logger().debug("shootController.__onKeyPressed(): pause shooting")
284                        self.__pauseShooting()
285
286                    #... and paused resumes shooting
287                    else:
288                        Logger().debug("shootController.__onKeyPressed(): resume shooting")
289                        self.__resumeShooting()
290                return True
291
292        # 'Escape' key
293        elif event.keyval == self.__key['Escape']:
294           if not self.__keyPressedDict['Escape']:
295               Logger().debug("shootController.__onKeyPressed(): 'Escape' key pressed")
296               self.__keyPressedDict['Escape'] = True
297
298               # Pressing 'Escape' while not shooting exit shoot dialog
299               if not self._model.isShooting():
300                   Logger().debug("shootController.__onKeyPressed(): close shooting dialog")
301                   self.dialog.response(0)
302
303               # Pressing 'Escape' while shooting stops shooting
304               else:
305                   Logger().debug("shootController.__onKeyPressed(): stop shooting")
306                   self.__stopShooting()
307               return True
308
309        else:
310            Logger().warning("MainController.__onKeyPressed(): unbind '%s' key" % event.keyval)
311
312    def __onKeyReleased(self, widget, event, *args):
313
314        # 'Right' key
315        if event.keyval == self.__key['Right']:
316            if self.__keyPressedDict['Right']:
317                Logger().debug("MainController.__onKeyReleased(): 'Right' key released")
318                self.__keyPressedDict['Right'] = False
319            return True
320
321        # 'Left' key
322        if event.keyval == self.__key['Left']:
323            if self.__keyPressedDict['Left']:
324                Logger().debug("MainController.__onKeyReleased(): 'Left' key released")
325                self.__keyPressedDict['Left'] = False
326            return True
327
328        # 'Up' key
329        if event.keyval == self.__key['Up']:
330            if self.__keyPressedDict['Up']:
331                Logger().debug("MainController.__onKeyReleased(): 'Up' key released;")
332                self.__keyPressedDict['Up'] = False
333            return True
334
335        # 'Down' key
336        if event.keyval == self.__key['Down']:
337            if self.__keyPressedDict['Down']:
338                Logger().debug("MainController.__onKeyReleased(): 'Down' key released;")
339                self.__keyPressedDict['Down'] = False
340            return True
341
342        # 'Return' key
343        if event.keyval == self.__key['Return']:
344            if self.__keyPressedDict['Return']:
345                Logger().debug("MainController.__onKeyReleased(): 'Return' key released")
346                self.__keyPressedDict['Return'] = False
347            return True
348
349        # 'Escape' key
350        if event.keyval == self.__key['Escape']:
351            if self.__keyPressedDict['Escape']:
352                Logger().debug("MainController.__onKeyReleased(): 'Escape' key released")
353                self.__keyPressedDict['Escape'] = False
354            return True
355
356        else:
357            Logger().warning("MainController.__onKeyReleased(): unbind '%s' key" % event.keyval)
358
359    def __onDelete(self, widget, event):
360        Logger().trace("ShootController.__onDelete()")
361        self.__stopShooting() # Freeze if shooting!
362        return True
363
364    def __onMouseButtonPressed(self, widget, event):
365        Logger().trace("ShootController.__onMouseButtonPressed()")
366        if self._model.isPaused():
367            if event.button == 1:
368                index = self.shootingArea.get_selected_image_index(event.x, event.y)
369                if index is not None:
370                    Logger().debug("ShootController.__onMouseButtonPressed(): x=%d, y=%d, index=%d" % (event.x, event.y, index))
371                    self._model.setNextPositionIndex(index)
372                    self.__refreshNextPosition()
373
374    def __onMotionNotify(self, widget, event):
375        #Logger().trace("ShootController.__onMotionNotify()")
376        if self._model.isPaused():
377            if event.is_hint:
378                Logger().trace("ShootController.__onMotionNotify(): is_hint")
379                x, y, state = event.window.get_pointer()
380            else:
381                x = event.x
382                y = event.y
383                state = event.state
384
385            if state & gtk.gdk.BUTTON1_MASK:
386                Logger().debug("ShootController.__onMotionNotify(): drag x=%d, y=%d" % (x, y))
387
388    def __onTextViewTogglebuttonToggled(self, widget):
389        Logger().trace("ShootController.__onTextViewTogglebuttonToggled()")
390        if widget.get_active():
391            self.viewport.remove(self.shootingArea)
392            self.viewport.add(self.textShootingArea)
393        else:
394            self.viewport.remove(self.textShootingArea)
395            self.viewport.add(self.shootingArea)
396
397    def __onRewindButtonclicked(self, widget):
398        Logger().trace("ShootController.__onRewindButtonclicked()")
399        self.__rewindShootingPosition()
400
401    def __onForwardButtonclicked(self, widget):
402        Logger().trace("ShootController.__onForwardButtonclicked()")
403        self.__forwardShootingPosition()
404
405    def __onStepByStepCheckbuttonToggled(self, widget):
406        Logger().trace("ShootController.____onStepByStepCheckbuttonToggled()")
407        switch = self.stepByStepCheckbutton.get_active()
408        self._model.setManualShoot(switch)
409
410    def __onDataFileButtonclicked(self, widget):
411        Logger().trace("ShootController.__onDataFileButtonclicked()")
412        controller = ConfigController(self, self._model, self._serializer)
413        controller.selectPage(5, disable=True)
414        response = controller.run()
415        controller.shutdown()
416        self.refreshView()
417
418    def __onTimerButtonClicked(self, widget):
419        Logger().trace("ShootController.__onTimerButtonClicked()")
420        controller = ConfigController(self, self._model, self._serializer)
421        controller.selectPage(6, disable=True)
422        response = controller.run()
423        controller.shutdown()
424        #if self._model.timerRepeatEnable:
425            #self.repeatLabel.set_text(_("--/%d") % self._model.timerRepeat)
426        #else:
427            #self.repeatLabel.set_text("")
428        self.refreshView()
429
430    def __onStartButtonClicked(self, widget):
431        Logger().trace("ShootController.__startButtonClicked()")
432        self.__startShooting()
433
434    def __onPauseResumeButtonClicked(self, widget):
435        Logger().trace("ShootController.__onPauseResumeButtonClicked()")
436        if self._model.isShooting(): # Should always be true here, but...
437            if not self._model.isPaused():
438                self.__pauseShooting() # Not used
439            else:
440                self.__resumeShooting()
441
442    def __onStopButtonClicked(self, widget):
443        Logger().trace("ShootController.__stopButtonClicked()")
444        self.__stopShooting()
445
446    def __onDoneButtonClicked(self, widget):
447        Logger().trace("ShootController.__onDoneButtonClicked()")
448
449    # Callback model (all GUI calls must be done via the serializer)
450    def __shootingStarted(self):
451        Logger().trace("ShootController.__shootingStarted()")
452        self._serializer.addWork(self.shootingArea.clear)
453        self._serializer.addWork(self.progressbar.set_fraction, 0.)
454        self._serializer.addWork(self.currentIndexLabel.set_text, _("--/%d") % self._model.scan.totalNbPicts)
455        self._serializer.addWork(self.nextIndexLabel.set_text, _("--/%d") % self._model.scan.totalNbPicts)
456        if self._model.timerRepeatEnable:
457            self._serializer.addWork(self.repeatLabel.set_text, _("--/%d") % self._model.timerRepeat)
458        else:
459            self._serializer.addWork(self.repeatLabel.set_text, "")
460        if self._model.mode == 'mosaic':
461            self._serializer.addWork(self.yawCurrentIndexLabel.set_text, _("--/%d") % self._model.mosaic.yawNbPicts)
462            self._serializer.addWork(self.pitchCurrentIndexLabel.set_text, _("--/%d") % self._model.mosaic.pitchNbPicts)
463            self._serializer.addWork(self.yawNextIndexLabel.set_text, _("--/%d") % self._model.mosaic.yawNbPicts)
464            self._serializer.addWork(self.pitchNextIndexLabel.set_text, _("--/%d") % self._model.mosaic.pitchNbPicts)
465        else:
466            self._serializer.addWork(self.yawCurrentIndexLabel.set_text, "")
467            self._serializer.addWork(self.pitchCurrentIndexLabel.set_text, "")
468            self._serializer.addWork(self.yawNextIndexLabel.set_text, "")
469            self._serializer.addWork(self.pitchNextIndexLabel.set_text, "")
470        self._serializer.addWork(self.dataFileButton.set_sensitive, False)
471        self._serializer.addWork(self.timerButton.set_sensitive, False)
472        self._serializer.addWork(self.startButton.set_sensitive, False)
473        self._serializer.addWork(self.pauseResumeButton.set_sensitive, True)
474        self._serializer.addWork(self.stopButton.set_sensitive, True)
475        self._serializer.addWork(self.doneButton.set_sensitive, False)
476        self._serializer.addWork(self.rewindButton.set_sensitive, False)
477        self._serializer.addWork(self.forwardButton.set_sensitive, False)
478
479    def __shootingPaused(self):
480        Logger().trace("ShootController.__shootingPaused()")
481        self.pauseResumeButton.set_sensitive(True)
482        self._serializer.addWork(self.pauseResumeLabel.set_text, _("Resume"))
483        self._serializer.addWork(self.rewindButton.set_sensitive, True)
484        self._serializer.addWork(self.forwardButton.set_sensitive, True)
485        self._serializer.addWork(self.progressbar.set_text, _("Idle"))
486
487    def __shootingResumed(self):
488        Logger().trace("ShootController.__shootingResumed()")
489        self._serializer.addWork(self.pauseResumeLabel.set_text, _("Pause"))
490        self._serializer.addWork(self.rewindButton.set_sensitive, False)
491        self._serializer.addWork(self.forwardButton.set_sensitive, False)
492
493    def __shootingStopped(self, status):
494        Logger().debug("ShootController.__shootingStopped(): status=%s" % status)
495        if status == 'ok':
496            self._serializer.addWork(self.progressbar.set_text, _("Finished"))
497        elif status == 'cancel':
498            self._serializer.addWork(self.progressbar.set_text, _("Canceled"))
499        elif status == 'fail':
500            self._serializer.addWork(self.progressbar.set_text, _("Failed"))
501        self._serializer.addWork(self.dataFileButton.set_sensitive, True)
502        self._serializer.addWork(self.timerButton.set_sensitive, True)
503        self._serializer.addWork(self.startButton.set_sensitive, True)
504        self._serializer.addWork(self.pauseResumeButton.set_sensitive, False)
505        self._serializer.addWork(self.stopButton.set_sensitive, False)
506        self._serializer.addWork(self.doneButton.set_sensitive, True)
507
508    def __shootingWaiting(self, wait):
509        Logger().trace("ShootController.__shootingRepeat()")
510        sequenceMessage = _("Waiting %s") % sToHmsAsStr(wait)
511        self._serializer.addWork(self.progressbar.set_text, sequenceMessage)
512
513    def __shootingBeginShoot(self):
514        Logger().trace("ShootController.__shootingBeginShoot()")
515        self._serializer.addWork(self.shootingArea.clear)
516
517    def __shootingProgress(self, progress):
518        Logger().trace("ShootController.__shootingProgress()")
519        self._serializer.addWork(self.progressbar.set_fraction, progress)
520
521    def __shootingRepeat(self, repeat):
522        Logger().trace("ShootController.__shootingRepeat()")
523        if self._model.timerRepeatEnable:
524            self._serializer.addWork(self.repeatLabel.set_text, _("%d/%d") % (repeat, self._model.timerRepeat))
525
526    def __shootingNewPosition(self, index, yaw, pitch, status=None, next=False):
527        Logger().trace("ShootController.__shootingNewPosition()")
528
529        # Update text area
530        if isinstance(index, tuple):
531            index, yawIndex, pitchIndex = index
532            self._serializer.addWork(self.yawCurrentIndexLabel.set_text, _("%d/%d") % (yawIndex, self._model.mosaic.yawNbPicts))
533            self._serializer.addWork(self.yawNextIndexLabel.set_text, _("%d/%d") % (yawIndex, self._model.mosaic.yawNbPicts))
534            self._serializer.addWork(self.pitchCurrentIndexLabel.set_text, _("%d/%d") % (pitchIndex, self._model.mosaic.pitchNbPicts))
535            self._serializer.addWork(self.pitchNextIndexLabel.set_text, _("%d/%d") % (pitchIndex, self._model.mosaic.pitchNbPicts))
536        self._serializer.addWork(self.currentIndexLabel.set_text, _("%d/%d") % (index, self._model.scan.totalNbPicts))
537        self._serializer.addWork(self.nextIndexLabel.set_text, _("%d/%d") % (index, self._model.scan.totalNbPicts))
538
539        # Update graphical area
540        self.shootingArea.add_pict(yaw, pitch, status, next)
541        self._serializer.addWork(self.shootingArea.refresh)
542
543    def __shootingSequence(self, sequence, **kwargs):
544        Logger().trace("ShootController.__shootingSequence()")
545        if sequence == 'moving':
546            self._serializer.addWork(self.progressbar.set_text, _("Moving"))
547        elif sequence == 'stabilization':
548            self._serializer.addWork(self.progressbar.set_text, _("Stabilization"))
549        elif sequence == 'mirror':
550            self._serializer.addWork(self.progressbar.set_text, _("Mirror lockup"))
551        elif sequence == 'shutter':
552            bracket = kwargs['bracket']
553            totalNbPicts = self._model.camera.bracketingNbPicts
554            self._serializer.addWork(self.progressbar.set_text, _("Shutter - Picture %d/%d") % (bracket, totalNbPicts))
555
556    def __refreshPos(self, yaw, pitch):
557        Logger().trace("ShootController.__refreshPos()")
558        self.shootingArea.set_current_head_position(yaw, pitch)
559        self._serializer.addWork(self.shootingArea.refresh)
560
561    # Helpers
562    def __refreshNextPosition(self):
563        index = self._model.getShootingIndex() # getNexPositionIndex()
564        index, (yaw, pitch) = self._model.scan.getPositionAtIndex(index)
565
566        # Update text area
567        if isinstance(index, tuple):
568            index, yawIndex, pitchIndex = index
569            self.yawNextIndexLabel.set_text(_("%d/%d") % (yawIndex, self._model.mosaic.yawNbPicts))
570            self.pitchNextIndexLabel.set_text(_("%d/%d") % (pitchIndex, self._model.mosaic.pitchNbPicts))
571        self.nextIndexLabel.set_text(_("%d/%d") % (index, self._model.scan.totalNbPicts))
572
573        # Update graphical area
574        self.shootingArea.set_selected_image_index(index)
575
576    def __rewindShootingPosition(self):
577        """
578        """
579        index = self._model.getShootingIndex()
580        Logger().debug("ShootController.__rewindShootingPosition(): old index=%d" % index)
581        try:
582            self._model.setNextPositionIndex(index - 1)
583            self.__refreshNextPosition()
584            Logger().debug("ShootController.__rewindShootingPosition():new index=%d" % (index - 1))
585        except IndexError:
586            Logger().exception("ShootController.__rewindShootingPosition()", debug=True)
587
588    def __forwardShootingPosition(self):
589        """
590        """
591        index = self._model.getShootingIndex()
592        Logger().debug("ShootController.__forwardShootingPosition(): old index=%d" % index)
593        try:
594            self._model.setNextPositionIndex(index + 1)
595            self.__refreshNextPosition()
596            Logger().debug("ShootController.__forwardShootingPosition(): new index=%d" % (index + 1))
597        except IndexError:
598            Logger().exception("ShootController.__forwardShootingPosition()", debug=True)
599
600    def __startShooting(self):
601
602        # Join previous thread, if any
603        if self.__thread is not None:
604            self.__thread.join()
605
606        # Start new shooting thread
607        self.__thread = threading.Thread(target=self._model.start, name="Shooting")
608        self.__thread.start()
609
610    def __pauseShooting(self):
611        self._model.pause()
612        self.pauseResumeButton.set_sensitive(False)
613
614    def __resumeShooting(self):
615        self._model.resume()
616
617    def __stopShooting(self):
618        self._model.stop()
619
620    # Interface
621    def shutdown(self):
622        super(ShootController, self).shutdown()
623        if self.__thread is not None:
624            self.__thread.join()
625        Spy().newPosSignal.disconnect(self.__refreshPos)
626        self._model.startedSignal.disconnect(self.__shootingStarted)
627        self._model.pausedSignal.disconnect(self.__shootingPaused)
628        self._model.resumedSignal.disconnect(self.__shootingResumed)
629        self._model.stoppedSignal.disconnect(self.__shootingStopped)
630        self._model.waitingSignal.disconnect(self.__shootingWaiting)
631        self._model.beginShootSignal.disconnect(self.__shootingBeginShoot)
632        self._model.progressSignal.disconnect(self.__shootingProgress)
633        self._model.repeatSignal.connect(self.__shootingRepeat)
634        self._model.newPositionSignal.disconnect(self.__shootingNewPosition)
635        self._model.sequenceSignal.disconnect(self.__shootingSequence)
636
637    def refreshView(self):
638        dataFileFlag = ConfigManager().getBoolean('Preferences', 'DATA_FILE_ENABLE')
639        self.dataFileButtonImage.set_sensitive(dataFileFlag)
640        timerFlag = self._model.timerAfterEnable or self._model.timerRepeatEnable
641        self.timerButtonImage.set_sensitive(timerFlag)
Note: See TracBrowser for help on using the repository browser.