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

Proposed by NicoInattendu
Status: Merged
Approved by: NicoInattendu
Approved revision: 131
Merged at revision: 129
Proposed branch: lp:~nico-inattendu/luciole/bug_727165
Merge into: lp:luciole
Diff against target: 1177 lines (+331/-232)
8 files modified
luciole/ctrl/ctrl_acq.py (+9/-5)
luciole/ctrl/ctrl_project.py (+66/-41)
luciole/gui/windows/assistant_new_project.py (+7/-6)
luciole/gui/windows/dialog_project_properties.py (+14/-7)
luciole/gui/windows/webcam_detection_widget.py (+84/-162)
test/test_assistant_new_project.py (+6/-1)
test/test_project_properties.py (+21/-10)
test/test_webcam_detection_widget.py (+124/-0)
To merge this branch: bzr merge lp:~nico-inattendu/luciole/bug_727165
Reviewer Review Type Date Requested Status
NicoInattendu Pending
Review via email: mp+52663@code.launchpad.net

Commit message

fix for bug #727165. ow on assistant and webcam properties window, the webcam playback is activated, in viewer window. It's allow a preview of webcam parameters

Description of the change

Bug correction.
Now on assistant and webcam properties window, the webcam plauback is activated, in viewer window. It's allow a preview of webcam parameters

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/ctrl_acq.py'
2--- luciole/ctrl/ctrl_acq.py 2011-03-05 14:23:17 +0000
3+++ luciole/ctrl/ctrl_acq.py 2011-03-09 11:46:59 +0000
4@@ -33,7 +33,7 @@
5 import gst
6 from pitivi.signalgroup import SignalGroup
7 from pitivi.action import ViewAction
8-from pitivi.pipeline import Pipeline
9+from pitivi.pipeline import Pipeline, PipelineError
10
11 # local application/library specific imports
12 from luciole.media.lgst.webcam_factory import WebcamSourceFactory
13@@ -157,10 +157,14 @@
14 else :
15 #self._source_factory.active_mixer(False)
16 self._mode = "ACQUISITION"
17-
18- self._pipeline.play()
19- self.debug('send acquisition-started - mode : %s', self._mode)
20- self.emit('acquisition-started', with_mixer)
21+ try :
22+ self._pipeline.play()
23+ except PipelineError :
24+ self.warning('Fail to start pipeline')
25+ self._mode = "NO_ACQUISITION"
26+ else :
27+ self.debug('send acquisition-started - mode : %s', self._mode)
28+ self.emit('acquisition-started', with_mixer)
29
30
31 else :
32
33=== modified file 'luciole/ctrl/ctrl_project.py'
34--- luciole/ctrl/ctrl_project.py 2011-03-05 13:59:13 +0000
35+++ luciole/ctrl/ctrl_project.py 2011-03-09 11:46:59 +0000
36@@ -39,15 +39,11 @@
37 import luciole.base.exceptions as LEXCEP
38 import luciole.base.tools as LT
39 import luciole.constants as LCONST
40-import luciole.ctrl.constants as CTRL_CONST
41 import luciole.ctrl.ctrl_acq as CTRL_ACQ
42-import luciole.ctrl.ctrl_base as CTRL_BASE
43 import luciole.ctrl.ctrl_timeline as CTRL_TMLN
44 import luciole.ctrl.ctrl_no_project as CTRL_NO_PROJECT
45 import luciole.ctrl.ctrl_img_vw as CTRL_IMG_VW
46 import luciole.ctrl.load_rush as LRUSH
47-import luciole.gui.constants as GUI_CONST
48-import luciole.media.image as LI
49 import luciole.project.project_etree as LPF
50
51 from luciole.gui.windows.assistant_new_project import AssistantNewProject
52@@ -58,7 +54,7 @@
53 _NULL_TUPLE = None, None
54
55 class Project(object) :
56-
57+ """ Type class for project data """
58
59 def __init__(self) :
60 self.parser = LPF.ProjectToFile()
61@@ -69,6 +65,7 @@
62
63
64 def save(self, path) :
65+ """ save to xml file """
66 _project_path = None
67 if path is not None :
68 try :
69@@ -83,6 +80,9 @@
70 return _project_path
71
72 def set_non_pjt_dpdt_props(self) :
73+ """ set default valus for properties ,
74+ who are not stored in xml file
75+ """
76 # init props not managed by porject in file
77 self.props['is_modified'] = False
78 self.props['is-mixer-active'] = False
79@@ -90,7 +90,8 @@
80 self.props['alpha'] = LCONST.DEFAULT_ALPHA_IMAGE
81
82 class CtrlProject(Signallable, Loggable) :
83-
84+ """ High level class who manage a luciole project """
85+
86 # CONSTANTS
87 MODES = ("NO_PROJECT", "ACQUISITION", "TIMELINE", "IMAGE_VIEW", "EXPORT")
88 PROJECT_LOADED_MODES = ("ACQUISITION", "TIMELINE", "IMAGE_VIEW", "EXPORT")
89@@ -141,6 +142,7 @@
90 Loggable.__init__(self)
91
92 self._mode = None
93+ self._old_mode = None
94 self.gui = None
95 self.project = Project()
96
97@@ -154,6 +156,7 @@
98
99
100 def connect_to_gui(self, gui) :
101+ """ connect project controller with gui """
102 self.gui = gui
103
104 self.ctrl_acq.set_viewer(gui.drawarea)
105@@ -162,6 +165,7 @@
106 self.ctrl_img_vw.set_viewer(gui.drawarea)
107
108 def no_project_mode(self) :
109+ """ activate NO_PROJECT mode """
110 self.debug('No project mode')
111
112 if self._mode == 'ACQUISITION' :
113@@ -178,7 +182,7 @@
114
115
116 def acquisition_mode(self, force = False) :
117- """ activate acquisition mode """
118+ """ activate ACQUISITION mode """
119 self.debug('Acquisition mode')
120 if self._mode in self.PROJECT_LOADED_MODES \
121 and self._mode != 'ACQUISITION' :
122@@ -195,30 +199,34 @@
123
124 self.ctrl_acq.active_viewer()
125 self.ctrl_acq.start()
126- self.debug('Emit project-mode-changed : %s'%self._mode)
127- self.emit('project-mode-changed',self._mode)
128+ self.debug('Emit project-mode-changed : %s' % self._mode)
129+ self.emit('project-mode-changed', self._mode)
130
131 else :
132 self.warning("impossible to switch to acquisition mode (%s)",
133 self._mode )
134
135- def timeline_mode(self) :
136- """ activate timeline mode """
137+ def timeline_mode(self, force = False) :
138+ """ activate TIMELINE mode """
139+ self.debug('setting timeline mode')
140+
141 if self._mode == 'ACQUISITION' :
142 self.ctrl_acq.stop()
143
144- if self._mode in self.PROJECT_LOADED_MODES \
145- and self._mode != 'TIMELINE' :
146+ if (self._mode in self.PROJECT_LOADED_MODES \
147+ and self._mode != 'TIMELINE') \
148+ or (force == True) :
149
150 self._mode = 'TIMELINE'
151 self.ctrl_tmln.active_viewer()
152- self.debug('Emit project-mode-changed : %s'%self._mode)
153- self.emit('project-mode-changed',self._mode)
154+ self.debug('Emit project-mode-changed : %s' % self._mode)
155+ self.emit('project-mode-changed', self._mode)
156 else :
157 self.warning("impossible to switch to timeline mode")
158
159
160 def img_vw_mode(self, origin, image_name, position = 0) :
161+ """ activate IMAGE_VIEW mode """
162 if self._mode in self.PROJECT_LOADED_MODES :
163 if self._mode == 'ACQUISITION' :
164 self.ctrl_acq.stop()
165@@ -274,7 +282,7 @@
166 # close current project
167 self.close()
168
169- _ass = AssistantNewProject(self._new_project_cb)
170+ _ass = AssistantNewProject(self._new_project_cb, self.gui.drawarea)
171
172
173
174@@ -315,13 +323,14 @@
175 self.project = None
176
177 def save(self, dir_path = None ) :
178+ """ save project """
179 if self._mode not in self.PROJECT_LOADED_MODES :
180 self.error('invalid mode for save : %s'%self._mode)
181 return
182 if dir_path and not os.path.exists(dir_path) :
183 self.error('Path %s exists. Impossible to save project', dir_path)
184 return
185- self.debug("%s",dir_path)
186+ self.debug("%s", dir_path)
187 try :
188 _project_path = self.project.save(dir_path)
189 except LEXCEP.LucioException, _err_msg :
190@@ -332,10 +341,11 @@
191 if dir_path is not None and _project_path is not None :
192 # reload project is corretcly saved
193 self.close()
194- self.debug('Opening project with path %s',_project_path)
195+ self.debug('Opening project with path %s', _project_path)
196 self.open(_project_path)
197
198 def set_framerate(self, fpi, force = False) :
199+ """ set project framerate """
200 if self._mode != "TIMELINE" and force == False :
201 self.info('update of fpi only availabe in TIMELINE mode')
202 return
203@@ -347,18 +357,9 @@
204
205
206
207- def new(self, project_data = None) :
208-
209- # create new project
210-
211- if project_data :
212- # TODO case with assistant
213- pass
214-
215-
216-
217 def release(self) :
218-
219+ """ release project ctrl """
220+ # TODO : this fucntion seems unuseful : Ton analyse
221 # release signals between aquirer and project
222 if self.project.props['hardtype'] in \
223 (LCONST.FAKE, LCONST.DVCAM, LCONST.WEBCAM ) :
224@@ -374,12 +375,13 @@
225
226
227 def import_images(self, paths) :
228+ """ import images """
229 if self._mode not in self.PROJECT_LOADED_MODES :
230 self.error('invalid mode for import: %s'%self._mode)
231 return
232
233 if paths != [] :
234- self.debug('Starting image importer for %s',paths)
235+ self.debug('Starting image importer for %s', paths)
236 importer = ImportController( paths,
237 self.project.props,
238 self.project.rush,
239@@ -398,7 +400,7 @@
240 # snapshot tajed, so snapshot-taken signal can
241 # be emited for each image :
242 for image in images :
243- self.ctrl_acq.emit('snapshot-taken',image )
244+ self.ctrl_acq.emit('snapshot-taken', image )
245
246 # update project
247 # get image names
248@@ -419,7 +421,7 @@
249 if self._mode not in self.PROJECT_LOADED_MODES :
250 self.error('invalid mode for import: %s'%self._mode)
251 return
252- self.debug('%s',self.project.props)
253+ self.debug('%s', self.project.props)
254 self._old_mode = self._mode
255 if self._mode == 'ACQUISITION' :
256 # switch to TIMELINE to free the webcam
257@@ -427,21 +429,34 @@
258
259
260 _properties = ProjectProperties(self.gui.main_window,
261- self.project.props)
262+ self.project.props, self.gui.drawarea)
263 _properties.connect('project-changed', self._project_modified_cb)
264+ _properties.connect('dialog-closed', self._dialog_pp_closed_cb)
265 _properties.run()
266
267 def _project_modified_cb(self, dialog, project_data) :
268 """ callback for modified data from project properties dialog """
269 self.is_modified = True
270+
271+ def _dialog_pp_closed_cb(self, dialog) :
272+ """ dialog project properties closed callback """
273 if self._old_mode == 'ACQUISITION' :
274 # go back to acqusition mode
275 self.acquisition_mode(True)
276 self._old_mode = None
277+ if self._old_mode == 'TIMELINE' :
278+ # go back to acqusition mode
279+ # trick to force timeline mode reload
280+ self.timeline_mode(True)
281+ self._old_mode = None
282+
283
284
285
286 def _start_project_load(self) :
287+ """ start project load.
288+ i.e. execute project controller """
289+
290 # start rusher controller
291 _rush_ctrl = LRUSH.ControllerLoadRush( self.project,
292 self.gui.status_bar )
293@@ -449,6 +464,7 @@
294
295
296 def _rush_load_finish_cb(self, rush_ctrl, rush_obj) :
297+ """ image rush load finish callback """
298 self.debug(" Rush Load Finish :%s ", rush_obj.dump_image_name() )
299 if rush_obj != None :
300 self._terminate_project_load(rush_obj)
301@@ -456,13 +472,14 @@
302 rush_ctrl.disconnect_by_function( self._rush_load_finish_cb)
303
304 def _terminate_project_load(self, rush_obj) :
305+ """ terminate load of a project """
306 self.project.rush = rush_obj
307
308 # set project as not modified as it is just loaded
309 self.project.set_non_pjt_dpdt_props()
310
311 # set path for image to mix
312- self.project.props['image2mix'] =\
313+ self.project.props['image2mix'] = \
314 os.path.join(
315 self.project.props['project_dir'],
316 LCONST.IMAGE2MIX_NAME
317@@ -481,15 +498,18 @@
318 self.emit('project-loaded', self.project )
319
320 def _connect_to_acq(self , ctrl_acq) :
321+ """ connect to acqusision controller """
322 ctrl_acq.connect('acquirer-ready', self._acquirer_ready_cb)
323 ctrl_acq.connect('acquirer-error', self._acquirer_error_cb)
324
325 def _disconnect_from_acq(self , ctrl_acq) :
326+ """ disconnect from acqusision controller """
327 ctrl_acq.disconnect_by_function( self._acquirer_ready_cb)
328 ctrl_acq.disconnect_by_function( self._acquirer_error_cb)
329
330
331 def _acquirer_ready_cb(self, ctrl_acq ) :
332+ """ acquirer ready callback """
333 self.debug('RX acquirer-ready signal')
334 if self.project.props['hardtype'] in \
335 (LCONST.FAKE, LCONST.DVCAM, LCONST.WEBCAM ) :
336@@ -504,27 +524,32 @@
337
338
339 def _acquirer_error_cb(self, ctrl_acq, msg) :
340+ """ acquirer error callback """
341+ # TODO : implementation of acqusition errot
342+ # not corectly managed
343 self.error(msg)
344
345 def _connect_to_timeline(self, ctrl_tmln) :
346+ """ connect to timeline controller """
347 ctrl_tmln.connect('timeline-ready', self._timeline_ready_cb)
348
349 def _disconnect_from_timeline(self, ctrl_tmln) :
350+ """ discconnect from timeline controller """
351 ctrl_tmln.disconnect_from_project(self)
352- ctrl_tmln.disconnect_by_function(self._timeline_loaded_cb)
353+ ctrl_tmln.disconnect_by_function(self._timeline_ready_cb)
354
355 def _timeline_ready_cb(self, ctrl_tmln):
356+ """ timeline ready callback """
357+ self.debug('RX timeline-ready signal')
358 if self.project.props['hardtype'] == LCONST.DIGICAM :
359- # TODO : work around on mode
360- # FIXME : set to image to force transtion to acquisition mode
361- # default mode when project is started
362- self._mode = 'IMAGE_VIEW'
363- self.timeline_mode()
364+ # when digicam mode is set force timeline mode
365+ self.timeline_mode(True)
366
367
368
369 def _copy_to_image2mix(self, image_name) :
370-
371+ """ on directory, copy an image to image the image 2 mix path
372+ """
373 _source = os.path.join( self.project.props['project_dir'],
374 self.project.props['rush_dir'],
375 image_name)
376
377=== modified file 'luciole/gui/windows/assistant_new_project.py'
378--- luciole/gui/windows/assistant_new_project.py 2011-02-28 12:58:02 +0000
379+++ luciole/gui/windows/assistant_new_project.py 2011-03-09 11:46:59 +0000
380@@ -408,8 +408,8 @@
381 class PageWebcam(LWDW.WebcamDetectionWidget) :
382 """ Assistant page for webcam detection """
383
384- def __init__(self, assistant, project_data, *args ) :
385- LWDW.WebcamDetectionWidget.__init__(self, project_data, *args )
386+ def __init__(self, assistant, project_data, viewer_wdg, *args ) :
387+ LWDW.WebcamDetectionWidget.__init__(self, project_data, viewer_wdg, *args )
388 self.assistant = assistant
389
390 def webcam_detection_prepare(self, page) :
391@@ -517,8 +517,8 @@
392 """ Call back for 'selection-changed' signal """
393 _filename = widget.get_filename()
394 if _filename :
395- self.project_data['sound']['active'] = 'yes'
396- self.project_data['sound']['input_path'] = _filename
397+ self.project_data['sound']['active'] = 'yes'
398+ self.project_data['sound']['input_path'] = _filename
399
400
401
402@@ -650,9 +650,10 @@
403
404 __LUCIOLE_LOGO = os.path.join(LCONST.IMAGE_DIR,'luciole_logo.png')
405
406- def __init__(self, apply_callback) :
407+ def __init__(self, apply_callback, viewer_wdg) :
408 """ Initialize assistant window """
409 self.apply_callback = apply_callback
410+ self.viewer_wdg = viewer_wdg
411
412 #
413 # init project datas
414@@ -696,7 +697,7 @@
415 #
416 # configure page 3
417 #
418- self._pg3 = PageWebcam( self.assistant, self.project_data)
419+ self._pg3 = PageWebcam( self.assistant, self.project_data, self.viewer_wdg)
420 self.assistant.append_page(self._pg3)
421 self.assistant.set_page_title( self._pg3, _(' Webcam detection '))
422 self.assistant.set_page_type( self._pg3, gtk.ASSISTANT_PAGE_CONTENT)
423
424=== modified file 'luciole/gui/windows/dialog_project_properties.py'
425--- luciole/gui/windows/dialog_project_properties.py 2011-02-27 18:32:53 +0000
426+++ luciole/gui/windows/dialog_project_properties.py 2011-03-09 11:46:59 +0000
427@@ -53,6 +53,7 @@
428 """
429 __signals__ = {
430 'project-changed' : ['project'],
431+ 'dialog-closed' : [],
432 }
433
434 # This tow 2 tables descibes how to display project info
435@@ -130,7 +131,7 @@
436
437 _title = _('Project properties')
438
439- def __init__(self, main_window, project) :
440+ def __init__(self, main_window, project , viewer_wdg) :
441 """ create a Dialog with project properties and display it"""
442 Loggable.__init__(self)
443 Signallable.__init__(self)
444@@ -145,8 +146,8 @@
445 gtk.STOCK_APPLY, gtk.RESPONSE_APPLY
446 )
447 )
448- print self._dialog.vbox
449 self._project = project
450+ self._viewer_wdg = viewer_wdg
451 # keep framerate list and framerate selected those value can change
452 #self._framerate_selected = None
453 #self._framerate_list = None
454@@ -204,8 +205,9 @@
455 self._new_webcam_props != self._project['webcam_data'] :
456 self._project['webcam_data'].update(self._new_webcam_props)
457 self.emit('project-changed', self._project)
458-
459-
460+
461+ self.debug('emit dialog-closed signal')
462+ self.emit('dialog-closed')
463
464 def _cb_on_exit(self, widget, event) :
465 """ on exit callback """
466@@ -530,7 +532,10 @@
467
468 def on_button_webcam_clicked(self, widget) :
469 """ Button webcam clicked """
470- self._widget_webcam = WebcamDetectionDlg(self._dialog, self._cb_webcam_updated)
471+ self._widget_webcam = WebcamDetectionDlg(
472+ self._dialog,
473+ self._viewer_wdg,
474+ self._cb_webcam_updated)
475
476
477 def _cb_webcam_updated(self, webcam_props) :
478@@ -667,7 +672,7 @@
479 class WebcamDetectionDlg(gtk.MessageDialog, Loggable) :
480 """ Opens Dialog for webcam Detection """
481
482- def __init__(self, parent, cb_ok = None ) :
483+ def __init__(self, parent, viewer_wdg, cb_ok = None ) :
484 """ create a Dialog with project properties and display it
485 parent : The parent window
486 cb_ok : The callback when on button is clicked
487@@ -685,7 +690,9 @@
488 # detected data will be stored here
489 self.project_webcam = dict()
490
491- self.webcam_widget = LWDW.WebcamDetectionWidget(self.project_webcam)
492+ self.webcam_widget = \
493+ LWDW.WebcamDetectionWidget(self.project_webcam,
494+ viewer_wdg)
495 self.webcam_widget.connect('webcam-caps-selected',
496 self._webcam_caps_selected)
497 self.webcam_widget.connect('webcam-caps-selected',
498
499=== modified file 'luciole/gui/windows/webcam_detection_widget.py'
500--- luciole/gui/windows/webcam_detection_widget.py 2011-02-16 13:04:44 +0000
501+++ luciole/gui/windows/webcam_detection_widget.py 2011-03-09 11:46:59 +0000
502@@ -35,19 +35,13 @@
503 import gobject
504
505
506-import gst
507-
508-
509 from pitivi.log.loggable import Loggable
510 from pitivi.signalinterface import Signallable
511
512 # for test
513-from pitivi.encode import RenderSinkFactory, RenderFactory
514-from pitivi.action import RenderAction
515-from pitivi.factories.base import SinkFactory
516 from pitivi.pipeline import Pipeline
517-from pitivi.settings import StreamEncodeSettings, RenderSettings
518
519+from pitivi.action import ViewAction
520 # local application/library specific imports
521 import luciole.media.webcam_detect.webcam_detection as WBCM_DTCT
522
523@@ -55,6 +49,7 @@
524 from luciole.media.lgst.webcam_factory import WebcamSourceFactory
525
526 class WebcamField(Loggable, Signallable) :
527+ """ Manage webcam properties/fields """
528 __signals__ = {
529 'combo-changed' : ['field','value'],
530 }
531@@ -68,9 +63,10 @@
532 self._combo_idx = []
533 self._combo = None
534 self._range = None
535- self.widget = self._createUi()
536+ self.widget = self._create_ui()
537
538- def _createUi(self) :
539+ def _create_ui(self) :
540+ """ Gui widgetc creation """
541 _bbox = gtk.HBox()
542 _boxalign = gtk.Alignment(xalign=0.0, yalign=0.0)
543 _boxalign.add(_bbox)
544@@ -91,16 +87,18 @@
545 return _boxalign
546
547 def _create_combo(self, bbox) :
548+ """ create GUI combo box """
549 _combo = gtk.combo_box_new_text()
550 self.debug('create combobox for field %s', self.field_name)
551 for _idx, _value in enumerate(self.value) :
552 _combo.append_text(str(_value))
553 self._combo_idx.append(str(_value))
554- _combo.connect('changed', self.combobox_defintion_changed_cb)
555+ _combo.connect('changed', self._combobox_defintion_changed_cb)
556 bbox.pack_start(_combo, expand=False)
557 return _combo
558
559 def _create_range(self, bbox) :
560+ """ create GUI range """
561
562 _adj = gtk.Adjustment(
563 float(self.value[0]),
564@@ -115,19 +113,21 @@
565 _scale.set_value_pos(gtk.POS_RIGHT)
566 _scale.set_draw_value(True)
567 _scale.set_size_request(500, 500)
568- _scale.connect('value-changed', self.vscale_value_changed_cb)
569+ _scale.connect('value-changed', self._vscale_value_changed_cb)
570 bbox.pack_start(_scale, expand=True, fill = True )
571 return _scale
572
573- def combobox_defintion_changed_cb(self, widget) :
574-
575+ def _combobox_defintion_changed_cb(self, widget) :
576+ """ combobox change callback"""
577 self.emit('combo-changed', self.field_name, widget.get_active_text() )
578
579- def vscale_value_changed_cb(self, widget) :
580+ def _vscale_value_changed_cb(self, widget) :
581+ """ scale value changed callback"""
582 self.emit('combo-changed', self.field_name, widget.get_value() )
583
584
585 def set_active(self, value) :
586+ """ active values on combo """
587 if self._combo is not None :
588 try :
589 _idx = self._combo_idx.index(value)
590@@ -138,7 +138,7 @@
591
592
593 class WebcamPropsWdg(Loggable, Signallable) :
594- """ Webcam Properties """
595+ """ Webcam Properties widget """
596
597 __signals__ = {
598 'prop-changed' : ['prop','value'],
599@@ -158,46 +158,48 @@
600
601 parent_wdg.add(self._main_window)
602
603- self.prepare_ui()
604
605 # Show the window and all its children
606 self._main_window.show_all()
607
608-
609-
610- def prepare_ui(self) :
611- pass
612
613
614 def set_definitions(self, definitions) :
615+ """ set webcam definitions GUI prop"""
616 self.set_prop('definition', definitions)
617
618 def set_active_defintion(self, definition) :
619+ """ set webcam active definition GUI prop"""
620 _wdg = self.prop_widgets['definition']
621 _wdg.set_active(definition)
622
623
624 def set_videotypes(self, videotypes) :
625+ """ set webcam videotypes GUI prop"""
626 self.set_prop('videotype', videotypes)
627
628 def set_active_videotype(self, value) :
629+ """ set webcam active videotype GUI prop"""
630 self.set_active_prop('videotype', value)
631
632
633 def set_prop(self, prop, prop_values, wdg_type='combo' ) :
634+ """ set a webcam GUI prop. Generic method """
635 _wdg = WebcamField(prop, prop_values, wdg_type )
636 if isinstance(prop_values, list) :
637- _wdg.connect('combo-changed', self.combo_changed_cb)
638+ _wdg.connect('combo-changed', self._combo_changed_cb)
639 self.prop_widgets[prop] = _wdg
640 self._main_window.pack_start(_wdg.widget)
641 _wdg.widget.show_all()
642
643
644 def set_active_prop(self, prop, active_value):
645+ """ set a webcam active GUI prop. Generic method """
646 _wdg = self.prop_widgets[prop]
647 _wdg.set_active(active_value)
648
649 def remove_prop(self, prop) :
650+ """ remove a webcam property """
651 if prop in self.prop_widgets :
652
653 self.debug('remove prop %s', prop)
654@@ -207,20 +209,23 @@
655 del self.prop_widgets[prop]
656
657 def remove_all_props(self) :
658+ """ remove all properties """
659 _props = self.prop_widgets.keys()
660 for _prop in _props:
661 _wdg = self.prop_widgets.pop(_prop)
662 self._main_window.remove(_wdg.widget)
663- _wdg.disconnect_by_function(self.combo_changed_cb)
664+ _wdg.disconnect_by_function(self._combo_changed_cb)
665 self.debug("remove widget prop %s", _prop)
666
667
668- def combo_changed_cb(self, widget, prop, value) :
669+ def _combo_changed_cb(self, widget, prop, value) :
670+ """ combobox value changed callback """
671 self.debug('emit prop-changed : %s=%s', prop, value)
672 self.emit('prop-changed', prop, value)
673
674
675 def display_webcams(self, _webcams) :
676+ """ display detected webcams """
677 _wdg = WebcamField('webcam-name', _webcams)
678 if isinstance(_webcams, list) :
679 _wdg.connect('combo-changed', self._webcam_changed_cb)
680@@ -230,21 +235,15 @@
681 _wdg.widget.show_all()
682
683 def _webcam_changed_cb(self, widget, prop, value) :
684+ """ webcam selection callback """
685 self.debug('emit webcam-changed : %s=%s', prop, value)
686
687 self.emit('webcam-changed', value)
688
689
690-class FakeSinkFactory(SinkFactory):
691- def __init__(self, factoryname="fakesink", *args, **kwargs):
692- SinkFactory.__init__(self, *args, **kwargs)
693- self.__factoryname=factoryname
694-
695- def _makeBin(self, output_stream=None):
696- return gst.element_factory_make(self.__factoryname)
697-
698 class WebcamDetectionWidget(gtk.Frame, Loggable) :
699 """ Assistant page for webcam detection """
700+
701 __gsignals__ = {
702 'webcams-detected' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
703 (gobject.TYPE_PYOBJECT,)),
704@@ -260,12 +259,14 @@
705
706
707
708- def __init__(self, project_data, *args ) :
709+ def __init__(self, project_data, viewer, *args ) :
710 gtk.Frame.__init__(self, *args )
711- Signallable.__init__(self)
712 Loggable.__init__(self)
713 self.wcam_params = {}
714-
715+ self._viewer = viewer
716+ self.factory = None
717+ self.action = None
718+ self.pipeline = None
719 self.set_name('Page_webcam')
720 self.project_data = project_data
721
722@@ -306,57 +307,55 @@
723 self.info('No webcam detected')
724 self.emit('webcam-not-detetcted')
725
726+ def prepare_viewer(self, wcam_params) :
727+ """ prepare viewer and pipeline """
728+ self.debug('prepare pipeline/viewer start')
729
730- def active_webcam(self, device) :
731- if self.pipeline is not None :
732+ viewer = self._viewer
733+ if viewer.pipeline is not None :
734 try :
735- self.pipeline.pause()
736- self.render.deactivate()
737+ viewer.pause()
738 except :
739- pass
740-
741-
742+ self.warning('Impossible to pause viewer')
743 self.factory = WebcamSourceFactory()
744- self.debug("%s", self.wcam_params)
745- self.factory.webcam_params = self.wcam_params
746+ self.factory.webcam_params = wcam_params
747+ self.factory.with_scale = False
748+
749 self.pipeline = Pipeline()
750-
751- vsettings = StreamEncodeSettings(encoder="theoraenc")
752- rsettings = RenderSettings(settings=[vsettings],
753- muxer="oggmux")
754-
755- self.fakesink = FakeSinkFactory()
756- rendersink = RenderSinkFactory(RenderFactory(settings=rsettings),
757- self.fakesink)
758- self.render = RenderAction()
759- #self.pipeline.connect("eos", self._renderEOSCb)
760- #self.pipeline.connect("error", self._renderErrorCb)
761- self.pipeline.addAction(self.render)
762- self.render.addConsumers(rendersink)
763- self.render.addProducers(self.factory)
764- self.render.activate()
765- self.pipeline.play()
766- gobject.timeout_add(1000, self._deactive_pipeline)
767- return self.factory
768-
769- def _deactive_pipeline(self) :
770- self.debug('Deactive Pipeline')
771- if self.pipeline is not None :
772+ self.action = ViewAction()
773+ self.action.addProducers(self.factory)
774+ viewer.setPipeline(None)
775+ #viewer.showSlider()
776+
777+ # FIXME: why do I have to call viewer.setAction ?
778+ viewer.setAction(self.action)
779+ viewer.setPipeline(self.pipeline)
780+ viewer.play()
781+ self.debug('viewer started')
782+
783+ def release_viewer(self) :
784+ """ release pipeline for viewer"""
785+ self.debug(' release pipe %s', self.pipeline)
786+
787+ viewer = self._viewer
788+ if self.pipeline is None :
789+ self.debug('No pipeline to release')
790+ return
791+ if viewer.pipeline is not None :
792 try :
793- print " release ."
794- self.pipeline.stop()
795- self.render.deactivate()
796- self.render.setPipeline(None)
797- self.pipeline.release()
798- self.pipeline = None
799- self.factory = None
800-
801+ viewer.stop()
802 except :
803- pass
804- return False
805+ self.warning('Impossible to stop pipeline')
806+
807+ viewer.setPipeline(None)
808+ self.pipeline.release()
809+ self.pipeline = None
810+ self.factory = None
811+ self.action = None
812
813
814 def _webcam_changed_cb(self, wdg, webcam) :
815+ """ webcam selection changed callback """
816 self.debug('Rx webcam-changed : %s', webcam )
817 self.webcam_props.clear_all()
818 self.wcam_params = {}
819@@ -379,8 +378,8 @@
820 'device':_selected_device['device-file'],
821 }
822 }
823- _factory = self.active_webcam(self.wcam_params)
824- self.webcam_props.prepare(_factory.webcam_caps)
825+ self.prepare_viewer(self.wcam_params)
826+ self.webcam_props.prepare(self.factory.webcam_caps)
827
828
829 else :
830@@ -388,94 +387,17 @@
831
832
833 def _caps_selected_cb(self, webcam_props, caps) :
834+ """ webcam caps(propeties) selected callback """
835 self.project_data['webcam_data']['caps'] = caps
836+
837+ self.wcam_params['wcam_filter'] = {
838+ 'media_type' : caps,
839+ }
840+
841+ self.prepare_viewer(self.wcam_params)
842+
843 self.debug('Rx caps-selected : %s', caps.to_string() )
844 self.emit('webcam-caps-selected', caps)
845-
846-
847-
848-
849- def _on_webcam_detect_complete(self, webcam_obj) :
850- """ callback , executed when webcam detection is complete
851- Return the number of detected webcams"""
852- _status = 0
853-
854- if webcam_obj != None and webcam_obj.webcam_devices != None:
855- _vbox = self._vbox
856- # firt clean childs on the vbox widget
857- for _child in _vbox.get_children() :
858- _vbox.remove(_child)
859- # loop on detected webcams
860- _rd_btn = None
861-
862- for (_wbcm_idx, _webcam ) in \
863- enumerate(webcam_obj.webcam_devices) :
864- _rd_btn = gtk.RadioButton(
865- group =_rd_btn,
866- label = _webcam["name"] )
867- _vbox.pack_start(_rd_btn)
868- _rd_btn.show()
869-
870- #connect event
871- _rd_btn.connect(
872- "clicked",
873- self.on_webcam_radio_button_clicked,
874- _wbcm_idx,
875- webcam_obj )
876-
877- # First set
878- if _wbcm_idx == 0 :
879- # select by default.
880- self.project_data['webcam_data'] = \
881- webcam_obj.get_gst_best_input(_wbcm_idx)
882-
883- self.label.set_text(_('Detected webcam(s)'))
884- _status = len(webcam_obj.webcam_devices)
885- else :
886- self.project_data['webcam_data'] = None
887- self.label.set_text(_('No webcam detected'))
888- self.label.show()
889- return _status
890-
891- def on_webcam_radio_button_clicked(self, widget, webcam_index, webcam_obj):
892- """ callback for webcam rasdio button.
893- Save info on selected webcam
894- """
895- # when a webcam is selected select webcam data
896- self.project_data['webcam_data'] = \
897- webcam_obj.get_gst_best_input(webcam_index)
898-
899
900-if __name__ == '__main__' :
901- import pygtk
902-
903- def init_log() :
904- import os
905- from pitivi.log import log
906- enable_color = os.environ.get('PITIVI_DEBUG_NO_COLOR', '0') in ('', '0')
907- log.init('PITIVI_DEBUG', enable_color)
908
909- class Tester(Loggable) :
910-
911- def __init__(self) :
912- Loggable.__init__(self)
913- window = gtk.Window()
914- window.connect('destroy', lambda w: gtk.main_quit())
915- self.debug(' starting App')
916- _wdg = WebcamDetectionWidget(project_data = {})
917- _wdg.connect('webcams-detected',self._webcam_detected_cb)
918- window.add(_wdg)
919- window.show_all()
920-
921- _wdg.prepare_webcam_detection()
922-
923- return
924-
925- def _webcam_detected_cb(self, widget, data = None):
926- self.debug('Rx webcam detected %s', data)
927-
928- init_log()
929- Tester()
930- gtk.main()
931-
932
933
934=== modified file 'test/test_assistant_new_project.py'
935--- test/test_assistant_new_project.py 2011-02-25 08:17:16 +0000
936+++ test/test_assistant_new_project.py 2011-03-09 11:46:59 +0000
937@@ -42,6 +42,7 @@
938 # local application/library specific imports
939 from common import init_log
940
941+from pitivi.ui.viewer import PitiviViewer
942 #tested module
943 from luciole.gui.windows.assistant_new_project import AssistantNewProject
944
945@@ -49,6 +50,7 @@
946 PROJECT_PATH = '/home/nico/temp/testLuciole'
947
948 class Tester(Loggable) :
949+ """ Tester class """
950
951 def __init__(self) :
952 Loggable.__init__(self)
953@@ -56,10 +58,13 @@
954 gobject.threads_init()
955 window = gtk.Window()
956 window.connect('destroy', lambda w: gtk.main_quit())
957+
958+ self.ptv_viewer = PitiviViewer()
959+ window.add(self.ptv_viewer)
960 window.show_all()
961
962 # start assistant
963- _ass =AssistantNewProject(self._apply_cb)
964+ _ass =AssistantNewProject(self._apply_cb, self.ptv_viewer)
965 self.prepare_assistant(_ass)
966
967 def _apply_cb(self, project_data) :
968
969=== modified file 'test/test_project_properties.py'
970--- test/test_project_properties.py 2011-02-27 18:32:53 +0000
971+++ test/test_project_properties.py 2011-03-09 11:46:59 +0000
972@@ -22,12 +22,10 @@
973 #
974 #
975 """
976-test_assistant_new_project.py :
977- GTK assistant for creation of new projects
978+test_project_properties.py :
979+ Test project properties
980 """
981 # standard library imports
982-import os.path
983-import shutil
984
985 # related third party imports
986 import pygtk
987@@ -41,11 +39,11 @@
988
989 # local application/library specific imports
990 from common import init_log
991+from pitivi.ui.viewer import PitiviViewer
992
993 #tested module
994 from luciole.gui.windows.dialog_project_properties import ProjectProperties
995
996-import gst
997
998 CAPS_STR = ("video/x-raw-yuv, format=(fourcc)I420, width=(int)1280,"
999 "height=(int)1024, interlaced=(boolean)false,"
1000@@ -63,7 +61,6 @@
1001 'v4ldriver': 'v4l2src',
1002 'name': 'Built-in iSight'
1003 },
1004- 'project_name': 'test_luciole',
1005 'fpi': 5,
1006 'hardtype': 2,
1007 'resize' : 'no',
1008@@ -71,22 +68,36 @@
1009 }
1010
1011 class Tester(Loggable) :
1012-
1013+ """ Tester class """
1014+
1015 def __init__(self) :
1016 Loggable.__init__(self)
1017 self.debug('starting tester')
1018 gobject.threads_init()
1019 window = gtk.Window()
1020 window.connect('destroy', lambda w: gtk.main_quit())
1021+ self.ptv_viewer = PitiviViewer()
1022+ window.add(self.ptv_viewer)
1023+
1024 window.show_all()
1025 self.debug("project properties : %s", PROJECT_PROPS)
1026- _properties = ProjectProperties(window, PROJECT_PROPS)
1027+ _properties = ProjectProperties(window, PROJECT_PROPS, self.ptv_viewer)
1028 _properties.connect('project-changed', self._project_modified_cb)
1029+ _properties.connect('dialog-closed', self._dialog_pp_closed_cb)
1030 _properties.run()
1031
1032 def _project_modified_cb(self, gui, project_data) :
1033- self.debug('received aplly cb -- project_data =%s ; %r %r', project_data, project_data, PROJECT_PROPS )
1034-
1035+ """ callback for modified data from project properties dialog """
1036+ self.debug( ("received aplly cb"
1037+ "-- project_data =%s ; %r %r"),
1038+ project_data,
1039+ project_data,
1040+ PROJECT_PROPS)
1041+
1042+ def _dialog_pp_closed_cb(self, dialog) :
1043+ """ dialog project properties closed callback """
1044+ self.debug('dialog closed')
1045+ gtk.main_quit()
1046
1047
1048 if __name__ == '__main__' :
1049
1050=== added file 'test/test_webcam_detection_widget.py'
1051--- test/test_webcam_detection_widget.py 1970-01-01 00:00:00 +0000
1052+++ test/test_webcam_detection_widget.py 2011-03-09 11:46:59 +0000
1053@@ -0,0 +1,124 @@
1054+#!/usr/bin/env python
1055+# -*- coding: utf-8 -*-
1056+# -*- Mode: Python -*-
1057+# vim:si:ai:et:sw=4:sts=4:ts=4
1058+#
1059+# Copyright Nicolas Bertrand (nico@inattendu.org), 2009-2010
1060+#
1061+# This file is part of Luciole.
1062+#
1063+# Luciole is free software: you can redistribute it and/or modify
1064+# it under the terms of the GNU General Public License as published by
1065+# the Free Software Foundation, either version 3 of the License, or
1066+# (at your option) any later version.
1067+#
1068+# Luciole is distributed in the hope that it will be useful,
1069+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1070+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1071+# GNU General Public License for more details.
1072+#
1073+# You should have received a copy of the GNU General Public License
1074+# along with Luciole. If not, see <http://www.gnu.org/licenses/>.
1075+#
1076+#
1077+"""
1078+test_webcam_detection_widget.py :
1079+ test webcam detection widget
1080+"""
1081+# standard library imports
1082+
1083+# related third party imports
1084+import pygtk
1085+pygtk.require('2.0')
1086+import gtk
1087+import gobject
1088+import pygst
1089+pygst.require('0.10')
1090+
1091+from pitivi.log.loggable import Loggable
1092+from pitivi.action import ViewAction
1093+from pitivi.ui.viewer import PitiviViewer
1094+from pitivi.pipeline import Pipeline
1095+from pitivi.ui.viewer import PitiviViewer
1096+
1097+# local application/library specific imports
1098+from common import init_log
1099+
1100+#tested module
1101+from luciole.gui.windows.webcam_detection_widget import WebcamDetectionWidget
1102+from luciole.media.lgst.webcam_factory import WebcamSourceFactory
1103+
1104+class Tester(Loggable) :
1105+ """ Test class """
1106+
1107+ def __init__(self) :
1108+ Loggable.__init__(self)
1109+ self.debug('starting tester')
1110+ gobject.threads_init()
1111+ self.wcam_params = {}
1112+ self.factory = None
1113+
1114+ window = gtk.Window()
1115+ window.connect('destroy', lambda w: gtk.main_quit())
1116+ bbox = gtk.VBox()
1117+ boxalign = gtk.Alignment(xalign=0.5, yalign=0.5)
1118+ boxalign.add(bbox)
1119+
1120+ self.ptv_viewer = PitiviViewer()
1121+
1122+ # set webcam detection widget
1123+ self.project_data = {}
1124+ _wdg = WebcamDetectionWidget(self.project_data, self.ptv_viewer)
1125+ _wdg.connect('webcam-caps-selected', self._wcam_caps_selected)
1126+ _wdg.prepare_webcam_detection()
1127+ bbox.pack_start(_wdg)
1128+
1129+ bbox.pack_start(self.ptv_viewer, expand=False)
1130+
1131+
1132+ window.add(boxalign)
1133+
1134+ window.show_all()
1135+
1136+ def _wcam_caps_selected(self, wdg ,caps) :
1137+ self.debug('received webcam-caps-selected -- project_data =%s',
1138+ caps )
1139+
1140+ self.wcam_params['wcam_filter'] = {
1141+ 'media_type' : caps,
1142+ }
1143+
1144+ #self.prepare_viewer()
1145+
1146+ def prepare_viewer(self) :
1147+ viewer = self.ptv_viewer
1148+ if viewer.pipeline is not None :
1149+ try :
1150+ viewer.pause()
1151+ except :
1152+ pass
1153+ self.factory = WebcamSourceFactory()
1154+ self.factory.webcam_params = self.wcam_params
1155+ self.factory.with_scale = False
1156+
1157+ pipeline = Pipeline()
1158+ action = ViewAction()
1159+ action.addProducers(self.factory)
1160+ viewer.setPipeline(None)
1161+ viewer.showSlider()
1162+
1163+ # FIXME: why do I have to call viewer.setAction ?
1164+ viewer.setAction(action)
1165+ viewer.setPipeline(pipeline)
1166+ viewer.play()
1167+
1168+ return False
1169+
1170+
1171+
1172+if __name__ == '__main__' :
1173+ init_log()
1174+ Tester()
1175+ gtk.main()
1176+
1177+

Subscribers

People subscribed via source and target branches

to all changes:
to status/vote changes: