Merge lp:~nico-inattendu/luciole/bug_727175 into lp:luciole

Proposed by NicoInattendu
Status: Merged
Approved by: NicoInattendu
Approved revision: 132
Merged at revision: 128
Proposed branch: lp:~nico-inattendu/luciole/bug_727175
Merge into: lp:luciole
Diff against target: 1723 lines (+205/-1101)
6 files modified
luciole/ctrl/base.py (+13/-3)
luciole/ctrl/ctrl_acq.py (+40/-325)
luciole/ctrl/ctrl_app.py (+80/-722)
luciole/ctrl/ctrl_project.py (+30/-36)
luciole/ctrl/ctrl_timeline.py (+18/-11)
luciole/gui/actions.py (+24/-4)
To merge this branch: bzr merge lp:~nico-inattendu/luciole/bug_727175
Reviewer Review Type Date Requested Status
NicoInattendu Pending
Review via email: mp+52300@code.launchpad.net

Commit message

fix for bug bug #727175

Description of the change

Correction for bug #727175.

Timeline mode change by default

Inhibit Acquisition mode ?

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'luciole/ctrl/base.py'
2--- luciole/ctrl/base.py 2010-12-15 05:23:57 +0000
3+++ luciole/ctrl/base.py 2011-03-05 15:01:33 +0000
4@@ -30,10 +30,20 @@
5 from pitivi.signalinterface import Signallable
6 from pitivi.log.loggable import Loggable
7 # local application/library specific imports
8+from luciole.base.exceptions import LucioException
9+
10+
11+
12+class ProjectModeError(LucioException) :
13+ """ ProjectMode Error class"""
14+
15+ def __init__(self, *params):
16+ LucioException.__init__(self, *params)
17+
18
19
20 class ProjectMode(Signallable, Loggable) :
21- """ Base class """
22+ """ Base/abstact for project modes class """
23 __signals__ = {}
24
25 def __init__(self, ctrl_project, mode_type = None) :
26@@ -78,7 +88,8 @@
27 def active_viewer(self) :
28 """ Meta function.
29 active displays associted to mode """
30- pass
31+ self.debug('active viewer')
32+
33
34 def prepare(self, project) :
35 """ Meta function.
36@@ -97,7 +108,6 @@
37 release """
38 self.debug('Release')
39 self._viewer.setPipeline(None)
40- pass
41
42
43
44
45=== modified file 'luciole/ctrl/ctrl_acq.py'
46--- luciole/ctrl/ctrl_acq.py 2011-02-27 18:32:53 +0000
47+++ luciole/ctrl/ctrl_acq.py 2011-03-05 15:01:33 +0000
48@@ -31,8 +31,6 @@
49
50 # related third party imports
51 import gst
52-from pitivi.signalinterface import Signallable
53-from pitivi.log.loggable import Loggable
54 from pitivi.signalgroup import SignalGroup
55 from pitivi.action import ViewAction
56 from pitivi.pipeline import Pipeline
57@@ -47,6 +45,10 @@
58 from luciole.ctrl.base import ProjectMode
59
60 class ProjectModeAcquisition(ProjectMode) :
61+ """
62+ class in charge of Acquisition.
63+ High level class
64+ """
65 MODES = ( "INVALID",
66 "NO_ACQUISITION",
67 "ACQUISITION",
68@@ -63,10 +65,13 @@
69 }
70
71 def __init__(self, ctrl_project) :
72- self._mode ="INVALID"
73+ self._mode = "INVALID"
74 ProjectMode.__init__(self, ctrl_project, "ACQUISITION")
75 self.gui_signals = SignalGroup()
76
77+ self._source_factory = None
78+ self._view_action = None
79+
80 def prepare(self, project) :
81 """ prepare acquistion """
82 ProjectMode.prepare(self, project)
83@@ -83,7 +88,8 @@
84 WebcamSourceFactory(capture_path = _capture_path,
85 with_mixer = False)
86
87- self.debug(' webcam filter : %s',self.project.props['webcam_data'])
88+ self.debug('webcam filter : %s',
89+ self.project.props['webcam_data'])
90 self._set_webcam_params(
91 self.project.props['webcam_data'],
92 self._source_factory)
93@@ -102,12 +108,15 @@
94 self._view_action.addProducers(self._source_factory)
95
96 self._mode = "NO_ACQUISITION"
97- self.debug('emit acquirer-ready, Webcam factory : %s, pipeline : %s',
98- self._source_factory, self._pipeline )
99+ self.debug(
100+ 'emit acquirer-ready, Webcam factory : %s, pipeline : %s',
101+ self._source_factory, self._pipeline )
102 self.emit('acquirer-ready')
103
104
105 def release(self) :
106+ """ release ctrl_acq used objects
107+ """
108 ProjectMode.release(self)
109 self.debug('releasing acquisition')
110 self._disconnect_from_factory(self._source_factory)
111@@ -118,6 +127,7 @@
112 self._view_action = None
113
114 def active_viewer(self) :
115+ """ set gui viewer with acquisition view """
116 if self._viewer :
117 self._viewer.setPipeline(None)
118 self._viewer.hideSlider()
119@@ -140,21 +150,25 @@
120
121 if self._mode == "NO_ACQUISITION" :
122 if with_mixer == True :
123- self._source_factory.active_mixer(True)
124- self._mode = "ACQUISITION_WITH_MIXER"
125+ pass
126+ # TODO : deactivated code mixer does not work
127+ #self._source_factory.active_mixer(True)
128+ #self._mode = "ACQUISITION_WITH_MIXER"
129 else :
130 #self._source_factory.active_mixer(False)
131 self._mode = "ACQUISITION"
132
133 self._pipeline.play()
134- self.debug('send acquisition-started - mode : %s',self._mode )
135+ self.debug('send acquisition-started - mode : %s', self._mode)
136 self.emit('acquisition-started', with_mixer)
137
138
139 else :
140- self.error("Cannot start acquisition. Controller in incorrect mode (%s)",
141+ self.error("Cannot start acquisition."
142+ "Controller in incorrect mode (%s)",
143 self._mode)
144-
145+
146+
147 def stop(self) :
148 """ stop acquisition """
149 self.debug('stop acquisition - mode %s', self._mode)
150@@ -170,9 +184,10 @@
151 self.error(
152 "Cannot stop acquistion. Controller in incorrect mode (%s)",
153 self._mode)
154-
155+
156
157 def do_snapshot(self) :
158+ """ make/request image snapshot """
159 if self._mode in ("ACQUISITION", "ACQUISITION_WITH_MIXER") :
160 self._source_factory.capture()
161
162@@ -182,6 +197,8 @@
163 self._mode)
164
165 def active_mixer(self, is_active) :
166+ """ active the mixer (onion skin)"""
167+
168 # check with current mixer status
169 self.debug('active_mixer : %s', is_active)
170 if self.project.props['is-mixer-active'] == is_active :
171@@ -230,18 +247,27 @@
172 self.project.props['is-mixer-active'] = is_active
173
174 def _connect_to_factory(self, factory, _capture_path) :
175- factory.connect("image-capture-done", self._image_capture_done_cb, _capture_path )
176-
177+ """ connect to acqusistion factory signals """
178+ factory.connect("image-capture-done",
179+ self._image_capture_done_cb,
180+ _capture_path )
181 def _disconnect_from_factory(self, factory) :
182+ """ disconnect signals from factory """
183 factory.disconnect_by_function(self._image_capture_done_cb)
184
185 def _image_capture_done_cb( self, factory, _capture_path) :
186+ """ image capture done callback,
187+ signal received from factory """
188+
189 self.debug('RX image-capture-done')
190 _rush_image = self._process_snapshot(_capture_path)
191 self.debug('emit snapshot-taken : %s', _rush_image.name)
192 self.emit('snapshot-taken', _rush_image)
193
194 def _process_snapshot(self, capture_path) :
195+ """
196+ process image capture to insert in the luciole project
197+ """
198 # get acquired image name
199 _acq_image = capture_path
200
201@@ -320,315 +346,4 @@
202
203
204
205-# TODO : suppress CtrlAcq
206-
207-class CtrlAcq(Signallable, Loggable) :
208- MODES = ( "INVALID",
209- "NO_ACQUISITION",
210- "ACQUISITION",
211- "ACQUISITION_WITH_MIXER",
212- )
213-
214-
215- __signals__ = {
216- 'acquirer-ready' : ['acquirer'],
217- 'acquirer-error' : ['msg'],
218- 'acquisition-started' : ['with_mixer'],
219- 'acquisition-stopped' : [],
220- 'snapshot-on-progress' : [],
221- 'snapshot-taken' : ['rush_image'],
222- }
223-
224-
225- def __init__(self, ctrl_project) :
226- """ initialize the acquirer """
227- Signallable.__init__(self)
228- Loggable.__init__(self)
229- self.ctrl_project = ctrl_project
230-
231- self.acquirer = None
232- self.project = None
233- self._mode = "INVALID"
234-
235- # signal connections
236- self._connect_to_project(self.ctrl_project)
237-
238- self.gui_signals = SignalGroup()
239-
240- self.debug('CtrlAcq intialized : %s %s',self.ctrl_project, ctrl_project )
241-
242-
243- def init_acquirer(self, project) :
244- self.debug("Init acquirer")
245- _project = project.props
246- if _project != None :
247- # Create acquisition object
248- _acq_obj = None
249- # remark; acquisition object for webcam and dv cam
250- if _project['hardtype'] == LCONST.WEBCAM :
251- # init webcam factory
252- self.factory = WebcamSourceFactory()
253- self.debug('Webcam factory : %s', self.factory )
254- self.pipeline = PTV_PPLN.Pipeline()
255- self.view_action = ViewAction()
256- self.view_action.addProducers(self.factory)
257-
258- self.viewer = self.ctrl_project.gui._get_drawarea()
259- self.viewer.hideSlider()
260- self.viewer.setPipeline(None)
261- self.viewer.setAction(self.view_action)
262- self.viewer.setPipeline(self.pipeline, "ACQUISITION")
263- #self.viewer.play()
264- # just for debug
265- _acq_obj =self.pipeline
266-
267-
268-
269- elif _project['hardtype'] == LCONST.DVCAM :
270- # default acquisition load i.e. DVCAM
271- _acq_obj = LACQ.Acquisition(
272- self._get_drawarea(self.ctrl_project.gui),
273- False,
274- _project['hardtype'],
275- project_dir = _project['project_dir'],
276- cb_error = self._on_error_acqusition,
277- cb_capture_done = self._on_done_snaphot)
278- else :
279- # Nothing to do
280- self.emit('acquirer-error', 'No valid acquirer found' )
281- if _acq_obj != None :
282- self._mode = "NO_ACQUISITION"
283- # for mixer initialisation set image to mix with the last image
284- # of the capture view. only if capture image is not empty
285- if len(_project['capture_images'] ) > 0 :
286- _last_image_path = \
287- os.path.join( _project['project_dir'],
288- _project['rush_dir'],
289- _project['capture_images'][-1])
290- if os.path.exists(_last_image_path) :
291- _acq_obj.Image2Mix = _last_image_path
292-
293- self.emit('acquirer-ready', _acq_obj )
294- self.acquirer = _acq_obj
295-
296-
297- def start_acquisition(self) :
298- if self._mode == "NO_ACQUISITION" :
299- self.pipeline.play()
300- self._mode = "ACQUISITION"
301- self.emit('acquisition-started', False)
302- else :
303- self.error(
304- "Cannot start acquisition. Controller in incorrect mode (%s)",
305- self._mode)
306-
307- def stop_acquisition(self) :
308- if self._mode in ("ACQUISITION", "ACQUISITION_WITH_MIXER") :
309- if self._mode == "ACQUISITION_WITH_MIXER" :
310- pass
311- #self.acquirer.deactive_onion_skin()
312- self.pipeline.stop()
313-
314- self._mode = "NO_ACQUISITION"
315- self.debug('emit acquisition-stopped')
316- self.emit('acquisition-stopped')
317- else :
318- self.error(
319- "Cannot stop acquistion. Controller in incorrect mode (%s)",
320- self._mode)
321-
322- def active_mixer(self) :
323- if self._mode == "ACQUISITION" :
324- # the active onion skin stop the acquistion
325- self.acquirer.active_onion_skin()
326- # so start acqusition
327- self.acquirer.start_acqusition()
328-
329- self._mode = "ACQUISITION_WITH_MIXER"
330- self.emit('acquisition-started', True)
331- else :
332- self.error(
333- "Cannot active mixer. Controller in incorrect mode (%s)",
334- self._mode)
335-
336-
337- def deactive_mixer(self) :
338- if self._mode == "ACQUISITION_WITH_MIXER" :
339- # deactivate onion skin stop the acquistion
340- self.acquirer.deactive_onion_skin()
341- # so start acqusition
342- self.acquirer.start_acqusition()
343-
344- self._mode = "ACQUISITION"
345- self.emit('acquisition-started', False)
346- else :
347- self.error(
348- "Cannot deactive mixer. Controller in incorrect mode (%s)",
349- self._mode)
350-
351- def take_snapshot(self) :
352- if self._mode in ("ACQUISITION", "ACQUISITION_WITH_MIXER") :
353- if self.acquirer.is_streaming_active == True :
354-
355- self.debug('emit snapshot-on-progress')
356- self.emit('snapshot-on-progress')
357- self.acquirer.capture_image()
358-
359-
360-
361- def release(self) :
362- # ensure acquisition stop
363- self.debug('Enterin release in mode=%s', self._mode)
364- if self._mode in ("ACQUISITION","ACQUISITION_WITH_MIXER") :
365- self.debug('Force acquistion stop : %s', self._mode)
366- self.stop_acquisition()
367- else :
368- self.debug('Bad state : %s', self._mode)
369- self.acquirer.release()
370-
371- #self._disconnect_from_project(self.ctrl_project)
372- #self._disconnect_from_gui(self.ctrl_project.gui)
373- #self.gui_signals.disconnectAll()
374-
375- def _connect_to_project(self, ctrl_project) :
376- ctrl_project.connect('project-loaded', self._project_loaded_cb)
377- ctrl_project.connect('project-closed', self._project_closed_cb)
378- """
379- def _disconnect_from_project(self, ctrl_project) :
380- ctrl_project.disconnect_by_function(self._project_loaded_cb)
381- ctrl_project.disconnect_by_function(self._project_closed_cb)
382- """
383- def _project_closed_cb(self, project_ctrl) :
384- self.debug('RX project-closed')
385- self.release()
386-
387-
388- def _project_loaded_cb(self, project_ctrl, project) :
389- self.debug('RX project-loaded')
390- self.init_acquirer(project)
391- self._connect_to_gui(self.ctrl_project.gui)
392- self.pipeline.play()
393- self.project = project
394-
395- """"
396- def _connect_to_gui(self, gui) :
397- # connection GUI to ctrl_acq
398- gui.connect('start-acqusition', self._start_acq_cb)
399- gui.connect('stop-acqusition', self._stop_acq_cb)
400- gui.connect('take-snapshot', self._take_snapshot_cb)
401- gui.connect('active-mixer', self._active_mixer_cb)
402- gui.connect('deactive-mixer', self._deactive_mixer_cb)
403-
404- # connection ctrl_acq to gui
405- gui._project_mode.connect_to_ctrl('ACQUISITION', self)
406- """
407-
408- def _connect_to_gui(self, gui) :
409- self.gui_signals.connect(
410- gui, "start-acqusition", None, self._start_acq_cb)
411- self.gui_signals.connect(
412- gui, "stop-acqusition", None, self._stop_acq_cb)
413- self.gui_signals.connect(
414- gui, "take-snapshot", None, self._take_snapshot_cb)
415- self.gui_signals.connect(
416- gui, "active-mixer", None, self._active_mixer_cb)
417- self.gui_signals.connect(
418- gui, "deactive-mixer", None, self._deactive_mixer_cb)
419-
420- # connection ctrl_acq to gui
421- gui._project_mode.connect_to_ctrl('ACQUISITION', self)
422-
423-
424- def _disconnect_from_gui(self,gui) :
425- # dicconnection GUI to ctrl_acq
426- gui.disconnect_by_function(self._start_acq_cb)
427- gui.disconnect_by_function(self._stop_acq_cb)
428- gui.disconnect_by_function(self._take_snapshot_cb)
429- gui.disconnect_by_function(self._active_mixer_cb)
430- gui.disconnect_by_function(self._deactive_mixer_cb)
431-
432-
433- def _start_acq_cb(self, gui) :
434- if self.ctrl_project.mode == 'ACQUISITION' :
435- self.start_acquisition()
436-
437- def _stop_acq_cb(self, gui) :
438- if self.ctrl_project.mode == 'ACQUISITION' :
439- self.stop_acquisition()
440-
441- def _take_snapshot_cb(self, gui) :
442- if self.ctrl_project.mode == 'ACQUISITION' :
443- self.take_snapshot()
444-
445- def _active_mixer_cb(self, gui) :
446- self.active_mixer()
447-
448- def _deactive_mixer_cb(self, gui) :
449- self.deactive_mixer()
450-
451- def _on_error_acqusition(self, message) :
452- """
453- callback error
454- propagate it to main controller.
455- """
456- print " acqusistion error\n ", message
457- self.emit('acquirer-error', message)
458-
459- def _on_done_snaphot(self, *unsued) :
460- """
461- callback when snaphot done.
462- """
463- _rush_image = self._process_snapshot()
464- self.debug('emit snapshot-taken : %s', _rush_image.name)
465- self.emit('snapshot-taken', _rush_image)
466-
467- def _process_snapshot(self) :
468- # get acquired image name
469- _acq_image = self.acquirer.image2save
470-
471- # build temp impage path
472- _temp_dir = os.path.join(self.project.props['project_dir'], 'tmp')
473- # copy name
474- _ac_image_temp = os.path.join(_temp_dir, _acq_image)
475- # resized copy name
476- _ac_image_temp_rz = \
477- os.path.join(_temp_dir, LCONST.ACQUIRED_IMAGE_NAME_RZ)
478-
479- # build rush image name
480- _basename = LCONST.RUSH_FILENAME_TPL % self.project.rush.rush_index
481- _rush_image = \
482- os.path.join(self.project.props['project_dir'],
483- self.project.props['rush_dir'],
484- _basename)
485-
486- try :
487- # 1. move image acquired image to tmp dir
488- LT.movef(_acq_image, _ac_image_temp)
489-
490- # 2. resize image result is in _ac_image_temp_rz
491- _rz_obj = LI.ImageResize(_ac_image_temp, _ac_image_temp_rz )
492- _rz_obj.convert()
493-
494- # 3. move resized image to rush dire
495- LT.movef(_ac_image_temp_rz, _rush_image)
496-
497- except LEXCEP.LucioException, _err_msg :
498- self.error(_err_msg)
499- else :
500- # 4. append image to rush list
501- _rush_image = self.project.rush.append(_basename)
502-
503- # always update the image 2 mix, even if mixer is not active
504- # used to memorize the last capture
505- self.acquirer.Image2Mix = _rush_image.path
506-
507- # project modified
508- self.ctrl_project.is_modified = True
509-
510- return _rush_image
511-
512- def _get_drawarea(self, gui) :
513- _da = gui._get_drawarea()
514- self.debug(" Drawarea used : %s", _da)
515- return _da
516
517
518=== modified file 'luciole/ctrl/ctrl_app.py'
519--- luciole/ctrl/ctrl_app.py 2011-02-27 18:32:53 +0000
520+++ luciole/ctrl/ctrl_app.py 2011-03-05 15:01:33 +0000
521@@ -27,7 +27,6 @@
522 Main application controller
523 """
524 # standard library imports
525-import sys
526 import os
527 import os.path
528 import locale
529@@ -40,21 +39,14 @@
530
531 from pitivi.signalinterface import Signallable
532 from pitivi.log.loggable import Loggable
533-from pitivi.log import log
534
535 # local application/library specific imports
536-import luciole.base.app_logging as LOGGING
537-import luciole.base.exceptions as LEXCEP
538 import luciole.base.options as OPTIONS
539 import luciole.conf as LCONF
540 import luciole.constants as LCONST
541-import luciole.ctrl.constants as CTRL_CONST
542-import luciole.ctrl.import_image as CTRL_IMPORT
543 import luciole.ctrl.ctrl_project as CTRL_PROJECT
544-import luciole.gui.constants as GUI_CONST
545 import luciole.gui.main_window as GUI_MAIN
546 import luciole.gui.gui_ctrl as GUI_CTRL
547-import luciole.info as INFO
548 import luciole.media.lgst.play_sound as LSOUND
549 #####
550
551@@ -72,97 +64,128 @@
552 self._connect_gui_and_project()
553
554 def _connect_gui_and_project(self) :
555-
556+ """ conect gui signals to project """
557 # application high level actions
558 self.gui.gui_actions.connect('open-project', self._open_project_cb)
559 self.gui.gui_actions.connect('new-project', self._new_project_cb)
560 self.gui.gui_actions.connect('quit-app', self._quit_cb)
561
562 # Project level actions
563- self.gui.gui_actions.connect('save-project', self._save_project_cb)
564- self.gui.gui_actions.connect('save-as-project', self._save_as_project_cb)
565- self.gui.gui_actions.connect('close-project', self._close_project_cb)
566- self.gui.gui_actions.connect('acquisition-mode', self._acq_mode_cb)
567- self.gui.gui_actions.connect('timeline-mode', self._timeline_mode_cb)
568- self.gui.gui_actions.connect('import-sound', self._import_sound_cb)
569- self.gui.gui_actions.connect('image-view', self._image_view_cb)
570- self.gui.gui_actions.connect('import-images', self._import_images_cb)
571- self.gui.gui_actions.connect('show-project-properties', self._show_project_properties_cb)
572+ self.gui.gui_actions.connect('save-project',
573+ self._save_project_cb)
574+ self.gui.gui_actions.connect('save-as-project',
575+ self._save_as_project_cb)
576+ self.gui.gui_actions.connect('close-project',
577+ self._close_project_cb)
578+ self.gui.gui_actions.connect('acquisition-mode',
579+ self._acq_mode_cb)
580+ self.gui.gui_actions.connect('timeline-mode',
581+ self._timeline_mode_cb)
582+ self.gui.gui_actions.connect('import-sound',
583+ self._import_sound_cb)
584+ self.gui.gui_actions.connect('image-view',
585+ self._image_view_cb)
586+ self.gui.gui_actions.connect('import-images',
587+ self._import_images_cb)
588+ self.gui.gui_actions.connect('show-project-properties',
589+ self._show_project_properties_cb)
590
591
592 # Acqusition actions
593- self.gui.gui_actions.connect('start-acquistion', self._start_acq_cb)
594- self.gui.gui_actions.connect('stop-acquistion', self._stop_acq_cb)
595- self.gui.gui_actions.connect('take-snapshot', self._take_snapshot_cb)
596- self.gui.gui_actions.connect('active-mixer', self._active_mixer_cb)
597+ self.gui.gui_actions.connect('start-acquistion',
598+ self._start_acq_cb)
599+ self.gui.gui_actions.connect('stop-acquistion',
600+ self._stop_acq_cb)
601+ self.gui.gui_actions.connect('take-snapshot',
602+ self._take_snapshot_cb)
603+ self.gui.gui_actions.connect('active-mixer',
604+ self._active_mixer_cb)
605
606 # Timeline actions
607- self.gui.gui_actions.connect('change-timeline-order', self._change_timeline_order_cb)
608- self.gui.gui_actions.connect('insert-image-on-timeline', self._insert_image_on_timeline_cb)
609- self.gui.gui_actions.connect('remove-image-on-timeline', self._remove_image_on_timeline_cb)
610- self.gui.gui_actions.connect('active-sound', self._active_sound_cb)
611- self.gui.gui_actions.connect('deactive-sound', self._deactive_sound_cb)
612- self.gui.gui_actions.connect('sound-stop-with-video', self._sound_stop_with_video_cb)
613- self.gui.gui_actions.connect('change-framerate', self._change_framerate_cb)
614+ self.gui.gui_actions.connect('change-timeline-order',
615+ self._change_timeline_order_cb)
616+ self.gui.gui_actions.connect('insert-image-on-timeline',
617+ self._insert_image_on_timeline_cb)
618+ self.gui.gui_actions.connect('remove-image-on-timeline',
619+ self._remove_image_on_timeline_cb)
620+ self.gui.gui_actions.connect('active-sound',
621+ self._active_sound_cb)
622+ self.gui.gui_actions.connect('deactive-sound',
623+ self._deactive_sound_cb)
624+ self.gui.gui_actions.connect('sound-stop-with-video',
625+ self._sound_stop_with_video_cb)
626+ self.gui.gui_actions.connect('change-framerate',
627+ self._change_framerate_cb)
628
629
630-
631-
632 #
633 # application high level callbacks
634 #
635
636 def _open_project_cb(self, gui, path) :
637- self.debug('RX close-project signal')
638+ """ GUI open project callback"""
639+ self.debug('RX open-project signal')
640 self.project_ctrl.open(path)
641
642 def _new_project_cb(self, gui ) :
643+ """ GUI new project callback"""
644 self.debug('RX new-project signal' )
645 self.project_ctrl.new_project()
646
647
648 def _quit_cb(self, gui):
649+ """ GUI quit callback"""
650 self.app.quit()
651 return True
652 #
653 # Project level callbacks
654 #
655 def _save_project_cb(self, gui) :
656+ """ GUI save project callback"""
657 self.debug('RX save-project signal')
658 self.project_ctrl.save()
659
660 def _save_as_project_cb(self, gui, path) :
661+ """ GUI save as project callback"""
662 self.debug('RX save-as-project signal')
663 self.project_ctrl.save(path)
664
665
666 def _close_project_cb(self, gui) :
667+ """ GUI close project callback"""
668 self.debug('RX close-project signal')
669 self.project_ctrl.close()
670
671
672 def _acq_mode_cb(self, gui) :
673+ """ GUI acquisition mode callback"""
674 self.debug('RX acquisition-mode signal')
675 self.project_ctrl.acquisition_mode()
676
677 def _timeline_mode_cb(self, gui) :
678+ """ GUI timeline mode callback"""
679 self.debug('RX timeline-mode signal')
680- self.project_ctrl.timleline_mode()
681+ self.project_ctrl.timeline_mode()
682
683 def _import_sound_cb(self, gui, path) :
684+ """ GUI import sound callback"""
685 self.debug('RX import-sound signal : %s', path)
686 self.project_ctrl.ctrl_tmln.add_sound_track(path)
687
688 def _image_view_cb(self, gui, origin, image_name, position = 0) :
689- self.debug('RX image-view signal : origin %s image %s', origin, image_name)
690+ """ GUI image view callback"""
691+ self.debug('RX image-view signal : origin %s image %s',
692+ origin,
693+ image_name)
694 self.project_ctrl.img_vw_mode(origin, image_name, position)
695
696 def _import_images_cb(self, gui, paths) :
697- self.debug('RX import-images signal : %s',paths )
698+ """ GUI import images callback"""
699+ self.debug('RX import-images signal : %s', paths )
700 self.project_ctrl.import_images(paths)
701
702 def _show_project_properties_cb(self, gui) :
703- """ show project properties callback """
704+ """ GUI show project properties callback """
705 self.debug('RX show-project-properties' )
706 self.project_ctrl.show_project_properties()
707
708@@ -173,18 +196,22 @@
709 #
710
711 def _start_acq_cb(self, gui) :
712+ """ GUI start acqusisition callback"""
713 self.debug(' RX start-acquistion signal')
714 self.project_ctrl.ctrl_acq.start()
715
716 def _stop_acq_cb(self, gui) :
717+ """ GUI stop acqusisition callback"""
718 self.debug(' RX stop-acquistion signal')
719 self.project_ctrl.ctrl_acq.stop()
720
721 def _take_snapshot_cb(self, gui) :
722+ """ GUI take snapshot callback"""
723 self.debug('RX take-snapshot signal')
724 self.project_ctrl.ctrl_acq.do_snapshot()
725
726 def _active_mixer_cb(self, gui, is_active) :
727+ """ GUI active mixer callback"""
728 self.debug('RX active-mixer signal : %s', is_active)
729 self.project_ctrl.ctrl_acq.active_mixer(is_active)
730
731@@ -192,31 +219,42 @@
732 # Timeline callbacks
733 #
734 def _change_timeline_order_cb(self, gui, objs, target):
735- self.debug('RX change-timeline-order signal - objs %s target %s', objs, target)
736+ """ GUI change timeline sequence callback"""
737+ self.debug(("RX change-timeline-order signal"
738+ " - objs %s target %s")
739+ , objs, target)
740 self.project_ctrl.ctrl_tmln.change_order(objs, target)
741
742 def _insert_image_on_timeline_cb(self, gui, objs, target):
743- self.debug('RX insert-image-on-timeline signal - objs %s target %s', objs, target)
744+ """ GUI insert image on timeline callback"""
745+ self.debug(("RX insert-image-on-timeline signal"
746+ "- objs %s target %s"),
747+ objs, target)
748 self.project_ctrl.ctrl_tmln.insert(objs, target)
749
750 def _remove_image_on_timeline_cb(self, gui, objs):
751+ """ GUI remove image on timeline callback"""
752 self.debug('RX remove-image-on-timeline signal - objs %s', objs)
753 self.project_ctrl.ctrl_tmln.remove(objs)
754
755 def _active_sound_cb(self, gui) :
756+ """ GUI active sound callback"""
757 self.debug('RX active-sound signal')
758 self.project_ctrl.ctrl_tmln.add_sound_track_to_timeline()
759
760 def _deactive_sound_cb(self, gui) :
761+ """ GUI deactive sound callback"""
762 self.debug('RX deactive-sound signal')
763 self.project_ctrl.ctrl_tmln.remove_sound_track_from_timeline()
764
765 def _sound_stop_with_video_cb(self, gui, is_stop) :
766+ """ GUI sound stop with video callback"""
767 self.debug('RX sound-stop-with-video, is_stop %s', is_stop)
768 self.project_ctrl.ctrl_tmln.stop_sound_with_video(is_stop)
769
770 def _change_framerate_cb(self, gui, fpi) :
771- self.debug('RXchange-framerate, fpi %s', fpi)
772+ """ GUI cahnge framerate callback"""
773+ self.debug('RX change-framerate, fpi %s', fpi)
774 self.project_ctrl.set_framerate(fpi)
775
776 class CtrlApp(Signallable, Loggable) :
777@@ -363,688 +401,8 @@
778 def _quit_cb(self, project) :
779 self.quit()
780
781-class LucioleController(object):
782- """
783- Main luciole controller
784- """
785-
786- def __init__(self, args) :
787- """ Controller initialisation.
788-
789- Is the main appication intialisation """
790- # init logging as early as possible so we can log startup code
791- enable_color = os.environ.get('PITIVI_DEBUG_NO_COLOR', '0') in ('', '0')
792- log.init('PITIVI_DEBUG', enable_color)
793-
794- #
795- # init attributes
796- #
797- self.ctrl_signals = None
798- self.__rusher = None
799-
800- # parse program options
801- self.__options = OPTIONS.options_parser()
802-
803- # init logging
804- self.logger = LOGGING.init_logging(
805- self.__options.is_verbose,
806- log_to_file = self.__options.is_logfile
807- )
808- self.logger.info("Starting luciole")
809-
810- # Init i18n
811- self.__init_i18n()
812-
813- # load configuration : ie. saved user options
814- self.__configurer = LCONF.LucioleConf()
815- # load GUI theme
816- self.__configurer.load_theme()
817- # create controller signals
818- self.__connect_signals()
819- # initialize gui and BTW threads
820- self.__gui = GUI_CTRL.GuiController(self.ctrl_signals)
821-
822-
823-
824- # load recent projects
825- _cbs = None
826- _recent_mnger = self.__configurer.init_recent_manager(
827- self.__gui.file_recent_menu,
828- self.__gui.windows,
829- _cbs)
830-
831- # prepare callbacks for Project controller
832- _cbs = { 'done-rush' : self.on_done_rush,
833- 'close-project' : self.on_close_project }
834-
835-
836- # start project controller
837- self._project = \
838- CTRL_PROJECT.ProjectController(self.__gui,_recent_mnger ,_cbs)
839-
840- _cbs = {
841- 'on-done-snapshot' : self.on_done_snapshot,
842- 'on-error':self.on_error
843- }
844- self._viewer = CTRL_VIEWER.Viewer(self.__gui, _cbs)
845-
846- # display capture trash if option is set
847- if self.__configurer.conf_options['CaptureTrashDisplay'] == 'yes' :
848- self.__gui.capture_trash = True
849-
850-
851-
852- # conncet gui signals after the controller initialisation
853- self.__gui.connect_gui_signals()
854- # Connect GUI with app
855- self.__gui.connect_to_app_ctrl(self)
856-
857- # TODO : load timeline
858- #TMLN.Timeline()
859-
860- def __connect_signals(self):
861- """ connect controller signals """
862- self.ctrl_signals = gobject.GObject()
863- for _signal in CTRL_CONST.CTRL_SIGNALS :
864-
865- # declare signal
866- gobject.signal_new(_signal, self.ctrl_signals,
867- gobject.SIGNAL_RUN_LAST,
868- gobject.TYPE_NONE,
869- (gobject.TYPE_PYOBJECT,))
870-
871- # Build signal callback function name from signal name
872- # example : signal "change-alpha-mixer"
873- # have callback self.on_change_alpha_mixer
874- _cb = 'self.on_' + _signal.replace('-', '_')
875- # connect signal
876- self.ctrl_signals.connect(_signal, eval(_cb))
877-
878-
879- def on_change_alpha_mixer(self, *args) :
880- """ Request change mixer alpha value """
881- _args = self.__extract_signal_args(args)
882- try :
883- self._viewer.change_mixer_alpha(_args['alpha'])
884- except LEXCEP.LucioException, _err_msg :
885- raise LEXCEP.LucioException, _err_msg
886-
887-
888- def on_change_framerate(self, *args) :
889- """ Request of framerate(fpi) change """
890- _args = self.__extract_signal_args(args)
891- self._project.change_framerate(_args['framerate'])
892-
893- def on_change_project(self, *args) :
894- """ Request for prohect change """
895- _args = self.__extract_signal_args(args)
896- for _key, _value in _args.iteritems() :
897- self._project.change_project(_key, _value)
898-
899- def on_close_project(self, *args ) :
900- """ Request for project close """
901- _args = self.__extract_signal_args(args)
902- # test if project exists
903- if self._project.mode == CTRL_CONST.PROJECT_LOADED :
904- # check if project is modified
905- if self._project.data['is_modified'] :
906- # ask for save it before close
907- _res = self.__gui.windows.\
908- question_message(_('Save Project before closing'))
909- if _res :
910- self._project.save()
911-
912- # set viewer in default mode
913- self._viewer.mode = self._viewer.DEFAULT
914-
915- # clear project controller
916- self._project.mode = CTRL_CONST.NO_PROJECT
917-
918- # display close message
919- _msg = _('Project %s is closed' % self._project.data['project_name'])
920- self.__gui.status_bar.display_message(_msg)
921-
922-
923- def on_create_project(self, *args) :
924- """ Request new project """
925- _args = self.__extract_signal_args(args)
926- self._project.new()
927-
928-
929- def on_delete_capture(self, *args) :
930- """ Request delete on capture """
931- _args = self.__extract_signal_args(args)
932- # remove on treeview
933- self.__gui.treeviews[LCONST.CAPTURE].remove()
934-
935- # The image selected for delete is displayed before delete
936- # so after go in default mode to nom more display the deleted image
937- self._viewer.mode = self._viewer.DEFAULT
938-
939- # change control widget in no acquisition mode
940- if self.__gui.control_widget.mode in\
941- ( GUI_CONST.ACQUISITION_ACTIVE,
942- GUI_CONST.ACQUISITION_ACTIVE_WITH_MIXER) :
943- self.__gui.control_widget.mode = GUI_CONST.ACQUISTION_INACTIVE
944-
945-
946- def on_delete_chrono(self, *args) :
947- """ Request delete on capture """
948- _args = self.__extract_signal_args(args)
949- # remove on treeview
950- self.__gui.treeviews[LCONST.CHRONO].remove()
951-
952- # The image selected for delete is displayed before delete
953- # so after go in default mode to nom more display the deleted image
954- self._viewer.mode = self._viewer.DEFAULT
955-
956- # change control widget in no acquisition mode
957- if self.__gui.control_widget.mode in \
958- ( GUI_CONST.ACQUISITION_ACTIVE,
959- GUI_CONST.ACQUISITION_ACTIVE_WITH_MIXER) :
960- self.__gui.control_widget.mode = GUI_CONST.ACQUISTION_INACTIVE
961-
962-
963- def on_display_about(self, *args) :
964- """ request display about """
965- _args = self.__extract_signal_args(args)
966- # compute version
967- __version = "\n %s (%s)" % (INFO.VERSION, INFO.REVNO)
968- # display window
969- self.__gui.windows.about(__version)
970-
971-
972- def on_display_luciole_preferences(self, *args) :
973- """ Request display of application preferences """
974- _args = self.__extract_signal_args(args)
975- _cbs = {'done-preferences' : self.on_done_preferences}
976- self.__gui.windows.preferences( self.__configurer.conf_options,
977- _cbs)
978-
979-
980-
981-
982-
983- def on_display_project_properties(self, *args) :
984- """ Request display project properties """
985- _args = self.__extract_signal_args(args)
986- # test if project exists
987- if self._project.mode == CTRL_CONST.PROJECT_LOADED :
988- # go in default mode before dispalying window
989- # due to webcam detection and avoid confilcts with acquisition
990- self._viewer.mode = self._viewer.DEFAULT
991-
992- # change control widget in no acquisition mode
993- self.__gui.control_widget.mode = GUI_CONST.ACQUISTION_INACTIVE
994-
995- # display message
996- self.__gui.status_bar.display_message(_('No Acquistion'))
997-
998- # launch project poperties window
999- _cbs = \
1000- {'change-project-properties' : self.on_change_project_properties}
1001- self.__gui.windows.project_properties(self._project.data, _cbs)
1002-
1003-
1004- def on_export_to_tool(self, *args) :
1005- """ Request export to tool """
1006- _args = self.__extract_signal_args(args)
1007- # test if project exists
1008- if self._project.mode == CTRL_CONST.PROJECT_LOADED :
1009- self.__gui.windows.export_tool(self._project.data)
1010-
1011-
1012- def on_export_to_video(self, *args) :
1013- """ Request export to video """
1014- _args = self.__extract_signal_args(args)
1015- # test if project exists
1016- if self._project.mode == CTRL_CONST.PROJECT_LOADED :
1017- self.__gui.windows.export_video(self._project.data)
1018-
1019-
1020- def on_import_image(self, *args) :
1021- """ Request image import """
1022- _args = self.__extract_signal_args(args)
1023- # check if project exists
1024- if self._project.mode == CTRL_CONST.PROJECT_LOADED :
1025- # open filename chooser dialog
1026- _filenames = self.__gui.windows.import_dialog()
1027-
1028- if _filenames != [] :
1029- _cbs = { 'done-import' : self.on_done_import}
1030- # start import controller
1031- CTRL_IMPORT.ImportController(_filenames,
1032- self._project.data,
1033- self.__rusher,
1034- self.__gui.status_bar,
1035- _cbs)
1036- else :
1037- _msg = _("No files or valid files choosen for image import.")
1038- self.__gui.windows.error_message( _msg)
1039- else :
1040- _msg = _("Impossible to import images when no project are loaded.")
1041- self.__gui.windows.error_message( _msg)
1042-
1043- def on_move_down_chrono(self, *args) :
1044- """ request to move down an image """
1045- _args = self.__extract_signal_args(args)
1046- if self._project.mode == CTRL_CONST.PROJECT_LOADED :
1047- self.__gui.treeviews[LCONST.CHRONO].move_down()
1048-
1049-
1050- def on_move_to_chrono(self, *args) :
1051- """ request for move imge from capture to chrono"""
1052- _args = self.__extract_signal_args(args)
1053- # get images to move from capture widget
1054- _images_name = self.__gui.treeviews[LCONST.CAPTURE].images_to_move()
1055- # append this images in chrono widget
1056- _images_obj = \
1057- [ self.__rusher.get_image(_image) for _image in _images_name ]
1058- for _image in _images_obj :
1059- self.__gui.treeviews[LCONST.CHRONO].append_image(_image)
1060-
1061-
1062- def on_move_up_chrono(self, *args) :
1063- """ request to move up an image """
1064- _args = self.__extract_signal_args(args)
1065- if self._project.mode == CTRL_CONST.PROJECT_LOADED :
1066- self.__gui.treeviews[LCONST.CHRONO].move_up()
1067-
1068-
1069-
1070-
1071-
1072- def on_play_query_position(self, *args) :
1073- """ Query for player position """
1074- _args = self.__extract_signal_args(args)
1075- (_position, _duration) = self._viewer.play_query_position()
1076- if _args['cb'] :
1077- # callback call to gui
1078- _args['cb'](_position, _duration)
1079-
1080-
1081- def on_play_video(self, *args) :
1082- """ Play video request """
1083- _args = self.__extract_signal_args(args)
1084- # test if project exists
1085- if self._project.mode == CTRL_CONST.PROJECT_LOADED :
1086- try :
1087- self._viewer.init_video_player(self._project.data)
1088- except LEXCEP.LucioException, _err_msg :
1089- raise LEXCEP.LucioException, _err_msg
1090- else :
1091- self._viewer.mode = self._viewer.PLAYER
1092- try :
1093- self._viewer.play_video(self._project.data)
1094- except LEXCEP.LucioException, _err_msg :
1095- raise LEXCEP.LucioException, _err_msg
1096- else :
1097- # send error message
1098- msg = _("Can not play animation : No project loaded")
1099- self.__gui.windows.error_message( msg)
1100-
1101-
1102- def on_quit_app(self, *args) :
1103- """ Request quit application """
1104- _args = self.__extract_signal_args(args)
1105- if self._project.mode == CTRL_CONST.PROJECT_LOADED and \
1106- self._project.data['is_modified'] :
1107- _msg = _('Project modified. Save project before exit ?')
1108- _res = self.__gui.windows.question_message(_msg)
1109- # if response is not a bool : cancel clicked
1110- if isinstance(_res, bool) :
1111- if _res :
1112- # if True save project before exit
1113- self._project.save()
1114- GUI_CTRL.GuiController.quit()
1115- else :
1116- GUI_CTRL.GuiController.quit()
1117-
1118- def on_save_as_project(self, *args) :
1119- """ save as project request """
1120- _args = self.__extract_signal_args(args)
1121- if self._project.mode == CTRL_CONST.PROJECT_LOADED :
1122- _dir = self.__gui.windows.dir_chooser()
1123- if _dir != None :
1124- # set viewer in default mode due to project reload
1125- self._viewer.mode = self._viewer.DEFAULT
1126- try :
1127- self._project.save_as(_dir)
1128- except LEXCEP.LucioException, _err_msg :
1129- _msg = _('Impossible to save as project : %s' % _err_msg)
1130- self.__gui.windows.error_message(_msg)
1131- else :
1132- _msg = _('Project saved as %s' % \
1133- self._project.data['project_name'])
1134- self.__gui.status_bar.display_message(_msg)
1135-
1136-
1137- def on_save_project(self, *args) :
1138- """ save project request """
1139- _args = self.__extract_signal_args(args)
1140- if self._project.mode == CTRL_CONST.PROJECT_LOADED :
1141- try :
1142- self._project.save()
1143- except LEXCEP.LucioException, _err_msg :
1144- _msg = _('Impossible to save project : %s' % _err_msg)
1145- self.__gui.windows.error_message(_msg)
1146- else :
1147- _msg = _('Project %s saved' % \
1148- self._project.data['project_name'])
1149- self.__gui.status_bar.display_message(_msg)
1150- # update project name on Main bar
1151- self.__gui.set_program_bar(self._project.data['project_name'],
1152- self._project.data['is_modified'])
1153-
1154-
1155- def on_start_acquisition(self, *args ) :
1156- """Request for starting acqusisition """
1157- _args = self.__extract_signal_args(args)
1158- # check if a project is loaded
1159- if self._project.mode == CTRL_CONST.PROJECT_LOADED :
1160- self._viewer.mode = self._viewer.ACQUIRER
1161-
1162- # change control widget in acquisition mode
1163- self.__gui.control_widget.mode = GUI_CONST.ACQUISITION_ACTIVE
1164-
1165- else :
1166- _msg = \
1167- _(' Can not start acquisition when no project are loaded.')
1168- self.__gui.windows.error_message(_msg)
1169-
1170-
1171- def on_start_mixer(self, *args) :
1172- """ Request mixer start """
1173- _args = self.__extract_signal_args(args)
1174- # check if a project is loaded
1175- if self._project.mode == CTRL_CONST.PROJECT_LOADED :
1176- # switch to viewer with acqusisition and mixer
1177- self._viewer.mode = self._viewer.ACQUIRER_WITH_MIXER
1178- # change control widget in no acquisition mode
1179- self.__gui.control_widget.mode = \
1180- GUI_CONST.ACQUISITION_ACTIVE_WITH_MIXER
1181-
1182- # display message
1183- self.__gui.status_bar.display_message(_('Acquiring with mixer'))
1184- else :
1185- # robustness
1186- _msg = \
1187- _('No project are loaded.')
1188- self.__gui.windows.error_message(_msg)
1189-
1190-
1191-
1192- def on_stop_acquisition(self, *args) :
1193- """ Request to stop acquistion """
1194- _args = self.__extract_signal_args(args)
1195- # check if a project is loaded
1196- if self._project.mode == CTRL_CONST.PROJECT_LOADED :
1197- # switch to viewer default
1198- self._viewer.mode = self._viewer.DEFAULT
1199- # change control widget in no acquisition mode
1200- self.__gui.control_widget.mode = GUI_CONST.ACQUISTION_INACTIVE
1201-
1202- else :
1203- # robustness
1204- _msg = \
1205- _('No project are loaded.')
1206- self.__gui.windows.error_message(_msg)
1207-
1208- def on_stop_mixer(self, *args) :
1209- """ Request mixer stop """
1210- _args = self.__extract_signal_args(args)
1211- # check if a project is loaded
1212- if self._project.mode == CTRL_CONST.PROJECT_LOADED :
1213- # switch to viewer with acqusisition and mixer
1214- self._viewer.mode = self._viewer.ACQUIRER
1215- # change control widget in no acquisition mode
1216- self.__gui.control_widget.mode = \
1217- GUI_CONST.ACQUISITION_ACTIVE
1218-
1219- # display message
1220- self.__gui.status_bar.display_message(_('Acquiring'))
1221- else :
1222- # robustness
1223- _msg = \
1224- _('No project are loaded.')
1225- self.__gui.windows.error_message(_msg)
1226-
1227- def on_stop_video(self, *args) :
1228- """ Stop video request """
1229- _args = self.__extract_signal_args(args)
1230- try :
1231- self._viewer.stop_video()
1232- except LEXCEP.LucioException, _err_msg :
1233- raise LEXCEP.LucioException, _err_msg
1234- else :
1235- self._viewer.mode = self._viewer.DEFAULT
1236-
1237-
1238- def on_take_snapshot(self, *args) :
1239- """ take image snapshot request """
1240- _args = self.__extract_signal_args(args)
1241- if self._project.mode == CTRL_CONST.PROJECT_LOADED :
1242- self._viewer.take_snapshot()
1243- else :
1244- # robustness
1245- _msg = \
1246- _('No project are loaded.')
1247- self.__gui.windows.error_message(_msg)
1248-
1249- _msg = \
1250- _('No project are loaded.')
1251- self.__gui.windows.error_message(_msg)
1252-
1253-
1254- def on_view_image(self, *args) :
1255- """
1256- request image view/display :
1257- Mix image with stream if viewer mode is acquirer with mixer
1258- """
1259- _args = self.__extract_signal_args(args)
1260- #if mode is player does not allow image view
1261- if self._viewer.mode == self._viewer.PLAYER :
1262- pass
1263-
1264- # if mode is acquirer with mixer and image is from capture treeview :
1265- # mix image with acqusisition stream
1266- elif self._viewer.mode == self._viewer.ACQUIRER_WITH_MIXER \
1267- and _args['tv_type'] == LCONST.CAPTURE :
1268- self._viewer.mix_image_in_stream(_args['image'])
1269-
1270- # on other cases view image
1271- else :
1272- self._viewer.mode = self._viewer.IMAGER
1273- self._viewer.view_image(_args['image'])
1274-
1275- #change control widget in no acquisition mode
1276- if self.__gui.control_widget.mode in \
1277- ( GUI_CONST.ACQUISITION_ACTIVE,
1278- GUI_CONST.ACQUISITION_ACTIVE_WITH_MIXER) :
1279- self.__gui.control_widget.mode = GUI_CONST.ACQUISTION_INACTIVE
1280-
1281-
1282- def run(self) :
1283- """ main program ininite loop """
1284- # TODO :
1285- GUI_CTRL.GuiController.threads_enter()
1286- # before starting main loop check for
1287- # options given to application
1288-
1289- # load a project ?
1290- if self.__options.filename \
1291- and os.path.exists(self.__options.filename):
1292- # emit open project signal
1293- self.__gui.emit(
1294- "open-project", self.__options.filename)
1295-
1296- GUI_CTRL.GuiController.main_loop()
1297- GUI_CTRL.GuiController.threads_leave()
1298- self.logger.info("Leaving luciole")
1299- #
1300- # Callbacks from controller
1301- #
1302- def on_done_rush(self, rusher) :
1303- """ callback : when tush images are loaded """
1304- if rusher != None \
1305- and self._project.mode == CTRL_CONST.PROJECT_LOADED :
1306- # load treeviews
1307- # prepare data
1308- _app_data = {}
1309- _app_data['capture_images'] = self._project.data['capture_images']
1310- _app_data['chrono_images'] = self._project.data['chrono_images']
1311- _app_data['rush'] = rusher
1312-
1313- self.__gui.load_treeviews(_app_data)
1314-
1315- # init acquisition
1316- self._viewer.init_acquisition(self._project.data)
1317-
1318-
1319- # update fpi on gui and show it
1320- self.__gui.update_framerate(int(self._project.data['fpi']))
1321-
1322- # show project acquisition widgets
1323- self.__gui.control_widget.mode = GUI_CONST.ACQUISTION_INACTIVE
1324-
1325- # update project name on Main bar
1326- self.__gui.set_program_bar(self._project.data['project_name'],
1327- self._project.data['is_modified'])
1328-
1329- # finish project load (project aspect)
1330- self._project.finish_project_load()
1331-
1332- # store rusher
1333- self.__rusher = rusher
1334-
1335-
1336-
1337- def on_done_snapshot(self) :
1338- """
1339- callback : image snapshot is done.
1340- Now image can be processed into project
1341- """
1342- self._project.append_snapshot(self.__rusher, self._viewer.acquirer)
1343-
1344- def on_done_preferences(self , modified_options) :
1345- """ callback : preferences modified fome diaog """
1346- # update prefernces
1347- (_capture_trash, _ask_restart) = \
1348- self.__configurer.update_preferences(modified_options)
1349-
1350- # check if gui update is needed
1351- if isinstance(_capture_trash, bool) :
1352- self.__gui.capture_trash = _capture_trash
1353-
1354- if isinstance(_ask_restart, bool) and _ask_restart == True :
1355- _msg = \
1356- _('Please restart Luciole to take into account the new theme ')
1357- self.__gui.status_bar.display_message(_msg)
1358-
1359- def on_change_project_properties(self, key, key_webcam= None, data =None) :
1360- """ callback project change from properties window """
1361- # webcam_data field of project dictionaty is a dictionaty
1362- # Test if webcam data change key
1363- if key == 'webcam_data':
1364- # make a local copy of webcam_data
1365- webcam_dict = self._project.data['webcam_data']
1366- #test if webcam dict key exists
1367- if webcam_dict.has_key(key_webcam) :
1368- # update webcam key and call project change
1369- webcam_dict[key_webcam] = data
1370- self._project.change_project('webcam_data', webcam_dict)
1371-
1372- def on_done_import(self, image_objs = [] ) :
1373- """ callback : image import (rush generation) is done """
1374- if image_objs != [] :
1375- self._project.change_project( 'rush_images',
1376- self.__rusher.dump_image_name())
1377- # Not to be done in thread : interacts with gui
1378- for _image_obj in image_objs :
1379- self.__gui.append_capture(_image_obj)
1380-
1381-
1382-
1383- #
1384- # Error calbacks
1385- #
1386- def on_error(self, err_type, message) :
1387- """ Main error callback """
1388- _msg = _("error type : %s. %s" % (err_type, message))
1389- # Display error on log window
1390- self.logger.info(_msg)
1391- #
1392- # private methods
1393- #
1394- def __init_i18n(self) :
1395- """ intialize locales """
1396- _locale_path = LCONST.LOCALE_DIR
1397-
1398- # Init the list of languages to support
1399- _langs = []
1400- #Check the default locale
1401- _lc, _encoding = locale.getdefaultlocale()
1402- if (_lc):
1403- #If we have a default, it's the first in the list
1404- _langs = [_lc]
1405- # Now lets get all of the supported languages on the system
1406- _language = os.environ.get('LANGUAGE', None)
1407- _msg = "language : " , _language
1408- self.logger.debug(_msg)
1409- if (_language):
1410- # langage comes back something like en_CA:en_US:en_GB:en
1411- # on linuxy systems, on Win32 it's nothing, so we need to
1412- # split it up into a list
1413- _langs += _language.split(":")
1414- # Now add on to the back of the list the translations that we
1415- # know that we have, our defaults"""
1416- _langs += ["en_US"]
1417-
1418- # Now langs is a list of all of the languages that we are going
1419- # to try to use. First we check the default, then what the system
1420- # told us, and finally the 'known' list
1421- _msg = "locale path", _locale_path
1422- self.logger.debug(_msg)
1423-
1424- GUI_CTRL.GuiController.init_18n(_locale_path)
1425- #import gtk.glade
1426- #gtk.glade.bindtextdomain(LCONST.APP_NAME, _locale_path)
1427- #gtk.glade.textdomain(LCONST.APP_NAME)
1428-
1429- gettext.bindtextdomain(LCONST.APP_NAME, _locale_path)
1430- gettext.textdomain(LCONST.APP_NAME)
1431-
1432- # Get the language to use
1433- _lang = gettext.translation(LCONST.APP_NAME, _locale_path
1434- , languages=_langs, fallback = True)
1435- # Install the language, map _() (which we marked our
1436- # strings to translate with) to self.lang.gettext() which will
1437- # translate them."""
1438- global _
1439- _ = _lang.gettext
1440-
1441-
1442-
1443- #
1444- # static_method
1445- #
1446- @staticmethod
1447- def __extract_signal_args(args) :
1448- """
1449- extract the signals arguments :
1450- arfs is a tuple
1451- The first argument is the emitter object ( gobject)
1452- the second argument is a dict with all the parameter given
1453- to signal.
1454-
1455- The function returns the paramter dictionary
1456- """
1457- return args[1]
1458-
1459-
1460-if __name__ == '__main__' :
1461- X = LucioleController(sys.argv)
1462- X.run()
1463-
1464+
1465+
1466+
1467
1468
1469
1470=== modified file 'luciole/ctrl/ctrl_project.py'
1471--- luciole/ctrl/ctrl_project.py 2011-02-28 18:27:56 +0000
1472+++ luciole/ctrl/ctrl_project.py 2011-03-05 15:01:33 +0000
1473@@ -202,7 +202,7 @@
1474 self.warning("impossible to switch to acquisition mode (%s)",
1475 self._mode )
1476
1477- def timleline_mode(self) :
1478+ def timeline_mode(self) :
1479 """ activate timeline mode """
1480 if self._mode == 'ACQUISITION' :
1481 self.ctrl_acq.stop()
1482@@ -394,7 +394,11 @@
1483 """ import-image-done callback """
1484 self.debug("RX import-image-done : %s", images)
1485 if images != [] :
1486- self.emit('import-image-done', images)
1487+ # when image is imported is equivalent to a
1488+ # snapshot tajed, so snapshot-taken signal can
1489+ # be emited for each image :
1490+ for image in images :
1491+ self.ctrl_acq.emit('snapshot-taken',image )
1492
1493 # update project
1494 # get image names
1495@@ -402,6 +406,8 @@
1496 self.project.props['rush_images'].extend(_names)
1497 self.project.props['capture_images'].extend(_names)
1498 self.is_modified = True
1499+ self.debug(' rush images : %s', self.project.props['rush_images'])
1500+
1501 else :
1502 self.warning('No image imported')
1503
1504@@ -417,7 +423,7 @@
1505 self._old_mode = self._mode
1506 if self._mode == 'ACQUISITION' :
1507 # switch to TIMELINE to free the webcam
1508- self.timleline_mode()
1509+ self.timeline_mode()
1510
1511
1512 _properties = ProjectProperties(self.gui.main_window,
1513@@ -436,39 +442,18 @@
1514
1515
1516 def _start_project_load(self) :
1517-
1518-
1519 # start rusher controller
1520 _rush_ctrl = LRUSH.ControllerLoadRush( self.project,
1521 self.gui.status_bar )
1522- self._connect_to_rush(_rush_ctrl)
1523-
1524- # start acquirer controller
1525- if self.project.props['hardtype'] in \
1526- (LCONST.FAKE, LCONST.DVCAM, LCONST.WEBCAM ) :
1527- # start acquisition controller
1528- #self.acq_ctrl = CTRL_ACQ.CtrlAcq(self)
1529- self.debug('Acquirer Object loaded %s', self.ctrl_acq)
1530- else :
1531- # No acquisition (only import and timeline)
1532- self._mode = "TIMELINE"
1533-
1534- # start timeline controller
1535- #self.ctrl_tmln = CTRL_TMLN.CtrlTimeline(self)
1536-
1537-
1538- def _connect_to_rush(self, rush_ctrl) :
1539- rush_ctrl.connect('rush-loaded', self._rush_load_finish_cb)
1540-
1541- def _disconnect_from_rush(self, rush_ctrl) :
1542- rush_ctrl.disconnect_by_function( self._rush_load_finish_cb)
1543+ _rush_ctrl.connect('rush-loaded', self._rush_load_finish_cb)
1544+
1545
1546 def _rush_load_finish_cb(self, rush_ctrl, rush_obj) :
1547 self.debug(" Rush Load Finish :%s ", rush_obj.dump_image_name() )
1548 if rush_obj != None :
1549 self._terminate_project_load(rush_obj)
1550 # Load rush is done only one time at load so disconnect it
1551- self._disconnect_from_rush(rush_ctrl)
1552+ rush_ctrl.disconnect_by_function( self._rush_load_finish_cb)
1553
1554 def _terminate_project_load(self, rush_obj) :
1555 self.project.rush = rush_obj
1556@@ -506,11 +491,15 @@
1557
1558 def _acquirer_ready_cb(self, ctrl_acq ) :
1559 self.debug('RX acquirer-ready signal')
1560- # TODO : work around on mode
1561- # FIXME : set to image to force transtion to acquisition mode
1562- # default mode when project is started
1563- self._mode = 'IMAGE_VIEW'
1564- self.acquisition_mode()
1565+ if self.project.props['hardtype'] in \
1566+ (LCONST.FAKE, LCONST.DVCAM, LCONST.WEBCAM ) :
1567+
1568+
1569+ # TODO : work around on mode
1570+ # FIXME : set to image to force transtion to acquisition mode
1571+ # default mode when project is started
1572+ self._mode = 'IMAGE_VIEW'
1573+ self.acquisition_mode()
1574
1575
1576
1577@@ -518,15 +507,20 @@
1578 self.error(msg)
1579
1580 def _connect_to_timeline(self, ctrl_tmln) :
1581- ctrl_tmln.connect('timeline-loaded', self._timeline_loaded_cb)
1582+ ctrl_tmln.connect('timeline-ready', self._timeline_ready_cb)
1583
1584 def _disconnect_from_timeline(self, ctrl_tmln) :
1585 ctrl_tmln.disconnect_from_project(self)
1586 ctrl_tmln.disconnect_by_function(self._timeline_loaded_cb)
1587
1588- def _timeline_loaded_cb(self, ctrl_tmln):
1589- pass
1590- #self.project.timeline = timeline
1591+ def _timeline_ready_cb(self, ctrl_tmln):
1592+ if self.project.props['hardtype'] == LCONST.DIGICAM :
1593+ # TODO : work around on mode
1594+ # FIXME : set to image to force transtion to acquisition mode
1595+ # default mode when project is started
1596+ self._mode = 'IMAGE_VIEW'
1597+ self.timeline_mode()
1598+
1599
1600
1601 def _copy_to_image2mix(self, image_name) :
1602
1603=== modified file 'luciole/ctrl/ctrl_timeline.py'
1604--- luciole/ctrl/ctrl_timeline.py 2011-02-28 12:58:02 +0000
1605+++ luciole/ctrl/ctrl_timeline.py 2011-03-05 15:01:33 +0000
1606@@ -430,7 +430,8 @@
1607
1608 class ProjectModeTimeline(ProjectMode):
1609 __signals__ = {
1610- 'timeline-loaded' : ['timeline'] ,
1611+ 'timeline-ready' : [],
1612+ 'timeline-error' : ['msg'] ,
1613 'sound-props-changed' : ['active', 'stop_with_video'],
1614 }
1615
1616@@ -755,18 +756,24 @@
1617 self.error(
1618 'Sound track active but no sound file present (%s)' %
1619 _sound_track)
1620-
1621- # discover the factories
1622- closure = {"rediscovered": 0}
1623- discoverer = self.sources.discoverer
1624- discoverer.connect("discovery-done", self._discovererDiscoveryDoneCb,
1625+
1626+ if uris != [] :
1627+ # discover the factories
1628+ closure = {"rediscovered": 0}
1629+ discoverer = self.sources.discoverer
1630+ discoverer.connect("discovery-done", self._discovererDiscoveryDoneCb,
1631 _project, _image_duration, uris, closure)
1632- discoverer.connect("discovery-error", self._discovererDiscoveryErrorCb,
1633+ discoverer.connect("discovery-error", self._discovererDiscoveryErrorCb,
1634 _project, _image_duration, uris, closure)
1635
1636- # start discoverer
1637+ # start discoverer
1638
1639- self.sources.addUris(uris)
1640+ self.sources.addUris(uris)
1641+ else :
1642+ # Nothing to load. emit timeline ready
1643+ self.debug('Nothing to load. Emit timeline-ready')
1644+ self.emit('timeline-ready')
1645+ # TODO : check why to be done here
1646 self.default_duration = _image_duration
1647
1648
1649@@ -805,8 +812,8 @@
1650 stop_with_video = project['sound']['stop_with_video'])
1651
1652
1653- self.debug('Emit timeline-loaded')
1654- self.emit('timeline-loaded')
1655+ self.debug('Emit timeline-ready')
1656+ self.emit('timeline-ready')
1657
1658
1659
1660
1661=== modified file 'luciole/gui/actions.py'
1662--- luciole/gui/actions.py 2011-02-28 12:58:02 +0000
1663+++ luciole/gui/actions.py 2011-03-05 15:01:33 +0000
1664@@ -212,11 +212,14 @@
1665 self._MODES_SIGNALS = {
1666 self._MODE_ACQ : 'acquisition-mode',
1667 self._MODE_TIMELINE : 'timeline-mode', }
1668+ (self._MODE_ACQ_VAL, self._MODE_TIMELINE_VAL) = range(2)
1669 self._MODES_RADIO_ACTION = [
1670 (self._MODE_ACQ, gtk.STOCK_MEDIA_RECORD,
1671- '_Acqusition', '<Control>a', 'Acquisition Mode', 0),
1672+ '_Acqusition', '<Control>a', 'Acquisition Mode',
1673+ self._MODE_ACQ_VAL),
1674 (self._MODE_TIMELINE, gtk.STOCK_EXECUTE,
1675- '_Timeline', '<Control>t', 'Timeline Mode', 1)
1676+ '_Timeline', '<Control>t', 'Timeline Mode',
1677+ self._MODE_TIMELINE_VAL)
1678 ]
1679
1680 # treeview actions
1681@@ -690,13 +693,18 @@
1682 #self._action_groups['TIMELINE'].set_sensitive(False)
1683
1684 def _project_mode_changed_cb(self, ctrl, mode ):
1685+ self.debug('RX project-mode-changed')
1686+
1687 if mode == 'TIMELINE' :
1688 self._action_groups['TIMELINE'].set_sensitive(True)
1689 _list_actions = self._action_groups['TIMELINE'].list_actions()
1690-
1691+ # TODO : code unusefull for toogleAction
1692+ # keeped as example
1693+
1694 self.debug('Actions in TIMELINE group : %s', _list_actions
1695 )
1696 for _action in _list_actions :
1697+ # check if toggla actions are in this group
1698 if isinstance(_action, gtk.ToggleAction) :
1699 self.debug(' Action %s is sensitive :%s',
1700 _action.get_name(),
1701@@ -706,12 +714,24 @@
1702 self.debug(' widget is sensitive :%s',
1703 _wdg.get_property('sensitive'))
1704
1705-
1706+
1707
1708 self._action_groups['ACQUISITION'].set_sensitive(False)
1709+ # update mode action , if needed:
1710+ _action = self.get_action(self._MODE_TIMELINE)
1711+ _val = _action.get_current_value()
1712+ if _val != self._MODE_TIMELINE_VAL :
1713+ _action.set_active(True)
1714+
1715 elif mode == "ACQUISITION" :
1716 self._action_groups['TIMELINE'].set_sensitive(False)
1717 self._action_groups['ACQUISITION'].set_sensitive(True)
1718+
1719+ # update mode action , if needed:
1720+ _action = self.get_action(self._MODE_ACQ)
1721+ _val = _action.get_current_value()
1722+ if _val != self._MODE_TIMELINE_VAL :
1723+ _action.set_active(True)
1724
1725
1726

Subscribers

People subscribed via source and target branches

to all changes:
to status/vote changes: