Compare commits

...

214 Commits

Author SHA1 Message Date
Simon A. Eugster
85e0e9808e Algorithm SVG: Timeline helper for snapping 2014-08-14 20:57:14 +02:00
Simon A. Eugster
20663d7b33 Git workflow updated 2014-08-14 20:57:14 +02:00
Simon A. Eugster
5ef795f509 Dependencies SVG added (from installation page) 2014-08-14 20:57:14 +02:00
Till Theato
2e2f488c90 Short introduction on timeline groups/selections. 2014-08-14 14:14:48 +02:00
Till Theato
9b28ddbe48 Add timeline operations documentation. 2014-08-14 13:54:49 +02:00
Till Theato
35ec064a62 Remove obsolete refactoring documentation. 2014-08-12 15:25:36 +02:00
Simon A. Eugster
f46dea749c Architecture: Effects view updated 2014-08-12 12:46:48 +02:00
Simon A. Eugster
2d6b84bba6 Alternative timeline view proposal 2014-08-12 11:18:02 +02:00
Simon A. Eugster
2a49f801e2 Architecture: Proposed view 2014-08-11 22:36:25 +02:00
Simon A. Eugster
a267685415 Architecture: More UML and details 2014-08-11 11:54:22 +02:00
Simon A. Eugster
c411a3c523 Architecture: Inheritance 2014-08-11 10:51:42 +02:00
Simon A. Eugster
9ef2b9ba4f Architecture SVG updated with corresponding GUI elements 2014-08-11 09:33:50 +02:00
Simon A. Eugster
40d735e8da Architecture: First draft 2014-08-10 22:48:13 +02:00
Till Theato
c7ca9f27ac Update refactoring notes 2014-08-10 12:19:09 +02:00
Till Theato
5da2eb92f1 Add some refactoring notes 2014-08-10 11:25:04 +02:00
Till Theato
81707e9411 Remove not refactoring related files (3/x). 2014-04-15 11:53:14 +02:00
Till Theato
d257eb406c Remove not refactoring related files (2/x). 2014-04-15 11:42:02 +02:00
Till Theato
53c3ca5127 Remove not refactoring related files (1/x). 2014-04-15 11:26:11 +02:00
l10n daemon script
1eed118ece SVN_SILENT made messages (.desktop file) 2013-11-24 04:07:15 +00:00
l10n daemon script
ed0f5102cd SVN_SILENT made messages (.desktop file) 2013-10-08 04:18:08 +00:00
l10n daemon script
ff9bad0740 SVN_SILENT made messages (.desktop file) 2013-10-03 04:10:52 +00:00
l10n daemon script
4608ca1dda SVN_SILENT made messages (.desktop file) 2013-09-09 04:06:34 +00:00
l10n daemon script
2f92381b96 SVN_SILENT made messages (.desktop file) 2013-09-08 04:17:45 +00:00
l10n daemon script
381b239532 SVN_SILENT made messages (.desktop file) 2013-08-17 04:07:39 +00:00
l10n daemon script
9edcb7cc02 SVN_SILENT made messages (.desktop file) 2013-08-14 04:08:04 +00:00
l10n daemon script
affe004127 SVN_SILENT made messages (.desktop file) 2013-08-09 04:01:37 +00:00
l10n daemon script
02807c83b7 SVN_SILENT made messages (.desktop file) 2013-08-08 04:00:07 +00:00
l10n daemon script
6d1938ab4e SVN_SILENT made messages (.desktop file) 2013-08-06 04:01:11 +00:00
l10n daemon script
6954c6573b SVN_SILENT made messages (.desktop file) 2013-08-04 04:19:28 +00:00
l10n daemon script
cafcd9339f SVN_SILENT made messages (.desktop file) 2013-07-23 04:00:07 +00:00
l10n daemon script
ab67e058d5 SVN_SILENT made messages (.desktop file) 2013-07-14 04:10:32 +00:00
l10n daemon script
30b94d484a SVN_SILENT made messages (.desktop file) 2013-07-12 04:00:14 +00:00
Montel Laurent
ae7f426b69 USe const'ref 2013-07-06 13:41:36 +02:00
Montel Laurent
f67f33d461 Fix i18n (we must use I18N_NOOP if we want to use i18n(str) after that. Otherwise it will not work. But for it better to use i18n directly 2013-07-06 12:40:01 +02:00
Montel Laurent
ddcaac19b4 Fix potential crash 2013-07-06 12:37:50 +02:00
Montel Laurent
6b9d68f47a Minor optimization. Fix indent. 2013-07-06 12:35:02 +02:00
Montel Laurent
ae9cedfed8 Fix order 2013-07-06 12:31:30 +02:00
l10n daemon script
0f2c1f7f9d SVN_SILENT made messages (.desktop file) 2013-07-06 03:52:00 +00:00
l10n daemon script
4a6ed227d7 SVN_SILENT made messages (.desktop file) 2013-07-05 03:45:59 +00:00
Jean-Baptiste Mardelle
6af0aceb17 Fix crash on undo add effect 2013-07-04 17:42:40 +02:00
Jean-Baptiste Mardelle
cbe38d9efc Add undo command for add effect action 2013-07-04 01:24:15 +02:00
Jean-Baptiste Mardelle
14b5b4d8f3 Merge branch 'master' of git://anongit.kde.org/kdenlive 2013-07-03 17:35:23 +02:00
Jean-Baptiste Mardelle
17ed62f04c Add delete clip; first test of context menu in project bin 2013-07-03 17:33:05 +02:00
l10n daemon script
e00eadcc36 SVN_SILENT made messages (.desktop file) 2013-07-01 03:48:43 +00:00
l10n daemon script
1efa3c1d38 SVN_SILENT made messages (.desktop file) 2013-06-28 03:45:41 +00:00
l10n daemon script
bc1261f439 SVN_SILENT made messages (.desktop file) 2013-06-27 03:49:12 +00:00
l10n daemon script
9e2b86bd6a SVN_SILENT made messages (.desktop file) 2013-06-25 03:44:48 +00:00
Montel Laurent
2e17b6ab59 Fix indent 2013-06-24 07:14:30 +02:00
Montel Laurent
2f04ad1aac include mocs 2013-06-24 07:10:56 +02:00
Jean-Baptiste Mardelle
ec4182cac7 Load and display existing clip effects in clip timeline 2013-06-23 16:20:22 +02:00
Jean-Baptiste Mardelle
fa9e76c4c5 Add webfvx clip type. Add basis for clip reload on some property change 2013-06-23 14:28:05 +02:00
Jean-Baptiste Mardelle
00d500f845 use black background in empty playlist too 2013-06-14 14:04:19 +02:00
Jean-Baptiste Mardelle
f013aae85e Fix black clip in monitor init when opening Kdenlive 2013-06-14 13:53:45 +02:00
Montel Laurent
574c232695 Fix indent. Remove not necessary virtual. 2013-06-14 07:35:57 +02:00
Montel Laurent
1be0881b44 Normalize signal/slots 2013-06-12 07:32:17 +02:00
Montel Laurent
71afde5f0b Minor optimization 2013-06-12 07:31:35 +02:00
Montel Laurent
b47c796bf2 Minor optimization. Fix indent. 2013-06-12 07:31:05 +02:00
Montel Laurent
b39d74ea65 Start to use QLatin1String and other (for some optimization) 2013-06-12 07:24:11 +02:00
Montel Laurent
fe1b3a4086 Not necessary to show it 2013-06-12 07:19:54 +02:00
l10n daemon script
0538af2954 SVN_SILENT made messages (.desktop file) 2013-06-12 03:59:13 +00:00
Jean-Baptiste Mardelle
a8573ae1b4 First basic implementation of effects: double click on a clip in bin, and a timeline will show with an effect panel allowing to add an effect 2013-06-12 00:20:27 +02:00
Jean-Baptiste Mardelle
0da7c8bd94 Fix compile warnings 2013-06-11 19:40:41 +02:00
Montel Laurent
c02af737b2 Minor optimization. Remove virtual keyword 2013-06-10 20:15:40 +02:00
Montel Laurent
4610d9c6c1 Add const'ref. Fix indent. Minor optimization 2013-06-10 13:30:08 +02:00
Montel Laurent
da90b478c5 use const'ref 2013-06-10 09:43:24 +02:00
Montel Laurent
dcfad98f8f Const'ref. Fix indent 2013-06-10 09:40:42 +02:00
l10n daemon script
2a26ee136b SVN_SILENT made messages (.desktop file) 2013-06-10 03:42:45 +00:00
Montel Laurent
e85c4c8940 Use qlatin1String 2013-06-09 20:51:56 +02:00
Montel Laurent
2cd963d24e Fix create default kde menu. Fix indent 2013-06-09 20:45:15 +02:00
Montel Laurent
1e0200da94 use reference. Fix indent 2013-06-09 20:37:36 +02:00
Montel Laurent
b1dfe4678c Not necessary to check pointer before to delete it. Fix indent 2013-06-09 20:35:26 +02:00
Montel Laurent
a2c923b428 Fix warning order 2013-06-09 20:34:11 +02:00
Jean-Baptiste Mardelle
7c13c5f63b Implement basic monitor shortcuts (play/pause, back, forwards) 2013-06-09 20:00:51 +02:00
Jean-Baptiste Mardelle
e6995fffbc Remember timeline zoom for each bin in clip 2013-06-09 18:57:58 +02:00
Jean-Baptiste Mardelle
2aaa510110 Start work on bin clip's timeline: double click on a bin clip to open its timeline 2013-06-09 16:17:27 +02:00
Jean-Baptiste Mardelle
9797308b17 Start work on bin clip's timeline: double click on a bin clip to open its timeline 2013-06-09 12:23:47 +02:00
Montel Laurent
8c35c8743f Use reference 2013-06-09 11:13:03 +02:00
Jean-Baptiste Mardelle
6f05726cc1 Remember zone for each clip in bin 2013-06-09 02:33:42 +02:00
Montel Laurent
90ee526da0 Fix forward declaration 2013-06-08 15:47:42 +02:00
Montel Laurent
3f39cf9dce Use own export variable 2013-06-08 15:42:34 +02:00
Montel Laurent
c6f2b5f686 Fix warning 2013-06-08 15:35:02 +02:00
Montel Laurent
7c85fd3eca 0.9.7 is for stable branch. Change to 0.9.9 if it will next 1.0 2013-06-08 15:19:18 +02:00
l10n daemon script
60dd7e20d0 SVN_SILENT made messages (.desktop file) 2013-06-08 03:43:08 +00:00
Montel Laurent
0528edc164 Minor coding style 2013-06-07 20:01:11 +02:00
Montel Laurent
57aa0e9126 Const'ref 2013-06-07 13:26:19 +02:00
Montel Laurent
c2ab685110 normalize signals/slots 2013-06-07 12:40:07 +02:00
Montel Laurent
92546cbd4b Fix signal/slots 2013-06-07 11:37:28 +02:00
Montel Laurent
c561f54977 Minor optimization 2013-06-07 09:45:45 +02:00
Montel Laurent
62fea41c79 fix indent. Const'ref. Optimization 2013-06-07 09:14:45 +02:00
Montel Laurent
21701e6231 const'ify. Minor optimization. if (foo) delete foo => delete foo, C++ is able to delete null pointer 2013-06-07 09:08:32 +02:00
l10n daemon script
a48e231708 SVN_SILENT made messages (.desktop file) 2013-06-07 03:35:57 +00:00
Montel Laurent
495c751675 const'ref. Fix indent. 2013-06-06 20:50:26 +02:00
Montel Laurent
964aed970d const'ref. fix indent. Optimization 2013-06-06 20:49:10 +02:00
Montel Laurent
42627cfe39 Remove not necessary title 2013-06-06 13:24:23 +02:00
Montel Laurent
3c91085cce const'ref 2013-06-06 13:23:59 +02:00
Montel Laurent
bd098265d0 includemocs 2013-06-06 07:30:04 +02:00
l10n daemon script
6caee75b8f SVN_SILENT made messages (.desktop file) 2013-06-06 03:42:08 +00:00
Montel Laurent
34e009270a includemocs 2013-06-05 22:01:54 +02:00
Montel Laurent
2c2c353327 Includemocs 2013-06-05 22:01:02 +02:00
Montel Laurent
96a29bed85 Merge branch 'master' of git.kde.org:kdenlive 2013-06-05 21:58:56 +02:00
Montel Laurent
bc560c1bc5 Const'ref + pedantic 2013-06-05 21:58:14 +02:00
Jean-Baptiste Mardelle
e620ba6e21 Merge branch 'master' of git://anongit.kde.org/kdenlive 2013-06-05 21:49:39 +02:00
Jean-Baptiste Mardelle
594bb71802 GLWidget: show nice overlay for zones / markers 2013-06-05 21:47:47 +02:00
Montel Laurent
df713257bd const'ref 2013-06-05 21:33:39 +02:00
Montel Laurent
c4e95f4ee6 USe const'ref 2013-06-05 21:31:49 +02:00
Montel Laurent
98717ef6aa const'ref. Fix indent here 2013-06-05 21:29:47 +02:00
Jean-Baptiste Mardelle
d38050bf6d Fix startup crash on loading document 2013-06-05 19:52:36 +02:00
Jean-Baptiste Mardelle
84bc98dccf Do not allow to open Kdenlive documents from previous versions so that users don't destroy their work. Opening MLT playlist still works. 2013-06-05 17:25:21 +02:00
Jean-Baptiste Mardelle
82c2d74c1c Merge branch 'master' of git://anongit.kde.org/kdenlive 2013-06-05 14:57:23 +02:00
Jean-Baptiste Mardelle
6ef1962f83 Update required MLT version 2013-06-05 14:25:54 +02:00
Montel Laurent
557fb3ea0b Fix compile 2013-06-05 14:12:09 +02:00
Jean-Baptiste Mardelle
b711b8125e Use ++i 2013-06-05 13:40:18 +02:00
Jean-Baptiste Mardelle
6069ce084b Merge branch 'refactoring'
Conflicts:
	data/CMakeLists.txt
	data/blacklisted_effects.txt
	effects/frei0r_alpha0ps.xml
	src/CMakeLists.txt
	src/clipitem.cpp
	src/core/widgets/colorpickerwidget.h
	src/core/widgets/dragvalue.cpp
	src/core/widgets/dragvalue.h
	src/customtrackview.cpp
	src/customtrackview.h
	src/dvdwizard.cpp
	src/effectstackview.cpp
	src/geometrywidget.cpp
	src/keyframehelper.cpp
	src/main.cpp
	src/mainwindow.cpp
	src/monitormanager.cpp
	src/nolib/qtimerWithTime.h
	src/plugins/projectparts/notes/noteswidget.cpp
	src/plugins/projectparts/notes/noteswidget.h
	src/transitionsettings.cpp
	src/utils/resourcewidget.cpp
2013-06-05 13:34:53 +02:00
Jean-Baptiste Mardelle
28a2b7fa96 Small cleanup and fix crash when switching to SDL display 2013-06-05 12:43:04 +02:00
Jean-Baptiste Mardelle
7ea11da975 Add missing files 2013-06-04 21:42:01 +02:00
Jean-Baptiste Mardelle
74343fc4ad Add missing files 2013-06-04 21:40:48 +02:00
Jean-Baptiste Mardelle
5388e17acd Add missing directory 2013-06-04 21:39:17 +02:00
Jean-Baptiste Mardelle
756d87e074 Merge my work, introducing OpenGL, GLSL and SDL display modes as well as new producer system based on effect system 2013-06-04 21:36:30 +02:00
Jean-Baptiste Mardelle
072944c953 Rewrite monitor code 2013-05-24 16:04:16 +02:00
Till Theato
6ef3bb63cc Move clip editing actions into own classes. 2013-04-07 16:10:24 +02:00
Till Theato
e329d11fed Prepare adding new clips to the timeline. 2013-03-04 20:27:16 +01:00
Till Theato
e01ad25458 Rename getHash() to hash() to follow coding style. 2013-02-18 19:18:12 +01:00
Till Theato
36d560caf6 Support more av mimetypes. 2013-02-18 19:09:33 +01:00
Till Theato
b7e0a9de00 Implement moving clips across tracks. 2013-02-13 21:09:42 +01:00
Till Theato
42bface06d Do not allow moving clips into gaps too small. 2013-02-13 19:57:18 +01:00
Till Theato
7e39c2b2ff Prepare for clip movement across tracks. 2013-02-03 21:05:39 +01:00
Jean-Baptiste Mardelle
420395edc8 Some progress on the bin's tree view painting 2013-02-01 23:20:58 +01:00
Jean-Baptiste Mardelle
d8b10cd44d Merge branch 'refactoring' of git://anongit.kde.org/kdenlive into refactoring 2013-02-01 20:04:16 +01:00
Jean-Baptiste Mardelle
1efe305ca2 Double clip in bin to add a clip 2013-02-01 20:04:00 +01:00
Till Theato
0ef794e39a Clean up timecode handling on startup. 2013-02-01 19:20:03 +01:00
Till Theato
78701001d8 Merge branch 'refactoring' of git://anongit.kde.org/kdenlive into refactoring 2013-02-01 19:16:54 +01:00
Till Theato
5813a31685 Fix leak. 2013-02-01 19:06:18 +01:00
Jean-Baptiste Mardelle
428196f276 Merge branch 'refactoring' of git://anongit.kde.org/kdenlive into refactoring 2013-02-01 18:50:27 +01:00
Jean-Baptiste Mardelle
c640110c7a Some preparation work for cached thumbnails 2013-02-01 18:45:21 +01:00
Till Theato
a717b1b7ab Properly intialize project parts.
This did not happen when no information was saved before.
Also fix related start-up problem.
2013-02-01 18:38:56 +01:00
Jean-Baptiste Mardelle
e4889dc7fe prepare for centralized thumbnail management 2013-01-29 15:31:21 +01:00
Jean-Baptiste Mardelle
7f874349bc Allow startup with empty doc without crashing 2013-01-29 13:31:18 +01:00
Jean-Baptiste Mardelle
72e99aaf5f Fix startup crash 2013-01-28 16:11:21 +01:00
Till Theato
c3b67e41c3 Introduce ShiftingProducer.
ShiftingProducer handles the connection to shifting producers, which
occur for example on some clip movements.
2012-11-21 22:09:54 +01:00
Till Theato
5f4f997774 Fix profile wrongly saved. 2012-11-18 15:58:00 +01:00
Till Theato
0cbc9b8ae8 Add "save as". 2012-11-18 15:41:47 +01:00
Till Theato
033c9e02b1 Also save bin, project parts and project settings. 2012-11-15 21:45:34 +01:00
Till Theato
d62751f74d Start work on saving projects.
In order to have the xml consumer save the properties Kdenlive adds
through MLT API we have to add a prefix to them and tell the consumer
about it.
2012-11-12 22:16:42 +01:00
Till Theato
e4d3bd9a34 Add some API documentation 2012-08-23 14:40:59 +02:00
Till Theato
bc083fabe4 Reformat. 2012-08-20 15:11:00 +02:00
Till Theato
69b1c53d0e Merge branch 'refactoring' of git://anongit.kde.org/kdenlive into refactoring
Conflicts:
	src/core/bin/bin.cpp
	src/core/bin/bin.h
	src/core/project/abstractprojectitem.h
2012-08-16 16:39:08 +02:00
Jean-Baptiste Mardelle
27042c59e0 Add basic support for loading video clips in project 2012-08-05 15:09:47 +02:00
Jean-Baptiste Mardelle
2499a8cb2a * Some progress on the bin (user can switch between icon view and tree view)
* Add improved seeking marker to monitor ruler (same as Shotcut)
2012-08-05 14:27:15 +02:00
Jean-Baptiste Mardelle
88083dae38 Revert unwanted commit 2012-07-23 09:25:16 +02:00
Jean-Baptiste Mardelle
173a31e8f7 added shotcut qglwidget 2012-07-05 18:54:57 +02:00
Till Theato
34f38ea16a Add API documentation. 2012-06-29 11:16:52 +02:00
Till Theato
0c76bc4ad6 Fix moving a clip close to another one. 2012-06-27 10:52:45 +02:00
Till Theato
d270407690 Resize background track when necessary. 2012-06-26 16:32:25 +02:00
Till Theato
38eaf619ef Implement simple inner track clip movement. 2012-06-26 14:18:37 +02:00
Till Theato
9705319ad5 Adopt to timeline duration changes. 2012-06-25 17:09:27 +02:00
Till Theato
8946f86005 Allow to store settings in project with less overhead. 2012-06-25 16:19:21 +02:00
Till Theato
d59d1c773f Store and load timeline view zoom level. 2012-06-25 16:18:00 +02:00
Till Theato
658688fe6b Start work on timeline tools.
For now only simple resizing works.
2012-06-25 14:42:05 +02:00
Till Theato
8fe051f21e Add generic plugin loader and notes widget. 2012-06-21 17:17:31 +02:00
Till Theato
cb432dc3b7 Fix track order and don't show background track. 2012-06-18 10:56:27 +02:00
Till Theato
a03f67fc3c Add track headers. 2012-06-18 09:58:34 +02:00
Till Theato
bde898da80 Add position indicator (line) to timeline view. 2012-06-14 12:16:19 +02:00
Till Theato
044fb8b3f7 Fix setting the position through the timeline position bar. 2012-06-14 11:52:36 +02:00
Till Theato
5e3005cb90 Position bar: Don't allow to drag indicator out of range. 2012-06-14 11:41:02 +02:00
Till Theato
b5bd0f7ff7 Restore producer position after creating thumbnail. 2012-06-14 11:34:44 +02:00
Till Theato
7954d56f4c Add basic timeline thumbnailing. 2012-06-14 11:21:57 +02:00
Till Theato
f50a792176 Properly notify the bin item view about insertions/deletions. 2012-06-13 18:03:45 +02:00
Till Theato
2da75f88ec Small cleanup. 2012-06-13 10:44:03 +02:00
Till Theato
563e40bc56 Introduce undo system. 2012-06-13 10:34:45 +02:00
Till Theato
8403250130 Add monitor manager and allow to play timeline. 2012-06-12 13:43:28 +02:00
Till Theato
92619653f7 Add TimecodeWidget to view and edit timecodes. 2012-06-11 12:06:11 +02:00
Till Theato
55043544bf Fix clip painting on zoomed timeline view. 2012-06-10 22:23:05 +02:00
Till Theato
730e0ff663 Fix timeline scene positioning. 2012-06-10 22:05:21 +02:00
Till Theato
c51cf04e33 Implement basic timeline zooming. 2012-06-10 21:29:12 +02:00
Till Theato
d5efda3811 Fix rounding problems in timeline position bar. 2012-06-10 21:15:14 +02:00
Till Theato
1e97ddc90d Small cleanup to position bar painting. 2012-06-08 08:34:08 +02:00
Till Theato
6ac3368bef Add timeline position bar/ruler. 2012-06-07 16:34:44 +02:00
Till Theato
124d5075f9 Add Timecode and TimecodeFormatter classes.
They replace GenTime and the current Timecode.
2012-06-06 15:53:41 +02:00
Till Theato
b0dbb8aef2 Add ProjectManager. Contains only open action so far. 2012-06-05 15:29:21 +02:00
Till Theato
7d5a55b5e6 Fix playback of newly added clips. 2012-06-05 14:20:04 +02:00
Till Theato
ccf85b0fe2 Enable playback of project clips. 2012-06-05 11:33:10 +02:00
Till Theato
245c23df89 Use KDualAction for monitor playback button. 2012-06-04 22:02:02 +02:00
Till Theato
4700403844 Implement simple adding of files (cliptype specific). 2012-06-04 21:43:11 +02:00
Till Theato
3dd55b31f9 Add singleton Core class for easy access of widely used objects. 2012-06-04 10:21:07 +02:00
Till Theato
a254a65994 Add position bar/ruler to monitor.
Also experiment with pixel buffer object (PBO) to upload the frames to the
GPU.
2012-06-01 22:55:50 +02:00
Till Theato
092439a1fe Fix delay when pausing playback. 2012-06-01 15:55:26 +02:00
Till Theato
42c57fd01a Fix monitor not properly resizable 2012-05-31 14:34:59 +02:00
Till Theato
c6e878daf3 Fix image alignment problem in monitor scene. 2012-05-31 14:24:45 +02:00
Till Theato
57f090a0c2 Initial work on new monitor.
OpenGL is used to draw the frames in a GraphicsScene, so it is zoomable
and no separate implementation is required for on monitor editing of
effects.
2012-05-31 12:10:14 +02:00
Till Theato
4381f2976a First work on timeline view (read only). 2012-05-27 11:17:47 +02:00
Till Theato
b5a933e558 First work on new project tree ("Bin").
A data -> model -> view separation is used to make it easy to add new
views in the future. The data which consists of clips and folders has a
common base class AbstractProjectItem to make data -> model interaction
and loading of documents straight forward. Inside the document file the
items are now stored in a more hierarchical way to represent this object
structure.
2012-05-24 12:13:44 +02:00
Till Theato
74505eed37 Initial work on project and timeline. 2012-05-22 10:59:53 +02:00
Till Theato
8732cad923 Implement some basic functionality for effect properties view.
Also fix kdenliveproperties include.
2012-05-15 16:15:10 +02:00
Till Theato
a9c346817a Start work on properties view widget for effects.
Also move library cmake to core/.
2012-05-15 11:07:20 +02:00
Till Theato
1373516253 Move the string color conversion functions to ColorParameter and make them static. 2012-05-14 11:25:29 +02:00
Till Theato
3887249b21 Port color parameter. 2012-05-14 11:06:39 +02:00
Till Theato
3896d5d0d5 Some renaming in the parameter plugins. 2012-05-14 09:04:43 +02:00
Till Theato
100a68c7db Remove leftover files from rename in previous commit. 2012-05-14 00:18:44 +02:00
Till Theato
2d998e5f52 Fix wrong connection in boolean parameter properties view.
Also change names a bit.
2012-05-14 00:16:21 +02:00
Till Theato
997db532ce Port list parameter.
This requires a change in the descriptions for parameters that use
double values as items. listitemtype="double" has to be added to make
sure that proper locale conversion are done.
2012-05-13 23:58:20 +02:00
Till Theato
bafa25b5bb Add parameter type "fixed" and simplify its XML description.
Only some effect descriptions are updated. In other cases a different
treatment is required anyways (e.g. the fades).
2012-05-13 16:00:09 +02:00
Till Theato
4474c3bdce Fix getting double parameter value from filter. 2012-05-13 15:25:57 +02:00
Till Theato
b5c101970a Fix build and typo. 2012-05-13 13:41:46 +02:00
Till Theato
51e4829d89 Add documentation to most of the new code.
Also stop using the prefix 'get' for accessors.
2012-05-12 23:35:17 +02:00
Till Theato
6ea3e0483c Move generic parameter value getter to AbstractParameter. 2012-05-10 12:44:52 +02:00
Till Theato
5306c68f87 Port parameter boolean 2012-05-10 12:41:52 +02:00
Till Theato
07f7357724 Introduce new effect system base class to simplify handling the views.
Additionally hack new effect system into existing code to test it.
2012-05-10 11:05:10 +02:00
Till Theato
e8ef2ff696 Add missing files. 2012-05-09 15:24:50 +02:00
Till Theato
4afcb530a4 Create parameters through their description object.
This way no knowlegde about the parameter type is required outside of
the plugin.
2012-05-09 15:22:13 +02:00
Till Theato
efb72f3bf9 Load the (effect) parameter types as plugins.
This required the introduction of a library to be able to access
effectsystem base classes and used widgets.
The library "kdenlivecore" is currently in src/core/ but might at a
later point of refactoring be moved up to src/ when it contains major
parts of the source to enable a powerful plugin system.
2012-05-09 11:23:58 +02:00
Till Theato
eb3b733dc8 Use the effectdescription to create new effects. 2012-05-07 14:34:30 +02:00
Till Theato
b39703956a Initial work on a new effect list loading system. 2012-05-03 20:42:21 +02:00
Till Theato
04e1945deb Add empty EffectDevice class.
This will be the connection to the clip or track or ...
2012-05-02 23:36:19 +02:00
Till Theato
de770d924b First work on effects refactoring.
Setup of a rough outline of the new structure.
2012-05-02 22:37:23 +02:00
852 changed files with 32263 additions and 131267 deletions

View File

@@ -2,10 +2,10 @@ project(kdenlive)
# An odd patch version number means development version, while an even one means
# stable release. An additional number can be used for bugfix-only releases.
set(KDENLIVE_VERSION 0.9.7)
set(KDENLIVE_VERSION 0.9.9)
# Minimum versions of main dependencies.
set(LIBMLT_MIN_VERSION 0.8.8)
set(LIBMLT_MIN_VERSION 0.9.0)
set(QT_MIN_VERSION 4.5.0)
set(KDE_MIN_VERSION 4.3.0)
@@ -78,18 +78,12 @@ macro_log_feature(LIBMLT_FOUND
add_subdirectory(data)
macro_optional_add_subdirectory(doc)
add_subdirectory(effects)
add_subdirectory(export)
add_subdirectory(icons)
add_subdirectory(lumas)
add_subdirectory(man)
add_subdirectory(plugins)
macro_optional_add_subdirectory(po)
add_subdirectory(renderer)
add_subdirectory(src)
add_subdirectory(thumbnailer)
add_subdirectory(titles)
add_subdirectory(testingArea)
macro_display_feature_log()
configure_file(config-kdenlive.h.cmake config-kdenlive.h @ONLY)
add_subdirectory(producers)

206
ChangeLog
View File

@@ -1,206 +0,0 @@
0.9.6
* Fix keyframes when cutting a clip / undoing a clip cut
* Warn before overwriting .mlt stabilized file
* Fix monitor confusion (clip monitor sometimes playing timeline,...)
* Fix the Mono to Stereo effect UI
* Fix proxy of playlist having wrong aspect ratio in some locales
* Fix transition widget not correctly updated when resizing a transition
* Fix DVD chapters broken when using an intro movie
* Fix error message (No matching profile) poping up in render widget when everything was ok
* Fix clip keyframes not showing on project load
* Fix bug when moving guide (was not moving to the correct place)
* Fix project corruption (wrong character) caused by some clip's metadata
* Fix possible crash on track deletion
* Fix timeline corruption when using spacer tool or overwrite edit mode
* Fix possible crash when editing speed effect
* Fix transition losing all its properties when moved
* Fix crash when pressing del when editing animation in title widget
* Fix crash when doing quick clip resize
* Fix corruption when groups where overlapping
* Fix corruption when adding a title clip where a transition already existed
* Fix timeline preview corruption with some transitions
0.9.4
* Fix color parameter in some effects not working correctly (#2644)
* Fix V4l licensing issue (#2632)
* Fix keyframes lost / broken when pasting an effect
0.9.2
* Fix firewire capture (preview not showing)
* Fix freeze when reloading previously missing clip
* Fade effects lost when moving / resizing clip
* Undoing change in clip crop start breaking clip
* Make disabling of track effects possible
* Fix slideshow clips not working
* Fix crash on composite transition
* Fix crash when opening stop motion widget
* Fix rendering of projects created in another locale
0.9
* Fix monitor effect scene sometimes forcing monitor minimum size
* Improve detection of locale issues (default to POSIX when there is a locale conflict on the system)
* Improve timeline operation for small clips (disable resizing, only allow move)
* Add background color parameter to "Rotate" and "Pan and Zoom" effects
* Allow to scroll using the mouse wheel in monitor editing scene
* Zoom to mouse when using CTRL + mouse wheel in monitor editing scene
* Add support for new slope mode in "Color Selection" effect to allow smooth alpha transition
* Introduce grouping of effects; groups can also be saved
* Allow dragging an effect to another clip/track
* Allow record monitor to go fullscreen
* Image sequences can now start at an arbitrary frame (http://kdenlive.org/mantis/view.php?id=2508)
* Add automatic clip alignment based on audio (experimental, has to be manually enabled)s
* Allow archiving for offline use (only archive proxies)
* Offline editing: Allow working on project with only proxies available (http://kdenlive.org/mantis/view.php?id=2509)
* Allow rendering to another framerate
* Check for missing locale and ask to install instead of opening corrupted project
* Allow to open project files manually extracted from archived project
* Support dropping a folder in the project tree (http://kdenlive.org/mantis/view.php?id=1288)
* Add "select all clips in track" and "select all clips in timeline" features (http://kdenlive.org/mantis/view.php?id=1950)
* Put audio effects in subcategories to avoid uberlong menus (http://kdenlive.org/mantis/view.php?id=2436)
* Support for project metadata (can be embedded in rendered file)
* Add Online Resource Widget allowing easy search and download of online services (freesound, openclipart, archive.org)
* Introduce MLT clip analysis to get auto normalize data in sox gain effect
* Connect recording to audio scopes
* Add audio only recording (works while playing)
* Add extract zone function: part of clip is copied to new file without re-encoding
* Introduce generic job framework to process clips
* Improve the Choose color widget: Use less space and make it easier to pick the average color value from an area
* Add GUI for effect Dynamic Text: Allows to display timecode/framecount and other data
* Rework effect stack: All effects are shown at once and are collapsible
* Add two different video stabilizers
* Add IIR Blur GUI
* Add date column to project tree
* Fix clip move sometimes giving error when it should work
* Fix custom effects not considering capital letters in name (http://kdenlive.org/mantis/view.php?id=2580)
* Fix script rendering when script name contains whitespace
* Ensure clip in project tree is visible after rename (scroll if necessary) (http://kdenlive.org/mantis/view.php?id=2563)
* Fix monitor scene never resetting scrollbars
* Fix issues with transitions when inserting track (http://kdenlive.org/mantis/view.php?id=2477)
* Fix some GUI elements not responding to color theme change
* Do not hide render profile list when there is only one item to avoid confusion (http://kdenlive.org/mantis/view.php?id=2543)
* Fix consecutive error messages overwriting each other (http://www.kdenlive.org/mantis/view.php?id=2519)
* Fix crash when editing properties of several missing clips
* Fix vectorscope for 24b RGB images (http://kdenlive.org/mantis/view.php?id=2478)
* Fix archiving sometimes not saving playlist clips and subclips (http://kdenlive.org/mantis/view.php?id=2475)
* Fix archiving feature not saving playlist clips and slowmotion clips inside them (http://kdenlive.org/mantis/view.php?id=2475)
* Fix crash recovery feature issues with long or non UTF-8 filenames (http://kdenlive.org/mantis/view.php?id=2441, http://kdenlive.org/mantis/view.php?id=2450)
* Fix rendering jobs sometimes not starting
* Fix crash on proxy creation (concurrency issue) (http://kdenlive.org/mantis/view.php?id=2471)
* Fix zone playing (http://kdenlive.org/mantis/view.php?id=2468)
* Fix click on monitor sometimes not triggering play
* Fix crash when moving a folder and a clip in project tree (http://kdenlive.org/mantis/view.php?id=2458)
* Fix color change not working in title widget (http://kdenlive.org/mantis/view.php?id=2459)
* Fix slideshow clips created with invalid frame duration
* Fix profile warning with clips that have 1088 pixels height
* Fix unnecessary proxy reload on document load
* Fix detection of broken render scripts
0.8.2.1
* Fix title text oultine transparency not working
* Make titler window fit on smaller resolutions (1024x768)
* Fix corruption when undoing and redoing a transition add + move
* Fix possible crash in thumbnails
* Fix possible crashes in clip transcoding and improve feedback when failing
* Various small optimizations (unnecessary clip reloads)
* Fix timecode widget hard to edit and sometimes giving random values
* Workaround locale issue ahappening when system C locale and Qt's locale did not give the same numeric separator
* Fix audio thumbnail concurrency issue
* Fix various video thumbnails issues (don't load several times the same thumb, load all of them, ...)
* Fix crash when opening a file dialog on KDE < 4.5
* Fix various proxy issues (missing extension, concurrency, disabling broken proxy, ...)
* Fix startup crash caused by invalid parsing of v4l data
* Fix project tree disabled after loading some projects / creating new one
* Fix corrupted timeline / monitor timecode
* Fix search path for Luma files when missing
0.8.2
* Load zone thumbnails from disk if available.
* Optimise document loading.
* In case of missing or invalid clips, open only one dialog box instead of one for each clip.
* Display proxy creation progress in project tree.
* Improve way of picking an average color of an area.
* Make audio bitrate in render dialog selectable.
* Add support for handling different versions of filters and add rules to convert between them.
* Move all cached data in one operation, so that user does not get one dialog box for each file in case of duplicates. (http://kdenlive.org/mantis/view.php?id=2297)
* Show filter version in filter info box.
* When multiple clips are selected do not allow resizing, but moving only. (http://kdenlive.org/mantis/view.php?id=2257)
* Add remux with MKV transcode preset.
* Make audio only render profiles faster by telling ffmpeg to skip video.
* Open documents using a locale different to the system as read only.
* Replace locale-dependent comma with slash in geometry value.
* Add Kdenlive manual converted from UserBase QuickStart page.
* Improve handling of missing luma files. (http://kdenlive.org/mantis/view.php?id=2216)
* Remove the "avformat-novalidate" trick for faster loading, caused crash. (http://kdenlive.org/mantis/view.php?id=2205)
* Allow to assign a shortcut to usage of proxies in project.
* Use separate thread for generation of timeline thumbnails when zoom is at frame level to keep UI responsive.
* Allow to use JScript in render profile parameter values. Values that need evalutation need to be indicated by '%'.
* Check for missing proxies on document opening.
* Check document for invalid (overlapping) transitions.
* Check for duration mismatch in clip producers when opening a document (can cause corruption).
* Automatically create backups of the project file; they can be restored in a recovery dialog.
* Allow to manually edit video4linux capture profile.
* Allow to store presets for proxy creation parameters.
* Enable proxies for playlist clips (*.mlt, *.kdenlive).
* Directly encode capture from Decklink card to make it usable in Kdenlive.
* Allow to use bitrate different from presets in render dialog.
* Whole projects (including all necessary files) can be archieved into a directory or file.
* Allow use of different ffmpeg preset for 1st and 2nd render pass.
* Notes widget: context menu now allows to insert clickable timecode to make easy reference to some place in the project.
* Fix encoding of dvd vob menu file.
* Fix possible crash when doing fast start/stop.
* Fix multiple concurrency crashes related to thumbnail and proxy creation.
* Fix name of dvgrab captured file. (http://kdenlive.org/mantis/view.php?id=2344)
* Fix issues with simultaneous 2-pass rendering (x264). (http://kdenlive.org/mantis/view.php?id=2338)
* Fix rendering progress not shown if multiple copies of Kdenlive are open. (http://kdenlive.org/mantis/view.php?id=1265)
* Fix DVD chapters discarded when opening from render dialog. (http://kdenlive.org/mantis/view.php?id=2335)
* Fix possible corruption caused by vertical offset of transitions in timeline.
* Fix aspect ratio of thumbnails to correctly use the project's arpect ratio.
* Fix bitrate broken when editing render profile or making it a favorite. (http://kdenlive.org/mantis/view.php?id=2321)
* Fix audio issues in rendered file when using a recent ffmpeg version by replacing 'b' with 'vb' (ffmpeg bitrate parameter). (http://kdenlive.org/mantis/view.php?id=2318)
* Fix rendering to Flash could be broken by setting the number of encoder threads. (http://kdenlive.org/mantis/view.php?id=2312)
* Fix DVD wizard losing chapters data when switching to menu page.
* Fix previewing of affine transitions with transparent png.
* Fix timeline corruption when using 'Remove space' tool (transitions could overlap).
* Fix 'adjust to original size' and 'fit to width/height' for title and color clips in geometry widget (pan and zoom, composite, affine).
* Fix vorbis rendering by setting the audio quality (aq).
* Rotoscoping: do not allow to add keyframes until initial spline is created to avoid corruptions.
* Fix possible crash in DVD wizard chapters. (http://kdenlive.org/mantis/view.php?id=2264)
* Do not duplicate effect stack after split audio but move audio effects only.
* Fix issues related to the usage of comma as numeric separator in some locales.
* Fix build on GNU/kFreeBSD.
* Fix cursor not visible in title widget. (http://kdenlive.org/mantis/view.php?id=2231)
* Fix aspect ratio in title widget background image. (http://kdenlive.org/mantis/view.php?id=2225)
* Fix layout in save profile dialog. (http://kdenlive.org/mantis/view.php?id=2224)
* Fix timeline corruption because resizing a clip end could overlap another clip in some cases.
* Fix last keyframe for composite transition (and other geometry effects) inserted one frame after the end of the transition.
* Prevent crash when deleting a clip while playing. (http://kdenlive.org/mantis/view.php?id=2200)
* Disable save action if we are in the same state as last save.
* Fix pan and zoom keyframes lost after clip resize. (http://kdenlive.org/mantis/view.php?id=2210)
* Fix mouse wheel in slider section of (effect) parameters with a large range (> 1000).
* Fix GUI setup issues with some list parameters (for effects).
* Fix timecode widget not communicating changes upon focus leave.
* Fix list of effects in effect stack taking up to much space by default.
* Fix transition track not correctly saved. (http://kdenlive.org/mantis/view.php?id=2187)
* Fix "save zone" saving proxy instead of real clip. (http://kdenlive.org/mantis/view.php?id=2184)
* Fix freeze when saving while timeline is at maximum zoom. (http://kdenlive.org/mantis/view.php?id=2174)
* Fix crash when deleting a track and having an audio clip on last track. (http://kdenlive.org/mantis/view.php?id=2168)
* Do not allow to create overlapping transitions that could corrupt timeline. (http://kdenlive.org/mantis/view.php?id=1901)
* Fix sometimes effects were missing. (http://kdenlive.org/mantis/view.php?id=2152)
* Fix crash in histogram scope.
* Fix multiple possible timeline corruptions. (http://kdenlive.org/mantis/view.php?id=2157)
* Do not allow rendering to a frame rate different than current project's profile. (http://kdenlive.org/mantis/view.php?id=2138)
* Fix DVD menu entries hidden under some circumstances.
* Fix channels in audio thumbnails being displaced by one frame. (http://kdenlive.org/mantis/view.php?id=1976)
* Fix possible crash caused by audio thumbnails. (http://kdenlive.org/mantis/view.php?id=2147)
* Fix possible freeze and error on project opening. (http://kdenlive.org/mantis/view.php?id=2144)
* Fix progress bar running twice on 2pass render.
* Fix proxy file path issue on system installation.
* Use luma as default channel for levels effect.
* Fix handling of proxies when duration != duration of original clip.
* Fix filename encoding problem in renderer. (http://kdenlive.org/mantis/view.php?id=2110)
* Fix user specified CFLAGS ignored. (http://kdenlive.org/mantis/view.php?id=2108)
0.8
See http://kdenlive.org/discover/0.8

70
TODO
View File

@@ -1,70 +0,0 @@
Some ideas for a big refactoring of code.
Input
=========
handle MLT connection ((re-)move from renderer.cpp (hacks, special cases))
handle project document entry
draw layer on clip instances in timeline (thumbnails)
settings management (available through project tree items)
proxy creation
input method (register mimetype in file dialog, custom widget)
effect support (a, v, av, special effects (freeze, speed))
support for multi-channel sound (5.1, ...)
=> modules for avformat, qimage/gtk_image(?), generators (slideshow, color, f0r)
Timeline
=========
provides basic operations (resize, move, add, remove) (GUI + XML + MLT) to be applied on any item
=> modules for input modes (drag & drop, 3/4-point editing, cut, resize by dragging end), spacer, ripple edit, push/pull edit, ...)
Clip instances
-------
connection to input module
manage project document entry
information about support for timeline operations
owns an effect device
per instance settings (functionality provided by input module)
graphical timeline item (modules can register layers they want to draw (thumbnails, effect names, keyframes))
Clip groups
------
manage project document entry
pass on operations to items
Effect system
=========
Keyframe manager
------
pipe information from/to timeline effect device, effect stack, effect parameter
Effect parameter
------
custom widget
function to handle keyframes -> connect to keyframe manager
written in QScript/QML ?
Effect device
------
manages list of effects attached to clip, track, timeline, group, the world
passes info from/to timeline items and effect stack
manage project document entry
Project
=========
read/write
project settings management
provide functionality to manage settings (remove hardcoded stuff (slideshow, proxy, ...))
Interface
=========
provide functions to add menu items, global actions (for shortcut management)
layout management
styles management (see digikam)
...

545
dependencies.svg Normal file
View File

@@ -0,0 +1,545 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="471.37357"
height="312.8873"
id="svg2"
version="1.1"
inkscape:version="0.48.4 r9939"
sodipodi:docname="kdenlive-mlt-diagram.svg"
inkscape:export-filename="/tmp/kdenlive-mlt-diagram.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
<defs
id="defs4">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective10" />
<inkscape:perspective
id="perspective3625"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3652"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3725"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3725-8"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3725-9"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3725-80"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<marker
markerWidth="31.09709"
markerHeight="16.823833"
orient="auto"
id="marker3777">
<path
style="fill:#eeeeee;fill-opacity:1;stroke:none"
d="m -15.548545,-8.3235343 c 0.98737,-0.987372 31.09709,6.586995 31.09709,8.33243898 0,1.84100902 -30.23094,9.19859202 -31.09709,8.33244002 l 0,-16.664879 z"
id="path3775"
sodipodi:nodetypes="cccc" />
</marker>
<marker
markerWidth="10.3371"
markerHeight="5.5924713"
orient="auto"
id="marker4150">
<path
style="fill:#eeeeee;fill-opacity:1;stroke:none"
d="m -5.16855,-2.7668562 c 0.32822,-0.328216 10.3371,2.18960696 10.3371,2.76981596 0,0.611977 -10.04918,3.05773704 -10.3371,2.76981704 l 0,-5.539633 z"
id="path4148"
sodipodi:nodetypes="cccc" />
</marker>
<inkscape:perspective
id="perspective4723"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<marker
markerWidth="10.3371"
markerHeight="5.5924711"
orient="auto"
id="marker4150-6">
<path
style="fill:#eeeeee;fill-opacity:1;stroke:none"
d="m -5.16855,-2.7668562 c 0.32822,-0.328216 10.3371,2.18960696 10.3371,2.76981596 0,0.611977 -10.04918,3.05773704 -10.3371,2.76981704 l 0,-5.539633 z"
id="path4148-2"
sodipodi:nodetypes="cccc" />
</marker>
<inkscape:perspective
id="perspective4723-5"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<marker
markerWidth="10.3371"
markerHeight="5.5924711"
orient="auto"
id="marker4150-68">
<path
style="fill:#eeeeee;fill-opacity:1;stroke:none"
d="m -5.16855,-2.7668562 c 0.32822,-0.328216 10.3371,2.18960696 10.3371,2.76981596 0,0.611977 -10.04918,3.05773704 -10.3371,2.76981704 l 0,-5.539633 z"
id="path4148-5"
sodipodi:nodetypes="cccc" />
</marker>
<inkscape:perspective
id="perspective4723-2"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<marker
markerWidth="10.3371"
markerHeight="5.5924711"
orient="auto"
id="marker4150-3">
<path
style="fill:#eeeeee;fill-opacity:1;stroke:none"
d="m -5.16855,-2.7668562 c 0.32822,-0.328216 10.3371,2.18960696 10.3371,2.76981596 0,0.611977 -10.04918,3.05773704 -10.3371,2.76981704 l 0,-5.539633 z"
id="path4148-7"
sodipodi:nodetypes="cccc" />
</marker>
<inkscape:perspective
id="perspective4723-6"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<marker
markerWidth="10.3371"
markerHeight="5.5924711"
orient="auto"
id="marker4150-8">
<path
style="fill:#eeeeee;fill-opacity:1;stroke:none"
d="m -5.16855,-2.7668562 c 0.32822,-0.328216 10.3371,2.18960696 10.3371,2.76981596 0,0.611977 -10.04918,3.05773704 -10.3371,2.76981704 l 0,-5.539633 z"
id="path4148-22"
sodipodi:nodetypes="cccc" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#282828"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:zoom="1.4323"
inkscape:cx="377.1885"
inkscape:cy="156.24755"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:snap-bbox="true"
inkscape:bbox-nodes="true"
inkscape:bbox-paths="true"
inkscape:window-width="1364"
inkscape:window-height="713"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:showpageshadow="false"
showborder="false"
inkscape:snap-global="false"
showguides="true"
inkscape:guide-bbox="true" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="BG"
sodipodi:insensitive="true">
<rect
style="color:#000000;fill:#282828;fill-opacity:1;fill-rule:nonzero;stroke:#282828;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect2843"
width="469.87357"
height="311.3873"
x="0.75"
y="0.74999857"
rx="6.9817758"
ry="6.9817758" />
</g>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-45.329731,-60.897953)">
<text
xml:space="preserve"
style="font-size:27.2442379px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#eeeeee;fill-opacity:1;stroke:none;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"
x="283.32236"
y="332.06137"
id="text2816"
sodipodi:linespacing="100%"><tspan
sodipodi:role="line"
id="tspan2818"
x="283.32236"
y="332.06137">kdenlive</tspan></text>
<text
xml:space="preserve"
style="font-size:14.01654053px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#eeeeee;fill-opacity:1;stroke:none;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"
x="170.04121"
y="141.98691"
id="text2820"
sodipodi:linespacing="100%"><tspan
sodipodi:role="line"
id="tspan2822"
x="170.04121"
y="141.98691">Frei0r</tspan></text>
<text
xml:space="preserve"
style="font-size:11.89307213px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#eeeeee;fill-opacity:1;stroke:none;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"
x="333.90146"
y="137.10045"
id="text2824"
sodipodi:linespacing="100%"><tspan
sodipodi:role="line"
id="tspan2826"
x="333.90146"
y="137.10045">SoX</tspan></text>
<text
xml:space="preserve"
style="font-size:22.63406181px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#eeeeee;fill-opacity:1;stroke:none;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"
x="251.84148"
y="241.51353"
id="text2828"
sodipodi:linespacing="100%"><tspan
sodipodi:role="line"
id="tspan2830"
x="251.84148"
y="241.51353">MLT</tspan></text>
<text
xml:space="preserve"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr;text-anchor:start;fill:#eeeeee;fill-opacity:1;stroke:none;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"
x="133.70102"
y="244.91959"
id="text2832"
sodipodi:linespacing="100%"><tspan
sodipodi:role="line"
id="tspan2834"
x="133.70102"
y="244.91959">ffmpeg</tspan></text>
<text
xml:space="preserve"
style="font-size:11.37970638px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#eeeeee;fill-opacity:1;stroke:none;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"
x="319.48306"
y="173.76093"
id="text2836"
sodipodi:linespacing="100%"><tspan
sodipodi:role="line"
id="tspan2838"
x="319.48306"
y="173.76093">LADSPA</tspan></text>
<g
id="g3618"
transform="matrix(0.98815313,-0.15347112,0.15347112,0.98815313,-81.414431,-4.1588633)"
style="fill:#eeeeee;fill-opacity:1">
<path
sodipodi:nodetypes="cc"
id="path2840"
d="m 456.25917,185.68219 0,37.38942"
style="fill:#eeeeee;fill-opacity:1;stroke:#eeeeee;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<path
inkscape:transform-center-y="-1.3963555"
transform="matrix(0.99227788,-0.12403474,0.12403474,0.99227788,-21.929088,58.404098)"
d="m 454.86282,222.22884 c 0,2.60275 -3.43844,4.7127 -7.67996,4.7127 -4.24152,0 -7.67995,-2.10995 -7.67995,-4.7127 0,-2.60276 3.43843,-4.7127 7.67995,-4.7127 4.24152,0 7.67996,2.10994 7.67996,4.7127 z"
sodipodi:ry="4.7126999"
sodipodi:rx="7.679955"
sodipodi:cy="222.22884"
sodipodi:cx="447.18286"
id="path2842"
style="color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.20999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
sodipodi:type="arc" />
<path
sodipodi:nodetypes="cccc"
id="path2844"
d="m 477.57192,200.70203 c -17.10535,-0.69818 -7.06241,-14.14643 -20.67901,-15.01916 l 0,4.33654 c 10.49929,-1.82834 11.16527,8.53878 20.67901,10.68262 z"
style="fill:#eeeeee;fill-opacity:1;stroke:none" />
</g>
<text
xml:space="preserve"
style="font-size:13.83212471px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#eeeeee;fill-opacity:1;stroke:none;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"
x="385.48517"
y="182.45871"
id="text3623"
sodipodi:linespacing="100%"><tspan
sodipodi:role="line"
id="tspan3625"
x="385.48517"
y="182.45871">SRC</tspan></text>
<g
id="g3631"
transform="matrix(0.99709206,0.07620643,-0.07620643,0.99709206,-20.899324,-80.097483)"
style="fill:#eeeeee;fill-opacity:1;stroke:none">
<rect
rx="0"
ry="0"
y="204.02309"
x="147.00932"
height="14.623979"
width="29.178928"
id="rect3627"
style="color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.98357183;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
transform="matrix(0.9642511,-0.26499023,0.26499023,0.9642511,0,0)"
inkscape:transform-center-y="-6.2147158"
inkscape:transform-center-x="-13.932476"
style="color:#000000;fill:#eeeeee;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.98357183;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect3629"
width="29.178928"
height="3.6175911"
x="87.837669"
y="230.97163"
ry="0"
rx="0" />
</g>
<text
xml:space="preserve"
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:100%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr;text-anchor:start;color:#000000;fill:#6491e3;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"
x="96.729767"
y="103.21655"
id="text3640"
sodipodi:linespacing="100%"><tspan
sodipodi:role="line"
id="tspan3642"
x="96.729767"
y="103.21655">Video Effects</tspan></text>
<text
sodipodi:linespacing="100%"
id="text3667"
y="215.34749"
x="65.922745"
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:100%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr;text-anchor:start;color:#000000;fill:#6491e3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"
xml:space="preserve"><tspan
y="215.34749"
x="65.922745"
id="tspan3669"
sodipodi:role="line">Coding/Decoding, Transcoding</tspan></text>
<text
xml:space="preserve"
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:100%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr;text-anchor:start;color:#000000;fill:#6491e3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"
x="384.85358"
y="326.44742"
id="text3671"
sodipodi:linespacing="100%"><tspan
sodipodi:role="line"
id="tspan3673"
x="384.85358"
y="326.44742">Nonlinear Editor GUI</tspan></text>
<text
xml:space="preserve"
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:100%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr;text-anchor:start;color:#000000;fill:#6491e3;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro;stroke-width:1"
x="317.05167"
y="241.56248"
id="text3675"
sodipodi:linespacing="100%"><tspan
sodipodi:role="line"
id="tspan3677"
x="317.05167"
y="241.56248">Rendering, Effects</tspan></text>
<text
xml:space="preserve"
style="font-size:9px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
x="301.14859"
y="26.54929"
id="text3679"
sodipodi:linespacing="100%"
transform="translate(45.329731,60.897953)"><tspan
sodipodi:role="line"
id="tspan3681"
x="301.14859"
y="26.54929" /></text>
<text
sodipodi:linespacing="100%"
id="text3683"
y="99.640968"
x="386.87796"
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:100%;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr;text-anchor:start;color:#000000;fill:#6491e3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"
xml:space="preserve"><tspan
y="99.640968"
x="386.87796"
id="tspan3685"
sodipodi:role="line">Audio Effects</tspan></text>
<text
xml:space="preserve"
style="font-size:8.99999998px;font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr;text-anchor:start;fill:#eeeeee;fill-opacity:1;stroke:none;font-family:Source Code Pro;-inkscape-font-specification:Source Code Pro Heavy"
x="117.68263"
y="221.66136"
id="text3687"
sodipodi:linespacing="100%"
transform="matrix(0.97894222,0.20413754,-0.20413754,0.97894222,0,0)"><tspan
sodipodi:role="line"
id="tspan3689"
x="117.68263"
y="221.66136">0111010...</tspan></text>
<g
id="g3707"
transform="matrix(0.98972711,-0.14296942,0.14296942,0.98972711,13.042295,51.643621)">
<rect
ry="0"
rx="0"
transform="translate(45.329731,60.897953)"
y="231.89868"
x="61.788731"
height="11.519938"
width="82.73407"
id="rect3691"
style="color:#000000;fill:none;stroke:#eeeeee;stroke-width:1.5;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
style="color:#000000;fill:none;stroke:#eeeeee;stroke-width:1.5;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect3693"
width="82.73407"
height="11.519938"
x="107.11846"
y="304.31656"
rx="0"
ry="0" />
<rect
y="293.06757"
x="107.16393"
height="10.861097"
width="19.00692"
id="rect3695"
style="color:#000000;fill:#eeeeee;fill-opacity:1;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
style="color:#000000;fill:#eeeeee;fill-opacity:1;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect3697"
width="9.1331959"
height="10.861084"
x="123.94926"
y="304.91605" />
<rect
y="293.19101"
x="130.12033"
height="10.861084"
width="9.1331959"
id="rect3699"
style="color:#000000;fill:#eeeeee;fill-opacity:1;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
style="color:#000000;fill:#eeeeee;fill-opacity:1;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect3701"
width="22.215879"
height="10.861084"
x="136.53825"
y="304.79263" />
<rect
ry="0"
rx="0"
y="315.91818"
x="107.11846"
height="11.519938"
width="82.73407"
id="rect3703"
style="color:#000000;fill:none;stroke:#eeeeee;stroke-width:1.5;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
style="color:#000000;fill:#eeeeee;fill-opacity:1;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect3705"
width="6.664763"
height="10.861084"
x="156.53255"
y="316.39426" />
</g>
<path
style="fill:#eeeeee;fill-opacity:1;stroke:none"
d="m 384.61901,7.4179919 c 0.32822,-0.328216 10.3371,2.189607 10.3371,2.7698161 0,0.611977 -10.04918,3.057737 -10.3371,2.769817 l 0,-5.5396331 z"
id="path3773"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;stroke:#eeeeee;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker4150)"
d="m 212.94421,150.21188 c 0,0 -8.02904,-35.25797 -50.61788,-54.10877"
id="path4153"
transform="translate(45.329731,60.897953)"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#eeeeee;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;color:#000000;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#marker4150);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 230.39866,150.91006 c 4.88724,-39.09795 37.00342,-53.759686 37.00342,-53.759686"
id="path4713"
transform="translate(45.329731,60.897953)" />
<path
style="fill:none;stroke:#eeeeee;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;color:#000000;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#marker4150);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 197.96818,173.66778 c -29.62118,-2.96211 -45.91282,2.96212 -45.91282,2.96212"
id="path4742"
transform="translate(45.329731,60.897953)" />
<path
style="fill:none;stroke:#eeeeee;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;color:#000000;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#marker4150);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 286.91992,244.25038 c -13.07116,-29.24727 -43.17751,-55.8918 -43.17751,-55.8918"
id="path4756"
transform="translate(45.329731,60.897953)"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#eeeeee;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;color:#000000;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#marker4150);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 229.40673,262.19851 c -54.65634,-23.5566 -85.74404,-69.77065 -85.74404,-69.77065"
id="path4770"
transform="translate(45.329731,60.897953)"
sodipodi:nodetypes="cc" />
<text
sodipodi:linespacing="100%"
id="text3861"
y="162.93225"
x="159.56856"
style="font-size:14.01654053px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#eeeeee;fill-opacity:1;stroke:none;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"
xml:space="preserve"><tspan
y="162.93225"
x="159.56856"
id="tspan3863"
sodipodi:role="line">Movit</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -1,4 +0,0 @@
kde4_create_handbook(index.docbook
INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en
SUBDIR kdenlive
)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 249 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 313 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -1,357 +0,0 @@
<?xml version="1.0" ?>
<!DOCTYPE book PUBLIC "-//KDE//DTD DocBook XML V4.2-Based Variant V1.1//EN" "dtd/kdex.dtd" [
<!ENTITY % addindex "IGNORE">
<!ENTITY % English "INCLUDE">
]>
<book id="kdenlive" lang="&language;">
<bookinfo>
<title>The Kdenlive Quick Start Guide</title>
<authorgroup>
<author>
<personname>
<firstname>This documentation was converted from the KDE UserBase <ulink url=" http://userbase.kde.org/Kdenlive/Manual/QuickStart">Kdenlive/Manual/QuickStart</ulink> page.</firstname>
<surname></surname>
</personname>
</author>
<!-- TRANS:ROLES_OF_TRANSLATORS -->
</authorgroup>
<legalnotice>&FDLNotice;</legalnotice>
<date>2011-06-17</date>
<releaseinfo>0.8.2</releaseinfo>
<abstract>
<para></para>
</abstract>
<keywordset>
<keyword>KDE</keyword>
<keyword>multimedia</keyword>
<keyword>video</keyword>
</keywordset>
</bookinfo>
<!--userbase <timestamp>2011-06-17T15:39:59Z</timestamp>-->
<!--userbase-content-->
<chapter id="creating-a-new-project"><title>Creating a new project</title>
<para>
<screenshot>
<screeninfo></screeninfo>
<mediaobject>
<imageobject>
<imagedata fileref="Kdenlive_Quickstart-Folder-Structure.png" format="PNG"/>
</imageobject>
<textobject>
<phrase>Kdenlive directory structure</phrase>
</textobject>
<caption>
<para>Kdenlive directory structure</para>
</caption>
</mediaobject>
</screenshot></para>
<para>The first step is creating a new (empty) folder for our new project. I will call it <filename>quickstart-tutorial/</filename> in this tutorial. Then get some sample video clips, or download them from here:<ulink url="http://granjow.net/uploads/kdenlive/manual/kdenlive-tutorial-videos-2011-avi.tar.bz2">kdenlive-tutorial-videos-2011-avi.tar.bz2</ulink> (7 MB)<footnote><para>If you prefer Theora (which you probably dont since Ogg Video usually causes problems), you can alternatively download <ulink url="http://granjow.net/uploads/kdenlive/manual/kdenlive-tutorial-videos-2011-ogv.tar.bz2">kdenlive-tutorial-videos-2011-ogv.tar.bz2</ulink>.</para></footnote>, and extract them to &eg; a <filename>quickstart-tutorial/Videos/</filename> subfolder inside the project folder.</para>
<para>The image on the left shows the suggested directory structure: Each project has its own directory, with video files in the <filename>Videos</filename> subdirectory, audio files in the <filename>Audio</filename> directory, &etc; (<ulink url="http://userbase.kde.org/Special:myLanguage/Kdenlive/Manual/Projects_and_Files#File_Structure">read more</ulink>)</para>
<para>(The tutorial from now on assumes that you use the sample videos provided, but it works with any.)</para>
<para>
<screenshot>
<screeninfo></screeninfo>
<mediaobject>
<imageobject>
<imagedata fileref="Kdenlive_Quickstart-New-Project.png" format="PNG"/>
</imageobject>
<textobject>
<phrase>New Project dialog</phrase>
</textobject>
<caption>
<para>New Project dialog</para>
</caption>
</mediaobject>
</screenshot></para>
<para>Open <application>Kdenlive</application> and create a new project (<menuchoice><guimenu>File</guimenu><guimenuitem>New</guimenuitem></menuchoice>).</para>
<para>Choose the previously created project folder (<filename>quickstart-tutorial/</filename>) and select an appropriate project profile. The video files provided above are 720p, 23.98 fps.<footnote><para><ulink url="http://en.wikipedia.org/wiki/720p">720</ulink> is the video height, p stands for <ulink url="http://en.wikipedia.org/wiki/Progressive_scan">progressive scan</ulink> in contrast to <ulink url="http://en.wikipedia.org/wiki/Interlaced_video">interlaced video</ulink>, and the fps number denotes the number of full frames per second.</para></footnote> If you are using your own files and dont know which one to use, <application>Kdenlive</application> will suggest an appropriate one when the first clip is added, so you can leave the field on whatever it is.</para>
</chapter>
<chapter id="adding-clips"><title>Adding clips</title>
<para>
<screenshot>
<screeninfo></screeninfo>
<mediaobject>
<imageobject>
<imagedata fileref="Kdenlive_Quickstart-Add-Clips.png" format="PNG"/>
</imageobject>
<textobject>
<phrase>Project Tree: Adding video clips</phrase>
</textobject>
<caption>
<para>Project Tree: Adding video clips</para>
</caption>
</mediaobject>
</screenshot></para>
<para>Now that the project is ready, lets start adding some clips (&ie; the ones you downloaded). This works via the <emphasis>Project Tree widget</emphasis>; a click on the <guilabel>Add Clip</guilabel> icon directly opens the file dialog, a click on the small arrow shows a list of additional clip types that can be added as well. Video clips, audio clips, images, and other <application>Kdenlive</application> projects can be added via the default <guilabel>Add Clip</guilabel> dialog.</para>
<para>
<screenshot>
<screeninfo></screeninfo>
<mediaobject>
<imageobject>
<imagedata fileref="Kdenlive_Quickstart-Mainwindow.png" format="PNG"/>
</imageobject>
<textobject>
<phrase>Kdenlive 0.8 window with the tutorial files</phrase>
</textobject>
<caption>
<para>Kdenlive 0.8 window with the tutorial files</para>
</caption>
</mediaobject>
</screenshot></para>
<para>After loading the clips, <application>Kdenlive</application> will look similar to this. On the top left there is the already known project tree. Right of it are the monitors that show video; The clip monitor displays video from the original clips, the project monitor shows how the output video will look, with all effects, transitions, &etc; applied. The third, also very important, item is the timeline (below the monitors): This is the place where the video clips will be edited. There are two different types of tracks, Video and Audio. Video tracks can contain any kind of clip, audio tracks as well but when dropping a video file to the audio track, only the audio will be used.</para>
<para>
<screenshot>
<screeninfo></screeninfo>
<mediaobject>
<imageobject>
<imagedata fileref="Kdenlive_Quickstart-Save-Project.png" format="PNG"/>
</imageobject>
<textobject>
<phrase>Saving a Kdenlive project</phrase>
</textobject>
<caption>
<para>Saving a Kdenlive project</para>
</caption>
</mediaobject>
</screenshot></para>
<para>Lets save the work via <menuchoice><guimenu>File</guimenu><guimenuitem>Save</guimenuitem></menuchoice>. This saves our project, &ie; where we placed the clips on the timeline, which effects we applied, and so on. It can <emphasis>not</emphasis> be played.<footnote><para>To be correct, it <emphasis>can</emphasis> be played using <varname>melt yourproject.kdenlive</varname>, but this is not the way you would want to present your final video since it is (most likely) too slow. Additionally, it only works if melt is installed.</para></footnote> The process of creating the final video is called <emphasis>Rendering</emphasis>.</para>
</chapter>
<chapter id="timeline"><title>Timeline</title>
<para>Now comes the actual editing. Project clips are combined to the final result on the timeline. They get there by drag and drop: Drag some Napoli (assuming you are using the files provided above, as in the rest of this quick start tutorial; If not, please make sure your screen is waterproof, and perhaps tomatoproof), and drop it onto the first track in the timeline.</para>
<para>
<screenshot>
<screeninfo></screeninfo>
<mediaobject>
<imageobject>
<imagedata fileref="Kdenlive_Quickstart-Timeline-Clips.png" format="PNG"/>
</imageobject>
<textobject>
<phrase>First clips in the timeline</phrase>
</textobject>
<caption>
<para>First clips in the timeline</para>
</caption>
</mediaobject>
</screenshot></para>
<para>Since some cutlery is needed as well, drop the spoon on the first track as well. Then drag the Napoli to the beginning of the timeline (otherwise the rendered video would start with some seconds of plain black), and the Spoon right after the Napoli, such that it looks like in the image on the left. (Where I have zoomed in with <keycombo>&Ctrl;<keycap>Wheel</keycap></keycombo>.)</para>
<para>
<screenshot>
<screeninfo></screeninfo>
<mediaobject>
<imageobject>
<imagedata fileref="Kdenlive_Quickstart-TimelineCursor.png" format="PNG"/>
</imageobject>
<textobject>
<phrase>Timeline cursor</phrase>
</textobject>
<caption>
<para>Timeline cursor</para>
</caption>
</mediaobject>
</screenshot></para>
<para>The result can already be previewed by pressing <keycap>Space</keycap> (or the <guilabel>Play</guilabel> button in the project monitor). You will see the Napoli directly followed by a Spoon. If the timeline cursor is not at the beginning, the project monitor will start playing somewhere in the middle; you can move it by dragging it either on the timeline ruler or in the project monitor. If you prefer keyboard shortcuts, <keycombo>&Ctrl;<keycap>Home</keycap></keycombo> does the same for the monitor that is activated. (Select the <guilabel>Project Monitor</guilabel> if it is not selected yet before using the shortcut.)</para>
<para>
<screenshot>
<screeninfo></screeninfo>
<mediaobject>
<imageobject>
<imagedata fileref="Kdenlive_Quickstart-Resize-Marker.png" format="PNG"/>
</imageobject>
<textobject>
<phrase>Resize marker</phrase>
</textobject>
<caption>
<para>Resize marker</para>
</caption>
</mediaobject>
</screenshot></para>
<para>Since after eating comes playing, there is a Billard clip. Add it to the timeline as well. The first 1.5 seconds nothing happens in the clip, so it should perhaps be <guilabel>cut</guilabel> to avoid the video becoming boring. An easy way<footnote><para>Writing it this way suggests that there are several ways of cutting a clip. This is in fact true.</para></footnote> for this is to move the timeline cursor to the desired position (&ie; the position where you want to cut the video), then drag the left border of the clip when the resize marker appears. It will snap in at the timeline cursor when you move close enough.</para>
<para>
<screenshot>
<screeninfo></screeninfo>
<mediaobject>
<imageobject>
<imagedata fileref="Kdenlive_Quickstart-Overlap-Clips.png" format="PNG"/>
</imageobject>
<textobject>
<phrase>Overlapping clips</phrase>
</textobject>
<caption>
<para>Overlapping clips</para>
</caption>
</mediaobject>
</screenshot></para>
<para>To add a <emphasis>transition</emphasis> between eating (the Spoon) and playing billard, the two clips need to overlap. To be precise: the second clip should be above or below the first one and end some frames after the second one begins. Zooming in until the ticks for simple frames appear helps there; it also makes it easy to always have the same transition duration, like five frames in this case.</para>
<para>You can zoom in by either using the <guilabel>zoom slider</guilabel> at the bottom of the <application>Kdenlive</application> window, or with <keycombo>&Ctrl;<keycap>Mousewheel</keycap></keycombo>. <application>Kdenlive</application> will zoom to the timeline cursor, so first set it to the position which you want to see enlarged, then zoom in.</para>
<para>
<screenshot>
<screeninfo></screeninfo>
<mediaobject>
<imageobject>
<imagedata fileref="Kdenlive-Quickstart-Add-Transition.png" format="PNG"/>
</imageobject>
<textobject>
<phrase>Transition marker</phrase>
</textobject>
<caption>
<para>Transition marker</para>
</caption>
</mediaobject>
</screenshot></para>
<para>Now that the clips overlap, the transition can be added. This is done either by right-clicking on the upper clip and choosing <guilabel>Add Transition</guilabel> or, easier, by clicking the lower right corner of the Spoon clip. The latter by default adds a dissolve transition, which is in this case the best idea anyway since the Spoon is not required for playing anyway.</para>
<para>The dissolve transitions fades the first clip into the second one.</para>
<para>
<screenshot>
<screeninfo></screeninfo>
<mediaobject>
<imageobject>
<imagedata fileref="Kdenlive-Quickstart-Add-Last-Clip.png" format="PNG"/>
</imageobject>
<textobject>
<phrase></phrase>
</textobject>
<caption>
<para></para>
</caption>
</mediaobject>
</screenshot></para>
<para>Lets add the last clip, the Piano, now, and again apply a dissolve transition. When adding it on the first track of the timeline, you need to click on the new clips lower left edge to add the transition to the previous clip.</para>
<sect1 id="effects"><title>Effects</title>
<para>
<screenshot>
<screeninfo></screeninfo>
<mediaobject>
<imageobject>
<imagedata fileref="Kdenlive_Quickstart-Add-Effect.png" format="PNG"/>
</imageobject>
<textobject>
<phrase>Effect List</phrase>
</textobject>
<caption>
<para>Effect List</para>
</caption>
</mediaobject>
</screenshot></para>
<para>The Piano can be colourized by adding an <emphasis>effect</emphasis> to it. Select the piano clip, then double-click the <guilabel>RGB Adjustment</guilabel> effect in the <guilabel>Effect List</guilabel>. If it is not visible, you can get it via <menuchoice><guimenu>View</guimenu><guimenuitem>Effect List</guimenuitem></menuchoice>.</para>
<para>
<screenshot>
<screeninfo></screeninfo>
<mediaobject>
<imageobject>
<imagedata fileref="Kdenlive_Quickstart-Effect-Flag.png" format="PNG"/>
</imageobject>
<textobject>
<phrase></phrase>
</textobject>
<caption>
<para></para>
</caption>
</mediaobject>
</screenshot></para>
<para>Once the effect has been added, its name will be added to the timeline clip. It will also be shown in the <guilabel>Effect Stack</guilabel> widget.</para>
<para>
<screenshot>
<screeninfo></screeninfo>
<mediaobject>
<imageobject>
<imagedata fileref="Kdenlive-Quickstart-EffectStack.png" format="PNG"/>
</imageobject>
<textobject>
<phrase>Effect Stack with RGB adjustment</phrase>
</textobject>
<caption>
<para>Effect Stack with RGB adjustment</para>
</caption>
</mediaobject>
</screenshot></para>
<para>To get a warm yellow-orange tone on the image, fitting the comfortable evening, blue needs to be reduced and red and green improved.</para>
<para>The values in the effect stack widget can be changed by using the slider (middle mouse button resets it to the default value), or by entering a value directly by double-clicking the number right to the slider.</para>
<para>Effects can also be added with the <guilabel>Add new effect</guilabel> icon (framed in the image on the left) in the <guilabel>Effect Stack</guilabel>; It always refers to the timeline clip that is currently selected. By unchecking the checkbox they are temporarily disabled (the settings remain though), this is &eg; useful for effects that require a lot of computing power, so they can be disabled when editing and enabled again for rendering.</para>
<para>For some effects, like the one used there, it is possible to add keyframes. The framed watch icon indicates this. Keyframes are used for changing effect parameters over time. In our clip this allows us to fade the pianos colour from a warm evening colour to a cold night colour.</para>
<para>
<screenshot>
<screeninfo></screeninfo>
<mediaobject>
<imageobject>
<imagedata fileref="Kdenlive_Quickstart-Keyframes.png" format="PNG"/>
</imageobject>
<textobject>
<phrase>Keyframes for effects</phrase>
</textobject>
<caption>
<para>Keyframes for effects</para>
</caption>
</mediaobject>
</screenshot></para>
<para>After clicking the <guilabel>keyframe</guilabel> icon (the clock icon framed in the previous image), the Effect Stack widget will re-arrange. By default there will be two keyframes, one at the beginning of the timeline clip and one at the end. Move the timeline cursor to the end of the timeline clip, such that the project monitor actually shows the new colours when changing the parameters of the keyframe at the end.</para>
<para>Make sure the last keyframe is selected in the Effect Stacks list. Then you are ready to flood the piano with a deep blue.</para>
<para>Moving the timeline cursor to the beginning of the project and playing it (with <keycap>Space</keycap>, or the <guilabel>Play</guilabel> button in the <guilabel>Project Monitor</guilabel>), the piano should now change the colour as desired.</para>
<para>Keyframing was the hardest part of this tutorial. If you managed to do it, you will master <guilabel>Kdenilve</guilabel> easily!</para>
</sect1>
<sect1 id="music"><title>Music</title>
<para>
<screenshot>
<screeninfo></screeninfo>
<mediaobject>
<imageobject>
<imagedata fileref="Kdenlive_Quickstart-Fadeout.png" format="PNG"/>
</imageobject>
<textobject>
<phrase>Audio fadeout</phrase>
</textobject>
<caption>
<para>Audio fadeout</para>
</caption>
</mediaobject>
</screenshot></para>
<para>Since the clips do not provide any audio, lets search for some nice piece of music, on your local collection or on web pages like <ulink url="http://www.jamendo.com">Jamendo</ulink>. The audio clip should, after adding it, go to an audio track on the timeline.</para>
<para>The audio clip can be resized on the timeline the same way as video clips are. The cursor will snap in at the end of the project automatically. To add a fade out effect at the end of the audio clip (except if you found a file with exactly the right length) you can hover the top right (or left) edge of the timeline clip and drag the green disc to the position where fading out should start.<footnote><para>This green disc is a shorthand for adding the effect <menuchoice><guimenu>Fade</guimenu><guimenuitem>Fade out</guimenuitem></menuchoice>. Both ways lead to the same result.</para></footnote></para>
</sect1>
</chapter>
<chapter id="rendering"><title>Rendering</title>
<para>
<screenshot>
<screeninfo></screeninfo>
<mediaobject>
<imageobject>
<imagedata fileref="Kdenlive_Quickstart-Renderer.png" format="PNG"/>
</imageobject>
<textobject>
<phrase>Rendering dialog</phrase>
</textobject>
<caption>
<para>Rendering dialog</para>
</caption>
</mediaobject>
</screenshot></para>
<para>A few minutes left, and the project is finished! Click the Render button (or go to <menuchoice><guimenu>Project</guimenu><guimenuitem>Render</guimenuitem></menuchoice>, or press <keycombo>&Ctrl;&Enter;</keycombo>) to get the dialog shown on the left. Select the desired output file for our new video with all effects and transitions, choose MPEG4 (works nearly everywhere) and a bitrate of 2000k (the higher the bitrate, the larger the output file and the better the quality but since the bitrate for the input clips was 2000k already, using a higher one would not improve quality and is therefore unnecessary), and press the <emphasis>Render to File</emphasis> button.</para>
<para>
<screenshot>
<screeninfo></screeninfo>
<mediaobject>
<imageobject>
<imagedata fileref="Kdenlive_Quickstart-Rendering.png" format="PNG"/>
</imageobject>
<textobject>
<phrase>Rendering progress</phrase>
</textobject>
<caption>
<para>Rendering progress</para>
</caption>
</mediaobject>
</screenshot></para>
<para>After some seconds rendering will be finished, and your first <application>Kdenlive</application> project completed. Congratulations!</para>
</chapter>
<!--userbase-content-->
<chapter id="credits">
<title>Credits and License</title>
<para>
Documentation Copyright see the UserBase
<ulink url="http://userbase.kde.org/index.php?title=Kdenlive/Manual/QuickStart&amp;action=history">Kdenlive/Manual/QuickStart page history</ulink></para>
<!-- TRANS:CREDIT_FOR_TRANSLATORS -->
&underFDL;
</chapter>
&documentation.index;
</book>

View File

@@ -31,7 +31,6 @@
<name>Invert</name>
</parameter>
</effect>
<effect LC_NUMERIC="C" tag="frei0r.alpha0ps" id="frei0r.alpha0ps" version="0.3">
<name>Alpha operations</name>
<description>Display and manipulation of the alpha channel</description>

View File

@@ -25,7 +25,7 @@
<name>Max</name>
</parameter>
<parameter type="list" name="Operation" default="0.0" paramlist="0.0;0.3;0.5;0.7;1.0">
<parameter type="list" name="Operation" default="0.0" paramlist="0.0;0.3;0.5;0.7;1.0" listitemtype="double">
<paramlistdisplay>Write on clear,Max,Min,Add,Subtract</paramlistdisplay>
<name>Operation</name>
</parameter>

View File

@@ -5,7 +5,7 @@
<author>Marko Cebokli</author>
<parameter type="list" name="Shape" default="0.0" paramlist="0.0;0.38;0.62;1.0">
<parameter type="list" name="Shape" default="0.0" paramlist="0.0;0.38;0.62;1.0" listitemtype="double">
<paramlistdisplay>Rectangle,Ellipse,Triangle,Diamond</paramlistdisplay>
<name>Shape</name>
</parameter>
@@ -42,7 +42,7 @@
<name>Max</name>
</parameter>
<parameter type="list" name="Operation" default="0.0" paramlist="0.0;0.3;0.5;0.7;1.0">
<parameter type="list" name="Operation" default="0.0" paramlist="0.0;0.3;0.5;0.7;1.0" listitemtype="double">
<paramlistdisplay>Write on clear,Max,Min,Add,Subtract</paramlistdisplay>
<name>Operation</name>
</parameter>

View File

@@ -4,7 +4,7 @@
<description>Color curves adjustment</description>
<author>Till Theato, Maksim Golovkin</author>
<parameter type="list" name="Channel" default="0.5" paramlist="0.5;0;0.1;0.2;0.3;0.4;0.6;0.71">
<parameter type="list" name="Channel" default="0.5" paramlist="0.5;0;0.1;0.2;0.3;0.4;0.6;0.71" listitemtype="double">
<paramlistdisplay>RGB,Red,Green,Blue,Alpha,Luma,Hue,Saturation</paramlistdisplay>
<name>Channel</name>
</parameter>

View File

@@ -52,7 +52,7 @@
<name>Enable Stretch</name>
</parameter>
<parameter type="list" name="Interpolator" default="0.166" paramlist="0;0.166;0.333;0.5;0.666;0.833;1.0">
<parameter type="list" name="Interpolator" default="0.166" paramlist="0;0.166;0.333;0.5;0.666;0.833;1.0" listitemtype="double">
<paramlistdisplay>Nearest neighbor,Bilinear,Bicubic smooth,Bicubic sharp,Spline 4x4,Spline 6x6,Lanczos</paramlistdisplay>
<name>Interpolator</name>
</parameter>
@@ -61,7 +61,7 @@
<name>Transparent Background</name>
</parameter>
<parameter type="list" name="Alpha operation" default="0.0" paramlist="0.0;0.3;0.5;0.7;1.0">
<parameter type="list" name="Alpha operation" default="0.0" paramlist="0.0;0.3;0.5;0.7;1.0" listitemtype="double">
<paramlistdisplay>Write on clear,Maximum,Minimum,Add,Subtract</paramlistdisplay>
<name>Alpha operation</name>
</parameter>

View File

@@ -16,7 +16,7 @@
<name>B</name>
</parameter>
<parameter type="list" name="Action" default="0.5" paramlist="0.0;0.5;1.0">
<parameter type="list" name="Action" default="0.5" paramlist="0.0;0.5;1.0" listitemtype="double">
<paramlistdisplay>Add constant,Change gamma,Multiply</paramlistdisplay>
<name>Action</name>
</parameter>
@@ -29,7 +29,7 @@
<name>Alpha controlled</name>
</parameter>
<parameter type="list" name="Luma formula" default="1.0" paramlist="0.0;1.0">
<parameter type="list" name="Luma formula" default="1.0" paramlist="0.0;1.0" listitemtype="double">
<paramlistdisplay>Rec. 601,Rec. 709</paramlistdisplay>
<name>Luma formula</name>
</parameter>

View File

@@ -109,7 +109,7 @@
<parameter type="bool" name="Show curves" default="0">
<name>Show graph in picture</name>
</parameter>
<parameter type="list" name="Graph position" default="0.3" paramlist="0;0.1;0.2;0.3">
<parameter type="list" name="Graph position" default="0.3" paramlist="0;0.1;0.2;0.3" listitemtype="double">
<paramlistdisplay>Top Left,Top Right,Bottom Left,Bottom Right</paramlistdisplay>
<name>Graph position</name>
</parameter>

View File

@@ -9,22 +9,22 @@
<parameter type="bool" name="DeFish" default="1">
<name>DeFish</name>
</parameter>
<parameter type="list" name="Type" default="0.666" paramlist="0;0.333;0.666;1.0">
<parameter type="list" name="Type" default="0.666" paramlist="0;0.333;0.666;1.0" listitemtype="double">
<paramlistdisplay>Equidistant,Orthographic,Equiarea,Stereographic</paramlistdisplay>
<name>Type</name>
</parameter>
<parameter type="list" name="Scaling" default="0" paramlist="0;0.333;0.666;1.0">
<parameter type="list" name="Scaling" default="0" paramlist="0;0.333;0.666;1.0" listitemtype="double">
<paramlistdisplay>Fill,Center,Fit,Manual</paramlistdisplay>
<name>Scaling</name>
</parameter>
<parameter type="constant" name="Manual Scale" default="500" min="0" max="1000" factor="1000">
<name>Manual Scale</name>
</parameter>
<parameter type="list" name="Interpolator" default="0.166" paramlist="0;0.166;0.333;0.5;0.666;0.833;1.0">
<parameter type="list" name="Interpolator" default="0.166" paramlist="0;0.166;0.333;0.5;0.666;0.833;1.0" listitemtype="double">
<paramlistdisplay>Nearest neighbor,Bilinear,Bicubic smooth,Bicubic sharp,Spline 4x4,Spline 6x6,Lanczos</paramlistdisplay>
<name>Interpolator</name>
</parameter>
<parameter type="list" name="Aspect type" default="0" paramlist="0;0.25;0.5;0.75;1.0">
<parameter type="list" name="Aspect type" default="0" paramlist="0;0.25;0.5;0.75;1.0" listitemtype="double">
<paramlistdisplay>Square,PAL DV,NTSC DV,HDV,Manual</paramlistdisplay>
<name>Aspect type</name>
</parameter>

View File

@@ -24,7 +24,7 @@
<comment>How often to detect a face. In between checks, it does object motion tracking.</comment>
</parameter>
<parameter type="list" name="Shape" default="0.0" paramlist="0.0;0.1;0.2;1.0">
<parameter type="list" name="Shape" default="0.0" paramlist="0.0;0.1;0.2;1.0" listitemtype="double">
<paramlistdisplay>circle,ellipse,rectangle,random</paramlistdisplay>
<name>Shape</name>
</parameter>

View File

@@ -9,7 +9,7 @@
<comment>Amount of blur</comment>
</parameter>
<parameter type="list" name="Type" default="0.5" paramlist="0.0,0.5,0.999">
<parameter type="list" name="Type" default="0.5" paramlist="0.0;0.5;0.999" listitemtype="double">
<paramlistdisplay>Exponential,Lowpass,Gaussian</paramlistdisplay>
<name>Type</name>
<comment>Select blurring algorithm</comment>

View File

@@ -37,7 +37,7 @@
<description>Adjust levels</description>
<author>Maksim Golovkin</author>
<parameter type="list" name="Channel" default="0.3" paramlist="0;0.1;0.2;0.3">
<parameter type="list" name="Channel" default="0.3" paramlist="0;0.1;0.2;0.3" listitemtype="double">
<paramlistdisplay>Red,Green,Blue,Luma</paramlistdisplay>
<name>Channel</name>
</parameter>
@@ -59,7 +59,7 @@
<parameter type="bool" name="Show histogram" default="0">
<name>Show histogram</name>
</parameter>
<parameter type="list" name="Histogram position" default="0.3" paramlist="0;0.1;0.2;0.3">
<parameter type="list" name="Histogram position" default="0.3" paramlist="0;0.1;0.2;0.3" listitemtype="double">
<paramlistdisplay>Top Left,Top Right,Bottom Left,Bottom Right</paramlistdisplay>
<name>Histogram position</name>
</parameter>

View File

@@ -4,7 +4,7 @@
<description>Measure video values</description>
<author>Marko Cebokli</author>
<parameter type="list" name="Measurement" default="0.0" paramlist="0.0;0.3;0.5;0.7;1.0">
<parameter type="list" name="Measurement" default="0.0" paramlist="0.0;0.3;0.5;0.7;1.0" listitemtype="double">
<paramlistdisplay>RGB,Y'PbPr - rec. 601,Y'PbPr - rec. 709,HSV,HSL</paramlistdisplay>
<name>Measurement</name>
</parameter>

View File

@@ -20,7 +20,7 @@
<name>Length</name>
</parameter>
<parameter type="list" name="Channel" default="0.5" paramlist="0.0;0.2;0.4;0.5;0.6;0.8;1.0">
<parameter type="list" name="Channel" default="0.5" paramlist="0.0;0.2;0.4;0.5;0.6;0.8;1.0" listitemtype="double">
<paramlistdisplay>R,G,B,Y',Pr,Pb,Alpha</paramlistdisplay>
<name>Channel</name>
</parameter>
@@ -81,7 +81,7 @@
<name>256 scale</name>
</parameter>
<parameter type="list" name="Color" default="0.0" paramlist="0.0;1.0">
<parameter type="list" name="Color" default="0.0" paramlist="0.0;1.0" listitemtype="double">
<paramlistdisplay>CCIR rec. 601,CCIR rec. 709</paramlistdisplay>
<name>Color</name>
</parameter>

View File

@@ -25,22 +25,22 @@
<name>Delta B / I / I</name>
</parameter>
<parameter type="list" name="Selection subspace" default="0.0" paramlist="0.0;0.5;1.0">
<parameter type="list" name="Selection subspace" default="0.0" paramlist="0.0;0.5;1.0" listitemtype="double">
<paramlistdisplay>RGB,ABI,HCI</paramlistdisplay>
<name>Selection subspace</name>
</parameter>
<parameter type="list" name="Subspace shape" default="0.5" paramlist="0.0;0.5;1.0">
<parameter type="list" name="Subspace shape" default="0.5" paramlist="0.0;0.5;1.0" listitemtype="double">
<paramlistdisplay>Box,Ellipsoid,Diamond</paramlistdisplay>
<name>Subspace shape</name>
</parameter>
<parameter type="list" name="Edge mode" default="0.0" paramlist="0.0;0.35;0.60;1.0">
<parameter type="list" name="Edge mode" default="0.0" paramlist="0.0;0.35;0.60;1.0" listitemtype="double">
<paramlistdisplay>Hard,Fat,Normal,Skinny</paramlistdisplay>
<name>Edge mode</name>
</parameter>
<parameter type="list" name="Operation" default="0.0" paramlist="0.0;0.3;0.5;0.7;1.0">
<parameter type="list" name="Operation" default="0.0" paramlist="0.0;0.3;0.5;0.7;1.0" listitemtype="double">
<paramlistdisplay>Write on clear,Max,Min,Add,Subtract</paramlistdisplay>
<name>Operation</name>
</parameter>
@@ -60,17 +60,17 @@
<name>Invert selection</name>
</parameter>
<parameter type="list" name="Selection subspace" default="0.0" paramlist="0.0;0.5;1.0">
<parameter type="list" name="Selection subspace" default="0.0" paramlist="0.0;0.5;1.0" listitemtype="double">
<paramlistdisplay>RGB,ABI,HCI</paramlistdisplay>
<name>Selection subspace</name>
</parameter>
<parameter type="list" name="Subspace shape" default="0.5" paramlist="0.0;0.5;1.0">
<parameter type="list" name="Subspace shape" default="0.5" paramlist="0.0;0.5;1.0" listitemtype="double">
<paramlistdisplay>Box,Ellipsoid,Diamond</paramlistdisplay>
<name>Subspace shape</name>
</parameter>
<parameter type="list" name="Edge mode" default="0.9" paramlist="0.0;0.35;0.60;0.7;0.9">
<parameter type="list" name="Edge mode" default="0.9" paramlist="0.0;0.35;0.60;0.7;0.9" listitemtype="double">
<paramlistdisplay>Hard,Fat,Normal,Skinny,Slope</paramlistdisplay>
<name>Edge mode</name>
</parameter>
@@ -91,7 +91,7 @@
<name>Slope</name>
</parameter>
<parameter type="list" name="Operation" default="0.0" paramlist="0.0;0.3;0.5;0.7;1.0">
<parameter type="list" name="Operation" default="0.0" paramlist="0.0;0.3;0.5;0.7;1.0" listitemtype="double">
<paramlistdisplay>Write on clear,Max,Min,Add,Subtract</paramlistdisplay>
<name>Operation</name>
</parameter>

View File

@@ -3,7 +3,7 @@
<name>Mute</name>
<description>Mute clip</description>
<author>Dan Dennedy</author>
<parameter type="fixed" name="gain" max="0" min="0" default="0">
<parameter type="fixed" name="gain" value="0">
<name>Gain</name>
</parameter>
</effect>

View File

@@ -9,5 +9,5 @@
<parameter type="geometry" name="composite.geometry" default="0%,0%:100%x100%" fixed="1" opacity="false">
<name>Pan and Zoom</name>
</parameter>
<parameter type="fixed" name="filter_only" min="1" max="1" default="1" />
<parameter type="fixed" name="filter_only" value="1" />
</effect>

View File

@@ -21,6 +21,6 @@
<parameter type="color" name="background" default="colour:0x00000000" alpha="1" paramprefix="colour:">
<name>Background Color</name>
</parameter>
<parameter type="fixed" name="transition.keyed" max="1" min="1" default="1" />
<parameter type="fixed" name="transition.always_active" max="1" min="1" default="1" />
<parameter type="fixed" name="transition.keyed" value="1" />
<parameter type="fixed" name="transition.always_active" value="1" />
</effect>

View File

@@ -1,5 +0,0 @@
INSTALL (FILES
profiles.xml
DESTINATION ${DATA_INSTALL_DIR}/kdenlive/export)

View File

@@ -1,150 +0,0 @@
<profiles version="0.1">
<group name="HDV" renderer="avformat" extension="m2t" type="av">
<profile name="PAL 1080 50i" standard="PAL" args="f=mpegts acodec=mp2 ab=384k ar=48000 ac=2 vcodec=mpeg2video s=1440x1080 vb=25000k g=12 trellis=1 mlt_profile=hdv_1080_50i pass=%passes" />
<profile name="PAL 1080 25p" standard="PAL" args="f=mpegts acodec=mp2 ab=384k ar=48000 ac=2 vcodec=mpeg2video s=1440x1080 vb=25000k g=12 trellis=1 mlt_profile=hdv_1080_25p pass=%passes" />
<profile name="PAL 720 25p" standard="PAL" args="f=mpegts acodec=mp2 ab=384k ar=48000 ac=2 vcodec=mpeg2video s=1280x720 vb=19700k g=12 trellis=1 mlt_profile=hdv_720_25p pass=%passes" />
<profile name="NTSC 1080 60i" standard="NTSC" args="f=mpegts acodec=mp2 ab=384k ar=48000 ac=2 vcodec=mpeg2video s=1440x1080 vb=25000k g=15 trellis=1 mlt_profile=hdv_1080_60i pass=%passes" />
<profile name="NTSC 1080 30p" standard="NTSC" args="f=mpegts acodec=mp2 ab=384k ar=48000 ac=2 vcodec=mpeg2video s=1440x1080 vb=25000k g=15 trellis=1 mlt_profile=hdv_1080_30p pass=%passes" />
<profile name="NTSC 720 30p" standard="NTSC" args="f=mpegts acodec=mp2 ab=384k ar=48000 ac=2 vcodec=mpeg2video s=1280x720 vb=19700k g=15 trellis=1 mlt_profile=hdv_720_30p pass=%passes" />
</group>
<group name="Raw DV" renderer="avformat" type="av" extension="dv">
<profile name="DV PAL 4:3" standard="PAL" args="f=dv pix_fmt=yuv420p s=720x576 mlt_profile=dv_pal" />
<profile name="DV PAL 16:9" standard="PAL" args="f=dv pix_fmt=yuv420p s=720x576 mlt_profile=dv_pal_wide" />
<profile name="DVCPRO25 PAL 4:3" standard="PAL" args="f=dv pix_fmt=yuv411p s=720x576 mlt_profile=dv_pal" />
<profile name="DVCPRO25 PAL 16:9" standard="PAL" args="f=dv pix_fmt=yuv411p s=720x576 mlt_profile=dv_pal_wide" />
<profile name="DVCPRO50 PAL 4:3" standard="PAL" args="f=dv pix_fmt=yuv422p s=720x576 mlt_profile=dv_pal" />
<profile name="DVCPRO50 PAL 16:9" standard="PAL" args="f=dv pix_fmt=yuv422p s=720x576 mlt_profile=dv_pal_wide" />
<profile name="DV NTSC 4:3" standard="NTSC" args="f=dv pix_fmt=yuv411p s=720x480 mlt_profile=dv_ntsc" />
<profile name="DV NTSC 16:9" standard="NTSC" args="f=dv pix_fmt=yuv411p s=720x480 mlt_profile=dv_ntsc_wide" />
<profile name="DVCPRO25 NTSC 4:3" standard="NTSC" args="f=dv pix_fmt=yuv411p s=720x480 mlt_profile=dv_ntsc" />
<profile name="DVCPRO25 NTSC 16:9" standard="NTSC" args="f=dv pix_fmt=yuv411p s=720x480 mlt_profile=dv_ntsc_wide" />
<profile name="DVCPRO50 NTSC 4:3" standard="NTSC" args="f=dv pix_fmt=yuv422p s=720x480 mlt_profile=dv_ntsc" />
<profile name="DVCPRO50 NTSC 16:9" standard="NTSC" args="f=dv pix_fmt=yuv422p s=720x480 mlt_profile=dv_ntsc_wide" />
</group>
<group name="AVI DV" renderer="avformat" type="av" extension="avi">
<profile name="DV PAL 4:3" standard="PAL" args="f=avi vcodec=dvvideo pix_fmt=yuv420p acodec=pcm_s16le s=720x576 mlt_profile=dv_pal" />
<profile name="DV PAL 16:9" standard="PAL" args="f=avi vcodec=dvvideo pix_fmt=yuv420p acodec=pcm_s16le s=720x576 mlt_profile=dv_pal_wide" />
<profile name="DVCPRO25 PAL 4:3" standard="PAL" args="f=avi vcodec=dvvideo pix_fmt=yuv411p acodec=pcm_s16le s=720x576 mlt_profile=dv_pal" />
<profile name="DVCPRO25 PAL 16:9" standard="PAL" args="f=avi vcodec=dvvideo pix_fmt=yuv411p acodec=pcm_s16le s=720x576 mlt_profile=dv_pal_wide" />
<profile name="DVCPRO50 PAL 4:3" standard="PAL" args="f=avi vcodec=dvvideo pix_fmt=yuv422p acodec=pcm_s16le s=720x576 mlt_profile=dv_pal" />
<profile name="DVCPRO50 PAL 16:9" standard="PAL" args="f=avi vcodec=dvvideo pix_fmt=yuv422p acodec=pcm_s16le s=720x576 mlt_profile=dv_pal_wide" />
<profile name="DV NTSC 4:3" standard="NTSC" args="f=avi vcodec=dvvideo pix_fmt=yuv411p acodec=pcm_s16le s=720x480 mlt_profile=dv_ntsc" />
<profile name="DV NTSC 16:9" standard="NTSC" args="f=avi vcodec=dvvideo pix_fmt=yuv411p acodec=pcm_s16le s=720x480 mlt_profile=dv_ntsc_wide" />
<profile name="DVCPRO25 NTSC 4:3" standard="NTSC" args="f=avi vcodec=dvvideo pix_fmt=yuv411p acodec=pcm_s16le s=720x480 mlt_profile=dv_ntsc" />
<profile name="DVCPRO25 NTSC 16:9" standard="NTSC" args="f=avi vcodec=dvvideo pix_fmt=yuv411p acodec=pcm_s16le s=720x480 mlt_profile=dv_ntsc_wide" />
<profile name="DVCPRO50 NTSC 4:3" standard="NTSC" args="f=avi vcodec=dvvideo pix_fmt=yuv422p acodec=pcm_s16le s=720x480 mlt_profile=dv_ntsc" />
<profile name="DVCPRO50 NTSC 16:9" standard="NTSC" args="f=avi vcodec=dvvideo pix_fmt=yuv422p acodec=pcm_s16le s=720x480 mlt_profile=dv_ntsc_wide" />
</group>
<group name="DVD" renderer="avformat" type="av">
<groupname id="dvd">DVD</groupname>
<profile name="PAL 4:3 VOB" standard="PAL" extension="vob" args="f=dvd vcodec=mpeg2video acodec=ac3 vb=5000k maxrate=8000k minrate=0 bufsize=1835008 packetsize=2048 muxrate=10080000 ab=192k ar=48000 s=720x576 g=15 me_range=63 trellis=1 mlt_profile=dv_pal pass=%passes" />
<profile name="PAL 16:9 VOB" standard="PAL" extension="vob" args="f=dvd vcodec=mpeg2video acodec=ac3 vb=5000k maxrate=8000k minrate=0 bufsize=1835008 packetsize=2048 muxrate=10080000 ab=192k ar=48000 s=720x576 g=15 me_range=63 trellis=1 mlt_profile=dv_pal_wide pass=%passes" />
<profile name="NTSC 4:3 VOB" standard="NTSC" extension="vob" args="f=dvd vcodec=mpeg2video acodec=ac3 s=720x480 vb=6000k maxrate=9000k minrate=0 bufsize=1835008 packetsize=2048 muxrate=10080000 ab=192k ar=48000 g=18 me_range=63 trellis=1 mlt_profile=dv_ntsc pass=%passes" />
<profile name="NTSC 16:9 VOB" standard="NTSC" extension="vob" args="f=dvd vcodec=mpeg2video acodec=ac3 s=720x480 vb=6000k maxrate=9000k minrate=0 bufsize=1835008 packetsize=2048 muxrate=10080000 ab=192k ar=48000 g=18 me_range=63 trellis=1 mlt_profile=dv_ntsc_wide pass=%passes" />
</group>
<group name="MPEG-2" renderer="avformat" extension="mpg" type="av">
<profile name="MPEG-2" bitrates="200,400,600,800,1000,2000,4000,6000,8000,10000,12000,18000,25000" defaultbitrate="12000" audiobitrates="64,128,192,256,384" defaultaudiobitrate="384"
args="f=mpeg acodec=mp2 ab=%audiobitrate+'k' ar=48000 vcodec=mpeg2video minrate=0 vb=%bitrate+'k' bf=2 b_strategy=1 trellis=1 aspect=%dar pass=%passes" />
</group>
<group name="MPEG-4" renderer="avformat" extension="mp4" type="av">
<profile name="MPEG-4/AAC" bitrates="200,400,600,800,1000,2000,4000,6000,8000,10000,12000,18000,25000" defaultbitrate="12000" audiobitrates="64,128,192,256,384" defaultaudiobitrate="128"
args="f=mp4 acodec=aac ab=%audiobitrate+'k' ar=44100 vcodec=mpeg4 minrate=0 vb=%bitrate+'k' aspect=%dar mbd=2 trellis=1 mv4=1 pass=%passes" />
<profile name="MPEG-4/MP3" bitrates="200,400,600,800,1000,2000,4000,6000,8000,10000,12000,18000,25000" defaultbitrate="12000" audiobitrates="64,128,192,256,384" defaultaudiobitrate="128"
args="f=mp4 acodec=libmp3lame ab=%audiobitrate+'k' ar=44100 vcodec=mpeg4 minrate=0 vb=%bitrate+'k' aspect=%dar mbd=2 trellis=1 mv4=1 pass=%passes" />
</group>
<group name="XVid4" renderer="avformat" extension="avi" type="av">
<profile name="XVid4" bitrates="400,600,800,1000,2000,4000,8000,10000,12000" defaultbitrate="8000"
audiobitrates="64,128,192,256,384" defaultaudiobitrate="128" args="acodec=libmp3lame ab=%audiobitrate+'k' ar=44100 vcodec=libxvid minrate=0 vb=%bitrate+'k' aspect=%dar mbd=2 trellis=1 mv4=1 pass=%passes" />
</group>
<group name="H.264" renderer="avformat" extension="mp4" type="av">
<profile name="H.264" bitrates="200,400,600,800,1000,2000,4000,6000,8000,10000,12000,18000,25000" defaultbitrate="12000" audiobitrates="64,128,192,256,384" defaultaudiobitrate="384"
args="f=mp4 hq=1 acodec=aac ab=%audiobitrate+'k' ar=48000 pix_fmt=yuv420p vcodec=libx264 minrate=0 vb=%bitrate+'k' g=250 bf=3 b_strategy=1 subcmp=2 cmp=2 coder=1 flags=+loop flags2=dct8x8 qmax=51 subq=7 qmin=10 qcomp=0.6 qdiff=4 trellis=1 aspect=%dar pass=%passes" />
</group>
<group name="Flash" renderer="avformat" extension="flv" type="av">
<profile name="Flash" bitrates="200,400,600,800,1000,2000,4000,6000,8000,10000,12000" defaultbitrate="8000"
args="f=flv acodec=libmp3lame ab=128k ar=44100 vcodec=flv minrate=0 vb=%bitrate+'k' progressive=1 pass=%passes threads=1" />
<profile name="Flash 720x576" standard="PAL" args="f=flv acodec=libmp3lame ab=128k ar=44100 vcodec=flv minrate=0 vb=12000k s=720x576 progressive=1 pass=%passes threads=1" />
<profile name="Flash 720x480" standard="NTSC" args="f=flv acodec=libmp3lame ab=128k ar=44100 vcodec=flv minrate=0 vb=12000k s=720x480 progressive=1 pass=%passes threads=1" />
</group>
<group name="RealVideo" renderer="avformat" extension="rm" type="av">
<profile name="RealVideo" bitrates="200,400,600,800,1000,2000,4000,6000,8000,10000,12000" defaultbitrate="8000"
args="vcodec=rv20 acodec=ac3 minrate=0 vb=%bitrate+'k' ab=128k ar=44100 g=8 pass=%passes" />
<profile name="RealVideo 720x576" standard="PAL" args="vcodec=rv20 acodec=ac3 minrate=0 vb=12000k ab=384k ar=48000 s=720x576 g=8 pass=%passes" />
<profile name="RealVideo 720x480" standard="NTSC" args="vcodec=rv20 acodec=ac3 minrate=0 vb=12000k ab=384k ar=48000 s=720x480 g=8 pass=%passes" />
</group>
<group name="Theora" renderer="avformat" extension="ogv" type="av">
<profile name="Theora" bitrates="200,400,600,800,1000,2000,4000,6000,8000,10000,12000" defaultbitrate="8000"
audiobitrates="64,128,192,256,384" defaultaudiobitrate="128" args="acodec=vorbis ab=%audiobitrate+'k' ar=44100 aq=50 vcodec=libtheora minrate=0 vb=%bitrate+'k' aspect=%dar pass=%passes" />
<profile name="Theora 720x576" standard="PAL" args="acodec=vorbis ab=384k aq=30 ar=44100 vcodec=libtheora minrate=0 vb=12000k s=720x576 aspect=%dar pass=%passes" />
<profile name="Theora 720x480" standard="NTSC" args="acodec=vorbis ab=384k aq=30 ar=44100 vcodec=libtheora minrate=0 vb=12000k s=720x480 aspect=%dar pass=%passes" />
</group>
<group name="WebM" renderer="avformat" extension="webm" type="av">
<profile name="WebM" bitrates="200,400,600,800,1000,2000,4000,6000,8000,10000,12000,18000,25000" defaultbitrate="8000"
audiobitrates="64,128,192,256,384" defaultaudiobitrate="128" args="acodec=vorbis ab=%audiobitrate+'k' ar=44100 aq=50 vcodec=libvpx minrate=0 vb=%bitrate+'k' aspect=%dar maxrate=%bitrate*2+'k' g=120 qmax=42 qmin=10" />
</group>
<group name="Media players" renderer="avformat" type="av">
<groupname id="mediaplayers">Media players</groupname>
<profile name="Windows Media Player WMV V7" bitrates="400,1000,2000" defaultbitrate="2000"
extension="avi" args="acodec=libmp3lame ab=128k ar=48000 ac=2 vcodec=wmv1 minrate=0 vb=%bitrate+'k' aspect=%dar pass=%passes" />
<profile name="Apple Quicktime Player MPEG-4" bitrates="400,1000,2000" defaultbitrate="2000"
extension="mov" args="acodec=aac ab=128k ac=2 ar=48000 vcodec=mpeg4 minrate=0 vb=%bitrate+'k' aspect=%dar pass=%passes" />
</group>
<group name="Web sites" renderer="avformat" type="av">
<groupname id="websites">Web sites</groupname>
<profile name="Dailymotion 320x240" extension="flv" args="f=flv acodec=libmp3lame ab=128k ar=44100 vcodec=flv minrate=0 vb=800k s=320x240 aspect=%dar trellis=1 pass=%passes" url="http://www.dailymotion.com/upload" />
<profile name="Dailymotion 512x384" extension="mp4" args="f=mp4 acodec=aac ab=96k ar=44100 vcodec=libx264 minrate=0 vb=600k g=250 bf=3 s=512x384 aspect=%dar mbd=2 trellis=1 mv4=1 subq=7 qmin=10 qcomp=0.6 qdiff=4 qmax=51 pass=%passes" url="http://www.dailymotion.com/upload" />
<profile name="Dailymotion 1280x720" extension="mp4" args="f=mp4 acodec=aac ab=96k ar=44100 vcodec=libx264 minrate=0 vb=1500k g=250 bf=3 s=1280x720 aspect=%dar mbd=2 trellis=1 mv4=1 subq=7 qmin=10 qcomp=0.6 qdiff=4 qmax=51 pass=%passes" url="http://www.dailymotion.com/upload" />
<profile name="Vimeo 640x480" extension="mp4" args="f=mp4 acodec=aac ab=128k ar=44100 vcodec=libx264 minrate=0 vb=3000k g=250 bf=3 s=640x480 aspect=%dar mbd=2 trellis=1 mv4=1 subq=7 qmin=10 qcomp=0.6 qdiff=4 qmax=51 pass=%passes" url="http://www.vimeo.com/upload" />
<profile name="Vimeo 1280x720" extension="mp4" args="f=mp4 acodec=aac ab=128k ar=44100 vcodec=libx264 minrate=0 vb=5000k g=250 bf=3 s=1280x720 aspect=%dar mbd=2 trellis=1 mv4=1 subq=7 qmin=10 qcomp=0.6 qdiff=4 qmax=51 pass=%passes" url="http://www.vimeo.com/upload" />
<profile name="YouTube 640x480" extension="mp4" args="f=mp4 acodec=libmp3lame ab=128k ar=44100 vcodec=mpeg4 minrate=0 vb=800k s=640x480 aspect=%dar mbd=2 trellis=1 mv4=1 subq=7 qmin=10 qcomp=0.6 qdiff=4 qmax=51 pass=%passes" url="http://www.youtube.com/upload" />
<profile name="YouTube 1280x720" extension="mp4" args="f=mp4 hq=1 acodec=aac ab=128k ar=44100 vcodec=mpeg4 minrate=0 vb=2000k s=1280x720 aspect=%dar mbd=2 trellis=1 mv4=1 subq=7 qmin=10 qcomp=0.6 qdiff=4 qmax=51 pass=%passes" url="http://www.youtube.com/upload" />
</group>
<group name="Wav" renderer="avformat" type="audio">
<groupname id="audioonly">Audio only</groupname>
<profile name="WAV 22050 KHz" extension="wav" args="f=wav ar=22050 video_off=1" />
<profile name="WAV 32000 KHz" extension="wav" args="f=wav ar=32000 video_off=1" />
<profile name="WAV 44100 KHz" extension="wav" args="f=wav ar=44100 video_off=1" />
<profile name="WAV 48000 KHz" extension="wav" args="f=wav ar=48000 video_off=1" />
</group>
<group name="Lossless/HQ" renderer="avformat" type="av">
<groupname id="lossless">Lossless / HQ</groupname>
<profile name="FFV1 lossless (video) + FLAC (sound)" extension="mkv" args="f=matroska acodec=flac ar=48000 ac=2 vcodec=ffv1 aspect=%dar" />
<profile name="FFV1 lossless (video) + PCM (sound)" extension="mkv" args="f=matroska acodec=pcm_s16le ac=2 vcodec=ffv1 aspect=%dar" />
<profile name="HuffYUV lossless (video) + PCM (sound)" extension="avi" args="f=avi acodec=pcm_s16le ac=2 vcodec=huffyuv aspect=%dar" />
<profile name="MPEG-2 I-frame only (video) + MP2 (sound)" extension="mpg" args="f=mpeg acodec=mp2 ab=384k ar=48000 ac=2 vcodec=mpeg2video qscale=1 qmin=1 aspect=%dar intra=1" />
<profile name="MPEG-4 I-frame only (video) + MP3 (sound)" extension="mp4" args="f=mp4 acodec=libmp3lame ab=384k ar=48000 ac=2 vcodec=mpeg4 qscale=1 qmin=1 aspect=%dar intra=1" />
<profile name="H.264 I-frame only (video) + AAC (sound)" extension="mp4" args="f=mp4 acodec=aac ab=384k ar=48000 ac=2 pix_fmt=yuv420p vcodec=libx264 cqp=1 subq=1 qmax=1 qmin=1 qcomp=0.6 qdiff=0 coder=ac trellis=1 aspect=%dar intra=1" />
<profile name="H.264 lossless slow (video) + PCM (sound)" extension="mkv" args="f=matroska acodec=pcm_s16le ac=2 pix_fmt=yuv420p vcodec=libx264 qp=0 preset=veryslow aspect=%dar" />
<profile name="H.264 lossless fast (video) + PCM (sound)" extension="mkv" args="f=matroska acodec=pcm_s16le ac=2 pix_fmt=yuv420p vcodec=libx264 qp=0 preset=ultrafast aspect=%dar" />
</group>
<group name="Apple" renderer="avformat" type="av">
<groupname id="mobile">Mobile devices</groupname>
<profile name="iPod Classic 500k" extension="m4v" args="s=320x240 aspect=%dar progressive=1 acodec=aac ab=128k vcodec=libx264 vb=500k flags=+loop cmp=+chroma partitions=+parti8x8+parti4x4+partp8x8+partb8x8 me_method=umh subq=5 me_range=16 g=250 keyint_min=25 sc_threshold=40 i_qfactor=0.71 qcomp=0.6 qmin=10 qmax=51 qdiff=4 directpred=1 trellis=1 coder=0 bf=0 refs=1 flags2=-wpred-dct8x8 level=13 maxrate=3000k bufsize=768k wpredp=0 bt=256k pass=%passes" />
<profile name="iPhone/iPod Touch 700k" extension="m4v" args="s=480x320 aspect=%dar progressive=1 acodec=aac ab=128k vcodec=libx264 vb=700k flags=+loop cmp=+chroma partitions=+parti8x8+parti4x4+partp8x8+partb8x8 me_method=umh subq=7 me_range=16 g=250 keyint_min=25 sc_threshold=40 i_qfactor=0.71 qcomp=0.6 qmin=10 qmax=51 qdiff=4 directpred=1 trellis=1 coder=0 bf=0 refs=3 flags2=-wpred-dct8x8 level=30 maxrate=10000k bufsize=10000k wpredp=0 pass=%passes" />
</group>
<group name="Android" renderer="avformat" type="av">
<groupname id="mobile">Mobile devices</groupname>
<profile name="480x320 700k" extension="mp4" args="s=480x320 aspect=%dar progressive=1 acodec=aac ab=128k vcodec=libx264 vb=700k flags=+loop cmp=+chroma partitions=+parti8x8+parti4x4+partp8x8+partb8x8 me_method=umh subq=7 me_range=16 g=250 keyint_min=25 sc_threshold=40 i_qfactor=0.71 qcomp=0.6 qmin=10 qmax=51 qdiff=4 directpred=1 trellis=1 coder=0 bf=0 refs=1 flags2=-wpred-dct8x8 level=30 maxrate=10000k bufsize=10000k wpredp=0 pass=%passes" />
</group>
</profiles>

View File

@@ -14,7 +14,7 @@
height="800"
id="svg2"
version="1.1"
inkscape:version="0.48.1 r9760"
inkscape:version="0.48.4 r9939"
sodipodi:docname="git-workflow.svg"
inkscape:export-filename="/tmp/kdenlive-git-workflow.png"
inkscape:export-xdpi="90"
@@ -72,15 +72,15 @@
inkscape:pageopacity="1"
inkscape:pageshadow="2"
inkscape:zoom="0.70710678"
inkscape:cx="774.51484"
inkscape:cx="831.08338"
inkscape:cy="378.04332"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1366"
inkscape:window-height="709"
inkscape:window-x="-3"
inkscape:window-y="-3"
inkscape:window-width="1364"
inkscape:window-height="713"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:snap-bbox="true"
inkscape:bbox-nodes="false"
@@ -137,29 +137,6 @@
height="72"
x="-789.76361"
y="-244.63782" />
<g
id="g3850"
transform="translate(20.681252,9.4129353)">
<use
height="1052.3622"
width="744.09448"
transform="translate(646.46509,470.75735)"
id="use3816"
xlink:href="#g3811"
y="0"
x="0" />
<text
sodipodi:linespacing="125%"
id="text2991"
y="278.65509"
x="94"
style="font-size:30px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
xml:space="preserve"><tspan
y="278.65509"
x="94"
id="tspan2993"
sodipodi:role="line">Release</tspan></text>
</g>
<g
id="g3791"
transform="translate(-181.31874,-86.712769)">
@@ -199,7 +176,7 @@
id="text3005"
y="289.24088"
x="461"
style="font-size:30px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
style="font-size:30px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic"
xml:space="preserve"><tspan
y="289.24088"
x="461"
@@ -287,37 +264,6 @@
id="tspan3884"
x="678.7309"
y="237.77515">Experimental features</tspan></text>
<text
xml:space="preserve"
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
x="25.45586"
y="237.77515"
id="text3886"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3888"
x="25.45586"
y="237.77515">Bugfix branches</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)"
d="m 160.13708,65.079645 0,141.421365"
id="path3909"
inkscape:connector-curvature="0" />
<text
xml:space="preserve"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
x="87.681259"
y="118.6328"
id="text4541"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4543"
x="92.775009"
y="118.6328">Branch a tagged release </tspan><tspan
sodipodi:role="line"
x="87.681259"
y="138.6328"
id="tspan5179">for working on urgent fixes</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)"
d="m 539.28845,217.81471 0,-154.149285"
@@ -410,7 +356,11 @@
sodipodi:role="line"
x="678.7309"
y="10.682662"
id="tspan5259">with the newest features</tspan></text>
id="tspan5259">with the newest features.</tspan><tspan
sodipodi:role="line"
x="678.7309"
y="30.682663"
id="tspan4410">Refactoring work is done here.</tspan></text>
<text
xml:space="preserve"
style="font-size:36px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#484848;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
@@ -433,17 +383,6 @@
id="tspan5177"
x="-750.03271"
y="-269.9263">Originals of the clones in the drawing</tspan></text>
<text
xml:space="preserve"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
x="25.45586"
y="270.67548"
id="text5181"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan5183"
x="25.45586"
y="270.67548">Urgent bugfixes are done here</tspan></text>
<text
xml:space="preserve"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
@@ -460,59 +399,21 @@
id="path5247"
d="m 271.73042,5.8836853 154.14928,0"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)" />
<text
sodipodi:linespacing="125%"
id="text5249"
y="294.68268"
x="678.7309"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
xml:space="preserve"><tspan
id="tspan5253"
y="294.68268"
x="678.7309"
sodipodi:role="line">Normal development goes on here only</tspan></text>
<text
xml:space="preserve"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
x="678.7309"
y="324.26544"
y="294.56696"
id="text3179"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3181"
x="678.7309"
y="324.26544">For new features and non-trivial bugfixes</tspan></text>
<text
sodipodi:linespacing="125%"
id="text3183"
y="298.95975"
x="25.45586"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
xml:space="preserve"><tspan
y="298.95975"
x="25.45586"
id="tspan3185"
sodipodi:role="line">(No need to create a new branch</tspan><tspan
y="318.95975"
x="25.45586"
y="294.56696">For new features and non-trivial bugfixes;</tspan><tspan
sodipodi:role="line"
id="tspan3187">if no urgent bugfixes)</tspan></text>
<path
inkscape:connector-curvature="0"
id="path3189"
d="m 189.83556,207.32903 0,-141.421365"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)" />
<text
sodipodi:linespacing="125%"
id="text3191"
y="118.6328"
x="207.04877"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
xml:space="preserve"><tspan
id="tspan3195"
y="118.6328"
x="207.04877"
sodipodi:role="line">Bugfixes</tspan></text>
x="678.7309"
y="314.56696"
id="tspan4408">each feature gets its branch</tspan></text>
<path
style="color:#000000;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#Arrow2Lend);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="M 274.35745,59.807513 425.6783,211.12836"
@@ -556,5 +457,17 @@
x="87.681259"
y="425.27512"
id="tspan3238">the feature branch is merged directly into Master.</tspan></text>
<text
xml:space="preserve"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"
x="784.88855"
y="609.08118"
id="text4412"
sodipodi:linespacing="125%"
transform="translate(-325.2691,-253.92633)"><tspan
sodipodi:role="line"
id="tspan4414"
x="784.88855"
y="609.08118">E.g. movit, newTimeline, …</tspan></text>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -1,22 +0,0 @@
INSTALL(FILES
bi-linear_x.pgm
bi-linear_y.pgm
burst.pgm
checkerboard_small.pgm
clock.pgm
cloud.pgm
curtain.pgm
horizontal_blinds.pgm
linear_x.pgm
linear_y.pgm
radial-bars.pgm
radial.pgm
spiral.pgm
spiral2.pgm
square.pgm
square2-bars.pgm
square2.pgm
symmetric_clock.pgm
DESTINATION ${DATA_INSTALL_DIR}/kdenlive/lumas)

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@@ -91,7 +91,7 @@ KUrl SamplePlugin::generatedClip(const QString &renderer, const QString &generat
}
else {
// Countdown producer
for (int i = 0; i < view.duration->value(); i++) {
for (int i = 0; i < view.duration->value(); ++i) {
// Create the producers
args << "pango:" << "in=0" << QString("out=" + QString::number((int) fps * view.duration->value()));
args << QString("text=" + QString::number(view.duration->value() - i));
@@ -99,7 +99,7 @@ KUrl SamplePlugin::generatedClip(const QString &renderer, const QString &generat
}
}
args << "-consumer"<<QString("xml:%1").arg(view.path->url().path());
args << "-consumer"<<QString::fromLatin1("xml:%1").arg(view.path->url().path());
generatorProcess.start(renderer, args);
if (generatorProcess.waitForFinished()) {
if (generatorProcess.exitStatus() == QProcess::CrashExit) {

6
producers/CMakeLists.txt Normal file
View File

@@ -0,0 +1,6 @@
INSTALL (FILES
ladspa_sine_oscillator.xml
DESTINATION ${DATA_INSTALL_DIR}/kdenlive/producers)

View File

@@ -0,0 +1,12 @@
<!DOCTYPE kpartgui>
<producer tag="ladspa.1047" library="" id="ladspa.1047" ladspaid="1047" type="audio">
<name>Sine Oscillator</name>
<description>LADSPA audio effect</description>
<author>Richard Furse (LADSPA example plugins)</author>
<parameter type="float" name="0" max="15000" min="0" default="2400" suffix="Hz">
<name>Frequency</name>
</parameter>
<parameter type="float" name="1" max="100" min="0" default="1">
<name>Amplitude</name>
</parameter>
</effect>

View File

@@ -0,0 +1,25 @@
State of refactoring
=========================
* Initial position: Problems with the old code
The last time the code structure saw bigger changes had been the port to the KDE 4 libs. But even back
then central parts had only been updated and the structure remained the same. Over the years a latitude
of features were added.
Most action happens in very few, very big classes. They are tightly coupled together. So to add a feature,
changes across the code base are required. This complicates not only adding features even for developers
who know Kdenlive well, but also makes the process of doing so quite error prone. The inevitably following
bugs are quite hard to track down and even little fixes tend to introduce further bugs because of side effects.
As over time this only gets worse, some fundamental changes seemed to be long overdue.
* Refactoring concepts
To counter the mentioned problems key concepts were discussed in Randa 2011:
* OOP! Object Oriented Programming does not simply mean putting code in classes. One class per logical unit, every class has a clear responsibility.
The same applies to functions.
* Separation in Model and View.
* The two points mentioned above mean that when dealing with MLT in most case its one class per MLT class.
* All this should lead to a well defined Kdenlive core accessible through an API for additional features.
* Current State of the refactoring branch
EffectSystem -> does not follow MV paradigm
Basic timeline action missing -> how to handle movement of clips accross tracks
Some later additions hackish/unclean

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 112 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 78 KiB

View File

@@ -0,0 +1,854 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="1549.194"
height="1332.16"
id="svg3337"
version="1.1"
inkscape:version="0.48.4 r9939"
sodipodi:docname="Timeline_Snapping.svg">
<defs
id="defs3339">
<marker
markerWidth="13.96875"
markerHeight="12.15625"
orient="auto"
id="marker6345">
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline"
d="M -12.068051,-5.618565 0.4541487,5.0000002e-6 -12.068051,5.618565"
id="path6343"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc"
inkscape:transform-center-x="5.8069513" />
</marker>
<marker
markerWidth="13.96875"
markerHeight="12.15625"
orient="auto"
id="marker6345-8">
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline"
d="M -12.068051,-5.618565 0.4541487,5.0000002e-6 -12.068051,5.618565"
id="path6343-1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc"
inkscape:transform-center-x="5.8069513" />
</marker>
<marker
markerWidth="13.96875"
markerHeight="12.15625"
orient="auto"
id="marker6345-5">
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline"
d="M -12.068051,-5.618565 0.4541487,5.0000002e-6 -12.068051,5.618565"
id="path6343-8"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc"
inkscape:transform-center-x="5.8069513" />
</marker>
<marker
markerWidth="13.96875"
markerHeight="12.15625"
orient="auto"
id="marker6345-7">
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline"
d="M -12.068051,-5.618565 0.4541487,5.0000002e-6 -12.068051,5.618565"
id="path6343-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc"
inkscape:transform-center-x="5.8069513" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.35355339"
inkscape:cx="678.36725"
inkscape:cy="684.94539"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
showborder="true"
inkscape:window-width="1364"
inkscape:window-height="713"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:object-nodes="true"
inkscape:snap-center="true"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0">
<inkscape:grid
type="xygrid"
id="grid3391"
empspacing="6"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true"
spacingx="20px"
spacingy="20px"
color="#808080"
opacity="0.1254902"
empcolor="#808080"
empopacity="0.20392157"
originx="440px"
originy="423.28px" />
</sodipodi:namedview>
<metadata
id="metadata3342">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(440,-143.48218)">
<text
xml:space="preserve"
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro Bold"
x="-240"
y="172.36218"
id="text3345"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3347"
x="-240"
y="172.36218">Kdenlive Model: Timeline moving + snapping helper</tspan></text>
<text
xml:space="preserve"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"
x="-240"
y="232.36218"
id="text3349"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
x="-240"
y="232.36218"
id="tspan4823">When moving items in the timeline, we need “collision detection” and snapping.</tspan><tspan
sodipodi:role="line"
x="-240"
y="252.36218"
id="tspan4827">In the following example, the lighter clip is dragged over another clip. It cannot be dropped there.</tspan><tspan
sodipodi:role="line"
x="-240"
y="272.36218"
id="tspan4829">When dragging it to the left, the user would expect it to stick on the right of the other clip until </tspan><tspan
sodipodi:role="line"
x="-240"
y="292.36218"
id="tspan4831">it is dragged far enough that it can be inserted again.</tspan></text>
<rect
style="color:#000000;fill:#d4d4d4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect3372"
width="240"
height="60"
x="0"
y="332.36218" />
<rect
style="color:#000000;fill:#e9e9e9;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect3412"
width="100"
height="60"
x="60"
y="352.36218" />
<rect
style="color:#000000;fill:#5b5b5b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect4216"
width="20"
height="60"
x="0"
y="332.36218" />
<rect
style="color:#000000;fill:#5b5b5b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect4218"
width="20"
height="60"
x="140"
y="352.36218" />
<rect
style="color:#000000;fill:#d4d4d4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect4233"
width="120"
height="60"
x="-180"
y="332.36218" />
<rect
style="color:#000000;fill:#5b5b5b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect4220"
width="20"
height="60"
x="-180"
y="332.36218" />
<path
style="opacity:0.2893082;color:#000000;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#marker6345);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 160,432.36218 -160,0"
id="path4241"
inkscape:connector-curvature="0" />
<path
style="opacity:0.2893082;color:#000000;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#marker6345);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 160,452.36218 -340,0"
id="path4243"
inkscape:connector-curvature="0" />
<text
xml:space="preserve"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"
x="167.26912"
y="438.0582"
id="text4815"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4817"
x="167.26912"
y="438.0582">10 f</tspan></text>
<text
xml:space="preserve"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"
x="167.61313"
y="458.0582"
id="text4819"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4821"
x="167.61313"
y="458.0582">20 f</tspan></text>
<text
xml:space="preserve"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"
x="-240"
y="512.36218"
id="text4833"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4835"
x="-240"
y="512.36218">If a clip cannot be moved to the current mouse position, the helper calculates two points:</tspan><tspan
sodipodi:role="line"
x="-240"
y="532.36218"
id="tspan4839">The shortest distance to the left and to the right where insertion is possible again. For all</tspan><tspan
sodipodi:role="line"
x="-240"
y="552.36218"
id="tspan4843">of those points, we know that the right edge of the selected (i.e. dragged) clip must be adjacent</tspan><tspan
sodipodi:role="line"
x="-240"
y="572.36218"
id="tspan4847">to a left edge of an unselected clip—otherwise we could move it a few frames to the right.</tspan></text>
<text
xml:space="preserve"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"
x="-240"
y="612.36218"
id="text3019"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3021"
x="-240"
y="612.36218">The following algorithm can be used to find the next matching point:</tspan><tspan
sodipodi:role="line"
x="-240"
y="632.65387"
id="tspan3023">1. Create a list of possible positions (how many frames Δf to move) for the selected clip</tspan><tspan
sodipodi:role="line"
x="-240"
y="652.9455"
id="tspan3025">2. Sort the list ascendingly, so the smallest Δf is taken first</tspan><tspan
sodipodi:role="line"
x="-240"
y="672.9455"
id="tspan3027">3. Test all positions in order, and return the first one where no overlaps occur.</tspan></text>
<text
xml:space="preserve"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"
x="-240"
y="712.36218"
id="text3029"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3031"
x="-240"
y="712.36218">If multiple clips are selected and moved together, step 1 needs to be repeated for all clips</tspan><tspan
sodipodi:role="line"
x="-240"
y="732.36218"
id="tspan3033">in the selection. Example:</tspan></text>
<g
id="g3967">
<rect
y="772.36218"
x="-220"
height="60"
width="100"
id="rect3035"
style="color:#000000;fill:#d4d4d4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
y="772.36218"
x="100"
height="60"
width="80"
id="rect3854"
style="color:#000000;fill:#d4d4d4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
y="772.36218"
x="100"
height="60"
width="20"
id="rect3898"
style="color:#000000;fill:#5b5b5b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
y="772.36218"
x="-220"
height="60"
width="20"
id="rect3900"
style="color:#000000;fill:#5b5b5b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
</g>
<g
id="g3961">
<rect
y="792.36218"
x="120"
height="60"
width="60"
id="rect3856"
style="color:#000000;fill:#e9e9e9;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
y="792.36218"
x="240"
height="60"
width="100"
id="rect3858"
style="color:#000000;fill:#e9e9e9;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
y="792.36218"
x="160"
height="60"
width="20"
id="rect3888"
style="color:#000000;fill:#5b5b5b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
y="792.36218"
x="320"
height="60"
width="20"
id="rect3896"
style="color:#000000;fill:#5b5b5b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
</g>
<path
style="opacity:0.2893082;color:#000000;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#marker6345);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 180,872.36218 -80,0"
id="path3902"
inkscape:connector-curvature="0" />
<path
style="opacity:0.2893082;color:#000000;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#marker6345);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 180,892.36218 -400,0"
id="path3904"
inkscape:connector-curvature="0" />
<path
style="opacity:0.2893082;color:#000000;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#marker6345);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 340,912.36218 -240,0"
id="path3906"
inkscape:connector-curvature="0" />
<path
style="opacity:0.2893082;color:#000000;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#marker6345);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 340,932.36218 -560,0"
id="path3908"
inkscape:connector-curvature="0" />
<text
xml:space="preserve"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"
x="187.26912"
y="878.05817"
id="text3910"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3912"
x="187.26912"
y="878.05817">10 f</tspan></text>
<text
xml:space="preserve"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"
x="347.69312"
y="918.05817"
id="text3914"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3916"
x="347.69312"
y="918.05817">30 f</tspan></text>
<text
xml:space="preserve"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"
x="187.70113"
y="898.05817"
id="text3918"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3920"
x="187.70113"
y="898.05817">50 f</tspan></text>
<text
xml:space="preserve"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"
x="347.54913"
y="938.05817"
id="text3922"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3924"
x="347.54913"
y="938.05817">70 f</tspan></text>
<flowRoot
xml:space="preserve"
id="flowRoot3926"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"><flowRegion
id="flowRegion3928"><rect
id="rect3930"
width="88"
height="26"
x="429"
y="654.36218" /></flowRegion><flowPara
id="flowPara3932" /></flowRoot> <text
xml:space="preserve"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"
x="-240"
y="992.36218"
id="text3957"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3959"
x="-240"
y="992.36218">This would lead to the following tests (the vertical offset is just for clarity; </tspan><tspan
sodipodi:role="line"
x="-240"
y="1012.3622"
id="tspan4115">clips are all on the same track):</tspan></text>
<g
id="g3973"
transform="translate(0,280)">
<rect
style="color:#000000;fill:#d4d4d4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect3975"
width="100"
height="20"
x="-220"
y="772.36218" />
<rect
style="color:#000000;fill:#d4d4d4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect3977"
width="80"
height="20"
x="100"
y="772.36218" />
<rect
style="color:#000000;fill:#5b5b5b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect3979"
width="20"
height="20"
x="100"
y="772.36218" />
</g>
<g
id="g3983"
transform="translate(-80,280)">
<rect
style="color:#000000;fill:#e9e9e9;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect3985"
width="60"
height="20"
x="120"
y="792.36218" />
<rect
style="color:#000000;fill:#e9e9e9;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect3987"
width="100"
height="20"
x="240"
y="792.36218" />
<rect
style="color:#000000;fill:#5b5b5b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect3989"
width="20"
height="20"
x="160"
y="792.36218" />
</g>
<g
transform="translate(0,360)"
id="g3993">
<rect
y="772.36218"
x="-220"
height="20"
width="100"
id="rect3995"
style="color:#000000;fill:#d4d4d4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
y="772.36218"
x="100"
height="20"
width="80"
id="rect3997"
style="color:#000000;fill:#d4d4d4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
y="772.36218"
x="100"
height="20"
width="20"
id="rect3999"
style="color:#000000;fill:#5b5b5b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
</g>
<g
transform="translate(-240,360)"
id="g4003">
<rect
y="792.36218"
x="120"
height="20"
width="60"
id="rect4005"
style="color:#000000;fill:#e9e9e9;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
y="792.36218"
x="240"
height="20"
width="100"
id="rect4007"
style="color:#000000;fill:#e9e9e9;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
y="792.36218"
x="320"
height="20"
width="20"
id="rect4011"
style="color:#000000;fill:#5b5b5b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
</g>
<g
id="g4013"
transform="translate(0,440)">
<rect
style="color:#000000;fill:#d4d4d4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect4015"
width="100"
height="20"
x="-220"
y="772.36218" />
<rect
style="color:#000000;fill:#d4d4d4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect4017"
width="80"
height="20"
x="100"
y="772.36218" />
<rect
style="color:#000000;fill:#5b5b5b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect4021"
width="20"
height="20"
x="-220"
y="772.36218" />
</g>
<g
id="g4023"
transform="translate(-400,440)">
<rect
style="color:#000000;fill:#e9e9e9;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect4025"
width="60"
height="20"
x="120"
y="792.36218" />
<rect
style="color:#000000;fill:#e9e9e9;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect4027"
width="100"
height="20"
x="240"
y="792.36218" />
<rect
style="color:#000000;fill:#5b5b5b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect4029"
width="20"
height="20"
x="160"
y="792.36218" />
</g>
<g
transform="translate(0,520)"
id="g4033">
<rect
y="772.36218"
x="-220"
height="20"
width="100"
id="rect4035"
style="color:#000000;fill:#d4d4d4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
y="772.36218"
x="100"
height="20"
width="80"
id="rect4037"
style="color:#000000;fill:#d4d4d4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
y="772.36218"
x="-220"
height="20"
width="20"
id="rect4041"
style="color:#000000;fill:#5b5b5b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
</g>
<g
transform="translate(-560,520)"
id="g4043">
<rect
y="792.36218"
x="120"
height="20"
width="60"
id="rect4045"
style="color:#000000;fill:#e9e9e9;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
y="792.36218"
x="240"
height="20"
width="100"
id="rect4047"
style="color:#000000;fill:#e9e9e9;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
y="792.36218"
x="320"
height="20"
width="20"
id="rect4051"
style="color:#000000;fill:#5b5b5b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
</g>
<path
inkscape:connector-curvature="0"
id="path4056"
d="m 180,1092.3622 -80,0"
style="opacity:0.2893082;color:#000000;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#marker6345);visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<text
sodipodi:linespacing="125%"
id="text4058"
y="1098.0582"
x="187.26912"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"
xml:space="preserve"><tspan
y="1098.0582"
x="187.26912"
id="tspan4060"
sodipodi:role="line">10 f</tspan></text>
<path
inkscape:connector-curvature="0"
id="path4062"
d="m 180,1172.3622 -240,0"
style="opacity:0.2893082;color:#000000;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#marker6345);visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<text
sodipodi:linespacing="125%"
id="text4064"
y="1178.0582"
x="187.69312"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"
xml:space="preserve"><tspan
y="1178.0582"
x="187.69312"
id="tspan4066"
sodipodi:role="line">30 f</tspan></text>
<path
inkscape:connector-curvature="0"
id="path4068"
d="m 180,1252.3622 -400,0"
style="opacity:0.2893082;color:#000000;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#marker6345);visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<text
sodipodi:linespacing="125%"
id="text4070"
y="1258.0582"
x="187.70113"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"
xml:space="preserve"><tspan
y="1258.0582"
x="187.70113"
id="tspan4072"
sodipodi:role="line">50 f</tspan></text>
<path
inkscape:connector-curvature="0"
id="path4074"
d="m 180,1332.3622 -560,0"
style="opacity:0.2893082;color:#000000;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#marker6345);visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<text
sodipodi:linespacing="125%"
id="text4076"
y="1338.0582"
x="187.54913"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"
xml:space="preserve"><tspan
y="1338.0582"
x="187.54913"
id="tspan4078"
sodipodi:role="line">70 f</tspan></text>
<text
xml:space="preserve"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"
x="-240"
y="1392.3622"
id="text4117"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4119"
x="-240"
y="1392.3622">Tests 1, 2, and 4 match here. The algorithm would stop after test 1.</tspan></text>
<text
xml:space="preserve"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"
x="-240"
y="1452.3622"
id="text4121"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4123"
x="-240"
y="1452.3622">This algorithm can be extended to multiple tracks as it has been extended to multiple clips</tspan><tspan
sodipodi:role="line"
x="-240"
y="1472.3622"
id="tspan4125">per selection. </tspan></text>
<text
xml:space="preserve"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"
x="540"
y="232.36218"
id="text4127"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4129"
x="540"
y="232.36218">Another application of this algorithm is snapping to adjacent clips. The difference</tspan><tspan
sodipodi:role="line"
x="540"
y="252.36218"
id="tspan4131">is minor: Instead of trying to find the first place to the left (when dragging the clip </tspan><tspan
sodipodi:role="line"
x="540"
y="272.36218"
id="tspan4133">this way) where we can put the selected clip, we search for the first place where </tspan><tspan
sodipodi:role="line"
x="540"
y="292.36218"
id="tspan4135">another clip stops the selected one.</tspan></text>
<rect
style="color:#000000;fill:#d4d4d4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect3112"
width="140"
height="60"
x="580"
y="332.36218" />
<rect
style="color:#000000;fill:#e9e9e9;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect3114"
width="140"
height="60"
x="880"
y="352.36218" />
<rect
style="color:#000000;fill:#5b5b5b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect4218-0"
width="20"
height="60"
x="880"
y="352.36218" />
<rect
style="color:#000000;fill:#5b5b5b;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect4218-4"
width="20"
height="60"
x="700"
y="332.36218" />
<path
style="opacity:0.2893082;color:#000000;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#marker6345);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 880,432.36218 -160,0"
id="path3964"
inkscape:connector-curvature="0" />
<text
xml:space="preserve"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"
x="887.2691"
y="438.0582"
id="text3966"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3968"
x="887.2691"
y="438.0582">15 f</tspan></text>
<text
xml:space="preserve"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"
x="540"
y="492.36218"
id="text3993"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
x="540"
y="492.36218"
id="tspan4001">In this case, the helper takes the left edge of the selected clip and compares it to the</tspan><tspan
sodipodi:role="line"
x="540"
y="512.36218"
id="tspan4011">right edge of the clip to the left of it. This way the helper can give feedback about</tspan><tspan
sodipodi:role="line"
x="540"
y="532.36218"
id="tspan4015">where snapping is possible.</tspan></text>
<text
xml:space="preserve"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"
x="540"
y="592.36218"
id="text4017"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4019"
x="540"
y="592.36218">Performance of the algorithm can be improved by e.g. considering the visible part</tspan><tspan
sodipodi:role="line"
x="540"
y="612.36218"
id="tspan4021">of the timeline only, or by limiting the number of “lookahead steps” in a different way.</tspan></text>
<text
xml:space="preserve"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Source Sans Pro;-inkscape-font-specification:Source Sans Pro"
x="920"
y="172.36221"
id="text4023"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4025"
x="920"
y="172.36221">Author: Simon A. Eugster</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 40 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 82 KiB

View File

@@ -0,0 +1,43 @@
* How operations on clips in the timeline are implemented (in the model)
TimelineClip->setIn (in: number of frames relative to uncut clip (same as in MLT))
->setInOut()
TimelineClip->setOut(out: number of frames relative to uncut clip (same as in MLT))
->setInOut()
TimelineClip->setInOut(in, out)
=> ResizeClipCommand: * does not do any safety checks for available space!
* resizes the clip's producer,
* does not change its position when changing the in point!
* makes the clip emit resized()
TimelineClip->setPosition(position, track)
=> MoveClipCommand: * does not do any safety checks for available space!
* inserts the same producer cut at the requested position (if on same track)
* inserts a new producer cut at the requested position on the requested track,
as avformat clips require on base producer per track (audio bugs, search ml (kdenlive-devel, mlt-devel) for more info),
it asks the the ProjectClip (through TimelineClip) for the base producer associated with this track, then uses it
to create a cut and insert it.
* notifies the affacted tracks, so they can update their stored clip indices
* makes the clip emit moved()
To create a TimelineClip:
ProjectClip->createInstance()
To remove a TimelineClip:
TimelineClip->remove() -> ProjectClip->removeInstance()
=> 4 basic operations: add, remove, resize, move
These four operations should be enough to achieve everything imaginable,
without the need to use the MLT API.
Because they do not perform safety checks they should never be used directly (without performing checks).
As set of "compiled operations" can be directly used from the UI or from plugins.
Moving Helper:
The UI can use a moving helper from the model, to check if a move is allowed,
the moving helper provides alternative positions if a move is not possible, or because of snapping.
Regarding groups/selections:
They do not fit into the timeline tree (timeline->tracks->clips), and they do not represent a Mlt producer.
Instead they are some sort of meta clip. They forward operations applied on them to their member clips,
adding some safety checks and taking care of the right order.

View File

@@ -1,21 +0,0 @@
set(QT_DONT_USE_QTGUI 1)
set(QT_USE_QTDBUS 1)
set(kdenlive_render_SRCS
kdenlive_render.cpp
renderjob.cpp
)
kde4_add_executable(kdenlive_render ${kdenlive_render_SRCS})
include_directories(
${QT_INCLUDES}
)
include(${QT_USE_FILE})
target_link_libraries(kdenlive_render
${QT_LIBRARIES}
)
install(TARGETS kdenlive_render DESTINATION ${BIN_INSTALL_DIR})

View File

@@ -1,141 +0,0 @@
/***************************************************************************
* Copyright (C) 2008 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#include <stdio.h>
#include <QCoreApplication>
#include <QStringList>
#include <QString>
#include <QUrl>
#include <QtDebug>
#include "renderjob.h"
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
QStringList args = app.arguments();
QStringList preargs;
QString locale;
int pid = 0;
int in = -1;
int out = -1;
if (args.count() >= 7) {
// Remove program name
args.removeFirst();
bool erase = false;
if (args.at(0) == "-erase") {
erase = true;
args.removeFirst();
}
bool usekuiserver = false;
if (args.at(0) == "-kuiserver") {
usekuiserver = true;
args.removeFirst();
}
if (QString(args.at(0)).startsWith("-pid:")) {
pid = QString(args.at(0)).section(':', 1).toInt();
args.removeFirst();
}
if (QString(args.at(0)).startsWith("-locale:")) {
locale = QString(args.at(0)).section(':', 1);
args.removeFirst();
}
if (args.at(0).startsWith("in="))
in = args.takeFirst().section('=', -1).toInt();
if (args.at(0).startsWith("out="))
out = args.takeFirst().section('=', -1).toInt();
if (args.at(0).startsWith("preargs="))
preargs = args.takeFirst().section('=', 1).split(' ', QString::SkipEmptyParts);
QString render = args.takeFirst();
QString profile = args.takeFirst();
QString rendermodule = args.takeFirst();
QString player = args.takeFirst();
QByteArray srcString = args.takeFirst().toUtf8();
QUrl srcurl = QUrl::fromEncoded(srcString);
QString src = srcurl.path();
// The QUrl path() strips the consumer: protocol, so re-add it if necessary
if (srcString.startsWith("consumer:"))
src.prepend("consumer:");
QUrl desturl = QUrl::fromEncoded(args.takeFirst().toUtf8());
QString dest = desturl.path();
bool dualpass = false;
bool doerase;
QString vpre;
int vprepos = args.indexOf(QRegExp("vpre=.*"));
if (vprepos >= 0) {
vpre=args.at(vprepos);
}
QStringList vprelist = vpre.replace("vpre=", "").split(',');
if (vprelist.size() > 0) {
args.replaceInStrings(QRegExp("^vpre=.*"), QString("vpre=").append(vprelist.at(0)));
}
if (args.contains("pass=2")) {
// dual pass encoding
dualpass = true;
doerase = false;
args.replace(args.indexOf("pass=2"), "pass=1");
if (args.contains("vcodec=libx264")) args << QString("passlogfile=%1").arg(dest + ".log");
} else {
args.removeAll("pass=1");
doerase = erase;
}
// Decode metadata
for (int i = 0; i < args.count(); ++i) {
if (args.at(i).startsWith("meta.attr")) {
QString data = args.at(i);
args.replace(i, data.section('=', 0, 0) + "=\"" + QUrl::fromPercentEncoding(data.section('=', 1).toUtf8()) + "\"");
}
}
qDebug() << "//STARTING RENDERING: " << erase << "," << usekuiserver << "," << render << "," << profile << "," << rendermodule << "," << player << "," << src << "," << dest << "," << preargs << "," << args << "," << in << "," << out ;
RenderJob *job = new RenderJob(doerase, usekuiserver, pid, render, profile, rendermodule, player, src, dest, preargs, args, in, out);
if (!locale.isEmpty()) job->setLocale(locale);
job->start();
if (dualpass) {
if (vprelist.size()>1)
args.replaceInStrings(QRegExp("^vpre=.*"),QString("vpre=").append(vprelist.at(1)));
args.replace(args.indexOf("pass=1"), "pass=2");
RenderJob *dualjob = new RenderJob(erase, usekuiserver, pid, render, profile, rendermodule, player, src, dest, preargs, args, in, out);
QObject::connect(job, SIGNAL(renderingFinished()), dualjob, SLOT(start()));
}
app.exec();
} else {
fprintf(stderr, "Kdenlive video renderer for MLT.\nUsage: "
"kdenlive_render [-erase] [-kuiserver] [-locale:LOCALE] [in=pos] [out=pos] [render] [profile] [rendermodule] [player] [src] [dest] [[arg1] [arg2] ...]\n"
" -erase: if that parameter is present, src file will be erased at the end\n"
" -kuiserver: if that parameter is present, use KDE job tracker\n"
" -locale:LOCALE : set a locale for rendering. For example, -locale:fr_FR.UTF-8 will use a french locale (comma as numeric separator)\n"
" in=pos: start rendering at frame pos\n"
" out=pos: end rendering at frame pos\n"
" render: path to MLT melt renderer\n"
" profile: the MLT video profile\n"
" rendermodule: the MLT consumer used for rendering, usually it is avformat\n"
" player: path to video player to play when rendering is over, use '-' to disable playing\n"
" src: source file (usually MLT XML)\n"
" dest: destination file\n"
" args: space separated libavformat arguments\n");
}
}

View File

@@ -1,395 +0,0 @@
/***************************************************************************
* Copyright (C) 2007 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#include "renderjob.h"
#include <stdlib.h> // for getenv, posix portable to Windows: http://msdn.microsoft.com/en-us/library/tehxacec(VS.80).aspx
#include <QtDBus>
#include <QFile>
#include <QThread>
#include <QStringList>
// Can't believe I need to do this to sleep.
class SleepThread : QThread
{
public:
virtual void run() {}
static void msleep(unsigned long msecs) {
QThread::msleep(msecs);
}
};
RenderJob::RenderJob(bool erase, bool usekuiserver, int pid, const QString& renderer, const QString& profile, const QString& rendermodule, const QString& player, const QString& scenelist, const QString& dest, const QStringList& preargs, const QStringList& args, int in, int out) :
QObject(),
m_jobUiserver(NULL),
m_kdenliveinterface(NULL),
m_usekuiserver(usekuiserver),
m_enablelog(false),
m_pid(pid)
{
m_scenelist = scenelist;
m_dest = dest;
m_player = player;
m_progress = 0;
m_erase = erase;
m_renderProcess = new QProcess;
// Disable VDPAU so that rendering will work even if there is a Kdenlive instance using VDPAU
#if QT_VERSION >= 0x040600
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
env.insert("MLT_NO_VDPAU", "1");
m_renderProcess->setProcessEnvironment(env);
#else
QStringList env = QProcess::systemEnvironment();
env << "MLT_NO_VDPAU=1";
m_renderProcess->setEnvironment(env);
#endif
m_prog = renderer;
m_args << scenelist;
if (in != -1) m_args << "in=" + QString::number(in);
if (out != -1) m_args << "out=" + QString::number(out);
m_args << preargs;
//qDebug()<<"PRE ARGS: "<<preargs;
if (scenelist.startsWith("consumer:")) {
// Use MLT's producer_consumer, needs a different syntax for profile:
m_args << "profile=" + profile;
} else m_args << "-profile" << profile;
m_args << "-consumer" << rendermodule + ':' + m_dest << "progress=1" << args;
m_dualpass = false;
if (args.contains("pass=1")) m_dualpass = true;
connect(m_renderProcess, SIGNAL(stateChanged(QProcess::ProcessState)), this, SLOT(slotCheckProcess(QProcess::ProcessState)));
m_renderProcess->setReadChannel(QProcess::StandardError);
m_enablelog = (getenv("KDENLIVE_RENDER_LOG") != NULL);
if (m_enablelog) {
// Create a log of every render process.
m_logfile.setAutoRemove(false);
m_logfile.setFileTemplate(QDir::tempPath() + "/kdenlive_render.log.XXXXXXXX");
if (m_logfile.open()) {
qDebug() << "Writing render log to " << m_logfile.fileName();
} else {
qDebug() << "Unable to log to " << m_logfile.fileName();
}
m_logstream.setDevice(&m_logfile);
QString tmplist = scenelist;
if (tmplist.contains("consumer:")) {
QStringList tl = tmplist.split("consumer:");
if (tl.count() == 2) {
tmplist = tl[1];
}
}
m_logstream << "Log starting. Dumping contents of " << tmplist << endl;
QFile file(tmplist);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
m_logstream << "Unable to read contents of " << tmplist << endl;
} else {
m_logstream.flush();
QTextStream in(&file);
m_logstream << in.readAll() << endl;
}
}
}
RenderJob::~RenderJob()
{
delete m_renderProcess;
if (m_enablelog) {
m_logfile.close();
}
}
void RenderJob::setLocale(const QString &locale)
{
#if QT_VERSION >= 0x040600
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
env.insert("LC_NUMERIC", locale);
m_renderProcess->setProcessEnvironment(env);
#else
QStringList env = QProcess::systemEnvironment();
env << QString("LC_NUMERIC=%1").arg(locale);
m_renderProcess->setEnvironment(env);
#endif
}
void RenderJob::slotAbort(const QString& url)
{
if (m_dest == url) slotAbort();
}
void RenderJob::slotAbort()
{
qDebug() << "Kdenlive-render: JOB ABORTED BY USER...";
m_renderProcess->kill();
if (m_kdenliveinterface) {
m_dbusargs[1] = -3;
m_dbusargs.append(QString());
m_kdenliveinterface->callWithArgumentList(QDBus::NoBlock, "setRenderingFinished", m_dbusargs);
}
if (m_jobUiserver) m_jobUiserver->call("terminate", QString());
if (m_erase) {
QFile f(m_scenelist);
f.remove();
}
QFile f(m_dest);
f.remove();
if (m_enablelog) {
m_logstream << "Job aborted by user" << endl;
m_logstream.flush();
m_logfile.close();
}
qApp->quit();
}
void RenderJob::receivedStderr()
{
QString result = QString(m_renderProcess->readAllStandardError()).simplified();
//fprintf(stderr, "* * * *RENDER LG: %s\n", result.toUtf8().data());
if (!result.startsWith("Current Frame")) m_errorMessage.append(result + "<br>");
else {
if (m_enablelog) m_logstream << "ReceivedStderr from melt: " << result << endl;
result = result.section(' ', -1);
int pro = result.toInt();
if (pro < 0 || pro > 100) return;
if (pro > m_progress) {
m_progress = pro;
if (m_args.contains("pass=1")) {
m_progress /= 2.0;
} else if (m_args.contains("pass=2")) {
m_progress = 50 + m_progress / 2.0;
}
if (m_kdenliveinterface) {
if (!m_kdenliveinterface->isValid()) {
delete m_kdenliveinterface;
m_kdenliveinterface = NULL;
// qDebug() << "BROKEN COMMUNICATION WITH KDENLIVE";
} else {
m_dbusargs[1] = m_progress;
m_kdenliveinterface->callWithArgumentList(QDBus::NoBlock, "setRenderingProgress", m_dbusargs);
}
} else if (pro % 5 == 0) {
// Try to restart communication with Kdenlive every 5 percents
// qDebug() << "TRYING TO RESTART COMMUNICATION WITH KDENLIVE";
initKdenliveDbusInterface();
}
if (m_jobUiserver) {
m_jobUiserver->call("setPercent", (uint) m_progress);
/*int seconds = m_startTime.secsTo(QTime::currentTime());
seconds = seconds * (100 - m_progress) / m_progress;
m_jobUiserver->call("setDescriptionField", (uint) 1, tr("Remaining time"), QTime().addSecs(seconds).toString("hh:mm:ss"));*/
}
}
}
}
void RenderJob::start()
{
QDBusConnectionInterface* interface = QDBusConnection::sessionBus().interface();
if (interface && m_usekuiserver) {
if (!interface->isServiceRegistered("org.kde.JobViewServer")) {
qDebug() << "No org.kde.JobViewServer registered, trying to start kuiserver";
if (m_enablelog) m_logstream << "No org.kde.JobViewServer registered, trying to start kuiserver";
if (QProcess::startDetached("kuiserver")) {
qDebug() << "Started kuiserver";
if (m_enablelog) m_logstream << "Started kuiserver";
// Give it a couple of seconds to start
QTime t;
t.start();
while (!interface->isServiceRegistered("org.kde.JobViewServer") && t.elapsed() < 3000) {
SleepThread::msleep(100); //Sleep 100 ms
}
} else {
qDebug() << "Failed to start kuiserver";
if (m_enablelog) m_logstream << "Failed to start kuiserver";
}
}
if (interface->isServiceRegistered("org.kde.JobViewServer")) {
QDBusInterface kuiserver("org.kde.JobViewServer", "/JobViewServer", "org.kde.JobViewServer");
QDBusReply<QDBusObjectPath> objectPath = kuiserver.call("requestView", "Kdenlive", "kdenlive", 0x0001);
QString reply = ((QDBusObjectPath) objectPath).path();
// Use of the KDE JobViewServer is an ugly hack, it is not reliable
QString dbusView = "org.kde.JobViewV2";
m_jobUiserver = new QDBusInterface("org.kde.JobViewServer", reply, dbusView);
if (!m_jobUiserver || !m_jobUiserver->isValid()) {
dbusView = "org.kde.JobView";
m_jobUiserver = new QDBusInterface("org.kde.JobViewServer", reply, dbusView);
}
if (m_jobUiserver && m_jobUiserver->isValid()) {
m_startTime = QTime::currentTime();
if (!m_args.contains("pass=2"))
m_jobUiserver->call("setPercent", (uint) 0);
//m_jobUiserver->call("setInfoMessage", tr("Rendering %1").arg(QFileInfo(m_dest).fileName()));
m_jobUiserver->call("setDescriptionField", (uint) 0, tr("Rendering"), m_dest);
QDBusConnection::sessionBus().connect("org.kde.JobViewServer", reply, dbusView, "cancelRequested", this, SLOT(slotAbort()));
}
}
}
initKdenliveDbusInterface();
// Make sure the destination file is writable
QFile checkDestination(m_dest);
if (!checkDestination.open(QIODevice::WriteOnly)) {
slotIsOver(QProcess::NormalExit, false);
}
checkDestination.close();
// Because of the logging, we connect to stderr in all cases.
connect(m_renderProcess, SIGNAL(readyReadStandardError()), this, SLOT(receivedStderr()));
m_renderProcess->start(m_prog, m_args);
if (m_enablelog) m_logstream << "Started render process: " << m_prog << " " << m_args.join(" ") << endl;
qDebug() << "Started render process: " << m_prog << " " << m_args.join(" ");
}
void RenderJob::initKdenliveDbusInterface()
{
QString kdenliveId;
QDBusConnection connection = QDBusConnection::sessionBus();
QDBusConnectionInterface* ibus = connection.interface();
kdenliveId = QString("org.kde.kdenlive-%1").arg(m_pid);
if (!ibus->isServiceRegistered(kdenliveId))
{
kdenliveId.clear();
const QStringList services = ibus->registeredServiceNames();
foreach(const QString & service, services) {
if (!service.startsWith("org.kde.kdenlive"))
continue;
kdenliveId = service;
break;
}
}
m_dbusargs.clear();
if (kdenliveId.isEmpty()) return;
m_kdenliveinterface = new QDBusInterface(kdenliveId,
"/MainWindow",
"org.kdenlive.MainWindow",
connection,
this);
if (m_kdenliveinterface) {
m_dbusargs.append(m_dest);
m_dbusargs.append((int) 0);
if (!m_args.contains("pass=2"))
m_kdenliveinterface->callWithArgumentList(QDBus::NoBlock, "setRenderingProgress", m_dbusargs);
connect(m_kdenliveinterface, SIGNAL(abortRenderJob(QString)),
this, SLOT(slotAbort(QString)));
}
}
void RenderJob::slotCheckProcess(QProcess::ProcessState state)
{
if (state == QProcess::NotRunning) slotIsOver(m_renderProcess->exitStatus());
}
void RenderJob::slotIsOver(QProcess::ExitStatus status, bool isWritable)
{
if (m_jobUiserver) m_jobUiserver->call("terminate", QString());
if (!isWritable) {
QString error = tr("Cannot write to %1, check the permissions.").arg(m_dest);
if (m_kdenliveinterface) {
m_dbusargs[1] = (int) - 2;
m_dbusargs.append(error);
m_kdenliveinterface->callWithArgumentList(QDBus::NoBlock, "setRenderingFinished", m_dbusargs);
}
QStringList args;
args << "--error" << error;
if (m_enablelog) m_logstream << error << endl;
qDebug() << error;
QProcess::startDetached("kdialog", args);
qApp->quit();
}
if (m_erase) {
QFile f(m_scenelist);
f.remove();
}
if (status == QProcess::CrashExit || m_renderProcess->error() != QProcess::UnknownError) {
// rendering crashed
if (m_kdenliveinterface) {
m_dbusargs[1] = (int) - 2;
m_dbusargs.append(m_errorMessage);
m_kdenliveinterface->callWithArgumentList(QDBus::NoBlock, "setRenderingFinished", m_dbusargs);
}
QStringList args;
QString error = tr("Rendering of %1 aborted, resulting video will probably be corrupted.").arg(m_dest);
args << "--error" << error;
if (m_enablelog) m_logstream << error << endl;
qDebug() << error;
QProcess::startDetached("kdialog", args);
qApp->quit();
} else {
if (!m_dualpass && m_kdenliveinterface) {
m_dbusargs[1] = (int) - 1;
m_dbusargs.append(QString());
m_kdenliveinterface->callWithArgumentList(QDBus::NoBlock, "setRenderingFinished", m_dbusargs);
}
QDBusConnectionInterface* interface = QDBusConnection::sessionBus().interface();
if (!m_dualpass && interface && interface->isServiceRegistered("org.kde.knotify")) {
QDBusMessage m = QDBusMessage::createMethodCall("org.kde.knotify",
"/Notify",
"org.kde.KNotify",
"event");
int seconds = m_startTime.secsTo(QTime::currentTime());
QList<QVariant> args;
args.append(QString("RenderFinished")); // action name
args.append(QString("kdenlive")); // app name
args.append(QVariantList()); // contexts
args.append(tr("Rendering of %1 finished in %2").arg(m_dest, QTime(0, 0, seconds).toString("hh:mm:ss"))); // body
args.append(QByteArray()); // app icon
QStringList actionList;
args.append(actionList); // actions
qlonglong wid = 0;
args.append(wid); // win id
m.setArguments(args);
QDBusMessage replyMsg = QDBusConnection::sessionBus().call(m);
}
if (m_enablelog) m_logstream << "Rendering of " << m_dest << " finished" << endl;
qDebug() << "Rendering of " << m_dest << " finished";
if (!m_dualpass && m_player != "-") {
if (m_enablelog) m_logstream << "Starting player" << endl;
QStringList args;
args << m_dest;
QProcess::startDetached(m_player, args);
}
if (m_dualpass) {
emit renderingFinished();
deleteLater();
} else qApp->quit();
}
}
#include "renderjob.moc"

View File

@@ -1,80 +0,0 @@
/***************************************************************************
* Copyright (C) 2007 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#ifndef RENDERJOB_H
#define RENDERJOB_H
#include <QProcess>
#include <QObject>
#include <QDBusInterface>
#include <QTime>
// Testing
#include <QTemporaryFile>
#include <QTextStream>
class RenderJob : public QObject
{
Q_OBJECT
public:
RenderJob(bool erase, bool usekuiserver, int pid, const QString& renderer, const QString& profile, const QString& rendermodule, const QString& player, const QString& scenelist, const QString& dest, const QStringList& preargs, const QStringList& args, int in = -1, int out = -1);
~RenderJob();
void setLocale(const QString &locale);
public slots:
void start();
private slots:
void slotIsOver(QProcess::ExitStatus status, bool isWritable = true);
void receivedStderr();
void slotAbort();
void slotAbort(const QString& url);
void slotCheckProcess(QProcess::ProcessState state);
private:
QString m_scenelist;
QString m_dest;
int m_progress;
QProcess* m_renderProcess;
QString m_errorMessage;
QString m_prog;
QString m_player;
QStringList m_args;
bool m_erase;
bool m_dualpass;
QDBusInterface* m_jobUiserver;
QDBusInterface* m_kdenliveinterface;
QList<QVariant> m_dbusargs;
QTime m_startTime;
void initKdenliveDbusInterface();
bool m_usekuiserver;
bool m_enablelog;
/** @brief Used to create a temporary file for logging. */
QTemporaryFile m_logfile;
/** @brief Used to write to the log file. */
QTextStream m_logstream;
/** @brief The process id of the Kdenlive instance, used to get the dbus service. */
int m_pid;
signals:
void renderingFinished();
};
#endif

View File

@@ -5,6 +5,9 @@ set(QT_USE_QTSVG 1)
set(QT_USE_QTXML 1)
find_package(OpenGL REQUIRED)
find_package(GLEW REQUIRED)
if(APPLE)
find_package(SDL REQUIRED)
endif(APPLE)
@@ -33,6 +36,13 @@ if(WITH_JogShuttle)
endif(HAVE_LINUX_INPUT_H)
endif(WITH_JogShuttle)
macro_log_feature(GLEW_FOUND
"GLEW"
"OpenGL Extension Wrangler Library (GLEW)"
""
TRUE
)
macro_log_feature(QT_QTOPENGL_FOUND
"QtOpenGL"
"Qt bindings for the OpenGL library"
@@ -79,223 +89,14 @@ macro_log_feature(QJSON_FOUND
"Required to build the rotoscoping filter and for Freesound.org queries"
)
add_subdirectory(beziercurve)
add_subdirectory(colorcorrection)
add_subdirectory(commands)
add_subdirectory(lib)
add_subdirectory(projecttree)
add_subdirectory(utils)
add_subdirectory(databackup)
add_subdirectory(effectstack)
add_subdirectory(mimetypes)
add_subdirectory(onmonitoritems)
add_subdirectory(scopes)
add_subdirectory(simplekeyframes)
add_subdirectory(stopmotion)
if(QJSON_FOUND)
add_subdirectory(onmonitoritems/rotoscoping)
add_subdirectory(rotoscoping)
endif(QJSON_FOUND)
if(BUILD_V4L)
add_subdirectory(v4l)
endif(BUILD_V4L)
add_subdirectory(core)
add_subdirectory(plugins)
list(APPEND kdenlive_SRCS
main.cpp
mainwindow.cpp
KoSliderCombo.cpp
abstractclipitem.cpp
abstractgroupitem.cpp
abstractmonitor.cpp
archivewidget.cpp
choosecolorwidget.cpp
clipdurationdialog.cpp
clipitem.cpp
clipmanager.cpp
clipproperties.cpp
cliptranscode.cpp
clipstabilize.cpp
colorpickerwidget.cpp
colorplaneexport.cpp
colortools.cpp
complexparameter.cpp
cornerswidget.cpp
customruler.cpp
customtrackscene.cpp
customtrackview.cpp
definitions.cpp
docclipbase.cpp
documentchecker.cpp
documentvalidator.cpp
doubleparameterwidget.cpp
dragvalue.cpp
dvdwizard.cpp
dvdwizardchapters.cpp
dvdwizardmenu.cpp
dvdwizardvob.cpp
effectslist.cpp
effectslistview.cpp
effectslistwidget.cpp
effectstackedit.cpp
encodingprofilesdialog.cpp
folderprojectitem.cpp
gentime.cpp
geometryval.cpp
geometrywidget.cpp
graphicsscenerectmove.cpp
guide.cpp
headertrack.cpp
initeffects.cpp
kdenlivedoc.cpp
kdenlivesettingsdialog.cpp
keyframeedit.cpp
keyframehelper.cpp
kis_cubic_curve.cpp
kis_curve_widget.cpp
kthumb.cpp
managecapturesdialog.cpp
markerdialog.cpp
mltdevicecapture.cpp
monitor.cpp
monitoreditwidget.cpp
monitormanager.cpp
monitorscene.cpp
noteswidget.cpp
parameterplotter.cpp
positionedit.cpp
profilesdialog.cpp
projectitem.cpp
projectlist.cpp
projectlistview.cpp
projectsettings.cpp
recmonitor.cpp
renderer.cpp
renderwidget.cpp
slideshowclip.cpp
smallruler.cpp
spacerdialog.cpp
statusbarmessagelabel.cpp
subprojectitem.cpp
timecode.cpp
timecodedisplay.cpp
titledocument.cpp
titlewidget.cpp
trackdialog.cpp
tracksconfigdialog.cpp
trackview.cpp
transition.cpp
transitionsettings.cpp
unicodedialog.cpp
wizard.cpp
)
kde4_add_ui_files(kdenlive_UIS
widgets/addtrack_ui.ui
widgets/archivewidget_ui.ui
widgets/audiospectrum_ui.ui
widgets/backupdialog_ui.ui
widgets/bezierspline_ui.ui
widgets/boolval_ui.ui
widgets/clipdurationdialog_ui.ui
widgets/clipproperties_ui.ui
widgets/cliptranscode_ui.ui
widgets/collapsiblewidget_ui.ui
widgets/clipstabilize_ui.ui
widgets/colorclip_ui.ui
widgets/colorplaneexport_ui.ui
widgets/configcapture_ui.ui
widgets/configenv_ui.ui
widgets/configjogshuttle_ui.ui
widgets/configmisc_ui.ui
widgets/configproject_ui.ui
widgets/configsdl_ui.ui
widgets/configtimeline_ui.ui
widgets/configtranscode_ui.ui
widgets/dvdwizardchapters_ui.ui
widgets/dvdwizardmenu_ui.ui
widgets/dvdwizardstatus_ui.ui
widgets/dvdwizardvob_ui.ui
widgets/effectlist_ui.ui
widgets/effectstack_ui.ui
widgets/effectstack2_ui.ui
widgets/freesound_ui.ui
widgets/geometryval_ui.ui
widgets/geometrywidget_ui.ui
widgets/histogram_ui.ui
widgets/keyframedialog_ui.ui
widgets/keyframeeditor_ui.ui
widgets/keyframewidget_ui.ui
widgets/listval_ui.ui
widgets/managecaptures_ui.ui
widgets/manageencodingprofile_ui.ui
widgets/markerdialog_ui.ui
widgets/missingclips_ui.ui
widgets/monitoreditwidget_ui.ui
widgets/profiledialog_ui.ui
widgets/projectsettings_ui.ui
widgets/recmonitor_ui.ui
widgets/renderwidget_ui.ui
widgets/rgbparade_ui.ui
widgets/saveprofile_ui.ui
widgets/slideshowclip_ui.ui
widgets/smconfig_ui.ui
widgets/spacerdialog_ui.ui
widgets/spectrogram_ui.ui
widgets/stopmotion_ui.ui
widgets/templateclip_ui.ui
widgets/timeline_ui.ui
widgets/timelinebuttons_ui.ui
widgets/titlewidget_ui.ui
widgets/trackheader_ui.ui
widgets/tracksconfigdialog_ui.ui
widgets/transitionsettings_ui.ui
widgets/unicodewidget_ui.ui
widgets/urlval_ui.ui
widgets/vectorscope_ui.ui
widgets/waveform_ui.ui
widgets/wipeval_ui.ui
widgets/wizardcapture_ui.ui
widgets/wizardcheck_ui.ui
widgets/wizardextra_ui.ui
widgets/wizardmltcheck_ui.ui
widgets/wizardstandard_ui.ui
widgets/keywordval_ui.ui
widgets/fontval_ui.ui
widgets/cutjobdialog_ui.ui
widgets/scenecutdialog_ui.ui
widgets/importkeyframesdialog_ui.ui
)
if(OPENGL_FOUND)
list(APPEND kdenlive_SRCS videoglwidget.cpp)
endif(OPENGL_FOUND)
if(BUILD_JogShuttle)
list(APPEND kdenlive_SRCS
jogaction.cpp
jogshuttle.cpp
jogshuttleconfig.cpp
)
endif(BUILD_JogShuttle)
kde4_add_kcfg_files(kdenlive_SRCS kdenlivesettings.kcfgc)
qt4_add_dbus_adaptor(kdenlive_SRCS
org.kdenlive.MainWindow.xml
mainwindow.h
MainWindow
)
qt4_add_resources(kdenlive_SRCS widgets/resources.qrc)
kde4_add_executable(kdenlive
${kdenlive_SRCS}
${kdenlive_UIS}
)
# To compile kiss_fft.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --std=c99")
# KDE definitions and include directories *must* always come first, Qt follows
# (to avoid breaking builds when KDE and/or Qt are installed to different
@@ -303,10 +104,13 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --std=c99")
add_definitions(${KDE4_DEFINITIONS})
include_directories(
${CMAKE_SOURCE_DIR}/src/core
${CMAKE_SOURCE_DIR}
${CMAKE_BINARY_DIR}
${KDE4_INCLUDES} # Adds Qt include directories too.
${LIBMLT_INCLUDE_DIR}
${LIBMLTPLUS_INCLUDE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
)
@@ -314,6 +118,19 @@ include_directories(
# to the components requested in find_package().
include(${QT_USE_FILE})
# qt4_add_dbus_adaptor(kdenlive_SRCS
# org.kdenlive.MainWindow.xml
# mainwindow.h
# MainWindow
# )
kde4_add_executable(kdenlive
${kdenlive_SRCS}
)
# To compile kiss_fft.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --std=c99")
if(${KDE_VERSION} VERSION_LESS 4.3.80)
set(KDE4_KNEWSTUFF_LIBS ${KDE4_KNEWSTUFF2_LIBS})
else(${KDE_VERSION} VERSION_LESS 4.3.80)
@@ -321,6 +138,7 @@ else(${KDE_VERSION} VERSION_LESS 4.3.80)
endif(${KDE_VERSION} VERSION_LESS 4.3.80)
target_link_libraries(kdenlive
kdenlivecore
${KDE4_KDEUI_LIBS}
${KDE4_KIO_LIBS}
${KDE4_KNEWSTUFF_LIBS}
@@ -377,19 +195,11 @@ if(BUILD_JogShuttle)
endif(BUILD_JogShuttle)
install(TARGETS kdenlive DESTINATION ${BIN_INSTALL_DIR})
install(FILES
kdenliveui.rc
kdenlive.notifyrc
DESTINATION ${DATA_INSTALL_DIR}/kdenlive
)
install(FILES kdenlivesettings.kcfg DESTINATION ${KCFG_INSTALL_DIR})
install(FILES
kdenlive_projectprofiles.knsrc
kdenlive_renderprofiles.knsrc
kdenlive_titles.knsrc
kdenlive_wipes.knsrc
kdenlivetranscodingrc
DESTINATION ${CONFIG_INSTALL_DIR}
)
# install(FILES
# kdenliveui.rc
# kdenlive.notifyrc
# DESTINATION ${DATA_INSTALL_DIR}/kdenlive
# )
kde4_install_icons(${ICON_INSTALL_DIR})
install(FILES kdenlive.desktop DESTINATION ${XDG_APPS_INSTALL_DIR})

View File

@@ -1,334 +0,0 @@
/* This file is part of the KDE project
Copyright (c) 2007 Casper Boemann <cbr@boemann.dk>
Copyright (c) 2010 Jean-Baptiste Mardelle <jb@kdenlive.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "KoSliderCombo.h"
#include <QTimer>
#include <QApplication>
#include <QSize>
#include <QSlider>
#include <QStyle>
#include <QStylePainter>
#include <QStyleOptionSlider>
#include <QLineEdit>
#include <QValidator>
#include <QHBoxLayout>
#include <QFrame>
#include <QMenu>
#include <QMouseEvent>
#include <QDoubleSpinBox>
#include <QDesktopWidget>
#include <kglobal.h>
#include <klocale.h>
#include <kdebug.h>
class KoSliderComboContainer : public QMenu
{
public:
KoSliderComboContainer(KoSliderCombo *parent) : QMenu(parent), m_parent(parent) {}
protected:
virtual void mousePressEvent(QMouseEvent *e);
private:
KoSliderCombo *m_parent;
};
void KoSliderComboContainer::mousePressEvent(QMouseEvent *e)
{
QStyleOptionComboBox opt;
opt.init(m_parent);
opt.subControls = QStyle::SC_All;
opt.activeSubControls = QStyle::SC_ComboBoxArrow;
QStyle::SubControl sc = style()->hitTestComplexControl(QStyle::CC_ComboBox, &opt,
m_parent->mapFromGlobal(e->globalPos()),
m_parent);
if (sc == QStyle::SC_ComboBoxArrow)
setAttribute(Qt::WA_NoMouseReplay);
QMenu::mousePressEvent(e);
}
class KoSliderCombo::KoSliderComboPrivate
{
public:
KoSliderCombo *thePublic;
QValidator *m_validator;
QTimer m_timer;
KoSliderComboContainer *container;
QSlider *slider;
QStyle::StateFlag arrowState;
qreal minimum;
qreal maximum;
int decimals;
bool firstShowOfSlider;
void showPopup();
void hidePopup();
void sliderValueChanged(int value);
void sliderReleased();
void lineEditFinished();
};
KoSliderCombo::KoSliderCombo(QWidget *parent)
: QComboBox(parent)
, d(new KoSliderComboPrivate())
{
d->thePublic = this;
d->minimum = 0.0;
d->maximum = 100.0;
d->decimals = 2;
d->container = new KoSliderComboContainer(this);
d->container->setAttribute(Qt::WA_WindowPropagation);
QStyleOptionComboBox opt;
opt.init(this);
// d->container->setFrameStyle(style()->styleHint(QStyle::SH_ComboBox_PopupFrameStyle, &opt, this));
d->slider = new QSlider(Qt::Horizontal);
d->slider->setMinimum(0);
d->slider->setMaximum(256);
d->slider->setPageStep(10);
d->slider->setValue(0);
// When set to true, causes flicker on Qt 4.6. Any reason to keep it?
d->firstShowOfSlider = false; //true;
QHBoxLayout * l = new QHBoxLayout();
l->setMargin(2);
l->setSpacing(2);
l->addWidget(d->slider);
d->container->setLayout(l);
d->container->resize(200, 30);
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
setEditable(true);
setEditText(KGlobal::locale()->formatNumber(0, d->decimals));
connect(d->slider, SIGNAL(valueChanged(int)), SLOT(sliderValueChanged(int)));
connect(d->slider, SIGNAL(sliderReleased()), SLOT(sliderReleased()));
connect(lineEdit(), SIGNAL(editingFinished()), SLOT(lineEditFinished()));
}
KoSliderCombo::~KoSliderCombo()
{
delete d;
}
QSize KoSliderCombo::sizeHint() const
{
return minimumSizeHint();
}
QSize KoSliderCombo::minimumSizeHint() const
{
QSize sh;
const QFontMetrics &fm = fontMetrics();
sh.setWidth(5 * fm.width(QLatin1Char('8')));
sh.setHeight(qMax(fm.lineSpacing(), 14) + 2);
// add style and strut values
QStyleOptionComboBox opt;
opt.init(this);
opt.subControls = QStyle::SC_All;
opt.editable = true;
sh = style()->sizeFromContents(QStyle::CT_ComboBox, &opt, sh, this);
return sh.expandedTo(QApplication::globalStrut());
}
void KoSliderCombo::KoSliderComboPrivate::showPopup()
{
if (firstShowOfSlider) {
container->show(); //show container a bit early so the slider can be layout'ed
firstShowOfSlider = false;
}
QStyleOptionSlider opt;
opt.init(slider);
opt.maximum = 256;
opt.sliderPosition = opt.sliderValue = slider->value();
int hdlPos = thePublic->style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle).center().x();
QStyleOptionComboBox optThis;
optThis.init(thePublic);
optThis.subControls = QStyle::SC_All;
optThis.editable = true;
int arrowPos = thePublic->style()->subControlRect(QStyle::CC_ComboBox, &optThis, QStyle::SC_ComboBoxArrow).center().x();
QSize popSize = container->size();
QRect popupRect(thePublic->mapToGlobal(QPoint(arrowPos - hdlPos - slider->x(), thePublic->size().height())), popSize);
// Make sure the popup is not drawn outside the screen area
QRect screenRect = QApplication::desktop()->availableGeometry(thePublic);
if (popupRect.right() > screenRect.right())
popupRect.translate(screenRect.right() - popupRect.right(), 0);
if (popupRect.left() < screenRect.left())
popupRect.translate(screenRect.left() - popupRect.left(), 0);
if (popupRect.bottom() > screenRect.bottom())
popupRect.translate(0, -(thePublic->height() + container->height()));
container->setGeometry(popupRect);
container->raise();
container->show();
slider->setFocus();
}
void KoSliderCombo::KoSliderComboPrivate::hidePopup()
{
container->hide();
}
void KoSliderCombo::hideEvent(QHideEvent *)
{
d->hidePopup();
}
void KoSliderCombo::changeEvent(QEvent *e)
{
switch (e->type()) {
case QEvent::EnabledChange:
if (!isEnabled())
d->hidePopup();
break;
case QEvent::PaletteChange:
d->container->setPalette(palette());
break;
default:
break;
}
QComboBox::changeEvent(e);
}
void KoSliderCombo::paintEvent(QPaintEvent *)
{
QStylePainter gc(this);
gc.setPen(palette().color(QPalette::Text));
QStyleOptionComboBox opt;
opt.init(this);
opt.subControls = QStyle::SC_All;
opt.editable = true;
gc.drawComplexControl(QStyle::CC_ComboBox, opt);
gc.drawControl(QStyle::CE_ComboBoxLabel, opt);
}
void KoSliderCombo::mousePressEvent(QMouseEvent *e)
{
QStyleOptionComboBox opt;
opt.init(this);
opt.subControls = QStyle::SC_All;
opt.editable = true;
QStyle::SubControl sc = style()->hitTestComplexControl(QStyle::CC_ComboBox, &opt, e->pos(),
this);
if (sc == QStyle::SC_ComboBoxArrow && !d->container->isVisible()) {
d->showPopup();
} else
QComboBox::mousePressEvent(e);
}
void KoSliderCombo::keyPressEvent(QKeyEvent *e)
{
if (e->key() == Qt::Key_Up) setValue(value() + d->slider->singleStep() *(maximum() - minimum()) / 256 + 0.5);
else if (e->key() == Qt::Key_Down) setValue(value() - d->slider->singleStep() *(maximum() - minimum()) / 256 - 0.5);
else QComboBox::keyPressEvent(e);
}
void KoSliderCombo::wheelEvent(QWheelEvent *e)
{
if (e->delta() > 0) setValue(value() + d->slider->singleStep() *(maximum() - minimum()) / 256 + 0.5);
else setValue(value() - d->slider->singleStep() *(maximum() - minimum()) / 256 - 0.5);
}
void KoSliderCombo::KoSliderComboPrivate::lineEditFinished()
{
qreal value = thePublic->currentText().toDouble();
slider->blockSignals(true);
slider->setValue(int((value - minimum) * 256 / (maximum - minimum) + 0.5));
slider->blockSignals(false);
emit thePublic->valueChanged(value, true);
}
void KoSliderCombo::KoSliderComboPrivate::sliderValueChanged(int slidervalue)
{
thePublic->setEditText(KGlobal::locale()->formatNumber(minimum + (maximum - minimum)*slidervalue / 256, decimals));
qreal value = thePublic->currentText().toDouble();
emit thePublic->valueChanged(value, false);
}
void KoSliderCombo::KoSliderComboPrivate::sliderReleased()
{
qreal value = thePublic->currentText().toDouble();
emit thePublic->valueChanged(value, true);
}
qreal KoSliderCombo::maximum() const
{
return d->maximum;
}
qreal KoSliderCombo::minimum() const
{
return d->minimum;
}
qreal KoSliderCombo::decimals() const
{
return d->decimals;
}
qreal KoSliderCombo::value() const
{
return currentText().toDouble();
}
void KoSliderCombo::setDecimals(int dec)
{
d->decimals = dec;
if (dec == 0) lineEdit()->setValidator(new QIntValidator(this));
else lineEdit()->setValidator(new QDoubleValidator(this));
}
void KoSliderCombo::setMinimum(qreal min)
{
d->minimum = min;
}
void KoSliderCombo::setMaximum(qreal max)
{
d->maximum = max;
}
void KoSliderCombo::setValue(qreal value)
{
if (value < d->minimum)
value = d->minimum;
if (value > d->maximum)
value = d->maximum;
setEditText(KGlobal::locale()->formatNumber(value, d->decimals));
d->slider->blockSignals(true);
d->slider->setValue(int((value - d->minimum) * 256 / (d->maximum - d->minimum) + 0.5));
d->slider->blockSignals(false);
emit valueChanged(value, true);
}
#include <KoSliderCombo.moc>

View File

@@ -1,140 +0,0 @@
/* This file is part of the KDE project
Copyright (c) 2007 Casper Boemann <cbr@boemann.dk>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef KOSLIDERCOMBO_H_
#define KOSLIDERCOMBO_H_
#include <QComboBox>
/**
* @short A widget for qreal values with a popup slider
*
* KoSliderCombo combines a numerical input and a dropdown slider in a way that takes up as
* little screen space as possible.
*
* It allows the user to either enter a floating point value or quickly set the value using a slider
*
* One signal is emitted when the value changes. The signal is even emitted when the slider
* is moving. The second argument of the signal however tells you if the value is final or not. A
* final value is produced by entering a value numerically or by releasing the slider.
*
* The input of the numerical line edit is constrained to numbers and decimal signs.
*/
class KoSliderCombo : public QComboBox
{
Q_OBJECT
public:
/**
* Constructor for the widget, where value is set to 0
*
* @param parent parent QWidget
*/
explicit KoSliderCombo(QWidget *parent = 0);
/**
* Destructor
*/
virtual ~KoSliderCombo();
/**
* The precision of values given as the number of digits after the period.
* default is 2
*/
qreal decimals() const;
/**
* The minimum value that can be entered.
* default is 0
*/
qreal minimum() const;
/**
* The maximum value that can be entered.
* default is 100
*/
qreal maximum() const;
/**
* Sets the precision of the entered values.
* @param number the number of digits after the period
*/
void setDecimals(int number);
/**
* Sets the minimum value that can be entered.
* @param min the minimum value
*/
void setMinimum(qreal min);
/**
* Sets the maximum value that can be entered.
* @param max the maximum value
*/
void setMaximum(qreal max);
/**
* The value shown.
*/
qreal value() const;
virtual QSize minimumSizeHint() const; ///< reimplemented from QComboBox
virtual QSize sizeHint() const; ///< reimplemented from QComboBox
public slots:
/**
* Sets the value.
* The value actually set is forced to be within the legal range: minimum <= value <= maximum
* @param value the new value
*/
void setValue(qreal value);
signals:
/**
* Emitted every time the value changes (by calling setValue() or
* by user interaction).
* @param value the new value
* @param final if the value is final ie not produced during sliding (on slider release it's final)
*/
void valueChanged(qreal value, bool final);
protected:
virtual void paintEvent(QPaintEvent *); ///< reimplemented from QComboBox
virtual void hideEvent(QHideEvent *); ///< reimplemented from QComboBox
virtual void changeEvent(QEvent *e); ///< reimplemented from QComboBox
virtual void mousePressEvent(QMouseEvent *e); ///< reimplemented from QComboBox
virtual void keyPressEvent(QKeyEvent *e); ///< reimplemented from QComboBox
virtual void wheelEvent(QWheelEvent *e); ///< reimplemented from QComboBox
private:
Q_PRIVATE_SLOT(d, void sliderValueChanged(int value))
Q_PRIVATE_SLOT(d, void sliderReleased())
Q_PRIVATE_SLOT(d, void lineEditFinished())
class KoSliderComboPrivate;
KoSliderComboPrivate * const d;
};
#endif

View File

@@ -1,551 +0,0 @@
/***************************************************************************
* Copyright (C) 2008 by Marco Gittler (g.marco@freenet.de) *
* Copyright (C) 2008 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#include "abstractclipitem.h"
#include "customtrackscene.h"
#include "kdenlivesettings.h"
#include <KDebug>
#include <KLocale>
#include <KGlobalSettings>
#include <QPainter>
#include <QToolTip>
#include <QGraphicsSceneMouseEvent>
#include <QParallelAnimationGroup>
AbstractClipItem::AbstractClipItem(const ItemInfo &info, const QRectF& rect, double fps) :
QObject()
, QGraphicsRectItem(rect)
, m_info(info)
, m_editedKeyframe(-1)
, m_selectedKeyframe(0)
, m_keyframeFactor(1)
, m_keyframeOffset(0)
, m_keyframeDefault(0)
, m_visibleParam(0)
, m_fps(fps)
, m_isMainSelectedClip(false)
{
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
#if QT_VERSION >= 0x040600
setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
setFlag(QGraphicsItem::ItemUsesExtendedStyleOption, true);
#endif
}
AbstractClipItem::~AbstractClipItem()
{
}
void AbstractClipItem::closeAnimation()
{
#if QT_VERSION >= 0x040600
if (!isEnabled()) return;
setEnabled(false);
setFlag(QGraphicsItem::ItemIsSelectable, false);
if (!(KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects)) {
// animation disabled
deleteLater();
return;
}
QPropertyAnimation *closeAnimation = new QPropertyAnimation(this, "rect");
QPropertyAnimation *closeAnimation2 = new QPropertyAnimation(this, "opacity");
closeAnimation->setDuration(200);
closeAnimation2->setDuration(200);
QRectF r = rect();
QRectF r2 = r;
r2.setLeft(r.left() + r.width() / 2);
r2.setTop(r.top() + r.height() / 2);
r2.setWidth(1);
r2.setHeight(1);
closeAnimation->setStartValue(r);
closeAnimation->setEndValue(r2);
closeAnimation->setEasingCurve(QEasingCurve::InQuad);
closeAnimation2->setStartValue(1.0);
closeAnimation2->setEndValue(0.0);
QParallelAnimationGroup *group = new QParallelAnimationGroup;
connect(group, SIGNAL(finished()), this, SLOT(deleteLater()));
group->addAnimation(closeAnimation);
group->addAnimation(closeAnimation2);
group->start(QAbstractAnimation::DeleteWhenStopped);
#endif
}
ItemInfo AbstractClipItem::info() const
{
ItemInfo info = m_info;
info.cropStart = cropStart();
info.endPos = endPos();
return info;
}
int AbstractClipItem::defaultZValue() const
{
return 2;
}
GenTime AbstractClipItem::endPos() const
{
return m_info.startPos + m_info.cropDuration;
}
int AbstractClipItem::track() const
{
return m_info.track;
}
GenTime AbstractClipItem::cropStart() const
{
return m_info.cropStart;
}
GenTime AbstractClipItem::cropDuration() const
{
return m_info.cropDuration;
}
void AbstractClipItem::setCropStart(const GenTime &pos)
{
m_info.cropStart = pos;
}
void AbstractClipItem::updateItem()
{
m_info.track = (int)(scenePos().y() / KdenliveSettings::trackheight());
m_info.startPos = GenTime((int) scenePos().x(), m_fps);
}
void AbstractClipItem::updateRectGeometry()
{
setRect(0, 0, cropDuration().frames(m_fps) - 0.02, rect().height());
}
void AbstractClipItem::resizeStart(int posx, bool hasSizeLimit, bool /*emitChange*/)
{
GenTime durationDiff = GenTime(posx, m_fps) - m_info.startPos;
if (durationDiff == GenTime()) return;
if (type() == AVWIDGET && hasSizeLimit && (cropStart() + durationDiff < GenTime())) {
durationDiff = GenTime() - cropStart();
} else if (durationDiff >= cropDuration()) {
return;
/*if (cropDuration() > GenTime(3, m_fps)) durationDiff = GenTime(3, m_fps);
else return;*/
}
m_info.startPos += durationDiff;
// set to true if crop from start is negative (possible for color clips, images as they have no size limit)
bool negCropStart = false;
if (type() == AVWIDGET) {
m_info.cropStart += durationDiff;
if (m_info.cropStart < GenTime())
negCropStart = true;
}
m_info.cropDuration -= durationDiff;
setRect(0, 0, cropDuration().frames(m_fps) - 0.02, rect().height());
moveBy(durationDiff.frames(m_fps), 0);
if (m_info.startPos != GenTime(posx, m_fps)) {
//kDebug() << "////// WARNING, DIFF IN XPOS: " << pos().x() << " == " << m_info.startPos.frames(m_fps);
GenTime diff = m_info.startPos - GenTime(posx, m_fps);
if (type() == AVWIDGET)
m_info.cropStart += diff;
m_info.cropDuration -= diff;
setRect(0, 0, cropDuration().frames(m_fps) - 0.02, rect().height());
//kDebug()<<"// NEW START: "<<m_startPos.frames(25)<<", NW DUR: "<<m_cropDuration.frames(25);
}
// set crop from start to 0 (isn't relevant as this only happens for color clips, images)
if (negCropStart)
m_info.cropStart = GenTime();
//kDebug() << "-- NEW CLIP=" << startPos().frames(25) << "-" << endPos().frames(25);
//setRect((double) m_startPos.frames(m_fps) * scale, rect().y(), (double) m_cropDuration.frames(m_fps) * scale, rect().height());
/* if (durationDiff < GenTime()) {
QList <QGraphicsItem *> collisionList = collidingItems(Qt::IntersectsItemBoundingRect);
for (int i = 0; i < collisionList.size(); ++i) {
QGraphicsItem *item = collisionList.at(i);
if (item->type() == type() && item->pos().x() < pos().x()) {
kDebug() << "///////// COLLISION DETECTED!!!!!!!!!";
GenTime diff = ((AbstractClipItem *)item)->endPos() + GenTime(1, m_fps) - m_startPos;
setRect(0, 0, (m_cropDuration - diff).frames(m_fps) - 0.02, rect().height());
setPos((m_startPos + diff).frames(m_fps), pos().y());
m_startPos += diff;
if (type() == AVWIDGET) m_cropStart += diff;
m_cropDuration = m_cropDuration - diff;
break;
}
}
}*/
}
void AbstractClipItem::resizeEnd(int posx, bool /*emitChange*/)
{
GenTime durationDiff = GenTime(posx, m_fps) - endPos();
if (durationDiff == GenTime()) return;
if (cropDuration() + durationDiff <= GenTime()) {
durationDiff = GenTime() - (cropDuration() - GenTime(3, m_fps));
}
m_info.cropDuration += durationDiff;
m_info.endPos += durationDiff;
setRect(0, 0, cropDuration().frames(m_fps) - 0.02, rect().height());
if (durationDiff > GenTime()) {
QList <QGraphicsItem *> collisionList = collidingItems(Qt::IntersectsItemBoundingRect);
bool fixItem = false;
for (int i = 0; i < collisionList.size(); ++i) {
if (!collisionList.at(i)->isEnabled()) continue;
QGraphicsItem *item = collisionList.at(i);
if (item->type() == type() && item->pos().x() > pos().x()) {
//kDebug() << "///////// COLLISION DETECTED!!!!!!!!!";
//kDebug() << "///////// CURRENT: " << startPos().frames(25) << "x" << endPos().frames(25) << ", RECT: " << rect() << "-" << pos();
//kDebug() << "///////// COLLISION: " << ((AbstractClipItem *)item)->startPos().frames(25) << "x" << ((AbstractClipItem *)item)->endPos().frames(25) << ", RECT: " << ((AbstractClipItem *)item)->rect() << "-" << item->pos();
GenTime diff = ((AbstractClipItem *)item)->startPos() - startPos();
if (fixItem == false || diff < m_info.cropDuration) {
fixItem = true;
m_info.cropDuration = diff;
}
}
}
if (fixItem) setRect(0, 0, cropDuration().frames(m_fps) - 0.02, rect().height());
}
}
GenTime AbstractClipItem::startPos() const
{
return m_info.startPos;
}
void AbstractClipItem::setTrack(int track)
{
m_info.track = track;
}
double AbstractClipItem::fps() const
{
return m_fps;
}
void AbstractClipItem::updateFps(double fps)
{
m_fps = fps;
setPos((qreal) startPos().frames(m_fps), pos().y());
updateRectGeometry();
}
GenTime AbstractClipItem::maxDuration() const
{
return m_maxDuration;
}
void AbstractClipItem::drawKeyFrames(QPainter *painter, const QTransform &transformation, bool limitedKeyFrames)
{
if (m_keyframes.count() < 1)
return;
QRectF br = rect();
double maxw = br.width() / cropDuration().frames(m_fps);
double maxh = br.height() / 100.0 * m_keyframeFactor;
double start = cropStart().frames(m_fps);
double x1, y1, x2, y2;
bool antialiasing = painter->renderHints() & QPainter::Antialiasing;
// draw line showing default value
bool active = isSelected() || (parentItem() && parentItem()->isSelected());
if (active) {
x1 = br.x();
x2 = br.right();
if (limitedKeyFrames) {
QMap<int, int>::const_iterator end = m_keyframes.constEnd();
--end;
x2 = x1 + maxw * (end.key() - start);
x1 += maxw * (m_keyframes.constBegin().key() - start);
}
y1 = br.bottom() - (m_keyframeDefault - m_keyframeOffset) * maxh;
QLineF l(x1, y1, x2, y1);
QLineF l2 = transformation.map(l);
painter->setPen(QColor(168, 168, 168, 180));
painter->drawLine(l2);
painter->setPen(QColor(108, 108, 108, 180));
painter->drawLine(l2.translated(0, 1));
painter->setPen(QColor(Qt::white));
painter->setRenderHint(QPainter::Antialiasing);
}
// draw keyframes
QMap<int, int>::const_iterator i = m_keyframes.constBegin();
QColor color(Qt::blue);
QLineF l2;
x1 = br.x() + maxw * (i.key() - start);
y1 = br.bottom() - (i.value() - m_keyframeOffset) * maxh;
// make sure line begins with clip beginning
if (!limitedKeyFrames && i.key() != start) {
QLineF l(br.x(), y1, x1, y1);
l2 = transformation.map(l);
painter->drawLine(l2);
}
while (i != m_keyframes.constEnd()) {
if (i.key() == m_editedKeyframe)
color = QColor(Qt::red);
else
color = QColor(Qt::blue);
++i;
if (i == m_keyframes.constEnd() && m_keyframes.count() != 1)
break;
if (m_keyframes.count() == 1) {
x2 = br.right();
y2 = y1;
} else {
x2 = br.x() + maxw * (i.key() - start);
y2 = br.bottom() - (i.value() - m_keyframeOffset) * maxh;
}
QLineF l(x1, y1, x2, y2);
l2 = transformation.map(l);
painter->drawLine(l2);
if (active) {
const QRectF frame(l2.x1() - 3, l2.y1() - 3, 6, 6);
painter->fillRect(frame, color);
}
x1 = x2;
y1 = y2;
}
// make sure line ends at clip end
if (!limitedKeyFrames && x1 != br.right()) {
QLineF l(x1, y1, br.right(), y1);
painter->drawLine(transformation.map(l));
}
if (active && m_keyframes.count() > 1) {
const QRectF frame(l2.x2() - 3, l2.y2() - 3, 6, 6);
painter->fillRect(frame, color);
}
painter->setRenderHint(QPainter::Antialiasing, antialiasing);
}
int AbstractClipItem::mouseOverKeyFrames(QPointF pos, double maxOffset)
{
const QRectF br = sceneBoundingRect();
double maxw = br.width() / cropDuration().frames(m_fps);
double maxh = br.height() / 100.0 * m_keyframeFactor;
if (m_keyframes.count() > 0) {
QMap<int, int>::const_iterator i = m_keyframes.constBegin();
double x1;
double y1;
while (i != m_keyframes.constEnd()) {
x1 = br.x() + maxw * (i.key() - cropStart().frames(m_fps));
y1 = br.bottom() - (i.value() - m_keyframeOffset) * maxh;
if (qAbs(pos.x() - x1) < maxOffset && qAbs(pos.y() - y1) < 10) {
setToolTip('[' + QString::number((GenTime(i.key(), m_fps) - cropStart()).seconds(), 'f', 2) + i18n("seconds") + ", " + QString::number(i.value(), 'f', 1) + ']');
return i.key();
} else if (x1 > pos.x()) {
break;
}
++i;
}
}
setToolTip(QString());
return -1;
}
void AbstractClipItem::updateSelectedKeyFrame()
{
if (m_editedKeyframe == -1)
return;
QRectF br = sceneBoundingRect();
double maxw = br.width() / cropDuration().frames(m_fps);
double maxh = br.height() / 100.0 * m_keyframeFactor;
update(br.x() + maxw *(m_selectedKeyframe - cropStart().frames(m_fps)) - 3, br.bottom() - (m_keyframes.value(m_selectedKeyframe) - m_keyframeOffset) * maxh - 3, 12, 12);
m_selectedKeyframe = m_editedKeyframe;
update(br.x() + maxw *(m_selectedKeyframe - cropStart().frames(m_fps)) - 3, br.bottom() - (m_keyframes.value(m_selectedKeyframe) - m_keyframeOffset) * maxh - 3, 12, 12);
}
int AbstractClipItem::editedKeyFramePos() const
{
return m_editedKeyframe;
}
double AbstractClipItem::editedKeyFrameValue() const
{
return m_keyframes.value(m_editedKeyframe);
}
int AbstractClipItem::selectedKeyFramePos() const
{
return m_selectedKeyframe;
}
double AbstractClipItem::selectedKeyFrameValue() const
{
return m_keyframes.value(m_selectedKeyframe);
}
void AbstractClipItem::updateKeyFramePos(const GenTime &pos, const double value)
{
if (!m_keyframes.contains(m_editedKeyframe))
return;
int newpos = (int) pos.frames(m_fps);
int min = (int) cropStart().frames(m_fps) - 1;
int max = (int)(cropStart() + cropDuration()).frames(m_fps);
QMap<int, int>::const_iterator i = m_keyframes.constBegin();
while (i.key() < m_editedKeyframe) {
min = qMax(i.key(), min);
++i;
}
i = m_keyframes.constEnd() - 1;
while (i.key() > m_editedKeyframe) {
max = qMin(i.key(), max);
--i;
}
if (newpos <= min)
newpos = min + 1;
if (newpos >= max)
newpos = max - 1;
double newval = qMax(value, 0.0);
newval = qMin(newval, 100.0);
newval = newval / m_keyframeFactor + m_keyframeOffset;
if (m_editedKeyframe != newpos)
m_keyframes.remove(m_editedKeyframe);
m_keyframes[newpos] = (int) newval;
m_editedKeyframe = newpos;
update();
}
double AbstractClipItem::keyFrameFactor() const
{
return m_keyframeFactor;
}
int AbstractClipItem::keyFrameNumber() const
{
return m_keyframes.count();
}
int AbstractClipItem::checkForSingleKeyframe()
{
// Check if we have only one keyframe
if (!m_keyframes.isEmpty() && m_keyframes.count() == 1) {
int min = (int) cropStart().frames(m_fps);
int max = (int)(cropStart() + cropDuration()).frames(m_fps) - 1;
if (m_keyframes.contains(min)) {
// Add keyframe at end of clip to allow inserting a new keframe in between
m_keyframes[max] = m_keyframes.value(min);
return m_keyframes.value(min);
}
}
return -1;
}
int AbstractClipItem::addKeyFrame(const GenTime &pos, const double value)
{
QRectF br = sceneBoundingRect();
double maxh = 100.0 / br.height() / m_keyframeFactor;
int newval = (br.bottom() - value) * maxh + m_keyframeOffset;
//kDebug() << "Rect: " << br << "/ SCENE: " << sceneBoundingRect() << ", VALUE: " << value << ", MAX: " << maxh << ", NEWVAL: " << newval;
int newpos = (int) pos.frames(m_fps) ;
m_keyframes[newpos] = newval;
m_selectedKeyframe = newpos;
update();
return newval;
}
bool AbstractClipItem::hasKeyFrames() const
{
return !m_keyframes.isEmpty();
}
/*QRect AbstractClipItem::visibleRect() {
QRect rectInView;
if (scene()->views().size() > 0) {
rectInView = scene()->views()[0]->viewport()->rect();
rectInView.moveTo(scene()->views()[0]->horizontalScrollBar()->value(), scene()->views()[0]->verticalScrollBar()->value());
rectInView.adjust(-10, -10, 10, 10);//make view rect 10 pixel greater on each site, or repaint after scroll event
//kDebug() << scene()->views()[0]->viewport()->rect() << " " << scene()->views()[0]->horizontalScrollBar()->value();
}
return rectInView;
}*/
CustomTrackScene* AbstractClipItem::projectScene()
{
if (scene())
return static_cast <CustomTrackScene*>(scene());
return NULL;
}
void AbstractClipItem::setItemLocked(bool locked)
{
if (locked)
setSelected(false);
setFlag(QGraphicsItem::ItemIsMovable, !locked);
setFlag(QGraphicsItem::ItemIsSelectable, !locked);
}
bool AbstractClipItem::isItemLocked() const
{
return !(flags() & (QGraphicsItem::ItemIsSelectable));
}
// virtual
void AbstractClipItem::mousePressEvent(QGraphicsSceneMouseEvent * event)
{
if (event->modifiers() & Qt::ShiftModifier) {
// User want to do a rectangle selection, so ignore the event to pass it to the view
event->ignore();
} else {
QGraphicsItem::mousePressEvent(event);
}
}
int AbstractClipItem::itemHeight()
{
return 0;
}
int AbstractClipItem::itemOffset()
{
return 0;
}
void AbstractClipItem::setMainSelectedClip(bool selected)
{
if (selected == m_isMainSelectedClip) return;
m_isMainSelectedClip = selected;
update();
}
bool AbstractClipItem::isMainSelectedClip()
{
return m_isMainSelectedClip;
}
#include "abstractclipitem.moc"

View File

@@ -1,136 +0,0 @@
/***************************************************************************
* Copyright (C) 2008 by Marco Gittler (g.marco@freenet.de) *
* Copyright (C) 2008 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#ifndef ABSTRACTCLIPITEM
#define ABSTRACTCLIPITEM
#include <QGraphicsRectItem>
#include <QGraphicsWidget>
#if QT_VERSION >= 0x040600
#include <QPropertyAnimation>
#endif
#include "definitions.h"
#include "gentime.h"
class CustomTrackScene;
class QGraphicsSceneMouseEvent;
class AbstractClipItem : public QObject, public QGraphicsRectItem
{
Q_OBJECT
Q_PROPERTY(QRectF rect READ rect WRITE setRect)
Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity)
public:
AbstractClipItem(const ItemInfo &info, const QRectF& rect, double fps);
virtual ~ AbstractClipItem();
void updateSelectedKeyFrame();
/** @brief Move the selected keyframe (does not influence the effect, only the display in timeline).
* @param pos new Position
* @param value new Value */
void updateKeyFramePos(const GenTime &pos, const double value);
int checkForSingleKeyframe();
int addKeyFrame(const GenTime &pos, const double value);
bool hasKeyFrames() const;
int editedKeyFramePos() const;
int selectedKeyFramePos() const;
double selectedKeyFrameValue() const;
double editedKeyFrameValue() const;
double keyFrameFactor() const;
/** @brief Returns the number of keyframes the selected effect has. */
int keyFrameNumber() const;
ItemInfo info() const;
CustomTrackScene* projectScene();
void updateRectGeometry();
void updateItem();
void setItemLocked(bool locked);
bool isItemLocked() const;
void closeAnimation();
virtual OPERATIONTYPE operationMode(const QPointF &pos) = 0;
virtual GenTime startPos() const ;
virtual void setTrack(int track);
virtual GenTime endPos() const ;
virtual int defaultZValue() const ;
virtual int track() const ;
virtual GenTime cropStart() const ;
virtual GenTime cropDuration() const ;
/** @brief Return the current item's height */
static int itemHeight();
/** @brief Return the current item's vertical offset
* For example transitions are drawn at 1/3 of track height */
static int itemOffset();
/** @brief Resizes the clip from the start.
* @param posx Absolute position of new in point
* @param hasSizeLimit (optional) Whether the clip has a maximum size */
virtual void resizeStart(int posx, bool hasSizeLimit = true, bool emitChange = true);
/** @brief Resizes the clip from the end.
* @param posx Absolute position of new out point */
virtual void resizeEnd(int posx, bool emitChange = true);
virtual double fps() const;
virtual void updateFps(double fps);
virtual GenTime maxDuration() const;
virtual void setCropStart(const GenTime &pos);
/** @brief Set this clip as the main selected clip (or not). */
void setMainSelectedClip(bool selected);
/** @brief Is this clip selected as the main clip. */
bool isMainSelectedClip();
protected:
ItemInfo m_info;
/** The position of the current keyframe when it has moved */
int m_editedKeyframe;
/** The position of the current keyframe before it was moved */
int m_selectedKeyframe;
/* GenTime m_cropStart;
GenTime m_cropDuration;
GenTime m_startPos;*/
GenTime m_maxDuration;
QMap <int, int> m_keyframes;
/** @brief Strech factor so that keyframes display on the full clip height. */
double m_keyframeFactor;
/** @brief Offset factor so that keyframes minimum value are displaed at the bottom of the clip. */
double m_keyframeOffset;
/** @brief Default reset value for keyframe. */
double m_keyframeDefault;
/** The (keyframe) parameter that is visible and editable in timeline (on the clip) */
int m_visibleParam;
double m_fps;
/** @brief True if this is the last clip the user selected */
bool m_isMainSelectedClip;
/** @brief Draw the keyframes of a clip
* @param painter The painter device for the clip
* @param limitedKeyFrames The keyframes can be of type "keyframe" or "simplekeyframe". In the
* "simplekeyframe" type, the effect always starts on clip start and ends on clip end. With the
* "keyframe" type, the effect starts on the first keyframe and ends on the last keyframe
*/
void drawKeyFrames(QPainter *painter, const QTransform &transformation, bool limitedKeyFrames);
int mouseOverKeyFrames(QPointF pos, double maxOffset);
void mousePressEvent(QGraphicsSceneMouseEvent * event);
};
#endif

View File

@@ -1,558 +0,0 @@
/***************************************************************************
* Copyright (C) 2008 by Marco Gittler (g.marco@freenet.de) *
* Copyright (C) 2008 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#include "abstractgroupitem.h"
#include "abstractclipitem.h"
#include "kdenlivesettings.h"
#include "customtrackscene.h"
#include "customtrackview.h"
#include <KDebug>
#include <QPainter>
#include <QStyleOptionGraphicsItem>
#include <QDomDocument>
#include <QMimeData>
#include <QGraphicsSceneMouseEvent>
AbstractGroupItem::AbstractGroupItem(double /* fps */) :
QObject(),
QGraphicsItemGroup()
{
setZValue(1);
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
#if QT_VERSION >= 0x040600
setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
#endif
setAcceptDrops(true);
m_resizeInfos = QList <ItemInfo>();
}
int AbstractGroupItem::type() const
{
return GROUPWIDGET;
}
int AbstractGroupItem::track() const
{
//return (int)(scenePos().y() / KdenliveSettings::trackheight());
int topTrack = -1;
QList<QGraphicsItem *> children = childItems();
for (int i = 0; i < children.count(); ++i) {
if (children.at(i)->type() == GROUPWIDGET) {
children.append(children.at(i)->childItems());
continue;
}
AbstractClipItem *item = static_cast <AbstractClipItem *>(children.at(i));
if (item && (topTrack == -1 || topTrack > item->track())) {
topTrack = item->track();
}
}
return topTrack;
}
void AbstractGroupItem::setItemLocked(bool locked)
{
if (locked)
setSelected(false);
setFlag(QGraphicsItem::ItemIsMovable, !locked);
setFlag(QGraphicsItem::ItemIsSelectable, !locked);
foreach (QGraphicsItem *child, childItems())
((AbstractClipItem *)child)->setItemLocked(locked);
}
bool AbstractGroupItem::isItemLocked() const
{
return !(flags() & (QGraphicsItem::ItemIsSelectable));
}
CustomTrackScene* AbstractGroupItem::projectScene()
{
if (scene()) return static_cast <CustomTrackScene*>(scene());
return NULL;
}
QPainterPath AbstractGroupItem::clipGroupSpacerShape(const QPointF &offset) const
{
return spacerGroupShape(AVWIDGET, offset);
}
QPainterPath AbstractGroupItem::clipGroupShape(const QPointF &offset) const
{
return groupShape(AVWIDGET, offset);
}
QPainterPath AbstractGroupItem::transitionGroupShape(const QPointF &offset) const
{
return groupShape(TRANSITIONWIDGET, offset);
}
QPainterPath AbstractGroupItem::groupShape(GRAPHICSRECTITEM type, const QPointF &offset) const
{
QPainterPath path;
QList<QGraphicsItem *> children = childItems();
for (int i = 0; i < children.count(); ++i) {
if (children.at(i)->type() == (int)type) {
QRectF r(children.at(i)->sceneBoundingRect());
r.translate(offset);
path.addRect(r);
} else if (children.at(i)->type() == GROUPWIDGET) {
QList<QGraphicsItem *> subchildren = children.at(i)->childItems();
for (int j = 0; j < subchildren.count(); j++) {
if (subchildren.at(j)->type() == (int)type) {
QRectF r(subchildren.at(j)->sceneBoundingRect());
r.translate(offset);
path.addRect(r);
}
}
}
}
return path;
}
QPainterPath AbstractGroupItem::spacerGroupShape(GRAPHICSRECTITEM type, const QPointF &offset) const
{
QPainterPath path;
QList<QGraphicsItem *> children = childItems();
for (int i = 0; i < children.count(); ++i) {
if (children.at(i)->type() == (int)type) {
QRectF r(children.at(i)->sceneBoundingRect());
r.translate(offset);
r.setRight(scene()->width());
path.addRect(r);
} else if (children.at(i)->type() == GROUPWIDGET) {
QList<QGraphicsItem *> subchildren = children.at(i)->childItems();
for (int j = 0; j < subchildren.count(); j++) {
if (subchildren.at(j)->type() == (int)type) {
QRectF r(subchildren.at(j)->sceneBoundingRect());
r.translate(offset);
r.setRight(scene()->width());
path.addRect(r);
}
}
}
}
return path;
}
void AbstractGroupItem::addItem(QGraphicsItem * item)
{
addToGroup(item);
item->setFlag(QGraphicsItem::ItemIsMovable, false);
}
void AbstractGroupItem::removeItem(QGraphicsItem * item)
{
removeFromGroup(item);
}
void AbstractGroupItem::fixItemRect()
{
QPointF start = boundingRect().topLeft();
if (start != QPointF(0, 0)) {
translate(0 - start.x(), 0 - start.y());
setPos(start);
}
}
/*ItemInfo AbstractGroupItem::info() const {
ItemInfo itemInfo;
itemInfo.startPos = m_startPos;
itemInfo.track = m_track;
return itemInfo;
}*/
// virtual
void AbstractGroupItem::paint(QPainter *p, const QStyleOptionGraphicsItem *option, QWidget *)
{
QColor bgcolor(100, 100, 200, 100);
QRectF bound = option->exposedRect.adjusted(0, 0, 1, 1);
p->setClipRect(bound);
p->setBrush(bgcolor);
QPen pen = p->pen();
pen.setColor(QColor(200, 90, 90));
pen.setStyle(Qt::DashLine);
pen.setWidthF(0.0);
p->setPen(pen);
p->drawRoundedRect(boundingRect().adjusted(0, 0, -1, 0), 3, 3);
}
//virtual
QVariant AbstractGroupItem::itemChange(GraphicsItemChange change, const QVariant &value)
{
if (change == QGraphicsItem::ItemSelectedChange) {
if (value.toBool()) setZValue(10);
else setZValue(1);
}
if (change == ItemPositionChange && scene() && parentItem() == 0) {
// calculate new position.
const int trackHeight = KdenliveSettings::trackheight();
QPointF start = sceneBoundingRect().topLeft();
QPointF newPos = value.toPointF();
int xpos = projectScene()->getSnapPointForPos((int)(start.x() + newPos.x() - pos().x()), KdenliveSettings::snaptopoints());
xpos = qMax(xpos, 0);
//kDebug()<<"GRP XPOS:"<<xpos<<", START:"<<start.x()<<",NEW:"<<newPos.x()<<"; SCENE:"<<scenePos().x()<<",POS:"<<pos().x();
newPos.setX((int)(pos().x() + xpos - (int) start.x()));
QStringList lockedTracks = property("locked_tracks").toStringList();
int proposedTrack = (property("y_absolute").toInt() + newPos.y()) / trackHeight;
// Check if top item is a clip or a transition
int offset = 0;
int topTrack = -1;
QList<int> groupTracks;
QList<QGraphicsItem *> children = childItems();
for (int i = 0; i < children.count(); ++i) {
int currentTrack = 0;
if (children.at(i)->type() == AVWIDGET || children.at(i)->type() == TRANSITIONWIDGET) {
currentTrack = static_cast <AbstractClipItem*> (children.at(i))->track();
if (!groupTracks.contains(currentTrack)) groupTracks.append(currentTrack);
}
else if (children.at(i)->type() == GROUPWIDGET) {
currentTrack = static_cast <AbstractGroupItem*> (children.at(i))->track();
}
else continue;
if (children.at(i)->type() == AVWIDGET) {
if (topTrack == -1 || currentTrack <= topTrack) {
offset = 0;
topTrack = currentTrack;
}
} else if (children.at(i)->type() == TRANSITIONWIDGET) {
if (topTrack == -1 || currentTrack < topTrack) {
offset = (int)(trackHeight / 3 * 2 - 1);
topTrack = currentTrack;
}
} else if (children.at(i)->type() == GROUPWIDGET) {
QList<QGraphicsItem *> subchildren = children.at(i)->childItems();
bool clipGroup = false;
for (int j = 0; j < subchildren.count(); j++) {
if (subchildren.at(j)->type() == AVWIDGET || subchildren.at(j)->type() == TRANSITIONWIDGET) {
int subTrack = static_cast <AbstractClipItem*> (subchildren.at(j))->track();
if (!groupTracks.contains(subTrack)) groupTracks.append(subTrack);
clipGroup = true;
}
}
if (clipGroup) {
if (topTrack == -1 || currentTrack <= topTrack) {
offset = 0;
topTrack = currentTrack;
}
} else {
if (topTrack == -1 || currentTrack < topTrack) {
offset = (int)(trackHeight / 3 * 2 - 1);
topTrack = currentTrack;
}
}
}
}
// Check no clip in the group goes outside of existing tracks
int maximumTrack = projectScene()->tracksCount() - 1;
int groupHeight = 0;
for (int i = 0; i < groupTracks.count(); ++i) {
int offset = groupTracks.at(i) - topTrack;
if (offset > groupHeight) groupHeight = offset;
}
maximumTrack -= groupHeight;
proposedTrack = qMin(proposedTrack, maximumTrack);
proposedTrack = qMax(proposedTrack, 0);
int groupOffset = proposedTrack - topTrack;
if (!lockedTracks.isEmpty()) {
for (int i = 0; i < groupTracks.count(); ++i) {
if (lockedTracks.contains(QString::number(groupTracks.at(i) + groupOffset))) {
return pos();
}
}
}
newPos.setY((int)((proposedTrack) * trackHeight) + offset);
//if (newPos == start) return start;
/*if (newPos.x() < 0) {
// If group goes below 0, adjust position to 0
return QPointF(pos().x() - start.x(), pos().y());
}*/
QList<QGraphicsItem*> collidingItems;
QPainterPath shape;
if (projectScene()->editMode() == NORMALEDIT) {
shape = clipGroupShape(newPos - pos());
collidingItems = scene()->items(shape, Qt::IntersectsItemShape);
collidingItems.removeAll(this);
for (int i = 0; i < children.count(); ++i) {
if (children.at(i)->type() == GROUPWIDGET) {
QList<QGraphicsItem *> subchildren = children.at(i)->childItems();
for (int j = 0; j < subchildren.count(); j++) {
collidingItems.removeAll(subchildren.at(j));
}
}
collidingItems.removeAll(children.at(i));
}
}
if (!collidingItems.isEmpty()) {
bool forwardMove = xpos > start.x();
int offset = 0;
for (int i = 0; i < collidingItems.count(); ++i) {
QGraphicsItem *collision = collidingItems.at(i);
if (collision->type() == AVWIDGET) {
// Collision
if (newPos.y() != pos().y()) {
// Track change results in collision, restore original position
return pos();
}
AbstractClipItem *item = static_cast <AbstractClipItem *>(collision);
if (forwardMove) {
// Moving forward, determine best pos
QPainterPath clipPath;
clipPath.addRect(item->sceneBoundingRect());
QPainterPath res = shape.intersected(clipPath);
offset = qMax(offset, (int)(res.boundingRect().width() + 0.5));
} else {
// Moving backward, determine best pos
QPainterPath clipPath;
clipPath.addRect(item->sceneBoundingRect());
QPainterPath res = shape.intersected(clipPath);
offset = qMax(offset, (int)(res.boundingRect().width() + 0.5));
}
}
}
if (offset > 0) {
if (forwardMove) {
newPos.setX(newPos.x() - offset);
} else {
newPos.setX(newPos.x() + offset);
}
// If there is still a collision after our position adjust, restore original pos
collidingItems = scene()->items(clipGroupShape(newPos - pos()), Qt::IntersectsItemShape);
collidingItems.removeAll(this);
for (int i = 0; i < children.count(); ++i) {
if (children.at(i)->type() == GROUPWIDGET) {
QList<QGraphicsItem *> subchildren = children.at(i)->childItems();
for (int j = 0; j < subchildren.count(); j++) {
collidingItems.removeAll(subchildren.at(j));
}
}
collidingItems.removeAll(children.at(i));
}
for (int i = 0; i < collidingItems.count(); ++i)
if (collidingItems.at(i)->type() == AVWIDGET) return pos();
}
}
if (projectScene()->editMode() == NORMALEDIT) {
shape = transitionGroupShape(newPos - pos());
collidingItems = scene()->items(shape, Qt::IntersectsItemShape);
collidingItems.removeAll(this);
for (int i = 0; i < children.count(); ++i) {
if (children.at(i)->type() == GROUPWIDGET) {
QList<QGraphicsItem *> subchildren = children.at(i)->childItems();
for (int j = 0; j < subchildren.count(); j++) {
collidingItems.removeAll(subchildren.at(j));
}
}
collidingItems.removeAll(children.at(i));
}
}
if (collidingItems.isEmpty()) return newPos;
else {
bool forwardMove = xpos > start.x();
int offset = 0;
for (int i = 0; i < collidingItems.count(); ++i) {
QGraphicsItem *collision = collidingItems.at(i);
if (collision->type() == TRANSITIONWIDGET) {
// Collision
if (newPos.y() != pos().y()) {
// Track change results in collision, restore original position
return pos();
}
AbstractClipItem *item = static_cast <AbstractClipItem *>(collision);
if (forwardMove) {
// Moving forward, determine best pos
QPainterPath clipPath;
clipPath.addRect(item->sceneBoundingRect());
QPainterPath res = shape.intersected(clipPath);
offset = qMax(offset, (int)(res.boundingRect().width() + 0.5));
} else {
// Moving backward, determine best pos
QPainterPath clipPath;
clipPath.addRect(item->sceneBoundingRect());
QPainterPath res = shape.intersected(clipPath);
offset = qMax(offset, (int)(res.boundingRect().width() + 0.5));
}
}
}
if (offset > 0) {
if (forwardMove) {
newPos.setX(newPos.x() - offset);
} else {
newPos.setX(newPos.x() + offset);
}
// If there is still a collision after our position adjust, restore original pos
collidingItems = scene()->items(transitionGroupShape(newPos - pos()), Qt::IntersectsItemShape);
for (int i = 0; i < children.count(); ++i) {
collidingItems.removeAll(children.at(i));
}
for (int i = 0; i < collidingItems.count(); ++i)
if (collidingItems.at(i)->type() == TRANSITIONWIDGET) return pos();
}
}
return newPos;
}
return QGraphicsItemGroup::itemChange(change, value);
}
//virtual
void AbstractGroupItem::dropEvent(QGraphicsSceneDragDropEvent * event)
{
QString effects = QString::fromUtf8(event->mimeData()->data("kdenlive/effectslist"));
QDomDocument doc;
doc.setContent(effects, true);
QDomElement e = doc.documentElement();
e.setAttribute("kdenlive_ix", 0);
CustomTrackView *view = (CustomTrackView *) scene()->views()[0];
QPointF dropPos = event->scenePos();
QList<QGraphicsItem *> selection = scene()->items(dropPos);
AbstractClipItem *dropChild = NULL;
for (int i = 0; i < selection.count(); ++i) {
if (selection.at(i)->type() == AVWIDGET) {
dropChild = (AbstractClipItem *) selection.at(i);
break;
}
}
if (view) view->slotAddGroupEffect(e, this, dropChild);
}
//virtual
void AbstractGroupItem::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
{
event->setAccepted(event->mimeData()->hasFormat("kdenlive/effectslist"));
}
void AbstractGroupItem::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
{
Q_UNUSED(event)
}
// virtual
void AbstractGroupItem::mousePressEvent(QGraphicsSceneMouseEvent * event)
{
if (event->modifiers() & Qt::ShiftModifier) {
// User want to do a rectangle selection, so ignore the event to pass it to the view
event->ignore();
} else {
QList <QGraphicsItem *>list = scene()->items(event->scenePos());
// only allow group move if we click over an item in the group
foreach(const QGraphicsItem *item, list) {
if (item->type() == TRANSITIONWIDGET || item->type() == AVWIDGET) {
QGraphicsItem::mousePressEvent(event);
return;
}
}
event->ignore();
}
}
void AbstractGroupItem::resizeStart(int diff)
{
bool info = false;
if (m_resizeInfos.isEmpty())
info = true;
int maximum = diff;
QList <QGraphicsItem *> children = childItems();
QList <AbstractClipItem *> items;
int itemcount = 0;
for (int i = 0; i < children.count(); ++i) {
AbstractClipItem *item = static_cast <AbstractClipItem *>(children.at(i));
if (item && item->type() == AVWIDGET) {
items << item;
if (info)
m_resizeInfos << item->info();
item->resizeStart((int)(m_resizeInfos.at(itemcount).startPos.frames(item->fps())) + diff);
int itemdiff = (int)(item->startPos() - m_resizeInfos.at(itemcount).startPos).frames(item->fps());
if (qAbs(itemdiff) < qAbs(maximum))
maximum = itemdiff;
++itemcount;
}
}
for (int i = 0; i < items.count(); ++i)
items.at(i)->resizeStart((int)(m_resizeInfos.at(i).startPos.frames(items.at(i)->fps())) + maximum);
}
void AbstractGroupItem::resizeEnd(int diff)
{
bool info = false;
if (m_resizeInfos.isEmpty())
info = true;
int maximum = diff;
QList <QGraphicsItem *> children = childItems();
QList <AbstractClipItem *> items;
int itemcount = 0;
for (int i = 0; i < children.count(); ++i) {
AbstractClipItem *item = static_cast <AbstractClipItem *>(children.at(i));
if (item && item->type() == AVWIDGET) {
items << item;
if (info)
m_resizeInfos << item->info();
item->resizeEnd((int)(m_resizeInfos.at(itemcount).endPos.frames(item->fps())) + diff);
int itemdiff = (int)(item->endPos() - m_resizeInfos.at(itemcount).endPos).frames(item->fps());
if (qAbs(itemdiff) < qAbs(maximum))
maximum = itemdiff;
++itemcount;
}
}
for (int i = 0; i < items.count(); ++i)
items.at(i)->resizeEnd((int)(m_resizeInfos.at(i).endPos.frames(items.at(i)->fps())) + maximum);
}
QList< ItemInfo > AbstractGroupItem::resizeInfos()
{
return m_resizeInfos;
}
void AbstractGroupItem::clearResizeInfos()
{
// m_resizeInfos.clear() will crash in some cases for unknown reasons - ttill
m_resizeInfos = QList <ItemInfo>();
}
GenTime AbstractGroupItem::duration()
{
QList <QGraphicsItem *> children = childItems();
GenTime start = GenTime(-1.0);
GenTime end = GenTime();
for (int i = 0; i < children.count(); ++i) {
if (children.at(i)->type() != GROUPWIDGET) {
AbstractClipItem *item = static_cast <AbstractClipItem *>(children.at(i));
if (item) {
if (start < GenTime() || item->startPos() < start)
start = item->startPos();
if (item->endPos() > end)
end = item->endPos();
}
} else {
children << children.at(i)->childItems();
}
}
return end - start;
}
#include "abstractgroupitem.moc"

View File

@@ -1,80 +0,0 @@
/***************************************************************************
* Copyright (C) 2008 by Marco Gittler (g.marco@freenet.de) *
* Copyright (C) 2008 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#ifndef ABSTRACTGROUPITEM
#define ABSTRACTGROUPITEM
#include "definitions.h"
#include "gentime.h"
#include <QGraphicsItemGroup>
#include <QGraphicsSceneMouseEvent>
class CustomTrackScene;
class QGraphicsSceneMouseEvent;
class AbstractGroupItem : public QObject , public QGraphicsItemGroup
{
Q_OBJECT
public:
AbstractGroupItem(double fps);
virtual int type() const;
CustomTrackScene* projectScene();
void addItem(QGraphicsItem * item);
void removeItem(QGraphicsItem * item);
int track() const;
QPainterPath clipGroupShape(const QPointF &offset) const;
QPainterPath clipGroupSpacerShape(const QPointF &offset) const;
QPainterPath transitionGroupShape(const QPointF &offset) const;
void setItemLocked(bool locked);
bool isItemLocked() const;
// ItemInfo info() const;
/** @brief Resizes all clips in this group from start.
*@param diff Difference to startPos stored in m_resizeInfos */
void resizeStart(int diff);
/** @brief Resizes all clips in this group from end.
* @param diff Difference to endPos stored in m_resizeInfos */
void resizeEnd(int diff);
/** @brief Gets m_resizeInfos */
QList <ItemInfo> resizeInfos();
/** @brief Clears m_resizeInfos */
void clearResizeInfos();
/** @brief Gets the duration (length) of the group. */
GenTime duration();
protected:
virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
virtual void dragEnterEvent(QGraphicsSceneDragDropEvent *event);
virtual void dragLeaveEvent(QGraphicsSceneDragDropEvent *event);
virtual void dropEvent(QGraphicsSceneDragDropEvent *event);
virtual void mousePressEvent(QGraphicsSceneMouseEvent * event);
private:
void fixItemRect();
QPainterPath groupShape(GRAPHICSRECTITEM type, const QPointF &offset) const;
QPainterPath spacerGroupShape(GRAPHICSRECTITEM type, const QPointF &offset) const;
/** Stores the original info of the items beeing resized. */
QList <ItemInfo> m_resizeInfos;
};
#endif

View File

@@ -1,183 +0,0 @@
/***************************************************************************
* Copyright (C) 2011 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#include "abstractmonitor.h"
#include "kdenlivesettings.h"
#include "monitormanager.h"
#include <KDebug>
#include <QPaintEvent>
#include <QDesktopWidget>
#include <QVBoxLayout>
AbstractMonitor::AbstractMonitor(Kdenlive::MONITORID id, MonitorManager *manager, QWidget *parent):
QWidget(parent),
videoSurface(NULL),
m_id(id),
m_monitorManager(manager)
{
videoBox = new VideoContainer(this);
}
AbstractMonitor::~AbstractMonitor()
{
delete videoSurface;
}
void AbstractMonitor::createVideoSurface()
{
QVBoxLayout *lay = new QVBoxLayout;
lay->setContentsMargins(0, 0, 0, 0);
videoSurface = new VideoSurface;
lay->addWidget(videoSurface);
videoBox->setLayout(lay);
}
bool AbstractMonitor::isActive() const
{
return m_monitorManager->isActive(m_id);
}
bool AbstractMonitor::slotActivateMonitor(bool forceRefresh)
{
return m_monitorManager->activateMonitor(m_id, forceRefresh);
}
VideoContainer::VideoContainer(AbstractMonitor* monitor, QWidget *parent) :
QFrame(parent)
, m_monitor(monitor)
{
setFrameShape(QFrame::NoFrame);
setFocusPolicy(Qt::ClickFocus);
//setEnabled(false);
setContentsMargins(0, 0, 0, 0);
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
}
// virtual
void VideoContainer::mouseReleaseEvent(QMouseEvent * event)
{
if (event->button() != Qt::RightButton) {
if (m_monitor->isActive()) {
m_monitor->slotPlay();
}
}
}
// virtual
void VideoContainer::keyPressEvent(QKeyEvent *event)
{
// Exit fullscreen with Esc key
if (event->key() == Qt::Key_Escape && isFullScreen()) {
switchFullScreen();
event->setAccepted(true);
} else event->setAccepted(false);
}
// virtual
void VideoContainer::wheelEvent(QWheelEvent * event)
{
m_monitor->slotMouseSeek(event->delta(), event->modifiers() == Qt::ControlModifier);
event->accept();
}
void VideoContainer::mouseDoubleClickEvent(QMouseEvent * event)
{
if (!KdenliveSettings::openglmonitors())
switchFullScreen();
event->accept();
}
void VideoContainer::switchFullScreen()
{
// TODO: disable screensaver?
Qt::WindowFlags flags = windowFlags();
if (!isFullScreen()) {
// Check if we ahave a multiple monitor setup
setUpdatesEnabled(false);
#if QT_VERSION >= 0x040600
int monitors = QApplication::desktop()->screenCount();
#else
int monitors = QApplication::desktop()->numScreens();
#endif
if (monitors > 1) {
QRect screenres;
// Move monitor widget to the second screen (one screen for Kdenlive, the other one for the Monitor widget
int currentScreen = QApplication::desktop()->screenNumber(this);
if (currentScreen < monitors - 1)
screenres = QApplication::desktop()->screenGeometry(currentScreen + 1);
else
screenres = QApplication::desktop()->screenGeometry(currentScreen - 1);
move(QPoint(screenres.x(), screenres.y()));
resize(screenres.width(), screenres.height());
}
m_baseFlags = flags & (Qt::Window | Qt::SubWindow);
flags |= Qt::Window;
flags ^= Qt::SubWindow;
setWindowFlags(flags);
#ifdef Q_WS_X11
// This works around a bug with Compiz
// as the window must be visible before we can set the state
show();
raise();
setWindowState(windowState() | Qt::WindowFullScreen); // set
#else
setWindowState(windowState() | Qt::WindowFullScreen); // set
setUpdatesEnabled(true);
show();
#endif
setEnabled(true);
} else {
setUpdatesEnabled(false);
flags ^= (Qt::Window | Qt::SubWindow); //clear the flags...
flags |= m_baseFlags; //then we reset the flags (window and subwindow)
setWindowFlags(flags);
setWindowState(windowState() ^ Qt::WindowFullScreen); // reset
setUpdatesEnabled(true);
setEnabled(false);
show();
}
}
VideoSurface::VideoSurface(QWidget* parent) :
QWidget(parent)
{
// MonitorRefresh is used as container for the SDL display (it's window id is passed to SDL)
setAttribute(Qt::WA_PaintOnScreen);
setAttribute(Qt::WA_OpaquePaintEvent);
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
setAttribute(Qt::WA_NoSystemBackground);
//setUpdatesEnabled(false);
}
void VideoSurface::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
//WARNING: This might trigger unnecessary refreshes from MLT's producer, but without this,
// as soon as monitor is covered by a popup menu or another window, image is corrupted.
emit refreshMonitor();
}
#include "abstractmonitor.moc"

View File

@@ -1,138 +0,0 @@
/***************************************************************************
* Copyright (C) 2011 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#ifndef ABSTRACTMONITOR_H
#define ABSTRACTMONITOR_H
#include "definitions.h"
#include <QObject>
#include <QVector>
#include <QWidget>
#include <QImage>
#include <QFrame>
#include <stdint.h>
class MonitorManager;
class VideoContainer;
class AbstractRender: public QObject
{
Q_OBJECT public:
/** @brief Build an abstract MLT Renderer
* @param name A unique identifier for this renderer
* @param winid The parent widget identifier (required for SDL display). Set to 0 for OpenGL rendering
* @param profile The MLT profile used for the renderer (default one will be used if empty). */
explicit AbstractRender(Kdenlive::MONITORID name, QWidget *parent = 0)
: QObject(parent),
sendFrameForAnalysis(false),
analyseAudio(false),
m_name(name)
{
}
/** @brief Destroy the MLT Renderer. */
virtual ~AbstractRender() {}
/** @brief This property is used to decide if the renderer should convert it's frames to QImage for use in other Kdenlive widgets. */
bool sendFrameForAnalysis;
/** @brief This property is used to decide if the renderer should send audio data for monitoring. */
bool analyseAudio;
const QString &name() const {return m_name;}
/** @brief Someone needs us to send again a frame. */
virtual void sendFrameUpdate() = 0;
private:
QString m_name;
signals:
/** @brief The renderer refreshed the current frame. */
void frameUpdated(const QImage &);
/** @brief This signal contains the audio of the current frame. */
void audioSamplesSignal(const QVector<int16_t>&,int,int,int);
};
class VideoSurface : public QWidget
{
Q_OBJECT
public:
VideoSurface(QWidget *parent = 0);
signals:
void refreshMonitor();
protected:
virtual void paintEvent ( QPaintEvent * event );
};
class AbstractMonitor : public QWidget
{
Q_OBJECT
public:
AbstractMonitor(Kdenlive::MONITORID id, MonitorManager *manager, QWidget *parent = 0);
Kdenlive::MONITORID id() {return m_id;}
virtual ~AbstractMonitor();
virtual AbstractRender *abstractRender() = 0;
bool isActive() const;
VideoContainer *videoBox;
VideoSurface *videoSurface;
void createVideoSurface();
public slots:
virtual void stop() = 0;
virtual void start() = 0;
virtual void slotPlay() = 0;
virtual void slotMouseSeek(int eventDelta, bool fast) = 0;
bool slotActivateMonitor(bool forceRefresh = false);
virtual void slotSwitchFullScreen() = 0;
protected:
Kdenlive::MONITORID m_id;
MonitorManager *m_monitorManager;
};
class VideoContainer : public QFrame
{
Q_OBJECT
public:
explicit VideoContainer(AbstractMonitor *monitor, QWidget *parent = 0);
void switchFullScreen();
protected:
virtual void mouseDoubleClickEvent(QMouseEvent * event);
virtual void mouseReleaseEvent(QMouseEvent *event);
void keyPressEvent(QKeyEvent *event);
virtual void wheelEvent(QWheelEvent * event);
private:
Qt::WindowFlags m_baseFlags;
AbstractMonitor *m_monitor;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,125 +0,0 @@
/***************************************************************************
* Copyright (C) 2011 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#ifndef ARCHIVEWIDGET_H
#define ARCHIVEWIDGET_H
#include "ui_archivewidget_ui.h"
#include "docclipbase.h"
#include <kio/global.h>
#include <KIO/CopyJob>
#include <KTemporaryFile>
#include <kdeversion.h>
#include <QLabel>
#include <QDialog>
#include <QList>
class KJob;
class KArchive;
/**
* @class ArchiveWidget
* @brief A widget allowing to archive a project (copy all project files to a new location)
* @author Jean-Baptiste Mardelle
*/
#if KDE_IS_VERSION(4,7,0)
class KMessageWidget;
#endif
class ArchiveWidget : public QDialog, public Ui::ArchiveWidget_UI
{
Q_OBJECT
public:
ArchiveWidget(const QString &projectName, const QDomDocument &doc, const QList <DocClipBase*> &list, const QStringList &luma_list, QWidget * parent = 0);
// Constructor for extracting widget
explicit ArchiveWidget(const KUrl &url, QWidget * parent = 0);
~ArchiveWidget();
QString extractedProjectFile() const;
private slots:
void slotCheckSpace();
bool slotStartArchiving(bool firstPass = true);
void slotArchivingFinished(KJob *job = NULL, bool finished = false);
void slotArchivingProgress(KJob *, qulonglong);
virtual void done ( int r );
bool closeAccepted();
void createArchive();
void slotArchivingProgress(int);
void slotArchivingFinished(bool result);
void slotStartExtracting();
void doExtracting();
void slotExtractingFinished();
void slotExtractProgress();
void slotGotProgress(KJob*);
void openArchiveForExtraction();
void slotDisplayMessage(const QString &icon, const QString &text);
void slotJobResult(bool success, const QString &text);
void slotProxyOnly(int onlyProxy);
protected:
virtual void closeEvent ( QCloseEvent * e );
private:
KIO::filesize_t m_requestedSize;
KIO::CopyJob *m_copyJob;
QMap <KUrl, KUrl> m_duplicateFiles;
QMap <KUrl, KUrl> m_replacementList;
QString m_name;
QDomDocument m_doc;
KTemporaryFile *m_temp;
bool m_abortArchive;
QFuture<void> m_archiveThread;
QStringList m_foldersList;
QMap <QString, QString> m_filesList;
bool m_extractMode;
KUrl m_extractUrl;
QString m_projectName;
QTimer *m_progressTimer;
KArchive *m_extractArchive;
int m_missingClips;
#if KDE_IS_VERSION(4,7,0)
KMessageWidget *m_infoMessage;
#endif
/** @brief Generate tree widget subitems from a string list of urls. */
void generateItems(QTreeWidgetItem *parentItem, const QStringList &items);
/** @brief Generate tree widget subitems from a map of clip ids / urls. */
void generateItems(QTreeWidgetItem *parentItem, const QMap<QString, QString> &items);
/** @brief Replace urls in project file. */
bool processProjectFile();
signals:
void archivingFinished(bool);
void archiveProgress(int);
void extractingFinished();
void showMessage(const QString &, const QString &);
};
#endif

View File

@@ -1,7 +0,0 @@
set(kdenlive_SRCS
${kdenlive_SRCS}
audioscopes/abstractaudioscopewidget.cpp
audioscopes/audiospectrum.cpp
audioscopes/spectrogram.cpp
PARENT_SCOPE
)

View File

@@ -1,8 +0,0 @@
set(kdenlive_SRCS
${kdenlive_SRCS}
beziercurve/beziersplineeditor.cpp
beziercurve/beziersplinewidget.cpp
beziercurve/bpoint.cpp
beziercurve/cubicbezierspline.cpp
PARENT_SCOPE
)

View File

@@ -1,499 +0,0 @@
/***************************************************************************
* Copyright (C) 2010 by Till Theato (root@ttill.de) *
* This file is part of Kdenlive (www.kdenlive.org). *
* *
* Kdenlive is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 2 of the License, or *
* (at your option) any later version. *
* *
* Kdenlive is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with Kdenlive. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#include "beziersplineeditor.h"
#include "kdenlivesettings.h"
#include <QPainter>
#include <QMouseEvent>
BezierSplineEditor::BezierSplineEditor(QWidget* parent) :
QWidget(parent)
, m_mode(ModeNormal)
, m_zoomLevel(0)
, m_gridLines(3)
, m_showAllHandles(true)
, m_pixmapCache(NULL)
, m_pixmapIsDirty(true)
, m_currentPointIndex(-1)
, m_currentPointType(PTypeP)
, m_grabOffsetX(0)
, m_grabOffsetY(0)
{
setMouseTracking(true);
setAutoFillBackground(false);
setAttribute(Qt::WA_OpaquePaintEvent);
setMinimumSize(150, 150);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
}
BezierSplineEditor::~BezierSplineEditor()
{
delete m_pixmapCache;
}
CubicBezierSpline BezierSplineEditor::spline() const
{
return m_spline;
}
void BezierSplineEditor::setSpline(const CubicBezierSpline& spline)
{
m_spline = spline;
m_currentPointIndex = -1;
m_mode = ModeNormal;
emit currentPoint(BPoint());
emit modified();
update();
}
BPoint BezierSplineEditor::getCurrentPoint()
{
if (m_currentPointIndex >= 0)
return m_spline.getPoint(m_currentPointIndex);
else
return BPoint();
}
void BezierSplineEditor::updateCurrentPoint(const BPoint& p, bool final)
{
if (m_currentPointIndex >= 0) {
m_spline.setPoint(m_currentPointIndex, p);
// during validation the point might have changed
emit currentPoint(m_spline.getPoint(m_currentPointIndex));
if (final)
emit modified();
update();
}
}
void BezierSplineEditor::setPixmap(const QPixmap& pixmap)
{
m_pixmap = pixmap;
m_pixmapIsDirty = true;
update();
}
void BezierSplineEditor::slotZoomIn()
{
m_zoomLevel = qMax(m_zoomLevel-1, 0);
m_pixmapIsDirty = true;
update();
}
void BezierSplineEditor::slotZoomOut()
{
m_zoomLevel = qMin(m_zoomLevel+1, 3);
m_pixmapIsDirty = true;
update();
}
void BezierSplineEditor::setShowAllHandles(bool show)
{
if (m_showAllHandles != show) {
m_showAllHandles = show;
update();
}
}
int BezierSplineEditor::gridLines() const
{
return m_gridLines;
}
void BezierSplineEditor::setGridLines(int lines)
{
m_gridLines = qBound(0, lines, 8);
update();
}
void BezierSplineEditor::paintEvent(QPaintEvent* event)
{
Q_UNUSED(event)
QPainter p(this);
/*
* Zoom
*/
int wWidth = width() - 1;
int wHeight = height() - 1;
int offsetX = 1/8. * m_zoomLevel * wWidth;
int offsetY = 1/8. * m_zoomLevel * wHeight;
wWidth -= 2 * offsetX;
wHeight -= 2 * offsetY;
p.translate(offsetX, offsetY);
/*
* Background
*/
p.fillRect(rect().translated(-offsetX, -offsetY), palette().background());
if (!m_pixmap.isNull()) {
if (m_pixmapIsDirty || !m_pixmapCache) {
if (m_pixmapCache)
delete m_pixmapCache;
m_pixmapCache = new QPixmap(wWidth + 1, wHeight + 1);
QPainter cachePainter(m_pixmapCache);
cachePainter.scale(1.0*(wWidth+1) / m_pixmap.width(), 1.0*(wHeight+1) / m_pixmap.height());
cachePainter.drawPixmap(0, 0, m_pixmap);
m_pixmapIsDirty = false;
}
p.drawPixmap(0, 0, *m_pixmapCache);
}
p.setPen(QPen(Qt::gray, 1, Qt::SolidLine));
/*
* Borders
*/
if (m_zoomLevel != 0) {
p.drawRect(0, 0, wWidth, wHeight);
}
/*
* Grid
*/
if (m_gridLines != 0) {
double stepH = wWidth / (double)(m_gridLines + 1);
double stepV = wHeight / (double)(m_gridLines + 1);
for (int i = 1; i <= m_gridLines; ++i) {
p.drawLine(QLineF(i * stepH, 0, i * stepH, wHeight));
p.drawLine(QLineF(0, i * stepV, wWidth, i * stepV));
}
}
p.setRenderHint(QPainter::Antialiasing);
/*
* Standard line
*/
p.drawLine(QLineF(0, wHeight, wWidth, 0));
/*
* Prepare Spline, Points
*/
int max = m_spline.points().count() - 1;
if (max < 1)
return;
BPoint point(m_spline.getPoint(0, wWidth, wHeight, true));
/*
* Spline
*/
BPoint next;
QPainterPath splinePath(QPointF(point.p.x(), point.p.y()));
for (int i = 0; i < max; ++i) {
point = m_spline.getPoint(i, wWidth, wHeight, true);
next = m_spline.getPoint(i + 1, wWidth, wHeight, true);
splinePath.cubicTo(point.h2, next.h1, next.p);
}
p.setPen(QPen(Qt::black, 1, Qt::SolidLine));
p.drawPath(splinePath);
/*
* Points + Handles
*/
p.setPen(QPen(Qt::red, 1, Qt::SolidLine));
QPolygonF handle = QPolygonF() << QPointF(0, -3) << QPointF(3, 0) << QPointF(0, 3) << QPointF(-3, 0);
#if QT_VERSION < 0x040600
QPolygonF tmp;
#endif
for (int i = 0; i <= max; ++i) {
point = m_spline.getPoint(i, wWidth, wHeight, true);
if (i == m_currentPointIndex) {
// selected point: fill p and handles
p.setBrush(QBrush(QColor(Qt::red), Qt::SolidPattern));
// connect p and handles with lines
if (i != 0)
p.drawLine(QLineF(point.h1.x(), point.h1.y(), point.p.x(),point.p.y()));
if (i != max)
p.drawLine(QLineF(point.p.x(), point.p.y(), point.h2.x(), point.h2.y()));
}
p.drawEllipse(QRectF(point.p.x() - 3,
point.p.y() - 3, 6, 6));
if (i != 0 && (i == m_currentPointIndex || m_showAllHandles)) {
#if QT_VERSION >= 0x040600
p.drawConvexPolygon(handle.translated(point.h1.x(), point.h1.y()));
#else
tmp = handle;
tmp.translate(point.h1.x(), point.h1.y());
p.drawConvexPolygon(tmp);
#endif
}
if (i != max && (i == m_currentPointIndex || m_showAllHandles)) {
#if QT_VERSION >= 0x040600
p.drawConvexPolygon(handle.translated(point.h2.x(), point.h2.y()));
#else
tmp = handle;
tmp.translate(point.h2.x(), point.h2.y());
p.drawConvexPolygon(tmp);
#endif
}
if ( i == m_currentPointIndex)
p.setBrush(QBrush(Qt::NoBrush));
}
}
void BezierSplineEditor::resizeEvent(QResizeEvent* event)
{
m_pixmapIsDirty = true;
QWidget::resizeEvent(event);
}
void BezierSplineEditor::mousePressEvent(QMouseEvent* event)
{
int wWidth = width() - 1;
int wHeight = height() - 1;
int offsetX = 1/8. * m_zoomLevel * wWidth;
int offsetY = 1/8. * m_zoomLevel * wHeight;
wWidth -= 2 * offsetX;
wHeight -= 2 * offsetY;
double x = (event->pos().x() - offsetX) / (double)(wWidth);
double y = 1.0 - (event->pos().y() - offsetY) / (double)(wHeight);
point_types selectedPoint;
int closestPointIndex = nearestPointInRange(QPointF(x, y), wWidth, wHeight, &selectedPoint);
if (event->button() == Qt::RightButton && closestPointIndex > 0 && closestPointIndex < m_spline.points().count() - 1 && selectedPoint == PTypeP) {
m_spline.removePoint(closestPointIndex);
setCursor(Qt::ArrowCursor);
m_mode = ModeNormal;
if (closestPointIndex < m_currentPointIndex)
--m_currentPointIndex;
update();
if (m_currentPointIndex >= 0)
emit currentPoint(m_spline.getPoint(m_currentPointIndex));
else
emit currentPoint(BPoint());
emit modified();
return;
} else if (event->button() != Qt::LeftButton) {
return;
}
if (closestPointIndex < 0) {
m_currentPointIndex = m_spline.addPoint(BPoint(QPointF(x-0.05, y-0.05),
QPointF(x, y),
QPointF(x+0.05, y+0.05)));
m_currentPointType = PTypeP;
} else {
m_currentPointIndex = closestPointIndex;
m_currentPointType = selectedPoint;
}
BPoint point = m_spline.getPoint(m_currentPointIndex);
m_grabPOriginal = point;
if (m_currentPointIndex > 0)
m_grabPPrevious = m_spline.getPoint(m_currentPointIndex - 1);
if (m_currentPointIndex < m_spline.points().count() - 1)
m_grabPNext = m_spline.getPoint(m_currentPointIndex + 1);
m_grabOffsetX = point[(int)m_currentPointType].x() - x;
m_grabOffsetY = point[(int)m_currentPointType].y() - y;
point[(int)m_currentPointType] = QPointF(x + m_grabOffsetX, y + m_grabOffsetY);
m_spline.setPoint(m_currentPointIndex, point);
m_mode = ModeDrag;
emit currentPoint(point);
update();
}
void BezierSplineEditor::mouseReleaseEvent(QMouseEvent* event)
{
if (event->button() != Qt::LeftButton)
return;
setCursor(Qt::ArrowCursor);
m_mode = ModeNormal;
emit modified();
}
void BezierSplineEditor::mouseMoveEvent(QMouseEvent* event)
{
int wWidth = width() - 1;
int wHeight = height() - 1;
int offsetX = 1/8. * m_zoomLevel * wWidth;
int offsetY = 1/8. * m_zoomLevel * wHeight;
wWidth -= 2 * offsetX;
wHeight -= 2 * offsetY;
double x = (event->pos().x() - offsetX) / (double)(wWidth);
double y = 1.0 - (event->pos().y() - offsetY) / (double)(wHeight);
if (m_mode == ModeNormal) {
// If no point is selected set the the cursor shape if on top
point_types type;
int nearestPointIndex = nearestPointInRange(QPointF(x, y), wWidth, wHeight, &type);
if (nearestPointIndex < 0)
setCursor(Qt::ArrowCursor);
else
setCursor(Qt::CrossCursor);
} else {
// Else, drag the selected point
setCursor(Qt::CrossCursor);
x += m_grabOffsetX;
y += m_grabOffsetY;
double leftX = 0.;
double rightX = 1.;
BPoint point = m_spline.getPoint(m_currentPointIndex);
switch (m_currentPointType) {
case PTypeH1:
rightX = point.p.x();
if (m_currentPointIndex == 0)
leftX = -4;
else
leftX = m_spline.getPoint(m_currentPointIndex - 1).p.x();
x = qBound(leftX, x, rightX);
point.setH1(QPointF(x, y));
break;
case PTypeP:
if (m_currentPointIndex == 0)
rightX = 0.0;
else if (m_currentPointIndex == m_spline.points().count() - 1)
leftX = 1.0;
x = qBound(leftX, x, rightX);
y = qBound(0., y, 1.);
// handles might have changed because we neared another point
// try to restore
point.h1 = m_grabPOriginal.h1;
point.h2 = m_grabPOriginal.h2;
// and move by same offset
// (using update handle in point.setP won't work because the offset between new and old point is very small)
point.h1 += QPointF(x, y) - m_grabPOriginal.p;
point.h2 += QPointF(x, y) - m_grabPOriginal.p;
point.setP(QPointF(x, y), false);
break;
case PTypeH2:
leftX = point.p.x();
if (m_currentPointIndex == m_spline.points().count() - 1)
rightX = 5;
else
rightX = m_spline.getPoint(m_currentPointIndex + 1).p.x();
x = qBound(leftX, x, rightX);
point.setH2(QPointF(x, y));
};
int index = m_currentPointIndex;
m_currentPointIndex = m_spline.setPoint(m_currentPointIndex, point);
if (m_currentPointType == PTypeP) {
// we might have changed the handles of other points
// try to restore
if (index == m_currentPointIndex) {
if (m_currentPointIndex > 0)
m_spline.setPoint(m_currentPointIndex - 1, m_grabPPrevious);
if (m_currentPointIndex < m_spline.points().count() -1)
m_spline.setPoint(m_currentPointIndex + 1, m_grabPNext);
} else {
if (m_currentPointIndex < index) {
m_spline.setPoint(index, m_grabPPrevious);
m_grabPNext = m_grabPPrevious;
if (m_currentPointIndex > 0)
m_grabPPrevious = m_spline.getPoint(m_currentPointIndex - 1);
} else {
m_spline.setPoint(index, m_grabPNext);
m_grabPPrevious = m_grabPNext;
if (m_currentPointIndex < m_spline.points().count() - 1)
m_grabPNext = m_spline.getPoint(m_currentPointIndex + 1);
}
}
}
emit currentPoint(point);
if (KdenliveSettings::dragvalue_directupdate())
emit modified();
update();
}
}
void BezierSplineEditor::mouseDoubleClickEvent(QMouseEvent* /*event*/)
{
if (m_currentPointIndex >= 0) {
BPoint p = m_spline.getPoint(m_currentPointIndex);
p.handlesLinked = !p.handlesLinked;
m_spline.setPoint(m_currentPointIndex, p);
emit currentPoint(p);
}
}
void BezierSplineEditor::leaveEvent(QEvent* event)
{
QWidget::leaveEvent(event);
}
int BezierSplineEditor::nearestPointInRange(const QPointF &p, int wWidth, int wHeight, BezierSplineEditor::point_types* sel)
{
double nearestDistanceSquared = 1000;
point_types selectedPoint = PTypeP;
int nearestIndex = -1;
int i = 0;
double distanceSquared;
// find out distance using the Pythagorean theorem
foreach(const BPoint & point, m_spline.points()) {
for (int j = 0; j < 3; ++j) {
distanceSquared = pow(point[j].x() - p.x(), 2) + pow(point[j].y() - p.y(), 2);
if (distanceSquared < nearestDistanceSquared) {
nearestIndex = i;
nearestDistanceSquared = distanceSquared;
selectedPoint = (point_types)j;
}
}
++i;
}
if (nearestIndex >= 0 && (nearestIndex == m_currentPointIndex || selectedPoint == PTypeP || m_showAllHandles)) {
// a point was found and it is not a hidden handle
BPoint point = m_spline.getPoint(nearestIndex);
if (qAbs(p.x() - point[(int)selectedPoint].x()) * wWidth < 5 && qAbs(p.y() - point[(int)selectedPoint].y()) * wHeight < 5) {
*sel = selectedPoint;
return nearestIndex;
}
}
return -1;
}
#include "beziersplineeditor.moc"

View File

@@ -1,110 +0,0 @@
/***************************************************************************
* Copyright (C) 2010 by Till Theato (root@ttill.de) *
* This file is part of Kdenlive (www.kdenlive.org). *
* *
* Kdenlive is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 2 of the License, or *
* (at your option) any later version. *
* *
* Kdenlive is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with Kdenlive. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef BEZIERSPLINEEDITOR_H
#define BEZIERSPLINEEDITOR_H
#include "cubicbezierspline.h"
#include <QtCore>
#include <QWidget>
class BezierSplineEditor : public QWidget
{
Q_OBJECT
public:
explicit BezierSplineEditor(QWidget* parent = 0);
~BezierSplineEditor();
CubicBezierSpline spline() const;
void setSpline(const CubicBezierSpline &spline);
/** @brief Returns the selected point or else BPoint. */
BPoint getCurrentPoint();
/** @brief Replaces current point with @param p (index stays the same).
* @param final (default = true) emit signal modified? */
void updateCurrentPoint(const BPoint &p, bool final = true);
/** @brief Number of lines used in grid. */
int gridLines() const;
/** @brief Sets the number of grid lines to draw (in one direction) to @param lines. */
void setGridLines(int lines);
/** @brief Sets the background pixmap to @param pixmap. */
void setPixmap(const QPixmap &pixmap);
/** @brief Sets the property showAllHandles to @param show.
*
* showAllHandles: Whether to show only handles for the selected point for all points. */
void setShowAllHandles(bool show);
public slots:
void slotZoomIn();
void slotZoomOut();
protected:
void paintEvent(QPaintEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent * event);
void mouseMoveEvent(QMouseEvent * event);
void mouseDoubleClickEvent(QMouseEvent *event);
void leaveEvent(QEvent *event);
void resizeEvent(QResizeEvent *event);
private:
CubicBezierSpline m_spline;
enum modes { ModeDrag, ModeNormal };
enum point_types { PTypeH1, PTypeP, PTypeH2 };
modes m_mode;
int m_zoomLevel;
int m_gridLines;
/** Whether to show handles for all points or only for the selected one. */
bool m_showAllHandles;
/** Background */
QPixmap m_pixmap;
/** A copy of m_pixmap but scaled to fit the size of the edit region */
QPixmap *m_pixmapCache;
/** Whether we have to regenerate the pixmap cache because the pixmap or the size of the edit region changed. */
bool m_pixmapIsDirty;
int m_currentPointIndex;
point_types m_currentPointType;
double m_grabOffsetX;
double m_grabOffsetY;
/** selected point before it was modified by dragging (at the time of the mouse press) */
BPoint m_grabPOriginal;
/** point with the index currentPointIndex + 1 at the time of the mouse press */
BPoint m_grabPNext;
/** point with the index currentPointIndex - 1 at the time of the mouse press */
BPoint m_grabPPrevious;
/** @brief Finds the point nearest to @param p and returns it's index.
* @param sel Is filled with the type of the closest point (h1, p, h2)
*
* If no point is near enough -1 is returned. */
int nearestPointInRange(const QPointF &p, int wWidth, int wHeight, point_types *sel);
signals:
void modified();
void currentPoint(const BPoint &p);
};
#endif

View File

@@ -1,215 +0,0 @@
/***************************************************************************
* Copyright (C) 2010 by Till Theato (root@ttill.de) *
* This file is part of Kdenlive (www.kdenlive.org). *
* *
* Kdenlive is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 2 of the License, or *
* (at your option) any later version. *
* *
* Kdenlive is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with Kdenlive. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#include "beziersplinewidget.h"
#include "colortools.h"
#include "dragvalue.h"
#include "kdenlivesettings.h"
#include <QVBoxLayout>
#include <KIcon>
#include <KLocale>
BezierSplineWidget::BezierSplineWidget(const QString& spline, QWidget* parent) :
QWidget(parent),
m_mode(ModeRGB),
m_showPixmap(true)
{
QVBoxLayout *layout = new QVBoxLayout(this);
layout->addWidget(&m_edit);
QWidget *widget = new QWidget(this);
m_ui.setupUi(widget);
layout->addWidget(widget);
m_ui.buttonLinkHandles->setIcon(KIcon("insert-link"));
m_ui.buttonZoomIn->setIcon(KIcon("zoom-in"));
m_ui.buttonZoomOut->setIcon(KIcon("zoom-out"));
m_ui.buttonGridChange->setIcon(KIcon("view-grid"));
m_ui.buttonShowPixmap->setIcon(QIcon(QPixmap::fromImage(ColorTools::rgbCurvePlane(QSize(16, 16), ColorTools::COL_Luma, 0.8))));
m_ui.buttonResetSpline->setIcon(KIcon("view-refresh"));
m_ui.buttonShowAllHandles->setIcon(KIcon("draw-bezier-curves"));
m_ui.widgetPoint->setEnabled(false);
m_pX = new DragValue(i18n("In"), 0, 3, 0, 1, -1, QString(), false, this);
m_pX->setStep(0.001);
m_pY = new DragValue(i18n("Out"), 0, 3, 0, 1, -1, QString(), false, this);
m_pY->setStep(0.001);
m_h1X = new DragValue(i18n("X"), 0, 3, -2, 2, -1, QString(), false, this);
m_h1X->setStep(0.001);
m_h1Y = new DragValue(i18n("Y"), 0, 3, -2, 2, -1, QString(), false, this);
m_h1Y->setStep(0.001);
m_h2X = new DragValue(i18n("X"), 0, 3, -2, 2, -1, QString(), false, this);
m_h2X->setStep(0.001);
m_h2Y = new DragValue(i18n("Y"), 0, 3, -2, 2, -1, QString(), false, this);
m_h2Y->setStep(0.001);
m_ui.layoutP->addWidget(m_pX);
m_ui.layoutP->addWidget(m_pY);
m_ui.layoutH1->addWidget(new QLabel(i18n("Handle 1:")));
m_ui.layoutH1->addWidget(m_h1X);
m_ui.layoutH1->addWidget(m_h1Y);
m_ui.layoutH2->addWidget(new QLabel(i18n("Handle 2:")));
m_ui.layoutH2->addWidget(m_h2X);
m_ui.layoutH2->addWidget(m_h2Y);
CubicBezierSpline s;
s.fromString(spline);
m_edit.setSpline(s);
connect(&m_edit, SIGNAL(modified()), this, SIGNAL(modified()));
connect(&m_edit, SIGNAL(currentPoint(BPoint)), this, SLOT(slotUpdatePointEntries(BPoint)));
connect(m_pX, SIGNAL(valueChanged(double,bool)), this, SLOT(slotUpdatePointP(double,bool)));
connect(m_pY, SIGNAL(valueChanged(double,bool)), this, SLOT(slotUpdatePointP(double,bool)));
connect(m_h1X, SIGNAL(valueChanged(double,bool)), this, SLOT(slotUpdatePointH1(double,bool)));
connect(m_h1Y, SIGNAL(valueChanged(double,bool)), this, SLOT(slotUpdatePointH1(double,bool)));
connect(m_h2X, SIGNAL(valueChanged(double,bool)), this, SLOT(slotUpdatePointH2(double,bool)));
connect(m_h2Y, SIGNAL(valueChanged(double,bool)), this, SLOT(slotUpdatePointH2(double,bool)));
connect(m_ui.buttonLinkHandles, SIGNAL(toggled(bool)), this, SLOT(slotSetHandlesLinked(bool)));
connect(m_ui.buttonZoomIn, SIGNAL(clicked()), &m_edit, SLOT(slotZoomIn()));
connect(m_ui.buttonZoomOut, SIGNAL(clicked()), &m_edit, SLOT(slotZoomOut()));
connect(m_ui.buttonGridChange, SIGNAL(clicked()), this, SLOT(slotGridChange()));
connect(m_ui.buttonShowPixmap, SIGNAL(toggled(bool)), this, SLOT(slotShowPixmap(bool)));
connect(m_ui.buttonResetSpline, SIGNAL(clicked()), this, SLOT(slotResetSpline()));
connect(m_ui.buttonShowAllHandles, SIGNAL(toggled(bool)), this, SLOT(slotShowAllHandles(bool)));
m_edit.setGridLines(KdenliveSettings::bezier_gridlines());
m_ui.buttonShowPixmap->setChecked(KdenliveSettings::bezier_showpixmap());
slotShowPixmap(m_ui.buttonShowPixmap->isChecked());
m_ui.buttonShowAllHandles->setChecked(KdenliveSettings::bezier_showallhandles());
}
QString BezierSplineWidget::spline() const
{
return m_edit.spline().toString();
}
void BezierSplineWidget::setMode(BezierSplineWidget::CurveModes mode)
{
if (m_mode != mode) {
m_mode = mode;
if (m_showPixmap)
slotShowPixmap();
}
}
void BezierSplineWidget::slotGridChange()
{
m_edit.setGridLines((m_edit.gridLines() + 1) % 9);
KdenliveSettings::setBezier_gridlines(m_edit.gridLines());
}
void BezierSplineWidget::slotShowPixmap(bool show)
{
if (m_showPixmap != show) {
m_showPixmap = show;
KdenliveSettings::setBezier_showpixmap(show);
if (show && (int)m_mode < 6)
m_edit.setPixmap(QPixmap::fromImage(ColorTools::rgbCurvePlane(m_edit.size(), (ColorTools::ColorsRGB)((int)m_mode), 1, palette().background().color().rgb())));
else if (show && m_mode == ModeHue)
m_edit.setPixmap(QPixmap::fromImage(ColorTools::hsvCurvePlane(m_edit.size(), QColor::fromHsv(200, 200, 200), ColorTools::COM_H, ColorTools::COM_H)));
else
m_edit.setPixmap(QPixmap());
}
}
void BezierSplineWidget::slotUpdatePointEntries(const BPoint &p)
{
blockSignals(true);
if (p == BPoint()) {
m_ui.widgetPoint->setEnabled(false);
} else {
m_ui.widgetPoint->setEnabled(true);
m_pX->blockSignals(true);
m_pY->blockSignals(true);
m_h1X->blockSignals(true);
m_h1Y->blockSignals(true);
m_h2X->blockSignals(true);
m_h2Y->blockSignals(true);
m_pX->setValue(p.p.x());
m_pY->setValue(p.p.y());
m_h1X->setValue(p.h1.x());
m_h1Y->setValue(p.h1.y());
m_h2X->setValue(p.h2.x());
m_h2Y->setValue(p.h2.y());
m_pX->blockSignals(false);
m_pY->blockSignals(false);
m_h1X->blockSignals(false);
m_h1Y->blockSignals(false);
m_h2X->blockSignals(false);
m_h2Y->blockSignals(false);
m_ui.buttonLinkHandles->setChecked(p.handlesLinked);
}
blockSignals(false);
}
void BezierSplineWidget::slotUpdatePointP(double value, bool final)
{
Q_UNUSED(value)
BPoint p = m_edit.getCurrentPoint();
p.setP(QPointF(m_pX->value(), m_pY->value()));
m_edit.updateCurrentPoint(p, final);
}
void BezierSplineWidget::slotUpdatePointH1(double value, bool final)
{
Q_UNUSED(value)
BPoint p = m_edit.getCurrentPoint();
p.setH1(QPointF(m_h1X->value(), m_h1Y->value()));
m_edit.updateCurrentPoint(p, final);
}
void BezierSplineWidget::slotUpdatePointH2(double value, bool final)
{
Q_UNUSED(value)
BPoint p = m_edit.getCurrentPoint();
p.setH2(QPointF(m_h2X->value(), m_h2Y->value()));
m_edit.updateCurrentPoint(p, final);
}
void BezierSplineWidget::slotSetHandlesLinked(bool linked)
{
BPoint p = m_edit.getCurrentPoint();
p.handlesLinked = linked;
m_edit.updateCurrentPoint(p);
}
void BezierSplineWidget::slotResetSpline()
{
m_edit.setSpline(CubicBezierSpline());
}
void BezierSplineWidget::slotShowAllHandles(bool show)
{
m_edit.setShowAllHandles(show);
KdenliveSettings::setBezier_showallhandles(show);
}
#include "beziersplinewidget.moc"

View File

@@ -1,92 +0,0 @@
/***************************************************************************
* Copyright (C) 2010 by Till Theato (root@ttill.de) *
* This file is part of Kdenlive (www.kdenlive.org). *
* *
* Kdenlive is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 2 of the License, or *
* (at your option) any later version. *
* *
* Kdenlive is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with Kdenlive. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef BEZIERSPLINEWIDGET_H
#define BEZIERSPLINEWIDGET_H
#include "cubicbezierspline.h"
#include "beziersplineeditor.h"
#include "ui_bezierspline_ui.h"
#include <QWidget>
class DragValue;
class BezierSplineWidget : public QWidget
{
Q_OBJECT
public:
/** @brief Sets up the UI and sets the spline to @param spline. */
explicit BezierSplineWidget(const QString &spline, QWidget* parent = 0);
/** @brief Returns the current spline. */
QString spline() const;
/** The curvemodes refer to the usage of the spline.
* As this widget is currently only used for frei0r.curves the modes are the channels this filter accepts. */
enum CurveModes { ModeRed, ModeGreen, ModeBlue, ModeAlpha, ModeLuma, ModeRGB, ModeHue, ModeSaturation };
/** @brief Sets the mode to @param mode and updates the editors background pixmap if necessary. */
void setMode(CurveModes mode);
private slots:
/** @brief Sets the spinboxes for modifing the selected point to @param p. */
void slotUpdatePointEntries(const BPoint &p);
/** @brief Updates the spline if the current point's p was modified using the spinboxes.
* @param value (optional) not used, neccessary to be able to connect to DragValue's valueChanged.
* @param final (default = true) emit signal modified? */
void slotUpdatePointP(double value = 1, bool final = true);
/** @brief Updates the spline if the current point's h1 was modified using the spinboxes.
* @param value (optional) not used, neccessary to be able to connect to DragValue's valueChanged.
* @param final (default = true) emit signal modified? */
void slotUpdatePointH1(double value = 1, bool final = true);
/** @brief Updates the spline if the current point's h2 was modified using the spinboxes.
* @param value (optional) not used, neccessary to be able to connect to DragValue's valueChanged.
* @param final (default = true) emit signal modified? */
void slotUpdatePointH2(double value = 1, bool final = true);
/** @brief Increases the number of lines in the editor's grid. If there are already 8 lines the number is set to 0. */
void slotGridChange();
/** @brief Turns showing the background pixmap in the editor on/off. */
void slotShowPixmap(bool show = true);
/** @brief Resets the current spline. */
void slotResetSpline();
/** @brief Linkes the handles. This will always make them stay in one line through p. */
void slotSetHandlesLinked(bool linked);
void slotShowAllHandles(bool show);
private:
Ui::BezierSpline_UI m_ui;
DragValue *m_pX;
DragValue *m_pY;
DragValue *m_h1X;
DragValue *m_h1Y;
DragValue *m_h2X;
DragValue *m_h2Y;
BezierSplineEditor m_edit;
CurveModes m_mode;
bool m_showPixmap;
signals:
void modified();
};
#endif

View File

@@ -1,99 +0,0 @@
/***************************************************************************
* Copyright (C) 2011 by Till Theato (root@ttill.de) *
* This file is part of Kdenlive (www.kdenlive.org). *
* *
* Kdenlive is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 2 of the License, or *
* (at your option) any later version. *
* *
* Kdenlive is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with Kdenlive. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#include "bpoint.h"
BPoint::BPoint() :
h1(QPointF(-1, -1)),
p(QPointF(-1, -1)),
h2(QPointF(-1, -1)),
handlesLinked(true)
{
}
BPoint::BPoint(const QPointF &handle1, const QPointF &point, const QPointF &handle2) :
h1(handle1),
p(point),
h2(handle2)
{
autoSetLinked();
}
QPointF &BPoint::operator[](int i)
{
return i == 0 ? h1 : (i == 1 ? p : h2);
}
const QPointF &BPoint::operator[](int i) const
{
return i == 0 ? h1 : (i == 1 ? p : h2);
}
bool BPoint::operator==(const BPoint& point) const
{
return point.h1 == h1 &&
point.p == p &&
point.h2 == h2;
}
void BPoint::setP(const QPointF &point, bool updateHandles)
{
QPointF offset = point - p;
p = point;
if (updateHandles) {
h1 += offset;
h2 += offset;
}
}
void BPoint::setH1(const QPointF &handle1)
{
h1 = handle1;
if (handlesLinked) {
qreal angle = QLineF(h1, p).angle();
QLineF l = QLineF(p, h2);
l.setAngle(angle);
h2 = l.p2();
}
}
void BPoint::setH2(const QPointF &handle2)
{
h2 = handle2;
if (handlesLinked) {
qreal angle = QLineF(h2, p).angle();
QLineF l = QLineF(p, h1);
l.setAngle(angle);
h1 = l.p2();
}
}
void BPoint::keepInRange(qreal xMin, qreal xMax)
{
Q_UNUSED(xMin)
Q_UNUSED(xMax)
}
void BPoint::autoSetLinked()
{
// sometimes the angle is returned as 360°
// due to rounding problems the angle is sometimes not quite 0
qreal angle = QLineF(h1, p).angleTo(QLineF(p, h2));
handlesLinked = angle < 1e-3 || qRound(angle) == 360;
}

View File

@@ -1,71 +0,0 @@
/***************************************************************************
* Copyright (C) 2011 by Till Theato (root@ttill.de) *
* This file is part of Kdenlive (www.kdenlive.org). *
* *
* Kdenlive is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 2 of the License, or *
* (at your option) any later version. *
* *
* Kdenlive is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with Kdenlive. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef BPOINT_H
#define BPOINT_H
#include <QtCore>
/**
* @brief Represents a point in a cubic Bézier spline.
*/
class BPoint
{
public:
/** @brief Sets the point to -1, -1 to mark it as unusable (until point + handles have proper values) */
BPoint();
/** @brief Sets up according to the params. Linking detecting is done using autoSetLinked(). */
BPoint(const QPointF &handle1, const QPointF &point, const QPointF &handle2);
/** @brief Returns h1 if i = 0, p if i = 1, h2 if i = 2. */
QPointF &operator[](int i);
/** @brief Returns h1 if i = 0, p if i = 1, h2 if i = 2. */
const QPointF &operator[](int i) const;
bool operator==(const BPoint &point) const;
/** @brief Sets p to @param point.
* @param updateHandles (default = true) Whether to make sure the handles keep their position relative to p. */
void setP(const QPointF &point, bool updateHandles = true);
/** @brief Sets h1 to @param handle1.
*
* If handlesLinked is true h2 is updated. */
void setH1(const QPointF &handle1);
/** @brief Sets h2 to @param handle2.
*
* If handlesLinked is true h1 is updated. */
void setH2(const QPointF &handle2);
void keepInRange(qreal xMin, qreal xMax);
/** @brief Sets handlesLinked to true if the handles are in a linked state (line through h1, p, h2) otherwise to false. */
void autoSetLinked();
/** handle 1 */
QPointF h1;
/** point */
QPointF p;
/** handle 2 */
QPointF h2;
/** handles are linked to achieve a natural locking spline => PH1 = -r*PH2 ; a line can be drawn through h1, p, h2 */
bool handlesLinked;
};
#endif

View File

@@ -1,152 +0,0 @@
/***************************************************************************
* Copyright (C) 2010 by Till Theato (root@ttill.de) *
* This file is part of Kdenlive (www.kdenlive.org). *
* *
* Kdenlive is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 2 of the License, or *
* (at your option) any later version. *
* *
* Kdenlive is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with Kdenlive. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#include "cubicbezierspline.h"
#include <KDebug>
/** @brief For sorting a Bezier spline. Whether a is before b. */
static bool pointLessThan(const BPoint &a, const BPoint &b)
{
return a.p.x() < b.p.x();
}
CubicBezierSpline::CubicBezierSpline(QObject* parent) :
QObject(parent)
{
m_points.append(BPoint(QPointF(0, 0), QPointF(0, 0), QPointF(.1, .1)));
m_points.append(BPoint(QPointF(.9, .9), QPointF(1, 1), QPointF(1, 1)));
}
CubicBezierSpline::CubicBezierSpline(const CubicBezierSpline& spline, QObject* parent) :
QObject(parent)
{
m_points = spline.m_points;
}
CubicBezierSpline& CubicBezierSpline::operator=(const CubicBezierSpline& spline)
{
m_points = spline.m_points;
return *this;
}
void CubicBezierSpline::fromString(const QString& spline)
{
m_points.clear();
const QStringList bpoints = spline.split(QLatin1Char('|'));
foreach(const QString &bpoint, bpoints) {
const QStringList points = bpoint.split(QLatin1Char('#'));
QList <QPointF> values;
foreach(const QString &point, points) {
QStringList xy = point.split(QLatin1Char(';'));
if (xy.count() == 2)
values.append(QPointF(xy.at(0).toDouble(), xy.at(1).toDouble()));
}
if (values.count() == 3) {
m_points.append(BPoint(values.at(0), values.at(1), values.at(2)));
}
}
keepSorted();
validatePoints();
}
QString CubicBezierSpline::toString() const
{
QStringList spline;
QLocale locale;
foreach(const BPoint &p, m_points) {
spline << QString("%1;%2#%3;%4#%5;%6").arg(locale.toString(p.h1.x())).arg(locale.toString(p.h1.y()))
.arg(locale.toString(p.p.x())).arg(locale.toString(p.p.y()))
.arg(locale.toString(p.h2.x())).arg(locale.toString(p.h2.y()));
}
return spline.join("|");
}
int CubicBezierSpline::setPoint(int ix, const BPoint& point)
{
m_points[ix] = point;
keepSorted();
validatePoints();
return indexOf(point); // in case it changed
}
QList <BPoint> CubicBezierSpline::points() const
{
return m_points;
}
void CubicBezierSpline::removePoint(int ix)
{
m_points.removeAt(ix);
}
int CubicBezierSpline::addPoint(const BPoint& point)
{
m_points.append(point);
keepSorted();
validatePoints();
return indexOf(point);
}
BPoint CubicBezierSpline::getPoint(int ix, int normalisedWidth, int normalisedHeight, bool invertHeight)
{
BPoint p = m_points.at(ix);
for (int i = 0; i < 3; ++i) {
p[i].rx() *= normalisedWidth;
p[i].ry() *= normalisedHeight;
if (invertHeight)
p[i].ry() = normalisedHeight - p[i].y();
}
return p;
}
void CubicBezierSpline::validatePoints()
{
BPoint p1, p2;
for (int i = 0; i < m_points.count() - 1; ++i) {
p1 = m_points.at(i);
p2 = m_points.at(i+1);
p1.h2.setX(qBound(p1.p.x(), p1.h2.x(), p2.p.x()));
p2.h1.setX(qBound(p1.p.x(), p2.h1.x(), p2.p.x()));
m_points[i] = p1;
m_points[i+1] = p2;
}
}
void CubicBezierSpline::keepSorted()
{
qSort(m_points.begin(), m_points.end(), pointLessThan);
}
int CubicBezierSpline::indexOf(const BPoint& p)
{
if (m_points.indexOf(p) == -1) {
// point changed during validation process
for (int i = 0; i < m_points.count(); ++i) {
// this condition should be sufficient, too
if (m_points.at(i).p == p.p)
return i;
}
} else {
return m_points.indexOf(p);
}
return -1;
}
#include "cubicbezierspline.moc"

View File

@@ -1,79 +0,0 @@
/***************************************************************************
* Copyright (C) 2010 by Till Theato (root@ttill.de) *
* This file is part of Kdenlive (www.kdenlive.org). *
* *
* Kdenlive is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 2 of the License, or *
* (at your option) any later version. *
* *
* Kdenlive is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with Kdenlive. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifndef CUBICBEZIERSPLINE_H
#define CUBICBEZIERSPLINE_H
#include "bpoint.h"
#include <QtCore>
class CubicBezierSpline : public QObject
{
Q_OBJECT
public:
explicit CubicBezierSpline(QObject* parent = 0);
CubicBezierSpline(const CubicBezierSpline &spline, QObject* parent = 0);
CubicBezierSpline& operator=(const CubicBezierSpline &spline);
/** @brief Loads the points from the string @param spline.
*
* x, y values have to be separated with a ';'
* handles and points with a '#'
* and the nodes with a '|'
* So that you get: h1x;h1y#px;py#h2x;h2y|h1x;h1y#... */
void fromString(const QString &spline);
/** @brief Returns the points stoed in a string.
*
* x, y values have are separated with a ';'
* handles and points with a '#'
* and the nodes with a '|'
* So that you get: h1x;h1y#px;py#h2x;h2y|h1x;h1y#... */
QString toString() const;
/** @brief Returns a list of the points defining the spline. */
QList <BPoint> points() const;
/** @brief Sets the point at index @param ix to @param point and returns its index (it might have changed during validation). */
int setPoint(int ix, const BPoint &point);
/** @brief Adds @param point and returns its index. */
int addPoint(const BPoint &point);
/** @brief Removes the point at @param ix. */
void removePoint(int ix);
/** @brief Returns the point at @param ix.
* @param ix Index of the point
* @param normalisedWidth (default = 1) Will be multiplied will all x values to change the range from 0-1 into another one
* @param normalisedHeight (default = 1) Will be multiplied will all y values to change the range from 0-1 into another one
* @param invertHeight (default = false) true => y = 0 is at the very top
*/
BPoint getPoint(int ix, int normalisedWidth = 1, int normalisedHeight = 1, bool invertHeight = false);
private:
void validatePoints();
void keepSorted();
int indexOf(const BPoint &p);
QList <BPoint> m_points;
};
#endif

View File

@@ -1,136 +0,0 @@
/***************************************************************************
* Copyright (C) 2010 by Till Theato (root@ttill.de) *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#include "choosecolorwidget.h"
#include "colorpickerwidget.h"
#include <QLabel>
#include <QHBoxLayout>
#include <KColorButton>
#include <KLocalizedString>
#include <kdeversion.h>
#include <KDebug>
static QColor stringToColor(QString strColor)
{
bool ok = false;
QColor color("black");
int intval = 0;
if (strColor.startsWith("0x")) {
if (strColor.length() == 10) {
// 0xRRGGBBAA
intval = strColor.toUInt(&ok, 16);
color.setRgb( ( intval >> 24 ) & 0xff, // r
( intval >> 16 ) & 0xff, // g
( intval >> 8 ) & 0xff, // b
( intval ) & 0xff ); // a
} else {
// 0xRRGGBB, 0xRGB
color.setNamedColor(strColor.replace(0, 2, "#"));
}
} else {
if (strColor.length() == 9) {
// #AARRGGBB
strColor = strColor.replace('#', "0x");
intval = strColor.toUInt(&ok, 16);
color.setRgb( ( intval >> 16 ) & 0xff, // r
( intval >> 8 ) & 0xff, // g
( intval ) & 0xff, // b
( intval >> 24 ) & 0xff ); // a
} else if (strColor.length() == 8) {
// 0xRRGGBB
strColor = strColor.replace('#', "0x");
color.setNamedColor(strColor);
} else {
// #RRGGBB, #RGB
color.setNamedColor(strColor);
}
}
return color;
}
static QString colorToString(const QColor &color, bool alpha)
{
QString colorStr;
QTextStream stream(&colorStr);
stream << "0x";
stream.setIntegerBase(16);
stream.setFieldWidth(2);
stream.setFieldAlignment(QTextStream::AlignRight);
stream.setPadChar('0');
stream << color.red() << color.green() << color.blue();
if (alpha) {
stream << color.alpha();
} else {
// MLT always wants 0xRRGGBBAA format
stream << "ff";
}
return colorStr;
}
ChooseColorWidget::ChooseColorWidget(const QString &text, const QString &color, bool alphaEnabled, QWidget *parent) :
QWidget(parent)
{
QHBoxLayout *layout = new QHBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
QLabel *label = new QLabel(text, this);
QWidget *rightSide = new QWidget(this);
QHBoxLayout *rightSideLayout = new QHBoxLayout(rightSide);
rightSideLayout->setContentsMargins(0, 0, 0, 0);
rightSideLayout->setSpacing(0);
m_button = new KColorButton(stringToColor(color), rightSide);
#if KDE_IS_VERSION(4,5,0)
if (alphaEnabled) m_button->setAlphaChannelEnabled(alphaEnabled);
#endif
// m_button->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
ColorPickerWidget *picker = new ColorPickerWidget(rightSide);
layout->addWidget(label);
layout->addWidget(rightSide);
rightSideLayout->addWidget(m_button);
rightSideLayout->addWidget(picker, 0, Qt::AlignRight);
connect(picker, SIGNAL(colorPicked(QColor)), this, SLOT(setColor(QColor)));
connect(picker, SIGNAL(displayMessage(QString,int)), this, SIGNAL(displayMessage(QString,int)));
connect(picker, SIGNAL(disableCurrentFilter(bool)), this, SIGNAL(disableCurrentFilter(bool)));
connect(m_button, SIGNAL(changed(QColor)), this, SIGNAL(modified()));
}
QString ChooseColorWidget::getColor() const
{
bool alphaChannel = false;
#if KDE_IS_VERSION(4,5,0)
alphaChannel = m_button->isAlphaChannelEnabled();
#endif
return colorToString(m_button->color(), alphaChannel);
}
void ChooseColorWidget::setColor(const QColor& color)
{
m_button->setColor(color);
}
#include "choosecolorwidget.moc"

View File

@@ -1,62 +0,0 @@
/***************************************************************************
* Copyright (C) 2010 by Till Theato (root@ttill.de) *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#ifndef CHOOSECOLORWIDGET_H
#define CHOOSECOLORWIDGET_H
#include <QWidget>
class KColorButton;
/**
* @class ChooseColorWidget
* @brief Provides options to choose a color.
* @author Till Theato
*/
class ChooseColorWidget : public QWidget
{
Q_OBJECT
public:
/** @brief Sets up the widget.
* @param text (optional) What the color will be used for
* @param color (optional) initial color
* @param alphaEnabled (optional) Should transparent colors be enabled */
explicit ChooseColorWidget(const QString &text = QString(), const QString &color = "0xffffffff", bool alphaEnabled = false, QWidget* parent = 0);
/** @brief Gets the choosen color. */
QString getColor() const;
private:
KColorButton *m_button;
private slots:
/** @brief Updates the different color choosing options to have all selected @param color. */
void setColor(const QColor &color);
signals:
/** @brief Emitted whenever a different color was choosen. */
void modified();
void displayMessage(const QString&, int);
/** @brief When user wants to pick a color, it's better to disable filter so we get proper color values. */
void disableCurrentFilter(bool);
};
#endif

View File

@@ -1,177 +0,0 @@
/***************************************************************************
* Copyright (C) 2008 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#include "clipdurationdialog.h"
#include "clipitem.h"
#include <KDebug>
#include <KMessageBox>
#include <KGlobalSettings>
#include <QWheelEvent>
ClipDurationDialog::ClipDurationDialog(AbstractClipItem *clip, const Timecode &tc, const GenTime &min, const GenTime &max, QWidget * parent):
QDialog(parent),
m_clip(clip),
m_min(min),
m_max(max)
{
setFont(KGlobalSettings::toolBarFont());
setupUi(this);
m_pos = new TimecodeDisplay(tc);
m_cropStart = new TimecodeDisplay(tc);
m_dur = new TimecodeDisplay(tc);
m_cropEnd = new TimecodeDisplay(tc);
clip_position_box->addWidget(m_pos);
crop_start_box->addWidget(m_cropStart);
clip_duration_box->addWidget(m_dur);
crop_end_box->addWidget(m_cropEnd);
bool allowCrop = true;
if (clip->type() == AVWIDGET) {
ClipItem *item = static_cast <ClipItem *>(clip);
const int t = item->clipType();
if (t == COLOR || t == IMAGE || t == TEXT)
allowCrop = false;
}
if (!allowCrop || clip->type() == TRANSITIONWIDGET) {
m_cropStart->setHidden(true);
crop_label->hide();
m_cropEnd->setHidden(true),
end_label->hide();
}
m_crop = m_clip->cropStart();
m_pos->setValue(m_clip->startPos());
m_dur->setValue(m_clip->cropDuration());
m_cropStart->setValue(m_clip->cropStart());
m_cropEnd->setValue(m_clip->maxDuration() - m_clip->cropDuration() - m_clip->cropStart());
connect(m_pos, SIGNAL(timeCodeEditingFinished()), this, SLOT(slotCheckStart()));
connect(m_dur, SIGNAL(timeCodeEditingFinished()), this, SLOT(slotCheckDuration()));
connect(m_cropStart, SIGNAL(timeCodeEditingFinished()), this, SLOT(slotCheckCrop()));
connect(m_cropEnd, SIGNAL(timeCodeEditingFinished()), this, SLOT(slotCheckEnd()));
adjustSize();
}
ClipDurationDialog::~ClipDurationDialog()
{
delete m_pos;
delete m_dur;
delete m_cropStart;
delete m_cropEnd;
}
void ClipDurationDialog::slotCheckStart()
{
GenTime start = m_pos->gentime();
GenTime duration = m_dur->gentime();
if (m_min != GenTime() && start < m_min)
m_pos->setValue(m_min);
else if (m_max != GenTime() && start + duration > m_max)
m_pos->setValue(m_max - duration);
}
void ClipDurationDialog::slotCheckDuration()
{
GenTime start = m_pos->gentime();
GenTime duration = m_dur->gentime();
GenTime cropStart = m_cropStart->gentime();
GenTime maxDuration;
if (m_clip->maxDuration() == GenTime())
maxDuration = m_max;
else
maxDuration = m_max == GenTime() ? start + m_clip->maxDuration() - cropStart : qMin(m_max, start + m_clip->maxDuration() - cropStart);
if (maxDuration != GenTime() && start + duration > maxDuration) {
m_dur->blockSignals(true);
m_dur->setValue(maxDuration - start);
m_dur->blockSignals(false);
}
m_cropEnd->blockSignals(true);
m_cropEnd->setValue(m_clip->maxDuration() - m_dur->gentime() - cropStart);
m_cropEnd->blockSignals(false);
}
void ClipDurationDialog::slotCheckCrop()
{
GenTime duration = m_dur->gentime();
GenTime cropStart = m_cropStart->gentime();
GenTime maxDuration = m_clip->maxDuration();
GenTime diff = cropStart - m_crop;
if ((diff > GenTime() && diff < duration) || diff < GenTime()) {
duration -= diff;
} else {
m_cropStart->setValue(m_crop);
return;
}
if (maxDuration != GenTime() && cropStart + duration > maxDuration) {
m_cropStart->setValue(m_crop);
} else {
m_crop = cropStart;
m_dur->blockSignals(true);
m_dur->setValue(duration);
m_dur->blockSignals(false);
}
}
void ClipDurationDialog::slotCheckEnd()
{
GenTime cropStart = m_cropStart->gentime();
GenTime cropEnd = m_cropEnd->gentime();
GenTime duration = m_clip->maxDuration() - cropEnd - cropStart;
if (duration >= GenTime()) {
m_dur->setValue(duration);
slotCheckDuration();
} else {
m_cropEnd->blockSignals(true);
m_cropEnd->setValue(m_clip->maxDuration() - m_dur->gentime() - cropStart);
m_cropEnd->blockSignals(false);
}
}
GenTime ClipDurationDialog::startPos() const
{
return m_pos->gentime();
}
GenTime ClipDurationDialog::cropStart() const
{
return m_cropStart->gentime();
}
GenTime ClipDurationDialog::duration() const
{
return m_dur->gentime();
}
#include "clipdurationdialog.moc"

Some files were not shown because too many files have changed in this diff Show More