Changes of Revision 6

flowblade.changes Changed
x
 
1
@@ -1,4 +1,11 @@
2
 -------------------------------------------------------------------
3
+Wed Oct  4 23:03:03 UTC 2017 - avvissu@yandex.by
4
+
5
+- Update to 1.14:
6
+  * see /usr/share/doc/packages/flowblade/RELEASE_NOTES
7
+- Use python-gobject-Gdk instead of python-gobject
8
+
9
+-------------------------------------------------------------------
10
 Tue Mar 21 18:43:57 UTC 2017 - avvissu@yandex.by
11
 
12
 - Update to 1.12.2:
13
flowblade.spec Changed
26
 
1
@@ -17,7 +17,7 @@
2
 
3
 %define prjname Flowblade
4
 Name:           flowblade
5
-Version:        1.12.2
6
+Version:        1.14
7
 Release:        0
8
 Summary:        Multitrack non-linear video editor
9
 License:        GPL-3.0
10
@@ -36,7 +36,6 @@
11
 BuildRequires:  dbus-1-python
12
 BuildRequires:  python-cairo
13
 BuildRequires:  python-gnomevfs
14
-BuildRequires:  python-gobject
15
 BuildRequires:  python-imaging
16
 BuildRequires:  python-mlt
17
 BuildRequires:  python-numpy
18
@@ -48,6 +47,7 @@
19
 Requires:       libmlt6-modules
20
 Requires:       python-cairo
21
 Requires:       python-gnomevfs
22
+Requires:       python-gobject-Gdk
23
 Requires:       python-gobject
24
 Requires:       python-imaging
25
 Requires:       python-mlt
26
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/locale/ru/LC_MESSAGES/flowblade_old.po Deleted
201
 
1
@@ -1,5879 +0,0 @@
2
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
3
-# This file is distributed under the same license as the PACKAGE package.
4
-#
5
-# Николай Смольянинов <smolianinow.colya2016@yandex.ru>, 2017.
6
-msgid ""
7
-msgstr ""
8
-"Project-Id-Version: Flowblade\n"
9
-"Report-Msgid-Bugs-To: \n"
10
-"POT-Creation-Date: 2017-03-06 18:44+0200\n"
11
-"PO-Revision-Date: 2017-03-06 18:18+0300\n"
12
-"Last-Translator: Николай Смольянинов <smolianinow.colya2016@yandex.ru>\n"
13
-"Language-Team: Russian\n"
14
-"Language: ru_RU\n"
15
-"MIME-Version: 1.0\n"
16
-"Content-Type: text/plain; charset=UTF-8\n"
17
-"Content-Transfer-Encoding: 8bit\n"
18
-"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
19
-"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
20
-"X-Generator: Poedit 1.8.7.1\n"
21
-
22
-#: app.py:758
23
-msgid "Too small screen for this application."
24
-msgstr "Недостаточное разрешение экрана."
25
-
26
-#: app.py:761
27
-msgid "Minimum screen dimensions for this application are 1152 x 768.\n"
28
-msgstr "Разрешение экрана должно быть не ниже 1152 х 768.\n"
29
-
30
-#: app.py:762
31
-msgid "Your screen dimensions are "
32
-msgstr "Ваше разрешение экрана"
33
-
34
-#: app.py:795 projectaction.py:366 projectaction.py:696
35
-msgid "Project has not been saved previously"
36
-msgstr "Проект не был сохранён"
37
-
38
-#: app.py:796 projectaction.py:367 projectaction.py:697
39
-msgid "Save project with File -> Save As before closing."
40
-msgstr "Сохраните проект перед закрытием (Файл ⇨ Сохранить как...)."
41
-
42
-#: projectaction.py:111
43
-msgid "Media asset was missing!"
44
-msgstr "Недостающий медиа актив!"
45
-
46
-#: projectaction.py:112
47
-msgid "Path of missing asset:"
48
-msgstr "Путь недостающего актива"
49
-
50
-#: projectaction.py:113
51
-msgid ""
52
-"Relative search for replacement file in sub folders of project file failed."
53
-msgstr ""
54
-"Относительный поиск замены файла во вложеных папках файла проекта не удался."
55
-
56
-#: projectaction.py:114
57
-msgid "To load the project you will need to either:"
58
-msgstr "Для загрузки проекта требуется, либо:"
59
-
60
-#: projectaction.py:115
61
-msgid ""
62
-"Open project in 'Media Relinker' tool to relink media assets to new files, or"
63
-msgstr ""
64
-"Открытый проект в инструменте \"Медиа компоновщик\"  переупакует медиа-"
65
-"активы к новым файлам, или"
66
-
67
-#: projectaction.py:116
68
-msgid "Place a file with the same exact name and path on the hard drive"
69
-msgstr "Создать резервный файл с тем же именем и  содержанием"
70
-
71
-#: projectaction.py:117
72
-msgid "Open project in Media Relinker tool"
73
-msgstr "Открытый проект в Медиа компоновщике"
74
-
75
-#: projectaction.py:136
76
-msgid "Profile with Description: '"
77
-msgstr "Профиль с описанием: '"
78
-
79
-#: projectaction.py:136
80
-msgid "' was not found on load!"
81
-msgstr "' не найден при загрузке!"
82
-
83
-#: projectaction.py:137
84
-msgid ""
85
-"It is possible to load the project by creating a User Profile with exactly "
86
-"the same Description\n"
87
-"as the missing profile. "
88
-msgstr ""
89
-"Можно загрузить проект путём создания профиля с тем же содержанием, что было "
90
-"в отсутствующем\n"
91
-"профиле. "
92
-
93
-#: projectaction.py:138
94
-msgid "User Profiles can be created by selecting 'Edit->Profiles Manager'."
95
-msgstr ""
96
-"Профили пользователей могут быть созданы с помощью меню  \"Правка ⇨ Менеджер "
97
-"профилей\"."
98
-
99
-#: projectaction.py:145
100
-msgid "Opening"
101
-msgstr "Открывается"
102
-
103
-#: projectaction.py:276
104
-msgid "Media files already present in project were opened!"
105
-msgstr "Клипы уже присутствуют в проекте и были открыты!"
106
-
107
-#: projectaction.py:282
108
-msgid ""
109
-"Files already present:\n"
110
-"\n"
111
-msgstr ""
112
-"Файлы уже присутствуют:\n"
113
-"\n"
114
-
115
-#: projectaction.py:481
116
-msgid "Selected folder contains files"
117
-msgstr "Выбранная папка содержит файлы"
118
-
119
-#: projectaction.py:482
120
-msgid ""
121
-"When saving a back-up snapshot of the project, the selected folder\n"
122
-"has to be empty."
123
-msgstr ""
124
-"При сохранении резервной копии проекта, выбираемая папка\n"
125
-"должна быть пустой."
126
-
127
-#: projectaction.py:553
128
-msgid "Copying project media assets"
129
-msgstr "Копирование медиа-активов проекта"
130
-
131
-#: projectaction.py:554
132
-msgid "Saving project file"
133
-msgstr "Сохранение файла проекта"
134
-
135
-#: projectaction.py:709
136
-msgid "Project not found on disk"
137
-msgstr "Проект не найден"
138
-
139
-#: projectaction.py:710
140
-msgid "Project can't be loaded."
141
-msgstr "Невозможно загрузить проект"
142
-
143
-#: projectaction.py:718
144
-msgid "Project has not been saved since it was opened."
145
-msgstr "Открыт не сохранённый проект."
146
-
147
-#: projectaction.py:723
148
-msgid "Project was saved less than a minute ago."
149
-msgstr "Проект был сохранён менее минуты назад."
150
-
151
-#: projectaction.py:726
152
-msgid "Project was saved one minute ago."
153
-msgstr "Проект был сохранён минуту назад."
154
-
155
-#: projectaction.py:728
156
-msgid "Project was saved "
157
-msgstr "Проект был сохранён "
158
-
159
-#: projectaction.py:728
160
-msgid " minutes ago."
161
-msgstr " минут назад."
162
-
163
-#: projectaction.py:782
164
-msgid "Render launch failed!"
165
-msgstr "Не удалось запустить сборку!"
166
-
167
-#: projectaction.py:783 projectaction.py:797 tools/batchrendering.py:299
168
-msgid "Error message: "
169
-msgstr "Сообщение об ошибке:"
170
-
171
-#: projectaction.py:796
172
-msgid "Adding item to render queue failed!"
173
-msgstr "Не удалось добавить элемент в очередь!"
174
-
175
-#: projectaction.py:815
176
-msgid "Open.."
177
-msgstr "Открыть.."
178
-
179
-#: projectaction.py:845
180
-msgid "No file was selected"
181
-msgstr "Ничего не выбрано"
182
-
183
-#: projectaction.py:845
184
-msgid "Select a numbered file to add an Image Sequence to Project."
185
-msgstr ""
186
-"Выберите нумерованный файл для добавления последовательности изображений в "
187
-"проект."
188
-
189
-#: projectaction.py:853
190
-msgid "Not a sequence file!"
191
-msgstr "Нет последовательности файлов!"
192
-
193
-#: projectaction.py:853
194
-msgid ""
195
-"Selected file does not have a number part in it,\n"
196
-"so it can't be an image sequence file."
197
-msgstr ""
198
-"Выбранный файл содержит номера, \\ поэтому он не может быть файлом "
199
-"последовательности изображений."
200
-
201
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/res/help/resync.html Deleted
79
 
1
@@ -1,77 +0,0 @@
2
- <!DOCTYPE html>
3
-<html>
4
-<head>
5
-  <title>Clip Syncing</title>
6
-  <link rel="stylesheet" href="style.css">
7
-<script src="toc.js" type="text/javascript"></script>
8
-</head>
9
-
10
-<body>
11
-
12
-<div id="content">
13
-<img src="header_text_5.png" >
14
-
15
-<script src="tocgen.js"></script>
16
-
17
-<div id="toccontent">
18
-
19
-<div class="subject-header">Clip Syncing and Audio Split Editing</div>
20
-
21
-<p>
22
-In Flowblade Movie Editor you can <b>set a clip's positions to follow another clip's positions</b> on request.
23
-</p>
24
-
25
-
26
-<div id="toc"></div>
27
-
28
-<h3>Main points</h3>
29
-<ul>
30
-<li>Sync relations are set up by selecting a <b>Sync Parent Clip</b> for a <b>Sync Child Clip</b>.</li>
31
-<li><b>Only clips on track V1 can be Sync Parent Clips</b>. This is done to encourage edit style in which the main body of the Sequence is on track V1 and composites and audio split edits are done relative to the clip sequence on track V1.</li>
32
-<li><b>Sync feature helps preserve earlier work</b> an multitrack composites and audio split edits when clips are no longer in correct positions relative to each other, because of edits elsewhere on the Sequence.</li>
33
-<li><b>Resyncs are only done on request</b> to avoid jumping of clips on the timeline while editing. Explicit resyncs are also better from the point of view of avoiding side effects when doing edits.
34
-</li>
35
-</ul>
36
-<h3>Setting Sync Parent</h3>
37
-<ol>
38
-<li> Click <b>Right Mouse</b> on clip and select Select Sync Parent Clip... on any clip NOT on track V1.</li>
39
-<li> Cursor turns into a Target Cross. Click on clip on track V1 to select it as Sync Parent Clip.</li>
40
-<li> Sync Relation is established between the two clips. Cursor turns back into a default pointer.</li>
41
-<li> Sync State Stripe appers on the Sync Child Clip. Sync State Indicator Stripes on Clips:</li>
42
-<ul>
43
-<li> Green means that clip is in sync with parent.</li>
44
-<li> Red means that clip is NOT in sync with parent.</li>
45
-<li> Gray means that Sync Parent Clip is no longer on track V1.</li>
46
-</ul>
47
-</ol>
48
-
49
-<h3>Resyncing Sync Child Clips</h3>
50
-<ul>
51
-<li> Select <b>Edit -> Resync All to resync</b> from application menu all Sync Child Clips.</li>
52
-<li> Select <b>Edit - >Resync Selected to resync</b> from application menu selected Sync Child Clips.</li>
53
-<li> Click <b>Right Mouse</b> on Sync Child Clip and select <b>Resync</b> from popoup menu to resync single clip.</li>
54
-<li> Press <b>Resync Selected</b> Bbtton to resync selected Sync Child Clips.</li>
55
-</ul>
56
-
57
-<h3> Clearing Sync Parent Relations </h3>
58
-<ul>
59
-<li> Click <b>Right Mouse</b> on Sync Child Clip and select Clear Sync Relation.</li>
60
-</ul>
61
-
62
-<h3>Syncing Composited Clips</h3>
63
-<ul>
64
-<li> If appropriate set all clips that are part of a multitrack composite synched to the same clip.</li>
65
-</ul>
66
-
67
-<h3>Audio Split Syncing</h3>
68
-<ul>
69
-<li> Click <b>Right Mouse</b> on clip in track V1 and select Split Audio Synched.</li>
70
-<li> Edit audio split using Two Roll Trim mode to maintain sync with parent clip.</li>
71
-<li> Resync Audio as needed.</li>
72
-</ul>
73
-
74
-</div>
75
-</div>
76
-</body>
77
-
78
-</html> 
79
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/res/help/slow.html Deleted
48
 
1
@@ -1,46 +0,0 @@
2
- <!DOCTYPE html>
3
-<html>
4
-<head>
5
-  <title>Page Title</title>
6
-  <link rel="stylesheet" href="style.css">
7
-<script src="toc.js" type="text/javascript"></script>
8
-</head>
9
-
10
-<body>
11
-
12
-<div id="content">
13
-<img src="header_text_5.png" >
14
-
15
-<script src="tocgen.js"></script>
16
-
17
-<div id="toccontent">
18
-
19
-<div class="subject-header">Slow / Fast Motion </div>
20
-
21
-<div id="toc"></div>
22
-
23
-<p>
24
-In Flowblade motion effects are achived by <b>rendering slow / fast motion versions of video clips</b> and placing those on the timeline.
25
-</p>
26
-<h3> Creating Motion Clips </h3>
27
-<ol>
28
-<li> Right click on a Media File and select <b>Render Slow / Fast Motion File</b> from menu</li>
29
-<li>Edit parameters for the new motion Clip
30
-<ul>
31
-<li> Set speed</li>
32
-<li> Give name and location for motion Clip </li>
33
-<li> Select rendering parameters for motion Clip. It is probably a good idea to use a <b>lossless format</b> here to avoid any generational quality losses.</li>
34
-<li> Select render range, either:</li>
35
-<ul>
36
-<li> Full Source Clip</li>
37
-<li> From Source Clip Mark In to Mark Out</li>
38
-</ul>
39
-</ul>
40
-<li> Click <b>Render</b> button to create a new motion Clip</li>
41
-</ol>
42
-
43
-</div>
44
-</div>
45
-</body>
46
-
47
-</html> 
48
flowblade-1.12.2.tar.gz/README.md -> flowblade-1.14.tar.gz/README.md Changed
33
 
1
@@ -1,9 +1,7 @@
2
 
3
 ![Flowblade](flowblade-trunk/Flowblade/res/img/header_text.png "Flowblade")
4
 
5
-**NEW RELEASE 1.12 is out. Relesase notes [here](./flowblade-trunk/docs/RELEASE_NOTES.md).**
6
-
7
-**Installing instructions are available [here](./flowblade-trunk/docs/INSTALLING.md).**
8
+**Coming soon: Target date for release 1.14 further post-poned to August 6th 2017.**
9
 
10
 **Contents:**
11
   1. [Introduction](https://github.com/jliljebl/flowblade#introduction)
12
@@ -58,9 +56,9 @@
13
         
14
 # Releases
15
 
16
-**Latest release:** Flowblade Movie Editor 1.12 was released on March 2016.
17
+**Latest release:** Flowblade Movie Editor 1.12 was released on March 2017.
18
 
19
-**Next release:** Flowblade Movie Editor 1.12 will be out on August 2017.
20
+**Next release:** Flowblade Movie Editor 1.14 will be out on August 2017.
21
 
22
 # Installing Flowblade
23
 
24
@@ -95,7 +93,7 @@
25
 
26
 [The project webpage is here](http://jliljebl.github.io/flowblade/). 
27
 
28
-For questions and discussion on Flowblade we have a [Google+ group] (https://plus.google.com/u/0/communities/103860400113389238474) available. There will be some updates on what is happening with the project too.
29
+For questions and discussion on Flowblade we have a [Google+ group](https://plus.google.com/u/0/communities/103860400113389238474) available. There will be some updates on what is happening with the project too.
30
 
31
 Use the **Issues** tab to give bug reports or to make feature requests.
32
 
33
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/app.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/app.py Changed
105
 
1
@@ -83,6 +83,7 @@
2
 import respaths
3
 import resync
4
 import sequence
5
+import shortcuts
6
 import snapping
7
 import titler
8
 import tlinewidgets
9
@@ -94,6 +95,7 @@
10
 import updater
11
 import utils
12
 
13
+
14
 import jackaudio
15
 
16
 AUTOSAVE_DIR = appconsts.AUTOSAVE_DIR
17
@@ -175,7 +177,7 @@
18
         os.mkdir(user_dir + appconsts.TRIM_VIEW_DIR)
19
     if not os.path.exists(user_dir + appconsts.NATRON_DIR):
20
         os.mkdir(user_dir + appconsts.NATRON_DIR)
21
-        
22
+       
23
     # Set paths.
24
     respaths.set_paths(root_path)
25
 
26
@@ -195,6 +197,10 @@
27
     translations.load_filters_translations()
28
     mlttransitions.init_module()
29
 
30
+    # Apr-2017 - SvdB - Keyboard shortcuts
31
+    shortcuts.load_shortcut_files()
32
+    shortcuts.load_shortcuts()
33
+    
34
     # RHEL7/CentOS compatibility fix
35
     if gtk_version == "3.8.8":
36
         GObject.threads_init()
37
@@ -270,6 +276,7 @@
38
     gmic.test_availablity()
39
     toolnatron.init()
40
     toolsintegration.init()
41
+    #toolsintegration.test()
42
     
43
     # Create player object
44
     create_player()
45
@@ -327,7 +334,7 @@
46
             print "Launch assoc file:", assoc_file_path
47
             global assoc_timeout_id
48
             assoc_timeout_id = GObject.timeout_add(10, open_assoc_file)
49
-            
50
+       
51
     # Launch gtk+ main loop
52
     Gtk.main()
53
 
54
@@ -537,6 +544,8 @@
55
 
56
     proxyediting.set_menu_to_proxy_state()
57
 
58
+    undo.clear_undos()
59
+
60
     # Enable edit action GUI updates
61
     edit.do_gui_update = True
62
 
63
@@ -557,7 +566,6 @@
64
     audiowaveform.frames_cache = {}
65
 
66
     editorstate.project = new_project
67
-
68
     editorstate.media_view_filter = appconsts.SHOW_ALL_FILES
69
     
70
     # Inits widgets with project data
71
@@ -599,7 +607,7 @@
72
     gui.editor_window.handle_insert_move_mode_button_press()
73
     editorstate.trim_mode_ripple = False
74
 
75
-    #editorstate.project.c_seq.print_all()
76
+    updater.set_timeline_height()
77
         
78
 def change_current_sequence(index):
79
     stop_autosave()
80
@@ -624,6 +632,8 @@
81
     selection.select_path(str(selected_index))
82
     start_autosave()
83
 
84
+    updater.set_timeline_height()
85
+
86
 def display_current_sequence():
87
     # Get shorter alias.
88
     player = editorstate.player
89
@@ -750,6 +760,15 @@
90
         editorwindow.MONITOR_AREA_WIDTH = 400
91
         positionbar.BAR_WIDTH = 100
92
 
93
+    if editorpersistance.prefs.double_track_hights == True:
94
+        appconsts.TRACK_HEIGHT_NORMAL = 100 # track height in canvas and column
95
+        appconsts.TRACK_HEIGHT_SMALL = 50 # track height in canvas and column
96
+        appconsts.TRACK_HEIGHT_SMALLEST = 50 # maybe remove as it is no longer meaningful
97
+        appconsts.TLINE_HEIGHT = 520
98
+        sequence.TRACK_HEIGHT_NORMAL = appconsts.TRACK_HEIGHT_NORMAL # track height in canvas and column
99
+        sequence.TRACK_HEIGHT_SMALL = appconsts.TRACK_HEIGHT_SMALL # track height in canvas and column
100
+        tlinewidgets.set_tracks_double_height_consts()
101
+        
102
 def _too_small_screen_exit():
103
     global exit_timeout_id
104
     exit_timeout_id = GObject.timeout_add(200, _show_too_small_info)
105
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/appconsts.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/appconsts.py Changed
43
 
1
@@ -65,10 +65,11 @@
2
 PROP_FLOAT = 1
3
 PROP_EXPRESSION = 2
4
 
5
-# Display heights for tracks.
6
+# Display heights for tracks and timeline.
7
 TRACK_HEIGHT_NORMAL = 50 # track height in canvas and column
8
 TRACK_HEIGHT_SMALL = 25 # track height in canvas and column
9
 TRACK_HEIGHT_SMALLEST = 25 # maybe remove as it is no longer meaningful
10
+TLINE_HEIGHT = 260
11
 
12
 # Notebook widths
13
 NOTEBOOK_WIDTH = 600 # defines app min width with MONITOR_AREA_WIDTH
14
@@ -147,8 +148,8 @@
15
 THUMBNAILS_DIR = "thumbnails"
16
 RENDERED_CLIPS_DIR = "rendered_clips"
17
 GMIC_DIR = "gmic"
18
-NODE_COMPOSITORS_DIR = "node_compositors"
19
-PHANTOM_DISK_CACHE_DIR = "phantom_disk_cache"
20
+PHANTOM_DIR = "phantom2d"
21
+PHANTOM_DISK_CACHE_DIR = "disk_cache"
22
 MATCH_FRAME_DIR = "match_frame"
23
 MATCH_FRAME = MATCH_FRAME_DIR + "/match_frame.png"
24
 MATCH_FRAME_NEW = MATCH_FRAME_DIR + "/match_frame_new.png"
25
@@ -192,3 +193,17 @@
26
 SINGLE_WINDOW = 1
27
 TWO_WINDOWS = 2
28
 
29
+# Apr-2017 - SvdB
30
+SHORTCUTS_DEFAULT = 'Flowblade Default'
31
+SHORTCUTS_DEFAULT_XML = 'flowblade'
32
+SHORTCUTS_ROOT_TAG = 'flowblade'
33
+SHORTCUTS_TAG = 'shortcuts'
34
+
35
+# Project properties keys
36
+P_PROP_DISSOLVE_GROUP_FADE_IN = "P_PROP_DISSOLVE_GROUP_FADE_IN"
37
+P_PROP_DISSOLVE_GROUP_FADE_OUT = "P_PROP_DISSOLVE_GROUP_FADE_OUT"
38
+P_PROP_ANIM_GROUP_FADE_IN = "P_PROP_ANIM_GROUP_FADE_IN"
39
+P_PROP_ANIM_GROUP_FADE_OUT = "P_PROP_ANIM_GROUP_FADE_OUT"
40
+P_PROP_TLINE_SHRINK_VERTICAL = "tline_shrink_vertical"
41
+P_PROP_LAST_RENDER_SELECTIONS = "P_PROP_LAST_RENDER_SELECTIONS"
42
+P_PROP_TRANSITION_ENCODING = "P_PROP_TRANSITION_ENCODING"
43
flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/audiosync.py Added
201
 
1
@@ -0,0 +1,351 @@
2
+"""
3
+    Flowblade Movie Editor is a nonlinear video editor.
4
+    Copyright 2012 Janne Liljeblad.
5
+
6
+    This file is part of Flowblade Movie Editor <http://code.google.com/p/flowblade>.
7
+
8
+    Flowblade Movie Editor is free software: you can redistribute it and/or modify
9
+    it under the terms of the GNU General Public License as published by
10
+    the Free Software Foundation, either version 3 of the License, or
11
+    (at your option) any later version.
12
+
13
+    Flowblade Movie Editor is distributed in the hope that it will be useful,
14
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+    GNU General Public License for more details.
17
+
18
+    You should have received a copy of the GNU General Public License
19
+    along with Flowblade Movie Editor. If not, see <http://www.gnu.org/licenses/>.
20
+"""
21
+
22
+"""
23
+Application module.
24
+
25
+Handles application initialization, shutdown, opening projects, autosave and changing
26
+sequences.
27
+"""
28
+import datetime
29
+import md5
30
+import mlt
31
+import os
32
+import subprocess
33
+import sys
34
+import time
35
+import threading
36
+
37
+import gi
38
+gi.require_version('Gtk', '3.0')
39
+gi.require_version('PangoCairo', '1.0')
40
+from gi.repository import GLib
41
+from gi.repository import Gtk, Gdk, GdkPixbuf
42
+
43
+import appconsts
44
+import clapperless
45
+import dialogs
46
+import dialogutils
47
+import edit
48
+import editorpersistance
49
+import editorstate
50
+from editorstate import PROJECT
51
+from editorstate import current_sequence
52
+import gui
53
+import movemodes
54
+import projectaction
55
+import renderconsumer
56
+import respaths
57
+import tlinewidgets
58
+import updater
59
+import utils
60
+
61
+_tline_sync_data = None # Compound clip and tline clip sync functions can't pass the same data througn clapperless so 
62
+                         # we use this global to save data as needed for tline sync function.
63
+                         # The data flow is a bit haed to follow here, this needs tobe refactored.
64
+
65
+class ClapperlesLaunchThread(threading.Thread):
66
+    def __init__(self, video_file, audio_file, completed_callback):
67
+        threading.Thread.__init__(self)
68
+        self.video_file = video_file
69
+        self.audio_file = audio_file
70
+        self.completed_callback = completed_callback
71
+        
72
+    def run(self):
73
+        _write_offsets(self.video_file, self.audio_file, self.completed_callback)
74
+
75
+# ------------------------------------------------------- module funcs
76
+def _write_offsets(video_file_path, audio_file_path, completed_callback):
77
+    print "Starting clapperless analysis..."
78
+    fps = str(int(utils.fps() + 0.5))
79
+    idstr = _get_offset_file_idstr(video_file_path, audio_file_path)
80
+
81
+    FLOG = open(utils.get_hidden_user_dir_path() + "log_clapperless", 'w')
82
+    
83
+    # clapperless.py computes offsets and writes them to file clapperless.OFFSETS_DATA_FILE
84
+    p = subprocess.Popen([sys.executable, respaths.LAUNCH_DIR + "flowbladeclapperless", video_file_path, audio_file_path, "--rate", fps, "--idstr", idstr], stdin=FLOG, stdout=FLOG, stderr=FLOG)
85
+    p.wait()
86
+    
87
+    # Offsets are now available
88
+    GLib.idle_add(completed_callback, (video_file_path, audio_file_path, idstr))
89
+
90
+def _get_offset_file_idstr(file_1, file_2):
91
+    # Create unique file path in hidden render folder
92
+    folder = editorpersistance.prefs.render_folder
93
+    return md5.new(file_1 + file_2).hexdigest()
94
+    
95
+def _read_offsets(idstr):
96
+    offsets_file = utils.get_hidden_user_dir_path() + clapperless.OFFSETS_DATA_FILE + "_"+ idstr
97
+    with open(offsets_file) as f:
98
+        file_lines = f.readlines()
99
+    file_lines = [x.rstrip("\n") for x in file_lines]
100
+    
101
+    _files_offsets = {}
102
+    for line in file_lines:
103
+        tokens = line.split(" ")
104
+        _files_offsets[tokens[0]] = tokens[1]
105
+    
106
+    os.remove(offsets_file)
107
+
108
+    return _files_offsets
109
+
110
+
111
+# ------------------------------------------------------- tline audio sync
112
+def init_select_tline_sync_clip(popup_data):
113
+
114
+    clip, track, item_id, x = popup_data
115
+    frame = tlinewidgets.get_frame(x)
116
+    clip_index = current_sequence().get_clip_index(track, frame)
117
+
118
+    if not (track.clips[clip_index] == clip):
119
+        # This should never happen 
120
+        print "big fu at init_select_tline_sync_clip(...)"
121
+        return
122
+
123
+    gdk_window = gui.tline_display.get_parent_window();
124
+    gdk_window.set_cursor(Gdk.Cursor.new(Gdk.CursorType.TCROSS))
125
+    editorstate.edit_mode = editorstate.SELECT_TLINE_SYNC_CLIP
126
+
127
+    global _tline_sync_data
128
+    _tline_sync_data = TLineSyncData()
129
+    _tline_sync_data.origin_clip = clip
130
+    _tline_sync_data.origin_track = track
131
+    _tline_sync_data.origin_clip_index = clip_index
132
+    
133
+    
134
+def select_sync_clip_mouse_pressed(event, frame):
135
+    sync_clip = _get_sync_tline_clip(event, frame)
136
+
137
+    if sync_clip == None:
138
+        return # selection wasn't good
139
+    
140
+    if utils.is_mlt_xml_file(sync_clip.path) == True:
141
+        # This isn't translated because 1.14 translation window is close, translation coming for 1.16
142
+        dialogutils.warning_message("Cannot Timeline Audio Sync with Compound Clips!", 
143
+                                    "Audio syncing for Compound Clips is not supported.",
144
+                                    gui.editor_window.window,
145
+                                    True)
146
+        return
147
+
148
+    sync_track =  tlinewidgets.get_track(event.y)
149
+    sync_clip_index = sync_track.clips.index(sync_clip)
150
+
151
+    _tline_sync_data.sync_clip = sync_clip
152
+    _tline_sync_data.sync_track = sync_track
153
+    _tline_sync_data.sync_clip_index = sync_clip_index
154
+
155
+    # TImeline media offset for clips
156
+    sync_clip_start_in_tline = sync_track.clip_start(sync_clip_index)
157
+    _tline_sync_data.origin_clip_start_in_tline = _tline_sync_data.origin_track.clip_start(_tline_sync_data.origin_clip_index)
158
+    
159
+    _tline_sync_data.clip_tline_media_offset = (sync_clip_start_in_tline - sync_clip.clip_in) - (_tline_sync_data.origin_clip_start_in_tline - _tline_sync_data.origin_clip.clip_in)
160
+    
161
+    gdk_window = gui.tline_display.get_parent_window();
162
+    gdk_window.set_cursor(Gdk.Cursor.new(Gdk.CursorType.LEFT_PTR))
163
+    
164
+    # This or GUI freezes, we really can't do Popen.wait() in a Gtk thread
165
+    clapperless_thread = ClapperlesLaunchThread(_tline_sync_data.origin_clip.path, sync_clip.path, _tline_sync_offsets_computed_callback)
166
+    clapperless_thread.start()
167
+
168
+    # Edit consumes selection
169
+    movemodes.clear_selected_clips()
170
+
171
+    updater.repaint_tline()
172
+
173
+def _get_sync_tline_clip(event, frame):
174
+    sync_track = tlinewidgets.get_track(event.y)
175
+
176
+    if sync_track == None:
177
+        return None
178
+        
179
+    if sync_track == _tline_sync_data.origin_track:
180
+        dialogutils.warning_message(_("Audio Sync parent clips must be on differnt tracks "), 
181
+                                _("Selected audio sync clip is on the sametrack as the sync action origin clip."),
182
+                                gui.editor_window.window,
183
+                                True)
184
+        return None
185
+
186
+    sync_clip_index = current_sequence().get_clip_index(sync_track, frame)
187
+    if sync_clip_index == -1:
188
+        return None
189
+
190
+    return sync_track.clips[sync_clip_index]
191
+    
192
+def _tline_sync_offsets_computed_callback(clapperless_data):
193
+    print "Clapperless done for tline sync"
194
+    
195
+    file_path_1, file_path_2, idstr = clapperless_data
196
+    files_offsets = _read_offsets(idstr)
197
+    
198
+    _tline_sync_data.media_offset_frames = int(float(files_offsets[file_path_2]) + 0.5)
199
+    
200
+    dialogs.tline_audio_sync_dialog(_tline_audio_sync_dialog_callback, _tline_sync_data)
201
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/clipenddragmode.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/clipenddragmode.py Changed
10
 
1
@@ -141,7 +141,7 @@
2
                 action = edit.clip_end_drag_replace_blank_action(data)
3
                 action.do_edit()
4
     else:# Dragging clip start
5
-        delta =  frame - orig_in  - 1 # -1 because..uhh..inclusive exclusive something something
6
+        delta = frame - orig_in  - 1 # -1 because..uhh..inclusive exclusive something something
7
         # prev clip is not blank or first clip
8
         if ((clip_index == 0) or
9
             (track.clips[clip_index - 1].is_blanck_clip == False)):
10
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/clipmenuaction.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/clipmenuaction.py Changed
181
 
1
@@ -33,6 +33,7 @@
2
 import time
3
 
4
 import audiowaveform
5
+import audiosync
6
 import appconsts
7
 import clipeffectseditor
8
 import compositeeditor
9
@@ -216,12 +217,43 @@
10
                 "out_frame":compositor_out,
11
                 "a_track":target_track_index,
12
                 "b_track":track.id,
13
-                "compositor_type":compositor_type}
14
+                "compositor_type":compositor_type,
15
+                "clip":clip}
16
     action = edit.add_compositor_action(edit_data)
17
     action.do_edit()
18
     
19
     updater.repaint_tline()
20
 
21
+def _add_autofade(data):
22
+    clip, track, item_id, item_data = data
23
+    x, compositor_type = item_data
24
+
25
+    frame = tlinewidgets.get_frame(x)
26
+    clip_index = track.get_clip_index_at(frame)
27
+
28
+    target_track_index = track.id - 1
29
+
30
+    clip_length = clip.clip_out - clip.clip_in
31
+    if compositor_type == "##auto_fade_in":
32
+        compositor_in = current_sequence().tracks[track.id].clip_start(clip_index)
33
+        compositor_out = compositor_in + int(utils.fps()) - 1
34
+    else:
35
+        clip_start = current_sequence().tracks[track.id].clip_start(clip_index)
36
+        compositor_out = clip_start + clip_length
37
+        compositor_in = compositor_out - int(utils.fps()) + 1
38
+
39
+    edit_data = {"origin_clip_id":clip.id,
40
+                "in_frame":compositor_in,
41
+                "out_frame":compositor_out,
42
+                "a_track":target_track_index,
43
+                "b_track":track.id,
44
+                "compositor_type":compositor_type,
45
+                "clip":clip}
46
+    action = edit.add_compositor_action(edit_data)
47
+    action.do_edit()
48
+    
49
+    updater.repaint_tline()
50
+    
51
 def _mute_clip(data):
52
     clip, track, item_id, item_data = data
53
     set_clip_muted = item_data
54
@@ -235,6 +267,62 @@
55
         action = edit.unmute_clip(data)
56
         action.do_edit()
57
 
58
+def _delete_clip(data):
59
+    tlineaction.splice_out_button_pressed()
60
+    
61
+def _lift(data):
62
+    tlineaction.lift_button_pressed()
63
+    
64
+def _set_length(data):
65
+    clip, track, item_id, item_data = data
66
+    dialogs.clip_length_change_dialog(_change_clip_length_dialog_callback, clip, track)
67
+
68
+def _change_clip_length_dialog_callback(dialog, response_id, clip, track, length_changer):
69
+    if response_id != Gtk.ResponseType.ACCEPT:
70
+        dialog.destroy()
71
+        return
72
+
73
+    length = length_changer.get_length()
74
+    index = track.clips.index(clip)
75
+    
76
+    dialog.destroy()
77
+    
78
+    data = {"track":track,
79
+            "clip":clip,
80
+            "index":index,
81
+            "length":length}
82
+            
83
+    action = edit.set_clip_length_action(data)
84
+    action.do_edit()
85
+                
86
+def _stretch_next(data):
87
+    clip, track, item_id, item_data = data
88
+    try:
89
+        next_index = track.clips.index(clip) + 1
90
+        if next_index >= len( track.clips):
91
+            return # clip is last clip
92
+        if track.clips[next_index].is_blanck_clip == True:
93
+            # Next clip is blank so we can do this.
94
+            clip = track.clips[next_index]
95
+            data = (clip, track, item_id, item_data)
96
+            _cover_blank_from_prev(data, True)
97
+    except:
98
+        pass # any error means that this can't be done
99
+        
100
+def _stretch_prev(data):
101
+    clip, track, item_id, item_data = data
102
+    try:
103
+        prev_index = track.clips.index(clip) - 1
104
+        if prev_index < 0:
105
+            return # clip is first clip
106
+        if track.clips[prev_index].is_blanck_clip == True:
107
+            # Next clip is blank so we can do this.
108
+            clip = track.clips[prev_index]
109
+            data = (clip, track, item_id, item_data)
110
+            _cover_blank_from_next(data, True)
111
+    except:
112
+        pass # any error means that this can't be done
113
+        
114
 def _delete_blank(data):
115
     clip, track, item_id, x = data
116
     movemodes.select_blank_range(track, clip)
117
@@ -245,13 +333,17 @@
118
     action = edit.remove_multiple_action(data)
119
     action.do_edit()
120
 
121
-def _cover_blank_from_prev(data):
122
+def _cover_blank_from_prev(data, called_from_prev_clip=False):
123
     clip, track, item_id, item_data = data
124
-    clip_index = movemodes.selected_range_in - 1
125
-    if clip_index < 0: # we're not getting legal clip index
126
-        return 
127
-    cover_clip = track.clips[clip_index]
128
-
129
+    if not called_from_prev_clip:
130
+        clip_index = movemodes.selected_range_in - 1
131
+        if clip_index < 0: # we're not getting legal clip index
132
+            return 
133
+        cover_clip = track.clips[clip_index]
134
+    else:
135
+        clip_index = track.clips.index(clip) - 1
136
+        cover_clip = track.clips[clip_index]
137
+        
138
     # Check that clip covers blank area
139
     total_length = 0
140
     for i in range(movemodes.selected_range_in,  movemodes.selected_range_out + 1):
141
@@ -269,14 +361,19 @@
142
     action = edit.trim_end_over_blanks(data)
143
     action.do_edit()
144
 
145
-def _cover_blank_from_next(data):
146
+def _cover_blank_from_next(data, called_from_next_clip=False):
147
     clip, track, item_id, item_data = data
148
-    clip_index = movemodes.selected_range_out + 1
149
-    blank_index = movemodes.selected_range_in
150
-    if clip_index < 0: # we're not getting legal clip index
151
-        return
152
-    cover_clip = track.clips[clip_index]
153
-    
154
+    if not called_from_next_clip:
155
+        clip_index = movemodes.selected_range_out + 1
156
+        blank_index = movemodes.selected_range_in
157
+        if clip_index < 0: # we're not getting legal clip index
158
+            return
159
+        cover_clip = track.clips[clip_index]
160
+    else:
161
+        clip_index = track.clips.index(clip) + 1
162
+        blank_index = clip_index - 1
163
+        cover_clip = track.clips[clip_index]
164
+        
165
     # Check that clip covers blank area
166
     total_length = 0
167
     for i in range(movemodes.selected_range_in,  movemodes.selected_range_out + 1):
168
@@ -465,4 +562,11 @@
169
                   "match_frame_start_monitor":_match_frame_start_monitor,
170
                   "match_frame_end_monitor":_match_frame_end_monitor,
171
                   "select_all_after": _select_all_after,
172
-                  "select_all_before":_select_all_before}
173
+                  "select_all_before":_select_all_before,
174
+                  "delete":_delete_clip,
175
+                  "lift":_lift, 
176
+                  "length":_set_length,
177
+                  "stretch_next":_stretch_next, 
178
+                  "stretch_prev":_stretch_prev,
179
+                  "add_autofade":_add_autofade,
180
+                  "set_audio_sync_clip":audiosync.init_select_tline_sync_clip}
181
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/compositeeditor.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/compositeeditor.py Changed
117
 
1
@@ -19,13 +19,14 @@
2
 """
3
 
4
 """
5
-Module handles clips compositing gui.
6
+Module handles Compositors edit panel.
7
 """
8
 
9
 import copy
10
 
11
 from gi.repository import Gtk
12
 
13
+import compositorfades
14
 import gui
15
 import guicomponents
16
 import guiutils
17
@@ -33,6 +34,7 @@
18
 from editorstate import current_sequence
19
 import editorpersistance
20
 import keyframeeditor
21
+import mlttransitions
22
 import propertyeditorbuilder
23
 import propertyedit
24
 import propertyparse
25
@@ -56,6 +58,17 @@
26
     """
27
     # Left side
28
     widgets.compositor_info = guicomponents.CompositorInfoPanel()
29
+    widgets.fade_in_b = Gtk.Button(_("Add Fade In"))
30
+    widgets.fade_in_b.connect("clicked", lambda w,e: _add_fade_in_pressed(), None)
31
+    widgets.fade_out_b = Gtk.Button(_("Add Fade Out"))
32
+    widgets.fade_out_b.connect("clicked", lambda w,e: _add_fade_out_pressed(), None)
33
+
34
+    widgets.fade_in_spin = Gtk.SpinButton.new_with_range(0, 150, 1)
35
+    widgets.fade_in_spin.set_value(10)
36
+    
37
+    widgets.fade_out_spin = Gtk.SpinButton.new_with_range(0, 150, 1)
38
+    widgets.fade_out_spin.set_value(10)
39
+    
40
     widgets.delete_b = Gtk.Button(_("Delete"))
41
     widgets.delete_b.connect("clicked", lambda w,e: _delete_compositor_pressed(), None)
42
     widgets.reset_b = Gtk.Button(_("Reset"))
43
@@ -74,6 +87,13 @@
44
     
45
     compositor_vbox = Gtk.VBox(False, 2)
46
     compositor_vbox.pack_start(widgets.compositor_info, False, False, 0)
47
+    compositor_vbox.pack_start(guiutils.get_pad_label(5, 24), False, False, 0)
48
+    compositor_vbox.pack_start(widgets.fade_in_b, False, False, 0)
49
+    compositor_vbox.pack_start(widgets.fade_in_spin, False, False, 0)
50
+    compositor_vbox.pack_start(guiutils.get_pad_label(5, 12), False, False, 0)
51
+    compositor_vbox.pack_start(widgets.fade_out_b, False, False, 0)
52
+    compositor_vbox.pack_start(widgets.fade_out_spin, False, False, 0)
53
+    compositor_vbox.pack_start(guiutils.get_pad_label(5, 24), False, False, 0)
54
     compositor_vbox.pack_start(Gtk.Label(), True, True, 0)
55
     compositor_vbox.pack_start(widgets.reset_b, False, False, 0)
56
     compositor_vbox.pack_start(widgets.delete_b, False, False, 0)
57
@@ -113,10 +133,32 @@
58
     widgets.delete_b.set_sensitive(value)
59
     widgets.reset_b.set_sensitive(value)
60
 
61
+    if compositor == None or (compositor.transition.info.auto_fade_compositor == False \
62
+        and mlttransitions.is_blender(compositor.transition.info.name) == False):
63
+        widgets.fade_in_b.set_sensitive(value)
64
+        widgets.fade_out_b.set_sensitive(value)
65
+        widgets.fade_in_spin.set_sensitive(value)
66
+        widgets.fade_out_spin.set_sensitive(value)
67
+    else: # Autofade compositors or blenders don't use these buttons
68
+        widgets.fade_in_b.set_sensitive(False)
69
+        widgets.fade_out_b.set_sensitive(False)
70
+        widgets.fade_in_spin.set_sensitive(False)
71
+        widgets.fade_out_spin.set_sensitive(False)
72
+
73
 def maybe_clear_editor(killed_compositor):
74
     if killed_compositor.destroy_id == compositor.destroy_id:
75
         clear_compositor()
76
 
77
+def _add_fade_in_pressed():
78
+    compositorfades.add_fade_in(compositor, int(widgets.fade_in_spin.get_value()))
79
+    # We need GUI reload to show results
80
+    set_compositor(compositor)
81
+
82
+def _add_fade_out_pressed():
83
+    compositorfades.add_fade_out(compositor, int(widgets.fade_out_spin.get_value()))
84
+    # We need GUI reload to show results
85
+    set_compositor(compositor)
86
+
87
 def _delete_compositor_pressed():
88
     data = {"compositor":compositor}
89
     action = edit.delete_compositor_action(data)
90
@@ -141,7 +183,7 @@
91
 
92
     vbox = Gtk.VBox()
93
 
94
-    # case: Empty edit frame
95
+    # Case: Empty edit frame
96
     global compositor
97
     if compositor == None:
98
         widgets.empty_label = Gtk.Label(label=_("No Compositor"))
99
@@ -152,7 +194,8 @@
100
         widgets.value_edit_box = vbox
101
         widgets.value_edit_frame.add(vbox)
102
         return 
103
-    
104
+
105
+    # Case: Filled frame
106
     compositor_name_label = Gtk.Label(label= "<b>" + compositor.name + "</b>")
107
     compositor_name_label.set_use_markup(True)
108
     vbox.pack_start(compositor_name_label, False, False, 0)
109
@@ -190,6 +233,7 @@
110
         if ((editor_type == propertyeditorbuilder.KEYFRAME_EDITOR)
111
             or (editor_type == propertyeditorbuilder.KEYFRAME_EDITOR_RELEASE)
112
             or (editor_type == propertyeditorbuilder.KEYFRAME_EDITOR_CLIP)
113
+            or (editor_type == propertyeditorbuilder.FADE_LENGTH)
114
             or (editor_type == propertyeditorbuilder.GEOMETRY_EDITOR)):
115
                 keyframe_editor_widgets.append(editor_row)
116
     
117
flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/compositorfades.py Added
201
 
1
@@ -0,0 +1,285 @@
2
+"""
3
+    Flowblade Movie Editor is a nonlinear video editor.
4
+    Copyright 2012 Janne Liljeblad.
5
+
6
+    This file is part of Flowblade Movie Editor <http://code.google.com/p/flowblade>.
7
+
8
+    Flowblade Movie Editor is free software: you can redistribute it and/or modify
9
+    it under the terms of the GNU General Public License as published by
10
+    the Free Software Foundation, either version 3 of the License, or
11
+    (at your option) any later version.
12
+
13
+    Flowblade Movie Editor is distributed in the hope that it will be useful,
14
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+    GNU General Public License for more details.
17
+
18
+    You should have received a copy of the GNU General Public License
19
+    along with Flowblade Movie Editor.  If not, see <http://www.gnu.org/licenses/>.
20
+"""
21
+import appconsts
22
+import dialogutils
23
+import gui
24
+import editorstate
25
+from editorstate import current_sequence
26
+import propertyedit
27
+import propertyparse
28
+
29
+"""
30
+This module handles adding fade-ins and fade-outs to compositors.
31
+
32
+Creating and managing keyframes is mostly handled by editor GUI components which cannot easily 
33
+be used for adding fade-ins and fade outs, so this dedicated module is needed.
34
+"""
35
+
36
+# Dissolve default fades group ("Dissolve", "Blend") keyframe property class names
37
+_dissolve_property_klasses = ["OpacityInGeomKeyframeProperty", "KeyFrameHCSTransitionProperty"]
38
+
39
+# -------------------------------------------------------------- module interface
40
+def add_default_fades(compositor, clip):
41
+    # Default fades are not aplied to auto fade compositors
42
+    if compositor.transition.info.auto_fade_compositor == True:
43
+        return
44
+        
45
+    keyframe_property, property_klass, keyframes = _get_kfproperty_klass_and_keyframes(compositor, clip)
46
+
47
+    if keyframe_property == None:
48
+        return
49
+        
50
+    fade_in_length, fade_out_length = _get_default_fades_lengths(property_klass)
51
+    print fade_in_length, 
52
+    if fade_in_length > 0:
53
+        if fade_in_length <= clip.clip_length():
54
+            keyframes = _add_default_fade_in(keyframe_property, property_klass, keyframes, fade_in_length)
55
+        else:
56
+            _show_defaults_length_error_dialog()
57
+            return
58
+            
59
+    if fade_out_length > 0:
60
+        if fade_out_length + fade_in_length + 1 <= clip.clip_length():
61
+            keyframes = _add_default_fade_out(keyframe_property, property_klass, keyframes, fade_out_length, clip)
62
+        else:
63
+            _show_defaults_length_error_dialog()
64
+            return
65
+
66
+    keyframe_property.write_out_keyframes(keyframes)
67
+
68
+def add_fade_in(compositor, fade_in_length):
69
+    clip = _get_compositor_clip(compositor)
70
+    keyframe_property, property_klass, keyframes = _get_kfproperty_klass_and_keyframes(compositor, clip)
71
+    
72
+    if fade_in_length > 0:
73
+        if fade_in_length <= clip.clip_length():
74
+            _do_user_add_fade_in(keyframe_property, property_klass, keyframes, fade_in_length)
75
+        else:
76
+            _show_length_error_dialog()
77
+
78
+def add_fade_out(compositor, fade_out_length):
79
+    clip = _get_compositor_clip(compositor)
80
+    keyframe_property, property_klass, keyframes = _get_kfproperty_klass_and_keyframes(compositor, clip)
81
+    
82
+    if fade_out_length > 0:
83
+        if fade_out_length + 1 <= clip.clip_length():
84
+            _do_user_add_fade_out(keyframe_property, property_klass, keyframes, fade_out_length, clip)
85
+        else:
86
+            _show_length_error_dialog()
87
+
88
+def set_auto_fade_in_keyframes(compositor):
89
+    clip = _get_compositor_clip(compositor)
90
+    keyframe_property, property_klass, keyframes = _get_kfproperty_klass_and_keyframes(compositor, clip)
91
+    
92
+    # Remove all key frames, there exists 2 or 1, 0 when created 1 always after that
93
+    while len(keyframes) > 0: 
94
+        keyframes.pop()
95
+    
96
+    # Set in fade in keyframes
97
+    keyframes.append((0, 0))
98
+    keyframes.append((compositor.get_length() - 1, 100))
99
+
100
+    keyframe_property.write_out_keyframes(keyframes)
101
+
102
+def set_auto_fade_out_keyframes(compositor):
103
+    clip = _get_compositor_clip(compositor)
104
+    keyframe_property, property_klass, keyframes = _get_kfproperty_klass_and_keyframes(compositor, clip)
105
+
106
+    # Pop first keyframe to get frame
107
+    #frame, geom, opacity = keyframes.pop(0)
108
+    
109
+    # Remove all key frames, there exists 2 or 1, 0 when created 1 always after that
110
+    while len(keyframes) > 0: 
111
+        keyframes.pop()
112
+    
113
+    # Set in fade in keyframes
114
+    keyframes.append((0, 100))
115
+    keyframes.append((compositor.get_length() - 1, 0))
116
+
117
+    keyframe_property.write_out_keyframes(keyframes)
118
+    
119
+# ---------------------------------------------------------------------- module finctions
120
+def _get_kfproperty_klass_and_keyframes(compositor, clip):
121
+    # Create editable properties from compositor properties.
122
+    t_editable_properties = propertyedit.get_transition_editable_properties(compositor)
123
+
124
+    # Find keyframe property, its class and create keyframes list
125
+    if compositor.transition.info.mlt_service_id == "frei0r.cairoaffineblend": # Affine Blend
126
+        # Because of frei0r's forced value 0.0-1.0 range "Affine Blend" is handled in a more complex way compared to other compositors
127
+        keyframe_property = propertyparse.create_editable_property_for_affine_blend(clip, t_editable_properties)
128
+        keyframes = propertyparse.rotating_geom_keyframes_value_string_to_geom_kf_array(keyframe_property.value, keyframe_property.get_in_value)
129
+        property_klass = keyframe_property.__class__.__name__
130
+        return (keyframe_property, property_klass, keyframes)
131
+        
132
+    else: # Dissolve, Blend, Picture-in-Picture, Region
133
+        keyframe_property = None
134
+        property_klass = None
135
+        for ep in t_editable_properties:
136
+            property_klass = ep.__class__.__name__
137
+            if property_klass == "OpacityInGeomKeyframeProperty": # Dissolve
138
+                keyframe_property = ep
139
+                keyframes = propertyparse.geom_keyframes_value_string_to_opacity_kf_array(keyframe_property.value, keyframe_property.get_in_value)
140
+                break
141
+            if property_klass == "KeyFrameHCSTransitionProperty": # Blend
142
+                keyframe_property = ep
143
+                keyframes = propertyparse.single_value_keyframes_string_to_kf_array(keyframe_property.value, keyframe_property.get_in_value)
144
+                break
145
+            if property_klass == "KeyFrameGeometryOpacityProperty": # Picture-in-Picture, Region
146
+                keyframe_property = ep
147
+                keyframes = propertyparse.geom_keyframes_value_string_to_geom_kf_array(keyframe_property.value, keyframe_property.get_in_value)
148
+                break
149
+
150
+        if keyframe_property == None:
151
+            print "didn't find keyframe_property in _get_kfproperty_klass_and_keyframes"
152
+            return (None, None, None)
153
+
154
+        return (keyframe_property, property_klass, keyframes)
155
+
156
+def _get_compositor_clip(compositor):
157
+    for i in range(current_sequence().first_video_index, len(current_sequence().tracks) - 1): # -1, there is a topmost hidden track 
158
+        track = current_sequence().tracks[i] # b_track is source track where origin clip is
159
+        for j in range(0, len(track.clips)):
160
+            clip = track.clips[j]
161
+            if clip.id == compositor.origin_clip_id:
162
+                return clip
163
+    
164
+    return None
165
+
166
+def _get_default_fades_lengths(property_klass):
167
+    if property_klass in _dissolve_property_klasses:
168
+        fade_in_length = editorstate.PROJECT().get_project_property(appconsts.P_PROP_DISSOLVE_GROUP_FADE_IN)
169
+        fade_out_length = editorstate.PROJECT().get_project_property(appconsts.P_PROP_DISSOLVE_GROUP_FADE_OUT) 
170
+    else:
171
+        fade_in_length = editorstate.PROJECT().get_project_property(appconsts.P_PROP_ANIM_GROUP_FADE_IN)
172
+        fade_out_length = editorstate.PROJECT().get_project_property(appconsts.P_PROP_ANIM_GROUP_FADE_OUT)
173
+    
174
+    return (fade_in_length, fade_out_length)
175
+
176
+def _add_default_fade_in(keyframe_property, property_klass, keyframes, fade_in_length):
177
+    if property_klass in _dissolve_property_klasses:
178
+        frame, opacity  = keyframes.pop(0)
179
+        keyframes.append((frame, 0))
180
+        keyframes.append((frame + fade_in_length, 100))
181
+        return keyframes
182
+    else:
183
+        # (0, [0, 0, 1280, 720], 100.0) or (0, [640.0, 360.0, 1.0, 1.0, 0.0], 100.0) e.g.
184
+        frame, geom, opacity = keyframes.pop(0)
185
+        keyframes.append((frame, geom, 0))
186
+        keyframes.append((frame + fade_in_length, geom, 100))
187
+        return keyframes
188
+
189
+def _add_default_fade_out(keyframe_property, property_klass, keyframes, fade_out_length, clip, kf_before_fade_out_index=0):
190
+    if property_klass in _dissolve_property_klasses:
191
+        keyframes.append((clip.clip_length() - fade_out_length - 1, 100))
192
+        keyframes.append((clip.clip_length() - 1, 0))
193
+        return keyframes
194
+    else:
195
+        # (0, [0, 0, 1280, 720], 100.0) or (0, [640.0, 360.0, 1.0, 1.0, 0.0], 100.0) e.g.
196
+        frame, geom, opacity = keyframes[kf_before_fade_out_index]
197
+        keyframes.append((clip.clip_length() - fade_out_length - 1, geom, 100))
198
+        keyframes.append((clip.clip_length() - 1, geom, 0))
199
+        return keyframes
200
+
201
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/compositormodes.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/compositormodes.py Changed
34
 
1
@@ -86,6 +86,7 @@
2
         edit_data = {"clip_in":compositor.clip_in,
3
                      "clip_out":compositor.clip_out,
4
                      "trim_is_clip_in":True,
5
+                     "orig_clip_in":compositor.clip_in,
6
                      "compositor_y":  compositor_y,
7
                      "compositor": compositor}
8
         tlinewidgets.set_edit_mode(edit_data, tlinewidgets.draw_compositor_trim)
9
@@ -94,6 +95,7 @@
10
         edit_data = {"clip_in":compositor.clip_in,
11
                      "clip_out":compositor.clip_out,
12
                      "trim_is_clip_in":False,
13
+                     "orig_clip_out":compositor.clip_out,
14
                      "compositor_y": compositor_y,
15
                      "compositor": compositor}
16
         tlinewidgets.set_edit_mode(edit_data, tlinewidgets.draw_compositor_trim)
17
@@ -119,6 +121,8 @@
18
     updater.repaint_tline()
19
     
20
 def mouse_release(x, y, frame, state):
21
+    global sub_mode
22
+    
23
     editorstate.edit_mode = prev_edit_mode
24
     if editorstate.edit_mode == editorstate.INSERT_MOVE:
25
         tlinewidgets.set_edit_mode(None, tlinewidgets.draw_insert_overlay)
26
@@ -153,7 +157,6 @@
27
         action = edit.move_compositor_action(data)
28
         action.do_edit()
29
     
30
-    global sub_mode
31
     sub_mode = NO_COMPOSITOR_EDIT
32
     
33
     updater.repaint_tline()
34
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/dialogs.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/dialogs.py Changed
201
 
1
@@ -43,6 +43,7 @@
2
 import panels
3
 import renderconsumer
4
 import respaths
5
+import shortcuts
6
 import utils
7
 
8
 
9
@@ -252,11 +253,14 @@
10
     dialog.connect('response', callback, project_folder, compact_name_entry)
11
     dialog.show_all()
12
 
13
-def load_project_dialog(callback, parent=None):
14
+def load_project_dialog(callback, parent=None, title_text=None):
15
     if parent == None:
16
         parent = gui.editor_window.window
17
 
18
-    dialog = Gtk.FileChooserDialog(_("Select Project File"), parent,
19
+    if title_text == None:
20
+       title_text = _("Select Project File")
21
+
22
+    dialog = Gtk.FileChooserDialog(title_text, parent,
23
                                    Gtk.FileChooserAction.OPEN,
24
                                    (_("Cancel").encode('utf-8'), Gtk.ResponseType.CANCEL,
25
                                     _("OK").encode('utf-8'), Gtk.ResponseType.ACCEPT))
26
@@ -307,6 +311,38 @@
27
     dialog.connect('response', callback)
28
     dialog.show()
29
 
30
+def compound_clip_name_dialog(callback, default_name, dialog_title, data=None):
31
+    
32
+    dialog = Gtk.Dialog(dialog_title,  gui.editor_window.window,
33
+                        Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,
34
+                        (_("Cancel").encode('utf-8'), Gtk.ResponseType.REJECT,
35
+                        _("Create").encode('utf-8'), Gtk.ResponseType.ACCEPT))
36
+
37
+    name_entry = Gtk.Entry()
38
+    name_entry.set_width_chars(30)
39
+    name_entry.set_text(default_name)
40
+    name_entry.set_activates_default(True)
41
+
42
+    name_select = panels.get_two_column_box(Gtk.Label(label=_("Clip Name:")),
43
+                                               name_entry,
44
+                                               180)
45
+
46
+    vbox = Gtk.VBox(False, 2)
47
+    vbox.pack_start(name_select, False, False, 0)
48
+    vbox.pack_start(guiutils.get_pad_label(12, 12), False, False, 0)
49
+
50
+    alignment = dialogutils.get_alignment2(vbox)
51
+
52
+    dialog.vbox.pack_start(alignment, True, True, 0)
53
+    dialogutils.set_outer_margins(dialog.vbox)
54
+    _default_behaviour(dialog)
55
+    dialog.set_default_response(Gtk.ResponseType.ACCEPT)
56
+    if data == None:
57
+        dialog.connect('response', callback, name_entry)
58
+    else:
59
+        dialog.connect('response', callback, (data, name_entry))
60
+    dialog.show_all()
61
+    
62
 def save_env_data_dialog(callback):
63
     dialog = Gtk.FileChooserDialog(_("Save Runtime Environment Data"),  gui.editor_window.window,
64
                                    Gtk.FileChooserAction.SAVE,
65
@@ -404,14 +440,16 @@
66
                         Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,
67
                         (_("OK").encode('utf-8'), Gtk.ResponseType.ACCEPT))
68
 
69
+    # Application tab
70
     img = Gtk.Image.new_from_file(respaths.IMAGE_PATH + "flowbladeappicon.png")
71
     flow_label = Gtk.Label(label="Flowblade Movie Editor")
72
-    ver_label = Gtk.Label(label="1.12.0")
73
-    janne_label = Gtk.Label(label="Copyright 2016 Janne Liljeblad and contributors")
74
-    page_label = Gtk.Label(label="Project page: https://github.com/jliljebl/flowblade")
75
+    ver_label = Gtk.Label(label="1.14.0")
76
+    janne_label = Gtk.Label(label="Copyright 2017 Janne Liljeblad and contributors")
77
+    page_label = Gtk.Label(label=_("Project page:") + " " + "<a href=\"https://github.com/jliljebl/flowblade\">https://github.com/jliljebl/flowblade</a>")
78
+    page_label.set_use_markup(True)
79
     flow_label.modify_font(Pango.FontDescription("sans bold 14"))
80
-    janne_label.modify_font(Pango.FontDescription("sans 8"))
81
-    page_label.modify_font(Pango.FontDescription("sans 8"))
82
+    janne_label.modify_font(Pango.FontDescription("sans 10"))
83
+    page_label.modify_font(Pango.FontDescription("sans 10"))
84
 
85
     vbox = Gtk.VBox(False, 4)
86
     vbox.pack_start(guiutils.get_pad_label(30, 12), False, False, 0)
87
@@ -427,10 +465,11 @@
88
     alignment =  dialogutils.get_default_alignment(vbox)
89
     alignment.set_size_request(450, 370)
90
 
91
-    up_label = Gtk.Label(label="Upstream:")
92
+    # Thanks tab
93
+    up_label = Gtk.Label(label=_("Upstream:"))
94
     up_projs = Gtk.Label(label="MLT")
95
     up_projs2 = Gtk.Label("FFMpeg, Frei0r, LADSPA, Cairo, Gnome, Linux")
96
-    tools_label = Gtk.Label(label="Tools:")
97
+    tools_label = Gtk.Label(label=_("Tools:"))
98
     tools_list = Gtk.Label("Geany, Inkscape, Gimp, ack-grep")
99
 
100
     up_label.modify_font(Pango.FontDescription("sans bold 12"))
101
@@ -450,21 +489,23 @@
102
     alignment2 = dialogutils.get_default_alignment(vbox2)
103
     alignment2.set_size_request(450, 370)
104
 
105
+    # Licence tab
106
     license_view = guicomponents.get_gpl3_scroll_widget((450, 370))
107
     alignment3 = dialogutils.get_default_alignment(license_view)
108
     alignment3.set_size_request(450, 370)
109
 
110
-    lead_label = Gtk.Label(label="Lead Developer:")
111
+    # Developers tab
112
+    lead_label = Gtk.Label(label=_("Lead Developer:"))
113
     lead_label.modify_font(Pango.FontDescription("sans bold 12"))
114
     lead_info = Gtk.Label(label="Janne Liljeblad")
115
-    developers_label = Gtk.Label("Developers:")
116
+    developers_label = Gtk.Label(_("Developers:"))
117
     developers_label.modify_font(Pango.FontDescription("sans bold 12"))
118
 
119
     devs_file = open(respaths.DEVELOPERS_DOC)
120
     devs_text = devs_file.read()
121
     devs_info = Gtk.Label(label=devs_text)
122
 
123
-    contributos_label = Gtk.Label(label="Contributors:")
124
+    contributos_label = Gtk.Label(label=_("Contributors:"))
125
     contributos_label.modify_font(Pango.FontDescription("sans bold 12"))
126
     
127
     contributors_file = open(respaths.CONTRIBUTORS_DOC)
128
@@ -476,6 +517,7 @@
129
     contributors_view.set_left_margin(2)
130
     contributors_view.set_wrap_mode(Gtk.WrapMode.WORD)
131
     contributors_view.get_buffer().set_text(contributors_text)
132
+    contributors_view.set_justification(2) # Centered
133
     guiutils.set_margins(contributors_view, 0, 0, 30, 30)
134
     
135
     vbox3 = Gtk.VBox(False, 4)
136
@@ -491,9 +533,18 @@
137
     
138
     alignment5 = dialogutils.get_default_alignment(vbox3)
139
     alignment5.set_size_request(450, 370)
140
-    
141
+
142
+    # Translations tab
143
+    translations_label = Gtk.Label(label=_("Translations by:"))
144
+    translations_label.modify_font(Pango.FontDescription("sans bold 12"))
145
     translations_view = guicomponents.get_translations_scroll_widget((450, 370))
146
-    alignment4 = dialogutils.get_default_alignment(translations_view)
147
+
148
+    vbox4 = Gtk.VBox(False, 4)
149
+    vbox4.pack_start(guiutils.get_pad_label(30, 12), False, False, 0)
150
+    vbox4.pack_start(translations_label, False, False, 0)
151
+    vbox4.pack_start(translations_view, False, False, 0)
152
+
153
+    alignment4 = dialogutils.get_default_alignment(vbox4)
154
     alignment4.set_size_request(450, 370)
155
 
156
     notebook = Gtk.Notebook()
157
@@ -875,6 +926,28 @@
158
     dialog.connect('response', callback, tracks_select)
159
     dialog.show_all()
160
 
161
+
162
+def clip_length_change_dialog(callback, clip, track):
163
+    dialog = Gtk.Dialog(_("Change Clip Length"),  gui.editor_window.window,
164
+                        Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,
165
+                        (_("Cancel").encode('utf-8'), Gtk.ResponseType.REJECT,
166
+                        _("Ok").encode('utf-8'), Gtk.ResponseType.ACCEPT))
167
+    
168
+    length_changer = guicomponents.ClipLengthChanger(clip)
169
+
170
+    vbox = Gtk.VBox(False, 2)
171
+    vbox.pack_start(length_changer.widget, False, False, 0)
172
+    vbox.pack_start(guiutils.get_pad_label(24, 24), False, False, 0)
173
+
174
+    alignment = dialogutils.get_alignment2(vbox)
175
+
176
+    dialog.vbox.pack_start(alignment, True, True, 0)
177
+    dialogutils.set_outer_margins(dialog.vbox)
178
+    _default_behaviour(dialog)
179
+    dialog.connect('response', callback, clip, track, length_changer)
180
+    dialog.show_all()
181
+
182
+
183
 def new_sequence_dialog(callback, default_name):
184
     dialog = Gtk.Dialog(_("Create New Sequence"),  gui.editor_window.window,
185
                         Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,
186
@@ -1114,73 +1187,150 @@
187
     _default_behaviour(dialog)
188
     dialog.show_all()
189
 
190
-def keyboard_shortcuts_dialog(parent_window):
191
+def keyboard_shortcuts_dialog(parent_window, callback):
192
     dialog = Gtk.Dialog(_("Keyboard Shortcuts"),
193
                         parent_window,
194
                         Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,
195
-                        (_("Close").encode('utf-8'), Gtk.ResponseType.CLOSE))
196
+                        (_("Cancel").encode('utf-8'), Gtk.ResponseType.REJECT,
197
+                        _("Apply").encode('utf-8'), Gtk.ResponseType.ACCEPT))
198
+
199
+    presets_label = guiutils.bold_label(_("Shortcuts Presets:"))
200
+    shortcuts_combo = guicomponents.get_shorcuts_selector()
201
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/dialogutils.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/dialogutils.py Changed
24
 
1
@@ -79,15 +79,20 @@
2
     dialog.connect('response', callback)
3
     dialog.show_all()
4
     
5
-def warning_confirmation(callback, primary_txt, secondary_txt, parent_window, data=None, is_info=False):
6
+def warning_confirmation(callback, primary_txt, secondary_txt, parent_window, data=None, is_info=False, use_confirm_text=False):
7
     content = get_warning_message_dialog_panel(primary_txt, secondary_txt, is_info)
8
     align = get_default_alignment(content)
9
     
10
+    if use_confirm_text == True:
11
+        accept_text = _("Confirm").encode('utf-8')
12
+    else:
13
+        accept_text = _("OK").encode('utf-8')
14
+    
15
     dialog = Gtk.Dialog("",
16
                         parent_window,
17
                         Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,
18
                         (_("Cancel").encode('utf-8'), Gtk.ResponseType.REJECT,
19
-                         _("OK").encode('utf-8'), Gtk.ResponseType.ACCEPT))
20
+                         accept_text, Gtk.ResponseType.ACCEPT))
21
     dialog.vbox.pack_start(align, True, True, 0)
22
     set_outer_margins(dialog.vbox)
23
     dialog.set_resizable(False)
24
flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/diskcachemanagement.py Added
179
 
1
@@ -0,0 +1,177 @@
2
+"""
3
+    Flowblade Movie Editor is a nonlinear video editor.
4
+    Copyright 2017 Janne Liljeblad.
5
+
6
+    This file is part of Flowblade Movie Editor <http://code.google.com/p/flowblade>.
7
+
8
+    Flowblade Movie Editor is free software: you can redistribute it and/or modify
9
+    it under the terms of the GNU General Public License as published by
10
+    the Free Software Foundation, either version 3 of the License, or
11
+    (at your option) any later version.
12
+
13
+    Flowblade Movie Editor is distributed in the hope that it will be useful,
14
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+    GNU General Public License for more details.
17
+
18
+    You should have received a copy of the GNU General Public License
19
+    along with Flowblade Movie Editor.  If not, see <http://www.gnu.org/licenses/>.
20
+"""
21
+
22
+from gi.repository import Gtk
23
+
24
+from os import listdir
25
+from os.path import isfile, join
26
+import os
27
+
28
+import dialogutils
29
+import gui
30
+import guiutils
31
+import utils
32
+
33
+
34
+NO_WARNING = 0
35
+RECREATE_WARNING = 1
36
+PROJECT_DATA_WARNING = 2
37
+
38
+_panels = None
39
+
40
+
41
+class DiskFolderManagementPanel:
42
+    
43
+    def __init__(self, folder, info_text, warning_level):
44
+        self.folder = folder
45
+        self.warning_level = warning_level
46
+                
47
+        self.destroy_button = Gtk.Button(_("Destroy data"))
48
+        self.destroy_button.connect("clicked", self.destroy_pressed)
49
+        self.destroy_guard_check = Gtk.CheckButton()
50
+        self.destroy_guard_check.set_active(False)
51
+        self.destroy_guard_check.connect("toggled", self.destroy_guard_toggled)
52
+        
53
+        self.size_info = Gtk.Label()
54
+        self.size_info.set_text(self.get_folder_size_str())
55
+
56
+        folder_label = Gtk.Label("/<i>" + folder + "</i>")
57
+        folder_label.set_use_markup(True)
58
+
59
+        info = Gtk.HBox(True, 2)
60
+        info.pack_start(guiutils.get_left_justified_box([guiutils.bold_label(info_text)]), True, True, 0)
61
+        info.pack_start(guiutils.get_left_justified_box([guiutils.pad_label(40, 12), folder_label]), True, True, 0)
62
+        info.pack_start(guiutils.get_left_justified_box([guiutils.pad_label(12, 12), self.size_info]), True, True, 0)
63
+
64
+        button_area = Gtk.HBox(False, 2)
65
+        if self.warning_level == PROJECT_DATA_WARNING:
66
+            button_area.pack_start(self.destroy_guard_check, True, True, 0)
67
+            self.destroy_button.set_sensitive(False)
68
+        button_area.pack_start(self.destroy_button, True, True, 0)
69
+        if self.warning_level == PROJECT_DATA_WARNING:
70
+            warning_icon = Gtk.Image.new_from_stock(Gtk.STOCK_DIALOG_WARNING, Gtk.IconSize.SMALL_TOOLBAR)
71
+            warning_icon.set_tooltip_text( _("Destroying this data may change contents of existing\nprojects and make some projects unopenable."))
72
+            button_area.pack_start(warning_icon, False, False, 0)
73
+        else:
74
+            button_area.pack_start(guiutils.pad_label(16, 16), False, False, 0)
75
+        button_area.set_size_request(150, 24)
76
+
77
+        row = Gtk.HBox(False, 2)
78
+        row.pack_start(info, True, True, 0)
79
+        row.pack_start(button_area, False, False, 0)
80
+        
81
+        self.vbox = Gtk.VBox(False, 2)
82
+        self.vbox.pack_start(row, False, False, 0)
83
+
84
+    def get_cache_folder(self):
85
+        return utils.get_hidden_user_dir_path() + "/" + self.folder
86
+
87
+    def get_folder_files(self):
88
+        cache_folder = self.get_cache_folder()
89
+        return [f for f in listdir(cache_folder) if isfile(join(cache_folder, f))]
90
+    
91
+    def get_folder_size(self):
92
+        files = self.get_folder_files()
93
+        size = 0
94
+        for f in files:
95
+            size += os.path.getsize(self.get_cache_folder() +"/" + f)
96
+        return size
97
+
98
+    def get_folder_size_str(self):
99
+        size = self.get_folder_size()
100
+        if size > 1000000:
101
+            return str(int((size + 500000) / 1000000)) + _(" MB")
102
+        elif size > 1000:
103
+            return str(int((size + 500) / 1000)) + _(" kB")
104
+        else:
105
+            return str(int(size)) + " B"
106
+
107
+    def destroy_pressed(self, widget):
108
+        if self.warning_level == NO_WARNING:
109
+            # Delete data
110
+            self.destroy_data()
111
+            return
112
+            
113
+        primaty_text = _("Confirm Destroying Cached Data!")
114
+        if self.warning_level == PROJECT_DATA_WARNING:
115
+            secondary_text = _("Destroying this data may <b>change contents</b> of existing\nprojects or <b>make some projects unopenable!</b>")
116
+            secondary_text += "\n\n"
117
+            secondary_text += _("You can use 'File->Save Backup Snapshot...' functionality to backup projects\nso that they can be opened later before destroying this data.")
118
+        else:
119
+            secondary_text = _("Destroying this data may require parts of it to be recreated later.")
120
+            
121
+        dialogutils. warning_confirmation(self.warning_confirmation, primaty_text, secondary_text, gui.editor_window.window, None, False, True)
122
+
123
+    def destroy_guard_toggled(self, check_button):
124
+        if check_button.get_active() == True:
125
+            self.destroy_button.set_sensitive(True)
126
+        else:
127
+            self.destroy_button.set_sensitive(False)
128
+         
129
+    def warning_confirmation(self, dialog, response_id):
130
+        dialog.destroy()
131
+
132
+        if response_id != Gtk.ResponseType.ACCEPT:
133
+            return
134
+    
135
+        self.destroy_data()
136
+    
137
+    def destroy_data(self):
138
+        print "deleting ", self.folder
139
+        
140
+        files = self.get_folder_files()
141
+        for f in files:
142
+            os.remove(self.get_cache_folder() +"/" + f)
143
+
144
+        self.size_info.set_text(self.get_folder_size_str())
145
+        self.size_info.queue_draw()
146
+            
147
+def show_disk_management_dialog():
148
+    dialog = Gtk.Dialog(_("Disk Cache Manager"), None,
149
+                    Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,
150
+                    (_("Close").encode('utf-8'), Gtk.ResponseType.CLOSE))
151
+
152
+    global _panels
153
+    _panels = _get_disk_dir_panels()
154
+
155
+    pane = Gtk.VBox(True, 2)
156
+    for panel in _panels:
157
+        pane.pack_start(panel.vbox, True, True, 0)
158
+
159
+    guiutils.set_margins(pane, 12, 24, 12, 12)
160
+
161
+    dialog.connect('response', dialogutils.dialog_destroy)
162
+    
163
+    dialog.vbox.pack_start(pane, True, True, 0)
164
+    dialogutils.set_outer_margins(dialog.vbox)
165
+    dialogutils.default_behaviour(dialog)
166
+    dialog.show_all()
167
+    return dialog
168
+
169
+def _get_disk_dir_panels():
170
+    panels = []
171
+    panels.append(DiskFolderManagementPanel("audiolevels", _("Audio Levels Data"), RECREATE_WARNING))
172
+    panels.append(DiskFolderManagementPanel("gmic", _("G'Mic Tool Session Data"), NO_WARNING))
173
+    panels.append(DiskFolderManagementPanel("natron", _("Natron Clip Export Data"), NO_WARNING))
174
+    panels.append(DiskFolderManagementPanel("rendered_clips", _("Rendered Files"), PROJECT_DATA_WARNING))
175
+    panels.append(DiskFolderManagementPanel("thumbnails", _("Thumbnails"), RECREATE_WARNING))
176
+    panels.append(DiskFolderManagementPanel("user_profiles", _("User Created Custom Profiles"), PROJECT_DATA_WARNING))
177
+
178
+    return panels
179
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/dnd.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/dnd.py Changed
18
 
1
@@ -46,7 +46,6 @@
2
 
3
 MEDIA_FILES_DND_TARGET = Gtk.TargetEntry.new('media_file', Gtk.TargetFlags.SAME_APP, 0)
4
 EFFECTS_DND_TARGET = Gtk.TargetEntry.new('effect', Gtk.TargetFlags.SAME_APP, 0)
5
-#EFFECTS_STACK_DND_TARGET = Gtk.TargetEntry.new('effectstack', Gtk.TargetFlags.SAME_APP, 0)
6
 CLIPS_DND_TARGET = Gtk.TargetEntry.new('clip', Gtk.TargetFlags.SAME_APP, 0)
7
 RANGE_DND_TARGET = Gtk.TargetEntry.new('range', Gtk.TargetFlags.SAME_APP, 0)
8
 
9
@@ -181,6 +180,8 @@
10
 
11
 def _on_monitor_drop(widget, context, x, y, timestamp):
12
     context.finish(True, False, timestamp)
13
+    if drag_data == None: # A user error drag from monitor to monitor
14
+        return
15
     media_file = drag_data[0].media_file
16
     display_monitor_media_file(media_file)
17
     gui.pos_bar.widget.grab_focus()
18
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/edit.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/edit.py Changed
85
 
1
@@ -29,6 +29,7 @@
2
 import audiowaveform
3
 import appconsts
4
 import compositeeditor
5
+import compositorfades
6
 from editorstate import current_sequence
7
 from editorstate import get_track
8
 from editorstate import PLAYER
9
@@ -368,7 +369,7 @@
10
         if do_gui_update:
11
             self._update_gui()
12
 
13
-    def _update_gui(self):
14
+    def _update_gui(self): # This copied  with small modifications into projectaction.py for sequence imports, update there too if needed...yeah.
15
         updater.update_tline_scrollbar() # Slider needs to adjust to possily new program length.
16
                                          # This REPAINTS TIMELINE as a side effect.
17
         if self.clear_effects_editor_for_multitrack_edit == False:
18
@@ -1425,6 +1426,24 @@
19
         self.first_do = False
20
         self.undo_done_callback(self.track)
21
 
22
+#------------------ SET CLIP LENGTH
23
+# "track","clip","index","length"
24
+# Trims end of clip
25
+def set_clip_length_action(data):
26
+    action = EditAction(_set_clip_length_undo,_set_clip_length_redo, data)
27
+    return action
28
+
29
+def _set_clip_length_undo(self):
30
+    _remove_clip(self.track, self.index)
31
+    _insert_clip(self.track, self.clip, self.index,
32
+                 self.clip.clip_in, self.orig_clip_out)
33
+    
34
+def _set_clip_length_redo(self):
35
+    self.orig_clip_out = self.clip.clip_out
36
+    _remove_clip(self.track, self.index)
37
+    _insert_clip(self.track, self.clip, self.index,
38
+                 self.clip.clip_in,  self.clip.clip_in + self.length - 1) # -1, out is inclusive and we're usin length here
39
+
40
 # ----------------------------------- CLIP END DRAG ON BLANK
41
 # "track","index","clip","blank_clip_length","delta"
42
 def clip_end_drag_on_blank_action(data):
43
@@ -1704,7 +1723,7 @@
44
     _attach_all(self.clip)
45
     
46
 # -------------------------------------- ADD COMPOSITOR ACTION
47
-# "origin_clip_id",in_frame","out_frame","compositor_type","a_track","b_track"
48
+# "origin_clip_id",in_frame","out_frame","compositor_type","a_track","b_track", "clip"
49
 def add_compositor_action(data):
50
     action = EditAction(_add_compositor_undo, _add_compositor_redo, data)
51
     action.first_do = True
52
@@ -1728,7 +1747,7 @@
53
     self.compositor.origin_clip_id = self.origin_clip_id
54
 
55
     # Compositors are recreated continually in sequence.restack_compositors() and cannot be identified for undo/redo using object identity 
56
-    # so these ids must be  preserved for all succesive versions of a compositor
57
+    # so these ids must be  preserved for all successive versions of a compositor
58
     if self.first_do == True:
59
         self.destroy_id = self.compositor.destroy_id
60
         self.first_do = False
61
@@ -1738,6 +1757,9 @@
62
     current_sequence().add_compositor(self.compositor)
63
     current_sequence().restack_compositors()
64
 
65
+    compositorfades.add_default_fades(self.compositor, self.clip)
66
+    self.compositor.update_autofade_keyframes()
67
+    
68
     compositeeditor.set_compositor(self.compositor)
69
 
70
 # -------------------------------------- DELETE COMPOSITOR ACTION
71
@@ -1771,12 +1793,7 @@
72
         
73
     current_sequence().remove_compositor(self.compositor)
74
     current_sequence().restack_compositors()
75
-    
76
-    # Hack!!! Some filters don't seem to handle setting compositors None (and the
77
-    # following gc) and crash, so we'll hold references to them forever.
78
-    #global old_compositors
79
-    #old_compositors.append(self.compositor)
80
-    
81
+        
82
     compositeeditor.maybe_clear_editor(self.compositor)
83
 
84
 #--------------------------------------------------- MOVE COMPOSITOR
85
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/editevent.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/editevent.py Changed
34
 
1
@@ -31,6 +31,7 @@
2
 from gi.repository import Gdk
3
 
4
 import appconsts
5
+import audiosync
6
 import boxmove
7
 import clipeffectseditor
8
 import clipenddragmode
9
@@ -540,6 +541,14 @@
10
         set_default_edit_mode()  
11
         return
12
 
13
+    # Handle and exit tline sync clip selecting
14
+    if EDIT_MODE() == editorstate.SELECT_TLINE_SYNC_CLIP:
15
+        audiosync.select_sync_clip_mouse_pressed(event, frame)
16
+        mouse_disabled = True
17
+        # Set INSERT_MODE
18
+        set_default_edit_mode()  
19
+        return
20
+        
21
     # Hitting timeline in clip display mode displays timeline in
22
     # default mode.
23
     if not timeline_visible():
24
@@ -740,6 +749,9 @@
25
         return
26
 
27
     clip = track.clips[clip_index]
28
+    if clip.is_blanck_clip == True:
29
+        return
30
+        
31
     data = (clip, track, None, x)
32
     updater.open_clip_in_effects_editor(data)
33
 
34
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/editorpersistance.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/editorpersistance.py Changed
87
 
1
@@ -22,8 +22,8 @@
2
 Module handles saving and loading data that is related to the editor and not any particular project.
3
 """
4
 
5
-
6
 from gi.repository import Gtk
7
+from gi.repository import Gdk
8
 
9
 import os
10
 import pickle
11
@@ -32,6 +32,9 @@
12
 import mltprofiles
13
 import utils
14
 
15
+# Apr-2017 - SvdB
16
+import shortcuts
17
+
18
 PREFS_DOC = "prefs"
19
 RECENT_DOC = "recent"
20
 
21
@@ -175,15 +178,20 @@
22
     default_profile_combo, open_in_last_opened_check, open_in_last_rendered_check, undo_max_spin, load_order_combo = gen_opts_widgets
23
     
24
     # Jul-2016 - SvdB - Added play_pause_button
25
+    # Apr-2017 - SvdB - Added ffwd / rev values
26
     auto_play_in_clip_monitor_check, auto_center_check, grfx_insert_length_spin, \
27
         trim_exit_click, trim_quick_enter, remember_clip_frame, overwrite_clip_drop, cover_delete, \
28
-        play_pause_button, mouse_scroll_action, hide_file_ext_button, auto_center_on_updown = edit_prefs_widgets
29
+        play_pause_button, mouse_scroll_action, hide_file_ext_button, auto_center_on_updown, \
30
+        ffwd_rev_shift, ffwd_rev_ctrl, ffwd_rev_caps = edit_prefs_widgets
31
     
32
-    use_english, disp_splash, buttons_style, dark_theme, theme_combo, audio_levels_combo, window_mode_combo, full_names = view_prefs_widgets
33
+    use_english, disp_splash, buttons_style, dark_theme, theme_combo, audio_levels_combo, window_mode_combo, full_names, double_track_hights = view_prefs_widgets
34
 
35
     # Jan-2017 - SvdB
36
     perf_render_threads, perf_drop_frames = performance_widgets
37
 
38
+    # Apr-2017 - SvdB
39
+    #shortcuts_combo = shortcuts_widgets
40
+
41
     global prefs
42
     prefs.open_in_last_opended_media_dir = open_in_last_opened_check.get_active()
43
     prefs.remember_last_render_dir = open_in_last_rendered_check.get_active()
44
@@ -203,6 +211,10 @@
45
     prefs.play_pause = play_pause_button.get_active()
46
     prefs.hide_file_ext = hide_file_ext_button.get_active()
47
     prefs.mouse_scroll_action_is_zoom = (mouse_scroll_action.get_active() == 0)
48
+    # Apr-2017 - SvdB - ffwd / rev values
49
+    prefs.ffwd_rev_shift = int(ffwd_rev_shift.get_adjustment().get_value())
50
+    prefs.ffwd_rev_ctrl = int(ffwd_rev_ctrl.get_adjustment().get_value())
51
+    prefs.ffwd_rev_caps = int(ffwd_rev_caps.get_adjustment().get_value())
52
     
53
     prefs.use_english_always = use_english.get_active()
54
     prefs.display_splash_screen = disp_splash.get_active()
55
@@ -217,6 +229,12 @@
56
     # Feb-2017 - SvdB - for full file names
57
     prefs.show_full_file_names = full_names.get_active()
58
     prefs.center_on_arrow_move = auto_center_on_updown.get_active()
59
+    prefs.double_track_hights = (double_track_hights.get_active() == 1)
60
+
61
+    #if prefs.shortcuts != shortcuts.shortcut_files[shortcuts_combo.get_active()]:
62
+    #    prefs.shortcuts = shortcuts.shortcut_files[shortcuts_combo.get_active()]
63
+    #    shortcuts.load_shortcuts()
64
+
65
 
66
 def get_graphics_default_in_out_length():
67
     in_fr = int(15000/2) - int(prefs.default_grfx_length/2)
68
@@ -237,7 +255,6 @@
69
             os.mkdir(render_folder + "/")
70
         prefs.render_folder = render_folder
71
 
72
-
73
 class EditorPreferences:
74
     """
75
     Class holds data of persistant user preferences for editor.
76
@@ -303,3 +320,10 @@
77
         # Feb-2017 - SvdB - for full file names
78
         self.show_full_file_names = False
79
         self.center_on_arrow_move = False
80
+        # Apr-2017 - SvdB - Using these values we maintain the original hardcoded speed
81
+        self.ffwd_rev_shift = 1
82
+        self.ffwd_rev_ctrl = 10
83
+        self.ffwd_rev_caps = 1
84
+        self.shortcuts = "flowblade.xml"
85
+        self.double_track_hights = False
86
+        self.delta_overlay = True
87
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/editorstate.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/editorstate.py Changed
10
 
1
@@ -42,7 +42,7 @@
2
 SLIDE_TRIM_NO_EDIT = 9
3
 MULTI_MOVE = 10
4
 CLIP_END_DRAG = 11
5
-
6
+SELECT_TLINE_SYNC_CLIP = 12
7
 
8
 # Project being edited
9
 project = None
10
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/editorwindow.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/editorwindow.py Changed
148
 
1
@@ -31,12 +31,15 @@
2
 import app
3
 import appconsts
4
 import audiomonitoring
5
+import audiosync
6
 import batchrendering
7
 import boxmove
8
 import clipeffectseditor
9
 import clipmenuaction
10
 import compositeeditor
11
 import dialogs
12
+import dialogutils
13
+import diskcachemanagement
14
 import dnd
15
 import editevent
16
 import editorpersistance
17
@@ -192,8 +195,10 @@
18
             ('FiltersOff', None, _('All Filters Off'), None, None, lambda a:tlineaction.all_filters_off()),
19
             ('FiltersOn', None, _('All Filters On'), None, None, lambda a:tlineaction.all_filters_on()),
20
             ('SyncCompositors', None, _('Sync All Compositors'), None, None, lambda a:tlineaction.sync_all_compositors()),
21
+            ('CompositorsFadesDefaults', None, _('Set Compositor Auto Fades...'), None, None, lambda a:tlineaction.set_compositors_fades_defaults()),
22
             ('ChangeSequenceTracks', None, _('Change Sequence Tracks Count...'), None, None, lambda a:projectaction.change_sequence_track_count()),
23
             ('Watermark', None, _('Watermark...'), None, None, lambda a:menuactions.edit_watermark()),
24
+            ('DiskCacheManager', None, _('Disk Cache Manager'), None, None, lambda a:diskcachemanagement.show_disk_management_dialog()),
25
             ('ProfilesManager', None, _('Profiles Manager'), None, None, lambda a:menuactions.profiles_manager()),
26
             ('Preferences', None, _('Preferences'), None, None, lambda a:preferenceswindow.preferences_dialog()),
27
             ('ViewMenu', None, _('View')),
28
@@ -207,6 +212,12 @@
29
             ('CreateBarsClip', None, _('EBU Bars'), None, None, lambda a:patternproducer.create_bars_clip()),
30
             ('CreateIsingClip', None, _('Ising'), None, None, lambda a:patternproducer.create_icing_clip()),
31
             ('CreateColorPulseClip', None, _('Color Pulse'), None, None, lambda a:patternproducer.create_color_pulse_clip()),
32
+            ('CompoundClipsMenu', None, _('Create Compound Clip')),
33
+            ('CreateSelectionCompound', None, _('From Selected Clips'), None, None, lambda a:projectaction.create_selection_compound_clip()),
34
+            ('CreateSequenceCompound', None, _('From Current Sequence'), None, None, lambda a:projectaction.create_sequence_compound_clip()),
35
+            ('AudioSyncCompoundClip', None, _('Audio Sync Merge Clip From 2 Media Items '), None, None, lambda a:audiosync.create_audio_sync_compound_clip()),
36
+            ('ImportProjectMedia', None, _('Import Media From Project...'), None, None, lambda a:projectaction.import_project_media()),
37
+            ('CombineSequences', None, _('Import Another Sequence Into This Sequence...'), None, None, lambda a:projectaction.combine_sequences()),
38
             ('LogClipRange', None, _('Log Marked Clip Range'), '<control>L', None, lambda a:medialog.log_range_clicked()),
39
             ('RecreateMediaIcons', None, _('Recreate Media Icons...'), None, None, lambda a:menuactions.recreate_media_file_icons()),
40
             ('RemoveUnusedMedia', None, _('Remove Unused Media...'), None, None, lambda a:projectaction.remove_unused_media()),
41
@@ -226,7 +237,7 @@
42
             ('HelpMenu', None, _('_Help')),
43
             ('QuickReference', None, _('Contents'), None, None, lambda a:menuactions.quick_reference()),
44
             ('Environment', None, _('Runtime Environment'), None, None, lambda a:menuactions.environment()),
45
-            ('KeyboardShortcuts', None, _('Keyboard Shortcuts'), None, None, lambda a:dialogs.keyboard_shortcuts_dialog(self.window)),
46
+            ('KeyboardShortcuts', None, _('Keyboard Shortcuts'), None, None, lambda a:dialogs.keyboard_shortcuts_dialog(self.window, menuactions.keyboard_shortcuts_callback)),
47
             ('About', None, _('About'), None, None, lambda a:menuactions.about()),
48
             ('InsertMode', None, None, '1', None, lambda a:_this_is_not_used()),
49
             ('OverMode', None, None, '2', None, lambda a:_this_is_not_used()),
50
@@ -291,6 +302,8 @@
51
                     <menuitem action='Watermark'/>
52
                     <separator/>
53
                     <menuitem action='ProfilesManager'/>
54
+                    <menuitem action='DiskCacheManager'/>
55
+                    <menuitem action='KeyboardShortcuts'/>
56
                     <menuitem action='Preferences'/>
57
                 </menu>
58
                 <menu action='ViewMenu'>
59
@@ -307,6 +320,14 @@
60
                         <menuitem action='CreateIsingClip'/>
61
                         <menuitem action='CreateBarsClip'/>    
62
                     </menu>
63
+                    <menu action='CompoundClipsMenu'>
64
+                        <menuitem action='CreateSelectionCompound'/>
65
+                        <menuitem action='CreateSequenceCompound'/>
66
+                        <menuitem action='AudioSyncCompoundClip'/>
67
+                    </menu>
68
+                    <separator/>
69
+                    <menuitem action='ImportProjectMedia'/>
70
+                    <menuitem action='CombineSequences'/>
71
                     <separator/>
72
                     <menuitem action='LogClipRange'/>
73
                     <separator/>
74
@@ -333,7 +354,6 @@
75
                 </menu>
76
                 <menu action='HelpMenu'>
77
                     <menuitem action='QuickReference'/>
78
-                    <menuitem action='KeyboardShortcuts'/>
79
                     <menuitem action='Environment'/>
80
                     <separator/>
81
                     <menuitem action='About'/>
82
@@ -757,6 +777,28 @@
83
         sep = Gtk.SeparatorMenuItem()
84
         menu.append(sep)
85
 
86
+        windows_menu_item = Gtk.MenuItem(_("Window Mode").encode('utf-8'))
87
+        windows_menu =  Gtk.Menu()
88
+        one_window = Gtk.RadioMenuItem()
89
+        one_window.set_label( _("Single Window").encode('utf-8'))
90
+
91
+        windows_menu.append(one_window)
92
+        
93
+        two_windows = Gtk.RadioMenuItem.new_with_label([one_window], _("Two Windows").encode('utf-8'))
94
+
95
+
96
+        if editorpersistance.prefs.global_layout == appconsts.SINGLE_WINDOW:
97
+            one_window.set_active(True)
98
+        else:
99
+            two_windows.set_active(True)
100
+
101
+        one_window.connect("activate", lambda w: self._change_windows_preference(w, appconsts.SINGLE_WINDOW))
102
+        two_windows.connect("activate", lambda w: self._change_windows_preference(w, appconsts.TWO_WINDOWS))
103
+        
104
+        windows_menu.append(two_windows)
105
+        windows_menu_item.set_submenu(windows_menu)
106
+        menu.append(windows_menu_item)
107
+        
108
         mb_menu_item = Gtk.MenuItem(_("Middlebar Layout").encode('utf-8'))
109
         mb_menu = Gtk.Menu()
110
         tc_left = Gtk.RadioMenuItem()
111
@@ -861,6 +903,18 @@
112
         else:
113
             self.notebook.set_tab_pos(Gtk.PositionType.BOTTOM)
114
 
115
+    def _change_windows_preference(self, widget, new_window_layout):
116
+        if widget.get_active() == False:
117
+            return
118
+
119
+        editorpersistance.prefs.global_layout = new_window_layout
120
+        editorpersistance.save()
121
+        
122
+        primary_txt = _("Global Window Mode changed")
123
+        secondary_txt = _("Application restart required for the new layout choice to take effect.")
124
+        
125
+        dialogutils.info_message(primary_txt, secondary_txt, self.window)
126
+        
127
     def _show_tabs_up(self, widget):
128
         if widget.get_active() == False:
129
             return
130
@@ -968,7 +1022,7 @@
131
         return buttons_row
132
 
133
     def _add_tool_tips(self):
134
-        self.big_TC.widget.set_tooltip_text(_("Timeline current frame timecode"))
135
+        self.big_TC.set_tooltip_text(_("Timeline current frame timecode"))
136
 
137
         self.view_mode_select.widget.set_tooltip_text(_("Select view mode: Video/Vectorscope/RGBParade"))
138
         
139
@@ -1090,6 +1144,8 @@
140
             cursor = self.get_own_cursor(display, SLIDE_NO_EDIT_CURSOR, 9, 9)
141
         elif mode == editorstate.SELECT_PARENT_CLIP:
142
             cursor =  Gdk.Cursor.new(Gdk.CursorType.TCROSS)
143
+        elif mode == editorstate.SELECT_TLINE_SYNC_CLIP:
144
+            cursor =  Gdk.Cursor.new(Gdk.CursorType.TCROSS)
145
         elif mode == editorstate.MULTI_MOVE:
146
             cursor = self.get_own_cursor(display, MULTIMOVE_CURSOR, 4, 8)
147
         elif mode == editorstate.CLIP_END_DRAG:
148
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/glassbuttons.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/glassbuttons.py Changed
10
 
1
@@ -519,7 +519,7 @@
2
 def focus_group_has_focus(focus_group):
3
     group = focus_groups[focus_group]
4
     for widget in group:
5
-        if widget.is_focus():
6
+        if widget.has_focus():
7
             return True
8
     
9
     return False
10
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/guicomponents.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/guicomponents.py Changed
201
 
1
@@ -50,6 +50,7 @@
2
 import mlttransitions
3
 import monitorwidget
4
 import respaths
5
+import shortcuts
6
 import snapping
7
 import toolsintegration
8
 import translations
9
@@ -1128,6 +1129,8 @@
10
 
11
     clip_menu = clip_popup_menu
12
     guiutils.remove_children(clip_menu)
13
+    
14
+    # Menu items    
15
     clip_menu.add(_get_menu_item(_("Open in Filters Editor"), callback, (clip, track, "open_in_editor", event.x)))
16
     # Only make opening in compositor editor for video tracks V2 and higher
17
     if track.id <= current_sequence().first_video_index:
18
@@ -1165,6 +1168,11 @@
19
            clip_menu.add(_get_menu_item(_("Clear Waveform"), callback,\
20
               (clip, track, "clear_waveform", event.x), True))
21
 
22
+    audio_sync_item = _get_menu_item(_("Select Clip to Audio Sync With..."), callback, (clip, track, "set_audio_sync_clip", event.x))
23
+    if utils.is_mlt_xml_file(clip.path) == True:
24
+        audio_sync_item.set_sensitive(False)
25
+    clip_menu.add(audio_sync_item)
26
+            
27
     _add_separetor(clip_menu)
28
 
29
     if track.id != current_sequence().first_video_index:
30
@@ -1188,6 +1196,7 @@
31
     else:
32
         active = True
33
     clip_menu.add(_get_compositors_add_menu_item(event, clip, track, callback, active))
34
+    clip_menu.add(_get_auto_fade_compositors_add_menu_item(event, clip, track, callback, active))
35
     clip_menu.add(_get_blenders_add_menu_item(event, clip, track, callback, active))
36
 
37
     _add_separetor(clip_menu)
38
@@ -1208,7 +1217,11 @@
39
     if track.type == appconsts.VIDEO and clip.media_type != appconsts.PATTERN_PRODUCER:
40
         _add_separetor(clip_menu)
41
         clip_menu.add(_get_match_frame_menu_item(event, clip, track, callback))
42
-            
43
+
44
+    _add_separetor(clip_menu)
45
+    
46
+    clip_menu.add(_get_edit_menu_item(event, clip, track, callback))
47
+
48
     clip_menu.popup(None, None, None, None, event.button, event.time)
49
 
50
 
51
@@ -1298,7 +1311,11 @@
52
 
53
     _add_separetor(clip_menu)
54
     clip_menu.add(_get_select_menu_item(event, clip, track, callback))
55
+
56
+    _add_separetor(clip_menu)
57
     
58
+    clip_menu.add(_get_edit_menu_item(event, clip, track, callback))
59
+
60
     clip_menu.popup(None, None, None, None, event.button, event.time)
61
 
62
 def display_compositor_popup_menu(event, compositor, callback):
63
@@ -1394,6 +1411,26 @@
64
     menu_item.show()
65
     return menu_item
66
 
67
+def _get_auto_fade_compositors_add_menu_item(event, clip, track, callback, sensitive):
68
+    menu_item = Gtk.MenuItem(_("Add Fade"))
69
+    sub_menu = Gtk.Menu()
70
+    menu_item.set_submenu(sub_menu)
71
+
72
+    for i in range(0, len(mlttransitions.autofades)):
73
+        auto_fade_compositor = mlttransitions.autofades[i]
74
+        name, compositor_type = auto_fade_compositor
75
+        try:
76
+            info = mlttransitions.mlt_compositor_transition_infos[compositor_type]
77
+        except:
78
+            continue
79
+        compositor_item = Gtk.MenuItem(name)
80
+        sub_menu.append(compositor_item)
81
+        compositor_item.connect("activate", callback, (clip, track, "add_autofade", (event.x, compositor_type)))
82
+        compositor_item.show()
83
+    menu_item.set_sensitive(sensitive)
84
+    menu_item.show()
85
+    return menu_item
86
+    
87
 def _get_match_frame_menu_item(event, clip, track, callback):
88
     menu_item = Gtk.MenuItem(_("Show Match Frame"))
89
     sub_menu = Gtk.Menu()
90
@@ -1468,6 +1505,31 @@
91
     menu_item.show()
92
     return menu_item
93
 
94
+def _get_edit_menu_item(event, clip, track, callback):
95
+    menu_item = Gtk.MenuItem(_("Edit"))
96
+    sub_menu = Gtk.Menu()
97
+    menu_item.set_submenu(sub_menu)
98
+
99
+    del_item = _get_menu_item(_("Delete"), callback, (clip, track, "delete", event.x))
100
+    sub_menu.append(del_item)
101
+
102
+    lift_item = _get_menu_item(_("Lift"), callback, (clip, track, "lift", event.x))
103
+    sub_menu.append(lift_item)
104
+    
105
+    _add_separetor(sub_menu)
106
+
107
+    length_item = _get_menu_item(_("Set Clip Length..."), callback, (clip, track, "length", event.x))
108
+    sub_menu.append(length_item)
109
+
110
+    stretch_next_item = _get_menu_item(_("Stretch Over Next Blank"), callback, (clip, track, "stretch_next", event.x))
111
+    sub_menu.append(stretch_next_item)
112
+
113
+    stretch_prev_item = _get_menu_item(_("Stretch Over Prev Blank"), callback, (clip, track, "stretch_prev", event.x))
114
+    sub_menu.append(stretch_prev_item)
115
+    
116
+    menu_item.show()
117
+    return menu_item
118
+    
119
 def _get_clone_filters_menu_item(event, clip, track, callback):
120
     menu_item = Gtk.MenuItem(_("Clone Filters"))
121
     sub_menu = Gtk.Menu()
122
@@ -1582,6 +1644,8 @@
123
         _add_separetor(media_file_menu)
124
         if media_file.type != appconsts.IMAGE_SEQUENCE:
125
             media_file_menu.add(_get_menu_item(_("Render Slow/Fast Motion File"), callback, ("Render Slow/Fast Motion File", media_file, event)))
126
+        if media_file.type != appconsts.IMAGE_SEQUENCE:
127
+            media_file_menu.add(_get_menu_item(_("Render Reverse Motion File"), callback, ("Render Reverse Motion File", media_file, event)))
128
     if media_file.type == appconsts.VIDEO or media_file.type == appconsts.IMAGE_SEQUENCE:
129
         item = _get_menu_item(_("Render Proxy File"), callback, ("Render Proxy File", media_file, event))
130
         media_file_menu.add(item)
131
@@ -1780,6 +1844,8 @@
132
         self.TEXT_X = 18
133
         self.TEXT_Y = 1
134
 
135
+        self.widget.connect("button-press-event", self._button_press)
136
+
137
     def _draw(self, event, cr, allocation):
138
         """
139
         Callback for repaint from CairoDrawableArea.
140
@@ -1834,6 +1900,56 @@
141
         cr.arc (x + radius, y + radius, radius, 180 * degrees, 270 * degrees)
142
         cr.close_path ()
143
 
144
+    def _button_press(self, widget, event):
145
+        gui.big_tc.set_visible_child_name("BigTCEntry")
146
+        entry = gui.big_tc.get_visible_child()
147
+        entry.set_text(BigTCEntry().get_current_frame_text())
148
+        entry.grab_focus()
149
+
150
+    def _seek_frame(self, frame):
151
+        PLAYER().seek_frame(frame)
152
+
153
+
154
+class BigTCEntry:
155
+    """
156
+    Test class for replacement of BigTCDisplay, when Editing time position
157
+    """
158
+
159
+    def __init__(self):
160
+        self.widget = Gtk.Entry()
161
+        frame_str = self.get_current_frame_text()
162
+        self.widget.set_text(frame_str)
163
+        self.visible = False
164
+        self.widget.connect("activate", self._enter_pressed)
165
+        self.widget.connect("focus-out-event", self._focus_lost)
166
+        self.widget.connect("focus", self._focus_received)
167
+
168
+    def get_current_frame_text(self):
169
+        try:
170
+            frame = PLAYER().tracktor_producer.frame()
171
+            frame_str = utils.get_tc_string(frame)
172
+        except:
173
+            frame_str = "00:00:00:00"
174
+        return frame_str
175
+
176
+    def _handle_set_time(self):
177
+        self.visible = False
178
+        frame_str = gui.big_tc.get_visible_child().get_text()
179
+        frame = utils.get_tc_frame(frame_str)
180
+        gui.big_tc.set_visible_child_name("BigTCDisplay")
181
+        PLAYER().seek_frame(int(frame))
182
+
183
+    def _enter_pressed(self, event):
184
+        self._handle_set_time()
185
+
186
+    def _focus_lost(self, widget, event):
187
+        if self.visible:
188
+            self._handle_set_time()
189
+
190
+    def _focus_received(self, widget, event):
191
+        self.visible = True
192
+
193
+
194
 
195
 class MonitorTCDisplay:
196
     """
197
@@ -1960,16 +2076,17 @@
198
         self.MAX_TRACKS = appconsts.MAX_TRACKS
199
         
200
         self.widget = Gtk.HBox()
201
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/guiutils.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/guiutils.py Changed
41
 
1
@@ -169,11 +169,38 @@
2
         name = slider_name
3
     name = translations.get_param_name(name)
4
     
5
-    editable_property.value_changed_ID = adjustment.connect("value-changed", listener) # patching in to make available for disconnect
6
+    editable_property.value_changed_ID = adjustment.connect("value-changed", listener) # saving ID to make it available for disconnect
7
                                                                                        # This also needs to be after adjustment is set to not loose exiting value for build dummy value 
8
         
9
     return (get_two_column_editor_row(name, hbox), hslider)
10
 
11
+def get_slider_row_and_spin_widget(editable_property, listener, slider_name=None):
12
+    adjustment = editable_property.get_input_range_adjustment()
13
+    editable_property.adjustment = adjustment # patching in to make available for disconnect
14
+
15
+    hslider = Gtk.HScale()
16
+    hslider.set_adjustment(adjustment)
17
+    hslider.set_draw_value(False)
18
+    
19
+    spin = Gtk.SpinButton()
20
+    spin.set_numeric(True)
21
+    spin.set_adjustment(adjustment)
22
+
23
+    hbox = Gtk.HBox(False, 4)
24
+    hbox.pack_start(hslider, True, True, 0)
25
+    hbox.pack_start(spin, False, False, 4)
26
+    
27
+    if slider_name == None:
28
+        name = editable_property.get_display_name()
29
+    else:
30
+        name = slider_name
31
+    name = translations.get_param_name(name)
32
+    
33
+    editable_property.value_changed_ID = adjustment.connect("value-changed", listener) # saving ID to make it available for disconnect
34
+                                                                                       # This also needs to be available after adjustment is set to not lose exiting value for build dummy value 
35
+        
36
+    return (get_two_column_editor_row(name, hbox), hslider, spin)
37
+    
38
 def get_non_property_slider_row(lower, upper, step, value=0, listener=None):
39
     hslider = Gtk.HScale()
40
     hslider.set_draw_value(False)
41
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/keyevents.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/keyevents.py Changed
201
 
1
@@ -25,6 +25,7 @@
2
 from gi.repository import Gtk
3
 from gi.repository import Gdk
4
 
5
+import appconsts
6
 import audiowaveform
7
 import clipeffectseditor
8
 import compositeeditor
9
@@ -42,6 +43,9 @@
10
 import menuactions
11
 import monitorevent
12
 import mltrefhold
13
+# Apr-2017 - SvdB
14
+import shortcuts
15
+import re
16
 import tlineaction
17
 import tlinewidgets
18
 import trimmodes
19
@@ -61,9 +65,11 @@
20
         if audiowaveform.waveform_thread != None:
21
             audiowaveform.waveform_thread.abort_rendering()
22
             return True
23
-        else:
24
-            if editorstate.current_is_move_mode() == False:
25
-                editevent.set_default_edit_mode()
26
+        elif editorstate.current_is_move_mode() == False:
27
+            editevent.set_default_edit_mode()
28
+            return True
29
+        elif gui.big_tc.get_visible_child_name() == "BigTCEntry":
30
+            gui.big_tc.set_visible_child_name("BigTCDisplay")
31
             return True
32
 
33
     # Compositor editors keyevents
34
@@ -150,14 +156,14 @@
35
     return False
36
     
37
 def _timeline_has_focus():
38
-    if(gui.tline_canvas.widget.is_focus()
39
-       or gui.tline_column.widget.is_focus()
40
-       or gui.editor_window.modes_selector.widget.is_focus()
41
-       or (gui.pos_bar.widget.is_focus() and timeline_visible())
42
-       or gui.tline_scale.widget.is_focus()
43
+    if(gui.tline_canvas.widget.has_focus()
44
+       or gui.tline_column.widget.has_focus()
45
+       or gui.editor_window.modes_selector.widget.has_focus()
46
+       or (gui.pos_bar.widget.has_focus() and timeline_visible())
47
+       or gui.tline_scale.widget.has_focus()
48
        or glassbuttons.focus_group_has_focus(glassbuttons.DEFAULT_FOCUS_GROUP)):
49
         return True
50
-    
51
+        
52
     return False
53
     
54
 def _handle_tline_key_event(event):
55
@@ -166,117 +172,94 @@
56
     Returns True for handled key presses to stop those
57
     keyevents from going forward.
58
     """
59
-    # I
60
-    if event.keyval == Gdk.KEY_i:
61
-        if (event.get_state() & Gdk.ModifierType.MOD1_MASK):
62
-            monitorevent.to_mark_in_pressed()
63
-            return True
64
+    # Apr-2017 - SvdB - For keyboard shortcuts
65
+    action = _get_shortcut_action(event)
66
+    
67
+    # Apr-2017 - SvdB - For ffwd / rev speeds
68
+    prefs = editorpersistance.prefs
69
+
70
+    if action == 'mark_in':
71
         monitorevent.mark_in_pressed()
72
         return True
73
-    if event.keyval == Gdk.KEY_I:
74
-        if (event.get_state() & Gdk.ModifierType.MOD1_MASK):
75
-            monitorevent.to_mark_in_pressed()
76
-            return True
77
+    if action == 'to_mark_in':
78
         monitorevent.to_mark_in_pressed()
79
         return True
80
-
81
-    # O
82
-    if event.keyval == Gdk.KEY_o:
83
-        if (event.get_state() & Gdk.ModifierType.MOD1_MASK):
84
-            monitorevent.to_mark_out_pressed()
85
-            return True
86
+    if action == 'zoom_out':
87
+        updater.zoom_out()
88
+    if action == 'zoom_in':
89
+        updater.zoom_in()
90
+    if action == 'mark_out':
91
         monitorevent.mark_out_pressed()
92
         return True
93
-    if event.keyval == Gdk.KEY_O:
94
-        if (event.get_state() & Gdk.ModifierType.MOD1_MASK):
95
-            monitorevent.to_mark_out_pressed()
96
-            return True
97
+    if action == 'to_mark_out':
98
         monitorevent.to_mark_out_pressed()
99
         return True
100
-
101
-    # SPACE
102
-    if event.keyval == Gdk.KEY_space:
103
+    if action == 'play_pause':
104
         if PLAYER().is_playing():
105
             monitorevent.stop_pressed()
106
         else:
107
             monitorevent.play_pressed()
108
         return True
109
-    
110
-    # TAB
111
-    if event.keyval == Gdk.KEY_Tab:
112
+    if action == 'switch_monitor':
113
         updater.switch_monitor_display()
114
         return True
115
-
116
-    # M
117
-    if event.keyval == Gdk.KEY_m:
118
+    if action == 'add_marker':
119
         tlineaction.add_marker()
120
         return True
121
-
122
-    # Number edit mode changes
123
-    if event.keyval == Gdk.KEY_1:
124
+    if action == 'edit_mode_insert':
125
         gui.editor_window.handle_insert_move_mode_button_press()
126
         gui.editor_window.set_mode_selector_to_mode()
127
         return True
128
-    if event.keyval == Gdk.KEY_2:
129
+    if action == 'edit_mode_overwrite':
130
         gui.editor_window.handle_over_move_mode_button_press()
131
         gui.editor_window.set_mode_selector_to_mode()
132
         return True
133
-    if event.keyval == Gdk.KEY_3:
134
+    if action == 'edit_mode_trim':
135
         gui.editor_window.handle_one_roll_mode_button_press()
136
         gui.editor_window.set_mode_selector_to_mode()
137
         return True
138
-    if event.keyval == Gdk.KEY_4:
139
+    if action == 'edit_mode_roll':
140
         gui.editor_window.handle_two_roll_mode_button_press()
141
         gui.editor_window.set_mode_selector_to_mode()
142
         return True
143
-    if event.keyval == Gdk.KEY_5:
144
+    if action == 'edit_mode_slip':
145
         gui.editor_window.handle_slide_mode_button_press()
146
         gui.editor_window.set_mode_selector_to_mode()
147
         return True
148
-    if event.keyval == Gdk.KEY_6:
149
+    if action == 'edit_mode_spacer':
150
         gui.editor_window.handle_multi_mode_button_press()
151
         gui.editor_window.set_mode_selector_to_mode()
152
         return True
153
-    if event.keyval == Gdk.KEY_7:
154
+    if action == 'edit_mode_box':
155
         gui.editor_window.handle_box_mode_button_press()
156
         gui.editor_window.set_mode_selector_to_mode()
157
         return True
158
-        
159
-    # X
160
-    if event.keyval == Gdk.KEY_x:
161
+    if action == 'cut':
162
         tlineaction.cut_pressed()
163
         return True
164
-
165
-    # G
166
-    if event.keyval == Gdk.KEY_g:
167
+    if action == 'log_range':
168
         medialog.log_range_clicked()
169
         return True
170
-
171
-    # R
172
-    if event.keyval == Gdk.KEY_r:
173
+    if action == 'toggle_ripple':
174
         gui.editor_window.toggle_trim_ripple_mode()
175
         return True
176
-
177
+    
178
+    
179
     # Key bindings for keyboard trimming
180
     if editorstate.current_is_active_trim_mode() == True:
181
-        # LEFT ARROW, prev frame
182
-        if event.keyval == Gdk.KEY_Left:
183
+        if action == 'prev_frame':
184
             trimmodes.left_arrow_pressed((event.get_state() & Gdk.ModifierType.CONTROL_MASK))
185
             return True
186
-
187
-        # RIGHT ARROW, next frame
188
-        if event.keyval == Gdk.KEY_Right:
189
+        elif action == 'next_frame':
190
             trimmodes.right_arrow_pressed((event.get_state() & Gdk.ModifierType.CONTROL_MASK))
191
             return True
192
-
193
-        if event.keyval == Gdk.KEY_Return:
194
+        elif action == 'enter_edit':
195
             trimmodes.enter_pressed()
196
             return True
197
 
198
     # Key bindings for MOVE MODES and _NO_EDIT modes
199
     if editorstate.current_is_move_mode() or editorstate.current_is_active_trim_mode() == False:
200
-         # UP ARROW, next cut
201
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/keyframeeditor.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/keyframeeditor.py Changed
191
 
1
@@ -113,7 +113,9 @@
2
 DISCONNECTED_SIGNAL_HANDLER = -9999999
3
 
4
 actions_menu = Gtk.Menu()
5
-        
6
+
7
+_shift_down = None
8
+
9
 # ----------------------------------------------------- editor objects
10
 class ClipKeyFrameEditor:
11
     """
12
@@ -319,7 +321,7 @@
13
                     next_frame, val = self.keyframes[hit_kf + 1]
14
                     self.drag_max = next_frame - 1
15
                 except:
16
-                    self.drag_max = self.clip_length - 1
17
+                    self.drag_max = self.clip_length
18
             self.widget.queue_draw()
19
 
20
     def _motion_notify_event(self, x, y, state):
21
@@ -332,9 +334,6 @@
22
             self._set_clip_frame(lx)
23
             self.parent_editor.clip_editor_frame_changed(self.current_clip_frame)
24
         elif self.current_mouse_action == KF_DRAG:
25
-            if abs(lx - self.drag_start_x) < KF_DRAG_THRESHOLD:
26
-                return
27
-            
28
             frame = self._get_drag_frame(lx)
29
             self.set_active_kf_frame(frame)
30
             self.current_clip_frame = frame
31
@@ -354,8 +353,6 @@
32
             self.parent_editor.clip_editor_frame_changed(self.current_clip_frame)
33
             self.parent_editor.update_slider_value_display(self.current_clip_frame)
34
         elif self.current_mouse_action == KF_DRAG:
35
-            if abs(lx - self.drag_start_x) < KF_DRAG_THRESHOLD:
36
-                return
37
             frame = self._get_drag_frame(lx)
38
             self.set_active_kf_frame(frame)
39
             self.current_clip_frame = frame
40
@@ -805,7 +802,6 @@
41
         self.keyframes.sort(key=_geom_kf_sort)
42
         
43
     def delete_active_keyframe(self, keyframe_index):
44
-        #print keyframe_index
45
         if keyframe_index == 0:
46
             # keyframe frame 0 cannot be removed
47
             return
48
@@ -878,13 +874,15 @@
49
         delta_x = x - self.mouse_start_x
50
         delta_y = y - self.mouse_start_y
51
         
52
+        global _shift_down 
53
         if state & Gdk.ModifierType.SHIFT_MASK:
54
             if abs(x - self.mouse_start_x) < abs(y - self.mouse_start_y):
55
                 delta_x = 0
56
             else:
57
                 delta_y = 0
58
-        #elif state & Gdk.ModifierType.CONTROL_MASK:
59
-        #    print "control"
60
+            _shift_down = (self.mouse_start_x, self.mouse_start_y)
61
+        else:
62
+            _shift_down = None
63
                 
64
         self._shape__motion_notify_event(delta_x, delta_y, (state & Gdk.ModifierType.CONTROL_MASK))
65
 
66
@@ -893,8 +891,10 @@
67
     def _shape__motion_notify_event(self, delta_x, delta_y, CTRL_DOWN):
68
         print "_shape__motion_notify_event not impl"
69
 
70
-    
71
     def _release_event(self, event):
72
+        global _shift_down 
73
+        _shift_down = None
74
+        
75
         if self.current_mouse_hit == NO_HIT:
76
             return
77
             
78
@@ -944,6 +944,17 @@
79
                        self.coords.screen_w, self.coords.screen_h)
80
         cr.fill()
81
 
82
+        if _shift_down != None:
83
+            cr.set_source_rgb(0.0, 0.0, 0.77)
84
+            cr.set_line_width(1.0)
85
+            mx, my = _shift_down
86
+            cr.move_to(mx, 0)
87
+            cr.line_to(mx, h)
88
+            cr.stroke()
89
+            cr.move_to(0, my)
90
+            cr.line_to(w, my)
91
+            cr.stroke()
92
+            
93
         screen_rect = [self.coords.orig_x, self.coords.orig_y, 
94
                        self.coords.screen_w, self.coords.screen_h]
95
         self._draw_edge(cr, screen_rect)
96
@@ -1075,7 +1086,7 @@
97
     def _draw_edit_shape(self, cr, allocation):
98
         # Edit rect is created here only when we're sure to have allocation
99
         if self.source_edit_rect == None:
100
-            self.source_edit_rect = EditRect(10, 10, 10, 10) # values are immediatyly overwritten
101
+            self.source_edit_rect = EditRect(10, 10, 10, 10) # values are immediately overwritten
102
             self._update_source_rect()
103
 
104
         # Draw source
105
@@ -1618,10 +1629,11 @@
106
             self.clip_in = 0
107
 
108
         # Value slider
109
-        row, slider = guiutils.get_slider_row(editable_property, self.slider_value_changed)
110
+        row, slider, spin = guiutils.get_slider_row_and_spin_widget(editable_property, self.slider_value_changed)
111
         self.value_slider_row = row
112
         self.slider = slider
113
-        
114
+        self.spin = spin
115
+
116
         self.initializing = False # Hack against too early for on slider listner
117
 
118
     def display_tline_frame(self, tline_frame):
119
@@ -1769,13 +1781,22 @@
120
         self.queue_draw()
121
 
122
     def connect_to_update_on_release(self):
123
+        print "jjjjjj"
124
         self.editable_property.adjustment.disconnect(self.editable_property.value_changed_ID)
125
         self.editable_property.value_changed_ID = DISCONNECTED_SIGNAL_HANDLER
126
+        self.spin.connect("activate", lambda w:self.spin_value_changed(w))
127
+        self.spin.connect("button-release-event", lambda w, e:self.spin_value_changed(w))
128
         self.slider.connect("button-release-event", lambda w, e:self.slider_value_changed(w.get_adjustment()))
129
         
130
     def update_property_value(self):
131
         self.editable_property.write_out_keyframes(self.clip_editor.keyframes)
132
 
133
+    def spin_value_changed(self, w):
134
+        adj = w.get_adjustment()
135
+        val = int(w.get_text())
136
+        adj.set_value(float(val))
137
+        self.slider_value_changed(adj)
138
+
139
 
140
 class GeometryEditor(AbstractKeyFrameEditor):
141
     """
142
@@ -1988,6 +2009,7 @@
143
             view_size_index = 2
144
         self.geom_buttons_row.size_select.set_active(view_size_index)
145
 
146
+
147
 class RotatingGeometryEditor(GeometryEditor):
148
     
149
     def init_geom_gui(self, editable_property):
150
@@ -2000,37 +2022,9 @@
151
         self.geom_kf_edit.keyframe_parser = propertyparse.rotating_geom_keyframes_value_string_to_geom_kf_array
152
         self.geom_kf_edit.set_keyframes(editable_property.value, editable_property.get_in_value)
153
 
154
-def rotating_ge_write_out_keyframes(ep, keyframes):
155
-    x_val = ""
156
-    y_val = ""
157
-    x_scale_val = ""
158
-    y_scale_val = ""
159
-    rotation_val = ""
160
-    opacity_val = ""
161
-    
162
-    for kf in keyframes:
163
-        frame, transf, opacity = kf
164
-        x, y, x_scale, y_scale, rotation = transf
165
-        x_val += str(frame) + "=" + str(propertyparse.get_frei0r_cairo_position(x, ep.profile_width)) + ";"
166
-        y_val += str(frame) + "=" + str(propertyparse.get_frei0r_cairo_position(y, ep.profile_height)) + ";"
167
-        x_scale_val += str(frame) + "=" + str(propertyparse.get_frei0r_cairo_scale(x_scale)) + ";"
168
-        y_scale_val += str(frame) + "=" + str(propertyparse.get_frei0r_cairo_scale(y_scale)) + ";"
169
-        rotation_val += str(frame) + "=" + str(rotation / 360.0) + ";"
170
-        opacity_val += str(frame) + "=" + str(opacity / 100.0) + ";"
171
-
172
-    x_val = x_val.strip(";")
173
-    y_val = y_val.strip(";")
174
-    x_scale_val = x_scale_val.strip(";")
175
-    y_scale_val = y_scale_val.strip(";")
176
-    rotation_val = rotation_val.strip(";")
177
-    opacity_val = opacity_val.strip(";")
178
-   
179
-    ep.x.write_value(x_val)
180
-    ep.y.write_value(y_val)
181
-    ep.x_scale.write_value(x_scale_val)
182
-    ep.y_scale.write_value(y_scale_val)
183
-    ep.rotation.write_value(rotation_val)
184
-    ep.opacity.write_value(opacity_val)
185
+
186
+
187
+
188
 
189
 # ----------------------------------------------------------------- linear interpolation
190
 def _get_frame_value(frame, keyframes):
191
flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/launch/flowbladeclapperless Added
17
 
1
@@ -0,0 +1,15 @@
2
+#!/usr/bin/env python
3
+
4
+import sys
5
+import os
6
+
7
+
8
+modules_path = os.path.dirname(os.path.abspath(sys.argv[0])).rstrip("/launch")
9
+
10
+sys.path.insert(0, modules_path)
11
+sys.path.insert(0, modules_path + "/vieweditor")
12
+sys.path.insert(0, modules_path + "/tools")
13
+
14
+import clapperless
15
+
16
+clapperless.main()
17
flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/launch/flowblademediaimport Added
31
 
1
@@ -0,0 +1,29 @@
2
+#!/usr/bin/env python
3
+
4
+import sys
5
+import os
6
+
7
+
8
+modules_path = os.path.dirname(os.path.abspath(sys.argv[0])).rstrip("/launch")
9
+
10
+sys.path.insert(0, modules_path)
11
+sys.path.insert(0, modules_path + "/vieweditor")
12
+sys.path.insert(0, modules_path + "/tools")
13
+
14
+
15
+try:
16
+    import projectmediaimport
17
+    import editorstate # Used to decide which translations from file system are used
18
+    root_dir = modules_path.split("/")[1]
19
+    if root_dir != "home":
20
+        editorstate.app_running_from = editorstate.RUNNING_FROM_INSTALLATION
21
+    else:
22
+        editorstate.app_running_from = editorstate.RUNNING_FROM_DEV_VERSION
23
+except Exception, err:
24
+    print "Failed to import projectmediaimport"
25
+    print "ERROR:", err
26
+    print "Installation was assumed to be at:", modules_path
27
+    sys.exit(1)
28
+
29
+
30
+projectmediaimport.main(modules_path, sys.argv[1]) # sys.argv[1] is a file path to project that is the media import target
31
flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/launch/natron_render.sh Added
8
 
1
@@ -0,0 +1,6 @@
2
+#!/bin/bash
3
+
4
+#NatronRenderer -w Write2 1-10 /home/janne/test/natrontestout/frame###.png /home/janne/test/natrontest.ntp
5
+RENDER_COMMAND="-w "$1" "$2" "$3" "$4
6
+echo $RENDER_COMMAND
7
+NatronRenderer  $RENDER_COMMAND
8
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/locale/Flowblade/flowblade.pot -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/locale/Flowblade/flowblade.pot Changed
201
 
1
@@ -8,7 +8,7 @@
2
 msgstr ""
3
 "Project-Id-Version: PACKAGE VERSION\n"
4
 "Report-Msgid-Bugs-To: \n"
5
-"POT-Creation-Date: 2017-03-20 09:48+0200\n"
6
+"POT-Creation-Date: 2017-10-04 15:30+0300\n"
7
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
8
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
9
 "Language-Team: LANGUAGE <LL@li.org>\n"
10
@@ -17,552 +17,633 @@
11
 "Content-Type: text/plain; charset=CHARSET\n"
12
 "Content-Transfer-Encoding: 8bit\n"
13
 
14
-#: app.py:761
15
+#: app.py:780
16
 msgid "Too small screen for this application."
17
 msgstr ""
18
 
19
-#: app.py:764
20
+#: app.py:783
21
 msgid "Minimum screen dimensions for this application are 1152 x 768.\n"
22
 msgstr ""
23
 
24
-#: app.py:765
25
+#: app.py:784
26
 msgid "Your screen dimensions are "
27
 msgstr ""
28
 
29
-#: app.py:798 projectaction.py:365 projectaction.py:695
30
+#: app.py:817 projectaction.py:380 projectaction.py:714
31
 msgid "Project has not been saved previously"
32
 msgstr ""
33
 
34
-#: app.py:799 projectaction.py:366 projectaction.py:696
35
+#: app.py:818 projectaction.py:381 projectaction.py:715
36
 msgid "Save project with File -> Save As before closing."
37
 msgstr ""
38
 
39
-#: projectaction.py:111
40
+#: projectaction.py:121
41
 msgid "Media asset was missing!"
42
 msgstr ""
43
 
44
-#: projectaction.py:112
45
+#: projectaction.py:122
46
 msgid "Path of missing asset:"
47
 msgstr ""
48
 
49
-#: projectaction.py:113
50
+#: projectaction.py:123
51
 msgid ""
52
 "Relative search for replacement file in sub folders of project file failed."
53
 msgstr ""
54
 
55
-#: projectaction.py:114
56
+#: projectaction.py:124
57
 msgid "To load the project you will need to either:"
58
 msgstr ""
59
 
60
-#: projectaction.py:115
61
+#: projectaction.py:125
62
 msgid ""
63
 "Open project in 'Media Relinker' tool to relink media assets to new files, or"
64
 msgstr ""
65
 
66
-#: projectaction.py:116
67
+#: projectaction.py:126
68
 msgid "Place a file with the same exact name and path on the hard drive"
69
 msgstr ""
70
 
71
-#: projectaction.py:117
72
+#: projectaction.py:127
73
 msgid "Open project in Media Relinker tool"
74
 msgstr ""
75
 
76
-#: projectaction.py:136
77
+#: projectaction.py:146
78
 msgid "Profile with Description: '"
79
 msgstr ""
80
 
81
-#: projectaction.py:136
82
+#: projectaction.py:146
83
 msgid "' was not found on load!"
84
 msgstr ""
85
 
86
-#: projectaction.py:137
87
+#: projectaction.py:147
88
 msgid ""
89
 "It is possible to load the project by creating a User Profile with exactly "
90
 "the same Description\n"
91
 "as the missing profile. "
92
 msgstr ""
93
 
94
-#: projectaction.py:138
95
+#: projectaction.py:148
96
 msgid "User Profiles can be created by selecting 'Edit->Profiles Manager'."
97
 msgstr ""
98
 
99
-#: projectaction.py:145
100
+#: projectaction.py:155
101
 msgid "Opening"
102
 msgstr ""
103
 
104
-#: projectaction.py:275
105
+#: projectaction.py:288
106
 msgid "Media files already present in project were opened!"
107
 msgstr ""
108
 
109
-#: projectaction.py:281
110
+#: projectaction.py:294
111
 msgid ""
112
 "Files already present:\n"
113
 "\n"
114
 msgstr ""
115
 
116
-#: projectaction.py:480
117
+#: projectaction.py:495
118
 msgid "Selected folder contains files"
119
 msgstr ""
120
 
121
-#: projectaction.py:481
122
+#: projectaction.py:496
123
 msgid ""
124
 "When saving a back-up snapshot of the project, the selected folder\n"
125
 "has to be empty."
126
 msgstr ""
127
 
128
-#: projectaction.py:552
129
+#: projectaction.py:571
130
 msgid "Copying project media assets"
131
 msgstr ""
132
 
133
-#: projectaction.py:553
134
+#: projectaction.py:572
135
 msgid "Saving project file"
136
 msgstr ""
137
 
138
-#: projectaction.py:708
139
+#: projectaction.py:727
140
 msgid "Project not found on disk"
141
 msgstr ""
142
 
143
-#: projectaction.py:709
144
+#: projectaction.py:728
145
 msgid "Project can't be loaded."
146
 msgstr ""
147
 
148
-#: projectaction.py:717
149
+#: projectaction.py:736
150
 msgid "Project has not been saved since it was opened."
151
 msgstr ""
152
 
153
-#: projectaction.py:722
154
+#: projectaction.py:741
155
 msgid "Project was saved less than a minute ago."
156
 msgstr ""
157
 
158
-#: projectaction.py:725
159
+#: projectaction.py:744
160
 msgid "Project was saved one minute ago."
161
 msgstr ""
162
 
163
-#: projectaction.py:727
164
+#: projectaction.py:746
165
 msgid "Project was saved "
166
 msgstr ""
167
 
168
-#: projectaction.py:727
169
+#: projectaction.py:746
170
 msgid " minutes ago."
171
 msgstr ""
172
 
173
-#: projectaction.py:781
174
+#: projectaction.py:753
175
+msgid "Render target file exists!"
176
+msgstr ""
177
+
178
+#: projectaction.py:754
179
+msgid "Confirm overwriting existing file."
180
+msgstr ""
181
+
182
+#: projectaction.py:760
183
+msgid "Project is currently using proxy media!"
184
+msgstr ""
185
+
186
+#: projectaction.py:761
187
+msgid ""
188
+"Rendering from proxy media will produce worse quality than rendering from "
189
+"original media.\n"
190
+"Convert to using original media in Proxy Manager for best quality.\n"
191
+"\n"
192
+"Select 'Confirm' to render from proxy media anyway."
193
+msgstr ""
194
+
195
+#: projectaction.py:838
196
 msgid "Render launch failed!"
197
 msgstr ""
198
 
199
-#: projectaction.py:782 projectaction.py:796 tools/batchrendering.py:299
200
+#: projectaction.py:839 projectaction.py:853 tools/batchrendering.py:299
201
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/locale/create_pot -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/locale/create_pot Changed
7
 
1
@@ -7,4 +7,4 @@
2
 ROOT_DIR=$(pwd)
3
 
4
 # Creates .pot file that can be turned to .po file for each language
5
-xgettext -o locale/Flowblade/flowblade.pot app.py projectaction.py editorwindow.py clipeffectseditor.py compositeeditor.py dialogs.py editevent.py editorpersistance.py guicomponents.py movemodes.py panels.py persistance.py projectdata.py render.py syncsplitevent.py translations.py mlttransitions.py propertyeditorbuilder.py keyframeeditor.py middlebar.py medialog.py projectinfogui.py tools/titler.py rendergui.py profilesmanager.py preferenceswindow.py tools/batchrendering.py proxyediting.py tlineaction.py extraeditors.py trackaction.py medialinker.py patternproducer.py tools/gmic.py tools/gmic.py tools/toolsencoding.py monitorevent.py
6
+xgettext -o locale/Flowblade/flowblade.pot app.py projectaction.py editorwindow.py clipeffectseditor.py compositeeditor.py dialogs.py editevent.py editorpersistance.py guicomponents.py movemodes.py panels.py persistance.py projectdata.py render.py syncsplitevent.py translations.py mlttransitions.py propertyeditorbuilder.py keyframeeditor.py middlebar.py medialog.py projectinfogui.py tools/titler.py rendergui.py profilesmanager.py preferenceswindow.py tools/batchrendering.py proxyediting.py tlineaction.py extraeditors.py trackaction.py medialinker.py patternproducer.py tools/gmic.py tools/gmic.py tools/toolsencoding.py monitorevent.py compositorfades.py audiosync.py diskcachemanagement.py toolsintegration.py projectmediaimport.py shortcuts.py
7
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/locale/cs/LC_MESSAGES/flowblade.mo -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/locale/cs/LC_MESSAGES/flowblade.mo Changed
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/locale/cs/LC_MESSAGES/flowblade.po -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/locale/cs/LC_MESSAGES/flowblade.po Changed
201
 
1
@@ -6,8 +6,8 @@
2
 msgstr ""
3
 "Project-Id-Version: \n"
4
 "Report-Msgid-Bugs-To: \n"
5
-"POT-Creation-Date: 2017-03-20 09:48+0200\n"
6
-"PO-Revision-Date: 2017-03-19 20:35+0100\n"
7
+"POT-Creation-Date: 2017-10-04 15:30+0300\n"
8
+"PO-Revision-Date: 2017-09-09 21:07+0200\n"
9
 "Last-Translator: Pavel Fric <pavelfric@seznam.cz>\n"
10
 "Language-Team: Czech <translation-team-cs@lists.sourceforge.net>\n"
11
 "Language: cs\n"
12
@@ -15,73 +15,73 @@
13
 "Content-Type: text/plain; charset=UTF-8\n"
14
 "Content-Transfer-Encoding: 8bit\n"
15
 "Plural-Forms: nplurals=3; plural=((n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2);\n"
16
-"X-Generator: Lokalize 2.0\n"
17
+"X-Generator: Lokalize 1.5\n"
18
 "X-Language: cs_CZ\n"
19
 "X-Source-Language: C\n"
20
 
21
-#: app.py:761
22
+#: app.py:780
23
 msgid "Too small screen for this application."
24
 msgstr "Příliš malá obrazovka pro tento program."
25
 
26
-#: app.py:764
27
+#: app.py:783
28
 msgid "Minimum screen dimensions for this application are 1152 x 768.\n"
29
 msgstr "Nejmenší rozměry obrazovky pro tento program jsou 1152 x 768.\n"
30
 
31
-#: app.py:765
32
+#: app.py:784
33
 msgid "Your screen dimensions are "
34
 msgstr "Rozměry vaší obrazovky jsou "
35
 
36
-#: app.py:798 projectaction.py:365 projectaction.py:695
37
+#: app.py:817 projectaction.py:380 projectaction.py:714
38
 msgid "Project has not been saved previously"
39
 msgstr "Projekt předtím byl uložen"
40
 
41
-#: app.py:799 projectaction.py:366 projectaction.py:696
42
+#: app.py:818 projectaction.py:381 projectaction.py:715
43
 msgid "Save project with File -> Save As before closing."
44
-msgstr "Uložte projekt před zavření pomocí Soubor -> Uložit."
45
+msgstr "Uložte projekt před zavření pomocí Soubor → Uložit."
46
 
47
-#: projectaction.py:111
48
+#: projectaction.py:121
49
 msgid "Media asset was missing!"
50
 msgstr "Položka záznamů chybí!"
51
 
52
-#: projectaction.py:112
53
+#: projectaction.py:122
54
 msgid "Path of missing asset:"
55
 msgstr "Cesta k chybějící položce:"
56
 
57
-#: projectaction.py:113
58
+#: projectaction.py:123
59
 msgid ""
60
 "Relative search for replacement file in sub folders of project file failed."
61
 msgstr ""
62
 "Relativní hledání pro nahrazovací soubor v podsložkách souboru s projektem "
63
 "se nezdařilo."
64
 
65
-#: projectaction.py:114
66
+#: projectaction.py:124
67
 msgid "To load the project you will need to either:"
68
 msgstr "Pro nahrání projektu budete potřebovat:"
69
 
70
-#: projectaction.py:115
71
+#: projectaction.py:125
72
 msgid ""
73
 "Open project in 'Media Relinker' tool to relink media assets to new files, or"
74
 msgstr ""
75
 "Otevřít projekt v nástroji Znovuspojovač záznamů pro opětovné spojení "
76
 "položek záznamů s novými soubory, nebo"
77
 
78
-#: projectaction.py:116
79
+#: projectaction.py:126
80
 msgid "Place a file with the same exact name and path on the hard drive"
81
 msgstr "Umístěte falešný soubor s přesně stejným názvem a cestou na pevný disk"
82
 
83
-#: projectaction.py:117
84
+#: projectaction.py:127
85
 msgid "Open project in Media Relinker tool"
86
 msgstr "Otevřít projekt v nástroji Znovuspojovač záznamů"
87
 
88
-#: projectaction.py:136
89
+#: projectaction.py:146
90
 msgid "Profile with Description: '"
91
 msgstr "Profil s popisem: "
92
 
93
-#: projectaction.py:136
94
+#: projectaction.py:146
95
 msgid "' was not found on load!"
96
 msgstr " nebyl při nahrávání nalezen!"
97
 
98
-#: projectaction.py:137
99
+#: projectaction.py:147
100
 msgid ""
101
 "It is possible to load the project by creating a User Profile with exactly "
102
 "the same Description\n"
103
@@ -91,19 +91,19 @@
104
 "popisem\n"
105
 "jako má chybějící profil. "
106
 
107
-#: projectaction.py:138
108
+#: projectaction.py:148
109
 msgid "User Profiles can be created by selecting 'Edit->Profiles Manager'."
110
-msgstr "Uživatelské profily lze vytvářet vybráním Úpravy -> Správce profilů."
111
+msgstr "Uživatelské profily lze vytvářet vybráním Úpravy → Správce profilů."
112
 
113
-#: projectaction.py:145
114
+#: projectaction.py:155
115
 msgid "Opening"
116
 msgstr "Otevírá se"
117
 
118
-#: projectaction.py:275
119
+#: projectaction.py:288
120
 msgid "Media files already present in project were opened!"
121
 msgstr "Soubory již přítomné v projektu byly otevřeny!"
122
 
123
-#: projectaction.py:281
124
+#: projectaction.py:294
125
 msgid ""
126
 "Files already present:\n"
127
 "\n"
128
@@ -111,476 +111,566 @@
129
 "Soubory již přítomné:\n"
130
 "\n"
131
 
132
-#: projectaction.py:480
133
+#: projectaction.py:495
134
 msgid "Selected folder contains files"
135
 msgstr "Vybraná složka obsahuje soubory"
136
 
137
-#: projectaction.py:481
138
+#: projectaction.py:496
139
 msgid ""
140
 "When saving a back-up snapshot of the project, the selected folder\n"
141
 "has to be empty."
142
 msgstr ""
143
 "Při ukládání záložního snímku projektu musí být vybraná složka prázdná."
144
 
145
-#: projectaction.py:552
146
+#: projectaction.py:571
147
 msgid "Copying project media assets"
148
 msgstr "Kopírují se položky záznamů projektu"
149
 
150
-#: projectaction.py:553
151
+#: projectaction.py:572
152
 msgid "Saving project file"
153
 msgstr "Ukládá se soubor s projektem"
154
 
155
-#: projectaction.py:708
156
+#: projectaction.py:727
157
 msgid "Project not found on disk"
158
 msgstr "Projekt nebyl na disku nalezen"
159
 
160
-#: projectaction.py:709
161
+#: projectaction.py:728
162
 msgid "Project can't be loaded."
163
 msgstr "Projekt nelze nahrát."
164
 
165
-#: projectaction.py:717
166
+#: projectaction.py:736
167
 msgid "Project has not been saved since it was opened."
168
 msgstr "Projekt nebyl od té doby, co byl otevřen, uložen."
169
 
170
-#: projectaction.py:722
171
+#: projectaction.py:741
172
 msgid "Project was saved less than a minute ago."
173
 msgstr "Projekt byl uložen před méně než minutou."
174
 
175
-#: projectaction.py:725
176
+#: projectaction.py:744
177
 msgid "Project was saved one minute ago."
178
 msgstr "Projekt byl uložen před jednou minutou."
179
 
180
-#: projectaction.py:727
181
+#: projectaction.py:746
182
 msgid "Project was saved "
183
 msgstr "Projekt byl uložen před "
184
 
185
-#: projectaction.py:727
186
+#: projectaction.py:746
187
 msgid " minutes ago."
188
 msgstr " minutami"
189
 
190
-#: projectaction.py:781
191
+#: projectaction.py:753
192
+msgid "Render target file exists!"
193
+msgstr "Cílový soubor se zpracováním existuje!!"
194
+
195
+#: projectaction.py:754
196
+msgid "Confirm overwriting existing file."
197
+msgstr "Potvrdit přepsání stávajícího souboru."
198
+
199
+#: projectaction.py:760
200
+msgid "Project is currently using proxy media!"
201
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/locale/de/LC_MESSAGES/flowblade.mo -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/locale/de/LC_MESSAGES/flowblade.mo Changed
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/locale/de/LC_MESSAGES/flowblade.po -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/locale/de/LC_MESSAGES/flowblade.po Changed
201
 
1
@@ -9,7 +9,7 @@
2
 msgstr ""
3
 "Project-Id-Version: PACKAGE VERSION\n"
4
 "Report-Msgid-Bugs-To: \n"
5
-"POT-Creation-Date: 2017-03-17 17:18+0200\n"
6
+"POT-Creation-Date: 2017-10-04 15:30+0300\n"
7
 "PO-Revision-Date: 2014-11-23 14:22+0100\n"
8
 "Last-Translator: Mario Dejanovic <mario.dejanovic@gmx.at>\n"
9
 "Language-Team: German\n"
10
@@ -19,68 +19,68 @@
11
 "Content-Transfer-Encoding: 8bit\n"
12
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
 
14
-#: app.py:761
15
+#: app.py:780
16
 msgid "Too small screen for this application."
17
 msgstr "Zu kleiner Bildschirm für diese Applikation."
18
 
19
-#: app.py:764
20
+#: app.py:783
21
 msgid "Minimum screen dimensions for this application are 1152 x 768.\n"
22
 msgstr "Minimale Auflösung für diese Applikation ist 1152 x 768.\n"
23
 
24
-#: app.py:765
25
+#: app.py:784
26
 msgid "Your screen dimensions are "
27
 msgstr "Ihre Auflösung beträgt "
28
 
29
-#: app.py:798 projectaction.py:365 projectaction.py:695
30
+#: app.py:817 projectaction.py:380 projectaction.py:714
31
 msgid "Project has not been saved previously"
32
 msgstr "Projekt wurde noch nicht gesichert"
33
 
34
-#: app.py:799 projectaction.py:366 projectaction.py:696
35
+#: app.py:818 projectaction.py:381 projectaction.py:715
36
 msgid "Save project with File -> Save As before closing."
37
 msgstr "Projekt vor dem Schließen sichern mit 'Datei -> Sichern als...'."
38
 
39
-#: projectaction.py:111
40
+#: projectaction.py:121
41
 msgid "Media asset was missing!"
42
 msgstr "Mediendatei fehlt!"
43
 
44
-#: projectaction.py:112
45
+#: projectaction.py:122
46
 msgid "Path of missing asset:"
47
 msgstr "Pfad der fehlenden Datei:"
48
 
49
-#: projectaction.py:113
50
+#: projectaction.py:123
51
 msgid ""
52
 "Relative search for replacement file in sub folders of project file failed."
53
 msgstr ""
54
 "Relative Suche nach einem Ersatz in Unterverzeichnissen ist fehlgeschlagen."
55
 
56
-#: projectaction.py:114
57
+#: projectaction.py:124
58
 msgid "To load the project you will need to either:"
59
 msgstr "Um das Projekt zu laden ist einer der folgenden Schritte erforderlich:"
60
 
61
-#: projectaction.py:115
62
+#: projectaction.py:125
63
 msgid ""
64
 "Open project in 'Media Relinker' tool to relink media assets to new files, or"
65
 msgstr ""
66
 "'Medien-Link'-Werkzeug nutzen, um Medien mit anderen Dateien zu verknüpfen, "
67
 "oder"
68
 
69
-#: projectaction.py:116
70
+#: projectaction.py:126
71
 msgid "Place a file with the same exact name and path on the hard drive"
72
 msgstr "eine Ersatzdatei mit gleichem Namen und ähnlichem Inhalt anlegen"
73
 
74
-#: projectaction.py:117
75
+#: projectaction.py:127
76
 msgid "Open project in Media Relinker tool"
77
 msgstr "Öffne das Projekt im Medien-Link Werkzeug"
78
 
79
-#: projectaction.py:136
80
+#: projectaction.py:146
81
 msgid "Profile with Description: '"
82
 msgstr "Profil mit Beschreibung: '"
83
 
84
-#: projectaction.py:136
85
+#: projectaction.py:146
86
 msgid "' was not found on load!"
87
 msgstr "' wurde beim Laden nicht gefunden!"
88
 
89
-#: projectaction.py:137
90
+#: projectaction.py:147
91
 msgid ""
92
 "It is possible to load the project by creating a User Profile with exactly "
93
 "the same Description\n"
94
@@ -90,20 +90,20 @@
95
 "Parametern\n"
96
 "wie das fehlende Profil, angelegt wird. "
97
 
98
-#: projectaction.py:138
99
+#: projectaction.py:148
100
 msgid "User Profiles can be created by selecting 'Edit->Profiles Manager'."
101
 msgstr ""
102
 "Nutzerprofile können unter 'Bearbeiten->Profil-Manager' angelegt werden."
103
 
104
-#: projectaction.py:145
105
+#: projectaction.py:155
106
 msgid "Opening"
107
 msgstr "Öffnen"
108
 
109
-#: projectaction.py:275
110
+#: projectaction.py:288
111
 msgid "Media files already present in project were opened!"
112
 msgstr "Im Projekt bereits vorhandene Mediendateien wurden geöffnet!"
113
 
114
-#: projectaction.py:281
115
+#: projectaction.py:294
116
 msgid ""
117
 "Files already present:\n"
118
 "\n"
119
@@ -111,11 +111,11 @@
120
 "Bereits vorhandene Dateien:\n"
121
 "\n"
122
 
123
-#: projectaction.py:480
124
+#: projectaction.py:495
125
 msgid "Selected folder contains files"
126
 msgstr "Gewählter Ordner enthält Dateien"
127
 
128
-#: projectaction.py:481
129
+#: projectaction.py:496
130
 msgid ""
131
 "When saving a back-up snapshot of the project, the selected folder\n"
132
 "has to be empty."
133
@@ -123,71 +123,105 @@
134
 "Für das Sichern einer Sicherungskopie muss der gewählte Ordner\n"
135
 "leer sein."
136
 
137
-#: projectaction.py:552
138
+#: projectaction.py:571
139
 msgid "Copying project media assets"
140
 msgstr "Kopiere Projektmediendaten"
141
 
142
-#: projectaction.py:553
143
+#: projectaction.py:572
144
 msgid "Saving project file"
145
 msgstr "Sichere Projektdatei"
146
 
147
-#: projectaction.py:708
148
+#: projectaction.py:727
149
 msgid "Project not found on disk"
150
 msgstr "Projekt nicht gefunden"
151
 
152
-#: projectaction.py:709
153
+#: projectaction.py:728
154
 msgid "Project can't be loaded."
155
 msgstr "Projekt kann nicht geladen werden."
156
 
157
-#: projectaction.py:717
158
+#: projectaction.py:736
159
 msgid "Project has not been saved since it was opened."
160
 msgstr "Projekt wurde seit dem Öffnen nicht gesichert."
161
 
162
-#: projectaction.py:722
163
+#: projectaction.py:741
164
 msgid "Project was saved less than a minute ago."
165
 msgstr "Projekt wurde vor weniger als einer Minute gesichert."
166
 
167
-#: projectaction.py:725
168
+#: projectaction.py:744
169
 msgid "Project was saved one minute ago."
170
 msgstr "Projekt wurde vor einer Minute gesichert."
171
 
172
-#: projectaction.py:727
173
+#: projectaction.py:746
174
 msgid "Project was saved "
175
 msgstr "Projekt wurde vor "
176
 
177
-#: projectaction.py:727
178
+#: projectaction.py:746
179
 msgid " minutes ago."
180
 msgstr " Minuten gesichert."
181
 
182
-#: projectaction.py:781
183
+#: projectaction.py:753
184
+#, fuzzy
185
+msgid "Render target file exists!"
186
+msgstr "Renderbereich nicht definiert!"
187
+
188
+#: projectaction.py:754
189
+#, fuzzy
190
+msgid "Confirm overwriting existing file."
191
+msgstr "Wollen Sie die existierende Datei überschreiben?"
192
+
193
+#: projectaction.py:760
194
+msgid "Project is currently using proxy media!"
195
+msgstr ""
196
+
197
+#: projectaction.py:761
198
+msgid ""
199
+"Rendering from proxy media will produce worse quality than rendering from "
200
+"original media.\n"
201
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/locale/es/LC_MESSAGES/flowblade.mo -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/locale/es/LC_MESSAGES/flowblade.mo Changed
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/locale/es/LC_MESSAGES/flowblade.po -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/locale/es/LC_MESSAGES/flowblade.po Changed
201
 
1
@@ -7,7 +7,7 @@
2
 msgstr ""
3
 "Project-Id-Version: PACKAGE VERSION\n"
4
 "Report-Msgid-Bugs-To: \n"
5
-"POT-Creation-Date: 2017-03-17 17:18+0200\n"
6
+"POT-Creation-Date: 2017-10-04 15:30+0300\n"
7
 "PO-Revision-Date: 2014-02-21 12:08+0200\n"
8
 "Last-Translator: David Gámiz Jiménez <david.gamiz@gmail.com>\n"
9
 "Language-Team: David Gamiz Jimenez\n"
10
@@ -18,175 +18,209 @@
11
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
12
 "X-Generator: Virtaal 0.7.0\n"
13
 
14
-#: app.py:761
15
+#: app.py:780
16
 msgid "Too small screen for this application."
17
 msgstr "La pantalla es demasiado pequeña para esta aplicación."
18
 
19
-#: app.py:764
20
+#: app.py:783
21
 msgid "Minimum screen dimensions for this application are 1152 x 768.\n"
22
 msgstr ""
23
 "La dimensión de pantalla mínima para esta aplicación es de 1152 x 768.\n"
24
 
25
-#: app.py:765
26
+#: app.py:784
27
 msgid "Your screen dimensions are "
28
 msgstr "Las dimensiones de su pantalla son "
29
 
30
-#: app.py:798 projectaction.py:365 projectaction.py:695
31
+#: app.py:817 projectaction.py:380 projectaction.py:714
32
 msgid "Project has not been saved previously"
33
 msgstr "El proyecto no se ha salvado antes"
34
 
35
-#: app.py:799 projectaction.py:366 projectaction.py:696
36
+#: app.py:818 projectaction.py:381 projectaction.py:715
37
 msgid "Save project with File -> Save As before closing."
38
 msgstr "Salvar el proyecto en un Archivo -> Salvar como antes de cerrar."
39
 
40
-#: projectaction.py:111
41
+#: projectaction.py:121
42
 msgid "Media asset was missing!"
43
 msgstr ""
44
 
45
-#: projectaction.py:112
46
+#: projectaction.py:122
47
 msgid "Path of missing asset:"
48
 msgstr ""
49
 
50
-#: projectaction.py:113
51
+#: projectaction.py:123
52
 msgid ""
53
 "Relative search for replacement file in sub folders of project file failed."
54
 msgstr ""
55
 
56
-#: projectaction.py:114
57
+#: projectaction.py:124
58
 msgid "To load the project you will need to either:"
59
 msgstr ""
60
 
61
-#: projectaction.py:115
62
+#: projectaction.py:125
63
 msgid ""
64
 "Open project in 'Media Relinker' tool to relink media assets to new files, or"
65
 msgstr ""
66
 
67
-#: projectaction.py:116
68
+#: projectaction.py:126
69
 #, fuzzy
70
 msgid "Place a file with the same exact name and path on the hard drive"
71
 msgstr ""
72
 "Coloque un archivo vacío con el mismo nombre y contenido similar para activar"
73
 
74
-#: projectaction.py:117
75
+#: projectaction.py:127
76
 msgid "Open project in Media Relinker tool"
77
 msgstr ""
78
 
79
-#: projectaction.py:136
80
+#: projectaction.py:146
81
 #, fuzzy
82
 msgid "Profile with Description: '"
83
 msgstr "Descripción:"
84
 
85
-#: projectaction.py:136
86
+#: projectaction.py:146
87
 #, fuzzy
88
 msgid "' was not found on load!"
89
 msgstr " ¡no se ha encontrado en la carga!"
90
 
91
-#: projectaction.py:137
92
+#: projectaction.py:147
93
 msgid ""
94
 "It is possible to load the project by creating a User Profile with exactly "
95
 "the same Description\n"
96
 "as the missing profile. "
97
 msgstr ""
98
 
99
-#: projectaction.py:138
100
+#: projectaction.py:148
101
 msgid "User Profiles can be created by selecting 'Edit->Profiles Manager'."
102
 msgstr ""
103
 
104
-#: projectaction.py:145
105
+#: projectaction.py:155
106
 msgid "Opening"
107
 msgstr "Abriendo"
108
 
109
-#: projectaction.py:275
110
+#: projectaction.py:288
111
 msgid "Media files already present in project were opened!"
112
 msgstr ""
113
 
114
-#: projectaction.py:281
115
+#: projectaction.py:294
116
 #, fuzzy
117
 msgid ""
118
 "Files already present:\n"
119
 "\n"
120
 msgstr " ya existe!"
121
 
122
-#: projectaction.py:480
123
+#: projectaction.py:495
124
 #, fuzzy
125
 msgid "Selected folder contains files"
126
 msgstr "Seleccionar carpeta para nuevos miniaturas."
127
 
128
-#: projectaction.py:481
129
+#: projectaction.py:496
130
 msgid ""
131
 "When saving a back-up snapshot of the project, the selected folder\n"
132
 "has to be empty."
133
 msgstr ""
134
 
135
-#: projectaction.py:552
136
+#: projectaction.py:571
137
 msgid "Copying project media assets"
138
 msgstr ""
139
 
140
-#: projectaction.py:553
141
+#: projectaction.py:572
142
 #, fuzzy
143
 msgid "Saving project file"
144
 msgstr "¿Guardar proyecto '"
145
 
146
-#: projectaction.py:708
147
+#: projectaction.py:727
148
 msgid "Project not found on disk"
149
 msgstr "El proyecto no se encuentra en el disco"
150
 
151
-#: projectaction.py:709
152
+#: projectaction.py:728
153
 msgid "Project can't be loaded."
154
 msgstr "El proyecto no puede ser cargado."
155
 
156
-#: projectaction.py:717
157
+#: projectaction.py:736
158
 msgid "Project has not been saved since it was opened."
159
 msgstr "El proyecto no ha sido salvado desde que se abrió."
160
 
161
-#: projectaction.py:722
162
+#: projectaction.py:741
163
 msgid "Project was saved less than a minute ago."
164
 msgstr "El proyecto fue salvado hace menos de un minuto."
165
 
166
-#: projectaction.py:725
167
+#: projectaction.py:744
168
 msgid "Project was saved one minute ago."
169
 msgstr "El proyecto fue salvado hace un minuto."
170
 
171
-#: projectaction.py:727
172
+#: projectaction.py:746
173
 msgid "Project was saved "
174
 msgstr "El proyecto salvado "
175
 
176
-#: projectaction.py:727
177
+#: projectaction.py:746
178
 msgid " minutes ago."
179
 msgstr " hace minutos."
180
 
181
-#: projectaction.py:781
182
+#: projectaction.py:753
183
+#, fuzzy
184
+msgid "Render target file exists!"
185
+msgstr "Render rango no definido!"
186
+
187
+#: projectaction.py:754
188
+#, fuzzy
189
+msgid "Confirm overwriting existing file."
190
+msgstr "¿Usted desea sobrescribir el archivo existente?"
191
+
192
+#: projectaction.py:760
193
+msgid "Project is currently using proxy media!"
194
+msgstr ""
195
+
196
+#: projectaction.py:761
197
+msgid ""
198
+"Rendering from proxy media will produce worse quality than rendering from "
199
+"original media.\n"
200
+"Convert to using original media in Proxy Manager for best quality.\n"
201
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/locale/fi/LC_MESSAGES/flowblade.mo -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/locale/fi/LC_MESSAGES/flowblade.mo Changed
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/locale/fi/LC_MESSAGES/flowblade.po -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/locale/fi/LC_MESSAGES/flowblade.po Changed
201
 
1
@@ -7,7 +7,7 @@
2
 msgstr ""
3
 "Project-Id-Version: PACKAGE VERSION\n"
4
 "Report-Msgid-Bugs-To: \n"
5
-"POT-Creation-Date: 2017-03-17 17:18+0200\n"
6
+"POT-Creation-Date: 2017-10-04 15:30+0300\n"
7
 "PO-Revision-Date: 2011-12-13 23:55+0200\n"
8
 "Last-Translator: Janne Liljeblad <janne@janne-kx557aa-uuw-a6521-sc>\n"
9
 "Language-Team: Finnish\n"
10
@@ -17,67 +17,67 @@
11
 "Content-Transfer-Encoding: 8bit\n"
12
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
 
14
-#: app.py:761
15
+#: app.py:780
16
 msgid "Too small screen for this application."
17
 msgstr "Näyttö on liian pieni tälle ohjelmalle."
18
 
19
-#: app.py:764
20
+#: app.py:783
21
 msgid "Minimum screen dimensions for this application are 1152 x 768.\n"
22
 msgstr "Minimi näyttökoko tällle ohjelmalle on 1152 x 768.\n"
23
 
24
-#: app.py:765
25
+#: app.py:784
26
 msgid "Your screen dimensions are "
27
 msgstr "Sinun näyttösi koko on "
28
 
29
-#: app.py:798 projectaction.py:365 projectaction.py:695
30
+#: app.py:817 projectaction.py:380 projectaction.py:714
31
 msgid "Project has not been saved previously"
32
 msgstr "Projektia ei ole tallennettu aikaisemmin"
33
 
34
-#: app.py:799 projectaction.py:366 projectaction.py:696
35
+#: app.py:818 projectaction.py:381 projectaction.py:715
36
 msgid "Save project with File -> Save As before closing."
37
 msgstr ""
38
 "Tallenna projekti valinnalla Tiedosto -> Tallenna nimellä ennen sulkemista."
39
 
40
-#: projectaction.py:111
41
+#: projectaction.py:121
42
 msgid "Media asset was missing!"
43
 msgstr "Mediaa ei löytynyt!"
44
 
45
-#: projectaction.py:112
46
+#: projectaction.py:122
47
 msgid "Path of missing asset:"
48
 msgstr ""
49
 
50
-#: projectaction.py:113
51
+#: projectaction.py:123
52
 msgid ""
53
 "Relative search for replacement file in sub folders of project file failed."
54
 msgstr ""
55
 
56
-#: projectaction.py:114
57
+#: projectaction.py:124
58
 msgid "To load the project you will need to either:"
59
 msgstr ""
60
 
61
-#: projectaction.py:115
62
+#: projectaction.py:125
63
 msgid ""
64
 "Open project in 'Media Relinker' tool to relink media assets to new files, or"
65
 msgstr ""
66
 
67
-#: projectaction.py:116
68
+#: projectaction.py:126
69
 msgid "Place a file with the same exact name and path on the hard drive"
70
 msgstr ""
71
 "Aseta samaan paikkaan samanniminen ja tyyppinen tiedosto mahdollistaaksesi"
72
 
73
-#: projectaction.py:117
74
+#: projectaction.py:127
75
 msgid "Open project in Media Relinker tool"
76
 msgstr ""
77
 
78
-#: projectaction.py:136
79
+#: projectaction.py:146
80
 msgid "Profile with Description: '"
81
 msgstr "Priilia, jolla on kuvaus:"
82
 
83
-#: projectaction.py:136
84
+#: projectaction.py:146
85
 msgid "' was not found on load!"
86
 msgstr " ei löytynyt ladattaessa!"
87
 
88
-#: projectaction.py:137
89
+#: projectaction.py:147
90
 msgid ""
91
 "It is possible to load the project by creating a User Profile with exactly "
92
 "the same Description\n"
93
@@ -87,19 +87,19 @@
94
 "nimi kuin\n"
95
 "puuttuvalla profiililla."
96
 
97
-#: projectaction.py:138
98
+#: projectaction.py:148
99
 msgid "User Profiles can be created by selecting 'Edit->Profiles Manager'."
100
 msgstr ""
101
 
102
-#: projectaction.py:145
103
+#: projectaction.py:155
104
 msgid "Opening"
105
 msgstr "Avaa"
106
 
107
-#: projectaction.py:275
108
+#: projectaction.py:288
109
 msgid "Media files already present in project were opened!"
110
 msgstr "Avattiin media tiedostoja, jotka jo ovat projektissa"
111
 
112
-#: projectaction.py:281
113
+#: projectaction.py:294
114
 msgid ""
115
 "Files already present:\n"
116
 "\n"
117
@@ -107,11 +107,11 @@
118
 "Projektissa jo olevat tiedostot:\n"
119
 "\n"
120
 
121
-#: projectaction.py:480
122
+#: projectaction.py:495
123
 msgid "Selected folder contains files"
124
 msgstr "Valitussa kansiossa on tiedostoja"
125
 
126
-#: projectaction.py:481
127
+#: projectaction.py:496
128
 msgid ""
129
 "When saving a back-up snapshot of the project, the selected folder\n"
130
 "has to be empty."
131
@@ -119,71 +119,105 @@
132
 "Kun tallennetaan projektia ja mediaa yhtä aikaa\n"
133
 "täytyy kansion olla tyhjä."
134
 
135
-#: projectaction.py:552
136
+#: projectaction.py:571
137
 msgid "Copying project media assets"
138
 msgstr "Kopioidaan mediaa"
139
 
140
-#: projectaction.py:553
141
+#: projectaction.py:572
142
 msgid "Saving project file"
143
 msgstr "Tallennetaan projektia"
144
 
145
-#: projectaction.py:708
146
+#: projectaction.py:727
147
 msgid "Project not found on disk"
148
 msgstr "Projektia ei löytynyt kovalevyltä"
149
 
150
-#: projectaction.py:709
151
+#: projectaction.py:728
152
 msgid "Project can't be loaded."
153
 msgstr "Projektia ei voida ladata."
154
 
155
-#: projectaction.py:717
156
+#: projectaction.py:736
157
 msgid "Project has not been saved since it was opened."
158
 msgstr "Projektia ei ole tallennettu aikaisemmin."
159
 
160
-#: projectaction.py:722
161
+#: projectaction.py:741
162
 msgid "Project was saved less than a minute ago."
163
 msgstr "Projekti tallennettiin viimeksi alle minuutti sitten."
164
 
165
-#: projectaction.py:725
166
+#: projectaction.py:744
167
 msgid "Project was saved one minute ago."
168
 msgstr "Projekti tallennettiin viimeksi minuutti sitten."
169
 
170
-#: projectaction.py:727
171
+#: projectaction.py:746
172
 msgid "Project was saved "
173
 msgstr "Projektia ei ole tallennettu aikaisemmin"
174
 
175
-#: projectaction.py:727
176
+#: projectaction.py:746
177
 msgid " minutes ago."
178
 msgstr " minuuttia sitten."
179
 
180
-#: projectaction.py:781
181
+#: projectaction.py:753
182
+#, fuzzy
183
+msgid "Render target file exists!"
184
+msgstr "Renderöinti alue ei ole määritelty"
185
+
186
+#: projectaction.py:754
187
+#, fuzzy
188
+msgid "Confirm overwriting existing file."
189
+msgstr "Haluatko kirjoittaa olemassa olevan tiedoston päälle?"
190
+
191
+#: projectaction.py:760
192
+msgid "Project is currently using proxy media!"
193
+msgstr ""
194
+
195
+#: projectaction.py:761
196
+msgid ""
197
+"Rendering from proxy media will produce worse quality than rendering from "
198
+"original media.\n"
199
+"Convert to using original media in Proxy Manager for best quality.\n"
200
+"\n"
201
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/locale/fr/LC_MESSAGES/flowblade.mo -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/locale/fr/LC_MESSAGES/flowblade.mo Changed
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/locale/fr/LC_MESSAGES/flowblade.po -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/locale/fr/LC_MESSAGES/flowblade.po Changed
201
 
1
@@ -7,7 +7,7 @@
2
 msgstr ""
3
 "Project-Id-Version: PACKAGE VERSION\n"
4
 "Report-Msgid-Bugs-To: \n"
5
-"POT-Creation-Date: 2017-03-17 17:18+0200\n"
6
+"POT-Creation-Date: 2017-10-04 15:30+0300\n"
7
 "PO-Revision-Date: 2013-09-20 18:54+0200\n"
8
 "Last-Translator: Loïc Vanderstichelen <lv@loicvanderstichelen.com>\n"
9
 "Language-Team: French\n"
10
@@ -17,174 +17,208 @@
11
 "Content-Transfer-Encoding: 8bit\n"
12
 "Plural-Forms: nplurals=2; plural=(n > 1);\n"
13
 
14
-#: app.py:761
15
+#: app.py:780
16
 msgid "Too small screen for this application."
17
 msgstr "Votre écran est trop petit pour cette application."
18
 
19
-#: app.py:764
20
+#: app.py:783
21
 msgid "Minimum screen dimensions for this application are 1152 x 768.\n"
22
 msgstr "La résolution minimum pour cet application est de 1152 x 768.\n"
23
 
24
-#: app.py:765
25
+#: app.py:784
26
 msgid "Your screen dimensions are "
27
 msgstr "Votre résolution actuelle est "
28
 
29
-#: app.py:798 projectaction.py:365 projectaction.py:695
30
+#: app.py:817 projectaction.py:380 projectaction.py:714
31
 msgid "Project has not been saved previously"
32
 msgstr "Le projet n'a jamais été sauvegardé"
33
 
34
-#: app.py:799 projectaction.py:366 projectaction.py:696
35
+#: app.py:818 projectaction.py:381 projectaction.py:715
36
 msgid "Save project with File -> Save As before closing."
37
 msgstr "Sauvegardez le projet avec Fichier -> Enregistrer sous."
38
 
39
-#: projectaction.py:111
40
+#: projectaction.py:121
41
 msgid "Media asset was missing!"
42
 msgstr ""
43
 
44
-#: projectaction.py:112
45
+#: projectaction.py:122
46
 msgid "Path of missing asset:"
47
 msgstr ""
48
 
49
-#: projectaction.py:113
50
+#: projectaction.py:123
51
 msgid ""
52
 "Relative search for replacement file in sub folders of project file failed."
53
 msgstr ""
54
 
55
-#: projectaction.py:114
56
+#: projectaction.py:124
57
 msgid "To load the project you will need to either:"
58
 msgstr ""
59
 
60
-#: projectaction.py:115
61
+#: projectaction.py:125
62
 msgid ""
63
 "Open project in 'Media Relinker' tool to relink media assets to new files, or"
64
 msgstr ""
65
 
66
-#: projectaction.py:116
67
+#: projectaction.py:126
68
 #, fuzzy
69
 msgid "Place a file with the same exact name and path on the hard drive"
70
 msgstr "Créez un fichier de même nom au contenu similaire pour pouvoir"
71
 
72
-#: projectaction.py:117
73
+#: projectaction.py:127
74
 msgid "Open project in Media Relinker tool"
75
 msgstr ""
76
 
77
-#: projectaction.py:136
78
+#: projectaction.py:146
79
 #, fuzzy
80
 msgid "Profile with Description: '"
81
 msgstr "Description:"
82
 
83
-#: projectaction.py:136
84
+#: projectaction.py:146
85
 #, fuzzy
86
 msgid "' was not found on load!"
87
 msgstr " n'a pas été trouvé!"
88
 
89
-#: projectaction.py:137
90
+#: projectaction.py:147
91
 msgid ""
92
 "It is possible to load the project by creating a User Profile with exactly "
93
 "the same Description\n"
94
 "as the missing profile. "
95
 msgstr ""
96
 
97
-#: projectaction.py:138
98
+#: projectaction.py:148
99
 msgid "User Profiles can be created by selecting 'Edit->Profiles Manager'."
100
 msgstr ""
101
 
102
-#: projectaction.py:145
103
+#: projectaction.py:155
104
 msgid "Opening"
105
 msgstr "Ouverture"
106
 
107
-#: projectaction.py:275
108
+#: projectaction.py:288
109
 msgid "Media files already present in project were opened!"
110
 msgstr ""
111
 
112
-#: projectaction.py:281
113
+#: projectaction.py:294
114
 #, fuzzy
115
 msgid ""
116
 "Files already present:\n"
117
 "\n"
118
 msgstr " existe déjà!"
119
 
120
-#: projectaction.py:480
121
+#: projectaction.py:495
122
 #, fuzzy
123
 msgid "Selected folder contains files"
124
 msgstr "Sélectionner un dossier pour les nouvelles miniatures"
125
 
126
-#: projectaction.py:481
127
+#: projectaction.py:496
128
 msgid ""
129
 "When saving a back-up snapshot of the project, the selected folder\n"
130
 "has to be empty."
131
 msgstr ""
132
 
133
-#: projectaction.py:552
134
+#: projectaction.py:571
135
 msgid "Copying project media assets"
136
 msgstr ""
137
 
138
-#: projectaction.py:553
139
+#: projectaction.py:572
140
 #, fuzzy
141
 msgid "Saving project file"
142
 msgstr "Sauvegarder le projet '"
143
 
144
-#: projectaction.py:708
145
+#: projectaction.py:727
146
 msgid "Project not found on disk"
147
 msgstr "Le projet n'a pas été trouvé sur le disque"
148
 
149
-#: projectaction.py:709
150
+#: projectaction.py:728
151
 msgid "Project can't be loaded."
152
 msgstr "Le projet ne peut pas être chargé."
153
 
154
-#: projectaction.py:717
155
+#: projectaction.py:736
156
 msgid "Project has not been saved since it was opened."
157
 msgstr "Ce projet n'a pas été enregistré depuis qu'il a été ouvert."
158
 
159
-#: projectaction.py:722
160
+#: projectaction.py:741
161
 msgid "Project was saved less than a minute ago."
162
 msgstr "Le projet a été sauvegardé il y a moins d'une minute."
163
 
164
-#: projectaction.py:725
165
+#: projectaction.py:744
166
 msgid "Project was saved one minute ago."
167
 msgstr "Le projet a été sauvegardé il y a une minute."
168
 
169
-#: projectaction.py:727
170
+#: projectaction.py:746
171
 msgid "Project was saved "
172
 msgstr "Le projet a été sauvegardé il y a "
173
 
174
-#: projectaction.py:727
175
+#: projectaction.py:746
176
 msgid " minutes ago."
177
 msgstr " minutes."
178
 
179
-#: projectaction.py:781
180
+#: projectaction.py:753
181
+#, fuzzy
182
+msgid "Render target file exists!"
183
+msgstr "Zone de rendu non définie!"
184
+
185
+#: projectaction.py:754
186
+#, fuzzy
187
+msgid "Confirm overwriting existing file."
188
+msgstr "Voulez-vous écraser le fichier existant?"
189
+
190
+#: projectaction.py:760
191
+msgid "Project is currently using proxy media!"
192
+msgstr ""
193
+
194
+#: projectaction.py:761
195
+msgid ""
196
+"Rendering from proxy media will produce worse quality than rendering from "
197
+"original media.\n"
198
+"Convert to using original media in Proxy Manager for best quality.\n"
199
+"\n"
200
+"Select 'Confirm' to render from proxy media anyway."
201
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/locale/hu/LC_MESSAGES/flowblade.mo -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/locale/hu/LC_MESSAGES/flowblade.mo Changed
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/locale/hu/LC_MESSAGES/flowblade.po -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/locale/hu/LC_MESSAGES/flowblade.po Changed
201
 
1
@@ -7,8 +7,8 @@
2
 msgstr ""
3
 "Project-Id-Version: \n"
4
 "Report-Msgid-Bugs-To: \n"
5
-"POT-Creation-Date: 2017-03-17 17:18+0200\n"
6
-"PO-Revision-Date: 2017-03-10 15:54+0100\n"
7
+"POT-Creation-Date: 2017-10-04 15:30+0300\n"
8
+"PO-Revision-Date: 2017-03-24 08:40+0100\n"
9
 "Last-Translator: Péter Gábor <ptrg@freemail.hu>\n"
10
 "Language-Team: \n"
11
 "Language: hu-HU\n"
12
@@ -17,71 +17,71 @@
13
 "Content-Transfer-Encoding: 8bit\n"
14
 "X-Generator: Poedit 1.5.4\n"
15
 
16
-#: app.py:761
17
+#: app.py:780
18
 msgid "Too small screen for this application."
19
 msgstr "Túl kicsi a képernyő az alkalmazás számára."
20
 
21
-#: app.py:764
22
+#: app.py:783
23
 msgid "Minimum screen dimensions for this application are 1152 x 768.\n"
24
 msgstr "A minimális képernyőfelbontás ezen alkalmazás számára 1152 x 768.\n"
25
 
26
-#: app.py:765
27
+#: app.py:784
28
 msgid "Your screen dimensions are "
29
 msgstr "Az ön képernyőjének felbontása "
30
 
31
-#: app.py:798 projectaction.py:365 projectaction.py:695
32
+#: app.py:817 projectaction.py:380 projectaction.py:714
33
 msgid "Project has not been saved previously"
34
 msgstr "A projekt korábban még nem volt mentve"
35
 
36
-#: app.py:799 projectaction.py:366 projectaction.py:696
37
+#: app.py:818 projectaction.py:381 projectaction.py:715
38
 msgid "Save project with File -> Save As before closing."
39
 msgstr ""
40
 "Mentse a projektet a Fájl -> Mentés másként menüpont használatával mielőtt "
41
 "bezárná."
42
 
43
-#: projectaction.py:111
44
+#: projectaction.py:121
45
 msgid "Media asset was missing!"
46
 msgstr "Hiányzó média összetevő!"
47
 
48
-#: projectaction.py:112
49
+#: projectaction.py:122
50
 msgid "Path of missing asset:"
51
 msgstr "A hiányzó média összetevő útvonala:"
52
 
53
-#: projectaction.py:113
54
+#: projectaction.py:123
55
 msgid ""
56
 "Relative search for replacement file in sub folders of project file failed."
57
 msgstr ""
58
 "A keresés a relatív útvonalakon a projekt almappáiban nem járt sikerrel."
59
 
60
-#: projectaction.py:114
61
+#: projectaction.py:124
62
 msgid "To load the project you will need to either:"
63
 msgstr "A projekt betöltéséhez szükség van a következők valamelyikére:"
64
 
65
-#: projectaction.py:115
66
+#: projectaction.py:125
67
 msgid ""
68
 "Open project in 'Media Relinker' tool to relink media assets to new files, or"
69
 msgstr ""
70
 "Projekt megnyitása a 'Média újracsatoló' eszközben a média összetevők "
71
 "újracsatolásához, vagy"
72
 
73
-#: projectaction.py:116
74
+#: projectaction.py:126
75
 msgid "Place a file with the same exact name and path on the hard drive"
76
 msgstr ""
77
 "Helyezzen el egy fájlt teljesen megegyező névvel és útvonallal a meghajtón"
78
 
79
-#: projectaction.py:117
80
+#: projectaction.py:127
81
 msgid "Open project in Media Relinker tool"
82
 msgstr "Projekt megnyitása a 'Média újracsatoló' eszközben"
83
 
84
-#: projectaction.py:136
85
+#: projectaction.py:146
86
 msgid "Profile with Description: '"
87
 msgstr "A profil ezzel a leírással: '"
88
 
89
-#: projectaction.py:136
90
+#: projectaction.py:146
91
 msgid "' was not found on load!"
92
 msgstr "' nem volt a megtalálható betöltés során!"
93
 
94
-#: projectaction.py:137
95
+#: projectaction.py:147
96
 msgid ""
97
 "It is possible to load the project by creating a User Profile with exactly "
98
 "the same Description\n"
99
@@ -91,21 +91,21 @@
100
 "tartalmazó\n"
101
 "felhasználói profil létrehozása után."
102
 
103
-#: projectaction.py:138
104
+#: projectaction.py:148
105
 msgid "User Profiles can be created by selecting 'Edit->Profiles Manager'."
106
 msgstr ""
107
 "Felhasználói profilok létrehozhatók a 'Szerkesztés -> Profilkezelő' "
108
 "használatával."
109
 
110
-#: projectaction.py:145
111
+#: projectaction.py:155
112
 msgid "Opening"
113
 msgstr "Megnyitás"
114
 
115
-#: projectaction.py:275
116
+#: projectaction.py:288
117
 msgid "Media files already present in project were opened!"
118
 msgstr "A projektben már jelenlévő fájlok lettek megnyitva!"
119
 
120
-#: projectaction.py:281
121
+#: projectaction.py:294
122
 msgid ""
123
 "Files already present:\n"
124
 "\n"
125
@@ -113,11 +113,11 @@
126
 "Már jelenlévő fájlok:\n"
127
 "\n"
128
 
129
-#: projectaction.py:480
130
+#: projectaction.py:495
131
 msgid "Selected folder contains files"
132
 msgstr "A választott könyvtár fájlokat tartalmaz"
133
 
134
-#: projectaction.py:481
135
+#: projectaction.py:496
136
 msgid ""
137
 "When saving a back-up snapshot of the project, the selected folder\n"
138
 "has to be empty."
139
@@ -125,72 +125,105 @@
140
 "Egy projekt állapotának mentésekor a választott mappának\n"
141
 "üresnek kell lennie."
142
 
143
-#: projectaction.py:552
144
+#: projectaction.py:571
145
 msgid "Copying project media assets"
146
 msgstr "A projekt média összetevőinek másolása"
147
 
148
-#: projectaction.py:553
149
+#: projectaction.py:572
150
 msgid "Saving project file"
151
 msgstr "Projekt fájl mentése"
152
 
153
-#: projectaction.py:708
154
+#: projectaction.py:727
155
 msgid "Project not found on disk"
156
 msgstr "A projekt nem található a lemezen"
157
 
158
-#: projectaction.py:709
159
+#: projectaction.py:728
160
 msgid "Project can't be loaded."
161
 msgstr "A projekt nem tölthető be."
162
 
163
-#: projectaction.py:717
164
+#: projectaction.py:736
165
 msgid "Project has not been saved since it was opened."
166
 msgstr "A projekt még nem volt mentve a megnyitás óta."
167
 
168
-#: projectaction.py:722
169
+#: projectaction.py:741
170
 msgid "Project was saved less than a minute ago."
171
 msgstr "A projekt kevesebb mint egy perce volt mentve"
172
 
173
-#: projectaction.py:725
174
+#: projectaction.py:744
175
 msgid "Project was saved one minute ago."
176
 msgstr "A projekt egy perce volt mentve."
177
 
178
-#: projectaction.py:727
179
+#: projectaction.py:746
180
 msgid "Project was saved "
181
 msgstr "A projekt mentése "
182
 
183
-#: projectaction.py:727
184
+#: projectaction.py:746
185
 msgid " minutes ago."
186
 msgstr " perce történt."
187
 
188
-#: projectaction.py:781
189
+#: projectaction.py:753
190
+#, fuzzy
191
+msgid "Render target file exists!"
192
+msgstr "Renderelendő tartomány nincs meghatározva!"
193
+
194
+#: projectaction.py:754
195
+msgid "Confirm overwriting existing file."
196
+msgstr ""
197
+
198
+#: projectaction.py:760
199
+msgid "Project is currently using proxy media!"
200
+msgstr ""
201
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/locale/it/LC_MESSAGES/flowblade.mo -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/locale/it/LC_MESSAGES/flowblade.mo Changed
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/locale/it/LC_MESSAGES/flowblade.po -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/locale/it/LC_MESSAGES/flowblade.po Changed
201
 
1
@@ -7,7 +7,7 @@
2
 msgstr ""
3
 "Project-Id-Version: Floblade Italian Translation 0.14\n"
4
 "Report-Msgid-Bugs-To: \n"
5
-"POT-Creation-Date: 2017-03-17 17:18+0200\n"
6
+"POT-Creation-Date: 2017-10-04 15:30+0300\n"
7
 "PO-Revision-Date: 2014-09-15 23:42+0100\n"
8
 "Last-Translator: Massimo Stella <info@massimostella.it>\n"
9
 "Language-Team: Italiano\n"
10
@@ -18,87 +18,87 @@
11
 "Plural-Forms: nplurals=2; plural=(n > 1);\n"
12
 "X-Generator: Poedit 1.5.4\n"
13
 
14
-#: app.py:761
15
+#: app.py:780
16
 msgid "Too small screen for this application."
17
 msgstr "Lo schermo è troppo piccolo per questa applicazione."
18
 
19
-#: app.py:764
20
+#: app.py:783
21
 msgid "Minimum screen dimensions for this application are 1152 x 768.\n"
22
 msgstr "La risoluzione minima per questa applicazione è 1152 x 768.\n"
23
 
24
-#: app.py:765
25
+#: app.py:784
26
 msgid "Your screen dimensions are "
27
 msgstr "La risoluzione corrente è"
28
 
29
-#: app.py:798 projectaction.py:365 projectaction.py:695
30
+#: app.py:817 projectaction.py:380 projectaction.py:714
31
 msgid "Project has not been saved previously"
32
 msgstr "Il progetto non è mai stato salvato"
33
 
34
-#: app.py:799 projectaction.py:366 projectaction.py:696
35
+#: app.py:818 projectaction.py:381 projectaction.py:715
36
 msgid "Save project with File -> Save As before closing."
37
 msgstr "Salva il progetto da File -> Salva con nome"
38
 
39
-#: projectaction.py:111
40
+#: projectaction.py:121
41
 msgid "Media asset was missing!"
42
 msgstr ""
43
 
44
-#: projectaction.py:112
45
+#: projectaction.py:122
46
 msgid "Path of missing asset:"
47
 msgstr ""
48
 
49
-#: projectaction.py:113
50
+#: projectaction.py:123
51
 msgid ""
52
 "Relative search for replacement file in sub folders of project file failed."
53
 msgstr ""
54
 
55
-#: projectaction.py:114
56
+#: projectaction.py:124
57
 msgid "To load the project you will need to either:"
58
 msgstr ""
59
 
60
-#: projectaction.py:115
61
+#: projectaction.py:125
62
 msgid ""
63
 "Open project in 'Media Relinker' tool to relink media assets to new files, or"
64
 msgstr ""
65
 
66
-#: projectaction.py:116
67
+#: projectaction.py:126
68
 #, fuzzy
69
 msgid "Place a file with the same exact name and path on the hard drive"
70
 msgstr "Crea un file con lo stesso nome con contenuti simili per poter "
71
 
72
-#: projectaction.py:117
73
+#: projectaction.py:127
74
 msgid "Open project in Media Relinker tool"
75
 msgstr ""
76
 
77
-#: projectaction.py:136
78
+#: projectaction.py:146
79
 #, fuzzy
80
 msgid "Profile with Description: '"
81
 msgstr "Descrizione:"
82
 
83
-#: projectaction.py:136
84
+#: projectaction.py:146
85
 #, fuzzy
86
 msgid "' was not found on load!"
87
 msgstr "non è stato trovato!"
88
 
89
-#: projectaction.py:137
90
+#: projectaction.py:147
91
 msgid ""
92
 "It is possible to load the project by creating a User Profile with exactly "
93
 "the same Description\n"
94
 "as the missing profile. "
95
 msgstr ""
96
 
97
-#: projectaction.py:138
98
+#: projectaction.py:148
99
 msgid "User Profiles can be created by selecting 'Edit->Profiles Manager'."
100
 msgstr ""
101
 
102
-#: projectaction.py:145
103
+#: projectaction.py:155
104
 msgid "Opening"
105
 msgstr "Apertura"
106
 
107
-#: projectaction.py:275
108
+#: projectaction.py:288
109
 msgid "Media files already present in project were opened!"
110
 msgstr "File multimediali già presenti nel progetto sono stati aperti!"
111
 
112
-#: projectaction.py:281
113
+#: projectaction.py:294
114
 msgid ""
115
 "Files already present:\n"
116
 "\n"
117
@@ -106,84 +106,118 @@
118
 "File già esistenti:\n"
119
 "\n"
120
 
121
-#: projectaction.py:480
122
+#: projectaction.py:495
123
 #, fuzzy
124
 msgid "Selected folder contains files"
125
 msgstr "Seleziona cartella per le nuove miniature."
126
 
127
-#: projectaction.py:481
128
+#: projectaction.py:496
129
 msgid ""
130
 "When saving a back-up snapshot of the project, the selected folder\n"
131
 "has to be empty."
132
 msgstr ""
133
 
134
-#: projectaction.py:552
135
+#: projectaction.py:571
136
 msgid "Copying project media assets"
137
 msgstr ""
138
 
139
-#: projectaction.py:553
140
+#: projectaction.py:572
141
 #, fuzzy
142
 msgid "Saving project file"
143
 msgstr "Salvo il progetto '"
144
 
145
-#: projectaction.py:708
146
+#: projectaction.py:727
147
 msgid "Project not found on disk"
148
 msgstr "Il progetto non è stato trovato sul disco"
149
 
150
-#: projectaction.py:709
151
+#: projectaction.py:728
152
 msgid "Project can't be loaded."
153
 msgstr "Il progetto non può essere caricato."
154
 
155
-#: projectaction.py:717
156
+#: projectaction.py:736
157
 msgid "Project has not been saved since it was opened."
158
 msgstr "Questo progetto non è ancora stato salvato dall'apertura."
159
 
160
-#: projectaction.py:722
161
+#: projectaction.py:741
162
 msgid "Project was saved less than a minute ago."
163
 msgstr "Il progetto è stato salvato meno di un minuto fa."
164
 
165
-#: projectaction.py:725
166
+#: projectaction.py:744
167
 msgid "Project was saved one minute ago."
168
 msgstr "Il progetto è stato salvato un minuto fa."
169
 
170
-#: projectaction.py:727
171
+#: projectaction.py:746
172
 msgid "Project was saved "
173
 msgstr "Il progetto è stato salvato"
174
 
175
-#: projectaction.py:727
176
+#: projectaction.py:746
177
 msgid " minutes ago."
178
 msgstr " minuti fa."
179
 
180
-#: projectaction.py:781
181
+#: projectaction.py:753
182
+#, fuzzy
183
+msgid "Render target file exists!"
184
+msgstr "Area di calcolo non definita!"
185
+
186
+#: projectaction.py:754
187
+#, fuzzy
188
+msgid "Confirm overwriting existing file."
189
+msgstr "Vuoi sovrascriverlo?"
190
+
191
+#: projectaction.py:760
192
+msgid "Project is currently using proxy media!"
193
+msgstr ""
194
+
195
+#: projectaction.py:761
196
+msgid ""
197
+"Rendering from proxy media will produce worse quality than rendering from "
198
+"original media.\n"
199
+"Convert to using original media in Proxy Manager for best quality.\n"
200
+"\n"
201
flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/locale/pl Added
2
 
1
+(directory)
2
flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/locale/pl/LC_MESSAGES Added
2
 
1
+(directory)
2
flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/locale/pl/LC_MESSAGES/flowblade.mo Added
flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/locale/pl/LC_MESSAGES/flowblade.po Added
201
 
1
@@ -0,0 +1,6543 @@
2
+# Polish translations for PACKAGE package.
3
+# Copyright (C) 2017 THE PACKAGE'S COPYRIGHT HOLDER
4
+# This file is distributed under the same license as the PACKAGE package.
5
+# Stanisław Polak <polak@icsr.agh.edu.pl>, 2017.
6
+msgid ""
7
+msgstr ""
8
+"Project-Id-Version: PACKAGE VERSION\n"
9
+"Report-Msgid-Bugs-To: \n"
10
+"POT-Creation-Date: 2017-10-04 15:30+0300\n"
11
+"PO-Revision-Date: 2017-05-27 08:50+0200\n"
12
+"Last-Translator: Stanislaw Polak <polak@icsr.agh.edu.pl>\n"
13
+"Language-Team: Polish\n"
14
+"Language: pl\n"
15
+"MIME-Version: 1.0\n"
16
+"Content-Type: text/plain; charset=utf-8\n"
17
+"Content-Transfer-Encoding: 8bit\n"
18
+"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
19
+"|| n%100>=20) ? 1 : 2);\n"
20
+
21
+#: app.py:780
22
+msgid "Too small screen for this application."
23
+msgstr "Zbyt mały ekran dla tej aplikacji."
24
+
25
+#: app.py:783
26
+msgid "Minimum screen dimensions for this application are 1152 x 768.\n"
27
+msgstr "Minimalne wymiary ekranu dla tej aplikacji to 1152 x 768.\n"
28
+
29
+#: app.py:784
30
+msgid "Your screen dimensions are "
31
+msgstr "Wymiary twojego ekranu to "
32
+
33
+#: app.py:817 projectaction.py:380 projectaction.py:714
34
+msgid "Project has not been saved previously"
35
+msgstr "Projekt nie został wcześniej zapisany"
36
+
37
+#: app.py:818 projectaction.py:381 projectaction.py:715
38
+msgid "Save project with File -> Save As before closing."
39
+msgstr "Przed zamknięciem, zapisz projekt za pomocą Plik -> Zapisz jako."
40
+
41
+#: projectaction.py:121
42
+msgid "Media asset was missing!"
43
+msgstr "Brak zasobów multimedialnych!"
44
+
45
+#: projectaction.py:122
46
+msgid "Path of missing asset:"
47
+msgstr "Ścieżka brakującego zasobu:"
48
+
49
+#: projectaction.py:123
50
+msgid ""
51
+"Relative search for replacement file in sub folders of project file failed."
52
+msgstr ""
53
+"Względne wyszukiwanie plików zastępczych w podfolderach pliku projektu nie "
54
+"powiodło się."
55
+
56
+#: projectaction.py:124
57
+msgid "To load the project you will need to either:"
58
+msgstr "Aby załadować projekt, musisz również:"
59
+
60
+#: projectaction.py:125
61
+msgid ""
62
+"Open project in 'Media Relinker' tool to relink media assets to new files, or"
63
+msgstr ""
64
+"Otwórz projekt w narzędziu 'Relinker multimediów', aby powiązać zasoby "
65
+"multimedialne z nowymi plikami, lub"
66
+
67
+#: projectaction.py:126
68
+msgid "Place a file with the same exact name and path on the hard drive"
69
+msgstr "Umieść plik o tej samej nazwie i ścieżce na dysku twardym"
70
+
71
+#: projectaction.py:127
72
+msgid "Open project in Media Relinker tool"
73
+msgstr "Otwórz projekt w narzędziu Relinker multimediów"
74
+
75
+#: projectaction.py:146
76
+msgid "Profile with Description: '"
77
+msgstr "Profil z Opisem: '"
78
+
79
+#: projectaction.py:146
80
+msgid "' was not found on load!"
81
+msgstr "' nie został znaleziony podczas ładowania!"
82
+
83
+#: projectaction.py:147
84
+msgid ""
85
+"It is possible to load the project by creating a User Profile with exactly "
86
+"the same Description\n"
87
+"as the missing profile. "
88
+msgstr ""
89
+"Możliwe jest załadowanie projektu poprzez utworzenie Profilu Użytkownika z "
90
+"dokładnie tym samym opisem \n"
91
+"jak w przypadku brakującego profilu. "
92
+
93
+#: projectaction.py:148
94
+msgid "User Profiles can be created by selecting 'Edit->Profiles Manager'."
95
+msgstr ""
96
+"Profile Użytkowników można tworzyć, wybierając 'Edytuj -> Manager Profili'."
97
+
98
+#: projectaction.py:155
99
+msgid "Opening"
100
+msgstr "Otwieranie"
101
+
102
+#: projectaction.py:288
103
+msgid "Media files already present in project were opened!"
104
+msgstr "Otwarto pliki multimedialne, które już występują w projekcie!"
105
+
106
+#: projectaction.py:294
107
+msgid ""
108
+"Files already present:\n"
109
+"\n"
110
+msgstr ""
111
+"Pliki, które już występują:\n"
112
+"\n"
113
+
114
+#: projectaction.py:495
115
+msgid "Selected folder contains files"
116
+msgstr "Wybrany folder zawiera pliki"
117
+
118
+#: projectaction.py:496
119
+msgid ""
120
+"When saving a back-up snapshot of the project, the selected folder\n"
121
+"has to be empty."
122
+msgstr ""
123
+"Podczas zapisywania kopii migawkowej projektu, wybrany folder\n"
124
+"musi być pusty."
125
+
126
+#: projectaction.py:571
127
+msgid "Copying project media assets"
128
+msgstr "Kopiowanie zasobów multimedialnych projektu"
129
+
130
+#: projectaction.py:572
131
+msgid "Saving project file"
132
+msgstr "Zapisywanie pliku projektu"
133
+
134
+#: projectaction.py:727
135
+msgid "Project not found on disk"
136
+msgstr "Nie znaleziono projektu na dysku"
137
+
138
+#: projectaction.py:728
139
+msgid "Project can't be loaded."
140
+msgstr "Nie można załadować projektu."
141
+
142
+#: projectaction.py:736
143
+msgid "Project has not been saved since it was opened."
144
+msgstr "Od czasu jego otwarcia projekt nie został zapisany."
145
+
146
+#: projectaction.py:741
147
+msgid "Project was saved less than a minute ago."
148
+msgstr "Projekt został zapisany mniej niż minutę temu."
149
+
150
+#: projectaction.py:744
151
+msgid "Project was saved one minute ago."
152
+msgstr "Projekt został zapisany minutę temu."
153
+
154
+#: projectaction.py:746
155
+msgid "Project was saved "
156
+msgstr "Projekt został zapisany "
157
+
158
+#: projectaction.py:746
159
+msgid " minutes ago."
160
+msgstr " minut temu."
161
+
162
+#: projectaction.py:753
163
+#, fuzzy
164
+msgid "Render target file exists!"
165
+msgstr "Niezdefiniowany zakres renderowania"
166
+
167
+#: projectaction.py:754
168
+msgid "Confirm overwriting existing file."
169
+msgstr ""
170
+
171
+#: projectaction.py:760
172
+msgid "Project is currently using proxy media!"
173
+msgstr ""
174
+
175
+#: projectaction.py:761
176
+msgid ""
177
+"Rendering from proxy media will produce worse quality than rendering from "
178
+"original media.\n"
179
+"Convert to using original media in Proxy Manager for best quality.\n"
180
+"\n"
181
+"Select 'Confirm' to render from proxy media anyway."
182
+msgstr ""
183
+
184
+#: projectaction.py:838
185
+msgid "Render launch failed!"
186
+msgstr "Renderowanie nie powiodło się!"
187
+
188
+#: projectaction.py:839 projectaction.py:853 tools/batchrendering.py:299
189
+msgid "Error message: "
190
+msgstr "Komunikat o błędzie: "
191
+
192
+#: projectaction.py:852
193
+msgid "Adding item to render queue failed!"
194
+msgstr "Dodawanie elementu do kolejki renderowania nie powiodło się!"
195
+
196
+#: projectaction.py:871
197
+msgid "Open.."
198
+msgstr "Otwórz.."
199
+
200
+#: projectaction.py:896
201
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/locale/ru/LC_MESSAGES/flowblade.mo -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/locale/ru/LC_MESSAGES/flowblade.mo Changed
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/locale/ru/LC_MESSAGES/flowblade.po -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/locale/ru/LC_MESSAGES/flowblade.po Changed
201
 
1
@@ -6,81 +6,81 @@
2
 msgstr ""
3
 "Project-Id-Version: Flowblade\n"
4
 "Report-Msgid-Bugs-To: \n"
5
-"POT-Creation-Date: 2017-03-17 17:18+0200\n"
6
-"PO-Revision-Date: 2017-03-07 21:29+0300\n"
7
+"POT-Creation-Date: 2017-10-04 15:30+0300\n"
8
+"PO-Revision-Date: 2017-09-17 22:05+0300\n"
9
 "Last-Translator: Николай Смольянинов <smolianinow.colya2016@yandex.ru>\n"
10
-"Language-Team: Russian <kde-russian@lists.kde.ru>\n"
11
+"Language-Team: Russian\n"
12
 "Language: ru_RU\n"
13
 "MIME-Version: 1.0\n"
14
 "Content-Type: text/plain; charset=UTF-8\n"
15
 "Content-Transfer-Encoding: 8bit\n"
16
 "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
17
 "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
18
-"X-Generator: Lokalize 2.0\n"
19
+"X-Generator: Poedit 1.8.7.1\n"
20
 
21
-#: app.py:761
22
+#: app.py:780
23
 msgid "Too small screen for this application."
24
 msgstr "Недостаточное разрешение экрана."
25
 
26
-#: app.py:764
27
+#: app.py:783
28
 msgid "Minimum screen dimensions for this application are 1152 x 768.\n"
29
 msgstr "Разрешение экрана должно быть не ниже 1152 х 768.\n"
30
 
31
-#: app.py:765
32
+#: app.py:784
33
 msgid "Your screen dimensions are "
34
 msgstr "Ваше разрешение экрана"
35
 
36
-#: app.py:798 projectaction.py:365 projectaction.py:695
37
+#: app.py:817 projectaction.py:380 projectaction.py:714
38
 msgid "Project has not been saved previously"
39
 msgstr "Проект не был сохранён"
40
 
41
-#: app.py:799 projectaction.py:366 projectaction.py:696
42
+#: app.py:818 projectaction.py:381 projectaction.py:715
43
 msgid "Save project with File -> Save As before closing."
44
 msgstr "Сохраните проект перед закрытием (Файл ⇨ Сохранить как...)."
45
 
46
-#: projectaction.py:111
47
+#: projectaction.py:121
48
 msgid "Media asset was missing!"
49
 msgstr "Недостающий медиа актив!"
50
 
51
-#: projectaction.py:112
52
+#: projectaction.py:122
53
 msgid "Path of missing asset:"
54
 msgstr "Путь к недостающему активу"
55
 
56
-#: projectaction.py:113
57
+#: projectaction.py:123
58
 msgid ""
59
 "Relative search for replacement file in sub folders of project file failed."
60
 msgstr ""
61
 "Относительный поиск пути для замены файла во вложенных папках файла проекта "
62
 "не удался."
63
 
64
-#: projectaction.py:114
65
+#: projectaction.py:124
66
 msgid "To load the project you will need to either:"
67
 msgstr "Для загрузки проекта требуется, либо:"
68
 
69
-#: projectaction.py:115
70
+#: projectaction.py:125
71
 msgid ""
72
 "Open project in 'Media Relinker' tool to relink media assets to new files, or"
73
 msgstr ""
74
-"Открытый проект в инструменте \"Медиа компоновщик\"  переупакует медиа-"
75
-"активы к новым файлам, или"
76
+"Откройте проект в инструменте \"Перелинковщике медиа\" для повторной связи "
77
+"ресурсов медиа с новыми файлами или"
78
 
79
-#: projectaction.py:116
80
+#: projectaction.py:126
81
 msgid "Place a file with the same exact name and path on the hard drive"
82
 msgstr "Создать резервный файл с тем же именем и содержанием"
83
 
84
-#: projectaction.py:117
85
+#: projectaction.py:127
86
 msgid "Open project in Media Relinker tool"
87
-msgstr "Проект открыт в Медиа компоновщике"
88
+msgstr "Проект открыт в Перелинковщике медиа"
89
 
90
-#: projectaction.py:136
91
+#: projectaction.py:146
92
 msgid "Profile with Description: '"
93
 msgstr "Профиль с описанием: '"
94
 
95
-#: projectaction.py:136
96
+#: projectaction.py:146
97
 msgid "' was not found on load!"
98
 msgstr "' не найден при загрузке!"
99
 
100
-#: projectaction.py:137
101
+#: projectaction.py:147
102
 msgid ""
103
 "It is possible to load the project by creating a User Profile with exactly "
104
 "the same Description\n"
105
@@ -90,21 +90,21 @@
106
 "в отсутствующем\n"
107
 "профиле. "
108
 
109
-#: projectaction.py:138
110
+#: projectaction.py:148
111
 msgid "User Profiles can be created by selecting 'Edit->Profiles Manager'."
112
 msgstr ""
113
 "Профили пользователей могут быть созданы с помощью меню  \"Правка ⇨ Менеджер "
114
 "профилей\"."
115
 
116
-#: projectaction.py:145
117
+#: projectaction.py:155
118
 msgid "Opening"
119
 msgstr "Открывается"
120
 
121
-#: projectaction.py:275
122
+#: projectaction.py:288
123
 msgid "Media files already present in project were opened!"
124
 msgstr "Клипы уже присутствуют в проекте и были открыты!"
125
 
126
-#: projectaction.py:281
127
+#: projectaction.py:294
128
 msgid ""
129
 "Files already present:\n"
130
 "\n"
131
@@ -112,11 +112,11 @@
132
 "Файлы уже присутствуют:\n"
133
 "\n"
134
 
135
-#: projectaction.py:480
136
+#: projectaction.py:495
137
 msgid "Selected folder contains files"
138
 msgstr "Выбранная папка содержит файлы"
139
 
140
-#: projectaction.py:481
141
+#: projectaction.py:496
142
 msgid ""
143
 "When saving a back-up snapshot of the project, the selected folder\n"
144
 "has to be empty."
145
@@ -124,73 +124,115 @@
146
 "При сохранении резервной копии проекта, выбираемая папка\n"
147
 "должна быть пустой."
148
 
149
-#: projectaction.py:552
150
+#: projectaction.py:571
151
 msgid "Copying project media assets"
152
 msgstr "Копирование медиа-активов проекта"
153
 
154
-#: projectaction.py:553
155
+#: projectaction.py:572
156
 msgid "Saving project file"
157
 msgstr "Сохранение файла проекта"
158
 
159
-#: projectaction.py:708
160
+#: projectaction.py:727
161
 msgid "Project not found on disk"
162
 msgstr "Проект не найден"
163
 
164
-#: projectaction.py:709
165
+#: projectaction.py:728
166
 msgid "Project can't be loaded."
167
 msgstr "Невозможно загрузить проект"
168
 
169
-#: projectaction.py:717
170
+#: projectaction.py:736
171
 msgid "Project has not been saved since it was opened."
172
-msgstr "Открыт не сохранённый проект."
173
+msgstr "Открыт несохранённый проект."
174
 
175
-#: projectaction.py:722
176
+#: projectaction.py:741
177
 msgid "Project was saved less than a minute ago."
178
 msgstr "Проект был сохранён менее минуты назад."
179
 
180
-#: projectaction.py:725
181
+#: projectaction.py:744
182
 msgid "Project was saved one minute ago."
183
 msgstr "Проект был сохранён минуту назад."
184
 
185
-#: projectaction.py:727
186
+#: projectaction.py:746
187
 msgid "Project was saved "
188
 msgstr "Проект был сохранён "
189
 
190
-#: projectaction.py:727
191
+#: projectaction.py:746
192
 msgid " minutes ago."
193
 msgstr " минут назад."
194
 
195
-#: projectaction.py:781
196
+#: projectaction.py:753
197
+msgid "Render target file exists!"
198
+msgstr "Целевой файл существует!"
199
+
200
+#: projectaction.py:754
201
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/locale/upgrade_all -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/locale/upgrade_all Changed
9
 
1
@@ -1,6 +1,6 @@
2
 #!/bin/bash
3
 
4
-LANGUAGES=("fi" "cs" "fr" "es" "it" "de" "hu" "ru")
5
+LANGUAGES=("fi" "cs" "fr" "es" "it" "de" "hu" "ru" "zh_CN" "pl")
6
 
7
 echo "Upgading all languages"
8
 
9
flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/locale/zh_CN Added
2
 
1
+(directory)
2
flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/locale/zh_CN/LC_MESSAGES Added
2
 
1
+(directory)
2
flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/locale/zh_CN/LC_MESSAGES/flowblade.mo Added
flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/locale/zh_CN/LC_MESSAGES/flowblade.po Added
201
 
1
@@ -0,0 +1,6512 @@
2
+# Language LANGUAGE translations for PACKAGE package.
3
+# Copyright (C) 2017 THE PACKAGE'S COPYRIGHT HOLDER
4
+# This file is distributed under the same license as the PACKAGE package.
5
+# 老吴的BOX<laowudebox@126.com>, 2017.05.01
6
+#
7
+msgid ""
8
+msgstr ""
9
+"Project-Id-Version: PACKAGE VERSION\n"
10
+"Report-Msgid-Bugs-To: \n"
11
+"POT-Creation-Date: 2017-10-04 15:30+0300\n"
12
+"PO-Revision-Date: 2017-04-15 18:47+0800\n"
13
+"Last-Translator: wu <laowudebox@126.com>\n"
14
+"Language-Team: Language LANGUAGE\n"
15
+"Language: LANGUAGE_CODE\n"
16
+"MIME-Version: 1.1\n"
17
+"Content-Type: text/plain; charset=UTF-8\n"
18
+"Content-Transfer-Encoding: 8bit\n"
19
+
20
+#: app.py:780
21
+msgid "Too small screen for this application."
22
+msgstr "对于这个应用,画面太小。"
23
+
24
+#: app.py:783
25
+msgid "Minimum screen dimensions for this application are 1152 x 768.\n"
26
+msgstr "对于这个应用,最小画面尺寸是1152 x 768.\n"
27
+
28
+#: app.py:784
29
+msgid "Your screen dimensions are "
30
+msgstr "你的画面尺寸是"
31
+
32
+#: app.py:817 projectaction.py:380 projectaction.py:714
33
+msgid "Project has not been saved previously"
34
+msgstr "项目还未被保存过"
35
+
36
+#: app.py:818 projectaction.py:381 projectaction.py:715
37
+msgid "Save project with File -> Save As before closing."
38
+msgstr "保存项目为 -> 与关闭之前一致"
39
+
40
+#: projectaction.py:121
41
+msgid "Media asset was missing!"
42
+msgstr "有用的媒体已丢失"
43
+
44
+#: projectaction.py:122
45
+msgid "Path of missing asset:"
46
+msgstr "已丢失的有用东西的路径"
47
+
48
+#: projectaction.py:123
49
+msgid ""
50
+"Relative search for replacement file in sub folders of project file failed."
51
+msgstr "在失败项目文件的子文件夹中搜索相关代替文件"
52
+
53
+#: projectaction.py:124
54
+msgid "To load the project you will need to either:"
55
+msgstr "加载你将会需要的另一个项目"
56
+
57
+#: projectaction.py:125
58
+msgid ""
59
+"Open project in 'Media Relinker' tool to relink media assets to new files, or"
60
+msgstr "在媒体重新链接器工具中打开项目以便重新连接相关媒体到新文件,或者"
61
+
62
+#: projectaction.py:126
63
+msgid "Place a file with the same exact name and path on the hard drive"
64
+msgstr "放置一个名字和路径完全相同的的文件到硬盘上"
65
+
66
+#: projectaction.py:127
67
+msgid "Open project in Media Relinker tool"
68
+msgstr "在媒体重新链接器工具中打开项目"
69
+
70
+#: projectaction.py:146
71
+msgid "Profile with Description: '"
72
+msgstr "带有描述的简介"
73
+
74
+#: projectaction.py:146
75
+msgid "' was not found on load!"
76
+msgstr "未找到加载内容"
77
+
78
+#: projectaction.py:147
79
+msgid ""
80
+"It is possible to load the project by creating a User Profile with exactly "
81
+"the same Description\n"
82
+"as the missing profile. "
83
+msgstr ""
84
+"通过准确地创建一个用户简介来加载项目相同的描述\n"
85
+"作为已丢失的简介。"
86
+
87
+#: projectaction.py:148
88
+msgid "User Profiles can be created by selecting 'Edit->Profiles Manager'."
89
+msgstr "用户简介可以通过选择“简介管理器”来创建"
90
+
91
+#: projectaction.py:155
92
+msgid "Opening"
93
+msgstr "正在打开"
94
+
95
+#: projectaction.py:288
96
+msgid "Media files already present in project were opened!"
97
+msgstr "媒体文件已经发送到被打开的项目"
98
+
99
+#: projectaction.py:294
100
+msgid ""
101
+"Files already present:\n"
102
+"\n"
103
+msgstr ""
104
+"文件已经发送\n"
105
+"\n"
106
+
107
+#: projectaction.py:495
108
+msgid "Selected folder contains files"
109
+msgstr "选中的目录包含文件"
110
+
111
+#: projectaction.py:496
112
+msgid ""
113
+"When saving a back-up snapshot of the project, the selected folder\n"
114
+"has to be empty."
115
+msgstr ""
116
+"当保存一个项目的快照备份时,被选中的目录\n"
117
+"必须为空。"
118
+
119
+#: projectaction.py:571
120
+msgid "Copying project media assets"
121
+msgstr "正在复制相关项目媒体"
122
+
123
+#: projectaction.py:572
124
+msgid "Saving project file"
125
+msgstr "正在保存项目文件"
126
+
127
+#: projectaction.py:727
128
+msgid "Project not found on disk"
129
+msgstr "项目未在磁盘找到"
130
+
131
+#: projectaction.py:728
132
+msgid "Project can't be loaded."
133
+msgstr "项目不能被加载。"
134
+
135
+#: projectaction.py:736
136
+msgid "Project has not been saved since it was opened."
137
+msgstr "由于被打开,项目未被保存"
138
+
139
+#: projectaction.py:741
140
+msgid "Project was saved less than a minute ago."
141
+msgstr "不到1分钟之前,项目已被保存"
142
+
143
+#: projectaction.py:744
144
+msgid "Project was saved one minute ago."
145
+msgstr "1分钟之前,项目已被保存"
146
+
147
+#: projectaction.py:746
148
+msgid "Project was saved "
149
+msgstr "项目已被保存"
150
+
151
+#: projectaction.py:746
152
+msgid " minutes ago."
153
+msgstr "几分钟之前"
154
+
155
+#: projectaction.py:753
156
+#, fuzzy
157
+msgid "Render target file exists!"
158
+msgstr "渲染范围未明确"
159
+
160
+#: projectaction.py:754
161
+msgid "Confirm overwriting existing file."
162
+msgstr ""
163
+
164
+#: projectaction.py:760
165
+msgid "Project is currently using proxy media!"
166
+msgstr ""
167
+
168
+#: projectaction.py:761
169
+msgid ""
170
+"Rendering from proxy media will produce worse quality than rendering from "
171
+"original media.\n"
172
+"Convert to using original media in Proxy Manager for best quality.\n"
173
+"\n"
174
+"Select 'Confirm' to render from proxy media anyway."
175
+msgstr ""
176
+
177
+#: projectaction.py:838
178
+msgid "Render launch failed!"
179
+msgstr "导致启动失败!"
180
+
181
+#: projectaction.py:839 projectaction.py:853 tools/batchrendering.py:299
182
+msgid "Error message: "
183
+msgstr "错误信息"
184
+
185
+#: projectaction.py:852
186
+msgid "Adding item to render queue failed!"
187
+msgstr "添加条款导致列队失败!"
188
+
189
+#: projectaction.py:871
190
+msgid "Open.."
191
+msgstr "打开.."
192
+
193
+#: projectaction.py:896
194
+msgid "Opening .mlt or .xml file as media was disallowed!"
195
+msgstr ""
196
+
197
+#: projectaction.py:897
198
+msgid ""
199
+"Because of current MLT behaviour of overwriting projct properties when "
200
+"opening MLT XML files\n"
201
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/menuactions.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/menuactions.py Changed
51
 
1
@@ -34,6 +34,7 @@
2
 import appconsts
3
 import dialogs
4
 import dialogutils
5
+import editorpersistance
6
 from editorstate import PROJECT
7
 from editorstate import PLAYER
8
 from editorstate import current_sequence
9
@@ -46,6 +47,7 @@
10
 import projectdata
11
 import patternproducer
12
 import profilesmanager
13
+import shortcuts
14
 import renderconsumer
15
 import respaths
16
 
17
@@ -112,14 +114,12 @@
18
 def _show_project_info_callback(dialog, response_id):
19
     dialog.destroy()
20
 
21
-# ------------------------------------------------------ help menu
22
 def about():
23
     dialogs.about_dialog(gui.editor_window)
24
 
25
 def environment():
26
     dialogs.environment_dialog(gui.editor_window)
27
-
28
-# ----------------------------------------------------- environment data        
29
+    
30
 def quick_reference():
31
     try:
32
         url = "file://" + respaths.HELP_DOC
33
@@ -170,3 +170,17 @@
34
     else:
35
        gui.editor_window.window.unfullscreen()
36
        editorstate.fullscreen = False
37
+
38
+def keyboard_shortcuts_callback(dialog, response_id, presets_combo):
39
+    selected_shortcuts_index = presets_combo.get_active()
40
+    dialog.destroy()
41
+    
42
+    if response_id == Gtk.ResponseType.REJECT:
43
+        return
44
+    
45
+    selected_xml = shortcuts.shortcut_files[selected_shortcuts_index]
46
+    if selected_xml == editorpersistance.prefs.shortcuts:
47
+        return
48
+
49
+    editorpersistance.prefs.shortcuts = selected_xml
50
+    shortcuts.set_keyboard_shortcuts()
51
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/middlebar.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/middlebar.py Changed
45
 
1
@@ -117,7 +117,15 @@
2
 
3
 def _create_buttons(editor_window):
4
     IMG_PATH = respaths.IMAGE_PATH
5
-    editor_window.big_TC = guicomponents.BigTCDisplay()
6
+    editor_window.big_TC = Gtk.Stack()
7
+    tc_disp = guicomponents.BigTCDisplay()
8
+    tc_entry = guicomponents.BigTCEntry()
9
+    tc_disp.widget.show()
10
+    tc_entry.widget.show()
11
+    editor_window.big_TC.add_named(tc_disp.widget, "BigTCDisplay")
12
+    editor_window.big_TC.add_named(tc_entry.widget, "BigTCEntry")
13
+    editor_window.big_TC.set_visible_child_name("BigTCDisplay")
14
+    gui.big_tc = editor_window.big_TC 
15
     editor_window.modes_selector = guicomponents.ToolSelector(editor_window.mode_selector_pressed, m_pixbufs, 40, 22)
16
 
17
     editor_window.zoom_buttons = glassbuttons.GlassButtonsGroup(46, 23, 2, 4, 5)
18
@@ -169,7 +177,7 @@
19
 def fill_with_TC_LEFT_pattern(buttons_row, window):
20
     global w
21
     w = window
22
-    buttons_row.pack_start(w.big_TC.widget, False, True, 0)
23
+    buttons_row.pack_start(w.big_TC, False, True, 0)
24
     buttons_row.pack_start(guiutils.get_pad_label(7, MIDDLE_ROW_HEIGHT), False, True, 0) #### NOTE!!!!!! THIS DETERMINES THE HEIGHT OF MIDDLE ROW
25
     buttons_row.pack_start(w.modes_selector.widget, False, True, 0)
26
     if editorstate.SCREEN_WIDTH > 1279:
27
@@ -212,7 +220,7 @@
28
     left_panel.pack_start(Gtk.Label(), True, True, 0)
29
 
30
     middle_panel = Gtk.HBox(False, 0) 
31
-    middle_panel.pack_start(w.big_TC.widget, False, True, 0)
32
+    middle_panel.pack_start(w.big_TC, False, True, 0)
33
     middle_panel.pack_start(guiutils.get_pad_label(10, 10), False, True, 0)
34
     middle_panel.pack_start(w.modes_selector.widget, False, True, 0)
35
     
36
@@ -234,7 +242,7 @@
37
     global w
38
     w = window
39
     buttons_row.pack_start(Gtk.Label(), True, True, 0)
40
-    buttons_row.pack_start(w.big_TC.widget, False, True, 0)
41
+    buttons_row.pack_start(w.big_TC, False, True, 0)
42
     buttons_row.pack_start(guiutils.get_pad_label(7, MIDDLE_ROW_HEIGHT), False, True, 0) #### NOTE!!!!!! THIS DETERMINES THE HEIGHT OF MIDDLE ROW
43
     buttons_row.pack_start(w.modes_selector.widget, False, True, 0)
44
     if editorstate.SCREEN_WIDTH > 1279:
45
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/mltenv.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/mltenv.py Changed
20
 
1
@@ -98,13 +98,17 @@
2
 def render_profile_supported(frmt, vcodec, acodec):
3
     if environment_detection_success == False:
4
         return (True, "")
5
-
6
+        
7
     if acodec in acodecs or acodec == None: # some encoding options do not specify audio codecs
8
         if vcodec in vcodecs or vcodec == None: # some encoding options do not specify video codecs
9
             if frmt in formats or frmt == None: # some encoding options do not specify formats
10
                 return (True, "")
11
+            elif frmt == "mkv" and "matroska" in formats:
12
+                # "matroska" format means that "mkv" files can created
13
+                return (True, "")
14
             else:
15
                 err_msg = "format " + frmt
16
+                print err_msg
17
         else:
18
             err_msg = "video codec " + vcodec
19
     else:
20
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/mltprofiles.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/mltprofiles.py Changed
110
 
1
@@ -19,7 +19,7 @@
2
 """
3
 
4
 """
5
-MLT framework profiles. 
6
+MLT framework profiles.
7
 """
8
 import os
9
 import mlt
10
@@ -38,7 +38,6 @@
11
 _hidden_factory_profiles = []
12
 _user_profiles = []
13
 
14
-
15
 def load_profile_list():
16
     """ 
17
     Creates a list of MLT profile objects.
18
@@ -62,20 +61,20 @@
19
     file_list = os.listdir(dir_path)
20
     for fname in file_list:
21
         ## Feb-2017 - SvdB - Filter out duplicate profiles based on profile name
22
-        #found_duplicate = False
23
+        found_duplicate = False
24
         
25
         file_path = dir_path + fname
26
         profile = mlt.Profile(file_path)
27
         profile.file_path = file_path
28
         load_profiles.append([profile.description(), profile])
29
-        
30
+
31
         # Feb-2017 - SvdB - Filter out duplicate profiles based on profile name
32
-        #for enu_count, prof in enumerate(load_profiles):
33
-        #    for prof_idx, prof_name in enumerate(prof):
34
-        #        if prof_name == profile.description():
35
-        #            found_duplicate = True
36
-        #if found_duplicate == False:
37
-        #    load_profiles.append([profile.description(), profile])
38
+        for enu_count, prof in enumerate(load_profiles):
39
+            for prof_idx, prof_name in enumerate(prof):
40
+                if prof_name == profile.description():
41
+                    found_duplicate = True
42
+        if found_duplicate == False:
43
+            load_profiles.append([profile.description(), profile])
44
     
45
     return load_profiles
46
 
47
@@ -149,14 +148,34 @@
48
             return i
49
     return -1
50
 
51
+def get_profile_node(profile):
52
+    node_str = '<profile description="' +  profile.description() + '" '
53
+    node_str += 'width="' + str(profile.width()) + '" '
54
+    node_str += 'height="' +  str(profile.height()) + '" '
55
+    if profile.progressive() == True:
56
+        prog_val = "1"
57
+    else:
58
+        prog_val = "0"
59
+    node_str += 'progressive="' + prog_val + '" '
60
+    node_str += 'sample_aspect_num="' + str(profile.sample_aspect_num()) + '" '
61
+    node_str += 'sample_aspect_den="' + str(profile.sample_aspect_den()) + '" '
62
+    node_str += 'display_aspect_num="' + str(profile.display_aspect_num()) + '" '
63
+    node_str += 'display_aspect_den="' + str(profile.display_aspect_den()) + '" '
64
+    node_str += 'frame_rate_num="' + str(profile.frame_rate_num()) + '" '
65
+    node_str += 'frame_rate_den="' + str(profile.frame_rate_den()) + '" '
66
+    node_str += 'colorspace="' + str(profile.colorspace()) + '"/>'
67
+
68
+    return node_str
69
+
70
 def get_closest_matching_profile_index(producer_info):
71
     # producer_info is dict from utils.get_file_producer_info
72
     width = producer_info["width"]
73
-    height= producer_info["height"]
74
+    height = producer_info["height"]
75
     fps_num =  producer_info["fps_num"]
76
     fps_den = producer_info["fps_den"]
77
     progressive = producer_info["progressive"]
78
     fps = round(float(float(fps_num)/float(fps_den)), 1)
79
+    fps_2 = round(float(float(fps_num)/float(fps_den)), 2) # We added as a fix later for #290, fix might have been done some other way
80
     
81
     # We calculate match score for all available profiles and return 
82
     # the one with the highest score
83
@@ -172,21 +191,23 @@
84
         prof_fps_den = profile.frame_rate_den()
85
         prof_progressive = profile.progressive()
86
         prof_fps = round(float(float(prof_fps_num)/float(prof_fps_den)), 1)
87
-
88
+        prof_fps_2 = round(float(float(prof_fps_num)/float(prof_fps_den)), 2) # We added this as a fix later for #290, fix might have been done some other way
89
+        
90
         if width == prof_width and height == prof_height:
91
             match_score = match_score + 1000
92
         if fps == prof_fps:
93
             match_score = match_score + 100
94
+        if fps_2 == prof_fps_2: # We added this as a fix later for #290, fix might have been done some other way
95
+            match_score = match_score + 5
96
         if prof_progressive: # prefer progressive always
97
             match_score = match_score + 10
98
-
99
         if match_score > current_match_score:
100
             current_match_score = match_score
101
             current_match_index = i
102
 
103
     if current_match_index == -1:
104
         return get_default_profile_index()
105
-
106
+    
107
     return current_match_index
108
 
109
 def _sort_profiles(a, b):
110
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/mlttransitions.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/mlttransitions.py Changed
149
 
1
@@ -28,6 +28,7 @@
2
 import xml.dom.minidom
3
 
4
 import appconsts
5
+import compositorfades
6
 import mltrefhold
7
 import patternproducer
8
 import propertyparse
9
@@ -40,6 +41,7 @@
10
 EXTRA_EDITOR = appconsts.EXTRA_EDITOR
11
 MLT_SERVICE = appconsts.MLT_SERVICE
12
 COMPOSITOR = "compositortransition"
13
+AUTO_FADE_COMPOSITOR = "autofadecompositor"
14
 
15
 # Property types.
16
 PROP_INT = appconsts.PROP_INT
17
@@ -68,11 +70,12 @@
18
 wipe_lumas = None # User displayed name -> resource image
19
 compositors = None
20
 blenders = None
21
+autofades = None
22
 
23
 def init_module():
24
 
25
     # translations and module load order make us do this in method instead of at module load
26
-    global wipe_lumas, compositors, blenders, name_for_type, rendered_transitions, single_track_render_type_names
27
+    global wipe_lumas, compositors, blenders, name_for_type, rendered_transitions, single_track_render_type_names, autofades
28
     wipe_lumas = { \
29
                 _("Vertical From Center"):"bi-linear_x.pgm",
30
                 _("Vertical Top to Bottom"):"wipe_top_to_bottom.svg",
31
@@ -151,6 +154,9 @@
32
                 (_("Subtract"),"##subtract"),
33
                 (_("Value"),"##value")]
34
 
35
+    autofades = [(_("Fade In"),"##auto_fade_in"),
36
+                (_("Fade Out"),"##auto_fade_out")]
37
+    
38
     for comp in compositors:
39
         name, comp_type = comp
40
         name_for_type[comp_type] = name
41
@@ -158,7 +164,11 @@
42
     for blend in blenders:
43
         name, comp_type = blend
44
         name_for_type[comp_type] = name
45
-    
46
+
47
+    for fade in autofades:
48
+        name, comp_type = fade
49
+        name_for_type[comp_type] = name
50
+        
51
     # change this, tuples are not need we only need list of translatd names
52
     rendered_transitions = [  (_("Dissolve"), RENDERED_DISSOLVE), 
53
                               (_("Wipe"), RENDERED_WIPE),
54
@@ -174,6 +184,11 @@
55
     """
56
     def __init__(self, compositor_node):
57
         self.mlt_service_id = compositor_node.getAttribute(MLT_SERVICE)
58
+        if compositor_node.hasAttribute(AUTO_FADE_COMPOSITOR):
59
+            self.auto_fade_compositor = bool(compositor_node.getAttribute(AUTO_FADE_COMPOSITOR))
60
+        else:
61
+            self.auto_fade_compositor = False
62
+
63
         self.xml = compositor_node.toxml()
64
         self.name = compositor_node.getElementsByTagName(NAME).item(0).firstChild.nodeValue
65
         
66
@@ -195,7 +210,7 @@
67
     They wrap mlt.Transition objects that do the actual mixing.
68
     """
69
     def __init__(self, transition_info):
70
-        self.mlt_transition = None
71
+        self.mlt_transition = None # mlt.Transition object
72
         self.info = transition_info
73
         # Editable properties, usually a subset of all properties of 
74
         # mlt_serveice "composite", defined in compositors.xml
75
@@ -273,6 +288,7 @@
76
         self.mlt_transition.set("a_track", str(a_track))
77
         self.mlt_transition.set("b_track", str(b_track))
78
 
79
+
80
     def set_target_track(self, a_track, force_track):
81
         self.a_track = a_track
82
         self.mlt_transition.set("a_track", str(a_track))
83
@@ -304,7 +320,7 @@
84
         self.clip_out = -1 # ducktyping for clip for property editors
85
         self.planted = False
86
         self.compositor_index = None
87
-        self.name = None # ducktyping for clip for property editors
88
+        self.name = None # ducktyping as clip for property editors
89
         self.selected = False
90
         self.origin_clip_id = None
91
         
92
@@ -328,7 +344,18 @@
93
         self.clip_out = out_frame
94
         self.transition.mlt_transition.set("in", str(in_frame))
95
         self.transition.mlt_transition.set("out", str(out_frame))
96
+        self.update_autofade_keyframes()
97
 
98
+    def set_length_from_in(self, length):
99
+        self.clip_out = self.clip_in + length - 1
100
+        self.transition.mlt_transition.set("out", str(self.clip_out))
101
+        self.update_autofade_keyframes()
102
+
103
+    def set_length_from_out(self, length):
104
+        self.clip_in = self.clip_out - length + 1
105
+        self.transition.mlt_transition.set("in", str(self.clip_in))
106
+        self.update_autofade_keyframes()
107
+        
108
     def create_mlt_objects(self, mlt_profile):
109
         self.transition.create_mlt_transition(mlt_profile)
110
     
111
@@ -351,7 +378,15 @@
112
             self.transition.properties = copy.deepcopy(properties)
113
             self.transition.update_editable_mlt_properties()
114
         
115
+    def update_autofade_keyframes(self):
116
+        if self.transition.info.auto_fade_compositor == False:
117
+            return
118
         
119
+        if self.transition.info.name == "##auto_fade_in":
120
+            compositorfades.set_auto_fade_in_keyframes(self)
121
+        else:
122
+            compositorfades.set_auto_fade_out_keyframes(self)
123
+            
124
 # -------------------------------------------------- compositor interface methods
125
 def load_compositors_xml(transitions):
126
     """
127
@@ -369,6 +404,7 @@
128
             global not_found_transitions
129
             not_found_transitions.append(compositor_info)
130
             continue
131
+
132
         mlt_compositor_transition_infos[compositor_info.name] = compositor_info
133
 
134
 def get_wipe_resource_path_for_sorted_keys_index(sorted_keys_index):
135
@@ -389,6 +425,13 @@
136
     compositor.type_id = compositor_type # this is a string like "##add", "##affineblend", in compositors.xml it is name element: <name>##affine</name> etc...
137
     return compositor
138
 
139
+def is_blender(compositor_type_test):
140
+    for blend in blenders:
141
+        name, compositor_type = blend
142
+        if compositor_type_test == compositor_type:
143
+            return True
144
+    
145
+    return False
146
 
147
 # ------------------------------------------------------ rendered transitions
148
 # These are tractor objects used to create rendered transitions.
149
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/monitorwidget.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/monitorwidget.py Changed
10
 
1
@@ -163,7 +163,7 @@
2
         if self.view == FRAME_MATCH_VIEW and force_default_mode==False:
3
             return
4
             
5
-        # Refreshing while rendering overwrites file on disk and loses 
6
+        # Refreshing player while rendering overwrites file on disk and loses 
7
         # previous rendered data. 
8
         if PLAYER().is_rendering:
9
             return
10
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/panels.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/panels.py Changed
68
 
1
@@ -27,6 +27,7 @@
2
 from gi.repository import Gtk, Gdk
3
 from gi.repository import GdkPixbuf
4
 
5
+import appconsts
6
 import gui
7
 import guicomponents
8
 import guiutils
9
@@ -380,7 +381,9 @@
10
     encodings_cb.connect("changed", 
11
                               lambda w,e: _transition_encoding_changed(transition_widgets), 
12
                               None)
13
-    _fill_transition_quality_combo_box(transition_widgets)
14
+    _fill_transition_quality_combo_box(transition_widgets, 10)
15
+    
16
+    _set_saved_encoding(transition_widgets)
17
     
18
     # Build panel
19
     edit_vbox = Gtk.VBox(False, 2)
20
@@ -439,7 +442,10 @@
21
     encodings_cb.connect("changed", 
22
                               lambda w,e: _transition_encoding_changed(transition_widgets), 
23
                               None)
24
-    _fill_transition_quality_combo_box(transition_widgets)
25
+
26
+    _fill_transition_quality_combo_box(transition_widgets, 10)
27
+    _set_saved_encoding(transition_widgets)
28
+    
29
     
30
     # Build panel
31
     edit_vbox = Gtk.VBox(False, 2)
32
@@ -462,7 +468,7 @@
33
 def _transition_encoding_changed(widgets):
34
     _fill_transition_quality_combo_box(widgets)
35
  
36
-def _fill_transition_quality_combo_box(widgets):
37
+def _fill_transition_quality_combo_box(widgets, quality_index=-1):
38
     encodings_cb, quality_cb = widgets
39
     enc_index = encodings_cb.get_active()
40
     encoding = renderconsumer.encoding_options[enc_index]
41
@@ -471,11 +477,22 @@
42
     for quality_option in encoding.quality_options:
43
         quality_cb.append_text(quality_option.name)
44
 
45
-    if encoding.quality_default_index != None:
46
-        quality_cb.set_active(encoding.quality_default_index)
47
+    if quality_index == -1:
48
+        if encoding.quality_default_index != None:
49
+            quality_cb.set_active(encoding.quality_default_index)
50
+        else:
51
+            quality_cb.set_active(0)
52
     else:
53
-        quality_cb.set_active(0)
54
-
55
+            quality_cb.set_active(quality_index)
56
+            
57
+def _set_saved_encoding(transition_widgets):
58
+    saved_encoding = editorstate.PROJECT().get_project_property(appconsts.P_PROP_TRANSITION_ENCODING)
59
+    if saved_encoding != None:
60
+        encodings_cb, quality_cb = transition_widgets
61
+        enc_index, quality_index = saved_encoding
62
+        encodings_cb.set_active(enc_index)
63
+        quality_cb.set_active(quality_index)
64
+    
65
 def _transition_type_changed(transition_type_widgets):
66
     type_combo_box, wipe_luma_combo_box, color_button, wipe_label, color_label = transition_type_widgets
67
     if type_combo_box.get_active() == 0:
68
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/persistance.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/persistance.py Changed
162
 
1
@@ -29,6 +29,7 @@
2
 import copy
3
 import glob
4
 import fnmatch
5
+import md5
6
 import os
7
 import pickle
8
 import time
9
@@ -83,20 +84,19 @@
10
 
11
 # Used to compute in/out points when saving to change profile
12
 _fps_conv_mult = 1.0
13
-    
14
+
15
+# A dict is put here when saving for profile change to contain paths to changed MLT XML files
16
+_xml_new_paths_for_profile_change = None
17
+
18
 class FileProducerNotFoundError(Exception):
19
-    """
20
-    We're only catching this, other errors we'll just crash on load
21
-    """
22
+
23
     def __init__(self, value):
24
         self.value = value
25
     def __str__(self):
26
         return repr(self.value)
27
 
28
 class ProjectProfileNotFoundError(Exception):
29
-    """
30
-    We're only catching this, other errors we'll just crash on load
31
-    """
32
+
33
     def __init__(self, value):
34
         self.value = value
35
     def __str__(self):
36
@@ -121,13 +121,17 @@
37
     s_proj = copy.copy(project)
38
     
39
     # Implements "change profile" functionality
40
-    global _fps_conv_mult
41
+    global _fps_conv_mult, _xml_new_paths_for_profile_change
42
     _fps_conv_mult = 1.0
43
     if changed_profile_desc != None:
44
         _fps_conv_mult = mltprofiles.get_profile(changed_profile_desc).fps() / mltprofiles.get_profile(s_proj.profile_desc).fps()
45
         s_proj.profile_desc = changed_profile_desc
46
+        _xml_new_paths_for_profile_change = {} # dict acts also as a flag to show that profile change save is happening
47
+        new_profile = mltprofiles.get_profile(changed_profile_desc)
48
         print "Saving changed profile project: ", changed_profile_desc
49
         print "FPS conversion multiplier:", _fps_conv_mult
50
+    else:
51
+        _xml_new_paths_for_profile_change = None # None value acts also as a flag to show that profile change save is _not_ happening
52
 
53
     # Set current sequence index
54
     s_proj.c_seq_index = project.sequences.index(project.c_seq)
55
@@ -145,8 +149,19 @@
56
     media_files = {}
57
     for k, v in s_proj.media_files.iteritems():
58
         s_media_file = copy.copy(v)
59
-        remove_attrs(s_media_file, MEDIA_FILE_REMOVE)
60
         
61
+        # Because of MLT misfeature of changing project profile when loading MLT XML files we need to create new modified XML files when
62
+        # saving to change profile.
63
+        # Underlying reason: https://github.com/mltframework/mlt/issues/212
64
+        if changed_profile_desc != None and s_media_file.path != None and utils.is_mlt_xml_file(s_media_file.path) == True:
65
+            new_xml_file_path = _save_changed_xml_file(s_media_file, new_profile)
66
+            _xml_new_paths_for_profile_change[s_media_file.path] = new_xml_file_path
67
+            s_media_file.path = new_xml_file_path
68
+            print "XML path replace for media:", s_media_file.path,  new_xml_file_path
69
+
70
+        # Remove unpicleable attrs
71
+        remove_attrs(s_media_file, MEDIA_FILE_REMOVE)
72
+
73
         # Convert media files between original and proxy files
74
         if project_proxy_mode == appconsts.CONVERTING_TO_USE_PROXY_MEDIA:
75
             if s_media_file.has_proxy_file:
76
@@ -165,6 +180,7 @@
77
                 s_media_file.path = snapshot_paths[s_media_file.path] 
78
 
79
         media_files[s_media_file.id] = s_media_file
80
+
81
     s_proj.media_files = media_files
82
 
83
     # Replace sequences with pickleable objects
84
@@ -227,7 +243,19 @@
85
     Creates pickleable version of MLT Producer object
86
     """
87
     s_clip = copy.copy(clip)
88
-     
89
+
90
+    # Because of MLT misfeature of changing project profile when loading MLT XML files we need to create new modified XML files when
91
+    # saving to change profile.
92
+    # Underlying reason: https://github.com/mltframework/mlt/issues/212
93
+    if _xml_new_paths_for_profile_change != None and hasattr(s_clip, "path") and s_clip.path != None and utils.is_mlt_xml_file(s_clip.path) == True:
94
+        try:
95
+            new_path = _xml_new_paths_for_profile_change[s_clip.path]
96
+            print "XML path replace for clip:", s_clip.path, new_path
97
+            s_clip.path = new_path
98
+        except:
99
+            # Something is really wrong, this should not be possible
100
+            print "Failed to find a new XML file for path:", s_clip.path
101
+
102
     # Set 'type' attribute for MLT object type
103
     # This IS NOT USED anywhere anymore and should be removed.
104
     s_clip.type = 'Mlt__Producer'
105
@@ -301,6 +329,7 @@
106
         s_compositor.transition.mlt_transition = None
107
         if _fps_conv_mult != 1.0:
108
             _update_compositor_in_out_for_fps_change(s_compositor)
109
+
110
         s_compositors.append(s_compositor)
111
 
112
     return s_compositors
113
@@ -330,7 +359,29 @@
114
 def _update_compositor_in_out_for_fps_change(s_compositor):
115
     s_compositor.clip_in = int(s_compositor.clip_in * _fps_conv_mult)
116
     s_compositor.clip_out = int(s_compositor.clip_out * _fps_conv_mult)
117
- 
118
+
119
+# Needed for xml files when doing profile change saves
120
+def _save_changed_xml_file(s_media_file, new_profile):
121
+    xml_file = open(s_media_file.path)
122
+    xml_text = xml_file.read()
123
+        
124
+    new_profile_node = mltprofiles.get_profile_node(new_profile)
125
+    
126
+    in_index = xml_text.find("<profile")
127
+    out_index = xml_text.find("/>", in_index) + 2
128
+    
129
+    new_xml_text = xml_text[0:in_index] + new_profile_node + xml_text[out_index:len(xml_text)]
130
+
131
+    folder = editorpersistance.prefs.render_folder
132
+    uuid_str = md5.new(str(os.urandom(32))).hexdigest()
133
+    new_xml_file_path = folder + "/"+ uuid_str + ".xml"
134
+
135
+    new_xml_file = open(new_xml_file_path, "w")
136
+    new_xml_file.write(new_xml_text)
137
+    new_xml_file.close()
138
+    
139
+    return new_xml_file_path
140
+
141
 # -------------------------------------------------- LOAD
142
 def load_project(file_path, icons_and_thumnails=True, relinker_load=False):
143
     _show_msg("Unpickling")
144
@@ -460,6 +511,7 @@
145
             compositor.transition.set_tracks(py_compositor.transition.a_track, py_compositor.transition.b_track)
146
             compositor.set_in_and_out(py_compositor.clip_in, py_compositor.clip_out)
147
             compositor.origin_clip_id = py_compositor.origin_clip_id
148
+           
149
             mlt_compositors.append(compositor)
150
 
151
     seq.compositors = mlt_compositors
152
@@ -727,6 +779,9 @@
153
     if (not(hasattr(project, "media_log_groups"))):
154
         project.media_log_groups = []
155
 
156
+    if (not(hasattr(project, "project_properties"))):
157
+        project.project_properties = {}
158
+        
159
 def _fix_wipe_relative_path(compositor):
160
     if compositor.type_id == "##wipe": # Wipe may have user luma and needs to be looked up relatively
161
         _set_wipe_res_path(compositor, "resource")
162
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/preferenceswindow.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/preferenceswindow.py Changed
201
 
1
@@ -26,9 +26,12 @@
2
 import editorpersistance
3
 import gui
4
 import guiutils
5
+import guicomponents
6
 import mltprofiles
7
 # Jan-2017 - SvdB - To get the number of CPU cores
8
 import multiprocessing
9
+# Apr-2017 - SvdB
10
+import shortcuts
11
 
12
 PREFERENCES_WIDTH = 730
13
 PREFERENCES_HEIGHT = 440
14
@@ -50,6 +53,8 @@
15
     view_pres_panel, view_pref_widgets = _view_prefs_panel()
16
     # Jan-2017 - SvdB
17
     performance_panel, performance_widgets = _performance_panel()
18
+    # Apr-2017 - SvdB
19
+    #shortcuts_panel, shortcuts_widgets = _shortcuts_panel()
20
 
21
     notebook = Gtk.Notebook()
22
     notebook.set_size_request(PREFERENCES_WIDTH, PREFERENCES_HEIGHT)
23
@@ -57,9 +62,11 @@
24
     notebook.append_page(edit_prefs_panel, Gtk.Label(label=_("Editing")))
25
     notebook.append_page(view_pres_panel, Gtk.Label(label=_("View")))
26
     notebook.append_page(performance_panel, Gtk.Label(label=_("Performance")))
27
+    #notebook.append_page(shortcuts_panel, Gtk.Label(label=_("Shortcuts")))
28
     guiutils.set_margins(notebook, 4, 24, 6, 0)
29
 
30
-    dialog.connect('response', _preferences_dialog_callback, (gen_opts_widgets, edit_prefs_widgets, view_pref_widgets, performance_widgets))
31
+    dialog.connect('response', _preferences_dialog_callback, (gen_opts_widgets, edit_prefs_widgets, view_pref_widgets, \
32
+        performance_widgets))
33
     dialog.vbox.pack_start(notebook, True, True, 0)
34
     dialogutils.set_outer_margins(dialog.vbox)
35
     dialogutils.default_behaviour(dialog)
36
@@ -207,6 +214,31 @@
37
     auto_center_on_updown = Gtk.CheckButton()
38
     auto_center_on_updown.set_active(prefs.center_on_arrow_move)
39
     
40
+    # Apr-2017 - SvdB - For FF/Rev speed options
41
+    if hasattr(prefs, 'ffwd_rev_shift'):
42
+        spin_adj = Gtk.Adjustment(prefs.ffwd_rev_shift, 1, 10, 1)
43
+    else:
44
+        spin_adj = Gtk.Adjustment(1, 1, 10, 1)
45
+    ffwd_rev_shift_spin = Gtk.SpinButton()
46
+    ffwd_rev_shift_spin.set_adjustment(spin_adj)
47
+    ffwd_rev_shift_spin.set_numeric(True)
48
+
49
+    if hasattr(prefs, 'ffwd_rev_ctrl'):
50
+        spin_adj = Gtk.Adjustment(prefs.ffwd_rev_ctrl, 1, 10, 1)
51
+    else:
52
+        spin_adj = Gtk.Adjustment(10, 1, 10, 1)
53
+    ffwd_rev_ctrl_spin = Gtk.SpinButton()
54
+    ffwd_rev_ctrl_spin.set_adjustment(spin_adj)
55
+    ffwd_rev_ctrl_spin.set_numeric(True)
56
+    
57
+    if hasattr(prefs, 'ffwd_rev_caps'):
58
+        spin_adj = Gtk.Adjustment(prefs.ffwd_rev_caps, 1, 10, 1)
59
+    else:
60
+        spin_adj = Gtk.Adjustment(1, 1, 10, 1)
61
+    ffwd_rev_caps_spin = Gtk.SpinButton()
62
+    ffwd_rev_caps_spin.set_adjustment(spin_adj)
63
+    ffwd_rev_caps_spin.set_numeric(True)
64
+    
65
     # Layout
66
     row1 = _row(guiutils.get_checkbox_row_box(auto_play_in_clip_monitor, Gtk.Label(label=_("Autoplay new Clips in Clip Monitor"))))
67
     row2 = _row(guiutils.get_checkbox_row_box(auto_center_on_stop, Gtk.Label(label=_("Center Current Frame on Playback Stop"))))
68
@@ -221,6 +253,17 @@
69
     row10 = _row(guiutils.get_checkbox_row_box(play_pause_button, Gtk.Label(label=_("Enable single Play/Pause button"))))
70
     row11 = _row(guiutils.get_two_column_box(Gtk.Label(label=_("Mouse Middle Button Scroll Action")), mouse_scroll_action, PREFERENCES_LEFT))
71
     row12 = _row(guiutils.get_checkbox_row_box(hide_file_ext_button, Gtk.Label(label=_("Hide file extensions when importing Clips"))))
72
+    # Apr-2017 - SvdB - For Fast Forward / Reverse options
73
+    row14 = _row(guiutils.get_two_column_box(Gtk.Label(label=_("Fast Forward / Reverse Speed for Shift Key:")), ffwd_rev_shift_spin, PREFERENCES_LEFT))
74
+    row14.set_tooltip_text(_("Speed of Forward / Reverse will be multiplied by this value if Shift Key is held (Only using KEYS).\n" \
75
+        "Enabling multiple modifier keys will multiply the set values.\n" \
76
+        "E.g. if Shift is set to " + str(prefs.ffwd_rev_shift) + " and Ctrl to " + str(prefs.ffwd_rev_ctrl) + \
77
+        ", holding Shift + Ctrl will result in up to " + str(prefs.ffwd_rev_shift * prefs.ffwd_rev_ctrl) + "x speed.\n" \
78
+        "(Effective maximum speed depends on underlying software and/or hardware limitations)"))
79
+    row15 = _row(guiutils.get_two_column_box(Gtk.Label(label=_("Fast Forward / Reverse Speed for Control Key:")), ffwd_rev_ctrl_spin, PREFERENCES_LEFT))
80
+    row15.set_tooltip_text(_("Speed of Forward / Reverse will be multiplied by this value if Ctrl Key is held (Only using KEYS)."))
81
+    row16 = _row(guiutils.get_two_column_box(Gtk.Label(label=_("Fast Forward / Reverse Speed for Caps Lock Key:")), ffwd_rev_caps_spin, PREFERENCES_LEFT))
82
+    row16.set_tooltip_text(_("Speed of Forward / Reverse will be multiplied by this value if Caps Lock is set (Only using KEYS)."))
83
     
84
     vbox = Gtk.VBox(False, 2)
85
     vbox.pack_start(row5, False, False, 0)
86
@@ -236,14 +279,20 @@
87
     vbox.pack_start(row10, False, False, 0)
88
     vbox.pack_start(row11, False, False, 0)
89
     vbox.pack_start(row12, False, False, 0)
90
+    # Apr-2017 - SvdB - For ffwd / rev speed
91
+    vbox.pack_start(row14, False, False, 0)
92
+    vbox.pack_start(row15, False, False, 0)
93
+    vbox.pack_start(row16, False, False, 0)
94
     vbox.pack_start(Gtk.Label(), True, True, 0)
95
 
96
     guiutils.set_margins(vbox, 12, 0, 12, 12)
97
 
98
     # Jul-2016 - SvdB - Added play_pause_button
99
+    # Apr-2017 - SvdB - Added ffwd / rev values
100
     return vbox, (auto_play_in_clip_monitor, auto_center_on_stop, gfx_length_spin,
101
                   trim_exit_on_empty, quick_enter_trim, remember_clip_frame, overwrite_clip_drop, cover_delete,
102
-                  play_pause_button, mouse_scroll_action, hide_file_ext_button, auto_center_on_updown)
103
+                  play_pause_button, mouse_scroll_action, hide_file_ext_button, auto_center_on_updown,
104
+                  ffwd_rev_shift_spin, ffwd_rev_ctrl_spin, ffwd_rev_caps_spin)
105
 
106
 def _view_prefs_panel():
107
     prefs = editorpersistance.prefs
108
@@ -295,7 +344,12 @@
109
         window_mode_combo.set_active(0)
110
     else:
111
         window_mode_combo.set_active(1)
112
-        
113
+
114
+    tracks_combo = Gtk.ComboBoxText()
115
+    tracks_combo.append_text(_("Normal - 50px, 25px"))
116
+    tracks_combo.append_text(_("Double for HiDPI - 100px, 50px"))
117
+    tracks_combo.set_active(prefs.double_track_hights)
118
+
119
     # Layout
120
     row00 = _row(guiutils.get_two_column_box(Gtk.Label(label=_("Application window mode:")), window_mode_combo, PREFERENCES_LEFT))
121
     row0 =  _row(guiutils.get_checkbox_row_box(force_english_check, Gtk.Label(label=_("Use English texts on localized OS"))))
122
@@ -304,6 +358,8 @@
123
     row3 =  _row(guiutils.get_two_column_box(Gtk.Label(label=_("Theme request, icons and colors:")), dark_combo, PREFERENCES_LEFT))
124
     row4 =  _row(guiutils.get_two_column_box(Gtk.Label(label=_("Theme detection fail fallback colors:")), theme_combo, PREFERENCES_LEFT))
125
     row5 =  _row(guiutils.get_two_column_box(Gtk.Label(label=_("Default audio levels display:")), audio_levels_combo, PREFERENCES_LEFT))
126
+    row7 =  _row(guiutils.get_two_column_box(Gtk.Label(label=_("Tracks Heights:")), tracks_combo, PREFERENCES_LEFT))
127
+
128
     # Feb-2017 - SvdB - For full file names
129
     row6 =  _row(guiutils.get_checkbox_row_box(show_full_file_names, Gtk.Label(label=_("Show Full File names"))))
130
 
131
@@ -315,6 +371,7 @@
132
     vbox.pack_start(row3, False, False, 0)
133
     vbox.pack_start(row4, False, False, 0)
134
     vbox.pack_start(row5, False, False, 0)
135
+    vbox.pack_start(row7, False, False, 0)
136
     # Feb-2017 - SvdB - For full file names
137
     vbox.pack_start(row6, False, False, 0)
138
     vbox.pack_start(Gtk.Label(), True, True, 0)
139
@@ -323,7 +380,7 @@
140
 
141
     # Feb-2017 - SvdB - Added code for full file names
142
     return vbox, (force_english_check, display_splash_check, buttons_combo, dark_combo, theme_combo, audio_levels_combo, 
143
-                  window_mode_combo, show_full_file_names)
144
+                  window_mode_combo, show_full_file_names, tracks_combo)
145
 
146
 def _performance_panel():
147
     # Jan-2017 - SvdB
148
@@ -334,6 +391,8 @@
149
     # Allow Frame Dropping should help getting real time output on low performance computers.
150
     prefs = editorpersistance.prefs
151
 
152
+    warning_icon = Gtk.Image.new_from_stock(Gtk.STOCK_DIALOG_WARNING, Gtk.IconSize.DIALOG)
153
+    warning_label = Gtk.Label(label=_("Changing these values may cause problems with playback and rendering.\nThe safe values are Render Threads:1, Allow Frame Dropping: No."))
154
     # Widgets
155
     spin_adj = Gtk.Adjustment(prefs.perf_render_threads, 1, multiprocessing.cpu_count(), 1)
156
     perf_render_threads = Gtk.SpinButton()
157
@@ -348,10 +407,13 @@
158
     perf_drop_frames.set_tooltip_text(_("Allow Frame Dropping for real-time rendering, when needed"))
159
 
160
     # Layout
161
+    row0 = _row(guiutils.get_left_justified_box([warning_icon, warning_label]))
162
     row1 = _row(guiutils.get_two_column_box(Gtk.Label(label=_("Render Threads:")), perf_render_threads, PREFERENCES_LEFT))
163
     row2 = _row(guiutils.get_checkbox_row_box(perf_drop_frames, Gtk.Label(label=_("Allow Frame Dropping"))))
164
 
165
     vbox = Gtk.VBox(False, 2)
166
+    vbox.pack_start(row0, False, False, 0)
167
+    vbox.pack_start(guiutils.pad_label(12, 12), False, False, 0)
168
     vbox.pack_start(row1, False, False, 0)
169
     vbox.pack_start(row2, False, False, 0)
170
     vbox.pack_start(Gtk.Label(), True, True, 0)
171
@@ -360,6 +422,44 @@
172
 
173
     return vbox, (perf_render_threads, perf_drop_frames)
174
 
175
+"""
176
+def _shortcuts_panel():
177
+    # Apr-2017 - SvdB
178
+    # Add a panel for keyboard shortcuts
179
+    # Widgets
180
+    shortcuts_combo = guicomponents.get_shorcuts_selector()
181
+    
182
+
183
+    shortcuts_combo = Gtk.ComboBoxText()
184
+    current_pref_index = -1
185
+
186
+    for i in range(0, len(shortcuts.shortcut_files)):
187
+        shortcut_file = shortcuts.shortcut_files[i]
188
+        shortcuts_combo.append_text(shortcuts.shortcut_files_display_names[i])
189
+        if editorpersistance.prefs.shortcuts == shortcut_file:
190
+            current_pref_index = i
191
+    
192
+    # Set current selection active
193
+    if current_pref_index != -1:
194
+        shortcuts_combo.set_active(current_pref_index)
195
+    else:
196
+        # Something is wrong, the pref shortcut file is not preset in the system.
197
+        print "Shortcut file in editprpersistance.pref.shortcuts not found!"
198
+        shortcuts_combo.set_active(0)
199
+
200
+    
201
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/projectaction.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/projectaction.py Changed
201
 
1
@@ -50,6 +50,7 @@
2
 import gui
3
 import guicomponents
4
 import guiutils
5
+import edit
6
 import editevent
7
 import editorstate
8
 from editorstate import current_sequence
9
@@ -63,11 +64,14 @@
10
 import persistance
11
 import projectdata
12
 import projectinfogui
13
+import projectmediaimport
14
 import propertyparse
15
 import proxyediting
16
 import render
17
+import renderconsumer
18
 import rendergui
19
 import sequence
20
+import undo
21
 import updater
22
 import utils
23
 
24
@@ -75,6 +79,12 @@
25
 save_time = None
26
 save_icon_remove_event_id = None
27
 
28
+# Used to get some render confirmations
29
+force_overwrite = False
30
+force_proxy = False
31
+
32
+#_xml_render_player = None
33
+
34
 #--------------------------------------- worker threads
35
 class LoadThread(threading.Thread):
36
     
37
@@ -156,6 +166,9 @@
38
         Gdk.threads_leave()
39
         
40
         Gdk.threads_enter()
41
+        selections = project.get_project_property(appconsts.P_PROP_LAST_RENDER_SELECTIONS)
42
+        if selections != None:
43
+            render.set_saved_gui_selections(selections)
44
         updater.set_info_icon(None)
45
         dialog.destroy()
46
         Gdk.threads_leave()
47
@@ -180,10 +193,11 @@
48
 
49
 class AddMediaFilesThread(threading.Thread):
50
     
51
-    def __init__(self, filenames):
52
+    def __init__(self, filenames, compound_clip_name=None):
53
         threading.Thread.__init__(self)
54
         self.filenames = filenames
55
-
56
+        self.compound_clip_name = compound_clip_name # Compound clips saved in hidden folder need this name displayed to user, not the md5 hash.
57
+                                                     # Underlying reason, XML clip creation overwrites existing profile objects property values, https://github.com/mltframework/mlt/issues/212
58
     def run(self): 
59
         Gdk.threads_enter()
60
         watch = Gdk.Cursor.new(Gdk.CursorType.WATCH)
61
@@ -200,7 +214,7 @@
62
                 duplicates.append(file_name)
63
             else:
64
                 try:
65
-                    PROJECT().add_media_file(new_file)
66
+                    PROJECT().add_media_file(new_file, self.compound_clip_name)
67
                     succes_new_file = new_file
68
                 except projectdata.ProducerNotValidError as err:
69
                     print err.__str__()
70
@@ -212,7 +226,7 @@
71
             gui.editor_window.media_scroll_window.get_vadjustment().set_value(max_val)
72
             Gdk.threads_leave()
73
 
74
-        if succes_new_file != None:
75
+        if succes_new_file != None and self.compound_clip_name == None: # hidden rendered files folder for compound clips is not a last_opened_media_dir
76
             editorpersistance.prefs.last_opened_media_dir = os.path.dirname(succes_new_file)
77
             editorpersistance.save()
78
 
79
@@ -249,7 +263,6 @@
80
         Gdk.threads_leave()
81
 
82
         for key, media_file in PROJECT().media_files.iteritems():
83
-            print media_file.name
84
             if media_file.type == appconsts.VIDEO or media_file.type == appconsts.IMAGE_SEQUENCE:
85
                 Gdk.threads_enter()
86
                 dialog.info.set_text(media_file.name)
87
@@ -299,12 +312,14 @@
88
 
89
 def _not_matching_media_info_callback(dialog, response_id, media_file):
90
     dialog.destroy()
91
-            
92
+    
93
+    match_profile_index = mltprofiles.get_closest_matching_profile_index(media_file.info)
94
+    profile = mltprofiles.get_profile_for_index(match_profile_index)
95
+        
96
     if response_id == Gtk.ResponseType.ACCEPT:
97
         # Save in hidden and open
98
         match_profile_index = mltprofiles.get_closest_matching_profile_index(media_file.info)
99
         profile = mltprofiles.get_profile_for_index(match_profile_index)
100
-
101
         path = utils.get_hidden_user_dir_path() + "/" + PROJECT().name
102
         PROJECT().update_media_lengths_on_load = True
103
         
104
@@ -504,15 +519,19 @@
105
 
106
 def _change_project_profile_callback(dialog, response_id, profile_combo, out_folder, project_name_entry):
107
     if response_id == Gtk.ResponseType.ACCEPT:
108
-        folder = "/" + out_folder.get_uri().lstrip("file:/")
109
-        name = project_name_entry.get_text()
110
+        ou = out_folder.get_filename().decode('utf-8')
111
+        folder = (u"/" + ou.lstrip(u"file:/"))
112
+        name = project_name_entry.get_text().decode('utf-8')
113
         profile = mltprofiles.get_profile_for_index(profile_combo.get_active())
114
-        path = folder + "/" + name
115
+        path = folder + u"/" + name
116
 
117
         PROJECT().update_media_lengths_on_load = True # saved version needs to do this
118
+        old_name = PROJECT().name
119
+        PROJECT().name  = name
120
         
121
         persistance.save_project(PROJECT(), path, profile.description()) #<----- HERE
122
 
123
+        PROJECT().name = old_name
124
         PROJECT().update_media_lengths_on_load = False
125
 
126
         dialog.destroy()
127
@@ -728,10 +747,48 @@
128
     
129
 # ---------------------------------- rendering
130
 def do_rendering():
131
+    if force_overwrite == False:
132
+        render_path = render.get_file_path()
133
+        if os.path.isfile(render_path):
134
+            primary_txt = _("Render target file exists!")
135
+            secondary_txt = _("Confirm overwriting existing file.")
136
+            dialogutils.warning_confirmation(_overwrite_confirm_dialog_callback, primary_txt, secondary_txt, gui.editor_window.window, data=None, is_info=False, use_confirm_text=True)
137
+            return
138
+
139
+    if force_proxy == False:
140
+        if PROJECT().proxy_data.proxy_mode == appconsts.USE_PROXY_MEDIA:
141
+            primary_txt = _("Project is currently using proxy media!")
142
+            secondary_txt = _("Rendering from proxy media will produce worse quality than rendering from original media.\nConvert to using original media in Proxy Manager for best quality.\n\nSelect 'Confirm' to render from proxy media anyway.")
143
+            dialogutils.warning_confirmation(_proxy_confirm_dialog_callback, primary_txt, secondary_txt, gui.editor_window.window, data=None, is_info=False, use_confirm_text=True)
144
+            return
145
+            
146
+    global force_overwrite, force_proxy
147
+    force_overwrite = False
148
+    force_proxy = False
149
+    
150
     success = _write_out_render_item(True)
151
     if success:
152
+        render_selections = render.get_current_gui_selections()
153
+        PROJECT().set_project_property(appconsts.P_PROP_LAST_RENDER_SELECTIONS, render_selections)
154
         batchrendering.launch_single_rendering()
155
 
156
+def _overwrite_confirm_dialog_callback(dialog, response_id):
157
+    dialog.destroy()
158
+    if response_id == Gtk.ResponseType.ACCEPT:
159
+        global force_overwrite
160
+        force_overwrite = True
161
+        do_rendering()
162
+
163
+def _proxy_confirm_dialog_callback(dialog, response_id):
164
+    dialog.destroy()
165
+    if response_id == Gtk.ResponseType.ACCEPT:
166
+        global force_proxy
167
+        force_proxy = True
168
+        do_rendering()
169
+    else:  # This could otherwise stay accepting overwrites until app close
170
+        global force_overwrite
171
+        force_overwrite = False
172
+        
173
 def add_to_render_queue():
174
     _write_out_render_item(False)
175
 
176
@@ -804,7 +861,7 @@
177
     """
178
     User selects a media file to added to current bin.
179
     """
180
-    # User neds to select thumbnail folder when promted to complete action
181
+    # User needs to select thumbnail folder when promted to complete action
182
     if editorpersistance.prefs.thumbnail_folder == None:
183
         if this_call_is_retry == True:
184
             return
185
@@ -821,9 +878,25 @@
186
         return
187
     if len(filenames) == 0:
188
         return
189
-        
190
+    
191
+    # We're disallowing opening .mlt or .xml files as media beause MLTs behaviour of overwriten project profile properties
192
+    # when opening MLT XML files as nedia
193
+    # Underlying reason: https://github.com/mltframework/mlt/issues/212
194
+    mlt_files_deleted = False
195
+    for i in range(len(filenames) - 1, -1, -1):
196
+        file_path = filenames[i]
197
+        if utils.is_mlt_xml_file(file_path) == True:
198
+            filenames.pop(i)
199
+            mlt_files_deleted = True
200
+    
201
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/projectdata.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/projectdata.py Changed
64
 
1
@@ -61,6 +61,13 @@
2
 
3
 thumbnailer = None
4
 
5
+_project_properties_default_values = {appconsts.P_PROP_TLINE_SHRINK_VERTICAL:False,
6
+                                      appconsts.P_PROP_DISSOLVE_GROUP_FADE_IN:-1,
7
+                                      appconsts.P_PROP_DISSOLVE_GROUP_FADE_OUT:-1,
8
+                                      appconsts.P_PROP_ANIM_GROUP_FADE_IN:-1,
9
+                                      appconsts.P_PROP_ANIM_GROUP_FADE_OUT:-1,
10
+                                      appconsts.P_PROP_LAST_RENDER_SELECTIONS: None,
11
+                                      appconsts.P_PROP_TRANSITION_ENCODING: None}
12
 
13
 class Project:
14
     """
15
@@ -86,6 +93,7 @@
16
         self.proxy_data = miscdataobjects.ProjectProxyEditingData()
17
         self.update_media_lengths_on_load = False # old projects < 1.10 had wrong media length data which just was never used.
18
                                                   # 1.10 needed that data for the first time and required recreating it correctly for older projects
19
+        self.project_properties = {} # Key value pair for misc persistent properties, dict is used that we can add thesse without worrying loading
20
 
21
         self.SAVEFILE_VERSION = SAVEFILE_VERSION
22
         
23
@@ -109,7 +117,7 @@
24
         media_object.length = length
25
         media_object.name = name
26
 
27
-    def add_media_file(self, file_path):
28
+    def add_media_file(self, file_path, compound_clip_name=None):
29
         """
30
         Adds media file to project if exists and file is of right type.
31
         """
32
@@ -131,6 +139,11 @@
33
         clip_name = file_name
34
         if editorpersistance.prefs.hide_file_ext == True:
35
             clip_name = name
36
+        
37
+        # Media objects from compound clips need this to display to users instead of md5 hash.
38
+        # Underlying reason, XML clip creation overwrites existing profile objects property values, https://github.com/mltframework/mlt/issues/212
39
+        if compound_clip_name != None:
40
+            clip_name = compound_clip_name
41
 
42
         # Create media file object
43
         media_object = MediaFile(self.next_media_file_id, file_path, 
44
@@ -277,7 +290,19 @@
45
         
46
         return True
47
 
48
+    def get_project_property(self, property_name):
49
+        try:
50
+            return self.project_properties[property_name]
51
+        except:
52
+            try:
53
+                return _project_properties_default_values[property_name]
54
+            except:
55
+                return None # No default values for all properties exist, action value decided at callsite in that case
56
+
57
+    def set_project_property(self, key, value):
58
+        self.project_properties[key] = value
59
 
60
+            
61
 class MediaFile:
62
     """
63
     Media file that can added to and edited in Sequence.
64
flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/projectmediaimport.py Added
201
 
1
@@ -0,0 +1,230 @@
2
+"""
3
+    Flowblade Movie Editor is a nonlinear video editor.
4
+    Copyright 2012 Janne Liljeblad.
5
+
6
+    This file is part of Flowblade Movie Editor <http://code.google.com/p/flowblade>.
7
+
8
+    Flowblade Movie Editor is free software: you can redistribute it and/or modify
9
+    it under the terms of the GNU General Public License as published by
10
+    the Free Software Foundation, either version 3 of the License, or
11
+    (at your option) any later version.
12
+
13
+    Flowblade Movie Editor is distributed in the hope that it will be useful,
14
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+    GNU General Public License for more details.
17
+
18
+    You should have received a copy of the GNU General Public License
19
+    along with Flowblade Movie Editor.  If not, see <http://www.gnu.org/licenses/>.
20
+"""
21
+
22
+import mlt
23
+import locale
24
+import os
25
+import subprocess
26
+import sys
27
+import threading
28
+
29
+import gi
30
+gi.require_version('Gtk', '3.0')
31
+gi.require_version('PangoCairo', '1.0')
32
+from gi.repository import Gtk, Gdk, GdkPixbuf
33
+from gi.repository import GLib
34
+from gi.repository import Pango, GObject
35
+
36
+import dialogutils
37
+import editorstate
38
+import editorpersistance
39
+import guiutils
40
+import mltenv
41
+import mltprofiles
42
+import mlttransitions
43
+import mltfilters
44
+import patternproducer
45
+import persistance
46
+import respaths
47
+import renderconsumer
48
+import translations
49
+import utils
50
+
51
+"""
52
+This module implements media import from another project feature.
53
+
54
+The easiest way to do it is to open file in own process and write media paths to disk.
55
+There is so much bolierplate needed for this feature that it was best to create own module for it.
56
+"""
57
+
58
+MEDIA_ASSETS_IMPORT_FILE = "media_assets_import_file"
59
+
60
+_info_window = None
61
+_media_paths_written_to_disk_complete_callback = None
62
+
63
+class ProjectLoadThread(threading.Thread):
64
+    def __init__(self, filename):
65
+        threading.Thread.__init__(self)
66
+        self.filename = filename
67
+
68
+    def run(self):
69
+        Gdk.threads_enter()
70
+        _info_window.info.set_text("Loading project " + self.filename + "...")
71
+        Gdk.threads_leave()
72
+
73
+        persistance.show_messages = False
74
+        target_project = persistance.load_project(self.filename, False, True)
75
+        
76
+        target_project.c_seq = target_project.sequences[target_project.c_seq_index]
77
+
78
+        # Media file media assets
79
+        media_assets = ""
80
+        for media_file_id, media_file in target_project.media_files.iteritems():
81
+            if isinstance(media_file, patternproducer.AbstractBinClip):
82
+                continue
83
+            if os.path.isfile(media_file.path):                
84
+                media_assets = media_assets + str(media_file.path) + "\n"
85
+        
86
+        f = open(_get_assets_file(), 'w')
87
+        f.write(media_assets)
88
+        f.close()
89
+
90
+        _shutdown()
91
+
92
+
93
+class ProcesslauchThread(threading.Thread):
94
+    def __init__(self, filename):
95
+        threading.Thread.__init__(self)
96
+        self.filename = filename
97
+
98
+    def run(self):
99
+        write_files(self.filename)
100
+
101
+
102
+# ----------------------------------------------------------- interface
103
+def import_media_files(project_file_path, callback):
104
+    
105
+    global _media_paths_written_to_disk_complete_callback
106
+    _media_paths_written_to_disk_complete_callback = callback
107
+
108
+    # This or GUI freezes, we really can't do Popen.wait() in a Gtk thread
109
+    process_launch_thread = ProcesslauchThread(project_file_path)
110
+    process_launch_thread.start()
111
+
112
+def get_imported_media():
113
+    with open(_get_assets_file()) as f:
114
+        files_list = f.readlines()
115
+
116
+    files_list = [x.rstrip("\n") for x in files_list] 
117
+    return files_list
118
+    
119
+def write_files(filename):
120
+    print "Starting media import..."
121
+    FLOG = open(utils.get_hidden_user_dir_path() + "log_media_import", 'w')
122
+    p = subprocess.Popen([sys.executable, respaths.LAUNCH_DIR + "flowblademediaimport", filename], stdin=FLOG, stdout=FLOG, stderr=FLOG)
123
+    p.wait()
124
+    
125
+    GLib.idle_add(assets_write_complete)
126
+
127
+def assets_write_complete():
128
+    _media_paths_written_to_disk_complete_callback()
129
+
130
+
131
+# ------------------------------------------------------------ module internal
132
+def _do_assets_write(filename):
133
+    _create_info_dialog()
134
+    
135
+    global load_thread
136
+    load_thread = ProjectLoadThread(filename)
137
+    load_thread.start()
138
+        
139
+def _get_assets_file():
140
+    return utils.get_hidden_user_dir_path() + MEDIA_ASSETS_IMPORT_FILE
141
+
142
+def _create_info_dialog():
143
+    dialog = Gtk.Window(Gtk.WindowType.TOPLEVEL)
144
+    dialog.set_title(_("Loading Media Import Project"))
145
+
146
+    info_label = Gtk.Label(label="")
147
+    status_box = Gtk.HBox(False, 2)
148
+    status_box.pack_start(info_label, False, False, 0)
149
+    status_box.pack_start(Gtk.Label(), True, True, 0)
150
+
151
+    progress_bar = Gtk.ProgressBar()
152
+    progress_bar.set_fraction(0.2)
153
+    progress_bar.set_pulse_step(0.1)
154
+
155
+    est_box = Gtk.HBox(False, 2)
156
+    est_box.pack_start(Gtk.Label(label=""),False, False, 0)
157
+    est_box.pack_start(Gtk.Label(), True, True, 0)
158
+
159
+    progress_vbox = Gtk.VBox(False, 2)
160
+    progress_vbox.pack_start(status_box, False, False, 0)
161
+    progress_vbox.pack_start(progress_bar, True, True, 0)
162
+    progress_vbox.pack_start(est_box, False, False, 0)
163
+
164
+    alignment = guiutils.set_margins(progress_vbox, 12, 12, 12, 12)
165
+
166
+    dialog.add(alignment)
167
+    dialog.set_default_size(400, 70)
168
+    dialog.set_position(Gtk.WindowPosition.CENTER)
169
+    dialog.show_all()
170
+
171
+    # Make refs available for updates
172
+    dialog.progress_bar = progress_bar
173
+    dialog.info = info_label
174
+
175
+    global _info_window
176
+    _info_window = dialog
177
+
178
+
179
+# ----------------------------------------------------------- main
180
+def main(root_path, filename):
181
+    # This the main for launched process, this is reached via 'flowblademediaimport' laucher file
182
+    gtk_version = "%s.%s.%s" % (Gtk.get_major_version(), Gtk.get_minor_version(), Gtk.get_micro_version())
183
+    print "GTK+ version:", gtk_version
184
+    editorstate.gtk_version = gtk_version
185
+    try:
186
+        editorstate.mlt_version = mlt.LIBMLT_VERSION
187
+    except:
188
+        editorstate.mlt_version = "0.0.99" # magic string for "not found"
189
+
190
+    # Set paths.
191
+    respaths.set_paths(root_path)
192
+
193
+    # Load editor prefs and list of recent projects
194
+    editorpersistance.load()
195
+    
196
+    # Init translations module with translations data
197
+    translations.init_languages()
198
+    translations.load_filters_translations()
199
+    mlttransitions.init_module()
200
+
201
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/propertyeditorbuilder.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/propertyeditorbuilder.py Changed
147
 
1
@@ -22,7 +22,7 @@
2
 Module creates GUI editors for editable mlt properties.
3
 """
4
 
5
-from gi.repository import Gtk, Gdk
6
+from gi.repository import Gtk, Gdk, GObject
7
 
8
 import appconsts
9
 from editorstate import PROJECT
10
@@ -33,7 +33,9 @@
11
 import keyframeeditor
12
 import mltfilters
13
 import mlttransitions
14
+import propertyparse
15
 import translations
16
+import updater
17
 import utils
18
 
19
 EDITOR = "editor"
20
@@ -59,6 +61,7 @@
21
 COLOR_LGG = "colorlgg"                                      # Editor for ColorLGG filter
22
 FILE_SELECTOR = "file_select"                               # File selector button for selecting single files from
23
 FILE_TYPES = "file_types"                                   # list of files types with "." chracters, like ".png.tga.bmp"
24
+FADE_LENGTH = "fade_length"                                 # Autofade composiyots fade length
25
 NO_EDITOR = "no_editor"                                     # No editor displayed for property
26
 
27
 COMPOSITE_EDITOR_BUILDER = "composite_properties"           # Creates a single row editor for multiple properties of composite transition
28
@@ -106,7 +109,6 @@
29
     """
30
     Returns list of extraeditors GUI components.
31
     """
32
-    #print editable_properties
33
     extra_editors = filt.info.extra_editors
34
     rows = []
35
     for editor_name in extra_editors:
36
@@ -443,6 +445,49 @@
37
     
38
     return editor_pane
39
 
40
+class FadeLengthEditor(Gtk.HBox):
41
+    def __init__(self, editable_property):
42
+
43
+        GObject.GObject.__init__(self)
44
+        self.set_homogeneous(False)
45
+        self.set_spacing(2)
46
+        
47
+        self.editable_property = editable_property
48
+        length = self.editable_property.clip.clip_out - self.editable_property.clip.clip_in + 1
49
+        
50
+        name = editable_property.get_display_name()
51
+        name = _p(name)
52
+        name_label = Gtk.Label(label=name + ":")
53
+        
54
+        label_box = Gtk.HBox()
55
+        label_box.pack_start(name_label, False, False, 0)
56
+        label_box.pack_start(Gtk.Label(), True, True, 0)
57
+        label_box.set_size_request(appconsts.PROPERTY_NAME_WIDTH, appconsts.PROPERTY_ROW_HEIGHT)
58
+           
59
+        self.spin = Gtk.SpinButton.new_with_range (1, 1000, 1)
60
+        self.spin.set_numeric(True)
61
+        self.spin.set_value(length)
62
+        self.spin.connect("value-changed", self.spin_value_changed)
63
+
64
+        self.pack_start(guiutils.pad_label(4,4), False, False, 0)
65
+        self.pack_start(label_box, False, False, 0)
66
+        self.pack_start(self.spin, False, False, 0)
67
+        self.pack_start(Gtk.Label(), True, True, 0)
68
+        
69
+    def spin_value_changed(self, spin):
70
+        if self.editable_property.clip.transition.info.name == "##auto_fade_in":
71
+            self.editable_property.clip.set_length_from_in(int(spin.get_value()))
72
+        else:
73
+            self.editable_property.clip.set_length_from_out(int(spin.get_value()))
74
+
75
+        updater.repaint_tline()
76
+    
77
+    def display_tline_frame(self, frame):
78
+        pass # we don't seem to need this afte all, panel gets recreated after cpompositor length change
79
+        
80
+def _get_fade_length_editor(editable_property):
81
+    return FadeLengthEditor(editable_property)
82
+
83
 def _wipe_preset_combo_changed(widget, ep, widgets):
84
     combo_box, use_preset_luma_combo, user_luma_select, user_luma_label, keys = widgets
85
     if widget.get_active() == 1:
86
@@ -547,49 +592,9 @@
87
         deinterlace.write_value("1")
88
         progressive.write_value("1")
89
 
90
-def _create_rotion_geometry_editor(clip, editable_properties):
91
-    # Build a custom object that duck types for TransitionEditableProperty to use in editor
92
-    ep = utils.EmptyClass()
93
-    # pack real properties to go
94
-    ep.x = filter(lambda ep: ep.name == "x", editable_properties)[0]
95
-    ep.y = filter(lambda ep: ep.name == "y", editable_properties)[0]
96
-    ep.x_scale = filter(lambda ep: ep.name == "x scale", editable_properties)[0]
97
-    ep.y_scale = filter(lambda ep: ep.name == "y scale", editable_properties)[0]
98
-    ep.rotation = filter(lambda ep: ep.name == "rotation", editable_properties)[0]
99
-    ep.opacity = filter(lambda ep: ep.name == "opacity", editable_properties)[0]
100
-    # Screen width and height are needeed for frei0r conversions
101
-    ep.profile_width = current_sequence().profile.width()
102
-    ep.profile_height = current_sequence().profile.height()
103
-    # duck type methods, using opacity is not meaningful, any property with clip member could do
104
-    ep.get_clip_tline_pos = lambda : ep.opacity.clip.clip_in # clip is compositor, compositor in and out points staright in timeline frames
105
-    ep.get_clip_length = lambda : ep.opacity.clip.clip_out - ep.opacity.clip.clip_in + 1
106
-    ep.get_input_range_adjustment = lambda : Gtk.Adjustment(float(100), float(0), float(100), float(1))
107
-    ep.get_display_name = lambda : "Opacity"
108
-    ep.get_pixel_aspect_ratio = lambda : (float(current_sequence().profile.sample_aspect_num()) / current_sequence().profile.sample_aspect_den())
109
-    ep.get_in_value = lambda out_value : out_value # hard coded for opacity 100 -> 100 range
110
-    ep.write_out_keyframes = lambda w_kf : keyframeeditor.rotating_ge_write_out_keyframes(ep, w_kf)
111
-    # duck type members
112
-    x_tokens = ep.x.value.split(";")
113
-    y_tokens = ep.y.value.split(";")
114
-    x_scale_tokens = ep.x_scale.value.split(";")
115
-    y_scale_tokens = ep.y_scale.value.split(";")
116
-    rotation_tokens = ep.rotation.value.split(";")
117
-    opacity_tokens = ep.opacity.value.split(";")
118
-    
119
-    value = ""
120
-    for i in range(0, len(x_tokens)): # these better match, same number of keyframes for all values, or this will not work
121
-        frame, x = x_tokens[i].split("=")
122
-        frame, y = y_tokens[i].split("=")
123
-        frame, x_scale = x_scale_tokens[i].split("=")
124
-        frame, y_scale = y_scale_tokens[i].split("=")
125
-        frame, rotation = rotation_tokens[i].split("=")
126
-        frame, opacity = opacity_tokens[i].split("=")
127
-        
128
-        frame_str = str(frame) + "=" + str(x) + ":" + str(y) + ":" + str(x_scale) + ":" + str(y_scale) + ":" + str(rotation) + ":" + str(opacity)
129
-        value += frame_str + ";"
130
-
131
-    ep.value = value.strip(";")
132
-
133
+def _create_rotion_geometry_editor(clip, editable_properties):   
134
+    ep = propertyparse.create_editable_property_for_affine_blend(clip, editable_properties)
135
+    
136
     kf_edit = keyframeeditor.RotatingGeometryEditor(ep, False)
137
     return kf_edit
138
 
139
@@ -767,6 +772,7 @@
140
     LADSPA_SLIDER: lambda ep: _get_ladspa_slider_row(ep),
141
     CLIP_FRAME_SLIDER: lambda ep: _get_clip_frame_slider(ep),
142
     FILE_SELECTOR: lambda ep: _get_file_select_editor(ep),
143
+    FADE_LENGTH: lambda ep: _get_fade_length_editor(ep),
144
     NO_EDITOR: lambda ep: _get_no_editor(),
145
     COMPOSITE_EDITOR_BUILDER: lambda comp, editable_properties: _create_composite_editor(comp, editable_properties),
146
     REGION_EDITOR_BUILDER: lambda comp, editable_properties: _create_region_editor(comp, editable_properties),
147
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/propertyparse.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/propertyparse.py Changed
98
 
1
@@ -23,10 +23,12 @@
2
 - parses strings to property tuples or argument dicts
3
 - build value strings from property tuples.
4
 """
5
+from gi.repository import Gtk
6
 
7
 import appconsts
8
 from editorstate import current_sequence
9
 import respaths
10
+import utils
11
 
12
 PROP_INT = appconsts.PROP_INT
13
 PROP_FLOAT = appconsts.PROP_FLOAT
14
@@ -196,6 +198,83 @@
15
 
16
     return new_keyframes
17
 
18
+def create_editable_property_for_affine_blend(clip, editable_properties):
19
+    # Build a custom object that duck types for TransitionEditableProperty to use in editor
20
+    ep = utils.EmptyClass()
21
+    # pack real properties to go
22
+    ep.x = filter(lambda ep: ep.name == "x", editable_properties)[0]
23
+    ep.y = filter(lambda ep: ep.name == "y", editable_properties)[0]
24
+    ep.x_scale = filter(lambda ep: ep.name == "x scale", editable_properties)[0]
25
+    ep.y_scale = filter(lambda ep: ep.name == "y scale", editable_properties)[0]
26
+    ep.rotation = filter(lambda ep: ep.name == "rotation", editable_properties)[0]
27
+    ep.opacity = filter(lambda ep: ep.name == "opacity", editable_properties)[0]
28
+    # Screen width and height are needeed for frei0r conversions
29
+    ep.profile_width = current_sequence().profile.width()
30
+    ep.profile_height = current_sequence().profile.height()
31
+    # duck type methods, using opacity is not meaningful, any property with clip member could do
32
+    ep.get_clip_tline_pos = lambda : ep.opacity.clip.clip_in # clip is compositor, compositor in and out points straight in timeline frames
33
+    ep.get_clip_length = lambda : ep.opacity.clip.clip_out - ep.opacity.clip.clip_in + 1
34
+    ep.get_input_range_adjustment = lambda : Gtk.Adjustment(float(100), float(0), float(100), float(1))
35
+    ep.get_display_name = lambda : "Opacity"
36
+    ep.get_pixel_aspect_ratio = lambda : (float(current_sequence().profile.sample_aspect_num()) / current_sequence().profile.sample_aspect_den())
37
+    ep.get_in_value = lambda out_value : out_value # hard coded for opacity 100 -> 100 range
38
+    ep.write_out_keyframes = lambda w_kf : rotating_ge_write_out_keyframes(ep, w_kf)
39
+    # duck type members
40
+    x_tokens = ep.x.value.split(";")
41
+    y_tokens = ep.y.value.split(";")
42
+    x_scale_tokens = ep.x_scale.value.split(";")
43
+    y_scale_tokens = ep.y_scale.value.split(";")
44
+    rotation_tokens = ep.rotation.value.split(";")
45
+    opacity_tokens = ep.opacity.value.split(";")
46
+    
47
+    value = ""
48
+    for i in range(0, len(x_tokens)): # these better match, same number of keyframes for all values, or this will not work
49
+        frame, x = x_tokens[i].split("=")
50
+        frame, y = y_tokens[i].split("=")
51
+        frame, x_scale = x_scale_tokens[i].split("=")
52
+        frame, y_scale = y_scale_tokens[i].split("=")
53
+        frame, rotation = rotation_tokens[i].split("=")
54
+        frame, opacity = opacity_tokens[i].split("=")
55
+        
56
+        frame_str = str(frame) + "=" + str(x) + ":" + str(y) + ":" + str(x_scale) + ":" + str(y_scale) + ":" + str(rotation) + ":" + str(opacity)
57
+        value += frame_str + ";"
58
+
59
+    ep.value = value.strip(";")
60
+    
61
+    return ep
62
+
63
+def rotating_ge_write_out_keyframes(ep, keyframes):
64
+    x_val = ""
65
+    y_val = ""
66
+    x_scale_val = ""
67
+    y_scale_val = ""
68
+    rotation_val = ""
69
+    opacity_val = ""
70
+    
71
+    for kf in keyframes:
72
+        frame, transf, opacity = kf
73
+        x, y, x_scale, y_scale, rotation = transf
74
+        x_val += str(frame) + "=" + str(get_frei0r_cairo_position(x, ep.profile_width)) + ";"
75
+        y_val += str(frame) + "=" + str(get_frei0r_cairo_position(y, ep.profile_height)) + ";"
76
+        x_scale_val += str(frame) + "=" + str(get_frei0r_cairo_scale(x_scale)) + ";"
77
+        y_scale_val += str(frame) + "=" + str(get_frei0r_cairo_scale(y_scale)) + ";"
78
+        rotation_val += str(frame) + "=" + str(rotation / 360.0) + ";"
79
+        opacity_val += str(frame) + "=" + str(opacity / 100.0) + ";"
80
+
81
+    x_val = x_val.strip(";")
82
+    y_val = y_val.strip(";")
83
+    x_scale_val = x_scale_val.strip(";")
84
+    y_scale_val = y_scale_val.strip(";")
85
+    rotation_val = rotation_val.strip(";")
86
+    opacity_val = opacity_val.strip(";")
87
+   
88
+    ep.x.write_value(x_val)
89
+    ep.y.write_value(y_val)
90
+    ep.x_scale.write_value(x_scale_val)
91
+    ep.y_scale.write_value(y_scale_val)
92
+    ep.rotation.write_value(rotation_val)
93
+    ep.opacity.write_value(opacity_val)
94
+    
95
 def _get_pixel_pos_from_frei0r_cairo_pos(value, screen_dim):
96
     # convert positions from range used by frei0r cairo plugins to pixel values
97
     return -2.0 * screen_dim + value * 5.0 * screen_dim
98
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/proxyediting.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/proxyediting.py Changed
89
 
1
@@ -38,6 +38,7 @@
2
 import guiutils
3
 import mltrefhold
4
 import persistance
5
+import render
6
 import renderconsumer
7
 import sequence
8
 import utils
9
@@ -87,11 +88,12 @@
10
             # Create render objects
11
             proxy_file_path = media_file.create_proxy_path(proxy_w, proxy_h, proxy_encoding.extension)
12
             self.current_render_file_path = proxy_file_path
13
+            renderconsumer.performance_settings_enabled = False
14
             consumer = renderconsumer.get_render_consumer_for_encoding(
15
                                                         proxy_file_path,
16
                                                         self.proxy_profile, 
17
                                                         proxy_encoding)
18
-
19
+            renderconsumer.performance_settings_enabled = True
20
             # Bit rates for proxy files are counted using 2500kbs for 
21
             # PAL size image as starting point.
22
             pal_pix_count = 720.0 * 576.0
23
@@ -676,10 +678,13 @@
24
     editorstate.PROJECT().proxy_data.proxy_mode = appconsts.CONVERTING_TO_USE_PROXY_MEDIA
25
     conv_temp_project_path = utils.get_hidden_user_dir_path() + "proxy_conv.flb"
26
     manager_window.convert_progress_bar.set_text(_("Converting Project to Use Proxy Media"))
27
-
28
+    
29
+    mark_in = editorstate.PROJECT().c_seq.tractor.mark_in
30
+    mark_out = editorstate.PROJECT().c_seq.tractor.mark_out
31
+    
32
     persistance.save_project(editorstate.PROJECT(), conv_temp_project_path)
33
     global load_thread
34
-    load_thread = ProxyProjectLoadThread(conv_temp_project_path, manager_window.convert_progress_bar)
35
+    load_thread = ProxyProjectLoadThread(conv_temp_project_path, manager_window.convert_progress_bar, mark_in, mark_out)
36
     load_thread.start()
37
 
38
 def _convert_to_original_media_project():
39
@@ -687,9 +692,12 @@
40
     conv_temp_project_path = utils.get_hidden_user_dir_path() + "proxy_conv.flb"
41
     manager_window.convert_progress_bar.set_text(_("Converting to Use Original Media"))
42
 
43
+    mark_in = editorstate.PROJECT().c_seq.tractor.mark_in
44
+    mark_out = editorstate.PROJECT().c_seq.tractor.mark_out
45
+    
46
     persistance.save_project(editorstate.PROJECT(), conv_temp_project_path)
47
     global load_thread
48
-    load_thread = ProxyProjectLoadThread(conv_temp_project_path, manager_window.convert_progress_bar)
49
+    load_thread = ProxyProjectLoadThread(conv_temp_project_path, manager_window.convert_progress_bar, mark_in, mark_out)
50
     load_thread.start()
51
 
52
 def _auto_re_convert_after_proxy_render_in_proxy_mode():
53
@@ -743,11 +751,13 @@
54
 
55
 class ProxyProjectLoadThread(threading.Thread):
56
 
57
-    def __init__(self, proxy_project_path, progressbar):
58
+    def __init__(self, proxy_project_path, progressbar, mark_in, mark_out):
59
         threading.Thread.__init__(self)
60
         self.proxy_project_path = proxy_project_path
61
         self.progressbar = progressbar
62
-
63
+        self.mark_in = mark_in
64
+        self.mark_out = mark_out
65
+    
66
     def run(self):
67
         pulse_runner = guiutils.PulseThread(self.progressbar)
68
         pulse_runner.start()
69
@@ -764,6 +774,9 @@
70
         pulse_runner.running = False
71
         time.sleep(0.3) # need to be sure pulse_runner has stopped
72
         
73
+        project.c_seq.tractor.mark_in = self.mark_in
74
+        project.c_seq.tractor.mark_out = self.mark_out
75
+    
76
         app.stop_autosave()
77
 
78
         Gdk.threads_enter()
79
@@ -783,6 +796,9 @@
80
         persistance.show_messages = True
81
 
82
         Gdk.threads_enter()
83
+        selections = project.get_project_property(appconsts.P_PROP_LAST_RENDER_SELECTIONS)
84
+        if selections != None:
85
+            render.set_saved_gui_selections(selections)
86
         _converting_proxy_mode_done()
87
         Gdk.threads_leave()
88
 
89
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/render.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/render.py Changed
160
 
1
@@ -26,7 +26,6 @@
2
 """
3
 
4
 
5
-
6
 from gi.repository import Gtk
7
 
8
 import mlt
9
@@ -99,8 +98,6 @@
10
         PLAYER().set_render_callbacks(callbacks)
11
         PLAYER().start_rendering(self.render_consumer, self.start_frame, self.end_frame)
12
 
13
-
14
-
15
 def get_args_vals_list_for_current_selections():
16
     profile = get_current_profile()
17
     encoding_option_index = widgets.encoding_panel.encoding_selector.widget.get_active()
18
@@ -129,6 +126,26 @@
19
     
20
     return args_vals_list
21
 
22
+def get_current_gui_selections():
23
+    selections = {}
24
+    selections["use_user_encodings"] = widgets.render_type_panel.type_combo.get_active()
25
+    selections["encoding_option_index"] = widgets.encoding_panel.encoding_selector.widget.get_active()
26
+    selections["quality_option_index"]= widgets.encoding_panel.quality_selector.widget.get_active()
27
+    selections["presets_index"] = widgets.render_type_panel.presets_selector.widget.get_active()
28
+    selections["folder"] = widgets.file_panel.out_folder.get_current_folder()
29
+    selections["name"] = widgets.file_panel.movie_name.get_text()
30
+    selections["range"] = widgets.range_cb.get_active()
31
+    return selections
32
+
33
+def set_saved_gui_selections(selections):
34
+    widgets.render_type_panel.type_combo.set_active(selections["use_user_encodings"])
35
+    widgets.encoding_panel.encoding_selector.widget.set_active(selections["encoding_option_index"])
36
+    widgets.encoding_panel.quality_selector.widget.set_active(selections["quality_option_index"])
37
+    widgets.render_type_panel.presets_selector.widget.set_active(selections["presets_index"])
38
+    widgets.file_panel.out_folder.set_current_folder(selections["folder"])
39
+    widgets.file_panel.movie_name.set_text(selections["name"])
40
+    widgets.range_cb.set_active(selections["range"])
41
+    
42
 def get_file_path():
43
     folder = widgets.file_panel.out_folder.get_filenames()[0]        
44
     filename = widgets.file_panel.movie_name.get_text()
45
@@ -413,8 +430,8 @@
46
         wait_for_producer_stop = True
47
         if range_selection == 1:
48
             start_frame = int(float(media_file.mark_in) * (1.0 / speed))
49
-            end_frame = int(float(media_file.mark_out + 1) * (1.0 / speed)) + int(1.0 / speed) #+ 40 # I'm unable to get this frame perfect.
50
-                                                                                                    # +40 is to make sure rendering stops after mark out.
51
+            end_frame = int(float(media_file.mark_out + 1) * (1.0 / speed)) + int(1.0 / speed)
52
+            
53
             if end_frame > motion_producer.get_length() - 1:
54
                 end_frame = motion_producer.get_length() - 1
55
             
56
@@ -449,6 +466,103 @@
57
 
58
     dialogutils.delay_destroy_window(dialog, 1.6)
59
 
60
+def render_reverse_clip(media_file, default_range_render=False):
61
+    rendergui.show_reverse_dialog(media_file, default_range_render, _render_reverse_clip_dialog_callback)
62
+
63
+def _render_reverse_clip_dialog_callback(dialog, response_id, fb_widgets, media_file):
64
+    if response_id == Gtk.ResponseType.ACCEPT:
65
+        # speed, filename folder
66
+        speed = float(int(fb_widgets.hslider.get_value())) / 100.0
67
+        file_name = fb_widgets.file_name.get_text()
68
+        filenames = fb_widgets.out_folder.get_filenames()
69
+        folder = filenames[0]
70
+        write_file = folder + "/"+ file_name + fb_widgets.extension_label.get_text()
71
+
72
+        if os.path.exists(write_file):
73
+            primary_txt = _("A File with given path exists!")
74
+            secondary_txt = _("It is not allowed to render Motion Files with same paths as existing files.\nSelect another name for file.") 
75
+            dialogutils.warning_message(primary_txt, secondary_txt, dialog)
76
+            return
77
+
78
+         # Profile
79
+        profile_index = fb_widgets.out_profile_combo.get_active()
80
+        if profile_index == 0:
81
+            # project_profile is first selection in combo box
82
+            profile = PROJECT().profile
83
+        else:
84
+            profile = mltprofiles.get_profile_for_index(profile_index - 1)
85
+
86
+        # Render consumer properties
87
+        encoding_option_index = fb_widgets.encodings_cb.get_active()
88
+        quality_option_index = fb_widgets.quality_cb.get_active()
89
+
90
+        # Range
91
+        range_selection = fb_widgets.render_range.get_active()
92
+        
93
+        dialog.destroy()
94
+
95
+        # Create motion producer
96
+        source_path = media_file.path
97
+        if media_file.is_proxy_file == True:
98
+            source_path = media_file.second_file_path
99
+
100
+        motion_producer = mlt.Producer(profile, None, str("timewarp:" + str(speed) + ":" + str(source_path)))
101
+        mltrefhold.hold_ref(motion_producer)
102
+        
103
+        # Create sequence and add motion producer into it
104
+        seq = sequence.Sequence(profile)
105
+        seq.create_default_tracks()
106
+        track = seq.tracks[seq.first_video_index]
107
+        track.append(motion_producer, 0, motion_producer.get_length() - 1)
108
+
109
+        print "motion clip render starting..."
110
+
111
+        consumer = renderconsumer.get_render_consumer_for_encoding_and_quality(write_file, profile, encoding_option_index, quality_option_index)
112
+        
113
+        # start and end frames
114
+        start_frame = 0
115
+        end_frame = motion_producer.get_length() - 1
116
+        wait_for_producer_stop = True
117
+        if range_selection == 1:
118
+            start_frame = int(float(media_file.length - media_file.mark_out - 1) * (1.0 / -speed))
119
+            end_frame = int(float(media_file.length - media_file.mark_out + (media_file.mark_out - media_file.mark_in) + 1) * (1.0 / -speed)) + int(1.0 / -speed)
120
+
121
+            if end_frame > motion_producer.get_length() - 1:
122
+                end_frame = motion_producer.get_length() - 1
123
+            if start_frame < 0:
124
+                start_frame = 0
125
+            
126
+            wait_for_producer_stop = False # consumer wont stop automatically and needs to stopped explicitly
127
+
128
+        # Launch render
129
+        global motion_renderer, motion_progress_update
130
+        motion_renderer = renderconsumer.FileRenderPlayer(write_file, seq.tractor, consumer, start_frame, end_frame)
131
+        motion_renderer.wait_for_producer_end_stop = wait_for_producer_stop
132
+        motion_renderer.start()
133
+
134
+        title = _("Rendering Reverse Clip")
135
+        text = _("<b>Motion Clip File: </b>") + write_file
136
+        progress_bar = Gtk.ProgressBar()
137
+        dialog = rendergui.clip_render_progress_dialog(_FB_render_stop, title, text, progress_bar, gui.editor_window.window)
138
+
139
+        motion_progress_update = renderconsumer.ProgressWindowThread(dialog, progress_bar, motion_renderer, _REVERSE_render_stop)
140
+        motion_progress_update.start()
141
+
142
+    else:
143
+        dialog.destroy()
144
+
145
+def _REVERSE_render_stop(dialog, response_id):
146
+    print "reverse clip render done"
147
+
148
+    global motion_renderer, motion_progress_update
149
+    motion_renderer.running = False
150
+    motion_progress_update.running = False
151
+    open_media_file_callback(motion_renderer.file_name)
152
+    motion_renderer.running = None
153
+    motion_progress_update.running = None
154
+
155
+    dialogutils.delay_destroy_window(dialog, 1.6)
156
+    
157
 # ----------------------------------------------------------------------- single track transition render 
158
 def render_single_track_transition_clip(transition_producer, encoding_option_index, quality_option_index, file_ext, transition_render_complete_cb, window_text):
159
     # Set render complete callback to availble render stop callback using global variable
160
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/renderconsumer.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/renderconsumer.py Changed
112
 
1
@@ -76,6 +76,9 @@
2
 non_user_encodings = []
3
 proxy_encodings = None
4
 
5
+# This is used to turn performance settings off for proxy rendering
6
+performance_settings_enabled = True
7
+
8
 # replace empty strings with None values
9
 def _get_attribute(node, attr_name):
10
     value = node.getAttribute(attr_name)
11
@@ -272,24 +275,48 @@
12
     
13
     consumer = mlt.Consumer(profile, "avformat", str(render_path))
14
     # Jan-2017 - SvdB - perf_value instead of -1
15
-    if editorpersistance.prefs.perf_drop_frames == True:
16
-        perf_value = 1 * editorpersistance.prefs.perf_render_threads
17
+    if performance_settings_enabled == True:
18
+        if editorpersistance.prefs.perf_drop_frames == True:
19
+            perf_value = 1 * editorpersistance.prefs.perf_render_threads
20
+        else:
21
+            perf_value = -1 * editorpersistance.prefs.perf_render_threads
22
+        consumer.set("real_time", perf_value)
23
     else:
24
-        perf_value = -1 * editorpersistance.prefs.perf_render_threads
25
-    consumer.set("real_time", perf_value)
26
+        consumer.set("real_time", -1)
27
     consumer.set("rescale", "bicubic")
28
     consumer.set("vcodec", str(vcodec))
29
-    #print "img seq render consumer created, path:" +  str(render_path) #+ ", args: " + args_msg
30
+
31
+    return consumer
32
+
33
+def get_img_seq_render_consumer_codec_ext(file_path, profile, vcodec, ext):
34
+    render_path = os.path.dirname(file_path) + "/" + os.path.basename(file_path).split(".")[0] + "_%05d." + ext
35
+    
36
+    consumer = mlt.Consumer(profile, "avformat", str(render_path))
37
+    # Jan-2017 - SvdB - perf_value instead of -1
38
+    if performance_settings_enabled == True:
39
+        if editorpersistance.prefs.perf_drop_frames == True:
40
+            perf_value = 1 * editorpersistance.prefs.perf_render_threads
41
+        else:
42
+            perf_value = -1 * editorpersistance.prefs.perf_render_threads
43
+        consumer.set("real_time", perf_value)
44
+    else:
45
+        consumer.set("real_time", -1)
46
+    consumer.set("rescale", "bicubic")
47
+    consumer.set("vcodec", str(vcodec))
48
+
49
     return consumer
50
     
51
 def get_mlt_render_consumer(file_path, profile, args_vals_list):
52
     consumer = mlt.Consumer(profile, "avformat", str(file_path))
53
     # Jan-2017 - SvdB - perf_value instead of -1
54
-    if editorpersistance.prefs.perf_drop_frames == True:
55
-        perf_value = 1 * editorpersistance.prefs.perf_render_threads
56
+    if performance_settings_enabled == True:
57
+        if editorpersistance.prefs.perf_drop_frames == True:
58
+            perf_value = 1 * editorpersistance.prefs.perf_render_threads
59
+        else:
60
+            perf_value = -1 * editorpersistance.prefs.perf_render_threads
61
+        consumer.set("real_time", perf_value)
62
     else:
63
-        perf_value = -1 * editorpersistance.prefs.perf_render_threads
64
-    consumer.set("real_time", perf_value)
65
+        consumer.set("real_time", -1)
66
     consumer.set("rescale", "bicubic")
67
 
68
     args_msg = ""
69
@@ -503,6 +530,42 @@
70
         self.render_done_callback(self.data)
71
 
72
 
73
+class XMLCompoundRenderPlayer(threading.Thread):
74
+    def __init__(self, file_name, media_name, callback, tractor):
75
+        self.file_name = file_name
76
+        self.media_name = media_name
77
+        self.render_done_callback = callback
78
+        self.tractor = tractor
79
+
80
+        threading.Thread.__init__(self)
81
+
82
+    def run(self):
83
+        tractor = self.tractor
84
+        tractor.set_speed(0)
85
+        tractor.seek(0)
86
+        
87
+        # Wait until producer is at start
88
+        while tractor.frame() != 0:
89
+            time.sleep(0.1)
90
+
91
+        # Get render consumer
92
+        xml_consumer = mlt.Consumer(PROJECT().profile, "xml", str(self.file_name))
93
+
94
+        # Connect and start rendering
95
+        xml_consumer.connect(tractor)
96
+        xml_consumer.start()
97
+        tractor.set_speed(1)
98
+
99
+        # Wait until done
100
+        while xml_consumer.is_stopped() == False:
101
+            print "In XML render wait loop..."
102
+            time.sleep(0.1)
103
+    
104
+        print "XML compound clip render done"
105
+
106
+        self.render_done_callback(self.file_name, self.media_name)
107
+
108
+
109
 class ProgressWindowThread(threading.Thread):
110
     def __init__(self, dialog, progress_bar, clip_renderer, callback):
111
         self.dialog = dialog
112
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/rendergui.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/rendergui.py Changed
177
 
1
@@ -220,11 +220,10 @@
2
     slider_hbox = Gtk.HBox(False, 4)
3
     slider_hbox.pack_start(fb_widgets.hslider, True, True, 0)
4
     slider_hbox.pack_start(spin, False, False, 4)
5
-    slider_hbox.set_size_request(350,35)
6
+    slider_hbox.set_size_request(450,35)
7
 
8
     hbox = Gtk.HBox(False, 2)
9
     hbox.pack_start(guiutils.pad_label(8, 8), False, False, 0)
10
-    hbox.pack_start(label, False, False, 0)
11
     hbox.pack_start(slider_hbox, False, False, 0)
12
 
13
     profile_selector = ProfileSelector()
14
@@ -272,6 +271,7 @@
15
     vbox.pack_start(guiutils.get_left_justified_box([Gtk.Label(label=_("Source Mark In: ")), guiutils.pad_label(SOURCE_PAD, SOURCE_HEIGHT), mark_in]), False, False, 0)
16
     vbox.pack_start(guiutils.get_left_justified_box([Gtk.Label(label=_("Source Mark Out: ")), guiutils.pad_label(SOURCE_PAD, SOURCE_HEIGHT), mark_out]), False, False, 0)
17
     vbox.pack_start(guiutils.pad_label(18, 12), False, False, 0)
18
+    vbox.pack_start(label, False, False, 0)
19
     vbox.pack_start(hbox, False, False, 0)
20
     vbox.pack_start(guiutils.pad_label(18, 12), False, False, 0)
21
     vbox.pack_start(guiutils.get_two_column_box(Gtk.Label(label=_("Target File:")), name_row, 120), False, False, 0)
22
@@ -306,6 +306,154 @@
23
         orig_len = media_file.length
24
 
25
     return int((float(orig_len) * 100.0) / float(speed))
26
+    
27
+def show_reverse_dialog(media_file, default_range_render, _response_callback):
28
+    folder, file_name = os.path.split(media_file.path)
29
+    if media_file.is_proxy_file:
30
+        folder, file_name = os.path.split(media_file.second_file_path)
31
+
32
+    name, ext = os.path.splitext(file_name)
33
+        
34
+    dialog = Gtk.Dialog(_("Render Reverse Motion Video File"), gui.editor_window.window,
35
+                        Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,
36
+                        (Gtk.STOCK_CANCEL, Gtk.ResponseType.REJECT,
37
+                        _("Render").encode('utf-8'), Gtk.ResponseType.ACCEPT))
38
+
39
+    media_file_label = Gtk.Label(label=_("Source Media File: "))
40
+    media_name = Gtk.Label(label="<b>" + media_file.name + "</b>")
41
+    media_name.set_use_markup(True)
42
+    SOURCE_PAD = 8
43
+    SOURCE_HEIGHT = 20
44
+    mf_row = guiutils.get_left_justified_box([media_file_label,  guiutils.pad_label(SOURCE_PAD, SOURCE_HEIGHT), media_name])
45
+    
46
+    mark_in = Gtk.Label(label=_("<b>not set</b>"))
47
+    mark_out = Gtk.Label(label=_("<b>not set</b>"))
48
+    if media_file.mark_in != -1:
49
+        mark_in = Gtk.Label(label="<b>" + utils.get_tc_string(media_file.mark_in) + "</b>")
50
+    if media_file.mark_out != -1:
51
+        mark_out = Gtk.Label(label="<b>" + utils.get_tc_string(media_file.mark_out) + "</b>")
52
+    mark_in.set_use_markup(True)
53
+    mark_out.set_use_markup(True)
54
+    
55
+    fb_widgets = utils.EmptyClass()
56
+
57
+    fb_widgets.file_name = Gtk.Entry()
58
+    fb_widgets.file_name.set_text(name + "_REVERSE")
59
+    
60
+    fb_widgets.extension_label = Gtk.Label()
61
+    fb_widgets.extension_label.set_size_request(45, 20)
62
+
63
+    name_row = Gtk.HBox(False, 4)
64
+    name_row.pack_start(fb_widgets.file_name, True, True, 0)
65
+    name_row.pack_start(fb_widgets.extension_label, False, False, 4)
66
+    
67
+    fb_widgets.out_folder = Gtk.FileChooserButton(_("Select Target Folder"))
68
+    fb_widgets.out_folder.set_action(Gtk.FileChooserAction.SELECT_FOLDER)
69
+    fb_widgets.out_folder.set_current_folder(folder)
70
+    
71
+    label = Gtk.Label(label=_("Speed %:"))
72
+
73
+    adjustment = Gtk.Adjustment(float(-100), float(-600), float(-1), float(1))
74
+    fb_widgets.hslider = Gtk.HScale()
75
+    fb_widgets.hslider.set_adjustment(adjustment)
76
+    fb_widgets.hslider.set_draw_value(False)
77
+
78
+    spin = Gtk.SpinButton()
79
+    spin.set_numeric(True)
80
+    spin.set_adjustment(adjustment)
81
+
82
+    fb_widgets.hslider.set_digits(0)
83
+    spin.set_digits(0)
84
+
85
+    slider_hbox = Gtk.HBox(False, 4)
86
+    slider_hbox.pack_start(fb_widgets.hslider, True, True, 0)
87
+    slider_hbox.pack_start(spin, False, False, 4)
88
+    slider_hbox.set_size_request(450,35)
89
+
90
+    hbox = Gtk.HBox(False, 2)
91
+    hbox.pack_start(guiutils.pad_label(8, 8), False, False, 0)
92
+    hbox.pack_start(slider_hbox, False, False, 0)
93
+
94
+    profile_selector = ProfileSelector()
95
+    profile_selector.fill_options()
96
+    profile_selector.widget.set_sensitive(True)
97
+    fb_widgets.out_profile_combo = profile_selector.widget
98
+
99
+    quality_selector = RenderQualitySelector()
100
+    fb_widgets.quality_cb = quality_selector.widget
101
+    
102
+    # Encoding
103
+    encoding_selector = RenderEncodingSelector(quality_selector, fb_widgets.extension_label, None)
104
+    encoding_selector.encoding_selection_changed()
105
+    fb_widgets.encodings_cb = encoding_selector.widget
106
+    
107
+    objects_list = Gtk.TreeStore(str, bool)
108
+    objects_list.append(None, [_("Full Source Length"), True])
109
+    if media_file.mark_in != -1 and media_file.mark_out != -1:
110
+        range_available = True
111
+    else:
112
+        range_available = False
113
+    objects_list.append(None, [_("Source Mark In to Mark Out"), range_available])
114
+    
115
+    fb_widgets.render_range = Gtk.ComboBox.new_with_model(objects_list)
116
+    
117
+    renderer_text = Gtk.CellRendererText()
118
+    fb_widgets.render_range.pack_start(renderer_text, True)
119
+    fb_widgets.render_range.add_attribute(renderer_text, "text", 0)
120
+    fb_widgets.render_range.add_attribute(renderer_text, 'sensitive', 1)
121
+    if default_range_render == False:
122
+        fb_widgets.render_range.set_active(0)
123
+    else:
124
+        fb_widgets.render_range.set_active(1)
125
+    fb_widgets.render_range.show()
126
+
127
+    # To update rendered length display
128
+    clip_length = _get_rendered_slomo_clip_length(media_file, fb_widgets.render_range, 100)
129
+    clip_length_label = Gtk.Label(label=utils.get_tc_string(clip_length))
130
+    fb_widgets.hslider.connect("value-changed", _reverse_speed_changed, media_file, fb_widgets.render_range, clip_length_label)
131
+    fb_widgets.render_range.connect("changed", _reverse_range_changed,  media_file, fb_widgets.hslider,  clip_length_label)
132
+
133
+    # Build gui
134
+    vbox = Gtk.VBox(False, 2)
135
+    vbox.pack_start(mf_row, False, False, 0)
136
+    vbox.pack_start(guiutils.get_left_justified_box([Gtk.Label(label=_("Source Mark In: ")), guiutils.pad_label(SOURCE_PAD, SOURCE_HEIGHT), mark_in]), False, False, 0)
137
+    vbox.pack_start(guiutils.get_left_justified_box([Gtk.Label(label=_("Source Mark Out: ")), guiutils.pad_label(SOURCE_PAD, SOURCE_HEIGHT), mark_out]), False, False, 0)
138
+    vbox.pack_start(guiutils.pad_label(18, 12), False, False, 0)
139
+    vbox.pack_start(label, False, False, 0)
140
+    vbox.pack_start(hbox, False, False, 0)
141
+    vbox.pack_start(guiutils.pad_label(18, 12), False, False, 0)
142
+    vbox.pack_start(guiutils.get_two_column_box(Gtk.Label(label=_("Target File:")), name_row, 120), False, False, 0)
143
+    vbox.pack_start(guiutils.get_two_column_box(Gtk.Label(label=_("Target Folder:")), fb_widgets.out_folder, 120), False, False, 0)
144
+    vbox.pack_start(guiutils.get_two_column_box(Gtk.Label(label=_("Target Profile:")), fb_widgets.out_profile_combo, 200), False, False, 0)
145
+    vbox.pack_start(guiutils.get_two_column_box(Gtk.Label(label=_("Target Encoding:")), fb_widgets.encodings_cb, 200), False, False, 0)
146
+    vbox.pack_start(guiutils.get_two_column_box(Gtk.Label(label=_("Target Quality:")), fb_widgets.quality_cb, 200), False, False, 0)
147
+    vbox.pack_start(guiutils.pad_label(18, 12), False, False, 0)
148
+    vbox.pack_start(guiutils.get_two_column_box(Gtk.Label(label=_("Render Range:")), fb_widgets.render_range, 180), False, False, 0)
149
+    vbox.pack_start(guiutils.get_two_column_box(Gtk.Label(label=_("Rendered Clip Length:")), clip_length_label, 180), False, False, 0)
150
+    
151
+    alignment = guiutils.set_margins(vbox, 6, 24, 24, 24)
152
+    
153
+    dialog.vbox.pack_start(alignment, True, True, 0)
154
+    dialogutils.set_outer_margins(dialog.vbox)
155
+    dialogutils.default_behaviour(dialog)
156
+    dialog.connect('response', _response_callback, fb_widgets, media_file)
157
+    dialog.show_all()
158
+
159
+def _reverse_speed_changed(slider, media_file, range_combo, length_label):
160
+    clip_length = _get_rendered_reverse_clip_length(media_file, range_combo, slider.get_adjustment().get_value())
161
+    length_label.set_text(utils.get_tc_string(clip_length))
162
+
163
+def _reverse_range_changed(range_combo, media_file, slider, length_label):
164
+    clip_length = _get_rendered_reverse_clip_length(media_file, range_combo, slider.get_adjustment().get_value())
165
+    length_label.set_text(utils.get_tc_string(clip_length))
166
+
167
+def _get_rendered_reverse_clip_length(media_file, range_combo, speed):
168
+    if range_combo.get_active() == 1:
169
+        orig_len = media_file.mark_out -  media_file.mark_in + 1 # +1 mark out incl
170
+    else:
171
+        orig_len = media_file.length
172
+
173
+    return int((float(orig_len) * 100.0) / float(-speed))
174
 
175
 # ----------------------------------------------------------- widgets
176
 class RenderQualitySelector():
177
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/res/darktheme/flowblade_splash_black_small.png -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/res/darktheme/flowblade_splash_black_small.png Changed
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/res/filters/compositors.xml -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/res/filters/compositors.xml Changed
39
 
1
@@ -82,6 +82,37 @@
2
         <property name="opacity" args="editor=keyframe_editor_clip range_in=0,100 range_out=0,1 exptype=keyframe_hcs_transition displayname=Opacity">0=1.0</property>
3
     </compositortransition>
4
 
5
+
6
+
7
+    <!-- AUTOFADES -->
8
+    <compositortransition mlt_service="composite" autofadecompositor="True">
9
+        <name>##auto_fade_in</name>
10
+        <property name="force_track" args="editor=no_editor">0</property>
11
+        <property name="geometry" args="editor=fade_length exptype=opacity_in_geom_kf displayname=Fade!In!Length">0=0/0:SCREENSIZE:100</property>
12
+        <property name="aligned" args="editor=no_editor">0</property>
13
+        <property name="distort" args="editor=no_editor">0</property>
14
+        <property name="fill" args="editor=no_editor">1</property>        
15
+        <property name="operator" args="editor=no_editor exptype=not_parsed_transition">over</property>
16
+        <property name="deinterlace" args="editor=no_editor">0</property>
17
+        <property name="progressive" args="editor=no_editor">1</property>
18
+        <extraeditor name="composite_properties"></extraeditor>
19
+    </compositortransition>
20
+
21
+    <compositortransition mlt_service="composite" autofadecompositor="True">
22
+        <name>##auto_fade_out</name>
23
+        <property name="force_track" args="editor=no_editor">0</property>
24
+        <property name="geometry" args="editor=fade_length exptype=opacity_in_geom_kf displayname=Fade!Out!Length">0=0/0:SCREENSIZE:100</property>
25
+        <property name="aligned" args="editor=no_editor">0</property>
26
+        <property name="distort" args="editor=no_editor">0</property>
27
+        <property name="fill" args="editor=no_editor">1</property>        
28
+        <property name="operator" args="editor=no_editor exptype=not_parsed_transition">over</property>
29
+        <property name="deinterlace" args="editor=no_editor">0</property>
30
+        <property name="progressive" args="editor=no_editor">1</property>
31
+        <extraeditor name="composite_properties"></extraeditor>
32
+    </compositortransition>
33
+    
34
+    
35
+    
36
     <!-- BLENDS -->
37
     <compositortransition mlt_service="frei0r.darken">
38
         <name>##darken</name>
39
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/res/filters/filters.xml -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/res/filters/filters.xml Changed
31
 
1
@@ -88,7 +88,7 @@
2
     <filter id="volume" multipart="true">
3
         <name>Volume</name>
4
         <group>Audio</group>
5
-        <multipartproperty multistartprop="gain" multiendprop="end" args="editor=keyframe_editor_release range_in=0,100 exptype=multipart_keyframe displayname=Volume">"0=1.0"</multipartproperty>
6
+        <multipartproperty multistartprop="gain" multiendprop="end" args="editor=keyframe_editor_release range_in=0,200 range_out=0.0,2.0 exptype=multipart_keyframe displayname=Volume">"0=1.0"</multipartproperty>
7
         <property name="max_gain" args="editor=no_editor exptype=not_parsed">20dB</property>
8
         <property name="track" args="editor=no_editor">0</property>
9
         <property name="gain" args="editor=no_editor">1</property> <!-- Volume at start of filter --> 
10
@@ -901,15 +901,16 @@
11
         <property name="transition.fix_shear_x" args="range_in=-180,180 range_out=-180,180 displayname=Shear!X">0</property>
12
         <property name="transition.fix_shear_y" args="range_in=-180,180 range_out=-180,180 displayname=Shear!Y">0</property>
13
     </filter>
14
+    <!--- Removed because didn't work on all media items.
15
     <filter id="avfilter.zoompan">
16
         <name>Zoom Pan</name>
17
         <group>Transform</group>
18
-        <property name="av.zoom" args="range_in=100,500 range_out=1,5 displayname=Zoom">1</property>
19
-        <property name="av.x" args="range_in=0,SCREENSIZE_WIDTH range_out=0,SCREENSIZE_WIDTH displayname=x">0</property>
20
-        <property name="av.y" args="range_in=0,SCREENSIZE_HEIGHT range_out=0,SCREENSIZE_HEIGHT displayname=y">0</property>
21
+        <property name="av.zoom" args="range_in=100,500 range_out=1,5 displayname=Zoom">1.1</property>
22
+        <property name="av.x" args="range_in=0,SCREENSIZE_WIDTH range_out=0,SCREENSIZE_WIDTH displayname=x">10</property>
23
+        <property name="av.y" args="range_in=0,SCREENSIZE_HEIGHT range_out=0,SCREENSIZE_HEIGHT displayname=y">10</property>
24
         <property name="av.d" args="editor=no_editor">1</property>
25
     </filter>
26
-
27
+    -->
28
 
29
     <!-- compositor filters that are not displayed to user, not used currently -->
30
     <filter id="frei0r.mask0mate">
31
flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/res/help/advanced.html Added
201
 
1
@@ -0,0 +1,230 @@
2
+ <!DOCTYPE html>
3
+<html>
4
+<head>
5
+  <title>Advanced Editing</title>
6
+  <link rel="stylesheet" href="style.css">
7
+<script src="toc.js" type="text/javascript"></script>
8
+</head>
9
+
10
+<body>
11
+
12
+<div id="content">
13
+<img src="header_text_5.png" >
14
+
15
+<script src="tocgen.js"></script>
16
+
17
+<div id="toccontent">
18
+
19
+<div id="advtoc">
20
+<div class="subject-header">Advanced Editing</div>
21
+</div>
22
+
23
+<div id="toc"></div>
24
+
25
+<h2>1. Advanced Project Actions </h2>
26
+
27
+
28
+<h3>Combining Sequences</h3>
29
+<p>
30
+It is possible to import full contents of another Sequence into Sequence currently being edited.
31
+</p>
32
+
33
+<ol>
34
+<li> Select <b>Project->Import Another Sequence into this Sequnce..</b></li>
35
+<li> Select Import action.</li>
36
+<ul>
37
+<li> <b>Append Sequence</b> adds imported Sequence at the end of current Sequence</li>
38
+<li> <b>Insert Sequence at Playhead Position</b> creates a cut at playhead position and inserts imported Sequences at that position</li>
39
+</ul>
40
+<li> Select a Sequence to Import</li>
41
+<ul>
42
+<li> <b>Note that you obivously need atleast two Sequences to exist to do any import actions.</b></li>
43
+</ul>
44
+<li> Press <b>Import</b> button to execute import.</li>
45
+</ol>
46
+
47
+<h3>Importing Media from another Project</h3>
48
+
49
+<p>
50
+You can import Media Items from another Project.
51
+</p>
52
+
53
+<ol>
54
+<li> Select <b>Project->Import Media From Project...</b></li>
55
+<li> Select a Project file from file system.</li>
56
+<li> Media items that are not present in current Project will be opened in the current bin. Note that it takes a few seconds to load the project before new Media Items begin to appear.</li>
57
+</ol>
58
+
59
+
60
+
61
+<h2>2. Compound Clips </h2>
62
+
63
+<p>
64
+A <b>Compound Clip</b> is a single clip created by combining multiple clips and compositors in to a single media item.
65
+</p>
66
+
67
+<p>
68
+In Flowblade Compound Clips are <i>implemented by creating an MLT XML file</i> that is saved in a hidden folder. Note that it is currently not possible to unpack a Compound Clip back to its components.
69
+</p>
70
+
71
+<p>
72
+Compound Clips are useful when some complex sequence is more conveniently handled as a single unit.
73
+</p>
74
+
75
+<h3> Creating Compound Clip from Selection</h3>
76
+
77
+<ol>
78
+<li> Select 2 or more adjacent clips from a single track.</li>
79
+<li> Select <b>Project->Create Compound Clip->From Selected Clips</b></li>
80
+<li> Give a name for the new Media Item in the dialog.</li>
81
+<li> A new Media Item appears in the current Bin.</li>
82
+</ol>
83
+
84
+<h3> Creating Compound Clip from Sequence</h3>
85
+
86
+<ol>
87
+<li> Select <b>Project->Create Compound Clip->From Current Sequence</b></li>
88
+<li> Give a name for the new Media Item in the dialog.</li>
89
+<li> A new Media Item appears in the current Bin.</li>
90
+</ol>
91
+
92
+<h3> Creating audio synced Compound Clip from two Media Items</h3>
93
+
94
+<ol>
95
+<li> Select 2 Media Items in Media panel.</b></li>
96
+<ul>
97
+<li> The expected case is to select <b>1 Video and 1 Audio Clip</b>.</li>
98
+<li> If you select <b>2 Video Clips</b> then which is used as video depends on selection order.</li>
99
+<li> Audio from clip treated as video is muted.</li>
100
+</ul>
101
+<li> Select <b>Project->Create Compound Clip->Audio Sync Merge Clip From 2 Media Items</b></li>
102
+<li> If audio sync is successful a dialog  appers. Give a name for the new Media Item in the dialog.</li>
103
+<li> A new Media Item appears in the current Bin.</li>
104
+</ol>
105
+
106
+<div class="note">
107
+Audio synching looks for best matemathical match between two audio waveforms, so <b>audio syncing non-matching audio will produce random results.</b>
108
+</div>
109
+
110
+<h2>3. Timeline Audio Syncing</h2>
111
+
112
+<p>
113
+You can make a clip to move to a position in timeline in which its audio is in sync with audio of another clip on timeline.
114
+</p>
115
+
116
+<p>
117
+This enables you to do simplified version of multicam editing on the timeline.
118
+</p>
119
+
120
+<ol>
121
+<li> Open context menu with <b>Right Mouse</b> on Clip you wish to sync with some other clip.</li>
122
+<li> Select menu item <b>Select Clip to Audio Sync With...</b>. The cursor changes to a targeting cross.</li>
123
+<li> Click on Clip you wish to audio sync with.</li>
124
+<li> A dialog opens giving info on the sync action that is to be done to sync clips.</li>
125
+<li> Press <b>Do Audio Sync Move Edit</b> button to do the syncing edit.</li>
126
+<li> It is usually a good idea to mute one of the synched clips</li>
127
+</ol>
128
+
129
+<div class="note">
130
+Audio synching looks for best matemathical match between two audio waveforms, so <b>audio syncing non-matching audio will produce random results.</b>
131
+</div>
132
+
133
+
134
+<h2>4. Slow / Fast Motion and Reverse Clips</h2>
135
+
136
+<p>
137
+In Flowblade motion effects are achived by <b>rendering slow / fast motion  or reverse versions of video clips</b> and placing those on the timeline.
138
+</p>
139
+<h3> Creating Motion Clips </h3>
140
+<ol>
141
+<li> Right click on a Media File and select <b>Render Slow / Fast Motion File</b> from menu</li>
142
+<li>Edit parameters for the new motion Clip
143
+<ul>
144
+<li> Set speed</li>
145
+<li> Give name and location for motion Clip </li>
146
+<li> Select rendering parameters for motion Clip. It is probably a good idea to use a <b>lossless format</b> here to avoid any generational quality losses.</li>
147
+<li> Select render range, either:</li>
148
+<ul>
149
+<li> Full Source Clip</li>
150
+<li> From Source Clip Mark In to Mark Out</li>
151
+</ul>
152
+</ul>
153
+<li> Click <b>Render</b> button to create a new motion Clip</li>
154
+</ol>
155
+
156
+<h3> Creating Reverse Clips </h3>
157
+<ol>
158
+<li> Right click on a Media File and select <b>Render Reverse Motion File</b> from menu</li>
159
+<li>Edit parameters for the new motion Clip
160
+<ul>
161
+<li> Set speed</li>
162
+<li> Give name and location for reverse Clip </li>
163
+<li> Select rendering parameters for reverse Clip. It is probably a good idea to use a <b>lossless format</b> here to avoid any generational quality losses.</li>
164
+<li> Select render range, either:</li>
165
+<ul>
166
+<li> Full Source Clip</li>
167
+<li> From Source Clip Mark In to Mark Out</li>
168
+</ul>
169
+</ul>
170
+<li> Click <b>Render</b> button to create a new reverse Clip</li>
171
+</ol>
172
+
173
+<h2>5. Clip Parenting</h2>
174
+
175
+<p>
176
+In Flowblade Movie Editor you can <b>set a clip's positions to follow another clip's positions</b> on request.
177
+</p>
178
+
179
+<h3>Main points</h3>
180
+<ul>
181
+<li>Sync relations are set up by selecting a <b>Sync Parent Clip</b> for a <b>Sync Child Clip</b>.</li>
182
+<li><b>Only clips on track V1 can be Sync Parent Clips</b>. This is done to encourage edit style in which the main body of the Sequence is on track V1 and composites and audio split edits are done relative to the clip sequence on track V1.</li>
183
+<li><b>Sync feature helps preserve earlier work</b> an multitrack composites and audio split edits when clips are no longer in correct positions relative to each other, because of edits elsewhere on the Sequence.</li>
184
+<li><b>Resyncs are only done on request</b> to avoid jumping of clips on the timeline while editing. Explicit resyncs are also better from the point of view of avoiding side effects when doing edits.
185
+</li>
186
+</ul>
187
+<h3>Setting Sync Parent</h3>
188
+<ol>
189
+<li> Click <b>Right Mouse</b> on clip and select Select Sync Parent Clip... on any clip NOT on track V1.</li>
190
+<li> Cursor turns into a Target Cross. Click on clip on track V1 to select it as Sync Parent Clip.</li>
191
+<li> Sync Relation is established between the two clips. Cursor turns back into a default pointer.</li>
192
+<li> Sync State Stripe appers on the Sync Child Clip. Sync State Indicator Stripes on Clips:</li>
193
+<ul>
194
+<li> Green means that clip is in sync with parent.</li>
195
+<li> Red means that clip is NOT in sync with parent.</li>
196
+<li> Gray means that Sync Parent Clip is no longer on track V1.</li>
197
+</ul>
198
+</ol>
199
+
200
+<h3>Resyncing Sync Child Clips</h3>
201
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/res/help/basic_editing.html -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/res/help/basic_editing.html Changed
39
 
1
@@ -59,8 +59,13 @@
2
 
3
 <h3>Adding and removing new Sequences</h3>
4
 <p>
5
-A Project contains one or more Sequences. 
6
+A Project contains one or more Sequences. The term Sequence refers to the full contents of the timeline forming a program, a movie.
7
 </p>
8
+
9
+<p>
10
+For complex projects it is sometimes best to use multiple sequences for creating and managing different parts of the finished product.
11
+</p>
12
+
13
 <p>
14
 Use <b>Add</b> and <b>Delete</b> buttons in the <b>Project</b> tab <b>Sequences</b> panel. All Sequences use the same Profile.
15
 </p>
16
@@ -102,6 +107,14 @@
17
 
18
 <h3>Working with Bins</h3>
19
 
20
+<p>
21
+In video editing a bin is a location for storing media. The term is used in Avid and was earlier used by film editors.
22
+</p>
23
+
24
+<p>
25
+For small projects using bins is usually not needed and you can hide the Bin panel by dragging a handle between the panels.
26
+</p>
27
+
28
 <div class="tabbed">
29
 <p><b>Adding a Bin</b>: Press <b>Add</b> button above Bins table.</p>
30
 <p><b>Deleting a Bin</b>: Press <b>Delete</b> button above Bins table.
31
@@ -172,7 +185,6 @@
32
 <li> Click on another clip on the same track with <b>Control + Left Mouse</b> button.</li>
33
 <li> All clips between clicked clips will be selected.</li>
34
 </ul>
35
-<div class="note"><b>There is no box selection or any other means of selecting clips from different Tracks at the same time.</b></div>
36
 
37
 <h4>De-selecting all clips</h4>
38
 <ul>
39
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/res/help/compositor.html -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/res/help/compositor.html Changed
23
 
1
@@ -1,7 +1,7 @@
2
  <!DOCTYPE html>
3
 <html>
4
 <head>
5
-  <title>Page Title</title>
6
+  <title>Creating Composited Images</title>
7
   <link rel="stylesheet" href="style.css">
8
 </head>
9
 
10
@@ -28,10 +28,10 @@
11
 <p>
12
 Compositors have a Source track and a Destination track.</p>
13
 <p>
14
- On the Timeline Compositor is displayed as a dark rectangular object that is displayed on top of two tracks. Source track is always the one above Compositor, but Destination track may be any of the tracks below it.
15
+ On the Timeline a Compositor is displayed as a rectangular object on top of two tracks. Source track is always the one above Compositor, but Destination track may be any of the tracks below it.
16
 </p>
17
 <p>
18
-Parameters defining the resulting composite are edited in the <b>Compositors</b> tab.
19
+Parameters defining the resulting image are edited in the <b>Compositors</b> tab.
20
 </p>
21
 <p>
22
 There is a subtype of Compositors called Blenders.
23
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/res/help/contributors -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/res/help/contributors Changed
5
 
1
@@ -1,1 +1,2 @@
2
-ptrg bergamote oberon20073 faridosc pzl siom79 apienk Rayne kaosbeat
3
+ptrg, bergamote, oberon2007, faridosc, pzl, siom79, apienk, Rayne, kaosbeat, lsde, Bene81, ahangarha, theychx
4
+
5
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/res/help/developers -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/res/help/developers Changed
4
 
1
@@ -1,1 +1,1 @@
2
-Steven van de Beek  Nathan Rosenquist
3
+Steven van de Beek, Nathan Rosenquist
4
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/res/help/help.html -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/res/help/help.html Changed
29
 
1
@@ -42,7 +42,7 @@
2
        </div> 
3
        <div class="column4">
4
        <div class="subject-cell">
5
-           <a href="resync.html">Clip Syncing and Audio Split Editing</a> 
6
+           <a href="advanced.html">Advanced Editing</a> 
7
        </div> 
8
        </div> 
9
    </div>
10
@@ -59,16 +59,11 @@
11
        </div> 
12
        <div class="column4">
13
        <div class="subject-cell">
14
-           <a href="slow.html">Slow / Fast Motion</a>
15
-       </div> 
16
-       </div> 
17
-   </div>
18
-   <div class="row">
19
-       <div class="column4">
20
-       <div class="subject-cell">
21
            <a href="tools.html">Tools</a>
22
        </div>
23
        </div> 
24
+   </div>
25
+   <div class="row">
26
        <div class="column4">
27
        <div class="subject-cell">
28
             <a href="rendering.html">Rendering</a>
29
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/res/help/style.css -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/res/help/style.css Changed
22
 
1
@@ -146,6 +146,12 @@
2
    margin-bottom:10px;
3
 }
4
 
5
+#advtoc {
6
+   margin-top:50px;
7
+   margin-bottom:30px;
8
+}
9
+
10
+
11
 /* Otsikot 1 */
12
 h1, h2, h3, h4, h5, h6{
13
    text-transform: uppercase;
14
@@ -160,6 +166,7 @@
15
    color: #000000;
16
 }
17
 h2{
18
+   margin-top: 80px;
19
    font-size:26px;
20
 }
21
 h3{
22
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/res/help/translations -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/res/help/translations Changed
13
 
1
@@ -1,4 +1,3 @@
2
-Translations by:
3
   cs - Pavel Fric
4
   fi - jl
5
   fr - Loïc Vanderstichelen
6
@@ -6,4 +5,6 @@
7
   es - David Gamiz Jimenez
8
   it - Massimo Stella
9
   hu - Péter Gábor
10
+  pl - Stanisław Polak
11
   ru - Николай Смольянинов
12
+  zh_CN - 老吴的BOX
13
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/res/img/flowblade_splash_black_small.png -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/res/img/flowblade_splash_black_small.png Changed
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/res/render/renderencoding.xml -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/res/render/renderencoding.xml Changed
20
 
1
@@ -3,7 +3,7 @@
2
     <!-- quality qroups are groups of quality options presented with an encoding option -->
3
     <!-- addargs="arg1=val1 arg2=va2"(space separated list) -->
4
     <!-- replvalues="replexp1 replval1;replexp2 replval2" (; separated list) -->
5
-    <qualityqroup id="qgroup1" defaultindex="6">
6
+    <qualityqroup id="qgroup1" defaultindex="10">
7
         <quality name="200 kb/s" replvalues="%BITRATE% 200k" />
8
         <quality name="400 kb/s" replvalues="%BITRATE% 400k" />
9
         <quality name="600 kb/s" replvalues="%BITRATE% 600k" />
10
@@ -91,6 +91,9 @@
11
     <encodingoption name="Lossless H.264 / .mp4" extension="mp4" audiodesc=" aac"  type="av" resize="True" qgroup="lossless">
12
         <profile args="f=mp4 acodec=aac ab=384k ac=2 pix_fmt=yuv420p vcodec=libx264 cqp=0 me_method=esa subq=8 qmin=10 qcomp=0.6 qdiff=4 qmax=51 coder=ac partitions=+parti4x4+parti8x8+partp4x4+partp8x8+partb8x8 refs=16 trellis=1" />
13
     </encodingoption>
14
+    <encodingoption name="Lossless FFv1 / .mkv" extension="mkv" audiodesc=" flac"  type="av" resize="True" qgroup="lossless">
15
+        <profile args="f=mkv acodec=flac vcodec=ffv1 level=3 g=1 slicecrc=1 slices=16" />
16
+    </encodingoption>
17
     <encodingoption name="Apple ProRes 4:2:2 / .mov" extension="mov" audiodesc=" pcm" type="av" resize="True" qgroup="variablenooption">
18
     <profile args="f=mov acodec=pcm_s16le ac=2 vcodec=prores vb=0 g=0 bf=0 threads=1 vprofile=2" />
19
     </encodingoption>
20
flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/res/shortcuts Added
2
 
1
+(directory)
2
flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/res/shortcuts/flowblade.xml Added
113
 
1
@@ -0,0 +1,111 @@
2
+<?xml version='1.0' encoding='utf-8'?>
3
+<!--
4
+  Shortcut configuration file for Flowblade.
5
+  Apr-2017 - SvdB
6
+  Each config file should contain a single set of shortcuts
7
+
8
+  The attribute 'name' in the <flowblade> tag should be the same as the file name.
9
+  The filename will be displayed in the application preferences screen.
10
+
11
+  The author tag is optional.
12
+
13
+  The shortcuts tag is mandatory.
14
+
15
+  There must be at least one event tag. Missing event tags will use the default
16
+  Flowblade values.
17
+
18
+  The code attribute is used internally. Unknown code values will be ignored.
19
+
20
+  The name attribute is optional but used for clarity.
21
+
22
+  There can be multiple event lines for the same code. The defined shortcuts
23
+  will all be usable. 
24
+  The modifiers attribute can contain any combination of modifiers and are
25
+  applied together with the key. The format is Ctrl+Alt, i.e. separated by +
26
+  If no modifiers attribute is given then no modifier will be needed or allowed.
27
+
28
+  The modifiers are defined as follows:
29
+  Ctrl, Alt, Meta (Typically Windows key), Shift, Any
30
+  'Any' is a special case where modifier states are not actually checked
31
+  to determine the action. This is used for ffwd / rev where the modifiers ARE
32
+  used, but hardcoded in the application.
33
+  If you have CapsLock engaged on your keyboard it will equate to SHIFT.
34
+  Others may be added later.
35
+  Case is not important for the modifiers, so ALT and Alt and alt are all the same.
36
+  Case IS important for the code attribute.
37
+  
38
+  At the moment there is no difference between left/right Shift or Ctrl.
39
+  Non alpha-numerical keys can be referenced by their key name:
40
+  insert delete home space end page_up page_down up down left right
41
+  f1..f12 kp_divide kp_multiply kp_subtract kp_add kp_enter kp_decimal
42
+  kp_0..kp_9
43
+  NB: The Keypad numbers have a different assignment to the 'normal' numbers.
44
+  If you want a shortcut for the Keypad numbers, use kp_0..kp_9 instead of 0..9
45
+
46
+  The keys used can be typed normally in this file. Alphabetical keys MUST be
47
+  lower case. If you want to use upper case, then use the Shift
48
+  modifier.
49
+-->
50
+<flowblade file='shortcuts' name='Flowblade' comment='Default values'>
51
+  <author name='me'>
52
+    <name>Steven van de Beek</name>
53
+    <date format='dd-Mmm-yyyy'>16-Apr-2017</date>
54
+  </author>
55
+  <shortcuts>
56
+    <event code='mark_in' name='Mark In'>i</event>
57
+    <event code='mark_out' name='Mark Out'>o</event>
58
+    <event code='to_mark_in' name='Go To Mark In' modifiers='ALT'>i</event>
59
+    <event code='to_mark_in' name='Go To Mark In' modifiers='SHIFT'>i</event>
60
+    <event code='to_mark_in' name='Go To Mark In' modifiers='ALT+SHIFT'>i</event>
61
+    <event code='to_mark_out' name='Go To Mark Out' modifiers='ALT'>o</event>
62
+    <event code='to_mark_out' name='Go To Mark Out' modifiers='SHIFT'>o</event>
63
+    <event code='to_mark_out' name='Go To Mark Out' modifiers='ALT+SHIFT'>o</event>
64
+    <event code='play_pause' name='Play / Pause'>space</event>
65
+    <event code='prev_cut' name='Go To Previous Cut'>down</event>
66
+    <event code='next_cut' name='Go To Next Cut'>up</event>
67
+    <event code='prev_frame' name='Go To Previous Frame' modifiers='Any'>left</event>
68
+    <event code='next_frame' name='Go To Next Frame' modifiers='Any'>right</event>
69
+    <event code='insert' name='Insert'>y</event>
70
+    <event code='insert' name='Insert' modifiers='SHIFT'>y</event>
71
+    <event code='append' name='Append'>u</event>
72
+    <event code='append' name='Append' modifiers='SHIFT'>u</event>
73
+    <event code='slower' name='Slower'>j</event>
74
+    <event code='stop' name='Stop'>k</event>
75
+    <event code='faster' name='Faster'>l</event>
76
+    <event code='log_range' name='Log Range' modifiers='CTRL'>l</event>
77
+    <event code='log_range' name='Log Range'>g</event>
78
+    <event code='resync' name='Resynchronization'>s</event>
79
+    <event code='delete' name='Delete'>delete</event>
80
+    <event code='to_start' name='Go To Start'>home</event>
81
+    <event code='to_end' name='Go To End'>end</event>
82
+    <event code='3_point_overwrite' name='Three Point Overwrite'>t</event>
83
+    <event code='toggle_ripple' name='Toggle Ripple Mode'>r</event>
84
+    <event code='cut' name='Cut'>x</event>
85
+    <event code='edit_mode_insert' name='Change Edit Mode to Insert'>1</event>
86
+    <event code='edit_mode_insert' name='Change Edit Mode to Insert'>kp_1</event>
87
+    <event code='edit_mode_insert' name='Change Edit Mode to Insert'>kp_end</event>
88
+    <event code='edit_mode_overwrite' name='Change Edit Mode to Overwrite'>2</event>
89
+    <event code='edit_mode_overwrite' name='Change Edit Mode to Overwrite'>kp_2</event>
90
+    <event code='edit_mode_overwrite' name='Change Edit Mode to Overwrite'>kp_down</event>
91
+    <event code='edit_mode_trim' name='Change Edit Mode to Trim'>3</event>
92
+    <event code='edit_mode_trim' name='Change Edit Mode to Trim'>kp_3</event>
93
+    <event code='edit_mode_trim' name='Change Edit Mode to Trim'>kp_next</event>
94
+    <event code='edit_mode_roll' name='Change Edit Mode to Roll'>4</event>
95
+    <event code='edit_mode_roll' name='Change Edit Mode to Roll'>kp_4</event>
96
+    <event code='edit_mode_roll' name='Change Edit Mode to Roll'>kp_left</event>
97
+    <event code='edit_mode_slip' name='Change Edit Mode to Slip'>5</event>
98
+    <event code='edit_mode_slip' name='Change Edit Mode to Slip'>kp_5</event>
99
+    <event code='edit_mode_slip' name='Change Edit Mode to Slip'>kp_begin</event>
100
+    <event code='edit_mode_spacer' name='Change Edit Mode to Spacer'>6</event>
101
+    <event code='edit_mode_spacer' name='Change Edit Mode to Spacer'>kp_6</event>
102
+    <event code='edit_mode_spacer' name='Change Edit Mode to Spacer'>kp_right</event>
103
+    <event code='edit_mode_box' name='Change Edit Mode to Box'>7</event>
104
+    <event code='edit_mode_box' name='Change Edit Mode to Box'>kp_7</event>
105
+    <event code='edit_mode_box' name='Change Edit Mode to Box'>kp_home</event>
106
+    <event code='zoom_out' name='Zoom Out'>minus</event>
107
+    <event code='zoom_in' name='Zoom In'>plus</event>
108
+    <event code='switch_monitor' name='Switch Monitor Display'>tab</event>
109
+    <event code='add_marker' name='Add Marker'>m</event>
110
+    <event code='enter_edit' name='Enter Editing Mode'>return</event>
111
+  </shortcuts>
112
+</flowblade>
113
flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/res/shortcuts/premiere.xml Added
114
 
1
@@ -0,0 +1,112 @@
2
+<?xml version='1.0' encoding='utf-8'?>
3
+<!--
4
+  Shortcut configuration file for Flowblade.
5
+  Apr-2017 - SvdB
6
+  Each config file should contain a single set of shortcuts
7
+
8
+  The attribute 'name' in the <flowblade> tag should be the same as the file name.
9
+  The filename will be displayed in the application preferences screen.
10
+
11
+  The author tag is optional.
12
+
13
+  The shortcuts tag is mandatory.
14
+
15
+  There must be at least one event tag. Missing event tags will use the default
16
+  Flowblade values.
17
+
18
+  The code attribute is used internally. Unknown code values will be ignored.
19
+
20
+  The name attribute is optional but used for clarity.
21
+
22
+  There can be multiple event lines for the same code. The defined shortcuts
23
+  will all be usable. 
24
+  The modifiers attribute can contain any combination of modifiers and are
25
+  applied together with the key. The format is Ctrl+Alt, i.e. separated by +
26
+  If no modifiers attribute is given then no modifier will be needed or allowed.
27
+
28
+  The modifiers are defined as follows:
29
+  Ctrl, Alt, Meta (Typically Windows key), Shift, Any
30
+  'Any' is a special case where modifier states are not actually checked
31
+  to determine the action. This is used for ffwd / rev where the modifiers ARE
32
+  used, but hardcoded in the application.
33
+  If you have CapsLock engaged on your keyboard it will equate to SHIFT.
34
+  Others may be added later.
35
+  Case is not important for the modifiers, so ALT and Alt and alt are all the same.
36
+  Case IS important for the code attribute.
37
+  
38
+  At the moment there is no difference between left/right Shift or Ctrl.
39
+  Non alpha-numerical keys can be referenced by their key name:
40
+  insert delete home space end page_up page_down up down left right
41
+  f1..f12 kp_divide kp_multiply kp_subtract kp_add kp_enter kp_decimal
42
+  kp_0..kp_9
43
+  NB: The Keypad numbers have a different assignment to the 'normal' numbers.
44
+  If you want a shortcut for the Keypad numbers, use kp_0..kp_9 instead of 0..9
45
+
46
+  The keys used can be typed normally in this file. Alphabetical keys MUST be
47
+  lower case. If you want to use upper case, then use the Shift
48
+  modifier.
49
+-->
50
+<flowblade file='shortcuts' name='Premiere-ish/ US keyboard' comment='Default values'>
51
+  <author name='me'>
52
+    <name>Steven van de Beek</name>
53
+    <date format='dd-Mmm-yyyy'>16-Apr-2017</date>
54
+  </author>
55
+  <shortcuts>
56
+    <event code='mark_in' name='Mark In'>i</event>
57
+    <event code='mark_out' name='Mark Out'>o</event>
58
+    <event code='to_mark_in' name='Go To Mark In' modifiers='ALT'>i</event>
59
+    <event code='to_mark_in' name='Go To Mark In' modifiers='SHIFT'>i</event>
60
+    <event code='to_mark_in' name='Go To Mark In' modifiers='ALT+SHIFT'>i</event>
61
+    <event code='to_mark_out' name='Go To Mark Out' modifiers='ALT'>o</event>
62
+    <event code='to_mark_out' name='Go To Mark Out' modifiers='SHIFT'>o</event>
63
+    <event code='to_mark_out' name='Go To Mark Out' modifiers='ALT+SHIFT'>o</event>
64
+    <event code='play_pause' name='Play / Pause'>space</event>
65
+    <event code='prev_cut' name='Go To Previous Cut'>up</event>
66
+    <event code='next_cut' name='Go To Next Cut'>down</event>
67
+    <event code='prev_frame' name='Go To Previous Frame' modifiers='Any'>left</event>
68
+    <event code='next_frame' name='Go To Next Frame' modifiers='Any'>right</event>
69
+    <event code='insert' name='Insert'>y</event>
70
+    <event code='insert' name='Insert' modifiers='SHIFT'>y</event>
71
+    <event code='append' name='Append'>u</event>
72
+    <event code='append' name='Append' modifiers='SHIFT'>u</event>
73
+    <event code='slower' name='Slower'>j</event>
74
+    <event code='stop' name='Stop'>k</event>
75
+    <event code='faster' name='Faster'>l</event>
76
+    <event code='log_range' name='Log Range' modifiers='CTRL'>l</event>
77
+    <event code='log_range' name='Log Range'>g</event>
78
+    <event code='resync' name='Resynchronization'>s</event>
79
+    <event code='delete' name='Delete'>delete</event>
80
+    <event code='to_start' name='Go To Start'>home</event>
81
+    <event code='to_end' name='Go To End'>end</event>
82
+    <event code='3_point_overwrite' name='Three Point Overwrite'>t</event>
83
+    <event code='toggle_ripple' name='Toggle Ripple Mode'>r</event>
84
+    <event code='cut' name='Cut'>x</event>
85
+    <event code='edit_mode_insert' name='Change Edit Mode to Insert'>1</event>
86
+    <event code='edit_mode_insert' name='Change Edit Mode to Insert'>kp_1</event>
87
+    <event code='edit_mode_insert' name='Change Edit Mode to Insert'>kp_end</event>
88
+    <event code='edit_mode_overwrite' name='Change Edit Mode to Overwrite'>2</event>
89
+    <event code='edit_mode_overwrite' name='Change Edit Mode to Overwrite'>kp_2</event>
90
+    <event code='edit_mode_overwrite' name='Change Edit Mode to Overwrite'>kp_down</event>
91
+    <event code='edit_mode_trim' name='Change Edit Mode to Trim'>3</event>
92
+    <event code='edit_mode_trim' name='Change Edit Mode to Trim'>kp_3</event>
93
+    <event code='edit_mode_trim' name='Change Edit Mode to Trim'>kp_next</event>
94
+    <event code='edit_mode_roll' name='Change Edit Mode to Roll'>4</event>
95
+    <event code='edit_mode_roll' name='Change Edit Mode to Roll'>kp_4</event>
96
+    <event code='edit_mode_roll' name='Change Edit Mode to Roll'>kp_left</event>
97
+    <event code='edit_mode_slip' name='Change Edit Mode to Slip'>5</event>
98
+    <event code='edit_mode_slip' name='Change Edit Mode to Slip'>kp_5</event>
99
+    <event code='edit_mode_slip' name='Change Edit Mode to Slip'>kp_begin</event>
100
+    <event code='edit_mode_spacer' name='Change Edit Mode to Spacer'>6</event>
101
+    <event code='edit_mode_spacer' name='Change Edit Mode to Spacer'>kp_6</event>
102
+    <event code='edit_mode_spacer' name='Change Edit Mode to Spacer'>kp_right</event>
103
+    <event code='edit_mode_box' name='Change Edit Mode to Box'>7</event>
104
+    <event code='edit_mode_box' name='Change Edit Mode to Box'>kp_7</event>
105
+    <event code='edit_mode_box' name='Change Edit Mode to Box'>kp_home</event>
106
+    <event code='zoom_out' name='Zoom Out'>minus</event>
107
+    <event code='zoom_in' name='Zoom In'>equal</event>
108
+    <event code='zoom_in' name='Zoom In' modifiers='SHIFT'>equal</event>
109
+    <event code='switch_monitor' name='Switch Monitor Display'>tab</event>
110
+    <event code='add_marker' name='Add Marker'>m</event>
111
+    <event code='enter_edit' name='Enter Editing Mode'>return</event>
112
+  </shortcuts>
113
+</flowblade>
114
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/respaths.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/respaths.py Changed
26
 
1
@@ -45,12 +45,14 @@
2
 PHANTOM_JAR = None
3
 
4
 def set_paths(root_path):
5
+    # Apr-2017 - SvdB - Added SHORTCUTS_PATH for keyboard shortcuts files
6
     global ROOT_PATH, IMAGE_PATH, THUMBNAIL_PATH, PROFILE_PATH,\
7
     BLACK_IMAGE_PATH, FILTERS_XML_DOC, COMPOSITORS_XML_DOC, \
8
     WIPE_RESOURCES_PATH, PREFS_PATH, HELP_DOC, LOCALE_PATH, \
9
     GPL_3_DOC, ROOT_PARENT, PATTERN_PRODUCER_PATH, TRANSLATIONS_DOC, \
10
     LAUNCH_DIR, REPLACEMENTS_XML_DOC, GMIC_SCRIPTS_DOC,  \
11
-    PHANTOM_JAR, PHANTOM_DIR, DEVELOPERS_DOC, CONTRIBUTORS_DOC
12
+    PHANTOM_JAR, PHANTOM_DIR, DEVELOPERS_DOC, CONTRIBUTORS_DOC, \
13
+    SHORTCUTS_PATH
14
     
15
     ROOT_PATH = root_path
16
     IMAGE_PATH = root_path + "/res/img/"
17
@@ -72,6 +74,8 @@
18
     LAUNCH_DIR = root_path + "/launch/"
19
     GMIC_SCRIPTS_DOC = root_path + "/res/gmic/gmicscripts.xml"
20
     PHANTOM_JAR = root_path + "/phantom2d/Phantom2D.jar"
21
+    # Apr-2017 - SvdB
22
+    SHORTCUTS_PATH = root_path + "/res/shortcuts/"
23
 
24
 def apply_dark_theme():
25
     global IMAGE_PATH
26
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/sequence.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/sequence.py Changed
41
 
1
@@ -88,7 +88,7 @@
2
 AUDIO_MIX_DOWN_TRACK = 0
3
 
4
 # Vectorscop and RGB Parade
5
-SCOPE_MIX_VALUES = [1.0, 0.8, 0.5, 0.2, 0.0]
6
+SCOPE_MIX_VALUES = [0.0, 0.2, 0.5, 0.8, 1.0]
7
 _scope_over_lay_mix = 2
8
 
9
 class Sequence:
10
@@ -162,7 +162,7 @@
11
         0                                               black bg track
12
         1 - (self.first_video_index - 1)                audio tracks    
13
         self.first_video_index - (len(self.tracks) - 2) video tracks
14
-        (len(self.tracks) - 1)                          hidden track
15
+        (len(self.tracks) - 1)                          hidden track for trimmming
16
         
17
         Tracks are never changed after creation, changing tracks count feature is
18
         achieved by creating a new sequence.
19
@@ -325,6 +325,12 @@
20
             h += track.height
21
         return  h
22
 
23
+    def get_shrunk_tline_height_min(self):
24
+        UNSHRUNK_HEIGHT = appconsts.TLINE_HEIGHT
25
+        THREE_TRACK_MIN_HEIGHT = 3 * appconsts.TRACK_HEIGHT_NORMAL
26
+        PER_TRACK_ADD = ((UNSHRUNK_HEIGHT - THREE_TRACK_MIN_HEIGHT) / 6.0) * (len(self.tracks) - 5)
27
+        return int(THREE_TRACK_MIN_HEIGHT + PER_TRACK_ADD)
28
+
29
     def set_track_gain(self, track, gain):
30
         track.gain_filter.set("gain", str(gain))
31
         track.audio_gain = gain
32
@@ -836,7 +842,7 @@
33
                 # This shold not happen because track heights should be set up so that minimized app 
34
                 # has enough space to display all tracks.
35
                 # Yet it happens sometimes, meh.
36
-                print "sequence.resize_tracks_to_fit (): could not make panels fit"
37
+                print "sequence.resize_tracks_to_fit (): could not make tracks fit in timeline vertical space"
38
                 fix_next = False
39
             else:
40
                 self.tracks[1 + count].height = TRACK_HEIGHT_SMALL
41
flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/shortcuts.py Added
201
 
1
@@ -0,0 +1,267 @@
2
+"""
3
+    Flowblade Movie Editor is a nonlinear video editor.
4
+    Copyright 2013 Janne Liljeblad.
5
+
6
+    This file is part of Flowblade Movie Editor <http://code.google.com/p/flowblade>.
7
+
8
+    Flowblade Movie Editor is free software: you can redistribute it and/or modify
9
+    it under the terms of the GNU General Public License as published by
10
+    the Free Software Foundation, either version 3 of the License, or
11
+    (at your option) any later version.
12
+
13
+    Flowblade Movie Editor is distributed in the hope that it will be useful,
14
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+    GNU General Public License for more details.
17
+
18
+    You should have received a copy of the GNU General Public License
19
+    along with Flowblade Movie Editor.  If not, see <http://www.gnu.org/licenses/>.
20
+"""
21
+
22
+# Apr-2017 - SvdB - Functions to scan available shortcut files, validate and load them
23
+import appconsts
24
+import respaths
25
+import os
26
+import xml.etree.ElementTree as etree
27
+import editorpersistance
28
+import re
29
+
30
+
31
+DEFAULT_SHORTCUTS_FILE = "flowblade.xml"
32
+    
33
+shortcut_files = []
34
+shortcut_files_display_names = []
35
+_keyboard_actions = {}
36
+_keyboard_action_names = {}
37
+_key_names = {}
38
+_mod_names = {}
39
+
40
+
41
+def load_shortcut_files():
42
+    global shortcut_files, shortcut_files_display_names
43
+    default_shortcuts_file_found = False
44
+
45
+    for f in os.listdir(respaths.SHORTCUTS_PATH):
46
+        format_error = True
47
+
48
+        if f[-4:] == '.xml':
49
+            # We have a valid file name. Now inspect the file for a valid format before loading it
50
+            shortcuts = etree.parse(respaths.SHORTCUTS_PATH + f)
51
+            # Verify if the file has the right format
52
+            root = shortcuts.getroot()
53
+            # Check the 'tag' is flowblade
54
+            if root.tag == appconsts.SHORTCUTS_ROOT_TAG:
55
+                # Check if this is a shortcuts file
56
+                if root.get('file') == appconsts.SHORTCUTS_TAG:
57
+                    # Get name and comments
58
+                    file_len = len(f) - 4
59
+                    # Default file is added last to always be at index 0
60
+                    if f != DEFAULT_SHORTCUTS_FILE:
61
+                        shortcut_files.append(f)
62
+                        shortcut_files_display_names.append(root.get('name'))
63
+                        format_error = False
64
+                    else:
65
+                        # This is added below to index 0
66
+                        default_shortcuts_file_found = True
67
+                        format_error = False
68
+                        
69
+        else:
70
+            format_error = False
71
+            print "Shortcuts file " + f + " found, but ignored."
72
+
73
+        if format_error:
74
+            print "Shortcuts file " + f + " found, but has incorrect format."
75
+    
76
+    # Default shortcuts file always goes to index 0
77
+    if default_shortcuts_file_found == True:# this is a bit unneccceasy, it is there unless someone destroys it manually
78
+        shortcut_files.insert(0, DEFAULT_SHORTCUTS_FILE)
79
+        shortcut_files_display_names.insert(0, "Flowblade Default")
80
+
81
+    print "Valid shortcut files found: " + str(shortcut_files)
82
+
83
+# Apr-2017 - SvdB - keyboard shortcuts
84
+def load_shortcuts():
85
+    _set_keyboard_action_names()
86
+    _set_key_names()
87
+    set_keyboard_shortcuts()
88
+
89
+def set_keyboard_shortcuts():
90
+    global _keyboard_actions
91
+    prefs = editorpersistance.prefs
92
+    print "Keyboard shortcuts file:",  editorpersistance.prefs.shortcuts
93
+    _modifier_dict = {}
94
+
95
+    # Make sure that whatever is in preferences is a valid file. If it's not in shortcut_files it's not valid
96
+    if not prefs.shortcuts in shortcut_files:
97
+        #print "The shortcuts file selected in preferences is not valid: " + prefs.shortcuts
98
+        # print "Switching to defaults."
99
+        return
100
+    try:
101
+        shortcuts = etree.parse(respaths.SHORTCUTS_PATH + prefs.shortcuts)
102
+        # Verify if the file has the right format
103
+        root = shortcuts.getroot()
104
+        # Check the 'tag' is flowblade
105
+        if root.tag == appconsts.SHORTCUTS_ROOT_TAG:
106
+            # Check if this is a shortcuts file
107
+            if root.get('file') == appconsts.SHORTCUTS_TAG:
108
+                # Get name and comments
109
+                print "Loading shortcuts: " + root.get('name')
110
+                # We have good shortcuts file, destroy hardcoded defaults
111
+                _keyboard_actions = {}
112
+                # Now loop through all the events and assign them
113
+                events = root.getiterator('event')
114
+                for event in events:
115
+                    # Retrieve any previous _modifier_dict values
116
+                    try:
117
+                        _modifier_dict = _keyboard_actions[event.text]
118
+                    except:
119
+                        _modifier_dict = {}
120
+                    # Build up the _modifier_dict
121
+                    # NB: The text string representing the modifiers is sorted alphabetically and converted to lower
122
+                    # case. It is also stripped of spaces.
123
+                    # ''.join(sorted(string)) will return the sorted string (sorted returns an array, join converts
124
+                    # it to a string)
125
+                    # re.sub('[\s]','',string) will remove the spaces
126
+                    # .lower() will convert it all to lower space.
127
+                    # to easily compare with any entered combo of the modifiers. In fact, CTRL+ALT becomes the
128
+                    # same as ALT+CTRL and Alt+Ctrl- it will all be +acllrtt
129
+                    if event.get('modifiers') == None:
130
+                        _modifier_dict[''.join(sorted(re.sub('[\s]','','None'.lower())))] = event.get('code')
131
+                    else:
132
+                        _modifier_dict[''.join(sorted(re.sub('[\s]','',event.get('modifiers').lower())))] = event.get('code')
133
+                    _keyboard_actions[event.text] = _modifier_dict
134
+    except:
135
+        print "Error opening shortcuts file:" + prefs.shortcuts
136
+
137
+    #_print_shortcuts()
138
+
139
+def get_shortcuts_xml_root_node(xml_file):
140
+    try:
141
+        shortcuts = etree.parse(respaths.SHORTCUTS_PATH + xml_file)
142
+        return shortcuts.getroot()
143
+    except:
144
+        return None # This is handled at callsites
145
+
146
+def get_shortcut_info(root, code):
147
+    events = root.getiterator('event')
148
+    for event in events:
149
+        if event.get('code') == code:
150
+            return (_key_names[event.text], _get_mod_string(event) + _keyboard_action_names[code]) 
151
+    
152
+    return (None, None)
153
+
154
+def _get_mod_string(event):
155
+    mod = event.get("modifier")
156
+    if mod == "Any" or mod == None:
157
+        return ""
158
+    
159
+    return _mod_names[mod]
160
+ 
161
+def get_diff_to_defaults(xml_file):
162
+    diff_str = ""
163
+    test_root = get_shortcuts_xml_root_node(xml_file)
164
+    def_root = get_shortcuts_xml_root_node(DEFAULT_SHORTCUTS_FILE)
165
+    
166
+    for code, action_name in _keyboard_action_names.iteritems():
167
+        key_name_test, action_name = get_shortcut_info(test_root, code)
168
+        key_name_def, action_name = get_shortcut_info(def_root , code)
169
+    
170
+        if key_name_def != key_name_test:
171
+            diff_str = diff_str + action_name + " (" + key_name_test + ")    "
172
+    
173
+    return diff_str
174
+
175
+def _set_keyboard_action_names():
176
+    global _keyboard_action_names
177
+    # Start with an empty slate
178
+    _keyboard_action_names = {}
179
+    _keyboard_action_names['mark_in'] = _("Set Mark In")
180
+    _keyboard_action_names['mark_out'] =  _("Set Mark Out")
181
+    _keyboard_action_names['play_pause'] = _("Start / Stop Playback")
182
+    _keyboard_action_names['prev_cut'] = _("Prev Edit/Mark")
183
+    _keyboard_action_names['next_cut'] = _("Next Edit/Mark")
184
+    _keyboard_action_names['prev_frame'] =_("Prev Frame")
185
+    _keyboard_action_names['next_frame'] = _("Next Frame")
186
+    _keyboard_action_names['insert'] = _("Insert")
187
+    _keyboard_action_names['append'] =  _("Append")
188
+    _keyboard_action_names['slower'] = _("Backwards Faster")
189
+    _keyboard_action_names['stop'] = _("Stop")
190
+    _keyboard_action_names['faster'] =  _("Forward Faster")
191
+    _keyboard_action_names['log_range'] = _("Log Marked Clip Range")
192
+    _keyboard_action_names['resync'] = _("Resync selected Clip or Compositor")
193
+    _keyboard_action_names['delete'] = _("Delete Selected Item")
194
+    _keyboard_action_names['to_start'] = _("Go To Start")
195
+    _keyboard_action_names['to_end'] = _("Go To End")
196
+    _keyboard_action_names['3_point_overwrite'] = _("3 Point Overwrite")
197
+    _keyboard_action_names['toggle_ripple'] = _("Trim Tool Ripple Mode On/Off")
198
+    _keyboard_action_names['cut'] = _("Cut Clip")
199
+    _keyboard_action_names['edit_mode_insert'] = _("Insert")
200
+    _keyboard_action_names['edit_mode_overwrite'] =  _("Overwrite")
201
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/tlineaction.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/tlineaction.py Changed
201
 
1
@@ -30,6 +30,7 @@
2
 from operator import itemgetter
3
 
4
 import appconsts
5
+import boxmove
6
 import clipeffectseditor
7
 import compositeeditor
8
 import compositormodes
9
@@ -46,10 +47,12 @@
10
 from editorstate import get_track
11
 from editorstate import current_sequence
12
 from editorstate import PLAYER
13
+from editorstate import PROJECT
14
 from editorstate import timeline_visible
15
 from editorstate import MONITOR_MEDIA_FILE
16
 from editorstate import EDIT_MODE
17
 import movemodes
18
+import multimovemode
19
 import mlttransitions
20
 import render
21
 import renderconsumer
22
@@ -101,16 +104,22 @@
23
 # ---------------------------------- edit button events
24
 def cut_pressed():
25
     if not timeline_visible():
26
-        updater.display_sequence_in_monitor()
27
+        updater.display_sequence_in_monitor()   
28
+
29
+    # Disable whencut action when it cut clash with ongoing edits
30
+    if EDIT_MODE() == editorstate.ONE_ROLL_TRIM or EDIT_MODE() == editorstate.TWO_ROLL_TRIM or EDIT_MODE() == editorstate.SLIDE_TRIM:
31
+        return
32
 
33
-    if EDIT_MODE() == editorstate.ONE_ROLL_TRIM:
34
-        editevent.oneroll_trim_no_edit_init()
35
+    if EDIT_MODE() == editorstate.MULTI_MOVE and multimovemode.edit_data != None:
36
         return
37
 
38
-    if EDIT_MODE() == editorstate.TWO_ROLL_TRIM:
39
-        editevent.tworoll_trim_no_edit_init()
40
+    if EDIT_MODE() == editorstate.MULTI_MOVE and multimovemode.edit_data != None:
41
         return
42
         
43
+    if boxmove.box_selection_data != None:
44
+        return
45
+    
46
+    # Get cut frame
47
     tline_frame = PLAYER().current_frame()
48
 
49
     movemodes.clear_selected_clips()
50
@@ -385,16 +394,6 @@
51
     track = current_sequence().get_first_active_track()
52
     if editevent.track_lock_check_and_user_info(track, range_overwrite_pressed, "range overwrite"):
53
         return
54
-    
55
-    # tractor is has mark in and mark
56
-    mark_in_frame = current_sequence().tractor.mark_in
57
-    mark_out_frame = current_sequence().tractor.mark_out
58
-    range_length = mark_out_frame - mark_in_frame + 1 # end is incl.
59
-    if mark_in_frame == -1 or mark_out_frame == -1:
60
-        primary_txt = _("Timeline Range not set!")
61
-        secondary_txt = _("You need to set Timeline Range using Mark In and Mark Out buttons\nto perform this edit.")
62
-        dialogutils.info_message(primary_txt, secondary_txt, gui.editor_window.window)
63
-        return
64
 
65
     # Get over clip and check it overwrite range area
66
     over_clip = _get_new_clip_from_clip_monitor()
67
@@ -402,13 +401,46 @@
68
         no_monitor_clip_info(gui.editor_window.window)
69
         return
70
 
71
-    over_length = over_clip.mark_out - over_clip.mark_in + 1 # + 1 out incl
72
-    if over_length < range_length:
73
-        monitor_clip_too_short(gui.editor_window.window)
74
-        return
75
+    # tractor is has mark in and mark
76
+    mark_in_frame = current_sequence().tractor.mark_in
77
+    mark_out_frame = current_sequence().tractor.mark_out
78
+    
79
+    # Case timeline marked
80
+    if mark_in_frame != -1 and mark_out_frame != -1:
81
+        range_length = mark_out_frame - mark_in_frame + 1 # end is incl.
82
+        if over_clip.mark_in == -1:
83
+            # This actually never hit because mark in and mark out seem to first and last frame if nothing set
84
+            show_three_point_edit_not_defined()
85
+            return
86
 
87
-    over_clip_out = over_clip.mark_in + range_length - 1
88
+        over_length = over_clip.mark_out - over_clip.mark_in + 1 # + 1 out incl
89
+        if over_length < range_length:
90
+            monitor_clip_too_short(gui.editor_window.window)
91
+            return
92
 
93
+        over_clip_out = over_clip.mark_in + range_length - 1
94
+        
95
+    # Case clip marked
96
+    elif over_clip.mark_out != -1 and over_clip.mark_in != -1:
97
+        range_length = over_clip.mark_out - over_clip.mark_in + 1 # end is incl.
98
+        
99
+        if mark_in_frame == -1:
100
+            show_three_point_edit_not_defined()
101
+            return
102
+
103
+        over_length = track.get_length() - mark_in_frame + 1 # + 1 out incl
104
+        if over_length < range_length:
105
+            monitor_clip_too_short(gui.editor_window.window)
106
+            return
107
+            
108
+        over_clip_out = over_clip.mark_out
109
+        mark_out_frame = mark_in_frame + range_length - 1 # -1 because it gets readded later
110
+        
111
+    # case neither clip or timeline has both in and out points
112
+    else:
113
+        show_three_point_edit_not_defined()
114
+        return
115
+        
116
     movemodes.clear_selected_clips() # edit consumes selection
117
 
118
     updater.save_monitor_frame = False # hack to not get wrong value saved in MediaFile.current_frame
119
@@ -426,6 +458,11 @@
120
 
121
     updater.display_tline_cut_frame(track, track.get_clip_index_at(mark_in_frame))
122
 
123
+def _show_three_poimt_edit_not_defined():
124
+    primary_txt = _("3 point edit not defined!")
125
+    secondary_txt = _("You need to set Timeline Range using Mark In and Mark Out buttons\nto perform this edit.")
126
+    dialogutils.info_message(primary_txt, secondary_txt, gui.editor_window.window)
127
+            
128
 def delete_range_button_pressed():
129
     # Get data
130
     #track = current_sequence().get_first_active_track()
131
@@ -486,10 +523,50 @@
132
     clip_index = track.clips.index(origin_clip)
133
     clip_start = track.clip_start(clip_index)
134
     clip_end = clip_start + origin_clip.clip_out - origin_clip.clip_in
135
+    
136
+    # Auto fades need to go to start or end of clips and maintain their lengths
137
+    if compositor.transition.info.auto_fade_compositor == True:
138
+        if compositor.transition.info.name == "##auto_fade_in":
139
+            clip_end = clip_start + compositor.get_length() - 1
140
+        else:
141
+            clip_start = clip_end - compositor.get_length() + 1
142
+            
143
     data = {"compositor":compositor,"clip_in":clip_start,"clip_out":clip_end}
144
     action = edit.move_compositor_action(data)
145
     action.do_edit()
146
+        
147
+def set_compositors_fades_defaults():
148
+    dialogs.set_fades_defaults_dialog(_compositors_fades_defaults_callback)
149
+
150
+def _compositors_fades_defaults_callback(dialog, response_id, widgets):
151
+    group_select, fade_in_check, fade_in_spin, fade_out_check, fade_out_spin, fade_in_length_label, fade_out_length_label = widgets
152
     
153
+    group = group_select.get_active()
154
+    fade_in_on = fade_in_check.get_active()
155
+    fade_in_length = int(fade_in_spin.get_value())
156
+    fade_out_on = fade_out_check.get_active()
157
+    fade_out_length = int(fade_out_spin.get_value())
158
+
159
+    dialog.destroy()
160
+    
161
+    if group == 0:
162
+        fade_in_key = appconsts.P_PROP_DISSOLVE_GROUP_FADE_IN
163
+        fade_out_key = appconsts.P_PROP_DISSOLVE_GROUP_FADE_OUT
164
+    else:
165
+        fade_in_key = appconsts.P_PROP_ANIM_GROUP_FADE_IN
166
+        fade_out_key = appconsts.P_PROP_ANIM_GROUP_FADE_OUT
167
+
168
+    if fade_in_on == False or fade_in_length == 0:
169
+        PROJECT().set_project_property(fade_in_key, -1)
170
+    else:
171
+        PROJECT().set_project_property(fade_in_key, fade_in_length)
172
+        
173
+    if fade_out_on == False or fade_out_length == 0:
174
+        PROJECT().set_project_property(fade_out_key, -1)
175
+    else:
176
+        PROJECT().set_project_property(fade_out_key, fade_out_length)
177
+
178
+
179
 def split_audio_button_pressed():
180
     if movemodes.selected_track == -1:
181
         return
182
@@ -505,30 +582,44 @@
183
     syncsplitevent.split_audio_from_clips_list(clips, track)
184
 
185
 def sync_all_compositors():
186
-    # Pair all compositors with their origin clips and clip data
187
+    # Pair all compositors with their origin clips ids
188
     comp_clip_pairings = {}
189
     for compositor in current_sequence().compositors:
190
-        comp_clip_pairings[compositor.origin_clip_id] = compositor
191
+        if compositor.origin_clip_id in comp_clip_pairings:
192
+            comp_clip_pairings[compositor.origin_clip_id].append(compositor)
193
+        else:
194
+            comp_clip_pairings[compositor.origin_clip_id] = [compositor]
195
     
196
+    # Create resync list
197
+    resync_list = []
198
     for i in range(current_sequence().first_video_index, len(current_sequence().tracks) - 1): # -1, there is a topmost hidden track 
199
         track = current_sequence().tracks[i] # b_track is source track where origin clip is
200
         for j in range(0, len(track.clips)):
201
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/tlinewidgets.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/tlinewidgets.py Changed
201
 
1
@@ -56,7 +56,7 @@
2
 REF_LINE_Y = 250 # Y pos of tracks are relative to this. This is recalculated on initilization, so value here is irrelevent.
3
 
4
 WIDTH = 430 # this has no effect if smaller then editorwindow.NOTEBOOK_WIDTH + editorwindow.MONITOR_AREA_WIDTH
5
-HEIGHT = 260 # defines window min height together with editorwindow.TOP_ROW_HEIGHT
6
+HEIGHT = appconsts.TLINE_HEIGHT # defines window min height together with editorwindow.TOP_ROW_HEIGHT
7
 
8
 # Timeline draw constants
9
 # Other elements than black outline are not drawn if clip screen size
10
@@ -335,6 +335,28 @@
11
         BG_COLOR = (0.44, 0.44, 0.46)
12
         FRAME_SCALE_LINES = (0.8, 0.8, 0.8)
13
 
14
+def set_tracks_double_height_consts():
15
+    global ID_PAD_Y, ID_PAD_Y_SMALL, VIDEO_TRACK_V_ICON_POS, VIDEO_TRACK_A_ICON_POS, VIDEO_TRACK_V_ICON_POS_SMALL, VIDEO_TRACK_A_ICON_POS_SMALL, \
16
+    AUDIO_TRACK_ICON_POS, AUDIO_TRACK_ICON_POS_SMALL, MUTE_ICON_POS, MUTE_ICON_POS_NORMAL, LOCK_POS, INSRT_ICON_POS, INSRT_ICON_POS_SMALL, \
17
+    WAVEFORM_PAD_LARGE, WAVEFORM_PAD_SMALL, HEIGHT
18
+    
19
+    HEIGHT = appconsts.TLINE_HEIGHT
20
+    ID_PAD_Y = 41
21
+    ID_PAD_Y_SMALL = 16
22
+    VIDEO_TRACK_V_ICON_POS = (5, 41)
23
+    VIDEO_TRACK_A_ICON_POS = (5, 50)
24
+    VIDEO_TRACK_V_ICON_POS_SMALL = (5, 16)
25
+    VIDEO_TRACK_A_ICON_POS_SMALL = (5, 25) 
26
+    AUDIO_TRACK_ICON_POS = (5, 43)
27
+    AUDIO_TRACK_ICON_POS_SMALL = (5, 18)
28
+    MUTE_ICON_POS = (5, 14)
29
+    MUTE_ICON_POS_NORMAL = (5, 39)
30
+    LOCK_POS = (67, 2)
31
+    INSRT_ICON_POS = (81, 43)
32
+    INSRT_ICON_POS_SMALL =  (81, 18)
33
+    WAVEFORM_PAD_LARGE = 77
34
+    WAVEFORM_PAD_SMALL = 33
35
+
36
 def set_dark_bg_color():
37
     if editorpersistance.prefs.dark_theme == False:
38
         return
39
@@ -646,6 +668,13 @@
40
         cr.line_to(draw_x, draw_y + size)
41
         cr.close_path()
42
         cr.fill()
43
+
44
+        if editorpersistance.prefs.delta_overlay == True:
45
+            delta = data["delta"]       
46
+            tc_str = utils.get_tc_string_short(abs(delta))
47
+            tc_str = _get_signed_tc_str(tc_str, delta)
48
+                
49
+            _draw_text_info_box(cr, x, y - 12, tc_str)
50
         
51
 def _draw_move_overlay(cr, data, y):
52
     # Get data
53
@@ -656,7 +685,8 @@
54
     track_height = data["to_track_object"].height
55
 
56
     # Get first frame for drawing shadow clips
57
-    draw_start = first_clip_start + (current_frame - press_frame)
58
+    delta = current_frame - press_frame
59
+    draw_start = first_clip_start + delta
60
     clip_start_frame = draw_start - pos
61
         
62
     # Draw clips in draw range
63
@@ -673,6 +703,14 @@
64
         # Start frame for next clip
65
         clip_start_frame += clip_length
66
 
67
+    if editorpersistance.prefs.delta_overlay == True:
68
+        x = (draw_start - pos) * pix_per_frame
69
+        
70
+        tc_str = utils.get_tc_string_short(abs(delta))
71
+        tc_str = _get_signed_tc_str(tc_str, delta)
72
+            
73
+        _draw_text_info_box(cr, x, y - 12, tc_str)
74
+
75
 def draw_multi_overlay(cr, data):
76
     if data == None:
77
         return
78
@@ -741,6 +779,13 @@
79
             cr.fill()
80
 
81
     y = _get_track_y(current_sequence().first_video_index)
82
+
83
+    if editorpersistance.prefs.delta_overlay == True:        
84
+        tc_str = utils.get_tc_string_short(abs(delta))
85
+        tc_str = _get_signed_tc_str(tc_str, delta)
86
+            
87
+        _draw_text_info_box(cr, draw_x, y - 12, tc_str)
88
+    
89
     _draw_snap(cr, y)
90
     
91
 def draw_two_roll_overlay(cr, data):
92
@@ -805,9 +850,16 @@
93
     cr.line_to(selection_frame_x - radius - bit, track_y + track_height)
94
     cr.stroke()
95
 
96
+    if editorpersistance.prefs.delta_overlay == True:
97
+        delta = data["selected_frame"] - data["edit_frame"]        
98
+        tc_str = utils.get_tc_string_short(abs(delta))
99
+        tc_str = _get_signed_tc_str(tc_str, delta)
100
+            
101
+        _draw_text_info_box(cr, selection_frame_x + 3, track_y - 12, tc_str)
102
+
103
     _draw_kb_trim_indicator(cr, selection_frame_x, track_y)
104
     _draw_snap(cr, track_y)
105
-
106
+    
107
 def draw_one_roll_overlay(cr, data):
108
     track_height = current_sequence().tracks[data["track"]].height
109
     track_y = _get_track_y(data["track"])
110
@@ -867,6 +919,13 @@
111
         cr.line_to(selection_frame_x - radius - bit, track_y + track_height)
112
     cr.stroke()
113
 
114
+    if editorpersistance.prefs.delta_overlay == True:
115
+        delta = data["selected_frame"] - data["edit_frame"]        
116
+        tc_str = utils.get_tc_string_short(abs(delta))
117
+        tc_str = _get_signed_tc_str(tc_str, delta)
118
+            
119
+        _draw_text_info_box(cr, selection_frame_x + 3, track_y - 12, tc_str)
120
+
121
     _draw_kb_trim_indicator(cr, selection_frame_x, track_y)
122
     _draw_snap(cr, track_y)
123
     
124
@@ -985,7 +1044,14 @@
125
     cr.paint()
126
 
127
     _draw_kb_trim_indicator(cr, x, track_y)
128
-    
129
+
130
+    if editorpersistance.prefs.delta_overlay == True:
131
+        delta = data["mouse_delta"]  
132
+        tc_str = utils.get_tc_string_short(abs(delta))
133
+        tc_str = _get_signed_tc_str(tc_str, delta)
134
+            
135
+        _draw_text_info_box(cr, clip_start_frame_x + 3, track_y - 12, tc_str)
136
+        
137
 def draw_clip_end_drag_overlay(cr, data):
138
     if data["editing_clip_end"] == True:
139
         end = data["frame"]  - pos
140
@@ -1008,8 +1074,21 @@
141
     cr.rectangle(scale_in, int(y) + 1.5, int(scale_length), track_height - 2.0)
142
     cr.stroke()
143
 
144
-    _draw_snap(cr, y)
145
+    if editorpersistance.prefs.delta_overlay == True:
146
+        if data["editing_clip_end"] == True:
147
+            x = scale_in + scale_length
148
+            delta = data["frame"] - data["orig_out"]
149
+        else:
150
+            x = scale_in
151
+            delta = data["frame"] - data["orig_in"]  - 1
152
+            
153
+        tc_str = utils.get_tc_string_short(abs(delta))
154
+        tc_str = _get_signed_tc_str(tc_str, delta)
155
+
156
+        _draw_text_info_box(cr, x - 3, y - 12, tc_str)
157
     
158
+    _draw_snap(cr, y)
159
+            
160
 def draw_compositor_move_overlay(cr, data):
161
     # Get data
162
     press_frame = data["press_frame"]
163
@@ -1033,8 +1112,15 @@
164
     cr.set_source_rgb(*OVERLAY_COLOR)
165
     cr.stroke()
166
 
167
+    if editorpersistance.prefs.delta_overlay == True:
168
+        delta = current_frame - press_frame
169
+        tc_str = utils.get_tc_string_short(abs(delta))
170
+        tc_str = _get_signed_tc_str(tc_str, delta)
171
+            
172
+        _draw_text_info_box(cr, scale_in, y - 12, tc_str)
173
+    
174
     _draw_snap(cr, y)
175
-
176
+        
177
 def draw_compositor_trim(cr, data):
178
     clip_in = data["clip_in"]
179
     clip_out = data["clip_out"]
180
@@ -1057,10 +1143,21 @@
181
     
182
     if data["trim_is_clip_in"] == True:
183
         x = scale_in + 2
184
+        delta = data["clip_in"] - data["orig_clip_in"]
185
+        info_x = scale_in - 3
186
     else:
187
         x = scale_in + scale_length - 26
188
+        delta = data["clip_out"] - data["orig_clip_out"]
189
+        info_x = scale_in + + scale_length - 3
190
+
191
     _draw_two_arrows(cr, x, y + 4, 4)
192
 
193
+    if editorpersistance.prefs.delta_overlay == True:
194
+        tc_str = utils.get_tc_string_short(abs(delta))
195
+        tc_str = _get_signed_tc_str(tc_str, delta)
196
+            
197
+        _draw_text_info_box(cr, info_x, y - 12, tc_str)
198
+
199
     _draw_snap(cr, y)
200
     
201
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/tools/batchrendering.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/tools/batchrendering.py Changed
52
 
1
@@ -1170,9 +1170,18 @@
2
 
3
         producer = project.c_seq.tractor
4
         profile = mltprofiles.get_profile(render_item.render_data.profile_name)
5
-        consumer = renderconsumer.get_mlt_render_consumer(render_item.render_path, 
6
-                                                          profile,
7
-                                                          render_item.args_vals_list)
8
+        
9
+        vcodec = self.get_vcodec(render_item)
10
+        if self.is_frame_sequence_render(vcodec) == True:
11
+            # Frame sequence render
12
+            consumer = renderconsumer.get_img_seq_render_consumer_codec_ext(render_item.render_path,
13
+                                                                             profile,  
14
+                                                                             vcodec, 
15
+                                                                             self.get_frame_seq_ext(vcodec))
16
+        else: # All other renders
17
+            consumer = renderconsumer.get_mlt_render_consumer(render_item.render_path, 
18
+                                                              profile,
19
+                                                              render_item.args_vals_list)
20
 
21
         # Get render range
22
         start_frame, end_frame, wait_for_stop_render = get_render_range(render_item)
23
@@ -1221,7 +1230,27 @@
24
         single_render_thread = None
25
         # Update view for render end
26
         GLib.idle_add(_single_render_shutdown)
27
-                    
28
+
29
+    def is_frame_sequence_render(self, vcodec):
30
+        if vcodec in ["png","bmp","dpx","ppm","targa","tiff"]:
31
+            return True
32
+
33
+        return False
34
+
35
+    def get_vcodec(self, render_item):
36
+        for arg_val in render_item.args_vals_list:
37
+            arg, val = arg_val
38
+            if arg == "vcodec":
39
+                return val
40
+        
41
+        return None
42
+            
43
+    def get_frame_seq_ext(self, vcodec):
44
+        if vcodec == "targa":
45
+            return "tga"
46
+        else:
47
+            return vcodec
48
+
49
     def abort(self):
50
         self.running = False
51
 
52
flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/tools/clapperless.py Added
201
 
1
@@ -0,0 +1,368 @@
2
+#!/usr/bin/env python
3
+# -*- encoding: utf-8 -*-
4
+
5
+# clapperless -- automatic find sync offsets for multi source recordings
6
+# Copyright (c) 2013, Martin Schitter <ms@mur.at>
7
+#
8
+# this code is based on an implementation written for PiTiVi 
9
+# by Benjamin M. Schwartz <bens@alum.mit.edu>
10
+# http://git.pitivi.org/?p=pitivi.git;a=blob;f=pitivi/autoaligner.py
11
+#
12
+# with some minor modifications for use in Flowblade by janne Liljeblad in 2017
13
+#
14
+# This program is free software: you can redistribute it and/or modify
15
+# it under the terms of the GNU General Public License as published by
16
+# the Free Software Foundation, either version 3 of the License, or
17
+# (at your option) any later version.
18
+#
19
+# This program is distributed in the hope that it will be useful,
20
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
21
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
+# GNU General Public License for more details.
23
+#
24
+# You should have received a copy of the GNU General Public License
25
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
26
+
27
+import logging, time, struct, subprocess, sys, os, array, argparse
28
+import stat, tempfile, hashlib, re
29
+import numpy
30
+
31
+import utils
32
+
33
+OFFSETS_DATA_FILE = "audio_offsets_data"
34
+OFFSETS_DATA_FILE_ID_DEFAULT = "idstr_default"
35
+
36
+__version__ = "0.99.8"
37
+
38
+"""
39
+Algorithms for aligning (i.e. registering, synchronizing) time series
40
+"""
41
+
42
+## BLOCKRATE set by the comand line option --rate
43
+"""
44
+@ivar BLOCKRATE: The number of amplitude blocks per second.
45
+
46
+The AutoAligner works by computing the "amplitude envelope" of each
47
+audio stream. We define an amplitude envelope as the absolute value
48
+of the audio samples, downsampled to a low samplerate. This
49
+samplerate, in Hz, is given by BLOCKRATE. (It is given this name
50
+because the downsampling filter is implemented by very simple
51
+averaging over blocks, i.e. a box filter.) 25 Hz appears to be a
52
+good choice because it evenly divides all common audio samplerates
53
+(e.g. 11025 and 8000). Lower blockrate requires less CPU time but
54
+produces less accurate alignment. Higher blockrate is the reverse
55
+(and also cannot evenly divide all samplerates).
56
+
57
+"""
58
+
59
+def nextpow2(x):
60
+    a = 1
61
+    while a < x:
62
+        a *= 2
63
+    return a
64
+
65
+
66
+def submax(left, middle, right):
67
+    """
68
+    Find the maximum of a quadratic function from three samples.
69
+
70
+    Given samples from a quadratic P(x) at x=-1, 0, and 1, find the x
71
+    that extremizes P.  This is useful for determining the subsample
72
+    position of the extremum given three samples around the observed
73
+    extreme.
74
+
75
+    @param left: value at x=-1
76
+    @type left: L{float}
77
+    @param middle: value at x=0
78
+    @type middle: L{float}
79
+    @param right: value at x=1
80
+    @type right: L{float}
81
+    @returns: value of x that extremizes the interpolating quadratic
82
+    @rtype: L{float}
83
+
84
+    """
85
+    L = middle - left   # L and R are both positive if middle is the
86
+    R = middle - right  # observed max of the integer samples
87
+    return 0.5 * (R - L) / (R + L)
88
+    # Derivation: Consider a quadratic q(x) := P(0) - P(x).  Then q(x) has
89
+    # two roots, one at 0 and one at z, and the extreme is at (0+z)/2
90
+    # (i.e. at z/2)
91
+    # q(x) = bx*(x-z) # a may be positive or negative
92
+    # q(1) = b*(1 - z) = R
93
+    # q(-1) = b*(1 + z) = L
94
+    # (1+z)/(1-z) = L/R  (from here it's just algebra to find a)
95
+    # z + 1 = R/L - (R/L)*z
96
+    # z*(1+R/L) = R/L - 1
97
+    # z = (R/L - 1)/(R/L + 1) = (R-L)/(R+L)
98
+
99
+
100
+def rigidalign(reference, targets):
101
+    """
102
+    Estimate the relative shift between reference and targets.
103
+
104
+    The algorithm works by subtracting the mean, and then locating
105
+    the maximum of the cross-correlation.  For inputs of length M{N},
106
+    the running time is M{O(C{len(targets)}*N*log(N))}.
107
+
108
+    @param reference: the waveform to regard as fixed
109
+    @type reference: Sequence(Number)
110
+    @param targets: the waveforms that should be aligned to reference
111
+    @type targets: Sequence(Sequence(Number))
112
+    @returns: The shift necessary to bring each target into alignment
113
+        with the reference.  The returned shift may not be an integer,
114
+        indicating that the best alignment would be achieved by a
115
+        non-integer shift and appropriate interpolation.
116
+    @rtype: Sequence(Number)
117
+
118
+    """
119
+    # L is the maximum size of a cross-correlation between the
120
+    # reference and any of the targets.
121
+    L = len(reference) + max(len(t) for t in targets) - 1
122
+    # We round up L to the next power of 2 for speed in the FFT.
123
+    L = nextpow2(L)
124
+    reference = reference - numpy.mean(reference)
125
+    fref = numpy.fft.rfft(reference, L).conj()
126
+    shifts = []
127
+    for t in targets:
128
+        t = t - numpy.mean(t)
129
+        # Compute cross-correlation
130
+        xcorr = numpy.fft.irfft(fref * numpy.fft.rfft(t, L))
131
+        # shift maximizes dotproduct(t[shift:],reference)
132
+        # int() to convert numpy.int32 to python int
133
+        shift = int(numpy.argmax(xcorr))
134
+        subsample_shift = submax(xcorr[(shift - 1) % L],
135
+                                 xcorr[shift],
136
+                                 xcorr[(shift + 1) % L])
137
+        shift = shift + subsample_shift
138
+        # shift is now a float indicating the interpolated maximum
139
+        if shift >= len(t):  # Negative shifts appear large and positive
140
+            shift -= L       # This corrects them to be negative
141
+        shifts.append(-shift)
142
+        # Sign reversed to move the target instead of the reference
143
+    return shifts
144
+
145
+class Envelope:
146
+    
147
+    def __init__(self, filename, args):
148
+        
149
+        "read and generate envelope for filename" 
150
+        
151
+        self.args = args
152
+        self.envelope = None
153
+
154
+        # handle time slice
155
+        parts = re.findall(r'(^[^[]+|\[.*?\])', filename)
156
+        if len(parts) == 2:
157
+            ss = parts[-1][1:-1]
158
+            duration = 0
159
+        elif len(parts) > 2:
160
+            ss = parts[-2][1:-1]
161
+            duration = parts[-1][1:-1]
162
+        else:
163
+            ss = 0
164
+            duration = 0
165
+
166
+        self.filename = parts[0]
167
+        
168
+        # use filename with optionale time slice info for caching
169
+        if args.use_cache:
170
+            self.read_cache(filename)
171
+        if self.envelope:
172
+            return
173
+
174
+        logging.info("read file: %s" % filename)
175
+
176
+        ffmpeg_call = ["ffmpeg"]
177
+        
178
+        if ss:
179
+            ffmpeg_call += ["-ss", ss]
180
+        if duration:
181
+            ffmpeg_call += ["-t", duration]
182
+            
183
+        ffmpeg_call += ["-i", self.filename,
184
+                        "-vn",      # Drop any video streams if there are any
185
+                        "-ac", "1", # mix down to mono
186
+                        "-f:a", "wav",
187
+                        "-sample_fmt", "s16",
188
+                        "-loglevel", "error",
189
+                        "-" ]
190
+
191
+        try:
192
+            logging.debug('ffmpeg call: "%s"' % ffmpeg_call)
193
+            sp = subprocess.Popen(ffmpeg_call,
194
+                                  bufsize=-1,
195
+                                  stdout=subprocess.PIPE,
196
+                                  # stderr=open(os.devnull)
197
+                                  )                
198
+        except:
199
+            logging.error("could not start 'ffmpeg' subprocess") 
200
+            sys.exit(2)
201
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/tools/titler.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/tools/titler.py Changed
201
 
1
@@ -123,15 +123,26 @@
2
         self.font_family = "Times New Roman"
3
         self.font_face = FACE_REGULAR
4
         self.font_size = 15
5
+        self.fill_on = True
6
         self.color_rgba = (1.0, 1.0, 1.0, 1.0) 
7
         self.alignment = ALIGN_LEFT
8
         self.pixel_size = (100, 100)
9
         self.spacing = 5
10
+        
11
+        self.outline_on = False
12
+        self.outline_color_rgba = (0.3, 0.3, 0.3, 1.0) 
13
+        self.outline_width = 2
14
+
15
+        self.shadow_on = False
16
+        self.shadow_color_rgb = (0.0, 0.0, 0.0) 
17
+        self.shadow_opacity = 100
18
+        self.shadow_xoff = 3
19
+        self.shadow_yoff = 3
20
+        self.shadow_blur = 0.0 # not impl yet, for future so that we don't need to break save format again
21
+        
22
         self.pango_layout = None # PangoTextLayout(self)
23
 
24
-        self.drop_shadow = None # future feature, here to keep file compat once added
25
-        self.animation = None # future feature
26
-        self.layer_attributes = None # future feature (kerning etc. go here, we're not using all pango features)
27
+        self.layer_attributes = None # future feature 
28
         self.visible = True
29
 
30
     def get_font_desc_str(self):
31
@@ -304,7 +315,8 @@
32
         self.color_button.connect("color-set", self._edit_value_changed)
33
         self.fill_on = Gtk.CheckButton()
34
         self.fill_on.set_active(True)
35
-        
36
+        self.fill_on.connect("toggled", self._edit_value_changed)
37
+
38
         buttons_box = Gtk.HBox()
39
         buttons_box.pack_start(Gtk.Label(), True, True, 0)
40
         buttons_box.pack_start(self.bold_font, False, False, 0)
41
@@ -316,22 +328,25 @@
42
         buttons_box.pack_start(guiutils.pad_label(15, 5), False, False, 0)
43
         buttons_box.pack_start(self.color_button, False, False, 0)
44
         buttons_box.pack_start(guiutils.pad_label(2, 1), False, False, 0)
45
-        #buttons_box.pack_start(self.fill_on, False, False, 0)
46
+        buttons_box.pack_start(self.fill_on, False, False, 0)
47
         buttons_box.pack_start(Gtk.Label(), True, True, 0)
48
 
49
-        outline_label = Gtk.Label(_("Outline"))
50
-        outline_size = Gtk.Label(_("Size"))
51
+        outline_label = Gtk.Label(_("<b>Outline</b>"))
52
+        outline_label.set_use_markup(True)
53
+        outline_size = Gtk.Label(_("Size:"))
54
         
55
         self.out_line_color_button = Gtk.ColorButton.new_with_rgba(Gdk.RGBA(red=0.3, green=0.3, blue=0.3, alpha=1.0))
56
-        #self.color_button.connect("color-set", self._edit_value_changed)
57
-        adj = Gtk.Adjustment(float(DEFAULT_FONT_SIZE), float(1), float(300), float(1))
58
+        self.out_line_color_button.connect("color-set", self._edit_value_changed)
59
+        
60
+        adj2 = Gtk.Adjustment(float(3), float(1), float(50), float(1))
61
         self.out_line_size_spin = Gtk.SpinButton()
62
-        self.out_line_size_spin.set_adjustment(adj)
63
+        self.out_line_size_spin.set_adjustment(adj2)
64
         self.out_line_size_spin.connect("changed", self._edit_value_changed)
65
         self.out_line_size_spin.connect("key-press-event", self._key_pressed_on_widget)
66
 
67
         self.outline_on = Gtk.CheckButton()
68
         self.outline_on.set_active(False)
69
+        self.outline_on.connect("toggled", self._edit_value_changed)
70
         
71
         outline_box = Gtk.HBox()
72
         outline_box.pack_start(outline_label, False, False, 0)
73
@@ -345,31 +360,37 @@
74
         outline_box.pack_start(self.outline_on, False, False, 0)
75
         outline_box.pack_start(Gtk.Label(), True, True, 0)
76
 
77
-        shadow_label = Gtk.Label(_("Shadow"))
78
-        shadow_opacity_label = Gtk.Label(_("Opacity"))
79
-        shadow_xoff = Gtk.Label(_("X Off"))
80
-        shadow_yoff = Gtk.Label(_("Y Off"))
81
+        shadow_label = Gtk.Label(_("<b>Shadow</b>"))
82
+        shadow_label.set_use_markup(True)
83
+        shadow_opacity_label = Gtk.Label(_("Opacity:"))
84
+        shadow_xoff = Gtk.Label(_("X Off:"))
85
+        shadow_yoff = Gtk.Label(_("Y Off:"))
86
         
87
         self.shadow_opa_spin = Gtk.SpinButton()
88
-        self.shadow_opa_spin.set_adjustment(adj)
89
+        adj3 = Gtk.Adjustment(float(100), float(1), float(100), float(1))
90
+        self.shadow_opa_spin.set_adjustment(adj3)
91
         self.shadow_opa_spin.connect("changed", self._edit_value_changed)
92
         self.shadow_opa_spin.connect("key-press-event", self._key_pressed_on_widget)
93
 
94
         self.shadow_xoff_spin = Gtk.SpinButton()
95
-        self.shadow_xoff_spin.set_adjustment(adj)
96
+        adj4 = Gtk.Adjustment(float(3), float(1), float(100), float(1))
97
+        self.shadow_xoff_spin.set_adjustment(adj4)
98
         self.shadow_xoff_spin.connect("changed", self._edit_value_changed)
99
         self.shadow_xoff_spin.connect("key-press-event", self._key_pressed_on_widget)
100
 
101
         self.shadow_yoff_spin = Gtk.SpinButton()
102
-        self.shadow_yoff_spin.set_adjustment(adj)
103
+        adj5 = Gtk.Adjustment(float(3), float(1), float(100), float(1))
104
+        self.shadow_yoff_spin.set_adjustment(adj5)
105
         self.shadow_yoff_spin.connect("changed", self._edit_value_changed)
106
         self.shadow_yoff_spin.connect("key-press-event", self._key_pressed_on_widget)
107
 
108
         self.shadow_on = Gtk.CheckButton()
109
         self.shadow_on.set_active(False)
110
-
111
-        self.shadow_color_button = Gtk.ColorButton.new_with_rgba(Gdk.RGBA(red=0.3, green=0.3, blue=0.3, alpha=1.0))
112
+        self.shadow_on.connect("toggled", self._edit_value_changed)
113
         
114
+        self.shadow_color_button = Gtk.ColorButton.new_with_rgba(Gdk.RGBA(red=0.3, green=0.3, blue=0.3, alpha=1.0))
115
+        self.shadow_color_button.connect("color-set", self._edit_value_changed)
116
+
117
         shadow_box_1 = Gtk.HBox()
118
         shadow_box_1.pack_start(shadow_label, False, False, 0)
119
         shadow_box_1.pack_start(guiutils.pad_label(15, 1), False, False, 0)
120
@@ -468,11 +489,11 @@
121
         controls_panel_2.pack_start(scroll_frame, True, True, 0)
122
         controls_panel_2.pack_start(font_main_row, False, False, 0)
123
         controls_panel_2.pack_start(buttons_box, False, False, 0)
124
-        #controls_panel_2.pack_start(guiutils.pad_label(40, 1), False, False, 0)
125
-        #controls_panel_2.pack_start(outline_box, False, False, 0)
126
-        #controls_panel_2.pack_start(guiutils.pad_label(40, 1), False, False, 0)
127
-        #controls_panel_2.pack_start(shadow_box_1, False, False, 0)
128
-        #controls_panel_2.pack_start(shadow_box_2, False, False, 0)
129
+        controls_panel_2.pack_start(guiutils.pad_label(40, 1), False, False, 0)
130
+        controls_panel_2.pack_start(outline_box, False, False, 0)
131
+        controls_panel_2.pack_start(guiutils.pad_label(40, 1), False, False, 0)
132
+        controls_panel_2.pack_start(shadow_box_1, False, False, 0)
133
+        controls_panel_2.pack_start(shadow_box_2, False, False, 0)
134
         
135
         controls_panel = Gtk.VBox()
136
         controls_panel.pack_start(guiutils.get_named_frame(_("Active Layer"),controls_panel_2), True, True, 0)
137
@@ -842,7 +863,28 @@
138
         r, g, b = utils.hex_to_rgb(color.to_string())
139
         new_color = (r/65535.0, g/65535.0, b/65535.0, 1.0)        
140
         _titler_data.active_layer.color_rgba = new_color
141
+        _titler_data.active_layer.fill_on = self.fill_on.get_active()
142
+        
143
+        # OUTLINE
144
+        color = self.out_line_color_button.get_color()
145
+        r, g, b = utils.hex_to_rgb(color.to_string())
146
+        new_color2 = (r/65535.0, g/65535.0, b/65535.0, 1.0)    
147
+        _titler_data.active_layer.outline_color_rgba = new_color2
148
+        _titler_data.active_layer.outline_on = self.outline_on.get_active()
149
+        _titler_data.active_layer.outline_width = self.out_line_size_spin.get_value()
150
 
151
+        
152
+        # SHADOW
153
+        color = self.shadow_color_button.get_color()
154
+        r, g, b = utils.hex_to_rgb(color.to_string())
155
+        a = self.shadow_opa_spin.get_value() / 100.0
156
+        new_color3 = (r/65535.0, g/65535.0, b/65535.0)  
157
+        _titler_data.active_layer.shadow_color_rgb = new_color3
158
+        _titler_data.active_layer.shadow_on = self.shadow_on.get_active()
159
+        _titler_data.active_layer.shadow_opacity = self.shadow_opa_spin.get_value()
160
+        _titler_data.active_layer.shadow_xoff = self.shadow_xoff_spin.get_value()
161
+        _titler_data.active_layer.shadow_yoff = self.shadow_yoff_spin.get_value()
162
+                
163
         self.view_editor.active_layer.update_rect = True
164
         _titler_data.active_layer.update_pango_layout()
165
 
166
@@ -860,6 +902,7 @@
167
         # gui events from being added to queue would be nice.
168
         self.block_updates = True
169
         
170
+        # TEXT
171
         layer = _titler_data.active_layer
172
         self.text_view.get_buffer().set_text(layer.text)
173
 
174
@@ -901,6 +944,24 @@
175
         self.y_pos_spin.set_value(layer.y)
176
         self.rotation_spin.set_value(layer.angle)
177
         
178
+        self.fill_on.set_active(layer.fill_on)
179
+                
180
+        # OUTLINE
181
+        r, g, b, a = layer.outline_color_rgba
182
+        button_color = Gdk.RGBA(r, g, b, 1.0)
183
+        self.out_line_color_button.set_rgba(button_color)
184
+        self.out_line_size_spin.set_value(layer.outline_width)
185
+        self.outline_on.set_active(layer.outline_on)
186
+        
187
+        # SHADOW
188
+        r, g, b = layer.shadow_color_rgb
189
+        button_color = Gdk.RGBA(r, g, b, 1.0)
190
+        self.shadow_color_button.set_rgba(button_color)
191
+        self.shadow_opa_spin.set_value(layer.shadow_opacity)
192
+        self.shadow_xoff_spin.set_value(layer.shadow_xoff)
193
+        self.shadow_yoff_spin.set_value(layer.shadow_yoff)
194
+        self.shadow_on.set_active(layer.shadow_on)
195
+        
196
         self.block_updates = False
197
 
198
 
199
@@ -922,7 +983,18 @@
200
         self.color_rgba = layer.color_rgba
201
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/tools/toolnatron.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/tools/toolnatron.py Changed
22
 
1
@@ -55,3 +55,20 @@
2
     print "Launch Natron..."
3
     args = [str(respaths.LAUNCH_DIR + "natron_clip_export_start.sh"), str(respaths.LAUNCH_DIR)]
4
     subprocess.Popen(args)
5
+
6
+def render_program(render_folder, frame_name, project_file, writer, start_frame, end_frame):
7
+    render_frame = render_folder + "/" + frame_name + "####.png"
8
+    range_str = str(start_frame) + "-" + str(end_frame)
9
+    #NatronRenderer -w Write2 1-10 /home/janne/test/natrontest.ntp
10
+    #NatronRenderer -w Write2 1-10 /home/janne/test/natrontestout/frame###.png /home/janne/test/natrontest.ntp
11
+    #NatronRenderer -w Write2 1-10 /home/janne/test/natrontestout/frame###.png /home/janne/test/natrontest.ntp
12
+    
13
+        # Launch Natron
14
+    print "Launch Natron render with ", writer, range_str, render_frame, project_file
15
+    args = [str(respaths.LAUNCH_DIR + "natron_render.sh"), writer, range_str, render_frame, project_file]
16
+    p = subprocess.Popen(args)
17
+    p.wait()
18
+    
19
+    
20
+    
21
+        
22
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/toolsintegration.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/toolsintegration.py Changed
156
 
1
@@ -17,17 +17,23 @@
2
     You should have received a copy of the GNU General Public License
3
     along with Flowblade Movie Editor. If not, see <http://www.gnu.org/licenses/>.
4
 """
5
+from gi.repository import GObject
6
+
7
 import copy
8
+import os
9
 
10
 import appconsts
11
 from editorstate import PROJECT
12
 import gmic
13
 import toolnatron
14
 import render
15
+import utils
16
 
17
 _tools = []
18
-_active_integrators = []
19
-
20
+_render_items = []
21
+#_active_integrators = []
22
+test_timeout_id = None
23
+           
24
 # --------------------------------------------------- interface
25
 def init():
26
     
27
@@ -38,7 +44,8 @@
28
         _tools.append(NatronIntegrator())
29
         
30
     _tools.append(SlowMoIntegrator())
31
-        
32
+    _tools.append(ReverseIntegrator())
33
+    
34
 def get_export_integrators():
35
     export_integrators = []
36
     for tool_integrator in _tools:
37
@@ -47,21 +54,26 @@
38
     
39
     return export_integrators
40
 
41
+
42
+def test():
43
+    global test_timeout_id
44
+    test_timeout_id = GObject.timeout_add(4000, _do_test)
45
+
46
+def _do_test():
47
+    GObject.source_remove(test_timeout_id)
48
+    
49
+    natroninteg = NatronIntegrator()
50
+    natroninteg.render_program("/home/janne/test/natrontest.ntp", "/home/janne/test/natrontestout", ("Write2",0,100), None, None)
51
+    
52
 # --------------------------------------------------- integrator classes
53
 class ToolIntegrator:
54
     
55
-    def __init__(self, tool_name, supported_media_types,is_export_target):
56
+    def __init__(self, tool_name, supported_media_types, is_export_target):
57
         self.tool_name = tool_name
58
         self.is_export_target = is_export_target
59
         self.supported_media_types = supported_media_types
60
         self.data = None # Used at call sites to give needed info for exports
61
-         
62
-    def activate(self):
63
-        _active_integrators.append(self)
64
     
65
-    def deactivate(self):
66
-        _active_integrators.remove(self)
67
-
68
     def supports_clip_media(self, clip):
69
         if clip.media_type in self.supported_media_types:
70
             return True
71
@@ -71,12 +83,39 @@
72
     def export_callback(self, widget, data):
73
         new_instance = copy.deepcopy(self)
74
         new_instance.data = data
75
-        new_instance.activate()
76
         new_instance.do_export()
77
         
78
     def do_export(self):
79
         print self.__class__.__name__ + " does not implement do_export()"
80
          
81
+    def render_program(self, program_file, write_file, render_data, progress_callback, completion_callback):
82
+        new_instance = copy.deepcopy(self)
83
+        new_instance.program_file = program_file
84
+        new_instance.write_file = write_file
85
+        new_instance.render_data = render_data
86
+        new_instance.progress_callback = progress_callback
87
+        new_instance.completion_callback = completion_callback
88
+        _render_items.append(new_instance)
89
+        new_instance.start_render()
90
+
91
+    def launch_render_ticker(self):
92
+        self.ticker = utils.Ticker(self.render_tick, 1.0)
93
+        self.ticker.start_ticker()
94
+
95
+    def stop_render_ticker(self):
96
+        self.ticker.stop_ticker()
97
+        
98
+    def start_render(self):
99
+        print self.__class__.__name__ + " does not implement start_render()"
100
+
101
+    def stop_render(self):
102
+        print self.__class__.__name__ + " does not implement start_render()"
103
+        
104
+    def render_tick(self):
105
+        print self.__class__.__name__ + " does not implement render_tick()"
106
+        
107
+    def create_render_ticker(self):
108
+        self.render_ticker = utils.Ticker(self.render_tick, 1.0)
109
 
110
 
111
 class GMICIntegrator(ToolIntegrator):
112
@@ -96,6 +135,25 @@
113
         clip, track = self.data
114
         toolnatron.export_clip(clip)
115
 
116
+    def start_render(self):
117
+        name, ext = os.path.splitext(self.program_file)
118
+        self.frame_name = name.split("/")[-1].lower()
119
+        self.writer, self.frame_in, self.frame_out = self.render_data
120
+        
121
+        launch_thread = utils.LaunchThread(None, self.render_launch)
122
+        launch_thread.start()
123
+        
124
+        self.launch_render_ticker()
125
+
126
+    def render_launch(self, data):
127
+        # Blocks until render complete
128
+        toolnatron.render_program(self.write_file, self.frame_name, self.program_file , self.writer, self.frame_in, self.frame_out)
129
+        self.stop_render_ticker()
130
+        print "renedirng done"
131
+
132
+    def render_tick(self):
133
+        print "tick"
134
+
135
 
136
 class SlowMoIntegrator(ToolIntegrator):
137
     
138
@@ -108,4 +166,16 @@
139
         media_file.mark_in = clip.clip_in
140
         media_file.mark_out = clip.clip_out
141
         render.render_frame_buffer_clip(media_file, True)
142
-                
143
+
144
+
145
+class ReverseIntegrator(ToolIntegrator):
146
+    
147
+    def __init__(self):
148
+        ToolIntegrator.__init__(self, _("Reverse"), [appconsts.VIDEO], True)
149
+        
150
+    def do_export(self):
151
+        clip, track = self.data
152
+        media_file = PROJECT().get_media_file_for_path(clip.path)
153
+        media_file.mark_in = clip.clip_in
154
+        media_file.mark_out = clip.clip_out
155
+        render.render_reverse_clip(media_file, True)
156
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/trackaction.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/trackaction.py Changed
29
 
1
@@ -29,6 +29,7 @@
2
 import editorstate
3
 from editorstate import get_track
4
 from editorstate import current_sequence
5
+from editorstate import PROJECT
6
 import snapping
7
 import tlinewidgets
8
 import updater
9
@@ -113,12 +114,19 @@
10
     if msg == "topactiveonly":
11
         _activate_only_current_top_active()
12
     
13
+    if msg == "shrink":
14
+         _tline_vertical_shrink_changed(widget)
15
+        
16
 def _tracks_resize_update():
17
     tlinewidgets.set_ref_line_y(gui.tline_canvas.widget.get_allocation())
18
     gui.tline_column.init_listeners()
19
     updater.repaint_tline()
20
     gui.tline_column.widget.queue_draw()
21
 
22
+def _tline_vertical_shrink_changed(widget):
23
+    PROJECT().project_properties[appconsts.P_PROP_TLINE_SHRINK_VERTICAL] = widget.get_active()
24
+    updater.set_timeline_height()
25
+
26
 def _activate_all_tracks():
27
     for i in range(0, len(current_sequence().tracks) - 1):
28
         current_sequence().tracks[i].active = True
29
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/translations.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/translations.py Changed
19
 
1
@@ -76,7 +76,7 @@
2
         lang = gettext.translation(APP_NAME, locale_path, languages=langs, fallback=True)
3
 
4
     # Un-comment for translations tests
5
-    # lang = gettext.translation(APP_NAME, locale_path, languages=["ru"], fallback=True)
6
+    #lang = gettext.translation(APP_NAME, locale_path, languages=["cs"], fallback=True)
7
 
8
     lang.install(APP_NAME) # makes _() a build-in available in all modules without imports
9
 
10
@@ -534,6 +534,8 @@
11
     param_names["Wipe Type"] = _("Wipe Type")
12
     param_names["Invert"] = _("Invert")
13
     param_names["Softness"] = _("Softness")
14
+    param_names["Fade Out Length"] = _("Fade Out Length")
15
+    param_names["Fade In Length"] = _("Fade In Length")
16
 
17
     # Combo options
18
     global combo_options
19
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/trimmodes.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/trimmodes.py Changed
46
 
1
@@ -965,7 +965,7 @@
2
         clip_start = trim_limits["from_start"]
3
 
4
     # Init two roll trim view layout
5
-    if track.type == appconsts.VIDEO and clip.media_type != appconsts.PATTERN_PRODUCER:
6
+    if track.type == appconsts.VIDEO and clip.media_type != appconsts.PATTERN_PRODUCER and editorstate.show_trim_view == appconsts.TRIM_VIEW_ON:
7
         if edit_data["to_side_being_edited"]:
8
             gui.monitor_widget.set_roll_trim_right_active_view(edit_data["from_clip"], clip_start)
9
         else:
10
@@ -1192,14 +1192,14 @@
11
     return (first, last)
12
 
13
 #---------------------------------------- SLIP ROLL TRIM EVENTS
14
-def set_slide_mode(track, current_frame): # we need to change to to correct one some time
15
+def set_slide_mode(track, current_frame):
16
     """
17
     Sets SLIP tool mode
18
     """
19
     if track == None:
20
         return None
21
 
22
-    if current_frame > track.get_length():
23
+    if current_frame > track.get_length() - 1:
24
         return False
25
 
26
     current_sequence().clear_hidden_track()
27
@@ -1234,7 +1234,7 @@
28
     clip_start = 0 # we'll calculate the offset from actual position of clip on timeline to display the frame displayed after sliding
29
 
30
     # Init two roll trim view layout
31
-    if track.type == appconsts.VIDEO and clip.media_type != appconsts.PATTERN_PRODUCER:
32
+    if track.type == appconsts.VIDEO and clip.media_type != appconsts.PATTERN_PRODUCER and editorstate.show_trim_view == appconsts.TRIM_VIEW_ON:
33
         if not start_frame_being_viewed:
34
             gui.monitor_widget.set_slip_trim_right_active_view(edit_data["clip"])
35
             gui.monitor_widget.set_edit_tline_frame(clip.clip_out, 0)
36
@@ -1264,6 +1264,9 @@
37
     Sets edit mode data used by both trim modes
38
     """
39
     index = current_sequence().get_clip_index(track, edit_frame)
40
+    if index == -1:
41
+        index = len(track.clips) - 1
42
+
43
     clip = track.clips[index]
44
 
45
     trim_limits = {}
46
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/undo.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/undo.py Changed
21
 
1
@@ -45,7 +45,10 @@
2
 undo_item = None 
3
 redo_item = None
4
 
5
-
6
+def clear_undos():
7
+    global undo_stack, index
8
+    undo_stack = []
9
+    index = 0
10
 
11
 def set_post_undo_redo_callback(undo_redo_callback):
12
     global set_post_undo_redo_edit_mode
13
@@ -90,7 +93,6 @@
14
     
15
 def do_undo():
16
     global index
17
-    
18
     if index == 0:
19
         return
20
     
21
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/updater.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/updater.py Changed
71
 
1
@@ -41,8 +41,8 @@
2
 import respaths
3
 import tlinewidgets
4
 
5
-page_size = 99.0 # Gtk.Adjustment.get_page_size() wasn't there
6
-                 # (wft?) so use this to have page size
7
+page_size = 99.0 # Gtk.Adjustment.get_page_size() wasn't there (wft?)
8
+                 # so use this to have page size
9
 
10
 # Scale constants
11
 PIX_PER_FRAME_MAX = 20.0
12
@@ -238,7 +238,7 @@
13
     repaint_tline()
14
     update_tline_scrollbar()
15
     center_tline_to_current_frame()
16
-    
17
+
18
 def zoom_out():
19
     """
20
     Zooms out in the timeline view.
21
@@ -248,8 +248,8 @@
22
         tlinewidgets.pix_per_frame = PIX_PER_FRAME_MIN
23
     repaint_tline()
24
     update_tline_scrollbar()
25
-    center_tline_to_current_frame()
26
-
27
+    tline_scrolled(gui.tline_scroll.get_adjustment())
28
+    
29
 def zoom_max():
30
     tlinewidgets.pix_per_frame = PIX_PER_FRAME_MAX
31
     repaint_tline()
32
@@ -290,6 +290,29 @@
33
         if editorpersistance.prefs.auto_center_on_play_stop == True:
34
             center_tline_to_current_frame()
35
 
36
+# ------------------------------------------ timeline shrinking
37
+def set_timeline_height():
38
+    orig_pos = gui.editor_window.app_v_paned.get_position()
39
+    orig_height = tlinewidgets.HEIGHT 
40
+    
41
+    if len(current_sequence().tracks) == 11 or PROJECT().get_project_property(appconsts.P_PROP_TLINE_SHRINK_VERTICAL) == False:
42
+        tlinewidgets.HEIGHT = appconsts.TLINE_HEIGHT
43
+        set_v_paned = False
44
+    else:
45
+        tlinewidgets.HEIGHT = current_sequence().get_shrunk_tline_height_min()
46
+        set_v_paned = True
47
+
48
+    gui.tline_canvas.widget.set_size_request(tlinewidgets.WIDTH, tlinewidgets.HEIGHT)
49
+    gui.tline_column.widget.set_size_request(tlinewidgets.COLUMN_WIDTH, tlinewidgets.HEIGHT)
50
+    
51
+    if set_v_paned == True:
52
+        new_pos = orig_pos + orig_height - tlinewidgets.HEIGHT
53
+        gui.editor_window.app_v_paned.set_position(new_pos)
54
+    
55
+    current_sequence().resize_tracks_to_fit(gui.tline_canvas.widget.get_allocation())
56
+    tlinewidgets.set_ref_line_y(gui.tline_canvas.widget.get_allocation())
57
+    gui.tline_column.init_listeners()
58
+    repaint_tline()
59
 
60
 # ----------------------------------------- monitor
61
 def display_clip_in_monitor(clip_monitor_currently_active=False):
62
@@ -513,7 +536,7 @@
63
 
64
     gui.tline_scale.widget.queue_draw()
65
     gui.tline_canvas.widget.queue_draw()
66
-    gui.big_tc.widget.queue_draw()
67
+    gui.big_tc.queue_draw()
68
     clipeffectseditor.display_kfeditors_tline_frame(frame)
69
     compositeeditor.display_kfeditors_tline_frame(frame)
70
 
71
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/utils.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/utils.py Changed
181
 
1
@@ -23,6 +23,8 @@
2
 """
3
 import time
4
 
5
+import gi
6
+gi.require_version('Gtk', '3.0')
7
 from gi.repository import Gtk
8
 
9
 import math
10
@@ -30,6 +32,7 @@
11
 import os
12
 import re
13
 import threading
14
+import xml.dom.minidom
15
 
16
 import appconsts
17
 import editorstate
18
@@ -46,8 +49,8 @@
19
     Calls function repeatedly with given delay between calls.
20
     """
21
     def __init__(self, action, delay):
22
-        self.action = action
23
-        self.delay = delay
24
+        self.action = action # callback function
25
+        self.delay = delay # in seconds
26
         self.running = False
27
         self.exited = False
28
     
29
@@ -81,7 +84,15 @@
30
             event.wait(delay)
31
         self.exited = True
32
 
33
+
34
+class LaunchThread(threading.Thread):
35
+    def __init__(self, data, callback):
36
+        threading.Thread.__init__(self)
37
+        self.data = data
38
+        self.callback = callback
39
         
40
+    def run(self):
41
+        self.callback(self.data)
42
         
43
 # -------------------------------- UTIL FUNCTIONS
44
 def fps():
45
@@ -116,6 +127,46 @@
46
     """
47
     return get_tc_string_with_fps(frame, fps())
48
 
49
+def get_tc_string_short(frame):
50
+    tc_str = get_tc_string(frame)
51
+    while len(tc_str) > 4:
52
+        if tc_str[0: 1] == "0" or tc_str[0: 1] == ":":
53
+            tc_str = tc_str[1: len(tc_str)]
54
+        else:
55
+            break
56
+    return tc_str
57
+            
58
+def get_tc_frame(frame_str):
59
+    """
60
+    Return timecode frame from string
61
+    """
62
+    return get_tc_frame_with_fps(frame_str, fps())
63
+
64
+def get_tc_frame_with_fps(frame_str, frames_per_sec):
65
+    # split time string hh:mm:ss:ff into integer and
66
+    # calculate corresponding frame
67
+    try:
68
+        times = frame_str.split(":", 4)
69
+    except expression as identifier:
70
+        return 0
71
+
72
+    # now we calculate the sum of frames that would sum up at corresponding
73
+    # time
74
+    sum = 0
75
+    for t in times:
76
+        num = int(t)
77
+        sum = sum * 60 + num
78
+
79
+    # but well, actually, calculated sum is wrong, because according
80
+    # to our calculation, that would give us 60 fps, we need to correct that
81
+    # last 'num' is frames already, no need to correct those
82
+    sum = sum - num
83
+    sum = int(sum / (60.0 / round(frames_per_sec)))
84
+    sum = sum + num
85
+
86
+    # and that is our frame, so we return sum
87
+    return sum
88
+
89
 def get_tc_string_with_fps(frame, frames_per_sec):
90
     # convert fractional frame rates (like 23.976) into integers,
91
     # otherwise the timeline will slowly drift over time
92
@@ -302,6 +353,15 @@
93
     
94
     return "unknown"
95
 
96
+def is_mlt_xml_file(file_path):
97
+    name, ext = os.path.splitext(file_path)
98
+    ext = ext.lstrip(".")
99
+    ext = ext.lower()
100
+    if ext == "xml" or ext == "mlt":
101
+        return True
102
+    
103
+    return False
104
+        
105
 def hex_to_rgb(value):
106
     value = value.lstrip('#')
107
     lv = len(value)
108
@@ -356,15 +416,20 @@
109
     return file_name
110
     
111
 def get_hidden_user_dir_path():
112
+    """ 
113
+    this is nit for now, reactiva if flatpack snadboxing is tried.
114
+    
115
     if editorstate.use_xdg:
116
         return os.path.join( 
117
                             os.getenv("XDG_CONFIG_HOME", os.path.join(os.getenv("HOME"),".config")),
118
                             "flowblade/")
119
     else:
120
-        return os.getenv("HOME") + "/.flowblade/"
121
+    """
122
+    
123
+    return os.getenv("HOME") + "/.flowblade/"
124
 
125
 def get_phantom_disk_cache_folder():
126
-    return get_hidden_user_dir_path() +  appconsts.NODE_COMPOSITORS_DIR + "/" + appconsts.PHANTOM_DISK_CACHE_DIR
127
+    return get_hidden_user_dir_path() +  appconsts.PHANTOM_DIR + "/" + appconsts.PHANTOM_DISK_CACHE_DIR
128
 
129
 def get_hidden_screenshot_dir_path():
130
     return get_hidden_user_dir_path() + "screenshot/"
131
@@ -427,8 +492,31 @@
132
     info["progressive"] = frame.get_int("meta.media.progressive") == 1
133
     info["top_field_first"] = frame.get_int("meta.media.top_field_first") == 1
134
     
135
+    resource = clip.get("resource")
136
+    name, ext = os.path.splitext(resource)
137
+    ext = ext.lstrip(".")
138
+    ext = ext.lower()
139
+    if ext == "xml" or ext =="mlt":
140
+        update_xml_file_producer_info(resource, info)
141
+        
142
     return info
143
 
144
+def update_xml_file_producer_info(resource, info):
145
+    # xml and mlt files require reading xml file to determine producer info
146
+    mlt_doc = xml.dom.minidom.parse(resource)
147
+
148
+    mlt_node = mlt_doc.getElementsByTagName("mlt").item(0)
149
+    profile_node = mlt_node.getElementsByTagName("profile").item(0)
150
+
151
+    info["width"] = int(profile_node.getAttribute("width"))
152
+    info["height"] = int(profile_node.getAttribute("height"))
153
+    info["fps_num"] = float(profile_node.getAttribute("frame_rate_num"))
154
+    info["fps_den"] = float(profile_node.getAttribute("frame_rate_den"))
155
+    info["progressive"] = int(profile_node.getAttribute("progressive"))
156
+    
157
+    print info
158
+    #  <profile description="HD 720p 29.97 fps" width="1280" height="720" progressive="1" sample_aspect_num="1" sample_aspect_den="1" display_aspect_num="16" display_aspect_den="9" frame_rate_num="30000" frame_rate_den="1001" colorspace="0"/>
159
+    
160
 def is_media_file(file_path):
161
     file_type = get_file_type(file_path)
162
     if file_type == "unknown":
163
@@ -532,6 +620,7 @@
164
                             "m2ts",
165
                             "m2v",
166
                             "m4e",
167
+                            "mlt",
168
                             "mjpg",
169
                             "mp4v",
170
                             "mts",
171
@@ -560,7 +649,8 @@
172
                             "wmv",
173
                             "xvid",
174
                             "y4m",
175
-                            "yuv"]
176
+                            "yuv",
177
+                            "xml"]
178
                             
179
                             
180
 def start_timing(msg="start timing"):
181
flowblade-1.12.2.tar.gz/flowblade-trunk/Flowblade/vieweditor/vieweditor.py -> flowblade-1.14.tar.gz/flowblade-trunk/Flowblade/vieweditor/vieweditor.py Changed
18
 
1
@@ -19,6 +19,7 @@
2
 """
3
 
4
 import numpy as np
5
+print "numpy version:", np.version.version
6
 
7
 from gi.repository import Gtk, GObject
8
 
9
@@ -211,7 +212,7 @@
10
         cr.fill()
11
 
12
 
13
-        if self.bg_buf != None:
14
+        if self.bg_buf is not None:
15
             # MLT Provides images in which R <-> B are swiched from what Cairo wants them,
16
             # so use numpy to switch them and to create a modifiable buffer for Cairo
17
             
18
flowblade-1.12.2.tar.gz/flowblade-trunk/copyrights -> flowblade-1.14.tar.gz/flowblade-trunk/copyrights Changed
12
 
1
@@ -6,6 +6,10 @@
2
 Copyright: 2012 Janne Liljeblad <janne.liljeblad@gmail.com>
3
 License: GPL-3.0+
4
 
5
+Files: clapperless.py
6
+Copyright: 2013 Benjamin M. Schwartz
7
+License: GPL-3.0+
8
+
9
 Files: bi-linear_x.pgm bi-linear_y.pgm burtst.pgm checkerboard_small.pgm cloud.pgm radial-bars.pgm spiral.pgm spiral2.pgm square.pgm square2.pgm square2-bars.pgm symmetric_clock.pgm
10
 Copyright: 2012 (files are from Kdenlive http://www.kdenlive.org. Project AUTHORS file contents are prosumed to be copyright holders)
11
     Jean-Baptiste Mardelle
12
flowblade-1.12.2.tar.gz/flowblade-trunk/docs/FAQ.md -> flowblade-1.14.tar.gz/flowblade-trunk/docs/FAQ.md Changed
29
 
1
@@ -1,11 +1,11 @@
2
-#FAQ#
3
+# FAQ
4
 
5
 **Contents**
6
 
7
-  1. [Crop filter does not work](./FAQ.md####crop-filter-does-not-work)
8
-  2. [How can I move clips around freely?](./FAQ.md####how-can-i-move-clips-around-freely)
9
-  3. [Will there be Windows or OSX versions?](./FAQ.md####will-there-be windows-or-OSX-versions)
10
-  4. [Rendering with a profile with different framerate changes video playback speed and loses audio sync](./FAQ.md####rendering-with-a-profile-with-different-framerate-changes-video playback-speed-and-loses-audio-sync)
11
+  1. [Crop filter does not work](./FAQ.md#crop-filter-does-not-work)
12
+  2. [How can I move clips around freely?](./FAQ.md#how-can-i-move-clips-around-freely)
13
+  3. [Will there be Windows or OSX versions?](./FAQ.md#will-there-be-windows-or-osx-versions)
14
+  4. [Rendering with a profile with different framerate changes video playback speed and loses audio sync](./FAQ.md#rendering-with-a-profile-with-different-framerate-changes-video-playback-speed-and-loses-audio-sync)
15
 
16
 #### Crop filter does not work
17
 
18
@@ -26,8 +26,9 @@
19
 These are not currently planned. If in the future the port effort is reasonable, does not have adverse effects on the code base and someone provides quality patches, then those patches can probably be accepted.
20
 
21
 
22
-#### Rendering with a profile with different framerate changes video playback speed and loses audio sync ####
23
+#### Rendering with a profile with different framerate changes video playback speed and loses audio sync
24
 
25
 Yes, this will happen. When rendering the video frames are just copied, no complex slowdown/speedup prosessing is done, and audio is **not** resampled.
26
 
27
 To maintain sync and playback both Project Profile and Render Profile both need to match the frame rate of original material.  
28
+
29
flowblade-1.14.tar.gz/flowblade-trunk/docs/Flowblade-Patch-Shortcuts.pdf Added
flowblade-1.12.2.tar.gz/flowblade-trunk/docs/KNOWN_ISSUES.md -> flowblade-1.14.tar.gz/flowblade-trunk/docs/KNOWN_ISSUES.md Changed
11
 
1
@@ -43,4 +43,9 @@
2
 
3
 **Status:** Some fix may be attempted later.
4
 
5
+#### 7. MLT 6.4.0 crashes with terminal output: "ERROR: /usr/lib/python2.7/dist-packages/_mlt.x86_64-linux-gnu.so: undefined symbol: _ZNK3Mlt7Profile8is_validEv"
6
+
7
+In systems running MLT 6.4.0 Flowblade does not start, more info on issue here: https://plus.google.com/u/0/102624418925189345577/posts/7ANDDW3hzHB?sfc=true
8
+
9
+**Status:** This is fixed upstream, make sure to use MLT 6.4.1 or higher.
10
 
11
flowblade-1.12.2.tar.gz/flowblade-trunk/docs/RELEASE_NOTES.md -> flowblade-1.14.tar.gz/flowblade-trunk/docs/RELEASE_NOTES.md Changed
147
 
1
@@ -1,9 +1,126 @@
2
 # Release Notes #
3
 
4
 
5
+**COMING SOON...**
6
+
7
+## Flowblade 1.14 ##
8
+
9
+Date: August x, 2017
10
+
11
+**Flowblade 1.14** is the fourteenth release of Flowblade. This release had probably more new features then any release  since the initial release 0.6. New functionality like sequence combining, compound clips and audio syncing take the application to the next level as a complete editing solution.
12
+
13
+Especially sequence combining feature together with existing features like *Range Log* make Flowblade easily the most advanced and featureful FLOSS tool for projects with long complex edits and large amounts of media.
14
+
15
+Improved user feedback has also made possible to refine many areas of functionality beoynd original design. 
16
+
17
+### Audio Syncing ###
18
+
19
+Python module *clapperless.py* by *Martin Schitter* and *Benjamin M. Schwartz* has made it possible to offer functionality that syncs media items based on their audio data. We have two new features offering Audio Syncing functionality.
20
+
21
+  * **Timeline Audio Syncing** Now you can select  two clips on timeline and request one of them to be moved so that clips' audio is synced on timeline. This makes it possible to do multicamera editing on timeline, one needs to manually set video mute on/off on tracks to see all tracks, but the workflow is possible now.
22
+
23
+* **Audio Synced Compound Clips** User can select a video and audio clip and create an audio synced compound clip media item from them. This is useful e.g. when audio is recorded separately and video clip only has some help audio.
24
+
25
+### Combining Sequences ###
26
+
27
+It is possible to import full contents of another Sequence into the Sequence currently being edited. There are two ways provided to combine sequences:
28
+  * Imported sequence can be **appended at the end of current sequence**.
29
+  * Imported sequence can be **spliced in at the playhead position**.
30
+
31
+This long overdue feature will make having multiple sequences per project a much more useful and flexible tool when building complex programs from smaller parts.
32
+
33
+### Compound Clips ###
34
+
35
+A **Compound Clip** is a single clip created by combining multiple clips and compositors in to a single media item. Compound Clips are useful when some complex sequence is more conveniently handled as a single unit.
36
+  * **Compound Clip from Selection** feature creates a Compound Clip from currently selected clips into a Xompound Clip.
37
+  * **Compound Clip from Sequence** feature creates a Compound Clip from current full contents of the timeline.
38
+  * **Audio Synced Compound Clips**, see above.
39
+  
40
+### Fade in/out ###
41
+We have two new features addressing user requests for speeding up the process of creating fade in and fade out transittions.
42
+  * **Fade Compositors** These are special new compositors that will automatically on creation place themselves at the beginning or end of clips and do not need any keyframe manipulation; lengths of fades are changed by changing the lengths of compositors.
43
+  * **Add Fade buttons** *Compositors* panel now has **Add Fade In** and **Add Fade Out** buttons that will create keyframes that define a fade of desired length in a single click.
44
+
45
+### User Selectable Keyboard shortcuts ###
46
+
47
+**Steven van de Beek** contributed code that makes it possible to have user defined keyboard shortcuts. In this release we offer a possibility to select between two predefined sets of shortcuts, and fully configurable keyboard shortcuts will be made available in the future.
48
+
49
+### Tools development ###
50
+
51
+#### Reverse clips tool ####
52
+We now offer a new tool to create reverse clips of user selectable speed from media items.
53
+
54
+#### Titler ####
55
+
56
+Titler got two new features
57
+
58
+  * Text drop shadow 
59
+  * Text outline features
60
+
61
+#### Disk cache management ####
62
+Disk cache management window provides GUI tool for deleting saved hidden files that could eventually consume noticable amounts of disk space.
63
+
64
+### Translations ###
65
+
66
+We got a new new Cantonese translation by 老吴的BOX.
67
+
68
+We got fully up to date translations for 1.14 in Russian, Polish and Czezh by Николай Смольянинов, Stanisław Polak and Pavel Fric respectively.
69
+
70
+### Future directions ###
71
+
72
+During next cycle work continues roughly as outlined in road map and Issues list at Github. 
73
+
74
+Translations workflow update is definately in the plans. The current workflow is difficult and outdated when there are several web solutions that are likely preferable to all translations contributors.
75
+
76
+Next cycle will also see move to spending more development time on some upstream issues that can take a bit of time to come through as available features in the application, expecially on installationss from distro repositories.
77
+
78
+We will probably continue with the 6 month release cycle, but a shorter one is possible if certain planned improvements come together quickly enough.
79
+
80
+### Other new Features ###
81
+  * Import media items from another project.
82
+  * Support for manually entered time codes/frame values on clicked time code display  in **by Bene81**.
83
+  * Timeline edit move delta info overlay.
84
+  * Save render settings for proxy conversions.
85
+  * Add Lossless FFv1 profile **by lsde**.
86
+  * Fix timelineline zoom issue causing problems with scrolling.
87
+  * About menu visually impored **by Mostafa Ahangarha**.
88
+  * Allow user preferences for Fast Forward / Reverse speeds **by Steven van de Beek**.
89
+  * Allow shrinking timeline vertically when fewer than maximum tracks used tracks.
90
+  * Make Range Overwrite 3 point edit work with only In set on Timeline.
91
+  * Enable Volume filter to  bring volume up > 100%
92
+
93
+### Feature Removals ###
94
+  * Dropped **Zoom Pan filter** because it does not work on all files.
95
+
96
+### Other bugfixes and improvements ###
97
+  * Double track heights for HiDPI screens.
98
+  * Fix frame sequence render issue.
99
+  * Fix wrong FPS on import for certain clips.
100
+  * Fix Slip tool bug for clips with index 0.
101
+  * Fix keyboard focus handling for 2 window layout.
102
+  * Add guide lines for shift down edits in geometry editors.
103
+  * Fix double click on blank crash.
104
+  * Fix trim view handling for roll and slide with TRIM_VIEW_SINGLE.
105
+  * Fix change profile unicode bug.
106
+  * Get confirmation when rendering from proxy media.
107
+  * Make default rate 8000kB for rendered transitions.
108
+  * Get overwrite confirmation when rendering.
109
+  * Disable cut action when it might interfere with ongoing edits.
110
+  * Fix titler for 1.13 numpy.
111
+  * Save mark in/out for proxy conversions.
112
+  * Make keypad 1-7 change tools too.
113
+  * Fix issue with Volume filter spin inputs.
114
+  * Fix keyframe drag to last frame bug.
115
+  * Fix not updating TC display after layout change.
116
+  * Fix unicode marker names.
117
+  * Add Clip Edit menu.
118
+  * Reverse order of SCOPE_MIX_VALUES.
119
+  * Add Window mode menu item.
120
+  * Fix duplicate profiles.
121
+
122
 ## Flowblade 1.12 ##
123
 
124
-Date: March 18, 2016
125
+Date: March 18, 2017
126
 
127
 **Flowblade 1.12** is the fourteenth release of Flowblade.
128
 
129
@@ -266,7 +383,7 @@
130
 
131
 The next cycle will be the longest since 0.16 because of the amount of coding and research needed. The target release date for 1.8 is September 2016.
132
 
133
-####Bugfixes and enhancements####
134
+#### Bugfixes and enhancements ####
135
 * Fix set parent clip functionality
136
 * Fix translation scripts (apienk)
137
 * Re-create all media icons always when requested
138
@@ -323,7 +440,7 @@
139
 * **Filters can now be copy/pasted from one clip to another**. It has been possible to copy paste clips on timeline for quite a while, but now this feature was made more discovarable by adding menu items for the functionality.  
140
 
141
 
142
-####Other features and enhancements####
143
+#### Other features and enhancements ####
144
 * Fix media relinking for projects with SAVEFILE_VERSION < 4
145
 * Add 1080p 50fps profile
146
 * Fix keys 1-6 stopping working after tool selection
147
flowblade-1.12.2.tar.gz/flowblade-trunk/docs/ROADMAP.md -> flowblade-1.14.tar.gz/flowblade-trunk/docs/ROADMAP.md Changed
68
 
1
@@ -1,17 +1,18 @@
2
 # FLOWBLADE ROADMAP
3
 
4
-Last updated: March. 2017
5
+Last updated: September. 2017
6
 
7
 
8
-## Animation
9
-- MLT keyframe types *bezier* and *step* to be made available in addition to current linear type keyframes for all keyframe editors
10
-- 100% coverage for keyframe editing for float value paramaters. A light weight editor component needs to made for cases where keyframe editing is the secondary 
11
+
12
+## Editing
13
+- **Context sensitive Timeline tool cursor** This was originally part of non-features list of the design, but it seems that users prefer this, and we will look for a way to incoporate this with current design.
14
+- **Automatic Timeline Rendering** The only way to provide smooth playback in all circumstances is to do some form of timeline rendering. There are some ideas here that will be attempted, but cannot be quaranteed to work beforehand.
15
 
16
 ## Tracks
17
 - **Track filters stack** for both video and audio tracks.
18
 
19
 ## Filters
20
-- Contribute **Cairo filters for MLT**. Spotligt, animated producer, animated overlay filter, animated alpha and affine transform filter seem most interesting. Frei0r is not an adequate platform for some of these.
21
+- Contribute **filters for MLT**. Spotligt, affine transform filter seem most interesting. Frei0r is not an adequate platform for some of these. may require using Cairo.
22
 - **Selective Filter Application**, this function allows user to apply any filter only inside an area defined by alpha filters. This can currently be simulated with two clips. Requires MLT contribution.
23
 
24
 ## Compositing
25
@@ -20,18 +21,10 @@
26
 - animated line/curve masks, this may also be best done using **Cairo**.  Requires MLT contribution.
27
 - add to all alpha filters composing methods union, intersection, difference and exclusion.  Requires MLT and Frei0r contribution.
28
 
29
-## Multiclip functonality
30
-- create Compound clips from selections and full sequences
31
-- make possible to combine sequences with insert and append functions
32
-
33
 ## Tools development
34
-
35
-- multispeed reversed clips tool
36
-- Titler tool improvements: drop shadow with blur, color outline.
37
 - dedicated masking/keying tool
38
 
39
 ## Tool integration
40
-- **Timeline Container Clips** with data on original media, tool program data, rendered media and rendered media offset known and saved. Combine with polling for automatic prompts for update on render completion.
41
 - **Media Item creation** from ready made programs for e.g. text animations with Natron
42
 - Gimp, Inkscape, Audacity, Krita examined as **Timeline Container Clip** media creator programs
43
 
44
@@ -45,11 +38,7 @@
45
 ## Editor functionality
46
 
47
 - Configurable Keyboard Shortcuts.
48
-- Disk Cache Manager. Data in hidden folder can become quite big eventually, and controlling it from application would be useful
49
 
50
-## Project data
51
-
52
-- import media data from one project into another project
53
 
54
 ## Packaging
55
 
56
@@ -68,5 +57,10 @@
57
 - The **Wayland** transition using SDL2 or OpenGL consumer. SDL2 consumer does not exist and would need to be contributed.
58
    
59
 
60
-   
61
+
62
+*Changelog*
63
+- *20-9-2017 drop FFMpeg tool, Container clips are done, add Editing section*
64
+- *13-5-17 Remove undoable items related to animating property values in in MLT, require too large MLt controinutions for the time being*
65
+- *13-5-17 Remove completed items and items that will be in 1.14*
66
+- *13-5-17 Add change log*
67
    
68
flowblade-1.12.2.tar.gz/flowblade-trunk/flowblade -> flowblade-1.14.tar.gz/flowblade-trunk/flowblade Changed
10
 
1
@@ -23,7 +23,7 @@
2
 import os
3
 import sys
4
 
5
-print "FLOWBLADE MOVIE EDITOR 1.12"
6
+print "FLOWBLADE MOVIE EDITOR 1.14"
7
 print "---------------------------"
8
 
9
 
10
flowblade-1.12.2.tar.gz/flowblade-trunk/setup.py -> flowblade-1.14.tar.gz/flowblade-trunk/setup.py Changed
19
 
1
@@ -33,7 +33,7 @@
2
 flowblade_package_data = ['res/filters/*.xml','res/filters/wipes/*','res/img/*',
3
                           'res/profiles/*','res/render/renderencoding.xml',
4
                           'res/patternproducer/*','res/help/*','locale/Flowblade/*',
5
-                          'res/proxyprofiles/*','res/darktheme/*','launch/*','res/gmic/*']
6
+                          'res/proxyprofiles/*','res/darktheme/*','launch/*','res/gmic/*','res/shortcuts/*']
7
 
8
 locale_files = []
9
 for filepath in glob.glob("Flowblade/locale/*/LC_MESSAGES/*"):
10
@@ -41,7 +41,7 @@
11
     locale_files.append(filepath)
12
 
13
 setup(  name='flowblade',
14
-        version='1.12.0',
15
+        version='1.14.0',
16
         author='Janne Liljeblad',
17
         author_email='janne.liljeblad at gmail dot com',
18
         description='Non-linear video editor',
19