~timo-jyrinki/ubuntu/trusty/pitivi/backport_utopic_fixes

« back to all changes in this revision

Viewing changes to pitivi/ui/clipproperties.py

  • Committer: Bazaar Package Importer
  • Author(s): Jeremy Bicha
  • Date: 2011-08-15 02:32:20 UTC
  • mfrom: (1.5.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20110815023220-x2n5l0i4deiqn7dn
Tags: 0.14.2-0ubuntu1
* New upstream version.
  - New Mallard format help
* debian/control:
  - Add gnome-doc-utils to build-depends
  - Bump pygtk minimum to 2.24
* debian/patches/01_lpi.patch
  - Move LPI items below User Manual in Help menu
* debian/watch: Watch for 0.14.* tar.bz2

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
import gtk
26
26
import pango
27
27
import dnd
 
28
import gst
 
29
import os
28
30
 
29
31
from gettext import gettext as _
30
32
 
34
36
 
35
37
from pitivi.ui.gstwidget import GstElementSettingsWidget
36
38
from pitivi.ui.effectsconfiguration import EffectsPropertiesHandling
 
39
from pitivi.ui.depsmanager import DepsManager
37
40
from pitivi.ui.common import PADDING, SPACING
38
 
from pitivi.ui import dynamic
 
41
from pitivi.configure import get_ui_dir
 
42
from pitivi.check import soft_deps
 
43
from pitivi.ui.effectlist import HIDDEN_EFFECTS
39
44
 
40
45
(COL_ACTIVATED,
41
46
 COL_TYPE,
49
54
    pass
50
55
 
51
56
 
52
 
class ClipProperties(gtk.VBox, Loggable):
 
57
class ClipProperties(gtk.ScrolledWindow, Loggable):
53
58
    """
54
59
    Widget for configuring clips properties
55
60
    """
56
61
 
57
62
    def __init__(self, instance, uiman):
58
 
        gtk.VBox.__init__(self)
 
63
        gtk.ScrolledWindow.__init__(self)
59
64
        Loggable.__init__(self)
60
65
 
 
66
        self.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
 
67
        self.set_shadow_type(gtk.SHADOW_NONE)
 
68
 
 
69
        vp = gtk.Viewport()
 
70
        vp.set_shadow_type(gtk.SHADOW_NONE)
 
71
        self.add(vp)
 
72
 
61
73
        self.app = instance
62
74
        self.settings = instance.settings
63
75
        self._project = None
 
76
        self.transformation_expander = None
64
77
        self.info_bar_box = gtk.VBox()
65
78
 
 
79
        vbox = gtk.VBox()
 
80
        vp.add(vbox)
 
81
 
66
82
        self.effect_properties_handling = EffectsPropertiesHandling(instance.action_log)
 
83
 
67
84
        self.effect_expander = EffectProperties(instance,
68
85
                                                self.effect_properties_handling,
69
86
                                                self)
70
87
 
71
 
        self.pack_start(self.info_bar_box, expand=False, fill=True)
72
 
        self.pack_end(self.effect_expander, expand=True, fill=True)
 
88
        vbox.pack_start(self.info_bar_box, expand=False, fill=True)
 
89
 
 
90
        self.transformation_expander = TransformationProperties(
 
91
            instance, instance.action_log)
 
92
        vbox.pack_start(self.transformation_expander, expand=False, fill=False)
 
93
        self.transformation_expander.show()
 
94
 
 
95
        vbox.pack_end(self.effect_expander, expand=True, fill=True)
 
96
        vbox.set_spacing(SPACING)
73
97
 
74
98
        self.info_bar_box.show()
75
99
        self.effect_expander.show()
 
100
        vbox.show()
 
101
        vp.show()
76
102
        self.show()
77
103
 
78
104
    def _setProject(self, project):
79
105
        self._project = project
80
106
        if project:
81
107
            self.effect_expander._connectTimelineSelection(self._project.timeline)
 
108
            if self.transformation_expander:
 
109
                self.transformation_expander.timeline = self._project.timeline
82
110
 
83
111
    def _getProject(self):
84
112
        return self._project
101
129
        return label, info_bar
102
130
 
103
131
 
104
 
class EffectProperties(gtk.HBox):
 
132
class EffectProperties(gtk.Expander, gtk.HBox):
105
133
    """
106
134
    Widget for viewing and configuring effects
107
135
    """
109
137
    # to put in ClipProperties, that is why this is done this way
110
138
 
111
139
    def __init__(self, instance, effect_properties_handling, clip_properties):
 
140
        gtk.Expander.__init__(self)
112
141
        gtk.HBox.__init__(self)
113
142
        #self.set_expanded(True)
114
143
 
205
234
        self.app.connect("new-project-loaded",
206
235
            self._newProjectLoadedCb)
207
236
 
208
 
        #self.connect('notify::expanded', self._expandedCb)
209
 
 
210
237
        self._table.attach(self.treeview_scrollwin, 0, 1, 2, 3)
211
238
 
212
239
        self._vcontent.pack1(self._table, resize=True, shrink=False)
213
240
        self._showInfoBar()
214
241
        self._vcontent.show()
 
242
        self.set_expanded(True)
 
243
        self.set_label("Effects configuration")
215
244
 
216
245
    def _newProjectLoadedCb(self, app, project):
217
246
        self.clip_properties.project = project
247
276
                timeline_object.connect("track-object-removed", self._trackRemovedRemovedCb)
248
277
        else:
249
278
            self.timeline_objects = []
 
279
            self.set_sensitive(False)
250
280
        self._updateAll()
251
281
 
252
282
    def  _trackObjectAddedCb(self, unused_timeline_object, track_object):
320
350
        track_effect.active = not track_effect.active
321
351
        self.app.action_log.commit()
322
352
 
323
 
    #def _expandedCb(self, expander, params):
324
 
    #    self._updateAll()
 
353
    def _expandedCb(self, expander, params):
 
354
        self._updateAll()
325
355
 
326
356
    def _treeViewQueryTooltipCb(self, treeview, x, y, keyboard_mode, tooltip):
327
357
        context = treeview.get_tooltip_context(x, y, keyboard_mode)
335
365
        return True
336
366
 
337
367
    def _updateAll(self):
338
 
        #if self.get_expanded():
339
 
        self._removeEffectBt.set_sensitive(False)
340
 
        if len(self.timeline_objects) == 1:
341
 
            self._setEffectDragable()
342
 
            self._updateTreeview()
343
 
            self._updateEffectConfigUi()
 
368
        if self.get_expanded():
 
369
            self._removeEffectBt.set_sensitive(False)
 
370
            if len(self.timeline_objects) == 1:
 
371
                self._setEffectDragable()
 
372
                self._updateTreeview()
 
373
                self._updateEffectConfigUi()
 
374
            else:
 
375
                self._hideEffectConfig()
 
376
                self.storemodel.clear()
 
377
                self._showInfoBar()
 
378
            self._vcontent.show()
344
379
        else:
345
 
            self._hideEffectConfig()
346
 
            self.storemodel.clear()
347
 
            self._showInfoBar()
348
 
        self._vcontent.show()
349
 
        #else:
350
 
        #    self._vcontent.hide()
 
380
            self._vcontent.hide()
351
381
 
352
382
    def _activeChangedCb(self, unusedObj, unusedActive):
353
383
        self._updateTreeview()
355
385
    def _updateTreeview(self):
356
386
        self.storemodel.clear()
357
387
        for track_effect in self.selected_effects:
358
 
            to_append = [track_effect.gnl_object.get_property("active")]
359
 
            track_effect.gnl_object.connect("notify::active",
360
 
                                            self._activeChangedCb)
361
 
            if isinstance(track_effect.factory.getInputStreams()[0],
362
 
                          VideoStream):
363
 
                to_append.append("Video")
364
 
            else:
365
 
                to_append.append("Audio")
366
 
 
367
 
            to_append.append(track_effect.factory.getHumanName())
368
 
            to_append.append(track_effect.factory.getDescription())
369
 
            to_append.append(track_effect)
370
 
 
371
 
            self.storemodel.append(to_append)
 
388
            if not track_effect.factory.effectname in HIDDEN_EFFECTS:
 
389
                to_append = [track_effect.gnl_object.get_property("active")]
 
390
                track_effect.gnl_object.connect("notify::active",
 
391
                                                self._activeChangedCb)
 
392
                if isinstance(track_effect.factory.getInputStreams()[0],
 
393
                              VideoStream):
 
394
                    to_append.append("Video")
 
395
                else:
 
396
                    to_append.append("Audio")
 
397
 
 
398
                to_append.append(track_effect.factory.getHumanName())
 
399
                to_append.append(track_effect.factory.getDescription())
 
400
                to_append.append(track_effect)
 
401
 
 
402
                self.storemodel.append(to_append)
372
403
 
373
404
    def _showInfoBar(self):
374
405
        if self._info_bar is None:
379
410
        self.txtlabel.show()
380
411
        self._info_bar.show()
381
412
 
382
 
        self.treeview.set_sensitive(False)
 
413
        self.set_sensitive(False)
383
414
        self._table.show_all()
384
415
 
385
416
    def _setEffectDragable(self):
386
 
        self.treeview.set_sensitive(True)
 
417
        self.set_sensitive(True)
387
418
        self._table.show_all()
388
419
        self._info_bar.hide_all()
389
420
 
430
461
        if self._effect_config_ui:
431
462
            self._effect_config_ui.hide()
432
463
            self._effect_config_ui = None
 
464
 
 
465
 
 
466
class TransformationProperties(gtk.Expander):
 
467
    """
 
468
    Widget for viewing and configuring speed
 
469
    """
 
470
    __signals__ = {
 
471
        'selection-changed': []}
 
472
 
 
473
    def __init__(self, app, action_log):
 
474
        gtk.Expander.__init__(self)
 
475
        self.action_log = action_log
 
476
        self.app = app
 
477
        self._timeline = None
 
478
        self._current_tl_obj = None
 
479
        self.spin_buttons = {}
 
480
        self.default_values = {}
 
481
        self.set_label(_("Transformation configuration"))
 
482
        self.set_sensitive(False)
 
483
 
 
484
        if not "Frei0r" in soft_deps:
 
485
            self.builder = gtk.Builder()
 
486
            self.builder.add_from_file(os.path.join(get_ui_dir(),
 
487
                        "cliptransformation.ui"))
 
488
 
 
489
            self.add(self.builder.get_object("transform_box"))
 
490
            self.show_all()
 
491
            self._initButtons()
 
492
        self.connect('notify::expanded', self._expandedCb)
 
493
 
 
494
    def _initButtons(self):
 
495
        self.zoom_scale = self.builder.get_object("zoom_scale")
 
496
        self.zoom_scale.connect("value-changed", self._zoomViewerCb)
 
497
        clear_button = self.builder.get_object("clear_button")
 
498
        clear_button.connect("clicked", self._defaultValuesCb)
 
499
 
 
500
        self._getAndConnectToEffect("xpos_spinbtn", "tilt_x")
 
501
        self._getAndConnectToEffect("ypos_spinbtn", "tilt_y")
 
502
 
 
503
        self._getAndConnectToEffect("width_spinbtn", "scale_x")
 
504
        self._getAndConnectToEffect("height_spinbtn", "scale_y")
 
505
 
 
506
        self._getAndConnectToEffect("crop_left_spinbtn", "clip_left")
 
507
        self._getAndConnectToEffect("crop_right_spinbtn", "clip_right")
 
508
        self._getAndConnectToEffect("crop_top_spinbtn", "clip_top")
 
509
        self._getAndConnectToEffect("crop_bottom_spinbtn", "clip_bottom")
 
510
        self.connectSpinButtonsToFlush()
 
511
 
 
512
    def _zoomViewerCb(self, scale):
 
513
        self.app.gui.viewer.setZoom(scale.get_value())
 
514
 
 
515
    def _expandedCb(self, expander, params):
 
516
        if not "Frei0r" in soft_deps:
 
517
            if self._current_tl_obj:
 
518
                self.effect = self._findOrCreateEffect("frei0r-filter-scale0tilt")
 
519
                self._updateSpinButtons()
 
520
                self.set_expanded(self.get_expanded())
 
521
                self._updateBoxVisibility()
 
522
                self.zoom_scale.set_value(1.0)
 
523
        else:
 
524
            if self.get_expanded():
 
525
                DepsManager(self.app)
 
526
            self.set_expanded(False)
 
527
 
 
528
    def _defaultValuesCb(self, widget):
 
529
        self.disconnectSpinButtonsFromFlush()
 
530
        for name, spinbtn in self.spin_buttons.items():
 
531
            spinbtn.set_value(self.default_values[name])
 
532
        self.app.gui.viewer.pipeline.flushSeekVideo()
 
533
        self.connectSpinButtonsToFlush()
 
534
        self.track_effect.gnl_object.props.active = False
 
535
 
 
536
    def disconnectSpinButtonsFromFlush(self):
 
537
        for spinbtn in self.spin_buttons.values():
 
538
            spinbtn.disconnect_by_func(self._flushPipeLineCb)
 
539
 
 
540
    def connectSpinButtonsToFlush(self):
 
541
        for spinbtn in self.spin_buttons.values():
 
542
            spinbtn.connect("output", self._flushPipeLineCb)
 
543
 
 
544
    def _updateSpinButtons(self):
 
545
        for name, spinbtn in self.spin_buttons.items():
 
546
            spinbtn.set_value(self.effect.get_property(name))
 
547
 
 
548
    def _getAndConnectToEffect(self, widget_name, property_name):
 
549
        spinbtn = self.builder.get_object(widget_name)
 
550
        spinbtn.connect("output",
 
551
                        self._onValueChangedCb, property_name)
 
552
        self.spin_buttons[property_name] = spinbtn
 
553
        self.default_values[property_name] = spinbtn.get_value()
 
554
 
 
555
    def _onValueChangedCb(self, spinbtn, prop):
 
556
        value = spinbtn.get_value()
 
557
 
 
558
        if value != self.default_values[prop] and not self.track_effect.gnl_object.props.active:
 
559
            self.track_effect.gnl_object.props.active = True
 
560
 
 
561
        if value != self.effect.get_property(prop):
 
562
            self.action_log.begin("Transformation property change")
 
563
            self.effect.set_property(prop, value)
 
564
            self.action_log.commit()
 
565
        box = self.app.gui.viewer.internal.box
 
566
 
 
567
        # update box when values are changed in the spin boxes,
 
568
        # so no point is selected
 
569
        if box and box.clicked_point == 0:
 
570
            box.update_from_effect(self.effect)
 
571
 
 
572
    def _flushPipeLineCb(self, widget):
 
573
        self.app.gui.viewer.pipeline.flushSeekVideo()
 
574
 
 
575
    def _findEffect(self, name):
 
576
        for track_effect in self._current_tl_obj.track_objects:
 
577
            if isinstance(track_effect, TrackEffect):
 
578
                if name in track_effect.getElement().get_path_string():
 
579
                        self.track_effect = track_effect
 
580
                        return track_effect.getElement()
 
581
 
 
582
    def _findOrCreateEffect(self, name):
 
583
        effect = self._findEffect(name)
 
584
        if not effect:
 
585
            factory = self.app.effects.getFactoryFromName(name)
 
586
            self.timeline.addEffectFactoryOnObject(factory, [self._current_tl_obj])
 
587
            effect = self._findEffect(name)
 
588
            # disable the effect on default
 
589
            self.track_effect.gnl_object.props.active = False
 
590
        self.app.gui.viewer.internal.set_transformation_properties(self)
 
591
        effect.freeze_notify()
 
592
        return effect
 
593
 
 
594
    def _selectionChangedCb(self, timeline):
 
595
        if self.timeline and len(self.timeline.selection.selected) > 0:
 
596
            for tl_obj in self.timeline.selection.selected:
 
597
                pass
 
598
 
 
599
            if tl_obj != self._current_tl_obj:
 
600
                self._current_tl_obj = tl_obj
 
601
                self.effect = None
 
602
 
 
603
            self.set_sensitive(True)
 
604
            if self.get_expanded():
 
605
                self.effect = self._findOrCreateEffect("frei0r-filter-scale0tilt")
 
606
                self._updateSpinButtons()
 
607
        else:
 
608
            if self._current_tl_obj:
 
609
                self._current_tl_obj = None
 
610
                self.zoom_scale.set_value(1.0)
 
611
                self.app.gui.viewer.pipeline.flushSeekVideo()
 
612
            self.effect = None
 
613
            self.set_sensitive(False)
 
614
        self._updateBoxVisibility()
 
615
 
 
616
    def _updateBoxVisibility(self):
 
617
        if self.get_expanded() and self._current_tl_obj:
 
618
            self.app.gui.viewer.internal.show_box()
 
619
        else:
 
620
            self.app.gui.viewer.internal.hide_box()
 
621
 
 
622
    def _getTimeline(self):
 
623
        return self._timeline
 
624
 
 
625
    def _setTimeline(self, timeline):
 
626
        self._timeline = timeline
 
627
        if timeline:
 
628
            self.timeline.connect('selection-changed', self._selectionChangedCb)
 
629
 
 
630
    timeline = property(_getTimeline, _setTimeline)