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

« back to all changes in this revision

Viewing changes to pitivi/ui/mainwindow.py

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2011-05-26 15:29:58 UTC
  • mfrom: (3.1.20 experimental)
  • Revision ID: james.westby@ubuntu.com-20110526152958-90je1myzzjly26vw
Tags: 0.13.9.90-1ubuntu1
* Resynchronize on Debian
* debian/control:
  - Depend on python-launchpad-integration
  - Drop hal from Recommends to Suggests. This version has the patch applied
    to not crash without hal.
* debian/patches/01_lpi.patch:
  - launchpad integration  
* debian/rules:
  - Use gnome.mk so a translation template is built

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
1
2
# PiTiVi , Non-linear video editor
2
3
#
3
4
#       ui/mainwindow.py
29
30
import gobject
30
31
gobject.threads_init()
31
32
import gst
32
 
import gst.pbutils
33
33
from urllib import unquote
 
34
import webbrowser
34
35
 
35
36
try:
36
37
    import gconf
40
41
    HAVE_GCONF = True
41
42
 
42
43
from gettext import gettext as _
 
44
from gtk import RecentManager
43
45
 
44
46
from pitivi.log.loggable import Loggable
45
47
 
46
48
from pitivi.ui.timeline import Timeline
47
 
from pitivi.ui.projecttabs import ProjectTabs
 
49
from pitivi.ui.basetabs import BaseTabs
48
50
from pitivi.ui.viewer import PitiviViewer
49
 
from pitivi.configure import pitivi_version, APPNAME, get_pixmap_dir, \
50
 
     get_global_pixmap_dir, LIBDIR
 
51
from pitivi.configure import pitivi_version, APPNAME, APPURL, APPMANUALURL, \
 
52
     get_pixmap_dir, LIBDIR
51
53
from pitivi.ui import dnd
52
54
from pitivi.pipeline import Pipeline
53
55
from pitivi.action import ViewAction
56
58
import pitivi.formatters.format as formatter
57
59
from pitivi.sourcelist import SourceListError
58
60
from pitivi.ui.sourcelist import SourceList
59
 
from pitivi.ui.common import beautify_factory
 
61
from pitivi.ui.effectlist import EffectList
 
62
from pitivi.ui.clipproperties import ClipProperties
 
63
from pitivi.ui.common import SPACING
 
64
from pitivi.ui.common import factory_name
60
65
from pitivi.utils import beautify_length
61
66
from pitivi.ui.zoominterface import Zoomable
62
67
 
79
84
    section="main-window",
80
85
    key="hpane-position",
81
86
    type_=int)
 
87
GlobalSettings.addConfigOption('mainWindowMainHPanePosition',
 
88
    section="main-window",
 
89
    key="main-hpane-position",
 
90
    type_=int)
82
91
GlobalSettings.addConfigOption('mainWindowVPanePosition',
83
92
    section="main-window",
84
93
    key="vpane-position",
118
127
    section='export',
119
128
    key='element-settings-dialog-height',
120
129
    default = 460)
 
130
GlobalSettings.addConfigSection("effect-configuration")
 
131
GlobalSettings.addConfigOption('effectVPanedPosition',
 
132
    section='effect-configuration',
 
133
    key='effect-vpaned-position',
 
134
    type_=int)
121
135
 
122
136
def supported(info):
123
137
    return formatter.can_handle_location(info[1])
179
193
        create_stock_icons()
180
194
        self._setActions(instance)
181
195
        self._createUi(instance)
 
196
 
182
197
        self.app = instance
 
198
        self.manager = RecentManager()
183
199
        self._zoom_duration_changed = False
 
200
        self._missingUriOnLoading = False
184
201
 
185
202
        self.app.projectManager.connect("new-project-loading",
186
203
                self._projectManagerNewProjectLoadingCb)
217
234
        else:
218
235
            self.webcam_button.set_sensitive(False)
219
236
 
220
 
        self.show()
221
 
 
222
237
    def showEncodingDialog(self, project, pause=True):
223
238
        """
224
239
        Shows the L{EncodingDialog} for the given project Timeline.
252
267
        self.actions = [
253
268
            ("NewProject", gtk.STOCK_NEW, None,
254
269
             None, _("Create a new project"), self._newProjectMenuCb),
255
 
            ("OpenProject", gtk.STOCK_OPEN, None,
 
270
            ("OpenProject", gtk.STOCK_OPEN, _("_Open..."),
256
271
             None, _("Open an existing project"), self._openProjectCb),
257
272
            ("SaveProject", gtk.STOCK_SAVE, None,
258
273
             None, _("Save the current project"), self._saveProjectCb),
259
 
            ("SaveProjectAs", gtk.STOCK_SAVE_AS, None,
 
274
            ("SaveProjectAs", gtk.STOCK_SAVE_AS, _("Save _As..."),
260
275
             None, _("Save the current project"), self._saveProjectAsCb),
261
276
            ("RevertToSavedProject", gtk.STOCK_REVERT_TO_SAVED, None,
262
 
             None, _("Reload the current project"), self._revertToSavedProjectCb),             
 
277
             None, _("Reload the current project"), self._revertToSavedProjectCb),
263
278
            ("ProjectSettings", gtk.STOCK_PROPERTIES, _("Project Settings"),
264
279
             None, _("Edit the project settings"), self._projectSettingsCb),
265
280
            ("RenderProject", 'pitivi-render' , _("_Render project"),
266
 
             None, _("Render project"), self._recordCb),
 
281
             None, _("Render project..."), self._recordCb),
267
282
            ("Undo", gtk.STOCK_UNDO,
268
283
             _("_Undo"),
269
284
             "<Ctrl>Z", _("Undo the last operation"), self._undoCb),
287
302
            ("Quit", gtk.STOCK_QUIT, None, None, None, self._quitCb),
288
303
            ("About", gtk.STOCK_ABOUT, None, None,
289
304
             _("Information about %s") % APPNAME, self._aboutCb),
 
305
            ("UserManual", gtk.STOCK_HELP, _("User manual"),
 
306
             None, None, self._userManualCb),
290
307
            ("File", None, _("_File")),
291
308
            ("Edit", None, _("_Edit")),
292
309
            ("View", None, _("_View")),
317
334
        self.actiongroup = gtk.ActionGroup("mainwindow")
318
335
        self.actiongroup.add_actions(self.actions)
319
336
        self.actiongroup.add_toggle_actions(self.toggleactions)
 
337
        self.undock_action = gtk.Action("WindowizeViewer", _("Undock Viewer"),
 
338
            _("Put the viewer in a separate window"), None)
 
339
        self.actiongroup.add_action(self.undock_action)
320
340
 
321
341
        # deactivating non-functional actions
322
342
        # FIXME : reactivate them
340
360
                action.set_visible(False)
341
361
            elif action_name in [
342
362
                "ProjectSettings", "Quit", "File", "Edit", "Help", "About",
343
 
                "View", "FullScreen", "FullScreenAlternate",
 
363
                "View", "FullScreen", "FullScreenAlternate", "UserManual",
344
364
                "ImportSourcesFolder", "PluginManager", "PlayPause",
345
365
                "Project", "FrameForward", "FrameBackward",
346
366
                "ShowHideMainToolbar", "ShowHideTimelineToolbar", "Library",
347
367
                "Timeline", "Viewer", "FrameForward", "FrameBackward",
348
368
                "SecondForward", "SecondBackward", "EdgeForward",
349
 
                "EdgeBackward", "Preferences"]:
 
369
                "EdgeBackward", "Preferences", "WindowizeViewer"]:
350
370
                action.set_sensitive(True)
351
371
            elif action_name in ["NewProject", "SaveProjectAs", "OpenProject"]:
352
372
                if instance.settings.fileSupportEnabled:
400
420
        self.timeline = Timeline(instance, self.uimanager)
401
421
        self.timeline.project = self.project
402
422
 
403
 
        vpaned.pack2(self.timeline, resize=False, shrink=False)
 
423
        vpaned.pack2(self.timeline, resize=True, shrink=False)
404
424
        self.timeline.show()
405
 
        hpaned = gtk.HPaned()
406
 
        vpaned.pack1(hpaned, resize=True, shrink=False)
407
 
        hpaned.show()
408
 
        self.projecttabs = ProjectTabs()
 
425
        self.mainhpaned = gtk.HPaned()
 
426
        vpaned.pack1(self.mainhpaned, resize=True, shrink=False)
 
427
 
 
428
        self.secondhpaned = gtk.HPaned()
 
429
        self.mainhpaned.pack1(self.secondhpaned, resize=True, shrink=False)
 
430
        self.secondhpaned.show()
 
431
        self.mainhpaned.show()
 
432
 
 
433
        self.projecttabs = BaseTabs(instance)
409
434
 
410
435
        self.sourcelist = SourceList(instance, self.uimanager)
411
436
        self.projecttabs.append_page(self.sourcelist, gtk.Label(_("Media Library")))
412
437
        self._connectToSourceList()
413
438
        self.sourcelist.show()
414
439
 
415
 
        hpaned.pack1(self.projecttabs, resize=True, shrink=False)
 
440
        self.effectlist = EffectList(instance, self.uimanager)
 
441
        self.projecttabs.append_page(self.effectlist, gtk.Label(_("Effect Library")))
 
442
        self.effectlist.show()
 
443
 
 
444
        self.secondhpaned.pack1(self.projecttabs, resize=True, shrink=False)
416
445
        self.projecttabs.show()
417
446
 
 
447
        # Actions with key accelerators that will be made unsensitive while
 
448
        # a gtk entry box is used to avoid conflicts.
 
449
        self.sensitive_actions = []
 
450
        for action in self.timeline.playhead_actions:
 
451
            self.sensitive_actions.append(action[0])
 
452
        for action in self.toggleactions:
 
453
            self.sensitive_actions.append(action[0])
 
454
 
 
455
        #Clips properties
 
456
        self.propertiestabs = BaseTabs(instance, True)
 
457
        self.clipconfig = ClipProperties(instance, self.uimanager)
 
458
        self.clipconfig.project = self.project
 
459
        self.propertiestabs.append_page(self.clipconfig,
 
460
                                        gtk.Label(_("Effects configurations")))
 
461
        self.clipconfig.show()
 
462
 
 
463
        self.secondhpaned.pack2(self.propertiestabs, resize= True, shrink=False)
 
464
        self.propertiestabs.show()
 
465
 
418
466
        # Viewer
419
 
        self.viewer = PitiviViewer()
 
467
        self.viewer = PitiviViewer(instance, undock_action=self.undock_action)
420
468
        # drag and drop
421
469
        self.viewer.drag_dest_set(gtk.DEST_DEFAULT_DROP | gtk.DEST_DEFAULT_MOTION,
422
470
                           [dnd.FILESOURCE_TUPLE, dnd.URI_TUPLE],
423
471
                           gtk.gdk.ACTION_COPY)
424
472
        self.viewer.connect("drag_data_received", self._viewerDndDataReceivedCb)
425
 
        hpaned.pack2(self.viewer, resize=False, shrink=False)
426
 
        self.viewer.show()
 
473
        self.mainhpaned.pack2(self.viewer, resize=False, shrink=False)
427
474
        self.viewer.connect("expose-event", self._exposeEventCb)
428
475
 
429
476
        # window and pane position defaults
430
 
        self.hpaned = hpaned
 
477
        self.mainhpaned = self.mainhpaned
 
478
        self.hpaned = self.secondhpaned
431
479
        self.vpaned = vpaned
432
480
        height = -1
433
481
        width = -1
434
482
        if self.settings.mainWindowHPanePosition:
435
483
            self.hpaned.set_position(self.settings.mainWindowHPanePosition)
 
484
        if self.settings.mainWindowMainHPanePosition:
 
485
            self.mainhpaned.set_position(self.settings.mainWindowMainHPanePosition)
436
486
        if self.settings.mainWindowVPanePosition:
437
487
            self.vpaned.set_position(self.settings.mainWindowVPanePosition)
438
488
        if self.settings.mainWindowWidth:
455
505
        vbox.pack_start(ttb, expand=False)
456
506
        ttb.show()
457
507
 
458
 
        self.show()
459
 
 
460
508
        if not self.settings.mainWindowShowMainToolbar:
461
509
            self.toolbar.props.visible = False
462
510
 
482
530
            self.viewer.window.unfullscreen()
483
531
            self.is_fullscreen = False
484
532
 
485
 
## PlayGround callback
486
 
 
487
 
    def _windowizeViewer(self, button, pane):
488
 
        # FIXME: the viewer can't seem to handle being unparented/reparented
489
 
        pane.remove(self.viewer)
490
 
        window = gtk.Window()
491
 
        window.add(self.viewer)
492
 
        window.connect("destroy", self._reparentViewer, pane)
493
 
        window.resize(200, 200)
494
 
        window.show_all()
495
 
 
496
 
    def _reparentViewer(self, window, pane):
497
 
        window.remove(self.viewer)
498
 
        pane.pack2(self.viewer, resize=False, shrink=False)
499
 
        self.viewer.show()
 
533
    #TODO check if it is the way to go
 
534
    def setActionsSensitive(self, action_names, sensitive):
 
535
        """
 
536
        Grab (or release) keyboard letter keys focus/sensitivity
 
537
        for operations such as typing text in an entry.
 
538
        @param action_names: The name of actions we
 
539
                             want to set to sensitive or not, if set to "default"
 
540
                             we use the default actions.
 
541
        @type action_names: A {list} of action names
 
542
        @param sensitive: %True if actions must be sensitive False otherwise
 
543
        @type action_names: C{Bool}
 
544
        """
 
545
        if action_names == "default":
 
546
            action_names = self.sensitive_actions
 
547
 
 
548
        for action in self.actiongroup.list_actions():
 
549
            if action.get_name() in action_names:
 
550
                action.set_sensitive(sensitive)
 
551
 
 
552
        if self.timeline:
 
553
            for action_group in self.timeline.ui_manager.get_action_groups():
 
554
                for action in action_group.list_actions():
 
555
                    if action.get_name() in action_names:
 
556
                        action.set_sensitive(sensitive)
500
557
 
501
558
## Missing Plugin Support
502
559
 
530
587
    def _saveWindowSettings(self):
531
588
        self.settings.mainWindowFullScreen = self.is_fullscreen
532
589
        self.settings.mainWindowHPanePosition = self.hpaned.get_position()
 
590
        self.settings.mainWindowMainHPanePosition = self.mainhpaned.get_position()
533
591
        self.settings.mainWindowVPanePosition = self.vpaned.get_position()
534
592
        mtb = self.actiongroup.get_action("ShowHideMainToolbar")
535
593
        ttb = self.actiongroup.get_action("ShowHideTimelineToolbar")
546
604
        self.app.projectManager.newBlankProject()
547
605
 
548
606
    def _openProjectCb(self, unused_action):
549
 
 
550
 
        chooser = gtk.FileChooserDialog(_("Open File..."),
551
 
            self,
552
 
            action=gtk.FILE_CHOOSER_ACTION_OPEN,
553
 
            buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
554
 
                gtk.STOCK_OPEN, gtk.RESPONSE_OK))
555
 
        chooser.set_icon_name("pitivi")
556
 
        chooser.set_select_multiple(False)
557
 
        chooser.set_current_folder(self.settings.lastProjectFolder)
558
 
        formats = formatter.list_formats()
559
 
        for format in formats:
560
 
            filt = gtk.FileFilter()
561
 
            filt.set_name(format[1])
562
 
            for ext in format[2]:
563
 
                filt.add_pattern("*%s" % ext)
564
 
            chooser.add_filter(filt)
565
 
        default = gtk.FileFilter()
566
 
        default.set_name(_("All Supported Formats"))
567
 
        default.add_custom(gtk.FILE_FILTER_URI, supported)
568
 
        chooser.add_filter(default)
569
 
 
570
 
        response = chooser.run()
571
 
        self.settings.lastProjectFolder = chooser.get_current_folder()
572
 
        if response == gtk.RESPONSE_OK:
573
 
            uri = chooser.get_uri()
574
 
            uri = unquote(uri)
575
 
            self.app.projectManager.loadProject(uri)
576
 
 
577
 
        chooser.destroy()
578
 
        return True
 
607
        self.openProject()
579
608
 
580
609
    def _saveProjectCb(self, unused_action):
581
610
        if not self.project.uri:
592
621
 
593
622
    def _revertToSavedProjectCb(self, unused_action):
594
623
        return self.app.projectManager.revertToSavedProject()
595
 
            
596
624
 
597
625
    def _projectSettingsCb(self, unused_action):
 
626
        self.showProjectSettingsDialog()
 
627
 
 
628
    def showProjectSettingsDialog(self):
598
629
        from projectsettings import ProjectSettingsDialog
599
630
        ProjectSettingsDialog(self, self.app.current).show()
600
631
 
616
647
        self.uimanager.get_widget("/TimelineToolBar").props.visible = \
617
648
            action.props.active
618
649
 
 
650
    def _userManualCb(self, unused_action):
 
651
        webbrowser.open_new (APPMANUALURL)
 
652
 
619
653
    def _aboutResponseCb(self, dialog, unused_response):
620
654
        dialog.destroy()
621
655
 
622
656
    def _showWebsiteCb(self, dialog, uri):
623
 
        import webbrowser
624
657
        webbrowser.open_new(uri)
625
658
 
626
659
    def _aboutCb(self, unused_action):
628
661
        abt.set_name(APPNAME)
629
662
        abt.set_version("v%s" % pitivi_version)
630
663
        gtk.about_dialog_set_url_hook(self._showWebsiteCb)
631
 
        abt.set_website("http://www.pitivi.org/")
 
664
        abt.set_website(APPURL)
632
665
        authors = ["Edward Hervey <bilboed@bilboed.com>",
633
666
                   "Alessandro Decina <alessandro.decina@collabora.co.uk>",
634
667
                   "Brandon Lewis <brandon_lewis@berkeley.edu> (UI)",
639
672
                   "Ernst Persson  <ernstp@gmail.com>",
640
673
                   "Richard Boulton <richard@tartarus.org>",
641
674
                   "Thibaut Girka <thibaut.girka@free.fr> (UI)",
642
 
                   "Jeff Fortin <nekohayo@gmail.com> (UI)",
 
675
                   "Jean-François Fortin Tam <nekohayo@gmail.com> (UI)",
643
676
                   "Johan Dahlin <jdahlin@async.com.br> (UI)",
644
677
                   "Luca Della Santina <dellasantina@farm.unipi.it>",
645
678
                   "Thijs Vermeir <thijsvermeir@gmail.com>",
652
685
        abt.connect("response", self._aboutResponseCb)
653
686
        abt.show()
654
687
 
 
688
    def openProject(self):
 
689
        chooser = gtk.FileChooserDialog(_("Open File..."),
 
690
            self,
 
691
            action=gtk.FILE_CHOOSER_ACTION_OPEN,
 
692
            buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
 
693
                gtk.STOCK_OPEN, gtk.RESPONSE_OK))
 
694
        chooser.set_icon_name("pitivi")
 
695
        chooser.set_select_multiple(False)
 
696
        chooser.set_current_folder(self.settings.lastProjectFolder)
 
697
        formats = formatter.list_formats()
 
698
        for format in formats:
 
699
            filt = gtk.FileFilter()
 
700
            filt.set_name(format[1])
 
701
            for ext in format[2]:
 
702
                filt.add_pattern("*%s" % ext)
 
703
            chooser.add_filter(filt)
 
704
        default = gtk.FileFilter()
 
705
        default.set_name(_("All Supported Formats"))
 
706
        default.add_custom(gtk.FILE_FILTER_URI, supported)
 
707
        chooser.add_filter(default)
 
708
 
 
709
        response = chooser.run()
 
710
        self.settings.lastProjectFolder = chooser.get_current_folder()
 
711
        if response == gtk.RESPONSE_OK:
 
712
            uri = chooser.get_uri()
 
713
            uri = unquote(uri)
 
714
            self.app.projectManager.loadProject(uri)
 
715
 
 
716
        chooser.destroy()
 
717
        return True
 
718
 
655
719
    def _undoCb(self, action):
656
720
        self.app.action_log.undo()
657
721
 
720
784
        self.render_button.set_sensitive(can_render)
721
785
        self._syncDoUndo(self.app.action_log)
722
786
 
 
787
        if self._missingUriOnLoading:
 
788
            self.app.current.setModificationState(True)
 
789
            self.actiongroup.get_action("SaveProject").set_sensitive(True)
 
790
            self._missingUriOnLoading = False
 
791
 
723
792
        if project.timeline.duration != 0:
724
 
            self._setBestZoomRatio()
 
793
            self.setBestZoomRatio()
725
794
        else:
726
795
            self._zoom_duration_changed = True
727
796
 
730
799
        # preliminary seek to ensure the project pipeline is configured
731
800
        self.project.seeker.seek(0)
732
801
 
733
 
    def _setBestZoomRatio(self):
 
802
    def setBestZoomRatio(self, p=0):
 
803
        """Set the zoom level so that the entire timeline is in view."""
734
804
        ruler_width = self.timeline.ruler.get_allocation()[2]
735
 
        timeline_duration = self.project.timeline.duration
 
805
        # Add gst.SECOND - 1 to the timeline duration to make sure the
 
806
        # last second of the timeline will be in view.
 
807
        timeline_duration = self.project.timeline.duration + gst.SECOND - 1
 
808
        timeline_duration_s = int(timeline_duration / gst.SECOND)
736
809
 
737
 
        ideal_zoom_ratio = ruler_width / float(timeline_duration / gst.SECOND)
 
810
        ideal_zoom_ratio = float(ruler_width) / timeline_duration_s
738
811
        nearest_zoom_level = Zoomable.computeZoomLevel(ideal_zoom_ratio)
739
812
        Zoomable.setZoomLevel(nearest_zoom_level)
740
813
 
741
814
    def _projectManagerNewProjectLoadingCb(self, projectManager, uri):
 
815
        if uri != None :
 
816
            self.manager.add_item(uri)
742
817
        self.log("A NEW project is being loaded, deactivate UI")
743
818
 
744
819
    def _projectManagerSaveProjectFailedCb(self, projectManager,
787
862
                "changes will be lost")
788
863
 
789
864
        # put the text in a vbox
790
 
        vbox = gtk.VBox(False, 12)
 
865
        vbox = gtk.VBox(False, SPACING*2)
791
866
        vbox.pack_start(primary, expand=True, fill=True)
792
867
        vbox.pack_start(secondary, expand=True, fill=True)
793
868
 
794
869
        # make the [[image] text] hbox
795
870
        image = gtk.image_new_from_stock(gtk.STOCK_DIALOG_WARNING,
796
871
               gtk.ICON_SIZE_DIALOG)
797
 
        hbox = gtk.HBox(False, 12)
 
872
        hbox = gtk.HBox(False, SPACING*2)
798
873
        hbox.pack_start(image, expand=False)
799
874
        hbox.pack_start(vbox, expand=True, fill=True)
800
875
        action_area = dialog.get_action_area()
801
 
        # FIXME: find out where this "6" comes from. It's needed to align our
802
 
        # hbox with the action area button box
803
 
        hbox.set_border_width(6)
 
876
        hbox.set_border_width(SPACING)
804
877
 
805
878
        # stuff the hbox in the dialog
806
879
        content_area = dialog.get_content_area()
807
880
        content_area.pack_start(hbox, expand=True, fill=True)
808
 
        content_area.set_spacing(14)
 
881
        content_area.set_spacing(SPACING*2)
809
882
        hbox.show_all()
810
883
 
811
884
        response = dialog.run()
843
916
                                        gtk.STOCK_REVERT_TO_SAVED, gtk.RESPONSE_YES)
844
917
            dialog.set_title(_("Revert to saved project"))
845
918
            dialog.set_resizable(False)
846
 
            dialog.set_property("secondary-text", 
 
919
            dialog.set_property("secondary-text",
847
920
                                            _("All unsaved changes will be lost.")
848
921
                                        )
849
922
            dialog.set_default_response(gtk.RESPONSE_NO)
852
925
            if response <> gtk.RESPONSE_YES:
853
926
                return False
854
927
        return True
855
 
        
 
928
 
856
929
 
857
930
    def _projectManagerNewProjectFailedCb(self, projectManager, uri, exception):
858
 
        # ungrey UI
 
931
        project_filename = unquote(uri.split("/")[-1])
859
932
        dialog = gtk.MessageDialog(self,
860
933
            gtk.DIALOG_MODAL,
861
934
            gtk.MESSAGE_ERROR,
862
935
            gtk.BUTTONS_OK,
863
 
            _("PiTiVi is unable to load file \"%s\"") %
864
 
                uri)
 
936
            _('Unable to load project "%s"') % project_filename)
865
937
        dialog.set_icon_name("pitivi")
866
938
        dialog.set_title(_("Error Loading File"))
867
 
        dialog.set_property("secondary-text", str(exception))
 
939
        dialog.set_property("secondary-text", unquote(str(exception)))
868
940
        dialog.run()
869
941
        dialog.destroy()
870
942
        self.set_sensitive(True)
876
948
            buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
877
949
            gtk.STOCK_OPEN, gtk.RESPONSE_OK))
878
950
        dialog.set_icon_name("pitivi")
879
 
        dialog.set_border_width(12)
880
 
        dialog.get_content_area().set_spacing(6)
 
951
        dialog.set_border_width(SPACING*2)
 
952
        dialog.get_content_area().set_spacing(SPACING)
881
953
 
882
 
        text = _("The following file has moved, please tell PiTiVi where to find it.") + \
883
 
            "\n\n" + beautify_factory(factory) + "\n" + \
884
 
            "<b>%s</b>" % _("Duration:") + beautify_length(factory.duration)
 
954
        text = _('The following file has moved: "<b>%s</b>" (duration: %s)\
 
955
                \nPlease specify its new location:' \
 
956
                % (factory_name(factory), beautify_length(factory.duration)))
 
957
        # TODO: display the filesize to help the user identify the file
885
958
 
886
959
        label = gtk.Label()
887
960
        label.set_markup(text)
888
 
        label.set_justify(gtk.JUSTIFY_CENTER)
889
961
        dialog.get_content_area().pack_start(label, False, False)
890
962
        label.show()
891
963
 
895
967
        dialog.get_content_area().pack_start(chooser, True, True)
896
968
        chooser.show()
897
969
 
898
 
        dialog.set_size_request(640, 480)
 
970
        # If the window is too big, the window manager will resize it so that
 
971
        # it fits on the screen.
 
972
        dialog.set_default_size(1024, 1000)
899
973
        response = dialog.run()
900
974
 
901
975
        if response == gtk.RESPONSE_OK:
902
 
            self.log("User chose a URI to save project to")
 
976
            self.log("User chose a new URI for the missing file")
903
977
            new = chooser.get_uri()
904
978
            if new:
905
979
                formatter.addMapping(uri, unquote(new))
 
980
                self._missingUriOnLoading = True
906
981
        else:
907
 
            self.log("User didn't choose a URI to save project to")
 
982
            self.log("User didn't choose a URI for the missing file")
908
983
            # FIXME: not calling addMapping doesn't keep the formatter from
909
984
            # re-emitting the same signal. How do we get out of this
910
985
            # situation?
966
1041
            self.project_timeline = self.project.timeline
967
1042
            if self.timeline:
968
1043
                self.timeline.project = self.project
 
1044
                self.clipconfig.project = self.project
 
1045
                self.app.timelineLogObserver.pipeline = self.project.pipeline
969
1046
 
970
1047
    project = receiver(_setProject)
971
1048
 
1012
1089
        if duration > 0:
1013
1090
            sensitive = True
1014
1091
            if self._zoom_duration_changed:
1015
 
                self._setBestZoomRatio()
 
1092
                self.setBestZoomRatio()
1016
1093
                self._zoom_duration_changed = False
1017
1094
        else:
1018
1095
            sensitive = False